Update to bc8dcc3ede286fbcaac3f741c379297cffff0eea

Same version as used by Chromium 57.0.2987.108

Fixes: 28051413, 34337228
Test: cts-tradefed run cts-dev -m CtsGraphicsTestCases -t android.graphics.pdf.cts
      cts-tradefed run cts-dev -m Print -t android.print.pdf.cts
Change-Id: I1bf02cae444c9f08711953c4475af10db2becd58
diff --git a/fpdfsdk/Android.mk b/fpdfsdk/Android.mk
deleted file mode 100644
index 1b0fc98..0000000
--- a/fpdfsdk/Android.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-BASE_PATH := $(call my-dir)
-
-include $(BASE_PATH)/pdfium.mk
-include $(BASE_PATH)/pdfiumformfiller.mk
-include $(BASE_PATH)/pdfiumfxedit.mk
-include $(BASE_PATH)/pdfiumjavascript.mk
-include $(BASE_PATH)/pdfiumpdfwindow.mk
diff --git a/fpdfsdk/DEPS b/fpdfsdk/DEPS
index 488a396..e077225 100644
--- a/fpdfsdk/DEPS
+++ b/fpdfsdk/DEPS
@@ -1,7 +1,9 @@
 include_rules = [
-  '+core/include',
-  '+javascript/IJavaScript.h',
+  '+core',
   '+public',
   '+v8',
-  '+xfa/include',
-]
+  '+xfa/fwl',
+  '+xfa/fxbarcode',
+  '+xfa/fxfa',
+  '+xfa/fxgraphics',
+  ]
diff --git a/fpdfsdk/cba_annotiterator.cpp b/fpdfsdk/cba_annotiterator.cpp
new file mode 100644
index 0000000..cc842ba
--- /dev/null
+++ b/fpdfsdk/cba_annotiterator.cpp
@@ -0,0 +1,176 @@
+// 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/cba_annotiterator.h"
+
+#include <algorithm>
+
+#include "core/fpdfapi/page/cpdf_page.h"
+#include "fpdfsdk/cpdfsdk_annot.h"
+#include "fpdfsdk/cpdfsdk_pageview.h"
+
+namespace {
+
+CFX_FloatRect GetAnnotRect(const CPDFSDK_Annot* pAnnot) {
+  return pAnnot->GetPDFAnnot()->GetRect();
+}
+
+bool CompareByLeftAscending(const CPDFSDK_Annot* p1, const CPDFSDK_Annot* p2) {
+  return GetAnnotRect(p1).left < GetAnnotRect(p2).left;
+}
+
+bool CompareByTopDescending(const CPDFSDK_Annot* p1, const CPDFSDK_Annot* p2) {
+  return GetAnnotRect(p1).top > GetAnnotRect(p2).top;
+}
+
+}  // namespace
+
+CBA_AnnotIterator::CBA_AnnotIterator(CPDFSDK_PageView* pPageView,
+                                     CPDF_Annot::Subtype nAnnotSubtype)
+    : m_eTabOrder(STRUCTURE),
+      m_pPageView(pPageView),
+      m_nAnnotSubtype(nAnnotSubtype) {
+  CPDF_Page* pPDFPage = m_pPageView->GetPDFPage();
+  CFX_ByteString sTabs = pPDFPage->m_pFormDict->GetStringFor("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::CollectAnnots(std::vector<CPDFSDK_Annot*>* pArray) {
+  for (auto pAnnot : m_pPageView->GetAnnotList()) {
+    if (pAnnot->GetAnnotSubtype() == m_nAnnotSubtype &&
+        !pAnnot->IsSignatureWidget()) {
+      pArray->push_back(pAnnot);
+    }
+  }
+}
+
+CFX_FloatRect CBA_AnnotIterator::AddToAnnotsList(
+    std::vector<CPDFSDK_Annot*>* sa,
+    size_t idx) {
+  CPDFSDK_Annot* pLeftTopAnnot = sa->at(idx);
+  CFX_FloatRect rcLeftTop = GetAnnotRect(pLeftTopAnnot);
+  m_Annots.push_back(pLeftTopAnnot);
+  sa->erase(sa->begin() + idx);
+  return rcLeftTop;
+}
+
+void CBA_AnnotIterator::AddSelectedToAnnots(std::vector<CPDFSDK_Annot*>* sa,
+                                            std::vector<size_t>* aSelect) {
+  for (size_t i = 0; i < aSelect->size(); ++i)
+    m_Annots.push_back(sa->at(aSelect->at(i)));
+
+  for (int i = aSelect->size() - 1; i >= 0; --i)
+    sa->erase(sa->begin() + aSelect->at(i));
+}
+
+void CBA_AnnotIterator::GenerateResults() {
+  switch (m_eTabOrder) {
+    case STRUCTURE:
+      CollectAnnots(&m_Annots);
+      break;
+
+    case ROW: {
+      std::vector<CPDFSDK_Annot*> sa;
+      CollectAnnots(&sa);
+      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)
+          continue;
+
+        CFX_FloatRect rcLeftTop = AddToAnnotsList(&sa, nLeftTopIndex);
+
+        std::vector<size_t> 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);
+        }
+        AddSelectedToAnnots(&sa, &aSelect);
+      }
+      break;
+    }
+
+    case COLUMN: {
+      std::vector<CPDFSDK_Annot*> sa;
+      CollectAnnots(&sa);
+      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)
+          continue;
+
+        CFX_FloatRect rcLeftTop = AddToAnnotsList(&sa, nLeftTopIndex);
+
+        std::vector<size_t> 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);
+        }
+        AddSelectedToAnnots(&sa, &aSelect);
+      }
+      break;
+    }
+  }
+}
diff --git a/fpdfsdk/cba_annotiterator.h b/fpdfsdk/cba_annotiterator.h
new file mode 100644
index 0000000..5cbe8e3
--- /dev/null
+++ b/fpdfsdk/cba_annotiterator.h
@@ -0,0 +1,45 @@
+// 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_CBA_ANNOTITERATOR_H_
+#define FPDFSDK_CBA_ANNOTITERATOR_H_
+
+#include <vector>
+
+#include "core/fpdfdoc/cpdf_annot.h"
+#include "core/fxcrt/fx_coordinates.h"
+#include "core/fxcrt/fx_string.h"
+
+class CPDFSDK_Annot;
+class CPDFSDK_PageView;
+
+class CBA_AnnotIterator {
+ public:
+  enum TabOrder { STRUCTURE = 0, ROW, COLUMN };
+
+  CBA_AnnotIterator(CPDFSDK_PageView* pPageView,
+                    CPDF_Annot::Subtype nAnnotSubtype);
+  ~CBA_AnnotIterator();
+
+  CPDFSDK_Annot* GetFirstAnnot();
+  CPDFSDK_Annot* GetLastAnnot();
+  CPDFSDK_Annot* GetNextAnnot(CPDFSDK_Annot* pAnnot);
+  CPDFSDK_Annot* GetPrevAnnot(CPDFSDK_Annot* pAnnot);
+
+ private:
+  void GenerateResults();
+  void CollectAnnots(std::vector<CPDFSDK_Annot*>* pArray);
+  CFX_FloatRect AddToAnnotsList(std::vector<CPDFSDK_Annot*>* sa, size_t idx);
+  void AddSelectedToAnnots(std::vector<CPDFSDK_Annot*>* sa,
+                           std::vector<size_t>* aSelect);
+
+  TabOrder m_eTabOrder;
+  CPDFSDK_PageView* m_pPageView;
+  CPDF_Annot::Subtype m_nAnnotSubtype;
+  std::vector<CPDFSDK_Annot*> m_Annots;
+};
+
+#endif  // FPDFSDK_CBA_ANNOTITERATOR_H_
diff --git a/fpdfsdk/cfx_systemhandler.cpp b/fpdfsdk/cfx_systemhandler.cpp
new file mode 100644
index 0000000..f38be4c
--- /dev/null
+++ b/fpdfsdk/cfx_systemhandler.cpp
@@ -0,0 +1,147 @@
+// 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/cfx_systemhandler.h"
+
+#include <memory>
+
+#include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fxge/cfx_fontmapper.h"
+#include "core/fxge/cfx_fontmgr.h"
+#include "core/fxge/cfx_gemodule.h"
+#include "fpdfsdk/cpdfsdk_annot.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/cpdfsdk_pageview.h"
+#include "fpdfsdk/cpdfsdk_widget.h"
+#include "fpdfsdk/formfiller/cffl_formfiller.h"
+
+namespace {
+
+int CharSet2CP(int charset) {
+  if (charset == FXFONT_SHIFTJIS_CHARSET)
+    return 932;
+  if (charset == FXFONT_GB2312_CHARSET)
+    return 936;
+  if (charset == FXFONT_HANGUL_CHARSET)
+    return 949;
+  if (charset == FXFONT_CHINESEBIG5_CHARSET)
+    return 950;
+  return 0;
+}
+
+}  // namespace
+
+void CFX_SystemHandler::InvalidateRect(CPDFSDK_Widget* widget, FX_RECT rect) {
+  CPDFSDK_PageView* pPageView = widget->GetPageView();
+  UnderlyingPageType* pPage = widget->GetUnderlyingPage();
+  if (!pPage || !pPageView)
+    return;
+
+  CFX_Matrix page2device;
+  pPageView->GetCurrentMatrix(page2device);
+
+  CFX_Matrix device2page;
+  device2page.SetReverse(page2device);
+
+  FX_FLOAT left;
+  FX_FLOAT top;
+  FX_FLOAT right;
+  FX_FLOAT bottom;
+  device2page.Transform(static_cast<FX_FLOAT>(rect.left),
+                        static_cast<FX_FLOAT>(rect.top), left, top);
+  device2page.Transform(static_cast<FX_FLOAT>(rect.right),
+                        static_cast<FX_FLOAT>(rect.bottom), right, bottom);
+  CFX_FloatRect rcPDF(left, bottom, right, top);
+  rcPDF.Normalize();
+
+  m_pFormFillEnv->Invalidate(pPage, rcPDF.left, rcPDF.top, rcPDF.right,
+                             rcPDF.bottom);
+}
+
+void CFX_SystemHandler::OutputSelectedRect(CFFL_FormFiller* pFormFiller,
+                                           CFX_FloatRect& rect) {
+  if (!pFormFiller)
+    return;
+
+  CFX_FloatPoint leftbottom = CFX_FloatPoint(rect.left, rect.bottom);
+  CFX_FloatPoint righttop = CFX_FloatPoint(rect.right, rect.top);
+  CFX_FloatPoint ptA = pFormFiller->PWLtoFFL(leftbottom);
+  CFX_FloatPoint ptB = pFormFiller->PWLtoFFL(righttop);
+
+  CPDFSDK_Annot* pAnnot = pFormFiller->GetSDKAnnot();
+  UnderlyingPageType* pPage = pAnnot->GetUnderlyingPage();
+  ASSERT(pPage);
+
+  m_pFormFillEnv->OutputSelectedRect(pPage, ptA.x, ptB.y, ptB.x, ptA.y);
+}
+
+bool CFX_SystemHandler::IsSelectionImplemented() const {
+  if (!m_pFormFillEnv)
+    return false;
+
+  FPDF_FORMFILLINFO* pInfo = m_pFormFillEnv->GetFormFillInfo();
+  return pInfo && pInfo->FFI_OutputSelectedRect;
+}
+
+void CFX_SystemHandler::SetCursor(int32_t nCursorType) {
+  m_pFormFillEnv->SetCursor(nCursorType);
+}
+
+bool CFX_SystemHandler::FindNativeTrueTypeFont(CFX_ByteString sFontFaceName) {
+  CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr();
+  if (!pFontMgr)
+    return false;
+
+  CFX_FontMapper* pFontMapper = pFontMgr->GetBuiltinMapper();
+  if (!pFontMapper)
+    return false;
+
+  if (pFontMapper->m_InstalledTTFonts.empty())
+    pFontMapper->LoadInstalledFonts();
+
+  for (const auto& font : pFontMapper->m_InstalledTTFonts) {
+    if (font.Compare(sFontFaceName.AsStringC()))
+      return true;
+  }
+  for (const auto& fontPair : pFontMapper->m_LocalizedTTFonts) {
+    if (fontPair.first.Compare(sFontFaceName.AsStringC()))
+      return true;
+  }
+  return false;
+}
+
+CPDF_Font* CFX_SystemHandler::AddNativeTrueTypeFontToPDF(
+    CPDF_Document* pDoc,
+    CFX_ByteString sFontFaceName,
+    uint8_t nCharset) {
+  if (!pDoc)
+    return nullptr;
+
+  std::unique_ptr<CFX_Font> pFXFont(new CFX_Font);
+  pFXFont->LoadSubst(sFontFaceName, true, 0, 0, 0, CharSet2CP(nCharset), false);
+  return pDoc->AddFont(pFXFont.get(), nCharset, false);
+}
+
+int32_t CFX_SystemHandler::SetTimer(int32_t uElapse,
+                                    TimerCallback lpTimerFunc) {
+  return m_pFormFillEnv->SetTimer(uElapse, lpTimerFunc);
+}
+
+void CFX_SystemHandler::KillTimer(int32_t nID) {
+  m_pFormFillEnv->KillTimer(nID);
+}
+
+bool CFX_SystemHandler::IsSHIFTKeyDown(uint32_t nFlag) const {
+  return !!m_pFormFillEnv->IsSHIFTKeyDown(nFlag);
+}
+
+bool CFX_SystemHandler::IsCTRLKeyDown(uint32_t nFlag) const {
+  return !!m_pFormFillEnv->IsCTRLKeyDown(nFlag);
+}
+
+bool CFX_SystemHandler::IsALTKeyDown(uint32_t nFlag) const {
+  return !!m_pFormFillEnv->IsALTKeyDown(nFlag);
+}
diff --git a/fpdfsdk/cfx_systemhandler.h b/fpdfsdk/cfx_systemhandler.h
new file mode 100644
index 0000000..82cfc53
--- /dev/null
+++ b/fpdfsdk/cfx_systemhandler.h
@@ -0,0 +1,78 @@
+// 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_CFX_SYSTEMHANDLER_H_
+#define FPDFSDK_CFX_SYSTEMHANDLER_H_
+
+#include "core/fxcrt/fx_coordinates.h"
+#include "core/fxcrt/fx_system.h"
+
+using TimerCallback = void (*)(int32_t idEvent);
+
+struct FX_SYSTEMTIME {
+  FX_SYSTEMTIME()
+      : wYear(0),
+        wMonth(0),
+        wDayOfWeek(0),
+        wDay(0),
+        wHour(0),
+        wMinute(0),
+        wSecond(0),
+        wMilliseconds(0) {}
+
+  uint16_t wYear;
+  uint16_t wMonth;
+  uint16_t wDayOfWeek;
+  uint16_t wDay;
+  uint16_t wHour;
+  uint16_t wMinute;
+  uint16_t wSecond;
+  uint16_t wMilliseconds;
+};
+
+// Cursor style. These must match the values in public/fpdf_formfill.h
+#define FXCT_ARROW 0
+#define FXCT_NESW 1
+#define FXCT_NWSE 2
+#define FXCT_VBEAM 3
+#define FXCT_HBEAM 4
+#define FXCT_HAND 5
+
+class CFFL_FormFiller;
+class CPDF_Document;
+class CPDF_Font;
+class CPDFSDK_FormFillEnvironment;
+class CPDFSDK_Widget;
+
+class CFX_SystemHandler {
+ public:
+  explicit CFX_SystemHandler(CPDFSDK_FormFillEnvironment* pFormFillEnv)
+      : m_pFormFillEnv(pFormFillEnv) {}
+  ~CFX_SystemHandler() {}
+
+  void InvalidateRect(CPDFSDK_Widget* widget, FX_RECT rect);
+  void OutputSelectedRect(CFFL_FormFiller* pFormFiller, CFX_FloatRect& rect);
+  bool IsSelectionImplemented() const;
+
+  void SetCursor(int32_t nCursorType);
+
+  bool FindNativeTrueTypeFont(CFX_ByteString sFontFaceName);
+  CPDF_Font* AddNativeTrueTypeFontToPDF(CPDF_Document* pDoc,
+                                        CFX_ByteString sFontFaceName,
+                                        uint8_t nCharset);
+
+  int32_t SetTimer(int32_t uElapse, TimerCallback lpTimerFunc);
+  void KillTimer(int32_t nID);
+
+  bool IsSHIFTKeyDown(uint32_t nFlag) const;
+  bool IsCTRLKeyDown(uint32_t nFlag) const;
+  bool IsALTKeyDown(uint32_t nFlag) const;
+
+ private:
+  CPDFSDK_FormFillEnvironment* const m_pFormFillEnv;
+};
+
+#endif  // FPDFSDK_CFX_SYSTEMHANDLER_H_
diff --git a/fpdfsdk/cpdfsdk_annot.cpp b/fpdfsdk/cpdfsdk_annot.cpp
new file mode 100644
index 0000000..4dcce48
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_annot.cpp
@@ -0,0 +1,98 @@
+// 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/cpdfsdk_annot.h"
+
+#include <algorithm>
+
+#include "fpdfsdk/cpdfsdk_pageview.h"
+#include "third_party/base/stl_util.h"
+
+#ifdef PDF_ENABLE_XFA
+#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
+#endif  // PDF_ENABLE_XFA
+
+namespace {
+
+const float kMinWidth = 1.0f;
+const float kMinHeight = 1.0f;
+
+}  // namespace
+
+CPDFSDK_Annot::CPDFSDK_Annot(CPDFSDK_PageView* pPageView)
+    : m_pPageView(pPageView), m_bSelected(false) {}
+
+CPDFSDK_Annot::~CPDFSDK_Annot() {}
+
+#ifdef PDF_ENABLE_XFA
+
+bool CPDFSDK_Annot::IsXFAField() {
+  return false;
+}
+
+CXFA_FFWidget* CPDFSDK_Annot::GetXFAWidget() const {
+  return nullptr;
+}
+
+CPDFXFA_Page* CPDFSDK_Annot::GetPDFXFAPage() {
+  return m_pPageView ? m_pPageView->GetPDFXFAPage() : nullptr;
+}
+
+#endif  // PDF_ENABLE_XFA
+
+FX_FLOAT CPDFSDK_Annot::GetMinWidth() const {
+  return kMinWidth;
+}
+
+FX_FLOAT CPDFSDK_Annot::GetMinHeight() const {
+  return kMinHeight;
+}
+
+int CPDFSDK_Annot::GetLayoutOrder() const {
+  return 5;
+}
+
+CPDF_Annot* CPDFSDK_Annot::GetPDFAnnot() const {
+  return nullptr;
+}
+
+CPDF_Annot::Subtype CPDFSDK_Annot::GetAnnotSubtype() const {
+  return CPDF_Annot::Subtype::UNKNOWN;
+}
+
+bool CPDFSDK_Annot::IsSignatureWidget() const {
+  return false;
+}
+
+void CPDFSDK_Annot::SetRect(const CFX_FloatRect& rect) {}
+
+CFX_FloatRect CPDFSDK_Annot::GetRect() const {
+  return CFX_FloatRect();
+}
+
+void CPDFSDK_Annot::Annot_OnDraw(CFX_RenderDevice* pDevice,
+                                 CFX_Matrix* pUser2Device,
+                                 CPDF_RenderOptions* pOptions) {}
+
+bool CPDFSDK_Annot::IsSelected() {
+  return m_bSelected;
+}
+
+void CPDFSDK_Annot::SetSelected(bool bSelected) {
+  m_bSelected = bSelected;
+}
+
+UnderlyingPageType* CPDFSDK_Annot::GetUnderlyingPage() {
+#ifdef PDF_ENABLE_XFA
+  return GetPDFXFAPage();
+#else   // PDF_ENABLE_XFA
+  return GetPDFPage();
+#endif  // PDF_ENABLE_XFA
+}
+
+CPDF_Page* CPDFSDK_Annot::GetPDFPage() {
+  return m_pPageView ? m_pPageView->GetPDFPage() : nullptr;
+}
diff --git a/fpdfsdk/cpdfsdk_annot.h b/fpdfsdk/cpdfsdk_annot.h
new file mode 100644
index 0000000..36e7b56
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_annot.h
@@ -0,0 +1,65 @@
+// 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_CPDFSDK_ANNOT_H_
+#define FPDFSDK_CPDFSDK_ANNOT_H_
+
+#include "core/fpdfdoc/cpdf_aaction.h"
+#include "core/fpdfdoc/cpdf_annot.h"
+#include "core/fpdfdoc/cpdf_defaultappearance.h"
+#include "core/fxcrt/cfx_observable.h"
+#include "core/fxcrt/fx_basic.h"
+#include "fpdfsdk/cfx_systemhandler.h"
+#include "fpdfsdk/fsdk_common.h"
+#include "fpdfsdk/fsdk_define.h"
+
+class CFX_Matrix;
+class CFX_RenderDevice;
+class CPDF_Page;
+class CPDF_RenderOptions;
+class CPDFSDK_PageView;
+
+class CPDFSDK_Annot : public CFX_Observable<CPDFSDK_Annot> {
+ public:
+  explicit CPDFSDK_Annot(CPDFSDK_PageView* pPageView);
+  virtual ~CPDFSDK_Annot();
+
+#ifdef PDF_ENABLE_XFA
+  virtual bool IsXFAField();
+  virtual CXFA_FFWidget* GetXFAWidget() const;
+#endif  // PDF_ENABLE_XFA
+
+  virtual FX_FLOAT GetMinWidth() const;
+  virtual FX_FLOAT GetMinHeight() const;
+  virtual int GetLayoutOrder() const;
+  virtual CPDF_Annot* GetPDFAnnot() const;
+  virtual CPDF_Annot::Subtype GetAnnotSubtype() const;
+  virtual bool IsSignatureWidget() const;
+  virtual CFX_FloatRect GetRect() const;
+
+  virtual void SetRect(const CFX_FloatRect& rect);
+  virtual void Annot_OnDraw(CFX_RenderDevice* pDevice,
+                            CFX_Matrix* pUser2Device,
+                            CPDF_RenderOptions* pOptions);
+
+  UnderlyingPageType* GetUnderlyingPage();
+  CPDF_Page* GetPDFPage();
+#ifdef PDF_ENABLE_XFA
+  CPDFXFA_Page* GetPDFXFAPage();
+#endif  // PDF_ENABLE_XFA
+
+  void SetPage(CPDFSDK_PageView* pPageView);
+  CPDFSDK_PageView* GetPageView() const { return m_pPageView; }
+
+  bool IsSelected();
+  void SetSelected(bool bSelected);
+
+ protected:
+  CPDFSDK_PageView* m_pPageView;
+  bool m_bSelected;
+};
+
+#endif  // FPDFSDK_CPDFSDK_ANNOT_H_
diff --git a/fpdfsdk/cpdfsdk_annothandlermgr.cpp b/fpdfsdk/cpdfsdk_annothandlermgr.cpp
new file mode 100644
index 0000000..898b9cc
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_annothandlermgr.cpp
@@ -0,0 +1,309 @@
+// 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/cpdfsdk_annothandlermgr.h"
+
+#include "core/fpdfapi/parser/cpdf_number.h"
+#include "core/fpdfapi/parser/cpdf_string.h"
+#include "core/fpdfdoc/cpdf_annot.h"
+#include "fpdfsdk/cba_annotiterator.h"
+#include "fpdfsdk/cpdfsdk_annot.h"
+#include "fpdfsdk/cpdfsdk_baannot.h"
+#include "fpdfsdk/cpdfsdk_baannothandler.h"
+#include "fpdfsdk/cpdfsdk_datetime.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/cpdfsdk_pageview.h"
+#include "fpdfsdk/cpdfsdk_widgethandler.h"
+
+#ifdef PDF_ENABLE_XFA
+#include "fpdfsdk/cpdfsdk_xfawidgethandler.h"
+#include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
+#include "xfa/fxfa/xfa_ffpageview.h"
+#include "xfa/fxfa/xfa_ffwidget.h"
+#endif  // PDF_ENABLE_XFA
+
+CPDFSDK_AnnotHandlerMgr::CPDFSDK_AnnotHandlerMgr(
+    CPDFSDK_FormFillEnvironment* pFormFillEnv)
+    : m_pBAAnnotHandler(new CPDFSDK_BAAnnotHandler()),
+      m_pWidgetHandler(new CPDFSDK_WidgetHandler(pFormFillEnv)),
+#ifdef PDF_ENABLE_XFA
+      m_pXFAWidgetHandler(new CPDFSDK_XFAWidgetHandler(pFormFillEnv)),
+#endif  // PDF_ENABLE_XFA
+      m_pFormFillEnv(pFormFillEnv) {
+  m_pWidgetHandler->SetFormFiller(m_pFormFillEnv->GetInteractiveFormFiller());
+}
+
+CPDFSDK_AnnotHandlerMgr::~CPDFSDK_AnnotHandlerMgr() {}
+
+CPDFSDK_Annot* CPDFSDK_AnnotHandlerMgr::NewAnnot(CPDF_Annot* pAnnot,
+                                                 CPDFSDK_PageView* pPageView) {
+  ASSERT(pPageView);
+  return GetAnnotHandler(pAnnot->GetSubtype())->NewAnnot(pAnnot, pPageView);
+}
+
+#ifdef PDF_ENABLE_XFA
+CPDFSDK_Annot* CPDFSDK_AnnotHandlerMgr::NewAnnot(CXFA_FFWidget* pAnnot,
+                                                 CPDFSDK_PageView* pPageView) {
+  ASSERT(pAnnot);
+  ASSERT(pPageView);
+
+  return GetAnnotHandler(CPDF_Annot::Subtype::XFAWIDGET)
+      ->NewAnnot(pAnnot, pPageView);
+}
+#endif  // PDF_ENABLE_XFA
+
+void CPDFSDK_AnnotHandlerMgr::ReleaseAnnot(CPDFSDK_Annot* pAnnot) {
+  IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot);
+  pAnnotHandler->ReleaseAnnot(pAnnot);
+}
+
+void CPDFSDK_AnnotHandlerMgr::Annot_OnCreate(CPDFSDK_Annot* pAnnot) {
+  CPDF_Annot* pPDFAnnot = pAnnot->GetPDFAnnot();
+
+  CPDFSDK_DateTime curTime;
+  pPDFAnnot->GetAnnotDict()->SetNewFor<CPDF_String>(
+      "M", curTime.ToPDFDateTimeString(), false);
+  pPDFAnnot->GetAnnotDict()->SetNewFor<CPDF_Number>("F", 0);
+}
+
+void CPDFSDK_AnnotHandlerMgr::Annot_OnLoad(CPDFSDK_Annot* pAnnot) {
+  ASSERT(pAnnot);
+  GetAnnotHandler(pAnnot)->OnLoad(pAnnot);
+}
+
+IPDFSDK_AnnotHandler* CPDFSDK_AnnotHandlerMgr::GetAnnotHandler(
+    CPDFSDK_Annot* pAnnot) const {
+  return GetAnnotHandler(pAnnot->GetAnnotSubtype());
+}
+
+IPDFSDK_AnnotHandler* CPDFSDK_AnnotHandlerMgr::GetAnnotHandler(
+    CPDF_Annot::Subtype nAnnotSubtype) const {
+  if (nAnnotSubtype == CPDF_Annot::Subtype::WIDGET)
+    return m_pWidgetHandler.get();
+
+#ifdef PDF_ENABLE_XFA
+  if (nAnnotSubtype == CPDF_Annot::Subtype::XFAWIDGET)
+    return m_pXFAWidgetHandler.get();
+#endif  // PDF_ENABLE_XFA
+
+  return m_pBAAnnotHandler.get();
+}
+
+void CPDFSDK_AnnotHandlerMgr::Annot_OnDraw(CPDFSDK_PageView* pPageView,
+                                           CPDFSDK_Annot* pAnnot,
+                                           CFX_RenderDevice* pDevice,
+                                           CFX_Matrix* pUser2Device,
+                                           bool bDrawAnnots) {
+  ASSERT(pAnnot);
+  GetAnnotHandler(pAnnot)->OnDraw(pPageView, pAnnot, pDevice, pUser2Device,
+                                  bDrawAnnots);
+}
+
+bool CPDFSDK_AnnotHandlerMgr::Annot_OnLButtonDown(
+    CPDFSDK_PageView* pPageView,
+    CPDFSDK_Annot::ObservedPtr* pAnnot,
+    uint32_t nFlags,
+    const CFX_FloatPoint& point) {
+  ASSERT(*pAnnot);
+  return GetAnnotHandler(pAnnot->Get())
+      ->OnLButtonDown(pPageView, pAnnot, nFlags, point);
+}
+
+bool CPDFSDK_AnnotHandlerMgr::Annot_OnLButtonUp(
+    CPDFSDK_PageView* pPageView,
+    CPDFSDK_Annot::ObservedPtr* pAnnot,
+    uint32_t nFlags,
+    const CFX_FloatPoint& point) {
+  ASSERT(*pAnnot);
+  return GetAnnotHandler(pAnnot->Get())
+      ->OnLButtonUp(pPageView, pAnnot, nFlags, point);
+}
+
+bool CPDFSDK_AnnotHandlerMgr::Annot_OnLButtonDblClk(
+    CPDFSDK_PageView* pPageView,
+    CPDFSDK_Annot::ObservedPtr* pAnnot,
+    uint32_t nFlags,
+    const CFX_FloatPoint& point) {
+  ASSERT(*pAnnot);
+  return GetAnnotHandler(pAnnot->Get())
+      ->OnLButtonDblClk(pPageView, pAnnot, nFlags, point);
+}
+
+bool CPDFSDK_AnnotHandlerMgr::Annot_OnMouseMove(
+    CPDFSDK_PageView* pPageView,
+    CPDFSDK_Annot::ObservedPtr* pAnnot,
+    uint32_t nFlags,
+    const CFX_FloatPoint& point) {
+  ASSERT(*pAnnot);
+  return GetAnnotHandler(pAnnot->Get())
+      ->OnMouseMove(pPageView, pAnnot, nFlags, point);
+}
+
+bool CPDFSDK_AnnotHandlerMgr::Annot_OnMouseWheel(
+    CPDFSDK_PageView* pPageView,
+    CPDFSDK_Annot::ObservedPtr* pAnnot,
+    uint32_t nFlags,
+    short zDelta,
+    const CFX_FloatPoint& point) {
+  ASSERT(*pAnnot);
+  return GetAnnotHandler(pAnnot->Get())
+      ->OnMouseWheel(pPageView, pAnnot, nFlags, zDelta, point);
+}
+
+bool CPDFSDK_AnnotHandlerMgr::Annot_OnRButtonDown(
+    CPDFSDK_PageView* pPageView,
+    CPDFSDK_Annot::ObservedPtr* pAnnot,
+    uint32_t nFlags,
+    const CFX_FloatPoint& point) {
+  ASSERT(*pAnnot);
+  return GetAnnotHandler(pAnnot->Get())
+      ->OnRButtonDown(pPageView, pAnnot, nFlags, point);
+}
+
+bool CPDFSDK_AnnotHandlerMgr::Annot_OnRButtonUp(
+    CPDFSDK_PageView* pPageView,
+    CPDFSDK_Annot::ObservedPtr* pAnnot,
+    uint32_t nFlags,
+    const CFX_FloatPoint& point) {
+  ASSERT(*pAnnot);
+  return GetAnnotHandler(pAnnot->Get())
+      ->OnRButtonUp(pPageView, pAnnot, nFlags, point);
+}
+
+void CPDFSDK_AnnotHandlerMgr::Annot_OnMouseEnter(
+    CPDFSDK_PageView* pPageView,
+    CPDFSDK_Annot::ObservedPtr* pAnnot,
+    uint32_t nFlag) {
+  ASSERT(*pAnnot);
+  GetAnnotHandler(pAnnot->Get())->OnMouseEnter(pPageView, pAnnot, nFlag);
+}
+
+void CPDFSDK_AnnotHandlerMgr::Annot_OnMouseExit(
+    CPDFSDK_PageView* pPageView,
+    CPDFSDK_Annot::ObservedPtr* pAnnot,
+    uint32_t nFlag) {
+  ASSERT(*pAnnot);
+  GetAnnotHandler(pAnnot->Get())->OnMouseExit(pPageView, pAnnot, nFlag);
+}
+
+bool CPDFSDK_AnnotHandlerMgr::Annot_OnChar(CPDFSDK_Annot* pAnnot,
+                                           uint32_t nChar,
+                                           uint32_t nFlags) {
+  return GetAnnotHandler(pAnnot)->OnChar(pAnnot, nChar, nFlags);
+}
+
+bool CPDFSDK_AnnotHandlerMgr::Annot_OnKeyDown(CPDFSDK_Annot* pAnnot,
+                                              int nKeyCode,
+                                              int nFlag) {
+  if (m_pFormFillEnv->IsCTRLKeyDown(nFlag) ||
+      m_pFormFillEnv->IsALTKeyDown(nFlag)) {
+    return GetAnnotHandler(pAnnot)->OnKeyDown(pAnnot, nKeyCode, nFlag);
+  }
+
+  CPDFSDK_PageView* pPage = pAnnot->GetPageView();
+  CPDFSDK_Annot* pFocusAnnot = pPage->GetFocusAnnot();
+  if (pFocusAnnot && (nKeyCode == FWL_VKEY_Tab)) {
+    CPDFSDK_Annot::ObservedPtr pNext(
+        GetNextAnnot(pFocusAnnot, !m_pFormFillEnv->IsSHIFTKeyDown(nFlag)));
+    if (pNext && pNext.Get() != pFocusAnnot) {
+      pPage->GetFormFillEnv()->SetFocusAnnot(&pNext);
+      return true;
+    }
+  }
+
+  return GetAnnotHandler(pAnnot)->OnKeyDown(pAnnot, nKeyCode, nFlag);
+}
+
+bool CPDFSDK_AnnotHandlerMgr::Annot_OnKeyUp(CPDFSDK_Annot* pAnnot,
+                                            int nKeyCode,
+                                            int nFlag) {
+  return false;
+}
+
+bool CPDFSDK_AnnotHandlerMgr::Annot_OnSetFocus(
+    CPDFSDK_Annot::ObservedPtr* pAnnot,
+    uint32_t nFlag) {
+  ASSERT(*pAnnot);
+  return GetAnnotHandler(pAnnot->Get())->OnSetFocus(pAnnot, nFlag);
+}
+
+bool CPDFSDK_AnnotHandlerMgr::Annot_OnKillFocus(
+    CPDFSDK_Annot::ObservedPtr* pAnnot,
+    uint32_t nFlag) {
+  ASSERT(*pAnnot);
+  return GetAnnotHandler(pAnnot->Get())->OnKillFocus(pAnnot, nFlag);
+}
+
+#ifdef PDF_ENABLE_XFA
+bool CPDFSDK_AnnotHandlerMgr::Annot_OnChangeFocus(
+    CPDFSDK_Annot::ObservedPtr* pSetAnnot,
+    CPDFSDK_Annot::ObservedPtr* pKillAnnot) {
+  bool bXFA = (*pSetAnnot && (*pSetAnnot)->GetXFAWidget()) ||
+              (*pKillAnnot && (*pKillAnnot)->GetXFAWidget());
+
+  if (bXFA) {
+    if (IPDFSDK_AnnotHandler* pXFAAnnotHandler =
+            GetAnnotHandler(CPDF_Annot::Subtype::XFAWIDGET))
+      return pXFAAnnotHandler->OnXFAChangedFocus(pKillAnnot, pSetAnnot);
+  }
+
+  return true;
+}
+#endif  // PDF_ENABLE_XFA
+
+CFX_FloatRect CPDFSDK_AnnotHandlerMgr::Annot_OnGetViewBBox(
+    CPDFSDK_PageView* pPageView,
+    CPDFSDK_Annot* pAnnot) {
+  ASSERT(pAnnot);
+  return GetAnnotHandler(pAnnot)->GetViewBBox(pPageView, pAnnot);
+}
+
+bool CPDFSDK_AnnotHandlerMgr::Annot_OnHitTest(CPDFSDK_PageView* pPageView,
+                                              CPDFSDK_Annot* pAnnot,
+                                              const CFX_FloatPoint& point) {
+  ASSERT(pAnnot);
+  IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot);
+  if (pAnnotHandler->CanAnswer(pAnnot))
+    return pAnnotHandler->HitTest(pPageView, pAnnot, point);
+
+  return false;
+}
+
+CPDFSDK_Annot* CPDFSDK_AnnotHandlerMgr::GetNextAnnot(CPDFSDK_Annot* pSDKAnnot,
+                                                     bool bNext) {
+#ifdef PDF_ENABLE_XFA
+  CPDFSDK_PageView* pPageView = pSDKAnnot->GetPageView();
+  CPDFXFA_Page* pPage = pPageView->GetPDFXFAPage();
+  if (!pPage)
+    return nullptr;
+  if (pPage->GetPDFPage()) {  // for pdf annots.
+    CBA_AnnotIterator ai(pSDKAnnot->GetPageView(),
+                         pSDKAnnot->GetAnnotSubtype());
+    CPDFSDK_Annot* pNext =
+        bNext ? ai.GetNextAnnot(pSDKAnnot) : ai.GetPrevAnnot(pSDKAnnot);
+    return pNext;
+  }
+  // for xfa annots
+  std::unique_ptr<IXFA_WidgetIterator> pWidgetIterator(
+      pPage->GetXFAPageView()->CreateWidgetIterator(
+          XFA_TRAVERSEWAY_Tranvalse, XFA_WidgetStatus_Visible |
+                                         XFA_WidgetStatus_Viewable |
+                                         XFA_WidgetStatus_Focused));
+  if (!pWidgetIterator)
+    return nullptr;
+  if (pWidgetIterator->GetCurrentWidget() != pSDKAnnot->GetXFAWidget())
+    pWidgetIterator->SetCurrentWidget(pSDKAnnot->GetXFAWidget());
+  CXFA_FFWidget* hNextFocus =
+      bNext ? pWidgetIterator->MoveToNext() : pWidgetIterator->MoveToPrevious();
+  if (!hNextFocus && pSDKAnnot)
+    hNextFocus = pWidgetIterator->MoveToFirst();
+
+  return pPageView->GetAnnotByXFAWidget(hNextFocus);
+#else   // PDF_ENABLE_XFA
+  CBA_AnnotIterator ai(pSDKAnnot->GetPageView(), CPDF_Annot::Subtype::WIDGET);
+  return bNext ? ai.GetNextAnnot(pSDKAnnot) : ai.GetPrevAnnot(pSDKAnnot);
+#endif  // PDF_ENABLE_XFA
+}
diff --git a/fpdfsdk/cpdfsdk_annothandlermgr.h b/fpdfsdk/cpdfsdk_annothandlermgr.h
new file mode 100644
index 0000000..7742fd6
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_annothandlermgr.h
@@ -0,0 +1,118 @@
+// 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_CPDFSDK_ANNOTHANDLERMGR_H_
+#define FPDFSDK_CPDFSDK_ANNOTHANDLERMGR_H_
+
+#include <map>
+#include <memory>
+
+#include "core/fpdfdoc/cpdf_annot.h"
+#include "core/fxcrt/fx_basic.h"
+#include "core/fxcrt/fx_coordinates.h"
+#include "fpdfsdk/cpdfsdk_annot.h"
+
+class CFX_Matrix;
+class CFX_RenderDevice;
+class CPDFSDK_FormFillEnvironment;
+class CPDFSDK_BAAnnotHandler;
+class CPDFSDK_WidgetHandler;
+class CPDFSDK_PageView;
+class IPDFSDK_AnnotHandler;
+
+#ifdef PDF_ENABLE_XFA
+class CPDFSDK_XFAWidgetHandler;
+class CXFA_FFWidget;
+#endif  // PDF_ENABLE_XFA
+
+class CPDFSDK_AnnotHandlerMgr {
+ public:
+  explicit CPDFSDK_AnnotHandlerMgr(CPDFSDK_FormFillEnvironment* pApp);
+  ~CPDFSDK_AnnotHandlerMgr();
+
+  CPDFSDK_Annot* NewAnnot(CPDF_Annot* pAnnot, CPDFSDK_PageView* pPageView);
+#ifdef PDF_ENABLE_XFA
+  CPDFSDK_Annot* NewAnnot(CXFA_FFWidget* pAnnot, CPDFSDK_PageView* pPageView);
+#endif  // PDF_ENABLE_XFA
+  void ReleaseAnnot(CPDFSDK_Annot* pAnnot);
+
+  void Annot_OnCreate(CPDFSDK_Annot* pAnnot);
+  void Annot_OnLoad(CPDFSDK_Annot* pAnnot);
+
+  IPDFSDK_AnnotHandler* GetAnnotHandler(CPDFSDK_Annot* pAnnot) const;
+  void Annot_OnDraw(CPDFSDK_PageView* pPageView,
+                    CPDFSDK_Annot* pAnnot,
+                    CFX_RenderDevice* pDevice,
+                    CFX_Matrix* pUser2Device,
+                    bool bDrawAnnots);
+
+  void Annot_OnMouseEnter(CPDFSDK_PageView* pPageView,
+                          CPDFSDK_Annot::ObservedPtr* pAnnot,
+                          uint32_t nFlags);
+  void Annot_OnMouseExit(CPDFSDK_PageView* pPageView,
+                         CPDFSDK_Annot::ObservedPtr* pAnnot,
+                         uint32_t nFlags);
+  bool Annot_OnLButtonDown(CPDFSDK_PageView* pPageView,
+                           CPDFSDK_Annot::ObservedPtr* pAnnot,
+                           uint32_t nFlags,
+                           const CFX_FloatPoint& point);
+  bool Annot_OnLButtonUp(CPDFSDK_PageView* pPageView,
+                         CPDFSDK_Annot::ObservedPtr* pAnnot,
+                         uint32_t nFlags,
+                         const CFX_FloatPoint& point);
+  bool Annot_OnLButtonDblClk(CPDFSDK_PageView* pPageView,
+                             CPDFSDK_Annot::ObservedPtr* pAnnot,
+                             uint32_t nFlags,
+                             const CFX_FloatPoint& point);
+  bool Annot_OnMouseMove(CPDFSDK_PageView* pPageView,
+                         CPDFSDK_Annot::ObservedPtr* pAnnot,
+                         uint32_t nFlags,
+                         const CFX_FloatPoint& point);
+  bool Annot_OnMouseWheel(CPDFSDK_PageView* pPageView,
+                          CPDFSDK_Annot::ObservedPtr* pAnnot,
+                          uint32_t nFlags,
+                          short zDelta,
+                          const CFX_FloatPoint& point);
+  bool Annot_OnRButtonDown(CPDFSDK_PageView* pPageView,
+                           CPDFSDK_Annot::ObservedPtr* pAnnot,
+                           uint32_t nFlags,
+                           const CFX_FloatPoint& point);
+  bool Annot_OnRButtonUp(CPDFSDK_PageView* pPageView,
+                         CPDFSDK_Annot::ObservedPtr* pAnnot,
+                         uint32_t nFlags,
+                         const CFX_FloatPoint& point);
+  bool Annot_OnChar(CPDFSDK_Annot* pAnnot, uint32_t nChar, uint32_t nFlags);
+  bool Annot_OnKeyDown(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag);
+  bool Annot_OnKeyUp(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag);
+
+  bool Annot_OnSetFocus(CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlag);
+  bool Annot_OnKillFocus(CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlag);
+
+#ifdef PDF_ENABLE_XFA
+  bool Annot_OnChangeFocus(CPDFSDK_Annot::ObservedPtr* pSetAnnot,
+                           CPDFSDK_Annot::ObservedPtr* pKillAnnot);
+#endif  // PDF_ENABLE_XFA
+
+  CFX_FloatRect Annot_OnGetViewBBox(CPDFSDK_PageView* pPageView,
+                                    CPDFSDK_Annot* pAnnot);
+  bool Annot_OnHitTest(CPDFSDK_PageView* pPageView,
+                       CPDFSDK_Annot* pAnnot,
+                       const CFX_FloatPoint& point);
+
+ private:
+  IPDFSDK_AnnotHandler* GetAnnotHandler(CPDF_Annot::Subtype nSubtype) const;
+  CPDFSDK_Annot* GetNextAnnot(CPDFSDK_Annot* pSDKAnnot, bool bNext);
+
+  std::unique_ptr<CPDFSDK_BAAnnotHandler> m_pBAAnnotHandler;
+  std::unique_ptr<CPDFSDK_WidgetHandler> m_pWidgetHandler;
+#ifdef PDF_ENABLE_XFA
+  std::unique_ptr<CPDFSDK_XFAWidgetHandler> m_pXFAWidgetHandler;
+#endif  // PDF_ENABLE_XFA
+
+  CPDFSDK_FormFillEnvironment* m_pFormFillEnv;
+};
+
+#endif  // FPDFSDK_CPDFSDK_ANNOTHANDLERMGR_H_
diff --git a/fpdfsdk/cpdfsdk_annotiteration.cpp b/fpdfsdk/cpdfsdk_annotiteration.cpp
new file mode 100644
index 0000000..dd99ade
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_annotiteration.cpp
@@ -0,0 +1,40 @@
+// Copyright 2017 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/cpdfsdk_annotiteration.h"
+
+#include <algorithm>
+#include <utility>
+
+#include "fpdfsdk/cpdfsdk_annot.h"
+#include "fpdfsdk/cpdfsdk_pageview.h"
+
+CPDFSDK_AnnotIteration::CPDFSDK_AnnotIteration(CPDFSDK_PageView* pPageView,
+                                               bool bReverse) {
+  // Copying/sorting ObservedPtrs is expensive, so do it once at the end.
+  std::vector<CPDFSDK_Annot*> copiedList = pPageView->GetAnnotList();
+  std::stable_sort(copiedList.begin(), copiedList.end(),
+                   [](const CPDFSDK_Annot* p1, const CPDFSDK_Annot* p2) {
+                     return p1->GetLayoutOrder() < p2->GetLayoutOrder();
+                   });
+
+  CPDFSDK_Annot* pTopMostAnnot = pPageView->GetFocusAnnot();
+  if (pTopMostAnnot) {
+    auto it = std::find(copiedList.begin(), copiedList.end(), pTopMostAnnot);
+    if (it != copiedList.end()) {
+      copiedList.erase(it);
+      copiedList.insert(copiedList.begin(), pTopMostAnnot);
+    }
+  }
+  if (bReverse)
+    std::reverse(copiedList.begin(), copiedList.end());
+
+  m_List.reserve(copiedList.size());
+  for (const auto& pAnnot : copiedList)
+    m_List.emplace_back(pAnnot);
+}
+
+CPDFSDK_AnnotIteration::~CPDFSDK_AnnotIteration() {}
diff --git a/fpdfsdk/cpdfsdk_annotiteration.h b/fpdfsdk/cpdfsdk_annotiteration.h
new file mode 100644
index 0000000..70edfd1
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_annotiteration.h
@@ -0,0 +1,31 @@
+// Copyright 2017 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_CPDFSDK_ANNOTITERATION_H_
+#define FPDFSDK_CPDFSDK_ANNOTITERATION_H_
+
+#include <vector>
+
+#include "fpdfsdk/cpdfsdk_annot.h"
+
+class CPDFSDK_PageView;
+
+class CPDFSDK_AnnotIteration {
+ public:
+  using const_iterator =
+      std::vector<CPDFSDK_Annot::ObservedPtr>::const_iterator;
+
+  CPDFSDK_AnnotIteration(CPDFSDK_PageView* pPageView, bool bReverse);
+  ~CPDFSDK_AnnotIteration();
+
+  const_iterator begin() const { return m_List.begin(); }
+  const_iterator end() const { return m_List.end(); }
+
+ private:
+  std::vector<CPDFSDK_Annot::ObservedPtr> m_List;
+};
+
+#endif  // FPDFSDK_CPDFSDK_ANNOTITERATION_H_
diff --git a/fpdfsdk/cpdfsdk_baannot.cpp b/fpdfsdk/cpdfsdk_baannot.cpp
new file mode 100644
index 0000000..3eedf15
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_baannot.cpp
@@ -0,0 +1,400 @@
+// 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/cpdfsdk_baannot.h"
+
+#include <algorithm>
+#include <utility>
+
+#include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/cpdf_name.h"
+#include "core/fpdfapi/parser/cpdf_number.h"
+#include "core/fpdfapi/parser/cpdf_reference.h"
+#include "core/fpdfapi/parser/cpdf_stream.h"
+#include "core/fpdfapi/parser/cpdf_string.h"
+#include "core/fpdfapi/parser/fpdf_parser_decode.h"
+#include "fpdfsdk/cpdfsdk_datetime.h"
+#include "fpdfsdk/cpdfsdk_pageview.h"
+
+CPDFSDK_BAAnnot::CPDFSDK_BAAnnot(CPDF_Annot* pAnnot,
+                                 CPDFSDK_PageView* pPageView)
+    : CPDFSDK_Annot(pPageView), m_pAnnot(pAnnot) {}
+
+CPDFSDK_BAAnnot::~CPDFSDK_BAAnnot() {}
+
+CPDF_Annot* CPDFSDK_BAAnnot::GetPDFAnnot() const {
+  return m_pAnnot;
+}
+
+CPDF_Annot* CPDFSDK_BAAnnot::GetPDFPopupAnnot() const {
+  return m_pAnnot->GetPopupAnnot();
+}
+
+CPDF_Dictionary* CPDFSDK_BAAnnot::GetAnnotDict() const {
+  return m_pAnnot->GetAnnotDict();
+}
+
+void CPDFSDK_BAAnnot::SetRect(const CFX_FloatRect& rect) {
+  ASSERT(rect.right - rect.left >= GetMinWidth());
+  ASSERT(rect.top - rect.bottom >= GetMinHeight());
+
+  m_pAnnot->GetAnnotDict()->SetRectFor("Rect", rect);
+}
+
+CFX_FloatRect CPDFSDK_BAAnnot::GetRect() const {
+  return m_pAnnot->GetRect();
+}
+
+CPDF_Annot::Subtype CPDFSDK_BAAnnot::GetAnnotSubtype() const {
+  return m_pAnnot->GetSubtype();
+}
+
+void CPDFSDK_BAAnnot::DrawAppearance(CFX_RenderDevice* pDevice,
+                                     const CFX_Matrix* pUser2Device,
+                                     CPDF_Annot::AppearanceMode mode,
+                                     const CPDF_RenderOptions* pOptions) {
+  m_pAnnot->DrawAppearance(m_pPageView->GetPDFPage(), pDevice, pUser2Device,
+                           mode, pOptions);
+}
+
+bool CPDFSDK_BAAnnot::IsAppearanceValid() {
+  return !!m_pAnnot->GetAnnotDict()->GetDictFor("AP");
+}
+
+bool CPDFSDK_BAAnnot::IsAppearanceValid(CPDF_Annot::AppearanceMode mode) {
+  CPDF_Dictionary* pAP = m_pAnnot->GetAnnotDict()->GetDictFor("AP");
+  if (!pAP)
+    return false;
+
+  // Choose the right sub-ap
+  const FX_CHAR* ap_entry = "N";
+  if (mode == CPDF_Annot::Down)
+    ap_entry = "D";
+  else if (mode == CPDF_Annot::Rollover)
+    ap_entry = "R";
+  if (!pAP->KeyExist(ap_entry))
+    ap_entry = "N";
+
+  // Get the AP stream or subdirectory
+  CPDF_Object* psub = pAP->GetDirectObjectFor(ap_entry);
+  return !!psub;
+}
+
+void CPDFSDK_BAAnnot::DrawBorder(CFX_RenderDevice* pDevice,
+                                 const CFX_Matrix* pUser2Device,
+                                 const CPDF_RenderOptions* pOptions) {
+  m_pAnnot->DrawBorder(pDevice, pUser2Device, pOptions);
+}
+
+void CPDFSDK_BAAnnot::ClearCachedAP() {
+  m_pAnnot->ClearCachedAP();
+}
+
+void CPDFSDK_BAAnnot::SetContents(const CFX_WideString& sContents) {
+  if (sContents.IsEmpty()) {
+    m_pAnnot->GetAnnotDict()->RemoveFor("Contents");
+  } else {
+    m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_String>(
+        "Contents", PDF_EncodeText(sContents), false);
+  }
+}
+
+CFX_WideString CPDFSDK_BAAnnot::GetContents() const {
+  return m_pAnnot->GetAnnotDict()->GetUnicodeTextFor("Contents");
+}
+
+void CPDFSDK_BAAnnot::SetAnnotName(const CFX_WideString& sName) {
+  if (sName.IsEmpty()) {
+    m_pAnnot->GetAnnotDict()->RemoveFor("NM");
+  } else {
+    m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_String>(
+        "NM", PDF_EncodeText(sName), false);
+  }
+}
+
+CFX_WideString CPDFSDK_BAAnnot::GetAnnotName() const {
+  return m_pAnnot->GetAnnotDict()->GetUnicodeTextFor("NM");
+}
+
+void CPDFSDK_BAAnnot::SetModifiedDate(const FX_SYSTEMTIME& st) {
+  CPDFSDK_DateTime dt(st);
+  CFX_ByteString str = dt.ToPDFDateTimeString();
+  if (str.IsEmpty())
+    m_pAnnot->GetAnnotDict()->RemoveFor("M");
+  else
+    m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_String>("M", str, false);
+}
+
+FX_SYSTEMTIME CPDFSDK_BAAnnot::GetModifiedDate() const {
+  FX_SYSTEMTIME systime;
+  CFX_ByteString str = m_pAnnot->GetAnnotDict()->GetStringFor("M");
+  CPDFSDK_DateTime dt(str);
+  dt.ToSystemTime(systime);
+  return systime;
+}
+
+void CPDFSDK_BAAnnot::SetFlags(uint32_t nFlags) {
+  m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_Number>("F",
+                                                   static_cast<int>(nFlags));
+}
+
+uint32_t CPDFSDK_BAAnnot::GetFlags() const {
+  return m_pAnnot->GetAnnotDict()->GetIntegerFor("F");
+}
+
+void CPDFSDK_BAAnnot::SetAppState(const CFX_ByteString& str) {
+  if (str.IsEmpty())
+    m_pAnnot->GetAnnotDict()->RemoveFor("AS");
+  else
+    m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_String>("AS", str, false);
+}
+
+CFX_ByteString CPDFSDK_BAAnnot::GetAppState() const {
+  return m_pAnnot->GetAnnotDict()->GetStringFor("AS");
+}
+
+void CPDFSDK_BAAnnot::SetStructParent(int key) {
+  m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_Number>("StructParent", key);
+}
+
+int CPDFSDK_BAAnnot::GetStructParent() const {
+  return m_pAnnot->GetAnnotDict()->GetIntegerFor("StructParent");
+}
+
+// border
+void CPDFSDK_BAAnnot::SetBorderWidth(int nWidth) {
+  CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArrayFor("Border");
+  if (pBorder) {
+    pBorder->SetNewAt<CPDF_Number>(2, nWidth);
+  } else {
+    CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictFor("BS");
+    if (!pBSDict)
+      pBSDict = m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_Dictionary>("BS");
+
+    pBSDict->SetNewFor<CPDF_Number>("W", nWidth);
+  }
+}
+
+int CPDFSDK_BAAnnot::GetBorderWidth() const {
+  if (CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArrayFor("Border"))
+    return pBorder->GetIntegerAt(2);
+
+  if (CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictFor("BS"))
+    return pBSDict->GetIntegerFor("W", 1);
+
+  return 1;
+}
+
+void CPDFSDK_BAAnnot::SetBorderStyle(BorderStyle nStyle) {
+  CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictFor("BS");
+  if (!pBSDict)
+    pBSDict = m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_Dictionary>("BS");
+
+  switch (nStyle) {
+    case BorderStyle::SOLID:
+      pBSDict->SetNewFor<CPDF_Name>("S", "S");
+      break;
+    case BorderStyle::DASH:
+      pBSDict->SetNewFor<CPDF_Name>("S", "D");
+      break;
+    case BorderStyle::BEVELED:
+      pBSDict->SetNewFor<CPDF_Name>("S", "B");
+      break;
+    case BorderStyle::INSET:
+      pBSDict->SetNewFor<CPDF_Name>("S", "I");
+      break;
+    case BorderStyle::UNDERLINE:
+      pBSDict->SetNewFor<CPDF_Name>("S", "U");
+      break;
+    default:
+      break;
+  }
+}
+
+BorderStyle CPDFSDK_BAAnnot::GetBorderStyle() const {
+  CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictFor("BS");
+  if (pBSDict) {
+    CFX_ByteString sBorderStyle = pBSDict->GetStringFor("S", "S");
+    if (sBorderStyle == "S")
+      return BorderStyle::SOLID;
+    if (sBorderStyle == "D")
+      return BorderStyle::DASH;
+    if (sBorderStyle == "B")
+      return BorderStyle::BEVELED;
+    if (sBorderStyle == "I")
+      return BorderStyle::INSET;
+    if (sBorderStyle == "U")
+      return BorderStyle::UNDERLINE;
+  }
+
+  CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArrayFor("Border");
+  if (pBorder) {
+    if (pBorder->GetCount() >= 4) {
+      CPDF_Array* pDP = pBorder->GetArrayAt(3);
+      if (pDP && pDP->GetCount() > 0)
+        return BorderStyle::DASH;
+    }
+  }
+
+  return BorderStyle::SOLID;
+}
+
+void CPDFSDK_BAAnnot::SetColor(FX_COLORREF color) {
+  CPDF_Array* pArray = m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_Array>("C");
+  pArray->AddNew<CPDF_Number>(static_cast<FX_FLOAT>(FXSYS_GetRValue(color)) /
+                              255.0f);
+  pArray->AddNew<CPDF_Number>(static_cast<FX_FLOAT>(FXSYS_GetGValue(color)) /
+                              255.0f);
+  pArray->AddNew<CPDF_Number>(static_cast<FX_FLOAT>(FXSYS_GetBValue(color)) /
+                              255.0f);
+}
+
+void CPDFSDK_BAAnnot::RemoveColor() {
+  m_pAnnot->GetAnnotDict()->RemoveFor("C");
+}
+
+bool CPDFSDK_BAAnnot::GetColor(FX_COLORREF& color) const {
+  if (CPDF_Array* pEntry = m_pAnnot->GetAnnotDict()->GetArrayFor("C")) {
+    size_t nCount = pEntry->GetCount();
+    if (nCount == 1) {
+      FX_FLOAT g = pEntry->GetNumberAt(0) * 255;
+
+      color = FXSYS_RGB((int)g, (int)g, (int)g);
+
+      return true;
+    } else if (nCount == 3) {
+      FX_FLOAT r = pEntry->GetNumberAt(0) * 255;
+      FX_FLOAT g = pEntry->GetNumberAt(1) * 255;
+      FX_FLOAT b = pEntry->GetNumberAt(2) * 255;
+
+      color = FXSYS_RGB((int)r, (int)g, (int)b);
+
+      return true;
+    } else if (nCount == 4) {
+      FX_FLOAT c = pEntry->GetNumberAt(0);
+      FX_FLOAT m = pEntry->GetNumberAt(1);
+      FX_FLOAT y = pEntry->GetNumberAt(2);
+      FX_FLOAT k = pEntry->GetNumberAt(3);
+
+      FX_FLOAT r = 1.0f - std::min(1.0f, c + k);
+      FX_FLOAT g = 1.0f - std::min(1.0f, m + k);
+      FX_FLOAT b = 1.0f - std::min(1.0f, y + k);
+
+      color = FXSYS_RGB((int)(r * 255), (int)(g * 255), (int)(b * 255));
+
+      return true;
+    }
+  }
+
+  return false;
+}
+
+void CPDFSDK_BAAnnot::WriteAppearance(const CFX_ByteString& sAPType,
+                                      const CFX_FloatRect& rcBBox,
+                                      const CFX_Matrix& matrix,
+                                      const CFX_ByteString& sContents,
+                                      const CFX_ByteString& sAPState) {
+  CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDictFor("AP");
+  if (!pAPDict)
+    pAPDict = m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_Dictionary>("AP");
+
+  CPDF_Stream* pStream = nullptr;
+  CPDF_Dictionary* pParentDict = nullptr;
+  if (sAPState.IsEmpty()) {
+    pParentDict = pAPDict;
+    pStream = pAPDict->GetStreamFor(sAPType);
+  } else {
+    CPDF_Dictionary* pAPTypeDict = pAPDict->GetDictFor(sAPType);
+    if (!pAPTypeDict)
+      pAPTypeDict = pAPDict->SetNewFor<CPDF_Dictionary>(sAPType);
+
+    pParentDict = pAPTypeDict;
+    pStream = pAPTypeDict->GetStreamFor(sAPState);
+  }
+
+  if (!pStream) {
+    CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
+    pStream = pDoc->NewIndirect<CPDF_Stream>();
+    pParentDict->SetNewFor<CPDF_Reference>(sAPType, pDoc, pStream->GetObjNum());
+  }
+
+  CPDF_Dictionary* pStreamDict = pStream->GetDict();
+  if (!pStreamDict) {
+    auto pNewDict = pdfium::MakeUnique<CPDF_Dictionary>(
+        m_pAnnot->GetDocument()->GetByteStringPool());
+    pStreamDict = pNewDict.get();
+    pStreamDict->SetNewFor<CPDF_Name>("Type", "XObject");
+    pStreamDict->SetNewFor<CPDF_Name>("Subtype", "Form");
+    pStreamDict->SetNewFor<CPDF_Number>("FormType", 1);
+    pStream->InitStream(nullptr, 0, std::move(pNewDict));
+  }
+  pStreamDict->SetMatrixFor("Matrix", matrix);
+  pStreamDict->SetRectFor("BBox", rcBBox);
+  pStream->SetData((uint8_t*)sContents.c_str(), sContents.GetLength());
+}
+
+bool CPDFSDK_BAAnnot::IsVisible() const {
+  uint32_t nFlags = GetFlags();
+  return !((nFlags & ANNOTFLAG_INVISIBLE) || (nFlags & ANNOTFLAG_HIDDEN) ||
+           (nFlags & ANNOTFLAG_NOVIEW));
+}
+
+CPDF_Action CPDFSDK_BAAnnot::GetAction() const {
+  return CPDF_Action(m_pAnnot->GetAnnotDict()->GetDictFor("A"));
+}
+
+void CPDFSDK_BAAnnot::SetAction(const CPDF_Action& action) {
+  CPDF_Dictionary* pDict = action.GetDict();
+  if (pDict != m_pAnnot->GetAnnotDict()->GetDictFor("A")) {
+    CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
+    if (pDict->IsInline())
+      pDict = pDoc->AddIndirectObject(pDict->Clone())->AsDictionary();
+    m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_Reference>("A", pDoc,
+                                                        pDict->GetObjNum());
+  }
+}
+
+void CPDFSDK_BAAnnot::RemoveAction() {
+  m_pAnnot->GetAnnotDict()->RemoveFor("A");
+}
+
+CPDF_AAction CPDFSDK_BAAnnot::GetAAction() const {
+  return CPDF_AAction(m_pAnnot->GetAnnotDict()->GetDictFor("AA"));
+}
+
+void CPDFSDK_BAAnnot::SetAAction(const CPDF_AAction& aa) {
+  if (aa.GetDict() != m_pAnnot->GetAnnotDict()->GetDictFor("AA"))
+    m_pAnnot->GetAnnotDict()->SetFor("AA", pdfium::WrapUnique(aa.GetDict()));
+}
+
+void CPDFSDK_BAAnnot::RemoveAAction() {
+  m_pAnnot->GetAnnotDict()->RemoveFor("AA");
+}
+
+CPDF_Action CPDFSDK_BAAnnot::GetAAction(CPDF_AAction::AActionType eAAT) {
+  CPDF_AAction AAction = GetAAction();
+  if (AAction.ActionExist(eAAT))
+    return AAction.GetAction(eAAT);
+
+  if (eAAT == CPDF_AAction::ButtonUp)
+    return GetAction();
+
+  return CPDF_Action();
+}
+
+void CPDFSDK_BAAnnot::Annot_OnDraw(CFX_RenderDevice* pDevice,
+                                   CFX_Matrix* pUser2Device,
+                                   CPDF_RenderOptions* pOptions) {
+  m_pAnnot->GetAPForm(m_pPageView->GetPDFPage(), CPDF_Annot::Normal);
+  m_pAnnot->DrawAppearance(m_pPageView->GetPDFPage(), pDevice, pUser2Device,
+                           CPDF_Annot::Normal, nullptr);
+}
+
+void CPDFSDK_BAAnnot::SetOpenState(bool bOpenState) {
+  if (CPDF_Annot* pAnnot = m_pAnnot->GetPopupAnnot())
+    pAnnot->SetOpenState(bOpenState);
+}
diff --git a/fpdfsdk/cpdfsdk_baannot.h b/fpdfsdk/cpdfsdk_baannot.h
new file mode 100644
index 0000000..2da5723
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_baannot.h
@@ -0,0 +1,106 @@
+// 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_CPDFSDK_BAANNOT_H_
+#define FPDFSDK_CPDFSDK_BAANNOT_H_
+
+#include "core/fpdfdoc/cpdf_aaction.h"
+#include "core/fpdfdoc/cpdf_action.h"
+#include "core/fpdfdoc/cpdf_annot.h"
+#include "core/fpdfdoc/cpdf_defaultappearance.h"
+#include "core/fxcrt/fx_coordinates.h"
+#include "core/fxcrt/fx_string.h"
+#include "fpdfsdk/cfx_systemhandler.h"
+#include "fpdfsdk/cpdfsdk_annot.h"
+
+class CFX_Matrix;
+class CFX_RenderDevice;
+class CPDF_Dictionary;
+class CPDF_RenderOptions;
+class CPDFSDK_PageView;
+
+class CPDFSDK_BAAnnot : public CPDFSDK_Annot {
+ public:
+  CPDFSDK_BAAnnot(CPDF_Annot* pAnnot, CPDFSDK_PageView* pPageView);
+  ~CPDFSDK_BAAnnot() override;
+
+  // CPDFSDK_Annot
+  CPDF_Annot::Subtype GetAnnotSubtype() const override;
+  void SetRect(const CFX_FloatRect& rect) override;
+  CFX_FloatRect GetRect() const override;
+  CPDF_Annot* GetPDFAnnot() const override;
+  void Annot_OnDraw(CFX_RenderDevice* pDevice,
+                    CFX_Matrix* pUser2Device,
+                    CPDF_RenderOptions* pOptions) override;
+
+  CPDF_Dictionary* GetAnnotDict() const;
+  CPDF_Annot* GetPDFPopupAnnot() const;
+
+  void SetContents(const CFX_WideString& sContents);
+  CFX_WideString GetContents() const;
+
+  void SetAnnotName(const CFX_WideString& sName);
+  CFX_WideString GetAnnotName() const;
+
+  void SetModifiedDate(const FX_SYSTEMTIME& st);
+  FX_SYSTEMTIME GetModifiedDate() const;
+
+  void SetFlags(uint32_t nFlags);
+  uint32_t GetFlags() const;
+
+  void SetAppState(const CFX_ByteString& str);
+  CFX_ByteString GetAppState() const;
+
+  void SetStructParent(int key);
+  int GetStructParent() const;
+
+  void SetBorderWidth(int nWidth);
+  int GetBorderWidth() const;
+
+  void SetBorderStyle(BorderStyle nStyle);
+  BorderStyle GetBorderStyle() const;
+
+  void SetColor(FX_COLORREF color);
+  void RemoveColor();
+  bool GetColor(FX_COLORREF& color) const;
+
+  bool IsVisible() const;
+
+  CPDF_Action GetAction() const;
+  void SetAction(const CPDF_Action& a);
+  void RemoveAction();
+
+  CPDF_AAction GetAAction() const;
+  void SetAAction(const CPDF_AAction& aa);
+  void RemoveAAction();
+
+  virtual CPDF_Action GetAAction(CPDF_AAction::AActionType eAAT);
+  virtual bool IsAppearanceValid();
+  virtual bool IsAppearanceValid(CPDF_Annot::AppearanceMode mode);
+  virtual void DrawAppearance(CFX_RenderDevice* pDevice,
+                              const CFX_Matrix* pUser2Device,
+                              CPDF_Annot::AppearanceMode mode,
+                              const CPDF_RenderOptions* pOptions);
+
+  void DrawBorder(CFX_RenderDevice* pDevice,
+                  const CFX_Matrix* pUser2Device,
+                  const CPDF_RenderOptions* pOptions);
+
+  void ClearCachedAP();
+
+  void WriteAppearance(const CFX_ByteString& sAPType,
+                       const CFX_FloatRect& rcBBox,
+                       const CFX_Matrix& matrix,
+                       const CFX_ByteString& sContents,
+                       const CFX_ByteString& sAPState = "");
+
+  void SetOpenState(bool bState);
+
+ protected:
+  CPDF_Annot* const m_pAnnot;
+};
+
+#endif  // FPDFSDK_CPDFSDK_BAANNOT_H_
diff --git a/fpdfsdk/cpdfsdk_baannothandler.cpp b/fpdfsdk/cpdfsdk_baannothandler.cpp
new file mode 100644
index 0000000..617d88f
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_baannothandler.cpp
@@ -0,0 +1,204 @@
+// 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/cpdfsdk_baannothandler.h"
+
+#include <memory>
+#include <vector>
+
+#include "core/fpdfapi/page/cpdf_page.h"
+#include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfdoc/cpdf_interform.h"
+#include "fpdfsdk/cpdfsdk_annot.h"
+#include "fpdfsdk/cpdfsdk_baannot.h"
+#include "fpdfsdk/cpdfsdk_pageview.h"
+#include "fpdfsdk/formfiller/cffl_formfiller.h"
+
+#ifdef PDF_ENABLE_XFA
+#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
+#endif  // PDF_ENABLE_XFA
+
+namespace {
+
+void UpdateAnnotRects(CPDFSDK_PageView* pPageView, CPDFSDK_BAAnnot* pBAAnnot) {
+  std::vector<CFX_FloatRect> rects;
+  rects.push_back(pBAAnnot->GetRect());
+  if (CPDF_Annot* pPopupAnnot = pBAAnnot->GetPDFPopupAnnot())
+    rects.push_back(pPopupAnnot->GetRect());
+
+  // Make the rects round up to avoid https://crbug.com/662804
+  for (CFX_FloatRect& rect : rects)
+    rect.Inflate(1, 1);
+
+  pPageView->UpdateRects(rects);
+}
+
+}  // namespace
+
+CPDFSDK_BAAnnotHandler::CPDFSDK_BAAnnotHandler() {}
+
+CPDFSDK_BAAnnotHandler::~CPDFSDK_BAAnnotHandler() {}
+
+bool CPDFSDK_BAAnnotHandler::CanAnswer(CPDFSDK_Annot* pAnnot) {
+  return false;
+}
+
+CPDFSDK_Annot* CPDFSDK_BAAnnotHandler::NewAnnot(CPDF_Annot* pAnnot,
+                                                CPDFSDK_PageView* pPage) {
+  return new CPDFSDK_BAAnnot(pAnnot, pPage);
+}
+
+#ifdef PDF_ENABLE_XFA
+CPDFSDK_Annot* CPDFSDK_BAAnnotHandler::NewAnnot(CXFA_FFWidget* hWidget,
+                                                CPDFSDK_PageView* pPage) {
+  return nullptr;
+}
+#endif  // PDF_ENABLE_XFA
+
+void CPDFSDK_BAAnnotHandler::ReleaseAnnot(CPDFSDK_Annot* pAnnot) {
+  delete pAnnot;
+}
+
+void CPDFSDK_BAAnnotHandler::OnDraw(CPDFSDK_PageView* pPageView,
+                                    CPDFSDK_Annot* pAnnot,
+                                    CFX_RenderDevice* pDevice,
+                                    CFX_Matrix* pUser2Device,
+                                    bool bDrawAnnots) {
+#ifdef PDF_ENABLE_XFA
+  if (pAnnot->IsXFAField())
+    return;
+#endif  // PDF_ENABLE_XFA
+  if (bDrawAnnots && pAnnot->GetAnnotSubtype() == CPDF_Annot::Subtype::POPUP) {
+    static_cast<CPDFSDK_BAAnnot*>(pAnnot)->DrawAppearance(
+        pDevice, pUser2Device, CPDF_Annot::Normal, nullptr);
+  }
+}
+
+void CPDFSDK_BAAnnotHandler::OnMouseEnter(CPDFSDK_PageView* pPageView,
+                                          CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                          uint32_t nFlag) {
+  CPDFSDK_BAAnnot* pBAAnnot = static_cast<CPDFSDK_BAAnnot*>(pAnnot->Get());
+  pBAAnnot->SetOpenState(true);
+  UpdateAnnotRects(pPageView, pBAAnnot);
+}
+
+void CPDFSDK_BAAnnotHandler::OnMouseExit(CPDFSDK_PageView* pPageView,
+                                         CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                         uint32_t nFlag) {
+  CPDFSDK_BAAnnot* pBAAnnot = static_cast<CPDFSDK_BAAnnot*>(pAnnot->Get());
+  pBAAnnot->SetOpenState(false);
+  UpdateAnnotRects(pPageView, pBAAnnot);
+}
+
+bool CPDFSDK_BAAnnotHandler::OnLButtonDown(CPDFSDK_PageView* pPageView,
+                                           CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                           uint32_t nFlags,
+                                           const CFX_FloatPoint& point) {
+  return false;
+}
+
+bool CPDFSDK_BAAnnotHandler::OnLButtonUp(CPDFSDK_PageView* pPageView,
+                                         CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                         uint32_t nFlags,
+                                         const CFX_FloatPoint& point) {
+  return false;
+}
+
+bool CPDFSDK_BAAnnotHandler::OnLButtonDblClk(CPDFSDK_PageView* pPageView,
+                                             CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                             uint32_t nFlags,
+                                             const CFX_FloatPoint& point) {
+  return false;
+}
+
+bool CPDFSDK_BAAnnotHandler::OnMouseMove(CPDFSDK_PageView* pPageView,
+                                         CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                         uint32_t nFlags,
+                                         const CFX_FloatPoint& point) {
+  return false;
+}
+
+bool CPDFSDK_BAAnnotHandler::OnMouseWheel(CPDFSDK_PageView* pPageView,
+                                          CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                          uint32_t nFlags,
+                                          short zDelta,
+                                          const CFX_FloatPoint& point) {
+  return false;
+}
+
+bool CPDFSDK_BAAnnotHandler::OnRButtonDown(CPDFSDK_PageView* pPageView,
+                                           CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                           uint32_t nFlags,
+                                           const CFX_FloatPoint& point) {
+  return false;
+}
+
+bool CPDFSDK_BAAnnotHandler::OnRButtonUp(CPDFSDK_PageView* pPageView,
+                                         CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                         uint32_t nFlags,
+                                         const CFX_FloatPoint& point) {
+  return false;
+}
+
+bool CPDFSDK_BAAnnotHandler::OnRButtonDblClk(CPDFSDK_PageView* pPageView,
+                                             CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                             uint32_t nFlags,
+                                             const CFX_FloatPoint& point) {
+  return false;
+}
+
+bool CPDFSDK_BAAnnotHandler::OnChar(CPDFSDK_Annot* pAnnot,
+                                    uint32_t nChar,
+                                    uint32_t nFlags) {
+  return false;
+}
+
+bool CPDFSDK_BAAnnotHandler::OnKeyDown(CPDFSDK_Annot* pAnnot,
+                                       int nKeyCode,
+                                       int nFlag) {
+  return false;
+}
+
+bool CPDFSDK_BAAnnotHandler::OnKeyUp(CPDFSDK_Annot* pAnnot,
+                                     int nKeyCode,
+                                     int nFlag) {
+  return false;
+}
+
+void CPDFSDK_BAAnnotHandler::OnLoad(CPDFSDK_Annot* pAnnot) {}
+
+bool CPDFSDK_BAAnnotHandler::OnSetFocus(CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                        uint32_t nFlag) {
+  return false;
+}
+
+bool CPDFSDK_BAAnnotHandler::OnKillFocus(CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                         uint32_t nFlag) {
+  return false;
+}
+
+#ifdef PDF_ENABLE_XFA
+bool CPDFSDK_BAAnnotHandler::OnXFAChangedFocus(
+    CPDFSDK_Annot::ObservedPtr* pOldAnnot,
+    CPDFSDK_Annot::ObservedPtr* pNewAnnot) {
+  return true;
+}
+#endif  // PDF_ENABLE_XFA
+
+CFX_FloatRect CPDFSDK_BAAnnotHandler::GetViewBBox(CPDFSDK_PageView* pPageView,
+                                                  CPDFSDK_Annot* pAnnot) {
+  return pAnnot->GetRect();
+}
+
+bool CPDFSDK_BAAnnotHandler::HitTest(CPDFSDK_PageView* pPageView,
+                                     CPDFSDK_Annot* pAnnot,
+                                     const CFX_FloatPoint& point) {
+  ASSERT(pPageView);
+  ASSERT(pAnnot);
+
+  CFX_FloatRect rect = GetViewBBox(pPageView, pAnnot);
+  return rect.Contains(point.x, point.y);
+}
diff --git a/fpdfsdk/cpdfsdk_baannothandler.h b/fpdfsdk/cpdfsdk_baannothandler.h
new file mode 100644
index 0000000..2efed0e
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_baannothandler.h
@@ -0,0 +1,100 @@
+// 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_CPDFSDK_BAANNOTHANDLER_H_
+#define FPDFSDK_CPDFSDK_BAANNOTHANDLER_H_
+
+#include "core/fxcrt/fx_basic.h"
+#include "core/fxcrt/fx_coordinates.h"
+#include "fpdfsdk/ipdfsdk_annothandler.h"
+
+class CFFL_InteractiveFormFiller;
+class CFX_Matrix;
+class CFX_RenderDevice;
+class CPDF_Annot;
+class CPDFSDK_FormFillEnvironment;
+class CPDFSDK_Annot;
+class CPDFSDK_PageView;
+
+#ifdef PDF_ENABLE_XFA
+class CXFA_FFWidget;
+#endif  // PDF_ENABLE_XFA
+
+class CPDFSDK_BAAnnotHandler : public IPDFSDK_AnnotHandler {
+ public:
+  CPDFSDK_BAAnnotHandler();
+  ~CPDFSDK_BAAnnotHandler() override;
+
+  bool CanAnswer(CPDFSDK_Annot* pAnnot) override;
+  CPDFSDK_Annot* NewAnnot(CPDF_Annot* pAnnot, CPDFSDK_PageView* pPage) override;
+#ifdef PDF_ENABLE_XFA
+  CPDFSDK_Annot* NewAnnot(CXFA_FFWidget* hWidget,
+                          CPDFSDK_PageView* pPage) override;
+#endif  // PDF_ENABLE_XFA
+  void ReleaseAnnot(CPDFSDK_Annot* pAnnot) override;
+  CFX_FloatRect GetViewBBox(CPDFSDK_PageView* pPageView,
+                            CPDFSDK_Annot* pAnnot) override;
+  bool HitTest(CPDFSDK_PageView* pPageView,
+               CPDFSDK_Annot* pAnnot,
+               const CFX_FloatPoint& point) override;
+  void OnDraw(CPDFSDK_PageView* pPageView,
+              CPDFSDK_Annot* pAnnot,
+              CFX_RenderDevice* pDevice,
+              CFX_Matrix* pUser2Device,
+              bool bDrawAnnots) override;
+  void OnLoad(CPDFSDK_Annot* pAnnot) override;
+
+  void OnMouseEnter(CPDFSDK_PageView* pPageView,
+                    CPDFSDK_Annot::ObservedPtr* pAnnot,
+                    uint32_t nFlag) override;
+  void OnMouseExit(CPDFSDK_PageView* pPageView,
+                   CPDFSDK_Annot::ObservedPtr* pAnnot,
+                   uint32_t nFlag) override;
+  bool OnLButtonDown(CPDFSDK_PageView* pPageView,
+                     CPDFSDK_Annot::ObservedPtr* pAnnot,
+                     uint32_t nFlags,
+                     const CFX_FloatPoint& point) override;
+  bool OnLButtonUp(CPDFSDK_PageView* pPageView,
+                   CPDFSDK_Annot::ObservedPtr* pAnnot,
+                   uint32_t nFlags,
+                   const CFX_FloatPoint& point) override;
+  bool OnLButtonDblClk(CPDFSDK_PageView* pPageView,
+                       CPDFSDK_Annot::ObservedPtr* pAnnot,
+                       uint32_t nFlags,
+                       const CFX_FloatPoint& point) override;
+  bool OnMouseMove(CPDFSDK_PageView* pPageView,
+                   CPDFSDK_Annot::ObservedPtr* pAnnot,
+                   uint32_t nFlags,
+                   const CFX_FloatPoint& point) override;
+  bool OnMouseWheel(CPDFSDK_PageView* pPageView,
+                    CPDFSDK_Annot::ObservedPtr* pAnnot,
+                    uint32_t nFlags,
+                    short zDelta,
+                    const CFX_FloatPoint& point) override;
+  bool OnRButtonDown(CPDFSDK_PageView* pPageView,
+                     CPDFSDK_Annot::ObservedPtr* pAnnot,
+                     uint32_t nFlags,
+                     const CFX_FloatPoint& point) override;
+  bool OnRButtonUp(CPDFSDK_PageView* pPageView,
+                   CPDFSDK_Annot::ObservedPtr* pAnnot,
+                   uint32_t nFlags,
+                   const CFX_FloatPoint& point) override;
+  bool OnRButtonDblClk(CPDFSDK_PageView* pPageView,
+                       CPDFSDK_Annot::ObservedPtr* pAnnot,
+                       uint32_t nFlags,
+                       const CFX_FloatPoint& point) override;
+  bool OnChar(CPDFSDK_Annot* pAnnot, uint32_t nChar, uint32_t nFlags) override;
+  bool OnKeyDown(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag) override;
+  bool OnKeyUp(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag) override;
+  bool OnSetFocus(CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlag) override;
+  bool OnKillFocus(CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlag) override;
+#ifdef PDF_ENABLE_XFA
+  bool OnXFAChangedFocus(CPDFSDK_Annot::ObservedPtr* pOldAnnot,
+                         CPDFSDK_Annot::ObservedPtr* pNewAnnot) override;
+#endif  // PDF_ENABLE_XFA
+};
+
+#endif  // FPDFSDK_CPDFSDK_BAANNOTHANDLER_H_
diff --git a/fpdfsdk/cpdfsdk_datetime.cpp b/fpdfsdk/cpdfsdk_datetime.cpp
new file mode 100644
index 0000000..72f50a6
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_datetime.cpp
@@ -0,0 +1,412 @@
+// 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/cpdfsdk_datetime.h"
+
+#include "core/fxcrt/fx_ext.h"
+
+namespace {
+
+int GetTimeZoneInSeconds(int8_t tzhour, uint8_t tzminute) {
+  return (int)tzhour * 3600 + (int)tzminute * (tzhour >= 0 ? 60 : -60);
+}
+
+bool IsLeapYear(int16_t year) {
+  return ((year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0)));
+}
+
+uint16_t GetYearDays(int16_t year) {
+  return (IsLeapYear(year) ? 366 : 365);
+}
+
+uint8_t GetMonthDays(int16_t year, uint8_t month) {
+  uint8_t mDays;
+  switch (month) {
+    case 1:
+    case 3:
+    case 5:
+    case 7:
+    case 8:
+    case 10:
+    case 12:
+      mDays = 31;
+      break;
+
+    case 4:
+    case 6:
+    case 9:
+    case 11:
+      mDays = 30;
+      break;
+
+    case 2:
+      if (IsLeapYear(year))
+        mDays = 29;
+      else
+        mDays = 28;
+      break;
+
+    default:
+      mDays = 0;
+      break;
+  }
+
+  return mDays;
+}
+
+}  // namespace
+
+CPDFSDK_DateTime::CPDFSDK_DateTime() {
+  ResetDateTime();
+}
+
+CPDFSDK_DateTime::CPDFSDK_DateTime(const CFX_ByteString& dtStr) {
+  ResetDateTime();
+  FromPDFDateTimeString(dtStr);
+}
+
+CPDFSDK_DateTime::CPDFSDK_DateTime(const CPDFSDK_DateTime& that)
+    : m_year(that.m_year),
+      m_month(that.m_month),
+      m_day(that.m_day),
+      m_hour(that.m_hour),
+      m_minute(that.m_minute),
+      m_second(that.m_second),
+      m_tzHour(that.m_tzHour),
+      m_tzMinute(that.m_tzMinute) {}
+
+CPDFSDK_DateTime::CPDFSDK_DateTime(const FX_SYSTEMTIME& st) {
+  tzset();
+
+  m_year = static_cast<int16_t>(st.wYear);
+  m_month = static_cast<uint8_t>(st.wMonth);
+  m_day = static_cast<uint8_t>(st.wDay);
+  m_hour = static_cast<uint8_t>(st.wHour);
+  m_minute = static_cast<uint8_t>(st.wMinute);
+  m_second = static_cast<uint8_t>(st.wSecond);
+}
+
+void CPDFSDK_DateTime::ResetDateTime() {
+  tzset();
+
+  time_t curTime;
+  time(&curTime);
+
+  struct tm* newtime = localtime(&curTime);
+  m_year = newtime->tm_year + 1900;
+  m_month = newtime->tm_mon + 1;
+  m_day = newtime->tm_mday;
+  m_hour = newtime->tm_hour;
+  m_minute = newtime->tm_min;
+  m_second = newtime->tm_sec;
+}
+
+bool CPDFSDK_DateTime::operator==(const CPDFSDK_DateTime& that) const {
+  return m_year == that.m_year && m_month == that.m_month &&
+         m_day == that.m_day && m_hour == that.m_hour &&
+         m_minute == that.m_minute && m_second == that.m_second &&
+         m_tzHour == that.m_tzHour && m_tzMinute == that.m_tzMinute;
+}
+
+bool CPDFSDK_DateTime::operator!=(const CPDFSDK_DateTime& datetime) const {
+  return !(*this == datetime);
+}
+
+time_t CPDFSDK_DateTime::ToTime_t() const {
+  struct tm newtime;
+
+  newtime.tm_year = m_year - 1900;
+  newtime.tm_mon = m_month - 1;
+  newtime.tm_mday = m_day;
+  newtime.tm_hour = m_hour;
+  newtime.tm_min = m_minute;
+  newtime.tm_sec = m_second;
+
+  return mktime(&newtime);
+}
+
+CPDFSDK_DateTime& CPDFSDK_DateTime::FromPDFDateTimeString(
+    const CFX_ByteString& dtStr) {
+  int strLength = dtStr.GetLength();
+  if (strLength <= 0)
+    return *this;
+
+  int i = 0;
+  while (i < strLength && !std::isdigit(dtStr[i]))
+    ++i;
+
+  if (i >= strLength)
+    return *this;
+
+  int j = 0;
+  int k = 0;
+  FX_CHAR ch;
+  while (i < strLength && j < 4) {
+    ch = dtStr[i];
+    k = k * 10 + FXSYS_toDecimalDigit(ch);
+    j++;
+    if (!std::isdigit(ch))
+      break;
+    i++;
+  }
+  m_year = static_cast<int16_t>(k);
+  if (i >= strLength || j < 4)
+    return *this;
+
+  j = 0;
+  k = 0;
+  while (i < strLength && j < 2) {
+    ch = dtStr[i];
+    k = k * 10 + FXSYS_toDecimalDigit(ch);
+    j++;
+    if (!std::isdigit(ch))
+      break;
+    i++;
+  }
+  m_month = static_cast<uint8_t>(k);
+  if (i >= strLength || j < 2)
+    return *this;
+
+  j = 0;
+  k = 0;
+  while (i < strLength && j < 2) {
+    ch = dtStr[i];
+    k = k * 10 + FXSYS_toDecimalDigit(ch);
+    j++;
+    if (!std::isdigit(ch))
+      break;
+    i++;
+  }
+  m_day = static_cast<uint8_t>(k);
+  if (i >= strLength || j < 2)
+    return *this;
+
+  j = 0;
+  k = 0;
+  while (i < strLength && j < 2) {
+    ch = dtStr[i];
+    k = k * 10 + FXSYS_toDecimalDigit(ch);
+    j++;
+    if (!std::isdigit(ch))
+      break;
+    i++;
+  }
+  m_hour = static_cast<uint8_t>(k);
+  if (i >= strLength || j < 2)
+    return *this;
+
+  j = 0;
+  k = 0;
+  while (i < strLength && j < 2) {
+    ch = dtStr[i];
+    k = k * 10 + FXSYS_toDecimalDigit(ch);
+    j++;
+    if (!std::isdigit(ch))
+      break;
+    i++;
+  }
+  m_minute = static_cast<uint8_t>(k);
+  if (i >= strLength || j < 2)
+    return *this;
+
+  j = 0;
+  k = 0;
+  while (i < strLength && j < 2) {
+    ch = dtStr[i];
+    k = k * 10 + FXSYS_toDecimalDigit(ch);
+    j++;
+    if (!std::isdigit(ch))
+      break;
+    i++;
+  }
+  m_second = static_cast<uint8_t>(k);
+  if (i >= strLength || j < 2)
+    return *this;
+
+  ch = dtStr[i++];
+  if (ch != '-' && ch != '+')
+    return *this;
+  if (ch == '-')
+    m_tzHour = -1;
+  else
+    m_tzHour = 1;
+  j = 0;
+  k = 0;
+  while (i < strLength && j < 2) {
+    ch = dtStr[i];
+    k = k * 10 + FXSYS_toDecimalDigit(ch);
+    j++;
+    if (!std::isdigit(ch))
+      break;
+    i++;
+  }
+  m_tzHour *= static_cast<int8_t>(k);
+  if (i >= strLength || j < 2)
+    return *this;
+
+  if (dtStr[i++] != '\'')
+    return *this;
+  j = 0;
+  k = 0;
+  while (i < strLength && j < 2) {
+    ch = dtStr[i];
+    k = k * 10 + FXSYS_toDecimalDigit(ch);
+    j++;
+    if (!std::isdigit(ch))
+      break;
+    i++;
+  }
+  m_tzMinute = static_cast<uint8_t>(k);
+  return *this;
+}
+
+CFX_ByteString CPDFSDK_DateTime::ToCommonDateTimeString() {
+  CFX_ByteString str1;
+  str1.Format("%04d-%02u-%02u %02u:%02u:%02u ", m_year, m_month, m_day, m_hour,
+              m_minute, m_second);
+  if (m_tzHour < 0)
+    str1 += "-";
+  else
+    str1 += "+";
+  CFX_ByteString str2;
+  str2.Format("%02d:%02u", std::abs(static_cast<int>(m_tzHour)), m_tzMinute);
+  return str1 + str2;
+}
+
+CFX_ByteString CPDFSDK_DateTime::ToPDFDateTimeString() {
+  CFX_ByteString dtStr;
+  char tempStr[32];
+  memset(tempStr, 0, sizeof(tempStr));
+  FXSYS_snprintf(tempStr, sizeof(tempStr) - 1, "D:%04d%02u%02u%02u%02u%02u",
+                 m_year, m_month, m_day, m_hour, m_minute, m_second);
+  dtStr = CFX_ByteString(tempStr);
+  if (m_tzHour < 0)
+    dtStr += CFX_ByteString("-");
+  else
+    dtStr += CFX_ByteString("+");
+  memset(tempStr, 0, sizeof(tempStr));
+  FXSYS_snprintf(tempStr, sizeof(tempStr) - 1, "%02d'%02u'",
+                 std::abs(static_cast<int>(m_tzHour)), m_tzMinute);
+  dtStr += CFX_ByteString(tempStr);
+  return dtStr;
+}
+
+void CPDFSDK_DateTime::ToSystemTime(FX_SYSTEMTIME& st) {
+  time_t t = this->ToTime_t();
+  struct tm* pTime = localtime(&t);
+
+  if (!pTime)
+    return;
+
+  st.wYear = static_cast<uint16_t>(pTime->tm_year) + 1900;
+  st.wMonth = static_cast<uint16_t>(pTime->tm_mon) + 1;
+  st.wDay = static_cast<uint16_t>(pTime->tm_mday);
+  st.wDayOfWeek = static_cast<uint16_t>(pTime->tm_wday);
+  st.wHour = static_cast<uint16_t>(pTime->tm_hour);
+  st.wMinute = static_cast<uint16_t>(pTime->tm_min);
+  st.wSecond = static_cast<uint16_t>(pTime->tm_sec);
+  st.wMilliseconds = 0;
+}
+
+CPDFSDK_DateTime CPDFSDK_DateTime::ToGMT() const {
+  CPDFSDK_DateTime new_dt = *this;
+  new_dt.AddSeconds(-GetTimeZoneInSeconds(new_dt.m_tzHour, new_dt.m_tzMinute));
+  new_dt.m_tzHour = 0;
+  new_dt.m_tzMinute = 0;
+  return new_dt;
+}
+
+CPDFSDK_DateTime& CPDFSDK_DateTime::AddDays(short days) {
+  if (days == 0)
+    return *this;
+
+  int16_t y = m_year;
+  uint8_t m = m_month;
+  uint8_t d = m_day;
+
+  int ldays = days;
+  if (ldays > 0) {
+    int16_t yy = y;
+    if ((static_cast<uint16_t>(m) * 100 + d) > 300)
+      yy++;
+    int ydays = GetYearDays(yy);
+    int mdays;
+    while (ldays >= ydays) {
+      y++;
+      ldays -= ydays;
+      yy++;
+      mdays = GetMonthDays(y, m);
+      if (d > mdays) {
+        m++;
+        d -= mdays;
+      }
+      ydays = GetYearDays(yy);
+    }
+    mdays = GetMonthDays(y, m) - d + 1;
+    while (ldays >= mdays) {
+      ldays -= mdays;
+      m++;
+      d = 1;
+      mdays = GetMonthDays(y, m);
+    }
+    d += ldays;
+  } else {
+    ldays *= -1;
+    int16_t yy = y;
+    if ((static_cast<uint16_t>(m) * 100 + d) < 300)
+      yy--;
+    int ydays = GetYearDays(yy);
+    while (ldays >= ydays) {
+      y--;
+      ldays -= ydays;
+      yy--;
+      int mdays = GetMonthDays(y, m);
+      if (d > mdays) {
+        m++;
+        d -= mdays;
+      }
+      ydays = GetYearDays(yy);
+    }
+    while (ldays >= d) {
+      ldays -= d;
+      m--;
+      d = GetMonthDays(y, m);
+    }
+    d -= ldays;
+  }
+
+  m_year = y;
+  m_month = m;
+  m_day = d;
+
+  return *this;
+}
+
+CPDFSDK_DateTime& CPDFSDK_DateTime::AddSeconds(int seconds) {
+  if (seconds == 0)
+    return *this;
+
+  int n;
+  int days;
+
+  n = m_hour * 3600 + m_minute * 60 + m_second + seconds;
+  if (n < 0) {
+    days = (n - 86399) / 86400;
+    n -= days * 86400;
+  } else {
+    days = n / 86400;
+    n %= 86400;
+  }
+  m_hour = static_cast<uint8_t>(n / 3600);
+  m_hour %= 24;
+  n %= 3600;
+  m_minute = static_cast<uint8_t>(n / 60);
+  m_second = static_cast<uint8_t>(n % 60);
+  if (days != 0)
+    AddDays(days);
+
+  return *this;
+}
diff --git a/fpdfsdk/cpdfsdk_datetime.h b/fpdfsdk/cpdfsdk_datetime.h
new file mode 100644
index 0000000..6b612b2
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_datetime.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_CPDFSDK_DATETIME_H_
+#define FPDFSDK_CPDFSDK_DATETIME_H_
+
+#if _FX_OS_ == _FX_ANDROID_
+#include <time.h>
+#else
+#include <ctime>
+#endif
+
+#include "fpdfsdk/cfx_systemhandler.h"
+
+class CPDFSDK_DateTime {
+ public:
+  CPDFSDK_DateTime();
+  explicit CPDFSDK_DateTime(const CFX_ByteString& dtStr);
+  explicit CPDFSDK_DateTime(const FX_SYSTEMTIME& st);
+  CPDFSDK_DateTime(const CPDFSDK_DateTime& datetime);
+
+  bool operator==(const CPDFSDK_DateTime& datetime) const;
+  bool operator!=(const CPDFSDK_DateTime& datetime) const;
+
+  CPDFSDK_DateTime& FromPDFDateTimeString(const CFX_ByteString& dtStr);
+  CFX_ByteString ToCommonDateTimeString();
+  CFX_ByteString ToPDFDateTimeString();
+  void ToSystemTime(FX_SYSTEMTIME& st);
+  time_t ToTime_t() const;
+  CPDFSDK_DateTime ToGMT() const;
+  CPDFSDK_DateTime& AddDays(short days);
+  CPDFSDK_DateTime& AddSeconds(int seconds);
+  void ResetDateTime();
+
+ private:
+  int16_t m_year;
+  uint8_t m_month;
+  uint8_t m_day;
+  uint8_t m_hour;
+  uint8_t m_minute;
+  uint8_t m_second;
+  int8_t m_tzHour;
+  uint8_t m_tzMinute;
+};
+
+#endif  // FPDFSDK_CPDFSDK_DATETIME_H_
diff --git a/fpdfsdk/cpdfsdk_formfillenvironment.cpp b/fpdfsdk/cpdfsdk_formfillenvironment.cpp
new file mode 100644
index 0000000..b91c978
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_formfillenvironment.cpp
@@ -0,0 +1,761 @@
+// 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/cpdfsdk_formfillenvironment.h"
+
+#include <memory>
+
+#include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfdoc/cpdf_docjsactions.h"
+#include "fpdfsdk/cpdfsdk_annothandlermgr.h"
+#include "fpdfsdk/cpdfsdk_interform.h"
+#include "fpdfsdk/cpdfsdk_pageview.h"
+#include "fpdfsdk/cpdfsdk_widget.h"
+#include "fpdfsdk/formfiller/cffl_interactiveformfiller.h"
+#include "fpdfsdk/fsdk_actionhandler.h"
+#include "fpdfsdk/javascript/ijs_runtime.h"
+#include "third_party/base/ptr_util.h"
+
+namespace {
+
+// NOTE: |bsUTF16LE| must outlive the use of the result. Care must be taken
+// since modifying the result would impact |bsUTF16LE|.
+FPDF_WIDESTRING AsFPDFWideString(CFX_ByteString* bsUTF16LE) {
+  return reinterpret_cast<FPDF_WIDESTRING>(
+      bsUTF16LE->GetBuffer(bsUTF16LE->GetLength()));
+}
+
+}  // namespace
+
+CPDFSDK_FormFillEnvironment::CPDFSDK_FormFillEnvironment(
+    UnderlyingDocumentType* pDoc,
+    FPDF_FORMFILLINFO* pFFinfo)
+    : m_pInfo(pFFinfo),
+      m_pUnderlyingDoc(pDoc),
+      m_pSysHandler(new CFX_SystemHandler(this)),
+      m_bChangeMask(false),
+      m_bBeingDestroyed(false) {}
+
+CPDFSDK_FormFillEnvironment::~CPDFSDK_FormFillEnvironment() {
+  m_bBeingDestroyed = true;
+  ClearAllFocusedAnnots();
+
+  // |m_PageMap| will try to access |m_pInterForm| when it cleans itself up.
+  // Make sure it is deleted before |m_pInterForm|.
+  m_PageMap.clear();
+
+  // |m_pAnnotHandlerMgr| will try to access |m_pFormFiller| when it cleans
+  // itself up. Make sure it is deleted before |m_pFormFiller|.
+  m_pAnnotHandlerMgr.reset();
+
+  // Must destroy the |m_pFormFiller| before the environment (|this|)
+  // because any created form widgets hold a pointer to the environment.
+  // Those widgets may call things like KillTimer() as they are shutdown.
+  m_pFormFiller.reset();
+
+  if (m_pInfo && m_pInfo->Release)
+    m_pInfo->Release(m_pInfo);
+}
+
+int CPDFSDK_FormFillEnvironment::JS_appAlert(const FX_WCHAR* Msg,
+                                             const FX_WCHAR* Title,
+                                             uint32_t Type,
+                                             uint32_t Icon) {
+  if (!m_pInfo || !m_pInfo->m_pJsPlatform ||
+      !m_pInfo->m_pJsPlatform->app_alert) {
+    return -1;
+  }
+  CFX_ByteString bsMsg = CFX_WideString(Msg).UTF16LE_Encode();
+  CFX_ByteString bsTitle = CFX_WideString(Title).UTF16LE_Encode();
+  return m_pInfo->m_pJsPlatform->app_alert(
+      m_pInfo->m_pJsPlatform, AsFPDFWideString(&bsMsg),
+      AsFPDFWideString(&bsTitle), Type, Icon);
+}
+
+int CPDFSDK_FormFillEnvironment::JS_appResponse(const FX_WCHAR* Question,
+                                                const FX_WCHAR* Title,
+                                                const FX_WCHAR* Default,
+                                                const FX_WCHAR* cLabel,
+                                                FPDF_BOOL bPassword,
+                                                void* response,
+                                                int length) {
+  if (!m_pInfo || !m_pInfo->m_pJsPlatform ||
+      !m_pInfo->m_pJsPlatform->app_response) {
+    return -1;
+  }
+  CFX_ByteString bsQuestion = CFX_WideString(Question).UTF16LE_Encode();
+  CFX_ByteString bsTitle = CFX_WideString(Title).UTF16LE_Encode();
+  CFX_ByteString bsDefault = CFX_WideString(Default).UTF16LE_Encode();
+  CFX_ByteString bsLabel = CFX_WideString(cLabel).UTF16LE_Encode();
+  return m_pInfo->m_pJsPlatform->app_response(
+      m_pInfo->m_pJsPlatform, AsFPDFWideString(&bsQuestion),
+      AsFPDFWideString(&bsTitle), AsFPDFWideString(&bsDefault),
+      AsFPDFWideString(&bsLabel), bPassword, response, length);
+}
+
+void CPDFSDK_FormFillEnvironment::JS_appBeep(int nType) {
+  if (!m_pInfo || !m_pInfo->m_pJsPlatform ||
+      !m_pInfo->m_pJsPlatform->app_beep) {
+    return;
+  }
+  m_pInfo->m_pJsPlatform->app_beep(m_pInfo->m_pJsPlatform, nType);
+}
+
+CFX_WideString CPDFSDK_FormFillEnvironment::JS_fieldBrowse() {
+  if (!m_pInfo || !m_pInfo->m_pJsPlatform ||
+      !m_pInfo->m_pJsPlatform->Field_browse) {
+    return CFX_WideString();
+  }
+  const int nRequiredLen =
+      m_pInfo->m_pJsPlatform->Field_browse(m_pInfo->m_pJsPlatform, nullptr, 0);
+  if (nRequiredLen <= 0)
+    return CFX_WideString();
+
+  std::unique_ptr<char[]> pBuff(new char[nRequiredLen]);
+  memset(pBuff.get(), 0, nRequiredLen);
+  const int nActualLen = m_pInfo->m_pJsPlatform->Field_browse(
+      m_pInfo->m_pJsPlatform, pBuff.get(), nRequiredLen);
+  if (nActualLen <= 0 || nActualLen > nRequiredLen)
+    return CFX_WideString();
+
+  return CFX_WideString::FromLocal(CFX_ByteStringC(pBuff.get(), nActualLen));
+}
+
+CFX_WideString CPDFSDK_FormFillEnvironment::JS_docGetFilePath() {
+  if (!m_pInfo || !m_pInfo->m_pJsPlatform ||
+      !m_pInfo->m_pJsPlatform->Doc_getFilePath) {
+    return CFX_WideString();
+  }
+  const int nRequiredLen = m_pInfo->m_pJsPlatform->Doc_getFilePath(
+      m_pInfo->m_pJsPlatform, nullptr, 0);
+  if (nRequiredLen <= 0)
+    return CFX_WideString();
+
+  std::unique_ptr<char[]> pBuff(new char[nRequiredLen]);
+  memset(pBuff.get(), 0, nRequiredLen);
+  const int nActualLen = m_pInfo->m_pJsPlatform->Doc_getFilePath(
+      m_pInfo->m_pJsPlatform, pBuff.get(), nRequiredLen);
+  if (nActualLen <= 0 || nActualLen > nRequiredLen)
+    return CFX_WideString();
+
+  return CFX_WideString::FromLocal(CFX_ByteStringC(pBuff.get(), nActualLen));
+}
+
+void CPDFSDK_FormFillEnvironment::JS_docSubmitForm(void* formData,
+                                                   int length,
+                                                   const FX_WCHAR* URL) {
+  if (!m_pInfo || !m_pInfo->m_pJsPlatform ||
+      !m_pInfo->m_pJsPlatform->Doc_submitForm) {
+    return;
+  }
+  CFX_ByteString bsDestination = CFX_WideString(URL).UTF16LE_Encode();
+  m_pInfo->m_pJsPlatform->Doc_submitForm(m_pInfo->m_pJsPlatform, formData,
+                                         length,
+                                         AsFPDFWideString(&bsDestination));
+}
+
+void CPDFSDK_FormFillEnvironment::JS_docmailForm(void* mailData,
+                                                 int length,
+                                                 FPDF_BOOL bUI,
+                                                 const FX_WCHAR* To,
+                                                 const FX_WCHAR* Subject,
+                                                 const FX_WCHAR* CC,
+                                                 const FX_WCHAR* BCC,
+                                                 const FX_WCHAR* Msg) {
+  if (!m_pInfo || !m_pInfo->m_pJsPlatform ||
+      !m_pInfo->m_pJsPlatform->Doc_mail) {
+    return;
+  }
+  CFX_ByteString bsTo = CFX_WideString(To).UTF16LE_Encode();
+  CFX_ByteString bsSubject = CFX_WideString(Subject).UTF16LE_Encode();
+  CFX_ByteString bsCC = CFX_WideString(CC).UTF16LE_Encode();
+  CFX_ByteString bsBcc = CFX_WideString(BCC).UTF16LE_Encode();
+  CFX_ByteString bsMsg = CFX_WideString(Msg).UTF16LE_Encode();
+  m_pInfo->m_pJsPlatform->Doc_mail(
+      m_pInfo->m_pJsPlatform, mailData, length, bUI, AsFPDFWideString(&bsTo),
+      AsFPDFWideString(&bsSubject), AsFPDFWideString(&bsCC),
+      AsFPDFWideString(&bsBcc), AsFPDFWideString(&bsMsg));
+}
+
+void CPDFSDK_FormFillEnvironment::JS_docprint(FPDF_BOOL bUI,
+                                              int nStart,
+                                              int nEnd,
+                                              FPDF_BOOL bSilent,
+                                              FPDF_BOOL bShrinkToFit,
+                                              FPDF_BOOL bPrintAsImage,
+                                              FPDF_BOOL bReverse,
+                                              FPDF_BOOL bAnnotations) {
+  if (!m_pInfo || !m_pInfo->m_pJsPlatform ||
+      !m_pInfo->m_pJsPlatform->Doc_print) {
+    return;
+  }
+  m_pInfo->m_pJsPlatform->Doc_print(m_pInfo->m_pJsPlatform, bUI, nStart, nEnd,
+                                    bSilent, bShrinkToFit, bPrintAsImage,
+                                    bReverse, bAnnotations);
+}
+
+void CPDFSDK_FormFillEnvironment::JS_docgotoPage(int nPageNum) {
+  if (!m_pInfo || !m_pInfo->m_pJsPlatform ||
+      !m_pInfo->m_pJsPlatform->Doc_gotoPage) {
+    return;
+  }
+  m_pInfo->m_pJsPlatform->Doc_gotoPage(m_pInfo->m_pJsPlatform, nPageNum);
+}
+
+IJS_Runtime* CPDFSDK_FormFillEnvironment::GetJSRuntime() {
+  if (!IsJSInitiated())
+    return nullptr;
+  if (!m_pJSRuntime)
+    m_pJSRuntime.reset(IJS_Runtime::Create(this));
+  return m_pJSRuntime.get();
+}
+
+CPDFSDK_AnnotHandlerMgr* CPDFSDK_FormFillEnvironment::GetAnnotHandlerMgr() {
+  if (!m_pAnnotHandlerMgr)
+    m_pAnnotHandlerMgr = pdfium::MakeUnique<CPDFSDK_AnnotHandlerMgr>(this);
+  return m_pAnnotHandlerMgr.get();
+}
+
+CPDFSDK_ActionHandler* CPDFSDK_FormFillEnvironment::GetActionHander() {
+  if (!m_pActionHandler)
+    m_pActionHandler = pdfium::MakeUnique<CPDFSDK_ActionHandler>();
+  return m_pActionHandler.get();
+}
+
+CFFL_InteractiveFormFiller*
+CPDFSDK_FormFillEnvironment::GetInteractiveFormFiller() {
+  if (!m_pFormFiller)
+    m_pFormFiller = pdfium::MakeUnique<CFFL_InteractiveFormFiller>(this);
+  return m_pFormFiller.get();
+}
+
+void CPDFSDK_FormFillEnvironment::Invalidate(FPDF_PAGE page,
+                                             double left,
+                                             double top,
+                                             double right,
+                                             double bottom) {
+  if (m_pInfo && m_pInfo->FFI_Invalidate)
+    m_pInfo->FFI_Invalidate(m_pInfo, page, left, top, right, bottom);
+}
+
+void CPDFSDK_FormFillEnvironment::OutputSelectedRect(FPDF_PAGE page,
+                                                     double left,
+                                                     double top,
+                                                     double right,
+                                                     double bottom) {
+  if (m_pInfo && m_pInfo->FFI_OutputSelectedRect)
+    m_pInfo->FFI_OutputSelectedRect(m_pInfo, page, left, top, right, bottom);
+}
+
+void CPDFSDK_FormFillEnvironment::SetCursor(int nCursorType) {
+  if (m_pInfo && m_pInfo->FFI_SetCursor)
+    m_pInfo->FFI_SetCursor(m_pInfo, nCursorType);
+}
+
+int CPDFSDK_FormFillEnvironment::SetTimer(int uElapse,
+                                          TimerCallback lpTimerFunc) {
+  if (m_pInfo && m_pInfo->FFI_SetTimer)
+    return m_pInfo->FFI_SetTimer(m_pInfo, uElapse, lpTimerFunc);
+  return -1;
+}
+
+void CPDFSDK_FormFillEnvironment::KillTimer(int nTimerID) {
+  if (m_pInfo && m_pInfo->FFI_KillTimer)
+    m_pInfo->FFI_KillTimer(m_pInfo, nTimerID);
+}
+
+FX_SYSTEMTIME CPDFSDK_FormFillEnvironment::GetLocalTime() const {
+  FX_SYSTEMTIME fxtime;
+  if (!m_pInfo || !m_pInfo->FFI_GetLocalTime)
+    return fxtime;
+
+  FPDF_SYSTEMTIME systime = m_pInfo->FFI_GetLocalTime(m_pInfo);
+  fxtime.wDay = systime.wDay;
+  fxtime.wDayOfWeek = systime.wDayOfWeek;
+  fxtime.wHour = systime.wHour;
+  fxtime.wMilliseconds = systime.wMilliseconds;
+  fxtime.wMinute = systime.wMinute;
+  fxtime.wMonth = systime.wMonth;
+  fxtime.wSecond = systime.wSecond;
+  fxtime.wYear = systime.wYear;
+  return fxtime;
+}
+
+void CPDFSDK_FormFillEnvironment::OnChange() {
+  if (m_pInfo && m_pInfo->FFI_OnChange)
+    m_pInfo->FFI_OnChange(m_pInfo);
+}
+
+bool CPDFSDK_FormFillEnvironment::IsSHIFTKeyDown(uint32_t nFlag) const {
+  return (nFlag & FWL_EVENTFLAG_ShiftKey) != 0;
+}
+
+bool CPDFSDK_FormFillEnvironment::IsCTRLKeyDown(uint32_t nFlag) const {
+  return (nFlag & FWL_EVENTFLAG_ControlKey) != 0;
+}
+
+bool CPDFSDK_FormFillEnvironment::IsALTKeyDown(uint32_t nFlag) const {
+  return (nFlag & FWL_EVENTFLAG_AltKey) != 0;
+}
+
+FPDF_PAGE CPDFSDK_FormFillEnvironment::GetPage(FPDF_DOCUMENT document,
+                                               int nPageIndex) {
+  if (m_pInfo && m_pInfo->FFI_GetPage)
+    return m_pInfo->FFI_GetPage(m_pInfo, document, nPageIndex);
+  return nullptr;
+}
+
+FPDF_PAGE CPDFSDK_FormFillEnvironment::GetCurrentPage(FPDF_DOCUMENT document) {
+  if (m_pInfo && m_pInfo->FFI_GetCurrentPage)
+    return m_pInfo->FFI_GetCurrentPage(m_pInfo, document);
+  return nullptr;
+}
+
+void CPDFSDK_FormFillEnvironment::ExecuteNamedAction(
+    const FX_CHAR* namedAction) {
+  if (m_pInfo && m_pInfo->FFI_ExecuteNamedAction)
+    m_pInfo->FFI_ExecuteNamedAction(m_pInfo, namedAction);
+}
+
+void CPDFSDK_FormFillEnvironment::OnSetFieldInputFocus(
+    FPDF_WIDESTRING focusText,
+    FPDF_DWORD nTextLen,
+    bool bFocus) {
+  if (m_pInfo && m_pInfo->FFI_SetTextFieldFocus)
+    m_pInfo->FFI_SetTextFieldFocus(m_pInfo, focusText, nTextLen, bFocus);
+}
+
+void CPDFSDK_FormFillEnvironment::DoURIAction(const FX_CHAR* bsURI) {
+  if (m_pInfo && m_pInfo->FFI_DoURIAction)
+    m_pInfo->FFI_DoURIAction(m_pInfo, bsURI);
+}
+
+void CPDFSDK_FormFillEnvironment::DoGoToAction(int nPageIndex,
+                                               int zoomMode,
+                                               float* fPosArray,
+                                               int sizeOfArray) {
+  if (m_pInfo && m_pInfo->FFI_DoGoToAction) {
+    m_pInfo->FFI_DoGoToAction(m_pInfo, nPageIndex, zoomMode, fPosArray,
+                              sizeOfArray);
+  }
+}
+
+#ifdef PDF_ENABLE_XFA
+void CPDFSDK_FormFillEnvironment::DisplayCaret(FPDF_PAGE page,
+                                               FPDF_BOOL bVisible,
+                                               double left,
+                                               double top,
+                                               double right,
+                                               double bottom) {
+  if (m_pInfo && m_pInfo->FFI_DisplayCaret) {
+    m_pInfo->FFI_DisplayCaret(m_pInfo, page, bVisible, left, top, right,
+                              bottom);
+  }
+}
+
+int CPDFSDK_FormFillEnvironment::GetCurrentPageIndex(FPDF_DOCUMENT document) {
+  if (!m_pInfo || !m_pInfo->FFI_GetCurrentPageIndex)
+    return -1;
+  return m_pInfo->FFI_GetCurrentPageIndex(m_pInfo, document);
+}
+
+void CPDFSDK_FormFillEnvironment::SetCurrentPage(FPDF_DOCUMENT document,
+                                                 int iCurPage) {
+  if (m_pInfo && m_pInfo->FFI_SetCurrentPage)
+    m_pInfo->FFI_SetCurrentPage(m_pInfo, document, iCurPage);
+}
+
+CFX_WideString CPDFSDK_FormFillEnvironment::GetPlatform() {
+  if (!m_pInfo || !m_pInfo->FFI_GetPlatform)
+    return L"";
+
+  int nRequiredLen = m_pInfo->FFI_GetPlatform(m_pInfo, nullptr, 0);
+  if (nRequiredLen <= 0)
+    return L"";
+
+  char* pbuff = new char[nRequiredLen];
+  memset(pbuff, 0, nRequiredLen);
+  int nActualLen = m_pInfo->FFI_GetPlatform(m_pInfo, pbuff, nRequiredLen);
+  if (nActualLen <= 0 || nActualLen > nRequiredLen) {
+    delete[] pbuff;
+    return L"";
+  }
+  CFX_ByteString bsRet = CFX_ByteString(pbuff, nActualLen);
+  CFX_WideString wsRet = CFX_WideString::FromUTF16LE(
+      (unsigned short*)bsRet.GetBuffer(bsRet.GetLength()),
+      bsRet.GetLength() / sizeof(unsigned short));
+  delete[] pbuff;
+  return wsRet;
+}
+
+void CPDFSDK_FormFillEnvironment::GotoURL(FPDF_DOCUMENT document,
+                                          const CFX_WideStringC& wsURL) {
+  if (!m_pInfo || !m_pInfo->FFI_GotoURL)
+    return;
+
+  CFX_ByteString bsTo = CFX_WideString(wsURL).UTF16LE_Encode();
+  FPDF_WIDESTRING pTo = (FPDF_WIDESTRING)bsTo.GetBuffer(wsURL.GetLength());
+  m_pInfo->FFI_GotoURL(m_pInfo, document, pTo);
+  bsTo.ReleaseBuffer();
+}
+
+void CPDFSDK_FormFillEnvironment::GetPageViewRect(FPDF_PAGE page,
+                                                  FS_RECTF& dstRect) {
+  if (!m_pInfo || !m_pInfo->FFI_GetPageViewRect)
+    return;
+
+  double left;
+  double top;
+  double right;
+  double bottom;
+  m_pInfo->FFI_GetPageViewRect(m_pInfo, page, &left, &top, &right, &bottom);
+
+  dstRect.left = static_cast<float>(left);
+  dstRect.top = static_cast<float>(top < bottom ? bottom : top);
+  dstRect.bottom = static_cast<float>(top < bottom ? top : bottom);
+  dstRect.right = static_cast<float>(right);
+}
+
+bool CPDFSDK_FormFillEnvironment::PopupMenu(FPDF_PAGE page,
+                                            FPDF_WIDGET hWidget,
+                                            int menuFlag,
+                                            CFX_PointF pt) {
+  return m_pInfo && m_pInfo->FFI_PopupMenu &&
+         m_pInfo->FFI_PopupMenu(m_pInfo, page, hWidget, menuFlag, pt.x, pt.y);
+}
+
+void CPDFSDK_FormFillEnvironment::Alert(FPDF_WIDESTRING Msg,
+                                        FPDF_WIDESTRING Title,
+                                        int Type,
+                                        int Icon) {
+  if (m_pInfo && m_pInfo->m_pJsPlatform && m_pInfo->m_pJsPlatform->app_alert) {
+    m_pInfo->m_pJsPlatform->app_alert(m_pInfo->m_pJsPlatform, Msg, Title, Type,
+                                      Icon);
+  }
+}
+
+void CPDFSDK_FormFillEnvironment::EmailTo(FPDF_FILEHANDLER* fileHandler,
+                                          FPDF_WIDESTRING pTo,
+                                          FPDF_WIDESTRING pSubject,
+                                          FPDF_WIDESTRING pCC,
+                                          FPDF_WIDESTRING pBcc,
+                                          FPDF_WIDESTRING pMsg) {
+  if (m_pInfo && m_pInfo->FFI_EmailTo)
+    m_pInfo->FFI_EmailTo(m_pInfo, fileHandler, pTo, pSubject, pCC, pBcc, pMsg);
+}
+
+void CPDFSDK_FormFillEnvironment::UploadTo(FPDF_FILEHANDLER* fileHandler,
+                                           int fileFlag,
+                                           FPDF_WIDESTRING uploadTo) {
+  if (m_pInfo && m_pInfo->FFI_UploadTo)
+    m_pInfo->FFI_UploadTo(m_pInfo, fileHandler, fileFlag, uploadTo);
+}
+
+FPDF_FILEHANDLER* CPDFSDK_FormFillEnvironment::OpenFile(int fileType,
+                                                        FPDF_WIDESTRING wsURL,
+                                                        const char* mode) {
+  if (m_pInfo && m_pInfo->FFI_OpenFile)
+    return m_pInfo->FFI_OpenFile(m_pInfo, fileType, wsURL, mode);
+  return nullptr;
+}
+
+CFX_RetainPtr<IFX_SeekableReadStream>
+CPDFSDK_FormFillEnvironment::DownloadFromURL(const FX_WCHAR* url) {
+  if (!m_pInfo || !m_pInfo->FFI_DownloadFromURL)
+    return nullptr;
+
+  CFX_ByteString bstrURL = CFX_WideString(url).UTF16LE_Encode();
+  FPDF_WIDESTRING wsURL =
+      (FPDF_WIDESTRING)bstrURL.GetBuffer(bstrURL.GetLength());
+
+  FPDF_LPFILEHANDLER fileHandler = m_pInfo->FFI_DownloadFromURL(m_pInfo, wsURL);
+  return MakeSeekableStream(fileHandler);
+}
+
+CFX_WideString CPDFSDK_FormFillEnvironment::PostRequestURL(
+    const FX_WCHAR* wsURL,
+    const FX_WCHAR* wsData,
+    const FX_WCHAR* wsContentType,
+    const FX_WCHAR* wsEncode,
+    const FX_WCHAR* wsHeader) {
+  if (!m_pInfo || !m_pInfo->FFI_PostRequestURL)
+    return L"";
+
+  CFX_ByteString bsURL = CFX_WideString(wsURL).UTF16LE_Encode();
+  FPDF_WIDESTRING URL = (FPDF_WIDESTRING)bsURL.GetBuffer(bsURL.GetLength());
+
+  CFX_ByteString bsData = CFX_WideString(wsData).UTF16LE_Encode();
+  FPDF_WIDESTRING data = (FPDF_WIDESTRING)bsData.GetBuffer(bsData.GetLength());
+
+  CFX_ByteString bsContentType = CFX_WideString(wsContentType).UTF16LE_Encode();
+  FPDF_WIDESTRING contentType =
+      (FPDF_WIDESTRING)bsContentType.GetBuffer(bsContentType.GetLength());
+
+  CFX_ByteString bsEncode = CFX_WideString(wsEncode).UTF16LE_Encode();
+  FPDF_WIDESTRING encode =
+      (FPDF_WIDESTRING)bsEncode.GetBuffer(bsEncode.GetLength());
+
+  CFX_ByteString bsHeader = CFX_WideString(wsHeader).UTF16LE_Encode();
+  FPDF_WIDESTRING header =
+      (FPDF_WIDESTRING)bsHeader.GetBuffer(bsHeader.GetLength());
+
+  FPDF_BSTR response;
+  FPDF_BStr_Init(&response);
+  m_pInfo->FFI_PostRequestURL(m_pInfo, URL, data, contentType, encode, header,
+                              &response);
+
+  CFX_WideString wsRet = CFX_WideString::FromUTF16LE(
+      (FPDF_WIDESTRING)response.str, response.len / sizeof(FPDF_WIDESTRING));
+  FPDF_BStr_Clear(&response);
+
+  return wsRet;
+}
+
+FPDF_BOOL CPDFSDK_FormFillEnvironment::PutRequestURL(const FX_WCHAR* wsURL,
+                                                     const FX_WCHAR* wsData,
+                                                     const FX_WCHAR* wsEncode) {
+  if (!m_pInfo || !m_pInfo->FFI_PutRequestURL)
+    return false;
+
+  CFX_ByteString bsURL = CFX_WideString(wsURL).UTF16LE_Encode();
+  FPDF_WIDESTRING URL = (FPDF_WIDESTRING)bsURL.GetBuffer(bsURL.GetLength());
+
+  CFX_ByteString bsData = CFX_WideString(wsData).UTF16LE_Encode();
+  FPDF_WIDESTRING data = (FPDF_WIDESTRING)bsData.GetBuffer(bsData.GetLength());
+
+  CFX_ByteString bsEncode = CFX_WideString(wsEncode).UTF16LE_Encode();
+  FPDF_WIDESTRING encode =
+      (FPDF_WIDESTRING)bsEncode.GetBuffer(bsEncode.GetLength());
+
+  return m_pInfo->FFI_PutRequestURL(m_pInfo, URL, data, encode);
+}
+
+CFX_WideString CPDFSDK_FormFillEnvironment::GetLanguage() {
+  if (!m_pInfo || !m_pInfo->FFI_GetLanguage)
+    return L"";
+
+  int nRequiredLen = m_pInfo->FFI_GetLanguage(m_pInfo, nullptr, 0);
+  if (nRequiredLen <= 0)
+    return L"";
+
+  char* pbuff = new char[nRequiredLen];
+  memset(pbuff, 0, nRequiredLen);
+  int nActualLen = m_pInfo->FFI_GetLanguage(m_pInfo, pbuff, nRequiredLen);
+  if (nActualLen <= 0 || nActualLen > nRequiredLen) {
+    delete[] pbuff;
+    return L"";
+  }
+  CFX_ByteString bsRet = CFX_ByteString(pbuff, nActualLen);
+  CFX_WideString wsRet = CFX_WideString::FromUTF16LE(
+      (FPDF_WIDESTRING)bsRet.GetBuffer(bsRet.GetLength()),
+      bsRet.GetLength() / sizeof(FPDF_WIDESTRING));
+  delete[] pbuff;
+  return wsRet;
+}
+
+void CPDFSDK_FormFillEnvironment::PageEvent(int iPageCount,
+                                            uint32_t dwEventType) const {
+  if (m_pInfo && m_pInfo->FFI_PageEvent)
+    m_pInfo->FFI_PageEvent(m_pInfo, iPageCount, dwEventType);
+}
+#endif  // PDF_ENABLE_XFA
+
+void CPDFSDK_FormFillEnvironment::ClearAllFocusedAnnots() {
+  for (auto& it : m_PageMap) {
+    if (it.second->IsValidSDKAnnot(GetFocusAnnot()))
+      KillFocusAnnot(0);
+  }
+}
+
+CPDFSDK_PageView* CPDFSDK_FormFillEnvironment::GetPageView(
+    UnderlyingPageType* pUnderlyingPage,
+    bool renew) {
+  auto it = m_PageMap.find(pUnderlyingPage);
+  if (it != m_PageMap.end())
+    return it->second.get();
+
+  if (!renew)
+    return nullptr;
+
+  CPDFSDK_PageView* pPageView = new CPDFSDK_PageView(this, pUnderlyingPage);
+  m_PageMap[pUnderlyingPage].reset(pPageView);
+  // Delay to load all the annotations, to avoid endless loop.
+  pPageView->LoadFXAnnots();
+  return pPageView;
+}
+
+CPDFSDK_PageView* CPDFSDK_FormFillEnvironment::GetCurrentView() {
+  UnderlyingPageType* pPage =
+      UnderlyingFromFPDFPage(GetCurrentPage(m_pUnderlyingDoc));
+  return pPage ? GetPageView(pPage, true) : nullptr;
+}
+
+CPDFSDK_PageView* CPDFSDK_FormFillEnvironment::GetPageView(int nIndex) {
+  UnderlyingPageType* pTempPage =
+      UnderlyingFromFPDFPage(GetPage(m_pUnderlyingDoc, nIndex));
+  if (!pTempPage)
+    return nullptr;
+
+  auto it = m_PageMap.find(pTempPage);
+  return it != m_PageMap.end() ? it->second.get() : nullptr;
+}
+
+void CPDFSDK_FormFillEnvironment::ProcJavascriptFun() {
+  CPDF_Document* pPDFDoc = GetPDFDocument();
+  CPDF_DocJSActions docJS(pPDFDoc);
+  int iCount = docJS.CountJSActions();
+  if (iCount < 1)
+    return;
+  for (int i = 0; i < iCount; i++) {
+    CFX_ByteString csJSName;
+    CPDF_Action jsAction = docJS.GetJSAction(i, csJSName);
+    if (GetActionHander()) {
+      GetActionHander()->DoAction_JavaScript(
+          jsAction, CFX_WideString::FromLocal(csJSName.AsStringC()), this);
+    }
+  }
+}
+
+bool CPDFSDK_FormFillEnvironment::ProcOpenAction() {
+  if (!m_pUnderlyingDoc)
+    return false;
+
+  CPDF_Dictionary* pRoot = GetPDFDocument()->GetRoot();
+  if (!pRoot)
+    return false;
+
+  CPDF_Object* pOpenAction = pRoot->GetDictFor("OpenAction");
+  if (!pOpenAction)
+    pOpenAction = pRoot->GetArrayFor("OpenAction");
+
+  if (!pOpenAction)
+    return false;
+
+  if (pOpenAction->IsArray())
+    return true;
+
+  if (CPDF_Dictionary* pDict = pOpenAction->AsDictionary()) {
+    CPDF_Action action(pDict);
+    if (GetActionHander())
+      GetActionHander()->DoAction_DocOpen(action, this);
+    return true;
+  }
+  return false;
+}
+
+void CPDFSDK_FormFillEnvironment::RemovePageView(
+    UnderlyingPageType* pUnderlyingPage) {
+  auto it = m_PageMap.find(pUnderlyingPage);
+  if (it == m_PageMap.end())
+    return;
+
+  CPDFSDK_PageView* pPageView = it->second.get();
+  if (pPageView->IsLocked() || pPageView->IsBeingDestroyed())
+    return;
+
+  // Mark the page view so we do not come into |RemovePageView| a second
+  // time while we're in the process of removing.
+  pPageView->SetBeingDestroyed();
+
+  // This must happen before we remove |pPageView| from the map because
+  // |KillFocusAnnot| can call into the |GetPage| method which will
+  // look for this page view in the map, if it doesn't find it a new one will
+  // be created. We then have two page views pointing to the same page and
+  // bad things happen.
+  if (pPageView->IsValidSDKAnnot(GetFocusAnnot()))
+    KillFocusAnnot(0);
+
+  // Remove the page from the map to make sure we don't accidentally attempt
+  // to use the |pPageView| while we're cleaning it up.
+  m_PageMap.erase(it);
+}
+
+UnderlyingPageType* CPDFSDK_FormFillEnvironment::GetPage(int nIndex) {
+  return UnderlyingFromFPDFPage(GetPage(m_pUnderlyingDoc, nIndex));
+}
+
+CPDFSDK_InterForm* CPDFSDK_FormFillEnvironment::GetInterForm() {
+  if (!m_pInterForm)
+    m_pInterForm = pdfium::MakeUnique<CPDFSDK_InterForm>(this);
+  return m_pInterForm.get();
+}
+
+void CPDFSDK_FormFillEnvironment::UpdateAllViews(CPDFSDK_PageView* pSender,
+                                                 CPDFSDK_Annot* pAnnot) {
+  for (const auto& it : m_PageMap) {
+    CPDFSDK_PageView* pPageView = it.second.get();
+    if (pPageView != pSender)
+      pPageView->UpdateView(pAnnot);
+  }
+}
+
+bool CPDFSDK_FormFillEnvironment::SetFocusAnnot(
+    CPDFSDK_Annot::ObservedPtr* pAnnot) {
+  if (m_bBeingDestroyed)
+    return false;
+  if (m_pFocusAnnot == *pAnnot)
+    return true;
+  if (m_pFocusAnnot && !KillFocusAnnot(0))
+    return false;
+  if (!*pAnnot)
+    return false;
+
+#ifdef PDF_ENABLE_XFA
+  CPDFSDK_Annot::ObservedPtr pLastFocusAnnot(m_pFocusAnnot.Get());
+#endif  // PDF_ENABLE_XFA
+  CPDFSDK_PageView* pPageView = (*pAnnot)->GetPageView();
+  if (pPageView && pPageView->IsValid()) {
+    CPDFSDK_AnnotHandlerMgr* pAnnotHandler = GetAnnotHandlerMgr();
+    if (!m_pFocusAnnot) {
+#ifdef PDF_ENABLE_XFA
+      if (!pAnnotHandler->Annot_OnChangeFocus(pAnnot, &pLastFocusAnnot))
+        return false;
+#endif  // PDF_ENABLE_XFA
+      if (!pAnnotHandler->Annot_OnSetFocus(pAnnot, 0))
+        return false;
+      if (!m_pFocusAnnot) {
+        m_pFocusAnnot.Reset(pAnnot->Get());
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+bool CPDFSDK_FormFillEnvironment::KillFocusAnnot(uint32_t nFlag) {
+  if (m_pFocusAnnot) {
+    CPDFSDK_AnnotHandlerMgr* pAnnotHandler = GetAnnotHandlerMgr();
+    CPDFSDK_Annot::ObservedPtr pFocusAnnot(m_pFocusAnnot.Get());
+    m_pFocusAnnot.Reset();
+
+#ifdef PDF_ENABLE_XFA
+    CPDFSDK_Annot::ObservedPtr pNull;
+    if (!pAnnotHandler->Annot_OnChangeFocus(&pNull, &pFocusAnnot))
+      return false;
+#endif  // PDF_ENABLE_XFA
+
+    if (pAnnotHandler->Annot_OnKillFocus(&pFocusAnnot, nFlag)) {
+      if (pFocusAnnot->GetAnnotSubtype() == CPDF_Annot::Subtype::WIDGET) {
+        CPDFSDK_Widget* pWidget =
+            static_cast<CPDFSDK_Widget*>(pFocusAnnot.Get());
+        int nFieldType = pWidget->GetFieldType();
+        if (FIELDTYPE_TEXTFIELD == nFieldType ||
+            FIELDTYPE_COMBOBOX == nFieldType) {
+          OnSetFieldInputFocus(nullptr, 0, false);
+        }
+      }
+      if (!m_pFocusAnnot)
+        return true;
+    } else {
+      m_pFocusAnnot.Reset(pFocusAnnot.Get());
+    }
+  }
+  return false;
+}
+
+bool CPDFSDK_FormFillEnvironment::GetPermissions(int nFlag) {
+  return !!(GetPDFDocument()->GetUserPermissions() & nFlag);
+}
diff --git a/fpdfsdk/cpdfsdk_formfillenvironment.h b/fpdfsdk/cpdfsdk_formfillenvironment.h
new file mode 100644
index 0000000..8c2a8a3
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_formfillenvironment.h
@@ -0,0 +1,228 @@
+// 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_CPDFSDK_FORMFILLENVIRONMENT_H_
+#define FPDFSDK_CPDFSDK_FORMFILLENVIRONMENT_H_
+
+#include <map>
+#include <memory>
+#include <vector>
+
+#include "core/fpdfapi/page/cpdf_page.h"
+#include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfdoc/cpdf_occontext.h"
+#include "core/fxcrt/cfx_observable.h"
+#include "fpdfsdk/cfx_systemhandler.h"
+#include "fpdfsdk/cpdfsdk_annot.h"
+#include "fpdfsdk/fsdk_define.h"
+#include "public/fpdf_formfill.h"
+#include "public/fpdf_fwlevent.h"
+
+class CFFL_InteractiveFormFiller;
+class CFX_SystemHandler;
+class CPDFSDK_ActionHandler;
+class CPDFSDK_AnnotHandlerMgr;
+class CPDFSDK_InterForm;
+class CPDFSDK_PageView;
+class IJS_Runtime;
+
+class CPDFSDK_FormFillEnvironment
+    : public CFX_Observable<CPDFSDK_FormFillEnvironment> {
+ public:
+  CPDFSDK_FormFillEnvironment(UnderlyingDocumentType* pDoc,
+                              FPDF_FORMFILLINFO* pFFinfo);
+  ~CPDFSDK_FormFillEnvironment();
+
+  CPDFSDK_PageView* GetPageView(UnderlyingPageType* pPage, bool renew);
+  CPDFSDK_PageView* GetPageView(int nIndex);
+  CPDFSDK_PageView* GetCurrentView();
+  void RemovePageView(UnderlyingPageType* pPage);
+  void UpdateAllViews(CPDFSDK_PageView* pSender, CPDFSDK_Annot* pAnnot);
+
+  CPDFSDK_Annot* GetFocusAnnot() { return m_pFocusAnnot.Get(); }
+  bool SetFocusAnnot(CPDFSDK_Annot::ObservedPtr* pAnnot);
+  bool KillFocusAnnot(uint32_t nFlag);
+  void ClearAllFocusedAnnots();
+
+  bool ExtractPages(const std::vector<uint16_t>& arrExtraPages,
+                    CPDF_Document* pDstDoc);
+  bool InsertPages(int nInsertAt,
+                   const CPDF_Document* pSrcDoc,
+                   const std::vector<uint16_t>& arrSrcPages);
+  bool ReplacePages(int nPage,
+                    const CPDF_Document* pSrcDoc,
+                    const std::vector<uint16_t>& arrSrcPages);
+
+  int GetPageCount() { return m_pUnderlyingDoc->GetPageCount(); }
+  bool GetPermissions(int nFlag);
+
+  bool GetChangeMark() const { return m_bChangeMask; }
+  void SetChangeMark() { m_bChangeMask = true; }
+  void ClearChangeMark() { m_bChangeMask = false; }
+
+  UnderlyingPageType* GetPage(int nIndex);
+
+  void ProcJavascriptFun();
+  bool ProcOpenAction();
+
+  void Invalidate(FPDF_PAGE page,
+                  double left,
+                  double top,
+                  double right,
+                  double bottom);
+  void OutputSelectedRect(FPDF_PAGE page,
+                          double left,
+                          double top,
+                          double right,
+                          double bottom);
+
+  void SetCursor(int nCursorType);
+  int SetTimer(int uElapse, TimerCallback lpTimerFunc);
+  void KillTimer(int nTimerID);
+  FX_SYSTEMTIME GetLocalTime() const;
+
+  void OnChange();
+  bool IsSHIFTKeyDown(uint32_t nFlag) const;
+  bool IsCTRLKeyDown(uint32_t nFlag) const;
+  bool IsALTKeyDown(uint32_t nFlag) const;
+
+  FPDF_PAGE GetPage(FPDF_DOCUMENT document, int nPageIndex);
+  FPDF_PAGE GetCurrentPage(FPDF_DOCUMENT document);
+
+  void ExecuteNamedAction(const FX_CHAR* namedAction);
+  void OnSetFieldInputFocus(FPDF_WIDESTRING focusText,
+                            FPDF_DWORD nTextLen,
+                            bool bFocus);
+  void DoURIAction(const FX_CHAR* bsURI);
+  void DoGoToAction(int nPageIndex,
+                    int zoomMode,
+                    float* fPosArray,
+                    int sizeOfArray);
+
+  UnderlyingDocumentType* GetUnderlyingDocument() const {
+    return m_pUnderlyingDoc;
+  }
+
+#ifdef PDF_ENABLE_XFA
+  CPDF_Document* GetPDFDocument() const {
+    return m_pUnderlyingDoc ? m_pUnderlyingDoc->GetPDFDoc() : nullptr;
+  }
+
+  CPDFXFA_Context* GetXFAContext() const { return m_pUnderlyingDoc; }
+  void ResetXFADocument() { m_pUnderlyingDoc = nullptr; }
+
+  int GetPageViewCount() const { return m_PageMap.size(); }
+
+  void DisplayCaret(FPDF_PAGE page,
+                    FPDF_BOOL bVisible,
+                    double left,
+                    double top,
+                    double right,
+                    double bottom);
+  int GetCurrentPageIndex(FPDF_DOCUMENT document);
+  void SetCurrentPage(FPDF_DOCUMENT document, int iCurPage);
+
+  // TODO(dsinclair): This should probably change to PDFium?
+  CFX_WideString FFI_GetAppName() const { return CFX_WideString(L"Acrobat"); }
+
+  CFX_WideString GetPlatform();
+  void GotoURL(FPDF_DOCUMENT document, const CFX_WideStringC& wsURL);
+  void GetPageViewRect(FPDF_PAGE page, FS_RECTF& dstRect);
+  bool PopupMenu(FPDF_PAGE page,
+                 FPDF_WIDGET hWidget,
+                 int menuFlag,
+                 CFX_PointF pt);
+
+  void Alert(FPDF_WIDESTRING Msg, FPDF_WIDESTRING Title, int Type, int Icon);
+  void EmailTo(FPDF_FILEHANDLER* fileHandler,
+               FPDF_WIDESTRING pTo,
+               FPDF_WIDESTRING pSubject,
+               FPDF_WIDESTRING pCC,
+               FPDF_WIDESTRING pBcc,
+               FPDF_WIDESTRING pMsg);
+  void UploadTo(FPDF_FILEHANDLER* fileHandler,
+                int fileFlag,
+                FPDF_WIDESTRING uploadTo);
+  FPDF_FILEHANDLER* OpenFile(int fileType,
+                             FPDF_WIDESTRING wsURL,
+                             const char* mode);
+  CFX_RetainPtr<IFX_SeekableReadStream> DownloadFromURL(const FX_WCHAR* url);
+  CFX_WideString PostRequestURL(const FX_WCHAR* wsURL,
+                                const FX_WCHAR* wsData,
+                                const FX_WCHAR* wsContentType,
+                                const FX_WCHAR* wsEncode,
+                                const FX_WCHAR* wsHeader);
+  FPDF_BOOL PutRequestURL(const FX_WCHAR* wsURL,
+                          const FX_WCHAR* wsData,
+                          const FX_WCHAR* wsEncode);
+  CFX_WideString GetLanguage();
+
+  void PageEvent(int iPageCount, uint32_t dwEventType) const;
+#else   // PDF_ENABLE_XFA
+  CPDF_Document* GetPDFDocument() const { return m_pUnderlyingDoc; }
+#endif  // PDF_ENABLE_XFA
+
+  int JS_appAlert(const FX_WCHAR* Msg,
+                  const FX_WCHAR* Title,
+                  uint32_t Type,
+                  uint32_t Icon);
+  int JS_appResponse(const FX_WCHAR* Question,
+                     const FX_WCHAR* Title,
+                     const FX_WCHAR* Default,
+                     const FX_WCHAR* cLabel,
+                     FPDF_BOOL bPassword,
+                     void* response,
+                     int length);
+  void JS_appBeep(int nType);
+  CFX_WideString JS_fieldBrowse();
+  CFX_WideString JS_docGetFilePath();
+  void JS_docSubmitForm(void* formData, int length, const FX_WCHAR* URL);
+  void JS_docmailForm(void* mailData,
+                      int length,
+                      FPDF_BOOL bUI,
+                      const FX_WCHAR* To,
+                      const FX_WCHAR* Subject,
+                      const FX_WCHAR* CC,
+                      const FX_WCHAR* BCC,
+                      const FX_WCHAR* Msg);
+  void JS_docprint(FPDF_BOOL bUI,
+                   int nStart,
+                   int nEnd,
+                   FPDF_BOOL bSilent,
+                   FPDF_BOOL bShrinkToFit,
+                   FPDF_BOOL bPrintAsImage,
+                   FPDF_BOOL bReverse,
+                   FPDF_BOOL bAnnotations);
+  void JS_docgotoPage(int nPageNum);
+
+  bool IsJSInitiated() const { return m_pInfo && m_pInfo->m_pJsPlatform; }
+  CFX_ByteString GetAppName() const { return ""; }
+  CFX_SystemHandler* GetSysHandler() const { return m_pSysHandler.get(); }
+  FPDF_FORMFILLINFO* GetFormFillInfo() const { return m_pInfo; }
+
+  // Creates if not present.
+  CFFL_InteractiveFormFiller* GetInteractiveFormFiller();
+  CPDFSDK_AnnotHandlerMgr* GetAnnotHandlerMgr();  // Creates if not present.
+  IJS_Runtime* GetJSRuntime();                    // Creates if not present.
+  CPDFSDK_ActionHandler* GetActionHander();       // Creates if not present.
+  CPDFSDK_InterForm* GetInterForm();              // Creates if not present.
+
+ private:
+  std::unique_ptr<CPDFSDK_AnnotHandlerMgr> m_pAnnotHandlerMgr;
+  std::unique_ptr<CPDFSDK_ActionHandler> m_pActionHandler;
+  std::unique_ptr<IJS_Runtime> m_pJSRuntime;
+  FPDF_FORMFILLINFO* const m_pInfo;
+  std::map<UnderlyingPageType*, std::unique_ptr<CPDFSDK_PageView>> m_PageMap;
+  std::unique_ptr<CPDFSDK_InterForm> m_pInterForm;
+  CPDFSDK_Annot::ObservedPtr m_pFocusAnnot;
+  UnderlyingDocumentType* m_pUnderlyingDoc;
+  std::unique_ptr<CFFL_InteractiveFormFiller> m_pFormFiller;
+  std::unique_ptr<CFX_SystemHandler> m_pSysHandler;
+  bool m_bChangeMask;
+  bool m_bBeingDestroyed;
+};
+
+#endif  // FPDFSDK_CPDFSDK_FORMFILLENVIRONMENT_H_
diff --git a/fpdfsdk/cpdfsdk_interform.cpp b/fpdfsdk/cpdfsdk_interform.cpp
new file mode 100644
index 0000000..7b77180
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_interform.cpp
@@ -0,0 +1,702 @@
+// 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/cpdfsdk_interform.h"
+
+#include <algorithm>
+#include <memory>
+#include <vector>
+
+#include "core/fpdfapi/page/cpdf_page.h"
+#include "core/fpdfapi/parser/cfdf_document.h"
+#include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/cpdf_stream.h"
+#include "core/fpdfdoc/cpdf_actionfields.h"
+#include "core/fpdfdoc/cpdf_interform.h"
+#include "core/fxge/cfx_graphstatedata.h"
+#include "core/fxge/cfx_pathdata.h"
+#include "core/fxge/cfx_renderdevice.h"
+#include "fpdfsdk/cba_annotiterator.h"
+#include "fpdfsdk/cpdfsdk_annot.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/cpdfsdk_pageview.h"
+#include "fpdfsdk/cpdfsdk_widget.h"
+#include "fpdfsdk/formfiller/cffl_formfiller.h"
+#include "fpdfsdk/fsdk_actionhandler.h"
+#include "fpdfsdk/fsdk_define.h"
+#include "fpdfsdk/fxedit/fxet_edit.h"
+#include "fpdfsdk/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/cpdfsdk_xfawidget.h"
+#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
+#include "fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h"
+#include "xfa/fxfa/cxfa_eventparam.h"
+#include "xfa/fxfa/xfa_ffdocview.h"
+#include "xfa/fxfa/xfa_ffwidget.h"
+#include "xfa/fxfa/xfa_ffwidgethandler.h"
+#endif  // PDF_ENABLE_XFA
+
+CPDFSDK_InterForm::CPDFSDK_InterForm(CPDFSDK_FormFillEnvironment* pFormFillEnv)
+    : m_pFormFillEnv(pFormFillEnv),
+      m_pInterForm(new CPDF_InterForm(m_pFormFillEnv->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
+}
+
+bool CPDFSDK_InterForm::HighlightWidgets() {
+  return false;
+}
+
+CPDFSDK_Widget* CPDFSDK_InterForm::GetSibling(CPDFSDK_Widget* pWidget,
+                                              bool bNext) const {
+  std::unique_ptr<CBA_AnnotIterator> pIterator(new CBA_AnnotIterator(
+      pWidget->GetPageView(), CPDF_Annot::Subtype::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) 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;
+
+  CPDF_Dictionary* pControlDict = pControl->GetWidget();
+  CPDF_Document* pDocument = m_pFormFillEnv->GetPDFDocument();
+  CPDFSDK_PageView* pPage = nullptr;
+
+  if (CPDF_Dictionary* pPageDict = pControlDict->GetDictFor("P")) {
+    int nPageIndex = pDocument->GetPageIndex(pPageDict->GetObjNum());
+    if (nPageIndex >= 0)
+      pPage = m_pFormFillEnv->GetPageView(nPageIndex);
+  }
+
+  if (!pPage) {
+    int nPageIndex = GetPageIndexByAnnotDict(pDocument, pControlDict);
+    if (nPageIndex >= 0)
+      pPage = m_pFormFillEnv->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_Annot::ObservedPtr>* 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_Annot::ObservedPtr>* 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);
+    if (pWidget)
+      widgets->emplace_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->GetArrayFor("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(bool bEnabled) {
+  m_bCalculate = bEnabled;
+}
+
+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(bool bEnabled) {
+  m_bXfaCalculate = bEnabled;
+}
+bool CPDFSDK_InterForm::IsXfaCalculateEnabled() const {
+  return m_bXfaCalculate;
+}
+
+bool CPDFSDK_InterForm::IsXfaValidationsEnabled() {
+  return m_bXfaValidationsEnabled;
+}
+void CPDFSDK_InterForm::XfaSetValidationsEnabled(bool bEnabled) {
+  m_bXfaValidationsEnabled = bEnabled;
+}
+
+void CPDFSDK_InterForm::SynchronizeField(CPDF_FormField* pFormField,
+                                         bool bSynchronizeElse) {
+  for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
+    CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
+    if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl))
+      pWidget->Synchronize(bSynchronizeElse);
+  }
+}
+#endif  // PDF_ENABLE_XFA
+
+void CPDFSDK_InterForm::OnCalculate(CPDF_FormField* pFormField) {
+  if (!m_pFormFillEnv->IsJSInitiated())
+    return;
+
+  if (m_bBusy)
+    return;
+
+  m_bBusy = true;
+
+  if (!IsCalculateEnabled()) {
+    m_bBusy = false;
+    return;
+  }
+
+  IJS_Runtime* pRuntime = m_pFormFillEnv->GetJSRuntime();
+  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;
+    bool bRC = true;
+    pContext->OnField_Calculate(pFormField, pField, sValue, bRC);
+
+    CFX_WideString sInfo;
+    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,
+                                           bool& bFormatted) {
+  CFX_WideString sValue = pFormField->GetValue();
+  if (!m_pFormFillEnv->IsJSInitiated()) {
+    bFormatted = false;
+    return sValue;
+  }
+
+  IJS_Runtime* pRuntime = m_pFormFillEnv->GetJSRuntime();
+  if (pFormField->GetFieldType() == FIELDTYPE_COMBOBOX &&
+      pFormField->CountSelectedItems() > 0) {
+    int index = pFormField->GetSelectedIndex(0);
+    if (index >= 0)
+      sValue = pFormField->GetOptionLabel(index);
+  }
+
+  bFormatted = 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;
+        bool bRet = pContext->RunScript(script, &sInfo);
+        pRuntime->ReleaseContext(pContext);
+
+        if (bRet) {
+          sValue = Value;
+          bFormatted = true;
+        }
+      }
+    }
+  }
+
+  return sValue;
+}
+
+void CPDFSDK_InterForm::ResetFieldAppearance(CPDF_FormField* pFormField,
+                                             const CFX_WideString* sValue,
+                                             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))
+      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)) {
+      UnderlyingPageType* pPage = pWidget->GetUnderlyingPage();
+      CPDFSDK_PageView* pPageView = m_pFormFillEnv->GetPageView(pPage, false);
+      FX_RECT rcBBox = m_pFormFillEnv->GetInteractiveFormFiller()->GetViewBBox(
+          pPageView, pWidget);
+
+      m_pFormFillEnv->Invalidate(pPage, rcBBox.left, rcBBox.top, rcBBox.right,
+                                 rcBBox.bottom);
+    }
+  }
+}
+
+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;
+
+  CPDFSDK_ActionHandler* pActionHandler = m_pFormFillEnv->GetActionHander();
+  PDFSDK_FieldAction fa;
+  fa.bModifier = m_pFormFillEnv->IsCTRLKeyDown(0);
+  fa.bShift = m_pFormFillEnv->IsSHIFTKeyDown(0);
+  fa.sValue = csValue;
+  pActionHandler->DoAction_FieldJavaScript(action, CPDF_AAction::KeyStroke,
+                                           m_pFormFillEnv, pFormField, fa);
+  return fa.bRC;
+}
+
+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;
+
+  CPDFSDK_ActionHandler* pActionHandler = m_pFormFillEnv->GetActionHander();
+  PDFSDK_FieldAction fa;
+  fa.bModifier = m_pFormFillEnv->IsCTRLKeyDown(0);
+  fa.bShift = m_pFormFillEnv->IsSHIFTKeyDown(0);
+  fa.sValue = csValue;
+  pActionHandler->DoAction_FieldJavaScript(action, CPDF_AAction::Validate,
+                                           m_pFormFillEnv, pFormField, fa);
+  return fa.bRC;
+}
+
+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();
+  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)) {
+        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;
+}
+
+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);
+}
+
+bool CPDFSDK_InterForm::SubmitFields(const CFX_WideString& csDestination,
+                                     const std::vector<CPDF_FormField*>& fields,
+                                     bool bIncludeOrExclude,
+                                     bool bUrlEncoded) {
+  CFX_ByteTextBuf textBuf;
+  ExportFieldsToFDFTextBuf(fields, bIncludeOrExclude, textBuf);
+
+  uint8_t* pBuffer = textBuf.GetBuffer();
+  FX_STRSIZE nBufSize = textBuf.GetLength();
+
+  if (bUrlEncoded && !FDFToURLEncodedData(pBuffer, nBufSize))
+    return false;
+
+  m_pFormFillEnv->JS_docSubmitForm(pBuffer, nBufSize, csDestination.c_str());
+  return true;
+}
+
+bool CPDFSDK_InterForm::FDFToURLEncodedData(CFX_WideString csFDFFile,
+                                            CFX_WideString csTxtFile) {
+  return true;
+}
+
+bool CPDFSDK_InterForm::FDFToURLEncodedData(uint8_t*& pBuf,
+                                            FX_STRSIZE& nBufSize) {
+  std::unique_ptr<CFDF_Document> pFDF =
+      CFDF_Document::ParseMemory(pBuf, nBufSize);
+  if (!pFDF)
+    return true;
+
+  CPDF_Dictionary* pMainDict = pFDF->GetRoot()->GetDictFor("FDF");
+  if (!pMainDict)
+    return false;
+
+  CPDF_Array* pFields = pMainDict->GetArrayFor("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->GetUnicodeTextFor("T");
+    CFX_ByteString name_b = CFX_ByteString::FromUnicode(name);
+    CFX_ByteString csBValue = pField->GetStringFor("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;
+}
+
+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_pFormFillEnv->JS_docGetFilePath().AsStringC(),
+                                fields, bIncludeOrExclude, false);
+  return pFDF ? pFDF->WriteBuf(textBuf) : false;
+}
+
+CFX_WideString CPDFSDK_InterForm::GetTemporaryFileName(
+    const CFX_WideString& sFileExt) {
+  return L"";
+}
+
+bool CPDFSDK_InterForm::SubmitForm(const CFX_WideString& sDestination,
+                                   bool bUrlEncoded) {
+  if (sDestination.IsEmpty())
+    return false;
+
+  if (!m_pFormFillEnv || !m_pInterForm)
+    return false;
+
+  std::unique_ptr<CFDF_Document> pFDFDoc = m_pInterForm->ExportToFDF(
+      m_pFormFillEnv->JS_docGetFilePath().AsStringC(), false);
+  if (!pFDFDoc)
+    return false;
+
+  CFX_ByteTextBuf FdfBuffer;
+  if (!pFDFDoc->WriteBuf(FdfBuffer))
+    return false;
+
+  uint8_t* pBuffer = FdfBuffer.GetBuffer();
+  FX_STRSIZE nBufSize = FdfBuffer.GetLength();
+  if (bUrlEncoded && !FDFToURLEncodedData(pBuffer, nBufSize))
+    return false;
+
+  m_pFormFillEnv->JS_docSubmitForm(pBuffer, nBufSize, sDestination.c_str());
+  if (bUrlEncoded)
+    FX_Free(pBuffer);
+
+  return true;
+}
+
+bool CPDFSDK_InterForm::ExportFormToFDFTextBuf(CFX_ByteTextBuf& textBuf) {
+  std::unique_ptr<CFDF_Document> pFDF = m_pInterForm->ExportToFDF(
+      m_pFormFillEnv->JS_docGetFilePath().AsStringC(), false);
+  return pFDF && pFDF->WriteBuf(textBuf);
+}
+
+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);
+}
+
+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);
+    bool bFormatted = false;
+    CFX_WideString sValue = OnFormat(pField, bFormatted);
+    ResetFieldAppearance(pField, bFormatted ? &sValue : 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);
+}
+
+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/cpdfsdk_interform.h b/fpdfsdk/cpdfsdk_interform.h
new file mode 100644
index 0000000..032399c
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_interform.h
@@ -0,0 +1,143 @@
+// 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_CPDFSDK_INTERFORM_H_
+#define FPDFSDK_CPDFSDK_INTERFORM_H_
+
+#include <map>
+#include <memory>
+#include <vector>
+
+#include "core/fpdfdoc/cpdf_action.h"
+#include "core/fpdfdoc/ipdf_formnotify.h"
+#include "core/fxcrt/fx_basic.h"
+#include "core/fxge/fx_dib.h"
+#include "fpdfsdk/cpdfsdk_widget.h"
+
+class CPDF_Dictionary;
+class CPDF_FormControl;
+class CPDF_FormField;
+class CPDF_InterForm;
+class CPDF_Object;
+class CPDFSDK_FormFillEnvironment;
+
+#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_FormFillEnvironment* pFormFillEnv);
+  ~CPDFSDK_InterForm() override;
+
+  CPDF_InterForm* GetInterForm() const { return m_pInterForm.get(); }
+  CPDFSDK_FormFillEnvironment* GetFormFillEnv() const { return m_pFormFillEnv; }
+
+  bool HighlightWidgets();
+
+  CPDFSDK_Widget* GetSibling(CPDFSDK_Widget* pWidget, bool bNext) const;
+  CPDFSDK_Widget* GetWidget(CPDF_FormControl* pControl) const;
+  void GetWidgets(const CFX_WideString& sFieldName,
+                  std::vector<CPDFSDK_Annot::ObservedPtr>* widgets) const;
+  void GetWidgets(CPDF_FormField* pField,
+                  std::vector<CPDFSDK_Annot::ObservedPtr>* widgets) const;
+
+  void AddMap(CPDF_FormControl* pControl, CPDFSDK_Widget* pWidget);
+  void RemoveMap(CPDF_FormControl* pControl);
+
+  void EnableCalculate(bool bEnabled);
+  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(bool bEnabled);
+  bool IsXfaCalculateEnabled() const;
+  bool IsXfaValidationsEnabled();
+  void XfaSetValidationsEnabled(bool bEnabled);
+  void SynchronizeField(CPDF_FormField* pFormField, bool bSynchronizeElse);
+#endif  // PDF_ENABLE_XFA
+
+  bool OnKeyStrokeCommit(CPDF_FormField* pFormField,
+                         const CFX_WideString& csValue);
+  bool OnValidate(CPDF_FormField* pFormField, const CFX_WideString& csValue);
+  void OnCalculate(CPDF_FormField* pFormField = nullptr);
+  CFX_WideString OnFormat(CPDF_FormField* pFormField, bool& bFormatted);
+
+  void ResetFieldAppearance(CPDF_FormField* pFormField,
+                            const CFX_WideString* sValue,
+                            bool bValueChanged);
+  void UpdateField(CPDF_FormField* pFormField);
+
+  bool DoAction_Hide(const CPDF_Action& action);
+  bool DoAction_SubmitForm(const CPDF_Action& action);
+  bool DoAction_ResetForm(const CPDF_Action& action);
+  bool DoAction_ImportData(const CPDF_Action& action);
+
+  std::vector<CPDF_FormField*> GetFieldFromObjects(
+      const std::vector<CPDF_Object*>& objects) const;
+  bool IsValidField(CPDF_Dictionary* pFieldDict);
+  bool SubmitFields(const CFX_WideString& csDestination,
+                    const std::vector<CPDF_FormField*>& fields,
+                    bool bIncludeOrExclude,
+                    bool bUrlEncoded);
+  bool SubmitForm(const CFX_WideString& sDestination, bool bUrlEncoded);
+  bool ExportFormToFDFTextBuf(CFX_ByteTextBuf& textBuf);
+  bool ExportFieldsToFDFTextBuf(const std::vector<CPDF_FormField*>& fields,
+                                bool bIncludeOrExclude,
+                                CFX_ByteTextBuf& textBuf);
+  CFX_WideString GetTemporaryFileName(const CFX_WideString& sFileExt);
+
+  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;
+
+  bool FDFToURLEncodedData(CFX_WideString csFDFFile, CFX_WideString csTxtFile);
+  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_FormFillEnvironment* m_pFormFillEnv;  // Not owned.
+  std::unique_ptr<CPDF_InterForm> m_pInterForm;
+  CPDFSDK_WidgetMap m_Map;
+#ifdef PDF_ENABLE_XFA
+  std::map<CXFA_FFWidget*, CPDFSDK_XFAWidget*> m_XFAMap;
+  bool m_bXfaCalculate;
+  bool m_bXfaValidationsEnabled;
+  static const int kNumFieldTypes = 7;
+#else   // PDF_ENABLE_XFA
+  static const int kNumFieldTypes = 6;
+#endif  // PDF_ENABLE_XFA
+  bool m_bCalculate;
+  bool m_bBusy;
+
+  FX_COLORREF m_aHighlightColor[kNumFieldTypes];
+  uint8_t m_iHighlightAlpha;
+  bool m_bNeedHightlight[kNumFieldTypes];
+};
+
+#endif  // FPDFSDK_CPDFSDK_INTERFORM_H_
diff --git a/fpdfsdk/cpdfsdk_pageview.cpp b/fpdfsdk/cpdfsdk_pageview.cpp
new file mode 100644
index 0000000..416adff
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_pageview.cpp
@@ -0,0 +1,502 @@
+// 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/cpdfsdk_pageview.h"
+
+#include <memory>
+#include <vector>
+
+#include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/render/cpdf_renderoptions.h"
+#include "core/fpdfdoc/cpdf_annotlist.h"
+#include "core/fpdfdoc/cpdf_interform.h"
+#include "fpdfsdk/cpdfsdk_annot.h"
+#include "fpdfsdk/cpdfsdk_annothandlermgr.h"
+#include "fpdfsdk/cpdfsdk_annotiteration.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/cpdfsdk_interform.h"
+#include "third_party/base/ptr_util.h"
+
+#ifdef PDF_ENABLE_XFA
+#include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
+#include "xfa/fxfa/xfa_ffdocview.h"
+#include "xfa/fxfa/xfa_ffpageview.h"
+#include "xfa/fxfa/xfa_ffwidgethandler.h"
+#include "xfa/fxfa/xfa_rendercontext.h"
+#include "xfa/fxgraphics/cfx_graphics.h"
+#endif  // PDF_ENABLE_XFA
+
+CPDFSDK_PageView::CPDFSDK_PageView(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                                   UnderlyingPageType* page)
+    : m_page(page),
+      m_pFormFillEnv(pFormFillEnv),
+#ifndef PDF_ENABLE_XFA
+      m_bOwnsPage(false),
+#endif  // PDF_ENABLE_XFA
+      m_bEnterWidget(false),
+      m_bExitWidget(false),
+      m_bOnWidget(false),
+      m_bValid(false),
+      m_bLocked(false),
+      m_bBeingDestroyed(false) {
+  CPDFSDK_InterForm* pInterForm = pFormFillEnv->GetInterForm();
+  if (pInterForm) {
+    CPDF_InterForm* pPDFInterForm = pInterForm->GetInterForm();
+#ifdef PDF_ENABLE_XFA
+    if (page->GetPDFPage())
+      pPDFInterForm->FixPageFields(page->GetPDFPage());
+#else   // PDF_ENABLE_XFA
+    pPDFInterForm->FixPageFields(page);
+#endif  // PDF_ENABLE_XFA
+  }
+#ifndef PDF_ENABLE_XFA
+  m_page->SetView(this);
+#endif  // PDF_ENABLE_XFA
+}
+
+CPDFSDK_PageView::~CPDFSDK_PageView() {
+#ifndef PDF_ENABLE_XFA
+  // The call to |ReleaseAnnot| can cause the page pointed to by |m_page| to
+  // be freed, which will cause issues if we try to cleanup the pageview pointer
+  // in |m_page|. So, reset the pageview pointer before doing anything else.
+  m_page->SetView(nullptr);
+#endif  // PDF_ENABLE_XFA
+
+  CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
+      m_pFormFillEnv->GetAnnotHandlerMgr();
+  for (CPDFSDK_Annot* pAnnot : m_SDKAnnotArray)
+    pAnnotHandlerMgr->ReleaseAnnot(pAnnot);
+
+  m_SDKAnnotArray.clear();
+  m_pAnnotList.reset();
+
+#ifndef PDF_ENABLE_XFA
+  if (m_bOwnsPage)
+    delete m_page;
+#endif  // PDF_ENABLE_XFA
+}
+
+void CPDFSDK_PageView::PageView_OnDraw(CFX_RenderDevice* pDevice,
+                                       CFX_Matrix* pUser2Device,
+#ifdef PDF_ENABLE_XFA
+                                       CPDF_RenderOptions* pOptions,
+                                       const FX_RECT& pClip) {
+#else
+                                       CPDF_RenderOptions* pOptions) {
+#endif  // PDF_ENABLE_XFA
+  m_curMatrix = *pUser2Device;
+
+#ifdef PDF_ENABLE_XFA
+  CPDFXFA_Page* pPage = GetPDFXFAPage();
+  if (!pPage)
+    return;
+
+  if (pPage->GetContext()->GetDocType() == DOCTYPE_DYNAMIC_XFA) {
+    CFX_Graphics gs;
+    gs.Create(pDevice);
+    CFX_RectF rectClip;
+    rectClip.Set(static_cast<FX_FLOAT>(pClip.left),
+                 static_cast<FX_FLOAT>(pClip.top),
+                 static_cast<FX_FLOAT>(pClip.Width()),
+                 static_cast<FX_FLOAT>(pClip.Height()));
+    gs.SetClipRect(rectClip);
+    std::unique_ptr<CXFA_RenderContext> pRenderContext(new CXFA_RenderContext);
+    CXFA_RenderOptions renderOptions;
+    renderOptions.m_bHighlight = true;
+    CXFA_FFPageView* xfaView = pPage->GetXFAPageView();
+    pRenderContext->StartRender(xfaView, &gs, *pUser2Device, renderOptions);
+    pRenderContext->DoRender();
+    pRenderContext->StopRender();
+    CXFA_FFDocView* docView = xfaView->GetDocView();
+    if (!docView)
+      return;
+    CPDFSDK_Annot* annot = GetFocusAnnot();
+    if (!annot)
+      return;
+    // Render the focus widget
+    docView->GetWidgetHandler()->RenderWidget(annot->GetXFAWidget(), &gs,
+                                              pUser2Device, false);
+    return;
+  }
+#endif  // PDF_ENABLE_XFA
+
+  // for pdf/static xfa.
+  CPDFSDK_AnnotIteration annotIteration(this, true);
+  for (const auto& pSDKAnnot : annotIteration) {
+    m_pFormFillEnv->GetAnnotHandlerMgr()->Annot_OnDraw(
+        this, pSDKAnnot.Get(), pDevice, pUser2Device, pOptions->m_bDrawAnnots);
+  }
+}
+
+CPDFSDK_Annot* CPDFSDK_PageView::GetFXAnnotAtPoint(FX_FLOAT pageX,
+                                                   FX_FLOAT pageY) {
+  CPDFSDK_AnnotHandlerMgr* pAnnotMgr = m_pFormFillEnv->GetAnnotHandlerMgr();
+  CPDFSDK_AnnotIteration annotIteration(this, false);
+  for (const auto& pSDKAnnot : annotIteration) {
+    CFX_FloatRect rc = pAnnotMgr->Annot_OnGetViewBBox(this, pSDKAnnot.Get());
+    if (pSDKAnnot->GetAnnotSubtype() == CPDF_Annot::Subtype::POPUP)
+      continue;
+    if (rc.Contains(pageX, pageY))
+      return pSDKAnnot.Get();
+  }
+  return nullptr;
+}
+
+CPDFSDK_Annot* CPDFSDK_PageView::GetFXWidgetAtPoint(FX_FLOAT pageX,
+                                                    FX_FLOAT pageY) {
+  CPDFSDK_AnnotHandlerMgr* pAnnotMgr = m_pFormFillEnv->GetAnnotHandlerMgr();
+  CPDFSDK_AnnotIteration annotIteration(this, false);
+  for (const auto& pSDKAnnot : annotIteration) {
+    bool bHitTest = pSDKAnnot->GetAnnotSubtype() == CPDF_Annot::Subtype::WIDGET;
+#ifdef PDF_ENABLE_XFA
+    bHitTest = bHitTest ||
+               pSDKAnnot->GetAnnotSubtype() == CPDF_Annot::Subtype::XFAWIDGET;
+#endif  // PDF_ENABLE_XFA
+    if (bHitTest) {
+      pAnnotMgr->Annot_OnGetViewBBox(this, pSDKAnnot.Get());
+      CFX_FloatPoint point(pageX, pageY);
+      if (pAnnotMgr->Annot_OnHitTest(this, pSDKAnnot.Get(), point))
+        return pSDKAnnot.Get();
+    }
+  }
+  return nullptr;
+}
+
+#ifdef PDF_ENABLE_XFA
+CPDFSDK_Annot* CPDFSDK_PageView::AddAnnot(CXFA_FFWidget* pPDFAnnot) {
+  if (!pPDFAnnot)
+    return nullptr;
+
+  CPDFSDK_Annot* pSDKAnnot = GetAnnotByXFAWidget(pPDFAnnot);
+  if (pSDKAnnot)
+    return pSDKAnnot;
+
+  CPDFSDK_AnnotHandlerMgr* pAnnotHandler = m_pFormFillEnv->GetAnnotHandlerMgr();
+  pSDKAnnot = pAnnotHandler->NewAnnot(pPDFAnnot, this);
+  if (!pSDKAnnot)
+    return nullptr;
+
+  m_SDKAnnotArray.push_back(pSDKAnnot);
+  return pSDKAnnot;
+}
+
+bool CPDFSDK_PageView::DeleteAnnot(CPDFSDK_Annot* pAnnot) {
+  if (!pAnnot)
+    return false;
+  CPDFXFA_Page* pPage = pAnnot->GetPDFXFAPage();
+  if (!pPage || (pPage->GetContext()->GetDocType() != DOCTYPE_STATIC_XFA &&
+                 pPage->GetContext()->GetDocType() != DOCTYPE_DYNAMIC_XFA))
+    return false;
+
+  if (GetFocusAnnot() == pAnnot)
+    m_pFormFillEnv->KillFocusAnnot(0);
+  CPDFSDK_AnnotHandlerMgr* pAnnotHandler = m_pFormFillEnv->GetAnnotHandlerMgr();
+  if (pAnnotHandler)
+    pAnnotHandler->ReleaseAnnot(pAnnot);
+
+  auto it = std::find(m_SDKAnnotArray.begin(), m_SDKAnnotArray.end(), pAnnot);
+  if (it != m_SDKAnnotArray.end())
+    m_SDKAnnotArray.erase(it);
+  if (m_pCaptureWidget.Get() == pAnnot)
+    m_pCaptureWidget.Reset();
+
+  return true;
+}
+#endif  // PDF_ENABLE_XFA
+
+CPDF_Document* CPDFSDK_PageView::GetPDFDocument() {
+  if (m_page) {
+#ifdef PDF_ENABLE_XFA
+    return m_page->GetContext()->GetPDFDoc();
+#else   // PDF_ENABLE_XFA
+    return m_page->m_pDocument;
+#endif  // PDF_ENABLE_XFA
+  }
+  return nullptr;
+}
+
+CPDF_Page* CPDFSDK_PageView::GetPDFPage() const {
+#ifdef PDF_ENABLE_XFA
+  return m_page ? m_page->GetPDFPage() : nullptr;
+#else   // PDF_ENABLE_XFA
+  return m_page;
+#endif  // PDF_ENABLE_XFA
+}
+
+CPDFSDK_Annot* CPDFSDK_PageView::GetAnnotByDict(CPDF_Dictionary* pDict) {
+  for (CPDFSDK_Annot* pAnnot : m_SDKAnnotArray) {
+    if (pAnnot->GetPDFAnnot()->GetAnnotDict() == pDict)
+      return pAnnot;
+  }
+  return nullptr;
+}
+
+#ifdef PDF_ENABLE_XFA
+CPDFSDK_Annot* CPDFSDK_PageView::GetAnnotByXFAWidget(CXFA_FFWidget* hWidget) {
+  if (!hWidget)
+    return nullptr;
+
+  for (CPDFSDK_Annot* pAnnot : m_SDKAnnotArray) {
+    if (pAnnot->GetXFAWidget() == hWidget)
+      return pAnnot;
+  }
+  return nullptr;
+}
+#endif  // PDF_ENABLE_XFA
+
+bool CPDFSDK_PageView::OnLButtonDown(const CFX_FloatPoint& point,
+                                     uint32_t nFlag) {
+  CPDFSDK_Annot::ObservedPtr pAnnot(GetFXWidgetAtPoint(point.x, point.y));
+  if (!pAnnot) {
+    m_pFormFillEnv->KillFocusAnnot(nFlag);
+    return false;
+  }
+
+  CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
+      m_pFormFillEnv->GetAnnotHandlerMgr();
+  if (!pAnnotHandlerMgr->Annot_OnLButtonDown(this, &pAnnot, nFlag, point))
+    return false;
+
+  if (!pAnnot)
+    return false;
+
+  m_pFormFillEnv->SetFocusAnnot(&pAnnot);
+  return true;
+}
+
+#ifdef PDF_ENABLE_XFA
+bool CPDFSDK_PageView::OnRButtonDown(const CFX_FloatPoint& point,
+                                     uint32_t nFlag) {
+  CPDFSDK_Annot::ObservedPtr pAnnot(GetFXWidgetAtPoint(point.x, point.y));
+  if (!pAnnot)
+    return false;
+
+  CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
+      m_pFormFillEnv->GetAnnotHandlerMgr();
+  bool ok = pAnnotHandlerMgr->Annot_OnRButtonDown(this, &pAnnot, nFlag, point);
+  if (!pAnnot)
+    return false;
+
+  if (ok)
+    m_pFormFillEnv->SetFocusAnnot(&pAnnot);
+
+  return true;
+}
+
+bool CPDFSDK_PageView::OnRButtonUp(const CFX_FloatPoint& point,
+                                   uint32_t nFlag) {
+  CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
+      m_pFormFillEnv->GetAnnotHandlerMgr();
+  CPDFSDK_Annot::ObservedPtr pFXAnnot(GetFXWidgetAtPoint(point.x, point.y));
+  if (!pFXAnnot)
+    return false;
+
+  if (pAnnotHandlerMgr->Annot_OnRButtonUp(this, &pFXAnnot, nFlag, point))
+    m_pFormFillEnv->SetFocusAnnot(&pFXAnnot);
+
+  return true;
+}
+#endif  // PDF_ENABLE_XFA
+
+bool CPDFSDK_PageView::OnLButtonUp(const CFX_FloatPoint& point,
+                                   uint32_t nFlag) {
+  CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
+      m_pFormFillEnv->GetAnnotHandlerMgr();
+  CPDFSDK_Annot::ObservedPtr pFXAnnot(GetFXWidgetAtPoint(point.x, point.y));
+  CPDFSDK_Annot::ObservedPtr pFocusAnnot(GetFocusAnnot());
+  if (pFocusAnnot && pFocusAnnot != pFXAnnot) {
+    // Last focus Annot gets a chance to handle the event.
+    if (pAnnotHandlerMgr->Annot_OnLButtonUp(this, &pFocusAnnot, nFlag, point))
+      return true;
+  }
+  return pFXAnnot &&
+         pAnnotHandlerMgr->Annot_OnLButtonUp(this, &pFXAnnot, nFlag, point);
+}
+
+bool CPDFSDK_PageView::OnMouseMove(const CFX_FloatPoint& point, int nFlag) {
+  CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
+      m_pFormFillEnv->GetAnnotHandlerMgr();
+  CPDFSDK_Annot::ObservedPtr pFXAnnot(GetFXAnnotAtPoint(point.x, point.y));
+  if (pFXAnnot) {
+    if (m_pCaptureWidget && m_pCaptureWidget != pFXAnnot) {
+      m_bExitWidget = true;
+      m_bEnterWidget = false;
+      pAnnotHandlerMgr->Annot_OnMouseExit(this, &m_pCaptureWidget, nFlag);
+    }
+    m_pCaptureWidget.Reset(pFXAnnot.Get());
+    m_bOnWidget = true;
+    if (!m_bEnterWidget) {
+      m_bEnterWidget = true;
+      m_bExitWidget = false;
+      pAnnotHandlerMgr->Annot_OnMouseEnter(this, &pFXAnnot, nFlag);
+    }
+    pAnnotHandlerMgr->Annot_OnMouseMove(this, &pFXAnnot, nFlag, point);
+    return true;
+  }
+  if (m_bOnWidget) {
+    m_bOnWidget = false;
+    m_bExitWidget = true;
+    m_bEnterWidget = false;
+    if (m_pCaptureWidget) {
+      pAnnotHandlerMgr->Annot_OnMouseExit(this, &m_pCaptureWidget, nFlag);
+      m_pCaptureWidget.Reset();
+    }
+  }
+  return false;
+}
+
+bool CPDFSDK_PageView::OnMouseWheel(double deltaX,
+                                    double deltaY,
+                                    const CFX_FloatPoint& point,
+                                    int nFlag) {
+  CPDFSDK_Annot::ObservedPtr pAnnot(GetFXWidgetAtPoint(point.x, point.y));
+  if (!pAnnot)
+    return false;
+
+  CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
+      m_pFormFillEnv->GetAnnotHandlerMgr();
+  return pAnnotHandlerMgr->Annot_OnMouseWheel(this, &pAnnot, nFlag, (int)deltaY,
+                                              point);
+}
+
+bool CPDFSDK_PageView::OnChar(int nChar, uint32_t nFlag) {
+  if (CPDFSDK_Annot* pAnnot = GetFocusAnnot()) {
+    CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
+        m_pFormFillEnv->GetAnnotHandlerMgr();
+    return pAnnotHandlerMgr->Annot_OnChar(pAnnot, nChar, nFlag);
+  }
+
+  return false;
+}
+
+bool CPDFSDK_PageView::OnKeyDown(int nKeyCode, int nFlag) {
+  if (CPDFSDK_Annot* pAnnot = GetFocusAnnot()) {
+    CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
+        m_pFormFillEnv->GetAnnotHandlerMgr();
+    return pAnnotHandlerMgr->Annot_OnKeyDown(pAnnot, nKeyCode, nFlag);
+  }
+  return false;
+}
+
+bool CPDFSDK_PageView::OnKeyUp(int nKeyCode, int nFlag) {
+  return false;
+}
+
+void CPDFSDK_PageView::LoadFXAnnots() {
+  CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
+      m_pFormFillEnv->GetAnnotHandlerMgr();
+
+  SetLock(true);
+
+#ifdef PDF_ENABLE_XFA
+  CFX_RetainPtr<CPDFXFA_Page> protector(m_page);
+  if (m_pFormFillEnv->GetXFAContext()->GetDocType() == DOCTYPE_DYNAMIC_XFA) {
+    CXFA_FFPageView* pageView = m_page->GetXFAPageView();
+    std::unique_ptr<IXFA_WidgetIterator> pWidgetHander(
+        pageView->CreateWidgetIterator(
+            XFA_TRAVERSEWAY_Form,
+            XFA_WidgetStatus_Visible | XFA_WidgetStatus_Viewable));
+    if (!pWidgetHander) {
+      SetLock(false);
+      return;
+    }
+
+    while (CXFA_FFWidget* pXFAAnnot = pWidgetHander->MoveToNext()) {
+      CPDFSDK_Annot* pAnnot = pAnnotHandlerMgr->NewAnnot(pXFAAnnot, this);
+      if (!pAnnot)
+        continue;
+      m_SDKAnnotArray.push_back(pAnnot);
+      pAnnotHandlerMgr->Annot_OnLoad(pAnnot);
+    }
+
+    SetLock(false);
+    return;
+  }
+#endif  // PDF_ENABLE_XFA
+
+  CPDF_Page* pPage = GetPDFPage();
+  ASSERT(pPage);
+  bool bUpdateAP = CPDF_InterForm::IsUpdateAPEnabled();
+  // Disable the default AP construction.
+  CPDF_InterForm::SetUpdateAP(false);
+  m_pAnnotList = pdfium::MakeUnique<CPDF_AnnotList>(pPage);
+  CPDF_InterForm::SetUpdateAP(bUpdateAP);
+
+  const size_t nCount = m_pAnnotList->Count();
+  for (size_t i = 0; i < nCount; ++i) {
+    CPDF_Annot* pPDFAnnot = m_pAnnotList->GetAt(i);
+    CheckUnSupportAnnot(GetPDFDocument(), pPDFAnnot);
+    CPDFSDK_Annot* pAnnot = pAnnotHandlerMgr->NewAnnot(pPDFAnnot, this);
+    if (!pAnnot)
+      continue;
+    m_SDKAnnotArray.push_back(pAnnot);
+    pAnnotHandlerMgr->Annot_OnLoad(pAnnot);
+  }
+
+  SetLock(false);
+}
+
+void CPDFSDK_PageView::UpdateRects(const std::vector<CFX_FloatRect>& rects) {
+  for (const auto& rc : rects)
+    m_pFormFillEnv->Invalidate(m_page, rc.left, rc.top, rc.right, rc.bottom);
+}
+
+void CPDFSDK_PageView::UpdateView(CPDFSDK_Annot* pAnnot) {
+  CFX_FloatRect rcWindow = pAnnot->GetRect();
+  m_pFormFillEnv->Invalidate(m_page, rcWindow.left, rcWindow.top,
+                             rcWindow.right, rcWindow.bottom);
+}
+
+int CPDFSDK_PageView::GetPageIndex() const {
+  if (!m_page)
+    return -1;
+
+#ifdef PDF_ENABLE_XFA
+  int nDocType = m_page->GetContext()->GetDocType();
+  switch (nDocType) {
+    case DOCTYPE_DYNAMIC_XFA: {
+      CXFA_FFPageView* pPageView = m_page->GetXFAPageView();
+      return pPageView ? pPageView->GetPageIndex() : -1;
+    }
+    case DOCTYPE_STATIC_XFA:
+    case DOCTYPE_PDF:
+      return GetPageIndexForStaticPDF();
+    default:
+      return -1;
+  }
+#else   // PDF_ENABLE_XFA
+  return GetPageIndexForStaticPDF();
+#endif  // PDF_ENABLE_XFA
+}
+
+bool CPDFSDK_PageView::IsValidAnnot(const CPDF_Annot* p) const {
+  if (!p)
+    return false;
+
+  const auto& annots = m_pAnnotList->All();
+  auto it = std::find_if(annots.begin(), annots.end(),
+                         [p](const std::unique_ptr<CPDF_Annot>& annot) {
+                           return annot.get() == p;
+                         });
+  return it != annots.end();
+}
+
+bool CPDFSDK_PageView::IsValidSDKAnnot(const CPDFSDK_Annot* p) const {
+  if (!p)
+    return false;
+  return pdfium::ContainsValue(m_SDKAnnotArray, p);
+}
+
+CPDFSDK_Annot* CPDFSDK_PageView::GetFocusAnnot() {
+  CPDFSDK_Annot* pFocusAnnot = m_pFormFillEnv->GetFocusAnnot();
+  return IsValidSDKAnnot(pFocusAnnot) ? pFocusAnnot : nullptr;
+}
+
+int CPDFSDK_PageView::GetPageIndexForStaticPDF() const {
+  CPDF_Dictionary* pDict = GetPDFPage()->m_pFormDict;
+  CPDF_Document* pDoc = m_pFormFillEnv->GetPDFDocument();
+  return (pDoc && pDict) ? pDoc->GetPageIndex(pDict->GetObjNum()) : -1;
+}
diff --git a/fpdfsdk/cpdfsdk_pageview.h b/fpdfsdk/cpdfsdk_pageview.h
new file mode 100644
index 0000000..9a3443b
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_pageview.h
@@ -0,0 +1,118 @@
+// 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_CPDFSDK_PAGEVIEW_H_
+#define FPDFSDK_CPDFSDK_PAGEVIEW_H_
+
+#include <memory>
+#include <vector>
+
+#include "core/fpdfapi/page/cpdf_page.h"
+#include "core/fxcrt/fx_system.h"
+#include "fpdfsdk/cpdfsdk_annot.h"
+
+class CFX_RenderDevice;
+class CPDF_AnnotList;
+class CPDF_RenderOptions;
+
+class CPDFSDK_PageView final : public CPDF_Page::View {
+ public:
+  CPDFSDK_PageView(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                   UnderlyingPageType* page);
+  ~CPDFSDK_PageView();
+
+#ifdef PDF_ENABLE_XFA
+  void PageView_OnDraw(CFX_RenderDevice* pDevice,
+                       CFX_Matrix* pUser2Device,
+                       CPDF_RenderOptions* pOptions,
+                       const FX_RECT& pClip);
+#else   // PDF_ENABLE_XFA
+  void PageView_OnDraw(CFX_RenderDevice* pDevice,
+                       CFX_Matrix* pUser2Device,
+                       CPDF_RenderOptions* pOptions);
+#endif  // PDF_ENABLE_XFA
+
+  CPDFSDK_Annot* GetFXAnnotAtPoint(FX_FLOAT pageX, FX_FLOAT pageY);
+  CPDFSDK_Annot* GetFXWidgetAtPoint(FX_FLOAT pageX, FX_FLOAT pageY);
+
+  void LoadFXAnnots();
+  CPDFSDK_Annot* GetFocusAnnot();
+  bool IsValidAnnot(const CPDF_Annot* p) const;
+  bool IsValidSDKAnnot(const CPDFSDK_Annot* p) const;
+
+  const std::vector<CPDFSDK_Annot*>& GetAnnotList() const {
+    return m_SDKAnnotArray;
+  }
+  CPDFSDK_Annot* GetAnnotByDict(CPDF_Dictionary* pDict);
+
+#ifdef PDF_ENABLE_XFA
+  bool DeleteAnnot(CPDFSDK_Annot* pAnnot);
+  CPDFSDK_Annot* AddAnnot(CXFA_FFWidget* pPDFAnnot);
+  CPDFSDK_Annot* GetAnnotByXFAWidget(CXFA_FFWidget* hWidget);
+
+  CPDFXFA_Page* GetPDFXFAPage() { return m_page; }
+#endif  // PDF_ENABLE_XFA
+
+  CPDF_Page* GetPDFPage() const;
+  CPDF_Document* GetPDFDocument();
+  CPDFSDK_FormFillEnvironment* GetFormFillEnv() const { return m_pFormFillEnv; }
+  bool OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag);
+  bool OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag);
+#ifdef PDF_ENABLE_XFA
+  bool OnRButtonDown(const CFX_FloatPoint& point, uint32_t nFlag);
+  bool OnRButtonUp(const CFX_FloatPoint& point, uint32_t nFlag);
+#endif  // PDF_ENABLE_XFA
+  bool OnChar(int nChar, uint32_t nFlag);
+  bool OnKeyDown(int nKeyCode, int nFlag);
+  bool OnKeyUp(int nKeyCode, int nFlag);
+
+  bool OnMouseMove(const CFX_FloatPoint& point, int nFlag);
+  bool OnMouseWheel(double deltaX,
+                    double deltaY,
+                    const CFX_FloatPoint& point,
+                    int nFlag);
+
+  void GetCurrentMatrix(CFX_Matrix& matrix) { matrix = m_curMatrix; }
+  void UpdateRects(const std::vector<CFX_FloatRect>& rects);
+  void UpdateView(CPDFSDK_Annot* pAnnot);
+
+  int GetPageIndex() const;
+
+  void SetValid(bool bValid) { m_bValid = bValid; }
+  bool IsValid() { return m_bValid; }
+
+  void SetLock(bool bLocked) { m_bLocked = bLocked; }
+  bool IsLocked() { return m_bLocked; }
+
+  void SetBeingDestroyed() { m_bBeingDestroyed = true; }
+  bool IsBeingDestroyed() const { return m_bBeingDestroyed; }
+
+#ifndef PDF_ENABLE_XFA
+  bool OwnsPage() const { return m_bOwnsPage; }
+  void TakePageOwnership() { m_bOwnsPage = true; }
+#endif  // PDF_ENABLE_XFA
+
+ private:
+  int GetPageIndexForStaticPDF() const;
+
+  CFX_Matrix m_curMatrix;
+  UnderlyingPageType* const m_page;
+  std::unique_ptr<CPDF_AnnotList> m_pAnnotList;
+  std::vector<CPDFSDK_Annot*> m_SDKAnnotArray;
+  CPDFSDK_FormFillEnvironment* const m_pFormFillEnv;  // Not owned.
+  CPDFSDK_Annot::ObservedPtr m_pCaptureWidget;
+#ifndef PDF_ENABLE_XFA
+  bool m_bOwnsPage;
+#endif  // PDF_ENABLE_XFA
+  bool m_bEnterWidget;
+  bool m_bExitWidget;
+  bool m_bOnWidget;
+  bool m_bValid;
+  bool m_bLocked;
+  bool m_bBeingDestroyed;
+};
+
+#endif  // FPDFSDK_CPDFSDK_PAGEVIEW_H_
diff --git a/fpdfsdk/cpdfsdk_widget.cpp b/fpdfsdk/cpdfsdk_widget.cpp
new file mode 100644
index 0000000..1086906
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_widget.cpp
@@ -0,0 +1,1932 @@
+// 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/cpdfsdk_widget.h"
+
+#include <memory>
+
+#include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfapi/parser/cpdf_dictionary.h"
+#include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/cpdf_reference.h"
+#include "core/fpdfapi/parser/cpdf_stream.h"
+#include "core/fpdfapi/parser/cpdf_string.h"
+#include "core/fpdfdoc/cpdf_defaultappearance.h"
+#include "core/fpdfdoc/cpdf_formcontrol.h"
+#include "core/fpdfdoc/cpdf_formfield.h"
+#include "core/fpdfdoc/cpdf_iconfit.h"
+#include "core/fpdfdoc/cpdf_interform.h"
+#include "core/fxge/cfx_graphstatedata.h"
+#include "core/fxge/cfx_pathdata.h"
+#include "core/fxge/cfx_renderdevice.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/cpdfsdk_interform.h"
+#include "fpdfsdk/cpdfsdk_pageview.h"
+#include "fpdfsdk/formfiller/cba_fontmap.h"
+#include "fpdfsdk/fsdk_actionhandler.h"
+#include "fpdfsdk/fsdk_define.h"
+#include "fpdfsdk/fxedit/fxet_edit.h"
+#include "fpdfsdk/pdfwindow/PWL_Edit.h"
+#include "fpdfsdk/pdfwindow/PWL_Utils.h"
+
+#ifdef PDF_ENABLE_XFA
+#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
+#include "xfa/fxfa/cxfa_eventparam.h"
+#include "xfa/fxfa/fxfa_widget.h"
+#include "xfa/fxfa/xfa_ffdocview.h"
+#include "xfa/fxfa/xfa_ffwidget.h"
+#include "xfa/fxfa/xfa_ffwidgethandler.h"
+#endif  // PDF_ENABLE_XFA
+
+namespace {
+
+// Convert a FX_ARGB to a FX_COLORREF.
+FX_COLORREF ARGBToColorRef(FX_ARGB argb) {
+  return (((static_cast<uint32_t>(argb) & 0x00FF0000) >> 16) |
+          (static_cast<uint32_t>(argb) & 0x0000FF00) |
+          ((static_cast<uint32_t>(argb) & 0x000000FF) << 16));
+}
+
+}  // namespace
+
+CPDFSDK_Widget::CPDFSDK_Widget(CPDF_Annot* pAnnot,
+                               CPDFSDK_PageView* pPageView,
+                               CPDFSDK_InterForm* pInterForm)
+    : CPDFSDK_BAAnnot(pAnnot, pPageView),
+      m_pInterForm(pInterForm),
+      m_nAppAge(0),
+      m_nValueAge(0)
+#ifdef PDF_ENABLE_XFA
+      ,
+      m_hMixXFAWidget(nullptr),
+      m_pWidgetHandler(nullptr)
+#endif  // PDF_ENABLE_XFA
+{
+}
+
+CPDFSDK_Widget::~CPDFSDK_Widget() {}
+
+#ifdef PDF_ENABLE_XFA
+CXFA_FFWidget* CPDFSDK_Widget::GetMixXFAWidget() const {
+  CPDFXFA_Context* pContext = m_pPageView->GetFormFillEnv()->GetXFAContext();
+  if (pContext->GetDocType() == DOCTYPE_STATIC_XFA) {
+    if (!m_hMixXFAWidget) {
+      if (CXFA_FFDocView* pDocView = pContext->GetXFADocView()) {
+        CFX_WideString sName;
+        if (GetFieldType() == FIELDTYPE_RADIOBUTTON) {
+          sName = GetAnnotName();
+          if (sName.IsEmpty())
+            sName = GetName();
+        } else {
+          sName = GetName();
+        }
+
+        if (!sName.IsEmpty())
+          m_hMixXFAWidget = pDocView->GetWidgetByName(sName, nullptr);
+      }
+    }
+    return m_hMixXFAWidget;
+  }
+
+  return nullptr;
+}
+
+CXFA_FFWidget* CPDFSDK_Widget::GetGroupMixXFAWidget() {
+  CPDFXFA_Context* pContext = m_pPageView->GetFormFillEnv()->GetXFAContext();
+  if (pContext->GetDocType() == DOCTYPE_STATIC_XFA) {
+    if (CXFA_FFDocView* pDocView = pContext->GetXFADocView()) {
+      CFX_WideString sName = GetName();
+      if (!sName.IsEmpty())
+        return pDocView->GetWidgetByName(sName, nullptr);
+    }
+  }
+
+  return nullptr;
+}
+
+CXFA_FFWidgetHandler* CPDFSDK_Widget::GetXFAWidgetHandler() const {
+  CPDFXFA_Context* pContext = m_pPageView->GetFormFillEnv()->GetXFAContext();
+  if (pContext->GetDocType() == DOCTYPE_STATIC_XFA) {
+    if (!m_pWidgetHandler) {
+      if (CXFA_FFDocView* pDocView = pContext->GetXFADocView())
+        m_pWidgetHandler = pDocView->GetWidgetHandler();
+    }
+    return m_pWidgetHandler;
+  }
+
+  return nullptr;
+}
+
+static XFA_EVENTTYPE GetXFAEventType(PDFSDK_XFAAActionType eXFAAAT) {
+  XFA_EVENTTYPE eEventType = XFA_EVENT_Unknown;
+
+  switch (eXFAAAT) {
+    case PDFSDK_XFA_Click:
+      eEventType = XFA_EVENT_Click;
+      break;
+    case PDFSDK_XFA_Full:
+      eEventType = XFA_EVENT_Full;
+      break;
+    case PDFSDK_XFA_PreOpen:
+      eEventType = XFA_EVENT_PreOpen;
+      break;
+    case PDFSDK_XFA_PostOpen:
+      eEventType = XFA_EVENT_PostOpen;
+      break;
+  }
+
+  return eEventType;
+}
+
+static XFA_EVENTTYPE GetXFAEventType(CPDF_AAction::AActionType eAAT,
+                                     bool bWillCommit) {
+  XFA_EVENTTYPE eEventType = XFA_EVENT_Unknown;
+
+  switch (eAAT) {
+    case CPDF_AAction::CursorEnter:
+      eEventType = XFA_EVENT_MouseEnter;
+      break;
+    case CPDF_AAction::CursorExit:
+      eEventType = XFA_EVENT_MouseExit;
+      break;
+    case CPDF_AAction::ButtonDown:
+      eEventType = XFA_EVENT_MouseDown;
+      break;
+    case CPDF_AAction::ButtonUp:
+      eEventType = XFA_EVENT_MouseUp;
+      break;
+    case CPDF_AAction::GetFocus:
+      eEventType = XFA_EVENT_Enter;
+      break;
+    case CPDF_AAction::LoseFocus:
+      eEventType = XFA_EVENT_Exit;
+      break;
+    case CPDF_AAction::PageOpen:
+      break;
+    case CPDF_AAction::PageClose:
+      break;
+    case CPDF_AAction::PageVisible:
+      break;
+    case CPDF_AAction::PageInvisible:
+      break;
+    case CPDF_AAction::KeyStroke:
+      if (!bWillCommit)
+        eEventType = XFA_EVENT_Change;
+      break;
+    case CPDF_AAction::Validate:
+      eEventType = XFA_EVENT_Validate;
+      break;
+    case CPDF_AAction::OpenPage:
+    case CPDF_AAction::ClosePage:
+    case CPDF_AAction::Format:
+    case CPDF_AAction::Calculate:
+    case CPDF_AAction::CloseDocument:
+    case CPDF_AAction::SaveDocument:
+    case CPDF_AAction::DocumentSaved:
+    case CPDF_AAction::PrintDocument:
+    case CPDF_AAction::DocumentPrinted:
+      break;
+  }
+
+  return eEventType;
+}
+
+bool CPDFSDK_Widget::HasXFAAAction(PDFSDK_XFAAActionType eXFAAAT) {
+  CXFA_FFWidget* hWidget = GetMixXFAWidget();
+  if (!hWidget)
+    return false;
+
+  CXFA_FFWidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler();
+  if (!pXFAWidgetHandler)
+    return false;
+
+  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;
+    }
+  }
+
+  pAcc = hWidget->GetDataAcc();
+  return pXFAWidgetHandler->HasEvent(pAcc, eEventType);
+}
+
+bool CPDFSDK_Widget::OnXFAAAction(PDFSDK_XFAAActionType eXFAAAT,
+                                  PDFSDK_FieldAction& data,
+                                  CPDFSDK_PageView* pPageView) {
+  CPDFXFA_Context* pContext = m_pPageView->GetFormFillEnv()->GetXFAContext();
+
+  CXFA_FFWidget* hWidget = GetMixXFAWidget();
+  if (!hWidget)
+    return false;
+
+  XFA_EVENTTYPE eEventType = GetXFAEventType(eXFAAAT);
+  if (eEventType == XFA_EVENT_Unknown)
+    return false;
+
+  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);
+
+  if (CXFA_FFDocView* pDocView = pContext->GetXFADocView())
+    pDocView->UpdateDocView();
+
+  return nRet == XFA_EVENTERROR_Success;
+}
+
+void CPDFSDK_Widget::Synchronize(bool bSynchronizeElse) {
+  CXFA_FFWidget* hWidget = GetMixXFAWidget();
+  if (!hWidget)
+    return;
+
+  CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc();
+  if (!pWidgetAcc)
+    return;
+
+  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();
+
+      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();
+
+      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() {
+  CPDFXFA_Context* pContext = m_pPageView->GetFormFillEnv()->GetXFAContext();
+  CXFA_FFDocView* pXFADocView = pContext->GetXFADocView();
+  if (!pXFADocView)
+    return;
+
+  if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
+    if (GetXFAWidgetHandler()) {
+      CPDFSDK_Widget::SynchronizeXFAValue(pXFADocView, hWidget, GetFormField(),
+                                          GetFormControl());
+    }
+  }
+}
+
+void CPDFSDK_Widget::SynchronizeXFAItems() {
+  CPDFXFA_Context* pContext = m_pPageView->GetFormFillEnv()->GetXFAContext();
+  CXFA_FFDocView* pXFADocView = pContext->GetXFADocView();
+  if (!pXFADocView)
+    return;
+
+  if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
+    if (GetXFAWidgetHandler())
+      SynchronizeXFAItems(pXFADocView, hWidget, GetFormField(), nullptr);
+  }
+}
+
+void CPDFSDK_Widget::SynchronizeXFAValue(CXFA_FFDocView* pXFADocView,
+                                         CXFA_FFWidget* hWidget,
+                                         CPDF_FormField* pFormField,
+                                         CPDF_FormControl* pFormControl) {
+  ASSERT(hWidget);
+  ASSERT(pFormControl);
+
+  switch (pFormField->GetFieldType()) {
+    case FIELDTYPE_CHECKBOX: {
+      if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
+        pFormField->CheckControl(
+            pFormField->GetControlIndex(pFormControl),
+            pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On, true);
+      }
+      break;
+    }
+    case FIELDTYPE_RADIOBUTTON: {
+      // TODO(weili): Check whether we need to handle checkbox and radio
+      // button differently, otherwise, merge these two cases.
+      if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
+        pFormField->CheckControl(
+            pFormField->GetControlIndex(pFormControl),
+            pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On, true);
+      }
+      break;
+    }
+    case FIELDTYPE_TEXTFIELD: {
+      if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
+        CFX_WideString sValue;
+        pWidgetAcc->GetValue(sValue, XFA_VALUEPICTURE_Display);
+        pFormField->SetValue(sValue, true);
+      }
+      break;
+    }
+    case FIELDTYPE_LISTBOX: {
+      pFormField->ClearSelection(false);
+
+      if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
+        for (int i = 0, sz = pWidgetAcc->CountSelectedItems(); i < sz; i++) {
+          int nIndex = pWidgetAcc->GetSelectedItem(i);
+
+          if (nIndex > -1 && nIndex < pFormField->CountOptions()) {
+            pFormField->SetItemSelection(nIndex, true, true);
+          }
+        }
+      }
+      break;
+    }
+    case FIELDTYPE_COMBOBOX: {
+      pFormField->ClearSelection(false);
+
+      if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
+        for (int i = 0, sz = pWidgetAcc->CountSelectedItems(); i < sz; i++) {
+          int nIndex = pWidgetAcc->GetSelectedItem(i);
+
+          if (nIndex > -1 && nIndex < pFormField->CountOptions()) {
+            pFormField->SetItemSelection(nIndex, true, true);
+          }
+        }
+
+        CFX_WideString sValue;
+        pWidgetAcc->GetValue(sValue, XFA_VALUEPICTURE_Display);
+        pFormField->SetValue(sValue, true);
+      }
+      break;
+    }
+  }
+}
+
+void CPDFSDK_Widget::SynchronizeXFAItems(CXFA_FFDocView* pXFADocView,
+                                         CXFA_FFWidget* hWidget,
+                                         CPDF_FormField* pFormField,
+                                         CPDF_FormControl* pFormControl) {
+  ASSERT(hWidget);
+
+  switch (pFormField->GetFieldType()) {
+    case FIELDTYPE_LISTBOX: {
+      pFormField->ClearSelection(false);
+      pFormField->ClearOptions(true);
+
+      if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
+        for (int i = 0, sz = pWidgetAcc->CountChoiceListItems(); i < sz; i++) {
+          CFX_WideString swText;
+          pWidgetAcc->GetChoiceListItem(swText, i);
+
+          pFormField->InsertOption(swText, i, true);
+        }
+      }
+      break;
+    }
+    case FIELDTYPE_COMBOBOX: {
+      pFormField->ClearSelection(false);
+      pFormField->ClearOptions(false);
+
+      if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
+        for (int i = 0, sz = pWidgetAcc->CountChoiceListItems(); i < sz; i++) {
+          CFX_WideString swText;
+          pWidgetAcc->GetChoiceListItem(swText, i);
+
+          pFormField->InsertOption(swText, i, false);
+        }
+      }
+
+      pFormField->SetValue(L"", true);
+      break;
+    }
+  }
+}
+#endif  // PDF_ENABLE_XFA
+
+bool CPDFSDK_Widget::IsWidgetAppearanceValid(CPDF_Annot::AppearanceMode mode) {
+  CPDF_Dictionary* pAP = m_pAnnot->GetAnnotDict()->GetDictFor("AP");
+  if (!pAP)
+    return false;
+
+  // Choose the right sub-ap
+  const FX_CHAR* ap_entry = "N";
+  if (mode == CPDF_Annot::Down)
+    ap_entry = "D";
+  else if (mode == CPDF_Annot::Rollover)
+    ap_entry = "R";
+  if (!pAP->KeyExist(ap_entry))
+    ap_entry = "N";
+
+  // Get the AP stream or subdirectory
+  CPDF_Object* psub = pAP->GetDirectObjectFor(ap_entry);
+  if (!psub)
+    return false;
+
+  int nFieldType = GetFieldType();
+  switch (nFieldType) {
+    case FIELDTYPE_PUSHBUTTON:
+    case FIELDTYPE_COMBOBOX:
+    case FIELDTYPE_LISTBOX:
+    case FIELDTYPE_TEXTFIELD:
+    case FIELDTYPE_SIGNATURE:
+      return psub->IsStream();
+    case FIELDTYPE_CHECKBOX:
+    case FIELDTYPE_RADIOBUTTON:
+      if (CPDF_Dictionary* pSubDict = psub->AsDictionary()) {
+        return !!pSubDict->GetStreamFor(GetAppState());
+      }
+      return false;
+  }
+  return true;
+}
+
+int CPDFSDK_Widget::GetFieldType() const {
+  CPDF_FormField* pField = GetFormField();
+  return pField ? pField->GetFieldType() : FIELDTYPE_UNKNOWN;
+}
+
+bool CPDFSDK_Widget::IsAppearanceValid() {
+#ifdef PDF_ENABLE_XFA
+  CPDFXFA_Context* pContext = m_pPageView->GetFormFillEnv()->GetXFAContext();
+  int nDocType = pContext->GetDocType();
+  if (nDocType != DOCTYPE_PDF && nDocType != DOCTYPE_STATIC_XFA)
+    return true;
+#endif  // PDF_ENABLE_XFA
+  return CPDFSDK_BAAnnot::IsAppearanceValid();
+}
+
+int CPDFSDK_Widget::GetLayoutOrder() const {
+  return 2;
+}
+
+int CPDFSDK_Widget::GetFieldFlags() const {
+  CPDF_InterForm* pPDFInterForm = m_pInterForm->GetInterForm();
+  CPDF_FormControl* pFormControl =
+      pPDFInterForm->GetControlByDict(m_pAnnot->GetAnnotDict());
+  CPDF_FormField* pFormField = pFormControl->GetField();
+  return pFormField->GetFieldFlags();
+}
+
+bool CPDFSDK_Widget::IsSignatureWidget() const {
+  return GetFieldType() == FIELDTYPE_SIGNATURE;
+}
+
+CPDF_FormField* CPDFSDK_Widget::GetFormField() const {
+  CPDF_FormControl* pControl = GetFormControl();
+  return pControl ? pControl->GetField() : nullptr;
+}
+
+CPDF_FormControl* CPDFSDK_Widget::GetFormControl() const {
+  CPDF_InterForm* pPDFInterForm = m_pInterForm->GetInterForm();
+  return pPDFInterForm->GetControlByDict(GetAnnotDict());
+}
+
+CPDF_FormControl* CPDFSDK_Widget::GetFormControl(
+    CPDF_InterForm* pInterForm,
+    const CPDF_Dictionary* pAnnotDict) {
+  ASSERT(pAnnotDict);
+  return pInterForm->GetControlByDict(pAnnotDict);
+}
+
+int CPDFSDK_Widget::GetRotate() const {
+  CPDF_FormControl* pCtrl = GetFormControl();
+  return pCtrl->GetRotation() % 360;
+}
+
+#ifdef PDF_ENABLE_XFA
+CFX_WideString CPDFSDK_Widget::GetName() const {
+  CPDF_FormField* pFormField = GetFormField();
+  return pFormField->GetFullName();
+}
+#endif  // PDF_ENABLE_XFA
+
+bool CPDFSDK_Widget::GetFillColor(FX_COLORREF& color) const {
+  CPDF_FormControl* pFormCtrl = GetFormControl();
+  int iColorType = 0;
+  color = ARGBToColorRef(pFormCtrl->GetBackgroundColor(iColorType));
+  return iColorType != COLORTYPE_TRANSPARENT;
+}
+
+bool CPDFSDK_Widget::GetBorderColor(FX_COLORREF& color) const {
+  CPDF_FormControl* pFormCtrl = GetFormControl();
+  int iColorType = 0;
+  color = ARGBToColorRef(pFormCtrl->GetBorderColor(iColorType));
+  return iColorType != COLORTYPE_TRANSPARENT;
+}
+
+bool CPDFSDK_Widget::GetTextColor(FX_COLORREF& color) const {
+  CPDF_FormControl* pFormCtrl = GetFormControl();
+  CPDF_DefaultAppearance da = pFormCtrl->GetDefaultAppearance();
+  if (!da.HasColor())
+    return false;
+
+  FX_ARGB argb;
+  int iColorType = COLORTYPE_TRANSPARENT;
+  da.GetColor(argb, iColorType);
+  color = ARGBToColorRef(argb);
+  return iColorType != COLORTYPE_TRANSPARENT;
+}
+
+FX_FLOAT CPDFSDK_Widget::GetFontSize() const {
+  CPDF_FormControl* pFormCtrl = GetFormControl();
+  CPDF_DefaultAppearance pDa = pFormCtrl->GetDefaultAppearance();
+  CFX_ByteString csFont = "";
+  FX_FLOAT fFontSize = 0.0f;
+  pDa.GetFont(csFont, fFontSize);
+
+  return fFontSize;
+}
+
+int CPDFSDK_Widget::GetSelectedIndex(int nIndex) const {
+#ifdef PDF_ENABLE_XFA
+  if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
+    if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
+      if (nIndex < pWidgetAcc->CountSelectedItems())
+        return pWidgetAcc->GetSelectedItem(nIndex);
+    }
+  }
+#endif  // PDF_ENABLE_XFA
+  CPDF_FormField* pFormField = GetFormField();
+  return pFormField->GetSelectedIndex(nIndex);
+}
+
+#ifdef PDF_ENABLE_XFA
+CFX_WideString CPDFSDK_Widget::GetValue(bool bDisplay) const {
+  if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
+    if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
+      CFX_WideString sValue;
+      pWidgetAcc->GetValue(
+          sValue, bDisplay ? XFA_VALUEPICTURE_Display : XFA_VALUEPICTURE_Edit);
+      return sValue;
+    }
+  }
+#else
+CFX_WideString CPDFSDK_Widget::GetValue() const {
+#endif  // PDF_ENABLE_XFA
+  CPDF_FormField* pFormField = GetFormField();
+  return pFormField->GetValue();
+}
+
+CFX_WideString CPDFSDK_Widget::GetDefaultValue() const {
+  CPDF_FormField* pFormField = GetFormField();
+  return pFormField->GetDefaultValue();
+}
+
+CFX_WideString CPDFSDK_Widget::GetOptionLabel(int nIndex) const {
+  CPDF_FormField* pFormField = GetFormField();
+  return pFormField->GetOptionLabel(nIndex);
+}
+
+int CPDFSDK_Widget::CountOptions() const {
+  CPDF_FormField* pFormField = GetFormField();
+  return pFormField->CountOptions();
+}
+
+bool CPDFSDK_Widget::IsOptionSelected(int nIndex) const {
+#ifdef PDF_ENABLE_XFA
+  if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
+    if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
+      if (nIndex > -1 && nIndex < pWidgetAcc->CountChoiceListItems())
+        return pWidgetAcc->GetItemState(nIndex);
+
+      return false;
+    }
+  }
+#endif  // PDF_ENABLE_XFA
+  CPDF_FormField* pFormField = GetFormField();
+  return pFormField->IsItemSelected(nIndex);
+}
+
+int CPDFSDK_Widget::GetTopVisibleIndex() const {
+  CPDF_FormField* pFormField = GetFormField();
+  return pFormField->GetTopVisibleIndex();
+}
+
+bool CPDFSDK_Widget::IsChecked() const {
+#ifdef PDF_ENABLE_XFA
+  if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
+    if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc())
+      return pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On;
+  }
+#endif  // PDF_ENABLE_XFA
+  CPDF_FormControl* pFormCtrl = GetFormControl();
+  return pFormCtrl->IsChecked();
+}
+
+int CPDFSDK_Widget::GetAlignment() const {
+  CPDF_FormControl* pFormCtrl = GetFormControl();
+  return pFormCtrl->GetControlAlignment();
+}
+
+int CPDFSDK_Widget::GetMaxLen() const {
+  CPDF_FormField* pFormField = GetFormField();
+  return pFormField->GetMaxLen();
+}
+
+void CPDFSDK_Widget::SetCheck(bool bChecked, bool bNotify) {
+  CPDF_FormControl* pFormCtrl = GetFormControl();
+  CPDF_FormField* pFormField = pFormCtrl->GetField();
+  pFormField->CheckControl(pFormField->GetControlIndex(pFormCtrl), bChecked,
+                           bNotify);
+#ifdef PDF_ENABLE_XFA
+  if (!IsWidgetAppearanceValid(CPDF_Annot::Normal))
+    ResetAppearance(true);
+  if (!bNotify)
+    Synchronize(true);
+#endif  // PDF_ENABLE_XFA
+}
+
+void CPDFSDK_Widget::SetValue(const CFX_WideString& sValue, bool bNotify) {
+  CPDF_FormField* pFormField = GetFormField();
+  pFormField->SetValue(sValue, bNotify);
+#ifdef PDF_ENABLE_XFA
+  if (!bNotify)
+    Synchronize(true);
+#endif  // PDF_ENABLE_XFA
+}
+
+void CPDFSDK_Widget::SetDefaultValue(const CFX_WideString& sValue) {}
+void CPDFSDK_Widget::SetOptionSelection(int index,
+                                        bool bSelected,
+                                        bool bNotify) {
+  CPDF_FormField* pFormField = GetFormField();
+  pFormField->SetItemSelection(index, bSelected, bNotify);
+#ifdef PDF_ENABLE_XFA
+  if (!bNotify)
+    Synchronize(true);
+#endif  // PDF_ENABLE_XFA
+}
+
+void CPDFSDK_Widget::ClearSelection(bool bNotify) {
+  CPDF_FormField* pFormField = GetFormField();
+  pFormField->ClearSelection(bNotify);
+#ifdef PDF_ENABLE_XFA
+  if (!bNotify)
+    Synchronize(true);
+#endif  // PDF_ENABLE_XFA
+}
+
+void CPDFSDK_Widget::SetTopVisibleIndex(int index) {}
+
+void CPDFSDK_Widget::SetAppModified() {
+  m_bAppModified = true;
+}
+
+void CPDFSDK_Widget::ClearAppModified() {
+  m_bAppModified = false;
+}
+
+bool CPDFSDK_Widget::IsAppModified() const {
+  return m_bAppModified;
+}
+
+#ifdef PDF_ENABLE_XFA
+void CPDFSDK_Widget::ResetAppearance(bool bValueChanged) {
+  switch (GetFieldType()) {
+    case FIELDTYPE_TEXTFIELD:
+    case FIELDTYPE_COMBOBOX: {
+      bool bFormatted = false;
+      CFX_WideString sValue = OnFormat(bFormatted);
+      ResetAppearance(bFormatted ? &sValue : nullptr, true);
+      break;
+    }
+    default:
+      ResetAppearance(nullptr, false);
+      break;
+  }
+}
+#endif  // PDF_ENABLE_XFA
+
+void CPDFSDK_Widget::ResetAppearance(const CFX_WideString* sValue,
+                                     bool bValueChanged) {
+  SetAppModified();
+
+  m_nAppAge++;
+  if (m_nAppAge > 999999)
+    m_nAppAge = 0;
+  if (bValueChanged)
+    m_nValueAge++;
+
+  int nFieldType = GetFieldType();
+
+  switch (nFieldType) {
+    case FIELDTYPE_PUSHBUTTON:
+      ResetAppearance_PushButton();
+      break;
+    case FIELDTYPE_CHECKBOX:
+      ResetAppearance_CheckBox();
+      break;
+    case FIELDTYPE_RADIOBUTTON:
+      ResetAppearance_RadioButton();
+      break;
+    case FIELDTYPE_COMBOBOX:
+      ResetAppearance_ComboBox(sValue);
+      break;
+    case FIELDTYPE_LISTBOX:
+      ResetAppearance_ListBox();
+      break;
+    case FIELDTYPE_TEXTFIELD:
+      ResetAppearance_TextField(sValue);
+      break;
+  }
+
+  m_pAnnot->ClearCachedAP();
+}
+
+CFX_WideString CPDFSDK_Widget::OnFormat(bool& bFormatted) {
+  CPDF_FormField* pFormField = GetFormField();
+  ASSERT(pFormField);
+  return m_pInterForm->OnFormat(pFormField, bFormatted);
+}
+
+void CPDFSDK_Widget::ResetFieldAppearance(bool bValueChanged) {
+  CPDF_FormField* pFormField = GetFormField();
+  ASSERT(pFormField);
+  m_pInterForm->ResetFieldAppearance(pFormField, nullptr, bValueChanged);
+}
+
+void CPDFSDK_Widget::DrawAppearance(CFX_RenderDevice* pDevice,
+                                    const CFX_Matrix* pUser2Device,
+                                    CPDF_Annot::AppearanceMode mode,
+                                    const CPDF_RenderOptions* pOptions) {
+  int nFieldType = GetFieldType();
+
+  if ((nFieldType == FIELDTYPE_CHECKBOX ||
+       nFieldType == FIELDTYPE_RADIOBUTTON) &&
+      mode == CPDF_Annot::Normal &&
+      !IsWidgetAppearanceValid(CPDF_Annot::Normal)) {
+    CFX_PathData pathData;
+
+    CFX_FloatRect rcAnnot = GetRect();
+
+    pathData.AppendRect(rcAnnot.left, rcAnnot.bottom, rcAnnot.right,
+                        rcAnnot.top);
+
+    CFX_GraphStateData gsd;
+    gsd.m_LineWidth = 0.0f;
+
+    pDevice->DrawPath(&pathData, pUser2Device, &gsd, 0, 0xFFAAAAAA,
+                      FXFILL_ALTERNATE);
+  } else {
+    CPDFSDK_BAAnnot::DrawAppearance(pDevice, pUser2Device, mode, pOptions);
+  }
+}
+
+void CPDFSDK_Widget::UpdateField() {
+  CPDF_FormField* pFormField = GetFormField();
+  ASSERT(pFormField);
+  m_pInterForm->UpdateField(pFormField);
+}
+
+void CPDFSDK_Widget::DrawShadow(CFX_RenderDevice* pDevice,
+                                CPDFSDK_PageView* pPageView) {
+  int nFieldType = GetFieldType();
+  if (!m_pInterForm->IsNeedHighLight(nFieldType))
+    return;
+
+  CFX_FloatRect rc = GetRect();
+  FX_COLORREF color = m_pInterForm->GetHighlightColor(nFieldType);
+  uint8_t alpha = m_pInterForm->GetHighlightAlpha();
+
+  CFX_FloatRect rcDevice;
+  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);
+
+  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() {
+  CPDF_FormControl* pControl = GetFormControl();
+  CFX_FloatRect rcWindow = GetRotatedRect();
+  int32_t nLayout = 0;
+  switch (pControl->GetTextPosition()) {
+    case TEXTPOS_ICON:
+      nLayout = PPBL_ICON;
+      break;
+    case TEXTPOS_BELOW:
+      nLayout = PPBL_ICONTOPLABELBOTTOM;
+      break;
+    case TEXTPOS_ABOVE:
+      nLayout = PPBL_LABELTOPICONBOTTOM;
+      break;
+    case TEXTPOS_RIGHT:
+      nLayout = PPBL_ICONLEFTLABELRIGHT;
+      break;
+    case TEXTPOS_LEFT:
+      nLayout = PPBL_LABELLEFTICONRIGHT;
+      break;
+    case TEXTPOS_OVERLAID:
+      nLayout = PPBL_LABELOVERICON;
+      break;
+    default:
+      nLayout = PPBL_LABEL;
+      break;
+  }
+
+  CPWL_Color crBackground, crBorder;
+
+  int iColorType;
+  FX_FLOAT fc[4];
+
+  pControl->GetOriginalBackgroundColor(iColorType, fc);
+  if (iColorType > 0)
+    crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
+
+  pControl->GetOriginalBorderColor(iColorType, fc);
+  if (iColorType > 0)
+    crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
+
+  FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
+  CPWL_Dash dsBorder(3, 0, 0);
+  CPWL_Color crLeftTop, crRightBottom;
+
+  BorderStyle nBorderStyle = GetBorderStyle();
+  switch (nBorderStyle) {
+    case BorderStyle::DASH:
+      dsBorder = CPWL_Dash(3, 3, 0);
+      break;
+    case BorderStyle::BEVELED:
+      fBorderWidth *= 2;
+      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
+      crRightBottom = CPWL_Utils::DevideColor(crBackground, 2);
+      break;
+    case BorderStyle::INSET:
+      fBorderWidth *= 2;
+      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5);
+      crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75);
+      break;
+    default:
+      break;
+  }
+
+  CFX_FloatRect rcClient = CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);
+
+  CPWL_Color crText(COLORTYPE_GRAY, 0);
+
+  FX_FLOAT fFontSize = 12.0f;
+  CFX_ByteString csNameTag;
+
+  CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
+  if (da.HasColor()) {
+    da.GetColor(iColorType, fc);
+    crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
+  }
+
+  if (da.HasFont())
+    da.GetFont(csNameTag, fFontSize);
+
+  CFX_WideString csWCaption;
+  CFX_WideString csNormalCaption, csRolloverCaption, csDownCaption;
+
+  if (pControl->HasMKEntry("CA"))
+    csNormalCaption = pControl->GetNormalCaption();
+
+  if (pControl->HasMKEntry("RC"))
+    csRolloverCaption = pControl->GetRolloverCaption();
+
+  if (pControl->HasMKEntry("AC"))
+    csDownCaption = pControl->GetDownCaption();
+
+  CPDF_Stream* pNormalIcon = nullptr;
+  CPDF_Stream* pRolloverIcon = nullptr;
+  CPDF_Stream* pDownIcon = nullptr;
+
+  if (pControl->HasMKEntry("I"))
+    pNormalIcon = pControl->GetNormalIcon();
+
+  if (pControl->HasMKEntry("RI"))
+    pRolloverIcon = pControl->GetRolloverIcon();
+
+  if (pControl->HasMKEntry("IX"))
+    pDownIcon = pControl->GetDownIcon();
+
+  if (pNormalIcon) {
+    if (CPDF_Dictionary* pImageDict = pNormalIcon->GetDict()) {
+      if (pImageDict->GetStringFor("Name").IsEmpty())
+        pImageDict->SetNewFor<CPDF_String>("Name", "ImgA", false);
+    }
+  }
+
+  if (pRolloverIcon) {
+    if (CPDF_Dictionary* pImageDict = pRolloverIcon->GetDict()) {
+      if (pImageDict->GetStringFor("Name").IsEmpty())
+        pImageDict->SetNewFor<CPDF_String>("Name", "ImgB", false);
+    }
+  }
+
+  if (pDownIcon) {
+    if (CPDF_Dictionary* pImageDict = pDownIcon->GetDict()) {
+      if (pImageDict->GetStringFor("Name").IsEmpty())
+        pImageDict->SetNewFor<CPDF_String>("Name", "ImgC", false);
+    }
+  }
+
+  CPDF_IconFit iconFit = pControl->GetIconFit();
+
+  CBA_FontMap font_map(this, m_pInterForm->GetFormFillEnv()->GetSysHandler());
+  font_map.SetAPType("N");
+
+  CFX_ByteString csAP =
+      CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
+      CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
+                                     crLeftTop, crRightBottom, nBorderStyle,
+                                     dsBorder) +
+      CPWL_Utils::GetPushButtonAppStream(
+          iconFit.GetFittingBounds() ? rcWindow : rcClient, &font_map,
+          pNormalIcon, iconFit, csNormalCaption, crText, fFontSize, nLayout);
+
+  WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP);
+  if (pNormalIcon)
+    AddImageToAppearance("N", pNormalIcon);
+
+  CPDF_FormControl::HighlightingMode eHLM = pControl->GetHighlightingMode();
+  if (eHLM == CPDF_FormControl::Push || eHLM == CPDF_FormControl::Toggle) {
+    if (csRolloverCaption.IsEmpty() && !pRolloverIcon) {
+      csRolloverCaption = csNormalCaption;
+      pRolloverIcon = pNormalIcon;
+    }
+
+    font_map.SetAPType("R");
+
+    csAP = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
+           CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
+                                          crLeftTop, crRightBottom,
+                                          nBorderStyle, dsBorder) +
+           CPWL_Utils::GetPushButtonAppStream(
+               iconFit.GetFittingBounds() ? rcWindow : rcClient, &font_map,
+               pRolloverIcon, iconFit, csRolloverCaption, crText, fFontSize,
+               nLayout);
+
+    WriteAppearance("R", GetRotatedRect(), GetMatrix(), csAP);
+    if (pRolloverIcon)
+      AddImageToAppearance("R", pRolloverIcon);
+
+    if (csDownCaption.IsEmpty() && !pDownIcon) {
+      csDownCaption = csNormalCaption;
+      pDownIcon = pNormalIcon;
+    }
+
+    switch (nBorderStyle) {
+      case BorderStyle::BEVELED: {
+        CPWL_Color crTemp = crLeftTop;
+        crLeftTop = crRightBottom;
+        crRightBottom = crTemp;
+        break;
+      }
+      case BorderStyle::INSET: {
+        crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0);
+        crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
+        break;
+      }
+      default:
+        break;
+    }
+
+    font_map.SetAPType("D");
+
+    csAP = CPWL_Utils::GetRectFillAppStream(
+               rcWindow, CPWL_Utils::SubstractColor(crBackground, 0.25f)) +
+           CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
+                                          crLeftTop, crRightBottom,
+                                          nBorderStyle, dsBorder) +
+           CPWL_Utils::GetPushButtonAppStream(
+               iconFit.GetFittingBounds() ? rcWindow : rcClient, &font_map,
+               pDownIcon, iconFit, csDownCaption, crText, fFontSize, nLayout);
+
+    WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP);
+    if (pDownIcon)
+      AddImageToAppearance("D", pDownIcon);
+  } else {
+    RemoveAppearance("D");
+    RemoveAppearance("R");
+  }
+}
+
+void CPDFSDK_Widget::ResetAppearance_CheckBox() {
+  CPDF_FormControl* pControl = GetFormControl();
+  CPWL_Color crBackground, crBorder, crText;
+  int iColorType;
+  FX_FLOAT fc[4];
+
+  pControl->GetOriginalBackgroundColor(iColorType, fc);
+  if (iColorType > 0)
+    crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
+
+  pControl->GetOriginalBorderColor(iColorType, fc);
+  if (iColorType > 0)
+    crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
+
+  FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
+  CPWL_Dash dsBorder(3, 0, 0);
+  CPWL_Color crLeftTop, crRightBottom;
+
+  BorderStyle nBorderStyle = GetBorderStyle();
+  switch (nBorderStyle) {
+    case BorderStyle::DASH:
+      dsBorder = CPWL_Dash(3, 3, 0);
+      break;
+    case BorderStyle::BEVELED:
+      fBorderWidth *= 2;
+      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
+      crRightBottom = CPWL_Utils::DevideColor(crBackground, 2);
+      break;
+    case BorderStyle::INSET:
+      fBorderWidth *= 2;
+      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5);
+      crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75);
+      break;
+    default:
+      break;
+  }
+
+  CFX_FloatRect rcWindow = GetRotatedRect();
+  CFX_FloatRect rcClient = CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);
+
+  CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
+  if (da.HasColor()) {
+    da.GetColor(iColorType, fc);
+    crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
+  }
+
+  int32_t nStyle = 0;
+
+  CFX_WideString csWCaption = pControl->GetNormalCaption();
+  if (csWCaption.GetLength() > 0) {
+    switch (csWCaption[0]) {
+      case L'l':
+        nStyle = PCS_CIRCLE;
+        break;
+      case L'8':
+        nStyle = PCS_CROSS;
+        break;
+      case L'u':
+        nStyle = PCS_DIAMOND;
+        break;
+      case L'n':
+        nStyle = PCS_SQUARE;
+        break;
+      case L'H':
+        nStyle = PCS_STAR;
+        break;
+      default:  // L'4'
+        nStyle = PCS_CHECK;
+        break;
+    }
+  } else {
+    nStyle = PCS_CHECK;
+  }
+
+  CFX_ByteString csAP_N_ON =
+      CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
+      CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
+                                     crLeftTop, crRightBottom, nBorderStyle,
+                                     dsBorder);
+
+  CFX_ByteString csAP_N_OFF = csAP_N_ON;
+
+  switch (nBorderStyle) {
+    case BorderStyle::BEVELED: {
+      CPWL_Color crTemp = crLeftTop;
+      crLeftTop = crRightBottom;
+      crRightBottom = crTemp;
+      break;
+    }
+    case BorderStyle::INSET: {
+      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0);
+      crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
+      break;
+    }
+    default:
+      break;
+  }
+
+  CFX_ByteString csAP_D_ON =
+      CPWL_Utils::GetRectFillAppStream(
+          rcWindow, CPWL_Utils::SubstractColor(crBackground, 0.25f)) +
+      CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
+                                     crLeftTop, crRightBottom, nBorderStyle,
+                                     dsBorder);
+
+  CFX_ByteString csAP_D_OFF = csAP_D_ON;
+
+  csAP_N_ON += CPWL_Utils::GetCheckBoxAppStream(rcClient, nStyle, crText);
+  csAP_D_ON += CPWL_Utils::GetCheckBoxAppStream(rcClient, nStyle, crText);
+
+  WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_ON,
+                  pControl->GetCheckedAPState());
+  WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_OFF, "Off");
+
+  WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_ON,
+                  pControl->GetCheckedAPState());
+  WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_OFF, "Off");
+
+  CFX_ByteString csAS = GetAppState();
+  if (csAS.IsEmpty())
+    SetAppState("Off");
+}
+
+void CPDFSDK_Widget::ResetAppearance_RadioButton() {
+  CPDF_FormControl* pControl = GetFormControl();
+  CPWL_Color crBackground, crBorder, crText;
+  int iColorType;
+  FX_FLOAT fc[4];
+
+  pControl->GetOriginalBackgroundColor(iColorType, fc);
+  if (iColorType > 0)
+    crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
+
+  pControl->GetOriginalBorderColor(iColorType, fc);
+  if (iColorType > 0)
+    crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
+
+  FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
+  CPWL_Dash dsBorder(3, 0, 0);
+  CPWL_Color crLeftTop, crRightBottom;
+
+  BorderStyle nBorderStyle = GetBorderStyle();
+  switch (nBorderStyle) {
+    case BorderStyle::DASH:
+      dsBorder = CPWL_Dash(3, 3, 0);
+      break;
+    case BorderStyle::BEVELED:
+      fBorderWidth *= 2;
+      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
+      crRightBottom = CPWL_Utils::DevideColor(crBackground, 2);
+      break;
+    case BorderStyle::INSET:
+      fBorderWidth *= 2;
+      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5);
+      crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75);
+      break;
+    default:
+      break;
+  }
+
+  CFX_FloatRect rcWindow = GetRotatedRect();
+  CFX_FloatRect rcClient = CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);
+
+  CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
+  if (da.HasColor()) {
+    da.GetColor(iColorType, fc);
+    crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
+  }
+
+  int32_t nStyle = 0;
+
+  CFX_WideString csWCaption = pControl->GetNormalCaption();
+  if (csWCaption.GetLength() > 0) {
+    switch (csWCaption[0]) {
+      default:  // L'l':
+        nStyle = PCS_CIRCLE;
+        break;
+      case L'8':
+        nStyle = PCS_CROSS;
+        break;
+      case L'u':
+        nStyle = PCS_DIAMOND;
+        break;
+      case L'n':
+        nStyle = PCS_SQUARE;
+        break;
+      case L'H':
+        nStyle = PCS_STAR;
+        break;
+      case L'4':
+        nStyle = PCS_CHECK;
+        break;
+    }
+  } else {
+    nStyle = PCS_CIRCLE;
+  }
+
+  CFX_ByteString csAP_N_ON;
+
+  CFX_FloatRect rcCenter =
+      CPWL_Utils::DeflateRect(CPWL_Utils::GetCenterSquare(rcWindow), 1.0f);
+
+  if (nStyle == PCS_CIRCLE) {
+    if (nBorderStyle == BorderStyle::BEVELED) {
+      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
+      crRightBottom = CPWL_Utils::SubstractColor(crBackground, 0.25f);
+    } else if (nBorderStyle == BorderStyle::INSET) {
+      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5f);
+      crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75f);
+    }
+
+    csAP_N_ON = CPWL_Utils::GetCircleFillAppStream(rcCenter, crBackground) +
+                CPWL_Utils::GetCircleBorderAppStream(
+                    rcCenter, fBorderWidth, crBorder, crLeftTop, crRightBottom,
+                    nBorderStyle, dsBorder);
+  } else {
+    csAP_N_ON = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
+                CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
+                                               crLeftTop, crRightBottom,
+                                               nBorderStyle, dsBorder);
+  }
+
+  CFX_ByteString csAP_N_OFF = csAP_N_ON;
+
+  switch (nBorderStyle) {
+    case BorderStyle::BEVELED: {
+      CPWL_Color crTemp = crLeftTop;
+      crLeftTop = crRightBottom;
+      crRightBottom = crTemp;
+      break;
+    }
+    case BorderStyle::INSET: {
+      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0);
+      crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
+      break;
+    }
+    default:
+      break;
+  }
+
+  CFX_ByteString csAP_D_ON;
+
+  if (nStyle == PCS_CIRCLE) {
+    CPWL_Color crBK = CPWL_Utils::SubstractColor(crBackground, 0.25f);
+    if (nBorderStyle == BorderStyle::BEVELED) {
+      crLeftTop = CPWL_Utils::SubstractColor(crBackground, 0.25f);
+      crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
+      crBK = crBackground;
+    } else if (nBorderStyle == BorderStyle::INSET) {
+      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0);
+      crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
+    }
+
+    csAP_D_ON = CPWL_Utils::GetCircleFillAppStream(rcCenter, crBK) +
+                CPWL_Utils::GetCircleBorderAppStream(
+                    rcCenter, fBorderWidth, crBorder, crLeftTop, crRightBottom,
+                    nBorderStyle, dsBorder);
+  } else {
+    csAP_D_ON = CPWL_Utils::GetRectFillAppStream(
+                    rcWindow, CPWL_Utils::SubstractColor(crBackground, 0.25f)) +
+                CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
+                                               crLeftTop, crRightBottom,
+                                               nBorderStyle, dsBorder);
+  }
+
+  CFX_ByteString csAP_D_OFF = csAP_D_ON;
+
+  csAP_N_ON += CPWL_Utils::GetRadioButtonAppStream(rcClient, nStyle, crText);
+  csAP_D_ON += CPWL_Utils::GetRadioButtonAppStream(rcClient, nStyle, crText);
+
+  WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_ON,
+                  pControl->GetCheckedAPState());
+  WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_OFF, "Off");
+
+  WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_ON,
+                  pControl->GetCheckedAPState());
+  WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_OFF, "Off");
+
+  CFX_ByteString csAS = GetAppState();
+  if (csAS.IsEmpty())
+    SetAppState("Off");
+}
+
+void CPDFSDK_Widget::ResetAppearance_ComboBox(const CFX_WideString* sValue) {
+  CPDF_FormControl* pControl = GetFormControl();
+  CPDF_FormField* pField = pControl->GetField();
+  CFX_ByteTextBuf sBody, sLines;
+
+  CFX_FloatRect rcClient = GetClientRect();
+  CFX_FloatRect rcButton = rcClient;
+  rcButton.left = rcButton.right - 13;
+  rcButton.Normalize();
+
+  std::unique_ptr<CFX_Edit> pEdit(new CFX_Edit);
+  pEdit->EnableRefresh(false);
+
+  CBA_FontMap font_map(this, m_pInterForm->GetFormFillEnv()->GetSysHandler());
+  pEdit->SetFontMap(&font_map);
+
+  CFX_FloatRect rcEdit = rcClient;
+  rcEdit.right = rcButton.left;
+  rcEdit.Normalize();
+
+  pEdit->SetPlateRect(rcEdit);
+  pEdit->SetAlignmentV(1, true);
+
+  FX_FLOAT fFontSize = GetFontSize();
+  if (IsFloatZero(fFontSize))
+    pEdit->SetAutoFontSize(true, true);
+  else
+    pEdit->SetFontSize(fFontSize);
+
+  pEdit->Initialize();
+
+  if (sValue) {
+    pEdit->SetText(*sValue);
+  } else {
+    int32_t nCurSel = pField->GetSelectedIndex(0);
+    if (nCurSel < 0)
+      pEdit->SetText(pField->GetValue());
+    else
+      pEdit->SetText(pField->GetOptionLabel(nCurSel));
+  }
+
+  CFX_FloatRect rcContent = pEdit->GetContentRect();
+
+  CFX_ByteString sEdit =
+      CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_FloatPoint());
+  if (sEdit.GetLength() > 0) {
+    sBody << "/Tx BMC\n"
+          << "q\n";
+    if (rcContent.Width() > rcEdit.Width() ||
+        rcContent.Height() > rcEdit.Height()) {
+      sBody << rcEdit.left << " " << rcEdit.bottom << " " << rcEdit.Width()
+            << " " << rcEdit.Height() << " re\nW\nn\n";
+    }
+
+    CPWL_Color crText = GetTextPWLColor();
+    sBody << "BT\n"
+          << CPWL_Utils::GetColorAppStream(crText) << sEdit << "ET\n"
+          << "Q\nEMC\n";
+  }
+
+  sBody << CPWL_Utils::GetDropButtonAppStream(rcButton);
+
+  CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() +
+                       sLines.AsStringC() + sBody.AsStringC();
+
+  WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
+}
+
+void CPDFSDK_Widget::ResetAppearance_ListBox() {
+  CPDF_FormControl* pControl = GetFormControl();
+  CPDF_FormField* pField = pControl->GetField();
+  CFX_FloatRect rcClient = GetClientRect();
+  CFX_ByteTextBuf sBody, sLines;
+
+  std::unique_ptr<CFX_Edit> pEdit(new CFX_Edit);
+  pEdit->EnableRefresh(false);
+
+  CBA_FontMap font_map(this, m_pInterForm->GetFormFillEnv()->GetSysHandler());
+  pEdit->SetFontMap(&font_map);
+
+  pEdit->SetPlateRect(CFX_FloatRect(rcClient.left, 0.0f, rcClient.right, 0.0f));
+
+  FX_FLOAT fFontSize = GetFontSize();
+
+  pEdit->SetFontSize(IsFloatZero(fFontSize) ? 12.0f : fFontSize);
+
+  pEdit->Initialize();
+
+  CFX_ByteTextBuf sList;
+  FX_FLOAT fy = rcClient.top;
+
+  int32_t nTop = pField->GetTopVisibleIndex();
+  int32_t nCount = pField->CountOptions();
+  int32_t nSelCount = pField->CountSelectedItems();
+
+  for (int32_t i = nTop; i < nCount; ++i) {
+    bool bSelected = false;
+    for (int32_t j = 0; j < nSelCount; ++j) {
+      if (pField->GetSelectedIndex(j) == i) {
+        bSelected = true;
+        break;
+      }
+    }
+
+    pEdit->SetText(pField->GetOptionLabel(i));
+
+    CFX_FloatRect rcContent = pEdit->GetContentRect();
+    FX_FLOAT fItemHeight = rcContent.Height();
+
+    if (bSelected) {
+      CFX_FloatRect rcItem =
+          CFX_FloatRect(rcClient.left, fy - fItemHeight, rcClient.right, fy);
+      sList << "q\n"
+            << CPWL_Utils::GetColorAppStream(
+                   CPWL_Color(COLORTYPE_RGB, 0, 51.0f / 255.0f,
+                              113.0f / 255.0f),
+                   true)
+            << rcItem.left << " " << rcItem.bottom << " " << rcItem.Width()
+            << " " << rcItem.Height() << " re f\n"
+            << "Q\n";
+
+      sList << "BT\n"
+            << CPWL_Utils::GetColorAppStream(CPWL_Color(COLORTYPE_GRAY, 1),
+                                             true)
+            << CPWL_Utils::GetEditAppStream(pEdit.get(),
+                                            CFX_FloatPoint(0.0f, fy))
+            << "ET\n";
+    } else {
+      CPWL_Color crText = GetTextPWLColor();
+      sList << "BT\n"
+            << CPWL_Utils::GetColorAppStream(crText, true)
+            << CPWL_Utils::GetEditAppStream(pEdit.get(),
+                                            CFX_FloatPoint(0.0f, fy))
+            << "ET\n";
+    }
+
+    fy -= fItemHeight;
+  }
+
+  if (sList.GetSize() > 0) {
+    sBody << "/Tx BMC\n"
+          << "q\n"
+          << rcClient.left << " " << rcClient.bottom << " " << rcClient.Width()
+          << " " << rcClient.Height() << " re\nW\nn\n";
+    sBody << sList << "Q\nEMC\n";
+  }
+
+  CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() +
+                       sLines.AsStringC() + sBody.AsStringC();
+
+  WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
+}
+
+void CPDFSDK_Widget::ResetAppearance_TextField(const CFX_WideString* sValue) {
+  CPDF_FormControl* pControl = GetFormControl();
+  CPDF_FormField* pField = pControl->GetField();
+  CFX_ByteTextBuf sBody, sLines;
+
+  std::unique_ptr<CFX_Edit> pEdit(new CFX_Edit);
+  pEdit->EnableRefresh(false);
+
+  CBA_FontMap font_map(this, m_pInterForm->GetFormFillEnv()->GetSysHandler());
+  pEdit->SetFontMap(&font_map);
+
+  CFX_FloatRect rcClient = GetClientRect();
+  pEdit->SetPlateRect(rcClient);
+  pEdit->SetAlignmentH(pControl->GetControlAlignment(), true);
+
+  uint32_t dwFieldFlags = pField->GetFieldFlags();
+  bool bMultiLine = (dwFieldFlags >> 12) & 1;
+
+  if (bMultiLine) {
+    pEdit->SetMultiLine(true, true);
+    pEdit->SetAutoReturn(true, true);
+  } else {
+    pEdit->SetAlignmentV(1, true);
+  }
+
+  uint16_t subWord = 0;
+  if ((dwFieldFlags >> 13) & 1) {
+    subWord = '*';
+    pEdit->SetPasswordChar(subWord, true);
+  }
+
+  int nMaxLen = pField->GetMaxLen();
+  bool bCharArray = (dwFieldFlags >> 24) & 1;
+  FX_FLOAT fFontSize = GetFontSize();
+
+#ifdef PDF_ENABLE_XFA
+  CFX_WideString sValueTmp;
+  if (!sValue && GetMixXFAWidget()) {
+    sValueTmp = GetValue(true);
+    sValue = &sValueTmp;
+  }
+#endif  // PDF_ENABLE_XFA
+
+  if (nMaxLen > 0) {
+    if (bCharArray) {
+      pEdit->SetCharArray(nMaxLen);
+
+      if (IsFloatZero(fFontSize)) {
+        fFontSize = CPWL_Edit::GetCharArrayAutoFontSize(font_map.GetPDFFont(0),
+                                                        rcClient, nMaxLen);
+      }
+    } else {
+      if (sValue)
+        nMaxLen = sValue->GetLength();
+      pEdit->SetLimitChar(nMaxLen);
+    }
+  }
+
+  if (IsFloatZero(fFontSize))
+    pEdit->SetAutoFontSize(true, true);
+  else
+    pEdit->SetFontSize(fFontSize);
+
+  pEdit->Initialize();
+  pEdit->SetText(sValue ? *sValue : pField->GetValue());
+
+  CFX_FloatRect rcContent = pEdit->GetContentRect();
+  CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream(
+      pEdit.get(), CFX_FloatPoint(), nullptr, !bCharArray, subWord);
+
+  if (sEdit.GetLength() > 0) {
+    sBody << "/Tx BMC\n"
+          << "q\n";
+    if (rcContent.Width() > rcClient.Width() ||
+        rcContent.Height() > rcClient.Height()) {
+      sBody << rcClient.left << " " << rcClient.bottom << " "
+            << rcClient.Width() << " " << rcClient.Height() << " re\nW\nn\n";
+    }
+    CPWL_Color crText = GetTextPWLColor();
+    sBody << "BT\n"
+          << CPWL_Utils::GetColorAppStream(crText) << sEdit << "ET\n"
+          << "Q\nEMC\n";
+  }
+
+  if (bCharArray) {
+    switch (GetBorderStyle()) {
+      case BorderStyle::SOLID: {
+        CFX_ByteString sColor =
+            CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), false);
+        if (sColor.GetLength() > 0) {
+          sLines << "q\n"
+                 << GetBorderWidth() << " w\n"
+                 << CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), false)
+                 << " 2 J 0 j\n";
+
+          for (int32_t i = 1; i < nMaxLen; ++i) {
+            sLines << rcClient.left +
+                          ((rcClient.right - rcClient.left) / nMaxLen) * i
+                   << " " << rcClient.bottom << " m\n"
+                   << rcClient.left +
+                          ((rcClient.right - rcClient.left) / nMaxLen) * i
+                   << " " << rcClient.top << " l S\n";
+          }
+
+          sLines << "Q\n";
+        }
+        break;
+      }
+      case BorderStyle::DASH: {
+        CFX_ByteString sColor =
+            CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), false);
+        if (sColor.GetLength() > 0) {
+          CPWL_Dash dsBorder = CPWL_Dash(3, 3, 0);
+
+          sLines << "q\n"
+                 << GetBorderWidth() << " w\n"
+                 << CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), false)
+                 << "[" << dsBorder.nDash << " " << dsBorder.nGap << "] "
+                 << dsBorder.nPhase << " d\n";
+
+          for (int32_t i = 1; i < nMaxLen; ++i) {
+            sLines << rcClient.left +
+                          ((rcClient.right - rcClient.left) / nMaxLen) * i
+                   << " " << rcClient.bottom << " m\n"
+                   << rcClient.left +
+                          ((rcClient.right - rcClient.left) / nMaxLen) * i
+                   << " " << rcClient.top << " l S\n";
+          }
+
+          sLines << "Q\n";
+        }
+        break;
+      }
+      default:
+        break;
+    }
+  }
+
+  CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() +
+                       sLines.AsStringC() + sBody.AsStringC();
+  WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
+}
+
+CFX_FloatRect CPDFSDK_Widget::GetClientRect() const {
+  CFX_FloatRect rcWindow = GetRotatedRect();
+  FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
+  switch (GetBorderStyle()) {
+    case BorderStyle::BEVELED:
+    case BorderStyle::INSET:
+      fBorderWidth *= 2.0f;
+      break;
+    default:
+      break;
+  }
+
+  return CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);
+}
+
+CFX_FloatRect CPDFSDK_Widget::GetRotatedRect() const {
+  CFX_FloatRect rectAnnot = GetRect();
+  FX_FLOAT fWidth = rectAnnot.right - rectAnnot.left;
+  FX_FLOAT fHeight = rectAnnot.top - rectAnnot.bottom;
+
+  CPDF_FormControl* pControl = GetFormControl();
+  CFX_FloatRect rcPDFWindow;
+  switch (abs(pControl->GetRotation() % 360)) {
+    case 0:
+    case 180:
+    default:
+      rcPDFWindow = CFX_FloatRect(0, 0, fWidth, fHeight);
+      break;
+    case 90:
+    case 270:
+      rcPDFWindow = CFX_FloatRect(0, 0, fHeight, fWidth);
+      break;
+  }
+
+  return rcPDFWindow;
+}
+
+CFX_ByteString CPDFSDK_Widget::GetBackgroundAppStream() const {
+  CPWL_Color crBackground = GetFillPWLColor();
+  if (crBackground.nColorType != COLORTYPE_TRANSPARENT)
+    return CPWL_Utils::GetRectFillAppStream(GetRotatedRect(), crBackground);
+
+  return "";
+}
+
+CFX_ByteString CPDFSDK_Widget::GetBorderAppStream() const {
+  CFX_FloatRect rcWindow = GetRotatedRect();
+  CPWL_Color crBorder = GetBorderPWLColor();
+  CPWL_Color crBackground = GetFillPWLColor();
+  CPWL_Color crLeftTop, crRightBottom;
+
+  FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
+  CPWL_Dash dsBorder(3, 0, 0);
+
+  BorderStyle nBorderStyle = GetBorderStyle();
+  switch (nBorderStyle) {
+    case BorderStyle::DASH:
+      dsBorder = CPWL_Dash(3, 3, 0);
+      break;
+    case BorderStyle::BEVELED:
+      fBorderWidth *= 2;
+      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
+      crRightBottom = CPWL_Utils::DevideColor(crBackground, 2);
+      break;
+    case BorderStyle::INSET:
+      fBorderWidth *= 2;
+      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5);
+      crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75);
+      break;
+    default:
+      break;
+  }
+
+  return CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
+                                        crLeftTop, crRightBottom, nBorderStyle,
+                                        dsBorder);
+}
+
+CFX_Matrix CPDFSDK_Widget::GetMatrix() const {
+  CFX_Matrix mt;
+  CPDF_FormControl* pControl = GetFormControl();
+  CFX_FloatRect rcAnnot = GetRect();
+  FX_FLOAT fWidth = rcAnnot.right - rcAnnot.left;
+  FX_FLOAT fHeight = rcAnnot.top - rcAnnot.bottom;
+
+  switch (abs(pControl->GetRotation() % 360)) {
+    case 0:
+    default:
+      mt = CFX_Matrix(1, 0, 0, 1, 0, 0);
+      break;
+    case 90:
+      mt = CFX_Matrix(0, 1, -1, 0, fWidth, 0);
+      break;
+    case 180:
+      mt = CFX_Matrix(-1, 0, 0, -1, fWidth, fHeight);
+      break;
+    case 270:
+      mt = CFX_Matrix(0, -1, 1, 0, 0, fHeight);
+      break;
+  }
+
+  return mt;
+}
+
+CPWL_Color CPDFSDK_Widget::GetTextPWLColor() const {
+  CPWL_Color crText = CPWL_Color(COLORTYPE_GRAY, 0);
+
+  CPDF_FormControl* pFormCtrl = GetFormControl();
+  CPDF_DefaultAppearance da = pFormCtrl->GetDefaultAppearance();
+  if (da.HasColor()) {
+    int32_t iColorType;
+    FX_FLOAT fc[4];
+    da.GetColor(iColorType, fc);
+    crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
+  }
+
+  return crText;
+}
+
+CPWL_Color CPDFSDK_Widget::GetBorderPWLColor() const {
+  CPWL_Color crBorder;
+
+  CPDF_FormControl* pFormCtrl = GetFormControl();
+  int32_t iColorType;
+  FX_FLOAT fc[4];
+  pFormCtrl->GetOriginalBorderColor(iColorType, fc);
+  if (iColorType > 0)
+    crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
+
+  return crBorder;
+}
+
+CPWL_Color CPDFSDK_Widget::GetFillPWLColor() const {
+  CPWL_Color crFill;
+
+  CPDF_FormControl* pFormCtrl = GetFormControl();
+  int32_t iColorType;
+  FX_FLOAT fc[4];
+  pFormCtrl->GetOriginalBackgroundColor(iColorType, fc);
+  if (iColorType > 0)
+    crFill = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
+
+  return crFill;
+}
+
+void CPDFSDK_Widget::AddImageToAppearance(const CFX_ByteString& sAPType,
+                                          CPDF_Stream* pImage) {
+  CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDictFor("AP");
+  CPDF_Stream* pStream = pAPDict->GetStreamFor(sAPType);
+  CPDF_Dictionary* pStreamDict = pStream->GetDict();
+  CFX_ByteString sImageAlias = "IMG";
+
+  if (CPDF_Dictionary* pImageDict = pImage->GetDict()) {
+    sImageAlias = pImageDict->GetStringFor("Name");
+    if (sImageAlias.IsEmpty())
+      sImageAlias = "IMG";
+  }
+
+  CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
+  CPDF_Dictionary* pStreamResList = pStreamDict->GetDictFor("Resources");
+  if (!pStreamResList)
+    pStreamResList = pStreamDict->SetNewFor<CPDF_Dictionary>("Resources");
+
+  CPDF_Dictionary* pXObject =
+      pStreamResList->SetNewFor<CPDF_Dictionary>("XObject");
+  pXObject->SetNewFor<CPDF_Reference>(sImageAlias, pDoc, pImage->GetObjNum());
+}
+
+void CPDFSDK_Widget::RemoveAppearance(const CFX_ByteString& sAPType) {
+  if (CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDictFor("AP"))
+    pAPDict->RemoveFor(sAPType);
+}
+
+bool CPDFSDK_Widget::OnAAction(CPDF_AAction::AActionType type,
+                               PDFSDK_FieldAction& data,
+                               CPDFSDK_PageView* pPageView) {
+  CPDFSDK_FormFillEnvironment* pFormFillEnv = pPageView->GetFormFillEnv();
+
+#ifdef PDF_ENABLE_XFA
+  CPDFXFA_Context* pContext = pFormFillEnv->GetXFAContext();
+  if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
+    XFA_EVENTTYPE eEventType = GetXFAEventType(type, data.bWillCommit);
+
+    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 = data.sChange.GetLength() - 1; i >= 0; i--)
+          param.m_wsNewText.Insert(data.nSelStart, data.sChange[i]);
+        param.m_wsPrevText = data.sValue;
+
+        CXFA_WidgetAcc* pAcc = hWidget->GetDataAcc();
+        param.m_pTarget = pAcc;
+        int32_t nRet = pXFAWidgetHandler->ProcessEvent(pAcc, &param);
+
+        if (CXFA_FFDocView* pDocView = pContext->GetXFADocView())
+          pDocView->UpdateDocView();
+
+        if (nRet == XFA_EVENTERROR_Success)
+          return true;
+      }
+    }
+  }
+#endif  // PDF_ENABLE_XFA
+
+  CPDF_Action action = GetAAction(type);
+  if (action.GetDict() && action.GetType() != CPDF_Action::Unknown) {
+    CPDFSDK_ActionHandler* pActionHandler = pFormFillEnv->GetActionHander();
+    return pActionHandler->DoAction_Field(action, type, pFormFillEnv,
+                                          GetFormField(), data);
+  }
+  return false;
+}
+
+CPDF_Action CPDFSDK_Widget::GetAAction(CPDF_AAction::AActionType eAAT) {
+  switch (eAAT) {
+    case CPDF_AAction::CursorEnter:
+    case CPDF_AAction::CursorExit:
+    case CPDF_AAction::ButtonDown:
+    case CPDF_AAction::ButtonUp:
+    case CPDF_AAction::GetFocus:
+    case CPDF_AAction::LoseFocus:
+    case CPDF_AAction::PageOpen:
+    case CPDF_AAction::PageClose:
+    case CPDF_AAction::PageVisible:
+    case CPDF_AAction::PageInvisible:
+      return CPDFSDK_BAAnnot::GetAAction(eAAT);
+
+    case CPDF_AAction::KeyStroke:
+    case CPDF_AAction::Format:
+    case CPDF_AAction::Validate:
+    case CPDF_AAction::Calculate: {
+      CPDF_FormField* pField = GetFormField();
+      if (pField->GetAdditionalAction().GetDict())
+        return pField->GetAdditionalAction().GetAction(eAAT);
+      return CPDFSDK_BAAnnot::GetAAction(eAAT);
+    }
+    default:
+      break;
+  }
+
+  return CPDF_Action();
+}
+
+CFX_WideString CPDFSDK_Widget::GetAlternateName() const {
+  CPDF_FormField* pFormField = GetFormField();
+  return pFormField->GetAlternateName();
+}
+
+int32_t CPDFSDK_Widget::GetAppearanceAge() const {
+  return m_nAppAge;
+}
+
+int32_t CPDFSDK_Widget::GetValueAge() const {
+  return m_nValueAge;
+}
+
+bool CPDFSDK_Widget::HitTest(FX_FLOAT pageX, FX_FLOAT pageY) {
+  CPDF_Annot* pAnnot = GetPDFAnnot();
+  CFX_FloatRect annotRect = pAnnot->GetRect();
+  if (!annotRect.Contains(pageX, pageY))
+    return false;
+
+  if (!IsVisible())
+    return false;
+
+  if ((GetFieldFlags() & FIELDFLAG_READONLY) == FIELDFLAG_READONLY)
+    return false;
+
+  return true;
+}
diff --git a/fpdfsdk/cpdfsdk_widget.h b/fpdfsdk/cpdfsdk_widget.h
new file mode 100644
index 0000000..69114d1
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_widget.h
@@ -0,0 +1,176 @@
+// 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_CPDFSDK_WIDGET_H_
+#define FPDFSDK_CPDFSDK_WIDGET_H_
+
+#include <set>
+
+#include "core/fpdfdoc/cpdf_aaction.h"
+#include "core/fpdfdoc/cpdf_action.h"
+#include "core/fpdfdoc/cpdf_annot.h"
+#include "core/fxcrt/fx_coordinates.h"
+#include "core/fxcrt/fx_string.h"
+#include "fpdfsdk/cpdfsdk_baannot.h"
+#include "fpdfsdk/pdfsdk_fieldaction.h"
+#include "fpdfsdk/pdfwindow/cpwl_color.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:
+#ifdef PDF_ENABLE_XFA
+  CXFA_FFWidget* GetMixXFAWidget() const;
+  CXFA_FFWidget* GetGroupMixXFAWidget();
+  CXFA_FFWidgetHandler* GetXFAWidgetHandler() const;
+
+  bool HasXFAAAction(PDFSDK_XFAAActionType eXFAAAT);
+  bool OnXFAAAction(PDFSDK_XFAAActionType eXFAAAT,
+                    PDFSDK_FieldAction& data,
+                    CPDFSDK_PageView* pPageView);
+
+  void Synchronize(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;
+
+  bool IsSignatureWidget() const override;
+  CPDF_Action GetAAction(CPDF_AAction::AActionType eAAT) override;
+  bool IsAppearanceValid() override;
+
+  int GetLayoutOrder() const override;
+
+  int GetFieldType() const;
+  int GetFieldFlags() const;
+  int GetRotate() const;
+
+  bool GetFillColor(FX_COLORREF& color) const;
+  bool GetBorderColor(FX_COLORREF& color) const;
+  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(bool bDisplay = true) const;
+#endif  // PDF_ENABLE_XFA
+  CFX_WideString GetDefaultValue() const;
+  CFX_WideString GetOptionLabel(int nIndex) const;
+  int CountOptions() const;
+  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, bool bNotify);
+  void SetDefaultValue(const CFX_WideString& sValue);
+  void SetOptionSelection(int index, bool bSelected, bool bNotify);
+  void ClearSelection(bool bNotify);
+  void SetTopVisibleIndex(int index);
+
+#ifdef PDF_ENABLE_XFA
+  void ResetAppearance(bool bValueChanged);
+#endif  // PDF_ENABLE_XFA
+  void ResetAppearance(const CFX_WideString* sValue, bool bValueChanged);
+  void ResetFieldAppearance(bool bValueChanged);
+  void UpdateField();
+  CFX_WideString OnFormat(bool& bFormatted);
+
+  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();
+  bool IsAppModified() const;
+
+  int32_t GetAppearanceAge() const;
+  int32_t GetValueAge() const;
+
+  bool IsWidgetAppearanceValid(CPDF_Annot::AppearanceMode mode);
+  void DrawAppearance(CFX_RenderDevice* pDevice,
+                      const CFX_Matrix* pUser2Device,
+                      CPDF_Annot::AppearanceMode mode,
+                      const CPDF_RenderOptions* pOptions) override;
+
+  bool HitTest(FX_FLOAT pageX, FX_FLOAT pageY);
+
+ private:
+  void ResetAppearance_PushButton();
+  void ResetAppearance_CheckBox();
+  void ResetAppearance_RadioButton();
+  void ResetAppearance_ComboBox(const CFX_WideString* sValue);
+  void ResetAppearance_ListBox();
+  void ResetAppearance_TextField(const CFX_WideString* 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;
+  bool m_bAppModified;
+  int32_t m_nAppAge;
+  int32_t m_nValueAge;
+
+#ifdef PDF_ENABLE_XFA
+  mutable CXFA_FFWidget* m_hMixXFAWidget;
+  mutable CXFA_FFWidgetHandler* m_pWidgetHandler;
+#endif  // PDF_ENABLE_XFA
+};
+
+#endif  // FPDFSDK_CPDFSDK_WIDGET_H_
diff --git a/fpdfsdk/cpdfsdk_widgethandler.cpp b/fpdfsdk/cpdfsdk_widgethandler.cpp
new file mode 100644
index 0000000..4105ae4
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_widgethandler.cpp
@@ -0,0 +1,288 @@
+// 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/cpdfsdk_widgethandler.h"
+
+#include <memory>
+#include <vector>
+
+#include "core/fpdfapi/page/cpdf_page.h"
+#include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfdoc/cpdf_interform.h"
+#include "fpdfsdk/cpdfsdk_annot.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/cpdfsdk_interform.h"
+#include "fpdfsdk/cpdfsdk_pageview.h"
+#include "fpdfsdk/cpdfsdk_widget.h"
+#include "fpdfsdk/formfiller/cffl_formfiller.h"
+
+#ifdef PDF_ENABLE_XFA
+#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
+#endif  // PDF_ENABLE_XFA
+
+CPDFSDK_WidgetHandler::CPDFSDK_WidgetHandler(
+    CPDFSDK_FormFillEnvironment* pFormFillEnv)
+    : m_pFormFillEnv(pFormFillEnv), m_pFormFiller(nullptr) {}
+
+CPDFSDK_WidgetHandler::~CPDFSDK_WidgetHandler() {}
+
+bool CPDFSDK_WidgetHandler::CanAnswer(CPDFSDK_Annot* pAnnot) {
+  ASSERT(pAnnot->GetAnnotSubtype() == CPDF_Annot::Subtype::WIDGET);
+  if (pAnnot->IsSignatureWidget())
+    return false;
+
+  CPDFSDK_Widget* pWidget = static_cast<CPDFSDK_Widget*>(pAnnot);
+  if (!pWidget->IsVisible())
+    return false;
+
+  int nFieldFlags = pWidget->GetFieldFlags();
+  if ((nFieldFlags & FIELDFLAG_READONLY) == FIELDFLAG_READONLY)
+    return false;
+
+  if (pWidget->GetFieldType() == FIELDTYPE_PUSHBUTTON)
+    return true;
+
+  CPDF_Page* pPage = pWidget->GetPDFPage();
+  CPDF_Document* pDocument = pPage->m_pDocument;
+  uint32_t dwPermissions = pDocument->GetUserPermissions();
+  return (dwPermissions & FPDFPERM_FILL_FORM) ||
+         (dwPermissions & FPDFPERM_ANNOT_FORM);
+}
+
+CPDFSDK_Annot* CPDFSDK_WidgetHandler::NewAnnot(CPDF_Annot* pAnnot,
+                                               CPDFSDK_PageView* pPage) {
+  CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm();
+  CPDF_FormControl* pCtrl = CPDFSDK_Widget::GetFormControl(
+      pInterForm->GetInterForm(), pAnnot->GetAnnotDict());
+  if (!pCtrl)
+    return nullptr;
+
+  CPDFSDK_Widget* pWidget = new CPDFSDK_Widget(pAnnot, pPage, pInterForm);
+  pInterForm->AddMap(pCtrl, pWidget);
+  CPDF_InterForm* pPDFInterForm = pInterForm->GetInterForm();
+  if (pPDFInterForm && pPDFInterForm->NeedConstructAP())
+    pWidget->ResetAppearance(nullptr, false);
+
+  return pWidget;
+}
+
+#ifdef PDF_ENABLE_XFA
+CPDFSDK_Annot* CPDFSDK_WidgetHandler::NewAnnot(CXFA_FFWidget* hWidget,
+                                               CPDFSDK_PageView* pPage) {
+  return nullptr;
+}
+#endif  // PDF_ENABLE_XFA
+
+void CPDFSDK_WidgetHandler::ReleaseAnnot(CPDFSDK_Annot* pAnnot) {
+  ASSERT(pAnnot);
+
+  if (m_pFormFiller)
+    m_pFormFiller->OnDelete(pAnnot);
+
+  std::unique_ptr<CPDFSDK_Widget> pWidget(static_cast<CPDFSDK_Widget*>(pAnnot));
+  CPDFSDK_InterForm* pInterForm = pWidget->GetInterForm();
+  CPDF_FormControl* pControl = pWidget->GetFormControl();
+  pInterForm->RemoveMap(pControl);
+}
+
+void CPDFSDK_WidgetHandler::OnDraw(CPDFSDK_PageView* pPageView,
+                                   CPDFSDK_Annot* pAnnot,
+                                   CFX_RenderDevice* pDevice,
+                                   CFX_Matrix* pUser2Device,
+                                   bool bDrawAnnots) {
+  if (pAnnot->IsSignatureWidget()) {
+    static_cast<CPDFSDK_BAAnnot*>(pAnnot)->DrawAppearance(
+        pDevice, pUser2Device, CPDF_Annot::Normal, nullptr);
+  } else {
+    if (m_pFormFiller)
+      m_pFormFiller->OnDraw(pPageView, pAnnot, pDevice, pUser2Device);
+  }
+}
+
+void CPDFSDK_WidgetHandler::OnMouseEnter(CPDFSDK_PageView* pPageView,
+                                         CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                         uint32_t nFlag) {
+  if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
+    m_pFormFiller->OnMouseEnter(pPageView, pAnnot, nFlag);
+}
+
+void CPDFSDK_WidgetHandler::OnMouseExit(CPDFSDK_PageView* pPageView,
+                                        CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                        uint32_t nFlag) {
+  if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
+    m_pFormFiller->OnMouseExit(pPageView, pAnnot, nFlag);
+}
+
+bool CPDFSDK_WidgetHandler::OnLButtonDown(CPDFSDK_PageView* pPageView,
+                                          CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                          uint32_t nFlags,
+                                          const CFX_FloatPoint& point) {
+  if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
+    return m_pFormFiller->OnLButtonDown(pPageView, pAnnot, nFlags, point);
+
+  return false;
+}
+
+bool CPDFSDK_WidgetHandler::OnLButtonUp(CPDFSDK_PageView* pPageView,
+                                        CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                        uint32_t nFlags,
+                                        const CFX_FloatPoint& point) {
+  if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
+    return m_pFormFiller->OnLButtonUp(pPageView, pAnnot, nFlags, point);
+
+  return false;
+}
+
+bool CPDFSDK_WidgetHandler::OnLButtonDblClk(CPDFSDK_PageView* pPageView,
+                                            CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                            uint32_t nFlags,
+                                            const CFX_FloatPoint& point) {
+  if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
+    return m_pFormFiller->OnLButtonDblClk(pPageView, pAnnot, nFlags, point);
+
+  return false;
+}
+
+bool CPDFSDK_WidgetHandler::OnMouseMove(CPDFSDK_PageView* pPageView,
+                                        CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                        uint32_t nFlags,
+                                        const CFX_FloatPoint& point) {
+  if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
+    return m_pFormFiller->OnMouseMove(pPageView, pAnnot, nFlags, point);
+
+  return false;
+}
+
+bool CPDFSDK_WidgetHandler::OnMouseWheel(CPDFSDK_PageView* pPageView,
+                                         CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                         uint32_t nFlags,
+                                         short zDelta,
+                                         const CFX_FloatPoint& point) {
+  if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
+    return m_pFormFiller->OnMouseWheel(pPageView, pAnnot, nFlags, zDelta,
+                                       point);
+
+  return false;
+}
+
+bool CPDFSDK_WidgetHandler::OnRButtonDown(CPDFSDK_PageView* pPageView,
+                                          CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                          uint32_t nFlags,
+                                          const CFX_FloatPoint& point) {
+  if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
+    return m_pFormFiller->OnRButtonDown(pPageView, pAnnot, nFlags, point);
+
+  return false;
+}
+
+bool CPDFSDK_WidgetHandler::OnRButtonUp(CPDFSDK_PageView* pPageView,
+                                        CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                        uint32_t nFlags,
+                                        const CFX_FloatPoint& point) {
+  if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
+    return m_pFormFiller->OnRButtonUp(pPageView, pAnnot, nFlags, point);
+
+  return false;
+}
+
+bool CPDFSDK_WidgetHandler::OnRButtonDblClk(CPDFSDK_PageView* pPageView,
+                                            CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                            uint32_t nFlags,
+                                            const CFX_FloatPoint& point) {
+  return false;
+}
+
+bool CPDFSDK_WidgetHandler::OnChar(CPDFSDK_Annot* pAnnot,
+                                   uint32_t nChar,
+                                   uint32_t nFlags) {
+  if (!pAnnot->IsSignatureWidget() && m_pFormFiller)
+    return m_pFormFiller->OnChar(pAnnot, nChar, nFlags);
+
+  return false;
+}
+
+bool CPDFSDK_WidgetHandler::OnKeyDown(CPDFSDK_Annot* pAnnot,
+                                      int nKeyCode,
+                                      int nFlag) {
+  if (!pAnnot->IsSignatureWidget() && m_pFormFiller)
+    return m_pFormFiller->OnKeyDown(pAnnot, nKeyCode, nFlag);
+
+  return false;
+}
+
+bool CPDFSDK_WidgetHandler::OnKeyUp(CPDFSDK_Annot* pAnnot,
+                                    int nKeyCode,
+                                    int nFlag) {
+  return false;
+}
+
+void CPDFSDK_WidgetHandler::OnLoad(CPDFSDK_Annot* pAnnot) {
+  if (pAnnot->IsSignatureWidget())
+    return;
+
+  CPDFSDK_Widget* pWidget = static_cast<CPDFSDK_Widget*>(pAnnot);
+  if (!pWidget->IsAppearanceValid())
+    pWidget->ResetAppearance(nullptr, false);
+
+  int nFieldType = pWidget->GetFieldType();
+  if (nFieldType == FIELDTYPE_TEXTFIELD || nFieldType == FIELDTYPE_COMBOBOX) {
+    bool bFormatted = false;
+    CFX_WideString sValue = pWidget->OnFormat(bFormatted);
+    if (bFormatted && nFieldType == FIELDTYPE_COMBOBOX)
+      pWidget->ResetAppearance(&sValue, false);
+  }
+
+#ifdef PDF_ENABLE_XFA
+  CPDFSDK_PageView* pPageView = pAnnot->GetPageView();
+  CPDFXFA_Context* pContext = pPageView->GetFormFillEnv()->GetXFAContext();
+  if (pContext->GetDocType() == DOCTYPE_STATIC_XFA) {
+    if (!pWidget->IsAppearanceValid() && !pWidget->GetValue().IsEmpty())
+      pWidget->ResetAppearance(false);
+  }
+#endif  // PDF_ENABLE_XFA
+}
+
+bool CPDFSDK_WidgetHandler::OnSetFocus(CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                       uint32_t nFlag) {
+  if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
+    return m_pFormFiller->OnSetFocus(pAnnot, nFlag);
+
+  return true;
+}
+
+bool CPDFSDK_WidgetHandler::OnKillFocus(CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                        uint32_t nFlag) {
+  if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller)
+    return m_pFormFiller->OnKillFocus(pAnnot, nFlag);
+
+  return true;
+}
+
+#ifdef PDF_ENABLE_XFA
+bool CPDFSDK_WidgetHandler::OnXFAChangedFocus(
+    CPDFSDK_Annot::ObservedPtr* pOldAnnot,
+    CPDFSDK_Annot::ObservedPtr* pNewAnnot) {
+  return true;
+}
+#endif  // PDF_ENABLE_XFA
+
+CFX_FloatRect CPDFSDK_WidgetHandler::GetViewBBox(CPDFSDK_PageView* pPageView,
+                                                 CPDFSDK_Annot* pAnnot) {
+  if (!pAnnot->IsSignatureWidget() && m_pFormFiller)
+    return CFX_FloatRect(m_pFormFiller->GetViewBBox(pPageView, pAnnot));
+
+  return CFX_FloatRect(0, 0, 0, 0);
+}
+
+bool CPDFSDK_WidgetHandler::HitTest(CPDFSDK_PageView* pPageView,
+                                    CPDFSDK_Annot* pAnnot,
+                                    const CFX_FloatPoint& point) {
+  ASSERT(pPageView);
+  ASSERT(pAnnot);
+
+  CFX_FloatRect rect = GetViewBBox(pPageView, pAnnot);
+  return rect.Contains(point.x, point.y);
+}
diff --git a/fpdfsdk/cpdfsdk_widgethandler.h b/fpdfsdk/cpdfsdk_widgethandler.h
new file mode 100644
index 0000000..7154bda
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_widgethandler.h
@@ -0,0 +1,109 @@
+// 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_CPDFSDK_WIDGETHANDLER_H_
+#define FPDFSDK_CPDFSDK_WIDGETHANDLER_H_
+
+#include "core/fxcrt/fx_basic.h"
+#include "core/fxcrt/fx_coordinates.h"
+#include "fpdfsdk/ipdfsdk_annothandler.h"
+
+class CFFL_InteractiveFormFiller;
+class CFX_Matrix;
+class CFX_RenderDevice;
+class CPDF_Annot;
+class CPDFSDK_Annot;
+class CPDFSDK_FormFillEnvironment;
+class CPDFSDK_PageView;
+
+#ifdef PDF_ENABLE_XFA
+class CXFA_FFWidget;
+#endif  // PDF_ENABLE_XFA
+
+class CPDFSDK_WidgetHandler : public IPDFSDK_AnnotHandler {
+ public:
+  explicit CPDFSDK_WidgetHandler(CPDFSDK_FormFillEnvironment* pApp);
+  ~CPDFSDK_WidgetHandler() override;
+
+  bool CanAnswer(CPDFSDK_Annot* pAnnot) override;
+  CPDFSDK_Annot* NewAnnot(CPDF_Annot* pAnnot, CPDFSDK_PageView* pPage) override;
+#ifdef PDF_ENABLE_XFA
+  CPDFSDK_Annot* NewAnnot(CXFA_FFWidget* hWidget,
+                          CPDFSDK_PageView* pPage) override;
+#endif  // PDF_ENABLE_XFA
+  void ReleaseAnnot(CPDFSDK_Annot* pAnnot) override;
+  CFX_FloatRect GetViewBBox(CPDFSDK_PageView* pPageView,
+                            CPDFSDK_Annot* pAnnot) override;
+  bool HitTest(CPDFSDK_PageView* pPageView,
+               CPDFSDK_Annot* pAnnot,
+               const CFX_FloatPoint& point) override;
+  void OnDraw(CPDFSDK_PageView* pPageView,
+              CPDFSDK_Annot* pAnnot,
+              CFX_RenderDevice* pDevice,
+              CFX_Matrix* pUser2Device,
+              bool bDrawAnnots) override;
+  void OnLoad(CPDFSDK_Annot* pAnnot) override;
+
+  void OnMouseEnter(CPDFSDK_PageView* pPageView,
+                    CPDFSDK_Annot::ObservedPtr* pAnnot,
+                    uint32_t nFlag) override;
+  void OnMouseExit(CPDFSDK_PageView* pPageView,
+                   CPDFSDK_Annot::ObservedPtr* pAnnot,
+                   uint32_t nFlag) override;
+  bool OnLButtonDown(CPDFSDK_PageView* pPageView,
+                     CPDFSDK_Annot::ObservedPtr* pAnnot,
+                     uint32_t nFlags,
+                     const CFX_FloatPoint& point) override;
+  bool OnLButtonUp(CPDFSDK_PageView* pPageView,
+                   CPDFSDK_Annot::ObservedPtr* pAnnot,
+                   uint32_t nFlags,
+                   const CFX_FloatPoint& point) override;
+  bool OnLButtonDblClk(CPDFSDK_PageView* pPageView,
+                       CPDFSDK_Annot::ObservedPtr* pAnnot,
+                       uint32_t nFlags,
+                       const CFX_FloatPoint& point) override;
+  bool OnMouseMove(CPDFSDK_PageView* pPageView,
+                   CPDFSDK_Annot::ObservedPtr* pAnnot,
+                   uint32_t nFlags,
+                   const CFX_FloatPoint& point) override;
+  bool OnMouseWheel(CPDFSDK_PageView* pPageView,
+                    CPDFSDK_Annot::ObservedPtr* pAnnot,
+                    uint32_t nFlags,
+                    short zDelta,
+                    const CFX_FloatPoint& point) override;
+  bool OnRButtonDown(CPDFSDK_PageView* pPageView,
+                     CPDFSDK_Annot::ObservedPtr* pAnnot,
+                     uint32_t nFlags,
+                     const CFX_FloatPoint& point) override;
+  bool OnRButtonUp(CPDFSDK_PageView* pPageView,
+                   CPDFSDK_Annot::ObservedPtr* pAnnot,
+                   uint32_t nFlags,
+                   const CFX_FloatPoint& point) override;
+  bool OnRButtonDblClk(CPDFSDK_PageView* pPageView,
+                       CPDFSDK_Annot::ObservedPtr* pAnnot,
+                       uint32_t nFlags,
+                       const CFX_FloatPoint& point) override;
+  bool OnChar(CPDFSDK_Annot* pAnnot, uint32_t nChar, uint32_t nFlags) override;
+  bool OnKeyDown(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag) override;
+  bool OnKeyUp(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag) override;
+  bool OnSetFocus(CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlag) override;
+  bool OnKillFocus(CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlag) override;
+#ifdef PDF_ENABLE_XFA
+  bool OnXFAChangedFocus(CPDFSDK_Annot::ObservedPtr* pOldAnnot,
+                         CPDFSDK_Annot::ObservedPtr* pNewAnnot) override;
+#endif  // PDF_ENABLE_XFA
+
+  void SetFormFiller(CFFL_InteractiveFormFiller* pFiller) {
+    m_pFormFiller = pFiller;
+  }
+  CFFL_InteractiveFormFiller* GetFormFiller() { return m_pFormFiller; }
+
+ private:
+  CPDFSDK_FormFillEnvironment* m_pFormFillEnv;
+  CFFL_InteractiveFormFiller* m_pFormFiller;
+};
+
+#endif  // FPDFSDK_CPDFSDK_WIDGETHANDLER_H_
diff --git a/fpdfsdk/cpdfsdk_xfawidget.cpp b/fpdfsdk/cpdfsdk_xfawidget.cpp
new file mode 100644
index 0000000..67a8a17
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_xfawidget.cpp
@@ -0,0 +1,36 @@
+// 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/cpdfsdk_xfawidget.h"
+
+#include "fpdfsdk/ipdfsdk_annothandler.h"
+#include "xfa/fxfa/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) {}
+
+bool CPDFSDK_XFAWidget::IsXFAField() {
+  return true;
+}
+
+CXFA_FFWidget* CPDFSDK_XFAWidget::GetXFAWidget() const {
+  return m_hXFAWidget;
+}
+
+CPDF_Annot::Subtype CPDFSDK_XFAWidget::GetAnnotSubtype() const {
+  return CPDF_Annot::Subtype::XFAWIDGET;
+}
+
+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/cpdfsdk_xfawidget.h b/fpdfsdk/cpdfsdk_xfawidget.h
new file mode 100644
index 0000000..9d0be75
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_xfawidget.h
@@ -0,0 +1,37 @@
+// 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_CPDFSDK_XFAWIDGET_H_
+#define FPDFSDK_CPDFSDK_XFAWIDGET_H_
+
+#include "core/fxcrt/fx_coordinates.h"
+#include "core/fxcrt/fx_string.h"
+#include "fpdfsdk/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 {}
+
+  bool IsXFAField() override;
+  CXFA_FFWidget* GetXFAWidget() const override;
+  CPDF_Annot::Subtype GetAnnotSubtype() const override;
+  CFX_FloatRect GetRect() const override;
+
+  CPDFSDK_InterForm* GetInterForm() { return m_pInterForm; }
+
+ private:
+  CPDFSDK_InterForm* m_pInterForm;
+  CXFA_FFWidget* m_hXFAWidget;
+};
+
+#endif  // FPDFSDK_CPDFSDK_XFAWIDGET_H_
diff --git a/fpdfsdk/cpdfsdk_xfawidgethandler.cpp b/fpdfsdk/cpdfsdk_xfawidgethandler.cpp
new file mode 100644
index 0000000..eff351b
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_xfawidgethandler.cpp
@@ -0,0 +1,359 @@
+// 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/cpdfsdk_xfawidgethandler.h"
+
+#include "core/fpdfdoc/cpdf_interform.h"
+#include "fpdfsdk/cpdfsdk_annot.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/cpdfsdk_interform.h"
+#include "fpdfsdk/cpdfsdk_pageview.h"
+#include "fpdfsdk/cpdfsdk_xfawidget.h"
+#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
+#include "xfa/fwl/cfwl_app.h"
+#include "xfa/fwl/fwl_widgethit.h"
+#include "xfa/fxfa/fxfa_basic.h"
+#include "xfa/fxfa/xfa_ffdocview.h"
+#include "xfa/fxfa/xfa_ffpageview.h"
+#include "xfa/fxfa/xfa_ffwidget.h"
+#include "xfa/fxfa/xfa_ffwidgethandler.h"
+#include "xfa/fxgraphics/cfx_graphics.h"
+
+CPDFSDK_XFAWidgetHandler::CPDFSDK_XFAWidgetHandler(
+    CPDFSDK_FormFillEnvironment* pFormFillEnv)
+    : m_pFormFillEnv(pFormFillEnv) {}
+
+CPDFSDK_XFAWidgetHandler::~CPDFSDK_XFAWidgetHandler() {}
+
+bool CPDFSDK_XFAWidgetHandler::CanAnswer(CPDFSDK_Annot* pAnnot) {
+  return !!pAnnot->GetXFAWidget();
+}
+
+CPDFSDK_Annot* CPDFSDK_XFAWidgetHandler::NewAnnot(CPDF_Annot* pAnnot,
+                                                  CPDFSDK_PageView* pPage) {
+  return nullptr;
+}
+
+CPDFSDK_Annot* CPDFSDK_XFAWidgetHandler::NewAnnot(CXFA_FFWidget* pAnnot,
+                                                  CPDFSDK_PageView* pPage) {
+  CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm();
+  CPDFSDK_XFAWidget* pWidget = new CPDFSDK_XFAWidget(pAnnot, pPage, pInterForm);
+  pInterForm->AddXFAMap(pAnnot, pWidget);
+  return pWidget;
+}
+
+void CPDFSDK_XFAWidgetHandler::OnDraw(CPDFSDK_PageView* pPageView,
+                                      CPDFSDK_Annot* pAnnot,
+                                      CFX_RenderDevice* pDevice,
+                                      CFX_Matrix* pUser2Device,
+                                      bool bDrawAnnots) {
+  ASSERT(pPageView);
+  ASSERT(pAnnot);
+
+  CFX_Graphics gs;
+  gs.Create(pDevice);
+
+  CFX_Matrix mt;
+  mt = *pUser2Device;
+
+  bool bIsHighlight = false;
+  if (pPageView->GetFormFillEnv()->GetFocusAnnot() != pAnnot)
+    bIsHighlight = true;
+
+  GetXFAWidgetHandler(pAnnot)->RenderWidget(pAnnot->GetXFAWidget(), &gs, &mt,
+                                            bIsHighlight);
+
+  // to do highlight and shadow
+}
+
+void CPDFSDK_XFAWidgetHandler::OnLoad(CPDFSDK_Annot* pAnnot) {}
+
+void CPDFSDK_XFAWidgetHandler::ReleaseAnnot(CPDFSDK_Annot* pAnnot) {
+  CPDFSDK_XFAWidget* pWidget = reinterpret_cast<CPDFSDK_XFAWidget*>(pAnnot);
+  CPDFSDK_InterForm* pInterForm = pWidget->GetInterForm();
+  pInterForm->RemoveXFAMap(pWidget->GetXFAWidget());
+
+  delete pWidget;
+}
+
+CFX_FloatRect CPDFSDK_XFAWidgetHandler::GetViewBBox(CPDFSDK_PageView* pPageView,
+                                                    CPDFSDK_Annot* pAnnot) {
+  ASSERT(pAnnot);
+
+  CFX_RectF rcBBox;
+  XFA_Element eType = pAnnot->GetXFAWidget()->GetDataAcc()->GetUIType();
+  if (eType == XFA_Element::Signature)
+    pAnnot->GetXFAWidget()->GetBBox(rcBBox, XFA_WidgetStatus_Visible, true);
+  else
+    pAnnot->GetXFAWidget()->GetBBox(rcBBox, XFA_WidgetStatus_None);
+
+  CFX_FloatRect rcWidget(rcBBox.left, rcBBox.top, rcBBox.left + rcBBox.width,
+                         rcBBox.top + rcBBox.height);
+  rcWidget.left -= 1.0f;
+  rcWidget.right += 1.0f;
+  rcWidget.bottom -= 1.0f;
+  rcWidget.top += 1.0f;
+
+  return rcWidget;
+}
+
+bool CPDFSDK_XFAWidgetHandler::HitTest(CPDFSDK_PageView* pPageView,
+                                       CPDFSDK_Annot* pAnnot,
+                                       const CFX_FloatPoint& point) {
+  if (!pPageView || !pAnnot)
+    return false;
+
+  CPDFSDK_FormFillEnvironment* pFormFillEnv = pPageView->GetFormFillEnv();
+  if (!pFormFillEnv)
+    return false;
+
+  CPDFXFA_Context* pContext = pFormFillEnv->GetXFAContext();
+  if (!pContext)
+    return false;
+
+  CXFA_FFDocView* pDocView = pContext->GetXFADocView();
+  if (!pDocView)
+    return false;
+
+  CXFA_FFWidgetHandler* pWidgetHandler = pDocView->GetWidgetHandler();
+  if (!pWidgetHandler)
+    return false;
+
+  FWL_WidgetHit dwHitTest =
+      pWidgetHandler->OnHitTest(pAnnot->GetXFAWidget(), point.x, point.y);
+  return dwHitTest != FWL_WidgetHit::Unknown;
+}
+
+void CPDFSDK_XFAWidgetHandler::OnMouseEnter(CPDFSDK_PageView* pPageView,
+                                            CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                            uint32_t nFlag) {
+  if (!pPageView || !(*pAnnot))
+    return;
+  CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
+  pWidgetHandler->OnMouseEnter((*pAnnot)->GetXFAWidget());
+}
+
+void CPDFSDK_XFAWidgetHandler::OnMouseExit(CPDFSDK_PageView* pPageView,
+                                           CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                           uint32_t nFlag) {
+  if (!pPageView || !(*pAnnot))
+    return;
+
+  CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
+  pWidgetHandler->OnMouseExit((*pAnnot)->GetXFAWidget());
+}
+
+bool CPDFSDK_XFAWidgetHandler::OnLButtonDown(CPDFSDK_PageView* pPageView,
+                                             CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                             uint32_t nFlags,
+                                             const CFX_FloatPoint& point) {
+  if (!pPageView || !(*pAnnot))
+    return false;
+
+  CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
+  return pWidgetHandler->OnLButtonDown((*pAnnot)->GetXFAWidget(),
+                                       GetFWLFlags(nFlags), point.x, point.y);
+}
+
+bool CPDFSDK_XFAWidgetHandler::OnLButtonUp(CPDFSDK_PageView* pPageView,
+                                           CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                           uint32_t nFlags,
+                                           const CFX_FloatPoint& point) {
+  if (!pPageView || !(*pAnnot))
+    return false;
+
+  CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
+  return pWidgetHandler->OnLButtonUp((*pAnnot)->GetXFAWidget(),
+                                     GetFWLFlags(nFlags), point.x, point.y);
+}
+
+bool CPDFSDK_XFAWidgetHandler::OnLButtonDblClk(
+    CPDFSDK_PageView* pPageView,
+    CPDFSDK_Annot::ObservedPtr* pAnnot,
+    uint32_t nFlags,
+    const CFX_FloatPoint& point) {
+  if (!pPageView || !(*pAnnot))
+    return false;
+
+  CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
+  return pWidgetHandler->OnLButtonDblClk((*pAnnot)->GetXFAWidget(),
+                                         GetFWLFlags(nFlags), point.x, point.y);
+}
+
+bool CPDFSDK_XFAWidgetHandler::OnMouseMove(CPDFSDK_PageView* pPageView,
+                                           CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                           uint32_t nFlags,
+                                           const CFX_FloatPoint& point) {
+  if (!pPageView || !(*pAnnot))
+    return false;
+
+  CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
+  return pWidgetHandler->OnMouseMove((*pAnnot)->GetXFAWidget(),
+                                     GetFWLFlags(nFlags), point.x, point.y);
+}
+
+bool CPDFSDK_XFAWidgetHandler::OnMouseWheel(CPDFSDK_PageView* pPageView,
+                                            CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                            uint32_t nFlags,
+                                            short zDelta,
+                                            const CFX_FloatPoint& point) {
+  if (!pPageView || !(*pAnnot))
+    return false;
+
+  CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
+  return pWidgetHandler->OnMouseWheel(
+      (*pAnnot)->GetXFAWidget(), GetFWLFlags(nFlags), zDelta, point.x, point.y);
+}
+
+bool CPDFSDK_XFAWidgetHandler::OnRButtonDown(CPDFSDK_PageView* pPageView,
+                                             CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                             uint32_t nFlags,
+                                             const CFX_FloatPoint& point) {
+  if (!pPageView || !(*pAnnot))
+    return false;
+
+  CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
+  return pWidgetHandler->OnRButtonDown((*pAnnot)->GetXFAWidget(),
+                                       GetFWLFlags(nFlags), point.x, point.y);
+}
+
+bool CPDFSDK_XFAWidgetHandler::OnRButtonUp(CPDFSDK_PageView* pPageView,
+                                           CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                           uint32_t nFlags,
+                                           const CFX_FloatPoint& point) {
+  if (!pPageView || !(*pAnnot))
+    return false;
+
+  CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
+  return pWidgetHandler->OnRButtonUp((*pAnnot)->GetXFAWidget(),
+                                     GetFWLFlags(nFlags), point.x, point.y);
+}
+
+bool CPDFSDK_XFAWidgetHandler::OnRButtonDblClk(
+    CPDFSDK_PageView* pPageView,
+    CPDFSDK_Annot::ObservedPtr* pAnnot,
+    uint32_t nFlags,
+    const CFX_FloatPoint& point) {
+  if (!pPageView || !(*pAnnot))
+    return false;
+
+  CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get());
+  return pWidgetHandler->OnRButtonDblClk((*pAnnot)->GetXFAWidget(),
+                                         GetFWLFlags(nFlags), point.x, point.y);
+}
+
+bool CPDFSDK_XFAWidgetHandler::OnChar(CPDFSDK_Annot* pAnnot,
+                                      uint32_t nChar,
+                                      uint32_t nFlags) {
+  if (!pAnnot)
+    return false;
+
+  CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
+  return pWidgetHandler->OnChar(pAnnot->GetXFAWidget(), nChar,
+                                GetFWLFlags(nFlags));
+}
+
+bool CPDFSDK_XFAWidgetHandler::OnKeyDown(CPDFSDK_Annot* pAnnot,
+                                         int nKeyCode,
+                                         int nFlag) {
+  if (!pAnnot)
+    return false;
+
+  CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
+  return pWidgetHandler->OnKeyDown(pAnnot->GetXFAWidget(), nKeyCode,
+                                   GetFWLFlags(nFlag));
+}
+
+bool CPDFSDK_XFAWidgetHandler::OnKeyUp(CPDFSDK_Annot* pAnnot,
+                                       int nKeyCode,
+                                       int nFlag) {
+  if (!pAnnot)
+    return false;
+
+  CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
+  return pWidgetHandler->OnKeyUp(pAnnot->GetXFAWidget(), nKeyCode,
+                                 GetFWLFlags(nFlag));
+}
+
+bool CPDFSDK_XFAWidgetHandler::OnSetFocus(CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                          uint32_t nFlag) {
+  return true;
+}
+
+bool CPDFSDK_XFAWidgetHandler::OnKillFocus(CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                           uint32_t nFlag) {
+  return true;
+}
+
+bool CPDFSDK_XFAWidgetHandler::OnXFAChangedFocus(
+    CPDFSDK_Annot::ObservedPtr* pOldAnnot,
+    CPDFSDK_Annot::ObservedPtr* pNewAnnot) {
+  CXFA_FFWidgetHandler* pWidgetHandler = nullptr;
+  if (*pOldAnnot)
+    pWidgetHandler = GetXFAWidgetHandler(pOldAnnot->Get());
+  else if (*pNewAnnot)
+    pWidgetHandler = GetXFAWidgetHandler(pNewAnnot->Get());
+
+  if (!pWidgetHandler)
+    return true;
+
+  CXFA_FFWidget* hWidget = *pNewAnnot ? (*pNewAnnot)->GetXFAWidget() : nullptr;
+  if (!hWidget)
+    return true;
+
+  CXFA_FFPageView* pXFAPageView = hWidget->GetPageView();
+  if (!pXFAPageView)
+    return true;
+
+  bool bRet = pXFAPageView->GetDocView()->SetFocus(hWidget);
+  if (pXFAPageView->GetDocView()->GetFocusWidget() == hWidget)
+    bRet = true;
+
+  return bRet;
+}
+
+CXFA_FFWidgetHandler* CPDFSDK_XFAWidgetHandler::GetXFAWidgetHandler(
+    CPDFSDK_Annot* pAnnot) {
+  if (!pAnnot)
+    return nullptr;
+
+  CPDFSDK_PageView* pPageView = pAnnot->GetPageView();
+  if (!pPageView)
+    return nullptr;
+
+  CPDFSDK_FormFillEnvironment* pFormFillEnv = pPageView->GetFormFillEnv();
+  if (!pFormFillEnv)
+    return nullptr;
+
+  CPDFXFA_Context* pDoc = pFormFillEnv->GetXFAContext();
+  if (!pDoc)
+    return nullptr;
+
+  CXFA_FFDocView* pDocView = pDoc->GetXFADocView();
+  if (!pDocView)
+    return nullptr;
+
+  return pDocView->GetWidgetHandler();
+}
+
+uint32_t CPDFSDK_XFAWidgetHandler::GetFWLFlags(uint32_t dwFlag) {
+  uint32_t dwFWLFlag = 0;
+
+  if (dwFlag & FWL_EVENTFLAG_ControlKey)
+    dwFWLFlag |= FWL_KEYFLAG_Ctrl;
+  if (dwFlag & FWL_EVENTFLAG_LeftButtonDown)
+    dwFWLFlag |= FWL_KEYFLAG_LButton;
+  if (dwFlag & FWL_EVENTFLAG_MiddleButtonDown)
+    dwFWLFlag |= FWL_KEYFLAG_MButton;
+  if (dwFlag & FWL_EVENTFLAG_RightButtonDown)
+    dwFWLFlag |= FWL_KEYFLAG_RButton;
+  if (dwFlag & FWL_EVENTFLAG_ShiftKey)
+    dwFWLFlag |= FWL_KEYFLAG_Shift;
+  if (dwFlag & FWL_EVENTFLAG_AltKey)
+    dwFWLFlag |= FWL_KEYFLAG_Alt;
+
+  return dwFWLFlag;
+}
diff --git a/fpdfsdk/cpdfsdk_xfawidgethandler.h b/fpdfsdk/cpdfsdk_xfawidgethandler.h
new file mode 100644
index 0000000..1a1a480
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_xfawidgethandler.h
@@ -0,0 +1,98 @@
+// 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_CPDFSDK_XFAWIDGETHANDLER_H_
+#define FPDFSDK_CPDFSDK_XFAWIDGETHANDLER_H_
+
+#include "core/fxcrt/fx_basic.h"
+#include "core/fxcrt/fx_coordinates.h"
+#include "fpdfsdk/ipdfsdk_annothandler.h"
+
+class CFX_Matrix;
+class CFX_RenderDevice;
+class CPDF_Annot;
+class CPDFSDK_FormFillEnvironment;
+class CPDFSDK_Annot;
+class CPDFSDK_PageView;
+class CXFA_FFWidget;
+class CXFA_FFWidgetHandler;
+
+class CPDFSDK_XFAWidgetHandler : public IPDFSDK_AnnotHandler {
+ public:
+  explicit CPDFSDK_XFAWidgetHandler(CPDFSDK_FormFillEnvironment* pApp);
+  ~CPDFSDK_XFAWidgetHandler() override;
+
+  bool CanAnswer(CPDFSDK_Annot* pAnnot) override;
+  CPDFSDK_Annot* NewAnnot(CPDF_Annot* pAnnot, CPDFSDK_PageView* pPage) override;
+  CPDFSDK_Annot* NewAnnot(CXFA_FFWidget* pAnnot,
+                          CPDFSDK_PageView* pPage) override;
+  void ReleaseAnnot(CPDFSDK_Annot* pAnnot) override;
+  CFX_FloatRect GetViewBBox(CPDFSDK_PageView* pPageView,
+                            CPDFSDK_Annot* pAnnot) override;
+  bool HitTest(CPDFSDK_PageView* pPageView,
+               CPDFSDK_Annot* pAnnot,
+               const CFX_FloatPoint& point) override;
+  void OnDraw(CPDFSDK_PageView* pPageView,
+              CPDFSDK_Annot* pAnnot,
+              CFX_RenderDevice* pDevice,
+              CFX_Matrix* pUser2Device,
+              bool bDrawAnnots) override;
+  void OnLoad(CPDFSDK_Annot* pAnnot) override;
+  void OnMouseEnter(CPDFSDK_PageView* pPageView,
+                    CPDFSDK_Annot::ObservedPtr* pAnnot,
+                    uint32_t nFlag) override;
+  void OnMouseExit(CPDFSDK_PageView* pPageView,
+                   CPDFSDK_Annot::ObservedPtr* pAnnot,
+                   uint32_t nFlag) override;
+  bool OnLButtonDown(CPDFSDK_PageView* pPageView,
+                     CPDFSDK_Annot::ObservedPtr* pAnnot,
+                     uint32_t nFlags,
+                     const CFX_FloatPoint& point) override;
+  bool OnLButtonUp(CPDFSDK_PageView* pPageView,
+                   CPDFSDK_Annot::ObservedPtr* pAnnot,
+                   uint32_t nFlags,
+                   const CFX_FloatPoint& point) override;
+  bool OnLButtonDblClk(CPDFSDK_PageView* pPageView,
+                       CPDFSDK_Annot::ObservedPtr* pAnnot,
+                       uint32_t nFlags,
+                       const CFX_FloatPoint& point) override;
+  bool OnMouseMove(CPDFSDK_PageView* pPageView,
+                   CPDFSDK_Annot::ObservedPtr* pAnnot,
+                   uint32_t nFlags,
+                   const CFX_FloatPoint& point) override;
+  bool OnMouseWheel(CPDFSDK_PageView* pPageView,
+                    CPDFSDK_Annot::ObservedPtr* pAnnot,
+                    uint32_t nFlags,
+                    short zDelta,
+                    const CFX_FloatPoint& point) override;
+  bool OnRButtonDown(CPDFSDK_PageView* pPageView,
+                     CPDFSDK_Annot::ObservedPtr* pAnnot,
+                     uint32_t nFlags,
+                     const CFX_FloatPoint& point) override;
+  bool OnRButtonUp(CPDFSDK_PageView* pPageView,
+                   CPDFSDK_Annot::ObservedPtr* pAnnot,
+                   uint32_t nFlags,
+                   const CFX_FloatPoint& point) override;
+  bool OnRButtonDblClk(CPDFSDK_PageView* pPageView,
+                       CPDFSDK_Annot::ObservedPtr* pAnnot,
+                       uint32_t nFlags,
+                       const CFX_FloatPoint& point) override;
+  bool OnChar(CPDFSDK_Annot* pAnnot, uint32_t nChar, uint32_t nFlags) override;
+  bool OnKeyDown(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag) override;
+  bool OnKeyUp(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag) override;
+  bool OnSetFocus(CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlag) override;
+  bool OnKillFocus(CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlag) override;
+  bool OnXFAChangedFocus(CPDFSDK_Annot::ObservedPtr* pOldAnnot,
+                         CPDFSDK_Annot::ObservedPtr* pNewAnnot) override;
+
+ private:
+  CXFA_FFWidgetHandler* GetXFAWidgetHandler(CPDFSDK_Annot* pAnnot);
+  uint32_t GetFWLFlags(uint32_t dwFlag);
+
+  CPDFSDK_FormFillEnvironment* m_pFormFillEnv;
+};
+
+#endif  // FPDFSDK_CPDFSDK_XFAWIDGETHANDLER_H_
diff --git a/fpdfsdk/formfiller/cba_fontmap.cpp b/fpdfsdk/formfiller/cba_fontmap.cpp
new file mode 100644
index 0000000..750b416
--- /dev/null
+++ b/fpdfsdk/formfiller/cba_fontmap.cpp
@@ -0,0 +1,250 @@
+// 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
+
+#include "fpdfsdk/formfiller/cba_fontmap.h"
+
+#include <utility>
+
+#include "core/fpdfapi/font/cpdf_font.h"
+#include "core/fpdfapi/page/cpdf_page.h"
+#include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/cpdf_reference.h"
+#include "core/fpdfapi/parser/cpdf_simple_parser.h"
+#include "core/fpdfapi/parser/cpdf_stream.h"
+#include "core/fpdfapi/parser/fpdf_parser_decode.h"
+#include "core/fpdfdoc/cpdf_formfield.h"
+#include "core/fxge/cfx_substfont.h"
+#include "fpdfsdk/cpdfsdk_annot.h"
+
+CBA_FontMap::CBA_FontMap(CPDFSDK_Annot* pAnnot,
+                         CFX_SystemHandler* pSystemHandler)
+    : CPWL_FontMap(pSystemHandler),
+      m_pDocument(nullptr),
+      m_pAnnotDict(nullptr),
+      m_pDefaultFont(nullptr),
+      m_sAPType("N") {
+  CPDF_Page* pPage = pAnnot->GetPDFPage();
+
+  m_pDocument = pPage->m_pDocument;
+  m_pAnnotDict = pAnnot->GetPDFAnnot()->GetAnnotDict();
+  Initialize();
+}
+
+CBA_FontMap::~CBA_FontMap() {}
+
+void CBA_FontMap::Reset() {
+  Empty();
+  m_pDefaultFont = nullptr;
+  m_sDefaultFontName = "";
+}
+
+void CBA_FontMap::Initialize() {
+  int32_t nCharset = FXFONT_DEFAULT_CHARSET;
+
+  if (!m_pDefaultFont) {
+    m_pDefaultFont = GetAnnotDefaultFont(m_sDefaultFontName);
+    if (m_pDefaultFont) {
+      if (const CFX_SubstFont* pSubstFont = m_pDefaultFont->GetSubstFont()) {
+        nCharset = pSubstFont->m_Charset;
+      } else {
+        if (m_sDefaultFontName == "Wingdings" ||
+            m_sDefaultFontName == "Wingdings2" ||
+            m_sDefaultFontName == "Wingdings3" ||
+            m_sDefaultFontName == "Webdings")
+          nCharset = FXFONT_SYMBOL_CHARSET;
+        else
+          nCharset = FXFONT_ANSI_CHARSET;
+      }
+      AddFontData(m_pDefaultFont, m_sDefaultFontName, nCharset);
+      AddFontToAnnotDict(m_pDefaultFont, m_sDefaultFontName);
+    }
+  }
+
+  if (nCharset != FXFONT_ANSI_CHARSET)
+    CPWL_FontMap::Initialize();
+}
+
+void CBA_FontMap::SetDefaultFont(CPDF_Font* pFont,
+                                 const CFX_ByteString& sFontName) {
+  ASSERT(pFont);
+
+  if (m_pDefaultFont)
+    return;
+
+  m_pDefaultFont = pFont;
+  m_sDefaultFontName = sFontName;
+
+  int32_t nCharset = FXFONT_DEFAULT_CHARSET;
+  if (const CFX_SubstFont* pSubstFont = m_pDefaultFont->GetSubstFont())
+    nCharset = pSubstFont->m_Charset;
+  AddFontData(m_pDefaultFont, m_sDefaultFontName, nCharset);
+}
+
+CPDF_Font* CBA_FontMap::FindFontSameCharset(CFX_ByteString& sFontAlias,
+                                            int32_t nCharset) {
+  if (m_pAnnotDict->GetStringFor("Subtype") != "Widget")
+    return nullptr;
+
+  CPDF_Document* pDocument = GetDocument();
+  CPDF_Dictionary* pRootDict = pDocument->GetRoot();
+  if (!pRootDict)
+    return nullptr;
+
+  CPDF_Dictionary* pAcroFormDict = pRootDict->GetDictFor("AcroForm");
+  if (!pAcroFormDict)
+    return nullptr;
+
+  CPDF_Dictionary* pDRDict = pAcroFormDict->GetDictFor("DR");
+  if (!pDRDict)
+    return nullptr;
+
+  return FindResFontSameCharset(pDRDict, sFontAlias, nCharset);
+}
+
+CPDF_Document* CBA_FontMap::GetDocument() {
+  return m_pDocument;
+}
+
+CPDF_Font* CBA_FontMap::FindResFontSameCharset(CPDF_Dictionary* pResDict,
+                                               CFX_ByteString& sFontAlias,
+                                               int32_t nCharset) {
+  if (!pResDict)
+    return nullptr;
+
+  CPDF_Dictionary* pFonts = pResDict->GetDictFor("Font");
+  if (!pFonts)
+    return nullptr;
+
+  CPDF_Document* pDocument = GetDocument();
+  CPDF_Font* pFind = nullptr;
+  for (const auto& it : *pFonts) {
+    const CFX_ByteString& csKey = it.first;
+    if (!it.second)
+      continue;
+
+    CPDF_Dictionary* pElement = ToDictionary(it.second->GetDirect());
+    if (!pElement)
+      continue;
+    if (pElement->GetStringFor("Type") != "Font")
+      continue;
+
+    CPDF_Font* pFont = pDocument->LoadFont(pElement);
+    if (!pFont)
+      continue;
+    const CFX_SubstFont* pSubst = pFont->GetSubstFont();
+    if (!pSubst)
+      continue;
+    if (pSubst->m_Charset == nCharset) {
+      sFontAlias = csKey;
+      pFind = pFont;
+    }
+  }
+  return pFind;
+}
+
+void CBA_FontMap::AddedFont(CPDF_Font* pFont,
+                            const CFX_ByteString& sFontAlias) {
+  AddFontToAnnotDict(pFont, sFontAlias);
+}
+
+void CBA_FontMap::AddFontToAnnotDict(CPDF_Font* pFont,
+                                     const CFX_ByteString& sAlias) {
+  if (!pFont)
+    return;
+
+  CPDF_Dictionary* pAPDict = m_pAnnotDict->GetDictFor("AP");
+  if (!pAPDict)
+    pAPDict = m_pAnnotDict->SetNewFor<CPDF_Dictionary>("AP");
+
+  // to avoid checkbox and radiobutton
+  CPDF_Object* pObject = pAPDict->GetObjectFor(m_sAPType);
+  if (ToDictionary(pObject))
+    return;
+
+  CPDF_Stream* pStream = pAPDict->GetStreamFor(m_sAPType);
+  if (!pStream) {
+    pStream = m_pDocument->NewIndirect<CPDF_Stream>();
+    pAPDict->SetNewFor<CPDF_Reference>(m_sAPType, m_pDocument,
+                                       pStream->GetObjNum());
+  }
+
+  CPDF_Dictionary* pStreamDict = pStream->GetDict();
+  if (!pStreamDict) {
+    auto pOwnedDict =
+        pdfium::MakeUnique<CPDF_Dictionary>(m_pDocument->GetByteStringPool());
+    pStreamDict = pOwnedDict.get();
+    pStream->InitStream(nullptr, 0, std::move(pOwnedDict));
+  }
+
+  CPDF_Dictionary* pStreamResList = pStreamDict->GetDictFor("Resources");
+  if (!pStreamResList)
+    pStreamResList = pStreamDict->SetNewFor<CPDF_Dictionary>("Resources");
+  CPDF_Dictionary* pStreamResFontList = pStreamResList->GetDictFor("Font");
+  if (!pStreamResFontList) {
+    pStreamResFontList = m_pDocument->NewIndirect<CPDF_Dictionary>();
+    pStreamResList->SetNewFor<CPDF_Reference>("Font", m_pDocument,
+                                              pStreamResFontList->GetObjNum());
+  }
+  if (!pStreamResFontList->KeyExist(sAlias)) {
+    pStreamResFontList->SetNewFor<CPDF_Reference>(
+        sAlias, m_pDocument, pFont->GetFontDict()->GetObjNum());
+  }
+}
+
+CPDF_Font* CBA_FontMap::GetAnnotDefaultFont(CFX_ByteString& sAlias) {
+  CPDF_Dictionary* pAcroFormDict = nullptr;
+  const bool bWidget = (m_pAnnotDict->GetStringFor("Subtype") == "Widget");
+  if (bWidget) {
+    if (CPDF_Dictionary* pRootDict = m_pDocument->GetRoot())
+      pAcroFormDict = pRootDict->GetDictFor("AcroForm");
+  }
+
+  CFX_ByteString sDA;
+  CPDF_Object* pObj = FPDF_GetFieldAttr(m_pAnnotDict, "DA");
+  if (pObj)
+    sDA = pObj->GetString();
+
+  if (bWidget) {
+    if (sDA.IsEmpty()) {
+      pObj = FPDF_GetFieldAttr(pAcroFormDict, "DA");
+      sDA = pObj ? pObj->GetString() : CFX_ByteString();
+    }
+  }
+  if (sDA.IsEmpty())
+    return nullptr;
+
+  CPDF_SimpleParser syntax(sDA.AsStringC());
+  syntax.FindTagParamFromStart("Tf", 2);
+  CFX_ByteString sFontName(syntax.GetWord());
+  sAlias = PDF_NameDecode(sFontName).Mid(1);
+  CPDF_Dictionary* pFontDict = nullptr;
+
+  if (CPDF_Dictionary* pAPDict = m_pAnnotDict->GetDictFor("AP")) {
+    if (CPDF_Dictionary* pNormalDict = pAPDict->GetDictFor("N")) {
+      if (CPDF_Dictionary* pNormalResDict =
+              pNormalDict->GetDictFor("Resources")) {
+        if (CPDF_Dictionary* pResFontDict = pNormalResDict->GetDictFor("Font"))
+          pFontDict = pResFontDict->GetDictFor(sAlias);
+      }
+    }
+  }
+
+  if (bWidget && !pFontDict && pAcroFormDict) {
+    if (CPDF_Dictionary* pDRDict = pAcroFormDict->GetDictFor("DR")) {
+      if (CPDF_Dictionary* pDRFontDict = pDRDict->GetDictFor("Font"))
+        pFontDict = pDRFontDict->GetDictFor(sAlias);
+    }
+  }
+
+  return pFontDict ? m_pDocument->LoadFont(pFontDict) : nullptr;
+}
+
+void CBA_FontMap::SetAPType(const CFX_ByteString& sAPType) {
+  m_sAPType = sAPType;
+
+  Reset();
+  Initialize();
+}
diff --git a/fpdfsdk/include/formfiller/FFL_CBA_Fontmap.h b/fpdfsdk/formfiller/cba_fontmap.h
similarity index 81%
rename from fpdfsdk/include/formfiller/FFL_CBA_Fontmap.h
rename to fpdfsdk/formfiller/cba_fontmap.h
index c3e2e99..c0e569a 100644
--- a/fpdfsdk/include/formfiller/FFL_CBA_Fontmap.h
+++ b/fpdfsdk/formfiller/cba_fontmap.h
@@ -4,17 +4,17 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#ifndef FPDFSDK_INCLUDE_FORMFILLER_FFL_CBA_FONTMAP_H_
-#define FPDFSDK_INCLUDE_FORMFILLER_FFL_CBA_FONTMAP_H_
+#ifndef FPDFSDK_FORMFILLER_CBA_FONTMAP_H_
+#define FPDFSDK_FORMFILLER_CBA_FONTMAP_H_
 
-#include "fpdfsdk/include/pdfwindow/PWL_FontMap.h"
+#include "fpdfsdk/pdfwindow/PWL_FontMap.h"
 
 class CPDF_Dictionary;
 class CPDFSDK_Annot;
 
 class CBA_FontMap : public CPWL_FontMap {
  public:
-  CBA_FontMap(CPDFSDK_Annot* pAnnot, IFX_SystemHandler* pSystemHandler);
+  CBA_FontMap(CPDFSDK_Annot* pAnnot, CFX_SystemHandler* pSystemHandler);
   ~CBA_FontMap() override;
 
   void SetDefaultFont(CPDF_Font* pFont, const CFX_ByteString& sFontName);
@@ -43,4 +43,4 @@
   CFX_ByteString m_sAPType;
 };
 
-#endif  // FPDFSDK_INCLUDE_FORMFILLER_FFL_CBA_FONTMAP_H_
+#endif  // FPDFSDK_FORMFILLER_CBA_FONTMAP_H_
diff --git a/fpdfsdk/formfiller/cffl_checkbox.cpp b/fpdfsdk/formfiller/cffl_checkbox.cpp
new file mode 100644
index 0000000..ffa3a03
--- /dev/null
+++ b/fpdfsdk/formfiller/cffl_checkbox.cpp
@@ -0,0 +1,116 @@
+// 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
+
+#include "fpdfsdk/formfiller/cffl_checkbox.h"
+
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/cpdfsdk_widget.h"
+#include "fpdfsdk/formfiller/cffl_formfiller.h"
+#include "fpdfsdk/pdfwindow/PWL_SpecialButton.h"
+#include "public/fpdf_fwlevent.h"
+
+CFFL_CheckBox::CFFL_CheckBox(CPDFSDK_FormFillEnvironment* pApp,
+                             CPDFSDK_Widget* pWidget)
+    : CFFL_Button(pApp, pWidget) {}
+
+CFFL_CheckBox::~CFFL_CheckBox() {}
+
+CPWL_Wnd* CFFL_CheckBox::NewPDFWindow(const PWL_CREATEPARAM& cp,
+                                      CPDFSDK_PageView* pPageView) {
+  CPWL_CheckBox* pWnd = new CPWL_CheckBox();
+  pWnd->Create(cp);
+  pWnd->SetCheck(m_pWidget->IsChecked());
+  return pWnd;
+}
+
+bool CFFL_CheckBox::OnKeyDown(CPDFSDK_Annot* pAnnot,
+                              uint32_t nKeyCode,
+                              uint32_t nFlags) {
+  switch (nKeyCode) {
+    case FWL_VKEY_Return:
+    case FWL_VKEY_Space:
+      return true;
+    default:
+      return CFFL_FormFiller::OnKeyDown(pAnnot, nKeyCode, nFlags);
+  }
+}
+bool CFFL_CheckBox::OnChar(CPDFSDK_Annot* pAnnot,
+                           uint32_t nChar,
+                           uint32_t nFlags) {
+  switch (nChar) {
+    case FWL_VKEY_Return:
+    case FWL_VKEY_Space: {
+      CPDFSDK_PageView* pPageView = pAnnot->GetPageView();
+      ASSERT(pPageView);
+
+      bool bReset = false;
+      bool bExit = false;
+      CPDFSDK_Annot::ObservedPtr pObserved(m_pWidget);
+      m_pFormFillEnv->GetInteractiveFormFiller()->OnButtonUp(
+          &pObserved, pPageView, bReset, bExit, nFlags);
+      if (!pObserved) {
+        m_pWidget = nullptr;
+        return true;
+      }
+      if (bReset || bExit)
+        return true;
+
+      CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
+      if (CPWL_CheckBox* pWnd = (CPWL_CheckBox*)GetPDFWindow(pPageView, true))
+        pWnd->SetCheck(!pWnd->IsChecked());
+
+      CommitData(pPageView, nFlags);
+      return true;
+    }
+    default:
+      return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
+  }
+}
+
+bool CFFL_CheckBox::OnLButtonUp(CPDFSDK_PageView* pPageView,
+                                CPDFSDK_Annot* pAnnot,
+                                uint32_t nFlags,
+                                const CFX_FloatPoint& point) {
+  CFFL_Button::OnLButtonUp(pPageView, pAnnot, nFlags, point);
+
+  if (IsValid()) {
+    if (CPWL_CheckBox* pWnd = (CPWL_CheckBox*)GetPDFWindow(pPageView, true)) {
+      CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
+      pWnd->SetCheck(!pWidget->IsChecked());
+    }
+
+    if (!CommitData(pPageView, nFlags))
+      return false;
+  }
+
+  return true;
+}
+
+bool CFFL_CheckBox::IsDataChanged(CPDFSDK_PageView* pPageView) {
+  CPWL_CheckBox* pWnd = (CPWL_CheckBox*)GetPDFWindow(pPageView, false);
+  return pWnd && pWnd->IsChecked() != m_pWidget->IsChecked();
+}
+
+void CFFL_CheckBox::SaveData(CPDFSDK_PageView* pPageView) {
+  if (CPWL_CheckBox* pWnd = (CPWL_CheckBox*)GetPDFWindow(pPageView, false)) {
+    bool bNewChecked = pWnd->IsChecked();
+
+    if (bNewChecked) {
+      CPDF_FormField* pField = m_pWidget->GetFormField();
+      for (int32_t i = 0, sz = pField->CountControls(); i < sz; i++) {
+        if (CPDF_FormControl* pCtrl = pField->GetControl(i)) {
+          if (pCtrl->IsChecked()) {
+            break;
+          }
+        }
+      }
+    }
+
+    m_pWidget->SetCheck(bNewChecked, false);
+    m_pWidget->UpdateField();
+    SetChangeMark();
+  }
+}
diff --git a/fpdfsdk/formfiller/cffl_checkbox.h b/fpdfsdk/formfiller/cffl_checkbox.h
new file mode 100644
index 0000000..65dba29
--- /dev/null
+++ b/fpdfsdk/formfiller/cffl_checkbox.h
@@ -0,0 +1,32 @@
+// 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_FORMFILLER_CFFL_CHECKBOX_H_
+#define FPDFSDK_FORMFILLER_CFFL_CHECKBOX_H_
+
+#include "fpdfsdk/formfiller/cffl_formfiller.h"
+
+class CFFL_CheckBox : public CFFL_Button {
+ public:
+  CFFL_CheckBox(CPDFSDK_FormFillEnvironment* pApp, CPDFSDK_Widget* pWidget);
+  ~CFFL_CheckBox() override;
+
+  // CFFL_Button
+  CPWL_Wnd* NewPDFWindow(const PWL_CREATEPARAM& cp,
+                         CPDFSDK_PageView* pPageView) override;
+  bool OnKeyDown(CPDFSDK_Annot* pAnnot,
+                 uint32_t nKeyCode,
+                 uint32_t nFlags) override;
+  bool OnChar(CPDFSDK_Annot* pAnnot, uint32_t nChar, uint32_t nFlags) override;
+  bool OnLButtonUp(CPDFSDK_PageView* pPageView,
+                   CPDFSDK_Annot* pAnnot,
+                   uint32_t nFlags,
+                   const CFX_FloatPoint& point) override;
+  bool IsDataChanged(CPDFSDK_PageView* pPageView) override;
+  void SaveData(CPDFSDK_PageView* pPageView) override;
+};
+
+#endif  // FPDFSDK_FORMFILLER_CFFL_CHECKBOX_H_
diff --git a/fpdfsdk/src/formfiller/FFL_ComboBox.cpp b/fpdfsdk/formfiller/cffl_combobox.cpp
similarity index 71%
rename from fpdfsdk/src/formfiller/FFL_ComboBox.cpp
rename to fpdfsdk/formfiller/cffl_combobox.cpp
index 5e88a5d..c8438a3 100644
--- a/fpdfsdk/src/formfiller/FFL_ComboBox.cpp
+++ b/fpdfsdk/formfiller/cffl_combobox.cpp
@@ -4,17 +4,19 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#include "fpdfsdk/include/formfiller/FFL_ComboBox.h"
+#include "fpdfsdk/formfiller/cffl_combobox.h"
 
-#include "fpdfsdk/include/formfiller/FFL_CBA_Fontmap.h"
-#include "fpdfsdk/include/formfiller/FFL_FormFiller.h"
-#include "fpdfsdk/include/formfiller/FFL_IFormFiller.h"
-#include "fpdfsdk/include/fsdk_common.h"
-#include "fpdfsdk/include/fsdk_mgr.h"
-#include "fpdfsdk/include/pdfwindow/PWL_ComboBox.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/cpdfsdk_widget.h"
+#include "fpdfsdk/formfiller/cba_fontmap.h"
+#include "fpdfsdk/formfiller/cffl_formfiller.h"
+#include "fpdfsdk/formfiller/cffl_interactiveformfiller.h"
+#include "fpdfsdk/fsdk_common.h"
+#include "fpdfsdk/pdfwindow/PWL_ComboBox.h"
 
-CFFL_ComboBox::CFFL_ComboBox(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pAnnot)
-    : CFFL_FormFiller(pApp, pAnnot), m_pFontMap(NULL) {
+CFFL_ComboBox::CFFL_ComboBox(CPDFSDK_FormFillEnvironment* pApp,
+                             CPDFSDK_Annot* pAnnot)
+    : CFFL_FormFiller(pApp, pAnnot), m_pFontMap(nullptr) {
   m_State.nIndex = 0;
   m_State.nStart = 0;
   m_State.nEnd = 0;
@@ -23,6 +25,11 @@
 CFFL_ComboBox::~CFFL_ComboBox() {
   for (const auto& it : m_Maps)
     it.second->InvalidateFocusHandler(this);
+
+  // See comment in cffl_formfiller.h.
+  // The font map should be stored somewhere more appropriate so it will live
+  // until the PWL_Edit is done with it. pdfium:566
+  DestroyWindows();
   delete m_pFontMap;
 }
 
@@ -48,7 +55,8 @@
   pWnd->AttachFFLData(this);
   pWnd->Create(cp);
 
-  CFFL_IFormFiller* pFormFiller = m_pApp->GetIFormFiller();
+  CFFL_InteractiveFormFiller* pFormFiller =
+      m_pFormFillEnv->GetInteractiveFormFiller();
   pWnd->SetFillerNotify(pFormFiller);
 
   int32_t nCurSel = m_pWidget->GetSelectedIndex(0);
@@ -59,24 +67,24 @@
     swText = m_pWidget->GetOptionLabel(nCurSel);
 
   for (int32_t i = 0, sz = m_pWidget->CountOptions(); i < sz; i++) {
-    pWnd->AddString(m_pWidget->GetOptionLabel(i).c_str());
+    pWnd->AddString(m_pWidget->GetOptionLabel(i));
   }
 
   pWnd->SetSelect(nCurSel);
-  pWnd->SetText(swText.c_str());
+  pWnd->SetText(swText);
   return pWnd;
 }
 
-FX_BOOL CFFL_ComboBox::OnChar(CPDFSDK_Annot* pAnnot,
-                              FX_UINT nChar,
-                              FX_UINT nFlags) {
+bool CFFL_ComboBox::OnChar(CPDFSDK_Annot* pAnnot,
+                           uint32_t nChar,
+                           uint32_t nFlags) {
   return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
 }
 
-FX_BOOL CFFL_ComboBox::IsDataChanged(CPDFSDK_PageView* pPageView) {
-  CPWL_ComboBox* pWnd = (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE);
+bool CFFL_ComboBox::IsDataChanged(CPDFSDK_PageView* pPageView) {
+  CPWL_ComboBox* pWnd = (CPWL_ComboBox*)GetPDFWindow(pPageView, false);
   if (!pWnd)
-    return FALSE;
+    return false;
 
   int32_t nCurSel = pWnd->GetSelect();
   if (!(m_pWidget->GetFieldFlags() & FIELDFLAG_EDIT))
@@ -90,7 +98,7 @@
 
 void CFFL_ComboBox::SaveData(CPDFSDK_PageView* pPageView) {
   CPWL_ComboBox* pWnd =
-      static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, FALSE));
+      static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, false));
   if (!pWnd)
     return;
 
@@ -103,13 +111,13 @@
     bSetValue = (nCurSel < 0) || (swText != m_pWidget->GetOptionLabel(nCurSel));
 
   if (bSetValue) {
-    m_pWidget->SetValue(swText, FALSE);
+    m_pWidget->SetValue(swText, false);
   } else {
     m_pWidget->GetSelectedIndex(0);
-    m_pWidget->SetOptionSelection(nCurSel, TRUE, FALSE);
+    m_pWidget->SetOptionSelection(nCurSel, true, false);
   }
 
-  m_pWidget->ResetFieldAppearance(TRUE);
+  m_pWidget->ResetFieldAppearance(true);
   m_pWidget->UpdateField();
   SetChangeMark();
 
@@ -122,7 +130,7 @@
   switch (type) {
     case CPDF_AAction::KeyStroke:
       if (CPWL_ComboBox* pComboBox =
-              static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, FALSE))) {
+              static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, false))) {
         if (CPWL_Edit* pEdit = pComboBox->GetEdit()) {
           fa.bFieldFull = pEdit->IsTextFull();
           int nSelStart = 0;
@@ -142,7 +150,7 @@
       break;
     case CPDF_AAction::Validate:
       if (CPWL_ComboBox* pComboBox =
-              static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, FALSE))) {
+              static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, false))) {
         if (CPWL_Edit* pEdit = pComboBox->GetEdit()) {
           fa.sValue = pEdit->GetText();
         }
@@ -163,10 +171,10 @@
   switch (type) {
     case CPDF_AAction::KeyStroke:
       if (CPWL_ComboBox* pComboBox =
-              static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, FALSE))) {
+              static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, false))) {
         if (CPWL_Edit* pEdit = pComboBox->GetEdit()) {
           pEdit->SetSel(fa.nSelStart, fa.nSelEnd);
-          pEdit->ReplaceSel(fa.sChange.c_str());
+          pEdit->ReplaceSel(fa.sChange);
         }
       }
       break;
@@ -175,9 +183,9 @@
   }
 }
 
-FX_BOOL CFFL_ComboBox::IsActionDataChanged(CPDF_AAction::AActionType type,
-                                           const PDFSDK_FieldAction& faOld,
-                                           const PDFSDK_FieldAction& faNew) {
+bool CFFL_ComboBox::IsActionDataChanged(CPDF_AAction::AActionType type,
+                                        const PDFSDK_FieldAction& faOld,
+                                        const PDFSDK_FieldAction& faNew) {
   switch (type) {
     case CPDF_AAction::KeyStroke:
       return (!faOld.bFieldFull && faOld.nSelEnd != faNew.nSelEnd) ||
@@ -187,14 +195,14 @@
       break;
   }
 
-  return FALSE;
+  return false;
 }
 
 void CFFL_ComboBox::SaveState(CPDFSDK_PageView* pPageView) {
   ASSERT(pPageView);
 
   if (CPWL_ComboBox* pComboBox =
-          static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, FALSE))) {
+          static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, false))) {
     m_State.nIndex = pComboBox->GetSelect();
 
     if (CPWL_Edit* pEdit = pComboBox->GetEdit()) {
@@ -208,12 +216,12 @@
   ASSERT(pPageView);
 
   if (CPWL_ComboBox* pComboBox =
-          static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, TRUE))) {
+          static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, true))) {
     if (m_State.nIndex >= 0) {
       pComboBox->SetSelect(m_State.nIndex);
     } else {
       if (CPWL_Edit* pEdit = pComboBox->GetEdit()) {
-        pEdit->SetText(m_State.sValue.c_str());
+        pEdit->SetText(m_State.sValue);
         pEdit->SetSel(m_State.nStart, m_State.nEnd);
       }
     }
@@ -221,19 +229,19 @@
 }
 
 CPWL_Wnd* CFFL_ComboBox::ResetPDFWindow(CPDFSDK_PageView* pPageView,
-                                        FX_BOOL bRestoreValue) {
+                                        bool bRestoreValue) {
   if (bRestoreValue)
     SaveState(pPageView);
 
   DestroyPDFWindow(pPageView);
 
-  CPWL_Wnd* pRet = NULL;
+  CPWL_Wnd* pRet = nullptr;
 
   if (bRestoreValue) {
     RestoreState(pPageView);
-    pRet = GetPDFWindow(pPageView, FALSE);
+    pRet = GetPDFWindow(pPageView, false);
   } else {
-    pRet = GetPDFWindow(pPageView, TRUE);
+    pRet = GetPDFWindow(pPageView, true);
   }
 
   m_pWidget->UpdateField();
@@ -242,22 +250,22 @@
 }
 
 #ifdef PDF_ENABLE_XFA
-FX_BOOL CFFL_ComboBox::IsFieldFull(CPDFSDK_PageView* pPageView) {
+bool CFFL_ComboBox::IsFieldFull(CPDFSDK_PageView* pPageView) {
   if (CPWL_ComboBox* pComboBox =
-          static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, FALSE))) {
+          static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, false))) {
     if (CPWL_Edit* pEdit = pComboBox->GetEdit())
       return pEdit->IsTextFull();
   }
-  return FALSE;
+  return false;
 }
 #endif  // PDF_ENABLE_XFA
 
 void CFFL_ComboBox::OnSetFocus(CPWL_Wnd* pWnd) {
-  ASSERT(m_pApp);
+  ASSERT(m_pFormFillEnv);
 
   if (pWnd->GetClassName() == PWL_CLASSNAME_EDIT) {
     CPWL_Edit* pEdit = (CPWL_Edit*)pWnd;
-    pEdit->SetCharSet(134);
+    pEdit->SetCharSet(FXFONT_GB2312_CHARSET);
     pEdit->SetCodePage(936);
 
     pEdit->SetReadyToInput();
@@ -265,28 +273,17 @@
     int nCharacters = wsText.GetLength();
     CFX_ByteString bsUTFText = wsText.UTF16LE_Encode();
     unsigned short* pBuffer = (unsigned short*)bsUTFText.c_str();
-    m_pApp->FFI_OnSetFieldInputFocus(m_pWidget->GetFormField(), pBuffer,
-                                     nCharacters, TRUE);
-
-    pEdit->SetEditNotify(this);
+    m_pFormFillEnv->OnSetFieldInputFocus(pBuffer, nCharacters, true);
   }
 }
 
-void CFFL_ComboBox::OnKillFocus(CPWL_Wnd* pWnd) {
-  ASSERT(m_pApp);
-}
-
-void CFFL_ComboBox::OnAddUndo(CPWL_Edit* pEdit) {
-  ASSERT(pEdit);
-}
-
 CFX_WideString CFFL_ComboBox::GetSelectExportText() {
   CFX_WideString swRet;
 
   int nExport = -1;
-  CPDFSDK_PageView* pPageView = GetCurPageView();
+  CPDFSDK_PageView* pPageView = GetCurPageView(true);
   if (CPWL_ComboBox* pComboBox =
-          (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE)) {
+          (CPWL_ComboBox*)GetPDFWindow(pPageView, false)) {
     nExport = pComboBox->GetSelect();
   }
 
diff --git a/fpdfsdk/formfiller/cffl_combobox.h b/fpdfsdk/formfiller/cffl_combobox.h
new file mode 100644
index 0000000..aab10b9
--- /dev/null
+++ b/fpdfsdk/formfiller/cffl_combobox.h
@@ -0,0 +1,63 @@
+// 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_FORMFILLER_CFFL_COMBOBOX_H_
+#define FPDFSDK_FORMFILLER_CFFL_COMBOBOX_H_
+
+#include "core/fxcrt/fx_string.h"
+#include "fpdfsdk/formfiller/cffl_formfiller.h"
+
+class CBA_FontMap;
+
+struct FFL_ComboBoxState {
+  int nIndex;
+  int nStart;
+  int nEnd;
+  CFX_WideString sValue;
+};
+
+class CFFL_ComboBox : public CFFL_FormFiller, public IPWL_FocusHandler {
+ public:
+  CFFL_ComboBox(CPDFSDK_FormFillEnvironment* pApp, CPDFSDK_Annot* pWidget);
+  ~CFFL_ComboBox() override;
+
+  // CFFL_FormFiller:
+  PWL_CREATEPARAM GetCreateParam() override;
+  CPWL_Wnd* NewPDFWindow(const PWL_CREATEPARAM& cp,
+                         CPDFSDK_PageView* pPageView) override;
+  bool OnChar(CPDFSDK_Annot* pAnnot, uint32_t nChar, uint32_t nFlags) override;
+  bool IsDataChanged(CPDFSDK_PageView* pPageView) override;
+  void SaveData(CPDFSDK_PageView* pPageView) override;
+  void GetActionData(CPDFSDK_PageView* pPageView,
+                     CPDF_AAction::AActionType type,
+                     PDFSDK_FieldAction& fa) override;
+  void SetActionData(CPDFSDK_PageView* pPageView,
+                     CPDF_AAction::AActionType type,
+                     const PDFSDK_FieldAction& fa) override;
+  bool IsActionDataChanged(CPDF_AAction::AActionType type,
+                           const PDFSDK_FieldAction& faOld,
+                           const PDFSDK_FieldAction& faNew) override;
+  void SaveState(CPDFSDK_PageView* pPageView) override;
+  void RestoreState(CPDFSDK_PageView* pPageView) override;
+  CPWL_Wnd* ResetPDFWindow(CPDFSDK_PageView* pPageView,
+                           bool bRestoreValue) override;
+
+  // IPWL_FocusHandler:
+  void OnSetFocus(CPWL_Wnd* pWnd) override;
+
+#ifdef PDF_ENABLE_XFA
+  // CFFL_FormFiller:
+  bool IsFieldFull(CPDFSDK_PageView* pPageView) override;
+#endif  // PDF_ENABLE_XFA
+
+ private:
+  CFX_WideString GetSelectExportText();
+
+  CBA_FontMap* m_pFontMap;
+  FFL_ComboBoxState m_State;
+};
+
+#endif  // FPDFSDK_FORMFILLER_CFFL_COMBOBOX_H_
diff --git a/fpdfsdk/formfiller/cffl_formfiller.cpp b/fpdfsdk/formfiller/cffl_formfiller.cpp
new file mode 100644
index 0000000..281057a
--- /dev/null
+++ b/fpdfsdk/formfiller/cffl_formfiller.cpp
@@ -0,0 +1,711 @@
+// 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
+
+#include "fpdfsdk/formfiller/cffl_formfiller.h"
+
+#include "core/fpdfapi/page/cpdf_page.h"
+#include "core/fxge/cfx_renderdevice.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/cpdfsdk_pageview.h"
+#include "fpdfsdk/cpdfsdk_widget.h"
+#include "fpdfsdk/formfiller/cba_fontmap.h"
+#include "fpdfsdk/fsdk_common.h"
+#include "fpdfsdk/pdfwindow/PWL_Utils.h"
+
+#define GetRed(rgb) ((uint8_t)(rgb))
+#define GetGreen(rgb) ((uint8_t)(((uint16_t)(rgb)) >> 8))
+#define GetBlue(rgb) ((uint8_t)((rgb) >> 16))
+
+#define FFL_HINT_ELAPSE 800
+
+CFFL_FormFiller::CFFL_FormFiller(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                                 CPDFSDK_Annot* pAnnot)
+    : m_pFormFillEnv(pFormFillEnv), m_pAnnot(pAnnot), m_bValid(false) {
+  m_pWidget = static_cast<CPDFSDK_Widget*>(pAnnot);
+}
+
+CFFL_FormFiller::~CFFL_FormFiller() {
+  DestroyWindows();
+}
+
+void CFFL_FormFiller::DestroyWindows() {
+  for (const auto& it : m_Maps) {
+    CPWL_Wnd* pWnd = it.second;
+    CFFL_PrivateData* pData = (CFFL_PrivateData*)pWnd->GetAttachedData();
+    pWnd->InvalidateProvider(this);
+    pWnd->Destroy();
+    delete pWnd;
+    delete pData;
+  }
+  m_Maps.clear();
+}
+
+void CFFL_FormFiller::SetWindowRect(CPDFSDK_PageView* pPageView,
+                                    const CFX_FloatRect& rcWindow) {
+  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, false)) {
+    pWnd->Move(CFX_FloatRect(rcWindow), true, false);
+  }
+}
+
+CFX_FloatRect CFFL_FormFiller::GetWindowRect(CPDFSDK_PageView* pPageView) {
+  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, false)) {
+    return pWnd->GetWindowRect();
+  }
+
+  return CFX_FloatRect(0, 0, 0, 0);
+}
+
+FX_RECT CFFL_FormFiller::GetViewBBox(CPDFSDK_PageView* pPageView,
+                                     CPDFSDK_Annot* pAnnot) {
+  ASSERT(pPageView);
+  ASSERT(pAnnot);
+
+  CFX_FloatRect rcAnnot = m_pWidget->GetRect();
+
+  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, false)) {
+    CFX_FloatRect rcWindow = pWnd->GetWindowRect();
+    rcAnnot = PWLtoFFL(rcWindow);
+  }
+
+  CFX_FloatRect rcWin = rcAnnot;
+
+  CFX_FloatRect rcFocus = GetFocusBox(pPageView);
+  if (!rcFocus.IsEmpty())
+    rcWin.Union(rcFocus);
+
+  CFX_FloatRect rect = CPWL_Utils::InflateRect(rcWin, 1);
+
+  return rect.GetOuterRect();
+}
+
+void CFFL_FormFiller::OnDraw(CPDFSDK_PageView* pPageView,
+                             CPDFSDK_Annot* pAnnot,
+                             CFX_RenderDevice* pDevice,
+                             CFX_Matrix* pUser2Device) {
+  ASSERT(pAnnot->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
+
+  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, false)) {
+    CFX_Matrix mt = GetCurMatrix();
+    mt.Concat(*pUser2Device);
+    pWnd->DrawAppearance(pDevice, &mt);
+  } else {
+    CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
+    if (CFFL_InteractiveFormFiller::IsVisible(pWidget))
+      pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal,
+                              nullptr);
+  }
+}
+
+void CFFL_FormFiller::OnDrawDeactive(CPDFSDK_PageView* pPageView,
+                                     CPDFSDK_Annot* pAnnot,
+                                     CFX_RenderDevice* pDevice,
+                                     CFX_Matrix* pUser2Device) {
+  CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
+  pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, nullptr);
+}
+
+void CFFL_FormFiller::OnMouseEnter(CPDFSDK_PageView* pPageView,
+                                   CPDFSDK_Annot* pAnnot) {}
+
+void CFFL_FormFiller::OnMouseExit(CPDFSDK_PageView* pPageView,
+                                  CPDFSDK_Annot* pAnnot) {
+  EndTimer();
+  ASSERT(m_pWidget);
+}
+
+bool CFFL_FormFiller::OnLButtonDown(CPDFSDK_PageView* pPageView,
+                                    CPDFSDK_Annot* pAnnot,
+                                    uint32_t nFlags,
+                                    const CFX_FloatPoint& point) {
+  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, true)) {
+    m_bValid = true;
+    FX_RECT rect = GetViewBBox(pPageView, pAnnot);
+    InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
+
+    if (!rect.Contains((int)point.x, (int)point.y))
+      return false;
+
+    return pWnd->OnLButtonDown(WndtoPWL(pPageView, point), nFlags);
+  }
+
+  return false;
+}
+
+bool CFFL_FormFiller::OnLButtonUp(CPDFSDK_PageView* pPageView,
+                                  CPDFSDK_Annot* pAnnot,
+                                  uint32_t nFlags,
+                                  const CFX_FloatPoint& point) {
+  CPWL_Wnd* pWnd = GetPDFWindow(pPageView, false);
+  if (!pWnd)
+    return false;
+
+  FX_RECT rcFFL = GetViewBBox(pPageView, pAnnot);
+  InvalidateRect(rcFFL.left, rcFFL.top, rcFFL.right, rcFFL.bottom);
+  pWnd->OnLButtonUp(WndtoPWL(pPageView, point), nFlags);
+  return true;
+}
+
+bool CFFL_FormFiller::OnLButtonDblClk(CPDFSDK_PageView* pPageView,
+                                      CPDFSDK_Annot* pAnnot,
+                                      uint32_t nFlags,
+                                      const CFX_FloatPoint& point) {
+  CPWL_Wnd* pWnd = GetPDFWindow(pPageView, false);
+  if (!pWnd)
+    return false;
+
+  pWnd->OnLButtonDblClk(WndtoPWL(pPageView, point), nFlags);
+  return true;
+}
+
+bool CFFL_FormFiller::OnMouseMove(CPDFSDK_PageView* pPageView,
+                                  CPDFSDK_Annot* pAnnot,
+                                  uint32_t nFlags,
+                                  const CFX_FloatPoint& point) {
+  if (m_ptOldPos != point)
+    m_ptOldPos = point;
+
+  CPWL_Wnd* pWnd = GetPDFWindow(pPageView, false);
+  if (!pWnd)
+    return false;
+
+  pWnd->OnMouseMove(WndtoPWL(pPageView, point), nFlags);
+  return true;
+}
+
+bool CFFL_FormFiller::OnMouseWheel(CPDFSDK_PageView* pPageView,
+                                   CPDFSDK_Annot* pAnnot,
+                                   uint32_t nFlags,
+                                   short zDelta,
+                                   const CFX_FloatPoint& point) {
+  if (!IsValid())
+    return false;
+
+  CPWL_Wnd* pWnd = GetPDFWindow(pPageView, true);
+  return pWnd && pWnd->OnMouseWheel(zDelta, WndtoPWL(pPageView, point), nFlags);
+}
+
+bool CFFL_FormFiller::OnRButtonDown(CPDFSDK_PageView* pPageView,
+                                    CPDFSDK_Annot* pAnnot,
+                                    uint32_t nFlags,
+                                    const CFX_FloatPoint& point) {
+  CPWL_Wnd* pWnd = GetPDFWindow(pPageView, true);
+  if (!pWnd)
+    return false;
+
+  pWnd->OnRButtonDown(WndtoPWL(pPageView, point), nFlags);
+  return true;
+}
+
+bool CFFL_FormFiller::OnRButtonUp(CPDFSDK_PageView* pPageView,
+                                  CPDFSDK_Annot* pAnnot,
+                                  uint32_t nFlags,
+                                  const CFX_FloatPoint& point) {
+  CPWL_Wnd* pWnd = GetPDFWindow(pPageView, false);
+  if (!pWnd)
+    return false;
+
+  pWnd->OnRButtonUp(WndtoPWL(pPageView, point), nFlags);
+  return true;
+}
+
+bool CFFL_FormFiller::OnKeyDown(CPDFSDK_Annot* pAnnot,
+                                uint32_t nKeyCode,
+                                uint32_t nFlags) {
+  if (IsValid()) {
+    CPDFSDK_PageView* pPageView = GetCurPageView(true);
+    ASSERT(pPageView);
+
+    if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, false)) {
+      return pWnd->OnKeyDown(nKeyCode, nFlags);
+    }
+  }
+
+  return false;
+}
+
+bool CFFL_FormFiller::OnChar(CPDFSDK_Annot* pAnnot,
+                             uint32_t nChar,
+                             uint32_t nFlags) {
+  if (IsValid()) {
+    CPDFSDK_PageView* pPageView = GetCurPageView(true);
+    ASSERT(pPageView);
+
+    if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, false)) {
+      return pWnd->OnChar(nChar, nFlags);
+    }
+  }
+
+  return false;
+}
+
+void CFFL_FormFiller::SetFocusForAnnot(CPDFSDK_Annot* pAnnot, uint32_t nFlag) {
+  CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
+  UnderlyingPageType* pPage = pWidget->GetUnderlyingPage();
+  CPDFSDK_PageView* pPageView = m_pFormFillEnv->GetPageView(pPage, true);
+  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, true))
+    pWnd->SetFocus();
+
+  m_bValid = true;
+  FX_RECT rcRect = GetViewBBox(pPageView, pAnnot);
+  InvalidateRect(rcRect.left, rcRect.top, rcRect.right, rcRect.bottom);
+}
+
+void CFFL_FormFiller::KillFocusForAnnot(CPDFSDK_Annot* pAnnot, uint32_t nFlag) {
+  if (!IsValid())
+    return;
+
+  CPDFSDK_PageView* pPageView = GetCurPageView(false);
+  if (!pPageView)
+    return;
+
+  CommitData(pPageView, nFlag);
+
+  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, false))
+    pWnd->KillFocus();
+
+  bool bDestroyPDFWindow;
+  switch (m_pWidget->GetFieldType()) {
+    case FIELDTYPE_PUSHBUTTON:
+    case FIELDTYPE_CHECKBOX:
+    case FIELDTYPE_RADIOBUTTON:
+      bDestroyPDFWindow = true;
+      break;
+    default:
+      bDestroyPDFWindow = false;
+      break;
+  }
+  EscapeFiller(pPageView, bDestroyPDFWindow);
+}
+
+bool CFFL_FormFiller::IsValid() const {
+  return m_bValid;
+}
+
+PWL_CREATEPARAM CFFL_FormFiller::GetCreateParam() {
+  ASSERT(m_pFormFillEnv);
+
+  PWL_CREATEPARAM cp;
+  cp.pParentWnd = nullptr;
+  cp.pProvider.Reset(this);
+  cp.rcRectWnd = GetPDFWindowRect();
+
+  uint32_t dwCreateFlags = PWS_BORDER | PWS_BACKGROUND | PWS_VISIBLE;
+  uint32_t dwFieldFlag = m_pWidget->GetFieldFlags();
+  if (dwFieldFlag & FIELDFLAG_READONLY) {
+    dwCreateFlags |= PWS_READONLY;
+  }
+
+  FX_COLORREF color;
+  if (m_pWidget->GetFillColor(color)) {
+    cp.sBackgroundColor =
+        CPWL_Color(GetRed(color), GetGreen(color), GetBlue(color));
+  }
+
+  if (m_pWidget->GetBorderColor(color)) {
+    cp.sBorderColor =
+        CPWL_Color(GetRed(color), GetGreen(color), GetBlue(color));
+  }
+
+  cp.sTextColor = CPWL_Color(COLORTYPE_GRAY, 0);
+
+  if (m_pWidget->GetTextColor(color)) {
+    cp.sTextColor = CPWL_Color(GetRed(color), GetGreen(color), GetBlue(color));
+  }
+
+  cp.fFontSize = m_pWidget->GetFontSize();
+  cp.dwBorderWidth = m_pWidget->GetBorderWidth();
+
+  cp.nBorderStyle = m_pWidget->GetBorderStyle();
+  switch (cp.nBorderStyle) {
+    case BorderStyle::DASH:
+      cp.sDash = CPWL_Dash(3, 3, 0);
+      break;
+    case BorderStyle::BEVELED:
+      cp.dwBorderWidth *= 2;
+      break;
+    case BorderStyle::INSET:
+      cp.dwBorderWidth *= 2;
+      break;
+    default:
+      break;
+  }
+
+  if (cp.fFontSize <= 0)
+    dwCreateFlags |= PWS_AUTOFONTSIZE;
+
+  cp.dwFlags = dwCreateFlags;
+  cp.pSystemHandler = m_pFormFillEnv->GetSysHandler();
+  return cp;
+}
+
+CPWL_Wnd* CFFL_FormFiller::GetPDFWindow(CPDFSDK_PageView* pPageView,
+                                        bool bNew) {
+  ASSERT(pPageView);
+
+  auto it = m_Maps.find(pPageView);
+  const bool found = it != m_Maps.end();
+  CPWL_Wnd* pWnd = found ? it->second : nullptr;
+  if (!bNew)
+    return pWnd;
+
+  if (found) {
+    CFFL_PrivateData* pPrivateData = (CFFL_PrivateData*)pWnd->GetAttachedData();
+    if (pPrivateData->nWidgetAge != m_pWidget->GetAppearanceAge()) {
+      return ResetPDFWindow(
+          pPageView, m_pWidget->GetValueAge() == pPrivateData->nValueAge);
+    }
+  } else {
+    PWL_CREATEPARAM cp = GetCreateParam();
+    cp.pAttachedWidget.Reset(m_pWidget);
+
+    CFFL_PrivateData* pPrivateData = new CFFL_PrivateData;
+    pPrivateData->pWidget = m_pWidget;
+    pPrivateData->pPageView = pPageView;
+    pPrivateData->nWidgetAge = m_pWidget->GetAppearanceAge();
+    pPrivateData->nValueAge = 0;
+
+    cp.pAttachedData = pPrivateData;
+
+    pWnd = NewPDFWindow(cp, pPageView);
+    m_Maps[pPageView] = pWnd;
+  }
+
+  return pWnd;
+}
+
+void CFFL_FormFiller::DestroyPDFWindow(CPDFSDK_PageView* pPageView) {
+  auto it = m_Maps.find(pPageView);
+  if (it == m_Maps.end())
+    return;
+
+  CPWL_Wnd* pWnd = it->second;
+  CFFL_PrivateData* pData = (CFFL_PrivateData*)pWnd->GetAttachedData();
+  pWnd->Destroy();
+  delete pWnd;
+  delete pData;
+
+  m_Maps.erase(it);
+}
+
+CFX_Matrix CFFL_FormFiller::GetWindowMatrix(void* pAttachedData) {
+  if (CFFL_PrivateData* pPrivateData = (CFFL_PrivateData*)pAttachedData) {
+    if (pPrivateData->pPageView) {
+      CFX_Matrix mtPageView;
+      pPrivateData->pPageView->GetCurrentMatrix(mtPageView);
+      CFX_Matrix mt = GetCurMatrix();
+      mt.Concat(mtPageView);
+
+      return mt;
+    }
+  }
+  return CFX_Matrix(1, 0, 0, 1, 0, 0);
+}
+
+CFX_Matrix CFFL_FormFiller::GetCurMatrix() {
+  CFX_Matrix mt;
+
+  CFX_FloatRect rcDA = m_pWidget->GetPDFAnnot()->GetRect();
+
+  switch (m_pWidget->GetRotate()) {
+    default:
+    case 0:
+      mt = CFX_Matrix(1, 0, 0, 1, 0, 0);
+      break;
+    case 90:
+      mt = CFX_Matrix(0, 1, -1, 0, rcDA.right - rcDA.left, 0);
+      break;
+    case 180:
+      mt = CFX_Matrix(-1, 0, 0, -1, rcDA.right - rcDA.left,
+                      rcDA.top - rcDA.bottom);
+      break;
+    case 270:
+      mt = CFX_Matrix(0, -1, 1, 0, 0, rcDA.top - rcDA.bottom);
+      break;
+  }
+  mt.e += rcDA.left;
+  mt.f += rcDA.bottom;
+
+  return mt;
+}
+
+CFX_WideString CFFL_FormFiller::LoadPopupMenuString(int nIndex) {
+  ASSERT(m_pFormFillEnv);
+
+  return L"";
+}
+
+CFX_FloatRect CFFL_FormFiller::GetPDFWindowRect() const {
+  CFX_FloatRect rectAnnot = m_pWidget->GetPDFAnnot()->GetRect();
+
+  FX_FLOAT fWidth = rectAnnot.right - rectAnnot.left;
+  FX_FLOAT fHeight = rectAnnot.top - rectAnnot.bottom;
+  if ((m_pWidget->GetRotate() / 90) & 0x01)
+    return CFX_FloatRect(0, 0, fHeight, fWidth);
+
+  return CFX_FloatRect(0, 0, fWidth, fHeight);
+}
+
+CPDFSDK_PageView* CFFL_FormFiller::GetCurPageView(bool renew) {
+  UnderlyingPageType* pPage = m_pAnnot->GetUnderlyingPage();
+  return m_pFormFillEnv ? m_pFormFillEnv->GetPageView(pPage, renew) : nullptr;
+}
+
+CFX_FloatRect CFFL_FormFiller::GetFocusBox(CPDFSDK_PageView* pPageView) {
+  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, false)) {
+    CFX_FloatRect rcFocus = FFLtoWnd(pPageView, PWLtoFFL(pWnd->GetFocusRect()));
+    CFX_FloatRect rcPage = pPageView->GetPDFPage()->GetPageBBox();
+    if (rcPage.Contains(rcFocus))
+      return rcFocus;
+  }
+  return CFX_FloatRect(0, 0, 0, 0);
+}
+
+CFX_FloatRect CFFL_FormFiller::FFLtoPWL(const CFX_FloatRect& rect) {
+  CFX_Matrix mt;
+  mt.SetReverse(GetCurMatrix());
+
+  CFX_FloatRect temp = rect;
+  mt.TransformRect(temp);
+
+  return temp;
+}
+
+CFX_FloatRect CFFL_FormFiller::PWLtoFFL(const CFX_FloatRect& rect) {
+  CFX_Matrix mt = GetCurMatrix();
+
+  CFX_FloatRect temp = rect;
+  mt.TransformRect(temp);
+
+  return temp;
+}
+
+CFX_FloatPoint CFFL_FormFiller::FFLtoPWL(const CFX_FloatPoint& point) {
+  CFX_Matrix mt;
+  mt.SetReverse(GetCurMatrix());
+
+  CFX_FloatPoint pt = point;
+  mt.Transform(pt.x, pt.y);
+
+  return pt;
+}
+
+CFX_FloatPoint CFFL_FormFiller::PWLtoFFL(const CFX_FloatPoint& point) {
+  CFX_Matrix mt = GetCurMatrix();
+
+  CFX_FloatPoint pt = point;
+  mt.Transform(pt.x, pt.y);
+
+  return pt;
+}
+
+CFX_FloatPoint CFFL_FormFiller::WndtoPWL(CPDFSDK_PageView* pPageView,
+                                         const CFX_FloatPoint& pt) {
+  return FFLtoPWL(pt);
+}
+
+CFX_FloatRect CFFL_FormFiller::FFLtoWnd(CPDFSDK_PageView* pPageView,
+                                        const CFX_FloatRect& rect) {
+  return rect;
+}
+
+bool CFFL_FormFiller::CommitData(CPDFSDK_PageView* pPageView, uint32_t nFlag) {
+  if (IsDataChanged(pPageView)) {
+    bool bRC = true;
+    bool bExit = false;
+    CFFL_InteractiveFormFiller* pFormFiller =
+        m_pFormFillEnv->GetInteractiveFormFiller();
+    CPDFSDK_Annot::ObservedPtr pObserved(m_pWidget);
+    pFormFiller->OnKeyStrokeCommit(&pObserved, pPageView, bRC, bExit, nFlag);
+    if (!pObserved || bExit)
+      return true;
+    if (!bRC) {
+      ResetPDFWindow(pPageView, false);
+      return true;
+    }
+    pFormFiller->OnValidate(&pObserved, pPageView, bRC, bExit, nFlag);
+    if (!pObserved || bExit)
+      return true;
+    if (!bRC) {
+      ResetPDFWindow(pPageView, false);
+      return true;
+    }
+    SaveData(pPageView);
+    pFormFiller->OnCalculate(m_pWidget, pPageView, bExit, nFlag);
+    if (bExit)
+      return true;
+
+    pFormFiller->OnFormat(m_pWidget, pPageView, bExit, nFlag);
+  }
+  return true;
+}
+
+bool CFFL_FormFiller::IsDataChanged(CPDFSDK_PageView* pPageView) {
+  return false;
+}
+
+void CFFL_FormFiller::SaveData(CPDFSDK_PageView* pPageView) {}
+
+#ifdef PDF_ENABLE_XFA
+bool CFFL_FormFiller::IsFieldFull(CPDFSDK_PageView* pPageView) {
+  return false;
+}
+#endif  // PDF_ENABLE_XFA
+
+void CFFL_FormFiller::SetChangeMark() {
+  m_pFormFillEnv->OnChange();
+}
+
+void CFFL_FormFiller::GetActionData(CPDFSDK_PageView* pPageView,
+                                    CPDF_AAction::AActionType type,
+                                    PDFSDK_FieldAction& fa) {
+  fa.sValue = m_pWidget->GetValue();
+}
+
+void CFFL_FormFiller::SetActionData(CPDFSDK_PageView* pPageView,
+                                    CPDF_AAction::AActionType type,
+                                    const PDFSDK_FieldAction& fa) {}
+
+bool CFFL_FormFiller::IsActionDataChanged(CPDF_AAction::AActionType type,
+                                          const PDFSDK_FieldAction& faOld,
+                                          const PDFSDK_FieldAction& faNew) {
+  return false;
+}
+
+void CFFL_FormFiller::SaveState(CPDFSDK_PageView* pPageView) {}
+
+void CFFL_FormFiller::RestoreState(CPDFSDK_PageView* pPageView) {}
+
+CPWL_Wnd* CFFL_FormFiller::ResetPDFWindow(CPDFSDK_PageView* pPageView,
+                                          bool bRestoreValue) {
+  return GetPDFWindow(pPageView, false);
+}
+
+void CFFL_FormFiller::TimerProc() {}
+
+CFX_SystemHandler* CFFL_FormFiller::GetSystemHandler() const {
+  return m_pFormFillEnv->GetSysHandler();
+}
+
+void CFFL_FormFiller::EscapeFiller(CPDFSDK_PageView* pPageView,
+                                   bool bDestroyPDFWindow) {
+  m_bValid = false;
+
+  FX_RECT rcRect = GetViewBBox(pPageView, m_pWidget);
+  InvalidateRect(rcRect.left, rcRect.top, rcRect.right, rcRect.bottom);
+
+  if (bDestroyPDFWindow)
+    DestroyPDFWindow(pPageView);
+}
+
+void CFFL_FormFiller::InvalidateRect(double left,
+                                     double top,
+                                     double right,
+                                     double bottom) {
+  UnderlyingPageType* pPage = m_pWidget->GetUnderlyingPage();
+  m_pFormFillEnv->Invalidate(pPage, left, top, right, bottom);
+}
+
+CFFL_Button::CFFL_Button(CPDFSDK_FormFillEnvironment* pApp,
+                         CPDFSDK_Annot* pWidget)
+    : CFFL_FormFiller(pApp, pWidget), m_bMouseIn(false), m_bMouseDown(false) {}
+
+CFFL_Button::~CFFL_Button() {}
+
+void CFFL_Button::OnMouseEnter(CPDFSDK_PageView* pPageView,
+                               CPDFSDK_Annot* pAnnot) {
+  m_bMouseIn = true;
+  FX_RECT rect = GetViewBBox(pPageView, pAnnot);
+  InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
+}
+
+void CFFL_Button::OnMouseExit(CPDFSDK_PageView* pPageView,
+                              CPDFSDK_Annot* pAnnot) {
+  m_bMouseIn = false;
+
+  FX_RECT rect = GetViewBBox(pPageView, pAnnot);
+  InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
+  EndTimer();
+  ASSERT(m_pWidget);
+}
+
+bool CFFL_Button::OnLButtonDown(CPDFSDK_PageView* pPageView,
+                                CPDFSDK_Annot* pAnnot,
+                                uint32_t nFlags,
+                                const CFX_FloatPoint& point) {
+  CFX_FloatRect rcAnnot = pAnnot->GetRect();
+  if (!rcAnnot.Contains(point.x, point.y))
+    return false;
+
+  m_bMouseDown = true;
+  m_bValid = true;
+  FX_RECT rect = GetViewBBox(pPageView, pAnnot);
+  InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
+  return true;
+}
+
+bool CFFL_Button::OnLButtonUp(CPDFSDK_PageView* pPageView,
+                              CPDFSDK_Annot* pAnnot,
+                              uint32_t nFlags,
+                              const CFX_FloatPoint& point) {
+  CFX_FloatRect rcAnnot = pAnnot->GetRect();
+  if (!rcAnnot.Contains(point.x, point.y))
+    return false;
+
+  m_bMouseDown = false;
+  m_pWidget->GetPDFPage();
+
+  FX_RECT rect = GetViewBBox(pPageView, pAnnot);
+  InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
+  return true;
+}
+
+bool CFFL_Button::OnMouseMove(CPDFSDK_PageView* pPageView,
+                              CPDFSDK_Annot* pAnnot,
+                              uint32_t nFlags,
+                              const CFX_FloatPoint& point) {
+  ASSERT(m_pFormFillEnv);
+
+  return true;
+}
+
+void CFFL_Button::OnDraw(CPDFSDK_PageView* pPageView,
+                         CPDFSDK_Annot* pAnnot,
+                         CFX_RenderDevice* pDevice,
+                         CFX_Matrix* pUser2Device) {
+  ASSERT(pPageView);
+  CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
+  CPDF_FormControl* pCtrl = pWidget->GetFormControl();
+  CPDF_FormControl::HighlightingMode eHM = pCtrl->GetHighlightingMode();
+
+  if (eHM != CPDF_FormControl::Push) {
+    pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, nullptr);
+    return;
+  }
+
+  if (m_bMouseDown) {
+    if (pWidget->IsWidgetAppearanceValid(CPDF_Annot::Down))
+      pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Down, nullptr);
+    else
+      pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal,
+                              nullptr);
+  } else if (m_bMouseIn) {
+    if (pWidget->IsWidgetAppearanceValid(CPDF_Annot::Rollover))
+      pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Rollover,
+                              nullptr);
+    else
+      pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal,
+                              nullptr);
+  } else {
+    pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, nullptr);
+  }
+}
+
+void CFFL_Button::OnDrawDeactive(CPDFSDK_PageView* pPageView,
+                                 CPDFSDK_Annot* pAnnot,
+                                 CFX_RenderDevice* pDevice,
+                                 CFX_Matrix* pUser2Device) {
+  OnDraw(pPageView, pAnnot, pDevice, pUser2Device);
+}
diff --git a/fpdfsdk/formfiller/cffl_formfiller.h b/fpdfsdk/formfiller/cffl_formfiller.h
new file mode 100644
index 0000000..cf1aaf7
--- /dev/null
+++ b/fpdfsdk/formfiller/cffl_formfiller.h
@@ -0,0 +1,204 @@
+// 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_FORMFILLER_CFFL_FORMFILLER_H_
+#define FPDFSDK_FORMFILLER_CFFL_FORMFILLER_H_
+
+#include <map>
+
+#include "fpdfsdk/formfiller/cba_fontmap.h"
+#include "fpdfsdk/formfiller/cffl_interactiveformfiller.h"
+#include "fpdfsdk/pdfsdk_fieldaction.h"
+
+class CPDFSDK_Annot;
+class CPDFSDK_FormFillEnvironment;
+class CPDFSDK_PageView;
+class CPDFSDK_Widget;
+
+class CFFL_FormFiller : public IPWL_Provider, public CPWL_TimerHandler {
+ public:
+  CFFL_FormFiller(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                  CPDFSDK_Annot* pAnnot);
+  ~CFFL_FormFiller() override;
+
+  virtual FX_RECT GetViewBBox(CPDFSDK_PageView* pPageView,
+                              CPDFSDK_Annot* pAnnot);
+  virtual void OnDraw(CPDFSDK_PageView* pPageView,
+                      CPDFSDK_Annot* pAnnot,
+                      CFX_RenderDevice* pDevice,
+                      CFX_Matrix* pUser2Device);
+  virtual void OnDrawDeactive(CPDFSDK_PageView* pPageView,
+                              CPDFSDK_Annot* pAnnot,
+                              CFX_RenderDevice* pDevice,
+                              CFX_Matrix* pUser2Device);
+
+  virtual void OnMouseEnter(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot);
+  virtual void OnMouseExit(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot);
+
+  virtual bool OnLButtonDown(CPDFSDK_PageView* pPageView,
+                             CPDFSDK_Annot* pAnnot,
+                             uint32_t nFlags,
+                             const CFX_FloatPoint& point);
+  virtual bool OnLButtonUp(CPDFSDK_PageView* pPageView,
+                           CPDFSDK_Annot* pAnnot,
+                           uint32_t nFlags,
+                           const CFX_FloatPoint& point);
+  virtual bool OnLButtonDblClk(CPDFSDK_PageView* pPageView,
+                               CPDFSDK_Annot* pAnnot,
+                               uint32_t nFlags,
+                               const CFX_FloatPoint& point);
+  virtual bool OnMouseMove(CPDFSDK_PageView* pPageView,
+                           CPDFSDK_Annot* pAnnot,
+                           uint32_t nFlags,
+                           const CFX_FloatPoint& point);
+  virtual bool OnMouseWheel(CPDFSDK_PageView* pPageView,
+                            CPDFSDK_Annot* pAnnot,
+                            uint32_t nFlags,
+                            short zDelta,
+                            const CFX_FloatPoint& point);
+  virtual bool OnRButtonDown(CPDFSDK_PageView* pPageView,
+                             CPDFSDK_Annot* pAnnot,
+                             uint32_t nFlags,
+                             const CFX_FloatPoint& point);
+  virtual bool OnRButtonUp(CPDFSDK_PageView* pPageView,
+                           CPDFSDK_Annot* pAnnot,
+                           uint32_t nFlags,
+                           const CFX_FloatPoint& point);
+
+  virtual bool OnKeyDown(CPDFSDK_Annot* pAnnot,
+                         uint32_t nKeyCode,
+                         uint32_t nFlags);
+  virtual bool OnChar(CPDFSDK_Annot* pAnnot, uint32_t nChar, uint32_t nFlags);
+
+  void SetFocusForAnnot(CPDFSDK_Annot* pAnnot, uint32_t nFlag);
+  void KillFocusForAnnot(CPDFSDK_Annot* pAnnot, uint32_t nFlag);
+
+  // CPWL_TimerHandler
+  void TimerProc() override;
+  CFX_SystemHandler* GetSystemHandler() const override;
+
+  // IPWL_Provider
+  CFX_Matrix GetWindowMatrix(void* pAttachedData) override;
+  CFX_WideString LoadPopupMenuString(int nIndex) override;
+
+  virtual void GetActionData(CPDFSDK_PageView* pPageView,
+                             CPDF_AAction::AActionType type,
+                             PDFSDK_FieldAction& fa);
+  virtual void SetActionData(CPDFSDK_PageView* pPageView,
+                             CPDF_AAction::AActionType type,
+                             const PDFSDK_FieldAction& fa);
+  virtual bool IsActionDataChanged(CPDF_AAction::AActionType type,
+                                   const PDFSDK_FieldAction& faOld,
+                                   const PDFSDK_FieldAction& faNew);
+
+  virtual void SaveState(CPDFSDK_PageView* pPageView);
+  virtual void RestoreState(CPDFSDK_PageView* pPageView);
+
+  virtual CPWL_Wnd* ResetPDFWindow(CPDFSDK_PageView* pPageView,
+                                   bool bRestoreValue);
+
+  CFX_Matrix GetCurMatrix();
+
+  CFX_FloatRect FFLtoPWL(const CFX_FloatRect& rect);
+  CFX_FloatRect PWLtoFFL(const CFX_FloatRect& rect);
+  CFX_FloatPoint FFLtoPWL(const CFX_FloatPoint& point);
+  CFX_FloatPoint PWLtoFFL(const CFX_FloatPoint& point);
+
+  CFX_FloatPoint WndtoPWL(CPDFSDK_PageView* pPageView,
+                          const CFX_FloatPoint& pt);
+  CFX_FloatRect FFLtoWnd(CPDFSDK_PageView* pPageView,
+                         const CFX_FloatRect& rect);
+
+  void SetWindowRect(CPDFSDK_PageView* pPageView,
+                     const CFX_FloatRect& rcWindow);
+  CFX_FloatRect GetWindowRect(CPDFSDK_PageView* pPageView);
+
+  bool CommitData(CPDFSDK_PageView* pPageView, uint32_t nFlag);
+  virtual bool IsDataChanged(CPDFSDK_PageView* pPageView);
+  virtual void SaveData(CPDFSDK_PageView* pPageView);
+
+#ifdef PDF_ENABLE_XFA
+  virtual bool IsFieldFull(CPDFSDK_PageView* pPageView);
+#endif  // PDF_ENABLE_XFA
+
+  CPWL_Wnd* GetPDFWindow(CPDFSDK_PageView* pPageView, bool bNew);
+  void DestroyPDFWindow(CPDFSDK_PageView* pPageView);
+  void EscapeFiller(CPDFSDK_PageView* pPageView, bool bDestroyPDFWindow);
+
+  virtual PWL_CREATEPARAM GetCreateParam();
+  virtual CPWL_Wnd* NewPDFWindow(const PWL_CREATEPARAM& cp,
+                                 CPDFSDK_PageView* pPageView) = 0;
+  virtual CFX_FloatRect GetFocusBox(CPDFSDK_PageView* pPageView);
+
+  bool IsValid() const;
+  CFX_FloatRect GetPDFWindowRect() const;
+
+  CPDFSDK_PageView* GetCurPageView(bool renew);
+  void SetChangeMark();
+
+  virtual void InvalidateRect(double left,
+                              double top,
+                              double right,
+                              double bottom);
+  CPDFSDK_Annot* GetSDKAnnot() { return m_pAnnot; }
+
+ protected:
+  using CFFL_PageView2PDFWindow = std::map<CPDFSDK_PageView*, CPWL_Wnd*>;
+
+  // If the inheriting widget has its own fontmap and a PWL_Edit widget that
+  // access that fontmap then you have to call DestroyWindows before destroying
+  // the font map in order to not get a use-after-free.
+  //
+  // The font map should be stored somewhere more appropriate so it will live
+  // until the PWL_Edit is done with it. pdfium:566
+  void DestroyWindows();
+
+  CPDFSDK_FormFillEnvironment* m_pFormFillEnv;
+  CPDFSDK_Widget* m_pWidget;
+  CPDFSDK_Annot* m_pAnnot;
+
+  bool m_bValid;
+  CFFL_PageView2PDFWindow m_Maps;
+  CFX_FloatPoint m_ptOldPos;
+};
+
+class CFFL_Button : public CFFL_FormFiller {
+ public:
+  CFFL_Button(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+              CPDFSDK_Annot* pWidget);
+  ~CFFL_Button() override;
+
+  // CFFL_FormFiller
+  void OnMouseEnter(CPDFSDK_PageView* pPageView,
+                    CPDFSDK_Annot* pAnnot) override;
+  void OnMouseExit(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot) override;
+  bool OnLButtonDown(CPDFSDK_PageView* pPageView,
+                     CPDFSDK_Annot* pAnnot,
+                     uint32_t nFlags,
+                     const CFX_FloatPoint& point) override;
+  bool OnLButtonUp(CPDFSDK_PageView* pPageView,
+                   CPDFSDK_Annot* pAnnot,
+                   uint32_t nFlags,
+                   const CFX_FloatPoint& point) override;
+  bool OnMouseMove(CPDFSDK_PageView* pPageView,
+                   CPDFSDK_Annot* pAnnot,
+                   uint32_t nFlags,
+                   const CFX_FloatPoint& point) override;
+  void OnDraw(CPDFSDK_PageView* pPageView,
+              CPDFSDK_Annot* pAnnot,
+              CFX_RenderDevice* pDevice,
+              CFX_Matrix* pUser2Device) override;
+  void OnDrawDeactive(CPDFSDK_PageView* pPageView,
+                      CPDFSDK_Annot* pAnnot,
+                      CFX_RenderDevice* pDevice,
+                      CFX_Matrix* pUser2Device) override;
+
+ protected:
+  bool m_bMouseIn;
+  bool m_bMouseDown;
+};
+
+#endif  // FPDFSDK_FORMFILLER_CFFL_FORMFILLER_H_
diff --git a/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp b/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp
new file mode 100644
index 0000000..01009d2
--- /dev/null
+++ b/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp
@@ -0,0 +1,965 @@
+// 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
+
+#include "fpdfsdk/formfiller/cffl_interactiveformfiller.h"
+
+#include "core/fpdfapi/page/cpdf_page.h"
+#include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fxge/cfx_graphstatedata.h"
+#include "core/fxge/cfx_pathdata.h"
+#include "core/fxge/cfx_renderdevice.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/cpdfsdk_interform.h"
+#include "fpdfsdk/cpdfsdk_pageview.h"
+#include "fpdfsdk/cpdfsdk_widget.h"
+#include "fpdfsdk/formfiller/cffl_checkbox.h"
+#include "fpdfsdk/formfiller/cffl_combobox.h"
+#include "fpdfsdk/formfiller/cffl_formfiller.h"
+#include "fpdfsdk/formfiller/cffl_listbox.h"
+#include "fpdfsdk/formfiller/cffl_pushbutton.h"
+#include "fpdfsdk/formfiller/cffl_radiobutton.h"
+#include "fpdfsdk/formfiller/cffl_textfield.h"
+#include "fpdfsdk/pdfwindow/PWL_Utils.h"
+
+#define FFL_MAXLISTBOXHEIGHT 140.0f
+
+CFFL_InteractiveFormFiller::CFFL_InteractiveFormFiller(
+    CPDFSDK_FormFillEnvironment* pFormFillEnv)
+    : m_pFormFillEnv(pFormFillEnv), m_bNotifying(false) {}
+
+CFFL_InteractiveFormFiller::~CFFL_InteractiveFormFiller() {}
+
+bool CFFL_InteractiveFormFiller::Annot_HitTest(CPDFSDK_PageView* pPageView,
+                                               CPDFSDK_Annot* pAnnot,
+                                               CFX_FloatPoint point) {
+  CFX_FloatRect rc = pAnnot->GetRect();
+  return rc.Contains(point.x, point.y);
+}
+
+FX_RECT CFFL_InteractiveFormFiller::GetViewBBox(CPDFSDK_PageView* pPageView,
+                                                CPDFSDK_Annot* pAnnot) {
+  if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, false))
+    return pFormFiller->GetViewBBox(pPageView, pAnnot);
+
+  ASSERT(pPageView);
+
+  CPDF_Annot* pPDFAnnot = pAnnot->GetPDFAnnot();
+  CFX_FloatRect rcWin = CPWL_Utils::InflateRect(pPDFAnnot->GetRect(), 1);
+  return rcWin.GetOuterRect();
+}
+
+void CFFL_InteractiveFormFiller::OnDraw(CPDFSDK_PageView* pPageView,
+                                        CPDFSDK_Annot* pAnnot,
+                                        CFX_RenderDevice* pDevice,
+                                        CFX_Matrix* pUser2Device) {
+  ASSERT(pPageView);
+  CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
+
+  if (!IsVisible(pWidget))
+    return;
+
+  if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, false)) {
+    if (pFormFiller->IsValid()) {
+      pFormFiller->OnDraw(pPageView, pAnnot, pDevice, pUser2Device);
+      pAnnot->GetPDFPage();
+
+      if (m_pFormFillEnv->GetFocusAnnot() == pAnnot) {
+        CFX_FloatRect rcFocus = pFormFiller->GetFocusBox(pPageView);
+        if (!rcFocus.IsEmpty()) {
+          CFX_PathData path;
+          path.SetPointCount(5);
+          path.SetPoint(0, rcFocus.left, rcFocus.top, FXPT_MOVETO);
+          path.SetPoint(1, rcFocus.left, rcFocus.bottom, FXPT_LINETO);
+          path.SetPoint(2, rcFocus.right, rcFocus.bottom, FXPT_LINETO);
+          path.SetPoint(3, rcFocus.right, rcFocus.top, FXPT_LINETO);
+          path.SetPoint(4, rcFocus.left, rcFocus.top, FXPT_LINETO);
+
+          CFX_GraphStateData gsd;
+          gsd.SetDashCount(1);
+          gsd.m_DashArray[0] = 1.0f;
+          gsd.m_DashPhase = 0;
+          gsd.m_LineWidth = 1.0f;
+          pDevice->DrawPath(&path, pUser2Device, &gsd, 0,
+                            ArgbEncode(255, 0, 0, 0), FXFILL_ALTERNATE);
+        }
+      }
+      return;
+    }
+  }
+
+  if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, false)) {
+    pFormFiller->OnDrawDeactive(pPageView, pAnnot, pDevice, pUser2Device);
+  } else {
+    pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, nullptr);
+  }
+
+  if (!IsReadOnly(pWidget) && IsFillingAllowed(pWidget))
+    pWidget->DrawShadow(pDevice, pPageView);
+}
+
+void CFFL_InteractiveFormFiller::OnDelete(CPDFSDK_Annot* pAnnot) {
+  UnRegisterFormFiller(pAnnot);
+}
+
+void CFFL_InteractiveFormFiller::OnMouseEnter(
+    CPDFSDK_PageView* pPageView,
+    CPDFSDK_Annot::ObservedPtr* pAnnot,
+    uint32_t nFlag) {
+  ASSERT((*pAnnot)->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
+  if (!m_bNotifying) {
+    CPDFSDK_Widget* pWidget = static_cast<CPDFSDK_Widget*>(pAnnot->Get());
+    if (pWidget->GetAAction(CPDF_AAction::CursorEnter).GetDict()) {
+      m_bNotifying = true;
+
+      int nValueAge = pWidget->GetValueAge();
+      pWidget->ClearAppModified();
+      ASSERT(pPageView);
+
+      PDFSDK_FieldAction fa;
+      fa.bModifier = m_pFormFillEnv->IsCTRLKeyDown(nFlag);
+      fa.bShift = m_pFormFillEnv->IsSHIFTKeyDown(nFlag);
+      pWidget->OnAAction(CPDF_AAction::CursorEnter, fa, pPageView);
+      m_bNotifying = false;
+      if (!(*pAnnot))
+        return;
+
+      if (pWidget->IsAppModified()) {
+        if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, false)) {
+          pFormFiller->ResetPDFWindow(pPageView,
+                                      pWidget->GetValueAge() == nValueAge);
+        }
+      }
+    }
+  }
+  if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot->Get(), true))
+    pFormFiller->OnMouseEnter(pPageView, pAnnot->Get());
+}
+
+void CFFL_InteractiveFormFiller::OnMouseExit(CPDFSDK_PageView* pPageView,
+                                             CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                             uint32_t nFlag) {
+  ASSERT((*pAnnot)->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
+  if (!m_bNotifying) {
+    CPDFSDK_Widget* pWidget = static_cast<CPDFSDK_Widget*>(pAnnot->Get());
+    if (pWidget->GetAAction(CPDF_AAction::CursorExit).GetDict()) {
+      m_bNotifying = true;
+      pWidget->GetAppearanceAge();
+
+      int nValueAge = pWidget->GetValueAge();
+      pWidget->ClearAppModified();
+      ASSERT(pPageView);
+
+      PDFSDK_FieldAction fa;
+      fa.bModifier = m_pFormFillEnv->IsCTRLKeyDown(nFlag);
+      fa.bShift = m_pFormFillEnv->IsSHIFTKeyDown(nFlag);
+      pWidget->OnAAction(CPDF_AAction::CursorExit, fa, pPageView);
+      m_bNotifying = false;
+      if (!(*pAnnot))
+        return;
+
+      if (pWidget->IsAppModified()) {
+        if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, false)) {
+          pFormFiller->ResetPDFWindow(pPageView,
+                                      nValueAge == pWidget->GetValueAge());
+        }
+      }
+    }
+  }
+  if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot->Get(), false))
+    pFormFiller->OnMouseExit(pPageView, pAnnot->Get());
+}
+
+bool CFFL_InteractiveFormFiller::OnLButtonDown(
+    CPDFSDK_PageView* pPageView,
+    CPDFSDK_Annot::ObservedPtr* pAnnot,
+    uint32_t nFlags,
+    const CFX_FloatPoint& point) {
+  ASSERT((*pAnnot)->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
+  if (!m_bNotifying) {
+    CPDFSDK_Widget* pWidget = static_cast<CPDFSDK_Widget*>(pAnnot->Get());
+    if (Annot_HitTest(pPageView, pAnnot->Get(), point) &&
+        pWidget->GetAAction(CPDF_AAction::ButtonDown).GetDict()) {
+      m_bNotifying = true;
+      pWidget->GetAppearanceAge();
+
+      int nValueAge = pWidget->GetValueAge();
+      pWidget->ClearAppModified();
+      ASSERT(pPageView);
+
+      PDFSDK_FieldAction fa;
+      fa.bModifier = m_pFormFillEnv->IsCTRLKeyDown(nFlags);
+      fa.bShift = m_pFormFillEnv->IsSHIFTKeyDown(nFlags);
+      pWidget->OnAAction(CPDF_AAction::ButtonDown, fa, pPageView);
+      m_bNotifying = false;
+      if (!(*pAnnot))
+        return true;
+
+      if (!IsValidAnnot(pPageView, pAnnot->Get()))
+        return true;
+
+      if (pWidget->IsAppModified()) {
+        if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, false)) {
+          pFormFiller->ResetPDFWindow(pPageView,
+                                      nValueAge == pWidget->GetValueAge());
+        }
+      }
+    }
+  }
+  if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot->Get(), false))
+    return pFormFiller->OnLButtonDown(pPageView, pAnnot->Get(), nFlags, point);
+
+  return false;
+}
+
+bool CFFL_InteractiveFormFiller::OnLButtonUp(CPDFSDK_PageView* pPageView,
+                                             CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                             uint32_t nFlags,
+                                             const CFX_FloatPoint& point) {
+  ASSERT((*pAnnot)->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
+  CPDFSDK_Widget* pWidget = static_cast<CPDFSDK_Widget*>(pAnnot->Get());
+
+  switch (pWidget->GetFieldType()) {
+    case FIELDTYPE_PUSHBUTTON:
+    case FIELDTYPE_CHECKBOX:
+    case FIELDTYPE_RADIOBUTTON:
+      if (GetViewBBox(pPageView, pAnnot->Get())
+              .Contains((int)point.x, (int)point.y))
+        m_pFormFillEnv->SetFocusAnnot(pAnnot);
+      break;
+    default:
+      m_pFormFillEnv->SetFocusAnnot(pAnnot);
+      break;
+  }
+
+  bool bRet = false;
+  if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot->Get(), false))
+    bRet = pFormFiller->OnLButtonUp(pPageView, pAnnot->Get(), nFlags, point);
+
+  if (m_pFormFillEnv->GetFocusAnnot() == pAnnot->Get()) {
+    bool bExit = false;
+    bool bReset = false;
+    OnButtonUp(pAnnot, pPageView, bReset, bExit, nFlags);
+    if (!pAnnot || bExit)
+      return true;
+#ifdef PDF_ENABLE_XFA
+    OnClick(pWidget, pPageView, bReset, bExit, nFlags);
+    if (!pAnnot || bExit)
+      return true;
+#endif  // PDF_ENABLE_XFA
+  }
+  return bRet;
+}
+
+void CFFL_InteractiveFormFiller::OnButtonUp(CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                            CPDFSDK_PageView* pPageView,
+                                            bool& bReset,
+                                            bool& bExit,
+                                            uint32_t nFlag) {
+  if (!m_bNotifying) {
+    CPDFSDK_Widget* pWidget = static_cast<CPDFSDK_Widget*>(pAnnot->Get());
+    if (pWidget->GetAAction(CPDF_AAction::ButtonUp).GetDict()) {
+      m_bNotifying = true;
+
+      int nAge = pWidget->GetAppearanceAge();
+      int nValueAge = pWidget->GetValueAge();
+      ASSERT(pPageView);
+
+      PDFSDK_FieldAction fa;
+      fa.bModifier = m_pFormFillEnv->IsCTRLKeyDown(nFlag);
+      fa.bShift = m_pFormFillEnv->IsSHIFTKeyDown(nFlag);
+      pWidget->OnAAction(CPDF_AAction::ButtonUp, fa, pPageView);
+      m_bNotifying = false;
+      if (!(*pAnnot) || !IsValidAnnot(pPageView, pWidget)) {
+        bExit = true;
+        return;
+      }
+      if (nAge != pWidget->GetAppearanceAge()) {
+        if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, false)) {
+          pFormFiller->ResetPDFWindow(pPageView,
+                                      nValueAge == pWidget->GetValueAge());
+        }
+        bReset = true;
+      }
+    }
+  }
+}
+
+bool CFFL_InteractiveFormFiller::OnLButtonDblClk(
+    CPDFSDK_PageView* pPageView,
+    CPDFSDK_Annot::ObservedPtr* pAnnot,
+    uint32_t nFlags,
+    const CFX_FloatPoint& point) {
+  ASSERT((*pAnnot)->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
+  CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot->Get(), false);
+  return pFormFiller &&
+         pFormFiller->OnLButtonDblClk(pPageView, pAnnot->Get(), nFlags, point);
+}
+
+bool CFFL_InteractiveFormFiller::OnMouseMove(CPDFSDK_PageView* pPageView,
+                                             CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                             uint32_t nFlags,
+                                             const CFX_FloatPoint& point) {
+  ASSERT((*pAnnot)->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
+  CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot->Get(), true);
+  return pFormFiller &&
+         pFormFiller->OnMouseMove(pPageView, pAnnot->Get(), nFlags, point);
+}
+
+bool CFFL_InteractiveFormFiller::OnMouseWheel(
+    CPDFSDK_PageView* pPageView,
+    CPDFSDK_Annot::ObservedPtr* pAnnot,
+    uint32_t nFlags,
+    short zDelta,
+    const CFX_FloatPoint& point) {
+  ASSERT((*pAnnot)->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
+  CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot->Get(), false);
+  return pFormFiller &&
+         pFormFiller->OnMouseWheel(pPageView, pAnnot->Get(), nFlags, zDelta,
+                                   point);
+}
+
+bool CFFL_InteractiveFormFiller::OnRButtonDown(
+    CPDFSDK_PageView* pPageView,
+    CPDFSDK_Annot::ObservedPtr* pAnnot,
+    uint32_t nFlags,
+    const CFX_FloatPoint& point) {
+  ASSERT((*pAnnot)->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
+  CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot->Get(), false);
+  return pFormFiller &&
+         pFormFiller->OnRButtonDown(pPageView, pAnnot->Get(), nFlags, point);
+}
+
+bool CFFL_InteractiveFormFiller::OnRButtonUp(CPDFSDK_PageView* pPageView,
+                                             CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                             uint32_t nFlags,
+                                             const CFX_FloatPoint& point) {
+  ASSERT((*pAnnot)->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
+  CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot->Get(), false);
+  return pFormFiller &&
+         pFormFiller->OnRButtonUp(pPageView, pAnnot->Get(), nFlags, point);
+}
+
+bool CFFL_InteractiveFormFiller::OnKeyDown(CPDFSDK_Annot* pAnnot,
+                                           uint32_t nKeyCode,
+                                           uint32_t nFlags) {
+  ASSERT(pAnnot->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
+
+  if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, false)) {
+    return pFormFiller->OnKeyDown(pAnnot, nKeyCode, nFlags);
+  }
+
+  return false;
+}
+
+bool CFFL_InteractiveFormFiller::OnChar(CPDFSDK_Annot* pAnnot,
+                                        uint32_t nChar,
+                                        uint32_t nFlags) {
+  ASSERT(pAnnot->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
+  if (nChar == FWL_VKEY_Tab)
+    return true;
+
+  if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, false))
+    return pFormFiller->OnChar(pAnnot, nChar, nFlags);
+
+  return false;
+}
+
+bool CFFL_InteractiveFormFiller::OnSetFocus(CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                            uint32_t nFlag) {
+  if (!(*pAnnot))
+    return false;
+
+  ASSERT((*pAnnot)->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
+  if (!m_bNotifying) {
+    CPDFSDK_Widget* pWidget = static_cast<CPDFSDK_Widget*>(pAnnot->Get());
+    if (pWidget->GetAAction(CPDF_AAction::GetFocus).GetDict()) {
+      m_bNotifying = true;
+      pWidget->GetAppearanceAge();
+
+      int nValueAge = pWidget->GetValueAge();
+      pWidget->ClearAppModified();
+
+      CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, true);
+      if (!pFormFiller)
+        return false;
+
+      CPDFSDK_PageView* pPageView = (*pAnnot)->GetPageView();
+      ASSERT(pPageView);
+
+      PDFSDK_FieldAction fa;
+      fa.bModifier = m_pFormFillEnv->IsCTRLKeyDown(nFlag);
+      fa.bShift = m_pFormFillEnv->IsSHIFTKeyDown(nFlag);
+      pFormFiller->GetActionData(pPageView, CPDF_AAction::GetFocus, fa);
+      pWidget->OnAAction(CPDF_AAction::GetFocus, fa, pPageView);
+      m_bNotifying = false;
+      if (!(*pAnnot))
+        return false;
+
+      if (pWidget->IsAppModified()) {
+        if (CFFL_FormFiller* pFiller = GetFormFiller(pWidget, false)) {
+          pFiller->ResetPDFWindow(pPageView,
+                                  nValueAge == pWidget->GetValueAge());
+        }
+      }
+    }
+  }
+
+  if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot->Get(), true))
+    pFormFiller->SetFocusForAnnot(pAnnot->Get(), nFlag);
+
+  return true;
+}
+
+bool CFFL_InteractiveFormFiller::OnKillFocus(CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                             uint32_t nFlag) {
+  if (!(*pAnnot))
+    return false;
+
+  ASSERT((*pAnnot)->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
+  if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot->Get(), false)) {
+    pFormFiller->KillFocusForAnnot(pAnnot->Get(), nFlag);
+    if (!m_bNotifying) {
+      CPDFSDK_Widget* pWidget = static_cast<CPDFSDK_Widget*>(pAnnot->Get());
+      if (pWidget->GetAAction(CPDF_AAction::LoseFocus).GetDict()) {
+        m_bNotifying = true;
+        pWidget->ClearAppModified();
+
+        CPDFSDK_PageView* pPageView = pWidget->GetPageView();
+        ASSERT(pPageView);
+
+        PDFSDK_FieldAction fa;
+        fa.bModifier = m_pFormFillEnv->IsCTRLKeyDown(nFlag);
+        fa.bShift = m_pFormFillEnv->IsSHIFTKeyDown(nFlag);
+        pFormFiller->GetActionData(pPageView, CPDF_AAction::LoseFocus, fa);
+        pWidget->OnAAction(CPDF_AAction::LoseFocus, fa, pPageView);
+        m_bNotifying = false;
+        if (!(*pAnnot))
+          return false;
+      }
+    }
+  }
+  return true;
+}
+
+bool CFFL_InteractiveFormFiller::IsVisible(CPDFSDK_Widget* pWidget) {
+  return pWidget->IsVisible();
+}
+
+bool CFFL_InteractiveFormFiller::IsReadOnly(CPDFSDK_Widget* pWidget) {
+  int nFieldFlags = pWidget->GetFieldFlags();
+  return (nFieldFlags & FIELDFLAG_READONLY) == FIELDFLAG_READONLY;
+}
+
+bool CFFL_InteractiveFormFiller::IsFillingAllowed(CPDFSDK_Widget* pWidget) {
+  if (pWidget->GetFieldType() == FIELDTYPE_PUSHBUTTON)
+    return true;
+
+  CPDF_Page* pPage = pWidget->GetPDFPage();
+  CPDF_Document* pDocument = pPage->m_pDocument;
+  uint32_t dwPermissions = pDocument->GetUserPermissions();
+  return (dwPermissions & FPDFPERM_FILL_FORM) ||
+         (dwPermissions & FPDFPERM_ANNOT_FORM) ||
+         (dwPermissions & FPDFPERM_MODIFY);
+}
+
+CFFL_FormFiller* CFFL_InteractiveFormFiller::GetFormFiller(
+    CPDFSDK_Annot* pAnnot,
+    bool bRegister) {
+  auto it = m_Maps.find(pAnnot);
+  if (it != m_Maps.end())
+    return it->second.get();
+
+  if (!bRegister)
+    return nullptr;
+
+  CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
+  int nFieldType = pWidget->GetFieldType();
+  CFFL_FormFiller* pFormFiller;
+  switch (nFieldType) {
+    case FIELDTYPE_PUSHBUTTON:
+      pFormFiller = new CFFL_PushButton(m_pFormFillEnv, pWidget);
+      break;
+    case FIELDTYPE_CHECKBOX:
+      pFormFiller = new CFFL_CheckBox(m_pFormFillEnv, pWidget);
+      break;
+    case FIELDTYPE_RADIOBUTTON:
+      pFormFiller = new CFFL_RadioButton(m_pFormFillEnv, pWidget);
+      break;
+    case FIELDTYPE_TEXTFIELD:
+      pFormFiller = new CFFL_TextField(m_pFormFillEnv, pWidget);
+      break;
+    case FIELDTYPE_LISTBOX:
+      pFormFiller = new CFFL_ListBox(m_pFormFillEnv, pWidget);
+      break;
+    case FIELDTYPE_COMBOBOX:
+      pFormFiller = new CFFL_ComboBox(m_pFormFillEnv, pWidget);
+      break;
+    case FIELDTYPE_UNKNOWN:
+    default:
+      pFormFiller = nullptr;
+      break;
+  }
+
+  if (!pFormFiller)
+    return nullptr;
+
+  m_Maps[pAnnot].reset(pFormFiller);
+  return pFormFiller;
+}
+
+void CFFL_InteractiveFormFiller::RemoveFormFiller(CPDFSDK_Annot* pAnnot) {
+  if (pAnnot)
+    UnRegisterFormFiller(pAnnot);
+}
+
+void CFFL_InteractiveFormFiller::UnRegisterFormFiller(CPDFSDK_Annot* pAnnot) {
+  auto it = m_Maps.find(pAnnot);
+  if (it == m_Maps.end())
+    return;
+
+  m_Maps.erase(it);
+}
+
+void CFFL_InteractiveFormFiller::QueryWherePopup(void* pPrivateData,
+                                                 FX_FLOAT fPopupMin,
+                                                 FX_FLOAT fPopupMax,
+                                                 int32_t& nRet,
+                                                 FX_FLOAT& fPopupRet) {
+  CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
+
+  CFX_FloatRect rcPageView(0, 0, 0, 0);
+  rcPageView.right = pData->pWidget->GetPDFPage()->GetPageWidth();
+  rcPageView.bottom = pData->pWidget->GetPDFPage()->GetPageHeight();
+  rcPageView.Normalize();
+
+  CFX_FloatRect rcAnnot = pData->pWidget->GetRect();
+
+  FX_FLOAT fTop = 0.0f;
+  FX_FLOAT fBottom = 0.0f;
+
+  CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pData->pWidget;
+  switch (pWidget->GetRotate() / 90) {
+    default:
+    case 0:
+      fTop = rcPageView.top - rcAnnot.top;
+      fBottom = rcAnnot.bottom - rcPageView.bottom;
+      break;
+    case 1:
+      fTop = rcAnnot.left - rcPageView.left;
+      fBottom = rcPageView.right - rcAnnot.right;
+      break;
+    case 2:
+      fTop = rcAnnot.bottom - rcPageView.bottom;
+      fBottom = rcPageView.top - rcAnnot.top;
+      break;
+    case 3:
+      fTop = rcPageView.right - rcAnnot.right;
+      fBottom = rcAnnot.left - rcPageView.left;
+      break;
+  }
+
+  FX_FLOAT fFactHeight = 0;
+  bool bBottom = true;
+  FX_FLOAT fMaxListBoxHeight = 0;
+  if (fPopupMax > FFL_MAXLISTBOXHEIGHT) {
+    if (fPopupMin > FFL_MAXLISTBOXHEIGHT) {
+      fMaxListBoxHeight = fPopupMin;
+    } else {
+      fMaxListBoxHeight = FFL_MAXLISTBOXHEIGHT;
+    }
+  } else {
+    fMaxListBoxHeight = fPopupMax;
+  }
+
+  if (fBottom > fMaxListBoxHeight) {
+    fFactHeight = fMaxListBoxHeight;
+    bBottom = true;
+  } else {
+    if (fTop > fMaxListBoxHeight) {
+      fFactHeight = fMaxListBoxHeight;
+      bBottom = false;
+    } else {
+      if (fTop > fBottom) {
+        fFactHeight = fTop;
+        bBottom = false;
+      } else {
+        fFactHeight = fBottom;
+        bBottom = true;
+      }
+    }
+  }
+
+  nRet = bBottom ? 0 : 1;
+  fPopupRet = fFactHeight;
+}
+
+void CFFL_InteractiveFormFiller::OnKeyStrokeCommit(
+    CPDFSDK_Annot::ObservedPtr* pAnnot,
+    CPDFSDK_PageView* pPageView,
+    bool& bRC,
+    bool& bExit,
+    uint32_t nFlag) {
+  if (!m_bNotifying) {
+    CPDFSDK_Widget* pWidget = static_cast<CPDFSDK_Widget*>(pAnnot->Get());
+    if (pWidget->GetAAction(CPDF_AAction::KeyStroke).GetDict()) {
+      ASSERT(pPageView);
+      m_bNotifying = true;
+      pWidget->ClearAppModified();
+
+      PDFSDK_FieldAction fa;
+      fa.bModifier = m_pFormFillEnv->IsCTRLKeyDown(nFlag);
+      fa.bShift = m_pFormFillEnv->IsSHIFTKeyDown(nFlag);
+      fa.bWillCommit = true;
+      fa.bKeyDown = true;
+      fa.bRC = true;
+
+      CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, false);
+      pFormFiller->GetActionData(pPageView, CPDF_AAction::KeyStroke, fa);
+      pFormFiller->SaveState(pPageView);
+      pWidget->OnAAction(CPDF_AAction::KeyStroke, fa, pPageView);
+      if (!(*pAnnot))
+        return;
+
+      bRC = fa.bRC;
+      m_bNotifying = false;
+    }
+  }
+}
+
+void CFFL_InteractiveFormFiller::OnValidate(CPDFSDK_Annot::ObservedPtr* pAnnot,
+                                            CPDFSDK_PageView* pPageView,
+                                            bool& bRC,
+                                            bool& bExit,
+                                            uint32_t nFlag) {
+  if (!m_bNotifying) {
+    CPDFSDK_Widget* pWidget = static_cast<CPDFSDK_Widget*>(pAnnot->Get());
+    if (pWidget->GetAAction(CPDF_AAction::Validate).GetDict()) {
+      ASSERT(pPageView);
+      m_bNotifying = true;
+      pWidget->ClearAppModified();
+
+      PDFSDK_FieldAction fa;
+      fa.bModifier = m_pFormFillEnv->IsCTRLKeyDown(nFlag);
+      fa.bShift = m_pFormFillEnv->IsSHIFTKeyDown(nFlag);
+      fa.bKeyDown = true;
+      fa.bRC = true;
+
+      CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, false);
+      pFormFiller->GetActionData(pPageView, CPDF_AAction::Validate, fa);
+      pFormFiller->SaveState(pPageView);
+      pWidget->OnAAction(CPDF_AAction::Validate, fa, pPageView);
+      if (!(*pAnnot))
+        return;
+
+      bRC = fa.bRC;
+      m_bNotifying = false;
+    }
+  }
+}
+
+void CFFL_InteractiveFormFiller::OnCalculate(CPDFSDK_Widget* pWidget,
+                                             CPDFSDK_PageView* pPageView,
+                                             bool& bExit,
+                                             uint32_t nFlag) {
+  if (!m_bNotifying) {
+    ASSERT(pWidget);
+    CPDFSDK_InterForm* pInterForm = pPageView->GetFormFillEnv()->GetInterForm();
+    pInterForm->OnCalculate(pWidget->GetFormField());
+    m_bNotifying = false;
+  }
+}
+
+void CFFL_InteractiveFormFiller::OnFormat(CPDFSDK_Widget* pWidget,
+                                          CPDFSDK_PageView* pPageView,
+                                          bool& bExit,
+                                          uint32_t nFlag) {
+  if (!m_bNotifying) {
+    ASSERT(pWidget);
+    CPDFSDK_InterForm* pInterForm = pPageView->GetFormFillEnv()->GetInterForm();
+
+    bool bFormatted = false;
+    CFX_WideString sValue =
+        pInterForm->OnFormat(pWidget->GetFormField(), bFormatted);
+
+    if (bExit)
+      return;
+
+    if (bFormatted) {
+      pInterForm->ResetFieldAppearance(pWidget->GetFormField(), &sValue, true);
+      pInterForm->UpdateField(pWidget->GetFormField());
+    }
+
+    m_bNotifying = false;
+  }
+}
+
+#ifdef PDF_ENABLE_XFA
+void CFFL_InteractiveFormFiller::OnClick(CPDFSDK_Widget* pWidget,
+                                         CPDFSDK_PageView* pPageView,
+                                         bool& bReset,
+                                         bool& bExit,
+                                         uint32_t nFlag) {
+  if (!m_bNotifying) {
+    if (pWidget->HasXFAAAction(PDFSDK_XFA_Click)) {
+      m_bNotifying = true;
+      int nAge = pWidget->GetAppearanceAge();
+      int nValueAge = pWidget->GetValueAge();
+
+      PDFSDK_FieldAction fa;
+      fa.bModifier = m_pFormFillEnv->IsCTRLKeyDown(nFlag);
+      fa.bShift = m_pFormFillEnv->IsSHIFTKeyDown(nFlag);
+
+      pWidget->OnXFAAAction(PDFSDK_XFA_Click, fa, pPageView);
+      m_bNotifying = false;
+
+      if (!IsValidAnnot(pPageView, pWidget)) {
+        bExit = true;
+        return;
+      }
+
+      if (nAge != pWidget->GetAppearanceAge()) {
+        if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, false)) {
+          pFormFiller->ResetPDFWindow(pPageView,
+                                      nValueAge == pWidget->GetValueAge());
+        }
+
+        bReset = true;
+      }
+    }
+  }
+}
+
+void CFFL_InteractiveFormFiller::OnFull(CPDFSDK_Widget* pWidget,
+                                        CPDFSDK_PageView* pPageView,
+                                        bool& bReset,
+                                        bool& bExit,
+                                        uint32_t nFlag) {
+  if (!m_bNotifying) {
+    if (pWidget->HasXFAAAction(PDFSDK_XFA_Full)) {
+      m_bNotifying = true;
+      int nAge = pWidget->GetAppearanceAge();
+      int nValueAge = pWidget->GetValueAge();
+
+      PDFSDK_FieldAction fa;
+      fa.bModifier = m_pFormFillEnv->IsCTRLKeyDown(nFlag);
+      fa.bShift = m_pFormFillEnv->IsSHIFTKeyDown(nFlag);
+
+      pWidget->OnXFAAAction(PDFSDK_XFA_Full, fa, pPageView);
+      m_bNotifying = false;
+
+      if (!IsValidAnnot(pPageView, pWidget)) {
+        bExit = true;
+        return;
+      }
+
+      if (nAge != pWidget->GetAppearanceAge()) {
+        if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, false)) {
+          pFormFiller->ResetPDFWindow(pPageView,
+                                      nValueAge == pWidget->GetValueAge());
+        }
+
+        bReset = true;
+      }
+    }
+  }
+}
+
+void CFFL_InteractiveFormFiller::OnPopupPreOpen(void* pPrivateData,
+                                                bool& bExit,
+                                                uint32_t nFlag) {
+  CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
+  ASSERT(pData);
+  ASSERT(pData->pWidget);
+
+  bool bTempReset = false;
+  bool bTempExit = false;
+  OnPreOpen(pData->pWidget, pData->pPageView, bTempReset, bTempExit, nFlag);
+  if (bTempReset || bTempExit)
+    bExit = true;
+}
+
+void CFFL_InteractiveFormFiller::OnPopupPostOpen(void* pPrivateData,
+                                                 bool& bExit,
+                                                 uint32_t nFlag) {
+  CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
+  ASSERT(pData);
+  ASSERT(pData->pWidget);
+
+  bool bTempReset = false;
+  bool bTempExit = false;
+  OnPostOpen(pData->pWidget, pData->pPageView, bTempReset, bTempExit, nFlag);
+  if (bTempReset || bTempExit)
+    bExit = true;
+}
+
+void CFFL_InteractiveFormFiller::OnPreOpen(CPDFSDK_Widget* pWidget,
+                                           CPDFSDK_PageView* pPageView,
+                                           bool& bReset,
+                                           bool& bExit,
+                                           uint32_t nFlag) {
+  if (!m_bNotifying) {
+    if (pWidget->HasXFAAAction(PDFSDK_XFA_PreOpen)) {
+      m_bNotifying = true;
+      int nAge = pWidget->GetAppearanceAge();
+      int nValueAge = pWidget->GetValueAge();
+
+      PDFSDK_FieldAction fa;
+      fa.bModifier = m_pFormFillEnv->IsCTRLKeyDown(nFlag);
+      fa.bShift = m_pFormFillEnv->IsSHIFTKeyDown(nFlag);
+
+      pWidget->OnXFAAAction(PDFSDK_XFA_PreOpen, fa, pPageView);
+      m_bNotifying = false;
+
+      if (!IsValidAnnot(pPageView, pWidget)) {
+        bExit = true;
+        return;
+      }
+
+      if (nAge != pWidget->GetAppearanceAge()) {
+        if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, false)) {
+          pFormFiller->ResetPDFWindow(pPageView,
+                                      nValueAge == pWidget->GetValueAge());
+        }
+
+        bReset = true;
+      }
+    }
+  }
+}
+
+void CFFL_InteractiveFormFiller::OnPostOpen(CPDFSDK_Widget* pWidget,
+                                            CPDFSDK_PageView* pPageView,
+                                            bool& bReset,
+                                            bool& bExit,
+                                            uint32_t nFlag) {
+  if (!m_bNotifying) {
+    if (pWidget->HasXFAAAction(PDFSDK_XFA_PostOpen)) {
+      m_bNotifying = true;
+      int nAge = pWidget->GetAppearanceAge();
+      int nValueAge = pWidget->GetValueAge();
+
+      PDFSDK_FieldAction fa;
+      fa.bModifier = m_pFormFillEnv->IsCTRLKeyDown(nFlag);
+      fa.bShift = m_pFormFillEnv->IsSHIFTKeyDown(nFlag);
+
+      pWidget->OnXFAAAction(PDFSDK_XFA_PostOpen, fa, pPageView);
+      m_bNotifying = false;
+
+      if (!IsValidAnnot(pPageView, pWidget)) {
+        bExit = true;
+        return;
+      }
+
+      if (nAge != pWidget->GetAppearanceAge()) {
+        if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, false)) {
+          pFormFiller->ResetPDFWindow(pPageView,
+                                      nValueAge == pWidget->GetValueAge());
+        }
+
+        bReset = true;
+      }
+    }
+  }
+}
+#endif  // PDF_ENABLE_XFA
+
+bool CFFL_InteractiveFormFiller::IsValidAnnot(CPDFSDK_PageView* pPageView,
+                                              CPDFSDK_Annot* pAnnot) {
+  return pPageView && pPageView->IsValidAnnot(pAnnot->GetPDFAnnot());
+}
+
+void CFFL_InteractiveFormFiller::OnBeforeKeyStroke(
+    void* pPrivateData,
+    CFX_WideString& strChange,
+    const CFX_WideString& strChangeEx,
+    int nSelStart,
+    int nSelEnd,
+    bool bKeyDown,
+    bool& bRC,
+    bool& bExit,
+    uint32_t nFlag) {
+  CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
+  ASSERT(pData->pWidget);
+
+  CFFL_FormFiller* pFormFiller = GetFormFiller(pData->pWidget, false);
+
+#ifdef PDF_ENABLE_XFA
+  if (pFormFiller->IsFieldFull(pData->pPageView)) {
+    bool bFullExit = false;
+    bool bFullReset = false;
+    OnFull(pData->pWidget, pData->pPageView, bFullReset, bFullExit, nFlag);
+
+    if (bFullReset || bFullExit) {
+      bExit = true;
+      return;
+    }
+  }
+#endif  // PDF_ENABLE_XFA
+
+  if (!m_bNotifying) {
+    if (pData->pWidget->GetAAction(CPDF_AAction::KeyStroke).GetDict()) {
+      m_bNotifying = true;
+      int nAge = pData->pWidget->GetAppearanceAge();
+      int nValueAge = pData->pWidget->GetValueAge();
+
+      CPDFSDK_FormFillEnvironment* pFormFillEnv =
+          pData->pPageView->GetFormFillEnv();
+
+      PDFSDK_FieldAction fa;
+      fa.bModifier = m_pFormFillEnv->IsCTRLKeyDown(nFlag);
+      fa.bShift = m_pFormFillEnv->IsSHIFTKeyDown(nFlag);
+      fa.sChange = strChange;
+      fa.sChangeEx = strChangeEx;
+      fa.bKeyDown = bKeyDown;
+      fa.bWillCommit = false;
+      fa.bRC = true;
+      fa.nSelStart = nSelStart;
+      fa.nSelEnd = nSelEnd;
+
+      pFormFiller->GetActionData(pData->pPageView, CPDF_AAction::KeyStroke, fa);
+      pFormFiller->SaveState(pData->pPageView);
+
+      CPDFSDK_Annot::ObservedPtr pObserved(pData->pWidget);
+      if (pData->pWidget->OnAAction(CPDF_AAction::KeyStroke, fa,
+                                    pData->pPageView)) {
+        if (!pObserved || !IsValidAnnot(pData->pPageView, pData->pWidget)) {
+          bExit = true;
+          m_bNotifying = false;
+          return;
+        }
+
+        if (nAge != pData->pWidget->GetAppearanceAge()) {
+          CPWL_Wnd* pWnd = pFormFiller->ResetPDFWindow(
+              pData->pPageView, nValueAge == pData->pWidget->GetValueAge());
+          pData = (CFFL_PrivateData*)pWnd->GetAttachedData();
+          bExit = true;
+        }
+
+        if (fa.bRC) {
+          pFormFiller->SetActionData(pData->pPageView, CPDF_AAction::KeyStroke,
+                                     fa);
+          bRC = false;
+        } else {
+          pFormFiller->RestoreState(pData->pPageView);
+          bRC = false;
+        }
+
+        if (pFormFillEnv->GetFocusAnnot() != pData->pWidget) {
+          pFormFiller->CommitData(pData->pPageView, nFlag);
+          bExit = true;
+        }
+      } else {
+        if (!IsValidAnnot(pData->pPageView, pData->pWidget)) {
+          bExit = true;
+          m_bNotifying = false;
+          return;
+        }
+      }
+
+      m_bNotifying = false;
+    }
+  }
+}
diff --git a/fpdfsdk/formfiller/cffl_interactiveformfiller.h b/fpdfsdk/formfiller/cffl_interactiveformfiller.h
new file mode 100644
index 0000000..e81d3c8
--- /dev/null
+++ b/fpdfsdk/formfiller/cffl_interactiveformfiller.h
@@ -0,0 +1,177 @@
+// 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_FORMFILLER_CFFL_INTERACTIVEFORMFILLER_H_
+#define FPDFSDK_FORMFILLER_CFFL_INTERACTIVEFORMFILLER_H_
+
+#include <map>
+#include <memory>
+
+#include "fpdfsdk/cpdfsdk_annot.h"
+#include "fpdfsdk/fsdk_define.h"
+#include "fpdfsdk/pdfwindow/PWL_Edit.h"
+
+class CFFL_FormFiller;
+class CPDFSDK_FormFillEnvironment;
+class CPDFSDK_PageView;
+class CPDFSDK_Widget;
+
+class CFFL_InteractiveFormFiller : public IPWL_Filler_Notify {
+ public:
+  explicit CFFL_InteractiveFormFiller(
+      CPDFSDK_FormFillEnvironment* pFormFillEnv);
+  ~CFFL_InteractiveFormFiller() override;
+
+  bool Annot_HitTest(CPDFSDK_PageView* pPageView,
+                     CPDFSDK_Annot* pAnnot,
+                     CFX_FloatPoint point);
+  FX_RECT GetViewBBox(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot);
+  void OnDraw(CPDFSDK_PageView* pPageView,
+              CPDFSDK_Annot* pAnnot,
+              CFX_RenderDevice* pDevice,
+              CFX_Matrix* pUser2Device);
+
+  void OnDelete(CPDFSDK_Annot* pAnnot);
+
+  void OnMouseEnter(CPDFSDK_PageView* pPageView,
+                    CPDFSDK_Annot::ObservedPtr* pAnnot,
+                    uint32_t nFlag);
+  void OnMouseExit(CPDFSDK_PageView* pPageView,
+                   CPDFSDK_Annot::ObservedPtr* pAnnot,
+                   uint32_t nFlag);
+  bool OnLButtonDown(CPDFSDK_PageView* pPageView,
+                     CPDFSDK_Annot::ObservedPtr* pAnnot,
+                     uint32_t nFlags,
+                     const CFX_FloatPoint& point);
+  bool OnLButtonUp(CPDFSDK_PageView* pPageView,
+                   CPDFSDK_Annot::ObservedPtr* pAnnot,
+                   uint32_t nFlags,
+                   const CFX_FloatPoint& point);
+  bool OnLButtonDblClk(CPDFSDK_PageView* pPageView,
+                       CPDFSDK_Annot::ObservedPtr* pAnnot,
+                       uint32_t nFlags,
+                       const CFX_FloatPoint& point);
+  bool OnMouseMove(CPDFSDK_PageView* pPageView,
+                   CPDFSDK_Annot::ObservedPtr* pAnnot,
+                   uint32_t nFlags,
+                   const CFX_FloatPoint& point);
+  bool OnMouseWheel(CPDFSDK_PageView* pPageView,
+                    CPDFSDK_Annot::ObservedPtr* pAnnot,
+                    uint32_t nFlags,
+                    short zDelta,
+                    const CFX_FloatPoint& point);
+  bool OnRButtonDown(CPDFSDK_PageView* pPageView,
+                     CPDFSDK_Annot::ObservedPtr* pAnnot,
+                     uint32_t nFlags,
+                     const CFX_FloatPoint& point);
+  bool OnRButtonUp(CPDFSDK_PageView* pPageView,
+                   CPDFSDK_Annot::ObservedPtr* pAnnot,
+                   uint32_t nFlags,
+                   const CFX_FloatPoint& point);
+
+  bool OnKeyDown(CPDFSDK_Annot* pAnnot, uint32_t nKeyCode, uint32_t nFlags);
+  bool OnChar(CPDFSDK_Annot* pAnnot, uint32_t nChar, uint32_t nFlags);
+
+  bool OnSetFocus(CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlag);
+  bool OnKillFocus(CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlag);
+
+  CFFL_FormFiller* GetFormFiller(CPDFSDK_Annot* pAnnot, bool bRegister);
+  void RemoveFormFiller(CPDFSDK_Annot* pAnnot);
+
+  static bool IsVisible(CPDFSDK_Widget* pWidget);
+  static bool IsReadOnly(CPDFSDK_Widget* pWidget);
+  static bool IsFillingAllowed(CPDFSDK_Widget* pWidget);
+  static bool IsValidAnnot(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot);
+
+  void OnKeyStrokeCommit(CPDFSDK_Annot::ObservedPtr* pWidget,
+                         CPDFSDK_PageView* pPageView,
+                         bool& bRC,
+                         bool& bExit,
+                         uint32_t nFlag);
+  void OnValidate(CPDFSDK_Annot::ObservedPtr* pWidget,
+                  CPDFSDK_PageView* pPageView,
+                  bool& bRC,
+                  bool& bExit,
+                  uint32_t nFlag);
+
+  void OnCalculate(CPDFSDK_Widget* pWidget,
+                   CPDFSDK_PageView* pPageView,
+                   bool& bExit,
+                   uint32_t nFlag);
+  void OnFormat(CPDFSDK_Widget* pWidget,
+                CPDFSDK_PageView* pPageView,
+                bool& bExit,
+                uint32_t nFlag);
+  void OnButtonUp(CPDFSDK_Annot::ObservedPtr* pWidget,
+                  CPDFSDK_PageView* pPageView,
+                  bool& bReset,
+                  bool& bExit,
+                  uint32_t nFlag);
+#ifdef PDF_ENABLE_XFA
+  void OnClick(CPDFSDK_Widget* pWidget,
+               CPDFSDK_PageView* pPageView,
+               bool& bReset,
+               bool& bExit,
+               uint32_t nFlag);
+  void OnFull(CPDFSDK_Widget* pWidget,
+              CPDFSDK_PageView* pPageView,
+              bool& bReset,
+              bool& bExit,
+              uint32_t nFlag);
+  void OnPreOpen(CPDFSDK_Widget* pWidget,
+                 CPDFSDK_PageView* pPageView,
+                 bool& bReset,
+                 bool& bExit,
+                 uint32_t nFlag);
+  void OnPostOpen(CPDFSDK_Widget* pWidget,
+                  CPDFSDK_PageView* pPageView,
+                  bool& bReset,
+                  bool& bExit,
+                  uint32_t nFlag);
+#endif  // PDF_ENABLE_XFA
+
+ private:
+  using CFFL_Widget2Filler =
+      std::map<CPDFSDK_Annot*, std::unique_ptr<CFFL_FormFiller>>;
+
+  // IPWL_Filler_Notify:
+  void QueryWherePopup(void* pPrivateData,
+                       FX_FLOAT fPopupMin,
+                       FX_FLOAT fPopupMax,
+                       int32_t& nRet,
+                       FX_FLOAT& fPopupRet) override;
+  void OnBeforeKeyStroke(void* pPrivateData,
+                         CFX_WideString& strChange,
+                         const CFX_WideString& strChangeEx,
+                         int nSelStart,
+                         int nSelEnd,
+                         bool bKeyDown,
+                         bool& bRC,
+                         bool& bExit,
+                         uint32_t nFlag) override;
+#ifdef PDF_ENABLE_XFA
+  void OnPopupPreOpen(void* pPrivateData, bool& bExit, uint32_t nFlag) override;
+  void OnPopupPostOpen(void* pPrivateData,
+                       bool& bExit,
+                       uint32_t nFlag) override;
+  void SetFocusAnnotTab(CPDFSDK_Annot* pWidget, bool bSameField, bool bNext);
+#endif  // PDF_ENABLE_XFA
+  void UnRegisterFormFiller(CPDFSDK_Annot* pAnnot);
+
+  CPDFSDK_FormFillEnvironment* const m_pFormFillEnv;
+  CFFL_Widget2Filler m_Maps;
+  bool m_bNotifying;
+};
+
+class CFFL_PrivateData {
+ public:
+  CPDFSDK_Widget* pWidget;
+  CPDFSDK_PageView* pPageView;
+  int nWidgetAge;
+  int nValueAge;
+};
+
+#endif  // FPDFSDK_FORMFILLER_CFFL_INTERACTIVEFORMFILLER_H_
diff --git a/fpdfsdk/formfiller/cffl_listbox.cpp b/fpdfsdk/formfiller/cffl_listbox.cpp
new file mode 100644
index 0000000..bc3bb6c
--- /dev/null
+++ b/fpdfsdk/formfiller/cffl_listbox.cpp
@@ -0,0 +1,205 @@
+// 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
+
+#include "fpdfsdk/formfiller/cffl_listbox.h"
+
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/cpdfsdk_widget.h"
+#include "fpdfsdk/formfiller/cba_fontmap.h"
+#include "fpdfsdk/formfiller/cffl_formfiller.h"
+#include "fpdfsdk/formfiller/cffl_interactiveformfiller.h"
+#include "fpdfsdk/fsdk_common.h"
+#include "fpdfsdk/pdfwindow/PWL_ListBox.h"
+#include "third_party/base/ptr_util.h"
+
+#define FFL_DEFAULTLISTBOXFONTSIZE 12.0f
+
+CFFL_ListBox::CFFL_ListBox(CPDFSDK_FormFillEnvironment* pApp,
+                           CPDFSDK_Annot* pWidget)
+    : CFFL_FormFiller(pApp, pWidget) {}
+
+CFFL_ListBox::~CFFL_ListBox() {}
+
+PWL_CREATEPARAM CFFL_ListBox::GetCreateParam() {
+  PWL_CREATEPARAM cp = CFFL_FormFiller::GetCreateParam();
+
+  uint32_t dwFieldFlag = m_pWidget->GetFieldFlags();
+
+  if (dwFieldFlag & FIELDFLAG_MULTISELECT) {
+    cp.dwFlags |= PLBS_MULTIPLESEL;
+  }
+
+  cp.dwFlags |= PWS_VSCROLL;
+
+  if (cp.dwFlags & PWS_AUTOFONTSIZE)
+    cp.fFontSize = FFL_DEFAULTLISTBOXFONTSIZE;
+
+  if (!m_pFontMap) {
+    m_pFontMap = pdfium::MakeUnique<CBA_FontMap>(
+        m_pWidget, m_pFormFillEnv->GetSysHandler());
+  }
+  cp.pFontMap = m_pFontMap.get();
+
+  return cp;
+}
+
+CPWL_Wnd* CFFL_ListBox::NewPDFWindow(const PWL_CREATEPARAM& cp,
+                                     CPDFSDK_PageView* pPageView) {
+  CPWL_ListBox* pWnd = new CPWL_ListBox();
+  pWnd->AttachFFLData(this);
+  pWnd->Create(cp);
+  pWnd->SetFillerNotify(m_pFormFillEnv->GetInteractiveFormFiller());
+
+  for (int32_t i = 0, sz = m_pWidget->CountOptions(); i < sz; i++)
+    pWnd->AddString(m_pWidget->GetOptionLabel(i));
+
+  if (pWnd->HasFlag(PLBS_MULTIPLESEL)) {
+    m_OriginSelections.clear();
+
+    bool bSetCaret = false;
+    for (int32_t i = 0, sz = m_pWidget->CountOptions(); i < sz; i++) {
+      if (m_pWidget->IsOptionSelected(i)) {
+        if (!bSetCaret) {
+          pWnd->SetCaret(i);
+          bSetCaret = true;
+        }
+        pWnd->Select(i);
+        m_OriginSelections.insert(i);
+      }
+    }
+  } else {
+    for (int i = 0, sz = m_pWidget->CountOptions(); i < sz; i++) {
+      if (m_pWidget->IsOptionSelected(i)) {
+        pWnd->Select(i);
+        break;
+      }
+    }
+  }
+
+  pWnd->SetTopVisibleIndex(m_pWidget->GetTopVisibleIndex());
+
+  return pWnd;
+}
+
+bool CFFL_ListBox::OnChar(CPDFSDK_Annot* pAnnot,
+                          uint32_t nChar,
+                          uint32_t nFlags) {
+  return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
+}
+
+bool CFFL_ListBox::IsDataChanged(CPDFSDK_PageView* pPageView) {
+  CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, false);
+  if (!pListBox)
+    return false;
+
+  if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT) {
+    size_t nSelCount = 0;
+    for (int32_t i = 0, sz = pListBox->GetCount(); i < sz; ++i) {
+      if (pListBox->IsItemSelected(i)) {
+        if (m_OriginSelections.count(i) == 0)
+          return true;
+
+        ++nSelCount;
+      }
+    }
+
+    return nSelCount != m_OriginSelections.size();
+  }
+  return pListBox->GetCurSel() != m_pWidget->GetSelectedIndex(0);
+}
+
+void CFFL_ListBox::SaveData(CPDFSDK_PageView* pPageView) {
+  CPWL_ListBox* pListBox =
+      static_cast<CPWL_ListBox*>(GetPDFWindow(pPageView, false));
+  if (!pListBox)
+    return;
+
+  int32_t nNewTopIndex = pListBox->GetTopVisibleIndex();
+  m_pWidget->ClearSelection(false);
+  if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT) {
+    for (int32_t i = 0, sz = pListBox->GetCount(); i < sz; i++) {
+      if (pListBox->IsItemSelected(i))
+        m_pWidget->SetOptionSelection(i, true, false);
+    }
+  } else {
+    m_pWidget->SetOptionSelection(pListBox->GetCurSel(), true, false);
+  }
+  m_pWidget->SetTopVisibleIndex(nNewTopIndex);
+  m_pWidget->ResetFieldAppearance(true);
+  m_pWidget->UpdateField();
+  SetChangeMark();
+}
+
+void CFFL_ListBox::GetActionData(CPDFSDK_PageView* pPageView,
+                                 CPDF_AAction::AActionType type,
+                                 PDFSDK_FieldAction& fa) {
+  switch (type) {
+    case CPDF_AAction::Validate:
+      if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT) {
+        fa.sValue = L"";
+      } else {
+        if (CPWL_ListBox* pListBox =
+                (CPWL_ListBox*)GetPDFWindow(pPageView, false)) {
+          int32_t nCurSel = pListBox->GetCurSel();
+          if (nCurSel >= 0)
+            fa.sValue = m_pWidget->GetOptionLabel(nCurSel);
+        }
+      }
+      break;
+    case CPDF_AAction::LoseFocus:
+    case CPDF_AAction::GetFocus:
+      if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT) {
+        fa.sValue = L"";
+      } else {
+        int32_t nCurSel = m_pWidget->GetSelectedIndex(0);
+        if (nCurSel >= 0)
+          fa.sValue = m_pWidget->GetOptionLabel(nCurSel);
+      }
+      break;
+    default:
+      break;
+  }
+}
+
+void CFFL_ListBox::SaveState(CPDFSDK_PageView* pPageView) {
+  ASSERT(pPageView);
+
+  if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, false)) {
+    for (int32_t i = 0, sz = pListBox->GetCount(); i < sz; i++) {
+      if (pListBox->IsItemSelected(i)) {
+        m_State.Add(i);
+      }
+    }
+  }
+}
+
+void CFFL_ListBox::RestoreState(CPDFSDK_PageView* pPageView) {
+  if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, false)) {
+    for (int i = 0, sz = m_State.GetSize(); i < sz; i++)
+      pListBox->Select(m_State[i]);
+  }
+}
+
+CPWL_Wnd* CFFL_ListBox::ResetPDFWindow(CPDFSDK_PageView* pPageView,
+                                       bool bRestoreValue) {
+  if (bRestoreValue)
+    SaveState(pPageView);
+
+  DestroyPDFWindow(pPageView);
+
+  CPWL_Wnd* pRet = nullptr;
+
+  if (bRestoreValue) {
+    RestoreState(pPageView);
+    pRet = GetPDFWindow(pPageView, false);
+  } else {
+    pRet = GetPDFWindow(pPageView, true);
+  }
+
+  m_pWidget->UpdateField();
+
+  return pRet;
+}
diff --git a/fpdfsdk/include/formfiller/FFL_ListBox.h b/fpdfsdk/formfiller/cffl_listbox.h
similarity index 60%
rename from fpdfsdk/include/formfiller/FFL_ListBox.h
rename to fpdfsdk/formfiller/cffl_listbox.h
index 227f062..e97ede0 100644
--- a/fpdfsdk/include/formfiller/FFL_ListBox.h
+++ b/fpdfsdk/formfiller/cffl_listbox.h
@@ -4,42 +4,40 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#ifndef FPDFSDK_INCLUDE_FORMFILLER_FFL_LISTBOX_H_
-#define FPDFSDK_INCLUDE_FORMFILLER_FFL_LISTBOX_H_
+#ifndef FPDFSDK_FORMFILLER_CFFL_LISTBOX_H_
+#define FPDFSDK_FORMFILLER_CFFL_LISTBOX_H_
 
+#include <memory>
 #include <set>
 
-#include "FFL_FormFiller.h"
+#include "fpdfsdk/formfiller/cffl_formfiller.h"
 
 class CBA_FontMap;
 
 class CFFL_ListBox : public CFFL_FormFiller {
  public:
-  CFFL_ListBox(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pWidget);
+  CFFL_ListBox(CPDFSDK_FormFillEnvironment* pApp, CPDFSDK_Annot* pWidget);
   ~CFFL_ListBox() override;
 
   // CFFL_FormFiller
   PWL_CREATEPARAM GetCreateParam() override;
   CPWL_Wnd* NewPDFWindow(const PWL_CREATEPARAM& cp,
                          CPDFSDK_PageView* pPageView) override;
-  FX_BOOL OnChar(CPDFSDK_Annot* pAnnot, FX_UINT nChar, FX_UINT nFlags) override;
-  FX_BOOL IsDataChanged(CPDFSDK_PageView* pPageView) override;
+  bool OnChar(CPDFSDK_Annot* pAnnot, uint32_t nChar, uint32_t nFlags) override;
+  bool IsDataChanged(CPDFSDK_PageView* pPageView) override;
   void SaveData(CPDFSDK_PageView* pPageView) override;
   void GetActionData(CPDFSDK_PageView* pPageView,
                      CPDF_AAction::AActionType type,
                      PDFSDK_FieldAction& fa) override;
-  void SetActionData(CPDFSDK_PageView* pPageView,
-                     CPDF_AAction::AActionType type,
-                     const PDFSDK_FieldAction& fa) override;
   void SaveState(CPDFSDK_PageView* pPageView) override;
   void RestoreState(CPDFSDK_PageView* pPageView) override;
   CPWL_Wnd* ResetPDFWindow(CPDFSDK_PageView* pPageView,
-                           FX_BOOL bRestoreValue) override;
+                           bool bRestoreValue) override;
 
  private:
-  CBA_FontMap* m_pFontMap;
+  std::unique_ptr<CBA_FontMap> m_pFontMap;
   std::set<int> m_OriginSelections;
   CFX_ArrayTemplate<int> m_State;
 };
 
-#endif  // FPDFSDK_INCLUDE_FORMFILLER_FFL_LISTBOX_H_
+#endif  // FPDFSDK_FORMFILLER_CFFL_LISTBOX_H_
diff --git a/fpdfsdk/formfiller/cffl_pushbutton.cpp b/fpdfsdk/formfiller/cffl_pushbutton.cpp
new file mode 100644
index 0000000..9b4121a
--- /dev/null
+++ b/fpdfsdk/formfiller/cffl_pushbutton.cpp
@@ -0,0 +1,37 @@
+// 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
+
+#include "fpdfsdk/formfiller/cffl_pushbutton.h"
+
+#include "fpdfsdk/formfiller/cffl_formfiller.h"
+#include "fpdfsdk/pdfwindow/PWL_SpecialButton.h"
+
+CFFL_PushButton::CFFL_PushButton(CPDFSDK_FormFillEnvironment* pApp,
+                                 CPDFSDK_Annot* pAnnot)
+    : CFFL_Button(pApp, pAnnot) {}
+
+CFFL_PushButton::~CFFL_PushButton() {}
+
+CPWL_Wnd* CFFL_PushButton::NewPDFWindow(const PWL_CREATEPARAM& cp,
+                                        CPDFSDK_PageView* pPageView) {
+  CPWL_PushButton* pWnd = new CPWL_PushButton();
+  pWnd->Create(cp);
+
+  return pWnd;
+}
+
+bool CFFL_PushButton::OnChar(CPDFSDK_Annot* pAnnot,
+                             uint32_t nChar,
+                             uint32_t nFlags) {
+  return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
+}
+
+void CFFL_PushButton::OnDraw(CPDFSDK_PageView* pPageView,
+                             CPDFSDK_Annot* pAnnot,
+                             CFX_RenderDevice* pDevice,
+                             CFX_Matrix* pUser2Device) {
+  CFFL_Button::OnDraw(pPageView, pAnnot, pDevice, pUser2Device);
+}
diff --git a/fpdfsdk/formfiller/cffl_pushbutton.h b/fpdfsdk/formfiller/cffl_pushbutton.h
new file mode 100644
index 0000000..1d50595
--- /dev/null
+++ b/fpdfsdk/formfiller/cffl_pushbutton.h
@@ -0,0 +1,27 @@
+// 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_FORMFILLER_CFFL_PUSHBUTTON_H_
+#define FPDFSDK_FORMFILLER_CFFL_PUSHBUTTON_H_
+
+#include "fpdfsdk/formfiller/cffl_formfiller.h"
+
+class CFFL_PushButton : public CFFL_Button {
+ public:
+  CFFL_PushButton(CPDFSDK_FormFillEnvironment* pApp, CPDFSDK_Annot* pAnnot);
+  ~CFFL_PushButton() override;
+
+  // CFFL_Button
+  CPWL_Wnd* NewPDFWindow(const PWL_CREATEPARAM& cp,
+                         CPDFSDK_PageView* pPageView) override;
+  bool OnChar(CPDFSDK_Annot* pAnnot, uint32_t nChar, uint32_t nFlags) override;
+  void OnDraw(CPDFSDK_PageView* pPageView,
+              CPDFSDK_Annot* pAnnot,
+              CFX_RenderDevice* pDevice,
+              CFX_Matrix* pUser2Device) override;
+};
+
+#endif  // FPDFSDK_FORMFILLER_CFFL_PUSHBUTTON_H_
diff --git a/fpdfsdk/formfiller/cffl_radiobutton.cpp b/fpdfsdk/formfiller/cffl_radiobutton.cpp
new file mode 100644
index 0000000..70d4c0d
--- /dev/null
+++ b/fpdfsdk/formfiller/cffl_radiobutton.cpp
@@ -0,0 +1,119 @@
+// 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
+
+#include "fpdfsdk/formfiller/cffl_radiobutton.h"
+
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/cpdfsdk_widget.h"
+#include "fpdfsdk/formfiller/cffl_formfiller.h"
+#include "fpdfsdk/pdfwindow/PWL_SpecialButton.h"
+#include "public/fpdf_fwlevent.h"
+
+CFFL_RadioButton::CFFL_RadioButton(CPDFSDK_FormFillEnvironment* pApp,
+                                   CPDFSDK_Annot* pWidget)
+    : CFFL_Button(pApp, pWidget) {}
+
+CFFL_RadioButton::~CFFL_RadioButton() {}
+
+CPWL_Wnd* CFFL_RadioButton::NewPDFWindow(const PWL_CREATEPARAM& cp,
+                                         CPDFSDK_PageView* pPageView) {
+  CPWL_RadioButton* pWnd = new CPWL_RadioButton();
+  pWnd->Create(cp);
+
+  pWnd->SetCheck(m_pWidget->IsChecked());
+
+  return pWnd;
+}
+
+bool CFFL_RadioButton::OnKeyDown(CPDFSDK_Annot* pAnnot,
+                                 uint32_t nKeyCode,
+                                 uint32_t nFlags) {
+  switch (nKeyCode) {
+    case FWL_VKEY_Return:
+    case FWL_VKEY_Space:
+      return true;
+    default:
+      return CFFL_FormFiller::OnKeyDown(pAnnot, nKeyCode, nFlags);
+  }
+}
+
+bool CFFL_RadioButton::OnChar(CPDFSDK_Annot* pAnnot,
+                              uint32_t nChar,
+                              uint32_t nFlags) {
+  switch (nChar) {
+    case FWL_VKEY_Return:
+    case FWL_VKEY_Space: {
+      CPDFSDK_PageView* pPageView = pAnnot->GetPageView();
+      ASSERT(pPageView);
+
+      bool bReset = false;
+      bool bExit = false;
+      CPDFSDK_Annot::ObservedPtr pObserved(m_pWidget);
+      m_pFormFillEnv->GetInteractiveFormFiller()->OnButtonUp(
+          &pObserved, pPageView, bReset, bExit, nFlags);
+      if (!pObserved || bReset || bExit)
+        return true;
+
+      CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
+      if (CPWL_RadioButton* pWnd =
+              (CPWL_RadioButton*)GetPDFWindow(pPageView, true))
+        pWnd->SetCheck(true);
+      CommitData(pPageView, nFlags);
+      return true;
+    }
+    default:
+      return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
+  }
+}
+
+bool CFFL_RadioButton::OnLButtonUp(CPDFSDK_PageView* pPageView,
+                                   CPDFSDK_Annot* pAnnot,
+                                   uint32_t nFlags,
+                                   const CFX_FloatPoint& point) {
+  CFFL_Button::OnLButtonUp(pPageView, pAnnot, nFlags, point);
+
+  if (IsValid()) {
+    if (CPWL_RadioButton* pWnd =
+            (CPWL_RadioButton*)GetPDFWindow(pPageView, true))
+      pWnd->SetCheck(true);
+
+    if (!CommitData(pPageView, nFlags))
+      return false;
+  }
+
+  return true;
+}
+
+bool CFFL_RadioButton::IsDataChanged(CPDFSDK_PageView* pPageView) {
+  if (CPWL_RadioButton* pWnd =
+          (CPWL_RadioButton*)GetPDFWindow(pPageView, false)) {
+    return pWnd->IsChecked() != m_pWidget->IsChecked();
+  }
+
+  return false;
+}
+
+void CFFL_RadioButton::SaveData(CPDFSDK_PageView* pPageView) {
+  if (CPWL_RadioButton* pWnd =
+          (CPWL_RadioButton*)GetPDFWindow(pPageView, false)) {
+    bool bNewChecked = pWnd->IsChecked();
+
+    if (bNewChecked) {
+      CPDF_FormField* pField = m_pWidget->GetFormField();
+      for (int32_t i = 0, sz = pField->CountControls(); i < sz; i++) {
+        if (CPDF_FormControl* pCtrl = pField->GetControl(i)) {
+          if (pCtrl->IsChecked()) {
+            break;
+          }
+        }
+      }
+    }
+
+    m_pWidget->SetCheck(bNewChecked, false);
+    m_pWidget->UpdateField();
+    SetChangeMark();
+  }
+}
diff --git a/fpdfsdk/formfiller/cffl_radiobutton.h b/fpdfsdk/formfiller/cffl_radiobutton.h
new file mode 100644
index 0000000..49a658f
--- /dev/null
+++ b/fpdfsdk/formfiller/cffl_radiobutton.h
@@ -0,0 +1,32 @@
+// 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_FORMFILLER_CFFL_RADIOBUTTON_H_
+#define FPDFSDK_FORMFILLER_CFFL_RADIOBUTTON_H_
+
+#include "fpdfsdk/formfiller/cffl_formfiller.h"
+
+class CFFL_RadioButton : public CFFL_Button {
+ public:
+  CFFL_RadioButton(CPDFSDK_FormFillEnvironment* pApp, CPDFSDK_Annot* pAnnot);
+  ~CFFL_RadioButton() override;
+
+  // CFFL_Button
+  CPWL_Wnd* NewPDFWindow(const PWL_CREATEPARAM& cp,
+                         CPDFSDK_PageView* pPageView) override;
+  bool OnKeyDown(CPDFSDK_Annot* pAnnot,
+                 uint32_t nKeyCode,
+                 uint32_t nFlags) override;
+  bool OnChar(CPDFSDK_Annot* pAnnot, uint32_t nChar, uint32_t nFlags) override;
+  bool OnLButtonUp(CPDFSDK_PageView* pPageView,
+                   CPDFSDK_Annot* pAnnot,
+                   uint32_t nFlags,
+                   const CFX_FloatPoint& point) override;
+  bool IsDataChanged(CPDFSDK_PageView* pPageView) override;
+  void SaveData(CPDFSDK_PageView* pPageView) override;
+};
+
+#endif  // FPDFSDK_FORMFILLER_CFFL_RADIOBUTTON_H_
diff --git a/fpdfsdk/src/formfiller/FFL_TextField.cpp b/fpdfsdk/formfiller/cffl_textfield.cpp
similarity index 65%
rename from fpdfsdk/src/formfiller/FFL_TextField.cpp
rename to fpdfsdk/formfiller/cffl_textfield.cpp
index ca4e07b..c1cd786 100644
--- a/fpdfsdk/src/formfiller/FFL_TextField.cpp
+++ b/fpdfsdk/formfiller/cffl_textfield.cpp
@@ -4,21 +4,26 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#include "fpdfsdk/include/formfiller/FFL_TextField.h"
+#include "fpdfsdk/formfiller/cffl_textfield.h"
 
-#include "fpdfsdk/include/formfiller/FFL_CBA_Fontmap.h"
-#include "fpdfsdk/include/fsdk_common.h"
-#include "fpdfsdk/include/fsdk_mgr.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/cpdfsdk_widget.h"
+#include "fpdfsdk/formfiller/cba_fontmap.h"
+#include "fpdfsdk/fsdk_common.h"
+#include "third_party/base/ptr_util.h"
 
-CFFL_TextField::CFFL_TextField(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pAnnot)
-    : CFFL_FormFiller(pApp, pAnnot), m_pFontMap(NULL) {
-  m_State.nStart = m_State.nEnd = 0;
-}
+CFFL_TextField::CFFL_TextField(CPDFSDK_FormFillEnvironment* pApp,
+                               CPDFSDK_Annot* pAnnot)
+    : CFFL_FormFiller(pApp, pAnnot) {}
 
 CFFL_TextField::~CFFL_TextField() {
   for (const auto& it : m_Maps)
     it.second->InvalidateFocusHandler(this);
-  delete m_pFontMap;
+
+  // See comment in cffl_formfiller.h.
+  // The font map should be stored somewhere more appropriate so it will live
+  // until the PWL_Edit is done with it. pdfium:566
+  DestroyWindows();
 }
 
 PWL_CREATEPARAM CFFL_TextField::GetCreateParam() {
@@ -30,9 +35,6 @@
     cp.dwFlags |= PES_PASSWORD;
   }
 
-  if (!(nFlags & FIELDFLAG_DONOTSPELLCHECK)) {
-  }
-
   if (nFlags & FIELDFLAG_MULTILINE) {
     cp.dwFlags |= PES_MULTILINE | PES_AUTORETURN | PES_TOP;
 
@@ -70,9 +72,11 @@
       break;
   }
 
-  if (!m_pFontMap)
-    m_pFontMap = new CBA_FontMap(m_pWidget, m_pApp->GetSysHandler());
-  cp.pFontMap = m_pFontMap;
+  if (!m_pFontMap) {
+    m_pFontMap = pdfium::MakeUnique<CBA_FontMap>(
+        m_pWidget, m_pFormFillEnv->GetSysHandler());
+  }
+  cp.pFontMap = m_pFontMap.get();
   cp.pFocusHandler = this;
 
   return cp;
@@ -83,9 +87,7 @@
   CPWL_Edit* pWnd = new CPWL_Edit();
   pWnd->AttachFFLData(this);
   pWnd->Create(cp);
-
-  CFFL_IFormFiller* pIFormFiller = m_pApp->GetIFormFiller();
-  pWnd->SetFillerNotify(pIFormFiller);
+  pWnd->SetFillerNotify(m_pFormFillEnv->GetInteractiveFormFiller());
 
   int32_t nMaxLen = m_pWidget->GetMaxLen();
   CFX_WideString swValue = m_pWidget->GetValue();
@@ -99,60 +101,60 @@
     }
   }
 
-  pWnd->SetText(swValue.c_str());
+  pWnd->SetText(swValue);
   return pWnd;
 }
 
-FX_BOOL CFFL_TextField::OnChar(CPDFSDK_Annot* pAnnot,
-                               FX_UINT nChar,
-                               FX_UINT nFlags) {
+bool CFFL_TextField::OnChar(CPDFSDK_Annot* pAnnot,
+                            uint32_t nChar,
+                            uint32_t nFlags) {
   switch (nChar) {
     case FWL_VKEY_Return:
       if (!(m_pWidget->GetFieldFlags() & FIELDFLAG_MULTILINE)) {
-        CPDFSDK_PageView* pPageView = GetCurPageView();
+        CPDFSDK_PageView* pPageView = GetCurPageView(true);
         ASSERT(pPageView);
         m_bValid = !m_bValid;
-        CPDF_Rect rcAnnot = pAnnot->GetRect();
-        m_pApp->FFI_Invalidate(pAnnot->GetUnderlyingPage(), rcAnnot.left,
-                               rcAnnot.top, rcAnnot.right, rcAnnot.bottom);
+        CFX_FloatRect rcAnnot = pAnnot->GetRect();
+        m_pFormFillEnv->Invalidate(pAnnot->GetUnderlyingPage(), rcAnnot.left,
+                                   rcAnnot.top, rcAnnot.right, rcAnnot.bottom);
 
         if (m_bValid) {
-          if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, TRUE))
+          if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, true))
             pWnd->SetFocus();
         } else {
           if (CommitData(pPageView, nFlags)) {
             DestroyPDFWindow(pPageView);
-            return TRUE;
+            return true;
           }
-          return FALSE;
+          return false;
         }
       }
       break;
     case FWL_VKEY_Escape: {
-      CPDFSDK_PageView* pPageView = GetCurPageView();
+      CPDFSDK_PageView* pPageView = GetCurPageView(true);
       ASSERT(pPageView);
-      EscapeFiller(pPageView, TRUE);
-      return TRUE;
+      EscapeFiller(pPageView, true);
+      return true;
     }
   }
 
   return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
 }
 
-FX_BOOL CFFL_TextField::IsDataChanged(CPDFSDK_PageView* pPageView) {
-  if (CPWL_Edit* pEdit = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE))
+bool CFFL_TextField::IsDataChanged(CPDFSDK_PageView* pPageView) {
+  if (CPWL_Edit* pEdit = (CPWL_Edit*)GetPDFWindow(pPageView, false))
     return pEdit->GetText() != m_pWidget->GetValue();
 
-  return FALSE;
+  return false;
 }
 
 void CFFL_TextField::SaveData(CPDFSDK_PageView* pPageView) {
-  if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
+  if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, false)) {
     CFX_WideString sOldValue = m_pWidget->GetValue();
     CFX_WideString sNewValue = pWnd->GetText();
 
-    m_pWidget->SetValue(sNewValue, FALSE);
-    m_pWidget->ResetFieldAppearance(TRUE);
+    m_pWidget->SetValue(sNewValue, false);
+    m_pWidget->ResetFieldAppearance(true);
     m_pWidget->UpdateField();
     SetChangeMark();
   }
@@ -163,7 +165,7 @@
                                    PDFSDK_FieldAction& fa) {
   switch (type) {
     case CPDF_AAction::KeyStroke:
-      if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
+      if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, false)) {
         fa.bFieldFull = pWnd->IsTextFull();
 
         fa.sValue = pWnd->GetText();
@@ -175,7 +177,7 @@
       }
       break;
     case CPDF_AAction::Validate:
-      if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
+      if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, false)) {
         fa.sValue = pWnd->GetText();
       }
       break;
@@ -193,10 +195,10 @@
                                    const PDFSDK_FieldAction& fa) {
   switch (type) {
     case CPDF_AAction::KeyStroke:
-      if (CPWL_Edit* pEdit = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
+      if (CPWL_Edit* pEdit = (CPWL_Edit*)GetPDFWindow(pPageView, false)) {
         pEdit->SetFocus();
         pEdit->SetSel(fa.nSelStart, fa.nSelEnd);
-        pEdit->ReplaceSel(fa.sChange.c_str());
+        pEdit->ReplaceSel(fa.sChange);
       }
       break;
     default:
@@ -204,9 +206,9 @@
   }
 }
 
-FX_BOOL CFFL_TextField::IsActionDataChanged(CPDF_AAction::AActionType type,
-                                            const PDFSDK_FieldAction& faOld,
-                                            const PDFSDK_FieldAction& faNew) {
+bool CFFL_TextField::IsActionDataChanged(CPDF_AAction::AActionType type,
+                                         const PDFSDK_FieldAction& faOld,
+                                         const PDFSDK_FieldAction& faNew) {
   switch (type) {
     case CPDF_AAction::KeyStroke:
       return (!faOld.bFieldFull && faOld.nSelEnd != faNew.nSelEnd) ||
@@ -216,13 +218,13 @@
       break;
   }
 
-  return FALSE;
+  return false;
 }
 
 void CFFL_TextField::SaveState(CPDFSDK_PageView* pPageView) {
   ASSERT(pPageView);
 
-  if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
+  if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, false)) {
     pWnd->GetSel(m_State.nStart, m_State.nEnd);
     m_State.sValue = pWnd->GetText();
   }
@@ -231,26 +233,26 @@
 void CFFL_TextField::RestoreState(CPDFSDK_PageView* pPageView) {
   ASSERT(pPageView);
 
-  if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, TRUE)) {
-    pWnd->SetText(m_State.sValue.c_str());
+  if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, true)) {
+    pWnd->SetText(m_State.sValue);
     pWnd->SetSel(m_State.nStart, m_State.nEnd);
   }
 }
 
 CPWL_Wnd* CFFL_TextField::ResetPDFWindow(CPDFSDK_PageView* pPageView,
-                                         FX_BOOL bRestoreValue) {
+                                         bool bRestoreValue) {
   if (bRestoreValue)
     SaveState(pPageView);
 
   DestroyPDFWindow(pPageView);
 
-  CPWL_Wnd* pRet = NULL;
+  CPWL_Wnd* pRet = nullptr;
 
   if (bRestoreValue) {
     RestoreState(pPageView);
-    pRet = GetPDFWindow(pPageView, FALSE);
+    pRet = GetPDFWindow(pPageView, false);
   } else {
-    pRet = GetPDFWindow(pPageView, TRUE);
+    pRet = GetPDFWindow(pPageView, true);
   }
 
   m_pWidget->UpdateField();
@@ -259,20 +261,20 @@
 }
 
 #ifdef PDF_ENABLE_XFA
-FX_BOOL CFFL_TextField::IsFieldFull(CPDFSDK_PageView* pPageView) {
-  if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE)) {
+bool CFFL_TextField::IsFieldFull(CPDFSDK_PageView* pPageView) {
+  if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, false)) {
     return pWnd->IsTextFull();
   }
 
-  return FALSE;
+  return false;
 }
 #endif  // PDF_ENABLE_XFA
 
 void CFFL_TextField::OnSetFocus(CPWL_Wnd* pWnd) {
-  ASSERT(m_pApp);
+  ASSERT(m_pFormFillEnv);
   if (pWnd->GetClassName() == PWL_CLASSNAME_EDIT) {
     CPWL_Edit* pEdit = (CPWL_Edit*)pWnd;
-    pEdit->SetCharSet(134);
+    pEdit->SetCharSet(FXFONT_GB2312_CHARSET);
     pEdit->SetCodePage(936);
 
     pEdit->SetReadyToInput();
@@ -280,13 +282,6 @@
     int nCharacters = wsText.GetLength();
     CFX_ByteString bsUTFText = wsText.UTF16LE_Encode();
     unsigned short* pBuffer = (unsigned short*)bsUTFText.c_str();
-    m_pApp->FFI_OnSetFieldInputFocus(m_pWidget->GetFormField(), pBuffer,
-                                     nCharacters, TRUE);
-
-    pEdit->SetEditNotify(this);
+    m_pFormFillEnv->OnSetFieldInputFocus(pBuffer, nCharacters, true);
   }
 }
-
-void CFFL_TextField::OnKillFocus(CPWL_Wnd* pWnd) {}
-
-void CFFL_TextField::OnAddUndo(CPWL_Edit* pEdit) {}
diff --git a/fpdfsdk/formfiller/cffl_textfield.h b/fpdfsdk/formfiller/cffl_textfield.h
new file mode 100644
index 0000000..29579f7
--- /dev/null
+++ b/fpdfsdk/formfiller/cffl_textfield.h
@@ -0,0 +1,67 @@
+// 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_FORMFILLER_CFFL_TEXTFIELD_H_
+#define FPDFSDK_FORMFILLER_CFFL_TEXTFIELD_H_
+
+#include <memory>
+
+#include "fpdfsdk/formfiller/cffl_formfiller.h"
+
+#define BF_ALIGN_LEFT 0
+#define BF_ALIGN_MIDDLE 1
+#define BF_ALIGN_RIGHT 2
+
+class CBA_FontMap;
+
+struct FFL_TextFieldState {
+  FFL_TextFieldState() : nStart(0), nEnd(0) {}
+
+  int nStart;
+  int nEnd;
+  CFX_WideString sValue;
+};
+
+class CFFL_TextField : public CFFL_FormFiller, public IPWL_FocusHandler {
+ public:
+  CFFL_TextField(CPDFSDK_FormFillEnvironment* pApp, CPDFSDK_Annot* pAnnot);
+  ~CFFL_TextField() override;
+
+  // CFFL_FormFiller:
+  PWL_CREATEPARAM GetCreateParam() override;
+  CPWL_Wnd* NewPDFWindow(const PWL_CREATEPARAM& cp,
+                         CPDFSDK_PageView* pPageView) override;
+  bool OnChar(CPDFSDK_Annot* pAnnot, uint32_t nChar, uint32_t nFlags) override;
+  bool IsDataChanged(CPDFSDK_PageView* pPageView) override;
+  void SaveData(CPDFSDK_PageView* pPageView) override;
+  void GetActionData(CPDFSDK_PageView* pPageView,
+                     CPDF_AAction::AActionType type,
+                     PDFSDK_FieldAction& fa) override;
+  void SetActionData(CPDFSDK_PageView* pPageView,
+                     CPDF_AAction::AActionType type,
+                     const PDFSDK_FieldAction& fa) override;
+  bool IsActionDataChanged(CPDF_AAction::AActionType type,
+                           const PDFSDK_FieldAction& faOld,
+                           const PDFSDK_FieldAction& faNew) override;
+  void SaveState(CPDFSDK_PageView* pPageView) override;
+  void RestoreState(CPDFSDK_PageView* pPageView) override;
+  CPWL_Wnd* ResetPDFWindow(CPDFSDK_PageView* pPageView,
+                           bool bRestoreValue) override;
+
+  // IPWL_FocusHandler:
+  void OnSetFocus(CPWL_Wnd* pWnd) override;
+
+#ifdef PDF_ENABLE_XFA
+  // CFFL_FormFiller:
+  bool IsFieldFull(CPDFSDK_PageView* pPageView) override;
+#endif  // PDF_ENABLE_XFA
+
+ private:
+  std::unique_ptr<CBA_FontMap> m_pFontMap;
+  FFL_TextFieldState m_State;
+};
+
+#endif  // FPDFSDK_FORMFILLER_CFFL_TEXTFIELD_H_
diff --git a/fpdfsdk/fpdf_dataavail.cpp b/fpdfsdk/fpdf_dataavail.cpp
new file mode 100644
index 0000000..b1bc1e3
--- /dev/null
+++ b/fpdfsdk/fpdf_dataavail.cpp
@@ -0,0 +1,194 @@
+// 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
+
+#include "public/fpdf_dataavail.h"
+
+#include <memory>
+#include <utility>
+
+#include "core/fpdfapi/parser/cpdf_data_avail.h"
+#include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fxcrt/cfx_retain_ptr.h"
+#include "fpdfsdk/fsdk_define.h"
+#include "public/fpdf_formfill.h"
+#include "third_party/base/ptr_util.h"
+
+// These checks are here because core/ and public/ cannot depend on each other.
+static_assert(CPDF_DataAvail::DataError == PDF_DATA_ERROR,
+              "CPDF_DataAvail::DataError value mismatch");
+static_assert(CPDF_DataAvail::DataNotAvailable == PDF_DATA_NOTAVAIL,
+              "CPDF_DataAvail::DataNotAvailable value mismatch");
+static_assert(CPDF_DataAvail::DataAvailable == PDF_DATA_AVAIL,
+              "CPDF_DataAvail::DataAvailable value mismatch");
+
+static_assert(CPDF_DataAvail::LinearizationUnknown == PDF_LINEARIZATION_UNKNOWN,
+              "CPDF_DataAvail::LinearizationUnknown value mismatch");
+static_assert(CPDF_DataAvail::NotLinearized == PDF_NOT_LINEARIZED,
+              "CPDF_DataAvail::NotLinearized value mismatch");
+static_assert(CPDF_DataAvail::Linearized == PDF_LINEARIZED,
+              "CPDF_DataAvail::Linearized value mismatch");
+
+static_assert(CPDF_DataAvail::FormError == PDF_FORM_ERROR,
+              "CPDF_DataAvail::FormError value mismatch");
+static_assert(CPDF_DataAvail::FormNotAvailable == PDF_FORM_NOTAVAIL,
+              "CPDF_DataAvail::FormNotAvailable value mismatch");
+static_assert(CPDF_DataAvail::FormAvailable == PDF_FORM_AVAIL,
+              "CPDF_DataAvail::FormAvailable value mismatch");
+static_assert(CPDF_DataAvail::FormNotExist == PDF_FORM_NOTEXIST,
+              "CPDF_DataAvail::FormNotExist value mismatch");
+
+namespace {
+
+class CFPDF_FileAvailWrap : public CPDF_DataAvail::FileAvail {
+ public:
+  CFPDF_FileAvailWrap() : m_pfileAvail(nullptr) {}
+  ~CFPDF_FileAvailWrap() override {}
+
+  void Set(FX_FILEAVAIL* pfileAvail) { m_pfileAvail = pfileAvail; }
+
+  // CPDF_DataAvail::FileAvail:
+  bool IsDataAvail(FX_FILESIZE offset, uint32_t size) override {
+    return !!m_pfileAvail->IsDataAvail(m_pfileAvail, offset, size);
+  }
+
+ private:
+  FX_FILEAVAIL* m_pfileAvail;
+};
+
+class CFPDF_FileAccessWrap : public IFX_SeekableReadStream {
+ public:
+  static CFX_RetainPtr<CFPDF_FileAccessWrap> Create() {
+    return CFX_RetainPtr<CFPDF_FileAccessWrap>(new CFPDF_FileAccessWrap());
+  }
+  ~CFPDF_FileAccessWrap() override {}
+
+  void Set(FPDF_FILEACCESS* pFile) { m_pFileAccess = pFile; }
+
+  // IFX_SeekableReadStream
+  FX_FILESIZE GetSize() override { return m_pFileAccess->m_FileLen; }
+
+  bool ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override {
+    return !!m_pFileAccess->m_GetBlock(m_pFileAccess->m_Param, offset,
+                                       (uint8_t*)buffer, size);
+  }
+
+ private:
+  CFPDF_FileAccessWrap() : m_pFileAccess(nullptr) {}
+
+  FPDF_FILEACCESS* m_pFileAccess;
+};
+
+class CFPDF_DownloadHintsWrap : public CPDF_DataAvail::DownloadHints {
+ public:
+  explicit CFPDF_DownloadHintsWrap(FX_DOWNLOADHINTS* pDownloadHints) {
+    m_pDownloadHints = pDownloadHints;
+  }
+  ~CFPDF_DownloadHintsWrap() override {}
+
+ public:
+  // IFX_DownloadHints
+  void AddSegment(FX_FILESIZE offset, uint32_t size) override {
+    m_pDownloadHints->AddSegment(m_pDownloadHints, offset, size);
+  }
+
+ private:
+  FX_DOWNLOADHINTS* m_pDownloadHints;
+};
+
+class CFPDF_DataAvail {
+ public:
+  CFPDF_DataAvail()
+      : m_FileAvail(new CFPDF_FileAvailWrap),
+        m_FileRead(CFPDF_FileAccessWrap::Create()) {}
+  ~CFPDF_DataAvail() {}
+
+  std::unique_ptr<CPDF_DataAvail> m_pDataAvail;
+  std::unique_ptr<CFPDF_FileAvailWrap> m_FileAvail;
+  CFX_RetainPtr<CFPDF_FileAccessWrap> m_FileRead;
+};
+
+CFPDF_DataAvail* CFPDFDataAvailFromFPDFAvail(FPDF_AVAIL avail) {
+  return static_cast<CFPDF_DataAvail*>(avail);
+}
+
+}  // namespace
+
+DLLEXPORT FPDF_AVAIL STDCALL FPDFAvail_Create(FX_FILEAVAIL* file_avail,
+                                              FPDF_FILEACCESS* file) {
+  CFPDF_DataAvail* pAvail = new CFPDF_DataAvail;
+  pAvail->m_FileAvail->Set(file_avail);
+  pAvail->m_FileRead->Set(file);
+  pAvail->m_pDataAvail = pdfium::MakeUnique<CPDF_DataAvail>(
+      pAvail->m_FileAvail.get(), pAvail->m_FileRead, true);
+  return pAvail;
+}
+
+DLLEXPORT void STDCALL FPDFAvail_Destroy(FPDF_AVAIL avail) {
+  delete (CFPDF_DataAvail*)avail;
+}
+
+DLLEXPORT int STDCALL FPDFAvail_IsDocAvail(FPDF_AVAIL avail,
+                                           FX_DOWNLOADHINTS* hints) {
+  if (!avail || !hints)
+    return PDF_DATA_ERROR;
+  CFPDF_DownloadHintsWrap hints_wrap(hints);
+  return CFPDFDataAvailFromFPDFAvail(avail)->m_pDataAvail->IsDocAvail(
+      &hints_wrap);
+}
+
+DLLEXPORT FPDF_DOCUMENT STDCALL
+FPDFAvail_GetDocument(FPDF_AVAIL avail, FPDF_BYTESTRING password) {
+  CFPDF_DataAvail* pDataAvail = static_cast<CFPDF_DataAvail*>(avail);
+  if (!pDataAvail)
+    return nullptr;
+
+  std::unique_ptr<CPDF_Parser> pParser(new CPDF_Parser);
+  pParser->SetPassword(password);
+
+  std::unique_ptr<CPDF_Document> pDocument(
+      new CPDF_Document(std::move(pParser)));
+  CPDF_Parser::Error error = pDocument->GetParser()->StartLinearizedParse(
+      pDataAvail->m_pDataAvail->GetFileRead(), pDocument.get());
+  if (error != CPDF_Parser::SUCCESS) {
+    ProcessParseError(error);
+    return nullptr;
+  }
+  pDataAvail->m_pDataAvail->SetDocument(pDocument.get());
+  CheckUnSupportError(pDocument.get(), FPDF_ERR_SUCCESS);
+  return FPDFDocumentFromCPDFDocument(pDocument.release());
+}
+
+DLLEXPORT int STDCALL FPDFAvail_GetFirstPageNum(FPDF_DOCUMENT doc) {
+  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(doc);
+  return pDoc ? pDoc->GetParser()->GetFirstPageNo() : 0;
+}
+
+DLLEXPORT int STDCALL FPDFAvail_IsPageAvail(FPDF_AVAIL avail,
+                                            int page_index,
+                                            FX_DOWNLOADHINTS* hints) {
+  if (!avail || !hints)
+    return PDF_DATA_ERROR;
+  if (page_index < 0)
+    return PDF_DATA_NOTAVAIL;
+  CFPDF_DownloadHintsWrap hints_wrap(hints);
+  return CFPDFDataAvailFromFPDFAvail(avail)->m_pDataAvail->IsPageAvail(
+      page_index, &hints_wrap);
+}
+
+DLLEXPORT int STDCALL FPDFAvail_IsFormAvail(FPDF_AVAIL avail,
+                                            FX_DOWNLOADHINTS* hints) {
+  if (!avail || !hints)
+    return PDF_FORM_ERROR;
+  CFPDF_DownloadHintsWrap hints_wrap(hints);
+  return CFPDFDataAvailFromFPDFAvail(avail)->m_pDataAvail->IsFormAvail(
+      &hints_wrap);
+}
+
+DLLEXPORT int STDCALL FPDFAvail_IsLinearized(FPDF_AVAIL avail) {
+  if (!avail)
+    return PDF_LINEARIZATION_UNKNOWN;
+  return CFPDFDataAvailFromFPDFAvail(avail)->m_pDataAvail->IsLinearizedPDF();
+}
diff --git a/fpdfsdk/fpdf_dataavail_embeddertest.cpp b/fpdfsdk/fpdf_dataavail_embeddertest.cpp
new file mode 100644
index 0000000..c226a31
--- /dev/null
+++ b/fpdfsdk/fpdf_dataavail_embeddertest.cpp
@@ -0,0 +1,240 @@
+// Copyright 2015 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.
+
+#include <algorithm>
+#include <memory>
+#include <set>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "public/fpdfview.h"
+#include "testing/embedder_test.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/test_support.h"
+#include "testing/utils/path_service.h"
+
+namespace {
+class TestAsyncLoader : public FX_DOWNLOADHINTS, FX_FILEAVAIL {
+ public:
+  explicit TestAsyncLoader(const std::string& file_name) {
+    std::string file_path;
+    if (!PathService::GetTestFilePath(file_name, &file_path))
+      return;
+    file_contents_ = GetFileContents(file_path.c_str(), &file_length_);
+    if (!file_contents_)
+      return;
+
+    file_access_.m_FileLen = static_cast<unsigned long>(file_length_);
+    file_access_.m_GetBlock = SGetBlock;
+    file_access_.m_Param = this;
+
+    FX_DOWNLOADHINTS::version = 1;
+    FX_DOWNLOADHINTS::AddSegment = SAddSegment;
+
+    FX_FILEAVAIL::version = 1;
+    FX_FILEAVAIL::IsDataAvail = SIsDataAvail;
+  }
+
+  bool IsOpened() const { return !!file_contents_; }
+
+  FPDF_FILEACCESS* file_access() { return &file_access_; }
+  FX_DOWNLOADHINTS* hints() { return this; }
+  FX_FILEAVAIL* file_avail() { return this; }
+
+  const std::vector<std::pair<size_t, size_t>>& requested_segments() const {
+    return requested_segments_;
+  }
+
+  size_t max_requested_bound() const { return max_requested_bound_; }
+
+  void ClearRequestedSegments() {
+    requested_segments_.clear();
+    max_requested_bound_ = 0;
+  }
+
+  bool is_new_data_available() const { return is_new_data_available_; }
+  void set_is_new_data_available(bool is_new_data_available) {
+    is_new_data_available_ = is_new_data_available;
+  }
+
+  size_t max_already_available_bound() const {
+    return available_ranges_.empty() ? 0 : available_ranges_.rbegin()->second;
+  }
+
+ private:
+  void SetDataAvailable(size_t start, size_t size) {
+    if (size == 0)
+      return;
+    const auto range = std::make_pair(start, start + size);
+    if (available_ranges_.empty()) {
+      available_ranges_.insert(range);
+      return;
+    }
+    auto start_it = available_ranges_.upper_bound(range);
+    if (start_it != available_ranges_.begin())
+      --start_it;  // start now points to the key equal or lower than offset.
+    if (start_it->second < range.first)
+      ++start_it;  // start element is entirely before current range, skip it.
+
+    auto end_it = available_ranges_.upper_bound(
+        std::make_pair(range.second, range.second));
+    if (start_it == end_it) {  // No ranges to merge.
+      available_ranges_.insert(range);
+      return;
+    }
+
+    --end_it;
+
+    size_t new_start = std::min<size_t>(start_it->first, range.first);
+    size_t new_end = std::max(end_it->second, range.second);
+
+    available_ranges_.erase(start_it, ++end_it);
+    available_ranges_.insert(std::make_pair(new_start, new_end));
+  }
+
+  bool CheckDataAlreadyAvailable(size_t start, size_t size) const {
+    if (size == 0)
+      return false;
+    const auto range = std::make_pair(start, start + size);
+    auto it = available_ranges_.upper_bound(range);
+    if (it == available_ranges_.begin())
+      return false;  // No ranges includes range.start().
+
+    --it;  // Now it starts equal or before range.start().
+    return it->second >= range.second;
+  }
+
+  int GetBlockImpl(unsigned long pos, unsigned char* pBuf, unsigned long size) {
+    if (!IsDataAvailImpl(pos, size))
+      return 0;
+    const unsigned long end =
+        std::min(static_cast<unsigned long>(file_length_), pos + size);
+    if (end <= pos)
+      return 0;
+    memcpy(pBuf, file_contents_.get() + pos, end - pos);
+    SetDataAvailable(pos, end - pos);
+    return static_cast<int>(end - pos);
+  }
+
+  void AddSegmentImpl(size_t offset, size_t size) {
+    requested_segments_.push_back(std::make_pair(offset, size));
+    max_requested_bound_ = std::max(max_requested_bound_, offset + size);
+  }
+
+  bool IsDataAvailImpl(size_t offset, size_t size) {
+    if (offset + size > file_length_)
+      return false;
+    if (is_new_data_available_) {
+      SetDataAvailable(offset, size);
+      return true;
+    }
+    return CheckDataAlreadyAvailable(offset, size);
+  }
+
+  static int SGetBlock(void* param,
+                       unsigned long pos,
+                       unsigned char* pBuf,
+                       unsigned long size) {
+    return static_cast<TestAsyncLoader*>(param)->GetBlockImpl(pos, pBuf, size);
+  }
+
+  static void SAddSegment(FX_DOWNLOADHINTS* pThis, size_t offset, size_t size) {
+    return static_cast<TestAsyncLoader*>(pThis)->AddSegmentImpl(offset, size);
+  }
+
+  static FPDF_BOOL SIsDataAvail(FX_FILEAVAIL* pThis,
+                                size_t offset,
+                                size_t size) {
+    return static_cast<TestAsyncLoader*>(pThis)->IsDataAvailImpl(offset, size);
+  }
+
+  FPDF_FILEACCESS file_access_;
+
+  std::unique_ptr<char, pdfium::FreeDeleter> file_contents_;
+  size_t file_length_;
+  std::vector<std::pair<size_t, size_t>> requested_segments_;
+  size_t max_requested_bound_ = 0;
+  bool is_new_data_available_ = true;
+
+  using Range = std::pair<size_t, size_t>;
+  struct range_compare {
+    bool operator()(const Range& lval, const Range& rval) const {
+      return lval.first < rval.first;
+    }
+  };
+  using RangesContainer = std::set<Range, range_compare>;
+  RangesContainer available_ranges_;
+};
+
+}  // namespace
+
+class FPDFDataAvailEmbeddertest : public EmbedderTest {};
+
+TEST_F(FPDFDataAvailEmbeddertest, TrailerUnterminated) {
+  // Document must load without crashing but is too malformed to be available.
+  EXPECT_FALSE(OpenDocument("trailer_unterminated.pdf"));
+  EXPECT_FALSE(FPDFAvail_IsDocAvail(avail_, &hints_));
+}
+
+TEST_F(FPDFDataAvailEmbeddertest, TrailerAsHexstring) {
+  // Document must load without crashing but is too malformed to be available.
+  EXPECT_FALSE(OpenDocument("trailer_as_hexstring.pdf"));
+  EXPECT_FALSE(FPDFAvail_IsDocAvail(avail_, &hints_));
+}
+
+TEST_F(FPDFDataAvailEmbeddertest, LoadUsingHintTables) {
+  TestAsyncLoader loader("feature_linearized_loading.pdf");
+  avail_ = FPDFAvail_Create(loader.file_avail(), loader.file_access());
+  ASSERT_EQ(PDF_DATA_AVAIL, FPDFAvail_IsDocAvail(avail_, loader.hints()));
+  document_ = FPDFAvail_GetDocument(avail_, nullptr);
+  ASSERT_TRUE(document_);
+  ASSERT_EQ(PDF_DATA_AVAIL, FPDFAvail_IsPageAvail(avail_, 1, loader.hints()));
+
+  // No new data available, to prevent load "Pages" node.
+  loader.set_is_new_data_available(false);
+  FPDF_PAGE page = LoadPage(1);
+  EXPECT_TRUE(page);
+  UnloadPage(page);
+}
+
+TEST_F(FPDFDataAvailEmbeddertest,
+       DoNotLoadMainCrossRefForFirstPageIfLinearized) {
+  TestAsyncLoader loader("feature_linearized_loading.pdf");
+  avail_ = FPDFAvail_Create(loader.file_avail(), loader.file_access());
+  ASSERT_EQ(PDF_DATA_AVAIL, FPDFAvail_IsDocAvail(avail_, loader.hints()));
+  document_ = FPDFAvail_GetDocument(avail_, nullptr);
+  ASSERT_TRUE(document_);
+  const int first_page_num = FPDFAvail_GetFirstPageNum(document_);
+
+  // The main cross ref table should not be processed.
+  // (It is always at file end)
+  EXPECT_GT(loader.file_access()->m_FileLen,
+            loader.max_already_available_bound());
+
+  // Prevent access to non requested data to coerce the parser to send new
+  // request for non available (non requested before) data.
+  loader.set_is_new_data_available(false);
+  FPDFAvail_IsPageAvail(avail_, first_page_num, loader.hints());
+
+  // The main cross ref table should not be requested.
+  // (It is always at file end)
+  EXPECT_GT(loader.file_access()->m_FileLen, loader.max_requested_bound());
+
+  // Allow parse page.
+  loader.set_is_new_data_available(true);
+  ASSERT_EQ(PDF_DATA_AVAIL,
+            FPDFAvail_IsPageAvail(avail_, first_page_num, loader.hints()));
+
+  // The main cross ref table should not be processed.
+  // (It is always at file end)
+  EXPECT_GT(loader.file_access()->m_FileLen,
+            loader.max_already_available_bound());
+
+  // Prevent loading data, while page loading.
+  loader.set_is_new_data_available(false);
+  FPDF_PAGE page = LoadPage(first_page_num);
+  EXPECT_TRUE(page);
+  UnloadPage(page);
+}
diff --git a/fpdfsdk/src/fpdf_ext.cpp b/fpdfsdk/fpdf_ext.cpp
similarity index 60%
rename from fpdfsdk/src/fpdf_ext.cpp
rename to fpdfsdk/fpdf_ext.cpp
index c83464e..3bcb0c0 100644
--- a/fpdfsdk/src/fpdf_ext.cpp
+++ b/fpdfsdk/fpdf_ext.cpp
@@ -6,93 +6,76 @@
 
 #include "public/fpdf_ext.h"
 
-#include "core/include/fxcrt/fx_xml.h"
-#include "fpdfsdk/include/fsdk_define.h"
+#include <memory>
+
+#include "core/fpdfapi/cpdf_modulemgr.h"
+#include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfdoc/cpdf_annot.h"
+#include "core/fpdfdoc/cpdf_interform.h"
+#include "core/fpdfdoc/cpdf_metadata.h"
+#include "core/fxcrt/fx_basic.h"
+#include "core/fxcrt/fx_memory.h"
+#include "core/fxcrt/fx_xml.h"
+#include "fpdfsdk/fsdk_define.h"
+#include "third_party/base/ptr_util.h"
 
 #ifdef PDF_ENABLE_XFA
-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h"
+#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
 #endif  // PDF_ENABLE_XFA
 
-#define FPDFSDK_UNSUPPORT_CALL 100
-
-class CFSDK_UnsupportInfo_Adapter {
- public:
-  CFSDK_UnsupportInfo_Adapter(UNSUPPORT_INFO* unsp_info) {
-    m_unsp_info = unsp_info;
-  }
-  void ReportError(int nErrorType);
-
- private:
-  UNSUPPORT_INFO* m_unsp_info;
-};
-
-void CFSDK_UnsupportInfo_Adapter::ReportError(int nErrorType) {
-  if (m_unsp_info && m_unsp_info->FSDK_UnSupport_Handler) {
-    m_unsp_info->FSDK_UnSupport_Handler(m_unsp_info, nErrorType);
-  }
-}
-
-void FreeUnsupportInfo(void* pData) {
-  CFSDK_UnsupportInfo_Adapter* pAdapter = (CFSDK_UnsupportInfo_Adapter*)pData;
-  delete pAdapter;
-}
-
-FX_BOOL FPDF_UnSupportError(int nError) {
+bool FPDF_UnSupportError(int nError) {
   CFSDK_UnsupportInfo_Adapter* pAdapter =
-      (CFSDK_UnsupportInfo_Adapter*)CPDF_ModuleMgr::Get()->GetPrivateData(
-          (void*)FPDFSDK_UNSUPPORT_CALL);
-
+      CPDF_ModuleMgr::Get()->GetUnsupportInfoAdapter();
   if (!pAdapter)
-    return FALSE;
-  pAdapter->ReportError(nError);
-  return TRUE;
+    return false;
+
+  UNSUPPORT_INFO* info = static_cast<UNSUPPORT_INFO*>(pAdapter->GetUnspInfo());
+  if (info && info->FSDK_UnSupport_Handler)
+    info->FSDK_UnSupport_Handler(info, nError);
+  return true;
 }
 
 DLLEXPORT FPDF_BOOL STDCALL
 FSDK_SetUnSpObjProcessHandler(UNSUPPORT_INFO* unsp_info) {
   if (!unsp_info || unsp_info->version != 1)
-    return FALSE;
-  CFSDK_UnsupportInfo_Adapter* pAdapter =
-      new CFSDK_UnsupportInfo_Adapter(unsp_info);
+    return false;
 
-  CPDF_ModuleMgr::Get()->SetPrivateData((void*)FPDFSDK_UNSUPPORT_CALL, pAdapter,
-                                        &FreeUnsupportInfo);
-
-  return TRUE;
+  CPDF_ModuleMgr::Get()->SetUnsupportInfoAdapter(
+      pdfium::MakeUnique<CFSDK_UnsupportInfo_Adapter>(unsp_info));
+  return true;
 }
 
 void CheckUnSupportAnnot(CPDF_Document* pDoc, const CPDF_Annot* pPDFAnnot) {
-  CFX_ByteString cbSubType = pPDFAnnot->GetSubType();
-  if (cbSubType.Compare("3D") == 0) {
+  CPDF_Annot::Subtype nAnnotSubtype = pPDFAnnot->GetSubtype();
+  if (nAnnotSubtype == CPDF_Annot::Subtype::THREED) {
     FPDF_UnSupportError(FPDF_UNSP_ANNOT_3DANNOT);
-  } else if (cbSubType.Compare("Screen") == 0) {
+  } else if (nAnnotSubtype == CPDF_Annot::Subtype::SCREEN) {
     const CPDF_Dictionary* pAnnotDict = pPDFAnnot->GetAnnotDict();
     CFX_ByteString cbString;
     if (pAnnotDict->KeyExist("IT"))
-      cbString = pAnnotDict->GetString("IT");
+      cbString = pAnnotDict->GetStringFor("IT");
     if (cbString.Compare("Img") != 0)
       FPDF_UnSupportError(FPDF_UNSP_ANNOT_SCREEN_MEDIA);
-  } else if (cbSubType.Compare("Movie") == 0) {
+  } else if (nAnnotSubtype == CPDF_Annot::Subtype::MOVIE) {
     FPDF_UnSupportError(FPDF_UNSP_ANNOT_MOVIE);
-  } else if (cbSubType.Compare("Sound") == 0) {
+  } else if (nAnnotSubtype == CPDF_Annot::Subtype::SOUND) {
     FPDF_UnSupportError(FPDF_UNSP_ANNOT_SOUND);
-  } else if (cbSubType.Compare("RichMedia") == 0) {
+  } else if (nAnnotSubtype == CPDF_Annot::Subtype::RICHMEDIA) {
     FPDF_UnSupportError(FPDF_UNSP_ANNOT_SCREEN_RICHMEDIA);
-  } else if (cbSubType.Compare("FileAttachment") == 0) {
+  } else if (nAnnotSubtype == CPDF_Annot::Subtype::FILEATTACHMENT) {
     FPDF_UnSupportError(FPDF_UNSP_ANNOT_ATTACHMENT);
-  } else if (cbSubType.Compare("Widget") == 0) {
+  } else if (nAnnotSubtype == CPDF_Annot::Subtype::WIDGET) {
     const CPDF_Dictionary* pAnnotDict = pPDFAnnot->GetAnnotDict();
     CFX_ByteString cbString;
-    if (pAnnotDict->KeyExist("FT")) {
-      cbString = pAnnotDict->GetString("FT");
-    }
-    if (cbString.Compare("Sig") == 0) {
+    if (pAnnotDict->KeyExist("FT"))
+      cbString = pAnnotDict->GetStringFor("FT");
+    if (cbString.Compare("Sig") == 0)
       FPDF_UnSupportError(FPDF_UNSP_ANNOT_SIG);
-    }
   }
 }
 
-FX_BOOL CheckSharedForm(const CXML_Element* pElement, CFX_ByteString cbName) {
+bool CheckSharedForm(const CXML_Element* pElement, CFX_ByteString cbName) {
   int count = pElement->CountAttrs();
   int i = 0;
   for (i = 0; i < count; i++) {
@@ -101,10 +84,11 @@
     pElement->GetAttrByIndex(i, space, name, value);
     if (space == "xmlns" && name == "adhocwf" &&
         value == L"http://ns.adobe.com/AcrobatAdhocWorkflow/1.0/") {
-      CXML_Element* pVersion = pElement->GetElement("adhocwf", cbName);
+      CXML_Element* pVersion =
+          pElement->GetElement("adhocwf", cbName.AsStringC());
       if (!pVersion)
         continue;
-      CFX_WideString wsContent = pVersion->GetContent(0);  // == 1.1
+      CFX_WideString wsContent = pVersion->GetContent(0);
       int nType = wsContent.GetInteger();
       switch (nType) {
         case 1:
@@ -120,19 +104,19 @@
     }
   }
 
-  FX_DWORD nCount = pElement->CountChildren();
+  uint32_t nCount = pElement->CountChildren();
   for (i = 0; i < (int)nCount; i++) {
     CXML_Element::ChildType childType = pElement->GetChildType(i);
     if (childType == CXML_Element::Element) {
       CXML_Element* pChild = pElement->GetElement(i);
       if (CheckSharedForm(pChild, cbName))
-        return TRUE;
+        return true;
     }
   }
-  return FALSE;
+  return false;
 }
 
-void CheckUnSupportError(CPDF_Document* pDoc, FX_DWORD err_code) {
+void CheckUnSupportError(CPDF_Document* pDoc, uint32_t err_code) {
   // Security
   if (err_code == FPDF_ERR_SECURITY) {
     FPDF_UnSupportError(FPDF_UNSP_DOC_SECURITY);
@@ -150,18 +134,17 @@
       return;
     }
     if (pRootDict->KeyExist("Names")) {
-      CPDF_Dictionary* pNameDict = pRootDict->GetDict("Names");
+      CPDF_Dictionary* pNameDict = pRootDict->GetDictFor("Names");
       if (pNameDict && pNameDict->KeyExist("EmbeddedFiles")) {
         FPDF_UnSupportError(FPDF_UNSP_DOC_ATTACHMENT);
         return;
       }
       if (pNameDict && pNameDict->KeyExist("JavaScript")) {
-        CPDF_Dictionary* pJSDict = pNameDict->GetDict("JavaScript");
-        CPDF_Array* pArray = pJSDict ? pJSDict->GetArray("Names") : NULL;
+        CPDF_Dictionary* pJSDict = pNameDict->GetDictFor("JavaScript");
+        CPDF_Array* pArray = pJSDict ? pJSDict->GetArrayFor("Names") : nullptr;
         if (pArray) {
-          int nCount = pArray->GetCount();
-          for (int i = 0; i < nCount; i++) {
-            CFX_ByteString cbStr = pArray->GetString(i);
+          for (size_t i = 0; i < pArray->GetCount(); i++) {
+            CFX_ByteString cbStr = pArray->GetStringAt(i);
             if (cbStr.Compare("com.adobe.acrobat.SharedReview.Register") == 0) {
               FPDF_UnSupportError(FPDF_UNSP_DOC_SHAREDREVIEW);
               return;
@@ -180,15 +163,13 @@
 
 #ifndef PDF_ENABLE_XFA
   // XFA Forms
-  CPDF_InterForm* pInterForm = new CPDF_InterForm(pDoc, FALSE);
-  if (pInterForm->HasXFAForm()) {
+  CPDF_InterForm interform(pDoc);
+  if (interform.HasXFAForm())
     FPDF_UnSupportError(FPDF_UNSP_DOC_XFAFORM);
-  }
-  delete pInterForm;
 #endif  // PDF_ENABLE_XFA
 }
 
-DLLEXPORT int FPDFDoc_GetPageMode(FPDF_DOCUMENT document) {
+DLLEXPORT int STDCALL FPDFDoc_GetPageMode(FPDF_DOCUMENT document) {
   CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
   if (!pDoc)
     return PAGEMODE_UNKNOWN;
@@ -197,7 +178,7 @@
   if (!pRoot)
     return PAGEMODE_UNKNOWN;
 
-  CPDF_Object* pName = pRoot->GetElement("PageMode");
+  CPDF_Object* pName = pRoot->GetObjectFor("PageMode");
   if (!pName)
     return PAGEMODE_USENONE;
 
diff --git a/fpdfsdk/fpdf_flatten.cpp b/fpdfsdk/fpdf_flatten.cpp
new file mode 100644
index 0000000..e649bac
--- /dev/null
+++ b/fpdfsdk/fpdf_flatten.cpp
@@ -0,0 +1,429 @@
+// 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
+
+#include "public/fpdf_flatten.h"
+
+#include <algorithm>
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "core/fpdfapi/page/cpdf_page.h"
+#include "core/fpdfapi/page/cpdf_pageobject.h"
+#include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/cpdf_name.h"
+#include "core/fpdfapi/parser/cpdf_number.h"
+#include "core/fpdfapi/parser/cpdf_reference.h"
+#include "core/fpdfapi/parser/cpdf_stream.h"
+#include "core/fpdfapi/parser/cpdf_stream_acc.h"
+#include "core/fpdfdoc/cpdf_annot.h"
+#include "fpdfsdk/fsdk_define.h"
+#include "third_party/base/stl_util.h"
+
+enum FPDF_TYPE { MAX, MIN };
+enum FPDF_VALUE { TOP, LEFT, RIGHT, BOTTOM };
+
+namespace {
+
+bool IsValiableRect(CFX_FloatRect rect, CFX_FloatRect rcPage) {
+  if (rect.left - rect.right > 0.000001f || rect.bottom - rect.top > 0.000001f)
+    return false;
+
+  if (rect.left == 0.0f && rect.top == 0.0f && rect.right == 0.0f &&
+      rect.bottom == 0.0f)
+    return false;
+
+  if (!rcPage.IsEmpty()) {
+    if (rect.left - rcPage.left < -10.000001f ||
+        rect.right - rcPage.right > 10.000001f ||
+        rect.top - rcPage.top > 10.000001f ||
+        rect.bottom - rcPage.bottom < -10.000001f)
+      return false;
+  }
+
+  return true;
+}
+
+void GetContentsRect(CPDF_Document* pDoc,
+                     CPDF_Dictionary* pDict,
+                     std::vector<CFX_FloatRect>* pRectArray) {
+  std::unique_ptr<CPDF_Page> pPDFPage(new CPDF_Page(pDoc, pDict, false));
+  pPDFPage->ParseContent();
+
+  for (const auto& pPageObject : *pPDFPage->GetPageObjectList()) {
+    CFX_FloatRect rc;
+    rc.left = pPageObject->m_Left;
+    rc.right = pPageObject->m_Right;
+    rc.bottom = pPageObject->m_Bottom;
+    rc.top = pPageObject->m_Top;
+    if (IsValiableRect(rc, pDict->GetRectFor("MediaBox")))
+      pRectArray->push_back(rc);
+  }
+}
+
+void ParserStream(CPDF_Dictionary* pPageDic,
+                  CPDF_Dictionary* pStream,
+                  std::vector<CFX_FloatRect>* pRectArray,
+                  std::vector<CPDF_Dictionary*>* pObjectArray) {
+  if (!pStream)
+    return;
+  CFX_FloatRect rect;
+  if (pStream->KeyExist("Rect"))
+    rect = pStream->GetRectFor("Rect");
+  else if (pStream->KeyExist("BBox"))
+    rect = pStream->GetRectFor("BBox");
+
+  if (IsValiableRect(rect, pPageDic->GetRectFor("MediaBox")))
+    pRectArray->push_back(rect);
+
+  pObjectArray->push_back(pStream);
+}
+
+int ParserAnnots(CPDF_Document* pSourceDoc,
+                 CPDF_Dictionary* pPageDic,
+                 std::vector<CFX_FloatRect>* pRectArray,
+                 std::vector<CPDF_Dictionary*>* pObjectArray,
+                 int nUsage) {
+  if (!pSourceDoc || !pPageDic)
+    return FLATTEN_FAIL;
+
+  GetContentsRect(pSourceDoc, pPageDic, pRectArray);
+  CPDF_Array* pAnnots = pPageDic->GetArrayFor("Annots");
+  if (!pAnnots)
+    return FLATTEN_NOTHINGTODO;
+
+  uint32_t dwSize = pAnnots->GetCount();
+  for (int i = 0; i < (int)dwSize; i++) {
+    CPDF_Dictionary* pAnnotDic = ToDictionary(pAnnots->GetDirectObjectAt(i));
+    if (!pAnnotDic)
+      continue;
+
+    CFX_ByteString sSubtype = pAnnotDic->GetStringFor("Subtype");
+    if (sSubtype == "Popup")
+      continue;
+
+    int nAnnotFlag = pAnnotDic->GetIntegerFor("F");
+    if (nAnnotFlag & ANNOTFLAG_HIDDEN)
+      continue;
+
+    if (nUsage == FLAT_NORMALDISPLAY) {
+      if (nAnnotFlag & ANNOTFLAG_INVISIBLE)
+        continue;
+
+      ParserStream(pPageDic, pAnnotDic, pRectArray, pObjectArray);
+    } else {
+      if (nAnnotFlag & ANNOTFLAG_PRINT)
+        ParserStream(pPageDic, pAnnotDic, pRectArray, pObjectArray);
+    }
+  }
+  return FLATTEN_SUCCESS;
+}
+
+FX_FLOAT GetMinMaxValue(const std::vector<CFX_FloatRect>& array,
+                        FPDF_TYPE type,
+                        FPDF_VALUE value) {
+  size_t nRects = array.size();
+  if (nRects <= 0)
+    return 0.0f;
+
+  std::vector<FX_FLOAT> pArray(nRects);
+  switch (value) {
+    case LEFT:
+      for (size_t i = 0; i < nRects; i++)
+        pArray[i] = array[i].left;
+      break;
+    case TOP:
+      for (size_t i = 0; i < nRects; i++)
+        pArray[i] = array[i].top;
+      break;
+    case RIGHT:
+      for (size_t i = 0; i < nRects; i++)
+        pArray[i] = array[i].right;
+      break;
+    case BOTTOM:
+      for (size_t i = 0; i < nRects; i++)
+        pArray[i] = array[i].bottom;
+      break;
+    default:
+      // Not reachable.
+      return 0.0f;
+  }
+
+  FX_FLOAT fRet = pArray[0];
+  if (type == MAX) {
+    for (size_t i = 1; i < nRects; i++)
+      fRet = std::max(fRet, pArray[i]);
+  } else {
+    for (size_t i = 1; i < nRects; i++)
+      fRet = std::min(fRet, pArray[i]);
+  }
+  return fRet;
+}
+
+CFX_FloatRect CalculateRect(std::vector<CFX_FloatRect>* pRectArray) {
+  CFX_FloatRect rcRet;
+
+  rcRet.left = GetMinMaxValue(*pRectArray, MIN, LEFT);
+  rcRet.top = GetMinMaxValue(*pRectArray, MAX, TOP);
+  rcRet.right = GetMinMaxValue(*pRectArray, MAX, RIGHT);
+  rcRet.bottom = GetMinMaxValue(*pRectArray, MIN, BOTTOM);
+
+  return rcRet;
+}
+
+uint32_t NewIndirectContentsStream(const CFX_ByteString& key,
+                                   CPDF_Document* pDocument) {
+  CPDF_Stream* pNewContents = pDocument->NewIndirect<CPDF_Stream>(
+      nullptr, 0,
+      pdfium::MakeUnique<CPDF_Dictionary>(pDocument->GetByteStringPool()));
+  CFX_ByteString sStream;
+  sStream.Format("q 1 0 0 1 0 0 cm /%s Do Q", key.c_str());
+  pNewContents->SetData(sStream.raw_str(), sStream.GetLength());
+  return pNewContents->GetObjNum();
+}
+
+void SetPageContents(const CFX_ByteString& key,
+                     CPDF_Dictionary* pPage,
+                     CPDF_Document* pDocument) {
+  CPDF_Array* pContentsArray = nullptr;
+  CPDF_Stream* pContentsStream = pPage->GetStreamFor("Contents");
+  if (!pContentsStream) {
+    pContentsArray = pPage->GetArrayFor("Contents");
+    if (!pContentsArray) {
+      if (!key.IsEmpty()) {
+        pPage->SetNewFor<CPDF_Reference>(
+            "Contents", pDocument, NewIndirectContentsStream(key, pDocument));
+      }
+      return;
+    }
+  }
+  pPage->ConvertToIndirectObjectFor("Contents", pDocument);
+  if (!pContentsArray) {
+    pContentsArray = pDocument->NewIndirect<CPDF_Array>();
+    CPDF_StreamAcc acc;
+    acc.LoadAllData(pContentsStream);
+    CFX_ByteString sStream = "q\n";
+    CFX_ByteString sBody =
+        CFX_ByteString((const FX_CHAR*)acc.GetData(), acc.GetSize());
+    sStream = sStream + sBody + "\nQ";
+    pContentsStream->SetData(sStream.raw_str(), sStream.GetLength());
+    pContentsArray->AddNew<CPDF_Reference>(pDocument,
+                                           pContentsStream->GetObjNum());
+    pPage->SetNewFor<CPDF_Reference>("Contents", pDocument,
+                                     pContentsArray->GetObjNum());
+  }
+  if (!key.IsEmpty()) {
+    pContentsArray->AddNew<CPDF_Reference>(
+        pDocument, NewIndirectContentsStream(key, pDocument));
+  }
+}
+
+CFX_Matrix GetMatrix(CFX_FloatRect rcAnnot,
+                     CFX_FloatRect rcStream,
+                     const CFX_Matrix& matrix) {
+  if (rcStream.IsEmpty())
+    return CFX_Matrix();
+
+  matrix.TransformRect(rcStream);
+  rcStream.Normalize();
+
+  FX_FLOAT a = rcAnnot.Width() / rcStream.Width();
+  FX_FLOAT d = rcAnnot.Height() / rcStream.Height();
+
+  FX_FLOAT e = rcAnnot.left - rcStream.left * a;
+  FX_FLOAT f = rcAnnot.bottom - rcStream.bottom * d;
+  return CFX_Matrix(a, 0, 0, d, e, f);
+}
+
+}  // namespace
+
+DLLEXPORT int STDCALL FPDFPage_Flatten(FPDF_PAGE page, int nFlag) {
+  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
+  if (!page)
+    return FLATTEN_FAIL;
+
+  CPDF_Document* pDocument = pPage->m_pDocument;
+  CPDF_Dictionary* pPageDict = pPage->m_pFormDict;
+  if (!pDocument || !pPageDict)
+    return FLATTEN_FAIL;
+
+  std::vector<CPDF_Dictionary*> ObjectArray;
+  std::vector<CFX_FloatRect> RectArray;
+  int iRet =
+      ParserAnnots(pDocument, pPageDict, &RectArray, &ObjectArray, nFlag);
+  if (iRet == FLATTEN_NOTHINGTODO || iRet == FLATTEN_FAIL)
+    return iRet;
+
+  CFX_FloatRect rcOriginalCB;
+  CFX_FloatRect rcMerger = CalculateRect(&RectArray);
+  CFX_FloatRect rcOriginalMB = pPageDict->GetRectFor("MediaBox");
+  if (pPageDict->KeyExist("CropBox"))
+    rcOriginalMB = pPageDict->GetRectFor("CropBox");
+
+  if (rcOriginalMB.IsEmpty())
+    rcOriginalMB = CFX_FloatRect(0.0f, 0.0f, 612.0f, 792.0f);
+
+  rcMerger.left = std::max(rcMerger.left, rcOriginalMB.left);
+  rcMerger.right = std::min(rcMerger.right, rcOriginalMB.right);
+  rcMerger.bottom = std::max(rcMerger.bottom, rcOriginalMB.bottom);
+  rcMerger.top = std::min(rcMerger.top, rcOriginalMB.top);
+  if (pPageDict->KeyExist("ArtBox"))
+    rcOriginalCB = pPageDict->GetRectFor("ArtBox");
+  else
+    rcOriginalCB = rcOriginalMB;
+
+  if (!rcOriginalMB.IsEmpty()) {
+    CPDF_Array* pMediaBox = pPageDict->SetNewFor<CPDF_Array>("MediaBox");
+    pMediaBox->AddNew<CPDF_Number>(rcOriginalMB.left);
+    pMediaBox->AddNew<CPDF_Number>(rcOriginalMB.bottom);
+    pMediaBox->AddNew<CPDF_Number>(rcOriginalMB.right);
+    pMediaBox->AddNew<CPDF_Number>(rcOriginalMB.top);
+  }
+
+  if (!rcOriginalCB.IsEmpty()) {
+    CPDF_Array* pCropBox = pPageDict->SetNewFor<CPDF_Array>("ArtBox");
+    pCropBox->AddNew<CPDF_Number>(rcOriginalCB.left);
+    pCropBox->AddNew<CPDF_Number>(rcOriginalCB.bottom);
+    pCropBox->AddNew<CPDF_Number>(rcOriginalCB.right);
+    pCropBox->AddNew<CPDF_Number>(rcOriginalCB.top);
+  }
+
+  CPDF_Dictionary* pRes = pPageDict->GetDictFor("Resources");
+  if (!pRes)
+    pRes = pPageDict->SetNewFor<CPDF_Dictionary>("Resources");
+
+  CPDF_Stream* pNewXObject = pDocument->NewIndirect<CPDF_Stream>(
+      nullptr, 0,
+      pdfium::MakeUnique<CPDF_Dictionary>(pDocument->GetByteStringPool()));
+
+  uint32_t dwObjNum = pNewXObject->GetObjNum();
+  CPDF_Dictionary* pPageXObject = pRes->GetDictFor("XObject");
+  if (!pPageXObject)
+    pPageXObject = pRes->SetNewFor<CPDF_Dictionary>("XObject");
+
+  CFX_ByteString key = "";
+  int nStreams = pdfium::CollectionSize<int>(ObjectArray);
+  if (nStreams > 0) {
+    for (int iKey = 0; /*iKey < 100*/; iKey++) {
+      char sExtend[5] = {};
+      FXSYS_itoa(iKey, sExtend, 10);
+      key = CFX_ByteString("FFT") + CFX_ByteString(sExtend);
+      if (!pPageXObject->KeyExist(key))
+        break;
+    }
+  }
+
+  SetPageContents(key, pPageDict, pDocument);
+
+  CPDF_Dictionary* pNewXORes = nullptr;
+  if (!key.IsEmpty()) {
+    pPageXObject->SetNewFor<CPDF_Reference>(key, pDocument, dwObjNum);
+    CPDF_Dictionary* pNewOXbjectDic = pNewXObject->GetDict();
+    pNewXORes = pNewOXbjectDic->SetNewFor<CPDF_Dictionary>("Resources");
+    pNewOXbjectDic->SetNewFor<CPDF_Name>("Type", "XObject");
+    pNewOXbjectDic->SetNewFor<CPDF_Name>("Subtype", "Form");
+    pNewOXbjectDic->SetNewFor<CPDF_Number>("FormType", 1);
+    pNewOXbjectDic->SetNewFor<CPDF_Name>("Name", "FRM");
+    CFX_FloatRect rcBBox = pPageDict->GetRectFor("ArtBox");
+    pNewOXbjectDic->SetRectFor("BBox", rcBBox);
+  }
+
+  for (int i = 0; i < nStreams; i++) {
+    CPDF_Dictionary* pAnnotDic = ObjectArray[i];
+    if (!pAnnotDic)
+      continue;
+
+    CFX_FloatRect rcAnnot = pAnnotDic->GetRectFor("Rect");
+    rcAnnot.Normalize();
+
+    CFX_ByteString sAnnotState = pAnnotDic->GetStringFor("AS");
+    CPDF_Dictionary* pAnnotAP = pAnnotDic->GetDictFor("AP");
+    if (!pAnnotAP)
+      continue;
+
+    CPDF_Stream* pAPStream = pAnnotAP->GetStreamFor("N");
+    if (!pAPStream) {
+      CPDF_Dictionary* pAPDic = pAnnotAP->GetDictFor("N");
+      if (!pAPDic)
+        continue;
+
+      if (!sAnnotState.IsEmpty()) {
+        pAPStream = pAPDic->GetStreamFor(sAnnotState);
+      } else {
+        auto it = pAPDic->begin();
+        if (it != pAPDic->end()) {
+          CPDF_Object* pFirstObj = it->second.get();
+          if (pFirstObj) {
+            if (pFirstObj->IsReference())
+              pFirstObj = pFirstObj->GetDirect();
+            if (!pFirstObj->IsStream())
+              continue;
+            pAPStream = pFirstObj->AsStream();
+          }
+        }
+      }
+    }
+    if (!pAPStream)
+      continue;
+
+    CPDF_Dictionary* pAPDic = pAPStream->GetDict();
+    CFX_FloatRect rcStream;
+    if (pAPDic->KeyExist("Rect"))
+      rcStream = pAPDic->GetRectFor("Rect");
+    else if (pAPDic->KeyExist("BBox"))
+      rcStream = pAPDic->GetRectFor("BBox");
+
+    if (rcStream.IsEmpty())
+      continue;
+
+    CPDF_Object* pObj = pAPStream;
+    if (pObj->IsInline()) {
+      std::unique_ptr<CPDF_Object> pNew = pObj->Clone();
+      pObj = pNew.get();
+      pDocument->AddIndirectObject(std::move(pNew));
+    }
+
+    CPDF_Dictionary* pObjDic = pObj->GetDict();
+    if (pObjDic) {
+      pObjDic->SetNewFor<CPDF_Name>("Type", "XObject");
+      pObjDic->SetNewFor<CPDF_Name>("Subtype", "Form");
+    }
+
+    CPDF_Dictionary* pXObject = pNewXORes->GetDictFor("XObject");
+    if (!pXObject)
+      pXObject = pNewXORes->SetNewFor<CPDF_Dictionary>("XObject");
+
+    CFX_ByteString sFormName;
+    sFormName.Format("F%d", i);
+    pXObject->SetNewFor<CPDF_Reference>(sFormName, pDocument,
+                                        pObj->GetObjNum());
+
+    CPDF_StreamAcc acc;
+    acc.LoadAllData(pNewXObject);
+
+    const uint8_t* pData = acc.GetData();
+    CFX_ByteString sStream(pData, acc.GetSize());
+    CFX_Matrix matrix = pAPDic->GetMatrixFor("Matrix");
+    if (matrix.IsIdentity()) {
+      matrix.a = 1.0f;
+      matrix.b = 0.0f;
+      matrix.c = 0.0f;
+      matrix.d = 1.0f;
+      matrix.e = 0.0f;
+      matrix.f = 0.0f;
+    }
+
+    CFX_ByteString sTemp;
+    CFX_Matrix m = GetMatrix(rcAnnot, rcStream, matrix);
+    sTemp.Format("q %f 0 0 %f %f %f cm /%s Do Q\n", m.a, m.d, m.e, m.f,
+                 sFormName.c_str());
+    sStream += sTemp;
+    pNewXObject->SetData(sStream.raw_str(), sStream.GetLength());
+  }
+  pPageDict->RemoveFor("Annots");
+  return FLATTEN_SUCCESS;
+}
diff --git a/fpdfsdk/fpdf_flatten_embeddertest.cpp b/fpdfsdk/fpdf_flatten_embeddertest.cpp
new file mode 100644
index 0000000..d709f59
--- /dev/null
+++ b/fpdfsdk/fpdf_flatten_embeddertest.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.
+
+#include "core/fxcrt/fx_basic.h"
+#include "public/fpdf_flatten.h"
+#include "public/fpdfview.h"
+#include "testing/embedder_test.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/test_support.h"
+
+namespace {
+
+class FPDFFlattenEmbeddertest : public EmbedderTest {};
+
+}  // namespace
+
+TEST_F(FPDFFlattenEmbeddertest, FlatNothing) {
+  EXPECT_TRUE(OpenDocument("hello_world.pdf"));
+  FPDF_PAGE page = LoadPage(0);
+  EXPECT_TRUE(page);
+  EXPECT_EQ(FLATTEN_NOTHINGTODO, FPDFPage_Flatten(page, FLAT_NORMALDISPLAY));
+  UnloadPage(page);
+}
+
+TEST_F(FPDFFlattenEmbeddertest, FlatNormal) {
+  EXPECT_TRUE(OpenDocument("annotiter.pdf"));
+  FPDF_PAGE page = LoadPage(0);
+  EXPECT_TRUE(page);
+  EXPECT_EQ(FLATTEN_SUCCESS, FPDFPage_Flatten(page, FLAT_NORMALDISPLAY));
+  UnloadPage(page);
+}
+
+TEST_F(FPDFFlattenEmbeddertest, FlatPrint) {
+  EXPECT_TRUE(OpenDocument("annotiter.pdf"));
+  FPDF_PAGE page = LoadPage(0);
+  EXPECT_TRUE(page);
+  EXPECT_EQ(FLATTEN_SUCCESS, FPDFPage_Flatten(page, FLAT_PRINT));
+  UnloadPage(page);
+}
diff --git a/fpdfsdk/src/fpdf_progressive.cpp b/fpdfsdk/fpdf_progressive.cpp
similarity index 72%
rename from fpdfsdk/src/fpdf_progressive.cpp
rename to fpdfsdk/fpdf_progressive.cpp
index b6fd8e0..cc09d07 100644
--- a/fpdfsdk/src/fpdf_progressive.cpp
+++ b/fpdfsdk/fpdf_progressive.cpp
@@ -6,9 +6,16 @@
 
 #include "public/fpdf_progressive.h"
 
-#include "fpdfsdk/include/fsdk_define.h"
-#include "fpdfsdk/include/fsdk_rendercontext.h"
+#include "core/fpdfapi/cpdf_pagerendercontext.h"
+#include "core/fpdfapi/page/cpdf_page.h"
+#include "core/fpdfapi/render/cpdf_progressiverenderer.h"
+#include "core/fxcrt/fx_memory.h"
+#include "core/fxge/cfx_fxgedevice.h"
+#include "core/fxge/cfx_renderdevice.h"
+#include "fpdfsdk/fsdk_define.h"
+#include "fpdfsdk/fsdk_pauseadapter.h"
 #include "public/fpdfview.h"
+#include "third_party/base/ptr_util.h"
 
 // These checks are here because core/ and public/ cannot depend on each other.
 static_assert(CPDF_ProgressiveRenderer::Ready == FPDF_RENDER_READER,
@@ -37,27 +44,16 @@
   if (!pPage)
     return FPDF_RENDER_FAILED;
 
-  CRenderContext* pContext = new CRenderContext;
-  pPage->SetPrivateData((void*)1, pContext, DropContext);
-#ifdef _SKIA_SUPPORT_
-  pContext->m_pDevice = new CFX_SkiaDevice;
-  if (flags & FPDF_REVERSE_BYTE_ORDER)
-    ((CFX_SkiaDevice*)pContext->m_pDevice)
-        ->Attach((CFX_DIBitmap*)bitmap, 0, TRUE);
-  else
-    ((CFX_SkiaDevice*)pContext->m_pDevice)->Attach((CFX_DIBitmap*)bitmap);
-#else
-  pContext->m_pDevice = new CFX_FxgeDevice;
-  if (flags & FPDF_REVERSE_BYTE_ORDER)
-    ((CFX_FxgeDevice*)pContext->m_pDevice)
-        ->Attach((CFX_DIBitmap*)bitmap, 0, TRUE);
-  else
-    ((CFX_FxgeDevice*)pContext->m_pDevice)->Attach((CFX_DIBitmap*)bitmap);
-#endif
-  IFSDK_PAUSE_Adapter IPauseAdapter(pause);
+  CPDF_PageRenderContext* pContext = new CPDF_PageRenderContext;
+  pPage->SetRenderContext(pdfium::WrapUnique(pContext));
+  CFX_FxgeDevice* pDevice = new CFX_FxgeDevice;
+  pContext->m_pDevice.reset(pDevice);
+  CFX_DIBitmap* pBitmap = CFXBitmapFromFPDFBitmap(bitmap);
+  pDevice->Attach(pBitmap, !!(flags & FPDF_REVERSE_BYTE_ORDER), nullptr, false);
 
+  IFSDK_PAUSE_Adapter IPauseAdapter(pause);
   FPDF_RenderPage_Retail(pContext, page, start_x, start_y, size_x, size_y,
-                         rotate, flags, FALSE, &IPauseAdapter);
+                         rotate, flags, false, &IPauseAdapter);
 
   if (pContext->m_pRenderer) {
     return CPDF_ProgressiveRenderer::ToFPDFStatus(
@@ -75,7 +71,7 @@
   if (!pPage)
     return FPDF_RENDER_FAILED;
 
-  CRenderContext* pContext = (CRenderContext*)pPage->GetPrivateData((void*)1);
+  CPDF_PageRenderContext* pContext = pPage->GetRenderContext();
   if (pContext && pContext->m_pRenderer) {
     IFSDK_PAUSE_Adapter IPauseAdapter(pause);
     pContext->m_pRenderer->Continue(&IPauseAdapter);
@@ -90,11 +86,10 @@
   if (!pPage)
     return;
 
-  CRenderContext* pContext = (CRenderContext*)pPage->GetPrivateData((void*)1);
+  CPDF_PageRenderContext* pContext = pPage->GetRenderContext();
   if (!pContext)
     return;
 
-  pContext->m_pDevice->RestoreState();
-  delete pContext;
-  pPage->RemovePrivateData((void*)1);
+  pContext->m_pDevice->RestoreState(false);
+  pPage->SetRenderContext(nullptr);
 }
diff --git a/fpdfsdk/src/fpdf_searchex.cpp b/fpdfsdk/fpdf_searchex.cpp
similarity index 75%
rename from fpdfsdk/src/fpdf_searchex.cpp
rename to fpdfsdk/fpdf_searchex.cpp
index 96c5e53..f82db37 100644
--- a/fpdfsdk/src/fpdf_searchex.cpp
+++ b/fpdfsdk/fpdf_searchex.cpp
@@ -6,11 +6,12 @@
 
 #include "public/fpdf_searchex.h"
 
-#include "core/include/fpdftext/fpdf_text.h"
+#include "core/fpdftext/cpdf_textpage.h"
 
 DLLEXPORT int STDCALL
 FPDFText_GetCharIndexFromTextIndex(FPDF_TEXTPAGE text_page, int nTextIndex) {
   if (!text_page)
     return -1;
-  return ((IPDF_TextPage*)text_page)->CharIndexFromTextIndex(nTextIndex);
+  return static_cast<CPDF_TextPage*>(text_page)
+      ->CharIndexFromTextIndex(nTextIndex);
 }
diff --git a/fpdfsdk/fpdf_structtree.cpp b/fpdfsdk/fpdf_structtree.cpp
new file mode 100644
index 0000000..9bc1df6
--- /dev/null
+++ b/fpdfsdk/fpdf_structtree.cpp
@@ -0,0 +1,89 @@
+// 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.
+
+#include "public/fpdf_structtree.h"
+
+#include "core/fpdfapi/page/cpdf_page.h"
+#include "core/fpdfapi/parser/cpdf_dictionary.h"
+#include "core/fpdfdoc/fpdf_tagged.h"
+#include "fpdfsdk/fsdk_define.h"
+
+namespace {
+
+IPDF_StructTree* ToStructTree(FPDF_STRUCTTREE struct_tree) {
+  return reinterpret_cast<IPDF_StructTree*>(struct_tree);
+}
+
+IPDF_StructElement* ToStructTreeElement(FPDF_STRUCTELEMENT struct_element) {
+  return reinterpret_cast<IPDF_StructElement*>(struct_element);
+}
+
+}  // namespace
+
+DLLEXPORT FPDF_STRUCTTREE STDCALL FPDF_StructTree_GetForPage(FPDF_PAGE page) {
+  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
+  if (!pPage)
+    return nullptr;
+  return IPDF_StructTree::LoadPage(pPage->m_pDocument, pPage->m_pFormDict)
+      .release();
+}
+
+DLLEXPORT void STDCALL FPDF_StructTree_Close(FPDF_STRUCTTREE struct_tree) {
+  delete ToStructTree(struct_tree);
+}
+
+DLLEXPORT int STDCALL
+FPDF_StructTree_CountChildren(FPDF_STRUCTTREE struct_tree) {
+  IPDF_StructTree* tree = ToStructTree(struct_tree);
+  return tree ? tree->CountTopElements() : -1;
+}
+
+DLLEXPORT FPDF_STRUCTELEMENT STDCALL
+FPDF_StructTree_GetChildAtIndex(FPDF_STRUCTTREE struct_tree, int index) {
+  IPDF_StructTree* tree = ToStructTree(struct_tree);
+  if (!tree || index < 0 || index >= tree->CountTopElements())
+    return nullptr;
+  return tree->GetTopElement(index);
+}
+
+DLLEXPORT unsigned long STDCALL
+FPDF_StructElement_GetAltText(FPDF_STRUCTELEMENT struct_element,
+                              void* buffer,
+                              unsigned long buflen) {
+  IPDF_StructElement* elem = ToStructTreeElement(struct_element);
+  if (!elem)
+    return 0;
+
+  CPDF_Dictionary* dict = elem->GetDict();
+  if (!dict)
+    return 0;
+
+  CFX_WideString str = elem->GetDict()->GetUnicodeTextFor("Alt");
+  if (str.IsEmpty())
+    return 0;
+
+  CFX_ByteString encodedStr = str.UTF16LE_Encode();
+  const unsigned long len = encodedStr.GetLength();
+  if (buffer && len <= buflen)
+    FXSYS_memcpy(buffer, encodedStr.c_str(), len);
+  return len;
+}
+
+DLLEXPORT int STDCALL
+FPDF_StructElement_CountChildren(FPDF_STRUCTELEMENT struct_element) {
+  IPDF_StructElement* elem = ToStructTreeElement(struct_element);
+  return elem ? elem->CountKids() : -1;
+}
+
+DLLEXPORT FPDF_STRUCTELEMENT STDCALL
+FPDF_StructElement_GetChildAtIndex(FPDF_STRUCTELEMENT struct_element,
+                                   int index) {
+  IPDF_StructElement* elem = ToStructTreeElement(struct_element);
+  if (!elem || index < 0 || index >= elem->CountKids())
+    return nullptr;
+
+  CPDF_StructKid kid = elem->GetKid(index);
+  return kid.m_Type == CPDF_StructKid::Element ? kid.m_Element.m_pElement
+                                               : nullptr;
+}
diff --git a/fpdfsdk/fpdf_structtree_embeddertest.cpp b/fpdfsdk/fpdf_structtree_embeddertest.cpp
new file mode 100644
index 0000000..58b3172
--- /dev/null
+++ b/fpdfsdk/fpdf_structtree_embeddertest.cpp
@@ -0,0 +1,70 @@
+// 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.
+
+#include "core/fxcrt/fx_string.h"
+#include "public/fpdf_structtree.h"
+#include "testing/embedder_test.h"
+#include "testing/test_support.h"
+
+class FPDFStructTreeEmbeddertest : public EmbedderTest, public TestSaver {};
+
+TEST_F(FPDFStructTreeEmbeddertest, GetAltText) {
+  ASSERT_TRUE(OpenDocument("tagged_alt_text.pdf"));
+  FPDF_PAGE page = LoadPage(0);
+  ASSERT_TRUE(page);
+
+  FPDF_STRUCTTREE struct_tree = FPDF_StructTree_GetForPage(page);
+  ASSERT_TRUE(struct_tree);
+  ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree));
+
+  FPDF_STRUCTELEMENT element = FPDF_StructTree_GetChildAtIndex(struct_tree, -1);
+  EXPECT_EQ(nullptr, element);
+  element = FPDF_StructTree_GetChildAtIndex(struct_tree, 1);
+  EXPECT_EQ(nullptr, element);
+  element = FPDF_StructTree_GetChildAtIndex(struct_tree, 0);
+  ASSERT_NE(nullptr, element);
+  EXPECT_EQ(0U, FPDF_StructElement_GetAltText(element, nullptr, 0));
+
+  ASSERT_EQ(1, FPDF_StructElement_CountChildren(element));
+  FPDF_STRUCTELEMENT child_element =
+      FPDF_StructElement_GetChildAtIndex(element, -1);
+  EXPECT_EQ(nullptr, child_element);
+  child_element = FPDF_StructElement_GetChildAtIndex(element, 1);
+  EXPECT_EQ(nullptr, child_element);
+  child_element = FPDF_StructElement_GetChildAtIndex(element, 0);
+  ASSERT_NE(nullptr, child_element);
+  EXPECT_EQ(0U, FPDF_StructElement_GetAltText(child_element, nullptr, 0));
+
+  ASSERT_EQ(1, FPDF_StructElement_CountChildren(child_element));
+  FPDF_STRUCTELEMENT gchild_element =
+      FPDF_StructElement_GetChildAtIndex(child_element, -1);
+  EXPECT_EQ(nullptr, gchild_element);
+  gchild_element = FPDF_StructElement_GetChildAtIndex(child_element, 1);
+  EXPECT_EQ(nullptr, gchild_element);
+  gchild_element = FPDF_StructElement_GetChildAtIndex(child_element, 0);
+  ASSERT_NE(nullptr, gchild_element);
+  ASSERT_EQ(24U, FPDF_StructElement_GetAltText(gchild_element, nullptr, 0));
+
+  unsigned short buffer[12];
+  memset(buffer, 0, sizeof(buffer));
+  // Deliberately pass in a small buffer size to make sure |buffer| remains
+  // untouched.
+  ASSERT_EQ(24U, FPDF_StructElement_GetAltText(gchild_element, buffer, 1));
+  for (size_t i = 0; i < FX_ArraySize(buffer); ++i)
+    EXPECT_EQ(0U, buffer[i]);
+
+  ASSERT_EQ(24U, FPDF_StructElement_GetAltText(gchild_element, buffer,
+                                               sizeof(buffer)));
+  const FX_WCHAR kExpected[] = L"Black Image";
+  EXPECT_EQ(CFX_WideString(kExpected),
+            CFX_WideString::FromUTF16LE(buffer, FXSYS_len(kExpected)));
+
+  ASSERT_EQ(1, FPDF_StructElement_CountChildren(gchild_element));
+  FPDF_STRUCTELEMENT ggchild_element =
+      FPDF_StructElement_GetChildAtIndex(gchild_element, 0);
+  EXPECT_EQ(nullptr, ggchild_element);
+
+  FPDF_StructTree_Close(struct_tree);
+  FPDF_ClosePage(page);
+}
diff --git a/fpdfsdk/fpdf_sysfontinfo.cpp b/fpdfsdk/fpdf_sysfontinfo.cpp
new file mode 100644
index 0000000..1b62dc4
--- /dev/null
+++ b/fpdfsdk/fpdf_sysfontinfo.cpp
@@ -0,0 +1,203 @@
+// 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
+
+#include "public/fpdf_sysfontinfo.h"
+
+#include <memory>
+
+#include "core/fxge/cfx_fontmapper.h"
+#include "core/fxge/cfx_gemodule.h"
+#include "core/fxge/fx_font.h"
+#include "core/fxge/ifx_systemfontinfo.h"
+#include "fpdfsdk/fsdk_define.h"
+#include "fpdfsdk/pdfwindow/PWL_FontMap.h"
+
+class CFX_ExternalFontInfo final : public IFX_SystemFontInfo {
+ public:
+  explicit CFX_ExternalFontInfo(FPDF_SYSFONTINFO* pInfo) : m_pInfo(pInfo) {}
+  ~CFX_ExternalFontInfo() override {
+    if (m_pInfo->Release)
+      m_pInfo->Release(m_pInfo);
+  }
+
+  bool EnumFontList(CFX_FontMapper* pMapper) override {
+    if (m_pInfo->EnumFonts) {
+      m_pInfo->EnumFonts(m_pInfo, pMapper);
+      return true;
+    }
+    return false;
+  }
+
+  void* MapFont(int weight,
+                bool bItalic,
+                int charset,
+                int pitch_family,
+                const FX_CHAR* family,
+                int& iExact) override {
+    if (!m_pInfo->MapFont)
+      return nullptr;
+    return m_pInfo->MapFont(m_pInfo, weight, bItalic, charset, pitch_family,
+                            family, &iExact);
+  }
+
+  void* GetFont(const FX_CHAR* family) override {
+    if (!m_pInfo->GetFont)
+      return nullptr;
+    return m_pInfo->GetFont(m_pInfo, family);
+  }
+
+  uint32_t GetFontData(void* hFont,
+                       uint32_t table,
+                       uint8_t* buffer,
+                       uint32_t size) override {
+    if (!m_pInfo->GetFontData)
+      return 0;
+    return m_pInfo->GetFontData(m_pInfo, hFont, table, buffer, size);
+  }
+
+  bool GetFaceName(void* hFont, CFX_ByteString& name) override {
+    if (!m_pInfo->GetFaceName)
+      return false;
+    uint32_t size = m_pInfo->GetFaceName(m_pInfo, hFont, nullptr, 0);
+    if (size == 0)
+      return false;
+    char* buffer = FX_Alloc(char, size);
+    size = m_pInfo->GetFaceName(m_pInfo, hFont, buffer, size);
+    name = CFX_ByteString(buffer, size);
+    FX_Free(buffer);
+    return true;
+  }
+
+  bool GetFontCharset(void* hFont, int& charset) override {
+    if (!m_pInfo->GetFontCharset)
+      return false;
+
+    charset = m_pInfo->GetFontCharset(m_pInfo, hFont);
+    return true;
+  }
+
+  void DeleteFont(void* hFont) override {
+    if (m_pInfo->DeleteFont)
+      m_pInfo->DeleteFont(m_pInfo, hFont);
+  }
+
+ private:
+  FPDF_SYSFONTINFO* const m_pInfo;
+};
+
+DLLEXPORT void STDCALL FPDF_AddInstalledFont(void* mapper,
+                                             const char* name,
+                                             int charset) {
+  CFX_FontMapper* pMapper = reinterpret_cast<CFX_FontMapper*>(mapper);
+  pMapper->AddInstalledFont(name, charset);
+}
+
+DLLEXPORT void STDCALL FPDF_SetSystemFontInfo(FPDF_SYSFONTINFO* pFontInfoExt) {
+  if (pFontInfoExt->version != 1)
+    return;
+
+  CFX_GEModule::Get()->GetFontMgr()->SetSystemFontInfo(
+      std::unique_ptr<IFX_SystemFontInfo>(
+          new CFX_ExternalFontInfo(pFontInfoExt)));
+}
+
+DLLEXPORT const FPDF_CharsetFontMap* STDCALL FPDF_GetDefaultTTFMap() {
+  return CPWL_FontMap::defaultTTFMap;
+}
+
+struct FPDF_SYSFONTINFO_DEFAULT : public FPDF_SYSFONTINFO {
+  IFX_SystemFontInfo* m_pFontInfo;
+};
+
+static void DefaultRelease(struct _FPDF_SYSFONTINFO* pThis) {
+  auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
+  // TODO(thestig): Should this be set to nullptr too?
+  delete pDefault->m_pFontInfo;
+}
+
+static void DefaultEnumFonts(struct _FPDF_SYSFONTINFO* pThis, void* pMapper) {
+  auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
+  pDefault->m_pFontInfo->EnumFontList((CFX_FontMapper*)pMapper);
+}
+
+static void* DefaultMapFont(struct _FPDF_SYSFONTINFO* pThis,
+                            int weight,
+                            int bItalic,
+                            int charset,
+                            int pitch_family,
+                            const char* family,
+                            int* bExact) {
+  auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
+  return pDefault->m_pFontInfo->MapFont(weight, !!bItalic, charset,
+                                        pitch_family, family, *bExact);
+}
+
+void* DefaultGetFont(struct _FPDF_SYSFONTINFO* pThis, const char* family) {
+  auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
+  return pDefault->m_pFontInfo->GetFont(family);
+}
+
+static unsigned long DefaultGetFontData(struct _FPDF_SYSFONTINFO* pThis,
+                                        void* hFont,
+                                        unsigned int table,
+                                        unsigned char* buffer,
+                                        unsigned long buf_size) {
+  auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
+  return pDefault->m_pFontInfo->GetFontData(hFont, table, buffer, buf_size);
+}
+
+static unsigned long DefaultGetFaceName(struct _FPDF_SYSFONTINFO* pThis,
+                                        void* hFont,
+                                        char* buffer,
+                                        unsigned long buf_size) {
+  CFX_ByteString name;
+  auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
+  if (!pDefault->m_pFontInfo->GetFaceName(hFont, name))
+    return 0;
+  if (name.GetLength() >= (long)buf_size)
+    return name.GetLength() + 1;
+  FXSYS_strcpy(buffer, name.c_str());
+  return name.GetLength() + 1;
+}
+
+static int DefaultGetFontCharset(struct _FPDF_SYSFONTINFO* pThis, void* hFont) {
+  int charset;
+  auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
+  if (!pDefault->m_pFontInfo->GetFontCharset(hFont, charset))
+    return 0;
+  return charset;
+}
+
+static void DefaultDeleteFont(struct _FPDF_SYSFONTINFO* pThis, void* hFont) {
+  auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
+  pDefault->m_pFontInfo->DeleteFont(hFont);
+}
+
+DLLEXPORT FPDF_SYSFONTINFO* STDCALL FPDF_GetDefaultSystemFontInfo() {
+  std::unique_ptr<IFX_SystemFontInfo> pFontInfo =
+      IFX_SystemFontInfo::CreateDefault(nullptr);
+  if (!pFontInfo)
+    return nullptr;
+
+  FPDF_SYSFONTINFO_DEFAULT* pFontInfoExt =
+      FX_Alloc(FPDF_SYSFONTINFO_DEFAULT, 1);
+  pFontInfoExt->DeleteFont = DefaultDeleteFont;
+  pFontInfoExt->EnumFonts = DefaultEnumFonts;
+  pFontInfoExt->GetFaceName = DefaultGetFaceName;
+  pFontInfoExt->GetFont = DefaultGetFont;
+  pFontInfoExt->GetFontCharset = DefaultGetFontCharset;
+  pFontInfoExt->GetFontData = DefaultGetFontData;
+  pFontInfoExt->MapFont = DefaultMapFont;
+  pFontInfoExt->Release = DefaultRelease;
+  pFontInfoExt->version = 1;
+  pFontInfoExt->m_pFontInfo = pFontInfo.release();
+  return pFontInfoExt;
+}
+
+DLLEXPORT void FPDF_FreeDefaultSystemFontInfo(
+    FPDF_SYSFONTINFO* pDefaultFontInfo) {
+  FX_Free(static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pDefaultFontInfo));
+}
diff --git a/fpdfsdk/src/fpdf_transformpage.cpp b/fpdfsdk/fpdf_transformpage.cpp
similarity index 61%
rename from fpdfsdk/src/fpdf_transformpage.cpp
rename to fpdfsdk/fpdf_transformpage.cpp
index 3e2c7b1..13d9756 100644
--- a/fpdfsdk/src/fpdf_transformpage.cpp
+++ b/fpdfsdk/fpdf_transformpage.cpp
@@ -6,41 +6,48 @@
 
 #include "public/fpdf_transformpage.h"
 
-#include "fpdfsdk/include/fsdk_define.h"
+#include "core/fpdfapi/page/cpdf_clippath.h"
+#include "core/fpdfapi/page/cpdf_page.h"
+#include "core/fpdfapi/page/cpdf_pageobject.h"
+#include "core/fpdfapi/page/cpdf_path.h"
+#include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/cpdf_number.h"
+#include "core/fpdfapi/parser/cpdf_reference.h"
+#include "core/fpdfapi/parser/cpdf_stream.h"
+#include "core/fxge/cfx_pathdata.h"
+#include "fpdfsdk/fsdk_define.h"
 
 namespace {
 
 void SetBoundingBox(CPDF_Page* page,
-                    const CFX_ByteStringC& key,
+                    const CFX_ByteString& key,
                     float left,
                     float bottom,
                     float right,
                     float top) {
-  CPDF_Dictionary* pPageDict = page->m_pFormDict;
-  CPDF_Array* pBoundingBoxArray = new CPDF_Array;
-  pBoundingBoxArray->Add(new CPDF_Number(left));
-  pBoundingBoxArray->Add(new CPDF_Number(bottom));
-  pBoundingBoxArray->Add(new CPDF_Number(right));
-  pBoundingBoxArray->Add(new CPDF_Number(top));
-  pPageDict->SetAt(key, pBoundingBoxArray);
+  CPDF_Array* pBoundingBoxArray = page->m_pFormDict->SetNewFor<CPDF_Array>(key);
+  pBoundingBoxArray->AddNew<CPDF_Number>(left);
+  pBoundingBoxArray->AddNew<CPDF_Number>(bottom);
+  pBoundingBoxArray->AddNew<CPDF_Number>(right);
+  pBoundingBoxArray->AddNew<CPDF_Number>(top);
 }
 
-FPDF_BOOL GetBoundingBox(CPDF_Page* page,
-                         const CFX_ByteStringC& key,
-                         float* left,
-                         float* bottom,
-                         float* right,
-                         float* top) {
-  CPDF_Dictionary* pPageDict = page->m_pFormDict;
-  CPDF_Array* pArray = pPageDict->GetArray(key);
+bool GetBoundingBox(CPDF_Page* page,
+                    const CFX_ByteString& key,
+                    float* left,
+                    float* bottom,
+                    float* right,
+                    float* top) {
+  CPDF_Array* pArray = page->m_pFormDict->GetArrayFor(key);
   if (!pArray)
-    return FALSE;
+    return false;
 
-  *left = pArray->GetFloat(0);
-  *bottom = pArray->GetFloat(1);
-  *right = pArray->GetFloat(2);
-  *top = pArray->GetFloat(3);
-  return TRUE;
+  *left = pArray->GetFloatAt(0);
+  *bottom = pArray->GetFloatAt(1);
+  *right = pArray->GetFloatAt(2);
+  *top = pArray->GetFloatAt(3);
+  return true;
 }
 
 }  // namespace
@@ -92,7 +99,7 @@
                                                        FS_RECTF* clipRect) {
   CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
   if (!pPage)
-    return FALSE;
+    return false;
 
   CFX_ByteTextBuf textBuf;
   textBuf << "q ";
@@ -111,77 +118,79 @@
 
   CPDF_Dictionary* pPageDic = pPage->m_pFormDict;
   CPDF_Object* pContentObj =
-      pPageDic ? pPageDic->GetElement("Contents") : nullptr;
+      pPageDic ? pPageDic->GetObjectFor("Contents") : nullptr;
   if (!pContentObj)
-    pContentObj = pPageDic ? pPageDic->GetArray("Contents") : nullptr;
+    pContentObj = pPageDic ? pPageDic->GetArrayFor("Contents") : nullptr;
   if (!pContentObj)
-    return FALSE;
+    return false;
 
-  CPDF_Dictionary* pDic = new CPDF_Dictionary;
-  CPDF_Stream* pStream = new CPDF_Stream(nullptr, 0, pDic);
-  pStream->SetData(textBuf.GetBuffer(), textBuf.GetSize(), FALSE, FALSE);
   CPDF_Document* pDoc = pPage->m_pDocument;
   if (!pDoc)
-    return FALSE;
-  pDoc->AddIndirectObject(pStream);
+    return false;
 
-  pDic = new CPDF_Dictionary;
-  CPDF_Stream* pEndStream = new CPDF_Stream(nullptr, 0, pDic);
-  pEndStream->SetData((const uint8_t*)" Q", 2, FALSE, FALSE);
-  pDoc->AddIndirectObject(pEndStream);
+  CPDF_Stream* pStream = pDoc->NewIndirect<CPDF_Stream>(
+      nullptr, 0,
+      pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool()));
+  pStream->SetData(textBuf.GetBuffer(), textBuf.GetSize());
+
+  CPDF_Stream* pEndStream = pDoc->NewIndirect<CPDF_Stream>(
+      nullptr, 0,
+      pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool()));
+  pEndStream->SetData((const uint8_t*)" Q", 2);
 
   CPDF_Array* pContentArray = nullptr;
-  if (CPDF_Array* pArray = ToArray(pContentObj)) {
+  CPDF_Array* pArray = ToArray(pContentObj);
+  if (pArray) {
     pContentArray = pArray;
-    CPDF_Reference* pRef = new CPDF_Reference(pDoc, pStream->GetObjNum());
-    pContentArray->InsertAt(0, pRef);
-    pContentArray->AddReference(pDoc, pEndStream);
+    pContentArray->InsertNewAt<CPDF_Reference>(0, pDoc, pStream->GetObjNum());
+    pContentArray->AddNew<CPDF_Reference>(pDoc, pEndStream->GetObjNum());
   } else if (CPDF_Reference* pReference = ToReference(pContentObj)) {
     CPDF_Object* pDirectObj = pReference->GetDirect();
     if (pDirectObj) {
-      if (CPDF_Array* pArray = pDirectObj->AsArray()) {
-        pContentArray = pArray;
-        CPDF_Reference* pRef = new CPDF_Reference(pDoc, pStream->GetObjNum());
-        pContentArray->InsertAt(0, pRef);
-        pContentArray->AddReference(pDoc, pEndStream);
+      CPDF_Array* pObjArray = pDirectObj->AsArray();
+      if (pObjArray) {
+        pContentArray = pObjArray;
+        pContentArray->InsertNewAt<CPDF_Reference>(0, pDoc,
+                                                   pStream->GetObjNum());
+        pContentArray->AddNew<CPDF_Reference>(pDoc, pEndStream->GetObjNum());
       } else if (pDirectObj->IsStream()) {
-        pContentArray = new CPDF_Array();
-        pContentArray->AddReference(pDoc, pStream->GetObjNum());
-        pContentArray->AddReference(pDoc, pDirectObj->GetObjNum());
-        pContentArray->AddReference(pDoc, pEndStream);
-        pPageDic->SetAtReference("Contents", pDoc,
-                                 pDoc->AddIndirectObject(pContentArray));
+        pContentArray = pDoc->NewIndirect<CPDF_Array>();
+        pContentArray->AddNew<CPDF_Reference>(pDoc, pStream->GetObjNum());
+        pContentArray->AddNew<CPDF_Reference>(pDoc, pDirectObj->GetObjNum());
+        pContentArray->AddNew<CPDF_Reference>(pDoc, pEndStream->GetObjNum());
+        pPageDic->SetNewFor<CPDF_Reference>("Contents", pDoc,
+                                            pContentArray->GetObjNum());
       }
     }
   }
 
   // Need to transform the patterns as well.
-  CPDF_Dictionary* pRes = pPageDic->GetDict("Resources");
+  CPDF_Dictionary* pRes = pPageDic->GetDictFor("Resources");
   if (pRes) {
-    CPDF_Dictionary* pPattenDict = pRes->GetDict("Pattern");
+    CPDF_Dictionary* pPattenDict = pRes->GetDictFor("Pattern");
     if (pPattenDict) {
       for (const auto& it : *pPattenDict) {
-        CPDF_Object* pObj = it.second;
+        CPDF_Object* pObj = it.second.get();
         if (pObj->IsReference())
           pObj = pObj->GetDirect();
 
         CPDF_Dictionary* pDict = nullptr;
         if (pObj->IsDictionary())
           pDict = pObj->AsDictionary();
-        else if (CPDF_Stream* pStream = pObj->AsStream())
-          pDict = pStream->GetDict();
+        else if (CPDF_Stream* pObjStream = pObj->AsStream())
+          pDict = pObjStream->GetDict();
         else
           continue;
 
-        CFX_Matrix m = pDict->GetMatrix("Matrix");
+        CFX_Matrix m = pDict->GetMatrixFor("Matrix");
         CFX_Matrix t = *(CFX_Matrix*)matrix;
         m.Concat(t);
-        pDict->SetAtMatrix("Matrix", m);
+        pDict->SetMatrixFor("Matrix", m);
       }
     }
   }
 
-  return TRUE;
+  return true;
 }
 
 DLLEXPORT void STDCALL
@@ -200,7 +209,7 @@
 
   // Special treatment to shading object, because the ClipPath for shading
   // object is already transformed.
-  if (pPageObj->m_Type != PDFPAGE_SHADING)
+  if (!pPageObj->IsShading())
     pPageObj->TransformClipPath(matrix);
   pPageObj->TransformGeneralState(matrix);
 }
@@ -209,12 +218,11 @@
                                                     float bottom,
                                                     float right,
                                                     float top) {
-  CPDF_ClipPath* pNewClipPath = new CPDF_ClipPath();
-  pNewClipPath->GetModify();
   CPDF_Path Path;
-  Path.GetModify();
   Path.AppendRect(left, bottom, right, top);
-  pNewClipPath->AppendPath(Path, FXFILL_ALTERNATE, FALSE);
+
+  CPDF_ClipPath* pNewClipPath = new CPDF_ClipPath();
+  pNewClipPath->AppendPath(Path, FXFILL_ALTERNATE, false);
   return pNewClipPath;
 }
 
@@ -223,7 +231,7 @@
 }
 
 void OutputPath(CFX_ByteTextBuf& buf, CPDF_Path path) {
-  const CFX_PathData* pPathData = path;
+  const CFX_PathData* pPathData = path.GetObject();
   if (!pPathData)
     return;
 
@@ -240,9 +248,9 @@
   for (int i = 0; i < pPathData->GetPointCount(); i++) {
     buf << (pPoints[i].m_PointX) << " " << (pPoints[i].m_PointY);
     int point_type = pPoints[i].m_Flag & FXPT_TYPE;
-    if (point_type == FXPT_MOVETO)
+    if (point_type == FXPT_MOVETO) {
       buf << " m\n";
-    else if (point_type == FXPT_BEZIERTO) {
+    } else if (point_type == FXPT_BEZIERTO) {
       buf << " " << (pPoints[i + 1].m_PointX) << " "
           << (pPoints[i + 1].m_PointY) << " " << (pPoints[i + 2].m_PointX)
           << " " << (pPoints[i + 2].m_PointY);
@@ -268,15 +276,15 @@
 
   CPDF_Dictionary* pPageDic = pPage->m_pFormDict;
   CPDF_Object* pContentObj =
-      pPageDic ? pPageDic->GetElement("Contents") : nullptr;
+      pPageDic ? pPageDic->GetObjectFor("Contents") : nullptr;
   if (!pContentObj)
-    pContentObj = pPageDic ? pPageDic->GetArray("Contents") : nullptr;
+    pContentObj = pPageDic ? pPageDic->GetArrayFor("Contents") : nullptr;
   if (!pContentObj)
     return;
 
   CFX_ByteTextBuf strClip;
   CPDF_ClipPath* pClipPath = (CPDF_ClipPath*)clipPath;
-  FX_DWORD i;
+  uint32_t i;
   for (i = 0; i < pClipPath->GetPathCount(); i++) {
     CPDF_Path path = pClipPath->GetPath(i);
     int iClipType = pClipPath->GetClipType(i);
@@ -291,33 +299,38 @@
         strClip << "W* n\n";
     }
   }
-  CPDF_Dictionary* pDic = new CPDF_Dictionary;
-  CPDF_Stream* pStream = new CPDF_Stream(nullptr, 0, pDic);
-  pStream->SetData(strClip.GetBuffer(), strClip.GetSize(), FALSE, FALSE);
   CPDF_Document* pDoc = pPage->m_pDocument;
   if (!pDoc)
     return;
-  pDoc->AddIndirectObject(pStream);
 
-  CPDF_Array* pContentArray = nullptr;
-  if (CPDF_Array* pArray = ToArray(pContentObj)) {
-    pContentArray = pArray;
-    CPDF_Reference* pRef = new CPDF_Reference(pDoc, pStream->GetObjNum());
-    pContentArray->InsertAt(0, pRef);
-  } else if (CPDF_Reference* pReference = ToReference(pContentObj)) {
-    CPDF_Object* pDirectObj = pReference->GetDirect();
-    if (pDirectObj) {
-      if (CPDF_Array* pArray = pDirectObj->AsArray()) {
-        pContentArray = pArray;
-        CPDF_Reference* pRef = new CPDF_Reference(pDoc, pStream->GetObjNum());
-        pContentArray->InsertAt(0, pRef);
-      } else if (pDirectObj->IsStream()) {
-        pContentArray = new CPDF_Array();
-        pContentArray->AddReference(pDoc, pStream->GetObjNum());
-        pContentArray->AddReference(pDoc, pDirectObj->GetObjNum());
-        pPageDic->SetAtReference("Contents", pDoc,
-                                 pDoc->AddIndirectObject(pContentArray));
-      }
-    }
+  CPDF_Stream* pStream = pDoc->NewIndirect<CPDF_Stream>(
+      nullptr, 0,
+      pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool()));
+  pStream->SetData(strClip.GetBuffer(), strClip.GetSize());
+
+  CPDF_Array* pArray = ToArray(pContentObj);
+  if (pArray) {
+    pArray->InsertNewAt<CPDF_Reference>(0, pDoc, pStream->GetObjNum());
+    return;
+  }
+  CPDF_Reference* pReference = ToReference(pContentObj);
+  if (!pReference)
+    return;
+
+  CPDF_Object* pDirectObj = pReference->GetDirect();
+  if (!pDirectObj)
+    return;
+
+  CPDF_Array* pObjArray = pDirectObj->AsArray();
+  if (pObjArray) {
+    pObjArray->InsertNewAt<CPDF_Reference>(0, pDoc, pStream->GetObjNum());
+    return;
+  }
+  if (pDirectObj->IsStream()) {
+    CPDF_Array* pContentArray = pDoc->NewIndirect<CPDF_Array>();
+    pContentArray->AddNew<CPDF_Reference>(pDoc, pStream->GetObjNum());
+    pContentArray->AddNew<CPDF_Reference>(pDoc, pDirectObj->GetObjNum());
+    pPageDic->SetNewFor<CPDF_Reference>("Contents", pDoc,
+                                        pContentArray->GetObjNum());
   }
 }
diff --git a/fpdfsdk/src/fpdfdoc.cpp b/fpdfsdk/fpdfdoc.cpp
similarity index 61%
rename from fpdfsdk/src/fpdfdoc.cpp
rename to fpdfsdk/fpdfdoc.cpp
index 4bd37a7..82b898a 100644
--- a/fpdfsdk/src/fpdfdoc.cpp
+++ b/fpdfsdk/fpdfdoc.cpp
@@ -6,47 +6,68 @@
 
 #include "public/fpdf_doc.h"
 
-#include "fpdfsdk/include/fsdk_define.h"
+#include <memory>
+#include <set>
+
+#include "core/fpdfapi/page/cpdf_page.h"
+#include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfdoc/cpdf_bookmark.h"
+#include "core/fpdfdoc/cpdf_bookmarktree.h"
+#include "core/fpdfdoc/cpdf_dest.h"
+#include "core/fpdfdoc/cpdf_pagelabel.h"
+#include "fpdfsdk/fsdk_define.h"
+#include "third_party/base/ptr_util.h"
+#include "third_party/base/stl_util.h"
 
 namespace {
 
-int THISMODULE = 0;
-
 CPDF_Bookmark FindBookmark(const CPDF_BookmarkTree& tree,
                            CPDF_Bookmark bookmark,
-                           const CFX_WideString& title) {
-  if (bookmark && bookmark.GetTitle().CompareNoCase(title.c_str()) == 0) {
-    // First check this item
+                           const CFX_WideString& title,
+                           std::set<CPDF_Dictionary*>* visited) {
+  // Return if already checked to avoid circular calling.
+  if (pdfium::ContainsKey(*visited, bookmark.GetDict()))
+    return CPDF_Bookmark();
+  visited->insert(bookmark.GetDict());
+
+  if (bookmark.GetDict() &&
+      bookmark.GetTitle().CompareNoCase(title.c_str()) == 0) {
+    // First check this item.
     return bookmark;
   }
-  // go into children items
+
+  // Go into children items.
   CPDF_Bookmark child = tree.GetFirstChild(bookmark);
-  while (child) {
-    // check if this item
-    CPDF_Bookmark found = FindBookmark(tree, child, title);
-    if (found)
+  while (child.GetDict() && !pdfium::ContainsKey(*visited, child.GetDict())) {
+    // Check this item and its children.
+    CPDF_Bookmark found = FindBookmark(tree, child, title, visited);
+    if (found.GetDict())
       return found;
     child = tree.GetNextSibling(child);
   }
   return CPDF_Bookmark();
 }
 
-void ReleaseLinkList(void* data) {
-  delete (CPDF_LinkList*)data;
-}
-
 CPDF_LinkList* GetLinkList(CPDF_Page* page) {
   if (!page)
     return nullptr;
 
-  // Link list is stored with the document
   CPDF_Document* pDoc = page->m_pDocument;
-  CPDF_LinkList* pLinkList = (CPDF_LinkList*)pDoc->GetPrivateData(&THISMODULE);
-  if (!pLinkList) {
-    pLinkList = new CPDF_LinkList;
-    pDoc->SetPrivateData(&THISMODULE, pLinkList, ReleaseLinkList);
-  }
-  return pLinkList;
+  std::unique_ptr<CPDF_LinkList>* pHolder = pDoc->LinksContext();
+  if (!pHolder->get())
+    *pHolder = pdfium::MakeUnique<CPDF_LinkList>();
+  return pHolder->get();
+}
+
+unsigned long Utf16EncodeMaybeCopyAndReturnLength(const CFX_WideString& text,
+                                                  void* buffer,
+                                                  unsigned long buflen) {
+  CFX_ByteString encodedText = text.UTF16LE_Encode();
+  unsigned long len = encodedText.GetLength();
+  if (buffer && len <= buflen)
+    FXSYS_memcpy(buffer, encodedText.c_str(), len);
+  return len;
 }
 
 }  // namespace
@@ -82,12 +103,7 @@
     return 0;
   CPDF_Bookmark bookmark(ToDictionary(static_cast<CPDF_Object*>(pDict)));
   CFX_WideString title = bookmark.GetTitle();
-  CFX_ByteString encodedTitle = title.UTF16LE_Encode();
-  unsigned long len = encodedTitle.GetLength();
-  if (buffer && buflen >= len) {
-    FXSYS_memcpy(buffer, encodedTitle.c_str(), len);
-  }
-  return len;
+  return Utf16EncodeMaybeCopyAndReturnLength(title, buffer, buflen);
 }
 
 DLLEXPORT FPDF_BOOKMARK STDCALL FPDFBookmark_Find(FPDF_DOCUMENT document,
@@ -100,7 +116,8 @@
   CPDF_BookmarkTree tree(pDoc);
   FX_STRSIZE len = CFX_WideString::WStringLength(title);
   CFX_WideString encodedTitle = CFX_WideString::FromUTF16LE(title, len);
-  return FindBookmark(tree, CPDF_Bookmark(), encodedTitle).GetDict();
+  std::set<CPDF_Dictionary*> visited;
+  return FindBookmark(tree, CPDF_Bookmark(), encodedTitle, &visited).GetDict();
 }
 
 DLLEXPORT FPDF_DEST STDCALL FPDFBookmark_GetDest(FPDF_DOCUMENT document,
@@ -112,19 +129,19 @@
     return nullptr;
   CPDF_Bookmark bookmark(ToDictionary(static_cast<CPDF_Object*>(pDict)));
   CPDF_Dest dest = bookmark.GetDest(pDoc);
-  if (dest)
+  if (dest.GetObject())
     return dest.GetObject();
   // If this bookmark is not directly associated with a dest, we try to get
   // action
   CPDF_Action action = bookmark.GetAction();
-  if (!action)
+  if (!action.GetDict())
     return nullptr;
   return action.GetDest(pDoc).GetObject();
 }
 
 DLLEXPORT FPDF_ACTION STDCALL FPDFBookmark_GetAction(FPDF_BOOKMARK pDict) {
   if (!pDict)
-    return NULL;
+    return nullptr;
   CPDF_Bookmark bookmark(ToDictionary(static_cast<CPDF_Object*>(pDict)));
   return bookmark.GetAction().GetDict();
 }
@@ -160,8 +177,9 @@
   return action.GetDest(pDoc).GetObject();
 }
 
-DLLEXPORT unsigned long STDCALL
-FPDFAction_GetFilePath(FPDF_ACTION pDict, void* buffer, unsigned long buflen) {
+DLLEXPORT unsigned long STDCALL FPDFAction_GetFilePath(FPDF_ACTION pDict,
+                                                       void* buffer,
+                                                       unsigned long buflen) {
   unsigned long type = FPDFAction_GetType(pDict);
   if (type != PDFACTION_REMOTEGOTO && type != PDFACTION_LAUNCH)
     return 0;
@@ -169,7 +187,7 @@
   CPDF_Action action(ToDictionary(static_cast<CPDF_Object*>(pDict)));
   CFX_ByteString path = action.GetFilePath().UTF8Encode();
   unsigned long len = path.GetLength() + 1;
-  if (buffer && buflen >= len)
+  if (buffer && len <= buflen)
     FXSYS_memcpy(buffer, path.c_str(), len);
   return len;
 }
@@ -186,7 +204,7 @@
   CPDF_Action action(ToDictionary(static_cast<CPDF_Object*>(pDict)));
   CFX_ByteString path = action.GetURI(pDoc);
   unsigned long len = path.GetLength() + 1;
-  if (buffer && buflen >= len)
+  if (buffer && len <= buflen)
     FXSYS_memcpy(buffer, path.c_str(), len);
   return len;
 }
@@ -202,8 +220,35 @@
   return dest.GetPageIndex(pDoc);
 }
 
-DLLEXPORT FPDF_LINK STDCALL
-FPDFLink_GetLinkAtPoint(FPDF_PAGE page, double x, double y) {
+DLLEXPORT FPDF_BOOL STDCALL FPDFDest_GetLocationInPage(FPDF_DEST pDict,
+                                                       FPDF_BOOL* hasXVal,
+                                                       FPDF_BOOL* hasYVal,
+                                                       FPDF_BOOL* hasZoomVal,
+                                                       FS_FLOAT* x,
+                                                       FS_FLOAT* y,
+                                                       FS_FLOAT* zoom) {
+  if (!pDict)
+    return false;
+
+  std::unique_ptr<CPDF_Dest> dest(
+      new CPDF_Dest(static_cast<CPDF_Object*>(pDict)));
+
+  // FPDF_BOOL is an int, GetXYZ expects bools.
+  bool bHasX;
+  bool bHasY;
+  bool bHasZoom;
+  if (!dest->GetXYZ(&bHasX, &bHasY, &bHasZoom, x, y, zoom))
+    return false;
+
+  *hasXVal = bHasX;
+  *hasYVal = bHasY;
+  *hasZoomVal = bHasZoom;
+  return true;
+}
+
+DLLEXPORT FPDF_LINK STDCALL FPDFLink_GetLinkAtPoint(FPDF_PAGE page,
+                                                    double x,
+                                                    double y) {
   CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
   if (!pPage)
     return nullptr;
@@ -216,8 +261,9 @@
       .GetDict();
 }
 
-DLLEXPORT int STDCALL
-FPDFLink_GetLinkZOrderAtPoint(FPDF_PAGE page, double x, double y) {
+DLLEXPORT int STDCALL FPDFLink_GetLinkZOrderAtPoint(FPDF_PAGE page,
+                                                    double x,
+                                                    double y) {
   CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
   if (!pPage)
     return -1;
@@ -244,7 +290,7 @@
     return dest;
   // If this link is not directly associated with a dest, we try to get action
   CPDF_Action action = link.GetAction();
-  if (!action)
+  if (!action.GetDict())
     return nullptr;
   return action.GetDest(pDoc).GetObject();
 }
@@ -261,39 +307,39 @@
                                                int* startPos,
                                                FPDF_LINK* linkAnnot) {
   if (!startPos || !linkAnnot)
-    return FALSE;
+    return false;
   CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
   if (!pPage || !pPage->m_pFormDict)
-    return FALSE;
-  CPDF_Array* pAnnots = pPage->m_pFormDict->GetArray("Annots");
+    return false;
+  CPDF_Array* pAnnots = pPage->m_pFormDict->GetArrayFor("Annots");
   if (!pAnnots)
-    return FALSE;
-  for (int i = *startPos; i < (int)pAnnots->GetCount(); i++) {
+    return false;
+  for (size_t i = *startPos; i < pAnnots->GetCount(); i++) {
     CPDF_Dictionary* pDict =
-        ToDictionary(static_cast<CPDF_Object*>(pAnnots->GetElementValue(i)));
+        ToDictionary(static_cast<CPDF_Object*>(pAnnots->GetDirectObjectAt(i)));
     if (!pDict)
       continue;
-    if (pDict->GetString("Subtype").Equal("Link")) {
-      *startPos = i + 1;
-      *linkAnnot = (FPDF_LINK)pDict;
-      return TRUE;
+    if (pDict->GetStringFor("Subtype") == "Link") {
+      *startPos = static_cast<int>(i + 1);
+      *linkAnnot = static_cast<FPDF_LINK>(pDict);
+      return true;
     }
   }
-  return FALSE;
+  return false;
 }
 
 DLLEXPORT FPDF_BOOL STDCALL FPDFLink_GetAnnotRect(FPDF_LINK linkAnnot,
                                                   FS_RECTF* rect) {
   if (!linkAnnot || !rect)
-    return FALSE;
+    return false;
   CPDF_Dictionary* pAnnotDict =
       ToDictionary(static_cast<CPDF_Object*>(linkAnnot));
-  CPDF_Rect rt = pAnnotDict->GetRect("Rect");
+  CFX_FloatRect rt = pAnnotDict->GetRectFor("Rect");
   rect->left = rt.left;
   rect->bottom = rt.bottom;
   rect->right = rt.right;
   rect->top = rt.top;
-  return TRUE;
+  return true;
 }
 
 DLLEXPORT int STDCALL FPDFLink_CountQuadPoints(FPDF_LINK linkAnnot) {
@@ -301,55 +347,67 @@
     return 0;
   CPDF_Dictionary* pAnnotDict =
       ToDictionary(static_cast<CPDF_Object*>(linkAnnot));
-  CPDF_Array* pArray = pAnnotDict->GetArray("QuadPoints");
+  CPDF_Array* pArray = pAnnotDict->GetArrayFor("QuadPoints");
   if (!pArray)
     return 0;
-  return pArray->GetCount() / 8;
+  return static_cast<int>(pArray->GetCount() / 8);
 }
 
 DLLEXPORT FPDF_BOOL STDCALL FPDFLink_GetQuadPoints(FPDF_LINK linkAnnot,
                                                    int quadIndex,
                                                    FS_QUADPOINTSF* quadPoints) {
   if (!linkAnnot || !quadPoints)
-    return FALSE;
+    return false;
   CPDF_Dictionary* pAnnotDict =
       ToDictionary(static_cast<CPDF_Object*>(linkAnnot));
-  CPDF_Array* pArray = pAnnotDict->GetArray("QuadPoints");
-  if (pArray) {
-    if (quadIndex < 0 || quadIndex >= (int)pArray->GetCount() / 8 ||
-        ((quadIndex * 8 + 7) >= (int)pArray->GetCount()))
-      return FALSE;
-    quadPoints->x1 = pArray->GetNumber(quadIndex * 8);
-    quadPoints->y1 = pArray->GetNumber(quadIndex * 8 + 1);
-    quadPoints->x2 = pArray->GetNumber(quadIndex * 8 + 2);
-    quadPoints->y2 = pArray->GetNumber(quadIndex * 8 + 3);
-    quadPoints->x3 = pArray->GetNumber(quadIndex * 8 + 4);
-    quadPoints->y3 = pArray->GetNumber(quadIndex * 8 + 5);
-    quadPoints->x4 = pArray->GetNumber(quadIndex * 8 + 6);
-    quadPoints->y4 = pArray->GetNumber(quadIndex * 8 + 7);
-    return TRUE;
+  CPDF_Array* pArray = pAnnotDict->GetArrayFor("QuadPoints");
+  if (!pArray)
+    return false;
+
+  if (quadIndex < 0 ||
+      static_cast<size_t>(quadIndex) >= pArray->GetCount() / 8 ||
+      (static_cast<size_t>(quadIndex * 8 + 7) >= pArray->GetCount())) {
+    return false;
   }
-  return FALSE;
+
+  quadPoints->x1 = pArray->GetNumberAt(quadIndex * 8);
+  quadPoints->y1 = pArray->GetNumberAt(quadIndex * 8 + 1);
+  quadPoints->x2 = pArray->GetNumberAt(quadIndex * 8 + 2);
+  quadPoints->y2 = pArray->GetNumberAt(quadIndex * 8 + 3);
+  quadPoints->x3 = pArray->GetNumberAt(quadIndex * 8 + 4);
+  quadPoints->y3 = pArray->GetNumberAt(quadIndex * 8 + 5);
+  quadPoints->x4 = pArray->GetNumberAt(quadIndex * 8 + 6);
+  quadPoints->y4 = pArray->GetNumberAt(quadIndex * 8 + 7);
+  return true;
 }
 
-DLLEXPORT unsigned long STDCALL FPDF_GetMetaText(FPDF_DOCUMENT doc,
+DLLEXPORT unsigned long STDCALL FPDF_GetMetaText(FPDF_DOCUMENT document,
                                                  FPDF_BYTESTRING tag,
                                                  void* buffer,
                                                  unsigned long buflen) {
   if (!tag)
     return 0;
-  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(doc);
+  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
   if (!pDoc)
     return 0;
   CPDF_Dictionary* pInfo = pDoc->GetInfo();
   if (!pInfo)
     return 0;
-  CFX_WideString text = pInfo->GetUnicodeText(tag);
-  // Use UTF-16LE encoding
-  CFX_ByteString encodedText = text.UTF16LE_Encode();
-  unsigned long len = encodedText.GetLength();
-  if (buffer && buflen >= len) {
-    FXSYS_memcpy(buffer, encodedText.c_str(), len);
-  }
-  return len;
+  CFX_WideString text = pInfo->GetUnicodeTextFor(tag);
+  return Utf16EncodeMaybeCopyAndReturnLength(text, buffer, buflen);
+}
+
+DLLEXPORT unsigned long STDCALL FPDF_GetPageLabel(FPDF_DOCUMENT document,
+                                                  int page_index,
+                                                  void* buffer,
+                                                  unsigned long buflen) {
+  if (page_index < 0)
+    return 0;
+
+  // CPDF_PageLabel can deal with NULL |document|.
+  CPDF_PageLabel label(CPDFDocumentFromFPDFDocument(document));
+  CFX_WideString str;
+  if (!label.GetLabel(page_index, &str))
+    return 0;
+  return Utf16EncodeMaybeCopyAndReturnLength(str, buffer, buflen);
 }
diff --git a/fpdfsdk/fpdfdoc_embeddertest.cpp b/fpdfsdk/fpdfdoc_embeddertest.cpp
new file mode 100644
index 0000000..3666687
--- /dev/null
+++ b/fpdfsdk/fpdfdoc_embeddertest.cpp
@@ -0,0 +1,238 @@
+// Copyright 2015 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.
+
+#include <memory>
+#include <string>
+
+#include "core/fxcrt/fx_string.h"
+#include "public/fpdf_doc.h"
+#include "public/fpdf_edit.h"
+#include "public/fpdfview.h"
+#include "testing/embedder_test.h"
+#include "testing/fx_string_testhelpers.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/test_support.h"
+
+class FPDFDocEmbeddertest : public EmbedderTest {};
+
+TEST_F(FPDFDocEmbeddertest, DestGetPageIndex) {
+  EXPECT_TRUE(OpenDocument("named_dests.pdf"));
+
+  // NULL FPDF_DEST case.
+  EXPECT_EQ(0U, FPDFDest_GetPageIndex(document(), nullptr));
+
+  // Page number directly in item from Dests NameTree.
+  FPDF_DEST dest = FPDF_GetNamedDestByName(document(), "First");
+  EXPECT_TRUE(dest);
+  EXPECT_EQ(1U, FPDFDest_GetPageIndex(document(), dest));
+
+  // Page number via object reference in item from Dests NameTree.
+  dest = FPDF_GetNamedDestByName(document(), "Next");
+  EXPECT_TRUE(dest);
+  EXPECT_EQ(1U, FPDFDest_GetPageIndex(document(), dest));
+
+  // Page number directly in item from Dests dictionary.
+  dest = FPDF_GetNamedDestByName(document(), "FirstAlternate");
+  EXPECT_TRUE(dest);
+  EXPECT_EQ(11U, FPDFDest_GetPageIndex(document(), dest));
+
+  // Invalid object reference in item from Dests NameTree.
+  dest = FPDF_GetNamedDestByName(document(), "LastAlternate");
+  EXPECT_TRUE(dest);
+  EXPECT_EQ(0U, FPDFDest_GetPageIndex(document(), dest));
+}
+
+TEST_F(FPDFDocEmbeddertest, DestGetLocationInPage) {
+  EXPECT_TRUE(OpenDocument("named_dests.pdf"));
+
+  // NULL FPDF_DEST case.
+  EXPECT_EQ(0U, FPDFDest_GetPageIndex(document(), nullptr));
+
+  FPDF_DEST dest = FPDF_GetNamedDestByName(document(), "First");
+  EXPECT_TRUE(dest);
+
+  FPDF_BOOL hasX;
+  FPDF_BOOL hasY;
+  FPDF_BOOL hasZoom;
+  FS_FLOAT x;
+  FS_FLOAT y;
+  FS_FLOAT zoom;
+  EXPECT_TRUE(
+      FPDFDest_GetLocationInPage(dest, &hasX, &hasY, &hasZoom, &x, &y, &zoom));
+  EXPECT_TRUE(hasX);
+  EXPECT_TRUE(hasY);
+  EXPECT_TRUE(hasZoom);
+  EXPECT_EQ(0, x);
+  EXPECT_EQ(0, y);
+  EXPECT_EQ(1, zoom);
+}
+
+TEST_F(FPDFDocEmbeddertest, BUG_680376) {
+  EXPECT_TRUE(OpenDocument("bug_680376.pdf"));
+
+  // Page number directly in item from Dests NameTree.
+  FPDF_DEST dest = FPDF_GetNamedDestByName(document(), "First");
+  EXPECT_TRUE(dest);
+  EXPECT_EQ(static_cast<unsigned long>(-1),
+            FPDFDest_GetPageIndex(document(), dest));
+}
+
+TEST_F(FPDFDocEmbeddertest, ActionGetFilePath) {
+  EXPECT_TRUE(OpenDocument("launch_action.pdf"));
+
+  FPDF_PAGE page = FPDF_LoadPage(document(), 0);
+  ASSERT_TRUE(page);
+
+  // The target action is nearly the size of the whole page.
+  FPDF_LINK link = FPDFLink_GetLinkAtPoint(page, 100, 100);
+  ASSERT_TRUE(link);
+
+  FPDF_ACTION action = FPDFLink_GetAction(link);
+  ASSERT_TRUE(action);
+
+  const char kExpectedResult[] = "test.pdf";
+  const unsigned long kExpectedLength = sizeof(kExpectedResult);
+  unsigned long bufsize = FPDFAction_GetFilePath(action, nullptr, 0);
+  ASSERT_EQ(kExpectedLength, bufsize);
+
+  char buf[kExpectedLength];
+  EXPECT_EQ(bufsize, FPDFAction_GetFilePath(action, buf, bufsize));
+  EXPECT_EQ(std::string(kExpectedResult), std::string(buf));
+
+  FPDF_ClosePage(page);
+}
+
+TEST_F(FPDFDocEmbeddertest, NoBookmarks) {
+  // Open a file with no bookmarks.
+  EXPECT_TRUE(OpenDocument("named_dests.pdf"));
+
+  // The non-existent top-level bookmark has no title.
+  unsigned short buf[128];
+  EXPECT_EQ(0u, FPDFBookmark_GetTitle(nullptr, buf, sizeof(buf)));
+
+  // The non-existent top-level bookmark has no children.
+  EXPECT_EQ(nullptr, FPDFBookmark_GetFirstChild(document(), nullptr));
+}
+
+TEST_F(FPDFDocEmbeddertest, Bookmarks) {
+  // Open a file with two bookmarks.
+  EXPECT_TRUE(OpenDocument("bookmarks.pdf"));
+
+  // The existent top-level bookmark has no title.
+  unsigned short buf[128];
+  EXPECT_EQ(0u, FPDFBookmark_GetTitle(nullptr, buf, sizeof(buf)));
+
+  FPDF_BOOKMARK child = FPDFBookmark_GetFirstChild(document(), nullptr);
+  EXPECT_TRUE(child);
+  EXPECT_EQ(34u, FPDFBookmark_GetTitle(child, buf, sizeof(buf)));
+  EXPECT_EQ(CFX_WideString(L"A Good Beginning"),
+            CFX_WideString::FromUTF16LE(buf, 16));
+
+  EXPECT_EQ(nullptr, FPDFBookmark_GetFirstChild(document(), child));
+
+  FPDF_BOOKMARK sibling = FPDFBookmark_GetNextSibling(document(), child);
+  EXPECT_TRUE(sibling);
+  EXPECT_EQ(28u, FPDFBookmark_GetTitle(sibling, buf, sizeof(buf)));
+  EXPECT_EQ(CFX_WideString(L"A Good Ending"),
+            CFX_WideString::FromUTF16LE(buf, 13));
+
+  EXPECT_EQ(nullptr, FPDFBookmark_GetNextSibling(document(), sibling));
+}
+
+TEST_F(FPDFDocEmbeddertest, FindBookmarks) {
+  // Open a file with two bookmarks.
+  EXPECT_TRUE(OpenDocument("bookmarks.pdf"));
+
+  // Find the first one, based on its known title.
+  std::unique_ptr<unsigned short, pdfium::FreeDeleter> title =
+      GetFPDFWideString(L"A Good Beginning");
+  FPDF_BOOKMARK child = FPDFBookmark_Find(document(), title.get());
+  EXPECT_TRUE(child);
+
+  // Check that the string matches.
+  unsigned short buf[128];
+  EXPECT_EQ(34u, FPDFBookmark_GetTitle(child, buf, sizeof(buf)));
+  EXPECT_EQ(CFX_WideString(L"A Good Beginning"),
+            CFX_WideString::FromUTF16LE(buf, 16));
+
+  // Check that it is them same as the one returned by GetFirstChild.
+  EXPECT_EQ(child, FPDFBookmark_GetFirstChild(document(), nullptr));
+
+  // Try to find one using a non-existent title.
+  std::unique_ptr<unsigned short, pdfium::FreeDeleter> bad_title =
+      GetFPDFWideString(L"A BAD Beginning");
+  EXPECT_EQ(nullptr, FPDFBookmark_Find(document(), bad_title.get()));
+}
+
+// Check circular bookmarks will not cause infinite loop.
+TEST_F(FPDFDocEmbeddertest, FindBookmarks_bug420) {
+  // Open a file with circular bookmarks.
+  EXPECT_TRUE(OpenDocument("bookmarks_circular.pdf"));
+
+  // Try to find a title.
+  std::unique_ptr<unsigned short, pdfium::FreeDeleter> title =
+      GetFPDFWideString(L"anything");
+  EXPECT_EQ(nullptr, FPDFBookmark_Find(document(), title.get()));
+}
+
+TEST_F(FPDFDocEmbeddertest, DeletePage) {
+  EXPECT_TRUE(OpenDocument("hello_world.pdf"));
+  EXPECT_EQ(1, FPDF_GetPageCount(document()));
+  FPDFPage_Delete(document(), 0);
+  EXPECT_EQ(0, FPDF_GetPageCount(document()));
+}
+
+TEST_F(FPDFDocEmbeddertest, NoPageLabels) {
+  EXPECT_TRUE(OpenDocument("about_blank.pdf"));
+  EXPECT_EQ(1, FPDF_GetPageCount(document()));
+
+  ASSERT_EQ(0u, FPDF_GetPageLabel(document(), 0, nullptr, 0));
+}
+
+TEST_F(FPDFDocEmbeddertest, GetPageLabels) {
+  EXPECT_TRUE(OpenDocument("page_labels.pdf"));
+  EXPECT_EQ(7, FPDF_GetPageCount(document()));
+
+  unsigned short buf[128];
+  EXPECT_EQ(0u, FPDF_GetPageLabel(document(), -2, buf, sizeof(buf)));
+  EXPECT_EQ(0u, FPDF_GetPageLabel(document(), -1, buf, sizeof(buf)));
+
+  const FX_WCHAR kExpectedPageLabel0[] = L"i";
+  ASSERT_EQ(4u, FPDF_GetPageLabel(document(), 0, buf, sizeof(buf)));
+  EXPECT_EQ(CFX_WideString(kExpectedPageLabel0),
+            CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel0)));
+
+  const FX_WCHAR kExpectedPageLabel1[] = L"ii";
+  ASSERT_EQ(6u, FPDF_GetPageLabel(document(), 1, buf, sizeof(buf)));
+  EXPECT_EQ(CFX_WideString(kExpectedPageLabel1),
+            CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel1)));
+
+  const FX_WCHAR kExpectedPageLabel2[] = L"1";
+  ASSERT_EQ(4u, FPDF_GetPageLabel(document(), 2, buf, sizeof(buf)));
+  EXPECT_EQ(CFX_WideString(kExpectedPageLabel2),
+            CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel2)));
+
+  const FX_WCHAR kExpectedPageLabel3[] = L"2";
+  ASSERT_EQ(4u, FPDF_GetPageLabel(document(), 3, buf, sizeof(buf)));
+  EXPECT_EQ(CFX_WideString(kExpectedPageLabel3),
+            CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel3)));
+
+  const FX_WCHAR kExpectedPageLabel4[] = L"zzA";
+  ASSERT_EQ(8u, FPDF_GetPageLabel(document(), 4, buf, sizeof(buf)));
+  EXPECT_EQ(CFX_WideString(kExpectedPageLabel4),
+            CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel4)));
+
+  const FX_WCHAR kExpectedPageLabel5[] = L"zzB";
+  ASSERT_EQ(8u, FPDF_GetPageLabel(document(), 5, buf, sizeof(buf)));
+  EXPECT_EQ(CFX_WideString(kExpectedPageLabel5),
+            CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel5)));
+
+  const FX_WCHAR kExpectedPageLabel6[] = L"";
+  ASSERT_EQ(2u, FPDF_GetPageLabel(document(), 6, buf, sizeof(buf)));
+  EXPECT_EQ(CFX_WideString(kExpectedPageLabel6),
+            CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel6)));
+
+  ASSERT_EQ(0u, FPDF_GetPageLabel(document(), 7, buf, sizeof(buf)));
+  ASSERT_EQ(0u, FPDF_GetPageLabel(document(), 8, buf, sizeof(buf)));
+}
diff --git a/fpdfsdk/fpdfdoc_unittest.cpp b/fpdfsdk/fpdfdoc_unittest.cpp
new file mode 100644
index 0000000..c63d6c2
--- /dev/null
+++ b/fpdfsdk/fpdfdoc_unittest.cpp
@@ -0,0 +1,274 @@
+// 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.
+
+#include "public/fpdf_doc.h"
+
+#include <memory>
+#include <vector>
+
+#include "core/fpdfapi/cpdf_modulemgr.h"
+#include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/cpdf_name.h"
+#include "core/fpdfapi/parser/cpdf_null.h"
+#include "core/fpdfapi/parser/cpdf_number.h"
+#include "core/fpdfapi/parser/cpdf_parser.h"
+#include "core/fpdfapi/parser/cpdf_reference.h"
+#include "core/fpdfapi/parser/cpdf_string.h"
+#include "core/fpdfdoc/cpdf_dest.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/test_support.h"
+#include "third_party/base/ptr_util.h"
+
+#ifdef PDF_ENABLE_XFA
+#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
+#endif  // PDF_ENABLE_XFA
+
+class CPDF_TestDocument : public CPDF_Document {
+ public:
+  CPDF_TestDocument() : CPDF_Document(nullptr) {}
+
+  void SetRoot(CPDF_Dictionary* root) { m_pRootDict = root; }
+  CPDF_IndirectObjectHolder* GetHolder() { return this; }
+};
+
+#ifdef PDF_ENABLE_XFA
+class CPDF_TestXFAContext : public CPDFXFA_Context {
+ public:
+  CPDF_TestXFAContext()
+      : CPDFXFA_Context(pdfium::MakeUnique<CPDF_TestDocument>()) {}
+
+  void SetRoot(CPDF_Dictionary* root) {
+    reinterpret_cast<CPDF_TestDocument*>(GetPDFDoc())->SetRoot(root);
+  }
+
+  CPDF_IndirectObjectHolder* GetHolder() { return GetPDFDoc(); }
+};
+using CPDF_TestPdfDocument = CPDF_TestXFAContext;
+#else   // PDF_ENABLE_XFA
+using CPDF_TestPdfDocument = CPDF_TestDocument;
+#endif  // PDF_ENABLE_XFA
+
+class PDFDocTest : public testing::Test {
+ public:
+  struct DictObjInfo {
+    uint32_t num;
+    CPDF_Dictionary* obj;
+  };
+
+  void SetUp() override {
+    // We don't need page module or render module, but
+    // initialize them to keep the code sane.
+    CPDF_ModuleMgr* module_mgr = CPDF_ModuleMgr::Get();
+    module_mgr->InitPageModule();
+
+    m_pDoc = pdfium::MakeUnique<CPDF_TestPdfDocument>();
+    m_pIndirectObjs = m_pDoc->GetHolder();
+
+    // Setup the root directory.
+    m_pRootObj = pdfium::MakeUnique<CPDF_Dictionary>();
+    m_pDoc->SetRoot(m_pRootObj.get());
+  }
+
+  void TearDown() override {
+    m_pRootObj.reset();
+    m_pIndirectObjs = nullptr;
+    m_pDoc.reset();
+    CPDF_ModuleMgr::Destroy();
+  }
+
+  std::vector<DictObjInfo> CreateDictObjs(int num) {
+    std::vector<DictObjInfo> info;
+    for (int i = 0; i < num; ++i) {
+      // Objects created will be released by the document.
+      CPDF_Dictionary* obj = m_pIndirectObjs->NewIndirect<CPDF_Dictionary>();
+      info.push_back({obj->GetObjNum(), obj});
+    }
+    return info;
+  }
+
+ protected:
+  std::unique_ptr<CPDF_TestPdfDocument> m_pDoc;
+  CPDF_IndirectObjectHolder* m_pIndirectObjs;
+  std::unique_ptr<CPDF_Dictionary> m_pRootObj;
+};
+
+TEST_F(PDFDocTest, FindBookmark) {
+  {
+    // No bookmark information.
+    std::unique_ptr<unsigned short, pdfium::FreeDeleter> title =
+        GetFPDFWideString(L"");
+    EXPECT_EQ(nullptr, FPDFBookmark_Find(m_pDoc.get(), title.get()));
+
+    title = GetFPDFWideString(L"Preface");
+    EXPECT_EQ(nullptr, FPDFBookmark_Find(m_pDoc.get(), title.get()));
+  }
+  {
+    // Empty bookmark tree.
+    m_pRootObj->SetNewFor<CPDF_Dictionary>("Outlines");
+    std::unique_ptr<unsigned short, pdfium::FreeDeleter> title =
+        GetFPDFWideString(L"");
+    EXPECT_EQ(nullptr, FPDFBookmark_Find(m_pDoc.get(), title.get()));
+
+    title = GetFPDFWideString(L"Preface");
+    EXPECT_EQ(nullptr, FPDFBookmark_Find(m_pDoc.get(), title.get()));
+  }
+  {
+    // Check on a regular bookmark tree.
+    auto bookmarks = CreateDictObjs(3);
+
+    bookmarks[1].obj->SetNewFor<CPDF_String>("Title", L"Chapter 1");
+    bookmarks[1].obj->SetNewFor<CPDF_Reference>("Parent", m_pIndirectObjs,
+                                                bookmarks[0].num);
+    bookmarks[1].obj->SetNewFor<CPDF_Reference>("Next", m_pIndirectObjs,
+                                                bookmarks[2].num);
+
+    bookmarks[2].obj->SetNewFor<CPDF_String>("Title", L"Chapter 2");
+    bookmarks[2].obj->SetNewFor<CPDF_Reference>("Parent", m_pIndirectObjs,
+                                                bookmarks[0].num);
+    bookmarks[2].obj->SetNewFor<CPDF_Reference>("Prev", m_pIndirectObjs,
+                                                bookmarks[1].num);
+
+    bookmarks[0].obj->SetNewFor<CPDF_Name>("Type", "Outlines");
+    bookmarks[0].obj->SetNewFor<CPDF_Number>("Count", 2);
+    bookmarks[0].obj->SetNewFor<CPDF_Reference>("First", m_pIndirectObjs,
+                                                bookmarks[1].num);
+    bookmarks[0].obj->SetNewFor<CPDF_Reference>("Last", m_pIndirectObjs,
+                                                bookmarks[2].num);
+
+    m_pRootObj->SetNewFor<CPDF_Reference>("Outlines", m_pIndirectObjs,
+                                          bookmarks[0].num);
+
+    // Title with no match.
+    std::unique_ptr<unsigned short, pdfium::FreeDeleter> title =
+        GetFPDFWideString(L"Chapter 3");
+    EXPECT_EQ(nullptr, FPDFBookmark_Find(m_pDoc.get(), title.get()));
+
+    // Title with partial match only.
+    title = GetFPDFWideString(L"Chapter");
+    EXPECT_EQ(nullptr, FPDFBookmark_Find(m_pDoc.get(), title.get()));
+
+    // Title with a match.
+    title = GetFPDFWideString(L"Chapter 2");
+    EXPECT_EQ(bookmarks[2].obj, FPDFBookmark_Find(m_pDoc.get(), title.get()));
+
+    // Title match is case insensitive.
+    title = GetFPDFWideString(L"cHaPter 2");
+    EXPECT_EQ(bookmarks[2].obj, FPDFBookmark_Find(m_pDoc.get(), title.get()));
+  }
+  {
+    // Circular bookmarks in depth.
+    auto bookmarks = CreateDictObjs(3);
+
+    bookmarks[1].obj->SetNewFor<CPDF_String>("Title", L"Chapter 1");
+    bookmarks[1].obj->SetNewFor<CPDF_Reference>("Parent", m_pIndirectObjs,
+                                                bookmarks[0].num);
+    bookmarks[1].obj->SetNewFor<CPDF_Reference>("First", m_pIndirectObjs,
+                                                bookmarks[2].num);
+
+    bookmarks[2].obj->SetNewFor<CPDF_String>("Title", L"Chapter 2");
+    bookmarks[2].obj->SetNewFor<CPDF_Reference>("Parent", m_pIndirectObjs,
+                                                bookmarks[1].num);
+    bookmarks[2].obj->SetNewFor<CPDF_Reference>("First", m_pIndirectObjs,
+                                                bookmarks[1].num);
+
+    bookmarks[0].obj->SetNewFor<CPDF_Name>("Type", "Outlines");
+    bookmarks[0].obj->SetNewFor<CPDF_Number>("Count", 2);
+    bookmarks[0].obj->SetNewFor<CPDF_Reference>("First", m_pIndirectObjs,
+                                                bookmarks[1].num);
+    bookmarks[0].obj->SetNewFor<CPDF_Reference>("Last", m_pIndirectObjs,
+                                                bookmarks[2].num);
+
+    m_pRootObj->SetNewFor<CPDF_Reference>("Outlines", m_pIndirectObjs,
+                                          bookmarks[0].num);
+
+    // Title with no match.
+    std::unique_ptr<unsigned short, pdfium::FreeDeleter> title =
+        GetFPDFWideString(L"Chapter 3");
+    EXPECT_EQ(nullptr, FPDFBookmark_Find(m_pDoc.get(), title.get()));
+
+    // Title with a match.
+    title = GetFPDFWideString(L"Chapter 2");
+    EXPECT_EQ(bookmarks[2].obj, FPDFBookmark_Find(m_pDoc.get(), title.get()));
+  }
+  {
+    // Circular bookmarks in breadth.
+    auto bookmarks = CreateDictObjs(4);
+
+    bookmarks[1].obj->SetNewFor<CPDF_String>("Title", L"Chapter 1");
+    bookmarks[1].obj->SetNewFor<CPDF_Reference>("Parent", m_pIndirectObjs,
+                                                bookmarks[0].num);
+    bookmarks[1].obj->SetNewFor<CPDF_Reference>("Next", m_pIndirectObjs,
+                                                bookmarks[2].num);
+
+    bookmarks[2].obj->SetNewFor<CPDF_String>("Title", L"Chapter 2");
+    bookmarks[2].obj->SetNewFor<CPDF_Reference>("Parent", m_pIndirectObjs,
+                                                bookmarks[0].num);
+    bookmarks[2].obj->SetNewFor<CPDF_Reference>("Next", m_pIndirectObjs,
+                                                bookmarks[3].num);
+
+    bookmarks[3].obj->SetNewFor<CPDF_String>("Title", L"Chapter 3");
+    bookmarks[3].obj->SetNewFor<CPDF_Reference>("Parent", m_pIndirectObjs,
+                                                bookmarks[0].num);
+    bookmarks[3].obj->SetNewFor<CPDF_Reference>("Next", m_pIndirectObjs,
+                                                bookmarks[1].num);
+
+    bookmarks[0].obj->SetNewFor<CPDF_Name>("Type", "Outlines");
+    bookmarks[0].obj->SetNewFor<CPDF_Number>("Count", 2);
+    bookmarks[0].obj->SetNewFor<CPDF_Reference>("First", m_pIndirectObjs,
+                                                bookmarks[1].num);
+    bookmarks[0].obj->SetNewFor<CPDF_Reference>("Last", m_pIndirectObjs,
+                                                bookmarks[2].num);
+
+    m_pRootObj->SetNewFor<CPDF_Reference>("Outlines", m_pIndirectObjs,
+                                          bookmarks[0].num);
+
+    // Title with no match.
+    std::unique_ptr<unsigned short, pdfium::FreeDeleter> title =
+        GetFPDFWideString(L"Chapter 8");
+    EXPECT_EQ(nullptr, FPDFBookmark_Find(m_pDoc.get(), title.get()));
+
+    // Title with a match.
+    title = GetFPDFWideString(L"Chapter 3");
+    EXPECT_EQ(bookmarks[3].obj, FPDFBookmark_Find(m_pDoc.get(), title.get()));
+  }
+}
+
+TEST_F(PDFDocTest, GetLocationInPage) {
+  auto array = pdfium::MakeUnique<CPDF_Array>();
+  array->AddNew<CPDF_Number>(0);  // Page Index.
+  array->AddNew<CPDF_Name>("XYZ");
+  array->AddNew<CPDF_Number>(4);  // X
+  array->AddNew<CPDF_Number>(5);  // Y
+  array->AddNew<CPDF_Number>(6);  // Zoom.
+
+  FPDF_BOOL hasX;
+  FPDF_BOOL hasY;
+  FPDF_BOOL hasZoom;
+  FS_FLOAT x;
+  FS_FLOAT y;
+  FS_FLOAT zoom;
+
+  EXPECT_TRUE(FPDFDest_GetLocationInPage(array.get(), &hasX, &hasY, &hasZoom,
+                                         &x, &y, &zoom));
+  EXPECT_TRUE(hasX);
+  EXPECT_TRUE(hasY);
+  EXPECT_TRUE(hasZoom);
+  EXPECT_EQ(4, x);
+  EXPECT_EQ(5, y);
+  EXPECT_EQ(6, zoom);
+
+  array->SetNewAt<CPDF_Null>(2);
+  array->SetNewAt<CPDF_Null>(3);
+  array->SetNewAt<CPDF_Null>(4);
+  EXPECT_TRUE(FPDFDest_GetLocationInPage(array.get(), &hasX, &hasY, &hasZoom,
+                                         &x, &y, &zoom));
+  EXPECT_FALSE(hasX);
+  EXPECT_FALSE(hasY);
+  EXPECT_FALSE(hasZoom);
+
+  array = pdfium::MakeUnique<CPDF_Array>();
+  EXPECT_FALSE(FPDFDest_GetLocationInPage(array.get(), &hasX, &hasY, &hasZoom,
+                                          &x, &y, &zoom));
+}
diff --git a/fpdfsdk/fpdfedit_embeddertest.cpp b/fpdfsdk/fpdfedit_embeddertest.cpp
new file mode 100644
index 0000000..40bed3a
--- /dev/null
+++ b/fpdfsdk/fpdfedit_embeddertest.cpp
@@ -0,0 +1,155 @@
+// 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.
+
+#include <memory>
+#include <string>
+
+#include "public/fpdf_edit.h"
+#include "public/fpdfview.h"
+#include "testing/embedder_test.h"
+#include "testing/gmock/include/gmock/gmock-matchers.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/test_support.h"
+
+class FPDFEditEmbeddertest : public EmbedderTest, public TestSaver {};
+
+namespace {
+
+const char kExpectedPDF[] =
+    "%PDF-1.7\r\n"
+    "%\xA1\xB3\xC5\xD7\r\n"
+    "1 0 obj\r\n"
+    "<</Pages 2 0 R /Type/Catalog>>\r\n"
+    "endobj\r\n"
+    "2 0 obj\r\n"
+    "<</Count 1/Kids\\[ 4 0 R \\]/Type/Pages>>\r\n"
+    "endobj\r\n"
+    "3 0 obj\r\n"
+    "<</CreationDate\\(D:.*\\)/Creator\\(PDFium\\)>>\r\n"
+    "endobj\r\n"
+    "4 0 obj\r\n"
+    "<</Contents 5 0 R /MediaBox\\[ 0 0 640 480\\]"
+    "/Parent 2 0 R /Resources<<>>/Rotate 0/Type/Page"
+    ">>\r\n"
+    "endobj\r\n"
+    "5 0 obj\r\n"
+    "<</Filter/FlateDecode/Length 8>>stream\r\n"
+    // Character '_' is matching '\0' (see comment below).
+    "x\x9C\x3____\x1\r\n"
+    "endstream\r\n"
+    "endobj\r\n"
+    "xref\r\n"
+    "0 6\r\n"
+    "0000000000 65535 f\r\n"
+    "0000000017 00000 n\r\n"
+    "0000000066 00000 n\r\n"
+    "0000000122 00000 n\r\n"
+    "0000000192 00000 n\r\n"
+    "0000000301 00000 n\r\n"
+    "trailer\r\n"
+    "<<\r\n"
+    "/Root 1 0 R\r\n"
+    "/Info 3 0 R\r\n"
+    "/Size 6/ID\\[<.*><.*>\\]>>\r\n"
+    "startxref\r\n"
+    "379\r\n"
+    "%%EOF\r\n";
+
+int GetBlockFromString(void* param,
+                       unsigned long pos,
+                       unsigned char* buf,
+                       unsigned long size) {
+  std::string* new_file = static_cast<std::string*>(param);
+  if (!new_file || pos + size < pos)
+    return 0;
+
+  unsigned long file_size = new_file->size();
+  if (pos + size > file_size)
+    return 0;
+
+  memcpy(buf, new_file->data() + pos, size);
+  return 1;
+}
+
+}  // namespace
+
+TEST_F(FPDFEditEmbeddertest, EmptyCreation) {
+  EXPECT_TRUE(CreateEmptyDocument());
+  FPDF_PAGE page = FPDFPage_New(document(), 0, 640.0, 480.0);
+  EXPECT_NE(nullptr, page);
+  EXPECT_TRUE(FPDFPage_GenerateContent(page));
+  EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
+
+  // The MatchesRegexp doesn't support embedded NUL ('\0') characters. They are
+  // replaced by '_' for the purpose of the test.
+  std::string result = GetString();
+  std::replace(result.begin(), result.end(), '\0', '_');
+  EXPECT_THAT(result, testing::MatchesRegex(
+                          std::string(kExpectedPDF, sizeof(kExpectedPDF))));
+  FPDF_ClosePage(page);
+}
+
+// Regression test for https://crbug.com/667012
+TEST_F(FPDFEditEmbeddertest, RasterizePDF) {
+  const char kAllBlackMd5sum[] = "5708fc5c4a8bd0abde99c8e8f0390615";
+
+  // Get the bitmap for the original document/
+  FPDF_BITMAP orig_bitmap;
+  {
+    EXPECT_TRUE(OpenDocument("black.pdf"));
+    FPDF_PAGE orig_page = LoadPage(0);
+    EXPECT_NE(nullptr, orig_page);
+    orig_bitmap = RenderPage(orig_page);
+    CompareBitmap(orig_bitmap, 612, 792, kAllBlackMd5sum);
+    UnloadPage(orig_page);
+  }
+
+  // Create a new document from |orig_bitmap| and save it.
+  {
+    FPDF_DOCUMENT temp_doc = FPDF_CreateNewDocument();
+    FPDF_PAGE temp_page = FPDFPage_New(temp_doc, 0, 612, 792);
+
+    // Add the bitmap to an image object and add the image object to the output
+    // page.
+    FPDF_PAGEOBJECT temp_img = FPDFPageObj_NewImgeObj(temp_doc);
+    EXPECT_TRUE(FPDFImageObj_SetBitmap(&temp_page, 1, temp_img, orig_bitmap));
+    EXPECT_TRUE(FPDFImageObj_SetMatrix(temp_img, 612, 0, 0, 792, 0, 0));
+    FPDFPage_InsertObject(temp_page, temp_img);
+    EXPECT_TRUE(FPDFPage_GenerateContent(temp_page));
+    EXPECT_TRUE(FPDF_SaveAsCopy(temp_doc, this, 0));
+    FPDF_ClosePage(temp_page);
+    FPDF_CloseDocument(temp_doc);
+  }
+  FPDFBitmap_Destroy(orig_bitmap);
+
+  // Get the generated content. Make sure it is at least as big as the original
+  // PDF.
+  std::string new_file = GetString();
+  EXPECT_GT(new_file.size(), 923U);
+
+  // Read |new_file| in, and verify its rendered bitmap.
+  {
+    FPDF_FILEACCESS file_access;
+    memset(&file_access, 0, sizeof(file_access));
+    file_access.m_FileLen = new_file.size();
+    file_access.m_GetBlock = GetBlockFromString;
+    file_access.m_Param = &new_file;
+
+    FPDF_DOCUMENT new_doc = FPDF_LoadCustomDocument(&file_access, nullptr);
+    EXPECT_EQ(1, FPDF_GetPageCount(document_));
+    FPDF_PAGE new_page = FPDF_LoadPage(new_doc, 0);
+    EXPECT_NE(nullptr, new_page);
+    int width = static_cast<int>(FPDF_GetPageWidth(new_page));
+    int height = static_cast<int>(FPDF_GetPageHeight(new_page));
+    int alpha = FPDFPage_HasTransparency(new_page) ? 1 : 0;
+    FPDF_BITMAP new_bitmap = FPDFBitmap_Create(width, height, alpha);
+    FPDF_DWORD fill_color = alpha ? 0x00000000 : 0xFFFFFFFF;
+    FPDFBitmap_FillRect(new_bitmap, 0, 0, width, height, fill_color);
+    FPDF_RenderPageBitmap(new_bitmap, new_page, 0, 0, width, height, 0, 0);
+    CompareBitmap(new_bitmap, 612, 792, kAllBlackMd5sum);
+    FPDF_ClosePage(new_page);
+    FPDF_CloseDocument(new_doc);
+    FPDFBitmap_Destroy(new_bitmap);
+  }
+}
diff --git a/fpdfsdk/fpdfeditimg.cpp b/fpdfsdk/fpdfeditimg.cpp
new file mode 100644
index 0000000..56875e2
--- /dev/null
+++ b/fpdfsdk/fpdfeditimg.cpp
@@ -0,0 +1,105 @@
+// 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
+
+#include "public/fpdf_edit.h"
+
+#include "core/fpdfapi/cpdf_modulemgr.h"
+#include "core/fpdfapi/page/cpdf_image.h"
+#include "core/fpdfapi/page/cpdf_imageobject.h"
+#include "core/fpdfapi/page/cpdf_pageobject.h"
+#include "fpdfsdk/fsdk_define.h"
+#include "third_party/base/ptr_util.h"
+
+DLLEXPORT FPDF_PAGEOBJECT STDCALL
+FPDFPageObj_NewImgeObj(FPDF_DOCUMENT document) {
+  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
+  if (!pDoc)
+    return nullptr;
+
+  CPDF_ImageObject* pImageObj = new CPDF_ImageObject;
+  pImageObj->SetOwnedImage(pdfium::MakeUnique<CPDF_Image>(pDoc));
+  return pImageObj;
+}
+
+FPDF_BOOL FPDFImageObj_LoadJpegHelper(FPDF_PAGE* pages,
+                                      int nCount,
+                                      FPDF_PAGEOBJECT image_object,
+                                      FPDF_FILEACCESS* fileAccess,
+                                      bool inlineJpeg) {
+  if (!image_object || !fileAccess || !pages)
+    return false;
+
+  CFX_RetainPtr<IFX_SeekableReadStream> pFile =
+      MakeSeekableReadStream(fileAccess);
+  CPDF_ImageObject* pImgObj = reinterpret_cast<CPDF_ImageObject*>(image_object);
+  for (int index = 0; index < nCount; index++) {
+    CPDF_Page* pPage = CPDFPageFromFPDFPage(pages[index]);
+    if (pPage)
+      pImgObj->GetImage()->ResetCache(pPage, nullptr);
+  }
+
+  if (inlineJpeg)
+    pImgObj->GetImage()->SetJpegImageInline(pFile);
+  else
+    pImgObj->GetImage()->SetJpegImage(pFile);
+
+  return true;
+}
+
+DLLEXPORT FPDF_BOOL STDCALL
+FPDFImageObj_LoadJpegFile(FPDF_PAGE* pages,
+                          int nCount,
+                          FPDF_PAGEOBJECT image_object,
+                          FPDF_FILEACCESS* fileAccess) {
+  return FPDFImageObj_LoadJpegHelper(pages, nCount, image_object, fileAccess,
+                                     false);
+}
+
+DLLEXPORT FPDF_BOOL STDCALL
+FPDFImageObj_LoadJpegFileInline(FPDF_PAGE* pages,
+                                int nCount,
+                                FPDF_PAGEOBJECT image_object,
+                                FPDF_FILEACCESS* fileAccess) {
+  return FPDFImageObj_LoadJpegHelper(pages, nCount, image_object, fileAccess,
+                                     true);
+}
+
+DLLEXPORT FPDF_BOOL STDCALL FPDFImageObj_SetMatrix(FPDF_PAGEOBJECT image_object,
+                                                   double a,
+                                                   double b,
+                                                   double c,
+                                                   double d,
+                                                   double e,
+                                                   double f) {
+  if (!image_object)
+    return false;
+
+  CPDF_ImageObject* pImgObj = reinterpret_cast<CPDF_ImageObject*>(image_object);
+  pImgObj->set_matrix(
+      CFX_Matrix(static_cast<FX_FLOAT>(a), static_cast<FX_FLOAT>(b),
+                 static_cast<FX_FLOAT>(c), static_cast<FX_FLOAT>(d),
+                 static_cast<FX_FLOAT>(e), static_cast<FX_FLOAT>(f)));
+  pImgObj->CalcBoundingBox();
+  return true;
+}
+
+DLLEXPORT FPDF_BOOL STDCALL FPDFImageObj_SetBitmap(FPDF_PAGE* pages,
+                                                   int nCount,
+                                                   FPDF_PAGEOBJECT image_object,
+                                                   FPDF_BITMAP bitmap) {
+  if (!image_object || !bitmap || !pages)
+    return false;
+
+  CPDF_ImageObject* pImgObj = reinterpret_cast<CPDF_ImageObject*>(image_object);
+  for (int index = 0; index < nCount; index++) {
+    CPDF_Page* pPage = CPDFPageFromFPDFPage(pages[index]);
+    if (pPage)
+      pImgObj->GetImage()->ResetCache(pPage, nullptr);
+  }
+  pImgObj->GetImage()->SetImage(reinterpret_cast<CFX_DIBitmap*>(bitmap));
+  pImgObj->CalcBoundingBox();
+  return true;
+}
diff --git a/fpdfsdk/fpdfeditimg_unittest.cpp b/fpdfsdk/fpdfeditimg_unittest.cpp
new file mode 100644
index 0000000..ae4af25
--- /dev/null
+++ b/fpdfsdk/fpdfeditimg_unittest.cpp
@@ -0,0 +1,74 @@
+// 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.
+
+#include "public/fpdf_edit.h"
+
+#include "core/fpdfapi/cpdf_modulemgr.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+class PDFEditTest : public testing::Test {
+  void SetUp() override {
+    CPDF_ModuleMgr* module_mgr = CPDF_ModuleMgr::Get();
+    module_mgr->InitPageModule();
+  }
+
+  void TearDown() override { CPDF_ModuleMgr::Destroy(); }
+};
+
+TEST_F(PDFEditTest, InsertObjectWithInvalidPage) {
+  FPDF_DOCUMENT doc = FPDF_CreateNewDocument();
+  FPDF_PAGE page = FPDFPage_New(doc, 0, 100, 100);
+  EXPECT_EQ(0, FPDFPage_CountObject(page));
+
+  FPDFPage_InsertObject(nullptr, nullptr);
+  EXPECT_EQ(0, FPDFPage_CountObject(page));
+
+  FPDFPage_InsertObject(page, nullptr);
+  EXPECT_EQ(0, FPDFPage_CountObject(page));
+
+  FPDF_PAGEOBJECT page_image = FPDFPageObj_NewImgeObj(doc);
+  FPDFPage_InsertObject(nullptr, page_image);
+  EXPECT_EQ(0, FPDFPage_CountObject(page));
+
+  FPDF_ClosePage(page);
+  FPDF_CloseDocument(doc);
+}
+
+TEST_F(PDFEditTest, NewImgeObj) {
+  FPDF_DOCUMENT doc = FPDF_CreateNewDocument();
+  FPDF_PAGE page = FPDFPage_New(doc, 0, 100, 100);
+  EXPECT_EQ(0, FPDFPage_CountObject(page));
+
+  FPDF_PAGEOBJECT page_image = FPDFPageObj_NewImgeObj(doc);
+  FPDFPage_InsertObject(page, page_image);
+  EXPECT_EQ(1, FPDFPage_CountObject(page));
+  EXPECT_TRUE(FPDFPage_GenerateContent(page));
+
+  FPDF_ClosePage(page);
+  FPDF_CloseDocument(doc);
+}
+
+TEST_F(PDFEditTest, NewImgeObjGenerateContent) {
+  FPDF_DOCUMENT doc = FPDF_CreateNewDocument();
+  FPDF_PAGE page = FPDFPage_New(doc, 0, 100, 100);
+  EXPECT_EQ(0, FPDFPage_CountObject(page));
+
+  constexpr int kBitmapSize = 50;
+  FPDF_BITMAP bitmap = FPDFBitmap_Create(kBitmapSize, kBitmapSize, 0);
+  FPDFBitmap_FillRect(bitmap, 0, 0, kBitmapSize, kBitmapSize, 0x00000000);
+  EXPECT_EQ(kBitmapSize, FPDFBitmap_GetWidth(bitmap));
+  EXPECT_EQ(kBitmapSize, FPDFBitmap_GetHeight(bitmap));
+
+  FPDF_PAGEOBJECT page_image = FPDFPageObj_NewImgeObj(doc);
+  ASSERT_TRUE(FPDFImageObj_SetBitmap(&page, 0, page_image, bitmap));
+  ASSERT_TRUE(
+      FPDFImageObj_SetMatrix(page_image, kBitmapSize, 0, 0, kBitmapSize, 0, 0));
+  FPDFPage_InsertObject(page, page_image);
+  EXPECT_EQ(1, FPDFPage_CountObject(page));
+  EXPECT_TRUE(FPDFPage_GenerateContent(page));
+
+  FPDFBitmap_Destroy(bitmap);
+  FPDF_ClosePage(page);
+  FPDF_CloseDocument(doc);
+}
diff --git a/fpdfsdk/fpdfeditpage.cpp b/fpdfsdk/fpdfeditpage.cpp
new file mode 100644
index 0000000..18a1d61
--- /dev/null
+++ b/fpdfsdk/fpdfeditpage.cpp
@@ -0,0 +1,315 @@
+// 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
+
+#include "public/fpdf_edit.h"
+
+#include <algorithm>
+#include <memory>
+#include <utility>
+
+#include "core/fpdfapi/edit/cpdf_pagecontentgenerator.h"
+#include "core/fpdfapi/page/cpdf_form.h"
+#include "core/fpdfapi/page/cpdf_formobject.h"
+#include "core/fpdfapi/page/cpdf_imageobject.h"
+#include "core/fpdfapi/page/cpdf_page.h"
+#include "core/fpdfapi/page/cpdf_pageobject.h"
+#include "core/fpdfapi/page/cpdf_pathobject.h"
+#include "core/fpdfapi/page/cpdf_shadingobject.h"
+#include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/cpdf_number.h"
+#include "core/fpdfapi/parser/cpdf_string.h"
+#include "core/fpdfdoc/cpdf_annot.h"
+#include "core/fpdfdoc/cpdf_annotlist.h"
+#include "fpdfsdk/fsdk_define.h"
+#include "public/fpdf_formfill.h"
+#include "third_party/base/stl_util.h"
+
+#ifdef PDF_ENABLE_XFA
+#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
+#include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
+#endif  // PDF_ENABLE_XFA
+
+#if _FX_OS_ == _FX_ANDROID_
+#include <time.h>
+#else
+#include <ctime>
+#endif
+
+namespace {
+
+static_assert(FPDF_PAGEOBJ_TEXT == CPDF_PageObject::TEXT,
+              "FPDF_PAGEOBJ_TEXT/CPDF_PageObject::TEXT mismatch");
+static_assert(FPDF_PAGEOBJ_PATH == CPDF_PageObject::PATH,
+              "FPDF_PAGEOBJ_PATH/CPDF_PageObject::PATH mismatch");
+static_assert(FPDF_PAGEOBJ_IMAGE == CPDF_PageObject::IMAGE,
+              "FPDF_PAGEOBJ_IMAGE/CPDF_PageObject::IMAGE mismatch");
+static_assert(FPDF_PAGEOBJ_SHADING == CPDF_PageObject::SHADING,
+              "FPDF_PAGEOBJ_SHADING/CPDF_PageObject::SHADING mismatch");
+static_assert(FPDF_PAGEOBJ_FORM == CPDF_PageObject::FORM,
+              "FPDF_PAGEOBJ_FORM/CPDF_PageObject::FORM mismatch");
+
+bool IsPageObject(CPDF_Page* pPage) {
+  if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type"))
+    return false;
+
+  CPDF_Object* pObject = pPage->m_pFormDict->GetObjectFor("Type")->GetDirect();
+  return pObject && !pObject->GetString().Compare("Page");
+}
+
+}  // namespace
+
+DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_CreateNewDocument() {
+  CPDF_Document* pDoc = new CPDF_Document(nullptr);
+  pDoc->CreateNewDoc();
+  time_t currentTime;
+
+  CFX_ByteString DateStr;
+
+  if (FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS)) {
+    if (-1 != time(&currentTime)) {
+      tm* pTM = localtime(&currentTime);
+      if (pTM) {
+        DateStr.Format("D:%04d%02d%02d%02d%02d%02d", pTM->tm_year + 1900,
+                       pTM->tm_mon + 1, pTM->tm_mday, pTM->tm_hour, pTM->tm_min,
+                       pTM->tm_sec);
+      }
+    }
+  }
+
+  CPDF_Dictionary* pInfoDict = nullptr;
+  pInfoDict = pDoc->GetInfo();
+  if (pInfoDict) {
+    if (FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
+      pInfoDict->SetNewFor<CPDF_String>("CreationDate", DateStr, false);
+    pInfoDict->SetNewFor<CPDF_String>("Creator", L"PDFium");
+  }
+
+  return FPDFDocumentFromCPDFDocument(pDoc);
+}
+
+DLLEXPORT void STDCALL FPDFPage_Delete(FPDF_DOCUMENT document, int page_index) {
+  if (UnderlyingDocumentType* pDoc = UnderlyingFromFPDFDocument(document))
+    pDoc->DeletePage(page_index);
+}
+
+DLLEXPORT FPDF_PAGE STDCALL FPDFPage_New(FPDF_DOCUMENT document,
+                                         int page_index,
+                                         double width,
+                                         double height) {
+  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
+  if (!pDoc)
+    return nullptr;
+
+  page_index = std::min(std::max(page_index, 0), pDoc->GetPageCount());
+  CPDF_Dictionary* pPageDict = pDoc->CreateNewPage(page_index);
+  if (!pPageDict)
+    return nullptr;
+
+  CPDF_Array* pMediaBoxArray = pPageDict->SetNewFor<CPDF_Array>("MediaBox");
+  pMediaBoxArray->AddNew<CPDF_Number>(0);
+  pMediaBoxArray->AddNew<CPDF_Number>(0);
+  pMediaBoxArray->AddNew<CPDF_Number>(static_cast<FX_FLOAT>(width));
+  pMediaBoxArray->AddNew<CPDF_Number>(static_cast<FX_FLOAT>(height));
+  pPageDict->SetNewFor<CPDF_Number>("Rotate", 0);
+  pPageDict->SetNewFor<CPDF_Dictionary>("Resources");
+
+#ifdef PDF_ENABLE_XFA
+  CPDFXFA_Page* pPage =
+      new CPDFXFA_Page(static_cast<CPDFXFA_Context*>(document), page_index);
+  pPage->LoadPDFPage(pPageDict);
+#else   // PDF_ENABLE_XFA
+  CPDF_Page* pPage = new CPDF_Page(pDoc, pPageDict, true);
+  pPage->ParseContent();
+#endif  // PDF_ENABLE_XFA
+
+  return pPage;
+}
+
+DLLEXPORT int STDCALL FPDFPage_GetRotation(FPDF_PAGE page) {
+  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
+  if (!IsPageObject(pPage))
+    return -1;
+
+  CPDF_Dictionary* pDict = pPage->m_pFormDict;
+  while (pDict) {
+    if (pDict->KeyExist("Rotate")) {
+      CPDF_Object* pRotateObj = pDict->GetObjectFor("Rotate")->GetDirect();
+      return pRotateObj ? pRotateObj->GetInteger() / 90 : 0;
+    }
+    if (!pDict->KeyExist("Parent"))
+      break;
+
+    pDict = ToDictionary(pDict->GetObjectFor("Parent")->GetDirect());
+  }
+
+  return 0;
+}
+
+DLLEXPORT void STDCALL FPDFPage_InsertObject(FPDF_PAGE page,
+                                             FPDF_PAGEOBJECT page_obj) {
+  CPDF_PageObject* pPageObj = reinterpret_cast<CPDF_PageObject*>(page_obj);
+  if (!pPageObj)
+    return;
+
+  std::unique_ptr<CPDF_PageObject> pPageObjHolder(pPageObj);
+  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
+  if (!IsPageObject(pPage))
+    return;
+
+  pPage->GetPageObjectList()->push_back(std::move(pPageObjHolder));
+  switch (pPageObj->GetType()) {
+    case CPDF_PageObject::TEXT: {
+      break;
+    }
+    case CPDF_PageObject::PATH: {
+      CPDF_PathObject* pPathObj = pPageObj->AsPath();
+      pPathObj->CalcBoundingBox();
+      break;
+    }
+    case CPDF_PageObject::IMAGE: {
+      CPDF_ImageObject* pImageObj = pPageObj->AsImage();
+      pImageObj->CalcBoundingBox();
+      break;
+    }
+    case CPDF_PageObject::SHADING: {
+      CPDF_ShadingObject* pShadingObj = pPageObj->AsShading();
+      pShadingObj->CalcBoundingBox();
+      break;
+    }
+    case CPDF_PageObject::FORM: {
+      CPDF_FormObject* pFormObj = pPageObj->AsForm();
+      pFormObj->CalcBoundingBox();
+      break;
+    }
+    default: {
+      ASSERT(false);
+      break;
+    }
+  }
+}
+
+DLLEXPORT int STDCALL FPDFPage_CountObject(FPDF_PAGE page) {
+  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
+  if (!IsPageObject(pPage))
+    return -1;
+  return pdfium::CollectionSize<int>(*pPage->GetPageObjectList());
+}
+
+DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPage_GetObject(FPDF_PAGE page,
+                                                     int index) {
+  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
+  if (!IsPageObject(pPage))
+    return nullptr;
+  return pPage->GetPageObjectList()->GetPageObjectByIndex(index);
+}
+
+DLLEXPORT FPDF_BOOL STDCALL FPDFPage_HasTransparency(FPDF_PAGE page) {
+  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
+  return pPage && pPage->BackgroundAlphaNeeded();
+}
+
+DLLEXPORT FPDF_BOOL STDCALL
+FPDFPageObj_HasTransparency(FPDF_PAGEOBJECT pageObject) {
+  if (!pageObject)
+    return false;
+
+  CPDF_PageObject* pPageObj = reinterpret_cast<CPDF_PageObject*>(pageObject);
+  int blend_type = pPageObj->m_GeneralState.GetBlendType();
+  if (blend_type != FXDIB_BLEND_NORMAL)
+    return true;
+
+  CPDF_Dictionary* pSMaskDict =
+      ToDictionary(pPageObj->m_GeneralState.GetSoftMask());
+  if (pSMaskDict)
+    return true;
+
+  if (pPageObj->m_GeneralState.GetFillAlpha() != 1.0f)
+    return true;
+
+  if (pPageObj->IsPath() && pPageObj->m_GeneralState.GetStrokeAlpha() != 1.0f) {
+    return true;
+  }
+
+  if (pPageObj->IsForm()) {
+    const CPDF_Form* pForm = pPageObj->AsForm()->form();
+    if (pForm) {
+      int trans = pForm->m_Transparency;
+      if ((trans & PDFTRANS_ISOLATED) || (trans & PDFTRANS_GROUP))
+        return true;
+    }
+  }
+
+  return false;
+}
+
+DLLEXPORT FPDF_BOOL STDCALL FPDFPage_GenerateContent(FPDF_PAGE page) {
+  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
+  if (!IsPageObject(pPage))
+    return false;
+
+  CPDF_PageContentGenerator CG(pPage);
+  CG.GenerateContent();
+  return true;
+}
+
+DLLEXPORT void STDCALL FPDFPageObj_Transform(FPDF_PAGEOBJECT page_object,
+                                             double a,
+                                             double b,
+                                             double c,
+                                             double d,
+                                             double e,
+                                             double f) {
+  CPDF_PageObject* pPageObj = reinterpret_cast<CPDF_PageObject*>(page_object);
+  if (!pPageObj)
+    return;
+
+  CFX_Matrix matrix((FX_FLOAT)a, (FX_FLOAT)b, (FX_FLOAT)c, (FX_FLOAT)d,
+                    (FX_FLOAT)e, (FX_FLOAT)f);
+  pPageObj->Transform(matrix);
+}
+
+DLLEXPORT void STDCALL FPDFPage_TransformAnnots(FPDF_PAGE page,
+                                                double a,
+                                                double b,
+                                                double c,
+                                                double d,
+                                                double e,
+                                                double f) {
+  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
+  if (!pPage)
+    return;
+
+  CPDF_AnnotList AnnotList(pPage);
+  for (size_t i = 0; i < AnnotList.Count(); ++i) {
+    CPDF_Annot* pAnnot = AnnotList.GetAt(i);
+    CFX_FloatRect rect = pAnnot->GetRect();  // transformAnnots Rectangle
+    CFX_Matrix matrix((FX_FLOAT)a, (FX_FLOAT)b, (FX_FLOAT)c, (FX_FLOAT)d,
+                      (FX_FLOAT)e, (FX_FLOAT)f);
+    rect.Transform(&matrix);
+
+    CPDF_Array* pRectArray = pAnnot->GetAnnotDict()->GetArrayFor("Rect");
+    if (!pRectArray)
+      pRectArray = pAnnot->GetAnnotDict()->SetNewFor<CPDF_Array>("Rect");
+
+    pRectArray->SetNewAt<CPDF_Number>(0, rect.left);
+    pRectArray->SetNewAt<CPDF_Number>(1, rect.bottom);
+    pRectArray->SetNewAt<CPDF_Number>(2, rect.right);
+    pRectArray->SetNewAt<CPDF_Number>(3, rect.top);
+
+    // TODO(unknown): Transform AP's rectangle
+  }
+}
+
+DLLEXPORT void STDCALL FPDFPage_SetRotation(FPDF_PAGE page, int rotate) {
+  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
+  if (!IsPageObject(pPage))
+    return;
+
+  CPDF_Dictionary* pDict = pPage->m_pFormDict;
+  rotate %= 4;
+  pDict->SetNewFor<CPDF_Number>("Rotate", rotate * 90);
+}
diff --git a/fpdfsdk/src/fpdfext_embeddertest.cpp b/fpdfsdk/fpdfext_embeddertest.cpp
similarity index 100%
rename from fpdfsdk/src/fpdfext_embeddertest.cpp
rename to fpdfsdk/fpdfext_embeddertest.cpp
diff --git a/fpdfsdk/fpdfformfill.cpp b/fpdfsdk/fpdfformfill.cpp
new file mode 100644
index 0000000..6b8cbaa
--- /dev/null
+++ b/fpdfsdk/fpdfformfill.cpp
@@ -0,0 +1,755 @@
+// 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
+
+#include "public/fpdf_formfill.h"
+
+#include <memory>
+#include <vector>
+
+#include "core/fpdfapi/page/cpdf_page.h"
+#include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/render/cpdf_renderoptions.h"
+#include "core/fpdfdoc/cpdf_formcontrol.h"
+#include "core/fpdfdoc/cpdf_formfield.h"
+#include "core/fpdfdoc/cpdf_interform.h"
+#include "core/fpdfdoc/cpdf_occontext.h"
+#include "core/fxge/cfx_fxgedevice.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/cpdfsdk_interform.h"
+#include "fpdfsdk/cpdfsdk_pageview.h"
+#include "fpdfsdk/fsdk_actionhandler.h"
+#include "fpdfsdk/fsdk_define.h"
+#include "public/fpdfview.h"
+#include "third_party/base/ptr_util.h"
+#include "third_party/base/stl_util.h"
+
+#ifdef PDF_ENABLE_XFA
+#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
+#include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
+#include "xfa/fxfa/xfa_ffdocview.h"
+#include "xfa/fxfa/xfa_ffpageview.h"
+#include "xfa/fxfa/xfa_ffwidget.h"
+#endif  // PDF_ENABLE_XFA
+
+namespace {
+
+CPDFSDK_FormFillEnvironment* HandleToCPDFSDKEnvironment(
+    FPDF_FORMHANDLE handle) {
+  return static_cast<CPDFSDK_FormFillEnvironment*>(handle);
+}
+
+CPDFSDK_InterForm* FormHandleToInterForm(FPDF_FORMHANDLE hHandle) {
+  CPDFSDK_FormFillEnvironment* pFormFillEnv =
+      HandleToCPDFSDKEnvironment(hHandle);
+  return pFormFillEnv ? pFormFillEnv->GetInterForm() : nullptr;
+}
+
+CPDFSDK_PageView* FormHandleToPageView(FPDF_FORMHANDLE hHandle,
+                                       FPDF_PAGE page) {
+  UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
+  if (!pPage)
+    return nullptr;
+
+  CPDFSDK_FormFillEnvironment* pFormFillEnv =
+      HandleToCPDFSDKEnvironment(hHandle);
+  return pFormFillEnv ? pFormFillEnv->GetPageView(pPage, true) : nullptr;
+}
+
+#ifdef PDF_ENABLE_XFA
+std::vector<CFX_ByteString>* FromFPDFStringHandle(FPDF_STRINGHANDLE handle) {
+  return reinterpret_cast<std::vector<CFX_ByteString>*>(handle);
+}
+
+FPDF_STRINGHANDLE ToFPDFStringHandle(std::vector<CFX_ByteString>* strings) {
+  return reinterpret_cast<FPDF_STRINGHANDLE>(strings);
+}
+#endif  // PDF_ENABLE_XFA
+
+void FFLCommon(FPDF_FORMHANDLE hHandle,
+               FPDF_BITMAP bitmap,
+               FPDF_RECORDER recorder,
+               FPDF_PAGE page,
+               int start_x,
+               int start_y,
+               int size_x,
+               int size_y,
+               int rotate,
+               int flags) {
+  if (!hHandle)
+    return;
+
+  UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
+  if (!pPage)
+    return;
+
+#ifdef PDF_ENABLE_XFA
+  CPDFXFA_Context* pContext = pPage->GetContext();
+  if (!pContext)
+    return;
+  CPDF_Document* pPDFDoc = pContext->GetPDFDoc();
+  if (!pPDFDoc)
+    return;
+  CPDFSDK_FormFillEnvironment* pFormFillEnv =
+      HandleToCPDFSDKEnvironment(hHandle);
+  if (!pFormFillEnv)
+    return;
+#endif  // PDF_ENABLE_XFA
+
+  CFX_Matrix matrix;
+  pPage->GetDisplayMatrix(matrix, start_x, start_y, size_x, size_y, rotate);
+
+  FX_RECT clip(start_x, start_y, start_x + size_x, start_y + size_y);
+
+  std::unique_ptr<CFX_FxgeDevice> pDevice(new CFX_FxgeDevice);
+#ifdef _SKIA_SUPPORT_
+  pDevice->AttachRecorder(static_cast<SkPictureRecorder*>(recorder));
+#endif
+  pDevice->Attach(CFXBitmapFromFPDFBitmap(bitmap), false, nullptr, false);
+  pDevice->SaveState();
+  pDevice->SetClip_Rect(clip);
+
+  CPDF_RenderOptions options;
+  if (flags & FPDF_LCD_TEXT)
+    options.m_Flags |= RENDER_CLEARTYPE;
+  else
+    options.m_Flags &= ~RENDER_CLEARTYPE;
+
+  // Grayscale output
+  if (flags & FPDF_GRAYSCALE) {
+    options.m_ColorMode = RENDER_COLOR_GRAY;
+    options.m_ForeColor = 0;
+    options.m_BackColor = 0xffffff;
+  }
+  options.m_AddFlags = flags >> 8;
+  options.m_bDrawAnnots = flags & FPDF_ANNOT;
+
+#ifdef PDF_ENABLE_XFA
+  options.m_pOCContext = new CPDF_OCContext(pPDFDoc, CPDF_OCContext::View);
+  if (CPDFSDK_PageView* pPageView = pFormFillEnv->GetPageView(pPage, true))
+    pPageView->PageView_OnDraw(pDevice.get(), &matrix, &options, clip);
+#else   // PDF_ENABLE_XFA
+  options.m_pOCContext =
+      new CPDF_OCContext(pPage->m_pDocument, CPDF_OCContext::View);
+  if (CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, pPage))
+    pPageView->PageView_OnDraw(pDevice.get(), &matrix, &options);
+#endif  // PDF_ENABLE_XFA
+
+  pDevice->RestoreState(false);
+#ifdef _SKIA_SUPPORT_PATHS_
+  pDevice->Flush();
+  CFXBitmapFromFPDFBitmap(bitmap)->UnPreMultiply();
+#endif
+  delete options.m_pOCContext;
+  options.m_pOCContext = nullptr;
+}
+
+}  // namespace
+
+DLLEXPORT int STDCALL FPDFPage_HasFormFieldAtPoint(FPDF_FORMHANDLE hHandle,
+                                                   FPDF_PAGE page,
+                                                   double page_x,
+                                                   double page_y) {
+  if (!hHandle)
+    return -1;
+  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
+  if (pPage) {
+    CPDF_InterForm interform(pPage->m_pDocument);
+    CPDF_FormControl* pFormCtrl =
+        interform.GetControlAtPoint(pPage, static_cast<FX_FLOAT>(page_x),
+                                    static_cast<FX_FLOAT>(page_y), nullptr);
+    if (!pFormCtrl)
+      return -1;
+    CPDF_FormField* pFormField = pFormCtrl->GetField();
+    return pFormField ? pFormField->GetFieldType() : -1;
+  }
+
+#ifdef PDF_ENABLE_XFA
+  CPDFXFA_Page* pXFAPage = UnderlyingFromFPDFPage(page);
+  if (!pXFAPage)
+    return -1;
+
+  CXFA_FFPageView* pPageView = pXFAPage->GetXFAPageView();
+  if (!pPageView)
+    return -1;
+
+  CXFA_FFDocView* pDocView = pPageView->GetDocView();
+  if (!pDocView)
+    return -1;
+
+  CXFA_FFWidgetHandler* pWidgetHandler = pDocView->GetWidgetHandler();
+  if (!pWidgetHandler)
+    return -1;
+
+  std::unique_ptr<IXFA_WidgetIterator> pWidgetIterator(
+      pPageView->CreateWidgetIterator(XFA_TRAVERSEWAY_Form,
+                                      XFA_WidgetStatus_Viewable));
+  if (!pWidgetIterator)
+    return -1;
+
+  CXFA_FFWidget* pXFAAnnot = pWidgetIterator->MoveToNext();
+  while (pXFAAnnot) {
+    CFX_RectF rcBBox;
+    pXFAAnnot->GetBBox(rcBBox, 0);
+    CFX_FloatRect rcWidget(rcBBox.left, rcBBox.top, rcBBox.left + rcBBox.width,
+                           rcBBox.top + rcBBox.height);
+    rcWidget.left -= 1.0f;
+    rcWidget.right += 1.0f;
+    rcWidget.bottom -= 1.0f;
+    rcWidget.top += 1.0f;
+
+    if (rcWidget.Contains(static_cast<FX_FLOAT>(page_x),
+                          static_cast<FX_FLOAT>(page_y))) {
+      return FPDF_FORMFIELD_XFA;
+    }
+    pXFAAnnot = pWidgetIterator->MoveToNext();
+  }
+#endif  // PDF_ENABLE_XFA
+  return -1;
+}
+
+DLLEXPORT int STDCALL FPDPage_HasFormFieldAtPoint(FPDF_FORMHANDLE hHandle,
+                                                  FPDF_PAGE page,
+                                                  double page_x,
+                                                  double page_y) {
+  return FPDFPage_HasFormFieldAtPoint(hHandle, page, page_x, page_y);
+}
+
+DLLEXPORT int STDCALL FPDFPage_FormFieldZOrderAtPoint(FPDF_FORMHANDLE hHandle,
+                                                      FPDF_PAGE page,
+                                                      double page_x,
+                                                      double page_y) {
+  if (!hHandle)
+    return -1;
+  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
+  if (!pPage)
+    return -1;
+  CPDF_InterForm interform(pPage->m_pDocument);
+  int z_order = -1;
+  (void)interform.GetControlAtPoint(pPage, (FX_FLOAT)page_x, (FX_FLOAT)page_y,
+                                    &z_order);
+  return z_order;
+}
+
+DLLEXPORT FPDF_FORMHANDLE STDCALL
+FPDFDOC_InitFormFillEnvironment(FPDF_DOCUMENT document,
+                                FPDF_FORMFILLINFO* formInfo) {
+#ifdef PDF_ENABLE_XFA
+  const int kRequiredVersion = 2;
+#else   // PDF_ENABLE_XFA
+  const int kRequiredVersion = 1;
+#endif  // PDF_ENABLE_XFA
+  if (!formInfo || formInfo->version != kRequiredVersion)
+    return nullptr;
+
+  UnderlyingDocumentType* pDocument = UnderlyingFromFPDFDocument(document);
+  if (!pDocument)
+    return nullptr;
+
+#ifdef PDF_ENABLE_XFA
+  // If the CPDFXFA_Context has a FormFillEnvironment already then we've done
+  // this and can just return the old Env. Otherwise, we'll end up setting a new
+  // environment into the XFADocument and, that could get weird.
+  if (pDocument->GetFormFillEnv())
+    return pDocument->GetFormFillEnv();
+#endif
+
+  CPDFSDK_FormFillEnvironment* pFormFillEnv =
+      new CPDFSDK_FormFillEnvironment(pDocument, formInfo);
+
+#ifdef PDF_ENABLE_XFA
+  pDocument->SetFormFillEnv(pFormFillEnv);
+#endif  // PDF_ENABLE_XFA
+
+  return pFormFillEnv;
+}
+
+DLLEXPORT void STDCALL
+FPDFDOC_ExitFormFillEnvironment(FPDF_FORMHANDLE hHandle) {
+  if (!hHandle)
+    return;
+
+  CPDFSDK_FormFillEnvironment* pFormFillEnv =
+      HandleToCPDFSDKEnvironment(hHandle);
+
+#ifdef PDF_ENABLE_XFA
+  // Reset the focused annotations and remove the SDK document from the
+  // XFA document.
+  pFormFillEnv->ClearAllFocusedAnnots();
+  // If the document was closed first, it's possible the XFA document
+  // is now a nullptr.
+  if (pFormFillEnv->GetXFAContext())
+    pFormFillEnv->GetXFAContext()->SetFormFillEnv(nullptr);
+#endif  // PDF_ENABLE_XFA
+
+  delete pFormFillEnv;
+}
+
+DLLEXPORT FPDF_BOOL STDCALL FORM_OnMouseMove(FPDF_FORMHANDLE hHandle,
+                                             FPDF_PAGE page,
+                                             int modifier,
+                                             double page_x,
+                                             double page_y) {
+  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
+  if (!pPageView)
+    return false;
+
+  CFX_FloatPoint pt((FX_FLOAT)page_x, (FX_FLOAT)page_y);
+  return pPageView->OnMouseMove(pt, modifier);
+}
+
+DLLEXPORT FPDF_BOOL STDCALL FORM_OnLButtonDown(FPDF_FORMHANDLE hHandle,
+                                               FPDF_PAGE page,
+                                               int modifier,
+                                               double page_x,
+                                               double page_y) {
+  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
+  if (!pPageView)
+    return false;
+
+  CFX_FloatPoint pt((FX_FLOAT)page_x, (FX_FLOAT)page_y);
+  return pPageView->OnLButtonDown(pt, modifier);
+}
+
+DLLEXPORT FPDF_BOOL STDCALL FORM_OnLButtonUp(FPDF_FORMHANDLE hHandle,
+                                             FPDF_PAGE page,
+                                             int modifier,
+                                             double page_x,
+                                             double page_y) {
+  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
+  if (!pPageView)
+    return false;
+
+  CFX_FloatPoint pt((FX_FLOAT)page_x, (FX_FLOAT)page_y);
+  return pPageView->OnLButtonUp(pt, modifier);
+}
+
+#ifdef PDF_ENABLE_XFA
+DLLEXPORT FPDF_BOOL STDCALL FORM_OnRButtonDown(FPDF_FORMHANDLE hHandle,
+                                               FPDF_PAGE page,
+                                               int modifier,
+                                               double page_x,
+                                               double page_y) {
+  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
+  if (!pPageView)
+    return false;
+
+  CFX_FloatPoint pt((FX_FLOAT)page_x, (FX_FLOAT)page_y);
+  return pPageView->OnRButtonDown(pt, modifier);
+}
+
+DLLEXPORT FPDF_BOOL STDCALL FORM_OnRButtonUp(FPDF_FORMHANDLE hHandle,
+                                             FPDF_PAGE page,
+                                             int modifier,
+                                             double page_x,
+                                             double page_y) {
+  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
+  if (!pPageView)
+    return false;
+
+  CFX_FloatPoint pt((FX_FLOAT)page_x, (FX_FLOAT)page_y);
+  return pPageView->OnRButtonUp(pt, modifier);
+}
+#endif  // PDF_ENABLE_XFA
+
+DLLEXPORT FPDF_BOOL STDCALL FORM_OnKeyDown(FPDF_FORMHANDLE hHandle,
+                                           FPDF_PAGE page,
+                                           int nKeyCode,
+                                           int modifier) {
+  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
+  if (!pPageView)
+    return false;
+
+  return pPageView->OnKeyDown(nKeyCode, modifier);
+}
+
+DLLEXPORT FPDF_BOOL STDCALL FORM_OnKeyUp(FPDF_FORMHANDLE hHandle,
+                                         FPDF_PAGE page,
+                                         int nKeyCode,
+                                         int modifier) {
+  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
+  if (!pPageView)
+    return false;
+
+  return pPageView->OnKeyUp(nKeyCode, modifier);
+}
+
+DLLEXPORT FPDF_BOOL STDCALL FORM_OnChar(FPDF_FORMHANDLE hHandle,
+                                        FPDF_PAGE page,
+                                        int nChar,
+                                        int modifier) {
+  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
+  if (!pPageView)
+    return false;
+
+  return pPageView->OnChar(nChar, modifier);
+}
+
+DLLEXPORT FPDF_BOOL STDCALL FORM_ForceToKillFocus(FPDF_FORMHANDLE hHandle) {
+  CPDFSDK_FormFillEnvironment* pFormFillEnv =
+      HandleToCPDFSDKEnvironment(hHandle);
+  if (!pFormFillEnv)
+    return false;
+  return pFormFillEnv->KillFocusAnnot(0);
+}
+
+DLLEXPORT void STDCALL FPDF_FFLDraw(FPDF_FORMHANDLE hHandle,
+                                    FPDF_BITMAP bitmap,
+                                    FPDF_PAGE page,
+                                    int start_x,
+                                    int start_y,
+                                    int size_x,
+                                    int size_y,
+                                    int rotate,
+                                    int flags) {
+  FFLCommon(hHandle, bitmap, nullptr, page, start_x, start_y, size_x, size_y,
+            rotate, flags);
+}
+
+#ifdef _SKIA_SUPPORT_
+DLLEXPORT void STDCALL FPDF_FFLRecord(FPDF_FORMHANDLE hHandle,
+                                      FPDF_RECORDER recorder,
+                                      FPDF_PAGE page,
+                                      int start_x,
+                                      int start_y,
+                                      int size_x,
+                                      int size_y,
+                                      int rotate,
+                                      int flags) {
+  FFLCommon(hHandle, nullptr, recorder, page, start_x, start_y, size_x, size_y,
+            rotate, flags);
+}
+#endif
+
+#ifdef PDF_ENABLE_XFA
+DLLEXPORT void STDCALL FPDF_Widget_Undo(FPDF_DOCUMENT document,
+                                        FPDF_WIDGET hWidget) {
+  if (!hWidget || !document)
+    return;
+
+  CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
+  if (pContext->GetDocType() != XFA_DOCTYPE_Dynamic &&
+      pContext->GetDocType() != XFA_DOCTYPE_Static)
+    return;
+
+  static_cast<CXFA_FFWidget*>(hWidget)->Undo();
+}
+
+DLLEXPORT void STDCALL FPDF_Widget_Redo(FPDF_DOCUMENT document,
+                                        FPDF_WIDGET hWidget) {
+  if (!hWidget || !document)
+    return;
+
+  CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
+  if (pContext->GetDocType() != XFA_DOCTYPE_Dynamic &&
+      pContext->GetDocType() != XFA_DOCTYPE_Static)
+    return;
+
+  static_cast<CXFA_FFWidget*>(hWidget)->Redo();
+}
+
+DLLEXPORT void STDCALL FPDF_Widget_SelectAll(FPDF_DOCUMENT document,
+                                             FPDF_WIDGET hWidget) {
+  if (!hWidget || !document)
+    return;
+
+  CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
+  if (pContext->GetDocType() != XFA_DOCTYPE_Dynamic &&
+      pContext->GetDocType() != XFA_DOCTYPE_Static)
+    return;
+
+  static_cast<CXFA_FFWidget*>(hWidget)->SelectAll();
+}
+
+DLLEXPORT void STDCALL FPDF_Widget_Copy(FPDF_DOCUMENT document,
+                                        FPDF_WIDGET hWidget,
+                                        FPDF_WIDESTRING wsText,
+                                        FPDF_DWORD* size) {
+  if (!hWidget || !document)
+    return;
+
+  CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
+  if (pContext->GetDocType() != XFA_DOCTYPE_Dynamic &&
+      pContext->GetDocType() != XFA_DOCTYPE_Static)
+    return;
+
+  CFX_WideString wsCpText;
+  static_cast<CXFA_FFWidget*>(hWidget)->Copy(wsCpText);
+
+  CFX_ByteString bsCpText = wsCpText.UTF16LE_Encode();
+  uint32_t len = bsCpText.GetLength() / sizeof(unsigned short);
+  if (!wsText) {
+    *size = len;
+    return;
+  }
+
+  uint32_t real_size = len < *size ? len : *size;
+  if (real_size > 0) {
+    FXSYS_memcpy((void*)wsText,
+                 bsCpText.GetBuffer(real_size * sizeof(unsigned short)),
+                 real_size * sizeof(unsigned short));
+    bsCpText.ReleaseBuffer(real_size * sizeof(unsigned short));
+  }
+  *size = real_size;
+}
+
+DLLEXPORT void STDCALL FPDF_Widget_Cut(FPDF_DOCUMENT document,
+                                       FPDF_WIDGET hWidget,
+                                       FPDF_WIDESTRING wsText,
+                                       FPDF_DWORD* size) {
+  if (!hWidget || !document)
+    return;
+
+  CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
+  if (pContext->GetDocType() != XFA_DOCTYPE_Dynamic &&
+      pContext->GetDocType() != XFA_DOCTYPE_Static)
+    return;
+
+  CFX_WideString wsCpText;
+  static_cast<CXFA_FFWidget*>(hWidget)->Cut(wsCpText);
+
+  CFX_ByteString bsCpText = wsCpText.UTF16LE_Encode();
+  uint32_t len = bsCpText.GetLength() / sizeof(unsigned short);
+  if (!wsText) {
+    *size = len;
+    return;
+  }
+
+  uint32_t real_size = len < *size ? len : *size;
+  if (real_size > 0) {
+    FXSYS_memcpy((void*)wsText,
+                 bsCpText.GetBuffer(real_size * sizeof(unsigned short)),
+                 real_size * sizeof(unsigned short));
+    bsCpText.ReleaseBuffer(real_size * sizeof(unsigned short));
+  }
+  *size = real_size;
+}
+
+DLLEXPORT void STDCALL FPDF_Widget_Paste(FPDF_DOCUMENT document,
+                                         FPDF_WIDGET hWidget,
+                                         FPDF_WIDESTRING wsText,
+                                         FPDF_DWORD size) {
+  if (!hWidget || !document)
+    return;
+
+  CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
+  if (pContext->GetDocType() != XFA_DOCTYPE_Dynamic &&
+      pContext->GetDocType() != XFA_DOCTYPE_Static)
+    return;
+
+  CFX_WideString wstr = CFX_WideString::FromUTF16LE(wsText, size);
+  static_cast<CXFA_FFWidget*>(hWidget)->Paste(wstr);
+}
+
+DLLEXPORT void STDCALL
+FPDF_Widget_ReplaceSpellCheckWord(FPDF_DOCUMENT document,
+                                  FPDF_WIDGET hWidget,
+                                  float x,
+                                  float y,
+                                  FPDF_BYTESTRING bsText) {
+  if (!hWidget || !document)
+    return;
+
+  CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
+  if (pContext->GetDocType() != XFA_DOCTYPE_Dynamic &&
+      pContext->GetDocType() != XFA_DOCTYPE_Static)
+    return;
+
+  CFX_PointF ptPopup;
+  ptPopup.x = x;
+  ptPopup.y = y;
+  CFX_ByteStringC bs(bsText);
+  static_cast<CXFA_FFWidget*>(hWidget)->ReplaceSpellCheckWord(ptPopup, bs);
+}
+
+DLLEXPORT void STDCALL
+FPDF_Widget_GetSpellCheckWords(FPDF_DOCUMENT document,
+                               FPDF_WIDGET hWidget,
+                               float x,
+                               float y,
+                               FPDF_STRINGHANDLE* stringHandle) {
+  if (!hWidget || !document)
+    return;
+
+  CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
+  if (pContext->GetDocType() != XFA_DOCTYPE_Dynamic &&
+      pContext->GetDocType() != XFA_DOCTYPE_Static)
+    return;
+
+  std::vector<CFX_ByteString>* sSuggestWords = new std::vector<CFX_ByteString>;
+  CFX_PointF ptPopup;
+  ptPopup.x = x;
+  ptPopup.y = y;
+  static_cast<CXFA_FFWidget*>(hWidget)
+      ->GetSuggestWords(ptPopup, *sSuggestWords);
+  *stringHandle = ToFPDFStringHandle(sSuggestWords);
+}
+
+DLLEXPORT int STDCALL FPDF_StringHandleCounts(FPDF_STRINGHANDLE sHandle) {
+  std::vector<CFX_ByteString>* sSuggestWords = FromFPDFStringHandle(sHandle);
+  return sSuggestWords ? pdfium::CollectionSize<int>(*sSuggestWords) : -1;
+}
+
+DLLEXPORT FPDF_BOOL STDCALL
+FPDF_StringHandleGetStringByIndex(FPDF_STRINGHANDLE sHandle,
+                                  int index,
+                                  FPDF_BYTESTRING bsText,
+                                  FPDF_DWORD* size) {
+  if (!sHandle || !size)
+    return false;
+
+  int count = FPDF_StringHandleCounts(sHandle);
+  if (index < 0 || index >= count)
+    return false;
+
+  std::vector<CFX_ByteString>* sSuggestWords = FromFPDFStringHandle(sHandle);
+  uint32_t len = (*sSuggestWords)[index].GetLength();
+  if (!bsText) {
+    *size = len;
+    return true;
+  }
+
+  uint32_t real_size = len < *size ? len : *size;
+  if (real_size > 0)
+    FXSYS_memcpy((void*)bsText, (*sSuggestWords)[index].c_str(), real_size);
+  *size = real_size;
+  return true;
+}
+
+DLLEXPORT void STDCALL
+FPDF_StringHandleRelease(FPDF_STRINGHANDLE stringHandle) {
+  delete FromFPDFStringHandle(stringHandle);
+}
+
+DLLEXPORT FPDF_BOOL STDCALL
+FPDF_StringHandleAddString(FPDF_STRINGHANDLE stringHandle,
+                           FPDF_BYTESTRING bsText,
+                           FPDF_DWORD size) {
+  if (!stringHandle || !bsText || size == 0)
+    return false;
+
+  FromFPDFStringHandle(stringHandle)->push_back(CFX_ByteString(bsText, size));
+  return true;
+}
+#endif  // PDF_ENABLE_XFA
+
+DLLEXPORT void STDCALL FPDF_SetFormFieldHighlightColor(FPDF_FORMHANDLE hHandle,
+                                                       int fieldType,
+                                                       unsigned long color) {
+  if (CPDFSDK_InterForm* pInterForm = FormHandleToInterForm(hHandle))
+    pInterForm->SetHighlightColor(color, fieldType);
+}
+
+DLLEXPORT void STDCALL FPDF_SetFormFieldHighlightAlpha(FPDF_FORMHANDLE hHandle,
+                                                       unsigned char alpha) {
+  if (CPDFSDK_InterForm* pInterForm = FormHandleToInterForm(hHandle))
+    pInterForm->SetHighlightAlpha(alpha);
+}
+
+DLLEXPORT void STDCALL FPDF_RemoveFormFieldHighlight(FPDF_FORMHANDLE hHandle) {
+  if (CPDFSDK_InterForm* pInterForm = FormHandleToInterForm(hHandle))
+    pInterForm->RemoveAllHighLight();
+}
+
+DLLEXPORT void STDCALL FORM_OnAfterLoadPage(FPDF_PAGE page,
+                                            FPDF_FORMHANDLE hHandle) {
+  if (CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page))
+    pPageView->SetValid(true);
+}
+
+DLLEXPORT void STDCALL FORM_OnBeforeClosePage(FPDF_PAGE page,
+                                              FPDF_FORMHANDLE hHandle) {
+  if (!hHandle)
+    return;
+
+  CPDFSDK_FormFillEnvironment* pFormFillEnv =
+      HandleToCPDFSDKEnvironment(hHandle);
+  if (!pFormFillEnv)
+    return;
+
+  UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
+  if (!pPage)
+    return;
+
+  CPDFSDK_PageView* pPageView = pFormFillEnv->GetPageView(pPage, false);
+  if (pPageView) {
+    pPageView->SetValid(false);
+    // RemovePageView() takes care of the delete for us.
+    pFormFillEnv->RemovePageView(pPage);
+  }
+}
+
+DLLEXPORT void STDCALL FORM_DoDocumentJSAction(FPDF_FORMHANDLE hHandle) {
+  CPDFSDK_FormFillEnvironment* pFormFillEnv =
+      HandleToCPDFSDKEnvironment(hHandle);
+  if (pFormFillEnv && pFormFillEnv->IsJSInitiated())
+    pFormFillEnv->ProcJavascriptFun();
+}
+
+DLLEXPORT void STDCALL FORM_DoDocumentOpenAction(FPDF_FORMHANDLE hHandle) {
+  CPDFSDK_FormFillEnvironment* pFormFillEnv =
+      HandleToCPDFSDKEnvironment(hHandle);
+  if (pFormFillEnv && pFormFillEnv->IsJSInitiated())
+    pFormFillEnv->ProcOpenAction();
+}
+
+DLLEXPORT void STDCALL FORM_DoDocumentAAction(FPDF_FORMHANDLE hHandle,
+                                              int aaType) {
+  CPDFSDK_FormFillEnvironment* pFormFillEnv =
+      HandleToCPDFSDKEnvironment(hHandle);
+  if (!pFormFillEnv)
+    return;
+
+  CPDF_Document* pDoc = pFormFillEnv->GetPDFDocument();
+  CPDF_Dictionary* pDic = pDoc->GetRoot();
+  if (!pDic)
+    return;
+
+  CPDF_AAction aa(pDic->GetDictFor("AA"));
+  if (aa.ActionExist((CPDF_AAction::AActionType)aaType)) {
+    CPDF_Action action = aa.GetAction((CPDF_AAction::AActionType)aaType);
+    CPDFSDK_ActionHandler* pActionHandler =
+        HandleToCPDFSDKEnvironment(hHandle)->GetActionHander();
+    pActionHandler->DoAction_Document(action, (CPDF_AAction::AActionType)aaType,
+                                      pFormFillEnv);
+  }
+}
+
+DLLEXPORT void STDCALL FORM_DoPageAAction(FPDF_PAGE page,
+                                          FPDF_FORMHANDLE hHandle,
+                                          int aaType) {
+  if (!hHandle)
+    return;
+
+  CPDFSDK_FormFillEnvironment* pFormFillEnv =
+      HandleToCPDFSDKEnvironment(hHandle);
+  if (!pFormFillEnv)
+    return;
+
+  UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
+  CPDF_Page* pPDFPage = CPDFPageFromFPDFPage(page);
+  if (!pPDFPage)
+    return;
+
+  if (!pFormFillEnv->GetPageView(pPage, false))
+    return;
+
+  CPDFSDK_ActionHandler* pActionHandler = pFormFillEnv->GetActionHander();
+  CPDF_Dictionary* pPageDict = pPDFPage->m_pFormDict;
+  CPDF_AAction aa(pPageDict->GetDictFor("AA"));
+  if (FPDFPAGE_AACTION_OPEN == aaType) {
+    if (aa.ActionExist(CPDF_AAction::OpenPage)) {
+      CPDF_Action action = aa.GetAction(CPDF_AAction::OpenPage);
+      pActionHandler->DoAction_Page(action, CPDF_AAction::OpenPage,
+                                    pFormFillEnv);
+    }
+  } else {
+    if (aa.ActionExist(CPDF_AAction::ClosePage)) {
+      CPDF_Action action = aa.GetAction(CPDF_AAction::ClosePage);
+      pActionHandler->DoAction_Page(action, CPDF_AAction::ClosePage,
+                                    pFormFillEnv);
+    }
+  }
+}
diff --git a/fpdfsdk/fpdfformfill_embeddertest.cpp b/fpdfsdk/fpdfformfill_embeddertest.cpp
new file mode 100644
index 0000000..47f1a75
--- /dev/null
+++ b/fpdfsdk/fpdfformfill_embeddertest.cpp
@@ -0,0 +1,199 @@
+// Copyright 2015 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.
+
+#include "public/fpdf_formfill.h"
+#include "testing/embedder_test.h"
+#include "testing/embedder_test_mock_delegate.h"
+#include "testing/embedder_test_timer_handling_delegate.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::_;
+using testing::Return;
+
+class FPDFFormFillEmbeddertest : public EmbedderTest {};
+
+TEST_F(FPDFFormFillEmbeddertest, FirstTest) {
+  EmbedderTestMockDelegate mock;
+  EXPECT_CALL(mock, Alert(_, _, _, _)).Times(0);
+  EXPECT_CALL(mock, UnsupportedHandler(_)).Times(0);
+  EXPECT_CALL(mock, SetTimer(_, _)).Times(0);
+  EXPECT_CALL(mock, KillTimer(_)).Times(0);
+  SetDelegate(&mock);
+
+  EXPECT_TRUE(OpenDocument("hello_world.pdf"));
+  FPDF_PAGE page = LoadPage(0);
+  EXPECT_TRUE(page);
+  UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest, BUG_487928) {
+  EmbedderTestTimerHandlingDelegate delegate;
+  SetDelegate(&delegate);
+
+  EXPECT_TRUE(OpenDocument("bug_487928.pdf"));
+  FPDF_PAGE page = LoadPage(0);
+  EXPECT_TRUE(page);
+  DoOpenActions();
+  delegate.AdvanceTime(5000);
+  UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest, BUG_507316) {
+  EmbedderTestTimerHandlingDelegate delegate;
+  SetDelegate(&delegate);
+
+  EXPECT_TRUE(OpenDocument("bug_507316.pdf"));
+  FPDF_PAGE page = LoadPage(2);
+  EXPECT_TRUE(page);
+  DoOpenActions();
+  delegate.AdvanceTime(4000);
+  UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest, BUG_514690) {
+  EXPECT_TRUE(OpenDocument("hello_world.pdf"));
+  FPDF_PAGE page = LoadPage(0);
+  EXPECT_TRUE(page);
+
+  // Test that FORM_OnMouseMove() etc. permit null HANDLES and PAGES.
+  FORM_OnMouseMove(nullptr, page, 0, 10.0, 10.0);
+  FORM_OnMouseMove(form_handle(), nullptr, 0, 10.0, 10.0);
+
+  UnloadPage(page);
+}
+
+#ifdef PDF_ENABLE_V8
+TEST_F(FPDFFormFillEmbeddertest, BUG_551248) {
+  // Test that timers fire once and intervals fire repeatedly.
+  EmbedderTestTimerHandlingDelegate delegate;
+  SetDelegate(&delegate);
+
+  EXPECT_TRUE(OpenDocument("bug_551248.pdf"));
+  FPDF_PAGE page = LoadPage(0);
+  EXPECT_TRUE(page);
+  DoOpenActions();
+
+  const auto& alerts = delegate.GetAlerts();
+  EXPECT_EQ(0U, alerts.size());
+
+  delegate.AdvanceTime(1000);
+  EXPECT_EQ(0U, alerts.size());  // nothing fired.
+  delegate.AdvanceTime(1000);
+  EXPECT_EQ(1U, alerts.size());  // interval fired.
+  delegate.AdvanceTime(1000);
+  EXPECT_EQ(2U, alerts.size());  // timer fired.
+  delegate.AdvanceTime(1000);
+  EXPECT_EQ(3U, alerts.size());  // interval fired again.
+  delegate.AdvanceTime(1000);
+  EXPECT_EQ(3U, alerts.size());  // nothing fired.
+  delegate.AdvanceTime(1000);
+  EXPECT_EQ(4U, alerts.size());  // interval fired again.
+  delegate.AdvanceTime(1000);
+  EXPECT_EQ(4U, alerts.size());  // nothing fired.
+  UnloadPage(page);
+
+  ASSERT_EQ(4U, alerts.size());  // nothing else fired.
+
+  EXPECT_STREQ(L"interval fired", alerts[0].message.c_str());
+  EXPECT_STREQ(L"Alert", alerts[0].title.c_str());
+  EXPECT_EQ(0, alerts[0].type);
+  EXPECT_EQ(0, alerts[0].icon);
+
+  EXPECT_STREQ(L"timer fired", alerts[1].message.c_str());
+  EXPECT_STREQ(L"Alert", alerts[1].title.c_str());
+  EXPECT_EQ(0, alerts[1].type);
+  EXPECT_EQ(0, alerts[1].icon);
+
+  EXPECT_STREQ(L"interval fired", alerts[2].message.c_str());
+  EXPECT_STREQ(L"Alert", alerts[2].title.c_str());
+  EXPECT_EQ(0, alerts[2].type);
+  EXPECT_EQ(0, alerts[2].icon);
+
+  EXPECT_STREQ(L"interval fired", alerts[3].message.c_str());
+  EXPECT_STREQ(L"Alert", alerts[3].title.c_str());
+  EXPECT_EQ(0, alerts[3].type);
+  EXPECT_EQ(0, alerts[3].icon);
+}
+
+TEST_F(FPDFFormFillEmbeddertest, BUG_620428) {
+  // Test that timers and intervals are cancelable.
+  EmbedderTestTimerHandlingDelegate delegate;
+  SetDelegate(&delegate);
+
+  EXPECT_TRUE(OpenDocument("bug_620428.pdf"));
+  FPDF_PAGE page = LoadPage(0);
+  EXPECT_TRUE(page);
+  DoOpenActions();
+  delegate.AdvanceTime(5000);
+  UnloadPage(page);
+
+  const auto& alerts = delegate.GetAlerts();
+  ASSERT_EQ(1U, alerts.size());
+  EXPECT_STREQ(L"done", alerts[0].message.c_str());
+}
+
+TEST_F(FPDFFormFillEmbeddertest, BUG_634394) {
+  // Cancel timer inside timer callback.
+  EmbedderTestTimerHandlingDelegate delegate;
+  SetDelegate(&delegate);
+
+  EXPECT_TRUE(OpenDocument("bug_634394.pdf"));
+  FPDF_PAGE page = LoadPage(0);
+  EXPECT_TRUE(page);
+  DoOpenActions();
+
+  // Timers fire at most once per AdvanceTime(), allow intervals
+  // to fire several times if possible.
+  delegate.AdvanceTime(1000);
+  delegate.AdvanceTime(1000);
+  delegate.AdvanceTime(1000);
+  delegate.AdvanceTime(1000);
+  delegate.AdvanceTime(1000);
+  UnloadPage(page);
+
+  const auto& alerts = delegate.GetAlerts();
+  EXPECT_EQ(2U, alerts.size());
+}
+
+TEST_F(FPDFFormFillEmbeddertest, BUG_634716) {
+  EmbedderTestTimerHandlingDelegate delegate;
+  SetDelegate(&delegate);
+
+  EXPECT_TRUE(OpenDocument("bug_634716.pdf"));
+  FPDF_PAGE page = LoadPage(0);
+  EXPECT_TRUE(page);
+  DoOpenActions();
+
+  // Timers fire at most once per AdvanceTime(), allow intervals
+  // to fire several times if possible.
+  delegate.AdvanceTime(1000);
+  delegate.AdvanceTime(1000);
+  delegate.AdvanceTime(1000);
+  delegate.AdvanceTime(1000);
+  delegate.AdvanceTime(1000);
+  UnloadPage(page);
+
+  const auto& alerts = delegate.GetAlerts();
+  EXPECT_EQ(2U, alerts.size());
+}
+
+TEST_F(FPDFFormFillEmbeddertest, BUG_679649) {
+  EmbedderTestTimerHandlingDelegate delegate;
+  SetDelegate(&delegate);
+
+  EXPECT_TRUE(OpenDocument("bug_679649.pdf"));
+  FPDF_PAGE page = LoadPage(0);
+  EXPECT_TRUE(page);
+
+  delegate.SetFailNextTimer();
+  DoOpenActions();
+  delegate.AdvanceTime(2000);
+  UnloadPage(page);
+
+  const auto& alerts = delegate.GetAlerts();
+  EXPECT_EQ(0u, alerts.size());
+}
+
+#endif  // PDF_ENABLE_V8
diff --git a/fpdfsdk/fpdfppo.cpp b/fpdfsdk/fpdfppo.cpp
new file mode 100644
index 0000000..4e06856
--- /dev/null
+++ b/fpdfsdk/fpdfppo.cpp
@@ -0,0 +1,390 @@
+// 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
+
+#include "public/fpdf_ppo.h"
+
+#include <map>
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/cpdf_name.h"
+#include "core/fpdfapi/parser/cpdf_number.h"
+#include "core/fpdfapi/parser/cpdf_reference.h"
+#include "core/fpdfapi/parser/cpdf_stream.h"
+#include "core/fpdfapi/parser/cpdf_string.h"
+#include "fpdfsdk/fsdk_define.h"
+#include "third_party/base/ptr_util.h"
+#include "third_party/base/stl_util.h"
+
+namespace {
+
+CPDF_Object* PageDictGetInheritableTag(CPDF_Dictionary* pDict,
+                                       const CFX_ByteString& bsSrcTag) {
+  if (!pDict || bsSrcTag.IsEmpty())
+    return nullptr;
+  if (!pDict->KeyExist("Parent") || !pDict->KeyExist("Type"))
+    return nullptr;
+
+  CPDF_Object* pType = pDict->GetObjectFor("Type")->GetDirect();
+  if (!ToName(pType))
+    return nullptr;
+  if (pType->GetString().Compare("Page"))
+    return nullptr;
+
+  CPDF_Dictionary* pp =
+      ToDictionary(pDict->GetObjectFor("Parent")->GetDirect());
+  if (!pp)
+    return nullptr;
+
+  if (pDict->KeyExist(bsSrcTag))
+    return pDict->GetObjectFor(bsSrcTag);
+
+  while (pp) {
+    if (pp->KeyExist(bsSrcTag))
+      return pp->GetObjectFor(bsSrcTag);
+    if (!pp->KeyExist("Parent"))
+      break;
+    pp = ToDictionary(pp->GetObjectFor("Parent")->GetDirect());
+  }
+  return nullptr;
+}
+
+bool CopyInheritable(CPDF_Dictionary* pCurPageDict,
+                     CPDF_Dictionary* pSrcPageDict,
+                     const CFX_ByteString& key) {
+  if (pCurPageDict->KeyExist(key))
+    return true;
+
+  CPDF_Object* pInheritable = PageDictGetInheritableTag(pSrcPageDict, key);
+  if (!pInheritable)
+    return false;
+
+  pCurPageDict->SetFor(key, pInheritable->Clone());
+  return true;
+}
+
+bool ParserPageRangeString(CFX_ByteString rangstring,
+                           std::vector<uint16_t>* pageArray,
+                           int nCount) {
+  if (rangstring.IsEmpty())
+    return true;
+
+  rangstring.Remove(' ');
+  int nLength = rangstring.GetLength();
+  CFX_ByteString cbCompareString("0123456789-,");
+  for (int i = 0; i < nLength; ++i) {
+    if (cbCompareString.Find(rangstring[i]) == -1)
+      return false;
+  }
+
+  CFX_ByteString cbMidRange;
+  int nStringFrom = 0;
+  int nStringTo = 0;
+  while (nStringTo < nLength) {
+    nStringTo = rangstring.Find(',', nStringFrom);
+    if (nStringTo == -1)
+      nStringTo = nLength;
+    cbMidRange = rangstring.Mid(nStringFrom, nStringTo - nStringFrom);
+    int nMid = cbMidRange.Find('-');
+    if (nMid == -1) {
+      long lPageNum = atol(cbMidRange.c_str());
+      if (lPageNum <= 0 || lPageNum > nCount)
+        return false;
+      pageArray->push_back((uint16_t)lPageNum);
+    } else {
+      int nStartPageNum = atol(cbMidRange.Mid(0, nMid).c_str());
+      if (nStartPageNum == 0)
+        return false;
+
+      ++nMid;
+      int nEnd = cbMidRange.GetLength() - nMid;
+      if (nEnd == 0)
+        return false;
+
+      int nEndPageNum = atol(cbMidRange.Mid(nMid, nEnd).c_str());
+      if (nStartPageNum < 0 || nStartPageNum > nEndPageNum ||
+          nEndPageNum > nCount) {
+        return false;
+      }
+      for (int i = nStartPageNum; i <= nEndPageNum; ++i) {
+        pageArray->push_back(i);
+      }
+    }
+    nStringFrom = nStringTo + 1;
+  }
+  return true;
+}
+
+}  // namespace
+
+class CPDF_PageOrganizer {
+ public:
+  CPDF_PageOrganizer(CPDF_Document* pDestPDFDoc, CPDF_Document* pSrcPDFDoc);
+  ~CPDF_PageOrganizer();
+
+  bool PDFDocInit();
+  bool ExportPage(const std::vector<uint16_t>& pageNums, int nIndex);
+
+ private:
+  using ObjectNumberMap = std::map<uint32_t, uint32_t>;
+
+  bool UpdateReference(CPDF_Object* pObj, ObjectNumberMap* pObjNumberMap);
+  uint32_t GetNewObjId(ObjectNumberMap* pObjNumberMap, CPDF_Reference* pRef);
+
+  CPDF_Document* m_pDestPDFDoc;
+  CPDF_Document* m_pSrcPDFDoc;
+};
+
+CPDF_PageOrganizer::CPDF_PageOrganizer(CPDF_Document* pDestPDFDoc,
+                                       CPDF_Document* pSrcPDFDoc)
+    : m_pDestPDFDoc(pDestPDFDoc), m_pSrcPDFDoc(pSrcPDFDoc) {}
+
+CPDF_PageOrganizer::~CPDF_PageOrganizer() {}
+
+bool CPDF_PageOrganizer::PDFDocInit() {
+  ASSERT(m_pDestPDFDoc);
+  ASSERT(m_pSrcPDFDoc);
+
+  CPDF_Dictionary* pNewRoot = m_pDestPDFDoc->GetRoot();
+  if (!pNewRoot)
+    return false;
+
+  CPDF_Dictionary* pDocInfoDict = m_pDestPDFDoc->GetInfo();
+  if (!pDocInfoDict)
+    return false;
+
+  pDocInfoDict->SetNewFor<CPDF_String>("Producer", "PDFium", false);
+
+  CFX_ByteString cbRootType = pNewRoot->GetStringFor("Type", "");
+  if (cbRootType.IsEmpty())
+    pNewRoot->SetNewFor<CPDF_Name>("Type", "Catalog");
+
+  CPDF_Object* pElement = pNewRoot->GetObjectFor("Pages");
+  CPDF_Dictionary* pNewPages =
+      pElement ? ToDictionary(pElement->GetDirect()) : nullptr;
+  if (!pNewPages) {
+    pNewPages = m_pDestPDFDoc->NewIndirect<CPDF_Dictionary>();
+    pNewRoot->SetNewFor<CPDF_Reference>("Pages", m_pDestPDFDoc,
+                                        pNewPages->GetObjNum());
+  }
+
+  CFX_ByteString cbPageType = pNewPages->GetStringFor("Type", "");
+  if (cbPageType.IsEmpty())
+    pNewPages->SetNewFor<CPDF_Name>("Type", "Pages");
+
+  if (!pNewPages->GetArrayFor("Kids")) {
+    pNewPages->SetNewFor<CPDF_Number>("Count", 0);
+    pNewPages->SetNewFor<CPDF_Reference>(
+        "Kids", m_pDestPDFDoc,
+        m_pDestPDFDoc->NewIndirect<CPDF_Array>()->GetObjNum());
+  }
+
+  return true;
+}
+
+bool CPDF_PageOrganizer::ExportPage(const std::vector<uint16_t>& pageNums,
+                                    int nIndex) {
+  int curpage = nIndex;
+  auto pObjNumberMap = pdfium::MakeUnique<ObjectNumberMap>();
+  int nSize = pdfium::CollectionSize<int>(pageNums);
+  for (int i = 0; i < nSize; ++i) {
+    CPDF_Dictionary* pCurPageDict = m_pDestPDFDoc->CreateNewPage(curpage);
+    CPDF_Dictionary* pSrcPageDict = m_pSrcPDFDoc->GetPage(pageNums[i] - 1);
+    if (!pSrcPageDict || !pCurPageDict)
+      return false;
+
+    // Clone the page dictionary
+    for (const auto& it : *pSrcPageDict) {
+      const CFX_ByteString& cbSrcKeyStr = it.first;
+      if (cbSrcKeyStr == "Type" || cbSrcKeyStr == "Parent")
+        continue;
+
+      CPDF_Object* pObj = it.second.get();
+      pCurPageDict->SetFor(cbSrcKeyStr, pObj->Clone());
+    }
+
+    // inheritable item
+    // 1 MediaBox - required
+    if (!CopyInheritable(pCurPageDict, pSrcPageDict, "MediaBox")) {
+      // Search for "CropBox" in the source page dictionary,
+      // if it does not exists, use the default letter size.
+      CPDF_Object* pInheritable =
+          PageDictGetInheritableTag(pSrcPageDict, "CropBox");
+      if (pInheritable) {
+        pCurPageDict->SetFor("MediaBox", pInheritable->Clone());
+      } else {
+        // Make the default size to be letter size (8.5'x11')
+        CPDF_Array* pArray = pCurPageDict->SetNewFor<CPDF_Array>("MediaBox");
+        pArray->AddNew<CPDF_Number>(0);
+        pArray->AddNew<CPDF_Number>(0);
+        pArray->AddNew<CPDF_Number>(612);
+        pArray->AddNew<CPDF_Number>(792);
+      }
+    }
+
+    // 2 Resources - required
+    if (!CopyInheritable(pCurPageDict, pSrcPageDict, "Resources"))
+      return false;
+
+    // 3 CropBox - optional
+    CopyInheritable(pCurPageDict, pSrcPageDict, "CropBox");
+    // 4 Rotate - optional
+    CopyInheritable(pCurPageDict, pSrcPageDict, "Rotate");
+
+    // Update the reference
+    uint32_t dwOldPageObj = pSrcPageDict->GetObjNum();
+    uint32_t dwNewPageObj = pCurPageDict->GetObjNum();
+    (*pObjNumberMap)[dwOldPageObj] = dwNewPageObj;
+    UpdateReference(pCurPageDict, pObjNumberMap.get());
+    ++curpage;
+  }
+
+  return true;
+}
+
+bool CPDF_PageOrganizer::UpdateReference(CPDF_Object* pObj,
+                                         ObjectNumberMap* pObjNumberMap) {
+  switch (pObj->GetType()) {
+    case CPDF_Object::REFERENCE: {
+      CPDF_Reference* pReference = pObj->AsReference();
+      uint32_t newobjnum = GetNewObjId(pObjNumberMap, pReference);
+      if (newobjnum == 0)
+        return false;
+      pReference->SetRef(m_pDestPDFDoc, newobjnum);
+      break;
+    }
+    case CPDF_Object::DICTIONARY: {
+      CPDF_Dictionary* pDict = pObj->AsDictionary();
+      auto it = pDict->begin();
+      while (it != pDict->end()) {
+        const CFX_ByteString& key = it->first;
+        CPDF_Object* pNextObj = it->second.get();
+        ++it;
+        if (key == "Parent" || key == "Prev" || key == "First")
+          continue;
+        if (!pNextObj)
+          return false;
+        if (!UpdateReference(pNextObj, pObjNumberMap))
+          pDict->RemoveFor(key);
+      }
+      break;
+    }
+    case CPDF_Object::ARRAY: {
+      CPDF_Array* pArray = pObj->AsArray();
+      for (size_t i = 0; i < pArray->GetCount(); ++i) {
+        CPDF_Object* pNextObj = pArray->GetObjectAt(i);
+        if (!pNextObj)
+          return false;
+        if (!UpdateReference(pNextObj, pObjNumberMap))
+          return false;
+      }
+      break;
+    }
+    case CPDF_Object::STREAM: {
+      CPDF_Stream* pStream = pObj->AsStream();
+      CPDF_Dictionary* pDict = pStream->GetDict();
+      if (!pDict)
+        return false;
+      if (!UpdateReference(pDict, pObjNumberMap))
+        return false;
+      break;
+    }
+    default:
+      break;
+  }
+
+  return true;
+}
+
+uint32_t CPDF_PageOrganizer::GetNewObjId(ObjectNumberMap* pObjNumberMap,
+                                         CPDF_Reference* pRef) {
+  if (!pRef)
+    return 0;
+
+  uint32_t dwObjnum = pRef->GetRefObjNum();
+  uint32_t dwNewObjNum = 0;
+  const auto it = pObjNumberMap->find(dwObjnum);
+  if (it != pObjNumberMap->end())
+    dwNewObjNum = it->second;
+  if (dwNewObjNum)
+    return dwNewObjNum;
+
+  CPDF_Object* pDirect = pRef->GetDirect();
+  if (!pDirect)
+    return 0;
+
+  std::unique_ptr<CPDF_Object> pClone = pDirect->Clone();
+  if (CPDF_Dictionary* pDictClone = pClone->AsDictionary()) {
+    if (pDictClone->KeyExist("Type")) {
+      CFX_ByteString strType = pDictClone->GetStringFor("Type");
+      if (!FXSYS_stricmp(strType.c_str(), "Pages"))
+        return 4;
+      if (!FXSYS_stricmp(strType.c_str(), "Page"))
+        return 0;
+    }
+  }
+  CPDF_Object* pUnownedClone =
+      m_pDestPDFDoc->AddIndirectObject(std::move(pClone));
+  dwNewObjNum = pUnownedClone->GetObjNum();
+  (*pObjNumberMap)[dwObjnum] = dwNewObjNum;
+  if (!UpdateReference(pUnownedClone, pObjNumberMap))
+    return 0;
+
+  return dwNewObjNum;
+}
+
+DLLEXPORT FPDF_BOOL STDCALL FPDF_ImportPages(FPDF_DOCUMENT dest_doc,
+                                             FPDF_DOCUMENT src_doc,
+                                             FPDF_BYTESTRING pagerange,
+                                             int index) {
+  CPDF_Document* pDestDoc = CPDFDocumentFromFPDFDocument(dest_doc);
+  if (!dest_doc)
+    return false;
+
+  CPDF_Document* pSrcDoc = CPDFDocumentFromFPDFDocument(src_doc);
+  if (!pSrcDoc)
+    return false;
+
+  std::vector<uint16_t> pageArray;
+  int nCount = pSrcDoc->GetPageCount();
+  if (pagerange) {
+    if (!ParserPageRangeString(pagerange, &pageArray, nCount))
+      return false;
+  } else {
+    for (int i = 1; i <= nCount; ++i) {
+      pageArray.push_back(i);
+    }
+  }
+
+  CPDF_PageOrganizer pageOrg(pDestDoc, pSrcDoc);
+  return pageOrg.PDFDocInit() && pageOrg.ExportPage(pageArray, index);
+}
+
+DLLEXPORT FPDF_BOOL STDCALL FPDF_CopyViewerPreferences(FPDF_DOCUMENT dest_doc,
+                                                       FPDF_DOCUMENT src_doc) {
+  CPDF_Document* pDstDoc = CPDFDocumentFromFPDFDocument(dest_doc);
+  if (!pDstDoc)
+    return false;
+
+  CPDF_Document* pSrcDoc = CPDFDocumentFromFPDFDocument(src_doc);
+  if (!pSrcDoc)
+    return false;
+
+  CPDF_Dictionary* pSrcDict = pSrcDoc->GetRoot();
+  pSrcDict = pSrcDict->GetDictFor("ViewerPreferences");
+  if (!pSrcDict)
+    return false;
+
+  CPDF_Dictionary* pDstDict = pDstDoc->GetRoot();
+  if (!pDstDict)
+    return false;
+
+  pDstDict->SetFor("ViewerPreferences", pSrcDict->CloneDirectObject());
+  return true;
+}
diff --git a/fpdfsdk/fpdfppo_embeddertest.cpp b/fpdfsdk/fpdfppo_embeddertest.cpp
new file mode 100644
index 0000000..0972316
--- /dev/null
+++ b/fpdfsdk/fpdfppo_embeddertest.cpp
@@ -0,0 +1,106 @@
+// 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.
+
+#include "public/fpdf_ppo.h"
+
+#include "core/fxcrt/fx_basic.h"
+#include "public/fpdf_edit.h"
+#include "public/fpdfview.h"
+#include "testing/embedder_test.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/test_support.h"
+
+namespace {
+
+class FPDFPPOEmbeddertest : public EmbedderTest {};
+
+}  // namespace
+
+TEST_F(FPDFPPOEmbeddertest, NoViewerPreferences) {
+  EXPECT_TRUE(OpenDocument("hello_world.pdf"));
+
+  FPDF_DOCUMENT output_doc = FPDF_CreateNewDocument();
+  EXPECT_TRUE(output_doc);
+  EXPECT_FALSE(FPDF_CopyViewerPreferences(output_doc, document()));
+  FPDF_CloseDocument(output_doc);
+}
+
+TEST_F(FPDFPPOEmbeddertest, ViewerPreferences) {
+  EXPECT_TRUE(OpenDocument("viewer_ref.pdf"));
+
+  FPDF_DOCUMENT output_doc = FPDF_CreateNewDocument();
+  EXPECT_TRUE(output_doc);
+  EXPECT_TRUE(FPDF_CopyViewerPreferences(output_doc, document()));
+  FPDF_CloseDocument(output_doc);
+}
+
+TEST_F(FPDFPPOEmbeddertest, ImportPages) {
+  EXPECT_TRUE(OpenDocument("viewer_ref.pdf"));
+
+  FPDF_PAGE page = LoadPage(0);
+  EXPECT_TRUE(page);
+
+  FPDF_DOCUMENT output_doc = FPDF_CreateNewDocument();
+  EXPECT_TRUE(output_doc);
+  EXPECT_TRUE(FPDF_CopyViewerPreferences(output_doc, document()));
+  EXPECT_TRUE(FPDF_ImportPages(output_doc, document(), "1", 0));
+  EXPECT_EQ(1, FPDF_GetPageCount(output_doc));
+  FPDF_CloseDocument(output_doc);
+
+  UnloadPage(page);
+}
+
+TEST_F(FPDFPPOEmbeddertest, BadRanges) {
+  EXPECT_TRUE(OpenDocument("viewer_ref.pdf"));
+
+  FPDF_PAGE page = LoadPage(0);
+  EXPECT_TRUE(page);
+
+  FPDF_DOCUMENT output_doc = FPDF_CreateNewDocument();
+  EXPECT_TRUE(output_doc);
+  EXPECT_FALSE(FPDF_ImportPages(output_doc, document(), "clams", 0));
+  EXPECT_FALSE(FPDF_ImportPages(output_doc, document(), "0", 0));
+  EXPECT_FALSE(FPDF_ImportPages(output_doc, document(), "42", 0));
+  EXPECT_FALSE(FPDF_ImportPages(output_doc, document(), "1,2", 0));
+  EXPECT_FALSE(FPDF_ImportPages(output_doc, document(), "1-2", 0));
+  EXPECT_FALSE(FPDF_ImportPages(output_doc, document(), ",1", 0));
+  EXPECT_FALSE(FPDF_ImportPages(output_doc, document(), "1,", 0));
+  EXPECT_FALSE(FPDF_ImportPages(output_doc, document(), "1-", 0));
+  EXPECT_FALSE(FPDF_ImportPages(output_doc, document(), "-1", 0));
+  EXPECT_FALSE(FPDF_ImportPages(output_doc, document(), "-,0,,,1-", 0));
+  FPDF_CloseDocument(output_doc);
+
+  UnloadPage(page);
+}
+
+TEST_F(FPDFPPOEmbeddertest, GoodRanges) {
+  EXPECT_TRUE(OpenDocument("viewer_ref.pdf"));
+
+  FPDF_PAGE page = LoadPage(0);
+  EXPECT_TRUE(page);
+
+  FPDF_DOCUMENT output_doc = FPDF_CreateNewDocument();
+  EXPECT_TRUE(output_doc);
+  EXPECT_TRUE(FPDF_CopyViewerPreferences(output_doc, document()));
+  EXPECT_TRUE(FPDF_ImportPages(output_doc, document(), "1,1,1,1", 0));
+  EXPECT_TRUE(FPDF_ImportPages(output_doc, document(), "1-1", 0));
+  EXPECT_EQ(5, FPDF_GetPageCount(output_doc));
+  FPDF_CloseDocument(output_doc);
+
+  UnloadPage(page);
+}
+
+TEST_F(FPDFPPOEmbeddertest, BUG_664284) {
+  EXPECT_TRUE(OpenDocument("bug_664284.pdf"));
+
+  FPDF_PAGE page = LoadPage(0);
+  EXPECT_TRUE(page);
+
+  FPDF_DOCUMENT output_doc = FPDF_CreateNewDocument();
+  EXPECT_TRUE(output_doc);
+  EXPECT_TRUE(FPDF_ImportPages(output_doc, document(), "1", 0));
+  FPDF_CloseDocument(output_doc);
+
+  UnloadPage(page);
+}
diff --git a/fpdfsdk/fpdfsave.cpp b/fpdfsdk/fpdfsave.cpp
new file mode 100644
index 0000000..0cfcd4a
--- /dev/null
+++ b/fpdfsdk/fpdfsave.cpp
@@ -0,0 +1,319 @@
+// 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
+
+#include "public/fpdf_save.h"
+
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "core/fpdfapi/edit/cpdf_creator.h"
+#include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/cpdf_reference.h"
+#include "core/fpdfapi/parser/cpdf_stream_acc.h"
+#include "core/fpdfapi/parser/cpdf_string.h"
+#include "core/fxcrt/fx_ext.h"
+#include "fpdfsdk/fsdk_define.h"
+#include "public/fpdf_edit.h"
+
+#ifdef PDF_ENABLE_XFA
+#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
+#include "fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h"
+#include "public/fpdf_formfill.h"
+#include "xfa/fxfa/cxfa_eventparam.h"
+#include "xfa/fxfa/xfa_checksum.h"
+#include "xfa/fxfa/xfa_ffapp.h"
+#include "xfa/fxfa/xfa_ffdocview.h"
+#include "xfa/fxfa/xfa_ffwidgethandler.h"
+#endif
+
+#if _FX_OS_ == _FX_ANDROID_
+#include <time.h>
+#else
+#include <ctime>
+#endif
+
+class CFX_IFileWrite final : public IFX_WriteStream {
+ public:
+  static CFX_RetainPtr<CFX_IFileWrite> Create();
+  bool Init(FPDF_FILEWRITE* pFileWriteStruct);
+  bool WriteBlock(const void* pData, size_t size) override;
+
+ protected:
+  CFX_IFileWrite();
+  ~CFX_IFileWrite() override {}
+
+  FPDF_FILEWRITE* m_pFileWriteStruct;
+};
+
+CFX_RetainPtr<CFX_IFileWrite> CFX_IFileWrite::Create() {
+  return CFX_RetainPtr<CFX_IFileWrite>(new CFX_IFileWrite());
+}
+
+CFX_IFileWrite::CFX_IFileWrite() : m_pFileWriteStruct(nullptr) {}
+
+bool CFX_IFileWrite::Init(FPDF_FILEWRITE* pFileWriteStruct) {
+  if (!pFileWriteStruct)
+    return false;
+
+  m_pFileWriteStruct = pFileWriteStruct;
+  return true;
+}
+
+bool CFX_IFileWrite::WriteBlock(const void* pData, size_t size) {
+  if (!m_pFileWriteStruct)
+    return false;
+
+  m_pFileWriteStruct->WriteBlock(m_pFileWriteStruct, pData, size);
+  return true;
+}
+
+namespace {
+
+#ifdef PDF_ENABLE_XFA
+bool SaveXFADocumentData(
+    CPDFXFA_Context* pContext,
+    std::vector<CFX_RetainPtr<IFX_SeekableStream>>* fileList) {
+  if (!pContext)
+    return false;
+
+  if (pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA &&
+      pContext->GetDocType() != DOCTYPE_STATIC_XFA)
+    return true;
+
+  CXFA_FFDocView* pXFADocView = pContext->GetXFADocView();
+  if (!pXFADocView)
+    return true;
+
+  CPDF_Document* pPDFDocument = pContext->GetPDFDoc();
+  if (!pPDFDocument)
+    return false;
+
+  CPDF_Dictionary* pRoot = pPDFDocument->GetRoot();
+  if (!pRoot)
+    return false;
+
+  CPDF_Dictionary* pAcroForm = pRoot->GetDictFor("AcroForm");
+  if (!pAcroForm)
+    return false;
+
+  CPDF_Object* pXFA = pAcroForm->GetObjectFor("XFA");
+  if (!pXFA)
+    return true;
+
+  CPDF_Array* pArray = pXFA->AsArray();
+  if (!pArray)
+    return false;
+
+  int size = pArray->GetCount();
+  int iFormIndex = -1;
+  int iDataSetsIndex = -1;
+  int iTemplate = -1;
+  int iLast = size - 2;
+  for (int i = 0; i < size - 1; i++) {
+    CPDF_Object* pPDFObj = pArray->GetObjectAt(i);
+    if (!pPDFObj->IsString())
+      continue;
+    if (pPDFObj->GetString() == "form")
+      iFormIndex = i + 1;
+    else if (pPDFObj->GetString() == "datasets")
+      iDataSetsIndex = i + 1;
+    else if (pPDFObj->GetString() == "template")
+      iTemplate = i + 1;
+  }
+  std::unique_ptr<CXFA_ChecksumContext> pChecksum(new CXFA_ChecksumContext);
+  pChecksum->StartChecksum();
+
+  // template
+  if (iTemplate > -1) {
+    CPDF_Stream* pTemplateStream = pArray->GetStreamAt(iTemplate);
+    CPDF_StreamAcc streamAcc;
+    streamAcc.LoadAllData(pTemplateStream);
+    uint8_t* pData = (uint8_t*)streamAcc.GetData();
+    uint32_t dwSize2 = streamAcc.GetSize();
+    CFX_RetainPtr<IFX_SeekableStream> pTemplate =
+        IFX_MemoryStream::Create(pData, dwSize2);
+    pChecksum->UpdateChecksum(pTemplate);
+  }
+  CPDF_Stream* pFormStream = nullptr;
+  CPDF_Stream* pDataSetsStream = nullptr;
+  if (iFormIndex != -1) {
+    // Get form CPDF_Stream
+    CPDF_Object* pFormPDFObj = pArray->GetObjectAt(iFormIndex);
+    if (pFormPDFObj->IsReference()) {
+      CPDF_Object* pFormDirectObj = pFormPDFObj->GetDirect();
+      if (pFormDirectObj && pFormDirectObj->IsStream()) {
+        pFormStream = (CPDF_Stream*)pFormDirectObj;
+      }
+    } else if (pFormPDFObj->IsStream()) {
+      pFormStream = (CPDF_Stream*)pFormPDFObj;
+    }
+  }
+
+  if (iDataSetsIndex != -1) {
+    // Get datasets CPDF_Stream
+    CPDF_Object* pDataSetsPDFObj = pArray->GetObjectAt(iDataSetsIndex);
+    if (pDataSetsPDFObj->IsReference()) {
+      CPDF_Reference* pDataSetsRefObj = (CPDF_Reference*)pDataSetsPDFObj;
+      CPDF_Object* pDataSetsDirectObj = pDataSetsRefObj->GetDirect();
+      if (pDataSetsDirectObj && pDataSetsDirectObj->IsStream()) {
+        pDataSetsStream = (CPDF_Stream*)pDataSetsDirectObj;
+      }
+    } else if (pDataSetsPDFObj->IsStream()) {
+      pDataSetsStream = (CPDF_Stream*)pDataSetsPDFObj;
+    }
+  }
+  // L"datasets"
+  {
+    CFX_RetainPtr<IFX_SeekableStream> pDsfileWrite = IFX_MemoryStream::Create();
+    if (pXFADocView->GetDoc()->SavePackage(XFA_HASHCODE_Datasets, pDsfileWrite,
+                                           nullptr) &&
+        pDsfileWrite->GetSize() > 0) {
+      // Datasets
+      pChecksum->UpdateChecksum(pDsfileWrite);
+      pChecksum->FinishChecksum();
+      auto pDataDict = pdfium::MakeUnique<CPDF_Dictionary>(
+          pPDFDocument->GetByteStringPool());
+      if (iDataSetsIndex != -1) {
+        if (pDataSetsStream) {
+          pDataSetsStream->InitStreamFromFile(pDsfileWrite,
+                                              std::move(pDataDict));
+        }
+      } else {
+        CPDF_Stream* pData = pPDFDocument->NewIndirect<CPDF_Stream>();
+        pData->InitStreamFromFile(pDsfileWrite, std::move(pDataDict));
+        iLast = pArray->GetCount() - 2;
+        pArray->InsertNewAt<CPDF_String>(iLast, "datasets", false);
+        pArray->InsertNewAt<CPDF_Reference>(iLast + 1, pPDFDocument,
+                                            pData->GetObjNum());
+      }
+      fileList->push_back(std::move(pDsfileWrite));
+    }
+  }
+  // L"form"
+  {
+    CFX_RetainPtr<IFX_SeekableStream> pfileWrite = IFX_MemoryStream::Create();
+    if (pXFADocView->GetDoc()->SavePackage(XFA_HASHCODE_Form, pfileWrite,
+                                           pChecksum.get()) &&
+        pfileWrite->GetSize() > 0) {
+      auto pDataDict = pdfium::MakeUnique<CPDF_Dictionary>(
+          pPDFDocument->GetByteStringPool());
+      if (iFormIndex != -1) {
+        if (pFormStream)
+          pFormStream->InitStreamFromFile(pfileWrite, std::move(pDataDict));
+      } else {
+        CPDF_Stream* pData = pPDFDocument->NewIndirect<CPDF_Stream>();
+        pData->InitStreamFromFile(pfileWrite, std::move(pDataDict));
+        iLast = pArray->GetCount() - 2;
+        pArray->InsertNewAt<CPDF_String>(iLast, "form", false);
+        pArray->InsertNewAt<CPDF_Reference>(iLast + 1, pPDFDocument,
+                                            pData->GetObjNum());
+      }
+      fileList->push_back(std::move(pfileWrite));
+    }
+  }
+  return true;
+}
+
+bool SendPostSaveToXFADoc(CPDFXFA_Context* pContext) {
+  if (!pContext)
+    return false;
+
+  if (pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA &&
+      pContext->GetDocType() != DOCTYPE_STATIC_XFA)
+    return true;
+
+  CXFA_FFDocView* pXFADocView = pContext->GetXFADocView();
+  if (!pXFADocView)
+    return false;
+
+  CXFA_FFWidgetHandler* pWidgetHander = pXFADocView->GetWidgetHandler();
+  std::unique_ptr<CXFA_WidgetAccIterator> pWidgetAccIterator(
+      pXFADocView->CreateWidgetAccIterator());
+  while (CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext()) {
+    CXFA_EventParam preParam;
+    preParam.m_eType = XFA_EVENT_PostSave;
+    pWidgetHander->ProcessEvent(pWidgetAcc, &preParam);
+  }
+  pXFADocView->UpdateDocView();
+  pContext->ClearChangeMark();
+  return true;
+}
+
+bool SendPreSaveToXFADoc(
+    CPDFXFA_Context* pContext,
+    std::vector<CFX_RetainPtr<IFX_SeekableStream>>* fileList) {
+  if (pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA &&
+      pContext->GetDocType() != DOCTYPE_STATIC_XFA)
+    return true;
+
+  CXFA_FFDocView* pXFADocView = pContext->GetXFADocView();
+  if (!pXFADocView)
+    return true;
+
+  CXFA_FFWidgetHandler* pWidgetHander = pXFADocView->GetWidgetHandler();
+  std::unique_ptr<CXFA_WidgetAccIterator> pWidgetAccIterator(
+      pXFADocView->CreateWidgetAccIterator());
+  while (CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext()) {
+    CXFA_EventParam preParam;
+    preParam.m_eType = XFA_EVENT_PreSave;
+    pWidgetHander->ProcessEvent(pWidgetAcc, &preParam);
+  }
+  pXFADocView->UpdateDocView();
+  return SaveXFADocumentData(pContext, fileList);
+}
+#endif  // PDF_ENABLE_XFA
+
+bool FPDF_Doc_Save(FPDF_DOCUMENT document,
+                   FPDF_FILEWRITE* pFileWrite,
+                   FPDF_DWORD flags,
+                   FPDF_BOOL bSetVersion,
+                   int fileVerion) {
+  CPDF_Document* pPDFDoc = CPDFDocumentFromFPDFDocument(document);
+  if (!pPDFDoc)
+    return 0;
+
+#ifdef PDF_ENABLE_XFA
+  CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
+  std::vector<CFX_RetainPtr<IFX_SeekableStream>> fileList;
+  SendPreSaveToXFADoc(pContext, &fileList);
+#endif  // PDF_ENABLE_XFA
+
+  if (flags < FPDF_INCREMENTAL || flags > FPDF_REMOVE_SECURITY)
+    flags = 0;
+
+  CPDF_Creator FileMaker(pPDFDoc);
+  if (bSetVersion)
+    FileMaker.SetFileVersion(fileVerion);
+  if (flags == FPDF_REMOVE_SECURITY) {
+    flags = 0;
+    FileMaker.RemoveSecurity();
+  }
+
+  CFX_RetainPtr<CFX_IFileWrite> pStreamWrite = CFX_IFileWrite::Create();
+  pStreamWrite->Init(pFileWrite);
+  bool bRet = FileMaker.Create(pStreamWrite, flags);
+#ifdef PDF_ENABLE_XFA
+  SendPostSaveToXFADoc(pContext);
+#endif  // PDF_ENABLE_XFA
+  return bRet;
+}
+
+}  // namespace
+
+DLLEXPORT FPDF_BOOL STDCALL FPDF_SaveAsCopy(FPDF_DOCUMENT document,
+                                            FPDF_FILEWRITE* pFileWrite,
+                                            FPDF_DWORD flags) {
+  return FPDF_Doc_Save(document, pFileWrite, flags, false, 0);
+}
+
+DLLEXPORT FPDF_BOOL STDCALL FPDF_SaveWithVersion(FPDF_DOCUMENT document,
+                                                 FPDF_FILEWRITE* pFileWrite,
+                                                 FPDF_DWORD flags,
+                                                 int fileVersion) {
+  return FPDF_Doc_Save(document, pFileWrite, flags, true, fileVersion);
+}
diff --git a/fpdfsdk/src/fpdfsave_embeddertest.cpp b/fpdfsdk/fpdfsave_embeddertest.cpp
similarity index 75%
rename from fpdfsdk/src/fpdfsave_embeddertest.cpp
rename to fpdfsdk/fpdfsave_embeddertest.cpp
index 1c93f4f..9187270 100644
--- a/fpdfsdk/src/fpdfsave_embeddertest.cpp
+++ b/fpdfsdk/fpdfsave_embeddertest.cpp
@@ -2,10 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "public/fpdf_save.h"
+
 #include <string.h>
 
-#include "core/include/fxcrt/fx_string.h"
-#include "public/fpdf_save.h"
+#include "core/fxcrt/fx_string.h"
+#include "public/fpdf_edit.h"
+#include "public/fpdf_ppo.h"
 #include "public/fpdfview.h"
 #include "testing/embedder_test.h"
 #include "testing/fx_string_testhelpers.h"
@@ -19,14 +22,14 @@
   EXPECT_TRUE(OpenDocument("hello_world.pdf"));
   EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
   EXPECT_THAT(GetString(), testing::StartsWith("%PDF-1.7\r\n"));
-  EXPECT_EQ(843, GetString().length());
+  EXPECT_EQ(843u, GetString().length());
 }
 
 TEST_F(FPDFSaveEmbedderTest, SaveSimpleDocWithVersion) {
   EXPECT_TRUE(OpenDocument("hello_world.pdf"));
   EXPECT_TRUE(FPDF_SaveWithVersion(document(), this, 0, 14));
   EXPECT_THAT(GetString(), testing::StartsWith("%PDF-1.4\r\n"));
-  EXPECT_EQ(843, GetString().length());
+  EXPECT_EQ(843u, GetString().length());
 }
 
 TEST_F(FPDFSaveEmbedderTest, SaveSimpleDocWithBadVersion) {
@@ -43,6 +46,21 @@
   EXPECT_THAT(GetString(), testing::StartsWith("%PDF-1.7\r\n"));
 }
 
+TEST_F(FPDFSaveEmbedderTest, SaveCopiedDoc) {
+  EXPECT_TRUE(OpenDocument("hello_world.pdf"));
+
+  FPDF_PAGE page = LoadPage(0);
+  EXPECT_TRUE(page);
+
+  FPDF_DOCUMENT output_doc = FPDF_CreateNewDocument();
+  EXPECT_TRUE(output_doc);
+  EXPECT_TRUE(FPDF_ImportPages(output_doc, document(), "1", 0));
+  EXPECT_TRUE(FPDF_SaveAsCopy(output_doc, this, 0));
+  FPDF_CloseDocument(output_doc);
+
+  UnloadPage(page);
+}
+
 TEST_F(FPDFSaveEmbedderTest, BUG_342) {
   EXPECT_TRUE(OpenDocument("hello_world.pdf"));
   EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
diff --git a/fpdfsdk/src/fpdftext.cpp b/fpdfsdk/fpdftext.cpp
similarity index 66%
rename from fpdfsdk/src/fpdftext.cpp
rename to fpdfsdk/fpdftext.cpp
index c745c26..629e596 100644
--- a/fpdfsdk/src/fpdftext.cpp
+++ b/fpdfsdk/fpdftext.cpp
@@ -6,51 +6,81 @@
 
 #include "public/fpdf_text.h"
 
-#include "core/include/fpdfdoc/fpdf_doc.h"
-#include "core/include/fpdftext/fpdf_text.h"
-#include "fpdfsdk/include/fsdk_define.h"
+#include <algorithm>
+#include <vector>
+
+#include "core/fpdfapi/page/cpdf_page.h"
+#include "core/fpdfdoc/cpdf_viewerpreferences.h"
+#include "core/fpdftext/cpdf_linkextract.h"
+#include "core/fpdftext/cpdf_textpage.h"
+#include "core/fpdftext/cpdf_textpagefind.h"
+#include "fpdfsdk/fsdk_define.h"
+#include "third_party/base/numerics/safe_conversions.h"
+#include "third_party/base/stl_util.h"
 
 #ifdef PDF_ENABLE_XFA
-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h"
-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_page.h"
+#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
+#include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
 #endif  // PDF_ENABLE_XFA
 
 #ifdef _WIN32
 #include <tchar.h>
 #endif
 
+namespace {
+
+CPDF_TextPage* CPDFTextPageFromFPDFTextPage(FPDF_TEXTPAGE text_page) {
+  return static_cast<CPDF_TextPage*>(text_page);
+}
+
+CPDF_TextPageFind* CPDFTextPageFindFromFPDFSchHandle(FPDF_SCHHANDLE handle) {
+  return static_cast<CPDF_TextPageFind*>(handle);
+}
+
+CPDF_LinkExtract* CPDFLinkExtractFromFPDFPageLink(FPDF_PAGELINK link) {
+  return static_cast<CPDF_LinkExtract*>(link);
+}
+
+}  // namespace
+
 DLLEXPORT FPDF_TEXTPAGE STDCALL FPDFText_LoadPage(FPDF_PAGE page) {
   CPDF_Page* pPDFPage = CPDFPageFromFPDFPage(page);
   if (!pPDFPage)
     return nullptr;
+
 #ifdef PDF_ENABLE_XFA
   CPDFXFA_Page* pPage = (CPDFXFA_Page*)page;
-  CPDFXFA_Document* pDoc = pPage->GetDocument();
-  CPDF_ViewerPreferences viewRef(pDoc->GetPDFDoc());
+  CPDFXFA_Context* pContext = pPage->GetContext();
+  CPDF_ViewerPreferences viewRef(pContext->GetPDFDoc());
 #else  // PDF_ENABLE_XFA
   CPDF_ViewerPreferences viewRef(pPDFPage->m_pDocument);
 #endif  // PDF_ENABLE_XFA
-  IPDF_TextPage* textpage =
-      IPDF_TextPage::CreateTextPage(pPDFPage, viewRef.IsDirectionR2L());
+
+  CPDF_TextPage* textpage = new CPDF_TextPage(
+      pPDFPage, viewRef.IsDirectionR2L() ? FPDFText_Direction::Right
+                                         : FPDFText_Direction::Left);
   textpage->ParseTextPage();
   return textpage;
 }
+
 DLLEXPORT void STDCALL FPDFText_ClosePage(FPDF_TEXTPAGE text_page) {
-  delete (IPDF_TextPage*)text_page;
+  delete CPDFTextPageFromFPDFTextPage(text_page);
 }
+
 DLLEXPORT int STDCALL FPDFText_CountChars(FPDF_TEXTPAGE text_page) {
   if (!text_page)
     return -1;
-  IPDF_TextPage* textpage = (IPDF_TextPage*)text_page;
+
+  CPDF_TextPage* textpage = CPDFTextPageFromFPDFTextPage(text_page);
   return textpage->CountChars();
 }
 
 DLLEXPORT unsigned int STDCALL FPDFText_GetUnicode(FPDF_TEXTPAGE text_page,
                                                    int index) {
   if (!text_page)
-    return -1;
-  IPDF_TextPage* textpage = (IPDF_TextPage*)text_page;
+    return 0;
 
+  CPDF_TextPage* textpage = CPDFTextPageFromFPDFTextPage(text_page);
   if (index < 0 || index >= textpage->CountChars())
     return 0;
 
@@ -63,7 +93,7 @@
                                               int index) {
   if (!text_page)
     return 0;
-  IPDF_TextPage* textpage = (IPDF_TextPage*)text_page;
+  CPDF_TextPage* textpage = CPDFTextPageFromFPDFTextPage(text_page);
 
   if (index < 0 || index >= textpage->CountChars())
     return 0;
@@ -81,7 +111,7 @@
                                            double* top) {
   if (!text_page)
     return;
-  IPDF_TextPage* textpage = (IPDF_TextPage*)text_page;
+  CPDF_TextPage* textpage = CPDFTextPageFromFPDFTextPage(text_page);
 
   if (index < 0 || index >= textpage->CountChars())
     return;
@@ -101,7 +131,8 @@
                                                  double yTolerance) {
   if (!text_page)
     return -3;
-  IPDF_TextPage* textpage = (IPDF_TextPage*)text_page;
+
+  CPDF_TextPage* textpage = CPDFTextPageFromFPDFTextPage(text_page);
   return textpage->GetIndexAtPos((FX_FLOAT)x, (FX_FLOAT)y, (FX_FLOAT)xTolerance,
                                  (FX_FLOAT)yTolerance);
 }
@@ -112,8 +143,8 @@
                                        unsigned short* result) {
   if (!text_page)
     return 0;
-  IPDF_TextPage* textpage = (IPDF_TextPage*)text_page;
 
+  CPDF_TextPage* textpage = CPDFTextPageFromFPDFTextPage(text_page);
   if (start >= textpage->CountChars())
     return 0;
 
@@ -134,9 +165,11 @@
                                           int count) {
   if (!text_page)
     return 0;
-  IPDF_TextPage* textpage = (IPDF_TextPage*)text_page;
+
+  CPDF_TextPage* textpage = CPDFTextPageFromFPDFTextPage(text_page);
   return textpage->CountRects(start, count);
 }
+
 DLLEXPORT void STDCALL FPDFText_GetRect(FPDF_TEXTPAGE text_page,
                                         int rect_index,
                                         double* left,
@@ -145,7 +178,8 @@
                                         double* bottom) {
   if (!text_page)
     return;
-  IPDF_TextPage* textpage = (IPDF_TextPage*)text_page;
+
+  CPDF_TextPage* textpage = CPDFTextPageFromFPDFTextPage(text_page);
   CFX_FloatRect rect;
   textpage->GetRect(rect_index, rect.left, rect.top, rect.right, rect.bottom);
   *left = rect.left;
@@ -163,14 +197,14 @@
                                               int buflen) {
   if (!text_page)
     return 0;
-  IPDF_TextPage* textpage = (IPDF_TextPage*)text_page;
+
+  CPDF_TextPage* textpage = CPDFTextPageFromFPDFTextPage(text_page);
   CFX_FloatRect rect((FX_FLOAT)left, (FX_FLOAT)bottom, (FX_FLOAT)right,
                      (FX_FLOAT)top);
   CFX_WideString str = textpage->GetTextByRect(rect);
 
-  if (buflen <= 0 || !buffer) {
+  if (buflen <= 0 || !buffer)
     return str.GetLength();
-  }
 
   CFX_ByteString cbUTF16Str = str.UTF16LE_Encode();
   int len = cbUTF16Str.GetLength() / sizeof(unsigned short);
@@ -183,97 +217,113 @@
 }
 
 // Search
-//-1 for end
+// -1 for end
 DLLEXPORT FPDF_SCHHANDLE STDCALL FPDFText_FindStart(FPDF_TEXTPAGE text_page,
                                                     FPDF_WIDESTRING findwhat,
                                                     unsigned long flags,
                                                     int start_index) {
   if (!text_page)
-    return NULL;
-  IPDF_TextPageFind* textpageFind = NULL;
-  textpageFind = IPDF_TextPageFind::CreatePageFind((IPDF_TextPage*)text_page);
+    return nullptr;
+
+  CPDF_TextPageFind* textpageFind =
+      new CPDF_TextPageFind(CPDFTextPageFromFPDFTextPage(text_page));
   FX_STRSIZE len = CFX_WideString::WStringLength(findwhat);
   textpageFind->FindFirst(CFX_WideString::FromUTF16LE(findwhat, len), flags,
                           start_index);
   return textpageFind;
 }
+
 DLLEXPORT FPDF_BOOL STDCALL FPDFText_FindNext(FPDF_SCHHANDLE handle) {
   if (!handle)
-    return FALSE;
-  IPDF_TextPageFind* textpageFind = (IPDF_TextPageFind*)handle;
+    return false;
+
+  CPDF_TextPageFind* textpageFind = CPDFTextPageFindFromFPDFSchHandle(handle);
   return textpageFind->FindNext();
 }
+
 DLLEXPORT FPDF_BOOL STDCALL FPDFText_FindPrev(FPDF_SCHHANDLE handle) {
   if (!handle)
-    return FALSE;
-  IPDF_TextPageFind* textpageFind = (IPDF_TextPageFind*)handle;
+    return false;
+
+  CPDF_TextPageFind* textpageFind = CPDFTextPageFindFromFPDFSchHandle(handle);
   return textpageFind->FindPrev();
 }
+
 DLLEXPORT int STDCALL FPDFText_GetSchResultIndex(FPDF_SCHHANDLE handle) {
   if (!handle)
     return 0;
-  IPDF_TextPageFind* textpageFind = (IPDF_TextPageFind*)handle;
+
+  CPDF_TextPageFind* textpageFind = CPDFTextPageFindFromFPDFSchHandle(handle);
   return textpageFind->GetCurOrder();
 }
+
 DLLEXPORT int STDCALL FPDFText_GetSchCount(FPDF_SCHHANDLE handle) {
   if (!handle)
     return 0;
-  IPDF_TextPageFind* textpageFind = (IPDF_TextPageFind*)handle;
+
+  CPDF_TextPageFind* textpageFind = CPDFTextPageFindFromFPDFSchHandle(handle);
   return textpageFind->GetMatchedCount();
 }
+
 DLLEXPORT void STDCALL FPDFText_FindClose(FPDF_SCHHANDLE handle) {
   if (!handle)
     return;
-  IPDF_TextPageFind* textpageFind = (IPDF_TextPageFind*)handle;
+
+  CPDF_TextPageFind* textpageFind = CPDFTextPageFindFromFPDFSchHandle(handle);
   delete textpageFind;
-  handle = NULL;
+  handle = nullptr;
 }
 
 // web link
 DLLEXPORT FPDF_PAGELINK STDCALL FPDFLink_LoadWebLinks(FPDF_TEXTPAGE text_page) {
   if (!text_page)
-    return NULL;
-  IPDF_LinkExtract* pageLink = NULL;
-  pageLink = IPDF_LinkExtract::CreateLinkExtract();
-  pageLink->ExtractLinks((IPDF_TextPage*)text_page);
+    return nullptr;
+
+  CPDF_LinkExtract* pageLink =
+      new CPDF_LinkExtract(CPDFTextPageFromFPDFTextPage(text_page));
+  pageLink->ExtractLinks();
   return pageLink;
 }
+
 DLLEXPORT int STDCALL FPDFLink_CountWebLinks(FPDF_PAGELINK link_page) {
   if (!link_page)
     return 0;
-  IPDF_LinkExtract* pageLink = (IPDF_LinkExtract*)link_page;
-  return pageLink->CountLinks();
+
+  CPDF_LinkExtract* pageLink = CPDFLinkExtractFromFPDFPageLink(link_page);
+  return pdfium::base::checked_cast<int>(pageLink->CountLinks());
 }
+
 DLLEXPORT int STDCALL FPDFLink_GetURL(FPDF_PAGELINK link_page,
                                       int link_index,
                                       unsigned short* buffer,
                                       int buflen) {
-  if (!link_page)
-    return 0;
-  IPDF_LinkExtract* pageLink = (IPDF_LinkExtract*)link_page;
-  CFX_WideString url = pageLink->GetURL(link_index);
-
-  CFX_ByteString cbUTF16URL = url.UTF16LE_Encode();
-  int len = cbUTF16URL.GetLength() / sizeof(unsigned short);
+  CFX_WideString wsUrl(L"");
+  if (link_page && link_index >= 0) {
+    CPDF_LinkExtract* pageLink = CPDFLinkExtractFromFPDFPageLink(link_page);
+    wsUrl = pageLink->GetURL(link_index);
+  }
+  CFX_ByteString cbUTF16URL = wsUrl.UTF16LE_Encode();
+  int required = cbUTF16URL.GetLength() / sizeof(unsigned short);
   if (!buffer || buflen <= 0)
-    return len;
-  int size = len < buflen ? len : buflen;
+    return required;
+
+  int size = std::min(required, buflen);
   if (size > 0) {
-    FXSYS_memcpy(buffer, cbUTF16URL.GetBuffer(size * sizeof(unsigned short)),
-                 size * sizeof(unsigned short));
-    cbUTF16URL.ReleaseBuffer(size * sizeof(unsigned short));
+    int buf_size = size * sizeof(unsigned short);
+    FXSYS_memcpy(buffer, cbUTF16URL.GetBuffer(buf_size), buf_size);
   }
   return size;
 }
+
 DLLEXPORT int STDCALL FPDFLink_CountRects(FPDF_PAGELINK link_page,
                                           int link_index) {
-  if (!link_page)
+  if (!link_page || link_index < 0)
     return 0;
-  IPDF_LinkExtract* pageLink = (IPDF_LinkExtract*)link_page;
-  CFX_RectArray rectArray;
-  pageLink->GetRects(link_index, rectArray);
-  return rectArray.GetSize();
+
+  CPDF_LinkExtract* pageLink = CPDFLinkExtractFromFPDFPageLink(link_page);
+  return pdfium::CollectionSize<int>(pageLink->GetRects(link_index));
 }
+
 DLLEXPORT void STDCALL FPDFLink_GetRect(FPDF_PAGELINK link_page,
                                         int link_index,
                                         int rect_index,
@@ -281,19 +331,20 @@
                                         double* top,
                                         double* right,
                                         double* bottom) {
-  if (!link_page)
+  if (!link_page || link_index < 0 || rect_index < 0)
     return;
-  IPDF_LinkExtract* pageLink = (IPDF_LinkExtract*)link_page;
-  CFX_RectArray rectArray;
-  pageLink->GetRects(link_index, rectArray);
-  if (rect_index >= 0 && rect_index < rectArray.GetSize()) {
-    CFX_FloatRect rect = rectArray.GetAt(rect_index);
-    *left = rect.left;
-    *right = rect.right;
-    *top = rect.top;
-    *bottom = rect.bottom;
-  }
+
+  CPDF_LinkExtract* pageLink = CPDFLinkExtractFromFPDFPageLink(link_page);
+  std::vector<CFX_FloatRect> rectArray = pageLink->GetRects(link_index);
+  if (rect_index >= pdfium::CollectionSize<int>(rectArray))
+    return;
+
+  *left = rectArray[rect_index].left;
+  *right = rectArray[rect_index].right;
+  *top = rectArray[rect_index].top;
+  *bottom = rectArray[rect_index].bottom;
 }
+
 DLLEXPORT void STDCALL FPDFLink_CloseWebLinks(FPDF_PAGELINK link_page) {
-  delete (IPDF_LinkExtract*)link_page;
+  delete CPDFLinkExtractFromFPDFPageLink(link_page);
 }
diff --git a/fpdfsdk/src/fpdftext_embeddertest.cpp b/fpdfsdk/fpdftext_embeddertest.cpp
similarity index 87%
rename from fpdfsdk/src/fpdftext_embeddertest.cpp
rename to fpdfsdk/fpdftext_embeddertest.cpp
index e84a96e..198ef8a 100644
--- a/fpdfsdk/src/fpdftext_embeddertest.cpp
+++ b/fpdfsdk/fpdftext_embeddertest.cpp
@@ -2,12 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "core/include/fxcrt/fx_basic.h"
+#include <memory>
+
+#include "core/fxcrt/fx_basic.h"
 #include "public/fpdf_text.h"
 #include "public/fpdfview.h"
 #include "testing/embedder_test.h"
-#include "testing/test_support.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "testing/test_support.h"
 
 namespace {
 
@@ -32,10 +34,10 @@
 TEST_F(FPDFTextEmbeddertest, Text) {
   EXPECT_TRUE(OpenDocument("hello_world.pdf"));
   FPDF_PAGE page = LoadPage(0);
-  EXPECT_NE(nullptr, page);
+  EXPECT_TRUE(page);
 
   FPDF_TEXTPAGE textpage = FPDFText_LoadPage(page);
-  EXPECT_NE(nullptr, textpage);
+  EXPECT_TRUE(textpage);
 
   static const char expected[] = "Hello, world!\r\nGoodbye, world!";
   unsigned short fixed_buffer[128];
@@ -48,7 +50,8 @@
   EXPECT_TRUE(check_unsigned_shorts(expected, fixed_buffer, sizeof(expected)));
 
   // Count does not include the terminating NUL in the string literal.
-  EXPECT_EQ(sizeof(expected) - 1, FPDFText_CountChars(textpage));
+  EXPECT_EQ(sizeof(expected) - 1,
+            static_cast<size_t>(FPDFText_CountChars(textpage)));
   for (size_t i = 0; i < sizeof(expected) - 1; ++i) {
     EXPECT_EQ(static_cast<unsigned int>(expected[i]),
               FPDFText_GetUnicode(textpage, i))
@@ -140,10 +143,10 @@
 TEST_F(FPDFTextEmbeddertest, TextSearch) {
   EXPECT_TRUE(OpenDocument("hello_world.pdf"));
   FPDF_PAGE page = LoadPage(0);
-  EXPECT_NE(nullptr, page);
+  EXPECT_TRUE(page);
 
   FPDF_TEXTPAGE textpage = FPDFText_LoadPage(page);
-  EXPECT_NE(nullptr, textpage);
+  EXPECT_TRUE(textpage);
 
   std::unique_ptr<unsigned short, pdfium::FreeDeleter> nope =
       GetFPDFWideString(L"nope");
@@ -156,7 +159,7 @@
 
   // No occurences of "nope" in test page.
   FPDF_SCHHANDLE search = FPDFText_FindStart(textpage, nope.get(), 0, 0);
-  EXPECT_NE(nullptr, search);
+  EXPECT_TRUE(search);
   EXPECT_EQ(0, FPDFText_GetSchResultIndex(search));
   EXPECT_EQ(0, FPDFText_GetSchCount(search));
 
@@ -173,7 +176,7 @@
 
   // Two occurences of "world" in test page.
   search = FPDFText_FindStart(textpage, world.get(), 0, 2);
-  EXPECT_NE(nullptr, search);
+  EXPECT_TRUE(search);
 
   // Remains not found until advanced.
   EXPECT_EQ(0, FPDFText_GetSchResultIndex(search));
@@ -208,7 +211,7 @@
   // Exact search unaffected by case sensitiity and whole word flags.
   search = FPDFText_FindStart(textpage, world.get(),
                               FPDF_MATCHCASE | FPDF_MATCHWHOLEWORD, 0);
-  EXPECT_NE(nullptr, search);
+  EXPECT_TRUE(search);
   EXPECT_TRUE(FPDFText_FindNext(search));
   EXPECT_EQ(7, FPDFText_GetSchResultIndex(search));
   EXPECT_EQ(5, FPDFText_GetSchCount(search));
@@ -216,7 +219,7 @@
 
   // Default is case-insensitive, so matching agaist caps works.
   search = FPDFText_FindStart(textpage, world_caps.get(), 0, 0);
-  EXPECT_NE(nullptr, search);
+  EXPECT_TRUE(search);
   EXPECT_TRUE(FPDFText_FindNext(search));
   EXPECT_EQ(7, FPDFText_GetSchResultIndex(search));
   EXPECT_EQ(5, FPDFText_GetSchCount(search));
@@ -251,10 +254,10 @@
 TEST_F(FPDFTextEmbeddertest, StreamLengthPastEndOfFile) {
   EXPECT_TRUE(OpenDocument("bug_57.pdf"));
   FPDF_PAGE page = LoadPage(0);
-  EXPECT_NE(nullptr, page);
+  EXPECT_TRUE(page);
 
   FPDF_TEXTPAGE textpage = FPDFText_LoadPage(page);
-  EXPECT_NE(nullptr, textpage);
+  EXPECT_TRUE(textpage);
   EXPECT_EQ(13, FPDFText_CountChars(textpage));
 
   FPDFText_ClosePage(textpage);
@@ -264,13 +267,13 @@
 TEST_F(FPDFTextEmbeddertest, WebLinks) {
   EXPECT_TRUE(OpenDocument("weblinks.pdf"));
   FPDF_PAGE page = LoadPage(0);
-  EXPECT_NE(nullptr, page);
+  EXPECT_TRUE(page);
 
   FPDF_TEXTPAGE textpage = FPDFText_LoadPage(page);
-  EXPECT_NE(nullptr, textpage);
+  EXPECT_TRUE(textpage);
 
   FPDF_PAGELINK pagelink = FPDFLink_LoadWebLinks(textpage);
-  EXPECT_NE(nullptr, pagelink);
+  EXPECT_TRUE(pagelink);
 
   // Page contains two HTTP-style URLs.
   EXPECT_EQ(2, FPDFLink_CountWebLinks(pagelink));
@@ -285,6 +288,7 @@
   EXPECT_EQ(26, FPDFLink_GetURL(pagelink, 1, nullptr, 0));
 
   static const char expected_url[] = "http://example.com?q=foo";
+  static const size_t expected_len = sizeof(expected_url);
   unsigned short fixed_buffer[128];
 
   // Retrieve a link with too small a buffer.  Buffer will not be
@@ -297,30 +301,27 @@
 
   // Check buffer that doesn't have space for a terminating NUL.
   memset(fixed_buffer, 0xbd, sizeof(fixed_buffer));
-  EXPECT_EQ(
-      sizeof(expected_url) - 1,
-      FPDFLink_GetURL(pagelink, 0, fixed_buffer, sizeof(expected_url) - 1));
-  EXPECT_TRUE(check_unsigned_shorts(expected_url, fixed_buffer,
-                                    sizeof(expected_url) - 1));
-  EXPECT_EQ(0xbdbd, fixed_buffer[sizeof(expected_url) - 1]);
+  EXPECT_EQ(static_cast<int>(expected_len - 1),
+            FPDFLink_GetURL(pagelink, 0, fixed_buffer, expected_len - 1));
+  EXPECT_TRUE(
+      check_unsigned_shorts(expected_url, fixed_buffer, expected_len - 1));
+  EXPECT_EQ(0xbdbd, fixed_buffer[expected_len - 1]);
 
   // Retreive link with exactly-sized buffer.
   memset(fixed_buffer, 0xbd, sizeof(fixed_buffer));
-  EXPECT_EQ(sizeof(expected_url),
-            FPDFLink_GetURL(pagelink, 0, fixed_buffer, sizeof(expected_url)));
-  EXPECT_TRUE(
-      check_unsigned_shorts(expected_url, fixed_buffer, sizeof(expected_url)));
-  EXPECT_EQ(0u, fixed_buffer[sizeof(expected_url) - 1]);
-  EXPECT_EQ(0xbdbd, fixed_buffer[sizeof(expected_url)]);
+  EXPECT_EQ(static_cast<int>(expected_len),
+            FPDFLink_GetURL(pagelink, 0, fixed_buffer, expected_len));
+  EXPECT_TRUE(check_unsigned_shorts(expected_url, fixed_buffer, expected_len));
+  EXPECT_EQ(0u, fixed_buffer[expected_len - 1]);
+  EXPECT_EQ(0xbdbd, fixed_buffer[expected_len]);
 
   // Retreive link with ample-sized-buffer.
   memset(fixed_buffer, 0xbd, sizeof(fixed_buffer));
-  EXPECT_EQ(sizeof(expected_url),
+  EXPECT_EQ(static_cast<int>(expected_len),
             FPDFLink_GetURL(pagelink, 0, fixed_buffer, 128));
-  EXPECT_TRUE(
-      check_unsigned_shorts(expected_url, fixed_buffer, sizeof(expected_url)));
-  EXPECT_EQ(0u, fixed_buffer[sizeof(expected_url) - 1]);
-  EXPECT_EQ(0xbdbd, fixed_buffer[sizeof(expected_url)]);
+  EXPECT_TRUE(check_unsigned_shorts(expected_url, fixed_buffer, expected_len));
+  EXPECT_EQ(0u, fixed_buffer[expected_len - 1]);
+  EXPECT_EQ(0xbdbd, fixed_buffer[expected_len]);
 
   // Each link rendered in a single rect in this test page.
   EXPECT_EQ(1, FPDFLink_CountRects(pagelink, 0));
@@ -372,20 +373,35 @@
 TEST_F(FPDFTextEmbeddertest, GetFontSize) {
   EXPECT_TRUE(OpenDocument("hello_world.pdf"));
   FPDF_PAGE page = LoadPage(0);
-  EXPECT_NE(nullptr, page);
+  EXPECT_TRUE(page);
 
   FPDF_TEXTPAGE textpage = FPDFText_LoadPage(page);
-  EXPECT_NE(nullptr, textpage);
+  EXPECT_TRUE(textpage);
 
   const double kExpectedFontsSizes[] = {12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
                                         12, 12, 12, 1,  1,  16, 16, 16, 16, 16,
                                         16, 16, 16, 16, 16, 16, 16, 16, 16, 16};
 
   int count = FPDFText_CountChars(textpage);
-  ASSERT_EQ(FX_ArraySize(kExpectedFontsSizes), count);
+  ASSERT_EQ(FX_ArraySize(kExpectedFontsSizes), static_cast<size_t>(count));
   for (int i = 0; i < count; ++i)
     EXPECT_EQ(kExpectedFontsSizes[i], FPDFText_GetFontSize(textpage, i)) << i;
 
   FPDFText_ClosePage(textpage);
   UnloadPage(page);
 }
+
+TEST_F(FPDFTextEmbeddertest, ToUnicode) {
+  EXPECT_TRUE(OpenDocument("bug_583.pdf"));
+  FPDF_PAGE page = LoadPage(0);
+  EXPECT_TRUE(page);
+
+  FPDF_TEXTPAGE textpage = FPDFText_LoadPage(page);
+  EXPECT_TRUE(textpage);
+
+  ASSERT_EQ(1, FPDFText_CountChars(textpage));
+  EXPECT_EQ(static_cast<unsigned int>(0), FPDFText_GetUnicode(textpage, 0));
+
+  FPDFText_ClosePage(textpage);
+  UnloadPage(page);
+}
diff --git a/fpdfsdk/fpdfview.cpp b/fpdfsdk/fpdfview.cpp
new file mode 100644
index 0000000..ff4d46e
--- /dev/null
+++ b/fpdfsdk/fpdfview.cpp
@@ -0,0 +1,1243 @@
+// 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
+
+#include "public/fpdfview.h"
+
+#include <memory>
+#include <utility>
+
+#include "core/fpdfapi/cpdf_modulemgr.h"
+#include "core/fpdfapi/cpdf_pagerendercontext.h"
+#include "core/fpdfapi/page/cpdf_page.h"
+#include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/fpdf_parser_decode.h"
+#include "core/fpdfapi/render/cpdf_progressiverenderer.h"
+#include "core/fpdfapi/render/cpdf_renderoptions.h"
+#include "core/fpdfdoc/cpdf_annotlist.h"
+#include "core/fpdfdoc/cpdf_nametree.h"
+#include "core/fpdfdoc/cpdf_occontext.h"
+#include "core/fpdfdoc/cpdf_viewerpreferences.h"
+#include "core/fxcodec/fx_codec.h"
+#include "core/fxcrt/fx_memory.h"
+#include "core/fxcrt/fx_safe_types.h"
+#include "core/fxge/cfx_fxgedevice.h"
+#include "core/fxge/cfx_gemodule.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/cpdfsdk_pageview.h"
+#include "fpdfsdk/fsdk_define.h"
+#include "fpdfsdk/fsdk_pauseadapter.h"
+#include "fpdfsdk/javascript/ijs_runtime.h"
+#include "public/fpdf_ext.h"
+#include "public/fpdf_progressive.h"
+#include "third_party/base/numerics/safe_conversions_impl.h"
+#include "third_party/base/ptr_util.h"
+
+#ifdef PDF_ENABLE_XFA
+#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
+#include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
+#include "fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h"
+#include "public/fpdf_formfill.h"
+#include "xfa/fxbarcode/BC_Library.h"
+#endif  // PDF_ENABLE_XFA
+
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
+#include "core/fxge/cfx_windowsdevice.h"
+#endif
+
+namespace {
+
+// Also indicates whether library is currently initialized.
+CCodec_ModuleMgr* g_pCodecModule = nullptr;
+
+void RenderPageImpl(CPDF_PageRenderContext* pContext,
+                    CPDF_Page* pPage,
+                    const CFX_Matrix& matrix,
+                    const FX_RECT& clipping_rect,
+                    int flags,
+                    bool bNeedToRestore,
+                    IFSDK_PAUSE_Adapter* pause) {
+  if (!pContext->m_pOptions)
+    pContext->m_pOptions = pdfium::MakeUnique<CPDF_RenderOptions>();
+
+  if (flags & FPDF_LCD_TEXT)
+    pContext->m_pOptions->m_Flags |= RENDER_CLEARTYPE;
+  else
+    pContext->m_pOptions->m_Flags &= ~RENDER_CLEARTYPE;
+
+  if (flags & FPDF_NO_NATIVETEXT)
+    pContext->m_pOptions->m_Flags |= RENDER_NO_NATIVETEXT;
+  if (flags & FPDF_RENDER_LIMITEDIMAGECACHE)
+    pContext->m_pOptions->m_Flags |= RENDER_LIMITEDIMAGECACHE;
+  if (flags & FPDF_RENDER_FORCEHALFTONE)
+    pContext->m_pOptions->m_Flags |= RENDER_FORCE_HALFTONE;
+#ifndef PDF_ENABLE_XFA
+  if (flags & FPDF_RENDER_NO_SMOOTHTEXT)
+    pContext->m_pOptions->m_Flags |= RENDER_NOTEXTSMOOTH;
+  if (flags & FPDF_RENDER_NO_SMOOTHIMAGE)
+    pContext->m_pOptions->m_Flags |= RENDER_NOIMAGESMOOTH;
+  if (flags & FPDF_RENDER_NO_SMOOTHPATH)
+    pContext->m_pOptions->m_Flags |= RENDER_NOPATHSMOOTH;
+#endif  // PDF_ENABLE_XFA
+
+  // Grayscale output
+  if (flags & FPDF_GRAYSCALE) {
+    pContext->m_pOptions->m_ColorMode = RENDER_COLOR_GRAY;
+    pContext->m_pOptions->m_ForeColor = 0;
+    pContext->m_pOptions->m_BackColor = 0xffffff;
+  }
+
+  const CPDF_OCContext::UsageType usage =
+      (flags & FPDF_PRINTING) ? CPDF_OCContext::Print : CPDF_OCContext::View;
+  pContext->m_pOptions->m_AddFlags = flags >> 8;
+  pContext->m_pOptions->m_pOCContext =
+      new CPDF_OCContext(pPage->m_pDocument, usage);
+
+  pContext->m_pDevice->SaveState();
+  pContext->m_pDevice->SetClip_Rect(clipping_rect);
+
+  pContext->m_pContext = pdfium::MakeUnique<CPDF_RenderContext>(pPage);
+  pContext->m_pContext->AppendLayer(pPage, &matrix);
+
+  if (flags & FPDF_ANNOT) {
+    pContext->m_pAnnots = pdfium::MakeUnique<CPDF_AnnotList>(pPage);
+    bool bPrinting = pContext->m_pDevice->GetDeviceClass() != FXDC_DISPLAY;
+    pContext->m_pAnnots->DisplayAnnots(pPage, pContext->m_pContext.get(),
+                                       bPrinting, &matrix, false, nullptr);
+  }
+
+  pContext->m_pRenderer = pdfium::MakeUnique<CPDF_ProgressiveRenderer>(
+      pContext->m_pContext.get(), pContext->m_pDevice.get(),
+      pContext->m_pOptions.get());
+  pContext->m_pRenderer->Start(pause);
+  if (bNeedToRestore)
+    pContext->m_pDevice->RestoreState(false);
+}
+
+class CPDF_CustomAccess final : public IFX_SeekableReadStream {
+ public:
+  static CFX_RetainPtr<CPDF_CustomAccess> Create(FPDF_FILEACCESS* pFileAccess) {
+    return CFX_RetainPtr<CPDF_CustomAccess>(new CPDF_CustomAccess(pFileAccess));
+  }
+
+  // IFX_SeekableReadStream
+  FX_FILESIZE GetSize() override;
+  bool ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override;
+
+ private:
+  explicit CPDF_CustomAccess(FPDF_FILEACCESS* pFileAccess);
+
+  FPDF_FILEACCESS m_FileAccess;
+};
+
+CPDF_CustomAccess::CPDF_CustomAccess(FPDF_FILEACCESS* pFileAccess)
+    : m_FileAccess(*pFileAccess) {}
+
+FX_FILESIZE CPDF_CustomAccess::GetSize() {
+  return m_FileAccess.m_FileLen;
+}
+
+bool CPDF_CustomAccess::ReadBlock(void* buffer,
+                                  FX_FILESIZE offset,
+                                  size_t size) {
+  if (offset < 0)
+    return false;
+
+  FX_SAFE_FILESIZE newPos = pdfium::base::checked_cast<FX_FILESIZE>(size);
+  newPos += offset;
+  if (!newPos.IsValid() ||
+      newPos.ValueOrDie() > static_cast<FX_FILESIZE>(m_FileAccess.m_FileLen)) {
+    return false;
+  }
+  return !!m_FileAccess.m_GetBlock(m_FileAccess.m_Param, offset,
+                                   reinterpret_cast<uint8_t*>(buffer), size);
+}
+
+#ifdef PDF_ENABLE_XFA
+class CFPDF_FileStream : public IFX_SeekableStream {
+ public:
+  static CFX_RetainPtr<CFPDF_FileStream> Create(FPDF_FILEHANDLER* pFS) {
+    return CFX_RetainPtr<CFPDF_FileStream>(new CFPDF_FileStream(pFS));
+  }
+  ~CFPDF_FileStream() override;
+
+  // IFX_SeekableStream:
+  FX_FILESIZE GetSize() override;
+  bool IsEOF() override;
+  FX_FILESIZE GetPosition() override;
+  bool ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override;
+  size_t ReadBlock(void* buffer, size_t size) override;
+  bool WriteBlock(const void* buffer, FX_FILESIZE offset, size_t size) override;
+  bool Flush() override;
+
+  void SetPosition(FX_FILESIZE pos) { m_nCurPos = pos; }
+
+ protected:
+  explicit CFPDF_FileStream(FPDF_FILEHANDLER* pFS);
+
+  FPDF_FILEHANDLER* m_pFS;
+  FX_FILESIZE m_nCurPos;
+};
+
+CFPDF_FileStream::CFPDF_FileStream(FPDF_FILEHANDLER* pFS) {
+  m_pFS = pFS;
+  m_nCurPos = 0;
+}
+
+CFPDF_FileStream::~CFPDF_FileStream() {
+  if (m_pFS && m_pFS->Release)
+    m_pFS->Release(m_pFS->clientData);
+}
+
+FX_FILESIZE CFPDF_FileStream::GetSize() {
+  if (m_pFS && m_pFS->GetSize)
+    return (FX_FILESIZE)m_pFS->GetSize(m_pFS->clientData);
+  return 0;
+}
+
+bool CFPDF_FileStream::IsEOF() {
+  return m_nCurPos >= GetSize();
+}
+
+FX_FILESIZE CFPDF_FileStream::GetPosition() {
+  return m_nCurPos;
+}
+
+bool CFPDF_FileStream::ReadBlock(void* buffer,
+                                 FX_FILESIZE offset,
+                                 size_t size) {
+  if (!buffer || !size || !m_pFS->ReadBlock)
+    return false;
+
+  if (m_pFS->ReadBlock(m_pFS->clientData, (FPDF_DWORD)offset, buffer,
+                       (FPDF_DWORD)size) == 0) {
+    m_nCurPos = offset + size;
+    return true;
+  }
+  return false;
+}
+
+size_t CFPDF_FileStream::ReadBlock(void* buffer, size_t size) {
+  if (!buffer || !size || !m_pFS->ReadBlock)
+    return 0;
+
+  FX_FILESIZE nSize = GetSize();
+  if (m_nCurPos >= nSize)
+    return 0;
+  FX_FILESIZE dwAvail = nSize - m_nCurPos;
+  if (dwAvail < (FX_FILESIZE)size)
+    size = (size_t)dwAvail;
+  if (m_pFS->ReadBlock(m_pFS->clientData, (FPDF_DWORD)m_nCurPos, buffer,
+                       (FPDF_DWORD)size) == 0) {
+    m_nCurPos += size;
+    return size;
+  }
+
+  return 0;
+}
+
+bool CFPDF_FileStream::WriteBlock(const void* buffer,
+                                  FX_FILESIZE offset,
+                                  size_t size) {
+  if (!m_pFS || !m_pFS->WriteBlock)
+    return false;
+
+  if (m_pFS->WriteBlock(m_pFS->clientData, (FPDF_DWORD)offset, buffer,
+                        (FPDF_DWORD)size) == 0) {
+    m_nCurPos = offset + size;
+    return true;
+  }
+  return false;
+}
+
+bool CFPDF_FileStream::Flush() {
+  if (!m_pFS || !m_pFS->Flush)
+    return true;
+
+  return m_pFS->Flush(m_pFS->clientData) == 0;
+}
+#endif  // PDF_ENABLE_XFA
+
+}  // namespace
+
+UnderlyingDocumentType* UnderlyingFromFPDFDocument(FPDF_DOCUMENT doc) {
+  return static_cast<UnderlyingDocumentType*>(doc);
+}
+
+FPDF_DOCUMENT FPDFDocumentFromUnderlying(UnderlyingDocumentType* doc) {
+  return static_cast<FPDF_DOCUMENT>(doc);
+}
+
+UnderlyingPageType* UnderlyingFromFPDFPage(FPDF_PAGE page) {
+  return static_cast<UnderlyingPageType*>(page);
+}
+
+CPDF_Document* CPDFDocumentFromFPDFDocument(FPDF_DOCUMENT doc) {
+#ifdef PDF_ENABLE_XFA
+  return doc ? UnderlyingFromFPDFDocument(doc)->GetPDFDoc() : nullptr;
+#else   // PDF_ENABLE_XFA
+  return UnderlyingFromFPDFDocument(doc);
+#endif  // PDF_ENABLE_XFA
+}
+
+FPDF_DOCUMENT FPDFDocumentFromCPDFDocument(CPDF_Document* doc) {
+#ifdef PDF_ENABLE_XFA
+  return doc ? FPDFDocumentFromUnderlying(
+                   new CPDFXFA_Context(pdfium::WrapUnique(doc)))
+             : nullptr;
+#else   // PDF_ENABLE_XFA
+  return FPDFDocumentFromUnderlying(doc);
+#endif  // PDF_ENABLE_XFA
+}
+
+CPDF_Page* CPDFPageFromFPDFPage(FPDF_PAGE page) {
+#ifdef PDF_ENABLE_XFA
+  return page ? UnderlyingFromFPDFPage(page)->GetPDFPage() : nullptr;
+#else   // PDF_ENABLE_XFA
+  return UnderlyingFromFPDFPage(page);
+#endif  // PDF_ENABLE_XFA
+}
+
+CFX_DIBitmap* CFXBitmapFromFPDFBitmap(FPDF_BITMAP bitmap) {
+  return static_cast<CFX_DIBitmap*>(bitmap);
+}
+
+CFX_RetainPtr<IFX_SeekableReadStream> MakeSeekableReadStream(
+    FPDF_FILEACCESS* pFileAccess) {
+  return CPDF_CustomAccess::Create(pFileAccess);
+}
+
+#ifdef PDF_ENABLE_XFA
+CFX_RetainPtr<IFX_SeekableStream> MakeSeekableStream(
+    FPDF_FILEHANDLER* pFilehandler) {
+  return CFPDF_FileStream::Create(pFilehandler);
+}
+#endif  // PDF_ENABLE_XFA
+
+// 0 bit: FPDF_POLICY_MACHINETIME_ACCESS
+static uint32_t foxit_sandbox_policy = 0xFFFFFFFF;
+
+void FSDK_SetSandBoxPolicy(FPDF_DWORD policy, FPDF_BOOL enable) {
+  switch (policy) {
+    case FPDF_POLICY_MACHINETIME_ACCESS: {
+      if (enable)
+        foxit_sandbox_policy |= 0x01;
+      else
+        foxit_sandbox_policy &= 0xFFFFFFFE;
+    } break;
+    default:
+      break;
+  }
+}
+
+FPDF_BOOL FSDK_IsSandBoxPolicyEnabled(FPDF_DWORD policy) {
+  switch (policy) {
+    case FPDF_POLICY_MACHINETIME_ACCESS:
+      return !!(foxit_sandbox_policy & 0x01);
+    default:
+      return false;
+  }
+}
+
+DLLEXPORT void STDCALL FPDF_InitLibrary() {
+  FPDF_InitLibraryWithConfig(nullptr);
+}
+
+DLLEXPORT void STDCALL
+FPDF_InitLibraryWithConfig(const FPDF_LIBRARY_CONFIG* cfg) {
+  if (g_pCodecModule)
+    return;
+
+  g_pCodecModule = new CCodec_ModuleMgr();
+
+  CFX_GEModule* pModule = CFX_GEModule::Get();
+  pModule->Init(cfg ? cfg->m_pUserFontPaths : nullptr, g_pCodecModule);
+
+  CPDF_ModuleMgr* pModuleMgr = CPDF_ModuleMgr::Get();
+  pModuleMgr->SetCodecModule(g_pCodecModule);
+  pModuleMgr->InitPageModule();
+  pModuleMgr->LoadEmbeddedGB1CMaps();
+  pModuleMgr->LoadEmbeddedJapan1CMaps();
+  pModuleMgr->LoadEmbeddedCNS1CMaps();
+  pModuleMgr->LoadEmbeddedKorea1CMaps();
+
+#ifdef PDF_ENABLE_XFA
+  FXJSE_Initialize();
+  BC_Library_Init();
+#endif  // PDF_ENABLE_XFA
+  if (cfg && cfg->version >= 2)
+    IJS_Runtime::Initialize(cfg->m_v8EmbedderSlot, cfg->m_pIsolate);
+}
+
+DLLEXPORT void STDCALL FPDF_DestroyLibrary() {
+  if (!g_pCodecModule)
+    return;
+
+#ifdef PDF_ENABLE_XFA
+  BC_Library_Destory();
+  FXJSE_Finalize();
+#endif  // PDF_ENABLE_XFA
+
+  CPDF_ModuleMgr::Destroy();
+  CFX_GEModule::Destroy();
+
+  delete g_pCodecModule;
+  g_pCodecModule = nullptr;
+
+  IJS_Runtime::Destroy();
+}
+
+#ifndef _WIN32
+int g_LastError;
+void SetLastError(int err) {
+  g_LastError = err;
+}
+
+int GetLastError() {
+  return g_LastError;
+}
+#endif  // _WIN32
+
+void ProcessParseError(CPDF_Parser::Error err) {
+  uint32_t err_code = FPDF_ERR_SUCCESS;
+  // Translate FPDFAPI error code to FPDFVIEW error code
+  switch (err) {
+    case CPDF_Parser::SUCCESS:
+      err_code = FPDF_ERR_SUCCESS;
+      break;
+    case CPDF_Parser::FILE_ERROR:
+      err_code = FPDF_ERR_FILE;
+      break;
+    case CPDF_Parser::FORMAT_ERROR:
+      err_code = FPDF_ERR_FORMAT;
+      break;
+    case CPDF_Parser::PASSWORD_ERROR:
+      err_code = FPDF_ERR_PASSWORD;
+      break;
+    case CPDF_Parser::HANDLER_ERROR:
+      err_code = FPDF_ERR_SECURITY;
+      break;
+  }
+  SetLastError(err_code);
+}
+
+DLLEXPORT void STDCALL FPDF_SetSandBoxPolicy(FPDF_DWORD policy,
+                                             FPDF_BOOL enable) {
+  return FSDK_SetSandBoxPolicy(policy, enable);
+}
+
+#if defined(_WIN32)
+#if defined(PDFIUM_PRINT_TEXT_WITH_GDI)
+DLLEXPORT void STDCALL
+FPDF_SetTypefaceAccessibleFunc(PDFiumEnsureTypefaceCharactersAccessible func) {
+  g_pdfium_typeface_accessible_func = func;
+}
+
+DLLEXPORT void STDCALL FPDF_SetPrintTextWithGDI(FPDF_BOOL use_gdi) {
+  g_pdfium_print_text_with_gdi = !!use_gdi;
+}
+#endif  // PDFIUM_PRINT_TEXT_WITH_GDI
+
+DLLEXPORT FPDF_BOOL STDCALL FPDF_SetPrintPostscriptLevel(int postscript_level) {
+  if (postscript_level != 0 && postscript_level != 2 && postscript_level != 3)
+    return FALSE;
+  g_pdfium_print_postscript_level = postscript_level;
+  return TRUE;
+}
+#endif  // defined(_WIN32)
+
+DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_LoadDocument(FPDF_STRING file_path,
+                                                  FPDF_BYTESTRING password) {
+  // NOTE: the creation of the file needs to be by the embedder on the
+  // other side of this API.
+  CFX_RetainPtr<IFX_SeekableReadStream> pFileAccess =
+      IFX_SeekableReadStream::CreateFromFilename((const FX_CHAR*)file_path);
+  if (!pFileAccess)
+    return nullptr;
+
+  auto pParser = pdfium::MakeUnique<CPDF_Parser>();
+  pParser->SetPassword(password);
+
+  auto pDocument = pdfium::MakeUnique<CPDF_Document>(std::move(pParser));
+  CPDF_Parser::Error error =
+      pDocument->GetParser()->StartParse(pFileAccess, pDocument.get());
+  if (error != CPDF_Parser::SUCCESS) {
+    ProcessParseError(error);
+    return nullptr;
+  }
+  return FPDFDocumentFromCPDFDocument(pDocument.release());
+}
+
+#ifdef PDF_ENABLE_XFA
+DLLEXPORT FPDF_BOOL STDCALL FPDF_HasXFAField(FPDF_DOCUMENT document,
+                                             int* docType) {
+  if (!document)
+    return false;
+
+  CPDF_Document* pdfDoc =
+      (static_cast<CPDFXFA_Context*>(document))->GetPDFDoc();
+  if (!pdfDoc)
+    return false;
+
+  CPDF_Dictionary* pRoot = pdfDoc->GetRoot();
+  if (!pRoot)
+    return false;
+
+  CPDF_Dictionary* pAcroForm = pRoot->GetDictFor("AcroForm");
+  if (!pAcroForm)
+    return false;
+
+  CPDF_Object* pXFA = pAcroForm->GetObjectFor("XFA");
+  if (!pXFA)
+    return false;
+
+  bool bDynamicXFA = pRoot->GetBooleanFor("NeedsRendering", false);
+  *docType = bDynamicXFA ? DOCTYPE_DYNAMIC_XFA : DOCTYPE_STATIC_XFA;
+  return true;
+}
+
+DLLEXPORT FPDF_BOOL STDCALL FPDF_LoadXFA(FPDF_DOCUMENT document) {
+  return document && (static_cast<CPDFXFA_Context*>(document))->LoadXFADoc();
+}
+#endif  // PDF_ENABLE_XFA
+
+class CMemFile final : public IFX_SeekableReadStream {
+ public:
+  static CFX_RetainPtr<CMemFile> Create(uint8_t* pBuf, FX_FILESIZE size) {
+    return CFX_RetainPtr<CMemFile>(new CMemFile(pBuf, size));
+  }
+
+  FX_FILESIZE GetSize() override { return m_size; }
+  bool ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override {
+    if (offset < 0)
+      return false;
+
+    FX_SAFE_FILESIZE newPos = pdfium::base::checked_cast<FX_FILESIZE>(size);
+    newPos += offset;
+    if (!newPos.IsValid() || newPos.ValueOrDie() > m_size)
+      return false;
+
+    FXSYS_memcpy(buffer, m_pBuf + offset, size);
+    return true;
+  }
+
+ private:
+  CMemFile(uint8_t* pBuf, FX_FILESIZE size) : m_pBuf(pBuf), m_size(size) {}
+
+  uint8_t* const m_pBuf;
+  const FX_FILESIZE m_size;
+};
+
+DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_LoadMemDocument(const void* data_buf,
+                                                     int size,
+                                                     FPDF_BYTESTRING password) {
+  CFX_RetainPtr<CMemFile> pMemFile = CMemFile::Create((uint8_t*)data_buf, size);
+  auto pParser = pdfium::MakeUnique<CPDF_Parser>();
+  pParser->SetPassword(password);
+
+  auto pDocument = pdfium::MakeUnique<CPDF_Document>(std::move(pParser));
+  CPDF_Parser::Error error =
+      pDocument->GetParser()->StartParse(pMemFile, pDocument.get());
+  if (error != CPDF_Parser::SUCCESS) {
+    ProcessParseError(error);
+    return nullptr;
+  }
+  CheckUnSupportError(pDocument.get(), error);
+  return FPDFDocumentFromCPDFDocument(pDocument.release());
+}
+
+DLLEXPORT FPDF_DOCUMENT STDCALL
+FPDF_LoadCustomDocument(FPDF_FILEACCESS* pFileAccess,
+                        FPDF_BYTESTRING password) {
+  CFX_RetainPtr<CPDF_CustomAccess> pFile =
+      CPDF_CustomAccess::Create(pFileAccess);
+  auto pParser = pdfium::MakeUnique<CPDF_Parser>();
+  pParser->SetPassword(password);
+
+  auto pDocument = pdfium::MakeUnique<CPDF_Document>(std::move(pParser));
+  CPDF_Parser::Error error =
+      pDocument->GetParser()->StartParse(pFile, pDocument.get());
+  if (error != CPDF_Parser::SUCCESS) {
+    ProcessParseError(error);
+    return nullptr;
+  }
+  CheckUnSupportError(pDocument.get(), error);
+  return FPDFDocumentFromCPDFDocument(pDocument.release());
+}
+
+DLLEXPORT FPDF_BOOL STDCALL FPDF_GetFileVersion(FPDF_DOCUMENT doc,
+                                                int* fileVersion) {
+  if (!fileVersion)
+    return false;
+
+  *fileVersion = 0;
+  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(doc);
+  if (!pDoc)
+    return false;
+
+  CPDF_Parser* pParser = pDoc->GetParser();
+  if (!pParser)
+    return false;
+
+  *fileVersion = pParser->GetFileVersion();
+  return true;
+}
+
+// jabdelmalek: changed return type from uint32_t to build on Linux (and match
+// header).
+DLLEXPORT unsigned long STDCALL FPDF_GetDocPermissions(FPDF_DOCUMENT document) {
+  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
+  // https://bugs.chromium.org/p/pdfium/issues/detail?id=499
+  if (!pDoc) {
+#ifndef PDF_ENABLE_XFA
+    return 0;
+#else   // PDF_ENABLE_XFA
+    return 0xFFFFFFFF;
+#endif  // PDF_ENABLE_XFA
+  }
+
+  return pDoc->GetUserPermissions();
+}
+
+DLLEXPORT int STDCALL FPDF_GetSecurityHandlerRevision(FPDF_DOCUMENT document) {
+  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
+  if (!pDoc || !pDoc->GetParser())
+    return -1;
+
+  CPDF_Dictionary* pDict = pDoc->GetParser()->GetEncryptDict();
+  return pDict ? pDict->GetIntegerFor("R") : -1;
+}
+
+DLLEXPORT int STDCALL FPDF_GetPageCount(FPDF_DOCUMENT document) {
+  UnderlyingDocumentType* pDoc = UnderlyingFromFPDFDocument(document);
+  return pDoc ? pDoc->GetPageCount() : 0;
+}
+
+DLLEXPORT FPDF_PAGE STDCALL FPDF_LoadPage(FPDF_DOCUMENT document,
+                                          int page_index) {
+  UnderlyingDocumentType* pDoc = UnderlyingFromFPDFDocument(document);
+  if (!pDoc)
+    return nullptr;
+
+  if (page_index < 0 || page_index >= pDoc->GetPageCount())
+    return nullptr;
+
+#ifdef PDF_ENABLE_XFA
+  return pDoc->GetXFAPage(page_index);
+#else   // PDF_ENABLE_XFA
+  CPDF_Dictionary* pDict = pDoc->GetPage(page_index);
+  if (!pDict)
+    return nullptr;
+
+  CPDF_Page* pPage = new CPDF_Page(pDoc, pDict, true);
+  pPage->ParseContent();
+  return pPage;
+#endif  // PDF_ENABLE_XFA
+}
+
+DLLEXPORT double STDCALL FPDF_GetPageWidth(FPDF_PAGE page) {
+  UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
+  return pPage ? pPage->GetPageWidth() : 0.0;
+}
+
+DLLEXPORT double STDCALL FPDF_GetPageHeight(FPDF_PAGE page) {
+  UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
+  return pPage ? pPage->GetPageHeight() : 0.0;
+}
+
+#if defined(_WIN32)
+DLLEXPORT void STDCALL FPDF_RenderPage(HDC dc,
+                                       FPDF_PAGE page,
+                                       int start_x,
+                                       int start_y,
+                                       int size_x,
+                                       int size_y,
+                                       int rotate,
+                                       int flags) {
+  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
+  if (!pPage)
+    return;
+
+  CPDF_PageRenderContext* pContext = new CPDF_PageRenderContext;
+  pPage->SetRenderContext(pdfium::WrapUnique(pContext));
+
+  std::unique_ptr<CFX_DIBitmap> pBitmap;
+  // TODO: This results in unnecessary rasterization of some PDFs due to
+  // HasImageMask() returning true. If any image on the page is a mask, the
+  // entire page gets rasterized and the spool size gets huge.
+  const bool bNewBitmap =
+      pPage->BackgroundAlphaNeeded() || pPage->HasImageMask();
+  if (bNewBitmap) {
+    pBitmap = pdfium::MakeUnique<CFX_DIBitmap>();
+    pBitmap->Create(size_x, size_y, FXDIB_Argb);
+    pBitmap->Clear(0x00ffffff);
+    CFX_FxgeDevice* pDevice = new CFX_FxgeDevice;
+    pContext->m_pDevice = pdfium::WrapUnique(pDevice);
+    pDevice->Attach(pBitmap.get(), false, nullptr, false);
+  } else {
+    pContext->m_pDevice = pdfium::MakeUnique<CFX_WindowsDevice>(dc);
+  }
+
+  FPDF_RenderPage_Retail(pContext, page, start_x, start_y, size_x, size_y,
+                         rotate, flags, true, nullptr);
+
+  if (bNewBitmap) {
+    CFX_WindowsDevice WinDC(dc);
+    if (WinDC.GetDeviceCaps(FXDC_DEVICE_CLASS) == FXDC_PRINTER) {
+      std::unique_ptr<CFX_DIBitmap> pDst = pdfium::MakeUnique<CFX_DIBitmap>();
+      int pitch = pBitmap->GetPitch();
+      pDst->Create(size_x, size_y, FXDIB_Rgb32);
+      FXSYS_memset(pDst->GetBuffer(), -1, pitch * size_y);
+      pDst->CompositeBitmap(0, 0, size_x, size_y, pBitmap.get(), 0, 0,
+                            FXDIB_BLEND_NORMAL, nullptr, false, nullptr);
+      WinDC.StretchDIBits(pDst.get(), 0, 0, size_x, size_y);
+    } else {
+      WinDC.SetDIBits(pBitmap.get(), 0, 0);
+    }
+  }
+
+  pPage->SetRenderContext(nullptr);
+}
+#endif  // defined(_WIN32)
+
+DLLEXPORT void STDCALL FPDF_RenderPageBitmap(FPDF_BITMAP bitmap,
+                                             FPDF_PAGE page,
+                                             int start_x,
+                                             int start_y,
+                                             int size_x,
+                                             int size_y,
+                                             int rotate,
+                                             int flags) {
+  if (!bitmap)
+    return;
+
+  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
+  if (!pPage)
+    return;
+
+  CPDF_PageRenderContext* pContext = new CPDF_PageRenderContext;
+  pPage->SetRenderContext(pdfium::WrapUnique(pContext));
+  CFX_FxgeDevice* pDevice = new CFX_FxgeDevice;
+  pContext->m_pDevice.reset(pDevice);
+  CFX_DIBitmap* pBitmap = CFXBitmapFromFPDFBitmap(bitmap);
+  pDevice->Attach(pBitmap, !!(flags & FPDF_REVERSE_BYTE_ORDER), nullptr, false);
+
+  FPDF_RenderPage_Retail(pContext, page, start_x, start_y, size_x, size_y,
+                         rotate, flags, true, nullptr);
+
+#ifdef _SKIA_SUPPORT_PATHS_
+  pDevice->Flush();
+  pBitmap->UnPreMultiply();
+#endif
+  pPage->SetRenderContext(nullptr);
+}
+
+DLLEXPORT void STDCALL FPDF_RenderPageBitmapWithMatrix(FPDF_BITMAP bitmap,
+                                                       FPDF_PAGE page,
+                                                       const FS_MATRIX* matrix,
+                                                       const FS_RECTF* clipping,
+                                                       int flags) {
+  if (!bitmap)
+    return;
+
+  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
+  if (!pPage)
+    return;
+
+  CPDF_PageRenderContext* pContext = new CPDF_PageRenderContext;
+  pPage->SetRenderContext(pdfium::WrapUnique(pContext));
+  CFX_FxgeDevice* pDevice = new CFX_FxgeDevice;
+  pContext->m_pDevice.reset(pDevice);
+  CFX_DIBitmap* pBitmap = CFXBitmapFromFPDFBitmap(bitmap);
+  pDevice->Attach(pBitmap, !!(flags & FPDF_REVERSE_BYTE_ORDER), nullptr, false);
+
+  CFX_Matrix transform_matrix = pPage->GetPageMatrix();
+  if (matrix) {
+    CFX_Matrix cmatrix;
+    cmatrix.a = matrix->a;
+    cmatrix.b = matrix->b;
+    cmatrix.c = matrix->c;
+    cmatrix.d = matrix->d;
+    cmatrix.e = matrix->e;
+    cmatrix.f = matrix->f;
+    transform_matrix.Concat(cmatrix);
+  }
+
+  CFX_FloatRect clipping_rect;
+  if (clipping) {
+    clipping_rect.left = clipping->left;
+    clipping_rect.bottom = clipping->bottom;
+    clipping_rect.right = clipping->right;
+    clipping_rect.top = clipping->top;
+  }
+  RenderPageImpl(pContext, pPage, transform_matrix, clipping_rect.ToFxRect(),
+                 flags, true, nullptr);
+
+  pPage->SetRenderContext(nullptr);
+}
+
+#ifdef _SKIA_SUPPORT_
+DLLEXPORT FPDF_RECORDER STDCALL FPDF_RenderPageSkp(FPDF_PAGE page,
+                                                   int size_x,
+                                                   int size_y) {
+  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
+  if (!pPage)
+    return nullptr;
+
+  CPDF_PageRenderContext* pContext = new CPDF_PageRenderContext;
+  pPage->SetRenderContext(pdfium::WrapUnique(pContext));
+  CFX_FxgeDevice* skDevice = new CFX_FxgeDevice;
+  FPDF_RECORDER recorder = skDevice->CreateRecorder(size_x, size_y);
+  pContext->m_pDevice.reset(skDevice);
+  FPDF_RenderPage_Retail(pContext, page, 0, 0, size_x, size_y, 0, 0, true,
+                         nullptr);
+  pPage->SetRenderContext(nullptr);
+  return recorder;
+}
+#endif
+
+DLLEXPORT void STDCALL FPDF_ClosePage(FPDF_PAGE page) {
+  UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
+  if (!page)
+    return;
+#ifdef PDF_ENABLE_XFA
+  pPage->Release();
+#else   // PDF_ENABLE_XFA
+  CPDFSDK_PageView* pPageView =
+      static_cast<CPDFSDK_PageView*>(pPage->GetView());
+  if (pPageView) {
+    // We're already destroying the pageview, so bail early.
+    if (pPageView->IsBeingDestroyed())
+      return;
+
+    if (pPageView->IsLocked()) {
+      pPageView->TakePageOwnership();
+      return;
+    }
+
+    bool owned = pPageView->OwnsPage();
+    // This will delete the |pPageView| object. We must cleanup the PageView
+    // first because it will attempt to reset the View on the |pPage| during
+    // destruction.
+    pPageView->GetFormFillEnv()->RemovePageView(pPage);
+    // If the page was owned then the pageview will have deleted the page.
+    if (owned)
+      return;
+  }
+  delete pPage;
+#endif  // PDF_ENABLE_XFA
+}
+
+DLLEXPORT void STDCALL FPDF_CloseDocument(FPDF_DOCUMENT document) {
+  delete UnderlyingFromFPDFDocument(document);
+}
+
+DLLEXPORT unsigned long STDCALL FPDF_GetLastError() {
+  return GetLastError();
+}
+
+DLLEXPORT void STDCALL FPDF_DeviceToPage(FPDF_PAGE page,
+                                         int start_x,
+                                         int start_y,
+                                         int size_x,
+                                         int size_y,
+                                         int rotate,
+                                         int device_x,
+                                         int device_y,
+                                         double* page_x,
+                                         double* page_y) {
+  if (!page || !page_x || !page_y)
+    return;
+  UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
+#ifdef PDF_ENABLE_XFA
+  pPage->DeviceToPage(start_x, start_y, size_x, size_y, rotate, device_x,
+                      device_y, page_x, page_y);
+#else   // PDF_ENABLE_XFA
+  CFX_Matrix page2device;
+  pPage->GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y,
+                          rotate);
+  CFX_Matrix device2page;
+  device2page.SetReverse(page2device);
+  FX_FLOAT page_x_f, page_y_f;
+  device2page.Transform((FX_FLOAT)(device_x), (FX_FLOAT)(device_y), page_x_f,
+                        page_y_f);
+  *page_x = (page_x_f);
+  *page_y = (page_y_f);
+#endif  // PDF_ENABLE_XFA
+}
+
+DLLEXPORT void STDCALL FPDF_PageToDevice(FPDF_PAGE page,
+                                         int start_x,
+                                         int start_y,
+                                         int size_x,
+                                         int size_y,
+                                         int rotate,
+                                         double page_x,
+                                         double page_y,
+                                         int* device_x,
+                                         int* device_y) {
+  if (!device_x || !device_y)
+    return;
+  UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
+  if (!pPage)
+    return;
+#ifdef PDF_ENABLE_XFA
+  pPage->PageToDevice(start_x, start_y, size_x, size_y, rotate, page_x, page_y,
+                      device_x, device_y);
+#else   // PDF_ENABLE_XFA
+  CFX_Matrix page2device;
+  pPage->GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y,
+                          rotate);
+  FX_FLOAT device_x_f, device_y_f;
+  page2device.Transform(((FX_FLOAT)page_x), ((FX_FLOAT)page_y), device_x_f,
+                        device_y_f);
+  *device_x = FXSYS_round(device_x_f);
+  *device_y = FXSYS_round(device_y_f);
+#endif  // PDF_ENABLE_XFA
+}
+
+DLLEXPORT FPDF_BITMAP STDCALL FPDFBitmap_Create(int width,
+                                                int height,
+                                                int alpha) {
+  auto pBitmap = pdfium::MakeUnique<CFX_DIBitmap>();
+  if (!pBitmap->Create(width, height, alpha ? FXDIB_Argb : FXDIB_Rgb32))
+    return nullptr;
+
+  return pBitmap.release();
+}
+
+DLLEXPORT FPDF_BITMAP STDCALL FPDFBitmap_CreateEx(int width,
+                                                  int height,
+                                                  int format,
+                                                  void* first_scan,
+                                                  int stride) {
+  FXDIB_Format fx_format;
+  switch (format) {
+    case FPDFBitmap_Gray:
+      fx_format = FXDIB_8bppRgb;
+      break;
+    case FPDFBitmap_BGR:
+      fx_format = FXDIB_Rgb;
+      break;
+    case FPDFBitmap_BGRx:
+      fx_format = FXDIB_Rgb32;
+      break;
+    case FPDFBitmap_BGRA:
+      fx_format = FXDIB_Argb;
+      break;
+    default:
+      return nullptr;
+  }
+  CFX_DIBitmap* pBitmap = new CFX_DIBitmap;
+  pBitmap->Create(width, height, fx_format, (uint8_t*)first_scan, stride);
+  return pBitmap;
+}
+
+DLLEXPORT void STDCALL FPDFBitmap_FillRect(FPDF_BITMAP bitmap,
+                                           int left,
+                                           int top,
+                                           int width,
+                                           int height,
+                                           FPDF_DWORD color) {
+  if (!bitmap)
+    return;
+
+  CFX_FxgeDevice device;
+  CFX_DIBitmap* pBitmap = CFXBitmapFromFPDFBitmap(bitmap);
+  device.Attach(pBitmap, false, nullptr, false);
+  if (!pBitmap->HasAlpha())
+    color |= 0xFF000000;
+  FX_RECT rect(left, top, left + width, top + height);
+  device.FillRect(&rect, color);
+}
+
+DLLEXPORT void* STDCALL FPDFBitmap_GetBuffer(FPDF_BITMAP bitmap) {
+  return bitmap ? CFXBitmapFromFPDFBitmap(bitmap)->GetBuffer() : nullptr;
+}
+
+DLLEXPORT int STDCALL FPDFBitmap_GetWidth(FPDF_BITMAP bitmap) {
+  return bitmap ? CFXBitmapFromFPDFBitmap(bitmap)->GetWidth() : 0;
+}
+
+DLLEXPORT int STDCALL FPDFBitmap_GetHeight(FPDF_BITMAP bitmap) {
+  return bitmap ? CFXBitmapFromFPDFBitmap(bitmap)->GetHeight() : 0;
+}
+
+DLLEXPORT int STDCALL FPDFBitmap_GetStride(FPDF_BITMAP bitmap) {
+  return bitmap ? CFXBitmapFromFPDFBitmap(bitmap)->GetPitch() : 0;
+}
+
+DLLEXPORT void STDCALL FPDFBitmap_Destroy(FPDF_BITMAP bitmap) {
+  delete CFXBitmapFromFPDFBitmap(bitmap);
+}
+
+void FPDF_RenderPage_Retail(CPDF_PageRenderContext* pContext,
+                            FPDF_PAGE page,
+                            int start_x,
+                            int start_y,
+                            int size_x,
+                            int size_y,
+                            int rotate,
+                            int flags,
+                            bool bNeedToRestore,
+                            IFSDK_PAUSE_Adapter* pause) {
+  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
+  if (!pPage)
+    return;
+
+  CFX_Matrix matrix;
+  pPage->GetDisplayMatrix(matrix, start_x, start_y, size_x, size_y, rotate);
+  FX_RECT rect(start_x, start_y, start_x + size_x, start_y + size_y);
+  RenderPageImpl(pContext, pPage, matrix, rect, flags, bNeedToRestore, pause);
+}
+
+DLLEXPORT int STDCALL FPDF_GetPageSizeByIndex(FPDF_DOCUMENT document,
+                                              int page_index,
+                                              double* width,
+                                              double* height) {
+  UnderlyingDocumentType* pDoc = UnderlyingFromFPDFDocument(document);
+  if (!pDoc)
+    return false;
+
+#ifdef PDF_ENABLE_XFA
+  int count = pDoc->GetPageCount();
+  if (page_index < 0 || page_index >= count)
+    return false;
+  CPDFXFA_Page* pPage = pDoc->GetXFAPage(page_index);
+  if (!pPage)
+    return false;
+  *width = pPage->GetPageWidth();
+  *height = pPage->GetPageHeight();
+#else   // PDF_ENABLE_XFA
+  CPDF_Dictionary* pDict = pDoc->GetPage(page_index);
+  if (!pDict)
+    return false;
+
+  CPDF_Page page(pDoc, pDict, true);
+  *width = page.GetPageWidth();
+  *height = page.GetPageHeight();
+#endif  // PDF_ENABLE_XFA
+
+  return true;
+}
+
+DLLEXPORT FPDF_BOOL STDCALL
+FPDF_VIEWERREF_GetPrintScaling(FPDF_DOCUMENT document) {
+  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
+  if (!pDoc)
+    return true;
+  CPDF_ViewerPreferences viewRef(pDoc);
+  return viewRef.PrintScaling();
+}
+
+DLLEXPORT int STDCALL FPDF_VIEWERREF_GetNumCopies(FPDF_DOCUMENT document) {
+  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
+  if (!pDoc)
+    return 1;
+  CPDF_ViewerPreferences viewRef(pDoc);
+  return viewRef.NumCopies();
+}
+
+DLLEXPORT FPDF_PAGERANGE STDCALL
+FPDF_VIEWERREF_GetPrintPageRange(FPDF_DOCUMENT document) {
+  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
+  if (!pDoc)
+    return nullptr;
+  CPDF_ViewerPreferences viewRef(pDoc);
+  return viewRef.PrintPageRange();
+}
+
+DLLEXPORT FPDF_DUPLEXTYPE STDCALL
+FPDF_VIEWERREF_GetDuplex(FPDF_DOCUMENT document) {
+  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
+  if (!pDoc)
+    return DuplexUndefined;
+  CPDF_ViewerPreferences viewRef(pDoc);
+  CFX_ByteString duplex = viewRef.Duplex();
+  if ("Simplex" == duplex)
+    return Simplex;
+  if ("DuplexFlipShortEdge" == duplex)
+    return DuplexFlipShortEdge;
+  if ("DuplexFlipLongEdge" == duplex)
+    return DuplexFlipLongEdge;
+  return DuplexUndefined;
+}
+
+DLLEXPORT unsigned long STDCALL FPDF_VIEWERREF_GetName(FPDF_DOCUMENT document,
+                                                       FPDF_BYTESTRING key,
+                                                       char* buffer,
+                                                       unsigned long length) {
+  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
+  if (!pDoc)
+    return 0;
+
+  CPDF_ViewerPreferences viewRef(pDoc);
+  CFX_ByteString bsVal;
+  if (!viewRef.GenericName(key, &bsVal))
+    return 0;
+
+  unsigned long dwStringLen = bsVal.GetLength() + 1;
+  if (buffer && length >= dwStringLen)
+    memcpy(buffer, bsVal.c_str(), dwStringLen);
+  return dwStringLen;
+}
+
+DLLEXPORT FPDF_DWORD STDCALL FPDF_CountNamedDests(FPDF_DOCUMENT document) {
+  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
+  if (!pDoc)
+    return 0;
+
+  CPDF_Dictionary* pRoot = pDoc->GetRoot();
+  if (!pRoot)
+    return 0;
+
+  CPDF_NameTree nameTree(pDoc, "Dests");
+  pdfium::base::CheckedNumeric<FPDF_DWORD> count = nameTree.GetCount();
+  CPDF_Dictionary* pDest = pRoot->GetDictFor("Dests");
+  if (pDest)
+    count += pDest->GetCount();
+
+  if (!count.IsValid())
+    return 0;
+
+  return count.ValueOrDie();
+}
+
+DLLEXPORT FPDF_DEST STDCALL FPDF_GetNamedDestByName(FPDF_DOCUMENT document,
+                                                    FPDF_BYTESTRING name) {
+  if (!name || name[0] == 0)
+    return nullptr;
+
+  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
+  if (!pDoc)
+    return nullptr;
+
+  CPDF_NameTree name_tree(pDoc, "Dests");
+  return name_tree.LookupNamedDest(pDoc, name);
+}
+
+#ifdef PDF_ENABLE_XFA
+DLLEXPORT FPDF_RESULT STDCALL FPDF_BStr_Init(FPDF_BSTR* str) {
+  if (!str)
+    return -1;
+
+  FXSYS_memset(str, 0, sizeof(FPDF_BSTR));
+  return 0;
+}
+
+DLLEXPORT FPDF_RESULT STDCALL FPDF_BStr_Set(FPDF_BSTR* str,
+                                            FPDF_LPCSTR bstr,
+                                            int length) {
+  if (!str)
+    return -1;
+  if (!bstr || !length)
+    return -1;
+  if (length == -1)
+    length = FXSYS_strlen(bstr);
+
+  if (length == 0) {
+    if (str->str) {
+      FX_Free(str->str);
+      str->str = nullptr;
+    }
+    str->len = 0;
+    return 0;
+  }
+
+  if (str->str && str->len < length)
+    str->str = FX_Realloc(char, str->str, length + 1);
+  else if (!str->str)
+    str->str = FX_Alloc(char, length + 1);
+
+  str->str[length] = 0;
+  FXSYS_memcpy(str->str, bstr, length);
+  str->len = length;
+
+  return 0;
+}
+
+DLLEXPORT FPDF_RESULT STDCALL FPDF_BStr_Clear(FPDF_BSTR* str) {
+  if (!str)
+    return -1;
+
+  if (str->str) {
+    FX_Free(str->str);
+    str->str = nullptr;
+  }
+  str->len = 0;
+  return 0;
+}
+#endif  // PDF_ENABLE_XFA
+
+DLLEXPORT FPDF_DEST STDCALL FPDF_GetNamedDest(FPDF_DOCUMENT document,
+                                              int index,
+                                              void* buffer,
+                                              long* buflen) {
+  if (!buffer)
+    *buflen = 0;
+
+  if (index < 0)
+    return nullptr;
+
+  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
+  if (!pDoc)
+    return nullptr;
+
+  CPDF_Dictionary* pRoot = pDoc->GetRoot();
+  if (!pRoot)
+    return nullptr;
+
+  CPDF_Object* pDestObj = nullptr;
+  CFX_ByteString bsName;
+  CPDF_NameTree nameTree(pDoc, "Dests");
+  int count = nameTree.GetCount();
+  if (index >= count) {
+    CPDF_Dictionary* pDest = pRoot->GetDictFor("Dests");
+    if (!pDest)
+      return nullptr;
+
+    pdfium::base::CheckedNumeric<int> checked_count = count;
+    checked_count += pDest->GetCount();
+    if (!checked_count.IsValid() || index >= checked_count.ValueOrDie())
+      return nullptr;
+
+    index -= count;
+    int i = 0;
+    for (const auto& it : *pDest) {
+      bsName = it.first;
+      pDestObj = it.second.get();
+      if (!pDestObj)
+        continue;
+      if (i == index)
+        break;
+      i++;
+    }
+  } else {
+    pDestObj = nameTree.LookupValue(index, bsName);
+  }
+  if (!pDestObj)
+    return nullptr;
+  if (CPDF_Dictionary* pDict = pDestObj->AsDictionary()) {
+    pDestObj = pDict->GetArrayFor("D");
+    if (!pDestObj)
+      return nullptr;
+  }
+  if (!pDestObj->IsArray())
+    return nullptr;
+
+  CFX_WideString wsName = PDF_DecodeText(bsName);
+  CFX_ByteString utf16Name = wsName.UTF16LE_Encode();
+  int len = utf16Name.GetLength();
+  if (!buffer) {
+    *buflen = len;
+  } else if (len <= *buflen) {
+    memcpy(buffer, utf16Name.c_str(), len);
+    *buflen = len;
+  } else {
+    *buflen = -1;
+  }
+  return (FPDF_DEST)pDestObj;
+}
diff --git a/fpdfsdk/src/fpdfview_c_api_test.c b/fpdfsdk/fpdfview_c_api_test.c
similarity index 92%
rename from fpdfsdk/src/fpdfview_c_api_test.c
rename to fpdfsdk/fpdfview_c_api_test.c
index fdf83be..98478f0 100644
--- a/fpdfsdk/src/fpdfview_c_api_test.c
+++ b/fpdfsdk/fpdfview_c_api_test.c
@@ -7,7 +7,7 @@
 
 #include <stdio.h>
 
-#include "fpdfview_c_api_test.h"
+#include "fpdfsdk/fpdfview_c_api_test.h"
 
 #include "public/fpdf_dataavail.h"
 #include "public/fpdf_doc.h"
@@ -20,6 +20,7 @@
 #include "public/fpdf_progressive.h"
 #include "public/fpdf_save.h"
 #include "public/fpdf_searchex.h"
+#include "public/fpdf_structtree.h"
 #include "public/fpdf_sysfontinfo.h"
 #include "public/fpdf_text.h"
 #include "public/fpdf_transformpage.h"
@@ -54,6 +55,7 @@
     CHK(FPDFAction_GetFilePath);
     CHK(FPDFAction_GetURIPath);
     CHK(FPDFDest_GetPageIndex);
+    CHK(FPDFDest_GetLocationInPage);
     CHK(FPDFLink_GetLinkAtPoint);
     CHK(FPDFLink_GetLinkZOrderAtPoint);
     CHK(FPDFLink_GetDest);
@@ -63,6 +65,7 @@
     CHK(FPDFLink_CountQuadPoints);
     CHK(FPDFLink_GetQuadPoints);
     CHK(FPDF_GetMetaText);
+    CHK(FPDF_GetPageLabel);
 
     // fpdf_edit.h
     CHK(FPDF_CreateNewDocument);
@@ -152,11 +155,21 @@
     // fpdf_searchex.h
     CHK(FPDFText_GetCharIndexFromTextIndex);
 
+    // fpdf_structtree.h
+    CHK(FPDF_StructTree_GetForPage);
+    CHK(FPDF_StructTree_Close);
+    CHK(FPDF_StructTree_CountChildren);
+    CHK(FPDF_StructTree_GetChildAtIndex);
+    CHK(FPDF_StructElement_GetAltText);
+    CHK(FPDF_StructElement_CountChildren);
+    CHK(FPDF_StructElement_GetChildAtIndex);
+
     // fpdf_sysfontinfo.h
     CHK(FPDF_GetDefaultTTFMap);
     CHK(FPDF_AddInstalledFont);
     CHK(FPDF_SetSystemFontInfo);
     CHK(FPDF_GetDefaultSystemFontInfo);
+    CHK(FPDF_FreeDefaultSystemFontInfo);
 
     // fpdf_text.h
     CHK(FPDFText_LoadPage);
@@ -212,6 +225,7 @@
     CHK(FPDF_GetPageHeight);
     CHK(FPDF_GetPageSizeByIndex);
     CHK(FPDF_RenderPageBitmap);
+    CHK(FPDF_RenderPageBitmapWithMatrix);
     CHK(FPDF_ClosePage);
     CHK(FPDF_CloseDocument);
     CHK(FPDF_DeviceToPage);
@@ -228,6 +242,7 @@
     CHK(FPDF_VIEWERREF_GetNumCopies);
     CHK(FPDF_VIEWERREF_GetPrintPageRange);
     CHK(FPDF_VIEWERREF_GetDuplex);
+    CHK(FPDF_VIEWERREF_GetName);
     CHK(FPDF_CountNamedDests);
     CHK(FPDF_GetNamedDestByName);
     CHK(FPDF_GetNamedDest);
diff --git a/fpdfsdk/src/fpdfview_c_api_test.h b/fpdfsdk/fpdfview_c_api_test.h
similarity index 73%
rename from fpdfsdk/src/fpdfview_c_api_test.h
rename to fpdfsdk/fpdfview_c_api_test.h
index 755d821..d5b84a2 100644
--- a/fpdfsdk/src/fpdfview_c_api_test.h
+++ b/fpdfsdk/fpdfview_c_api_test.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef FPDFSDK_SRC_FPDFVIEW_C_API_TEST_H_
-#define FPDFSDK_SRC_FPDFVIEW_C_API_TEST_H_
+#ifndef FPDFSDK_FPDFVIEW_C_API_TEST_H_
+#define FPDFSDK_FPDFVIEW_C_API_TEST_H_
 
 #ifdef __cplusplus
 extern "C" {
@@ -17,4 +17,4 @@
 }
 #endif
 
-#endif  // FPDFSDK_SRC_FPDFVIEW_C_API_TEST_H_
+#endif  // FPDFSDK_FPDFVIEW_C_API_TEST_H_
diff --git a/fpdfsdk/fpdfview_embeddertest.cpp b/fpdfsdk/fpdfview_embeddertest.cpp
new file mode 100644
index 0000000..1d94b72
--- /dev/null
+++ b/fpdfsdk/fpdfview_embeddertest.cpp
@@ -0,0 +1,380 @@
+// Copyright 2015 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.
+
+#include <limits>
+#include <string>
+
+#include "fpdfsdk/fpdfview_c_api_test.h"
+#include "public/fpdfview.h"
+#include "testing/embedder_test.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+TEST(fpdf, CApiTest) {
+  EXPECT_TRUE(CheckPDFiumCApi());
+}
+
+class FPDFViewEmbeddertest : public EmbedderTest {};
+
+TEST_F(FPDFViewEmbeddertest, Document) {
+  EXPECT_TRUE(OpenDocument("about_blank.pdf"));
+  EXPECT_EQ(1, GetPageCount());
+  EXPECT_EQ(0, GetFirstPageNum());
+
+  int version;
+  EXPECT_TRUE(FPDF_GetFileVersion(document(), &version));
+  EXPECT_EQ(14, version);
+
+  EXPECT_EQ(0xFFFFFFFF, FPDF_GetDocPermissions(document()));
+  EXPECT_EQ(-1, FPDF_GetSecurityHandlerRevision(document()));
+}
+
+// See bug 465.
+TEST_F(FPDFViewEmbeddertest, EmptyDocument) {
+  EXPECT_TRUE(CreateEmptyDocument());
+
+  {
+    int version = 42;
+    EXPECT_FALSE(FPDF_GetFileVersion(document(), &version));
+    EXPECT_EQ(0, version);
+  }
+
+  {
+#ifndef PDF_ENABLE_XFA
+    const unsigned long kExpected = 0;
+#else
+    const unsigned long kExpected = static_cast<uint32_t>(-1);
+#endif
+    EXPECT_EQ(kExpected, FPDF_GetDocPermissions(document()));
+  }
+
+  EXPECT_EQ(-1, FPDF_GetSecurityHandlerRevision(document()));
+
+  EXPECT_EQ(0, FPDF_GetPageCount(document()));
+
+  EXPECT_TRUE(FPDF_VIEWERREF_GetPrintScaling(document()));
+  EXPECT_EQ(1, FPDF_VIEWERREF_GetNumCopies(document()));
+  EXPECT_EQ(DuplexUndefined, FPDF_VIEWERREF_GetDuplex(document()));
+
+  char buf[100];
+  EXPECT_EQ(0U, FPDF_VIEWERREF_GetName(document(), "foo", nullptr, 0));
+  EXPECT_EQ(0U, FPDF_VIEWERREF_GetName(document(), "foo", buf, sizeof(buf)));
+
+  EXPECT_EQ(0u, FPDF_CountNamedDests(document()));
+}
+
+TEST_F(FPDFViewEmbeddertest, Page) {
+  EXPECT_TRUE(OpenDocument("about_blank.pdf"));
+  FPDF_PAGE page = LoadPage(0);
+  EXPECT_NE(nullptr, page);
+  EXPECT_EQ(612.0, FPDF_GetPageWidth(page));
+  EXPECT_EQ(792.0, FPDF_GetPageHeight(page));
+  UnloadPage(page);
+  EXPECT_EQ(nullptr, LoadPage(1));
+}
+
+TEST_F(FPDFViewEmbeddertest, ViewerRefDummy) {
+  EXPECT_TRUE(OpenDocument("about_blank.pdf"));
+  EXPECT_TRUE(FPDF_VIEWERREF_GetPrintScaling(document()));
+  EXPECT_EQ(1, FPDF_VIEWERREF_GetNumCopies(document()));
+  EXPECT_EQ(DuplexUndefined, FPDF_VIEWERREF_GetDuplex(document()));
+
+  char buf[100];
+  EXPECT_EQ(0U, FPDF_VIEWERREF_GetName(document(), "foo", nullptr, 0));
+  EXPECT_EQ(0U, FPDF_VIEWERREF_GetName(document(), "foo", buf, sizeof(buf)));
+}
+
+TEST_F(FPDFViewEmbeddertest, ViewerRef) {
+  EXPECT_TRUE(OpenDocument("viewer_ref.pdf"));
+  EXPECT_TRUE(FPDF_VIEWERREF_GetPrintScaling(document()));
+  EXPECT_EQ(5, FPDF_VIEWERREF_GetNumCopies(document()));
+  EXPECT_EQ(DuplexUndefined, FPDF_VIEWERREF_GetDuplex(document()));
+
+  // Test some corner cases.
+  char buf[100];
+  EXPECT_EQ(0U, FPDF_VIEWERREF_GetName(document(), "", buf, sizeof(buf)));
+  EXPECT_EQ(0U, FPDF_VIEWERREF_GetName(document(), "foo", nullptr, 0));
+  EXPECT_EQ(0U, FPDF_VIEWERREF_GetName(document(), "foo", buf, sizeof(buf)));
+
+  // Make sure |buf| does not get written into when it appears to be too small.
+  // NOLINTNEXTLINE(runtime/printf)
+  strcpy(buf, "ABCD");
+  EXPECT_EQ(4U, FPDF_VIEWERREF_GetName(document(), "Foo", buf, 1));
+  EXPECT_STREQ("ABCD", buf);
+
+  // Note "Foo" is a different key from "foo".
+  EXPECT_EQ(4U,
+            FPDF_VIEWERREF_GetName(document(), "Foo", nullptr, sizeof(buf)));
+  ASSERT_EQ(4U, FPDF_VIEWERREF_GetName(document(), "Foo", buf, sizeof(buf)));
+  EXPECT_STREQ("foo", buf);
+
+  // Try to retrieve a boolean and an integer.
+  EXPECT_EQ(
+      0U, FPDF_VIEWERREF_GetName(document(), "HideToolbar", buf, sizeof(buf)));
+  EXPECT_EQ(0U,
+            FPDF_VIEWERREF_GetName(document(), "NumCopies", buf, sizeof(buf)));
+
+  // Try more valid cases.
+  ASSERT_EQ(4U,
+            FPDF_VIEWERREF_GetName(document(), "Direction", buf, sizeof(buf)));
+  EXPECT_STREQ("R2L", buf);
+  ASSERT_EQ(8U,
+            FPDF_VIEWERREF_GetName(document(), "ViewArea", buf, sizeof(buf)));
+  EXPECT_STREQ("CropBox", buf);
+}
+
+TEST_F(FPDFViewEmbeddertest, NamedDests) {
+  EXPECT_TRUE(OpenDocument("named_dests.pdf"));
+  long buffer_size;
+  char fixed_buffer[512];
+  FPDF_DEST dest;
+
+  // Query the size of the first item.
+  buffer_size = 2000000;  // Absurdly large, check not used for this case.
+  dest = FPDF_GetNamedDest(document(), 0, nullptr, &buffer_size);
+  EXPECT_NE(nullptr, dest);
+  EXPECT_EQ(12, buffer_size);
+
+  // Try to retrieve the first item with too small a buffer.
+  buffer_size = 10;
+  dest = FPDF_GetNamedDest(document(), 0, fixed_buffer, &buffer_size);
+  EXPECT_NE(nullptr, dest);
+  EXPECT_EQ(-1, buffer_size);
+
+  // Try to retrieve the first item with correctly sized buffer. Item is
+  // taken from Dests NameTree in named_dests.pdf.
+  buffer_size = 12;
+  dest = FPDF_GetNamedDest(document(), 0, fixed_buffer, &buffer_size);
+  EXPECT_NE(nullptr, dest);
+  EXPECT_EQ(12, buffer_size);
+  EXPECT_EQ(std::string("F\0i\0r\0s\0t\0\0\0", 12),
+            std::string(fixed_buffer, buffer_size));
+
+  // Try to retrieve the second item with ample buffer. Item is taken
+  // from Dests NameTree but has a sub-dictionary in named_dests.pdf.
+  buffer_size = sizeof(fixed_buffer);
+  dest = FPDF_GetNamedDest(document(), 1, fixed_buffer, &buffer_size);
+  EXPECT_NE(nullptr, dest);
+  EXPECT_EQ(10, buffer_size);
+  EXPECT_EQ(std::string("N\0e\0x\0t\0\0\0", 10),
+            std::string(fixed_buffer, buffer_size));
+
+  // Try to retrieve third item with ample buffer. Item is taken
+  // from Dests NameTree but has a bad sub-dictionary in named_dests.pdf.
+  // in named_dests.pdf).
+  buffer_size = sizeof(fixed_buffer);
+  dest = FPDF_GetNamedDest(document(), 2, fixed_buffer, &buffer_size);
+  EXPECT_EQ(nullptr, dest);
+  EXPECT_EQ(sizeof(fixed_buffer),
+            static_cast<size_t>(buffer_size));  // unmodified.
+
+  // Try to retrieve the forth item with ample buffer. Item is taken
+  // from Dests NameTree but has a vale of the wrong type in named_dests.pdf.
+  buffer_size = sizeof(fixed_buffer);
+  dest = FPDF_GetNamedDest(document(), 3, fixed_buffer, &buffer_size);
+  EXPECT_EQ(nullptr, dest);
+  EXPECT_EQ(sizeof(fixed_buffer),
+            static_cast<size_t>(buffer_size));  // unmodified.
+
+  // Try to retrieve fifth item with ample buffer. Item taken from the
+  // old-style Dests dictionary object in named_dests.pdf.
+  buffer_size = sizeof(fixed_buffer);
+  dest = FPDF_GetNamedDest(document(), 4, fixed_buffer, &buffer_size);
+  EXPECT_NE(nullptr, dest);
+  EXPECT_EQ(30, buffer_size);
+  EXPECT_EQ(std::string("F\0i\0r\0s\0t\0A\0l\0t\0e\0r\0n\0a\0t\0e\0\0\0", 30),
+            std::string(fixed_buffer, buffer_size));
+
+  // Try to retrieve sixth item with ample buffer. Item istaken from the
+  // old-style Dests dictionary object but has a sub-dictionary in
+  // named_dests.pdf.
+  buffer_size = sizeof(fixed_buffer);
+  dest = FPDF_GetNamedDest(document(), 5, fixed_buffer, &buffer_size);
+  EXPECT_NE(nullptr, dest);
+  EXPECT_EQ(28, buffer_size);
+  EXPECT_EQ(std::string("L\0a\0s\0t\0A\0l\0t\0e\0r\0n\0a\0t\0e\0\0\0", 28),
+            std::string(fixed_buffer, buffer_size));
+
+  // Try to retrieve non-existent item with ample buffer.
+  buffer_size = sizeof(fixed_buffer);
+  dest = FPDF_GetNamedDest(document(), 6, fixed_buffer, &buffer_size);
+  EXPECT_EQ(nullptr, dest);
+  EXPECT_EQ(sizeof(fixed_buffer),
+            static_cast<size_t>(buffer_size));  // unmodified.
+
+  // Try to underflow/overflow the integer index.
+  buffer_size = sizeof(fixed_buffer);
+  dest = FPDF_GetNamedDest(document(), std::numeric_limits<int>::max(),
+                           fixed_buffer, &buffer_size);
+  EXPECT_EQ(nullptr, dest);
+  EXPECT_EQ(sizeof(fixed_buffer),
+            static_cast<size_t>(buffer_size));  // unmodified.
+
+  buffer_size = sizeof(fixed_buffer);
+  dest = FPDF_GetNamedDest(document(), std::numeric_limits<int>::min(),
+                           fixed_buffer, &buffer_size);
+  EXPECT_EQ(nullptr, dest);
+  EXPECT_EQ(sizeof(fixed_buffer),
+            static_cast<size_t>(buffer_size));  // unmodified.
+
+  buffer_size = sizeof(fixed_buffer);
+  dest = FPDF_GetNamedDest(document(), -1, fixed_buffer, &buffer_size);
+  EXPECT_EQ(nullptr, dest);
+  EXPECT_EQ(sizeof(fixed_buffer),
+            static_cast<size_t>(buffer_size));  // unmodified.
+}
+
+TEST_F(FPDFViewEmbeddertest, NamedDestsByName) {
+  EXPECT_TRUE(OpenDocument("named_dests.pdf"));
+
+  // Null pointer returns nullptr.
+  FPDF_DEST dest = FPDF_GetNamedDestByName(document(), nullptr);
+  EXPECT_EQ(nullptr, dest);
+
+  // Empty string returns nullptr.
+  dest = FPDF_GetNamedDestByName(document(), "");
+  EXPECT_EQ(nullptr, dest);
+
+  // Item from Dests NameTree.
+  dest = FPDF_GetNamedDestByName(document(), "First");
+  EXPECT_NE(nullptr, dest);
+
+  long ignore_len = 0;
+  FPDF_DEST dest_by_index =
+      FPDF_GetNamedDest(document(), 0, nullptr, &ignore_len);
+  EXPECT_EQ(dest_by_index, dest);
+
+  // Item from Dests dictionary.
+  dest = FPDF_GetNamedDestByName(document(), "FirstAlternate");
+  EXPECT_NE(nullptr, dest);
+
+  ignore_len = 0;
+  dest_by_index = FPDF_GetNamedDest(document(), 4, nullptr, &ignore_len);
+  EXPECT_EQ(dest_by_index, dest);
+
+  // Bad value type for item from Dests NameTree array.
+  dest = FPDF_GetNamedDestByName(document(), "WrongType");
+  EXPECT_EQ(nullptr, dest);
+
+  // No such destination in either Dest NameTree or dictionary.
+  dest = FPDF_GetNamedDestByName(document(), "Bogus");
+  EXPECT_EQ(nullptr, dest);
+}
+
+// The following tests pass if the document opens without crashing.
+TEST_F(FPDFViewEmbeddertest, Crasher_113) {
+  EXPECT_TRUE(OpenDocument("bug_113.pdf"));
+}
+
+TEST_F(FPDFViewEmbeddertest, Crasher_451830) {
+  // Document is damaged and can't be opened.
+  EXPECT_FALSE(OpenDocument("bug_451830.pdf"));
+}
+
+TEST_F(FPDFViewEmbeddertest, Crasher_452455) {
+  EXPECT_TRUE(OpenDocument("bug_452455.pdf"));
+  FPDF_PAGE page = LoadPage(0);
+  EXPECT_NE(nullptr, page);
+  UnloadPage(page);
+}
+
+TEST_F(FPDFViewEmbeddertest, Crasher_454695) {
+  // Document is damaged and can't be opened.
+  EXPECT_FALSE(OpenDocument("bug_454695.pdf"));
+}
+
+TEST_F(FPDFViewEmbeddertest, Crasher_572871) {
+  EXPECT_TRUE(OpenDocument("bug_572871.pdf"));
+}
+
+// It tests that document can still be loaded even the trailer has no 'Size'
+// field if other information is right.
+TEST_F(FPDFViewEmbeddertest, Failed_213) {
+  EXPECT_TRUE(OpenDocument("bug_213.pdf"));
+}
+
+// The following tests pass if the document opens without infinite looping.
+TEST_F(FPDFViewEmbeddertest, Hang_298) {
+  EXPECT_FALSE(OpenDocument("bug_298.pdf"));
+}
+
+// Test if the document opens without infinite looping.
+// Previously this test will hang in a loop inside LoadAllCrossRefV4. After
+// the fix, LoadAllCrossRefV4 will return false after detecting a cross
+// reference loop. Cross references will be rebuilt successfully.
+TEST_F(FPDFViewEmbeddertest, CrossRefV4Loop) {
+  EXPECT_TRUE(OpenDocument("bug_xrefv4_loop.pdf"));
+}
+
+// The test should pass when circular references to ParseIndirectObject will not
+// cause infinite loop.
+TEST_F(FPDFViewEmbeddertest, Hang_343) {
+  EXPECT_FALSE(OpenDocument("bug_343.pdf"));
+}
+
+// The test should pass when the absence of 'Contents' field in a signature
+// dictionary will not cause an infinite loop in CPDF_SyntaxParser::GetObject().
+TEST_F(FPDFViewEmbeddertest, Hang_344) {
+  EXPECT_FALSE(OpenDocument("bug_344.pdf"));
+}
+
+// The test should pass when there is no infinite recursion in
+// CPDF_SyntaxParser::GetString().
+TEST_F(FPDFViewEmbeddertest, Hang_355) {
+  EXPECT_FALSE(OpenDocument("bug_355.pdf"));
+}
+// The test should pass even when the file has circular references to pages.
+TEST_F(FPDFViewEmbeddertest, Hang_360) {
+  EXPECT_FALSE(OpenDocument("bug_360.pdf"));
+}
+
+TEST_F(FPDFViewEmbeddertest, FPDF_RenderPageBitmapWithMatrix) {
+  const char kAllBlackMd5sum[] = "5708fc5c4a8bd0abde99c8e8f0390615";
+  const char kTopLeftQuarterBlackMd5sum[] = "24e4d1ec06fa0258af758cfc8b2ad50a";
+
+  EXPECT_TRUE(OpenDocument("black.pdf"));
+  FPDF_PAGE page = LoadPage(0);
+  EXPECT_NE(nullptr, page);
+  const int width = static_cast<int>(FPDF_GetPageWidth(page));
+  const int height = static_cast<int>(FPDF_GetPageHeight(page));
+  EXPECT_EQ(612, width);
+  EXPECT_EQ(792, height);
+
+  FPDF_BITMAP bitmap = RenderPage(page);
+  CompareBitmap(bitmap, width, height, kAllBlackMd5sum);
+  FPDFBitmap_Destroy(bitmap);
+
+  // Try rendering with an identity matrix. The output should be the same as
+  // the RenderPage() output.
+  FS_MATRIX matrix;
+  matrix.a = 1;
+  matrix.b = 0;
+  matrix.c = 0;
+  matrix.d = 1;
+  matrix.e = 0;
+  matrix.f = 0;
+
+  FS_RECTF rect;
+  rect.left = 0;
+  rect.top = 0;
+  rect.right = width;
+  rect.bottom = height;
+
+  bitmap = FPDFBitmap_Create(width, height, 0);
+  FPDFBitmap_FillRect(bitmap, 0, 0, width, height, 0xFFFFFFFF);
+  FPDF_RenderPageBitmapWithMatrix(bitmap, page, &matrix, &rect, 0);
+  CompareBitmap(bitmap, width, height, kAllBlackMd5sum);
+  FPDFBitmap_Destroy(bitmap);
+
+  // Now render again with the image scaled.
+  matrix.a = 0.5;
+  matrix.d = 0.5;
+
+  bitmap = FPDFBitmap_Create(width, height, 0);
+  FPDFBitmap_FillRect(bitmap, 0, 0, width, height, 0xFFFFFFFF);
+  FPDF_RenderPageBitmapWithMatrix(bitmap, page, &matrix, &rect, 0);
+  CompareBitmap(bitmap, width, height, kTopLeftQuarterBlackMd5sum);
+  FPDFBitmap_Destroy(bitmap);
+
+  UnloadPage(page);
+}
diff --git a/fpdfsdk/fpdfview_unittest.cpp b/fpdfsdk/fpdfview_unittest.cpp
new file mode 100644
index 0000000..27680b3
--- /dev/null
+++ b/fpdfsdk/fpdfview_unittest.cpp
@@ -0,0 +1,20 @@
+// 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.
+
+#include "public/fpdfview.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/test_support.h"
+
+TEST(FPDFView, DoubleInit) {
+  FPDF_InitLibrary();
+  FPDF_InitLibrary();
+  FPDF_DestroyLibrary();
+}
+
+TEST(FPDFView, DoubleDestroy) {
+  FPDF_InitLibrary();
+  FPDF_DestroyLibrary();
+  FPDF_DestroyLibrary();
+}
diff --git a/fpdfsdk/fpdfxfa/DEPS b/fpdfsdk/fpdfxfa/DEPS
new file mode 100644
index 0000000..1687e30
--- /dev/null
+++ b/fpdfsdk/fpdfxfa/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+  '+fxjs',
+  '+xfa/fxbarcode',
+]
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp b/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp
new file mode 100644
index 0000000..113a74e
--- /dev/null
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp
@@ -0,0 +1,366 @@
+// 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
+
+#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
+
+#include <utility>
+
+#include "core/fpdfapi/parser/cpdf_document.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/cpdfsdk_interform.h"
+#include "fpdfsdk/cpdfsdk_pageview.h"
+#include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
+#include "fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h"
+#include "fpdfsdk/fsdk_define.h"
+#include "fpdfsdk/javascript/cjs_runtime.h"
+#include "fpdfsdk/javascript/ijs_runtime.h"
+#include "public/fpdf_formfill.h"
+#include "third_party/base/ptr_util.h"
+#include "xfa/fxfa/cxfa_eventparam.h"
+#include "xfa/fxfa/xfa_ffapp.h"
+#include "xfa/fxfa/xfa_ffdoc.h"
+#include "xfa/fxfa/xfa_ffdocview.h"
+#include "xfa/fxfa/xfa_ffpageview.h"
+#include "xfa/fxfa/xfa_ffwidgethandler.h"
+#include "xfa/fxfa/xfa_fontmgr.h"
+
+#ifndef _WIN32
+extern void SetLastError(int err);
+extern int GetLastError();
+#endif
+
+CPDFXFA_Context::CPDFXFA_Context(std::unique_ptr<CPDF_Document> pPDFDoc)
+    : m_iDocType(DOCTYPE_PDF),
+      m_pPDFDoc(std::move(pPDFDoc)),
+      m_pFormFillEnv(nullptr),
+      m_pXFADocView(nullptr),
+      m_nLoadStatus(FXFA_LOADSTATUS_PRELOAD),
+      m_nPageCount(0),
+      m_DocEnv(this) {
+  m_pXFAApp = pdfium::MakeUnique<CXFA_FFApp>(this);
+  m_pXFAApp->SetDefaultFontMgr(pdfium::MakeUnique<CXFA_DefFontMgr>());
+}
+
+CPDFXFA_Context::~CPDFXFA_Context() {
+  m_nLoadStatus = FXFA_LOADSTATUS_CLOSING;
+
+  // Must happen before we remove the form fill environment.
+  CloseXFADoc();
+
+  if (m_pFormFillEnv) {
+    m_pFormFillEnv->ClearAllFocusedAnnots();
+    // Once we're deleted the FormFillEnvironment will point at a bad underlying
+    // doc so we need to reset it ...
+    m_pFormFillEnv->ResetXFADocument();
+    m_pFormFillEnv = nullptr;
+  }
+
+  m_nLoadStatus = FXFA_LOADSTATUS_CLOSED;
+}
+
+void CPDFXFA_Context::CloseXFADoc() {
+  if (!m_pXFADoc)
+    return;
+  m_pXFADoc->CloseDoc();
+  m_pXFADoc.reset();
+  m_pXFADocView = nullptr;
+}
+
+void CPDFXFA_Context::SetFormFillEnv(
+    CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+  // The layout data can have pointers back into the script context. That
+  // context will be different if the form fill environment closes, so, force
+  // the layout data to clear.
+  if (m_pXFADoc && m_pXFADoc->GetXFADoc())
+    m_pXFADoc->GetXFADoc()->ClearLayoutData();
+
+  m_pFormFillEnv = pFormFillEnv;
+}
+
+bool CPDFXFA_Context::LoadXFADoc() {
+  m_nLoadStatus = FXFA_LOADSTATUS_LOADING;
+
+  if (!m_pPDFDoc)
+    return false;
+
+  m_XFAPageList.RemoveAll();
+
+  CXFA_FFApp* pApp = GetXFAApp();
+  if (!pApp)
+    return false;
+
+  m_pXFADoc = pApp->CreateDoc(&m_DocEnv, m_pPDFDoc.get());
+  if (!m_pXFADoc) {
+    SetLastError(FPDF_ERR_XFALOAD);
+    return false;
+  }
+
+  CXFA_FFDocHandler* pDocHandler = pApp->GetDocHandler();
+  if (!pDocHandler) {
+    SetLastError(FPDF_ERR_XFALOAD);
+    return false;
+  }
+
+  m_pXFADoc->StartLoad();
+  int iStatus = m_pXFADoc->DoLoad(nullptr);
+  if (iStatus != XFA_PARSESTATUS_Done) {
+    CloseXFADoc();
+    SetLastError(FPDF_ERR_XFALOAD);
+    return false;
+  }
+  m_pXFADoc->StopLoad();
+  m_pXFADoc->GetXFADoc()->InitScriptContext(GetJSERuntime());
+
+  if (m_pXFADoc->GetDocType() == XFA_DOCTYPE_Dynamic)
+    m_iDocType = DOCTYPE_DYNAMIC_XFA;
+  else
+    m_iDocType = DOCTYPE_STATIC_XFA;
+
+  m_pXFADocView = m_pXFADoc->CreateDocView(XFA_DOCVIEW_View);
+  if (m_pXFADocView->StartLayout() < 0) {
+    CloseXFADoc();
+    SetLastError(FPDF_ERR_XFALAYOUT);
+    return false;
+  }
+
+  m_pXFADocView->DoLayout(nullptr);
+  m_pXFADocView->StopLayout();
+  m_nLoadStatus = FXFA_LOADSTATUS_LOADED;
+
+  return true;
+}
+
+int CPDFXFA_Context::GetPageCount() const {
+  if (!m_pPDFDoc && !m_pXFADoc)
+    return 0;
+
+  switch (m_iDocType) {
+    case DOCTYPE_PDF:
+    case DOCTYPE_STATIC_XFA:
+      if (m_pPDFDoc)
+        return m_pPDFDoc->GetPageCount();
+    case DOCTYPE_DYNAMIC_XFA:
+      if (m_pXFADoc)
+        return m_pXFADocView->CountPageViews();
+    default:
+      return 0;
+  }
+}
+
+CPDFXFA_Page* CPDFXFA_Context::GetXFAPage(int page_index) {
+  if (page_index < 0)
+    return nullptr;
+
+  CPDFXFA_Page* pPage = nullptr;
+  int nCount = m_XFAPageList.GetSize();
+  if (nCount > 0 && page_index < nCount) {
+    pPage = m_XFAPageList.GetAt(page_index);
+    if (pPage)
+      pPage->Retain();
+  } else {
+    m_nPageCount = GetPageCount();
+    m_XFAPageList.SetSize(m_nPageCount);
+  }
+  if (pPage)
+    return pPage;
+
+  pPage = new CPDFXFA_Page(this, page_index);
+  if (!pPage->LoadPage()) {
+    pPage->Release();
+    return nullptr;
+  }
+  m_XFAPageList.SetAt(page_index, pPage);
+  return pPage;
+}
+
+CPDFXFA_Page* CPDFXFA_Context::GetXFAPage(CXFA_FFPageView* pPage) const {
+  if (!pPage)
+    return nullptr;
+
+  if (!m_pXFADoc)
+    return nullptr;
+
+  if (m_iDocType != DOCTYPE_DYNAMIC_XFA)
+    return nullptr;
+
+  int nSize = m_XFAPageList.GetSize();
+  for (int i = 0; i < nSize; i++) {
+    CPDFXFA_Page* pTempPage = m_XFAPageList.GetAt(i);
+    if (!pTempPage)
+      continue;
+    if (pTempPage->GetXFAPageView() && pTempPage->GetXFAPageView() == pPage)
+      return pTempPage;
+  }
+
+  return nullptr;
+}
+
+void CPDFXFA_Context::DeletePage(int page_index) {
+  // Delete from the document first because, if GetPage was never called for
+  // this |page_index| then |m_XFAPageList| may have size < |page_index| even
+  // if it's a valid page in the document.
+  if (m_pPDFDoc)
+    m_pPDFDoc->DeletePage(page_index);
+
+  if (page_index < 0 || page_index >= m_XFAPageList.GetSize())
+    return;
+
+  if (CPDFXFA_Page* pPage = m_XFAPageList.GetAt(page_index))
+    pPage->Release();
+}
+
+void CPDFXFA_Context::RemovePage(CPDFXFA_Page* page) {
+  m_XFAPageList.SetAt(page->GetPageIndex(), nullptr);
+}
+
+void CPDFXFA_Context::ClearChangeMark() {
+  if (m_pFormFillEnv)
+    m_pFormFillEnv->ClearChangeMark();
+}
+
+v8::Isolate* CPDFXFA_Context::GetJSERuntime() const {
+  if (!m_pFormFillEnv)
+    return nullptr;
+
+  // XFA requires V8, if we have V8 then we have a CJS_Runtime and not the stub.
+  CJS_Runtime* runtime =
+      static_cast<CJS_Runtime*>(m_pFormFillEnv->GetJSRuntime());
+  return runtime->GetIsolate();
+}
+
+CFX_WideString CPDFXFA_Context::GetAppTitle() const {
+  return L"PDFium";
+}
+
+CFX_WideString CPDFXFA_Context::GetAppName() {
+  return m_pFormFillEnv ? m_pFormFillEnv->FFI_GetAppName() : L"";
+}
+
+CFX_WideString CPDFXFA_Context::GetLanguage() {
+  return m_pFormFillEnv ? m_pFormFillEnv->GetLanguage() : L"";
+}
+
+CFX_WideString CPDFXFA_Context::GetPlatform() {
+  return m_pFormFillEnv ? m_pFormFillEnv->GetPlatform() : L"";
+}
+
+void CPDFXFA_Context::Beep(uint32_t dwType) {
+  if (m_pFormFillEnv)
+    m_pFormFillEnv->JS_appBeep(dwType);
+}
+
+int32_t CPDFXFA_Context::MsgBox(const CFX_WideString& wsMessage,
+                                const CFX_WideString& wsTitle,
+                                uint32_t dwIconType,
+                                uint32_t dwButtonType) {
+  if (!m_pFormFillEnv)
+    return -1;
+
+  uint32_t iconType = 0;
+  int iButtonType = 0;
+  switch (dwIconType) {
+    case XFA_MBICON_Error:
+      iconType |= 0;
+      break;
+    case XFA_MBICON_Warning:
+      iconType |= 1;
+      break;
+    case XFA_MBICON_Question:
+      iconType |= 2;
+      break;
+    case XFA_MBICON_Status:
+      iconType |= 3;
+      break;
+  }
+  switch (dwButtonType) {
+    case XFA_MB_OK:
+      iButtonType |= 0;
+      break;
+    case XFA_MB_OKCancel:
+      iButtonType |= 1;
+      break;
+    case XFA_MB_YesNo:
+      iButtonType |= 2;
+      break;
+    case XFA_MB_YesNoCancel:
+      iButtonType |= 3;
+      break;
+  }
+  int32_t iRet = m_pFormFillEnv->JS_appAlert(wsMessage.c_str(), wsTitle.c_str(),
+                                             iButtonType, iconType);
+  switch (iRet) {
+    case 1:
+      return XFA_IDOK;
+    case 2:
+      return XFA_IDCancel;
+    case 3:
+      return XFA_IDNo;
+    case 4:
+      return XFA_IDYes;
+  }
+  return XFA_IDYes;
+}
+
+CFX_WideString CPDFXFA_Context::Response(const CFX_WideString& wsQuestion,
+                                         const CFX_WideString& wsTitle,
+                                         const CFX_WideString& wsDefaultAnswer,
+                                         bool bMark) {
+  CFX_WideString wsAnswer;
+  if (!m_pFormFillEnv)
+    return wsAnswer;
+
+  int nLength = 2048;
+  char* pBuff = new char[nLength];
+  nLength = m_pFormFillEnv->JS_appResponse(wsQuestion.c_str(), wsTitle.c_str(),
+                                           wsDefaultAnswer.c_str(), nullptr,
+                                           bMark, pBuff, nLength);
+  if (nLength > 0) {
+    nLength = nLength > 2046 ? 2046 : nLength;
+    pBuff[nLength] = 0;
+    pBuff[nLength + 1] = 0;
+    wsAnswer = CFX_WideString::FromUTF16LE(
+        reinterpret_cast<const unsigned short*>(pBuff),
+        nLength / sizeof(unsigned short));
+  }
+  delete[] pBuff;
+  return wsAnswer;
+}
+
+CFX_RetainPtr<IFX_SeekableReadStream> CPDFXFA_Context::DownloadURL(
+    const CFX_WideString& wsURL) {
+  return m_pFormFillEnv ? m_pFormFillEnv->DownloadFromURL(wsURL.c_str())
+                        : nullptr;
+}
+
+bool CPDFXFA_Context::PostRequestURL(const CFX_WideString& wsURL,
+                                     const CFX_WideString& wsData,
+                                     const CFX_WideString& wsContentType,
+                                     const CFX_WideString& wsEncode,
+                                     const CFX_WideString& wsHeader,
+                                     CFX_WideString& wsResponse) {
+  if (!m_pFormFillEnv)
+    return false;
+
+  wsResponse = m_pFormFillEnv->PostRequestURL(
+      wsURL.c_str(), wsData.c_str(), wsContentType.c_str(), wsEncode.c_str(),
+      wsHeader.c_str());
+  return true;
+}
+
+bool CPDFXFA_Context::PutRequestURL(const CFX_WideString& wsURL,
+                                    const CFX_WideString& wsData,
+                                    const CFX_WideString& wsEncode) {
+  return m_pFormFillEnv &&
+         m_pFormFillEnv->PutRequestURL(wsURL.c_str(), wsData.c_str(),
+                                       wsEncode.c_str());
+}
+
+IFWL_AdapterTimerMgr* CPDFXFA_Context::GetTimerMgr() {
+  CXFA_FWLAdapterTimerMgr* pAdapter = nullptr;
+  if (m_pFormFillEnv)
+    pAdapter = new CXFA_FWLAdapterTimerMgr(m_pFormFillEnv);
+  return pAdapter;
+}
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_context.h b/fpdfsdk/fpdfxfa/cpdfxfa_context.h
new file mode 100644
index 0000000..de3f39c
--- /dev/null
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_context.h
@@ -0,0 +1,117 @@
+// 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_FPDFXFA_CPDFXFA_CONTEXT_H_
+#define FPDFSDK_FPDFXFA_CPDFXFA_CONTEXT_H_
+
+#include <memory>
+
+#include "fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.h"
+#include "xfa/fxfa/xfa_ffdoc.h"
+
+class CJS_Runtime;
+class CPDFSDK_FormFillEnvironment;
+class CPDFXFA_Page;
+class CXFA_FFDocHandler;
+class IJS_Runtime;
+class IJS_Context;
+
+enum LoadStatus {
+  FXFA_LOADSTATUS_PRELOAD = 0,
+  FXFA_LOADSTATUS_LOADING,
+  FXFA_LOADSTATUS_LOADED,
+  FXFA_LOADSTATUS_CLOSING,
+  FXFA_LOADSTATUS_CLOSED
+};
+
+class CPDFXFA_Context : public IXFA_AppProvider {
+ public:
+  explicit CPDFXFA_Context(std::unique_ptr<CPDF_Document> pPDFDoc);
+  ~CPDFXFA_Context() override;
+
+  bool LoadXFADoc();
+  CPDF_Document* GetPDFDoc() { return m_pPDFDoc.get(); }
+  CXFA_FFDoc* GetXFADoc() { return m_pXFADoc.get(); }
+  CXFA_FFDocView* GetXFADocView() { return m_pXFADocView; }
+  int GetDocType() const { return m_iDocType; }
+  v8::Isolate* GetJSERuntime() const;
+  CXFA_FFApp* GetXFAApp() { return m_pXFAApp.get(); }
+
+  CPDFSDK_FormFillEnvironment* GetFormFillEnv() const { return m_pFormFillEnv; }
+  void SetFormFillEnv(CPDFSDK_FormFillEnvironment* pFormFillEnv);
+
+  void DeletePage(int page_index);
+  int GetPageCount() const;
+
+  CPDFXFA_Page* GetXFAPage(int page_index);
+  CPDFXFA_Page* GetXFAPage(CXFA_FFPageView* pPage) const;
+
+  void RemovePage(CPDFXFA_Page* page);
+
+  void ClearChangeMark();
+
+  // IFXA_AppProvider:
+  CFX_WideString GetLanguage() override;
+  CFX_WideString GetPlatform() override;
+  CFX_WideString GetAppName() override;
+  CFX_WideString GetAppTitle() const override;
+
+  void Beep(uint32_t dwType) override;
+  int32_t MsgBox(const CFX_WideString& wsMessage,
+                 const CFX_WideString& wsTitle,
+                 uint32_t dwIconType,
+                 uint32_t dwButtonType) override;
+  CFX_WideString Response(const CFX_WideString& wsQuestion,
+                          const CFX_WideString& wsTitle,
+                          const CFX_WideString& wsDefaultAnswer,
+                          bool bMark) override;
+  CFX_RetainPtr<IFX_SeekableReadStream> DownloadURL(
+      const CFX_WideString& wsURL) override;
+  bool PostRequestURL(const CFX_WideString& wsURL,
+                      const CFX_WideString& wsData,
+                      const CFX_WideString& wsContentType,
+                      const CFX_WideString& wsEncode,
+                      const CFX_WideString& wsHeader,
+                      CFX_WideString& wsResponse) override;
+  bool PutRequestURL(const CFX_WideString& wsURL,
+                     const CFX_WideString& wsData,
+                     const CFX_WideString& wsEncode) override;
+
+  IFWL_AdapterTimerMgr* GetTimerMgr() override;
+
+ protected:
+  friend class CPDFXFA_DocEnvironment;
+
+  int GetOriginalPageCount() const { return m_nPageCount; }
+  void SetOriginalPageCount(int count) {
+    m_nPageCount = count;
+    m_XFAPageList.SetSize(count);
+  }
+
+  LoadStatus GetLoadStatus() const { return m_nLoadStatus; }
+
+  CFX_ArrayTemplate<CPDFXFA_Page*>* GetXFAPageList() { return &m_XFAPageList; }
+
+ private:
+  void CloseXFADoc();
+
+  int m_iDocType;
+
+  std::unique_ptr<CPDF_Document> m_pPDFDoc;
+  std::unique_ptr<CXFA_FFDoc> m_pXFADoc;
+  CPDFSDK_FormFillEnvironment* m_pFormFillEnv;  // not owned.
+  CXFA_FFDocView* m_pXFADocView;                // not owned.
+  std::unique_ptr<CXFA_FFApp> m_pXFAApp;
+  std::unique_ptr<CJS_Runtime> m_pRuntime;
+  CFX_ArrayTemplate<CPDFXFA_Page*> m_XFAPageList;
+  LoadStatus m_nLoadStatus;
+  int m_nPageCount;
+
+  // Must be destroyed before |m_pFormFillEnv|.
+  CPDFXFA_DocEnvironment m_DocEnv;
+};
+
+#endif  // FPDFSDK_FPDFXFA_CPDFXFA_CONTEXT_H_
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp
new file mode 100644
index 0000000..2b3368b
--- /dev/null
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp
@@ -0,0 +1,1030 @@
+// 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/fpdfxfa/cpdfxfa_docenvironment.h"
+
+#include <memory>
+
+#include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfapi/parser/cpdf_stream_acc.h"
+#include "core/fpdfapi/parser/cpdf_string.h"
+#include "core/fxcrt/cfx_retain_ptr.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/cpdfsdk_interform.h"
+#include "fpdfsdk/cpdfsdk_pageview.h"
+#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
+#include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
+#include "fpdfsdk/javascript/ijs_runtime.h"
+#include "xfa/fxfa/xfa_ffdocview.h"
+#include "xfa/fxfa/xfa_ffwidget.h"
+#include "xfa/fxfa/xfa_ffwidgethandler.h"
+
+#define IDS_XFA_Validate_Input                                          \
+  "At least one required field was empty. Please fill in the required " \
+  "fields\r\n(highlighted) before continuing."
+
+// submit
+#define FXFA_CONFIG 0x00000001
+#define FXFA_TEMPLATE 0x00000010
+#define FXFA_LOCALESET 0x00000100
+#define FXFA_DATASETS 0x00001000
+#define FXFA_XMPMETA 0x00010000
+#define FXFA_XFDF 0x00100000
+#define FXFA_FORM 0x01000000
+#define FXFA_PDF 0x10000000
+#define FXFA_XFA_ALL 0x01111111
+
+CPDFXFA_DocEnvironment::CPDFXFA_DocEnvironment(CPDFXFA_Context* pContext)
+    : m_pContext(pContext), m_pJSContext(nullptr) {
+  ASSERT(m_pContext);
+}
+
+CPDFXFA_DocEnvironment::~CPDFXFA_DocEnvironment() {
+  if (m_pJSContext && m_pContext->GetFormFillEnv())
+    m_pContext->GetFormFillEnv()->GetJSRuntime()->ReleaseContext(m_pJSContext);
+}
+
+void CPDFXFA_DocEnvironment::SetChangeMark(CXFA_FFDoc* hDoc) {
+  if (hDoc == m_pContext->GetXFADoc() && m_pContext->GetFormFillEnv())
+    m_pContext->GetFormFillEnv()->SetChangeMark();
+}
+
+void CPDFXFA_DocEnvironment::InvalidateRect(CXFA_FFPageView* pPageView,
+                                            const CFX_RectF& rt,
+                                            uint32_t dwFlags /* = 0 */) {
+  if (!m_pContext->GetXFADoc() || !m_pContext->GetFormFillEnv())
+    return;
+
+  if (m_pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA)
+    return;
+
+  CPDFXFA_Page* pPage = m_pContext->GetXFAPage(pPageView);
+  if (!pPage)
+    return;
+
+  CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
+  if (!pFormFillEnv)
+    return;
+
+  CFX_FloatRect rcPage = CFX_FloatRect::FromCFXRectF(rt);
+  pFormFillEnv->Invalidate((FPDF_PAGE)pPage, rcPage.left, rcPage.bottom,
+                           rcPage.right, rcPage.top);
+}
+
+void CPDFXFA_DocEnvironment::DisplayCaret(CXFA_FFWidget* hWidget,
+                                          bool bVisible,
+                                          const CFX_RectF* pRtAnchor) {
+  if (!hWidget || !pRtAnchor || !m_pContext->GetXFADoc() ||
+      !m_pContext->GetFormFillEnv() || !m_pContext->GetXFADocView())
+    return;
+
+  if (m_pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA)
+    return;
+
+  CXFA_FFWidgetHandler* pWidgetHandler =
+      m_pContext->GetXFADocView()->GetWidgetHandler();
+  if (!pWidgetHandler)
+    return;
+
+  CXFA_FFPageView* pPageView = hWidget->GetPageView();
+  if (!pPageView)
+    return;
+
+  CPDFXFA_Page* pPage = m_pContext->GetXFAPage(pPageView);
+  if (!pPage)
+    return;
+
+  CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
+  if (!pFormFillEnv)
+    return;
+
+  CFX_FloatRect rcCaret = CFX_FloatRect::FromCFXRectF(*pRtAnchor);
+  pFormFillEnv->DisplayCaret((FPDF_PAGE)pPage, bVisible, rcCaret.left,
+                             rcCaret.top, rcCaret.right, rcCaret.bottom);
+}
+
+bool CPDFXFA_DocEnvironment::GetPopupPos(CXFA_FFWidget* hWidget,
+                                         FX_FLOAT fMinPopup,
+                                         FX_FLOAT fMaxPopup,
+                                         const CFX_RectF& rtAnchor,
+                                         CFX_RectF& rtPopup) {
+  if (!hWidget)
+    return false;
+
+  CXFA_FFPageView* pXFAPageView = hWidget->GetPageView();
+  if (!pXFAPageView)
+    return false;
+
+  CPDFXFA_Page* pPage = m_pContext->GetXFAPage(pXFAPageView);
+  if (!pPage)
+    return false;
+
+  CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc();
+  int nRotate = pWidgetAcc->GetRotate();
+  CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
+  if (!pFormFillEnv)
+    return false;
+
+  FS_RECTF pageViewRect = {0.0f, 0.0f, 0.0f, 0.0f};
+  pFormFillEnv->GetPageViewRect(pPage, pageViewRect);
+
+  int t1;
+  int t2;
+  CFX_FloatRect rcAnchor = CFX_FloatRect::FromCFXRectF(rtAnchor);
+  switch (nRotate) {
+    case 90: {
+      t1 = (int)(pageViewRect.right - rcAnchor.right);
+      t2 = (int)(rcAnchor.left - pageViewRect.left);
+      if (rcAnchor.bottom < pageViewRect.bottom)
+        rtPopup.left += rcAnchor.bottom - pageViewRect.bottom;
+      break;
+    }
+    case 180: {
+      t2 = (int)(pageViewRect.top - rcAnchor.top);
+      t1 = (int)(rcAnchor.bottom - pageViewRect.bottom);
+      if (rcAnchor.left < pageViewRect.left)
+        rtPopup.left += rcAnchor.left - pageViewRect.left;
+      break;
+    }
+    case 270: {
+      t1 = (int)(rcAnchor.left - pageViewRect.left);
+      t2 = (int)(pageViewRect.right - rcAnchor.right);
+      if (rcAnchor.top > pageViewRect.top)
+        rtPopup.left -= rcAnchor.top - pageViewRect.top;
+      break;
+    }
+    case 0:
+    default: {
+      t1 = (int)(pageViewRect.top - rcAnchor.top);
+      t2 = (int)(rcAnchor.bottom - pageViewRect.bottom);
+      if (rcAnchor.right > pageViewRect.right)
+        rtPopup.left -= rcAnchor.right - pageViewRect.right;
+      break;
+    }
+  }
+
+  int t;
+  uint32_t dwPos;
+  if (t1 <= 0 && t2 <= 0)
+    return false;
+  if (t1 <= 0) {
+    t = t2;
+    dwPos = 1;
+  } else if (t2 <= 0) {
+    t = t1;
+    dwPos = 0;
+  } else if (t1 > t2) {
+    t = t1;
+    dwPos = 0;
+  } else {
+    t = t2;
+    dwPos = 1;
+  }
+
+  FX_FLOAT fPopupHeight;
+  if (t < fMinPopup)
+    fPopupHeight = fMinPopup;
+  else if (t > fMaxPopup)
+    fPopupHeight = fMaxPopup;
+  else
+    fPopupHeight = static_cast<FX_FLOAT>(t);
+
+  switch (nRotate) {
+    case 0:
+    case 180: {
+      if (dwPos == 0) {
+        rtPopup.top = rtAnchor.height;
+        rtPopup.height = fPopupHeight;
+      } else {
+        rtPopup.top = -fPopupHeight;
+        rtPopup.height = fPopupHeight;
+      }
+      break;
+    }
+    case 90:
+    case 270: {
+      if (dwPos == 0) {
+        rtPopup.top = rtAnchor.width;
+        rtPopup.height = fPopupHeight;
+      } else {
+        rtPopup.top = -fPopupHeight;
+        rtPopup.height = fPopupHeight;
+      }
+      break;
+    }
+    default:
+      break;
+  }
+
+  return true;
+}
+
+bool CPDFXFA_DocEnvironment::PopupMenu(CXFA_FFWidget* hWidget,
+                                       CFX_PointF ptPopup) {
+  if (!hWidget)
+    return false;
+
+  CXFA_FFPageView* pXFAPageView = hWidget->GetPageView();
+  if (!pXFAPageView)
+    return false;
+
+  CPDFXFA_Page* pPage = m_pContext->GetXFAPage(pXFAPageView);
+  if (!pPage)
+    return false;
+
+  CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
+  if (!pFormFillEnv)
+    return false;
+
+  int menuFlag = 0;
+  if (hWidget->CanUndo())
+    menuFlag |= FXFA_MENU_UNDO;
+  if (hWidget->CanRedo())
+    menuFlag |= FXFA_MENU_REDO;
+  if (hWidget->CanPaste())
+    menuFlag |= FXFA_MENU_PASTE;
+  if (hWidget->CanCopy())
+    menuFlag |= FXFA_MENU_COPY;
+  if (hWidget->CanCut())
+    menuFlag |= FXFA_MENU_CUT;
+  if (hWidget->CanSelectAll())
+    menuFlag |= FXFA_MENU_SELECTALL;
+
+  return pFormFillEnv->PopupMenu(pPage, hWidget, menuFlag, ptPopup);
+}
+
+void CPDFXFA_DocEnvironment::PageViewEvent(CXFA_FFPageView* pPageView,
+                                           uint32_t dwFlags) {
+  CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
+  if (!pFormFillEnv)
+    return;
+
+  if (m_pContext->GetLoadStatus() == FXFA_LOADSTATUS_LOADING ||
+      m_pContext->GetLoadStatus() == FXFA_LOADSTATUS_CLOSING ||
+      XFA_PAGEVIEWEVENT_StopLayout != dwFlags)
+    return;
+
+  int nNewCount = m_pContext->GetPageCount();
+  if (nNewCount == m_pContext->GetOriginalPageCount())
+    return;
+
+  CXFA_FFDocView* pXFADocView = m_pContext->GetXFADocView();
+  if (!pXFADocView)
+    return;
+
+  for (int iPageIter = 0; iPageIter < m_pContext->GetOriginalPageCount();
+       iPageIter++) {
+    CPDFXFA_Page* pPage = m_pContext->GetXFAPageList()->GetAt(iPageIter);
+    if (!pPage)
+      continue;
+
+    m_pContext->GetFormFillEnv()->RemovePageView(pPage);
+    pPage->SetXFAPageView(pXFADocView->GetPageView(iPageIter));
+  }
+
+  int flag = (nNewCount < m_pContext->GetOriginalPageCount())
+                 ? FXFA_PAGEVIEWEVENT_POSTREMOVED
+                 : FXFA_PAGEVIEWEVENT_POSTADDED;
+  int count = FXSYS_abs(nNewCount - m_pContext->GetOriginalPageCount());
+  m_pContext->SetOriginalPageCount(nNewCount);
+  pFormFillEnv->PageEvent(count, flag);
+}
+
+void CPDFXFA_DocEnvironment::WidgetPostAdd(CXFA_FFWidget* hWidget,
+                                           CXFA_WidgetAcc* pWidgetData) {
+  if (m_pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA || !hWidget)
+    return;
+
+  CXFA_FFPageView* pPageView = hWidget->GetPageView();
+  if (!pPageView)
+    return;
+
+  CPDFXFA_Page* pXFAPage = m_pContext->GetXFAPage(pPageView);
+  if (!pXFAPage)
+    return;
+
+  m_pContext->GetFormFillEnv()->GetPageView(pXFAPage, true)->AddAnnot(hWidget);
+}
+
+void CPDFXFA_DocEnvironment::WidgetPreRemove(CXFA_FFWidget* hWidget,
+                                             CXFA_WidgetAcc* pWidgetData) {
+  if (m_pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA || !hWidget)
+    return;
+
+  CXFA_FFPageView* pPageView = hWidget->GetPageView();
+  if (!pPageView)
+    return;
+
+  CPDFXFA_Page* pXFAPage = m_pContext->GetXFAPage(pPageView);
+  if (!pXFAPage)
+    return;
+
+  CPDFSDK_PageView* pSdkPageView =
+      m_pContext->GetFormFillEnv()->GetPageView(pXFAPage, true);
+  if (CPDFSDK_Annot* pAnnot = pSdkPageView->GetAnnotByXFAWidget(hWidget))
+    pSdkPageView->DeleteAnnot(pAnnot);
+}
+
+int32_t CPDFXFA_DocEnvironment::CountPages(CXFA_FFDoc* hDoc) {
+  if (hDoc == m_pContext->GetXFADoc() && m_pContext->GetFormFillEnv())
+    return m_pContext->GetPageCount();
+  return 0;
+}
+
+int32_t CPDFXFA_DocEnvironment::GetCurrentPage(CXFA_FFDoc* hDoc) {
+  if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetFormFillEnv())
+    return -1;
+  if (m_pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA)
+    return -1;
+
+  CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
+  if (!pFormFillEnv)
+    return -1;
+
+  return pFormFillEnv->GetCurrentPageIndex(this);
+}
+
+void CPDFXFA_DocEnvironment::SetCurrentPage(CXFA_FFDoc* hDoc,
+                                            int32_t iCurPage) {
+  if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetFormFillEnv() ||
+      m_pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA || iCurPage < 0 ||
+      iCurPage >= m_pContext->GetFormFillEnv()->GetPageCount()) {
+    return;
+  }
+
+  CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
+  if (!pFormFillEnv)
+    return;
+  pFormFillEnv->SetCurrentPage(this, iCurPage);
+}
+
+bool CPDFXFA_DocEnvironment::IsCalculationsEnabled(CXFA_FFDoc* hDoc) {
+  if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetFormFillEnv())
+    return false;
+  if (m_pContext->GetFormFillEnv()->GetInterForm()) {
+    return m_pContext->GetFormFillEnv()
+        ->GetInterForm()
+        ->IsXfaCalculateEnabled();
+  }
+  return false;
+}
+
+void CPDFXFA_DocEnvironment::SetCalculationsEnabled(CXFA_FFDoc* hDoc,
+                                                    bool bEnabled) {
+  if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetFormFillEnv())
+    return;
+  if (m_pContext->GetFormFillEnv()->GetInterForm()) {
+    m_pContext->GetFormFillEnv()->GetInterForm()->XfaEnableCalculate(bEnabled);
+  }
+}
+
+void CPDFXFA_DocEnvironment::GetTitle(CXFA_FFDoc* hDoc,
+                                      CFX_WideString& wsTitle) {
+  if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetPDFDoc())
+    return;
+
+  CPDF_Dictionary* pInfoDict = m_pContext->GetPDFDoc()->GetInfo();
+  if (!pInfoDict)
+    return;
+
+  CFX_ByteString csTitle = pInfoDict->GetStringFor("Title");
+  wsTitle = wsTitle.FromLocal(csTitle.GetBuffer(csTitle.GetLength()));
+  csTitle.ReleaseBuffer(csTitle.GetLength());
+}
+
+void CPDFXFA_DocEnvironment::SetTitle(CXFA_FFDoc* hDoc,
+                                      const CFX_WideString& wsTitle) {
+  if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetPDFDoc())
+    return;
+
+  if (CPDF_Dictionary* pInfoDict = m_pContext->GetPDFDoc()->GetInfo())
+    pInfoDict->SetNewFor<CPDF_String>("Title", wsTitle);
+}
+
+void CPDFXFA_DocEnvironment::ExportData(CXFA_FFDoc* hDoc,
+                                        const CFX_WideString& wsFilePath,
+                                        bool bXDP) {
+  if (hDoc != m_pContext->GetXFADoc())
+    return;
+
+  if (m_pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA &&
+      m_pContext->GetDocType() != DOCTYPE_STATIC_XFA) {
+    return;
+  }
+
+  CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
+  if (!pFormFillEnv)
+    return;
+
+  int fileType = bXDP ? FXFA_SAVEAS_XDP : FXFA_SAVEAS_XML;
+  CFX_ByteString bs = wsFilePath.UTF16LE_Encode();
+  if (wsFilePath.IsEmpty()) {
+    if (!pFormFillEnv->GetFormFillInfo() ||
+        !pFormFillEnv->GetFormFillInfo()->m_pJsPlatform) {
+      return;
+    }
+
+    CFX_WideString filepath = pFormFillEnv->JS_fieldBrowse();
+    bs = filepath.UTF16LE_Encode();
+  }
+  int len = bs.GetLength();
+  FPDF_FILEHANDLER* pFileHandler =
+      pFormFillEnv->OpenFile(bXDP ? FXFA_SAVEAS_XDP : FXFA_SAVEAS_XML,
+                             (FPDF_WIDESTRING)bs.GetBuffer(len), "wb");
+  bs.ReleaseBuffer(len);
+  if (!pFileHandler)
+    return;
+
+  CFX_RetainPtr<IFX_SeekableStream> fileWrite =
+      MakeSeekableStream(pFileHandler);
+  CFX_ByteString content;
+  if (fileType == FXFA_SAVEAS_XML) {
+    content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n";
+    fileWrite->WriteBlock(content.c_str(), fileWrite->GetSize(),
+                          content.GetLength());
+    m_pContext->GetXFADocView()->GetDoc()->SavePackage(XFA_HASHCODE_Data,
+                                                       fileWrite, nullptr);
+  } else if (fileType == FXFA_SAVEAS_XDP) {
+    if (!m_pContext->GetPDFDoc())
+      return;
+
+    CPDF_Dictionary* pRoot = m_pContext->GetPDFDoc()->GetRoot();
+    if (!pRoot)
+      return;
+
+    CPDF_Dictionary* pAcroForm = pRoot->GetDictFor("AcroForm");
+    if (!pAcroForm)
+      return;
+
+    CPDF_Array* pArray = ToArray(pAcroForm->GetObjectFor("XFA"));
+    if (!pArray)
+      return;
+
+    int size = pArray->GetCount();
+    for (int i = 1; i < size; i += 2) {
+      CPDF_Object* pPDFObj = pArray->GetObjectAt(i);
+      CPDF_Object* pPrePDFObj = pArray->GetObjectAt(i - 1);
+      if (!pPrePDFObj->IsString())
+        continue;
+      if (!pPDFObj->IsReference())
+        continue;
+
+      CPDF_Stream* pStream = ToStream(pPDFObj->GetDirect());
+      if (!pStream)
+        continue;
+      if (pPrePDFObj->GetString() == "form") {
+        m_pContext->GetXFADocView()->GetDoc()->SavePackage(XFA_HASHCODE_Form,
+                                                           fileWrite, nullptr);
+        continue;
+      }
+      if (pPrePDFObj->GetString() == "datasets") {
+        m_pContext->GetXFADocView()->GetDoc()->SavePackage(
+            XFA_HASHCODE_Datasets, fileWrite, nullptr);
+        continue;
+      }
+      if (i == size - 1) {
+        CFX_WideString wPath = CFX_WideString::FromUTF16LE(
+            reinterpret_cast<const unsigned short*>(bs.c_str()),
+            bs.GetLength() / sizeof(unsigned short));
+        CFX_ByteString bPath = wPath.UTF8Encode();
+        const char* szFormat =
+            "\n<pdf href=\"%s\" xmlns=\"http://ns.adobe.com/xdp/pdf/\"/>";
+        content.Format(szFormat, bPath.c_str());
+        fileWrite->WriteBlock(content.c_str(), fileWrite->GetSize(),
+                              content.GetLength());
+      }
+      std::unique_ptr<CPDF_StreamAcc> pAcc(new CPDF_StreamAcc);
+      pAcc->LoadAllData(pStream);
+      fileWrite->WriteBlock(pAcc->GetData(), fileWrite->GetSize(),
+                            pAcc->GetSize());
+    }
+  }
+  fileWrite->Flush();
+}
+
+void CPDFXFA_DocEnvironment::GotoURL(CXFA_FFDoc* hDoc,
+                                     const CFX_WideString& bsURL) {
+  if (hDoc != m_pContext->GetXFADoc())
+    return;
+
+  if (m_pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA)
+    return;
+
+  CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
+  if (!pFormFillEnv)
+    return;
+
+  CFX_WideStringC str(bsURL.c_str());
+  pFormFillEnv->GotoURL(this, str);
+}
+
+bool CPDFXFA_DocEnvironment::IsValidationsEnabled(CXFA_FFDoc* hDoc) {
+  if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetFormFillEnv())
+    return false;
+  if (m_pContext->GetFormFillEnv()->GetInterForm()) {
+    return m_pContext->GetFormFillEnv()
+        ->GetInterForm()
+        ->IsXfaValidationsEnabled();
+  }
+  return true;
+}
+
+void CPDFXFA_DocEnvironment::SetValidationsEnabled(CXFA_FFDoc* hDoc,
+                                                   bool bEnabled) {
+  if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetFormFillEnv())
+    return;
+  if (m_pContext->GetFormFillEnv()->GetInterForm()) {
+    m_pContext->GetFormFillEnv()->GetInterForm()->XfaSetValidationsEnabled(
+        bEnabled);
+  }
+}
+
+void CPDFXFA_DocEnvironment::SetFocusWidget(CXFA_FFDoc* hDoc,
+                                            CXFA_FFWidget* hWidget) {
+  if (hDoc != m_pContext->GetXFADoc())
+    return;
+
+  if (!hWidget) {
+    CPDFSDK_Annot::ObservedPtr pNull;
+    m_pContext->GetFormFillEnv()->SetFocusAnnot(&pNull);
+    return;
+  }
+
+  int pageViewCount = m_pContext->GetFormFillEnv()->GetPageViewCount();
+  for (int i = 0; i < pageViewCount; i++) {
+    CPDFSDK_PageView* pPageView = m_pContext->GetFormFillEnv()->GetPageView(i);
+    if (!pPageView)
+      continue;
+
+    CPDFSDK_Annot::ObservedPtr pAnnot(pPageView->GetAnnotByXFAWidget(hWidget));
+    if (pAnnot) {
+      m_pContext->GetFormFillEnv()->SetFocusAnnot(&pAnnot);
+      break;
+    }
+  }
+}
+
+void CPDFXFA_DocEnvironment::Print(CXFA_FFDoc* hDoc,
+                                   int32_t nStartPage,
+                                   int32_t nEndPage,
+                                   uint32_t dwOptions) {
+  if (hDoc != m_pContext->GetXFADoc())
+    return;
+
+  CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
+  if (!pFormFillEnv || !pFormFillEnv->GetFormFillInfo() ||
+      !pFormFillEnv->GetFormFillInfo()->m_pJsPlatform ||
+      !pFormFillEnv->GetFormFillInfo()->m_pJsPlatform->Doc_print) {
+    return;
+  }
+
+  pFormFillEnv->GetFormFillInfo()->m_pJsPlatform->Doc_print(
+      pFormFillEnv->GetFormFillInfo()->m_pJsPlatform,
+      dwOptions & XFA_PRINTOPT_ShowDialog, nStartPage, nEndPage,
+      dwOptions & XFA_PRINTOPT_CanCancel, dwOptions & XFA_PRINTOPT_ShrinkPage,
+      dwOptions & XFA_PRINTOPT_AsImage, dwOptions & XFA_PRINTOPT_ReverseOrder,
+      dwOptions & XFA_PRINTOPT_PrintAnnot);
+}
+
+FX_ARGB CPDFXFA_DocEnvironment::GetHighlightColor(CXFA_FFDoc* hDoc) {
+  if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetFormFillEnv())
+    return 0;
+
+  CPDFSDK_InterForm* pInterForm = m_pContext->GetFormFillEnv()->GetInterForm();
+  if (!pInterForm)
+    return 0;
+
+  return ArgbEncode(pInterForm->GetHighlightAlpha(),
+                    pInterForm->GetHighlightColor(FPDF_FORMFIELD_XFA));
+}
+
+bool CPDFXFA_DocEnvironment::NotifySubmit(bool bPrevOrPost) {
+  if (bPrevOrPost)
+    return OnBeforeNotifySubmit();
+
+  OnAfterNotifySubmit();
+  return true;
+}
+
+bool CPDFXFA_DocEnvironment::OnBeforeNotifySubmit() {
+  if (m_pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA &&
+      m_pContext->GetDocType() != DOCTYPE_STATIC_XFA) {
+    return true;
+  }
+
+  if (!m_pContext->GetXFADocView())
+    return true;
+
+  CXFA_FFWidgetHandler* pWidgetHandler =
+      m_pContext->GetXFADocView()->GetWidgetHandler();
+  if (!pWidgetHandler)
+    return true;
+
+  std::unique_ptr<CXFA_WidgetAccIterator> pWidgetAccIterator(
+      m_pContext->GetXFADocView()->CreateWidgetAccIterator());
+  if (pWidgetAccIterator) {
+    CXFA_EventParam Param;
+    Param.m_eType = XFA_EVENT_PreSubmit;
+    while (CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext())
+      pWidgetHandler->ProcessEvent(pWidgetAcc, &Param);
+  }
+
+  pWidgetAccIterator.reset(
+      m_pContext->GetXFADocView()->CreateWidgetAccIterator());
+  if (!pWidgetAccIterator)
+    return true;
+
+  CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext();
+  pWidgetAcc = pWidgetAccIterator->MoveToNext();
+  while (pWidgetAcc) {
+    int fRet = pWidgetAcc->ProcessValidate(-1);
+    if (fRet == XFA_EVENTERROR_Error) {
+      CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
+      if (!pFormFillEnv)
+        return false;
+
+      CFX_WideString ws;
+      ws.FromLocal(IDS_XFA_Validate_Input);
+      CFX_ByteString bs = ws.UTF16LE_Encode();
+      int len = bs.GetLength();
+      pFormFillEnv->Alert((FPDF_WIDESTRING)bs.GetBuffer(len),
+                          (FPDF_WIDESTRING)L"", 0, 1);
+      bs.ReleaseBuffer(len);
+      return false;
+    }
+    pWidgetAcc = pWidgetAccIterator->MoveToNext();
+  }
+  m_pContext->GetXFADocView()->UpdateDocView();
+
+  return true;
+}
+
+void CPDFXFA_DocEnvironment::OnAfterNotifySubmit() {
+  if (m_pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA &&
+      m_pContext->GetDocType() != DOCTYPE_STATIC_XFA)
+    return;
+
+  if (!m_pContext->GetXFADocView())
+    return;
+
+  CXFA_FFWidgetHandler* pWidgetHandler =
+      m_pContext->GetXFADocView()->GetWidgetHandler();
+  if (!pWidgetHandler)
+    return;
+
+  std::unique_ptr<CXFA_WidgetAccIterator> pWidgetAccIterator(
+      m_pContext->GetXFADocView()->CreateWidgetAccIterator());
+  if (!pWidgetAccIterator)
+    return;
+
+  CXFA_EventParam Param;
+  Param.m_eType = XFA_EVENT_PostSubmit;
+  CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext();
+  while (pWidgetAcc) {
+    pWidgetHandler->ProcessEvent(pWidgetAcc, &Param);
+    pWidgetAcc = pWidgetAccIterator->MoveToNext();
+  }
+  m_pContext->GetXFADocView()->UpdateDocView();
+}
+
+bool CPDFXFA_DocEnvironment::SubmitData(CXFA_FFDoc* hDoc, CXFA_Submit submit) {
+  if (!NotifySubmit(true) || !m_pContext->GetXFADocView())
+    return false;
+
+  m_pContext->GetXFADocView()->UpdateDocView();
+  bool ret = SubmitDataInternal(hDoc, submit);
+  NotifySubmit(false);
+  return ret;
+}
+
+CFX_RetainPtr<IFX_SeekableReadStream> CPDFXFA_DocEnvironment::OpenLinkedFile(
+    CXFA_FFDoc* hDoc,
+    const CFX_WideString& wsLink) {
+  CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
+  if (!pFormFillEnv)
+    return nullptr;
+
+  CFX_ByteString bs = wsLink.UTF16LE_Encode();
+  int len = bs.GetLength();
+  FPDF_FILEHANDLER* pFileHandler =
+      pFormFillEnv->OpenFile(0, (FPDF_WIDESTRING)bs.GetBuffer(len), "rb");
+  bs.ReleaseBuffer(len);
+  if (!pFileHandler)
+    return nullptr;
+
+  return MakeSeekableStream(pFileHandler);
+}
+
+bool CPDFXFA_DocEnvironment::ExportSubmitFile(FPDF_FILEHANDLER* pFileHandler,
+                                              int fileType,
+                                              FPDF_DWORD encodeType,
+                                              FPDF_DWORD flag) {
+  if (!m_pContext->GetXFADocView())
+    return false;
+
+  CFX_ByteString content;
+  CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
+  if (!pFormFillEnv)
+    return false;
+
+  CFX_RetainPtr<IFX_SeekableStream> fileStream =
+      MakeSeekableStream(pFileHandler);
+
+  if (fileType == FXFA_SAVEAS_XML) {
+    const char kContent[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n";
+    fileStream->WriteBlock(kContent, 0, strlen(kContent));
+    m_pContext->GetXFADoc()->SavePackage(XFA_HASHCODE_Data, fileStream,
+                                         nullptr);
+    return true;
+  }
+
+  if (fileType != FXFA_SAVEAS_XDP)
+    return true;
+
+  if (!flag) {
+    flag = FXFA_CONFIG | FXFA_TEMPLATE | FXFA_LOCALESET | FXFA_DATASETS |
+           FXFA_XMPMETA | FXFA_XFDF | FXFA_FORM;
+  }
+  if (!m_pContext->GetPDFDoc()) {
+    fileStream->Flush();
+    return false;
+  }
+
+  CPDF_Dictionary* pRoot = m_pContext->GetPDFDoc()->GetRoot();
+  if (!pRoot) {
+    fileStream->Flush();
+    return false;
+  }
+
+  CPDF_Dictionary* pAcroForm = pRoot->GetDictFor("AcroForm");
+  if (!pAcroForm) {
+    fileStream->Flush();
+    return false;
+  }
+
+  CPDF_Array* pArray = ToArray(pAcroForm->GetObjectFor("XFA"));
+  if (!pArray) {
+    fileStream->Flush();
+    return false;
+  }
+
+  int size = pArray->GetCount();
+  for (int i = 1; i < size; i += 2) {
+    CPDF_Object* pPDFObj = pArray->GetObjectAt(i);
+    CPDF_Object* pPrePDFObj = pArray->GetObjectAt(i - 1);
+    if (!pPrePDFObj->IsString())
+      continue;
+    if (!pPDFObj->IsReference())
+      continue;
+
+    CPDF_Object* pDirectObj = pPDFObj->GetDirect();
+    if (!pDirectObj->IsStream())
+      continue;
+    if (pPrePDFObj->GetString() == "config" && !(flag & FXFA_CONFIG))
+      continue;
+    if (pPrePDFObj->GetString() == "template" && !(flag & FXFA_TEMPLATE))
+      continue;
+    if (pPrePDFObj->GetString() == "localeSet" && !(flag & FXFA_LOCALESET))
+      continue;
+    if (pPrePDFObj->GetString() == "datasets" && !(flag & FXFA_DATASETS))
+      continue;
+    if (pPrePDFObj->GetString() == "xmpmeta" && !(flag & FXFA_XMPMETA))
+      continue;
+    if (pPrePDFObj->GetString() == "xfdf" && !(flag & FXFA_XFDF))
+      continue;
+    if (pPrePDFObj->GetString() == "form" && !(flag & FXFA_FORM))
+      continue;
+    if (pPrePDFObj->GetString() == "form") {
+      m_pContext->GetXFADoc()->SavePackage(XFA_HASHCODE_Form, fileStream,
+                                           nullptr);
+    } else if (pPrePDFObj->GetString() == "datasets") {
+      m_pContext->GetXFADoc()->SavePackage(XFA_HASHCODE_Datasets, fileStream,
+                                           nullptr);
+    } else {
+      // PDF,creator.
+    }
+  }
+  return true;
+}
+
+void CPDFXFA_DocEnvironment::ToXFAContentFlags(CFX_WideString csSrcContent,
+                                               FPDF_DWORD& flag) {
+  if (csSrcContent.Find(L" config ", 0) != -1)
+    flag |= FXFA_CONFIG;
+  if (csSrcContent.Find(L" template ", 0) != -1)
+    flag |= FXFA_TEMPLATE;
+  if (csSrcContent.Find(L" localeSet ", 0) != -1)
+    flag |= FXFA_LOCALESET;
+  if (csSrcContent.Find(L" datasets ", 0) != -1)
+    flag |= FXFA_DATASETS;
+  if (csSrcContent.Find(L" xmpmeta ", 0) != -1)
+    flag |= FXFA_XMPMETA;
+  if (csSrcContent.Find(L" xfdf ", 0) != -1)
+    flag |= FXFA_XFDF;
+  if (csSrcContent.Find(L" form ", 0) != -1)
+    flag |= FXFA_FORM;
+  if (flag == 0) {
+    flag = FXFA_CONFIG | FXFA_TEMPLATE | FXFA_LOCALESET | FXFA_DATASETS |
+           FXFA_XMPMETA | FXFA_XFDF | FXFA_FORM;
+  }
+}
+
+bool CPDFXFA_DocEnvironment::MailToInfo(CFX_WideString& csURL,
+                                        CFX_WideString& csToAddress,
+                                        CFX_WideString& csCCAddress,
+                                        CFX_WideString& csBCCAddress,
+                                        CFX_WideString& csSubject,
+                                        CFX_WideString& csMsg) {
+  CFX_WideString srcURL = csURL;
+  srcURL.TrimLeft();
+  if (srcURL.Left(7).CompareNoCase(L"mailto:") != 0)
+    return false;
+
+  int pos = srcURL.Find(L'?', 0);
+  CFX_WideString tmp;
+  if (pos == -1) {
+    pos = srcURL.Find(L'@', 0);
+    if (pos == -1)
+      return false;
+
+    tmp = srcURL.Right(csURL.GetLength() - 7);
+  } else {
+    tmp = srcURL.Left(pos);
+    tmp = tmp.Right(tmp.GetLength() - 7);
+  }
+  tmp.TrimLeft();
+  tmp.TrimRight();
+
+  csToAddress = tmp;
+
+  srcURL = srcURL.Right(srcURL.GetLength() - (pos + 1));
+  while (!srcURL.IsEmpty()) {
+    srcURL.TrimLeft();
+    srcURL.TrimRight();
+    pos = srcURL.Find(L'&', 0);
+
+    tmp = (pos == -1) ? srcURL : srcURL.Left(pos);
+    tmp.TrimLeft();
+    tmp.TrimRight();
+    if (tmp.GetLength() >= 3 && tmp.Left(3).CompareNoCase(L"cc=") == 0) {
+      tmp = tmp.Right(tmp.GetLength() - 3);
+      if (!csCCAddress.IsEmpty())
+        csCCAddress += L';';
+      csCCAddress += tmp;
+    } else if (tmp.GetLength() >= 4 &&
+               tmp.Left(4).CompareNoCase(L"bcc=") == 0) {
+      tmp = tmp.Right(tmp.GetLength() - 4);
+      if (!csBCCAddress.IsEmpty())
+        csBCCAddress += L';';
+      csBCCAddress += tmp;
+    } else if (tmp.GetLength() >= 8 &&
+               tmp.Left(8).CompareNoCase(L"subject=") == 0) {
+      tmp = tmp.Right(tmp.GetLength() - 8);
+      csSubject += tmp;
+    } else if (tmp.GetLength() >= 5 &&
+               tmp.Left(5).CompareNoCase(L"body=") == 0) {
+      tmp = tmp.Right(tmp.GetLength() - 5);
+      csMsg += tmp;
+    }
+    srcURL = (pos == -1) ? L"" : srcURL.Right(csURL.GetLength() - (pos + 1));
+  }
+  csToAddress.Replace(L",", L";");
+  csCCAddress.Replace(L",", L";");
+  csBCCAddress.Replace(L",", L";");
+  return true;
+}
+
+bool CPDFXFA_DocEnvironment::SubmitDataInternal(CXFA_FFDoc* hDoc,
+                                                CXFA_Submit submit) {
+  CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
+  if (!pFormFillEnv)
+    return false;
+
+  CFX_WideStringC csURLC;
+  submit.GetSubmitTarget(csURLC);
+  CFX_WideString csURL(csURLC);
+  if (csURL.IsEmpty()) {
+    CFX_WideString ws;
+    ws.FromLocal("Submit cancelled.");
+    CFX_ByteString bs = ws.UTF16LE_Encode();
+    int len = bs.GetLength();
+    pFormFillEnv->Alert((FPDF_WIDESTRING)bs.GetBuffer(len),
+                        (FPDF_WIDESTRING)L"", 0, 4);
+    bs.ReleaseBuffer(len);
+    return false;
+  }
+
+  FPDF_FILEHANDLER* pFileHandler = nullptr;
+  int fileFlag = -1;
+  switch (submit.GetSubmitFormat()) {
+    case XFA_ATTRIBUTEENUM_Xdp: {
+      CFX_WideStringC csContentC;
+      submit.GetSubmitXDPContent(csContentC);
+      CFX_WideString csContent;
+      csContent = csContentC;
+      csContent.TrimLeft();
+      csContent.TrimRight();
+      CFX_WideString space;
+      space.FromLocal(" ");
+      csContent = space + csContent + space;
+      FPDF_DWORD flag = 0;
+      if (submit.IsSubmitEmbedPDF())
+        flag |= FXFA_PDF;
+
+      ToXFAContentFlags(csContent, flag);
+      pFileHandler = pFormFillEnv->OpenFile(FXFA_SAVEAS_XDP, nullptr, "wb");
+      fileFlag = FXFA_SAVEAS_XDP;
+      ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XDP, 0, flag);
+      break;
+    }
+    case XFA_ATTRIBUTEENUM_Xml:
+      pFileHandler = pFormFillEnv->OpenFile(FXFA_SAVEAS_XML, nullptr, "wb");
+      fileFlag = FXFA_SAVEAS_XML;
+      ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XML, 0, FXFA_XFA_ALL);
+      break;
+    case XFA_ATTRIBUTEENUM_Pdf:
+      break;
+    case XFA_ATTRIBUTEENUM_Urlencoded:
+      pFileHandler = pFormFillEnv->OpenFile(FXFA_SAVEAS_XML, nullptr, "wb");
+      fileFlag = FXFA_SAVEAS_XML;
+      ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XML, 0, FXFA_XFA_ALL);
+      break;
+    default:
+      return false;
+  }
+  if (!pFileHandler)
+    return false;
+  if (csURL.Left(7).CompareNoCase(L"mailto:") == 0) {
+    CFX_WideString csToAddress;
+    CFX_WideString csCCAddress;
+    CFX_WideString csBCCAddress;
+    CFX_WideString csSubject;
+    CFX_WideString csMsg;
+    if (!MailToInfo(csURL, csToAddress, csCCAddress, csBCCAddress, csSubject,
+                    csMsg)) {
+      return false;
+    }
+    CFX_ByteString bsTo = CFX_WideString(csToAddress).UTF16LE_Encode();
+    CFX_ByteString bsCC = CFX_WideString(csCCAddress).UTF16LE_Encode();
+    CFX_ByteString bsBcc = CFX_WideString(csBCCAddress).UTF16LE_Encode();
+    CFX_ByteString bsSubject = CFX_WideString(csSubject).UTF16LE_Encode();
+    CFX_ByteString bsMsg = CFX_WideString(csMsg).UTF16LE_Encode();
+    FPDF_WIDESTRING pTo = (FPDF_WIDESTRING)bsTo.GetBuffer(bsTo.GetLength());
+    FPDF_WIDESTRING pCC = (FPDF_WIDESTRING)bsCC.GetBuffer(bsCC.GetLength());
+    FPDF_WIDESTRING pBcc = (FPDF_WIDESTRING)bsBcc.GetBuffer(bsBcc.GetLength());
+    FPDF_WIDESTRING pSubject =
+        (FPDF_WIDESTRING)bsSubject.GetBuffer(bsSubject.GetLength());
+    FPDF_WIDESTRING pMsg = (FPDF_WIDESTRING)bsMsg.GetBuffer(bsMsg.GetLength());
+    pFormFillEnv->EmailTo(pFileHandler, pTo, pSubject, pCC, pBcc, pMsg);
+    bsTo.ReleaseBuffer();
+    bsCC.ReleaseBuffer();
+    bsBcc.ReleaseBuffer();
+    bsSubject.ReleaseBuffer();
+    bsMsg.ReleaseBuffer();
+  } else {
+    // HTTP or FTP
+    CFX_WideString ws;
+    CFX_ByteString bs = csURL.UTF16LE_Encode();
+    int len = bs.GetLength();
+    pFormFillEnv->UploadTo(pFileHandler, fileFlag,
+                           (FPDF_WIDESTRING)bs.GetBuffer(len));
+    bs.ReleaseBuffer(len);
+  }
+  return true;
+}
+
+bool CPDFXFA_DocEnvironment::SetGlobalProperty(
+    CXFA_FFDoc* hDoc,
+    const CFX_ByteStringC& szPropName,
+    CFXJSE_Value* pValue) {
+  if (hDoc != m_pContext->GetXFADoc())
+    return false;
+
+  if (m_pContext->GetFormFillEnv() &&
+      m_pContext->GetFormFillEnv()->GetJSRuntime()) {
+    return m_pContext->GetFormFillEnv()->GetJSRuntime()->SetValueByName(
+        szPropName, pValue);
+  }
+  return false;
+}
+
+bool CPDFXFA_DocEnvironment::GetGlobalProperty(
+    CXFA_FFDoc* hDoc,
+    const CFX_ByteStringC& szPropName,
+    CFXJSE_Value* pValue) {
+  if (hDoc != m_pContext->GetXFADoc())
+    return false;
+  if (!m_pContext->GetFormFillEnv() ||
+      !m_pContext->GetFormFillEnv()->GetJSRuntime()) {
+    return false;
+  }
+
+  CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
+  if (!m_pJSContext)
+    m_pJSContext = pFormFillEnv->GetJSRuntime()->NewContext();
+
+  return pFormFillEnv->GetJSRuntime()->GetValueByName(szPropName, pValue);
+}
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.h b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.h
new file mode 100644
index 0000000..d7cb169
--- /dev/null
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.h
@@ -0,0 +1,114 @@
+// 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_FPDFXFA_CPDFXFA_DOCENVIRONMENT_H_
+#define FPDFSDK_FPDFXFA_CPDFXFA_DOCENVIRONMENT_H_
+
+#include "core/fxcrt/cfx_retain_ptr.h"
+#include "public/fpdfview.h"
+#include "xfa/fxfa/fxfa.h"
+
+class CPDFXFA_Context;
+class IJS_Context;
+
+class CPDFXFA_DocEnvironment : public IXFA_DocEnvironment {
+ public:
+  explicit CPDFXFA_DocEnvironment(CPDFXFA_Context*);
+  ~CPDFXFA_DocEnvironment() override;
+
+  // IXFA_DocEnvironment
+  void SetChangeMark(CXFA_FFDoc* hDoc) override;
+  // used in dynamic xfa, dwFlags refer to XFA_INVALIDATE_XXX macros.
+  void InvalidateRect(CXFA_FFPageView* pPageView,
+                      const CFX_RectF& rt,
+                      uint32_t dwFlags) override;
+  // show or hide caret
+  void DisplayCaret(CXFA_FFWidget* hWidget,
+                    bool bVisible,
+                    const CFX_RectF* pRtAnchor) override;
+  // dwPos: (0:bottom 1:top)
+  bool GetPopupPos(CXFA_FFWidget* hWidget,
+                   FX_FLOAT fMinPopup,
+                   FX_FLOAT fMaxPopup,
+                   const CFX_RectF& rtAnchor,
+                   CFX_RectF& rtPopup) override;
+  bool PopupMenu(CXFA_FFWidget* hWidget, CFX_PointF ptPopup) override;
+
+  // dwFlags XFA_PAGEVIEWEVENT_Added, XFA_PAGEVIEWEVENT_Removing
+  void PageViewEvent(CXFA_FFPageView* pPageView, uint32_t dwFlags) override;
+  void WidgetPostAdd(CXFA_FFWidget* hWidget,
+                     CXFA_WidgetAcc* pWidgetData) override;
+  void WidgetPreRemove(CXFA_FFWidget* hWidget,
+                       CXFA_WidgetAcc* pWidgetData) override;
+
+  // Host method
+  int32_t CountPages(CXFA_FFDoc* hDoc) override;
+  int32_t GetCurrentPage(CXFA_FFDoc* hDoc) override;
+  void SetCurrentPage(CXFA_FFDoc* hDoc, int32_t iCurPage) override;
+  bool IsCalculationsEnabled(CXFA_FFDoc* hDoc) override;
+  void SetCalculationsEnabled(CXFA_FFDoc* hDoc, bool bEnabled) override;
+  void GetTitle(CXFA_FFDoc* hDoc, CFX_WideString& wsTitle) override;
+  void SetTitle(CXFA_FFDoc* hDoc, const CFX_WideString& wsTitle) override;
+  void ExportData(CXFA_FFDoc* hDoc,
+                  const CFX_WideString& wsFilePath,
+                  bool bXDP) override;
+  void GotoURL(CXFA_FFDoc* hDoc, const CFX_WideString& bsURL) override;
+  bool IsValidationsEnabled(CXFA_FFDoc* hDoc) override;
+  void SetValidationsEnabled(CXFA_FFDoc* hDoc, bool bEnabled) override;
+  void SetFocusWidget(CXFA_FFDoc* hDoc, CXFA_FFWidget* hWidget) override;
+  void Print(CXFA_FFDoc* hDoc,
+             int32_t nStartPage,
+             int32_t nEndPage,
+             uint32_t dwOptions) override;
+  FX_ARGB GetHighlightColor(CXFA_FFDoc* hDoc) override;
+
+  /**
+   *Submit data to email, http, ftp.
+   * @param[in] hDoc The document handler.
+   * @param[in] eFormat Determines the format in which the data will be
+   *submitted. XFA_ATTRIBUTEENUM_Xdp, XFA_ATTRIBUTEENUM_Xml...
+   * @param[in] wsTarget The URL to which the data will be submitted.
+   * @param[in] eEncoding The encoding of text content.
+   * @param[in] pXDPContent Controls what subset of the data is submitted, used
+   *only when the format property is xdp.
+   * @param[in] bEmbedPDF, specifies whether PDF is embedded in the submitted
+   *content or not.
+   */
+  bool SubmitData(CXFA_FFDoc* hDoc, CXFA_Submit submit) override;
+
+  bool GetGlobalProperty(CXFA_FFDoc* hDoc,
+                         const CFX_ByteStringC& szPropName,
+                         CFXJSE_Value* pValue) override;
+  bool SetGlobalProperty(CXFA_FFDoc* hDoc,
+                         const CFX_ByteStringC& szPropName,
+                         CFXJSE_Value* pValue) override;
+
+  CFX_RetainPtr<IFX_SeekableReadStream> OpenLinkedFile(
+      CXFA_FFDoc* hDoc,
+      const CFX_WideString& wsLink) override;
+
+ private:
+  bool OnBeforeNotifySubmit();
+  void OnAfterNotifySubmit();
+  bool NotifySubmit(bool bPrevOrPost);
+  bool SubmitDataInternal(CXFA_FFDoc* hDoc, CXFA_Submit submit);
+  bool MailToInfo(CFX_WideString& csURL,
+                  CFX_WideString& csToAddress,
+                  CFX_WideString& csCCAddress,
+                  CFX_WideString& csBCCAddress,
+                  CFX_WideString& csSubject,
+                  CFX_WideString& csMsg);
+  bool ExportSubmitFile(FPDF_FILEHANDLER* ppFileHandler,
+                        int fileType,
+                        FPDF_DWORD encodeType,
+                        FPDF_DWORD flag);
+  void ToXFAContentFlags(CFX_WideString csSrcContent, FPDF_DWORD& flag);
+
+  CPDFXFA_Context* const m_pContext;  // Not owned;
+  IJS_Context* m_pJSContext;
+};
+
+#endif  // FPDFSDK_FPDFXFA_CPDFXFA_DOCENVIRONMENT_H_
diff --git a/fpdfsdk/src/fpdfxfa/fpdfxfa_page.cpp b/fpdfsdk/fpdfxfa/cpdfxfa_page.cpp
similarity index 63%
rename from fpdfsdk/src/fpdfxfa/fpdfxfa_page.cpp
rename to fpdfsdk/fpdfxfa/cpdfxfa_page.cpp
index dec9e95..8cc3250 100644
--- a/fpdfsdk/src/fpdfxfa/fpdfxfa_page.cpp
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_page.cpp
@@ -1,255 +1,224 @@
-// 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

-

-#include "fpdfsdk/include/fsdk_define.h"

-#include "fpdfsdk/include/fsdk_mgr.h"

-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h"

-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h"

-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_page.h"

-

-CPDFXFA_Page::CPDFXFA_Page(CPDFXFA_Document* pDoc, int page_index)

-    : m_pPDFPage(NULL),

-      m_pXFAPageView(NULL),

-      m_iPageIndex(page_index),

-      m_pDocument(pDoc),

-      m_iRef(1) {}

-

-CPDFXFA_Page::~CPDFXFA_Page() {

-  if (m_pPDFPage)

-    delete m_pPDFPage;

-  m_pPDFPage = NULL;

-  m_pXFAPageView = NULL;

-}

-

-void CPDFXFA_Page::Release() {

-  m_iRef--;

-  if (m_iRef > 0)

-    return;

-

-  if (m_pDocument)

-    m_pDocument->RemovePage(this);

-

-  delete this;

-}

-

-FX_BOOL CPDFXFA_Page::LoadPDFPage() {

-  if (!m_pDocument)

-    return FALSE;

-  CPDF_Document* pPDFDoc = m_pDocument->GetPDFDoc();

-  if (pPDFDoc) {

-    CPDF_Dictionary* pDict = pPDFDoc->GetPage(m_iPageIndex);

-    if (pDict == NULL)

-      return FALSE;

-    if (m_pPDFPage) {

-      if (m_pPDFPage->m_pFormDict == pDict)

-        return TRUE;

-

-      delete m_pPDFPage;

-      m_pPDFPage = NULL;

-    }

-

-    m_pPDFPage = new CPDF_Page;

-    m_pPDFPage->Load(pPDFDoc, pDict);

-    m_pPDFPage->ParseContent();

-    return TRUE;

-  }

-

-  return FALSE;

-}

-

-FX_BOOL CPDFXFA_Page::LoadXFAPageView() {

-  if (!m_pDocument)

-    return FALSE;

-  IXFA_Doc* pXFADoc = m_pDocument->GetXFADoc();

-  if (!pXFADoc)

-    return FALSE;

-

-  IXFA_DocView* pXFADocView = m_pDocument->GetXFADocView();

-  if (!pXFADocView)

-    return FALSE;

-

-  IXFA_PageView* pPageView = pXFADocView->GetPageView(m_iPageIndex);

-  if (!pPageView)

-    return FALSE;

-

-  if (m_pXFAPageView == pPageView)

-    return TRUE;

-

-  m_pXFAPageView = pPageView;

-  (void)m_pXFAPageView->LoadPageView(nullptr);

-  return TRUE;

-}

-

-FX_BOOL CPDFXFA_Page::LoadPage() {

-  if (!m_pDocument || m_iPageIndex < 0)

-    return FALSE;

-

-  int iDocType = m_pDocument->GetDocType();

-  switch (iDocType) {

-    case DOCTYPE_PDF:

-    case DOCTYPE_STATIC_XFA: {

-      return LoadPDFPage();

-    }

-    case DOCTYPE_DYNAMIC_XFA: {

-      return LoadXFAPageView();

-    }

-    default:

-      return FALSE;

-  }

-

-  return FALSE;

-}

-

-FX_BOOL CPDFXFA_Page::LoadPDFPage(CPDF_Dictionary* pageDict) {

-  if (!m_pDocument || m_iPageIndex < 0 || !pageDict)

-    return FALSE;

-

-  if (m_pPDFPage)

-    delete m_pPDFPage;

-

-  m_pPDFPage = new CPDF_Page();

-  m_pPDFPage->Load(m_pDocument->GetPDFDoc(), pageDict);

-  m_pPDFPage->ParseContent();

-

-  return TRUE;

-}

-

-FX_FLOAT CPDFXFA_Page::GetPageWidth() {

-  ASSERT(m_pDocument != NULL);

-

-  if (!m_pPDFPage && !m_pXFAPageView)

-    return 0.0f;

-

-  int nDocType = m_pDocument->GetDocType();

-  switch (nDocType) {

-    case DOCTYPE_DYNAMIC_XFA: {

-      if (m_pXFAPageView) {

-        CFX_RectF rect;

-        m_pXFAPageView->GetPageViewRect(rect);

-        return rect.width;

-      }

-    } break;

-    case DOCTYPE_STATIC_XFA:

-    case DOCTYPE_PDF: {

-      if (m_pPDFPage)

-        return m_pPDFPage->GetPageWidth();

-    } break;

-    default:

-      return 0.0f;

-  }

-

-  return 0.0f;

-}

-

-FX_FLOAT CPDFXFA_Page::GetPageHeight() {

-  ASSERT(m_pDocument != NULL);

-

-  if (!m_pPDFPage && !m_pXFAPageView)

-    return 0.0f;

-

-  int nDocType = m_pDocument->GetDocType();

-  switch (nDocType) {

-    case DOCTYPE_PDF:

-    case DOCTYPE_STATIC_XFA: {

-      if (m_pPDFPage)

-        return m_pPDFPage->GetPageHeight();

-    } break;

-    case DOCTYPE_DYNAMIC_XFA: {

-      if (m_pXFAPageView) {

-        CFX_RectF rect;

-        m_pXFAPageView->GetPageViewRect(rect);

-        return rect.height;

-      }

-    } break;

-    default:

-      return 0.0f;

-  }

-

-  return 0.0f;

-}

-

-void CPDFXFA_Page::DeviceToPage(int start_x,

-                                int start_y,

-                                int size_x,

-                                int size_y,

-                                int rotate,

-                                int device_x,

-                                int device_y,

-                                double* page_x,

-                                double* page_y) {

-  ASSERT(m_pDocument != NULL);

-

-  if (!m_pPDFPage && !m_pXFAPageView)

-    return;

-

-  CFX_Matrix page2device;

-  CFX_Matrix device2page;

-  FX_FLOAT page_x_f, page_y_f;

-

-  GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, rotate);

-

-  device2page.SetReverse(page2device);

-  device2page.Transform((FX_FLOAT)(device_x), (FX_FLOAT)(device_y), page_x_f,

-                        page_y_f);

-

-  *page_x = (page_x_f);

-  *page_y = (page_y_f);

-}

-

-void CPDFXFA_Page::PageToDevice(int start_x,

-                                int start_y,

-                                int size_x,

-                                int size_y,

-                                int rotate,

-                                double page_x,

-                                double page_y,

-                                int* device_x,

-                                int* device_y) {

-  if (!m_pPDFPage && !m_pXFAPageView)

-    return;

-

-  CFX_Matrix page2device;

-  FX_FLOAT device_x_f, device_y_f;

-

-  GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, rotate);

-

-  page2device.Transform(((FX_FLOAT)page_x), ((FX_FLOAT)page_y), device_x_f,

-                        device_y_f);

-

-  *device_x = FXSYS_round(device_x_f);

-  *device_y = FXSYS_round(device_y_f);

-}

-

-void CPDFXFA_Page::GetDisplayMatrix(CFX_Matrix& matrix,

-                                    int xPos,

-                                    int yPos,

-                                    int xSize,

-                                    int ySize,

-                                    int iRotate) const {

-  ASSERT(m_pDocument != NULL);

-

-  if (!m_pPDFPage && !m_pXFAPageView)

-    return;

-

-  int nDocType = m_pDocument->GetDocType();

-  switch (nDocType) {

-    case DOCTYPE_DYNAMIC_XFA: {

-      if (m_pXFAPageView) {

-        CFX_Rect rect;

-        rect.Set(xPos, yPos, xSize, ySize);

-        m_pXFAPageView->GetDisplayMatrix(matrix, rect, iRotate);

-      }

-    } break;

-    case DOCTYPE_PDF:

-    case DOCTYPE_STATIC_XFA: {

-      if (m_pPDFPage) {

-        m_pPDFPage->GetDisplayMatrix(matrix, xPos, yPos, xSize, ySize, iRotate);

-      }

-    } break;

-    default:

-      return;

-  }

-}

+// 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
+
+#include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
+
+#include "core/fpdfapi/page/cpdf_page.h"
+#include "core/fpdfapi/parser/cpdf_document.h"
+#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
+#include "fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h"
+#include "fpdfsdk/fsdk_define.h"
+#include "public/fpdf_formfill.h"
+#include "third_party/base/ptr_util.h"
+#include "xfa/fxfa/xfa_ffdocview.h"
+#include "xfa/fxfa/xfa_ffpageview.h"
+
+CPDFXFA_Page::CPDFXFA_Page(CPDFXFA_Context* pContext, int page_index)
+    : m_pXFAPageView(nullptr),
+      m_pContext(pContext),
+      m_iPageIndex(page_index),
+      m_iRef(1) {}
+
+CPDFXFA_Page::~CPDFXFA_Page() {
+  if (m_pContext)
+    m_pContext->RemovePage(this);
+}
+
+bool CPDFXFA_Page::LoadPDFPage() {
+  if (!m_pContext)
+    return false;
+
+  CPDF_Document* pPDFDoc = m_pContext->GetPDFDoc();
+  if (!pPDFDoc)
+    return false;
+
+  CPDF_Dictionary* pDict = pPDFDoc->GetPage(m_iPageIndex);
+  if (!pDict)
+    return false;
+
+  if (!m_pPDFPage || m_pPDFPage->m_pFormDict != pDict) {
+    m_pPDFPage = pdfium::MakeUnique<CPDF_Page>(pPDFDoc, pDict, true);
+    m_pPDFPage->ParseContent();
+  }
+  return true;
+}
+
+bool CPDFXFA_Page::LoadXFAPageView() {
+  if (!m_pContext)
+    return false;
+
+  CXFA_FFDoc* pXFADoc = m_pContext->GetXFADoc();
+  if (!pXFADoc)
+    return false;
+
+  CXFA_FFDocView* pXFADocView = m_pContext->GetXFADocView();
+  if (!pXFADocView)
+    return false;
+
+  CXFA_FFPageView* pPageView = pXFADocView->GetPageView(m_iPageIndex);
+  if (!pPageView)
+    return false;
+
+  m_pXFAPageView = pPageView;
+  return true;
+}
+
+bool CPDFXFA_Page::LoadPage() {
+  if (!m_pContext || m_iPageIndex < 0)
+    return false;
+
+  int iDocType = m_pContext->GetDocType();
+  switch (iDocType) {
+    case DOCTYPE_PDF:
+    case DOCTYPE_STATIC_XFA: {
+      return LoadPDFPage();
+    }
+    case DOCTYPE_DYNAMIC_XFA: {
+      return LoadXFAPageView();
+    }
+    default:
+      return false;
+  }
+}
+
+bool CPDFXFA_Page::LoadPDFPage(CPDF_Dictionary* pageDict) {
+  if (!m_pContext || m_iPageIndex < 0 || !pageDict)
+    return false;
+
+  m_pPDFPage =
+      pdfium::MakeUnique<CPDF_Page>(m_pContext->GetPDFDoc(), pageDict, true);
+  m_pPDFPage->ParseContent();
+  return true;
+}
+
+FX_FLOAT CPDFXFA_Page::GetPageWidth() const {
+  if (!m_pPDFPage && !m_pXFAPageView)
+    return 0.0f;
+
+  int nDocType = m_pContext->GetDocType();
+  switch (nDocType) {
+    case DOCTYPE_DYNAMIC_XFA: {
+      if (m_pXFAPageView) {
+        CFX_RectF rect;
+        m_pXFAPageView->GetPageViewRect(rect);
+        return rect.width;
+      }
+    } break;
+    case DOCTYPE_STATIC_XFA:
+    case DOCTYPE_PDF: {
+      if (m_pPDFPage)
+        return m_pPDFPage->GetPageWidth();
+    } break;
+    default:
+      return 0.0f;
+  }
+
+  return 0.0f;
+}
+
+FX_FLOAT CPDFXFA_Page::GetPageHeight() const {
+  if (!m_pPDFPage && !m_pXFAPageView)
+    return 0.0f;
+
+  int nDocType = m_pContext->GetDocType();
+  switch (nDocType) {
+    case DOCTYPE_PDF:
+    case DOCTYPE_STATIC_XFA: {
+      if (m_pPDFPage)
+        return m_pPDFPage->GetPageHeight();
+    } break;
+    case DOCTYPE_DYNAMIC_XFA: {
+      if (m_pXFAPageView) {
+        CFX_RectF rect;
+        m_pXFAPageView->GetPageViewRect(rect);
+        return rect.height;
+      }
+    } break;
+    default:
+      return 0.0f;
+  }
+
+  return 0.0f;
+}
+
+void CPDFXFA_Page::DeviceToPage(int start_x,
+                                int start_y,
+                                int size_x,
+                                int size_y,
+                                int rotate,
+                                int device_x,
+                                int device_y,
+                                double* page_x,
+                                double* page_y) {
+  if (!m_pPDFPage && !m_pXFAPageView)
+    return;
+
+  CFX_Matrix page2device;
+  CFX_Matrix device2page;
+  FX_FLOAT page_x_f, page_y_f;
+
+  GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, rotate);
+
+  device2page.SetReverse(page2device);
+  device2page.Transform((FX_FLOAT)(device_x), (FX_FLOAT)(device_y), page_x_f,
+                        page_y_f);
+
+  *page_x = (page_x_f);
+  *page_y = (page_y_f);
+}
+
+void CPDFXFA_Page::PageToDevice(int start_x,
+                                int start_y,
+                                int size_x,
+                                int size_y,
+                                int rotate,
+                                double page_x,
+                                double page_y,
+                                int* device_x,
+                                int* device_y) {
+  if (!m_pPDFPage && !m_pXFAPageView)
+    return;
+
+  CFX_Matrix page2device;
+  FX_FLOAT device_x_f, device_y_f;
+
+  GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, rotate);
+
+  page2device.Transform(((FX_FLOAT)page_x), ((FX_FLOAT)page_y), device_x_f,
+                        device_y_f);
+
+  *device_x = FXSYS_round(device_x_f);
+  *device_y = FXSYS_round(device_y_f);
+}
+
+void CPDFXFA_Page::GetDisplayMatrix(CFX_Matrix& matrix,
+                                    int xPos,
+                                    int yPos,
+                                    int xSize,
+                                    int ySize,
+                                    int iRotate) const {
+  if (!m_pPDFPage && !m_pXFAPageView)
+    return;
+
+  int nDocType = m_pContext->GetDocType();
+  switch (nDocType) {
+    case DOCTYPE_DYNAMIC_XFA: {
+      if (m_pXFAPageView) {
+        CFX_Rect rect;
+        rect.Set(xPos, yPos, xSize, ySize);
+        m_pXFAPageView->GetDisplayMatrix(matrix, rect, iRotate);
+      }
+    } break;
+    case DOCTYPE_PDF:
+    case DOCTYPE_STATIC_XFA: {
+      if (m_pPDFPage) {
+        m_pPDFPage->GetDisplayMatrix(matrix, xPos, yPos, xSize, ySize, iRotate);
+      }
+    } break;
+    default:
+      return;
+  }
+}
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_page.h b/fpdfsdk/fpdfxfa/cpdfxfa_page.h
new file mode 100644
index 0000000..79158f4
--- /dev/null
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_page.h
@@ -0,0 +1,85 @@
+// 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_FPDFXFA_CPDFXFA_PAGE_H_
+#define FPDFSDK_FPDFXFA_CPDFXFA_PAGE_H_
+
+#include <memory>
+
+#include "core/fxcrt/fx_system.h"
+
+class CFX_Matrix;
+class CPDFXFA_Context;
+class CPDF_Dictionary;
+class CPDF_Page;
+class CXFA_FFPageView;
+
+class CPDFXFA_Page {
+ public:
+  CPDFXFA_Page(CPDFXFA_Context* pContext, int page_index);
+
+  void Retain() { m_iRef++; }
+  void Release() {
+    if (--m_iRef <= 0)
+      delete this;
+  }
+
+  bool LoadPage();
+  bool LoadPDFPage(CPDF_Dictionary* pageDict);
+  CPDFXFA_Context* GetContext() const { return m_pContext; }
+  int GetPageIndex() const { return m_iPageIndex; }
+  CPDF_Page* GetPDFPage() const { return m_pPDFPage.get(); }
+  CXFA_FFPageView* GetXFAPageView() const { return m_pXFAPageView; }
+
+  void SetXFAPageView(CXFA_FFPageView* pPageView) {
+    m_pXFAPageView = pPageView;
+  }
+
+  FX_FLOAT GetPageWidth() const;
+  FX_FLOAT GetPageHeight() const;
+
+  void DeviceToPage(int start_x,
+                    int start_y,
+                    int size_x,
+                    int size_y,
+                    int rotate,
+                    int device_x,
+                    int device_y,
+                    double* page_x,
+                    double* page_y);
+  void PageToDevice(int start_x,
+                    int start_y,
+                    int size_x,
+                    int size_y,
+                    int rotate,
+                    double page_x,
+                    double page_y,
+                    int* device_x,
+                    int* device_y);
+
+  void GetDisplayMatrix(CFX_Matrix& matrix,
+                        int xPos,
+                        int yPos,
+                        int xSize,
+                        int ySize,
+                        int iRotate) const;
+
+ protected:
+  // Refcounted class.
+  ~CPDFXFA_Page();
+
+  bool LoadPDFPage();
+  bool LoadXFAPageView();
+
+ private:
+  std::unique_ptr<CPDF_Page> m_pPDFPage;
+  CXFA_FFPageView* m_pXFAPageView;
+  CPDFXFA_Context* const m_pContext;
+  const int m_iPageIndex;
+  int m_iRef;
+};
+
+#endif  // FPDFSDK_FPDFXFA_CPDFXFA_PAGE_H_
diff --git a/fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.cpp b/fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.cpp
new file mode 100644
index 0000000..39aa72b
--- /dev/null
+++ b/fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.cpp
@@ -0,0 +1,77 @@
+// 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
+
+#include "fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h"
+
+#include <utility>
+#include <vector>
+
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/fsdk_define.h"
+
+namespace {
+
+class CFWL_FWLAdapterTimerInfo : public CFWL_TimerInfo {
+ public:
+  CFWL_FWLAdapterTimerInfo(IFWL_AdapterTimerMgr* mgr,
+                           int32_t event,
+                           CFWL_Timer* timer)
+      : CFWL_TimerInfo(mgr), idEvent(event), pTimer(timer) {}
+
+  int32_t idEvent;
+  CFWL_Timer* pTimer;
+};
+
+}  // namespace
+
+std::vector<CFWL_TimerInfo*>* CXFA_FWLAdapterTimerMgr::s_TimerArray = nullptr;
+
+void CXFA_FWLAdapterTimerMgr::Start(CFWL_Timer* pTimer,
+                                    uint32_t dwElapse,
+                                    bool bImmediately,
+                                    CFWL_TimerInfo** pTimerInfo) {
+  if (!m_pFormFillEnv)
+    return;
+
+  int32_t id_event = m_pFormFillEnv->SetTimer(dwElapse, TimerProc);
+  if (!s_TimerArray)
+    s_TimerArray = new std::vector<CFWL_TimerInfo*>;
+
+  *pTimerInfo = new CFWL_FWLAdapterTimerInfo(this, id_event, pTimer);
+  s_TimerArray->push_back(*pTimerInfo);
+}
+
+void CXFA_FWLAdapterTimerMgr::Stop(CFWL_TimerInfo* pTimerInfo) {
+  if (!pTimerInfo || !m_pFormFillEnv)
+    return;
+
+  CFWL_FWLAdapterTimerInfo* pInfo =
+      static_cast<CFWL_FWLAdapterTimerInfo*>(pTimerInfo);
+  m_pFormFillEnv->KillTimer(pInfo->idEvent);
+  if (!s_TimerArray)
+    return;
+
+  auto it = std::find(s_TimerArray->begin(), s_TimerArray->end(), pInfo);
+  if (it != s_TimerArray->end()) {
+    s_TimerArray->erase(it);
+    delete pInfo;
+  }
+}
+
+// static
+void CXFA_FWLAdapterTimerMgr::TimerProc(int32_t idEvent) {
+  if (!s_TimerArray)
+    return;
+
+  for (const auto info : *s_TimerArray) {
+    CFWL_FWLAdapterTimerInfo* pInfo =
+        static_cast<CFWL_FWLAdapterTimerInfo*>(info);
+    if (pInfo->idEvent == idEvent) {
+      pInfo->pTimer->Run(pInfo);
+      break;
+    }
+  }
+}
diff --git a/fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h b/fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h
new file mode 100644
index 0000000..fdb5635
--- /dev/null
+++ b/fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h
@@ -0,0 +1,35 @@
+// 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_FPDFXFA_CXFA_FWLADAPTERTIMERMGR_H_
+#define FPDFSDK_FPDFXFA_CXFA_FWLADAPTERTIMERMGR_H_
+
+#include <memory>
+#include <vector>
+
+#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
+#include "xfa/fwl/cfwl_timerinfo.h"
+#include "xfa/fwl/ifwl_adaptertimermgr.h"
+
+class CXFA_FWLAdapterTimerMgr : public IFWL_AdapterTimerMgr {
+ public:
+  explicit CXFA_FWLAdapterTimerMgr(CPDFSDK_FormFillEnvironment* pFormFillEnv)
+      : m_pFormFillEnv(pFormFillEnv) {}
+
+  void Start(CFWL_Timer* pTimer,
+             uint32_t dwElapse,
+             bool bImmediately,
+             CFWL_TimerInfo** pTimerInfo) override;
+  void Stop(CFWL_TimerInfo* pTimerInfo) override;
+
+ protected:
+  static void TimerProc(int32_t idEvent);
+
+  static std::vector<CFWL_TimerInfo*>* s_TimerArray;
+  CPDFSDK_FormFillEnvironment* const m_pFormFillEnv;
+};
+
+#endif  // FPDFSDK_FPDFXFA_CXFA_FWLADAPTERTIMERMGR_H_
diff --git a/fpdfsdk/fsdk_actionhandler.cpp b/fpdfsdk/fsdk_actionhandler.cpp
new file mode 100644
index 0000000..61d2a52
--- /dev/null
+++ b/fpdfsdk/fsdk_actionhandler.cpp
@@ -0,0 +1,629 @@
+// 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
+
+#include "fpdfsdk/fsdk_actionhandler.h"
+
+#include <set>
+
+#include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfdoc/cpdf_formfield.h"
+#include "core/fpdfdoc/cpdf_interform.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/cpdfsdk_interform.h"
+#include "fpdfsdk/fsdk_define.h"
+#include "fpdfsdk/javascript/ijs_context.h"
+#include "fpdfsdk/javascript/ijs_runtime.h"
+#include "third_party/base/stl_util.h"
+
+bool CPDFSDK_ActionHandler::DoAction_DocOpen(
+    const CPDF_Action& action,
+    CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+  std::set<CPDF_Dictionary*> visited;
+  return ExecuteDocumentOpenAction(action, pFormFillEnv, &visited);
+}
+
+bool CPDFSDK_ActionHandler::DoAction_JavaScript(
+    const CPDF_Action& JsAction,
+    CFX_WideString csJSName,
+    CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+  if (JsAction.GetType() == CPDF_Action::JavaScript) {
+    CFX_WideString swJS = JsAction.GetJavaScript();
+    if (!swJS.IsEmpty()) {
+      RunDocumentOpenJavaScript(pFormFillEnv, csJSName, swJS);
+      return true;
+    }
+  }
+
+  return false;
+}
+
+bool CPDFSDK_ActionHandler::DoAction_FieldJavaScript(
+    const CPDF_Action& JsAction,
+    CPDF_AAction::AActionType type,
+    CPDFSDK_FormFillEnvironment* pFormFillEnv,
+    CPDF_FormField* pFormField,
+    PDFSDK_FieldAction& data) {
+  ASSERT(pFormFillEnv);
+  if (pFormFillEnv->IsJSInitiated() &&
+      JsAction.GetType() == CPDF_Action::JavaScript) {
+    CFX_WideString swJS = JsAction.GetJavaScript();
+    if (!swJS.IsEmpty()) {
+      RunFieldJavaScript(pFormFillEnv, pFormField, type, data, swJS);
+      return true;
+    }
+  }
+  return false;
+}
+
+bool CPDFSDK_ActionHandler::DoAction_Page(
+    const CPDF_Action& action,
+    enum CPDF_AAction::AActionType eType,
+    CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+  std::set<CPDF_Dictionary*> visited;
+  return ExecuteDocumentPageAction(action, eType, pFormFillEnv, &visited);
+}
+
+bool CPDFSDK_ActionHandler::DoAction_Document(
+    const CPDF_Action& action,
+    enum CPDF_AAction::AActionType eType,
+    CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+  std::set<CPDF_Dictionary*> visited;
+  return ExecuteDocumentPageAction(action, eType, pFormFillEnv, &visited);
+}
+
+bool CPDFSDK_ActionHandler::DoAction_BookMark(
+    CPDF_Bookmark* pBookMark,
+    const CPDF_Action& action,
+    CPDF_AAction::AActionType type,
+    CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+  std::set<CPDF_Dictionary*> visited;
+  return ExecuteBookMark(action, pFormFillEnv, pBookMark, &visited);
+}
+
+bool CPDFSDK_ActionHandler::DoAction_Screen(
+    const CPDF_Action& action,
+    CPDF_AAction::AActionType type,
+    CPDFSDK_FormFillEnvironment* pFormFillEnv,
+    CPDFSDK_Annot* pScreen) {
+  std::set<CPDF_Dictionary*> visited;
+  return ExecuteScreenAction(action, type, pFormFillEnv, pScreen, &visited);
+}
+
+bool CPDFSDK_ActionHandler::DoAction_Link(
+    const CPDF_Action& action,
+    CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+  std::set<CPDF_Dictionary*> visited;
+  return ExecuteLinkAction(action, pFormFillEnv, &visited);
+}
+
+bool CPDFSDK_ActionHandler::DoAction_Field(
+    const CPDF_Action& action,
+    CPDF_AAction::AActionType type,
+    CPDFSDK_FormFillEnvironment* pFormFillEnv,
+    CPDF_FormField* pFormField,
+    PDFSDK_FieldAction& data) {
+  std::set<CPDF_Dictionary*> visited;
+  return ExecuteFieldAction(action, type, pFormFillEnv, pFormField, data,
+                            &visited);
+}
+
+bool CPDFSDK_ActionHandler::ExecuteDocumentOpenAction(
+    const CPDF_Action& action,
+    CPDFSDK_FormFillEnvironment* pFormFillEnv,
+    std::set<CPDF_Dictionary*>* visited) {
+  CPDF_Dictionary* pDict = action.GetDict();
+  if (pdfium::ContainsKey(*visited, pDict))
+    return false;
+
+  visited->insert(pDict);
+
+  ASSERT(pFormFillEnv);
+  if (action.GetType() == CPDF_Action::JavaScript) {
+    if (pFormFillEnv->IsJSInitiated()) {
+      CFX_WideString swJS = action.GetJavaScript();
+      if (!swJS.IsEmpty()) {
+        RunDocumentOpenJavaScript(pFormFillEnv, L"", swJS);
+      }
+    }
+  } else {
+    DoAction_NoJs(action, pFormFillEnv);
+  }
+
+  for (int32_t i = 0, sz = action.GetSubActionsCount(); i < sz; i++) {
+    CPDF_Action subaction = action.GetSubAction(i);
+    if (!ExecuteDocumentOpenAction(subaction, pFormFillEnv, visited))
+      return false;
+  }
+
+  return true;
+}
+
+bool CPDFSDK_ActionHandler::ExecuteLinkAction(
+    const CPDF_Action& action,
+    CPDFSDK_FormFillEnvironment* pFormFillEnv,
+    std::set<CPDF_Dictionary*>* visited) {
+  CPDF_Dictionary* pDict = action.GetDict();
+  if (pdfium::ContainsKey(*visited, pDict))
+    return false;
+
+  visited->insert(pDict);
+
+  ASSERT(pFormFillEnv);
+  if (action.GetType() == CPDF_Action::JavaScript) {
+    if (pFormFillEnv->IsJSInitiated()) {
+      CFX_WideString swJS = action.GetJavaScript();
+      if (!swJS.IsEmpty()) {
+        IJS_Runtime* pRuntime = pFormFillEnv->GetJSRuntime();
+        IJS_Context* pContext = pRuntime->NewContext();
+        pContext->OnLink_MouseUp(pFormFillEnv);
+
+        CFX_WideString csInfo;
+        bool bRet = pContext->RunScript(swJS, &csInfo);
+        if (!bRet) {
+          // FIXME: return error.
+        }
+
+        pRuntime->ReleaseContext(pContext);
+      }
+    }
+  } else {
+    DoAction_NoJs(action, pFormFillEnv);
+  }
+
+  for (int32_t i = 0, sz = action.GetSubActionsCount(); i < sz; i++) {
+    CPDF_Action subaction = action.GetSubAction(i);
+    if (!ExecuteLinkAction(subaction, pFormFillEnv, visited))
+      return false;
+  }
+
+  return true;
+}
+
+bool CPDFSDK_ActionHandler::ExecuteDocumentPageAction(
+    const CPDF_Action& action,
+    CPDF_AAction::AActionType type,
+    CPDFSDK_FormFillEnvironment* pFormFillEnv,
+    std::set<CPDF_Dictionary*>* visited) {
+  CPDF_Dictionary* pDict = action.GetDict();
+  if (pdfium::ContainsKey(*visited, pDict))
+    return false;
+
+  visited->insert(pDict);
+
+  ASSERT(pFormFillEnv);
+  if (action.GetType() == CPDF_Action::JavaScript) {
+    if (pFormFillEnv->IsJSInitiated()) {
+      CFX_WideString swJS = action.GetJavaScript();
+      if (!swJS.IsEmpty()) {
+        RunDocumentPageJavaScript(pFormFillEnv, type, swJS);
+      }
+    }
+  } else {
+    DoAction_NoJs(action, pFormFillEnv);
+  }
+
+  if (!IsValidDocView(pFormFillEnv))
+    return false;
+
+  for (int32_t i = 0, sz = action.GetSubActionsCount(); i < sz; i++) {
+    CPDF_Action subaction = action.GetSubAction(i);
+    if (!ExecuteDocumentPageAction(subaction, type, pFormFillEnv, visited))
+      return false;
+  }
+
+  return true;
+}
+
+bool CPDFSDK_ActionHandler::IsValidField(
+    CPDFSDK_FormFillEnvironment* pFormFillEnv,
+    CPDF_Dictionary* pFieldDict) {
+  ASSERT(pFieldDict);
+
+  CPDFSDK_InterForm* pInterForm = pFormFillEnv->GetInterForm();
+  CPDF_InterForm* pPDFInterForm = pInterForm->GetInterForm();
+  return !!pPDFInterForm->GetFieldByDict(pFieldDict);
+}
+
+bool CPDFSDK_ActionHandler::ExecuteFieldAction(
+    const CPDF_Action& action,
+    CPDF_AAction::AActionType type,
+    CPDFSDK_FormFillEnvironment* pFormFillEnv,
+    CPDF_FormField* pFormField,
+    PDFSDK_FieldAction& data,
+    std::set<CPDF_Dictionary*>* visited) {
+  CPDF_Dictionary* pDict = action.GetDict();
+  if (pdfium::ContainsKey(*visited, pDict))
+    return false;
+
+  visited->insert(pDict);
+
+  ASSERT(pFormFillEnv);
+  if (action.GetType() == CPDF_Action::JavaScript) {
+    if (pFormFillEnv->IsJSInitiated()) {
+      CFX_WideString swJS = action.GetJavaScript();
+      if (!swJS.IsEmpty()) {
+        RunFieldJavaScript(pFormFillEnv, pFormField, type, data, swJS);
+        if (!IsValidField(pFormFillEnv, pFormField->GetFieldDict()))
+          return false;
+      }
+    }
+  } else {
+    DoAction_NoJs(action, pFormFillEnv);
+  }
+
+  for (int32_t i = 0, sz = action.GetSubActionsCount(); i < sz; i++) {
+    CPDF_Action subaction = action.GetSubAction(i);
+    if (!ExecuteFieldAction(subaction, type, pFormFillEnv, pFormField, data,
+                            visited))
+      return false;
+  }
+
+  return true;
+}
+
+bool CPDFSDK_ActionHandler::ExecuteScreenAction(
+    const CPDF_Action& action,
+    CPDF_AAction::AActionType type,
+    CPDFSDK_FormFillEnvironment* pFormFillEnv,
+    CPDFSDK_Annot* pScreen,
+    std::set<CPDF_Dictionary*>* visited) {
+  CPDF_Dictionary* pDict = action.GetDict();
+  if (pdfium::ContainsKey(*visited, pDict))
+    return false;
+
+  visited->insert(pDict);
+
+  ASSERT(pFormFillEnv);
+  if (action.GetType() == CPDF_Action::JavaScript) {
+    if (pFormFillEnv->IsJSInitiated()) {
+      CFX_WideString swJS = action.GetJavaScript();
+      if (!swJS.IsEmpty()) {
+        IJS_Runtime* pRuntime = pFormFillEnv->GetJSRuntime();
+        IJS_Context* pContext = pRuntime->NewContext();
+        CFX_WideString csInfo;
+        bool bRet = pContext->RunScript(swJS, &csInfo);
+        if (!bRet) {
+          // FIXME: return error.
+        }
+
+        pRuntime->ReleaseContext(pContext);
+      }
+    }
+  } else {
+    DoAction_NoJs(action, pFormFillEnv);
+  }
+
+  for (int32_t i = 0, sz = action.GetSubActionsCount(); i < sz; i++) {
+    CPDF_Action subaction = action.GetSubAction(i);
+    if (!ExecuteScreenAction(subaction, type, pFormFillEnv, pScreen, visited))
+      return false;
+  }
+
+  return true;
+}
+
+bool CPDFSDK_ActionHandler::ExecuteBookMark(
+    const CPDF_Action& action,
+    CPDFSDK_FormFillEnvironment* pFormFillEnv,
+    CPDF_Bookmark* pBookmark,
+    std::set<CPDF_Dictionary*>* visited) {
+  CPDF_Dictionary* pDict = action.GetDict();
+  if (pdfium::ContainsKey(*visited, pDict))
+    return false;
+
+  visited->insert(pDict);
+
+  ASSERT(pFormFillEnv);
+  if (action.GetType() == CPDF_Action::JavaScript) {
+    if (pFormFillEnv->IsJSInitiated()) {
+      CFX_WideString swJS = action.GetJavaScript();
+      if (!swJS.IsEmpty()) {
+        IJS_Runtime* pRuntime = pFormFillEnv->GetJSRuntime();
+        IJS_Context* pContext = pRuntime->NewContext();
+        pContext->OnBookmark_MouseUp(pBookmark);
+
+        CFX_WideString csInfo;
+        bool bRet = pContext->RunScript(swJS, &csInfo);
+        if (!bRet) {
+          // FIXME: return error.
+        }
+
+        pRuntime->ReleaseContext(pContext);
+      }
+    }
+  } else {
+    DoAction_NoJs(action, pFormFillEnv);
+  }
+
+  for (int32_t i = 0, sz = action.GetSubActionsCount(); i < sz; i++) {
+    CPDF_Action subaction = action.GetSubAction(i);
+    if (!ExecuteBookMark(subaction, pFormFillEnv, pBookmark, visited))
+      return false;
+  }
+
+  return true;
+}
+
+void CPDFSDK_ActionHandler::DoAction_NoJs(
+    const CPDF_Action& action,
+    CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+  ASSERT(pFormFillEnv);
+
+  switch (action.GetType()) {
+    case CPDF_Action::GoTo:
+      DoAction_GoTo(pFormFillEnv, action);
+      break;
+    case CPDF_Action::GoToR:
+      DoAction_GoToR(pFormFillEnv, action);
+      break;
+    case CPDF_Action::GoToE:
+      break;
+    case CPDF_Action::Launch:
+      DoAction_Launch(pFormFillEnv, action);
+      break;
+    case CPDF_Action::Thread:
+      break;
+    case CPDF_Action::URI:
+      DoAction_URI(pFormFillEnv, action);
+      break;
+    case CPDF_Action::Sound:
+      break;
+    case CPDF_Action::Movie:
+      break;
+    case CPDF_Action::Hide:
+      DoAction_Hide(action, pFormFillEnv);
+      break;
+    case CPDF_Action::Named:
+      DoAction_Named(pFormFillEnv, action);
+      break;
+    case CPDF_Action::SubmitForm:
+      DoAction_SubmitForm(action, pFormFillEnv);
+      break;
+    case CPDF_Action::ResetForm:
+      DoAction_ResetForm(action, pFormFillEnv);
+      break;
+    case CPDF_Action::ImportData:
+      DoAction_ImportData(action, pFormFillEnv);
+      break;
+    case CPDF_Action::JavaScript:
+      ASSERT(false);
+      break;
+    case CPDF_Action::SetOCGState:
+      DoAction_SetOCGState(pFormFillEnv, action);
+      break;
+    case CPDF_Action::Rendition:
+      break;
+    case CPDF_Action::Trans:
+      break;
+    case CPDF_Action::GoTo3DView:
+      break;
+    default:
+      break;
+  }
+}
+
+bool CPDFSDK_ActionHandler::IsValidDocView(
+    CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+  ASSERT(pFormFillEnv);
+  return true;
+}
+
+void CPDFSDK_ActionHandler::DoAction_GoTo(
+    CPDFSDK_FormFillEnvironment* pFormFillEnv,
+    const CPDF_Action& action) {
+  ASSERT(action.GetDict());
+
+  CPDF_Document* pPDFDocument = pFormFillEnv->GetPDFDocument();
+  ASSERT(pPDFDocument);
+
+  CPDF_Dest MyDest = action.GetDest(pPDFDocument);
+  int nPageIndex = MyDest.GetPageIndex(pPDFDocument);
+  int nFitType = MyDest.GetZoomMode();
+  const CPDF_Array* pMyArray = ToArray(MyDest.GetObject());
+  float* pPosAry = nullptr;
+  int sizeOfAry = 0;
+  if (pMyArray) {
+    pPosAry = new float[pMyArray->GetCount()];
+    int j = 0;
+    for (size_t i = 2; i < pMyArray->GetCount(); i++) {
+      pPosAry[j++] = pMyArray->GetFloatAt(i);
+    }
+    sizeOfAry = j;
+  }
+
+  pFormFillEnv->DoGoToAction(nPageIndex, nFitType, pPosAry, sizeOfAry);
+  delete[] pPosAry;
+}
+
+void CPDFSDK_ActionHandler::DoAction_GoToR(
+    CPDFSDK_FormFillEnvironment* pFormFillEnv,
+    const CPDF_Action& action) {}
+
+void CPDFSDK_ActionHandler::DoAction_Launch(
+    CPDFSDK_FormFillEnvironment* pFormFillEnv,
+    const CPDF_Action& action) {}
+
+void CPDFSDK_ActionHandler::DoAction_URI(
+    CPDFSDK_FormFillEnvironment* pFormFillEnv,
+    const CPDF_Action& action) {
+  ASSERT(action.GetDict());
+
+  CFX_ByteString sURI = action.GetURI(pFormFillEnv->GetPDFDocument());
+  pFormFillEnv->DoURIAction(sURI.c_str());
+}
+
+void CPDFSDK_ActionHandler::DoAction_Named(
+    CPDFSDK_FormFillEnvironment* pFormFillEnv,
+    const CPDF_Action& action) {
+  ASSERT(action.GetDict());
+
+  CFX_ByteString csName = action.GetNamedAction();
+  pFormFillEnv->ExecuteNamedAction(csName.c_str());
+}
+
+void CPDFSDK_ActionHandler::DoAction_SetOCGState(
+    CPDFSDK_FormFillEnvironment* pFormFillEnv,
+    const CPDF_Action& action) {}
+
+void CPDFSDK_ActionHandler::RunFieldJavaScript(
+    CPDFSDK_FormFillEnvironment* pFormFillEnv,
+    CPDF_FormField* pFormField,
+    CPDF_AAction::AActionType type,
+    PDFSDK_FieldAction& data,
+    const CFX_WideString& script) {
+  ASSERT(type != CPDF_AAction::Calculate);
+  ASSERT(type != CPDF_AAction::Format);
+
+  IJS_Runtime* pRuntime = pFormFillEnv->GetJSRuntime();
+  IJS_Context* pContext = pRuntime->NewContext();
+  switch (type) {
+    case CPDF_AAction::CursorEnter:
+      pContext->OnField_MouseEnter(data.bModifier, data.bShift, pFormField);
+      break;
+    case CPDF_AAction::CursorExit:
+      pContext->OnField_MouseExit(data.bModifier, data.bShift, pFormField);
+      break;
+    case CPDF_AAction::ButtonDown:
+      pContext->OnField_MouseDown(data.bModifier, data.bShift, pFormField);
+      break;
+    case CPDF_AAction::ButtonUp:
+      pContext->OnField_MouseUp(data.bModifier, data.bShift, pFormField);
+      break;
+    case CPDF_AAction::GetFocus:
+      pContext->OnField_Focus(data.bModifier, data.bShift, pFormField,
+                              data.sValue);
+      break;
+    case CPDF_AAction::LoseFocus:
+      pContext->OnField_Blur(data.bModifier, data.bShift, pFormField,
+                             data.sValue);
+      break;
+    case CPDF_AAction::KeyStroke:
+      pContext->OnField_Keystroke(data.sChange, data.sChangeEx, data.bKeyDown,
+                                  data.bModifier, data.nSelEnd, data.nSelStart,
+                                  data.bShift, pFormField, data.sValue,
+                                  data.bWillCommit, data.bFieldFull, data.bRC);
+      break;
+    case CPDF_AAction::Validate:
+      pContext->OnField_Validate(data.sChange, data.sChangeEx, data.bKeyDown,
+                                 data.bModifier, data.bShift, pFormField,
+                                 data.sValue, data.bRC);
+      break;
+    default:
+      ASSERT(false);
+      break;
+  }
+
+  CFX_WideString csInfo;
+  bool bRet = pContext->RunScript(script, &csInfo);
+  if (!bRet) {
+    // FIXME: return error.
+  }
+
+  pRuntime->ReleaseContext(pContext);
+}
+
+void CPDFSDK_ActionHandler::RunDocumentOpenJavaScript(
+    CPDFSDK_FormFillEnvironment* pFormFillEnv,
+    const CFX_WideString& sScriptName,
+    const CFX_WideString& script) {
+  IJS_Runtime* pRuntime = pFormFillEnv->GetJSRuntime();
+  IJS_Context* pContext = pRuntime->NewContext();
+  pContext->OnDoc_Open(pFormFillEnv, sScriptName);
+
+  CFX_WideString csInfo;
+  bool bRet = pContext->RunScript(script, &csInfo);
+  if (!bRet) {
+    // FIXME: return error.
+  }
+
+  pRuntime->ReleaseContext(pContext);
+}
+
+void CPDFSDK_ActionHandler::RunDocumentPageJavaScript(
+    CPDFSDK_FormFillEnvironment* pFormFillEnv,
+    CPDF_AAction::AActionType type,
+    const CFX_WideString& script) {
+  IJS_Runtime* pRuntime = pFormFillEnv->GetJSRuntime();
+  IJS_Context* pContext = pRuntime->NewContext();
+  switch (type) {
+    case CPDF_AAction::OpenPage:
+      pContext->OnPage_Open(pFormFillEnv);
+      break;
+    case CPDF_AAction::ClosePage:
+      pContext->OnPage_Close(pFormFillEnv);
+      break;
+    case CPDF_AAction::CloseDocument:
+      pContext->OnDoc_WillClose(pFormFillEnv);
+      break;
+    case CPDF_AAction::SaveDocument:
+      pContext->OnDoc_WillSave(pFormFillEnv);
+      break;
+    case CPDF_AAction::DocumentSaved:
+      pContext->OnDoc_DidSave(pFormFillEnv);
+      break;
+    case CPDF_AAction::PrintDocument:
+      pContext->OnDoc_WillPrint(pFormFillEnv);
+      break;
+    case CPDF_AAction::DocumentPrinted:
+      pContext->OnDoc_DidPrint(pFormFillEnv);
+      break;
+    case CPDF_AAction::PageVisible:
+      pContext->OnPage_InView(pFormFillEnv);
+      break;
+    case CPDF_AAction::PageInvisible:
+      pContext->OnPage_OutView(pFormFillEnv);
+      break;
+    default:
+      ASSERT(false);
+      break;
+  }
+
+  CFX_WideString csInfo;
+  bool bRet = pContext->RunScript(script, &csInfo);
+  if (!bRet) {
+    // FIXME: return error.
+  }
+
+  pRuntime->ReleaseContext(pContext);
+}
+
+bool CPDFSDK_ActionHandler::DoAction_Hide(
+    const CPDF_Action& action,
+    CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+  CPDFSDK_InterForm* pInterForm = pFormFillEnv->GetInterForm();
+  if (pInterForm->DoAction_Hide(action)) {
+    pFormFillEnv->SetChangeMark();
+    return true;
+  }
+
+  return false;
+}
+
+bool CPDFSDK_ActionHandler::DoAction_SubmitForm(
+    const CPDF_Action& action,
+    CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+  CPDFSDK_InterForm* pInterForm = pFormFillEnv->GetInterForm();
+  return pInterForm->DoAction_SubmitForm(action);
+}
+
+bool CPDFSDK_ActionHandler::DoAction_ResetForm(
+    const CPDF_Action& action,
+    CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+  CPDFSDK_InterForm* pInterForm = pFormFillEnv->GetInterForm();
+  return pInterForm->DoAction_ResetForm(action);
+}
+
+bool CPDFSDK_ActionHandler::DoAction_ImportData(
+    const CPDF_Action& action,
+    CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+  CPDFSDK_InterForm* pInterForm = pFormFillEnv->GetInterForm();
+  if (pInterForm->DoAction_ImportData(action)) {
+    pFormFillEnv->SetChangeMark();
+    return true;
+  }
+
+  return false;
+}
diff --git a/fpdfsdk/fsdk_actionhandler.h b/fpdfsdk/fsdk_actionhandler.h
new file mode 100644
index 0000000..1c8dede
--- /dev/null
+++ b/fpdfsdk/fsdk_actionhandler.h
@@ -0,0 +1,126 @@
+// 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_FSDK_ACTIONHANDLER_H_
+#define FPDFSDK_FSDK_ACTIONHANDLER_H_
+
+#include <memory>
+#include <set>
+
+#include "core/fpdfdoc/cpdf_aaction.h"
+#include "core/fpdfdoc/cpdf_action.h"
+#include "core/fxcrt/fx_string.h"
+#include "fpdfsdk/pdfsdk_fieldaction.h"
+
+class CPDFSDK_Annot;
+class CPDFSDK_FormFillEnvironment;
+class CPDF_Bookmark;
+class CPDF_Dictionary;
+class CPDF_FormField;
+
+class CPDFSDK_ActionHandler {
+ public:
+  bool DoAction_DocOpen(const CPDF_Action& action,
+                        CPDFSDK_FormFillEnvironment* pFormFillEnv);
+  bool DoAction_JavaScript(const CPDF_Action& JsAction,
+                           CFX_WideString csJSName,
+                           CPDFSDK_FormFillEnvironment* pFormFillEnv);
+  bool DoAction_Page(const CPDF_Action& action,
+                     enum CPDF_AAction::AActionType eType,
+                     CPDFSDK_FormFillEnvironment* pFormFillEnv);
+  bool DoAction_Document(const CPDF_Action& action,
+                         enum CPDF_AAction::AActionType eType,
+                         CPDFSDK_FormFillEnvironment* pFormFillEnv);
+  bool DoAction_BookMark(CPDF_Bookmark* pBookMark,
+                         const CPDF_Action& action,
+                         CPDF_AAction::AActionType type,
+                         CPDFSDK_FormFillEnvironment* pFormFillEnv);
+  bool DoAction_Screen(const CPDF_Action& action,
+                       CPDF_AAction::AActionType type,
+                       CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                       CPDFSDK_Annot* pScreen);
+  bool DoAction_Link(const CPDF_Action& action,
+                     CPDFSDK_FormFillEnvironment* pFormFillEnv);
+  bool DoAction_Field(const CPDF_Action& action,
+                      CPDF_AAction::AActionType type,
+                      CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                      CPDF_FormField* pFormField,
+                      PDFSDK_FieldAction& data);
+  bool DoAction_FieldJavaScript(const CPDF_Action& JsAction,
+                                CPDF_AAction::AActionType type,
+                                CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                                CPDF_FormField* pFormField,
+                                PDFSDK_FieldAction& data);
+
+ private:
+  bool ExecuteDocumentOpenAction(const CPDF_Action& action,
+                                 CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                                 std::set<CPDF_Dictionary*>* visited);
+  bool ExecuteDocumentPageAction(const CPDF_Action& action,
+                                 CPDF_AAction::AActionType type,
+                                 CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                                 std::set<CPDF_Dictionary*>* visited);
+  bool ExecuteFieldAction(const CPDF_Action& action,
+                          CPDF_AAction::AActionType type,
+                          CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                          CPDF_FormField* pFormField,
+                          PDFSDK_FieldAction& data,
+                          std::set<CPDF_Dictionary*>* visited);
+  bool ExecuteScreenAction(const CPDF_Action& action,
+                           CPDF_AAction::AActionType type,
+                           CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                           CPDFSDK_Annot* pScreen,
+                           std::set<CPDF_Dictionary*>* visited);
+  bool ExecuteBookMark(const CPDF_Action& action,
+                       CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                       CPDF_Bookmark* pBookmark,
+                       std::set<CPDF_Dictionary*>* visited);
+  bool ExecuteLinkAction(const CPDF_Action& action,
+                         CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                         std::set<CPDF_Dictionary*>* visited);
+
+  void DoAction_NoJs(const CPDF_Action& action,
+                     CPDFSDK_FormFillEnvironment* pFormFillEnv);
+  void RunDocumentPageJavaScript(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                                 CPDF_AAction::AActionType type,
+                                 const CFX_WideString& script);
+  void RunDocumentOpenJavaScript(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                                 const CFX_WideString& sScriptName,
+                                 const CFX_WideString& script);
+  void RunFieldJavaScript(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                          CPDF_FormField* pFormField,
+                          CPDF_AAction::AActionType type,
+                          PDFSDK_FieldAction& data,
+                          const CFX_WideString& script);
+
+  bool IsValidField(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                    CPDF_Dictionary* pFieldDict);
+  bool IsValidDocView(CPDFSDK_FormFillEnvironment* pFormFillEnv);
+
+  void DoAction_GoTo(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                     const CPDF_Action& action);
+  void DoAction_GoToR(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                      const CPDF_Action& action);
+  void DoAction_Launch(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                       const CPDF_Action& action);
+  void DoAction_URI(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                    const CPDF_Action& action);
+  void DoAction_Named(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                      const CPDF_Action& action);
+  void DoAction_SetOCGState(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                            const CPDF_Action& action);
+
+  bool DoAction_Hide(const CPDF_Action& action,
+                     CPDFSDK_FormFillEnvironment* pFormFillEnv);
+  bool DoAction_SubmitForm(const CPDF_Action& action,
+                           CPDFSDK_FormFillEnvironment* pFormFillEnv);
+  bool DoAction_ResetForm(const CPDF_Action& action,
+                          CPDFSDK_FormFillEnvironment* pFormFillEnv);
+  bool DoAction_ImportData(const CPDF_Action& action,
+                           CPDFSDK_FormFillEnvironment* pFormFillEnv);
+};
+
+#endif  // FPDFSDK_FSDK_ACTIONHANDLER_H_
diff --git a/fpdfsdk/fsdk_baseform_embeddertest.cpp b/fpdfsdk/fsdk_baseform_embeddertest.cpp
new file mode 100644
index 0000000..13efe86
--- /dev/null
+++ b/fpdfsdk/fsdk_baseform_embeddertest.cpp
@@ -0,0 +1,126 @@
+// 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.
+
+#include "fpdfsdk/cba_annotiterator.h"
+#include "fpdfsdk/cpdfsdk_annot.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/fsdk_define.h"
+#include "testing/embedder_test.h"
+#include "testing/embedder_test_mock_delegate.h"
+#include "testing/embedder_test_timer_handling_delegate.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+void CheckRect(const CFX_FloatRect& actual, const CFX_FloatRect& expected) {
+  EXPECT_EQ(expected.left, actual.left);
+  EXPECT_EQ(expected.bottom, actual.bottom);
+  EXPECT_EQ(expected.right, actual.right);
+  EXPECT_EQ(expected.top, actual.top);
+}
+
+}  // namespace
+
+class FSDKBaseFormEmbeddertest : public EmbedderTest {};
+
+TEST_F(FSDKBaseFormEmbeddertest, CBA_AnnotIterator) {
+  EXPECT_TRUE(OpenDocument("annotiter.pdf"));
+  FPDF_PAGE page0 = LoadPage(0);
+  FPDF_PAGE page1 = LoadPage(1);
+  FPDF_PAGE page2 = LoadPage(2);
+  EXPECT_TRUE(page0);
+  EXPECT_TRUE(page1);
+  EXPECT_TRUE(page2);
+
+  CFX_FloatRect LeftBottom(200, 200, 220, 220);
+  CFX_FloatRect RightBottom(400, 201, 420, 221);
+  CFX_FloatRect LeftTop(201, 400, 221, 420);
+  CFX_FloatRect RightTop(401, 401, 421, 421);
+
+  CPDFSDK_FormFillEnvironment* pFormFillEnv =
+      static_cast<CPDFSDK_FormFillEnvironment*>(form_handle());
+
+  {
+    // Page 0 specifies "row order".
+    CBA_AnnotIterator iter(pFormFillEnv->GetPageView(0),
+                           CPDF_Annot::Subtype::WIDGET);
+    CPDFSDK_Annot* pAnnot = iter.GetFirstAnnot();
+    CheckRect(pAnnot->GetRect(), RightTop);
+    pAnnot = iter.GetNextAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), LeftTop);
+    pAnnot = iter.GetNextAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), RightBottom);
+    pAnnot = iter.GetNextAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), LeftBottom);
+    pAnnot = iter.GetNextAnnot(pAnnot);
+    EXPECT_EQ(iter.GetFirstAnnot(), pAnnot);
+
+    pAnnot = iter.GetLastAnnot();
+    CheckRect(pAnnot->GetRect(), LeftBottom);
+    pAnnot = iter.GetPrevAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), RightBottom);
+    pAnnot = iter.GetPrevAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), LeftTop);
+    pAnnot = iter.GetPrevAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), RightTop);
+    pAnnot = iter.GetPrevAnnot(pAnnot);
+    EXPECT_EQ(iter.GetLastAnnot(), pAnnot);
+  }
+  {
+    // Page 1 specifies "column order"
+    CBA_AnnotIterator iter(pFormFillEnv->GetPageView(1),
+                           CPDF_Annot::Subtype::WIDGET);
+    CPDFSDK_Annot* pAnnot = iter.GetFirstAnnot();
+    CheckRect(pAnnot->GetRect(), RightTop);
+    pAnnot = iter.GetNextAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), RightBottom);
+    pAnnot = iter.GetNextAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), LeftTop);
+    pAnnot = iter.GetNextAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), LeftBottom);
+    pAnnot = iter.GetNextAnnot(pAnnot);
+    EXPECT_EQ(iter.GetFirstAnnot(), pAnnot);
+
+    pAnnot = iter.GetLastAnnot();
+    CheckRect(pAnnot->GetRect(), LeftBottom);
+    pAnnot = iter.GetPrevAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), LeftTop);
+    pAnnot = iter.GetPrevAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), RightBottom);
+    pAnnot = iter.GetPrevAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), RightTop);
+    pAnnot = iter.GetPrevAnnot(pAnnot);
+    EXPECT_EQ(iter.GetLastAnnot(), pAnnot);
+  }
+  {
+    // Page 2 specifies "struct order"
+    CBA_AnnotIterator iter(pFormFillEnv->GetPageView(2),
+                           CPDF_Annot::Subtype::WIDGET);
+    CPDFSDK_Annot* pAnnot = iter.GetFirstAnnot();
+    CheckRect(pAnnot->GetRect(), LeftBottom);
+    pAnnot = iter.GetNextAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), RightTop);
+    pAnnot = iter.GetNextAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), LeftTop);
+    pAnnot = iter.GetNextAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), RightBottom);
+    pAnnot = iter.GetNextAnnot(pAnnot);
+    EXPECT_EQ(iter.GetFirstAnnot(), pAnnot);
+
+    pAnnot = iter.GetLastAnnot();
+    CheckRect(pAnnot->GetRect(), RightBottom);
+    pAnnot = iter.GetPrevAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), LeftTop);
+    pAnnot = iter.GetPrevAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), RightTop);
+    pAnnot = iter.GetPrevAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), LeftBottom);
+    pAnnot = iter.GetPrevAnnot(pAnnot);
+    EXPECT_EQ(iter.GetLastAnnot(), pAnnot);
+  }
+  UnloadPage(page2);
+  UnloadPage(page1);
+  UnloadPage(page0);
+}
diff --git a/fpdfsdk/include/fsdk_common.h b/fpdfsdk/fsdk_common.h
similarity index 71%
rename from fpdfsdk/include/fsdk_common.h
rename to fpdfsdk/fsdk_common.h
index 279048b..d803026 100644
--- a/fpdfsdk/include/fsdk_common.h
+++ b/fpdfsdk/fsdk_common.h
@@ -4,10 +4,8 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#ifndef FPDFSDK_INCLUDE_FSDK_COMMON_H_
-#define FPDFSDK_INCLUDE_FSDK_COMMON_H_
-
-#define BFFT_SIGNATURE "Signature"
+#ifndef FPDFSDK_FSDK_COMMON_H_
+#define FPDFSDK_FSDK_COMMON_H_
 
 // for all fields
 #define FIELDFLAG_READONLY 1
@@ -25,21 +23,12 @@
 #define FIELDFLAG_NOTOGGLETOOFF (1 << 14)
 #define FIELDFLAG_RADIO (1 << 15)
 #define FIELDFLAG_PUSHBUTTON (1 << 16)
-#define FIELDFLAG_RADIOSINUNISON (1 << 25)
+#define FIELDFLAG_RADIOSINUNISON (1 << 27)
 // for choice fields
 #define FIELDFLAG_COMBO (1 << 17)
 #define FIELDFLAG_EDIT (1 << 18)
 #define FIELDFLAG_SORT (1 << 19)
 #define FIELDFLAG_MULTISELECT (1 << 21)
-#ifndef FIELDFLAG_DONOTSPELLCHECK
-#define FIELDFLAG_DONOTSPELLCHECK (1 << 22)
-#endif
 #define FIELDFLAG_COMMITONSELCHANGE (1 << 26)
 
-#define BBS_SOLID 0
-#define BBS_DASH 1
-#define BBS_BEVELED 2
-#define BBS_INSET 3
-#define BBS_UNDERLINE 4
-
-#endif  // FPDFSDK_INCLUDE_FSDK_COMMON_H_
+#endif  // FPDFSDK_FSDK_COMMON_H_
diff --git a/fpdfsdk/fsdk_define.h b/fpdfsdk/fsdk_define.h
new file mode 100644
index 0000000..9a11596
--- /dev/null
+++ b/fpdfsdk/fsdk_define.h
@@ -0,0 +1,82 @@
+// 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_FSDK_DEFINE_H_
+#define FPDFSDK_FSDK_DEFINE_H_
+
+#include "core/fpdfapi/parser/cpdf_parser.h"
+#include "core/fxge/fx_dib.h"
+#include "public/fpdfview.h"
+
+#ifdef PDF_ENABLE_XFA
+#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
+#endif  // PDF_ENABLE_XFA
+
+#ifdef _WIN32
+#include <math.h>
+#include <tchar.h>
+#endif
+
+class CPDF_Annot;
+class CPDF_Page;
+class CPDF_PageRenderContext;
+class IFSDK_PAUSE_Adapter;
+
+// Layering prevents fxcrt from knowing about FPDF_FILEACCESS, so this can't
+// be a static method of IFX_SeekableReadStream.
+CFX_RetainPtr<IFX_SeekableReadStream> MakeSeekableReadStream(
+    FPDF_FILEACCESS* pFileAccess);
+
+#ifdef PDF_ENABLE_XFA
+// Layering prevents fxcrt from knowing about FPDF_FILEHANDLER, so this can't
+// be a static method of IFX_SeekableStream.
+CFX_RetainPtr<IFX_SeekableStream> MakeSeekableStream(
+    FPDF_FILEHANDLER* pFileHandler);
+#endif  // PDF_ENABLE_XFA
+
+// Object types for public FPDF_ types; these correspond to next layer down
+// from fpdfsdk. For master, these are CPDF_ types, but for XFA, these are
+// CPDFXFA_ types.
+#ifndef PDF_ENABLE_XFA
+using UnderlyingDocumentType = CPDF_Document;
+using UnderlyingPageType = CPDF_Page;
+#else   // PDF_ENABLE_XFA
+using UnderlyingDocumentType = CPDFXFA_Context;
+using UnderlyingPageType = CPDFXFA_Page;
+#endif  // PDF_ENABLE_XFA
+
+// Conversions to/from underlying types.
+UnderlyingDocumentType* UnderlyingFromFPDFDocument(FPDF_DOCUMENT doc);
+FPDF_DOCUMENT FPDFDocumentFromUnderlying(UnderlyingDocumentType* doc);
+
+UnderlyingPageType* UnderlyingFromFPDFPage(FPDF_PAGE page);
+
+// Conversions to/from FPDF_ types.
+CPDF_Document* CPDFDocumentFromFPDFDocument(FPDF_DOCUMENT doc);
+FPDF_DOCUMENT FPDFDocumentFromCPDFDocument(CPDF_Document* doc);
+
+CPDF_Page* CPDFPageFromFPDFPage(FPDF_PAGE page);
+
+CFX_DIBitmap* CFXBitmapFromFPDFBitmap(FPDF_BITMAP bitmap);
+
+void FSDK_SetSandBoxPolicy(FPDF_DWORD policy, FPDF_BOOL enable);
+FPDF_BOOL FSDK_IsSandBoxPolicyEnabled(FPDF_DWORD policy);
+void FPDF_RenderPage_Retail(CPDF_PageRenderContext* pContext,
+                            FPDF_PAGE page,
+                            int start_x,
+                            int start_y,
+                            int size_x,
+                            int size_y,
+                            int rotate,
+                            int flags,
+                            bool bNeedToRestore,
+                            IFSDK_PAUSE_Adapter* pause);
+
+void CheckUnSupportError(CPDF_Document* pDoc, uint32_t err_code);
+void CheckUnSupportAnnot(CPDF_Document* pDoc, const CPDF_Annot* pPDFAnnot);
+void ProcessParseError(CPDF_Parser::Error err);
+
+#endif  // FPDFSDK_FSDK_DEFINE_H_
diff --git a/fpdfsdk/fsdk_pauseadapter.cpp b/fpdfsdk/fsdk_pauseadapter.cpp
new file mode 100644
index 0000000..237266b
--- /dev/null
+++ b/fpdfsdk/fsdk_pauseadapter.cpp
@@ -0,0 +1,16 @@
+// 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/fsdk_pauseadapter.h"
+
+IFSDK_PAUSE_Adapter::IFSDK_PAUSE_Adapter(IFSDK_PAUSE* IPause)
+    : m_IPause(IPause) {}
+
+IFSDK_PAUSE_Adapter::~IFSDK_PAUSE_Adapter() {}
+
+bool IFSDK_PAUSE_Adapter::NeedToPauseNow() {
+  return m_IPause->NeedToPauseNow && m_IPause->NeedToPauseNow(m_IPause);
+}
diff --git a/fpdfsdk/fsdk_pauseadapter.h b/fpdfsdk/fsdk_pauseadapter.h
new file mode 100644
index 0000000..bd302f2
--- /dev/null
+++ b/fpdfsdk/fsdk_pauseadapter.h
@@ -0,0 +1,25 @@
+// 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_FSDK_PAUSEADAPTER_H_
+#define FPDFSDK_FSDK_PAUSEADAPTER_H_
+
+#include "core/fxcrt/fx_basic.h"
+#include "core/fxcrt/fx_system.h"
+#include "public/fpdf_progressive.h"
+
+class IFSDK_PAUSE_Adapter : public IFX_Pause {
+ public:
+  explicit IFSDK_PAUSE_Adapter(IFSDK_PAUSE* IPause);
+  ~IFSDK_PAUSE_Adapter() override;
+
+  bool NeedToPauseNow() override;
+
+ private:
+  IFSDK_PAUSE* const m_IPause;
+};
+
+#endif  // FPDFSDK_FSDK_PAUSEADAPTER_H_
diff --git a/fpdfsdk/fxedit/fx_edit.h b/fpdfsdk/fxedit/fx_edit.h
new file mode 100644
index 0000000..6c91667
--- /dev/null
+++ b/fpdfsdk/fxedit/fx_edit.h
@@ -0,0 +1,23 @@
+// 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_FXEDIT_FX_EDIT_H_
+#define FPDFSDK_FXEDIT_FX_EDIT_H_
+
+#include "core/fxcrt/fx_basic.h"
+
+class IPVT_FontMap;
+
+#define FX_EDIT_ISLATINWORD(u)                  \
+  (u == 0x2D || (u <= 0x005A && u >= 0x0041) || \
+   (u <= 0x007A && u >= 0x0061) || (u <= 0x02AF && u >= 0x00C0))
+
+CFX_ByteString GetPDFWordString(IPVT_FontMap* pFontMap,
+                                int32_t nFontIndex,
+                                uint16_t Word,
+                                uint16_t SubWord);
+
+#endif  // FPDFSDK_FXEDIT_FX_EDIT_H_
diff --git a/fpdfsdk/fxedit/fxet_ap.cpp b/fpdfsdk/fxedit/fxet_ap.cpp
new file mode 100644
index 0000000..448a539
--- /dev/null
+++ b/fpdfsdk/fxedit/fxet_ap.cpp
@@ -0,0 +1,38 @@
+// 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
+
+#include "core/fpdfapi/font/cpdf_font.h"
+#include "core/fpdfapi/parser/fpdf_parser_decode.h"
+#include "core/fpdfdoc/cpvt_word.h"
+#include "core/fpdfdoc/ipvt_fontmap.h"
+#include "fpdfsdk/fxedit/fx_edit.h"
+#include "fpdfsdk/fxedit/fxet_edit.h"
+
+CFX_ByteString GetPDFWordString(IPVT_FontMap* pFontMap,
+                                int32_t nFontIndex,
+                                uint16_t Word,
+                                uint16_t SubWord) {
+  CPDF_Font* pPDFFont = pFontMap->GetPDFFont(nFontIndex);
+  if (!pPDFFont)
+    return CFX_ByteString();
+
+  CFX_ByteString sWord;
+  if (SubWord > 0) {
+    Word = SubWord;
+  } else {
+    uint32_t dwCharCode = pPDFFont->IsUnicodeCompatible()
+                              ? pPDFFont->CharCodeFromUnicode(Word)
+                              : pFontMap->CharCodeFromUnicode(nFontIndex, Word);
+
+    if (dwCharCode > 0) {
+      pPDFFont->AppendChar(sWord, dwCharCode);
+      return sWord;
+    }
+  }
+
+  pPDFFont->AppendChar(sWord, Word);
+  return sWord;
+}
diff --git a/fpdfsdk/fxedit/fxet_edit.cpp b/fpdfsdk/fxedit/fxet_edit.cpp
new file mode 100644
index 0000000..aa77e9f
--- /dev/null
+++ b/fpdfsdk/fxedit/fxet_edit.cpp
@@ -0,0 +1,2530 @@
+// 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
+
+#include "fpdfsdk/fxedit/fxet_edit.h"
+
+#include <algorithm>
+#include <memory>
+#include <utility>
+
+#include "core/fpdfapi/font/cpdf_font.h"
+#include "core/fpdfapi/page/cpdf_pageobject.h"
+#include "core/fpdfapi/page/cpdf_pageobjectholder.h"
+#include "core/fpdfapi/page/cpdf_pathobject.h"
+#include "core/fpdfapi/page/cpdf_textobject.h"
+#include "core/fpdfapi/parser/fpdf_parser_decode.h"
+#include "core/fpdfapi/render/cpdf_renderoptions.h"
+#include "core/fpdfapi/render/cpdf_textrenderer.h"
+#include "core/fpdfdoc/cpvt_section.h"
+#include "core/fpdfdoc/cpvt_word.h"
+#include "core/fpdfdoc/ipvt_fontmap.h"
+#include "core/fxge/cfx_graphstatedata.h"
+#include "core/fxge/cfx_pathdata.h"
+#include "core/fxge/cfx_renderdevice.h"
+#include "fpdfsdk/cfx_systemhandler.h"
+#include "fpdfsdk/fxedit/fx_edit.h"
+#include "fpdfsdk/pdfwindow/PWL_Edit.h"
+#include "fpdfsdk/pdfwindow/PWL_EditCtrl.h"
+#include "third_party/base/ptr_util.h"
+
+namespace {
+
+const int kEditUndoMaxItems = 10000;
+
+CFX_ByteString GetWordRenderString(const CFX_ByteString& strWords) {
+  if (strWords.GetLength() > 0)
+    return PDF_EncodeString(strWords) + " Tj\n";
+  return CFX_ByteString();
+}
+
+CFX_ByteString GetFontSetString(IPVT_FontMap* pFontMap,
+                                int32_t nFontIndex,
+                                FX_FLOAT fFontSize) {
+  if (!pFontMap)
+    return CFX_ByteString();
+
+  CFX_ByteString sFontAlias = pFontMap->GetPDFFontAlias(nFontIndex);
+  if (sFontAlias.GetLength() <= 0 || fFontSize <= 0)
+    return CFX_ByteString();
+
+  CFX_ByteTextBuf sRet;
+  sRet << "/" << sFontAlias << " " << fFontSize << " Tf\n";
+  return sRet.MakeString();
+}
+
+void DrawTextString(CFX_RenderDevice* pDevice,
+                    const CFX_FloatPoint& pt,
+                    CPDF_Font* pFont,
+                    FX_FLOAT fFontSize,
+                    CFX_Matrix* pUser2Device,
+                    const CFX_ByteString& str,
+                    FX_ARGB crTextFill,
+                    FX_ARGB crTextStroke,
+                    int32_t nHorzScale) {
+  FX_FLOAT x = pt.x, y = pt.y;
+  pUser2Device->Transform(x, y);
+
+  if (pFont) {
+    if (nHorzScale != 100) {
+      CFX_Matrix mt(nHorzScale / 100.0f, 0, 0, 1, 0, 0);
+      mt.Concat(*pUser2Device);
+
+      CPDF_RenderOptions ro;
+      ro.m_Flags = RENDER_CLEARTYPE;
+      ro.m_ColorMode = RENDER_COLOR_NORMAL;
+
+      if (crTextStroke != 0) {
+        CFX_FloatPoint pt1;
+        CFX_FloatPoint pt2;
+        pUser2Device->Transform(pt1.x, pt1.y);
+        pUser2Device->Transform(pt2.x, pt2.y);
+        CFX_GraphStateData gsd;
+        gsd.m_LineWidth =
+            (FX_FLOAT)FXSYS_fabs((pt2.x + pt2.y) - (pt1.x + pt1.y));
+
+        CPDF_TextRenderer::DrawTextString(pDevice, x, y, pFont, fFontSize, &mt,
+                                          str, crTextFill, crTextStroke, &gsd,
+                                          &ro);
+      } else {
+        CPDF_TextRenderer::DrawTextString(pDevice, x, y, pFont, fFontSize, &mt,
+                                          str, crTextFill, 0, nullptr, &ro);
+      }
+    } else {
+      CPDF_RenderOptions ro;
+      ro.m_Flags = RENDER_CLEARTYPE;
+      ro.m_ColorMode = RENDER_COLOR_NORMAL;
+
+      if (crTextStroke != 0) {
+        CFX_FloatPoint pt1;
+        CFX_FloatPoint pt2;
+        pUser2Device->Transform(pt1.x, pt1.y);
+        pUser2Device->Transform(pt2.x, pt2.y);
+        CFX_GraphStateData gsd;
+        gsd.m_LineWidth =
+            (FX_FLOAT)FXSYS_fabs((pt2.x + pt2.y) - (pt1.x + pt1.y));
+
+        CPDF_TextRenderer::DrawTextString(pDevice, x, y, pFont, fFontSize,
+                                          pUser2Device, str, crTextFill,
+                                          crTextStroke, &gsd, &ro);
+      } else {
+        CPDF_TextRenderer::DrawTextString(pDevice, x, y, pFont, fFontSize,
+                                          pUser2Device, str, crTextFill, 0,
+                                          nullptr, &ro);
+      }
+    }
+  }
+}
+
+CPDF_TextObject* AddTextObjToPageObjects(CPDF_PageObjectHolder* pObjectHolder,
+                                         FX_COLORREF crText,
+                                         CPDF_Font* pFont,
+                                         FX_FLOAT fFontSize,
+                                         FX_FLOAT fCharSpace,
+                                         int32_t nHorzScale,
+                                         const CFX_FloatPoint& point,
+                                         const CFX_ByteString& text) {
+  std::unique_ptr<CPDF_TextObject> pTxtObj(new CPDF_TextObject);
+  pTxtObj->m_TextState.SetFont(pFont);
+  pTxtObj->m_TextState.SetFontSize(fFontSize);
+  pTxtObj->m_TextState.SetCharSpace(fCharSpace);
+  pTxtObj->m_TextState.SetWordSpace(0);
+  pTxtObj->m_TextState.SetTextMode(TextRenderingMode::MODE_FILL);
+
+  FX_FLOAT* matrix = pTxtObj->m_TextState.GetMutableMatrix();
+  matrix[0] = nHorzScale / 100.0f;
+  matrix[1] = 0;
+  matrix[2] = 0;
+  matrix[3] = 1;
+
+  FX_FLOAT rgb[3];
+  rgb[0] = FXARGB_R(crText) / 255.0f;
+  rgb[1] = FXARGB_G(crText) / 255.0f;
+  rgb[2] = FXARGB_B(crText) / 255.0f;
+  pTxtObj->m_ColorState.SetFillColor(
+      CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB), rgb, 3);
+  pTxtObj->m_ColorState.SetStrokeColor(
+      CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB), rgb, 3);
+
+  pTxtObj->SetPosition(point.x, point.y);
+  pTxtObj->SetText(text);
+
+  CPDF_TextObject* pRet = pTxtObj.get();
+  pObjectHolder->GetPageObjectList()->push_back(std::move(pTxtObj));
+  return pRet;
+}
+
+}  // namespace
+
+CFX_Edit_Iterator::CFX_Edit_Iterator(CFX_Edit* pEdit,
+                                     CPDF_VariableText::Iterator* pVTIterator)
+    : m_pEdit(pEdit), m_pVTIterator(pVTIterator) {}
+
+CFX_Edit_Iterator::~CFX_Edit_Iterator() {}
+
+bool CFX_Edit_Iterator::NextWord() {
+  return m_pVTIterator->NextWord();
+}
+
+bool CFX_Edit_Iterator::PrevWord() {
+  return m_pVTIterator->PrevWord();
+}
+
+bool CFX_Edit_Iterator::GetWord(CPVT_Word& word) const {
+  ASSERT(m_pEdit);
+
+  if (m_pVTIterator->GetWord(word)) {
+    word.ptWord = m_pEdit->VTToEdit(word.ptWord);
+    return true;
+  }
+  return false;
+}
+
+bool CFX_Edit_Iterator::GetLine(CPVT_Line& line) const {
+  ASSERT(m_pEdit);
+
+  if (m_pVTIterator->GetLine(line)) {
+    line.ptLine = m_pEdit->VTToEdit(line.ptLine);
+    return true;
+  }
+  return false;
+}
+
+bool CFX_Edit_Iterator::GetSection(CPVT_Section& section) const {
+  ASSERT(m_pEdit);
+
+  if (m_pVTIterator->GetSection(section)) {
+    section.rcSection = m_pEdit->VTToEdit(section.rcSection);
+    return true;
+  }
+  return false;
+}
+
+void CFX_Edit_Iterator::SetAt(int32_t nWordIndex) {
+  m_pVTIterator->SetAt(nWordIndex);
+}
+
+void CFX_Edit_Iterator::SetAt(const CPVT_WordPlace& place) {
+  m_pVTIterator->SetAt(place);
+}
+
+const CPVT_WordPlace& CFX_Edit_Iterator::GetAt() const {
+  return m_pVTIterator->GetAt();
+}
+
+CFX_Edit_Provider::CFX_Edit_Provider(IPVT_FontMap* pFontMap)
+    : CPDF_VariableText::Provider(pFontMap), m_pFontMap(pFontMap) {
+  ASSERT(m_pFontMap);
+}
+
+CFX_Edit_Provider::~CFX_Edit_Provider() {}
+
+IPVT_FontMap* CFX_Edit_Provider::GetFontMap() {
+  return m_pFontMap;
+}
+
+int32_t CFX_Edit_Provider::GetCharWidth(int32_t nFontIndex, uint16_t word) {
+  if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex)) {
+    uint32_t charcode = word;
+
+    if (pPDFFont->IsUnicodeCompatible())
+      charcode = pPDFFont->CharCodeFromUnicode(word);
+    else
+      charcode = m_pFontMap->CharCodeFromUnicode(nFontIndex, word);
+
+    if (charcode != CPDF_Font::kInvalidCharCode)
+      return pPDFFont->GetCharWidthF(charcode);
+  }
+
+  return 0;
+}
+
+int32_t CFX_Edit_Provider::GetTypeAscent(int32_t nFontIndex) {
+  if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex))
+    return pPDFFont->GetTypeAscent();
+
+  return 0;
+}
+
+int32_t CFX_Edit_Provider::GetTypeDescent(int32_t nFontIndex) {
+  if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex))
+    return pPDFFont->GetTypeDescent();
+
+  return 0;
+}
+
+int32_t CFX_Edit_Provider::GetWordFontIndex(uint16_t word,
+                                            int32_t charset,
+                                            int32_t nFontIndex) {
+  return m_pFontMap->GetWordFontIndex(word, charset, nFontIndex);
+}
+
+int32_t CFX_Edit_Provider::GetDefaultFontIndex() {
+  return 0;
+}
+
+bool CFX_Edit_Provider::IsLatinWord(uint16_t word) {
+  return FX_EDIT_ISLATINWORD(word);
+}
+
+CFX_Edit_Refresh::CFX_Edit_Refresh() {}
+
+CFX_Edit_Refresh::~CFX_Edit_Refresh() {}
+
+void CFX_Edit_Refresh::BeginRefresh() {
+  m_RefreshRects.Empty();
+  m_OldLineRects = m_NewLineRects;
+}
+
+void CFX_Edit_Refresh::Push(const CPVT_WordRange& linerange,
+                            const CFX_FloatRect& rect) {
+  m_NewLineRects.Add(linerange, rect);
+}
+
+void CFX_Edit_Refresh::NoAnalyse() {
+  {
+    for (int32_t i = 0, sz = m_OldLineRects.GetSize(); i < sz; i++)
+      if (CFX_Edit_LineRect* pOldRect = m_OldLineRects.GetAt(i))
+        m_RefreshRects.Add(pOldRect->m_rcLine);
+  }
+
+  {
+    for (int32_t i = 0, sz = m_NewLineRects.GetSize(); i < sz; i++)
+      if (CFX_Edit_LineRect* pNewRect = m_NewLineRects.GetAt(i))
+        m_RefreshRects.Add(pNewRect->m_rcLine);
+  }
+}
+
+void CFX_Edit_Refresh::AddRefresh(const CFX_FloatRect& rect) {
+  m_RefreshRects.Add(rect);
+}
+
+const CFX_Edit_RectArray* CFX_Edit_Refresh::GetRefreshRects() const {
+  return &m_RefreshRects;
+}
+
+void CFX_Edit_Refresh::EndRefresh() {
+  m_RefreshRects.Empty();
+}
+
+CFX_Edit_Undo::CFX_Edit_Undo(int32_t nBufsize)
+    : m_nCurUndoPos(0),
+      m_nBufSize(nBufsize),
+      m_bModified(false),
+      m_bVirgin(true),
+      m_bWorking(false) {}
+
+CFX_Edit_Undo::~CFX_Edit_Undo() {
+  Reset();
+}
+
+bool CFX_Edit_Undo::CanUndo() const {
+  return m_nCurUndoPos > 0;
+}
+
+void CFX_Edit_Undo::Undo() {
+  m_bWorking = true;
+
+  if (m_nCurUndoPos > 0) {
+    IFX_Edit_UndoItem* pItem = m_UndoItemStack.GetAt(m_nCurUndoPos - 1);
+    pItem->Undo();
+
+    m_nCurUndoPos--;
+    m_bModified = (m_nCurUndoPos != 0);
+  }
+
+  m_bWorking = false;
+}
+
+bool CFX_Edit_Undo::CanRedo() const {
+  return m_nCurUndoPos < m_UndoItemStack.GetSize();
+}
+
+void CFX_Edit_Undo::Redo() {
+  m_bWorking = true;
+
+  int32_t nStackSize = m_UndoItemStack.GetSize();
+
+  if (m_nCurUndoPos < nStackSize) {
+    IFX_Edit_UndoItem* pItem = m_UndoItemStack.GetAt(m_nCurUndoPos);
+    pItem->Redo();
+
+    m_nCurUndoPos++;
+    m_bModified = (m_nCurUndoPos != 0);
+  }
+
+  m_bWorking = false;
+}
+
+void CFX_Edit_Undo::AddItem(IFX_Edit_UndoItem* pItem) {
+  ASSERT(!m_bWorking);
+  ASSERT(pItem);
+  ASSERT(m_nBufSize > 1);
+
+  if (m_nCurUndoPos < m_UndoItemStack.GetSize())
+    RemoveTails();
+
+  if (m_UndoItemStack.GetSize() >= m_nBufSize) {
+    RemoveHeads();
+    m_bVirgin = false;
+  }
+
+  m_UndoItemStack.Add(pItem);
+  m_nCurUndoPos = m_UndoItemStack.GetSize();
+
+  m_bModified = (m_nCurUndoPos != 0);
+}
+
+bool CFX_Edit_Undo::IsModified() const {
+  return m_bVirgin ? m_bModified : true;
+}
+
+void CFX_Edit_Undo::RemoveHeads() {
+  ASSERT(m_UndoItemStack.GetSize() > 1);
+
+  delete m_UndoItemStack.GetAt(0);
+  m_UndoItemStack.RemoveAt(0);
+}
+
+void CFX_Edit_Undo::RemoveTails() {
+  for (int32_t i = m_UndoItemStack.GetSize() - 1; i >= m_nCurUndoPos; i--) {
+    delete m_UndoItemStack.GetAt(i);
+    m_UndoItemStack.RemoveAt(i);
+  }
+}
+
+void CFX_Edit_Undo::Reset() {
+  for (int32_t i = 0, sz = m_UndoItemStack.GetSize(); i < sz; i++) {
+    delete m_UndoItemStack.GetAt(i);
+  }
+  m_nCurUndoPos = 0;
+  m_UndoItemStack.RemoveAll();
+}
+
+CFX_Edit_UndoItem::CFX_Edit_UndoItem() : m_bFirst(true), m_bLast(true) {}
+
+CFX_Edit_UndoItem::~CFX_Edit_UndoItem() {}
+
+CFX_WideString CFX_Edit_UndoItem::GetUndoTitle() {
+  return L"";
+}
+
+void CFX_Edit_UndoItem::SetFirst(bool bFirst) {
+  m_bFirst = bFirst;
+}
+
+void CFX_Edit_UndoItem::SetLast(bool bLast) {
+  m_bLast = bLast;
+}
+
+bool CFX_Edit_UndoItem::IsLast() {
+  return m_bLast;
+}
+
+CFX_Edit_GroupUndoItem::CFX_Edit_GroupUndoItem(const CFX_WideString& sTitle)
+    : m_sTitle(sTitle) {}
+
+CFX_Edit_GroupUndoItem::~CFX_Edit_GroupUndoItem() {
+  for (int i = 0, sz = m_Items.GetSize(); i < sz; i++) {
+    delete m_Items[i];
+  }
+
+  m_Items.RemoveAll();
+}
+
+void CFX_Edit_GroupUndoItem::AddUndoItem(CFX_Edit_UndoItem* pUndoItem) {
+  pUndoItem->SetFirst(false);
+  pUndoItem->SetLast(false);
+
+  m_Items.Add(pUndoItem);
+
+  if (m_sTitle.IsEmpty())
+    m_sTitle = pUndoItem->GetUndoTitle();
+}
+
+void CFX_Edit_GroupUndoItem::UpdateItems() {
+  if (m_Items.GetSize() > 0) {
+    CFX_Edit_UndoItem* pFirstItem = m_Items[0];
+    pFirstItem->SetFirst(true);
+
+    CFX_Edit_UndoItem* pLastItem = m_Items[m_Items.GetSize() - 1];
+    pLastItem->SetLast(true);
+  }
+}
+
+void CFX_Edit_GroupUndoItem::Undo() {
+  for (int i = m_Items.GetSize() - 1; i >= 0; i--) {
+    CFX_Edit_UndoItem* pUndoItem = m_Items[i];
+    pUndoItem->Undo();
+  }
+}
+
+void CFX_Edit_GroupUndoItem::Redo() {
+  for (int i = 0, sz = m_Items.GetSize(); i < sz; i++) {
+    CFX_Edit_UndoItem* pUndoItem = m_Items[i];
+    pUndoItem->Redo();
+  }
+}
+
+CFX_WideString CFX_Edit_GroupUndoItem::GetUndoTitle() {
+  return m_sTitle;
+}
+
+CFXEU_InsertWord::CFXEU_InsertWord(CFX_Edit* pEdit,
+                                   const CPVT_WordPlace& wpOldPlace,
+                                   const CPVT_WordPlace& wpNewPlace,
+                                   uint16_t word,
+                                   int32_t charset,
+                                   const CPVT_WordProps* pWordProps)
+    : m_pEdit(pEdit),
+      m_wpOld(wpOldPlace),
+      m_wpNew(wpNewPlace),
+      m_Word(word),
+      m_nCharset(charset),
+      m_WordProps() {
+  if (pWordProps)
+    m_WordProps = *pWordProps;
+}
+
+CFXEU_InsertWord::~CFXEU_InsertWord() {}
+
+void CFXEU_InsertWord::Redo() {
+  if (m_pEdit) {
+    m_pEdit->SelectNone();
+    m_pEdit->SetCaret(m_wpOld);
+    m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, false, true);
+  }
+}
+
+void CFXEU_InsertWord::Undo() {
+  if (m_pEdit) {
+    m_pEdit->SelectNone();
+    m_pEdit->SetCaret(m_wpNew);
+    m_pEdit->Backspace(false, true);
+  }
+}
+
+CFXEU_InsertReturn::CFXEU_InsertReturn(CFX_Edit* pEdit,
+                                       const CPVT_WordPlace& wpOldPlace,
+                                       const CPVT_WordPlace& wpNewPlace,
+                                       const CPVT_SecProps* pSecProps,
+                                       const CPVT_WordProps* pWordProps)
+    : m_pEdit(pEdit),
+      m_wpOld(wpOldPlace),
+      m_wpNew(wpNewPlace),
+      m_SecProps(),
+      m_WordProps() {
+  if (pSecProps)
+    m_SecProps = *pSecProps;
+  if (pWordProps)
+    m_WordProps = *pWordProps;
+}
+
+CFXEU_InsertReturn::~CFXEU_InsertReturn() {}
+
+void CFXEU_InsertReturn::Redo() {
+  if (m_pEdit) {
+    m_pEdit->SelectNone();
+    m_pEdit->SetCaret(m_wpOld);
+    m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, false, true);
+  }
+}
+
+void CFXEU_InsertReturn::Undo() {
+  if (m_pEdit) {
+    m_pEdit->SelectNone();
+    m_pEdit->SetCaret(m_wpNew);
+    m_pEdit->Backspace(false, true);
+  }
+}
+
+CFXEU_Backspace::CFXEU_Backspace(CFX_Edit* pEdit,
+                                 const CPVT_WordPlace& wpOldPlace,
+                                 const CPVT_WordPlace& wpNewPlace,
+                                 uint16_t word,
+                                 int32_t charset,
+                                 const CPVT_SecProps& SecProps,
+                                 const CPVT_WordProps& WordProps)
+    : m_pEdit(pEdit),
+      m_wpOld(wpOldPlace),
+      m_wpNew(wpNewPlace),
+      m_Word(word),
+      m_nCharset(charset),
+      m_SecProps(SecProps),
+      m_WordProps(WordProps) {}
+
+CFXEU_Backspace::~CFXEU_Backspace() {}
+
+void CFXEU_Backspace::Redo() {
+  if (m_pEdit) {
+    m_pEdit->SelectNone();
+    m_pEdit->SetCaret(m_wpOld);
+    m_pEdit->Backspace(false, true);
+  }
+}
+
+void CFXEU_Backspace::Undo() {
+  if (m_pEdit) {
+    m_pEdit->SelectNone();
+    m_pEdit->SetCaret(m_wpNew);
+    if (m_wpNew.SecCmp(m_wpOld) != 0) {
+      m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, false, true);
+    } else {
+      m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, false, true);
+    }
+  }
+}
+
+CFXEU_Delete::CFXEU_Delete(CFX_Edit* pEdit,
+                           const CPVT_WordPlace& wpOldPlace,
+                           const CPVT_WordPlace& wpNewPlace,
+                           uint16_t word,
+                           int32_t charset,
+                           const CPVT_SecProps& SecProps,
+                           const CPVT_WordProps& WordProps,
+                           bool bSecEnd)
+    : m_pEdit(pEdit),
+      m_wpOld(wpOldPlace),
+      m_wpNew(wpNewPlace),
+      m_Word(word),
+      m_nCharset(charset),
+      m_SecProps(SecProps),
+      m_WordProps(WordProps),
+      m_bSecEnd(bSecEnd) {}
+
+CFXEU_Delete::~CFXEU_Delete() {}
+
+void CFXEU_Delete::Redo() {
+  if (m_pEdit) {
+    m_pEdit->SelectNone();
+    m_pEdit->SetCaret(m_wpOld);
+    m_pEdit->Delete(false, true);
+  }
+}
+
+void CFXEU_Delete::Undo() {
+  if (m_pEdit) {
+    m_pEdit->SelectNone();
+    m_pEdit->SetCaret(m_wpNew);
+    if (m_bSecEnd) {
+      m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, false, true);
+    } else {
+      m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, false, true);
+    }
+  }
+}
+
+CFXEU_Clear::CFXEU_Clear(CFX_Edit* pEdit,
+                         const CPVT_WordRange& wrSel,
+                         const CFX_WideString& swText)
+    : m_pEdit(pEdit), m_wrSel(wrSel), m_swText(swText) {}
+
+CFXEU_Clear::~CFXEU_Clear() {}
+
+void CFXEU_Clear::Redo() {
+  if (m_pEdit) {
+    m_pEdit->SelectNone();
+    m_pEdit->SetSel(m_wrSel.BeginPos, m_wrSel.EndPos);
+    m_pEdit->Clear(false, true);
+  }
+}
+
+void CFXEU_Clear::Undo() {
+  if (m_pEdit) {
+    m_pEdit->SelectNone();
+    m_pEdit->SetCaret(m_wrSel.BeginPos);
+    m_pEdit->InsertText(m_swText, FXFONT_DEFAULT_CHARSET, false, true);
+    m_pEdit->SetSel(m_wrSel.BeginPos, m_wrSel.EndPos);
+  }
+}
+
+CFXEU_InsertText::CFXEU_InsertText(CFX_Edit* pEdit,
+                                   const CPVT_WordPlace& wpOldPlace,
+                                   const CPVT_WordPlace& wpNewPlace,
+                                   const CFX_WideString& swText,
+                                   int32_t charset)
+    : m_pEdit(pEdit),
+      m_wpOld(wpOldPlace),
+      m_wpNew(wpNewPlace),
+      m_swText(swText),
+      m_nCharset(charset) {}
+
+CFXEU_InsertText::~CFXEU_InsertText() {}
+
+void CFXEU_InsertText::Redo() {
+  if (m_pEdit && IsLast()) {
+    m_pEdit->SelectNone();
+    m_pEdit->SetCaret(m_wpOld);
+    m_pEdit->InsertText(m_swText, m_nCharset, false, true);
+  }
+}
+
+void CFXEU_InsertText::Undo() {
+  if (m_pEdit) {
+    m_pEdit->SelectNone();
+    m_pEdit->SetSel(m_wpOld, m_wpNew);
+    m_pEdit->Clear(false, true);
+  }
+}
+
+// static
+CFX_ByteString CFX_Edit::GetEditAppearanceStream(CFX_Edit* pEdit,
+                                                 const CFX_FloatPoint& ptOffset,
+                                                 const CPVT_WordRange* pRange,
+                                                 bool bContinuous,
+                                                 uint16_t SubWord) {
+  CFX_Edit_Iterator* pIterator = pEdit->GetIterator();
+  if (pRange)
+    pIterator->SetAt(pRange->BeginPos);
+  else
+    pIterator->SetAt(0);
+
+  CFX_ByteTextBuf sEditStream;
+  CFX_ByteTextBuf sWords;
+  int32_t nCurFontIndex = -1;
+  CFX_FloatPoint ptOld;
+  CFX_FloatPoint ptNew;
+  CPVT_WordPlace oldplace;
+
+  while (pIterator->NextWord()) {
+    CPVT_WordPlace place = pIterator->GetAt();
+    if (pRange && place.WordCmp(pRange->EndPos) > 0)
+      break;
+
+    if (bContinuous) {
+      if (place.LineCmp(oldplace) != 0) {
+        if (sWords.GetSize() > 0) {
+          sEditStream << GetWordRenderString(sWords.MakeString());
+          sWords.Clear();
+        }
+
+        CPVT_Word word;
+        if (pIterator->GetWord(word)) {
+          ptNew = CFX_FloatPoint(word.ptWord.x + ptOffset.x,
+                                 word.ptWord.y + ptOffset.y);
+        } else {
+          CPVT_Line line;
+          pIterator->GetLine(line);
+          ptNew = CFX_FloatPoint(line.ptLine.x + ptOffset.x,
+                                 line.ptLine.y + ptOffset.y);
+        }
+
+        if (ptNew.x != ptOld.x || ptNew.y != ptOld.y) {
+          sEditStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y
+                      << " Td\n";
+
+          ptOld = ptNew;
+        }
+      }
+
+      CPVT_Word word;
+      if (pIterator->GetWord(word)) {
+        if (word.nFontIndex != nCurFontIndex) {
+          if (sWords.GetSize() > 0) {
+            sEditStream << GetWordRenderString(sWords.MakeString());
+            sWords.Clear();
+          }
+          sEditStream << GetFontSetString(pEdit->GetFontMap(), word.nFontIndex,
+                                          word.fFontSize);
+          nCurFontIndex = word.nFontIndex;
+        }
+
+        sWords << GetPDFWordString(pEdit->GetFontMap(), nCurFontIndex,
+                                   word.Word, SubWord);
+      }
+
+      oldplace = place;
+    } else {
+      CPVT_Word word;
+      if (pIterator->GetWord(word)) {
+        ptNew = CFX_FloatPoint(word.ptWord.x + ptOffset.x,
+                               word.ptWord.y + ptOffset.y);
+
+        if (ptNew.x != ptOld.x || ptNew.y != ptOld.y) {
+          sEditStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y
+                      << " Td\n";
+          ptOld = ptNew;
+        }
+
+        if (word.nFontIndex != nCurFontIndex) {
+          sEditStream << GetFontSetString(pEdit->GetFontMap(), word.nFontIndex,
+                                          word.fFontSize);
+          nCurFontIndex = word.nFontIndex;
+        }
+
+        sEditStream << GetWordRenderString(GetPDFWordString(
+            pEdit->GetFontMap(), nCurFontIndex, word.Word, SubWord));
+      }
+    }
+  }
+
+  if (sWords.GetSize() > 0) {
+    sEditStream << GetWordRenderString(sWords.MakeString());
+    sWords.Clear();
+  }
+
+  CFX_ByteTextBuf sAppStream;
+  if (sEditStream.GetSize() > 0) {
+    int32_t nHorzScale = pEdit->GetHorzScale();
+    if (nHorzScale != 100) {
+      sAppStream << nHorzScale << " Tz\n";
+    }
+
+    FX_FLOAT fCharSpace = pEdit->GetCharSpace();
+    if (!IsFloatZero(fCharSpace)) {
+      sAppStream << fCharSpace << " Tc\n";
+    }
+
+    sAppStream << sEditStream;
+  }
+
+  return sAppStream.MakeString();
+}
+
+// static
+CFX_ByteString CFX_Edit::GetSelectAppearanceStream(
+    CFX_Edit* pEdit,
+    const CFX_FloatPoint& ptOffset,
+    const CPVT_WordRange* pRange) {
+  if (!pRange || !pRange->IsExist())
+    return CFX_ByteString();
+
+  CFX_Edit_Iterator* pIterator = pEdit->GetIterator();
+  pIterator->SetAt(pRange->BeginPos);
+
+  CFX_ByteTextBuf sRet;
+  while (pIterator->NextWord()) {
+    CPVT_WordPlace place = pIterator->GetAt();
+    if (place.WordCmp(pRange->EndPos) > 0)
+      break;
+
+    CPVT_Word word;
+    CPVT_Line line;
+    if (pIterator->GetWord(word) && pIterator->GetLine(line)) {
+      sRet << word.ptWord.x + ptOffset.x << " "
+           << line.ptLine.y + line.fLineDescent << " " << word.fWidth << " "
+           << line.fLineAscent - line.fLineDescent << " re\nf\n";
+    }
+  }
+
+  return sRet.MakeString();
+}
+
+// static
+void CFX_Edit::DrawEdit(CFX_RenderDevice* pDevice,
+                        CFX_Matrix* pUser2Device,
+                        CFX_Edit* pEdit,
+                        FX_COLORREF crTextFill,
+                        FX_COLORREF crTextStroke,
+                        const CFX_FloatRect& rcClip,
+                        const CFX_FloatPoint& ptOffset,
+                        const CPVT_WordRange* pRange,
+                        CFX_SystemHandler* pSystemHandler,
+                        CFFL_FormFiller* pFFLData) {
+  const bool bContinuous =
+      pEdit->GetCharArray() == 0 && pEdit->GetCharSpace() <= 0.0f;
+  uint16_t SubWord = pEdit->GetPasswordChar();
+  FX_FLOAT fFontSize = pEdit->GetFontSize();
+  CPVT_WordRange wrSelect = pEdit->GetSelectWordRange();
+  int32_t nHorzScale = pEdit->GetHorzScale();
+
+  FX_COLORREF crCurFill = crTextFill;
+  FX_COLORREF crOldFill = crCurFill;
+
+  bool bSelect = false;
+  const FX_COLORREF crWhite = ArgbEncode(255, 255, 255, 255);
+  const FX_COLORREF crSelBK = ArgbEncode(255, 0, 51, 113);
+
+  CFX_ByteTextBuf sTextBuf;
+  int32_t nFontIndex = -1;
+  CFX_FloatPoint ptBT;
+  pDevice->SaveState();
+  if (!rcClip.IsEmpty()) {
+    CFX_FloatRect rcTemp = rcClip;
+    pUser2Device->TransformRect(rcTemp);
+    pDevice->SetClip_Rect(rcTemp.ToFxRect());
+  }
+
+  CFX_Edit_Iterator* pIterator = pEdit->GetIterator();
+  if (IPVT_FontMap* pFontMap = pEdit->GetFontMap()) {
+    if (pRange)
+      pIterator->SetAt(pRange->BeginPos);
+    else
+      pIterator->SetAt(0);
+
+    CPVT_WordPlace oldplace;
+    while (pIterator->NextWord()) {
+      CPVT_WordPlace place = pIterator->GetAt();
+      if (pRange && place.WordCmp(pRange->EndPos) > 0)
+        break;
+
+      if (wrSelect.IsExist()) {
+        bSelect = place.WordCmp(wrSelect.BeginPos) > 0 &&
+                  place.WordCmp(wrSelect.EndPos) <= 0;
+        crCurFill = bSelect ? crWhite : crTextFill;
+      }
+      if (pSystemHandler && pSystemHandler->IsSelectionImplemented()) {
+        crCurFill = crTextFill;
+        crOldFill = crCurFill;
+      }
+      CPVT_Word word;
+      if (pIterator->GetWord(word)) {
+        if (bSelect) {
+          CPVT_Line line;
+          pIterator->GetLine(line);
+
+          if (pSystemHandler && pSystemHandler->IsSelectionImplemented()) {
+            CFX_FloatRect rc(word.ptWord.x, line.ptLine.y + line.fLineDescent,
+                             word.ptWord.x + word.fWidth,
+                             line.ptLine.y + line.fLineAscent);
+            rc.Intersect(rcClip);
+            pSystemHandler->OutputSelectedRect(pFFLData, rc);
+          } else {
+            CFX_PathData pathSelBK;
+            pathSelBK.AppendRect(
+                word.ptWord.x, line.ptLine.y + line.fLineDescent,
+                word.ptWord.x + word.fWidth, line.ptLine.y + line.fLineAscent);
+
+            pDevice->DrawPath(&pathSelBK, pUser2Device, nullptr, crSelBK, 0,
+                              FXFILL_WINDING);
+          }
+        }
+
+        if (bContinuous) {
+          if (place.LineCmp(oldplace) != 0 || word.nFontIndex != nFontIndex ||
+              crOldFill != crCurFill) {
+            if (sTextBuf.GetLength() > 0) {
+              DrawTextString(
+                  pDevice,
+                  CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
+                  pFontMap->GetPDFFont(nFontIndex), fFontSize, pUser2Device,
+                  sTextBuf.MakeString(), crOldFill, crTextStroke, nHorzScale);
+
+              sTextBuf.Clear();
+            }
+            nFontIndex = word.nFontIndex;
+            ptBT = word.ptWord;
+            crOldFill = crCurFill;
+          }
+
+          sTextBuf << GetPDFWordString(pFontMap, word.nFontIndex, word.Word,
+                                       SubWord)
+                          .AsStringC();
+        } else {
+          DrawTextString(
+              pDevice, CFX_FloatPoint(word.ptWord.x + ptOffset.x,
+                                      word.ptWord.y + ptOffset.y),
+              pFontMap->GetPDFFont(word.nFontIndex), fFontSize, pUser2Device,
+              GetPDFWordString(pFontMap, word.nFontIndex, word.Word, SubWord),
+              crCurFill, crTextStroke, nHorzScale);
+        }
+        oldplace = place;
+      }
+    }
+
+    if (sTextBuf.GetLength() > 0) {
+      DrawTextString(
+          pDevice, CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
+          pFontMap->GetPDFFont(nFontIndex), fFontSize, pUser2Device,
+          sTextBuf.MakeString(), crOldFill, crTextStroke, nHorzScale);
+    }
+  }
+
+  pDevice->RestoreState(false);
+}
+
+// static
+void CFX_Edit::GeneratePageObjects(CPDF_PageObjectHolder* pObjectHolder,
+                                   CFX_Edit* pEdit,
+                                   const CFX_FloatPoint& ptOffset,
+                                   const CPVT_WordRange* pRange,
+                                   FX_COLORREF crText,
+                                   std::vector<CPDF_TextObject*>* ObjArray) {
+  ObjArray->clear();
+
+  IPVT_FontMap* pFontMap = pEdit->GetFontMap();
+  if (!pFontMap)
+    return;
+
+  FX_FLOAT fFontSize = pEdit->GetFontSize();
+  int32_t nOldFontIndex = -1;
+  CFX_ByteTextBuf sTextBuf;
+  CPVT_WordPlace oldplace;
+  CFX_FloatPoint ptBT(0.0f, 0.0f);
+  CFX_Edit_Iterator* pIterator = pEdit->GetIterator();
+  if (pRange)
+    pIterator->SetAt(pRange->BeginPos);
+  else
+    pIterator->SetAt(0);
+
+  while (pIterator->NextWord()) {
+    CPVT_WordPlace place = pIterator->GetAt();
+    if (pRange && place.WordCmp(pRange->EndPos) > 0)
+      break;
+
+    CPVT_Word word;
+    if (!pIterator->GetWord(word))
+      continue;
+
+    if (place.LineCmp(oldplace) != 0 || nOldFontIndex != word.nFontIndex) {
+      if (sTextBuf.GetLength() > 0) {
+        ObjArray->push_back(AddTextObjToPageObjects(
+            pObjectHolder, crText, pFontMap->GetPDFFont(nOldFontIndex),
+            fFontSize, 0.0f, 100,
+            CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
+            sTextBuf.MakeString()));
+
+        sTextBuf.Clear();
+      }
+      ptBT = word.ptWord;
+      nOldFontIndex = word.nFontIndex;
+    }
+    sTextBuf << GetPDFWordString(pFontMap, word.nFontIndex, word.Word, 0)
+                    .AsStringC();
+    oldplace = place;
+  }
+  if (sTextBuf.GetLength() > 0) {
+    ObjArray->push_back(AddTextObjToPageObjects(
+        pObjectHolder, crText, pFontMap->GetPDFFont(nOldFontIndex), fFontSize,
+        0.0f, 100, CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
+        sTextBuf.MakeString()));
+  }
+}
+
+CFX_Edit::CFX_Edit()
+    : m_pVT(new CPDF_VariableText),
+      m_pNotify(nullptr),
+      m_pOprNotify(nullptr),
+      m_wpCaret(-1, -1, -1),
+      m_wpOldCaret(-1, -1, -1),
+      m_SelState(),
+      m_bEnableScroll(false),
+      m_Undo(kEditUndoMaxItems),
+      m_nAlignment(0),
+      m_bNotifyFlag(false),
+      m_bEnableOverflow(false),
+      m_bEnableRefresh(true),
+      m_rcOldContent(0.0f, 0.0f, 0.0f, 0.0f),
+      m_bEnableUndo(true),
+      m_bOprNotify(false),
+      m_pGroupUndoItem(nullptr) {}
+
+CFX_Edit::~CFX_Edit() {
+  ASSERT(!m_pGroupUndoItem);
+}
+
+void CFX_Edit::Initialize() {
+  m_pVT->Initialize();
+  SetCaret(m_pVT->GetBeginWordPlace());
+  SetCaretOrigin();
+}
+
+void CFX_Edit::SetFontMap(IPVT_FontMap* pFontMap) {
+  m_pVTProvider = pdfium::MakeUnique<CFX_Edit_Provider>(pFontMap);
+  m_pVT->SetProvider(m_pVTProvider.get());
+}
+
+void CFX_Edit::SetNotify(CPWL_EditCtrl* pNotify) {
+  m_pNotify = pNotify;
+}
+
+void CFX_Edit::SetOprNotify(CPWL_Edit* pOprNotify) {
+  m_pOprNotify = pOprNotify;
+}
+
+CFX_Edit_Iterator* CFX_Edit::GetIterator() {
+  if (!m_pIterator) {
+    m_pIterator =
+        pdfium::MakeUnique<CFX_Edit_Iterator>(this, m_pVT->GetIterator());
+  }
+  return m_pIterator.get();
+}
+
+IPVT_FontMap* CFX_Edit::GetFontMap() {
+  return m_pVTProvider ? m_pVTProvider->GetFontMap() : nullptr;
+}
+
+void CFX_Edit::SetPlateRect(const CFX_FloatRect& rect) {
+  m_pVT->SetPlateRect(rect);
+  m_ptScrollPos = CFX_FloatPoint(rect.left, rect.top);
+  Paint();
+}
+
+void CFX_Edit::SetAlignmentH(int32_t nFormat, bool bPaint) {
+  m_pVT->SetAlignment(nFormat);
+  if (bPaint)
+    Paint();
+}
+
+void CFX_Edit::SetAlignmentV(int32_t nFormat, bool bPaint) {
+  m_nAlignment = nFormat;
+  if (bPaint)
+    Paint();
+}
+
+void CFX_Edit::SetPasswordChar(uint16_t wSubWord, bool bPaint) {
+  m_pVT->SetPasswordChar(wSubWord);
+  if (bPaint)
+    Paint();
+}
+
+void CFX_Edit::SetLimitChar(int32_t nLimitChar) {
+  m_pVT->SetLimitChar(nLimitChar);
+  Paint();
+}
+
+void CFX_Edit::SetCharArray(int32_t nCharArray) {
+  m_pVT->SetCharArray(nCharArray);
+  Paint();
+}
+
+void CFX_Edit::SetCharSpace(FX_FLOAT fCharSpace) {
+  m_pVT->SetCharSpace(fCharSpace);
+  Paint();
+}
+
+void CFX_Edit::SetMultiLine(bool bMultiLine, bool bPaint) {
+  m_pVT->SetMultiLine(bMultiLine);
+  if (bPaint)
+    Paint();
+}
+
+void CFX_Edit::SetAutoReturn(bool bAuto, bool bPaint) {
+  m_pVT->SetAutoReturn(bAuto);
+  if (bPaint)
+    Paint();
+}
+
+void CFX_Edit::SetAutoFontSize(bool bAuto, bool bPaint) {
+  m_pVT->SetAutoFontSize(bAuto);
+  if (bPaint)
+    Paint();
+}
+
+void CFX_Edit::SetFontSize(FX_FLOAT fFontSize) {
+  m_pVT->SetFontSize(fFontSize);
+  Paint();
+}
+
+void CFX_Edit::SetAutoScroll(bool bAuto, bool bPaint) {
+  m_bEnableScroll = bAuto;
+  if (bPaint)
+    Paint();
+}
+
+void CFX_Edit::SetTextOverflow(bool bAllowed, bool bPaint) {
+  m_bEnableOverflow = bAllowed;
+  if (bPaint)
+    Paint();
+}
+
+void CFX_Edit::SetSel(int32_t nStartChar, int32_t nEndChar) {
+  if (m_pVT->IsValid()) {
+    if (nStartChar == 0 && nEndChar < 0) {
+      SelectAll();
+    } else if (nStartChar < 0) {
+      SelectNone();
+    } else {
+      if (nStartChar < nEndChar) {
+        SetSel(m_pVT->WordIndexToWordPlace(nStartChar),
+               m_pVT->WordIndexToWordPlace(nEndChar));
+      } else {
+        SetSel(m_pVT->WordIndexToWordPlace(nEndChar),
+               m_pVT->WordIndexToWordPlace(nStartChar));
+      }
+    }
+  }
+}
+
+void CFX_Edit::SetSel(const CPVT_WordPlace& begin, const CPVT_WordPlace& end) {
+  if (m_pVT->IsValid()) {
+    SelectNone();
+
+    m_SelState.Set(begin, end);
+
+    SetCaret(m_SelState.EndPos);
+
+    if (m_SelState.IsExist()) {
+      ScrollToCaret();
+      Refresh();
+      SetCaretInfo();
+    } else {
+      ScrollToCaret();
+      SetCaretInfo();
+    }
+  }
+}
+
+void CFX_Edit::GetSel(int32_t& nStartChar, int32_t& nEndChar) const {
+  nStartChar = -1;
+  nEndChar = -1;
+
+  if (m_pVT->IsValid()) {
+    if (m_SelState.IsExist()) {
+      if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos) < 0) {
+        nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos);
+        nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos);
+      } else {
+        nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos);
+        nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos);
+      }
+    } else {
+      nStartChar = m_pVT->WordPlaceToWordIndex(m_wpCaret);
+      nEndChar = m_pVT->WordPlaceToWordIndex(m_wpCaret);
+    }
+  }
+}
+
+int32_t CFX_Edit::GetCaret() const {
+  if (m_pVT->IsValid())
+    return m_pVT->WordPlaceToWordIndex(m_wpCaret);
+
+  return -1;
+}
+
+CPVT_WordPlace CFX_Edit::GetCaretWordPlace() const {
+  return m_wpCaret;
+}
+
+CFX_WideString CFX_Edit::GetText() const {
+  CFX_WideString swRet;
+
+  if (!m_pVT->IsValid())
+    return swRet;
+
+  CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
+  pIterator->SetAt(0);
+
+  CPVT_Word wordinfo;
+  CPVT_WordPlace oldplace = pIterator->GetAt();
+  while (pIterator->NextWord()) {
+    CPVT_WordPlace place = pIterator->GetAt();
+
+    if (pIterator->GetWord(wordinfo))
+      swRet += wordinfo.Word;
+
+    if (oldplace.SecCmp(place) != 0)
+      swRet += L"\r\n";
+
+    oldplace = place;
+  }
+
+  return swRet;
+}
+
+CFX_WideString CFX_Edit::GetRangeText(const CPVT_WordRange& range) const {
+  CFX_WideString swRet;
+
+  if (!m_pVT->IsValid())
+    return swRet;
+
+  CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
+  CPVT_WordRange wrTemp = range;
+  m_pVT->UpdateWordPlace(wrTemp.BeginPos);
+  m_pVT->UpdateWordPlace(wrTemp.EndPos);
+  pIterator->SetAt(wrTemp.BeginPos);
+
+  CPVT_Word wordinfo;
+  CPVT_WordPlace oldplace = wrTemp.BeginPos;
+  while (pIterator->NextWord()) {
+    CPVT_WordPlace place = pIterator->GetAt();
+    if (place.WordCmp(wrTemp.EndPos) > 0)
+      break;
+
+    if (pIterator->GetWord(wordinfo))
+      swRet += wordinfo.Word;
+
+    if (oldplace.SecCmp(place) != 0)
+      swRet += L"\r\n";
+
+    oldplace = place;
+  }
+
+  return swRet;
+}
+
+CFX_WideString CFX_Edit::GetSelText() const {
+  return GetRangeText(m_SelState.ConvertToWordRange());
+}
+
+int32_t CFX_Edit::GetTotalWords() const {
+  return m_pVT->GetTotalWords();
+}
+
+int32_t CFX_Edit::GetTotalLines() const {
+  int32_t nLines = 1;
+
+  CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
+  pIterator->SetAt(0);
+  while (pIterator->NextLine())
+    ++nLines;
+
+  return nLines;
+}
+
+CPVT_WordRange CFX_Edit::GetSelectWordRange() const {
+  return m_SelState.ConvertToWordRange();
+}
+
+void CFX_Edit::SetText(const CFX_WideString& sText) {
+  Empty();
+  DoInsertText(CPVT_WordPlace(0, 0, -1), sText, FXFONT_DEFAULT_CHARSET);
+  Paint();
+}
+
+bool CFX_Edit::InsertWord(uint16_t word, int32_t charset) {
+  return InsertWord(word, charset, nullptr, true, true);
+}
+
+bool CFX_Edit::InsertReturn() {
+  return InsertReturn(nullptr, nullptr, true, true);
+}
+
+bool CFX_Edit::Backspace() {
+  return Backspace(true, true);
+}
+
+bool CFX_Edit::Delete() {
+  return Delete(true, true);
+}
+
+bool CFX_Edit::Clear() {
+  return Clear(true, true);
+}
+
+bool CFX_Edit::InsertText(const CFX_WideString& sText, int32_t charset) {
+  return InsertText(sText, charset, true, true);
+}
+
+FX_FLOAT CFX_Edit::GetFontSize() const {
+  return m_pVT->GetFontSize();
+}
+
+uint16_t CFX_Edit::GetPasswordChar() const {
+  return m_pVT->GetPasswordChar();
+}
+
+int32_t CFX_Edit::GetCharArray() const {
+  return m_pVT->GetCharArray();
+}
+
+CFX_FloatRect CFX_Edit::GetContentRect() const {
+  return VTToEdit(m_pVT->GetContentRect());
+}
+
+int32_t CFX_Edit::GetHorzScale() const {
+  return m_pVT->GetHorzScale();
+}
+
+FX_FLOAT CFX_Edit::GetCharSpace() const {
+  return m_pVT->GetCharSpace();
+}
+
+CPVT_WordRange CFX_Edit::GetWholeWordRange() const {
+  if (m_pVT->IsValid())
+    return CPVT_WordRange(m_pVT->GetBeginWordPlace(), m_pVT->GetEndWordPlace());
+
+  return CPVT_WordRange();
+}
+
+CPVT_WordRange CFX_Edit::GetVisibleWordRange() const {
+  if (m_bEnableOverflow)
+    return GetWholeWordRange();
+
+  if (m_pVT->IsValid()) {
+    CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
+
+    CPVT_WordPlace place1 = m_pVT->SearchWordPlace(
+        EditToVT(CFX_FloatPoint(rcPlate.left, rcPlate.top)));
+    CPVT_WordPlace place2 = m_pVT->SearchWordPlace(
+        EditToVT(CFX_FloatPoint(rcPlate.right, rcPlate.bottom)));
+
+    return CPVT_WordRange(place1, place2);
+  }
+
+  return CPVT_WordRange();
+}
+
+CPVT_WordPlace CFX_Edit::SearchWordPlace(const CFX_FloatPoint& point) const {
+  if (m_pVT->IsValid()) {
+    return m_pVT->SearchWordPlace(EditToVT(point));
+  }
+
+  return CPVT_WordPlace();
+}
+
+void CFX_Edit::Paint() {
+  if (m_pVT->IsValid()) {
+    RearrangeAll();
+    ScrollToCaret();
+    Refresh();
+    SetCaretOrigin();
+    SetCaretInfo();
+  }
+}
+
+void CFX_Edit::RearrangeAll() {
+  if (m_pVT->IsValid()) {
+    m_pVT->UpdateWordPlace(m_wpCaret);
+    m_pVT->RearrangeAll();
+    m_pVT->UpdateWordPlace(m_wpCaret);
+    SetScrollInfo();
+    SetContentChanged();
+  }
+}
+
+void CFX_Edit::RearrangePart(const CPVT_WordRange& range) {
+  if (m_pVT->IsValid()) {
+    m_pVT->UpdateWordPlace(m_wpCaret);
+    m_pVT->RearrangePart(range);
+    m_pVT->UpdateWordPlace(m_wpCaret);
+    SetScrollInfo();
+    SetContentChanged();
+  }
+}
+
+void CFX_Edit::SetContentChanged() {
+  if (m_pNotify) {
+    CFX_FloatRect rcContent = m_pVT->GetContentRect();
+    if (rcContent.Width() != m_rcOldContent.Width() ||
+        rcContent.Height() != m_rcOldContent.Height()) {
+      if (!m_bNotifyFlag) {
+        m_bNotifyFlag = true;
+        m_pNotify->IOnContentChange(rcContent);
+        m_bNotifyFlag = false;
+      }
+      m_rcOldContent = rcContent;
+    }
+  }
+}
+
+void CFX_Edit::SelectAll() {
+  if (m_pVT->IsValid()) {
+    m_SelState = CFX_Edit_Select(GetWholeWordRange());
+    SetCaret(m_SelState.EndPos);
+
+    ScrollToCaret();
+    Refresh();
+    SetCaretInfo();
+  }
+}
+
+void CFX_Edit::SelectNone() {
+  if (m_pVT->IsValid()) {
+    if (m_SelState.IsExist()) {
+      m_SelState.Default();
+      Refresh();
+    }
+  }
+}
+
+bool CFX_Edit::IsSelected() const {
+  return m_SelState.IsExist();
+}
+
+CFX_FloatPoint CFX_Edit::VTToEdit(const CFX_FloatPoint& point) const {
+  CFX_FloatRect rcContent = m_pVT->GetContentRect();
+  CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
+
+  FX_FLOAT fPadding = 0.0f;
+
+  switch (m_nAlignment) {
+    case 0:
+      fPadding = 0.0f;
+      break;
+    case 1:
+      fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f;
+      break;
+    case 2:
+      fPadding = rcPlate.Height() - rcContent.Height();
+      break;
+  }
+
+  return CFX_FloatPoint(point.x - (m_ptScrollPos.x - rcPlate.left),
+                        point.y - (m_ptScrollPos.y + fPadding - rcPlate.top));
+}
+
+CFX_FloatPoint CFX_Edit::EditToVT(const CFX_FloatPoint& point) const {
+  CFX_FloatRect rcContent = m_pVT->GetContentRect();
+  CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
+
+  FX_FLOAT fPadding = 0.0f;
+
+  switch (m_nAlignment) {
+    case 0:
+      fPadding = 0.0f;
+      break;
+    case 1:
+      fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f;
+      break;
+    case 2:
+      fPadding = rcPlate.Height() - rcContent.Height();
+      break;
+  }
+
+  return CFX_FloatPoint(point.x + (m_ptScrollPos.x - rcPlate.left),
+                        point.y + (m_ptScrollPos.y + fPadding - rcPlate.top));
+}
+
+CFX_FloatRect CFX_Edit::VTToEdit(const CFX_FloatRect& rect) const {
+  CFX_FloatPoint ptLeftBottom =
+      VTToEdit(CFX_FloatPoint(rect.left, rect.bottom));
+  CFX_FloatPoint ptRightTop = VTToEdit(CFX_FloatPoint(rect.right, rect.top));
+
+  return CFX_FloatRect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x,
+                       ptRightTop.y);
+}
+
+void CFX_Edit::SetScrollInfo() {
+  if (m_pNotify) {
+    CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
+    CFX_FloatRect rcContent = m_pVT->GetContentRect();
+
+    if (!m_bNotifyFlag) {
+      m_bNotifyFlag = true;
+      m_pNotify->IOnSetScrollInfoY(rcPlate.bottom, rcPlate.top,
+                                   rcContent.bottom, rcContent.top,
+                                   rcPlate.Height() / 3, rcPlate.Height());
+      m_bNotifyFlag = false;
+    }
+  }
+}
+
+void CFX_Edit::SetScrollPosX(FX_FLOAT fx) {
+  if (!m_bEnableScroll)
+    return;
+
+  if (m_pVT->IsValid()) {
+    if (!IsFloatEqual(m_ptScrollPos.x, fx)) {
+      m_ptScrollPos.x = fx;
+      Refresh();
+    }
+  }
+}
+
+void CFX_Edit::SetScrollPosY(FX_FLOAT fy) {
+  if (!m_bEnableScroll)
+    return;
+
+  if (m_pVT->IsValid()) {
+    if (!IsFloatEqual(m_ptScrollPos.y, fy)) {
+      m_ptScrollPos.y = fy;
+      Refresh();
+
+      if (m_pNotify) {
+        if (!m_bNotifyFlag) {
+          m_bNotifyFlag = true;
+          m_pNotify->IOnSetScrollPosY(fy);
+          m_bNotifyFlag = false;
+        }
+      }
+    }
+  }
+}
+
+void CFX_Edit::SetScrollPos(const CFX_FloatPoint& point) {
+  SetScrollPosX(point.x);
+  SetScrollPosY(point.y);
+  SetScrollLimit();
+  SetCaretInfo();
+}
+
+CFX_FloatPoint CFX_Edit::GetScrollPos() const {
+  return m_ptScrollPos;
+}
+
+void CFX_Edit::SetScrollLimit() {
+  if (m_pVT->IsValid()) {
+    CFX_FloatRect rcContent = m_pVT->GetContentRect();
+    CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
+
+    if (rcPlate.Width() > rcContent.Width()) {
+      SetScrollPosX(rcPlate.left);
+    } else {
+      if (IsFloatSmaller(m_ptScrollPos.x, rcContent.left)) {
+        SetScrollPosX(rcContent.left);
+      } else if (IsFloatBigger(m_ptScrollPos.x,
+                               rcContent.right - rcPlate.Width())) {
+        SetScrollPosX(rcContent.right - rcPlate.Width());
+      }
+    }
+
+    if (rcPlate.Height() > rcContent.Height()) {
+      SetScrollPosY(rcPlate.top);
+    } else {
+      if (IsFloatSmaller(m_ptScrollPos.y,
+                         rcContent.bottom + rcPlate.Height())) {
+        SetScrollPosY(rcContent.bottom + rcPlate.Height());
+      } else if (IsFloatBigger(m_ptScrollPos.y, rcContent.top)) {
+        SetScrollPosY(rcContent.top);
+      }
+    }
+  }
+}
+
+void CFX_Edit::ScrollToCaret() {
+  SetScrollLimit();
+
+  if (!m_pVT->IsValid())
+    return;
+
+  CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
+  pIterator->SetAt(m_wpCaret);
+
+  CFX_FloatPoint ptHead;
+  CFX_FloatPoint ptFoot;
+  CPVT_Word word;
+  CPVT_Line line;
+  if (pIterator->GetWord(word)) {
+    ptHead.x = word.ptWord.x + word.fWidth;
+    ptHead.y = word.ptWord.y + word.fAscent;
+    ptFoot.x = word.ptWord.x + word.fWidth;
+    ptFoot.y = word.ptWord.y + word.fDescent;
+  } else if (pIterator->GetLine(line)) {
+    ptHead.x = line.ptLine.x;
+    ptHead.y = line.ptLine.y + line.fLineAscent;
+    ptFoot.x = line.ptLine.x;
+    ptFoot.y = line.ptLine.y + line.fLineDescent;
+  }
+
+  CFX_FloatPoint ptHeadEdit = VTToEdit(ptHead);
+  CFX_FloatPoint ptFootEdit = VTToEdit(ptFoot);
+  CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
+  if (!IsFloatEqual(rcPlate.left, rcPlate.right)) {
+    if (IsFloatSmaller(ptHeadEdit.x, rcPlate.left) ||
+        IsFloatEqual(ptHeadEdit.x, rcPlate.left)) {
+      SetScrollPosX(ptHead.x);
+    } else if (IsFloatBigger(ptHeadEdit.x, rcPlate.right)) {
+      SetScrollPosX(ptHead.x - rcPlate.Width());
+    }
+  }
+
+  if (!IsFloatEqual(rcPlate.top, rcPlate.bottom)) {
+    if (IsFloatSmaller(ptFootEdit.y, rcPlate.bottom) ||
+        IsFloatEqual(ptFootEdit.y, rcPlate.bottom)) {
+      if (IsFloatSmaller(ptHeadEdit.y, rcPlate.top)) {
+        SetScrollPosY(ptFoot.y + rcPlate.Height());
+      }
+    } else if (IsFloatBigger(ptHeadEdit.y, rcPlate.top)) {
+      if (IsFloatBigger(ptFootEdit.y, rcPlate.bottom)) {
+        SetScrollPosY(ptHead.y);
+      }
+    }
+  }
+}
+
+void CFX_Edit::Refresh() {
+  if (m_bEnableRefresh && m_pVT->IsValid()) {
+    m_Refresh.BeginRefresh();
+    RefreshPushLineRects(GetVisibleWordRange());
+
+    m_Refresh.NoAnalyse();
+    m_ptRefreshScrollPos = m_ptScrollPos;
+
+    if (m_pNotify) {
+      if (!m_bNotifyFlag) {
+        m_bNotifyFlag = true;
+        if (const CFX_Edit_RectArray* pRects = m_Refresh.GetRefreshRects()) {
+          for (int32_t i = 0, sz = pRects->GetSize(); i < sz; i++)
+            m_pNotify->IOnInvalidateRect(pRects->GetAt(i));
+        }
+        m_bNotifyFlag = false;
+      }
+    }
+
+    m_Refresh.EndRefresh();
+  }
+}
+
+void CFX_Edit::RefreshPushLineRects(const CPVT_WordRange& wr) {
+  if (!m_pVT->IsValid())
+    return;
+
+  CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
+  CPVT_WordPlace wpBegin = wr.BeginPos;
+  m_pVT->UpdateWordPlace(wpBegin);
+  CPVT_WordPlace wpEnd = wr.EndPos;
+  m_pVT->UpdateWordPlace(wpEnd);
+  pIterator->SetAt(wpBegin);
+
+  CPVT_Line lineinfo;
+  do {
+    if (!pIterator->GetLine(lineinfo))
+      break;
+    if (lineinfo.lineplace.LineCmp(wpEnd) > 0)
+      break;
+
+    CFX_FloatRect rcLine(lineinfo.ptLine.x,
+                         lineinfo.ptLine.y + lineinfo.fLineDescent,
+                         lineinfo.ptLine.x + lineinfo.fLineWidth,
+                         lineinfo.ptLine.y + lineinfo.fLineAscent);
+
+    m_Refresh.Push(CPVT_WordRange(lineinfo.lineplace, lineinfo.lineEnd),
+                   VTToEdit(rcLine));
+  } while (pIterator->NextLine());
+}
+
+void CFX_Edit::RefreshWordRange(const CPVT_WordRange& wr) {
+  CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
+  CPVT_WordRange wrTemp = wr;
+
+  m_pVT->UpdateWordPlace(wrTemp.BeginPos);
+  m_pVT->UpdateWordPlace(wrTemp.EndPos);
+  pIterator->SetAt(wrTemp.BeginPos);
+
+  CPVT_Word wordinfo;
+  CPVT_Line lineinfo;
+  CPVT_WordPlace place;
+
+  while (pIterator->NextWord()) {
+    place = pIterator->GetAt();
+    if (place.WordCmp(wrTemp.EndPos) > 0)
+      break;
+
+    pIterator->GetWord(wordinfo);
+    pIterator->GetLine(lineinfo);
+
+    if (place.LineCmp(wrTemp.BeginPos) == 0 ||
+        place.LineCmp(wrTemp.EndPos) == 0) {
+      CFX_FloatRect rcWord(wordinfo.ptWord.x,
+                           lineinfo.ptLine.y + lineinfo.fLineDescent,
+                           wordinfo.ptWord.x + wordinfo.fWidth,
+                           lineinfo.ptLine.y + lineinfo.fLineAscent);
+
+      if (m_pNotify) {
+        if (!m_bNotifyFlag) {
+          m_bNotifyFlag = true;
+          CFX_FloatRect rcRefresh = VTToEdit(rcWord);
+          m_pNotify->IOnInvalidateRect(&rcRefresh);
+          m_bNotifyFlag = false;
+        }
+      }
+    } else {
+      CFX_FloatRect rcLine(lineinfo.ptLine.x,
+                           lineinfo.ptLine.y + lineinfo.fLineDescent,
+                           lineinfo.ptLine.x + lineinfo.fLineWidth,
+                           lineinfo.ptLine.y + lineinfo.fLineAscent);
+
+      if (m_pNotify) {
+        if (!m_bNotifyFlag) {
+          m_bNotifyFlag = true;
+          CFX_FloatRect rcRefresh = VTToEdit(rcLine);
+          m_pNotify->IOnInvalidateRect(&rcRefresh);
+          m_bNotifyFlag = false;
+        }
+      }
+
+      pIterator->NextLine();
+    }
+  }
+}
+
+void CFX_Edit::SetCaret(const CPVT_WordPlace& place) {
+  m_wpOldCaret = m_wpCaret;
+  m_wpCaret = place;
+}
+
+void CFX_Edit::SetCaretInfo() {
+  if (m_pNotify) {
+    if (!m_bNotifyFlag) {
+      CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
+      pIterator->SetAt(m_wpCaret);
+
+      CFX_FloatPoint ptHead;
+      CFX_FloatPoint ptFoot;
+      CPVT_Word word;
+      CPVT_Line line;
+      if (pIterator->GetWord(word)) {
+        ptHead.x = word.ptWord.x + word.fWidth;
+        ptHead.y = word.ptWord.y + word.fAscent;
+        ptFoot.x = word.ptWord.x + word.fWidth;
+        ptFoot.y = word.ptWord.y + word.fDescent;
+      } else if (pIterator->GetLine(line)) {
+        ptHead.x = line.ptLine.x;
+        ptHead.y = line.ptLine.y + line.fLineAscent;
+        ptFoot.x = line.ptLine.x;
+        ptFoot.y = line.ptLine.y + line.fLineDescent;
+      }
+
+      m_bNotifyFlag = true;
+      m_pNotify->IOnSetCaret(!m_SelState.IsExist(), VTToEdit(ptHead),
+                             VTToEdit(ptFoot), m_wpCaret);
+      m_bNotifyFlag = false;
+    }
+  }
+}
+
+void CFX_Edit::SetCaret(int32_t nPos) {
+  if (m_pVT->IsValid()) {
+    SelectNone();
+    SetCaret(m_pVT->WordIndexToWordPlace(nPos));
+    m_SelState.Set(m_wpCaret, m_wpCaret);
+
+    ScrollToCaret();
+    SetCaretOrigin();
+    SetCaretInfo();
+  }
+}
+
+void CFX_Edit::OnMouseDown(const CFX_FloatPoint& point,
+                           bool bShift,
+                           bool bCtrl) {
+  if (m_pVT->IsValid()) {
+    SelectNone();
+    SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
+    m_SelState.Set(m_wpCaret, m_wpCaret);
+
+    ScrollToCaret();
+    SetCaretOrigin();
+    SetCaretInfo();
+  }
+}
+
+void CFX_Edit::OnMouseMove(const CFX_FloatPoint& point,
+                           bool bShift,
+                           bool bCtrl) {
+  if (m_pVT->IsValid()) {
+    SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
+
+    if (m_wpCaret != m_wpOldCaret) {
+      m_SelState.SetEndPos(m_wpCaret);
+
+      ScrollToCaret();
+      Refresh();
+      SetCaretOrigin();
+      SetCaretInfo();
+    }
+  }
+}
+
+void CFX_Edit::OnVK_UP(bool bShift, bool bCtrl) {
+  if (m_pVT->IsValid()) {
+    SetCaret(m_pVT->GetUpWordPlace(m_wpCaret, m_ptCaret));
+
+    if (bShift) {
+      if (m_SelState.IsExist())
+        m_SelState.SetEndPos(m_wpCaret);
+      else
+        m_SelState.Set(m_wpOldCaret, m_wpCaret);
+
+      if (m_wpOldCaret != m_wpCaret) {
+        ScrollToCaret();
+        Refresh();
+        SetCaretInfo();
+      }
+    } else {
+      SelectNone();
+
+      ScrollToCaret();
+      SetCaretInfo();
+    }
+  }
+}
+
+void CFX_Edit::OnVK_DOWN(bool bShift, bool bCtrl) {
+  if (m_pVT->IsValid()) {
+    SetCaret(m_pVT->GetDownWordPlace(m_wpCaret, m_ptCaret));
+
+    if (bShift) {
+      if (m_SelState.IsExist())
+        m_SelState.SetEndPos(m_wpCaret);
+      else
+        m_SelState.Set(m_wpOldCaret, m_wpCaret);
+
+      if (m_wpOldCaret != m_wpCaret) {
+        ScrollToCaret();
+        Refresh();
+        SetCaretInfo();
+      }
+    } else {
+      SelectNone();
+
+      ScrollToCaret();
+      SetCaretInfo();
+    }
+  }
+}
+
+void CFX_Edit::OnVK_LEFT(bool bShift, bool bCtrl) {
+  if (m_pVT->IsValid()) {
+    if (bShift) {
+      if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
+          m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret))
+        SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
+
+      SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
+
+      if (m_SelState.IsExist())
+        m_SelState.SetEndPos(m_wpCaret);
+      else
+        m_SelState.Set(m_wpOldCaret, m_wpCaret);
+
+      if (m_wpOldCaret != m_wpCaret) {
+        ScrollToCaret();
+        Refresh();
+        SetCaretInfo();
+      }
+    } else {
+      if (m_SelState.IsExist()) {
+        if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos) < 0)
+          SetCaret(m_SelState.BeginPos);
+        else
+          SetCaret(m_SelState.EndPos);
+
+        SelectNone();
+        ScrollToCaret();
+        SetCaretInfo();
+      } else {
+        if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
+            m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret))
+          SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
+
+        SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
+
+        ScrollToCaret();
+        SetCaretOrigin();
+        SetCaretInfo();
+      }
+    }
+  }
+}
+
+void CFX_Edit::OnVK_RIGHT(bool bShift, bool bCtrl) {
+  if (m_pVT->IsValid()) {
+    if (bShift) {
+      SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
+
+      if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
+          m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret))
+        SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
+
+      if (m_SelState.IsExist())
+        m_SelState.SetEndPos(m_wpCaret);
+      else
+        m_SelState.Set(m_wpOldCaret, m_wpCaret);
+
+      if (m_wpOldCaret != m_wpCaret) {
+        ScrollToCaret();
+        Refresh();
+        SetCaretInfo();
+      }
+    } else {
+      if (m_SelState.IsExist()) {
+        if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos) > 0)
+          SetCaret(m_SelState.BeginPos);
+        else
+          SetCaret(m_SelState.EndPos);
+
+        SelectNone();
+        ScrollToCaret();
+        SetCaretInfo();
+      } else {
+        SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
+
+        if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
+            m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret))
+          SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
+
+        ScrollToCaret();
+        SetCaretOrigin();
+        SetCaretInfo();
+      }
+    }
+  }
+}
+
+void CFX_Edit::OnVK_HOME(bool bShift, bool bCtrl) {
+  if (m_pVT->IsValid()) {
+    if (bShift) {
+      if (bCtrl)
+        SetCaret(m_pVT->GetBeginWordPlace());
+      else
+        SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));
+
+      if (m_SelState.IsExist())
+        m_SelState.SetEndPos(m_wpCaret);
+      else
+        m_SelState.Set(m_wpOldCaret, m_wpCaret);
+
+      ScrollToCaret();
+      Refresh();
+      SetCaretInfo();
+    } else {
+      if (m_SelState.IsExist()) {
+        if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos) < 0)
+          SetCaret(m_SelState.BeginPos);
+        else
+          SetCaret(m_SelState.EndPos);
+
+        SelectNone();
+        ScrollToCaret();
+        SetCaretInfo();
+      } else {
+        if (bCtrl)
+          SetCaret(m_pVT->GetBeginWordPlace());
+        else
+          SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));
+
+        ScrollToCaret();
+        SetCaretOrigin();
+        SetCaretInfo();
+      }
+    }
+  }
+}
+
+void CFX_Edit::OnVK_END(bool bShift, bool bCtrl) {
+  if (m_pVT->IsValid()) {
+    if (bShift) {
+      if (bCtrl)
+        SetCaret(m_pVT->GetEndWordPlace());
+      else
+        SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));
+
+      if (m_SelState.IsExist())
+        m_SelState.SetEndPos(m_wpCaret);
+      else
+        m_SelState.Set(m_wpOldCaret, m_wpCaret);
+
+      ScrollToCaret();
+      Refresh();
+      SetCaretInfo();
+    } else {
+      if (m_SelState.IsExist()) {
+        if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos) > 0)
+          SetCaret(m_SelState.BeginPos);
+        else
+          SetCaret(m_SelState.EndPos);
+
+        SelectNone();
+        ScrollToCaret();
+        SetCaretInfo();
+      } else {
+        if (bCtrl)
+          SetCaret(m_pVT->GetEndWordPlace());
+        else
+          SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));
+
+        ScrollToCaret();
+        SetCaretOrigin();
+        SetCaretInfo();
+      }
+    }
+  }
+}
+
+bool CFX_Edit::InsertWord(uint16_t word,
+                          int32_t charset,
+                          const CPVT_WordProps* pWordProps,
+                          bool bAddUndo,
+                          bool bPaint) {
+  if (IsTextOverflow())
+    return false;
+
+  if (m_pVT->IsValid()) {
+    m_pVT->UpdateWordPlace(m_wpCaret);
+
+    SetCaret(m_pVT->InsertWord(
+        m_wpCaret, word, GetCharSetFromUnicode(word, charset), pWordProps));
+    m_SelState.Set(m_wpCaret, m_wpCaret);
+
+    if (m_wpCaret != m_wpOldCaret) {
+      if (bAddUndo && m_bEnableUndo) {
+        AddEditUndoItem(new CFXEU_InsertWord(this, m_wpOldCaret, m_wpCaret,
+                                             word, charset, pWordProps));
+      }
+
+      if (bPaint)
+        PaintInsertText(m_wpOldCaret, m_wpCaret);
+
+      if (m_bOprNotify && m_pOprNotify)
+        m_pOprNotify->OnInsertWord(m_wpCaret, m_wpOldCaret);
+
+      return true;
+    }
+  }
+
+  return false;
+}
+
+bool CFX_Edit::InsertReturn(const CPVT_SecProps* pSecProps,
+                            const CPVT_WordProps* pWordProps,
+                            bool bAddUndo,
+                            bool bPaint) {
+  if (IsTextOverflow())
+    return false;
+
+  if (m_pVT->IsValid()) {
+    m_pVT->UpdateWordPlace(m_wpCaret);
+    SetCaret(m_pVT->InsertSection(m_wpCaret, pSecProps, pWordProps));
+    m_SelState.Set(m_wpCaret, m_wpCaret);
+
+    if (m_wpCaret != m_wpOldCaret) {
+      if (bAddUndo && m_bEnableUndo) {
+        AddEditUndoItem(new CFXEU_InsertReturn(this, m_wpOldCaret, m_wpCaret,
+                                               pSecProps, pWordProps));
+      }
+
+      if (bPaint) {
+        RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret));
+        ScrollToCaret();
+        Refresh();
+        SetCaretOrigin();
+        SetCaretInfo();
+      }
+
+      if (m_bOprNotify && m_pOprNotify)
+        m_pOprNotify->OnInsertReturn(m_wpCaret, m_wpOldCaret);
+
+      return true;
+    }
+  }
+
+  return false;
+}
+
+bool CFX_Edit::Backspace(bool bAddUndo, bool bPaint) {
+  if (m_pVT->IsValid()) {
+    if (m_wpCaret == m_pVT->GetBeginWordPlace())
+      return false;
+
+    CPVT_Section section;
+    CPVT_Word word;
+
+    if (bAddUndo) {
+      CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
+      pIterator->SetAt(m_wpCaret);
+      pIterator->GetSection(section);
+      pIterator->GetWord(word);
+    }
+
+    m_pVT->UpdateWordPlace(m_wpCaret);
+    SetCaret(m_pVT->BackSpaceWord(m_wpCaret));
+    m_SelState.Set(m_wpCaret, m_wpCaret);
+
+    if (m_wpCaret != m_wpOldCaret) {
+      if (bAddUndo && m_bEnableUndo) {
+        if (m_wpCaret.SecCmp(m_wpOldCaret) != 0)
+          AddEditUndoItem(new CFXEU_Backspace(
+              this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
+              section.SecProps, section.WordProps));
+        else
+          AddEditUndoItem(new CFXEU_Backspace(
+              this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
+              section.SecProps, word.WordProps));
+      }
+
+      if (bPaint) {
+        RearrangePart(CPVT_WordRange(m_wpCaret, m_wpOldCaret));
+        ScrollToCaret();
+        Refresh();
+        SetCaretOrigin();
+        SetCaretInfo();
+      }
+
+      if (m_bOprNotify && m_pOprNotify)
+        m_pOprNotify->OnBackSpace(m_wpCaret, m_wpOldCaret);
+
+      return true;
+    }
+  }
+
+  return false;
+}
+
+bool CFX_Edit::Delete(bool bAddUndo, bool bPaint) {
+  if (m_pVT->IsValid()) {
+    if (m_wpCaret == m_pVT->GetEndWordPlace())
+      return false;
+
+    CPVT_Section section;
+    CPVT_Word word;
+
+    if (bAddUndo) {
+      CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
+      pIterator->SetAt(m_pVT->GetNextWordPlace(m_wpCaret));
+      pIterator->GetSection(section);
+      pIterator->GetWord(word);
+    }
+
+    m_pVT->UpdateWordPlace(m_wpCaret);
+    bool bSecEnd = (m_wpCaret == m_pVT->GetSectionEndPlace(m_wpCaret));
+
+    SetCaret(m_pVT->DeleteWord(m_wpCaret));
+    m_SelState.Set(m_wpCaret, m_wpCaret);
+
+    if (bAddUndo && m_bEnableUndo) {
+      if (bSecEnd)
+        AddEditUndoItem(new CFXEU_Delete(
+            this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
+            section.SecProps, section.WordProps, bSecEnd));
+      else
+        AddEditUndoItem(new CFXEU_Delete(
+            this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
+            section.SecProps, word.WordProps, bSecEnd));
+    }
+
+    if (bPaint) {
+      RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret));
+      ScrollToCaret();
+      Refresh();
+      SetCaretOrigin();
+      SetCaretInfo();
+    }
+
+    if (m_bOprNotify && m_pOprNotify)
+      m_pOprNotify->OnDelete(m_wpCaret, m_wpOldCaret);
+
+    return true;
+  }
+
+  return false;
+}
+
+bool CFX_Edit::Empty() {
+  if (m_pVT->IsValid()) {
+    m_pVT->DeleteWords(GetWholeWordRange());
+    SetCaret(m_pVT->GetBeginWordPlace());
+
+    return true;
+  }
+
+  return false;
+}
+
+bool CFX_Edit::Clear(bool bAddUndo, bool bPaint) {
+  if (!m_pVT->IsValid())
+    return false;
+
+  if (!m_SelState.IsExist())
+    return false;
+
+  CPVT_WordRange range = m_SelState.ConvertToWordRange();
+
+  if (bAddUndo && m_bEnableUndo)
+    AddEditUndoItem(new CFXEU_Clear(this, range, GetSelText()));
+
+  SelectNone();
+  SetCaret(m_pVT->DeleteWords(range));
+  m_SelState.Set(m_wpCaret, m_wpCaret);
+
+  if (bPaint) {
+    RearrangePart(range);
+    ScrollToCaret();
+    Refresh();
+    SetCaretOrigin();
+    SetCaretInfo();
+  }
+
+  if (m_bOprNotify && m_pOprNotify)
+    m_pOprNotify->OnClear(m_wpCaret, m_wpOldCaret);
+
+  return true;
+}
+
+bool CFX_Edit::InsertText(const CFX_WideString& sText,
+                          int32_t charset,
+                          bool bAddUndo,
+                          bool bPaint) {
+  if (IsTextOverflow())
+    return false;
+
+  m_pVT->UpdateWordPlace(m_wpCaret);
+  SetCaret(DoInsertText(m_wpCaret, sText, charset));
+  m_SelState.Set(m_wpCaret, m_wpCaret);
+  if (m_wpCaret == m_wpOldCaret)
+    return false;
+
+  if (bAddUndo && m_bEnableUndo) {
+    AddEditUndoItem(
+        new CFXEU_InsertText(this, m_wpOldCaret, m_wpCaret, sText, charset));
+  }
+
+  if (bPaint)
+    PaintInsertText(m_wpOldCaret, m_wpCaret);
+
+  if (m_bOprNotify && m_pOprNotify)
+    m_pOprNotify->OnInsertText(m_wpCaret, m_wpOldCaret);
+
+  return true;
+}
+
+void CFX_Edit::PaintInsertText(const CPVT_WordPlace& wpOld,
+                               const CPVT_WordPlace& wpNew) {
+  if (m_pVT->IsValid()) {
+    RearrangePart(CPVT_WordRange(wpOld, wpNew));
+    ScrollToCaret();
+    Refresh();
+    SetCaretOrigin();
+    SetCaretInfo();
+  }
+}
+
+bool CFX_Edit::Redo() {
+  if (m_bEnableUndo) {
+    if (m_Undo.CanRedo()) {
+      m_Undo.Redo();
+      return true;
+    }
+  }
+
+  return false;
+}
+
+bool CFX_Edit::Undo() {
+  if (m_bEnableUndo) {
+    if (m_Undo.CanUndo()) {
+      m_Undo.Undo();
+      return true;
+    }
+  }
+
+  return false;
+}
+
+void CFX_Edit::SetCaretOrigin() {
+  if (!m_pVT->IsValid())
+    return;
+
+  CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
+  pIterator->SetAt(m_wpCaret);
+  CPVT_Word word;
+  CPVT_Line line;
+  if (pIterator->GetWord(word)) {
+    m_ptCaret.x = word.ptWord.x + word.fWidth;
+    m_ptCaret.y = word.ptWord.y;
+  } else if (pIterator->GetLine(line)) {
+    m_ptCaret.x = line.ptLine.x;
+    m_ptCaret.y = line.ptLine.y;
+  }
+}
+
+int32_t CFX_Edit::WordPlaceToWordIndex(const CPVT_WordPlace& place) const {
+  if (m_pVT->IsValid())
+    return m_pVT->WordPlaceToWordIndex(place);
+
+  return -1;
+}
+
+CPVT_WordPlace CFX_Edit::WordIndexToWordPlace(int32_t index) const {
+  if (m_pVT->IsValid())
+    return m_pVT->WordIndexToWordPlace(index);
+
+  return CPVT_WordPlace();
+}
+
+bool CFX_Edit::IsTextFull() const {
+  int32_t nTotalWords = m_pVT->GetTotalWords();
+  int32_t nLimitChar = m_pVT->GetLimitChar();
+  int32_t nCharArray = m_pVT->GetCharArray();
+
+  return IsTextOverflow() || (nLimitChar > 0 && nTotalWords >= nLimitChar) ||
+         (nCharArray > 0 && nTotalWords >= nCharArray);
+}
+
+bool CFX_Edit::IsTextOverflow() const {
+  if (!m_bEnableScroll && !m_bEnableOverflow) {
+    CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
+    CFX_FloatRect rcContent = m_pVT->GetContentRect();
+
+    if (m_pVT->IsMultiLine() && GetTotalLines() > 1 &&
+        IsFloatBigger(rcContent.Height(), rcPlate.Height())) {
+      return true;
+    }
+
+    if (IsFloatBigger(rcContent.Width(), rcPlate.Width()))
+      return true;
+  }
+
+  return false;
+}
+
+bool CFX_Edit::CanUndo() const {
+  if (m_bEnableUndo) {
+    return m_Undo.CanUndo();
+  }
+
+  return false;
+}
+
+bool CFX_Edit::CanRedo() const {
+  if (m_bEnableUndo) {
+    return m_Undo.CanRedo();
+  }
+
+  return false;
+}
+
+void CFX_Edit::EnableRefresh(bool bRefresh) {
+  m_bEnableRefresh = bRefresh;
+}
+
+void CFX_Edit::EnableUndo(bool bUndo) {
+  m_bEnableUndo = bUndo;
+}
+
+void CFX_Edit::EnableOprNotify(bool bNotify) {
+  m_bOprNotify = bNotify;
+}
+
+CPVT_WordPlace CFX_Edit::DoInsertText(const CPVT_WordPlace& place,
+                                      const CFX_WideString& sText,
+                                      int32_t charset) {
+  CPVT_WordPlace wp = place;
+
+  if (m_pVT->IsValid()) {
+    for (int32_t i = 0, sz = sText.GetLength(); i < sz; i++) {
+      uint16_t word = sText[i];
+      switch (word) {
+        case 0x0D:
+          wp = m_pVT->InsertSection(wp, nullptr, nullptr);
+          if (sText[i + 1] == 0x0A)
+            i++;
+          break;
+        case 0x0A:
+          wp = m_pVT->InsertSection(wp, nullptr, nullptr);
+          if (sText[i + 1] == 0x0D)
+            i++;
+          break;
+        case 0x09:
+          word = 0x20;
+        default:
+          wp = m_pVT->InsertWord(wp, word, GetCharSetFromUnicode(word, charset),
+                                 nullptr);
+          break;
+      }
+    }
+  }
+
+  return wp;
+}
+
+int32_t CFX_Edit::GetCharSetFromUnicode(uint16_t word, int32_t nOldCharset) {
+  if (IPVT_FontMap* pFontMap = GetFontMap())
+    return pFontMap->CharSetFromUnicode(word, nOldCharset);
+  return nOldCharset;
+}
+
+void CFX_Edit::AddEditUndoItem(CFX_Edit_UndoItem* pEditUndoItem) {
+  if (m_pGroupUndoItem) {
+    m_pGroupUndoItem->AddUndoItem(pEditUndoItem);
+  } else {
+    m_Undo.AddItem(pEditUndoItem);
+  }
+}
+
+CFX_Edit_LineRectArray::CFX_Edit_LineRectArray() {}
+
+CFX_Edit_LineRectArray::~CFX_Edit_LineRectArray() {
+  Empty();
+}
+
+void CFX_Edit_LineRectArray::Empty() {
+  for (int32_t i = 0, sz = m_LineRects.GetSize(); i < sz; i++)
+    delete m_LineRects.GetAt(i);
+
+  m_LineRects.RemoveAll();
+}
+
+void CFX_Edit_LineRectArray::RemoveAll() {
+  m_LineRects.RemoveAll();
+}
+
+void CFX_Edit_LineRectArray::operator=(CFX_Edit_LineRectArray& rects) {
+  Empty();
+  for (int32_t i = 0, sz = rects.GetSize(); i < sz; i++)
+    m_LineRects.Add(rects.GetAt(i));
+
+  rects.RemoveAll();
+}
+
+void CFX_Edit_LineRectArray::Add(const CPVT_WordRange& wrLine,
+                                 const CFX_FloatRect& rcLine) {
+  m_LineRects.Add(new CFX_Edit_LineRect(wrLine, rcLine));
+}
+
+int32_t CFX_Edit_LineRectArray::GetSize() const {
+  return m_LineRects.GetSize();
+}
+
+CFX_Edit_LineRect* CFX_Edit_LineRectArray::GetAt(int32_t nIndex) const {
+  if (nIndex < 0 || nIndex >= m_LineRects.GetSize())
+    return nullptr;
+
+  return m_LineRects.GetAt(nIndex);
+}
+
+CFX_Edit_Select::CFX_Edit_Select() {}
+
+CFX_Edit_Select::CFX_Edit_Select(const CPVT_WordPlace& begin,
+                                 const CPVT_WordPlace& end) {
+  Set(begin, end);
+}
+
+CFX_Edit_Select::CFX_Edit_Select(const CPVT_WordRange& range) {
+  Set(range.BeginPos, range.EndPos);
+}
+
+CPVT_WordRange CFX_Edit_Select::ConvertToWordRange() const {
+  return CPVT_WordRange(BeginPos, EndPos);
+}
+
+void CFX_Edit_Select::Default() {
+  BeginPos.Default();
+  EndPos.Default();
+}
+
+void CFX_Edit_Select::Set(const CPVT_WordPlace& begin,
+                          const CPVT_WordPlace& end) {
+  BeginPos = begin;
+  EndPos = end;
+}
+
+void CFX_Edit_Select::SetBeginPos(const CPVT_WordPlace& begin) {
+  BeginPos = begin;
+}
+
+void CFX_Edit_Select::SetEndPos(const CPVT_WordPlace& end) {
+  EndPos = end;
+}
+
+bool CFX_Edit_Select::IsExist() const {
+  return BeginPos != EndPos;
+}
+
+CFX_Edit_RectArray::CFX_Edit_RectArray() {}
+
+CFX_Edit_RectArray::~CFX_Edit_RectArray() {
+  Empty();
+}
+
+void CFX_Edit_RectArray::Empty() {
+  for (int32_t i = 0, sz = m_Rects.GetSize(); i < sz; i++)
+    delete m_Rects.GetAt(i);
+
+  m_Rects.RemoveAll();
+}
+
+void CFX_Edit_RectArray::Add(const CFX_FloatRect& rect) {
+  // check for overlapped area
+  for (int32_t i = 0, sz = m_Rects.GetSize(); i < sz; i++) {
+    CFX_FloatRect* pRect = m_Rects.GetAt(i);
+    if (pRect && pRect->Contains(rect))
+      return;
+  }
+
+  m_Rects.Add(new CFX_FloatRect(rect));
+}
+
+int32_t CFX_Edit_RectArray::GetSize() const {
+  return m_Rects.GetSize();
+}
+
+CFX_FloatRect* CFX_Edit_RectArray::GetAt(int32_t nIndex) const {
+  if (nIndex < 0 || nIndex >= m_Rects.GetSize())
+    return nullptr;
+
+  return m_Rects.GetAt(nIndex);
+}
diff --git a/fpdfsdk/fxedit/fxet_edit.h b/fpdfsdk/fxedit/fxet_edit.h
new file mode 100644
index 0000000..2ab27d3
--- /dev/null
+++ b/fpdfsdk/fxedit/fxet_edit.h
@@ -0,0 +1,560 @@
+// 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_FXEDIT_FXET_EDIT_H_
+#define FPDFSDK_FXEDIT_FXET_EDIT_H_
+
+#include <memory>
+#include <vector>
+
+#include "core/fpdfdoc/cpvt_secprops.h"
+#include "core/fpdfdoc/cpvt_wordprops.h"
+#include "fpdfsdk/fxedit/fx_edit.h"
+
+class CFFL_FormFiller;
+class CFX_Edit;
+class CFX_Edit_Iterator;
+class CFX_Edit_Provider;
+class CFX_RenderDevice;
+class CFX_SystemHandler;
+class CPDF_PageObjectHolder;
+class CPDF_TextObject;
+class CPWL_Edit;
+class CPWL_EditCtrl;
+
+class IFX_Edit_UndoItem;
+
+struct CFX_Edit_LineRect {
+  CFX_Edit_LineRect(const CPVT_WordRange& wrLine, const CFX_FloatRect& rcLine)
+      : m_wrLine(wrLine), m_rcLine(rcLine) {}
+
+  CPVT_WordRange m_wrLine;
+  CFX_FloatRect m_rcLine;
+};
+
+class CFX_Edit_LineRectArray {
+ public:
+  CFX_Edit_LineRectArray();
+  virtual ~CFX_Edit_LineRectArray();
+
+  void Empty();
+  void RemoveAll();
+  void operator=(CFX_Edit_LineRectArray& rects);
+  void Add(const CPVT_WordRange& wrLine, const CFX_FloatRect& rcLine);
+
+  int32_t GetSize() const;
+  CFX_Edit_LineRect* GetAt(int32_t nIndex) const;
+
+ private:
+  CFX_ArrayTemplate<CFX_Edit_LineRect*> m_LineRects;
+};
+
+class CFX_Edit_RectArray {
+ public:
+  CFX_Edit_RectArray();
+  virtual ~CFX_Edit_RectArray();
+
+  void Empty();
+  void Add(const CFX_FloatRect& rect);
+
+  int32_t GetSize() const;
+  CFX_FloatRect* GetAt(int32_t nIndex) const;
+
+ private:
+  CFX_ArrayTemplate<CFX_FloatRect*> m_Rects;
+};
+
+class CFX_Edit_Refresh {
+ public:
+  CFX_Edit_Refresh();
+  virtual ~CFX_Edit_Refresh();
+
+  void BeginRefresh();
+  void Push(const CPVT_WordRange& linerange, const CFX_FloatRect& rect);
+  void NoAnalyse();
+  void AddRefresh(const CFX_FloatRect& rect);
+  const CFX_Edit_RectArray* GetRefreshRects() const;
+  void EndRefresh();
+
+ private:
+  CFX_Edit_LineRectArray m_NewLineRects;
+  CFX_Edit_LineRectArray m_OldLineRects;
+  CFX_Edit_RectArray m_RefreshRects;
+};
+
+class CFX_Edit_Select {
+ public:
+  CFX_Edit_Select();
+  CFX_Edit_Select(const CPVT_WordPlace& begin, const CPVT_WordPlace& end);
+  explicit CFX_Edit_Select(const CPVT_WordRange& range);
+
+  void Default();
+  void Set(const CPVT_WordPlace& begin, const CPVT_WordPlace& end);
+  void SetBeginPos(const CPVT_WordPlace& begin);
+  void SetEndPos(const CPVT_WordPlace& end);
+
+  CPVT_WordRange ConvertToWordRange() const;
+  bool IsExist() const;
+
+  CPVT_WordPlace BeginPos, EndPos;
+};
+
+class CFX_Edit_Undo {
+ public:
+  explicit CFX_Edit_Undo(int32_t nBufsize);
+  virtual ~CFX_Edit_Undo();
+
+  void Undo();
+  void Redo();
+
+  void AddItem(IFX_Edit_UndoItem* pItem);
+
+  bool CanUndo() const;
+  bool CanRedo() const;
+  bool IsModified() const;
+
+  void Reset();
+
+ private:
+  void RemoveHeads();
+  void RemoveTails();
+
+ private:
+  CFX_ArrayTemplate<IFX_Edit_UndoItem*> m_UndoItemStack;
+
+  int32_t m_nCurUndoPos;
+  int32_t m_nBufSize;
+  bool m_bModified;
+  bool m_bVirgin;
+  bool m_bWorking;
+};
+
+class IFX_Edit_UndoItem {
+ public:
+  virtual ~IFX_Edit_UndoItem() {}
+
+  virtual void Undo() = 0;
+  virtual void Redo() = 0;
+  virtual CFX_WideString GetUndoTitle() = 0;
+};
+
+class CFX_Edit_UndoItem : public IFX_Edit_UndoItem {
+ public:
+  CFX_Edit_UndoItem();
+  ~CFX_Edit_UndoItem() override;
+
+  CFX_WideString GetUndoTitle() override;
+
+  void SetFirst(bool bFirst);
+  void SetLast(bool bLast);
+  bool IsLast();
+
+ private:
+  bool m_bFirst;
+  bool m_bLast;
+};
+
+class CFX_Edit_GroupUndoItem : public IFX_Edit_UndoItem {
+ public:
+  explicit CFX_Edit_GroupUndoItem(const CFX_WideString& sTitle);
+  ~CFX_Edit_GroupUndoItem() override;
+
+  // IFX_Edit_UndoItem
+  void Undo() override;
+  void Redo() override;
+  CFX_WideString GetUndoTitle() override;
+
+  void AddUndoItem(CFX_Edit_UndoItem* pUndoItem);
+  void UpdateItems();
+
+ private:
+  CFX_WideString m_sTitle;
+  CFX_ArrayTemplate<CFX_Edit_UndoItem*> m_Items;
+};
+
+class CFXEU_InsertWord : public CFX_Edit_UndoItem {
+ public:
+  CFXEU_InsertWord(CFX_Edit* pEdit,
+                   const CPVT_WordPlace& wpOldPlace,
+                   const CPVT_WordPlace& wpNewPlace,
+                   uint16_t word,
+                   int32_t charset,
+                   const CPVT_WordProps* pWordProps);
+  ~CFXEU_InsertWord() override;
+
+  // CFX_Edit_UndoItem
+  void Redo() override;
+  void Undo() override;
+
+ private:
+  CFX_Edit* m_pEdit;
+
+  CPVT_WordPlace m_wpOld;
+  CPVT_WordPlace m_wpNew;
+  uint16_t m_Word;
+  int32_t m_nCharset;
+  CPVT_WordProps m_WordProps;
+};
+
+class CFXEU_InsertReturn : public CFX_Edit_UndoItem {
+ public:
+  CFXEU_InsertReturn(CFX_Edit* pEdit,
+                     const CPVT_WordPlace& wpOldPlace,
+                     const CPVT_WordPlace& wpNewPlace,
+                     const CPVT_SecProps* pSecProps,
+                     const CPVT_WordProps* pWordProps);
+  ~CFXEU_InsertReturn() override;
+
+  // CFX_Edit_UndoItem
+  void Redo() override;
+  void Undo() override;
+
+ private:
+  CFX_Edit* m_pEdit;
+
+  CPVT_WordPlace m_wpOld;
+  CPVT_WordPlace m_wpNew;
+  CPVT_SecProps m_SecProps;
+  CPVT_WordProps m_WordProps;
+};
+
+class CFXEU_Backspace : public CFX_Edit_UndoItem {
+ public:
+  CFXEU_Backspace(CFX_Edit* pEdit,
+                  const CPVT_WordPlace& wpOldPlace,
+                  const CPVT_WordPlace& wpNewPlace,
+                  uint16_t word,
+                  int32_t charset,
+                  const CPVT_SecProps& SecProps,
+                  const CPVT_WordProps& WordProps);
+  ~CFXEU_Backspace() override;
+
+  // CFX_Edit_UndoItem
+  void Redo() override;
+  void Undo() override;
+
+ private:
+  CFX_Edit* m_pEdit;
+
+  CPVT_WordPlace m_wpOld;
+  CPVT_WordPlace m_wpNew;
+  uint16_t m_Word;
+  int32_t m_nCharset;
+  CPVT_SecProps m_SecProps;
+  CPVT_WordProps m_WordProps;
+};
+
+class CFXEU_Delete : public CFX_Edit_UndoItem {
+ public:
+  CFXEU_Delete(CFX_Edit* pEdit,
+               const CPVT_WordPlace& wpOldPlace,
+               const CPVT_WordPlace& wpNewPlace,
+               uint16_t word,
+               int32_t charset,
+               const CPVT_SecProps& SecProps,
+               const CPVT_WordProps& WordProps,
+               bool bSecEnd);
+  ~CFXEU_Delete() override;
+
+  // CFX_Edit_UndoItem
+  void Redo() override;
+  void Undo() override;
+
+ private:
+  CFX_Edit* m_pEdit;
+
+  CPVT_WordPlace m_wpOld;
+  CPVT_WordPlace m_wpNew;
+  uint16_t m_Word;
+  int32_t m_nCharset;
+  CPVT_SecProps m_SecProps;
+  CPVT_WordProps m_WordProps;
+  bool m_bSecEnd;
+};
+
+class CFXEU_Clear : public CFX_Edit_UndoItem {
+ public:
+  CFXEU_Clear(CFX_Edit* pEdit,
+              const CPVT_WordRange& wrSel,
+              const CFX_WideString& swText);
+  ~CFXEU_Clear() override;
+
+  // CFX_Edit_UndoItem
+  void Redo() override;
+  void Undo() override;
+
+ private:
+  CFX_Edit* m_pEdit;
+
+  CPVT_WordRange m_wrSel;
+  CFX_WideString m_swText;
+};
+
+class CFXEU_InsertText : public CFX_Edit_UndoItem {
+ public:
+  CFXEU_InsertText(CFX_Edit* pEdit,
+                   const CPVT_WordPlace& wpOldPlace,
+                   const CPVT_WordPlace& wpNewPlace,
+                   const CFX_WideString& swText,
+                   int32_t charset);
+  ~CFXEU_InsertText() override;
+
+  // CFX_Edit_UndoItem
+  void Redo() override;
+  void Undo() override;
+
+ private:
+  CFX_Edit* m_pEdit;
+
+  CPVT_WordPlace m_wpOld;
+  CPVT_WordPlace m_wpNew;
+  CFX_WideString m_swText;
+  int32_t m_nCharset;
+};
+
+class CFX_Edit {
+ public:
+  static CFX_ByteString GetEditAppearanceStream(CFX_Edit* pEdit,
+                                                const CFX_FloatPoint& ptOffset,
+                                                const CPVT_WordRange* pRange,
+                                                bool bContinuous,
+                                                uint16_t SubWord);
+  static CFX_ByteString GetSelectAppearanceStream(
+      CFX_Edit* pEdit,
+      const CFX_FloatPoint& ptOffset,
+      const CPVT_WordRange* pRange);
+  static void DrawEdit(CFX_RenderDevice* pDevice,
+                       CFX_Matrix* pUser2Device,
+                       CFX_Edit* pEdit,
+                       FX_COLORREF crTextFill,
+                       FX_COLORREF crTextStroke,
+                       const CFX_FloatRect& rcClip,
+                       const CFX_FloatPoint& ptOffset,
+                       const CPVT_WordRange* pRange,
+                       CFX_SystemHandler* pSystemHandler,
+                       CFFL_FormFiller* pFFLData);
+  static void GeneratePageObjects(CPDF_PageObjectHolder* pObjectHolder,
+                                  CFX_Edit* pEdit,
+                                  const CFX_FloatPoint& ptOffset,
+                                  const CPVT_WordRange* pRange,
+                                  FX_COLORREF crText,
+                                  std::vector<CPDF_TextObject*>* ObjArray);
+
+  CFX_Edit();
+  ~CFX_Edit();
+
+  void SetFontMap(IPVT_FontMap* pFontMap);
+  void SetNotify(CPWL_EditCtrl* pNotify);
+  void SetOprNotify(CPWL_Edit* pOprNotify);
+
+  // Returns an iterator for the contents. Should not be released.
+  CFX_Edit_Iterator* GetIterator();
+  IPVT_FontMap* GetFontMap();
+  void Initialize();
+
+  // Set the bounding box of the text area.
+  void SetPlateRect(const CFX_FloatRect& rect);
+  void SetScrollPos(const CFX_FloatPoint& point);
+
+  // Set the horizontal text alignment. (nFormat [0:left, 1:middle, 2:right])
+  void SetAlignmentH(int32_t nFormat, bool bPaint);
+  // Set the vertical text alignment. (nFormat [0:left, 1:middle, 2:right])
+  void SetAlignmentV(int32_t nFormat, bool bPaint);
+
+  // Set the substitution character for hidden text.
+  void SetPasswordChar(uint16_t wSubWord, bool bPaint);
+
+  // Set the maximum number of words in the text.
+  void SetLimitChar(int32_t nLimitChar);
+  void SetCharArray(int32_t nCharArray);
+  void SetCharSpace(FX_FLOAT fCharSpace);
+  void SetMultiLine(bool bMultiLine, bool bPaint);
+  void SetAutoReturn(bool bAuto, bool bPaint);
+  void SetAutoFontSize(bool bAuto, bool bPaint);
+  void SetAutoScroll(bool bAuto, bool bPaint);
+  void SetFontSize(FX_FLOAT fFontSize);
+  void SetTextOverflow(bool bAllowed, bool bPaint);
+  void OnMouseDown(const CFX_FloatPoint& point, bool bShift, bool bCtrl);
+  void OnMouseMove(const CFX_FloatPoint& point, bool bShift, bool bCtrl);
+  void OnVK_UP(bool bShift, bool bCtrl);
+  void OnVK_DOWN(bool bShift, bool bCtrl);
+  void OnVK_LEFT(bool bShift, bool bCtrl);
+  void OnVK_RIGHT(bool bShift, bool bCtrl);
+  void OnVK_HOME(bool bShift, bool bCtrl);
+  void OnVK_END(bool bShift, bool bCtrl);
+  void SetText(const CFX_WideString& sText);
+  bool InsertWord(uint16_t word, int32_t charset);
+  bool InsertReturn();
+  bool Backspace();
+  bool Delete();
+  bool Clear();
+  bool InsertText(const CFX_WideString& sText, int32_t charset);
+  bool Redo();
+  bool Undo();
+  int32_t WordPlaceToWordIndex(const CPVT_WordPlace& place) const;
+  CPVT_WordPlace WordIndexToWordPlace(int32_t index) const;
+  CPVT_WordPlace SearchWordPlace(const CFX_FloatPoint& point) const;
+  int32_t GetCaret() const;
+  CPVT_WordPlace GetCaretWordPlace() const;
+  CFX_WideString GetSelText() const;
+  CFX_WideString GetText() const;
+  FX_FLOAT GetFontSize() const;
+  uint16_t GetPasswordChar() const;
+  CFX_FloatPoint GetScrollPos() const;
+  int32_t GetCharArray() const;
+  CFX_FloatRect GetContentRect() const;
+  CFX_WideString GetRangeText(const CPVT_WordRange& range) const;
+  int32_t GetHorzScale() const;
+  FX_FLOAT GetCharSpace() const;
+  int32_t GetTotalWords() const;
+  void SetSel(int32_t nStartChar, int32_t nEndChar);
+  void GetSel(int32_t& nStartChar, int32_t& nEndChar) const;
+  void SelectAll();
+  void SelectNone();
+  bool IsSelected() const;
+  void Paint();
+  void EnableRefresh(bool bRefresh);
+  void RefreshWordRange(const CPVT_WordRange& wr);
+  void SetCaret(int32_t nPos);
+  CPVT_WordRange GetWholeWordRange() const;
+  CPVT_WordRange GetSelectWordRange() const;
+  void EnableUndo(bool bUndo);
+  void EnableOprNotify(bool bNotify);
+  bool IsTextFull() const;
+  bool IsTextOverflow() const;
+  bool CanUndo() const;
+  bool CanRedo() const;
+  CPVT_WordRange GetVisibleWordRange() const;
+
+  bool Empty();
+
+  CPVT_WordPlace DoInsertText(const CPVT_WordPlace& place,
+                              const CFX_WideString& sText,
+                              int32_t charset);
+  int32_t GetCharSetFromUnicode(uint16_t word, int32_t nOldCharset);
+
+  int32_t GetTotalLines() const;
+
+ private:
+  friend class CFX_Edit_Iterator;
+  friend class CFXEU_InsertWord;
+  friend class CFXEU_InsertReturn;
+  friend class CFXEU_Backspace;
+  friend class CFXEU_Delete;
+  friend class CFXEU_Clear;
+  friend class CFXEU_InsertText;
+
+  void SetSel(const CPVT_WordPlace& begin, const CPVT_WordPlace& end);
+
+  void RearrangeAll();
+  void RearrangePart(const CPVT_WordRange& range);
+  void ScrollToCaret();
+  void SetScrollInfo();
+  void SetScrollPosX(FX_FLOAT fx);
+  void SetScrollPosY(FX_FLOAT fy);
+  void SetScrollLimit();
+  void SetContentChanged();
+
+  bool InsertWord(uint16_t word,
+                  int32_t charset,
+                  const CPVT_WordProps* pWordProps,
+                  bool bAddUndo,
+                  bool bPaint);
+  bool InsertReturn(const CPVT_SecProps* pSecProps,
+                    const CPVT_WordProps* pWordProps,
+                    bool bAddUndo,
+                    bool bPaint);
+  bool Backspace(bool bAddUndo, bool bPaint);
+  bool Delete(bool bAddUndo, bool bPaint);
+  bool Clear(bool bAddUndo, bool bPaint);
+  bool InsertText(const CFX_WideString& sText,
+                  int32_t charset,
+                  bool bAddUndo,
+                  bool bPaint);
+  void PaintInsertText(const CPVT_WordPlace& wpOld,
+                       const CPVT_WordPlace& wpNew);
+
+  inline CFX_FloatPoint VTToEdit(const CFX_FloatPoint& point) const;
+  inline CFX_FloatPoint EditToVT(const CFX_FloatPoint& point) const;
+  inline CFX_FloatRect VTToEdit(const CFX_FloatRect& rect) const;
+
+  void Refresh();
+  void RefreshPushLineRects(const CPVT_WordRange& wr);
+
+  void SetCaret(const CPVT_WordPlace& place);
+  void SetCaretInfo();
+  void SetCaretOrigin();
+
+  void AddEditUndoItem(CFX_Edit_UndoItem* pEditUndoItem);
+
+ private:
+  std::unique_ptr<CPDF_VariableText> m_pVT;
+  CPWL_EditCtrl* m_pNotify;
+  CPWL_Edit* m_pOprNotify;
+  std::unique_ptr<CFX_Edit_Provider> m_pVTProvider;
+
+  CPVT_WordPlace m_wpCaret;
+  CPVT_WordPlace m_wpOldCaret;
+  CFX_Edit_Select m_SelState;
+
+  CFX_FloatPoint m_ptScrollPos;
+  CFX_FloatPoint m_ptRefreshScrollPos;
+  bool m_bEnableScroll;
+  std::unique_ptr<CFX_Edit_Iterator> m_pIterator;
+  CFX_Edit_Refresh m_Refresh;
+  CFX_FloatPoint m_ptCaret;
+  CFX_Edit_Undo m_Undo;
+  int32_t m_nAlignment;
+  bool m_bNotifyFlag;
+  bool m_bEnableOverflow;
+  bool m_bEnableRefresh;
+  CFX_FloatRect m_rcOldContent;
+  bool m_bEnableUndo;
+  bool m_bOprNotify;
+  CFX_Edit_GroupUndoItem* m_pGroupUndoItem;
+};
+
+class CFX_Edit_Iterator {
+ public:
+  CFX_Edit_Iterator(CFX_Edit* pEdit, CPDF_VariableText::Iterator* pVTIterator);
+  ~CFX_Edit_Iterator();
+
+  bool NextWord();
+  bool PrevWord();
+  bool GetWord(CPVT_Word& word) const;
+  bool GetLine(CPVT_Line& line) const;
+  bool GetSection(CPVT_Section& section) const;
+  void SetAt(int32_t nWordIndex);
+  void SetAt(const CPVT_WordPlace& place);
+  const CPVT_WordPlace& GetAt() const;
+
+ private:
+  CFX_Edit* m_pEdit;
+  CPDF_VariableText::Iterator* m_pVTIterator;
+};
+
+class CFX_Edit_Provider : public CPDF_VariableText::Provider {
+ public:
+  explicit CFX_Edit_Provider(IPVT_FontMap* pFontMap);
+  ~CFX_Edit_Provider() override;
+
+  IPVT_FontMap* GetFontMap();
+
+  // CPDF_VariableText::Provider:
+  int32_t GetCharWidth(int32_t nFontIndex, uint16_t word) override;
+  int32_t GetTypeAscent(int32_t nFontIndex) override;
+  int32_t GetTypeDescent(int32_t nFontIndex) override;
+  int32_t GetWordFontIndex(uint16_t word,
+                           int32_t charset,
+                           int32_t nFontIndex) override;
+  int32_t GetDefaultFontIndex() override;
+  bool IsLatinWord(uint16_t word) override;
+
+ private:
+  IPVT_FontMap* m_pFontMap;
+};
+
+#endif  // FPDFSDK_FXEDIT_FXET_EDIT_H_
diff --git a/fpdfsdk/src/fxedit/fxet_list.cpp b/fpdfsdk/fxedit/fxet_list.cpp
similarity index 61%
rename from fpdfsdk/src/fxedit/fxet_list.cpp
rename to fpdfsdk/fxedit/fxet_list.cpp
index 4e8ae0c..cf718b9 100644
--- a/fpdfsdk/src/fxedit/fxet_list.cpp
+++ b/fpdfsdk/fxedit/fxet_list.cpp
@@ -4,37 +4,33 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#include "fpdfsdk/include/fxedit/fxet_edit.h"
-#include "fpdfsdk/include/fxedit/fxet_list.h"
+#include "fpdfsdk/fxedit/fxet_list.h"
+
+#include "core/fpdfdoc/cpvt_word.h"
+#include "fpdfsdk/fxedit/fxet_edit.h"
+#include "fpdfsdk/pdfwindow/PWL_ListBox.h"
 
 CFX_ListItem::CFX_ListItem()
-    : m_pEdit(NULL),
-      m_bSelected(FALSE),
-      m_bCaret(FALSE),
+    : m_pEdit(new CFX_Edit),
+      m_bSelected(false),
       m_rcListItem(0.0f, 0.0f, 0.0f, 0.0f) {
-  m_pEdit = IFX_Edit::NewEdit();
-  m_pEdit->SetAlignmentV(1);
+  m_pEdit->SetAlignmentV(1, true);
   m_pEdit->Initialize();
 }
 
 CFX_ListItem::~CFX_ListItem() {
-  IFX_Edit::DelEdit(m_pEdit);
 }
 
-void CFX_ListItem::SetFontMap(IFX_Edit_FontMap* pFontMap) {
-  if (m_pEdit)
-    m_pEdit->SetFontMap(pFontMap);
+void CFX_ListItem::SetFontMap(IPVT_FontMap* pFontMap) {
+  m_pEdit->SetFontMap(pFontMap);
 }
 
-IFX_Edit* CFX_ListItem::GetEdit() const {
-  return m_pEdit;
+CFX_Edit* CFX_ListItem::GetEdit() const {
+  return m_pEdit.get();
 }
 
-IFX_Edit_Iterator* CFX_ListItem::GetIterator() const {
-  if (m_pEdit)
-    return m_pEdit->GetIterator();
-
-  return NULL;
+CFX_Edit_Iterator* CFX_ListItem::GetIterator() const {
+  return m_pEdit->GetIterator();
 }
 
 void CFX_ListItem::SetRect(const CLST_Rect& rect) {
@@ -45,260 +41,44 @@
   return m_rcListItem;
 }
 
-FX_BOOL CFX_ListItem::IsSelected() const {
+bool CFX_ListItem::IsSelected() const {
   return m_bSelected;
 }
 
-void CFX_ListItem::SetSelect(FX_BOOL bSelected) {
+void CFX_ListItem::SetSelect(bool bSelected) {
   m_bSelected = bSelected;
 }
 
-FX_BOOL CFX_ListItem::IsCaret() const {
-  return m_bCaret;
-}
-
-void CFX_ListItem::SetCaret(FX_BOOL bCaret) {
-  m_bCaret = bCaret;
-}
-
-void CFX_ListItem::SetText(const FX_WCHAR* text) {
-  if (m_pEdit)
-    m_pEdit->SetText(text);
+void CFX_ListItem::SetText(const CFX_WideString& text) {
+  m_pEdit->SetText(text);
 }
 
 void CFX_ListItem::SetFontSize(FX_FLOAT fFontSize) {
-  if (m_pEdit)
-    m_pEdit->SetFontSize(fFontSize);
+  m_pEdit->SetFontSize(fFontSize);
 }
 
 FX_FLOAT CFX_ListItem::GetItemHeight() const {
-  if (m_pEdit)
-    return m_pEdit->GetContentRect().Height();
-
-  return 0.0f;
+  return m_pEdit->GetContentRect().Height();
 }
 
-FX_WORD CFX_ListItem::GetFirstChar() const {
+uint16_t CFX_ListItem::GetFirstChar() const {
   CPVT_Word word;
-
-  if (IFX_Edit_Iterator* pIterator = GetIterator()) {
-    pIterator->SetAt(1);
-    pIterator->GetWord(word);
-  }
-
+  CFX_Edit_Iterator* pIterator = GetIterator();
+  pIterator->SetAt(1);
+  pIterator->GetWord(word);
   return word.Word;
 }
 
 CFX_WideString CFX_ListItem::GetText() const {
-  if (m_pEdit)
-    return m_pEdit->GetText();
-
-  return L"";
+  return m_pEdit->GetText();
 }
 
-CFX_List::CFX_List()
-    : m_fFontSize(0.0f), m_pFontMap(NULL), m_bMultiple(FALSE) {}
+CFX_ListContainer::CFX_ListContainer() {}
 
-CFX_List::~CFX_List() {
-  Empty();
-}
+CFX_ListContainer::~CFX_ListContainer() {}
 
-void CFX_List::Empty() {
-  for (int32_t i = 0, sz = m_aListItems.GetSize(); i < sz; i++)
-    delete m_aListItems.GetAt(i);
-
-  m_aListItems.RemoveAll();
-}
-
-void CFX_List::SetFontMap(IFX_Edit_FontMap* pFontMap) {
-  m_pFontMap = pFontMap;
-}
-
-void CFX_List::SetFontSize(FX_FLOAT fFontSize) {
-  m_fFontSize = fFontSize;
-}
-
-void CFX_List::AddItem(const FX_WCHAR* str) {
-  CFX_ListItem* pListItem = new CFX_ListItem();
-  pListItem->SetFontMap(m_pFontMap);
-  pListItem->SetFontSize(m_fFontSize);
-  pListItem->SetText(str);
-  m_aListItems.Add(pListItem);
-}
-
-void CFX_List::ReArrange(int32_t nItemIndex) {
-  FX_FLOAT fPosY = 0.0f;
-
-  if (CFX_ListItem* pPrevItem = m_aListItems.GetAt(nItemIndex - 1))
-    fPosY = pPrevItem->GetRect().bottom;
-
-  for (int32_t i = nItemIndex, sz = m_aListItems.GetSize(); i < sz; i++) {
-    if (CFX_ListItem* pListItem = m_aListItems.GetAt(i)) {
-      FX_FLOAT fListItemHeight = pListItem->GetItemHeight();
-      pListItem->SetRect(CLST_Rect(0.0f, fPosY, 0.0f, fPosY + fListItemHeight));
-      fPosY += fListItemHeight;
-    }
-  }
-
-  SetContentRect(CLST_Rect(0.0f, 0.0f, 0.0f, fPosY));
-}
-
-IFX_Edit* CFX_List::GetItemEdit(int32_t nIndex) const {
-  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nIndex)) {
-    return pListItem->GetEdit();
-  }
-
-  return NULL;
-}
-
-int32_t CFX_List::GetCount() const {
-  return m_aListItems.GetSize();
-}
-
-CPDF_Rect CFX_List::GetPlateRect() const {
-  return CFX_ListContainer::GetPlateRect();
-}
-
-CPDF_Rect CFX_List::GetContentRect() const {
-  return InnerToOuter(CFX_ListContainer::GetContentRect());
-}
-
-FX_FLOAT CFX_List::GetFontSize() const {
-  return m_fFontSize;
-}
-
-int32_t CFX_List::GetItemIndex(const CPDF_Point& point) const {
-  CPDF_Point pt = OuterToInner(point);
-
-  FX_BOOL bFirst = TRUE;
-  FX_BOOL bLast = TRUE;
-
-  for (int32_t i = 0, sz = m_aListItems.GetSize(); i < sz; i++) {
-    if (CFX_ListItem* pListItem = m_aListItems.GetAt(i)) {
-      CLST_Rect rcListItem = pListItem->GetRect();
-
-      if (FX_EDIT_IsFloatBigger(pt.y, rcListItem.top)) {
-        bFirst = FALSE;
-      }
-
-      if (FX_EDIT_IsFloatSmaller(pt.y, rcListItem.bottom)) {
-        bLast = FALSE;
-      }
-
-      if (pt.y >= rcListItem.top && pt.y < rcListItem.bottom) {
-        return i;
-      }
-    }
-  }
-
-  if (bFirst)
-    return 0;
-  if (bLast)
-    return m_aListItems.GetSize() - 1;
-
-  return -1;
-}
-
-FX_FLOAT CFX_List::GetFirstHeight() const {
-  if (CFX_ListItem* pListItem = m_aListItems.GetAt(0)) {
-    return pListItem->GetItemHeight();
-  }
-
-  return 1.0f;
-}
-
-int32_t CFX_List::GetFirstSelected() const {
-  for (int32_t i = 0, sz = m_aListItems.GetSize(); i < sz; i++) {
-    if (CFX_ListItem* pListItem = m_aListItems.GetAt(i)) {
-      if (pListItem->IsSelected())
-        return i;
-    }
-  }
-  return -1;
-}
-
-int32_t CFX_List::GetLastSelected() const {
-  for (int32_t i = m_aListItems.GetSize() - 1; i >= 0; i--) {
-    if (CFX_ListItem* pListItem = m_aListItems.GetAt(i)) {
-      if (pListItem->IsSelected())
-        return i;
-    }
-  }
-  return -1;
-}
-
-FX_WCHAR CFX_List::Toupper(FX_WCHAR c) const {
-  if ((c >= 'a') && (c <= 'z'))
-    c = c - ('a' - 'A');
-  return c;
-}
-
-int32_t CFX_List::FindNext(int32_t nIndex, FX_WCHAR nChar) const {
-  int32_t nCircleIndex = nIndex;
-
-  for (int32_t i = 0, sz = m_aListItems.GetSize(); i < sz; i++) {
-    nCircleIndex++;
-    if (nCircleIndex >= sz)
-      nCircleIndex = 0;
-
-    if (CFX_ListItem* pListItem = m_aListItems.GetAt(nCircleIndex)) {
-      if (Toupper(pListItem->GetFirstChar()) == Toupper(nChar))
-        return nCircleIndex;
-    }
-  }
-
-  return nCircleIndex;
-}
-
-CPDF_Rect CFX_List::GetItemRect(int32_t nIndex) const {
-  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nIndex)) {
-    CPDF_Rect rcItem = pListItem->GetRect();
-    rcItem.left = 0.0f;
-    rcItem.right = GetPlateRect().Width();
-    return InnerToOuter(rcItem);
-  }
-
-  return CPDF_Rect();
-}
-
-FX_BOOL CFX_List::IsItemSelected(int32_t nIndex) const {
-  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nIndex)) {
-    return pListItem->IsSelected();
-  }
-
-  return FALSE;
-}
-
-void CFX_List::SetItemSelect(int32_t nItemIndex, FX_BOOL bSelected) {
-  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nItemIndex)) {
-    pListItem->SetSelect(bSelected);
-  }
-}
-
-void CFX_List::SetItemCaret(int32_t nItemIndex, FX_BOOL bCaret) {
-  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nItemIndex)) {
-    pListItem->SetCaret(bCaret);
-  }
-}
-
-void CFX_List::SetMultipleSel(FX_BOOL bMultiple) {
-  m_bMultiple = bMultiple;
-}
-
-FX_BOOL CFX_List::IsMultipleSel() const {
-  return m_bMultiple;
-}
-
-FX_BOOL CFX_List::IsValid(int32_t nItemIndex) const {
-  return nItemIndex >= 0 && nItemIndex < m_aListItems.GetSize();
-}
-
-CFX_WideString CFX_List::GetItemText(int32_t nIndex) const {
-  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nIndex)) {
-    return pListItem->GetText();
-  }
-
-  return L"";
+void CFX_ListContainer::SetPlateRect(const CFX_FloatRect& rect) {
+  m_rcPlate = rect;
 }
 
 CPLST_Select::CPLST_Select() {}
@@ -363,7 +143,7 @@
   return -1;
 }
 
-FX_BOOL CPLST_Select::IsExist(int32_t nItemIndex) const {
+bool CPLST_Select::IsExist(int32_t nItemIndex) const {
   return Find(nItemIndex) >= 0;
 }
 
@@ -409,51 +189,57 @@
 }
 
 CFX_ListCtrl::CFX_ListCtrl()
-    : m_pNotify(NULL),
-      m_bNotifyFlag(FALSE),
-      m_ptScrollPos(0.0f, 0.0f),
+    : m_pNotify(nullptr),
+      m_bNotifyFlag(false),
       m_nSelItem(-1),
       m_nFootIndex(-1),
-      m_bCtrlSel(FALSE),
-      m_nCaretIndex(-1) {}
+      m_bCtrlSel(false),
+      m_nCaretIndex(-1),
+      m_fFontSize(0.0f),
+      m_pFontMap(nullptr),
+      m_bMultiple(false) {}
 
-CFX_ListCtrl::~CFX_ListCtrl() {}
+CFX_ListCtrl::~CFX_ListCtrl() {
+  Empty();
+}
 
-void CFX_ListCtrl::SetNotify(IFX_List_Notify* pNotify) {
+void CFX_ListCtrl::SetNotify(CPWL_List_Notify* pNotify) {
   m_pNotify = pNotify;
 }
 
-CPDF_Point CFX_ListCtrl::InToOut(const CPDF_Point& point) const {
-  CPDF_Rect rcPlate = GetPlateRect();
+CFX_FloatPoint CFX_ListCtrl::InToOut(const CFX_FloatPoint& point) const {
+  CFX_FloatRect rcPlate = GetPlateRect();
 
-  return CPDF_Point(point.x - (m_ptScrollPos.x - rcPlate.left),
-                    point.y - (m_ptScrollPos.y - rcPlate.top));
+  return CFX_FloatPoint(point.x - (m_ptScrollPos.x - rcPlate.left),
+                        point.y - (m_ptScrollPos.y - rcPlate.top));
 }
 
-CPDF_Point CFX_ListCtrl::OutToIn(const CPDF_Point& point) const {
-  CPDF_Rect rcPlate = GetPlateRect();
+CFX_FloatPoint CFX_ListCtrl::OutToIn(const CFX_FloatPoint& point) const {
+  CFX_FloatRect rcPlate = GetPlateRect();
 
-  return CPDF_Point(point.x + (m_ptScrollPos.x - rcPlate.left),
-                    point.y + (m_ptScrollPos.y - rcPlate.top));
+  return CFX_FloatPoint(point.x + (m_ptScrollPos.x - rcPlate.left),
+                        point.y + (m_ptScrollPos.y - rcPlate.top));
 }
 
-CPDF_Rect CFX_ListCtrl::InToOut(const CPDF_Rect& rect) const {
-  CPDF_Point ptLeftBottom = InToOut(CPDF_Point(rect.left, rect.bottom));
-  CPDF_Point ptRightTop = InToOut(CPDF_Point(rect.right, rect.top));
+CFX_FloatRect CFX_ListCtrl::InToOut(const CFX_FloatRect& rect) const {
+  CFX_FloatPoint ptLeftBottom = InToOut(CFX_FloatPoint(rect.left, rect.bottom));
+  CFX_FloatPoint ptRightTop = InToOut(CFX_FloatPoint(rect.right, rect.top));
 
-  return CPDF_Rect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x, ptRightTop.y);
+  return CFX_FloatRect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x,
+                       ptRightTop.y);
 }
 
-CPDF_Rect CFX_ListCtrl::OutToIn(const CPDF_Rect& rect) const {
-  CPDF_Point ptLeftBottom = OutToIn(CPDF_Point(rect.left, rect.bottom));
-  CPDF_Point ptRightTop = OutToIn(CPDF_Point(rect.right, rect.top));
+CFX_FloatRect CFX_ListCtrl::OutToIn(const CFX_FloatRect& rect) const {
+  CFX_FloatPoint ptLeftBottom = OutToIn(CFX_FloatPoint(rect.left, rect.bottom));
+  CFX_FloatPoint ptRightTop = OutToIn(CFX_FloatPoint(rect.right, rect.top));
 
-  return CPDF_Rect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x, ptRightTop.y);
+  return CFX_FloatRect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x,
+                       ptRightTop.y);
 }
 
-void CFX_ListCtrl::OnMouseDown(const CPDF_Point& point,
-                               FX_BOOL bShift,
-                               FX_BOOL bCtrl) {
+void CFX_ListCtrl::OnMouseDown(const CFX_FloatPoint& point,
+                               bool bShift,
+                               bool bCtrl) {
   int32_t nHitIndex = GetItemIndex(point);
 
   if (IsMultipleSel()) {
@@ -461,11 +247,11 @@
       if (IsItemSelected(nHitIndex)) {
         m_aSelItems.Sub(nHitIndex);
         SelectItems();
-        m_bCtrlSel = FALSE;
+        m_bCtrlSel = false;
       } else {
         m_aSelItems.Add(nHitIndex);
         SelectItems();
-        m_bCtrlSel = TRUE;
+        m_bCtrlSel = true;
       }
 
       m_nFootIndex = nHitIndex;
@@ -490,9 +276,9 @@
     ScrollToListItem(nHitIndex);
 }
 
-void CFX_ListCtrl::OnMouseMove(const CPDF_Point& point,
-                               FX_BOOL bShift,
-                               FX_BOOL bCtrl) {
+void CFX_ListCtrl::OnMouseMove(const CFX_FloatPoint& point,
+                               bool bShift,
+                               bool bCtrl) {
   int32_t nHitIndex = GetItemIndex(point);
 
   if (IsMultipleSel()) {
@@ -518,7 +304,7 @@
     ScrollToListItem(nHitIndex);
 }
 
-void CFX_ListCtrl::OnVK(int32_t nItemIndex, FX_BOOL bShift, FX_BOOL bCtrl) {
+void CFX_ListCtrl::OnVK(int32_t nItemIndex, bool bShift, bool bCtrl) {
   if (IsMultipleSel()) {
     if (nItemIndex >= 0 && nItemIndex < GetCount()) {
       if (bCtrl) {
@@ -543,68 +329,87 @@
     ScrollToListItem(nItemIndex);
 }
 
-void CFX_ListCtrl::OnVK_UP(FX_BOOL bShift, FX_BOOL bCtrl) {
+void CFX_ListCtrl::OnVK_UP(bool bShift, bool bCtrl) {
   OnVK(IsMultipleSel() ? GetCaret() - 1 : GetSelect() - 1, bShift, bCtrl);
 }
 
-void CFX_ListCtrl::OnVK_DOWN(FX_BOOL bShift, FX_BOOL bCtrl) {
+void CFX_ListCtrl::OnVK_DOWN(bool bShift, bool bCtrl) {
   OnVK(IsMultipleSel() ? GetCaret() + 1 : GetSelect() + 1, bShift, bCtrl);
 }
 
-void CFX_ListCtrl::OnVK_LEFT(FX_BOOL bShift, FX_BOOL bCtrl) {
+void CFX_ListCtrl::OnVK_LEFT(bool bShift, bool bCtrl) {
   OnVK(0, bShift, bCtrl);
 }
 
-void CFX_ListCtrl::OnVK_RIGHT(FX_BOOL bShift, FX_BOOL bCtrl) {
+void CFX_ListCtrl::OnVK_RIGHT(bool bShift, bool bCtrl) {
   OnVK(GetCount() - 1, bShift, bCtrl);
 }
 
-void CFX_ListCtrl::OnVK_HOME(FX_BOOL bShift, FX_BOOL bCtrl) {
+void CFX_ListCtrl::OnVK_HOME(bool bShift, bool bCtrl) {
   OnVK(0, bShift, bCtrl);
 }
 
-void CFX_ListCtrl::OnVK_END(FX_BOOL bShift, FX_BOOL bCtrl) {
+void CFX_ListCtrl::OnVK_END(bool bShift, bool bCtrl) {
   OnVK(GetCount() - 1, bShift, bCtrl);
 }
 
-FX_BOOL CFX_ListCtrl::OnChar(FX_WORD nChar, FX_BOOL bShift, FX_BOOL bCtrl) {
+bool CFX_ListCtrl::OnChar(uint16_t nChar, bool bShift, bool bCtrl) {
   int32_t nIndex = GetLastSelected();
   int32_t nFindIndex = FindNext(nIndex, nChar);
 
   if (nFindIndex != nIndex) {
     OnVK(nFindIndex, bShift, bCtrl);
-    return TRUE;
+    return true;
   }
-  return FALSE;
+  return false;
 }
 
-void CFX_ListCtrl::SetPlateRect(const CPDF_Rect& rect) {
+void CFX_ListCtrl::SetPlateRect(const CFX_FloatRect& rect) {
   CFX_ListContainer::SetPlateRect(rect);
   m_ptScrollPos.x = rect.left;
-  SetScrollPos(CPDF_Point(rect.left, rect.top));
+  SetScrollPos(CFX_FloatPoint(rect.left, rect.top));
   ReArrange(0);
   InvalidateItem(-1);
 }
 
-CPDF_Rect CFX_ListCtrl::GetItemRect(int32_t nIndex) const {
-  return InToOut(CFX_List::GetItemRect(nIndex));
+CFX_FloatRect CFX_ListCtrl::GetItemRect(int32_t nIndex) const {
+  return InToOut(GetItemRectInternal(nIndex));
 }
 
-void CFX_ListCtrl::AddString(const FX_WCHAR* string) {
-  AddItem(string);
+CFX_FloatRect CFX_ListCtrl::GetItemRectInternal(int32_t nIndex) const {
+  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nIndex)) {
+    CFX_FloatRect rcItem = pListItem->GetRect();
+    rcItem.left = 0.0f;
+    rcItem.right = GetPlateRect().Width();
+    return InnerToOuter(CLST_Rect(rcItem));
+  }
+
+  return CFX_FloatRect();
+}
+
+int32_t CFX_ListCtrl::GetCaret() const {
+  return m_nCaretIndex;
+}
+
+int32_t CFX_ListCtrl::GetSelect() const {
+  return m_nSelItem;
+}
+
+void CFX_ListCtrl::AddString(const CFX_WideString& str) {
+  AddItem(str);
   ReArrange(GetCount() - 1);
 }
 
-void CFX_ListCtrl::SetMultipleSelect(int32_t nItemIndex, FX_BOOL bSelected) {
+void CFX_ListCtrl::SetMultipleSelect(int32_t nItemIndex, bool bSelected) {
   if (!IsValid(nItemIndex))
     return;
 
   if (bSelected != IsItemSelected(nItemIndex)) {
     if (bSelected) {
-      SetItemSelect(nItemIndex, TRUE);
+      SetItemSelect(nItemIndex, true);
       InvalidateItem(nItemIndex);
     } else {
-      SetItemSelect(nItemIndex, FALSE);
+      SetItemSelect(nItemIndex, false);
       InvalidateItem(nItemIndex);
     }
   }
@@ -616,11 +421,11 @@
 
   if (m_nSelItem != nItemIndex) {
     if (m_nSelItem >= 0) {
-      SetItemSelect(m_nSelItem, FALSE);
+      SetItemSelect(m_nSelItem, false);
       InvalidateItem(m_nSelItem);
     }
 
-    SetItemSelect(nItemIndex, TRUE);
+    SetItemSelect(nItemIndex, true);
     InvalidateItem(nItemIndex);
     m_nSelItem = nItemIndex;
   }
@@ -635,10 +440,6 @@
 
     if (nOldIndex != nItemIndex) {
       m_nCaretIndex = nItemIndex;
-
-      SetItemCaret(nOldIndex, FALSE);
-      SetItemCaret(nItemIndex, TRUE);
-
       InvalidateItem(nOldIndex);
       InvalidateItem(nItemIndex);
     }
@@ -649,22 +450,22 @@
   if (m_pNotify) {
     if (nItemIndex == -1) {
       if (!m_bNotifyFlag) {
-        m_bNotifyFlag = TRUE;
-        CPDF_Rect rcRefresh = GetPlateRect();
+        m_bNotifyFlag = true;
+        CFX_FloatRect rcRefresh = GetPlateRect();
         m_pNotify->IOnInvalidateRect(&rcRefresh);
-        m_bNotifyFlag = FALSE;
+        m_bNotifyFlag = false;
       }
     } else {
       if (!m_bNotifyFlag) {
-        m_bNotifyFlag = TRUE;
-        CPDF_Rect rcRefresh = GetItemRect(nItemIndex);
+        m_bNotifyFlag = true;
+        CFX_FloatRect rcRefresh = GetItemRect(nItemIndex);
         rcRefresh.left -= 1.0f;
         rcRefresh.right += 1.0f;
         rcRefresh.bottom -= 1.0f;
         rcRefresh.top += 1.0f;
 
         m_pNotify->IOnInvalidateRect(&rcRefresh);
-        m_bNotifyFlag = FALSE;
+        m_bNotifyFlag = false;
       }
     }
   }
@@ -677,10 +478,10 @@
 
     switch (nState) {
       case 1:
-        SetMultipleSelect(nItemIndex, TRUE);
+        SetMultipleSelect(nItemIndex, true);
         break;
       case -1:
-        SetMultipleSelect(nItemIndex, FALSE);
+        SetMultipleSelect(nItemIndex, false);
         break;
     }
   }
@@ -700,9 +501,9 @@
   }
 }
 
-FX_BOOL CFX_ListCtrl::IsItemVisible(int32_t nItemIndex) const {
-  CPDF_Rect rcPlate = GetPlateRect();
-  CPDF_Rect rcItem = GetItemRect(nItemIndex);
+bool CFX_ListCtrl::IsItemVisible(int32_t nItemIndex) const {
+  CFX_FloatRect rcPlate = GetPlateRect();
+  CFX_FloatRect rcItem = GetItemRect(nItemIndex);
 
   return rcItem.bottom >= rcPlate.bottom && rcItem.top <= rcPlate.top;
 }
@@ -711,16 +512,16 @@
   if (!IsValid(nItemIndex))
     return;
 
-  CPDF_Rect rcPlate = GetPlateRect();
-  CPDF_Rect rcItem = CFX_List::GetItemRect(nItemIndex);
-  CPDF_Rect rcItemCtrl = GetItemRect(nItemIndex);
+  CFX_FloatRect rcPlate = GetPlateRect();
+  CFX_FloatRect rcItem = GetItemRectInternal(nItemIndex);
+  CFX_FloatRect rcItemCtrl = GetItemRect(nItemIndex);
 
-  if (FX_EDIT_IsFloatSmaller(rcItemCtrl.bottom, rcPlate.bottom)) {
-    if (FX_EDIT_IsFloatSmaller(rcItemCtrl.top, rcPlate.top)) {
+  if (IsFloatSmaller(rcItemCtrl.bottom, rcPlate.bottom)) {
+    if (IsFloatSmaller(rcItemCtrl.top, rcPlate.top)) {
       SetScrollPosY(rcItem.bottom + rcPlate.Height());
     }
-  } else if (FX_EDIT_IsFloatBigger(rcItemCtrl.top, rcPlate.top)) {
-    if (FX_EDIT_IsFloatBigger(rcItemCtrl.bottom, rcPlate.bottom)) {
+  } else if (IsFloatBigger(rcItemCtrl.top, rcPlate.top)) {
+    if (IsFloatBigger(rcItemCtrl.bottom, rcPlate.bottom)) {
       SetScrollPosY(rcItem.top);
     }
   }
@@ -728,34 +529,34 @@
 
 void CFX_ListCtrl::SetScrollInfo() {
   if (m_pNotify) {
-    CPDF_Rect rcPlate = GetPlateRect();
-    CPDF_Rect rcContent = CFX_List::GetContentRect();
+    CFX_FloatRect rcPlate = GetPlateRect();
+    CFX_FloatRect rcContent = GetContentRectInternal();
 
     if (!m_bNotifyFlag) {
-      m_bNotifyFlag = TRUE;
+      m_bNotifyFlag = true;
       m_pNotify->IOnSetScrollInfoY(rcPlate.bottom, rcPlate.top,
                                    rcContent.bottom, rcContent.top,
                                    GetFirstHeight(), rcPlate.Height());
-      m_bNotifyFlag = FALSE;
+      m_bNotifyFlag = false;
     }
   }
 }
 
-void CFX_ListCtrl::SetScrollPos(const CPDF_Point& point) {
+void CFX_ListCtrl::SetScrollPos(const CFX_FloatPoint& point) {
   SetScrollPosY(point.y);
 }
 
 void CFX_ListCtrl::SetScrollPosY(FX_FLOAT fy) {
-  if (!FX_EDIT_IsFloatEqual(m_ptScrollPos.y, fy)) {
-    CPDF_Rect rcPlate = GetPlateRect();
-    CPDF_Rect rcContent = CFX_List::GetContentRect();
+  if (!IsFloatEqual(m_ptScrollPos.y, fy)) {
+    CFX_FloatRect rcPlate = GetPlateRect();
+    CFX_FloatRect rcContent = GetContentRectInternal();
 
     if (rcPlate.Height() > rcContent.Height()) {
       fy = rcPlate.top;
     } else {
-      if (FX_EDIT_IsFloatSmaller(fy - rcPlate.Height(), rcContent.bottom)) {
+      if (IsFloatSmaller(fy - rcPlate.Height(), rcContent.bottom)) {
         fy = rcContent.bottom + rcPlate.Height();
-      } else if (FX_EDIT_IsFloatBigger(fy, rcContent.top)) {
+      } else if (IsFloatBigger(fy, rcContent.top)) {
         fy = rcContent.top;
       }
     }
@@ -765,27 +566,44 @@
 
     if (m_pNotify) {
       if (!m_bNotifyFlag) {
-        m_bNotifyFlag = TRUE;
+        m_bNotifyFlag = true;
         m_pNotify->IOnSetScrollPosY(fy);
-        m_bNotifyFlag = FALSE;
+        m_bNotifyFlag = false;
       }
     }
   }
 }
 
-CPDF_Rect CFX_ListCtrl::GetContentRect() const {
-  return InToOut(CFX_List::GetContentRect());
+CFX_FloatRect CFX_ListCtrl::GetContentRectInternal() const {
+  return InnerToOuter(CFX_ListContainer::GetContentRect());
+}
+
+CFX_FloatRect CFX_ListCtrl::GetContentRect() const {
+  return InToOut(GetContentRectInternal());
 }
 
 void CFX_ListCtrl::ReArrange(int32_t nItemIndex) {
-  CFX_List::ReArrange(nItemIndex);
+  FX_FLOAT fPosY = 0.0f;
+
+  if (CFX_ListItem* pPrevItem = m_aListItems.GetAt(nItemIndex - 1))
+    fPosY = pPrevItem->GetRect().bottom;
+
+  for (int32_t i = nItemIndex, sz = m_aListItems.GetSize(); i < sz; i++) {
+    if (CFX_ListItem* pListItem = m_aListItems.GetAt(i)) {
+      FX_FLOAT fListItemHeight = pListItem->GetItemHeight();
+      pListItem->SetRect(CLST_Rect(0.0f, fPosY, 0.0f, fPosY + fListItemHeight));
+      fPosY += fListItemHeight;
+    }
+  }
+
+  SetContentRect(CLST_Rect(0.0f, 0.0f, 0.0f, fPosY));
   SetScrollInfo();
 }
 
 void CFX_ListCtrl::SetTopItem(int32_t nIndex) {
   if (IsValid(nIndex)) {
     GetPlateRect();
-    CPDF_Rect rcItem = CFX_List::GetItemRect(nIndex);
+    CFX_FloatRect rcItem = GetItemRectInternal(nIndex);
     SetScrollPosY(rcItem.top);
   }
 }
@@ -800,7 +618,11 @@
 }
 
 void CFX_ListCtrl::Empty() {
-  CFX_List::Empty();
+  for (int32_t i = 0, sz = m_aListItems.GetSize(); i < sz; i++)
+    delete m_aListItems.GetAt(i);
+
+  m_aListItems.RemoveAll();
+
   InvalidateItem(-1);
 }
 
@@ -808,8 +630,36 @@
   m_aSelItems.DeselectAll();
 }
 
-int32_t CFX_ListCtrl::GetItemIndex(const CPDF_Point& point) const {
-  return CFX_List::GetItemIndex(OutToIn(point));
+int32_t CFX_ListCtrl::GetItemIndex(const CFX_FloatPoint& point) const {
+  CFX_FloatPoint pt = OuterToInner(OutToIn(point));
+
+  bool bFirst = true;
+  bool bLast = true;
+
+  for (int32_t i = 0, sz = m_aListItems.GetSize(); i < sz; i++) {
+    if (CFX_ListItem* pListItem = m_aListItems.GetAt(i)) {
+      CLST_Rect rcListItem = pListItem->GetRect();
+
+      if (IsFloatBigger(pt.y, rcListItem.top)) {
+        bFirst = false;
+      }
+
+      if (IsFloatSmaller(pt.y, rcListItem.bottom)) {
+        bLast = false;
+      }
+
+      if (pt.y >= rcListItem.top && pt.y < rcListItem.bottom) {
+        return i;
+      }
+    }
+  }
+
+  if (bFirst)
+    return 0;
+  if (bLast)
+    return m_aListItems.GetSize() - 1;
+
+  return -1;
 }
 
 CFX_WideString CFX_ListCtrl::GetText() const {
@@ -817,3 +667,122 @@
     return GetItemText(m_nCaretIndex);
   return GetItemText(m_nSelItem);
 }
+
+void CFX_ListCtrl::SetFontMap(IPVT_FontMap* pFontMap) {
+  m_pFontMap = pFontMap;
+}
+
+void CFX_ListCtrl::SetFontSize(FX_FLOAT fFontSize) {
+  m_fFontSize = fFontSize;
+}
+
+void CFX_ListCtrl::AddItem(const CFX_WideString& str) {
+  CFX_ListItem* pListItem = new CFX_ListItem();
+  pListItem->SetFontMap(m_pFontMap);
+  pListItem->SetFontSize(m_fFontSize);
+  pListItem->SetText(str);
+  m_aListItems.Add(pListItem);
+}
+
+CFX_Edit* CFX_ListCtrl::GetItemEdit(int32_t nIndex) const {
+  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nIndex)) {
+    return pListItem->GetEdit();
+  }
+
+  return nullptr;
+}
+
+int32_t CFX_ListCtrl::GetCount() const {
+  return m_aListItems.GetSize();
+}
+
+CFX_FloatRect CFX_ListCtrl::GetPlateRect() const {
+  return CFX_ListContainer::GetPlateRect();
+}
+
+FX_FLOAT CFX_ListCtrl::GetFontSize() const {
+  return m_fFontSize;
+}
+
+FX_FLOAT CFX_ListCtrl::GetFirstHeight() const {
+  if (CFX_ListItem* pListItem = m_aListItems.GetAt(0)) {
+    return pListItem->GetItemHeight();
+  }
+
+  return 1.0f;
+}
+
+int32_t CFX_ListCtrl::GetFirstSelected() const {
+  for (int32_t i = 0, sz = m_aListItems.GetSize(); i < sz; i++) {
+    if (CFX_ListItem* pListItem = m_aListItems.GetAt(i)) {
+      if (pListItem->IsSelected())
+        return i;
+    }
+  }
+  return -1;
+}
+
+int32_t CFX_ListCtrl::GetLastSelected() const {
+  for (int32_t i = m_aListItems.GetSize() - 1; i >= 0; i--) {
+    if (CFX_ListItem* pListItem = m_aListItems.GetAt(i)) {
+      if (pListItem->IsSelected())
+        return i;
+    }
+  }
+  return -1;
+}
+
+FX_WCHAR CFX_ListCtrl::Toupper(FX_WCHAR c) const {
+  if ((c >= 'a') && (c <= 'z'))
+    c = c - ('a' - 'A');
+  return c;
+}
+
+int32_t CFX_ListCtrl::FindNext(int32_t nIndex, FX_WCHAR nChar) const {
+  int32_t nCircleIndex = nIndex;
+
+  for (int32_t i = 0, sz = m_aListItems.GetSize(); i < sz; i++) {
+    nCircleIndex++;
+    if (nCircleIndex >= sz)
+      nCircleIndex = 0;
+
+    if (CFX_ListItem* pListItem = m_aListItems.GetAt(nCircleIndex)) {
+      if (Toupper(pListItem->GetFirstChar()) == Toupper(nChar))
+        return nCircleIndex;
+    }
+  }
+
+  return nCircleIndex;
+}
+
+bool CFX_ListCtrl::IsItemSelected(int32_t nIndex) const {
+  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nIndex))
+    return pListItem->IsSelected();
+  return false;
+}
+
+void CFX_ListCtrl::SetItemSelect(int32_t nItemIndex, bool bSelected) {
+  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nItemIndex)) {
+    pListItem->SetSelect(bSelected);
+  }
+}
+
+void CFX_ListCtrl::SetMultipleSel(bool bMultiple) {
+  m_bMultiple = bMultiple;
+}
+
+bool CFX_ListCtrl::IsMultipleSel() const {
+  return m_bMultiple;
+}
+
+bool CFX_ListCtrl::IsValid(int32_t nItemIndex) const {
+  return nItemIndex >= 0 && nItemIndex < m_aListItems.GetSize();
+}
+
+CFX_WideString CFX_ListCtrl::GetItemText(int32_t nIndex) const {
+  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nIndex)) {
+    return pListItem->GetText();
+  }
+
+  return L"";
+}
diff --git a/fpdfsdk/fxedit/fxet_list.h b/fpdfsdk/fxedit/fxet_list.h
new file mode 100644
index 0000000..38d1957
--- /dev/null
+++ b/fpdfsdk/fxedit/fxet_list.h
@@ -0,0 +1,306 @@
+// 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_FXEDIT_FXET_LIST_H_
+#define FPDFSDK_FXEDIT_FXET_LIST_H_
+
+#include <memory>
+
+#include "core/fxcrt/fx_coordinates.h"
+#include "fpdfsdk/fxedit/fx_edit.h"
+
+class CFX_Edit;
+class CFX_Edit_Iterator;
+class CPWL_List_Notify;
+
+class CLST_Rect : public CFX_FloatRect {
+ public:
+  CLST_Rect() { left = top = right = bottom = 0.0f; }
+
+  CLST_Rect(FX_FLOAT other_left,
+            FX_FLOAT other_top,
+            FX_FLOAT other_right,
+            FX_FLOAT other_bottom) {
+    left = other_left;
+    top = other_top;
+    right = other_right;
+    bottom = other_bottom;
+  }
+
+  explicit CLST_Rect(const CFX_FloatRect& rect) {
+    left = rect.left;
+    top = rect.top;
+    right = rect.right;
+    bottom = rect.bottom;
+  }
+
+  ~CLST_Rect() {}
+
+  void Default() { left = top = right = bottom = 0.0f; }
+
+  const CLST_Rect operator=(const CFX_FloatRect& rect) {
+    left = rect.left;
+    top = rect.top;
+    right = rect.right;
+    bottom = rect.bottom;
+
+    return *this;
+  }
+
+  bool operator==(const CLST_Rect& rect) const {
+    return FXSYS_memcmp(this, &rect, sizeof(CLST_Rect)) == 0;
+  }
+
+  bool operator!=(const CLST_Rect& rect) const { return !(*this == rect); }
+
+  FX_FLOAT Width() const { return right - left; }
+
+  FX_FLOAT Height() const {
+    if (top > bottom)
+      return top - bottom;
+    return bottom - top;
+  }
+
+  CFX_FloatPoint LeftTop() const { return CFX_FloatPoint(left, top); }
+
+  CFX_FloatPoint RightBottom() const { return CFX_FloatPoint(right, bottom); }
+
+  const CLST_Rect operator+=(const CFX_FloatPoint& point) {
+    left += point.x;
+    right += point.x;
+    top += point.y;
+    bottom += point.y;
+
+    return *this;
+  }
+
+  const CLST_Rect operator-=(const CFX_FloatPoint& point) {
+    left -= point.x;
+    right -= point.x;
+    top -= point.y;
+    bottom -= point.y;
+
+    return *this;
+  }
+
+  CLST_Rect operator+(const CFX_FloatPoint& point) const {
+    return CLST_Rect(left + point.x, top + point.y, right + point.x,
+                     bottom + point.y);
+  }
+
+  CLST_Rect operator-(const CFX_FloatPoint& point) const {
+    return CLST_Rect(left - point.x, top - point.y, right - point.x,
+                     bottom - point.y);
+  }
+};
+
+class CFX_ListItem final {
+ public:
+  CFX_ListItem();
+  ~CFX_ListItem();
+
+  void SetFontMap(IPVT_FontMap* pFontMap);
+  CFX_Edit* GetEdit() const;
+
+  void SetRect(const CLST_Rect& rect);
+  void SetSelect(bool bSelected);
+  void SetText(const CFX_WideString& text);
+  void SetFontSize(FX_FLOAT fFontSize);
+  CFX_WideString GetText() const;
+
+  CLST_Rect GetRect() const;
+  bool IsSelected() const;
+  FX_FLOAT GetItemHeight() const;
+  uint16_t GetFirstChar() const;
+
+ private:
+  CFX_Edit_Iterator* GetIterator() const;
+
+  std::unique_ptr<CFX_Edit> m_pEdit;
+  bool m_bSelected;
+  CLST_Rect m_rcListItem;
+};
+
+class CFX_ListContainer {
+ public:
+  CFX_ListContainer();
+  virtual ~CFX_ListContainer();
+
+  virtual void SetPlateRect(const CFX_FloatRect& rect);
+
+  CFX_FloatRect GetPlateRect() const { return m_rcPlate; }
+  void SetContentRect(const CLST_Rect& rect) { m_rcContent = rect; }
+  CLST_Rect GetContentRect() const { return m_rcContent; }
+  CFX_FloatPoint GetBTPoint() const {
+    return CFX_FloatPoint(m_rcPlate.left, m_rcPlate.top);
+  }
+  CFX_FloatPoint GetETPoint() const {
+    return CFX_FloatPoint(m_rcPlate.right, m_rcPlate.bottom);
+  }
+
+ public:
+  CFX_FloatPoint InnerToOuter(const CFX_FloatPoint& point) const {
+    return CFX_FloatPoint(point.x + GetBTPoint().x, GetBTPoint().y - point.y);
+  }
+  CFX_FloatPoint OuterToInner(const CFX_FloatPoint& point) const {
+    return CFX_FloatPoint(point.x - GetBTPoint().x, GetBTPoint().y - point.y);
+  }
+  CFX_FloatRect InnerToOuter(const CLST_Rect& rect) const {
+    CFX_FloatPoint ptLeftTop =
+        InnerToOuter(CFX_FloatPoint(rect.left, rect.top));
+    CFX_FloatPoint ptRightBottom =
+        InnerToOuter(CFX_FloatPoint(rect.right, rect.bottom));
+    return CFX_FloatRect(ptLeftTop.x, ptRightBottom.y, ptRightBottom.x,
+                         ptLeftTop.y);
+  }
+  CLST_Rect OuterToInner(const CFX_FloatRect& rect) const {
+    CFX_FloatPoint ptLeftTop =
+        OuterToInner(CFX_FloatPoint(rect.left, rect.top));
+    CFX_FloatPoint ptRightBottom =
+        OuterToInner(CFX_FloatPoint(rect.right, rect.bottom));
+    return CLST_Rect(ptLeftTop.x, ptLeftTop.y, ptRightBottom.x,
+                     ptRightBottom.y);
+  }
+
+ private:
+  CFX_FloatRect m_rcPlate;
+  CLST_Rect m_rcContent;  // positive forever!
+};
+
+template <class TYPE>
+class CLST_ArrayTemplate : public CFX_ArrayTemplate<TYPE> {
+ public:
+  bool IsEmpty() { return CFX_ArrayTemplate<TYPE>::GetSize() <= 0; }
+  TYPE GetAt(int32_t nIndex) const {
+    if (nIndex >= 0 && nIndex < CFX_ArrayTemplate<TYPE>::GetSize())
+      return CFX_ArrayTemplate<TYPE>::GetAt(nIndex);
+    return nullptr;
+  }
+  void RemoveAt(int32_t nIndex) {
+    if (nIndex >= 0 && nIndex < CFX_ArrayTemplate<TYPE>::GetSize())
+      CFX_ArrayTemplate<TYPE>::RemoveAt(nIndex);
+  }
+};
+
+struct CPLST_Select_Item {
+  CPLST_Select_Item(int32_t other_nItemIndex, int32_t other_nState) {
+    nItemIndex = other_nItemIndex;
+    nState = other_nState;
+  }
+
+  int32_t nItemIndex;
+  int32_t nState;  // 0:normal select -1:to deselect 1: to select
+};
+
+class CPLST_Select {
+ public:
+  CPLST_Select();
+  virtual ~CPLST_Select();
+
+ public:
+  void Add(int32_t nItemIndex);
+  void Add(int32_t nBeginIndex, int32_t nEndIndex);
+  void Sub(int32_t nItemIndex);
+  void Sub(int32_t nBeginIndex, int32_t nEndIndex);
+  bool IsExist(int32_t nItemIndex) const;
+  int32_t Find(int32_t nItemIndex) const;
+  int32_t GetCount() const;
+  int32_t GetItemIndex(int32_t nIndex) const;
+  int32_t GetState(int32_t nIndex) const;
+  void Done();
+  void DeselectAll();
+
+ private:
+  CFX_ArrayTemplate<CPLST_Select_Item*> m_aItems;
+};
+
+class CFX_ListCtrl : protected CFX_ListContainer {
+ public:
+  CFX_ListCtrl();
+  ~CFX_ListCtrl() override;
+
+  // CFX_ListContainer
+  void SetPlateRect(const CFX_FloatRect& rect) override;
+
+  void SetNotify(CPWL_List_Notify* pNotify);
+  void OnMouseDown(const CFX_FloatPoint& point, bool bShift, bool bCtrl);
+  void OnMouseMove(const CFX_FloatPoint& point, bool bShift, bool bCtrl);
+  void OnVK_UP(bool bShift, bool bCtrl);
+  void OnVK_DOWN(bool bShift, bool bCtrl);
+  void OnVK_LEFT(bool bShift, bool bCtrl);
+  void OnVK_RIGHT(bool bShift, bool bCtrl);
+  void OnVK_HOME(bool bShift, bool bCtrl);
+  void OnVK_END(bool bShift, bool bCtrl);
+  void OnVK(int32_t nItemIndex, bool bShift, bool bCtrl);
+  bool OnChar(uint16_t nChar, bool bShift, bool bCtrl);
+
+  void SetScrollPos(const CFX_FloatPoint& point);
+  void ScrollToListItem(int32_t nItemIndex);
+  CFX_FloatRect GetItemRect(int32_t nIndex) const;
+  int32_t GetCaret() const;
+  int32_t GetSelect() const;
+  int32_t GetTopItem() const;
+  CFX_FloatRect GetContentRect() const;
+  int32_t GetItemIndex(const CFX_FloatPoint& point) const;
+  void AddString(const CFX_WideString& str);
+  void SetTopItem(int32_t nIndex);
+  void Select(int32_t nItemIndex);
+  void SetCaret(int32_t nItemIndex);
+  void Empty();
+  void Cancel();
+  CFX_WideString GetText() const;
+
+  void SetFontMap(IPVT_FontMap* pFontMap);
+  void SetFontSize(FX_FLOAT fFontSize);
+  CFX_FloatRect GetPlateRect() const;
+  FX_FLOAT GetFontSize() const;
+  CFX_Edit* GetItemEdit(int32_t nIndex) const;
+  int32_t GetCount() const;
+  bool IsItemSelected(int32_t nIndex) const;
+  FX_FLOAT GetFirstHeight() const;
+  void SetMultipleSel(bool bMultiple);
+  bool IsMultipleSel() const;
+  bool IsValid(int32_t nItemIndex) const;
+  int32_t FindNext(int32_t nIndex, FX_WCHAR nChar) const;
+  int32_t GetFirstSelected() const;
+
+  CFX_FloatPoint InToOut(const CFX_FloatPoint& point) const;
+  CFX_FloatPoint OutToIn(const CFX_FloatPoint& point) const;
+  CFX_FloatRect InToOut(const CFX_FloatRect& rect) const;
+  CFX_FloatRect OutToIn(const CFX_FloatRect& rect) const;
+
+ private:
+  void ReArrange(int32_t nItemIndex);
+  CFX_FloatRect GetItemRectInternal(int32_t nIndex) const;
+  CFX_FloatRect GetContentRectInternal() const;
+  void SetMultipleSelect(int32_t nItemIndex, bool bSelected);
+  void SetSingleSelect(int32_t nItemIndex);
+  void InvalidateItem(int32_t nItemIndex);
+  void SelectItems();
+  bool IsItemVisible(int32_t nItemIndex) const;
+  void SetScrollInfo();
+  void SetScrollPosY(FX_FLOAT fy);
+  void AddItem(const CFX_WideString& str);
+  CFX_WideString GetItemText(int32_t nIndex) const;
+  void SetItemSelect(int32_t nItemIndex, bool bSelected);
+  int32_t GetLastSelected() const;
+  FX_WCHAR Toupper(FX_WCHAR c) const;
+
+  CPWL_List_Notify* m_pNotify;
+  bool m_bNotifyFlag;
+  CFX_FloatPoint m_ptScrollPos;
+  CPLST_Select m_aSelItems;  // for multiple
+  int32_t m_nSelItem;        // for single
+  int32_t m_nFootIndex;      // for multiple
+  bool m_bCtrlSel;           // for multiple
+  int32_t m_nCaretIndex;     // for multiple
+  CLST_ArrayTemplate<CFX_ListItem*> m_aListItems;
+  FX_FLOAT m_fFontSize;
+  IPVT_FontMap* m_pFontMap;
+  bool m_bMultiple;
+};
+
+#endif  // FPDFSDK_FXEDIT_FXET_LIST_H_
diff --git a/fpdfsdk/include/formfiller/FFL_CheckBox.h b/fpdfsdk/include/formfiller/FFL_CheckBox.h
deleted file mode 100644
index 27af16b..0000000
--- a/fpdfsdk/include/formfiller/FFL_CheckBox.h
+++ /dev/null
@@ -1,32 +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_FORMFILLER_FFL_CHECKBOX_H_
-#define FPDFSDK_INCLUDE_FORMFILLER_FFL_CHECKBOX_H_
-
-#include "FFL_FormFiller.h"
-
-class CFFL_CheckBox : public CFFL_Button {
- public:
-  CFFL_CheckBox(CPDFDoc_Environment* pApp, CPDFSDK_Widget* pWidget);
-  ~CFFL_CheckBox() override;
-
-  // CFFL_Button
-  CPWL_Wnd* NewPDFWindow(const PWL_CREATEPARAM& cp,
-                         CPDFSDK_PageView* pPageView) override;
-  FX_BOOL OnKeyDown(CPDFSDK_Annot* pAnnot,
-                    FX_UINT nKeyCode,
-                    FX_UINT nFlags) override;
-  FX_BOOL OnChar(CPDFSDK_Annot* pAnnot, FX_UINT nChar, FX_UINT nFlags) override;
-  FX_BOOL OnLButtonUp(CPDFSDK_PageView* pPageView,
-                      CPDFSDK_Annot* pAnnot,
-                      FX_UINT nFlags,
-                      const CPDF_Point& point) override;
-  FX_BOOL IsDataChanged(CPDFSDK_PageView* pPageView) override;
-  void SaveData(CPDFSDK_PageView* pPageView) override;
-};
-
-#endif  // FPDFSDK_INCLUDE_FORMFILLER_FFL_CHECKBOX_H_
diff --git a/fpdfsdk/include/formfiller/FFL_ComboBox.h b/fpdfsdk/include/formfiller/FFL_ComboBox.h
deleted file mode 100644
index 5c36779..0000000
--- a/fpdfsdk/include/formfiller/FFL_ComboBox.h
+++ /dev/null
@@ -1,70 +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_FORMFILLER_FFL_COMBOBOX_H_
-#define FPDFSDK_INCLUDE_FORMFILLER_FFL_COMBOBOX_H_
-
-#include "FFL_FormFiller.h"
-#include "core/include/fxcrt/fx_string.h"
-
-class CBA_FontMap;
-class CPDFSDK_Document;
-
-struct FFL_ComboBoxState {
-  int nIndex;
-  int nStart;
-  int nEnd;
-  CFX_WideString sValue;
-};
-
-class CFFL_ComboBox : public CFFL_FormFiller,
-                      public IPWL_FocusHandler,
-                      public IPWL_Edit_Notify {
- public:
-  CFFL_ComboBox(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pWidget);
-  ~CFFL_ComboBox() override;
-
-  // CFFL_FormFiller:
-  PWL_CREATEPARAM GetCreateParam() override;
-  CPWL_Wnd* NewPDFWindow(const PWL_CREATEPARAM& cp,
-                         CPDFSDK_PageView* pPageView) override;
-  FX_BOOL OnChar(CPDFSDK_Annot* pAnnot, FX_UINT nChar, FX_UINT nFlags) override;
-  FX_BOOL IsDataChanged(CPDFSDK_PageView* pPageView) override;
-  void SaveData(CPDFSDK_PageView* pPageView) override;
-  void GetActionData(CPDFSDK_PageView* pPageView,
-                     CPDF_AAction::AActionType type,
-                     PDFSDK_FieldAction& fa) override;
-  void SetActionData(CPDFSDK_PageView* pPageView,
-                     CPDF_AAction::AActionType type,
-                     const PDFSDK_FieldAction& fa) override;
-  FX_BOOL IsActionDataChanged(CPDF_AAction::AActionType type,
-                              const PDFSDK_FieldAction& faOld,
-                              const PDFSDK_FieldAction& faNew) override;
-  void SaveState(CPDFSDK_PageView* pPageView) override;
-  void RestoreState(CPDFSDK_PageView* pPageView) override;
-  CPWL_Wnd* ResetPDFWindow(CPDFSDK_PageView* pPageView,
-                           FX_BOOL bRestoreValue) override;
-
-  // IPWL_FocusHandler:
-  void OnSetFocus(CPWL_Wnd* pWnd) override;
-  void OnKillFocus(CPWL_Wnd* pWnd) override;
-
-  // IPWL_Edit_Notify:
-  void OnAddUndo(CPWL_Edit* pEdit) override;
-
-#ifdef PDF_ENABLE_XFA
-  // CFFL_FormFiller:
-  FX_BOOL IsFieldFull(CPDFSDK_PageView* pPageView) override;
-#endif  // PDF_ENABLE_XFA
-
- private:
-  CFX_WideString GetSelectExportText();
-
-  CBA_FontMap* m_pFontMap;
-  FFL_ComboBoxState m_State;
-};
-
-#endif  // FPDFSDK_INCLUDE_FORMFILLER_FFL_COMBOBOX_H_
diff --git a/fpdfsdk/include/formfiller/FFL_FormFiller.h b/fpdfsdk/include/formfiller/FFL_FormFiller.h
deleted file mode 100644
index cb14397..0000000
--- a/fpdfsdk/include/formfiller/FFL_FormFiller.h
+++ /dev/null
@@ -1,199 +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_FORMFILLER_FFL_FORMFILLER_H_
-#define FPDFSDK_INCLUDE_FORMFILLER_FFL_FORMFILLER_H_
-
-#include "fpdfsdk/include/formfiller/FFL_CBA_Fontmap.h"
-#include "fpdfsdk/include/formfiller/FFL_IFormFiller.h"
-#include "fpdfsdk/include/fsdk_baseform.h"
-
-class CPDFDoc_Environment;
-class CPDFSDK_Annot;
-class CPDFSDK_Document;
-class CPDFSDK_PageView;
-class CPDFSDK_Widget;
-
-class CFFL_FormFiller : public IPWL_Provider, public CPWL_TimerHandler {
- public:
-  CFFL_FormFiller(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pAnnot);
-  ~CFFL_FormFiller() override;
-
-  virtual FX_RECT GetViewBBox(CPDFSDK_PageView* pPageView,
-                              CPDFSDK_Annot* pAnnot);
-  virtual void OnDraw(CPDFSDK_PageView* pPageView,
-                      CPDFSDK_Annot* pAnnot,
-                      CFX_RenderDevice* pDevice,
-                      CFX_Matrix* pUser2Device,
-                      FX_DWORD dwFlags);
-  virtual void OnDrawDeactive(CPDFSDK_PageView* pPageView,
-                              CPDFSDK_Annot* pAnnot,
-                              CFX_RenderDevice* pDevice,
-                              CFX_Matrix* pUser2Device,
-                              FX_DWORD dwFlags);
-
-  virtual void OnCreate(CPDFSDK_Annot* pAnnot);
-  virtual void OnLoad(CPDFSDK_Annot* pAnnot);
-  virtual void OnDelete(CPDFSDK_Annot* pAnnot);
-
-  virtual void OnMouseEnter(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot);
-  virtual void OnMouseExit(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot);
-
-  virtual FX_BOOL OnLButtonDown(CPDFSDK_PageView* pPageView,
-                                CPDFSDK_Annot* pAnnot,
-                                FX_UINT nFlags,
-                                const CPDF_Point& point);
-  virtual FX_BOOL OnLButtonUp(CPDFSDK_PageView* pPageView,
-                              CPDFSDK_Annot* pAnnot,
-                              FX_UINT nFlags,
-                              const CPDF_Point& point);
-  virtual FX_BOOL OnLButtonDblClk(CPDFSDK_PageView* pPageView,
-                                  CPDFSDK_Annot* pAnnot,
-                                  FX_UINT nFlags,
-                                  const CPDF_Point& point);
-  virtual FX_BOOL OnMouseMove(CPDFSDK_PageView* pPageView,
-                              CPDFSDK_Annot* pAnnot,
-                              FX_UINT nFlags,
-                              const CPDF_Point& point);
-  virtual FX_BOOL OnMouseWheel(CPDFSDK_PageView* pPageView,
-                               CPDFSDK_Annot* pAnnot,
-                               FX_UINT nFlags,
-                               short zDelta,
-                               const CPDF_Point& point);
-  virtual FX_BOOL OnRButtonDown(CPDFSDK_PageView* pPageView,
-                                CPDFSDK_Annot* pAnnot,
-                                FX_UINT nFlags,
-                                const CPDF_Point& point);
-  virtual FX_BOOL OnRButtonUp(CPDFSDK_PageView* pPageView,
-                              CPDFSDK_Annot* pAnnot,
-                              FX_UINT nFlags,
-                              const CPDF_Point& point);
-
-  virtual FX_BOOL OnKeyDown(CPDFSDK_Annot* pAnnot,
-                            FX_UINT nKeyCode,
-                            FX_UINT nFlags);
-  virtual FX_BOOL OnChar(CPDFSDK_Annot* pAnnot, FX_UINT nChar, FX_UINT nFlags);
-
-  void SetFocusForAnnot(CPDFSDK_Annot* pAnnot, FX_UINT nFlag);
-  void KillFocusForAnnot(CPDFSDK_Annot* pAnnot, FX_UINT nFlag);
-
-  // CPWL_TimerHandler
-  void TimerProc() override;
-  IFX_SystemHandler* GetSystemHandler() const override;
-
-  // IPWL_Provider
-  CFX_Matrix GetWindowMatrix(void* pAttachedData) override;
-  CFX_WideString LoadPopupMenuString(int nIndex) override;
-
-  virtual void GetActionData(CPDFSDK_PageView* pPageView,
-                             CPDF_AAction::AActionType type,
-                             PDFSDK_FieldAction& fa);
-  virtual void SetActionData(CPDFSDK_PageView* pPageView,
-                             CPDF_AAction::AActionType type,
-                             const PDFSDK_FieldAction& fa);
-  virtual FX_BOOL IsActionDataChanged(CPDF_AAction::AActionType type,
-                                      const PDFSDK_FieldAction& faOld,
-                                      const PDFSDK_FieldAction& faNew);
-
-  virtual void SaveState(CPDFSDK_PageView* pPageView);
-  virtual void RestoreState(CPDFSDK_PageView* pPageView);
-
-  virtual CPWL_Wnd* ResetPDFWindow(CPDFSDK_PageView* pPageView,
-                                   FX_BOOL bRestoreValue);
-
-  CFX_Matrix GetCurMatrix();
-
-  CPDF_Rect FFLtoPWL(const CPDF_Rect& rect);
-  CPDF_Rect PWLtoFFL(const CPDF_Rect& rect);
-  CPDF_Point FFLtoPWL(const CPDF_Point& point);
-  CPDF_Point PWLtoFFL(const CPDF_Point& point);
-
-  CPDF_Point WndtoPWL(CPDFSDK_PageView* pPageView, const CPDF_Point& pt);
-  CPDF_Rect FFLtoWnd(CPDFSDK_PageView* pPageView, const CPDF_Rect& rect);
-
-  void SetWindowRect(CPDFSDK_PageView* pPageView, const CPDF_Rect& rcWindow);
-  CPDF_Rect GetWindowRect(CPDFSDK_PageView* pPageView);
-
-  FX_BOOL CommitData(CPDFSDK_PageView* pPageView, FX_UINT nFlag);
-  virtual FX_BOOL IsDataChanged(CPDFSDK_PageView* pPageView);
-  virtual void SaveData(CPDFSDK_PageView* pPageView);
-
-#ifdef PDF_ENABLE_XFA
-  virtual FX_BOOL IsFieldFull(CPDFSDK_PageView* pPageView);
-#endif  // PDF_ENABLE_XFA
-
-  CPWL_Wnd* GetPDFWindow(CPDFSDK_PageView* pPageView, FX_BOOL bNew);
-  void DestroyPDFWindow(CPDFSDK_PageView* pPageView);
-  void EscapeFiller(CPDFSDK_PageView* pPageView, FX_BOOL bDestroyPDFWindow);
-
-  virtual PWL_CREATEPARAM GetCreateParam();
-  virtual CPWL_Wnd* NewPDFWindow(const PWL_CREATEPARAM& cp,
-                                 CPDFSDK_PageView* pPageView) = 0;
-  virtual CPDF_Rect GetFocusBox(CPDFSDK_PageView* pPageView);
-
-  FX_BOOL IsValid() const;
-  CPDF_Rect GetPDFWindowRect() const;
-
-  CPDFSDK_PageView* GetCurPageView();
-  void SetChangeMark();
-
-  virtual void InvalidateRect(double left,
-                              double top,
-                              double right,
-                              double bottom);
-  CPDFDoc_Environment* GetApp() { return m_pApp; }
-  CPDFSDK_Annot* GetSDKAnnot() { return m_pAnnot; }
-
- protected:
-  using CFFL_PageView2PDFWindow = std::map<CPDFSDK_PageView*, CPWL_Wnd*>;
-
-  CPDFDoc_Environment* m_pApp;
-  CPDFSDK_Widget* m_pWidget;
-  CPDFSDK_Annot* m_pAnnot;
-
-  FX_BOOL m_bValid;
-  CFFL_PageView2PDFWindow m_Maps;
-  CPDF_Point m_ptOldPos;
-};
-
-class CFFL_Button : public CFFL_FormFiller {
- public:
-  CFFL_Button(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pWidget);
-  ~CFFL_Button() override;
-
-  // CFFL_FormFiller
-  void OnMouseEnter(CPDFSDK_PageView* pPageView,
-                    CPDFSDK_Annot* pAnnot) override;
-  void OnMouseExit(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot) override;
-  FX_BOOL OnLButtonDown(CPDFSDK_PageView* pPageView,
-                        CPDFSDK_Annot* pAnnot,
-                        FX_UINT nFlags,
-                        const CPDF_Point& point) override;
-  FX_BOOL OnLButtonUp(CPDFSDK_PageView* pPageView,
-                      CPDFSDK_Annot* pAnnot,
-                      FX_UINT nFlags,
-                      const CPDF_Point& point) override;
-  FX_BOOL OnMouseMove(CPDFSDK_PageView* pPageView,
-                      CPDFSDK_Annot* pAnnot,
-                      FX_UINT nFlags,
-                      const CPDF_Point& point) override;
-  void OnDraw(CPDFSDK_PageView* pPageView,
-              CPDFSDK_Annot* pAnnot,
-              CFX_RenderDevice* pDevice,
-              CFX_Matrix* pUser2Device,
-              FX_DWORD dwFlags) override;
-  void OnDrawDeactive(CPDFSDK_PageView* pPageView,
-                      CPDFSDK_Annot* pAnnot,
-                      CFX_RenderDevice* pDevice,
-                      CFX_Matrix* pUser2Device,
-                      FX_DWORD dwFlags) override;
-
- protected:
-  FX_BOOL m_bMouseIn;
-  FX_BOOL m_bMouseDown;
-};
-
-#endif  // FPDFSDK_INCLUDE_FORMFILLER_FFL_FORMFILLER_H_
diff --git a/fpdfsdk/include/formfiller/FFL_IFormFiller.h b/fpdfsdk/include/formfiller/FFL_IFormFiller.h
deleted file mode 100644
index 93e7505..0000000
--- a/fpdfsdk/include/formfiller/FFL_IFormFiller.h
+++ /dev/null
@@ -1,187 +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_FORMFILLER_FFL_IFORMFILLER_H_
-#define FPDFSDK_INCLUDE_FORMFILLER_FFL_IFORMFILLER_H_
-
-#include <map>
-
-#include "fpdfsdk/include/fsdk_define.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Edit.h"
-
-class CFFL_FormFiller;
-class CFFL_PrivateData;
-class CPDFDoc_Environment;
-class CPDFSDK_Annot;
-class CPDFSDK_PageView;
-class CPDFSDK_Widget;
-
-class CFFL_IFormFiller : public IPWL_Filler_Notify {
- public:
-  explicit CFFL_IFormFiller(CPDFDoc_Environment* pApp);
-  ~CFFL_IFormFiller() override;
-
-  virtual FX_BOOL Annot_HitTest(CPDFSDK_PageView* pPageView,
-                                CPDFSDK_Annot* pAnnot,
-                                CPDF_Point point);
-  virtual FX_RECT GetViewBBox(CPDFSDK_PageView* pPageView,
-                              CPDFSDK_Annot* pAnnot);
-  virtual void OnDraw(CPDFSDK_PageView* pPageView,
-                      CPDFSDK_Annot* pAnnot,
-                      CFX_RenderDevice* pDevice,
-                      CFX_Matrix* pUser2Device,
-                      FX_DWORD dwFlags);
-
-  virtual void OnCreate(CPDFSDK_Annot* pAnnot);
-  virtual void OnLoad(CPDFSDK_Annot* pAnnot);
-  virtual void OnDelete(CPDFSDK_Annot* pAnnot);
-
-  virtual void OnMouseEnter(CPDFSDK_PageView* pPageView,
-                            CPDFSDK_Annot* pAnnot,
-                            FX_UINT nFlag);
-  virtual void OnMouseExit(CPDFSDK_PageView* pPageView,
-                           CPDFSDK_Annot* pAnnot,
-                           FX_UINT nFlag);
-
-  virtual FX_BOOL OnLButtonDown(CPDFSDK_PageView* pPageView,
-                                CPDFSDK_Annot* pAnnot,
-                                FX_UINT nFlags,
-                                const CPDF_Point& point);
-  virtual FX_BOOL OnLButtonUp(CPDFSDK_PageView* pPageView,
-                              CPDFSDK_Annot* pAnnot,
-                              FX_UINT nFlags,
-                              const CPDF_Point& point);
-  virtual FX_BOOL OnLButtonDblClk(CPDFSDK_PageView* pPageView,
-                                  CPDFSDK_Annot* pAnnot,
-                                  FX_UINT nFlags,
-                                  const CPDF_Point& point);
-  virtual FX_BOOL OnMouseMove(CPDFSDK_PageView* pPageView,
-                              CPDFSDK_Annot* pAnnot,
-                              FX_UINT nFlags,
-                              const CPDF_Point& point);
-  virtual FX_BOOL OnMouseWheel(CPDFSDK_PageView* pPageView,
-                               CPDFSDK_Annot* pAnnot,
-                               FX_UINT nFlags,
-                               short zDelta,
-                               const CPDF_Point& point);
-  virtual FX_BOOL OnRButtonDown(CPDFSDK_PageView* pPageView,
-                                CPDFSDK_Annot* pAnnot,
-                                FX_UINT nFlags,
-                                const CPDF_Point& point);
-  virtual FX_BOOL OnRButtonUp(CPDFSDK_PageView* pPageView,
-                              CPDFSDK_Annot* pAnnot,
-                              FX_UINT nFlags,
-                              const CPDF_Point& point);
-
-  virtual FX_BOOL OnKeyDown(CPDFSDK_Annot* pAnnot,
-                            FX_UINT nKeyCode,
-                            FX_UINT nFlags);
-  virtual FX_BOOL OnChar(CPDFSDK_Annot* pAnnot, FX_UINT nChar, FX_UINT nFlags);
-
-  virtual FX_BOOL OnSetFocus(CPDFSDK_Annot* pAnnot, FX_UINT nFlag);
-  virtual FX_BOOL OnKillFocus(CPDFSDK_Annot* pAnnot, FX_UINT nFlag);
-
-  CFFL_FormFiller* GetFormFiller(CPDFSDK_Annot* pAnnot, FX_BOOL bRegister);
-  void RemoveFormFiller(CPDFSDK_Annot* pAnnot);
-
-  static FX_BOOL IsVisible(CPDFSDK_Widget* pWidget);
-  static FX_BOOL IsReadOnly(CPDFSDK_Widget* pWidget);
-  static FX_BOOL IsFillingAllowed(CPDFSDK_Widget* pWidget);
-  static FX_BOOL IsValidAnnot(CPDFSDK_PageView* pPageView,
-                              CPDFSDK_Annot* pAnnot);
-
-  void OnKeyStrokeCommit(CPDFSDK_Widget* pWidget,
-                         CPDFSDK_PageView* pPageView,
-                         FX_BOOL& bRC,
-                         FX_BOOL& bExit,
-                         FX_DWORD nFlag);
-  void OnValidate(CPDFSDK_Widget* pWidget,
-                  CPDFSDK_PageView* pPageView,
-                  FX_BOOL& bRC,
-                  FX_BOOL& bExit,
-                  FX_DWORD nFlag);
-
-  void OnCalculate(CPDFSDK_Widget* pWidget,
-                   CPDFSDK_PageView* pPageView,
-                   FX_BOOL& bExit,
-                   FX_DWORD nFlag);
-  void OnFormat(CPDFSDK_Widget* pWidget,
-                CPDFSDK_PageView* pPageView,
-                FX_BOOL& bExit,
-                FX_DWORD nFlag);
-  void OnButtonUp(CPDFSDK_Widget* pWidget,
-                  CPDFSDK_PageView* pPageView,
-                  FX_BOOL& bReset,
-                  FX_BOOL& bExit,
-                  FX_UINT nFlag);
-#ifdef PDF_ENABLE_XFA
-  void OnClick(CPDFSDK_Widget* pWidget,
-               CPDFSDK_PageView* pPageView,
-               FX_BOOL& bReset,
-               FX_BOOL& bExit,
-               FX_UINT nFlag);
-  void OnFull(CPDFSDK_Widget* pWidget,
-              CPDFSDK_PageView* pPageView,
-              FX_BOOL& bReset,
-              FX_BOOL& bExit,
-              FX_UINT nFlag);
-  void OnPreOpen(CPDFSDK_Widget* pWidget,
-                 CPDFSDK_PageView* pPageView,
-                 FX_BOOL& bReset,
-                 FX_BOOL& bExit,
-                 FX_UINT nFlag);
-  void OnPostOpen(CPDFSDK_Widget* pWidget,
-                  CPDFSDK_PageView* pPageView,
-                  FX_BOOL& bReset,
-                  FX_BOOL& bExit,
-                  FX_UINT nFlag);
-#endif  // PDF_ENABLE_XFA
-
- private:
-  using CFFL_Widget2Filler = std::map<CPDFSDK_Annot*, CFFL_FormFiller*>;
-
-  // IPWL_Filler_Notify:
-  void QueryWherePopup(void* pPrivateData,
-                       FX_FLOAT fPopupMin,
-                       FX_FLOAT fPopupMax,
-                       int32_t& nRet,
-                       FX_FLOAT& fPopupRet) override;
-  void OnBeforeKeyStroke(void* pPrivateData,
-                         CFX_WideString& strChange,
-                         const CFX_WideString& strChangeEx,
-                         int nSelStart,
-                         int nSelEnd,
-                         FX_BOOL bKeyDown,
-                         FX_BOOL& bRC,
-                         FX_BOOL& bExit,
-                         FX_DWORD nFlag) override;
-#ifdef PDF_ENABLE_XFA
-  void OnPopupPreOpen(void* pPrivateData,
-                      FX_BOOL& bExit,
-                      FX_DWORD nFlag) override;
-  void OnPopupPostOpen(void* pPrivateData,
-                       FX_BOOL& bExit,
-                       FX_DWORD nFlag) override;
-  void SetFocusAnnotTab(CPDFSDK_Annot* pWidget,
-                        FX_BOOL bSameField,
-                        FX_BOOL bNext);
-#endif  // PDF_ENABLE_XFA
-  void UnRegisterFormFiller(CPDFSDK_Annot* pAnnot);
-
-  CPDFDoc_Environment* m_pApp;
-  CFFL_Widget2Filler m_Maps;
-  FX_BOOL m_bNotifying;
-};
-
-class CFFL_PrivateData {
- public:
-  CPDFSDK_Widget* pWidget;
-  CPDFSDK_PageView* pPageView;
-  int nWidgetAge;
-  int nValueAge;
-};
-
-#endif  // FPDFSDK_INCLUDE_FORMFILLER_FFL_IFORMFILLER_H_
diff --git a/fpdfsdk/include/formfiller/FFL_PushButton.h b/fpdfsdk/include/formfiller/FFL_PushButton.h
deleted file mode 100644
index 13d6085..0000000
--- a/fpdfsdk/include/formfiller/FFL_PushButton.h
+++ /dev/null
@@ -1,28 +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_FORMFILLER_FFL_PUSHBUTTON_H_
-#define FPDFSDK_INCLUDE_FORMFILLER_FFL_PUSHBUTTON_H_
-
-#include "FFL_FormFiller.h"
-
-class CFFL_PushButton : public CFFL_Button {
- public:
-  CFFL_PushButton(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pAnnot);
-  ~CFFL_PushButton() override;
-
-  // CFFL_Button
-  CPWL_Wnd* NewPDFWindow(const PWL_CREATEPARAM& cp,
-                         CPDFSDK_PageView* pPageView) override;
-  FX_BOOL OnChar(CPDFSDK_Annot* pAnnot, FX_UINT nChar, FX_UINT nFlags) override;
-  void OnDraw(CPDFSDK_PageView* pPageView,
-              CPDFSDK_Annot* pAnnot,
-              CFX_RenderDevice* pDevice,
-              CFX_Matrix* pUser2Device,
-              FX_DWORD dwFlags) override;
-};
-
-#endif  // FPDFSDK_INCLUDE_FORMFILLER_FFL_PUSHBUTTON_H_
diff --git a/fpdfsdk/include/formfiller/FFL_RadioButton.h b/fpdfsdk/include/formfiller/FFL_RadioButton.h
deleted file mode 100644
index 3a82803..0000000
--- a/fpdfsdk/include/formfiller/FFL_RadioButton.h
+++ /dev/null
@@ -1,32 +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_FORMFILLER_FFL_RADIOBUTTON_H_
-#define FPDFSDK_INCLUDE_FORMFILLER_FFL_RADIOBUTTON_H_
-
-#include "FFL_FormFiller.h"
-
-class CFFL_RadioButton : public CFFL_Button {
- public:
-  CFFL_RadioButton(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pAnnot);
-  ~CFFL_RadioButton() override;
-
-  // CFFL_Button
-  CPWL_Wnd* NewPDFWindow(const PWL_CREATEPARAM& cp,
-                         CPDFSDK_PageView* pPageView) override;
-  FX_BOOL OnKeyDown(CPDFSDK_Annot* pAnnot,
-                    FX_UINT nKeyCode,
-                    FX_UINT nFlags) override;
-  FX_BOOL OnChar(CPDFSDK_Annot* pAnnot, FX_UINT nChar, FX_UINT nFlags) override;
-  FX_BOOL OnLButtonUp(CPDFSDK_PageView* pPageView,
-                      CPDFSDK_Annot* pAnnot,
-                      FX_UINT nFlags,
-                      const CPDF_Point& point) override;
-  FX_BOOL IsDataChanged(CPDFSDK_PageView* pPageView) override;
-  void SaveData(CPDFSDK_PageView* pPageView) override;
-};
-
-#endif  // FPDFSDK_INCLUDE_FORMFILLER_FFL_RADIOBUTTON_H_
diff --git a/fpdfsdk/include/formfiller/FFL_TextField.h b/fpdfsdk/include/formfiller/FFL_TextField.h
deleted file mode 100644
index 12ac15a..0000000
--- a/fpdfsdk/include/formfiller/FFL_TextField.h
+++ /dev/null
@@ -1,69 +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_FORMFILLER_FFL_TEXTFIELD_H_
-#define FPDFSDK_INCLUDE_FORMFILLER_FFL_TEXTFIELD_H_
-
-#include "FFL_FormFiller.h"
-
-#define BF_ALIGN_LEFT 0
-#define BF_ALIGN_MIDDLE 1
-#define BF_ALIGN_RIGHT 2
-
-class CBA_FontMap;
-
-struct FFL_TextFieldState {
-  int nStart;
-  int nEnd;
-  CFX_WideString sValue;
-};
-
-class CFFL_TextField : public CFFL_FormFiller,
-                       public IPWL_FocusHandler,
-                       public IPWL_Edit_Notify {
- public:
-  CFFL_TextField(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pAnnot);
-  ~CFFL_TextField() override;
-
-  // CFFL_FormFiller:
-  PWL_CREATEPARAM GetCreateParam() override;
-  CPWL_Wnd* NewPDFWindow(const PWL_CREATEPARAM& cp,
-                         CPDFSDK_PageView* pPageView) override;
-  FX_BOOL OnChar(CPDFSDK_Annot* pAnnot, FX_UINT nChar, FX_UINT nFlags) override;
-  FX_BOOL IsDataChanged(CPDFSDK_PageView* pPageView) override;
-  void SaveData(CPDFSDK_PageView* pPageView) override;
-  void GetActionData(CPDFSDK_PageView* pPageView,
-                     CPDF_AAction::AActionType type,
-                     PDFSDK_FieldAction& fa) override;
-  void SetActionData(CPDFSDK_PageView* pPageView,
-                     CPDF_AAction::AActionType type,
-                     const PDFSDK_FieldAction& fa) override;
-  FX_BOOL IsActionDataChanged(CPDF_AAction::AActionType type,
-                              const PDFSDK_FieldAction& faOld,
-                              const PDFSDK_FieldAction& faNew) override;
-  void SaveState(CPDFSDK_PageView* pPageView) override;
-  void RestoreState(CPDFSDK_PageView* pPageView) override;
-  CPWL_Wnd* ResetPDFWindow(CPDFSDK_PageView* pPageView,
-                           FX_BOOL bRestoreValue) override;
-
-  // IPWL_FocusHandler:
-  void OnSetFocus(CPWL_Wnd* pWnd) override;
-  void OnKillFocus(CPWL_Wnd* pWnd) override;
-
-  // IPWL_Edit_Notify:
-  void OnAddUndo(CPWL_Edit* pEdit) override;
-
-#ifdef PDF_ENABLE_XFA
-  // CFFL_FormFiller:
-  FX_BOOL IsFieldFull(CPDFSDK_PageView* pPageView) override;
-#endif  // PDF_ENABLE_XFA
-
- private:
-  CBA_FontMap* m_pFontMap;
-  FFL_TextFieldState m_State;
-};
-
-#endif  // FPDFSDK_INCLUDE_FORMFILLER_FFL_TEXTFIELD_H_
diff --git a/fpdfsdk/include/fpdfxfa/fpdfxfa_app.h b/fpdfsdk/include/fpdfxfa/fpdfxfa_app.h
deleted file mode 100644
index b25a903..0000000
--- a/fpdfsdk/include/fpdfxfa/fpdfxfa_app.h
+++ /dev/null
@@ -1,97 +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 FPDFXFA_APP_H_

-#define FPDFXFA_APP_H_

-

-#include "xfa/include/fxfa/fxfa.h"

-

-class IFXJS_Runtime;

-

-class CPDFXFA_App : public IXFA_AppProvider {

- public:

-  static CPDFXFA_App* GetInstance();

-  static void ReleaseInstance();

-

-  CPDFXFA_App();

-  ~CPDFXFA_App() override;

-

-  FX_BOOL Initialize();

-  IXFA_App* GetXFAApp() { return m_pXFAApp; }

-

-  FX_BOOL AddFormFillEnv(CPDFDoc_Environment* pEnv);

-  FX_BOOL RemoveFormFillEnv(CPDFDoc_Environment* pEnv);

-

-  FX_BOOL IsJavaScriptInitialized() const { return m_bJavaScriptInitialized; }

-  void SetJavaScriptInitialized(FX_BOOL bInitialized) {

-    m_bJavaScriptInitialized = bInitialized;

-  }

-

-  FXJSE_HRUNTIME GetJSERuntime() const { return m_hJSERuntime; }

-

-  // IFXA_AppProvider:

-  void GetAppType(CFX_WideString& wsAppType) override;

-  void SetAppType(const CFX_WideStringC& wsAppType) override;

-

-  void GetLanguage(CFX_WideString& wsLanguage) override;

-  void GetPlatform(CFX_WideString& wsPlatform) override;

-  void GetVariation(CFX_WideString& wsVariation) override;

-  void GetVersion(CFX_WideString& wsVersion) override;

-  void GetFoxitVersion(CFX_WideString& wsFoxitVersion) override {

-    wsFoxitVersion = L"7.0";

-  }

-

-  void GetAppName(CFX_WideString& wsName) override;

-  void GetFoxitAppName(CFX_WideString& wsFoxitName) override {

-    wsFoxitName = L"Foxit";

-  }

-

-  void Beep(FX_DWORD dwType) override;

-  int32_t MsgBox(const CFX_WideStringC& wsMessage,

-                 const CFX_WideStringC& wsTitle,

-                 FX_DWORD dwIconType,

-                 FX_DWORD dwButtonType) override;

-  void Response(CFX_WideString& wsAnswer,

-                const CFX_WideStringC& wsQuestion,

-                const CFX_WideStringC& wsTitle,

-                const CFX_WideStringC& wsDefaultAnswer,

-                FX_BOOL bMark) override;

-

-  int32_t GetDocumentCountInBatch() override;

-  int32_t GetCurDocumentInBatch() override;

-

-  IFX_FileRead* DownloadURL(const CFX_WideStringC& wsURL) override;

-  FX_BOOL PostRequestURL(const CFX_WideStringC& wsURL,

-                         const CFX_WideStringC& wsData,

-                         const CFX_WideStringC& wsContentType,

-                         const CFX_WideStringC& wsEncode,

-                         const CFX_WideStringC& wsHeader,

-                         CFX_WideString& wsResponse) override;

-  FX_BOOL PutRequestURL(const CFX_WideStringC& wsURL,

-                        const CFX_WideStringC& wsData,

-                        const CFX_WideStringC& wsEncode) override;

-

-  void LoadString(int32_t iStringID, CFX_WideString& wsString) override;

-  FX_BOOL ShowFileDialog(const CFX_WideStringC& wsTitle,

-                         const CFX_WideStringC& wsFilter,

-                         CFX_WideStringArray& wsPathArr,

-                         FX_BOOL bOpen) override;

-  IFWL_AdapterTimerMgr* GetTimerMgr() override;

-

-  CFX_ArrayTemplate<CPDFDoc_Environment*> m_pEnvList;

-

- protected:

-  static CPDFXFA_App* g_pApp;

-

-  FX_BOOL m_bJavaScriptInitialized;

-  IXFA_App* m_pXFAApp;

-  IXFA_FontMgr* m_pFontMgr;

-  FXJSE_HRUNTIME m_hJSERuntime;

-  IFXJS_Runtime* m_pJSRuntime;

-  CFX_WideString m_csAppType;

-};

-

-#endif  // FPDFXFA_APP_H_

diff --git a/fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h b/fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h
deleted file mode 100644
index abe22a7..0000000
--- a/fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h
+++ /dev/null
@@ -1,228 +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 FPDFXFA_DOC_H_

-#define FPDFXFA_DOC_H_

-

-#include "public/fpdfview.h"

-#include "xfa/include/fxfa/fxfa.h"

-

-class CPDFXFA_App;

-class CPDFXFA_Document;

-class CPDFXFA_Page;

-class CPDFSDK_Document;

-class CPDFDoc_Environment;

-class IJS_Runtime;

-class IJS_Context;

-class IXFA_DocHandler;

-

-class CPDFXFA_Document : public IXFA_DocProvider {

- public:

-  CPDFXFA_Document(CPDF_Document* pPDFDoc, CPDFXFA_App* pProvider);

-  ~CPDFXFA_Document();

-

-  FX_BOOL LoadXFADoc();

-  CPDFXFA_App* GetApp() { return m_pApp; }

-  CPDF_Document* GetPDFDoc() { return m_pPDFDoc; }

-  IXFA_Doc* GetXFADoc() { return m_pXFADoc; }

-  IXFA_DocView* GetXFADocView() { return m_pXFADocView; }

-

-  int GetPageCount();

-  CPDFXFA_Page* GetPage(int page_index);

-  CPDFXFA_Page* GetPage(IXFA_PageView* pPage);

-  void RemovePage(CPDFXFA_Page* page);

-  int GetDocType() { return m_iDocType; }

-

-  CPDFSDK_Document* GetSDKDocument(CPDFDoc_Environment* pFormFillEnv);

-

-  void FXRect2PDFRect(const CFX_RectF& fxRectF, CPDF_Rect& pdfRect);

-

-  virtual void SetChangeMark(IXFA_Doc* hDoc);

-  virtual FX_BOOL GetChangeMark(IXFA_Doc* hDoc);

-  // used in dynamic xfa, dwFlags refer to XFA_INVALIDATE_XXX macros.

-  virtual void InvalidateRect(IXFA_PageView* pPageView,

-                              const CFX_RectF& rt,

-                              FX_DWORD dwFlags = 0);

-  // used in static xfa, dwFlags refer to XFA_INVALIDATE_XXX macros.

-  virtual void InvalidateRect(IXFA_Widget* hWidget, FX_DWORD dwFlags = 0);

-  // show or hide caret

-  virtual void DisplayCaret(IXFA_Widget* hWidget,

-                            FX_BOOL bVisible,

-                            const CFX_RectF* pRtAnchor);

-  // dwPos: (0:bottom 1:top)

-  virtual FX_BOOL GetPopupPos(IXFA_Widget* hWidget,

-                              FX_FLOAT fMinPopup,

-                              FX_FLOAT fMaxPopup,

-                              const CFX_RectF& rtAnchor,

-                              CFX_RectF& rtPopup);

-  virtual FX_BOOL PopupMenu(IXFA_Widget* hWidget,

-                            CFX_PointF ptPopup,

-                            const CFX_RectF* pRectExclude = NULL);

-

-  // dwFlags XFA_PAGEVIEWEVENT_Added, XFA_PAGEVIEWEVENT_Removing

-  virtual void PageViewEvent(IXFA_PageView* pPageView, FX_DWORD dwFlags);

-  // dwEvent refer to XFA_WIDGETEVENT_XXX

-  virtual void WidgetEvent(IXFA_Widget* hWidget,

-                           CXFA_WidgetAcc* pWidgetData,

-                           FX_DWORD dwEvent,

-                           void* pParam = NULL,

-                           void* pAdditional = NULL);

-

-  // return true if render it.

-  virtual FX_BOOL RenderCustomWidget(IXFA_Widget* hWidget,

-                                     CFX_Graphics* pGS,

-                                     CFX_Matrix* pMatrix,

-                                     const CFX_RectF& rtUI) {

-    return FALSE;

-  }

-

-  // host method

-  virtual int32_t CountPages(IXFA_Doc* hDoc);

-  virtual int32_t GetCurrentPage(IXFA_Doc* hDoc);

-  virtual void SetCurrentPage(IXFA_Doc* hDoc, int32_t iCurPage);

-  virtual FX_BOOL IsCalculationsEnabled(IXFA_Doc* hDoc);

-  virtual void SetCalculationsEnabled(IXFA_Doc* hDoc, FX_BOOL bEnabled);

-  virtual void GetTitle(IXFA_Doc* hDoc, CFX_WideString& wsTitle);

-  virtual void SetTitle(IXFA_Doc* hDoc, const CFX_WideStringC& wsTitle);

-  virtual void ExportData(IXFA_Doc* hDoc,

-                          const CFX_WideStringC& wsFilePath,

-                          FX_BOOL bXDP = TRUE);

-  virtual void ImportData(IXFA_Doc* hDoc, const CFX_WideStringC& wsFilePath);

-  virtual void GotoURL(IXFA_Doc* hDoc,

-                       const CFX_WideStringC& bsURL,

-                       FX_BOOL bAppend = TRUE);

-  virtual FX_BOOL IsValidationsEnabled(IXFA_Doc* hDoc);

-  virtual void SetValidationsEnabled(IXFA_Doc* hDoc, FX_BOOL bEnabled);

-  virtual void SetFocusWidget(IXFA_Doc* hDoc, IXFA_Widget* hWidget);

-  virtual void Print(IXFA_Doc* hDoc,

-                     int32_t nStartPage,

-                     int32_t nEndPage,

-                     FX_DWORD dwOptions);

-

-  // LayoutPseudo method

-  virtual int32_t AbsPageCountInBatch(IXFA_Doc* hDoc) { return 0; }

-  virtual int32_t AbsPageInBatch(IXFA_Doc* hDoc, IXFA_Widget* hWidget) {

-    return 0;

-  }

-  virtual int32_t SheetCountInBatch(IXFA_Doc* hDoc) { return 0; }

-  virtual int32_t SheetInBatch(IXFA_Doc* hDoc, IXFA_Widget* hWidget) {

-    return 0;

-  }

-

-  // SignaturePseudoModel method

-  // TODO:

-  virtual int32_t Verify(

-      IXFA_Doc* hDoc,

-      CXFA_Node* pSigNode,

-      FX_BOOL

-          bUsed = TRUE /*, SecurityHandler* pHandler, SignatureInfo &info*/) {

-    return 0;

-  }

-  virtual FX_BOOL Sign(

-      IXFA_Doc* hDoc,

-      CXFA_NodeList* pNodeList,

-      const CFX_WideStringC& wsExpression,

-      const CFX_WideStringC& wsXMLIdent,

-      const CFX_WideStringC& wsValue = FX_WSTRC(L"open"),

-      FX_BOOL

-          bUsed = TRUE /*, SecurityHandler* pHandler = NULL, SignatureInfo &info*/) {

-    return 0;

-  }

-  virtual CXFA_NodeList* Enumerate(IXFA_Doc* hDoc) { return 0; }

-  virtual FX_BOOL Clear(IXFA_Doc* hDoc,

-                        CXFA_Node* pSigNode,

-                        FX_BOOL bCleared = TRUE) {

-    return 0;

-  }

-

-  // Get document path

-  virtual void GetURL(IXFA_Doc* hDoc, CFX_WideString& wsDocURL);

-  virtual FX_ARGB GetHighlightColor(IXFA_Doc* hDoc);

-  virtual void AddDoRecord(IXFA_Widget* hWidget);

-  /**

-   *Submit data to email, http, ftp.

-   * @param[in] hDoc The document handler.

-   * @param[in] eFormat Determines the format in which the data will be

-   *submitted. XFA_ATTRIBUTEENUM_Xdp, XFA_ATTRIBUTEENUM_Xml...

-   * @param[in] wsTarget The URL to which the data will be submitted.

-   * @param[in] eEncoding The encoding of text content.

-   * @param[in] pXDPContent Controls what subset of the data is submitted, used

-   *only when the format property is xdp.

-   * @param[in] bEmbedPDF, specifies whether PDF is embedded in the submitted

-   *content or not.

-   */

-  virtual FX_BOOL SubmitData(IXFA_Doc* hDoc, CXFA_Submit submit);

-

-  virtual FX_BOOL CheckWord(IXFA_Doc* hDoc, const CFX_ByteStringC& sWord) {

-    return FALSE;

-  }

-  virtual FX_BOOL GetSuggestWords(IXFA_Doc* hDoc,

-                                  const CFX_ByteStringC& sWord,

-                                  CFX_ByteStringArray& sSuggest) {

-    return FALSE;

-  }

-

-  // Get PDF javascript object, set the object to hValue.

-  virtual FX_BOOL GetPDFScriptObject(IXFA_Doc* hDoc,

-                                     const CFX_ByteStringC& utf8Name,

-                                     FXJSE_HVALUE hValue);

-

-  virtual FX_BOOL GetGlobalProperty(IXFA_Doc* hDoc,

-                                    const CFX_ByteStringC& szPropName,

-                                    FXJSE_HVALUE hValue);

-  virtual FX_BOOL SetGlobalProperty(IXFA_Doc* hDoc,

-                                    const CFX_ByteStringC& szPropName,

-                                    FXJSE_HVALUE hValue);

-  virtual CPDF_Document* OpenPDF(IXFA_Doc* hDoc,

-                                 IFX_FileRead* pFile,

-                                 FX_BOOL bTakeOverFile) {

-    return NULL;

-  }

-

-  virtual IFX_FileRead* OpenLinkedFile(IXFA_Doc* hDoc,

-                                       const CFX_WideString& wsLink);

-

-  FX_BOOL _GetHValueByName(const CFX_ByteStringC& utf8Name,

-                           FXJSE_HVALUE hValue,

-                           IJS_Runtime* runTime);

-  FX_BOOL _OnBeforeNotifySumbit();

-  void _OnAfterNotifySumbit();

-  FX_BOOL _NotifySubmit(FX_BOOL bPrevOrPost);

-  FX_BOOL _SubmitData(IXFA_Doc* hDoc, CXFA_Submit submit);

-  FX_BOOL _MailToInfo(CFX_WideString& csURL,

-                      CFX_WideString& csToAddress,

-                      CFX_WideString& csCCAddress,

-                      CFX_WideString& csBCCAddress,

-                      CFX_WideString& csSubject,

-                      CFX_WideString& csMsg);

-  FX_BOOL _ExportSubmitFile(FPDF_FILEHANDLER* ppFileHandler,

-                            int fileType,

-                            FPDF_DWORD encodeType,

-                            FPDF_DWORD flag = 0x01111111);

-  void _ToXFAContentFlags(CFX_WideString csSrcContent, FPDF_DWORD& flag);

-  void _ClearChangeMark();

-

- private:

-  void CloseXFADoc(IXFA_DocHandler* pDoc) {

-    if (pDoc) {

-      pDoc->CloseDoc(m_pXFADoc);

-      pDoc->ReleaseDoc(m_pXFADoc);

-      m_pXFADoc = NULL;

-      m_pXFADocView = NULL;

-    }

-  }

-

-  int m_iDocType;

-  CPDF_Document* m_pPDFDoc;

-  CPDFSDK_Document* m_pSDKDoc;

-  IXFA_Doc* m_pXFADoc;

-  IXFA_DocView* m_pXFADocView;

-  CPDFXFA_App* m_pApp;

-  IJS_Context* m_pJSContext;

-  CFX_ArrayTemplate<CPDFXFA_Page*> m_XFAPageList;

-};

-

-#endif  // FPDFXFA_DOC_H_

diff --git a/fpdfsdk/include/fpdfxfa/fpdfxfa_page.h b/fpdfsdk/include/fpdfxfa/fpdfxfa_page.h
deleted file mode 100644
index d88ba9f..0000000
--- a/fpdfsdk/include/fpdfxfa/fpdfxfa_page.h
+++ /dev/null
@@ -1,65 +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 _FPDFXFA_PAGEVIEW_H_

-#define _FPDFXFA_PAGEVIEW_H_

-

-class CPDFXFA_Page {

- public:

-  CPDFXFA_Page(CPDFXFA_Document* pDoc, int page_index);

-  ~CPDFXFA_Page();

-

-  void Release();

-  void AddRef() { m_iRef++; }

-  FX_BOOL LoadPage();

-  FX_BOOL LoadPDFPage(CPDF_Dictionary* pageDict);

-  CPDFXFA_Document* GetDocument() { return m_pDocument; }

-  int GetPageIndex() { return m_iPageIndex; }

-  CPDF_Page* GetPDFPage() { return m_pPDFPage; }

-  IXFA_PageView* GetXFAPageView() { return m_pXFAPageView; }

-

-  FX_FLOAT GetPageWidth();

-  FX_FLOAT GetPageHeight();

-

-  void DeviceToPage(int start_x,

-                    int start_y,

-                    int size_x,

-                    int size_y,

-                    int rotate,

-                    int device_x,

-                    int device_y,

-                    double* page_x,

-                    double* page_y);

-  void PageToDevice(int start_x,

-                    int start_y,

-                    int size_x,

-                    int size_y,

-                    int rotate,

-                    double page_x,

-                    double page_y,

-                    int* device_x,

-                    int* device_y);

-

-  void GetDisplayMatrix(CFX_Matrix& matrix,

-                        int xPos,

-                        int yPos,

-                        int xSize,

-                        int ySize,

-                        int iRotate) const;

-

- protected:

-  FX_BOOL LoadPDFPage();

-  FX_BOOL LoadXFAPageView();

-

- private:

-  CPDF_Page* m_pPDFPage;

-  IXFA_PageView* m_pXFAPageView;

-  int m_iPageIndex;

-  CPDFXFA_Document* m_pDocument;

-  int m_iRef;

-};

-

-#endif

diff --git a/fpdfsdk/include/fpdfxfa/fpdfxfa_util.h b/fpdfsdk/include/fpdfxfa/fpdfxfa_util.h
deleted file mode 100644
index a64d030..0000000
--- a/fpdfsdk/include/fpdfxfa/fpdfxfa_util.h
+++ /dev/null
@@ -1,40 +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_FPDFXFA_FPDFXFA_UTIL_H_

-#define FPDFSDK_INCLUDE_FPDFXFA_FPDFXFA_UTIL_H_

-

-#include "xfa/include/fwl/adapter/fwl_adaptertimermgr.h"

-

-#define JS_STR_VIEWERTYPE_STANDARD L"Exchange"

-#define JS_STR_LANGUANGE L"ENU"

-#define JS_STR_VIEWERVARIATION L"Full"

-#define JS_STR_VIEWERVERSION_XFA L"11"

-

-class CXFA_FWLAdapterTimerMgr : public IFWL_AdapterTimerMgr {

- public:

-  CXFA_FWLAdapterTimerMgr(CPDFDoc_Environment* pEnv) : m_pEnv(pEnv) {}

-  virtual FWL_ERR Start(IFWL_Timer* pTimer,

-                        FX_DWORD dwElapse,

-                        FWL_HTIMER& hTimer,

-                        FX_BOOL bImmediately = TRUE);

-  virtual FWL_ERR Stop(FWL_HTIMER hTimer);

-

- protected:

-  static void TimerProc(int32_t idEvent);

-

-  static CFX_PtrArray ms_timerArray;

-  CPDFDoc_Environment* m_pEnv;

-};

-

-class CFWL_TimerInfo {

- public:

-  CFWL_TimerInfo() : pTimer(nullptr) {}

-  uint32_t uIDEvent;

-  IFWL_Timer* pTimer;

-};

-

-#endif  // FPDFSDK_INCLUDE_FPDFXFA_FPDFXFA_UTIL_H_

diff --git a/fpdfsdk/include/fsdk_actionhandler.h b/fpdfsdk/include/fsdk_actionhandler.h
deleted file mode 100644
index 33f127d..0000000
--- a/fpdfsdk/include/fsdk_actionhandler.h
+++ /dev/null
@@ -1,123 +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_ACTIONHANDLER_H_
-#define FPDFSDK_INCLUDE_FSDK_ACTIONHANDLER_H_
-
-#include <memory>
-
-#include "core/include/fpdfdoc/fpdf_doc.h"
-#include "core/include/fxcrt/fx_string.h"
-#include "fsdk_baseform.h"
-
-class CFX_PtrList;
-class CPDFSDK_Annot;
-class CPDFSDK_Document;
-class CPDF_Bookmark;
-class CPDF_Dictionary;
-
-class CPDFSDK_FormActionHandler {
- public:
-  FX_BOOL DoAction_Hide(const CPDF_Action& action, CPDFSDK_Document* pDocument);
-  FX_BOOL DoAction_SubmitForm(const CPDF_Action& action,
-                              CPDFSDK_Document* pDocument);
-  FX_BOOL DoAction_ResetForm(const CPDF_Action& action,
-                             CPDFSDK_Document* pDocument);
-  FX_BOOL DoAction_ImportData(const CPDF_Action& action,
-                              CPDFSDK_Document* pDocument);
-};
-
-class CPDFSDK_ActionHandler {
- public:
-  CPDFSDK_ActionHandler();
-
-  FX_BOOL DoAction_DocOpen(const CPDF_Action& action,
-                           CPDFSDK_Document* pDocument);
-  FX_BOOL DoAction_JavaScript(const CPDF_Action& JsAction,
-                              CFX_WideString csJSName,
-                              CPDFSDK_Document* pDocument);
-  FX_BOOL DoAction_Page(const CPDF_Action& action,
-                        enum CPDF_AAction::AActionType eType,
-                        CPDFSDK_Document* pDocument);
-  FX_BOOL DoAction_Document(const CPDF_Action& action,
-                            enum CPDF_AAction::AActionType eType,
-                            CPDFSDK_Document* pDocument);
-  FX_BOOL DoAction_BookMark(CPDF_Bookmark* pBookMark,
-                            const CPDF_Action& action,
-                            CPDF_AAction::AActionType type,
-                            CPDFSDK_Document* pDocument);
-  FX_BOOL DoAction_Screen(const CPDF_Action& action,
-                          CPDF_AAction::AActionType type,
-                          CPDFSDK_Document* pDocument,
-                          CPDFSDK_Annot* pScreen);
-  FX_BOOL DoAction_Link(const CPDF_Action& action, CPDFSDK_Document* pDocument);
-  FX_BOOL DoAction_Field(const CPDF_Action& action,
-                         CPDF_AAction::AActionType type,
-                         CPDFSDK_Document* pDocument,
-                         CPDF_FormField* pFormField,
-                         PDFSDK_FieldAction& data);
-  FX_BOOL DoAction_FieldJavaScript(const CPDF_Action& JsAction,
-                                   CPDF_AAction::AActionType type,
-                                   CPDFSDK_Document* pDocument,
-                                   CPDF_FormField* pFormField,
-                                   PDFSDK_FieldAction& data);
-
- private:
-  FX_BOOL ExecuteDocumentOpenAction(const CPDF_Action& action,
-                                    CPDFSDK_Document* pDocument,
-                                    CFX_PtrList& list);
-  FX_BOOL ExecuteDocumentPageAction(const CPDF_Action& action,
-                                    CPDF_AAction::AActionType type,
-                                    CPDFSDK_Document* pDocument,
-                                    CFX_PtrList& list);
-  FX_BOOL ExecuteFieldAction(const CPDF_Action& action,
-                             CPDF_AAction::AActionType type,
-                             CPDFSDK_Document* pDocument,
-                             CPDF_FormField* pFormField,
-                             PDFSDK_FieldAction& data,
-                             CFX_PtrList& list);
-  FX_BOOL ExecuteScreenAction(const CPDF_Action& action,
-                              CPDF_AAction::AActionType type,
-                              CPDFSDK_Document* pDocument,
-                              CPDFSDK_Annot* pScreen,
-                              CFX_PtrList& list);
-  FX_BOOL ExecuteBookMark(const CPDF_Action& action,
-                          CPDFSDK_Document* pDocument,
-                          CPDF_Bookmark* pBookmark,
-                          CFX_PtrList& list);
-  FX_BOOL ExecuteLinkAction(const CPDF_Action& action,
-                            CPDFSDK_Document* pDocument,
-                            CFX_PtrList& list);
-
-  void DoAction_NoJs(const CPDF_Action& action, CPDFSDK_Document* pDocument);
-  void RunDocumentPageJavaScript(CPDFSDK_Document* pDocument,
-                                 CPDF_AAction::AActionType type,
-                                 const CFX_WideString& script);
-  void RunDocumentOpenJavaScript(CPDFSDK_Document* pDocument,
-                                 const CFX_WideString& sScriptName,
-                                 const CFX_WideString& script);
-  void RunFieldJavaScript(CPDFSDK_Document* pDocument,
-                          CPDF_FormField* pFormField,
-                          CPDF_AAction::AActionType type,
-                          PDFSDK_FieldAction& data,
-                          const CFX_WideString& script);
-
-  FX_BOOL IsValidField(CPDFSDK_Document* pDocument,
-                       CPDF_Dictionary* pFieldDict);
-  FX_BOOL IsValidDocView(CPDFSDK_Document* pDocument);
-
-  void DoAction_GoTo(CPDFSDK_Document* pDocument, const CPDF_Action& action);
-  void DoAction_GoToR(CPDFSDK_Document* pDocument, const CPDF_Action& action);
-  void DoAction_Launch(CPDFSDK_Document* pDocument, const CPDF_Action& action);
-  void DoAction_URI(CPDFSDK_Document* pDocument, const CPDF_Action& action);
-  void DoAction_Named(CPDFSDK_Document* pDocument, const CPDF_Action& action);
-  void DoAction_SetOCGState(CPDFSDK_Document* pDocument,
-                            const CPDF_Action& action);
-
-  std::unique_ptr<CPDFSDK_FormActionHandler> m_pFormActionHandler;
-};
-
-#endif  // FPDFSDK_INCLUDE_FSDK_ACTIONHANDLER_H_
diff --git a/fpdfsdk/include/fsdk_annothandler.h b/fpdfsdk/include/fsdk_annothandler.h
deleted file mode 100644
index 95b11d1..0000000
--- a/fpdfsdk/include/fsdk_annothandler.h
+++ /dev/null
@@ -1,469 +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_ANNOTHANDLER_H_
-#define FPDFSDK_INCLUDE_FSDK_ANNOTHANDLER_H_
-
-#include <map>
-#include <vector>
-
-#include "core/include/fxcrt/fx_basic.h"
-
-#ifdef PDF_ENABLE_XFA
-#define FSDK_XFAWIDGET_TYPENAME "XFAWidget"
-#endif  // PDF_ENABLE_XFA
-
-class CFFL_IFormFiller;
-class CFX_RenderDevice;
-class CPDFDoc_Environment;
-class CPDFSDK_Annot;
-class CPDFSDK_PageView;
-class CPDF_Annot;
-class CFX_Matrix;
-class CPDF_Point;
-
-class IPDFSDK_AnnotHandler {
- public:
-  virtual ~IPDFSDK_AnnotHandler() {}
-
-  virtual CFX_ByteString GetType() = 0;
-
-  virtual CFX_ByteString GetName() = 0;
-
-  virtual FX_BOOL CanAnswer(CPDFSDK_Annot* pAnnot) = 0;
-
-  virtual CPDFSDK_Annot* NewAnnot(CPDF_Annot* pAnnot,
-                                  CPDFSDK_PageView* pPage) = 0;
-
-#ifdef PDF_ENABLE_XFA
-  virtual CPDFSDK_Annot* NewAnnot(IXFA_Widget* hWidget,
-                                  CPDFSDK_PageView* pPage) = 0;
-#endif  // PDF_ENABLE_XFA
-
-  virtual void ReleaseAnnot(CPDFSDK_Annot* pAnnot) = 0;
-
-  virtual void DeleteAnnot(CPDFSDK_Annot* pAnnot) = 0;
-
-  virtual CPDF_Rect GetViewBBox(CPDFSDK_PageView* pPageView,
-                                CPDFSDK_Annot* pAnnot) = 0;
-
-  virtual FX_BOOL HitTest(CPDFSDK_PageView* pPageView,
-                          CPDFSDK_Annot* pAnnot,
-                          const CPDF_Point& point) = 0;
-
-  virtual void OnDraw(CPDFSDK_PageView* pPageView,
-                      CPDFSDK_Annot* pAnnot,
-                      CFX_RenderDevice* pDevice,
-                      CFX_Matrix* pUser2Device,
-                      FX_DWORD dwFlags) = 0;
-
-  virtual void OnDrawSleep(CPDFSDK_PageView* pPageView,
-                           CPDFSDK_Annot* pAnnot,
-                           CFX_RenderDevice* pDevice,
-                           CFX_Matrix* pUser2Device,
-                           const CPDF_Rect& rcWindow,
-                           FX_DWORD dwFlags) = 0;
-
-  virtual void OnCreate(CPDFSDK_Annot* pAnnot) = 0;
-
-  virtual void OnLoad(CPDFSDK_Annot* pAnnot) = 0;
-
-  virtual void OnDelete(CPDFSDK_Annot* pAnnot) = 0;
-
-  virtual void OnRelease(CPDFSDK_Annot* pAnnot) = 0;
-
-  virtual void OnMouseEnter(CPDFSDK_PageView* pPageView,
-                            CPDFSDK_Annot* pAnnot,
-                            FX_DWORD nFlag) = 0;
-  virtual void OnMouseExit(CPDFSDK_PageView* pPageView,
-                           CPDFSDK_Annot* pAnnot,
-                           FX_DWORD nFlag) = 0;
-
-  virtual FX_BOOL OnLButtonDown(CPDFSDK_PageView* pPageView,
-                                CPDFSDK_Annot* pAnnot,
-                                FX_DWORD nFlags,
-                                const CPDF_Point& point) = 0;
-  virtual FX_BOOL OnLButtonUp(CPDFSDK_PageView* pPageView,
-                              CPDFSDK_Annot* pAnnot,
-                              FX_DWORD nFlags,
-                              const CPDF_Point& point) = 0;
-  virtual FX_BOOL OnLButtonDblClk(CPDFSDK_PageView* pPageView,
-                                  CPDFSDK_Annot* pAnnot,
-                                  FX_DWORD nFlags,
-                                  const CPDF_Point& point) = 0;
-  virtual FX_BOOL OnMouseMove(CPDFSDK_PageView* pPageView,
-                              CPDFSDK_Annot* pAnnot,
-                              FX_DWORD nFlags,
-                              const CPDF_Point& point) = 0;
-  virtual FX_BOOL OnMouseWheel(CPDFSDK_PageView* pPageView,
-                               CPDFSDK_Annot* pAnnot,
-                               FX_DWORD nFlags,
-                               short zDelta,
-                               const CPDF_Point& point) = 0;
-  virtual FX_BOOL OnRButtonDown(CPDFSDK_PageView* pPageView,
-                                CPDFSDK_Annot* pAnnot,
-                                FX_DWORD nFlags,
-                                const CPDF_Point& point) = 0;
-  virtual FX_BOOL OnRButtonUp(CPDFSDK_PageView* pPageView,
-                              CPDFSDK_Annot* pAnnot,
-                              FX_DWORD nFlags,
-                              const CPDF_Point& point) = 0;
-  virtual FX_BOOL OnRButtonDblClk(CPDFSDK_PageView* pPageView,
-                                  CPDFSDK_Annot* pAnnot,
-                                  FX_DWORD nFlags,
-                                  const CPDF_Point& point) = 0;
-  // by wjm.
-  virtual FX_BOOL OnChar(CPDFSDK_Annot* pAnnot,
-                         FX_DWORD nChar,
-                         FX_DWORD nFlags) = 0;
-  virtual FX_BOOL OnKeyDown(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag) = 0;
-  virtual FX_BOOL OnKeyUp(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag) = 0;
-
-  virtual void OnDeSelected(CPDFSDK_Annot* pAnnot) = 0;
-  virtual void OnSelected(CPDFSDK_Annot* pAnnot) = 0;
-
-  virtual FX_BOOL OnSetFocus(CPDFSDK_Annot* pAnnot, FX_DWORD nFlag) = 0;
-  virtual FX_BOOL OnKillFocus(CPDFSDK_Annot* pAnnot, FX_DWORD nFlag) = 0;
-#ifdef PDF_ENABLE_XFA
-  virtual FX_BOOL OnXFAChangedFocus(CPDFSDK_Annot* pOldAnnot,
-                                    CPDFSDK_Annot* pNewAnnot) = 0;
-#endif  // PDF_ENABLE_XFA
-};
-
-class CPDFSDK_BFAnnotHandler : public IPDFSDK_AnnotHandler {
- public:
-  explicit CPDFSDK_BFAnnotHandler(CPDFDoc_Environment* pApp)
-      : m_pApp(pApp), m_pFormFiller(NULL) {}
-  ~CPDFSDK_BFAnnotHandler() override {}
-
-  // IPDFSDK_AnnotHandler
-  CFX_ByteString GetType() override { return CFX_ByteString("Widget"); }
-  CFX_ByteString GetName() override { return CFX_ByteString("WidgetHandler"); }
-  FX_BOOL CanAnswer(CPDFSDK_Annot* pAnnot) override;
-  CPDFSDK_Annot* NewAnnot(CPDF_Annot* pAnnot, CPDFSDK_PageView* pPage) override;
-#ifdef PDF_ENABLE_XFA
-  CPDFSDK_Annot* NewAnnot(IXFA_Widget* hWidget,
-                          CPDFSDK_PageView* pPage) override;
-#endif  // PDF_ENABLE_XFA
-  void ReleaseAnnot(CPDFSDK_Annot* pAnnot) override;
-  void DeleteAnnot(CPDFSDK_Annot* pAnnot) override {}
-  CPDF_Rect GetViewBBox(CPDFSDK_PageView* pPageView,
-                        CPDFSDK_Annot* pAnnot) override;
-  FX_BOOL HitTest(CPDFSDK_PageView* pPageView,
-                  CPDFSDK_Annot* pAnnot,
-                  const CPDF_Point& point) override;
-  void OnDraw(CPDFSDK_PageView* pPageView,
-              CPDFSDK_Annot* pAnnot,
-              CFX_RenderDevice* pDevice,
-              CFX_Matrix* pUser2Device,
-              FX_DWORD dwFlags) override;
-  void OnDrawSleep(CPDFSDK_PageView* pPageView,
-                   CPDFSDK_Annot* pAnnot,
-                   CFX_RenderDevice* pDevice,
-                   CFX_Matrix* pUser2Device,
-                   const CPDF_Rect& rcWindow,
-                   FX_DWORD dwFlags) override {}
-  void OnCreate(CPDFSDK_Annot* pAnnot) override;
-  void OnLoad(CPDFSDK_Annot* pAnnot) override;
-  void OnDelete(CPDFSDK_Annot* pAnnot) override {}
-  void OnRelease(CPDFSDK_Annot* pAnnot) override {}
-  void OnMouseEnter(CPDFSDK_PageView* pPageView,
-                    CPDFSDK_Annot* pAnnot,
-                    FX_DWORD nFlag) override;
-  void OnMouseExit(CPDFSDK_PageView* pPageView,
-                   CPDFSDK_Annot* pAnnot,
-                   FX_DWORD nFlag) override;
-  FX_BOOL OnLButtonDown(CPDFSDK_PageView* pPageView,
-                        CPDFSDK_Annot* pAnnot,
-                        FX_DWORD nFlags,
-                        const CPDF_Point& point) override;
-  FX_BOOL OnLButtonUp(CPDFSDK_PageView* pPageView,
-                      CPDFSDK_Annot* pAnnot,
-                      FX_DWORD nFlags,
-                      const CPDF_Point& point) override;
-  FX_BOOL OnLButtonDblClk(CPDFSDK_PageView* pPageView,
-                          CPDFSDK_Annot* pAnnot,
-                          FX_DWORD nFlags,
-                          const CPDF_Point& point) override;
-  FX_BOOL OnMouseMove(CPDFSDK_PageView* pPageView,
-                      CPDFSDK_Annot* pAnnot,
-                      FX_DWORD nFlags,
-                      const CPDF_Point& point) override;
-  FX_BOOL OnMouseWheel(CPDFSDK_PageView* pPageView,
-                       CPDFSDK_Annot* pAnnot,
-                       FX_DWORD nFlags,
-                       short zDelta,
-                       const CPDF_Point& point) override;
-  FX_BOOL OnRButtonDown(CPDFSDK_PageView* pPageView,
-                        CPDFSDK_Annot* pAnnot,
-                        FX_DWORD nFlags,
-                        const CPDF_Point& point) override;
-  FX_BOOL OnRButtonUp(CPDFSDK_PageView* pPageView,
-                      CPDFSDK_Annot* pAnnot,
-                      FX_DWORD nFlags,
-                      const CPDF_Point& point) override;
-  FX_BOOL OnRButtonDblClk(CPDFSDK_PageView* pPageView,
-                          CPDFSDK_Annot* pAnnot,
-                          FX_DWORD nFlags,
-                          const CPDF_Point& point) override {
-    return FALSE;
-  }
-  FX_BOOL OnChar(CPDFSDK_Annot* pAnnot,
-                 FX_DWORD nChar,
-                 FX_DWORD nFlags) override;
-  FX_BOOL OnKeyDown(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag) override;
-  FX_BOOL OnKeyUp(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag) override;
-  void OnDeSelected(CPDFSDK_Annot* pAnnot) override {}
-  void OnSelected(CPDFSDK_Annot* pAnnot) override {}
-  FX_BOOL OnSetFocus(CPDFSDK_Annot* pAnnot, FX_DWORD nFlag) override;
-  FX_BOOL OnKillFocus(CPDFSDK_Annot* pAnnot, FX_DWORD nFlag) override;
-#ifdef PDF_ENABLE_XFA
-  FX_BOOL OnXFAChangedFocus(CPDFSDK_Annot* pOldAnnot,
-                            CPDFSDK_Annot* pNewAnnot) override {
-    return TRUE;
-  }
-#endif  // PDF_ENABLE_XFA
-
-  void SetFormFiller(CFFL_IFormFiller* pFiller) { m_pFormFiller = pFiller; }
-  CFFL_IFormFiller* GetFormFiller() { return m_pFormFiller; }
-
- private:
-  CPDFDoc_Environment* m_pApp;
-  CFFL_IFormFiller* m_pFormFiller;
-};
-
-#ifdef PDF_ENABLE_XFA
-class CPDFSDK_XFAAnnotHandler : public IPDFSDK_AnnotHandler {
- public:
-  explicit CPDFSDK_XFAAnnotHandler(CPDFDoc_Environment* pApp);
-  ~CPDFSDK_XFAAnnotHandler() {}
-
- public:
-  virtual CFX_ByteString GetType() { return FSDK_XFAWIDGET_TYPENAME; }
-
-  virtual CFX_ByteString GetName() { return "XFAWidgetHandler"; }
-
-  virtual FX_BOOL CanAnswer(CPDFSDK_Annot* pAnnot);
-
-  virtual CPDFSDK_Annot* NewAnnot(CPDF_Annot* pAnnot, CPDFSDK_PageView* pPage) {
-    return NULL;
-  }
-
-  virtual CPDFSDK_Annot* NewAnnot(IXFA_Widget* pAnnot, CPDFSDK_PageView* pPage);
-
-  virtual void ReleaseAnnot(CPDFSDK_Annot* pAnnot);
-
-  virtual void DeleteAnnot(CPDFSDK_Annot* pAnnot) {}
-
-  virtual CPDF_Rect GetViewBBox(CPDFSDK_PageView* pPageView,
-                                CPDFSDK_Annot* pAnnot);
-
-  virtual FX_BOOL HitTest(CPDFSDK_PageView* pPageView,
-                          CPDFSDK_Annot* pAnnot,
-                          const CPDF_Point& point);
-
-  virtual void OnDraw(CPDFSDK_PageView* pPageView,
-                      CPDFSDK_Annot* pAnnot,
-                      CFX_RenderDevice* pDevice,
-                      CFX_Matrix* pUser2Device,
-                      FX_DWORD dwFlags);
-
-  virtual void OnDrawSleep(CPDFSDK_PageView* pPageView,
-                           CPDFSDK_Annot* pAnnot,
-                           CFX_RenderDevice* pDevice,
-                           CFX_Matrix* pUser2Device,
-                           const CPDF_Rect& rcWindow,
-                           FX_DWORD dwFlags) {}
-
-  virtual void OnCreate(CPDFSDK_Annot* pAnnot) {}
-
-  virtual void OnLoad(CPDFSDK_Annot* pAnnot) {}
-
-  virtual void OnDelete(CPDFSDK_Annot* pAnnot) {}
-
-  virtual void OnRelease(CPDFSDK_Annot* pAnnot) {}
-
-  virtual void OnMouseEnter(CPDFSDK_PageView* pPageView,
-                            CPDFSDK_Annot* pAnnot,
-                            FX_DWORD nFlag);
-  virtual void OnMouseExit(CPDFSDK_PageView* pPageView,
-                           CPDFSDK_Annot* pAnnot,
-                           FX_DWORD nFlag);
-
-  virtual FX_BOOL OnLButtonDown(CPDFSDK_PageView* pPageView,
-                                CPDFSDK_Annot* pAnnot,
-                                FX_DWORD nFlags,
-                                const CPDF_Point& point);
-  virtual FX_BOOL OnLButtonUp(CPDFSDK_PageView* pPageView,
-                              CPDFSDK_Annot* pAnnot,
-                              FX_DWORD nFlags,
-                              const CPDF_Point& point);
-  virtual FX_BOOL OnLButtonDblClk(CPDFSDK_PageView* pPageView,
-                                  CPDFSDK_Annot* pAnnot,
-                                  FX_DWORD nFlags,
-                                  const CPDF_Point& point);
-  virtual FX_BOOL OnMouseMove(CPDFSDK_PageView* pPageView,
-                              CPDFSDK_Annot* pAnnot,
-                              FX_DWORD nFlags,
-                              const CPDF_Point& point);
-  virtual FX_BOOL OnMouseWheel(CPDFSDK_PageView* pPageView,
-                               CPDFSDK_Annot* pAnnot,
-                               FX_DWORD nFlags,
-                               short zDelta,
-                               const CPDF_Point& point);
-  virtual FX_BOOL OnRButtonDown(CPDFSDK_PageView* pPageView,
-                                CPDFSDK_Annot* pAnnot,
-                                FX_DWORD nFlags,
-                                const CPDF_Point& point);
-  virtual FX_BOOL OnRButtonUp(CPDFSDK_PageView* pPageView,
-                              CPDFSDK_Annot* pAnnot,
-                              FX_DWORD nFlags,
-                              const CPDF_Point& point);
-  virtual FX_BOOL OnRButtonDblClk(CPDFSDK_PageView* pPageView,
-                                  CPDFSDK_Annot* pAnnot,
-                                  FX_DWORD nFlags,
-                                  const CPDF_Point& point);
-  // by wjm.
-  virtual FX_BOOL OnChar(CPDFSDK_Annot* pAnnot,
-                         FX_DWORD nChar,
-                         FX_DWORD nFlags);
-  virtual FX_BOOL OnKeyDown(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag);
-  virtual FX_BOOL OnKeyUp(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag);
-
-  virtual void OnDeSelected(CPDFSDK_Annot* pAnnot) {}
-  virtual void OnSelected(CPDFSDK_Annot* pAnnot) {}
-
-  virtual FX_BOOL OnSetFocus(CPDFSDK_Annot* pAnnot, FX_DWORD nFlag);
-  virtual FX_BOOL OnKillFocus(CPDFSDK_Annot* pAnnot, FX_DWORD nFlag);
-  virtual FX_BOOL OnXFAChangedFocus(CPDFSDK_Annot* pOldAnnot,
-                                    CPDFSDK_Annot* pNewAnnot);
-
- private:
-  IXFA_WidgetHandler* GetXFAWidgetHandler(CPDFSDK_Annot* pAnnot);
-  FX_DWORD GetFWLFlags(FX_DWORD dwFlag);
-
- private:
-  CPDFDoc_Environment* m_pApp;
-};
-#endif  // PDF_ENABLE_XFA
-
-#define CBA_AnnotHandlerArray CFX_ArrayTemplate<IPDFSDK_AnnotHandler*>
-class CPDFSDK_AnnotHandlerMgr {
- public:
-  // Destroy the handler
-  explicit CPDFSDK_AnnotHandlerMgr(CPDFDoc_Environment* pApp);
-  virtual ~CPDFSDK_AnnotHandlerMgr();
-
- public:
-  void RegisterAnnotHandler(IPDFSDK_AnnotHandler* pAnnotHandler);
-  void UnRegisterAnnotHandler(IPDFSDK_AnnotHandler* pAnnotHandler);
-
-  virtual CPDFSDK_Annot* NewAnnot(CPDF_Annot* pAnnot,
-                                  CPDFSDK_PageView* pPageView);
-#ifdef PDF_ENABLE_XFA
-  virtual CPDFSDK_Annot* NewAnnot(IXFA_Widget* pAnnot,
-                                  CPDFSDK_PageView* pPageView);
-#endif  // PDF_ENABLE_XFA
-  virtual void ReleaseAnnot(CPDFSDK_Annot* pAnnot);
-
-  virtual void Annot_OnCreate(CPDFSDK_Annot* pAnnot);
-  virtual void Annot_OnLoad(CPDFSDK_Annot* pAnnot);
-
- public:
-  IPDFSDK_AnnotHandler* GetAnnotHandler(CPDFSDK_Annot* pAnnot) const;
-  virtual void Annot_OnDraw(CPDFSDK_PageView* pPageView,
-                            CPDFSDK_Annot* pAnnot,
-                            CFX_RenderDevice* pDevice,
-                            CFX_Matrix* pUser2Device,
-                            FX_DWORD dwFlags);
-
-  virtual void Annot_OnMouseEnter(CPDFSDK_PageView* pPageView,
-                                  CPDFSDK_Annot* pAnnot,
-                                  FX_DWORD nFlags);
-  virtual void Annot_OnMouseExit(CPDFSDK_PageView* pPageView,
-                                 CPDFSDK_Annot* pAnnot,
-                                 FX_DWORD nFlags);
-
-  virtual FX_BOOL Annot_OnLButtonDown(CPDFSDK_PageView* pPageView,
-                                      CPDFSDK_Annot* pAnnot,
-                                      FX_DWORD nFlags,
-                                      const CPDF_Point& point);
-  virtual FX_BOOL Annot_OnLButtonUp(CPDFSDK_PageView* pPageView,
-                                    CPDFSDK_Annot* pAnnot,
-                                    FX_DWORD nFlags,
-                                    const CPDF_Point& point);
-  virtual FX_BOOL Annot_OnLButtonDblClk(CPDFSDK_PageView* pPageView,
-                                        CPDFSDK_Annot* pAnnot,
-                                        FX_DWORD nFlags,
-                                        const CPDF_Point& point);
-
-  virtual FX_BOOL Annot_OnMouseMove(CPDFSDK_PageView* pPageView,
-                                    CPDFSDK_Annot* pAnnot,
-                                    FX_DWORD nFlags,
-                                    const CPDF_Point& point);
-  virtual FX_BOOL Annot_OnMouseWheel(CPDFSDK_PageView* pPageView,
-                                     CPDFSDK_Annot* pAnnot,
-                                     FX_DWORD nFlags,
-                                     short zDelta,
-                                     const CPDF_Point& point);
-  virtual FX_BOOL Annot_OnRButtonDown(CPDFSDK_PageView* pPageView,
-                                      CPDFSDK_Annot* pAnnot,
-                                      FX_DWORD nFlags,
-                                      const CPDF_Point& point);
-  virtual FX_BOOL Annot_OnRButtonUp(CPDFSDK_PageView* pPageView,
-                                    CPDFSDK_Annot* pAnnot,
-                                    FX_DWORD nFlags,
-                                    const CPDF_Point& point);
-
-  virtual FX_BOOL Annot_OnChar(CPDFSDK_Annot* pAnnot,
-                               FX_DWORD nChar,
-                               FX_DWORD nFlags);
-  virtual FX_BOOL Annot_OnKeyDown(CPDFSDK_Annot* pAnnot,
-                                  int nKeyCode,
-                                  int nFlag);
-  virtual FX_BOOL Annot_OnKeyUp(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag);
-
-  virtual FX_BOOL Annot_OnSetFocus(CPDFSDK_Annot* pAnnot, FX_DWORD nFlag);
-  virtual FX_BOOL Annot_OnKillFocus(CPDFSDK_Annot* pAnnot, FX_DWORD nFlag);
-
-#ifdef PDF_ENABLE_XFA
-  virtual FX_BOOL Annot_OnChangeFocus(CPDFSDK_Annot* pSetAnnot,
-                                      CPDFSDK_Annot* pKillAnnot);
-#endif  // PDF_ENABLE_XFA
-
-  virtual CPDF_Rect Annot_OnGetViewBBox(CPDFSDK_PageView* pPageView,
-                                        CPDFSDK_Annot* pAnnot);
-  virtual FX_BOOL Annot_OnHitTest(CPDFSDK_PageView* pPageView,
-                                  CPDFSDK_Annot* pAnnot,
-                                  const CPDF_Point& point);
-
- private:
-  IPDFSDK_AnnotHandler* GetAnnotHandler(const CFX_ByteString& sType) const;
-  CPDFSDK_Annot* GetNextAnnot(CPDFSDK_Annot* pSDKAnnot, FX_BOOL bNext);
-
- private:
-  CBA_AnnotHandlerArray m_Handlers;
-  std::map<CFX_ByteString, IPDFSDK_AnnotHandler*> m_mapType2Handler;
-  CPDFDoc_Environment* m_pApp;
-};
-
-class CPDFSDK_AnnotIterator {
- public:
-  CPDFSDK_AnnotIterator(CPDFSDK_PageView* pPageView, bool bReverse);
-  ~CPDFSDK_AnnotIterator();
-
-  CPDFSDK_Annot* Next();
-
- private:
-  CPDFSDK_Annot* NextAnnot();
-  CPDFSDK_Annot* PrevAnnot();
-
-  std::vector<CPDFSDK_Annot*> m_iteratorAnnotList;
-  const bool m_bReverse;
-  size_t m_pos;
-};
-
-#endif  // FPDFSDK_INCLUDE_FSDK_ANNOTHANDLER_H_
diff --git a/fpdfsdk/include/fsdk_baseannot.h b/fpdfsdk/include/fsdk_baseannot.h
deleted file mode 100644
index 49c25de..0000000
--- a/fpdfsdk/include/fsdk_baseannot.h
+++ /dev/null
@@ -1,222 +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_BASEANNOT_H_
-#define FPDFSDK_INCLUDE_FSDK_BASEANNOT_H_
-
-#if _FX_OS_ == _FX_ANDROID_
-#include "time.h"
-#else
-#include <ctime>
-#endif
-
-#include "core/include/fpdfdoc/fpdf_doc.h"
-#include "core/include/fxcrt/fx_basic.h"
-#include "fpdfsdk/include/fsdk_define.h"
-#include "fpdfsdk/include/fx_systemhandler.h"
-
-class CPDFSDK_PageView;
-class CPDF_Annot;
-class CPDF_Page;
-class CFX_Matrix;
-class CPDF_RenderOptions;
-class CFX_RenderDevice;
-
-#define CFX_IntArray CFX_ArrayTemplate<int>
-
-class CPDFSDK_DateTime {
- public:
-  CPDFSDK_DateTime();
-  CPDFSDK_DateTime(const CFX_ByteString& dtStr);
-  CPDFSDK_DateTime(const CPDFSDK_DateTime& datetime);
-  CPDFSDK_DateTime(const FX_SYSTEMTIME& st);
-
-  CPDFSDK_DateTime& operator=(const CPDFSDK_DateTime& datetime);
-  CPDFSDK_DateTime& operator=(const FX_SYSTEMTIME& st);
-  FX_BOOL operator==(CPDFSDK_DateTime& datetime);
-  FX_BOOL operator!=(CPDFSDK_DateTime& datetime);
-  FX_BOOL operator>(CPDFSDK_DateTime& datetime);
-  FX_BOOL operator>=(CPDFSDK_DateTime& datetime);
-  FX_BOOL operator<(CPDFSDK_DateTime& datetime);
-  FX_BOOL operator<=(CPDFSDK_DateTime& datetime);
-  operator time_t();
-
-  CPDFSDK_DateTime& FromPDFDateTimeString(const CFX_ByteString& dtStr);
-  CFX_ByteString ToCommonDateTimeString();
-  CFX_ByteString ToPDFDateTimeString();
-  void ToSystemTime(FX_SYSTEMTIME& st);
-  CPDFSDK_DateTime ToGMT();
-  CPDFSDK_DateTime& AddDays(short days);
-  CPDFSDK_DateTime& AddSeconds(int seconds);
-
-  void ResetDateTime();
-
-  struct FX_DATETIME {
-    int16_t year;
-    uint8_t month;
-    uint8_t day;
-    uint8_t hour;
-    uint8_t minute;
-    uint8_t second;
-    int8_t tzHour;
-    uint8_t tzMinute;
-  } dt;
-};
-
-class CPDFSDK_Annot {
- public:
-  explicit CPDFSDK_Annot(CPDFSDK_PageView* pPageView);
-  virtual ~CPDFSDK_Annot() {}
-
-#ifdef PDF_ENABLE_XFA
-  virtual FX_BOOL IsXFAField() { return FALSE; }
-#endif  // PDF_ENABLE_XFA
-
-  virtual FX_FLOAT GetMinWidth() const;
-  virtual FX_FLOAT GetMinHeight() const;
-  // define layout order to 5.
-  virtual int GetLayoutOrder() const { return 5; }
-
-  virtual CPDF_Annot* GetPDFAnnot() const { return nullptr; }
-
-#ifdef PDF_ENABLE_XFA
-  virtual IXFA_Widget* GetXFAWidget() const { return nullptr; }
-#endif  // PDF_ENABLE_XFA
-
-  virtual CFX_ByteString GetType() const { return ""; }
-  virtual CFX_ByteString GetSubType() const { return ""; }
-
-  virtual void SetRect(const CPDF_Rect& rect) {}
-  virtual CPDF_Rect GetRect() const { return CPDF_Rect(); }
-
-  virtual void Annot_OnDraw(CFX_RenderDevice* pDevice,
-                            CFX_Matrix* pUser2Device,
-                            CPDF_RenderOptions* pOptions) {}
-
-  UnderlyingPageType* GetUnderlyingPage();
-  CPDF_Page* GetPDFPage();
-#ifdef PDF_ENABLE_XFA
-  CPDFXFA_Page* GetPDFXFAPage();
-#endif  // PDF_ENABLE_XFA
-
-  void SetPage(CPDFSDK_PageView* pPageView) { m_pPageView = pPageView; }
-  CPDFSDK_PageView* GetPageView() const { return m_pPageView; }
-
-  // Tab Order
-  int GetTabOrder();
-  void SetTabOrder(int iTabOrder);
-
-  // Selection
-  FX_BOOL IsSelected();
-  void SetSelected(FX_BOOL bSelected);
-
- protected:
-  CPDFSDK_PageView* m_pPageView;
-  FX_BOOL m_bSelected;
-  int m_nTabOrder;
-};
-
-class CPDFSDK_BAAnnot : public CPDFSDK_Annot {
- public:
-  CPDFSDK_BAAnnot(CPDF_Annot* pAnnot, CPDFSDK_PageView* pPageView);
-  ~CPDFSDK_BAAnnot() override {}
-
-#ifdef PDF_ENABLE_XFA
-  FX_BOOL IsXFAField() override;
-#endif  // PDF_ENABLE_XFA
-
-  CFX_ByteString GetType() const override;
-  CFX_ByteString GetSubType() const override;
-  void SetRect(const CPDF_Rect& rect) override;
-  CPDF_Rect GetRect() const override;
-  CPDF_Annot* GetPDFAnnot() const override;
-  void Annot_OnDraw(CFX_RenderDevice* pDevice,
-                    CFX_Matrix* pUser2Device,
-                    CPDF_RenderOptions* pOptions) override;
-
-  CPDF_Dictionary* GetAnnotDict() const;
-
-  void SetContents(const CFX_WideString& sContents);
-  CFX_WideString GetContents() const;
-
-  void SetAnnotName(const CFX_WideString& sName);
-  CFX_WideString GetAnnotName() const;
-
-  void SetModifiedDate(const FX_SYSTEMTIME& st);
-  FX_SYSTEMTIME GetModifiedDate() const;
-
-  void SetFlags(int nFlags);
-  int GetFlags() const;
-
-  void SetAppState(const CFX_ByteString& str);
-  CFX_ByteString GetAppState() const;
-
-  void SetStructParent(int key);
-  int GetStructParent() const;
-
-  // border
-  void SetBorderWidth(int nWidth);
-  int GetBorderWidth() const;
-
-  // BBS_SOLID
-  // BBS_DASH
-  // BBS_BEVELED
-  // BBS_INSET
-  // BBS_UNDERLINE
-
-  void SetBorderStyle(int nStyle);
-  int GetBorderStyle() const;
-
-  void SetBorderDash(const CFX_IntArray& array);
-  void GetBorderDash(CFX_IntArray& array) const;
-
-  // The background of the annotation's icon when closed
-  // The title bar of the annotation's pop-up window
-  // The border of a link annotation
-
-  void SetColor(FX_COLORREF color);
-  void RemoveColor();
-  FX_BOOL GetColor(FX_COLORREF& color) const;
-
-  FX_BOOL IsVisible() const;
-  // action
-
-  CPDF_Action GetAction() const;
-  void SetAction(const CPDF_Action& a);
-  void RemoveAction();
-
-  CPDF_AAction GetAAction() const;
-  void SetAAction(const CPDF_AAction& aa);
-  void RemoveAAction();
-
-  virtual CPDF_Action GetAAction(CPDF_AAction::AActionType eAAT);
-
-  virtual FX_BOOL IsAppearanceValid();
-  virtual FX_BOOL IsAppearanceValid(CPDF_Annot::AppearanceMode mode);
-  virtual void DrawAppearance(CFX_RenderDevice* pDevice,
-                              const CFX_Matrix* pUser2Device,
-                              CPDF_Annot::AppearanceMode mode,
-                              const CPDF_RenderOptions* pOptions);
-  void DrawBorder(CFX_RenderDevice* pDevice,
-                  const CFX_Matrix* pUser2Device,
-                  const CPDF_RenderOptions* pOptions);
-
-  void ClearCachedAP();
-
-  void WriteAppearance(const CFX_ByteString& sAPType,
-                       const CPDF_Rect& rcBBox,
-                       const CFX_Matrix& matrix,
-                       const CFX_ByteString& sContents,
-                       const CFX_ByteString& sAPState = "");
-
- protected:
-  CPDF_Annot* m_pAnnot;
-
- private:
-  FX_BOOL CreateFormFiller();
-};
-
-#endif  // FPDFSDK_INCLUDE_FSDK_BASEANNOT_H_
diff --git a/fpdfsdk/include/fsdk_baseform.h b/fpdfsdk/include/fsdk_baseform.h
deleted file mode 100644
index 023ea74..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_
-
-#if _FX_OS_ == _FX_ANDROID_
-#include "time.h"
-#else
-#include <ctime>
-#endif
-
-#include <map>
-
-#include "core/include/fpdfapi/fpdf_parser.h"
-#include "core/include/fpdfdoc/fpdf_doc.h"
-#include "core/include/fxcrt/fx_basic.h"
-#include "core/include/fxge/fx_dib.h"
-#include "fsdk_baseannot.h"
-
-class CFFL_FormFiller;
-class CPDFSDK_Annot;
-class CPDFSDK_DateTime;
-class CPDFSDK_Document;
-class CPDFSDK_InterForm;
-class CPDFSDK_PageView;
-class CPDF_Action;
-class CPDF_FormField;
-struct CPWL_Color;
-
-#ifdef PDF_ENABLE_XFA
-typedef enum _PDFSDK_XFAAActionType {
-  PDFSDK_XFA_Click = 0,
-  PDFSDK_XFA_Full,
-  PDFSDK_XFA_PreOpen,
-  PDFSDK_XFA_PostOpen
-} PDFSDK_XFAAActionType;
-#endif  // PDF_ENABLE_XFA
-
-typedef struct _PDFSDK_FieldAction {
-  _PDFSDK_FieldAction() {
-    bModifier = FALSE;
-    bShift = FALSE;
-    nCommitKey = 0;
-    bKeyDown = FALSE;
-    nSelEnd = nSelStart = 0;
-    bWillCommit = FALSE;
-    bFieldFull = FALSE;
-    bRC = TRUE;
-  }
-
-  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]
-} PDFSDK_FieldAction;
-
-class CPDFSDK_Widget : public CPDFSDK_BAAnnot {
- public:
-#ifdef PDF_ENABLE_XFA
-  IXFA_Widget* GetMixXFAWidget() const;
-  IXFA_Widget* GetGroupMixXFAWidget();
-  IXFA_WidgetHandler* 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(IXFA_DocView* pXFADocView,
-                                  IXFA_Widget* hWidget,
-                                  CPDF_FormField* pFormField,
-                                  CPDF_FormControl* pFormControl);
-  static void SynchronizeXFAItems(IXFA_DocView* pXFADocView,
-                                  IXFA_Widget* 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;
-
-  // CPDFSDK_Annot
-  CFX_ByteString GetSubType() const override;
-  CPDF_Action GetAAction(CPDF_AAction::AActionType eAAT) override;
-  FX_BOOL IsAppearanceValid() override;
-
-  int GetLayoutOrder() const override { return 2; }
-
-  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;
-  FX_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(FX_BOOL bChecked, FX_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;
-
- 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);
-
-  CPDF_Rect GetClientRect() const;
-  CPDF_Rect 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);
-
- public:
-  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);
-
-#ifndef PDF_ENABLE_XFA
- private:
-#endif  // PDF_ENABLE_XFA
-  CPDFSDK_InterForm* m_pInterForm;
-  FX_BOOL m_bAppModified;
-  int32_t m_nAppAge;
-  int32_t m_nValueAge;
-
-#ifdef PDF_ENABLE_XFA
-  mutable IXFA_Widget* m_hMixXFAWidget;
-  mutable IXFA_WidgetHandler* m_pWidgetHandler;
-#endif  // PDF_ENABLE_XFA
-};
-
-#ifdef PDF_ENABLE_XFA
-class CPDFSDK_XFAWidget : public CPDFSDK_Annot {
- public:
-  CPDFSDK_XFAWidget(IXFA_Widget* pAnnot,
-                    CPDFSDK_PageView* pPageView,
-                    CPDFSDK_InterForm* pInterForm);
-  ~CPDFSDK_XFAWidget() override {}
-
-  FX_BOOL IsXFAField() override;
-  IXFA_Widget* GetXFAWidget() const override { return m_hXFAWidget; }
-  CFX_ByteString GetType() const override;
-  CFX_ByteString GetSubType() const override { return ""; }
-  CFX_FloatRect GetRect() const override;
-
-  CPDFSDK_InterForm* GetInterForm() { return m_pInterForm; }
-
- private:
-  CPDFSDK_InterForm* m_pInterForm;
-  IXFA_Widget* m_hXFAWidget;
-};
-#define CPDFSDK_XFAWidgetMap \
-  CFX_MapPtrTemplate<IXFA_Widget*, CPDFSDK_XFAWidget*>
-#define CPDFSDK_FieldSynchronizeMap CFX_MapPtrTemplate<CPDF_FormField*, int>
-#endif  // PDF_ENABLE_XFA
-
-class CPDFSDK_InterForm : public CPDF_FormNotify {
- public:
-  explicit CPDFSDK_InterForm(CPDFSDK_Document* pDocument);
-  ~CPDFSDK_InterForm() override;
-
-  CPDF_InterForm* GetInterForm() const { return m_pInterForm; }
-  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) 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(IXFA_Widget* hWidget, CPDFSDK_XFAWidget* pWidget);
-  void RemoveXFAMap(IXFA_Widget* hWidget);
-  CPDFSDK_XFAWidget* GetXFAWidget(IXFA_Widget* hWidget);
-  void XfaEnableCalculate(FX_BOOL bEnabled);
-  FX_BOOL IsXfaCalculateEnabled() const;
-  FX_BOOL IsXfaValidationsEnabled();
-  void XfaSetValidationsEnabled(FX_BOOL bEnabled);
-#endif  // PDF_ENABLE_XFA
-
-  void OnKeyStrokeCommit(CPDF_FormField* pFormField,
-                         CFX_WideString& csValue,
-                         FX_BOOL& bRC);
-  void OnValidate(CPDF_FormField* pFormField,
-                  CFX_WideString& csValue,
-                  FX_BOOL& bRC);
-  void OnCalculate(CPDF_FormField* pFormField = NULL);
-  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,
-                       FX_BOOL bIncludeOrExclude,
-                       FX_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,
-                                   FX_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:
-  // CPDF_FormNotify
-  int BeforeValueChange(const CPDF_FormField* pField,
-                        CFX_WideString& csValue) override;
-  int AfterValueChange(const CPDF_FormField* pField) override;
-  int BeforeSelectionChange(const CPDF_FormField* pField,
-                            CFX_WideString& csValue) override;
-  int AfterSelectionChange(const CPDF_FormField* pField) override;
-  int AfterCheckedStatusChange(const CPDF_FormField* pField,
-                               const CFX_ByteArray& statusArray) override;
-  int BeforeFormReset(const CPDF_InterForm* pForm) override;
-  int AfterFormReset(const CPDF_InterForm* pForm) override;
-  int BeforeFormImportData(const CPDF_InterForm* pForm) override;
-  int AfterFormImportData(const 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;
-  CPDF_InterForm* m_pInterForm;
-  CPDFSDK_WidgetMap m_Map;
-#ifdef PDF_ENABLE_XFA
-  CPDFSDK_XFAWidgetMap m_XFAMap;
-  CPDFSDK_FieldSynchronizeMap m_FieldSynchronizeMap;
-  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];
-};
-
-#define BAI_STRUCTURE 0
-#define BAI_ROW 1
-#define BAI_COLUMN 2
-
-#define CPDFSDK_Annots CFX_ArrayTemplate<CPDFSDK_Annot*>
-#define CPDFSDK_SortAnnots CGW_ArrayTemplate<CPDFSDK_Annot*>
-class CBA_AnnotIterator {
- public:
-  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 int CompareByLeft(CPDFSDK_Annot* p1, CPDFSDK_Annot* p2);
-  static int CompareByTop(CPDFSDK_Annot* p1, CPDFSDK_Annot* p2);
-  static CPDF_Rect GetAnnotRect(CPDFSDK_Annot* pAnnot);
-
-  CPDFSDK_PageView* m_pPageView;
-  CFX_ByteString m_sType;
-  CFX_ByteString m_sSubType;
-  int m_nTabs;
-  CPDFSDK_Annots m_Annots;
-};
-
-#endif  // FPDFSDK_INCLUDE_FSDK_BASEFORM_H_
diff --git a/fpdfsdk/include/fsdk_define.h b/fpdfsdk/include/fsdk_define.h
deleted file mode 100644
index 708e817..0000000
--- a/fpdfsdk/include/fsdk_define.h
+++ /dev/null
@@ -1,140 +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_DEFINE_H_
-#define FPDFSDK_INCLUDE_FSDK_DEFINE_H_
-
-#include "core/include/fpdfapi/fpdf_module.h"
-#include "core/include/fpdfapi/fpdf_pageobj.h"
-#include "core/include/fpdfapi/fpdf_parser.h"
-#include "core/include/fpdfapi/fpdf_render.h"
-#include "core/include/fpdfdoc/fpdf_doc.h"
-#include "core/include/fpdfdoc/fpdf_vt.h"
-#include "core/include/fxge/fx_ge.h"
-#include "core/include/fxge/fx_ge_win32.h"
-#include "public/fpdfview.h"
-
-#ifdef PDF_ENABLE_XFA
-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h"
-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_page.h"
-#include "xfa/include/fwl/adapter/fwl_adaptertimermgr.h"
-#include "xfa/include/fxbarcode/BC_BarCode.h"
-#include "xfa/include/fxfa/fxfa.h"
-#include "xfa/include/fxgraphics/fx_graphics.h"
-#include "xfa/include/fxjse/fxjse.h"
-#endif  // PDF_ENABLE_XFA
-
-#ifdef _WIN32
-#include <tchar.h>
-#include <math.h>
-#endif
-
-// Convert a #FX_ARGB to a #FX_COLORREF.
-#define FX_ARGBTOCOLORREF(argb)                                            \
-  ((((FX_DWORD)argb & 0x00FF0000) >> 16) | ((FX_DWORD)argb & 0x0000FF00) | \
-   (((FX_DWORD)argb & 0x000000FF) << 16))
-
-// Convert a #FX_COLORREF to a #FX_ARGB.
-#define FX_COLORREFTOARGB(rgb)                                   \
-  ((FX_DWORD)0xFF000000 | (((FX_DWORD)rgb & 0x000000FF) << 16) | \
-   ((FX_DWORD)rgb & 0x0000FF00) | (((FX_DWORD)rgb & 0x00FF0000) >> 16))
-
-typedef unsigned int FX_UINT;
-class CRenderContext;
-class IFSDK_PAUSE_Adapter;
-
-class CPDF_CustomAccess final : public IFX_FileRead {
- public:
-  explicit CPDF_CustomAccess(FPDF_FILEACCESS* pFileAccess);
-  ~CPDF_CustomAccess() override {}
-
-  // IFX_FileRead
-  FX_FILESIZE GetSize() override { return m_FileAccess.m_FileLen; }
-  void Release() override { delete this; }
-  FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override;
-
-#ifdef PDF_ENABLE_XFA
-  virtual CFX_ByteString GetFullPath() { return ""; }
-  virtual FX_BOOL GetByte(FX_DWORD pos, uint8_t& ch);
-  virtual FX_BOOL GetBlock(FX_DWORD pos, uint8_t* pBuf, FX_DWORD size);
-#endif  // PDF_ENABLE_XFA
-
- private:
-  FPDF_FILEACCESS m_FileAccess;
-#ifdef PDF_ENABLE_XFA
-  uint8_t m_Buffer[512];
-  FX_DWORD m_BufferOffset;
-#endif  // PDF_ENABLE_XFA
-};
-
-#ifdef PDF_ENABLE_XFA
-class CFPDF_FileStream : public IFX_FileStream {
- public:
-  CFPDF_FileStream(FPDF_FILEHANDLER* pFS);
-  virtual ~CFPDF_FileStream() {}
-
-  virtual IFX_FileStream* Retain();
-  virtual void Release();
-
-  virtual FX_FILESIZE GetSize();
-  virtual FX_BOOL IsEOF();
-  virtual FX_FILESIZE GetPosition() { return m_nCurPos; }
-  virtual void SetPosition(FX_FILESIZE pos) { m_nCurPos = pos; }
-  virtual FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size);
-  virtual size_t ReadBlock(void* buffer, size_t size);
-  virtual FX_BOOL WriteBlock(const void* buffer,
-                             FX_FILESIZE offset,
-                             size_t size);
-  virtual FX_BOOL Flush();
-
- protected:
-  FPDF_FILEHANDLER* m_pFS;
-  FX_FILESIZE m_nCurPos;
-};
-#endif  // PDF_ENABLE_XFA
-
-// Object types for public FPDF_ types; these correspond to next layer down
-// from fpdfsdk. For master, these are CPDF_ types, but for XFA, these are
-// CPDFXFA_ types.
-#ifndef PDF_ENABLE_XFA
-using UnderlyingDocumentType = CPDF_Document;
-using UnderlyingPageType = CPDF_Page;
-#else   // PDF_ENABLE_XFA
-using UnderlyingDocumentType = CPDFXFA_Document;
-using UnderlyingPageType = CPDFXFA_Page;
-#endif  // PDF_ENABLE_XFA
-
-// Conversions to/from underlying types.
-UnderlyingDocumentType* UnderlyingFromFPDFDocument(FPDF_DOCUMENT doc);
-FPDF_DOCUMENT FPDFDocumentFromUnderlying(UnderlyingDocumentType* doc);
-
-UnderlyingPageType* UnderlyingFromFPDFPage(FPDF_PAGE page);
-
-// Conversions to/from FPDF_ types.
-CPDF_Document* CPDFDocumentFromFPDFDocument(FPDF_DOCUMENT doc);
-FPDF_DOCUMENT FPDFDocumentFromCPDFDocument(CPDF_Document* doc);
-
-CPDF_Page* CPDFPageFromFPDFPage(FPDF_PAGE page);
-
-void DropContext(void* data);
-void FSDK_SetSandBoxPolicy(FPDF_DWORD policy, FPDF_BOOL enable);
-FPDF_BOOL FSDK_IsSandBoxPolicyEnabled(FPDF_DWORD policy);
-void FPDF_RenderPage_Retail(CRenderContext* pContext,
-                            FPDF_PAGE page,
-                            int start_x,
-                            int start_y,
-                            int size_x,
-                            int size_y,
-                            int rotate,
-                            int flags,
-                            FX_BOOL bNeedToRestore,
-                            IFSDK_PAUSE_Adapter* pause);
-
-void CheckUnSupportError(CPDF_Document* pDoc, FX_DWORD err_code);
-void CheckUnSupportAnnot(CPDF_Document* pDoc, const CPDF_Annot* pPDFAnnot);
-void ProcessParseError(FX_DWORD err_code);
-
-#endif  // FPDFSDK_INCLUDE_FSDK_DEFINE_H_
diff --git a/fpdfsdk/include/fsdk_mgr.h b/fpdfsdk/include/fsdk_mgr.h
deleted file mode 100644
index 51f1691..0000000
--- a/fpdfsdk/include/fsdk_mgr.h
+++ /dev/null
@@ -1,741 +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_MGR_H_
-#define FPDFSDK_INCLUDE_FSDK_MGR_H_
-
-#include <map>
-#include <memory>
-
-#include "core/include/fpdftext/fpdf_text.h"
-#include "fsdk_actionhandler.h"
-#include "fsdk_annothandler.h"
-#include "fsdk_baseannot.h"
-#include "fsdk_baseform.h"
-#include "fsdk_common.h"
-#include "fsdk_define.h"
-#include "fx_systemhandler.h"
-#include "javascript/IJavaScript.h"
-#include "public/fpdf_formfill.h"
-#include "public/fpdf_fwlevent.h"  // cross platform keycode and events define.
-
-#ifdef PDF_ENABLE_XFA
-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h"
-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_page.h"
-#endif  // PDF_ENABLE_XFA
-
-class CFFL_IFormFiller;
-class CPDFSDK_ActionHandler;
-class CPDFSDK_Annot;
-class CPDFSDK_Document;
-class CPDFSDK_InterForm;
-class CPDFSDK_PageView;
-class CPDFSDK_Widget;
-class IFX_SystemHandler;
-
-class CPDFDoc_Environment final {
- public:
-  CPDFDoc_Environment(UnderlyingDocumentType* pDoc, FPDF_FORMFILLINFO* pFFinfo);
-  ~CPDFDoc_Environment();
-
-#ifdef PDF_ENABLE_XFA
-  void Release() {
-    if (m_pInfo && m_pInfo->Release)
-      m_pInfo->Release(m_pInfo);
-    delete this;
-  }
-#endif  // PDF_ENABLE_XFA
-
-  void FFI_Invalidate(FPDF_PAGE page,
-                      double left,
-                      double top,
-                      double right,
-                      double bottom) {
-    if (m_pInfo && m_pInfo->FFI_Invalidate)
-      m_pInfo->FFI_Invalidate(m_pInfo, page, left, top, right, bottom);
-  }
-
-  void FFI_OutputSelectedRect(FPDF_PAGE page,
-                              double left,
-                              double top,
-                              double right,
-                              double bottom) {
-    if (m_pInfo && m_pInfo->FFI_OutputSelectedRect)
-      m_pInfo->FFI_OutputSelectedRect(m_pInfo, page, left, top, right, bottom);
-  }
-
-  void FFI_SetCursor(int nCursorType) {
-    if (m_pInfo && m_pInfo->FFI_SetCursor)
-      m_pInfo->FFI_SetCursor(m_pInfo, nCursorType);
-  }
-
-  int FFI_SetTimer(int uElapse, TimerCallback lpTimerFunc) {
-    if (m_pInfo && m_pInfo->FFI_SetTimer)
-      return m_pInfo->FFI_SetTimer(m_pInfo, uElapse, lpTimerFunc);
-    return -1;
-  }
-
-  void FFI_KillTimer(int nTimerID) {
-    if (m_pInfo && m_pInfo->FFI_KillTimer)
-      m_pInfo->FFI_KillTimer(m_pInfo, nTimerID);
-  }
-
-  FX_SYSTEMTIME FFI_GetLocalTime() const {
-    FX_SYSTEMTIME fxtime;
-    if (m_pInfo && m_pInfo->FFI_GetLocalTime) {
-      FPDF_SYSTEMTIME systime = m_pInfo->FFI_GetLocalTime(m_pInfo);
-      fxtime.wDay = systime.wDay;
-      fxtime.wDayOfWeek = systime.wDayOfWeek;
-      fxtime.wHour = systime.wHour;
-      fxtime.wMilliseconds = systime.wMilliseconds;
-      fxtime.wMinute = systime.wMinute;
-      fxtime.wMonth = systime.wMonth;
-      fxtime.wSecond = systime.wSecond;
-      fxtime.wYear = systime.wYear;
-    }
-    return fxtime;
-  }
-
-  void FFI_OnChange() {
-    if (m_pInfo && m_pInfo->FFI_OnChange)
-      m_pInfo->FFI_OnChange(m_pInfo);
-  }
-
-  FX_BOOL FFI_IsSHIFTKeyDown(FX_DWORD nFlag) const {
-    return (nFlag & FWL_EVENTFLAG_ShiftKey) != 0;
-  }
-
-  FX_BOOL FFI_IsCTRLKeyDown(FX_DWORD nFlag) const {
-    return (nFlag & FWL_EVENTFLAG_ControlKey) != 0;
-  }
-
-  FX_BOOL FFI_IsALTKeyDown(FX_DWORD nFlag) const {
-    return (nFlag & FWL_EVENTFLAG_AltKey) != 0;
-  }
-
-  FX_BOOL FFI_IsINSERTKeyDown(FX_DWORD nFlag) const { return FALSE; }
-
-  int JS_appAlert(const FX_WCHAR* Msg,
-                  const FX_WCHAR* Title,
-                  FX_UINT Type,
-                  FX_UINT Icon);
-  int JS_appResponse(const FX_WCHAR* Question,
-                     const FX_WCHAR* Title,
-                     const FX_WCHAR* Default,
-                     const FX_WCHAR* cLabel,
-                     FPDF_BOOL bPassword,
-                     void* response,
-                     int length);
-
-  void JS_appBeep(int nType) {
-    if (m_pInfo && m_pInfo->m_pJsPlatform && m_pInfo->m_pJsPlatform->app_beep)
-      m_pInfo->m_pJsPlatform->app_beep(m_pInfo->m_pJsPlatform, nType);
-  }
-
-  CFX_WideString JS_fieldBrowse();
-  CFX_WideString JS_docGetFilePath();
-
-  void JS_docSubmitForm(void* formData, int length, const FX_WCHAR* URL);
-  void JS_docmailForm(void* mailData,
-                      int length,
-                      FPDF_BOOL bUI,
-                      const FX_WCHAR* To,
-                      const FX_WCHAR* Subject,
-                      const FX_WCHAR* CC,
-                      const FX_WCHAR* BCC,
-                      const FX_WCHAR* Msg);
-
-  void JS_docprint(FPDF_BOOL bUI,
-                   int nStart,
-                   int nEnd,
-                   FPDF_BOOL bSilent,
-                   FPDF_BOOL bShrinkToFit,
-                   FPDF_BOOL bPrintAsImage,
-                   FPDF_BOOL bReverse,
-                   FPDF_BOOL bAnnotations) {
-    if (m_pInfo && m_pInfo->m_pJsPlatform && m_pInfo->m_pJsPlatform->Doc_print)
-      m_pInfo->m_pJsPlatform->Doc_print(m_pInfo->m_pJsPlatform, bUI, nStart,
-                                        nEnd, bSilent, bShrinkToFit,
-                                        bPrintAsImage, bReverse, bAnnotations);
-  }
-
-  void JS_docgotoPage(int nPageNum) {
-    if (m_pInfo && m_pInfo->m_pJsPlatform &&
-        m_pInfo->m_pJsPlatform->Doc_gotoPage)
-      m_pInfo->m_pJsPlatform->Doc_gotoPage(m_pInfo->m_pJsPlatform, nPageNum);
-  }
-
-  FPDF_PAGE FFI_GetPage(FPDF_DOCUMENT document, int nPageIndex) {
-    if (m_pInfo && m_pInfo->FFI_GetPage)
-      return m_pInfo->FFI_GetPage(m_pInfo, document, nPageIndex);
-    return NULL;
-  }
-
-  FPDF_PAGE FFI_GetCurrentPage(FPDF_DOCUMENT document) {
-    if (m_pInfo && m_pInfo->FFI_GetCurrentPage)
-      return m_pInfo->FFI_GetCurrentPage(m_pInfo, document);
-    return NULL;
-  }
-
-  int FFI_GetRotation(FPDF_PAGE page) {
-    if (m_pInfo && m_pInfo->FFI_GetRotation)
-      return m_pInfo->FFI_GetRotation(m_pInfo, page);
-    return 0;
-  }
-
-  void FFI_ExecuteNamedAction(const FX_CHAR* namedAction) {
-    if (m_pInfo && m_pInfo->FFI_ExecuteNamedAction)
-      m_pInfo->FFI_ExecuteNamedAction(m_pInfo, namedAction);
-  }
-
-  void FFI_OnSetFieldInputFocus(void* field,
-                                FPDF_WIDESTRING focusText,
-                                FPDF_DWORD nTextLen,
-                                FX_BOOL bFocus) {
-    if (m_pInfo && m_pInfo->FFI_SetTextFieldFocus)
-      m_pInfo->FFI_SetTextFieldFocus(m_pInfo, focusText, nTextLen, bFocus);
-  }
-
-  void FFI_DoURIAction(const FX_CHAR* bsURI) {
-    if (m_pInfo && m_pInfo->FFI_DoURIAction)
-      m_pInfo->FFI_DoURIAction(m_pInfo, bsURI);
-  }
-
-  void FFI_DoGoToAction(int nPageIndex,
-                        int zoomMode,
-                        float* fPosArray,
-                        int sizeOfArray) {
-    if (m_pInfo && m_pInfo->FFI_DoGoToAction)
-      m_pInfo->FFI_DoGoToAction(m_pInfo, nPageIndex, zoomMode, fPosArray,
-                                sizeOfArray);
-  }
-
-#ifdef PDF_ENABLE_XFA
-  void FFI_DisplayCaret(FPDF_PAGE page,
-                        FPDF_BOOL bVisible,
-                        double left,
-                        double top,
-                        double right,
-                        double bottom) {
-    if (m_pInfo && m_pInfo->FFI_DisplayCaret)
-      m_pInfo->FFI_DisplayCaret(m_pInfo, page, bVisible, left, top, right,
-                                bottom);
-  }
-
-  int FFI_GetCurrentPageIndex(FPDF_DOCUMENT document) {
-    if (!m_pInfo || !m_pInfo->FFI_GetCurrentPageIndex) {
-      return -1;
-    }
-    return m_pInfo->FFI_GetCurrentPageIndex(m_pInfo, document);
-  }
-
-  void FFI_SetCurrentPage(FPDF_DOCUMENT document, int iCurPage) {
-    if (m_pInfo && m_pInfo->FFI_SetCurrentPage)
-      m_pInfo->FFI_SetCurrentPage(m_pInfo, document, iCurPage);
-  }
-
-  CFX_WideString FFI_GetAppName() const { return CFX_WideString(L"Acrobat"); }
-
-  CFX_WideString FFI_GetPlatform() {
-    if (m_pInfo && m_pInfo->FFI_GetPlatform) {
-      int nRequiredLen = m_pInfo->FFI_GetPlatform(m_pInfo, NULL, 0);
-      if (nRequiredLen <= 0)
-        return L"";
-
-      char* pbuff = new char[nRequiredLen];
-      memset(pbuff, 0, nRequiredLen);
-      int nActualLen = m_pInfo->FFI_GetPlatform(m_pInfo, pbuff, nRequiredLen);
-      if (nActualLen <= 0 || nActualLen > nRequiredLen) {
-        delete[] pbuff;
-        return L"";
-      }
-      CFX_ByteString bsRet = CFX_ByteString(pbuff, nActualLen);
-      CFX_WideString wsRet = CFX_WideString::FromUTF16LE(
-          (unsigned short*)bsRet.GetBuffer(bsRet.GetLength()),
-          bsRet.GetLength() / sizeof(unsigned short));
-      delete[] pbuff;
-      return wsRet;
-    }
-    return L"";
-  }
-
-  void FFI_GotoURL(FPDF_DOCUMENT document,
-                   const CFX_WideStringC& wsURL,
-                   FX_BOOL bAppend) {
-    if (m_pInfo && m_pInfo->FFI_GotoURL) {
-      CFX_ByteString bsTo = CFX_WideString(wsURL).UTF16LE_Encode();
-      FPDF_WIDESTRING pTo = (FPDF_WIDESTRING)bsTo.GetBuffer(wsURL.GetLength());
-      m_pInfo->FFI_GotoURL(m_pInfo, document, pTo);
-      bsTo.ReleaseBuffer();
-    }
-  }
-
-  void FFI_GetURL(FPDF_DOCUMENT document, CFX_WideString& wsURL) {
-    wsURL = CFX_WideString();
-  }
-
-  void FFI_AddDoRecord(FPDF_DOCUMENT document, FPDF_WIDGET hWidget) {}
-  void FFI_PageEvent(FPDF_PAGE page, FPDF_DWORD flag) {}
-
-  void FFI_GetPageViewRect(FPDF_PAGE page, FS_RECTF& dstRect) {
-    if (m_pInfo && m_pInfo->FFI_GetPageViewRect) {
-      double left;
-      double top;
-      double right;
-      double bottom;
-      m_pInfo->FFI_GetPageViewRect(m_pInfo, page, &left, &top, &right, &bottom);
-
-      dstRect.left = static_cast<float>(left);
-      dstRect.top = static_cast<float>(top < bottom ? bottom : top);
-      dstRect.bottom = static_cast<float>(top < bottom ? top : bottom);
-      dstRect.right = static_cast<float>(right);
-    }
-  }
-
-  FX_BOOL FFI_PopupMenu(FPDF_PAGE page,
-                        FPDF_WIDGET hWidget,
-                        int menuFlag,
-                        CFX_PointF ptPopup,
-                        const CFX_PointF* pRectExclude) {
-    if (m_pInfo && m_pInfo->FFI_PopupMenu)
-      return m_pInfo->FFI_PopupMenu(m_pInfo, page, hWidget, menuFlag, ptPopup.x,
-                                    ptPopup.y);
-    return FALSE;
-  }
-
-  void FFI_Alert(FPDF_WIDESTRING Msg,
-                 FPDF_WIDESTRING Title,
-                 int Type,
-                 int Icon) {
-    if (m_pInfo && m_pInfo->m_pJsPlatform && m_pInfo->m_pJsPlatform->app_alert)
-      m_pInfo->m_pJsPlatform->app_alert(m_pInfo->m_pJsPlatform, Msg, Title,
-                                        Type, Icon);
-  }
-
-  void FFI_EmailTo(FPDF_FILEHANDLER* fileHandler,
-                   FPDF_WIDESTRING pTo,
-                   FPDF_WIDESTRING pSubject,
-                   FPDF_WIDESTRING pCC,
-                   FPDF_WIDESTRING pBcc,
-                   FPDF_WIDESTRING pMsg) {
-    if (m_pInfo && m_pInfo->FFI_EmailTo)
-      m_pInfo->FFI_EmailTo(m_pInfo, fileHandler, pTo, pSubject, pCC, pBcc,
-                           pMsg);
-  }
-
-  void FFI_UploadTo(FPDF_FILEHANDLER* fileHandler,
-                    int fileFlag,
-                    FPDF_WIDESTRING uploadTo) {
-    if (m_pInfo && m_pInfo->FFI_UploadTo)
-      m_pInfo->FFI_UploadTo(m_pInfo, fileHandler, fileFlag, uploadTo);
-  }
-
-  FPDF_FILEHANDLER* FFI_OpenFile(int fileType,
-                                 FPDF_WIDESTRING wsURL,
-                                 const char* mode) {
-    if (m_pInfo && m_pInfo->FFI_OpenFile)
-      return m_pInfo->FFI_OpenFile(m_pInfo, fileType, wsURL, mode);
-    return NULL;
-  }
-
-  CFX_WideString FFI_GetFilePath(FPDF_FILEHANDLER* pFileHandler) const {
-    return L"";
-  }
-
-  int FFI_GetDocumentCount() const { return 0; }
-  int FFI_GetCurDocument() const { return 0; }
-
-  IFX_FileRead* FFI_DownloadFromURL(const FX_WCHAR* url) {
-    if (m_pInfo && m_pInfo->FFI_DownloadFromURL) {
-      CFX_ByteString bstrURL = CFX_WideString(url).UTF16LE_Encode();
-      FPDF_WIDESTRING wsURL =
-          (FPDF_WIDESTRING)bstrURL.GetBuffer(bstrURL.GetLength());
-
-      FPDF_LPFILEHANDLER fileHandler =
-          m_pInfo->FFI_DownloadFromURL(m_pInfo, wsURL);
-
-      return new CFPDF_FileStream(fileHandler);
-    }
-    return NULL;
-  }
-
-  CFX_WideString FFI_PostRequestURL(const FX_WCHAR* wsURL,
-                                    const FX_WCHAR* wsData,
-                                    const FX_WCHAR* wsContentType,
-                                    const FX_WCHAR* wsEncode,
-                                    const FX_WCHAR* wsHeader) {
-    if (m_pInfo && m_pInfo->FFI_PostRequestURL) {
-      CFX_ByteString bsURL = CFX_WideString(wsURL).UTF16LE_Encode();
-      FPDF_WIDESTRING URL = (FPDF_WIDESTRING)bsURL.GetBuffer(bsURL.GetLength());
-
-      CFX_ByteString bsData = CFX_WideString(wsData).UTF16LE_Encode();
-      FPDF_WIDESTRING data =
-          (FPDF_WIDESTRING)bsData.GetBuffer(bsData.GetLength());
-
-      CFX_ByteString bsContentType =
-          CFX_WideString(wsContentType).UTF16LE_Encode();
-      FPDF_WIDESTRING contentType =
-          (FPDF_WIDESTRING)bsContentType.GetBuffer(bsContentType.GetLength());
-
-      CFX_ByteString bsEncode = CFX_WideString(wsEncode).UTF16LE_Encode();
-      FPDF_WIDESTRING encode =
-          (FPDF_WIDESTRING)bsEncode.GetBuffer(bsEncode.GetLength());
-
-      CFX_ByteString bsHeader = CFX_WideString(wsHeader).UTF16LE_Encode();
-      FPDF_WIDESTRING header =
-          (FPDF_WIDESTRING)bsHeader.GetBuffer(bsHeader.GetLength());
-
-      FPDF_BSTR respone;
-      FPDF_BStr_Init(&respone);
-      m_pInfo->FFI_PostRequestURL(m_pInfo, URL, data, contentType, encode,
-                                  header, &respone);
-
-      CFX_WideString wsRet = CFX_WideString::FromUTF16LE(
-          (unsigned short*)respone.str, respone.len / sizeof(unsigned short));
-      FPDF_BStr_Clear(&respone);
-
-      return wsRet;
-    }
-    return L"";
-  }
-
-  FPDF_BOOL FFI_PutRequestURL(const FX_WCHAR* wsURL,
-                              const FX_WCHAR* wsData,
-                              const FX_WCHAR* wsEncode) {
-    if (m_pInfo && m_pInfo->FFI_PutRequestURL) {
-      CFX_ByteString bsURL = CFX_WideString(wsURL).UTF16LE_Encode();
-      FPDF_WIDESTRING URL = (FPDF_WIDESTRING)bsURL.GetBuffer(bsURL.GetLength());
-
-      CFX_ByteString bsData = CFX_WideString(wsData).UTF16LE_Encode();
-      FPDF_WIDESTRING data =
-          (FPDF_WIDESTRING)bsData.GetBuffer(bsData.GetLength());
-
-      CFX_ByteString bsEncode = CFX_WideString(wsEncode).UTF16LE_Encode();
-      FPDF_WIDESTRING encode =
-          (FPDF_WIDESTRING)bsEncode.GetBuffer(bsEncode.GetLength());
-
-      return m_pInfo->FFI_PutRequestURL(m_pInfo, URL, data, encode);
-    }
-    return FALSE;
-  }
-
-  FPDF_BOOL FFI_ShowFileDialog(const FX_WCHAR* wsTitle,
-                               const FX_WCHAR* wsFilter,
-                               CFX_WideStringArray& wsPathArr,
-                               FX_BOOL bOpen) {
-    return FALSE;
-  }
-
-  CFX_WideString FFI_GetLanguage() {
-    if (m_pInfo && m_pInfo->FFI_GetLanguage) {
-      int nRequiredLen = m_pInfo->FFI_GetLanguage(m_pInfo, NULL, 0);
-      if (nRequiredLen <= 0)
-        return L"";
-
-      char* pbuff = new char[nRequiredLen];
-      memset(pbuff, 0, nRequiredLen);
-      int nActualLen = m_pInfo->FFI_GetLanguage(m_pInfo, pbuff, nRequiredLen);
-      if (nActualLen <= 0 || nActualLen > nRequiredLen) {
-        delete[] pbuff;
-        return L"";
-      }
-      CFX_ByteString bsRet = CFX_ByteString(pbuff, nActualLen);
-      CFX_WideString wsRet = CFX_WideString::FromUTF16LE(
-          (unsigned short*)bsRet.GetBuffer(bsRet.GetLength()),
-          bsRet.GetLength() / sizeof(unsigned short));
-      delete[] pbuff;
-      return wsRet;
-    }
-    return L"";
-  }
-#endif  // PDF_ENABLE_XFA
-
-  FX_BOOL IsJSInitiated() const { return m_pInfo && m_pInfo->m_pJsPlatform; }
-  void SetSDKDocument(CPDFSDK_Document* pFXDoc) { m_pSDKDoc = pFXDoc; }
-  CPDFSDK_Document* GetSDKDocument() const { return m_pSDKDoc; }
-  UnderlyingDocumentType* GetUnderlyingDocument() const {
-    return m_pUnderlyingDoc;
-  }
-  CFX_ByteString GetAppName() const { return ""; }
-  IFX_SystemHandler* GetSysHandler() const { return m_pSysHandler.get(); }
-  FPDF_FORMFILLINFO* GetFormFillInfo() const { return m_pInfo; }
-
-  CFFL_IFormFiller* GetIFormFiller();             // Creates if not present.
-  CPDFSDK_AnnotHandlerMgr* GetAnnotHandlerMgr();  // Creates if not present.
-  IJS_Runtime* GetJSRuntime();                    // Creates if not present.
-  CPDFSDK_ActionHandler* GetActionHander();       // Creates if not present.
-
- private:
-  std::unique_ptr<CPDFSDK_AnnotHandlerMgr> m_pAnnotHandlerMgr;
-  std::unique_ptr<CPDFSDK_ActionHandler> m_pActionHandler;
-  std::unique_ptr<IJS_Runtime> m_pJSRuntime;
-  FPDF_FORMFILLINFO* const m_pInfo;
-  CPDFSDK_Document* m_pSDKDoc;
-  UnderlyingDocumentType* const m_pUnderlyingDoc;
-  std::unique_ptr<CFFL_IFormFiller> m_pIFormFiller;
-  std::unique_ptr<IFX_SystemHandler> m_pSysHandler;
-};
-
-class CPDFSDK_Document {
- public:
-  CPDFSDK_Document(UnderlyingDocumentType* pDoc, CPDFDoc_Environment* pEnv);
-  ~CPDFSDK_Document();
-
-  CPDFSDK_InterForm* GetInterForm();
-
-  // Gets the document object for the next layer down; for master this is
-  // a CPDF_Document, but for XFA it is a CPDFXFA_Document.
-  UnderlyingDocumentType* GetUnderlyingDocument() const {
-#ifdef PDF_ENABLE_XFA
-    return GetXFADocument();
-#else   // PDF_ENABLE_XFA
-    return GetPDFDocument();
-#endif  // PDF_ENABLE_XFA
-  }
-
-  // Gets the CPDF_Document, either directly in master, or from the
-  // CPDFXFA_Document for XFA.
-  CPDF_Document* GetPDFDocument() const {
-#ifdef PDF_ENABLE_XFA
-    return m_pDoc ? m_pDoc->GetPDFDoc() : nullptr;
-#else   // PDF_ENABLE_XFA
-    return m_pDoc;
-#endif  // PDF_ENABLE_XFA
-  }
-
-#ifdef PDF_ENABLE_XFA
-  // Gets the XFA document directly (XFA-only).
-  CPDFXFA_Document* GetXFADocument() const { return m_pDoc; }
-
-  int GetPageViewCount() const { return m_pageMap.size(); }
-#endif  // PDF_ENABLE_XFA
-
-  CPDFSDK_PageView* GetPageView(UnderlyingPageType* pPage,
-                                FX_BOOL ReNew = TRUE);
-  CPDFSDK_PageView* GetPageView(int nIndex);
-  CPDFSDK_PageView* GetCurrentView();
-  void RemovePageView(UnderlyingPageType* pPage);
-  void UpdateAllViews(CPDFSDK_PageView* pSender, CPDFSDK_Annot* pAnnot);
-
-  CPDFSDK_Annot* GetFocusAnnot();
-
-  IJS_Runtime* GetJsRuntime();
-
-  FX_BOOL SetFocusAnnot(CPDFSDK_Annot* pAnnot, FX_UINT nFlag = 0);
-  FX_BOOL KillFocusAnnot(FX_UINT nFlag = 0);
-
-  FX_BOOL ExtractPages(const CFX_WordArray& arrExtraPages,
-                       CPDF_Document* pDstDoc);
-  FX_BOOL InsertPages(int nInsertAt,
-                      const CPDF_Document* pSrcDoc,
-                      const CFX_WordArray& arrSrcPages);
-  FX_BOOL ReplacePages(int nPage,
-                       const CPDF_Document* pSrcDoc,
-                       const CFX_WordArray& arrSrcPages);
-
-  void OnCloseDocument();
-
-  int GetPageCount() { return m_pDoc->GetPageCount(); }
-  FX_BOOL GetPermissions(int nFlag);
-  FX_BOOL GetChangeMark() { return m_bChangeMask; }
-  void SetChangeMark() { m_bChangeMask = TRUE; }
-  void ClearChangeMark() { m_bChangeMask = FALSE; }
-  CFX_WideString GetPath();
-  UnderlyingPageType* GetPage(int nIndex);
-  CPDFDoc_Environment* GetEnv() { return m_pEnv; }
-  void ProcJavascriptFun();
-  FX_BOOL ProcOpenAction();
-  CPDF_OCContext* GetOCContext();
-
- private:
-  std::map<UnderlyingPageType*, CPDFSDK_PageView*> m_pageMap;
-  UnderlyingDocumentType* m_pDoc;
-  std::unique_ptr<CPDFSDK_InterForm> m_pInterForm;
-  CPDFSDK_Annot* m_pFocusAnnot;
-  CPDFDoc_Environment* m_pEnv;
-  std::unique_ptr<CPDF_OCContext> m_pOccontent;
-  FX_BOOL m_bChangeMask;
-  FX_BOOL m_bBeingDestroyed;
-};
-class CPDFSDK_PageView final {
- public:
-  CPDFSDK_PageView(CPDFSDK_Document* pSDKDoc, UnderlyingPageType* page);
-  ~CPDFSDK_PageView();
-
-#ifdef PDF_ENABLE_XFA
-  void PageView_OnDraw(CFX_RenderDevice* pDevice,
-                       CFX_Matrix* pUser2Device,
-                       CPDF_RenderOptions* pOptions,
-                       const FX_RECT& pClip);
-#else   // PDF_ENABLE_XFA
-  void PageView_OnDraw(CFX_RenderDevice* pDevice,
-                       CFX_Matrix* pUser2Device,
-                       CPDF_RenderOptions* pOptions);
-#endif  // PDF_ENABLE_XFA
-
-  const CPDF_Annot* GetPDFAnnotAtPoint(FX_FLOAT pageX, FX_FLOAT pageY);
-  CPDFSDK_Annot* GetFXAnnotAtPoint(FX_FLOAT pageX, FX_FLOAT pageY);
-  const CPDF_Annot* GetPDFWidgetAtPoint(FX_FLOAT pageX, FX_FLOAT pageY);
-  CPDFSDK_Annot* GetFXWidgetAtPoint(FX_FLOAT pageX, FX_FLOAT pageY);
-  CPDFSDK_Annot* GetFocusAnnot();
-  void SetFocusAnnot(CPDFSDK_Annot* pSDKAnnot, FX_UINT nFlag = 0) {
-    m_pSDKDoc->SetFocusAnnot(pSDKAnnot, nFlag);
-  }
-  FX_BOOL KillFocusAnnot(FX_UINT nFlag = 0) {
-    return m_pSDKDoc->KillFocusAnnot(nFlag);
-  }
-  void KillFocusAnnotIfNeeded();
-  FX_BOOL Annot_HasAppearance(CPDF_Annot* pAnnot);
-
-  CPDFSDK_Annot* AddAnnot(CPDF_Dictionary* pDict);
-  CPDFSDK_Annot* AddAnnot(const FX_CHAR* lpSubType, CPDF_Dictionary* pDict);
-  CPDFSDK_Annot* AddAnnot(CPDF_Annot* pPDFAnnot);
-
-  FX_BOOL DeleteAnnot(CPDFSDK_Annot* pAnnot);
-  size_t CountAnnots() const;
-  CPDFSDK_Annot* GetAnnot(size_t nIndex);
-  CPDFSDK_Annot* GetAnnotByDict(CPDF_Dictionary* pDict);
-
-#ifdef PDF_ENABLE_XFA
-  CPDFSDK_Annot* AddAnnot(IXFA_Widget* pPDFAnnot);
-  CPDFSDK_Annot* GetAnnotByXFAWidget(IXFA_Widget* hWidget);
-  CPDFXFA_Page* GetPDFXFAPage() { return m_page; }
-  CPDF_Page* GetPDFPage();
-#else
-  CPDF_Page* GetPDFPage() { return m_page; }
-#endif  // PDF_ENABLE_XFA
-
-  CPDF_Document* GetPDFDocument();
-  CPDFSDK_Document* GetSDKDocument() { return m_pSDKDoc; }
-  FX_BOOL OnLButtonDown(const CPDF_Point& point, FX_UINT nFlag);
-  FX_BOOL OnLButtonUp(const CPDF_Point& point, FX_UINT nFlag);
-#ifdef PDF_ENABLE_XFA
-  FX_BOOL OnRButtonDown(const CPDF_Point& point, FX_UINT nFlag);
-  FX_BOOL OnRButtonUp(const CPDF_Point& point, FX_UINT nFlag);
-#endif  // PDF_ENABLE_XFA
-  FX_BOOL OnChar(int nChar, FX_UINT nFlag);
-  FX_BOOL OnKeyDown(int nKeyCode, int nFlag);
-  FX_BOOL OnKeyUp(int nKeyCode, int nFlag);
-
-  FX_BOOL OnMouseMove(const CPDF_Point& point, int nFlag);
-  FX_BOOL OnMouseWheel(double deltaX,
-                       double deltaY,
-                       const CPDF_Point& point,
-                       int nFlag);
-  bool IsValidAnnot(const CPDF_Annot* p) const;
-  void GetCurrentMatrix(CFX_Matrix& matrix) { matrix = m_curMatrix; }
-  void UpdateRects(CFX_RectArray& rects);
-  void UpdateView(CPDFSDK_Annot* pAnnot);
-  const std::vector<CPDFSDK_Annot*>& GetAnnotList() const {
-    return m_fxAnnotArray;
-  }
-
-  int GetPageIndex();
-  void LoadFXAnnots();
-  void SetValid(FX_BOOL bValid) { m_bValid = bValid; }
-  FX_BOOL IsValid() { return m_bValid; }
-  void SetLock(FX_BOOL bLocked) { m_bLocked = bLocked; }
-  FX_BOOL IsLocked() { return m_bLocked; }
-#ifndef PDF_ENABLE_XFA
-  void TakeOverPage() { m_bTakeOverPage = TRUE; }
-#endif  // PDF_ENABLE_XFA
-
- private:
-  void PageView_OnHighlightFormFields(CFX_RenderDevice* pDevice,
-                                      CPDFSDK_Widget* pWidget);
-
-  CFX_Matrix m_curMatrix;
-  UnderlyingPageType* m_page;
-  std::unique_ptr<CPDF_AnnotList> m_pAnnotList;
-  std::vector<CPDFSDK_Annot*> m_fxAnnotArray;
-  CPDFSDK_Document* m_pSDKDoc;
-#ifdef PDF_ENABLE_XFA
-  CPDFSDK_Annot* m_CaptureWidget;
-#else  // PDF_ENABLE_XFA
-  CPDFSDK_Widget* m_CaptureWidget;
-  FX_BOOL m_bTakeOverPage;
-#endif  // PDF_ENABLE_XFA
-  FX_BOOL m_bEnterWidget;
-  FX_BOOL m_bExitWidget;
-  FX_BOOL m_bOnWidget;
-  FX_BOOL m_bValid;
-  FX_BOOL m_bLocked;
-};
-
-template <class TYPE>
-class CGW_ArrayTemplate : public CFX_ArrayTemplate<TYPE> {
- public:
-  CGW_ArrayTemplate() {}
-  ~CGW_ArrayTemplate() {}
-
-  typedef int (*LP_COMPARE)(TYPE p1, TYPE p2);
-
-  void Sort(LP_COMPARE pCompare, FX_BOOL bAscent = TRUE) {
-    int nSize = this->GetSize();
-    QuickSort(0, nSize - 1, bAscent, pCompare);
-  }
-
- private:
-  void QuickSort(FX_UINT nStartPos,
-                 FX_UINT nStopPos,
-                 FX_BOOL bAscend,
-                 LP_COMPARE pCompare) {
-    if (nStartPos >= nStopPos)
-      return;
-
-    if ((nStopPos - nStartPos) == 1) {
-      TYPE Value1 = this->GetAt(nStartPos);
-      TYPE Value2 = this->GetAt(nStopPos);
-
-      int iGreate = (*pCompare)(Value1, Value2);
-      if ((bAscend && iGreate > 0) || (!bAscend && iGreate < 0)) {
-        this->SetAt(nStartPos, Value2);
-        this->SetAt(nStopPos, Value1);
-      }
-      return;
-    }
-
-    FX_UINT m = nStartPos + (nStopPos - nStartPos) / 2;
-    FX_UINT i = nStartPos;
-
-    TYPE Value = this->GetAt(m);
-
-    while (i < m) {
-      TYPE temp = this->GetAt(i);
-
-      int iGreate = (*pCompare)(temp, Value);
-      if ((bAscend && iGreate > 0) || (!bAscend && iGreate < 0)) {
-        this->InsertAt(m + 1, temp);
-        this->RemoveAt(i);
-        m--;
-      } else {
-        i++;
-      }
-    }
-
-    FX_UINT j = nStopPos;
-
-    while (j > m) {
-      TYPE temp = this->GetAt(j);
-
-      int iGreate = (*pCompare)(temp, Value);
-      if ((bAscend && iGreate < 0) || (!bAscend && iGreate > 0)) {
-        this->RemoveAt(j);
-        this->InsertAt(m, temp);
-        m++;
-      } else {
-        j--;
-      }
-    }
-
-    if (nStartPos < m)
-      QuickSort(nStartPos, m, bAscend, pCompare);
-    if (nStopPos > m)
-      QuickSort(m, nStopPos, bAscend, pCompare);
-  }
-};
-
-#endif  // FPDFSDK_INCLUDE_FSDK_MGR_H_
diff --git a/fpdfsdk/include/fsdk_rendercontext.h b/fpdfsdk/include/fsdk_rendercontext.h
deleted file mode 100644
index 8c007b5..0000000
--- a/fpdfsdk/include/fsdk_rendercontext.h
+++ /dev/null
@@ -1,43 +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_RENDERCONTEXT_H_
-#define FPDFSDK_INCLUDE_FSDK_RENDERCONTEXT_H_
-
-#include "fsdk_define.h"
-#include "public/fpdf_progressive.h"
-
-// Everything about rendering is put here: for OOM recovery
-class CRenderContext {
- public:
-  CRenderContext() { Clear(); }
-  ~CRenderContext();
-
-  void Clear();
-
-  CFX_RenderDevice* m_pDevice;
-  CPDF_RenderContext* m_pContext;
-  CPDF_ProgressiveRenderer* m_pRenderer;
-  CPDF_AnnotList* m_pAnnots;
-  CPDF_RenderOptions* m_pOptions;
-#ifdef _WIN32_WCE
-  CFX_DIBitmap* m_pBitmap;
-  HBITMAP m_hBitmap;
-#endif
-};
-
-class IFSDK_PAUSE_Adapter : public IFX_Pause {
- public:
-  explicit IFSDK_PAUSE_Adapter(IFSDK_PAUSE* IPause);
-  ~IFSDK_PAUSE_Adapter() override;
-
-  FX_BOOL NeedToPauseNow() override;
-
- private:
-  IFSDK_PAUSE* m_IPause;
-};
-
-#endif  // FPDFSDK_INCLUDE_FSDK_RENDERCONTEXT_H_
diff --git a/fpdfsdk/include/fx_systemhandler.h b/fpdfsdk/include/fx_systemhandler.h
deleted file mode 100644
index 224e075..0000000
--- a/fpdfsdk/include/fx_systemhandler.h
+++ /dev/null
@@ -1,107 +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_FX_SYSTEMHANDLER_H_
-#define FPDFSDK_INCLUDE_FX_SYSTEMHANDLER_H_
-
-#include "core/include/fpdfapi/fpdf_parser.h"
-#include "core/include/fxcrt/fx_coordinates.h"
-#include "core/include/fxcrt/fx_system.h"
-
-class CPDF_Document;
-class CPDF_Font;
-
-typedef void* FX_HWND;
-typedef void* FX_HMENU;
-typedef void (*TimerCallback)(int32_t idEvent);
-
-typedef struct _FX_SYSTEMTIME {
-  _FX_SYSTEMTIME()
-      : wYear(0),
-        wMonth(0),
-        wDayOfWeek(0),
-        wDay(0),
-        wHour(0),
-        wMinute(0),
-        wSecond(0),
-        wMilliseconds(0) {}
-  FX_WORD wYear;
-  FX_WORD wMonth;
-  FX_WORD wDayOfWeek;
-  FX_WORD wDay;
-  FX_WORD wHour;
-  FX_WORD wMinute;
-  FX_WORD wSecond;
-  FX_WORD wMilliseconds;
-} FX_SYSTEMTIME;
-
-// cursor style
-#define FXCT_ARROW 0
-#define FXCT_NESW 1
-#define FXCT_NWSE 2
-#define FXCT_VBEAM 3
-#define FXCT_HBEAM 4
-#define FXCT_HAND 5
-
-class IFX_SystemHandler {
- public:
-  virtual ~IFX_SystemHandler() {}
-  virtual void InvalidateRect(FX_HWND hWnd, FX_RECT rect) = 0;
-  virtual void OutputSelectedRect(void* pFormFiller, CPDF_Rect& rect) = 0;
-
-  virtual FX_BOOL IsSelectionImplemented() = 0;
-
-  virtual CFX_WideString GetClipboardText(FX_HWND hWnd) = 0;
-  virtual FX_BOOL SetClipboardText(FX_HWND hWnd, CFX_WideString string) = 0;
-
-  virtual void ClientToScreen(FX_HWND hWnd, int32_t& x, int32_t& y) = 0;
-  virtual void ScreenToClient(FX_HWND hWnd, int32_t& x, int32_t& y) = 0;
-
-  /*cursor style
-  FXCT_ARROW
-  FXCT_NESW
-  FXCT_NWSE
-  FXCT_VBEAM
-  FXCT_HBEAM
-  FXCT_HAND
-  */
-  virtual void SetCursor(int32_t nCursorType) = 0;
-
-  virtual FX_HMENU CreatePopupMenu() = 0;
-  virtual FX_BOOL AppendMenuItem(FX_HMENU hMenu,
-                                 int32_t nIDNewItem,
-                                 CFX_WideString string) = 0;
-  virtual FX_BOOL EnableMenuItem(FX_HMENU hMenu,
-                                 int32_t nIDItem,
-                                 FX_BOOL bEnabled) = 0;
-  virtual int32_t TrackPopupMenu(FX_HMENU hMenu,
-                                 int32_t x,
-                                 int32_t y,
-                                 FX_HWND hParent) = 0;
-  virtual void DestroyMenu(FX_HMENU hMenu) = 0;
-
-  virtual CFX_ByteString GetNativeTrueTypeFont(int32_t nCharset) = 0;
-  virtual FX_BOOL FindNativeTrueTypeFont(int32_t nCharset,
-                                         CFX_ByteString sFontFaceName) = 0;
-  virtual CPDF_Font* AddNativeTrueTypeFontToPDF(CPDF_Document* pDoc,
-                                                CFX_ByteString sFontFaceName,
-                                                uint8_t nCharset) = 0;
-
-  virtual int32_t SetTimer(int32_t uElapse, TimerCallback lpTimerFunc) = 0;
-  virtual void KillTimer(int32_t nID) = 0;
-
-  virtual FX_BOOL IsSHIFTKeyDown(FX_DWORD nFlag) = 0;
-  virtual FX_BOOL IsCTRLKeyDown(FX_DWORD nFlag) = 0;
-  virtual FX_BOOL IsALTKeyDown(FX_DWORD nFlag) = 0;
-  virtual FX_BOOL IsINSERTKeyDown(FX_DWORD nFlag) = 0;
-
-  virtual FX_SYSTEMTIME GetLocalTime() = 0;
-
-  virtual int32_t GetCharSet() = 0;
-  virtual void SetCharSet(int32_t nCharSet) = 0;
-};
-
-#endif  // FPDFSDK_INCLUDE_FX_SYSTEMHANDLER_H_
diff --git a/fpdfsdk/include/fxedit/fx_edit.h b/fpdfsdk/include/fxedit/fx_edit.h
deleted file mode 100644
index a8f5bba..0000000
--- a/fpdfsdk/include/fxedit/fx_edit.h
+++ /dev/null
@@ -1,576 +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_FXEDIT_FX_EDIT_H_
-#define FPDFSDK_INCLUDE_FXEDIT_FX_EDIT_H_
-
-#include "core/include/fpdfapi/fpdf_parser.h"
-#include "core/include/fxcrt/fx_basic.h"
-#include "core/include/fxge/fx_dib.h"
-
-class CFX_RenderDevice;
-class CPDF_Font;
-class CFX_Matrix;
-class CPDF_PageObjects;
-class CPDF_Point;
-class CPDF_TextObject;
-class IFX_Edit;
-class IFX_Edit_FontMap;
-class IFX_Edit_Iterator;
-class IFX_Edit_Notify;
-class IFX_Edit_UndoItem;
-class IFX_List;
-class IFX_List_Notify;
-class IFX_SystemHandler;
-class IPDF_VariableText;
-class IPDF_VariableText_Provider;
-struct CPVT_Line;
-struct CPVT_SecProps;
-struct CPVT_Section;
-struct CPVT_Word;
-struct CPVT_WordPlace;
-struct CPVT_WordProps;
-struct CPVT_WordRange;
-
-#define PVTWORD_STYLE_NORMAL 0x0000L
-#define PVTWORD_STYLE_HIGHLIGHT 0x0001L
-#define PVTWORD_STYLE_UNDERLINE 0x0002L
-#define PVTWORD_STYLE_CROSSOUT 0x0004L
-#define PVTWORD_STYLE_SQUIGGLY 0x0008L
-#define PVTWORD_STYLE_DUALCROSSOUT 0x0010L
-#define PVTWORD_STYLE_BOLD 0x0020L
-#define PVTWORD_STYLE_ITALIC 0x0040L
-
-#define FX_EDIT_ISLATINWORD(u)                  \
-  (u == 0x2D || (u <= 0x005A && u >= 0x0041) || \
-   (u <= 0x007A && u >= 0x0061) || (u <= 0x02AF && u >= 0x00C0))
-
-#ifndef DEFAULT_CHARSET
-#define DEFAULT_CHARSET 1
-#endif
-
-class IFX_Edit_FontMap {
- public:
-  virtual ~IFX_Edit_FontMap() {}
-  // map a fontindex to pdf font.
-  virtual CPDF_Font* GetPDFFont(int32_t nFontIndex) = 0;
-  // get the alias of a pdf font.
-  virtual CFX_ByteString GetPDFFontAlias(int32_t nFontIndex) = 0;
-  // get the index of a font that can show a word.
-  virtual int32_t GetWordFontIndex(FX_WORD word,
-                                   int32_t charset,
-                                   int32_t nFontIndex) = 0;
-  // get the charcode of word from unicode
-  virtual int32_t CharCodeFromUnicode(int32_t nFontIndex, FX_WORD word) = 0;
-  // get the charset of unicode
-  virtual int32_t CharSetFromUnicode(FX_WORD word, int32_t nOldCharset) = 0;
-};
-
-class IFX_Edit_Notify {
- public:
-  virtual ~IFX_Edit_Notify() {}
-  // set the horizontal scrollbar information.
-  virtual void IOnSetScrollInfoX(FX_FLOAT fPlateMin,
-                                 FX_FLOAT fPlateMax,
-                                 FX_FLOAT fContentMin,
-                                 FX_FLOAT fContentMax,
-                                 FX_FLOAT fSmallStep,
-                                 FX_FLOAT fBigStep) = 0;
-  // set the vertical scrollbar information.
-  virtual void IOnSetScrollInfoY(FX_FLOAT fPlateMin,
-                                 FX_FLOAT fPlateMax,
-                                 FX_FLOAT fContentMin,
-                                 FX_FLOAT fContentMax,
-                                 FX_FLOAT fSmallStep,
-                                 FX_FLOAT fBigStep) = 0;
-  // set the position of horizontal scrollbar.
-  virtual void IOnSetScrollPosX(FX_FLOAT fx) = 0;
-  // set the position of vertical scrollbar.
-  virtual void IOnSetScrollPosY(FX_FLOAT fy) = 0;
-  // set the caret information.
-  virtual void IOnSetCaret(FX_BOOL bVisible,
-                           const CPDF_Point& ptHead,
-                           const CPDF_Point& ptFoot,
-                           const CPVT_WordPlace& place) = 0;
-  // if the caret position is changed ,send the information of current postion
-  // to user.
-  virtual void IOnCaretChange(const CPVT_SecProps& secProps,
-                              const CPVT_WordProps& wordProps) = 0;
-  // if the text area is changed, send the information to user.
-  virtual void IOnContentChange(const CPDF_Rect& rcContent) = 0;
-  // Invalidate the rectangle relative to the bounding box of edit.
-  virtual void IOnInvalidateRect(CPDF_Rect* pRect) = 0;
-};
-
-class IFX_Edit_OprNotify {
- public:
-  virtual ~IFX_Edit_OprNotify() {}
-
-  // OprType: 0
-  virtual void OnInsertWord(const CPVT_WordPlace& place,
-                            const CPVT_WordPlace& oldplace) = 0;
-  // OprType: 1
-  virtual void OnInsertReturn(const CPVT_WordPlace& place,
-                              const CPVT_WordPlace& oldplace) = 0;
-  // OprType: 2
-  virtual void OnBackSpace(const CPVT_WordPlace& place,
-                           const CPVT_WordPlace& oldplace) = 0;
-  // OprType: 3
-  virtual void OnDelete(const CPVT_WordPlace& place,
-                        const CPVT_WordPlace& oldplace) = 0;
-  // OprType: 4
-  virtual void OnClear(const CPVT_WordPlace& place,
-                       const CPVT_WordPlace& oldplace) = 0;
-  // OprType: 5
-  virtual void OnInsertText(const CPVT_WordPlace& place,
-                            const CPVT_WordPlace& oldplace) = 0;
-  // OprType: 6
-  virtual void OnSetText(const CPVT_WordPlace& place,
-                         const CPVT_WordPlace& oldplace) = 0;
-  //
-  virtual void OnAddUndo(IFX_Edit_UndoItem* pUndoItem) = 0;
-};
-
-class IFX_Edit_Iterator {
- public:
-  virtual ~IFX_Edit_Iterator() {}
-
- public:
-  // move the current position to the next word.
-  virtual FX_BOOL NextWord() = 0;
-  // move the current position to the next line.
-  virtual FX_BOOL NextLine() = 0;
-  // move the current position to the next section.
-  virtual FX_BOOL NextSection() = 0;
-
-  // move the current position to the previous word.
-  virtual FX_BOOL PrevWord() = 0;
-  // move the current position to the previous line.
-  virtual FX_BOOL PrevLine() = 0;
-  // move the current position to the previous section.
-  virtual FX_BOOL PrevSection() = 0;
-
-  // get the information of the current word.
-  virtual FX_BOOL GetWord(CPVT_Word& word) const = 0;
-  // get the information of the current line.
-  virtual FX_BOOL GetLine(CPVT_Line& line) const = 0;
-  // get the information of the current section.
-  virtual FX_BOOL GetSection(CPVT_Section& section) const = 0;
-  // set the current position.
-  virtual void SetAt(int32_t nWordIndex) = 0;
-  // set the current position.
-  virtual void SetAt(const CPVT_WordPlace& place) = 0;
-  // get the current position.
-  virtual const CPVT_WordPlace& GetAt() const = 0;
-
-  // get the edit which this iterator belongs to
-  virtual IFX_Edit* GetEdit() const = 0;
-};
-
-class IFX_Edit_UndoItem {
- public:
-  virtual ~IFX_Edit_UndoItem() {}
-
-  virtual void Undo() = 0;
-  virtual void Redo() = 0;
-  virtual CFX_WideString GetUndoTitle() = 0;
-};
-
-class IFX_Edit {
- public:
-  static IFX_Edit* NewEdit();
-  static void DelEdit(IFX_Edit* pEdit);
-
-  // set a IFX_Edit_FontMap pointer implemented by user.
-  virtual void SetFontMap(IFX_Edit_FontMap* pFontMap) = 0;
-  // if user don't like to use FontMap, implement VTProvider and set it
-  // directly.
-  virtual void SetVTProvider(IPDF_VariableText_Provider* pProvider) = 0;
-  // set a IFX_Edit_Notify pointer implemented by user.
-  virtual void SetNotify(IFX_Edit_Notify* pNotify) = 0;
-  virtual void SetOprNotify(IFX_Edit_OprNotify* pOprNotify) = 0;
-  // get a pointer allocated by CPDF_Edit, by this pointer, user can iterate the
-  // contents of edit, but don't need to release.
-  virtual IFX_Edit_Iterator* GetIterator() = 0;
-  // get a VT pointer relative to this edit.
-  virtual IPDF_VariableText* GetVariableText() = 0;
-  // get the IFX_Edit_FontMap pointer set by user.
-  virtual IFX_Edit_FontMap* GetFontMap() = 0;
-
-  // initialize the edit.
-  virtual void Initialize() = 0;
-
-  // set the bounding box of the text area.
-  virtual void SetPlateRect(const CPDF_Rect& rect, FX_BOOL bPaint = TRUE) = 0;
-  // set the scroll origin
-  virtual void SetScrollPos(const CPDF_Point& point) = 0;
-
-  // set the horizontal text alignment in text box, nFormat (0:left 1:middle
-  // 2:right).
-  virtual void SetAlignmentH(int32_t nFormat = 0, FX_BOOL bPaint = TRUE) = 0;
-  // set the vertical text alignment in text box, nFormat (0:top 1:center
-  // 2:bottom).
-  virtual void SetAlignmentV(int32_t nFormat = 0, FX_BOOL bPaint = TRUE) = 0;
-  // if the text is shown in secret , set a character for substitute.
-  virtual void SetPasswordChar(FX_WORD wSubWord = '*',
-                               FX_BOOL bPaint = TRUE) = 0;
-  // set the maximal count of words of the text.
-  virtual void SetLimitChar(int32_t nLimitChar = 0, FX_BOOL bPaint = TRUE) = 0;
-  // if set the count of charArray , then all words is shown in equal space.
-  virtual void SetCharArray(int32_t nCharArray = 0, FX_BOOL bPaint = TRUE) = 0;
-  // set the space of two characters.
-  virtual void SetCharSpace(FX_FLOAT fCharSpace = 0.0f,
-                            FX_BOOL bPaint = TRUE) = 0;
-  // set the horizontal scale of all characters.
-  virtual void SetHorzScale(int32_t nHorzScale = 100,
-                            FX_BOOL bPaint = TRUE) = 0;
-  // set the leading of all lines
-  virtual void SetLineLeading(FX_FLOAT fLineLeading, FX_BOOL bPaint = TRUE) = 0;
-  // if set, CRLF is allowed.
-  virtual void SetMultiLine(FX_BOOL bMultiLine = TRUE,
-                            FX_BOOL bPaint = TRUE) = 0;
-  // if set, all words auto fit the width of the bounding box.
-  virtual void SetAutoReturn(FX_BOOL bAuto = TRUE, FX_BOOL bPaint = TRUE) = 0;
-  // if set, a font size is calculated to full fit the bounding box.
-  virtual void SetAutoFontSize(FX_BOOL bAuto = TRUE, FX_BOOL bPaint = TRUE) = 0;
-  // is set, the text is allowed to scroll.
-  virtual void SetAutoScroll(FX_BOOL bAuto = TRUE, FX_BOOL bPaint = TRUE) = 0;
-  // set the font size of all words.
-  virtual void SetFontSize(FX_FLOAT fFontSize, FX_BOOL bPaint = TRUE) = 0;
-  // the text is allowed to auto-scroll, allow the text overflow?
-  virtual void SetTextOverflow(FX_BOOL bAllowed = FALSE,
-                               FX_BOOL bPaint = TRUE) = 0;
-
-  // query if the edit is richedit.
-  virtual FX_BOOL IsRichText() const = 0;
-  // set the edit is richedit.
-  virtual void SetRichText(FX_BOOL bRichText = TRUE, FX_BOOL bPaint = TRUE) = 0;
-  // set the fontsize of selected text.
-  virtual FX_BOOL SetRichFontSize(FX_FLOAT fFontSize) = 0;
-  // set the fontindex of selected text, user can change the font of selected
-  // text.
-  virtual FX_BOOL SetRichFontIndex(int32_t nFontIndex) = 0;
-  // set the textcolor of selected text.
-  virtual FX_BOOL SetRichTextColor(FX_COLORREF dwColor) = 0;
-  // set the text script type of selected text. (0:normal 1:superscript
-  // 2:subscript)
-  virtual FX_BOOL SetRichTextScript(int32_t nScriptType) = 0;
-  // set the bold font style of selected text.
-  virtual FX_BOOL SetRichTextBold(FX_BOOL bBold = TRUE) = 0;
-  // set the italic font style of selected text.
-  virtual FX_BOOL SetRichTextItalic(FX_BOOL bItalic = TRUE) = 0;
-  // set the underline style of selected text.
-  virtual FX_BOOL SetRichTextUnderline(FX_BOOL bUnderline = TRUE) = 0;
-  // set the crossout style of selected text.
-  virtual FX_BOOL SetRichTextCrossout(FX_BOOL bCrossout = TRUE) = 0;
-  // set the charspace of selected text, in user coordinate.
-  virtual FX_BOOL SetRichTextCharSpace(FX_FLOAT fCharSpace) = 0;
-  // set the horizontal scale of selected text, default value is 100.
-  virtual FX_BOOL SetRichTextHorzScale(int32_t nHorzScale = 100) = 0;
-  // set the leading of selected section, in user coordinate.
-  virtual FX_BOOL SetRichTextLineLeading(FX_FLOAT fLineLeading) = 0;
-  // set the indent of selected section, in user coordinate.
-  virtual FX_BOOL SetRichTextLineIndent(FX_FLOAT fLineIndent) = 0;
-  // set the alignment of selected section, nAlignment(0:left 1:middle 2:right)
-  virtual FX_BOOL SetRichTextAlignment(int32_t nAlignment) = 0;
-
-  // set the selected range of text.
-  // if nStartChar == 0 and nEndChar == -1, select all the text.
-  virtual void SetSel(int32_t nStartChar, int32_t nEndChar) = 0;
-  // get the selected range of text.
-  virtual void GetSel(int32_t& nStartChar, int32_t& nEndChar) const = 0;
-  // select all the text.
-  virtual void SelectAll() = 0;
-  // set text is not selected.
-  virtual void SelectNone() = 0;
-  // get the caret position.
-  virtual int32_t GetCaret() const = 0;
-  virtual CPVT_WordPlace GetCaretWordPlace() const = 0;
-  // get the string of selected text.
-  virtual CFX_WideString GetSelText() const = 0;
-  // get the text conent
-  virtual CFX_WideString GetText() const = 0;
-  // query if any text is selected.
-  virtual FX_BOOL IsSelected() const = 0;
-  // get the scroll origin
-  virtual CPDF_Point GetScrollPos() const = 0;
-  // get the bounding box of the text area.
-  virtual CPDF_Rect GetPlateRect() const = 0;
-  // get the fact area of the text.
-  virtual CPDF_Rect GetContentRect() const = 0;
-  // get the visible word range
-  virtual CPVT_WordRange GetVisibleWordRange() const = 0;
-  // get the whole word range
-  virtual CPVT_WordRange GetWholeWordRange() const = 0;
-  // get the word range of select text
-  virtual CPVT_WordRange GetSelectWordRange() const = 0;
-
-  // send the mousedown message to edit for response.
-  // if Shift key is hold, bShift is TRUE, is Ctrl key is hold, bCtrl is TRUE.
-  virtual void OnMouseDown(const CPDF_Point& point,
-                           FX_BOOL bShift,
-                           FX_BOOL bCtrl) = 0;
-  // send the mousemove message to edit when mouse down is TRUE.
-  virtual void OnMouseMove(const CPDF_Point& point,
-                           FX_BOOL bShift,
-                           FX_BOOL bCtrl) = 0;
-  // send the UP key message to edit.
-  virtual void OnVK_UP(FX_BOOL bShift, FX_BOOL bCtrl) = 0;
-  // send the DOWN key message to edit.
-  virtual void OnVK_DOWN(FX_BOOL bShift, FX_BOOL bCtrl) = 0;
-  // send the LEFT key message to edit.
-  virtual void OnVK_LEFT(FX_BOOL bShift, FX_BOOL bCtrl) = 0;
-  // send the RIGHT key message to edit.
-  virtual void OnVK_RIGHT(FX_BOOL bShift, FX_BOOL bCtrl) = 0;
-  // send the HOME key message to edit.
-  virtual void OnVK_HOME(FX_BOOL bShift, FX_BOOL bCtrl) = 0;
-  // send the END key message to edit.
-  virtual void OnVK_END(FX_BOOL bShift, FX_BOOL bCtrl) = 0;
-
-  // put text into edit.
-  virtual void SetText(const FX_WCHAR* text,
-                       int32_t charset = DEFAULT_CHARSET,
-                       const CPVT_SecProps* pSecProps = NULL,
-                       const CPVT_WordProps* pWordProps = NULL) = 0;
-  // insert a word into the edit.
-  virtual FX_BOOL InsertWord(FX_WORD word,
-                             int32_t charset = DEFAULT_CHARSET,
-                             const CPVT_WordProps* pWordProps = NULL) = 0;
-  // insert a return into the edit.
-  virtual FX_BOOL InsertReturn(const CPVT_SecProps* pSecProps = NULL,
-                               const CPVT_WordProps* pWordProps = NULL) = 0;
-  // insert text into the edit.
-  virtual FX_BOOL InsertText(const FX_WCHAR* text,
-                             int32_t charset = DEFAULT_CHARSET,
-                             const CPVT_SecProps* pSecProps = NULL,
-                             const CPVT_WordProps* pWordProps = NULL) = 0;
-  // do backspace operation.
-  virtual FX_BOOL Backspace() = 0;
-  // do delete operation.
-  virtual FX_BOOL Delete() = 0;
-  // delete the selected text.
-  virtual FX_BOOL Clear() = 0;
-
-  // do Redo operation.
-  virtual FX_BOOL Redo() = 0;
-  // do Undo operation.
-  virtual FX_BOOL Undo() = 0;
-  // move caret
-  virtual void SetCaret(int32_t nPos) = 0;
-
-  // arrange all words over again
-  virtual void Paint() = 0;
-
-  // allow to refresh screen?
-  virtual void EnableRefresh(FX_BOOL bRefresh) = 0;
-
-  virtual void RefreshWordRange(const CPVT_WordRange& wr) = 0;
-
-  // allow undo/redo?
-  virtual void EnableUndo(FX_BOOL bUndo) = 0;
-
-  // allow notify?
-  virtual void EnableNotify(FX_BOOL bNotify) = 0;
-
-  // allow opr notify?
-  virtual void EnableOprNotify(FX_BOOL bNotify) = 0;
-
-  // map word place to word index.
-  virtual int32_t WordPlaceToWordIndex(const CPVT_WordPlace& place) const = 0;
-  // map word index to word place.
-  virtual CPVT_WordPlace WordIndexToWordPlace(int32_t index) const = 0;
-
-  // get the beginning position of a line
-  virtual CPVT_WordPlace GetLineBeginPlace(
-      const CPVT_WordPlace& place) const = 0;
-
-  // get the ending position of a line
-  virtual CPVT_WordPlace GetLineEndPlace(const CPVT_WordPlace& place) const = 0;
-
-  // get the beginning position of a section
-  virtual CPVT_WordPlace GetSectionBeginPlace(
-      const CPVT_WordPlace& place) const = 0;
-
-  // get the ending position of a section
-  virtual CPVT_WordPlace GetSectionEndPlace(
-      const CPVT_WordPlace& place) const = 0;
-
-  // search a wordplace form point
-  virtual CPVT_WordPlace SearchWordPlace(const CPDF_Point& point) const = 0;
-
-  // get the font size of non_rich text or default font size of richtext.
-  virtual FX_FLOAT GetFontSize() const = 0;
-  // get the mask character.
-  virtual FX_WORD GetPasswordChar() const = 0;
-  // get the count of charArray
-  virtual int32_t GetCharArray() const = 0;
-  // get the horizontal scale of all characters
-  virtual int32_t GetHorzScale() const = 0;
-  // get the space of two characters
-  virtual FX_FLOAT GetCharSpace() const = 0;
-  // get the latin words of specified range
-  virtual CFX_WideString GetRangeText(const CPVT_WordRange& range) const = 0;
-  // is the text full in bounding box
-  virtual FX_BOOL IsTextFull() const = 0;
-  virtual FX_BOOL CanUndo() const = 0;
-  virtual FX_BOOL CanRedo() const = 0;
-  // if the content is changed after settext?
-  virtual FX_BOOL IsModified() const = 0;
-  // get the total words in edit
-  virtual int32_t GetTotalWords() const = 0;
-
-  virtual void AddUndoItem(IFX_Edit_UndoItem* pUndoItem) = 0;
-
-  static CFX_ByteString GetEditAppearanceStream(
-      IFX_Edit* pEdit,
-      const CPDF_Point& ptOffset,
-      const CPVT_WordRange* pRange = NULL,
-      FX_BOOL bContinuous = TRUE,
-      FX_WORD SubWord = 0);
-  static CFX_ByteString GetSelectAppearanceStream(
-      IFX_Edit* pEdit,
-      const CPDF_Point& ptOffset,
-      const CPVT_WordRange* pRange = NULL);
-  static void DrawEdit(CFX_RenderDevice* pDevice,
-                       CFX_Matrix* pUser2Device,
-                       IFX_Edit* pEdit,
-                       FX_COLORREF crTextFill,
-                       FX_COLORREF crTextStroke,
-                       const CPDF_Rect& rcClip,
-                       const CPDF_Point& ptOffset,
-                       const CPVT_WordRange* pRange,
-                       IFX_SystemHandler* pSystemHandler,
-                       void* pFFLData);
-  static void DrawUnderline(CFX_RenderDevice* pDevice,
-                            CFX_Matrix* pUser2Device,
-                            IFX_Edit* pEdit,
-                            FX_COLORREF color,
-                            const CPDF_Rect& rcClip,
-                            const CPDF_Point& ptOffset,
-                            const CPVT_WordRange* pRange);
-  static void DrawRichEdit(CFX_RenderDevice* pDevice,
-                           CFX_Matrix* pUser2Device,
-                           IFX_Edit* pEdit,
-                           const CPDF_Rect& rcClip,
-                           const CPDF_Point& ptOffset,
-                           const CPVT_WordRange* pRange);
-  static void GeneratePageObjects(
-      CPDF_PageObjects* pPageObjects,
-      IFX_Edit* pEdit,
-      const CPDF_Point& ptOffset,
-      const CPVT_WordRange* pRange,
-      FX_COLORREF crText,
-      CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray);
-  static void GenerateRichPageObjects(
-      CPDF_PageObjects* pPageObjects,
-      IFX_Edit* pEdit,
-      const CPDF_Point& ptOffset,
-      const CPVT_WordRange* pRange,
-      CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray);
-  static void GenerateUnderlineObjects(CPDF_PageObjects* pPageObjects,
-                                       IFX_Edit* pEdit,
-                                       const CPDF_Point& ptOffset,
-                                       const CPVT_WordRange* pRange,
-                                       FX_COLORREF color);
-
- protected:
-  virtual ~IFX_Edit() {}
-};
-
-class IFX_List_Notify {
- public:
-  // set the horizontal scrollbar information.
-  virtual void IOnSetScrollInfoX(FX_FLOAT fPlateMin,
-                                 FX_FLOAT fPlateMax,
-                                 FX_FLOAT fContentMin,
-                                 FX_FLOAT fContentMax,
-                                 FX_FLOAT fSmallStep,
-                                 FX_FLOAT fBigStep) = 0;
-  // set the vertical scrollbar information.
-  virtual void IOnSetScrollInfoY(FX_FLOAT fPlateMin,
-                                 FX_FLOAT fPlateMax,
-                                 FX_FLOAT fContentMin,
-                                 FX_FLOAT fContentMax,
-                                 FX_FLOAT fSmallStep,
-                                 FX_FLOAT fBigStep) = 0;
-  // set the position of horizontal scrollbar.
-  virtual void IOnSetScrollPosX(FX_FLOAT fx) = 0;
-  // set the position of vertical scrollbar.
-  virtual void IOnSetScrollPosY(FX_FLOAT fy) = 0;
-  // Invalidate the rectangle relative to the bounding box of edit.
-  virtual void IOnInvalidateRect(CPDF_Rect* pRect) = 0;
-
- protected:
-  virtual ~IFX_List_Notify() {}
-};
-
-class IFX_List {
- public:
-  static IFX_List* NewList();
-  static void DelList(IFX_List* pList);
-
-  virtual void SetFontMap(IFX_Edit_FontMap* pFontMap) = 0;
-  virtual void SetNotify(IFX_List_Notify* pNotify) = 0;
-
-  virtual void SetPlateRect(const CPDF_Rect& rect) = 0;
-  virtual void SetFontSize(FX_FLOAT fFontSize) = 0;
-
-  virtual CPDF_Rect GetPlateRect() const = 0;
-  virtual CPDF_Rect GetContentRect() const = 0;
-
-  virtual FX_FLOAT GetFontSize() const = 0;
-  virtual IFX_Edit* GetItemEdit(int32_t nIndex) const = 0;
-  virtual int32_t GetCount() const = 0;
-  virtual FX_BOOL IsItemSelected(int32_t nIndex) const = 0;
-  virtual FX_FLOAT GetFirstHeight() const = 0;
-
-  virtual void SetMultipleSel(FX_BOOL bMultiple) = 0;
-  virtual FX_BOOL IsMultipleSel() const = 0;
-  virtual FX_BOOL IsValid(int32_t nItemIndex) const = 0;
-  virtual int32_t FindNext(int32_t nIndex, FX_WCHAR nChar) const = 0;
-
-  virtual void SetScrollPos(const CPDF_Point& point) = 0;
-  virtual void ScrollToListItem(int32_t nItemIndex) = 0;
-  virtual CPDF_Rect GetItemRect(int32_t nIndex) const = 0;
-  virtual int32_t GetCaret() const = 0;
-  virtual int32_t GetSelect() const = 0;
-  virtual int32_t GetTopItem() const = 0;
-  virtual int32_t GetItemIndex(const CPDF_Point& point) const = 0;
-  virtual int32_t GetFirstSelected() const = 0;
-
-  virtual void AddString(const FX_WCHAR* string) = 0;
-  virtual void SetTopItem(int32_t nIndex) = 0;
-  virtual void Select(int32_t nItemIndex) = 0;
-  virtual void SetCaret(int32_t nItemIndex) = 0;
-  virtual void Empty() = 0;
-  virtual void Cancel() = 0;
-  virtual CFX_WideString GetText() const = 0;
-
-  virtual void OnMouseDown(const CPDF_Point& point,
-                           FX_BOOL bShift,
-                           FX_BOOL bCtrl) = 0;
-  virtual void OnMouseMove(const CPDF_Point& point,
-                           FX_BOOL bShift,
-                           FX_BOOL bCtrl) = 0;
-  virtual void OnVK_UP(FX_BOOL bShift, FX_BOOL bCtrl) = 0;
-  virtual void OnVK_DOWN(FX_BOOL bShift, FX_BOOL bCtrl) = 0;
-  virtual void OnVK_LEFT(FX_BOOL bShift, FX_BOOL bCtrl) = 0;
-  virtual void OnVK_RIGHT(FX_BOOL bShift, FX_BOOL bCtrl) = 0;
-  virtual void OnVK_HOME(FX_BOOL bShift, FX_BOOL bCtrl) = 0;
-  virtual void OnVK_END(FX_BOOL bShift, FX_BOOL bCtrl) = 0;
-  virtual void OnVK(int32_t nItemIndex, FX_BOOL bShift, FX_BOOL bCtrl) = 0;
-  virtual FX_BOOL OnChar(FX_WORD nChar, FX_BOOL bShift, FX_BOOL bCtrl) = 0;
-
- protected:
-  virtual ~IFX_List() {}
-};
-
-CFX_ByteString GetPDFWordString(IFX_Edit_FontMap* pFontMap,
-                                int32_t nFontIndex,
-                                FX_WORD Word,
-                                FX_WORD SubWord);
-
-#endif  // FPDFSDK_INCLUDE_FXEDIT_FX_EDIT_H_
diff --git a/fpdfsdk/include/fxedit/fxet_edit.h b/fpdfsdk/include/fxedit/fxet_edit.h
deleted file mode 100644
index d1df381..0000000
--- a/fpdfsdk/include/fxedit/fxet_edit.h
+++ /dev/null
@@ -1,816 +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_FXEDIT_FXET_EDIT_H_
-#define FPDFSDK_INCLUDE_FXEDIT_FXET_EDIT_H_
-
-#include "core/include/fpdfdoc/fpdf_vt.h"
-#include "fpdfsdk/include/fxedit/fx_edit.h"
-
-class CFX_Edit;
-class CFX_Edit_Iterator;
-class CFX_Edit_Provider;
-
-#define FX_EDIT_IsFloatZero(f) (f < 0.0001 && f > -0.0001)
-#define FX_EDIT_IsFloatEqual(fa, fb) FX_EDIT_IsFloatZero(fa - fb)
-#define FX_EDIT_IsFloatBigger(fa, fb) (fa > fb && !FX_EDIT_IsFloatEqual(fa, fb))
-#define FX_EDIT_IsFloatSmaller(fa, fb) \
-  (fa < fb && !FX_EDIT_IsFloatEqual(fa, fb))
-
-/* ------------------------- CFX_Edit_Refresh ---------------------------- */
-
-enum REFRESH_PLAN_E { RP_ANALYSE, RP_NOANALYSE, RP_OPTIONAL };
-
-enum EDIT_PROPS_E {
-  EP_LINELEADING,
-  EP_LINEINDENT,
-  EP_ALIGNMENT,
-  EP_FONTINDEX,
-  EP_FONTSIZE,
-  EP_WORDCOLOR,
-  EP_SCRIPTTYPE,
-  EP_UNDERLINE,
-  EP_CROSSOUT,
-  EP_CHARSPACE,
-  EP_HORZSCALE,
-  EP_BOLD,
-  EP_ITALIC
-};
-
-struct CFX_Edit_LineRect {
-  CFX_Edit_LineRect(const CPVT_WordRange& wrLine, const CPDF_Rect& rcLine)
-      : m_wrLine(wrLine), m_rcLine(rcLine) {}
-
-  FX_BOOL operator!=(const CFX_Edit_LineRect& linerect) const {
-    return FXSYS_memcmp(this, &linerect, sizeof(CFX_Edit_LineRect)) != 0;
-  }
-
-  FX_BOOL IsSameHeight(const CFX_Edit_LineRect& linerect) const {
-    return FX_EDIT_IsFloatZero(
-        (m_rcLine.top - m_rcLine.bottom) -
-        (linerect.m_rcLine.top - linerect.m_rcLine.bottom));
-  }
-
-  FX_BOOL IsSameTop(const CFX_Edit_LineRect& linerect) const {
-    return FX_EDIT_IsFloatZero(m_rcLine.top - linerect.m_rcLine.top);
-  }
-
-  FX_BOOL IsSameLeft(const CFX_Edit_LineRect& linerect) const {
-    return FX_EDIT_IsFloatZero(m_rcLine.left - linerect.m_rcLine.left);
-  }
-
-  FX_BOOL IsSameRight(const CFX_Edit_LineRect& linerect) const {
-    return FX_EDIT_IsFloatZero(m_rcLine.right - linerect.m_rcLine.right);
-  }
-
-  CPVT_WordRange m_wrLine;
-  CPDF_Rect m_rcLine;
-};
-
-class CFX_Edit_LineRectArray {
- public:
-  CFX_Edit_LineRectArray() {}
-
-  virtual ~CFX_Edit_LineRectArray() { Empty(); }
-
-  void Empty() {
-    for (int32_t i = 0, sz = m_LineRects.GetSize(); i < sz; i++)
-      delete m_LineRects.GetAt(i);
-
-    m_LineRects.RemoveAll();
-  }
-
-  void RemoveAll() { m_LineRects.RemoveAll(); }
-
-  void operator=(CFX_Edit_LineRectArray& rects) {
-    Empty();
-    for (int32_t i = 0, sz = rects.GetSize(); i < sz; i++)
-      m_LineRects.Add(rects.GetAt(i));
-
-    rects.RemoveAll();
-  }
-
-  void Add(const CPVT_WordRange& wrLine, const CPDF_Rect& rcLine) {
-    m_LineRects.Add(new CFX_Edit_LineRect(wrLine, rcLine));
-  }
-
-  int32_t GetSize() const { return m_LineRects.GetSize(); }
-
-  CFX_Edit_LineRect* GetAt(int32_t nIndex) const {
-    if (nIndex < 0 || nIndex >= m_LineRects.GetSize())
-      return NULL;
-
-    return m_LineRects.GetAt(nIndex);
-  }
-
-  CFX_ArrayTemplate<CFX_Edit_LineRect*> m_LineRects;
-};
-
-class CFX_Edit_RectArray {
- public:
-  CFX_Edit_RectArray() {}
-
-  virtual ~CFX_Edit_RectArray() { Empty(); }
-
-  void Empty() {
-    for (int32_t i = 0, sz = m_Rects.GetSize(); i < sz; i++)
-      delete m_Rects.GetAt(i);
-
-    m_Rects.RemoveAll();
-  }
-
-  void Add(const CPDF_Rect& rect) {
-    // check for overlapped area
-    for (int32_t i = 0, sz = m_Rects.GetSize(); i < sz; i++) {
-      CPDF_Rect* pRect = m_Rects.GetAt(i);
-      if (pRect && pRect->Contains(rect))
-        return;
-    }
-
-    m_Rects.Add(new CPDF_Rect(rect));
-  }
-
-  int32_t GetSize() const { return m_Rects.GetSize(); }
-
-  CPDF_Rect* GetAt(int32_t nIndex) const {
-    if (nIndex < 0 || nIndex >= m_Rects.GetSize())
-      return NULL;
-
-    return m_Rects.GetAt(nIndex);
-  }
-
-  CFX_ArrayTemplate<CPDF_Rect*> m_Rects;
-};
-
-class CFX_Edit_Refresh {
- public:
-  CFX_Edit_Refresh();
-  virtual ~CFX_Edit_Refresh();
-
-  void BeginRefresh();
-  void Push(const CPVT_WordRange& linerange, const CPDF_Rect& rect);
-  void NoAnalyse();
-  void Analyse(int32_t nAlignment);
-  void AddRefresh(const CPDF_Rect& rect);
-  const CFX_Edit_RectArray* GetRefreshRects() const;
-  void EndRefresh();
-
- private:
-  CFX_Edit_LineRectArray m_NewLineRects;
-  CFX_Edit_LineRectArray m_OldLineRects;
-  CFX_Edit_RectArray m_RefreshRects;
-};
-
-/* ------------------------- CFX_Edit_Select ---------------------------- */
-
-class CFX_Edit_Select {
- public:
-  CFX_Edit_Select() {}
-
-  CFX_Edit_Select(const CPVT_WordPlace& begin, const CPVT_WordPlace& end) {
-    Set(begin, end);
-  }
-
-  explicit CFX_Edit_Select(const CPVT_WordRange& range) {
-    Set(range.BeginPos, range.EndPos);
-  }
-
-  CPVT_WordRange ConvertToWordRange() const {
-    return CPVT_WordRange(BeginPos, EndPos);
-  }
-
-  void Default() {
-    BeginPos.Default();
-    EndPos.Default();
-  }
-
-  void Set(const CPVT_WordPlace& begin, const CPVT_WordPlace& end) {
-    BeginPos = begin;
-    EndPos = end;
-  }
-
-  void SetBeginPos(const CPVT_WordPlace& begin) { BeginPos = begin; }
-
-  void SetEndPos(const CPVT_WordPlace& end) { EndPos = end; }
-
-  FX_BOOL IsExist() const { return BeginPos != EndPos; }
-
-  FX_BOOL operator!=(const CPVT_WordRange& wr) const {
-    return wr.BeginPos != BeginPos || wr.EndPos != EndPos;
-  }
-
-  CPVT_WordPlace BeginPos, EndPos;
-};
-
-/* ------------------------- CFX_Edit_Undo ---------------------------- */
-
-class CFX_Edit_Undo {
- public:
-  explicit CFX_Edit_Undo(int32_t nBufsize);
-  virtual ~CFX_Edit_Undo();
-
-  void Undo();
-  void Redo();
-
-  void AddItem(IFX_Edit_UndoItem* pItem);
-
-  FX_BOOL CanUndo() const;
-  FX_BOOL CanRedo() const;
-  FX_BOOL IsModified() const;
-  FX_BOOL IsWorking() const;
-
-  void Reset();
-
-  IFX_Edit_UndoItem* GetItem(int32_t nIndex);
-  int32_t GetItemCount() { return m_UndoItemStack.GetSize(); }
-  int32_t GetCurUndoPos() { return m_nCurUndoPos; }
-
- private:
-  void SetBufSize(int32_t nSize) { m_nBufSize = nSize; }
-  int32_t GetBufSize() { return m_nBufSize; }
-
-  void RemoveHeads();
-  void RemoveTails();
-
- private:
-  CFX_ArrayTemplate<IFX_Edit_UndoItem*> m_UndoItemStack;
-
-  int32_t m_nCurUndoPos;
-  int32_t m_nBufSize;
-  FX_BOOL m_bModified;
-  FX_BOOL m_bVirgin;
-  FX_BOOL m_bWorking;
-};
-
-class CFX_Edit_UndoItem : public IFX_Edit_UndoItem {
- public:
-  CFX_Edit_UndoItem() : m_bFirst(TRUE), m_bLast(TRUE) {}
-  ~CFX_Edit_UndoItem() override {}
-
-  CFX_WideString GetUndoTitle() override { return L""; }
-
-  void SetFirst(FX_BOOL bFirst) { m_bFirst = bFirst; }
-  FX_BOOL IsFirst() { return m_bFirst; }
-  void SetLast(FX_BOOL bLast) { m_bLast = bLast; }
-  FX_BOOL IsLast() { return m_bLast; }
-
- private:
-  FX_BOOL m_bFirst;
-  FX_BOOL m_bLast;
-};
-
-class CFX_Edit_GroupUndoItem : public IFX_Edit_UndoItem {
- public:
-  explicit CFX_Edit_GroupUndoItem(const CFX_WideString& sTitle);
-  ~CFX_Edit_GroupUndoItem() override;
-
-  void Undo() override;
-  void Redo() override;
-  CFX_WideString GetUndoTitle() override;
-
-  void AddUndoItem(CFX_Edit_UndoItem* pUndoItem);
-  void UpdateItems();
-
- private:
-  CFX_WideString m_sTitle;
-  CFX_ArrayTemplate<CFX_Edit_UndoItem*> m_Items;
-};
-
-/* ------------------------- CFX_Edit_UndoItem derived classes
- * ---------------------------- */
-
-class CFXEU_InsertWord : public CFX_Edit_UndoItem {
- public:
-  CFXEU_InsertWord(CFX_Edit* pEdit,
-                   const CPVT_WordPlace& wpOldPlace,
-                   const CPVT_WordPlace& wpNewPlace,
-                   FX_WORD word,
-                   int32_t charset,
-                   const CPVT_WordProps* pWordProps);
-  ~CFXEU_InsertWord() override;
-
-  // CFX_Edit_UndoItem
-  void Redo() override;
-  void Undo() override;
-
- private:
-  CFX_Edit* m_pEdit;
-
-  CPVT_WordPlace m_wpOld;
-  CPVT_WordPlace m_wpNew;
-  FX_WORD m_Word;
-  int32_t m_nCharset;
-  CPVT_WordProps m_WordProps;
-};
-
-class CFXEU_InsertReturn : public CFX_Edit_UndoItem {
- public:
-  CFXEU_InsertReturn(CFX_Edit* pEdit,
-                     const CPVT_WordPlace& wpOldPlace,
-                     const CPVT_WordPlace& wpNewPlace,
-                     const CPVT_SecProps* pSecProps,
-                     const CPVT_WordProps* pWordProps);
-  ~CFXEU_InsertReturn() override;
-
-  // CFX_Edit_UndoItem
-  void Redo() override;
-  void Undo() override;
-
- private:
-  CFX_Edit* m_pEdit;
-
-  CPVT_WordPlace m_wpOld;
-  CPVT_WordPlace m_wpNew;
-  CPVT_SecProps m_SecProps;
-  CPVT_WordProps m_WordProps;
-};
-
-class CFXEU_Backspace : public CFX_Edit_UndoItem {
- public:
-  CFXEU_Backspace(CFX_Edit* pEdit,
-                  const CPVT_WordPlace& wpOldPlace,
-                  const CPVT_WordPlace& wpNewPlace,
-                  FX_WORD word,
-                  int32_t charset,
-                  const CPVT_SecProps& SecProps,
-                  const CPVT_WordProps& WordProps);
-  ~CFXEU_Backspace() override;
-
-  // CFX_Edit_UndoItem
-  void Redo() override;
-  void Undo() override;
-
- private:
-  CFX_Edit* m_pEdit;
-
-  CPVT_WordPlace m_wpOld;
-  CPVT_WordPlace m_wpNew;
-  FX_WORD m_Word;
-  int32_t m_nCharset;
-  CPVT_SecProps m_SecProps;
-  CPVT_WordProps m_WordProps;
-};
-
-class CFXEU_Delete : public CFX_Edit_UndoItem {
- public:
-  CFXEU_Delete(CFX_Edit* pEdit,
-               const CPVT_WordPlace& wpOldPlace,
-               const CPVT_WordPlace& wpNewPlace,
-               FX_WORD word,
-               int32_t charset,
-               const CPVT_SecProps& SecProps,
-               const CPVT_WordProps& WordProps,
-               FX_BOOL bSecEnd);
-  ~CFXEU_Delete() override;
-
-  // CFX_Edit_UndoItem
-  void Redo() override;
-  void Undo() override;
-
- private:
-  CFX_Edit* m_pEdit;
-
-  CPVT_WordPlace m_wpOld;
-  CPVT_WordPlace m_wpNew;
-  FX_WORD m_Word;
-  int32_t m_nCharset;
-  CPVT_SecProps m_SecProps;
-  CPVT_WordProps m_WordProps;
-  FX_BOOL m_bSecEnd;
-};
-
-class CFXEU_Clear : public CFX_Edit_UndoItem {
- public:
-  CFXEU_Clear(CFX_Edit* pEdit,
-              const CPVT_WordRange& wrSel,
-              const CFX_WideString& swText);
-  ~CFXEU_Clear() override;
-
-  // CFX_Edit_UndoItem
-  void Redo() override;
-  void Undo() override;
-
- private:
-  CFX_Edit* m_pEdit;
-
-  CPVT_WordRange m_wrSel;
-  CFX_WideString m_swText;
-};
-
-class CFXEU_ClearRich : public CFX_Edit_UndoItem {
- public:
-  CFXEU_ClearRich(CFX_Edit* pEdit,
-                  const CPVT_WordPlace& wpOldPlace,
-                  const CPVT_WordPlace& wpNewPlace,
-                  const CPVT_WordRange& wrSel,
-                  FX_WORD word,
-                  int32_t charset,
-                  const CPVT_SecProps& SecProps,
-                  const CPVT_WordProps& WordProps);
-  ~CFXEU_ClearRich() override;
-
-  // CFX_Edit_UndoItem
-  void Redo() override;
-  void Undo() override;
-
- private:
-  CFX_Edit* m_pEdit;
-
-  CPVT_WordPlace m_wpOld;
-  CPVT_WordPlace m_wpNew;
-  CPVT_WordRange m_wrSel;
-  FX_WORD m_Word;
-  int32_t m_nCharset;
-  CPVT_SecProps m_SecProps;
-  CPVT_WordProps m_WordProps;
-};
-
-class CFXEU_InsertText : public CFX_Edit_UndoItem {
- public:
-  CFXEU_InsertText(CFX_Edit* pEdit,
-                   const CPVT_WordPlace& wpOldPlace,
-                   const CPVT_WordPlace& wpNewPlace,
-                   const CFX_WideString& swText,
-                   int32_t charset,
-                   const CPVT_SecProps* pSecProps,
-                   const CPVT_WordProps* pWordProps);
-  ~CFXEU_InsertText() override;
-
-  // CFX_Edit_UndoItem
-  void Redo() override;
-  void Undo() override;
-
- private:
-  CFX_Edit* m_pEdit;
-
-  CPVT_WordPlace m_wpOld;
-  CPVT_WordPlace m_wpNew;
-  CFX_WideString m_swText;
-  int32_t m_nCharset;
-  CPVT_SecProps m_SecProps;
-  CPVT_WordProps m_WordProps;
-};
-
-class CFXEU_SetSecProps : public CFX_Edit_UndoItem {
- public:
-  CFXEU_SetSecProps(CFX_Edit* pEdit,
-                    const CPVT_WordPlace& place,
-                    EDIT_PROPS_E ep,
-                    const CPVT_SecProps& oldsecprops,
-                    const CPVT_WordProps& oldwordprops,
-                    const CPVT_SecProps& newsecprops,
-                    const CPVT_WordProps& newwordprops,
-                    const CPVT_WordRange& range);
-  ~CFXEU_SetSecProps() override;
-
-  // CFX_Edit_UndoItem
-  void Redo() override;
-  void Undo() override;
-
- private:
-  CFX_Edit* m_pEdit;
-  CPVT_WordPlace m_wpPlace;
-  CPVT_WordRange m_wrPlace;
-  EDIT_PROPS_E m_eProps;
-
-  CPVT_SecProps m_OldSecProps;
-  CPVT_SecProps m_NewSecProps;
-  CPVT_WordProps m_OldWordProps;
-  CPVT_WordProps m_NewWordProps;
-};
-
-class CFXEU_SetWordProps : public CFX_Edit_UndoItem {
- public:
-  CFXEU_SetWordProps(CFX_Edit* pEdit,
-                     const CPVT_WordPlace& place,
-                     EDIT_PROPS_E ep,
-                     const CPVT_WordProps& oldprops,
-                     const CPVT_WordProps& newprops,
-                     const CPVT_WordRange& range);
-  ~CFXEU_SetWordProps() override;
-
-  // CFX_Edit_UndoItem
-  void Redo() override;
-  void Undo() override;
-
- private:
-  CFX_Edit* m_pEdit;
-  CPVT_WordPlace m_wpPlace;
-  CPVT_WordRange m_wrPlace;
-  EDIT_PROPS_E m_eProps;
-
-  CPVT_WordProps m_OldWordProps;
-  CPVT_WordProps m_NewWordProps;
-};
-
-/* ------------------------- CFX_Edit ---------------------------- */
-
-class CFX_Edit : public IFX_Edit {
-  friend class CFX_Edit_Iterator;
-  friend class CFXEU_InsertWord;
-  friend class CFXEU_InsertReturn;
-  friend class CFXEU_Backspace;
-  friend class CFXEU_Delete;
-  friend class CFXEU_Clear;
-  friend class CFXEU_ClearRich;
-  friend class CFXEU_SetSecProps;
-  friend class CFXEU_SetWordProps;
-  friend class CFXEU_InsertText;
-
- public:
-  explicit CFX_Edit(IPDF_VariableText* pVT);
-  ~CFX_Edit() override;
-
-  // IFX_Edit
-  void SetFontMap(IFX_Edit_FontMap* pFontMap) override;
-  void SetVTProvider(IPDF_VariableText_Provider* pProvider) override;
-  void SetNotify(IFX_Edit_Notify* pNotify) override;
-  void SetOprNotify(IFX_Edit_OprNotify* pOprNotify) override;
-  IFX_Edit_Iterator* GetIterator() override;
-  IPDF_VariableText* GetVariableText() override;
-  IFX_Edit_FontMap* GetFontMap() override;
-  void Initialize() override;
-  void SetPlateRect(const CPDF_Rect& rect, FX_BOOL bPaint = TRUE) override;
-  void SetScrollPos(const CPDF_Point& point) override;
-  void SetAlignmentH(int32_t nFormat = 0, FX_BOOL bPaint = TRUE) override;
-  void SetAlignmentV(int32_t nFormat = 0, FX_BOOL bPaint = TRUE) override;
-  void SetPasswordChar(FX_WORD wSubWord = '*', FX_BOOL bPaint = TRUE) override;
-  void SetLimitChar(int32_t nLimitChar = 0, FX_BOOL bPaint = TRUE) override;
-  void SetCharArray(int32_t nCharArray = 0, FX_BOOL bPaint = TRUE) override;
-  void SetCharSpace(FX_FLOAT fCharSpace = 0.0f, FX_BOOL bPaint = TRUE) override;
-  void SetHorzScale(int32_t nHorzScale = 100, FX_BOOL bPaint = TRUE) override;
-  void SetLineLeading(FX_FLOAT fLineLeading, FX_BOOL bPaint = TRUE) override;
-  void SetMultiLine(FX_BOOL bMultiLine = TRUE, FX_BOOL bPaint = TRUE) override;
-  void SetAutoReturn(FX_BOOL bAuto = TRUE, FX_BOOL bPaint = TRUE) override;
-  void SetAutoFontSize(FX_BOOL bAuto = TRUE, FX_BOOL bPaint = TRUE) override;
-  void SetAutoScroll(FX_BOOL bAuto = TRUE, FX_BOOL bPaint = TRUE) override;
-  void SetFontSize(FX_FLOAT fFontSize, FX_BOOL bPaint = TRUE) override;
-  void SetTextOverflow(FX_BOOL bAllowed = FALSE,
-                       FX_BOOL bPaint = TRUE) override;
-  FX_BOOL IsRichText() const override;
-  void SetRichText(FX_BOOL bRichText = TRUE, FX_BOOL bPaint = TRUE) override;
-  FX_BOOL SetRichFontSize(FX_FLOAT fFontSize) override;
-  FX_BOOL SetRichFontIndex(int32_t nFontIndex) override;
-  FX_BOOL SetRichTextColor(FX_COLORREF dwColor) override;
-  FX_BOOL SetRichTextScript(int32_t nScriptType) override;
-  FX_BOOL SetRichTextBold(FX_BOOL bBold = TRUE) override;
-  FX_BOOL SetRichTextItalic(FX_BOOL bItalic = TRUE) override;
-  FX_BOOL SetRichTextUnderline(FX_BOOL bUnderline = TRUE) override;
-  FX_BOOL SetRichTextCrossout(FX_BOOL bCrossout = TRUE) override;
-  FX_BOOL SetRichTextCharSpace(FX_FLOAT fCharSpace) override;
-  FX_BOOL SetRichTextHorzScale(int32_t nHorzScale = 100) override;
-  FX_BOOL SetRichTextLineLeading(FX_FLOAT fLineLeading) override;
-  FX_BOOL SetRichTextLineIndent(FX_FLOAT fLineIndent) override;
-  FX_BOOL SetRichTextAlignment(int32_t nAlignment) override;
-  void OnMouseDown(const CPDF_Point& point,
-                   FX_BOOL bShift,
-                   FX_BOOL bCtrl) override;
-  void OnMouseMove(const CPDF_Point& point,
-                   FX_BOOL bShift,
-                   FX_BOOL bCtrl) override;
-  void OnVK_UP(FX_BOOL bShift, FX_BOOL bCtrl) override;
-  void OnVK_DOWN(FX_BOOL bShift, FX_BOOL bCtrl) override;
-  void OnVK_LEFT(FX_BOOL bShift, FX_BOOL bCtrl) override;
-  void OnVK_RIGHT(FX_BOOL bShift, FX_BOOL bCtrl) override;
-  void OnVK_HOME(FX_BOOL bShift, FX_BOOL bCtrl) override;
-  void OnVK_END(FX_BOOL bShift, FX_BOOL bCtrl) override;
-  void SetText(const FX_WCHAR* text,
-               int32_t charset = DEFAULT_CHARSET,
-               const CPVT_SecProps* pSecProps = NULL,
-               const CPVT_WordProps* pWordProps = NULL) override;
-  FX_BOOL InsertWord(FX_WORD word,
-                     int32_t charset = DEFAULT_CHARSET,
-                     const CPVT_WordProps* pWordProps = NULL) override;
-  FX_BOOL InsertReturn(const CPVT_SecProps* pSecProps = NULL,
-                       const CPVT_WordProps* pWordProps = NULL) override;
-  FX_BOOL Backspace() override;
-  FX_BOOL Delete() override;
-  FX_BOOL Clear() override;
-  FX_BOOL InsertText(const FX_WCHAR* text,
-                     int32_t charset = DEFAULT_CHARSET,
-                     const CPVT_SecProps* pSecProps = NULL,
-                     const CPVT_WordProps* pWordProps = NULL) override;
-  FX_BOOL Redo() override;
-  FX_BOOL Undo() override;
-  int32_t WordPlaceToWordIndex(const CPVT_WordPlace& place) const override;
-  CPVT_WordPlace WordIndexToWordPlace(int32_t index) const override;
-  CPVT_WordPlace GetLineBeginPlace(const CPVT_WordPlace& place) const override;
-  CPVT_WordPlace GetLineEndPlace(const CPVT_WordPlace& place) const override;
-  CPVT_WordPlace GetSectionBeginPlace(
-      const CPVT_WordPlace& place) const override;
-  CPVT_WordPlace GetSectionEndPlace(const CPVT_WordPlace& place) const override;
-  CPVT_WordPlace SearchWordPlace(const CPDF_Point& point) const override;
-  int32_t GetCaret() const override;
-  CPVT_WordPlace GetCaretWordPlace() const override;
-  CFX_WideString GetSelText() const override;
-  CFX_WideString GetText() const override;
-  FX_FLOAT GetFontSize() const override;
-  FX_WORD GetPasswordChar() const override;
-  CPDF_Point GetScrollPos() const override;
-  int32_t GetCharArray() const override;
-  CPDF_Rect GetPlateRect() const override;
-  CPDF_Rect GetContentRect() const override;
-  CFX_WideString GetRangeText(const CPVT_WordRange& range) const override;
-  int32_t GetHorzScale() const override;
-  FX_FLOAT GetCharSpace() const override;
-  int32_t GetTotalWords() const override;
-  void SetSel(int32_t nStartChar, int32_t nEndChar) override;
-  void GetSel(int32_t& nStartChar, int32_t& nEndChar) const override;
-  void SelectAll() override;
-  void SelectNone() override;
-  FX_BOOL IsSelected() const override;
-  void Paint() override;
-  void EnableNotify(FX_BOOL bNotify) override;
-  void EnableRefresh(FX_BOOL bRefresh) override;
-  void RefreshWordRange(const CPVT_WordRange& wr) override;
-  void SetCaret(int32_t nPos) override;
-  CPVT_WordRange GetWholeWordRange() const override;
-  CPVT_WordRange GetSelectWordRange() const override;
-  void EnableUndo(FX_BOOL bUndo) override;
-  void EnableOprNotify(FX_BOOL bNotify) override;
-  FX_BOOL IsTextFull() const override;
-  FX_BOOL IsTextOverflow() const;
-  FX_BOOL CanUndo() const override;
-  FX_BOOL CanRedo() const override;
-  FX_BOOL IsModified() const override;
-  CPVT_WordRange GetVisibleWordRange() const override;
-  void AddUndoItem(IFX_Edit_UndoItem* pUndoItem) override;
-
-  FX_BOOL Empty();
-
-  CPVT_WordPlace DoInsertText(const CPVT_WordPlace& place,
-                              const FX_WCHAR* text,
-                              int32_t charset,
-                              const CPVT_SecProps* pSecProps,
-                              const CPVT_WordProps* pWordProps);
-  int32_t GetCharSetFromUnicode(FX_WORD word, int32_t nOldCharset);
-
-  int32_t GetTotalLines() const;
-
- private:
-  void SetSel(const CPVT_WordPlace& begin, const CPVT_WordPlace& end);
-
-  void RearrangeAll();
-  void RearrangePart(const CPVT_WordRange& range);
-  void ScrollToCaret();
-  void SetScrollInfo();
-  void SetScrollPosX(FX_FLOAT fx);
-  void SetScrollPosY(FX_FLOAT fy);
-  void SetScrollLimit();
-  void SetContentChanged();
-
-  void SetText(const FX_WCHAR* text,
-               int32_t charset,
-               const CPVT_SecProps* pSecProps,
-               const CPVT_WordProps* pWordProps,
-               FX_BOOL bAddUndo,
-               FX_BOOL bPaint);
-  FX_BOOL InsertWord(FX_WORD word,
-                     int32_t charset,
-                     const CPVT_WordProps* pWordProps,
-                     FX_BOOL bAddUndo,
-                     FX_BOOL bPaint);
-  FX_BOOL InsertReturn(const CPVT_SecProps* pSecProps,
-                       const CPVT_WordProps* pWordProps,
-                       FX_BOOL bAddUndo,
-                       FX_BOOL bPaint);
-  FX_BOOL Backspace(FX_BOOL bAddUndo, FX_BOOL bPaint);
-  FX_BOOL Delete(FX_BOOL bAddUndo, FX_BOOL bPaint);
-  FX_BOOL Clear(FX_BOOL bAddUndo, FX_BOOL bPaint);
-  FX_BOOL InsertText(const FX_WCHAR* text,
-                     int32_t charset,
-                     const CPVT_SecProps* pSecProps,
-                     const CPVT_WordProps* pWordProps,
-                     FX_BOOL bAddUndo,
-                     FX_BOOL bPaint);
-  FX_BOOL SetRichTextProps(EDIT_PROPS_E eProps,
-                           const CPVT_SecProps* pSecProps,
-                           const CPVT_WordProps* pWordProps);
-  FX_BOOL SetSecProps(EDIT_PROPS_E eProps,
-                      const CPVT_WordPlace& place,
-                      const CPVT_SecProps* pSecProps,
-                      const CPVT_WordProps* pWordProps,
-                      const CPVT_WordRange& wr,
-                      FX_BOOL bAddUndo);
-  FX_BOOL SetWordProps(EDIT_PROPS_E eProps,
-                       const CPVT_WordPlace& place,
-                       const CPVT_WordProps* pWordProps,
-                       const CPVT_WordRange& wr,
-                       FX_BOOL bAddUndo);
-  void PaintSetProps(EDIT_PROPS_E eProps, const CPVT_WordRange& wr);
-  void PaintInsertText(const CPVT_WordPlace& wpOld,
-                       const CPVT_WordPlace& wpNew);
-
-  inline CPDF_Point VTToEdit(const CPDF_Point& point) const;
-  inline CPDF_Point EditToVT(const CPDF_Point& point) const;
-  inline CPDF_Rect VTToEdit(const CPDF_Rect& rect) const;
-  inline CPDF_Rect EditToVT(const CPDF_Rect& rect) const;
-
-  void Refresh(REFRESH_PLAN_E ePlan,
-               const CPVT_WordRange* pRange1 = NULL,
-               const CPVT_WordRange* pRange2 = NULL);
-  void RefreshPushLineRects(const CPVT_WordRange& wr);
-  void RefreshPushRandomRects(const CPVT_WordRange& wr);
-
-  void SetCaret(const CPVT_WordPlace& place);
-  void SetCaretInfo();
-  void SetCaretOrigin();
-  void SetCaretChange();
-
-  CPVT_WordRange GetLatinWordsRange(const CPVT_WordPlace& place) const;
-  CPVT_WordRange CombineWordRange(const CPVT_WordRange& wr1,
-                                  const CPVT_WordRange& wr2);
-
-
-  void BeginGroupUndo(const CFX_WideString& sTitle);
-  void EndGroupUndo();
-  void AddEditUndoItem(CFX_Edit_UndoItem* pEditUndoItem);
-
-  void SetPageInfo(const CPVT_WordPlace& place);
-  CPVT_WordPlace SearchPageEndPlace(const CPVT_WordPlace& wpPageBegin,
-                                    const CPDF_Point& point) const;
-  FX_FLOAT GetLineTop(const CPVT_WordPlace& place) const;
-  FX_FLOAT GetLineBottom(const CPVT_WordPlace& place) const;
-
- private:
-  IPDF_VariableText* m_pVT;
-  IFX_Edit_Notify* m_pNotify;
-  IFX_Edit_OprNotify* m_pOprNotify;
-  CFX_Edit_Provider* m_pVTProvide;
-
-  CPVT_WordPlace m_wpCaret;
-  CPVT_WordPlace m_wpOldCaret;
-  CFX_Edit_Select m_SelState;
-
-  CPDF_Point m_ptScrollPos;
-  CPDF_Point m_ptRefreshScrollPos;
-  FX_BOOL m_bEnableScroll;
-  IFX_Edit_Iterator* m_pIterator;
-  CFX_Edit_Refresh m_Refresh;
-  CPDF_Point m_ptCaret;
-  CFX_Edit_Undo m_Undo;
-  int32_t m_nAlignment;
-  FX_BOOL m_bNotifyFlag;
-  FX_BOOL m_bEnableOverflow;
-  FX_BOOL m_bEnableRefresh;
-  CPDF_Rect m_rcOldContent;
-  FX_BOOL m_bEnableUndo;
-  FX_BOOL m_bNotify;
-  FX_BOOL m_bOprNotify;
-  CFX_Edit_GroupUndoItem* m_pGroupUndoItem;
-};
-
-/* ------------------------- CFX_Edit_Iterator ---------------------------- */
-
-class CFX_Edit_Iterator : public IFX_Edit_Iterator {
- public:
-  CFX_Edit_Iterator(CFX_Edit* pEdit, IPDF_VariableText_Iterator* pVTIterator);
-  ~CFX_Edit_Iterator() override;
-
-  // IFX_Edit_Iterator
-  FX_BOOL NextWord() override;
-  FX_BOOL NextLine() override;
-  FX_BOOL NextSection() override;
-  FX_BOOL PrevWord() override;
-  FX_BOOL PrevLine() override;
-  FX_BOOL PrevSection() override;
-  FX_BOOL GetWord(CPVT_Word& word) const override;
-  FX_BOOL GetLine(CPVT_Line& line) const override;
-  FX_BOOL GetSection(CPVT_Section& section) const override;
-  void SetAt(int32_t nWordIndex) override;
-  void SetAt(const CPVT_WordPlace& place) override;
-  const CPVT_WordPlace& GetAt() const override;
-  IFX_Edit* GetEdit() const override;
-
- private:
-  CFX_Edit* m_pEdit;
-  IPDF_VariableText_Iterator* m_pVTIterator;
-};
-
-class CFX_Edit_Provider : public IPDF_VariableText_Provider {
- public:
-  explicit CFX_Edit_Provider(IFX_Edit_FontMap* pFontMap);
-  ~CFX_Edit_Provider() override;
-
-  IFX_Edit_FontMap* GetFontMap();
-
-  // IPDF_VariableText_Provider:
-  int32_t GetCharWidth(int32_t nFontIndex,
-                       FX_WORD word,
-                       int32_t nWordStyle) override;
-  int32_t GetTypeAscent(int32_t nFontIndex) override;
-  int32_t GetTypeDescent(int32_t nFontIndex) override;
-  int32_t GetWordFontIndex(FX_WORD word,
-                           int32_t charset,
-                           int32_t nFontIndex) override;
-  int32_t GetDefaultFontIndex() override;
-  FX_BOOL IsLatinWord(FX_WORD word) override;
-
- private:
-  IFX_Edit_FontMap* m_pFontMap;
-};
-
-#endif  // FPDFSDK_INCLUDE_FXEDIT_FXET_EDIT_H_
diff --git a/fpdfsdk/include/fxedit/fxet_list.h b/fpdfsdk/include/fxedit/fxet_list.h
deleted file mode 100644
index 2700b92..0000000
--- a/fpdfsdk/include/fxedit/fxet_list.h
+++ /dev/null
@@ -1,344 +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_FXEDIT_FXET_LIST_H_
-#define FPDFSDK_INCLUDE_FXEDIT_FXET_LIST_H_
-
-#include "core/include/fpdfapi/fpdf_parser.h"  // For CPDF_Point.
-#include "fx_edit.h"
-
-class IFX_Edit;
-
-class CLST_Size {
- public:
-  CLST_Size() : x(0.0f), y(0.0f) {}
-
-  CLST_Size(FX_FLOAT other_x, FX_FLOAT other_y) {
-    x = other_x;
-    y = other_y;
-  }
-
-  void Default() {
-    x = 0.0f;
-    y = 0.0f;
-  }
-
-  FX_BOOL operator!=(const CLST_Size& size) const {
-    return FXSYS_memcmp(this, &size, sizeof(CLST_Size)) != 0;
-  }
-
-  FX_FLOAT x, y;
-};
-
-class CLST_Rect : public CPDF_Rect {
- public:
-  CLST_Rect() { left = top = right = bottom = 0.0f; }
-
-  CLST_Rect(FX_FLOAT other_left,
-            FX_FLOAT other_top,
-            FX_FLOAT other_right,
-            FX_FLOAT other_bottom) {
-    left = other_left;
-    top = other_top;
-    right = other_right;
-    bottom = other_bottom;
-  }
-
-  CLST_Rect(const CPDF_Rect& rect) {
-    left = rect.left;
-    top = rect.top;
-    right = rect.right;
-    bottom = rect.bottom;
-  }
-
-  ~CLST_Rect() {}
-
-  void Default() { left = top = right = bottom = 0.0f; }
-
-  const CLST_Rect operator=(const CPDF_Rect& rect) {
-    left = rect.left;
-    top = rect.top;
-    right = rect.right;
-    bottom = rect.bottom;
-
-    return *this;
-  }
-
-  FX_BOOL operator==(const CLST_Rect& rect) const {
-    return FXSYS_memcmp(this, &rect, sizeof(CLST_Rect)) == 0;
-  }
-
-  FX_BOOL operator!=(const CLST_Rect& rect) const {
-    return FXSYS_memcmp(this, &rect, sizeof(CLST_Rect)) != 0;
-  }
-
-  FX_FLOAT Width() const { return right - left; }
-
-  FX_FLOAT Height() const {
-    if (top > bottom)
-      return top - bottom;
-    return bottom - top;
-  }
-
-  CPDF_Point LeftTop() const { return CPDF_Point(left, top); }
-
-  CPDF_Point RightBottom() const { return CPDF_Point(right, bottom); }
-
-  const CLST_Rect operator+=(const CPDF_Point& point) {
-    left += point.x;
-    right += point.x;
-    top += point.y;
-    bottom += point.y;
-
-    return *this;
-  }
-
-  const CLST_Rect operator-=(const CPDF_Point& point) {
-    left -= point.x;
-    right -= point.x;
-    top -= point.y;
-    bottom -= point.y;
-
-    return *this;
-  }
-
-  CLST_Rect operator+(const CPDF_Point& point) const {
-    return CLST_Rect(left + point.x, top + point.y, right + point.x,
-                     bottom + point.y);
-  }
-
-  CLST_Rect operator-(const CPDF_Point& point) const {
-    return CLST_Rect(left - point.x, top - point.y, right - point.x,
-                     bottom - point.y);
-  }
-};
-
-class CFX_ListItem {
- public:
-  CFX_ListItem();
-  virtual ~CFX_ListItem();
-
-  void SetFontMap(IFX_Edit_FontMap* pFontMap);
-  IFX_Edit_Iterator* GetIterator() const;
-  IFX_Edit* GetEdit() const;
-
- public:
-  void SetRect(const CLST_Rect& rect);
-  void SetSelect(FX_BOOL bSelected);
-  void SetCaret(FX_BOOL bCaret);
-  void SetText(const FX_WCHAR* text);
-  void SetFontSize(FX_FLOAT fFontSize);
-  CFX_WideString GetText() const;
-
-  CLST_Rect GetRect() const;
-  FX_BOOL IsSelected() const;
-  FX_BOOL IsCaret() const;
-  FX_FLOAT GetItemHeight() const;
-  FX_WORD GetFirstChar() const;
-
- private:
-  IFX_Edit* m_pEdit;
-  FX_BOOL m_bSelected;
-  FX_BOOL m_bCaret;
-  CLST_Rect m_rcListItem;
-};
-
-class CFX_ListContainer {
- public:
-  CFX_ListContainer()
-      : m_rcPlate(0.0f, 0.0f, 0.0f, 0.0f),
-        m_rcContent(0.0f, 0.0f, 0.0f, 0.0f) {}
-  virtual ~CFX_ListContainer() {}
-  virtual void SetPlateRect(const CPDF_Rect& rect) { m_rcPlate = rect; }
-  CPDF_Rect GetPlateRect() const { return m_rcPlate; }
-  void SetContentRect(const CLST_Rect& rect) { m_rcContent = rect; }
-  CLST_Rect GetContentRect() const { return m_rcContent; }
-  CPDF_Point GetBTPoint() const {
-    return CPDF_Point(m_rcPlate.left, m_rcPlate.top);
-  }
-  CPDF_Point GetETPoint() const {
-    return CPDF_Point(m_rcPlate.right, m_rcPlate.bottom);
-  }
-
- public:
-  CPDF_Point InnerToOuter(const CPDF_Point& point) const {
-    return CPDF_Point(point.x + GetBTPoint().x, GetBTPoint().y - point.y);
-  }
-  CPDF_Point OuterToInner(const CPDF_Point& point) const {
-    return CPDF_Point(point.x - GetBTPoint().x, GetBTPoint().y - point.y);
-  }
-  CPDF_Rect InnerToOuter(const CLST_Rect& rect) const {
-    CPDF_Point ptLeftTop = InnerToOuter(CPDF_Point(rect.left, rect.top));
-    CPDF_Point ptRightBottom =
-        InnerToOuter(CPDF_Point(rect.right, rect.bottom));
-    return CPDF_Rect(ptLeftTop.x, ptRightBottom.y, ptRightBottom.x,
-                     ptLeftTop.y);
-  }
-  CLST_Rect OuterToInner(const CPDF_Rect& rect) const {
-    CPDF_Point ptLeftTop = OuterToInner(CPDF_Point(rect.left, rect.top));
-    CPDF_Point ptRightBottom =
-        OuterToInner(CPDF_Point(rect.right, rect.bottom));
-    return CLST_Rect(ptLeftTop.x, ptLeftTop.y, ptRightBottom.x,
-                     ptRightBottom.y);
-  }
-
- private:
-  CPDF_Rect m_rcPlate;
-  CLST_Rect m_rcContent;  // positive forever!
-};
-
-template <class TYPE>
-class CLST_ArrayTemplate : public CFX_ArrayTemplate<TYPE> {
- public:
-  FX_BOOL IsEmpty() { return CFX_ArrayTemplate<TYPE>::GetSize() <= 0; }
-  TYPE GetAt(int32_t nIndex) const {
-    if (nIndex >= 0 && nIndex < CFX_ArrayTemplate<TYPE>::GetSize())
-      return CFX_ArrayTemplate<TYPE>::GetAt(nIndex);
-    return NULL;
-  }
-  void RemoveAt(int32_t nIndex) {
-    if (nIndex >= 0 && nIndex < CFX_ArrayTemplate<TYPE>::GetSize())
-      CFX_ArrayTemplate<TYPE>::RemoveAt(nIndex);
-  }
-};
-
-class CFX_List : protected CFX_ListContainer, public IFX_List {
- public:
-  CFX_List();
-  ~CFX_List() override;
-
-  // IFX_List:
-  void SetFontMap(IFX_Edit_FontMap* pFontMap) override;
-  void SetFontSize(FX_FLOAT fFontSize) override;
-  CPDF_Rect GetPlateRect() const override;
-  CPDF_Rect GetContentRect() const override;
-  FX_FLOAT GetFontSize() const override;
-  IFX_Edit* GetItemEdit(int32_t nIndex) const override;
-  int32_t GetCount() const override;
-  FX_BOOL IsItemSelected(int32_t nIndex) const override;
-  FX_FLOAT GetFirstHeight() const override;
-  void SetMultipleSel(FX_BOOL bMultiple) override;
-  FX_BOOL IsMultipleSel() const override;
-  FX_BOOL IsValid(int32_t nItemIndex) const override;
-  int32_t FindNext(int32_t nIndex, FX_WCHAR nChar) const override;
-  void Empty() override;
-  CPDF_Rect GetItemRect(int32_t nIndex) const override;
-  int32_t GetItemIndex(const CPDF_Point& point) const override;
-  int32_t GetFirstSelected() const override;
-
- protected:
-  void AddItem(const FX_WCHAR* str);
-  virtual void ReArrange(int32_t nItemIndex);
-  CFX_WideString GetItemText(int32_t nIndex) const;
-  void SetItemSelect(int32_t nItemIndex, FX_BOOL bSelected);
-  void SetItemCaret(int32_t nItemIndex, FX_BOOL bCaret);
-  int32_t GetLastSelected() const;
-  FX_WCHAR Toupper(FX_WCHAR c) const;
-
- private:
-  CLST_ArrayTemplate<CFX_ListItem*> m_aListItems;
-  FX_FLOAT m_fFontSize;
-  IFX_Edit_FontMap* m_pFontMap;
-  FX_BOOL m_bMultiple;
-};
-
-struct CPLST_Select_Item {
-  CPLST_Select_Item(int32_t other_nItemIndex, int32_t other_nState) {
-    nItemIndex = other_nItemIndex;
-    nState = other_nState;
-  }
-
-  int32_t nItemIndex;
-  int32_t nState;  // 0:normal select -1:to deselect 1: to select
-};
-
-class CPLST_Select {
- public:
-  CPLST_Select();
-  virtual ~CPLST_Select();
-
- public:
-  void Add(int32_t nItemIndex);
-  void Add(int32_t nBeginIndex, int32_t nEndIndex);
-  void Sub(int32_t nItemIndex);
-  void Sub(int32_t nBeginIndex, int32_t nEndIndex);
-  FX_BOOL IsExist(int32_t nItemIndex) const;
-  int32_t Find(int32_t nItemIndex) const;
-  int32_t GetCount() const;
-  int32_t GetItemIndex(int32_t nIndex) const;
-  int32_t GetState(int32_t nIndex) const;
-  void Done();
-  void DeselectAll();
-
- private:
-  CFX_ArrayTemplate<CPLST_Select_Item*> m_aItems;
-};
-
-class CFX_ListCtrl : public CFX_List {
- public:
-  CFX_ListCtrl();
-  ~CFX_ListCtrl() override;
-
-  // CFX_List
-  void SetNotify(IFX_List_Notify* pNotify) override;
-  void OnMouseDown(const CPDF_Point& point,
-                   FX_BOOL bShift,
-                   FX_BOOL bCtrl) override;
-  void OnMouseMove(const CPDF_Point& point,
-                   FX_BOOL bShift,
-                   FX_BOOL bCtrl) override;
-  void OnVK_UP(FX_BOOL bShift, FX_BOOL bCtrl) override;
-  void OnVK_DOWN(FX_BOOL bShift, FX_BOOL bCtrl) override;
-  void OnVK_LEFT(FX_BOOL bShift, FX_BOOL bCtrl) override;
-  void OnVK_RIGHT(FX_BOOL bShift, FX_BOOL bCtrl) override;
-  void OnVK_HOME(FX_BOOL bShift, FX_BOOL bCtrl) override;
-  void OnVK_END(FX_BOOL bShift, FX_BOOL bCtrl) override;
-  void OnVK(int32_t nItemIndex, FX_BOOL bShift, FX_BOOL bCtrl) override;
-  FX_BOOL OnChar(FX_WORD nChar, FX_BOOL bShift, FX_BOOL bCtrl) override;
-  void SetPlateRect(const CPDF_Rect& rect) override;
-  void SetScrollPos(const CPDF_Point& point) override;
-  void ScrollToListItem(int32_t nItemIndex) override;
-  CPDF_Rect GetItemRect(int32_t nIndex) const override;
-  int32_t GetCaret() const override { return m_nCaretIndex; }
-  int32_t GetSelect() const override { return m_nSelItem; }
-  int32_t GetTopItem() const override;
-  CPDF_Rect GetContentRect() const override;
-  int32_t GetItemIndex(const CPDF_Point& point) const override;
-  void AddString(const FX_WCHAR* string) override;
-  void SetTopItem(int32_t nIndex) override;
-  void Select(int32_t nItemIndex) override;
-  void SetCaret(int32_t nItemIndex) override;
-  void Empty() override;
-  void Cancel() override;
-  CFX_WideString GetText() const override;
-  void ReArrange(int32_t nItemIndex) override;
-
-  virtual CPDF_Point InToOut(const CPDF_Point& point) const;
-  virtual CPDF_Point OutToIn(const CPDF_Point& point) const;
-  virtual CPDF_Rect InToOut(const CPDF_Rect& rect) const;
-  virtual CPDF_Rect OutToIn(const CPDF_Rect& rect) const;
-
- private:
-  void SetMultipleSelect(int32_t nItemIndex, FX_BOOL bSelected);
-  void SetSingleSelect(int32_t nItemIndex);
-  void InvalidateItem(int32_t nItemIndex);
-  void SelectItems();
-  FX_BOOL IsItemVisible(int32_t nItemIndex) const;
-  void SetScrollInfo();
-  void SetScrollPosY(FX_FLOAT fy);
-
- private:
-  IFX_List_Notify* m_pNotify;
-  FX_BOOL m_bNotifyFlag;
-  CPDF_Point m_ptScrollPos;
-  CPLST_Select m_aSelItems;  // for multiple
-  int32_t m_nSelItem;        // for single
-  int32_t m_nFootIndex;      // for multiple
-  FX_BOOL m_bCtrlSel;        // for multiple
-  int32_t m_nCaretIndex;     // for multiple
-};
-
-#endif  // FPDFSDK_INCLUDE_FXEDIT_FXET_LIST_H_
diff --git a/fpdfsdk/include/javascript/IJavaScript.h b/fpdfsdk/include/javascript/IJavaScript.h
deleted file mode 100644
index 6b15467..0000000
--- a/fpdfsdk/include/javascript/IJavaScript.h
+++ /dev/null
@@ -1,166 +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_JAVASCRIPT_IJAVASCRIPT_H_
-#define FPDFSDK_INCLUDE_JAVASCRIPT_IJAVASCRIPT_H_
-
-#include "core/include/fxcrt/fx_string.h"
-#include "core/include/fxcrt/fx_system.h"
-
-#ifdef PDF_ENABLE_XFA
-#include "xfa/include/fxjse/fxjse.h"
-#endif  // PDF_ENABLE_XFA
-
-class CPDFDoc_Environment;
-class CPDFSDK_Annot;
-class CPDFSDK_Document;
-class CPDF_Bookmark;
-class CPDF_FormField;
-
-// Records the details of an event and triggers JS execution for it.
-class IJS_Context {
- public:
-  virtual FX_BOOL RunScript(const CFX_WideString& script,
-                            CFX_WideString* info) = 0;
-
-  virtual void OnApp_Init() = 0;
-
-  virtual void OnDoc_Open(CPDFSDK_Document* pDoc,
-                          const CFX_WideString& strTargetName) = 0;
-  virtual void OnDoc_WillPrint(CPDFSDK_Document* pDoc) = 0;
-  virtual void OnDoc_DidPrint(CPDFSDK_Document* pDoc) = 0;
-  virtual void OnDoc_WillSave(CPDFSDK_Document* pDoc) = 0;
-  virtual void OnDoc_DidSave(CPDFSDK_Document* pDoc) = 0;
-  virtual void OnDoc_WillClose(CPDFSDK_Document* pDoc) = 0;
-
-  virtual void OnPage_Open(CPDFSDK_Document* pTarget) = 0;
-  virtual void OnPage_Close(CPDFSDK_Document* pTarget) = 0;
-  virtual void OnPage_InView(CPDFSDK_Document* pTarget) = 0;
-  virtual void OnPage_OutView(CPDFSDK_Document* pTarget) = 0;
-
-  virtual void OnField_MouseDown(FX_BOOL bModifier,
-                                 FX_BOOL bShift,
-                                 CPDF_FormField* pTarget) = 0;
-  virtual void OnField_MouseEnter(FX_BOOL bModifier,
-                                  FX_BOOL bShift,
-                                  CPDF_FormField* pTarget) = 0;
-  virtual void OnField_MouseExit(FX_BOOL bModifier,
-                                 FX_BOOL bShift,
-                                 CPDF_FormField* pTarget) = 0;
-  virtual void OnField_MouseUp(FX_BOOL bModifier,
-                               FX_BOOL bShift,
-                               CPDF_FormField* pTarget) = 0;
-  virtual void OnField_Focus(FX_BOOL bModifier,
-                             FX_BOOL bShift,
-                             CPDF_FormField* pTarget,
-                             const CFX_WideString& Value) = 0;
-  virtual void OnField_Blur(FX_BOOL bModifier,
-                            FX_BOOL bShift,
-                            CPDF_FormField* pTarget,
-                            const CFX_WideString& Value) = 0;
-
-  virtual void OnField_Calculate(CPDF_FormField* pSource,
-                                 CPDF_FormField* pTarget,
-                                 CFX_WideString& Value,
-                                 FX_BOOL& bRc) = 0;
-  virtual void OnField_Format(CPDF_FormField* pTarget,
-                              CFX_WideString& Value,
-                              FX_BOOL bWillCommit) = 0;
-  virtual void OnField_Keystroke(CFX_WideString& strChange,
-                                 const CFX_WideString& strChangeEx,
-                                 FX_BOOL KeyDown,
-                                 FX_BOOL bModifier,
-                                 int& nSelEnd,
-                                 int& nSelStart,
-                                 FX_BOOL bShift,
-                                 CPDF_FormField* pTarget,
-                                 CFX_WideString& Value,
-                                 FX_BOOL bWillCommit,
-                                 FX_BOOL bFieldFull,
-                                 FX_BOOL& bRc) = 0;
-  virtual void OnField_Validate(CFX_WideString& strChange,
-                                const CFX_WideString& strChangeEx,
-                                FX_BOOL bKeyDown,
-                                FX_BOOL bModifier,
-                                FX_BOOL bShift,
-                                CPDF_FormField* pTarget,
-                                CFX_WideString& Value,
-                                FX_BOOL& bRc) = 0;
-
-  virtual void OnScreen_Focus(FX_BOOL bModifier,
-                              FX_BOOL bShift,
-                              CPDFSDK_Annot* pScreen) = 0;
-  virtual void OnScreen_Blur(FX_BOOL bModifier,
-                             FX_BOOL bShift,
-                             CPDFSDK_Annot* pScreen) = 0;
-  virtual void OnScreen_Open(FX_BOOL bModifier,
-                             FX_BOOL bShift,
-                             CPDFSDK_Annot* pScreen) = 0;
-  virtual void OnScreen_Close(FX_BOOL bModifier,
-                              FX_BOOL bShift,
-                              CPDFSDK_Annot* pScreen) = 0;
-  virtual void OnScreen_MouseDown(FX_BOOL bModifier,
-                                  FX_BOOL bShift,
-                                  CPDFSDK_Annot* pScreen) = 0;
-  virtual void OnScreen_MouseUp(FX_BOOL bModifier,
-                                FX_BOOL bShift,
-                                CPDFSDK_Annot* pScreen) = 0;
-  virtual void OnScreen_MouseEnter(FX_BOOL bModifier,
-                                   FX_BOOL bShift,
-                                   CPDFSDK_Annot* pScreen) = 0;
-  virtual void OnScreen_MouseExit(FX_BOOL bModifier,
-                                  FX_BOOL bShift,
-                                  CPDFSDK_Annot* pScreen) = 0;
-  virtual void OnScreen_InView(FX_BOOL bModifier,
-                               FX_BOOL bShift,
-                               CPDFSDK_Annot* pScreen) = 0;
-  virtual void OnScreen_OutView(FX_BOOL bModifier,
-                                FX_BOOL bShift,
-                                CPDFSDK_Annot* pScreen) = 0;
-
-  virtual void OnBookmark_MouseUp(CPDF_Bookmark* pBookMark) = 0;
-  virtual void OnLink_MouseUp(CPDFSDK_Document* pTarget) = 0;
-
-  virtual void OnMenu_Exec(CPDFSDK_Document* pTarget,
-                           const CFX_WideString&) = 0;
-  virtual void OnBatchExec(CPDFSDK_Document* pTarget) = 0;
-  virtual void OnConsole_Exec() = 0;
-  virtual void OnExternal_Exec() = 0;
-
-  virtual void EnableMessageBox(FX_BOOL bEnable) = 0;
-
- protected:
-  virtual ~IJS_Context() {}
-};
-
-// Owns the FJXS objects needed to actually execute JS.
-class IJS_Runtime {
- public:
-  static void Initialize(unsigned int slot, void* isolate);
-  static IJS_Runtime* Create(CPDFDoc_Environment* pEnv);
-  virtual ~IJS_Runtime() {}
-
-  virtual IJS_Context* NewContext() = 0;
-  virtual void ReleaseContext(IJS_Context* pContext) = 0;
-  virtual IJS_Context* GetCurrentContext() = 0;
-  virtual void SetReaderDocument(CPDFSDK_Document* pReaderDoc) = 0;
-  virtual CPDFSDK_Document* GetReaderDocument() = 0;
-  virtual int Execute(IJS_Context* cc,
-                      const wchar_t* script,
-                      CFX_WideString* info) = 0;
-
-#ifdef PDF_ENABLE_XFA
-  virtual FX_BOOL GetHValueByName(const CFX_ByteStringC& utf8Name,
-                                  FXJSE_HVALUE hValue) = 0;
-  virtual FX_BOOL SetHValueByName(const CFX_ByteStringC& utf8Name,
-                                  FXJSE_HVALUE hValue) = 0;
-#endif  // PDF_ENABLE_XFA
-
- protected:
-  IJS_Runtime() {}
-};
-
-#endif  // FPDFSDK_INCLUDE_JAVASCRIPT_IJAVASCRIPT_H_
diff --git a/fpdfsdk/include/jsapi/fxjs_v8.h b/fpdfsdk/include/jsapi/fxjs_v8.h
deleted file mode 100644
index b0845a3..0000000
--- a/fpdfsdk/include/jsapi/fxjs_v8.h
+++ /dev/null
@@ -1,248 +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
-
-// FXJS_V8 is a layer that makes it easier to define native objects in V8, but
-// has no knowledge of PDF-specific native objects. It could in theory be used
-// to implement other sets of native objects.
-
-// PDFium code should include this file rather than including V8 headers
-// directly.
-
-#ifndef FPDFSDK_INCLUDE_JSAPI_FXJS_V8_H_
-#define FPDFSDK_INCLUDE_JSAPI_FXJS_V8_H_
-
-#include <v8.h>
-
-#include <vector>
-
-#include "core/include/fxcrt/fx_string.h"
-
-class CFXJS_ObjDefinition;
-
-// FXJS_V8 places no restrictions on these two classes; it merely passes them
-// on to caller-provided methods.
-class IJS_Context;  // A description of the event that caused JS execution.
-class IJS_Runtime;  // A native runtime, typically owns the v8::Context.
-
-#ifdef PDF_ENABLE_XFA
-// FXJS_V8 places no interpreation on this calass; it merely passes it
-// along to XFA.
-class CFXJSE_RuntimeData;
-#endif  // PDF_ENABLE_XFA
-
-enum FXJSOBJTYPE {
-  FXJSOBJTYPE_DYNAMIC = 0,  // Created by native method and returned to JS.
-  FXJSOBJTYPE_STATIC,       // Created by init and hung off of global object.
-  FXJSOBJTYPE_GLOBAL,       // The global object itself (may only appear once).
-};
-
-struct FXJSErr {
-  const wchar_t* message;
-  const wchar_t* srcline;
-  unsigned linnum;
-};
-
-class FXJS_PerIsolateData {
- public:
-  static void SetUp(v8::Isolate* pIsolate);
-  static FXJS_PerIsolateData* Get(v8::Isolate* pIsolate);
-
-  std::vector<CFXJS_ObjDefinition*> m_ObjectDefnArray;
-#ifdef PDF_ENABLE_XFA
-  CFXJSE_RuntimeData* m_pFXJSERuntimeData;
-#endif  // PDF_ENABLE_XFA
-
- protected:
-#ifndef PDF_ENABLE_XFA
-  FXJS_PerIsolateData() {}
-#else  // PDF_ENABLE_XFA
-  FXJS_PerIsolateData() : m_pFXJSERuntimeData(nullptr) {}
-#endif  // PDF_ENABLE_XFA
-};
-
-extern const wchar_t kFXJSValueNameString[];
-extern const wchar_t kFXJSValueNameNumber[];
-extern const wchar_t kFXJSValueNameBoolean[];
-extern const wchar_t kFXJSValueNameDate[];
-extern const wchar_t kFXJSValueNameObject[];
-extern const wchar_t kFXJSValueNameFxobj[];
-extern const wchar_t kFXJSValueNameNull[];
-extern const wchar_t kFXJSValueNameUndefined[];
-
-class FXJS_ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
-  void* Allocate(size_t length) override;
-  void* AllocateUninitialized(size_t length) override;
-  void Free(void* data, size_t length) override;
-};
-
-using FXJS_CONSTRUCTOR = void (*)(IJS_Runtime* cc, v8::Local<v8::Object> obj);
-using FXJS_DESTRUCTOR = void (*)(v8::Local<v8::Object> obj);
-
-// Call before making FXJS_PrepareIsolate call.
-void FXJS_Initialize(unsigned int embedderDataSlot, v8::Isolate* pIsolate);
-void FXJS_Release();
-
-// Gets the global isolate set by FXJS_Initialize(), or makes a new one each
-// time if there is no such isolate. Returns true if a new isolate had to be
-// created.
-bool FXJS_GetIsolate(v8::Isolate** pResultIsolate);
-
-// Get the global isolate's ref count.
-size_t FXJS_GlobalIsolateRefCount();
-
-// Call before making FXJS_Define* calls. Resources allocated here are cleared
-// as part of FXJS_ReleaseRuntime().
-void FXJS_PrepareIsolate(v8::Isolate* pIsolate);
-
-// Call before making JS_Define* calls. Resources allocated here are cleared
-// as part of JS_ReleaseRuntime().
-void JS_PrepareIsolate(v8::Isolate* pIsolate);
-
-// Always returns a valid, newly-created objDefnID.
-int FXJS_DefineObj(v8::Isolate* pIsolate,
-                   const wchar_t* sObjName,
-                   FXJSOBJTYPE eObjType,
-                   FXJS_CONSTRUCTOR pConstructor,
-                   FXJS_DESTRUCTOR pDestructor);
-
-void FXJS_DefineObjMethod(v8::Isolate* pIsolate,
-                          int nObjDefnID,
-                          const wchar_t* sMethodName,
-                          v8::FunctionCallback pMethodCall);
-void FXJS_DefineObjProperty(v8::Isolate* pIsolate,
-                            int nObjDefnID,
-                            const wchar_t* sPropName,
-                            v8::AccessorGetterCallback pPropGet,
-                            v8::AccessorSetterCallback pPropPut);
-void FXJS_DefineObjAllProperties(v8::Isolate* pIsolate,
-                                 int nObjDefnID,
-                                 v8::NamedPropertyQueryCallback pPropQurey,
-                                 v8::NamedPropertyGetterCallback pPropGet,
-                                 v8::NamedPropertySetterCallback pPropPut,
-                                 v8::NamedPropertyDeleterCallback pPropDel);
-void FXJS_DefineObjConst(v8::Isolate* pIsolate,
-                         int nObjDefnID,
-                         const wchar_t* sConstName,
-                         v8::Local<v8::Value> pDefault);
-void FXJS_DefineGlobalMethod(v8::Isolate* pIsolate,
-                             const wchar_t* sMethodName,
-                             v8::FunctionCallback pMethodCall);
-void FXJS_DefineGlobalConst(v8::Isolate* pIsolate,
-                            const wchar_t* sConstName,
-                            v8::Local<v8::Value> pDefault);
-
-// Called after FXJS_Define* calls made.
-void FXJS_InitializeRuntime(
-    v8::Isolate* pIsolate,
-    IJS_Runtime* pIRuntime,
-    v8::Global<v8::Context>* pV8PersistentContext,
-    std::vector<v8::Global<v8::Object>*>* pStaticObjects);
-void FXJS_ReleaseRuntime(v8::Isolate* pIsolate,
-                         v8::Global<v8::Context>* pV8PersistentContext,
-                         std::vector<v8::Global<v8::Object>*>* pStaticObjects);
-IJS_Runtime* FXJS_GetRuntimeFromIsolate(v8::Isolate* pIsolate);
-
-#ifdef PDF_ENABLE_XFA
-// Called as part of FXJS_InitializeRuntime, exposed so PDF can make its
-// own contexts compatible with XFA or vice versa.
-void FXJS_SetRuntimeForV8Context(v8::Local<v8::Context> v8Context,
-                                 IJS_Runtime* pIRuntime);
-#endif  // PDF_ENABLE_XFA
-
-// Called after FXJS_InitializeRuntime call made.
-int FXJS_Execute(v8::Isolate* pIsolate,
-                 IJS_Context* pJSContext,
-                 const wchar_t* script,
-                 FXJSErr* perror);
-
-v8::Local<v8::Object> FXJS_NewFxDynamicObj(v8::Isolate* pIsolate,
-                                           IJS_Runtime* pJSContext,
-                                           int nObjDefnID);
-v8::Local<v8::Object> FXJS_GetThisObj(v8::Isolate* pIsolate);
-int FXJS_GetObjDefnID(v8::Local<v8::Object> pObj);
-const wchar_t* FXJS_GetTypeof(v8::Local<v8::Value> pObj);
-
-void FXJS_SetPrivate(v8::Isolate* pIsolate,
-                     v8::Local<v8::Object> pObj,
-                     void* p);
-void* FXJS_GetPrivate(v8::Isolate* pIsolate, v8::Local<v8::Object> pObj);
-void FXJS_FreePrivate(void* p);
-void FXJS_FreePrivate(v8::Local<v8::Object> pObj);
-
-void FXJS_Error(v8::Isolate* isolate, const CFX_WideString& message);
-v8::Local<v8::String> FXJS_WSToJSString(v8::Isolate* pIsolate,
-                                        const wchar_t* PropertyName,
-                                        int Len = -1);
-
-v8::Local<v8::Value> FXJS_GetObjectElement(v8::Isolate* pIsolate,
-                                           v8::Local<v8::Object> pObj,
-                                           const wchar_t* PropertyName);
-v8::Local<v8::Array> FXJS_GetObjectElementNames(v8::Isolate* pIsolate,
-                                                v8::Local<v8::Object> pObj);
-
-v8::Local<v8::Value> FXJS_GetArrayElement(v8::Isolate* pIsolate,
-                                          v8::Local<v8::Array> pArray,
-                                          unsigned index);
-unsigned FXJS_GetArrayLength(v8::Local<v8::Array> pArray);
-
-void FXJS_PutObjectString(v8::Isolate* pIsolate,
-                          v8::Local<v8::Object> pObj,
-                          const wchar_t* PropertyName,
-                          const wchar_t* sValue);
-void FXJS_PutObjectNumber(v8::Isolate* pIsolate,
-                          v8::Local<v8::Object> pObj,
-                          const wchar_t* PropertyName,
-                          int nValue);
-void FXJS_PutObjectNumber(v8::Isolate* pIsolate,
-                          v8::Local<v8::Object> pObj,
-                          const wchar_t* PropertyName,
-                          float fValue);
-void FXJS_PutObjectNumber(v8::Isolate* pIsolate,
-                          v8::Local<v8::Object> pObj,
-                          const wchar_t* PropertyName,
-                          double dValue);
-void FXJS_PutObjectBoolean(v8::Isolate* pIsolate,
-                           v8::Local<v8::Object> pObj,
-                           const wchar_t* PropertyName,
-                           bool bValue);
-void FXJS_PutObjectObject(v8::Isolate* pIsolate,
-                          v8::Local<v8::Object> pObj,
-                          const wchar_t* PropertyName,
-                          v8::Local<v8::Object> pPut);
-void FXJS_PutObjectNull(v8::Isolate* pIsolate,
-                        v8::Local<v8::Object> pObj,
-                        const wchar_t* PropertyName);
-unsigned FXJS_PutArrayElement(v8::Isolate* pIsolate,
-                              v8::Local<v8::Array> pArray,
-                              unsigned index,
-                              v8::Local<v8::Value> pValue);
-
-v8::Local<v8::Array> FXJS_NewArray(v8::Isolate* pIsolate);
-v8::Local<v8::Value> FXJS_NewNumber(v8::Isolate* pIsolate, int number);
-v8::Local<v8::Value> FXJS_NewNumber(v8::Isolate* pIsolate, double number);
-v8::Local<v8::Value> FXJS_NewNumber(v8::Isolate* pIsolate, float number);
-v8::Local<v8::Value> FXJS_NewBoolean(v8::Isolate* pIsolate, bool b);
-v8::Local<v8::Value> FXJS_NewObject(v8::Isolate* pIsolate,
-                                    v8::Local<v8::Object> pObj);
-v8::Local<v8::Value> FXJS_NewObject2(v8::Isolate* pIsolate,
-                                     v8::Local<v8::Array> pObj);
-v8::Local<v8::Value> FXJS_NewString(v8::Isolate* pIsolate,
-                                    const wchar_t* string);
-v8::Local<v8::Value> FXJS_NewNull();
-v8::Local<v8::Value> FXJS_NewDate(v8::Isolate* pIsolate, double d);
-
-int FXJS_ToInt32(v8::Isolate* pIsolate, v8::Local<v8::Value> pValue);
-bool FXJS_ToBoolean(v8::Isolate* pIsolate, v8::Local<v8::Value> pValue);
-double FXJS_ToNumber(v8::Isolate* pIsolate, v8::Local<v8::Value> pValue);
-v8::Local<v8::Object> FXJS_ToObject(v8::Isolate* pIsolate,
-                                    v8::Local<v8::Value> pValue);
-CFX_WideString FXJS_ToString(v8::Isolate* pIsolate,
-                             v8::Local<v8::Value> pValue);
-v8::Local<v8::Array> FXJS_ToArray(v8::Isolate* pIsolate,
-                                  v8::Local<v8::Value> pValue);
-void FXJS_ValueCopy(v8::Local<v8::Value>& pTo, v8::Local<v8::Value> pFrom);
-
-#endif  // FPDFSDK_INCLUDE_JSAPI_FXJS_V8_H_
diff --git a/fpdfsdk/include/pdfwindow/PWL_Button.h b/fpdfsdk/include/pdfwindow/PWL_Button.h
deleted file mode 100644
index 28a026c..0000000
--- a/fpdfsdk/include/pdfwindow/PWL_Button.h
+++ /dev/null
@@ -1,27 +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_PDFWINDOW_PWL_BUTTON_H_
-#define FPDFSDK_INCLUDE_PDFWINDOW_PWL_BUTTON_H_
-
-#include "PWL_Wnd.h"
-
-class CPWL_Button : public CPWL_Wnd {
- public:
-  CPWL_Button();
-  ~CPWL_Button() override;
-
-  // CPWL_Wnd
-  CFX_ByteString GetClassName() const override;
-  void OnCreate(PWL_CREATEPARAM& cp) override;
-  FX_BOOL OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) override;
-  FX_BOOL OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag) override;
-
- protected:
-  FX_BOOL m_bMouseDown;
-};
-
-#endif  // FPDFSDK_INCLUDE_PDFWINDOW_PWL_BUTTON_H_
diff --git a/fpdfsdk/include/pdfwindow/PWL_Caret.h b/fpdfsdk/include/pdfwindow/PWL_Caret.h
deleted file mode 100644
index c2a2caf..0000000
--- a/fpdfsdk/include/pdfwindow/PWL_Caret.h
+++ /dev/null
@@ -1,53 +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_PDFWINDOW_PWL_CARET_H_
-#define FPDFSDK_INCLUDE_PDFWINDOW_PWL_CARET_H_
-
-#include "PWL_Wnd.h"
-
-struct PWL_CARET_INFO {
- public:
-  PWL_CARET_INFO() : bVisible(FALSE), ptHead(0, 0), ptFoot(0, 0) {}
-
-  FX_BOOL bVisible;
-  CPDF_Point ptHead;
-  CPDF_Point ptFoot;
-};
-
-class CPWL_Caret : public CPWL_Wnd {
- public:
-  CPWL_Caret();
-  ~CPWL_Caret() override;
-
-  // CPWL_Wnd
-  CFX_ByteString GetClassName() const override;
-  void GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) override;
-  void DrawThisAppearance(CFX_RenderDevice* pDevice,
-                          CFX_Matrix* pUser2Device) override;
-  void InvalidateRect(CPDF_Rect* pRect = NULL) override;
-  void SetVisible(FX_BOOL bVisible) override {}
-  void TimerProc() override;
-
-  void SetCaret(FX_BOOL bVisible,
-                const CPDF_Point& ptHead,
-                const CPDF_Point& ptFoot);
-  CFX_ByteString GetCaretAppearanceStream(const CPDF_Point& ptOffset);
-  void SetInvalidRect(CPDF_Rect rc) { m_rcInvalid = rc; }
-
- private:
-  void GetCaretApp(CFX_ByteTextBuf& sAppStream, const CPDF_Point& ptOffset);
-  CPDF_Rect GetCaretRect() const;
-
-  FX_BOOL m_bFlash;
-  CPDF_Point m_ptHead;
-  CPDF_Point m_ptFoot;
-  FX_FLOAT m_fWidth;
-  int32_t m_nDelay;
-  CPDF_Rect m_rcInvalid;
-};
-
-#endif  // FPDFSDK_INCLUDE_PDFWINDOW_PWL_CARET_H_
diff --git a/fpdfsdk/include/pdfwindow/PWL_Edit.h b/fpdfsdk/include/pdfwindow/PWL_Edit.h
deleted file mode 100644
index e7be156..0000000
--- a/fpdfsdk/include/pdfwindow/PWL_Edit.h
+++ /dev/null
@@ -1,171 +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_PDFWINDOW_PWL_EDIT_H_
-#define FPDFSDK_INCLUDE_PDFWINDOW_PWL_EDIT_H_
-
-#include "core/include/fxcrt/fx_basic.h"
-#include "fpdfsdk/include/fxedit/fx_edit.h"
-#include "fpdfsdk/include/pdfwindow/PWL_EditCtrl.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Wnd.h"
-
-class IPWL_SpellCheck;
-
-class IPWL_Filler_Notify {
- public:
-  virtual ~IPWL_Filler_Notify() {}
-  virtual void QueryWherePopup(
-      void* pPrivateData,
-      FX_FLOAT fPopupMin,
-      FX_FLOAT fPopupMax,
-      int32_t& nRet,
-      FX_FLOAT& fPopupRet) = 0;  // nRet: (0:bottom 1:top)
-  virtual void OnBeforeKeyStroke(void* pPrivateData,
-                                 CFX_WideString& strChange,
-                                 const CFX_WideString& strChangeEx,
-                                 int nSelStart,
-                                 int nSelEnd,
-                                 FX_BOOL bKeyDown,
-                                 FX_BOOL& bRC,
-                                 FX_BOOL& bExit,
-                                 FX_DWORD nFlag) = 0;
-#ifdef PDF_ENABLE_XFA
-  virtual void OnPopupPreOpen(void* pPrivateData,
-                              FX_BOOL& bExit,
-                              FX_DWORD nFlag) = 0;
-  virtual void OnPopupPostOpen(void* pPrivateData,
-                               FX_BOOL& bExit,
-                               FX_DWORD nFlag) = 0;
-#endif  // PDF_ENABLE_XFA
-};
-
-class CPWL_Edit : public CPWL_EditCtrl, public IFX_Edit_OprNotify {
- public:
-  CPWL_Edit();
-  ~CPWL_Edit() override;
-
-  // CPWL_EditCtrl
-  CFX_ByteString GetClassName() const override;
-  void OnDestroy() override;
-  void OnCreated() override;
-  void RePosChildWnd() override;
-  CPDF_Rect GetClientRect() const override;
-  void GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) override;
-  void DrawThisAppearance(CFX_RenderDevice* pDevice,
-                          CFX_Matrix* pUser2Device) override;
-  FX_BOOL OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) override;
-  FX_BOOL OnLButtonDblClk(const CPDF_Point& point, FX_DWORD nFlag) override;
-  FX_BOOL OnRButtonUp(const CPDF_Point& point, FX_DWORD nFlag) override;
-  FX_BOOL OnMouseWheel(short zDelta,
-                       const CPDF_Point& point,
-                       FX_DWORD nFlag) override;
-  FX_BOOL OnKeyDown(FX_WORD nChar, FX_DWORD nFlag) override;
-  FX_BOOL OnChar(FX_WORD nChar, FX_DWORD nFlag) override;
-  CPDF_Rect GetFocusRect() const override;
-  void OnSetFocus() override;
-  void OnKillFocus() override;
-
-  void SetAlignFormatH(PWL_EDIT_ALIGNFORMAT_H nFormat = PEAH_LEFT,
-                       FX_BOOL bPaint = TRUE);  // 0:left 1:right 2:middle
-  void SetAlignFormatV(PWL_EDIT_ALIGNFORMAT_V nFormat = PEAV_TOP,
-                       FX_BOOL bPaint = TRUE);  // 0:top 1:bottom 2:center
-
-  void SetCharArray(int32_t nCharArray);
-  void SetLimitChar(int32_t nLimitChar);
-
-  void SetHorzScale(int32_t nHorzScale, FX_BOOL bPaint = TRUE);
-  void SetCharSpace(FX_FLOAT fCharSpace, FX_BOOL bPaint = TRUE);
-
-  void SetLineLeading(FX_FLOAT fLineLeading, FX_BOOL bPaint = TRUE);
-
-  void EnableSpellCheck(FX_BOOL bEnabled);
-
-  FX_BOOL CanSelectAll() const;
-  FX_BOOL CanClear() const;
-  FX_BOOL CanCopy() const;
-  FX_BOOL CanCut() const;
-  FX_BOOL CanPaste() const;
-
-  virtual void CopyText();
-  virtual void PasteText();
-  virtual void CutText();
-
-  virtual void SetText(const FX_WCHAR* csText);
-  void ReplaceSel(const FX_WCHAR* csText);
-
-  CFX_ByteString GetTextAppearanceStream(const CPDF_Point& ptOffset) const;
-  CFX_ByteString GetCaretAppearanceStream(const CPDF_Point& ptOffset) const;
-  CFX_ByteString GetSelectAppearanceStream(const CPDF_Point& ptOffset) const;
-
-  FX_BOOL IsTextFull() const;
-
-  static FX_FLOAT GetCharArrayAutoFontSize(CPDF_Font* pFont,
-                                           const CPDF_Rect& rcPlate,
-                                           int32_t nCharArray);
-
-  void SetFillerNotify(IPWL_Filler_Notify* pNotify) {
-    m_pFillerNotify = pNotify;
-  }
-
-  void GeneratePageObjects(CPDF_PageObjects* pPageObjects,
-                           const CPDF_Point& ptOffset,
-                           CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray);
-  void GeneratePageObjects(CPDF_PageObjects* pPageObjects,
-                           const CPDF_Point& ptOffset);
-
- protected:
-  // IFX_Edit_OprNotify
-  void OnInsertWord(const CPVT_WordPlace& place,
-                    const CPVT_WordPlace& oldplace) override;
-  void OnInsertReturn(const CPVT_WordPlace& place,
-                      const CPVT_WordPlace& oldplace) override;
-  void OnBackSpace(const CPVT_WordPlace& place,
-                   const CPVT_WordPlace& oldplace) override;
-  void OnDelete(const CPVT_WordPlace& place,
-                const CPVT_WordPlace& oldplace) override;
-  void OnClear(const CPVT_WordPlace& place,
-               const CPVT_WordPlace& oldplace) override;
-  void OnSetText(const CPVT_WordPlace& place,
-                 const CPVT_WordPlace& oldplace) override;
-  void OnInsertText(const CPVT_WordPlace& place,
-                    const CPVT_WordPlace& oldplace) override;
-  void OnAddUndo(IFX_Edit_UndoItem* pUndoItem) override;
-
- private:
-  CPVT_WordRange GetSelectWordRange() const;
-  virtual void ShowVScrollBar(FX_BOOL bShow);
-  FX_BOOL IsVScrollBarVisible() const;
-  void SetParamByFlag();
-
-  FX_FLOAT GetCharArrayAutoFontSize(int32_t nCharArray);
-  CPDF_Point GetWordRightBottomPoint(const CPVT_WordPlace& wpWord);
-
-  CPVT_WordRange CombineWordRange(const CPVT_WordRange& wr1,
-                                  const CPVT_WordRange& wr2);
-  CPVT_WordRange GetLatinWordsRange(const CPDF_Point& point) const;
-  CPVT_WordRange GetLatinWordsRange(const CPVT_WordPlace& place) const;
-  CPVT_WordRange GetArabicWordsRange(const CPVT_WordPlace& place) const;
-  CPVT_WordRange GetSameWordsRange(const CPVT_WordPlace& place,
-                                   FX_BOOL bLatin,
-                                   FX_BOOL bArabic) const;
-
- public:
-  FX_BOOL IsProceedtoOnChar(FX_WORD nKeyCode, FX_DWORD nFlag);
-
- private:
-  IPWL_Filler_Notify* m_pFillerNotify;
-  IPWL_SpellCheck* m_pSpellCheck;
-  FX_BOOL m_bFocus;
-  CPDF_Rect m_rcOldWindow;
-
- public:
-  void AttachFFLData(void* pData) { m_pFormFiller = pData; }
-
- private:
-  void* m_pFormFiller;
-};
-
-#endif  // FPDFSDK_INCLUDE_PDFWINDOW_PWL_EDIT_H_
diff --git a/fpdfsdk/include/pdfwindow/PWL_EditCtrl.h b/fpdfsdk/include/pdfwindow/PWL_EditCtrl.h
deleted file mode 100644
index 0d5c931..0000000
--- a/fpdfsdk/include/pdfwindow/PWL_EditCtrl.h
+++ /dev/null
@@ -1,181 +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_PDFWINDOW_PWL_EDITCTRL_H_
-#define FPDFSDK_INCLUDE_PDFWINDOW_PWL_EDITCTRL_H_
-
-#include "PWL_Wnd.h"
-#include "core/include/fxcrt/fx_string.h"
-#include "fpdfsdk/include/fxedit/fx_edit.h"
-
-class CPWL_Caret;
-class CPWL_Edit;
-class CPWL_EditCtrl;
-class IFX_Edit;
-class IPWL_Edit_Notify;
-struct CPVT_WordPlace;
-
-enum PWL_EDIT_ALIGNFORMAT_H { PEAH_LEFT = 0, PEAH_MIDDLE, PEAH_RIGHT };
-
-enum PWL_EDIT_ALIGNFORMAT_V { PEAV_TOP = 0, PEAV_CENTER, PEAV_BOTTOM };
-
-class IPWL_Edit_Notify {
- public:
-  virtual ~IPWL_Edit_Notify() {}
-  // when the position of caret is changed in edit
-  virtual void OnCaretMove(int32_t x1, int32_t y1, int32_t x2, int32_t y2) {}
-  virtual void OnContentChange(const CPDF_Rect& rcContent) {}
-  // OprType: 0 InsertWord
-  // 1 InsertReturn
-  // 2 BackSpace
-  // 3 Delete
-  // 4 Clear
-  // 5 InsertText
-  // 6 SetText
-  virtual void OnInsertWord(const CPVT_WordPlace& place,
-                            const CPVT_WordPlace& oldplace) {}
-  virtual void OnInsertReturn(const CPVT_WordPlace& place,
-                              const CPVT_WordPlace& oldplace) {}
-  virtual void OnBackSpace(const CPVT_WordPlace& place,
-                           const CPVT_WordPlace& oldplace) {}
-  virtual void OnDelete(const CPVT_WordPlace& place,
-                        const CPVT_WordPlace& oldplace) {}
-  virtual void OnClear(const CPVT_WordPlace& place,
-                       const CPVT_WordPlace& oldplace) {}
-  virtual void OnInsertText(const CPVT_WordPlace& place,
-                            const CPVT_WordPlace& oldplace) {}
-  virtual void OnSetText(const CPVT_WordPlace& place,
-                         const CPVT_WordPlace& oldplace) {}
-  virtual void OnAddUndo(CPWL_Edit* pEdit) {}
-};
-
-class CPWL_EditCtrl : public CPWL_Wnd, public IFX_Edit_Notify {
-  friend class CPWL_Edit_Notify;
-
- public:
-  CPWL_EditCtrl();
-  ~CPWL_EditCtrl() override;
-
-  CPDF_Rect GetContentRect() const;
-  void GetCaretPos(int32_t& x, int32_t& y) const;
-
-  CFX_WideString GetText() const;
-  void SetSel(int32_t nStartChar, int32_t nEndChar);
-  void GetSel(int32_t& nStartChar, int32_t& nEndChar) const;
-  void GetTextRange(const CPDF_Rect& rect,
-                    int32_t& nStartChar,
-                    int32_t& nEndChar) const;
-  CFX_WideString GetText(int32_t& nStartChar, int32_t& nEndChar) const;
-  void Clear();
-  void SelectAll();
-
-  int32_t GetCaret() const;
-  void SetCaret(int32_t nPos);
-  int32_t GetTotalWords() const;
-
-  void Paint();
-
-  void EnableRefresh(FX_BOOL bRefresh);
-  CPDF_Point GetScrollPos() const;
-  void SetScrollPos(const CPDF_Point& point);
-
-  void SetEditNotify(IPWL_Edit_Notify* pNotify) { m_pEditNotify = pNotify; }
-
-  void SetCharSet(uint8_t nCharSet) { m_nCharSet = nCharSet; }
-  int32_t GetCharSet() const;
-
-  void SetCodePage(int32_t nCodePage) { m_nCodePage = nCodePage; }
-  int32_t GetCodePage() const { return m_nCodePage; }
-
-  CPDF_Font* GetCaretFont() const;
-  FX_FLOAT GetCaretFontSize() const;
-
-  FX_BOOL CanUndo() const;
-  FX_BOOL CanRedo() const;
-  void Redo();
-  void Undo();
-
-  void SetReadyToInput();
-
-  // CPWL_Wnd
-  void OnCreate(PWL_CREATEPARAM& cp) override;
-  void OnCreated() override;
-  FX_BOOL OnKeyDown(FX_WORD nChar, FX_DWORD nFlag) override;
-  FX_BOOL OnChar(FX_WORD nChar, FX_DWORD nFlag) override;
-  FX_BOOL OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) override;
-  FX_BOOL OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag) override;
-  FX_BOOL OnMouseMove(const CPDF_Point& point, FX_DWORD nFlag) override;
-  void OnNotify(CPWL_Wnd* pWnd,
-                FX_DWORD msg,
-                intptr_t wParam = 0,
-                intptr_t lParam = 0) override;
-  void CreateChildWnd(const PWL_CREATEPARAM& cp) override;
-  void RePosChildWnd() override;
-  void SetFontSize(FX_FLOAT fFontSize) override;
-  FX_FLOAT GetFontSize() const override;
-  void SetCursor() override;
-
- protected:
-  // IFX_Edit_Notify
-  void IOnSetScrollInfoX(FX_FLOAT fPlateMin,
-                         FX_FLOAT fPlateMax,
-                         FX_FLOAT fContentMin,
-                         FX_FLOAT fContentMax,
-                         FX_FLOAT fSmallStep,
-                         FX_FLOAT fBigStep) override {}
-  void IOnSetScrollInfoY(FX_FLOAT fPlateMin,
-                         FX_FLOAT fPlateMax,
-                         FX_FLOAT fContentMin,
-                         FX_FLOAT fContentMax,
-                         FX_FLOAT fSmallStep,
-                         FX_FLOAT fBigStep) override;
-  void IOnSetScrollPosX(FX_FLOAT fx) override {}
-  void IOnSetScrollPosY(FX_FLOAT fy) override;
-  void IOnSetCaret(FX_BOOL bVisible,
-                   const CPDF_Point& ptHead,
-                   const CPDF_Point& ptFoot,
-                   const CPVT_WordPlace& place) override;
-  void IOnCaretChange(const CPVT_SecProps& secProps,
-                      const CPVT_WordProps& wordProps) override;
-  void IOnContentChange(const CPDF_Rect& rcContent) override;
-  void IOnInvalidateRect(CPDF_Rect* pRect) override;
-
-  void InsertText(const FX_WCHAR* csText);
-  void SetText(const FX_WCHAR* csText);
-  void CopyText();
-  void PasteText();
-  void CutText();
-  void ShowVScrollBar(FX_BOOL bShow);
-  void InsertWord(FX_WORD word, int32_t nCharset);
-  void InsertReturn();
-
-  FX_BOOL IsWndHorV();
-
-  void Delete();
-  void Backspace();
-
-  void GetCaretInfo(CPDF_Point& ptHead, CPDF_Point& ptFoot) const;
-  void SetCaret(FX_BOOL bVisible,
-                const CPDF_Point& ptHead,
-                const CPDF_Point& ptFoot);
-
-  void SetEditCaret(FX_BOOL bVisible);
-
- private:
-  void CreateEditCaret(const PWL_CREATEPARAM& cp);
-
- protected:
-  IFX_Edit* m_pEdit;
-  CPWL_Caret* m_pEditCaret;
-  FX_BOOL m_bMouseDown;
-  IPWL_Edit_Notify* m_pEditNotify;
-
- private:
-  int32_t m_nCharSet;
-  int32_t m_nCodePage;
-};
-
-#endif  // FPDFSDK_INCLUDE_PDFWINDOW_PWL_EDITCTRL_H_
diff --git a/fpdfsdk/include/pdfwindow/PWL_FontMap.h b/fpdfsdk/include/pdfwindow/PWL_FontMap.h
deleted file mode 100644
index c8c8722..0000000
--- a/fpdfsdk/include/pdfwindow/PWL_FontMap.h
+++ /dev/null
@@ -1,137 +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_PDFWINDOW_PWL_FONTMAP_H_
-#define FPDFSDK_INCLUDE_PDFWINDOW_PWL_FONTMAP_H_
-
-#include "fpdfsdk/include/fxedit/fx_edit.h"
-#include "public/fpdf_sysfontinfo.h"
-
-class CPDF_Document;
-class IFX_SystemHandler;
-
-struct CPWL_FontMap_Data {
-  CPDF_Font* pFont;
-  int32_t nCharset;
-  CFX_ByteString sFontName;
-};
-
-struct CPWL_FontMap_Native {
-  int32_t nCharset;
-  CFX_ByteString sFontName;
-};
-
-#ifndef ANSI_CHARSET
-
-#define ANSI_CHARSET 0
-#define DEFAULT_CHARSET 1
-#define SYMBOL_CHARSET 2
-#define SHIFTJIS_CHARSET 128
-#define HANGEUL_CHARSET 129
-#define HANGUL_CHARSET 129
-#define GB2312_CHARSET 134
-#define CHINESEBIG5_CHARSET 136
-#define OEM_CHARSET 255
-#define JOHAB_CHARSET 130
-#define HEBREW_CHARSET 177
-#define ARABIC_CHARSET 178
-#define GREEK_CHARSET 161
-#define TURKISH_CHARSET 162
-#define VIETNAMESE_CHARSET 163
-#define THAI_CHARSET 222
-#define EASTEUROPE_CHARSET 238
-#define RUSSIAN_CHARSET 204
-#define BALTIC_CHARSET 186
-
-#endif
-
-class CPWL_FontMap : public IFX_Edit_FontMap {
- public:
-  CPWL_FontMap(IFX_SystemHandler* pSystemHandler);
-  ~CPWL_FontMap() override;
-
-  // IFX_Edit_FontMap
-  CPDF_Font* GetPDFFont(int32_t nFontIndex) override;
-  CFX_ByteString GetPDFFontAlias(int32_t nFontIndex) override;
-  int32_t GetWordFontIndex(FX_WORD word,
-                           int32_t nCharset,
-                           int32_t nFontIndex) override;
-  int32_t CharCodeFromUnicode(int32_t nFontIndex, FX_WORD word) override;
-  int32_t CharSetFromUnicode(FX_WORD word, int32_t nOldCharset) override;
-
-  void SetSystemHandler(IFX_SystemHandler* pSystemHandler);
-  int32_t GetFontMapCount() const;
-  const CPWL_FontMap_Data* GetFontMapData(int32_t nIndex) const;
-  static int32_t GetNativeCharset();
-  CFX_ByteString GetNativeFontName(int32_t nCharset);
-
-  static CFX_ByteString GetDefaultFontByCharset(int32_t nCharset);
-
-  CPDF_Font* AddFontToDocument(CPDF_Document* pDoc,
-                               CFX_ByteString& sFontName,
-                               uint8_t nCharset);
-  static FX_BOOL IsStandardFont(const CFX_ByteString& sFontName);
-  CPDF_Font* AddStandardFont(CPDF_Document* pDoc, CFX_ByteString& sFontName);
-  CPDF_Font* AddSystemFont(CPDF_Document* pDoc,
-                           CFX_ByteString& sFontName,
-                           uint8_t nCharset);
-
- protected:
-  virtual void Initialize();
-  virtual CPDF_Document* GetDocument();
-  virtual CPDF_Font* FindFontSameCharset(CFX_ByteString& sFontAlias,
-                                         int32_t nCharset);
-  virtual void AddedFont(CPDF_Font* pFont, const CFX_ByteString& sFontAlias);
-
-  FX_BOOL KnowWord(int32_t nFontIndex, FX_WORD word);
-
-  void Empty();
-  int32_t GetFontIndex(const CFX_ByteString& sFontName,
-                       int32_t nCharset,
-                       FX_BOOL bFind);
-  int32_t GetPWLFontIndex(FX_WORD word, int32_t nCharset);
-  int32_t AddFontData(CPDF_Font* pFont,
-                      const CFX_ByteString& sFontAlias,
-                      int32_t nCharset = DEFAULT_CHARSET);
-
-  CFX_ByteString EncodeFontAlias(const CFX_ByteString& sFontName,
-                                 int32_t nCharset);
-  CFX_ByteString EncodeFontAlias(const CFX_ByteString& sFontName);
-
- private:
-  CFX_ByteString GetFontName(int32_t nFontIndex);
-  int32_t FindFont(const CFX_ByteString& sFontName,
-                   int32_t nCharset = DEFAULT_CHARSET);
-
-  CFX_ByteString GetNativeFont(int32_t nCharset);
-
- public:
-  using CharsetFontMap = FPDF_CharsetFontMap;
-  static const CharsetFontMap defaultTTFMap[];
-
- protected:
-  CFX_ArrayTemplate<CPWL_FontMap_Data*> m_aData;
-  CFX_ArrayTemplate<CPWL_FontMap_Native*> m_aNativeFont;
-
- private:
-  CPDF_Document* m_pPDFDoc;
-  IFX_SystemHandler* m_pSystemHandler;
-};
-
-class CPWL_DocFontMap : public CPWL_FontMap {
- public:
-  CPWL_DocFontMap(IFX_SystemHandler* pSystemHandler,
-                  CPDF_Document* pAttachedDoc);
-  ~CPWL_DocFontMap() override;
-
- private:
-  // CPWL_FontMap:
-  CPDF_Document* GetDocument() override;
-
-  CPDF_Document* m_pAttachedDoc;
-};
-
-#endif  // FPDFSDK_INCLUDE_PDFWINDOW_PWL_FONTMAP_H_
diff --git a/fpdfsdk/include/pdfwindow/PWL_IconList.h b/fpdfsdk/include/pdfwindow/PWL_IconList.h
deleted file mode 100644
index 0a21bbe..0000000
--- a/fpdfsdk/include/pdfwindow/PWL_IconList.h
+++ /dev/null
@@ -1,129 +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_PDFWINDOW_PWL_ICONLIST_H_
-#define FPDFSDK_INCLUDE_PDFWINDOW_PWL_ICONLIST_H_
-
-#include "PWL_ListCtrl.h"
-#include "PWL_Wnd.h"
-#include "core/include/fxcrt/fx_string.h"
-
-class IPWL_IconList_Notify;
-class CPWL_IconList_Item;
-class CPWL_IconList_Content;
-class CPWL_IconList;
-class CPWL_Label;
-
-class IPWL_IconList_Notify {
- public:
-  virtual ~IPWL_IconList_Notify() {}
-  virtual void OnNoteListSelChanged(int32_t nItemIndex) = 0;
-};
-
-class CPWL_IconList_Item : public CPWL_Wnd {
- public:
-  CPWL_IconList_Item();
-  ~CPWL_IconList_Item() override;
-
-  void SetSelect(FX_BOOL bSelected);
-  FX_BOOL IsSelected() const;
-  void SetData(void* pData);
-  void SetIcon(int32_t nIconIndex);
-  void SetText(const CFX_WideString& str);
-  void SetIconFillColor(const CPWL_Color& color);
-  CFX_WideString GetText() const;
-
- protected:
-  // CPWL_Wnd
-  CFX_ByteString GetClassName() const override;
-  void CreateChildWnd(const PWL_CREATEPARAM& cp) override;
-  void RePosChildWnd() override;
-  FX_FLOAT GetItemHeight(FX_FLOAT fLimitWidth) override;
-  void DrawThisAppearance(CFX_RenderDevice* pDevice,
-                          CFX_Matrix* pUser2Device) override;
-  void OnEnabled() override;
-  void OnDisabled() override;
-
- private:
-  int32_t m_nIconIndex;
-  void* m_pData;
-  FX_BOOL m_bSelected;
-  CPWL_Label* m_pText;
-  CPWL_Color m_crIcon;
-};
-
-class CPWL_IconList_Content : public CPWL_ListCtrl {
- public:
-  CPWL_IconList_Content(int32_t nListCount);
-  ~CPWL_IconList_Content() override;
-
-  void SetSelect(int32_t nIndex);
-  int32_t GetSelect() const;
-  void SetNotify(IPWL_IconList_Notify* pNotify);
-  void EnableNotify(FX_BOOL bNotify);
-  void SetListData(int32_t nItemIndex, void* pData);
-  void SetListIcon(int32_t nItemIndex, int32_t nIconIndex);
-  void SetListString(int32_t nItemIndex, const CFX_WideString& str);
-  void SetIconFillColor(const CPWL_Color& color);
-  CFX_WideString GetListString(int32_t nItemIndex) const;
-  IPWL_IconList_Notify* GetNotify() const;
-  void ScrollToItem(int32_t nItemIndex);
-
- protected:
-  // CPWL_ListCtrl
-  void CreateChildWnd(const PWL_CREATEPARAM& cp) override;
-  FX_BOOL OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) override;
-  FX_BOOL OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag) override;
-  FX_BOOL OnMouseMove(const CPDF_Point& point, FX_DWORD nFlag) override;
-  FX_BOOL OnKeyDown(FX_WORD nChar, FX_DWORD nFlag) override;
-
- private:
-  CPWL_IconList_Item* GetListItem(int32_t nItemIndex) const;
-  void SelectItem(int32_t nItemIndex, FX_BOOL bSelect);
-  int32_t FindItemIndex(const CPDF_Point& point);
-
-  int32_t m_nSelectIndex;
-  IPWL_IconList_Notify* m_pNotify;
-  FX_BOOL m_bEnableNotify;
-  FX_BOOL m_bMouseDown;
-  int32_t m_nListCount;
-};
-
-class CPWL_IconList : public CPWL_Wnd {
- public:
-  CPWL_IconList(int32_t nListCount);
-  ~CPWL_IconList() override;
-
-  void SetSelect(int32_t nIndex);
-  void SetTopItem(int32_t nIndex);
-  int32_t GetSelect() const;
-  void SetNotify(IPWL_IconList_Notify* pNotify);
-  void EnableNotify(FX_BOOL bNotify);
-  void SetListData(int32_t nItemIndex, void* pData);
-  void SetListIcon(int32_t nItemIndex, int32_t nIconIndex);
-  void SetListString(int32_t nItemIndex, const CFX_WideString& str);
-  void SetIconFillColor(const CPWL_Color& color);
-  CFX_WideString GetListString(int32_t nItemIndex) const;
-
- protected:
-  // CPWL_Wnd
-  FX_BOOL OnMouseWheel(short zDelta,
-                       const CPDF_Point& point,
-                       FX_DWORD nFlag) override;
-  void OnCreated() override;
-  void RePosChildWnd() override;
-  void CreateChildWnd(const PWL_CREATEPARAM& cp) override;
-  void OnNotify(CPWL_Wnd* pWnd,
-                FX_DWORD msg,
-                intptr_t wParam = 0,
-                intptr_t lParam = 0) override;
-
- private:
-  CPWL_IconList_Content* m_pListContent;
-  int32_t m_nListCount;
-};
-
-#endif  // FPDFSDK_INCLUDE_PDFWINDOW_PWL_ICONLIST_H_
diff --git a/fpdfsdk/include/pdfwindow/PWL_Label.h b/fpdfsdk/include/pdfwindow/PWL_Label.h
deleted file mode 100644
index aba84fb..0000000
--- a/fpdfsdk/include/pdfwindow/PWL_Label.h
+++ /dev/null
@@ -1,45 +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_PDFWINDOW_PWL_LABEL_H_
-#define FPDFSDK_INCLUDE_PDFWINDOW_PWL_LABEL_H_
-
-#include "PWL_Wnd.h"
-
-class IFX_Edit;
-
-class CPWL_Label : public CPWL_Wnd {
- public:
-  CPWL_Label();
-  ~CPWL_Label() override;
-
-  void SetText(const FX_WCHAR* csText);
-  CFX_WideString GetText() const;
-  void SetLimitChar(int32_t nLimitChar);
-  void SetHorzScale(int32_t nHorzScale);
-  void SetCharSpace(FX_FLOAT fCharSpace);
-  CPDF_Rect GetContentRect() const;
-  int32_t GetTotalWords();
-  CFX_ByteString GetTextAppearanceStream(const CPDF_Point& ptOffset) const;
-
- protected:
-  // CPWL_Wnd
-  CFX_ByteString GetClassName() const override;
-  void SetFontSize(FX_FLOAT fFontSize) override;
-  FX_FLOAT GetFontSize() const override;
-  void OnCreated() override;
-  void DrawThisAppearance(CFX_RenderDevice* pDevice,
-                          CFX_Matrix* pUser2Device) override;
-  void GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) override;
-  void RePosChildWnd() override;
-
- private:
-  void SetParamByFlag();
-
-  IFX_Edit* m_pEdit;
-};
-
-#endif  // FPDFSDK_INCLUDE_PDFWINDOW_PWL_LABEL_H_
diff --git a/fpdfsdk/include/pdfwindow/PWL_ListBox.h b/fpdfsdk/include/pdfwindow/PWL_ListBox.h
deleted file mode 100644
index 807f11e..0000000
--- a/fpdfsdk/include/pdfwindow/PWL_ListBox.h
+++ /dev/null
@@ -1,123 +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_PDFWINDOW_PWL_LISTBOX_H_
-#define FPDFSDK_INCLUDE_PDFWINDOW_PWL_LISTBOX_H_
-
-#include "PWL_Wnd.h"
-#include "fpdfsdk/include/fxedit/fx_edit.h"
-
-class CPDF_ListCtrl;
-class CPWL_List_Notify;
-class CPWL_ListBox;
-class IPWL_Filler_Notify;
-
-class CPWL_List_Notify : public IFX_List_Notify {
- public:
-  CPWL_List_Notify(CPWL_ListBox* pList);
-  ~CPWL_List_Notify() override;
-
-  // IFX_List_Notify
-  void IOnSetScrollInfoX(FX_FLOAT fPlateMin,
-                         FX_FLOAT fPlateMax,
-                         FX_FLOAT fContentMin,
-                         FX_FLOAT fContentMax,
-                         FX_FLOAT fSmallStep,
-                         FX_FLOAT fBigStep) override {}
-  void IOnSetScrollInfoY(FX_FLOAT fPlateMin,
-                         FX_FLOAT fPlateMax,
-                         FX_FLOAT fContentMin,
-                         FX_FLOAT fContentMax,
-                         FX_FLOAT fSmallStep,
-                         FX_FLOAT fBigStep) override;
-  void IOnSetScrollPosX(FX_FLOAT fx) override {}
-  void IOnSetScrollPosY(FX_FLOAT fy) override;
-  void IOnInvalidateRect(CPDF_Rect* pRect) override;
-
-  void IOnSetCaret(FX_BOOL bVisible,
-                   const CPDF_Point& ptHead,
-                   const CPDF_Point& ptFoot,
-                   const CPVT_WordPlace& place);
-  void IOnCaretChange(const CPVT_SecProps& secProps,
-                      const CPVT_WordProps& wordProps);
-
- private:
-  CPWL_ListBox* m_pList;
-};
-
-class CPWL_ListBox : public CPWL_Wnd {
- public:
-  CPWL_ListBox();
-  ~CPWL_ListBox() override;
-
-  // CPWL_Wnd
-  CFX_ByteString GetClassName() const override;
-  void OnCreated() override;
-  void OnDestroy() override;
-  void GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) override;
-  void DrawThisAppearance(CFX_RenderDevice* pDevice,
-                          CFX_Matrix* pUser2Device) override;
-  FX_BOOL OnKeyDown(FX_WORD nChar, FX_DWORD nFlag) override;
-  FX_BOOL OnChar(FX_WORD nChar, FX_DWORD nFlag) override;
-  FX_BOOL OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) override;
-  FX_BOOL OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag) override;
-  FX_BOOL OnMouseMove(const CPDF_Point& point, FX_DWORD nFlag) override;
-  FX_BOOL OnMouseWheel(short zDelta,
-                       const CPDF_Point& point,
-                       FX_DWORD nFlag) override;
-  void KillFocus() override;
-  void OnNotify(CPWL_Wnd* pWnd,
-                FX_DWORD msg,
-                intptr_t wParam = 0,
-                intptr_t lParam = 0) override;
-  void RePosChildWnd() override;
-  CPDF_Rect GetFocusRect() const override;
-  void SetFontSize(FX_FLOAT fFontSize) override;
-  FX_FLOAT GetFontSize() const override;
-
-  virtual CFX_WideString GetText() const;
-
-  void OnNotifySelChanged(FX_BOOL bKeyDown, FX_BOOL& bExit, FX_DWORD nFlag);
-
-  void AddString(const FX_WCHAR* string);
-  void SetTopVisibleIndex(int32_t nItemIndex);
-  void ScrollToListItem(int32_t nItemIndex);
-  void ResetContent();
-  void Reset();
-  void Select(int32_t nItemIndex);
-  void SetCaret(int32_t nItemIndex);
-  void SetHoverSel(FX_BOOL bHoverSel);
-
-  int32_t GetCount() const;
-  FX_BOOL IsMultipleSel() const;
-  int32_t GetCaretIndex() const;
-  int32_t GetCurSel() const;
-  FX_BOOL IsItemSelected(int32_t nItemIndex) const;
-  int32_t GetTopVisibleIndex() const;
-  int32_t FindNext(int32_t nIndex, FX_WCHAR nChar) const;
-  CPDF_Rect GetContentRect() const;
-  FX_FLOAT GetFirstHeight() const;
-  CPDF_Rect GetListRect() const;
-
-  void SetFillerNotify(IPWL_Filler_Notify* pNotify) {
-    m_pFillerNotify = pNotify;
-  }
-
- protected:
-  IFX_List* m_pList;
-  CPWL_List_Notify* m_pListNotify;
-  FX_BOOL m_bMouseDown;
-  FX_BOOL m_bHoverSel;
-  IPWL_Filler_Notify* m_pFillerNotify;
-
- public:
-  void AttachFFLData(void* pData) { m_pFormFiller = pData; }
-
- private:
-  void* m_pFormFiller;
-};
-
-#endif  // FPDFSDK_INCLUDE_PDFWINDOW_PWL_LISTBOX_H_
diff --git a/fpdfsdk/include/pdfwindow/PWL_ListCtrl.h b/fpdfsdk/include/pdfwindow/PWL_ListCtrl.h
deleted file mode 100644
index 4c96d43..0000000
--- a/fpdfsdk/include/pdfwindow/PWL_ListCtrl.h
+++ /dev/null
@@ -1,48 +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_PDFWINDOW_PWL_LISTCTRL_H_
-#define FPDFSDK_INCLUDE_PDFWINDOW_PWL_LISTCTRL_H_
-
-#include "PWL_Wnd.h"
-
-class CPWL_ListCtrl : public CPWL_Wnd {
- public:
-  CPWL_ListCtrl();
-  ~CPWL_ListCtrl() override;
-
-  void SetScrollPos(const CPDF_Point& point);
-  CPDF_Point GetScrollPos() const;
-  CPDF_Rect GetScrollArea() const;
-  void SetItemSpace(FX_FLOAT fSpace);
-  void SetTopSpace(FX_FLOAT fSpace);
-  void SetBottomSpace(FX_FLOAT fSpace);
-  void ResetFace();
-  void ResetContent(int32_t nStart);
-  int32_t GetItemIndex(CPWL_Wnd* pItem);
-  FX_FLOAT GetContentsHeight(FX_FLOAT fLimitWidth);
-  CPDF_Point InToOut(const CPDF_Point& point) const;
-  CPDF_Point OutToIn(const CPDF_Point& point) const;
-  CPDF_Rect InToOut(const CPDF_Rect& rect) const;
-  CPDF_Rect OutToIn(const CPDF_Rect& rect) const;
-
- protected:
-  // CPWL_Wnd
-  void RePosChildWnd() override;
-  void DrawChildAppearance(CFX_RenderDevice* pDevice,
-                           CFX_Matrix* pUser2Device) override;
-
- private:
-  void ResetAll(FX_BOOL bMove, int32_t nStart);
-
-  CPDF_Rect m_rcContent;
-  CPDF_Point m_ptScroll;
-  FX_FLOAT m_fItemSpace;
-  FX_FLOAT m_fTopSpace;
-  FX_FLOAT m_fBottomSpace;
-};
-
-#endif  // FPDFSDK_INCLUDE_PDFWINDOW_PWL_LISTCTRL_H_
diff --git a/fpdfsdk/include/pdfwindow/PWL_Note.h b/fpdfsdk/include/pdfwindow/PWL_Note.h
deleted file mode 100644
index 9946f44..0000000
--- a/fpdfsdk/include/pdfwindow/PWL_Note.h
+++ /dev/null
@@ -1,351 +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_PDFWINDOW_PWL_NOTE_H_
-#define FPDFSDK_INCLUDE_PDFWINDOW_PWL_NOTE_H_
-
-#include "PWL_Button.h"
-#include "PWL_Edit.h"
-#include "PWL_ListCtrl.h"
-#include "PWL_ScrollBar.h"
-#include "PWL_Wnd.h"
-
-class CPWL_Label;
-class CPWL_Note;
-class CPWL_NoteItem;
-class CPWL_Note_CloseBox;
-class CPWL_Note_Contents;
-class CPWL_Note_Edit;
-class CPWL_Note_Icon;
-class CPWL_Note_LBBox;
-class CPWL_Note_Options;
-class CPWL_Note_RBBox;
-class IPWL_NoteHandler;
-class IPWL_NoteItem;
-class IPWL_NoteNotify;
-class IPopup_Note;
-
-class IPWL_NoteNotify {
- public:
-  virtual ~IPWL_NoteNotify() {}
-  virtual void OnNoteMove(const FX_RECT& rtWin) = 0;
-  virtual void OnNoteShow(FX_BOOL bShow) = 0;
-  virtual void OnNoteActivate(FX_BOOL bActive) = 0;
-  virtual void OnNoteClose() = 0;
-  virtual void OnItemCreate(IPWL_NoteItem* pItem) = 0;
-  virtual void OnItemDelete(IPWL_NoteItem* pItem) = 0;
-  virtual void OnSetAuthorName(IPWL_NoteItem* pItem) = 0;
-  virtual void OnSetBkColor(IPWL_NoteItem* pItem) = 0;
-  virtual void OnSetContents(IPWL_NoteItem* pItem) = 0;
-  virtual void OnSetDateTime(IPWL_NoteItem* pItem) = 0;
-  virtual void OnSetSubjectName(IPWL_NoteItem* pItem) = 0;
-  virtual void OnPopupMenu(int32_t x, int32_t y) = 0;
-  virtual void OnPopupMenu(IPWL_NoteItem* pItem, int32_t x, int32_t y) = 0;
-};
-
-class IPWL_NoteHandler {
- public:
-  virtual ~IPWL_NoteHandler() {}
-  virtual void OnNoteColorChanged(const CPWL_Color& color) = 0;
-};
-
-class IPWL_NoteItem {
- public:
-  virtual ~IPWL_NoteItem() {}
-  virtual void SetPrivateData(void* pData) = 0;
-  virtual void SetBkColor(const CPWL_Color& color) = 0;
-  virtual void SetSubjectName(const CFX_WideString& sName) = 0;
-  virtual void SetAuthorName(const CFX_WideString& sName) = 0;
-  virtual void SetDateTime(FX_SYSTEMTIME time) = 0;
-  virtual void SetContents(const CFX_WideString& sContents) = 0;
-
-  virtual IPWL_NoteItem* CreateSubItem() = 0;
-  virtual int32_t CountSubItems() const = 0;
-  virtual IPWL_NoteItem* GetSubItems(int32_t index) const = 0;
-  virtual void DeleteSubItem(IPWL_NoteItem* pNoteItem) = 0;
-  virtual void SetFocus() = 0;
-
-  virtual IPWL_NoteItem* GetParentItem() const = 0;
-  virtual void* GetPrivateData() const = 0;
-  virtual CFX_WideString GetAuthorName() const = 0;
-  virtual CPWL_Color GetBkColor() const = 0;
-  virtual CFX_WideString GetContents() const = 0;
-  virtual FX_SYSTEMTIME GetDateTime() const = 0;
-  virtual CFX_WideString GetSubjectName() const = 0;
-
-  virtual CPWL_Edit* GetEdit() const = 0;
-};
-
-class CPWL_Note_Icon : public CPWL_Wnd {
- public:
-  CPWL_Note_Icon();
-  ~CPWL_Note_Icon() override;
-
-  void SetIconType(int32_t nType);
-
- protected:
-  // CPWL_Wnd
-  void DrawThisAppearance(CFX_RenderDevice* pDevice,
-                          CFX_Matrix* pUser2Device) override;
-
- private:
-  int32_t m_nType;
-};
-
-class CPWL_Note_CloseBox : public CPWL_Button {
- public:
-  CPWL_Note_CloseBox();
-  ~CPWL_Note_CloseBox() override;
-
- protected:
-  // CPWL_Button
-  void DrawThisAppearance(CFX_RenderDevice* pDevice,
-                          CFX_Matrix* pUser2Device) override;
-  FX_BOOL OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) override;
-  FX_BOOL OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag) override;
-
- private:
-  FX_BOOL m_bMouseDown;
-};
-
-class CPWL_Note_LBBox : public CPWL_Wnd {
- public:
-  CPWL_Note_LBBox();
-  ~CPWL_Note_LBBox() override;
-
- protected:
-  // CPWL_Wnd
-  void DrawThisAppearance(CFX_RenderDevice* pDevice,
-                          CFX_Matrix* pUser2Device) override;
-};
-
-class CPWL_Note_RBBox : public CPWL_Wnd {
- public:
-  CPWL_Note_RBBox();
-  ~CPWL_Note_RBBox() override;
-
- protected:
-  // CPWL_Wnd
-  void DrawThisAppearance(CFX_RenderDevice* pDevice,
-                          CFX_Matrix* pUser2Device) override;
-};
-
-class CPWL_Note_Edit : public CPWL_Edit {
- public:
-  CPWL_Note_Edit();
-  ~CPWL_Note_Edit() override;
-
-  void EnableNotify(FX_BOOL bEnable) { m_bEnableNotify = bEnable; }
-
-  // CPWL_Edit
-  FX_FLOAT GetItemLeftMargin() override;
-  FX_FLOAT GetItemRightMargin() override;
-  FX_FLOAT GetItemHeight(FX_FLOAT fLimitWidth) override;
-  void SetText(const FX_WCHAR* csText) override;
-  void OnNotify(CPWL_Wnd* pWnd,
-                FX_DWORD msg,
-                intptr_t wParam = 0,
-                intptr_t lParam = 0) override;
-  void RePosChildWnd() override;
-  void OnSetFocus() override;
-  void OnKillFocus() override;
-
- private:
-  FX_BOOL m_bEnableNotify;
-  FX_FLOAT m_fOldItemHeight;
-  FX_BOOL m_bSizeChanged;
-  FX_FLOAT m_fOldMin;
-  FX_FLOAT m_fOldMax;
-};
-
-class CPWL_Note_Options : public CPWL_Wnd {
- public:
-  CPWL_Note_Options();
-  ~CPWL_Note_Options() override;
-
-  CPDF_Rect GetContentRect() const;
-  void SetText(const CFX_WideString& sText);
-
-  // CPWL_Wnd
-  void RePosChildWnd() override;
-  void CreateChildWnd(const PWL_CREATEPARAM& cp) override;
-  void DrawThisAppearance(CFX_RenderDevice* pDevice,
-                          CFX_Matrix* pUser2Device) override;
-  void SetTextColor(const CPWL_Color& color) override;
-
- private:
-  CPWL_Label* m_pText;
-};
-
-class CPWL_Note_Contents : public CPWL_ListCtrl {
- public:
-  CPWL_Note_Contents();
-  ~CPWL_Note_Contents() override;
-
-  void SetEditFocus(FX_BOOL bLast);
-  CPWL_Edit* GetEdit() const;
-
-  void SetText(const CFX_WideString& sText);
-  CFX_WideString GetText() const;
-
-  CPWL_NoteItem* CreateSubItem();
-  void DeleteSubItem(IPWL_NoteItem* pNoteItem);
-  int32_t CountSubItems() const;
-  IPWL_NoteItem* GetSubItems(int32_t index) const;
-
-  virtual IPWL_NoteItem* GetHitNoteItem(const CPDF_Point& point);
-  void EnableRead(FX_BOOL bEnabled);
-  void EnableModify(FX_BOOL bEnabled);
-
-  // CPWL_ListCtrl
-  CFX_ByteString GetClassName() const override;
-  void OnNotify(CPWL_Wnd* pWnd,
-                FX_DWORD msg,
-                intptr_t wParam = 0,
-                intptr_t lParam = 0) override;
-  FX_BOOL OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) override;
-  void CreateChildWnd(const PWL_CREATEPARAM& cp) override;
-
- private:
-  CPWL_Note_Edit* m_pEdit;
-};
-
-class CPWL_NoteItem : public CPWL_Wnd, public IPWL_NoteItem {
- public:
-  CPWL_NoteItem();
-  ~CPWL_NoteItem() override;
-
-  virtual IPWL_NoteItem* GetHitNoteItem(const CPDF_Point& point);
-  virtual IPWL_NoteItem* GetFocusedNoteItem() const;
-
-  virtual FX_BOOL IsTopItem() const { return FALSE; }
-
-  virtual void ResetSubjectName(int32_t nItemIndex);
-  void EnableRead(FX_BOOL bEnabled);
-  void EnableModify(FX_BOOL bEnabled);
-
-  void OnContentsValidate();
-  void OnCreateNoteItem();
-
-  // IPWL_NoteItem
-  void SetPrivateData(void* pData) override;
-  void SetBkColor(const CPWL_Color& color) override;
-  void SetSubjectName(const CFX_WideString& sName) override;
-  void SetAuthorName(const CFX_WideString& sName) override;
-  void SetDateTime(FX_SYSTEMTIME time) override;
-  void SetContents(const CFX_WideString& sContents) override;
-  IPWL_NoteItem* CreateSubItem() override;
-  int32_t CountSubItems() const override;
-  IPWL_NoteItem* GetSubItems(int32_t index) const override;
-  void DeleteSubItem(IPWL_NoteItem* pNoteItem) override;
-  void SetFocus() override { SetNoteFocus(FALSE); }
-  IPWL_NoteItem* GetParentItem() const override;
-  void* GetPrivateData() const override;
-  CFX_WideString GetAuthorName() const override;
-  CPWL_Color GetBkColor() const override;
-  CFX_WideString GetContents() const override;
-  FX_SYSTEMTIME GetDateTime() const override;
-  CFX_WideString GetSubjectName() const override;
-  CPWL_Edit* GetEdit() const override;
-
- protected:
-  // CPWL_Wnd
-  FX_BOOL OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) override;
-  FX_BOOL OnRButtonUp(const CPDF_Point& point, FX_DWORD nFlag) override;
-  CFX_ByteString GetClassName() const override;
-  void RePosChildWnd() override;
-  void CreateChildWnd(const PWL_CREATEPARAM& cp) override;
-  void OnNotify(CPWL_Wnd* pWnd,
-                FX_DWORD msg,
-                intptr_t wParam = 0,
-                intptr_t lParam = 0) override;
-  FX_FLOAT GetItemHeight(FX_FLOAT fLimitWidth) override;
-  FX_FLOAT GetItemLeftMargin() override;
-  FX_FLOAT GetItemRightMargin() override;
-
-  CPWL_NoteItem* CreateNoteItem();
-  CPWL_NoteItem* GetParentNoteItem() const;
-
-  void SetNoteFocus(FX_BOOL bLast);
-  void PopupNoteItemMenu(const CPDF_Point& point);
-
-  virtual const CPWL_Note* GetNote() const;
-  virtual IPWL_NoteNotify* GetNoteNotify() const;
-
- protected:
-  CPWL_Label* m_pSubject;
-  CPWL_Label* m_pDateTime;
-  CPWL_Note_Contents* m_pContents;
-
- private:
-  void* m_pPrivateData;
-  FX_SYSTEMTIME m_dtNote;
-  CFX_WideString m_sAuthor;
-
-  FX_FLOAT m_fOldItemHeight;
-  FX_BOOL m_bSizeChanged;
-  FX_BOOL m_bAllowModify;
-};
-
-class CPWL_Note : public CPWL_NoteItem {
- public:
-  CPWL_Note(IPopup_Note* pPopupNote,
-            IPWL_NoteNotify* pNoteNotify,
-            IPWL_NoteHandler* pNoteHandler);
-  ~CPWL_Note() override;
-
-  IPWL_NoteItem* Reply();
-  void EnableNotify(FX_BOOL bEnabled);
-  void SetIconType(int32_t nType);
-  void SetOptionsText(const CFX_WideString& sText);
-  void EnableRead(FX_BOOL bEnabled);
-  void EnableModify(FX_BOOL bEnabled);
-
-  CFX_WideString GetReplyString() const;
-  void SetReplyString(const CFX_WideString& string);
-
-  // CPWL_NoteItem
-  void SetSubjectName(const CFX_WideString& sName) override;
-  void SetAuthorName(const CFX_WideString& sName) override;
-  CFX_WideString GetAuthorName() const override;
-  void SetBkColor(const CPWL_Color& color) override;
-  void ResetSubjectName(int32_t nItemIndex) override {}
-  FX_BOOL IsTopItem() const override { return TRUE; }
-  const CPWL_Note* GetNote() const override;
-  IPWL_NoteNotify* GetNoteNotify() const override;
-  FX_BOOL OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) override;
-  FX_BOOL OnRButtonUp(const CPDF_Point& point, FX_DWORD nFlag) override;
-  FX_BOOL OnMouseWheel(short zDelta,
-                       const CPDF_Point& point,
-                       FX_DWORD nFlag) override;
-  void RePosChildWnd() override;
-  void CreateChildWnd(const PWL_CREATEPARAM& cp) override;
-  void OnNotify(CPWL_Wnd* pWnd,
-                FX_DWORD msg,
-                intptr_t wParam = 0,
-                intptr_t lParam = 0) override;
-
- protected:
-  FX_BOOL ResetScrollBar();
-  void RePosNoteChildren();
-  FX_BOOL ScrollBarShouldVisible();
-
- private:
-  CPWL_Label* m_pAuthor;
-  CPWL_Note_Icon* m_pIcon;
-  CPWL_Note_CloseBox* m_pCloseBox;
-  CPWL_Note_LBBox* m_pLBBox;
-  CPWL_Note_RBBox* m_pRBBox;
-  CPWL_ScrollBar* m_pContentsBar;
-  CPWL_Note_Options* m_pOptions;
-  IPWL_NoteNotify* m_pNoteNotify;
-  FX_BOOL m_bResizing;
-  PWL_SCROLL_INFO m_OldScrollInfo;
-  FX_BOOL m_bEnableNotify;
-  CFX_WideString m_sReplyString;
-};
-
-#endif  // FPDFSDK_INCLUDE_PDFWINDOW_PWL_NOTE_H_
diff --git a/fpdfsdk/include/pdfwindow/PWL_ScrollBar.h b/fpdfsdk/include/pdfwindow/PWL_ScrollBar.h
deleted file mode 100644
index 891079e..0000000
--- a/fpdfsdk/include/pdfwindow/PWL_ScrollBar.h
+++ /dev/null
@@ -1,157 +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_PDFWINDOW_PWL_SCROLLBAR_H_
-#define FPDFSDK_INCLUDE_PDFWINDOW_PWL_SCROLLBAR_H_
-
-#include "PWL_Wnd.h"
-
-class CPWL_SBButton;
-class CPWL_ScrollBar;
-
-struct PWL_SCROLL_INFO {
- public:
-  PWL_SCROLL_INFO()
-      : fContentMin(0.0f),
-        fContentMax(0.0f),
-        fPlateWidth(0.0f),
-        fBigStep(0.0f),
-        fSmallStep(0.0f) {}
-  FX_FLOAT fContentMin;
-  FX_FLOAT fContentMax;
-  FX_FLOAT fPlateWidth;
-  FX_FLOAT fBigStep;
-  FX_FLOAT fSmallStep;
-};
-
-enum PWL_SCROLLBAR_TYPE { SBT_HSCROLL, SBT_VSCROLL };
-
-enum PWL_SBBUTTON_TYPE { PSBT_MIN, PSBT_MAX, PSBT_POS };
-
-class CPWL_SBButton : public CPWL_Wnd {
- public:
-  CPWL_SBButton(PWL_SCROLLBAR_TYPE eScrollBarType,
-                PWL_SBBUTTON_TYPE eButtonType);
-  ~CPWL_SBButton() override;
-
-  // CPWL_Wnd
-  CFX_ByteString GetClassName() const override;
-  void OnCreate(PWL_CREATEPARAM& cp) override;
-  void GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) override;
-  void DrawThisAppearance(CFX_RenderDevice* pDevice,
-                          CFX_Matrix* pUser2Device) override;
-  FX_BOOL OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) override;
-  FX_BOOL OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag) override;
-  FX_BOOL OnMouseMove(const CPDF_Point& point, FX_DWORD nFlag) override;
-
- protected:
-  PWL_SCROLLBAR_TYPE m_eScrollBarType;
-  PWL_SBBUTTON_TYPE m_eSBButtonType;
-
-  FX_BOOL m_bMouseDown;
-};
-
-struct PWL_FLOATRANGE {
- public:
-  PWL_FLOATRANGE();
-  PWL_FLOATRANGE(FX_FLOAT min, FX_FLOAT max);
-  void Default();
-  void Set(FX_FLOAT min, FX_FLOAT max);
-  FX_BOOL In(FX_FLOAT x) const;
-  FX_FLOAT GetWidth() const;
-
-  FX_FLOAT fMin, fMax;
-};
-
-struct PWL_SCROLL_PRIVATEDATA {
- public:
-  PWL_SCROLL_PRIVATEDATA();
-
-  void Default();
-  void SetScrollRange(FX_FLOAT min, FX_FLOAT max);
-  void SetClientWidth(FX_FLOAT width);
-  void SetSmallStep(FX_FLOAT step);
-  void SetBigStep(FX_FLOAT step);
-  FX_BOOL SetPos(FX_FLOAT pos);
-
-  void AddSmall();
-  void SubSmall();
-  void AddBig();
-  void SubBig();
-
-  PWL_FLOATRANGE ScrollRange;
-  FX_FLOAT fClientWidth;
-  FX_FLOAT fScrollPos;
-  FX_FLOAT fBigStep;
-  FX_FLOAT fSmallStep;
-};
-
-class CPWL_ScrollBar : public CPWL_Wnd {
- public:
-  CPWL_ScrollBar(PWL_SCROLLBAR_TYPE sbType = SBT_HSCROLL);
-  ~CPWL_ScrollBar() override;
-
-  // CPWL_Wnd
-  CFX_ByteString GetClassName() const override;
-  void OnCreate(PWL_CREATEPARAM& cp) override;
-  void RePosChildWnd() override;
-  void GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) override;
-  void DrawThisAppearance(CFX_RenderDevice* pDevice,
-                          CFX_Matrix* pUser2Device) override;
-  FX_BOOL OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) override;
-  FX_BOOL OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag) override;
-  void OnNotify(CPWL_Wnd* pWnd,
-                FX_DWORD msg,
-                intptr_t wParam = 0,
-                intptr_t lParam = 0) override;
-  void CreateChildWnd(const PWL_CREATEPARAM& cp) override;
-  void TimerProc() override;
-
-  FX_FLOAT GetScrollBarWidth() const;
-  PWL_SCROLLBAR_TYPE GetScrollBarType() const { return m_sbType; }
-
-  void SetNotifyForever(FX_BOOL bForever) { m_bNotifyForever = bForever; }
-
- protected:
-  void SetScrollRange(FX_FLOAT fMin, FX_FLOAT fMax, FX_FLOAT fClientWidth);
-  void SetScrollPos(FX_FLOAT fPos);
-  void MovePosButton(FX_BOOL bRefresh);
-  void SetScrollStep(FX_FLOAT fBigStep, FX_FLOAT fSmallStep);
-  void NotifyScrollWindow();
-  CPDF_Rect GetScrollArea() const;
-
- private:
-  void CreateButtons(const PWL_CREATEPARAM& cp);
-
-  void OnMinButtonLBDown(const CPDF_Point& point);
-  void OnMinButtonLBUp(const CPDF_Point& point);
-  void OnMinButtonMouseMove(const CPDF_Point& point);
-
-  void OnMaxButtonLBDown(const CPDF_Point& point);
-  void OnMaxButtonLBUp(const CPDF_Point& point);
-  void OnMaxButtonMouseMove(const CPDF_Point& point);
-
-  void OnPosButtonLBDown(const CPDF_Point& point);
-  void OnPosButtonLBUp(const CPDF_Point& point);
-  void OnPosButtonMouseMove(const CPDF_Point& point);
-
-  FX_FLOAT TrueToFace(FX_FLOAT);
-  FX_FLOAT FaceToTrue(FX_FLOAT);
-
-  PWL_SCROLLBAR_TYPE m_sbType;
-  PWL_SCROLL_INFO m_OriginInfo;
-  CPWL_SBButton* m_pMinButton;
-  CPWL_SBButton* m_pMaxButton;
-  CPWL_SBButton* m_pPosButton;
-  PWL_SCROLL_PRIVATEDATA m_sData;
-  FX_BOOL m_bMouseDown;
-  FX_BOOL m_bMinOrMax;
-  FX_BOOL m_bNotifyForever;
-  FX_FLOAT m_nOldPos;
-  FX_FLOAT m_fOldPosButton;
-};
-
-#endif  // FPDFSDK_INCLUDE_PDFWINDOW_PWL_SCROLLBAR_H_
diff --git a/fpdfsdk/include/pdfwindow/PWL_Signature.h b/fpdfsdk/include/pdfwindow/PWL_Signature.h
deleted file mode 100644
index 0dbd906..0000000
--- a/fpdfsdk/include/pdfwindow/PWL_Signature.h
+++ /dev/null
@@ -1,67 +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_PDFWINDOW_PWL_SIGNATURE_H_
-#define FPDFSDK_INCLUDE_PDFWINDOW_PWL_SIGNATURE_H_
-
-#include "PWL_Icon.h"
-#include "PWL_Wnd.h"
-
-class CFX_DIBSource;
-class CPWL_Label;
-
-class CPWL_Signature_Image : public CPWL_Image {
- public:
-  CPWL_Signature_Image();
-  ~CPWL_Signature_Image() override;
-
-  void SetImage(CFX_DIBSource* pImage);
-  CFX_DIBSource* GetImage();
-
- protected:
-  // CPWL_Image
-  void DrawThisAppearance(CFX_RenderDevice* pDevice,
-                          CFX_Matrix* pUser2Device) override;
-  void GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) override;
-  void GetScale(FX_FLOAT& fHScale, FX_FLOAT& fVScale) override;
-
- private:
-  CFX_DIBSource* m_pImage;
-};
-
-class CPWL_Signature : public CPWL_Wnd {
- public:
-  CPWL_Signature();
-  ~CPWL_Signature() override;
-
-  void SetText(const FX_WCHAR* sText);
-  void SetDescription(const FX_WCHAR* string);
-  void SetImage(CFX_DIBSource* pImage);
-  void SetImageStream(CPDF_Stream* pStream, const FX_CHAR* sImageAlias);
-
-  void SetTextFlag(FX_BOOL bTextExist);
-  void SetImageFlag(FX_BOOL bImageExist);
-  void SetFoxitFlag(FX_BOOL bFlagExist);
-
- protected:
-  // CPWL_Wnd
-  void RePosChildWnd() override;
-  void CreateChildWnd(const PWL_CREATEPARAM& cp) override;
-  void DrawThisAppearance(CFX_RenderDevice* pDevice,
-                          CFX_Matrix* pUser2Device) override;
-  void GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) override;
-
- private:
-  CPWL_Label* m_pText;
-  CPWL_Label* m_pDescription;
-  CPWL_Signature_Image* m_pImage;
-
-  FX_BOOL m_bTextExist;
-  FX_BOOL m_bImageExist;
-  FX_BOOL m_bFlagExist;
-};
-
-#endif  // FPDFSDK_INCLUDE_PDFWINDOW_PWL_SIGNATURE_H_
diff --git a/fpdfsdk/include/pdfwindow/PWL_SpecialButton.h b/fpdfsdk/include/pdfwindow/PWL_SpecialButton.h
deleted file mode 100644
index a62d18d..0000000
--- a/fpdfsdk/include/pdfwindow/PWL_SpecialButton.h
+++ /dev/null
@@ -1,56 +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_PDFWINDOW_PWL_SPECIALBUTTON_H_
-#define FPDFSDK_INCLUDE_PDFWINDOW_PWL_SPECIALBUTTON_H_
-
-#include "PWL_Button.h"
-
-class CPWL_PushButton : public CPWL_Button {
- public:
-  CPWL_PushButton();
-  ~CPWL_PushButton() override;
-
-  // CPWL_Button
-  CFX_ByteString GetClassName() const override;
-  CPDF_Rect GetFocusRect() const override;
-};
-
-class CPWL_CheckBox : public CPWL_Button {
- public:
-  CPWL_CheckBox();
-  ~CPWL_CheckBox() override;
-
-  // CPWL_Button
-  CFX_ByteString GetClassName() const override;
-  FX_BOOL OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag) override;
-  FX_BOOL OnChar(FX_WORD nChar, FX_DWORD nFlag) override;
-
-  void SetCheck(FX_BOOL bCheck);
-  FX_BOOL IsChecked() const;
-
- private:
-  FX_BOOL m_bChecked;
-};
-
-class CPWL_RadioButton : public CPWL_Button {
- public:
-  CPWL_RadioButton();
-  ~CPWL_RadioButton() override;
-
-  // CPWL_Button
-  CFX_ByteString GetClassName() const override;
-  FX_BOOL OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag) override;
-  FX_BOOL OnChar(FX_WORD nChar, FX_DWORD nFlag) override;
-
-  void SetCheck(FX_BOOL bCheck);
-  FX_BOOL IsChecked() const;
-
- private:
-  FX_BOOL m_bChecked;
-};
-
-#endif  // FPDFSDK_INCLUDE_PDFWINDOW_PWL_SPECIALBUTTON_H_
diff --git a/fpdfsdk/include/pdfwindow/PWL_Wnd.h b/fpdfsdk/include/pdfwindow/PWL_Wnd.h
deleted file mode 100644
index 058057b..0000000
--- a/fpdfsdk/include/pdfwindow/PWL_Wnd.h
+++ /dev/null
@@ -1,469 +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_PDFWINDOW_PWL_WND_H_
-#define FPDFSDK_INCLUDE_PDFWINDOW_PWL_WND_H_
-
-#include "core/include/fpdfdoc/fpdf_doc.h"
-#include "core/include/fxcrt/fx_basic.h"
-#include "fpdfsdk/include/fx_systemhandler.h"
-
-class CPWL_MsgControl;
-class CPWL_ScrollBar;
-class CPWL_Timer;
-class CPWL_TimerHandler;
-class CPWL_Wnd;
-class IFX_Edit_FontMap;
-class IFX_SystemHandler;
-class IPWL_Provider;
-class IPWL_SpellCheck;
-
-// window styles
-#define PWS_CHILD 0x80000000L
-#define PWS_BORDER 0x40000000L
-#define PWS_BACKGROUND 0x20000000L
-#define PWS_HSCROLL 0x10000000L
-#define PWS_VSCROLL 0x08000000L
-#define PWS_VISIBLE 0x04000000L
-#define PWS_DISABLE 0x02000000L
-#define PWS_READONLY 0x01000000L
-#define PWS_AUTOFONTSIZE 0x00800000L
-#define PWS_AUTOTRANSPARENT 0x00400000L
-#define PWS_NOREFRESHCLIP 0x00200000L
-
-// edit and label styles
-#define PES_MULTILINE 0x0001L
-#define PES_PASSWORD 0x0002L
-#define PES_LEFT 0x0004L
-#define PES_RIGHT 0x0008L
-#define PES_MIDDLE 0x0010L
-#define PES_TOP 0x0020L
-#define PES_BOTTOM 0x0040L
-#define PES_CENTER 0x0080L
-#define PES_CHARARRAY 0x0100L
-#define PES_AUTOSCROLL 0x0200L
-#define PES_AUTORETURN 0x0400L
-#define PES_UNDO 0x0800L
-#define PES_RICH 0x1000L
-#define PES_SPELLCHECK 0x2000L
-#define PES_TEXTOVERFLOW 0x4000L
-#define PES_NOREAD 0x8000L
-
-// listbox styles
-#define PLBS_MULTIPLESEL 0x0001L
-#define PLBS_HOVERSEL 0x0008L
-
-// combobox styles
-#define PCBS_ALLOWCUSTOMTEXT 0x0001L
-
-// richedit styles
-#define PRES_MULTILINE 0x0001L
-#define PRES_AUTORETURN 0x0002L
-#define PRES_AUTOSCROLL 0x0004L
-#define PRES_SPELLCHECK 0x0008L
-#define PRES_UNDO 0x0100L
-#define PRES_MULTIPAGES 0x0200L
-#define PRES_TEXTOVERFLOW 0x0400L
-
-// border style
-#define PBS_SOLID 0
-#define PBS_DASH 1
-#define PBS_BEVELED 2
-#define PBS_INSET 3
-#define PBS_UNDERLINED 4
-#define PBS_SHADOW 5
-
-// notification messages
-#define PNM_ADDCHILD 0x00000000L
-#define PNM_REMOVECHILD 0x00000001L
-#define PNM_SETSCROLLINFO 0x00000002L
-#define PNM_SETSCROLLPOS 0x00000003L
-#define PNM_SCROLLWINDOW 0x00000004L
-#define PNM_LBUTTONDOWN 0x00000005L
-#define PNM_LBUTTONUP 0x00000006L
-#define PNM_MOUSEMOVE 0x00000007L
-#define PNM_NOTERESET 0x00000008L
-#define PNM_SETCARETINFO 0x00000009L
-#define PNM_SELCHANGED 0x0000000AL
-#define PNM_NOTEEDITCHANGED 0x0000000BL
-
-#define PWL_CLASSNAME_EDIT "CPWL_Edit"
-
-struct CPWL_Dash {
-  CPWL_Dash(int32_t dash, int32_t gap, int32_t phase)
-      : nDash(dash), nGap(gap), nPhase(phase) {}
-
-  int32_t nDash;
-  int32_t nGap;
-  int32_t nPhase;
-};
-
-struct CPWL_Color {
-  CPWL_Color(int32_t type = COLORTYPE_TRANSPARENT,
-             FX_FLOAT color1 = 0.0f,
-             FX_FLOAT color2 = 0.0f,
-             FX_FLOAT color3 = 0.0f,
-             FX_FLOAT color4 = 0.0f)
-      : nColorType(type),
-        fColor1(color1),
-        fColor2(color2),
-        fColor3(color3),
-        fColor4(color4) {}
-
-  CPWL_Color(int32_t r, int32_t g, int32_t b)
-      : nColorType(COLORTYPE_RGB),
-        fColor1(r / 255.0f),
-        fColor2(g / 255.0f),
-        fColor3(b / 255.0f),
-        fColor4(0) {}
-
-  void ConvertColorType(int32_t other_nColorType);
-
-  /*
-  COLORTYPE_TRANSPARENT
-  COLORTYPE_RGB
-  COLORTYPE_CMYK
-  COLORTYPE_GRAY
-  */
-  int32_t nColorType;
-  FX_FLOAT fColor1, fColor2, fColor3, fColor4;
-};
-
-inline FX_BOOL operator==(const CPWL_Color& c1, const CPWL_Color& c2) {
-  return c1.nColorType == c2.nColorType && c1.fColor1 - c2.fColor1 < 0.0001 &&
-         c1.fColor1 - c2.fColor1 > -0.0001 &&
-         c1.fColor2 - c2.fColor2 < 0.0001 &&
-         c1.fColor2 - c2.fColor2 > -0.0001 &&
-         c1.fColor3 - c2.fColor3 < 0.0001 &&
-         c1.fColor3 - c2.fColor3 > -0.0001 &&
-         c1.fColor4 - c2.fColor4 < 0.0001 && c1.fColor4 - c2.fColor4 > -0.0001;
-}
-
-inline FX_BOOL operator!=(const CPWL_Color& c1, const CPWL_Color& c2) {
-  return !operator==(c1, c2);
-}
-
-#define PWL_SCROLLBAR_WIDTH 12.0f
-#define PWL_SCROLLBAR_BUTTON_WIDTH 9.0f
-#define PWL_SCROLLBAR_POSBUTTON_MINWIDTH 2.0f
-#define PWL_SCROLLBAR_TRANSPARANCY 150
-#define PWL_SCROLLBAR_BKCOLOR \
-  CPWL_Color(COLORTYPE_RGB, 220.0f / 255.0f, 220.0f / 255.0f, 220.0f / 255.0f)
-#define PWL_DEFAULT_SELTEXTCOLOR CPWL_Color(COLORTYPE_RGB, 1, 1, 1)
-#define PWL_DEFAULT_SELBACKCOLOR \
-  CPWL_Color(COLORTYPE_RGB, 0, 51.0f / 255.0f, 113.0f / 255.0f)
-#define PWL_DEFAULT_BACKCOLOR PWL_DEFAULT_SELTEXTCOLOR
-#define PWL_DEFAULT_TEXTCOLOR CPWL_Color(COLORTYPE_RGB, 0, 0, 0)
-#define PWL_DEFAULT_FONTSIZE 9.0f
-#define PWL_DEFAULT_BLACKCOLOR CPWL_Color(COLORTYPE_GRAY, 0)
-#define PWL_DEFAULT_WHITECOLOR CPWL_Color(COLORTYPE_GRAY, 1)
-#define PWL_DEFAULT_HEAVYGRAYCOLOR CPWL_Color(COLORTYPE_GRAY, 0.50)
-#define PWL_DEFAULT_LIGHTGRAYCOLOR CPWL_Color(COLORTYPE_GRAY, 0.75)
-#define PWL_TRIANGLE_HALFLEN 2.0f
-#define PWL_CBBUTTON_TRIANGLE_HALFLEN 3.0f
-#define PWL_INVALIDATE_INFLATE 2
-
-class IPWL_SpellCheck {
- public:
-  virtual ~IPWL_SpellCheck() {}
-  virtual FX_BOOL CheckWord(const FX_CHAR* sWord) = 0;
-  virtual void SuggestWords(const FX_CHAR* sWord,
-                            CFX_ByteStringArray& sSuggest) = 0;
-};
-
-class IPWL_Provider {
- public:
-  virtual ~IPWL_Provider() {}
-
-  // get a matrix which map user space to CWnd client space
-  virtual CFX_Matrix GetWindowMatrix(void* pAttachedData) = 0;
-
-  /*
-  0 L"&Undo\tCtrl+Z"
-  1 L"&Redo\tCtrl+Shift+Z"
-  2 L"Cu&t\tCtrl+X"
-  3 L"&Copy\tCtrl+C"
-  4 L"&Paste\tCtrl+V"
-  5 L"&Delete"
-  6  L"&Select All\tCtrl+A"
-  */
-  virtual CFX_WideString LoadPopupMenuString(int32_t nIndex) = 0;
-};
-
-class IPWL_FocusHandler {
- public:
-  virtual ~IPWL_FocusHandler() {}
-  virtual void OnSetFocus(CPWL_Wnd* pWnd) = 0;
-  virtual void OnKillFocus(CPWL_Wnd* pWnd) = 0;
-};
-
-struct PWL_CREATEPARAM {
- public:
-  PWL_CREATEPARAM()
-      : rcRectWnd(0, 0, 0, 0),
-        pSystemHandler(NULL),
-        pFontMap(NULL),
-        pProvider(NULL),
-        pFocusHandler(NULL),
-        dwFlags(0),
-        sBackgroundColor(),
-        hAttachedWnd(NULL),
-        pSpellCheck(NULL),
-        nBorderStyle(PBS_SOLID),
-        dwBorderWidth(1),
-        sBorderColor(),
-        sTextColor(),
-        sTextStrokeColor(),
-        nTransparency(255),
-        fFontSize(PWL_DEFAULT_FONTSIZE),
-        sDash(3, 0, 0),
-        pAttachedData(NULL),
-        pParentWnd(NULL),
-        pMsgControl(NULL),
-        eCursorType(FXCT_ARROW),
-        mtChild(1, 0, 0, 1, 0, 0) {}
-
-  CPDF_Rect rcRectWnd;                // required
-  IFX_SystemHandler* pSystemHandler;  // required
-  IFX_Edit_FontMap* pFontMap;         // required for text window
-  IPWL_Provider* pProvider;           // required for self coordinate
-  IPWL_FocusHandler* pFocusHandler;   // optional
-  FX_DWORD dwFlags;                   // optional
-  CPWL_Color sBackgroundColor;        // optional
-  FX_HWND hAttachedWnd;               // required for no-reader framework
-  IPWL_SpellCheck* pSpellCheck;       // required for spellchecking
-  int32_t nBorderStyle;               // optional
-  int32_t dwBorderWidth;              // optional
-  CPWL_Color sBorderColor;            // optional
-  CPWL_Color sTextColor;              // optional
-  CPWL_Color sTextStrokeColor;        // optional
-  int32_t nTransparency;              // optional
-  FX_FLOAT fFontSize;                 // optional
-  CPWL_Dash sDash;                    // optional
-  void* pAttachedData;                // optional
-  CPWL_Wnd* pParentWnd;               // ignore
-  CPWL_MsgControl* pMsgControl;       // ignore
-  int32_t eCursorType;                // ignore
-  CFX_Matrix mtChild;                 // ignore
-};
-
-class CPWL_Timer {
- public:
-  CPWL_Timer(CPWL_TimerHandler* pAttached, IFX_SystemHandler* pSystemHandler);
-  virtual ~CPWL_Timer();
-
-  int32_t SetPWLTimer(int32_t nElapse);
-  void KillPWLTimer();
-  static void TimerProc(int32_t idEvent);
-
- private:
-  int32_t m_nTimerID;
-  CPWL_TimerHandler* m_pAttached;
-  IFX_SystemHandler* m_pSystemHandler;
-};
-
-class CPWL_TimerHandler {
- public:
-  CPWL_TimerHandler();
-  virtual ~CPWL_TimerHandler();
-
-  void BeginTimer(int32_t nElapse);
-  void EndTimer();
-  virtual void TimerProc();
-  virtual IFX_SystemHandler* GetSystemHandler() const = 0;
-
- private:
-  CPWL_Timer* m_pTimer;
-};
-
-class CPWL_Wnd : public CPWL_TimerHandler {
-  friend class CPWL_MsgControl;
-
- public:
-  CPWL_Wnd();
-  ~CPWL_Wnd() override;
-
-  void Create(const PWL_CREATEPARAM& cp);
-  virtual CFX_ByteString GetClassName() const;
-  void InvalidateFocusHandler(IPWL_FocusHandler* handler);
-  void InvalidateProvider(IPWL_Provider* provider);
-  void Destroy();
-  void Move(const CPDF_Rect& rcNew, FX_BOOL bReset, FX_BOOL bRefresh);
-  virtual void InvalidateRect(CPDF_Rect* pRect = NULL);
-
-  void DrawAppearance(CFX_RenderDevice* pDevice, CFX_Matrix* pUser2Device);
-
-  virtual FX_BOOL OnKeyDown(FX_WORD nChar, FX_DWORD nFlag);
-  virtual FX_BOOL OnKeyUp(FX_WORD nChar, FX_DWORD nFlag);
-  virtual FX_BOOL OnChar(FX_WORD nChar, FX_DWORD nFlag);
-  virtual FX_BOOL OnLButtonDblClk(const CPDF_Point& point, FX_DWORD nFlag);
-  virtual FX_BOOL OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag);
-  virtual FX_BOOL OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag);
-  virtual FX_BOOL OnMButtonDblClk(const CPDF_Point& point, FX_DWORD nFlag);
-  virtual FX_BOOL OnMButtonDown(const CPDF_Point& point, FX_DWORD nFlag);
-  virtual FX_BOOL OnMButtonUp(const CPDF_Point& point, FX_DWORD nFlag);
-  virtual FX_BOOL OnRButtonDown(const CPDF_Point& point, FX_DWORD nFlag);
-  virtual FX_BOOL OnRButtonUp(const CPDF_Point& point, FX_DWORD nFlag);
-  virtual FX_BOOL OnMouseMove(const CPDF_Point& point, FX_DWORD nFlag);
-  virtual FX_BOOL OnMouseWheel(short zDelta,
-                               const CPDF_Point& point,
-                               FX_DWORD nFlag);
-
-  virtual void SetFocus();
-  virtual void KillFocus();
-  void SetCapture();
-  void ReleaseCapture();
-
-  virtual void OnNotify(CPWL_Wnd* pWnd,
-                        FX_DWORD msg,
-                        intptr_t wParam = 0,
-                        intptr_t lParam = 0);
-  virtual void SetTextColor(const CPWL_Color& color);
-  virtual void SetTextStrokeColor(const CPWL_Color& color);
-  virtual void SetVisible(FX_BOOL bVisible);
-
-  virtual CPDF_Rect GetFocusRect() const;
-  virtual CPWL_Color GetBackgroundColor() const;
-  virtual CPWL_Color GetBorderColor() const;
-  virtual CPWL_Color GetTextColor() const;
-  virtual CPWL_Color GetTextStrokeColor() const;
-  virtual FX_FLOAT GetFontSize() const;
-  virtual int32_t GetInnerBorderWidth() const;
-  virtual CPWL_Color GetBorderLeftTopColor(int32_t nBorderStyle) const;
-  virtual CPWL_Color GetBorderRightBottomColor(int32_t nBorderStyle) const;
-
-  virtual void SetFontSize(FX_FLOAT fFontSize);
-
-  void SetBackgroundColor(const CPWL_Color& color);
-  void SetClipRect(const CPDF_Rect& rect);
-  void SetBorderStyle(int32_t eBorderStyle);
-
-  virtual CPDF_Rect GetWindowRect() const;
-  virtual CPDF_Rect GetClientRect() const;
-  CPDF_Point GetCenterPoint() const;
-  int32_t GetBorderWidth() const;
-  FX_BOOL IsVisible() const { return m_bVisible; }
-  FX_BOOL HasFlag(FX_DWORD dwFlags) const;
-  void AddFlag(FX_DWORD dwFlags);
-  void RemoveFlag(FX_DWORD dwFlags);
-  const CPDF_Rect& GetClipRect() const;
-  CPWL_Wnd* GetParentWindow() const;
-  int32_t GetBorderStyle() const;
-  const CPWL_Dash& GetBorderDash() const;
-  void* GetAttachedData() const;
-
-  FX_BOOL WndHitTest(const CPDF_Point& point) const;
-  FX_BOOL ClientHitTest(const CPDF_Point& point) const;
-  FX_BOOL IsCaptureMouse() const;
-
-  const CPWL_Wnd* GetFocused() const;
-  FX_BOOL IsFocused() const;
-  FX_BOOL IsReadOnly() const;
-  CPWL_ScrollBar* GetVScrollBar() const;
-
-  IFX_Edit_FontMap* GetFontMap() const;
-  IPWL_Provider* GetProvider() const;
-  IPWL_FocusHandler* GetFocusHandler() const;
-
-  int32_t GetTransparency();
-  void SetTransparency(int32_t nTransparency);
-
-  CFX_Matrix GetChildToRoot() const;
-  CFX_Matrix GetChildMatrix() const;
-  void SetChildMatrix(const CFX_Matrix& mt);
-  CFX_Matrix GetWindowMatrix() const;
-
-  virtual CPDF_Point ChildToParent(const CPDF_Point& point) const;
-  virtual CPDF_Rect ChildToParent(const CPDF_Rect& rect) const;
-  virtual CPDF_Point ParentToChild(const CPDF_Point& point) const;
-  virtual CPDF_Rect ParentToChild(const CPDF_Rect& rect) const;
-
-  // those methods only implemented by listctrl item
-  virtual FX_FLOAT GetItemHeight(FX_FLOAT fLimitWidth) { return 0; }
-  virtual FX_FLOAT GetItemLeftMargin() { return 0; }
-  virtual FX_FLOAT GetItemRightMargin() { return 0; }
-
-  void EnableWindow(FX_BOOL bEnable);
-  FX_BOOL IsEnabled();
-  virtual void SetCursor();
-
- protected:
-  // CPWL_TimerHandler
-  IFX_SystemHandler* GetSystemHandler() const override;
-
-  virtual void CreateChildWnd(const PWL_CREATEPARAM& cp);
-  virtual void RePosChildWnd();
-  void GetAppearanceStream(CFX_ByteTextBuf& sAppStream);
-  virtual void GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream);
-  virtual void GetChildAppearanceStream(CFX_ByteTextBuf& sAppStream);
-
-  virtual void DrawThisAppearance(CFX_RenderDevice* pDevice,
-                                  CFX_Matrix* pUser2Device);
-  virtual void DrawChildAppearance(CFX_RenderDevice* pDevice,
-                                   CFX_Matrix* pUser2Device);
-
-  virtual void OnCreate(PWL_CREATEPARAM& cp);
-  virtual void OnCreated();
-  virtual void OnDestroy();
-
-  virtual void OnSetFocus();
-  virtual void OnKillFocus();
-
-  virtual void OnEnabled();
-  virtual void OnDisabled();
-
-  void SetNotifyFlag(FX_BOOL bNotifying = TRUE) { m_bNotifying = bNotifying; }
-
-  FX_BOOL IsValid() const;
-  const PWL_CREATEPARAM& GetCreationParam() const;
-  FX_BOOL IsNotifying() const { return m_bNotifying; }
-
-  void InvalidateRectMove(const CPDF_Rect& rcOld, const CPDF_Rect& rcNew);
-
-  void PWLtoWnd(const CPDF_Point& point, int32_t& x, int32_t& y) const;
-  FX_RECT PWLtoWnd(const CPDF_Rect& rect) const;
-  FX_HWND GetAttachedHWnd() const;
-
-  FX_BOOL IsWndCaptureMouse(const CPWL_Wnd* pWnd) const;
-  FX_BOOL IsWndCaptureKeyboard(const CPWL_Wnd* pWnd) const;
-  const CPWL_Wnd* GetRootWnd() const;
-
-  FX_BOOL IsCTRLpressed(FX_DWORD nFlag) const;
-  FX_BOOL IsSHIFTpressed(FX_DWORD nFlag) const;
-  FX_BOOL IsALTpressed(FX_DWORD nFlag) const;
-  FX_BOOL IsINSERTpressed(FX_DWORD nFlag) const;
-
- private:
-  void AddChild(CPWL_Wnd* pWnd);
-  void RemoveChild(CPWL_Wnd* pWnd);
-
-  void CreateScrollBar(const PWL_CREATEPARAM& cp);
-  void CreateVScrollBar(const PWL_CREATEPARAM& cp);
-
-  void AdjustStyle();
-  void CreateMsgControl();
-  void DestroyMsgControl();
-
-  CPWL_MsgControl* GetMsgControl() const;
-
- protected:
-  CFX_ArrayTemplate<CPWL_Wnd*> m_aChildren;
-
- private:
-  PWL_CREATEPARAM m_sPrivateParam;
-
-  CPWL_ScrollBar* m_pVScrollBar;
-
-  CPDF_Rect m_rcWindow;
-  CPDF_Rect m_rcClip;
-
-  FX_BOOL m_bCreated;
-  FX_BOOL m_bVisible;
-  FX_BOOL m_bNotifying;
-  FX_BOOL m_bEnabled;
-};
-
-#endif  // FPDFSDK_INCLUDE_PDFWINDOW_PWL_WND_H_
diff --git a/fpdfsdk/ipdfsdk_annothandler.h b/fpdfsdk/ipdfsdk_annothandler.h
new file mode 100644
index 0000000..408dcce
--- /dev/null
+++ b/fpdfsdk/ipdfsdk_annothandler.h
@@ -0,0 +1,103 @@
+// 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_IPDFSDK_ANNOTHANDLER_H_
+#define FPDFSDK_IPDFSDK_ANNOTHANDLER_H_
+
+#include "core/fxcrt/fx_basic.h"
+#include "core/fxcrt/fx_coordinates.h"
+#include "fpdfsdk/cpdfsdk_annot.h"
+
+class CFX_Matrix;
+class CFX_RenderDevice;
+class CPDF_Annot;
+class CPDFSDK_PageView;
+
+#ifdef PDF_ENABLE_XFA
+class CXFA_FFWidget;
+#endif  // PDF_ENABLE_XFA
+
+class IPDFSDK_AnnotHandler {
+ public:
+  virtual ~IPDFSDK_AnnotHandler() {}
+
+  virtual bool CanAnswer(CPDFSDK_Annot* pAnnot) = 0;
+  virtual CPDFSDK_Annot* NewAnnot(CPDF_Annot* pAnnot,
+                                  CPDFSDK_PageView* pPage) = 0;
+
+#ifdef PDF_ENABLE_XFA
+  virtual CPDFSDK_Annot* NewAnnot(CXFA_FFWidget* hWidget,
+                                  CPDFSDK_PageView* pPage) = 0;
+#endif  // PDF_ENABLE_XFA
+
+  virtual void ReleaseAnnot(CPDFSDK_Annot* pAnnot) = 0;
+  virtual CFX_FloatRect GetViewBBox(CPDFSDK_PageView* pPageView,
+                                    CPDFSDK_Annot* pAnnot) = 0;
+  virtual bool HitTest(CPDFSDK_PageView* pPageView,
+                       CPDFSDK_Annot* pAnnot,
+                       const CFX_FloatPoint& point) = 0;
+  virtual void OnDraw(CPDFSDK_PageView* pPageView,
+                      CPDFSDK_Annot* pAnnot,
+                      CFX_RenderDevice* pDevice,
+                      CFX_Matrix* pUser2Device,
+                      bool bDrawAnnots) = 0;
+  virtual void OnLoad(CPDFSDK_Annot* pAnnot) = 0;
+
+  virtual void OnMouseEnter(CPDFSDK_PageView* pPageView,
+                            CPDFSDK_Annot::ObservedPtr* pAnnot,
+                            uint32_t nFlag) = 0;
+  virtual void OnMouseExit(CPDFSDK_PageView* pPageView,
+                           CPDFSDK_Annot::ObservedPtr* pAnnot,
+                           uint32_t nFlag) = 0;
+  virtual bool OnLButtonDown(CPDFSDK_PageView* pPageView,
+                             CPDFSDK_Annot::ObservedPtr* pAnnot,
+                             uint32_t nFlags,
+                             const CFX_FloatPoint& point) = 0;
+  virtual bool OnLButtonUp(CPDFSDK_PageView* pPageView,
+                           CPDFSDK_Annot::ObservedPtr* pAnnot,
+                           uint32_t nFlags,
+                           const CFX_FloatPoint& point) = 0;
+  virtual bool OnLButtonDblClk(CPDFSDK_PageView* pPageView,
+                               CPDFSDK_Annot::ObservedPtr* pAnnot,
+                               uint32_t nFlags,
+                               const CFX_FloatPoint& point) = 0;
+  virtual bool OnMouseMove(CPDFSDK_PageView* pPageView,
+                           CPDFSDK_Annot::ObservedPtr* pAnnot,
+                           uint32_t nFlags,
+                           const CFX_FloatPoint& point) = 0;
+  virtual bool OnMouseWheel(CPDFSDK_PageView* pPageView,
+                            CPDFSDK_Annot::ObservedPtr* pAnnot,
+                            uint32_t nFlags,
+                            short zDelta,
+                            const CFX_FloatPoint& point) = 0;
+  virtual bool OnRButtonDown(CPDFSDK_PageView* pPageView,
+                             CPDFSDK_Annot::ObservedPtr* pAnnot,
+                             uint32_t nFlags,
+                             const CFX_FloatPoint& point) = 0;
+  virtual bool OnRButtonUp(CPDFSDK_PageView* pPageView,
+                           CPDFSDK_Annot::ObservedPtr* pAnnot,
+                           uint32_t nFlags,
+                           const CFX_FloatPoint& point) = 0;
+  virtual bool OnRButtonDblClk(CPDFSDK_PageView* pPageView,
+                               CPDFSDK_Annot::ObservedPtr* pAnnot,
+                               uint32_t nFlags,
+                               const CFX_FloatPoint& point) = 0;
+  virtual bool OnChar(CPDFSDK_Annot* pAnnot,
+                      uint32_t nChar,
+                      uint32_t nFlags) = 0;
+  virtual bool OnKeyDown(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag) = 0;
+  virtual bool OnKeyUp(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag) = 0;
+  virtual bool OnSetFocus(CPDFSDK_Annot::ObservedPtr* pAnnot,
+                          uint32_t nFlag) = 0;
+  virtual bool OnKillFocus(CPDFSDK_Annot::ObservedPtr* pAnnot,
+                           uint32_t nFlag) = 0;
+#ifdef PDF_ENABLE_XFA
+  virtual bool OnXFAChangedFocus(CPDFSDK_Annot::ObservedPtr* pOldAnnot,
+                                 CPDFSDK_Annot::ObservedPtr* pNewAnnot) = 0;
+#endif  // PDF_ENABLE_XFA
+};
+
+#endif  // FPDFSDK_IPDFSDK_ANNOTHANDLER_H_
diff --git a/fpdfsdk/javascript/Annot.cpp b/fpdfsdk/javascript/Annot.cpp
new file mode 100644
index 0000000..1aef463
--- /dev/null
+++ b/fpdfsdk/javascript/Annot.cpp
@@ -0,0 +1,111 @@
+// 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/javascript/Annot.h"
+
+#include "fpdfsdk/javascript/JS_Define.h"
+#include "fpdfsdk/javascript/JS_Object.h"
+#include "fpdfsdk/javascript/JS_Value.h"
+#include "fpdfsdk/javascript/cjs_context.h"
+
+namespace {
+
+CPDFSDK_BAAnnot* ToBAAnnot(CPDFSDK_Annot* annot) {
+  return static_cast<CPDFSDK_BAAnnot*>(annot);
+}
+
+}  // namespace
+
+BEGIN_JS_STATIC_CONST(CJS_Annot)
+END_JS_STATIC_CONST()
+
+BEGIN_JS_STATIC_PROP(CJS_Annot)
+JS_STATIC_PROP_ENTRY(hidden)
+JS_STATIC_PROP_ENTRY(name)
+JS_STATIC_PROP_ENTRY(type)
+END_JS_STATIC_PROP()
+
+BEGIN_JS_STATIC_METHOD(CJS_Annot)
+END_JS_STATIC_METHOD()
+
+IMPLEMENT_JS_CLASS(CJS_Annot, Annot)
+
+Annot::Annot(CJS_Object* pJSObject) : CJS_EmbedObj(pJSObject) {}
+
+Annot::~Annot() {}
+
+bool Annot::hidden(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
+  if (vp.IsGetting()) {
+    if (!m_pAnnot) {
+      sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+      return false;
+    }
+    CPDF_Annot* pPDFAnnot = ToBAAnnot(m_pAnnot.Get())->GetPDFAnnot();
+    vp << CPDF_Annot::IsAnnotationHidden(pPDFAnnot->GetAnnotDict());
+    return true;
+  }
+
+  bool bHidden;
+  vp >> bHidden;  // May invalidate m_pAnnot.
+  if (!m_pAnnot) {
+    sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+    return false;
+  }
+
+  uint32_t flags = ToBAAnnot(m_pAnnot.Get())->GetFlags();
+  if (bHidden) {
+    flags |= ANNOTFLAG_HIDDEN;
+    flags |= ANNOTFLAG_INVISIBLE;
+    flags |= ANNOTFLAG_NOVIEW;
+    flags &= ~ANNOTFLAG_PRINT;
+  } else {
+    flags &= ~ANNOTFLAG_HIDDEN;
+    flags &= ~ANNOTFLAG_INVISIBLE;
+    flags &= ~ANNOTFLAG_NOVIEW;
+    flags |= ANNOTFLAG_PRINT;
+  }
+  ToBAAnnot(m_pAnnot.Get())->SetFlags(flags);
+  return true;
+}
+
+bool Annot::name(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
+  if (vp.IsGetting()) {
+    if (!m_pAnnot) {
+      sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+      return false;
+    }
+    vp << ToBAAnnot(m_pAnnot.Get())->GetAnnotName();
+    return true;
+  }
+
+  CFX_WideString annotName;
+  vp >> annotName;  // May invalidate m_pAnnot.
+  if (!m_pAnnot) {
+    sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+    return false;
+  }
+
+  ToBAAnnot(m_pAnnot.Get())->SetAnnotName(annotName);
+  return true;
+}
+
+bool Annot::type(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
+  if (vp.IsSetting()) {
+    sError = JSGetStringFromID(IDS_STRING_JSREADONLY);
+    return false;
+  }
+  if (!m_pAnnot) {
+    sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+    return false;
+  }
+  vp << CPDF_Annot::AnnotSubtypeToString(
+      ToBAAnnot(m_pAnnot.Get())->GetAnnotSubtype());
+  return true;
+}
+
+void Annot::SetSDKAnnot(CPDFSDK_BAAnnot* annot) {
+  m_pAnnot.Reset(annot);
+}
diff --git a/fpdfsdk/javascript/Annot.h b/fpdfsdk/javascript/Annot.h
new file mode 100644
index 0000000..39073e6
--- /dev/null
+++ b/fpdfsdk/javascript/Annot.h
@@ -0,0 +1,41 @@
+// 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_JAVASCRIPT_ANNOT_H_
+#define FPDFSDK_JAVASCRIPT_ANNOT_H_
+
+#include <memory>
+
+#include "fpdfsdk/cpdfsdk_baannot.h"
+#include "fpdfsdk/javascript/JS_Define.h"
+
+class Annot : public CJS_EmbedObj {
+ public:
+  explicit Annot(CJS_Object* pJSObject);
+  ~Annot() override;
+
+  bool hidden(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool name(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool type(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+
+  void SetSDKAnnot(CPDFSDK_BAAnnot* annot);
+
+ private:
+  CPDFSDK_Annot::ObservedPtr m_pAnnot;
+};
+
+class CJS_Annot : public CJS_Object {
+ public:
+  explicit CJS_Annot(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_Annot() override {}
+
+  DECLARE_JS_CLASS();
+  JS_STATIC_PROP(hidden, Annot);
+  JS_STATIC_PROP(name, Annot);
+  JS_STATIC_PROP(type, Annot);
+};
+
+#endif  // FPDFSDK_JAVASCRIPT_ANNOT_H_
diff --git a/fpdfsdk/javascript/Consts.cpp b/fpdfsdk/javascript/Consts.cpp
new file mode 100644
index 0000000..c224ad0
--- /dev/null
+++ b/fpdfsdk/javascript/Consts.cpp
@@ -0,0 +1,205 @@
+// 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
+
+#include "fpdfsdk/javascript/Consts.h"
+
+#include "fpdfsdk/javascript/JS_Define.h"
+#include "fpdfsdk/javascript/JS_Object.h"
+#include "fpdfsdk/javascript/JS_Value.h"
+
+BEGIN_JS_STATIC_CONST(CJS_Border)
+JS_STATIC_CONST_ENTRY_STRING(L"s", L"solid")
+JS_STATIC_CONST_ENTRY_STRING(L"b", L"beveled")
+JS_STATIC_CONST_ENTRY_STRING(L"d", L"dashed")
+JS_STATIC_CONST_ENTRY_STRING(L"i", L"inset")
+JS_STATIC_CONST_ENTRY_STRING(L"u", L"underline")
+END_JS_STATIC_CONST()
+IMPLEMENT_JS_CLASS_CONST(CJS_Border, border)
+
+BEGIN_JS_STATIC_CONST(CJS_Display)
+JS_STATIC_CONST_ENTRY_NUMBER(L"visible", 0)
+JS_STATIC_CONST_ENTRY_NUMBER(L"hidden", 1)
+JS_STATIC_CONST_ENTRY_NUMBER(L"noPrint", 2)
+JS_STATIC_CONST_ENTRY_NUMBER(L"noView", 3)
+END_JS_STATIC_CONST()
+IMPLEMENT_JS_CLASS_CONST(CJS_Display, display)
+
+BEGIN_JS_STATIC_CONST(CJS_Font)
+JS_STATIC_CONST_ENTRY_STRING(L"Times", L"Times-Roman")
+JS_STATIC_CONST_ENTRY_STRING(L"TimesB", L"Times-Bold")
+JS_STATIC_CONST_ENTRY_STRING(L"TimesI", L"Times-Italic")
+JS_STATIC_CONST_ENTRY_STRING(L"TimesBI", L"Times-BoldItalic")
+JS_STATIC_CONST_ENTRY_STRING(L"Helv", L"Helvetica")
+JS_STATIC_CONST_ENTRY_STRING(L"HelvB", L"Helvetica-Bold")
+JS_STATIC_CONST_ENTRY_STRING(L"HelvI", L"Helvetica-Oblique")
+JS_STATIC_CONST_ENTRY_STRING(L"HelvBI", L"Helvetica-BoldOblique")
+JS_STATIC_CONST_ENTRY_STRING(L"Cour", L"Courier")
+JS_STATIC_CONST_ENTRY_STRING(L"CourB", L"Courier-Bold")
+JS_STATIC_CONST_ENTRY_STRING(L"CourI", L"Courier-Oblique")
+JS_STATIC_CONST_ENTRY_STRING(L"CourBI", L"Courier-BoldOblique")
+JS_STATIC_CONST_ENTRY_STRING(L"Symbol", L"Symbol")
+JS_STATIC_CONST_ENTRY_STRING(L"ZapfD", L"ZapfDingbats")
+END_JS_STATIC_CONST()
+IMPLEMENT_JS_CLASS_CONST(CJS_Font, font)
+
+BEGIN_JS_STATIC_CONST(CJS_Highlight)
+JS_STATIC_CONST_ENTRY_STRING(L"n", L"none")
+JS_STATIC_CONST_ENTRY_STRING(L"i", L"invert")
+JS_STATIC_CONST_ENTRY_STRING(L"p", L"push")
+JS_STATIC_CONST_ENTRY_STRING(L"o", L"outline")
+END_JS_STATIC_CONST()
+IMPLEMENT_JS_CLASS_CONST(CJS_Highlight, highlight)
+
+BEGIN_JS_STATIC_CONST(CJS_Position)
+JS_STATIC_CONST_ENTRY_NUMBER(L"textOnly", 0)
+JS_STATIC_CONST_ENTRY_NUMBER(L"iconOnly", 1)
+JS_STATIC_CONST_ENTRY_NUMBER(L"iconTextV", 2)
+JS_STATIC_CONST_ENTRY_NUMBER(L"textIconV", 3)
+JS_STATIC_CONST_ENTRY_NUMBER(L"iconTextH", 4)
+JS_STATIC_CONST_ENTRY_NUMBER(L"textIconH", 5)
+JS_STATIC_CONST_ENTRY_NUMBER(L"overlay", 6)
+END_JS_STATIC_CONST()
+IMPLEMENT_JS_CLASS_CONST(CJS_Position, position)
+
+BEGIN_JS_STATIC_CONST(CJS_ScaleHow)
+JS_STATIC_CONST_ENTRY_NUMBER(L"proportional", 0)
+JS_STATIC_CONST_ENTRY_NUMBER(L"anamorphic", 1)
+END_JS_STATIC_CONST()
+IMPLEMENT_JS_CLASS_CONST(CJS_ScaleHow, scaleHow)
+
+BEGIN_JS_STATIC_CONST(CJS_ScaleWhen)
+JS_STATIC_CONST_ENTRY_NUMBER(L"always", 0)
+JS_STATIC_CONST_ENTRY_NUMBER(L"never", 1)
+JS_STATIC_CONST_ENTRY_NUMBER(L"tooBig", 2)
+JS_STATIC_CONST_ENTRY_NUMBER(L"tooSmall", 3)
+END_JS_STATIC_CONST()
+IMPLEMENT_JS_CLASS_CONST(CJS_ScaleWhen, scaleWhen)
+
+BEGIN_JS_STATIC_CONST(CJS_Style)
+JS_STATIC_CONST_ENTRY_STRING(L"ch", L"check")
+JS_STATIC_CONST_ENTRY_STRING(L"cr", L"cross")
+JS_STATIC_CONST_ENTRY_STRING(L"di", L"diamond")
+JS_STATIC_CONST_ENTRY_STRING(L"ci", L"circle")
+JS_STATIC_CONST_ENTRY_STRING(L"st", L"star")
+JS_STATIC_CONST_ENTRY_STRING(L"sq", L"square")
+END_JS_STATIC_CONST()
+IMPLEMENT_JS_CLASS_CONST(CJS_Style, style)
+
+BEGIN_JS_STATIC_CONST(CJS_Zoomtype)
+JS_STATIC_CONST_ENTRY_STRING(L"none", L"NoVary")
+JS_STATIC_CONST_ENTRY_STRING(L"fitP", L"FitPage")
+JS_STATIC_CONST_ENTRY_STRING(L"fitW", L"FitWidth")
+JS_STATIC_CONST_ENTRY_STRING(L"fitH", L"FitHeight")
+JS_STATIC_CONST_ENTRY_STRING(L"fitV", L"FitVisibleWidth")
+JS_STATIC_CONST_ENTRY_STRING(L"pref", L"Preferred")
+JS_STATIC_CONST_ENTRY_STRING(L"refW", L"ReflowWidth")
+END_JS_STATIC_CONST()
+IMPLEMENT_JS_CLASS_CONST(CJS_Zoomtype, zoomtype)
+
+#define GLOBAL_STRING(rt, name, value)                                \
+  (rt)->DefineGlobalConst(                                            \
+      (name), [](const v8::FunctionCallbackInfo<v8::Value>& info) {   \
+        info.GetReturnValue().Set(                                    \
+            CFXJS_Engine::CurrentEngineFromIsolate(info.GetIsolate()) \
+                ->NewString(value));                                  \
+      })
+
+void CJS_GlobalConsts::DefineJSObjects(CJS_Runtime* pRuntime) {
+  GLOBAL_STRING(pRuntime, L"IDS_GREATER_THAN",
+                L"Invalid value: must be greater than or equal to % s.");
+
+  GLOBAL_STRING(pRuntime, L"IDS_GT_AND_LT",
+                L"Invalid value: must be greater than or equal to % s "
+                L"and less than or equal to % s.");
+
+  GLOBAL_STRING(pRuntime, L"IDS_LESS_THAN",
+                L"Invalid value: must be less than or equal to % s.");
+
+  GLOBAL_STRING(pRuntime, L"IDS_INVALID_MONTH", L"**Invalid**");
+  GLOBAL_STRING(
+      pRuntime, L"IDS_INVALID_DATE",
+      L"Invalid date / time: please ensure that the date / time exists.Field");
+
+  GLOBAL_STRING(pRuntime, L"IDS_INVALID_VALUE",
+                L"The value entered does not match the format of the field");
+
+  GLOBAL_STRING(pRuntime, L"IDS_AM", L"am");
+  GLOBAL_STRING(pRuntime, L"IDS_PM", L"pm");
+  GLOBAL_STRING(pRuntime, L"IDS_MONTH_INFO",
+                L"January[1] February[2] March[3] April[4] May[5] "
+                L"June[6] July[7] August[8] September[9] October[10] "
+                L"November[11] December[12] Sept[9] Jan[1] Feb[2] Mar[3] "
+                L"Apr[4] Jun[6] Jul[7] Aug[8] Sep[9] Oct[10] Nov[11] "
+                L"Dec[12]");
+
+  GLOBAL_STRING(pRuntime, L"IDS_STARTUP_CONSOLE_MSG", L"** ^ _ ^ **");
+}
+
+#define GLOBAL_ARRAY(rt, name, ...)                                          \
+  {                                                                          \
+    const FX_WCHAR* values[] = {__VA_ARGS__};                                \
+    v8::Local<v8::Array> array = (rt)->NewArray();                           \
+    for (size_t i = 0; i < FX_ArraySize(values); ++i)                        \
+      array->Set(i, (rt)->NewString(values[i]));                             \
+    (rt)->SetConstArray((name), array);                                      \
+    (rt)->DefineGlobalConst(                                                 \
+        (name), [](const v8::FunctionCallbackInfo<v8::Value>& info) {        \
+          CJS_Runtime* pCurrentRuntime =                                     \
+              CJS_Runtime::CurrentRuntimeFromIsolate(info.GetIsolate());     \
+          if (pCurrentRuntime)                                               \
+            info.GetReturnValue().Set(pCurrentRuntime->GetConstArray(name)); \
+        });                                                                  \
+  }
+
+void CJS_GlobalArrays::DefineJSObjects(CJS_Runtime* pRuntime) {
+  GLOBAL_ARRAY(pRuntime, L"RE_NUMBER_ENTRY_DOT_SEP", L"[+-]?\\d*\\.?\\d*");
+  GLOBAL_ARRAY(pRuntime, L"RE_NUMBER_COMMIT_DOT_SEP",
+               L"[+-]?\\d+(\\.\\d+)?",  // -1.0 or -1
+               L"[+-]?\\.\\d+",         // -.1
+               L"[+-]?\\d+\\.");        // -1.
+
+  GLOBAL_ARRAY(pRuntime, L"RE_NUMBER_ENTRY_COMMA_SEP", L"[+-]?\\d*,?\\d*");
+  GLOBAL_ARRAY(pRuntime, L"RE_NUMBER_COMMIT_COMMA_SEP",
+               L"[+-]?\\d+([.,]\\d+)?",  // -1,0 or -1
+               L"[+-]?[.,]\\d+",         // -,1
+               L"[+-]?\\d+[.,]");        // -1,
+
+  GLOBAL_ARRAY(pRuntime, L"RE_ZIP_ENTRY", L"\\d{0,5}");
+  GLOBAL_ARRAY(pRuntime, L"RE_ZIP_COMMIT", L"\\d{5}");
+  GLOBAL_ARRAY(pRuntime, L"RE_ZIP4_ENTRY", L"\\d{0,5}(\\.|[- ])?\\d{0,4}");
+  GLOBAL_ARRAY(pRuntime, L"RE_ZIP4_COMMIT", L"\\d{5}(\\.|[- ])?\\d{4}");
+  GLOBAL_ARRAY(pRuntime, L"RE_PHONE_ENTRY",
+               // 555-1234 or 408 555-1234
+               L"\\d{0,3}(\\.|[- ])?\\d{0,3}(\\.|[- ])?\\d{0,4}",
+
+               // (408
+               L"\\(\\d{0,3}",
+
+               // (408) 555-1234
+               // (allow the addition of parens as an afterthought)
+               L"\\(\\d{0,3}\\)(\\.|[- ])?\\d{0,3}(\\.|[- ])?\\d{0,4}",
+
+               // (408 555-1234
+               L"\\(\\d{0,3}(\\.|[- ])?\\d{0,3}(\\.|[- ])?\\d{0,4}",
+
+               // 408) 555-1234
+               L"\\d{0,3}\\)(\\.|[- ])?\\d{0,3}(\\.|[- ])?\\d{0,4}",
+
+               // international
+               L"011(\\.|[- \\d])*");
+
+  GLOBAL_ARRAY(
+      pRuntime, L"RE_PHONE_COMMIT", L"\\d{3}(\\.|[- ])?\\d{4}",  // 555-1234
+      L"\\d{3}(\\.|[- ])?\\d{3}(\\.|[- ])?\\d{4}",               // 408 555-1234
+      L"\\(\\d{3}\\)(\\.|[- ])?\\d{3}(\\.|[- ])?\\d{4}",  // (408) 555-1234
+      L"011(\\.|[- \\d])*");                              // international
+
+  GLOBAL_ARRAY(pRuntime, L"RE_SSN_ENTRY",
+               L"\\d{0,3}(\\.|[- ])?\\d{0,2}(\\.|[- ])?\\d{0,4}");
+
+  GLOBAL_ARRAY(pRuntime, L"RE_SSN_COMMIT",
+               L"\\d{3}(\\.|[- ])?\\d{2}(\\.|[- ])?\\d{4}");
+}
diff --git a/fpdfsdk/src/javascript/Consts.h b/fpdfsdk/javascript/Consts.h
similarity index 68%
rename from fpdfsdk/src/javascript/Consts.h
rename to fpdfsdk/javascript/Consts.h
index 57c843e..e358cb9 100644
--- a/fpdfsdk/src/javascript/Consts.h
+++ b/fpdfsdk/javascript/Consts.h
@@ -4,12 +4,10 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#ifndef FPDFSDK_SRC_JAVASCRIPT_CONSTS_H_
-#define FPDFSDK_SRC_JAVASCRIPT_CONSTS_H_
+#ifndef FPDFSDK_JAVASCRIPT_CONSTS_H_
+#define FPDFSDK_JAVASCRIPT_CONSTS_H_
 
-#include "JS_Define.h"
-
-/* ------------------------------ border ------------------------------ */
+#include "fpdfsdk/javascript/JS_Define.h"
 
 class CJS_Border : public CJS_Object {
  public:
@@ -19,8 +17,6 @@
   DECLARE_JS_CLASS_CONST();
 };
 
-/* ------------------------------ display ------------------------------ */
-
 class CJS_Display : public CJS_Object {
  public:
   explicit CJS_Display(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
@@ -29,8 +25,6 @@
   DECLARE_JS_CLASS_CONST();
 };
 
-/* ------------------------------ font ------------------------------ */
-
 class CJS_Font : public CJS_Object {
  public:
   explicit CJS_Font(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
@@ -39,8 +33,6 @@
   DECLARE_JS_CLASS_CONST();
 };
 
-/* ------------------------------ highlight ------------------------------ */
-
 class CJS_Highlight : public CJS_Object {
  public:
   explicit CJS_Highlight(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
@@ -49,8 +41,6 @@
   DECLARE_JS_CLASS_CONST();
 };
 
-/* ------------------------------ position ------------------------------ */
-
 class CJS_Position : public CJS_Object {
  public:
   explicit CJS_Position(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
@@ -59,8 +49,6 @@
   DECLARE_JS_CLASS_CONST();
 };
 
-/* ------------------------------ scaleHow ------------------------------ */
-
 class CJS_ScaleHow : public CJS_Object {
  public:
   explicit CJS_ScaleHow(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
@@ -69,8 +57,6 @@
   DECLARE_JS_CLASS_CONST();
 };
 
-/* ------------------------------ scaleWhen ------------------------------ */
-
 class CJS_ScaleWhen : public CJS_Object {
  public:
   explicit CJS_ScaleWhen(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
@@ -79,8 +65,6 @@
   DECLARE_JS_CLASS_CONST();
 };
 
-/* ------------------------------ style ------------------------------ */
-
 class CJS_Style : public CJS_Object {
  public:
   explicit CJS_Style(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
@@ -89,8 +73,6 @@
   DECLARE_JS_CLASS_CONST();
 };
 
-/* ------------------------------ zoomtype ------------------------------ */
-
 class CJS_Zoomtype : public CJS_Object {
  public:
   explicit CJS_Zoomtype(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
@@ -99,18 +81,14 @@
   DECLARE_JS_CLASS_CONST();
 };
 
-/* ------------------------------ CJS_GlobalConsts -------------------------- */
-
 class CJS_GlobalConsts : public CJS_Object {
  public:
   static void DefineJSObjects(CJS_Runtime* pRuntime);
 };
 
-/* ------------------------------ CJS_GlobalArrays -------------------------- */
-
 class CJS_GlobalArrays : public CJS_Object {
  public:
   static void DefineJSObjects(CJS_Runtime* pRuntmie);
 };
 
-#endif  // FPDFSDK_SRC_JAVASCRIPT_CONSTS_H_
+#endif  // FPDFSDK_JAVASCRIPT_CONSTS_H_
diff --git a/fpdfsdk/javascript/DEPS b/fpdfsdk/javascript/DEPS
new file mode 100644
index 0000000..36a51aa
--- /dev/null
+++ b/fpdfsdk/javascript/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  '+fxjs'
+]
diff --git a/fpdfsdk/javascript/Document.cpp b/fpdfsdk/javascript/Document.cpp
new file mode 100644
index 0000000..4bf1afd
--- /dev/null
+++ b/fpdfsdk/javascript/Document.cpp
@@ -0,0 +1,1732 @@
+// 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
+
+#include "fpdfsdk/javascript/Document.h"
+
+#include <utility>
+#include <vector>
+
+#include "core/fpdfapi/font/cpdf_font.h"
+#include "core/fpdfapi/page/cpdf_page.h"
+#include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/cpdf_string.h"
+#include "core/fpdfapi/parser/fpdf_parser_decode.h"
+#include "core/fpdfdoc/cpdf_interform.h"
+#include "core/fpdfdoc/cpdf_nametree.h"
+#include "fpdfsdk/cpdfsdk_annotiteration.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/cpdfsdk_interform.h"
+#include "fpdfsdk/cpdfsdk_pageview.h"
+#include "fpdfsdk/cpdfsdk_widget.h"
+#include "fpdfsdk/javascript/Annot.h"
+#include "fpdfsdk/javascript/Field.h"
+#include "fpdfsdk/javascript/Icon.h"
+#include "fpdfsdk/javascript/JS_Define.h"
+#include "fpdfsdk/javascript/JS_EventHandler.h"
+#include "fpdfsdk/javascript/JS_Object.h"
+#include "fpdfsdk/javascript/JS_Value.h"
+#include "fpdfsdk/javascript/app.h"
+#include "fpdfsdk/javascript/cjs_context.h"
+#include "fpdfsdk/javascript/cjs_runtime.h"
+#include "fpdfsdk/javascript/resource.h"
+#include "third_party/base/numerics/safe_math.h"
+#include "third_party/base/ptr_util.h"
+
+BEGIN_JS_STATIC_CONST(CJS_PrintParamsObj)
+END_JS_STATIC_CONST()
+
+BEGIN_JS_STATIC_PROP(CJS_PrintParamsObj)
+END_JS_STATIC_PROP()
+
+BEGIN_JS_STATIC_METHOD(CJS_PrintParamsObj)
+END_JS_STATIC_METHOD()
+
+IMPLEMENT_JS_CLASS(CJS_PrintParamsObj, PrintParamsObj)
+
+PrintParamsObj::PrintParamsObj(CJS_Object* pJSObject)
+    : CJS_EmbedObj(pJSObject) {
+  bUI = true;
+  nStart = 0;
+  nEnd = 0;
+  bSilent = false;
+  bShrinkToFit = false;
+  bPrintAsImage = false;
+  bReverse = false;
+  bAnnotations = true;
+}
+
+#define MINWIDTH 5.0f
+#define MINHEIGHT 5.0f
+
+BEGIN_JS_STATIC_CONST(CJS_Document)
+END_JS_STATIC_CONST()
+
+BEGIN_JS_STATIC_PROP(CJS_Document)
+JS_STATIC_PROP_ENTRY(ADBE)
+JS_STATIC_PROP_ENTRY(author)
+JS_STATIC_PROP_ENTRY(baseURL)
+JS_STATIC_PROP_ENTRY(bookmarkRoot)
+JS_STATIC_PROP_ENTRY(calculate)
+JS_STATIC_PROP_ENTRY(Collab)
+JS_STATIC_PROP_ENTRY(creationDate)
+JS_STATIC_PROP_ENTRY(creator)
+JS_STATIC_PROP_ENTRY(delay)
+JS_STATIC_PROP_ENTRY(dirty)
+JS_STATIC_PROP_ENTRY(documentFileName)
+JS_STATIC_PROP_ENTRY(external)
+JS_STATIC_PROP_ENTRY(filesize)
+JS_STATIC_PROP_ENTRY(icons)
+JS_STATIC_PROP_ENTRY(info)
+JS_STATIC_PROP_ENTRY(keywords)
+JS_STATIC_PROP_ENTRY(layout)
+JS_STATIC_PROP_ENTRY(media)
+JS_STATIC_PROP_ENTRY(modDate)
+JS_STATIC_PROP_ENTRY(mouseX)
+JS_STATIC_PROP_ENTRY(mouseY)
+JS_STATIC_PROP_ENTRY(numFields)
+JS_STATIC_PROP_ENTRY(numPages)
+JS_STATIC_PROP_ENTRY(pageNum)
+JS_STATIC_PROP_ENTRY(pageWindowRect)
+JS_STATIC_PROP_ENTRY(path)
+JS_STATIC_PROP_ENTRY(producer)
+JS_STATIC_PROP_ENTRY(subject)
+JS_STATIC_PROP_ENTRY(title)
+JS_STATIC_PROP_ENTRY(URL)
+JS_STATIC_PROP_ENTRY(zoom)
+JS_STATIC_PROP_ENTRY(zoomType)
+END_JS_STATIC_PROP()
+
+BEGIN_JS_STATIC_METHOD(CJS_Document)
+JS_STATIC_METHOD_ENTRY(addAnnot)
+JS_STATIC_METHOD_ENTRY(addField)
+JS_STATIC_METHOD_ENTRY(addLink)
+JS_STATIC_METHOD_ENTRY(addIcon)
+JS_STATIC_METHOD_ENTRY(calculateNow)
+JS_STATIC_METHOD_ENTRY(closeDoc)
+JS_STATIC_METHOD_ENTRY(createDataObject)
+JS_STATIC_METHOD_ENTRY(deletePages)
+JS_STATIC_METHOD_ENTRY(exportAsText)
+JS_STATIC_METHOD_ENTRY(exportAsFDF)
+JS_STATIC_METHOD_ENTRY(exportAsXFDF)
+JS_STATIC_METHOD_ENTRY(extractPages)
+JS_STATIC_METHOD_ENTRY(getAnnot)
+JS_STATIC_METHOD_ENTRY(getAnnots)
+JS_STATIC_METHOD_ENTRY(getAnnot3D)
+JS_STATIC_METHOD_ENTRY(getAnnots3D)
+JS_STATIC_METHOD_ENTRY(getField)
+JS_STATIC_METHOD_ENTRY(getIcon)
+JS_STATIC_METHOD_ENTRY(getLinks)
+JS_STATIC_METHOD_ENTRY(getNthFieldName)
+JS_STATIC_METHOD_ENTRY(getOCGs)
+JS_STATIC_METHOD_ENTRY(getPageBox)
+JS_STATIC_METHOD_ENTRY(getPageNthWord)
+JS_STATIC_METHOD_ENTRY(getPageNthWordQuads)
+JS_STATIC_METHOD_ENTRY(getPageNumWords)
+JS_STATIC_METHOD_ENTRY(getPrintParams)
+JS_STATIC_METHOD_ENTRY(getURL)
+JS_STATIC_METHOD_ENTRY(gotoNamedDest)
+JS_STATIC_METHOD_ENTRY(importAnFDF)
+JS_STATIC_METHOD_ENTRY(importAnXFDF)
+JS_STATIC_METHOD_ENTRY(importTextData)
+JS_STATIC_METHOD_ENTRY(insertPages)
+JS_STATIC_METHOD_ENTRY(mailForm)
+JS_STATIC_METHOD_ENTRY(print)
+JS_STATIC_METHOD_ENTRY(removeField)
+JS_STATIC_METHOD_ENTRY(replacePages)
+JS_STATIC_METHOD_ENTRY(resetForm)
+JS_STATIC_METHOD_ENTRY(removeIcon)
+JS_STATIC_METHOD_ENTRY(saveAs)
+JS_STATIC_METHOD_ENTRY(submitForm)
+JS_STATIC_METHOD_ENTRY(syncAnnotScan)
+JS_STATIC_METHOD_ENTRY(mailDoc)
+END_JS_STATIC_METHOD()
+
+IMPLEMENT_JS_CLASS(CJS_Document, Document)
+
+void CJS_Document::InitInstance(IJS_Runtime* pIRuntime) {
+  CJS_Runtime* pRuntime = static_cast<CJS_Runtime*>(pIRuntime);
+  Document* pDoc = static_cast<Document*>(GetEmbedObject());
+  pDoc->SetFormFillEnv(pRuntime->GetFormFillEnv());
+}
+
+Document::Document(CJS_Object* pJSObject)
+    : CJS_EmbedObj(pJSObject),
+      m_pFormFillEnv(nullptr),
+      m_cwBaseURL(L""),
+      m_bDelay(false) {}
+
+Document::~Document() {
+}
+
+// the total number of fileds in document.
+bool Document::numFields(IJS_Context* cc,
+                         CJS_PropValue& vp,
+                         CFX_WideString& sError) {
+  if (vp.IsSetting()) {
+    sError = JSGetStringFromID(IDS_STRING_JSREADONLY);
+    return false;
+  }
+  if (!m_pFormFillEnv) {
+    sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+    return false;
+  }
+  CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm();
+  CPDF_InterForm* pPDFForm = pInterForm->GetInterForm();
+  vp << static_cast<int>(pPDFForm->CountFields(CFX_WideString()));
+  return true;
+}
+
+bool Document::dirty(IJS_Context* cc,
+                     CJS_PropValue& vp,
+                     CFX_WideString& sError) {
+  if (!m_pFormFillEnv) {
+    sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+    return false;
+  }
+  if (vp.IsGetting()) {
+    vp << !!m_pFormFillEnv->GetChangeMark();
+  } else {
+    bool bChanged = false;
+    vp >> bChanged;
+
+    if (bChanged)
+      m_pFormFillEnv->SetChangeMark();
+    else
+      m_pFormFillEnv->ClearChangeMark();
+  }
+  return true;
+}
+
+bool Document::ADBE(IJS_Context* cc,
+                    CJS_PropValue& vp,
+                    CFX_WideString& sError) {
+  if (vp.IsGetting())
+    vp.GetJSValue()->SetNull(CJS_Runtime::FromContext(cc));
+
+  return true;
+}
+
+bool Document::pageNum(IJS_Context* cc,
+                       CJS_PropValue& vp,
+                       CFX_WideString& sError) {
+  if (!m_pFormFillEnv) {
+    sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+    return false;
+  }
+  if (vp.IsGetting()) {
+    if (CPDFSDK_PageView* pPageView = m_pFormFillEnv->GetCurrentView()) {
+      vp << pPageView->GetPageIndex();
+    }
+  } else {
+    int iPageCount = m_pFormFillEnv->GetPageCount();
+    int iPageNum = 0;
+    vp >> iPageNum;
+
+    if (iPageNum >= 0 && iPageNum < iPageCount) {
+      m_pFormFillEnv->JS_docgotoPage(iPageNum);
+    } else if (iPageNum >= iPageCount) {
+      m_pFormFillEnv->JS_docgotoPage(iPageCount - 1);
+    } else if (iPageNum < 0) {
+      m_pFormFillEnv->JS_docgotoPage(0);
+    }
+  }
+
+  return true;
+}
+
+bool Document::addAnnot(IJS_Context* cc,
+                        const std::vector<CJS_Value>& params,
+                        CJS_Value& vRet,
+                        CFX_WideString& sError) {
+  // Not supported.
+  return true;
+}
+
+bool Document::addField(IJS_Context* cc,
+                        const std::vector<CJS_Value>& params,
+                        CJS_Value& vRet,
+                        CFX_WideString& sError) {
+  // Not supported.
+  return true;
+}
+
+bool Document::exportAsText(IJS_Context* cc,
+                            const std::vector<CJS_Value>& params,
+                            CJS_Value& vRet,
+                            CFX_WideString& sError) {
+  // Unsafe, not supported.
+  return true;
+}
+
+bool Document::exportAsFDF(IJS_Context* cc,
+                           const std::vector<CJS_Value>& params,
+                           CJS_Value& vRet,
+                           CFX_WideString& sError) {
+  // Unsafe, not supported.
+  return true;
+}
+
+bool Document::exportAsXFDF(IJS_Context* cc,
+                            const std::vector<CJS_Value>& params,
+                            CJS_Value& vRet,
+                            CFX_WideString& sError) {
+  // Unsafe, not supported.
+  return true;
+}
+
+// Maps a field object in PDF document to a JavaScript variable
+// comment:
+// note: the paremter cName, this is clue how to treat if the cName is not a
+// valiable filed name in this document
+
+bool Document::getField(IJS_Context* cc,
+                        const std::vector<CJS_Value>& params,
+                        CJS_Value& vRet,
+                        CFX_WideString& sError) {
+  if (params.size() < 1) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+  if (!m_pFormFillEnv) {
+    sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+    return false;
+  }
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+  CFX_WideString wideName = params[0].ToCFXWideString(pRuntime);
+  CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm();
+  CPDF_InterForm* pPDFForm = pInterForm->GetInterForm();
+  if (pPDFForm->CountFields(wideName) <= 0) {
+    vRet.SetNull(pRuntime);
+    return true;
+  }
+
+  v8::Local<v8::Object> pFieldObj =
+      pRuntime->NewFxDynamicObj(CJS_Field::g_nObjDefnID);
+  CJS_Field* pJSField =
+      static_cast<CJS_Field*>(pRuntime->GetObjectPrivate(pFieldObj));
+  Field* pField = static_cast<Field*>(pJSField->GetEmbedObject());
+  pField->AttachField(this, wideName);
+
+  vRet = CJS_Value(pRuntime, pJSField);
+  return true;
+}
+
+// Gets the name of the nth field in the document
+bool Document::getNthFieldName(IJS_Context* cc,
+                               const std::vector<CJS_Value>& params,
+                               CJS_Value& vRet,
+                               CFX_WideString& sError) {
+  if (params.size() != 1) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+  if (!m_pFormFillEnv) {
+    sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+    return false;
+  }
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+  int nIndex = params[0].ToInt(pRuntime);
+  if (nIndex < 0) {
+    sError = JSGetStringFromID(IDS_STRING_JSVALUEERROR);
+    return false;
+  }
+  CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm();
+  CPDF_InterForm* pPDFForm = pInterForm->GetInterForm();
+  CPDF_FormField* pField = pPDFForm->GetField(nIndex, CFX_WideString());
+  if (!pField)
+    return false;
+
+  vRet = CJS_Value(pRuntime, pField->GetFullName().c_str());
+  return true;
+}
+
+bool Document::importAnFDF(IJS_Context* cc,
+                           const std::vector<CJS_Value>& params,
+                           CJS_Value& vRet,
+                           CFX_WideString& sError) {
+  // Unsafe, not supported.
+  return true;
+}
+
+bool Document::importAnXFDF(IJS_Context* cc,
+                            const std::vector<CJS_Value>& params,
+                            CJS_Value& vRet,
+                            CFX_WideString& sError) {
+  // Unsafe, not supported.
+  return true;
+}
+
+bool Document::importTextData(IJS_Context* cc,
+                              const std::vector<CJS_Value>& params,
+                              CJS_Value& vRet,
+                              CFX_WideString& sError) {
+  // Unsafe, not supported.
+  return true;
+}
+
+// exports the form data and mails the resulting fdf file as an attachment to
+// all recipients.
+// comment: need reader supports
+bool Document::mailForm(IJS_Context* cc,
+                        const std::vector<CJS_Value>& params,
+                        CJS_Value& vRet,
+                        CFX_WideString& sError) {
+  if (!m_pFormFillEnv) {
+    sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+    return false;
+  }
+  if (!m_pFormFillEnv->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) {
+    sError = JSGetStringFromID(IDS_STRING_JSNOPERMISSION);
+    return false;
+  }
+
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+
+  int iLength = params.size();
+  bool bUI = iLength > 0 ? params[0].ToBool(pRuntime) : true;
+  CFX_WideString cTo = iLength > 1 ? params[1].ToCFXWideString(pRuntime) : L"";
+  CFX_WideString cCc = iLength > 2 ? params[2].ToCFXWideString(pRuntime) : L"";
+  CFX_WideString cBcc = iLength > 3 ? params[3].ToCFXWideString(pRuntime) : L"";
+  CFX_WideString cSubject =
+      iLength > 4 ? params[4].ToCFXWideString(pRuntime) : L"";
+  CFX_WideString cMsg = iLength > 5 ? params[5].ToCFXWideString(pRuntime) : L"";
+
+  CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm();
+  CFX_ByteTextBuf textBuf;
+  if (!pInterForm->ExportFormToFDFTextBuf(textBuf))
+    return false;
+
+  pRuntime->BeginBlock();
+  CPDFSDK_FormFillEnvironment* pFormFillEnv = pContext->GetFormFillEnv();
+  pFormFillEnv->JS_docmailForm(textBuf.GetBuffer(), textBuf.GetLength(), bUI,
+                               cTo.c_str(), cSubject.c_str(), cCc.c_str(),
+                               cBcc.c_str(), cMsg.c_str());
+  pRuntime->EndBlock();
+  return true;
+}
+
+bool Document::print(IJS_Context* cc,
+                     const std::vector<CJS_Value>& params,
+                     CJS_Value& vRet,
+                     CFX_WideString& sError) {
+  if (!m_pFormFillEnv) {
+    sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+    return false;
+  }
+
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+
+  bool bUI = true;
+  int nStart = 0;
+  int nEnd = 0;
+  bool bSilent = false;
+  bool bShrinkToFit = false;
+  bool bPrintAsImage = false;
+  bool bReverse = false;
+  bool bAnnotations = false;
+
+  int nlength = params.size();
+  if (nlength == 9) {
+    if (params[8].GetType() == CJS_Value::VT_object) {
+      v8::Local<v8::Object> pObj = params[8].ToV8Object(pRuntime);
+      if (CFXJS_Engine::GetObjDefnID(pObj) ==
+          CJS_PrintParamsObj::g_nObjDefnID) {
+        if (CJS_Object* pJSObj = params[8].ToCJSObject(pRuntime)) {
+          if (PrintParamsObj* pprintparamsObj =
+                  static_cast<PrintParamsObj*>(pJSObj->GetEmbedObject())) {
+            bUI = pprintparamsObj->bUI;
+            nStart = pprintparamsObj->nStart;
+            nEnd = pprintparamsObj->nEnd;
+            bSilent = pprintparamsObj->bSilent;
+            bShrinkToFit = pprintparamsObj->bShrinkToFit;
+            bPrintAsImage = pprintparamsObj->bPrintAsImage;
+            bReverse = pprintparamsObj->bReverse;
+            bAnnotations = pprintparamsObj->bAnnotations;
+          }
+        }
+      }
+    }
+  } else {
+    if (nlength >= 1)
+      bUI = params[0].ToBool(pRuntime);
+    if (nlength >= 2)
+      nStart = params[1].ToInt(pRuntime);
+    if (nlength >= 3)
+      nEnd = params[2].ToInt(pRuntime);
+    if (nlength >= 4)
+      bSilent = params[3].ToBool(pRuntime);
+    if (nlength >= 5)
+      bShrinkToFit = params[4].ToBool(pRuntime);
+    if (nlength >= 6)
+      bPrintAsImage = params[5].ToBool(pRuntime);
+    if (nlength >= 7)
+      bReverse = params[6].ToBool(pRuntime);
+    if (nlength >= 8)
+      bAnnotations = params[7].ToBool(pRuntime);
+  }
+
+  if (m_pFormFillEnv) {
+    m_pFormFillEnv->JS_docprint(bUI, nStart, nEnd, bSilent, bShrinkToFit,
+                                bPrintAsImage, bReverse, bAnnotations);
+    return true;
+  }
+  return false;
+}
+
+// removes the specified field from the document.
+// comment:
+// note: if the filed name is not rational, adobe is dumb for it.
+
+bool Document::removeField(IJS_Context* cc,
+                           const std::vector<CJS_Value>& params,
+                           CJS_Value& vRet,
+                           CFX_WideString& sError) {
+  if (params.size() != 1) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+  if (!m_pFormFillEnv) {
+    sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+    return false;
+  }
+  if (!(m_pFormFillEnv->GetPermissions(FPDFPERM_MODIFY) ||
+        m_pFormFillEnv->GetPermissions(FPDFPERM_ANNOT_FORM))) {
+    sError = JSGetStringFromID(IDS_STRING_JSNOPERMISSION);
+    return false;
+  }
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+  CFX_WideString sFieldName = params[0].ToCFXWideString(pRuntime);
+  CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm();
+  std::vector<CPDFSDK_Annot::ObservedPtr> widgets;
+  pInterForm->GetWidgets(sFieldName, &widgets);
+  if (widgets.empty())
+    return true;
+
+  for (const auto& pAnnot : widgets) {
+    CPDFSDK_Widget* pWidget = static_cast<CPDFSDK_Widget*>(pAnnot.Get());
+    if (!pWidget)
+      continue;
+
+    CFX_FloatRect rcAnnot = pWidget->GetRect();
+    --rcAnnot.left;
+    --rcAnnot.bottom;
+    ++rcAnnot.right;
+    ++rcAnnot.top;
+
+    std::vector<CFX_FloatRect> aRefresh(1, rcAnnot);
+    UnderlyingPageType* pPage = pWidget->GetUnderlyingPage();
+    ASSERT(pPage);
+
+    // If there is currently no pageview associated with the page being used
+    // do not create one. We may be in the process of tearing down the document
+    // and creating a new pageview at this point will cause bad things.
+    CPDFSDK_PageView* pPageView = m_pFormFillEnv->GetPageView(pPage, false);
+    if (pPageView) {
+#if PDF_ENABLE_XFA
+      pPageView->DeleteAnnot(pWidget);
+#endif  // PDF_ENABLE_XFA
+      pPageView->UpdateRects(aRefresh);
+    }
+  }
+  m_pFormFillEnv->SetChangeMark();
+
+  return true;
+}
+
+// reset filed values within a document.
+// comment:
+// note: if the fields names r not rational, aodbe is dumb for it.
+
+bool Document::resetForm(IJS_Context* cc,
+                         const std::vector<CJS_Value>& params,
+                         CJS_Value& vRet,
+                         CFX_WideString& sError) {
+  if (!m_pFormFillEnv) {
+    sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+    return false;
+  }
+  if (!(m_pFormFillEnv->GetPermissions(FPDFPERM_MODIFY) ||
+        m_pFormFillEnv->GetPermissions(FPDFPERM_ANNOT_FORM) ||
+        m_pFormFillEnv->GetPermissions(FPDFPERM_FILL_FORM))) {
+    sError = JSGetStringFromID(IDS_STRING_JSNOPERMISSION);
+    return false;
+  }
+
+  CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm();
+  CPDF_InterForm* pPDFForm = pInterForm->GetInterForm();
+  CJS_Array aName;
+
+  if (params.empty()) {
+    pPDFForm->ResetForm(true);
+    m_pFormFillEnv->SetChangeMark();
+    return true;
+  }
+
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+
+  switch (params[0].GetType()) {
+    default:
+      aName.Attach(params[0].ToV8Array(pRuntime));
+      break;
+    case CJS_Value::VT_string:
+      aName.SetElement(pRuntime, 0, params[0]);
+      break;
+  }
+
+  std::vector<CPDF_FormField*> aFields;
+  for (int i = 0, isz = aName.GetLength(pRuntime); i < isz; ++i) {
+    CJS_Value valElement(pRuntime);
+    aName.GetElement(pRuntime, i, valElement);
+    CFX_WideString swVal = valElement.ToCFXWideString(pRuntime);
+    for (int j = 0, jsz = pPDFForm->CountFields(swVal); j < jsz; ++j)
+      aFields.push_back(pPDFForm->GetField(j, swVal));
+  }
+
+  if (!aFields.empty()) {
+    pPDFForm->ResetForm(aFields, true, true);
+    m_pFormFillEnv->SetChangeMark();
+  }
+
+  return true;
+}
+
+bool Document::saveAs(IJS_Context* cc,
+                      const std::vector<CJS_Value>& params,
+                      CJS_Value& vRet,
+                      CFX_WideString& sError) {
+  // Unsafe, not supported.
+  return true;
+}
+
+bool Document::syncAnnotScan(IJS_Context* cc,
+                             const std::vector<CJS_Value>& params,
+                             CJS_Value& vRet,
+                             CFX_WideString& sError) {
+  return true;
+}
+
+bool Document::submitForm(IJS_Context* cc,
+                          const std::vector<CJS_Value>& params,
+                          CJS_Value& vRet,
+                          CFX_WideString& sError) {
+  int nSize = params.size();
+  if (nSize < 1) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+  if (!m_pFormFillEnv) {
+    sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+    return false;
+  }
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+  CJS_Array aFields;
+  CFX_WideString strURL;
+  bool bFDF = true;
+  bool bEmpty = false;
+  CJS_Value v = params[0];
+  if (v.GetType() == CJS_Value::VT_string) {
+    strURL = params[0].ToCFXWideString(pRuntime);
+    if (nSize > 1)
+      bFDF = params[1].ToBool(pRuntime);
+    if (nSize > 2)
+      bEmpty = params[2].ToBool(pRuntime);
+    if (nSize > 3)
+      aFields.Attach(params[3].ToV8Array(pRuntime));
+  } else if (v.GetType() == CJS_Value::VT_object) {
+    v8::Local<v8::Object> pObj = params[0].ToV8Object(pRuntime);
+    v8::Local<v8::Value> pValue = pRuntime->GetObjectProperty(pObj, L"cURL");
+    if (!pValue.IsEmpty())
+      strURL = CJS_Value(pRuntime, pValue).ToCFXWideString(pRuntime);
+
+    pValue = pRuntime->GetObjectProperty(pObj, L"bFDF");
+    bFDF = CJS_Value(pRuntime, pValue).ToBool(pRuntime);
+
+    pValue = pRuntime->GetObjectProperty(pObj, L"bEmpty");
+    bEmpty = CJS_Value(pRuntime, pValue).ToBool(pRuntime);
+
+    pValue = pRuntime->GetObjectProperty(pObj, L"aFields");
+    aFields.Attach(CJS_Value(pRuntime, pValue).ToV8Array(pRuntime));
+  }
+
+  CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm();
+  CPDF_InterForm* pPDFInterForm = pInterForm->GetInterForm();
+  if (aFields.GetLength(pRuntime) == 0 && bEmpty) {
+    if (pPDFInterForm->CheckRequiredFields(nullptr, true)) {
+      pRuntime->BeginBlock();
+      pInterForm->SubmitForm(strURL, false);
+      pRuntime->EndBlock();
+    }
+    return true;
+  }
+
+  std::vector<CPDF_FormField*> fieldObjects;
+  for (int i = 0, sz = aFields.GetLength(pRuntime); i < sz; ++i) {
+    CJS_Value valName(pRuntime);
+    aFields.GetElement(pRuntime, i, valName);
+
+    CFX_WideString sName = valName.ToCFXWideString(pRuntime);
+    CPDF_InterForm* pPDFForm = pInterForm->GetInterForm();
+    for (int j = 0, jsz = pPDFForm->CountFields(sName); j < jsz; ++j) {
+      CPDF_FormField* pField = pPDFForm->GetField(j, sName);
+      if (!bEmpty && pField->GetValue().IsEmpty())
+        continue;
+
+      fieldObjects.push_back(pField);
+    }
+  }
+
+  if (pPDFInterForm->CheckRequiredFields(&fieldObjects, true)) {
+    pRuntime->BeginBlock();
+    pInterForm->SubmitFields(strURL, fieldObjects, true, !bFDF);
+    pRuntime->EndBlock();
+  }
+  return true;
+}
+
+void Document::SetFormFillEnv(CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+  m_pFormFillEnv.Reset(pFormFillEnv);
+}
+
+bool Document::bookmarkRoot(IJS_Context* cc,
+                            CJS_PropValue& vp,
+                            CFX_WideString& sError) {
+  return true;
+}
+
+bool Document::mailDoc(IJS_Context* cc,
+                       const std::vector<CJS_Value>& params,
+                       CJS_Value& vRet,
+                       CFX_WideString& sError) {
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+
+  // TODO(tsepez): Check maximum number of allowed params.
+
+  bool bUI = true;
+  CFX_WideString cTo = L"";
+  CFX_WideString cCc = L"";
+  CFX_WideString cBcc = L"";
+  CFX_WideString cSubject = L"";
+  CFX_WideString cMsg = L"";
+
+  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+
+  if (params.size() >= 1)
+    bUI = params[0].ToBool(pRuntime);
+  if (params.size() >= 2)
+    cTo = params[1].ToCFXWideString(pRuntime);
+  if (params.size() >= 3)
+    cCc = params[2].ToCFXWideString(pRuntime);
+  if (params.size() >= 4)
+    cBcc = params[3].ToCFXWideString(pRuntime);
+  if (params.size() >= 5)
+    cSubject = params[4].ToCFXWideString(pRuntime);
+  if (params.size() >= 6)
+    cMsg = params[5].ToCFXWideString(pRuntime);
+
+  if (params.size() >= 1 && params[0].GetType() == CJS_Value::VT_object) {
+    v8::Local<v8::Object> pObj = params[0].ToV8Object(pRuntime);
+
+    v8::Local<v8::Value> pValue = pRuntime->GetObjectProperty(pObj, L"bUI");
+    bUI = CJS_Value(pRuntime, pValue).ToBool(pRuntime);
+
+    pValue = pRuntime->GetObjectProperty(pObj, L"cTo");
+    cTo = CJS_Value(pRuntime, pValue).ToCFXWideString(pRuntime);
+
+    pValue = pRuntime->GetObjectProperty(pObj, L"cCc");
+    cCc = CJS_Value(pRuntime, pValue).ToCFXWideString(pRuntime);
+
+    pValue = pRuntime->GetObjectProperty(pObj, L"cBcc");
+    cBcc = CJS_Value(pRuntime, pValue).ToCFXWideString(pRuntime);
+
+    pValue = pRuntime->GetObjectProperty(pObj, L"cSubject");
+    cSubject = CJS_Value(pRuntime, pValue).ToCFXWideString(pRuntime);
+
+    pValue = pRuntime->GetObjectProperty(pObj, L"cMsg");
+    cMsg = CJS_Value(pRuntime, pValue).ToCFXWideString(pRuntime);
+  }
+
+  pRuntime->BeginBlock();
+  CPDFSDK_FormFillEnvironment* pFormFillEnv = pRuntime->GetFormFillEnv();
+  pFormFillEnv->JS_docmailForm(nullptr, 0, bUI, cTo.c_str(), cSubject.c_str(),
+                               cCc.c_str(), cBcc.c_str(), cMsg.c_str());
+  pRuntime->EndBlock();
+
+  return true;
+}
+
+bool Document::author(IJS_Context* cc,
+                      CJS_PropValue& vp,
+                      CFX_WideString& sError) {
+  return getPropertyInternal(cc, vp, "Author", sError);
+}
+
+bool Document::info(IJS_Context* cc,
+                    CJS_PropValue& vp,
+                    CFX_WideString& sError) {
+  if (vp.IsSetting()) {
+    sError = JSGetStringFromID(IDS_STRING_JSREADONLY);
+    return false;
+  }
+  if (!m_pFormFillEnv) {
+    sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+    return false;
+  }
+  CPDF_Dictionary* pDictionary = m_pFormFillEnv->GetPDFDocument()->GetInfo();
+  if (!pDictionary)
+    return false;
+
+  CFX_WideString cwAuthor = pDictionary->GetUnicodeTextFor("Author");
+  CFX_WideString cwTitle = pDictionary->GetUnicodeTextFor("Title");
+  CFX_WideString cwSubject = pDictionary->GetUnicodeTextFor("Subject");
+  CFX_WideString cwKeywords = pDictionary->GetUnicodeTextFor("Keywords");
+  CFX_WideString cwCreator = pDictionary->GetUnicodeTextFor("Creator");
+  CFX_WideString cwProducer = pDictionary->GetUnicodeTextFor("Producer");
+  CFX_WideString cwCreationDate =
+      pDictionary->GetUnicodeTextFor("CreationDate");
+  CFX_WideString cwModDate = pDictionary->GetUnicodeTextFor("ModDate");
+  CFX_WideString cwTrapped = pDictionary->GetUnicodeTextFor("Trapped");
+
+  CJS_Context* pContext = (CJS_Context*)cc;
+  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+
+  v8::Local<v8::Object> pObj = pRuntime->NewFxDynamicObj(-1);
+  pRuntime->PutObjectProperty(pObj, L"Author", pRuntime->NewString(cwAuthor));
+  pRuntime->PutObjectProperty(pObj, L"Title", pRuntime->NewString(cwTitle));
+  pRuntime->PutObjectProperty(pObj, L"Subject", pRuntime->NewString(cwSubject));
+  pRuntime->PutObjectProperty(pObj, L"Keywords",
+                              pRuntime->NewString(cwKeywords));
+  pRuntime->PutObjectProperty(pObj, L"Creator", pRuntime->NewString(cwCreator));
+  pRuntime->PutObjectProperty(pObj, L"Producer",
+                              pRuntime->NewString(cwProducer));
+  pRuntime->PutObjectProperty(pObj, L"CreationDate",
+                              pRuntime->NewString(cwCreationDate));
+  pRuntime->PutObjectProperty(pObj, L"ModDate", pRuntime->NewString(cwModDate));
+  pRuntime->PutObjectProperty(pObj, L"Trapped", pRuntime->NewString(cwTrapped));
+
+  // It's to be compatible to non-standard info dictionary.
+  for (const auto& it : *pDictionary) {
+    const CFX_ByteString& bsKey = it.first;
+    CPDF_Object* pValueObj = it.second.get();
+    CFX_WideString wsKey = CFX_WideString::FromUTF8(bsKey.AsStringC());
+    if (pValueObj->IsString() || pValueObj->IsName()) {
+      pRuntime->PutObjectProperty(
+          pObj, wsKey, pRuntime->NewString(pValueObj->GetUnicodeText()));
+    } else if (pValueObj->IsNumber()) {
+      pRuntime->PutObjectProperty(pObj, wsKey,
+                                  pRuntime->NewNumber(pValueObj->GetNumber()));
+    } else if (pValueObj->IsBoolean()) {
+      pRuntime->PutObjectProperty(
+          pObj, wsKey, pRuntime->NewBoolean(!!pValueObj->GetInteger()));
+    }
+  }
+  vp << pObj;
+  return true;
+}
+
+bool Document::getPropertyInternal(IJS_Context* cc,
+                                   CJS_PropValue& vp,
+                                   const CFX_ByteString& propName,
+                                   CFX_WideString& sError) {
+  if (!m_pFormFillEnv) {
+    sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+    return false;
+  }
+  CPDF_Dictionary* pDictionary = m_pFormFillEnv->GetPDFDocument()->GetInfo();
+  if (!pDictionary)
+    return false;
+
+  if (vp.IsGetting()) {
+    vp << pDictionary->GetUnicodeTextFor(propName);
+  } else {
+    if (!m_pFormFillEnv->GetPermissions(FPDFPERM_MODIFY)) {
+      sError = JSGetStringFromID(IDS_STRING_JSNOPERMISSION);
+      return false;
+    }
+    CFX_WideString csProperty;
+    vp >> csProperty;
+    pDictionary->SetNewFor<CPDF_String>(propName, PDF_EncodeText(csProperty),
+                                        false);
+    m_pFormFillEnv->SetChangeMark();
+  }
+  return true;
+}
+
+bool Document::creationDate(IJS_Context* cc,
+                            CJS_PropValue& vp,
+                            CFX_WideString& sError) {
+  return getPropertyInternal(cc, vp, "CreationDate", sError);
+}
+
+bool Document::creator(IJS_Context* cc,
+                       CJS_PropValue& vp,
+                       CFX_WideString& sError) {
+  return getPropertyInternal(cc, vp, "Creator", sError);
+}
+
+bool Document::delay(IJS_Context* cc,
+                     CJS_PropValue& vp,
+                     CFX_WideString& sError) {
+  if (!m_pFormFillEnv) {
+    sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+    return false;
+  }
+  if (vp.IsGetting()) {
+    vp << m_bDelay;
+  } else {
+    if (!m_pFormFillEnv->GetPermissions(FPDFPERM_MODIFY)) {
+      sError = JSGetStringFromID(IDS_STRING_JSNOPERMISSION);
+      return false;
+    }
+    vp >> m_bDelay;
+    if (m_bDelay) {
+      m_DelayData.clear();
+    } else {
+      std::list<std::unique_ptr<CJS_DelayData>> DelayDataToProcess;
+      DelayDataToProcess.swap(m_DelayData);
+      for (const auto& pData : DelayDataToProcess)
+        Field::DoDelay(m_pFormFillEnv.Get(), pData.get());
+    }
+  }
+  return true;
+}
+
+bool Document::keywords(IJS_Context* cc,
+                        CJS_PropValue& vp,
+                        CFX_WideString& sError) {
+  return getPropertyInternal(cc, vp, "Keywords", sError);
+}
+
+bool Document::modDate(IJS_Context* cc,
+                       CJS_PropValue& vp,
+                       CFX_WideString& sError) {
+  return getPropertyInternal(cc, vp, "ModDate", sError);
+}
+
+bool Document::producer(IJS_Context* cc,
+                        CJS_PropValue& vp,
+                        CFX_WideString& sError) {
+  return getPropertyInternal(cc, vp, "Producer", sError);
+}
+
+bool Document::subject(IJS_Context* cc,
+                       CJS_PropValue& vp,
+                       CFX_WideString& sError) {
+  return getPropertyInternal(cc, vp, "Subject", sError);
+}
+
+bool Document::title(IJS_Context* cc,
+                     CJS_PropValue& vp,
+                     CFX_WideString& sError) {
+  if (!m_pFormFillEnv || !m_pFormFillEnv->GetUnderlyingDocument()) {
+    sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+    return false;
+  }
+  return getPropertyInternal(cc, vp, "Title", sError);
+}
+
+bool Document::numPages(IJS_Context* cc,
+                        CJS_PropValue& vp,
+                        CFX_WideString& sError) {
+  if (vp.IsSetting()) {
+    sError = JSGetStringFromID(IDS_STRING_JSREADONLY);
+    return false;
+  }
+  if (!m_pFormFillEnv) {
+    sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+    return false;
+  }
+  vp << m_pFormFillEnv->GetPageCount();
+  return true;
+}
+
+bool Document::external(IJS_Context* cc,
+                        CJS_PropValue& vp,
+                        CFX_WideString& sError) {
+  // In Chrome case, should always return true.
+  if (vp.IsGetting()) {
+    vp << true;
+  }
+  return true;
+}
+
+bool Document::filesize(IJS_Context* cc,
+                        CJS_PropValue& vp,
+                        CFX_WideString& sError) {
+  if (vp.IsSetting()) {
+    sError = JSGetStringFromID(IDS_STRING_JSREADONLY);
+    return false;
+  }
+  vp << 0;
+  return true;
+}
+
+bool Document::mouseX(IJS_Context* cc,
+                      CJS_PropValue& vp,
+                      CFX_WideString& sError) {
+  return true;
+}
+
+bool Document::mouseY(IJS_Context* cc,
+                      CJS_PropValue& vp,
+                      CFX_WideString& sError) {
+  return true;
+}
+
+bool Document::URL(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
+  if (vp.IsSetting()) {
+    sError = JSGetStringFromID(IDS_STRING_JSREADONLY);
+    return false;
+  }
+  if (!m_pFormFillEnv) {
+    sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+    return false;
+  }
+  vp << m_pFormFillEnv->JS_docGetFilePath();
+  return true;
+}
+
+bool Document::baseURL(IJS_Context* cc,
+                       CJS_PropValue& vp,
+                       CFX_WideString& sError) {
+  if (vp.IsGetting()) {
+    vp << m_cwBaseURL;
+  } else {
+    vp >> m_cwBaseURL;
+  }
+  return true;
+}
+
+bool Document::calculate(IJS_Context* cc,
+                         CJS_PropValue& vp,
+                         CFX_WideString& sError) {
+  if (!m_pFormFillEnv) {
+    sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+    return false;
+  }
+  CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm();
+  if (vp.IsGetting()) {
+    vp << !!pInterForm->IsCalculateEnabled();
+  } else {
+    bool bCalculate;
+    vp >> bCalculate;
+    pInterForm->EnableCalculate(bCalculate);
+  }
+  return true;
+}
+
+bool Document::documentFileName(IJS_Context* cc,
+                                CJS_PropValue& vp,
+                                CFX_WideString& sError) {
+  if (vp.IsSetting()) {
+    sError = JSGetStringFromID(IDS_STRING_JSREADONLY);
+    return false;
+  }
+  if (!m_pFormFillEnv) {
+    sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+    return false;
+  }
+  CFX_WideString wsFilePath = m_pFormFillEnv->JS_docGetFilePath();
+  int32_t i = wsFilePath.GetLength() - 1;
+  for (; i >= 0; i--) {
+    if (wsFilePath.GetAt(i) == L'\\' || wsFilePath.GetAt(i) == L'/')
+      break;
+  }
+  if (i >= 0 && i < wsFilePath.GetLength() - 1) {
+    vp << (wsFilePath.GetBuffer(wsFilePath.GetLength()) + i + 1);
+  } else {
+    vp << L"";
+  }
+  return true;
+}
+
+bool Document::path(IJS_Context* cc,
+                    CJS_PropValue& vp,
+                    CFX_WideString& sError) {
+  if (vp.IsSetting()) {
+    sError = JSGetStringFromID(IDS_STRING_JSREADONLY);
+    return false;
+  }
+  if (!m_pFormFillEnv) {
+    sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+    return false;
+  }
+  vp << app::SysPathToPDFPath(m_pFormFillEnv->JS_docGetFilePath());
+  return true;
+}
+
+bool Document::pageWindowRect(IJS_Context* cc,
+                              CJS_PropValue& vp,
+                              CFX_WideString& sError) {
+  return true;
+}
+
+bool Document::layout(IJS_Context* cc,
+                      CJS_PropValue& vp,
+                      CFX_WideString& sError) {
+  return true;
+}
+
+bool Document::addLink(IJS_Context* cc,
+                       const std::vector<CJS_Value>& params,
+                       CJS_Value& vRet,
+                       CFX_WideString& sError) {
+  return true;
+}
+
+bool Document::closeDoc(IJS_Context* cc,
+                        const std::vector<CJS_Value>& params,
+                        CJS_Value& vRet,
+                        CFX_WideString& sError) {
+  return true;
+}
+
+bool Document::getPageBox(IJS_Context* cc,
+                          const std::vector<CJS_Value>& params,
+                          CJS_Value& vRet,
+                          CFX_WideString& sError) {
+  return true;
+}
+
+bool Document::getAnnot(IJS_Context* cc,
+                        const std::vector<CJS_Value>& params,
+                        CJS_Value& vRet,
+                        CFX_WideString& sError) {
+  if (params.size() != 2) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+  if (!m_pFormFillEnv) {
+    sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+    return false;
+  }
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+  int nPageNo = params[0].ToInt(pRuntime);
+  CFX_WideString swAnnotName = params[1].ToCFXWideString(pRuntime);
+  CPDFSDK_PageView* pPageView = m_pFormFillEnv->GetPageView(nPageNo);
+  if (!pPageView)
+    return false;
+
+  CPDFSDK_AnnotIteration annotIteration(pPageView, false);
+  CPDFSDK_BAAnnot* pSDKBAAnnot = nullptr;
+  for (const auto& pSDKAnnotCur : annotIteration) {
+    CPDFSDK_BAAnnot* pBAAnnot =
+        static_cast<CPDFSDK_BAAnnot*>(pSDKAnnotCur.Get());
+    if (pBAAnnot && pBAAnnot->GetAnnotName() == swAnnotName) {
+      pSDKBAAnnot = pBAAnnot;
+      break;
+    }
+  }
+  if (!pSDKBAAnnot)
+    return false;
+
+  v8::Local<v8::Object> pObj =
+      pRuntime->NewFxDynamicObj(CJS_Annot::g_nObjDefnID);
+  if (pObj.IsEmpty())
+    return false;
+
+  CJS_Annot* pJS_Annot =
+      static_cast<CJS_Annot*>(pRuntime->GetObjectPrivate(pObj));
+  if (!pJS_Annot)
+    return false;
+
+  Annot* pAnnot = static_cast<Annot*>(pJS_Annot->GetEmbedObject());
+  if (!pAnnot)
+    return false;
+
+  pAnnot->SetSDKAnnot(pSDKBAAnnot);
+  vRet = CJS_Value(pRuntime, pJS_Annot);
+  return true;
+}
+
+bool Document::getAnnots(IJS_Context* cc,
+                         const std::vector<CJS_Value>& params,
+                         CJS_Value& vRet,
+                         CFX_WideString& sError) {
+  if (!m_pFormFillEnv) {
+    sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+    return false;
+  }
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+
+  // TODO(tonikitoo): Add support supported parameters as per
+  // the PDF spec.
+
+  int nPageNo = m_pFormFillEnv->GetPageCount();
+  CJS_Array annots;
+
+  for (int i = 0; i < nPageNo; ++i) {
+    CPDFSDK_PageView* pPageView = m_pFormFillEnv->GetPageView(i);
+    if (!pPageView)
+      return false;
+
+    CPDFSDK_AnnotIteration annotIteration(pPageView, false);
+    for (const auto& pSDKAnnotCur : annotIteration) {
+      if (!pSDKAnnotCur) {
+        sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+        return false;
+      }
+      v8::Local<v8::Object> pObj =
+          pRuntime->NewFxDynamicObj(CJS_Annot::g_nObjDefnID);
+      if (pObj.IsEmpty())
+        return false;
+
+      CJS_Annot* pJS_Annot =
+          static_cast<CJS_Annot*>(pRuntime->GetObjectPrivate(pObj));
+      if (!pJS_Annot)
+        return false;
+
+      Annot* pAnnot = static_cast<Annot*>(pJS_Annot->GetEmbedObject());
+      if (!pAnnot)
+        return false;
+
+      pAnnot->SetSDKAnnot(static_cast<CPDFSDK_BAAnnot*>(pSDKAnnotCur.Get()));
+      annots.SetElement(pRuntime, i, CJS_Value(pRuntime, pJS_Annot));
+    }
+  }
+  vRet = CJS_Value(pRuntime, annots);
+  return true;
+}
+
+bool Document::getAnnot3D(IJS_Context* cc,
+                          const std::vector<CJS_Value>& params,
+                          CJS_Value& vRet,
+                          CFX_WideString& sError) {
+  vRet.SetNull(CJS_Runtime::FromContext(cc));
+  return true;
+}
+
+bool Document::getAnnots3D(IJS_Context* cc,
+                           const std::vector<CJS_Value>& params,
+                           CJS_Value& vRet,
+                           CFX_WideString& sError) {
+  return true;
+}
+
+bool Document::getOCGs(IJS_Context* cc,
+                       const std::vector<CJS_Value>& params,
+                       CJS_Value& vRet,
+                       CFX_WideString& sError) {
+  return true;
+}
+
+bool Document::getLinks(IJS_Context* cc,
+                        const std::vector<CJS_Value>& params,
+                        CJS_Value& vRet,
+                        CFX_WideString& sError) {
+  return true;
+}
+
+bool Document::IsEnclosedInRect(CFX_FloatRect rect, CFX_FloatRect LinkRect) {
+  return (rect.left <= LinkRect.left && rect.top <= LinkRect.top &&
+          rect.right >= LinkRect.right && rect.bottom >= LinkRect.bottom);
+}
+
+bool Document::addIcon(IJS_Context* cc,
+                       const std::vector<CJS_Value>& params,
+                       CJS_Value& vRet,
+                       CFX_WideString& sError) {
+  if (params.size() != 2) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+  CFX_WideString swIconName = params[0].ToCFXWideString(pRuntime);
+
+  if (params[1].GetType() != CJS_Value::VT_object) {
+    sError = JSGetStringFromID(IDS_STRING_JSTYPEERROR);
+    return false;
+  }
+
+  v8::Local<v8::Object> pJSIcon = params[1].ToV8Object(pRuntime);
+  if (pRuntime->GetObjDefnID(pJSIcon) != CJS_Icon::g_nObjDefnID) {
+    sError = JSGetStringFromID(IDS_STRING_JSTYPEERROR);
+    return false;
+  }
+
+  CJS_EmbedObj* pEmbedObj = params[1].ToCJSObject(pRuntime)->GetEmbedObject();
+  if (!pEmbedObj) {
+    sError = JSGetStringFromID(IDS_STRING_JSTYPEERROR);
+    return false;
+  }
+
+  m_Icons.push_back(pdfium::MakeUnique<IconElement>(
+      swIconName, static_cast<Icon*>(pEmbedObj)));
+  return true;
+}
+
+bool Document::icons(IJS_Context* cc,
+                     CJS_PropValue& vp,
+                     CFX_WideString& sError) {
+  if (vp.IsSetting()) {
+    sError = JSGetStringFromID(IDS_STRING_JSREADONLY);
+    return false;
+  }
+
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  if (m_Icons.empty()) {
+    vp.GetJSValue()->SetNull(pRuntime);
+    return true;
+  }
+
+  CJS_Array Icons;
+
+  int i = 0;
+  for (const auto& pIconElement : m_Icons) {
+    v8::Local<v8::Object> pObj =
+        pRuntime->NewFxDynamicObj(CJS_Icon::g_nObjDefnID);
+    if (pObj.IsEmpty())
+      return false;
+
+    CJS_Icon* pJS_Icon =
+        static_cast<CJS_Icon*>(pRuntime->GetObjectPrivate(pObj));
+    if (!pJS_Icon)
+      return false;
+
+    Icon* pIcon = static_cast<Icon*>(pJS_Icon->GetEmbedObject());
+    if (!pIcon)
+      return false;
+
+    pIcon->SetStream(pIconElement->IconStream->GetStream());
+    pIcon->SetIconName(pIconElement->IconName);
+    Icons.SetElement(pRuntime, i++, CJS_Value(pRuntime, pJS_Icon));
+  }
+
+  vp << Icons;
+  return true;
+}
+
+bool Document::getIcon(IJS_Context* cc,
+                       const std::vector<CJS_Value>& params,
+                       CJS_Value& vRet,
+                       CFX_WideString& sError) {
+  if (params.size() != 1) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+
+  if (m_Icons.empty())
+    return false;
+
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  CFX_WideString swIconName = params[0].ToCFXWideString(pRuntime);
+
+  for (const auto& pIconElement : m_Icons) {
+    if (pIconElement->IconName != swIconName)
+      continue;
+
+    v8::Local<v8::Object> pObj =
+        pRuntime->NewFxDynamicObj(CJS_Icon::g_nObjDefnID);
+    if (pObj.IsEmpty())
+      return false;
+
+    CJS_Icon* pJS_Icon =
+        static_cast<CJS_Icon*>(pRuntime->GetObjectPrivate(pObj));
+    if (!pJS_Icon)
+      return false;
+
+    Icon* pIcon = (Icon*)pJS_Icon->GetEmbedObject();
+    if (!pIcon)
+      return false;
+
+    pIcon->SetIconName(swIconName);
+    pIcon->SetStream(pIconElement->IconStream->GetStream());
+
+    vRet = CJS_Value(pRuntime, pJS_Icon);
+    return true;
+  }
+
+  return false;
+}
+
+bool Document::removeIcon(IJS_Context* cc,
+                          const std::vector<CJS_Value>& params,
+                          CJS_Value& vRet,
+                          CFX_WideString& sError) {
+  // Unsafe, no supported.
+  return true;
+}
+
+bool Document::createDataObject(IJS_Context* cc,
+                                const std::vector<CJS_Value>& params,
+                                CJS_Value& vRet,
+                                CFX_WideString& sError) {
+  // Unsafe, not implemented.
+  return true;
+}
+
+bool Document::media(IJS_Context* cc,
+                     CJS_PropValue& vp,
+                     CFX_WideString& sError) {
+  return true;
+}
+
+bool Document::calculateNow(IJS_Context* cc,
+                            const std::vector<CJS_Value>& params,
+                            CJS_Value& vRet,
+                            CFX_WideString& sError) {
+  if (!m_pFormFillEnv) {
+    sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+    return false;
+  }
+  if (!(m_pFormFillEnv->GetPermissions(FPDFPERM_MODIFY) ||
+        m_pFormFillEnv->GetPermissions(FPDFPERM_ANNOT_FORM) ||
+        m_pFormFillEnv->GetPermissions(FPDFPERM_FILL_FORM))) {
+    sError = JSGetStringFromID(IDS_STRING_JSNOPERMISSION);
+    return false;
+  }
+  m_pFormFillEnv->GetInterForm()->OnCalculate();
+  return true;
+}
+
+bool Document::Collab(IJS_Context* cc,
+                      CJS_PropValue& vp,
+                      CFX_WideString& sError) {
+  return true;
+}
+
+bool Document::getPageNthWord(IJS_Context* cc,
+                              const std::vector<CJS_Value>& params,
+                              CJS_Value& vRet,
+                              CFX_WideString& sError) {
+  if (!m_pFormFillEnv) {
+    sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+    return false;
+  }
+  if (!m_pFormFillEnv->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) {
+    sError = JSGetStringFromID(IDS_STRING_JSNOPERMISSION);
+    return false;
+  }
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+
+  // TODO(tsepez): check maximum allowable params.
+
+  int nPageNo = params.size() > 0 ? params[0].ToInt(pRuntime) : 0;
+  int nWordNo = params.size() > 1 ? params[1].ToInt(pRuntime) : 0;
+  bool bStrip = params.size() > 2 ? params[2].ToBool(pRuntime) : true;
+
+  CPDF_Document* pDocument = m_pFormFillEnv->GetPDFDocument();
+  if (!pDocument)
+    return false;
+
+  if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount()) {
+    sError = JSGetStringFromID(IDS_STRING_JSVALUEERROR);
+    return false;
+  }
+
+  CPDF_Dictionary* pPageDict = pDocument->GetPage(nPageNo);
+  if (!pPageDict)
+    return false;
+
+  CPDF_Page page(pDocument, pPageDict, true);
+  page.ParseContent();
+
+  int nWords = 0;
+  CFX_WideString swRet;
+  for (auto& pPageObj : *page.GetPageObjectList()) {
+    if (pPageObj->IsText()) {
+      CPDF_TextObject* pTextObj = pPageObj->AsText();
+      int nObjWords = CountWords(pTextObj);
+      if (nWords + nObjWords >= nWordNo) {
+        swRet = GetObjWordStr(pTextObj, nWordNo - nWords);
+        break;
+      }
+      nWords += nObjWords;
+    }
+  }
+
+  if (bStrip) {
+    swRet.TrimLeft();
+    swRet.TrimRight();
+  }
+
+  vRet = CJS_Value(pRuntime, swRet.c_str());
+  return true;
+}
+
+bool Document::getPageNthWordQuads(IJS_Context* cc,
+                                   const std::vector<CJS_Value>& params,
+                                   CJS_Value& vRet,
+                                   CFX_WideString& sError) {
+  if (!m_pFormFillEnv) {
+    sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+    return false;
+  }
+  if (!m_pFormFillEnv->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) {
+    sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+    return false;
+  }
+  return false;
+}
+
+bool Document::getPageNumWords(IJS_Context* cc,
+                               const std::vector<CJS_Value>& params,
+                               CJS_Value& vRet,
+                               CFX_WideString& sError) {
+  if (!m_pFormFillEnv) {
+    sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+    return false;
+  }
+  if (!m_pFormFillEnv->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) {
+    sError = JSGetStringFromID(IDS_STRING_JSNOPERMISSION);
+    return false;
+  }
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  int nPageNo = params.size() > 0 ? params[0].ToInt(pRuntime) : 0;
+  CPDF_Document* pDocument = m_pFormFillEnv->GetPDFDocument();
+  if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount()) {
+    sError = JSGetStringFromID(IDS_STRING_JSVALUEERROR);
+    return false;
+  }
+
+  CPDF_Dictionary* pPageDict = pDocument->GetPage(nPageNo);
+  if (!pPageDict)
+    return false;
+
+  CPDF_Page page(pDocument, pPageDict, true);
+  page.ParseContent();
+
+  int nWords = 0;
+  for (auto& pPageObj : *page.GetPageObjectList()) {
+    if (pPageObj->IsText())
+      nWords += CountWords(pPageObj->AsText());
+  }
+
+  vRet = CJS_Value(pRuntime, nWords);
+  return true;
+}
+
+bool Document::getPrintParams(IJS_Context* cc,
+                              const std::vector<CJS_Value>& params,
+                              CJS_Value& vRet,
+                              CFX_WideString& sError) {
+  CJS_Context* pContext = (CJS_Context*)cc;
+  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+  v8::Local<v8::Object> pRetObj =
+      pRuntime->NewFxDynamicObj(CJS_PrintParamsObj::g_nObjDefnID);
+
+  // Not implemented yet.
+
+  vRet = CJS_Value(pRuntime, pRetObj);
+  return true;
+}
+
+#define ISLATINWORD(u) (u != 0x20 && u <= 0x28FF)
+
+int Document::CountWords(CPDF_TextObject* pTextObj) {
+  if (!pTextObj)
+    return 0;
+
+  int nWords = 0;
+
+  CPDF_Font* pFont = pTextObj->GetFont();
+  if (!pFont)
+    return 0;
+
+  bool bIsLatin = false;
+
+  for (int i = 0, sz = pTextObj->CountChars(); i < sz; i++) {
+    uint32_t charcode = CPDF_Font::kInvalidCharCode;
+    FX_FLOAT kerning;
+
+    pTextObj->GetCharInfo(i, charcode, kerning);
+    CFX_WideString swUnicode = pFont->UnicodeFromCharCode(charcode);
+
+    uint16_t unicode = 0;
+    if (swUnicode.GetLength() > 0)
+      unicode = swUnicode[0];
+
+    if (ISLATINWORD(unicode) && bIsLatin)
+      continue;
+
+    bIsLatin = ISLATINWORD(unicode);
+    if (unicode != 0x20)
+      nWords++;
+  }
+
+  return nWords;
+}
+
+CFX_WideString Document::GetObjWordStr(CPDF_TextObject* pTextObj,
+                                       int nWordIndex) {
+  CFX_WideString swRet;
+
+  CPDF_Font* pFont = pTextObj->GetFont();
+  if (!pFont)
+    return L"";
+
+  int nWords = 0;
+  bool bIsLatin = false;
+
+  for (int i = 0, sz = pTextObj->CountChars(); i < sz; i++) {
+    uint32_t charcode = CPDF_Font::kInvalidCharCode;
+    FX_FLOAT kerning;
+
+    pTextObj->GetCharInfo(i, charcode, kerning);
+    CFX_WideString swUnicode = pFont->UnicodeFromCharCode(charcode);
+
+    uint16_t unicode = 0;
+    if (swUnicode.GetLength() > 0)
+      unicode = swUnicode[0];
+
+    if (ISLATINWORD(unicode) && bIsLatin) {
+    } else {
+      bIsLatin = ISLATINWORD(unicode);
+      if (unicode != 0x20)
+        nWords++;
+    }
+
+    if (nWords - 1 == nWordIndex)
+      swRet += unicode;
+  }
+
+  return swRet;
+}
+
+bool Document::zoom(IJS_Context* cc,
+                    CJS_PropValue& vp,
+                    CFX_WideString& sError) {
+  return true;
+}
+
+/**
+(none,  NoVary)
+(fitP,  FitPage)
+(fitW,  FitWidth)
+(fitH,  FitHeight)
+(fitV,  FitVisibleWidth)
+(pref,  Preferred)
+(refW,  ReflowWidth)
+*/
+
+bool Document::zoomType(IJS_Context* cc,
+                        CJS_PropValue& vp,
+                        CFX_WideString& sError) {
+  return true;
+}
+
+bool Document::deletePages(IJS_Context* cc,
+                           const std::vector<CJS_Value>& params,
+                           CJS_Value& vRet,
+                           CFX_WideString& sError) {
+  // Unsafe, no supported.
+  return true;
+}
+
+bool Document::extractPages(IJS_Context* cc,
+                            const std::vector<CJS_Value>& params,
+                            CJS_Value& vRet,
+                            CFX_WideString& sError) {
+  // Unsafe, not supported.
+  return true;
+}
+
+bool Document::insertPages(IJS_Context* cc,
+                           const std::vector<CJS_Value>& params,
+                           CJS_Value& vRet,
+                           CFX_WideString& sError) {
+  // Unsafe, not supported.
+  return true;
+}
+
+bool Document::replacePages(IJS_Context* cc,
+                            const std::vector<CJS_Value>& params,
+                            CJS_Value& vRet,
+                            CFX_WideString& sError) {
+  // Unsafe, not supported.
+  return true;
+}
+
+bool Document::getURL(IJS_Context* cc,
+                      const std::vector<CJS_Value>& params,
+                      CJS_Value& vRet,
+                      CFX_WideString& sError) {
+  // Unsafe, not supported.
+  return true;
+}
+
+bool Document::gotoNamedDest(IJS_Context* cc,
+                             const std::vector<CJS_Value>& params,
+                             CJS_Value& vRet,
+                             CFX_WideString& sError) {
+  if (params.size() != 1) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+  if (!m_pFormFillEnv) {
+    sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+    return false;
+  }
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  CFX_WideString wideName = params[0].ToCFXWideString(pRuntime);
+  CFX_ByteString utf8Name = wideName.UTF8Encode();
+  CPDF_Document* pDocument = m_pFormFillEnv->GetPDFDocument();
+  if (!pDocument)
+    return false;
+
+  CPDF_NameTree nameTree(pDocument, "Dests");
+  CPDF_Array* destArray = nameTree.LookupNamedDest(pDocument, utf8Name);
+  if (!destArray)
+    return false;
+
+  CPDF_Dest dest(destArray);
+  const CPDF_Array* arrayObject = ToArray(dest.GetObject());
+
+  std::unique_ptr<float[]> scrollPositionArray;
+  int scrollPositionArraySize = 0;
+
+  if (arrayObject) {
+    scrollPositionArray.reset(new float[arrayObject->GetCount()]);
+    int j = 0;
+    for (size_t i = 2; i < arrayObject->GetCount(); i++)
+      scrollPositionArray[j++] = arrayObject->GetFloatAt(i);
+    scrollPositionArraySize = j;
+  }
+
+  pRuntime->BeginBlock();
+  m_pFormFillEnv->DoGoToAction(dest.GetPageIndex(pDocument), dest.GetZoomMode(),
+                               scrollPositionArray.get(),
+                               scrollPositionArraySize);
+  pRuntime->EndBlock();
+
+  return true;
+}
+
+void Document::AddDelayData(CJS_DelayData* pData) {
+  m_DelayData.push_back(std::unique_ptr<CJS_DelayData>(pData));
+}
+
+void Document::DoFieldDelay(const CFX_WideString& sFieldName,
+                            int nControlIndex) {
+  std::vector<std::unique_ptr<CJS_DelayData>> DelayDataForFieldAndControlIndex;
+  auto iter = m_DelayData.begin();
+  while (iter != m_DelayData.end()) {
+    auto old = iter++;
+    if ((*old)->sFieldName == sFieldName &&
+        (*old)->nControlIndex == nControlIndex) {
+      DelayDataForFieldAndControlIndex.push_back(std::move(*old));
+      m_DelayData.erase(old);
+    }
+  }
+
+  for (const auto& pData : DelayDataForFieldAndControlIndex)
+    Field::DoDelay(m_pFormFillEnv.Get(), pData.get());
+}
+
+CJS_Document* Document::GetCJSDoc() const {
+  return static_cast<CJS_Document*>(m_pJSObject);
+}
diff --git a/fpdfsdk/javascript/Document.h b/fpdfsdk/javascript/Document.h
new file mode 100644
index 0000000..227c428
--- /dev/null
+++ b/fpdfsdk/javascript/Document.h
@@ -0,0 +1,382 @@
+// 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_JAVASCRIPT_DOCUMENT_H_
+#define FPDFSDK_JAVASCRIPT_DOCUMENT_H_
+
+#include <list>
+#include <memory>
+#include <vector>
+
+#include "core/fpdfapi/page/cpdf_pageobject.h"
+#include "core/fpdfapi/page/cpdf_textobject.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/javascript/JS_Define.h"
+
+class PrintParamsObj : public CJS_EmbedObj {
+ public:
+  explicit PrintParamsObj(CJS_Object* pJSObject);
+  ~PrintParamsObj() override {}
+
+ public:
+  bool bUI;
+  int nStart;
+  int nEnd;
+  bool bSilent;
+  bool bShrinkToFit;
+  bool bPrintAsImage;
+  bool bReverse;
+  bool bAnnotations;
+};
+
+class CJS_PrintParamsObj : public CJS_Object {
+ public:
+  explicit CJS_PrintParamsObj(v8::Local<v8::Object> pObject)
+      : CJS_Object(pObject) {}
+  ~CJS_PrintParamsObj() override {}
+
+  DECLARE_JS_CLASS();
+};
+
+class Icon;
+class Field;
+
+struct IconElement {
+  IconElement(const CFX_WideString& name, Icon* stream)
+      : IconName(name), IconStream(stream) {}
+
+  const CFX_WideString IconName;
+  Icon* const IconStream;
+};
+
+struct CJS_DelayData;
+struct CJS_DelayAnnot;
+struct CJS_AnnotObj;
+
+class Document : public CJS_EmbedObj {
+ public:
+  explicit Document(CJS_Object* pJSObject);
+  ~Document() override;
+
+  bool ADBE(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool author(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool baseURL(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool bookmarkRoot(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool calculate(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool Collab(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool creationDate(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool creator(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool delay(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool dirty(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool documentFileName(IJS_Context* cc,
+                        CJS_PropValue& vp,
+                        CFX_WideString& sError);
+  bool external(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool filesize(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool icons(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool info(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool keywords(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool layout(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool media(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool modDate(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool mouseX(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool mouseY(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool numFields(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool numPages(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool pageNum(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool pageWindowRect(IJS_Context* cc,
+                      CJS_PropValue& vp,
+                      CFX_WideString& sError);
+  bool path(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool producer(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool subject(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool title(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool zoom(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool zoomType(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+
+  bool addAnnot(IJS_Context* cc,
+                const std::vector<CJS_Value>& params,
+                CJS_Value& vRet,
+                CFX_WideString& sError);
+  bool addField(IJS_Context* cc,
+                const std::vector<CJS_Value>& params,
+                CJS_Value& vRet,
+                CFX_WideString& sError);
+  bool addLink(IJS_Context* cc,
+               const std::vector<CJS_Value>& params,
+               CJS_Value& vRet,
+               CFX_WideString& sError);
+  bool addIcon(IJS_Context* cc,
+               const std::vector<CJS_Value>& params,
+               CJS_Value& vRet,
+               CFX_WideString& sError);
+  bool calculateNow(IJS_Context* cc,
+                    const std::vector<CJS_Value>& params,
+                    CJS_Value& vRet,
+                    CFX_WideString& sError);
+  bool closeDoc(IJS_Context* cc,
+                const std::vector<CJS_Value>& params,
+                CJS_Value& vRet,
+                CFX_WideString& sError);
+  bool createDataObject(IJS_Context* cc,
+                        const std::vector<CJS_Value>& params,
+                        CJS_Value& vRet,
+                        CFX_WideString& sError);
+  bool deletePages(IJS_Context* cc,
+                   const std::vector<CJS_Value>& params,
+                   CJS_Value& vRet,
+                   CFX_WideString& sError);
+  bool exportAsText(IJS_Context* cc,
+                    const std::vector<CJS_Value>& params,
+                    CJS_Value& vRet,
+                    CFX_WideString& sError);
+  bool exportAsFDF(IJS_Context* cc,
+                   const std::vector<CJS_Value>& params,
+                   CJS_Value& vRet,
+                   CFX_WideString& sError);
+  bool exportAsXFDF(IJS_Context* cc,
+                    const std::vector<CJS_Value>& params,
+                    CJS_Value& vRet,
+                    CFX_WideString& sError);
+  bool extractPages(IJS_Context* cc,
+                    const std::vector<CJS_Value>& params,
+                    CJS_Value& vRet,
+                    CFX_WideString& sError);
+  bool getAnnot(IJS_Context* cc,
+                const std::vector<CJS_Value>& params,
+                CJS_Value& vRet,
+                CFX_WideString& sError);
+  bool getAnnots(IJS_Context* cc,
+                 const std::vector<CJS_Value>& params,
+                 CJS_Value& vRet,
+                 CFX_WideString& sError);
+  bool getAnnot3D(IJS_Context* cc,
+                  const std::vector<CJS_Value>& params,
+                  CJS_Value& vRet,
+                  CFX_WideString& sError);
+  bool getAnnots3D(IJS_Context* cc,
+                   const std::vector<CJS_Value>& params,
+                   CJS_Value& vRet,
+                   CFX_WideString& sError);
+  bool getField(IJS_Context* cc,
+                const std::vector<CJS_Value>& params,
+                CJS_Value& vRet,
+                CFX_WideString& sError);
+  bool getIcon(IJS_Context* cc,
+               const std::vector<CJS_Value>& params,
+               CJS_Value& vRet,
+               CFX_WideString& sError);
+  bool getLinks(IJS_Context* cc,
+                const std::vector<CJS_Value>& params,
+                CJS_Value& vRet,
+                CFX_WideString& sError);
+  bool getNthFieldName(IJS_Context* cc,
+                       const std::vector<CJS_Value>& params,
+                       CJS_Value& vRet,
+                       CFX_WideString& sError);
+  bool getOCGs(IJS_Context* cc,
+               const std::vector<CJS_Value>& params,
+               CJS_Value& vRet,
+               CFX_WideString& sError);
+  bool getPageBox(IJS_Context* cc,
+                  const std::vector<CJS_Value>& params,
+                  CJS_Value& vRet,
+                  CFX_WideString& sError);
+  bool getPageNthWord(IJS_Context* cc,
+                      const std::vector<CJS_Value>& params,
+                      CJS_Value& vRet,
+                      CFX_WideString& sError);
+  bool getPageNthWordQuads(IJS_Context* cc,
+                           const std::vector<CJS_Value>& params,
+                           CJS_Value& vRet,
+                           CFX_WideString& sError);
+  bool getPageNumWords(IJS_Context* cc,
+                       const std::vector<CJS_Value>& params,
+                       CJS_Value& vRet,
+                       CFX_WideString& sError);
+  bool getPrintParams(IJS_Context* cc,
+                      const std::vector<CJS_Value>& params,
+                      CJS_Value& vRet,
+                      CFX_WideString& sError);
+  bool getURL(IJS_Context* cc,
+              const std::vector<CJS_Value>& params,
+              CJS_Value& vRet,
+              CFX_WideString& sError);
+  bool gotoNamedDest(IJS_Context* cc,
+                     const std::vector<CJS_Value>& params,
+                     CJS_Value& vRet,
+                     CFX_WideString& sError);
+  bool importAnFDF(IJS_Context* cc,
+                   const std::vector<CJS_Value>& params,
+                   CJS_Value& vRet,
+                   CFX_WideString& sError);
+  bool importAnXFDF(IJS_Context* cc,
+                    const std::vector<CJS_Value>& params,
+                    CJS_Value& vRet,
+                    CFX_WideString& sError);
+  bool importTextData(IJS_Context* cc,
+                      const std::vector<CJS_Value>& params,
+                      CJS_Value& vRet,
+                      CFX_WideString& sError);
+  bool insertPages(IJS_Context* cc,
+                   const std::vector<CJS_Value>& params,
+                   CJS_Value& vRet,
+                   CFX_WideString& sError);
+  bool mailForm(IJS_Context* cc,
+                const std::vector<CJS_Value>& params,
+                CJS_Value& vRet,
+                CFX_WideString& sError);
+  bool print(IJS_Context* cc,
+             const std::vector<CJS_Value>& params,
+             CJS_Value& vRet,
+             CFX_WideString& sError);
+  bool removeField(IJS_Context* cc,
+                   const std::vector<CJS_Value>& params,
+                   CJS_Value& vRet,
+                   CFX_WideString& sError);
+  bool replacePages(IJS_Context* cc,
+                    const std::vector<CJS_Value>& params,
+                    CJS_Value& vRet,
+                    CFX_WideString& sError);
+  bool resetForm(IJS_Context* cc,
+                 const std::vector<CJS_Value>& params,
+                 CJS_Value& vRet,
+                 CFX_WideString& sError);
+  bool saveAs(IJS_Context* cc,
+              const std::vector<CJS_Value>& params,
+              CJS_Value& vRet,
+              CFX_WideString& sError);
+  bool submitForm(IJS_Context* cc,
+                  const std::vector<CJS_Value>& params,
+                  CJS_Value& vRet,
+                  CFX_WideString& sError);
+  bool syncAnnotScan(IJS_Context* cc,
+                     const std::vector<CJS_Value>& params,
+                     CJS_Value& vRet,
+                     CFX_WideString& sError);
+  bool mailDoc(IJS_Context* cc,
+               const std::vector<CJS_Value>& params,
+               CJS_Value& vRet,
+               CFX_WideString& sError);
+  bool removeIcon(IJS_Context* cc,
+                  const std::vector<CJS_Value>& params,
+                  CJS_Value& vRet,
+                  CFX_WideString& sError);
+  bool URL(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+
+  void SetFormFillEnv(CPDFSDK_FormFillEnvironment* pFormFillEnv);
+  CPDFSDK_FormFillEnvironment* GetFormFillEnv() const {
+    return m_pFormFillEnv.Get();
+  }
+  void AddDelayData(CJS_DelayData* pData);
+  void DoFieldDelay(const CFX_WideString& sFieldName, int nControlIndex);
+  CJS_Document* GetCJSDoc() const;
+
+ private:
+  bool IsEnclosedInRect(CFX_FloatRect rect, CFX_FloatRect LinkRect);
+  int CountWords(CPDF_TextObject* pTextObj);
+  CFX_WideString GetObjWordStr(CPDF_TextObject* pTextObj, int nWordIndex);
+
+  bool getPropertyInternal(IJS_Context* cc,
+                           CJS_PropValue& vp,
+                           const CFX_ByteString& propName,
+                           CFX_WideString& sError);
+
+  CPDFSDK_FormFillEnvironment::ObservedPtr m_pFormFillEnv;
+  CFX_WideString m_cwBaseURL;
+  std::list<std::unique_ptr<CJS_DelayData>> m_DelayData;
+  std::vector<std::unique_ptr<IconElement>> m_Icons;
+  bool m_bDelay;
+};
+
+class CJS_Document : public CJS_Object {
+ public:
+  explicit CJS_Document(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_Document() override {}
+
+  // CJS_Object
+  void InitInstance(IJS_Runtime* pIRuntime) override;
+
+  DECLARE_JS_CLASS();
+
+  JS_STATIC_PROP(ADBE, Document);
+  JS_STATIC_PROP(author, Document);
+  JS_STATIC_PROP(baseURL, Document);
+  JS_STATIC_PROP(bookmarkRoot, Document);
+  JS_STATIC_PROP(calculate, Document);
+  JS_STATIC_PROP(Collab, Document);
+  JS_STATIC_PROP(creationDate, Document);
+  JS_STATIC_PROP(creator, Document);
+  JS_STATIC_PROP(delay, Document);
+  JS_STATIC_PROP(dirty, Document);
+  JS_STATIC_PROP(documentFileName, Document);
+  JS_STATIC_PROP(external, Document);
+  JS_STATIC_PROP(filesize, Document);
+  JS_STATIC_PROP(icons, Document);
+  JS_STATIC_PROP(info, Document);
+  JS_STATIC_PROP(keywords, Document);
+  JS_STATIC_PROP(layout, Document);
+  JS_STATIC_PROP(media, Document);
+  JS_STATIC_PROP(modDate, Document);
+  JS_STATIC_PROP(mouseX, Document);
+  JS_STATIC_PROP(mouseY, Document);
+  JS_STATIC_PROP(numFields, Document);
+  JS_STATIC_PROP(numPages, Document);
+  JS_STATIC_PROP(pageNum, Document);
+  JS_STATIC_PROP(pageWindowRect, Document);
+  JS_STATIC_PROP(path, Document);
+  JS_STATIC_PROP(producer, Document);
+  JS_STATIC_PROP(subject, Document);
+  JS_STATIC_PROP(title, Document);
+  JS_STATIC_PROP(URL, Document);
+  JS_STATIC_PROP(zoom, Document);
+  JS_STATIC_PROP(zoomType, Document);
+
+  JS_STATIC_METHOD(addAnnot, Document);
+  JS_STATIC_METHOD(addField, Document);
+  JS_STATIC_METHOD(addLink, Document);
+  JS_STATIC_METHOD(addIcon, Document);
+  JS_STATIC_METHOD(calculateNow, Document);
+  JS_STATIC_METHOD(closeDoc, Document);
+  JS_STATIC_METHOD(createDataObject, Document);
+  JS_STATIC_METHOD(deletePages, Document);
+  JS_STATIC_METHOD(exportAsText, Document);
+  JS_STATIC_METHOD(exportAsFDF, Document);
+  JS_STATIC_METHOD(exportAsXFDF, Document);
+  JS_STATIC_METHOD(extractPages, Document);
+  JS_STATIC_METHOD(getAnnot, Document);
+  JS_STATIC_METHOD(getAnnots, Document);
+  JS_STATIC_METHOD(getAnnot3D, Document);
+  JS_STATIC_METHOD(getAnnots3D, Document);
+  JS_STATIC_METHOD(getField, Document);
+  JS_STATIC_METHOD(getIcon, Document);
+  JS_STATIC_METHOD(getLinks, Document);
+  JS_STATIC_METHOD(getNthFieldName, Document);
+  JS_STATIC_METHOD(getOCGs, Document);
+  JS_STATIC_METHOD(getPageBox, Document);
+  JS_STATIC_METHOD(getPageNthWord, Document);
+  JS_STATIC_METHOD(getPageNthWordQuads, Document);
+  JS_STATIC_METHOD(getPageNumWords, Document);
+  JS_STATIC_METHOD(getPrintParams, Document);
+  JS_STATIC_METHOD(getURL, Document);
+  JS_STATIC_METHOD(gotoNamedDest, Document);
+  JS_STATIC_METHOD(importAnFDF, Document);
+  JS_STATIC_METHOD(importAnXFDF, Document);
+  JS_STATIC_METHOD(importTextData, Document);
+  JS_STATIC_METHOD(insertPages, Document);
+  JS_STATIC_METHOD(mailForm, Document);
+  JS_STATIC_METHOD(print, Document);
+  JS_STATIC_METHOD(removeField, Document);
+  JS_STATIC_METHOD(replacePages, Document);
+  JS_STATIC_METHOD(removeIcon, Document);
+  JS_STATIC_METHOD(resetForm, Document);
+  JS_STATIC_METHOD(saveAs, Document);
+  JS_STATIC_METHOD(submitForm, Document);
+  JS_STATIC_METHOD(syncAnnotScan, Document);
+  JS_STATIC_METHOD(mailDoc, Document);
+};
+
+#endif  // FPDFSDK_JAVASCRIPT_DOCUMENT_H_
diff --git a/fpdfsdk/javascript/Field.cpp b/fpdfsdk/javascript/Field.cpp
new file mode 100644
index 0000000..e04cbd6
--- /dev/null
+++ b/fpdfsdk/javascript/Field.cpp
@@ -0,0 +1,3488 @@
+// 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
+
+#include "fpdfsdk/javascript/Field.h"
+
+#include <algorithm>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "core/fpdfapi/font/cpdf_font.h"
+#include "core/fpdfapi/page/cpdf_page.h"
+#include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfdoc/cpdf_interform.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/cpdfsdk_interform.h"
+#include "fpdfsdk/cpdfsdk_pageview.h"
+#include "fpdfsdk/cpdfsdk_widget.h"
+#include "fpdfsdk/javascript/Document.h"
+#include "fpdfsdk/javascript/Icon.h"
+#include "fpdfsdk/javascript/JS_Define.h"
+#include "fpdfsdk/javascript/JS_EventHandler.h"
+#include "fpdfsdk/javascript/JS_Object.h"
+#include "fpdfsdk/javascript/JS_Value.h"
+#include "fpdfsdk/javascript/PublicMethods.h"
+#include "fpdfsdk/javascript/cjs_context.h"
+#include "fpdfsdk/javascript/cjs_runtime.h"
+#include "fpdfsdk/javascript/color.h"
+
+namespace {
+
+bool SetWidgetDisplayStatus(CPDFSDK_Widget* pWidget, int value) {
+  if (!pWidget)
+    return false;
+
+  uint32_t dwFlag = pWidget->GetFlags();
+  switch (value) {
+    case 0:
+      dwFlag &= ~ANNOTFLAG_INVISIBLE;
+      dwFlag &= ~ANNOTFLAG_HIDDEN;
+      dwFlag &= ~ANNOTFLAG_NOVIEW;
+      dwFlag |= ANNOTFLAG_PRINT;
+      break;
+    case 1:
+      dwFlag &= ~ANNOTFLAG_INVISIBLE;
+      dwFlag &= ~ANNOTFLAG_NOVIEW;
+      dwFlag |= (ANNOTFLAG_HIDDEN | ANNOTFLAG_PRINT);
+      break;
+    case 2:
+      dwFlag &= ~ANNOTFLAG_INVISIBLE;
+      dwFlag &= ~ANNOTFLAG_PRINT;
+      dwFlag &= ~ANNOTFLAG_HIDDEN;
+      dwFlag &= ~ANNOTFLAG_NOVIEW;
+      break;
+    case 3:
+      dwFlag |= ANNOTFLAG_NOVIEW;
+      dwFlag |= ANNOTFLAG_PRINT;
+      dwFlag &= ~ANNOTFLAG_HIDDEN;
+      break;
+  }
+
+  if (dwFlag != pWidget->GetFlags()) {
+    pWidget->SetFlags(dwFlag);
+    return true;
+  }
+
+  return false;
+}
+
+}  // namespace
+
+BEGIN_JS_STATIC_CONST(CJS_Field)
+END_JS_STATIC_CONST()
+
+BEGIN_JS_STATIC_PROP(CJS_Field)
+JS_STATIC_PROP_ENTRY(alignment)
+JS_STATIC_PROP_ENTRY(borderStyle)
+JS_STATIC_PROP_ENTRY(buttonAlignX)
+JS_STATIC_PROP_ENTRY(buttonAlignY)
+JS_STATIC_PROP_ENTRY(buttonFitBounds)
+JS_STATIC_PROP_ENTRY(buttonPosition)
+JS_STATIC_PROP_ENTRY(buttonScaleHow)
+JS_STATIC_PROP_ENTRY(buttonScaleWhen)
+JS_STATIC_PROP_ENTRY(calcOrderIndex)
+JS_STATIC_PROP_ENTRY(charLimit)
+JS_STATIC_PROP_ENTRY(comb)
+JS_STATIC_PROP_ENTRY(commitOnSelChange)
+JS_STATIC_PROP_ENTRY(currentValueIndices)
+JS_STATIC_PROP_ENTRY(defaultStyle)
+JS_STATIC_PROP_ENTRY(defaultValue)
+JS_STATIC_PROP_ENTRY(doNotScroll)
+JS_STATIC_PROP_ENTRY(doNotSpellCheck)
+JS_STATIC_PROP_ENTRY(delay)
+JS_STATIC_PROP_ENTRY(display)
+JS_STATIC_PROP_ENTRY(doc)
+JS_STATIC_PROP_ENTRY(editable)
+JS_STATIC_PROP_ENTRY(exportValues)
+JS_STATIC_PROP_ENTRY(hidden)
+JS_STATIC_PROP_ENTRY(fileSelect)
+JS_STATIC_PROP_ENTRY(fillColor)
+JS_STATIC_PROP_ENTRY(lineWidth)
+JS_STATIC_PROP_ENTRY(highlight)
+JS_STATIC_PROP_ENTRY(multiline)
+JS_STATIC_PROP_ENTRY(multipleSelection)
+JS_STATIC_PROP_ENTRY(name)
+JS_STATIC_PROP_ENTRY(numItems)
+JS_STATIC_PROP_ENTRY(page)
+JS_STATIC_PROP_ENTRY(password)
+JS_STATIC_PROP_ENTRY(print)
+JS_STATIC_PROP_ENTRY(radiosInUnison)
+JS_STATIC_PROP_ENTRY(readonly)
+JS_STATIC_PROP_ENTRY(rect)
+JS_STATIC_PROP_ENTRY(required)
+JS_STATIC_PROP_ENTRY(richText)
+JS_STATIC_PROP_ENTRY(richValue)
+JS_STATIC_PROP_ENTRY(rotation)
+JS_STATIC_PROP_ENTRY(strokeColor)
+JS_STATIC_PROP_ENTRY(style)
+JS_STATIC_PROP_ENTRY(submitName)
+JS_STATIC_PROP_ENTRY(textColor)
+JS_STATIC_PROP_ENTRY(textFont)
+JS_STATIC_PROP_ENTRY(textSize)
+JS_STATIC_PROP_ENTRY(type)
+JS_STATIC_PROP_ENTRY(userName)
+JS_STATIC_PROP_ENTRY(value)
+JS_STATIC_PROP_ENTRY(valueAsString)
+JS_STATIC_PROP_ENTRY(source)
+END_JS_STATIC_PROP()
+
+BEGIN_JS_STATIC_METHOD(CJS_Field)
+JS_STATIC_METHOD_ENTRY(browseForFileToSubmit)
+JS_STATIC_METHOD_ENTRY(buttonGetCaption)
+JS_STATIC_METHOD_ENTRY(buttonGetIcon)
+JS_STATIC_METHOD_ENTRY(buttonImportIcon)
+JS_STATIC_METHOD_ENTRY(buttonSetCaption)
+JS_STATIC_METHOD_ENTRY(buttonSetIcon)
+JS_STATIC_METHOD_ENTRY(checkThisBox)
+JS_STATIC_METHOD_ENTRY(clearItems)
+JS_STATIC_METHOD_ENTRY(defaultIsChecked)
+JS_STATIC_METHOD_ENTRY(deleteItemAt)
+JS_STATIC_METHOD_ENTRY(getArray)
+JS_STATIC_METHOD_ENTRY(getItemAt)
+JS_STATIC_METHOD_ENTRY(getLock)
+JS_STATIC_METHOD_ENTRY(insertItemAt)
+JS_STATIC_METHOD_ENTRY(isBoxChecked)
+JS_STATIC_METHOD_ENTRY(isDefaultChecked)
+JS_STATIC_METHOD_ENTRY(setAction)
+JS_STATIC_METHOD_ENTRY(setFocus)
+JS_STATIC_METHOD_ENTRY(setItems)
+JS_STATIC_METHOD_ENTRY(setLock)
+JS_STATIC_METHOD_ENTRY(signatureGetModifications)
+JS_STATIC_METHOD_ENTRY(signatureGetSeedValue)
+JS_STATIC_METHOD_ENTRY(signatureInfo)
+JS_STATIC_METHOD_ENTRY(signatureSetSeedValue)
+JS_STATIC_METHOD_ENTRY(signatureSign)
+JS_STATIC_METHOD_ENTRY(signatureValidate)
+END_JS_STATIC_METHOD()
+
+IMPLEMENT_JS_CLASS(CJS_Field, Field)
+
+CJS_DelayData::CJS_DelayData(FIELD_PROP prop,
+                             int idx,
+                             const CFX_WideString& name)
+    : eProp(prop), nControlIndex(idx), sFieldName(name) {}
+
+CJS_DelayData::~CJS_DelayData() {}
+
+void CJS_Field::InitInstance(IJS_Runtime* pIRuntime) {
+}
+
+Field::Field(CJS_Object* pJSObject)
+    : CJS_EmbedObj(pJSObject),
+      m_pJSDoc(nullptr),
+      m_pFormFillEnv(nullptr),
+      m_nFormControlIndex(-1),
+      m_bCanSet(false),
+      m_bDelay(false) {}
+
+Field::~Field() {}
+
+// note: iControlNo = -1, means not a widget.
+void Field::ParseFieldName(const std::wstring& strFieldNameParsed,
+                           std::wstring& strFieldName,
+                           int& iControlNo) {
+  int iStart = strFieldNameParsed.find_last_of(L'.');
+  if (iStart == -1) {
+    strFieldName = strFieldNameParsed;
+    iControlNo = -1;
+    return;
+  }
+  std::wstring suffixal = strFieldNameParsed.substr(iStart + 1);
+  iControlNo = FXSYS_wtoi(suffixal.c_str());
+  if (iControlNo == 0) {
+    int iSpaceStart;
+    while ((iSpaceStart = suffixal.find_last_of(L" ")) != -1) {
+      suffixal.erase(iSpaceStart, 1);
+    }
+
+    if (suffixal.compare(L"0") != 0) {
+      strFieldName = strFieldNameParsed;
+      iControlNo = -1;
+      return;
+    }
+  }
+  strFieldName = strFieldNameParsed.substr(0, iStart);
+}
+
+bool Field::AttachField(Document* pDocument,
+                        const CFX_WideString& csFieldName) {
+  m_pJSDoc = pDocument;
+  m_pFormFillEnv.Reset(pDocument->GetFormFillEnv());
+  m_bCanSet = m_pFormFillEnv->GetPermissions(FPDFPERM_FILL_FORM) ||
+              m_pFormFillEnv->GetPermissions(FPDFPERM_ANNOT_FORM) ||
+              m_pFormFillEnv->GetPermissions(FPDFPERM_MODIFY);
+
+  CPDFSDK_InterForm* pRDInterForm = m_pFormFillEnv->GetInterForm();
+  CPDF_InterForm* pInterForm = pRDInterForm->GetInterForm();
+  CFX_WideString swFieldNameTemp = csFieldName;
+  swFieldNameTemp.Replace(L"..", L".");
+
+  if (pInterForm->CountFields(swFieldNameTemp) <= 0) {
+    std::wstring strFieldName;
+    int iControlNo = -1;
+    ParseFieldName(swFieldNameTemp.c_str(), strFieldName, iControlNo);
+    if (iControlNo == -1)
+      return false;
+
+    m_FieldName = strFieldName.c_str();
+    m_nFormControlIndex = iControlNo;
+    return true;
+  }
+
+  m_FieldName = swFieldNameTemp;
+  m_nFormControlIndex = -1;
+
+  return true;
+}
+
+std::vector<CPDF_FormField*> Field::GetFormFields(
+    CPDFSDK_FormFillEnvironment* pFormFillEnv,
+    const CFX_WideString& csFieldName) {
+  std::vector<CPDF_FormField*> fields;
+  CPDFSDK_InterForm* pReaderInterForm = pFormFillEnv->GetInterForm();
+  CPDF_InterForm* pInterForm = pReaderInterForm->GetInterForm();
+  for (int i = 0, sz = pInterForm->CountFields(csFieldName); i < sz; ++i) {
+    if (CPDF_FormField* pFormField = pInterForm->GetField(i, csFieldName))
+      fields.push_back(pFormField);
+  }
+  return fields;
+}
+
+std::vector<CPDF_FormField*> Field::GetFormFields(
+    const CFX_WideString& csFieldName) const {
+  return Field::GetFormFields(m_pFormFillEnv.Get(), csFieldName);
+}
+
+void Field::UpdateFormField(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                            CPDF_FormField* pFormField,
+                            bool bChangeMark,
+                            bool bResetAP,
+                            bool bRefresh) {
+  CPDFSDK_InterForm* pInterForm = pFormFillEnv->GetInterForm();
+
+  if (bResetAP) {
+    std::vector<CPDFSDK_Annot::ObservedPtr> widgets;
+    pInterForm->GetWidgets(pFormField, &widgets);
+
+    int nFieldType = pFormField->GetFieldType();
+    if (nFieldType == FIELDTYPE_COMBOBOX || nFieldType == FIELDTYPE_TEXTFIELD) {
+      for (auto& pObserved : widgets) {
+        if (pObserved) {
+          bool bFormatted = false;
+          CFX_WideString sValue = static_cast<CPDFSDK_Widget*>(pObserved.Get())
+                                      ->OnFormat(bFormatted);
+          if (pObserved) {  // Not redundant, may be clobbered by OnFormat.
+            static_cast<CPDFSDK_Widget*>(pObserved.Get())
+                ->ResetAppearance(bFormatted ? &sValue : nullptr, false);
+          }
+        }
+      }
+    } else {
+      for (auto& pObserved : widgets) {
+        if (pObserved) {
+          static_cast<CPDFSDK_Widget*>(pObserved.Get())
+              ->ResetAppearance(nullptr, false);
+        }
+      }
+    }
+  }
+
+  if (bRefresh) {
+    // Refresh the widget list. The calls in |bResetAP| may have caused widgets
+    // to be removed from the list. We need to call |GetWidgets| again to be
+    // sure none of the widgets have been deleted.
+    std::vector<CPDFSDK_Annot::ObservedPtr> widgets;
+    pInterForm->GetWidgets(pFormField, &widgets);
+
+    // TODO(dsinclair): Determine if all widgets share the same
+    // CPDFSDK_InterForm. If that's the case, we can move the code to
+    // |GetFormFillEnv| out of the loop.
+    for (auto& pObserved : widgets) {
+      if (pObserved) {
+        CPDFSDK_Widget* pWidget = static_cast<CPDFSDK_Widget*>(pObserved.Get());
+        pWidget->GetInterForm()->GetFormFillEnv()->UpdateAllViews(nullptr,
+                                                                  pWidget);
+      }
+    }
+  }
+
+  if (bChangeMark)
+    pFormFillEnv->SetChangeMark();
+}
+
+void Field::UpdateFormControl(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                              CPDF_FormControl* pFormControl,
+                              bool bChangeMark,
+                              bool bResetAP,
+                              bool bRefresh) {
+  ASSERT(pFormControl);
+
+  CPDFSDK_InterForm* pForm = pFormFillEnv->GetInterForm();
+  CPDFSDK_Widget* pWidget = pForm->GetWidget(pFormControl);
+
+  if (pWidget) {
+    if (bResetAP) {
+      int nFieldType = pWidget->GetFieldType();
+      if (nFieldType == FIELDTYPE_COMBOBOX ||
+          nFieldType == FIELDTYPE_TEXTFIELD) {
+        bool bFormatted = false;
+        CFX_WideString sValue = pWidget->OnFormat(bFormatted);
+        pWidget->ResetAppearance(bFormatted ? &sValue : nullptr, false);
+      } else {
+        pWidget->ResetAppearance(nullptr, false);
+      }
+    }
+
+    if (bRefresh) {
+      CPDFSDK_InterForm* pInterForm = pWidget->GetInterForm();
+      pInterForm->GetFormFillEnv()->UpdateAllViews(nullptr, pWidget);
+    }
+  }
+
+  if (bChangeMark)
+    pFormFillEnv->SetChangeMark();
+}
+
+CPDFSDK_Widget* Field::GetWidget(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                                 CPDF_FormControl* pFormControl) {
+  CPDFSDK_InterForm* pInterForm =
+      static_cast<CPDFSDK_InterForm*>(pFormFillEnv->GetInterForm());
+  return pInterForm ? pInterForm->GetWidget(pFormControl) : nullptr;
+}
+
+bool Field::ValueIsOccur(CPDF_FormField* pFormField,
+                         CFX_WideString csOptLabel) {
+  for (int i = 0, sz = pFormField->CountOptions(); i < sz; i++) {
+    if (csOptLabel.Compare(pFormField->GetOptionLabel(i)) == 0)
+      return true;
+  }
+
+  return false;
+}
+
+CPDF_FormControl* Field::GetSmartFieldControl(CPDF_FormField* pFormField) {
+  if (!pFormField->CountControls() ||
+      m_nFormControlIndex >= pFormField->CountControls())
+    return nullptr;
+
+  if (m_nFormControlIndex < 0)
+    return pFormField->GetControl(0);
+
+  return pFormField->GetControl(m_nFormControlIndex);
+}
+
+bool Field::alignment(IJS_Context* cc,
+                      CJS_PropValue& vp,
+                      CFX_WideString& sError) {
+  ASSERT(m_pFormFillEnv);
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    CFX_ByteString alignStr;
+    vp >> alignStr;
+
+    if (m_bDelay) {
+      AddDelay_String(FP_ALIGNMENT, alignStr);
+    } else {
+      Field::SetAlignment(m_pFormFillEnv.Get(), m_FieldName,
+                          m_nFormControlIndex, alignStr);
+    }
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD)
+      return false;
+
+    CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
+    if (!pFormControl)
+      return false;
+
+    switch (pFormControl->GetControlAlignment()) {
+      case 1:
+        vp << L"center";
+        break;
+      case 0:
+        vp << L"left";
+        break;
+      case 2:
+        vp << L"right";
+        break;
+      default:
+        vp << L"";
+    }
+  }
+
+  return true;
+}
+
+void Field::SetAlignment(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                         const CFX_WideString& swFieldName,
+                         int nControlIndex,
+                         const CFX_ByteString& string) {
+  // Not supported.
+}
+
+bool Field::borderStyle(IJS_Context* cc,
+                        CJS_PropValue& vp,
+                        CFX_WideString& sError) {
+  ASSERT(m_pFormFillEnv);
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    CFX_ByteString strType = "";
+    vp >> strType;
+
+    if (m_bDelay) {
+      AddDelay_String(FP_BORDERSTYLE, strType);
+    } else {
+      Field::SetBorderStyle(m_pFormFillEnv.Get(), m_FieldName,
+                            m_nFormControlIndex, strType);
+    }
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    if (!pFormField)
+      return false;
+
+    CPDFSDK_Widget* pWidget =
+        GetWidget(m_pFormFillEnv.Get(), GetSmartFieldControl(pFormField));
+    if (!pWidget)
+      return false;
+
+    switch (pWidget->GetBorderStyle()) {
+      case BorderStyle::SOLID:
+        vp << L"solid";
+        break;
+      case BorderStyle::DASH:
+        vp << L"dashed";
+        break;
+      case BorderStyle::BEVELED:
+        vp << L"beveled";
+        break;
+      case BorderStyle::INSET:
+        vp << L"inset";
+        break;
+      case BorderStyle::UNDERLINE:
+        vp << L"underline";
+        break;
+      default:
+        vp << L"";
+        break;
+    }
+  }
+
+  return true;
+}
+
+void Field::SetBorderStyle(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                           const CFX_WideString& swFieldName,
+                           int nControlIndex,
+                           const CFX_ByteString& string) {
+  ASSERT(pFormFillEnv);
+
+  BorderStyle nBorderStyle = BorderStyle::SOLID;
+  if (string == "solid")
+    nBorderStyle = BorderStyle::SOLID;
+  else if (string == "beveled")
+    nBorderStyle = BorderStyle::BEVELED;
+  else if (string == "dashed")
+    nBorderStyle = BorderStyle::DASH;
+  else if (string == "inset")
+    nBorderStyle = BorderStyle::INSET;
+  else if (string == "underline")
+    nBorderStyle = BorderStyle::UNDERLINE;
+  else
+    return;
+
+  std::vector<CPDF_FormField*> FieldArray =
+      GetFormFields(pFormFillEnv, swFieldName);
+  for (CPDF_FormField* pFormField : FieldArray) {
+    if (nControlIndex < 0) {
+      bool bSet = false;
+      for (int i = 0, sz = pFormField->CountControls(); i < sz; ++i) {
+        if (CPDFSDK_Widget* pWidget =
+                GetWidget(pFormFillEnv, pFormField->GetControl(i))) {
+          if (pWidget->GetBorderStyle() != nBorderStyle) {
+            pWidget->SetBorderStyle(nBorderStyle);
+            bSet = true;
+          }
+        }
+      }
+      if (bSet)
+        UpdateFormField(pFormFillEnv, pFormField, true, true, true);
+    } else {
+      if (nControlIndex >= pFormField->CountControls())
+        return;
+      if (CPDF_FormControl* pFormControl =
+              pFormField->GetControl(nControlIndex)) {
+        if (CPDFSDK_Widget* pWidget = GetWidget(pFormFillEnv, pFormControl)) {
+          if (pWidget->GetBorderStyle() != nBorderStyle) {
+            pWidget->SetBorderStyle(nBorderStyle);
+            UpdateFormControl(pFormFillEnv, pFormControl, true, true, true);
+          }
+        }
+      }
+    }
+  }
+}
+
+bool Field::buttonAlignX(IJS_Context* cc,
+                         CJS_PropValue& vp,
+                         CFX_WideString& sError) {
+  ASSERT(m_pFormFillEnv);
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    int nVP;
+    vp >> nVP;
+
+    if (m_bDelay) {
+      AddDelay_Int(FP_BUTTONALIGNX, nVP);
+    } else {
+      Field::SetButtonAlignX(m_pFormFillEnv.Get(), m_FieldName,
+                             m_nFormControlIndex, nVP);
+    }
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    if (pFormField->GetFieldType() != FIELDTYPE_PUSHBUTTON)
+      return false;
+
+    CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
+    if (!pFormControl)
+      return false;
+
+    CPDF_IconFit IconFit = pFormControl->GetIconFit();
+
+    FX_FLOAT fLeft, fBottom;
+    IconFit.GetIconPosition(fLeft, fBottom);
+
+    vp << (int32_t)fLeft;
+  }
+
+  return true;
+}
+
+void Field::SetButtonAlignX(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                            const CFX_WideString& swFieldName,
+                            int nControlIndex,
+                            int number) {
+  // Not supported.
+}
+
+bool Field::buttonAlignY(IJS_Context* cc,
+                         CJS_PropValue& vp,
+                         CFX_WideString& sError) {
+  ASSERT(m_pFormFillEnv);
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    int nVP;
+    vp >> nVP;
+
+    if (m_bDelay) {
+      AddDelay_Int(FP_BUTTONALIGNY, nVP);
+    } else {
+      Field::SetButtonAlignY(m_pFormFillEnv.Get(), m_FieldName,
+                             m_nFormControlIndex, nVP);
+    }
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    if (pFormField->GetFieldType() != FIELDTYPE_PUSHBUTTON)
+      return false;
+
+    CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
+    if (!pFormControl)
+      return false;
+
+    CPDF_IconFit IconFit = pFormControl->GetIconFit();
+
+    FX_FLOAT fLeft, fBottom;
+    IconFit.GetIconPosition(fLeft, fBottom);
+
+    vp << (int32_t)fBottom;
+  }
+
+  return true;
+}
+
+void Field::SetButtonAlignY(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                            const CFX_WideString& swFieldName,
+                            int nControlIndex,
+                            int number) {
+  // Not supported.
+}
+
+bool Field::buttonFitBounds(IJS_Context* cc,
+                            CJS_PropValue& vp,
+                            CFX_WideString& sError) {
+  ASSERT(m_pFormFillEnv);
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    bool bVP;
+    vp >> bVP;
+
+    if (m_bDelay) {
+      AddDelay_Bool(FP_BUTTONFITBOUNDS, bVP);
+    } else {
+      Field::SetButtonFitBounds(m_pFormFillEnv.Get(), m_FieldName,
+                                m_nFormControlIndex, bVP);
+    }
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    if (pFormField->GetFieldType() != FIELDTYPE_PUSHBUTTON)
+      return false;
+
+    CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
+    if (!pFormControl)
+      return false;
+
+    vp << pFormControl->GetIconFit().GetFittingBounds();
+  }
+
+  return true;
+}
+
+void Field::SetButtonFitBounds(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                               const CFX_WideString& swFieldName,
+                               int nControlIndex,
+                               bool b) {
+  // Not supported.
+}
+
+bool Field::buttonPosition(IJS_Context* cc,
+                           CJS_PropValue& vp,
+                           CFX_WideString& sError) {
+  ASSERT(m_pFormFillEnv);
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    int nVP;
+    vp >> nVP;
+
+    if (m_bDelay) {
+      AddDelay_Int(FP_BUTTONPOSITION, nVP);
+    } else {
+      Field::SetButtonPosition(m_pFormFillEnv.Get(), m_FieldName,
+                               m_nFormControlIndex, nVP);
+    }
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    if (pFormField->GetFieldType() != FIELDTYPE_PUSHBUTTON)
+      return false;
+
+    CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
+    if (!pFormControl)
+      return false;
+
+    vp << pFormControl->GetTextPosition();
+  }
+  return true;
+}
+
+void Field::SetButtonPosition(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                              const CFX_WideString& swFieldName,
+                              int nControlIndex,
+                              int number) {
+  // Not supported.
+}
+
+bool Field::buttonScaleHow(IJS_Context* cc,
+                           CJS_PropValue& vp,
+                           CFX_WideString& sError) {
+  ASSERT(m_pFormFillEnv);
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    int nVP;
+    vp >> nVP;
+
+    if (m_bDelay) {
+      AddDelay_Int(FP_BUTTONSCALEHOW, nVP);
+    } else {
+      Field::SetButtonScaleHow(m_pFormFillEnv.Get(), m_FieldName,
+                               m_nFormControlIndex, nVP);
+    }
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    if (pFormField->GetFieldType() != FIELDTYPE_PUSHBUTTON)
+      return false;
+
+    CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
+    if (!pFormControl)
+      return false;
+
+    CPDF_IconFit IconFit = pFormControl->GetIconFit();
+    if (IconFit.IsProportionalScale())
+      vp << (int32_t)0;
+    else
+      vp << (int32_t)1;
+  }
+
+  return true;
+}
+
+void Field::SetButtonScaleHow(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                              const CFX_WideString& swFieldName,
+                              int nControlIndex,
+                              int number) {
+  // Not supported.
+}
+
+bool Field::buttonScaleWhen(IJS_Context* cc,
+                            CJS_PropValue& vp,
+                            CFX_WideString& sError) {
+  ASSERT(m_pFormFillEnv);
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    int nVP;
+    vp >> nVP;
+
+    if (m_bDelay) {
+      AddDelay_Int(FP_BUTTONSCALEWHEN, nVP);
+    } else {
+      Field::SetButtonScaleWhen(m_pFormFillEnv.Get(), m_FieldName,
+                                m_nFormControlIndex, nVP);
+    }
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    if (pFormField->GetFieldType() != FIELDTYPE_PUSHBUTTON)
+      return false;
+
+    CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
+    if (!pFormControl)
+      return false;
+
+    CPDF_IconFit IconFit = pFormControl->GetIconFit();
+    int ScaleM = IconFit.GetScaleMethod();
+    switch (ScaleM) {
+      case CPDF_IconFit::Always:
+        vp << (int32_t)CPDF_IconFit::Always;
+        break;
+      case CPDF_IconFit::Bigger:
+        vp << (int32_t)CPDF_IconFit::Bigger;
+        break;
+      case CPDF_IconFit::Never:
+        vp << (int32_t)CPDF_IconFit::Never;
+        break;
+      case CPDF_IconFit::Smaller:
+        vp << (int32_t)CPDF_IconFit::Smaller;
+        break;
+    }
+  }
+
+  return true;
+}
+
+void Field::SetButtonScaleWhen(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                               const CFX_WideString& swFieldName,
+                               int nControlIndex,
+                               int number) {
+  // Not supported.
+}
+
+bool Field::calcOrderIndex(IJS_Context* cc,
+                           CJS_PropValue& vp,
+                           CFX_WideString& sError) {
+  ASSERT(m_pFormFillEnv);
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    int nVP;
+    vp >> nVP;
+
+    if (m_bDelay) {
+      AddDelay_Int(FP_CALCORDERINDEX, nVP);
+    } else {
+      Field::SetCalcOrderIndex(m_pFormFillEnv.Get(), m_FieldName,
+                               m_nFormControlIndex, nVP);
+    }
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    if (pFormField->GetFieldType() != FIELDTYPE_COMBOBOX &&
+        pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD) {
+      return false;
+    }
+
+    CPDFSDK_InterForm* pRDInterForm = m_pFormFillEnv->GetInterForm();
+    CPDF_InterForm* pInterForm = pRDInterForm->GetInterForm();
+    vp << (int32_t)pInterForm->FindFieldInCalculationOrder(pFormField);
+  }
+
+  return true;
+}
+
+void Field::SetCalcOrderIndex(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                              const CFX_WideString& swFieldName,
+                              int nControlIndex,
+                              int number) {
+  // Not supported.
+}
+
+bool Field::charLimit(IJS_Context* cc,
+                      CJS_PropValue& vp,
+                      CFX_WideString& sError) {
+  ASSERT(m_pFormFillEnv);
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    int nVP;
+    vp >> nVP;
+
+    if (m_bDelay) {
+      AddDelay_Int(FP_CHARLIMIT, nVP);
+    } else {
+      Field::SetCharLimit(m_pFormFillEnv.Get(), m_FieldName,
+                          m_nFormControlIndex, nVP);
+    }
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD)
+      return false;
+
+    vp << (int32_t)pFormField->GetMaxLen();
+  }
+  return true;
+}
+
+void Field::SetCharLimit(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                         const CFX_WideString& swFieldName,
+                         int nControlIndex,
+                         int number) {
+  // Not supported.
+}
+
+bool Field::comb(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
+  ASSERT(m_pFormFillEnv);
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    bool bVP;
+    vp >> bVP;
+
+    if (m_bDelay) {
+      AddDelay_Bool(FP_COMB, bVP);
+    } else {
+      Field::SetComb(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex,
+                     bVP);
+    }
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD)
+      return false;
+
+    if (pFormField->GetFieldFlags() & FIELDFLAG_COMB)
+      vp << true;
+    else
+      vp << false;
+  }
+
+  return true;
+}
+
+void Field::SetComb(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                    const CFX_WideString& swFieldName,
+                    int nControlIndex,
+                    bool b) {
+  // Not supported.
+}
+
+bool Field::commitOnSelChange(IJS_Context* cc,
+                              CJS_PropValue& vp,
+                              CFX_WideString& sError) {
+  ASSERT(m_pFormFillEnv);
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    bool bVP;
+    vp >> bVP;
+
+    if (m_bDelay) {
+      AddDelay_Bool(FP_COMMITONSELCHANGE, bVP);
+    } else {
+      Field::SetCommitOnSelChange(m_pFormFillEnv.Get(), m_FieldName,
+                                  m_nFormControlIndex, bVP);
+    }
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    if (pFormField->GetFieldType() != FIELDTYPE_COMBOBOX &&
+        pFormField->GetFieldType() != FIELDTYPE_LISTBOX) {
+      return false;
+    }
+
+    if (pFormField->GetFieldFlags() & FIELDFLAG_COMMITONSELCHANGE)
+      vp << true;
+    else
+      vp << false;
+  }
+
+  return true;
+}
+
+void Field::SetCommitOnSelChange(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                                 const CFX_WideString& swFieldName,
+                                 int nControlIndex,
+                                 bool b) {
+  // Not supported.
+}
+
+bool Field::currentValueIndices(IJS_Context* cc,
+                                CJS_PropValue& vp,
+                                CFX_WideString& sError) {
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    std::vector<uint32_t> array;
+    if (vp.GetJSValue()->GetType() == CJS_Value::VT_number) {
+      int iSelecting = 0;
+      vp >> iSelecting;
+      array.push_back(iSelecting);
+    } else if (vp.GetJSValue()->IsArrayObject()) {
+      CJS_Array SelArray;
+      CJS_Value SelValue(pRuntime);
+      int iSelecting;
+      vp >> SelArray;
+      for (int i = 0, sz = SelArray.GetLength(pRuntime); i < sz; i++) {
+        SelArray.GetElement(pRuntime, i, SelValue);
+        iSelecting = SelValue.ToInt(pRuntime);
+        array.push_back(iSelecting);
+      }
+    }
+
+    if (m_bDelay) {
+      AddDelay_WordArray(FP_CURRENTVALUEINDICES, array);
+    } else {
+      Field::SetCurrentValueIndices(m_pFormFillEnv.Get(), m_FieldName,
+                                    m_nFormControlIndex, array);
+    }
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    if (pFormField->GetFieldType() != FIELDTYPE_COMBOBOX &&
+        pFormField->GetFieldType() != FIELDTYPE_LISTBOX) {
+      return false;
+    }
+
+    if (pFormField->CountSelectedItems() == 1) {
+      vp << pFormField->GetSelectedIndex(0);
+    } else if (pFormField->CountSelectedItems() > 1) {
+      CJS_Array SelArray;
+      for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz; i++) {
+        SelArray.SetElement(
+            pRuntime, i, CJS_Value(pRuntime, pFormField->GetSelectedIndex(i)));
+      }
+      vp << SelArray;
+    } else {
+      vp << -1;
+    }
+  }
+
+  return true;
+}
+
+void Field::SetCurrentValueIndices(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                                   const CFX_WideString& swFieldName,
+                                   int nControlIndex,
+                                   const std::vector<uint32_t>& array) {
+  ASSERT(pFormFillEnv);
+  std::vector<CPDF_FormField*> FieldArray =
+      GetFormFields(pFormFillEnv, swFieldName);
+
+  for (CPDF_FormField* pFormField : FieldArray) {
+    int nFieldType = pFormField->GetFieldType();
+    if (nFieldType == FIELDTYPE_COMBOBOX || nFieldType == FIELDTYPE_LISTBOX) {
+      uint32_t dwFieldFlags = pFormField->GetFieldFlags();
+      pFormField->ClearSelection(true);
+      for (size_t i = 0; i < array.size(); ++i) {
+        if (i != 0 && !(dwFieldFlags & (1 << 21)))
+          break;
+        if (array[i] < static_cast<uint32_t>(pFormField->CountOptions()) &&
+            !pFormField->IsItemSelected(array[i])) {
+          pFormField->SetItemSelection(array[i], true);
+        }
+      }
+      UpdateFormField(pFormFillEnv, pFormField, true, true, true);
+    }
+  }
+}
+
+bool Field::defaultStyle(IJS_Context* cc,
+                         CJS_PropValue& vp,
+                         CFX_WideString& sError) {
+  return false;
+}
+
+void Field::SetDefaultStyle(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                            const CFX_WideString& swFieldName,
+                            int nControlIndex) {
+  // Not supported.
+}
+
+bool Field::defaultValue(IJS_Context* cc,
+                         CJS_PropValue& vp,
+                         CFX_WideString& sError) {
+  ASSERT(m_pFormFillEnv);
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    CFX_WideString WideStr;
+    vp >> WideStr;
+
+    if (m_bDelay) {
+      AddDelay_WideString(FP_DEFAULTVALUE, WideStr);
+    } else {
+      Field::SetDefaultValue(m_pFormFillEnv.Get(), m_FieldName,
+                             m_nFormControlIndex, WideStr);
+    }
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    if (pFormField->GetFieldType() == FIELDTYPE_PUSHBUTTON ||
+        pFormField->GetFieldType() == FIELDTYPE_SIGNATURE) {
+      return false;
+    }
+
+    vp << pFormField->GetDefaultValue();
+  }
+  return true;
+}
+
+void Field::SetDefaultValue(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                            const CFX_WideString& swFieldName,
+                            int nControlIndex,
+                            const CFX_WideString& string) {
+  // Not supported.
+}
+
+bool Field::doNotScroll(IJS_Context* cc,
+                        CJS_PropValue& vp,
+                        CFX_WideString& sError) {
+  ASSERT(m_pFormFillEnv);
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    bool bVP;
+    vp >> bVP;
+
+    if (m_bDelay) {
+      AddDelay_Bool(FP_DONOTSCROLL, bVP);
+    } else {
+      Field::SetDoNotScroll(m_pFormFillEnv.Get(), m_FieldName,
+                            m_nFormControlIndex, bVP);
+    }
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD)
+      return false;
+
+    if (pFormField->GetFieldFlags() & FIELDFLAG_DONOTSCROLL)
+      vp << true;
+    else
+      vp << false;
+  }
+
+  return true;
+}
+
+void Field::SetDoNotScroll(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                           const CFX_WideString& swFieldName,
+                           int nControlIndex,
+                           bool b) {
+  // Not supported.
+}
+
+bool Field::doNotSpellCheck(IJS_Context* cc,
+                            CJS_PropValue& vp,
+                            CFX_WideString& sError) {
+  ASSERT(m_pFormFillEnv);
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    bool bVP;
+    vp >> bVP;
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD &&
+        pFormField->GetFieldType() != FIELDTYPE_COMBOBOX) {
+      return false;
+    }
+
+    if (pFormField->GetFieldFlags() & FIELDFLAG_DONOTSPELLCHECK)
+      vp << true;
+    else
+      vp << false;
+  }
+
+  return true;
+}
+
+void Field::SetDelay(bool bDelay) {
+  m_bDelay = bDelay;
+
+  if (!m_bDelay) {
+    if (m_pJSDoc)
+      m_pJSDoc->DoFieldDelay(m_FieldName, m_nFormControlIndex);
+  }
+}
+
+bool Field::delay(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    bool bVP;
+    vp >> bVP;
+
+    SetDelay(bVP);
+  } else {
+    vp << m_bDelay;
+  }
+  return true;
+}
+
+bool Field::display(IJS_Context* cc,
+                    CJS_PropValue& vp,
+                    CFX_WideString& sError) {
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    int nVP;
+    vp >> nVP;
+
+    if (m_bDelay) {
+      AddDelay_Int(FP_DISPLAY, nVP);
+    } else {
+      Field::SetDisplay(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex,
+                        nVP);
+    }
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    ASSERT(pFormField);
+    CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm();
+    CPDFSDK_Widget* pWidget =
+        pInterForm->GetWidget(GetSmartFieldControl(pFormField));
+    if (!pWidget)
+      return false;
+
+    uint32_t dwFlag = pWidget->GetFlags();
+
+    if (ANNOTFLAG_INVISIBLE & dwFlag || ANNOTFLAG_HIDDEN & dwFlag) {
+      vp << (int32_t)1;
+    } else {
+      if (ANNOTFLAG_PRINT & dwFlag) {
+        if (ANNOTFLAG_NOVIEW & dwFlag) {
+          vp << (int32_t)3;
+        } else {
+          vp << (int32_t)0;
+        }
+      } else {
+        vp << (int32_t)2;
+      }
+    }
+  }
+
+  return true;
+}
+
+void Field::SetDisplay(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                       const CFX_WideString& swFieldName,
+                       int nControlIndex,
+                       int number) {
+  CPDFSDK_InterForm* pInterForm = pFormFillEnv->GetInterForm();
+  std::vector<CPDF_FormField*> FieldArray =
+      GetFormFields(pFormFillEnv, swFieldName);
+  for (CPDF_FormField* pFormField : FieldArray) {
+    if (nControlIndex < 0) {
+      bool bAnySet = false;
+      for (int i = 0, sz = pFormField->CountControls(); i < sz; ++i) {
+        CPDF_FormControl* pFormControl = pFormField->GetControl(i);
+        ASSERT(pFormControl);
+
+        CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormControl);
+        if (SetWidgetDisplayStatus(pWidget, number))
+          bAnySet = true;
+      }
+
+      if (bAnySet)
+        UpdateFormField(pFormFillEnv, pFormField, true, false, true);
+    } else {
+      if (nControlIndex >= pFormField->CountControls())
+        return;
+
+      CPDF_FormControl* pFormControl = pFormField->GetControl(nControlIndex);
+      if (!pFormControl)
+        return;
+
+      CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormControl);
+      if (SetWidgetDisplayStatus(pWidget, number))
+        UpdateFormControl(pFormFillEnv, pFormControl, true, false, true);
+    }
+  }
+}
+
+bool Field::doc(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
+  if (!vp.IsGetting()) {
+    return false;
+  }
+  vp << m_pJSDoc->GetCJSDoc();
+  return true;
+}
+
+bool Field::editable(IJS_Context* cc,
+                     CJS_PropValue& vp,
+                     CFX_WideString& sError) {
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    bool bVP;
+    vp >> bVP;
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    if (pFormField->GetFieldType() != FIELDTYPE_COMBOBOX)
+      return false;
+
+    if (pFormField->GetFieldFlags() & FIELDFLAG_EDIT)
+      vp << true;
+    else
+      vp << false;
+  }
+
+  return true;
+}
+
+bool Field::exportValues(IJS_Context* cc,
+                         CJS_PropValue& vp,
+                         CFX_WideString& sError) {
+  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+  if (FieldArray.empty())
+    return false;
+
+  CPDF_FormField* pFormField = FieldArray[0];
+  if (pFormField->GetFieldType() != FIELDTYPE_CHECKBOX &&
+      pFormField->GetFieldType() != FIELDTYPE_RADIOBUTTON) {
+    return false;
+  }
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    if (!vp.GetJSValue()->IsArrayObject())
+      return false;
+  } else {
+    CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+    CJS_Array ExportValusArray;
+    if (m_nFormControlIndex < 0) {
+      for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
+        CPDF_FormControl* pFormControl = pFormField->GetControl(i);
+        ExportValusArray.SetElement(
+            pRuntime, i,
+            CJS_Value(pRuntime, pFormControl->GetExportValue().c_str()));
+      }
+    } else {
+      if (m_nFormControlIndex >= pFormField->CountControls())
+        return false;
+
+      CPDF_FormControl* pFormControl =
+          pFormField->GetControl(m_nFormControlIndex);
+      if (!pFormControl)
+        return false;
+
+      ExportValusArray.SetElement(
+          pRuntime, 0,
+          CJS_Value(pRuntime, pFormControl->GetExportValue().c_str()));
+    }
+    vp << ExportValusArray;
+  }
+  return true;
+}
+
+bool Field::fileSelect(IJS_Context* cc,
+                       CJS_PropValue& vp,
+                       CFX_WideString& sError) {
+  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+  if (FieldArray.empty())
+    return false;
+
+  CPDF_FormField* pFormField = FieldArray[0];
+  if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD)
+    return false;
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    bool bVP;
+    vp >> bVP;
+  } else {
+    if (pFormField->GetFieldFlags() & FIELDFLAG_FILESELECT)
+      vp << true;
+    else
+      vp << false;
+  }
+  return true;
+}
+
+bool Field::fillColor(IJS_Context* cc,
+                      CJS_PropValue& vp,
+                      CFX_WideString& sError) {
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  CJS_Array crArray;
+  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+  if (FieldArray.empty())
+    return false;
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    if (!vp.GetJSValue()->IsArrayObject())
+      return false;
+
+    vp >> crArray;
+
+    CPWL_Color color;
+    color::ConvertArrayToPWLColor(pRuntime, crArray, &color);
+    if (m_bDelay) {
+      AddDelay_Color(FP_FILLCOLOR, color);
+    } else {
+      Field::SetFillColor(m_pFormFillEnv.Get(), m_FieldName,
+                          m_nFormControlIndex, color);
+    }
+  } else {
+    CPDF_FormField* pFormField = FieldArray[0];
+    ASSERT(pFormField);
+    CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
+    if (!pFormControl)
+      return false;
+
+    int iColorType;
+    pFormControl->GetBackgroundColor(iColorType);
+
+    CPWL_Color color;
+    if (iColorType == COLORTYPE_TRANSPARENT) {
+      color = CPWL_Color(COLORTYPE_TRANSPARENT);
+    } else if (iColorType == COLORTYPE_GRAY) {
+      color = CPWL_Color(COLORTYPE_GRAY,
+                         pFormControl->GetOriginalBackgroundColor(0));
+    } else if (iColorType == COLORTYPE_RGB) {
+      color =
+          CPWL_Color(COLORTYPE_RGB, pFormControl->GetOriginalBackgroundColor(0),
+                     pFormControl->GetOriginalBackgroundColor(1),
+                     pFormControl->GetOriginalBackgroundColor(2));
+    } else if (iColorType == COLORTYPE_CMYK) {
+      color = CPWL_Color(COLORTYPE_CMYK,
+                         pFormControl->GetOriginalBackgroundColor(0),
+                         pFormControl->GetOriginalBackgroundColor(1),
+                         pFormControl->GetOriginalBackgroundColor(2),
+                         pFormControl->GetOriginalBackgroundColor(3));
+    } else {
+      return false;
+    }
+
+    color::ConvertPWLColorToArray(pRuntime, color, &crArray);
+    vp << crArray;
+  }
+
+  return true;
+}
+
+void Field::SetFillColor(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                         const CFX_WideString& swFieldName,
+                         int nControlIndex,
+                         const CPWL_Color& color) {
+  // Not supported.
+}
+
+bool Field::hidden(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    bool bVP;
+    vp >> bVP;
+
+    if (m_bDelay) {
+      AddDelay_Bool(FP_HIDDEN, bVP);
+    } else {
+      Field::SetHidden(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex,
+                       bVP);
+    }
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    ASSERT(pFormField);
+    CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm();
+    CPDFSDK_Widget* pWidget =
+        pInterForm->GetWidget(GetSmartFieldControl(pFormField));
+    if (!pWidget)
+      return false;
+
+    uint32_t dwFlags = pWidget->GetFlags();
+
+    if (ANNOTFLAG_INVISIBLE & dwFlags || ANNOTFLAG_HIDDEN & dwFlags)
+      vp << true;
+    else
+      vp << false;
+  }
+
+  return true;
+}
+
+void Field::SetHidden(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                      const CFX_WideString& swFieldName,
+                      int nControlIndex,
+                      bool b) {
+  int display = b ? 1 /*Hidden*/ : 0 /*Visible*/;
+  SetDisplay(pFormFillEnv, swFieldName, nControlIndex, display);
+}
+
+bool Field::highlight(IJS_Context* cc,
+                      CJS_PropValue& vp,
+                      CFX_WideString& sError) {
+  ASSERT(m_pFormFillEnv);
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    CFX_ByteString strMode;
+    vp >> strMode;
+
+    if (m_bDelay) {
+      AddDelay_String(FP_HIGHLIGHT, strMode);
+    } else {
+      Field::SetHighlight(m_pFormFillEnv.Get(), m_FieldName,
+                          m_nFormControlIndex, strMode);
+    }
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    if (pFormField->GetFieldType() != FIELDTYPE_PUSHBUTTON)
+      return false;
+
+    CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
+    if (!pFormControl)
+      return false;
+
+    int eHM = pFormControl->GetHighlightingMode();
+    switch (eHM) {
+      case CPDF_FormControl::None:
+        vp << L"none";
+        break;
+      case CPDF_FormControl::Push:
+        vp << L"push";
+        break;
+      case CPDF_FormControl::Invert:
+        vp << L"invert";
+        break;
+      case CPDF_FormControl::Outline:
+        vp << L"outline";
+        break;
+      case CPDF_FormControl::Toggle:
+        vp << L"toggle";
+        break;
+    }
+  }
+
+  return true;
+}
+
+void Field::SetHighlight(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                         const CFX_WideString& swFieldName,
+                         int nControlIndex,
+                         const CFX_ByteString& string) {
+  // Not supported.
+}
+
+bool Field::lineWidth(IJS_Context* cc,
+                      CJS_PropValue& vp,
+                      CFX_WideString& sError) {
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    int iWidth;
+    vp >> iWidth;
+
+    if (m_bDelay) {
+      AddDelay_Int(FP_LINEWIDTH, iWidth);
+    } else {
+      Field::SetLineWidth(m_pFormFillEnv.Get(), m_FieldName,
+                          m_nFormControlIndex, iWidth);
+    }
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    ASSERT(pFormField);
+    CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
+    if (!pFormControl)
+      return false;
+
+    CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm();
+    if (!pFormField->CountControls())
+      return false;
+
+    CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormField->GetControl(0));
+    if (!pWidget)
+      return false;
+
+    vp << (int32_t)pWidget->GetBorderWidth();
+  }
+
+  return true;
+}
+
+void Field::SetLineWidth(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                         const CFX_WideString& swFieldName,
+                         int nControlIndex,
+                         int number) {
+  CPDFSDK_InterForm* pInterForm = pFormFillEnv->GetInterForm();
+  std::vector<CPDF_FormField*> FieldArray =
+      GetFormFields(pFormFillEnv, swFieldName);
+  for (CPDF_FormField* pFormField : FieldArray) {
+    if (nControlIndex < 0) {
+      bool bSet = false;
+      for (int i = 0, sz = pFormField->CountControls(); i < sz; ++i) {
+        CPDF_FormControl* pFormControl = pFormField->GetControl(i);
+        ASSERT(pFormControl);
+
+        if (CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormControl)) {
+          if (number != pWidget->GetBorderWidth()) {
+            pWidget->SetBorderWidth(number);
+            bSet = true;
+          }
+        }
+      }
+      if (bSet)
+        UpdateFormField(pFormFillEnv, pFormField, true, true, true);
+    } else {
+      if (nControlIndex >= pFormField->CountControls())
+        return;
+      if (CPDF_FormControl* pFormControl =
+              pFormField->GetControl(nControlIndex)) {
+        if (CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormControl)) {
+          if (number != pWidget->GetBorderWidth()) {
+            pWidget->SetBorderWidth(number);
+            UpdateFormControl(pFormFillEnv, pFormControl, true, true, true);
+          }
+        }
+      }
+    }
+  }
+}
+
+bool Field::multiline(IJS_Context* cc,
+                      CJS_PropValue& vp,
+                      CFX_WideString& sError) {
+  ASSERT(m_pFormFillEnv);
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    bool bVP;
+    vp >> bVP;
+
+    if (m_bDelay) {
+      AddDelay_Bool(FP_MULTILINE, bVP);
+    } else {
+      Field::SetMultiline(m_pFormFillEnv.Get(), m_FieldName,
+                          m_nFormControlIndex, bVP);
+    }
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD)
+      return false;
+
+    if (pFormField->GetFieldFlags() & FIELDFLAG_MULTILINE)
+      vp << true;
+    else
+      vp << false;
+  }
+
+  return true;
+}
+
+void Field::SetMultiline(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                         const CFX_WideString& swFieldName,
+                         int nControlIndex,
+                         bool b) {
+  // Not supported.
+}
+
+bool Field::multipleSelection(IJS_Context* cc,
+                              CJS_PropValue& vp,
+                              CFX_WideString& sError) {
+  ASSERT(m_pFormFillEnv);
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    bool bVP;
+    vp >> bVP;
+
+    if (m_bDelay) {
+      AddDelay_Bool(FP_MULTIPLESELECTION, bVP);
+    } else {
+      Field::SetMultipleSelection(m_pFormFillEnv.Get(), m_FieldName,
+                                  m_nFormControlIndex, bVP);
+    }
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    if (pFormField->GetFieldType() != FIELDTYPE_LISTBOX)
+      return false;
+
+    if (pFormField->GetFieldFlags() & FIELDFLAG_MULTISELECT)
+      vp << true;
+    else
+      vp << false;
+  }
+
+  return true;
+}
+
+void Field::SetMultipleSelection(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                                 const CFX_WideString& swFieldName,
+                                 int nControlIndex,
+                                 bool b) {
+  // Not supported.
+}
+
+bool Field::name(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
+  if (!vp.IsGetting())
+    return false;
+
+  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+  if (FieldArray.empty())
+    return false;
+
+  vp << m_FieldName;
+
+  return true;
+}
+
+bool Field::numItems(IJS_Context* cc,
+                     CJS_PropValue& vp,
+                     CFX_WideString& sError) {
+  if (!vp.IsGetting())
+    return false;
+
+  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+  if (FieldArray.empty())
+    return false;
+
+  CPDF_FormField* pFormField = FieldArray[0];
+  if (pFormField->GetFieldType() != FIELDTYPE_COMBOBOX &&
+      pFormField->GetFieldType() != FIELDTYPE_LISTBOX) {
+    return false;
+  }
+
+  vp << (int32_t)pFormField->CountOptions();
+  return true;
+}
+
+bool Field::page(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
+  if (!vp.IsGetting()) {
+    sError = JSGetStringFromID(IDS_STRING_JSREADONLY);
+    return false;
+  }
+
+  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+  if (FieldArray.empty())
+    return false;
+
+  CPDF_FormField* pFormField = FieldArray[0];
+  if (!pFormField)
+    return false;
+
+  std::vector<CPDFSDK_Annot::ObservedPtr> widgets;
+  m_pFormFillEnv->GetInterForm()->GetWidgets(pFormField, &widgets);
+  if (widgets.empty()) {
+    vp << (int32_t)-1;
+    return true;
+  }
+
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  CJS_Array PageArray;
+  int i = 0;
+  for (const auto& pObserved : widgets) {
+    if (!pObserved) {
+      sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT);
+      return false;
+    }
+
+    auto pWidget = static_cast<CPDFSDK_Widget*>(pObserved.Get());
+    CPDFSDK_PageView* pPageView = pWidget->GetPageView();
+    if (!pPageView)
+      return false;
+
+    PageArray.SetElement(
+        pRuntime, i, CJS_Value(pRuntime, (int32_t)pPageView->GetPageIndex()));
+    ++i;
+  }
+
+  vp << PageArray;
+  return true;
+}
+
+bool Field::password(IJS_Context* cc,
+                     CJS_PropValue& vp,
+                     CFX_WideString& sError) {
+  ASSERT(m_pFormFillEnv);
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    bool bVP;
+    vp >> bVP;
+
+    if (m_bDelay) {
+      AddDelay_Bool(FP_PASSWORD, bVP);
+    } else {
+      Field::SetPassword(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex,
+                         bVP);
+    }
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD)
+      return false;
+
+    if (pFormField->GetFieldFlags() & FIELDFLAG_PASSWORD)
+      vp << true;
+    else
+      vp << false;
+  }
+
+  return true;
+}
+
+void Field::SetPassword(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                        const CFX_WideString& swFieldName,
+                        int nControlIndex,
+                        bool b) {
+  // Not supported.
+}
+
+bool Field::print(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
+  CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm();
+  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+  if (FieldArray.empty())
+    return false;
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    bool bVP;
+    vp >> bVP;
+
+    for (CPDF_FormField* pFormField : FieldArray) {
+      if (m_nFormControlIndex < 0) {
+        bool bSet = false;
+        for (int i = 0, sz = pFormField->CountControls(); i < sz; ++i) {
+          if (CPDFSDK_Widget* pWidget =
+                  pInterForm->GetWidget(pFormField->GetControl(i))) {
+            uint32_t dwFlags = pWidget->GetFlags();
+            if (bVP)
+              dwFlags |= ANNOTFLAG_PRINT;
+            else
+              dwFlags &= ~ANNOTFLAG_PRINT;
+
+            if (dwFlags != pWidget->GetFlags()) {
+              pWidget->SetFlags(dwFlags);
+              bSet = true;
+            }
+          }
+        }
+
+        if (bSet)
+          UpdateFormField(m_pFormFillEnv.Get(), pFormField, true, false, true);
+      } else {
+        if (m_nFormControlIndex >= pFormField->CountControls())
+          return false;
+        if (CPDF_FormControl* pFormControl =
+                pFormField->GetControl(m_nFormControlIndex)) {
+          if (CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormControl)) {
+            uint32_t dwFlags = pWidget->GetFlags();
+            if (bVP)
+              dwFlags |= ANNOTFLAG_PRINT;
+            else
+              dwFlags &= ~ANNOTFLAG_PRINT;
+
+            if (dwFlags != pWidget->GetFlags()) {
+              pWidget->SetFlags(dwFlags);
+              UpdateFormControl(m_pFormFillEnv.Get(),
+                                pFormField->GetControl(m_nFormControlIndex),
+                                true, false, true);
+            }
+          }
+        }
+      }
+    }
+  } else {
+    CPDF_FormField* pFormField = FieldArray[0];
+    CPDFSDK_Widget* pWidget =
+        pInterForm->GetWidget(GetSmartFieldControl(pFormField));
+    if (!pWidget)
+      return false;
+
+    if (pWidget->GetFlags() & ANNOTFLAG_PRINT)
+      vp << true;
+    else
+      vp << false;
+  }
+
+  return true;
+}
+
+bool Field::radiosInUnison(IJS_Context* cc,
+                           CJS_PropValue& vp,
+                           CFX_WideString& sError) {
+  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+  if (FieldArray.empty())
+    return false;
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    bool bVP;
+    vp >> bVP;
+
+  } else {
+    CPDF_FormField* pFormField = FieldArray[0];
+    if (pFormField->GetFieldType() != FIELDTYPE_RADIOBUTTON)
+      return false;
+
+    if (pFormField->GetFieldFlags() & FIELDFLAG_RADIOSINUNISON)
+      vp << true;
+    else
+      vp << false;
+  }
+
+  return true;
+}
+
+bool Field::readonly(IJS_Context* cc,
+                     CJS_PropValue& vp,
+                     CFX_WideString& sError) {
+  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+  if (FieldArray.empty())
+    return false;
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    bool bVP;
+    vp >> bVP;
+
+  } else {
+    CPDF_FormField* pFormField = FieldArray[0];
+    if (pFormField->GetFieldFlags() & FIELDFLAG_READONLY)
+      vp << true;
+    else
+      vp << false;
+  }
+
+  return true;
+}
+
+bool Field::rect(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  CJS_Value Upper_Leftx(pRuntime);
+  CJS_Value Upper_Lefty(pRuntime);
+  CJS_Value Lower_Rightx(pRuntime);
+  CJS_Value Lower_Righty(pRuntime);
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+    if (!vp.GetJSValue()->IsArrayObject())
+      return false;
+
+    CJS_Array rcArray;
+    vp >> rcArray;
+    rcArray.GetElement(pRuntime, 0, Upper_Leftx);
+    rcArray.GetElement(pRuntime, 1, Upper_Lefty);
+    rcArray.GetElement(pRuntime, 2, Lower_Rightx);
+    rcArray.GetElement(pRuntime, 3, Lower_Righty);
+
+    FX_FLOAT pArray[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+    pArray[0] = static_cast<FX_FLOAT>(Upper_Leftx.ToInt(pRuntime));
+    pArray[1] = static_cast<FX_FLOAT>(Lower_Righty.ToInt(pRuntime));
+    pArray[2] = static_cast<FX_FLOAT>(Lower_Rightx.ToInt(pRuntime));
+    pArray[3] = static_cast<FX_FLOAT>(Upper_Lefty.ToInt(pRuntime));
+
+    CFX_FloatRect crRect(pArray);
+    if (m_bDelay) {
+      AddDelay_Rect(FP_RECT, crRect);
+    } else {
+      Field::SetRect(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex,
+                     crRect);
+    }
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm();
+    CPDFSDK_Widget* pWidget =
+        pInterForm->GetWidget(GetSmartFieldControl(pFormField));
+    if (!pWidget)
+      return false;
+
+    CFX_FloatRect crRect = pWidget->GetRect();
+    Upper_Leftx = CJS_Value(pRuntime, static_cast<int32_t>(crRect.left));
+    Upper_Lefty = CJS_Value(pRuntime, static_cast<int32_t>(crRect.top));
+    Lower_Rightx = CJS_Value(pRuntime, static_cast<int32_t>(crRect.right));
+    Lower_Righty = CJS_Value(pRuntime, static_cast<int32_t>(crRect.bottom));
+
+    CJS_Array rcArray;
+    rcArray.SetElement(pRuntime, 0, Upper_Leftx);
+    rcArray.SetElement(pRuntime, 1, Upper_Lefty);
+    rcArray.SetElement(pRuntime, 2, Lower_Rightx);
+    rcArray.SetElement(pRuntime, 3, Lower_Righty);
+    vp << rcArray;
+  }
+  return true;
+}
+
+void Field::SetRect(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                    const CFX_WideString& swFieldName,
+                    int nControlIndex,
+                    const CFX_FloatRect& rect) {
+  CPDFSDK_InterForm* pInterForm = pFormFillEnv->GetInterForm();
+  std::vector<CPDF_FormField*> FieldArray =
+      GetFormFields(pFormFillEnv, swFieldName);
+  for (CPDF_FormField* pFormField : FieldArray) {
+    if (nControlIndex < 0) {
+      bool bSet = false;
+      for (int i = 0, sz = pFormField->CountControls(); i < sz; ++i) {
+        CPDF_FormControl* pFormControl = pFormField->GetControl(i);
+        ASSERT(pFormControl);
+
+        if (CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormControl)) {
+          CFX_FloatRect crRect = rect;
+
+          CPDF_Page* pPDFPage = pWidget->GetPDFPage();
+          crRect.Intersect(pPDFPage->GetPageBBox());
+
+          if (!crRect.IsEmpty()) {
+            CFX_FloatRect rcOld = pWidget->GetRect();
+            if (crRect.left != rcOld.left || crRect.right != rcOld.right ||
+                crRect.top != rcOld.top || crRect.bottom != rcOld.bottom) {
+              pWidget->SetRect(crRect);
+              bSet = true;
+            }
+          }
+        }
+      }
+
+      if (bSet)
+        UpdateFormField(pFormFillEnv, pFormField, true, true, true);
+    } else {
+      if (nControlIndex >= pFormField->CountControls())
+        return;
+      if (CPDF_FormControl* pFormControl =
+              pFormField->GetControl(nControlIndex)) {
+        if (CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormControl)) {
+          CFX_FloatRect crRect = rect;
+
+          CPDF_Page* pPDFPage = pWidget->GetPDFPage();
+          crRect.Intersect(pPDFPage->GetPageBBox());
+
+          if (!crRect.IsEmpty()) {
+            CFX_FloatRect rcOld = pWidget->GetRect();
+            if (crRect.left != rcOld.left || crRect.right != rcOld.right ||
+                crRect.top != rcOld.top || crRect.bottom != rcOld.bottom) {
+              pWidget->SetRect(crRect);
+              UpdateFormControl(pFormFillEnv, pFormControl, true, true, true);
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+bool Field::required(IJS_Context* cc,
+                     CJS_PropValue& vp,
+                     CFX_WideString& sError) {
+  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+  if (FieldArray.empty())
+    return false;
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    bool bVP;
+    vp >> bVP;
+
+  } else {
+    CPDF_FormField* pFormField = FieldArray[0];
+    if (pFormField->GetFieldType() == FIELDTYPE_PUSHBUTTON)
+      return false;
+
+    if (pFormField->GetFieldFlags() & FIELDFLAG_REQUIRED)
+      vp << true;
+    else
+      vp << false;
+  }
+
+  return true;
+}
+
+bool Field::richText(IJS_Context* cc,
+                     CJS_PropValue& vp,
+                     CFX_WideString& sError) {
+  ASSERT(m_pFormFillEnv);
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    bool bVP;
+    vp >> bVP;
+
+    if (m_bDelay) {
+      AddDelay_Bool(FP_RICHTEXT, bVP);
+    }
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD)
+      return false;
+
+    if (pFormField->GetFieldFlags() & FIELDFLAG_RICHTEXT)
+      vp << true;
+    else
+      vp << false;
+  }
+
+  return true;
+}
+
+bool Field::richValue(IJS_Context* cc,
+                      CJS_PropValue& vp,
+                      CFX_WideString& sError) {
+  return true;
+}
+
+bool Field::rotation(IJS_Context* cc,
+                     CJS_PropValue& vp,
+                     CFX_WideString& sError) {
+  ASSERT(m_pFormFillEnv);
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    int nVP;
+    vp >> nVP;
+
+    if (m_bDelay) {
+      AddDelay_Int(FP_ROTATION, nVP);
+    } else {
+      Field::SetRotation(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex,
+                         nVP);
+    }
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
+    if (!pFormControl)
+      return false;
+
+    vp << (int32_t)pFormControl->GetRotation();
+  }
+
+  return true;
+}
+
+void Field::SetRotation(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                        const CFX_WideString& swFieldName,
+                        int nControlIndex,
+                        int number) {
+  // Not supported.
+}
+
+bool Field::strokeColor(IJS_Context* cc,
+                        CJS_PropValue& vp,
+                        CFX_WideString& sError) {
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  CJS_Array crArray;
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    if (!vp.GetJSValue()->IsArrayObject())
+      return false;
+
+    vp >> crArray;
+
+    CPWL_Color color;
+    color::ConvertArrayToPWLColor(pRuntime, crArray, &color);
+
+    if (m_bDelay) {
+      AddDelay_Color(FP_STROKECOLOR, color);
+    } else {
+      Field::SetStrokeColor(m_pFormFillEnv.Get(), m_FieldName,
+                            m_nFormControlIndex, color);
+    }
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
+    if (!pFormControl)
+      return false;
+
+    int iColorType;
+    pFormControl->GetBorderColor(iColorType);
+
+    CPWL_Color color;
+    if (iColorType == COLORTYPE_TRANSPARENT) {
+      color = CPWL_Color(COLORTYPE_TRANSPARENT);
+    } else if (iColorType == COLORTYPE_GRAY) {
+      color =
+          CPWL_Color(COLORTYPE_GRAY, pFormControl->GetOriginalBorderColor(0));
+    } else if (iColorType == COLORTYPE_RGB) {
+      color = CPWL_Color(COLORTYPE_RGB, pFormControl->GetOriginalBorderColor(0),
+                         pFormControl->GetOriginalBorderColor(1),
+                         pFormControl->GetOriginalBorderColor(2));
+    } else if (iColorType == COLORTYPE_CMYK) {
+      color =
+          CPWL_Color(COLORTYPE_CMYK, pFormControl->GetOriginalBorderColor(0),
+                     pFormControl->GetOriginalBorderColor(1),
+                     pFormControl->GetOriginalBorderColor(2),
+                     pFormControl->GetOriginalBorderColor(3));
+    } else {
+      return false;
+    }
+
+    color::ConvertPWLColorToArray(pRuntime, color, &crArray);
+    vp << crArray;
+  }
+  return true;
+}
+
+void Field::SetStrokeColor(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                           const CFX_WideString& swFieldName,
+                           int nControlIndex,
+                           const CPWL_Color& color) {
+  // Not supported.
+}
+
+bool Field::style(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
+  ASSERT(m_pFormFillEnv);
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    CFX_ByteString csBCaption;
+    vp >> csBCaption;
+
+    if (m_bDelay) {
+      AddDelay_String(FP_STYLE, csBCaption);
+    } else {
+      Field::SetStyle(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex,
+                      csBCaption);
+    }
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    if (pFormField->GetFieldType() != FIELDTYPE_RADIOBUTTON &&
+        pFormField->GetFieldType() != FIELDTYPE_CHECKBOX) {
+      return false;
+    }
+
+    CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
+    if (!pFormControl)
+      return false;
+
+    CFX_WideString csWCaption = pFormControl->GetNormalCaption();
+    CFX_ByteString csBCaption;
+
+    switch (csWCaption[0]) {
+      case L'l':
+        csBCaption = "circle";
+        break;
+      case L'8':
+        csBCaption = "cross";
+        break;
+      case L'u':
+        csBCaption = "diamond";
+        break;
+      case L'n':
+        csBCaption = "square";
+        break;
+      case L'H':
+        csBCaption = "star";
+        break;
+      default:  // L'4'
+        csBCaption = "check";
+        break;
+    }
+    vp << csBCaption;
+  }
+
+  return true;
+}
+
+void Field::SetStyle(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                     const CFX_WideString& swFieldName,
+                     int nControlIndex,
+                     const CFX_ByteString& string) {
+  // Not supported.
+}
+
+bool Field::submitName(IJS_Context* cc,
+                       CJS_PropValue& vp,
+                       CFX_WideString& sError) {
+  return true;
+}
+
+bool Field::textColor(IJS_Context* cc,
+                      CJS_PropValue& vp,
+                      CFX_WideString& sError) {
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  CJS_Array crArray;
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    if (!vp.GetJSValue()->IsArrayObject())
+      return false;
+
+    vp >> crArray;
+
+    CPWL_Color color;
+    color::ConvertArrayToPWLColor(pRuntime, crArray, &color);
+
+    if (m_bDelay) {
+      AddDelay_Color(FP_TEXTCOLOR, color);
+    } else {
+      Field::SetTextColor(m_pFormFillEnv.Get(), m_FieldName,
+                          m_nFormControlIndex, color);
+    }
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
+    if (!pFormControl)
+      return false;
+
+    int iColorType;
+    FX_ARGB color;
+    CPDF_DefaultAppearance FieldAppearance =
+        pFormControl->GetDefaultAppearance();
+    FieldAppearance.GetColor(color, iColorType);
+    int32_t a, r, g, b;
+    ArgbDecode(color, a, r, g, b);
+
+    CPWL_Color crRet =
+        CPWL_Color(COLORTYPE_RGB, r / 255.0f, g / 255.0f, b / 255.0f);
+
+    if (iColorType == COLORTYPE_TRANSPARENT)
+      crRet = CPWL_Color(COLORTYPE_TRANSPARENT);
+
+    color::ConvertPWLColorToArray(pRuntime, crRet, &crArray);
+    vp << crArray;
+  }
+  return true;
+}
+
+void Field::SetTextColor(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                         const CFX_WideString& swFieldName,
+                         int nControlIndex,
+                         const CPWL_Color& color) {
+  // Not supported.
+}
+
+bool Field::textFont(IJS_Context* cc,
+                     CJS_PropValue& vp,
+                     CFX_WideString& sError) {
+  ASSERT(m_pFormFillEnv);
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    CFX_ByteString csFontName;
+    vp >> csFontName;
+    if (csFontName.IsEmpty())
+      return false;
+
+    if (m_bDelay) {
+      AddDelay_String(FP_TEXTFONT, csFontName);
+    } else {
+      Field::SetTextFont(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex,
+                         csFontName);
+    }
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    ASSERT(pFormField);
+    CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
+    if (!pFormControl)
+      return false;
+
+    int nFieldType = pFormField->GetFieldType();
+
+    if (nFieldType == FIELDTYPE_PUSHBUTTON ||
+        nFieldType == FIELDTYPE_COMBOBOX || nFieldType == FIELDTYPE_LISTBOX ||
+        nFieldType == FIELDTYPE_TEXTFIELD) {
+      CPDF_Font* pFont = pFormControl->GetDefaultControlFont();
+      if (!pFont)
+        return false;
+
+      vp << pFont->GetBaseFont();
+    } else {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+void Field::SetTextFont(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                        const CFX_WideString& swFieldName,
+                        int nControlIndex,
+                        const CFX_ByteString& string) {
+  // Not supported.
+}
+
+bool Field::textSize(IJS_Context* cc,
+                     CJS_PropValue& vp,
+                     CFX_WideString& sError) {
+  ASSERT(m_pFormFillEnv);
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    int nVP;
+    vp >> nVP;
+
+    if (m_bDelay) {
+      AddDelay_Int(FP_TEXTSIZE, nVP);
+    } else {
+      Field::SetTextSize(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex,
+                         nVP);
+    }
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    ASSERT(pFormField);
+    CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
+    if (!pFormControl)
+      return false;
+
+    CPDF_DefaultAppearance FieldAppearance =
+        pFormControl->GetDefaultAppearance();
+
+    CFX_ByteString csFontNameTag;
+    FX_FLOAT fFontSize;
+    FieldAppearance.GetFont(csFontNameTag, fFontSize);
+
+    vp << (int)fFontSize;
+  }
+
+  return true;
+}
+
+void Field::SetTextSize(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                        const CFX_WideString& swFieldName,
+                        int nControlIndex,
+                        int number) {
+  // Not supported.
+}
+
+bool Field::type(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
+  if (!vp.IsGetting())
+    return false;
+
+  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+  if (FieldArray.empty())
+    return false;
+
+  CPDF_FormField* pFormField = FieldArray[0];
+  switch (pFormField->GetFieldType()) {
+    case FIELDTYPE_UNKNOWN:
+      vp << L"unknown";
+      break;
+    case FIELDTYPE_PUSHBUTTON:
+      vp << L"button";
+      break;
+    case FIELDTYPE_CHECKBOX:
+      vp << L"checkbox";
+      break;
+    case FIELDTYPE_RADIOBUTTON:
+      vp << L"radiobutton";
+      break;
+    case FIELDTYPE_COMBOBOX:
+      vp << L"combobox";
+      break;
+    case FIELDTYPE_LISTBOX:
+      vp << L"listbox";
+      break;
+    case FIELDTYPE_TEXTFIELD:
+      vp << L"text";
+      break;
+    case FIELDTYPE_SIGNATURE:
+      vp << L"signature";
+      break;
+    default:
+      vp << L"unknown";
+      break;
+  }
+
+  return true;
+}
+
+bool Field::userName(IJS_Context* cc,
+                     CJS_PropValue& vp,
+                     CFX_WideString& sError) {
+  ASSERT(m_pFormFillEnv);
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    CFX_WideString swName;
+    vp >> swName;
+
+    if (m_bDelay) {
+      AddDelay_WideString(FP_USERNAME, swName);
+    } else {
+      Field::SetUserName(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex,
+                         swName);
+    }
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    vp << (CFX_WideString)pFormField->GetAlternateName();
+  }
+
+  return true;
+}
+
+void Field::SetUserName(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                        const CFX_WideString& swFieldName,
+                        int nControlIndex,
+                        const CFX_WideString& string) {
+  // Not supported.
+}
+
+bool Field::value(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+
+  if (vp.IsSetting()) {
+    if (!m_bCanSet)
+      return false;
+
+    std::vector<CFX_WideString> strArray;
+    if (vp.GetJSValue()->IsArrayObject()) {
+      CJS_Array ValueArray;
+      vp.GetJSValue()->ConvertToArray(pRuntime, ValueArray);
+      for (int i = 0, sz = ValueArray.GetLength(pRuntime); i < sz; i++) {
+        CJS_Value ElementValue(pRuntime);
+        ValueArray.GetElement(pRuntime, i, ElementValue);
+        strArray.push_back(ElementValue.ToCFXWideString(pRuntime));
+      }
+    } else {
+      CFX_WideString swValue;
+      vp >> swValue;
+      strArray.push_back(swValue);
+    }
+
+    if (m_bDelay) {
+      AddDelay_WideStringArray(FP_VALUE, strArray);
+    } else {
+      Field::SetValue(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex,
+                      strArray);
+    }
+  } else {
+    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+    if (FieldArray.empty())
+      return false;
+
+    CPDF_FormField* pFormField = FieldArray[0];
+    switch (pFormField->GetFieldType()) {
+      case FIELDTYPE_PUSHBUTTON:
+        return false;
+      case FIELDTYPE_COMBOBOX:
+      case FIELDTYPE_TEXTFIELD: {
+        vp << pFormField->GetValue();
+      } break;
+      case FIELDTYPE_LISTBOX: {
+        if (pFormField->CountSelectedItems() > 1) {
+          CJS_Array ValueArray;
+          CJS_Value ElementValue(pRuntime);
+          int iIndex;
+          for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz; i++) {
+            iIndex = pFormField->GetSelectedIndex(i);
+            ElementValue =
+                CJS_Value(pRuntime, pFormField->GetOptionValue(iIndex).c_str());
+            if (FXSYS_wcslen(ElementValue.ToCFXWideString(pRuntime).c_str()) ==
+                0) {
+              ElementValue = CJS_Value(
+                  pRuntime, pFormField->GetOptionLabel(iIndex).c_str());
+            }
+            ValueArray.SetElement(pRuntime, i, ElementValue);
+          }
+          vp << ValueArray;
+        } else {
+          vp << pFormField->GetValue();
+        }
+      } break;
+      case FIELDTYPE_CHECKBOX:
+      case FIELDTYPE_RADIOBUTTON: {
+        bool bFind = false;
+        for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
+          if (pFormField->GetControl(i)->IsChecked()) {
+            vp << pFormField->GetControl(i)->GetExportValue();
+            bFind = true;
+            break;
+          }
+        }
+        if (!bFind)
+          vp << L"Off";
+      } break;
+      default:
+        vp << pFormField->GetValue();
+        break;
+    }
+  }
+  vp.GetJSValue()->MaybeCoerceToNumber(pRuntime);
+  return true;
+}
+
+void Field::SetValue(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                     const CFX_WideString& swFieldName,
+                     int nControlIndex,
+                     const std::vector<CFX_WideString>& strArray) {
+  ASSERT(pFormFillEnv);
+  if (strArray.empty())
+    return;
+
+  std::vector<CPDF_FormField*> FieldArray =
+      GetFormFields(pFormFillEnv, swFieldName);
+
+  for (CPDF_FormField* pFormField : FieldArray) {
+    if (pFormField->GetFullName().Compare(swFieldName) != 0)
+      continue;
+
+    switch (pFormField->GetFieldType()) {
+      case FIELDTYPE_TEXTFIELD:
+      case FIELDTYPE_COMBOBOX:
+        if (pFormField->GetValue() != strArray[0]) {
+          pFormField->SetValue(strArray[0], true);
+          UpdateFormField(pFormFillEnv, pFormField, true, false, true);
+        }
+        break;
+      case FIELDTYPE_CHECKBOX:
+      case FIELDTYPE_RADIOBUTTON: {
+        if (pFormField->GetValue() != strArray[0]) {
+          pFormField->SetValue(strArray[0], true);
+          UpdateFormField(pFormFillEnv, pFormField, true, false, true);
+        }
+      } break;
+      case FIELDTYPE_LISTBOX: {
+        bool bModified = false;
+        for (const auto& str : strArray) {
+          if (!pFormField->IsItemSelected(pFormField->FindOption(str))) {
+            bModified = true;
+            break;
+          }
+        }
+        if (bModified) {
+          pFormField->ClearSelection(true);
+          for (const auto& str : strArray) {
+            int index = pFormField->FindOption(str);
+            if (!pFormField->IsItemSelected(index))
+              pFormField->SetItemSelection(index, true, true);
+          }
+          UpdateFormField(pFormFillEnv, pFormField, true, false, true);
+        }
+      } break;
+      default:
+        break;
+    }
+  }
+}
+
+bool Field::valueAsString(IJS_Context* cc,
+                          CJS_PropValue& vp,
+                          CFX_WideString& sError) {
+  if (!vp.IsGetting())
+    return false;
+
+  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+  if (FieldArray.empty())
+    return false;
+
+  CPDF_FormField* pFormField = FieldArray[0];
+  if (pFormField->GetFieldType() == FIELDTYPE_PUSHBUTTON)
+    return false;
+
+  if (pFormField->GetFieldType() == FIELDTYPE_CHECKBOX) {
+    if (!pFormField->CountControls())
+      return false;
+
+    if (pFormField->GetControl(0)->IsChecked())
+      vp << L"Yes";
+    else
+      vp << L"Off";
+  } else if (pFormField->GetFieldType() == FIELDTYPE_RADIOBUTTON &&
+             !(pFormField->GetFieldFlags() & FIELDFLAG_RADIOSINUNISON)) {
+    for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
+      if (pFormField->GetControl(i)->IsChecked()) {
+        vp << pFormField->GetControl(i)->GetExportValue().c_str();
+        break;
+      } else {
+        vp << L"Off";
+      }
+    }
+  } else if (pFormField->GetFieldType() == FIELDTYPE_LISTBOX &&
+             (pFormField->CountSelectedItems() > 1)) {
+    vp << L"";
+  } else {
+    vp << pFormField->GetValue().c_str();
+  }
+
+  return true;
+}
+
+bool Field::browseForFileToSubmit(IJS_Context* cc,
+                                  const std::vector<CJS_Value>& params,
+                                  CJS_Value& vRet,
+                                  CFX_WideString& sError) {
+  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+  if (FieldArray.empty())
+    return false;
+
+  CPDF_FormField* pFormField = FieldArray[0];
+  if ((pFormField->GetFieldFlags() & FIELDFLAG_FILESELECT) &&
+      (pFormField->GetFieldType() == FIELDTYPE_TEXTFIELD)) {
+    CFX_WideString wsFileName = m_pFormFillEnv->JS_fieldBrowse();
+    if (!wsFileName.IsEmpty()) {
+      pFormField->SetValue(wsFileName);
+      UpdateFormField(m_pFormFillEnv.Get(), pFormField, true, true, true);
+    }
+    return true;
+  }
+  return false;
+}
+
+bool Field::buttonGetCaption(IJS_Context* cc,
+                             const std::vector<CJS_Value>& params,
+                             CJS_Value& vRet,
+                             CFX_WideString& sError) {
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+
+  int nface = 0;
+  int iSize = params.size();
+  if (iSize >= 1)
+    nface = params[0].ToInt(pRuntime);
+
+  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+  if (FieldArray.empty())
+    return false;
+
+  CPDF_FormField* pFormField = FieldArray[0];
+  if (pFormField->GetFieldType() != FIELDTYPE_PUSHBUTTON)
+    return false;
+
+  CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
+  if (!pFormControl)
+    return false;
+
+  if (nface == 0)
+    vRet = CJS_Value(pRuntime, pFormControl->GetNormalCaption().c_str());
+  else if (nface == 1)
+    vRet = CJS_Value(pRuntime, pFormControl->GetDownCaption().c_str());
+  else if (nface == 2)
+    vRet = CJS_Value(pRuntime, pFormControl->GetRolloverCaption().c_str());
+  else
+    return false;
+
+  return true;
+}
+
+bool Field::buttonGetIcon(IJS_Context* cc,
+                          const std::vector<CJS_Value>& params,
+                          CJS_Value& vRet,
+                          CFX_WideString& sError) {
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+
+  int nface = 0;
+  int iSize = params.size();
+  if (iSize >= 1)
+    nface = params[0].ToInt(pRuntime);
+
+  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+  if (FieldArray.empty())
+    return false;
+
+  CPDF_FormField* pFormField = FieldArray[0];
+  if (pFormField->GetFieldType() != FIELDTYPE_PUSHBUTTON)
+    return false;
+
+  CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
+  if (!pFormControl)
+    return false;
+
+  v8::Local<v8::Object> pObj =
+      pRuntime->NewFxDynamicObj(CJS_Icon::g_nObjDefnID);
+  ASSERT(pObj.IsEmpty() == false);
+
+  CJS_Icon* pJS_Icon = static_cast<CJS_Icon*>(pRuntime->GetObjectPrivate(pObj));
+  Icon* pIcon = (Icon*)pJS_Icon->GetEmbedObject();
+
+  CPDF_Stream* pIconStream = nullptr;
+  if (nface == 0)
+    pIconStream = pFormControl->GetNormalIcon();
+  else if (nface == 1)
+    pIconStream = pFormControl->GetDownIcon();
+  else if (nface == 2)
+    pIconStream = pFormControl->GetRolloverIcon();
+  else
+    return false;
+
+  pIcon->SetStream(pIconStream);
+  vRet = CJS_Value(pRuntime, pJS_Icon);
+  return true;
+}
+
+bool Field::buttonImportIcon(IJS_Context* cc,
+                             const std::vector<CJS_Value>& params,
+                             CJS_Value& vRet,
+                             CFX_WideString& sError) {
+  return true;
+}
+
+bool Field::buttonSetCaption(IJS_Context* cc,
+                             const std::vector<CJS_Value>& params,
+                             CJS_Value& vRet,
+                             CFX_WideString& sError) {
+  return false;
+}
+
+bool Field::buttonSetIcon(IJS_Context* cc,
+                          const std::vector<CJS_Value>& params,
+                          CJS_Value& vRet,
+                          CFX_WideString& sError) {
+  return false;
+}
+
+bool Field::checkThisBox(IJS_Context* cc,
+                         const std::vector<CJS_Value>& params,
+                         CJS_Value& vRet,
+                         CFX_WideString& sError) {
+  int iSize = params.size();
+  if (iSize < 1)
+    return false;
+
+  if (!m_bCanSet)
+    return false;
+
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  int nWidget = params[0].ToInt(pRuntime);
+
+  bool bCheckit = true;
+  if (iSize >= 2)
+    bCheckit = params[1].ToBool(pRuntime);
+
+  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+  if (FieldArray.empty())
+    return false;
+
+  CPDF_FormField* pFormField = FieldArray[0];
+  if (pFormField->GetFieldType() != FIELDTYPE_CHECKBOX &&
+      pFormField->GetFieldType() != FIELDTYPE_RADIOBUTTON)
+    return false;
+  if (nWidget < 0 || nWidget >= pFormField->CountControls())
+    return false;
+  // TODO(weili): Check whether anything special needed for radio button,
+  // otherwise merge these branches.
+  if (pFormField->GetFieldType() == FIELDTYPE_RADIOBUTTON)
+    pFormField->CheckControl(nWidget, bCheckit, true);
+  else
+    pFormField->CheckControl(nWidget, bCheckit, true);
+
+  UpdateFormField(m_pFormFillEnv.Get(), pFormField, true, true, true);
+  return true;
+}
+
+bool Field::clearItems(IJS_Context* cc,
+                       const std::vector<CJS_Value>& params,
+                       CJS_Value& vRet,
+                       CFX_WideString& sError) {
+  return true;
+}
+
+bool Field::defaultIsChecked(IJS_Context* cc,
+                             const std::vector<CJS_Value>& params,
+                             CJS_Value& vRet,
+                             CFX_WideString& sError) {
+  if (!m_bCanSet)
+    return false;
+
+  int iSize = params.size();
+  if (iSize < 1)
+    return false;
+
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  int nWidget = params[0].ToInt(pRuntime);
+
+  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+  if (FieldArray.empty())
+    return false;
+
+  CPDF_FormField* pFormField = FieldArray[0];
+  if (nWidget < 0 || nWidget >= pFormField->CountControls())
+    return false;
+
+  vRet = CJS_Value(pRuntime,
+                   pFormField->GetFieldType() == FIELDTYPE_CHECKBOX ||
+                       pFormField->GetFieldType() == FIELDTYPE_RADIOBUTTON);
+
+  return true;
+}
+
+bool Field::deleteItemAt(IJS_Context* cc,
+                         const std::vector<CJS_Value>& params,
+                         CJS_Value& vRet,
+                         CFX_WideString& sError) {
+  return true;
+}
+
+bool Field::getArray(IJS_Context* cc,
+                     const std::vector<CJS_Value>& params,
+                     CJS_Value& vRet,
+                     CFX_WideString& sError) {
+  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+  if (FieldArray.empty())
+    return false;
+
+  std::vector<std::unique_ptr<CFX_WideString>> swSort;
+  for (CPDF_FormField* pFormField : FieldArray) {
+    swSort.push_back(std::unique_ptr<CFX_WideString>(
+        new CFX_WideString(pFormField->GetFullName())));
+  }
+
+  std::sort(
+      swSort.begin(), swSort.end(),
+      [](const std::unique_ptr<CFX_WideString>& p1,
+         const std::unique_ptr<CFX_WideString>& p2) { return *p1 < *p2; });
+
+  CJS_Context* pContext = (CJS_Context*)cc;
+  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+  CJS_Array FormFieldArray;
+
+  int j = 0;
+  for (const auto& pStr : swSort) {
+    v8::Local<v8::Object> pObj =
+        pRuntime->NewFxDynamicObj(CJS_Field::g_nObjDefnID);
+    ASSERT(!pObj.IsEmpty());
+
+    CJS_Field* pJSField =
+        static_cast<CJS_Field*>(pRuntime->GetObjectPrivate(pObj));
+    Field* pField = static_cast<Field*>(pJSField->GetEmbedObject());
+    pField->AttachField(m_pJSDoc, *pStr);
+    FormFieldArray.SetElement(pRuntime, j++, CJS_Value(pRuntime, pJSField));
+  }
+
+  vRet = CJS_Value(pRuntime, FormFieldArray);
+  return true;
+}
+
+bool Field::getItemAt(IJS_Context* cc,
+                      const std::vector<CJS_Value>& params,
+                      CJS_Value& vRet,
+                      CFX_WideString& sError) {
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+
+  int iSize = params.size();
+  int nIdx = -1;
+  if (iSize >= 1)
+    nIdx = params[0].ToInt(pRuntime);
+
+  bool bExport = true;
+  if (iSize >= 2)
+    bExport = params[1].ToBool(pRuntime);
+
+  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+  if (FieldArray.empty())
+    return false;
+
+  CPDF_FormField* pFormField = FieldArray[0];
+  if ((pFormField->GetFieldType() == FIELDTYPE_LISTBOX) ||
+      (pFormField->GetFieldType() == FIELDTYPE_COMBOBOX)) {
+    if (nIdx == -1 || nIdx > pFormField->CountOptions())
+      nIdx = pFormField->CountOptions() - 1;
+    if (bExport) {
+      CFX_WideString strval = pFormField->GetOptionValue(nIdx);
+      if (strval.IsEmpty())
+        vRet = CJS_Value(pRuntime, pFormField->GetOptionLabel(nIdx).c_str());
+      else
+        vRet = CJS_Value(pRuntime, strval.c_str());
+    } else {
+      vRet = CJS_Value(pRuntime, pFormField->GetOptionLabel(nIdx).c_str());
+    }
+  } else {
+    return false;
+  }
+
+  return true;
+}
+
+bool Field::getLock(IJS_Context* cc,
+                    const std::vector<CJS_Value>& params,
+                    CJS_Value& vRet,
+                    CFX_WideString& sError) {
+  return false;
+}
+
+bool Field::insertItemAt(IJS_Context* cc,
+                         const std::vector<CJS_Value>& params,
+                         CJS_Value& vRet,
+                         CFX_WideString& sError) {
+  return true;
+}
+
+bool Field::isBoxChecked(IJS_Context* cc,
+                         const std::vector<CJS_Value>& params,
+                         CJS_Value& vRet,
+                         CFX_WideString& sError) {
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+
+  int nIndex = -1;
+  if (params.size() >= 1)
+    nIndex = params[0].ToInt(pRuntime);
+
+  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+  if (FieldArray.empty())
+    return false;
+
+  CPDF_FormField* pFormField = FieldArray[0];
+  if (nIndex < 0 || nIndex >= pFormField->CountControls()) {
+    return false;
+  }
+
+  vRet = CJS_Value(pRuntime,
+                   ((pFormField->GetFieldType() == FIELDTYPE_CHECKBOX ||
+                     pFormField->GetFieldType() == FIELDTYPE_RADIOBUTTON) &&
+                    pFormField->GetControl(nIndex)->IsChecked() != 0));
+  return true;
+}
+
+bool Field::isDefaultChecked(IJS_Context* cc,
+                             const std::vector<CJS_Value>& params,
+                             CJS_Value& vRet,
+                             CFX_WideString& sError) {
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+
+  int nIndex = -1;
+  if (params.size() >= 1)
+    nIndex = params[0].ToInt(pRuntime);
+
+  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+  if (FieldArray.empty())
+    return false;
+
+  CPDF_FormField* pFormField = FieldArray[0];
+  if (nIndex < 0 || nIndex >= pFormField->CountControls())
+    return false;
+
+  vRet = CJS_Value(pRuntime,
+                   ((pFormField->GetFieldType() == FIELDTYPE_CHECKBOX ||
+                     pFormField->GetFieldType() == FIELDTYPE_RADIOBUTTON) &&
+                    pFormField->GetControl(nIndex)->IsDefaultChecked() != 0));
+  return true;
+}
+
+bool Field::setAction(IJS_Context* cc,
+                      const std::vector<CJS_Value>& params,
+                      CJS_Value& vRet,
+                      CFX_WideString& sError) {
+  return true;
+}
+
+bool Field::setFocus(IJS_Context* cc,
+                     const std::vector<CJS_Value>& params,
+                     CJS_Value& vRet,
+                     CFX_WideString& sError) {
+  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
+  if (FieldArray.empty())
+    return false;
+
+  CPDF_FormField* pFormField = FieldArray[0];
+  int32_t nCount = pFormField->CountControls();
+  if (nCount < 1)
+    return false;
+
+  CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm();
+  CPDFSDK_Widget* pWidget = nullptr;
+  if (nCount == 1) {
+    pWidget = pInterForm->GetWidget(pFormField->GetControl(0));
+  } else {
+    UnderlyingPageType* pPage =
+        UnderlyingFromFPDFPage(m_pFormFillEnv->GetCurrentPage(
+            m_pFormFillEnv->GetUnderlyingDocument()));
+    if (!pPage)
+      return false;
+    if (CPDFSDK_PageView* pCurPageView =
+            m_pFormFillEnv->GetPageView(pPage, true)) {
+      for (int32_t i = 0; i < nCount; i++) {
+        if (CPDFSDK_Widget* pTempWidget =
+                pInterForm->GetWidget(pFormField->GetControl(i))) {
+          if (pTempWidget->GetPDFPage() == pCurPageView->GetPDFPage()) {
+            pWidget = pTempWidget;
+            break;
+          }
+        }
+      }
+    }
+  }
+
+  if (pWidget) {
+    CPDFSDK_Annot::ObservedPtr pObserved(pWidget);
+    m_pFormFillEnv->SetFocusAnnot(&pObserved);
+  }
+
+  return true;
+}
+
+bool Field::setItems(IJS_Context* cc,
+                     const std::vector<CJS_Value>& params,
+                     CJS_Value& vRet,
+                     CFX_WideString& sError) {
+  return true;
+}
+
+bool Field::setLock(IJS_Context* cc,
+                    const std::vector<CJS_Value>& params,
+                    CJS_Value& vRet,
+                    CFX_WideString& sError) {
+  return false;
+}
+
+bool Field::signatureGetModifications(IJS_Context* cc,
+                                      const std::vector<CJS_Value>& params,
+                                      CJS_Value& vRet,
+                                      CFX_WideString& sError) {
+  return false;
+}
+
+bool Field::signatureGetSeedValue(IJS_Context* cc,
+                                  const std::vector<CJS_Value>& params,
+                                  CJS_Value& vRet,
+                                  CFX_WideString& sError) {
+  return false;
+}
+
+bool Field::signatureInfo(IJS_Context* cc,
+                          const std::vector<CJS_Value>& params,
+                          CJS_Value& vRet,
+                          CFX_WideString& sError) {
+  return false;
+}
+
+bool Field::signatureSetSeedValue(IJS_Context* cc,
+                                  const std::vector<CJS_Value>& params,
+                                  CJS_Value& vRet,
+                                  CFX_WideString& sError) {
+  return false;
+}
+
+bool Field::signatureSign(IJS_Context* cc,
+                          const std::vector<CJS_Value>& params,
+                          CJS_Value& vRet,
+                          CFX_WideString& sError) {
+  return false;
+}
+
+bool Field::signatureValidate(IJS_Context* cc,
+                              const std::vector<CJS_Value>& params,
+                              CJS_Value& vRet,
+                              CFX_WideString& sError) {
+  return false;
+}
+
+bool Field::source(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
+  if (vp.IsGetting()) {
+    vp << (CJS_Object*)nullptr;
+  }
+
+  return true;
+}
+
+void Field::AddDelay_Int(FIELD_PROP prop, int32_t n) {
+  CJS_DelayData* pNewData =
+      new CJS_DelayData(prop, m_nFormControlIndex, m_FieldName);
+  pNewData->num = n;
+  m_pJSDoc->AddDelayData(pNewData);
+}
+
+void Field::AddDelay_Bool(FIELD_PROP prop, bool b) {
+  CJS_DelayData* pNewData =
+      new CJS_DelayData(prop, m_nFormControlIndex, m_FieldName);
+  pNewData->b = b;
+  m_pJSDoc->AddDelayData(pNewData);
+}
+
+void Field::AddDelay_String(FIELD_PROP prop, const CFX_ByteString& string) {
+  CJS_DelayData* pNewData =
+      new CJS_DelayData(prop, m_nFormControlIndex, m_FieldName);
+  pNewData->string = string;
+  m_pJSDoc->AddDelayData(pNewData);
+}
+
+void Field::AddDelay_WideString(FIELD_PROP prop, const CFX_WideString& string) {
+  CJS_DelayData* pNewData =
+      new CJS_DelayData(prop, m_nFormControlIndex, m_FieldName);
+  pNewData->widestring = string;
+  m_pJSDoc->AddDelayData(pNewData);
+}
+
+void Field::AddDelay_Rect(FIELD_PROP prop, const CFX_FloatRect& rect) {
+  CJS_DelayData* pNewData =
+      new CJS_DelayData(prop, m_nFormControlIndex, m_FieldName);
+  pNewData->rect = rect;
+  m_pJSDoc->AddDelayData(pNewData);
+}
+
+void Field::AddDelay_Color(FIELD_PROP prop, const CPWL_Color& color) {
+  CJS_DelayData* pNewData =
+      new CJS_DelayData(prop, m_nFormControlIndex, m_FieldName);
+  pNewData->color = color;
+  m_pJSDoc->AddDelayData(pNewData);
+}
+
+void Field::AddDelay_WordArray(FIELD_PROP prop,
+                               const std::vector<uint32_t>& array) {
+  CJS_DelayData* pNewData =
+      new CJS_DelayData(prop, m_nFormControlIndex, m_FieldName);
+  pNewData->wordarray = array;
+  m_pJSDoc->AddDelayData(pNewData);
+}
+
+void Field::AddDelay_WideStringArray(FIELD_PROP prop,
+                                     const std::vector<CFX_WideString>& array) {
+  CJS_DelayData* pNewData =
+      new CJS_DelayData(prop, m_nFormControlIndex, m_FieldName);
+  pNewData->widestringarray = array;
+  m_pJSDoc->AddDelayData(pNewData);
+}
+
+void Field::DoDelay(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                    CJS_DelayData* pData) {
+  ASSERT(pFormFillEnv);
+  switch (pData->eProp) {
+    case FP_ALIGNMENT:
+      Field::SetAlignment(pFormFillEnv, pData->sFieldName, pData->nControlIndex,
+                          pData->string);
+      break;
+    case FP_BORDERSTYLE:
+      Field::SetBorderStyle(pFormFillEnv, pData->sFieldName,
+                            pData->nControlIndex, pData->string);
+      break;
+    case FP_BUTTONALIGNX:
+      Field::SetButtonAlignX(pFormFillEnv, pData->sFieldName,
+                             pData->nControlIndex, pData->num);
+      break;
+    case FP_BUTTONALIGNY:
+      Field::SetButtonAlignY(pFormFillEnv, pData->sFieldName,
+                             pData->nControlIndex, pData->num);
+      break;
+    case FP_BUTTONFITBOUNDS:
+      Field::SetButtonFitBounds(pFormFillEnv, pData->sFieldName,
+                                pData->nControlIndex, pData->b);
+      break;
+    case FP_BUTTONPOSITION:
+      Field::SetButtonPosition(pFormFillEnv, pData->sFieldName,
+                               pData->nControlIndex, pData->num);
+      break;
+    case FP_BUTTONSCALEHOW:
+      Field::SetButtonScaleHow(pFormFillEnv, pData->sFieldName,
+                               pData->nControlIndex, pData->num);
+      break;
+    case FP_BUTTONSCALEWHEN:
+      Field::SetButtonScaleWhen(pFormFillEnv, pData->sFieldName,
+                                pData->nControlIndex, pData->num);
+      break;
+    case FP_CALCORDERINDEX:
+      Field::SetCalcOrderIndex(pFormFillEnv, pData->sFieldName,
+                               pData->nControlIndex, pData->num);
+      break;
+    case FP_CHARLIMIT:
+      Field::SetCharLimit(pFormFillEnv, pData->sFieldName, pData->nControlIndex,
+                          pData->num);
+      break;
+    case FP_COMB:
+      Field::SetComb(pFormFillEnv, pData->sFieldName, pData->nControlIndex,
+                     pData->b);
+      break;
+    case FP_COMMITONSELCHANGE:
+      Field::SetCommitOnSelChange(pFormFillEnv, pData->sFieldName,
+                                  pData->nControlIndex, pData->b);
+      break;
+    case FP_CURRENTVALUEINDICES:
+      Field::SetCurrentValueIndices(pFormFillEnv, pData->sFieldName,
+                                    pData->nControlIndex, pData->wordarray);
+      break;
+    case FP_DEFAULTVALUE:
+      Field::SetDefaultValue(pFormFillEnv, pData->sFieldName,
+                             pData->nControlIndex, pData->widestring);
+      break;
+    case FP_DONOTSCROLL:
+      Field::SetDoNotScroll(pFormFillEnv, pData->sFieldName,
+                            pData->nControlIndex, pData->b);
+      break;
+    case FP_DISPLAY:
+      Field::SetDisplay(pFormFillEnv, pData->sFieldName, pData->nControlIndex,
+                        pData->num);
+      break;
+    case FP_FILLCOLOR:
+      Field::SetFillColor(pFormFillEnv, pData->sFieldName, pData->nControlIndex,
+                          pData->color);
+      break;
+    case FP_HIDDEN:
+      Field::SetHidden(pFormFillEnv, pData->sFieldName, pData->nControlIndex,
+                       pData->b);
+      break;
+    case FP_HIGHLIGHT:
+      Field::SetHighlight(pFormFillEnv, pData->sFieldName, pData->nControlIndex,
+                          pData->string);
+      break;
+    case FP_LINEWIDTH:
+      Field::SetLineWidth(pFormFillEnv, pData->sFieldName, pData->nControlIndex,
+                          pData->num);
+      break;
+    case FP_MULTILINE:
+      Field::SetMultiline(pFormFillEnv, pData->sFieldName, pData->nControlIndex,
+                          pData->b);
+      break;
+    case FP_MULTIPLESELECTION:
+      Field::SetMultipleSelection(pFormFillEnv, pData->sFieldName,
+                                  pData->nControlIndex, pData->b);
+      break;
+    case FP_PASSWORD:
+      Field::SetPassword(pFormFillEnv, pData->sFieldName, pData->nControlIndex,
+                         pData->b);
+      break;
+    case FP_RECT:
+      Field::SetRect(pFormFillEnv, pData->sFieldName, pData->nControlIndex,
+                     pData->rect);
+      break;
+    case FP_RICHTEXT:
+      // Not supported.
+      break;
+    case FP_RICHVALUE:
+      break;
+    case FP_ROTATION:
+      Field::SetRotation(pFormFillEnv, pData->sFieldName, pData->nControlIndex,
+                         pData->num);
+      break;
+    case FP_STROKECOLOR:
+      Field::SetStrokeColor(pFormFillEnv, pData->sFieldName,
+                            pData->nControlIndex, pData->color);
+      break;
+    case FP_STYLE:
+      Field::SetStyle(pFormFillEnv, pData->sFieldName, pData->nControlIndex,
+                      pData->string);
+      break;
+    case FP_TEXTCOLOR:
+      Field::SetTextColor(pFormFillEnv, pData->sFieldName, pData->nControlIndex,
+                          pData->color);
+      break;
+    case FP_TEXTFONT:
+      Field::SetTextFont(pFormFillEnv, pData->sFieldName, pData->nControlIndex,
+                         pData->string);
+      break;
+    case FP_TEXTSIZE:
+      Field::SetTextSize(pFormFillEnv, pData->sFieldName, pData->nControlIndex,
+                         pData->num);
+      break;
+    case FP_USERNAME:
+      Field::SetUserName(pFormFillEnv, pData->sFieldName, pData->nControlIndex,
+                         pData->widestring);
+      break;
+    case FP_VALUE:
+      Field::SetValue(pFormFillEnv, pData->sFieldName, pData->nControlIndex,
+                      pData->widestringarray);
+      break;
+  }
+}
+
+void Field::AddField(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                     int nPageIndex,
+                     int nFieldType,
+                     const CFX_WideString& sName,
+                     const CFX_FloatRect& rcCoords) {
+  // Not supported.
+}
diff --git a/fpdfsdk/javascript/Field.h b/fpdfsdk/javascript/Field.h
new file mode 100644
index 0000000..f3948ff
--- /dev/null
+++ b/fpdfsdk/javascript/Field.h
@@ -0,0 +1,540 @@
+// 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_JAVASCRIPT_FIELD_H_
+#define FPDFSDK_JAVASCRIPT_FIELD_H_
+
+#include <string>
+#include <vector>
+
+#include "core/fxcrt/cfx_observable.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/javascript/JS_Define.h"
+#include "fpdfsdk/pdfwindow/PWL_Wnd.h"  // For CPWL_Color.
+
+class CPDFSDK_Widget;
+class Document;
+
+enum FIELD_PROP {
+  FP_ALIGNMENT,
+  FP_BORDERSTYLE,
+  FP_BUTTONALIGNX,
+  FP_BUTTONALIGNY,
+  FP_BUTTONFITBOUNDS,
+  FP_BUTTONPOSITION,
+  FP_BUTTONSCALEHOW,
+  FP_BUTTONSCALEWHEN,
+  FP_CALCORDERINDEX,
+  FP_CHARLIMIT,
+  FP_COMB,
+  FP_COMMITONSELCHANGE,
+  FP_CURRENTVALUEINDICES,
+  FP_DEFAULTVALUE,
+  FP_DONOTSCROLL,
+  FP_DISPLAY,
+  FP_FILLCOLOR,
+  FP_HIDDEN,
+  FP_HIGHLIGHT,
+  FP_LINEWIDTH,
+  FP_MULTILINE,
+  FP_MULTIPLESELECTION,
+  FP_PASSWORD,
+  FP_RECT,
+  FP_RICHTEXT,
+  FP_RICHVALUE,
+  FP_ROTATION,
+  FP_STROKECOLOR,
+  FP_STYLE,
+  FP_TEXTCOLOR,
+  FP_TEXTFONT,
+  FP_TEXTSIZE,
+  FP_USERNAME,
+  FP_VALUE
+};
+
+struct CJS_DelayData {
+  CJS_DelayData(FIELD_PROP prop, int idx, const CFX_WideString& name);
+  ~CJS_DelayData();
+
+  FIELD_PROP eProp;
+  int nControlIndex;
+  CFX_WideString sFieldName;
+  int32_t num;
+  bool b;
+  CFX_ByteString string;
+  CFX_WideString widestring;
+  CFX_FloatRect rect;
+  CPWL_Color color;
+  std::vector<uint32_t> wordarray;
+  std::vector<CFX_WideString> widestringarray;
+};
+
+class Field : public CJS_EmbedObj {
+ public:
+  explicit Field(CJS_Object* pJSObject);
+  ~Field() override;
+
+  bool alignment(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool borderStyle(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool buttonAlignX(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool buttonAlignY(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool buttonFitBounds(IJS_Context* cc,
+                       CJS_PropValue& vp,
+                       CFX_WideString& sError);
+  bool buttonPosition(IJS_Context* cc,
+                      CJS_PropValue& vp,
+                      CFX_WideString& sError);
+  bool buttonScaleHow(IJS_Context* cc,
+                      CJS_PropValue& vp,
+                      CFX_WideString& sError);
+  bool buttonScaleWhen(IJS_Context* cc,
+                       CJS_PropValue& vp,
+                       CFX_WideString& sError);
+  bool calcOrderIndex(IJS_Context* cc,
+                      CJS_PropValue& vp,
+                      CFX_WideString& sError);
+  bool charLimit(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool comb(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool commitOnSelChange(IJS_Context* cc,
+                         CJS_PropValue& vp,
+                         CFX_WideString& sError);
+  bool currentValueIndices(IJS_Context* cc,
+                           CJS_PropValue& vp,
+                           CFX_WideString& sError);
+  bool defaultStyle(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool defaultValue(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool doNotScroll(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool doNotSpellCheck(IJS_Context* cc,
+                       CJS_PropValue& vp,
+                       CFX_WideString& sError);
+  bool delay(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool display(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool doc(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool editable(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool exportValues(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool fileSelect(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool fillColor(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool hidden(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool highlight(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool lineWidth(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool multiline(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool multipleSelection(IJS_Context* cc,
+                         CJS_PropValue& vp,
+                         CFX_WideString& sError);
+  bool name(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool numItems(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool page(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool password(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool print(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool radiosInUnison(IJS_Context* cc,
+                      CJS_PropValue& vp,
+                      CFX_WideString& sError);
+  bool readonly(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool rect(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool required(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool richText(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool richValue(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool rotation(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool strokeColor(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool style(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool submitName(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool textColor(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool textFont(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool textSize(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool type(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool userName(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool value(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool valueAsString(IJS_Context* cc,
+                     CJS_PropValue& vp,
+                     CFX_WideString& sError);
+  bool source(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+
+  bool browseForFileToSubmit(IJS_Context* cc,
+                             const std::vector<CJS_Value>& params,
+                             CJS_Value& vRet,
+                             CFX_WideString& sError);
+  bool buttonGetCaption(IJS_Context* cc,
+                        const std::vector<CJS_Value>& params,
+                        CJS_Value& vRet,
+                        CFX_WideString& sError);
+  bool buttonGetIcon(IJS_Context* cc,
+                     const std::vector<CJS_Value>& params,
+                     CJS_Value& vRet,
+                     CFX_WideString& sError);
+  bool buttonImportIcon(IJS_Context* cc,
+                        const std::vector<CJS_Value>& params,
+                        CJS_Value& vRet,
+                        CFX_WideString& sError);
+  bool buttonSetCaption(IJS_Context* cc,
+                        const std::vector<CJS_Value>& params,
+                        CJS_Value& vRet,
+                        CFX_WideString& sError);
+  bool buttonSetIcon(IJS_Context* cc,
+                     const std::vector<CJS_Value>& params,
+                     CJS_Value& vRet,
+                     CFX_WideString& sError);
+  bool checkThisBox(IJS_Context* cc,
+                    const std::vector<CJS_Value>& params,
+                    CJS_Value& vRet,
+                    CFX_WideString& sError);
+  bool clearItems(IJS_Context* cc,
+                  const std::vector<CJS_Value>& params,
+                  CJS_Value& vRet,
+                  CFX_WideString& sError);
+  bool defaultIsChecked(IJS_Context* cc,
+                        const std::vector<CJS_Value>& params,
+                        CJS_Value& vRet,
+                        CFX_WideString& sError);
+  bool deleteItemAt(IJS_Context* cc,
+                    const std::vector<CJS_Value>& params,
+                    CJS_Value& vRet,
+                    CFX_WideString& sError);
+  bool getArray(IJS_Context* cc,
+                const std::vector<CJS_Value>& params,
+                CJS_Value& vRet,
+                CFX_WideString& sError);
+  bool getItemAt(IJS_Context* cc,
+                 const std::vector<CJS_Value>& params,
+                 CJS_Value& vRet,
+                 CFX_WideString& sError);
+  bool getLock(IJS_Context* cc,
+               const std::vector<CJS_Value>& params,
+               CJS_Value& vRet,
+               CFX_WideString& sError);
+  bool insertItemAt(IJS_Context* cc,
+                    const std::vector<CJS_Value>& params,
+                    CJS_Value& vRet,
+                    CFX_WideString& sError);
+  bool isBoxChecked(IJS_Context* cc,
+                    const std::vector<CJS_Value>& params,
+                    CJS_Value& vRet,
+                    CFX_WideString& sError);
+  bool isDefaultChecked(IJS_Context* cc,
+                        const std::vector<CJS_Value>& params,
+                        CJS_Value& vRet,
+                        CFX_WideString& sError);
+  bool setAction(IJS_Context* cc,
+                 const std::vector<CJS_Value>& params,
+                 CJS_Value& vRet,
+                 CFX_WideString& sError);
+  bool setFocus(IJS_Context* cc,
+                const std::vector<CJS_Value>& params,
+                CJS_Value& vRet,
+                CFX_WideString& sError);
+  bool setItems(IJS_Context* cc,
+                const std::vector<CJS_Value>& params,
+                CJS_Value& vRet,
+                CFX_WideString& sError);
+  bool setLock(IJS_Context* cc,
+               const std::vector<CJS_Value>& params,
+               CJS_Value& vRet,
+               CFX_WideString& sError);
+  bool signatureGetModifications(IJS_Context* cc,
+                                 const std::vector<CJS_Value>& params,
+                                 CJS_Value& vRet,
+                                 CFX_WideString& sError);
+  bool signatureGetSeedValue(IJS_Context* cc,
+                             const std::vector<CJS_Value>& params,
+                             CJS_Value& vRet,
+                             CFX_WideString& sError);
+  bool signatureInfo(IJS_Context* cc,
+                     const std::vector<CJS_Value>& params,
+                     CJS_Value& vRet,
+                     CFX_WideString& sError);
+  bool signatureSetSeedValue(IJS_Context* cc,
+                             const std::vector<CJS_Value>& params,
+                             CJS_Value& vRet,
+                             CFX_WideString& sError);
+  bool signatureSign(IJS_Context* cc,
+                     const std::vector<CJS_Value>& params,
+                     CJS_Value& vRet,
+                     CFX_WideString& sError);
+  bool signatureValidate(IJS_Context* cc,
+                         const std::vector<CJS_Value>& params,
+                         CJS_Value& vRet,
+                         CFX_WideString& sError);
+
+  static void SetAlignment(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                           const CFX_WideString& swFieldName,
+                           int nControlIndex,
+                           const CFX_ByteString& string);
+  static void SetBorderStyle(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                             const CFX_WideString& swFieldName,
+                             int nControlIndex,
+                             const CFX_ByteString& string);
+  static void SetButtonAlignX(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                              const CFX_WideString& swFieldName,
+                              int nControlIndex,
+                              int number);
+  static void SetButtonAlignY(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                              const CFX_WideString& swFieldName,
+                              int nControlIndex,
+                              int number);
+  static void SetButtonFitBounds(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                                 const CFX_WideString& swFieldName,
+                                 int nControlIndex,
+                                 bool b);
+  static void SetButtonPosition(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                                const CFX_WideString& swFieldName,
+                                int nControlIndex,
+                                int number);
+  static void SetButtonScaleHow(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                                const CFX_WideString& swFieldName,
+                                int nControlIndex,
+                                int number);
+  static void SetButtonScaleWhen(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                                 const CFX_WideString& swFieldName,
+                                 int nControlIndex,
+                                 int number);
+  static void SetCalcOrderIndex(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                                const CFX_WideString& swFieldName,
+                                int nControlIndex,
+                                int number);
+  static void SetCharLimit(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                           const CFX_WideString& swFieldName,
+                           int nControlIndex,
+                           int number);
+  static void SetComb(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                      const CFX_WideString& swFieldName,
+                      int nControlIndex,
+                      bool b);
+  static void SetCommitOnSelChange(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                                   const CFX_WideString& swFieldName,
+                                   int nControlIndex,
+                                   bool b);
+  static void SetCurrentValueIndices(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                                     const CFX_WideString& swFieldName,
+                                     int nControlIndex,
+                                     const std::vector<uint32_t>& array);
+  static void SetDefaultStyle(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                              const CFX_WideString& swFieldName,
+                              int nControlIndex);
+  static void SetDefaultValue(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                              const CFX_WideString& swFieldName,
+                              int nControlIndex,
+                              const CFX_WideString& string);
+  static void SetDoNotScroll(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                             const CFX_WideString& swFieldName,
+                             int nControlIndex,
+                             bool b);
+  static void SetDisplay(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                         const CFX_WideString& swFieldName,
+                         int nControlIndex,
+                         int number);
+  static void SetFillColor(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                           const CFX_WideString& swFieldName,
+                           int nControlIndex,
+                           const CPWL_Color& color);
+  static void SetHidden(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                        const CFX_WideString& swFieldName,
+                        int nControlIndex,
+                        bool b);
+  static void SetHighlight(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                           const CFX_WideString& swFieldName,
+                           int nControlIndex,
+                           const CFX_ByteString& string);
+  static void SetLineWidth(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                           const CFX_WideString& swFieldName,
+                           int nControlIndex,
+                           int number);
+  static void SetMultiline(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                           const CFX_WideString& swFieldName,
+                           int nControlIndex,
+                           bool b);
+  static void SetMultipleSelection(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                                   const CFX_WideString& swFieldName,
+                                   int nControlIndex,
+                                   bool b);
+  static void SetPassword(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                          const CFX_WideString& swFieldName,
+                          int nControlIndex,
+                          bool b);
+  static void SetRect(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                      const CFX_WideString& swFieldName,
+                      int nControlIndex,
+                      const CFX_FloatRect& rect);
+  static void SetRotation(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                          const CFX_WideString& swFieldName,
+                          int nControlIndex,
+                          int number);
+  static void SetStrokeColor(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                             const CFX_WideString& swFieldName,
+                             int nControlIndex,
+                             const CPWL_Color& color);
+  static void SetStyle(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                       const CFX_WideString& swFieldName,
+                       int nControlIndex,
+                       const CFX_ByteString& string);
+  static void SetTextColor(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                           const CFX_WideString& swFieldName,
+                           int nControlIndex,
+                           const CPWL_Color& color);
+  static void SetTextFont(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                          const CFX_WideString& swFieldName,
+                          int nControlIndex,
+                          const CFX_ByteString& string);
+  static void SetTextSize(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                          const CFX_WideString& swFieldName,
+                          int nControlIndex,
+                          int number);
+  static void SetUserName(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                          const CFX_WideString& swFieldName,
+                          int nControlIndex,
+                          const CFX_WideString& string);
+  static void SetValue(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                       const CFX_WideString& swFieldName,
+                       int nControlIndex,
+                       const std::vector<CFX_WideString>& strArray);
+
+  static void AddField(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                       int nPageIndex,
+                       int nFieldType,
+                       const CFX_WideString& sName,
+                       const CFX_FloatRect& rcCoords);
+
+  static void UpdateFormField(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                              CPDF_FormField* pFormField,
+                              bool bChangeMark,
+                              bool bResetAP,
+                              bool bRefresh);
+  static void UpdateFormControl(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                                CPDF_FormControl* pFormControl,
+                                bool bChangeMark,
+                                bool bResetAP,
+                                bool bRefresh);
+
+  static CPDFSDK_Widget* GetWidget(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                                   CPDF_FormControl* pFormControl);
+  static std::vector<CPDF_FormField*> GetFormFields(
+      CPDFSDK_FormFillEnvironment* pFormFillEnv,
+      const CFX_WideString& csFieldName);
+
+  static void DoDelay(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                      CJS_DelayData* pData);
+
+  bool AttachField(Document* pDocument, const CFX_WideString& csFieldName);
+  void SetDelay(bool bDelay);
+
+ protected:
+  void ParseFieldName(const std::wstring& strFieldNameParsed,
+                      std::wstring& strFieldName,
+                      int& iControlNo);
+  std::vector<CPDF_FormField*> GetFormFields(
+      const CFX_WideString& csFieldName) const;
+  CPDF_FormControl* GetSmartFieldControl(CPDF_FormField* pFormField);
+  bool ValueIsOccur(CPDF_FormField* pFormField, CFX_WideString csOptLabel);
+
+  void AddDelay_Int(FIELD_PROP prop, int32_t n);
+  void AddDelay_Bool(FIELD_PROP prop, bool b);
+  void AddDelay_String(FIELD_PROP prop, const CFX_ByteString& string);
+  void AddDelay_WideString(FIELD_PROP prop, const CFX_WideString& string);
+  void AddDelay_Rect(FIELD_PROP prop, const CFX_FloatRect& rect);
+  void AddDelay_Color(FIELD_PROP prop, const CPWL_Color& color);
+  void AddDelay_WordArray(FIELD_PROP prop, const std::vector<uint32_t>& array);
+  void AddDelay_WideStringArray(FIELD_PROP prop,
+                                const std::vector<CFX_WideString>& array);
+
+  void DoDelay();
+
+ public:
+  Document* m_pJSDoc;
+  CPDFSDK_FormFillEnvironment::ObservedPtr m_pFormFillEnv;
+  CFX_WideString m_FieldName;
+  int m_nFormControlIndex;
+  bool m_bCanSet;
+  bool m_bDelay;
+};
+
+class CJS_Field : public CJS_Object {
+ public:
+  explicit CJS_Field(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_Field() override {}
+
+  void InitInstance(IJS_Runtime* pIRuntime) override;
+
+  DECLARE_JS_CLASS();
+  JS_STATIC_PROP(alignment, Field);
+  JS_STATIC_PROP(borderStyle, Field);
+  JS_STATIC_PROP(buttonAlignX, Field);
+  JS_STATIC_PROP(buttonAlignY, Field);
+  JS_STATIC_PROP(buttonFitBounds, Field);
+  JS_STATIC_PROP(buttonPosition, Field);
+  JS_STATIC_PROP(buttonScaleHow, Field);
+  JS_STATIC_PROP(buttonScaleWhen, Field);
+  JS_STATIC_PROP(calcOrderIndex, Field);
+  JS_STATIC_PROP(charLimit, Field);
+  JS_STATIC_PROP(comb, Field);
+  JS_STATIC_PROP(commitOnSelChange, Field);
+  JS_STATIC_PROP(currentValueIndices, Field);
+  JS_STATIC_PROP(defaultStyle, Field);
+  JS_STATIC_PROP(defaultValue, Field);
+  JS_STATIC_PROP(doNotScroll, Field);
+  JS_STATIC_PROP(doNotSpellCheck, Field);
+  JS_STATIC_PROP(delay, Field);
+  JS_STATIC_PROP(display, Field);
+  JS_STATIC_PROP(doc, Field);
+  JS_STATIC_PROP(editable, Field);
+  JS_STATIC_PROP(exportValues, Field);
+  JS_STATIC_PROP(fileSelect, Field);
+  JS_STATIC_PROP(fillColor, Field);
+  JS_STATIC_PROP(hidden, Field);
+  JS_STATIC_PROP(highlight, Field);
+  JS_STATIC_PROP(lineWidth, Field);
+  JS_STATIC_PROP(multiline, Field);
+  JS_STATIC_PROP(multipleSelection, Field);
+  JS_STATIC_PROP(name, Field);
+  JS_STATIC_PROP(numItems, Field);
+  JS_STATIC_PROP(page, Field);
+  JS_STATIC_PROP(password, Field);
+  JS_STATIC_PROP(print, Field);
+  JS_STATIC_PROP(radiosInUnison, Field);
+  JS_STATIC_PROP(readonly, Field);
+  JS_STATIC_PROP(rect, Field);
+  JS_STATIC_PROP(required, Field);
+  JS_STATIC_PROP(richText, Field);
+  JS_STATIC_PROP(richValue, Field);
+  JS_STATIC_PROP(rotation, Field);
+  JS_STATIC_PROP(strokeColor, Field);
+  JS_STATIC_PROP(style, Field);
+  JS_STATIC_PROP(submitName, Field);
+  JS_STATIC_PROP(textColor, Field);
+  JS_STATIC_PROP(textFont, Field);
+  JS_STATIC_PROP(textSize, Field);
+  JS_STATIC_PROP(type, Field);
+  JS_STATIC_PROP(userName, Field);
+  JS_STATIC_PROP(value, Field);
+  JS_STATIC_PROP(valueAsString, Field);
+  JS_STATIC_PROP(source, Field);
+
+  JS_STATIC_METHOD(browseForFileToSubmit, Field);
+  JS_STATIC_METHOD(buttonGetCaption, Field);
+  JS_STATIC_METHOD(buttonGetIcon, Field);
+  JS_STATIC_METHOD(buttonImportIcon, Field);
+  JS_STATIC_METHOD(buttonSetCaption, Field);
+  JS_STATIC_METHOD(buttonSetIcon, Field);
+  JS_STATIC_METHOD(checkThisBox, Field);
+  JS_STATIC_METHOD(clearItems, Field);
+  JS_STATIC_METHOD(defaultIsChecked, Field);
+  JS_STATIC_METHOD(deleteItemAt, Field);
+  JS_STATIC_METHOD(getArray, Field);
+  JS_STATIC_METHOD(getItemAt, Field);
+  JS_STATIC_METHOD(getLock, Field);
+  JS_STATIC_METHOD(insertItemAt, Field);
+  JS_STATIC_METHOD(isBoxChecked, Field);
+  JS_STATIC_METHOD(isDefaultChecked, Field);
+  JS_STATIC_METHOD(setAction, Field);
+  JS_STATIC_METHOD(setFocus, Field);
+  JS_STATIC_METHOD(setItems, Field);
+  JS_STATIC_METHOD(setLock, Field);
+  JS_STATIC_METHOD(signatureGetModifications, Field);
+  JS_STATIC_METHOD(signatureGetSeedValue, Field);
+  JS_STATIC_METHOD(signatureInfo, Field);
+  JS_STATIC_METHOD(signatureSetSeedValue, Field);
+  JS_STATIC_METHOD(signatureSign, Field);
+  JS_STATIC_METHOD(signatureValidate, Field);
+};
+
+#endif  // FPDFSDK_JAVASCRIPT_FIELD_H_
diff --git a/fpdfsdk/src/javascript/Icon.cpp b/fpdfsdk/javascript/Icon.cpp
similarity index 69%
rename from fpdfsdk/src/javascript/Icon.cpp
rename to fpdfsdk/javascript/Icon.cpp
index bce66c0..94841ef 100644
--- a/fpdfsdk/src/javascript/Icon.cpp
+++ b/fpdfsdk/javascript/Icon.cpp
@@ -4,14 +4,11 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#include "Icon.h"
+#include "fpdfsdk/javascript/Icon.h"
 
-#include "JS_Define.h"
-#include "JS_Object.h"
-#include "JS_Value.h"
-#include "fpdfsdk/include/javascript/IJavaScript.h"
-
-/* ---------------------- Icon ---------------------- */
+#include "fpdfsdk/javascript/JS_Define.h"
+#include "fpdfsdk/javascript/JS_Object.h"
+#include "fpdfsdk/javascript/JS_Value.h"
 
 BEGIN_JS_STATIC_CONST(CJS_Icon)
 END_JS_STATIC_CONST()
@@ -26,7 +23,7 @@
 IMPLEMENT_JS_CLASS(CJS_Icon, Icon)
 
 Icon::Icon(CJS_Object* pJSObject)
-    : CJS_EmbedObj(pJSObject), m_pIconStream(NULL), m_swIconName(L"") {}
+    : CJS_EmbedObj(pJSObject), m_pIconStream(nullptr), m_swIconName(L"") {}
 
 Icon::~Icon() {}
 
@@ -47,10 +44,10 @@
   return m_swIconName;
 }
 
-FX_BOOL Icon::name(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
+bool Icon::name(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
   if (!vp.IsGetting())
-    return FALSE;
+    return false;
 
   vp << m_swIconName;
-  return TRUE;
+  return true;
 }
diff --git a/fpdfsdk/src/javascript/Icon.h b/fpdfsdk/javascript/Icon.h
similarity index 64%
rename from fpdfsdk/src/javascript/Icon.h
rename to fpdfsdk/javascript/Icon.h
index 6ea3153..98a479c 100644
--- a/fpdfsdk/src/javascript/Icon.h
+++ b/fpdfsdk/javascript/Icon.h
@@ -4,17 +4,19 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#ifndef FPDFSDK_SRC_JAVASCRIPT_ICON_H_
-#define FPDFSDK_SRC_JAVASCRIPT_ICON_H_
+#ifndef FPDFSDK_JAVASCRIPT_ICON_H_
+#define FPDFSDK_JAVASCRIPT_ICON_H_
 
-#include "JS_Define.h"
+#include "fpdfsdk/javascript/JS_Define.h"
+
+class CPDF_Stream;
 
 class Icon : public CJS_EmbedObj {
  public:
-  Icon(CJS_Object* pJSObject);
+  explicit Icon(CJS_Object* pJSObject);
   ~Icon() override;
 
-  FX_BOOL name(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool name(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
   void SetStream(CPDF_Stream* pIconStream);
   CPDF_Stream* GetStream();
   void SetIconName(CFX_WideString name);
@@ -27,11 +29,11 @@
 
 class CJS_Icon : public CJS_Object {
  public:
-  CJS_Icon(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  explicit CJS_Icon(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
   ~CJS_Icon() override {}
 
   DECLARE_JS_CLASS();
   JS_STATIC_PROP(name, Icon);
 };
 
-#endif  // FPDFSDK_SRC_JAVASCRIPT_ICON_H_
+#endif  // FPDFSDK_JAVASCRIPT_ICON_H_
diff --git a/fpdfsdk/src/javascript/JS_Define.h b/fpdfsdk/javascript/JS_Define.h
similarity index 62%
rename from fpdfsdk/src/javascript/JS_Define.h
rename to fpdfsdk/javascript/JS_Define.h
index 02b36f9..feab4d1 100644
--- a/fpdfsdk/src/javascript/JS_Define.h
+++ b/fpdfsdk/javascript/JS_Define.h
@@ -4,19 +4,21 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#ifndef FPDFSDK_SRC_JAVASCRIPT_JS_DEFINE_H_
-#define FPDFSDK_SRC_JAVASCRIPT_JS_DEFINE_H_
+#ifndef FPDFSDK_JAVASCRIPT_JS_DEFINE_H_
+#define FPDFSDK_JAVASCRIPT_JS_DEFINE_H_
 
-#include "JS_Object.h"
-#include "JS_Value.h"
-#include "fpdfsdk/include/jsapi/fxjs_v8.h"
-#include "resource.h"
+#include <vector>
+
+#include "fpdfsdk/javascript/JS_Object.h"
+#include "fpdfsdk/javascript/JS_Value.h"
+#include "fpdfsdk/javascript/resource.h"
+#include "fxjs/fxjs_v8.h"
 
 struct JSConstSpec {
   const wchar_t* pName;
   double number;
-  const wchar_t* string;
-  uint8_t t;  // 0:double 1:str
+  const wchar_t* str;
+  uint8_t t;              // 0:double 1:str
 };
 
 struct JSPropertySpec {
@@ -44,21 +46,18 @@
 #define END_JS_STATIC_CONST() \
   { 0, 0, 0, 0 }              \
   }                           \
-  ;
+  ;  // NOLINT
 
 #define BEGIN_JS_STATIC_PROP(js_class_name) \
   JSPropertySpec js_class_name::JS_Class_Properties[] = {
-#define JS_STATIC_PROP_ENTRY(prop_name)                 \
-  {                                                     \
-    JS_WIDESTRING(prop_name), get_##prop_name##_static, \
-        set_##prop_name##_static                        \
-  }                                                     \
-  ,
+#define JS_STATIC_PROP_ENTRY(prop_name)                \
+  {JS_WIDESTRING(prop_name), get_##prop_name##_static, \
+   set_##prop_name##_static},  // NOLINT
 
 #define END_JS_STATIC_PROP() \
   { 0, 0, 0 }                \
   }                          \
-  ;
+  ;  // NOLINT
 
 #define BEGIN_JS_STATIC_METHOD(js_class_name) \
   JSMethodSpec js_class_name::JS_Class_Methods[] = {
@@ -69,54 +68,50 @@
 #define END_JS_STATIC_METHOD() \
   { 0, 0 }                     \
   }                            \
-  ;
+  ;  // NOLINT
 
-template <class C,
-          FX_BOOL (C::*M)(IJS_Context*, CJS_PropValue&, CFX_WideString&)>
+template <class C, bool (C::*M)(IJS_Context*, CJS_PropValue&, CFX_WideString&)>
 void JSPropGetter(const char* prop_name_string,
                   const char* class_name_string,
                   v8::Local<v8::String> property,
                   const v8::PropertyCallbackInfo<v8::Value>& info) {
-  v8::Isolate* isolate = info.GetIsolate();
   CJS_Runtime* pRuntime =
-      static_cast<CJS_Runtime*>(FXJS_GetRuntimeFromIsolate(isolate));
+      CJS_Runtime::CurrentRuntimeFromIsolate(info.GetIsolate());
   if (!pRuntime)
     return;
-  IJS_Context* pContext = pRuntime->GetCurrentContext();
-  CJS_Object* pJSObj = (CJS_Object*)FXJS_GetPrivate(isolate, info.Holder());
+  CJS_Object* pJSObj =
+      static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(info.Holder()));
   C* pObj = reinterpret_cast<C*>(pJSObj->GetEmbedObject());
   CFX_WideString sError;
   CJS_PropValue value(pRuntime);
   value.StartGetting();
-  if (!(pObj->*M)(pContext, value, sError)) {
-    FXJS_Error(isolate, JSFormatErrorString(class_name_string, prop_name_string,
-                                            sError));
+  if (!(pObj->*M)(pRuntime->GetCurrentContext(), value, sError)) {
+    pRuntime->Error(
+        JSFormatErrorString(class_name_string, prop_name_string, sError));
     return;
   }
-  info.GetReturnValue().Set((v8::Local<v8::Value>)value);
+  info.GetReturnValue().Set(value.GetJSValue()->ToV8Value(pRuntime));
 }
 
-template <class C,
-          FX_BOOL (C::*M)(IJS_Context*, CJS_PropValue&, CFX_WideString&)>
+template <class C, bool (C::*M)(IJS_Context*, CJS_PropValue&, CFX_WideString&)>
 void JSPropSetter(const char* prop_name_string,
                   const char* class_name_string,
                   v8::Local<v8::String> property,
                   v8::Local<v8::Value> value,
                   const v8::PropertyCallbackInfo<void>& info) {
-  v8::Isolate* isolate = info.GetIsolate();
   CJS_Runtime* pRuntime =
-      static_cast<CJS_Runtime*>(FXJS_GetRuntimeFromIsolate(isolate));
+      CJS_Runtime::CurrentRuntimeFromIsolate(info.GetIsolate());
   if (!pRuntime)
     return;
-  IJS_Context* pContext = pRuntime->GetCurrentContext();
-  CJS_Object* pJSObj = (CJS_Object*)FXJS_GetPrivate(isolate, info.Holder());
+  CJS_Object* pJSObj =
+      static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(info.Holder()));
   C* pObj = reinterpret_cast<C*>(pJSObj->GetEmbedObject());
   CFX_WideString sError;
-  CJS_PropValue propValue(CJS_Value(pRuntime, value, CJS_Value::VT_unknown));
+  CJS_PropValue propValue(pRuntime, CJS_Value(pRuntime, value));
   propValue.StartSetting();
-  if (!(pObj->*M)(pContext, propValue, sError)) {
-    FXJS_Error(isolate, JSFormatErrorString(class_name_string, prop_name_string,
-                                            sError));
+  if (!(pObj->*M)(pRuntime->GetCurrentContext(), propValue, sError)) {
+    pRuntime->Error(
+        JSFormatErrorString(class_name_string, prop_name_string, sError));
   }
 }
 
@@ -135,33 +130,33 @@
   }
 
 template <class C,
-          FX_BOOL (C::*M)(IJS_Context*,
-                          const std::vector<CJS_Value>&,
-                          CJS_Value&,
-                          CFX_WideString&)>
+          bool (C::*M)(IJS_Context*,
+                       const std::vector<CJS_Value>&,
+                       CJS_Value&,
+                       CFX_WideString&)>
 void JSMethod(const char* method_name_string,
               const char* class_name_string,
               const v8::FunctionCallbackInfo<v8::Value>& info) {
-  v8::Isolate* isolate = info.GetIsolate();
   CJS_Runtime* pRuntime =
-      static_cast<CJS_Runtime*>(FXJS_GetRuntimeFromIsolate(isolate));
+      CJS_Runtime::CurrentRuntimeFromIsolate(info.GetIsolate());
   if (!pRuntime)
     return;
-  IJS_Context* pContext = pRuntime->GetCurrentContext();
   std::vector<CJS_Value> parameters;
   for (unsigned int i = 0; i < (unsigned int)info.Length(); i++) {
-    parameters.push_back(CJS_Value(pRuntime, info[i], CJS_Value::VT_unknown));
+    parameters.push_back(CJS_Value(pRuntime, info[i]));
   }
-  CJS_Value valueRes(pRuntime);
-  CJS_Object* pJSObj = (CJS_Object*)FXJS_GetPrivate(isolate, info.Holder());
+  CJS_Object* pJSObj =
+      static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(info.Holder()));
   C* pObj = reinterpret_cast<C*>(pJSObj->GetEmbedObject());
   CFX_WideString sError;
-  if (!(pObj->*M)(pContext, parameters, valueRes, sError)) {
-    FXJS_Error(isolate, JSFormatErrorString(class_name_string,
-                                            method_name_string, sError));
+  CJS_Value valueRes(pRuntime);
+  if (!(pObj->*M)(pRuntime->GetCurrentContext(), parameters, valueRes,
+                  sError)) {
+    pRuntime->Error(
+        JSFormatErrorString(class_name_string, method_name_string, sError));
     return;
   }
-  info.GetReturnValue().Set(valueRes.ToV8Value());
+  info.GetReturnValue().Set(valueRes.ToV8Value(pRuntime));
 }
 
 #define JS_STATIC_METHOD(method_name, class_name)                             \
@@ -184,7 +179,7 @@
 #define DECLARE_JS_CLASS_BASE_PART()  \
   static const wchar_t* g_pClassName; \
   static int g_nObjDefnID;            \
-  static void DefineJSObjects(v8::Isolate* pIsolate, FXJSOBJTYPE eObjType);
+  static void DefineJSObjects(CFXJS_Engine* pEngine, FXJSOBJTYPE eObjType);
 
 #define IMPLEMENT_JS_CLASS_BASE_PART(js_class_name, class_name)           \
   const wchar_t* js_class_name::g_pClassName = JS_WIDESTRING(class_name); \
@@ -195,29 +190,29 @@
   DECLARE_JS_CLASS_BASE_PART()   \
   DECLARE_JS_CLASS_CONST_PART()
 
-#define IMPLEMENT_JS_CLASS_CONST(js_class_name, class_name)              \
-  IMPLEMENT_JS_CLASS_BASE_PART(js_class_name, class_name)                \
-  IMPLEMENT_JS_CLASS_CONST_PART(js_class_name, class_name)               \
-  void js_class_name::DefineJSObjects(v8::Isolate* pIsolate,             \
-                                      FXJSOBJTYPE eObjType) {            \
-    g_nObjDefnID = FXJS_DefineObj(pIsolate, js_class_name::g_pClassName, \
-                                  eObjType, nullptr, nullptr);           \
-    DefineConsts(pIsolate);                                              \
+#define IMPLEMENT_JS_CLASS_CONST(js_class_name, class_name)                  \
+  IMPLEMENT_JS_CLASS_BASE_PART(js_class_name, class_name)                    \
+  IMPLEMENT_JS_CLASS_CONST_PART(js_class_name, class_name)                   \
+  void js_class_name::DefineJSObjects(CFXJS_Engine* pEngine,                 \
+                                      FXJSOBJTYPE eObjType) {                \
+    g_nObjDefnID = pEngine->DefineObj(js_class_name::g_pClassName, eObjType, \
+                                      nullptr, nullptr);                     \
+    DefineConsts(pEngine);                                                   \
   }
 
 #define DECLARE_JS_CLASS_CONST_PART()   \
   static JSConstSpec JS_Class_Consts[]; \
-  static void DefineConsts(v8::Isolate* pIsolate);
+  static void DefineConsts(CFXJS_Engine* pEngine);
 
-#define IMPLEMENT_JS_CLASS_CONST_PART(js_class_name, class_name)      \
-  void js_class_name::DefineConsts(v8::Isolate* pIsolate) {           \
-    for (size_t i = 0; i < FX_ArraySize(JS_Class_Consts) - 1; ++i) {  \
-      FXJS_DefineObjConst(                                            \
-          pIsolate, g_nObjDefnID, JS_Class_Consts[i].pName,           \
-          JS_Class_Consts[i].t == 0                                   \
-              ? FXJS_NewNumber(pIsolate, JS_Class_Consts[i].number)   \
-              : FXJS_NewString(pIsolate, JS_Class_Consts[i].string)); \
-    }                                                                 \
+#define IMPLEMENT_JS_CLASS_CONST_PART(js_class_name, class_name)     \
+  void js_class_name::DefineConsts(CFXJS_Engine* pEngine) {          \
+    for (size_t i = 0; i < FX_ArraySize(JS_Class_Consts) - 1; ++i) { \
+      pEngine->DefineObjConst(                                       \
+          g_nObjDefnID, JS_Class_Consts[i].pName,                    \
+          JS_Class_Consts[i].t == 0                                  \
+              ? pEngine->NewNumber(JS_Class_Consts[i].number)        \
+              : pEngine->NewString(JS_Class_Consts[i].str));         \
+    }                                                                \
   }
 
 // Convenience macros for declaring classes without an alternate.
@@ -232,53 +227,54 @@
   DECLARE_JS_CLASS_CONST_PART() \
   DECLARE_JS_CLASS_RICH_PART()
 
-#define IMPLEMENT_JS_CLASS_RICH(js_class_name, class_alternate, class_name) \
-  IMPLEMENT_JS_CLASS_BASE_PART(js_class_name, class_name)                   \
-  IMPLEMENT_JS_CLASS_CONST_PART(js_class_name, class_name)                  \
-  IMPLEMENT_JS_CLASS_RICH_PART(js_class_name, class_alternate, class_name)  \
-  void js_class_name::DefineJSObjects(v8::Isolate* pIsolate,                \
-                                      FXJSOBJTYPE eObjType) {               \
-    g_nObjDefnID = FXJS_DefineObj(pIsolate, js_class_name::g_pClassName,    \
-                                  eObjType, JSConstructor, JSDestructor);   \
-    DefineConsts(pIsolate);                                                 \
-    DefineProps(pIsolate);                                                  \
-    DefineMethods(pIsolate);                                                \
+#define IMPLEMENT_JS_CLASS_RICH(js_class_name, class_alternate, class_name)  \
+  IMPLEMENT_JS_CLASS_BASE_PART(js_class_name, class_name)                    \
+  IMPLEMENT_JS_CLASS_CONST_PART(js_class_name, class_name)                   \
+  IMPLEMENT_JS_CLASS_RICH_PART(js_class_name, class_alternate, class_name)   \
+  void js_class_name::DefineJSObjects(CFXJS_Engine* pEngine,                 \
+                                      FXJSOBJTYPE eObjType) {                \
+    g_nObjDefnID = pEngine->DefineObj(js_class_name::g_pClassName, eObjType, \
+                                      JSConstructor, JSDestructor);          \
+    DefineConsts(pEngine);                                                   \
+    DefineProps(pEngine);                                                    \
+    DefineMethods(pEngine);                                                  \
   }
 
 #define DECLARE_JS_CLASS_RICH_PART()                                           \
-  static void JSConstructor(IJS_Runtime* pRuntime, v8::Local<v8::Object> obj); \
-  static void JSDestructor(v8::Local<v8::Object> obj);                         \
-  static void DefineProps(v8::Isolate* pIsoalte);                              \
-  static void DefineMethods(v8::Isolate* pIsoalte);                            \
+  static void JSConstructor(CFXJS_Engine* pEngine, v8::Local<v8::Object> obj); \
+  static void JSDestructor(CFXJS_Engine* pEngine, v8::Local<v8::Object> obj);  \
+  static void DefineProps(CFXJS_Engine* pEngine);                              \
+  static void DefineMethods(CFXJS_Engine* pEngine);                            \
   static JSPropertySpec JS_Class_Properties[];                                 \
   static JSMethodSpec JS_Class_Methods[];
 
-#define IMPLEMENT_JS_CLASS_RICH_PART(js_class_name, class_alternate,          \
-                                     class_name)                              \
-  void js_class_name::JSConstructor(IJS_Runtime* pIRuntime,                   \
-                                    v8::Local<v8::Object> obj) {              \
-    CJS_Object* pObj = new js_class_name(obj);                                \
-    pObj->SetEmbedObject(new class_alternate(pObj));                          \
-    FXJS_SetPrivate(nullptr, obj, (void*)pObj);                               \
-    pObj->InitInstance(pIRuntime);                                            \
-  }                                                                           \
-  void js_class_name::JSDestructor(v8::Local<v8::Object> obj) {               \
-    js_class_name* pObj = (js_class_name*)FXJS_GetPrivate(nullptr, obj);      \
-    pObj->ExitInstance();                                                     \
-    delete pObj;                                                              \
-  }                                                                           \
-  void js_class_name::DefineProps(v8::Isolate* pIsolate) {                    \
-    for (size_t i = 0; i < FX_ArraySize(JS_Class_Properties) - 1; ++i) {      \
-      FXJS_DefineObjProperty(                                                 \
-          pIsolate, g_nObjDefnID, JS_Class_Properties[i].pName,               \
-          JS_Class_Properties[i].pPropGet, JS_Class_Properties[i].pPropPut);  \
-    }                                                                         \
-  }                                                                           \
-  void js_class_name::DefineMethods(v8::Isolate* pIsolate) {                  \
-    for (size_t i = 0; i < FX_ArraySize(JS_Class_Methods) - 1; ++i) {         \
-      FXJS_DefineObjMethod(pIsolate, g_nObjDefnID, JS_Class_Methods[i].pName, \
-                           JS_Class_Methods[i].pMethodCall);                  \
-    }                                                                         \
+#define IMPLEMENT_JS_CLASS_RICH_PART(js_class_name, class_alternate,         \
+                                     class_name)                             \
+  void js_class_name::JSConstructor(CFXJS_Engine* pEngine,                   \
+                                    v8::Local<v8::Object> obj) {             \
+    CJS_Object* pObj = new js_class_name(obj);                               \
+    pObj->SetEmbedObject(new class_alternate(pObj));                         \
+    pEngine->SetObjectPrivate(obj, (void*)pObj);                             \
+    pObj->InitInstance(static_cast<CJS_Runtime*>(pEngine));                  \
+  }                                                                          \
+  void js_class_name::JSDestructor(CFXJS_Engine* pEngine,                    \
+                                   v8::Local<v8::Object> obj) {              \
+    js_class_name* pObj =                                                    \
+        static_cast<js_class_name*>(pEngine->GetObjectPrivate(obj));         \
+    delete pObj;                                                             \
+  }                                                                          \
+  void js_class_name::DefineProps(CFXJS_Engine* pEngine) {                   \
+    for (size_t i = 0; i < FX_ArraySize(JS_Class_Properties) - 1; ++i) {     \
+      pEngine->DefineObjProperty(g_nObjDefnID, JS_Class_Properties[i].pName, \
+                                 JS_Class_Properties[i].pPropGet,            \
+                                 JS_Class_Properties[i].pPropPut);           \
+    }                                                                        \
+  }                                                                          \
+  void js_class_name::DefineMethods(CFXJS_Engine* pEngine) {                 \
+    for (size_t i = 0; i < FX_ArraySize(JS_Class_Methods) - 1; ++i) {        \
+      pEngine->DefineObjMethod(g_nObjDefnID, JS_Class_Methods[i].pName,      \
+                               JS_Class_Methods[i].pMethodCall);             \
+    }                                                                        \
   }
 
 // Special JS classes implement methods, props, and queries, but not consts.
@@ -293,14 +289,14 @@
   IMPLEMENT_JS_CLASS_CONST_PART(js_class_name, class_name)                     \
   IMPLEMENT_JS_CLASS_RICH_PART(js_class_name, class_alternate, class_name)     \
   IMPLEMENT_SPECIAL_JS_CLASS_PART(js_class_name, class_alternate, class_name)  \
-  void js_class_name::DefineJSObjects(v8::Isolate* pIsolate,                   \
+  void js_class_name::DefineJSObjects(CFXJS_Engine* pEngine,                   \
                                       FXJSOBJTYPE eObjType) {                  \
-    g_nObjDefnID = FXJS_DefineObj(pIsolate, js_class_name::g_pClassName,       \
-                                  eObjType, JSConstructor, JSDestructor);      \
-    DefineConsts(pIsolate);                                                    \
-    DefineProps(pIsolate);                                                     \
-    DefineMethods(pIsolate);                                                   \
-    DefineAllProperties(pIsolate);                                             \
+    g_nObjDefnID = pEngine->DefineObj(js_class_name::g_pClassName, eObjType,   \
+                                      JSConstructor, JSDestructor);            \
+    DefineConsts(pEngine);                                                     \
+    DefineProps(pEngine);                                                      \
+    DefineMethods(pEngine);                                                    \
+    DefineAllProperties(pEngine);                                              \
   }
 
 #define DECLARE_SPECIAL_JS_CLASS_PART()                                        \
@@ -315,7 +311,7 @@
   static void delprop_static(                                                  \
       v8::Local<v8::String> property,                                          \
       const v8::PropertyCallbackInfo<v8::Boolean>& info);                      \
-  static void DefineAllProperties(v8::Isolate* pIsolate);
+  static void DefineAllProperties(CFXJS_Engine* pEngine);
 
 #define IMPLEMENT_SPECIAL_JS_CLASS_PART(js_class_name, class_alternate,    \
                                         class_name)                        \
@@ -339,9 +335,9 @@
       const v8::PropertyCallbackInfo<v8::Boolean>& info) {                 \
     JSSpecialPropDel<class_alternate>(#class_name, property, info);        \
   }                                                                        \
-  void js_class_name::DefineAllProperties(v8::Isolate* pIsolate) {         \
-    FXJS_DefineObjAllProperties(                                           \
-        pIsolate, g_nObjDefnID, js_class_name::queryprop_static,           \
+  void js_class_name::DefineAllProperties(CFXJS_Engine* pEngine) {         \
+    pEngine->DefineObjAllProperties(                                       \
+        g_nObjDefnID, js_class_name::queryprop_static,                     \
         js_class_name::getprop_static, js_class_name::putprop_static,      \
         js_class_name::delprop_static);                                    \
   }
@@ -350,14 +346,15 @@
 void JSSpecialPropQuery(const char*,
                         v8::Local<v8::String> property,
                         const v8::PropertyCallbackInfo<v8::Integer>& info) {
-  v8::Isolate* isolate = info.GetIsolate();
+  CJS_Runtime* pRuntime =
+      CJS_Runtime::CurrentRuntimeFromIsolate(info.GetIsolate());
   v8::String::Utf8Value utf8_value(property);
-  CFX_WideString propname =
-      CFX_WideString::FromUTF8(*utf8_value, utf8_value.length());
+  CFX_WideString propname = CFX_WideString::FromUTF8(
+      CFX_ByteStringC(*utf8_value, utf8_value.length()));
   CJS_Object* pJSObj =
-      reinterpret_cast<CJS_Object*>(FXJS_GetPrivate(isolate, info.Holder()));
+      static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(info.Holder()));
   Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject());
-  FX_BOOL bRet = pObj->QueryProperty(propname.c_str());
+  bool bRet = pObj->QueryProperty(propname.c_str());
   info.GetReturnValue().Set(bRet ? 4 : 0);
 }
 
@@ -365,26 +362,25 @@
 void JSSpecialPropGet(const char* class_name,
                       v8::Local<v8::String> property,
                       const v8::PropertyCallbackInfo<v8::Value>& info) {
-  v8::Isolate* isolate = info.GetIsolate();
   CJS_Runtime* pRuntime =
-      static_cast<CJS_Runtime*>(FXJS_GetRuntimeFromIsolate(isolate));
+      CJS_Runtime::CurrentRuntimeFromIsolate(info.GetIsolate());
   if (!pRuntime)
     return;
-  IJS_Context* pContext = pRuntime->GetCurrentContext();
   CJS_Object* pJSObj =
-      reinterpret_cast<CJS_Object*>(FXJS_GetPrivate(isolate, info.Holder()));
+      static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(info.Holder()));
   Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject());
   v8::String::Utf8Value utf8_value(property);
-  CFX_WideString propname =
-      CFX_WideString::FromUTF8(*utf8_value, utf8_value.length());
+  CFX_WideString propname = CFX_WideString::FromUTF8(
+      CFX_ByteStringC(*utf8_value, utf8_value.length()));
   CFX_WideString sError;
   CJS_PropValue value(pRuntime);
   value.StartGetting();
-  if (!pObj->DoProperty(pContext, propname.c_str(), value, sError)) {
-    FXJS_Error(isolate, JSFormatErrorString(class_name, "GetProperty", sError));
+  if (!pObj->DoProperty(pRuntime->GetCurrentContext(), propname.c_str(), value,
+                        sError)) {
+    pRuntime->Error(JSFormatErrorString(class_name, "GetProperty", sError));
     return;
   }
-  info.GetReturnValue().Set((v8::Local<v8::Value>)value);
+  info.GetReturnValue().Set(value.GetJSValue()->ToV8Value(pRuntime));
 }
 
 template <class Alt>
@@ -392,23 +388,22 @@
                       v8::Local<v8::String> property,
                       v8::Local<v8::Value> value,
                       const v8::PropertyCallbackInfo<v8::Value>& info) {
-  v8::Isolate* isolate = info.GetIsolate();
   CJS_Runtime* pRuntime =
-      static_cast<CJS_Runtime*>(FXJS_GetRuntimeFromIsolate(isolate));
+      CJS_Runtime::CurrentRuntimeFromIsolate(info.GetIsolate());
   if (!pRuntime)
     return;
-  IJS_Context* pContext = pRuntime->GetCurrentContext();
   CJS_Object* pJSObj =
-      reinterpret_cast<CJS_Object*>(FXJS_GetPrivate(isolate, info.Holder()));
+      static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(info.Holder()));
   Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject());
   v8::String::Utf8Value utf8_value(property);
-  CFX_WideString propname =
-      CFX_WideString::FromUTF8(*utf8_value, utf8_value.length());
+  CFX_WideString propname = CFX_WideString::FromUTF8(
+      CFX_ByteStringC(*utf8_value, utf8_value.length()));
   CFX_WideString sError;
-  CJS_PropValue PropValue(CJS_Value(pRuntime, value, CJS_Value::VT_unknown));
+  CJS_PropValue PropValue(pRuntime, CJS_Value(pRuntime, value));
   PropValue.StartSetting();
-  if (!pObj->DoProperty(pContext, propname.c_str(), PropValue, sError)) {
-    FXJS_Error(isolate, JSFormatErrorString(class_name, "PutProperty", sError));
+  if (!pObj->DoProperty(pRuntime->GetCurrentContext(), propname.c_str(),
+                        PropValue, sError)) {
+    pRuntime->Error(JSFormatErrorString(class_name, "PutProperty", sError));
   }
 }
 
@@ -416,48 +411,46 @@
 void JSSpecialPropDel(const char* class_name,
                       v8::Local<v8::String> property,
                       const v8::PropertyCallbackInfo<v8::Boolean>& info) {
-  v8::Isolate* isolate = info.GetIsolate();
-  IJS_Runtime* pRuntime = FXJS_GetRuntimeFromIsolate(isolate);
+  CJS_Runtime* pRuntime =
+      CJS_Runtime::CurrentRuntimeFromIsolate(info.GetIsolate());
   if (!pRuntime)
     return;
-  IJS_Context* pContext = pRuntime->GetCurrentContext();
   CJS_Object* pJSObj =
-      reinterpret_cast<CJS_Object*>(FXJS_GetPrivate(isolate, info.Holder()));
+      static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(info.Holder()));
   Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject());
   v8::String::Utf8Value utf8_value(property);
-  CFX_WideString propname =
-      CFX_WideString::FromUTF8(*utf8_value, utf8_value.length());
+  CFX_WideString propname = CFX_WideString::FromUTF8(
+      CFX_ByteStringC(*utf8_value, utf8_value.length()));
   CFX_WideString sError;
-  if (!pObj->DelProperty(pContext, propname.c_str(), sError)) {
+  if (!pObj->DelProperty(pRuntime->GetCurrentContext(), propname.c_str(),
+                         sError)) {
     CFX_ByteString cbName;
     cbName.Format("%s.%s", class_name, "DelProperty");
     // Probably a missing call to JSFX_Error().
   }
 }
 
-template <FX_BOOL (*F)(IJS_Context*,
-                       const std::vector<CJS_Value>&,
-                       CJS_Value&,
-                       CFX_WideString&)>
+template <bool (*F)(IJS_Context*,
+                    const std::vector<CJS_Value>&,
+                    CJS_Value&,
+                    CFX_WideString&)>
 void JSGlobalFunc(const char* func_name_string,
                   const v8::FunctionCallbackInfo<v8::Value>& info) {
   CJS_Runtime* pRuntime =
-      static_cast<CJS_Runtime*>(FXJS_GetRuntimeFromIsolate(info.GetIsolate()));
+      CJS_Runtime::CurrentRuntimeFromIsolate(info.GetIsolate());
   if (!pRuntime)
     return;
-  IJS_Context* pContext = pRuntime->GetCurrentContext();
   std::vector<CJS_Value> parameters;
   for (unsigned int i = 0; i < (unsigned int)info.Length(); i++) {
-    parameters.push_back(CJS_Value(pRuntime, info[i], CJS_Value::VT_unknown));
+    parameters.push_back(CJS_Value(pRuntime, info[i]));
   }
   CJS_Value valueRes(pRuntime);
   CFX_WideString sError;
-  if (!(*F)(pContext, parameters, valueRes, sError)) {
-    FXJS_Error(pRuntime->GetIsolate(),
-               JSFormatErrorString(func_name_string, nullptr, sError));
+  if (!(*F)(pRuntime->GetCurrentContext(), parameters, valueRes, sError)) {
+    pRuntime->Error(JSFormatErrorString(func_name_string, nullptr, sError));
     return;
   }
-  info.GetReturnValue().Set(valueRes.ToV8Value());
+  info.GetReturnValue().Set(valueRes.ToV8Value(pRuntime));
 }
 
 #define JS_STATIC_GLOBAL_FUN(fun_name)                   \
@@ -468,7 +461,7 @@
 
 #define JS_STATIC_DECLARE_GLOBAL_FUN()  \
   static JSMethodSpec global_methods[]; \
-  static void DefineJSObjects(v8::Isolate* pIsolate)
+  static void DefineJSObjects(CFXJS_Engine* pEngine)
 
 #define BEGIN_JS_STATIC_GLOBAL_FUN(js_class_name) \
   JSMethodSpec js_class_name::global_methods[] = {
@@ -477,15 +470,13 @@
 
 #define END_JS_STATIC_GLOBAL_FUN() END_JS_STATIC_METHOD()
 
-#define IMPLEMENT_JS_STATIC_GLOBAL_FUN(js_class_name)                        \
-  void js_class_name::DefineJSObjects(v8::Isolate* pIsolate) {               \
-    for (size_t i = 0; i < FX_ArraySize(global_methods) - 1; ++i) {          \
-      FXJS_DefineGlobalMethod(pIsolate,                                      \
-                              js_class_name::global_methods[i].pName,        \
-                              js_class_name::global_methods[i].pMethodCall); \
-    }                                                                        \
+#define IMPLEMENT_JS_STATIC_GLOBAL_FUN(js_class_name)               \
+  void js_class_name::DefineJSObjects(CFXJS_Engine* pEngine) {      \
+    for (size_t i = 0; i < FX_ArraySize(global_methods) - 1; ++i) { \
+      pEngine->DefineGlobalMethod(                                  \
+          js_class_name::global_methods[i].pName,                   \
+          js_class_name::global_methods[i].pMethodCall);            \
+    }                                                               \
   }
 
-CJS_Value::Type GET_VALUE_TYPE(v8::Local<v8::Value> p);
-
-#endif  // FPDFSDK_SRC_JAVASCRIPT_JS_DEFINE_H_
+#endif  // FPDFSDK_JAVASCRIPT_JS_DEFINE_H_
diff --git a/fpdfsdk/src/javascript/JS_EventHandler.cpp b/fpdfsdk/javascript/JS_EventHandler.cpp
similarity index 64%
rename from fpdfsdk/src/javascript/JS_EventHandler.cpp
rename to fpdfsdk/javascript/JS_EventHandler.cpp
index e413166..5715cb9 100644
--- a/fpdfsdk/src/javascript/JS_EventHandler.cpp
+++ b/fpdfsdk/javascript/JS_EventHandler.cpp
@@ -4,41 +4,37 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#include "JS_EventHandler.h"
+#include "fpdfsdk/javascript/JS_EventHandler.h"
 
-#include "Document.h"
-#include "Field.h"
-#include "JS_Context.h"
-#include "JS_Define.h"
-#include "JS_Object.h"
-#include "JS_Runtime.h"
-#include "JS_Value.h"
-#include "fpdfsdk/include/javascript/IJavaScript.h"
-
-/* ---------------------------- CJS_EventHandler ---------------------------- */
+#include "fpdfsdk/javascript/Document.h"
+#include "fpdfsdk/javascript/Field.h"
+#include "fpdfsdk/javascript/JS_Define.h"
+#include "fpdfsdk/javascript/JS_Object.h"
+#include "fpdfsdk/javascript/JS_Value.h"
+#include "fpdfsdk/javascript/cjs_context.h"
+#include "fpdfsdk/javascript/cjs_runtime.h"
 
 CJS_EventHandler::CJS_EventHandler(CJS_Context* pContext)
     : m_pJSContext(pContext),
       m_eEventType(JET_UNKNOWN),
-      m_bValid(FALSE),
-      m_pWideStrChange(NULL),
+      m_bValid(false),
+      m_pWideStrChange(nullptr),
       m_nCommitKey(-1),
-      m_bKeyDown(FALSE),
-      m_bModifier(FALSE),
-      m_bShift(FALSE),
-      m_pISelEnd(NULL),
+      m_bKeyDown(false),
+      m_bModifier(false),
+      m_bShift(false),
+      m_pISelEnd(nullptr),
       m_nSelEndDu(0),
-      m_pISelStart(NULL),
+      m_pISelStart(nullptr),
       m_nSelStartDu(0),
-      m_bWillCommit(FALSE),
-      m_pValue(NULL),
-      m_bFieldFull(FALSE),
-      m_pbRc(NULL),
-      m_bRcDu(FALSE),
-      m_pSourceDoc(NULL),
-      m_pTargetBookMark(NULL),
-      m_pTargetDoc(NULL),
-      m_pTargetAnnot(NULL) {}
+      m_bWillCommit(false),
+      m_pValue(nullptr),
+      m_bFieldFull(false),
+      m_pbRc(nullptr),
+      m_bRcDu(false),
+      m_pTargetBookMark(nullptr),
+      m_pTargetFormFillEnv(nullptr),
+      m_pTargetAnnot(nullptr) {}
 
 CJS_EventHandler::~CJS_EventHandler() {}
 
@@ -46,69 +42,67 @@
   Initial(JET_APP_INIT);
 }
 
-void CJS_EventHandler::OnDoc_Open(CPDFSDK_Document* pDoc,
+void CJS_EventHandler::OnDoc_Open(CPDFSDK_FormFillEnvironment* pFormFillEnv,
                                   const CFX_WideString& strTargetName) {
   Initial(JET_DOC_OPEN);
-
-  m_pTargetDoc = pDoc;
+  m_pTargetFormFillEnv = pFormFillEnv;
   m_strTargetName = strTargetName;
 }
 
-void CJS_EventHandler::OnDoc_WillPrint(CPDFSDK_Document* pDoc) {
+void CJS_EventHandler::OnDoc_WillPrint(
+    CPDFSDK_FormFillEnvironment* pFormFillEnv) {
   Initial(JET_DOC_WILLPRINT);
-
-  m_pTargetDoc = pDoc;
+  m_pTargetFormFillEnv = pFormFillEnv;
 }
 
-void CJS_EventHandler::OnDoc_DidPrint(CPDFSDK_Document* pDoc) {
+void CJS_EventHandler::OnDoc_DidPrint(
+    CPDFSDK_FormFillEnvironment* pFormFillEnv) {
   Initial(JET_DOC_DIDPRINT);
-
-  m_pTargetDoc = pDoc;
+  m_pTargetFormFillEnv = pFormFillEnv;
 }
 
-void CJS_EventHandler::OnDoc_WillSave(CPDFSDK_Document* pDoc) {
+void CJS_EventHandler::OnDoc_WillSave(
+    CPDFSDK_FormFillEnvironment* pFormFillEnv) {
   Initial(JET_DOC_WILLSAVE);
-  m_pTargetDoc = pDoc;
+  m_pTargetFormFillEnv = pFormFillEnv;
 }
 
-void CJS_EventHandler::OnDoc_DidSave(CPDFSDK_Document* pDoc) {
+void CJS_EventHandler::OnDoc_DidSave(
+    CPDFSDK_FormFillEnvironment* pFormFillEnv) {
   Initial(JET_DOC_DIDSAVE);
-
-  m_pTargetDoc = pDoc;
+  m_pTargetFormFillEnv = pFormFillEnv;
 }
 
-void CJS_EventHandler::OnDoc_WillClose(CPDFSDK_Document* pDoc) {
+void CJS_EventHandler::OnDoc_WillClose(
+    CPDFSDK_FormFillEnvironment* pFormFillEnv) {
   Initial(JET_DOC_WILLCLOSE);
-
-  m_pTargetDoc = pDoc;
+  m_pTargetFormFillEnv = pFormFillEnv;
 }
 
-void CJS_EventHandler::OnPage_Open(CPDFSDK_Document* pDoc) {
+void CJS_EventHandler::OnPage_Open(CPDFSDK_FormFillEnvironment* pFormFillEnv) {
   Initial(JET_PAGE_OPEN);
-
-  m_pTargetDoc = pDoc;
+  m_pTargetFormFillEnv = pFormFillEnv;
 }
 
-void CJS_EventHandler::OnPage_Close(CPDFSDK_Document* pDoc) {
+void CJS_EventHandler::OnPage_Close(CPDFSDK_FormFillEnvironment* pFormFillEnv) {
   Initial(JET_PAGE_CLOSE);
-
-  m_pTargetDoc = pDoc;
+  m_pTargetFormFillEnv = pFormFillEnv;
 }
 
-void CJS_EventHandler::OnPage_InView(CPDFSDK_Document* pDoc) {
+void CJS_EventHandler::OnPage_InView(
+    CPDFSDK_FormFillEnvironment* pFormFillEnv) {
   Initial(JET_PAGE_INVIEW);
-
-  m_pTargetDoc = pDoc;
+  m_pTargetFormFillEnv = pFormFillEnv;
 }
 
-void CJS_EventHandler::OnPage_OutView(CPDFSDK_Document* pDoc) {
+void CJS_EventHandler::OnPage_OutView(
+    CPDFSDK_FormFillEnvironment* pFormFillEnv) {
   Initial(JET_PAGE_OUTVIEW);
-
-  m_pTargetDoc = pDoc;
+  m_pTargetFormFillEnv = pFormFillEnv;
 }
 
-void CJS_EventHandler::OnField_MouseEnter(FX_BOOL bModifier,
-                                          FX_BOOL bShift,
+void CJS_EventHandler::OnField_MouseEnter(bool bModifier,
+                                          bool bShift,
                                           CPDF_FormField* pTarget) {
   Initial(JET_FIELD_MOUSEENTER);
 
@@ -118,8 +112,8 @@
   m_strTargetName = pTarget->GetFullName();
 }
 
-void CJS_EventHandler::OnField_MouseExit(FX_BOOL bModifier,
-                                         FX_BOOL bShift,
+void CJS_EventHandler::OnField_MouseExit(bool bModifier,
+                                         bool bShift,
                                          CPDF_FormField* pTarget) {
   Initial(JET_FIELD_MOUSEEXIT);
 
@@ -128,8 +122,8 @@
   m_strTargetName = pTarget->GetFullName();
 }
 
-void CJS_EventHandler::OnField_MouseDown(FX_BOOL bModifier,
-                                         FX_BOOL bShift,
+void CJS_EventHandler::OnField_MouseDown(bool bModifier,
+                                         bool bShift,
                                          CPDF_FormField* pTarget) {
   Initial(JET_FIELD_MOUSEDOWN);
   m_eEventType = JET_FIELD_MOUSEDOWN;
@@ -139,8 +133,8 @@
   m_strTargetName = pTarget->GetFullName();
 }
 
-void CJS_EventHandler::OnField_MouseUp(FX_BOOL bModifier,
-                                       FX_BOOL bShift,
+void CJS_EventHandler::OnField_MouseUp(bool bModifier,
+                                       bool bShift,
                                        CPDF_FormField* pTarget) {
   Initial(JET_FIELD_MOUSEUP);
 
@@ -149,8 +143,8 @@
   m_strTargetName = pTarget->GetFullName();
 }
 
-void CJS_EventHandler::OnField_Focus(FX_BOOL bModifier,
-                                     FX_BOOL bShift,
+void CJS_EventHandler::OnField_Focus(bool bModifier,
+                                     bool bShift,
                                      CPDF_FormField* pTarget,
                                      const CFX_WideString& Value) {
   Initial(JET_FIELD_FOCUS);
@@ -161,8 +155,8 @@
   m_pValue = (CFX_WideString*)&Value;
 }
 
-void CJS_EventHandler::OnField_Blur(FX_BOOL bModifier,
-                                    FX_BOOL bShift,
+void CJS_EventHandler::OnField_Blur(bool bModifier,
+                                    bool bShift,
                                     CPDF_FormField* pTarget,
                                     const CFX_WideString& Value) {
   Initial(JET_FIELD_BLUR);
@@ -175,16 +169,16 @@
 
 void CJS_EventHandler::OnField_Keystroke(CFX_WideString& strChange,
                                          const CFX_WideString& strChangeEx,
-                                         FX_BOOL KeyDown,
-                                         FX_BOOL bModifier,
+                                         bool KeyDown,
+                                         bool bModifier,
                                          int& nSelEnd,
                                          int& nSelStart,
-                                         FX_BOOL bShift,
+                                         bool bShift,
                                          CPDF_FormField* pTarget,
                                          CFX_WideString& Value,
-                                         FX_BOOL bWillCommit,
-                                         FX_BOOL bFieldFull,
-                                         FX_BOOL& bRc) {
+                                         bool bWillCommit,
+                                         bool bFieldFull,
+                                         bool& bRc) {
   Initial(JET_FIELD_KEYSTROKE);
 
   m_nCommitKey = 0;
@@ -204,12 +198,12 @@
 
 void CJS_EventHandler::OnField_Validate(CFX_WideString& strChange,
                                         const CFX_WideString& strChangeEx,
-                                        FX_BOOL bKeyDown,
-                                        FX_BOOL bModifier,
-                                        FX_BOOL bShift,
+                                        bool bKeyDown,
+                                        bool bModifier,
+                                        bool bShift,
                                         CPDF_FormField* pTarget,
                                         CFX_WideString& Value,
-                                        FX_BOOL& bRc) {
+                                        bool& bRc) {
   Initial(JET_FIELD_VALIDATE);
 
   m_pWideStrChange = &strChange;
@@ -225,7 +219,7 @@
 void CJS_EventHandler::OnField_Calculate(CPDF_FormField* pSource,
                                          CPDF_FormField* pTarget,
                                          CFX_WideString& Value,
-                                         FX_BOOL& bRc) {
+                                         bool& bRc) {
   Initial(JET_FIELD_CALCULATE);
 
   if (pSource)
@@ -237,7 +231,7 @@
 
 void CJS_EventHandler::OnField_Format(CPDF_FormField* pTarget,
                                       CFX_WideString& Value,
-                                      FX_BOOL bWillCommit) {
+                                      bool bWillCommit) {
   Initial(JET_FIELD_FORMAT);
 
   m_nCommitKey = 0;
@@ -246,8 +240,8 @@
   m_bWillCommit = bWillCommit;
 }
 
-void CJS_EventHandler::OnScreen_Focus(FX_BOOL bModifier,
-                                      FX_BOOL bShift,
+void CJS_EventHandler::OnScreen_Focus(bool bModifier,
+                                      bool bShift,
                                       CPDFSDK_Annot* pScreen) {
   Initial(JET_SCREEN_FOCUS);
 
@@ -256,8 +250,8 @@
   m_pTargetAnnot = pScreen;
 }
 
-void CJS_EventHandler::OnScreen_Blur(FX_BOOL bModifier,
-                                     FX_BOOL bShift,
+void CJS_EventHandler::OnScreen_Blur(bool bModifier,
+                                     bool bShift,
                                      CPDFSDK_Annot* pScreen) {
   Initial(JET_SCREEN_BLUR);
 
@@ -266,8 +260,8 @@
   m_pTargetAnnot = pScreen;
 }
 
-void CJS_EventHandler::OnScreen_Open(FX_BOOL bModifier,
-                                     FX_BOOL bShift,
+void CJS_EventHandler::OnScreen_Open(bool bModifier,
+                                     bool bShift,
                                      CPDFSDK_Annot* pScreen) {
   Initial(JET_SCREEN_OPEN);
 
@@ -276,8 +270,8 @@
   m_pTargetAnnot = pScreen;
 }
 
-void CJS_EventHandler::OnScreen_Close(FX_BOOL bModifier,
-                                      FX_BOOL bShift,
+void CJS_EventHandler::OnScreen_Close(bool bModifier,
+                                      bool bShift,
                                       CPDFSDK_Annot* pScreen) {
   Initial(JET_SCREEN_CLOSE);
 
@@ -286,8 +280,8 @@
   m_pTargetAnnot = pScreen;
 }
 
-void CJS_EventHandler::OnScreen_MouseDown(FX_BOOL bModifier,
-                                          FX_BOOL bShift,
+void CJS_EventHandler::OnScreen_MouseDown(bool bModifier,
+                                          bool bShift,
                                           CPDFSDK_Annot* pScreen) {
   Initial(JET_SCREEN_MOUSEDOWN);
 
@@ -296,8 +290,8 @@
   m_pTargetAnnot = pScreen;
 }
 
-void CJS_EventHandler::OnScreen_MouseUp(FX_BOOL bModifier,
-                                        FX_BOOL bShift,
+void CJS_EventHandler::OnScreen_MouseUp(bool bModifier,
+                                        bool bShift,
                                         CPDFSDK_Annot* pScreen) {
   Initial(JET_SCREEN_MOUSEUP);
 
@@ -306,8 +300,8 @@
   m_pTargetAnnot = pScreen;
 }
 
-void CJS_EventHandler::OnScreen_MouseEnter(FX_BOOL bModifier,
-                                           FX_BOOL bShift,
+void CJS_EventHandler::OnScreen_MouseEnter(bool bModifier,
+                                           bool bShift,
                                            CPDFSDK_Annot* pScreen) {
   Initial(JET_SCREEN_MOUSEENTER);
 
@@ -316,8 +310,8 @@
   m_pTargetAnnot = pScreen;
 }
 
-void CJS_EventHandler::OnScreen_MouseExit(FX_BOOL bModifier,
-                                          FX_BOOL bShift,
+void CJS_EventHandler::OnScreen_MouseExit(bool bModifier,
+                                          bool bShift,
                                           CPDFSDK_Annot* pScreen) {
   Initial(JET_SCREEN_MOUSEEXIT);
 
@@ -326,8 +320,8 @@
   m_pTargetAnnot = pScreen;
 }
 
-void CJS_EventHandler::OnScreen_InView(FX_BOOL bModifier,
-                                       FX_BOOL bShift,
+void CJS_EventHandler::OnScreen_InView(bool bModifier,
+                                       bool bShift,
                                        CPDFSDK_Annot* pScreen) {
   Initial(JET_SCREEN_INVIEW);
 
@@ -336,8 +330,8 @@
   m_pTargetAnnot = pScreen;
 }
 
-void CJS_EventHandler::OnScreen_OutView(FX_BOOL bModifier,
-                                        FX_BOOL bShift,
+void CJS_EventHandler::OnScreen_OutView(bool bModifier,
+                                        bool bShift,
                                         CPDFSDK_Annot* pScreen) {
   Initial(JET_SCREEN_OUTVIEW);
 
@@ -346,10 +340,10 @@
   m_pTargetAnnot = pScreen;
 }
 
-void CJS_EventHandler::OnLink_MouseUp(CPDFSDK_Document* pTarget) {
+void CJS_EventHandler::OnLink_MouseUp(
+    CPDFSDK_FormFillEnvironment* pTargetFormFillEnv) {
   Initial(JET_LINK_MOUSEUP);
-
-  m_pTargetDoc = pTarget;
+  m_pTargetFormFillEnv = pTargetFormFillEnv;
 }
 
 void CJS_EventHandler::OnBookmark_MouseUp(CPDF_Bookmark* pBookMark) {
@@ -358,11 +352,11 @@
   m_pTargetBookMark = pBookMark;
 }
 
-void CJS_EventHandler::OnMenu_Exec(CPDFSDK_Document* pTarget,
-                                   const CFX_WideString& strTargetName) {
+void CJS_EventHandler::OnMenu_Exec(
+    CPDFSDK_FormFillEnvironment* pTargetFormFillEnv,
+    const CFX_WideString& strTargetName) {
   Initial(JET_MENU_EXEC);
-
-  m_pTargetDoc = pTarget;
+  m_pTargetFormFillEnv = pTargetFormFillEnv;
   m_strTargetName = strTargetName;
 }
 
@@ -370,10 +364,10 @@
   Initial(JET_EXTERNAL_EXEC);
 }
 
-void CJS_EventHandler::OnBatchExec(CPDFSDK_Document* pTarget) {
+void CJS_EventHandler::OnBatchExec(
+    CPDFSDK_FormFillEnvironment* pTargetFormFillEnv) {
   Initial(JET_BATCH_EXEC);
-
-  m_pTargetDoc = pTarget;
+  m_pTargetFormFillEnv = pTargetFormFillEnv;
 }
 
 void CJS_EventHandler::OnConsole_Exec() {
@@ -385,36 +379,35 @@
 
   m_strTargetName = L"";
   m_strSourceName = L"";
-  m_pWideStrChange = NULL;
+  m_pWideStrChange = nullptr;
   m_WideStrChangeDu = L"";
   m_WideStrChangeEx = L"";
   m_nCommitKey = -1;
-  m_bKeyDown = FALSE;
-  m_bModifier = FALSE;
-  m_bShift = FALSE;
-  m_pISelEnd = NULL;
+  m_bKeyDown = false;
+  m_bModifier = false;
+  m_bShift = false;
+  m_pISelEnd = nullptr;
   m_nSelEndDu = 0;
-  m_pISelStart = NULL;
+  m_pISelStart = nullptr;
   m_nSelStartDu = 0;
-  m_bWillCommit = FALSE;
-  m_pValue = NULL;
-  m_bFieldFull = FALSE;
-  m_pbRc = NULL;
-  m_bRcDu = FALSE;
+  m_bWillCommit = false;
+  m_pValue = nullptr;
+  m_bFieldFull = false;
+  m_pbRc = nullptr;
+  m_bRcDu = false;
 
-  m_pSourceDoc = NULL;
-  m_pTargetBookMark = NULL;
-  m_pTargetDoc = NULL;
-  m_pTargetAnnot = NULL;
+  m_pTargetBookMark = nullptr;
+  m_pTargetFormFillEnv = nullptr;
+  m_pTargetAnnot = nullptr;
 
-  m_bValid = TRUE;
+  m_bValid = true;
 }
 
 void CJS_EventHandler::Destroy() {
-  m_bValid = FALSE;
+  m_bValid = false;
 }
 
-FX_BOOL CJS_EventHandler::IsValid() {
+bool CJS_EventHandler::IsValid() {
   return m_bValid;
 }
 
@@ -433,15 +426,15 @@
   return m_nCommitKey;
 }
 
-FX_BOOL CJS_EventHandler::FieldFull() {
+bool CJS_EventHandler::FieldFull() {
   return m_bFieldFull;
 }
 
-FX_BOOL CJS_EventHandler::KeyDown() {
+bool CJS_EventHandler::KeyDown() {
   return m_bKeyDown;
 }
 
-FX_BOOL CJS_EventHandler::Modifier() {
+bool CJS_EventHandler::Modifier() {
   return m_bModifier;
 }
 
@@ -514,8 +507,6 @@
     default:
       return L"";
   }
-
-  return L"";
 }
 
 const FX_WCHAR* CJS_EventHandler::Type() {
@@ -571,11 +562,9 @@
     default:
       return L"";
   }
-
-  return L"";
 }
 
-FX_BOOL& CJS_EventHandler::Rc() {
+bool& CJS_EventHandler::Rc() {
   if (m_pbRc) {
     return *m_pbRc;
   }
@@ -596,28 +585,29 @@
   return m_nSelStartDu;
 }
 
-FX_BOOL CJS_EventHandler::Shift() {
+bool CJS_EventHandler::Shift() {
   return m_bShift;
 }
 
 Field* CJS_EventHandler::Source() {
   CJS_Runtime* pRuntime = m_pJSContext->GetJSRuntime();
-  v8::Local<v8::Object> pDocObj = FXJS_NewFxDynamicObj(
-      pRuntime->GetIsolate(), pRuntime, CJS_Document::g_nObjDefnID);
+  v8::Local<v8::Object> pDocObj =
+      pRuntime->NewFxDynamicObj(CJS_Document::g_nObjDefnID);
   ASSERT(!pDocObj.IsEmpty());
 
-  v8::Local<v8::Object> pFieldObj = FXJS_NewFxDynamicObj(
-      pRuntime->GetIsolate(), pRuntime, CJS_Field::g_nObjDefnID);
+  v8::Local<v8::Object> pFieldObj =
+      pRuntime->NewFxDynamicObj(CJS_Field::g_nObjDefnID);
   ASSERT(!pFieldObj.IsEmpty());
 
   CJS_Document* pJSDocument =
-      (CJS_Document*)FXJS_GetPrivate(pRuntime->GetIsolate(), pDocObj);
+      static_cast<CJS_Document*>(pRuntime->GetObjectPrivate(pDocObj));
   Document* pDocument = (Document*)pJSDocument->GetEmbedObject();
-  pDocument->AttachDoc(m_pTargetDoc ? m_pTargetDoc
-                                    : m_pJSContext->GetReaderDocument());
+  pDocument->SetFormFillEnv(m_pTargetFormFillEnv
+                                ? m_pTargetFormFillEnv
+                                : m_pJSContext->GetFormFillEnv());
 
   CJS_Field* pJSField =
-      (CJS_Field*)FXJS_GetPrivate(pRuntime->GetIsolate(), pFieldObj);
+      static_cast<CJS_Field*>(pRuntime->GetObjectPrivate(pFieldObj));
   Field* pField = (Field*)pJSField->GetEmbedObject();
   pField->AttachField(pDocument, m_strSourceName);
   return pField;
@@ -625,22 +615,23 @@
 
 Field* CJS_EventHandler::Target_Field() {
   CJS_Runtime* pRuntime = m_pJSContext->GetJSRuntime();
-  v8::Local<v8::Object> pDocObj = FXJS_NewFxDynamicObj(
-      pRuntime->GetIsolate(), pRuntime, CJS_Document::g_nObjDefnID);
+  v8::Local<v8::Object> pDocObj =
+      pRuntime->NewFxDynamicObj(CJS_Document::g_nObjDefnID);
   ASSERT(!pDocObj.IsEmpty());
 
-  v8::Local<v8::Object> pFieldObj = FXJS_NewFxDynamicObj(
-      pRuntime->GetIsolate(), pRuntime, CJS_Field::g_nObjDefnID);
+  v8::Local<v8::Object> pFieldObj =
+      pRuntime->NewFxDynamicObj(CJS_Field::g_nObjDefnID);
   ASSERT(!pFieldObj.IsEmpty());
 
   CJS_Document* pJSDocument =
-      (CJS_Document*)FXJS_GetPrivate(pRuntime->GetIsolate(), pDocObj);
+      static_cast<CJS_Document*>(pRuntime->GetObjectPrivate(pDocObj));
   Document* pDocument = (Document*)pJSDocument->GetEmbedObject();
-  pDocument->AttachDoc(m_pTargetDoc ? m_pTargetDoc
-                                    : m_pJSContext->GetReaderDocument());
+  pDocument->SetFormFillEnv(m_pTargetFormFillEnv
+                                ? m_pTargetFormFillEnv
+                                : m_pJSContext->GetFormFillEnv());
 
   CJS_Field* pJSField =
-      (CJS_Field*)FXJS_GetPrivate(pRuntime->GetIsolate(), pFieldObj);
+      static_cast<CJS_Field*>(pRuntime->GetObjectPrivate(pFieldObj));
   Field* pField = (Field*)pJSField->GetEmbedObject();
   pField->AttachField(pDocument, m_strTargetName);
   return pField;
@@ -650,7 +641,7 @@
   return *m_pValue;
 }
 
-FX_BOOL CJS_EventHandler::WillCommit() {
+bool CJS_EventHandler::WillCommit() {
   return m_bWillCommit;
 }
 
diff --git a/fpdfsdk/javascript/JS_EventHandler.h b/fpdfsdk/javascript/JS_EventHandler.h
new file mode 100644
index 0000000..8cfcfa7
--- /dev/null
+++ b/fpdfsdk/javascript/JS_EventHandler.h
@@ -0,0 +1,196 @@
+// 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_JAVASCRIPT_JS_EVENTHANDLER_H_
+#define FPDFSDK_JAVASCRIPT_JS_EVENTHANDLER_H_
+
+#include "core/fxcrt/fx_string.h"
+#include "core/fxcrt/fx_system.h"
+
+class CJS_Context;
+class CPDFSDK_Annot;
+class CPDFSDK_FormFillEnvironment;
+class CPDF_Bookmark;
+class CPDF_FormField;
+class Field;
+
+enum JS_EVENT_T {
+  JET_UNKNOWN,
+  JET_APP_INIT,
+  JET_DOC_OPEN,
+  JET_DOC_WILLPRINT,
+  JET_DOC_DIDPRINT,
+  JET_DOC_WILLSAVE,
+  JET_DOC_DIDSAVE,
+  JET_DOC_WILLCLOSE,
+  JET_PAGE_OPEN,
+  JET_PAGE_CLOSE,
+  JET_PAGE_INVIEW,
+  JET_PAGE_OUTVIEW,
+  JET_FIELD_MOUSEDOWN,
+  JET_FIELD_MOUSEUP,
+  JET_FIELD_MOUSEENTER,
+  JET_FIELD_MOUSEEXIT,
+  JET_FIELD_FOCUS,
+  JET_FIELD_BLUR,
+  JET_FIELD_KEYSTROKE,
+  JET_FIELD_VALIDATE,
+  JET_FIELD_CALCULATE,
+  JET_FIELD_FORMAT,
+  JET_SCREEN_FOCUS,
+  JET_SCREEN_BLUR,
+  JET_SCREEN_OPEN,
+  JET_SCREEN_CLOSE,
+  JET_SCREEN_MOUSEDOWN,
+  JET_SCREEN_MOUSEUP,
+  JET_SCREEN_MOUSEENTER,
+  JET_SCREEN_MOUSEEXIT,
+  JET_SCREEN_INVIEW,
+  JET_SCREEN_OUTVIEW,
+  JET_BATCH_EXEC,
+  JET_MENU_EXEC,
+  JET_CONSOLE_EXEC,
+  JET_EXTERNAL_EXEC,
+  JET_BOOKMARK_MOUSEUP,
+  JET_LINK_MOUSEUP
+};
+
+class CJS_EventHandler {
+ public:
+  explicit CJS_EventHandler(CJS_Context* pContext);
+  virtual ~CJS_EventHandler();
+
+  void OnApp_Init();
+
+  void OnDoc_Open(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                  const CFX_WideString& strTargetName);
+  void OnDoc_WillPrint(CPDFSDK_FormFillEnvironment* pFormFillEnv);
+  void OnDoc_DidPrint(CPDFSDK_FormFillEnvironment* pFormFillEnv);
+  void OnDoc_WillSave(CPDFSDK_FormFillEnvironment* pFormFillEnv);
+  void OnDoc_DidSave(CPDFSDK_FormFillEnvironment* pFormFillEnv);
+  void OnDoc_WillClose(CPDFSDK_FormFillEnvironment* pFormFillEnv);
+
+  void OnPage_Open(CPDFSDK_FormFillEnvironment* pFormFillEnv);
+  void OnPage_Close(CPDFSDK_FormFillEnvironment* pFormFillEnv);
+  void OnPage_InView(CPDFSDK_FormFillEnvironment* pFormFillEnv);
+  void OnPage_OutView(CPDFSDK_FormFillEnvironment* pFormFillEnv);
+
+  void OnField_Calculate(CPDF_FormField* pSource,
+                         CPDF_FormField* pTarget,
+                         CFX_WideString& Value,
+                         bool& bRc);
+  void OnField_Format(CPDF_FormField* pTarget,
+                      CFX_WideString& Value,
+                      bool bWillCommit);
+  void OnField_Keystroke(CFX_WideString& strChange,
+                         const CFX_WideString& strChangeEx,
+                         bool KeyDown,
+                         bool bModifier,
+                         int& nSelEnd,
+                         int& nSelStart,
+                         bool bShift,
+                         CPDF_FormField* pTarget,
+                         CFX_WideString& Value,
+                         bool bWillCommit,
+                         bool bFieldFull,
+                         bool& bRc);
+  void OnField_Validate(CFX_WideString& strChange,
+                        const CFX_WideString& strChangeEx,
+                        bool bKeyDown,
+                        bool bModifier,
+                        bool bShift,
+                        CPDF_FormField* pTarget,
+                        CFX_WideString& Value,
+                        bool& bRc);
+
+  void OnField_MouseDown(bool bModifier, bool bShift, CPDF_FormField* pTarget);
+  void OnField_MouseEnter(bool bModifier, bool bShift, CPDF_FormField* pTarget);
+  void OnField_MouseExit(bool bModifier, bool bShift, CPDF_FormField* pTarget);
+  void OnField_MouseUp(bool bModifier, bool bShift, CPDF_FormField* pTarget);
+  void OnField_Blur(bool bModifier,
+                    bool bShift,
+                    CPDF_FormField* pTarget,
+                    const CFX_WideString& Value);
+  void OnField_Focus(bool bModifier,
+                     bool bShift,
+                     CPDF_FormField* pTarget,
+                     const CFX_WideString& Value);
+
+  void OnScreen_Focus(bool bModifier, bool bShift, CPDFSDK_Annot* pScreen);
+  void OnScreen_Blur(bool bModifier, bool bShift, CPDFSDK_Annot* pScreen);
+  void OnScreen_Open(bool bModifier, bool bShift, CPDFSDK_Annot* pScreen);
+  void OnScreen_Close(bool bModifier, bool bShift, CPDFSDK_Annot* pScreen);
+  void OnScreen_MouseDown(bool bModifier, bool bShift, CPDFSDK_Annot* pScreen);
+  void OnScreen_MouseUp(bool bModifier, bool bShift, CPDFSDK_Annot* pScreen);
+  void OnScreen_MouseEnter(bool bModifier, bool bShift, CPDFSDK_Annot* pScreen);
+  void OnScreen_MouseExit(bool bModifier, bool bShift, CPDFSDK_Annot* pScreen);
+  void OnScreen_InView(bool bModifier, bool bShift, CPDFSDK_Annot* pScreen);
+  void OnScreen_OutView(bool bModifier, bool bShift, CPDFSDK_Annot* pScreen);
+
+  void OnBookmark_MouseUp(CPDF_Bookmark* pBookMark);
+  void OnLink_MouseUp(CPDFSDK_FormFillEnvironment* pFormFillEnv);
+
+  void OnMenu_Exec(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                   const CFX_WideString& strTargetName);
+  void OnBatchExec(CPDFSDK_FormFillEnvironment* pFormFillEnv);
+  void OnConsole_Exec();
+  void OnExternal_Exec();
+
+ public:
+  void Initial(JS_EVENT_T type);
+  void Destroy();
+  bool IsValid();
+
+  CFX_WideString& Change();
+  CFX_WideString ChangeEx();
+  int CommitKey();
+  bool FieldFull();
+  bool KeyDown();
+  bool Modifier();
+  const FX_WCHAR* Name();
+  const FX_WCHAR* Type();
+  bool& Rc();
+  int& SelEnd();
+  int& SelStart();
+  bool Shift();
+  Field* Source();
+  Field* Target_Field();
+  CFX_WideString& Value();
+  bool WillCommit();
+  CFX_WideString TargetName();
+
+  JS_EVENT_T EventType() { return m_eEventType; }
+
+ public:
+  CJS_Context* m_pJSContext;
+  JS_EVENT_T m_eEventType;
+  bool m_bValid;
+
+  CFX_WideString m_strTargetName;
+  CFX_WideString m_strSourceName;
+  CFX_WideString* m_pWideStrChange;
+  CFX_WideString m_WideStrChangeDu;
+  CFX_WideString m_WideStrChangeEx;
+  int m_nCommitKey;
+  bool m_bKeyDown;
+  bool m_bModifier;
+  bool m_bShift;
+  int* m_pISelEnd;
+  int m_nSelEndDu;
+  int* m_pISelStart;
+  int m_nSelStartDu;
+  bool m_bWillCommit;
+  CFX_WideString* m_pValue;
+  bool m_bFieldFull;
+  bool* m_pbRc;
+  bool m_bRcDu;
+
+  CPDF_Bookmark* m_pTargetBookMark;
+  CPDFSDK_FormFillEnvironment* m_pTargetFormFillEnv;
+  CPDFSDK_Annot* m_pTargetAnnot;
+};
+
+#endif  // FPDFSDK_JAVASCRIPT_JS_EVENTHANDLER_H_
diff --git a/fpdfsdk/javascript/JS_GlobalData.cpp b/fpdfsdk/javascript/JS_GlobalData.cpp
new file mode 100644
index 0000000..68d929f
--- /dev/null
+++ b/fpdfsdk/javascript/JS_GlobalData.cpp
@@ -0,0 +1,396 @@
+// 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
+
+#include "fpdfsdk/javascript/JS_GlobalData.h"
+
+#include <utility>
+
+#include "core/fdrm/crypto/fx_crypt.h"
+#include "third_party/base/stl_util.h"
+
+#define JS_MAXGLOBALDATA (1024 * 4 - 8)
+
+#define READER_JS_GLOBALDATA_FILENAME L"Reader_JsGlobal.Data"
+#define PHANTOM_JS_GLOBALDATA_FILENAME L"Phantom_JsGlobal.Data"
+#define SDK_JS_GLOBALDATA_FILENAME L"SDK_JsGlobal.Data"
+
+namespace {
+
+const uint8_t JS_RC4KEY[] = {
+    0x19, 0xa8, 0xe8, 0x01, 0xf6, 0xa8, 0xb6, 0x4d, 0x82, 0x04, 0x45, 0x6d,
+    0xb4, 0xcf, 0xd7, 0x77, 0x67, 0xf9, 0x75, 0x9f, 0xf0, 0xe0, 0x1e, 0x51,
+    0xee, 0x46, 0xfd, 0x0b, 0xc9, 0x93, 0x25, 0x55, 0x4a, 0xee, 0xe0, 0x16,
+    0xd0, 0xdf, 0x8c, 0xfa, 0x2a, 0xa9, 0x49, 0xfd, 0x97, 0x1c, 0x0e, 0x22,
+    0x13, 0x28, 0x7c, 0xaf, 0xc4, 0xfc, 0x9c, 0x12, 0x65, 0x8c, 0x4e, 0x5b,
+    0x04, 0x75, 0x89, 0xc9, 0xb1, 0xed, 0x50, 0xca, 0x96, 0x6f, 0x1a, 0x7a,
+    0xfe, 0x58, 0x5d, 0xec, 0x19, 0x4a, 0xf6, 0x35, 0x6a, 0x97, 0x14, 0x00,
+    0x0e, 0xd0, 0x6b, 0xbb, 0xd5, 0x75, 0x55, 0x8b, 0x6e, 0x6b, 0x19, 0xa0,
+    0xf8, 0x77, 0xd5, 0xa3};
+
+// Returns true if non-empty, setting sPropName
+bool TrimPropName(CFX_ByteString* sPropName) {
+  sPropName->TrimLeft();
+  sPropName->TrimRight();
+  return sPropName->GetLength() != 0;
+}
+
+CJS_GlobalData* g_pInstance = nullptr;
+
+}  // namespace
+
+// static
+CJS_GlobalData* CJS_GlobalData::GetRetainedInstance(
+    CPDFSDK_FormFillEnvironment* pApp) {
+  if (!g_pInstance) {
+    g_pInstance = new CJS_GlobalData();
+  }
+  ++g_pInstance->m_RefCount;
+  return g_pInstance;
+}
+
+void CJS_GlobalData::Release() {
+  if (!--m_RefCount) {
+    delete g_pInstance;
+    g_pInstance = nullptr;
+  }
+}
+
+CJS_GlobalData::CJS_GlobalData()
+    : m_RefCount(0), m_sFilePath(SDK_JS_GLOBALDATA_FILENAME) {
+  LoadGlobalPersistentVariables();
+}
+
+CJS_GlobalData::~CJS_GlobalData() {
+  SaveGlobalPersisitentVariables();
+}
+
+CJS_GlobalData::iterator CJS_GlobalData::FindGlobalVariable(
+    const CFX_ByteString& propname) {
+  for (auto it = m_arrayGlobalData.begin(); it != m_arrayGlobalData.end();
+       ++it) {
+    if ((*it)->data.sKey == propname)
+      return it;
+  }
+  return m_arrayGlobalData.end();
+}
+
+CJS_GlobalData::const_iterator CJS_GlobalData::FindGlobalVariable(
+    const CFX_ByteString& propname) const {
+  for (auto it = m_arrayGlobalData.begin(); it != m_arrayGlobalData.end();
+       ++it) {
+    if ((*it)->data.sKey == propname)
+      return it;
+  }
+  return m_arrayGlobalData.end();
+}
+
+CJS_GlobalData_Element* CJS_GlobalData::GetGlobalVariable(
+    const CFX_ByteString& propname) {
+  auto iter = FindGlobalVariable(propname);
+  return iter != m_arrayGlobalData.end() ? iter->get() : nullptr;
+}
+
+void CJS_GlobalData::SetGlobalVariableNumber(const CFX_ByteString& propname,
+                                             double dData) {
+  CFX_ByteString sPropName(propname);
+  if (!TrimPropName(&sPropName))
+    return;
+
+  if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
+    pData->data.nType = JS_GlobalDataType::NUMBER;
+    pData->data.dData = dData;
+    return;
+  }
+  std::unique_ptr<CJS_GlobalData_Element> pNewData(new CJS_GlobalData_Element);
+  pNewData->data.sKey = sPropName;
+  pNewData->data.nType = JS_GlobalDataType::NUMBER;
+  pNewData->data.dData = dData;
+  m_arrayGlobalData.push_back(std::move(pNewData));
+}
+
+void CJS_GlobalData::SetGlobalVariableBoolean(const CFX_ByteString& propname,
+                                              bool bData) {
+  CFX_ByteString sPropName(propname);
+  if (!TrimPropName(&sPropName))
+    return;
+
+  if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
+    pData->data.nType = JS_GlobalDataType::BOOLEAN;
+    pData->data.bData = bData;
+    return;
+  }
+  std::unique_ptr<CJS_GlobalData_Element> pNewData(new CJS_GlobalData_Element);
+  pNewData->data.sKey = sPropName;
+  pNewData->data.nType = JS_GlobalDataType::BOOLEAN;
+  pNewData->data.bData = bData;
+  m_arrayGlobalData.push_back(std::move(pNewData));
+}
+
+void CJS_GlobalData::SetGlobalVariableString(const CFX_ByteString& propname,
+                                             const CFX_ByteString& sData) {
+  CFX_ByteString sPropName(propname);
+  if (!TrimPropName(&sPropName))
+    return;
+
+  if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
+    pData->data.nType = JS_GlobalDataType::STRING;
+    pData->data.sData = sData;
+    return;
+  }
+  std::unique_ptr<CJS_GlobalData_Element> pNewData(new CJS_GlobalData_Element);
+  pNewData->data.sKey = sPropName;
+  pNewData->data.nType = JS_GlobalDataType::STRING;
+  pNewData->data.sData = sData;
+  m_arrayGlobalData.push_back(std::move(pNewData));
+}
+
+void CJS_GlobalData::SetGlobalVariableObject(
+    const CFX_ByteString& propname,
+    const CJS_GlobalVariableArray& array) {
+  CFX_ByteString sPropName(propname);
+  if (!TrimPropName(&sPropName))
+    return;
+
+  if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
+    pData->data.nType = JS_GlobalDataType::OBJECT;
+    pData->data.objData.Copy(array);
+    return;
+  }
+  std::unique_ptr<CJS_GlobalData_Element> pNewData(new CJS_GlobalData_Element);
+  pNewData->data.sKey = sPropName;
+  pNewData->data.nType = JS_GlobalDataType::OBJECT;
+  pNewData->data.objData.Copy(array);
+  m_arrayGlobalData.push_back(std::move(pNewData));
+}
+
+void CJS_GlobalData::SetGlobalVariableNull(const CFX_ByteString& propname) {
+  CFX_ByteString sPropName(propname);
+  if (!TrimPropName(&sPropName))
+    return;
+
+  if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
+    pData->data.nType = JS_GlobalDataType::NULLOBJ;
+    return;
+  }
+  std::unique_ptr<CJS_GlobalData_Element> pNewData(new CJS_GlobalData_Element);
+  pNewData->data.sKey = sPropName;
+  pNewData->data.nType = JS_GlobalDataType::NULLOBJ;
+  m_arrayGlobalData.push_back(std::move(pNewData));
+}
+
+bool CJS_GlobalData::SetGlobalVariablePersistent(const CFX_ByteString& propname,
+                                                 bool bPersistent) {
+  CFX_ByteString sPropName(propname);
+  if (!TrimPropName(&sPropName))
+    return false;
+
+  CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName);
+  if (!pData)
+    return false;
+
+  pData->bPersistent = bPersistent;
+  return true;
+}
+
+bool CJS_GlobalData::DeleteGlobalVariable(const CFX_ByteString& propname) {
+  CFX_ByteString sPropName(propname);
+  if (!TrimPropName(&sPropName))
+    return false;
+
+  auto iter = FindGlobalVariable(sPropName);
+  if (iter == m_arrayGlobalData.end())
+    return false;
+
+  m_arrayGlobalData.erase(iter);
+  return true;
+}
+
+int32_t CJS_GlobalData::GetSize() const {
+  return pdfium::CollectionSize<int32_t>(m_arrayGlobalData);
+}
+
+CJS_GlobalData_Element* CJS_GlobalData::GetAt(int index) const {
+  if (index < 0 || index >= GetSize())
+    return nullptr;
+  return m_arrayGlobalData[index].get();
+}
+
+void CJS_GlobalData::LoadGlobalPersistentVariables() {
+  uint8_t* pBuffer = nullptr;
+  int32_t nLength = 0;
+
+  LoadFileBuffer(m_sFilePath.c_str(), pBuffer, nLength);
+  CRYPT_ArcFourCryptBlock(pBuffer, nLength, JS_RC4KEY, sizeof(JS_RC4KEY));
+
+  if (pBuffer) {
+    uint8_t* p = pBuffer;
+    uint16_t wType = *((uint16_t*)p);
+    p += sizeof(uint16_t);
+
+    if (wType == (uint16_t)(('X' << 8) | 'F')) {
+      uint16_t wVersion = *((uint16_t*)p);
+      p += sizeof(uint16_t);
+
+      ASSERT(wVersion <= 2);
+
+      uint32_t dwCount = *((uint32_t*)p);
+      p += sizeof(uint32_t);
+
+      uint32_t dwSize = *((uint32_t*)p);
+      p += sizeof(uint32_t);
+
+      if (dwSize == nLength - sizeof(uint16_t) * 2 - sizeof(uint32_t) * 2) {
+        for (int32_t i = 0, sz = dwCount; i < sz; i++) {
+          if (p > pBuffer + nLength)
+            break;
+
+          uint32_t dwNameLen = *((uint32_t*)p);
+          p += sizeof(uint32_t);
+
+          if (p + dwNameLen > pBuffer + nLength)
+            break;
+
+          CFX_ByteString sEntry = CFX_ByteString(p, dwNameLen);
+          p += sizeof(char) * dwNameLen;
+
+          JS_GlobalDataType wDataType =
+              static_cast<JS_GlobalDataType>(*((uint16_t*)p));
+          p += sizeof(uint16_t);
+
+          switch (wDataType) {
+            case JS_GlobalDataType::NUMBER: {
+              double dData = 0;
+              switch (wVersion) {
+                case 1: {
+                  uint32_t dwData = *((uint32_t*)p);
+                  p += sizeof(uint32_t);
+                  dData = dwData;
+                } break;
+                case 2: {
+                  dData = *((double*)p);
+                  p += sizeof(double);
+                } break;
+              }
+              SetGlobalVariableNumber(sEntry, dData);
+              SetGlobalVariablePersistent(sEntry, true);
+            } break;
+            case JS_GlobalDataType::BOOLEAN: {
+              uint16_t wData = *((uint16_t*)p);
+              p += sizeof(uint16_t);
+              SetGlobalVariableBoolean(sEntry, (bool)(wData == 1));
+              SetGlobalVariablePersistent(sEntry, true);
+            } break;
+            case JS_GlobalDataType::STRING: {
+              uint32_t dwLength = *((uint32_t*)p);
+              p += sizeof(uint32_t);
+
+              if (p + dwLength > pBuffer + nLength)
+                break;
+
+              SetGlobalVariableString(sEntry, CFX_ByteString(p, dwLength));
+              SetGlobalVariablePersistent(sEntry, true);
+              p += sizeof(char) * dwLength;
+            } break;
+            case JS_GlobalDataType::NULLOBJ: {
+              SetGlobalVariableNull(sEntry);
+              SetGlobalVariablePersistent(sEntry, true);
+            }
+            case JS_GlobalDataType::OBJECT:
+              break;
+          }
+        }
+      }
+    }
+    FX_Free(pBuffer);
+  }
+}
+
+void CJS_GlobalData::SaveGlobalPersisitentVariables() {
+  uint32_t nCount = 0;
+  CFX_BinaryBuf sData;
+  for (const auto& pElement : m_arrayGlobalData) {
+    if (pElement->bPersistent) {
+      CFX_BinaryBuf sElement;
+      MakeByteString(pElement->data.sKey, &pElement->data, sElement);
+      if (sData.GetSize() + sElement.GetSize() > JS_MAXGLOBALDATA)
+        break;
+
+      sData.AppendBlock(sElement.GetBuffer(), sElement.GetSize());
+      nCount++;
+    }
+  }
+
+  CFX_BinaryBuf sFile;
+  uint16_t wType = (uint16_t)(('X' << 8) | 'F');
+  sFile.AppendBlock(&wType, sizeof(uint16_t));
+  uint16_t wVersion = 2;
+  sFile.AppendBlock(&wVersion, sizeof(uint16_t));
+  sFile.AppendBlock(&nCount, sizeof(uint32_t));
+  uint32_t dwSize = sData.GetSize();
+  sFile.AppendBlock(&dwSize, sizeof(uint32_t));
+
+  sFile.AppendBlock(sData.GetBuffer(), sData.GetSize());
+
+  CRYPT_ArcFourCryptBlock(sFile.GetBuffer(), sFile.GetSize(), JS_RC4KEY,
+                          sizeof(JS_RC4KEY));
+  WriteFileBuffer(m_sFilePath.c_str(), (const FX_CHAR*)sFile.GetBuffer(),
+                  sFile.GetSize());
+}
+
+void CJS_GlobalData::LoadFileBuffer(const FX_WCHAR* sFilePath,
+                                    uint8_t*& pBuffer,
+                                    int32_t& nLength) {
+  // UnSupport.
+}
+
+void CJS_GlobalData::WriteFileBuffer(const FX_WCHAR* sFilePath,
+                                     const FX_CHAR* pBuffer,
+                                     int32_t nLength) {
+  // UnSupport.
+}
+
+void CJS_GlobalData::MakeByteString(const CFX_ByteString& name,
+                                    CJS_KeyValue* pData,
+                                    CFX_BinaryBuf& sData) {
+  switch (pData->nType) {
+    case JS_GlobalDataType::NUMBER: {
+      uint32_t dwNameLen = (uint32_t)name.GetLength();
+      sData.AppendBlock(&dwNameLen, sizeof(uint32_t));
+      sData.AppendString(name);
+      sData.AppendBlock(&pData->nType, sizeof(uint16_t));
+
+      double dData = pData->dData;
+      sData.AppendBlock(&dData, sizeof(double));
+    } break;
+    case JS_GlobalDataType::BOOLEAN: {
+      uint32_t dwNameLen = (uint32_t)name.GetLength();
+      sData.AppendBlock(&dwNameLen, sizeof(uint32_t));
+      sData.AppendString(name);
+      sData.AppendBlock(&pData->nType, sizeof(uint16_t));
+
+      uint16_t wData = (uint16_t)pData->bData;
+      sData.AppendBlock(&wData, sizeof(uint16_t));
+    } break;
+    case JS_GlobalDataType::STRING: {
+      uint32_t dwNameLen = (uint32_t)name.GetLength();
+      sData.AppendBlock(&dwNameLen, sizeof(uint32_t));
+      sData.AppendString(name);
+      sData.AppendBlock(&pData->nType, sizeof(uint16_t));
+
+      uint32_t dwDataLen = (uint32_t)pData->sData.GetLength();
+      sData.AppendBlock(&dwDataLen, sizeof(uint32_t));
+      sData.AppendString(pData->sData);
+    } break;
+    case JS_GlobalDataType::NULLOBJ: {
+      uint32_t dwNameLen = (uint32_t)name.GetLength();
+      sData.AppendBlock(&dwNameLen, sizeof(uint32_t));
+      sData.AppendString(name);
+      sData.AppendBlock(&pData->nType, sizeof(uint32_t));
+    } break;
+    default:
+      break;
+  }
+}
diff --git a/fpdfsdk/javascript/JS_GlobalData.h b/fpdfsdk/javascript/JS_GlobalData.h
new file mode 100644
index 0000000..c8947cd
--- /dev/null
+++ b/fpdfsdk/javascript/JS_GlobalData.h
@@ -0,0 +1,77 @@
+// 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_JAVASCRIPT_JS_GLOBALDATA_H_
+#define FPDFSDK_JAVASCRIPT_JS_GLOBALDATA_H_
+
+#include <memory>
+#include <vector>
+
+#include "core/fxcrt/fx_basic.h"
+#include "fpdfsdk/javascript/JS_KeyValue.h"
+
+class CPDFSDK_FormFillEnvironment;
+
+class CJS_GlobalData_Element {
+ public:
+  CJS_GlobalData_Element() {}
+  ~CJS_GlobalData_Element() {}
+
+  CJS_KeyValue data;
+  bool bPersistent;
+};
+
+class CJS_GlobalData {
+ public:
+  static CJS_GlobalData* GetRetainedInstance(CPDFSDK_FormFillEnvironment* pApp);
+  void Release();
+
+  void SetGlobalVariableNumber(const CFX_ByteString& propname, double dData);
+  void SetGlobalVariableBoolean(const CFX_ByteString& propname, bool bData);
+  void SetGlobalVariableString(const CFX_ByteString& propname,
+                               const CFX_ByteString& sData);
+  void SetGlobalVariableObject(const CFX_ByteString& propname,
+                               const CJS_GlobalVariableArray& array);
+  void SetGlobalVariableNull(const CFX_ByteString& propname);
+  bool SetGlobalVariablePersistent(const CFX_ByteString& propname,
+                                   bool bPersistent);
+  bool DeleteGlobalVariable(const CFX_ByteString& propname);
+
+  int32_t GetSize() const;
+  CJS_GlobalData_Element* GetAt(int index) const;
+
+ private:
+  using iterator =
+      std::vector<std::unique_ptr<CJS_GlobalData_Element>>::iterator;
+  using const_iterator =
+      std::vector<std::unique_ptr<CJS_GlobalData_Element>>::const_iterator;
+
+  CJS_GlobalData();
+  ~CJS_GlobalData();
+
+  void LoadGlobalPersistentVariables();
+  void SaveGlobalPersisitentVariables();
+
+  CJS_GlobalData_Element* GetGlobalVariable(const CFX_ByteString& sPropname);
+  iterator FindGlobalVariable(const CFX_ByteString& sPropname);
+  const_iterator FindGlobalVariable(const CFX_ByteString& sPropname) const;
+
+  void LoadFileBuffer(const FX_WCHAR* sFilePath,
+                      uint8_t*& pBuffer,
+                      int32_t& nLength);
+  void WriteFileBuffer(const FX_WCHAR* sFilePath,
+                       const FX_CHAR* pBuffer,
+                       int32_t nLength);
+  void MakeByteString(const CFX_ByteString& name,
+                      CJS_KeyValue* pData,
+                      CFX_BinaryBuf& sData);
+
+  size_t m_RefCount;
+  std::vector<std::unique_ptr<CJS_GlobalData_Element>> m_arrayGlobalData;
+  CFX_WideString m_sFilePath;
+};
+
+#endif  // FPDFSDK_JAVASCRIPT_JS_GLOBALDATA_H_
diff --git a/fpdfsdk/javascript/JS_KeyValue.cpp b/fpdfsdk/javascript/JS_KeyValue.cpp
new file mode 100644
index 0000000..7d1e575
--- /dev/null
+++ b/fpdfsdk/javascript/JS_KeyValue.cpp
@@ -0,0 +1,70 @@
+// 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/javascript/JS_KeyValue.h"
+
+CJS_GlobalVariableArray::CJS_GlobalVariableArray() {}
+
+CJS_GlobalVariableArray::~CJS_GlobalVariableArray() {}
+
+void CJS_GlobalVariableArray::Copy(const CJS_GlobalVariableArray& array) {
+  m_Array.clear();
+  for (int i = 0, sz = array.Count(); i < sz; i++) {
+    CJS_KeyValue* pOldObjData = array.GetAt(i);
+    switch (pOldObjData->nType) {
+      case JS_GlobalDataType::NUMBER: {
+        CJS_KeyValue* pNewObjData = new CJS_KeyValue;
+        pNewObjData->sKey = pOldObjData->sKey;
+        pNewObjData->nType = pOldObjData->nType;
+        pNewObjData->dData = pOldObjData->dData;
+        Add(pNewObjData);
+      } break;
+      case JS_GlobalDataType::BOOLEAN: {
+        CJS_KeyValue* pNewObjData = new CJS_KeyValue;
+        pNewObjData->sKey = pOldObjData->sKey;
+        pNewObjData->nType = pOldObjData->nType;
+        pNewObjData->bData = pOldObjData->bData;
+        Add(pNewObjData);
+      } break;
+      case JS_GlobalDataType::STRING: {
+        CJS_KeyValue* pNewObjData = new CJS_KeyValue;
+        pNewObjData->sKey = pOldObjData->sKey;
+        pNewObjData->nType = pOldObjData->nType;
+        pNewObjData->sData = pOldObjData->sData;
+        Add(pNewObjData);
+      } break;
+      case JS_GlobalDataType::OBJECT: {
+        CJS_KeyValue* pNewObjData = new CJS_KeyValue;
+        pNewObjData->sKey = pOldObjData->sKey;
+        pNewObjData->nType = pOldObjData->nType;
+        pNewObjData->objData.Copy(pOldObjData->objData);
+        Add(pNewObjData);
+      } break;
+      case JS_GlobalDataType::NULLOBJ: {
+        CJS_KeyValue* pNewObjData = new CJS_KeyValue;
+        pNewObjData->sKey = pOldObjData->sKey;
+        pNewObjData->nType = pOldObjData->nType;
+        Add(pNewObjData);
+      } break;
+    }
+  }
+}
+
+void CJS_GlobalVariableArray::Add(CJS_KeyValue* p) {
+  m_Array.push_back(std::unique_ptr<CJS_KeyValue>(p));
+}
+
+int CJS_GlobalVariableArray::Count() const {
+  return m_Array.size();
+}
+
+CJS_KeyValue* CJS_GlobalVariableArray::GetAt(int index) const {
+  return m_Array.at(index).get();
+}
+
+CJS_KeyValue::CJS_KeyValue() {}
+
+CJS_KeyValue::~CJS_KeyValue() {}
diff --git a/fpdfsdk/javascript/JS_KeyValue.h b/fpdfsdk/javascript/JS_KeyValue.h
new file mode 100644
index 0000000..a571588
--- /dev/null
+++ b/fpdfsdk/javascript/JS_KeyValue.h
@@ -0,0 +1,46 @@
+// 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_JAVASCRIPT_JS_KEYVALUE_H_
+#define FPDFSDK_JAVASCRIPT_JS_KEYVALUE_H_
+
+#include <memory>
+#include <vector>
+
+#include "core/fxcrt/fx_basic.h"
+
+enum class JS_GlobalDataType { NUMBER = 0, BOOLEAN, STRING, OBJECT, NULLOBJ };
+
+class CJS_KeyValue;
+
+class CJS_GlobalVariableArray {
+ public:
+  CJS_GlobalVariableArray();
+  ~CJS_GlobalVariableArray();
+
+  void Add(CJS_KeyValue* p);
+  int Count() const;
+  CJS_KeyValue* GetAt(int index) const;
+  void Copy(const CJS_GlobalVariableArray& array);
+
+ private:
+  std::vector<std::unique_ptr<CJS_KeyValue>> m_Array;
+};
+
+class CJS_KeyValue {
+ public:
+  CJS_KeyValue();
+  ~CJS_KeyValue();
+
+  CFX_ByteString sKey;
+  JS_GlobalDataType nType;
+  double dData;
+  bool bData;
+  CFX_ByteString sData;
+  CJS_GlobalVariableArray objData;
+};
+
+#endif  // FPDFSDK_JAVASCRIPT_JS_KEYVALUE_H_
diff --git a/fpdfsdk/javascript/JS_Object.cpp b/fpdfsdk/javascript/JS_Object.cpp
new file mode 100644
index 0000000..9ef6cdd
--- /dev/null
+++ b/fpdfsdk/javascript/JS_Object.cpp
@@ -0,0 +1,45 @@
+// 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
+
+#include "fpdfsdk/javascript/JS_Object.h"
+
+#include "fpdfsdk/javascript/JS_Define.h"
+#include "fpdfsdk/javascript/cjs_context.h"
+
+CJS_EmbedObj::CJS_EmbedObj(CJS_Object* pJSObject) : m_pJSObject(pJSObject) {}
+
+CJS_EmbedObj::~CJS_EmbedObj() {
+}
+
+void FreeObject(const v8::WeakCallbackInfo<CJS_Object>& data) {
+  CJS_Object* pJSObj = data.GetParameter();
+  delete pJSObj;
+  CFXJS_Engine::FreeObjectPrivate(data.GetInternalField(0));
+}
+
+void DisposeObject(const v8::WeakCallbackInfo<CJS_Object>& data) {
+  CJS_Object* pJSObj = data.GetParameter();
+  pJSObj->Dispose();
+  data.SetSecondPassCallback(FreeObject);
+}
+
+CJS_Object::CJS_Object(v8::Local<v8::Object> pObject) {
+  m_pIsolate = pObject->GetIsolate();
+  m_pV8Object.Reset(m_pIsolate, pObject);
+}
+
+CJS_Object::~CJS_Object() {}
+
+void CJS_Object::MakeWeak() {
+  m_pV8Object.SetWeak(this, DisposeObject,
+                      v8::WeakCallbackType::kInternalFields);
+}
+
+void CJS_Object::Dispose() {
+  m_pV8Object.Reset();
+}
+
+void CJS_Object::InitInstance(IJS_Runtime* pIRuntime) {}
diff --git a/fpdfsdk/javascript/JS_Object.h b/fpdfsdk/javascript/JS_Object.h
new file mode 100644
index 0000000..658a5e2
--- /dev/null
+++ b/fpdfsdk/javascript/JS_Object.h
@@ -0,0 +1,57 @@
+// 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_JAVASCRIPT_JS_OBJECT_H_
+#define FPDFSDK_JAVASCRIPT_JS_OBJECT_H_
+
+#include <map>
+#include <memory>
+
+#include "fpdfsdk/fsdk_define.h"
+#include "fpdfsdk/javascript/cjs_runtime.h"
+#include "fxjs/fxjs_v8.h"
+
+class CJS_Context;
+class CJS_Object;
+class CPDFSDK_FormFillEnvironment;
+
+class CJS_EmbedObj {
+ public:
+  explicit CJS_EmbedObj(CJS_Object* pJSObject);
+  virtual ~CJS_EmbedObj();
+
+  CJS_Object* GetJSObject() const { return m_pJSObject; }
+
+ protected:
+  CJS_Object* const m_pJSObject;
+};
+
+class CJS_Object {
+ public:
+  explicit CJS_Object(v8::Local<v8::Object> pObject);
+  virtual ~CJS_Object();
+
+  void MakeWeak();
+  void Dispose();
+
+  virtual void InitInstance(IJS_Runtime* pIRuntime);
+
+  v8::Local<v8::Object> ToV8Object() { return m_pV8Object.Get(m_pIsolate); }
+
+  // Takes ownership of |pObj|.
+  void SetEmbedObject(CJS_EmbedObj* pObj) { m_pEmbedObj.reset(pObj); }
+  CJS_EmbedObj* GetEmbedObject() const { return m_pEmbedObj.get(); }
+
+  v8::Isolate* GetIsolate() const { return m_pIsolate; }
+
+ protected:
+  std::unique_ptr<CJS_EmbedObj> m_pEmbedObj;
+  v8::Global<v8::Object> m_pV8Object;
+  v8::Isolate* m_pIsolate;
+};
+
+
+#endif  // FPDFSDK_JAVASCRIPT_JS_OBJECT_H_
diff --git a/fpdfsdk/javascript/JS_Runtime_Stub.cpp b/fpdfsdk/javascript/JS_Runtime_Stub.cpp
new file mode 100644
index 0000000..96148d8
--- /dev/null
+++ b/fpdfsdk/javascript/JS_Runtime_Stub.cpp
@@ -0,0 +1,169 @@
+// Copyright 2015 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 <memory>
+
+#include "fpdfsdk/javascript/ijs_context.h"
+#include "fpdfsdk/javascript/ijs_runtime.h"
+#include "third_party/base/ptr_util.h"
+
+class CJS_ContextStub final : public IJS_Context {
+ public:
+  CJS_ContextStub() {}
+  ~CJS_ContextStub() override {}
+
+  // IJS_Context:
+  bool RunScript(const CFX_WideString& script, CFX_WideString* info) override {
+    return false;
+  }
+
+  void OnApp_Init() override {}
+  void OnDoc_Open(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                  const CFX_WideString& strTargetName) override {}
+  void OnDoc_WillPrint(CPDFSDK_FormFillEnvironment* pFormFillEnv) override {}
+  void OnDoc_DidPrint(CPDFSDK_FormFillEnvironment* pFormFillEnv) override {}
+  void OnDoc_WillSave(CPDFSDK_FormFillEnvironment* pFormFillEnv) override {}
+  void OnDoc_DidSave(CPDFSDK_FormFillEnvironment* pFormFillEnv) override {}
+  void OnDoc_WillClose(CPDFSDK_FormFillEnvironment* pFormFillEnv) override {}
+  void OnPage_Open(CPDFSDK_FormFillEnvironment* pFormFillEnv) override {}
+  void OnPage_Close(CPDFSDK_FormFillEnvironment* pFormFillEnv) override {}
+  void OnPage_InView(CPDFSDK_FormFillEnvironment* pFormFillEnv) override {}
+  void OnPage_OutView(CPDFSDK_FormFillEnvironment* pFormFillEnv) override {}
+  void OnField_MouseDown(bool bModifier,
+                         bool bShift,
+                         CPDF_FormField* pTarget) override {}
+  void OnField_MouseEnter(bool bModifier,
+                          bool bShift,
+                          CPDF_FormField* pTarget) override {}
+  void OnField_MouseExit(bool bModifier,
+                         bool bShift,
+                         CPDF_FormField* pTarget) override {}
+  void OnField_MouseUp(bool bModifier,
+                       bool bShift,
+                       CPDF_FormField* pTarget) override {}
+  void OnField_Focus(bool bModifier,
+                     bool bShift,
+                     CPDF_FormField* pTarget,
+                     const CFX_WideString& Value) override {}
+  void OnField_Blur(bool bModifier,
+                    bool bShift,
+                    CPDF_FormField* pTarget,
+                    const CFX_WideString& Value) override {}
+  void OnField_Calculate(CPDF_FormField* pSource,
+                         CPDF_FormField* pTarget,
+                         CFX_WideString& Value,
+                         bool& bRc) override {}
+  void OnField_Format(CPDF_FormField* pTarget,
+                      CFX_WideString& Value,
+                      bool bWillCommit) override {}
+  void OnField_Keystroke(CFX_WideString& strChange,
+                         const CFX_WideString& strChangeEx,
+                         bool KeyDown,
+                         bool bModifier,
+                         int& nSelEnd,
+                         int& nSelStart,
+                         bool bShift,
+                         CPDF_FormField* pTarget,
+                         CFX_WideString& Value,
+                         bool bWillCommit,
+                         bool bFieldFull,
+                         bool& bRc) override {}
+  void OnField_Validate(CFX_WideString& strChange,
+                        const CFX_WideString& strChangeEx,
+                        bool bKeyDown,
+                        bool bModifier,
+                        bool bShift,
+                        CPDF_FormField* pTarget,
+                        CFX_WideString& Value,
+                        bool& bRc) override {}
+  void OnScreen_Focus(bool bModifier,
+                      bool bShift,
+                      CPDFSDK_Annot* pScreen) override {}
+  void OnScreen_Blur(bool bModifier,
+                     bool bShift,
+                     CPDFSDK_Annot* pScreen) override {}
+  void OnScreen_Open(bool bModifier,
+                     bool bShift,
+                     CPDFSDK_Annot* pScreen) override {}
+  void OnScreen_Close(bool bModifier,
+                      bool bShift,
+                      CPDFSDK_Annot* pScreen) override {}
+  void OnScreen_MouseDown(bool bModifier,
+                          bool bShift,
+                          CPDFSDK_Annot* pScreen) override {}
+  void OnScreen_MouseUp(bool bModifier,
+                        bool bShift,
+                        CPDFSDK_Annot* pScreen) override {}
+  void OnScreen_MouseEnter(bool bModifier,
+                           bool bShift,
+                           CPDFSDK_Annot* pScreen) override {}
+  void OnScreen_MouseExit(bool bModifier,
+                          bool bShift,
+                          CPDFSDK_Annot* pScreen) override {}
+  void OnScreen_InView(bool bModifier,
+                       bool bShift,
+                       CPDFSDK_Annot* pScreen) override {}
+  void OnScreen_OutView(bool bModifier,
+                        bool bShift,
+                        CPDFSDK_Annot* pScreen) override {}
+  void OnBookmark_MouseUp(CPDF_Bookmark* pBookMark) override {}
+  void OnLink_MouseUp(CPDFSDK_FormFillEnvironment* pFormFillEnv) override {}
+  void OnMenu_Exec(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                   const CFX_WideString&) override {}
+  void OnBatchExec(CPDFSDK_FormFillEnvironment* pFormFillEnv) override {}
+  void OnConsole_Exec() override {}
+  void OnExternal_Exec() override {}
+};
+
+class CJS_RuntimeStub final : public IJS_Runtime {
+ public:
+  explicit CJS_RuntimeStub(CPDFSDK_FormFillEnvironment* pFormFillEnv)
+      : m_pFormFillEnv(pFormFillEnv) {}
+  ~CJS_RuntimeStub() override {}
+
+  IJS_Context* NewContext() override {
+    if (!m_pContext)
+      m_pContext = pdfium::MakeUnique<CJS_ContextStub>();
+    return GetCurrentContext();
+  }
+
+  IJS_Context* GetCurrentContext() override { return m_pContext.get(); }
+  void ReleaseContext(IJS_Context* pContext) override {}
+
+  CPDFSDK_FormFillEnvironment* GetFormFillEnv() const override {
+    return m_pFormFillEnv;
+  }
+
+#ifdef PDF_ENABLE_XFA
+  bool GetValueByName(const CFX_ByteStringC&, CFXJSE_Value*) override {
+    return false;
+  }
+
+  bool SetValueByName(const CFX_ByteStringC&, CFXJSE_Value*) override {
+    return false;
+  }
+#endif  // PDF_ENABLE_XFA
+
+  int ExecuteScript(const CFX_WideString& script,
+                    CFX_WideString* info) override {
+    return 0;
+  }
+
+ protected:
+  CPDFSDK_FormFillEnvironment* m_pFormFillEnv;
+  std::unique_ptr<CJS_ContextStub> m_pContext;
+};
+
+// static
+void IJS_Runtime::Initialize(unsigned int slot, void* isolate) {}
+
+// static
+void IJS_Runtime::Destroy() {}
+
+// static
+IJS_Runtime* IJS_Runtime::Create(CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+  return new CJS_RuntimeStub(pFormFillEnv);
+}
diff --git a/fpdfsdk/javascript/JS_Value.cpp b/fpdfsdk/javascript/JS_Value.cpp
new file mode 100644
index 0000000..7900914
--- /dev/null
+++ b/fpdfsdk/javascript/JS_Value.cpp
@@ -0,0 +1,769 @@
+// 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
+
+#include "fpdfsdk/javascript/JS_Value.h"
+
+#include <time.h>
+
+#include <algorithm>
+#include <cmath>
+#include <limits>
+#include <vector>
+
+#include "fpdfsdk/javascript/Document.h"
+#include "fpdfsdk/javascript/JS_Define.h"
+#include "fpdfsdk/javascript/JS_Object.h"
+
+namespace {
+
+const uint32_t g_nan[2] = {0, 0x7FF80000};
+
+double GetNan() {
+  return *(double*)g_nan;
+}
+
+double
+MakeDate(int year, int mon, int day, int hour, int min, int sec, int ms) {
+  return JS_MakeDate(JS_MakeDay(year, mon, day),
+                     JS_MakeTime(hour, min, sec, ms));
+}
+
+}  // namespace
+
+CJS_Value::CJS_Value(CJS_Runtime* pRuntime) {}
+
+CJS_Value::CJS_Value(CJS_Runtime* pRuntime, v8::Local<v8::Value> pValue)
+    : m_pValue(pValue) {}
+
+CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const int& iValue)
+    : m_pValue(pRuntime->NewNumber(iValue)) {}
+
+CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const bool& bValue)
+    : m_pValue(pRuntime->NewBoolean(bValue)) {}
+
+CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const float& fValue)
+    : m_pValue(pRuntime->NewNumber(fValue)) {}
+
+CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const double& dValue)
+    : m_pValue(pRuntime->NewNumber(dValue)) {}
+
+CJS_Value::CJS_Value(CJS_Runtime* pRuntime, CJS_Object* pObj) {
+  if (pObj)
+    m_pValue = pObj->ToV8Object();
+}
+
+CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const FX_WCHAR* pWstr)
+    : m_pValue(pRuntime->NewString(pWstr)) {}
+
+CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const FX_CHAR* pStr)
+    : m_pValue(pRuntime->NewString(CFX_WideString::FromLocal(pStr).c_str())) {}
+
+CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const CJS_Array& array)
+    : m_pValue(array.ToV8Array(pRuntime)) {}
+
+CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const CJS_Date& date)
+    : m_pValue(date.ToV8Date(pRuntime)) {}
+
+CJS_Value::~CJS_Value() {}
+
+CJS_Value::CJS_Value(const CJS_Value& other) = default;
+
+void CJS_Value::Attach(v8::Local<v8::Value> pValue) {
+  m_pValue = pValue;
+}
+
+void CJS_Value::Detach() {
+  m_pValue = v8::Local<v8::Value>();
+}
+
+int CJS_Value::ToInt(CJS_Runtime* pRuntime) const {
+  return pRuntime->ToInt32(m_pValue);
+}
+
+bool CJS_Value::ToBool(CJS_Runtime* pRuntime) const {
+  return pRuntime->ToBoolean(m_pValue);
+}
+
+double CJS_Value::ToDouble(CJS_Runtime* pRuntime) const {
+  return pRuntime->ToDouble(m_pValue);
+}
+
+float CJS_Value::ToFloat(CJS_Runtime* pRuntime) const {
+  return (float)ToDouble(pRuntime);
+}
+
+CJS_Object* CJS_Value::ToCJSObject(CJS_Runtime* pRuntime) const {
+  v8::Local<v8::Object> pObj = pRuntime->ToObject(m_pValue);
+  return static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(pObj));
+}
+
+v8::Local<v8::Object> CJS_Value::ToV8Object(CJS_Runtime* pRuntime) const {
+  return pRuntime->ToObject(m_pValue);
+}
+
+CFX_WideString CJS_Value::ToCFXWideString(CJS_Runtime* pRuntime) const {
+  return pRuntime->ToWideString(m_pValue);
+}
+
+CFX_ByteString CJS_Value::ToCFXByteString(CJS_Runtime* pRuntime) const {
+  return CFX_ByteString::FromUnicode(ToCFXWideString(pRuntime));
+}
+
+v8::Local<v8::Value> CJS_Value::ToV8Value(CJS_Runtime* pRuntime) const {
+  return m_pValue;
+}
+
+v8::Local<v8::Array> CJS_Value::ToV8Array(CJS_Runtime* pRuntime) const {
+  return pRuntime->ToArray(m_pValue);
+}
+
+void CJS_Value::SetNull(CJS_Runtime* pRuntime) {
+  m_pValue = pRuntime->NewNull();
+}
+
+void CJS_Value::MaybeCoerceToNumber(CJS_Runtime* pRuntime) {
+  bool bAllowNaN = false;
+  if (GetType() == VT_string) {
+    CFX_ByteString bstr = ToCFXByteString(pRuntime);
+    if (bstr.GetLength() == 0)
+      return;
+    if (bstr == "NaN")
+      bAllowNaN = true;
+  }
+  v8::Isolate* pIsolate = pRuntime->GetIsolate();
+  v8::TryCatch try_catch(pIsolate);
+  v8::MaybeLocal<v8::Number> maybeNum =
+      m_pValue->ToNumber(pIsolate->GetCurrentContext());
+  if (maybeNum.IsEmpty())
+    return;
+  v8::Local<v8::Number> num = maybeNum.ToLocalChecked();
+  if (std::isnan(num->Value()) && !bAllowNaN)
+    return;
+  m_pValue = num;
+}
+
+// static
+CJS_Value::Type CJS_Value::GetValueType(v8::Local<v8::Value> value) {
+  if (value.IsEmpty())
+    return VT_unknown;
+  if (value->IsString())
+    return VT_string;
+  if (value->IsNumber())
+    return VT_number;
+  if (value->IsBoolean())
+    return VT_boolean;
+  if (value->IsDate())
+    return VT_date;
+  if (value->IsObject())
+    return VT_object;
+  if (value->IsNull())
+    return VT_null;
+  if (value->IsUndefined())
+    return VT_undefined;
+  return VT_unknown;
+}
+
+bool CJS_Value::IsArrayObject() const {
+  return !m_pValue.IsEmpty() && m_pValue->IsArray();
+}
+
+bool CJS_Value::IsDateObject() const {
+  return !m_pValue.IsEmpty() && m_pValue->IsDate();
+}
+
+bool CJS_Value::ConvertToArray(CJS_Runtime* pRuntime, CJS_Array& array) const {
+  if (!IsArrayObject())
+    return false;
+  array.Attach(pRuntime->ToArray(m_pValue));
+  return true;
+}
+
+bool CJS_Value::ConvertToDate(CJS_Runtime* pRuntime, CJS_Date& date) const {
+  if (!IsDateObject())
+    return false;
+  v8::Local<v8::Value> mutable_value = m_pValue;
+  date.Attach(mutable_value.As<v8::Date>());
+  return true;
+}
+
+CJS_PropValue::CJS_PropValue(CJS_Runtime* pRuntime)
+    : m_bIsSetting(0), m_Value(pRuntime), m_pJSRuntime(pRuntime) {}
+
+CJS_PropValue::CJS_PropValue(CJS_Runtime* pRuntime, const CJS_Value& value)
+    : m_bIsSetting(0), m_Value(value), m_pJSRuntime(pRuntime) {}
+
+CJS_PropValue::~CJS_PropValue() {}
+
+void CJS_PropValue::operator<<(int iValue) {
+  ASSERT(!m_bIsSetting);
+  m_Value = CJS_Value(m_pJSRuntime, iValue);
+}
+
+void CJS_PropValue::operator>>(int& iValue) const {
+  ASSERT(m_bIsSetting);
+  iValue = m_Value.ToInt(m_pJSRuntime);
+}
+
+void CJS_PropValue::operator<<(bool bValue) {
+  ASSERT(!m_bIsSetting);
+  m_Value = CJS_Value(m_pJSRuntime, bValue);
+}
+
+void CJS_PropValue::operator>>(bool& bValue) const {
+  ASSERT(m_bIsSetting);
+  bValue = m_Value.ToBool(m_pJSRuntime);
+}
+
+void CJS_PropValue::operator<<(double dValue) {
+  ASSERT(!m_bIsSetting);
+  m_Value = CJS_Value(m_pJSRuntime, dValue);
+}
+
+void CJS_PropValue::operator>>(double& dValue) const {
+  ASSERT(m_bIsSetting);
+  dValue = m_Value.ToDouble(m_pJSRuntime);
+}
+
+void CJS_PropValue::operator<<(CJS_Object* pObj) {
+  ASSERT(!m_bIsSetting);
+  m_Value = CJS_Value(m_pJSRuntime, pObj);
+}
+
+void CJS_PropValue::operator>>(CJS_Object*& ppObj) const {
+  ASSERT(m_bIsSetting);
+  ppObj = m_Value.ToCJSObject(m_pJSRuntime);
+}
+
+void CJS_PropValue::operator<<(CJS_Document* pJsDoc) {
+  ASSERT(!m_bIsSetting);
+  m_Value = CJS_Value(m_pJSRuntime, pJsDoc);
+}
+
+void CJS_PropValue::operator>>(CJS_Document*& ppJsDoc) const {
+  ASSERT(m_bIsSetting);
+  ppJsDoc = static_cast<CJS_Document*>(m_Value.ToCJSObject(m_pJSRuntime));
+}
+
+void CJS_PropValue::operator<<(v8::Local<v8::Object> pObj) {
+  ASSERT(!m_bIsSetting);
+  m_Value = CJS_Value(m_pJSRuntime, pObj);
+}
+
+void CJS_PropValue::operator>>(v8::Local<v8::Object>& ppObj) const {
+  ASSERT(m_bIsSetting);
+  ppObj = m_Value.ToV8Object(m_pJSRuntime);
+}
+
+void CJS_PropValue::operator<<(CFX_ByteString str) {
+  ASSERT(!m_bIsSetting);
+  m_Value = CJS_Value(m_pJSRuntime, str.c_str());
+}
+
+void CJS_PropValue::operator>>(CFX_ByteString& str) const {
+  ASSERT(m_bIsSetting);
+  str = m_Value.ToCFXByteString(m_pJSRuntime);
+}
+
+void CJS_PropValue::operator<<(const FX_WCHAR* str) {
+  ASSERT(!m_bIsSetting);
+  m_Value = CJS_Value(m_pJSRuntime, str);
+}
+
+void CJS_PropValue::operator>>(CFX_WideString& wide_string) const {
+  ASSERT(m_bIsSetting);
+  wide_string = m_Value.ToCFXWideString(m_pJSRuntime);
+}
+
+void CJS_PropValue::operator<<(CFX_WideString wide_string) {
+  ASSERT(!m_bIsSetting);
+  m_Value = CJS_Value(m_pJSRuntime, wide_string.c_str());
+}
+
+void CJS_PropValue::operator>>(CJS_Array& array) const {
+  ASSERT(m_bIsSetting);
+  m_Value.ConvertToArray(m_pJSRuntime, array);
+}
+
+void CJS_PropValue::operator<<(CJS_Array& array) {
+  ASSERT(!m_bIsSetting);
+  m_Value = CJS_Value(m_pJSRuntime, array.ToV8Array(m_pJSRuntime));
+}
+
+void CJS_PropValue::operator>>(CJS_Date& date) const {
+  ASSERT(m_bIsSetting);
+  m_Value.ConvertToDate(m_pJSRuntime, date);
+}
+
+void CJS_PropValue::operator<<(CJS_Date& date) {
+  ASSERT(!m_bIsSetting);
+  m_Value = CJS_Value(m_pJSRuntime, date);
+}
+
+CJS_Array::CJS_Array() {}
+
+CJS_Array::CJS_Array(const CJS_Array& other) = default;
+
+CJS_Array::~CJS_Array() {}
+
+void CJS_Array::Attach(v8::Local<v8::Array> pArray) {
+  m_pArray = pArray;
+}
+
+void CJS_Array::GetElement(CJS_Runtime* pRuntime,
+                           unsigned index,
+                           CJS_Value& value) const {
+  if (!m_pArray.IsEmpty())
+    value.Attach(pRuntime->GetArrayElement(m_pArray, index));
+}
+
+void CJS_Array::SetElement(CJS_Runtime* pRuntime,
+                           unsigned index,
+                           const CJS_Value& value) {
+  if (m_pArray.IsEmpty())
+    m_pArray = pRuntime->NewArray();
+
+  pRuntime->PutArrayElement(m_pArray, index, value.ToV8Value(pRuntime));
+}
+
+int CJS_Array::GetLength(CJS_Runtime* pRuntime) const {
+  if (m_pArray.IsEmpty())
+    return 0;
+  return pRuntime->GetArrayLength(m_pArray);
+}
+
+v8::Local<v8::Array> CJS_Array::ToV8Array(CJS_Runtime* pRuntime) const {
+  if (m_pArray.IsEmpty())
+    m_pArray = pRuntime->NewArray();
+
+  return m_pArray;
+}
+
+CJS_Date::CJS_Date() {}
+
+CJS_Date::CJS_Date(CJS_Runtime* pRuntime, double dMsecTime)
+    : m_pDate(pRuntime->NewDate(dMsecTime)) {}
+
+CJS_Date::CJS_Date(CJS_Runtime* pRuntime,
+                   int year,
+                   int mon,
+                   int day,
+                   int hour,
+                   int min,
+                   int sec)
+    : m_pDate(pRuntime->NewDate(MakeDate(year, mon, day, hour, min, sec, 0))) {}
+
+CJS_Date::~CJS_Date() {}
+
+bool CJS_Date::IsValidDate(CJS_Runtime* pRuntime) const {
+  return !m_pDate.IsEmpty() && !JS_PortIsNan(pRuntime->ToDouble(m_pDate));
+}
+
+void CJS_Date::Attach(v8::Local<v8::Date> pDate) {
+  m_pDate = pDate;
+}
+
+int CJS_Date::GetYear(CJS_Runtime* pRuntime) const {
+  if (!IsValidDate(pRuntime))
+    return 0;
+
+  return JS_GetYearFromTime(JS_LocalTime(pRuntime->ToDouble(m_pDate)));
+}
+
+void CJS_Date::SetYear(CJS_Runtime* pRuntime, int iYear) {
+  m_pDate = pRuntime->NewDate(
+      MakeDate(iYear, GetMonth(pRuntime), GetDay(pRuntime), GetHours(pRuntime),
+               GetMinutes(pRuntime), GetSeconds(pRuntime), 0));
+}
+
+int CJS_Date::GetMonth(CJS_Runtime* pRuntime) const {
+  if (!IsValidDate(pRuntime))
+    return 0;
+
+  return JS_GetMonthFromTime(JS_LocalTime(pRuntime->ToDouble(m_pDate)));
+}
+
+void CJS_Date::SetMonth(CJS_Runtime* pRuntime, int iMonth) {
+  m_pDate = pRuntime->NewDate(
+      MakeDate(GetYear(pRuntime), iMonth, GetDay(pRuntime), GetHours(pRuntime),
+               GetMinutes(pRuntime), GetSeconds(pRuntime), 0));
+}
+
+int CJS_Date::GetDay(CJS_Runtime* pRuntime) const {
+  if (!IsValidDate(pRuntime))
+    return 0;
+
+  return JS_GetDayFromTime(JS_LocalTime(pRuntime->ToDouble(m_pDate)));
+}
+
+void CJS_Date::SetDay(CJS_Runtime* pRuntime, int iDay) {
+  m_pDate = pRuntime->NewDate(
+      MakeDate(GetYear(pRuntime), GetMonth(pRuntime), iDay, GetHours(pRuntime),
+               GetMinutes(pRuntime), GetSeconds(pRuntime), 0));
+}
+
+int CJS_Date::GetHours(CJS_Runtime* pRuntime) const {
+  if (!IsValidDate(pRuntime))
+    return 0;
+
+  return JS_GetHourFromTime(JS_LocalTime(pRuntime->ToDouble(m_pDate)));
+}
+
+void CJS_Date::SetHours(CJS_Runtime* pRuntime, int iHours) {
+  m_pDate = pRuntime->NewDate(
+      MakeDate(GetYear(pRuntime), GetMonth(pRuntime), GetDay(pRuntime), iHours,
+               GetMinutes(pRuntime), GetSeconds(pRuntime), 0));
+}
+
+int CJS_Date::GetMinutes(CJS_Runtime* pRuntime) const {
+  if (!IsValidDate(pRuntime))
+    return 0;
+
+  return JS_GetMinFromTime(JS_LocalTime(pRuntime->ToDouble(m_pDate)));
+}
+
+void CJS_Date::SetMinutes(CJS_Runtime* pRuntime, int minutes) {
+  m_pDate = pRuntime->NewDate(MakeDate(GetYear(pRuntime), GetMonth(pRuntime),
+                                       GetDay(pRuntime), GetHours(pRuntime),
+                                       minutes, GetSeconds(pRuntime), 0));
+}
+
+int CJS_Date::GetSeconds(CJS_Runtime* pRuntime) const {
+  if (!IsValidDate(pRuntime))
+    return 0;
+
+  return JS_GetSecFromTime(JS_LocalTime(pRuntime->ToDouble(m_pDate)));
+}
+
+void CJS_Date::SetSeconds(CJS_Runtime* pRuntime, int seconds) {
+  m_pDate = pRuntime->NewDate(MakeDate(GetYear(pRuntime), GetMonth(pRuntime),
+                                       GetDay(pRuntime), GetHours(pRuntime),
+                                       GetMinutes(pRuntime), seconds, 0));
+}
+
+double CJS_Date::ToDouble(CJS_Runtime* pRuntime) const {
+  return !m_pDate.IsEmpty() ? pRuntime->ToDouble(m_pDate) : 0.0;
+}
+
+CFX_WideString CJS_Date::ToString(CJS_Runtime* pRuntime) const {
+  return !m_pDate.IsEmpty() ? pRuntime->ToWideString(m_pDate)
+                            : CFX_WideString();
+}
+
+v8::Local<v8::Date> CJS_Date::ToV8Date(CJS_Runtime* pRuntime) const {
+  return m_pDate;
+}
+
+double _getLocalTZA() {
+  if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
+    return 0;
+  time_t t = 0;
+  time(&t);
+  localtime(&t);
+#if _MSC_VER >= 1900
+  // In gcc and in Visual Studio prior to VS 2015 'timezone' is a global
+  // variable declared in time.h. That variable was deprecated and in VS 2015
+  // is removed, with _get_timezone replacing it.
+  long timezone = 0;
+  _get_timezone(&timezone);
+#endif
+  return (double)(-(timezone * 1000));
+}
+
+int _getDaylightSavingTA(double d) {
+  if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
+    return 0;
+  time_t t = (time_t)(d / 1000);
+  struct tm* tmp = localtime(&t);
+  if (!tmp)
+    return 0;
+  if (tmp->tm_isdst > 0)
+    // One hour.
+    return (int)60 * 60 * 1000;
+  return 0;
+}
+
+double _Mod(double x, double y) {
+  double r = fmod(x, y);
+  if (r < 0)
+    r += y;
+  return r;
+}
+
+int _isfinite(double v) {
+#if _MSC_VER
+  return ::_finite(v);
+#else
+  return std::fabs(v) < std::numeric_limits<double>::max();
+#endif
+}
+
+double _toInteger(double n) {
+  return (n >= 0) ? FXSYS_floor(n) : -FXSYS_floor(-n);
+}
+
+bool _isLeapYear(int year) {
+  return (year % 4 == 0) && ((year % 100 != 0) || (year % 400 != 0));
+}
+
+int _DayFromYear(int y) {
+  return (int)(365 * (y - 1970.0) + FXSYS_floor((y - 1969.0) / 4) -
+               FXSYS_floor((y - 1901.0) / 100) +
+               FXSYS_floor((y - 1601.0) / 400));
+}
+
+double _TimeFromYear(int y) {
+  return 86400000.0 * _DayFromYear(y);
+}
+
+static const uint16_t daysMonth[12] = {0,   31,  59,  90,  120, 151,
+                                       181, 212, 243, 273, 304, 334};
+static const uint16_t leapDaysMonth[12] = {0,   31,  60,  91,  121, 152,
+                                           182, 213, 244, 274, 305, 335};
+
+double _TimeFromYearMonth(int y, int m) {
+  const uint16_t* pMonth = _isLeapYear(y) ? leapDaysMonth : daysMonth;
+  return _TimeFromYear(y) + ((double)pMonth[m]) * 86400000;
+}
+
+int _Day(double t) {
+  return (int)FXSYS_floor(t / 86400000);
+}
+
+int _YearFromTime(double t) {
+  // estimate the time.
+  int y = 1970 + static_cast<int>(t / (365.2425 * 86400000));
+  if (_TimeFromYear(y) <= t) {
+    while (_TimeFromYear(y + 1) <= t)
+      y++;
+  } else {
+    while (_TimeFromYear(y) > t)
+      y--;
+  }
+  return y;
+}
+
+int _DayWithinYear(double t) {
+  int year = _YearFromTime(t);
+  int day = _Day(t);
+  return day - _DayFromYear(year);
+}
+
+int _MonthFromTime(double t) {
+  int day = _DayWithinYear(t);
+  int year = _YearFromTime(t);
+  if (0 <= day && day < 31)
+    return 0;
+  if (31 <= day && day < 59 + _isLeapYear(year))
+    return 1;
+  if ((59 + _isLeapYear(year)) <= day && day < (90 + _isLeapYear(year)))
+    return 2;
+  if ((90 + _isLeapYear(year)) <= day && day < (120 + _isLeapYear(year)))
+    return 3;
+  if ((120 + _isLeapYear(year)) <= day && day < (151 + _isLeapYear(year)))
+    return 4;
+  if ((151 + _isLeapYear(year)) <= day && day < (181 + _isLeapYear(year)))
+    return 5;
+  if ((181 + _isLeapYear(year)) <= day && day < (212 + _isLeapYear(year)))
+    return 6;
+  if ((212 + _isLeapYear(year)) <= day && day < (243 + _isLeapYear(year)))
+    return 7;
+  if ((243 + _isLeapYear(year)) <= day && day < (273 + _isLeapYear(year)))
+    return 8;
+  if ((273 + _isLeapYear(year)) <= day && day < (304 + _isLeapYear(year)))
+    return 9;
+  if ((304 + _isLeapYear(year)) <= day && day < (334 + _isLeapYear(year)))
+    return 10;
+  if ((334 + _isLeapYear(year)) <= day && day < (365 + _isLeapYear(year)))
+    return 11;
+
+  return -1;
+}
+
+int _DateFromTime(double t) {
+  int day = _DayWithinYear(t);
+  int year = _YearFromTime(t);
+  int leap = _isLeapYear(year);
+  int month = _MonthFromTime(t);
+  switch (month) {
+    case 0:
+      return day + 1;
+    case 1:
+      return day - 30;
+    case 2:
+      return day - 58 - leap;
+    case 3:
+      return day - 89 - leap;
+    case 4:
+      return day - 119 - leap;
+    case 5:
+      return day - 150 - leap;
+    case 6:
+      return day - 180 - leap;
+    case 7:
+      return day - 211 - leap;
+    case 8:
+      return day - 242 - leap;
+    case 9:
+      return day - 272 - leap;
+    case 10:
+      return day - 303 - leap;
+    case 11:
+      return day - 333 - leap;
+    default:
+      return 0;
+  }
+}
+
+double JS_GetDateTime() {
+  if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
+    return 0;
+  time_t t = time(nullptr);
+  struct tm* pTm = localtime(&t);
+
+  int year = pTm->tm_year + 1900;
+  double t1 = _TimeFromYear(year);
+
+  return t1 + pTm->tm_yday * 86400000.0 + pTm->tm_hour * 3600000.0 +
+         pTm->tm_min * 60000.0 + pTm->tm_sec * 1000.0;
+}
+
+int JS_GetYearFromTime(double dt) {
+  return _YearFromTime(dt);
+}
+
+int JS_GetMonthFromTime(double dt) {
+  return _MonthFromTime(dt);
+}
+
+int JS_GetDayFromTime(double dt) {
+  return _DateFromTime(dt);
+}
+
+int JS_GetHourFromTime(double dt) {
+  return (int)_Mod(floor(dt / (60 * 60 * 1000)), 24);
+}
+
+int JS_GetMinFromTime(double dt) {
+  return (int)_Mod(floor(dt / (60 * 1000)), 60);
+}
+
+int JS_GetSecFromTime(double dt) {
+  return (int)_Mod(floor(dt / 1000), 60);
+}
+
+double JS_DateParse(const CFX_WideString& str) {
+  v8::Isolate* pIsolate = v8::Isolate::GetCurrent();
+  v8::Isolate::Scope isolate_scope(pIsolate);
+  v8::HandleScope scope(pIsolate);
+
+  v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
+
+  // Use the built-in object method.
+  v8::Local<v8::Value> v =
+      context->Global()
+          ->Get(context, v8::String::NewFromUtf8(pIsolate, "Date",
+                                                 v8::NewStringType::kNormal)
+                             .ToLocalChecked())
+          .ToLocalChecked();
+  if (v->IsObject()) {
+    v8::Local<v8::Object> o = v->ToObject(context).ToLocalChecked();
+    v = o->Get(context, v8::String::NewFromUtf8(pIsolate, "parse",
+                                                v8::NewStringType::kNormal)
+                            .ToLocalChecked())
+            .ToLocalChecked();
+    if (v->IsFunction()) {
+      v8::Local<v8::Function> funC = v8::Local<v8::Function>::Cast(v);
+      const int argc = 1;
+      v8::Local<v8::String> timeStr =
+          CJS_Runtime::CurrentRuntimeFromIsolate(pIsolate)->WSToJSString(str);
+      v8::Local<v8::Value> argv[argc] = {timeStr};
+      v = funC->Call(context, context->Global(), argc, argv).ToLocalChecked();
+      if (v->IsNumber()) {
+        double date = v->ToNumber(context).ToLocalChecked()->Value();
+        if (!_isfinite(date))
+          return date;
+        return JS_LocalTime(date);
+      }
+    }
+  }
+  return 0;
+}
+
+double JS_MakeDay(int nYear, int nMonth, int nDate) {
+  if (!_isfinite(nYear) || !_isfinite(nMonth) || !_isfinite(nDate))
+    return GetNan();
+  double y = _toInteger(nYear);
+  double m = _toInteger(nMonth);
+  double dt = _toInteger(nDate);
+  double ym = y + FXSYS_floor((double)m / 12);
+  double mn = _Mod(m, 12);
+
+  double t = _TimeFromYearMonth((int)ym, (int)mn);
+
+  if (_YearFromTime(t) != ym || _MonthFromTime(t) != mn ||
+      _DateFromTime(t) != 1)
+    return GetNan();
+  return _Day(t) + dt - 1;
+}
+
+double JS_MakeTime(int nHour, int nMin, int nSec, int nMs) {
+  if (!_isfinite(nHour) || !_isfinite(nMin) || !_isfinite(nSec) ||
+      !_isfinite(nMs))
+    return GetNan();
+
+  double h = _toInteger(nHour);
+  double m = _toInteger(nMin);
+  double s = _toInteger(nSec);
+  double milli = _toInteger(nMs);
+
+  return h * 3600000 + m * 60000 + s * 1000 + milli;
+}
+
+double JS_MakeDate(double day, double time) {
+  if (!_isfinite(day) || !_isfinite(time))
+    return GetNan();
+
+  return day * 86400000 + time;
+}
+
+bool JS_PortIsNan(double d) {
+  return d != d;
+}
+
+double JS_LocalTime(double d) {
+  return d + _getLocalTZA() + _getDaylightSavingTA(d);
+}
+
+std::vector<CJS_Value> JS_ExpandKeywordParams(
+    CJS_Runtime* pRuntime,
+    const std::vector<CJS_Value>& originals,
+    size_t nKeywords,
+    ...) {
+  ASSERT(nKeywords);
+
+  std::vector<CJS_Value> result(nKeywords, CJS_Value(pRuntime));
+  size_t size = std::min(originals.size(), nKeywords);
+  for (size_t i = 0; i < size; ++i)
+    result[i] = originals[i];
+
+  if (originals.size() != 1 || originals[0].GetType() != CJS_Value::VT_object ||
+      originals[0].IsArrayObject()) {
+    return result;
+  }
+  v8::Local<v8::Object> pObj = originals[0].ToV8Object(pRuntime);
+  result[0] = CJS_Value(pRuntime);  // Make unknown.
+
+  va_list ap;
+  va_start(ap, nKeywords);
+  for (size_t i = 0; i < nKeywords; ++i) {
+    const wchar_t* property = va_arg(ap, const wchar_t*);
+    v8::Local<v8::Value> v8Value = pRuntime->GetObjectProperty(pObj, property);
+    if (!v8Value->IsUndefined())
+      result[i] = CJS_Value(pRuntime, v8Value);
+  }
+  va_end(ap);
+  return result;
+}
diff --git a/fpdfsdk/javascript/JS_Value.h b/fpdfsdk/javascript/JS_Value.h
new file mode 100644
index 0000000..313f0c3
--- /dev/null
+++ b/fpdfsdk/javascript/JS_Value.h
@@ -0,0 +1,215 @@
+// 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_JAVASCRIPT_JS_VALUE_H_
+#define FPDFSDK_JAVASCRIPT_JS_VALUE_H_
+
+#include <vector>
+
+#include "core/fxcrt/fx_basic.h"
+#include "fxjs/fxjs_v8.h"
+
+class CJS_Array;
+class CJS_Date;
+class CJS_Document;
+class CJS_Object;
+class CJS_Runtime;
+
+class CJS_Value {
+ public:
+  enum Type {
+    VT_unknown,
+    VT_string,
+    VT_number,
+    VT_boolean,
+    VT_date,
+    VT_object,
+    VT_null,
+    VT_undefined
+  };
+
+  explicit CJS_Value(CJS_Runtime* pRuntime);
+  CJS_Value(CJS_Runtime* pRuntime, v8::Local<v8::Value> pValue);
+  CJS_Value(CJS_Runtime* pRuntime, const int& iValue);
+  CJS_Value(CJS_Runtime* pRuntime, const double& dValue);
+  CJS_Value(CJS_Runtime* pRuntime, const float& fValue);
+  CJS_Value(CJS_Runtime* pRuntime, const bool& bValue);
+  CJS_Value(CJS_Runtime* pRuntime, CJS_Object* pObj);
+  CJS_Value(CJS_Runtime* pRuntime, const FX_CHAR* pStr);
+  CJS_Value(CJS_Runtime* pRuntime, const FX_WCHAR* pWstr);
+  CJS_Value(CJS_Runtime* pRuntime, const CJS_Array& array);
+  CJS_Value(CJS_Runtime* pRuntime, const CJS_Date& date);
+  CJS_Value(CJS_Runtime* pRuntime, const CJS_Object* object);
+  CJS_Value(const CJS_Value& other);
+
+  ~CJS_Value();
+
+  void SetNull(CJS_Runtime* pRuntime);
+  void SetValue(const CJS_Value& other);
+  void Attach(v8::Local<v8::Value> pValue);
+  void Detach();
+
+  static Type GetValueType(v8::Local<v8::Value> value);
+  Type GetType() const { return GetValueType(m_pValue); }
+
+  int ToInt(CJS_Runtime* pRuntime) const;
+  bool ToBool(CJS_Runtime* pRuntime) const;
+  double ToDouble(CJS_Runtime* pRuntime) const;
+  float ToFloat(CJS_Runtime* pRuntime) const;
+  CJS_Object* ToCJSObject(CJS_Runtime* pRuntime) const;
+  CFX_WideString ToCFXWideString(CJS_Runtime* pRuntime) const;
+  CFX_ByteString ToCFXByteString(CJS_Runtime* pRuntime) const;
+  v8::Local<v8::Object> ToV8Object(CJS_Runtime* pRuntime) const;
+  v8::Local<v8::Array> ToV8Array(CJS_Runtime* pRuntime) const;
+  v8::Local<v8::Value> ToV8Value(CJS_Runtime* pRuntime) const;
+
+  // Replace the current |m_pValue| with a v8::Number if possible
+  // to make one from the current |m_pValue|.
+  void MaybeCoerceToNumber(CJS_Runtime* pRuntime);
+
+  bool IsArrayObject() const;
+  bool IsDateObject() const;
+  bool ConvertToArray(CJS_Runtime* pRuntime, CJS_Array&) const;
+  bool ConvertToDate(CJS_Runtime* pRuntime, CJS_Date&) const;
+
+ protected:
+  v8::Local<v8::Value> m_pValue;
+};
+
+class CJS_PropValue {
+ public:
+  explicit CJS_PropValue(CJS_Runtime* pRuntime);
+  CJS_PropValue(CJS_Runtime* pRuntime, const CJS_Value&);
+  ~CJS_PropValue();
+
+  void StartSetting() { m_bIsSetting = true; }
+  void StartGetting() { m_bIsSetting = false; }
+  bool IsSetting() const { return m_bIsSetting; }
+  bool IsGetting() const { return !m_bIsSetting; }
+  CJS_Runtime* GetJSRuntime() const { return m_pJSRuntime; }
+  CJS_Value* GetJSValue() { return &m_Value; }
+
+  // These calls may re-enter JS (and hence invalidate objects).
+  void operator<<(int val);
+  void operator>>(int&) const;
+  void operator<<(bool val);
+  void operator>>(bool&) const;
+  void operator<<(double val);
+  void operator>>(double&) const;
+  void operator<<(CJS_Object* pObj);
+  void operator>>(CJS_Object*& ppObj) const;
+  void operator<<(CJS_Document* pJsDoc);
+  void operator>>(CJS_Document*& ppJsDoc) const;
+  void operator<<(CFX_ByteString);
+  void operator>>(CFX_ByteString&) const;
+  void operator<<(CFX_WideString);
+  void operator>>(CFX_WideString&) const;
+  void operator<<(const FX_WCHAR* c_string);
+  void operator<<(v8::Local<v8::Object>);
+  void operator>>(v8::Local<v8::Object>&) const;
+  void operator>>(CJS_Array& array) const;
+  void operator<<(CJS_Array& array);
+  void operator<<(CJS_Date& date);
+  void operator>>(CJS_Date& date) const;
+
+ private:
+  bool m_bIsSetting;
+  CJS_Value m_Value;
+  CJS_Runtime* const m_pJSRuntime;
+};
+
+class CJS_Array {
+ public:
+  CJS_Array();
+  CJS_Array(const CJS_Array& other);
+  virtual ~CJS_Array();
+
+  void Attach(v8::Local<v8::Array> pArray);
+  int GetLength(CJS_Runtime* pRuntime) const;
+
+  // These two calls may re-enter JS (and hence invalidate objects).
+  void GetElement(CJS_Runtime* pRuntime,
+                  unsigned index,
+                  CJS_Value& value) const;
+  void SetElement(CJS_Runtime* pRuntime,
+                  unsigned index,
+                  const CJS_Value& value);
+
+  v8::Local<v8::Array> ToV8Array(CJS_Runtime* pRuntime) const;
+
+ private:
+  mutable v8::Local<v8::Array> m_pArray;
+};
+
+class CJS_Date {
+ public:
+  CJS_Date();
+  CJS_Date(CJS_Runtime* pRuntime, double dMsec_time);
+  CJS_Date(CJS_Runtime* pRuntime,
+           int year,
+           int mon,
+           int day,
+           int hour,
+           int min,
+           int sec);
+  virtual ~CJS_Date();
+
+  void Attach(v8::Local<v8::Date> pDate);
+  bool IsValidDate(CJS_Runtime* pRuntime) const;
+
+  int GetYear(CJS_Runtime* pRuntime) const;
+  void SetYear(CJS_Runtime* pRuntime, int iYear);
+
+  int GetMonth(CJS_Runtime* pRuntime) const;
+  void SetMonth(CJS_Runtime* pRuntime, int iMonth);
+
+  int GetDay(CJS_Runtime* pRuntime) const;
+  void SetDay(CJS_Runtime* pRuntime, int iDay);
+
+  int GetHours(CJS_Runtime* pRuntime) const;
+  void SetHours(CJS_Runtime* pRuntime, int iHours);
+
+  int GetMinutes(CJS_Runtime* pRuntime) const;
+  void SetMinutes(CJS_Runtime* pRuntime, int minutes);
+
+  int GetSeconds(CJS_Runtime* pRuntime) const;
+  void SetSeconds(CJS_Runtime* pRuntime, int seconds);
+
+  v8::Local<v8::Date> ToV8Date(CJS_Runtime* pRuntime) const;
+  double ToDouble(CJS_Runtime* pRuntime) const;
+  CFX_WideString ToString(CJS_Runtime* pRuntime) const;
+
+ protected:
+  v8::Local<v8::Date> m_pDate;
+};
+
+double JS_GetDateTime();
+int JS_GetYearFromTime(double dt);
+int JS_GetMonthFromTime(double dt);
+int JS_GetDayFromTime(double dt);
+int JS_GetHourFromTime(double dt);
+int JS_GetMinFromTime(double dt);
+int JS_GetSecFromTime(double dt);
+double JS_DateParse(const CFX_WideString& str);
+double JS_MakeDay(int nYear, int nMonth, int nDay);
+double JS_MakeTime(int nHour, int nMin, int nSec, int nMs);
+double JS_MakeDate(double day, double time);
+bool JS_PortIsNan(double d);
+double JS_LocalTime(double d);
+
+// Some JS methods have the bizarre convention that they may also be called
+// with a single argument which is an object containing the actual arguments
+// as its properties. The varying arguments to this method are the property
+// names as wchar_t string literals corresponding to each positional argument.
+// The result will always contain |nKeywords| value, with unspecified ones
+// being set to type VT_unknown.
+std::vector<CJS_Value> JS_ExpandKeywordParams(
+    CJS_Runtime* pRuntime,
+    const std::vector<CJS_Value>& originals,
+    size_t nKeywords,
+    ...);
+
+#endif  // FPDFSDK_JAVASCRIPT_JS_VALUE_H_
diff --git a/fpdfsdk/javascript/PublicMethods.cpp b/fpdfsdk/javascript/PublicMethods.cpp
new file mode 100644
index 0000000..c0ea84c
--- /dev/null
+++ b/fpdfsdk/javascript/PublicMethods.cpp
@@ -0,0 +1,1828 @@
+// 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
+
+#include "fpdfsdk/javascript/PublicMethods.h"
+
+#include <algorithm>
+#include <iomanip>
+#include <limits>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include "core/fpdfdoc/cpdf_interform.h"
+#include "core/fxcrt/fx_ext.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/cpdfsdk_interform.h"
+#include "fpdfsdk/javascript/Field.h"
+#include "fpdfsdk/javascript/JS_Define.h"
+#include "fpdfsdk/javascript/JS_EventHandler.h"
+#include "fpdfsdk/javascript/JS_Object.h"
+#include "fpdfsdk/javascript/JS_Value.h"
+#include "fpdfsdk/javascript/cjs_context.h"
+#include "fpdfsdk/javascript/cjs_runtime.h"
+#include "fpdfsdk/javascript/color.h"
+#include "fpdfsdk/javascript/resource.h"
+#include "fpdfsdk/javascript/util.h"
+
+#define DOUBLE_CORRECT 0.000000000000001
+
+BEGIN_JS_STATIC_GLOBAL_FUN(CJS_PublicMethods)
+JS_STATIC_GLOBAL_FUN_ENTRY(AFNumber_Format)
+JS_STATIC_GLOBAL_FUN_ENTRY(AFNumber_Keystroke)
+JS_STATIC_GLOBAL_FUN_ENTRY(AFPercent_Format)
+JS_STATIC_GLOBAL_FUN_ENTRY(AFPercent_Keystroke)
+JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_FormatEx)
+JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_KeystrokeEx)
+JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_Format)
+JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_Keystroke)
+JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_FormatEx)
+JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_KeystrokeEx)
+JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_Format)
+JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_Keystroke)
+JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_Format)
+JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_Keystroke)
+JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_KeystrokeEx)
+JS_STATIC_GLOBAL_FUN_ENTRY(AFSimple)
+JS_STATIC_GLOBAL_FUN_ENTRY(AFMakeNumber)
+JS_STATIC_GLOBAL_FUN_ENTRY(AFSimple_Calculate)
+JS_STATIC_GLOBAL_FUN_ENTRY(AFRange_Validate)
+JS_STATIC_GLOBAL_FUN_ENTRY(AFMergeChange)
+JS_STATIC_GLOBAL_FUN_ENTRY(AFParseDateEx)
+JS_STATIC_GLOBAL_FUN_ENTRY(AFExtractNums)
+END_JS_STATIC_GLOBAL_FUN()
+
+IMPLEMENT_JS_STATIC_GLOBAL_FUN(CJS_PublicMethods)
+
+namespace {
+
+const FX_WCHAR* const months[] = {L"Jan", L"Feb", L"Mar", L"Apr",
+                                  L"May", L"Jun", L"Jul", L"Aug",
+                                  L"Sep", L"Oct", L"Nov", L"Dec"};
+
+const FX_WCHAR* const fullmonths[] = {L"January", L"February", L"March",
+                                      L"April",   L"May",      L"June",
+                                      L"July",    L"August",   L"September",
+                                      L"October", L"November", L"December"};
+
+CFX_ByteString StrTrim(const CFX_ByteString& pStr) {
+  CFX_ByteString result(pStr);
+  result.TrimLeft(' ');
+  result.TrimRight(' ');
+  return result;
+}
+
+CFX_WideString StrTrim(const CFX_WideString& pStr) {
+  CFX_WideString result(pStr);
+  result.TrimLeft(' ');
+  result.TrimRight(' ');
+  return result;
+}
+
+void AlertIfPossible(CJS_Context* pContext, const FX_WCHAR* swMsg) {
+  CPDFSDK_FormFillEnvironment* pFormFillEnv = pContext->GetFormFillEnv();
+  if (pFormFillEnv)
+    pFormFillEnv->JS_appAlert(swMsg, nullptr, 0, 3);
+}
+
+#if _FX_OS_ != _FX_ANDROID_
+CFX_ByteString CalculateString(double dValue,
+                               int iDec,
+                               int* iDec2,
+                               bool* bNegative) {
+  *bNegative = dValue < 0;
+  if (*bNegative)
+    dValue = -dValue;
+
+  // Make sure the number of precision characters will fit.
+  if (iDec > std::numeric_limits<double>::digits10)
+    iDec = std::numeric_limits<double>::digits10;
+
+  std::stringstream ss;
+  ss << std::fixed << std::setprecision(iDec) << dValue;
+  std::string stringValue = ss.str();
+  size_t iDecimalPos = stringValue.find(".");
+  *iDec2 = iDecimalPos == std::string::npos ? stringValue.size()
+                                            : static_cast<int>(iDecimalPos);
+  return CFX_ByteString(stringValue.c_str());
+}
+#endif
+
+}  // namespace
+
+bool CJS_PublicMethods::IsNumber(const CFX_WideString& str) {
+  CFX_WideString sTrim = StrTrim(str);
+  const FX_WCHAR* pTrim = sTrim.c_str();
+  const FX_WCHAR* p = pTrim;
+  bool bDot = false;
+  bool bKXJS = false;
+
+  wchar_t c;
+  while ((c = *p) != L'\0') {
+    if (c == L'.' || c == L',') {
+      if (bDot)
+        return false;
+      bDot = true;
+    } else if (c == L'-' || c == L'+') {
+      if (p != pTrim)
+        return false;
+    } else if (c == L'e' || c == L'E') {
+      if (bKXJS)
+        return false;
+
+      p++;
+      c = *p;
+      if (c == L'+' || c == L'-') {
+        bKXJS = true;
+      } else {
+        return false;
+      }
+    } else if (!FXSYS_iswdigit(c)) {
+      return false;
+    }
+    p++;
+  }
+
+  return true;
+}
+
+bool CJS_PublicMethods::maskSatisfied(wchar_t c_Change, wchar_t c_Mask) {
+  switch (c_Mask) {
+    case L'9':
+      return FXSYS_iswdigit(c_Change);
+    case L'A':
+      return FXSYS_iswalpha(c_Change);
+    case L'O':
+      return FXSYS_iswalnum(c_Change);
+    case L'X':
+      return true;
+    default:
+      return (c_Change == c_Mask);
+  }
+}
+
+bool CJS_PublicMethods::isReservedMaskChar(wchar_t ch) {
+  return ch == L'9' || ch == L'A' || ch == L'O' || ch == L'X';
+}
+
+double CJS_PublicMethods::AF_Simple(const FX_WCHAR* sFuction,
+                                    double dValue1,
+                                    double dValue2) {
+  if (FXSYS_wcsicmp(sFuction, L"AVG") == 0 ||
+      FXSYS_wcsicmp(sFuction, L"SUM") == 0) {
+    return dValue1 + dValue2;
+  }
+  if (FXSYS_wcsicmp(sFuction, L"PRD") == 0) {
+    return dValue1 * dValue2;
+  }
+  if (FXSYS_wcsicmp(sFuction, L"MIN") == 0) {
+    return std::min(dValue1, dValue2);
+  }
+  if (FXSYS_wcsicmp(sFuction, L"MAX") == 0) {
+    return std::max(dValue1, dValue2);
+  }
+  return dValue1;
+}
+
+CJS_Array CJS_PublicMethods::AF_MakeArrayFromList(CJS_Runtime* pRuntime,
+                                                  CJS_Value val) {
+  CJS_Array StrArray;
+  if (val.IsArrayObject()) {
+    val.ConvertToArray(pRuntime, StrArray);
+    return StrArray;
+  }
+  CFX_WideString wsStr = val.ToCFXWideString(pRuntime);
+  CFX_ByteString t = CFX_ByteString::FromUnicode(wsStr);
+  const char* p = t.c_str();
+
+  int ch = ',';
+  int nIndex = 0;
+
+  while (*p) {
+    const char* pTemp = strchr(p, ch);
+    if (!pTemp) {
+      StrArray.SetElement(
+          pRuntime, nIndex,
+          CJS_Value(pRuntime, StrTrim(CFX_ByteString(p)).c_str()));
+      break;
+    }
+
+    char* pSub = new char[pTemp - p + 1];
+    strncpy(pSub, p, pTemp - p);
+    *(pSub + (pTemp - p)) = '\0';
+
+    StrArray.SetElement(
+        pRuntime, nIndex,
+        CJS_Value(pRuntime, StrTrim(CFX_ByteString(pSub)).c_str()));
+    delete[] pSub;
+
+    nIndex++;
+    p = ++pTemp;
+  }
+  return StrArray;
+}
+
+int CJS_PublicMethods::ParseStringInteger(const CFX_WideString& str,
+                                          int nStart,
+                                          int& nSkip,
+                                          int nMaxStep) {
+  int nRet = 0;
+  nSkip = 0;
+  for (int i = nStart, sz = str.GetLength(); i < sz; i++) {
+    if (i - nStart > 10)
+      break;
+
+    FX_WCHAR c = str.GetAt(i);
+    if (!FXSYS_iswdigit(c))
+      break;
+
+    nRet = nRet * 10 + FXSYS_toDecimalDigit(c);
+    nSkip = i - nStart + 1;
+    if (nSkip >= nMaxStep)
+      break;
+  }
+
+  return nRet;
+}
+
+CFX_WideString CJS_PublicMethods::ParseStringString(const CFX_WideString& str,
+                                                    int nStart,
+                                                    int& nSkip) {
+  CFX_WideString swRet;
+  nSkip = 0;
+  for (int i = nStart, sz = str.GetLength(); i < sz; i++) {
+    FX_WCHAR c = str.GetAt(i);
+    if (!FXSYS_iswdigit(c))
+      break;
+
+    swRet += c;
+    nSkip = i - nStart + 1;
+  }
+
+  return swRet;
+}
+
+double CJS_PublicMethods::ParseNormalDate(const CFX_WideString& value,
+                                          bool* bWrongFormat) {
+  double dt = JS_GetDateTime();
+
+  int nYear = JS_GetYearFromTime(dt);
+  int nMonth = JS_GetMonthFromTime(dt) + 1;
+  int nDay = JS_GetDayFromTime(dt);
+  int nHour = JS_GetHourFromTime(dt);
+  int nMin = JS_GetMinFromTime(dt);
+  int nSec = JS_GetSecFromTime(dt);
+
+  int number[3];
+
+  int nSkip = 0;
+  int nLen = value.GetLength();
+  int nIndex = 0;
+  int i = 0;
+  while (i < nLen) {
+    if (nIndex > 2)
+      break;
+
+    FX_WCHAR c = value.GetAt(i);
+    if (FXSYS_iswdigit(c)) {
+      number[nIndex++] = ParseStringInteger(value, i, nSkip, 4);
+      i += nSkip;
+    } else {
+      i++;
+    }
+  }
+
+  if (nIndex == 2) {
+    // case2: month/day
+    // case3: day/month
+    if ((number[0] >= 1 && number[0] <= 12) &&
+        (number[1] >= 1 && number[1] <= 31)) {
+      nMonth = number[0];
+      nDay = number[1];
+    } else if ((number[0] >= 1 && number[0] <= 31) &&
+               (number[1] >= 1 && number[1] <= 12)) {
+      nDay = number[0];
+      nMonth = number[1];
+    }
+
+    if (bWrongFormat)
+      *bWrongFormat = false;
+  } else if (nIndex == 3) {
+    // case1: year/month/day
+    // case2: month/day/year
+    // case3: day/month/year
+
+    if (number[0] > 12 && (number[1] >= 1 && number[1] <= 12) &&
+        (number[2] >= 1 && number[2] <= 31)) {
+      nYear = number[0];
+      nMonth = number[1];
+      nDay = number[2];
+    } else if ((number[0] >= 1 && number[0] <= 12) &&
+               (number[1] >= 1 && number[1] <= 31) && number[2] > 31) {
+      nMonth = number[0];
+      nDay = number[1];
+      nYear = number[2];
+    } else if ((number[0] >= 1 && number[0] <= 31) &&
+               (number[1] >= 1 && number[1] <= 12) && number[2] > 31) {
+      nDay = number[0];
+      nMonth = number[1];
+      nYear = number[2];
+    }
+
+    if (bWrongFormat)
+      *bWrongFormat = false;
+  } else {
+    if (bWrongFormat)
+      *bWrongFormat = true;
+    return dt;
+  }
+
+  CFX_WideString swTemp;
+  swTemp.Format(L"%d/%d/%d %d:%d:%d", nMonth, nDay, nYear, nHour, nMin, nSec);
+  return JS_DateParse(swTemp);
+}
+
+double CJS_PublicMethods::MakeRegularDate(const CFX_WideString& value,
+                                          const CFX_WideString& format,
+                                          bool* bWrongFormat) {
+  double dt = JS_GetDateTime();
+
+  if (format.IsEmpty() || value.IsEmpty())
+    return dt;
+
+  int nYear = JS_GetYearFromTime(dt);
+  int nMonth = JS_GetMonthFromTime(dt) + 1;
+  int nDay = JS_GetDayFromTime(dt);
+  int nHour = JS_GetHourFromTime(dt);
+  int nMin = JS_GetMinFromTime(dt);
+  int nSec = JS_GetSecFromTime(dt);
+
+  int nYearSub = 99;  // nYear - 2000;
+
+  bool bPm = false;
+  bool bExit = false;
+  bool bBadFormat = false;
+
+  int i = 0;
+  int j = 0;
+
+  while (i < format.GetLength()) {
+    if (bExit)
+      break;
+
+    FX_WCHAR c = format.GetAt(i);
+    switch (c) {
+      case ':':
+      case '.':
+      case '-':
+      case '\\':
+      case '/':
+        i++;
+        j++;
+        break;
+
+      case 'y':
+      case 'm':
+      case 'd':
+      case 'H':
+      case 'h':
+      case 'M':
+      case 's':
+      case 't': {
+        int oldj = j;
+        int nSkip = 0;
+        int remaining = format.GetLength() - i - 1;
+
+        if (remaining == 0 || format.GetAt(i + 1) != c) {
+          switch (c) {
+            case 'y':
+              i++;
+              j++;
+              break;
+            case 'm':
+              nMonth = ParseStringInteger(value, j, nSkip, 2);
+              i++;
+              j += nSkip;
+              break;
+            case 'd':
+              nDay = ParseStringInteger(value, j, nSkip, 2);
+              i++;
+              j += nSkip;
+              break;
+            case 'H':
+              nHour = ParseStringInteger(value, j, nSkip, 2);
+              i++;
+              j += nSkip;
+              break;
+            case 'h':
+              nHour = ParseStringInteger(value, j, nSkip, 2);
+              i++;
+              j += nSkip;
+              break;
+            case 'M':
+              nMin = ParseStringInteger(value, j, nSkip, 2);
+              i++;
+              j += nSkip;
+              break;
+            case 's':
+              nSec = ParseStringInteger(value, j, nSkip, 2);
+              i++;
+              j += nSkip;
+              break;
+            case 't':
+              bPm = (j < value.GetLength() && value.GetAt(j) == 'p');
+              i++;
+              j++;
+              break;
+          }
+        } else if (remaining == 1 || format.GetAt(i + 2) != c) {
+          switch (c) {
+            case 'y':
+              nYear = ParseStringInteger(value, j, nSkip, 4);
+              i += 2;
+              j += nSkip;
+              break;
+            case 'm':
+              nMonth = ParseStringInteger(value, j, nSkip, 2);
+              i += 2;
+              j += nSkip;
+              break;
+            case 'd':
+              nDay = ParseStringInteger(value, j, nSkip, 2);
+              i += 2;
+              j += nSkip;
+              break;
+            case 'H':
+              nHour = ParseStringInteger(value, j, nSkip, 2);
+              i += 2;
+              j += nSkip;
+              break;
+            case 'h':
+              nHour = ParseStringInteger(value, j, nSkip, 2);
+              i += 2;
+              j += nSkip;
+              break;
+            case 'M':
+              nMin = ParseStringInteger(value, j, nSkip, 2);
+              i += 2;
+              j += nSkip;
+              break;
+            case 's':
+              nSec = ParseStringInteger(value, j, nSkip, 2);
+              i += 2;
+              j += nSkip;
+              break;
+            case 't':
+              bPm = (j + 1 < value.GetLength() && value.GetAt(j) == 'p' &&
+                     value.GetAt(j + 1) == 'm');
+              i += 2;
+              j += 2;
+              break;
+          }
+        } else if (remaining == 2 || format.GetAt(i + 3) != c) {
+          switch (c) {
+            case 'm': {
+              CFX_WideString sMonth = ParseStringString(value, j, nSkip);
+              bool bFind = false;
+              for (int m = 0; m < 12; m++) {
+                if (sMonth.CompareNoCase(months[m]) == 0) {
+                  nMonth = m + 1;
+                  i += 3;
+                  j += nSkip;
+                  bFind = true;
+                  break;
+                }
+              }
+
+              if (!bFind) {
+                nMonth = ParseStringInteger(value, j, nSkip, 3);
+                i += 3;
+                j += nSkip;
+              }
+            } break;
+            case 'y':
+              break;
+            default:
+              i += 3;
+              j += 3;
+              break;
+          }
+        } else if (remaining == 3 || format.GetAt(i + 4) != c) {
+          switch (c) {
+            case 'y':
+              nYear = ParseStringInteger(value, j, nSkip, 4);
+              j += nSkip;
+              i += 4;
+              break;
+            case 'm': {
+              bool bFind = false;
+
+              CFX_WideString sMonth = ParseStringString(value, j, nSkip);
+              sMonth.MakeLower();
+
+              for (int m = 0; m < 12; m++) {
+                CFX_WideString sFullMonths = fullmonths[m];
+                sFullMonths.MakeLower();
+
+                if (sFullMonths.Find(sMonth.c_str(), 0) != -1) {
+                  nMonth = m + 1;
+                  i += 4;
+                  j += nSkip;
+                  bFind = true;
+                  break;
+                }
+              }
+
+              if (!bFind) {
+                nMonth = ParseStringInteger(value, j, nSkip, 4);
+                i += 4;
+                j += nSkip;
+              }
+            } break;
+            default:
+              i += 4;
+              j += 4;
+              break;
+          }
+        } else {
+          if (j >= value.GetLength() || format.GetAt(i) != value.GetAt(j)) {
+            bBadFormat = true;
+            bExit = true;
+          }
+          i++;
+          j++;
+        }
+
+        if (oldj == j) {
+          bBadFormat = true;
+          bExit = true;
+        }
+      }
+
+      break;
+      default:
+        if (value.GetLength() <= j) {
+          bExit = true;
+        } else if (format.GetAt(i) != value.GetAt(j)) {
+          bBadFormat = true;
+          bExit = true;
+        }
+
+        i++;
+        j++;
+        break;
+    }
+  }
+
+  if (bPm)
+    nHour += 12;
+
+  if (nYear >= 0 && nYear <= nYearSub)
+    nYear += 2000;
+
+  if (nMonth < 1 || nMonth > 12)
+    bBadFormat = true;
+
+  if (nDay < 1 || nDay > 31)
+    bBadFormat = true;
+
+  if (nHour < 0 || nHour > 24)
+    bBadFormat = true;
+
+  if (nMin < 0 || nMin > 60)
+    bBadFormat = true;
+
+  if (nSec < 0 || nSec > 60)
+    bBadFormat = true;
+
+  double dRet = 0;
+  if (bBadFormat) {
+    dRet = ParseNormalDate(value, &bBadFormat);
+  } else {
+    dRet = JS_MakeDate(JS_MakeDay(nYear, nMonth - 1, nDay),
+                       JS_MakeTime(nHour, nMin, nSec, 0));
+    if (JS_PortIsNan(dRet))
+      dRet = JS_DateParse(value);
+  }
+
+  if (JS_PortIsNan(dRet))
+    dRet = ParseNormalDate(value, &bBadFormat);
+
+  if (bWrongFormat)
+    *bWrongFormat = bBadFormat;
+
+  return dRet;
+}
+
+CFX_WideString CJS_PublicMethods::MakeFormatDate(double dDate,
+                                                 const CFX_WideString& format) {
+  CFX_WideString sRet = L"", sPart = L"";
+
+  int nYear = JS_GetYearFromTime(dDate);
+  int nMonth = JS_GetMonthFromTime(dDate) + 1;
+  int nDay = JS_GetDayFromTime(dDate);
+  int nHour = JS_GetHourFromTime(dDate);
+  int nMin = JS_GetMinFromTime(dDate);
+  int nSec = JS_GetSecFromTime(dDate);
+
+  int i = 0;
+  while (i < format.GetLength()) {
+    FX_WCHAR c = format.GetAt(i);
+    int remaining = format.GetLength() - i - 1;
+    sPart = L"";
+    switch (c) {
+      case 'y':
+      case 'm':
+      case 'd':
+      case 'H':
+      case 'h':
+      case 'M':
+      case 's':
+      case 't':
+        if (remaining == 0 || format.GetAt(i + 1) != c) {
+          switch (c) {
+            case 'y':
+              sPart += c;
+              break;
+            case 'm':
+              sPart.Format(L"%d", nMonth);
+              break;
+            case 'd':
+              sPart.Format(L"%d", nDay);
+              break;
+            case 'H':
+              sPart.Format(L"%d", nHour);
+              break;
+            case 'h':
+              sPart.Format(L"%d", nHour > 12 ? nHour - 12 : nHour);
+              break;
+            case 'M':
+              sPart.Format(L"%d", nMin);
+              break;
+            case 's':
+              sPart.Format(L"%d", nSec);
+              break;
+            case 't':
+              sPart += nHour > 12 ? 'p' : 'a';
+              break;
+          }
+          i++;
+        } else if (remaining == 1 || format.GetAt(i + 2) != c) {
+          switch (c) {
+            case 'y':
+              sPart.Format(L"%02d", nYear - (nYear / 100) * 100);
+              break;
+            case 'm':
+              sPart.Format(L"%02d", nMonth);
+              break;
+            case 'd':
+              sPart.Format(L"%02d", nDay);
+              break;
+            case 'H':
+              sPart.Format(L"%02d", nHour);
+              break;
+            case 'h':
+              sPart.Format(L"%02d", nHour > 12 ? nHour - 12 : nHour);
+              break;
+            case 'M':
+              sPart.Format(L"%02d", nMin);
+              break;
+            case 's':
+              sPart.Format(L"%02d", nSec);
+              break;
+            case 't':
+              sPart = nHour > 12 ? L"pm" : L"am";
+              break;
+          }
+          i += 2;
+        } else if (remaining == 2 || format.GetAt(i + 3) != c) {
+          switch (c) {
+            case 'm':
+              i += 3;
+              if (nMonth > 0 && nMonth <= 12)
+                sPart += months[nMonth - 1];
+              break;
+            default:
+              i += 3;
+              sPart += c;
+              sPart += c;
+              sPart += c;
+              break;
+          }
+        } else if (remaining == 3 || format.GetAt(i + 4) != c) {
+          switch (c) {
+            case 'y':
+              sPart.Format(L"%04d", nYear);
+              i += 4;
+              break;
+            case 'm':
+              i += 4;
+              if (nMonth > 0 && nMonth <= 12)
+                sPart += fullmonths[nMonth - 1];
+              break;
+            default:
+              i += 4;
+              sPart += c;
+              sPart += c;
+              sPart += c;
+              sPart += c;
+              break;
+          }
+        } else {
+          i++;
+          sPart += c;
+        }
+        break;
+      default:
+        i++;
+        sPart += c;
+        break;
+    }
+
+    sRet += sPart;
+  }
+
+  return sRet;
+}
+
+// function AFNumber_Format(nDec, sepStyle, negStyle, currStyle, strCurrency,
+// bCurrencyPrepend)
+bool CJS_PublicMethods::AFNumber_Format(IJS_Context* cc,
+                                        const std::vector<CJS_Value>& params,
+                                        CJS_Value& vRet,
+                                        CFX_WideString& sError) {
+#if _FX_OS_ != _FX_ANDROID_
+  if (params.size() != 6) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+  CJS_EventHandler* pEvent = pContext->GetEventHandler();
+  if (!pEvent->m_pValue)
+    return false;
+
+  CFX_WideString& Value = pEvent->Value();
+  CFX_ByteString strValue = StrTrim(CFX_ByteString::FromUnicode(Value));
+  if (strValue.IsEmpty())
+    return true;
+
+  int iDec = params[0].ToInt(pRuntime);
+  int iSepStyle = params[1].ToInt(pRuntime);
+  int iNegStyle = params[2].ToInt(pRuntime);
+  // params[3] is iCurrStyle, it's not used.
+  CFX_WideString wstrCurrency = params[4].ToCFXWideString(pRuntime);
+  bool bCurrencyPrepend = params[5].ToBool(pRuntime);
+
+  if (iDec < 0)
+    iDec = -iDec;
+
+  if (iSepStyle < 0 || iSepStyle > 3)
+    iSepStyle = 0;
+
+  if (iNegStyle < 0 || iNegStyle > 3)
+    iNegStyle = 0;
+
+  // Processing decimal places
+  strValue.Replace(",", ".");
+  double dValue = atof(strValue.c_str());
+  if (iDec > 0)
+    dValue += DOUBLE_CORRECT;
+
+  // Calculating number string
+  bool bNegative;
+  int iDec2;
+  strValue = CalculateString(dValue, iDec, &iDec2, &bNegative);
+  if (strValue.IsEmpty()) {
+    dValue = 0;
+    strValue = CalculateString(dValue, iDec, &iDec2, &bNegative);
+    if (strValue.IsEmpty()) {
+      strValue = "0";
+      iDec2 = 1;
+    }
+  }
+
+  // Processing separator style
+  if (iDec2 < strValue.GetLength()) {
+    if (iSepStyle == 2 || iSepStyle == 3)
+      strValue.Replace(".", ",");
+
+    if (iDec2 == 0)
+      strValue.Insert(iDec2, '0');
+  }
+  if (iSepStyle == 0 || iSepStyle == 2) {
+    char cSeparator;
+    if (iSepStyle == 0)
+      cSeparator = ',';
+    else
+      cSeparator = '.';
+
+    for (int iDecPositive = iDec2 - 3; iDecPositive > 0; iDecPositive -= 3)
+      strValue.Insert(iDecPositive, cSeparator);
+  }
+
+  // Processing currency string
+  Value = CFX_WideString::FromLocal(strValue.AsStringC());
+
+  if (bCurrencyPrepend)
+    Value = wstrCurrency + Value;
+  else
+    Value = Value + wstrCurrency;
+
+  // Processing negative style
+  if (bNegative) {
+    if (iNegStyle == 0)
+      Value = L"-" + Value;
+    else if (iNegStyle == 2 || iNegStyle == 3)
+      Value = L"(" + Value + L")";
+    if (iNegStyle == 1 || iNegStyle == 3) {
+      if (Field* fTarget = pEvent->Target_Field()) {
+        CJS_Array arColor;
+        CJS_Value vColElm(pRuntime);
+        vColElm = CJS_Value(pRuntime, L"RGB");
+        arColor.SetElement(pRuntime, 0, vColElm);
+        vColElm = CJS_Value(pRuntime, 1);
+        arColor.SetElement(pRuntime, 1, vColElm);
+        vColElm = CJS_Value(pRuntime, 0);
+        arColor.SetElement(pRuntime, 2, vColElm);
+        arColor.SetElement(pRuntime, 3, vColElm);
+
+        CJS_PropValue vProp(pRuntime);
+        vProp.StartGetting();
+        vProp << arColor;
+        vProp.StartSetting();
+        fTarget->textColor(cc, vProp, sError);  // red
+      }
+    }
+  } else {
+    if (iNegStyle == 1 || iNegStyle == 3) {
+      if (Field* fTarget = pEvent->Target_Field()) {
+        CJS_Array arColor;
+        CJS_Value vColElm(pRuntime);
+        vColElm = CJS_Value(pRuntime, L"RGB");
+        arColor.SetElement(pRuntime, 0, vColElm);
+        vColElm = CJS_Value(pRuntime, 0);
+        arColor.SetElement(pRuntime, 1, vColElm);
+        arColor.SetElement(pRuntime, 2, vColElm);
+        arColor.SetElement(pRuntime, 3, vColElm);
+
+        CJS_PropValue vProp(pRuntime);
+        vProp.StartGetting();
+        fTarget->textColor(cc, vProp, sError);
+
+        CJS_Array aProp;
+        vProp.GetJSValue()->ConvertToArray(pRuntime, aProp);
+
+        CPWL_Color crProp;
+        CPWL_Color crColor;
+        color::ConvertArrayToPWLColor(pRuntime, aProp, &crProp);
+        color::ConvertArrayToPWLColor(pRuntime, arColor, &crColor);
+
+        if (crColor != crProp) {
+          CJS_PropValue vProp2(pRuntime);
+          vProp2.StartGetting();
+          vProp2 << arColor;
+          vProp2.StartSetting();
+          fTarget->textColor(cc, vProp2, sError);
+        }
+      }
+    }
+  }
+#endif
+  return true;
+}
+
+// function AFNumber_Keystroke(nDec, sepStyle, negStyle, currStyle, strCurrency,
+// bCurrencyPrepend)
+bool CJS_PublicMethods::AFNumber_Keystroke(IJS_Context* cc,
+                                           const std::vector<CJS_Value>& params,
+                                           CJS_Value& vRet,
+                                           CFX_WideString& sError) {
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+  CJS_EventHandler* pEvent = pContext->GetEventHandler();
+
+  if (params.size() < 2)
+    return false;
+
+  if (!pEvent->m_pValue)
+    return false;
+
+  CFX_WideString& val = pEvent->Value();
+  CFX_WideString& wstrChange = pEvent->Change();
+  CFX_WideString wstrValue = val;
+
+  if (pEvent->WillCommit()) {
+    CFX_WideString swTemp = StrTrim(wstrValue);
+    if (swTemp.IsEmpty())
+      return true;
+
+    swTemp.Replace(L",", L".");
+    if (!IsNumber(swTemp.c_str())) {
+      pEvent->Rc() = false;
+      sError = JSGetStringFromID(IDS_STRING_JSAFNUMBER_KEYSTROKE);
+      AlertIfPossible(pContext, sError.c_str());
+    }
+    return true;  // it happens after the last keystroke and before validating,
+  }
+
+  CFX_WideString wstrSelected;
+  if (pEvent->SelStart() != -1) {
+    wstrSelected = wstrValue.Mid(pEvent->SelStart(),
+                                 pEvent->SelEnd() - pEvent->SelStart());
+  }
+
+  bool bHasSign = wstrValue.Find(L'-') != -1 && wstrSelected.Find(L'-') == -1;
+  if (bHasSign) {
+    // can't insert "change" in front to sign postion.
+    if (pEvent->SelStart() == 0) {
+      bool& bRc = pEvent->Rc();
+      bRc = false;
+      return true;
+    }
+  }
+
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  int iSepStyle = params[1].ToInt(pRuntime);
+  if (iSepStyle < 0 || iSepStyle > 3)
+    iSepStyle = 0;
+  const FX_WCHAR cSep = iSepStyle < 2 ? L'.' : L',';
+
+  bool bHasSep = wstrValue.Find(cSep) != -1;
+  for (FX_STRSIZE i = 0; i < wstrChange.GetLength(); ++i) {
+    if (wstrChange[i] == cSep) {
+      if (bHasSep) {
+        bool& bRc = pEvent->Rc();
+        bRc = false;
+        return true;
+      }
+      bHasSep = true;
+      continue;
+    }
+    if (wstrChange[i] == L'-') {
+      if (bHasSign) {
+        bool& bRc = pEvent->Rc();
+        bRc = false;
+        return true;
+      }
+      // sign's position is not correct
+      if (i != 0) {
+        bool& bRc = pEvent->Rc();
+        bRc = false;
+        return true;
+      }
+      if (pEvent->SelStart() != 0) {
+        bool& bRc = pEvent->Rc();
+        bRc = false;
+        return true;
+      }
+      bHasSign = true;
+      continue;
+    }
+
+    if (!FXSYS_iswdigit(wstrChange[i])) {
+      bool& bRc = pEvent->Rc();
+      bRc = false;
+      return true;
+    }
+  }
+
+  CFX_WideString wprefix = wstrValue.Mid(0, pEvent->SelStart());
+  CFX_WideString wpostfix;
+  if (pEvent->SelEnd() < wstrValue.GetLength())
+    wpostfix = wstrValue.Mid(pEvent->SelEnd());
+  val = wprefix + wstrChange + wpostfix;
+  return true;
+}
+
+// function AFPercent_Format(nDec, sepStyle)
+bool CJS_PublicMethods::AFPercent_Format(IJS_Context* cc,
+                                         const std::vector<CJS_Value>& params,
+                                         CJS_Value& vRet,
+                                         CFX_WideString& sError) {
+#if _FX_OS_ != _FX_ANDROID_
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  CJS_EventHandler* pEvent = pContext->GetEventHandler();
+
+  if (params.size() != 2) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+  if (!pEvent->m_pValue)
+    return false;
+
+  CFX_WideString& Value = pEvent->Value();
+  CFX_ByteString strValue = StrTrim(CFX_ByteString::FromUnicode(Value));
+  if (strValue.IsEmpty())
+    return true;
+
+  int iDec = params[0].ToInt(pRuntime);
+  if (iDec < 0)
+    iDec = -iDec;
+
+  int iSepStyle = params[1].ToInt(pRuntime);
+  if (iSepStyle < 0 || iSepStyle > 3)
+    iSepStyle = 0;
+
+  // for processing decimal places
+  double dValue = atof(strValue.c_str());
+  dValue *= 100;
+  if (iDec > 0)
+    dValue += DOUBLE_CORRECT;
+
+  int iDec2;
+  int iNegative = 0;
+  strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
+  if (strValue.IsEmpty()) {
+    dValue = 0;
+    strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
+  }
+
+  if (iDec2 < 0) {
+    for (int iNum = 0; iNum < abs(iDec2); iNum++) {
+      strValue = "0" + strValue;
+    }
+    iDec2 = 0;
+  }
+  int iMax = strValue.GetLength();
+  if (iDec2 > iMax) {
+    for (int iNum = 0; iNum <= iDec2 - iMax; iNum++) {
+      strValue += "0";
+    }
+    iMax = iDec2 + 1;
+  }
+
+  // for processing seperator style
+  if (iDec2 < iMax) {
+    if (iSepStyle == 0 || iSepStyle == 1) {
+      strValue.Insert(iDec2, '.');
+      iMax++;
+    } else if (iSepStyle == 2 || iSepStyle == 3) {
+      strValue.Insert(iDec2, ',');
+      iMax++;
+    }
+
+    if (iDec2 == 0)
+      strValue.Insert(iDec2, '0');
+  }
+  if (iSepStyle == 0 || iSepStyle == 2) {
+    char cSeperator;
+    if (iSepStyle == 0)
+      cSeperator = ',';
+    else
+      cSeperator = '.';
+
+    for (int iDecPositive = iDec2 - 3; iDecPositive > 0; iDecPositive -= 3) {
+      strValue.Insert(iDecPositive, cSeperator);
+      iMax++;
+    }
+  }
+
+  // negative mark
+  if (iNegative)
+    strValue = "-" + strValue;
+  strValue += "%";
+  Value = CFX_WideString::FromLocal(strValue.AsStringC());
+#endif
+  return true;
+}
+// AFPercent_Keystroke(nDec, sepStyle)
+bool CJS_PublicMethods::AFPercent_Keystroke(
+    IJS_Context* cc,
+    const std::vector<CJS_Value>& params,
+    CJS_Value& vRet,
+    CFX_WideString& sError) {
+  return AFNumber_Keystroke(cc, params, vRet, sError);
+}
+
+// function AFDate_FormatEx(cFormat)
+bool CJS_PublicMethods::AFDate_FormatEx(IJS_Context* cc,
+                                        const std::vector<CJS_Value>& params,
+                                        CJS_Value& vRet,
+                                        CFX_WideString& sError) {
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  CJS_EventHandler* pEvent = pContext->GetEventHandler();
+
+  if (params.size() != 1) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+  if (!pEvent->m_pValue)
+    return false;
+
+  CFX_WideString& val = pEvent->Value();
+  CFX_WideString strValue = val;
+  if (strValue.IsEmpty())
+    return true;
+
+  CFX_WideString sFormat = params[0].ToCFXWideString(pRuntime);
+  double dDate = 0.0f;
+
+  if (strValue.Find(L"GMT") != -1) {
+    // for GMT format time
+    // such as "Tue Aug 11 14:24:16 GMT+08002009"
+    dDate = MakeInterDate(strValue);
+  } else {
+    dDate = MakeRegularDate(strValue, sFormat, nullptr);
+  }
+
+  if (JS_PortIsNan(dDate)) {
+    CFX_WideString swMsg;
+    swMsg.Format(JSGetStringFromID(IDS_STRING_JSPARSEDATE).c_str(),
+                 sFormat.c_str());
+    AlertIfPossible(pContext, swMsg.c_str());
+    return false;
+  }
+
+  val = MakeFormatDate(dDate, sFormat);
+  return true;
+}
+
+double CJS_PublicMethods::MakeInterDate(const CFX_WideString& strValue) {
+  std::vector<CFX_WideString> wsArray;
+  CFX_WideString sTemp = L"";
+  for (int i = 0; i < strValue.GetLength(); ++i) {
+    FX_WCHAR c = strValue.GetAt(i);
+    if (c == L' ' || c == L':') {
+      wsArray.push_back(sTemp);
+      sTemp = L"";
+      continue;
+    }
+    sTemp += c;
+  }
+  wsArray.push_back(sTemp);
+  if (wsArray.size() != 8)
+    return 0;
+
+  int nMonth = 1;
+  sTemp = wsArray[1];
+  if (sTemp.Compare(L"Jan") == 0)
+    nMonth = 1;
+  else if (sTemp.Compare(L"Feb") == 0)
+    nMonth = 2;
+  else if (sTemp.Compare(L"Mar") == 0)
+    nMonth = 3;
+  else if (sTemp.Compare(L"Apr") == 0)
+    nMonth = 4;
+  else if (sTemp.Compare(L"May") == 0)
+    nMonth = 5;
+  else if (sTemp.Compare(L"Jun") == 0)
+    nMonth = 6;
+  else if (sTemp.Compare(L"Jul") == 0)
+    nMonth = 7;
+  else if (sTemp.Compare(L"Aug") == 0)
+    nMonth = 8;
+  else if (sTemp.Compare(L"Sep") == 0)
+    nMonth = 9;
+  else if (sTemp.Compare(L"Oct") == 0)
+    nMonth = 10;
+  else if (sTemp.Compare(L"Nov") == 0)
+    nMonth = 11;
+  else if (sTemp.Compare(L"Dec") == 0)
+    nMonth = 12;
+
+  int nDay = FX_atof(wsArray[2].AsStringC());
+  int nHour = FX_atof(wsArray[3].AsStringC());
+  int nMin = FX_atof(wsArray[4].AsStringC());
+  int nSec = FX_atof(wsArray[5].AsStringC());
+  int nYear = FX_atof(wsArray[7].AsStringC());
+  double dRet = JS_MakeDate(JS_MakeDay(nYear, nMonth - 1, nDay),
+                            JS_MakeTime(nHour, nMin, nSec, 0));
+  if (JS_PortIsNan(dRet))
+    dRet = JS_DateParse(strValue);
+
+  return dRet;
+}
+
+// AFDate_KeystrokeEx(cFormat)
+bool CJS_PublicMethods::AFDate_KeystrokeEx(IJS_Context* cc,
+                                           const std::vector<CJS_Value>& params,
+                                           CJS_Value& vRet,
+                                           CFX_WideString& sError) {
+  CJS_Context* pContext = (CJS_Context*)cc;
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  CJS_EventHandler* pEvent = pContext->GetEventHandler();
+
+  if (params.size() != 1) {
+    sError = L"AFDate_KeystrokeEx's parameters' size r not correct";
+    return false;
+  }
+
+  if (pEvent->WillCommit()) {
+    if (!pEvent->m_pValue)
+      return false;
+    CFX_WideString strValue = pEvent->Value();
+    if (strValue.IsEmpty())
+      return true;
+
+    CFX_WideString sFormat = params[0].ToCFXWideString(pRuntime);
+    bool bWrongFormat = false;
+    double dRet = MakeRegularDate(strValue, sFormat, &bWrongFormat);
+    if (bWrongFormat || JS_PortIsNan(dRet)) {
+      CFX_WideString swMsg;
+      swMsg.Format(JSGetStringFromID(IDS_STRING_JSPARSEDATE).c_str(),
+                   sFormat.c_str());
+      AlertIfPossible(pContext, swMsg.c_str());
+      pEvent->Rc() = false;
+      return true;
+    }
+  }
+  return true;
+}
+
+bool CJS_PublicMethods::AFDate_Format(IJS_Context* cc,
+                                      const std::vector<CJS_Value>& params,
+                                      CJS_Value& vRet,
+                                      CFX_WideString& sError) {
+  if (params.size() != 1) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  int iIndex = params[0].ToInt(pRuntime);
+  const FX_WCHAR* cFormats[] = {L"m/d",
+                                L"m/d/yy",
+                                L"mm/dd/yy",
+                                L"mm/yy",
+                                L"d-mmm",
+                                L"d-mmm-yy",
+                                L"dd-mmm-yy",
+                                L"yy-mm-dd",
+                                L"mmm-yy",
+                                L"mmmm-yy",
+                                L"mmm d, yyyy",
+                                L"mmmm d, yyyy",
+                                L"m/d/yy h:MM tt",
+                                L"m/d/yy HH:MM"};
+
+  if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
+    iIndex = 0;
+
+  std::vector<CJS_Value> newParams;
+  newParams.push_back(
+      CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
+  return AFDate_FormatEx(cc, newParams, vRet, sError);
+}
+
+// AFDate_KeystrokeEx(cFormat)
+bool CJS_PublicMethods::AFDate_Keystroke(IJS_Context* cc,
+                                         const std::vector<CJS_Value>& params,
+                                         CJS_Value& vRet,
+                                         CFX_WideString& sError) {
+  if (params.size() != 1) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  int iIndex = params[0].ToInt(pRuntime);
+  const FX_WCHAR* cFormats[] = {L"m/d",
+                                L"m/d/yy",
+                                L"mm/dd/yy",
+                                L"mm/yy",
+                                L"d-mmm",
+                                L"d-mmm-yy",
+                                L"dd-mmm-yy",
+                                L"yy-mm-dd",
+                                L"mmm-yy",
+                                L"mmmm-yy",
+                                L"mmm d, yyyy",
+                                L"mmmm d, yyyy",
+                                L"m/d/yy h:MM tt",
+                                L"m/d/yy HH:MM"};
+
+  if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
+    iIndex = 0;
+
+  std::vector<CJS_Value> newParams;
+  newParams.push_back(
+      CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
+  return AFDate_KeystrokeEx(cc, newParams, vRet, sError);
+}
+
+// function AFTime_Format(ptf)
+bool CJS_PublicMethods::AFTime_Format(IJS_Context* cc,
+                                      const std::vector<CJS_Value>& params,
+                                      CJS_Value& vRet,
+                                      CFX_WideString& sError) {
+  if (params.size() != 1) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  int iIndex = params[0].ToInt(pRuntime);
+  const FX_WCHAR* cFormats[] = {L"HH:MM", L"h:MM tt", L"HH:MM:ss",
+                                L"h:MM:ss tt"};
+
+  if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
+    iIndex = 0;
+
+  std::vector<CJS_Value> newParams;
+  newParams.push_back(
+      CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
+  return AFDate_FormatEx(cc, newParams, vRet, sError);
+}
+
+bool CJS_PublicMethods::AFTime_Keystroke(IJS_Context* cc,
+                                         const std::vector<CJS_Value>& params,
+                                         CJS_Value& vRet,
+                                         CFX_WideString& sError) {
+  if (params.size() != 1) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  int iIndex = params[0].ToInt(pRuntime);
+  const FX_WCHAR* cFormats[] = {L"HH:MM", L"h:MM tt", L"HH:MM:ss",
+                                L"h:MM:ss tt"};
+
+  if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
+    iIndex = 0;
+
+  std::vector<CJS_Value> newParams;
+  newParams.push_back(
+      CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
+  return AFDate_KeystrokeEx(cc, newParams, vRet, sError);
+}
+
+bool CJS_PublicMethods::AFTime_FormatEx(IJS_Context* cc,
+                                        const std::vector<CJS_Value>& params,
+                                        CJS_Value& vRet,
+                                        CFX_WideString& sError) {
+  return AFDate_FormatEx(cc, params, vRet, sError);
+}
+
+bool CJS_PublicMethods::AFTime_KeystrokeEx(IJS_Context* cc,
+                                           const std::vector<CJS_Value>& params,
+                                           CJS_Value& vRet,
+                                           CFX_WideString& sError) {
+  return AFDate_KeystrokeEx(cc, params, vRet, sError);
+}
+
+// function AFSpecial_Format(psf)
+bool CJS_PublicMethods::AFSpecial_Format(IJS_Context* cc,
+                                         const std::vector<CJS_Value>& params,
+                                         CJS_Value& vRet,
+                                         CFX_WideString& sError) {
+  if (params.size() != 1) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+  CJS_EventHandler* pEvent = pContext->GetEventHandler();
+  if (!pEvent->m_pValue)
+    return false;
+
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  CFX_WideString wsSource = pEvent->Value();
+  CFX_WideString wsFormat;
+  switch (params[0].ToInt(pRuntime)) {
+    case 0:
+      wsFormat = L"99999";
+      break;
+    case 1:
+      wsFormat = L"99999-9999";
+      break;
+    case 2:
+      if (util::printx(L"9999999999", wsSource).GetLength() >= 10)
+        wsFormat = L"(999) 999-9999";
+      else
+        wsFormat = L"999-9999";
+      break;
+    case 3:
+      wsFormat = L"999-99-9999";
+      break;
+  }
+
+  pEvent->Value() = util::printx(wsFormat, wsSource);
+  return true;
+}
+
+// function AFSpecial_KeystrokeEx(mask)
+bool CJS_PublicMethods::AFSpecial_KeystrokeEx(
+    IJS_Context* cc,
+    const std::vector<CJS_Value>& params,
+    CJS_Value& vRet,
+    CFX_WideString& sError) {
+  CJS_Context* pContext = (CJS_Context*)cc;
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  CJS_EventHandler* pEvent = pContext->GetEventHandler();
+
+  if (params.size() < 1) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+
+  if (!pEvent->m_pValue)
+    return false;
+
+  CFX_WideString& valEvent = pEvent->Value();
+  CFX_WideString wstrMask = params[0].ToCFXWideString(pRuntime);
+  if (wstrMask.IsEmpty())
+    return true;
+
+  if (pEvent->WillCommit()) {
+    if (valEvent.IsEmpty())
+      return true;
+
+    FX_STRSIZE iIndexMask = 0;
+    for (; iIndexMask < valEvent.GetLength(); ++iIndexMask) {
+      if (!maskSatisfied(valEvent[iIndexMask], wstrMask[iIndexMask]))
+        break;
+    }
+
+    if (iIndexMask != wstrMask.GetLength() ||
+        (iIndexMask != valEvent.GetLength() && wstrMask.GetLength() != 0)) {
+      AlertIfPossible(
+          pContext, JSGetStringFromID(IDS_STRING_JSAFNUMBER_KEYSTROKE).c_str());
+      pEvent->Rc() = false;
+    }
+    return true;
+  }
+
+  CFX_WideString& wideChange = pEvent->Change();
+  if (wideChange.IsEmpty())
+    return true;
+
+  CFX_WideString wChange = wideChange;
+  FX_STRSIZE iIndexMask = pEvent->SelStart();
+  FX_STRSIZE combined_len = valEvent.GetLength() + wChange.GetLength() +
+                            pEvent->SelStart() - pEvent->SelEnd();
+  if (combined_len > wstrMask.GetLength()) {
+    AlertIfPossible(pContext,
+                    JSGetStringFromID(IDS_STRING_JSPARAM_TOOLONG).c_str());
+    pEvent->Rc() = false;
+    return true;
+  }
+
+  if (iIndexMask >= wstrMask.GetLength() && !wChange.IsEmpty()) {
+    AlertIfPossible(pContext,
+                    JSGetStringFromID(IDS_STRING_JSPARAM_TOOLONG).c_str());
+    pEvent->Rc() = false;
+    return true;
+  }
+
+  for (FX_STRSIZE i = 0; i < wChange.GetLength(); ++i) {
+    if (iIndexMask >= wstrMask.GetLength()) {
+      AlertIfPossible(pContext,
+                      JSGetStringFromID(IDS_STRING_JSPARAM_TOOLONG).c_str());
+      pEvent->Rc() = false;
+      return true;
+    }
+    FX_WCHAR wMask = wstrMask[iIndexMask];
+    if (!isReservedMaskChar(wMask))
+      wChange.SetAt(i, wMask);
+
+    if (!maskSatisfied(wChange[i], wMask)) {
+      pEvent->Rc() = false;
+      return true;
+    }
+    iIndexMask++;
+  }
+  wideChange = wChange;
+  return true;
+}
+
+// function AFSpecial_Keystroke(psf)
+bool CJS_PublicMethods::AFSpecial_Keystroke(
+    IJS_Context* cc,
+    const std::vector<CJS_Value>& params,
+    CJS_Value& vRet,
+    CFX_WideString& sError) {
+  if (params.size() != 1) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+  CJS_EventHandler* pEvent = pContext->GetEventHandler();
+  if (!pEvent->m_pValue)
+    return false;
+
+  const char* cFormat = "";
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  switch (params[0].ToInt(pRuntime)) {
+    case 0:
+      cFormat = "99999";
+      break;
+    case 1:
+      cFormat = "999999999";
+      break;
+    case 2:
+      if (pEvent->Value().GetLength() + pEvent->Change().GetLength() > 7)
+        cFormat = "9999999999";
+      else
+        cFormat = "9999999";
+      break;
+    case 3:
+      cFormat = "999999999";
+      break;
+  }
+
+  std::vector<CJS_Value> params2;
+  params2.push_back(CJS_Value(CJS_Runtime::FromContext(cc), cFormat));
+  return AFSpecial_KeystrokeEx(cc, params2, vRet, sError);
+}
+
+bool CJS_PublicMethods::AFMergeChange(IJS_Context* cc,
+                                      const std::vector<CJS_Value>& params,
+                                      CJS_Value& vRet,
+                                      CFX_WideString& sError) {
+  if (params.size() != 1) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  CJS_EventHandler* pEventHandler = pContext->GetEventHandler();
+
+  CFX_WideString swValue;
+  if (pEventHandler->m_pValue)
+    swValue = pEventHandler->Value();
+
+  if (pEventHandler->WillCommit()) {
+    vRet = CJS_Value(pRuntime, swValue.c_str());
+    return true;
+  }
+
+  CFX_WideString prefix, postfix;
+
+  if (pEventHandler->SelStart() >= 0)
+    prefix = swValue.Mid(0, pEventHandler->SelStart());
+  else
+    prefix = L"";
+
+  if (pEventHandler->SelEnd() >= 0 &&
+      pEventHandler->SelEnd() <= swValue.GetLength())
+    postfix = swValue.Mid(pEventHandler->SelEnd(),
+                          swValue.GetLength() - pEventHandler->SelEnd());
+  else
+    postfix = L"";
+
+  vRet =
+      CJS_Value(pRuntime, (prefix + pEventHandler->Change() + postfix).c_str());
+  return true;
+}
+
+bool CJS_PublicMethods::AFParseDateEx(IJS_Context* cc,
+                                      const std::vector<CJS_Value>& params,
+                                      CJS_Value& vRet,
+                                      CFX_WideString& sError) {
+  if (params.size() != 2) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  CFX_WideString sValue = params[0].ToCFXWideString(pRuntime);
+  CFX_WideString sFormat = params[1].ToCFXWideString(pRuntime);
+
+  double dDate = MakeRegularDate(sValue, sFormat, nullptr);
+
+  if (JS_PortIsNan(dDate)) {
+    CFX_WideString swMsg;
+    swMsg.Format(JSGetStringFromID(IDS_STRING_JSPARSEDATE).c_str(),
+                 sFormat.c_str());
+    AlertIfPossible((CJS_Context*)cc, swMsg.c_str());
+    return false;
+  }
+
+  vRet = CJS_Value(pRuntime, dDate);
+  return true;
+}
+
+bool CJS_PublicMethods::AFSimple(IJS_Context* cc,
+                                 const std::vector<CJS_Value>& params,
+                                 CJS_Value& vRet,
+                                 CFX_WideString& sError) {
+  if (params.size() != 3) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  vRet = CJS_Value(pRuntime, static_cast<double>(AF_Simple(
+                                 params[0].ToCFXWideString(pRuntime).c_str(),
+                                 params[1].ToDouble(pRuntime),
+                                 params[2].ToDouble(pRuntime))));
+
+  return true;
+}
+
+bool CJS_PublicMethods::AFMakeNumber(IJS_Context* cc,
+                                     const std::vector<CJS_Value>& params,
+                                     CJS_Value& vRet,
+                                     CFX_WideString& sError) {
+  if (params.size() != 1) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  CFX_WideString ws = params[0].ToCFXWideString(pRuntime);
+  ws.Replace(L",", L".");
+  vRet = CJS_Value(pRuntime, ws.c_str());
+  vRet.MaybeCoerceToNumber(pRuntime);
+  if (vRet.GetType() != CJS_Value::VT_number)
+    vRet = CJS_Value(pRuntime, 0);
+  return true;
+}
+
+bool CJS_PublicMethods::AFSimple_Calculate(IJS_Context* cc,
+                                           const std::vector<CJS_Value>& params,
+                                           CJS_Value& vRet,
+                                           CFX_WideString& sError) {
+  if (params.size() != 2) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+
+  CJS_Value params1 = params[1];
+  if (!params1.IsArrayObject() && params1.GetType() != CJS_Value::VT_string) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  CPDFSDK_InterForm* pReaderInterForm =
+      pContext->GetFormFillEnv()->GetInterForm();
+  CPDF_InterForm* pInterForm = pReaderInterForm->GetInterForm();
+
+  CFX_WideString sFunction = params[0].ToCFXWideString(pRuntime);
+  double dValue = wcscmp(sFunction.c_str(), L"PRD") == 0 ? 1.0 : 0.0;
+
+  CJS_Array FieldNameArray = AF_MakeArrayFromList(pRuntime, params1);
+  int nFieldsCount = 0;
+
+  for (int i = 0, isz = FieldNameArray.GetLength(pRuntime); i < isz; i++) {
+    CJS_Value jsValue(pRuntime);
+    FieldNameArray.GetElement(pRuntime, i, jsValue);
+    CFX_WideString wsFieldName = jsValue.ToCFXWideString(pRuntime);
+
+    for (int j = 0, jsz = pInterForm->CountFields(wsFieldName); j < jsz; j++) {
+      if (CPDF_FormField* pFormField = pInterForm->GetField(j, wsFieldName)) {
+        double dTemp = 0.0;
+        switch (pFormField->GetFieldType()) {
+          case FIELDTYPE_TEXTFIELD:
+          case FIELDTYPE_COMBOBOX: {
+            CFX_WideString trimmed = pFormField->GetValue();
+            trimmed.TrimRight();
+            trimmed.TrimLeft();
+            dTemp = FX_atof(trimmed.AsStringC());
+          } break;
+          case FIELDTYPE_PUSHBUTTON: {
+            dTemp = 0.0;
+          } break;
+          case FIELDTYPE_CHECKBOX:
+          case FIELDTYPE_RADIOBUTTON: {
+            dTemp = 0.0;
+            for (int c = 0, csz = pFormField->CountControls(); c < csz; c++) {
+              if (CPDF_FormControl* pFormCtrl = pFormField->GetControl(c)) {
+                if (pFormCtrl->IsChecked()) {
+                  CFX_WideString trimmed = pFormCtrl->GetExportValue();
+                  trimmed.TrimRight();
+                  trimmed.TrimLeft();
+                  dTemp = FX_atof(trimmed.AsStringC());
+                  break;
+                }
+              }
+            }
+          } break;
+          case FIELDTYPE_LISTBOX: {
+            if (pFormField->CountSelectedItems() <= 1) {
+              CFX_WideString trimmed = pFormField->GetValue();
+              trimmed.TrimRight();
+              trimmed.TrimLeft();
+              dTemp = FX_atof(trimmed.AsStringC());
+            }
+          } break;
+          default:
+            break;
+        }
+
+        if (i == 0 && j == 0 && (wcscmp(sFunction.c_str(), L"MIN") == 0 ||
+                                 wcscmp(sFunction.c_str(), L"MAX") == 0))
+          dValue = dTemp;
+
+        dValue = AF_Simple(sFunction.c_str(), dValue, dTemp);
+
+        nFieldsCount++;
+      }
+    }
+  }
+
+  if (wcscmp(sFunction.c_str(), L"AVG") == 0 && nFieldsCount > 0)
+    dValue /= nFieldsCount;
+
+  dValue = (double)floor(dValue * FXSYS_pow((double)10, (double)6) + 0.49) /
+           FXSYS_pow((double)10, (double)6);
+  CJS_Value jsValue(pRuntime, dValue);
+  if (pContext->GetEventHandler()->m_pValue)
+    pContext->GetEventHandler()->Value() = jsValue.ToCFXWideString(pRuntime);
+
+  return true;
+}
+
+/* This function validates the current event to ensure that its value is
+** within the specified range. */
+
+bool CJS_PublicMethods::AFRange_Validate(IJS_Context* cc,
+                                         const std::vector<CJS_Value>& params,
+                                         CJS_Value& vRet,
+                                         CFX_WideString& sError) {
+  if (params.size() != 4) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  CJS_EventHandler* pEvent = pContext->GetEventHandler();
+  if (!pEvent->m_pValue)
+    return false;
+
+  if (pEvent->Value().IsEmpty())
+    return true;
+
+  double dEentValue =
+      atof(CFX_ByteString::FromUnicode(pEvent->Value()).c_str());
+  bool bGreaterThan = params[0].ToBool(pRuntime);
+  double dGreaterThan = params[1].ToDouble(pRuntime);
+  bool bLessThan = params[2].ToBool(pRuntime);
+  double dLessThan = params[3].ToDouble(pRuntime);
+  CFX_WideString swMsg;
+
+  if (bGreaterThan && bLessThan) {
+    if (dEentValue < dGreaterThan || dEentValue > dLessThan)
+      swMsg.Format(JSGetStringFromID(IDS_STRING_JSRANGE1).c_str(),
+                   params[1].ToCFXWideString(pRuntime).c_str(),
+                   params[3].ToCFXWideString(pRuntime).c_str());
+  } else if (bGreaterThan) {
+    if (dEentValue < dGreaterThan)
+      swMsg.Format(JSGetStringFromID(IDS_STRING_JSRANGE2).c_str(),
+                   params[1].ToCFXWideString(pRuntime).c_str());
+  } else if (bLessThan) {
+    if (dEentValue > dLessThan)
+      swMsg.Format(JSGetStringFromID(IDS_STRING_JSRANGE3).c_str(),
+                   params[3].ToCFXWideString(pRuntime).c_str());
+  }
+
+  if (!swMsg.IsEmpty()) {
+    AlertIfPossible(pContext, swMsg.c_str());
+    pEvent->Rc() = false;
+  }
+  return true;
+}
+
+bool CJS_PublicMethods::AFExtractNums(IJS_Context* cc,
+                                      const std::vector<CJS_Value>& params,
+                                      CJS_Value& vRet,
+                                      CFX_WideString& sError) {
+  if (params.size() != 1) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  CFX_WideString str = params[0].ToCFXWideString(pRuntime);
+  CFX_WideString sPart;
+  CJS_Array nums;
+
+  if (str.GetAt(0) == L'.' || str.GetAt(0) == L',')
+    str = L"0" + str;
+
+  int nIndex = 0;
+  for (int i = 0, sz = str.GetLength(); i < sz; i++) {
+    FX_WCHAR wc = str.GetAt(i);
+    if (FXSYS_iswdigit(wc)) {
+      sPart += wc;
+    } else {
+      if (sPart.GetLength() > 0) {
+        nums.SetElement(pRuntime, nIndex, CJS_Value(pRuntime, sPart.c_str()));
+        sPart = L"";
+        nIndex++;
+      }
+    }
+  }
+
+  if (sPart.GetLength() > 0) {
+    nums.SetElement(pRuntime, nIndex, CJS_Value(pRuntime, sPart.c_str()));
+  }
+
+  if (nums.GetLength(pRuntime) > 0)
+    vRet = CJS_Value(pRuntime, nums);
+  else
+    vRet.SetNull(pRuntime);
+
+  return true;
+}
diff --git a/fpdfsdk/javascript/PublicMethods.h b/fpdfsdk/javascript/PublicMethods.h
new file mode 100644
index 0000000..0820c40
--- /dev/null
+++ b/fpdfsdk/javascript/PublicMethods.h
@@ -0,0 +1,162 @@
+// 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_JAVASCRIPT_PUBLICMETHODS_H_
+#define FPDFSDK_JAVASCRIPT_PUBLICMETHODS_H_
+
+#include <string>
+#include <vector>
+
+#include "fpdfsdk/javascript/JS_Define.h"
+
+class CJS_PublicMethods : public CJS_Object {
+ public:
+  explicit CJS_PublicMethods(v8::Local<v8::Object> pObject)
+      : CJS_Object(pObject) {}
+  ~CJS_PublicMethods() override {}
+
+  static bool AFNumber_Format(IJS_Context* cc,
+                              const std::vector<CJS_Value>& params,
+                              CJS_Value& vRet,
+                              CFX_WideString& sError);
+  static bool AFNumber_Keystroke(IJS_Context* cc,
+                                 const std::vector<CJS_Value>& params,
+                                 CJS_Value& vRet,
+                                 CFX_WideString& sError);
+  static bool AFPercent_Format(IJS_Context* cc,
+                               const std::vector<CJS_Value>& params,
+                               CJS_Value& vRet,
+                               CFX_WideString& sError);
+  static bool AFPercent_Keystroke(IJS_Context* cc,
+                                  const std::vector<CJS_Value>& params,
+                                  CJS_Value& vRet,
+                                  CFX_WideString& sError);
+  static bool AFDate_FormatEx(IJS_Context* cc,
+                              const std::vector<CJS_Value>& params,
+                              CJS_Value& vRet,
+                              CFX_WideString& sError);
+  static bool AFDate_KeystrokeEx(IJS_Context* cc,
+                                 const std::vector<CJS_Value>& params,
+                                 CJS_Value& vRet,
+                                 CFX_WideString& sError);
+  static bool AFDate_Format(IJS_Context* cc,
+                            const std::vector<CJS_Value>& params,
+                            CJS_Value& vRet,
+                            CFX_WideString& sError);
+  static bool AFDate_Keystroke(IJS_Context* cc,
+                               const std::vector<CJS_Value>& params,
+                               CJS_Value& vRet,
+                               CFX_WideString& sError);
+  static bool AFTime_FormatEx(IJS_Context* cc,
+                              const std::vector<CJS_Value>& params,
+                              CJS_Value& vRet,
+                              CFX_WideString& sError);  //
+  static bool AFTime_KeystrokeEx(IJS_Context* cc,
+                                 const std::vector<CJS_Value>& params,
+                                 CJS_Value& vRet,
+                                 CFX_WideString& sError);
+  static bool AFTime_Format(IJS_Context* cc,
+                            const std::vector<CJS_Value>& params,
+                            CJS_Value& vRet,
+                            CFX_WideString& sError);
+  static bool AFTime_Keystroke(IJS_Context* cc,
+                               const std::vector<CJS_Value>& params,
+                               CJS_Value& vRet,
+                               CFX_WideString& sError);
+  static bool AFSpecial_Format(IJS_Context* cc,
+                               const std::vector<CJS_Value>& params,
+                               CJS_Value& vRet,
+                               CFX_WideString& sError);
+  static bool AFSpecial_Keystroke(IJS_Context* cc,
+                                  const std::vector<CJS_Value>& params,
+                                  CJS_Value& vRet,
+                                  CFX_WideString& sError);
+  static bool AFSpecial_KeystrokeEx(IJS_Context* cc,
+                                    const std::vector<CJS_Value>& params,
+                                    CJS_Value& vRet,
+                                    CFX_WideString& sError);  //
+  static bool AFSimple(IJS_Context* cc,
+                       const std::vector<CJS_Value>& params,
+                       CJS_Value& vRet,
+                       CFX_WideString& sError);
+  static bool AFMakeNumber(IJS_Context* cc,
+                           const std::vector<CJS_Value>& params,
+                           CJS_Value& vRet,
+                           CFX_WideString& sError);
+  static bool AFSimple_Calculate(IJS_Context* cc,
+                                 const std::vector<CJS_Value>& params,
+                                 CJS_Value& vRet,
+                                 CFX_WideString& sError);
+  static bool AFRange_Validate(IJS_Context* cc,
+                               const std::vector<CJS_Value>& params,
+                               CJS_Value& vRet,
+                               CFX_WideString& sError);
+  static bool AFMergeChange(IJS_Context* cc,
+                            const std::vector<CJS_Value>& params,
+                            CJS_Value& vRet,
+                            CFX_WideString& sError);
+  static bool AFParseDateEx(IJS_Context* cc,
+                            const std::vector<CJS_Value>& params,
+                            CJS_Value& vRet,
+                            CFX_WideString& sError);
+  static bool AFExtractNums(IJS_Context* cc,
+                            const std::vector<CJS_Value>& params,
+                            CJS_Value& vRet,
+                            CFX_WideString& sError);
+
+  JS_STATIC_GLOBAL_FUN(AFNumber_Format);
+  JS_STATIC_GLOBAL_FUN(AFNumber_Keystroke);
+  JS_STATIC_GLOBAL_FUN(AFPercent_Format);
+  JS_STATIC_GLOBAL_FUN(AFPercent_Keystroke);
+  JS_STATIC_GLOBAL_FUN(AFDate_FormatEx);
+  JS_STATIC_GLOBAL_FUN(AFDate_KeystrokeEx);
+  JS_STATIC_GLOBAL_FUN(AFDate_Format);
+  JS_STATIC_GLOBAL_FUN(AFDate_Keystroke);
+  JS_STATIC_GLOBAL_FUN(AFTime_FormatEx);
+  JS_STATIC_GLOBAL_FUN(AFTime_KeystrokeEx);
+  JS_STATIC_GLOBAL_FUN(AFTime_Format);
+  JS_STATIC_GLOBAL_FUN(AFTime_Keystroke);
+  JS_STATIC_GLOBAL_FUN(AFSpecial_Format);
+  JS_STATIC_GLOBAL_FUN(AFSpecial_Keystroke);
+  JS_STATIC_GLOBAL_FUN(AFSpecial_KeystrokeEx);
+  JS_STATIC_GLOBAL_FUN(AFSimple);
+  JS_STATIC_GLOBAL_FUN(AFMakeNumber);
+  JS_STATIC_GLOBAL_FUN(AFSimple_Calculate);
+  JS_STATIC_GLOBAL_FUN(AFRange_Validate);
+  JS_STATIC_GLOBAL_FUN(AFMergeChange);
+  JS_STATIC_GLOBAL_FUN(AFParseDateEx);
+  JS_STATIC_GLOBAL_FUN(AFExtractNums);
+
+  JS_STATIC_DECLARE_GLOBAL_FUN();
+
+  static int ParseStringInteger(const CFX_WideString& string,
+                                int nStart,
+                                int& nSkip,
+                                int nMaxStep);
+  static CFX_WideString ParseStringString(const CFX_WideString& string,
+                                          int nStart,
+                                          int& nSkip);
+  static double MakeRegularDate(const CFX_WideString& value,
+                                const CFX_WideString& format,
+                                bool* bWrongFormat);
+  static CFX_WideString MakeFormatDate(double dDate,
+                                       const CFX_WideString& format);
+  static double ParseNormalDate(const CFX_WideString& value,
+                                bool* bWrongFormat);
+  static double MakeInterDate(const CFX_WideString& value);
+
+  static bool IsNumber(const CFX_WideString& str);
+
+  static bool maskSatisfied(wchar_t c_Change, wchar_t c_Mask);
+  static bool isReservedMaskChar(wchar_t ch);
+
+  static double AF_Simple(const FX_WCHAR* sFuction,
+                          double dValue1,
+                          double dValue2);
+  static CJS_Array AF_MakeArrayFromList(CJS_Runtime* pRuntime, CJS_Value val);
+};
+
+#endif  // FPDFSDK_JAVASCRIPT_PUBLICMETHODS_H_
diff --git a/fpdfsdk/javascript/app.cpp b/fpdfsdk/javascript/app.cpp
new file mode 100644
index 0000000..6562d1b
--- /dev/null
+++ b/fpdfsdk/javascript/app.cpp
@@ -0,0 +1,802 @@
+// 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
+
+#include "fpdfsdk/javascript/app.h"
+
+#include <map>
+#include <memory>
+#include <vector>
+
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/cpdfsdk_interform.h"
+#include "fpdfsdk/javascript/Document.h"
+#include "fpdfsdk/javascript/JS_Define.h"
+#include "fpdfsdk/javascript/JS_EventHandler.h"
+#include "fpdfsdk/javascript/JS_Object.h"
+#include "fpdfsdk/javascript/JS_Value.h"
+#include "fpdfsdk/javascript/cjs_context.h"
+#include "fpdfsdk/javascript/cjs_runtime.h"
+#include "fpdfsdk/javascript/resource.h"
+#include "third_party/base/stl_util.h"
+
+class GlobalTimer {
+ public:
+  GlobalTimer(app* pObj,
+              CPDFSDK_FormFillEnvironment* pFormFillEnv,
+              CJS_Runtime* pRuntime,
+              int nType,
+              const CFX_WideString& script,
+              uint32_t dwElapse,
+              uint32_t dwTimeOut);
+  ~GlobalTimer();
+
+  static void Trigger(int nTimerID);
+  static void Cancel(int nTimerID);
+
+  bool IsOneShot() const { return m_nType == 1; }
+  uint32_t GetTimeOut() const { return m_dwTimeOut; }
+  int GetTimerID() const { return m_nTimerID; }
+  CJS_Runtime* GetRuntime() const { return m_pRuntime.Get(); }
+  CFX_WideString GetJScript() const { return m_swJScript; }
+
+ private:
+  using TimerMap = std::map<uint32_t, GlobalTimer*>;
+  static TimerMap* GetGlobalTimerMap();
+
+  uint32_t m_nTimerID;
+  app* const m_pEmbedObj;
+  bool m_bProcessing;
+
+  // data
+  const int m_nType;  // 0:Interval; 1:TimeOut
+  const uint32_t m_dwTimeOut;
+  const CFX_WideString m_swJScript;
+  CJS_Runtime::ObservedPtr m_pRuntime;
+  CPDFSDK_FormFillEnvironment* const m_pFormFillEnv;
+};
+
+GlobalTimer::GlobalTimer(app* pObj,
+                         CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                         CJS_Runtime* pRuntime,
+                         int nType,
+                         const CFX_WideString& script,
+                         uint32_t dwElapse,
+                         uint32_t dwTimeOut)
+    : m_nTimerID(0),
+      m_pEmbedObj(pObj),
+      m_bProcessing(false),
+      m_nType(nType),
+      m_dwTimeOut(dwTimeOut),
+      m_swJScript(script),
+      m_pRuntime(pRuntime),
+      m_pFormFillEnv(pFormFillEnv) {
+  CFX_SystemHandler* pHandler = m_pFormFillEnv->GetSysHandler();
+  m_nTimerID = pHandler->SetTimer(dwElapse, Trigger);
+  if (m_nTimerID)
+    (*GetGlobalTimerMap())[m_nTimerID] = this;
+}
+
+GlobalTimer::~GlobalTimer() {
+  if (!m_nTimerID)
+    return;
+
+  if (GetRuntime())
+    m_pFormFillEnv->GetSysHandler()->KillTimer(m_nTimerID);
+
+  GetGlobalTimerMap()->erase(m_nTimerID);
+}
+
+// static
+void GlobalTimer::Trigger(int nTimerID) {
+  auto it = GetGlobalTimerMap()->find(nTimerID);
+  if (it == GetGlobalTimerMap()->end())
+    return;
+
+  GlobalTimer* pTimer = it->second;
+  if (pTimer->m_bProcessing)
+    return;
+
+  pTimer->m_bProcessing = true;
+  if (pTimer->m_pEmbedObj)
+    pTimer->m_pEmbedObj->TimerProc(pTimer);
+
+  // Timer proc may have destroyed timer, find it again.
+  it = GetGlobalTimerMap()->find(nTimerID);
+  if (it == GetGlobalTimerMap()->end())
+    return;
+
+  pTimer = it->second;
+  pTimer->m_bProcessing = false;
+  if (pTimer->IsOneShot())
+    pTimer->m_pEmbedObj->CancelProc(pTimer);
+}
+
+// static
+void GlobalTimer::Cancel(int nTimerID) {
+  auto it = GetGlobalTimerMap()->find(nTimerID);
+  if (it == GetGlobalTimerMap()->end())
+    return;
+
+  GlobalTimer* pTimer = it->second;
+  pTimer->m_pEmbedObj->CancelProc(pTimer);
+}
+
+// static
+GlobalTimer::TimerMap* GlobalTimer::GetGlobalTimerMap() {
+  // Leak the timer array at shutdown.
+  static auto* s_TimerMap = new TimerMap;
+  return s_TimerMap;
+}
+
+BEGIN_JS_STATIC_CONST(CJS_TimerObj)
+END_JS_STATIC_CONST()
+
+BEGIN_JS_STATIC_PROP(CJS_TimerObj)
+END_JS_STATIC_PROP()
+
+BEGIN_JS_STATIC_METHOD(CJS_TimerObj)
+END_JS_STATIC_METHOD()
+
+IMPLEMENT_JS_CLASS(CJS_TimerObj, TimerObj)
+
+TimerObj::TimerObj(CJS_Object* pJSObject)
+    : CJS_EmbedObj(pJSObject), m_nTimerID(0) {}
+
+TimerObj::~TimerObj() {}
+
+void TimerObj::SetTimer(GlobalTimer* pTimer) {
+  m_nTimerID = pTimer->GetTimerID();
+}
+
+#define JS_STR_VIEWERTYPE L"pdfium"
+#define JS_STR_VIEWERVARIATION L"Full"
+#define JS_STR_PLATFORM L"WIN"
+#define JS_STR_LANGUAGE L"ENU"
+#define JS_NUM_VIEWERVERSION 8
+#ifdef PDF_ENABLE_XFA
+#define JS_NUM_VIEWERVERSION_XFA 11
+#endif  // PDF_ENABLE_XFA
+#define JS_NUM_FORMSVERSION 7
+
+BEGIN_JS_STATIC_CONST(CJS_App)
+END_JS_STATIC_CONST()
+
+BEGIN_JS_STATIC_PROP(CJS_App)
+JS_STATIC_PROP_ENTRY(activeDocs)
+JS_STATIC_PROP_ENTRY(calculate)
+JS_STATIC_PROP_ENTRY(formsVersion)
+JS_STATIC_PROP_ENTRY(fs)
+JS_STATIC_PROP_ENTRY(fullscreen)
+JS_STATIC_PROP_ENTRY(language)
+JS_STATIC_PROP_ENTRY(media)
+JS_STATIC_PROP_ENTRY(platform)
+JS_STATIC_PROP_ENTRY(runtimeHighlight)
+JS_STATIC_PROP_ENTRY(viewerType)
+JS_STATIC_PROP_ENTRY(viewerVariation)
+JS_STATIC_PROP_ENTRY(viewerVersion)
+END_JS_STATIC_PROP()
+
+BEGIN_JS_STATIC_METHOD(CJS_App)
+JS_STATIC_METHOD_ENTRY(alert)
+JS_STATIC_METHOD_ENTRY(beep)
+JS_STATIC_METHOD_ENTRY(browseForDoc)
+JS_STATIC_METHOD_ENTRY(clearInterval)
+JS_STATIC_METHOD_ENTRY(clearTimeOut)
+JS_STATIC_METHOD_ENTRY(execDialog)
+JS_STATIC_METHOD_ENTRY(execMenuItem)
+JS_STATIC_METHOD_ENTRY(findComponent)
+JS_STATIC_METHOD_ENTRY(goBack)
+JS_STATIC_METHOD_ENTRY(goForward)
+JS_STATIC_METHOD_ENTRY(launchURL)
+JS_STATIC_METHOD_ENTRY(mailMsg)
+JS_STATIC_METHOD_ENTRY(newFDF)
+JS_STATIC_METHOD_ENTRY(newDoc)
+JS_STATIC_METHOD_ENTRY(openDoc)
+JS_STATIC_METHOD_ENTRY(openFDF)
+JS_STATIC_METHOD_ENTRY(popUpMenuEx)
+JS_STATIC_METHOD_ENTRY(popUpMenu)
+JS_STATIC_METHOD_ENTRY(response)
+JS_STATIC_METHOD_ENTRY(setInterval)
+JS_STATIC_METHOD_ENTRY(setTimeOut)
+END_JS_STATIC_METHOD()
+
+IMPLEMENT_JS_CLASS(CJS_App, app)
+
+app::app(CJS_Object* pJSObject)
+    : CJS_EmbedObj(pJSObject), m_bCalculate(true), m_bRuntimeHighLight(false) {}
+
+app::~app() {
+}
+
+bool app::activeDocs(IJS_Context* cc,
+                     CJS_PropValue& vp,
+                     CFX_WideString& sError) {
+  if (!vp.IsGetting())
+    return false;
+
+  CJS_Context* pContext = (CJS_Context*)cc;
+  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+  CJS_Document* pJSDocument = nullptr;
+  v8::Local<v8::Object> pObj = pRuntime->GetThisObj();
+  if (CFXJS_Engine::GetObjDefnID(pObj) == CJS_Document::g_nObjDefnID) {
+    pJSDocument = static_cast<CJS_Document*>(pRuntime->GetObjectPrivate(pObj));
+  }
+
+  CJS_Array aDocs;
+  aDocs.SetElement(pRuntime, 0, CJS_Value(pRuntime, pJSDocument));
+
+  if (aDocs.GetLength(pRuntime) > 0)
+    vp << aDocs;
+  else
+    vp.GetJSValue()->SetNull(pRuntime);
+
+  return true;
+}
+
+bool app::calculate(IJS_Context* cc,
+                    CJS_PropValue& vp,
+                    CFX_WideString& sError) {
+  if (vp.IsSetting()) {
+    bool bVP;
+    vp >> bVP;
+    m_bCalculate = (bool)bVP;
+
+    CJS_Context* pContext = (CJS_Context*)cc;
+    pContext->GetFormFillEnv()->GetInterForm()->EnableCalculate(
+        (bool)m_bCalculate);
+  } else {
+    vp << (bool)m_bCalculate;
+  }
+  return true;
+}
+
+bool app::formsVersion(IJS_Context* cc,
+                       CJS_PropValue& vp,
+                       CFX_WideString& sError) {
+  if (vp.IsGetting()) {
+    vp << JS_NUM_FORMSVERSION;
+    return true;
+  }
+
+  return false;
+}
+
+bool app::viewerType(IJS_Context* cc,
+                     CJS_PropValue& vp,
+                     CFX_WideString& sError) {
+  if (vp.IsGetting()) {
+    vp << JS_STR_VIEWERTYPE;
+    return true;
+  }
+
+  return false;
+}
+
+bool app::viewerVariation(IJS_Context* cc,
+                          CJS_PropValue& vp,
+                          CFX_WideString& sError) {
+  if (vp.IsGetting()) {
+    vp << JS_STR_VIEWERVARIATION;
+    return true;
+  }
+
+  return false;
+}
+
+bool app::viewerVersion(IJS_Context* cc,
+                        CJS_PropValue& vp,
+                        CFX_WideString& sError) {
+  if (!vp.IsGetting())
+    return false;
+#ifdef PDF_ENABLE_XFA
+  CJS_Context* pJSContext = static_cast<CJS_Context*>(cc);
+  CPDFXFA_Context* pXFAContext = pJSContext->GetFormFillEnv()->GetXFAContext();
+  if (pXFAContext->GetDocType() == 1 || pXFAContext->GetDocType() == 2) {
+    vp << JS_NUM_VIEWERVERSION_XFA;
+    return true;
+  }
+#endif  // PDF_ENABLE_XFA
+  vp << JS_NUM_VIEWERVERSION;
+  return true;
+}
+
+bool app::platform(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
+  if (!vp.IsGetting())
+    return false;
+#ifdef PDF_ENABLE_XFA
+  CPDFSDK_FormFillEnvironment* pFormFillEnv =
+      static_cast<CJS_Context*>(cc)->GetJSRuntime()->GetFormFillEnv();
+  if (!pFormFillEnv)
+    return false;
+  CFX_WideString platfrom = pFormFillEnv->GetPlatform();
+  if (!platfrom.IsEmpty()) {
+    vp << platfrom;
+    return true;
+  }
+#endif
+  vp << JS_STR_PLATFORM;
+  return true;
+}
+
+bool app::language(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
+  if (!vp.IsGetting())
+    return false;
+#ifdef PDF_ENABLE_XFA
+  CPDFSDK_FormFillEnvironment* pFormFillEnv =
+      static_cast<CJS_Context*>(cc)->GetJSRuntime()->GetFormFillEnv();
+  if (!pFormFillEnv)
+    return false;
+  CFX_WideString language = pFormFillEnv->GetLanguage();
+  if (!language.IsEmpty()) {
+    vp << language;
+    return true;
+  }
+#endif
+  vp << JS_STR_LANGUAGE;
+  return true;
+}
+
+// creates a new fdf object that contains no data
+// comment: need reader support
+// note:
+// CFDF_Document * CPDFSDK_FormFillEnvironment::NewFDF();
+bool app::newFDF(IJS_Context* cc,
+                 const std::vector<CJS_Value>& params,
+                 CJS_Value& vRet,
+                 CFX_WideString& sError) {
+  return true;
+}
+// opens a specified pdf document and returns its document object
+// comment:need reader support
+// note: as defined in js reference, the proto of this function's fourth
+// parmeters, how old an fdf document while do not show it.
+// CFDF_Document * CPDFSDK_FormFillEnvironment::OpenFDF(string strPath,bool
+// bUserConv);
+
+bool app::openFDF(IJS_Context* cc,
+                  const std::vector<CJS_Value>& params,
+                  CJS_Value& vRet,
+                  CFX_WideString& sError) {
+  return true;
+}
+
+bool app::alert(IJS_Context* cc,
+                const std::vector<CJS_Value>& params,
+                CJS_Value& vRet,
+                CFX_WideString& sError) {
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  std::vector<CJS_Value> newParams = JS_ExpandKeywordParams(
+      pRuntime, params, 4, L"cMsg", L"nIcon", L"nType", L"cTitle");
+
+  if (newParams[0].GetType() == CJS_Value::VT_unknown) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+
+  CPDFSDK_FormFillEnvironment* pFormFillEnv = pRuntime->GetFormFillEnv();
+  if (!pFormFillEnv) {
+    vRet = CJS_Value(pRuntime, 0);
+    return true;
+  }
+
+  CFX_WideString swMsg;
+  if (newParams[0].GetType() == CJS_Value::VT_object) {
+    CJS_Array carray;
+    if (newParams[0].ConvertToArray(pRuntime, carray)) {
+      swMsg = L"[";
+      CJS_Value element(pRuntime);
+      for (int i = 0; i < carray.GetLength(pRuntime); ++i) {
+        if (i)
+          swMsg += L", ";
+        carray.GetElement(pRuntime, i, element);
+        swMsg += element.ToCFXWideString(pRuntime);
+      }
+      swMsg += L"]";
+    } else {
+      swMsg = newParams[0].ToCFXWideString(pRuntime);
+    }
+  } else {
+    swMsg = newParams[0].ToCFXWideString(pRuntime);
+  }
+
+  int iIcon = 0;
+  if (newParams[1].GetType() != CJS_Value::VT_unknown)
+    iIcon = newParams[1].ToInt(pRuntime);
+
+  int iType = 0;
+  if (newParams[2].GetType() != CJS_Value::VT_unknown)
+    iType = newParams[2].ToInt(pRuntime);
+
+  CFX_WideString swTitle;
+  if (newParams[3].GetType() != CJS_Value::VT_unknown)
+    swTitle = newParams[3].ToCFXWideString(pRuntime);
+  else
+    swTitle = JSGetStringFromID(IDS_STRING_JSALERT);
+
+  pRuntime->BeginBlock();
+  pFormFillEnv->KillFocusAnnot(0);
+
+  vRet = CJS_Value(pRuntime, pFormFillEnv->JS_appAlert(
+                                 swMsg.c_str(), swTitle.c_str(), iType, iIcon));
+  pRuntime->EndBlock();
+  return true;
+}
+
+bool app::beep(IJS_Context* cc,
+               const std::vector<CJS_Value>& params,
+               CJS_Value& vRet,
+               CFX_WideString& sError) {
+  if (params.size() == 1) {
+    CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+    pRuntime->GetFormFillEnv()->JS_appBeep(params[0].ToInt(pRuntime));
+    return true;
+  }
+
+  sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+  return false;
+}
+
+bool app::findComponent(IJS_Context* cc,
+                        const std::vector<CJS_Value>& params,
+                        CJS_Value& vRet,
+                        CFX_WideString& sError) {
+  return true;
+}
+
+bool app::popUpMenuEx(IJS_Context* cc,
+                      const std::vector<CJS_Value>& params,
+                      CJS_Value& vRet,
+                      CFX_WideString& sError) {
+  return false;
+}
+
+bool app::fs(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
+  return false;
+}
+
+bool app::setInterval(IJS_Context* cc,
+                      const std::vector<CJS_Value>& params,
+                      CJS_Value& vRet,
+                      CFX_WideString& sError) {
+  if (params.size() > 2 || params.size() == 0) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  CFX_WideString script =
+      params.size() > 0 ? params[0].ToCFXWideString(pRuntime) : L"";
+  if (script.IsEmpty()) {
+    sError = JSGetStringFromID(IDS_STRING_JSAFNUMBER_KEYSTROKE);
+    return true;
+  }
+
+  uint32_t dwInterval = params.size() > 1 ? params[1].ToInt(pRuntime) : 1000;
+
+  GlobalTimer* timerRef = new GlobalTimer(this, pRuntime->GetFormFillEnv(),
+                                          pRuntime, 0, script, dwInterval, 0);
+  m_Timers.insert(std::unique_ptr<GlobalTimer>(timerRef));
+
+  v8::Local<v8::Object> pRetObj =
+      pRuntime->NewFxDynamicObj(CJS_TimerObj::g_nObjDefnID);
+  CJS_TimerObj* pJS_TimerObj =
+      static_cast<CJS_TimerObj*>(pRuntime->GetObjectPrivate(pRetObj));
+  TimerObj* pTimerObj = static_cast<TimerObj*>(pJS_TimerObj->GetEmbedObject());
+  pTimerObj->SetTimer(timerRef);
+
+  vRet = CJS_Value(pRuntime, pRetObj);
+  return true;
+}
+
+bool app::setTimeOut(IJS_Context* cc,
+                     const std::vector<CJS_Value>& params,
+                     CJS_Value& vRet,
+                     CFX_WideString& sError) {
+  if (params.size() > 2 || params.size() == 0) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  CFX_WideString script = params[0].ToCFXWideString(pRuntime);
+  if (script.IsEmpty()) {
+    sError = JSGetStringFromID(IDS_STRING_JSAFNUMBER_KEYSTROKE);
+    return true;
+  }
+
+  uint32_t dwTimeOut = params.size() > 1 ? params[1].ToInt(pRuntime) : 1000;
+  GlobalTimer* timerRef =
+      new GlobalTimer(this, pRuntime->GetFormFillEnv(), pRuntime, 1, script,
+                      dwTimeOut, dwTimeOut);
+  m_Timers.insert(std::unique_ptr<GlobalTimer>(timerRef));
+
+  v8::Local<v8::Object> pRetObj =
+      pRuntime->NewFxDynamicObj(CJS_TimerObj::g_nObjDefnID);
+
+  CJS_TimerObj* pJS_TimerObj =
+      static_cast<CJS_TimerObj*>(pRuntime->GetObjectPrivate(pRetObj));
+
+  TimerObj* pTimerObj = static_cast<TimerObj*>(pJS_TimerObj->GetEmbedObject());
+  pTimerObj->SetTimer(timerRef);
+
+  vRet = CJS_Value(pRuntime, pRetObj);
+  return true;
+}
+
+bool app::clearTimeOut(IJS_Context* cc,
+                       const std::vector<CJS_Value>& params,
+                       CJS_Value& vRet,
+                       CFX_WideString& sError) {
+  if (params.size() != 1) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+
+  app::ClearTimerCommon(CJS_Runtime::FromContext(cc), params[0]);
+  return true;
+}
+
+bool app::clearInterval(IJS_Context* cc,
+                        const std::vector<CJS_Value>& params,
+                        CJS_Value& vRet,
+                        CFX_WideString& sError) {
+  if (params.size() != 1) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+
+  app::ClearTimerCommon(CJS_Runtime::FromContext(cc), params[0]);
+  return true;
+}
+
+void app::ClearTimerCommon(CJS_Runtime* pRuntime, const CJS_Value& param) {
+  if (param.GetType() != CJS_Value::VT_object)
+    return;
+
+  v8::Local<v8::Object> pObj = param.ToV8Object(pRuntime);
+  if (CFXJS_Engine::GetObjDefnID(pObj) != CJS_TimerObj::g_nObjDefnID)
+    return;
+
+  CJS_Object* pJSObj = param.ToCJSObject(pRuntime);
+  if (!pJSObj)
+    return;
+
+  TimerObj* pTimerObj = static_cast<TimerObj*>(pJSObj->GetEmbedObject());
+  if (!pTimerObj)
+    return;
+
+  GlobalTimer::Cancel(pTimerObj->GetTimerID());
+}
+
+bool app::execMenuItem(IJS_Context* cc,
+                       const std::vector<CJS_Value>& params,
+                       CJS_Value& vRet,
+                       CFX_WideString& sError) {
+  return false;
+}
+
+void app::TimerProc(GlobalTimer* pTimer) {
+  CJS_Runtime* pRuntime = pTimer->GetRuntime();
+  if (pRuntime && (!pTimer->IsOneShot() || pTimer->GetTimeOut() > 0))
+    RunJsScript(pRuntime, pTimer->GetJScript());
+}
+
+void app::CancelProc(GlobalTimer* pTimer) {
+  m_Timers.erase(pdfium::FakeUniquePtr<GlobalTimer>(pTimer));
+}
+
+void app::RunJsScript(CJS_Runtime* pRuntime, const CFX_WideString& wsScript) {
+  if (!pRuntime->IsBlocking()) {
+    IJS_Context* pContext = pRuntime->NewContext();
+    pContext->OnExternal_Exec();
+    CFX_WideString wtInfo;
+    pContext->RunScript(wsScript, &wtInfo);
+    pRuntime->ReleaseContext(pContext);
+  }
+}
+
+bool app::goBack(IJS_Context* cc,
+                 const std::vector<CJS_Value>& params,
+                 CJS_Value& vRet,
+                 CFX_WideString& sError) {
+  // Not supported.
+  return true;
+}
+
+bool app::goForward(IJS_Context* cc,
+                    const std::vector<CJS_Value>& params,
+                    CJS_Value& vRet,
+                    CFX_WideString& sError) {
+  // Not supported.
+  return true;
+}
+
+bool app::mailMsg(IJS_Context* cc,
+                  const std::vector<CJS_Value>& params,
+                  CJS_Value& vRet,
+                  CFX_WideString& sError) {
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  std::vector<CJS_Value> newParams =
+      JS_ExpandKeywordParams(pRuntime, params, 6, L"bUI", L"cTo", L"cCc",
+                             L"cBcc", L"cSubject", L"cMsg");
+
+  if (newParams[0].GetType() == CJS_Value::VT_unknown) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+  bool bUI = newParams[0].ToBool(pRuntime);
+
+  CFX_WideString cTo;
+  if (newParams[1].GetType() != CJS_Value::VT_unknown) {
+    cTo = newParams[1].ToCFXWideString(pRuntime);
+  } else {
+    if (!bUI) {
+      // cTo parameter required when UI not invoked.
+      sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+      return false;
+    }
+  }
+
+  CFX_WideString cCc;
+  if (newParams[2].GetType() != CJS_Value::VT_unknown)
+    cCc = newParams[2].ToCFXWideString(pRuntime);
+
+  CFX_WideString cBcc;
+  if (newParams[3].GetType() != CJS_Value::VT_unknown)
+    cBcc = newParams[3].ToCFXWideString(pRuntime);
+
+  CFX_WideString cSubject;
+  if (newParams[4].GetType() != CJS_Value::VT_unknown)
+    cSubject = newParams[4].ToCFXWideString(pRuntime);
+
+  CFX_WideString cMsg;
+  if (newParams[5].GetType() != CJS_Value::VT_unknown)
+    cMsg = newParams[5].ToCFXWideString(pRuntime);
+
+  pRuntime->BeginBlock();
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+  pContext->GetFormFillEnv()->JS_docmailForm(nullptr, 0, bUI, cTo.c_str(),
+                                             cSubject.c_str(), cCc.c_str(),
+                                             cBcc.c_str(), cMsg.c_str());
+  pRuntime->EndBlock();
+  return true;
+}
+
+bool app::launchURL(IJS_Context* cc,
+                    const std::vector<CJS_Value>& params,
+                    CJS_Value& vRet,
+                    CFX_WideString& sError) {
+  // Unsafe, not supported.
+  return true;
+}
+
+bool app::runtimeHighlight(IJS_Context* cc,
+                           CJS_PropValue& vp,
+                           CFX_WideString& sError) {
+  if (vp.IsSetting()) {
+    vp >> m_bRuntimeHighLight;
+  } else {
+    vp << m_bRuntimeHighLight;
+  }
+  return true;
+}
+
+bool app::fullscreen(IJS_Context* cc,
+                     CJS_PropValue& vp,
+                     CFX_WideString& sError) {
+  return false;
+}
+
+bool app::popUpMenu(IJS_Context* cc,
+                    const std::vector<CJS_Value>& params,
+                    CJS_Value& vRet,
+                    CFX_WideString& sError) {
+  return false;
+}
+
+bool app::browseForDoc(IJS_Context* cc,
+                       const std::vector<CJS_Value>& params,
+                       CJS_Value& vRet,
+                       CFX_WideString& sError) {
+  // Unsafe, not supported.
+  return true;
+}
+
+CFX_WideString app::SysPathToPDFPath(const CFX_WideString& sOldPath) {
+  CFX_WideString sRet = L"/";
+
+  for (int i = 0, sz = sOldPath.GetLength(); i < sz; i++) {
+    wchar_t c = sOldPath.GetAt(i);
+    if (c == L':') {
+    } else {
+      if (c == L'\\') {
+        sRet += L"/";
+      } else {
+        sRet += c;
+      }
+    }
+  }
+
+  return sRet;
+}
+
+bool app::newDoc(IJS_Context* cc,
+                 const std::vector<CJS_Value>& params,
+                 CJS_Value& vRet,
+                 CFX_WideString& sError) {
+  return false;
+}
+
+bool app::openDoc(IJS_Context* cc,
+                  const std::vector<CJS_Value>& params,
+                  CJS_Value& vRet,
+                  CFX_WideString& sError) {
+  return false;
+}
+
+bool app::response(IJS_Context* cc,
+                   const std::vector<CJS_Value>& params,
+                   CJS_Value& vRet,
+                   CFX_WideString& sError) {
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  std::vector<CJS_Value> newParams =
+      JS_ExpandKeywordParams(pRuntime, params, 5, L"cQuestion", L"cTitle",
+                             L"cDefault", L"bPassword", L"cLabel");
+
+  if (newParams[0].GetType() == CJS_Value::VT_unknown) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+  CFX_WideString swQuestion = newParams[0].ToCFXWideString(pRuntime);
+
+  CFX_WideString swTitle = L"PDF";
+  if (newParams[1].GetType() != CJS_Value::VT_unknown)
+    swTitle = newParams[1].ToCFXWideString(pRuntime);
+
+  CFX_WideString swDefault;
+  if (newParams[2].GetType() != CJS_Value::VT_unknown)
+    swDefault = newParams[2].ToCFXWideString(pRuntime);
+
+  bool bPassword = false;
+  if (newParams[3].GetType() != CJS_Value::VT_unknown)
+    bPassword = newParams[3].ToBool(pRuntime);
+
+  CFX_WideString swLabel;
+  if (newParams[4].GetType() != CJS_Value::VT_unknown)
+    swLabel = newParams[4].ToCFXWideString(pRuntime);
+
+  const int MAX_INPUT_BYTES = 2048;
+  std::unique_ptr<char[]> pBuff(new char[MAX_INPUT_BYTES + 2]);
+  memset(pBuff.get(), 0, MAX_INPUT_BYTES + 2);
+
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+  int nLengthBytes = pContext->GetFormFillEnv()->JS_appResponse(
+      swQuestion.c_str(), swTitle.c_str(), swDefault.c_str(), swLabel.c_str(),
+      bPassword, pBuff.get(), MAX_INPUT_BYTES);
+
+  if (nLengthBytes < 0 || nLengthBytes > MAX_INPUT_BYTES) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAM_TOOLONG);
+    return false;
+  }
+
+  vRet = CJS_Value(pRuntime, CFX_WideString::FromUTF16LE(
+                                 reinterpret_cast<uint16_t*>(pBuff.get()),
+                                 nLengthBytes / sizeof(uint16_t))
+                                 .c_str());
+
+  return true;
+}
+
+bool app::media(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
+  return false;
+}
+
+bool app::execDialog(IJS_Context* cc,
+                     const std::vector<CJS_Value>& params,
+                     CJS_Value& vRet,
+                     CFX_WideString& sError) {
+  return true;
+}
diff --git a/fpdfsdk/javascript/app.h b/fpdfsdk/javascript/app.h
new file mode 100644
index 0000000..e8c7241
--- /dev/null
+++ b/fpdfsdk/javascript/app.h
@@ -0,0 +1,207 @@
+// 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_JAVASCRIPT_APP_H_
+#define FPDFSDK_JAVASCRIPT_APP_H_
+
+#include <memory>
+#include <unordered_set>
+#include <vector>
+
+#include "fpdfsdk/javascript/JS_Define.h"
+
+class CJS_Runtime;
+class GlobalTimer;
+
+class TimerObj : public CJS_EmbedObj {
+ public:
+  explicit TimerObj(CJS_Object* pJSObject);
+  ~TimerObj() override;
+
+  void SetTimer(GlobalTimer* pTimer);
+  int GetTimerID() const { return m_nTimerID; }
+
+ private:
+  int m_nTimerID;  // Weak reference to GlobalTimer through global map.
+};
+
+class CJS_TimerObj : public CJS_Object {
+ public:
+  explicit CJS_TimerObj(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_TimerObj() override {}
+
+  DECLARE_JS_CLASS();
+};
+
+class app : public CJS_EmbedObj {
+ public:
+  explicit app(CJS_Object* pJSObject);
+  ~app() override;
+
+  bool activeDocs(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool calculate(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool formsVersion(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool fs(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool fullscreen(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool language(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool media(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool platform(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool runtimeHighlight(IJS_Context* cc,
+                        CJS_PropValue& vp,
+                        CFX_WideString& sError);
+  bool viewerType(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool viewerVariation(IJS_Context* cc,
+                       CJS_PropValue& vp,
+                       CFX_WideString& sError);
+  bool viewerVersion(IJS_Context* cc,
+                     CJS_PropValue& vp,
+                     CFX_WideString& sError);
+
+  bool alert(IJS_Context* cc,
+             const std::vector<CJS_Value>& params,
+             CJS_Value& vRet,
+             CFX_WideString& sError);
+  bool beep(IJS_Context* cc,
+            const std::vector<CJS_Value>& params,
+            CJS_Value& vRet,
+            CFX_WideString& sError);
+  bool browseForDoc(IJS_Context* cc,
+                    const std::vector<CJS_Value>& params,
+                    CJS_Value& vRet,
+                    CFX_WideString& sError);
+  bool clearInterval(IJS_Context* cc,
+                     const std::vector<CJS_Value>& params,
+                     CJS_Value& vRet,
+                     CFX_WideString& sError);
+  bool clearTimeOut(IJS_Context* cc,
+                    const std::vector<CJS_Value>& params,
+                    CJS_Value& vRet,
+                    CFX_WideString& sError);
+  bool execDialog(IJS_Context* cc,
+                  const std::vector<CJS_Value>& params,
+                  CJS_Value& vRet,
+                  CFX_WideString& sError);
+  bool execMenuItem(IJS_Context* cc,
+                    const std::vector<CJS_Value>& params,
+                    CJS_Value& vRet,
+                    CFX_WideString& sError);
+  bool findComponent(IJS_Context* cc,
+                     const std::vector<CJS_Value>& params,
+                     CJS_Value& vRet,
+                     CFX_WideString& sError);
+  bool goBack(IJS_Context* cc,
+              const std::vector<CJS_Value>& params,
+              CJS_Value& vRet,
+              CFX_WideString& sError);
+  bool goForward(IJS_Context* cc,
+                 const std::vector<CJS_Value>& params,
+                 CJS_Value& vRet,
+                 CFX_WideString& sError);
+  bool launchURL(IJS_Context* cc,
+                 const std::vector<CJS_Value>& params,
+                 CJS_Value& vRet,
+                 CFX_WideString& sError);
+  bool mailMsg(IJS_Context* cc,
+               const std::vector<CJS_Value>& params,
+               CJS_Value& vRet,
+               CFX_WideString& sError);
+  bool newFDF(IJS_Context* cc,
+              const std::vector<CJS_Value>& params,
+              CJS_Value& vRet,
+              CFX_WideString& sError);
+  bool newDoc(IJS_Context* cc,
+              const std::vector<CJS_Value>& params,
+              CJS_Value& vRet,
+              CFX_WideString& sError);
+  bool openDoc(IJS_Context* cc,
+               const std::vector<CJS_Value>& params,
+               CJS_Value& vRet,
+               CFX_WideString& sError);
+  bool openFDF(IJS_Context* cc,
+               const std::vector<CJS_Value>& params,
+               CJS_Value& vRet,
+               CFX_WideString& sError);
+  bool popUpMenuEx(IJS_Context* cc,
+                   const std::vector<CJS_Value>& params,
+                   CJS_Value& vRet,
+                   CFX_WideString& sError);
+  bool popUpMenu(IJS_Context* cc,
+                 const std::vector<CJS_Value>& params,
+                 CJS_Value& vRet,
+                 CFX_WideString& sError);
+  bool response(IJS_Context* cc,
+                const std::vector<CJS_Value>& params,
+                CJS_Value& vRet,
+                CFX_WideString& sError);
+  bool setInterval(IJS_Context* cc,
+                   const std::vector<CJS_Value>& params,
+                   CJS_Value& vRet,
+                   CFX_WideString& sError);
+  bool setTimeOut(IJS_Context* cc,
+                  const std::vector<CJS_Value>& params,
+                  CJS_Value& vRet,
+                  CFX_WideString& sError);
+
+  void TimerProc(GlobalTimer* pTimer);
+  void CancelProc(GlobalTimer* pTimer);
+
+  static CFX_WideString SysPathToPDFPath(const CFX_WideString& sOldPath);
+
+ private:
+  // CJS_EmbedObj
+  void RunJsScript(CJS_Runtime* pRuntime, const CFX_WideString& wsScript);
+
+  void ClearTimerCommon(CJS_Runtime* pRuntime, const CJS_Value& param);
+
+  bool m_bCalculate;
+  bool m_bRuntimeHighLight;
+  std::unordered_set<std::unique_ptr<GlobalTimer>> m_Timers;
+};
+
+class CJS_App : public CJS_Object {
+ public:
+  explicit CJS_App(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_App() override {}
+
+  DECLARE_JS_CLASS();
+
+  JS_STATIC_PROP(activeDocs, app);
+  JS_STATIC_PROP(calculate, app);
+  JS_STATIC_PROP(formsVersion, app);
+  JS_STATIC_PROP(fs, app);
+  JS_STATIC_PROP(fullscreen, app);
+  JS_STATIC_PROP(language, app);
+  JS_STATIC_PROP(media, app);
+  JS_STATIC_PROP(platform, app);
+  JS_STATIC_PROP(runtimeHighlight, app);
+  JS_STATIC_PROP(viewerType, app);
+  JS_STATIC_PROP(viewerVariation, app);
+  JS_STATIC_PROP(viewerVersion, app);
+
+  JS_STATIC_METHOD(alert, app);
+  JS_STATIC_METHOD(beep, app);
+  JS_STATIC_METHOD(browseForDoc, app);
+  JS_STATIC_METHOD(clearInterval, app);
+  JS_STATIC_METHOD(clearTimeOut, app);
+  JS_STATIC_METHOD(execDialog, app);
+  JS_STATIC_METHOD(execMenuItem, app);
+  JS_STATIC_METHOD(findComponent, app);
+  JS_STATIC_METHOD(goBack, app);
+  JS_STATIC_METHOD(goForward, app);
+  JS_STATIC_METHOD(launchURL, app);
+  JS_STATIC_METHOD(mailMsg, app);
+  JS_STATIC_METHOD(newFDF, app);
+  JS_STATIC_METHOD(newDoc, app);
+  JS_STATIC_METHOD(openDoc, app);
+  JS_STATIC_METHOD(openFDF, app);
+  JS_STATIC_METHOD(popUpMenuEx, app);
+  JS_STATIC_METHOD(popUpMenu, app);
+  JS_STATIC_METHOD(response, app);
+  JS_STATIC_METHOD(setInterval, app);
+  JS_STATIC_METHOD(setTimeOut, app);
+};
+
+#endif  // FPDFSDK_JAVASCRIPT_APP_H_
diff --git a/fpdfsdk/javascript/cjs_context.cpp b/fpdfsdk/javascript/cjs_context.cpp
new file mode 100644
index 0000000..e356bdd
--- /dev/null
+++ b/fpdfsdk/javascript/cjs_context.cpp
@@ -0,0 +1,272 @@
+// 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
+
+#include "fpdfsdk/javascript/cjs_context.h"
+
+#include "fpdfsdk/javascript/JS_EventHandler.h"
+#include "fpdfsdk/javascript/cjs_runtime.h"
+#include "fpdfsdk/javascript/resource.h"
+
+CJS_Context::CJS_Context(CJS_Runtime* pRuntime)
+    : m_pRuntime(pRuntime),
+      m_pEventHandler(new CJS_EventHandler(this)),
+      m_bBusy(false) {}
+
+CJS_Context::~CJS_Context() {}
+
+CPDFSDK_FormFillEnvironment* CJS_Context::GetFormFillEnv() {
+  return m_pRuntime->GetFormFillEnv();
+}
+
+bool CJS_Context::RunScript(const CFX_WideString& script,
+                            CFX_WideString* info) {
+  v8::Isolate::Scope isolate_scope(m_pRuntime->GetIsolate());
+  v8::HandleScope handle_scope(m_pRuntime->GetIsolate());
+  v8::Local<v8::Context> context = m_pRuntime->NewLocalContext();
+  v8::Context::Scope context_scope(context);
+
+  if (m_bBusy) {
+    *info = JSGetStringFromID(IDS_STRING_JSBUSY);
+    return false;
+  }
+  m_bBusy = true;
+
+  ASSERT(m_pEventHandler->IsValid());
+  CJS_Runtime::FieldEvent event(m_pEventHandler->TargetName(),
+                                m_pEventHandler->EventType());
+  if (!m_pRuntime->AddEventToSet(event)) {
+    *info = JSGetStringFromID(IDS_STRING_JSEVENT);
+    return false;
+  }
+
+  CFX_WideString sErrorMessage;
+  int nRet = 0;
+  if (script.GetLength() > 0) {
+    nRet = m_pRuntime->ExecuteScript(script.c_str(), &sErrorMessage);
+  }
+
+  if (nRet < 0) {
+    *info += sErrorMessage;
+  } else {
+    *info = JSGetStringFromID(IDS_STRING_RUN);
+  }
+
+  m_pRuntime->RemoveEventFromSet(event);
+  m_pEventHandler->Destroy();
+  m_bBusy = false;
+
+  return nRet >= 0;
+}
+
+void CJS_Context::OnApp_Init() {
+  m_pEventHandler->OnApp_Init();
+}
+
+void CJS_Context::OnDoc_Open(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                             const CFX_WideString& strTargetName) {
+  m_pEventHandler->OnDoc_Open(pFormFillEnv, strTargetName);
+}
+
+void CJS_Context::OnDoc_WillPrint(CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+  m_pEventHandler->OnDoc_WillPrint(pFormFillEnv);
+}
+
+void CJS_Context::OnDoc_DidPrint(CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+  m_pEventHandler->OnDoc_DidPrint(pFormFillEnv);
+}
+
+void CJS_Context::OnDoc_WillSave(CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+  m_pEventHandler->OnDoc_WillSave(pFormFillEnv);
+}
+
+void CJS_Context::OnDoc_DidSave(CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+  m_pEventHandler->OnDoc_DidSave(pFormFillEnv);
+}
+
+void CJS_Context::OnDoc_WillClose(CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+  m_pEventHandler->OnDoc_WillClose(pFormFillEnv);
+}
+
+void CJS_Context::OnPage_Open(CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+  m_pEventHandler->OnPage_Open(pFormFillEnv);
+}
+
+void CJS_Context::OnPage_Close(CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+  m_pEventHandler->OnPage_Close(pFormFillEnv);
+}
+
+void CJS_Context::OnPage_InView(CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+  m_pEventHandler->OnPage_InView(pFormFillEnv);
+}
+
+void CJS_Context::OnPage_OutView(CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+  m_pEventHandler->OnPage_OutView(pFormFillEnv);
+}
+
+void CJS_Context::OnField_MouseDown(bool bModifier,
+                                    bool bShift,
+                                    CPDF_FormField* pTarget) {
+  m_pEventHandler->OnField_MouseDown(bModifier, bShift, pTarget);
+}
+
+void CJS_Context::OnField_MouseEnter(bool bModifier,
+                                     bool bShift,
+                                     CPDF_FormField* pTarget) {
+  m_pEventHandler->OnField_MouseEnter(bModifier, bShift, pTarget);
+}
+
+void CJS_Context::OnField_MouseExit(bool bModifier,
+                                    bool bShift,
+                                    CPDF_FormField* pTarget) {
+  m_pEventHandler->OnField_MouseExit(bModifier, bShift, pTarget);
+}
+
+void CJS_Context::OnField_MouseUp(bool bModifier,
+                                  bool bShift,
+                                  CPDF_FormField* pTarget) {
+  m_pEventHandler->OnField_MouseUp(bModifier, bShift, pTarget);
+}
+
+void CJS_Context::OnField_Focus(bool bModifier,
+                                bool bShift,
+                                CPDF_FormField* pTarget,
+                                const CFX_WideString& Value) {
+  m_pEventHandler->OnField_Focus(bModifier, bShift, pTarget, Value);
+}
+
+void CJS_Context::OnField_Blur(bool bModifier,
+                               bool bShift,
+                               CPDF_FormField* pTarget,
+                               const CFX_WideString& Value) {
+  m_pEventHandler->OnField_Blur(bModifier, bShift, pTarget, Value);
+}
+
+void CJS_Context::OnField_Calculate(CPDF_FormField* pSource,
+                                    CPDF_FormField* pTarget,
+                                    CFX_WideString& Value,
+                                    bool& bRc) {
+  m_pEventHandler->OnField_Calculate(pSource, pTarget, Value, bRc);
+}
+
+void CJS_Context::OnField_Format(CPDF_FormField* pTarget,
+                                 CFX_WideString& Value,
+                                 bool bWillCommit) {
+  m_pEventHandler->OnField_Format(pTarget, Value, bWillCommit);
+}
+
+void CJS_Context::OnField_Keystroke(CFX_WideString& strChange,
+                                    const CFX_WideString& strChangeEx,
+                                    bool bKeyDown,
+                                    bool bModifier,
+                                    int& nSelEnd,
+                                    int& nSelStart,
+                                    bool bShift,
+                                    CPDF_FormField* pTarget,
+                                    CFX_WideString& Value,
+                                    bool bWillCommit,
+                                    bool bFieldFull,
+                                    bool& bRc) {
+  m_pEventHandler->OnField_Keystroke(
+      strChange, strChangeEx, bKeyDown, bModifier, nSelEnd, nSelStart, bShift,
+      pTarget, Value, bWillCommit, bFieldFull, bRc);
+}
+
+void CJS_Context::OnField_Validate(CFX_WideString& strChange,
+                                   const CFX_WideString& strChangeEx,
+                                   bool bKeyDown,
+                                   bool bModifier,
+                                   bool bShift,
+                                   CPDF_FormField* pTarget,
+                                   CFX_WideString& Value,
+                                   bool& bRc) {
+  m_pEventHandler->OnField_Validate(strChange, strChangeEx, bKeyDown, bModifier,
+                                    bShift, pTarget, Value, bRc);
+}
+
+void CJS_Context::OnScreen_Focus(bool bModifier,
+                                 bool bShift,
+                                 CPDFSDK_Annot* pScreen) {
+  m_pEventHandler->OnScreen_Focus(bModifier, bShift, pScreen);
+}
+
+void CJS_Context::OnScreen_Blur(bool bModifier,
+                                bool bShift,
+                                CPDFSDK_Annot* pScreen) {
+  m_pEventHandler->OnScreen_Blur(bModifier, bShift, pScreen);
+}
+
+void CJS_Context::OnScreen_Open(bool bModifier,
+                                bool bShift,
+                                CPDFSDK_Annot* pScreen) {
+  m_pEventHandler->OnScreen_Open(bModifier, bShift, pScreen);
+}
+
+void CJS_Context::OnScreen_Close(bool bModifier,
+                                 bool bShift,
+                                 CPDFSDK_Annot* pScreen) {
+  m_pEventHandler->OnScreen_Close(bModifier, bShift, pScreen);
+}
+
+void CJS_Context::OnScreen_MouseDown(bool bModifier,
+                                     bool bShift,
+                                     CPDFSDK_Annot* pScreen) {
+  m_pEventHandler->OnScreen_MouseDown(bModifier, bShift, pScreen);
+}
+
+void CJS_Context::OnScreen_MouseUp(bool bModifier,
+                                   bool bShift,
+                                   CPDFSDK_Annot* pScreen) {
+  m_pEventHandler->OnScreen_MouseUp(bModifier, bShift, pScreen);
+}
+
+void CJS_Context::OnScreen_MouseEnter(bool bModifier,
+                                      bool bShift,
+                                      CPDFSDK_Annot* pScreen) {
+  m_pEventHandler->OnScreen_MouseEnter(bModifier, bShift, pScreen);
+}
+
+void CJS_Context::OnScreen_MouseExit(bool bModifier,
+                                     bool bShift,
+                                     CPDFSDK_Annot* pScreen) {
+  m_pEventHandler->OnScreen_MouseExit(bModifier, bShift, pScreen);
+}
+
+void CJS_Context::OnScreen_InView(bool bModifier,
+                                  bool bShift,
+                                  CPDFSDK_Annot* pScreen) {
+  m_pEventHandler->OnScreen_InView(bModifier, bShift, pScreen);
+}
+
+void CJS_Context::OnScreen_OutView(bool bModifier,
+                                   bool bShift,
+                                   CPDFSDK_Annot* pScreen) {
+  m_pEventHandler->OnScreen_OutView(bModifier, bShift, pScreen);
+}
+
+void CJS_Context::OnBookmark_MouseUp(CPDF_Bookmark* pBookMark) {
+  m_pEventHandler->OnBookmark_MouseUp(pBookMark);
+}
+
+void CJS_Context::OnLink_MouseUp(CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+  m_pEventHandler->OnLink_MouseUp(pFormFillEnv);
+}
+
+void CJS_Context::OnConsole_Exec() {
+  m_pEventHandler->OnConsole_Exec();
+}
+
+void CJS_Context::OnExternal_Exec() {
+  m_pEventHandler->OnExternal_Exec();
+}
+
+void CJS_Context::OnBatchExec(CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+  m_pEventHandler->OnBatchExec(pFormFillEnv);
+}
+
+void CJS_Context::OnMenu_Exec(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                              const CFX_WideString& strTargetName) {
+  m_pEventHandler->OnMenu_Exec(pFormFillEnv, strTargetName);
+}
diff --git a/fpdfsdk/javascript/cjs_context.h b/fpdfsdk/javascript/cjs_context.h
new file mode 100644
index 0000000..95a63ad
--- /dev/null
+++ b/fpdfsdk/javascript/cjs_context.h
@@ -0,0 +1,135 @@
+// 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_JAVASCRIPT_CJS_CONTEXT_H_
+#define FPDFSDK_JAVASCRIPT_CJS_CONTEXT_H_
+
+#include <memory>
+
+#include "core/fxcrt/fx_string.h"
+#include "core/fxcrt/fx_system.h"
+#include "fpdfsdk/javascript/ijs_context.h"
+
+class CJS_EventHandler;
+class CJS_Runtime;
+class CPDFSDK_FormFillEnvironment;
+
+class CJS_Context : public IJS_Context {
+ public:
+  explicit CJS_Context(CJS_Runtime* pRuntime);
+  ~CJS_Context() override;
+
+  // IJS_Context
+  bool RunScript(const CFX_WideString& script, CFX_WideString* info) override;
+  void OnApp_Init() override;
+  void OnDoc_Open(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                  const CFX_WideString& strTargetName) override;
+  void OnDoc_WillPrint(CPDFSDK_FormFillEnvironment* pFormFillEnv) override;
+  void OnDoc_DidPrint(CPDFSDK_FormFillEnvironment* pFormFillEnv) override;
+  void OnDoc_WillSave(CPDFSDK_FormFillEnvironment* pFormFillEnv) override;
+  void OnDoc_DidSave(CPDFSDK_FormFillEnvironment* pFormFillEnv) override;
+  void OnDoc_WillClose(CPDFSDK_FormFillEnvironment* pFormFillEnv) override;
+  void OnPage_Open(CPDFSDK_FormFillEnvironment* pFormFillEnv) override;
+  void OnPage_Close(CPDFSDK_FormFillEnvironment* pFormFillEnv) override;
+  void OnPage_InView(CPDFSDK_FormFillEnvironment* pFormFillEnv) override;
+  void OnPage_OutView(CPDFSDK_FormFillEnvironment* pFormFillEnv) override;
+  void OnField_MouseDown(bool bModifier,
+                         bool bShift,
+                         CPDF_FormField* pTarget) override;
+  void OnField_MouseEnter(bool bModifier,
+                          bool bShift,
+                          CPDF_FormField* pTarget) override;
+  void OnField_MouseExit(bool bModifier,
+                         bool bShift,
+                         CPDF_FormField* pTarget) override;
+  void OnField_MouseUp(bool bModifier,
+                       bool bShift,
+                       CPDF_FormField* pTarget) override;
+  void OnField_Focus(bool bModifier,
+                     bool bShift,
+                     CPDF_FormField* pTarget,
+                     const CFX_WideString& Value) override;
+  void OnField_Blur(bool bModifier,
+                    bool bShift,
+                    CPDF_FormField* pTarget,
+                    const CFX_WideString& Value) override;
+  void OnField_Calculate(CPDF_FormField* pSource,
+                         CPDF_FormField* pTarget,
+                         CFX_WideString& Value,
+                         bool& bRc) override;
+  void OnField_Format(CPDF_FormField* pTarget,
+                      CFX_WideString& Value,
+                      bool bWillCommit) override;
+  void OnField_Keystroke(CFX_WideString& strChange,
+                         const CFX_WideString& strChangeEx,
+                         bool bKeyDown,
+                         bool bModifier,
+                         int& nSelEnd,
+                         int& nSelStart,
+                         bool bShift,
+                         CPDF_FormField* pTarget,
+                         CFX_WideString& Value,
+                         bool bWillCommit,
+                         bool bFieldFull,
+                         bool& bRc) override;
+  void OnField_Validate(CFX_WideString& strChange,
+                        const CFX_WideString& strChangeEx,
+                        bool bKeyDown,
+                        bool bModifier,
+                        bool bShift,
+                        CPDF_FormField* pTarget,
+                        CFX_WideString& Value,
+                        bool& bRc) override;
+  void OnScreen_Focus(bool bModifier,
+                      bool bShift,
+                      CPDFSDK_Annot* pScreen) override;
+  void OnScreen_Blur(bool bModifier,
+                     bool bShift,
+                     CPDFSDK_Annot* pScreen) override;
+  void OnScreen_Open(bool bModifier,
+                     bool bShift,
+                     CPDFSDK_Annot* pScreen) override;
+  void OnScreen_Close(bool bModifier,
+                      bool bShift,
+                      CPDFSDK_Annot* pScreen) override;
+  void OnScreen_MouseDown(bool bModifier,
+                          bool bShift,
+                          CPDFSDK_Annot* pScreen) override;
+  void OnScreen_MouseUp(bool bModifier,
+                        bool bShift,
+                        CPDFSDK_Annot* pScreen) override;
+  void OnScreen_MouseEnter(bool bModifier,
+                           bool bShift,
+                           CPDFSDK_Annot* pScreen) override;
+  void OnScreen_MouseExit(bool bModifier,
+                          bool bShift,
+                          CPDFSDK_Annot* pScreen) override;
+  void OnScreen_InView(bool bModifier,
+                       bool bShift,
+                       CPDFSDK_Annot* pScreen) override;
+  void OnScreen_OutView(bool bModifier,
+                        bool bShift,
+                        CPDFSDK_Annot* pScreen) override;
+  void OnBookmark_MouseUp(CPDF_Bookmark* pBookMark) override;
+  void OnLink_MouseUp(CPDFSDK_FormFillEnvironment* pFormFillEnv) override;
+  void OnMenu_Exec(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                   const CFX_WideString& strTargetName) override;
+  void OnBatchExec(CPDFSDK_FormFillEnvironment* pFormFillEnv) override;
+  void OnConsole_Exec() override;
+  void OnExternal_Exec() override;
+
+  CJS_Runtime* GetJSRuntime() const { return m_pRuntime; }
+  CJS_EventHandler* GetEventHandler() const { return m_pEventHandler.get(); }
+
+  CPDFSDK_FormFillEnvironment* GetFormFillEnv();
+
+ private:
+  CJS_Runtime* const m_pRuntime;
+  std::unique_ptr<CJS_EventHandler> m_pEventHandler;
+  bool m_bBusy;
+};
+
+#endif  // FPDFSDK_JAVASCRIPT_CJS_CONTEXT_H_
diff --git a/fpdfsdk/javascript/cjs_runtime.cpp b/fpdfsdk/javascript/cjs_runtime.cpp
new file mode 100644
index 0000000..f55a59c
--- /dev/null
+++ b/fpdfsdk/javascript/cjs_runtime.cpp
@@ -0,0 +1,269 @@
+// 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
+
+#include "fpdfsdk/javascript/cjs_runtime.h"
+
+#include <algorithm>
+
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/javascript/Annot.h"
+#include "fpdfsdk/javascript/Consts.h"
+#include "fpdfsdk/javascript/Document.h"
+#include "fpdfsdk/javascript/Field.h"
+#include "fpdfsdk/javascript/Icon.h"
+#include "fpdfsdk/javascript/JS_Define.h"
+#include "fpdfsdk/javascript/JS_EventHandler.h"
+#include "fpdfsdk/javascript/JS_GlobalData.h"
+#include "fpdfsdk/javascript/JS_Object.h"
+#include "fpdfsdk/javascript/JS_Value.h"
+#include "fpdfsdk/javascript/PublicMethods.h"
+#include "fpdfsdk/javascript/app.h"
+#include "fpdfsdk/javascript/cjs_context.h"
+#include "fpdfsdk/javascript/color.h"
+#include "fpdfsdk/javascript/console.h"
+#include "fpdfsdk/javascript/event.h"
+#include "fpdfsdk/javascript/global.h"
+#include "fpdfsdk/javascript/report.h"
+#include "fpdfsdk/javascript/util.h"
+#include "public/fpdf_formfill.h"
+#include "third_party/base/stl_util.h"
+
+#ifdef PDF_ENABLE_XFA
+#include "fxjs/cfxjse_value.h"
+#endif  // PDF_ENABLE_XFA
+
+// static
+void IJS_Runtime::Initialize(unsigned int slot, void* isolate) {
+  FXJS_Initialize(slot, reinterpret_cast<v8::Isolate*>(isolate));
+}
+
+// static
+void IJS_Runtime::Destroy() {
+  FXJS_Release();
+}
+
+// static
+IJS_Runtime* IJS_Runtime::Create(CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+  return new CJS_Runtime(pFormFillEnv);
+}
+
+// static
+CJS_Runtime* CJS_Runtime::FromContext(const IJS_Context* cc) {
+  const CJS_Context* pContext = static_cast<const CJS_Context*>(cc);
+  return pContext->GetJSRuntime();
+}
+
+// static
+CJS_Runtime* CJS_Runtime::CurrentRuntimeFromIsolate(v8::Isolate* pIsolate) {
+  return static_cast<CJS_Runtime*>(
+      CFXJS_Engine::CurrentEngineFromIsolate(pIsolate));
+}
+
+CJS_Runtime::CJS_Runtime(CPDFSDK_FormFillEnvironment* pFormFillEnv)
+    : m_pFormFillEnv(pFormFillEnv),
+      m_bBlocking(false),
+      m_isolateManaged(false) {
+  v8::Isolate* pIsolate = nullptr;
+
+  IPDF_JSPLATFORM* pPlatform = m_pFormFillEnv->GetFormFillInfo()->m_pJsPlatform;
+  if (pPlatform->version <= 2) {
+    unsigned int embedderDataSlot = 0;
+    v8::Isolate* pExternalIsolate = nullptr;
+    if (pPlatform->version == 2) {
+      pExternalIsolate = reinterpret_cast<v8::Isolate*>(pPlatform->m_isolate);
+      embedderDataSlot = pPlatform->m_v8EmbedderSlot;
+    }
+    FXJS_Initialize(embedderDataSlot, pExternalIsolate);
+  }
+  m_isolateManaged = FXJS_GetIsolate(&pIsolate);
+  SetIsolate(pIsolate);
+
+#ifdef PDF_ENABLE_XFA
+  v8::Isolate::Scope isolate_scope(pIsolate);
+  v8::HandleScope handle_scope(pIsolate);
+#endif
+
+  if (m_isolateManaged || FXJS_GlobalIsolateRefCount() == 0)
+    DefineJSObjects();
+
+  CJS_Context* pContext = (CJS_Context*)NewContext();
+  InitializeEngine();
+  ReleaseContext(pContext);
+
+  SetFormFillEnvToDocument();
+}
+
+CJS_Runtime::~CJS_Runtime() {
+  NotifyObservedPtrs();
+  ReleaseEngine();
+  if (m_isolateManaged) {
+    GetIsolate()->Dispose();
+    SetIsolate(nullptr);
+  }
+}
+
+void CJS_Runtime::DefineJSObjects() {
+  v8::Isolate::Scope isolate_scope(GetIsolate());
+  v8::HandleScope handle_scope(GetIsolate());
+  v8::Local<v8::Context> context = v8::Context::New(GetIsolate());
+  v8::Context::Scope context_scope(context);
+
+  // The call order determines the "ObjDefID" assigned to each class.
+  // ObjDefIDs 0 - 2
+  CJS_Border::DefineJSObjects(this, FXJSOBJTYPE_STATIC);
+  CJS_Display::DefineJSObjects(this, FXJSOBJTYPE_STATIC);
+  CJS_Font::DefineJSObjects(this, FXJSOBJTYPE_STATIC);
+
+  // ObjDefIDs 3 - 5
+  CJS_Highlight::DefineJSObjects(this, FXJSOBJTYPE_STATIC);
+  CJS_Position::DefineJSObjects(this, FXJSOBJTYPE_STATIC);
+  CJS_ScaleHow::DefineJSObjects(this, FXJSOBJTYPE_STATIC);
+
+  // ObjDefIDs 6 - 8
+  CJS_ScaleWhen::DefineJSObjects(this, FXJSOBJTYPE_STATIC);
+  CJS_Style::DefineJSObjects(this, FXJSOBJTYPE_STATIC);
+  CJS_Zoomtype::DefineJSObjects(this, FXJSOBJTYPE_STATIC);
+
+  // ObjDefIDs 9 - 11
+  CJS_App::DefineJSObjects(this, FXJSOBJTYPE_STATIC);
+  CJS_Color::DefineJSObjects(this, FXJSOBJTYPE_STATIC);
+  CJS_Console::DefineJSObjects(this, FXJSOBJTYPE_STATIC);
+
+  // ObjDefIDs 12 - 14
+  CJS_Document::DefineJSObjects(this, FXJSOBJTYPE_GLOBAL);
+  CJS_Event::DefineJSObjects(this, FXJSOBJTYPE_STATIC);
+  CJS_Field::DefineJSObjects(this, FXJSOBJTYPE_DYNAMIC);
+
+  // ObjDefIDs 15 - 17
+  CJS_Global::DefineJSObjects(this, FXJSOBJTYPE_STATIC);
+  CJS_Icon::DefineJSObjects(this, FXJSOBJTYPE_DYNAMIC);
+  CJS_Util::DefineJSObjects(this, FXJSOBJTYPE_STATIC);
+
+  // ObjDefIDs 18 - 20 (these can't fail, return void).
+  CJS_PublicMethods::DefineJSObjects(this);
+  CJS_GlobalConsts::DefineJSObjects(this);
+  CJS_GlobalArrays::DefineJSObjects(this);
+
+  // ObjDefIDs 21 - 23.
+  CJS_TimerObj::DefineJSObjects(this, FXJSOBJTYPE_DYNAMIC);
+  CJS_PrintParamsObj::DefineJSObjects(this, FXJSOBJTYPE_DYNAMIC);
+  CJS_Annot::DefineJSObjects(this, FXJSOBJTYPE_DYNAMIC);
+}
+
+IJS_Context* CJS_Runtime::NewContext() {
+  m_ContextArray.push_back(std::unique_ptr<CJS_Context>(new CJS_Context(this)));
+  return m_ContextArray.back().get();
+}
+
+void CJS_Runtime::ReleaseContext(IJS_Context* pContext) {
+  for (auto it = m_ContextArray.begin(); it != m_ContextArray.end(); ++it) {
+    if (it->get() == static_cast<CJS_Context*>(pContext)) {
+      m_ContextArray.erase(it);
+      return;
+    }
+  }
+}
+
+IJS_Context* CJS_Runtime::GetCurrentContext() {
+  return m_ContextArray.empty() ? nullptr : m_ContextArray.back().get();
+}
+
+void CJS_Runtime::SetFormFillEnvToDocument() {
+  v8::Isolate::Scope isolate_scope(GetIsolate());
+  v8::HandleScope handle_scope(GetIsolate());
+  v8::Local<v8::Context> context = NewLocalContext();
+  v8::Context::Scope context_scope(context);
+
+  v8::Local<v8::Object> pThis = GetThisObj();
+  if (pThis.IsEmpty())
+    return;
+
+  if (CFXJS_Engine::GetObjDefnID(pThis) != CJS_Document::g_nObjDefnID)
+    return;
+
+  CJS_Document* pJSDocument =
+      static_cast<CJS_Document*>(GetObjectPrivate(pThis));
+  if (!pJSDocument)
+    return;
+
+  Document* pDocument = static_cast<Document*>(pJSDocument->GetEmbedObject());
+  if (!pDocument)
+    return;
+
+  pDocument->SetFormFillEnv(m_pFormFillEnv);
+}
+
+CPDFSDK_FormFillEnvironment* CJS_Runtime::GetFormFillEnv() const {
+  return m_pFormFillEnv;
+}
+
+int CJS_Runtime::ExecuteScript(const CFX_WideString& script,
+                               CFX_WideString* info) {
+  FXJSErr error = {};
+  int nRet = Execute(script, &error);
+  if (nRet < 0) {
+    info->Format(L"[ Line: %05d { %s } ] : %s", error.linnum - 1, error.srcline,
+                 error.message);
+  }
+  return nRet;
+}
+
+bool CJS_Runtime::AddEventToSet(const FieldEvent& event) {
+  return m_FieldEventSet.insert(event).second;
+}
+
+void CJS_Runtime::RemoveEventFromSet(const FieldEvent& event) {
+  m_FieldEventSet.erase(event);
+}
+
+#ifdef PDF_ENABLE_XFA
+CFX_WideString ChangeObjName(const CFX_WideString& str) {
+  CFX_WideString sRet = str;
+  sRet.Replace(L"_", L".");
+  return sRet;
+}
+bool CJS_Runtime::GetValueByName(const CFX_ByteStringC& utf8Name,
+                                 CFXJSE_Value* pValue) {
+  const FX_CHAR* name = utf8Name.c_str();
+
+  v8::Isolate::Scope isolate_scope(GetIsolate());
+  v8::HandleScope handle_scope(GetIsolate());
+  v8::Local<v8::Context> context = NewLocalContext();
+  v8::Context::Scope context_scope(context);
+
+  v8::Local<v8::Value> propvalue =
+      context->Global()->Get(v8::String::NewFromUtf8(
+          GetIsolate(), name, v8::String::kNormalString, utf8Name.GetLength()));
+
+  if (propvalue.IsEmpty()) {
+    pValue->SetUndefined();
+    return false;
+  }
+  pValue->ForceSetValue(propvalue);
+  return true;
+}
+bool CJS_Runtime::SetValueByName(const CFX_ByteStringC& utf8Name,
+                                 CFXJSE_Value* pValue) {
+  if (utf8Name.IsEmpty() || !pValue)
+    return false;
+  const FX_CHAR* name = utf8Name.c_str();
+  v8::Isolate* pIsolate = GetIsolate();
+  v8::Isolate::Scope isolate_scope(pIsolate);
+  v8::HandleScope handle_scope(pIsolate);
+  v8::Local<v8::Context> context = NewLocalContext();
+  v8::Context::Scope context_scope(context);
+
+  // v8::Local<v8::Context> tmpCotext =
+  // v8::Local<v8::Context>::New(GetIsolate(), m_context);
+  v8::Local<v8::Value> propvalue =
+      v8::Local<v8::Value>::New(GetIsolate(), pValue->DirectGetValue());
+  context->Global()->Set(
+      v8::String::NewFromUtf8(pIsolate, name, v8::String::kNormalString,
+                              utf8Name.GetLength()),
+      propvalue);
+  return true;
+}
+#endif
diff --git a/fpdfsdk/javascript/cjs_runtime.h b/fpdfsdk/javascript/cjs_runtime.h
new file mode 100644
index 0000000..66f0877
--- /dev/null
+++ b/fpdfsdk/javascript/cjs_runtime.h
@@ -0,0 +1,72 @@
+// 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_JAVASCRIPT_CJS_RUNTIME_H_
+#define FPDFSDK_JAVASCRIPT_CJS_RUNTIME_H_
+
+#include <map>
+#include <memory>
+#include <set>
+#include <utility>
+#include <vector>
+
+#include "core/fxcrt/cfx_observable.h"
+#include "core/fxcrt/fx_basic.h"
+#include "fpdfsdk/javascript/JS_EventHandler.h"
+#include "fpdfsdk/javascript/ijs_runtime.h"
+#include "fxjs/fxjs_v8.h"
+
+class CJS_Context;
+
+class CJS_Runtime : public IJS_Runtime,
+                    public CFXJS_Engine,
+                    public CFX_Observable<CJS_Runtime> {
+ public:
+  using FieldEvent = std::pair<CFX_WideString, JS_EVENT_T>;
+
+  static CJS_Runtime* FromContext(const IJS_Context* cc);
+  static CJS_Runtime* CurrentRuntimeFromIsolate(v8::Isolate* pIsolate);
+
+  explicit CJS_Runtime(CPDFSDK_FormFillEnvironment* pFormFillEnv);
+  ~CJS_Runtime() override;
+
+  // IJS_Runtime
+  IJS_Context* NewContext() override;
+  void ReleaseContext(IJS_Context* pContext) override;
+  IJS_Context* GetCurrentContext() override;
+
+  CPDFSDK_FormFillEnvironment* GetFormFillEnv() const override;
+
+  int ExecuteScript(const CFX_WideString& script,
+                    CFX_WideString* info) override;
+
+  // Returns true if the event isn't already found in the set.
+  bool AddEventToSet(const FieldEvent& event);
+  void RemoveEventFromSet(const FieldEvent& event);
+
+  void BeginBlock() { m_bBlocking = true; }
+  void EndBlock() { m_bBlocking = false; }
+  bool IsBlocking() const { return m_bBlocking; }
+
+#ifdef PDF_ENABLE_XFA
+  bool GetValueByName(const CFX_ByteStringC& utf8Name,
+                      CFXJSE_Value* pValue) override;
+  bool SetValueByName(const CFX_ByteStringC& utf8Name,
+                      CFXJSE_Value* pValue) override;
+#endif  // PDF_ENABLE_XFA
+
+ private:
+  void DefineJSObjects();
+  void SetFormFillEnvToDocument();
+
+  std::vector<std::unique_ptr<CJS_Context>> m_ContextArray;
+  CPDFSDK_FormFillEnvironment* const m_pFormFillEnv;
+  bool m_bBlocking;
+  bool m_isolateManaged;
+  std::set<FieldEvent> m_FieldEventSet;
+};
+
+#endif  // FPDFSDK_JAVASCRIPT_CJS_RUNTIME_H_
diff --git a/fpdfsdk/javascript/color.cpp b/fpdfsdk/javascript/color.cpp
new file mode 100644
index 0000000..882a903
--- /dev/null
+++ b/fpdfsdk/javascript/color.cpp
@@ -0,0 +1,225 @@
+// 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
+
+#include "fpdfsdk/javascript/color.h"
+
+#include <vector>
+
+#include "fpdfsdk/javascript/JS_Define.h"
+#include "fpdfsdk/javascript/JS_EventHandler.h"
+#include "fpdfsdk/javascript/JS_Object.h"
+#include "fpdfsdk/javascript/JS_Value.h"
+#include "fpdfsdk/javascript/cjs_context.h"
+#include "fpdfsdk/javascript/cjs_runtime.h"
+
+BEGIN_JS_STATIC_CONST(CJS_Color)
+END_JS_STATIC_CONST()
+
+BEGIN_JS_STATIC_PROP(CJS_Color)
+JS_STATIC_PROP_ENTRY(black)
+JS_STATIC_PROP_ENTRY(blue)
+JS_STATIC_PROP_ENTRY(cyan)
+JS_STATIC_PROP_ENTRY(dkGray)
+JS_STATIC_PROP_ENTRY(gray)
+JS_STATIC_PROP_ENTRY(green)
+JS_STATIC_PROP_ENTRY(ltGray)
+JS_STATIC_PROP_ENTRY(magenta)
+JS_STATIC_PROP_ENTRY(red)
+JS_STATIC_PROP_ENTRY(transparent)
+JS_STATIC_PROP_ENTRY(white)
+JS_STATIC_PROP_ENTRY(yellow)
+END_JS_STATIC_PROP()
+
+BEGIN_JS_STATIC_METHOD(CJS_Color)
+JS_STATIC_METHOD_ENTRY(convert)
+JS_STATIC_METHOD_ENTRY(equal)
+END_JS_STATIC_METHOD()
+
+IMPLEMENT_JS_CLASS(CJS_Color, color)
+
+color::color(CJS_Object* pJSObject) : CJS_EmbedObj(pJSObject) {
+  m_crTransparent = CPWL_Color(COLORTYPE_TRANSPARENT);
+  m_crBlack = CPWL_Color(COLORTYPE_GRAY, 0);
+  m_crWhite = CPWL_Color(COLORTYPE_GRAY, 1);
+  m_crRed = CPWL_Color(COLORTYPE_RGB, 1, 0, 0);
+  m_crGreen = CPWL_Color(COLORTYPE_RGB, 0, 1, 0);
+  m_crBlue = CPWL_Color(COLORTYPE_RGB, 0, 0, 1);
+  m_crCyan = CPWL_Color(COLORTYPE_CMYK, 1, 0, 0, 0);
+  m_crMagenta = CPWL_Color(COLORTYPE_CMYK, 0, 1, 0, 0);
+  m_crYellow = CPWL_Color(COLORTYPE_CMYK, 0, 0, 1, 0);
+  m_crDKGray = CPWL_Color(COLORTYPE_GRAY, 0.25);
+  m_crGray = CPWL_Color(COLORTYPE_GRAY, 0.5);
+  m_crLTGray = CPWL_Color(COLORTYPE_GRAY, 0.75);
+}
+
+color::~color() {}
+
+void color::ConvertPWLColorToArray(CJS_Runtime* pRuntime,
+                                   const CPWL_Color& color,
+                                   CJS_Array* array) {
+  switch (color.nColorType) {
+    case COLORTYPE_TRANSPARENT:
+      array->SetElement(pRuntime, 0, CJS_Value(pRuntime, "T"));
+      break;
+    case COLORTYPE_GRAY:
+      array->SetElement(pRuntime, 0, CJS_Value(pRuntime, "G"));
+      array->SetElement(pRuntime, 1, CJS_Value(pRuntime, color.fColor1));
+      break;
+    case COLORTYPE_RGB:
+      array->SetElement(pRuntime, 0, CJS_Value(pRuntime, "RGB"));
+      array->SetElement(pRuntime, 1, CJS_Value(pRuntime, color.fColor1));
+      array->SetElement(pRuntime, 2, CJS_Value(pRuntime, color.fColor2));
+      array->SetElement(pRuntime, 3, CJS_Value(pRuntime, color.fColor3));
+      break;
+    case COLORTYPE_CMYK:
+      array->SetElement(pRuntime, 0, CJS_Value(pRuntime, "CMYK"));
+      array->SetElement(pRuntime, 1, CJS_Value(pRuntime, color.fColor1));
+      array->SetElement(pRuntime, 2, CJS_Value(pRuntime, color.fColor2));
+      array->SetElement(pRuntime, 3, CJS_Value(pRuntime, color.fColor3));
+      array->SetElement(pRuntime, 4, CJS_Value(pRuntime, color.fColor4));
+      break;
+  }
+}
+
+void color::ConvertArrayToPWLColor(CJS_Runtime* pRuntime,
+                                   const CJS_Array& array,
+                                   CPWL_Color* color) {
+  int nArrayLen = array.GetLength(pRuntime);
+  if (nArrayLen < 1)
+    return;
+
+  CJS_Value value(pRuntime);
+  array.GetElement(pRuntime, 0, value);
+  CFX_ByteString sSpace = value.ToCFXByteString(pRuntime);
+
+  double d1 = 0;
+  double d2 = 0;
+  double d3 = 0;
+  double d4 = 0;
+
+  if (nArrayLen > 1) {
+    array.GetElement(pRuntime, 1, value);
+    d1 = value.ToDouble(pRuntime);
+  }
+
+  if (nArrayLen > 2) {
+    array.GetElement(pRuntime, 2, value);
+    d2 = value.ToDouble(pRuntime);
+  }
+
+  if (nArrayLen > 3) {
+    array.GetElement(pRuntime, 3, value);
+    d3 = value.ToDouble(pRuntime);
+  }
+
+  if (nArrayLen > 4) {
+    array.GetElement(pRuntime, 4, value);
+    d4 = value.ToDouble(pRuntime);
+  }
+
+  if (sSpace == "T") {
+    *color = CPWL_Color(COLORTYPE_TRANSPARENT);
+  } else if (sSpace == "G") {
+    *color = CPWL_Color(COLORTYPE_GRAY, (FX_FLOAT)d1);
+  } else if (sSpace == "RGB") {
+    *color =
+        CPWL_Color(COLORTYPE_RGB, (FX_FLOAT)d1, (FX_FLOAT)d2, (FX_FLOAT)d3);
+  } else if (sSpace == "CMYK") {
+    *color = CPWL_Color(COLORTYPE_CMYK, (FX_FLOAT)d1, (FX_FLOAT)d2,
+                        (FX_FLOAT)d3, (FX_FLOAT)d4);
+  }
+}
+
+#define JS_IMPLEMENT_COLORPROP(prop, var)                    \
+  bool color::prop(IJS_Context* cc, CJS_PropValue& vp,       \
+                   CFX_WideString& sError) {                 \
+    CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);    \
+    CJS_Array array;                                         \
+    if (vp.IsGetting()) {                                    \
+      ConvertPWLColorToArray(pRuntime, var, &array);         \
+      vp << array;                                           \
+    } else {                                                 \
+      if (!vp.GetJSValue()->ConvertToArray(pRuntime, array)) \
+        return false;                                        \
+      ConvertArrayToPWLColor(pRuntime, array, &var);         \
+    }                                                        \
+    return true;                                             \
+  }
+
+JS_IMPLEMENT_COLORPROP(transparent, m_crTransparent)
+JS_IMPLEMENT_COLORPROP(black, m_crBlack)
+JS_IMPLEMENT_COLORPROP(white, m_crWhite)
+JS_IMPLEMENT_COLORPROP(red, m_crRed)
+JS_IMPLEMENT_COLORPROP(green, m_crGreen)
+JS_IMPLEMENT_COLORPROP(blue, m_crBlue)
+JS_IMPLEMENT_COLORPROP(cyan, m_crCyan)
+JS_IMPLEMENT_COLORPROP(magenta, m_crMagenta)
+JS_IMPLEMENT_COLORPROP(yellow, m_crYellow)
+JS_IMPLEMENT_COLORPROP(dkGray, m_crDKGray)
+JS_IMPLEMENT_COLORPROP(gray, m_crGray)
+JS_IMPLEMENT_COLORPROP(ltGray, m_crLTGray)
+
+bool color::convert(IJS_Context* cc,
+                    const std::vector<CJS_Value>& params,
+                    CJS_Value& vRet,
+                    CFX_WideString& sError) {
+  int iSize = params.size();
+  if (iSize < 2)
+    return false;
+
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  CJS_Array aSource;
+  if (!params[0].ConvertToArray(pRuntime, aSource))
+    return false;
+
+  CPWL_Color crSource;
+  ConvertArrayToPWLColor(pRuntime, aSource, &crSource);
+
+  CFX_ByteString sDestSpace = params[1].ToCFXByteString(pRuntime);
+  int nColorType = COLORTYPE_TRANSPARENT;
+
+  if (sDestSpace == "T") {
+    nColorType = COLORTYPE_TRANSPARENT;
+  } else if (sDestSpace == "G") {
+    nColorType = COLORTYPE_GRAY;
+  } else if (sDestSpace == "RGB") {
+    nColorType = COLORTYPE_RGB;
+  } else if (sDestSpace == "CMYK") {
+    nColorType = COLORTYPE_CMYK;
+  }
+
+  CJS_Array aDest;
+  CPWL_Color crDest = crSource;
+  crDest.ConvertColorType(nColorType);
+  ConvertPWLColorToArray(pRuntime, crDest, &aDest);
+  vRet = CJS_Value(pRuntime, aDest);
+
+  return true;
+}
+
+bool color::equal(IJS_Context* cc,
+                  const std::vector<CJS_Value>& params,
+                  CJS_Value& vRet,
+                  CFX_WideString& sError) {
+  if (params.size() < 2)
+    return false;
+
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  CJS_Array array1;
+  CJS_Array array2;
+  if (!params[0].ConvertToArray(pRuntime, array1))
+    return false;
+  if (!params[1].ConvertToArray(pRuntime, array2))
+    return false;
+
+  CPWL_Color color1;
+  CPWL_Color color2;
+  ConvertArrayToPWLColor(pRuntime, array1, &color1);
+  ConvertArrayToPWLColor(pRuntime, array2, &color2);
+  color1.ConvertColorType(color2.nColorType);
+  vRet = CJS_Value(pRuntime, color1 == color2);
+  return true;
+}
diff --git a/fpdfsdk/javascript/color.h b/fpdfsdk/javascript/color.h
new file mode 100644
index 0000000..9ea4d63
--- /dev/null
+++ b/fpdfsdk/javascript/color.h
@@ -0,0 +1,88 @@
+// 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_JAVASCRIPT_COLOR_H_
+#define FPDFSDK_JAVASCRIPT_COLOR_H_
+
+#include <vector>
+
+#include "fpdfsdk/javascript/JS_Define.h"
+#include "fpdfsdk/pdfwindow/PWL_Wnd.h"
+
+class color : public CJS_EmbedObj {
+ public:
+  explicit color(CJS_Object* pJSObject);
+  ~color() override;
+
+  bool black(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool blue(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool cyan(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool dkGray(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool gray(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool green(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool ltGray(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool magenta(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool red(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool transparent(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool white(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool yellow(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+
+  bool convert(IJS_Context* cc,
+               const std::vector<CJS_Value>& params,
+               CJS_Value& vRet,
+               CFX_WideString& sError);
+  bool equal(IJS_Context* cc,
+             const std::vector<CJS_Value>& params,
+             CJS_Value& vRet,
+             CFX_WideString& sError);
+
+  static void ConvertPWLColorToArray(CJS_Runtime* pRuntime,
+                                     const CPWL_Color& color,
+                                     CJS_Array* array);
+  static void ConvertArrayToPWLColor(CJS_Runtime* pRuntime,
+                                     const CJS_Array& array,
+                                     CPWL_Color* color);
+
+ private:
+  CPWL_Color m_crTransparent;
+  CPWL_Color m_crBlack;
+  CPWL_Color m_crWhite;
+  CPWL_Color m_crRed;
+  CPWL_Color m_crGreen;
+  CPWL_Color m_crBlue;
+  CPWL_Color m_crCyan;
+  CPWL_Color m_crMagenta;
+  CPWL_Color m_crYellow;
+  CPWL_Color m_crDKGray;
+  CPWL_Color m_crGray;
+  CPWL_Color m_crLTGray;
+};
+
+class CJS_Color : public CJS_Object {
+ public:
+  explicit CJS_Color(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_Color() override {}
+
+  DECLARE_JS_CLASS();
+
+  JS_STATIC_PROP(black, color);
+  JS_STATIC_PROP(blue, color);
+  JS_STATIC_PROP(cyan, color);
+  JS_STATIC_PROP(dkGray, color);
+  JS_STATIC_PROP(gray, color);
+  JS_STATIC_PROP(green, color);
+  JS_STATIC_PROP(ltGray, color);
+  JS_STATIC_PROP(magenta, color);
+  JS_STATIC_PROP(red, color);
+  JS_STATIC_PROP(transparent, color);
+  JS_STATIC_PROP(white, color);
+  JS_STATIC_PROP(yellow, color);
+
+  JS_STATIC_METHOD(convert, color);
+  JS_STATIC_METHOD(equal, color);
+};
+
+#endif  // FPDFSDK_JAVASCRIPT_COLOR_H_
diff --git a/fpdfsdk/javascript/console.cpp b/fpdfsdk/javascript/console.cpp
new file mode 100644
index 0000000..0a8c1e0
--- /dev/null
+++ b/fpdfsdk/javascript/console.cpp
@@ -0,0 +1,65 @@
+// 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
+
+#include "fpdfsdk/javascript/console.h"
+
+#include <vector>
+
+#include "fpdfsdk/javascript/JS_Define.h"
+#include "fpdfsdk/javascript/JS_EventHandler.h"
+#include "fpdfsdk/javascript/JS_Object.h"
+#include "fpdfsdk/javascript/JS_Value.h"
+#include "fpdfsdk/javascript/cjs_context.h"
+
+BEGIN_JS_STATIC_CONST(CJS_Console)
+END_JS_STATIC_CONST()
+
+BEGIN_JS_STATIC_PROP(CJS_Console)
+END_JS_STATIC_PROP()
+
+BEGIN_JS_STATIC_METHOD(CJS_Console)
+JS_STATIC_METHOD_ENTRY(clear)
+JS_STATIC_METHOD_ENTRY(hide)
+JS_STATIC_METHOD_ENTRY(println)
+JS_STATIC_METHOD_ENTRY(show)
+END_JS_STATIC_METHOD()
+
+IMPLEMENT_JS_CLASS(CJS_Console, console)
+
+console::console(CJS_Object* pJSObject) : CJS_EmbedObj(pJSObject) {}
+
+console::~console() {}
+
+bool console::clear(IJS_Context* cc,
+                    const std::vector<CJS_Value>& params,
+                    CJS_Value& vRet,
+                    CFX_WideString& sError) {
+  return true;
+}
+
+bool console::hide(IJS_Context* cc,
+                   const std::vector<CJS_Value>& params,
+                   CJS_Value& vRet,
+                   CFX_WideString& sError) {
+  return true;
+}
+
+bool console::println(IJS_Context* cc,
+                      const std::vector<CJS_Value>& params,
+                      CJS_Value& vRet,
+                      CFX_WideString& sError) {
+  if (params.size() < 1) {
+    return false;
+  }
+  return true;
+}
+
+bool console::show(IJS_Context* cc,
+                   const std::vector<CJS_Value>& params,
+                   CJS_Value& vRet,
+                   CFX_WideString& sError) {
+  return true;
+}
diff --git a/fpdfsdk/javascript/console.h b/fpdfsdk/javascript/console.h
new file mode 100644
index 0000000..069a81d
--- /dev/null
+++ b/fpdfsdk/javascript/console.h
@@ -0,0 +1,51 @@
+// 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_JAVASCRIPT_CONSOLE_H_
+#define FPDFSDK_JAVASCRIPT_CONSOLE_H_
+
+#include <vector>
+
+#include "fpdfsdk/javascript/JS_Define.h"
+
+class console : public CJS_EmbedObj {
+ public:
+  explicit console(CJS_Object* pJSObject);
+  ~console() override;
+
+ public:
+  bool clear(IJS_Context* cc,
+             const std::vector<CJS_Value>& params,
+             CJS_Value& vRet,
+             CFX_WideString& sError);
+  bool hide(IJS_Context* cc,
+            const std::vector<CJS_Value>& params,
+            CJS_Value& vRet,
+            CFX_WideString& sError);
+  bool println(IJS_Context* cc,
+               const std::vector<CJS_Value>& params,
+               CJS_Value& vRet,
+               CFX_WideString& sError);
+  bool show(IJS_Context* cc,
+            const std::vector<CJS_Value>& params,
+            CJS_Value& vRet,
+            CFX_WideString& sError);
+};
+
+class CJS_Console : public CJS_Object {
+ public:
+  explicit CJS_Console(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_Console() override {}
+
+  DECLARE_JS_CLASS();
+
+  JS_STATIC_METHOD(clear, console);
+  JS_STATIC_METHOD(hide, console);
+  JS_STATIC_METHOD(println, console);
+  JS_STATIC_METHOD(show, console);
+};
+
+#endif  // FPDFSDK_JAVASCRIPT_CONSOLE_H_
diff --git a/fpdfsdk/src/javascript/event.cpp b/fpdfsdk/javascript/event.cpp
similarity index 62%
rename from fpdfsdk/src/javascript/event.cpp
rename to fpdfsdk/javascript/event.cpp
index 2362c01..b4fb951 100644
--- a/fpdfsdk/src/javascript/event.cpp
+++ b/fpdfsdk/javascript/event.cpp
@@ -4,17 +4,14 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#include "event.h"
+#include "fpdfsdk/javascript/event.h"
 
-#include "Field.h"
-#include "JS_Context.h"
-#include "JS_Define.h"
-#include "JS_EventHandler.h"
-#include "JS_Object.h"
-#include "JS_Value.h"
-#include "fpdfsdk/include/javascript/IJavaScript.h"
-
-/* -------------------------- event -------------------------- */
+#include "fpdfsdk/javascript/Field.h"
+#include "fpdfsdk/javascript/JS_Define.h"
+#include "fpdfsdk/javascript/JS_EventHandler.h"
+#include "fpdfsdk/javascript/JS_Object.h"
+#include "fpdfsdk/javascript/JS_Value.h"
+#include "fpdfsdk/javascript/cjs_context.h"
 
 BEGIN_JS_STATIC_CONST(CJS_Event)
 END_JS_STATIC_CONST()
@@ -49,166 +46,144 @@
 
 event::event(CJS_Object* pJsObject) : CJS_EmbedObj(pJsObject) {}
 
-event::~event() {
-}
+event::~event() {}
 
-FX_BOOL event::change(IJS_Context* cc,
-                      CJS_PropValue& vp,
-                      CFX_WideString& sError) {
+bool event::change(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
   CJS_Context* pContext = (CJS_Context*)cc;
   CJS_EventHandler* pEvent = pContext->GetEventHandler();
   CFX_WideString& wChange = pEvent->Change();
   if (vp.IsSetting()) {
-    if (vp.GetType() == CJS_Value::VT_string)
+    if (vp.GetJSValue()->GetType() == CJS_Value::VT_string)
       vp >> wChange;
   } else {
     vp << wChange;
   }
-  return TRUE;
+  return true;
 }
 
-FX_BOOL event::changeEx(IJS_Context* cc,
-                        CJS_PropValue& vp,
-                        CFX_WideString& sError) {
+bool event::changeEx(IJS_Context* cc,
+                     CJS_PropValue& vp,
+                     CFX_WideString& sError) {
   if (!vp.IsGetting())
-    return FALSE;
+    return false;
 
   CJS_Context* pContext = (CJS_Context*)cc;
   CJS_EventHandler* pEvent = pContext->GetEventHandler();
 
   vp << pEvent->ChangeEx();
-  return TRUE;
+  return true;
 }
 
-FX_BOOL event::commitKey(IJS_Context* cc,
-                         CJS_PropValue& vp,
-                         CFX_WideString& sError) {
+bool event::commitKey(IJS_Context* cc,
+                      CJS_PropValue& vp,
+                      CFX_WideString& sError) {
   if (!vp.IsGetting())
-    return FALSE;
+    return false;
 
   CJS_Context* pContext = (CJS_Context*)cc;
   CJS_EventHandler* pEvent = pContext->GetEventHandler();
 
   vp << pEvent->CommitKey();
-  return TRUE;
+  return true;
 }
 
-FX_BOOL event::fieldFull(IJS_Context* cc,
-                         CJS_PropValue& vp,
-                         CFX_WideString& sError) {
-  CJS_Context* pContext = (CJS_Context*)cc;
-  CJS_EventHandler* pEvent = pContext->GetEventHandler();
-
-  if (!vp.IsGetting() &&
-      wcscmp((const wchar_t*)pEvent->Name(), L"Keystroke") != 0)
-    return FALSE;
-
-  if (pEvent->FieldFull())
-    vp << TRUE;
-  else
-    vp << FALSE;
-  return TRUE;
-}
-
-FX_BOOL event::keyDown(IJS_Context* cc,
-                       CJS_PropValue& vp,
-                       CFX_WideString& sError) {
-  if (!vp.IsGetting())
-    return FALSE;
-
-  CJS_Context* pContext = (CJS_Context*)cc;
-  CJS_EventHandler* pEvent = pContext->GetEventHandler();
-
-  if (pEvent->KeyDown())
-    vp << TRUE;
-  else
-    vp << FALSE;
-  return TRUE;
-}
-
-FX_BOOL event::modifier(IJS_Context* cc,
-                        CJS_PropValue& vp,
-                        CFX_WideString& sError) {
-  if (!vp.IsGetting())
-    return FALSE;
-
-  CJS_Context* pContext = (CJS_Context*)cc;
-  CJS_EventHandler* pEvent = pContext->GetEventHandler();
-
-  if (pEvent->Modifier())
-    vp << TRUE;
-  else
-    vp << FALSE;
-  return TRUE;
-}
-
-FX_BOOL event::name(IJS_Context* cc,
-                    CJS_PropValue& vp,
-                    CFX_WideString& sError) {
-  if (!vp.IsGetting())
-    return FALSE;
-
-  CJS_Context* pContext = (CJS_Context*)cc;
-  CJS_EventHandler* pEvent = pContext->GetEventHandler();
-
-  vp << pEvent->Name();
-  return TRUE;
-}
-
-FX_BOOL event::rc(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
-  CJS_Context* pContext = (CJS_Context*)cc;
-  CJS_EventHandler* pEvent = pContext->GetEventHandler();
-
-  FX_BOOL& bRc = pEvent->Rc();
-  if (vp.IsSetting()) {
-    vp >> bRc;
-  } else {
-    vp << bRc;
-  }
-  return TRUE;
-}
-
-FX_BOOL event::richChange(IJS_Context* cc,
-                          CJS_PropValue& vp,
-                          CFX_WideString& sError) {
-  return TRUE;
-  if (vp.IsSetting()) {
-  } else {
-    ;
-  }
-  return TRUE;
-}
-
-FX_BOOL event::richChangeEx(IJS_Context* cc,
-                            CJS_PropValue& vp,
-                            CFX_WideString& sError) {
-  return TRUE;
-  if (vp.IsSetting()) {
-  } else {
-    ;
-  }
-  return TRUE;
-}
-
-FX_BOOL event::richValue(IJS_Context* cc,
-                         CJS_PropValue& vp,
-                         CFX_WideString& sError) {
-  return TRUE;
-  if (vp.IsSetting()) {
-  } else {
-    ;
-  }
-  return TRUE;
-}
-
-FX_BOOL event::selEnd(IJS_Context* cc,
+bool event::fieldFull(IJS_Context* cc,
                       CJS_PropValue& vp,
                       CFX_WideString& sError) {
   CJS_Context* pContext = (CJS_Context*)cc;
   CJS_EventHandler* pEvent = pContext->GetEventHandler();
 
+  if (!vp.IsGetting() &&
+      wcscmp((const wchar_t*)pEvent->Name(), L"Keystroke") != 0)
+    return false;
+
+  if (pEvent->FieldFull())
+    vp << true;
+  else
+    vp << false;
+  return true;
+}
+
+bool event::keyDown(IJS_Context* cc,
+                    CJS_PropValue& vp,
+                    CFX_WideString& sError) {
+  if (!vp.IsGetting())
+    return false;
+
+  CJS_Context* pContext = (CJS_Context*)cc;
+  CJS_EventHandler* pEvent = pContext->GetEventHandler();
+
+  if (pEvent->KeyDown())
+    vp << true;
+  else
+    vp << false;
+  return true;
+}
+
+bool event::modifier(IJS_Context* cc,
+                     CJS_PropValue& vp,
+                     CFX_WideString& sError) {
+  if (!vp.IsGetting())
+    return false;
+
+  CJS_Context* pContext = (CJS_Context*)cc;
+  CJS_EventHandler* pEvent = pContext->GetEventHandler();
+
+  if (pEvent->Modifier())
+    vp << true;
+  else
+    vp << false;
+  return true;
+}
+
+bool event::name(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
+  if (!vp.IsGetting())
+    return false;
+
+  CJS_Context* pContext = (CJS_Context*)cc;
+  CJS_EventHandler* pEvent = pContext->GetEventHandler();
+
+  vp << pEvent->Name();
+  return true;
+}
+
+bool event::rc(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
+  CJS_Context* pContext = (CJS_Context*)cc;
+  CJS_EventHandler* pEvent = pContext->GetEventHandler();
+
+  bool& bRc = pEvent->Rc();
+  if (vp.IsSetting()) {
+    vp >> bRc;
+  } else {
+    vp << bRc;
+  }
+  return true;
+}
+
+bool event::richChange(IJS_Context* cc,
+                       CJS_PropValue& vp,
+                       CFX_WideString& sError) {
+  return true;
+}
+
+bool event::richChangeEx(IJS_Context* cc,
+                         CJS_PropValue& vp,
+                         CFX_WideString& sError) {
+  return true;
+}
+
+bool event::richValue(IJS_Context* cc,
+                      CJS_PropValue& vp,
+                      CFX_WideString& sError) {
+  return true;
+}
+
+bool event::selEnd(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
+  CJS_Context* pContext = (CJS_Context*)cc;
+  CJS_EventHandler* pEvent = pContext->GetEventHandler();
+
   if (wcscmp((const wchar_t*)pEvent->Name(), L"Keystroke") != 0) {
-    return TRUE;
+    return true;
   }
 
   int& iSelEnd = pEvent->SelEnd();
@@ -217,17 +192,17 @@
   } else {
     vp << iSelEnd;
   }
-  return TRUE;
+  return true;
 }
 
-FX_BOOL event::selStart(IJS_Context* cc,
-                        CJS_PropValue& vp,
-                        CFX_WideString& sError) {
+bool event::selStart(IJS_Context* cc,
+                     CJS_PropValue& vp,
+                     CFX_WideString& sError) {
   CJS_Context* pContext = (CJS_Context*)cc;
   CJS_EventHandler* pEvent = pContext->GetEventHandler();
 
   if (wcscmp((const wchar_t*)pEvent->Name(), L"Keystroke") != 0) {
-    return TRUE;
+    return true;
   }
   int& iSelStart = pEvent->SelStart();
   if (vp.IsSetting()) {
@@ -235,108 +210,98 @@
   } else {
     vp << iSelStart;
   }
-  return TRUE;
+  return true;
 }
 
-FX_BOOL event::shift(IJS_Context* cc,
-                     CJS_PropValue& vp,
-                     CFX_WideString& sError) {
+bool event::shift(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
   if (!vp.IsGetting())
-    return FALSE;
+    return false;
 
   CJS_Context* pContext = (CJS_Context*)cc;
   CJS_EventHandler* pEvent = pContext->GetEventHandler();
 
   if (pEvent->Shift())
-    vp << TRUE;
+    vp << true;
   else
-    vp << FALSE;
-  return TRUE;
+    vp << false;
+  return true;
 }
 
-FX_BOOL event::source(IJS_Context* cc,
-                      CJS_PropValue& vp,
-                      CFX_WideString& sError) {
+bool event::source(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
   if (!vp.IsGetting())
-    return FALSE;
+    return false;
 
   CJS_Context* pContext = (CJS_Context*)cc;
   CJS_EventHandler* pEvent = pContext->GetEventHandler();
 
   vp << pEvent->Source()->GetJSObject();
-  return TRUE;
+  return true;
 }
 
-FX_BOOL event::target(IJS_Context* cc,
-                      CJS_PropValue& vp,
-                      CFX_WideString& sError) {
+bool event::target(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
   if (!vp.IsGetting())
-    return FALSE;
+    return false;
 
   CJS_Context* pContext = (CJS_Context*)cc;
   CJS_EventHandler* pEvent = pContext->GetEventHandler();
 
   vp << pEvent->Target_Field()->GetJSObject();
-  return TRUE;
+  return true;
 }
 
-FX_BOOL event::targetName(IJS_Context* cc,
-                          CJS_PropValue& vp,
-                          CFX_WideString& sError) {
+bool event::targetName(IJS_Context* cc,
+                       CJS_PropValue& vp,
+                       CFX_WideString& sError) {
   if (!vp.IsGetting())
-    return FALSE;
+    return false;
 
   CJS_Context* pContext = (CJS_Context*)cc;
   CJS_EventHandler* pEvent = pContext->GetEventHandler();
 
   vp << pEvent->TargetName();
-  return TRUE;
+  return true;
 }
 
-FX_BOOL event::type(IJS_Context* cc,
-                    CJS_PropValue& vp,
-                    CFX_WideString& sError) {
+bool event::type(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
   if (!vp.IsGetting())
-    return FALSE;
+    return false;
 
   CJS_Context* pContext = (CJS_Context*)cc;
   CJS_EventHandler* pEvent = pContext->GetEventHandler();
 
   vp << pEvent->Type();
-  return TRUE;
+  return true;
 }
 
-FX_BOOL event::value(IJS_Context* cc,
-                     CJS_PropValue& vp,
-                     CFX_WideString& sError) {
+bool event::value(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
   CJS_Context* pContext = (CJS_Context*)cc;
   CJS_EventHandler* pEvent = pContext->GetEventHandler();
 
   if (wcscmp((const wchar_t*)pEvent->Type(), L"Field") != 0)
-    return FALSE;
+    return false;
   if (!pEvent->m_pValue)
-    return FALSE;
+    return false;
   CFX_WideString& val = pEvent->Value();
   if (vp.IsSetting()) {
     vp >> val;
   } else {
     vp << val;
   }
-  return TRUE;
+  return true;
 }
 
-FX_BOOL event::willCommit(IJS_Context* cc,
-                          CJS_PropValue& vp,
-                          CFX_WideString& sError) {
+bool event::willCommit(IJS_Context* cc,
+                       CJS_PropValue& vp,
+                       CFX_WideString& sError) {
   if (!vp.IsGetting())
-    return FALSE;
+    return false;
 
   CJS_Context* pContext = (CJS_Context*)cc;
   CJS_EventHandler* pEvent = pContext->GetEventHandler();
 
   if (pEvent->WillCommit())
-    vp << TRUE;
+    vp << true;
   else
-    vp << FALSE;
-  return TRUE;
+    vp << false;
+  return true;
 }
diff --git a/fpdfsdk/javascript/event.h b/fpdfsdk/javascript/event.h
new file mode 100644
index 0000000..6719494
--- /dev/null
+++ b/fpdfsdk/javascript/event.h
@@ -0,0 +1,68 @@
+// 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_JAVASCRIPT_EVENT_H_
+#define FPDFSDK_JAVASCRIPT_EVENT_H_
+
+#include "fpdfsdk/javascript/JS_Define.h"
+
+class event : public CJS_EmbedObj {
+ public:
+  explicit event(CJS_Object* pJSObject);
+  ~event() override;
+
+ public:
+  bool change(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool changeEx(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool commitKey(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool fieldFull(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool keyDown(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool modifier(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool name(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool rc(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool richChange(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool richChangeEx(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool richValue(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool selEnd(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool selStart(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool shift(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool source(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool target(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool targetName(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool type(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool value(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  bool willCommit(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+};
+
+class CJS_Event : public CJS_Object {
+ public:
+  explicit CJS_Event(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_Event() override {}
+
+  DECLARE_JS_CLASS();
+  JS_STATIC_PROP(change, event);
+  JS_STATIC_PROP(changeEx, event);
+  JS_STATIC_PROP(commitKey, event);
+  JS_STATIC_PROP(fieldFull, event);
+  JS_STATIC_PROP(keyDown, event);
+  JS_STATIC_PROP(modifier, event);
+  JS_STATIC_PROP(name, event);
+  JS_STATIC_PROP(rc, event);
+  JS_STATIC_PROP(richChange, event);
+  JS_STATIC_PROP(richChangeEx, event);
+  JS_STATIC_PROP(richValue, event);
+  JS_STATIC_PROP(selEnd, event);
+  JS_STATIC_PROP(selStart, event);
+  JS_STATIC_PROP(shift, event);
+  JS_STATIC_PROP(source, event);
+  JS_STATIC_PROP(target, event);
+  JS_STATIC_PROP(targetName, event);
+  JS_STATIC_PROP(type, event);
+  JS_STATIC_PROP(value, event);
+  JS_STATIC_PROP(willCommit, event);
+};
+
+#endif  // FPDFSDK_JAVASCRIPT_EVENT_H_
diff --git a/fpdfsdk/javascript/global.cpp b/fpdfsdk/javascript/global.cpp
new file mode 100644
index 0000000..aca8697
--- /dev/null
+++ b/fpdfsdk/javascript/global.cpp
@@ -0,0 +1,444 @@
+// 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
+
+#include "fpdfsdk/javascript/global.h"
+
+#include <vector>
+
+#include "core/fxcrt/fx_ext.h"
+#include "fpdfsdk/javascript/JS_Define.h"
+#include "fpdfsdk/javascript/JS_EventHandler.h"
+#include "fpdfsdk/javascript/JS_GlobalData.h"
+#include "fpdfsdk/javascript/JS_Object.h"
+#include "fpdfsdk/javascript/JS_Value.h"
+#include "fpdfsdk/javascript/cjs_context.h"
+#include "fpdfsdk/javascript/resource.h"
+
+BEGIN_JS_STATIC_CONST(CJS_Global)
+END_JS_STATIC_CONST()
+
+BEGIN_JS_STATIC_PROP(CJS_Global)
+END_JS_STATIC_PROP()
+
+BEGIN_JS_STATIC_METHOD(CJS_Global)
+JS_STATIC_METHOD_ENTRY(setPersistent)
+END_JS_STATIC_METHOD()
+
+IMPLEMENT_SPECIAL_JS_CLASS(CJS_Global, JSGlobalAlternate, global);
+
+void CJS_Global::InitInstance(IJS_Runtime* pIRuntime) {
+  CJS_Runtime* pRuntime = static_cast<CJS_Runtime*>(pIRuntime);
+  JSGlobalAlternate* pGlobal =
+      static_cast<JSGlobalAlternate*>(GetEmbedObject());
+  pGlobal->Initial(pRuntime->GetFormFillEnv());
+}
+
+JSGlobalData::JSGlobalData()
+    : nType(JS_GlobalDataType::NUMBER),
+      dData(0),
+      bData(false),
+      sData(""),
+      bPersistent(false),
+      bDeleted(false) {}
+
+JSGlobalData::~JSGlobalData() {
+  pData.Reset();
+}
+
+JSGlobalAlternate::JSGlobalAlternate(CJS_Object* pJSObject)
+    : CJS_EmbedObj(pJSObject), m_pFormFillEnv(nullptr) {}
+
+JSGlobalAlternate::~JSGlobalAlternate() {
+  DestroyGlobalPersisitentVariables();
+  m_pGlobalData->Release();
+}
+
+void JSGlobalAlternate::Initial(CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+  m_pFormFillEnv = pFormFillEnv;
+  m_pGlobalData = CJS_GlobalData::GetRetainedInstance(pFormFillEnv);
+  UpdateGlobalPersistentVariables();
+}
+
+bool JSGlobalAlternate::QueryProperty(const FX_WCHAR* propname) {
+  return CFX_WideString(propname) != L"setPersistent";
+}
+
+bool JSGlobalAlternate::DelProperty(IJS_Context* cc,
+                                    const FX_WCHAR* propname,
+                                    CFX_WideString& sError) {
+  auto it = m_mapGlobal.find(CFX_ByteString::FromUnicode(propname));
+  if (it == m_mapGlobal.end())
+    return false;
+
+  it->second->bDeleted = true;
+  return true;
+}
+
+bool JSGlobalAlternate::DoProperty(IJS_Context* cc,
+                                   const FX_WCHAR* propname,
+                                   CJS_PropValue& vp,
+                                   CFX_WideString& sError) {
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  if (vp.IsSetting()) {
+    CFX_ByteString sPropName = CFX_ByteString::FromUnicode(propname);
+    switch (vp.GetJSValue()->GetType()) {
+      case CJS_Value::VT_number: {
+        double dData;
+        vp >> dData;
+        return SetGlobalVariables(sPropName, JS_GlobalDataType::NUMBER, dData,
+                                  false, "", v8::Local<v8::Object>(), false);
+      }
+      case CJS_Value::VT_boolean: {
+        bool bData;
+        vp >> bData;
+        return SetGlobalVariables(sPropName, JS_GlobalDataType::BOOLEAN, 0,
+                                  bData, "", v8::Local<v8::Object>(), false);
+      }
+      case CJS_Value::VT_string: {
+        CFX_ByteString sData;
+        vp >> sData;
+        return SetGlobalVariables(sPropName, JS_GlobalDataType::STRING, 0,
+                                  false, sData, v8::Local<v8::Object>(), false);
+      }
+      case CJS_Value::VT_object: {
+        v8::Local<v8::Object> pData;
+        vp >> pData;
+        return SetGlobalVariables(sPropName, JS_GlobalDataType::OBJECT, 0,
+                                  false, "", pData, false);
+      }
+      case CJS_Value::VT_null: {
+        return SetGlobalVariables(sPropName, JS_GlobalDataType::NULLOBJ, 0,
+                                  false, "", v8::Local<v8::Object>(), false);
+      }
+      case CJS_Value::VT_undefined: {
+        DelProperty(cc, propname, sError);
+        return true;
+      }
+      default:
+        break;
+    }
+  } else {
+    auto it = m_mapGlobal.find(CFX_ByteString::FromUnicode(propname));
+    if (it == m_mapGlobal.end()) {
+      vp.GetJSValue()->SetNull(pRuntime);
+      return true;
+    }
+    JSGlobalData* pData = it->second;
+    if (pData->bDeleted) {
+      vp.GetJSValue()->SetNull(pRuntime);
+      return true;
+    }
+    switch (pData->nType) {
+      case JS_GlobalDataType::NUMBER:
+        vp << pData->dData;
+        return true;
+      case JS_GlobalDataType::BOOLEAN:
+        vp << pData->bData;
+        return true;
+      case JS_GlobalDataType::STRING:
+        vp << pData->sData;
+        return true;
+      case JS_GlobalDataType::OBJECT: {
+        v8::Local<v8::Object> obj = v8::Local<v8::Object>::New(
+            vp.GetJSRuntime()->GetIsolate(), pData->pData);
+        vp << obj;
+        return true;
+      }
+      case JS_GlobalDataType::NULLOBJ:
+        vp.GetJSValue()->SetNull(pRuntime);
+        return true;
+      default:
+        break;
+    }
+  }
+  return false;
+}
+
+bool JSGlobalAlternate::setPersistent(IJS_Context* cc,
+                                      const std::vector<CJS_Value>& params,
+                                      CJS_Value& vRet,
+                                      CFX_WideString& sError) {
+  if (params.size() != 2) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  auto it = m_mapGlobal.find(params[0].ToCFXByteString(pRuntime));
+  if (it != m_mapGlobal.end()) {
+    JSGlobalData* pData = it->second;
+    if (!pData->bDeleted) {
+      pData->bPersistent = params[1].ToBool(pRuntime);
+      return true;
+    }
+  }
+
+  sError = JSGetStringFromID(IDS_STRING_JSNOGLOBAL);
+  return false;
+}
+
+void JSGlobalAlternate::UpdateGlobalPersistentVariables() {
+  CJS_Runtime* pRuntime =
+      static_cast<CJS_Runtime*>(CFXJS_Engine::CurrentEngineFromIsolate(
+          m_pJSObject->ToV8Object()->GetIsolate()));
+
+  for (int i = 0, sz = m_pGlobalData->GetSize(); i < sz; i++) {
+    CJS_GlobalData_Element* pData = m_pGlobalData->GetAt(i);
+    switch (pData->data.nType) {
+      case JS_GlobalDataType::NUMBER:
+        SetGlobalVariables(pData->data.sKey, JS_GlobalDataType::NUMBER,
+                           pData->data.dData, false, "",
+                           v8::Local<v8::Object>(), pData->bPersistent == 1);
+        pRuntime->PutObjectProperty(m_pJSObject->ToV8Object(),
+                                    pData->data.sKey.UTF8Decode(),
+                                    pRuntime->NewNumber(pData->data.dData));
+        break;
+      case JS_GlobalDataType::BOOLEAN:
+        SetGlobalVariables(pData->data.sKey, JS_GlobalDataType::BOOLEAN, 0,
+                           pData->data.bData == 1, "", v8::Local<v8::Object>(),
+                           pData->bPersistent == 1);
+        pRuntime->PutObjectProperty(
+            m_pJSObject->ToV8Object(), pData->data.sKey.UTF8Decode(),
+            pRuntime->NewBoolean(pData->data.bData == 1));
+        break;
+      case JS_GlobalDataType::STRING:
+        SetGlobalVariables(pData->data.sKey, JS_GlobalDataType::STRING, 0,
+                           false, pData->data.sData, v8::Local<v8::Object>(),
+                           pData->bPersistent == 1);
+        pRuntime->PutObjectProperty(
+            m_pJSObject->ToV8Object(), pData->data.sKey.UTF8Decode(),
+            pRuntime->NewString(pData->data.sData.UTF8Decode()));
+        break;
+      case JS_GlobalDataType::OBJECT: {
+        v8::Local<v8::Object> pObj = pRuntime->NewFxDynamicObj(-1);
+        PutObjectProperty(pObj, &pData->data);
+        SetGlobalVariables(pData->data.sKey, JS_GlobalDataType::OBJECT, 0,
+                           false, "", pObj, pData->bPersistent == 1);
+        pRuntime->PutObjectProperty(m_pJSObject->ToV8Object(),
+                                    pData->data.sKey.UTF8Decode(), pObj);
+      } break;
+      case JS_GlobalDataType::NULLOBJ:
+        SetGlobalVariables(pData->data.sKey, JS_GlobalDataType::NULLOBJ, 0,
+                           false, "", v8::Local<v8::Object>(),
+                           pData->bPersistent == 1);
+        pRuntime->PutObjectProperty(m_pJSObject->ToV8Object(),
+                                    pData->data.sKey.UTF8Decode(),
+                                    pRuntime->NewNull());
+        break;
+    }
+  }
+}
+
+void JSGlobalAlternate::CommitGlobalPersisitentVariables(IJS_Context* cc) {
+  for (auto it = m_mapGlobal.begin(); it != m_mapGlobal.end(); ++it) {
+    CFX_ByteString name = it->first;
+    JSGlobalData* pData = it->second;
+    if (pData->bDeleted) {
+      m_pGlobalData->DeleteGlobalVariable(name);
+    } else {
+      switch (pData->nType) {
+        case JS_GlobalDataType::NUMBER:
+          m_pGlobalData->SetGlobalVariableNumber(name, pData->dData);
+          m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
+          break;
+        case JS_GlobalDataType::BOOLEAN:
+          m_pGlobalData->SetGlobalVariableBoolean(name, pData->bData);
+          m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
+          break;
+        case JS_GlobalDataType::STRING:
+          m_pGlobalData->SetGlobalVariableString(name, pData->sData);
+          m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
+          break;
+        case JS_GlobalDataType::OBJECT: {
+          CJS_GlobalVariableArray array;
+          v8::Local<v8::Object> obj = v8::Local<v8::Object>::New(
+              GetJSObject()->GetIsolate(), pData->pData);
+          ObjectToArray(cc, obj, array);
+          m_pGlobalData->SetGlobalVariableObject(name, array);
+          m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
+        } break;
+        case JS_GlobalDataType::NULLOBJ:
+          m_pGlobalData->SetGlobalVariableNull(name);
+          m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
+          break;
+      }
+    }
+  }
+}
+
+void JSGlobalAlternate::ObjectToArray(IJS_Context* cc,
+                                      v8::Local<v8::Object> pObj,
+                                      CJS_GlobalVariableArray& array) {
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  std::vector<CFX_WideString> pKeyList = pRuntime->GetObjectPropertyNames(pObj);
+  for (const auto& ws : pKeyList) {
+    CFX_ByteString sKey = ws.UTF8Encode();
+    v8::Local<v8::Value> v = pRuntime->GetObjectProperty(pObj, ws);
+    switch (CJS_Value::GetValueType(v)) {
+      case CJS_Value::VT_number: {
+        CJS_KeyValue* pObjElement = new CJS_KeyValue;
+        pObjElement->nType = JS_GlobalDataType::NUMBER;
+        pObjElement->sKey = sKey;
+        pObjElement->dData = pRuntime->ToDouble(v);
+        array.Add(pObjElement);
+      } break;
+      case CJS_Value::VT_boolean: {
+        CJS_KeyValue* pObjElement = new CJS_KeyValue;
+        pObjElement->nType = JS_GlobalDataType::BOOLEAN;
+        pObjElement->sKey = sKey;
+        pObjElement->dData = pRuntime->ToBoolean(v);
+        array.Add(pObjElement);
+      } break;
+      case CJS_Value::VT_string: {
+        CFX_ByteString sValue =
+            CJS_Value(pRuntime, v).ToCFXByteString(pRuntime);
+        CJS_KeyValue* pObjElement = new CJS_KeyValue;
+        pObjElement->nType = JS_GlobalDataType::STRING;
+        pObjElement->sKey = sKey;
+        pObjElement->sData = sValue;
+        array.Add(pObjElement);
+      } break;
+      case CJS_Value::VT_object: {
+        CJS_KeyValue* pObjElement = new CJS_KeyValue;
+        pObjElement->nType = JS_GlobalDataType::OBJECT;
+        pObjElement->sKey = sKey;
+        ObjectToArray(cc, pRuntime->ToObject(v), pObjElement->objData);
+        array.Add(pObjElement);
+      } break;
+      case CJS_Value::VT_null: {
+        CJS_KeyValue* pObjElement = new CJS_KeyValue;
+        pObjElement->nType = JS_GlobalDataType::NULLOBJ;
+        pObjElement->sKey = sKey;
+        array.Add(pObjElement);
+      } break;
+      default:
+        break;
+    }
+  }
+}
+
+void JSGlobalAlternate::PutObjectProperty(v8::Local<v8::Object> pObj,
+                                          CJS_KeyValue* pData) {
+  CJS_Runtime* pRuntime = CJS_Runtime::CurrentRuntimeFromIsolate(
+      m_pJSObject->ToV8Object()->GetIsolate());
+
+  for (int i = 0, sz = pData->objData.Count(); i < sz; i++) {
+    CJS_KeyValue* pObjData = pData->objData.GetAt(i);
+    switch (pObjData->nType) {
+      case JS_GlobalDataType::NUMBER:
+        pRuntime->PutObjectProperty(pObj, pObjData->sKey.UTF8Decode(),
+                                    pRuntime->NewNumber(pObjData->dData));
+        break;
+      case JS_GlobalDataType::BOOLEAN:
+        pRuntime->PutObjectProperty(pObj, pObjData->sKey.UTF8Decode(),
+                                    pRuntime->NewBoolean(pObjData->bData == 1));
+        break;
+      case JS_GlobalDataType::STRING:
+        pRuntime->PutObjectProperty(
+            pObj, pObjData->sKey.UTF8Decode(),
+            pRuntime->NewString(pObjData->sData.UTF8Decode()));
+        break;
+      case JS_GlobalDataType::OBJECT: {
+        v8::Local<v8::Object> pNewObj = pRuntime->NewFxDynamicObj(-1);
+        PutObjectProperty(pNewObj, pObjData);
+        pRuntime->PutObjectProperty(pObj, pObjData->sKey.UTF8Decode(), pNewObj);
+      } break;
+      case JS_GlobalDataType::NULLOBJ:
+        pRuntime->PutObjectProperty(pObj, pObjData->sKey.UTF8Decode(),
+                                    pRuntime->NewNull());
+        break;
+    }
+  }
+}
+
+void JSGlobalAlternate::DestroyGlobalPersisitentVariables() {
+  for (const auto& pair : m_mapGlobal) {
+    delete pair.second;
+  }
+  m_mapGlobal.clear();
+}
+
+bool JSGlobalAlternate::SetGlobalVariables(const CFX_ByteString& propname,
+                                           JS_GlobalDataType nType,
+                                           double dData,
+                                           bool bData,
+                                           const CFX_ByteString& sData,
+                                           v8::Local<v8::Object> pData,
+                                           bool bDefaultPersistent) {
+  if (propname.IsEmpty())
+    return false;
+
+  auto it = m_mapGlobal.find(propname);
+  if (it != m_mapGlobal.end()) {
+    JSGlobalData* pTemp = it->second;
+    if (pTemp->bDeleted || pTemp->nType != nType) {
+      pTemp->dData = 0;
+      pTemp->bData = 0;
+      pTemp->sData = "";
+      pTemp->nType = nType;
+    }
+
+    pTemp->bDeleted = false;
+    switch (nType) {
+      case JS_GlobalDataType::NUMBER: {
+        pTemp->dData = dData;
+      } break;
+      case JS_GlobalDataType::BOOLEAN: {
+        pTemp->bData = bData;
+      } break;
+      case JS_GlobalDataType::STRING: {
+        pTemp->sData = sData;
+      } break;
+      case JS_GlobalDataType::OBJECT: {
+        pTemp->pData.Reset(pData->GetIsolate(), pData);
+      } break;
+      case JS_GlobalDataType::NULLOBJ:
+        break;
+      default:
+        return false;
+    }
+    return true;
+  }
+
+  JSGlobalData* pNewData = nullptr;
+
+  switch (nType) {
+    case JS_GlobalDataType::NUMBER: {
+      pNewData = new JSGlobalData;
+      pNewData->nType = JS_GlobalDataType::NUMBER;
+      pNewData->dData = dData;
+      pNewData->bPersistent = bDefaultPersistent;
+    } break;
+    case JS_GlobalDataType::BOOLEAN: {
+      pNewData = new JSGlobalData;
+      pNewData->nType = JS_GlobalDataType::BOOLEAN;
+      pNewData->bData = bData;
+      pNewData->bPersistent = bDefaultPersistent;
+    } break;
+    case JS_GlobalDataType::STRING: {
+      pNewData = new JSGlobalData;
+      pNewData->nType = JS_GlobalDataType::STRING;
+      pNewData->sData = sData;
+      pNewData->bPersistent = bDefaultPersistent;
+    } break;
+    case JS_GlobalDataType::OBJECT: {
+      pNewData = new JSGlobalData;
+      pNewData->nType = JS_GlobalDataType::OBJECT;
+      pNewData->pData.Reset(pData->GetIsolate(), pData);
+      pNewData->bPersistent = bDefaultPersistent;
+    } break;
+    case JS_GlobalDataType::NULLOBJ: {
+      pNewData = new JSGlobalData;
+      pNewData->nType = JS_GlobalDataType::NULLOBJ;
+      pNewData->bPersistent = bDefaultPersistent;
+    } break;
+    default:
+      return false;
+  }
+
+  m_mapGlobal[propname] = pNewData;
+  return true;
+}
diff --git a/fpdfsdk/javascript/global.h b/fpdfsdk/javascript/global.h
new file mode 100644
index 0000000..9a6568b
--- /dev/null
+++ b/fpdfsdk/javascript/global.h
@@ -0,0 +1,86 @@
+// 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_JAVASCRIPT_GLOBAL_H_
+#define FPDFSDK_JAVASCRIPT_GLOBAL_H_
+
+#include <map>
+#include <vector>
+
+#include "fpdfsdk/javascript/JS_Define.h"
+#include "fpdfsdk/javascript/JS_KeyValue.h"
+
+class CJS_GlobalData;
+class CJS_GlobalVariableArray;
+class CJS_KeyValue;
+
+struct JSGlobalData {
+  JSGlobalData();
+  ~JSGlobalData();
+
+  JS_GlobalDataType nType;
+  double dData;
+  bool bData;
+  CFX_ByteString sData;
+  v8::Global<v8::Object> pData;
+  bool bPersistent;
+  bool bDeleted;
+};
+
+class JSGlobalAlternate : public CJS_EmbedObj {
+ public:
+  explicit JSGlobalAlternate(CJS_Object* pJSObject);
+  ~JSGlobalAlternate() override;
+
+  bool setPersistent(IJS_Context* cc,
+                     const std::vector<CJS_Value>& params,
+                     CJS_Value& vRet,
+                     CFX_WideString& sError);
+  bool QueryProperty(const FX_WCHAR* propname);
+  bool DoProperty(IJS_Context* cc,
+                  const FX_WCHAR* propname,
+                  CJS_PropValue& vp,
+                  CFX_WideString& sError);
+  bool DelProperty(IJS_Context* cc,
+                   const FX_WCHAR* propname,
+                   CFX_WideString& sError);
+  void Initial(CPDFSDK_FormFillEnvironment* pFormFillEnv);
+
+ private:
+  void UpdateGlobalPersistentVariables();
+  void CommitGlobalPersisitentVariables(IJS_Context* cc);
+  void DestroyGlobalPersisitentVariables();
+  bool SetGlobalVariables(const CFX_ByteString& propname,
+                          JS_GlobalDataType nType,
+                          double dData,
+                          bool bData,
+                          const CFX_ByteString& sData,
+                          v8::Local<v8::Object> pData,
+                          bool bDefaultPersistent);
+  void ObjectToArray(IJS_Context* cc,
+                     v8::Local<v8::Object> pObj,
+                     CJS_GlobalVariableArray& array);
+  void PutObjectProperty(v8::Local<v8::Object> obj, CJS_KeyValue* pData);
+
+  std::map<CFX_ByteString, JSGlobalData*> m_mapGlobal;
+  CFX_WideString m_sFilePath;
+  CJS_GlobalData* m_pGlobalData;
+  CPDFSDK_FormFillEnvironment* m_pFormFillEnv;
+};
+
+class CJS_Global : public CJS_Object {
+ public:
+  explicit CJS_Global(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_Global() override {}
+
+  // CJS_Object
+  void InitInstance(IJS_Runtime* pIRuntime) override;
+
+  DECLARE_SPECIAL_JS_CLASS();
+  JS_SPECIAL_STATIC_METHOD(setPersistent, JSGlobalAlternate, global);
+};
+
+#endif  // FPDFSDK_JAVASCRIPT_GLOBAL_H_
diff --git a/fpdfsdk/javascript/ijs_context.h b/fpdfsdk/javascript/ijs_context.h
new file mode 100644
index 0000000..2d2248f
--- /dev/null
+++ b/fpdfsdk/javascript/ijs_context.h
@@ -0,0 +1,132 @@
+// 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_JAVASCRIPT_IJS_CONTEXT_H_
+#define FPDFSDK_JAVASCRIPT_IJS_CONTEXT_H_
+
+#include "core/fxcrt/fx_string.h"
+#include "core/fxcrt/fx_system.h"
+
+class CPDF_Bookmark;
+class CPDF_FormField;
+class CPDFSDK_Annot;
+class CPDFSDK_FormFillEnvironment;
+
+// Records the details of an event and triggers JS execution for it.
+class IJS_Context {
+ public:
+  virtual bool RunScript(const CFX_WideString& script,
+                         CFX_WideString* info) = 0;
+
+  virtual void OnApp_Init() = 0;
+
+  virtual void OnDoc_Open(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                          const CFX_WideString& strTargetName) = 0;
+  virtual void OnDoc_WillPrint(CPDFSDK_FormFillEnvironment* pFormFillEnv) = 0;
+  virtual void OnDoc_DidPrint(CPDFSDK_FormFillEnvironment* pFormFillEnv) = 0;
+  virtual void OnDoc_WillSave(CPDFSDK_FormFillEnvironment* pFormFillEnv) = 0;
+  virtual void OnDoc_DidSave(CPDFSDK_FormFillEnvironment* pFormFillEnv) = 0;
+  virtual void OnDoc_WillClose(CPDFSDK_FormFillEnvironment* pFormFillEnv) = 0;
+
+  virtual void OnPage_Open(CPDFSDK_FormFillEnvironment* pFormFillEnv) = 0;
+  virtual void OnPage_Close(CPDFSDK_FormFillEnvironment* pFormFillEnv) = 0;
+  virtual void OnPage_InView(CPDFSDK_FormFillEnvironment* pFormFillEnv) = 0;
+  virtual void OnPage_OutView(CPDFSDK_FormFillEnvironment* pFormFillEnv) = 0;
+
+  virtual void OnField_MouseDown(bool bModifier,
+                                 bool bShift,
+                                 CPDF_FormField* pTarget) = 0;
+  virtual void OnField_MouseEnter(bool bModifier,
+                                  bool bShift,
+                                  CPDF_FormField* pTarget) = 0;
+  virtual void OnField_MouseExit(bool bModifier,
+                                 bool bShift,
+                                 CPDF_FormField* pTarget) = 0;
+  virtual void OnField_MouseUp(bool bModifier,
+                               bool bShift,
+                               CPDF_FormField* pTarget) = 0;
+  virtual void OnField_Focus(bool bModifier,
+                             bool bShift,
+                             CPDF_FormField* pTarget,
+                             const CFX_WideString& Value) = 0;
+  virtual void OnField_Blur(bool bModifier,
+                            bool bShift,
+                            CPDF_FormField* pTarget,
+                            const CFX_WideString& Value) = 0;
+
+  virtual void OnField_Calculate(CPDF_FormField* pSource,
+                                 CPDF_FormField* pTarget,
+                                 CFX_WideString& Value,
+                                 bool& bRc) = 0;
+  virtual void OnField_Format(CPDF_FormField* pTarget,
+                              CFX_WideString& Value,
+                              bool bWillCommit) = 0;
+  virtual void OnField_Keystroke(CFX_WideString& strChange,
+                                 const CFX_WideString& strChangeEx,
+                                 bool KeyDown,
+                                 bool bModifier,
+                                 int& nSelEnd,
+                                 int& nSelStart,
+                                 bool bShift,
+                                 CPDF_FormField* pTarget,
+                                 CFX_WideString& Value,
+                                 bool bWillCommit,
+                                 bool bFieldFull,
+                                 bool& bRc) = 0;
+  virtual void OnField_Validate(CFX_WideString& strChange,
+                                const CFX_WideString& strChangeEx,
+                                bool bKeyDown,
+                                bool bModifier,
+                                bool bShift,
+                                CPDF_FormField* pTarget,
+                                CFX_WideString& Value,
+                                bool& bRc) = 0;
+
+  virtual void OnScreen_Focus(bool bModifier,
+                              bool bShift,
+                              CPDFSDK_Annot* pScreen) = 0;
+  virtual void OnScreen_Blur(bool bModifier,
+                             bool bShift,
+                             CPDFSDK_Annot* pScreen) = 0;
+  virtual void OnScreen_Open(bool bModifier,
+                             bool bShift,
+                             CPDFSDK_Annot* pScreen) = 0;
+  virtual void OnScreen_Close(bool bModifier,
+                              bool bShift,
+                              CPDFSDK_Annot* pScreen) = 0;
+  virtual void OnScreen_MouseDown(bool bModifier,
+                                  bool bShift,
+                                  CPDFSDK_Annot* pScreen) = 0;
+  virtual void OnScreen_MouseUp(bool bModifier,
+                                bool bShift,
+                                CPDFSDK_Annot* pScreen) = 0;
+  virtual void OnScreen_MouseEnter(bool bModifier,
+                                   bool bShift,
+                                   CPDFSDK_Annot* pScreen) = 0;
+  virtual void OnScreen_MouseExit(bool bModifier,
+                                  bool bShift,
+                                  CPDFSDK_Annot* pScreen) = 0;
+  virtual void OnScreen_InView(bool bModifier,
+                               bool bShift,
+                               CPDFSDK_Annot* pScreen) = 0;
+  virtual void OnScreen_OutView(bool bModifier,
+                                bool bShift,
+                                CPDFSDK_Annot* pScreen) = 0;
+
+  virtual void OnBookmark_MouseUp(CPDF_Bookmark* pBookMark) = 0;
+  virtual void OnLink_MouseUp(CPDFSDK_FormFillEnvironment* pFormFillEnv) = 0;
+
+  virtual void OnMenu_Exec(CPDFSDK_FormFillEnvironment* pFormFillEnv,
+                           const CFX_WideString&) = 0;
+  virtual void OnBatchExec(CPDFSDK_FormFillEnvironment* pFormFillEnv) = 0;
+  virtual void OnConsole_Exec() = 0;
+  virtual void OnExternal_Exec() = 0;
+
+ protected:
+  virtual ~IJS_Context() {}
+};
+
+#endif  // FPDFSDK_JAVASCRIPT_IJS_CONTEXT_H_
diff --git a/fpdfsdk/javascript/ijs_runtime.h b/fpdfsdk/javascript/ijs_runtime.h
new file mode 100644
index 0000000..027c500
--- /dev/null
+++ b/fpdfsdk/javascript/ijs_runtime.h
@@ -0,0 +1,48 @@
+// 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_JAVASCRIPT_IJS_RUNTIME_H_
+#define FPDFSDK_JAVASCRIPT_IJS_RUNTIME_H_
+
+#include "core/fxcrt/fx_string.h"
+#include "core/fxcrt/fx_system.h"
+
+#ifdef PDF_ENABLE_XFA
+#include "fxjs/fxjse.h"
+#endif  // PDF_ENABLE_XFA
+
+class CPDFSDK_FormFillEnvironment;
+class IJS_Context;
+
+// Owns the FJXS objects needed to actually execute JS.
+class IJS_Runtime {
+ public:
+  static void Initialize(unsigned int slot, void* isolate);
+  static void Destroy();
+  static IJS_Runtime* Create(CPDFSDK_FormFillEnvironment* pFormFillEnv);
+  virtual ~IJS_Runtime() {}
+
+  virtual IJS_Context* NewContext() = 0;
+  virtual void ReleaseContext(IJS_Context* pContext) = 0;
+  virtual IJS_Context* GetCurrentContext() = 0;
+
+  virtual CPDFSDK_FormFillEnvironment* GetFormFillEnv() const = 0;
+
+  virtual int ExecuteScript(const CFX_WideString& script,
+                            CFX_WideString* info) = 0;
+
+#ifdef PDF_ENABLE_XFA
+  virtual bool GetValueByName(const CFX_ByteStringC& utf8Name,
+                              CFXJSE_Value* pValue) = 0;
+  virtual bool SetValueByName(const CFX_ByteStringC& utf8Name,
+                              CFXJSE_Value* pValue) = 0;
+#endif  // PDF_ENABLE_XFA
+
+ protected:
+  IJS_Runtime() {}
+};
+
+#endif  // FPDFSDK_JAVASCRIPT_IJS_RUNTIME_H_
diff --git a/fpdfsdk/src/javascript/public_methods_embeddertest.cpp b/fpdfsdk/javascript/public_methods_embeddertest.cpp
similarity index 82%
rename from fpdfsdk/src/javascript/public_methods_embeddertest.cpp
rename to fpdfsdk/javascript/public_methods_embeddertest.cpp
index c61215a..2479366 100644
--- a/fpdfsdk/src/javascript/public_methods_embeddertest.cpp
+++ b/fpdfsdk/javascript/public_methods_embeddertest.cpp
@@ -4,10 +4,10 @@
 
 #include <cmath>
 
-#include "core/include/fxcrt/fx_string.h"
-#include "fpdfsdk/src/javascript/PublicMethods.h"
-#include "testing/js_embedder_test.h"
+#include "core/fxcrt/fx_string.h"
+#include "fpdfsdk/javascript/PublicMethods.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "testing/js_embedder_test.h"
 
 namespace {
 
@@ -21,9 +21,6 @@
 
 TEST_F(PublicMethodsEmbedderTest, MakeRegularDate) {
   v8::Isolate::Scope isolate_scope(isolate());
-#ifdef PDF_ENABLE_XFA
-  v8::Locker locker(isolate());
-#endif  // PDF_ENABLE_XFA
   v8::HandleScope handle_scope(isolate());
   v8::Context::Scope context_scope(GetV8Context());
   bool bWrongFormat;
@@ -104,65 +101,62 @@
 
 TEST_F(PublicMethodsEmbedderTest, MakeFormatDate) {
   v8::Isolate::Scope isolate_scope(isolate());
-#ifdef PDF_ENABLE_XFA
-  v8::Locker locker(isolate());
-#endif  // PDF_ENABLE_XFA
   v8::HandleScope handle_scope(isolate());
   v8::Context::Scope context_scope(GetV8Context());
   CFX_WideString formatted_date;
 
   // 1968-06-25
   formatted_date = CJS_PublicMethods::MakeFormatDate(-47952000000, L"ddmmyy");
-  EXPECT_STREQ(L"250668", formatted_date);
+  EXPECT_STREQ(L"250668", formatted_date.c_str());
   formatted_date = CJS_PublicMethods::MakeFormatDate(-47952000000, L"yy/mm/dd");
-  EXPECT_STREQ(L"68/06/25", formatted_date);
+  EXPECT_STREQ(L"68/06/25", formatted_date.c_str());
 
   // 1969-12-31
   formatted_date = CJS_PublicMethods::MakeFormatDate(-0.0001, L"ddmmyy");
-  EXPECT_STREQ(L"311269", formatted_date);
+  EXPECT_STREQ(L"311269", formatted_date.c_str());
   formatted_date = CJS_PublicMethods::MakeFormatDate(-0.0001, L"yy!mmdd");
-  EXPECT_STREQ(L"69!1231", formatted_date);
+  EXPECT_STREQ(L"69!1231", formatted_date.c_str());
 
   // 1970-01-01
   formatted_date = CJS_PublicMethods::MakeFormatDate(0, L"ddmmyy");
-  EXPECT_STREQ(L"010170", formatted_date);
+  EXPECT_STREQ(L"010170", formatted_date.c_str());
   formatted_date = CJS_PublicMethods::MakeFormatDate(0, L"mm-yyyy-dd");
-  EXPECT_STREQ(L"01-1970-01", formatted_date);
+  EXPECT_STREQ(L"01-1970-01", formatted_date.c_str());
 
   // 1985-12-31
   formatted_date = CJS_PublicMethods::MakeFormatDate(504835200000.0, L"ddmmyy");
-  EXPECT_STREQ(L"311285", formatted_date);
+  EXPECT_STREQ(L"311285", formatted_date.c_str());
   formatted_date = CJS_PublicMethods::MakeFormatDate(504835200000.0, L"yymmdd");
-  EXPECT_STREQ(L"851231", formatted_date);
+  EXPECT_STREQ(L"851231", formatted_date.c_str());
 
   // 1995-02-01
   formatted_date = CJS_PublicMethods::MakeFormatDate(791596800000.0, L"ddmmyy");
-  EXPECT_STREQ(L"010295", formatted_date);
+  EXPECT_STREQ(L"010295", formatted_date.c_str());
   formatted_date =
       CJS_PublicMethods::MakeFormatDate(791596800000.0, L"yyyymmdd");
-  EXPECT_STREQ(L"19950201", formatted_date);
+  EXPECT_STREQ(L"19950201", formatted_date.c_str());
 
   // 2005-02-01
   formatted_date =
       CJS_PublicMethods::MakeFormatDate(1107216000000.0, L"ddmmyy");
-  EXPECT_STREQ(L"010205", formatted_date);
+  EXPECT_STREQ(L"010205", formatted_date.c_str());
   formatted_date =
       CJS_PublicMethods::MakeFormatDate(1107216000000.0, L"yyyyddmm");
-  EXPECT_STREQ(L"20050102", formatted_date);
+  EXPECT_STREQ(L"20050102", formatted_date.c_str());
 
   // 2085-12-31
   formatted_date =
       CJS_PublicMethods::MakeFormatDate(3660595200000.0, L"ddmmyy");
-  EXPECT_STREQ(L"311285", formatted_date);
+  EXPECT_STREQ(L"311285", formatted_date.c_str());
   formatted_date =
       CJS_PublicMethods::MakeFormatDate(3660595200000.0, L"yyyydd");
-  EXPECT_STREQ(L"208531", formatted_date);
+  EXPECT_STREQ(L"208531", formatted_date.c_str());
 
   // 2095-02-01
   formatted_date =
       CJS_PublicMethods::MakeFormatDate(3947356800000.0, L"ddmmyy");
-  EXPECT_STREQ(L"010295", formatted_date);
+  EXPECT_STREQ(L"010295", formatted_date.c_str());
   formatted_date =
       CJS_PublicMethods::MakeFormatDate(3947356800000.0, L"mmddyyyy");
-  EXPECT_STREQ(L"02012095", formatted_date);
+  EXPECT_STREQ(L"02012095", formatted_date.c_str());
 }
diff --git a/fpdfsdk/javascript/public_methods_unittest.cpp b/fpdfsdk/javascript/public_methods_unittest.cpp
new file mode 100644
index 0000000..ace0920
--- /dev/null
+++ b/fpdfsdk/javascript/public_methods_unittest.cpp
@@ -0,0 +1,51 @@
+// 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.
+
+#include "fpdfsdk/javascript/PublicMethods.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/test_support.h"
+
+TEST(CJS_PublicMethods, IsNumber) {
+  // TODO(weili): Check whether results from case 0, 1, 10, 15 are intended.
+  struct {
+    const wchar_t* input;
+    bool expected;
+  } test_data[] = {
+      // Empty string.
+      {L"", true},
+      // Only whitespaces.
+      {L"  ", true},
+      // Content with invalid characters.
+      {L"xyz00", false},
+      {L"1%", false},
+      // Hex string.
+      {L"0x234", false},
+      // Signed numbers.
+      {L"+123", true},
+      {L"-98765", true},
+      // Numbers with whitespaces.
+      {L"  345 ", true},
+      // Float numbers.
+      {L"-1e5", false},
+      {L"-2e", false},
+      {L"e-5", true},
+      {L"0.023", true},
+      {L".356089", true},
+      {L"1e-9", true},
+      {L"-1.23e+23", true},
+      // Numbers with commas.
+      {L"1,000,000", false},
+      {L"560,024", true},
+      // Regular numbers.
+      {L"0", true},
+      {L"0123", true},
+      {L"9876123", true},
+  };
+  for (size_t i = 0; i < FX_ArraySize(test_data); ++i) {
+    EXPECT_EQ(test_data[i].expected,
+              CJS_PublicMethods::IsNumber(test_data[i].input))
+        << "for case " << i;
+  }
+}
diff --git a/fpdfsdk/javascript/report.cpp b/fpdfsdk/javascript/report.cpp
new file mode 100644
index 0000000..ba6e97d
--- /dev/null
+++ b/fpdfsdk/javascript/report.cpp
@@ -0,0 +1,46 @@
+// 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
+
+#include "fpdfsdk/javascript/report.h"
+
+#include <vector>
+
+#include "fpdfsdk/javascript/JS_Define.h"
+#include "fpdfsdk/javascript/JS_Object.h"
+#include "fpdfsdk/javascript/JS_Value.h"
+
+BEGIN_JS_STATIC_CONST(CJS_Report)
+END_JS_STATIC_CONST()
+
+BEGIN_JS_STATIC_PROP(CJS_Report)
+END_JS_STATIC_PROP()
+
+BEGIN_JS_STATIC_METHOD(CJS_Report)
+JS_STATIC_METHOD_ENTRY(save)
+JS_STATIC_METHOD_ENTRY(writeText)
+END_JS_STATIC_METHOD()
+
+IMPLEMENT_JS_CLASS(CJS_Report, Report)
+
+Report::Report(CJS_Object* pJSObject) : CJS_EmbedObj(pJSObject) {}
+
+Report::~Report() {}
+
+bool Report::writeText(IJS_Context* cc,
+                       const std::vector<CJS_Value>& params,
+                       CJS_Value& vRet,
+                       CFX_WideString& sError) {
+  // Unsafe, not supported.
+  return true;
+}
+
+bool Report::save(IJS_Context* cc,
+                  const std::vector<CJS_Value>& params,
+                  CJS_Value& vRet,
+                  CFX_WideString& sError) {
+  // Unsafe, not supported.
+  return true;
+}
diff --git a/fpdfsdk/javascript/report.h b/fpdfsdk/javascript/report.h
new file mode 100644
index 0000000..fef2369
--- /dev/null
+++ b/fpdfsdk/javascript/report.h
@@ -0,0 +1,41 @@
+// 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_JAVASCRIPT_REPORT_H_
+#define FPDFSDK_JAVASCRIPT_REPORT_H_
+
+#include <vector>
+
+#include "fpdfsdk/javascript/JS_Define.h"
+
+class Report : public CJS_EmbedObj {
+ public:
+  explicit Report(CJS_Object* pJSObject);
+  ~Report() override;
+
+ public:
+  bool save(IJS_Context* cc,
+            const std::vector<CJS_Value>& params,
+            CJS_Value& vRet,
+            CFX_WideString& sError);
+  bool writeText(IJS_Context* cc,
+                 const std::vector<CJS_Value>& params,
+                 CJS_Value& vRet,
+                 CFX_WideString& sError);
+};
+
+class CJS_Report : public CJS_Object {
+ public:
+  explicit CJS_Report(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_Report() override {}
+
+  DECLARE_JS_CLASS();
+
+  JS_STATIC_METHOD(save, Report)
+  JS_STATIC_METHOD(writeText, Report);
+};
+
+#endif  // FPDFSDK_JAVASCRIPT_REPORT_H_
diff --git a/fpdfsdk/src/javascript/resource.cpp b/fpdfsdk/javascript/resource.cpp
similarity index 89%
rename from fpdfsdk/src/javascript/resource.cpp
rename to fpdfsdk/javascript/resource.cpp
index d99e7ce..6113c54 100644
--- a/fpdfsdk/src/javascript/resource.cpp
+++ b/fpdfsdk/javascript/resource.cpp
@@ -4,9 +4,9 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#include "resource.h"
+#include "fpdfsdk/javascript/resource.h"
 
-CFX_WideString JSGetStringFromID(CJS_Context* pContext, FX_UINT id) {
+CFX_WideString JSGetStringFromID(uint32_t id) {
   switch (id) {
     case IDS_STRING_JSALERT:
       return L"Alert";
@@ -25,7 +25,7 @@
       return L"The input value must be greater than or equal to %s.";
     case IDS_STRING_JSRANGE3:
       return L"The input value must be less than or equal to %s.";
-    case IDS_STRING_NOTSUPPORT:
+    case IDS_STRING_JSNOTSUPPORT:
       return L"Operation not supported.";
     case IDS_STRING_JSBUSY:
       return L"System is busy.";
@@ -45,6 +45,10 @@
       return L"Incorrect parameter type.";
     case IDS_STRING_JSVALUEERROR:
       return L"Incorrect parameter value.";
+    case IDS_STRING_JSNOPERMISSION:
+      return L"Permission denied.";
+    case IDS_STRING_JSBADOBJECT:
+      return L"Object no longer exists.";
     default:
       return L"";
   }
diff --git a/fpdfsdk/src/javascript/resource.h b/fpdfsdk/javascript/resource.h
similarity index 74%
rename from fpdfsdk/src/javascript/resource.h
rename to fpdfsdk/javascript/resource.h
index be3ae13..663cf3b 100644
--- a/fpdfsdk/src/javascript/resource.h
+++ b/fpdfsdk/javascript/resource.h
@@ -4,11 +4,10 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#ifndef FPDFSDK_SRC_JAVASCRIPT_RESOURCE_H_
-#define FPDFSDK_SRC_JAVASCRIPT_RESOURCE_H_
+#ifndef FPDFSDK_JAVASCRIPT_RESOURCE_H_
+#define FPDFSDK_JAVASCRIPT_RESOURCE_H_
 
-#include "core/include/fxcrt/fx_string.h"  // For CFX_WideString.
-#include "fpdfsdk/include/fsdk_define.h"   // For FX_UINT.
+#include "core/fxcrt/fx_string.h"
 
 class CJS_Context;
 
@@ -20,7 +19,7 @@
 #define IDS_STRING_JSRANGE1 25619
 #define IDS_STRING_JSRANGE2 25620
 #define IDS_STRING_JSRANGE3 25621
-#define IDS_STRING_NOTSUPPORT 25627
+#define IDS_STRING_JSNOTSUPPORT 25627
 #define IDS_STRING_JSBUSY 25628
 #define IDS_STRING_JSEVENT 25629
 #define IDS_STRING_RUN 25630
@@ -30,10 +29,12 @@
 #define IDS_STRING_JSREADONLY 25636
 #define IDS_STRING_JSTYPEERROR 25637
 #define IDS_STRING_JSVALUEERROR 25638
+#define IDS_STRING_JSNOPERMISSION 25639
+#define IDS_STRING_JSBADOBJECT 25640
 
-CFX_WideString JSGetStringFromID(CJS_Context* pContext, FX_UINT id);
+CFX_WideString JSGetStringFromID(uint32_t id);
 CFX_WideString JSFormatErrorString(const char* class_name,
                                    const char* property_name,
                                    const CFX_WideString& details);
 
-#endif  // FPDFSDK_SRC_JAVASCRIPT_RESOURCE_H_
+#endif  // FPDFSDK_JAVASCRIPT_RESOURCE_H_
diff --git a/fpdfsdk/javascript/util.cpp b/fpdfsdk/javascript/util.cpp
new file mode 100644
index 0000000..3967ceb
--- /dev/null
+++ b/fpdfsdk/javascript/util.cpp
@@ -0,0 +1,472 @@
+// 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
+
+#include "fpdfsdk/javascript/util.h"
+
+#include <time.h>
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+#include "core/fxcrt/fx_ext.h"
+#include "fpdfsdk/javascript/JS_Define.h"
+#include "fpdfsdk/javascript/JS_EventHandler.h"
+#include "fpdfsdk/javascript/JS_Object.h"
+#include "fpdfsdk/javascript/JS_Value.h"
+#include "fpdfsdk/javascript/PublicMethods.h"
+#include "fpdfsdk/javascript/cjs_context.h"
+#include "fpdfsdk/javascript/cjs_runtime.h"
+#include "fpdfsdk/javascript/resource.h"
+
+#if _FX_OS_ == _FX_ANDROID_
+#include <ctype.h>
+#endif
+
+BEGIN_JS_STATIC_CONST(CJS_Util)
+END_JS_STATIC_CONST()
+
+BEGIN_JS_STATIC_PROP(CJS_Util)
+END_JS_STATIC_PROP()
+
+BEGIN_JS_STATIC_METHOD(CJS_Util)
+JS_STATIC_METHOD_ENTRY(printd)
+JS_STATIC_METHOD_ENTRY(printf)
+JS_STATIC_METHOD_ENTRY(printx)
+JS_STATIC_METHOD_ENTRY(scand)
+JS_STATIC_METHOD_ENTRY(byteToChar)
+END_JS_STATIC_METHOD()
+
+IMPLEMENT_JS_CLASS(CJS_Util, util)
+
+#define UTIL_INT 0
+#define UTIL_DOUBLE 1
+#define UTIL_STRING 2
+
+namespace {
+
+// Map PDF-style directives to equivalent wcsftime directives. Not
+// all have direct equivalents, though.
+struct TbConvert {
+  const FX_WCHAR* lpszJSMark;
+  const FX_WCHAR* lpszCppMark;
+};
+
+// Map PDF-style directives lacking direct wcsftime directives to
+// the value with which they will be replaced.
+struct TbConvertAdditional {
+  const FX_WCHAR* lpszJSMark;
+  int iValue;
+};
+
+const TbConvert TbConvertTable[] = {
+    {L"mmmm", L"%B"}, {L"mmm", L"%b"}, {L"mm", L"%m"},   {L"dddd", L"%A"},
+    {L"ddd", L"%a"},  {L"dd", L"%d"},  {L"yyyy", L"%Y"}, {L"yy", L"%y"},
+    {L"HH", L"%H"},   {L"hh", L"%I"},  {L"MM", L"%M"},   {L"ss", L"%S"},
+    {L"TT", L"%p"},
+#if defined(_WIN32)
+    {L"tt", L"%p"},   {L"h", L"%#I"},
+#else
+    {L"tt", L"%P"},   {L"h", L"%l"},
+#endif
+};
+
+int ParseDataType(std::wstring* sFormat) {
+  bool bPercent = false;
+  for (size_t i = 0; i < sFormat->length(); ++i) {
+    wchar_t c = (*sFormat)[i];
+    if (c == L'%') {
+      bPercent = true;
+      continue;
+    }
+
+    if (bPercent) {
+      if (c == L'c' || c == L'C' || c == L'd' || c == L'i' || c == L'o' ||
+          c == L'u' || c == L'x' || c == L'X') {
+        return UTIL_INT;
+      }
+      if (c == L'e' || c == L'E' || c == L'f' || c == L'g' || c == L'G') {
+        return UTIL_DOUBLE;
+      }
+      if (c == L's' || c == L'S') {
+        // Map s to S since we always deal internally
+        // with wchar_t strings.
+        (*sFormat)[i] = L'S';
+        return UTIL_STRING;
+      }
+      if (c == L'.' || c == L'+' || c == L'-' || c == L'#' || c == L' ' ||
+          FXSYS_iswdigit(c)) {
+        continue;
+      }
+      break;
+    }
+  }
+
+  return -1;
+}
+
+}  // namespace
+
+util::util(CJS_Object* pJSObject) : CJS_EmbedObj(pJSObject) {}
+
+util::~util() {}
+
+bool util::printf(IJS_Context* cc,
+                  const std::vector<CJS_Value>& params,
+                  CJS_Value& vRet,
+                  CFX_WideString& sError) {
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  int iSize = params.size();
+  if (iSize < 1)
+    return false;
+  std::wstring c_ConvChar(params[0].ToCFXWideString(pRuntime).c_str());
+  std::vector<std::wstring> c_strConvers;
+  int iOffset = 0;
+  int iOffend = 0;
+  c_ConvChar.insert(c_ConvChar.begin(), L'S');
+  while (iOffset != -1) {
+    iOffend = c_ConvChar.find(L"%", iOffset + 1);
+    std::wstring strSub;
+    if (iOffend == -1)
+      strSub = c_ConvChar.substr(iOffset);
+    else
+      strSub = c_ConvChar.substr(iOffset, iOffend - iOffset);
+    c_strConvers.push_back(strSub);
+    iOffset = iOffend;
+  }
+
+  std::wstring c_strResult;
+  std::wstring c_strFormat;
+  for (int iIndex = 0; iIndex < (int)c_strConvers.size(); iIndex++) {
+    c_strFormat = c_strConvers[iIndex];
+    if (iIndex == 0) {
+      c_strResult = c_strFormat;
+      continue;
+    }
+
+    CFX_WideString strSegment;
+    if (iIndex >= iSize) {
+      c_strResult += c_strFormat;
+      continue;
+    }
+
+    switch (ParseDataType(&c_strFormat)) {
+      case UTIL_INT:
+        strSegment.Format(c_strFormat.c_str(), params[iIndex].ToInt(pRuntime));
+        break;
+      case UTIL_DOUBLE:
+        strSegment.Format(c_strFormat.c_str(),
+                          params[iIndex].ToDouble(pRuntime));
+        break;
+      case UTIL_STRING:
+        strSegment.Format(c_strFormat.c_str(),
+                          params[iIndex].ToCFXWideString(pRuntime).c_str());
+        break;
+      default:
+        strSegment.Format(L"%S", c_strFormat.c_str());
+        break;
+    }
+    c_strResult += strSegment.GetBuffer(strSegment.GetLength() + 1);
+  }
+
+  c_strResult.erase(c_strResult.begin());
+  vRet = CJS_Value(pRuntime, c_strResult.c_str());
+  return true;
+}
+
+bool util::printd(IJS_Context* cc,
+                  const std::vector<CJS_Value>& params,
+                  CJS_Value& vRet,
+                  CFX_WideString& sError) {
+  int iSize = params.size();
+  if (iSize < 2)
+    return false;
+
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  CJS_Value p1 = params[0];
+  CJS_Value p2 = params[1];
+  CJS_Date jsDate;
+  if (!p2.ConvertToDate(pRuntime, jsDate)) {
+    sError = JSGetStringFromID(IDS_STRING_JSPRINT1);
+    return false;
+  }
+
+  if (!jsDate.IsValidDate(pRuntime)) {
+    sError = JSGetStringFromID(IDS_STRING_JSPRINT2);
+    return false;
+  }
+
+  if (p1.GetType() == CJS_Value::VT_number) {
+    CFX_WideString swResult;
+    switch (p1.ToInt(pRuntime)) {
+      case 0:
+        swResult.Format(L"D:%04d%02d%02d%02d%02d%02d", jsDate.GetYear(pRuntime),
+                        jsDate.GetMonth(pRuntime) + 1, jsDate.GetDay(pRuntime),
+                        jsDate.GetHours(pRuntime), jsDate.GetMinutes(pRuntime),
+                        jsDate.GetSeconds(pRuntime));
+        break;
+      case 1:
+        swResult.Format(L"%04d.%02d.%02d %02d:%02d:%02d",
+                        jsDate.GetYear(pRuntime), jsDate.GetMonth(pRuntime) + 1,
+                        jsDate.GetDay(pRuntime), jsDate.GetHours(pRuntime),
+                        jsDate.GetMinutes(pRuntime),
+                        jsDate.GetSeconds(pRuntime));
+        break;
+      case 2:
+        swResult.Format(L"%04d/%02d/%02d %02d:%02d:%02d",
+                        jsDate.GetYear(pRuntime), jsDate.GetMonth(pRuntime) + 1,
+                        jsDate.GetDay(pRuntime), jsDate.GetHours(pRuntime),
+                        jsDate.GetMinutes(pRuntime),
+                        jsDate.GetSeconds(pRuntime));
+        break;
+      default:
+        sError = JSGetStringFromID(IDS_STRING_JSVALUEERROR);
+        return false;
+    }
+
+    vRet = CJS_Value(pRuntime, swResult.c_str());
+    return true;
+  }
+
+  if (p1.GetType() == CJS_Value::VT_string) {
+    if (iSize > 2 && params[2].ToBool(pRuntime)) {
+      sError = JSGetStringFromID(IDS_STRING_JSNOTSUPPORT);
+      return false;  // currently, it doesn't support XFAPicture.
+    }
+
+    // Convert PDF-style format specifiers to wcsftime specifiers. Remove any
+    // pre-existing %-directives before inserting our own.
+    std::basic_string<wchar_t> cFormat = p1.ToCFXWideString(pRuntime).c_str();
+    cFormat.erase(std::remove(cFormat.begin(), cFormat.end(), '%'),
+                  cFormat.end());
+
+    for (size_t i = 0; i < FX_ArraySize(TbConvertTable); ++i) {
+      int iStart = 0;
+      int iEnd;
+      while ((iEnd = cFormat.find(TbConvertTable[i].lpszJSMark, iStart)) !=
+             -1) {
+        cFormat.replace(iEnd, FXSYS_wcslen(TbConvertTable[i].lpszJSMark),
+                        TbConvertTable[i].lpszCppMark);
+        iStart = iEnd;
+      }
+    }
+
+    int iYear = jsDate.GetYear(pRuntime);
+    int iMonth = jsDate.GetMonth(pRuntime);
+    int iDay = jsDate.GetDay(pRuntime);
+    int iHour = jsDate.GetHours(pRuntime);
+    int iMin = jsDate.GetMinutes(pRuntime);
+    int iSec = jsDate.GetSeconds(pRuntime);
+
+    TbConvertAdditional cTableAd[] = {
+        {L"m", iMonth + 1}, {L"d", iDay},
+        {L"H", iHour},      {L"h", iHour > 12 ? iHour - 12 : iHour},
+        {L"M", iMin},       {L"s", iSec},
+    };
+
+    for (size_t i = 0; i < FX_ArraySize(cTableAd); ++i) {
+      wchar_t tszValue[16];
+      CFX_WideString sValue;
+      sValue.Format(L"%d", cTableAd[i].iValue);
+      memcpy(tszValue, (wchar_t*)sValue.GetBuffer(sValue.GetLength() + 1),
+             (sValue.GetLength() + 1) * sizeof(wchar_t));
+
+      int iStart = 0;
+      int iEnd;
+      while ((iEnd = cFormat.find(cTableAd[i].lpszJSMark, iStart)) != -1) {
+        if (iEnd > 0) {
+          if (cFormat[iEnd - 1] == L'%') {
+            iStart = iEnd + 1;
+            continue;
+          }
+        }
+        cFormat.replace(iEnd, FXSYS_wcslen(cTableAd[i].lpszJSMark), tszValue);
+        iStart = iEnd;
+      }
+    }
+
+    struct tm time = {};
+    time.tm_year = iYear - 1900;
+    time.tm_mon = iMonth;
+    time.tm_mday = iDay;
+    time.tm_hour = iHour;
+    time.tm_min = iMin;
+    time.tm_sec = iSec;
+
+    wchar_t buf[64] = {};
+    wcsftime(buf, 64, cFormat.c_str(), &time);
+    cFormat = buf;
+    vRet = CJS_Value(pRuntime, cFormat.c_str());
+    return true;
+  }
+
+  sError = JSGetStringFromID(IDS_STRING_JSTYPEERROR);
+  return false;
+}
+
+bool util::printx(IJS_Context* cc,
+                  const std::vector<CJS_Value>& params,
+                  CJS_Value& vRet,
+                  CFX_WideString& sError) {
+  if (params.size() < 2) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  vRet = CJS_Value(pRuntime, printx(params[0].ToCFXWideString(pRuntime),
+                                    params[1].ToCFXWideString(pRuntime))
+                                 .c_str());
+
+  return true;
+}
+
+enum CaseMode { kPreserveCase, kUpperCase, kLowerCase };
+
+static FX_WCHAR TranslateCase(FX_WCHAR input, CaseMode eMode) {
+  if (eMode == kLowerCase && input >= 'A' && input <= 'Z')
+    return input | 0x20;
+  if (eMode == kUpperCase && input >= 'a' && input <= 'z')
+    return input & ~0x20;
+  return input;
+}
+
+CFX_WideString util::printx(const CFX_WideString& wsFormat,
+                            const CFX_WideString& wsSource) {
+  CFX_WideString wsResult;
+  FX_STRSIZE iSourceIdx = 0;
+  FX_STRSIZE iFormatIdx = 0;
+  CaseMode eCaseMode = kPreserveCase;
+  bool bEscaped = false;
+  while (iFormatIdx < wsFormat.GetLength()) {
+    if (bEscaped) {
+      bEscaped = false;
+      wsResult += wsFormat[iFormatIdx];
+      ++iFormatIdx;
+      continue;
+    }
+    switch (wsFormat[iFormatIdx]) {
+      case '\\': {
+        bEscaped = true;
+        ++iFormatIdx;
+      } break;
+      case '<': {
+        eCaseMode = kLowerCase;
+        ++iFormatIdx;
+      } break;
+      case '>': {
+        eCaseMode = kUpperCase;
+        ++iFormatIdx;
+      } break;
+      case '=': {
+        eCaseMode = kPreserveCase;
+        ++iFormatIdx;
+      } break;
+      case '?': {
+        if (iSourceIdx < wsSource.GetLength()) {
+          wsResult += TranslateCase(wsSource[iSourceIdx], eCaseMode);
+          ++iSourceIdx;
+        }
+        ++iFormatIdx;
+      } break;
+      case 'X': {
+        if (iSourceIdx < wsSource.GetLength()) {
+          if ((wsSource[iSourceIdx] >= '0' && wsSource[iSourceIdx] <= '9') ||
+              (wsSource[iSourceIdx] >= 'a' && wsSource[iSourceIdx] <= 'z') ||
+              (wsSource[iSourceIdx] >= 'A' && wsSource[iSourceIdx] <= 'Z')) {
+            wsResult += TranslateCase(wsSource[iSourceIdx], eCaseMode);
+            ++iFormatIdx;
+          }
+          ++iSourceIdx;
+        } else {
+          ++iFormatIdx;
+        }
+      } break;
+      case 'A': {
+        if (iSourceIdx < wsSource.GetLength()) {
+          if ((wsSource[iSourceIdx] >= 'a' && wsSource[iSourceIdx] <= 'z') ||
+              (wsSource[iSourceIdx] >= 'A' && wsSource[iSourceIdx] <= 'Z')) {
+            wsResult += TranslateCase(wsSource[iSourceIdx], eCaseMode);
+            ++iFormatIdx;
+          }
+          ++iSourceIdx;
+        } else {
+          ++iFormatIdx;
+        }
+      } break;
+      case '9': {
+        if (iSourceIdx < wsSource.GetLength()) {
+          if (wsSource[iSourceIdx] >= '0' && wsSource[iSourceIdx] <= '9') {
+            wsResult += wsSource[iSourceIdx];
+            ++iFormatIdx;
+          }
+          ++iSourceIdx;
+        } else {
+          ++iFormatIdx;
+        }
+      } break;
+      case '*': {
+        if (iSourceIdx < wsSource.GetLength()) {
+          wsResult += TranslateCase(wsSource[iSourceIdx], eCaseMode);
+          ++iSourceIdx;
+        } else {
+          ++iFormatIdx;
+        }
+      } break;
+      default: {
+        wsResult += wsFormat[iFormatIdx];
+        ++iFormatIdx;
+      } break;
+    }
+  }
+  return wsResult;
+}
+
+bool util::scand(IJS_Context* cc,
+                 const std::vector<CJS_Value>& params,
+                 CJS_Value& vRet,
+                 CFX_WideString& sError) {
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  int iSize = params.size();
+  if (iSize < 2)
+    return false;
+
+  CFX_WideString sFormat = params[0].ToCFXWideString(pRuntime);
+  CFX_WideString sDate = params[1].ToCFXWideString(pRuntime);
+  double dDate = JS_GetDateTime();
+  if (sDate.GetLength() > 0) {
+    dDate = CJS_PublicMethods::MakeRegularDate(sDate, sFormat, nullptr);
+  }
+
+  if (!JS_PortIsNan(dDate)) {
+    vRet = CJS_Value(pRuntime, CJS_Date(pRuntime, dDate));
+  } else {
+    vRet.SetNull(pRuntime);
+  }
+
+  return true;
+}
+
+bool util::byteToChar(IJS_Context* cc,
+                      const std::vector<CJS_Value>& params,
+                      CJS_Value& vRet,
+                      CFX_WideString& sError) {
+  if (params.size() < 1) {
+    sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+    return false;
+  }
+
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  int arg = params[0].ToInt(pRuntime);
+  if (arg < 0 || arg > 255) {
+    sError = JSGetStringFromID(IDS_STRING_JSVALUEERROR);
+    return false;
+  }
+
+  CFX_WideString wStr(static_cast<FX_WCHAR>(arg));
+  vRet = CJS_Value(pRuntime, wStr.c_str());
+  return true;
+}
diff --git a/fpdfsdk/javascript/util.h b/fpdfsdk/javascript/util.h
new file mode 100644
index 0000000..80763d1
--- /dev/null
+++ b/fpdfsdk/javascript/util.h
@@ -0,0 +1,59 @@
+// 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_JAVASCRIPT_UTIL_H_
+#define FPDFSDK_JAVASCRIPT_UTIL_H_
+
+#include <string>
+#include <vector>
+
+#include "fpdfsdk/javascript/JS_Define.h"
+
+class util : public CJS_EmbedObj {
+ public:
+  explicit util(CJS_Object* pJSObject);
+  ~util() override;
+
+  bool printd(IJS_Context* cc,
+              const std::vector<CJS_Value>& params,
+              CJS_Value& vRet,
+              CFX_WideString& sError);
+  bool printf(IJS_Context* cc,
+              const std::vector<CJS_Value>& params,
+              CJS_Value& vRet,
+              CFX_WideString& sError);
+  bool printx(IJS_Context* cc,
+              const std::vector<CJS_Value>& params,
+              CJS_Value& vRet,
+              CFX_WideString& sError);
+  bool scand(IJS_Context* cc,
+             const std::vector<CJS_Value>& params,
+             CJS_Value& vRet,
+             CFX_WideString& sError);
+  bool byteToChar(IJS_Context* cc,
+                  const std::vector<CJS_Value>& params,
+                  CJS_Value& vRet,
+                  CFX_WideString& sError);
+
+  static CFX_WideString printx(const CFX_WideString& cFormat,
+                               const CFX_WideString& cSource);
+};
+
+class CJS_Util : public CJS_Object {
+ public:
+  explicit CJS_Util(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_Util() override {}
+
+  DECLARE_JS_CLASS();
+
+  JS_STATIC_METHOD(printd, util);
+  JS_STATIC_METHOD(printf, util);
+  JS_STATIC_METHOD(printx, util);
+  JS_STATIC_METHOD(scand, util);
+  JS_STATIC_METHOD(byteToChar, util);
+};
+
+#endif  // FPDFSDK_JAVASCRIPT_UTIL_H_
diff --git a/fpdfsdk/pdfium.mk b/fpdfsdk/pdfium.mk
deleted file mode 100644
index e0dc7f6..0000000
--- a/fpdfsdk/pdfium.mk
+++ /dev/null
@@ -1,69 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libpdfium
-
-LOCAL_ARM_MODE := arm
-LOCAL_NDK_STL_VARIANT := gnustl_static
-
-LOCAL_CFLAGS += -O3 -fstrict-aliasing -fprefetch-loop-arrays -fexceptions
-LOCAL_CFLAGS += -Wno-non-virtual-dtor -Wall -DOPJ_STATIC \
-                -DV8_DEPRECATION_WARNINGS -D_CRT_SECURE_NO_WARNINGS
-
-# Mask some warnings. These are benign, but we probably want to fix them
-# upstream at some point.
-LOCAL_CFLAGS += -Wno-sign-compare -Wno-unused-parameter
-LOCAL_CLANG_CFLAGS += -Wno-sign-compare
-
-LOCAL_STATIC_LIBRARIES := libpdfiumformfiller \
-                          libpdfiumpdfwindow \
-                          libpdfiumjavascript \
-                          libpdfiumfpdfapi \
-                          libpdfiumfxge \
-                          libpdfiumfxedit \
-                          libpdfiumfpdftext \
-                          libpdfiumfxcrt \
-                          libpdfiumfxcodec \
-                          libpdfiumfpdfdoc \
-                          libpdfiumfdrm \
-                          libpdfiumagg23 \
-                          libpdfiumbigint \
-                          libpdfiumlcms \
-                          libpdfiumjpeg \
-                          libpdfiumopenjpeg \
-                          libpdfiumzlib
-
-
-# TODO: figure out why turning on exceptions requires manually linking libdl
-LOCAL_SHARED_LIBRARIES := libdl libft2
-
-LOCAL_SRC_FILES := \
-    src/fpdf_dataavail.cpp \
-    src/fpdf_ext.cpp \
-    src/fpdf_flatten.cpp \
-    src/fpdf_progressive.cpp \
-    src/fpdf_searchex.cpp \
-    src/fpdf_sysfontinfo.cpp \
-    src/fpdf_transformpage.cpp \
-    src/fpdfdoc.cpp \
-    src/fpdfeditimg.cpp \
-    src/fpdfeditpage.cpp \
-    src/fpdfformfill.cpp \
-    src/fpdfppo.cpp \
-    src/fpdfsave.cpp \
-    src/fpdftext.cpp \
-    src/fpdfview.cpp \
-    src/fsdk_actionhandler.cpp \
-    src/fsdk_annothandler.cpp \
-    src/fsdk_baseannot.cpp \
-    src/fsdk_baseform.cpp \
-    src/fsdk_mgr.cpp \
-    src/fsdk_rendercontext.cpp
-
-LOCAL_C_INCLUDES := \
-    external/pdfium \
-    external/freetype/include \
-    external/freetype/include/freetype
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/fpdfsdk/pdfiumformfiller.mk b/fpdfsdk/pdfiumformfiller.mk
deleted file mode 100644
index e5abfaf..0000000
--- a/fpdfsdk/pdfiumformfiller.mk
+++ /dev/null
@@ -1,35 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE:= libpdfiumformfiller
-
-LOCAL_ARM_MODE := arm
-LOCAL_NDK_STL_VARIANT := gnustl_static
-
-LOCAL_CFLAGS += -O3 -fstrict-aliasing -fprefetch-loop-arrays -fexceptions
-LOCAL_CFLAGS += -Wno-non-virtual-dtor -Wall -DOPJ_STATIC \
-                -DV8_DEPRECATION_WARNINGS -D_CRT_SECURE_NO_WARNINGS
-
-# Mask some warnings. These are benign, but we probably want to fix them
-# upstream at some point.
-LOCAL_CFLAGS += -Wno-sign-compare -Wno-unused-parameter
-LOCAL_CLANG_CFLAGS += -Wno-sign-compare
-
-LOCAL_SRC_FILES := \
-    src/formfiller/FFL_CBA_Fontmap.cpp \
-    src/formfiller/FFL_CheckBox.cpp \
-    src/formfiller/FFL_ComboBox.cpp \
-    src/formfiller/FFL_FormFiller.cpp \
-    src/formfiller/FFL_IFormFiller.cpp \
-    src/formfiller/FFL_ListBox.cpp \
-    src/formfiller/FFL_PushButton.cpp \
-    src/formfiller/FFL_RadioButton.cpp \
-    src/formfiller/FFL_TextField.cpp
-
-LOCAL_C_INCLUDES := \
-    external/pdfium \
-    external/freetype/include \
-    external/freetype/include/freetype
-
-include $(BUILD_STATIC_LIBRARY)
diff --git a/fpdfsdk/pdfiumfxedit.mk b/fpdfsdk/pdfiumfxedit.mk
deleted file mode 100644
index 5a51af8..0000000
--- a/fpdfsdk/pdfiumfxedit.mk
+++ /dev/null
@@ -1,30 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE:= libpdfiumfxedit
-
-LOCAL_ARM_MODE := arm
-LOCAL_NDK_STL_VARIANT := gnustl_static
-
-LOCAL_CFLAGS += -O3 -fstrict-aliasing -fprefetch-loop-arrays -fexceptions
-LOCAL_CFLAGS += -Wno-non-virtual-dtor -Wall -DOPJ_STATIC \
-                -DV8_DEPRECATION_WARNINGS -D_CRT_SECURE_NO_WARNINGS
-
-# Mask some warnings. These are benign, but we probably want to fix them
-# upstream at some point.
-LOCAL_CFLAGS += -Wno-sign-compare -Wno-unused-parameter
-LOCAL_CLANG_CFLAGS += -Wno-sign-compare
-
-LOCAL_SRC_FILES := \
-    src/fxedit/fxet_ap.cpp \
-    src/fxedit/fxet_edit.cpp \
-    src/fxedit/fxet_list.cpp \
-    src/fxedit/fxet_module.cpp \
-    src/fxedit/fxet_pageobjs.cpp
-
-LOCAL_C_INCLUDES := \
-    external/pdfium \
-    external/freetype/include \
-    external/freetype/include/freetype
-include $(BUILD_STATIC_LIBRARY)
diff --git a/fpdfsdk/pdfiumjavascript.mk b/fpdfsdk/pdfiumjavascript.mk
deleted file mode 100644
index 9f39f73..0000000
--- a/fpdfsdk/pdfiumjavascript.mk
+++ /dev/null
@@ -1,27 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE:= libpdfiumjavascript
-
-LOCAL_ARM_MODE := arm
-LOCAL_NDK_STL_VARIANT := gnustl_static
-
-LOCAL_CFLAGS += -O3 -fstrict-aliasing -fprefetch-loop-arrays -fexceptions
-LOCAL_CFLAGS += -Wno-non-virtual-dtor -Wall -DOPJ_STATIC \
-                -DV8_DEPRECATION_WARNINGS -D_CRT_SECURE_NO_WARNINGS
-
-# Mask some warnings. These are benign, but we probably want to fix them
-# upstream at some point.
-LOCAL_CFLAGS += -Wno-sign-compare -Wno-unused-parameter
-LOCAL_CLANG_CFLAGS += -Wno-sign-compare
-
-LOCAL_SRC_FILES := \
-    src/javascript/JS_Runtime_Stub.cpp
-
-LOCAL_C_INCLUDES := \
-    external/pdfium \
-    external/freetype/include \
-    external/freetype/include/freetype
-
-include $(BUILD_STATIC_LIBRARY)
diff --git a/fpdfsdk/pdfiumpdfwindow.mk b/fpdfsdk/pdfiumpdfwindow.mk
deleted file mode 100644
index 3932ba4..0000000
--- a/fpdfsdk/pdfiumpdfwindow.mk
+++ /dev/null
@@ -1,43 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE:= libpdfiumpdfwindow
-
-LOCAL_ARM_MODE := arm
-LOCAL_NDK_STL_VARIANT := gnustl_static
-
-LOCAL_CFLAGS += -O3 -fstrict-aliasing -fprefetch-loop-arrays -fexceptions
-LOCAL_CFLAGS += -Wno-non-virtual-dtor -Wall -DOPJ_STATIC \
-                -DV8_DEPRECATION_WARNINGS -D_CRT_SECURE_NO_WARNINGS
-
-# Mask some warnings. These are benign, but we probably want to fix them
-# upstream at some point.
-LOCAL_CFLAGS += -Wno-sign-compare -Wno-unused-parameter
-LOCAL_CLANG_CFLAGS += -Wno-sign-compare
-
-LOCAL_SRC_FILES := \
-    src/pdfwindow/PWL_Button.cpp \
-    src/pdfwindow/PWL_Caret.cpp \
-    src/pdfwindow/PWL_ComboBox.cpp \
-    src/pdfwindow/PWL_Edit.cpp \
-    src/pdfwindow/PWL_EditCtrl.cpp \
-    src/pdfwindow/PWL_FontMap.cpp \
-    src/pdfwindow/PWL_Icon.cpp \
-    src/pdfwindow/PWL_IconList.cpp \
-    src/pdfwindow/PWL_Label.cpp \
-    src/pdfwindow/PWL_ListBox.cpp \
-    src/pdfwindow/PWL_ListCtrl.cpp \
-    src/pdfwindow/PWL_Note.cpp \
-    src/pdfwindow/PWL_ScrollBar.cpp \
-    src/pdfwindow/PWL_Signature.cpp \
-    src/pdfwindow/PWL_SpecialButton.cpp \
-    src/pdfwindow/PWL_Utils.cpp \
-    src/pdfwindow/PWL_Wnd.cpp
-
-LOCAL_C_INCLUDES := \
-    external/pdfium \
-    external/freetype/include \
-    external/freetype/include/freetype
-
-include $(BUILD_STATIC_LIBRARY)
diff --git a/fpdfsdk/pdfsdk_fieldaction.cpp b/fpdfsdk/pdfsdk_fieldaction.cpp
new file mode 100644
index 0000000..61228ea
--- /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/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/fpdfsdk/pdfsdk_fieldaction.h b/fpdfsdk/pdfsdk_fieldaction.h
new file mode 100644
index 0000000..4ee56ac
--- /dev/null
+++ b/fpdfsdk/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_PDFSDK_FIELDACTION_H_
+#define FPDFSDK_PDFSDK_FIELDACTION_H_
+
+#include "core/fxcrt/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;
+
+  bool bModifier;
+  bool bShift;
+  int nCommitKey;
+  CFX_WideString sChange;
+  CFX_WideString sChangeEx;
+  bool bKeyDown;
+  int nSelEnd;
+  int nSelStart;
+  CFX_WideString sValue;
+  bool bWillCommit;
+  bool bFieldFull;
+  bool bRC;
+};
+
+#endif  // FPDFSDK_PDFSDK_FIELDACTION_H_
diff --git a/fpdfsdk/pdfwindow/PWL_Button.cpp b/fpdfsdk/pdfwindow/PWL_Button.cpp
new file mode 100644
index 0000000..972e55e
--- /dev/null
+++ b/fpdfsdk/pdfwindow/PWL_Button.cpp
@@ -0,0 +1,39 @@
+// 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
+
+#include "fpdfsdk/pdfwindow/PWL_Button.h"
+#include "fpdfsdk/pdfwindow/PWL_Utils.h"
+#include "fpdfsdk/pdfwindow/PWL_Wnd.h"
+
+CPWL_Button::CPWL_Button() : m_bMouseDown(false) {}
+
+CPWL_Button::~CPWL_Button() {}
+
+CFX_ByteString CPWL_Button::GetClassName() const {
+  return "CPWL_Button";
+}
+
+void CPWL_Button::OnCreate(PWL_CREATEPARAM& cp) {
+  cp.eCursorType = FXCT_HAND;
+}
+
+bool CPWL_Button::OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag) {
+  CPWL_Wnd::OnLButtonDown(point, nFlag);
+
+  m_bMouseDown = true;
+  SetCapture();
+
+  return true;
+}
+
+bool CPWL_Button::OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) {
+  CPWL_Wnd::OnLButtonUp(point, nFlag);
+
+  ReleaseCapture();
+  m_bMouseDown = false;
+
+  return true;
+}
diff --git a/fpdfsdk/pdfwindow/PWL_Button.h b/fpdfsdk/pdfwindow/PWL_Button.h
new file mode 100644
index 0000000..f35e9ad
--- /dev/null
+++ b/fpdfsdk/pdfwindow/PWL_Button.h
@@ -0,0 +1,27 @@
+// 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_PDFWINDOW_PWL_BUTTON_H_
+#define FPDFSDK_PDFWINDOW_PWL_BUTTON_H_
+
+#include "fpdfsdk/pdfwindow/PWL_Wnd.h"
+
+class CPWL_Button : public CPWL_Wnd {
+ public:
+  CPWL_Button();
+  ~CPWL_Button() override;
+
+  // CPWL_Wnd
+  CFX_ByteString GetClassName() const override;
+  void OnCreate(PWL_CREATEPARAM& cp) override;
+  bool OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag) override;
+  bool OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) override;
+
+ protected:
+  bool m_bMouseDown;
+};
+
+#endif  // FPDFSDK_PDFWINDOW_PWL_BUTTON_H_
diff --git a/fpdfsdk/src/pdfwindow/PWL_Caret.cpp b/fpdfsdk/pdfwindow/PWL_Caret.cpp
similarity index 66%
rename from fpdfsdk/src/pdfwindow/PWL_Caret.cpp
rename to fpdfsdk/pdfwindow/PWL_Caret.cpp
index 75c9510..8a5f539 100644
--- a/fpdfsdk/src/pdfwindow/PWL_Caret.cpp
+++ b/fpdfsdk/pdfwindow/PWL_Caret.cpp
@@ -4,18 +4,17 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#include "fpdfsdk/include/pdfwindow/PWL_Caret.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Wnd.h"
+#include "fpdfsdk/pdfwindow/PWL_Caret.h"
+
+#include "core/fxge/cfx_graphstatedata.h"
+#include "core/fxge/cfx_pathdata.h"
+#include "core/fxge/cfx_renderdevice.h"
+#include "fpdfsdk/pdfwindow/PWL_Utils.h"
+#include "fpdfsdk/pdfwindow/PWL_Wnd.h"
 
 #define PWL_CARET_FLASHINTERVAL 500
 
-CPWL_Caret::CPWL_Caret()
-    : m_bFlash(FALSE),
-      m_ptHead(0, 0),
-      m_ptFoot(0, 0),
-      m_fWidth(0.4f),
-      m_nDelay(0) {}
+CPWL_Caret::CPWL_Caret() : m_bFlash(false), m_fWidth(0.4f), m_nDelay(0) {}
 
 CPWL_Caret::~CPWL_Caret() {}
 
@@ -24,23 +23,20 @@
 }
 
 void CPWL_Caret::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) {
-  GetCaretApp(sAppStream, CPDF_Point(0.0f, 0.0f));
+  GetCaretApp(sAppStream, CFX_FloatPoint(0.0f, 0.0f));
 }
 
 void CPWL_Caret::DrawThisAppearance(CFX_RenderDevice* pDevice,
                                     CFX_Matrix* pUser2Device) {
   if (IsVisible() && m_bFlash) {
-    CPDF_Rect rcRect = GetCaretRect();
-    CPDF_Rect rcClip = GetClipRect();
-
+    CFX_FloatRect rcRect = GetCaretRect();
+    CFX_FloatRect rcClip = GetClipRect();
     CFX_PathData path;
-
     path.SetPointCount(2);
 
     FX_FLOAT fCaretX = rcRect.left + m_fWidth * 0.5f;
     FX_FLOAT fCaretTop = rcRect.top;
     FX_FLOAT fCaretBottom = rcRect.bottom;
-
     if (!rcClip.IsEmpty()) {
       rcRect.Intersect(rcClip);
       if (!rcRect.IsEmpty()) {
@@ -58,19 +54,18 @@
 
     CFX_GraphStateData gsd;
     gsd.m_LineWidth = m_fWidth;
-
     pDevice->DrawPath(&path, pUser2Device, &gsd, 0, ArgbEncode(255, 0, 0, 0),
                       FXFILL_ALTERNATE);
   }
 }
 
 void CPWL_Caret::GetCaretApp(CFX_ByteTextBuf& sAppStream,
-                             const CPDF_Point& ptOffset) {
+                             const CFX_FloatPoint& ptOffset) {
   if (IsVisible() && m_bFlash) {
     CFX_ByteTextBuf sCaret;
 
-    CPDF_Rect rcRect = GetCaretRect();
-    CPDF_Rect rcClip = GetClipRect();
+    CFX_FloatRect rcRect = GetCaretRect();
+    CFX_FloatRect rcClip = GetClipRect();
 
     rcRect = CPWL_Utils::OffsetRect(rcRect, ptOffset.x, ptOffset.y);
     rcClip = CPWL_Utils::OffsetRect(rcClip, ptOffset.x, ptOffset.y);
@@ -90,10 +85,10 @@
 }
 
 CFX_ByteString CPWL_Caret::GetCaretAppearanceStream(
-    const CPDF_Point& ptOffset) {
+    const CFX_FloatPoint& ptOffset) {
   CFX_ByteTextBuf sCaret;
   GetCaretApp(sCaret, ptOffset);
-  return sCaret.GetByteString();
+  return sCaret.MakeString();
 }
 
 void CPWL_Caret::TimerProc() {
@@ -105,53 +100,47 @@
   }
 }
 
-CPDF_Rect CPWL_Caret::GetCaretRect() const {
-  return CPDF_Rect(m_ptFoot.x, m_ptFoot.y, m_ptHead.x + m_fWidth, m_ptHead.y);
+CFX_FloatRect CPWL_Caret::GetCaretRect() const {
+  return CFX_FloatRect(m_ptFoot.x, m_ptFoot.y, m_ptHead.x + m_fWidth,
+                       m_ptHead.y);
 }
 
-void CPWL_Caret::SetCaret(FX_BOOL bVisible,
-                          const CPDF_Point& ptHead,
-                          const CPDF_Point& ptFoot) {
+void CPWL_Caret::SetCaret(bool bVisible,
+                          const CFX_FloatPoint& ptHead,
+                          const CFX_FloatPoint& ptFoot) {
   if (bVisible) {
     if (IsVisible()) {
-      if (m_ptHead.x != ptHead.x || m_ptHead.y != ptHead.y ||
-          m_ptFoot.x != ptFoot.x || m_ptFoot.y != ptFoot.y) {
+      if (m_ptHead != ptHead || m_ptFoot != ptFoot) {
         m_ptHead = ptHead;
         m_ptFoot = ptFoot;
-
-        m_bFlash = TRUE;
-        Move(m_rcInvalid, FALSE, TRUE);
+        m_bFlash = true;
+        Move(m_rcInvalid, false, true);
       }
     } else {
       m_ptHead = ptHead;
       m_ptFoot = ptFoot;
-
       EndTimer();
       BeginTimer(PWL_CARET_FLASHINTERVAL);
-
-      CPWL_Wnd::SetVisible(TRUE);
-      m_bFlash = TRUE;
-
-      Move(m_rcInvalid, FALSE, TRUE);
+      CPWL_Wnd::SetVisible(true);
+      m_bFlash = true;
+      Move(m_rcInvalid, false, true);
     }
   } else {
-    m_ptHead = CPDF_Point(0, 0);
-    m_ptFoot = CPDF_Point(0, 0);
-
-    m_bFlash = FALSE;
+    m_ptHead = CFX_FloatPoint();
+    m_ptFoot = CFX_FloatPoint();
+    m_bFlash = false;
     if (IsVisible()) {
       EndTimer();
-      CPWL_Wnd::SetVisible(FALSE);
+      CPWL_Wnd::SetVisible(false);
     }
   }
 }
 
-void CPWL_Caret::InvalidateRect(CPDF_Rect* pRect) {
+void CPWL_Caret::InvalidateRect(CFX_FloatRect* pRect) {
   if (pRect) {
-    CPDF_Rect rcRefresh = CPWL_Utils::InflateRect(*pRect, 0.5f);
+    CFX_FloatRect rcRefresh = CPWL_Utils::InflateRect(*pRect, 0.5f);
     rcRefresh.top += 1;
     rcRefresh.bottom -= 1;
-
     CPWL_Wnd::InvalidateRect(&rcRefresh);
   } else {
     CPWL_Wnd::InvalidateRect(pRect);
diff --git a/fpdfsdk/pdfwindow/PWL_Caret.h b/fpdfsdk/pdfwindow/PWL_Caret.h
new file mode 100644
index 0000000..ccee961
--- /dev/null
+++ b/fpdfsdk/pdfwindow/PWL_Caret.h
@@ -0,0 +1,53 @@
+// 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_PDFWINDOW_PWL_CARET_H_
+#define FPDFSDK_PDFWINDOW_PWL_CARET_H_
+
+#include "fpdfsdk/pdfwindow/PWL_Wnd.h"
+
+struct PWL_CARET_INFO {
+ public:
+  PWL_CARET_INFO() : bVisible(false) {}
+
+  bool bVisible;
+  CFX_FloatPoint ptHead;
+  CFX_FloatPoint ptFoot;
+};
+
+class CPWL_Caret : public CPWL_Wnd {
+ public:
+  CPWL_Caret();
+  ~CPWL_Caret() override;
+
+  // CPWL_Wnd
+  CFX_ByteString GetClassName() const override;
+  void GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) override;
+  void DrawThisAppearance(CFX_RenderDevice* pDevice,
+                          CFX_Matrix* pUser2Device) override;
+  void InvalidateRect(CFX_FloatRect* pRect = nullptr) override;
+  void SetVisible(bool bVisible) override {}
+  void TimerProc() override;
+
+  void SetCaret(bool bVisible,
+                const CFX_FloatPoint& ptHead,
+                const CFX_FloatPoint& ptFoot);
+  CFX_ByteString GetCaretAppearanceStream(const CFX_FloatPoint& ptOffset);
+  void SetInvalidRect(CFX_FloatRect rc) { m_rcInvalid = rc; }
+
+ private:
+  void GetCaretApp(CFX_ByteTextBuf& sAppStream, const CFX_FloatPoint& ptOffset);
+  CFX_FloatRect GetCaretRect() const;
+
+  bool m_bFlash;
+  CFX_FloatPoint m_ptHead;
+  CFX_FloatPoint m_ptFoot;
+  FX_FLOAT m_fWidth;
+  int32_t m_nDelay;
+  CFX_FloatRect m_rcInvalid;
+};
+
+#endif  // FPDFSDK_PDFWINDOW_PWL_CARET_H_
diff --git a/fpdfsdk/src/pdfwindow/PWL_ComboBox.cpp b/fpdfsdk/pdfwindow/PWL_ComboBox.cpp
similarity index 70%
rename from fpdfsdk/src/pdfwindow/PWL_ComboBox.cpp
rename to fpdfsdk/pdfwindow/PWL_ComboBox.cpp
index 7582ae4..8e9a04b 100644
--- a/fpdfsdk/src/pdfwindow/PWL_ComboBox.cpp
+++ b/fpdfsdk/pdfwindow/PWL_ComboBox.cpp
@@ -4,54 +4,44 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#include "fpdfsdk/include/pdfwindow/PWL_ComboBox.h"
+#include "fpdfsdk/pdfwindow/PWL_ComboBox.h"
 
-#include "fpdfsdk/include/pdfwindow/PWL_Edit.h"
-#include "fpdfsdk/include/pdfwindow/PWL_EditCtrl.h"
-#include "fpdfsdk/include/pdfwindow/PWL_ListBox.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Wnd.h"
+#include "core/fxge/cfx_pathdata.h"
+#include "core/fxge/cfx_renderdevice.h"
+#include "fpdfsdk/fxedit/fxet_list.h"
+#include "fpdfsdk/pdfwindow/PWL_Edit.h"
+#include "fpdfsdk/pdfwindow/PWL_EditCtrl.h"
+#include "fpdfsdk/pdfwindow/PWL_ListBox.h"
+#include "fpdfsdk/pdfwindow/PWL_Utils.h"
+#include "fpdfsdk/pdfwindow/PWL_Wnd.h"
 #include "public/fpdf_fwlevent.h"
 
 #define PWLCB_DEFAULTFONTSIZE 12.0f
 
-#define IsFloatZero(f) ((f) < 0.0001 && (f) > -0.0001)
-#define IsFloatBigger(fa, fb) ((fa) > (fb) && !IsFloatZero((fa) - (fb)))
-#define IsFloatSmaller(fa, fb) ((fa) < (fb) && !IsFloatZero((fa) - (fb)))
-#define IsFloatEqual(fa, fb) IsFloatZero((fa) - (fb))
-
-FX_BOOL CPWL_CBListBox::OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag) {
+bool CPWL_CBListBox::OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) {
   CPWL_Wnd::OnLButtonUp(point, nFlag);
 
-  if (m_bMouseDown) {
-    ReleaseCapture();
-    m_bMouseDown = FALSE;
+  if (!m_bMouseDown)
+    return true;
 
-    if (ClientHitTest(point)) {
-      if (CPWL_Wnd* pParent = GetParentWindow()) {
-        pParent->OnNotify(this, PNM_LBUTTONUP, 0,
-                          PWL_MAKEDWORD(point.x, point.y));
-      }
+  ReleaseCapture();
+  m_bMouseDown = false;
 
-      FX_BOOL bExit = FALSE;
-      OnNotifySelChanged(FALSE, bExit, nFlag);
-      if (bExit)
-        return FALSE;
-    }
-  }
+  if (!ClientHitTest(point))
+    return true;
+  if (CPWL_Wnd* pParent = GetParentWindow())
+    pParent->OnNotify(this, PNM_LBUTTONUP, 0, PWL_MAKEDWORD(point.x, point.y));
 
-  return TRUE;
+  bool bExit = false;
+  OnNotifySelChanged(false, bExit, nFlag);
+
+  return !bExit;
 }
 
-FX_BOOL CPWL_CBListBox::OnKeyDownWithExit(FX_WORD nChar,
-                                          FX_BOOL& bExit,
-                                          FX_DWORD nFlag) {
-  if (!m_pList)
-    return FALSE;
-
+bool CPWL_CBListBox::OnKeyDownWithExit(uint16_t nChar,
+                                       bool& bExit,
+                                       uint32_t nFlag) {
   switch (nChar) {
-    default:
-      return FALSE;
     case FWL_VKEY_Up:
     case FWL_VKEY_Down:
     case FWL_VKEY_Home:
@@ -59,6 +49,8 @@
     case FWL_VKEY_End:
     case FWL_VKEY_Right:
       break;
+    default:
+      return false;
   }
 
   switch (nChar) {
@@ -84,45 +76,40 @@
       break;
   }
 
-  OnNotifySelChanged(TRUE, bExit, nFlag);
+  OnNotifySelChanged(true, bExit, nFlag);
 
-  return TRUE;
+  return true;
 }
 
-FX_BOOL CPWL_CBListBox::OnCharWithExit(FX_WORD nChar,
-                                       FX_BOOL& bExit,
-                                       FX_DWORD nFlag) {
-  if (!m_pList)
-    return FALSE;
-
+bool CPWL_CBListBox::OnCharWithExit(uint16_t nChar,
+                                    bool& bExit,
+                                    uint32_t nFlag) {
   if (!m_pList->OnChar(nChar, IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag)))
-    return FALSE;
-
-  if (CPWL_ComboBox* pComboBox = (CPWL_ComboBox*)GetParentWindow()) {
+    return false;
+  if (CPWL_ComboBox* pComboBox = (CPWL_ComboBox*)GetParentWindow())
     pComboBox->SetSelectText();
-  }
 
-  OnNotifySelChanged(TRUE, bExit, nFlag);
+  OnNotifySelChanged(true, bExit, nFlag);
 
-  return TRUE;
+  return true;
 }
 
 void CPWL_CBButton::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) {
   CPWL_Wnd::GetThisAppearanceStream(sAppStream);
 
-  CPDF_Rect rectWnd = CPWL_Wnd::GetWindowRect();
+  CFX_FloatRect rectWnd = CPWL_Wnd::GetWindowRect();
 
   if (IsVisible() && !rectWnd.IsEmpty()) {
     CFX_ByteTextBuf sButton;
 
-    CPDF_Point ptCenter = GetCenterPoint();
+    CFX_FloatPoint ptCenter = GetCenterPoint();
 
-    CPDF_Point pt1(ptCenter.x - PWL_CBBUTTON_TRIANGLE_HALFLEN,
-                   ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
-    CPDF_Point pt2(ptCenter.x + PWL_CBBUTTON_TRIANGLE_HALFLEN,
-                   ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
-    CPDF_Point pt3(ptCenter.x,
-                   ptCenter.y - PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
+    CFX_FloatPoint pt1(ptCenter.x - PWL_CBBUTTON_TRIANGLE_HALFLEN,
+                       ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
+    CFX_FloatPoint pt2(ptCenter.x + PWL_CBBUTTON_TRIANGLE_HALFLEN,
+                       ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
+    CFX_FloatPoint pt3(ptCenter.x,
+                       ptCenter.y - PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
 
     if (IsFloatBigger(rectWnd.right - rectWnd.left,
                       PWL_CBBUTTON_TRIANGLE_HALFLEN * 2) &&
@@ -143,17 +130,17 @@
                                        CFX_Matrix* pUser2Device) {
   CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device);
 
-  CPDF_Rect rectWnd = CPWL_Wnd::GetWindowRect();
+  CFX_FloatRect rectWnd = CPWL_Wnd::GetWindowRect();
 
   if (IsVisible() && !rectWnd.IsEmpty()) {
-    CPDF_Point ptCenter = GetCenterPoint();
+    CFX_FloatPoint ptCenter = GetCenterPoint();
 
-    CPDF_Point pt1(ptCenter.x - PWL_CBBUTTON_TRIANGLE_HALFLEN,
-                   ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
-    CPDF_Point pt2(ptCenter.x + PWL_CBBUTTON_TRIANGLE_HALFLEN,
-                   ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
-    CPDF_Point pt3(ptCenter.x,
-                   ptCenter.y - PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
+    CFX_FloatPoint pt1(ptCenter.x - PWL_CBBUTTON_TRIANGLE_HALFLEN,
+                       ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
+    CFX_FloatPoint pt2(ptCenter.x + PWL_CBBUTTON_TRIANGLE_HALFLEN,
+                       ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
+    CFX_FloatPoint pt3(ptCenter.x,
+                       ptCenter.y - PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
 
     if (IsFloatBigger(rectWnd.right - rectWnd.left,
                       PWL_CBBUTTON_TRIANGLE_HALFLEN * 2) &&
@@ -167,7 +154,7 @@
       path.SetPoint(2, pt3.x, pt3.y, FXPT_LINETO);
       path.SetPoint(3, pt1.x, pt1.y, FXPT_LINETO);
 
-      pDevice->DrawPath(&path, pUser2Device, NULL,
+      pDevice->DrawPath(&path, pUser2Device, nullptr,
                         CPWL_Utils::PWLColorToFXColor(PWL_DEFAULT_BLACKCOLOR,
                                                       GetTransparency()),
                         0, FXFILL_ALTERNATE);
@@ -175,7 +162,7 @@
   }
 }
 
-FX_BOOL CPWL_CBButton::OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) {
+bool CPWL_CBButton::OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag) {
   CPWL_Wnd::OnLButtonDown(point, nFlag);
 
   SetCapture();
@@ -185,25 +172,25 @@
                       PWL_MAKEDWORD(point.x, point.y));
   }
 
-  return TRUE;
+  return true;
 }
 
-FX_BOOL CPWL_CBButton::OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag) {
+bool CPWL_CBButton::OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) {
   CPWL_Wnd::OnLButtonUp(point, nFlag);
 
   ReleaseCapture();
 
-  return TRUE;
+  return true;
 }
 
 CPWL_ComboBox::CPWL_ComboBox()
-    : m_pEdit(NULL),
-      m_pButton(NULL),
-      m_pList(NULL),
-      m_bPopup(FALSE),
+    : m_pEdit(nullptr),
+      m_pButton(nullptr),
+      m_pList(nullptr),
+      m_bPopup(false),
       m_nPopupWhere(0),
       m_nSelectItem(-1),
-      m_pFillerNotify(NULL) {}
+      m_pFillerNotify(nullptr) {}
 
 CFX_ByteString CPWL_ComboBox::GetClassName() const {
   return "CPWL_ComboBox";
@@ -220,7 +207,7 @@
 }
 
 void CPWL_ComboBox::KillFocus() {
-  SetPopup(FALSE);
+  SetPopup(false);
   CPWL_Wnd::KillFocus();
 }
 
@@ -231,14 +218,14 @@
   return CFX_WideString();
 }
 
-void CPWL_ComboBox::SetText(const FX_WCHAR* text) {
+void CPWL_ComboBox::SetText(const CFX_WideString& text) {
   if (m_pEdit)
     m_pEdit->SetText(text);
 }
 
-void CPWL_ComboBox::AddString(const FX_WCHAR* string) {
+void CPWL_ComboBox::AddString(const CFX_WideString& str) {
   if (m_pList)
-    m_pList->AddString(string);
+    m_pList->AddString(str);
 }
 
 int32_t CPWL_ComboBox::GetSelect() const {
@@ -249,30 +236,26 @@
   if (m_pList)
     m_pList->Select(nItemIndex);
 
-  m_pEdit->SetText(m_pList->GetText().c_str());
-
+  m_pEdit->SetText(m_pList->GetText());
   m_nSelectItem = nItemIndex;
 }
 
 void CPWL_ComboBox::SetEditSel(int32_t nStartChar, int32_t nEndChar) {
-  if (m_pEdit) {
+  if (m_pEdit)
     m_pEdit->SetSel(nStartChar, nEndChar);
-  }
 }
 
 void CPWL_ComboBox::GetEditSel(int32_t& nStartChar, int32_t& nEndChar) const {
   nStartChar = -1;
   nEndChar = -1;
 
-  if (m_pEdit) {
+  if (m_pEdit)
     m_pEdit->GetSel(nStartChar, nEndChar);
-  }
 }
 
 void CPWL_ComboBox::Clear() {
-  if (m_pEdit) {
+  if (m_pEdit)
     m_pEdit->Clear();
-  }
 }
 
 void CPWL_ComboBox::CreateChildWnd(const PWL_CREATEPARAM& cp) {
@@ -297,9 +280,9 @@
     if (!HasFlag(PCBS_ALLOWCUSTOMTEXT))
       ecp.dwFlags |= PWS_READONLY;
 
-    ecp.rcRectWnd = CPDF_Rect(0, 0, 0, 0);
+    ecp.rcRectWnd = CFX_FloatRect(0, 0, 0, 0);
     ecp.dwBorderWidth = 0;
-    ecp.nBorderStyle = PBS_SOLID;
+    ecp.nBorderStyle = BorderStyle::SOLID;
 
     m_pEdit->Create(ecp);
   }
@@ -315,7 +298,7 @@
     bcp.sBackgroundColor = PWL_SCROLLBAR_BKCOLOR;
     bcp.sBorderColor = PWL_DEFAULT_BLACKCOLOR;
     bcp.dwBorderWidth = 2;
-    bcp.nBorderStyle = PBS_BEVELED;
+    bcp.nBorderStyle = BorderStyle::BEVELED;
     bcp.eCursorType = FXCT_ARROW;
 
     m_pButton->Create(bcp);
@@ -330,10 +313,10 @@
     lcp.pParentWnd = this;
     lcp.dwFlags =
         PWS_CHILD | PWS_BORDER | PWS_BACKGROUND | PLBS_HOVERSEL | PWS_VSCROLL;
-    lcp.nBorderStyle = PBS_SOLID;
+    lcp.nBorderStyle = BorderStyle::SOLID;
     lcp.dwBorderWidth = 1;
     lcp.eCursorType = FXCT_ARROW;
-    lcp.rcRectWnd = CPDF_Rect(0, 0, 0, 0);
+    lcp.rcRectWnd = CFX_FloatRect(0, 0, 0, 0);
 
     if (cp.dwFlags & PWS_AUTOFONTSIZE)
       lcp.fFontSize = PWLCB_DEFAULTFONTSIZE;
@@ -351,13 +334,13 @@
 }
 
 void CPWL_ComboBox::RePosChildWnd() {
-  CPDF_Rect rcClient = GetClientRect();
+  CFX_FloatRect rcClient = GetClientRect();
 
   if (m_bPopup) {
-    CPDF_Rect rclient = GetClientRect();
-    CPDF_Rect rcButton = rclient;
-    CPDF_Rect rcEdit = rcClient;
-    CPDF_Rect rcList = CPWL_Wnd::GetWindowRect();
+    CFX_FloatRect rclient = GetClientRect();
+    CFX_FloatRect rcButton = rclient;
+    CFX_FloatRect rcEdit = rcClient;
+    CFX_FloatRect rcList = CPWL_Wnd::GetWindowRect();
 
     FX_FLOAT fOldWindowHeight = m_rcOldWindow.Height();
     FX_FLOAT fOldClientHeight = fOldWindowHeight - GetBorderWidth() * 2;
@@ -408,18 +391,18 @@
     }
 
     if (m_pButton)
-      m_pButton->Move(rcButton, TRUE, FALSE);
+      m_pButton->Move(rcButton, true, false);
 
     if (m_pEdit)
-      m_pEdit->Move(rcEdit, TRUE, FALSE);
+      m_pEdit->Move(rcEdit, true, false);
 
     if (m_pList) {
-      m_pList->SetVisible(TRUE);
-      m_pList->Move(rcList, TRUE, FALSE);
+      m_pList->SetVisible(true);
+      m_pList->Move(rcList, true, false);
       m_pList->ScrollToListItem(m_nSelectItem);
     }
   } else {
-    CPDF_Rect rcButton = rcClient;
+    CFX_FloatRect rcButton = rcClient;
 
     rcButton.left = rcButton.right - PWL_COMBOBOX_BUTTON_WIDTH;
 
@@ -427,9 +410,9 @@
       rcButton.left = rcClient.left;
 
     if (m_pButton)
-      m_pButton->Move(rcButton, TRUE, FALSE);
+      m_pButton->Move(rcButton, true, false);
 
-    CPDF_Rect rcEdit = rcClient;
+    CFX_FloatRect rcEdit = rcClient;
     rcEdit.right = rcButton.left - 1.0f;
 
     if (rcEdit.left < rcClient.left)
@@ -439,10 +422,10 @@
       rcEdit.right = rcEdit.left;
 
     if (m_pEdit)
-      m_pEdit->Move(rcEdit, TRUE, FALSE);
+      m_pEdit->Move(rcEdit, true, false);
 
     if (m_pList)
-      m_pList->SetVisible(FALSE);
+      m_pList->SetVisible(false);
   }
 }
 
@@ -451,11 +434,11 @@
     m_pEdit->SelectAll();
 }
 
-CPDF_Rect CPWL_ComboBox::GetFocusRect() const {
-  return CPDF_Rect();
+CFX_FloatRect CPWL_ComboBox::GetFocusRect() const {
+  return CFX_FloatRect();
 }
 
-void CPWL_ComboBox::SetPopup(FX_BOOL bPopup) {
+void CPWL_ComboBox::SetPopup(bool bPopup) {
   if (!m_pList)
     return;
   if (bPopup == m_bPopup)
@@ -467,7 +450,7 @@
   if (bPopup) {
     if (m_pFillerNotify) {
 #ifdef PDF_ENABLE_XFA
-      FX_BOOL bExit = FALSE;
+      bool bExit = false;
       m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), bExit, 0);
       if (bExit)
         return;
@@ -485,7 +468,7 @@
       if (IsFloatBigger(fPopupRet, 0.0f)) {
         m_bPopup = bPopup;
 
-        CPDF_Rect rcWindow = CPWL_Wnd::GetWindowRect();
+        CFX_FloatRect rcWindow = CPWL_Wnd::GetWindowRect();
         m_rcOldWindow = rcWindow;
         switch (nWhere) {
           default:
@@ -498,9 +481,9 @@
         }
 
         m_nPopupWhere = nWhere;
-        Move(rcWindow, TRUE, TRUE);
+        Move(rcWindow, true, true);
 #ifdef PDF_ENABLE_XFA
-        bExit = FALSE;
+        bExit = false;
         m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), bExit, 0);
         if (bExit)
           return;
@@ -509,97 +492,97 @@
     }
   } else {
     m_bPopup = bPopup;
-    Move(m_rcOldWindow, TRUE, TRUE);
+    Move(m_rcOldWindow, true, true);
   }
 }
 
-FX_BOOL CPWL_ComboBox::OnKeyDown(FX_WORD nChar, FX_DWORD nFlag) {
+bool CPWL_ComboBox::OnKeyDown(uint16_t nChar, uint32_t nFlag) {
   if (!m_pList)
-    return FALSE;
+    return false;
   if (!m_pEdit)
-    return FALSE;
+    return false;
 
   m_nSelectItem = -1;
 
   switch (nChar) {
     case FWL_VKEY_Up:
       if (m_pList->GetCurSel() > 0) {
-        FX_BOOL bExit = FALSE;
+        bool bExit = false;
 #ifdef PDF_ENABLE_XFA
         if (m_pFillerNotify) {
           m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), bExit, nFlag);
           if (bExit)
-            return FALSE;
-          bExit = FALSE;
+            return false;
+          bExit = false;
           m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), bExit, nFlag);
           if (bExit)
-            return FALSE;
+            return false;
         }
 #endif  // PDF_ENABLE_XFA
         if (m_pList->OnKeyDownWithExit(nChar, bExit, nFlag)) {
           if (bExit)
-            return FALSE;
+            return false;
           SetSelectText();
         }
       }
-      return TRUE;
+      return true;
     case FWL_VKEY_Down:
       if (m_pList->GetCurSel() < m_pList->GetCount() - 1) {
-        FX_BOOL bExit = FALSE;
+        bool bExit = false;
 #ifdef PDF_ENABLE_XFA
         if (m_pFillerNotify) {
           m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), bExit, nFlag);
           if (bExit)
-            return FALSE;
-          bExit = FALSE;
+            return false;
+          bExit = false;
           m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), bExit, nFlag);
           if (bExit)
-            return FALSE;
+            return false;
         }
 #endif  // PDF_ENABLE_XFA
         if (m_pList->OnKeyDownWithExit(nChar, bExit, nFlag)) {
           if (bExit)
-            return FALSE;
+            return false;
           SetSelectText();
         }
       }
-      return TRUE;
+      return true;
   }
 
   if (HasFlag(PCBS_ALLOWCUSTOMTEXT))
     return m_pEdit->OnKeyDown(nChar, nFlag);
 
-  return FALSE;
+  return false;
 }
 
-FX_BOOL CPWL_ComboBox::OnChar(FX_WORD nChar, FX_DWORD nFlag) {
+bool CPWL_ComboBox::OnChar(uint16_t nChar, uint32_t nFlag) {
   if (!m_pList)
-    return FALSE;
+    return false;
 
   if (!m_pEdit)
-    return FALSE;
+    return false;
 
   m_nSelectItem = -1;
   if (HasFlag(PCBS_ALLOWCUSTOMTEXT))
     return m_pEdit->OnChar(nChar, nFlag);
 
-  FX_BOOL bExit = FALSE;
+  bool bExit = false;
 #ifdef PDF_ENABLE_XFA
   if (m_pFillerNotify) {
     m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), bExit, nFlag);
     if (bExit)
-      return FALSE;
+      return false;
 
     m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), bExit, nFlag);
     if (bExit)
-      return FALSE;
+      return false;
   }
 #endif  // PDF_ENABLE_XFA
-  return m_pList->OnCharWithExit(nChar, bExit, nFlag) ? bExit : FALSE;
+  return m_pList->OnCharWithExit(nChar, bExit, nFlag) ? bExit : false;
 }
 
 void CPWL_ComboBox::OnNotify(CPWL_Wnd* pWnd,
-                             FX_DWORD msg,
+                             uint32_t msg,
                              intptr_t wParam,
                              intptr_t lParam) {
   switch (msg) {
@@ -615,7 +598,7 @@
           SetSelectText();
           SelectAll();
           m_pEdit->SetFocus();
-          SetPopup(FALSE);
+          SetPopup(false);
           return;
         }
       }
@@ -624,16 +607,14 @@
   CPWL_Wnd::OnNotify(pWnd, msg, wParam, lParam);
 }
 
-FX_BOOL CPWL_ComboBox::IsPopup() const {
+bool CPWL_ComboBox::IsPopup() const {
   return m_bPopup;
 }
 
 void CPWL_ComboBox::SetSelectText() {
-  CFX_WideString swText = m_pList->GetText();
   m_pEdit->SelectAll();
-  m_pEdit->ReplaceSel(m_pList->GetText().c_str());
+  m_pEdit->ReplaceSel(m_pList->GetText());
   m_pEdit->SelectAll();
-
   m_nSelectItem = m_pList->GetCurSel();
 }
 
diff --git a/fpdfsdk/include/pdfwindow/PWL_ComboBox.h b/fpdfsdk/pdfwindow/PWL_ComboBox.h
similarity index 64%
rename from fpdfsdk/include/pdfwindow/PWL_ComboBox.h
rename to fpdfsdk/pdfwindow/PWL_ComboBox.h
index b174f02..8426119 100644
--- a/fpdfsdk/include/pdfwindow/PWL_ComboBox.h
+++ b/fpdfsdk/pdfwindow/PWL_ComboBox.h
@@ -4,12 +4,12 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#ifndef FPDFSDK_INCLUDE_PDFWINDOW_PWL_COMBOBOX_H_
-#define FPDFSDK_INCLUDE_PDFWINDOW_PWL_COMBOBOX_H_
+#ifndef FPDFSDK_PDFWINDOW_PWL_COMBOBOX_H_
+#define FPDFSDK_PDFWINDOW_PWL_COMBOBOX_H_
 
-#include "PWL_Edit.h"
-#include "PWL_ListBox.h"
-#include "PWL_Wnd.h"
+#include "fpdfsdk/pdfwindow/PWL_Edit.h"
+#include "fpdfsdk/pdfwindow/PWL_ListBox.h"
+#include "fpdfsdk/pdfwindow/PWL_Wnd.h"
 
 class CPWL_CBEdit : public CPWL_Edit {
  public:
@@ -23,10 +23,10 @@
   ~CPWL_CBListBox() override {}
 
   // CPWL_ListBox
-  FX_BOOL OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag) override;
+  bool OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) override;
 
-  FX_BOOL OnKeyDownWithExit(FX_WORD nChar, FX_BOOL& bExit, FX_DWORD nFlag);
-  FX_BOOL OnCharWithExit(FX_WORD nChar, FX_BOOL& bExit, FX_DWORD nFlag);
+  bool OnKeyDownWithExit(uint16_t nChar, bool& bExit, uint32_t nFlag);
+  bool OnCharWithExit(uint16_t nChar, bool& bExit, uint32_t nFlag);
 };
 
 #define PWL_COMBOBOX_BUTTON_WIDTH 13
@@ -40,8 +40,8 @@
   void GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) override;
   void DrawThisAppearance(CFX_RenderDevice* pDevice,
                           CFX_Matrix* pUser2Device) override;
-  FX_BOOL OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) override;
-  FX_BOOL OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag) override;
+  bool OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag) override;
+  bool OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) override;
 };
 
 class CPWL_ComboBox : public CPWL_Wnd {
@@ -54,24 +54,23 @@
   // CPWL_Wnd:
   CFX_ByteString GetClassName() const override;
   void OnCreate(PWL_CREATEPARAM& cp) override;
-  FX_BOOL OnKeyDown(FX_WORD nChar, FX_DWORD nFlag) override;
-  FX_BOOL OnChar(FX_WORD nChar, FX_DWORD nFlag) override;
+  bool OnKeyDown(uint16_t nChar, uint32_t nFlag) override;
+  bool OnChar(uint16_t nChar, uint32_t nFlag) override;
   void OnNotify(CPWL_Wnd* pWnd,
-                FX_DWORD msg,
+                uint32_t msg,
                 intptr_t wParam = 0,
                 intptr_t lParam = 0) override;
   void CreateChildWnd(const PWL_CREATEPARAM& cp) override;
   void RePosChildWnd() override;
-  CPDF_Rect GetFocusRect() const override;
+  CFX_FloatRect GetFocusRect() const override;
   void SetFocus() override;
   void KillFocus() override;
 
   void SetFillerNotify(IPWL_Filler_Notify* pNotify);
 
   CFX_WideString GetText() const;
-  void SetText(const FX_WCHAR* text);
-
-  void AddString(const FX_WCHAR* string);
+  void SetText(const CFX_WideString& text);
+  void AddString(const CFX_WideString& str);
   int32_t GetSelect() const;
   void SetSelect(int32_t nItemIndex);
 
@@ -79,28 +78,27 @@
   void GetEditSel(int32_t& nStartChar, int32_t& nEndChar) const;
   void Clear();
   void SelectAll();
-  FX_BOOL IsPopup() const;
+  bool IsPopup() const;
 
   void SetSelectText();
 
-  void AttachFFLData(void* pData) { m_pFormFiller = pData; }
+  void AttachFFLData(CFFL_FormFiller* pData) { m_pFormFiller = pData; }
 
  private:
   void CreateEdit(const PWL_CREATEPARAM& cp);
   void CreateButton(const PWL_CREATEPARAM& cp);
   void CreateListBox(const PWL_CREATEPARAM& cp);
-  void SetPopup(FX_BOOL bPopup);
+  void SetPopup(bool bPopup);
 
   CPWL_CBEdit* m_pEdit;
   CPWL_CBButton* m_pButton;
   CPWL_CBListBox* m_pList;
-  FX_BOOL m_bPopup;
-  CPDF_Rect m_rcOldWindow;
+  bool m_bPopup;
+  CFX_FloatRect m_rcOldWindow;
   int32_t m_nPopupWhere;
   int32_t m_nSelectItem;
   IPWL_Filler_Notify* m_pFillerNotify;
-
-  void* m_pFormFiller;
+  CFFL_FormFiller* m_pFormFiller;  // Not owned.
 };
 
-#endif  // FPDFSDK_INCLUDE_PDFWINDOW_PWL_COMBOBOX_H_
+#endif  // FPDFSDK_PDFWINDOW_PWL_COMBOBOX_H_
diff --git a/fpdfsdk/pdfwindow/PWL_Edit.cpp b/fpdfsdk/pdfwindow/PWL_Edit.cpp
new file mode 100644
index 0000000..bb8ec91
--- /dev/null
+++ b/fpdfsdk/pdfwindow/PWL_Edit.cpp
@@ -0,0 +1,894 @@
+// 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
+
+#include "fpdfsdk/pdfwindow/PWL_Edit.h"
+
+#include <vector>
+
+#include "core/fpdfapi/font/cpdf_font.h"
+#include "core/fpdfdoc/cpvt_word.h"
+#include "core/fxcrt/fx_safe_types.h"
+#include "core/fxcrt/fx_xml.h"
+#include "core/fxge/cfx_graphstatedata.h"
+#include "core/fxge/cfx_pathdata.h"
+#include "core/fxge/cfx_renderdevice.h"
+#include "core/fxge/fx_font.h"
+#include "fpdfsdk/fxedit/fxet_edit.h"
+#include "fpdfsdk/pdfwindow/PWL_Caret.h"
+#include "fpdfsdk/pdfwindow/PWL_EditCtrl.h"
+#include "fpdfsdk/pdfwindow/PWL_FontMap.h"
+#include "fpdfsdk/pdfwindow/PWL_ScrollBar.h"
+#include "fpdfsdk/pdfwindow/PWL_Utils.h"
+#include "fpdfsdk/pdfwindow/PWL_Wnd.h"
+#include "public/fpdf_fwlevent.h"
+#include "third_party/base/stl_util.h"
+
+CPWL_Edit::CPWL_Edit()
+    : m_pFillerNotify(nullptr), m_bFocus(false), m_pFormFiller(nullptr) {}
+
+CPWL_Edit::~CPWL_Edit() {
+  ASSERT(m_bFocus == false);
+}
+
+CFX_ByteString CPWL_Edit::GetClassName() const {
+  return PWL_CLASSNAME_EDIT;
+}
+
+void CPWL_Edit::OnDestroy() {}
+
+void CPWL_Edit::SetText(const CFX_WideString& csText) {
+  CFX_WideString swText = csText;
+  if (HasFlag(PES_RICH)) {
+    CFX_ByteString sValue = CFX_ByteString::FromUnicode(swText);
+    if (CXML_Element* pXML =
+            CXML_Element::Parse(sValue.c_str(), sValue.GetLength())) {
+      int32_t nCount = pXML->CountChildren();
+      bool bFirst = true;
+
+      swText.clear();
+
+      for (int32_t i = 0; i < nCount; i++) {
+        if (CXML_Element* pSubElement = pXML->GetElement(i)) {
+          CFX_ByteString tag = pSubElement->GetTagName();
+          if (tag.EqualNoCase("p")) {
+            int nChild = pSubElement->CountChildren();
+            CFX_WideString swSection;
+            for (int32_t j = 0; j < nChild; j++) {
+              swSection += pSubElement->GetContent(j);
+            }
+
+            if (bFirst)
+              bFirst = false;
+            else
+              swText += FWL_VKEY_Return;
+            swText += swSection;
+          }
+        }
+      }
+
+      delete pXML;
+    }
+  }
+
+  m_pEdit->SetText(swText);
+}
+
+void CPWL_Edit::RePosChildWnd() {
+  if (CPWL_ScrollBar* pVSB = GetVScrollBar()) {
+    CFX_FloatRect rcWindow = m_rcOldWindow;
+    CFX_FloatRect rcVScroll =
+        CFX_FloatRect(rcWindow.right, rcWindow.bottom,
+                      rcWindow.right + PWL_SCROLLBAR_WIDTH, rcWindow.top);
+    pVSB->Move(rcVScroll, true, false);
+  }
+
+  if (m_pEditCaret && !HasFlag(PES_TEXTOVERFLOW))
+    m_pEditCaret->SetClipRect(CPWL_Utils::InflateRect(
+        GetClientRect(), 1.0f));  // +1 for caret beside border
+
+  CPWL_EditCtrl::RePosChildWnd();
+}
+
+CFX_FloatRect CPWL_Edit::GetClientRect() const {
+  CFX_FloatRect rcClient = CPWL_Utils::DeflateRect(
+      GetWindowRect(), (FX_FLOAT)(GetBorderWidth() + GetInnerBorderWidth()));
+
+  if (CPWL_ScrollBar* pVSB = GetVScrollBar()) {
+    if (pVSB->IsVisible()) {
+      rcClient.right -= PWL_SCROLLBAR_WIDTH;
+    }
+  }
+
+  return rcClient;
+}
+
+void CPWL_Edit::SetAlignFormatV(PWL_EDIT_ALIGNFORMAT_V nFormat, bool bPaint) {
+  m_pEdit->SetAlignmentV((int32_t)nFormat, bPaint);
+}
+
+bool CPWL_Edit::CanSelectAll() const {
+  return GetSelectWordRange() != m_pEdit->GetWholeWordRange();
+}
+
+bool CPWL_Edit::CanClear() const {
+  return !IsReadOnly() && m_pEdit->IsSelected();
+}
+
+bool CPWL_Edit::CanCopy() const {
+  return !HasFlag(PES_PASSWORD) && !HasFlag(PES_NOREAD) &&
+         m_pEdit->IsSelected();
+}
+
+bool CPWL_Edit::CanCut() const {
+  return CanCopy() && !IsReadOnly();
+}
+void CPWL_Edit::CutText() {
+  if (!CanCut())
+    return;
+  m_pEdit->Clear();
+}
+
+void CPWL_Edit::OnCreated() {
+  CPWL_EditCtrl::OnCreated();
+
+  if (CPWL_ScrollBar* pScroll = GetVScrollBar()) {
+    pScroll->RemoveFlag(PWS_AUTOTRANSPARENT);
+    pScroll->SetTransparency(255);
+  }
+
+  SetParamByFlag();
+
+  m_rcOldWindow = GetWindowRect();
+
+  m_pEdit->SetOprNotify(this);
+  m_pEdit->EnableOprNotify(true);
+}
+
+void CPWL_Edit::SetParamByFlag() {
+  if (HasFlag(PES_RIGHT)) {
+    m_pEdit->SetAlignmentH(2, false);
+  } else if (HasFlag(PES_MIDDLE)) {
+    m_pEdit->SetAlignmentH(1, false);
+  } else {
+    m_pEdit->SetAlignmentH(0, false);
+  }
+
+  if (HasFlag(PES_BOTTOM)) {
+    m_pEdit->SetAlignmentV(2, false);
+  } else if (HasFlag(PES_CENTER)) {
+    m_pEdit->SetAlignmentV(1, false);
+  } else {
+    m_pEdit->SetAlignmentV(0, false);
+  }
+
+  if (HasFlag(PES_PASSWORD)) {
+    m_pEdit->SetPasswordChar('*', false);
+  }
+
+  m_pEdit->SetMultiLine(HasFlag(PES_MULTILINE), false);
+  m_pEdit->SetAutoReturn(HasFlag(PES_AUTORETURN), false);
+  m_pEdit->SetAutoFontSize(HasFlag(PWS_AUTOFONTSIZE), false);
+  m_pEdit->SetAutoScroll(HasFlag(PES_AUTOSCROLL), false);
+  m_pEdit->EnableUndo(HasFlag(PES_UNDO));
+
+  if (HasFlag(PES_TEXTOVERFLOW)) {
+    SetClipRect(CFX_FloatRect(0.0f, 0.0f, 0.0f, 0.0f));
+    m_pEdit->SetTextOverflow(true, false);
+  } else {
+    if (m_pEditCaret) {
+      m_pEditCaret->SetClipRect(CPWL_Utils::InflateRect(
+          GetClientRect(), 1.0f));  // +1 for caret beside border
+    }
+  }
+}
+
+void CPWL_Edit::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) {
+  CPWL_Wnd::GetThisAppearanceStream(sAppStream);
+
+  CFX_FloatRect rcClient = GetClientRect();
+  CFX_ByteTextBuf sLine;
+
+  int32_t nCharArray = m_pEdit->GetCharArray();
+
+  if (nCharArray > 0) {
+    switch (GetBorderStyle()) {
+      case BorderStyle::SOLID: {
+        sLine << "q\n"
+              << GetBorderWidth() << " w\n"
+              << CPWL_Utils::GetColorAppStream(GetBorderColor(), false)
+                     .AsStringC()
+              << " 2 J 0 j\n";
+
+        for (int32_t i = 1; i < nCharArray; i++) {
+          sLine << rcClient.left +
+                       ((rcClient.right - rcClient.left) / nCharArray) * i
+                << " " << rcClient.bottom << " m\n"
+                << rcClient.left +
+                       ((rcClient.right - rcClient.left) / nCharArray) * i
+                << " " << rcClient.top << " l S\n";
+        }
+
+        sLine << "Q\n";
+        break;
+      }
+      case BorderStyle::DASH: {
+        sLine << "q\n"
+              << GetBorderWidth() << " w\n"
+              << CPWL_Utils::GetColorAppStream(GetBorderColor(), false)
+                     .AsStringC()
+              << " 2 J 0 j\n"
+              << "[" << GetBorderDash().nDash << " " << GetBorderDash().nGap
+              << "] " << GetBorderDash().nPhase << " d\n";
+
+        for (int32_t i = 1; i < nCharArray; i++) {
+          sLine << rcClient.left +
+                       ((rcClient.right - rcClient.left) / nCharArray) * i
+                << " " << rcClient.bottom << " m\n"
+                << rcClient.left +
+                       ((rcClient.right - rcClient.left) / nCharArray) * i
+                << " " << rcClient.top << " l S\n";
+        }
+
+        sLine << "Q\n";
+        break;
+      }
+      default:
+        break;
+    }
+  }
+
+  sAppStream << sLine;
+
+  CFX_ByteTextBuf sText;
+  CFX_FloatPoint ptOffset = CFX_FloatPoint();
+  CPVT_WordRange wrWhole = m_pEdit->GetWholeWordRange();
+  CPVT_WordRange wrSelect = GetSelectWordRange();
+  CPVT_WordRange wrVisible =
+      HasFlag(PES_TEXTOVERFLOW) ? wrWhole : m_pEdit->GetVisibleWordRange();
+
+  CPVT_WordRange wrSelBefore(wrWhole.BeginPos, wrSelect.BeginPos);
+  CPVT_WordRange wrSelAfter(wrSelect.EndPos, wrWhole.EndPos);
+  CPVT_WordRange wrTemp =
+      CPWL_Utils::OverlapWordRange(GetSelectWordRange(), wrVisible);
+  CFX_ByteString sEditSel =
+      CPWL_Utils::GetEditSelAppStream(m_pEdit.get(), ptOffset, &wrTemp);
+
+  if (sEditSel.GetLength() > 0)
+    sText << CPWL_Utils::GetColorAppStream(PWL_DEFAULT_SELBACKCOLOR).AsStringC()
+          << sEditSel.AsStringC();
+
+  wrTemp = CPWL_Utils::OverlapWordRange(wrVisible, wrSelBefore);
+  CFX_ByteString sEditBefore = CPWL_Utils::GetEditAppStream(
+      m_pEdit.get(), ptOffset, &wrTemp, !HasFlag(PES_CHARARRAY),
+      m_pEdit->GetPasswordChar());
+
+  if (sEditBefore.GetLength() > 0)
+    sText << "BT\n" << CPWL_Utils::GetColorAppStream(GetTextColor()).AsStringC()
+          << sEditBefore.AsStringC() << "ET\n";
+
+  wrTemp = CPWL_Utils::OverlapWordRange(wrVisible, wrSelect);
+  CFX_ByteString sEditMid = CPWL_Utils::GetEditAppStream(
+      m_pEdit.get(), ptOffset, &wrTemp, !HasFlag(PES_CHARARRAY),
+      m_pEdit->GetPasswordChar());
+
+  if (sEditMid.GetLength() > 0)
+    sText << "BT\n"
+          << CPWL_Utils::GetColorAppStream(CPWL_Color(COLORTYPE_GRAY, 1))
+                 .AsStringC()
+          << sEditMid.AsStringC() << "ET\n";
+
+  wrTemp = CPWL_Utils::OverlapWordRange(wrVisible, wrSelAfter);
+  CFX_ByteString sEditAfter = CPWL_Utils::GetEditAppStream(
+      m_pEdit.get(), ptOffset, &wrTemp, !HasFlag(PES_CHARARRAY),
+      m_pEdit->GetPasswordChar());
+
+  if (sEditAfter.GetLength() > 0)
+    sText << "BT\n" << CPWL_Utils::GetColorAppStream(GetTextColor()).AsStringC()
+          << sEditAfter.AsStringC() << "ET\n";
+
+  if (sText.GetLength() > 0) {
+    CFX_FloatRect rect = GetClientRect();
+    sAppStream << "q\n/Tx BMC\n";
+
+    if (!HasFlag(PES_TEXTOVERFLOW))
+      sAppStream << rect.left << " " << rect.bottom << " "
+                 << rect.right - rect.left << " " << rect.top - rect.bottom
+                 << " re W n\n";
+
+    sAppStream << sText;
+
+    sAppStream << "EMC\nQ\n";
+  }
+}
+
+void CPWL_Edit::DrawThisAppearance(CFX_RenderDevice* pDevice,
+                                   CFX_Matrix* pUser2Device) {
+  CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device);
+
+  CFX_FloatRect rcClient = GetClientRect();
+  CFX_ByteTextBuf sLine;
+
+  int32_t nCharArray = m_pEdit->GetCharArray();
+  FX_SAFE_INT32 nCharArraySafe = nCharArray;
+  nCharArraySafe -= 1;
+  nCharArraySafe *= 2;
+
+  if (nCharArray > 0 && nCharArraySafe.IsValid()) {
+    switch (GetBorderStyle()) {
+      case BorderStyle::SOLID: {
+        CFX_GraphStateData gsd;
+        gsd.m_LineWidth = (FX_FLOAT)GetBorderWidth();
+
+        CFX_PathData path;
+        path.SetPointCount(nCharArraySafe.ValueOrDie());
+
+        for (int32_t i = 0; i < nCharArray - 1; i++) {
+          path.SetPoint(
+              i * 2,
+              rcClient.left +
+                  ((rcClient.right - rcClient.left) / nCharArray) * (i + 1),
+              rcClient.bottom, FXPT_MOVETO);
+          path.SetPoint(
+              i * 2 + 1,
+              rcClient.left +
+                  ((rcClient.right - rcClient.left) / nCharArray) * (i + 1),
+              rcClient.top, FXPT_LINETO);
+        }
+        if (path.GetPointCount() > 0) {
+          pDevice->DrawPath(
+              &path, pUser2Device, &gsd, 0,
+              CPWL_Utils::PWLColorToFXColor(GetBorderColor(), 255),
+              FXFILL_ALTERNATE);
+        }
+        break;
+      }
+      case BorderStyle::DASH: {
+        CFX_GraphStateData gsd;
+        gsd.m_LineWidth = (FX_FLOAT)GetBorderWidth();
+
+        gsd.SetDashCount(2);
+        gsd.m_DashArray[0] = (FX_FLOAT)GetBorderDash().nDash;
+        gsd.m_DashArray[1] = (FX_FLOAT)GetBorderDash().nGap;
+        gsd.m_DashPhase = (FX_FLOAT)GetBorderDash().nPhase;
+
+        CFX_PathData path;
+        path.SetPointCount(nCharArraySafe.ValueOrDie());
+
+        for (int32_t i = 0; i < nCharArray - 1; i++) {
+          path.SetPoint(
+              i * 2,
+              rcClient.left +
+                  ((rcClient.right - rcClient.left) / nCharArray) * (i + 1),
+              rcClient.bottom, FXPT_MOVETO);
+          path.SetPoint(
+              i * 2 + 1,
+              rcClient.left +
+                  ((rcClient.right - rcClient.left) / nCharArray) * (i + 1),
+              rcClient.top, FXPT_LINETO);
+        }
+        if (path.GetPointCount() > 0) {
+          pDevice->DrawPath(
+              &path, pUser2Device, &gsd, 0,
+              CPWL_Utils::PWLColorToFXColor(GetBorderColor(), 255),
+              FXFILL_ALTERNATE);
+        }
+        break;
+      }
+      default:
+        break;
+    }
+  }
+
+  CFX_FloatRect rcClip;
+  CPVT_WordRange wrRange = m_pEdit->GetVisibleWordRange();
+  CPVT_WordRange* pRange = nullptr;
+  if (!HasFlag(PES_TEXTOVERFLOW)) {
+    rcClip = GetClientRect();
+    pRange = &wrRange;
+  }
+
+  CFX_SystemHandler* pSysHandler = GetSystemHandler();
+  CFX_Edit::DrawEdit(
+      pDevice, pUser2Device, m_pEdit.get(),
+      CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()),
+      CPWL_Utils::PWLColorToFXColor(GetTextStrokeColor(), GetTransparency()),
+      rcClip, CFX_FloatPoint(), pRange, pSysHandler, m_pFormFiller);
+}
+
+bool CPWL_Edit::OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag) {
+  CPWL_Wnd::OnLButtonDown(point, nFlag);
+
+  if (HasFlag(PES_TEXTOVERFLOW) || ClientHitTest(point)) {
+    if (m_bMouseDown)
+      InvalidateRect();
+
+    m_bMouseDown = true;
+    SetCapture();
+
+    m_pEdit->OnMouseDown(point, IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
+  }
+
+  return true;
+}
+
+bool CPWL_Edit::OnLButtonDblClk(const CFX_FloatPoint& point, uint32_t nFlag) {
+  CPWL_Wnd::OnLButtonDblClk(point, nFlag);
+
+  if (HasFlag(PES_TEXTOVERFLOW) || ClientHitTest(point)) {
+    m_pEdit->SelectAll();
+  }
+
+  return true;
+}
+
+bool CPWL_Edit::OnRButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) {
+  if (m_bMouseDown)
+    return false;
+
+  CPWL_Wnd::OnRButtonUp(point, nFlag);
+
+  if (!HasFlag(PES_TEXTOVERFLOW) && !ClientHitTest(point))
+    return true;
+
+  CFX_SystemHandler* pSH = GetSystemHandler();
+  if (!pSH)
+    return false;
+
+  SetFocus();
+
+  return false;
+}
+
+void CPWL_Edit::OnSetFocus() {
+  SetEditCaret(true);
+  if (!IsReadOnly()) {
+    if (IPWL_FocusHandler* pFocusHandler = GetFocusHandler())
+      pFocusHandler->OnSetFocus(this);
+  }
+  m_bFocus = true;
+}
+
+void CPWL_Edit::OnKillFocus() {
+  ShowVScrollBar(false);
+  m_pEdit->SelectNone();
+  SetCaret(false, CFX_FloatPoint(), CFX_FloatPoint());
+  SetCharSet(FXFONT_ANSI_CHARSET);
+  m_bFocus = false;
+}
+
+void CPWL_Edit::SetCharSpace(FX_FLOAT fCharSpace) {
+  m_pEdit->SetCharSpace(fCharSpace);
+}
+
+CFX_ByteString CPWL_Edit::GetSelectAppearanceStream(
+    const CFX_FloatPoint& ptOffset) const {
+  CPVT_WordRange wr = GetSelectWordRange();
+  return CPWL_Utils::GetEditSelAppStream(m_pEdit.get(), ptOffset, &wr);
+}
+
+CPVT_WordRange CPWL_Edit::GetSelectWordRange() const {
+  if (m_pEdit->IsSelected()) {
+    int32_t nStart = -1;
+    int32_t nEnd = -1;
+
+    m_pEdit->GetSel(nStart, nEnd);
+
+    CPVT_WordPlace wpStart = m_pEdit->WordIndexToWordPlace(nStart);
+    CPVT_WordPlace wpEnd = m_pEdit->WordIndexToWordPlace(nEnd);
+
+    return CPVT_WordRange(wpStart, wpEnd);
+  }
+
+  return CPVT_WordRange();
+}
+
+CFX_ByteString CPWL_Edit::GetTextAppearanceStream(
+    const CFX_FloatPoint& ptOffset) const {
+  CFX_ByteTextBuf sRet;
+  CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream(m_pEdit.get(), ptOffset);
+  if (sEdit.GetLength() > 0) {
+    sRet << "BT\n" << CPWL_Utils::GetColorAppStream(GetTextColor()).AsStringC()
+         << sEdit.AsStringC() << "ET\n";
+  }
+  return sRet.MakeString();
+}
+
+CFX_ByteString CPWL_Edit::GetCaretAppearanceStream(
+    const CFX_FloatPoint& ptOffset) const {
+  if (m_pEditCaret)
+    return m_pEditCaret->GetCaretAppearanceStream(ptOffset);
+
+  return CFX_ByteString();
+}
+
+CFX_FloatPoint CPWL_Edit::GetWordRightBottomPoint(
+    const CPVT_WordPlace& wpWord) {
+  CFX_Edit_Iterator* pIterator = m_pEdit->GetIterator();
+  CPVT_WordPlace wpOld = pIterator->GetAt();
+  pIterator->SetAt(wpWord);
+
+  CFX_FloatPoint pt;
+  CPVT_Word word;
+  if (pIterator->GetWord(word)) {
+    pt = CFX_FloatPoint(word.ptWord.x + word.fWidth,
+                        word.ptWord.y + word.fDescent);
+  }
+  pIterator->SetAt(wpOld);
+  return pt;
+}
+
+bool CPWL_Edit::IsTextFull() const {
+  return m_pEdit->IsTextFull();
+}
+
+FX_FLOAT CPWL_Edit::GetCharArrayAutoFontSize(CPDF_Font* pFont,
+                                             const CFX_FloatRect& rcPlate,
+                                             int32_t nCharArray) {
+  if (pFont && !pFont->IsStandardFont()) {
+    FX_RECT rcBBox;
+    pFont->GetFontBBox(rcBBox);
+
+    CFX_FloatRect rcCell = rcPlate;
+    FX_FLOAT xdiv = rcCell.Width() / nCharArray * 1000.0f / rcBBox.Width();
+    FX_FLOAT ydiv = -rcCell.Height() * 1000.0f / rcBBox.Height();
+
+    return xdiv < ydiv ? xdiv : ydiv;
+  }
+
+  return 0.0f;
+}
+
+void CPWL_Edit::SetCharArray(int32_t nCharArray) {
+  if (HasFlag(PES_CHARARRAY) && nCharArray > 0) {
+    m_pEdit->SetCharArray(nCharArray);
+    m_pEdit->SetTextOverflow(true, true);
+
+    if (HasFlag(PWS_AUTOFONTSIZE)) {
+      if (IPVT_FontMap* pFontMap = GetFontMap()) {
+        FX_FLOAT fFontSize = GetCharArrayAutoFontSize(
+            pFontMap->GetPDFFont(0), GetClientRect(), nCharArray);
+        if (fFontSize > 0.0f) {
+          m_pEdit->SetAutoFontSize(false, true);
+          m_pEdit->SetFontSize(fFontSize);
+        }
+      }
+    }
+  }
+}
+
+void CPWL_Edit::SetLimitChar(int32_t nLimitChar) {
+  m_pEdit->SetLimitChar(nLimitChar);
+}
+
+void CPWL_Edit::ReplaceSel(const CFX_WideString& wsText) {
+  m_pEdit->Clear();
+  m_pEdit->InsertText(wsText, FXFONT_DEFAULT_CHARSET);
+}
+
+CFX_FloatRect CPWL_Edit::GetFocusRect() const {
+  return CFX_FloatRect();
+}
+
+void CPWL_Edit::ShowVScrollBar(bool bShow) {
+  if (CPWL_ScrollBar* pScroll = GetVScrollBar()) {
+    if (bShow) {
+      if (!pScroll->IsVisible()) {
+        pScroll->SetVisible(true);
+        CFX_FloatRect rcWindow = GetWindowRect();
+        m_rcOldWindow = rcWindow;
+        rcWindow.right += PWL_SCROLLBAR_WIDTH;
+        Move(rcWindow, true, true);
+      }
+    } else {
+      if (pScroll->IsVisible()) {
+        pScroll->SetVisible(false);
+        Move(m_rcOldWindow, true, true);
+      }
+    }
+  }
+}
+
+bool CPWL_Edit::IsVScrollBarVisible() const {
+  if (CPWL_ScrollBar* pScroll = GetVScrollBar()) {
+    return pScroll->IsVisible();
+  }
+
+  return false;
+}
+
+bool CPWL_Edit::OnKeyDown(uint16_t nChar, uint32_t nFlag) {
+  if (m_bMouseDown)
+    return true;
+
+  if (nChar == FWL_VKEY_Delete) {
+    if (m_pFillerNotify) {
+      bool bRC = true;
+      bool bExit = false;
+      CFX_WideString strChange;
+      CFX_WideString strChangeEx;
+
+      int nSelStart = 0;
+      int nSelEnd = 0;
+      GetSel(nSelStart, nSelEnd);
+
+      if (nSelStart == nSelEnd)
+        nSelEnd = nSelStart + 1;
+      m_pFillerNotify->OnBeforeKeyStroke(GetAttachedData(), strChange,
+                                         strChangeEx, nSelStart, nSelEnd, true,
+                                         bRC, bExit, nFlag);
+      if (!bRC)
+        return false;
+      if (bExit)
+        return false;
+    }
+  }
+
+  bool bRet = CPWL_EditCtrl::OnKeyDown(nChar, nFlag);
+
+  // In case of implementation swallow the OnKeyDown event.
+  if (IsProceedtoOnChar(nChar, nFlag))
+    return true;
+
+  return bRet;
+}
+
+/**
+*In case of implementation swallow the OnKeyDown event.
+*If the event is swallowed, implementation may do other unexpected things, which
+*is not the control means to do.
+*/
+bool CPWL_Edit::IsProceedtoOnChar(uint16_t nKeyCode, uint32_t nFlag) {
+  bool bCtrl = IsCTRLpressed(nFlag);
+  bool bAlt = IsALTpressed(nFlag);
+  if (bCtrl && !bAlt) {
+    // hot keys for edit control.
+    switch (nKeyCode) {
+      case 'C':
+      case 'V':
+      case 'X':
+      case 'A':
+      case 'Z':
+        return true;
+      default:
+        break;
+    }
+  }
+  // control characters.
+  switch (nKeyCode) {
+    case FWL_VKEY_Escape:
+    case FWL_VKEY_Back:
+    case FWL_VKEY_Return:
+    case FWL_VKEY_Space:
+      return true;
+    default:
+      return false;
+  }
+}
+
+bool CPWL_Edit::OnChar(uint16_t nChar, uint32_t nFlag) {
+  if (m_bMouseDown)
+    return true;
+
+  bool bRC = true;
+  bool bExit = false;
+
+  if (!IsCTRLpressed(nFlag)) {
+    if (m_pFillerNotify) {
+      CFX_WideString swChange;
+
+      int nSelStart = 0;
+      int nSelEnd = 0;
+      GetSel(nSelStart, nSelEnd);
+
+      switch (nChar) {
+        case FWL_VKEY_Back:
+          if (nSelStart == nSelEnd)
+            nSelStart = nSelEnd - 1;
+          break;
+        case FWL_VKEY_Return:
+          break;
+        default:
+          swChange += nChar;
+          break;
+      }
+
+      CFX_WideString strChangeEx;
+      m_pFillerNotify->OnBeforeKeyStroke(GetAttachedData(), swChange,
+                                         strChangeEx, nSelStart, nSelEnd, true,
+                                         bRC, bExit, nFlag);
+    }
+  }
+
+  if (!bRC)
+    return true;
+  if (bExit)
+    return false;
+
+  if (IPVT_FontMap* pFontMap = GetFontMap()) {
+    int32_t nOldCharSet = GetCharSet();
+    int32_t nNewCharSet =
+        pFontMap->CharSetFromUnicode(nChar, FXFONT_DEFAULT_CHARSET);
+    if (nOldCharSet != nNewCharSet) {
+      SetCharSet(nNewCharSet);
+    }
+  }
+
+  return CPWL_EditCtrl::OnChar(nChar, nFlag);
+}
+
+bool CPWL_Edit::OnMouseWheel(short zDelta,
+                             const CFX_FloatPoint& point,
+                             uint32_t nFlag) {
+  if (HasFlag(PES_MULTILINE)) {
+    CFX_FloatPoint ptScroll = GetScrollPos();
+
+    if (zDelta > 0) {
+      ptScroll.y += GetFontSize();
+    } else {
+      ptScroll.y -= GetFontSize();
+    }
+    SetScrollPos(ptScroll);
+
+    return true;
+  }
+
+  return false;
+}
+
+void CPWL_Edit::OnInsertReturn(const CPVT_WordPlace& place,
+                               const CPVT_WordPlace& oldplace) {
+  if (HasFlag(PES_SPELLCHECK)) {
+    m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
+                                               GetLatinWordsRange(place)));
+  }
+}
+
+void CPWL_Edit::OnBackSpace(const CPVT_WordPlace& place,
+                            const CPVT_WordPlace& oldplace) {
+  if (HasFlag(PES_SPELLCHECK)) {
+    m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
+                                               GetLatinWordsRange(place)));
+  }
+}
+
+void CPWL_Edit::OnDelete(const CPVT_WordPlace& place,
+                         const CPVT_WordPlace& oldplace) {
+  if (HasFlag(PES_SPELLCHECK)) {
+    m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
+                                               GetLatinWordsRange(place)));
+  }
+}
+
+void CPWL_Edit::OnClear(const CPVT_WordPlace& place,
+                        const CPVT_WordPlace& oldplace) {
+  if (HasFlag(PES_SPELLCHECK)) {
+    m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
+                                               GetLatinWordsRange(place)));
+  }
+}
+
+void CPWL_Edit::OnInsertWord(const CPVT_WordPlace& place,
+                             const CPVT_WordPlace& oldplace) {
+  if (HasFlag(PES_SPELLCHECK)) {
+    m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
+                                               GetLatinWordsRange(place)));
+  }
+}
+
+void CPWL_Edit::OnInsertText(const CPVT_WordPlace& place,
+                             const CPVT_WordPlace& oldplace) {
+  if (HasFlag(PES_SPELLCHECK)) {
+    m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
+                                               GetLatinWordsRange(place)));
+  }
+}
+
+CPVT_WordRange CPWL_Edit::CombineWordRange(const CPVT_WordRange& wr1,
+                                           const CPVT_WordRange& wr2) {
+  CPVT_WordRange wrRet;
+
+  if (wr1.BeginPos.WordCmp(wr2.BeginPos) < 0) {
+    wrRet.BeginPos = wr1.BeginPos;
+  } else {
+    wrRet.BeginPos = wr2.BeginPos;
+  }
+
+  if (wr1.EndPos.WordCmp(wr2.EndPos) < 0) {
+    wrRet.EndPos = wr2.EndPos;
+  } else {
+    wrRet.EndPos = wr1.EndPos;
+  }
+
+  return wrRet;
+}
+
+CPVT_WordRange CPWL_Edit::GetLatinWordsRange(
+    const CFX_FloatPoint& point) const {
+  return GetSameWordsRange(m_pEdit->SearchWordPlace(point), true, false);
+}
+
+CPVT_WordRange CPWL_Edit::GetLatinWordsRange(
+    const CPVT_WordPlace& place) const {
+  return GetSameWordsRange(place, true, false);
+}
+
+CPVT_WordRange CPWL_Edit::GetArabicWordsRange(
+    const CPVT_WordPlace& place) const {
+  return GetSameWordsRange(place, false, true);
+}
+
+#define PWL_ISARABICWORD(word) \
+  ((word >= 0x0600 && word <= 0x06FF) || (word >= 0xFB50 && word <= 0xFEFC))
+
+CPVT_WordRange CPWL_Edit::GetSameWordsRange(const CPVT_WordPlace& place,
+                                            bool bLatin,
+                                            bool bArabic) const {
+  CPVT_WordRange range;
+
+  CFX_Edit_Iterator* pIterator = m_pEdit->GetIterator();
+  CPVT_Word wordinfo;
+  CPVT_WordPlace wpStart(place), wpEnd(place);
+  pIterator->SetAt(place);
+
+  if (bLatin) {
+    while (pIterator->NextWord()) {
+      if (!pIterator->GetWord(wordinfo) ||
+          !FX_EDIT_ISLATINWORD(wordinfo.Word)) {
+        break;
+      }
+
+      wpEnd = pIterator->GetAt();
+    }
+  } else if (bArabic) {
+    while (pIterator->NextWord()) {
+      if (!pIterator->GetWord(wordinfo) || !PWL_ISARABICWORD(wordinfo.Word))
+        break;
+
+      wpEnd = pIterator->GetAt();
+    }
+  }
+
+  pIterator->SetAt(place);
+
+  if (bLatin) {
+    do {
+      if (!pIterator->GetWord(wordinfo) ||
+          !FX_EDIT_ISLATINWORD(wordinfo.Word)) {
+        break;
+      }
+
+      wpStart = pIterator->GetAt();
+    } while (pIterator->PrevWord());
+  } else if (bArabic) {
+    do {
+      if (!pIterator->GetWord(wordinfo) || !PWL_ISARABICWORD(wordinfo.Word))
+        break;
+
+      wpStart = pIterator->GetAt();
+    } while (pIterator->PrevWord());
+  }
+
+  range.Set(wpStart, wpEnd);
+  return range;
+}
+
+void CPWL_Edit::GeneratePageObjects(CPDF_PageObjectHolder* pObjectHolder,
+                                    const CFX_FloatPoint& ptOffset,
+                                    std::vector<CPDF_TextObject*>* ObjArray) {
+  CFX_Edit::GeneratePageObjects(
+      pObjectHolder, m_pEdit.get(), ptOffset, nullptr,
+      CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()),
+      ObjArray);
+}
+
+void CPWL_Edit::GeneratePageObjects(CPDF_PageObjectHolder* pObjectHolder,
+                                    const CFX_FloatPoint& ptOffset) {
+  std::vector<CPDF_TextObject*> ObjArray;
+  CFX_Edit::GeneratePageObjects(
+      pObjectHolder, m_pEdit.get(), ptOffset, nullptr,
+      CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()),
+      &ObjArray);
+}
diff --git a/fpdfsdk/pdfwindow/PWL_Edit.h b/fpdfsdk/pdfwindow/PWL_Edit.h
new file mode 100644
index 0000000..801dedd
--- /dev/null
+++ b/fpdfsdk/pdfwindow/PWL_Edit.h
@@ -0,0 +1,150 @@
+// 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_PDFWINDOW_PWL_EDIT_H_
+#define FPDFSDK_PDFWINDOW_PWL_EDIT_H_
+
+#include <vector>
+
+#include "core/fxcrt/fx_basic.h"
+#include "fpdfsdk/fxedit/fx_edit.h"
+#include "fpdfsdk/pdfwindow/PWL_EditCtrl.h"
+#include "fpdfsdk/pdfwindow/PWL_Wnd.h"
+
+class CPDF_PageObjectHolder;
+class CPDF_TextObject;
+class IFX_Edit_UndoItem;
+
+class IPWL_Filler_Notify {
+ public:
+  virtual ~IPWL_Filler_Notify() {}
+  virtual void QueryWherePopup(
+      void* pPrivateData,
+      FX_FLOAT fPopupMin,
+      FX_FLOAT fPopupMax,
+      int32_t& nRet,
+      FX_FLOAT& fPopupRet) = 0;  // nRet: (0:bottom 1:top)
+  virtual void OnBeforeKeyStroke(void* pPrivateData,
+                                 CFX_WideString& strChange,
+                                 const CFX_WideString& strChangeEx,
+                                 int nSelStart,
+                                 int nSelEnd,
+                                 bool bKeyDown,
+                                 bool& bRC,
+                                 bool& bExit,
+                                 uint32_t nFlag) = 0;
+#ifdef PDF_ENABLE_XFA
+  virtual void OnPopupPreOpen(void* pPrivateData,
+                              bool& bExit,
+                              uint32_t nFlag) = 0;
+  virtual void OnPopupPostOpen(void* pPrivateData,
+                               bool& bExit,
+                               uint32_t nFlag) = 0;
+#endif  // PDF_ENABLE_XFA
+};
+
+class CPWL_Edit : public CPWL_EditCtrl {
+ public:
+  CPWL_Edit();
+  ~CPWL_Edit() override;
+
+  // CPWL_EditCtrl
+  CFX_ByteString GetClassName() const override;
+  void OnDestroy() override;
+  void OnCreated() override;
+  void RePosChildWnd() override;
+  CFX_FloatRect GetClientRect() const override;
+  void GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) override;
+  void DrawThisAppearance(CFX_RenderDevice* pDevice,
+                          CFX_Matrix* pUser2Device) override;
+  bool OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag) override;
+  bool OnLButtonDblClk(const CFX_FloatPoint& point, uint32_t nFlag) override;
+  bool OnRButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) override;
+  bool OnMouseWheel(short zDelta,
+                    const CFX_FloatPoint& point,
+                    uint32_t nFlag) override;
+  bool OnKeyDown(uint16_t nChar, uint32_t nFlag) override;
+  bool OnChar(uint16_t nChar, uint32_t nFlag) override;
+  CFX_FloatRect GetFocusRect() const override;
+  void OnSetFocus() override;
+  void OnKillFocus() override;
+
+  void SetAlignFormatV(PWL_EDIT_ALIGNFORMAT_V nFormat = PEAV_TOP,
+                       bool bPaint = true);  // 0:top 1:bottom 2:center
+
+  void SetCharArray(int32_t nCharArray);
+  void SetLimitChar(int32_t nLimitChar);
+
+  void SetCharSpace(FX_FLOAT fCharSpace);
+
+  bool CanSelectAll() const;
+  bool CanClear() const;
+  bool CanCopy() const;
+  bool CanCut() const;
+
+  void CutText();
+
+  void SetText(const CFX_WideString& csText);
+  void ReplaceSel(const CFX_WideString& csText);
+
+  CFX_ByteString GetTextAppearanceStream(const CFX_FloatPoint& ptOffset) const;
+  CFX_ByteString GetCaretAppearanceStream(const CFX_FloatPoint& ptOffset) const;
+  CFX_ByteString GetSelectAppearanceStream(
+      const CFX_FloatPoint& ptOffset) const;
+
+  bool IsTextFull() const;
+
+  static FX_FLOAT GetCharArrayAutoFontSize(CPDF_Font* pFont,
+                                           const CFX_FloatRect& rcPlate,
+                                           int32_t nCharArray);
+
+  void SetFillerNotify(IPWL_Filler_Notify* pNotify) {
+    m_pFillerNotify = pNotify;
+  }
+
+  void GeneratePageObjects(CPDF_PageObjectHolder* pObjectHolder,
+                           const CFX_FloatPoint& ptOffset,
+                           std::vector<CPDF_TextObject*>* ObjArray);
+  void GeneratePageObjects(CPDF_PageObjectHolder* pObjectHolder,
+                           const CFX_FloatPoint& ptOffset);
+
+  bool IsProceedtoOnChar(uint16_t nKeyCode, uint32_t nFlag);
+  void AttachFFLData(CFFL_FormFiller* pData) { m_pFormFiller = pData; }
+
+  void OnInsertWord(const CPVT_WordPlace& place,
+                    const CPVT_WordPlace& oldplace);
+  void OnInsertReturn(const CPVT_WordPlace& place,
+                      const CPVT_WordPlace& oldplace);
+  void OnBackSpace(const CPVT_WordPlace& place, const CPVT_WordPlace& oldplace);
+  void OnDelete(const CPVT_WordPlace& place, const CPVT_WordPlace& oldplace);
+  void OnClear(const CPVT_WordPlace& place, const CPVT_WordPlace& oldplace);
+  void OnInsertText(const CPVT_WordPlace& place,
+                    const CPVT_WordPlace& oldplace);
+
+ private:
+  CPVT_WordRange GetSelectWordRange() const;
+  virtual void ShowVScrollBar(bool bShow);
+  bool IsVScrollBarVisible() const;
+  void SetParamByFlag();
+
+  FX_FLOAT GetCharArrayAutoFontSize(int32_t nCharArray);
+  CFX_FloatPoint GetWordRightBottomPoint(const CPVT_WordPlace& wpWord);
+
+  CPVT_WordRange CombineWordRange(const CPVT_WordRange& wr1,
+                                  const CPVT_WordRange& wr2);
+  CPVT_WordRange GetLatinWordsRange(const CFX_FloatPoint& point) const;
+  CPVT_WordRange GetLatinWordsRange(const CPVT_WordPlace& place) const;
+  CPVT_WordRange GetArabicWordsRange(const CPVT_WordPlace& place) const;
+  CPVT_WordRange GetSameWordsRange(const CPVT_WordPlace& place,
+                                   bool bLatin,
+                                   bool bArabic) const;
+  IPWL_Filler_Notify* m_pFillerNotify;
+  bool m_bFocus;
+  CFX_FloatRect m_rcOldWindow;
+  CFFL_FormFiller* m_pFormFiller;  // Not owned.
+};
+
+#endif  // FPDFSDK_PDFWINDOW_PWL_EDIT_H_
diff --git a/fpdfsdk/pdfwindow/PWL_EditCtrl.cpp b/fpdfsdk/pdfwindow/PWL_EditCtrl.cpp
new file mode 100644
index 0000000..9459215
--- /dev/null
+++ b/fpdfsdk/pdfwindow/PWL_EditCtrl.cpp
@@ -0,0 +1,592 @@
+// 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
+
+#include "fpdfsdk/pdfwindow/PWL_EditCtrl.h"
+
+#include "core/fpdfdoc/cpvt_section.h"
+#include "core/fpdfdoc/cpvt_word.h"
+#include "core/fxge/fx_font.h"
+#include "fpdfsdk/fxedit/fxet_edit.h"
+#include "fpdfsdk/pdfwindow/PWL_Caret.h"
+#include "fpdfsdk/pdfwindow/PWL_FontMap.h"
+#include "fpdfsdk/pdfwindow/PWL_ScrollBar.h"
+#include "fpdfsdk/pdfwindow/PWL_Utils.h"
+#include "fpdfsdk/pdfwindow/PWL_Wnd.h"
+#include "public/fpdf_fwlevent.h"
+
+CPWL_EditCtrl::CPWL_EditCtrl()
+    : m_pEdit(new CFX_Edit),
+      m_pEditCaret(nullptr),
+      m_bMouseDown(false),
+      m_nCharSet(FXFONT_DEFAULT_CHARSET),
+      m_nCodePage(0) {}
+
+CPWL_EditCtrl::~CPWL_EditCtrl() {}
+
+void CPWL_EditCtrl::OnCreate(PWL_CREATEPARAM& cp) {
+  cp.eCursorType = FXCT_VBEAM;
+}
+
+void CPWL_EditCtrl::OnCreated() {
+  SetFontSize(GetCreationParam().fFontSize);
+
+  m_pEdit->SetFontMap(GetFontMap());
+  m_pEdit->SetNotify(this);
+  m_pEdit->Initialize();
+}
+
+bool CPWL_EditCtrl::IsWndHorV() {
+  CFX_Matrix mt = GetWindowMatrix();
+  CFX_FloatPoint point1(0, 1);
+  CFX_FloatPoint point2(1, 1);
+
+  mt.Transform(point1.x, point1.y);
+  mt.Transform(point2.x, point2.y);
+
+  return point2.y == point1.y;
+}
+
+void CPWL_EditCtrl::SetCursor() {
+  if (IsValid()) {
+    if (CFX_SystemHandler* pSH = GetSystemHandler()) {
+      if (IsWndHorV())
+        pSH->SetCursor(FXCT_VBEAM);
+      else
+        pSH->SetCursor(FXCT_HBEAM);
+    }
+  }
+}
+
+void CPWL_EditCtrl::RePosChildWnd() {
+  m_pEdit->SetPlateRect(GetClientRect());
+}
+
+void CPWL_EditCtrl::OnNotify(CPWL_Wnd* pWnd,
+                             uint32_t msg,
+                             intptr_t wParam,
+                             intptr_t lParam) {
+  CPWL_Wnd::OnNotify(pWnd, msg, wParam, lParam);
+
+  switch (msg) {
+    case PNM_SETSCROLLINFO:
+      switch (wParam) {
+        case SBT_VSCROLL:
+          if (CPWL_Wnd* pChild = GetVScrollBar()) {
+            pChild->OnNotify(pWnd, PNM_SETSCROLLINFO, wParam, lParam);
+          }
+          break;
+      }
+      break;
+    case PNM_SETSCROLLPOS:
+      switch (wParam) {
+        case SBT_VSCROLL:
+          if (CPWL_Wnd* pChild = GetVScrollBar()) {
+            pChild->OnNotify(pWnd, PNM_SETSCROLLPOS, wParam, lParam);
+          }
+          break;
+      }
+      break;
+    case PNM_SCROLLWINDOW: {
+      FX_FLOAT fPos = *(FX_FLOAT*)lParam;
+      switch (wParam) {
+        case SBT_VSCROLL:
+          m_pEdit->SetScrollPos(
+              CFX_FloatPoint(m_pEdit->GetScrollPos().x, fPos));
+          break;
+      }
+    } break;
+    case PNM_SETCARETINFO: {
+      if (PWL_CARET_INFO* pCaretInfo = (PWL_CARET_INFO*)wParam) {
+        SetCaret(pCaretInfo->bVisible, pCaretInfo->ptHead, pCaretInfo->ptFoot);
+      }
+    } break;
+  }
+}
+
+void CPWL_EditCtrl::CreateChildWnd(const PWL_CREATEPARAM& cp) {
+  if (!IsReadOnly())
+    CreateEditCaret(cp);
+}
+
+void CPWL_EditCtrl::CreateEditCaret(const PWL_CREATEPARAM& cp) {
+  if (m_pEditCaret)
+    return;
+
+  m_pEditCaret = new CPWL_Caret;
+  m_pEditCaret->SetInvalidRect(GetClientRect());
+
+  PWL_CREATEPARAM ecp = cp;
+  ecp.pParentWnd = this;
+  ecp.dwFlags = PWS_CHILD | PWS_NOREFRESHCLIP;
+  ecp.dwBorderWidth = 0;
+  ecp.nBorderStyle = BorderStyle::SOLID;
+  ecp.rcRectWnd = CFX_FloatRect(0, 0, 0, 0);
+
+  m_pEditCaret->Create(ecp);
+}
+
+void CPWL_EditCtrl::SetFontSize(FX_FLOAT fFontSize) {
+  m_pEdit->SetFontSize(fFontSize);
+}
+
+FX_FLOAT CPWL_EditCtrl::GetFontSize() const {
+  return m_pEdit->GetFontSize();
+}
+
+bool CPWL_EditCtrl::OnKeyDown(uint16_t nChar, uint32_t nFlag) {
+  if (m_bMouseDown)
+    return true;
+
+  bool bRet = CPWL_Wnd::OnKeyDown(nChar, nFlag);
+
+  // FILTER
+  switch (nChar) {
+    default:
+      return false;
+    case FWL_VKEY_Delete:
+    case FWL_VKEY_Up:
+    case FWL_VKEY_Down:
+    case FWL_VKEY_Left:
+    case FWL_VKEY_Right:
+    case FWL_VKEY_Home:
+    case FWL_VKEY_End:
+    case FWL_VKEY_Insert:
+    case 'C':
+    case 'V':
+    case 'X':
+    case 'A':
+    case 'Z':
+    case 'c':
+    case 'v':
+    case 'x':
+    case 'a':
+    case 'z':
+      break;
+  }
+
+  if (nChar == FWL_VKEY_Delete && m_pEdit->IsSelected())
+    nChar = FWL_VKEY_Unknown;
+
+  switch (nChar) {
+    case FWL_VKEY_Delete:
+      Delete();
+      return true;
+    case FWL_VKEY_Insert:
+      if (IsSHIFTpressed(nFlag))
+        PasteText();
+      return true;
+    case FWL_VKEY_Up:
+      m_pEdit->OnVK_UP(IsSHIFTpressed(nFlag), false);
+      return true;
+    case FWL_VKEY_Down:
+      m_pEdit->OnVK_DOWN(IsSHIFTpressed(nFlag), false);
+      return true;
+    case FWL_VKEY_Left:
+      m_pEdit->OnVK_LEFT(IsSHIFTpressed(nFlag), false);
+      return true;
+    case FWL_VKEY_Right:
+      m_pEdit->OnVK_RIGHT(IsSHIFTpressed(nFlag), false);
+      return true;
+    case FWL_VKEY_Home:
+      m_pEdit->OnVK_HOME(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
+      return true;
+    case FWL_VKEY_End:
+      m_pEdit->OnVK_END(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
+      return true;
+    case FWL_VKEY_Unknown:
+      if (!IsSHIFTpressed(nFlag))
+        Clear();
+      else
+        CutText();
+      return true;
+    default:
+      break;
+  }
+
+  return bRet;
+}
+
+bool CPWL_EditCtrl::OnChar(uint16_t nChar, uint32_t nFlag) {
+  if (m_bMouseDown)
+    return true;
+
+  CPWL_Wnd::OnChar(nChar, nFlag);
+
+  // FILTER
+  switch (nChar) {
+    case 0x0A:
+    case 0x1B:
+      return false;
+    default:
+      break;
+  }
+
+  bool bCtrl = IsCTRLpressed(nFlag);
+  bool bAlt = IsALTpressed(nFlag);
+  bool bShift = IsSHIFTpressed(nFlag);
+
+  uint16_t word = nChar;
+
+  if (bCtrl && !bAlt) {
+    switch (nChar) {
+      case 'C' - 'A' + 1:
+        CopyText();
+        return true;
+      case 'V' - 'A' + 1:
+        PasteText();
+        return true;
+      case 'X' - 'A' + 1:
+        CutText();
+        return true;
+      case 'A' - 'A' + 1:
+        SelectAll();
+        return true;
+      case 'Z' - 'A' + 1:
+        if (bShift)
+          Redo();
+        else
+          Undo();
+        return true;
+      default:
+        if (nChar < 32)
+          return false;
+    }
+  }
+
+  if (IsReadOnly())
+    return true;
+
+  if (m_pEdit->IsSelected() && word == FWL_VKEY_Back)
+    word = FWL_VKEY_Unknown;
+
+  Clear();
+
+  switch (word) {
+    case FWL_VKEY_Back:
+      Backspace();
+      break;
+    case FWL_VKEY_Return:
+      InsertReturn();
+      break;
+    case FWL_VKEY_Unknown:
+      break;
+    default:
+      InsertWord(word, GetCharSet());
+      break;
+  }
+
+  return true;
+}
+
+bool CPWL_EditCtrl::OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag) {
+  CPWL_Wnd::OnLButtonDown(point, nFlag);
+
+  if (ClientHitTest(point)) {
+    if (m_bMouseDown)
+      InvalidateRect();
+
+    m_bMouseDown = true;
+    SetCapture();
+
+    m_pEdit->OnMouseDown(point, IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
+  }
+
+  return true;
+}
+
+bool CPWL_EditCtrl::OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) {
+  CPWL_Wnd::OnLButtonUp(point, nFlag);
+
+  if (m_bMouseDown) {
+    // can receive keybord message
+    if (ClientHitTest(point) && !IsFocused())
+      SetFocus();
+
+    ReleaseCapture();
+    m_bMouseDown = false;
+  }
+
+  return true;
+}
+
+bool CPWL_EditCtrl::OnMouseMove(const CFX_FloatPoint& point, uint32_t nFlag) {
+  CPWL_Wnd::OnMouseMove(point, nFlag);
+
+  if (m_bMouseDown)
+    m_pEdit->OnMouseMove(point, false, false);
+
+  return true;
+}
+
+CFX_FloatRect CPWL_EditCtrl::GetContentRect() const {
+  return m_pEdit->GetContentRect();
+}
+
+void CPWL_EditCtrl::SetEditCaret(bool bVisible) {
+  CFX_FloatPoint ptHead;
+  CFX_FloatPoint ptFoot;
+  if (bVisible)
+    GetCaretInfo(ptHead, ptFoot);
+
+  CPVT_WordPlace wpTemp = m_pEdit->GetCaretWordPlace();
+  IOnSetCaret(bVisible, ptHead, ptFoot, wpTemp);
+}
+
+void CPWL_EditCtrl::GetCaretInfo(CFX_FloatPoint& ptHead,
+                                 CFX_FloatPoint& ptFoot) const {
+  CFX_Edit_Iterator* pIterator = m_pEdit->GetIterator();
+  pIterator->SetAt(m_pEdit->GetCaret());
+  CPVT_Word word;
+  CPVT_Line line;
+  if (pIterator->GetWord(word)) {
+    ptHead.x = word.ptWord.x + word.fWidth;
+    ptHead.y = word.ptWord.y + word.fAscent;
+    ptFoot.x = word.ptWord.x + word.fWidth;
+    ptFoot.y = word.ptWord.y + word.fDescent;
+  } else if (pIterator->GetLine(line)) {
+    ptHead.x = line.ptLine.x;
+    ptHead.y = line.ptLine.y + line.fLineAscent;
+    ptFoot.x = line.ptLine.x;
+    ptFoot.y = line.ptLine.y + line.fLineDescent;
+  }
+}
+
+void CPWL_EditCtrl::GetCaretPos(int32_t& x, int32_t& y) const {
+  CFX_FloatPoint ptHead;
+  CFX_FloatPoint ptFoot;
+  GetCaretInfo(ptHead, ptFoot);
+  PWLtoWnd(ptHead, x, y);
+}
+
+void CPWL_EditCtrl::SetCaret(bool bVisible,
+                             const CFX_FloatPoint& ptHead,
+                             const CFX_FloatPoint& ptFoot) {
+  if (m_pEditCaret) {
+    if (!IsFocused() || m_pEdit->IsSelected())
+      bVisible = false;
+
+    m_pEditCaret->SetCaret(bVisible, ptHead, ptFoot);
+  }
+}
+
+CFX_WideString CPWL_EditCtrl::GetText() const {
+  return m_pEdit->GetText();
+}
+
+void CPWL_EditCtrl::SetSel(int32_t nStartChar, int32_t nEndChar) {
+  m_pEdit->SetSel(nStartChar, nEndChar);
+}
+
+void CPWL_EditCtrl::GetSel(int32_t& nStartChar, int32_t& nEndChar) const {
+  m_pEdit->GetSel(nStartChar, nEndChar);
+}
+
+void CPWL_EditCtrl::Clear() {
+  if (!IsReadOnly())
+    m_pEdit->Clear();
+}
+
+void CPWL_EditCtrl::SelectAll() {
+  m_pEdit->SelectAll();
+}
+
+void CPWL_EditCtrl::Paint() {
+  m_pEdit->Paint();
+}
+
+void CPWL_EditCtrl::EnableRefresh(bool bRefresh) {
+  m_pEdit->EnableRefresh(bRefresh);
+}
+
+int32_t CPWL_EditCtrl::GetCaret() const {
+  return m_pEdit->GetCaret();
+}
+
+void CPWL_EditCtrl::SetCaret(int32_t nPos) {
+  m_pEdit->SetCaret(nPos);
+}
+
+int32_t CPWL_EditCtrl::GetTotalWords() const {
+  return m_pEdit->GetTotalWords();
+}
+
+void CPWL_EditCtrl::SetScrollPos(const CFX_FloatPoint& point) {
+  m_pEdit->SetScrollPos(point);
+}
+
+CFX_FloatPoint CPWL_EditCtrl::GetScrollPos() const {
+  return m_pEdit->GetScrollPos();
+}
+
+CPDF_Font* CPWL_EditCtrl::GetCaretFont() const {
+  int32_t nFontIndex = 0;
+
+  CFX_Edit_Iterator* pIterator = m_pEdit->GetIterator();
+  pIterator->SetAt(m_pEdit->GetCaret());
+  CPVT_Word word;
+  CPVT_Section section;
+  if (pIterator->GetWord(word)) {
+    nFontIndex = word.nFontIndex;
+  } else if (HasFlag(PES_RICH)) {
+    if (pIterator->GetSection(section)) {
+      nFontIndex = section.WordProps.nFontIndex;
+    }
+  }
+
+  if (IPVT_FontMap* pFontMap = GetFontMap())
+    return pFontMap->GetPDFFont(nFontIndex);
+
+  return nullptr;
+}
+
+FX_FLOAT CPWL_EditCtrl::GetCaretFontSize() const {
+  FX_FLOAT fFontSize = GetFontSize();
+
+  CFX_Edit_Iterator* pIterator = m_pEdit->GetIterator();
+  pIterator->SetAt(m_pEdit->GetCaret());
+  CPVT_Word word;
+  CPVT_Section section;
+  if (pIterator->GetWord(word)) {
+    fFontSize = word.fFontSize;
+  } else if (HasFlag(PES_RICH)) {
+    if (pIterator->GetSection(section)) {
+      fFontSize = section.WordProps.fFontSize;
+    }
+  }
+
+  return fFontSize;
+}
+
+void CPWL_EditCtrl::SetText(const CFX_WideString& wsText) {
+  m_pEdit->SetText(wsText);
+}
+
+void CPWL_EditCtrl::CopyText() {}
+
+void CPWL_EditCtrl::PasteText() {}
+
+void CPWL_EditCtrl::CutText() {}
+
+void CPWL_EditCtrl::ShowVScrollBar(bool bShow) {}
+
+void CPWL_EditCtrl::InsertText(const CFX_WideString& wsText) {
+  if (!IsReadOnly())
+    m_pEdit->InsertText(wsText, FXFONT_DEFAULT_CHARSET);
+}
+
+void CPWL_EditCtrl::InsertWord(uint16_t word, int32_t nCharset) {
+  if (!IsReadOnly())
+    m_pEdit->InsertWord(word, nCharset);
+}
+
+void CPWL_EditCtrl::InsertReturn() {
+  if (!IsReadOnly())
+    m_pEdit->InsertReturn();
+}
+
+void CPWL_EditCtrl::Delete() {
+  if (!IsReadOnly())
+    m_pEdit->Delete();
+}
+
+void CPWL_EditCtrl::Backspace() {
+  if (!IsReadOnly())
+    m_pEdit->Backspace();
+}
+
+bool CPWL_EditCtrl::CanUndo() const {
+  return !IsReadOnly() && m_pEdit->CanUndo();
+}
+
+bool CPWL_EditCtrl::CanRedo() const {
+  return !IsReadOnly() && m_pEdit->CanRedo();
+}
+
+void CPWL_EditCtrl::Redo() {
+  if (CanRedo())
+    m_pEdit->Redo();
+}
+
+void CPWL_EditCtrl::Undo() {
+  if (CanUndo())
+    m_pEdit->Undo();
+}
+
+void CPWL_EditCtrl::IOnSetScrollInfoY(FX_FLOAT fPlateMin,
+                                      FX_FLOAT fPlateMax,
+                                      FX_FLOAT fContentMin,
+                                      FX_FLOAT fContentMax,
+                                      FX_FLOAT fSmallStep,
+                                      FX_FLOAT fBigStep) {
+  PWL_SCROLL_INFO Info;
+
+  Info.fPlateWidth = fPlateMax - fPlateMin;
+  Info.fContentMin = fContentMin;
+  Info.fContentMax = fContentMax;
+  Info.fSmallStep = fSmallStep;
+  Info.fBigStep = fBigStep;
+
+  OnNotify(this, PNM_SETSCROLLINFO, SBT_VSCROLL, (intptr_t)&Info);
+
+  if (IsFloatBigger(Info.fPlateWidth, Info.fContentMax - Info.fContentMin) ||
+      IsFloatEqual(Info.fPlateWidth, Info.fContentMax - Info.fContentMin)) {
+    ShowVScrollBar(false);
+  } else {
+    ShowVScrollBar(true);
+  }
+}
+
+void CPWL_EditCtrl::IOnSetScrollPosY(FX_FLOAT fy) {
+  OnNotify(this, PNM_SETSCROLLPOS, SBT_VSCROLL, (intptr_t)&fy);
+}
+
+void CPWL_EditCtrl::IOnSetCaret(bool bVisible,
+                                const CFX_FloatPoint& ptHead,
+                                const CFX_FloatPoint& ptFoot,
+                                const CPVT_WordPlace& place) {
+  PWL_CARET_INFO cInfo;
+  cInfo.bVisible = bVisible;
+  cInfo.ptHead = ptHead;
+  cInfo.ptFoot = ptFoot;
+
+  OnNotify(this, PNM_SETCARETINFO, (intptr_t)&cInfo, (intptr_t) nullptr);
+}
+
+void CPWL_EditCtrl::IOnCaretChange(const CPVT_SecProps& secProps,
+                                   const CPVT_WordProps& wordProps) {}
+
+void CPWL_EditCtrl::IOnContentChange(const CFX_FloatRect& rcContent) {}
+
+void CPWL_EditCtrl::IOnInvalidateRect(CFX_FloatRect* pRect) {
+  InvalidateRect(pRect);
+}
+
+int32_t CPWL_EditCtrl::GetCharSet() const {
+  return m_nCharSet < 0 ? FXFONT_DEFAULT_CHARSET : m_nCharSet;
+}
+
+void CPWL_EditCtrl::GetTextRange(const CFX_FloatRect& rect,
+                                 int32_t& nStartChar,
+                                 int32_t& nEndChar) const {
+  nStartChar = m_pEdit->WordPlaceToWordIndex(
+      m_pEdit->SearchWordPlace(CFX_FloatPoint(rect.left, rect.top)));
+  nEndChar = m_pEdit->WordPlaceToWordIndex(
+      m_pEdit->SearchWordPlace(CFX_FloatPoint(rect.right, rect.bottom)));
+}
+
+CFX_WideString CPWL_EditCtrl::GetText(int32_t& nStartChar,
+                                      int32_t& nEndChar) const {
+  CPVT_WordPlace wpStart = m_pEdit->WordIndexToWordPlace(nStartChar);
+  CPVT_WordPlace wpEnd = m_pEdit->WordIndexToWordPlace(nEndChar);
+  return m_pEdit->GetRangeText(CPVT_WordRange(wpStart, wpEnd));
+}
+
+void CPWL_EditCtrl::SetReadyToInput() {
+  if (m_bMouseDown) {
+    ReleaseCapture();
+    m_bMouseDown = false;
+  }
+}
diff --git a/fpdfsdk/pdfwindow/PWL_EditCtrl.h b/fpdfsdk/pdfwindow/PWL_EditCtrl.h
new file mode 100644
index 0000000..3ff5cc6
--- /dev/null
+++ b/fpdfsdk/pdfwindow/PWL_EditCtrl.h
@@ -0,0 +1,142 @@
+// 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_PDFWINDOW_PWL_EDITCTRL_H_
+#define FPDFSDK_PDFWINDOW_PWL_EDITCTRL_H_
+
+#include <memory>
+
+#include "core/fxcrt/fx_string.h"
+#include "fpdfsdk/fxedit/fx_edit.h"
+#include "fpdfsdk/pdfwindow/PWL_Wnd.h"
+
+class CFX_Edit;
+class CPWL_Caret;
+class CPWL_Edit;
+class CPWL_EditCtrl;
+struct CPVT_SecProps;
+struct CPVT_WordPlace;
+struct CPVT_WordProps;
+struct CPVT_WordRange;
+
+enum PWL_EDIT_ALIGNFORMAT_H { PEAH_LEFT = 0, PEAH_MIDDLE, PEAH_RIGHT };
+
+enum PWL_EDIT_ALIGNFORMAT_V { PEAV_TOP = 0, PEAV_CENTER, PEAV_BOTTOM };
+
+class CPWL_EditCtrl : public CPWL_Wnd {
+  friend class CPWL_Edit_Notify;
+
+ public:
+  CPWL_EditCtrl();
+  ~CPWL_EditCtrl() override;
+
+  CFX_FloatRect GetContentRect() const;
+  void GetCaretPos(int32_t& x, int32_t& y) const;
+
+  CFX_WideString GetText() const;
+  void SetSel(int32_t nStartChar, int32_t nEndChar);
+  void GetSel(int32_t& nStartChar, int32_t& nEndChar) const;
+  void GetTextRange(const CFX_FloatRect& rect,
+                    int32_t& nStartChar,
+                    int32_t& nEndChar) const;
+  CFX_WideString GetText(int32_t& nStartChar, int32_t& nEndChar) const;
+  void Clear();
+  void SelectAll();
+
+  int32_t GetCaret() const;
+  void SetCaret(int32_t nPos);
+  int32_t GetTotalWords() const;
+
+  void Paint();
+
+  void EnableRefresh(bool bRefresh);
+  CFX_FloatPoint GetScrollPos() const;
+  void SetScrollPos(const CFX_FloatPoint& point);
+
+  void SetCharSet(uint8_t nCharSet) { m_nCharSet = nCharSet; }
+  int32_t GetCharSet() const;
+
+  void SetCodePage(int32_t nCodePage) { m_nCodePage = nCodePage; }
+  int32_t GetCodePage() const { return m_nCodePage; }
+
+  CPDF_Font* GetCaretFont() const;
+  FX_FLOAT GetCaretFontSize() const;
+
+  bool CanUndo() const;
+  bool CanRedo() const;
+  void Redo();
+  void Undo();
+
+  void SetReadyToInput();
+
+  // CPWL_Wnd
+  void OnCreate(PWL_CREATEPARAM& cp) override;
+  void OnCreated() override;
+  bool OnKeyDown(uint16_t nChar, uint32_t nFlag) override;
+  bool OnChar(uint16_t nChar, uint32_t nFlag) override;
+  bool OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag) override;
+  bool OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) override;
+  bool OnMouseMove(const CFX_FloatPoint& point, uint32_t nFlag) override;
+  void OnNotify(CPWL_Wnd* pWnd,
+                uint32_t msg,
+                intptr_t wParam = 0,
+                intptr_t lParam = 0) override;
+  void CreateChildWnd(const PWL_CREATEPARAM& cp) override;
+  void RePosChildWnd() override;
+  void SetFontSize(FX_FLOAT fFontSize) override;
+  FX_FLOAT GetFontSize() const override;
+  void SetCursor() override;
+
+  void IOnSetScrollInfoY(FX_FLOAT fPlateMin,
+                         FX_FLOAT fPlateMax,
+                         FX_FLOAT fContentMin,
+                         FX_FLOAT fContentMax,
+                         FX_FLOAT fSmallStep,
+                         FX_FLOAT fBigStep);
+  void IOnSetScrollPosY(FX_FLOAT fy);
+  void IOnSetCaret(bool bVisible,
+                   const CFX_FloatPoint& ptHead,
+                   const CFX_FloatPoint& ptFoot,
+                   const CPVT_WordPlace& place);
+  void IOnCaretChange(const CPVT_SecProps& secProps,
+                      const CPVT_WordProps& wordProps);
+  void IOnContentChange(const CFX_FloatRect& rcContent);
+  void IOnInvalidateRect(CFX_FloatRect* pRect);
+
+ protected:
+  void InsertText(const CFX_WideString& wsText);
+  void SetText(const CFX_WideString& wsText);
+  void CopyText();
+  void PasteText();
+  void CutText();
+  void ShowVScrollBar(bool bShow);
+  void InsertWord(uint16_t word, int32_t nCharset);
+  void InsertReturn();
+
+  bool IsWndHorV();
+
+  void Delete();
+  void Backspace();
+
+  void GetCaretInfo(CFX_FloatPoint& ptHead, CFX_FloatPoint& ptFoot) const;
+  void SetCaret(bool bVisible,
+                const CFX_FloatPoint& ptHead,
+                const CFX_FloatPoint& ptFoot);
+
+  void SetEditCaret(bool bVisible);
+
+  std::unique_ptr<CFX_Edit> m_pEdit;
+  CPWL_Caret* m_pEditCaret;
+  bool m_bMouseDown;
+
+ private:
+  void CreateEditCaret(const PWL_CREATEPARAM& cp);
+
+  int32_t m_nCharSet;
+  int32_t m_nCodePage;
+};
+
+#endif  // FPDFSDK_PDFWINDOW_PWL_EDITCTRL_H_
diff --git a/fpdfsdk/pdfwindow/PWL_FontMap.cpp b/fpdfsdk/pdfwindow/PWL_FontMap.cpp
new file mode 100644
index 0000000..9a2962c
--- /dev/null
+++ b/fpdfsdk/pdfwindow/PWL_FontMap.cpp
@@ -0,0 +1,426 @@
+// 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
+
+#include "fpdfsdk/pdfwindow/PWL_FontMap.h"
+
+#include <utility>
+
+#include "core/fpdfapi/cpdf_modulemgr.h"
+#include "core/fpdfapi/font/cpdf_font.h"
+#include "core/fpdfapi/font/cpdf_fontencoding.h"
+#include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/cpdf_parser.h"
+#include "core/fpdfdoc/ipvt_fontmap.h"
+#include "fpdfsdk/pdfwindow/PWL_Wnd.h"
+#include "third_party/base/ptr_util.h"
+#include "third_party/base/stl_util.h"
+
+namespace {
+
+const char kDefaultFontName[] = "Helvetica";
+
+const char* const g_sDEStandardFontName[] = {"Courier",
+                                             "Courier-Bold",
+                                             "Courier-BoldOblique",
+                                             "Courier-Oblique",
+                                             "Helvetica",
+                                             "Helvetica-Bold",
+                                             "Helvetica-BoldOblique",
+                                             "Helvetica-Oblique",
+                                             "Times-Roman",
+                                             "Times-Bold",
+                                             "Times-Italic",
+                                             "Times-BoldItalic",
+                                             "Symbol",
+                                             "ZapfDingbats"};
+
+}  // namespace
+
+CPWL_FontMap::CPWL_FontMap(CFX_SystemHandler* pSystemHandler)
+    : m_pSystemHandler(pSystemHandler) {
+  ASSERT(m_pSystemHandler);
+}
+
+CPWL_FontMap::~CPWL_FontMap() {
+  Empty();
+}
+
+CPDF_Document* CPWL_FontMap::GetDocument() {
+  if (!m_pPDFDoc) {
+    if (CPDF_ModuleMgr::Get()) {
+      m_pPDFDoc = pdfium::MakeUnique<CPDF_Document>(nullptr);
+      m_pPDFDoc->CreateNewDoc();
+    }
+  }
+
+  return m_pPDFDoc.get();
+}
+
+CPDF_Font* CPWL_FontMap::GetPDFFont(int32_t nFontIndex) {
+  if (nFontIndex >= 0 && nFontIndex < pdfium::CollectionSize<int32_t>(m_Data)) {
+    if (m_Data[nFontIndex])
+      return m_Data[nFontIndex]->pFont;
+  }
+  return nullptr;
+}
+
+CFX_ByteString CPWL_FontMap::GetPDFFontAlias(int32_t nFontIndex) {
+  if (nFontIndex >= 0 && nFontIndex < pdfium::CollectionSize<int32_t>(m_Data)) {
+    if (m_Data[nFontIndex])
+      return m_Data[nFontIndex]->sFontName;
+  }
+  return CFX_ByteString();
+}
+
+bool CPWL_FontMap::KnowWord(int32_t nFontIndex, uint16_t word) {
+  if (nFontIndex >= 0 && nFontIndex < pdfium::CollectionSize<int32_t>(m_Data)) {
+    if (m_Data[nFontIndex])
+      return CharCodeFromUnicode(nFontIndex, word) >= 0;
+  }
+  return false;
+}
+
+int32_t CPWL_FontMap::GetWordFontIndex(uint16_t word,
+                                       int32_t nCharset,
+                                       int32_t nFontIndex) {
+  if (nFontIndex > 0) {
+    if (KnowWord(nFontIndex, word))
+      return nFontIndex;
+  } else {
+    if (const CPWL_FontMap_Data* pData = GetFontMapData(0)) {
+      if (nCharset == FXFONT_DEFAULT_CHARSET ||
+          pData->nCharset == FXFONT_SYMBOL_CHARSET ||
+          nCharset == pData->nCharset) {
+        if (KnowWord(0, word))
+          return 0;
+      }
+    }
+  }
+
+  int32_t nNewFontIndex =
+      GetFontIndex(GetNativeFontName(nCharset), nCharset, true);
+  if (nNewFontIndex >= 0) {
+    if (KnowWord(nNewFontIndex, word))
+      return nNewFontIndex;
+  }
+  nNewFontIndex =
+      GetFontIndex("Arial Unicode MS", FXFONT_DEFAULT_CHARSET, false);
+  if (nNewFontIndex >= 0) {
+    if (KnowWord(nNewFontIndex, word))
+      return nNewFontIndex;
+  }
+  return -1;
+}
+
+int32_t CPWL_FontMap::CharCodeFromUnicode(int32_t nFontIndex, uint16_t word) {
+  if (nFontIndex < 0 || nFontIndex >= pdfium::CollectionSize<int32_t>(m_Data))
+    return -1;
+
+  CPWL_FontMap_Data* pData = m_Data[nFontIndex].get();
+  if (!pData || !pData->pFont)
+    return -1;
+
+  if (pData->pFont->IsUnicodeCompatible())
+    return pData->pFont->CharCodeFromUnicode(word);
+
+  return word < 0xFF ? word : -1;
+}
+
+CFX_ByteString CPWL_FontMap::GetNativeFontName(int32_t nCharset) {
+  for (const auto& pData : m_NativeFont) {
+    if (pData && pData->nCharset == nCharset)
+      return pData->sFontName;
+  }
+
+  CFX_ByteString sNew = GetNativeFont(nCharset);
+  if (sNew.IsEmpty())
+    return CFX_ByteString();
+
+  auto pNewData = pdfium::MakeUnique<CPWL_FontMap_Native>();
+  pNewData->nCharset = nCharset;
+  pNewData->sFontName = sNew;
+  m_NativeFont.push_back(std::move(pNewData));
+  return sNew;
+}
+
+void CPWL_FontMap::Empty() {
+  m_Data.clear();
+  m_NativeFont.clear();
+}
+
+void CPWL_FontMap::Initialize() {
+  GetFontIndex(kDefaultFontName, FXFONT_ANSI_CHARSET, false);
+}
+
+bool CPWL_FontMap::IsStandardFont(const CFX_ByteString& sFontName) {
+  for (size_t i = 0; i < FX_ArraySize(g_sDEStandardFontName); ++i) {
+    if (sFontName == g_sDEStandardFontName[i])
+      return true;
+  }
+
+  return false;
+}
+
+int32_t CPWL_FontMap::FindFont(const CFX_ByteString& sFontName,
+                               int32_t nCharset) {
+  int32_t i = 0;
+  for (const auto& pData : m_Data) {
+    if (pData &&
+        (nCharset == FXFONT_DEFAULT_CHARSET || nCharset == pData->nCharset) &&
+        (sFontName.IsEmpty() || pData->sFontName == sFontName)) {
+      return i;
+    }
+    ++i;
+  }
+  return -1;
+}
+
+int32_t CPWL_FontMap::GetFontIndex(const CFX_ByteString& sFontName,
+                                   int32_t nCharset,
+                                   bool bFind) {
+  int32_t nFontIndex = FindFont(EncodeFontAlias(sFontName, nCharset), nCharset);
+  if (nFontIndex >= 0)
+    return nFontIndex;
+
+  CFX_ByteString sAlias;
+  CPDF_Font* pFont = nullptr;
+  if (bFind)
+    pFont = FindFontSameCharset(sAlias, nCharset);
+
+  if (!pFont) {
+    CFX_ByteString sTemp = sFontName;
+    pFont = AddFontToDocument(GetDocument(), sTemp, nCharset);
+    sAlias = EncodeFontAlias(sTemp, nCharset);
+  }
+  AddedFont(pFont, sAlias);
+  return AddFontData(pFont, sAlias, nCharset);
+}
+
+CPDF_Font* CPWL_FontMap::FindFontSameCharset(CFX_ByteString& sFontAlias,
+                                             int32_t nCharset) {
+  return nullptr;
+}
+
+int32_t CPWL_FontMap::AddFontData(CPDF_Font* pFont,
+                                  const CFX_ByteString& sFontAlias,
+                                  int32_t nCharset) {
+  auto pNewData = pdfium::MakeUnique<CPWL_FontMap_Data>();
+  pNewData->pFont = pFont;
+  pNewData->sFontName = sFontAlias;
+  pNewData->nCharset = nCharset;
+  m_Data.push_back(std::move(pNewData));
+  return pdfium::CollectionSize<int32_t>(m_Data) - 1;
+}
+
+void CPWL_FontMap::AddedFont(CPDF_Font* pFont,
+                             const CFX_ByteString& sFontAlias) {}
+
+CFX_ByteString CPWL_FontMap::GetNativeFont(int32_t nCharset) {
+  if (nCharset == FXFONT_DEFAULT_CHARSET)
+    nCharset = GetNativeCharset();
+
+  CFX_ByteString sFontName = GetDefaultFontByCharset(nCharset);
+  if (!m_pSystemHandler->FindNativeTrueTypeFont(sFontName))
+    return CFX_ByteString();
+
+  return sFontName;
+}
+
+CPDF_Font* CPWL_FontMap::AddFontToDocument(CPDF_Document* pDoc,
+                                           CFX_ByteString& sFontName,
+                                           uint8_t nCharset) {
+  if (IsStandardFont(sFontName))
+    return AddStandardFont(pDoc, sFontName);
+
+  return AddSystemFont(pDoc, sFontName, nCharset);
+}
+
+CPDF_Font* CPWL_FontMap::AddStandardFont(CPDF_Document* pDoc,
+                                         CFX_ByteString& sFontName) {
+  if (!pDoc)
+    return nullptr;
+
+  CPDF_Font* pFont = nullptr;
+
+  if (sFontName == "ZapfDingbats") {
+    pFont = pDoc->AddStandardFont(sFontName.c_str(), nullptr);
+  } else {
+    CPDF_FontEncoding fe(PDFFONT_ENCODING_WINANSI);
+    pFont = pDoc->AddStandardFont(sFontName.c_str(), &fe);
+  }
+
+  return pFont;
+}
+
+CPDF_Font* CPWL_FontMap::AddSystemFont(CPDF_Document* pDoc,
+                                       CFX_ByteString& sFontName,
+                                       uint8_t nCharset) {
+  if (!pDoc)
+    return nullptr;
+
+  if (sFontName.IsEmpty())
+    sFontName = GetNativeFont(nCharset);
+  if (nCharset == FXFONT_DEFAULT_CHARSET)
+    nCharset = GetNativeCharset();
+
+  return m_pSystemHandler->AddNativeTrueTypeFontToPDF(pDoc, sFontName,
+                                                      nCharset);
+}
+
+CFX_ByteString CPWL_FontMap::EncodeFontAlias(const CFX_ByteString& sFontName,
+                                             int32_t nCharset) {
+  CFX_ByteString sPostfix;
+  sPostfix.Format("_%02X", nCharset);
+  return EncodeFontAlias(sFontName) + sPostfix;
+}
+
+CFX_ByteString CPWL_FontMap::EncodeFontAlias(const CFX_ByteString& sFontName) {
+  CFX_ByteString sRet = sFontName;
+  sRet.Remove(' ');
+  return sRet;
+}
+
+const CPWL_FontMap_Data* CPWL_FontMap::GetFontMapData(int32_t nIndex) const {
+  if (nIndex < 0 || nIndex >= pdfium::CollectionSize<int32_t>(m_Data))
+    return nullptr;
+
+  return m_Data[nIndex].get();
+}
+
+int32_t CPWL_FontMap::GetNativeCharset() {
+  uint8_t nCharset = FXFONT_ANSI_CHARSET;
+  int32_t iCodePage = FXSYS_GetACP();
+  switch (iCodePage) {
+    case 932:  // Japan
+      nCharset = FXFONT_SHIFTJIS_CHARSET;
+      break;
+    case 936:  // Chinese (PRC, Singapore)
+      nCharset = FXFONT_GB2312_CHARSET;
+      break;
+    case 950:  // Chinese (Taiwan; Hong Kong SAR, PRC)
+      nCharset = FXFONT_GB2312_CHARSET;
+      break;
+    case 1252:  // Windows 3.1 Latin 1 (US, Western Europe)
+      nCharset = FXFONT_ANSI_CHARSET;
+      break;
+    case 874:  // Thai
+      nCharset = FXFONT_THAI_CHARSET;
+      break;
+    case 949:  // Korean
+      nCharset = FXFONT_HANGUL_CHARSET;
+      break;
+    case 1200:  // Unicode (BMP of ISO 10646)
+      nCharset = FXFONT_ANSI_CHARSET;
+      break;
+    case 1250:  // Windows 3.1 Eastern European
+      nCharset = FXFONT_EASTEUROPE_CHARSET;
+      break;
+    case 1251:  // Windows 3.1 Cyrillic
+      nCharset = FXFONT_RUSSIAN_CHARSET;
+      break;
+    case 1253:  // Windows 3.1 Greek
+      nCharset = FXFONT_GREEK_CHARSET;
+      break;
+    case 1254:  // Windows 3.1 Turkish
+      nCharset = FXFONT_TURKISH_CHARSET;
+      break;
+    case 1255:  // Hebrew
+      nCharset = FXFONT_HEBREW_CHARSET;
+      break;
+    case 1256:  // Arabic
+      nCharset = FXFONT_ARABIC_CHARSET;
+      break;
+    case 1257:  // Baltic
+      nCharset = FXFONT_BALTIC_CHARSET;
+      break;
+    case 1258:  // Vietnamese
+      nCharset = FXFONT_VIETNAMESE_CHARSET;
+      break;
+    case 1361:  // Korean(Johab)
+      nCharset = FXFONT_JOHAB_CHARSET;
+      break;
+  }
+  return nCharset;
+}
+
+const FPDF_CharsetFontMap CPWL_FontMap::defaultTTFMap[] = {
+    {FXFONT_ANSI_CHARSET, "Helvetica"},
+    {FXFONT_GB2312_CHARSET, "SimSun"},
+    {FXFONT_CHINESEBIG5_CHARSET, "MingLiU"},
+    {FXFONT_SHIFTJIS_CHARSET, "MS Gothic"},
+    {FXFONT_HANGUL_CHARSET, "Batang"},
+    {FXFONT_RUSSIAN_CHARSET, "Arial"},
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ || \
+    _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+    {FXFONT_EASTEUROPE_CHARSET, "Arial"},
+#else
+    {FXFONT_EASTEUROPE_CHARSET, "Tahoma"},
+#endif
+    {FXFONT_ARABIC_CHARSET, "Arial"},
+    {-1, nullptr}};
+
+CFX_ByteString CPWL_FontMap::GetDefaultFontByCharset(int32_t nCharset) {
+  int i = 0;
+  while (defaultTTFMap[i].charset != -1) {
+    if (nCharset == defaultTTFMap[i].charset)
+      return defaultTTFMap[i].fontname;
+    ++i;
+  }
+  return "";
+}
+
+int32_t CPWL_FontMap::CharSetFromUnicode(uint16_t word, int32_t nOldCharset) {
+  // to avoid CJK Font to show ASCII
+  if (word < 0x7F)
+    return FXFONT_ANSI_CHARSET;
+  // follow the old charset
+  if (nOldCharset != FXFONT_DEFAULT_CHARSET)
+    return nOldCharset;
+
+  // find new charset
+  if ((word >= 0x4E00 && word <= 0x9FA5) ||
+      (word >= 0xE7C7 && word <= 0xE7F3) ||
+      (word >= 0x3000 && word <= 0x303F) ||
+      (word >= 0x2000 && word <= 0x206F)) {
+    return FXFONT_GB2312_CHARSET;
+  }
+
+  if (((word >= 0x3040) && (word <= 0x309F)) ||
+      ((word >= 0x30A0) && (word <= 0x30FF)) ||
+      ((word >= 0x31F0) && (word <= 0x31FF)) ||
+      ((word >= 0xFF00) && (word <= 0xFFEF))) {
+    return FXFONT_SHIFTJIS_CHARSET;
+  }
+
+  if (((word >= 0xAC00) && (word <= 0xD7AF)) ||
+      ((word >= 0x1100) && (word <= 0x11FF)) ||
+      ((word >= 0x3130) && (word <= 0x318F))) {
+    return FXFONT_HANGUL_CHARSET;
+  }
+
+  if (word >= 0x0E00 && word <= 0x0E7F)
+    return FXFONT_THAI_CHARSET;
+
+  if ((word >= 0x0370 && word <= 0x03FF) || (word >= 0x1F00 && word <= 0x1FFF))
+    return FXFONT_GREEK_CHARSET;
+
+  if ((word >= 0x0600 && word <= 0x06FF) || (word >= 0xFB50 && word <= 0xFEFC))
+    return FXFONT_ARABIC_CHARSET;
+
+  if (word >= 0x0590 && word <= 0x05FF)
+    return FXFONT_HEBREW_CHARSET;
+
+  if (word >= 0x0400 && word <= 0x04FF)
+    return FXFONT_RUSSIAN_CHARSET;
+
+  if (word >= 0x0100 && word <= 0x024F)
+    return FXFONT_EASTEUROPE_CHARSET;
+
+  if (word >= 0x1E00 && word <= 0x1EFF)
+    return FXFONT_VIETNAMESE_CHARSET;
+
+  return FXFONT_ANSI_CHARSET;
+}
diff --git a/fpdfsdk/pdfwindow/PWL_FontMap.h b/fpdfsdk/pdfwindow/PWL_FontMap.h
new file mode 100644
index 0000000..c14fcd7
--- /dev/null
+++ b/fpdfsdk/pdfwindow/PWL_FontMap.h
@@ -0,0 +1,95 @@
+// 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_PDFWINDOW_PWL_FONTMAP_H_
+#define FPDFSDK_PDFWINDOW_PWL_FONTMAP_H_
+
+#include <memory>
+#include <vector>
+
+#include "core/fpdfdoc/ipvt_fontmap.h"
+#include "core/fxge/fx_font.h"
+#include "fpdfsdk/fxedit/fx_edit.h"
+#include "public/fpdf_sysfontinfo.h"
+
+class CPDF_Document;
+class CFX_SystemHandler;
+
+struct CPWL_FontMap_Data {
+  CPDF_Font* pFont;
+  int32_t nCharset;
+  CFX_ByteString sFontName;
+};
+
+struct CPWL_FontMap_Native {
+  int32_t nCharset;
+  CFX_ByteString sFontName;
+};
+
+class CPWL_FontMap : public IPVT_FontMap {
+ public:
+  explicit CPWL_FontMap(CFX_SystemHandler* pSystemHandler);
+  ~CPWL_FontMap() override;
+
+  // IPVT_FontMap
+  CPDF_Font* GetPDFFont(int32_t nFontIndex) override;
+  CFX_ByteString GetPDFFontAlias(int32_t nFontIndex) override;
+  int32_t GetWordFontIndex(uint16_t word,
+                           int32_t nCharset,
+                           int32_t nFontIndex) override;
+  int32_t CharCodeFromUnicode(int32_t nFontIndex, uint16_t word) override;
+  int32_t CharSetFromUnicode(uint16_t word, int32_t nOldCharset) override;
+
+  const CPWL_FontMap_Data* GetFontMapData(int32_t nIndex) const;
+  static int32_t GetNativeCharset();
+  CFX_ByteString GetNativeFontName(int32_t nCharset);
+
+  static CFX_ByteString GetDefaultFontByCharset(int32_t nCharset);
+  static const FPDF_CharsetFontMap defaultTTFMap[];
+
+ protected:
+  virtual void Initialize();
+  virtual CPDF_Document* GetDocument();
+  virtual CPDF_Font* FindFontSameCharset(CFX_ByteString& sFontAlias,
+                                         int32_t nCharset);
+  virtual void AddedFont(CPDF_Font* pFont, const CFX_ByteString& sFontAlias);
+
+  bool KnowWord(int32_t nFontIndex, uint16_t word);
+
+  void Empty();
+  int32_t GetFontIndex(const CFX_ByteString& sFontName,
+                       int32_t nCharset,
+                       bool bFind);
+  int32_t AddFontData(CPDF_Font* pFont,
+                      const CFX_ByteString& sFontAlias,
+                      int32_t nCharset = FXFONT_DEFAULT_CHARSET);
+
+  CFX_ByteString EncodeFontAlias(const CFX_ByteString& sFontName,
+                                 int32_t nCharset);
+  CFX_ByteString EncodeFontAlias(const CFX_ByteString& sFontName);
+
+  std::vector<std::unique_ptr<CPWL_FontMap_Data>> m_Data;
+  std::vector<std::unique_ptr<CPWL_FontMap_Native>> m_NativeFont;
+
+ private:
+  int32_t FindFont(const CFX_ByteString& sFontName,
+                   int32_t nCharset = FXFONT_DEFAULT_CHARSET);
+
+  CFX_ByteString GetNativeFont(int32_t nCharset);
+  CPDF_Font* AddFontToDocument(CPDF_Document* pDoc,
+                               CFX_ByteString& sFontName,
+                               uint8_t nCharset);
+  bool IsStandardFont(const CFX_ByteString& sFontName);
+  CPDF_Font* AddStandardFont(CPDF_Document* pDoc, CFX_ByteString& sFontName);
+  CPDF_Font* AddSystemFont(CPDF_Document* pDoc,
+                           CFX_ByteString& sFontName,
+                           uint8_t nCharset);
+
+  std::unique_ptr<CPDF_Document> m_pPDFDoc;
+  CFX_SystemHandler* const m_pSystemHandler;
+};
+
+#endif  // FPDFSDK_PDFWINDOW_PWL_FONTMAP_H_
diff --git a/fpdfsdk/src/pdfwindow/PWL_Icon.cpp b/fpdfsdk/pdfwindow/PWL_Icon.cpp
similarity index 81%
rename from fpdfsdk/src/pdfwindow/PWL_Icon.cpp
rename to fpdfsdk/pdfwindow/PWL_Icon.cpp
index 6afd76c..877921d 100644
--- a/fpdfsdk/src/pdfwindow/PWL_Icon.cpp
+++ b/fpdfsdk/pdfwindow/PWL_Icon.cpp
@@ -4,11 +4,14 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#include "fpdfsdk/include/pdfwindow/PWL_Icon.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Wnd.h"
+#include "fpdfsdk/pdfwindow/PWL_Icon.h"
 
-CPWL_Image::CPWL_Image() : m_pPDFStream(NULL) {}
+#include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfapi/parser/cpdf_stream.h"
+#include "fpdfsdk/pdfwindow/PWL_Utils.h"
+#include "fpdfsdk/pdfwindow/PWL_Wnd.h"
+
+CPWL_Image::CPWL_Image() : m_pPDFStream(nullptr) {}
 
 CPWL_Image::~CPWL_Image() {}
 
@@ -16,7 +19,7 @@
   CFX_ByteTextBuf sAppStream;
 
   CFX_ByteString sAlias = GetImageAlias();
-  CPDF_Rect rcPlate = GetClientRect();
+  CFX_FloatRect rcPlate = GetClientRect();
   CFX_Matrix mt;
   mt.SetReverse(GetImageMatrix());
 
@@ -39,11 +42,11 @@
     sAppStream << mt.GetA() << " " << mt.GetB() << " " << mt.GetC() << " "
                << mt.GetD() << " " << mt.GetE() << " " << mt.GetF() << " cm\n";
 
-    sAppStream << "0 g 0 G 1 w /" << sAlias << " Do\n"
+    sAppStream << "0 g 0 G 1 w /" << sAlias.AsStringC() << " Do\n"
                << "Q\n";
   }
 
-  return sAppStream.GetByteString();
+  return sAppStream.MakeString();
 }
 
 void CPWL_Image::SetPDFStream(CPDF_Stream* pStream) {
@@ -60,7 +63,7 @@
 
   if (m_pPDFStream) {
     if (CPDF_Dictionary* pDict = m_pPDFStream->GetDict()) {
-      CPDF_Rect rect = pDict->GetRect("BBox");
+      CFX_FloatRect rect = pDict->GetRectFor("BBox");
 
       fWidth = rect.right - rect.left;
       fHeight = rect.top - rect.bottom;
@@ -71,7 +74,7 @@
 CFX_Matrix CPWL_Image::GetImageMatrix() {
   if (m_pPDFStream) {
     if (CPDF_Dictionary* pDict = m_pPDFStream->GetDict()) {
-      return pDict->GetMatrix("Matrix");
+      return pDict->GetMatrixFor("Matrix");
     }
   }
 
@@ -84,7 +87,7 @@
 
   if (m_pPDFStream) {
     if (CPDF_Dictionary* pDict = m_pPDFStream->GetDict()) {
-      return pDict->GetString("Name");
+      return pDict->GetStringFor("Name");
     }
   }
 
@@ -105,10 +108,14 @@
   y = 0.0f;
 }
 
-CPWL_Icon::CPWL_Icon() : m_pIconFit(NULL) {}
+CPWL_Icon::CPWL_Icon() : m_pIconFit(nullptr) {}
 
 CPWL_Icon::~CPWL_Icon() {}
 
+CPDF_IconFit* CPWL_Icon::GetIconFit() {
+  return m_pIconFit;
+}
+
 int32_t CPWL_Icon::GetScaleMethod() {
   if (m_pIconFit)
     return m_pIconFit->GetScaleMethod();
@@ -116,25 +123,26 @@
   return 0;
 }
 
-FX_BOOL CPWL_Icon::IsProportionalScale() {
+bool CPWL_Icon::IsProportionalScale() {
   if (m_pIconFit)
     return m_pIconFit->IsProportionalScale();
 
-  return FALSE;
+  return false;
 }
 
 void CPWL_Icon::GetIconPosition(FX_FLOAT& fLeft, FX_FLOAT& fBottom) {
   if (m_pIconFit) {
     fLeft = 0.0f;
     fBottom = 0.0f;
-    CPDF_Array* pA =
-        m_pIconFit->m_pDict ? m_pIconFit->m_pDict->GetArray("A") : NULL;
+    CPDF_Array* pA = m_pIconFit->GetDict()
+                         ? m_pIconFit->GetDict()->GetArrayFor("A")
+                         : nullptr;
     if (pA) {
-      FX_DWORD dwCount = pA->GetCount();
+      size_t dwCount = pA->GetCount();
       if (dwCount > 0)
-        fLeft = pA->GetNumber(0);
+        fLeft = pA->GetNumberAt(0);
       if (dwCount > 1)
-        fBottom = pA->GetNumber(1);
+        fBottom = pA->GetNumberAt(1);
     }
   } else {
     fLeft = 0.0f;
@@ -142,13 +150,6 @@
   }
 }
 
-FX_BOOL CPWL_Icon::GetFittingBounds() {
-  if (m_pIconFit)
-    return m_pIconFit->GetFittingBounds();
-
-  return FALSE;
-}
-
 void CPWL_Icon::GetScale(FX_FLOAT& fHScale, FX_FLOAT& fVScale) {
   fHScale = 1.0f;
   fVScale = 1.0f;
@@ -157,7 +158,7 @@
     FX_FLOAT fImageWidth, fImageHeight;
     FX_FLOAT fPlateWidth, fPlateHeight;
 
-    CPDF_Rect rcPlate = GetClientRect();
+    CFX_FloatRect rcPlate = GetClientRect();
     fPlateWidth = rcPlate.right - rcPlate.left;
     fPlateHeight = rcPlate.top - rcPlate.bottom;
 
@@ -213,7 +214,7 @@
   FX_FLOAT fImageFactHeight = fImageHeight * fVScale;
 
   FX_FLOAT fPlateWidth, fPlateHeight;
-  CPDF_Rect rcPlate = GetClientRect();
+  CFX_FloatRect rcPlate = GetClientRect();
   fPlateWidth = rcPlate.right - rcPlate.left;
   fPlateHeight = rcPlate.top - rcPlate.bottom;
 
diff --git a/fpdfsdk/include/pdfwindow/PWL_Icon.h b/fpdfsdk/pdfwindow/PWL_Icon.h
similarity index 79%
rename from fpdfsdk/include/pdfwindow/PWL_Icon.h
rename to fpdfsdk/pdfwindow/PWL_Icon.h
index 0d2596f..4b62db4 100644
--- a/fpdfsdk/include/pdfwindow/PWL_Icon.h
+++ b/fpdfsdk/pdfwindow/PWL_Icon.h
@@ -4,11 +4,11 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#ifndef FPDFSDK_INCLUDE_PDFWINDOW_PWL_ICON_H_
-#define FPDFSDK_INCLUDE_PDFWINDOW_PWL_ICON_H_
+#ifndef FPDFSDK_PDFWINDOW_PWL_ICON_H_
+#define FPDFSDK_PDFWINDOW_PWL_ICON_H_
 
-#include "PWL_Wnd.h"
-#include "core/include/fxcrt/fx_string.h"
+#include "core/fxcrt/fx_string.h"
+#include "fpdfsdk/pdfwindow/PWL_Wnd.h"
 
 class CPWL_Image : public CPWL_Wnd {
  public:
@@ -38,16 +38,15 @@
   CPWL_Icon();
   ~CPWL_Icon() override;
 
-  virtual CPDF_IconFit* GetIconFit() { return m_pIconFit; }
+  virtual CPDF_IconFit* GetIconFit();
 
   // CPWL_Image
   void GetScale(FX_FLOAT& fHScale, FX_FLOAT& fVScale) override;
   void GetImageOffset(FX_FLOAT& x, FX_FLOAT& y) override;
 
   int32_t GetScaleMethod();
-  FX_BOOL IsProportionalScale();
+  bool IsProportionalScale();
   void GetIconPosition(FX_FLOAT& fLeft, FX_FLOAT& fBottom);
-  FX_BOOL GetFittingBounds();
 
   void SetIconFit(CPDF_IconFit* pIconFit) { m_pIconFit = pIconFit; }
 
@@ -55,4 +54,4 @@
   CPDF_IconFit* m_pIconFit;
 };
 
-#endif  // FPDFSDK_INCLUDE_PDFWINDOW_PWL_ICON_H_
+#endif  // FPDFSDK_PDFWINDOW_PWL_ICON_H_
diff --git a/fpdfsdk/pdfwindow/PWL_ListBox.cpp b/fpdfsdk/pdfwindow/PWL_ListBox.cpp
new file mode 100644
index 0000000..12cad7b
--- /dev/null
+++ b/fpdfsdk/pdfwindow/PWL_ListBox.cpp
@@ -0,0 +1,462 @@
+// 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
+
+#include "fpdfsdk/pdfwindow/PWL_ListBox.h"
+
+#include "fpdfsdk/fxedit/fxet_edit.h"
+#include "fpdfsdk/fxedit/fxet_list.h"
+#include "fpdfsdk/pdfwindow/PWL_Edit.h"
+#include "fpdfsdk/pdfwindow/PWL_EditCtrl.h"
+#include "fpdfsdk/pdfwindow/PWL_ScrollBar.h"
+#include "fpdfsdk/pdfwindow/PWL_Utils.h"
+#include "fpdfsdk/pdfwindow/PWL_Wnd.h"
+#include "public/fpdf_fwlevent.h"
+#include "third_party/base/ptr_util.h"
+
+CPWL_List_Notify::CPWL_List_Notify(CPWL_ListBox* pList) : m_pList(pList) {
+  ASSERT(m_pList);
+}
+
+CPWL_List_Notify::~CPWL_List_Notify() {}
+
+void CPWL_List_Notify::IOnSetScrollInfoY(FX_FLOAT fPlateMin,
+                                         FX_FLOAT fPlateMax,
+                                         FX_FLOAT fContentMin,
+                                         FX_FLOAT fContentMax,
+                                         FX_FLOAT fSmallStep,
+                                         FX_FLOAT fBigStep) {
+  PWL_SCROLL_INFO Info;
+
+  Info.fPlateWidth = fPlateMax - fPlateMin;
+  Info.fContentMin = fContentMin;
+  Info.fContentMax = fContentMax;
+  Info.fSmallStep = fSmallStep;
+  Info.fBigStep = fBigStep;
+
+  m_pList->OnNotify(m_pList, PNM_SETSCROLLINFO, SBT_VSCROLL, (intptr_t)&Info);
+
+  if (CPWL_ScrollBar* pScroll = m_pList->GetVScrollBar()) {
+    if (IsFloatBigger(Info.fPlateWidth, Info.fContentMax - Info.fContentMin) ||
+        IsFloatEqual(Info.fPlateWidth, Info.fContentMax - Info.fContentMin)) {
+      if (pScroll->IsVisible()) {
+        pScroll->SetVisible(false);
+        m_pList->RePosChildWnd();
+      }
+    } else {
+      if (!pScroll->IsVisible()) {
+        pScroll->SetVisible(true);
+        m_pList->RePosChildWnd();
+      }
+    }
+  }
+}
+
+void CPWL_List_Notify::IOnSetScrollPosY(FX_FLOAT fy) {
+  m_pList->OnNotify(m_pList, PNM_SETSCROLLPOS, SBT_VSCROLL, (intptr_t)&fy);
+}
+
+void CPWL_List_Notify::IOnInvalidateRect(CFX_FloatRect* pRect) {
+  m_pList->InvalidateRect(pRect);
+}
+
+CPWL_ListBox::CPWL_ListBox()
+    : m_pList(new CFX_ListCtrl),
+      m_bMouseDown(false),
+      m_bHoverSel(false),
+      m_pFillerNotify(nullptr) {}
+
+CPWL_ListBox::~CPWL_ListBox() {
+}
+
+CFX_ByteString CPWL_ListBox::GetClassName() const {
+  return "CPWL_ListBox";
+}
+
+void CPWL_ListBox::OnCreated() {
+  m_pList->SetFontMap(GetFontMap());
+  m_pListNotify = pdfium::MakeUnique<CPWL_List_Notify>(this);
+  m_pList->SetNotify(m_pListNotify.get());
+
+  SetHoverSel(HasFlag(PLBS_HOVERSEL));
+  m_pList->SetMultipleSel(HasFlag(PLBS_MULTIPLESEL));
+  m_pList->SetFontSize(GetCreationParam().fFontSize);
+
+  m_bHoverSel = HasFlag(PLBS_HOVERSEL);
+}
+
+void CPWL_ListBox::OnDestroy() {
+  // Make sure the notifier is removed from the list as we are about to
+  // destroy the notifier and don't want to leave a dangling pointer.
+  m_pList->SetNotify(nullptr);
+  m_pListNotify.reset();
+}
+
+void CPWL_ListBox::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) {
+  CPWL_Wnd::GetThisAppearanceStream(sAppStream);
+
+  CFX_ByteTextBuf sListItems;
+
+  CFX_FloatRect rcPlate = m_pList->GetPlateRect();
+  for (int32_t i = 0, sz = m_pList->GetCount(); i < sz; i++) {
+    CFX_FloatRect rcItem = m_pList->GetItemRect(i);
+
+    if (rcItem.bottom > rcPlate.top || rcItem.top < rcPlate.bottom)
+      continue;
+
+    CFX_FloatPoint ptOffset(rcItem.left, (rcItem.top + rcItem.bottom) * 0.5f);
+    if (m_pList->IsItemSelected(i)) {
+      sListItems << CPWL_Utils::GetRectFillAppStream(rcItem,
+                                                     PWL_DEFAULT_SELBACKCOLOR)
+                        .AsStringC();
+      CFX_ByteString sItem =
+          CPWL_Utils::GetEditAppStream(m_pList->GetItemEdit(i), ptOffset);
+      if (sItem.GetLength() > 0) {
+        sListItems << "BT\n"
+                   << CPWL_Utils::GetColorAppStream(PWL_DEFAULT_SELTEXTCOLOR)
+                          .AsStringC()
+                   << sItem.AsStringC() << "ET\n";
+      }
+    } else {
+      CFX_ByteString sItem =
+          CPWL_Utils::GetEditAppStream(m_pList->GetItemEdit(i), ptOffset);
+      if (sItem.GetLength() > 0) {
+        sListItems << "BT\n"
+                   << CPWL_Utils::GetColorAppStream(GetTextColor()).AsStringC()
+                   << sItem.AsStringC() << "ET\n";
+      }
+    }
+  }
+
+  if (sListItems.GetLength() > 0) {
+    CFX_ByteTextBuf sClip;
+    CFX_FloatRect rcClient = GetClientRect();
+
+    sClip << "q\n";
+    sClip << rcClient.left << " " << rcClient.bottom << " "
+          << rcClient.right - rcClient.left << " "
+          << rcClient.top - rcClient.bottom << " re W n\n";
+
+    sClip << sListItems << "Q\n";
+
+    sAppStream << "/Tx BMC\n" << sClip << "EMC\n";
+  }
+}
+
+void CPWL_ListBox::DrawThisAppearance(CFX_RenderDevice* pDevice,
+                                      CFX_Matrix* pUser2Device) {
+  CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device);
+
+  CFX_FloatRect rcPlate = m_pList->GetPlateRect();
+  CFX_FloatRect rcList = GetListRect();
+  CFX_FloatRect rcClient = GetClientRect();
+
+  for (int32_t i = 0, sz = m_pList->GetCount(); i < sz; i++) {
+    CFX_FloatRect rcItem = m_pList->GetItemRect(i);
+    if (rcItem.bottom > rcPlate.top || rcItem.top < rcPlate.bottom)
+      continue;
+
+    CFX_FloatPoint ptOffset(rcItem.left, (rcItem.top + rcItem.bottom) * 0.5f);
+    if (CFX_Edit* pEdit = m_pList->GetItemEdit(i)) {
+      CFX_FloatRect rcContent = pEdit->GetContentRect();
+      if (rcContent.Width() > rcClient.Width())
+        rcItem.Intersect(rcList);
+      else
+        rcItem.Intersect(rcClient);
+    }
+
+    if (m_pList->IsItemSelected(i)) {
+      CFX_SystemHandler* pSysHandler = GetSystemHandler();
+      if (pSysHandler && pSysHandler->IsSelectionImplemented()) {
+        CFX_Edit::DrawEdit(pDevice, pUser2Device, m_pList->GetItemEdit(i),
+                           CPWL_Utils::PWLColorToFXColor(GetTextColor()),
+                           CPWL_Utils::PWLColorToFXColor(GetTextStrokeColor()),
+                           rcList, ptOffset, nullptr, pSysHandler,
+                           m_pFormFiller);
+        pSysHandler->OutputSelectedRect(m_pFormFiller, rcItem);
+      } else {
+        CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rcItem,
+                                 ArgbEncode(255, 0, 51, 113));
+        CFX_Edit::DrawEdit(pDevice, pUser2Device, m_pList->GetItemEdit(i),
+                           ArgbEncode(255, 255, 255, 255), 0, rcList, ptOffset,
+                           nullptr, pSysHandler, m_pFormFiller);
+      }
+    } else {
+      CFX_SystemHandler* pSysHandler = GetSystemHandler();
+      CFX_Edit::DrawEdit(pDevice, pUser2Device, m_pList->GetItemEdit(i),
+                         CPWL_Utils::PWLColorToFXColor(GetTextColor()),
+                         CPWL_Utils::PWLColorToFXColor(GetTextStrokeColor()),
+                         rcList, ptOffset, nullptr, pSysHandler, nullptr);
+    }
+  }
+}
+
+bool CPWL_ListBox::OnKeyDown(uint16_t nChar, uint32_t nFlag) {
+  CPWL_Wnd::OnKeyDown(nChar, nFlag);
+
+  switch (nChar) {
+    default:
+      return false;
+    case FWL_VKEY_Up:
+    case FWL_VKEY_Down:
+    case FWL_VKEY_Home:
+    case FWL_VKEY_Left:
+    case FWL_VKEY_End:
+    case FWL_VKEY_Right:
+      break;
+  }
+
+  switch (nChar) {
+    case FWL_VKEY_Up:
+      m_pList->OnVK_UP(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
+      break;
+    case FWL_VKEY_Down:
+      m_pList->OnVK_DOWN(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
+      break;
+    case FWL_VKEY_Home:
+      m_pList->OnVK_HOME(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
+      break;
+    case FWL_VKEY_Left:
+      m_pList->OnVK_LEFT(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
+      break;
+    case FWL_VKEY_End:
+      m_pList->OnVK_END(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
+      break;
+    case FWL_VKEY_Right:
+      m_pList->OnVK_RIGHT(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
+      break;
+    case FWL_VKEY_Delete:
+      break;
+  }
+
+  bool bExit = false;
+  OnNotifySelChanged(true, bExit, nFlag);
+
+  return true;
+}
+
+bool CPWL_ListBox::OnChar(uint16_t nChar, uint32_t nFlag) {
+  CPWL_Wnd::OnChar(nChar, nFlag);
+
+  if (!m_pList->OnChar(nChar, IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag)))
+    return false;
+
+  bool bExit = false;
+  OnNotifySelChanged(true, bExit, nFlag);
+
+  return true;
+}
+
+bool CPWL_ListBox::OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag) {
+  CPWL_Wnd::OnLButtonDown(point, nFlag);
+
+  if (ClientHitTest(point)) {
+    m_bMouseDown = true;
+    SetFocus();
+    SetCapture();
+
+    m_pList->OnMouseDown(point, IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
+  }
+
+  return true;
+}
+
+bool CPWL_ListBox::OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) {
+  CPWL_Wnd::OnLButtonUp(point, nFlag);
+
+  if (m_bMouseDown) {
+    ReleaseCapture();
+    m_bMouseDown = false;
+  }
+
+  bool bExit = false;
+  OnNotifySelChanged(false, bExit, nFlag);
+
+  return true;
+}
+
+void CPWL_ListBox::SetHoverSel(bool bHoverSel) {
+  m_bHoverSel = bHoverSel;
+}
+
+bool CPWL_ListBox::OnMouseMove(const CFX_FloatPoint& point, uint32_t nFlag) {
+  CPWL_Wnd::OnMouseMove(point, nFlag);
+
+  if (m_bHoverSel && !IsCaptureMouse() && ClientHitTest(point))
+    m_pList->Select(m_pList->GetItemIndex(point));
+  if (m_bMouseDown)
+    m_pList->OnMouseMove(point, IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
+
+  return true;
+}
+
+void CPWL_ListBox::OnNotify(CPWL_Wnd* pWnd,
+                            uint32_t msg,
+                            intptr_t wParam,
+                            intptr_t lParam) {
+  CPWL_Wnd::OnNotify(pWnd, msg, wParam, lParam);
+
+  FX_FLOAT fPos;
+
+  switch (msg) {
+    case PNM_SETSCROLLINFO:
+      switch (wParam) {
+        case SBT_VSCROLL:
+          if (CPWL_Wnd* pChild = GetVScrollBar()) {
+            pChild->OnNotify(pWnd, PNM_SETSCROLLINFO, wParam, lParam);
+          }
+          break;
+      }
+      break;
+    case PNM_SETSCROLLPOS:
+      switch (wParam) {
+        case SBT_VSCROLL:
+          if (CPWL_Wnd* pChild = GetVScrollBar()) {
+            pChild->OnNotify(pWnd, PNM_SETSCROLLPOS, wParam, lParam);
+          }
+          break;
+      }
+      break;
+    case PNM_SCROLLWINDOW:
+      fPos = *(FX_FLOAT*)lParam;
+      switch (wParam) {
+        case SBT_VSCROLL:
+          m_pList->SetScrollPos(CFX_FloatPoint(0, fPos));
+          break;
+      }
+      break;
+  }
+}
+
+void CPWL_ListBox::KillFocus() {
+  CPWL_Wnd::KillFocus();
+}
+
+void CPWL_ListBox::RePosChildWnd() {
+  CPWL_Wnd::RePosChildWnd();
+
+  m_pList->SetPlateRect(GetListRect());
+}
+
+void CPWL_ListBox::OnNotifySelChanged(bool bKeyDown,
+                                      bool& bExit,
+                                      uint32_t nFlag) {
+  if (!m_pFillerNotify)
+    return;
+
+  bool bRC = true;
+  CFX_WideString swChange = GetText();
+  CFX_WideString strChangeEx;
+  int nSelStart = 0;
+  int nSelEnd = swChange.GetLength();
+  m_pFillerNotify->OnBeforeKeyStroke(GetAttachedData(), swChange, strChangeEx,
+                                     nSelStart, nSelEnd, bKeyDown, bRC, bExit,
+                                     nFlag);
+}
+
+CFX_FloatRect CPWL_ListBox::GetFocusRect() const {
+  if (m_pList->IsMultipleSel()) {
+    CFX_FloatRect rcCaret = m_pList->GetItemRect(m_pList->GetCaret());
+    rcCaret.Intersect(GetClientRect());
+    return rcCaret;
+  }
+
+  return CPWL_Wnd::GetFocusRect();
+}
+
+void CPWL_ListBox::AddString(const CFX_WideString& str) {
+  m_pList->AddString(str);
+}
+
+CFX_WideString CPWL_ListBox::GetText() const {
+  return m_pList->GetText();
+}
+
+void CPWL_ListBox::SetFontSize(FX_FLOAT fFontSize) {
+  m_pList->SetFontSize(fFontSize);
+}
+
+FX_FLOAT CPWL_ListBox::GetFontSize() const {
+  return m_pList->GetFontSize();
+}
+
+void CPWL_ListBox::Select(int32_t nItemIndex) {
+  m_pList->Select(nItemIndex);
+}
+
+void CPWL_ListBox::SetCaret(int32_t nItemIndex) {
+  m_pList->SetCaret(nItemIndex);
+}
+
+void CPWL_ListBox::SetTopVisibleIndex(int32_t nItemIndex) {
+  m_pList->SetTopItem(nItemIndex);
+}
+
+void CPWL_ListBox::ScrollToListItem(int32_t nItemIndex) {
+  m_pList->ScrollToListItem(nItemIndex);
+}
+
+void CPWL_ListBox::ResetContent() {
+  m_pList->Empty();
+}
+
+void CPWL_ListBox::Reset() {
+  m_pList->Cancel();
+}
+
+bool CPWL_ListBox::IsMultipleSel() const {
+  return m_pList->IsMultipleSel();
+}
+
+int32_t CPWL_ListBox::GetCaretIndex() const {
+  return m_pList->GetCaret();
+}
+
+int32_t CPWL_ListBox::GetCurSel() const {
+  return m_pList->GetSelect();
+}
+
+bool CPWL_ListBox::IsItemSelected(int32_t nItemIndex) const {
+  return m_pList->IsItemSelected(nItemIndex);
+}
+
+int32_t CPWL_ListBox::GetTopVisibleIndex() const {
+  m_pList->ScrollToListItem(m_pList->GetFirstSelected());
+  return m_pList->GetTopItem();
+}
+
+int32_t CPWL_ListBox::GetCount() const {
+  return m_pList->GetCount();
+}
+
+int32_t CPWL_ListBox::FindNext(int32_t nIndex, FX_WCHAR nChar) const {
+  return m_pList->FindNext(nIndex, nChar);
+}
+
+CFX_FloatRect CPWL_ListBox::GetContentRect() const {
+  return m_pList->GetContentRect();
+}
+
+FX_FLOAT CPWL_ListBox::GetFirstHeight() const {
+  return m_pList->GetFirstHeight();
+}
+
+CFX_FloatRect CPWL_ListBox::GetListRect() const {
+  return CPWL_Utils::DeflateRect(
+      GetWindowRect(), (FX_FLOAT)(GetBorderWidth() + GetInnerBorderWidth()));
+}
+
+bool CPWL_ListBox::OnMouseWheel(short zDelta,
+                                const CFX_FloatPoint& point,
+                                uint32_t nFlag) {
+  if (zDelta < 0)
+    m_pList->OnVK_DOWN(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
+  else
+    m_pList->OnVK_UP(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
+
+  bool bExit = false;
+  OnNotifySelChanged(false, bExit, nFlag);
+  return true;
+}
diff --git a/fpdfsdk/pdfwindow/PWL_ListBox.h b/fpdfsdk/pdfwindow/PWL_ListBox.h
new file mode 100644
index 0000000..6db4ecb
--- /dev/null
+++ b/fpdfsdk/pdfwindow/PWL_ListBox.h
@@ -0,0 +1,117 @@
+// 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_PDFWINDOW_PWL_LISTBOX_H_
+#define FPDFSDK_PDFWINDOW_PWL_LISTBOX_H_
+
+#include <memory>
+
+#include "fpdfsdk/fxedit/fx_edit.h"
+#include "fpdfsdk/pdfwindow/PWL_Wnd.h"
+
+class CFX_ListCtrl;
+class CPWL_List_Notify;
+class CPWL_ListBox;
+class IPWL_Filler_Notify;
+struct CPVT_SecProps;
+struct CPVT_WordPlace;
+struct CPVT_WordProps;
+
+class CPWL_List_Notify {
+ public:
+  explicit CPWL_List_Notify(CPWL_ListBox* pList);
+  ~CPWL_List_Notify();
+
+  void IOnSetScrollInfoY(FX_FLOAT fPlateMin,
+                         FX_FLOAT fPlateMax,
+                         FX_FLOAT fContentMin,
+                         FX_FLOAT fContentMax,
+                         FX_FLOAT fSmallStep,
+                         FX_FLOAT fBigStep);
+  void IOnSetScrollPosY(FX_FLOAT fy);
+  void IOnInvalidateRect(CFX_FloatRect* pRect);
+
+  void IOnSetCaret(bool bVisible,
+                   const CFX_FloatPoint& ptHead,
+                   const CFX_FloatPoint& ptFoot,
+                   const CPVT_WordPlace& place);
+
+ private:
+  CPWL_ListBox* m_pList;
+};
+
+class CPWL_ListBox : public CPWL_Wnd {
+ public:
+  CPWL_ListBox();
+  ~CPWL_ListBox() override;
+
+  // CPWL_Wnd
+  CFX_ByteString GetClassName() const override;
+  void OnCreated() override;
+  void OnDestroy() override;
+  void GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) override;
+  void DrawThisAppearance(CFX_RenderDevice* pDevice,
+                          CFX_Matrix* pUser2Device) override;
+  bool OnKeyDown(uint16_t nChar, uint32_t nFlag) override;
+  bool OnChar(uint16_t nChar, uint32_t nFlag) override;
+  bool OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag) override;
+  bool OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) override;
+  bool OnMouseMove(const CFX_FloatPoint& point, uint32_t nFlag) override;
+  bool OnMouseWheel(short zDelta,
+                    const CFX_FloatPoint& point,
+                    uint32_t nFlag) override;
+  void KillFocus() override;
+  void OnNotify(CPWL_Wnd* pWnd,
+                uint32_t msg,
+                intptr_t wParam = 0,
+                intptr_t lParam = 0) override;
+  void RePosChildWnd() override;
+  CFX_FloatRect GetFocusRect() const override;
+  void SetFontSize(FX_FLOAT fFontSize) override;
+  FX_FLOAT GetFontSize() const override;
+
+  virtual CFX_WideString GetText() const;
+
+  void OnNotifySelChanged(bool bKeyDown, bool& bExit, uint32_t nFlag);
+
+  void AddString(const CFX_WideString& str);
+  void SetTopVisibleIndex(int32_t nItemIndex);
+  void ScrollToListItem(int32_t nItemIndex);
+  void ResetContent();
+  void Reset();
+  void Select(int32_t nItemIndex);
+  void SetCaret(int32_t nItemIndex);
+  void SetHoverSel(bool bHoverSel);
+
+  int32_t GetCount() const;
+  bool IsMultipleSel() const;
+  int32_t GetCaretIndex() const;
+  int32_t GetCurSel() const;
+  bool IsItemSelected(int32_t nItemIndex) const;
+  int32_t GetTopVisibleIndex() const;
+  int32_t FindNext(int32_t nIndex, FX_WCHAR nChar) const;
+  CFX_FloatRect GetContentRect() const;
+  FX_FLOAT GetFirstHeight() const;
+  CFX_FloatRect GetListRect() const;
+
+  void SetFillerNotify(IPWL_Filler_Notify* pNotify) {
+    m_pFillerNotify = pNotify;
+  }
+
+  void AttachFFLData(CFFL_FormFiller* pData) { m_pFormFiller = pData; }
+
+ protected:
+  std::unique_ptr<CFX_ListCtrl> m_pList;
+  std::unique_ptr<CPWL_List_Notify> m_pListNotify;
+  bool m_bMouseDown;
+  bool m_bHoverSel;
+  IPWL_Filler_Notify* m_pFillerNotify;
+
+ private:
+  CFFL_FormFiller* m_pFormFiller;  // Not owned.
+};
+
+#endif  // FPDFSDK_PDFWINDOW_PWL_LISTBOX_H_
diff --git a/fpdfsdk/src/pdfwindow/PWL_ScrollBar.cpp b/fpdfsdk/pdfwindow/PWL_ScrollBar.cpp
similarity index 68%
rename from fpdfsdk/src/pdfwindow/PWL_ScrollBar.cpp
rename to fpdfsdk/pdfwindow/PWL_ScrollBar.cpp
index c48052d..8a09ac6 100644
--- a/fpdfsdk/src/pdfwindow/PWL_ScrollBar.cpp
+++ b/fpdfsdk/pdfwindow/PWL_ScrollBar.cpp
@@ -4,14 +4,12 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#include "fpdfsdk/include/pdfwindow/PWL_ScrollBar.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Wnd.h"
+#include "fpdfsdk/pdfwindow/PWL_ScrollBar.h"
 
-#define IsFloatZero(f) ((f) < 0.0001 && (f) > -0.0001)
-#define IsFloatBigger(fa, fb) ((fa) > (fb) && !IsFloatZero((fa) - (fb)))
-#define IsFloatSmaller(fa, fb) ((fa) < (fb) && !IsFloatZero((fa) - (fb)))
-#define IsFloatEqual(fa, fb) IsFloatZero((fa) - (fb))
+#include "core/fxge/cfx_pathdata.h"
+#include "core/fxge/cfx_renderdevice.h"
+#include "fpdfsdk/pdfwindow/PWL_Utils.h"
+#include "fpdfsdk/pdfwindow/PWL_Wnd.h"
 
 PWL_FLOATRANGE::PWL_FLOATRANGE() {
   Default();
@@ -36,7 +34,7 @@
   }
 }
 
-FX_BOOL PWL_FLOATRANGE::In(FX_FLOAT x) const {
+bool PWL_FLOATRANGE::In(FX_FLOAT x) const {
   return (IsFloatBigger(x, fMin) || IsFloatEqual(x, fMin)) &&
          (IsFloatSmaller(x, fMax) || IsFloatEqual(x, fMax));
 }
@@ -78,12 +76,12 @@
   fBigStep = step;
 }
 
-FX_BOOL PWL_SCROLL_PRIVATEDATA::SetPos(FX_FLOAT pos) {
+bool PWL_SCROLL_PRIVATEDATA::SetPos(FX_FLOAT pos) {
   if (ScrollRange.In(pos)) {
     fScrollPos = pos;
-    return TRUE;
+    return true;
   }
-  return FALSE;
+  return false;
 }
 
 void PWL_SCROLL_PRIVATEDATA::AddSmall() {
@@ -111,7 +109,7 @@
   m_eScrollBarType = eScrollBarType;
   m_eSBButtonType = eButtonType;
 
-  m_bMouseDown = FALSE;
+  m_bMouseDown = false;
 }
 
 CPWL_SBButton::~CPWL_SBButton() {}
@@ -132,24 +130,25 @@
 
   CFX_ByteTextBuf sButton;
 
-  CPDF_Rect rectWnd = GetWindowRect();
+  CFX_FloatRect rectWnd = GetWindowRect();
 
   if (rectWnd.IsEmpty())
     return;
 
   sAppStream << "q\n";
 
-  CPDF_Point ptCenter = GetCenterPoint();
+  CFX_FloatPoint ptCenter = GetCenterPoint();
 
   switch (m_eScrollBarType) {
     case SBT_HSCROLL:
       switch (m_eSBButtonType) {
         case PSBT_MIN: {
-          CPDF_Point pt1(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f, ptCenter.y);
-          CPDF_Point pt2(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f,
-                         ptCenter.y + PWL_TRIANGLE_HALFLEN);
-          CPDF_Point pt3(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f,
-                         ptCenter.y - PWL_TRIANGLE_HALFLEN);
+          CFX_FloatPoint pt1(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f,
+                             ptCenter.y);
+          CFX_FloatPoint pt2(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f,
+                             ptCenter.y + PWL_TRIANGLE_HALFLEN);
+          CFX_FloatPoint pt3(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f,
+                             ptCenter.y - PWL_TRIANGLE_HALFLEN);
 
           if (rectWnd.right - rectWnd.left > PWL_TRIANGLE_HALFLEN * 2 &&
               rectWnd.top - rectWnd.bottom > PWL_TRIANGLE_HALFLEN) {
@@ -163,11 +162,12 @@
           }
         } break;
         case PSBT_MAX: {
-          CPDF_Point pt1(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f, ptCenter.y);
-          CPDF_Point pt2(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f,
-                         ptCenter.y + PWL_TRIANGLE_HALFLEN);
-          CPDF_Point pt3(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f,
-                         ptCenter.y - PWL_TRIANGLE_HALFLEN);
+          CFX_FloatPoint pt1(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f,
+                             ptCenter.y);
+          CFX_FloatPoint pt2(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f,
+                             ptCenter.y + PWL_TRIANGLE_HALFLEN);
+          CFX_FloatPoint pt3(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f,
+                             ptCenter.y - PWL_TRIANGLE_HALFLEN);
 
           if (rectWnd.right - rectWnd.left > PWL_TRIANGLE_HALFLEN * 2 &&
               rectWnd.top - rectWnd.bottom > PWL_TRIANGLE_HALFLEN) {
@@ -187,11 +187,12 @@
     case SBT_VSCROLL:
       switch (m_eSBButtonType) {
         case PSBT_MIN: {
-          CPDF_Point pt1(ptCenter.x - PWL_TRIANGLE_HALFLEN,
-                         ptCenter.y - PWL_TRIANGLE_HALFLEN * 0.5f);
-          CPDF_Point pt2(ptCenter.x + PWL_TRIANGLE_HALFLEN,
-                         ptCenter.y - PWL_TRIANGLE_HALFLEN * 0.5f);
-          CPDF_Point pt3(ptCenter.x, ptCenter.y + PWL_TRIANGLE_HALFLEN * 0.5f);
+          CFX_FloatPoint pt1(ptCenter.x - PWL_TRIANGLE_HALFLEN,
+                             ptCenter.y - PWL_TRIANGLE_HALFLEN * 0.5f);
+          CFX_FloatPoint pt2(ptCenter.x + PWL_TRIANGLE_HALFLEN,
+                             ptCenter.y - PWL_TRIANGLE_HALFLEN * 0.5f);
+          CFX_FloatPoint pt3(ptCenter.x,
+                             ptCenter.y + PWL_TRIANGLE_HALFLEN * 0.5f);
 
           if (rectWnd.right - rectWnd.left > PWL_TRIANGLE_HALFLEN * 2 &&
               rectWnd.top - rectWnd.bottom > PWL_TRIANGLE_HALFLEN) {
@@ -205,11 +206,12 @@
           }
         } break;
         case PSBT_MAX: {
-          CPDF_Point pt1(ptCenter.x - PWL_TRIANGLE_HALFLEN,
-                         ptCenter.y + PWL_TRIANGLE_HALFLEN * 0.5f);
-          CPDF_Point pt2(ptCenter.x + PWL_TRIANGLE_HALFLEN,
-                         ptCenter.y + PWL_TRIANGLE_HALFLEN * 0.5f);
-          CPDF_Point pt3(ptCenter.x, ptCenter.y - PWL_TRIANGLE_HALFLEN * 0.5f);
+          CFX_FloatPoint pt1(ptCenter.x - PWL_TRIANGLE_HALFLEN,
+                             ptCenter.y + PWL_TRIANGLE_HALFLEN * 0.5f);
+          CFX_FloatPoint pt2(ptCenter.x + PWL_TRIANGLE_HALFLEN,
+                             ptCenter.y + PWL_TRIANGLE_HALFLEN * 0.5f);
+          CFX_FloatPoint pt3(ptCenter.x,
+                             ptCenter.y - PWL_TRIANGLE_HALFLEN * 0.5f);
 
           if (rectWnd.right - rectWnd.left > PWL_TRIANGLE_HALFLEN * 2 &&
               rectWnd.top - rectWnd.bottom > PWL_TRIANGLE_HALFLEN) {
@@ -238,11 +240,11 @@
   if (!IsVisible())
     return;
 
-  CPDF_Rect rectWnd = GetWindowRect();
+  CFX_FloatRect rectWnd = GetWindowRect();
   if (rectWnd.IsEmpty())
     return;
 
-  CPDF_Point ptCenter = GetCenterPoint();
+  CFX_FloatPoint ptCenter = GetCenterPoint();
   int32_t nTransparancy = GetTransparency();
 
   switch (m_eScrollBarType) {
@@ -250,11 +252,12 @@
       CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device);
       switch (m_eSBButtonType) {
         case PSBT_MIN: {
-          CPDF_Point pt1(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f, ptCenter.y);
-          CPDF_Point pt2(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f,
-                         ptCenter.y + PWL_TRIANGLE_HALFLEN);
-          CPDF_Point pt3(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f,
-                         ptCenter.y - PWL_TRIANGLE_HALFLEN);
+          CFX_FloatPoint pt1(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f,
+                             ptCenter.y);
+          CFX_FloatPoint pt2(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f,
+                             ptCenter.y + PWL_TRIANGLE_HALFLEN);
+          CFX_FloatPoint pt3(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f,
+                             ptCenter.y - PWL_TRIANGLE_HALFLEN);
 
           if (rectWnd.right - rectWnd.left > PWL_TRIANGLE_HALFLEN * 2 &&
               rectWnd.top - rectWnd.bottom > PWL_TRIANGLE_HALFLEN) {
@@ -266,18 +269,19 @@
             path.SetPoint(2, pt3.x, pt3.y, FXPT_LINETO);
             path.SetPoint(3, pt1.x, pt1.y, FXPT_LINETO);
 
-            pDevice->DrawPath(&path, pUser2Device, NULL,
+            pDevice->DrawPath(&path, pUser2Device, nullptr,
                               CPWL_Utils::PWLColorToFXColor(
                                   PWL_DEFAULT_BLACKCOLOR, nTransparancy),
                               0, FXFILL_ALTERNATE);
           }
         } break;
         case PSBT_MAX: {
-          CPDF_Point pt1(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f, ptCenter.y);
-          CPDF_Point pt2(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f,
-                         ptCenter.y + PWL_TRIANGLE_HALFLEN);
-          CPDF_Point pt3(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f,
-                         ptCenter.y - PWL_TRIANGLE_HALFLEN);
+          CFX_FloatPoint pt1(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f,
+                             ptCenter.y);
+          CFX_FloatPoint pt2(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f,
+                             ptCenter.y + PWL_TRIANGLE_HALFLEN);
+          CFX_FloatPoint pt3(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f,
+                             ptCenter.y - PWL_TRIANGLE_HALFLEN);
 
           if (rectWnd.right - rectWnd.left > PWL_TRIANGLE_HALFLEN * 2 &&
               rectWnd.top - rectWnd.bottom > PWL_TRIANGLE_HALFLEN) {
@@ -289,7 +293,7 @@
             path.SetPoint(2, pt3.x, pt3.y, FXPT_LINETO);
             path.SetPoint(3, pt1.x, pt1.y, FXPT_LINETO);
 
-            pDevice->DrawPath(&path, pUser2Device, NULL,
+            pDevice->DrawPath(&path, pUser2Device, nullptr,
                               CPWL_Utils::PWLColorToFXColor(
                                   PWL_DEFAULT_BLACKCOLOR, nTransparancy),
                               0, FXFILL_ALTERNATE);
@@ -303,7 +307,7 @@
       switch (m_eSBButtonType) {
         case PSBT_MIN: {
           // draw border
-          CPDF_Rect rcDraw = rectWnd;
+          CFX_FloatRect rcDraw = rectWnd;
           CPWL_Utils::DrawStrokeRect(pDevice, pUser2Device, rcDraw,
                                      ArgbEncode(nTransparancy, 100, 100, 100),
                                      0.0f);
@@ -319,7 +323,7 @@
           rcDraw = CPWL_Utils::DeflateRect(rectWnd, 1.0f);
 
           if (IsEnabled())
-            CPWL_Utils::DrawShadow(pDevice, pUser2Device, TRUE, FALSE, rcDraw,
+            CPWL_Utils::DrawShadow(pDevice, pUser2Device, true, false, rcDraw,
                                    nTransparancy, 80, 220);
           else
             CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rcDraw,
@@ -330,13 +334,13 @@
           if (rectWnd.top - rectWnd.bottom > 6.0f) {
             FX_FLOAT fX = rectWnd.left + 1.5f;
             FX_FLOAT fY = rectWnd.bottom;
-            CPDF_Point pts[7] = {CPDF_Point(fX + 2.5f, fY + 4.0f),
-                                 CPDF_Point(fX + 2.5f, fY + 3.0f),
-                                 CPDF_Point(fX + 4.5f, fY + 5.0f),
-                                 CPDF_Point(fX + 6.5f, fY + 3.0f),
-                                 CPDF_Point(fX + 6.5f, fY + 4.0f),
-                                 CPDF_Point(fX + 4.5f, fY + 6.0f),
-                                 CPDF_Point(fX + 2.5f, fY + 4.0f)};
+            CFX_FloatPoint pts[7] = {CFX_FloatPoint(fX + 2.5f, fY + 4.0f),
+                                     CFX_FloatPoint(fX + 2.5f, fY + 3.0f),
+                                     CFX_FloatPoint(fX + 4.5f, fY + 5.0f),
+                                     CFX_FloatPoint(fX + 6.5f, fY + 3.0f),
+                                     CFX_FloatPoint(fX + 6.5f, fY + 4.0f),
+                                     CFX_FloatPoint(fX + 4.5f, fY + 6.0f),
+                                     CFX_FloatPoint(fX + 2.5f, fY + 4.0f)};
 
             if (IsEnabled())
               CPWL_Utils::DrawFillArea(
@@ -350,7 +354,7 @@
         } break;
         case PSBT_MAX: {
           // draw border
-          CPDF_Rect rcDraw = rectWnd;
+          CFX_FloatRect rcDraw = rectWnd;
           CPWL_Utils::DrawStrokeRect(pDevice, pUser2Device, rcDraw,
                                      ArgbEncode(nTransparancy, 100, 100, 100),
                                      0.0f);
@@ -364,7 +368,7 @@
           // draw background
           rcDraw = CPWL_Utils::DeflateRect(rectWnd, 1.0f);
           if (IsEnabled())
-            CPWL_Utils::DrawShadow(pDevice, pUser2Device, TRUE, FALSE, rcDraw,
+            CPWL_Utils::DrawShadow(pDevice, pUser2Device, true, false, rcDraw,
                                    nTransparancy, 80, 220);
           else
             CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rcDraw,
@@ -376,13 +380,13 @@
             FX_FLOAT fX = rectWnd.left + 1.5f;
             FX_FLOAT fY = rectWnd.bottom;
 
-            CPDF_Point pts[7] = {CPDF_Point(fX + 2.5f, fY + 5.0f),
-                                 CPDF_Point(fX + 2.5f, fY + 6.0f),
-                                 CPDF_Point(fX + 4.5f, fY + 4.0f),
-                                 CPDF_Point(fX + 6.5f, fY + 6.0f),
-                                 CPDF_Point(fX + 6.5f, fY + 5.0f),
-                                 CPDF_Point(fX + 4.5f, fY + 3.0f),
-                                 CPDF_Point(fX + 2.5f, fY + 5.0f)};
+            CFX_FloatPoint pts[7] = {CFX_FloatPoint(fX + 2.5f, fY + 5.0f),
+                                     CFX_FloatPoint(fX + 2.5f, fY + 6.0f),
+                                     CFX_FloatPoint(fX + 4.5f, fY + 4.0f),
+                                     CFX_FloatPoint(fX + 6.5f, fY + 6.0f),
+                                     CFX_FloatPoint(fX + 6.5f, fY + 5.0f),
+                                     CFX_FloatPoint(fX + 4.5f, fY + 3.0f),
+                                     CFX_FloatPoint(fX + 2.5f, fY + 5.0f)};
 
             if (IsEnabled())
               CPWL_Utils::DrawFillArea(
@@ -396,7 +400,7 @@
         } break;
         case PSBT_POS: {
           // draw border
-          CPDF_Rect rcDraw = rectWnd;
+          CFX_FloatRect rcDraw = rectWnd;
           CPWL_Utils::DrawStrokeRect(pDevice, pUser2Device, rcDraw,
                                      ArgbEncode(nTransparancy, 100, 100, 100),
                                      0.0f);
@@ -410,9 +414,10 @@
           if (IsEnabled()) {
             // draw shadow effect
 
-            CPDF_Point ptTop = CPDF_Point(rectWnd.left, rectWnd.top - 1.0f);
-            CPDF_Point ptBottom =
-                CPDF_Point(rectWnd.left, rectWnd.bottom + 1.0f);
+            CFX_FloatPoint ptTop =
+                CFX_FloatPoint(rectWnd.left, rectWnd.top - 1.0f);
+            CFX_FloatPoint ptBottom =
+                CFX_FloatPoint(rectWnd.left, rectWnd.bottom + 1.0f);
 
             ptTop.x += 1.5f;
             ptBottom.x += 1.5f;
@@ -499,12 +504,12 @@
             FX_FLOAT nFrictionWidth = 5.0f;
             FX_FLOAT nFrictionHeight = 5.5f;
 
-            CPDF_Point ptLeft =
-                CPDF_Point(ptCenter.x - nFrictionWidth / 2.0f,
-                           ptCenter.y - nFrictionHeight / 2.0f + 0.5f);
-            CPDF_Point ptRight =
-                CPDF_Point(ptCenter.x + nFrictionWidth / 2.0f,
-                           ptCenter.y - nFrictionHeight / 2.0f + 0.5f);
+            CFX_FloatPoint ptLeft =
+                CFX_FloatPoint(ptCenter.x - nFrictionWidth / 2.0f,
+                               ptCenter.y - nFrictionHeight / 2.0f + 0.5f);
+            CFX_FloatPoint ptRight =
+                CFX_FloatPoint(ptCenter.x + nFrictionWidth / 2.0f,
+                               ptCenter.y - nFrictionHeight / 2.0f + 0.5f);
 
             CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptLeft, ptRight,
                                        crStroke, 1.0f);
@@ -531,48 +536,48 @@
   }
 }
 
-FX_BOOL CPWL_SBButton::OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) {
+bool CPWL_SBButton::OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag) {
   CPWL_Wnd::OnLButtonDown(point, nFlag);
 
   if (CPWL_Wnd* pParent = GetParentWindow())
     pParent->OnNotify(this, PNM_LBUTTONDOWN, 0, (intptr_t)&point);
 
-  m_bMouseDown = TRUE;
+  m_bMouseDown = true;
   SetCapture();
 
-  return TRUE;
+  return true;
 }
 
-FX_BOOL CPWL_SBButton::OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag) {
+bool CPWL_SBButton::OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) {
   CPWL_Wnd::OnLButtonUp(point, nFlag);
 
   if (CPWL_Wnd* pParent = GetParentWindow())
     pParent->OnNotify(this, PNM_LBUTTONUP, 0, (intptr_t)&point);
 
-  m_bMouseDown = FALSE;
+  m_bMouseDown = false;
   ReleaseCapture();
 
-  return TRUE;
+  return true;
 }
 
-FX_BOOL CPWL_SBButton::OnMouseMove(const CPDF_Point& point, FX_DWORD nFlag) {
+bool CPWL_SBButton::OnMouseMove(const CFX_FloatPoint& point, uint32_t nFlag) {
   CPWL_Wnd::OnMouseMove(point, nFlag);
 
   if (CPWL_Wnd* pParent = GetParentWindow()) {
     pParent->OnNotify(this, PNM_MOUSEMOVE, 0, (intptr_t)&point);
   }
 
-  return TRUE;
+  return true;
 }
 
 CPWL_ScrollBar::CPWL_ScrollBar(PWL_SCROLLBAR_TYPE sbType)
     : m_sbType(sbType),
-      m_pMinButton(NULL),
-      m_pMaxButton(NULL),
-      m_pPosButton(NULL),
-      m_bMouseDown(FALSE),
-      m_bMinOrMax(FALSE),
-      m_bNotifyForever(TRUE) {}
+      m_pMinButton(nullptr),
+      m_pMaxButton(nullptr),
+      m_pPosButton(nullptr),
+      m_bMouseDown(false),
+      m_bMinOrMax(false),
+      m_bNotifyForever(true) {}
 
 CPWL_ScrollBar::~CPWL_ScrollBar() {}
 
@@ -585,8 +590,8 @@
 }
 
 void CPWL_ScrollBar::RePosChildWnd() {
-  CPDF_Rect rcClient = GetClientRect();
-  CPDF_Rect rcMinButton, rcMaxButton;
+  CFX_FloatRect rcClient = GetClientRect();
+  CFX_FloatRect rcMinButton, rcMaxButton;
   FX_FLOAT fBWidth = 0;
 
   switch (m_sbType) {
@@ -594,23 +599,24 @@
       if (rcClient.right - rcClient.left >
           PWL_SCROLLBAR_BUTTON_WIDTH * 2 + PWL_SCROLLBAR_POSBUTTON_MINWIDTH +
               2) {
-        rcMinButton =
-            CPDF_Rect(rcClient.left, rcClient.bottom,
-                      rcClient.left + PWL_SCROLLBAR_BUTTON_WIDTH, rcClient.top);
-        rcMaxButton = CPDF_Rect(rcClient.right - PWL_SCROLLBAR_BUTTON_WIDTH,
-                                rcClient.bottom, rcClient.right, rcClient.top);
+        rcMinButton = CFX_FloatRect(rcClient.left, rcClient.bottom,
+                                    rcClient.left + PWL_SCROLLBAR_BUTTON_WIDTH,
+                                    rcClient.top);
+        rcMaxButton =
+            CFX_FloatRect(rcClient.right - PWL_SCROLLBAR_BUTTON_WIDTH,
+                          rcClient.bottom, rcClient.right, rcClient.top);
       } else {
         fBWidth = (rcClient.right - rcClient.left -
                    PWL_SCROLLBAR_POSBUTTON_MINWIDTH - 2) /
                   2;
 
         if (fBWidth > 0) {
-          rcMinButton = CPDF_Rect(rcClient.left, rcClient.bottom,
-                                  rcClient.left + fBWidth, rcClient.top);
-          rcMaxButton = CPDF_Rect(rcClient.right - fBWidth, rcClient.bottom,
-                                  rcClient.right, rcClient.top);
+          rcMinButton = CFX_FloatRect(rcClient.left, rcClient.bottom,
+                                      rcClient.left + fBWidth, rcClient.top);
+          rcMaxButton = CFX_FloatRect(rcClient.right - fBWidth, rcClient.bottom,
+                                      rcClient.right, rcClient.top);
         } else {
-          SetVisible(FALSE);
+          SetVisible(false);
         }
       }
       break;
@@ -618,44 +624,47 @@
       if (IsFloatBigger(rcClient.top - rcClient.bottom,
                         PWL_SCROLLBAR_BUTTON_WIDTH * 2 +
                             PWL_SCROLLBAR_POSBUTTON_MINWIDTH + 2)) {
-        rcMinButton =
-            CPDF_Rect(rcClient.left, rcClient.top - PWL_SCROLLBAR_BUTTON_WIDTH,
-                      rcClient.right, rcClient.top);
-        rcMaxButton = CPDF_Rect(rcClient.left, rcClient.bottom, rcClient.right,
-                                rcClient.bottom + PWL_SCROLLBAR_BUTTON_WIDTH);
+        rcMinButton = CFX_FloatRect(rcClient.left,
+                                    rcClient.top - PWL_SCROLLBAR_BUTTON_WIDTH,
+                                    rcClient.right, rcClient.top);
+        rcMaxButton =
+            CFX_FloatRect(rcClient.left, rcClient.bottom, rcClient.right,
+                          rcClient.bottom + PWL_SCROLLBAR_BUTTON_WIDTH);
       } else {
         fBWidth = (rcClient.top - rcClient.bottom -
                    PWL_SCROLLBAR_POSBUTTON_MINWIDTH - 2) /
                   2;
 
         if (IsFloatBigger(fBWidth, 0)) {
-          rcMinButton = CPDF_Rect(rcClient.left, rcClient.top - fBWidth,
-                                  rcClient.right, rcClient.top);
-          rcMaxButton = CPDF_Rect(rcClient.left, rcClient.bottom,
-                                  rcClient.right, rcClient.bottom + fBWidth);
+          rcMinButton = CFX_FloatRect(rcClient.left, rcClient.top - fBWidth,
+                                      rcClient.right, rcClient.top);
+          rcMaxButton =
+              CFX_FloatRect(rcClient.left, rcClient.bottom, rcClient.right,
+                            rcClient.bottom + fBWidth);
         } else {
-          SetVisible(FALSE);
+          SetVisible(false);
         }
       }
       break;
   }
 
   if (m_pMinButton)
-    m_pMinButton->Move(rcMinButton, TRUE, FALSE);
+    m_pMinButton->Move(rcMinButton, true, false);
   if (m_pMaxButton)
-    m_pMaxButton->Move(rcMaxButton, TRUE, FALSE);
-  MovePosButton(FALSE);
+    m_pMaxButton->Move(rcMaxButton, true, false);
+  MovePosButton(false);
 }
 
 void CPWL_ScrollBar::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) {
-  CPDF_Rect rectWnd = GetWindowRect();
+  CFX_FloatRect rectWnd = GetWindowRect();
 
   if (IsVisible() && !rectWnd.IsEmpty()) {
     CFX_ByteTextBuf sButton;
 
     sButton << "q\n";
     sButton << "0 w\n"
-            << CPWL_Utils::GetColorAppStream(GetBackgroundColor(), TRUE);
+            << CPWL_Utils::GetColorAppStream(GetBackgroundColor(), true)
+                   .AsStringC();
     sButton << rectWnd.left << " " << rectWnd.bottom << " "
             << rectWnd.right - rectWnd.left << " "
             << rectWnd.top - rectWnd.bottom << " re b Q\n";
@@ -666,7 +675,7 @@
 
 void CPWL_ScrollBar::DrawThisAppearance(CFX_RenderDevice* pDevice,
                                         CFX_Matrix* pUser2Device) {
-  CPDF_Rect rectWnd = GetWindowRect();
+  CFX_FloatRect rectWnd = GetWindowRect();
 
   if (IsVisible() && !rectWnd.IsEmpty()) {
     CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rectWnd,
@@ -674,19 +683,20 @@
 
     CPWL_Utils::DrawStrokeLine(
         pDevice, pUser2Device,
-        CPDF_Point(rectWnd.left + 2.0f, rectWnd.top - 2.0f),
-        CPDF_Point(rectWnd.left + 2.0f, rectWnd.bottom + 2.0f),
+        CFX_FloatPoint(rectWnd.left + 2.0f, rectWnd.top - 2.0f),
+        CFX_FloatPoint(rectWnd.left + 2.0f, rectWnd.bottom + 2.0f),
         ArgbEncode(GetTransparency(), 100, 100, 100), 1.0f);
 
     CPWL_Utils::DrawStrokeLine(
         pDevice, pUser2Device,
-        CPDF_Point(rectWnd.right - 2.0f, rectWnd.top - 2.0f),
-        CPDF_Point(rectWnd.right - 2.0f, rectWnd.bottom + 2.0f),
+        CFX_FloatPoint(rectWnd.right - 2.0f, rectWnd.top - 2.0f),
+        CFX_FloatPoint(rectWnd.right - 2.0f, rectWnd.bottom + 2.0f),
         ArgbEncode(GetTransparency(), 100, 100, 100), 1.0f);
   }
 }
 
-FX_BOOL CPWL_ScrollBar::OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) {
+bool CPWL_ScrollBar::OnLButtonDown(const CFX_FloatPoint& point,
+                                   uint32_t nFlag) {
   CPWL_Wnd::OnLButtonDown(point, nFlag);
 
   if (HasFlag(PWS_AUTOTRANSPARENT)) {
@@ -696,27 +706,29 @@
     }
   }
 
-  CPDF_Rect rcMinArea, rcMaxArea;
+  CFX_FloatRect rcMinArea, rcMaxArea;
 
   if (m_pPosButton && m_pPosButton->IsVisible()) {
-    CPDF_Rect rcClient = GetClientRect();
-    CPDF_Rect rcPosButton = m_pPosButton->GetWindowRect();
+    CFX_FloatRect rcClient = GetClientRect();
+    CFX_FloatRect rcPosButton = m_pPosButton->GetWindowRect();
 
     switch (m_sbType) {
       case SBT_HSCROLL:
-        rcMinArea = CPDF_Rect(rcClient.left + PWL_SCROLLBAR_BUTTON_WIDTH,
-                              rcClient.bottom, rcPosButton.left, rcClient.top);
-        rcMaxArea = CPDF_Rect(rcPosButton.right, rcClient.bottom,
-                              rcClient.right - PWL_SCROLLBAR_BUTTON_WIDTH,
-                              rcClient.top);
+        rcMinArea =
+            CFX_FloatRect(rcClient.left + PWL_SCROLLBAR_BUTTON_WIDTH,
+                          rcClient.bottom, rcPosButton.left, rcClient.top);
+        rcMaxArea = CFX_FloatRect(rcPosButton.right, rcClient.bottom,
+                                  rcClient.right - PWL_SCROLLBAR_BUTTON_WIDTH,
+                                  rcClient.top);
 
         break;
       case SBT_VSCROLL:
-        rcMinArea = CPDF_Rect(rcClient.left, rcPosButton.top, rcClient.right,
-                              rcClient.top - PWL_SCROLLBAR_BUTTON_WIDTH);
-        rcMaxArea = CPDF_Rect(rcClient.left,
-                              rcClient.bottom + PWL_SCROLLBAR_BUTTON_WIDTH,
-                              rcClient.right, rcPosButton.bottom);
+        rcMinArea =
+            CFX_FloatRect(rcClient.left, rcPosButton.top, rcClient.right,
+                          rcClient.top - PWL_SCROLLBAR_BUTTON_WIDTH);
+        rcMaxArea = CFX_FloatRect(rcClient.left,
+                                  rcClient.bottom + PWL_SCROLLBAR_BUTTON_WIDTH,
+                                  rcClient.right, rcPosButton.bottom);
         break;
     }
 
@@ -725,21 +737,21 @@
 
     if (rcMinArea.Contains(point.x, point.y)) {
       m_sData.SubBig();
-      MovePosButton(TRUE);
+      MovePosButton(true);
       NotifyScrollWindow();
     }
 
     if (rcMaxArea.Contains(point.x, point.y)) {
       m_sData.AddBig();
-      MovePosButton(TRUE);
+      MovePosButton(true);
       NotifyScrollWindow();
     }
   }
 
-  return TRUE;
+  return true;
 }
 
-FX_BOOL CPWL_ScrollBar::OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag) {
+bool CPWL_ScrollBar::OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) {
   CPWL_Wnd::OnLButtonUp(point, nFlag);
 
   if (HasFlag(PWS_AUTOTRANSPARENT)) {
@@ -750,13 +762,13 @@
   }
 
   EndTimer();
-  m_bMouseDown = FALSE;
+  m_bMouseDown = false;
 
-  return TRUE;
+  return true;
 }
 
 void CPWL_ScrollBar::OnNotify(CPWL_Wnd* pWnd,
-                              FX_DWORD msg,
+                              uint32_t msg,
                               intptr_t wParam,
                               intptr_t lParam) {
   CPWL_Wnd::OnNotify(pWnd, msg, wParam, lParam);
@@ -764,53 +776,52 @@
   switch (msg) {
     case PNM_LBUTTONDOWN:
       if (pWnd == m_pMinButton) {
-        OnMinButtonLBDown(*(CPDF_Point*)lParam);
+        OnMinButtonLBDown(*(CFX_FloatPoint*)lParam);
       }
 
       if (pWnd == m_pMaxButton) {
-        OnMaxButtonLBDown(*(CPDF_Point*)lParam);
+        OnMaxButtonLBDown(*(CFX_FloatPoint*)lParam);
       }
 
       if (pWnd == m_pPosButton) {
-        OnPosButtonLBDown(*(CPDF_Point*)lParam);
+        OnPosButtonLBDown(*(CFX_FloatPoint*)lParam);
       }
       break;
     case PNM_LBUTTONUP:
       if (pWnd == m_pMinButton) {
-        OnMinButtonLBUp(*(CPDF_Point*)lParam);
+        OnMinButtonLBUp(*(CFX_FloatPoint*)lParam);
       }
 
       if (pWnd == m_pMaxButton) {
-        OnMaxButtonLBUp(*(CPDF_Point*)lParam);
+        OnMaxButtonLBUp(*(CFX_FloatPoint*)lParam);
       }
 
       if (pWnd == m_pPosButton) {
-        OnPosButtonLBUp(*(CPDF_Point*)lParam);
+        OnPosButtonLBUp(*(CFX_FloatPoint*)lParam);
       }
       break;
     case PNM_MOUSEMOVE:
       if (pWnd == m_pMinButton) {
-        OnMinButtonMouseMove(*(CPDF_Point*)lParam);
+        OnMinButtonMouseMove(*(CFX_FloatPoint*)lParam);
       }
 
       if (pWnd == m_pMaxButton) {
-        OnMaxButtonMouseMove(*(CPDF_Point*)lParam);
+        OnMaxButtonMouseMove(*(CFX_FloatPoint*)lParam);
       }
 
       if (pWnd == m_pPosButton) {
-        OnPosButtonMouseMove(*(CPDF_Point*)lParam);
+        OnPosButtonMouseMove(*(CFX_FloatPoint*)lParam);
       }
       break;
     case PNM_SETSCROLLINFO: {
-      if (PWL_SCROLL_INFO* pInfo = (PWL_SCROLL_INFO*)lParam) {
-        if (FXSYS_memcmp(&m_OriginInfo, pInfo, sizeof(PWL_SCROLL_INFO)) != 0) {
-          m_OriginInfo = *pInfo;
-          FX_FLOAT fMax =
-              pInfo->fContentMax - pInfo->fContentMin - pInfo->fPlateWidth;
-          fMax = fMax > 0.0f ? fMax : 0.0f;
-          SetScrollRange(0, fMax, pInfo->fPlateWidth);
-          SetScrollStep(pInfo->fBigStep, pInfo->fSmallStep);
-        }
+      PWL_SCROLL_INFO* pInfo = reinterpret_cast<PWL_SCROLL_INFO*>(lParam);
+      if (pInfo && *pInfo != m_OriginInfo) {
+        m_OriginInfo = *pInfo;
+        FX_FLOAT fMax =
+            pInfo->fContentMax - pInfo->fContentMin - pInfo->fPlateWidth;
+        fMax = fMax > 0.0f ? fMax : 0.0f;
+        SetScrollRange(0, fMax, pInfo->fPlateWidth);
+        SetScrollStep(pInfo->fBigStep, pInfo->fSmallStep);
       }
     } break;
     case PNM_SETSCROLLPOS: {
@@ -832,7 +843,7 @@
   PWL_CREATEPARAM scp = cp;
   scp.pParentWnd = this;
   scp.dwBorderWidth = 2;
-  scp.nBorderStyle = PBS_BEVELED;
+  scp.nBorderStyle = BorderStyle::BEVELED;
 
   scp.dwFlags =
       PWS_VISIBLE | PWS_CHILD | PWS_BORDER | PWS_BACKGROUND | PWS_NOREFRESHCLIP;
@@ -849,7 +860,7 @@
 
   if (!m_pPosButton) {
     m_pPosButton = new CPWL_SBButton(m_sbType, PSBT_POS);
-    m_pPosButton->SetVisible(FALSE);
+    m_pPosButton->SetVisible(false);
     m_pPosButton->Create(scp);
   }
 }
@@ -869,10 +880,10 @@
     m_sData.SetClientWidth(fClientWidth);
 
     if (IsFloatSmaller(m_sData.ScrollRange.GetWidth(), 0.0f)) {
-      m_pPosButton->SetVisible(FALSE);
+      m_pPosButton->SetVisible(false);
     } else {
-      m_pPosButton->SetVisible(TRUE);
-      MovePosButton(TRUE);
+      m_pPosButton->SetVisible(true);
+      MovePosButton(true);
     }
   }
 }
@@ -883,7 +894,7 @@
   m_sData.SetPos(fPos);
 
   if (!IsFloatEqual(m_sData.fScrollPos, fOldPos))
-    MovePosButton(TRUE);
+    MovePosButton(true);
 }
 
 void CPWL_ScrollBar::SetScrollStep(FX_FLOAT fBigStep, FX_FLOAT fSmallStep) {
@@ -891,13 +902,13 @@
   m_sData.SetSmallStep(fSmallStep);
 }
 
-void CPWL_ScrollBar::MovePosButton(FX_BOOL bRefresh) {
+void CPWL_ScrollBar::MovePosButton(bool bRefresh) {
   ASSERT(m_pMinButton);
   ASSERT(m_pMaxButton);
 
   if (m_pPosButton->IsVisible()) {
-    CPDF_Rect rcClient;
-    CPDF_Rect rcPosArea, rcPosButton;
+    CFX_FloatRect rcClient;
+    CFX_FloatRect rcPosArea, rcPosButton;
 
     rcClient = GetClientRect();
     rcPosArea = GetScrollArea();
@@ -917,7 +928,8 @@
           fLeft = fRight - PWL_SCROLLBAR_POSBUTTON_MINWIDTH;
         }
 
-        rcPosButton = CPDF_Rect(fLeft, rcPosArea.bottom, fRight, rcPosArea.top);
+        rcPosButton =
+            CFX_FloatRect(fLeft, rcPosArea.bottom, fRight, rcPosArea.top);
 
         break;
       case SBT_VSCROLL:
@@ -932,50 +944,51 @@
           fTop = fBottom + PWL_SCROLLBAR_POSBUTTON_MINWIDTH;
         }
 
-        rcPosButton = CPDF_Rect(rcPosArea.left, fBottom, rcPosArea.right, fTop);
+        rcPosButton =
+            CFX_FloatRect(rcPosArea.left, fBottom, rcPosArea.right, fTop);
 
         break;
     }
 
-    m_pPosButton->Move(rcPosButton, TRUE, bRefresh);
+    m_pPosButton->Move(rcPosButton, true, bRefresh);
   }
 }
 
-void CPWL_ScrollBar::OnMinButtonLBDown(const CPDF_Point& point) {
+void CPWL_ScrollBar::OnMinButtonLBDown(const CFX_FloatPoint& point) {
   m_sData.SubSmall();
-  MovePosButton(TRUE);
+  MovePosButton(true);
   NotifyScrollWindow();
 
-  m_bMinOrMax = TRUE;
+  m_bMinOrMax = true;
 
   EndTimer();
   BeginTimer(100);
 }
 
-void CPWL_ScrollBar::OnMinButtonLBUp(const CPDF_Point& point) {}
+void CPWL_ScrollBar::OnMinButtonLBUp(const CFX_FloatPoint& point) {}
 
-void CPWL_ScrollBar::OnMinButtonMouseMove(const CPDF_Point& point) {}
+void CPWL_ScrollBar::OnMinButtonMouseMove(const CFX_FloatPoint& point) {}
 
-void CPWL_ScrollBar::OnMaxButtonLBDown(const CPDF_Point& point) {
+void CPWL_ScrollBar::OnMaxButtonLBDown(const CFX_FloatPoint& point) {
   m_sData.AddSmall();
-  MovePosButton(TRUE);
+  MovePosButton(true);
   NotifyScrollWindow();
 
-  m_bMinOrMax = FALSE;
+  m_bMinOrMax = false;
 
   EndTimer();
   BeginTimer(100);
 }
 
-void CPWL_ScrollBar::OnMaxButtonLBUp(const CPDF_Point& point) {}
+void CPWL_ScrollBar::OnMaxButtonLBUp(const CFX_FloatPoint& point) {}
 
-void CPWL_ScrollBar::OnMaxButtonMouseMove(const CPDF_Point& point) {}
+void CPWL_ScrollBar::OnMaxButtonMouseMove(const CFX_FloatPoint& point) {}
 
-void CPWL_ScrollBar::OnPosButtonLBDown(const CPDF_Point& point) {
-  m_bMouseDown = TRUE;
+void CPWL_ScrollBar::OnPosButtonLBDown(const CFX_FloatPoint& point) {
+  m_bMouseDown = true;
 
   if (m_pPosButton) {
-    CPDF_Rect rcPosButton = m_pPosButton->GetWindowRect();
+    CFX_FloatRect rcPosButton = m_pPosButton->GetWindowRect();
 
     switch (m_sbType) {
       case SBT_HSCROLL:
@@ -990,15 +1003,15 @@
   }
 }
 
-void CPWL_ScrollBar::OnPosButtonLBUp(const CPDF_Point& point) {
+void CPWL_ScrollBar::OnPosButtonLBUp(const CFX_FloatPoint& point) {
   if (m_bMouseDown) {
     if (!m_bNotifyForever)
       NotifyScrollWindow();
   }
-  m_bMouseDown = FALSE;
+  m_bMouseDown = false;
 }
 
-void CPWL_ScrollBar::OnPosButtonMouseMove(const CPDF_Point& point) {
+void CPWL_ScrollBar::OnPosButtonMouseMove(const CFX_FloatPoint& point) {
   FX_FLOAT fOldScrollPos = m_sData.fScrollPos;
 
   FX_FLOAT fNewPos = 0;
@@ -1047,7 +1060,7 @@
     }
 
     if (!IsFloatEqual(fOldScrollPos, m_sData.fScrollPos)) {
-      MovePosButton(TRUE);
+      MovePosButton(true);
 
       if (m_bNotifyForever)
         NotifyScrollWindow();
@@ -1071,15 +1084,15 @@
   }
 }
 
-CPDF_Rect CPWL_ScrollBar::GetScrollArea() const {
-  CPDF_Rect rcClient = GetClientRect();
-  CPDF_Rect rcArea;
+CFX_FloatRect CPWL_ScrollBar::GetScrollArea() const {
+  CFX_FloatRect rcClient = GetClientRect();
+  CFX_FloatRect rcArea;
 
   if (!m_pMinButton || !m_pMaxButton)
     return rcClient;
 
-  CPDF_Rect rcMin = m_pMinButton->GetWindowRect();
-  CPDF_Rect rcMax = m_pMaxButton->GetWindowRect();
+  CFX_FloatRect rcMin = m_pMinButton->GetWindowRect();
+  CFX_FloatRect rcMax = m_pMaxButton->GetWindowRect();
 
   FX_FLOAT fMinWidth = rcMin.right - rcMin.left;
   FX_FLOAT fMinHeight = rcMin.top - rcMin.bottom;
@@ -1089,20 +1102,21 @@
   switch (m_sbType) {
     case SBT_HSCROLL:
       if (rcClient.right - rcClient.left > fMinWidth + fMaxWidth + 2) {
-        rcArea = CPDF_Rect(rcClient.left + fMinWidth + 1, rcClient.bottom,
-                           rcClient.right - fMaxWidth - 1, rcClient.top);
+        rcArea = CFX_FloatRect(rcClient.left + fMinWidth + 1, rcClient.bottom,
+                               rcClient.right - fMaxWidth - 1, rcClient.top);
       } else {
-        rcArea = CPDF_Rect(rcClient.left + fMinWidth + 1, rcClient.bottom,
-                           rcClient.left + fMinWidth + 1, rcClient.top);
+        rcArea = CFX_FloatRect(rcClient.left + fMinWidth + 1, rcClient.bottom,
+                               rcClient.left + fMinWidth + 1, rcClient.top);
       }
       break;
     case SBT_VSCROLL:
       if (rcClient.top - rcClient.bottom > fMinHeight + fMaxHeight + 2) {
-        rcArea = CPDF_Rect(rcClient.left, rcClient.bottom + fMinHeight + 1,
-                           rcClient.right, rcClient.top - fMaxHeight - 1);
+        rcArea = CFX_FloatRect(rcClient.left, rcClient.bottom + fMinHeight + 1,
+                               rcClient.right, rcClient.top - fMaxHeight - 1);
       } else {
-        rcArea = CPDF_Rect(rcClient.left, rcClient.bottom + fMinHeight + 1,
-                           rcClient.right, rcClient.bottom + fMinHeight + 1);
+        rcArea =
+            CFX_FloatRect(rcClient.left, rcClient.bottom + fMinHeight + 1,
+                          rcClient.right, rcClient.bottom + fMinHeight + 1);
       }
       break;
   }
@@ -1113,7 +1127,7 @@
 }
 
 FX_FLOAT CPWL_ScrollBar::TrueToFace(FX_FLOAT fTrue) {
-  CPDF_Rect rcPosArea;
+  CFX_FloatRect rcPosArea;
   rcPosArea = GetScrollArea();
 
   FX_FLOAT fFactWidth = m_sData.ScrollRange.GetWidth() + m_sData.fClientWidth;
@@ -1136,7 +1150,7 @@
 }
 
 FX_FLOAT CPWL_ScrollBar::FaceToTrue(FX_FLOAT fFace) {
-  CPDF_Rect rcPosArea;
+  CFX_FloatRect rcPosArea;
   rcPosArea = GetScrollArea();
 
   FX_FLOAT fFactWidth = m_sData.ScrollRange.GetWidth() + m_sData.fClientWidth;
@@ -1164,14 +1178,13 @@
 
 void CPWL_ScrollBar::TimerProc() {
   PWL_SCROLL_PRIVATEDATA sTemp = m_sData;
-
   if (m_bMinOrMax)
     m_sData.SubSmall();
   else
     m_sData.AddSmall();
 
-  if (FXSYS_memcmp(&m_sData, &sTemp, sizeof(PWL_SCROLL_PRIVATEDATA)) != 0) {
-    MovePosButton(TRUE);
+  if (sTemp != m_sData) {
+    MovePosButton(true);
     NotifyScrollWindow();
   }
 }
diff --git a/fpdfsdk/pdfwindow/PWL_ScrollBar.h b/fpdfsdk/pdfwindow/PWL_ScrollBar.h
new file mode 100644
index 0000000..bcfb0a6
--- /dev/null
+++ b/fpdfsdk/pdfwindow/PWL_ScrollBar.h
@@ -0,0 +1,183 @@
+// 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_PDFWINDOW_PWL_SCROLLBAR_H_
+#define FPDFSDK_PDFWINDOW_PWL_SCROLLBAR_H_
+
+#include "fpdfsdk/pdfwindow/PWL_Wnd.h"
+
+class CPWL_SBButton;
+class CPWL_ScrollBar;
+
+struct PWL_SCROLL_INFO {
+ public:
+  PWL_SCROLL_INFO()
+      : fContentMin(0.0f),
+        fContentMax(0.0f),
+        fPlateWidth(0.0f),
+        fBigStep(0.0f),
+        fSmallStep(0.0f) {}
+
+  bool operator==(const PWL_SCROLL_INFO& that) const {
+    return fContentMin == that.fContentMin && fContentMax == that.fContentMax &&
+           fPlateWidth == that.fPlateWidth && fBigStep == that.fBigStep &&
+           fSmallStep == that.fSmallStep;
+  }
+  bool operator!=(const PWL_SCROLL_INFO& that) const {
+    return !(*this == that);
+  }
+
+  FX_FLOAT fContentMin;
+  FX_FLOAT fContentMax;
+  FX_FLOAT fPlateWidth;
+  FX_FLOAT fBigStep;
+  FX_FLOAT fSmallStep;
+};
+
+enum PWL_SCROLLBAR_TYPE { SBT_HSCROLL, SBT_VSCROLL };
+
+enum PWL_SBBUTTON_TYPE { PSBT_MIN, PSBT_MAX, PSBT_POS };
+
+class CPWL_SBButton : public CPWL_Wnd {
+ public:
+  CPWL_SBButton(PWL_SCROLLBAR_TYPE eScrollBarType,
+                PWL_SBBUTTON_TYPE eButtonType);
+  ~CPWL_SBButton() override;
+
+  // CPWL_Wnd
+  CFX_ByteString GetClassName() const override;
+  void OnCreate(PWL_CREATEPARAM& cp) override;
+  void GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) override;
+  void DrawThisAppearance(CFX_RenderDevice* pDevice,
+                          CFX_Matrix* pUser2Device) override;
+  bool OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag) override;
+  bool OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) override;
+  bool OnMouseMove(const CFX_FloatPoint& point, uint32_t nFlag) override;
+
+ protected:
+  PWL_SCROLLBAR_TYPE m_eScrollBarType;
+  PWL_SBBUTTON_TYPE m_eSBButtonType;
+
+  bool m_bMouseDown;
+};
+
+struct PWL_FLOATRANGE {
+ public:
+  PWL_FLOATRANGE();
+  PWL_FLOATRANGE(FX_FLOAT min, FX_FLOAT max);
+
+  bool operator==(const PWL_FLOATRANGE& that) const {
+    return fMin == that.fMin && fMax == that.fMax;
+  }
+  bool operator!=(const PWL_FLOATRANGE& that) const { return !(*this == that); }
+
+  void Default();
+  void Set(FX_FLOAT min, FX_FLOAT max);
+  bool In(FX_FLOAT x) const;
+  FX_FLOAT GetWidth() const;
+
+  FX_FLOAT fMin;
+  FX_FLOAT fMax;
+};
+
+struct PWL_SCROLL_PRIVATEDATA {
+ public:
+  PWL_SCROLL_PRIVATEDATA();
+
+  bool operator==(const PWL_SCROLL_PRIVATEDATA& that) const {
+    return ScrollRange == that.ScrollRange &&
+           fClientWidth == that.fClientWidth && fScrollPos == that.fScrollPos &&
+           fBigStep == that.fBigStep && fSmallStep == that.fSmallStep;
+  }
+  bool operator!=(const PWL_SCROLL_PRIVATEDATA& that) const {
+    return !(*this == that);
+  }
+
+  void Default();
+  void SetScrollRange(FX_FLOAT min, FX_FLOAT max);
+  void SetClientWidth(FX_FLOAT width);
+  void SetSmallStep(FX_FLOAT step);
+  void SetBigStep(FX_FLOAT step);
+  bool SetPos(FX_FLOAT pos);
+
+  void AddSmall();
+  void SubSmall();
+  void AddBig();
+  void SubBig();
+
+  PWL_FLOATRANGE ScrollRange;
+  FX_FLOAT fClientWidth;
+  FX_FLOAT fScrollPos;
+  FX_FLOAT fBigStep;
+  FX_FLOAT fSmallStep;
+};
+
+class CPWL_ScrollBar : public CPWL_Wnd {
+ public:
+  explicit CPWL_ScrollBar(PWL_SCROLLBAR_TYPE sbType = SBT_HSCROLL);
+  ~CPWL_ScrollBar() override;
+
+  // CPWL_Wnd
+  CFX_ByteString GetClassName() const override;
+  void OnCreate(PWL_CREATEPARAM& cp) override;
+  void RePosChildWnd() override;
+  void GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) override;
+  void DrawThisAppearance(CFX_RenderDevice* pDevice,
+                          CFX_Matrix* pUser2Device) override;
+  bool OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag) override;
+  bool OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) override;
+  void OnNotify(CPWL_Wnd* pWnd,
+                uint32_t msg,
+                intptr_t wParam = 0,
+                intptr_t lParam = 0) override;
+  void CreateChildWnd(const PWL_CREATEPARAM& cp) override;
+  void TimerProc() override;
+
+  FX_FLOAT GetScrollBarWidth() const;
+  PWL_SCROLLBAR_TYPE GetScrollBarType() const { return m_sbType; }
+
+  void SetNotifyForever(bool bForever) { m_bNotifyForever = bForever; }
+
+ protected:
+  void SetScrollRange(FX_FLOAT fMin, FX_FLOAT fMax, FX_FLOAT fClientWidth);
+  void SetScrollPos(FX_FLOAT fPos);
+  void MovePosButton(bool bRefresh);
+  void SetScrollStep(FX_FLOAT fBigStep, FX_FLOAT fSmallStep);
+  void NotifyScrollWindow();
+  CFX_FloatRect GetScrollArea() const;
+
+ private:
+  void CreateButtons(const PWL_CREATEPARAM& cp);
+
+  void OnMinButtonLBDown(const CFX_FloatPoint& point);
+  void OnMinButtonLBUp(const CFX_FloatPoint& point);
+  void OnMinButtonMouseMove(const CFX_FloatPoint& point);
+
+  void OnMaxButtonLBDown(const CFX_FloatPoint& point);
+  void OnMaxButtonLBUp(const CFX_FloatPoint& point);
+  void OnMaxButtonMouseMove(const CFX_FloatPoint& point);
+
+  void OnPosButtonLBDown(const CFX_FloatPoint& point);
+  void OnPosButtonLBUp(const CFX_FloatPoint& point);
+  void OnPosButtonMouseMove(const CFX_FloatPoint& point);
+
+  FX_FLOAT TrueToFace(FX_FLOAT);
+  FX_FLOAT FaceToTrue(FX_FLOAT);
+
+  PWL_SCROLLBAR_TYPE m_sbType;
+  PWL_SCROLL_INFO m_OriginInfo;
+  CPWL_SBButton* m_pMinButton;
+  CPWL_SBButton* m_pMaxButton;
+  CPWL_SBButton* m_pPosButton;
+  PWL_SCROLL_PRIVATEDATA m_sData;
+  bool m_bMouseDown;
+  bool m_bMinOrMax;
+  bool m_bNotifyForever;
+  FX_FLOAT m_nOldPos;
+  FX_FLOAT m_fOldPosButton;
+};
+
+#endif  // FPDFSDK_PDFWINDOW_PWL_SCROLLBAR_H_
diff --git a/fpdfsdk/pdfwindow/PWL_SpecialButton.cpp b/fpdfsdk/pdfwindow/PWL_SpecialButton.cpp
new file mode 100644
index 0000000..defb992
--- /dev/null
+++ b/fpdfsdk/pdfwindow/PWL_SpecialButton.cpp
@@ -0,0 +1,81 @@
+// 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
+
+#include "fpdfsdk/pdfwindow/PWL_Button.h"
+#include "fpdfsdk/pdfwindow/PWL_SpecialButton.h"
+#include "fpdfsdk/pdfwindow/PWL_Utils.h"
+#include "fpdfsdk/pdfwindow/PWL_Wnd.h"
+
+CPWL_PushButton::CPWL_PushButton() {}
+
+CPWL_PushButton::~CPWL_PushButton() {}
+
+CFX_ByteString CPWL_PushButton::GetClassName() const {
+  return "CPWL_PushButton";
+}
+
+CFX_FloatRect CPWL_PushButton::GetFocusRect() const {
+  return CPWL_Utils::DeflateRect(GetWindowRect(), (FX_FLOAT)GetBorderWidth());
+}
+
+CPWL_CheckBox::CPWL_CheckBox() : m_bChecked(false) {}
+
+CPWL_CheckBox::~CPWL_CheckBox() {}
+
+CFX_ByteString CPWL_CheckBox::GetClassName() const {
+  return "CPWL_CheckBox";
+}
+
+void CPWL_CheckBox::SetCheck(bool bCheck) {
+  m_bChecked = bCheck;
+}
+
+bool CPWL_CheckBox::IsChecked() const {
+  return m_bChecked;
+}
+
+bool CPWL_CheckBox::OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) {
+  if (IsReadOnly())
+    return false;
+
+  SetCheck(!IsChecked());
+  return true;
+}
+
+bool CPWL_CheckBox::OnChar(uint16_t nChar, uint32_t nFlag) {
+  SetCheck(!IsChecked());
+  return true;
+}
+
+CPWL_RadioButton::CPWL_RadioButton() : m_bChecked(false) {}
+
+CPWL_RadioButton::~CPWL_RadioButton() {}
+
+CFX_ByteString CPWL_RadioButton::GetClassName() const {
+  return "CPWL_RadioButton";
+}
+
+bool CPWL_RadioButton::OnLButtonUp(const CFX_FloatPoint& point,
+                                   uint32_t nFlag) {
+  if (IsReadOnly())
+    return false;
+
+  SetCheck(true);
+  return true;
+}
+
+void CPWL_RadioButton::SetCheck(bool bCheck) {
+  m_bChecked = bCheck;
+}
+
+bool CPWL_RadioButton::IsChecked() const {
+  return m_bChecked;
+}
+
+bool CPWL_RadioButton::OnChar(uint16_t nChar, uint32_t nFlag) {
+  SetCheck(true);
+  return true;
+}
diff --git a/fpdfsdk/pdfwindow/PWL_SpecialButton.h b/fpdfsdk/pdfwindow/PWL_SpecialButton.h
new file mode 100644
index 0000000..0aa6c45
--- /dev/null
+++ b/fpdfsdk/pdfwindow/PWL_SpecialButton.h
@@ -0,0 +1,56 @@
+// 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_PDFWINDOW_PWL_SPECIALBUTTON_H_
+#define FPDFSDK_PDFWINDOW_PWL_SPECIALBUTTON_H_
+
+#include "fpdfsdk/pdfwindow/PWL_Button.h"
+
+class CPWL_PushButton : public CPWL_Button {
+ public:
+  CPWL_PushButton();
+  ~CPWL_PushButton() override;
+
+  // CPWL_Button
+  CFX_ByteString GetClassName() const override;
+  CFX_FloatRect GetFocusRect() const override;
+};
+
+class CPWL_CheckBox : public CPWL_Button {
+ public:
+  CPWL_CheckBox();
+  ~CPWL_CheckBox() override;
+
+  // CPWL_Button
+  CFX_ByteString GetClassName() const override;
+  bool OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) override;
+  bool OnChar(uint16_t nChar, uint32_t nFlag) override;
+
+  void SetCheck(bool bCheck);
+  bool IsChecked() const;
+
+ private:
+  bool m_bChecked;
+};
+
+class CPWL_RadioButton : public CPWL_Button {
+ public:
+  CPWL_RadioButton();
+  ~CPWL_RadioButton() override;
+
+  // CPWL_Button
+  CFX_ByteString GetClassName() const override;
+  bool OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) override;
+  bool OnChar(uint16_t nChar, uint32_t nFlag) override;
+
+  void SetCheck(bool bCheck);
+  bool IsChecked() const;
+
+ private:
+  bool m_bChecked;
+};
+
+#endif  // FPDFSDK_PDFWINDOW_PWL_SPECIALBUTTON_H_
diff --git a/fpdfsdk/src/pdfwindow/PWL_Utils.cpp b/fpdfsdk/pdfwindow/PWL_Utils.cpp
similarity index 75%
rename from fpdfsdk/src/pdfwindow/PWL_Utils.cpp
rename to fpdfsdk/pdfwindow/PWL_Utils.cpp
index 27ba8bc..713a193 100644
--- a/fpdfsdk/src/pdfwindow/PWL_Utils.cpp
+++ b/fpdfsdk/pdfwindow/PWL_Utils.cpp
@@ -4,17 +4,18 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
+#include "fpdfsdk/pdfwindow/PWL_Utils.h"
 
 #include <algorithm>
+#include <memory>
 
-#include "fpdfsdk/include/pdfwindow/PWL_Icon.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Wnd.h"
-
-#define IsFloatZero(f) ((f) < 0.0001 && (f) > -0.0001)
-#define IsFloatBigger(fa, fb) ((fa) > (fb) && !IsFloatZero((fa) - (fb)))
-#define IsFloatSmaller(fa, fb) ((fa) < (fb) && !IsFloatZero((fa) - (fb)))
-#define IsFloatEqual(fa, fb) IsFloatZero((fa) - (fb))
+#include "core/fpdfdoc/cpvt_word.h"
+#include "core/fxge/cfx_graphstatedata.h"
+#include "core/fxge/cfx_pathdata.h"
+#include "core/fxge/cfx_renderdevice.h"
+#include "fpdfsdk/fxedit/fxet_edit.h"
+#include "fpdfsdk/pdfwindow/PWL_Icon.h"
+#include "fpdfsdk/pdfwindow/PWL_Wnd.h"
 
 CFX_ByteString CPWL_Utils::GetAppStreamFromArray(const CPWL_PathData* pPathData,
                                                  int32_t nCount) {
@@ -41,7 +42,7 @@
     }
   }
 
-  return csAP.GetByteString();
+  return csAP.MakeString();
 }
 
 void CPWL_Utils::GetPathDataFromArray(CFX_PathData& path,
@@ -69,8 +70,9 @@
   }
 }
 
-CPDF_Rect CPWL_Utils::MaxRect(const CPDF_Rect& rect1, const CPDF_Rect& rect2) {
-  CPDF_Rect rcRet;
+CFX_FloatRect CPWL_Utils::MaxRect(const CFX_FloatRect& rect1,
+                                  const CFX_FloatRect& rect2) {
+  CFX_FloatRect rcRet;
 
   rcRet.left = PWL_MIN(rect1.left, rect2.left);
   rcRet.bottom = PWL_MIN(rect1.bottom, rect2.bottom);
@@ -80,21 +82,21 @@
   return rcRet;
 }
 
-CPDF_Rect CPWL_Utils::OffsetRect(const CPDF_Rect& rect,
-                                 FX_FLOAT x,
-                                 FX_FLOAT y) {
-  return CPDF_Rect(rect.left + x, rect.bottom + y, rect.right + x,
-                   rect.top + y);
+CFX_FloatRect CPWL_Utils::OffsetRect(const CFX_FloatRect& rect,
+                                     FX_FLOAT x,
+                                     FX_FLOAT y) {
+  return CFX_FloatRect(rect.left + x, rect.bottom + y, rect.right + x,
+                       rect.top + y);
 }
 
-FX_BOOL CPWL_Utils::ContainsRect(const CPDF_Rect& rcParent,
-                                 const CPDF_Rect& rcChild) {
+bool CPWL_Utils::ContainsRect(const CFX_FloatRect& rcParent,
+                              const CFX_FloatRect& rcChild) {
   return rcChild.left >= rcParent.left && rcChild.bottom >= rcParent.bottom &&
          rcChild.right <= rcParent.right && rcChild.top <= rcParent.top;
 }
 
-FX_BOOL CPWL_Utils::IntersectRect(const CPDF_Rect& rect1,
-                                  const CPDF_Rect& rect2) {
+bool CPWL_Utils::IntersectRect(const CFX_FloatRect& rect1,
+                               const CFX_FloatRect& rect2) {
   FX_FLOAT left = rect1.left > rect2.left ? rect1.left : rect2.left;
   FX_FLOAT right = rect1.right < rect2.right ? rect1.right : rect2.right;
   FX_FLOAT bottom = rect1.bottom > rect2.bottom ? rect1.bottom : rect2.bottom;
@@ -103,10 +105,10 @@
   return left < right && bottom < top;
 }
 
-CPDF_Point CPWL_Utils::OffsetPoint(const CPDF_Point& point,
-                                   FX_FLOAT x,
-                                   FX_FLOAT y) {
-  return CPDF_Point(point.x + x, point.y + y);
+CFX_FloatPoint CPWL_Utils::OffsetPoint(const CFX_FloatPoint& point,
+                                       FX_FLOAT x,
+                                       FX_FLOAT y) {
+  return CFX_FloatPoint(point.x + x, point.y + y);
 }
 
 CPVT_WordRange CPWL_Utils::OverlapWordRange(const CPVT_WordRange& wr1,
@@ -135,7 +137,7 @@
   return wrRet;
 }
 
-CFX_ByteString CPWL_Utils::GetAP_Check(const CPDF_Rect& crBBox) {
+CFX_ByteString CPWL_Utils::GetAP_Check(const CFX_FloatRect& crBBox) {
   const FX_FLOAT fWidth = crBBox.right - crBBox.left;
   const FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
 
@@ -174,59 +176,59 @@
     FX_FLOAT px2 = pts[i][2].x - pts[nNext][0].x;
     FX_FLOAT py2 = pts[i][2].y - pts[nNext][0].y;
 
-    csAP << pts[i][0].x + px1 * PWL_BEZIER << " "
-         << pts[i][0].y + py1 * PWL_BEZIER << " "
-         << pts[nNext][0].x + px2 * PWL_BEZIER << " "
-         << pts[nNext][0].y + py2 * PWL_BEZIER << " " << pts[nNext][0].x << " "
+    csAP << pts[i][0].x + px1 * FX_BEZIER << " "
+         << pts[i][0].y + py1 * FX_BEZIER << " "
+         << pts[nNext][0].x + px2 * FX_BEZIER << " "
+         << pts[nNext][0].y + py2 * FX_BEZIER << " " << pts[nNext][0].x << " "
          << pts[nNext][0].y << " c\n";
   }
 
-  return csAP.GetByteString();
+  return csAP.MakeString();
 }
 
-CFX_ByteString CPWL_Utils::GetAP_Circle(const CPDF_Rect& crBBox) {
+CFX_ByteString CPWL_Utils::GetAP_Circle(const CFX_FloatRect& crBBox) {
   CFX_ByteTextBuf csAP;
 
   FX_FLOAT fWidth = crBBox.right - crBBox.left;
   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
 
-  CPDF_Point pt1(crBBox.left, crBBox.bottom + fHeight / 2);
-  CPDF_Point pt2(crBBox.left + fWidth / 2, crBBox.top);
-  CPDF_Point pt3(crBBox.right, crBBox.bottom + fHeight / 2);
-  CPDF_Point pt4(crBBox.left + fWidth / 2, crBBox.bottom);
+  CFX_FloatPoint pt1(crBBox.left, crBBox.bottom + fHeight / 2);
+  CFX_FloatPoint pt2(crBBox.left + fWidth / 2, crBBox.top);
+  CFX_FloatPoint pt3(crBBox.right, crBBox.bottom + fHeight / 2);
+  CFX_FloatPoint pt4(crBBox.left + fWidth / 2, crBBox.bottom);
 
   csAP << pt1.x << " " << pt1.y << " m\n";
 
   FX_FLOAT px = pt2.x - pt1.x;
   FX_FLOAT py = pt2.y - pt1.y;
 
-  csAP << pt1.x << " " << pt1.y + py * PWL_BEZIER << " "
-       << pt2.x - px * PWL_BEZIER << " " << pt2.y << " " << pt2.x << " "
-       << pt2.y << " c\n";
+  csAP << pt1.x << " " << pt1.y + py * FX_BEZIER << " "
+       << pt2.x - px * FX_BEZIER << " " << pt2.y << " " << pt2.x << " " << pt2.y
+       << " c\n";
 
   px = pt3.x - pt2.x;
   py = pt2.y - pt3.y;
 
-  csAP << pt2.x + px * PWL_BEZIER << " " << pt2.y << " " << pt3.x << " "
-       << pt3.y + py * PWL_BEZIER << " " << pt3.x << " " << pt3.y << " c\n";
+  csAP << pt2.x + px * FX_BEZIER << " " << pt2.y << " " << pt3.x << " "
+       << pt3.y + py * FX_BEZIER << " " << pt3.x << " " << pt3.y << " c\n";
 
   px = pt3.x - pt4.x;
   py = pt3.y - pt4.y;
 
-  csAP << pt3.x << " " << pt3.y - py * PWL_BEZIER << " "
-       << pt4.x + px * PWL_BEZIER << " " << pt4.y << " " << pt4.x << " "
-       << pt4.y << " c\n";
+  csAP << pt3.x << " " << pt3.y - py * FX_BEZIER << " "
+       << pt4.x + px * FX_BEZIER << " " << pt4.y << " " << pt4.x << " " << pt4.y
+       << " c\n";
 
   px = pt4.x - pt1.x;
   py = pt1.y - pt4.y;
 
-  csAP << pt4.x - px * PWL_BEZIER << " " << pt4.y << " " << pt1.x << " "
-       << pt1.y - py * PWL_BEZIER << " " << pt1.x << " " << pt1.y << " c\n";
+  csAP << pt4.x - px * FX_BEZIER << " " << pt4.y << " " << pt1.x << " "
+       << pt1.y - py * FX_BEZIER << " " << pt1.x << " " << pt1.y << " c\n";
 
-  return csAP.GetByteString();
+  return csAP.MakeString();
 }
 
-CFX_ByteString CPWL_Utils::GetAP_Cross(const CPDF_Rect& crBBox) {
+CFX_ByteString CPWL_Utils::GetAP_Cross(const CFX_FloatRect& crBBox) {
   CFX_ByteTextBuf csAP;
 
   csAP << crBBox.left << " " << crBBox.top << " m\n";
@@ -234,19 +236,19 @@
   csAP << crBBox.left << " " << crBBox.bottom << " m\n";
   csAP << crBBox.right << " " << crBBox.top << " l\n";
 
-  return csAP.GetByteString();
+  return csAP.MakeString();
 }
 
-CFX_ByteString CPWL_Utils::GetAP_Diamond(const CPDF_Rect& crBBox) {
+CFX_ByteString CPWL_Utils::GetAP_Diamond(const CFX_FloatRect& crBBox) {
   CFX_ByteTextBuf csAP;
 
   FX_FLOAT fWidth = crBBox.right - crBBox.left;
   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
 
-  CPDF_Point pt1(crBBox.left, crBBox.bottom + fHeight / 2);
-  CPDF_Point pt2(crBBox.left + fWidth / 2, crBBox.top);
-  CPDF_Point pt3(crBBox.right, crBBox.bottom + fHeight / 2);
-  CPDF_Point pt4(crBBox.left + fWidth / 2, crBBox.bottom);
+  CFX_FloatPoint pt1(crBBox.left, crBBox.bottom + fHeight / 2);
+  CFX_FloatPoint pt2(crBBox.left + fWidth / 2, crBBox.top);
+  CFX_FloatPoint pt3(crBBox.right, crBBox.bottom + fHeight / 2);
+  CFX_FloatPoint pt4(crBBox.left + fWidth / 2, crBBox.bottom);
 
   csAP << pt1.x << " " << pt1.y << " m\n";
   csAP << pt2.x << " " << pt2.y << " l\n";
@@ -254,10 +256,10 @@
   csAP << pt4.x << " " << pt4.y << " l\n";
   csAP << pt1.x << " " << pt1.y << " l\n";
 
-  return csAP.GetByteString();
+  return csAP.MakeString();
 }
 
-CFX_ByteString CPWL_Utils::GetAP_Square(const CPDF_Rect& crBBox) {
+CFX_ByteString CPWL_Utils::GetAP_Square(const CFX_FloatRect& crBBox) {
   CFX_ByteTextBuf csAP;
 
   csAP << crBBox.left << " " << crBBox.top << " m\n";
@@ -266,26 +268,26 @@
   csAP << crBBox.left << " " << crBBox.bottom << " l\n";
   csAP << crBBox.left << " " << crBBox.top << " l\n";
 
-  return csAP.GetByteString();
+  return csAP.MakeString();
 }
 
-CFX_ByteString CPWL_Utils::GetAP_Star(const CPDF_Rect& crBBox) {
+CFX_ByteString CPWL_Utils::GetAP_Star(const CFX_FloatRect& crBBox) {
   CFX_ByteTextBuf csAP;
 
   FX_FLOAT fRadius =
-      (crBBox.top - crBBox.bottom) / (1 + (FX_FLOAT)cos(PWL_PI / 5.0f));
-  CPDF_Point ptCenter = CPDF_Point((crBBox.left + crBBox.right) / 2.0f,
-                                   (crBBox.top + crBBox.bottom) / 2.0f);
+      (crBBox.top - crBBox.bottom) / (1 + (FX_FLOAT)cos(FX_PI / 5.0f));
+  CFX_FloatPoint ptCenter = CFX_FloatPoint((crBBox.left + crBBox.right) / 2.0f,
+                                           (crBBox.top + crBBox.bottom) / 2.0f);
 
   FX_FLOAT px[5], py[5];
 
-  FX_FLOAT fAngel = PWL_PI / 10.0f;
+  FX_FLOAT fAngel = FX_PI / 10.0f;
 
   for (int32_t i = 0; i < 5; i++) {
     px[i] = ptCenter.x + fRadius * (FX_FLOAT)cos(fAngel);
     py[i] = ptCenter.y + fRadius * (FX_FLOAT)sin(fAngel);
 
-    fAngel += PWL_PI * 2 / 5.0f;
+    fAngel += FX_PI * 2 / 5.0f;
   }
 
   csAP << px[0] << " " << py[0] << " m\n";
@@ -298,19 +300,19 @@
     csAP << px[nNext] << " " << py[nNext] << " l\n";
   }
 
-  return csAP.GetByteString();
+  return csAP.MakeString();
 }
 
-CFX_ByteString CPWL_Utils::GetAP_HalfCircle(const CPDF_Rect& crBBox,
+CFX_ByteString CPWL_Utils::GetAP_HalfCircle(const CFX_FloatRect& crBBox,
                                             FX_FLOAT fRotate) {
   CFX_ByteTextBuf csAP;
 
   FX_FLOAT fWidth = crBBox.right - crBBox.left;
   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
 
-  CPDF_Point pt1(-fWidth / 2, 0);
-  CPDF_Point pt2(0, fHeight / 2);
-  CPDF_Point pt3(fWidth / 2, 0);
+  CFX_FloatPoint pt1(-fWidth / 2, 0);
+  CFX_FloatPoint pt2(0, fHeight / 2);
+  CFX_FloatPoint pt3(fWidth / 2, 0);
 
   FX_FLOAT px, py;
 
@@ -323,56 +325,58 @@
   px = pt2.x - pt1.x;
   py = pt2.y - pt1.y;
 
-  csAP << pt1.x << " " << pt1.y + py * PWL_BEZIER << " "
-       << pt2.x - px * PWL_BEZIER << " " << pt2.y << " " << pt2.x << " "
-       << pt2.y << " c\n";
+  csAP << pt1.x << " " << pt1.y + py * FX_BEZIER << " "
+       << pt2.x - px * FX_BEZIER << " " << pt2.y << " " << pt2.x << " " << pt2.y
+       << " c\n";
 
   px = pt3.x - pt2.x;
   py = pt2.y - pt3.y;
 
-  csAP << pt2.x + px * PWL_BEZIER << " " << pt2.y << " " << pt3.x << " "
-       << pt3.y + py * PWL_BEZIER << " " << pt3.x << " " << pt3.y << " c\n";
+  csAP << pt2.x + px * FX_BEZIER << " " << pt2.y << " " << pt3.x << " "
+       << pt3.y + py * FX_BEZIER << " " << pt3.x << " " << pt3.y << " c\n";
 
-  return csAP.GetByteString();
+  return csAP.MakeString();
 }
 
-CPDF_Rect CPWL_Utils::InflateRect(const CPDF_Rect& rcRect, FX_FLOAT fSize) {
+CFX_FloatRect CPWL_Utils::InflateRect(const CFX_FloatRect& rcRect,
+                                      FX_FLOAT fSize) {
   if (rcRect.IsEmpty())
     return rcRect;
 
-  CPDF_Rect rcNew(rcRect.left - fSize, rcRect.bottom - fSize,
-                  rcRect.right + fSize, rcRect.top + fSize);
+  CFX_FloatRect rcNew(rcRect.left - fSize, rcRect.bottom - fSize,
+                      rcRect.right + fSize, rcRect.top + fSize);
   rcNew.Normalize();
   return rcNew;
 }
 
-CPDF_Rect CPWL_Utils::DeflateRect(const CPDF_Rect& rcRect, FX_FLOAT fSize) {
+CFX_FloatRect CPWL_Utils::DeflateRect(const CFX_FloatRect& rcRect,
+                                      FX_FLOAT fSize) {
   if (rcRect.IsEmpty())
     return rcRect;
 
-  CPDF_Rect rcNew(rcRect.left + fSize, rcRect.bottom + fSize,
-                  rcRect.right - fSize, rcRect.top - fSize);
+  CFX_FloatRect rcNew(rcRect.left + fSize, rcRect.bottom + fSize,
+                      rcRect.right - fSize, rcRect.top - fSize);
   rcNew.Normalize();
   return rcNew;
 }
 
-CPDF_Rect CPWL_Utils::ScaleRect(const CPDF_Rect& rcRect, FX_FLOAT fScale) {
+CFX_FloatRect CPWL_Utils::ScaleRect(const CFX_FloatRect& rcRect,
+                                    FX_FLOAT fScale) {
   FX_FLOAT fHalfWidth = (rcRect.right - rcRect.left) / 2.0f;
   FX_FLOAT fHalfHeight = (rcRect.top - rcRect.bottom) / 2.0f;
 
-  CPDF_Point ptCenter = CPDF_Point((rcRect.left + rcRect.right) / 2,
-                                   (rcRect.top + rcRect.bottom) / 2);
+  CFX_FloatPoint ptCenter = CFX_FloatPoint((rcRect.left + rcRect.right) / 2,
+                                           (rcRect.top + rcRect.bottom) / 2);
 
-  return CPDF_Rect(
+  return CFX_FloatRect(
       ptCenter.x - fHalfWidth * fScale, ptCenter.y - fHalfHeight * fScale,
       ptCenter.x + fHalfWidth * fScale, ptCenter.y + fHalfHeight * fScale);
 }
 
-CFX_ByteString CPWL_Utils::GetRectFillAppStream(const CPDF_Rect& rect,
+CFX_ByteString CPWL_Utils::GetRectFillAppStream(const CFX_FloatRect& rect,
                                                 const CPWL_Color& color) {
   CFX_ByteTextBuf sAppStream;
-
-  CFX_ByteString sColor = GetColorAppStream(color, TRUE);
+  CFX_ByteString sColor = GetColorAppStream(color, true);
   if (sColor.GetLength() > 0) {
     sAppStream << "q\n" << sColor;
     sAppStream << rect.left << " " << rect.bottom << " "
@@ -380,22 +384,20 @@
                << " re f\nQ\n";
   }
 
-  return sAppStream.GetByteString();
+  return sAppStream.MakeString();
 }
 
-CFX_ByteString CPWL_Utils::GetCircleFillAppStream(const CPDF_Rect& rect,
+CFX_ByteString CPWL_Utils::GetCircleFillAppStream(const CFX_FloatRect& rect,
                                                   const CPWL_Color& color) {
   CFX_ByteTextBuf sAppStream;
-
-  CFX_ByteString sColor = GetColorAppStream(color, TRUE);
+  CFX_ByteString sColor = GetColorAppStream(color, true);
   if (sColor.GetLength() > 0) {
     sAppStream << "q\n" << sColor << CPWL_Utils::GetAP_Circle(rect) << "f\nQ\n";
   }
-
-  return sAppStream.GetByteString();
+  return sAppStream.MakeString();
 }
 
-CPDF_Rect CPWL_Utils::GetCenterSquare(const CPDF_Rect& rect) {
+CFX_FloatRect CPWL_Utils::GetCenterSquare(const CFX_FloatRect& rect) {
   FX_FLOAT fWidth = rect.right - rect.left;
   FX_FLOAT fHeight = rect.top - rect.bottom;
 
@@ -404,211 +406,61 @@
 
   FX_FLOAT fRadius = (fWidth > fHeight) ? fHeight / 2 : fWidth / 2;
 
-  return CPDF_Rect(fCenterX - fRadius, fCenterY - fRadius, fCenterX + fRadius,
-                   fCenterY + fRadius);
+  return CFX_FloatRect(fCenterX - fRadius, fCenterY - fRadius,
+                       fCenterX + fRadius, fCenterY + fRadius);
 }
 
-CFX_ByteString CPWL_Utils::GetEditAppStream(IFX_Edit* pEdit,
-                                            const CPDF_Point& ptOffset,
+CFX_ByteString CPWL_Utils::GetEditAppStream(CFX_Edit* pEdit,
+                                            const CFX_FloatPoint& ptOffset,
                                             const CPVT_WordRange* pRange,
-                                            FX_BOOL bContinuous,
-                                            FX_WORD SubWord) {
-  return IFX_Edit::GetEditAppearanceStream(pEdit, ptOffset, pRange, bContinuous,
+                                            bool bContinuous,
+                                            uint16_t SubWord) {
+  return CFX_Edit::GetEditAppearanceStream(pEdit, ptOffset, pRange, bContinuous,
                                            SubWord);
 }
 
-CFX_ByteString CPWL_Utils::GetEditSelAppStream(IFX_Edit* pEdit,
-                                               const CPDF_Point& ptOffset,
+CFX_ByteString CPWL_Utils::GetEditSelAppStream(CFX_Edit* pEdit,
+                                               const CFX_FloatPoint& ptOffset,
                                                const CPVT_WordRange* pRange) {
-  return IFX_Edit::GetSelectAppearanceStream(pEdit, ptOffset, pRange);
+  return CFX_Edit::GetSelectAppearanceStream(pEdit, ptOffset, pRange);
 }
 
-static CFX_ByteString GetSquigglyAppearanceStream(FX_FLOAT fStartX,
-                                                  FX_FLOAT fEndX,
-                                                  FX_FLOAT fY,
-                                                  FX_FLOAT fStep) {
-  CFX_ByteTextBuf sRet;
-
-  sRet << "0 w\n" << fStartX << " " << fY << " m\n";
-
-  FX_FLOAT fx;
-  int32_t i;
-
-  for (i = 1, fx = fStartX + fStep; fx < fEndX; fx += fStep, i++) {
-    sRet << fx << " " << fY + (i & 1) * fStep << " l\n";
-  }
-
-  sRet << "S\n";
-
-  return sRet.GetByteString();
-}
-
-static CFX_ByteString GetWordSpellCheckAppearanceStream(
-    IFX_Edit_Iterator* pIterator,
-    const CPDF_Point& ptOffset,
-    const CPVT_WordRange& wrWord) {
-  CFX_ByteTextBuf sRet;
-
-  FX_FLOAT fStartX = 0.0f;
-  FX_FLOAT fEndX = 0.0f;
-  FX_FLOAT fY = 0.0f;
-  FX_FLOAT fStep = 0.0f;
-
-  FX_BOOL bBreak = FALSE;
-
-  if (pIterator) {
-    pIterator->SetAt(wrWord.BeginPos);
-
-    do {
-      CPVT_WordPlace place = pIterator->GetAt();
-
-      CPVT_Line line;
-      if (pIterator->GetLine(line)) {
-        fY = line.ptLine.y;
-        fStep = (line.fLineAscent - line.fLineDescent) / 16.0f;
-      }
-
-      if (place.LineCmp(wrWord.BeginPos) == 0) {
-        pIterator->SetAt(wrWord.BeginPos);
-        CPVT_Word word;
-        if (pIterator->GetWord(word)) {
-          fStartX = word.ptWord.x;
-        }
-      } else {
-        fStartX = line.ptLine.x;
-      }
-
-      if (place.LineCmp(wrWord.EndPos) == 0) {
-        pIterator->SetAt(wrWord.EndPos);
-        CPVT_Word word;
-        if (pIterator->GetWord(word)) {
-          fEndX = word.ptWord.x + word.fWidth;
-        }
-
-        bBreak = TRUE;
-      } else {
-        fEndX = line.ptLine.x + line.fLineWidth;
-      }
-
-      sRet << GetSquigglyAppearanceStream(
-          fStartX + ptOffset.x, fEndX + ptOffset.x, fY + ptOffset.y, fStep);
-
-      if (bBreak)
-        break;
-    } while (pIterator->NextLine());
-  }
-
-  return sRet.GetByteString();
-}
-
-CFX_ByteString CPWL_Utils::GetSpellCheckAppStream(
-    IFX_Edit* pEdit,
-    IPWL_SpellCheck* pSpellCheck,
-    const CPDF_Point& ptOffset,
-    const CPVT_WordRange* pRange) {
-  CFX_ByteTextBuf sRet;
-
-  if (pRange && pRange->IsExist()) {
-    if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator()) {
-      pIterator->SetAt(pRange->BeginPos);
-
-      FX_BOOL bLatinWord = FALSE;
-      CPVT_WordPlace wpWordStart;
-      CFX_ByteString sWord;
-
-      CPVT_WordPlace oldplace;
-      while (pIterator->NextWord()) {
-        CPVT_WordPlace place = pIterator->GetAt();
-        if (pRange && place.WordCmp(pRange->EndPos) > 0)
-          break;
-
-        CPVT_Word word;
-        if (pIterator->GetWord(word)) {
-          if (FX_EDIT_ISLATINWORD(word.Word)) {
-            if (!bLatinWord) {
-              wpWordStart = place;
-              bLatinWord = TRUE;
-            }
-
-            sWord += (char)word.Word;
-            oldplace = place;
-          } else {
-            if (bLatinWord) {
-              if (!pSpellCheck->CheckWord(sWord)) {
-                sRet << GetWordSpellCheckAppearanceStream(
-                    pIterator, ptOffset, CPVT_WordRange(wpWordStart, oldplace));
-                pIterator->SetAt(place);
-              }
-              bLatinWord = FALSE;
-            }
-
-            sWord.Empty();
-          }
-        } else {
-          if (bLatinWord) {
-            if (!pSpellCheck->CheckWord(sWord))
-              sRet << GetWordSpellCheckAppearanceStream(
-                  pIterator, ptOffset, CPVT_WordRange(wpWordStart, oldplace));
-            bLatinWord = FALSE;
-            sWord.Empty();
-          }
-        }
-      }
-
-      if (bLatinWord) {
-        if (!pSpellCheck->CheckWord(sWord))
-          sRet << GetWordSpellCheckAppearanceStream(
-              pIterator, ptOffset, CPVT_WordRange(wpWordStart, oldplace));
-
-        bLatinWord = FALSE;
-        sWord.Empty();
-      }
-    }
-  }
-
-  return sRet.GetByteString();
-}
-
-CFX_ByteString CPWL_Utils::GetTextAppStream(const CPDF_Rect& rcBBox,
-                                            IFX_Edit_FontMap* pFontMap,
+CFX_ByteString CPWL_Utils::GetTextAppStream(const CFX_FloatRect& rcBBox,
+                                            IPVT_FontMap* pFontMap,
                                             const CFX_WideString& sText,
                                             int32_t nAlignmentH,
                                             int32_t nAlignmentV,
                                             FX_FLOAT fFontSize,
-                                            FX_BOOL bMultiLine,
-                                            FX_BOOL bAutoReturn,
+                                            bool bMultiLine,
+                                            bool bAutoReturn,
                                             const CPWL_Color& crText) {
   CFX_ByteTextBuf sRet;
 
-  if (IFX_Edit* pEdit = IFX_Edit::NewEdit()) {
-    pEdit->SetFontMap(pFontMap);
-    pEdit->SetPlateRect(rcBBox);
-    pEdit->SetAlignmentH(nAlignmentH);
-    pEdit->SetAlignmentV(nAlignmentV);
-    pEdit->SetMultiLine(bMultiLine);
-    pEdit->SetAutoReturn(bAutoReturn);
-    if (IsFloatZero(fFontSize))
-      pEdit->SetAutoFontSize(TRUE);
-    else
-      pEdit->SetFontSize(fFontSize);
+  std::unique_ptr<CFX_Edit> pEdit(new CFX_Edit);
+  pEdit->SetFontMap(pFontMap);
+  pEdit->SetPlateRect(rcBBox);
+  pEdit->SetAlignmentH(nAlignmentH, true);
+  pEdit->SetAlignmentV(nAlignmentV, true);
+  pEdit->SetMultiLine(bMultiLine, true);
+  pEdit->SetAutoReturn(bAutoReturn, true);
+  if (IsFloatZero(fFontSize))
+    pEdit->SetAutoFontSize(true, true);
+  else
+    pEdit->SetFontSize(fFontSize);
 
-    pEdit->Initialize();
-    pEdit->SetText(sText.c_str());
+  pEdit->Initialize();
+  pEdit->SetText(sText);
 
-    CFX_ByteString sEdit =
-        CPWL_Utils::GetEditAppStream(pEdit, CPDF_Point(0.0f, 0.0f));
-    if (sEdit.GetLength() > 0) {
-      sRet << "BT\n" << CPWL_Utils::GetColorAppStream(crText) << sEdit
-           << "ET\n";
-    }
-    IFX_Edit::DelEdit(pEdit);
-  }
+  CFX_ByteString sEdit =
+      CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_FloatPoint(0.0f, 0.0f));
+  if (sEdit.GetLength() > 0)
+    sRet << "BT\n" << CPWL_Utils::GetColorAppStream(crText) << sEdit << "ET\n";
 
-  return sRet.GetByteString();
+  return sRet.MakeString();
 }
 
-CFX_ByteString CPWL_Utils::GetPushButtonAppStream(const CPDF_Rect& rcBBox,
-                                                  IFX_Edit_FontMap* pFontMap,
+CFX_ByteString CPWL_Utils::GetPushButtonAppStream(const CFX_FloatRect& rcBBox,
+                                                  IPVT_FontMap* pFontMap,
                                                   CPDF_Stream* pIconStream,
                                                   CPDF_IconFit& IconFit,
                                                   const CFX_WideString& sLabel,
@@ -617,225 +469,220 @@
                                                   int32_t nLayOut) {
   const FX_FLOAT fAutoFontScale = 1.0f / 3.0f;
 
-  if (IFX_Edit* pEdit = IFX_Edit::NewEdit()) {
-    pEdit->SetFontMap(pFontMap);
-    pEdit->SetAlignmentH(1);
-    pEdit->SetAlignmentV(1);
-    pEdit->SetMultiLine(FALSE);
-    pEdit->SetAutoReturn(FALSE);
-    if (IsFloatZero(fFontSize))
-      pEdit->SetAutoFontSize(TRUE);
-    else
-      pEdit->SetFontSize(fFontSize);
+  std::unique_ptr<CFX_Edit> pEdit(new CFX_Edit);
+  pEdit->SetFontMap(pFontMap);
+  pEdit->SetAlignmentH(1, true);
+  pEdit->SetAlignmentV(1, true);
+  pEdit->SetMultiLine(false, true);
+  pEdit->SetAutoReturn(false, true);
+  if (IsFloatZero(fFontSize))
+    pEdit->SetAutoFontSize(true, true);
+  else
+    pEdit->SetFontSize(fFontSize);
 
-    pEdit->Initialize();
-    pEdit->SetText(sLabel.c_str());
+  pEdit->Initialize();
+  pEdit->SetText(sLabel);
 
-    CPDF_Rect rcLabelContent = pEdit->GetContentRect();
-    CPWL_Icon Icon;
-    PWL_CREATEPARAM cp;
-    cp.dwFlags = PWS_VISIBLE;
-    Icon.Create(cp);
-    Icon.SetIconFit(&IconFit);
-    Icon.SetPDFStream(pIconStream);
+  CFX_FloatRect rcLabelContent = pEdit->GetContentRect();
+  CPWL_Icon Icon;
+  PWL_CREATEPARAM cp;
+  cp.dwFlags = PWS_VISIBLE;
+  Icon.Create(cp);
+  Icon.SetIconFit(&IconFit);
+  Icon.SetPDFStream(pIconStream);
 
-    CPDF_Rect rcLabel = CPDF_Rect(0, 0, 0, 0);
-    CPDF_Rect rcIcon = CPDF_Rect(0, 0, 0, 0);
-    FX_FLOAT fWidth = 0.0f;
-    FX_FLOAT fHeight = 0.0f;
+  CFX_FloatRect rcLabel = CFX_FloatRect(0, 0, 0, 0);
+  CFX_FloatRect rcIcon = CFX_FloatRect(0, 0, 0, 0);
+  FX_FLOAT fWidth = 0.0f;
+  FX_FLOAT fHeight = 0.0f;
 
-    switch (nLayOut) {
-      case PPBL_LABEL:
-        rcLabel = rcBBox;
-        rcIcon = CPDF_Rect(0, 0, 0, 0);
-        break;
-      case PPBL_ICON:
-        rcIcon = rcBBox;
-        rcLabel = CPDF_Rect(0, 0, 0, 0);
-        break;
-      case PPBL_ICONTOPLABELBOTTOM:
+  switch (nLayOut) {
+    case PPBL_LABEL:
+      rcLabel = rcBBox;
+      rcIcon = CFX_FloatRect(0, 0, 0, 0);
+      break;
+    case PPBL_ICON:
+      rcIcon = rcBBox;
+      rcLabel = CFX_FloatRect(0, 0, 0, 0);
+      break;
+    case PPBL_ICONTOPLABELBOTTOM:
 
-        if (pIconStream) {
-          if (IsFloatZero(fFontSize)) {
-            fHeight = rcBBox.top - rcBBox.bottom;
-            rcLabel = CPDF_Rect(rcBBox.left, rcBBox.bottom, rcBBox.right,
-                                rcBBox.bottom + fHeight * fAutoFontScale);
-            rcIcon =
-                CPDF_Rect(rcBBox.left, rcLabel.top, rcBBox.right, rcBBox.top);
-          } else {
-            fHeight = rcLabelContent.Height();
-
-            if (rcBBox.bottom + fHeight > rcBBox.top) {
-              rcIcon = CPDF_Rect(0, 0, 0, 0);
-              rcLabel = rcBBox;
-            } else {
-              rcLabel = CPDF_Rect(rcBBox.left, rcBBox.bottom, rcBBox.right,
-                                  rcBBox.bottom + fHeight);
-              rcIcon =
-                  CPDF_Rect(rcBBox.left, rcLabel.top, rcBBox.right, rcBBox.top);
-            }
-          }
+      if (pIconStream) {
+        if (IsFloatZero(fFontSize)) {
+          fHeight = rcBBox.top - rcBBox.bottom;
+          rcLabel = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcBBox.right,
+                                  rcBBox.bottom + fHeight * fAutoFontScale);
+          rcIcon =
+              CFX_FloatRect(rcBBox.left, rcLabel.top, rcBBox.right, rcBBox.top);
         } else {
-          rcLabel = rcBBox;
-          rcIcon = CPDF_Rect(0, 0, 0, 0);
-        }
+          fHeight = rcLabelContent.Height();
 
-        break;
-      case PPBL_LABELTOPICONBOTTOM:
-
-        if (pIconStream) {
-          if (IsFloatZero(fFontSize)) {
-            fHeight = rcBBox.top - rcBBox.bottom;
-            rcLabel =
-                CPDF_Rect(rcBBox.left, rcBBox.top - fHeight * fAutoFontScale,
-                          rcBBox.right, rcBBox.top);
-            rcIcon = CPDF_Rect(rcBBox.left, rcBBox.bottom, rcBBox.right,
-                               rcLabel.bottom);
+          if (rcBBox.bottom + fHeight > rcBBox.top) {
+            rcIcon = CFX_FloatRect(0, 0, 0, 0);
+            rcLabel = rcBBox;
           } else {
-            fHeight = rcLabelContent.Height();
-
-            if (rcBBox.bottom + fHeight > rcBBox.top) {
-              rcIcon = CPDF_Rect(0, 0, 0, 0);
-              rcLabel = rcBBox;
-            } else {
-              rcLabel = CPDF_Rect(rcBBox.left, rcBBox.top - fHeight,
-                                  rcBBox.right, rcBBox.top);
-              rcIcon = CPDF_Rect(rcBBox.left, rcBBox.bottom, rcBBox.right,
-                                 rcLabel.bottom);
-            }
-          }
-        } else {
-          rcLabel = rcBBox;
-          rcIcon = CPDF_Rect(0, 0, 0, 0);
-        }
-
-        break;
-      case PPBL_ICONLEFTLABELRIGHT:
-
-        if (pIconStream) {
-          if (IsFloatZero(fFontSize)) {
-            fWidth = rcBBox.right - rcBBox.left;
-            rcLabel = CPDF_Rect(rcBBox.right - fWidth * fAutoFontScale,
-                                rcBBox.bottom, rcBBox.right, rcBBox.top);
-            rcIcon =
-                CPDF_Rect(rcBBox.left, rcBBox.bottom, rcLabel.left, rcBBox.top);
-
-            if (rcLabelContent.Width() < fWidth * fAutoFontScale) {
-            } else {
-              if (rcLabelContent.Width() < fWidth) {
-                rcLabel = CPDF_Rect(rcBBox.right - rcLabelContent.Width(),
-                                    rcBBox.bottom, rcBBox.right, rcBBox.top);
-                rcIcon = CPDF_Rect(rcBBox.left, rcBBox.bottom, rcLabel.left,
+            rcLabel = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcBBox.right,
+                                    rcBBox.bottom + fHeight);
+            rcIcon = CFX_FloatRect(rcBBox.left, rcLabel.top, rcBBox.right,
                                    rcBBox.top);
-              } else {
-                rcLabel = rcBBox;
-                rcIcon = CPDF_Rect(0, 0, 0, 0);
-              }
-            }
-          } else {
-            fWidth = rcLabelContent.Width();
-
-            if (rcBBox.left + fWidth > rcBBox.right) {
-              rcLabel = rcBBox;
-              rcIcon = CPDF_Rect(0, 0, 0, 0);
-            } else {
-              rcLabel = CPDF_Rect(rcBBox.right - fWidth, rcBBox.bottom,
-                                  rcBBox.right, rcBBox.top);
-              rcIcon = CPDF_Rect(rcBBox.left, rcBBox.bottom, rcLabel.left,
-                                 rcBBox.top);
-            }
           }
-        } else {
-          rcLabel = rcBBox;
-          rcIcon = CPDF_Rect(0, 0, 0, 0);
         }
-
-        break;
-      case PPBL_LABELLEFTICONRIGHT:
-
-        if (pIconStream) {
-          if (IsFloatZero(fFontSize)) {
-            fWidth = rcBBox.right - rcBBox.left;
-            rcLabel =
-                CPDF_Rect(rcBBox.left, rcBBox.bottom,
-                          rcBBox.left + fWidth * fAutoFontScale, rcBBox.top);
-            rcIcon = CPDF_Rect(rcLabel.right, rcBBox.bottom, rcBBox.right,
-                               rcBBox.top);
-
-            if (rcLabelContent.Width() < fWidth * fAutoFontScale) {
-            } else {
-              if (rcLabelContent.Width() < fWidth) {
-                rcLabel =
-                    CPDF_Rect(rcBBox.left, rcBBox.bottom,
-                              rcBBox.left + rcLabelContent.Width(), rcBBox.top);
-                rcIcon = CPDF_Rect(rcLabel.right, rcBBox.bottom, rcBBox.right,
-                                   rcBBox.top);
-              } else {
-                rcLabel = rcBBox;
-                rcIcon = CPDF_Rect(0, 0, 0, 0);
-              }
-            }
-          } else {
-            fWidth = rcLabelContent.Width();
-
-            if (rcBBox.left + fWidth > rcBBox.right) {
-              rcLabel = rcBBox;
-              rcIcon = CPDF_Rect(0, 0, 0, 0);
-            } else {
-              rcLabel = CPDF_Rect(rcBBox.left, rcBBox.bottom,
-                                  rcBBox.left + fWidth, rcBBox.top);
-              rcIcon = CPDF_Rect(rcLabel.right, rcBBox.bottom, rcBBox.right,
-                                 rcBBox.top);
-            }
-          }
-        } else {
-          rcLabel = rcBBox;
-          rcIcon = CPDF_Rect(0, 0, 0, 0);
-        }
-
-        break;
-      case PPBL_LABELOVERICON:
+      } else {
         rcLabel = rcBBox;
-        rcIcon = rcBBox;
-        break;
-    }
-
-    CFX_ByteTextBuf sAppStream, sTemp;
-
-    if (!rcIcon.IsEmpty()) {
-      Icon.Move(rcIcon, FALSE, FALSE);
-      sTemp << Icon.GetImageAppStream();
-    }
-
-    Icon.Destroy();
-
-    if (!rcLabel.IsEmpty()) {
-      pEdit->SetPlateRect(rcLabel);
-      CFX_ByteString sEdit =
-          CPWL_Utils::GetEditAppStream(pEdit, CPDF_Point(0.0f, 0.0f));
-      if (sEdit.GetLength() > 0) {
-        sTemp << "BT\n" << CPWL_Utils::GetColorAppStream(crText) << sEdit
-              << "ET\n";
+        rcIcon = CFX_FloatRect(0, 0, 0, 0);
       }
-    }
 
-    IFX_Edit::DelEdit(pEdit);
+      break;
+    case PPBL_LABELTOPICONBOTTOM:
 
-    if (sTemp.GetSize() > 0) {
-      sAppStream << "q\n" << rcBBox.left << " " << rcBBox.bottom << " "
-                 << rcBBox.right - rcBBox.left << " "
-                 << rcBBox.top - rcBBox.bottom << " re W n\n";
-      sAppStream << sTemp << "Q\n";
-    }
+      if (pIconStream) {
+        if (IsFloatZero(fFontSize)) {
+          fHeight = rcBBox.top - rcBBox.bottom;
+          rcLabel =
+              CFX_FloatRect(rcBBox.left, rcBBox.top - fHeight * fAutoFontScale,
+                            rcBBox.right, rcBBox.top);
+          rcIcon = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcBBox.right,
+                                 rcLabel.bottom);
+        } else {
+          fHeight = rcLabelContent.Height();
 
-    return sAppStream.GetByteString();
+          if (rcBBox.bottom + fHeight > rcBBox.top) {
+            rcIcon = CFX_FloatRect(0, 0, 0, 0);
+            rcLabel = rcBBox;
+          } else {
+            rcLabel = CFX_FloatRect(rcBBox.left, rcBBox.top - fHeight,
+                                    rcBBox.right, rcBBox.top);
+            rcIcon = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcBBox.right,
+                                   rcLabel.bottom);
+          }
+        }
+      } else {
+        rcLabel = rcBBox;
+        rcIcon = CFX_FloatRect(0, 0, 0, 0);
+      }
+
+      break;
+    case PPBL_ICONLEFTLABELRIGHT:
+
+      if (pIconStream) {
+        if (IsFloatZero(fFontSize)) {
+          fWidth = rcBBox.right - rcBBox.left;
+          rcLabel = CFX_FloatRect(rcBBox.right - fWidth * fAutoFontScale,
+                                  rcBBox.bottom, rcBBox.right, rcBBox.top);
+          rcIcon = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcLabel.left,
+                                 rcBBox.top);
+
+          if (rcLabelContent.Width() < fWidth * fAutoFontScale) {
+          } else {
+            if (rcLabelContent.Width() < fWidth) {
+              rcLabel = CFX_FloatRect(rcBBox.right - rcLabelContent.Width(),
+                                      rcBBox.bottom, rcBBox.right, rcBBox.top);
+              rcIcon = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcLabel.left,
+                                     rcBBox.top);
+            } else {
+              rcLabel = rcBBox;
+              rcIcon = CFX_FloatRect(0, 0, 0, 0);
+            }
+          }
+        } else {
+          fWidth = rcLabelContent.Width();
+
+          if (rcBBox.left + fWidth > rcBBox.right) {
+            rcLabel = rcBBox;
+            rcIcon = CFX_FloatRect(0, 0, 0, 0);
+          } else {
+            rcLabel = CFX_FloatRect(rcBBox.right - fWidth, rcBBox.bottom,
+                                    rcBBox.right, rcBBox.top);
+            rcIcon = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcLabel.left,
+                                   rcBBox.top);
+          }
+        }
+      } else {
+        rcLabel = rcBBox;
+        rcIcon = CFX_FloatRect(0, 0, 0, 0);
+      }
+
+      break;
+    case PPBL_LABELLEFTICONRIGHT:
+
+      if (pIconStream) {
+        if (IsFloatZero(fFontSize)) {
+          fWidth = rcBBox.right - rcBBox.left;
+          rcLabel =
+              CFX_FloatRect(rcBBox.left, rcBBox.bottom,
+                            rcBBox.left + fWidth * fAutoFontScale, rcBBox.top);
+          rcIcon = CFX_FloatRect(rcLabel.right, rcBBox.bottom, rcBBox.right,
+                                 rcBBox.top);
+
+          if (rcLabelContent.Width() < fWidth * fAutoFontScale) {
+          } else {
+            if (rcLabelContent.Width() < fWidth) {
+              rcLabel = CFX_FloatRect(rcBBox.left, rcBBox.bottom,
+                                      rcBBox.left + rcLabelContent.Width(),
+                                      rcBBox.top);
+              rcIcon = CFX_FloatRect(rcLabel.right, rcBBox.bottom, rcBBox.right,
+                                     rcBBox.top);
+            } else {
+              rcLabel = rcBBox;
+              rcIcon = CFX_FloatRect(0, 0, 0, 0);
+            }
+          }
+        } else {
+          fWidth = rcLabelContent.Width();
+
+          if (rcBBox.left + fWidth > rcBBox.right) {
+            rcLabel = rcBBox;
+            rcIcon = CFX_FloatRect(0, 0, 0, 0);
+          } else {
+            rcLabel = CFX_FloatRect(rcBBox.left, rcBBox.bottom,
+                                    rcBBox.left + fWidth, rcBBox.top);
+            rcIcon = CFX_FloatRect(rcLabel.right, rcBBox.bottom, rcBBox.right,
+                                   rcBBox.top);
+          }
+        }
+      } else {
+        rcLabel = rcBBox;
+        rcIcon = CFX_FloatRect(0, 0, 0, 0);
+      }
+
+      break;
+    case PPBL_LABELOVERICON:
+      rcLabel = rcBBox;
+      rcIcon = rcBBox;
+      break;
   }
 
-  return "";
+  CFX_ByteTextBuf sAppStream, sTemp;
+
+  if (!rcIcon.IsEmpty()) {
+    Icon.Move(rcIcon, false, false);
+    sTemp << Icon.GetImageAppStream();
+  }
+
+  Icon.Destroy();
+
+  if (!rcLabel.IsEmpty()) {
+    pEdit->SetPlateRect(rcLabel);
+    CFX_ByteString sEdit =
+        CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_FloatPoint(0.0f, 0.0f));
+    if (sEdit.GetLength() > 0) {
+      sTemp << "BT\n"
+            << CPWL_Utils::GetColorAppStream(crText) << sEdit << "ET\n";
+    }
+  }
+
+  if (sTemp.GetSize() > 0) {
+    sAppStream << "q\n"
+               << rcBBox.left << " " << rcBBox.bottom << " "
+               << rcBBox.right - rcBBox.left << " "
+               << rcBBox.top - rcBBox.bottom << " re W n\n";
+    sAppStream << sTemp << "Q\n";
+  }
+  return sAppStream.MakeString();
 }
 
 CFX_ByteString CPWL_Utils::GetColorAppStream(const CPWL_Color& color,
-                                             const FX_BOOL& bFillOrStroke) {
+                                             const bool& bFillOrStroke) {
   CFX_ByteTextBuf sColorStream;
 
   switch (color.nColorType) {
@@ -855,15 +702,15 @@
       break;
   }
 
-  return sColorStream.GetByteString();
+  return sColorStream.MakeString();
 }
 
-CFX_ByteString CPWL_Utils::GetBorderAppStream(const CPDF_Rect& rect,
+CFX_ByteString CPWL_Utils::GetBorderAppStream(const CFX_FloatRect& rect,
                                               FX_FLOAT fWidth,
                                               const CPWL_Color& color,
                                               const CPWL_Color& crLeftTop,
                                               const CPWL_Color& crRightBottom,
-                                              int32_t nStyle,
+                                              BorderStyle nStyle,
                                               const CPWL_Dash& dash) {
   CFX_ByteTextBuf sAppStream;
   CFX_ByteString sColor;
@@ -880,8 +727,8 @@
 
     switch (nStyle) {
       default:
-      case PBS_SOLID:
-        sColor = CPWL_Utils::GetColorAppStream(color, TRUE);
+      case BorderStyle::SOLID:
+        sColor = CPWL_Utils::GetColorAppStream(color, true);
         if (sColor.GetLength() > 0) {
           sAppStream << sColor;
           sAppStream << fLeft << " " << fBottom << " " << fRight - fLeft << " "
@@ -892,8 +739,8 @@
           sAppStream << "f*\n";
         }
         break;
-      case PBS_DASH:
-        sColor = CPWL_Utils::GetColorAppStream(color, FALSE);
+      case BorderStyle::DASH:
+        sColor = CPWL_Utils::GetColorAppStream(color, false);
         if (sColor.GetLength() > 0) {
           sAppStream << sColor;
           sAppStream << fWidth << " w"
@@ -911,9 +758,9 @@
                      << " l S\n";
         }
         break;
-      case PBS_BEVELED:
-      case PBS_INSET:
-        sColor = CPWL_Utils::GetColorAppStream(crLeftTop, TRUE);
+      case BorderStyle::BEVELED:
+      case BorderStyle::INSET:
+        sColor = CPWL_Utils::GetColorAppStream(crLeftTop, true);
         if (sColor.GetLength() > 0) {
           sAppStream << sColor;
           sAppStream << fLeft + fHalfWidth << " " << fBottom + fHalfWidth
@@ -930,7 +777,7 @@
                      << fBottom + fHalfWidth * 2 << " l f\n";
         }
 
-        sColor = CPWL_Utils::GetColorAppStream(crRightBottom, TRUE);
+        sColor = CPWL_Utils::GetColorAppStream(crRightBottom, true);
         if (sColor.GetLength() > 0) {
           sAppStream << sColor;
           sAppStream << fRight - fHalfWidth << " " << fTop - fHalfWidth
@@ -947,7 +794,7 @@
                      << " l f\n";
         }
 
-        sColor = CPWL_Utils::GetColorAppStream(color, TRUE);
+        sColor = CPWL_Utils::GetColorAppStream(color, true);
         if (sColor.GetLength() > 0) {
           sAppStream << sColor;
           sAppStream << fLeft << " " << fBottom << " " << fRight - fLeft << " "
@@ -957,8 +804,8 @@
                      << fTop - fBottom - fHalfWidth * 2 << " re f*\n";
         }
         break;
-      case PBS_UNDERLINED:
-        sColor = CPWL_Utils::GetColorAppStream(color, FALSE);
+      case BorderStyle::UNDERLINE:
+        sColor = CPWL_Utils::GetColorAppStream(color, false);
         if (sColor.GetLength() > 0) {
           sAppStream << sColor;
           sAppStream << fWidth << " w\n";
@@ -971,16 +818,16 @@
     sAppStream << "Q\n";
   }
 
-  return sAppStream.GetByteString();
+  return sAppStream.MakeString();
 }
 
 CFX_ByteString CPWL_Utils::GetCircleBorderAppStream(
-    const CPDF_Rect& rect,
+    const CFX_FloatRect& rect,
     FX_FLOAT fWidth,
     const CPWL_Color& color,
     const CPWL_Color& crLeftTop,
     const CPWL_Color& crRightBottom,
-    int32_t nStyle,
+    BorderStyle nStyle,
     const CPWL_Dash& dash) {
   CFX_ByteTextBuf sAppStream;
   CFX_ByteString sColor;
@@ -990,9 +837,9 @@
 
     switch (nStyle) {
       default:
-      case PBS_SOLID:
-      case PBS_UNDERLINED: {
-        sColor = CPWL_Utils::GetColorAppStream(color, FALSE);
+      case BorderStyle::SOLID:
+      case BorderStyle::UNDERLINE: {
+        sColor = CPWL_Utils::GetColorAppStream(color, false);
         if (sColor.GetLength() > 0) {
           sAppStream << "q\n" << fWidth << " w\n" << sColor
                      << CPWL_Utils::GetAP_Circle(
@@ -1000,8 +847,8 @@
                      << " S\nQ\n";
         }
       } break;
-      case PBS_DASH: {
-        sColor = CPWL_Utils::GetColorAppStream(color, FALSE);
+      case BorderStyle::DASH: {
+        sColor = CPWL_Utils::GetColorAppStream(color, false);
         if (sColor.GetLength() > 0) {
           sAppStream << "q\n" << fWidth << " w\n"
                      << "[" << dash.nDash << " " << dash.nGap << "] "
@@ -1011,57 +858,57 @@
                      << " S\nQ\n";
         }
       } break;
-      case PBS_BEVELED: {
+      case BorderStyle::BEVELED: {
         FX_FLOAT fHalfWidth = fWidth / 2.0f;
 
-        sColor = CPWL_Utils::GetColorAppStream(color, FALSE);
+        sColor = CPWL_Utils::GetColorAppStream(color, false);
         if (sColor.GetLength() > 0) {
           sAppStream << "q\n" << fHalfWidth << " w\n" << sColor
                      << CPWL_Utils::GetAP_Circle(rect) << " S\nQ\n";
         }
 
-        sColor = CPWL_Utils::GetColorAppStream(crLeftTop, FALSE);
+        sColor = CPWL_Utils::GetColorAppStream(crLeftTop, false);
         if (sColor.GetLength() > 0) {
           sAppStream << "q\n" << fHalfWidth << " w\n" << sColor
                      << CPWL_Utils::GetAP_HalfCircle(
                             CPWL_Utils::DeflateRect(rect, fHalfWidth * 0.75f),
-                            PWL_PI / 4.0f)
+                            FX_PI / 4.0f)
                      << " S\nQ\n";
         }
 
-        sColor = CPWL_Utils::GetColorAppStream(crRightBottom, FALSE);
+        sColor = CPWL_Utils::GetColorAppStream(crRightBottom, false);
         if (sColor.GetLength() > 0) {
           sAppStream << "q\n" << fHalfWidth << " w\n" << sColor
                      << CPWL_Utils::GetAP_HalfCircle(
                             CPWL_Utils::DeflateRect(rect, fHalfWidth * 0.75f),
-                            PWL_PI * 5 / 4.0f)
+                            FX_PI * 5 / 4.0f)
                      << " S\nQ\n";
         }
       } break;
-      case PBS_INSET: {
+      case BorderStyle::INSET: {
         FX_FLOAT fHalfWidth = fWidth / 2.0f;
 
-        sColor = CPWL_Utils::GetColorAppStream(color, FALSE);
+        sColor = CPWL_Utils::GetColorAppStream(color, false);
         if (sColor.GetLength() > 0) {
           sAppStream << "q\n" << fHalfWidth << " w\n" << sColor
                      << CPWL_Utils::GetAP_Circle(rect) << " S\nQ\n";
         }
 
-        sColor = CPWL_Utils::GetColorAppStream(crLeftTop, FALSE);
+        sColor = CPWL_Utils::GetColorAppStream(crLeftTop, false);
         if (sColor.GetLength() > 0) {
           sAppStream << "q\n" << fHalfWidth << " w\n" << sColor
                      << CPWL_Utils::GetAP_HalfCircle(
                             CPWL_Utils::DeflateRect(rect, fHalfWidth * 0.75f),
-                            PWL_PI / 4.0f)
+                            FX_PI / 4.0f)
                      << " S\nQ\n";
         }
 
-        sColor = CPWL_Utils::GetColorAppStream(crRightBottom, FALSE);
+        sColor = CPWL_Utils::GetColorAppStream(crRightBottom, false);
         if (sColor.GetLength() > 0) {
           sAppStream << "q\n" << fHalfWidth << " w\n" << sColor
                      << CPWL_Utils::GetAP_HalfCircle(
                             CPWL_Utils::DeflateRect(rect, fHalfWidth * 0.75f),
-                            PWL_PI * 5 / 4.0f)
+                            FX_PI * 5 / 4.0f)
                      << " S\nQ\n";
         }
       } break;
@@ -1070,7 +917,7 @@
     sAppStream << "Q\n";
   }
 
-  return sAppStream.GetByteString();
+  return sAppStream.MakeString();
 }
 
 CPWL_Color CPWL_Utils::SubstractColor(const CPWL_Color& sColor,
@@ -1124,58 +971,64 @@
   return sRet;
 }
 
-CFX_ByteString CPWL_Utils::GetAppStream_Check(const CPDF_Rect& rcBBox,
+CFX_ByteString CPWL_Utils::GetAppStream_Check(const CFX_FloatRect& rcBBox,
                                               const CPWL_Color& crText) {
   CFX_ByteTextBuf sAP;
-  sAP << "q\n" << CPWL_Utils::GetColorAppStream(crText, TRUE)
+  sAP << "q\n"
+      << CPWL_Utils::GetColorAppStream(crText, true)
       << CPWL_Utils::GetAP_Check(rcBBox) << "f\nQ\n";
-  return sAP.GetByteString();
+  return sAP.MakeString();
 }
 
-CFX_ByteString CPWL_Utils::GetAppStream_Circle(const CPDF_Rect& rcBBox,
+CFX_ByteString CPWL_Utils::GetAppStream_Circle(const CFX_FloatRect& rcBBox,
                                                const CPWL_Color& crText) {
   CFX_ByteTextBuf sAP;
-  sAP << "q\n" << CPWL_Utils::GetColorAppStream(crText, TRUE)
+  sAP << "q\n"
+      << CPWL_Utils::GetColorAppStream(crText, true)
       << CPWL_Utils::GetAP_Circle(rcBBox) << "f\nQ\n";
-  return sAP.GetByteString();
+  return sAP.MakeString();
 }
 
-CFX_ByteString CPWL_Utils::GetAppStream_Cross(const CPDF_Rect& rcBBox,
+CFX_ByteString CPWL_Utils::GetAppStream_Cross(const CFX_FloatRect& rcBBox,
                                               const CPWL_Color& crText) {
   CFX_ByteTextBuf sAP;
-  sAP << "q\n" << CPWL_Utils::GetColorAppStream(crText, FALSE)
+  sAP << "q\n"
+      << CPWL_Utils::GetColorAppStream(crText, false)
       << CPWL_Utils::GetAP_Cross(rcBBox) << "S\nQ\n";
-  return sAP.GetByteString();
+  return sAP.MakeString();
 }
 
-CFX_ByteString CPWL_Utils::GetAppStream_Diamond(const CPDF_Rect& rcBBox,
+CFX_ByteString CPWL_Utils::GetAppStream_Diamond(const CFX_FloatRect& rcBBox,
                                                 const CPWL_Color& crText) {
   CFX_ByteTextBuf sAP;
-  sAP << "q\n1 w\n" << CPWL_Utils::GetColorAppStream(crText, TRUE)
+  sAP << "q\n1 w\n"
+      << CPWL_Utils::GetColorAppStream(crText, true)
       << CPWL_Utils::GetAP_Diamond(rcBBox) << "f\nQ\n";
-  return sAP.GetByteString();
+  return sAP.MakeString();
 }
 
-CFX_ByteString CPWL_Utils::GetAppStream_Square(const CPDF_Rect& rcBBox,
+CFX_ByteString CPWL_Utils::GetAppStream_Square(const CFX_FloatRect& rcBBox,
                                                const CPWL_Color& crText) {
   CFX_ByteTextBuf sAP;
-  sAP << "q\n" << CPWL_Utils::GetColorAppStream(crText, TRUE)
+  sAP << "q\n"
+      << CPWL_Utils::GetColorAppStream(crText, true)
       << CPWL_Utils::GetAP_Square(rcBBox) << "f\nQ\n";
-  return sAP.GetByteString();
+  return sAP.MakeString();
 }
 
-CFX_ByteString CPWL_Utils::GetAppStream_Star(const CPDF_Rect& rcBBox,
+CFX_ByteString CPWL_Utils::GetAppStream_Star(const CFX_FloatRect& rcBBox,
                                              const CPWL_Color& crText) {
   CFX_ByteTextBuf sAP;
-  sAP << "q\n" << CPWL_Utils::GetColorAppStream(crText, TRUE)
+  sAP << "q\n"
+      << CPWL_Utils::GetColorAppStream(crText, true)
       << CPWL_Utils::GetAP_Star(rcBBox) << "f\nQ\n";
-  return sAP.GetByteString();
+  return sAP.MakeString();
 }
 
-CFX_ByteString CPWL_Utils::GetCheckBoxAppStream(const CPDF_Rect& rcBBox,
+CFX_ByteString CPWL_Utils::GetCheckBoxAppStream(const CFX_FloatRect& rcBBox,
                                                 int32_t nStyle,
                                                 const CPWL_Color& crText) {
-  CPDF_Rect rcCenter = GetCenterSquare(rcBBox);
+  CFX_FloatRect rcCenter = GetCenterSquare(rcBBox);
   switch (nStyle) {
     default:
     case PCS_CHECK:
@@ -1193,10 +1046,10 @@
   }
 }
 
-CFX_ByteString CPWL_Utils::GetRadioButtonAppStream(const CPDF_Rect& rcBBox,
+CFX_ByteString CPWL_Utils::GetRadioButtonAppStream(const CFX_FloatRect& rcBBox,
                                                    int32_t nStyle,
                                                    const CPWL_Color& crText) {
-  CPDF_Rect rcCenter = GetCenterSquare(rcBBox);
+  CFX_FloatRect rcCenter = GetCenterSquare(rcBBox);
   switch (nStyle) {
     default:
     case PCS_CHECK:
@@ -1214,28 +1067,30 @@
   }
 }
 
-CFX_ByteString CPWL_Utils::GetDropButtonAppStream(const CPDF_Rect& rcBBox) {
+CFX_ByteString CPWL_Utils::GetDropButtonAppStream(const CFX_FloatRect& rcBBox) {
   CFX_ByteTextBuf sAppStream;
 
   if (!rcBBox.IsEmpty()) {
-    sAppStream << "q\n" << CPWL_Utils::GetColorAppStream(
-                               CPWL_Color(COLORTYPE_RGB, 220.0f / 255.0f,
-                                          220.0f / 255.0f, 220.0f / 255.0f),
-                               TRUE);
+    sAppStream << "q\n"
+               << CPWL_Utils::GetColorAppStream(
+                      CPWL_Color(COLORTYPE_RGB, 220.0f / 255.0f,
+                                 220.0f / 255.0f, 220.0f / 255.0f),
+                      true);
     sAppStream << rcBBox.left << " " << rcBBox.bottom << " "
                << rcBBox.right - rcBBox.left << " "
                << rcBBox.top - rcBBox.bottom << " re f\n";
     sAppStream << "Q\n";
 
-    sAppStream << "q\n" << CPWL_Utils::GetBorderAppStream(
-                               rcBBox, 2, CPWL_Color(COLORTYPE_GRAY, 0),
-                               CPWL_Color(COLORTYPE_GRAY, 1),
-                               CPWL_Color(COLORTYPE_GRAY, 0.5), PBS_BEVELED,
-                               CPWL_Dash(3, 0, 0))
+    sAppStream << "q\n"
+               << CPWL_Utils::GetBorderAppStream(
+                      rcBBox, 2, CPWL_Color(COLORTYPE_GRAY, 0),
+                      CPWL_Color(COLORTYPE_GRAY, 1),
+                      CPWL_Color(COLORTYPE_GRAY, 0.5), BorderStyle::BEVELED,
+                      CPWL_Dash(3, 0, 0))
                << "Q\n";
 
-    CPDF_Point ptCenter = CPDF_Point((rcBBox.left + rcBBox.right) / 2,
-                                     (rcBBox.top + rcBBox.bottom) / 2);
+    CFX_FloatPoint ptCenter = CFX_FloatPoint((rcBBox.left + rcBBox.right) / 2,
+                                             (rcBBox.top + rcBBox.bottom) / 2);
     if (IsFloatBigger(rcBBox.right - rcBBox.left, 6) &&
         IsFloatBigger(rcBBox.top - rcBBox.bottom, 6)) {
       sAppStream << "q\n"
@@ -1248,7 +1103,7 @@
     }
   }
 
-  return sAppStream.GetByteString();
+  return sAppStream.MakeString();
 }
 
 void CPWL_Utils::ConvertCMYK2GRAY(FX_FLOAT dC,
@@ -1365,17 +1220,17 @@
 
 void CPWL_Utils::DrawFillRect(CFX_RenderDevice* pDevice,
                               CFX_Matrix* pUser2Device,
-                              const CPDF_Rect& rect,
+                              const CFX_FloatRect& rect,
                               const FX_COLORREF& color) {
   CFX_PathData path;
-  CPDF_Rect rcTemp(rect);
+  CFX_FloatRect rcTemp(rect);
   path.AppendRect(rcTemp.left, rcTemp.bottom, rcTemp.right, rcTemp.top);
-  pDevice->DrawPath(&path, pUser2Device, NULL, color, 0, FXFILL_WINDING);
+  pDevice->DrawPath(&path, pUser2Device, nullptr, color, 0, FXFILL_WINDING);
 }
 
 void CPWL_Utils::DrawFillArea(CFX_RenderDevice* pDevice,
                               CFX_Matrix* pUser2Device,
-                              const CPDF_Point* pPts,
+                              const CFX_FloatPoint* pPts,
                               int32_t nCount,
                               const FX_COLORREF& color) {
   CFX_PathData path;
@@ -1385,16 +1240,16 @@
   for (int32_t i = 1; i < nCount; i++)
     path.SetPoint(i, pPts[i].x, pPts[i].y, FXPT_LINETO);
 
-  pDevice->DrawPath(&path, pUser2Device, NULL, color, 0, FXFILL_ALTERNATE);
+  pDevice->DrawPath(&path, pUser2Device, nullptr, color, 0, FXFILL_ALTERNATE);
 }
 
 void CPWL_Utils::DrawStrokeRect(CFX_RenderDevice* pDevice,
                                 CFX_Matrix* pUser2Device,
-                                const CPDF_Rect& rect,
+                                const CFX_FloatRect& rect,
                                 const FX_COLORREF& color,
                                 FX_FLOAT fWidth) {
   CFX_PathData path;
-  CPDF_Rect rcTemp(rect);
+  CFX_FloatRect rcTemp(rect);
   path.AppendRect(rcTemp.left, rcTemp.bottom, rcTemp.right, rcTemp.top);
 
   CFX_GraphStateData gsd;
@@ -1405,8 +1260,8 @@
 
 void CPWL_Utils::DrawStrokeLine(CFX_RenderDevice* pDevice,
                                 CFX_Matrix* pUser2Device,
-                                const CPDF_Point& ptMoveTo,
-                                const CPDF_Point& ptLineTo,
+                                const CFX_FloatPoint& ptMoveTo,
+                                const CFX_FloatPoint& ptLineTo,
                                 const FX_COLORREF& color,
                                 FX_FLOAT fWidth) {
   CFX_PathData path;
@@ -1422,7 +1277,7 @@
 
 void CPWL_Utils::DrawFillRect(CFX_RenderDevice* pDevice,
                               CFX_Matrix* pUser2Device,
-                              const CPDF_Rect& rect,
+                              const CFX_FloatRect& rect,
                               const CPWL_Color& color,
                               int32_t nTransparancy) {
   CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rect,
@@ -1431,9 +1286,9 @@
 
 void CPWL_Utils::DrawShadow(CFX_RenderDevice* pDevice,
                             CFX_Matrix* pUser2Device,
-                            FX_BOOL bVertical,
-                            FX_BOOL bHorizontal,
-                            CPDF_Rect rect,
+                            bool bVertical,
+                            bool bHorizontal,
+                            CFX_FloatRect rect,
                             int32_t nTransparancy,
                             int32_t nStartGray,
                             int32_t nEndGray) {
@@ -1445,8 +1300,8 @@
     for (FX_FLOAT fy = rect.bottom + 0.5f; fy <= rect.top - 0.5f; fy += 1.0f) {
       int32_t nGray = nStartGray + (int32_t)(fStepGray * (fy - rect.bottom));
       CPWL_Utils::DrawStrokeLine(
-          pDevice, pUser2Device, CPDF_Point(rect.left, fy),
-          CPDF_Point(rect.right, fy),
+          pDevice, pUser2Device, CFX_FloatPoint(rect.left, fy),
+          CFX_FloatPoint(rect.right, fy),
           ArgbEncode(nTransparancy, nGray, nGray, nGray), 1.5f);
     }
   }
@@ -1457,8 +1312,8 @@
     for (FX_FLOAT fx = rect.left + 0.5f; fx <= rect.right - 0.5f; fx += 1.0f) {
       int32_t nGray = nStartGray + (int32_t)(fStepGray * (fx - rect.left));
       CPWL_Utils::DrawStrokeLine(
-          pDevice, pUser2Device, CPDF_Point(fx, rect.bottom),
-          CPDF_Point(fx, rect.top),
+          pDevice, pUser2Device, CFX_FloatPoint(fx, rect.bottom),
+          CFX_FloatPoint(fx, rect.top),
           ArgbEncode(nTransparancy, nGray, nGray, nGray), 1.5f);
     }
   }
@@ -1466,12 +1321,12 @@
 
 void CPWL_Utils::DrawBorder(CFX_RenderDevice* pDevice,
                             CFX_Matrix* pUser2Device,
-                            const CPDF_Rect& rect,
+                            const CFX_FloatRect& rect,
                             FX_FLOAT fWidth,
                             const CPWL_Color& color,
                             const CPWL_Color& crLeftTop,
                             const CPWL_Color& crRightBottom,
-                            int32_t nStyle,
+                            BorderStyle nStyle,
                             int32_t nTransparancy) {
   FX_FLOAT fLeft = rect.left;
   FX_FLOAT fRight = rect.right;
@@ -1483,16 +1338,17 @@
 
     switch (nStyle) {
       default:
-      case PBS_SOLID: {
+      case BorderStyle::SOLID: {
         CFX_PathData path;
         path.AppendRect(fLeft, fBottom, fRight, fTop);
         path.AppendRect(fLeft + fWidth, fBottom + fWidth, fRight - fWidth,
                         fTop - fWidth);
-        pDevice->DrawPath(&path, pUser2Device, NULL,
+        pDevice->DrawPath(&path, pUser2Device, nullptr,
                           PWLColorToFXColor(color, nTransparancy), 0,
                           FXFILL_ALTERNATE);
-      } break;
-      case PBS_DASH: {
+        break;
+      }
+      case BorderStyle::DASH: {
         CFX_PathData path;
 
         path.SetPointCount(5);
@@ -1517,9 +1373,10 @@
         pDevice->DrawPath(&path, pUser2Device, &gsd, 0,
                           PWLColorToFXColor(color, nTransparancy),
                           FXFILL_WINDING);
-      } break;
-      case PBS_BEVELED:
-      case PBS_INSET: {
+        break;
+      }
+      case BorderStyle::BEVELED:
+      case BorderStyle::INSET: {
         CFX_GraphStateData gsd;
         gsd.m_LineWidth = fHalfWidth;
 
@@ -1572,8 +1429,9 @@
         pDevice->DrawPath(&path, pUser2Device, &gsd,
                           PWLColorToFXColor(color, nTransparancy), 0,
                           FXFILL_ALTERNATE);
-      } break;
-      case PBS_UNDERLINED: {
+        break;
+      }
+      case BorderStyle::UNDERLINE: {
         CFX_PathData path;
 
         path.SetPointCount(2);
@@ -1586,196 +1444,16 @@
         pDevice->DrawPath(&path, pUser2Device, &gsd, 0,
                           PWLColorToFXColor(color, nTransparancy),
                           FXFILL_ALTERNATE);
-      } break;
-      case PBS_SHADOW: {
-        CFX_PathData path;
-        path.AppendRect(fLeft, fBottom, fRight, fTop);
-        path.AppendRect(fLeft + fWidth, fBottom + fWidth, fRight - fWidth,
-                        fTop - fWidth);
-        pDevice->DrawPath(&path, pUser2Device, NULL,
-                          PWLColorToFXColor(color, nTransparancy / 2), 0,
-                          FXFILL_ALTERNATE);
-      } break;
-    }
-  }
-}
-
-static void AddSquigglyPath(CFX_PathData& PathData,
-                            FX_FLOAT fStartX,
-                            FX_FLOAT fEndX,
-                            FX_FLOAT fY,
-                            FX_FLOAT fStep) {
-  PathData.AddPointCount(1);
-  PathData.SetPoint(PathData.GetPointCount() - 1, fStartX, fY, FXPT_MOVETO);
-
-  FX_FLOAT fx;
-  int32_t i;
-
-  for (i = 1, fx = fStartX + fStep; fx < fEndX; fx += fStep, i++) {
-    PathData.AddPointCount(1);
-    PathData.SetPoint(PathData.GetPointCount() - 1, fx, fY + (i & 1) * fStep,
-                      FXPT_LINETO);
-  }
-}
-
-static void AddSpellCheckObj(CFX_PathData& PathData,
-                             IFX_Edit* pEdit,
-                             const CPVT_WordRange& wrWord) {
-  FX_FLOAT fStartX = 0.0f;
-  FX_FLOAT fEndX = 0.0f;
-  FX_FLOAT fY = 0.0f;
-  FX_FLOAT fStep = 0.0f;
-
-  FX_BOOL bBreak = FALSE;
-
-  if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator()) {
-    pIterator->SetAt(wrWord.BeginPos);
-
-    do {
-      CPVT_WordPlace place = pIterator->GetAt();
-
-      CPVT_Line line;
-      if (pIterator->GetLine(line)) {
-        fY = line.ptLine.y;
-        fStep = (line.fLineAscent - line.fLineDescent) / 16.0f;
-      }
-
-      if (place.LineCmp(wrWord.BeginPos) == 0) {
-        pIterator->SetAt(wrWord.BeginPos);
-        CPVT_Word word;
-        if (pIterator->GetWord(word)) {
-          fStartX = word.ptWord.x;
-        }
-      } else {
-        fStartX = line.ptLine.x;
-      }
-
-      if (place.LineCmp(wrWord.EndPos) == 0) {
-        pIterator->SetAt(wrWord.EndPos);
-        CPVT_Word word;
-        if (pIterator->GetWord(word)) {
-          fEndX = word.ptWord.x + word.fWidth;
-        }
-
-        bBreak = TRUE;
-      } else {
-        fEndX = line.ptLine.x + line.fLineWidth;
-      }
-
-      AddSquigglyPath(PathData, fStartX, fEndX, fY, fStep);
-
-      if (bBreak)
         break;
-    } while (pIterator->NextLine());
-  }
-}
-
-void CPWL_Utils::DrawEditSpellCheck(CFX_RenderDevice* pDevice,
-                                    CFX_Matrix* pUser2Device,
-                                    IFX_Edit* pEdit,
-                                    const CPDF_Rect& rcClip,
-                                    const CPDF_Point& ptOffset,
-                                    const CPVT_WordRange* pRange,
-                                    IPWL_SpellCheck* pSpellCheck) {
-  const FX_COLORREF crSpell = ArgbEncode(255, 255, 0, 0);
-
-  // for spellcheck
-  FX_BOOL bLatinWord = FALSE;
-  CPVT_WordPlace wpWordStart;
-  CFX_ByteString sLatinWord;
-
-  CFX_PathData pathSpell;
-
-  pDevice->SaveState();
-
-  if (!rcClip.IsEmpty()) {
-    CPDF_Rect rcTemp = rcClip;
-    pUser2Device->TransformRect(rcTemp);
-    FX_RECT rcDevClip;
-    rcDevClip.left = (int32_t)rcTemp.left;
-    rcDevClip.right = (int32_t)rcTemp.right;
-    rcDevClip.top = (int32_t)rcTemp.top;
-    rcDevClip.bottom = (int32_t)rcTemp.bottom;
-    pDevice->SetClip_Rect(&rcDevClip);
-  }
-
-  if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator()) {
-    if (pEdit->GetFontMap()) {
-      if (pRange)
-        pIterator->SetAt(pRange->BeginPos);
-      else
-        pIterator->SetAt(0);
-
-      CPVT_WordPlace oldplace;
-
-      while (pIterator->NextWord()) {
-        CPVT_WordPlace place = pIterator->GetAt();
-        if (pRange && place.WordCmp(pRange->EndPos) > 0)
-          break;
-
-        CPVT_Word word;
-        if (pIterator->GetWord(word)) {
-          if (FX_EDIT_ISLATINWORD(word.Word)) {
-            if (!bLatinWord) {
-              wpWordStart = place;
-              bLatinWord = TRUE;
-            }
-
-            sLatinWord += (char)word.Word;
-          } else {
-            if (bLatinWord) {
-              if (!sLatinWord.IsEmpty()) {
-                if (pSpellCheck && !pSpellCheck->CheckWord(sLatinWord)) {
-                  AddSpellCheckObj(pathSpell, pEdit,
-                                   CPVT_WordRange(wpWordStart, oldplace));
-                  pIterator->SetAt(place);
-                }
-              }
-              bLatinWord = FALSE;
-            }
-
-            sLatinWord.Empty();
-          }
-
-          oldplace = place;
-        } else {
-          if (bLatinWord) {
-            if (!sLatinWord.IsEmpty()) {
-              if (pSpellCheck && !pSpellCheck->CheckWord(sLatinWord)) {
-                AddSpellCheckObj(pathSpell, pEdit,
-                                 CPVT_WordRange(wpWordStart, oldplace));
-                pIterator->SetAt(place);
-              }
-            }
-            bLatinWord = FALSE;
-          }
-
-          sLatinWord.Empty();
-        }
-      }
-
-      if (!sLatinWord.IsEmpty()) {
-        if (pSpellCheck && !pSpellCheck->CheckWord(sLatinWord)) {
-          AddSpellCheckObj(pathSpell, pEdit,
-                           CPVT_WordRange(wpWordStart, oldplace));
-        }
       }
     }
   }
-
-  CFX_GraphStateData gsd;
-  gsd.m_LineWidth = 0;
-  if (pathSpell.GetPointCount() > 0)
-    pDevice->DrawPath(&pathSpell, pUser2Device, &gsd, 0, crSpell,
-                      FXFILL_ALTERNATE);
-
-  pDevice->RestoreState();
 }
 
-FX_BOOL CPWL_Utils::IsBlackOrWhite(const CPWL_Color& color) {
+bool CPWL_Utils::IsBlackOrWhite(const CPWL_Color& color) {
   switch (color.nColorType) {
     case COLORTYPE_TRANSPARENT:
-      return FALSE;
+      return false;
     case COLORTYPE_GRAY:
       return color.fColor1 < 0.5f;
     case COLORTYPE_RGB:
@@ -1785,7 +1463,7 @@
              2.0f;
   }
 
-  return TRUE;
+  return true;
 }
 
 CPWL_Color CPWL_Utils::GetReverseColor(const CPWL_Color& color) {
@@ -1812,11 +1490,11 @@
 }
 
 CFX_ByteString CPWL_Utils::GetIconAppStream(int32_t nType,
-                                            const CPDF_Rect& rect,
+                                            const CFX_FloatRect& rect,
                                             const CPWL_Color& crFill,
                                             const CPWL_Color& crStroke) {
-  CFX_ByteString sAppStream = CPWL_Utils::GetColorAppStream(crStroke, FALSE);
-  sAppStream += CPWL_Utils::GetColorAppStream(crFill, TRUE);
+  CFX_ByteString sAppStream = CPWL_Utils::GetColorAppStream(crStroke, false);
+  sAppStream += CPWL_Utils::GetColorAppStream(crFill, true);
 
   CFX_ByteString sPath;
   CFX_PathData path;
@@ -1896,7 +1574,7 @@
 void CPWL_Utils::DrawIconAppStream(CFX_RenderDevice* pDevice,
                                    CFX_Matrix* pUser2Device,
                                    int32_t nType,
-                                   const CPDF_Rect& rect,
+                                   const CFX_FloatRect& rect,
                                    const CPWL_Color& crFill,
                                    const CPWL_Color& crStroke,
                                    const int32_t nTransparancy) {
@@ -1978,7 +1656,7 @@
 
 void CPWL_Utils::GetGraphics_Checkmark(CFX_ByteString& sPathData,
                                        CFX_PathData& path,
-                                       const CPDF_Rect& crBBox,
+                                       const CFX_FloatRect& crBBox,
                                        const PWL_PATH_TYPE type) {
   FX_FLOAT fWidth = crBBox.right - crBBox.left;
   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
@@ -1988,41 +1666,40 @@
                                crBBox.bottom + fHeight * 2 / 5.0f),
                     PWLPT_MOVETO),
       CPWL_PathData(
-          CPWL_Point(
-              crBBox.left + fWidth / 15.0f +
-                  PWL_BEZIER * (fWidth / 7.0f - fWidth / 15.0f),
-              crBBox.bottom + fHeight * 2 / 5.0f +
-                  PWL_BEZIER * (fHeight * 2 / 7.0f - fHeight * 2 / 5.0f)),
+          CPWL_Point(crBBox.left + fWidth / 15.0f +
+                         FX_BEZIER * (fWidth / 7.0f - fWidth / 15.0f),
+                     crBBox.bottom + fHeight * 2 / 5.0f +
+                         FX_BEZIER * (fHeight * 2 / 7.0f - fHeight * 2 / 5.0f)),
           PWLPT_BEZIERTO),
       CPWL_PathData(
           CPWL_Point(crBBox.left + fWidth / 4.5f +
-                         PWL_BEZIER * (fWidth / 5.0f - fWidth / 4.5f),
+                         FX_BEZIER * (fWidth / 5.0f - fWidth / 4.5f),
                      crBBox.bottom + fHeight / 16.0f +
-                         PWL_BEZIER * (fHeight / 5.0f - fHeight / 16.0f)),
+                         FX_BEZIER * (fHeight / 5.0f - fHeight / 16.0f)),
           PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 4.5f,
                                crBBox.bottom + fHeight / 16.0f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 4.5f +
-                                   PWL_BEZIER * (fWidth / 4.4f - fWidth / 4.5f),
+                                   FX_BEZIER * (fWidth / 4.4f - fWidth / 4.5f),
                                crBBox.bottom + fHeight / 16.0f -
-                                   PWL_BEZIER * fHeight / 16.0f),
+                                   FX_BEZIER * fHeight / 16.0f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 3.0f +
-                                   PWL_BEZIER * (fWidth / 4.0f - fWidth / 3.0f),
+                                   FX_BEZIER * (fWidth / 4.0f - fWidth / 3.0f),
                                crBBox.bottom),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 3.0f, crBBox.bottom),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 3.0f +
-                                   PWL_BEZIER * fWidth * (1 / 7.0f + 2 / 15.0f),
-                               crBBox.bottom + PWL_BEZIER * fHeight * 4 / 5.0f),
+                                   FX_BEZIER * fWidth * (1 / 7.0f + 2 / 15.0f),
+                               crBBox.bottom + FX_BEZIER * fHeight * 4 / 5.0f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 14 / 15.0f +
-                                   PWL_BEZIER * fWidth * (1 / 7.0f - 7 / 15.0f),
+                                   FX_BEZIER * fWidth * (1 / 7.0f - 7 / 15.0f),
                                crBBox.bottom + fHeight * 15 / 16.0f +
-                                   PWL_BEZIER * (fHeight * 4 / 5.0f -
-                                                 fHeight * 15 / 16.0f)),
+                                   FX_BEZIER * (fHeight * 4 / 5.0f -
+                                                fHeight * 15 / 16.0f)),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 14 / 15.0f,
                                crBBox.bottom + fHeight * 15 / 16.0f),
@@ -2030,15 +1707,15 @@
       CPWL_PathData(
           CPWL_Point(
               crBBox.left + fWidth * 14 / 15.0f +
-                  PWL_BEZIER * (fWidth * 7 / 15.0f - fWidth * 14 / 15.0f),
+                  FX_BEZIER * (fWidth * 7 / 15.0f - fWidth * 14 / 15.0f),
               crBBox.bottom + fHeight * 15 / 16.0f +
-                  PWL_BEZIER * (fHeight * 8 / 7.0f - fHeight * 15 / 16.0f)),
+                  FX_BEZIER * (fHeight * 8 / 7.0f - fHeight * 15 / 16.0f)),
           PWLPT_BEZIERTO),
       CPWL_PathData(
           CPWL_Point(crBBox.left + fWidth / 3.6f +
-                         PWL_BEZIER * (fWidth / 3.4f - fWidth / 3.6f),
+                         FX_BEZIER * (fWidth / 3.4f - fWidth / 3.6f),
                      crBBox.bottom + fHeight / 3.5f +
-                         PWL_BEZIER * (fHeight / 3.5f - fHeight / 3.5f)),
+                         FX_BEZIER * (fHeight / 3.5f - fHeight / 3.5f)),
           PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 3.6f,
                                crBBox.bottom + fHeight / 3.5f),
@@ -2046,15 +1723,14 @@
       CPWL_PathData(
           CPWL_Point(crBBox.left + fWidth / 3.6f,
                      crBBox.bottom + fHeight / 3.5f +
-                         PWL_BEZIER * (fHeight / 4.0f - fHeight / 3.5f)),
+                         FX_BEZIER * (fHeight / 4.0f - fHeight / 3.5f)),
           PWLPT_BEZIERTO),
-      CPWL_PathData(
-          CPWL_Point(
-              crBBox.left + fWidth / 15.0f +
-                  PWL_BEZIER * (fWidth / 3.5f - fWidth / 15.0f),
-              crBBox.bottom + fHeight * 2 / 5.0f +
-                  PWL_BEZIER * (fHeight * 3.5f / 5.0f - fHeight * 2 / 5.0f)),
-          PWLPT_BEZIERTO),
+      CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 15.0f +
+                                   FX_BEZIER * (fWidth / 3.5f - fWidth / 15.0f),
+                               crBBox.bottom + fHeight * 2 / 5.0f +
+                                   FX_BEZIER * (fHeight * 3.5f / 5.0f -
+                                                fHeight * 2 / 5.0f)),
+                    PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 15.0f,
                                crBBox.bottom + fHeight * 2 / 5.0f),
                     PWLPT_BEZIERTO)};
@@ -2067,7 +1743,7 @@
 
 void CPWL_Utils::GetGraphics_Circle(CFX_ByteString& sPathData,
                                     CFX_PathData& path,
-                                    const CPDF_Rect& crBBox,
+                                    const CFX_FloatRect& crBBox,
                                     const PWL_PATH_TYPE type) {
   FX_FLOAT fWidth = crBBox.right - crBBox.left;
   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
@@ -2079,25 +1755,24 @@
       CPWL_PathData(
           CPWL_Point(crBBox.left + fWidth / 15.0f,
                      crBBox.bottom + fHeight / 2.0f +
-                         PWL_BEZIER * (fHeight * 14 / 15.0f - fHeight / 2.0f)),
+                         FX_BEZIER * (fHeight * 14 / 15.0f - fHeight / 2.0f)),
           PWLPT_BEZIERTO),
-      CPWL_PathData(
-          CPWL_Point(crBBox.left + fWidth / 2.0f -
-                         PWL_BEZIER * (fWidth / 2.0f - fWidth / 15.0f),
-                     crBBox.top - fHeight / 15.0f),
-          PWLPT_BEZIERTO),
+      CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f -
+                                   FX_BEZIER * (fWidth / 2.0f - fWidth / 15.0f),
+                               crBBox.top - fHeight / 15.0f),
+                    PWLPT_BEZIERTO),
       CPWL_PathData(
           CPWL_Point(crBBox.left + fWidth / 2.0f, crBBox.top - fHeight / 15.0f),
           PWLPT_BEZIERTO),
       CPWL_PathData(
           CPWL_Point(crBBox.left + fWidth / 2.0f +
-                         PWL_BEZIER * (fWidth * 14 / 15.0f - fWidth / 2.0f),
+                         FX_BEZIER * (fWidth * 14 / 15.0f - fWidth / 2.0f),
                      crBBox.top - fHeight / 15.0f),
           PWLPT_BEZIERTO),
       CPWL_PathData(
           CPWL_Point(crBBox.right - fWidth / 15.0f,
                      crBBox.bottom + fHeight / 2.0f +
-                         PWL_BEZIER * (fHeight * 14 / 15.0f - fHeight / 2.0f)),
+                         FX_BEZIER * (fHeight * 14 / 15.0f - fHeight / 2.0f)),
           PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 15.0f,
                                crBBox.bottom + fHeight / 2.0f),
@@ -2105,25 +1780,24 @@
       CPWL_PathData(
           CPWL_Point(crBBox.right - fWidth / 15.0f,
                      crBBox.bottom + fHeight / 2.0f -
-                         PWL_BEZIER * (fHeight / 2.0f - fHeight / 15.0f)),
+                         FX_BEZIER * (fHeight / 2.0f - fHeight / 15.0f)),
           PWLPT_BEZIERTO),
       CPWL_PathData(
           CPWL_Point(crBBox.left + fWidth / 2.0f +
-                         PWL_BEZIER * (fWidth * 14 / 15.0f - fWidth / 2.0f),
+                         FX_BEZIER * (fWidth * 14 / 15.0f - fWidth / 2.0f),
                      crBBox.bottom + fHeight / 15.0f),
           PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f,
                                crBBox.bottom + fHeight / 15.0f),
                     PWLPT_BEZIERTO),
-      CPWL_PathData(
-          CPWL_Point(crBBox.left + fWidth / 2.0f -
-                         PWL_BEZIER * (fWidth / 2.0f - fWidth / 15.0f),
-                     crBBox.bottom + fHeight / 15.0f),
-          PWLPT_BEZIERTO),
+      CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f -
+                                   FX_BEZIER * (fWidth / 2.0f - fWidth / 15.0f),
+                               crBBox.bottom + fHeight / 15.0f),
+                    PWLPT_BEZIERTO),
       CPWL_PathData(
           CPWL_Point(crBBox.left + fWidth / 15.0f,
                      crBBox.bottom + fHeight / 2.0f -
-                         PWL_BEZIER * (fHeight / 2.0f - fHeight / 15.0f)),
+                         FX_BEZIER * (fHeight / 2.0f - fHeight / 15.0f)),
           PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 15.0f,
                                crBBox.bottom + fHeight / 2.0f),
@@ -2134,11 +1808,11 @@
       CPWL_PathData(
           CPWL_Point(crBBox.left + fWidth * 3 / 15.0f,
                      crBBox.bottom + fHeight / 2.0f +
-                         PWL_BEZIER * (fHeight * 4 / 5.0f - fHeight / 2.0f)),
+                         FX_BEZIER * (fHeight * 4 / 5.0f - fHeight / 2.0f)),
           PWLPT_BEZIERTO),
       CPWL_PathData(
           CPWL_Point(crBBox.left + fWidth / 2.0f -
-                         PWL_BEZIER * (fWidth / 2.0f - fWidth * 3 / 15.0f),
+                         FX_BEZIER * (fWidth / 2.0f - fWidth * 3 / 15.0f),
                      crBBox.top - fHeight * 3 / 15.0f),
           PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f,
@@ -2146,13 +1820,13 @@
                     PWLPT_BEZIERTO),
       CPWL_PathData(
           CPWL_Point(crBBox.left + fWidth / 2.0f +
-                         PWL_BEZIER * (fWidth * 4 / 5.0f - fWidth / 2.0f),
+                         FX_BEZIER * (fWidth * 4 / 5.0f - fWidth / 2.0f),
                      crBBox.top - fHeight * 3 / 15.0f),
           PWLPT_BEZIERTO),
       CPWL_PathData(
           CPWL_Point(crBBox.right - fWidth * 3 / 15.0f,
                      crBBox.bottom + fHeight / 2.0f +
-                         PWL_BEZIER * (fHeight * 4 / 5.0f - fHeight / 2.0f)),
+                         FX_BEZIER * (fHeight * 4 / 5.0f - fHeight / 2.0f)),
           PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 3 / 15.0f,
                                crBBox.bottom + fHeight / 2.0f),
@@ -2160,11 +1834,11 @@
       CPWL_PathData(
           CPWL_Point(crBBox.right - fWidth * 3 / 15.0f,
                      crBBox.bottom + fHeight / 2.0f -
-                         PWL_BEZIER * (fHeight * 4 / 5.0f - fHeight / 2.0f)),
+                         FX_BEZIER * (fHeight * 4 / 5.0f - fHeight / 2.0f)),
           PWLPT_BEZIERTO),
       CPWL_PathData(
           CPWL_Point(crBBox.left + fWidth / 2.0f +
-                         PWL_BEZIER * (fWidth * 4 / 5.0f - fWidth / 2.0f),
+                         FX_BEZIER * (fWidth * 4 / 5.0f - fWidth / 2.0f),
                      crBBox.bottom + fHeight * 3 / 15.0f),
           PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f,
@@ -2172,13 +1846,13 @@
                     PWLPT_BEZIERTO),
       CPWL_PathData(
           CPWL_Point(crBBox.left + fWidth / 2.0f -
-                         PWL_BEZIER * (fWidth * 4 / 5.0f - fWidth / 2.0f),
+                         FX_BEZIER * (fWidth * 4 / 5.0f - fWidth / 2.0f),
                      crBBox.bottom + fHeight * 3 / 15.0f),
           PWLPT_BEZIERTO),
       CPWL_PathData(
           CPWL_Point(crBBox.left + fWidth * 3 / 15.0f,
                      crBBox.bottom + fHeight / 2.0f -
-                         PWL_BEZIER * (fHeight * 4 / 5.0f - fHeight / 2.0f)),
+                         FX_BEZIER * (fHeight * 4 / 5.0f - fHeight / 2.0f)),
           PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 3 / 15.0f,
                                crBBox.bottom + fHeight / 2.0f),
@@ -2192,7 +1866,7 @@
 
 void CPWL_Utils::GetGraphics_Comment(CFX_ByteString& sPathData,
                                      CFX_PathData& path,
-                                     const CPDF_Rect& crBBox,
+                                     const CFX_FloatRect& crBBox,
                                      const PWL_PATH_TYPE type) {
   FX_FLOAT fWidth = crBBox.right - crBBox.left;
   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
@@ -2204,10 +1878,10 @@
       CPWL_PathData(
           CPWL_Point(crBBox.left + fWidth / 15.0f,
                      crBBox.top - fHeight / 6.0f +
-                         PWL_BEZIER * (fHeight / 6.0f - fHeight / 10.0f)),
+                         FX_BEZIER * (fHeight / 6.0f - fHeight / 10.0f)),
           PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 2 / 15.0f -
-                                   PWL_BEZIER * fWidth / 15.0f,
+                                   FX_BEZIER * fWidth / 15.0f,
                                crBBox.top - fHeight / 10.0f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 2 / 15.0f,
@@ -2217,13 +1891,13 @@
                                crBBox.top - fHeight / 10.0f),
                     PWLPT_LINETO),
       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 2 / 15.0f +
-                                   PWL_BEZIER * fWidth / 15.0f,
+                                   FX_BEZIER * fWidth / 15.0f,
                                crBBox.top - fHeight / 10.0f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(
           CPWL_Point(crBBox.right - fWidth / 15.0f,
                      crBBox.top - fHeight / 6 +
-                         PWL_BEZIER * (fHeight / 6.0f - fHeight / 10.0f)),
+                         FX_BEZIER * (fHeight / 6.0f - fHeight / 10.0f)),
           PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 15.0f,
                                crBBox.top - fHeight / 6.0f),
@@ -2233,10 +1907,10 @@
                     PWLPT_LINETO),
       CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 15.0f,
                                crBBox.bottom + fHeight * 4 / 15.0f +
-                                   PWL_BEZIER * fHeight / 15.0f),
+                                   FX_BEZIER * fHeight / 15.0f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 2 / 15.0f +
-                                   PWL_BEZIER * fWidth / 15.0f,
+                                   FX_BEZIER * fWidth / 15.0f,
                                crBBox.bottom + fHeight * 4 / 15.0f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 2 / 15.0f,
@@ -2247,22 +1921,22 @@
                     PWLPT_LINETO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 5 / 15.0f,
                                crBBox.bottom + fHeight * 2 / 15 +
-                                   PWL_BEZIER * fHeight * 2 / 15.0f),
+                                   FX_BEZIER * fHeight * 2 / 15.0f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 5 / 15.0f -
-                                   PWL_BEZIER * fWidth * 2 / 15.0f,
+                                   FX_BEZIER * fWidth * 2 / 15.0f,
                                crBBox.bottom + fHeight * 2 / 15.0f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 6 / 30.0f,
                                crBBox.bottom + fHeight * 2 / 15.0f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 7 / 30.0f +
-                                   PWL_BEZIER * fWidth / 30.0f,
+                                   FX_BEZIER * fWidth / 30.0f,
                                crBBox.bottom + fHeight * 2 / 15.0f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 7 / 30.0f,
                                crBBox.bottom + fHeight * 2 / 15.0f +
-                                   PWL_BEZIER * fHeight * 2 / 15.0f),
+                                   FX_BEZIER * fHeight * 2 / 15.0f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 7 / 30.0f,
                                crBBox.bottom + fHeight * 4 / 15.0f),
@@ -2271,12 +1945,12 @@
                                crBBox.bottom + fHeight * 4 / 15.0f),
                     PWLPT_LINETO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 2 / 15.0f -
-                                   PWL_BEZIER * fWidth / 15.0f,
+                                   FX_BEZIER * fWidth / 15.0f,
                                crBBox.bottom + fHeight * 4 / 15.0f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 15.0f,
                                crBBox.bottom + fHeight / 3.0f -
-                                   PWL_BEZIER * fHeight / 15.0f),
+                                   FX_BEZIER * fHeight / 15.0f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 15.0f,
                                crBBox.bottom + fHeight / 3.0f),
@@ -2311,7 +1985,7 @@
 
 void CPWL_Utils::GetGraphics_Cross(CFX_ByteString& sPathData,
                                    CFX_PathData& path,
-                                   const CPDF_Rect& crBBox,
+                                   const CFX_FloatRect& crBBox,
                                    const PWL_PATH_TYPE type) {
   FX_FLOAT fWidth = crBBox.right - crBBox.left;
   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
@@ -2368,7 +2042,7 @@
 
 void CPWL_Utils::GetGraphics_Help(CFX_ByteString& sPathData,
                                   CFX_PathData& path,
-                                  const CPDF_Rect& crBBox,
+                                  const CFX_FloatRect& crBBox,
                                   const PWL_PATH_TYPE type) {
   FX_FLOAT fWidth = crBBox.right - crBBox.left;
   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
@@ -2380,46 +2054,45 @@
       CPWL_PathData(
           CPWL_Point(crBBox.left + fWidth / 60.0f,
                      crBBox.bottom + fHeight / 2.0f +
-                         PWL_BEZIER * (fHeight / 60.0f - fHeight / 2.0f)),
+                         FX_BEZIER * (fHeight / 60.0f - fHeight / 2.0f)),
           PWLPT_BEZIERTO),
-      CPWL_PathData(
-          CPWL_Point(crBBox.left + fWidth / 2.0f -
-                         PWL_BEZIER * (fWidth / 2.0f - fWidth / 60.0f),
-                     crBBox.bottom + fHeight / 60.0f),
-          PWLPT_BEZIERTO),
+      CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f -
+                                   FX_BEZIER * (fWidth / 2.0f - fWidth / 60.0f),
+                               crBBox.bottom + fHeight / 60.0f),
+                    PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f,
                                crBBox.bottom + fHeight / 60.0f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f +
-                                   PWL_BEZIER * fWidth * 29 / 60.0f,
+                                   FX_BEZIER * fWidth * 29 / 60.0f,
                                crBBox.bottom + fHeight / 60.0f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(
           CPWL_Point(crBBox.right - fWidth / 60.0f,
                      crBBox.bottom + fHeight / 2.0f +
-                         PWL_BEZIER * (fHeight / 60.0f - fHeight / 2.0f)),
+                         FX_BEZIER * (fHeight / 60.0f - fHeight / 2.0f)),
           PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 60.0f,
                                crBBox.bottom + fHeight / 2.0f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 60.0f,
                                crBBox.bottom + fHeight / 2.0f +
-                                   PWL_BEZIER * fHeight * 29 / 60.0f),
+                                   FX_BEZIER * fHeight * 29 / 60.0f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f +
-                                   PWL_BEZIER * fWidth * 29 / 60.0f,
+                                   FX_BEZIER * fWidth * 29 / 60.0f,
                                crBBox.top - fHeight / 60.0f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(
           CPWL_Point(crBBox.left + fWidth / 2.0f, crBBox.top - fHeight / 60.0f),
           PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f -
-                                   PWL_BEZIER * fWidth * 29 / 60.0f,
+                                   FX_BEZIER * fWidth * 29 / 60.0f,
                                crBBox.top - fHeight / 60.0f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 60.0f,
                                crBBox.bottom + fHeight / 2.0f +
-                                   PWL_BEZIER * fHeight * 29 / 60.0f),
+                                   FX_BEZIER * fHeight * 29 / 60.0f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 60.0f,
                                crBBox.bottom + fHeight / 2.0f),
@@ -2429,22 +2102,22 @@
                     PWLPT_MOVETO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.27f,
                                crBBox.top - fHeight * 0.36f +
-                                   PWL_BEZIER * fHeight * 0.23f),
+                                   FX_BEZIER * fHeight * 0.23f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(
-          CPWL_Point(crBBox.left + fWidth * 0.5f - PWL_BEZIER * fWidth * 0.23f,
+          CPWL_Point(crBBox.left + fWidth * 0.5f - FX_BEZIER * fWidth * 0.23f,
                      crBBox.bottom + fHeight * 0.87f),
           PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.5f,
                                crBBox.bottom + fHeight * 0.87f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(
-          CPWL_Point(crBBox.left + fWidth * 0.5f + PWL_BEZIER * fWidth * 0.23f,
+          CPWL_Point(crBBox.left + fWidth * 0.5f + FX_BEZIER * fWidth * 0.23f,
                      crBBox.bottom + fHeight * 0.87f),
           PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.27f,
                                crBBox.top - fHeight * 0.36f +
-                                   PWL_BEZIER * fHeight * 0.23f),
+                                   FX_BEZIER * fHeight * 0.23f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.27f,
                                crBBox.top - fHeight * 0.36f),
@@ -2512,22 +2185,22 @@
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.37f,
                                crBBox.top - fHeight * 0.36f +
-                                   PWL_BEZIER * fHeight * 0.13f),
+                                   FX_BEZIER * fHeight * 0.13f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(
-          CPWL_Point(crBBox.left + fWidth * 0.5f + PWL_BEZIER * fWidth * 0.13f,
+          CPWL_Point(crBBox.left + fWidth * 0.5f + FX_BEZIER * fWidth * 0.13f,
                      crBBox.bottom + fHeight * 0.77f),
           PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.5f,
                                crBBox.bottom + fHeight * 0.77f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(
-          CPWL_Point(crBBox.left + fWidth * 0.5f - PWL_BEZIER * fWidth * 0.13f,
+          CPWL_Point(crBBox.left + fWidth * 0.5f - FX_BEZIER * fWidth * 0.13f,
                      crBBox.bottom + fHeight * 0.77f),
           PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.37f,
                                crBBox.top - fHeight * 0.36f +
-                                   PWL_BEZIER * fHeight * 0.13f),
+                                   FX_BEZIER * fHeight * 0.13f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.37f,
                                crBBox.top - fHeight * 0.36f),
@@ -2548,44 +2221,44 @@
                     PWLPT_MOVETO),
       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.56f,
                                crBBox.bottom + fHeight * 0.13f +
-                                   PWL_BEZIER * fHeight * 0.055f),
+                                   FX_BEZIER * fHeight * 0.055f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.505f -
-                                   PWL_BEZIER * fWidth * 0.095f,
+                                   FX_BEZIER * fWidth * 0.095f,
                                crBBox.bottom + fHeight * 0.185f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.505f,
                                crBBox.bottom + fHeight * 0.185f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.505f +
-                                   PWL_BEZIER * fWidth * 0.065f,
+                                   FX_BEZIER * fWidth * 0.065f,
                                crBBox.bottom + fHeight * 0.185f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.44f,
                                crBBox.bottom + fHeight * 0.13f +
-                                   PWL_BEZIER * fHeight * 0.055f),
+                                   FX_BEZIER * fHeight * 0.055f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.44f,
                                crBBox.bottom + fHeight * 0.13f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.44f,
                                crBBox.bottom + fHeight * 0.13f -
-                                   PWL_BEZIER * fHeight * 0.055f),
+                                   FX_BEZIER * fHeight * 0.055f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.505f +
-                                   PWL_BEZIER * fWidth * 0.065f,
+                                   FX_BEZIER * fWidth * 0.065f,
                                crBBox.bottom + fHeight * 0.075f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.505f,
                                crBBox.bottom + fHeight * 0.075f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.505f -
-                                   PWL_BEZIER * fWidth * 0.065f,
+                                   FX_BEZIER * fWidth * 0.065f,
                                crBBox.bottom + fHeight * 0.075f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.56f,
                                crBBox.bottom + fHeight * 0.13f -
-                                   PWL_BEZIER * fHeight * 0.055f),
+                                   FX_BEZIER * fHeight * 0.055f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.56f,
                                crBBox.bottom + fHeight * 0.13f),
@@ -2599,7 +2272,7 @@
 
 void CPWL_Utils::GetGraphics_InsertText(CFX_ByteString& sPathData,
                                         CFX_PathData& path,
-                                        const CPDF_Rect& crBBox,
+                                        const CFX_FloatRect& crBBox,
                                         const PWL_PATH_TYPE type) {
   FX_FLOAT fWidth = crBBox.right - crBBox.left;
   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
@@ -2626,7 +2299,7 @@
 
 void CPWL_Utils::GetGraphics_Key(CFX_ByteString& sPathData,
                                  CFX_PathData& path,
-                                 const CPDF_Rect& crBBox,
+                                 const CFX_FloatRect& crBBox,
                                  const PWL_PATH_TYPE type) {
   FX_FLOAT fWidth = crBBox.right - crBBox.left;
   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
@@ -2757,7 +2430,7 @@
 
 void CPWL_Utils::GetGraphics_NewParagraph(CFX_ByteString& sPathData,
                                           CFX_PathData& path,
-                                          const CPDF_Rect& crBBox,
+                                          const CFX_FloatRect& crBBox,
                                           const PWL_PATH_TYPE type) {
   FX_FLOAT fWidth = crBBox.right - crBBox.left;
   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
@@ -2861,7 +2534,7 @@
 
 void CPWL_Utils::GetGraphics_TextNote(CFX_ByteString& sPathData,
                                       CFX_PathData& path,
-                                      const CPDF_Rect& crBBox,
+                                      const CFX_FloatRect& crBBox,
                                       const PWL_PATH_TYPE type) {
   FX_FLOAT fWidth = crBBox.right - crBBox.left;
   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
@@ -2927,7 +2600,7 @@
 
 void CPWL_Utils::GetGraphics_Paragraph(CFX_ByteString& sPathData,
                                        CFX_PathData& path,
-                                       const CPDF_Rect& crBBox,
+                                       const CFX_FloatRect& crBBox,
                                        const PWL_PATH_TYPE type) {
   FX_FLOAT fWidth = crBBox.right - crBBox.left;
   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
@@ -2978,7 +2651,7 @@
 
 void CPWL_Utils::GetGraphics_RightArrow(CFX_ByteString& sPathData,
                                         CFX_PathData& path,
-                                        const CPDF_Rect& crBBox,
+                                        const CFX_FloatRect& crBBox,
                                         const PWL_PATH_TYPE type) {
   FX_FLOAT fWidth = crBBox.right - crBBox.left;
   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
@@ -3023,7 +2696,7 @@
 
 void CPWL_Utils::GetGraphics_RightPointer(CFX_ByteString& sPathData,
                                           CFX_PathData& path,
-                                          const CPDF_Rect& crBBox,
+                                          const CFX_FloatRect& crBBox,
                                           const PWL_PATH_TYPE type) {
   FX_FLOAT fWidth = crBBox.right - crBBox.left;
   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
@@ -3053,34 +2726,34 @@
 
 void CPWL_Utils::GetGraphics_Star(CFX_ByteString& sPathData,
                                   CFX_PathData& path,
-                                  const CPDF_Rect& crBBox,
+                                  const CFX_FloatRect& crBBox,
                                   const PWL_PATH_TYPE type) {
   FX_FLOAT fLongRadius =
-      (crBBox.top - crBBox.bottom) / (1 + (FX_FLOAT)cos(PWL_PI / 5.0f));
+      (crBBox.top - crBBox.bottom) / (1 + (FX_FLOAT)cos(FX_PI / 5.0f));
   fLongRadius = fLongRadius * 0.7f;
   FX_FLOAT fShortRadius = fLongRadius * 0.55f;
-  CPDF_Point ptCenter = CPDF_Point((crBBox.left + crBBox.right) / 2.0f,
-                                   (crBBox.top + crBBox.bottom) / 2.0f);
+  CFX_FloatPoint ptCenter = CFX_FloatPoint((crBBox.left + crBBox.right) / 2.0f,
+                                           (crBBox.top + crBBox.bottom) / 2.0f);
 
   FX_FLOAT px1[5], py1[5];
   FX_FLOAT px2[5], py2[5];
 
-  FX_FLOAT fAngel = PWL_PI / 10.0f;
+  FX_FLOAT fAngel = FX_PI / 10.0f;
 
   for (int32_t i = 0; i < 5; i++) {
     px1[i] = ptCenter.x + fLongRadius * (FX_FLOAT)cos(fAngel);
     py1[i] = ptCenter.y + fLongRadius * (FX_FLOAT)sin(fAngel);
 
-    fAngel += PWL_PI * 2 / 5.0f;
+    fAngel += FX_PI * 2 / 5.0f;
   }
 
-  fAngel = PWL_PI / 5.0f + PWL_PI / 10.0f;
+  fAngel = FX_PI / 5.0f + FX_PI / 10.0f;
 
   for (int32_t j = 0; j < 5; j++) {
     px2[j] = ptCenter.x + fShortRadius * (FX_FLOAT)cos(fAngel);
     py2[j] = ptCenter.y + fShortRadius * (FX_FLOAT)sin(fAngel);
 
-    fAngel += PWL_PI * 2 / 5.0f;
+    fAngel += FX_PI * 2 / 5.0f;
   }
 
   CPWL_PathData PathArray[11];
@@ -3104,7 +2777,7 @@
 
 void CPWL_Utils::GetGraphics_UpArrow(CFX_ByteString& sPathData,
                                      CFX_PathData& path,
-                                     const CPDF_Rect& crBBox,
+                                     const CFX_FloatRect& crBBox,
                                      const PWL_PATH_TYPE type) {
   FX_FLOAT fWidth = crBBox.right - crBBox.left;
   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
@@ -3143,7 +2816,7 @@
 
 void CPWL_Utils::GetGraphics_UpLeftArrow(CFX_ByteString& sPathData,
                                          CFX_PathData& path,
-                                         const CPDF_Rect& crBBox,
+                                         const CFX_FloatRect& crBBox,
                                          const PWL_PATH_TYPE type) {
   FX_FLOAT fWidth = crBBox.right - crBBox.left;
   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
@@ -3198,7 +2871,7 @@
 
 void CPWL_Utils::GetGraphics_Graph(CFX_ByteString& sPathData,
                                    CFX_PathData& path,
-                                   const CPDF_Rect& crBBox,
+                                   const CFX_FloatRect& crBBox,
                                    const PWL_PATH_TYPE type) {
   FX_FLOAT fWidth = crBBox.right - crBBox.left;
   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
@@ -3276,7 +2949,7 @@
 
 void CPWL_Utils::GetGraphics_Paperclip(CFX_ByteString& sPathData,
                                        CFX_PathData& path,
-                                       const CPDF_Rect& crBBox,
+                                       const CFX_FloatRect& crBBox,
                                        const PWL_PATH_TYPE type) {
   FX_FLOAT fWidth = crBBox.right - crBBox.left;
   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
@@ -3419,7 +3092,7 @@
 
 void CPWL_Utils::GetGraphics_Attachment(CFX_ByteString& sPathData,
                                         CFX_PathData& path,
-                                        const CPDF_Rect& crBBox,
+                                        const CFX_FloatRect& crBBox,
                                         const PWL_PATH_TYPE type) {
   FX_FLOAT fWidth = crBBox.right - crBBox.left;
   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
@@ -3515,7 +3188,7 @@
 
 void CPWL_Utils::GetGraphics_Tag(CFX_ByteString& sPathData,
                                  CFX_PathData& path,
-                                 const CPDF_Rect& crBBox,
+                                 const CFX_FloatRect& crBBox,
                                  const PWL_PATH_TYPE type) {
   FX_FLOAT fWidth = crBBox.right - crBBox.left;
   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
@@ -3566,12 +3239,12 @@
 
 void CPWL_Utils::GetGraphics_Foxit(CFX_ByteString& sPathData,
                                    CFX_PathData& path,
-                                   const CPDF_Rect& crBBox,
+                                   const CFX_FloatRect& crBBox,
                                    const PWL_PATH_TYPE type) {
   FX_FLOAT fOutWidth = crBBox.right - crBBox.left;
   FX_FLOAT fOutHeight = crBBox.top - crBBox.bottom;
 
-  CPDF_Rect crInBox = crBBox;
+  CFX_FloatRect crInBox = crBBox;
   crInBox.left = crBBox.left + fOutWidth * 0.08f;
   crInBox.right = crBBox.right - fOutWidth * 0.08f;
   crInBox.top = crBBox.top - fOutHeight * 0.08f;
@@ -3585,12 +3258,12 @@
       CPWL_PathData(CPWL_Point(crInBox.left + fWidth * 0.45f, crInBox.top),
                     PWLPT_LINETO),
       CPWL_PathData(CPWL_Point(crInBox.left + fWidth * 0.45f,
-                               crInBox.top - PWL_BEZIER * fHeight * 0.4f),
+                               crInBox.top - FX_BEZIER * fHeight * 0.4f),
                     PWLPT_BEZIERTO),
-      CPWL_PathData(CPWL_Point(crInBox.left + fWidth * 0.45f -
-                                   PWL_BEZIER * fWidth * 0.45f,
-                               crInBox.top - fHeight * 0.4f),
-                    PWLPT_BEZIERTO),
+      CPWL_PathData(
+          CPWL_Point(crInBox.left + fWidth * 0.45f - FX_BEZIER * fWidth * 0.45f,
+                     crInBox.top - fHeight * 0.4f),
+          PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crInBox.left, crInBox.top - fHeight * 0.4f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crInBox.left, crInBox.top), PWLPT_LINETO),
@@ -3600,21 +3273,21 @@
       CPWL_PathData(CPWL_Point(crInBox.left + fWidth * 0.75f, crInBox.top),
                     PWLPT_LINETO),
       CPWL_PathData(CPWL_Point(crInBox.left + fWidth * 0.75f,
-                               crInBox.top - PWL_BEZIER * fHeight * 0.7f),
+                               crInBox.top - FX_BEZIER * fHeight * 0.7f),
                     PWLPT_BEZIERTO),
-      CPWL_PathData(CPWL_Point(crInBox.left + fWidth * 0.75f -
-                                   PWL_BEZIER * fWidth * 0.75f,
-                               crInBox.top - fHeight * 0.7f),
-                    PWLPT_BEZIERTO),
+      CPWL_PathData(
+          CPWL_Point(crInBox.left + fWidth * 0.75f - FX_BEZIER * fWidth * 0.75f,
+                     crInBox.top - fHeight * 0.7f),
+          PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crInBox.left, crInBox.top - fHeight * 0.7f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crInBox.left, crInBox.top - fHeight * 0.55f),
                     PWLPT_LINETO),
-      CPWL_PathData(CPWL_Point(crInBox.left + PWL_BEZIER * fWidth * 0.60f,
+      CPWL_PathData(CPWL_Point(crInBox.left + FX_BEZIER * fWidth * 0.60f,
                                crInBox.top - fHeight * 0.55f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crInBox.left + fWidth * 0.60f,
-                               crInBox.top - PWL_BEZIER * fHeight * 0.55f),
+                               crInBox.top - FX_BEZIER * fHeight * 0.55f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crInBox.left + fWidth * 0.60f, crInBox.top),
                     PWLPT_BEZIERTO),
@@ -3622,12 +3295,12 @@
       CPWL_PathData(CPWL_Point(crInBox.left + fWidth * 0.90f, crInBox.top),
                     PWLPT_MOVETO),
       CPWL_PathData(CPWL_Point(crInBox.left + fWidth * 0.90f,
-                               crInBox.top - PWL_BEZIER * fHeight * 0.85f),
+                               crInBox.top - FX_BEZIER * fHeight * 0.85f),
                     PWLPT_BEZIERTO),
-      CPWL_PathData(CPWL_Point(crInBox.left + fWidth * 0.90f -
-                                   PWL_BEZIER * fWidth * 0.90f,
-                               crInBox.top - fHeight * 0.85f),
-                    PWLPT_BEZIERTO),
+      CPWL_PathData(
+          CPWL_Point(crInBox.left + fWidth * 0.90f - FX_BEZIER * fWidth * 0.90f,
+                     crInBox.top - fHeight * 0.85f),
+          PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crInBox.left, crInBox.top - fHeight * 0.85f),
                     PWLPT_BEZIERTO),
       CPWL_PathData(CPWL_Point(crInBox.left, crInBox.bottom), PWLPT_LINETO),
@@ -3643,12 +3316,15 @@
     GetPathDataFromArray(path, PathArray, 23);
 }
 
-void CPWL_Color::ConvertColorType(int32_t other_nColorType) {
-  switch (other_nColorType) {
+void CPWL_Color::ConvertColorType(int32_t nConvertColorType) {
+  if (nColorType == nConvertColorType)
+    return;
+
+  switch (nColorType) {
     case COLORTYPE_TRANSPARENT:
       break;
     case COLORTYPE_GRAY:
-      switch (other_nColorType) {
+      switch (nConvertColorType) {
         case COLORTYPE_RGB:
           CPWL_Utils::ConvertGRAY2RGB(fColor1, fColor1, fColor2, fColor3);
           break;
@@ -3659,7 +3335,7 @@
       }
       break;
     case COLORTYPE_RGB:
-      switch (other_nColorType) {
+      switch (nConvertColorType) {
         case COLORTYPE_GRAY:
           CPWL_Utils::ConvertRGB2GRAY(fColor1, fColor2, fColor3, fColor1);
           break;
@@ -3670,7 +3346,7 @@
       }
       break;
     case COLORTYPE_CMYK:
-      switch (other_nColorType) {
+      switch (nConvertColorType) {
         case COLORTYPE_GRAY:
           CPWL_Utils::ConvertCMYK2GRAY(fColor1, fColor2, fColor3, fColor4,
                                        fColor1);
@@ -3682,5 +3358,5 @@
       }
       break;
   }
-  nColorType = other_nColorType;
+  nColorType = nConvertColorType;
 }
diff --git a/fpdfsdk/include/pdfwindow/PWL_Utils.h b/fpdfsdk/pdfwindow/PWL_Utils.h
similarity index 67%
rename from fpdfsdk/include/pdfwindow/PWL_Utils.h
rename to fpdfsdk/pdfwindow/PWL_Utils.h
index ef87ea3..f14c3c7 100644
--- a/fpdfsdk/include/pdfwindow/PWL_Utils.h
+++ b/fpdfsdk/pdfwindow/PWL_Utils.h
@@ -4,15 +4,15 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#ifndef FPDFSDK_INCLUDE_PDFWINDOW_PWL_UTILS_H_
-#define FPDFSDK_INCLUDE_PDFWINDOW_PWL_UTILS_H_
+#ifndef FPDFSDK_PDFWINDOW_PWL_UTILS_H_
+#define FPDFSDK_PDFWINDOW_PWL_UTILS_H_
 
-#include "PWL_Wnd.h"
-#include "core/include/fpdfapi/fpdf_parser.h"  // For CPDF_Point.
-#include "core/include/fpdfdoc/fpdf_vt.h"      // For CPVT_WordRange.
-#include "fpdfsdk/include/fxedit/fx_edit.h"
+#include "core/fpdfdoc/cpvt_wordrange.h"
+#include "fpdfsdk/pdfwindow/PWL_Wnd.h"
 
+class CFX_Edit;
 class CFX_PathData;
+
 struct CPWL_Color;
 
 template <class T>
@@ -28,9 +28,9 @@
 #define PWL_WIN2PDF(color) ((FX_FLOAT)((FX_FLOAT)color / 255.0f))
 
 #define PWL_MAKEDWORD(low, high) \
-  ((FX_DWORD)((FX_WORD)(low) | (FX_DWORD)(((FX_WORD)(high)) << 16)))
-#define PWL_GETLOWWORD(dword) ((FX_WORD)(dword))
-#define PWL_GETHIGHWORD(dword) ((FX_WORD)(dword >> 16))
+  ((uint32_t)((uint16_t)(low) | (uint32_t)(((uint16_t)(high)) << 16)))
+#define PWL_GETLOWWORD(dword) ((uint16_t)(dword))
+#define PWL_GETHIGHWORD(dword) ((uint16_t)(dword >> 16))
 
 #define PWL_ICONTYPE_CHECKMARK 0
 #define PWL_ICONTYPE_CIRCLE 1
@@ -65,9 +65,6 @@
 #define PCS_SQUARE 4
 #define PCS_STAR 5
 
-#define PWL_PI 3.14159265358979f
-#define PWL_BEZIER 0.5522847498308f
-
 // pushbutton layout style
 #define PPBL_LABEL 0
 #define PPBL_ICON 1
@@ -77,11 +74,11 @@
 #define PPBL_LABELLEFTICONRIGHT 5
 #define PPBL_LABELOVERICON 6
 
-class CPWL_Point : public CPDF_Point {
+class CPWL_Point : public CFX_FloatPoint {
  public:
-  CPWL_Point() : CPDF_Point(0.0f, 0.0f) {}
-  CPWL_Point(FX_FLOAT fx, FX_FLOAT fy) : CPDF_Point(fx, fy) {}
-  CPWL_Point(const CPWL_Point& point) : CPDF_Point(point.x, point.y) {}
+  CPWL_Point() {}
+  CPWL_Point(FX_FLOAT fx, FX_FLOAT fy) : CFX_FloatPoint(fx, fy) {}
+  CPWL_Point(const CPWL_Point& point) : CFX_FloatPoint(point.x, point.y) {}
 };
 
 enum PWL_PATHDATA_TYPE {
@@ -103,144 +100,134 @@
   PWL_PATHDATA_TYPE type;
 };
 
-class IPWL_SpellCheck;
-
 class CPWL_Utils {
  public:
-  static CPDF_Rect InflateRect(const CPDF_Rect& rcRect, FX_FLOAT fSize);
-  static CPDF_Rect DeflateRect(const CPDF_Rect& rcRect, FX_FLOAT fSize);
-  static FX_BOOL IntersectRect(const CPDF_Rect& rect1, const CPDF_Rect& rect2);
-  static FX_BOOL ContainsRect(const CPDF_Rect& rcParent,
-                              const CPDF_Rect& rcChild);
-  static CPDF_Rect ScaleRect(const CPDF_Rect& rcRect, FX_FLOAT fScale);
+  static CFX_FloatRect InflateRect(const CFX_FloatRect& rcRect, FX_FLOAT fSize);
+  static CFX_FloatRect DeflateRect(const CFX_FloatRect& rcRect, FX_FLOAT fSize);
+  static bool IntersectRect(const CFX_FloatRect& rect1,
+                            const CFX_FloatRect& rect2);
+  static bool ContainsRect(const CFX_FloatRect& rcParent,
+                           const CFX_FloatRect& rcChild);
+  static CFX_FloatRect ScaleRect(const CFX_FloatRect& rcRect, FX_FLOAT fScale);
   static CPVT_WordRange OverlapWordRange(const CPVT_WordRange& wr1,
                                          const CPVT_WordRange& wr2);
-  static CPDF_Rect GetCenterSquare(const CPDF_Rect& rect);
+  static CFX_FloatRect GetCenterSquare(const CFX_FloatRect& rect);
   static CPWL_Color SubstractColor(const CPWL_Color& sColor,
                                    FX_FLOAT fColorSub);
   static CPWL_Color DevideColor(const CPWL_Color& sColor,
                                 FX_FLOAT fColorDevide);
-  static CPDF_Rect MaxRect(const CPDF_Rect& rect1, const CPDF_Rect& rect2);
-  static CPDF_Rect OffsetRect(const CPDF_Rect& rect, FX_FLOAT x, FX_FLOAT y);
-  static CPDF_Point OffsetPoint(const CPDF_Point& point,
-                                FX_FLOAT x,
-                                FX_FLOAT y);
+  static CFX_FloatRect MaxRect(const CFX_FloatRect& rect1,
+                               const CFX_FloatRect& rect2);
+  static CFX_FloatRect OffsetRect(const CFX_FloatRect& rect,
+                                  FX_FLOAT x,
+                                  FX_FLOAT y);
+  static CFX_FloatPoint OffsetPoint(const CFX_FloatPoint& point,
+                                    FX_FLOAT x,
+                                    FX_FLOAT y);
   static FX_COLORREF PWLColorToFXColor(const CPWL_Color& color,
                                        int32_t nTransparancy = 255);
-  static FX_BOOL IsBlackOrWhite(const CPWL_Color& color);
+  static bool IsBlackOrWhite(const CPWL_Color& color);
   static CPWL_Color GetReverseColor(const CPWL_Color& color);
 
   static CFX_ByteString GetColorAppStream(const CPWL_Color& color,
-                                          const FX_BOOL& bFillOrStroke = TRUE);
-  static CFX_ByteString GetBorderAppStream(const CPDF_Rect& rect,
+                                          const bool& bFillOrStroke = true);
+  static CFX_ByteString GetBorderAppStream(const CFX_FloatRect& rect,
                                            FX_FLOAT fWidth,
                                            const CPWL_Color& color,
                                            const CPWL_Color& crLeftTop,
                                            const CPWL_Color& crRightBottom,
-                                           int32_t nStyle,
+                                           BorderStyle nStyle,
                                            const CPWL_Dash& dash);
   static CFX_ByteString GetCircleBorderAppStream(
-      const CPDF_Rect& rect,
+      const CFX_FloatRect& rect,
       FX_FLOAT fWidth,
       const CPWL_Color& color,
       const CPWL_Color& crLeftTop,
       const CPWL_Color& crRightBottom,
-      int32_t nStyle,
+      BorderStyle nStyle,
       const CPWL_Dash& dash);
-  static CFX_ByteString GetRectFillAppStream(const CPDF_Rect& rect,
+  static CFX_ByteString GetRectFillAppStream(const CFX_FloatRect& rect,
                                              const CPWL_Color& color);
-  static CFX_ByteString GetCircleFillAppStream(const CPDF_Rect& rect,
+  static CFX_ByteString GetCircleFillAppStream(const CFX_FloatRect& rect,
                                                const CPWL_Color& color);
 
-  static CFX_ByteString GetPushButtonAppStream(const CPDF_Rect& rcBBox,
-                                               IFX_Edit_FontMap* pFontMap,
+  static CFX_ByteString GetPushButtonAppStream(const CFX_FloatRect& rcBBox,
+                                               IPVT_FontMap* pFontMap,
                                                CPDF_Stream* pIconStream,
                                                CPDF_IconFit& IconFit,
                                                const CFX_WideString& sLabel,
                                                const CPWL_Color& crText,
                                                FX_FLOAT fFontSize,
                                                int32_t nLayOut);
-  static CFX_ByteString GetCheckBoxAppStream(const CPDF_Rect& rcBBox,
+  static CFX_ByteString GetCheckBoxAppStream(const CFX_FloatRect& rcBBox,
                                              int32_t nStyle,
                                              const CPWL_Color& crText);
-  static CFX_ByteString GetRadioButtonAppStream(const CPDF_Rect& rcBBox,
+  static CFX_ByteString GetRadioButtonAppStream(const CFX_FloatRect& rcBBox,
                                                 int32_t nStyle,
                                                 const CPWL_Color& crText);
 
-  static CFX_ByteString GetEditAppStream(IFX_Edit* pEdit,
-                                         const CPDF_Point& ptOffset,
-                                         const CPVT_WordRange* pRange = NULL,
-                                         FX_BOOL bContinuous = TRUE,
-                                         FX_WORD SubWord = 0);
+  static CFX_ByteString GetEditAppStream(CFX_Edit* pEdit,
+                                         const CFX_FloatPoint& ptOffset,
+                                         const CPVT_WordRange* pRange = nullptr,
+                                         bool bContinuous = true,
+                                         uint16_t SubWord = 0);
   static CFX_ByteString GetEditSelAppStream(
-      IFX_Edit* pEdit,
-      const CPDF_Point& ptOffset,
-      const CPVT_WordRange* pRange = NULL);
-  static CFX_ByteString GetSpellCheckAppStream(
-      IFX_Edit* pEdit,
-      IPWL_SpellCheck* pSpellCheck,
-      const CPDF_Point& ptOffset,
-      const CPVT_WordRange* pRange = NULL);
-  static CFX_ByteString GetTextAppStream(const CPDF_Rect& rcBBox,
-                                         IFX_Edit_FontMap* pFontMap,
+      CFX_Edit* pEdit,
+      const CFX_FloatPoint& ptOffset,
+      const CPVT_WordRange* pRange = nullptr);
+  static CFX_ByteString GetTextAppStream(const CFX_FloatRect& rcBBox,
+                                         IPVT_FontMap* pFontMap,
                                          const CFX_WideString& sText,
                                          int32_t nAlignmentH,
                                          int32_t nAlignmentV,
                                          FX_FLOAT fFontSize,
-                                         FX_BOOL bMultiLine,
-                                         FX_BOOL bAutoReturn,
+                                         bool bMultiLine,
+                                         bool bAutoReturn,
                                          const CPWL_Color& crText);
-  static CFX_ByteString GetDropButtonAppStream(const CPDF_Rect& rcBBox);
+  static CFX_ByteString GetDropButtonAppStream(const CFX_FloatRect& rcBBox);
 
   static void DrawFillRect(CFX_RenderDevice* pDevice,
                            CFX_Matrix* pUser2Device,
-                           const CPDF_Rect& rect,
+                           const CFX_FloatRect& rect,
                            const CPWL_Color& color,
                            int32_t nTransparancy);
   static void DrawFillRect(CFX_RenderDevice* pDevice,
                            CFX_Matrix* pUser2Device,
-                           const CPDF_Rect& rect,
+                           const CFX_FloatRect& rect,
                            const FX_COLORREF& color);
   static void DrawStrokeRect(CFX_RenderDevice* pDevice,
                              CFX_Matrix* pUser2Device,
-                             const CPDF_Rect& rect,
+                             const CFX_FloatRect& rect,
                              const FX_COLORREF& color,
                              FX_FLOAT fWidth);
   static void DrawStrokeLine(CFX_RenderDevice* pDevice,
                              CFX_Matrix* pUser2Device,
-                             const CPDF_Point& ptMoveTo,
-                             const CPDF_Point& ptLineTo,
+                             const CFX_FloatPoint& ptMoveTo,
+                             const CFX_FloatPoint& ptLineTo,
                              const FX_COLORREF& color,
                              FX_FLOAT fWidth);
   static void DrawBorder(CFX_RenderDevice* pDevice,
                          CFX_Matrix* pUser2Device,
-                         const CPDF_Rect& rect,
+                         const CFX_FloatRect& rect,
                          FX_FLOAT fWidth,
                          const CPWL_Color& color,
                          const CPWL_Color& crLeftTop,
                          const CPWL_Color& crRightBottom,
-                         int32_t nStyle,
+                         BorderStyle nStyle,
                          int32_t nTransparancy);
   static void DrawFillArea(CFX_RenderDevice* pDevice,
                            CFX_Matrix* pUser2Device,
-                           const CPDF_Point* pPts,
+                           const CFX_FloatPoint* pPts,
                            int32_t nCount,
                            const FX_COLORREF& color);
   static void DrawShadow(CFX_RenderDevice* pDevice,
                          CFX_Matrix* pUser2Device,
-                         FX_BOOL bVertical,
-                         FX_BOOL bHorizontal,
-                         CPDF_Rect rect,
+                         bool bVertical,
+                         bool bHorizontal,
+                         CFX_FloatRect rect,
                          int32_t nTransparancy,
                          int32_t nStartGray,
                          int32_t nEndGray);
-  static void DrawEditSpellCheck(CFX_RenderDevice* pDevice,
-                                 CFX_Matrix* pUser2Device,
-                                 IFX_Edit* pEdit,
-                                 const CPDF_Rect& rcClip,
-                                 const CPDF_Point& ptOffset,
-                                 const CPVT_WordRange* pRange,
-                                 IPWL_SpellCheck* pSpellCheck);
 
  public:
   static void ConvertCMYK2RGB(FX_FLOAT dC,
@@ -287,13 +274,13 @@
  public:
   static CFX_ByteString GetIconAppStream(
       int32_t nType,
-      const CPDF_Rect& rect,
+      const CFX_FloatRect& rect,
       const CPWL_Color& crFill,
       const CPWL_Color& crStroke = PWL_DEFAULT_BLACKCOLOR);
   static void DrawIconAppStream(CFX_RenderDevice* pDevice,
                                 CFX_Matrix* pUser2Device,
                                 int32_t nType,
-                                const CPDF_Rect& rect,
+                                const CFX_FloatRect& rect,
                                 const CPWL_Color& crFill,
                                 const CPWL_Color& crStroke,
                                 const int32_t nTransparancy);
@@ -305,108 +292,108 @@
                                    const CPWL_PathData* pPathData,
                                    int32_t nCount);
 
-  static CFX_ByteString GetAppStream_Check(const CPDF_Rect& rcBBox,
+  static CFX_ByteString GetAppStream_Check(const CFX_FloatRect& rcBBox,
                                            const CPWL_Color& crText);
-  static CFX_ByteString GetAppStream_Circle(const CPDF_Rect& rcBBox,
+  static CFX_ByteString GetAppStream_Circle(const CFX_FloatRect& rcBBox,
                                             const CPWL_Color& crText);
-  static CFX_ByteString GetAppStream_Cross(const CPDF_Rect& rcBBox,
+  static CFX_ByteString GetAppStream_Cross(const CFX_FloatRect& rcBBox,
                                            const CPWL_Color& crText);
-  static CFX_ByteString GetAppStream_Diamond(const CPDF_Rect& rcBBox,
+  static CFX_ByteString GetAppStream_Diamond(const CFX_FloatRect& rcBBox,
                                              const CPWL_Color& crText);
-  static CFX_ByteString GetAppStream_Square(const CPDF_Rect& rcBBox,
+  static CFX_ByteString GetAppStream_Square(const CFX_FloatRect& rcBBox,
                                             const CPWL_Color& crText);
-  static CFX_ByteString GetAppStream_Star(const CPDF_Rect& rcBBox,
+  static CFX_ByteString GetAppStream_Star(const CFX_FloatRect& rcBBox,
                                           const CPWL_Color& crText);
 
-  static CFX_ByteString GetAP_Check(const CPDF_Rect& crBBox);
-  static CFX_ByteString GetAP_Circle(const CPDF_Rect& crBBox);
-  static CFX_ByteString GetAP_Cross(const CPDF_Rect& crBBox);
-  static CFX_ByteString GetAP_Diamond(const CPDF_Rect& crBBox);
-  static CFX_ByteString GetAP_Square(const CPDF_Rect& crBBox);
-  static CFX_ByteString GetAP_Star(const CPDF_Rect& crBBox);
-  static CFX_ByteString GetAP_HalfCircle(const CPDF_Rect& crBBox,
+  static CFX_ByteString GetAP_Check(const CFX_FloatRect& crBBox);
+  static CFX_ByteString GetAP_Circle(const CFX_FloatRect& crBBox);
+  static CFX_ByteString GetAP_Cross(const CFX_FloatRect& crBBox);
+  static CFX_ByteString GetAP_Diamond(const CFX_FloatRect& crBBox);
+  static CFX_ByteString GetAP_Square(const CFX_FloatRect& crBBox);
+  static CFX_ByteString GetAP_Star(const CFX_FloatRect& crBBox);
+  static CFX_ByteString GetAP_HalfCircle(const CFX_FloatRect& crBBox,
                                          FX_FLOAT fRotate);
 
   static void GetGraphics_Checkmark(CFX_ByteString& sPathData,
                                     CFX_PathData& path,
-                                    const CPDF_Rect& crBBox,
+                                    const CFX_FloatRect& crBBox,
                                     const PWL_PATH_TYPE type);
   static void GetGraphics_Circle(CFX_ByteString& sPathData,
                                  CFX_PathData& path,
-                                 const CPDF_Rect& crBBox,
+                                 const CFX_FloatRect& crBBox,
                                  const PWL_PATH_TYPE type);
   static void GetGraphics_Comment(CFX_ByteString& sPathData,
                                   CFX_PathData& path,
-                                  const CPDF_Rect& crBBox,
+                                  const CFX_FloatRect& crBBox,
                                   const PWL_PATH_TYPE type);
   static void GetGraphics_Cross(CFX_ByteString& sPathData,
                                 CFX_PathData& path,
-                                const CPDF_Rect& crBBox,
+                                const CFX_FloatRect& crBBox,
                                 const PWL_PATH_TYPE type);
   static void GetGraphics_Help(CFX_ByteString& sPathData,
                                CFX_PathData& path,
-                               const CPDF_Rect& crBBox,
+                               const CFX_FloatRect& crBBox,
                                const PWL_PATH_TYPE type);
   static void GetGraphics_InsertText(CFX_ByteString& sPathData,
                                      CFX_PathData& path,
-                                     const CPDF_Rect& crBBox,
+                                     const CFX_FloatRect& crBBox,
                                      const PWL_PATH_TYPE type);
   static void GetGraphics_Key(CFX_ByteString& sPathData,
                               CFX_PathData& path,
-                              const CPDF_Rect& crBBox,
+                              const CFX_FloatRect& crBBox,
                               const PWL_PATH_TYPE type);
   static void GetGraphics_NewParagraph(CFX_ByteString& sPathData,
                                        CFX_PathData& path,
-                                       const CPDF_Rect& crBBox,
+                                       const CFX_FloatRect& crBBox,
                                        const PWL_PATH_TYPE type);
   static void GetGraphics_TextNote(CFX_ByteString& sPathData,
                                    CFX_PathData& path,
-                                   const CPDF_Rect& crBBox,
+                                   const CFX_FloatRect& crBBox,
                                    const PWL_PATH_TYPE type);
   static void GetGraphics_Paragraph(CFX_ByteString& sPathData,
                                     CFX_PathData& path,
-                                    const CPDF_Rect& crBBox,
+                                    const CFX_FloatRect& crBBox,
                                     const PWL_PATH_TYPE type);
   static void GetGraphics_RightArrow(CFX_ByteString& sPathData,
                                      CFX_PathData& path,
-                                     const CPDF_Rect& crBBox,
+                                     const CFX_FloatRect& crBBox,
                                      const PWL_PATH_TYPE type);
   static void GetGraphics_RightPointer(CFX_ByteString& sPathData,
                                        CFX_PathData& path,
-                                       const CPDF_Rect& crBBox,
+                                       const CFX_FloatRect& crBBox,
                                        const PWL_PATH_TYPE type);
   static void GetGraphics_Star(CFX_ByteString& sPathData,
                                CFX_PathData& path,
-                               const CPDF_Rect& crBBox,
+                               const CFX_FloatRect& crBBox,
                                const PWL_PATH_TYPE type);
   static void GetGraphics_UpArrow(CFX_ByteString& sPathData,
                                   CFX_PathData& path,
-                                  const CPDF_Rect& crBBox,
+                                  const CFX_FloatRect& crBBox,
                                   const PWL_PATH_TYPE type);
   static void GetGraphics_UpLeftArrow(CFX_ByteString& sPathData,
                                       CFX_PathData& path,
-                                      const CPDF_Rect& crBBox,
+                                      const CFX_FloatRect& crBBox,
                                       const PWL_PATH_TYPE type);
   static void GetGraphics_Graph(CFX_ByteString& sPathData,
                                 CFX_PathData& path,
-                                const CPDF_Rect& crBBox,
+                                const CFX_FloatRect& crBBox,
                                 const PWL_PATH_TYPE type);
   static void GetGraphics_Paperclip(CFX_ByteString& sPathData,
                                     CFX_PathData& path,
-                                    const CPDF_Rect& crBBox,
+                                    const CFX_FloatRect& crBBox,
                                     const PWL_PATH_TYPE type);
   static void GetGraphics_Attachment(CFX_ByteString& sPathData,
                                      CFX_PathData& path,
-                                     const CPDF_Rect& crBBox,
+                                     const CFX_FloatRect& crBBox,
                                      const PWL_PATH_TYPE type);
   static void GetGraphics_Tag(CFX_ByteString& sPathData,
                               CFX_PathData& path,
-                              const CPDF_Rect& crBBox,
+                              const CFX_FloatRect& crBBox,
                               const PWL_PATH_TYPE type);
   static void GetGraphics_Foxit(CFX_ByteString& sPathData,
                                 CFX_PathData& path,
-                                const CPDF_Rect& crBBox,
+                                const CFX_FloatRect& crBBox,
                                 const PWL_PATH_TYPE type);
 };
 
-#endif  // FPDFSDK_INCLUDE_PDFWINDOW_PWL_UTILS_H_
+#endif  // FPDFSDK_PDFWINDOW_PWL_UTILS_H_
diff --git a/fpdfsdk/pdfwindow/PWL_Wnd.cpp b/fpdfsdk/pdfwindow/PWL_Wnd.cpp
new file mode 100644
index 0000000..8fd7b16
--- /dev/null
+++ b/fpdfsdk/pdfwindow/PWL_Wnd.cpp
@@ -0,0 +1,998 @@
+// 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
+
+#include <map>
+#include <vector>
+
+#include "fpdfsdk/pdfwindow/PWL_ScrollBar.h"
+#include "fpdfsdk/pdfwindow/PWL_Utils.h"
+#include "fpdfsdk/pdfwindow/PWL_Wnd.h"
+#include "third_party/base/ptr_util.h"
+#include "third_party/base/stl_util.h"
+
+static std::map<int32_t, CPWL_Timer*>& GetPWLTimeMap() {
+  // Leak the object at shutdown.
+  static auto timeMap = new std::map<int32_t, CPWL_Timer*>;
+  return *timeMap;
+}
+
+PWL_CREATEPARAM::PWL_CREATEPARAM()
+    : rcRectWnd(0, 0, 0, 0),
+      pSystemHandler(nullptr),
+      pFontMap(nullptr),
+      pProvider(nullptr),
+      pFocusHandler(nullptr),
+      dwFlags(0),
+      sBackgroundColor(),
+      pAttachedWidget(nullptr),
+      nBorderStyle(BorderStyle::SOLID),
+      dwBorderWidth(1),
+      sBorderColor(),
+      sTextColor(),
+      sTextStrokeColor(),
+      nTransparency(255),
+      fFontSize(PWL_DEFAULT_FONTSIZE),
+      sDash(3, 0, 0),
+      pAttachedData(nullptr),
+      pParentWnd(nullptr),
+      pMsgControl(nullptr),
+      eCursorType(FXCT_ARROW),
+      mtChild(1, 0, 0, 1, 0, 0) {}
+
+PWL_CREATEPARAM::PWL_CREATEPARAM(const PWL_CREATEPARAM& other) = default;
+
+CPWL_Timer::CPWL_Timer(CPWL_TimerHandler* pAttached,
+                       CFX_SystemHandler* pSystemHandler)
+    : m_nTimerID(0), m_pAttached(pAttached), m_pSystemHandler(pSystemHandler) {
+  ASSERT(m_pAttached);
+  ASSERT(m_pSystemHandler);
+}
+
+CPWL_Timer::~CPWL_Timer() {
+  KillPWLTimer();
+}
+
+int32_t CPWL_Timer::SetPWLTimer(int32_t nElapse) {
+  if (m_nTimerID != 0)
+    KillPWLTimer();
+  m_nTimerID = m_pSystemHandler->SetTimer(nElapse, TimerProc);
+
+  GetPWLTimeMap()[m_nTimerID] = this;
+  return m_nTimerID;
+}
+
+void CPWL_Timer::KillPWLTimer() {
+  if (m_nTimerID == 0)
+    return;
+
+  m_pSystemHandler->KillTimer(m_nTimerID);
+  GetPWLTimeMap().erase(m_nTimerID);
+  m_nTimerID = 0;
+}
+
+void CPWL_Timer::TimerProc(int32_t idEvent) {
+  auto it = GetPWLTimeMap().find(idEvent);
+  if (it == GetPWLTimeMap().end())
+    return;
+
+  CPWL_Timer* pTimer = it->second;
+  if (pTimer->m_pAttached)
+    pTimer->m_pAttached->TimerProc();
+}
+
+CPWL_TimerHandler::CPWL_TimerHandler() {}
+
+CPWL_TimerHandler::~CPWL_TimerHandler() {}
+
+void CPWL_TimerHandler::BeginTimer(int32_t nElapse) {
+  if (!m_pTimer)
+    m_pTimer = pdfium::MakeUnique<CPWL_Timer>(this, GetSystemHandler());
+
+  m_pTimer->SetPWLTimer(nElapse);
+}
+
+void CPWL_TimerHandler::EndTimer() {
+  if (m_pTimer)
+    m_pTimer->KillPWLTimer();
+}
+
+void CPWL_TimerHandler::TimerProc() {}
+
+class CPWL_MsgControl {
+  friend class CPWL_Wnd;
+
+ public:
+  explicit CPWL_MsgControl(CPWL_Wnd* pWnd) {
+    m_pCreatedWnd = pWnd;
+    Default();
+  }
+
+  ~CPWL_MsgControl() { Default(); }
+
+  void Default() {
+    m_aMousePath.clear();
+    m_aKeyboardPath.clear();
+    m_pMainMouseWnd = nullptr;
+    m_pMainKeyboardWnd = nullptr;
+  }
+
+  bool IsWndCreated(const CPWL_Wnd* pWnd) const {
+    return m_pCreatedWnd == pWnd;
+  }
+
+  bool IsMainCaptureMouse(const CPWL_Wnd* pWnd) const {
+    return pWnd == m_pMainMouseWnd;
+  }
+
+  bool IsWndCaptureMouse(const CPWL_Wnd* pWnd) const {
+    return pWnd && pdfium::ContainsValue(m_aMousePath, pWnd);
+  }
+
+  bool IsMainCaptureKeyboard(const CPWL_Wnd* pWnd) const {
+    return pWnd == m_pMainKeyboardWnd;
+  }
+
+  bool IsWndCaptureKeyboard(const CPWL_Wnd* pWnd) const {
+    return pWnd && pdfium::ContainsValue(m_aKeyboardPath, pWnd);
+  }
+
+  void SetFocus(CPWL_Wnd* pWnd) {
+    m_aKeyboardPath.clear();
+    if (pWnd) {
+      m_pMainKeyboardWnd = pWnd;
+      CPWL_Wnd* pParent = pWnd;
+      while (pParent) {
+        m_aKeyboardPath.push_back(pParent);
+        pParent = pParent->GetParentWindow();
+      }
+      pWnd->OnSetFocus();
+    }
+  }
+
+  void KillFocus() {
+    if (!m_aKeyboardPath.empty())
+      if (CPWL_Wnd* pWnd = m_aKeyboardPath[0])
+        pWnd->OnKillFocus();
+
+    m_pMainKeyboardWnd = nullptr;
+    m_aKeyboardPath.clear();
+  }
+
+  void SetCapture(CPWL_Wnd* pWnd) {
+    m_aMousePath.clear();
+    if (pWnd) {
+      m_pMainMouseWnd = pWnd;
+      CPWL_Wnd* pParent = pWnd;
+      while (pParent) {
+        m_aMousePath.push_back(pParent);
+        pParent = pParent->GetParentWindow();
+      }
+    }
+  }
+
+  void ReleaseCapture() {
+    m_pMainMouseWnd = nullptr;
+    m_aMousePath.clear();
+  }
+
+ private:
+  std::vector<CPWL_Wnd*> m_aMousePath;
+  std::vector<CPWL_Wnd*> m_aKeyboardPath;
+  CPWL_Wnd* m_pCreatedWnd;
+  CPWL_Wnd* m_pMainMouseWnd;
+  CPWL_Wnd* m_pMainKeyboardWnd;
+};
+
+CPWL_Wnd::CPWL_Wnd()
+    : m_pVScrollBar(nullptr),
+      m_rcWindow(),
+      m_rcClip(),
+      m_bCreated(false),
+      m_bVisible(false),
+      m_bNotifying(false),
+      m_bEnabled(true) {}
+
+CPWL_Wnd::~CPWL_Wnd() {
+  ASSERT(m_bCreated == false);
+}
+
+CFX_ByteString CPWL_Wnd::GetClassName() const {
+  return "CPWL_Wnd";
+}
+
+void CPWL_Wnd::Create(const PWL_CREATEPARAM& cp) {
+  if (!IsValid()) {
+    m_sPrivateParam = cp;
+
+    OnCreate(m_sPrivateParam);
+
+    m_sPrivateParam.rcRectWnd.Normalize();
+    m_rcWindow = m_sPrivateParam.rcRectWnd;
+    m_rcClip = CPWL_Utils::InflateRect(m_rcWindow, 1.0f);
+
+    CreateMsgControl();
+
+    if (m_sPrivateParam.pParentWnd)
+      m_sPrivateParam.pParentWnd->OnNotify(this, PNM_ADDCHILD);
+
+    PWL_CREATEPARAM ccp = m_sPrivateParam;
+
+    ccp.dwFlags &= 0xFFFF0000L;  // remove sub styles
+    ccp.mtChild = CFX_Matrix(1, 0, 0, 1, 0, 0);
+
+    CreateScrollBar(ccp);
+    CreateChildWnd(ccp);
+
+    m_bVisible = HasFlag(PWS_VISIBLE);
+
+    OnCreated();
+
+    RePosChildWnd();
+    m_bCreated = true;
+  }
+}
+
+void CPWL_Wnd::OnCreate(PWL_CREATEPARAM& cp) {}
+
+void CPWL_Wnd::OnCreated() {}
+
+void CPWL_Wnd::OnDestroy() {}
+
+void CPWL_Wnd::InvalidateFocusHandler(IPWL_FocusHandler* handler) {
+  if (m_sPrivateParam.pFocusHandler == handler)
+    m_sPrivateParam.pFocusHandler = nullptr;
+}
+
+void CPWL_Wnd::InvalidateProvider(IPWL_Provider* provider) {
+  if (m_sPrivateParam.pProvider.Get() == provider)
+    m_sPrivateParam.pProvider.Reset();
+}
+
+void CPWL_Wnd::Destroy() {
+  KillFocus();
+  OnDestroy();
+  if (m_bCreated) {
+    for (auto it = m_Children.rbegin(); it != m_Children.rend(); ++it) {
+      if (CPWL_Wnd* pChild = *it) {
+        *it = nullptr;
+        pChild->Destroy();
+        delete pChild;
+      }
+    }
+    if (m_sPrivateParam.pParentWnd)
+      m_sPrivateParam.pParentWnd->OnNotify(this, PNM_REMOVECHILD);
+
+    m_bCreated = false;
+  }
+  DestroyMsgControl();
+  m_sPrivateParam.Reset();
+  m_Children.clear();
+  m_pVScrollBar = nullptr;
+}
+
+void CPWL_Wnd::Move(const CFX_FloatRect& rcNew, bool bReset, bool bRefresh) {
+  if (IsValid()) {
+    CFX_FloatRect rcOld = GetWindowRect();
+
+    m_rcWindow = rcNew;
+    m_rcWindow.Normalize();
+
+    if (rcOld.left != rcNew.left || rcOld.right != rcNew.right ||
+        rcOld.top != rcNew.top || rcOld.bottom != rcNew.bottom) {
+      if (bReset) {
+        RePosChildWnd();
+      }
+    }
+    if (bRefresh) {
+      InvalidateRectMove(rcOld, rcNew);
+    }
+
+    m_sPrivateParam.rcRectWnd = m_rcWindow;
+  }
+}
+
+void CPWL_Wnd::InvalidateRectMove(const CFX_FloatRect& rcOld,
+                                  const CFX_FloatRect& rcNew) {
+  CFX_FloatRect rcUnion = rcOld;
+  rcUnion.Union(rcNew);
+
+  InvalidateRect(&rcUnion);
+}
+
+void CPWL_Wnd::GetAppearanceStream(CFX_ByteTextBuf& sAppStream) {
+  if (IsValid() && IsVisible()) {
+    GetThisAppearanceStream(sAppStream);
+    GetChildAppearanceStream(sAppStream);
+  }
+}
+
+// if don't set,Get default apperance stream
+void CPWL_Wnd::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) {
+  CFX_FloatRect rectWnd = GetWindowRect();
+  if (!rectWnd.IsEmpty()) {
+    CFX_ByteTextBuf sThis;
+
+    if (HasFlag(PWS_BACKGROUND))
+      sThis << CPWL_Utils::GetRectFillAppStream(rectWnd, GetBackgroundColor());
+
+    if (HasFlag(PWS_BORDER)) {
+      sThis << CPWL_Utils::GetBorderAppStream(
+          rectWnd, (FX_FLOAT)GetBorderWidth(), GetBorderColor(),
+          GetBorderLeftTopColor(GetBorderStyle()),
+          GetBorderRightBottomColor(GetBorderStyle()), GetBorderStyle(),
+          GetBorderDash());
+    }
+
+    sAppStream << sThis;
+  }
+}
+
+void CPWL_Wnd::GetChildAppearanceStream(CFX_ByteTextBuf& sAppStream) {
+  for (CPWL_Wnd* pChild : m_Children) {
+    if (pChild)
+      pChild->GetAppearanceStream(sAppStream);
+  }
+}
+
+void CPWL_Wnd::DrawAppearance(CFX_RenderDevice* pDevice,
+                              CFX_Matrix* pUser2Device) {
+  if (IsValid() && IsVisible()) {
+    DrawThisAppearance(pDevice, pUser2Device);
+    DrawChildAppearance(pDevice, pUser2Device);
+  }
+}
+
+void CPWL_Wnd::DrawThisAppearance(CFX_RenderDevice* pDevice,
+                                  CFX_Matrix* pUser2Device) {
+  CFX_FloatRect rectWnd = GetWindowRect();
+  if (!rectWnd.IsEmpty()) {
+    if (HasFlag(PWS_BACKGROUND)) {
+      CFX_FloatRect rcClient = CPWL_Utils::DeflateRect(
+          rectWnd, (FX_FLOAT)(GetBorderWidth() + GetInnerBorderWidth()));
+      CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rcClient,
+                               GetBackgroundColor(), GetTransparency());
+    }
+
+    if (HasFlag(PWS_BORDER))
+      CPWL_Utils::DrawBorder(pDevice, pUser2Device, rectWnd,
+                             (FX_FLOAT)GetBorderWidth(), GetBorderColor(),
+                             GetBorderLeftTopColor(GetBorderStyle()),
+                             GetBorderRightBottomColor(GetBorderStyle()),
+                             GetBorderStyle(), GetTransparency());
+  }
+}
+
+void CPWL_Wnd::DrawChildAppearance(CFX_RenderDevice* pDevice,
+                                   CFX_Matrix* pUser2Device) {
+  for (CPWL_Wnd* pChild : m_Children) {
+    if (!pChild)
+      continue;
+
+    CFX_Matrix mt = pChild->GetChildMatrix();
+    if (mt.IsIdentity()) {
+      pChild->DrawAppearance(pDevice, pUser2Device);
+    } else {
+      mt.Concat(*pUser2Device);
+      pChild->DrawAppearance(pDevice, &mt);
+    }
+  }
+}
+
+void CPWL_Wnd::InvalidateRect(CFX_FloatRect* pRect) {
+  if (IsValid()) {
+    CFX_FloatRect rcRefresh = pRect ? *pRect : GetWindowRect();
+
+    if (!HasFlag(PWS_NOREFRESHCLIP)) {
+      CFX_FloatRect rcClip = GetClipRect();
+      if (!rcClip.IsEmpty()) {
+        rcRefresh.Intersect(rcClip);
+      }
+    }
+
+    FX_RECT rcWin = PWLtoWnd(rcRefresh);
+    rcWin.left -= PWL_INVALIDATE_INFLATE;
+    rcWin.top -= PWL_INVALIDATE_INFLATE;
+    rcWin.right += PWL_INVALIDATE_INFLATE;
+    rcWin.bottom += PWL_INVALIDATE_INFLATE;
+
+    if (CFX_SystemHandler* pSH = GetSystemHandler()) {
+      if (CPDFSDK_Widget* widget = static_cast<CPDFSDK_Widget*>(
+              m_sPrivateParam.pAttachedWidget.Get())) {
+        pSH->InvalidateRect(widget, rcWin);
+      }
+    }
+  }
+}
+
+#define PWL_IMPLEMENT_KEY_METHOD(key_method_name)                  \
+  bool CPWL_Wnd::key_method_name(uint16_t nChar, uint32_t nFlag) { \
+    if (!IsValid() || !IsVisible() || !IsEnabled())                \
+      return false;                                                \
+    if (!IsWndCaptureKeyboard(this))                               \
+      return false;                                                \
+    for (const auto& pChild : m_Children) {                        \
+      if (pChild && IsWndCaptureKeyboard(pChild))                  \
+        return pChild->key_method_name(nChar, nFlag);              \
+    }                                                              \
+    return false;                                                  \
+  }
+
+PWL_IMPLEMENT_KEY_METHOD(OnKeyDown)
+PWL_IMPLEMENT_KEY_METHOD(OnKeyUp)
+PWL_IMPLEMENT_KEY_METHOD(OnChar)
+#undef PWL_IMPLEMENT_KEY_METHOD
+
+#define PWL_IMPLEMENT_MOUSE_METHOD(mouse_method_name)                          \
+  bool CPWL_Wnd::mouse_method_name(const CFX_FloatPoint& point,                \
+                                   uint32_t nFlag) {                           \
+    if (!IsValid() || !IsVisible() || !IsEnabled())                            \
+      return false;                                                            \
+    if (IsWndCaptureMouse(this)) {                                             \
+      for (const auto& pChild : m_Children) {                                  \
+        if (pChild && IsWndCaptureMouse(pChild)) {                             \
+          return pChild->mouse_method_name(pChild->ParentToChild(point),       \
+                                           nFlag);                             \
+        }                                                                      \
+      }                                                                        \
+      SetCursor();                                                             \
+      return false;                                                            \
+    }                                                                          \
+    for (const auto& pChild : m_Children) {                                    \
+      if (pChild && pChild->WndHitTest(pChild->ParentToChild(point))) {        \
+        return pChild->mouse_method_name(pChild->ParentToChild(point), nFlag); \
+      }                                                                        \
+    }                                                                          \
+    if (WndHitTest(point))                                                     \
+      SetCursor();                                                             \
+    return false;                                                              \
+  }
+
+PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonDblClk)
+PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonDown)
+PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonUp)
+PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonDblClk)
+PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonDown)
+PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonUp)
+PWL_IMPLEMENT_MOUSE_METHOD(OnRButtonDown)
+PWL_IMPLEMENT_MOUSE_METHOD(OnRButtonUp)
+PWL_IMPLEMENT_MOUSE_METHOD(OnMouseMove)
+#undef PWL_IMPLEMENT_MOUSE_METHOD
+
+bool CPWL_Wnd::OnMouseWheel(short zDelta,
+                            const CFX_FloatPoint& point,
+                            uint32_t nFlag) {
+  if (!IsValid() || !IsVisible() || !IsEnabled())
+    return false;
+
+  SetCursor();
+  if (!IsWndCaptureKeyboard(this))
+    return false;
+
+  for (const auto& pChild : m_Children) {
+    if (pChild && IsWndCaptureKeyboard(pChild))
+      return pChild->OnMouseWheel(zDelta, pChild->ParentToChild(point), nFlag);
+  }
+  return false;
+}
+
+void CPWL_Wnd::AddChild(CPWL_Wnd* pWnd) {
+  m_Children.push_back(pWnd);
+}
+
+void CPWL_Wnd::RemoveChild(CPWL_Wnd* pWnd) {
+  for (auto it = m_Children.rbegin(); it != m_Children.rend(); ++it) {
+    if (*it && *it == pWnd) {
+      m_Children.erase(std::next(it).base());
+      break;
+    }
+  }
+}
+
+void CPWL_Wnd::OnNotify(CPWL_Wnd* pWnd,
+                        uint32_t msg,
+                        intptr_t wParam,
+                        intptr_t lParam) {
+  switch (msg) {
+    case PNM_ADDCHILD:
+      AddChild(pWnd);
+      break;
+    case PNM_REMOVECHILD:
+      RemoveChild(pWnd);
+      break;
+    default:
+      break;
+  }
+}
+
+bool CPWL_Wnd::IsValid() const {
+  return m_bCreated;
+}
+
+const PWL_CREATEPARAM& CPWL_Wnd::GetCreationParam() const {
+  return m_sPrivateParam;
+}
+
+CPWL_Wnd* CPWL_Wnd::GetParentWindow() const {
+  return m_sPrivateParam.pParentWnd;
+}
+
+CFX_FloatRect CPWL_Wnd::GetWindowRect() const {
+  return m_rcWindow;
+}
+
+CFX_FloatRect CPWL_Wnd::GetClientRect() const {
+  CFX_FloatRect rcWindow = GetWindowRect();
+  CFX_FloatRect rcClient = CPWL_Utils::DeflateRect(
+      rcWindow, (FX_FLOAT)(GetBorderWidth() + GetInnerBorderWidth()));
+  if (CPWL_ScrollBar* pVSB = GetVScrollBar())
+    rcClient.right -= pVSB->GetScrollBarWidth();
+
+  rcClient.Normalize();
+  return rcWindow.Contains(rcClient) ? rcClient : CFX_FloatRect();
+}
+
+CFX_FloatPoint CPWL_Wnd::GetCenterPoint() const {
+  CFX_FloatRect rcClient = GetClientRect();
+  return CFX_FloatPoint((rcClient.left + rcClient.right) * 0.5f,
+                        (rcClient.top + rcClient.bottom) * 0.5f);
+}
+
+bool CPWL_Wnd::HasFlag(uint32_t dwFlags) const {
+  return (m_sPrivateParam.dwFlags & dwFlags) != 0;
+}
+
+void CPWL_Wnd::RemoveFlag(uint32_t dwFlags) {
+  m_sPrivateParam.dwFlags &= ~dwFlags;
+}
+
+void CPWL_Wnd::AddFlag(uint32_t dwFlags) {
+  m_sPrivateParam.dwFlags |= dwFlags;
+}
+
+CPWL_Color CPWL_Wnd::GetBackgroundColor() const {
+  return m_sPrivateParam.sBackgroundColor;
+}
+
+void CPWL_Wnd::SetBackgroundColor(const CPWL_Color& color) {
+  m_sPrivateParam.sBackgroundColor = color;
+}
+
+void CPWL_Wnd::SetTextColor(const CPWL_Color& color) {
+  m_sPrivateParam.sTextColor = color;
+}
+
+void CPWL_Wnd::SetTextStrokeColor(const CPWL_Color& color) {
+  m_sPrivateParam.sTextStrokeColor = color;
+}
+
+CPWL_Color CPWL_Wnd::GetTextColor() const {
+  return m_sPrivateParam.sTextColor;
+}
+
+CPWL_Color CPWL_Wnd::GetTextStrokeColor() const {
+  return m_sPrivateParam.sTextStrokeColor;
+}
+
+BorderStyle CPWL_Wnd::GetBorderStyle() const {
+  return m_sPrivateParam.nBorderStyle;
+}
+
+void CPWL_Wnd::SetBorderStyle(BorderStyle nBorderStyle) {
+  if (HasFlag(PWS_BORDER))
+    m_sPrivateParam.nBorderStyle = nBorderStyle;
+}
+
+int32_t CPWL_Wnd::GetBorderWidth() const {
+  if (HasFlag(PWS_BORDER))
+    return m_sPrivateParam.dwBorderWidth;
+
+  return 0;
+}
+
+int32_t CPWL_Wnd::GetInnerBorderWidth() const {
+  return 0;
+}
+
+CPWL_Color CPWL_Wnd::GetBorderColor() const {
+  if (HasFlag(PWS_BORDER))
+    return m_sPrivateParam.sBorderColor;
+
+  return CPWL_Color();
+}
+
+const CPWL_Dash& CPWL_Wnd::GetBorderDash() const {
+  return m_sPrivateParam.sDash;
+}
+
+void* CPWL_Wnd::GetAttachedData() const {
+  return m_sPrivateParam.pAttachedData;
+}
+
+CPWL_ScrollBar* CPWL_Wnd::GetVScrollBar() const {
+  if (HasFlag(PWS_VSCROLL))
+    return m_pVScrollBar;
+
+  return nullptr;
+}
+
+void CPWL_Wnd::CreateScrollBar(const PWL_CREATEPARAM& cp) {
+  CreateVScrollBar(cp);
+}
+
+void CPWL_Wnd::CreateVScrollBar(const PWL_CREATEPARAM& cp) {
+  if (!m_pVScrollBar && HasFlag(PWS_VSCROLL)) {
+    PWL_CREATEPARAM scp = cp;
+
+    // flags
+    scp.dwFlags =
+        PWS_CHILD | PWS_BACKGROUND | PWS_AUTOTRANSPARENT | PWS_NOREFRESHCLIP;
+
+    scp.pParentWnd = this;
+    scp.sBackgroundColor = PWL_DEFAULT_WHITECOLOR;
+    scp.eCursorType = FXCT_ARROW;
+    scp.nTransparency = PWL_SCROLLBAR_TRANSPARANCY;
+
+    m_pVScrollBar = new CPWL_ScrollBar(SBT_VSCROLL);
+    m_pVScrollBar->Create(scp);
+  }
+}
+
+void CPWL_Wnd::SetCapture() {
+  if (CPWL_MsgControl* pMsgCtrl = GetMsgControl())
+    pMsgCtrl->SetCapture(this);
+}
+
+void CPWL_Wnd::ReleaseCapture() {
+  for (const auto& pChild : m_Children) {
+    if (pChild)
+      pChild->ReleaseCapture();
+  }
+  if (CPWL_MsgControl* pMsgCtrl = GetMsgControl())
+    pMsgCtrl->ReleaseCapture();
+}
+
+void CPWL_Wnd::SetFocus() {
+  if (CPWL_MsgControl* pMsgCtrl = GetMsgControl()) {
+    if (!pMsgCtrl->IsMainCaptureKeyboard(this))
+      pMsgCtrl->KillFocus();
+    pMsgCtrl->SetFocus(this);
+  }
+}
+
+void CPWL_Wnd::KillFocus() {
+  if (CPWL_MsgControl* pMsgCtrl = GetMsgControl()) {
+    if (pMsgCtrl->IsWndCaptureKeyboard(this))
+      pMsgCtrl->KillFocus();
+  }
+}
+
+void CPWL_Wnd::OnSetFocus() {}
+
+void CPWL_Wnd::OnKillFocus() {}
+
+bool CPWL_Wnd::WndHitTest(const CFX_FloatPoint& point) const {
+  return IsValid() && IsVisible() && GetWindowRect().Contains(point.x, point.y);
+}
+
+bool CPWL_Wnd::ClientHitTest(const CFX_FloatPoint& point) const {
+  return IsValid() && IsVisible() && GetClientRect().Contains(point.x, point.y);
+}
+
+const CPWL_Wnd* CPWL_Wnd::GetRootWnd() const {
+  if (m_sPrivateParam.pParentWnd)
+    return m_sPrivateParam.pParentWnd->GetRootWnd();
+
+  return this;
+}
+
+void CPWL_Wnd::SetVisible(bool bVisible) {
+  if (!IsValid())
+    return;
+
+  for (const auto& pChild : m_Children) {
+    if (pChild)
+      pChild->SetVisible(bVisible);
+  }
+  if (bVisible != m_bVisible) {
+    m_bVisible = bVisible;
+    RePosChildWnd();
+    InvalidateRect();
+  }
+}
+
+void CPWL_Wnd::SetClipRect(const CFX_FloatRect& rect) {
+  m_rcClip = rect;
+  m_rcClip.Normalize();
+}
+
+const CFX_FloatRect& CPWL_Wnd::GetClipRect() const {
+  return m_rcClip;
+}
+
+bool CPWL_Wnd::IsReadOnly() const {
+  return HasFlag(PWS_READONLY);
+}
+
+void CPWL_Wnd::RePosChildWnd() {
+  CFX_FloatRect rcContent = CPWL_Utils::DeflateRect(
+      GetWindowRect(), (FX_FLOAT)(GetBorderWidth() + GetInnerBorderWidth()));
+
+  CPWL_ScrollBar* pVSB = GetVScrollBar();
+
+  CFX_FloatRect rcVScroll =
+      CFX_FloatRect(rcContent.right - PWL_SCROLLBAR_WIDTH, rcContent.bottom,
+                    rcContent.right - 1.0f, rcContent.top);
+
+  if (pVSB)
+    pVSB->Move(rcVScroll, true, false);
+}
+
+void CPWL_Wnd::CreateChildWnd(const PWL_CREATEPARAM& cp) {}
+
+void CPWL_Wnd::SetCursor() {
+  if (IsValid()) {
+    if (CFX_SystemHandler* pSH = GetSystemHandler()) {
+      int32_t nCursorType = GetCreationParam().eCursorType;
+      pSH->SetCursor(nCursorType);
+    }
+  }
+}
+
+void CPWL_Wnd::CreateMsgControl() {
+  if (!m_sPrivateParam.pMsgControl)
+    m_sPrivateParam.pMsgControl = new CPWL_MsgControl(this);
+}
+
+void CPWL_Wnd::DestroyMsgControl() {
+  if (CPWL_MsgControl* pMsgControl = GetMsgControl())
+    if (pMsgControl->IsWndCreated(this))
+      delete pMsgControl;
+}
+
+CPWL_MsgControl* CPWL_Wnd::GetMsgControl() const {
+  return m_sPrivateParam.pMsgControl;
+}
+
+bool CPWL_Wnd::IsCaptureMouse() const {
+  return IsWndCaptureMouse(this);
+}
+
+bool CPWL_Wnd::IsWndCaptureMouse(const CPWL_Wnd* pWnd) const {
+  if (CPWL_MsgControl* pCtrl = GetMsgControl())
+    return pCtrl->IsWndCaptureMouse(pWnd);
+
+  return false;
+}
+
+bool CPWL_Wnd::IsWndCaptureKeyboard(const CPWL_Wnd* pWnd) const {
+  if (CPWL_MsgControl* pCtrl = GetMsgControl())
+    return pCtrl->IsWndCaptureKeyboard(pWnd);
+
+  return false;
+}
+
+bool CPWL_Wnd::IsFocused() const {
+  if (CPWL_MsgControl* pCtrl = GetMsgControl())
+    return pCtrl->IsMainCaptureKeyboard(this);
+
+  return false;
+}
+
+CFX_FloatRect CPWL_Wnd::GetFocusRect() const {
+  return CPWL_Utils::InflateRect(GetWindowRect(), 1);
+}
+
+FX_FLOAT CPWL_Wnd::GetFontSize() const {
+  return m_sPrivateParam.fFontSize;
+}
+
+void CPWL_Wnd::SetFontSize(FX_FLOAT fFontSize) {
+  m_sPrivateParam.fFontSize = fFontSize;
+}
+
+CFX_SystemHandler* CPWL_Wnd::GetSystemHandler() const {
+  return m_sPrivateParam.pSystemHandler;
+}
+
+IPWL_FocusHandler* CPWL_Wnd::GetFocusHandler() const {
+  return m_sPrivateParam.pFocusHandler;
+}
+
+IPWL_Provider* CPWL_Wnd::GetProvider() const {
+  return m_sPrivateParam.pProvider.Get();
+}
+
+IPVT_FontMap* CPWL_Wnd::GetFontMap() const {
+  return m_sPrivateParam.pFontMap;
+}
+
+CPWL_Color CPWL_Wnd::GetBorderLeftTopColor(BorderStyle nBorderStyle) const {
+  switch (nBorderStyle) {
+    case BorderStyle::BEVELED:
+      return CPWL_Color(COLORTYPE_GRAY, 1);
+    case BorderStyle::INSET:
+      return CPWL_Color(COLORTYPE_GRAY, 0.5f);
+    default:
+      return CPWL_Color();
+  }
+}
+
+CPWL_Color CPWL_Wnd::GetBorderRightBottomColor(BorderStyle nBorderStyle) const {
+  switch (nBorderStyle) {
+    case BorderStyle::BEVELED:
+      return CPWL_Utils::DevideColor(GetBackgroundColor(), 2);
+    case BorderStyle::INSET:
+      return CPWL_Color(COLORTYPE_GRAY, 0.75f);
+    default:
+      return CPWL_Color();
+  }
+}
+
+int32_t CPWL_Wnd::GetTransparency() {
+  return m_sPrivateParam.nTransparency;
+}
+
+void CPWL_Wnd::SetTransparency(int32_t nTransparency) {
+  for (const auto& pChild : m_Children) {
+    if (pChild)
+      pChild->SetTransparency(nTransparency);
+  }
+  m_sPrivateParam.nTransparency = nTransparency;
+}
+
+CFX_Matrix CPWL_Wnd::GetWindowMatrix() const {
+  CFX_Matrix mt = GetChildToRoot();
+  if (IPWL_Provider* pProvider = GetProvider())
+    mt.Concat(pProvider->GetWindowMatrix(GetAttachedData()));
+  return mt;
+}
+
+void CPWL_Wnd::PWLtoWnd(const CFX_FloatPoint& point,
+                        int32_t& x,
+                        int32_t& y) const {
+  CFX_Matrix mt = GetWindowMatrix();
+  CFX_FloatPoint pt = point;
+  mt.Transform(pt.x, pt.y);
+  x = (int32_t)(pt.x + 0.5);
+  y = (int32_t)(pt.y + 0.5);
+}
+
+FX_RECT CPWL_Wnd::PWLtoWnd(const CFX_FloatRect& rect) const {
+  CFX_FloatRect rcTemp = rect;
+  CFX_Matrix mt = GetWindowMatrix();
+  mt.TransformRect(rcTemp);
+  return FX_RECT((int32_t)(rcTemp.left + 0.5), (int32_t)(rcTemp.bottom + 0.5),
+                 (int32_t)(rcTemp.right + 0.5), (int32_t)(rcTemp.top + 0.5));
+}
+
+CFX_FloatPoint CPWL_Wnd::ChildToParent(const CFX_FloatPoint& point) const {
+  CFX_Matrix mt = GetChildMatrix();
+  if (mt.IsIdentity())
+    return point;
+
+  CFX_FloatPoint pt = point;
+  mt.Transform(pt.x, pt.y);
+  return pt;
+}
+
+CFX_FloatRect CPWL_Wnd::ChildToParent(const CFX_FloatRect& rect) const {
+  CFX_Matrix mt = GetChildMatrix();
+  if (mt.IsIdentity())
+    return rect;
+
+  CFX_FloatRect rc = rect;
+  mt.TransformRect(rc);
+  return rc;
+}
+
+CFX_FloatPoint CPWL_Wnd::ParentToChild(const CFX_FloatPoint& point) const {
+  CFX_Matrix mt = GetChildMatrix();
+  if (mt.IsIdentity())
+    return point;
+
+  mt.SetReverse(mt);
+  CFX_FloatPoint pt = point;
+  mt.Transform(pt.x, pt.y);
+  return pt;
+}
+
+CFX_FloatRect CPWL_Wnd::ParentToChild(const CFX_FloatRect& rect) const {
+  CFX_Matrix mt = GetChildMatrix();
+  if (mt.IsIdentity())
+    return rect;
+
+  mt.SetReverse(mt);
+  CFX_FloatRect rc = rect;
+  mt.TransformRect(rc);
+  return rc;
+}
+
+FX_FLOAT CPWL_Wnd::GetItemHeight(FX_FLOAT fLimitWidth) {
+  return 0;
+}
+
+FX_FLOAT CPWL_Wnd::GetItemLeftMargin() {
+  return 0;
+}
+
+FX_FLOAT CPWL_Wnd::GetItemRightMargin() {
+  return 0;
+}
+
+CFX_Matrix CPWL_Wnd::GetChildToRoot() const {
+  CFX_Matrix mt(1, 0, 0, 1, 0, 0);
+  if (HasFlag(PWS_CHILD)) {
+    const CPWL_Wnd* pParent = this;
+    while (pParent) {
+      mt.Concat(pParent->GetChildMatrix());
+      pParent = pParent->GetParentWindow();
+    }
+  }
+  return mt;
+}
+
+CFX_Matrix CPWL_Wnd::GetChildMatrix() const {
+  if (HasFlag(PWS_CHILD))
+    return m_sPrivateParam.mtChild;
+
+  return CFX_Matrix(1, 0, 0, 1, 0, 0);
+}
+
+void CPWL_Wnd::SetChildMatrix(const CFX_Matrix& mt) {
+  m_sPrivateParam.mtChild = mt;
+}
+
+const CPWL_Wnd* CPWL_Wnd::GetFocused() const {
+  CPWL_MsgControl* pMsgCtrl = GetMsgControl();
+  return pMsgCtrl ? pMsgCtrl->m_pMainKeyboardWnd : nullptr;
+}
+
+void CPWL_Wnd::EnableWindow(bool bEnable) {
+  if (m_bEnabled == bEnable)
+    return;
+
+  for (const auto& pChild : m_Children) {
+    if (pChild)
+      pChild->EnableWindow(bEnable);
+  }
+  m_bEnabled = bEnable;
+  if (bEnable)
+    OnEnabled();
+  else
+    OnDisabled();
+}
+
+bool CPWL_Wnd::IsEnabled() {
+  return m_bEnabled;
+}
+
+void CPWL_Wnd::OnEnabled() {}
+
+void CPWL_Wnd::OnDisabled() {}
+
+bool CPWL_Wnd::IsCTRLpressed(uint32_t nFlag) const {
+  if (CFX_SystemHandler* pSystemHandler = GetSystemHandler()) {
+    return pSystemHandler->IsCTRLKeyDown(nFlag);
+  }
+
+  return false;
+}
+
+bool CPWL_Wnd::IsSHIFTpressed(uint32_t nFlag) const {
+  if (CFX_SystemHandler* pSystemHandler = GetSystemHandler()) {
+    return pSystemHandler->IsSHIFTKeyDown(nFlag);
+  }
+
+  return false;
+}
+
+bool CPWL_Wnd::IsALTpressed(uint32_t nFlag) const {
+  if (CFX_SystemHandler* pSystemHandler = GetSystemHandler()) {
+    return pSystemHandler->IsALTKeyDown(nFlag);
+  }
+
+  return false;
+}
diff --git a/fpdfsdk/pdfwindow/PWL_Wnd.h b/fpdfsdk/pdfwindow/PWL_Wnd.h
new file mode 100644
index 0000000..dd4f321
--- /dev/null
+++ b/fpdfsdk/pdfwindow/PWL_Wnd.h
@@ -0,0 +1,430 @@
+// 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_PDFWINDOW_PWL_WND_H_
+#define FPDFSDK_PDFWINDOW_PWL_WND_H_
+
+#include <memory>
+#include <vector>
+
+#include "core/fpdfdoc/cpdf_formcontrol.h"
+#include "core/fxcrt/cfx_observable.h"
+#include "core/fxcrt/fx_basic.h"
+#include "fpdfsdk/cfx_systemhandler.h"
+#include "fpdfsdk/cpdfsdk_widget.h"
+#include "fpdfsdk/pdfwindow/cpwl_color.h"
+
+class CPWL_MsgControl;
+class CPWL_ScrollBar;
+class CPWL_Timer;
+class CPWL_TimerHandler;
+class CPWL_Wnd;
+class CFX_SystemHandler;
+class IPVT_FontMap;
+class IPWL_Provider;
+
+// window styles
+#define PWS_CHILD 0x80000000L
+#define PWS_BORDER 0x40000000L
+#define PWS_BACKGROUND 0x20000000L
+#define PWS_HSCROLL 0x10000000L
+#define PWS_VSCROLL 0x08000000L
+#define PWS_VISIBLE 0x04000000L
+#define PWS_DISABLE 0x02000000L
+#define PWS_READONLY 0x01000000L
+#define PWS_AUTOFONTSIZE 0x00800000L
+#define PWS_AUTOTRANSPARENT 0x00400000L
+#define PWS_NOREFRESHCLIP 0x00200000L
+
+// edit and label styles
+#define PES_MULTILINE 0x0001L
+#define PES_PASSWORD 0x0002L
+#define PES_LEFT 0x0004L
+#define PES_RIGHT 0x0008L
+#define PES_MIDDLE 0x0010L
+#define PES_TOP 0x0020L
+#define PES_BOTTOM 0x0040L
+#define PES_CENTER 0x0080L
+#define PES_CHARARRAY 0x0100L
+#define PES_AUTOSCROLL 0x0200L
+#define PES_AUTORETURN 0x0400L
+#define PES_UNDO 0x0800L
+#define PES_RICH 0x1000L
+#define PES_SPELLCHECK 0x2000L
+#define PES_TEXTOVERFLOW 0x4000L
+#define PES_NOREAD 0x8000L
+
+// listbox styles
+#define PLBS_MULTIPLESEL 0x0001L
+#define PLBS_HOVERSEL 0x0008L
+
+// combobox styles
+#define PCBS_ALLOWCUSTOMTEXT 0x0001L
+
+// richedit styles
+#define PRES_MULTILINE 0x0001L
+#define PRES_AUTORETURN 0x0002L
+#define PRES_AUTOSCROLL 0x0004L
+#define PRES_UNDO 0x0100L
+#define PRES_MULTIPAGES 0x0200L
+#define PRES_TEXTOVERFLOW 0x0400L
+
+// notification messages
+#define PNM_ADDCHILD 0x00000000L
+#define PNM_REMOVECHILD 0x00000001L
+#define PNM_SETSCROLLINFO 0x00000002L
+#define PNM_SETSCROLLPOS 0x00000003L
+#define PNM_SCROLLWINDOW 0x00000004L
+#define PNM_LBUTTONDOWN 0x00000005L
+#define PNM_LBUTTONUP 0x00000006L
+#define PNM_MOUSEMOVE 0x00000007L
+#define PNM_NOTERESET 0x00000008L
+#define PNM_SETCARETINFO 0x00000009L
+#define PNM_SELCHANGED 0x0000000AL
+#define PNM_NOTEEDITCHANGED 0x0000000BL
+
+#define PWL_CLASSNAME_EDIT "CPWL_Edit"
+
+struct CPWL_Dash {
+  CPWL_Dash() : nDash(0), nGap(0), nPhase(0) {}
+  CPWL_Dash(int32_t dash, int32_t gap, int32_t phase)
+      : nDash(dash), nGap(gap), nPhase(phase) {}
+
+  void Reset() {
+    nDash = 0;
+    nGap = 0;
+    nPhase = 0;
+  }
+
+  int32_t nDash;
+  int32_t nGap;
+  int32_t nPhase;
+};
+
+inline bool operator==(const CPWL_Color& c1, const CPWL_Color& c2) {
+  return c1.nColorType == c2.nColorType && c1.fColor1 - c2.fColor1 < 0.0001 &&
+         c1.fColor1 - c2.fColor1 > -0.0001 &&
+         c1.fColor2 - c2.fColor2 < 0.0001 &&
+         c1.fColor2 - c2.fColor2 > -0.0001 &&
+         c1.fColor3 - c2.fColor3 < 0.0001 &&
+         c1.fColor3 - c2.fColor3 > -0.0001 &&
+         c1.fColor4 - c2.fColor4 < 0.0001 && c1.fColor4 - c2.fColor4 > -0.0001;
+}
+
+inline bool operator!=(const CPWL_Color& c1, const CPWL_Color& c2) {
+  return !(c1 == c2);
+}
+
+#define PWL_SCROLLBAR_WIDTH 12.0f
+#define PWL_SCROLLBAR_BUTTON_WIDTH 9.0f
+#define PWL_SCROLLBAR_POSBUTTON_MINWIDTH 2.0f
+#define PWL_SCROLLBAR_TRANSPARANCY 150
+#define PWL_SCROLLBAR_BKCOLOR \
+  CPWL_Color(COLORTYPE_RGB, 220.0f / 255.0f, 220.0f / 255.0f, 220.0f / 255.0f)
+#define PWL_DEFAULT_SELTEXTCOLOR CPWL_Color(COLORTYPE_RGB, 1, 1, 1)
+#define PWL_DEFAULT_SELBACKCOLOR \
+  CPWL_Color(COLORTYPE_RGB, 0, 51.0f / 255.0f, 113.0f / 255.0f)
+#define PWL_DEFAULT_BACKCOLOR PWL_DEFAULT_SELTEXTCOLOR
+#define PWL_DEFAULT_TEXTCOLOR CPWL_Color(COLORTYPE_RGB, 0, 0, 0)
+#define PWL_DEFAULT_FONTSIZE 9.0f
+#define PWL_DEFAULT_BLACKCOLOR CPWL_Color(COLORTYPE_GRAY, 0)
+#define PWL_DEFAULT_WHITECOLOR CPWL_Color(COLORTYPE_GRAY, 1)
+#define PWL_DEFAULT_HEAVYGRAYCOLOR CPWL_Color(COLORTYPE_GRAY, 0.50)
+#define PWL_DEFAULT_LIGHTGRAYCOLOR CPWL_Color(COLORTYPE_GRAY, 0.75)
+#define PWL_TRIANGLE_HALFLEN 2.0f
+#define PWL_CBBUTTON_TRIANGLE_HALFLEN 3.0f
+#define PWL_INVALIDATE_INFLATE 2
+
+class IPWL_Provider : public CFX_Observable<IPWL_Provider> {
+ public:
+  virtual ~IPWL_Provider() {}
+
+  // get a matrix which map user space to CWnd client space
+  virtual CFX_Matrix GetWindowMatrix(void* pAttachedData) = 0;
+
+  /*
+  0 L"&Undo\tCtrl+Z"
+  1 L"&Redo\tCtrl+Shift+Z"
+  2 L"Cu&t\tCtrl+X"
+  3 L"&Copy\tCtrl+C"
+  4 L"&Paste\tCtrl+V"
+  5 L"&Delete"
+  6  L"&Select All\tCtrl+A"
+  */
+  virtual CFX_WideString LoadPopupMenuString(int32_t nIndex) = 0;
+};
+
+class IPWL_FocusHandler {
+ public:
+  virtual ~IPWL_FocusHandler() {}
+  virtual void OnSetFocus(CPWL_Wnd* pWnd) = 0;
+};
+
+struct PWL_CREATEPARAM {
+ public:
+  PWL_CREATEPARAM();
+  PWL_CREATEPARAM(const PWL_CREATEPARAM& other);
+
+  void Reset() {
+    rcRectWnd.Reset();
+    pSystemHandler = nullptr;
+    pFontMap = nullptr;
+    pProvider.Reset();
+    pFocusHandler = nullptr;
+    dwFlags = 0;
+    sBackgroundColor.Reset();
+    pAttachedWidget.Reset();
+    nBorderStyle = BorderStyle::SOLID;
+    dwBorderWidth = 0;
+    sBorderColor.Reset();
+    sTextColor.Reset();
+    sTextStrokeColor.Reset();
+    nTransparency = 0;
+    fFontSize = 0.0f;
+    sDash.Reset();
+    pAttachedData = nullptr;
+    pParentWnd = nullptr;
+    pMsgControl = nullptr;
+    eCursorType = 0;
+    mtChild.SetIdentity();
+  }
+
+  CFX_FloatRect rcRectWnd;            // required
+  CFX_SystemHandler* pSystemHandler;  // required
+  IPVT_FontMap* pFontMap;             // required
+  IPWL_Provider::ObservedPtr pProvider;  // required
+  IPWL_FocusHandler* pFocusHandler;   // optional
+  uint32_t dwFlags;                   // optional
+  CPWL_Color sBackgroundColor;        // optional
+  CPDFSDK_Widget::ObservedPtr pAttachedWidget;  // required
+  BorderStyle nBorderStyle;           // optional
+  int32_t dwBorderWidth;              // optional
+  CPWL_Color sBorderColor;            // optional
+  CPWL_Color sTextColor;              // optional
+  CPWL_Color sTextStrokeColor;        // optional
+  int32_t nTransparency;              // optional
+  FX_FLOAT fFontSize;                 // optional
+  CPWL_Dash sDash;                    // optional
+  void* pAttachedData;                // optional
+  CPWL_Wnd* pParentWnd;               // ignore
+  CPWL_MsgControl* pMsgControl;       // ignore
+  int32_t eCursorType;                // ignore
+  CFX_Matrix mtChild;                 // ignore
+};
+
+class CPWL_Timer {
+ public:
+  CPWL_Timer(CPWL_TimerHandler* pAttached, CFX_SystemHandler* pSystemHandler);
+  virtual ~CPWL_Timer();
+
+  int32_t SetPWLTimer(int32_t nElapse);
+  void KillPWLTimer();
+  static void TimerProc(int32_t idEvent);
+
+ private:
+  int32_t m_nTimerID;
+  CPWL_TimerHandler* m_pAttached;
+  CFX_SystemHandler* m_pSystemHandler;
+};
+
+class CPWL_TimerHandler {
+ public:
+  CPWL_TimerHandler();
+  virtual ~CPWL_TimerHandler();
+
+  void BeginTimer(int32_t nElapse);
+  void EndTimer();
+  virtual void TimerProc();
+  virtual CFX_SystemHandler* GetSystemHandler() const = 0;
+
+ private:
+  std::unique_ptr<CPWL_Timer> m_pTimer;
+};
+
+class CPWL_Wnd : public CPWL_TimerHandler {
+  friend class CPWL_MsgControl;
+
+ public:
+  CPWL_Wnd();
+  ~CPWL_Wnd() override;
+
+  void Create(const PWL_CREATEPARAM& cp);
+  virtual CFX_ByteString GetClassName() const;
+  void InvalidateFocusHandler(IPWL_FocusHandler* handler);
+  void InvalidateProvider(IPWL_Provider* provider);
+  void Destroy();
+  void Move(const CFX_FloatRect& rcNew, bool bReset, bool bRefresh);
+  virtual void InvalidateRect(CFX_FloatRect* pRect = nullptr);
+
+  void DrawAppearance(CFX_RenderDevice* pDevice, CFX_Matrix* pUser2Device);
+
+  virtual bool OnKeyDown(uint16_t nChar, uint32_t nFlag);
+  virtual bool OnKeyUp(uint16_t nChar, uint32_t nFlag);
+  virtual bool OnChar(uint16_t nChar, uint32_t nFlag);
+  virtual bool OnLButtonDblClk(const CFX_FloatPoint& point, uint32_t nFlag);
+  virtual bool OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag);
+  virtual bool OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag);
+  virtual bool OnMButtonDblClk(const CFX_FloatPoint& point, uint32_t nFlag);
+  virtual bool OnMButtonDown(const CFX_FloatPoint& point, uint32_t nFlag);
+  virtual bool OnMButtonUp(const CFX_FloatPoint& point, uint32_t nFlag);
+  virtual bool OnRButtonDown(const CFX_FloatPoint& point, uint32_t nFlag);
+  virtual bool OnRButtonUp(const CFX_FloatPoint& point, uint32_t nFlag);
+  virtual bool OnMouseMove(const CFX_FloatPoint& point, uint32_t nFlag);
+  virtual bool OnMouseWheel(short zDelta,
+                            const CFX_FloatPoint& point,
+                            uint32_t nFlag);
+
+  virtual void SetFocus();
+  virtual void KillFocus();
+  void SetCapture();
+  void ReleaseCapture();
+
+  virtual void OnNotify(CPWL_Wnd* pWnd,
+                        uint32_t msg,
+                        intptr_t wParam = 0,
+                        intptr_t lParam = 0);
+  virtual void SetTextColor(const CPWL_Color& color);
+  virtual void SetTextStrokeColor(const CPWL_Color& color);
+  virtual void SetVisible(bool bVisible);
+
+  virtual CFX_FloatRect GetFocusRect() const;
+  virtual CPWL_Color GetBackgroundColor() const;
+  virtual CPWL_Color GetBorderColor() const;
+  virtual CPWL_Color GetTextColor() const;
+  virtual CPWL_Color GetTextStrokeColor() const;
+  virtual FX_FLOAT GetFontSize() const;
+  virtual int32_t GetInnerBorderWidth() const;
+  virtual CPWL_Color GetBorderLeftTopColor(BorderStyle nBorderStyle) const;
+  virtual CPWL_Color GetBorderRightBottomColor(BorderStyle nBorderStyle) const;
+
+  virtual void SetFontSize(FX_FLOAT fFontSize);
+
+  void SetBackgroundColor(const CPWL_Color& color);
+  void SetClipRect(const CFX_FloatRect& rect);
+  void SetBorderStyle(BorderStyle eBorderStyle);
+
+  virtual CFX_FloatRect GetWindowRect() const;
+  virtual CFX_FloatRect GetClientRect() const;
+  CFX_FloatPoint GetCenterPoint() const;
+  int32_t GetBorderWidth() const;
+  bool IsVisible() const { return m_bVisible; }
+  bool HasFlag(uint32_t dwFlags) const;
+  void AddFlag(uint32_t dwFlags);
+  void RemoveFlag(uint32_t dwFlags);
+  const CFX_FloatRect& GetClipRect() const;
+  CPWL_Wnd* GetParentWindow() const;
+  BorderStyle GetBorderStyle() const;
+  const CPWL_Dash& GetBorderDash() const;
+  void* GetAttachedData() const;
+
+  bool WndHitTest(const CFX_FloatPoint& point) const;
+  bool ClientHitTest(const CFX_FloatPoint& point) const;
+  bool IsCaptureMouse() const;
+
+  const CPWL_Wnd* GetFocused() const;
+  bool IsFocused() const;
+  bool IsReadOnly() const;
+  CPWL_ScrollBar* GetVScrollBar() const;
+
+  IPVT_FontMap* GetFontMap() const;
+  IPWL_Provider* GetProvider() const;
+  IPWL_FocusHandler* GetFocusHandler() const;
+
+  int32_t GetTransparency();
+  void SetTransparency(int32_t nTransparency);
+
+  CFX_Matrix GetChildToRoot() const;
+  CFX_Matrix GetChildMatrix() const;
+  void SetChildMatrix(const CFX_Matrix& mt);
+  CFX_Matrix GetWindowMatrix() const;
+
+  virtual CFX_FloatPoint ChildToParent(const CFX_FloatPoint& point) const;
+  virtual CFX_FloatRect ChildToParent(const CFX_FloatRect& rect) const;
+  virtual CFX_FloatPoint ParentToChild(const CFX_FloatPoint& point) const;
+  virtual CFX_FloatRect ParentToChild(const CFX_FloatRect& rect) const;
+
+  // those methods only implemented by listctrl item
+  virtual FX_FLOAT GetItemHeight(FX_FLOAT fLimitWidth);
+  virtual FX_FLOAT GetItemLeftMargin();
+  virtual FX_FLOAT GetItemRightMargin();
+
+  void EnableWindow(bool bEnable);
+  bool IsEnabled();
+  virtual void SetCursor();
+
+ protected:
+  // CPWL_TimerHandler
+  CFX_SystemHandler* GetSystemHandler() const override;
+
+  virtual void CreateChildWnd(const PWL_CREATEPARAM& cp);
+  virtual void RePosChildWnd();
+  void GetAppearanceStream(CFX_ByteTextBuf& sAppStream);
+  virtual void GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream);
+  virtual void GetChildAppearanceStream(CFX_ByteTextBuf& sAppStream);
+
+  virtual void DrawThisAppearance(CFX_RenderDevice* pDevice,
+                                  CFX_Matrix* pUser2Device);
+  virtual void DrawChildAppearance(CFX_RenderDevice* pDevice,
+                                   CFX_Matrix* pUser2Device);
+
+  virtual void OnCreate(PWL_CREATEPARAM& cp);
+  virtual void OnCreated();
+  virtual void OnDestroy();
+
+  virtual void OnSetFocus();
+  virtual void OnKillFocus();
+
+  virtual void OnEnabled();
+  virtual void OnDisabled();
+
+  void SetNotifyFlag(bool bNotifying = true) { m_bNotifying = bNotifying; }
+
+  bool IsValid() const;
+  const PWL_CREATEPARAM& GetCreationParam() const;
+  bool IsNotifying() const { return m_bNotifying; }
+
+  void InvalidateRectMove(const CFX_FloatRect& rcOld,
+                          const CFX_FloatRect& rcNew);
+
+  void PWLtoWnd(const CFX_FloatPoint& point, int32_t& x, int32_t& y) const;
+  FX_RECT PWLtoWnd(const CFX_FloatRect& rect) const;
+
+  bool IsWndCaptureMouse(const CPWL_Wnd* pWnd) const;
+  bool IsWndCaptureKeyboard(const CPWL_Wnd* pWnd) const;
+  const CPWL_Wnd* GetRootWnd() const;
+
+  bool IsCTRLpressed(uint32_t nFlag) const;
+  bool IsSHIFTpressed(uint32_t nFlag) const;
+  bool IsALTpressed(uint32_t nFlag) const;
+
+ private:
+  void AddChild(CPWL_Wnd* pWnd);
+  void RemoveChild(CPWL_Wnd* pWnd);
+
+  void CreateScrollBar(const PWL_CREATEPARAM& cp);
+  void CreateVScrollBar(const PWL_CREATEPARAM& cp);
+
+  void AdjustStyle();
+  void CreateMsgControl();
+  void DestroyMsgControl();
+
+  CPWL_MsgControl* GetMsgControl() const;
+
+ protected:
+  std::vector<CPWL_Wnd*> m_Children;
+
+ private:
+  PWL_CREATEPARAM m_sPrivateParam;
+  CPWL_ScrollBar* m_pVScrollBar;
+  CFX_FloatRect m_rcWindow;
+  CFX_FloatRect m_rcClip;
+  bool m_bCreated;
+  bool m_bVisible;
+  bool m_bNotifying;
+  bool m_bEnabled;
+};
+
+#endif  // FPDFSDK_PDFWINDOW_PWL_WND_H_
diff --git a/fpdfsdk/pdfwindow/cpwl_color.h b/fpdfsdk/pdfwindow/cpwl_color.h
new file mode 100644
index 0000000..c1f9e6e
--- /dev/null
+++ b/fpdfsdk/pdfwindow/cpwl_color.h
@@ -0,0 +1,48 @@
+// Copyright 2017 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_PDFWINDOW_CPWL_COLOR_H_
+#define FPDFSDK_PDFWINDOW_CPWL_COLOR_H_
+
+#include "core/fpdfdoc/cpdf_formcontrol.h"
+
+struct CPWL_Color {
+  CPWL_Color(int32_t type = COLORTYPE_TRANSPARENT,
+             FX_FLOAT color1 = 0.0f,
+             FX_FLOAT color2 = 0.0f,
+             FX_FLOAT color3 = 0.0f,
+             FX_FLOAT color4 = 0.0f)
+      : nColorType(type),
+        fColor1(color1),
+        fColor2(color2),
+        fColor3(color3),
+        fColor4(color4) {}
+
+  CPWL_Color(int32_t r, int32_t g, int32_t b)
+      : nColorType(COLORTYPE_RGB),
+        fColor1(r / 255.0f),
+        fColor2(g / 255.0f),
+        fColor3(b / 255.0f),
+        fColor4(0) {}
+
+  void ConvertColorType(int32_t other_nColorType);
+
+  void Reset() {
+    nColorType = COLORTYPE_TRANSPARENT;
+    fColor1 = 0.0f;
+    fColor2 = 0.0f;
+    fColor3 = 0.0f;
+    fColor4 = 0.0f;
+  }
+
+  int32_t nColorType;
+  FX_FLOAT fColor1;
+  FX_FLOAT fColor2;
+  FX_FLOAT fColor3;
+  FX_FLOAT fColor4;
+};
+
+#endif  // FPDFSDK_PDFWINDOW_CPWL_COLOR_H_
diff --git a/fpdfsdk/src/formfiller/FFL_CBA_Fontmap.cpp b/fpdfsdk/src/formfiller/FFL_CBA_Fontmap.cpp
deleted file mode 100644
index 9253563..0000000
--- a/fpdfsdk/src/formfiller/FFL_CBA_Fontmap.cpp
+++ /dev/null
@@ -1,271 +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
-
-#include "fpdfsdk/include/formfiller/FFL_CBA_Fontmap.h"
-
-#include "core/include/fpdfapi/fpdf_page.h"
-#include "fpdfsdk/include/fsdk_baseannot.h"
-
-CBA_FontMap::CBA_FontMap(CPDFSDK_Annot* pAnnot,
-                         IFX_SystemHandler* pSystemHandler)
-    : CPWL_FontMap(pSystemHandler),
-      m_pDocument(NULL),
-      m_pAnnotDict(NULL),
-      m_pDefaultFont(NULL),
-      m_sAPType("N") {
-  CPDF_Page* pPage = pAnnot->GetPDFPage();
-
-  m_pDocument = pPage->m_pDocument;
-  m_pAnnotDict = pAnnot->GetPDFAnnot()->GetAnnotDict();
-  Initialize();
-}
-
-CBA_FontMap::~CBA_FontMap() {}
-
-void CBA_FontMap::Reset() {
-  Empty();
-  m_pDefaultFont = NULL;
-  m_sDefaultFontName = "";
-}
-
-void CBA_FontMap::Initialize() {
-  int32_t nCharset = DEFAULT_CHARSET;
-
-  if (!m_pDefaultFont) {
-    m_pDefaultFont = GetAnnotDefaultFont(m_sDefaultFontName);
-    if (m_pDefaultFont) {
-      if (const CFX_SubstFont* pSubstFont = m_pDefaultFont->GetSubstFont()) {
-        nCharset = pSubstFont->m_Charset;
-      } else {
-        if (m_sDefaultFontName == "Wingdings" ||
-            m_sDefaultFontName == "Wingdings2" ||
-            m_sDefaultFontName == "Wingdings3" ||
-            m_sDefaultFontName == "Webdings")
-          nCharset = SYMBOL_CHARSET;
-        else
-          nCharset = ANSI_CHARSET;
-      }
-      AddFontData(m_pDefaultFont, m_sDefaultFontName, nCharset);
-      AddFontToAnnotDict(m_pDefaultFont, m_sDefaultFontName);
-    }
-  }
-
-  if (nCharset != ANSI_CHARSET)
-    CPWL_FontMap::Initialize();
-}
-
-void CBA_FontMap::SetDefaultFont(CPDF_Font* pFont,
-                                 const CFX_ByteString& sFontName) {
-  ASSERT(pFont != NULL);
-
-  if (m_pDefaultFont)
-    return;
-
-  m_pDefaultFont = pFont;
-  m_sDefaultFontName = sFontName;
-
-  int32_t nCharset = DEFAULT_CHARSET;
-  if (const CFX_SubstFont* pSubstFont = m_pDefaultFont->GetSubstFont())
-    nCharset = pSubstFont->m_Charset;
-  AddFontData(m_pDefaultFont, m_sDefaultFontName, nCharset);
-}
-
-CPDF_Font* CBA_FontMap::FindFontSameCharset(CFX_ByteString& sFontAlias,
-                                            int32_t nCharset) {
-  ASSERT(m_pAnnotDict != NULL);
-
-  if (m_pAnnotDict->GetString("Subtype") == "Widget") {
-    CPDF_Document* pDocument = GetDocument();
-    ASSERT(pDocument != NULL);
-
-    CPDF_Dictionary* pRootDict = pDocument->GetRoot();
-    if (!pRootDict)
-      return NULL;
-
-    CPDF_Dictionary* pAcroFormDict = pRootDict->GetDict("AcroForm");
-    if (!pAcroFormDict)
-      return NULL;
-
-    CPDF_Dictionary* pDRDict = pAcroFormDict->GetDict("DR");
-    if (!pDRDict)
-      return NULL;
-
-    return FindResFontSameCharset(pDRDict, sFontAlias, nCharset);
-  }
-
-  return NULL;
-}
-
-CPDF_Document* CBA_FontMap::GetDocument() {
-  return m_pDocument;
-}
-
-CPDF_Font* CBA_FontMap::FindResFontSameCharset(CPDF_Dictionary* pResDict,
-                                               CFX_ByteString& sFontAlias,
-                                               int32_t nCharset) {
-  if (!pResDict)
-    return NULL;
-
-  CPDF_Document* pDocument = GetDocument();
-  ASSERT(pDocument != NULL);
-
-  CPDF_Dictionary* pFonts = pResDict->GetDict("Font");
-  if (!pFonts)
-    return NULL;
-
-  CPDF_Font* pFind = NULL;
-
-  for (const auto& it : *pFonts) {
-    const CFX_ByteString& csKey = it.first;
-    CPDF_Object* pObj = it.second;
-    if (!pObj)
-      continue;
-
-    CPDF_Dictionary* pElement = ToDictionary(pObj->GetDirect());
-    if (!pElement)
-      continue;
-    if (pElement->GetString("Type") != "Font")
-      continue;
-
-    CPDF_Font* pFont = pDocument->LoadFont(pElement);
-    if (!pFont)
-      continue;
-    const CFX_SubstFont* pSubst = pFont->GetSubstFont();
-    if (!pSubst)
-      continue;
-    if (pSubst->m_Charset == nCharset) {
-      sFontAlias = csKey;
-      pFind = pFont;
-    }
-  }
-  return pFind;
-}
-
-void CBA_FontMap::AddedFont(CPDF_Font* pFont,
-                            const CFX_ByteString& sFontAlias) {
-  AddFontToAnnotDict(pFont, sFontAlias);
-}
-
-void CBA_FontMap::AddFontToAnnotDict(CPDF_Font* pFont,
-                                     const CFX_ByteString& sAlias) {
-  if (!pFont)
-    return;
-
-  ASSERT(m_pAnnotDict != NULL);
-  ASSERT(m_pDocument != NULL);
-
-  CPDF_Dictionary* pAPDict = m_pAnnotDict->GetDict("AP");
-
-  if (!pAPDict) {
-    pAPDict = new CPDF_Dictionary;
-    m_pAnnotDict->SetAt("AP", pAPDict);
-  }
-
-  // to avoid checkbox and radiobutton
-  CPDF_Object* pObject = pAPDict->GetElement(m_sAPType);
-  if (ToDictionary(pObject))
-    return;
-
-  CPDF_Stream* pStream = pAPDict->GetStream(m_sAPType);
-  if (!pStream) {
-    pStream = new CPDF_Stream(NULL, 0, NULL);
-    int32_t objnum = m_pDocument->AddIndirectObject(pStream);
-    pAPDict->SetAtReference(m_sAPType, m_pDocument, objnum);
-  }
-
-  CPDF_Dictionary* pStreamDict = pStream->GetDict();
-
-  if (!pStreamDict) {
-    pStreamDict = new CPDF_Dictionary;
-    pStream->InitStream(NULL, 0, pStreamDict);
-  }
-
-  if (pStreamDict) {
-    CPDF_Dictionary* pStreamResList = pStreamDict->GetDict("Resources");
-    if (!pStreamResList) {
-      pStreamResList = new CPDF_Dictionary();
-      pStreamDict->SetAt("Resources", pStreamResList);
-    }
-
-    if (pStreamResList) {
-      CPDF_Dictionary* pStreamResFontList = pStreamResList->GetDict("Font");
-      if (!pStreamResFontList) {
-        pStreamResFontList = new CPDF_Dictionary;
-        int32_t objnum = m_pDocument->AddIndirectObject(pStreamResFontList);
-        pStreamResList->SetAtReference("Font", m_pDocument, objnum);
-      }
-      if (!pStreamResFontList->KeyExist(sAlias))
-        pStreamResFontList->SetAtReference(sAlias, m_pDocument,
-                                           pFont->GetFontDict());
-    }
-  }
-}
-
-CPDF_Font* CBA_FontMap::GetAnnotDefaultFont(CFX_ByteString& sAlias) {
-  ASSERT(m_pAnnotDict != NULL);
-  ASSERT(m_pDocument != NULL);
-
-  CPDF_Dictionary* pAcroFormDict = NULL;
-
-  FX_BOOL bWidget = (m_pAnnotDict->GetString("Subtype") == "Widget");
-
-  if (bWidget) {
-    if (CPDF_Dictionary* pRootDict = m_pDocument->GetRoot())
-      pAcroFormDict = pRootDict->GetDict("AcroForm");
-  }
-
-  CFX_ByteString sDA;
-  CPDF_Object* pObj;
-  if ((pObj = FPDF_GetFieldAttr(m_pAnnotDict, "DA")))
-    sDA = pObj->GetString();
-
-  if (bWidget) {
-    if (sDA.IsEmpty()) {
-      pObj = FPDF_GetFieldAttr(pAcroFormDict, "DA");
-      sDA = pObj ? pObj->GetString() : CFX_ByteString();
-    }
-  }
-
-  CPDF_Dictionary* pFontDict = NULL;
-
-  if (!sDA.IsEmpty()) {
-    CPDF_SimpleParser syntax(sDA);
-    syntax.FindTagParam("Tf", 2);
-    CFX_ByteString sFontName = syntax.GetWord();
-    sAlias = PDF_NameDecode(sFontName).Mid(1);
-
-    if (CPDF_Dictionary* pDRDict = m_pAnnotDict->GetDict("DR"))
-      if (CPDF_Dictionary* pDRFontDict = pDRDict->GetDict("Font"))
-        pFontDict = pDRFontDict->GetDict(sAlias);
-
-    if (!pFontDict)
-      if (CPDF_Dictionary* pAPDict = m_pAnnotDict->GetDict("AP"))
-        if (CPDF_Dictionary* pNormalDict = pAPDict->GetDict("N"))
-          if (CPDF_Dictionary* pNormalResDict =
-                  pNormalDict->GetDict("Resources"))
-            if (CPDF_Dictionary* pResFontDict = pNormalResDict->GetDict("Font"))
-              pFontDict = pResFontDict->GetDict(sAlias);
-
-    if (bWidget) {
-      if (!pFontDict) {
-        if (pAcroFormDict) {
-          if (CPDF_Dictionary* pDRDict = pAcroFormDict->GetDict("DR"))
-            if (CPDF_Dictionary* pDRFontDict = pDRDict->GetDict("Font"))
-              pFontDict = pDRFontDict->GetDict(sAlias);
-        }
-      }
-    }
-  }
-
-  return pFontDict ? m_pDocument->LoadFont(pFontDict) : nullptr;
-}
-
-void CBA_FontMap::SetAPType(const CFX_ByteString& sAPType) {
-  m_sAPType = sAPType;
-
-  Reset();
-  Initialize();
-}
diff --git a/fpdfsdk/src/formfiller/FFL_CheckBox.cpp b/fpdfsdk/src/formfiller/FFL_CheckBox.cpp
deleted file mode 100644
index c2e1b20..0000000
--- a/fpdfsdk/src/formfiller/FFL_CheckBox.cpp
+++ /dev/null
@@ -1,118 +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
-
-#include "fpdfsdk/include/formfiller/FFL_CheckBox.h"
-
-#include "fpdfsdk/include/formfiller/FFL_FormFiller.h"
-#include "fpdfsdk/include/fsdk_mgr.h"
-#include "fpdfsdk/include/pdfwindow/PWL_SpecialButton.h"
-#include "public/fpdf_fwlevent.h"
-
-CFFL_CheckBox::CFFL_CheckBox(CPDFDoc_Environment* pApp, CPDFSDK_Widget* pWidget)
-    : CFFL_Button(pApp, pWidget) {}
-
-CFFL_CheckBox::~CFFL_CheckBox() {}
-
-CPWL_Wnd* CFFL_CheckBox::NewPDFWindow(const PWL_CREATEPARAM& cp,
-                                      CPDFSDK_PageView* pPageView) {
-  CPWL_CheckBox* pWnd = new CPWL_CheckBox();
-  pWnd->Create(cp);
-  pWnd->SetCheck(m_pWidget->IsChecked());
-  return pWnd;
-}
-
-FX_BOOL CFFL_CheckBox::OnKeyDown(CPDFSDK_Annot* pAnnot,
-                                 FX_UINT nKeyCode,
-                                 FX_UINT nFlags) {
-  switch (nKeyCode) {
-    case FWL_VKEY_Return:
-    case FWL_VKEY_Space:
-      return TRUE;
-    default:
-      return CFFL_FormFiller::OnKeyDown(pAnnot, nKeyCode, nFlags);
-  }
-}
-FX_BOOL CFFL_CheckBox::OnChar(CPDFSDK_Annot* pAnnot,
-                              FX_UINT nChar,
-                              FX_UINT nFlags) {
-  switch (nChar) {
-    case FWL_VKEY_Return:
-    case FWL_VKEY_Space: {
-      CFFL_IFormFiller* pIFormFiller = m_pApp->GetIFormFiller();
-      ASSERT(pIFormFiller);
-
-      CPDFSDK_PageView* pPageView = pAnnot->GetPageView();
-      ASSERT(pPageView);
-
-      FX_BOOL bReset = FALSE;
-      FX_BOOL bExit = FALSE;
-
-      pIFormFiller->OnButtonUp(m_pWidget, pPageView, bReset, bExit, nFlags);
-
-      if (bReset)
-        return TRUE;
-      if (bExit)
-        return TRUE;
-
-      CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
-
-      if (CPWL_CheckBox* pWnd = (CPWL_CheckBox*)GetPDFWindow(pPageView, TRUE))
-        pWnd->SetCheck(!pWnd->IsChecked());
-
-      CommitData(pPageView, nFlags);
-      return TRUE;
-    }
-    default:
-      return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
-  }
-}
-
-FX_BOOL CFFL_CheckBox::OnLButtonUp(CPDFSDK_PageView* pPageView,
-                                   CPDFSDK_Annot* pAnnot,
-                                   FX_UINT nFlags,
-                                   const CPDF_Point& point) {
-  CFFL_Button::OnLButtonUp(pPageView, pAnnot, nFlags, point);
-
-  if (IsValid()) {
-    if (CPWL_CheckBox* pWnd = (CPWL_CheckBox*)GetPDFWindow(pPageView, TRUE)) {
-      CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
-      pWnd->SetCheck(!pWidget->IsChecked());
-    }
-
-    if (!CommitData(pPageView, nFlags))
-      return FALSE;
-  }
-
-  return TRUE;
-}
-
-FX_BOOL CFFL_CheckBox::IsDataChanged(CPDFSDK_PageView* pPageView) {
-  CPWL_CheckBox* pWnd = (CPWL_CheckBox*)GetPDFWindow(pPageView, FALSE);
-  return pWnd && pWnd->IsChecked() != m_pWidget->IsChecked();
-}
-
-void CFFL_CheckBox::SaveData(CPDFSDK_PageView* pPageView) {
-  if (CPWL_CheckBox* pWnd = (CPWL_CheckBox*)GetPDFWindow(pPageView, FALSE)) {
-    FX_BOOL bNewChecked = pWnd->IsChecked();
-
-    if (bNewChecked) {
-      CPDF_FormField* pField = m_pWidget->GetFormField();
-      ASSERT(pField != NULL);
-
-      for (int32_t i = 0, sz = pField->CountControls(); i < sz; i++) {
-        if (CPDF_FormControl* pCtrl = pField->GetControl(i)) {
-          if (pCtrl->IsChecked()) {
-            break;
-          }
-        }
-      }
-    }
-
-    m_pWidget->SetCheck(bNewChecked, FALSE);
-    m_pWidget->UpdateField();
-    SetChangeMark();
-  }
-}
diff --git a/fpdfsdk/src/formfiller/FFL_FormFiller.cpp b/fpdfsdk/src/formfiller/FFL_FormFiller.cpp
deleted file mode 100644
index ce73f7d..0000000
--- a/fpdfsdk/src/formfiller/FFL_FormFiller.cpp
+++ /dev/null
@@ -1,727 +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
-
-#include "fpdfsdk/include/formfiller/FFL_FormFiller.h"
-
-#include "fpdfsdk/include/formfiller/FFL_CBA_Fontmap.h"
-#include "fpdfsdk/include/fsdk_common.h"
-#include "fpdfsdk/include/fsdk_mgr.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
-
-#define GetRed(rgb) ((uint8_t)(rgb))
-#define GetGreen(rgb) ((uint8_t)(((FX_WORD)(rgb)) >> 8))
-#define GetBlue(rgb) ((uint8_t)((rgb) >> 16))
-
-#define FFL_HINT_ELAPSE 800
-
-CFFL_FormFiller::CFFL_FormFiller(CPDFDoc_Environment* pApp,
-                                 CPDFSDK_Annot* pAnnot)
-    : m_pApp(pApp), m_pAnnot(pAnnot), m_bValid(FALSE), m_ptOldPos(0, 0) {
-  m_pWidget = (CPDFSDK_Widget*)pAnnot;
-}
-
-CFFL_FormFiller::~CFFL_FormFiller() {
-  for (const auto& it : m_Maps) {
-    CPWL_Wnd* pWnd = it.second;
-    CFFL_PrivateData* pData = (CFFL_PrivateData*)pWnd->GetAttachedData();
-    pWnd->InvalidateProvider(this);
-    pWnd->Destroy();
-    delete pWnd;
-    delete pData;
-  }
-  m_Maps.clear();
-}
-
-void CFFL_FormFiller::SetWindowRect(CPDFSDK_PageView* pPageView,
-                                    const CPDF_Rect& rcWindow) {
-  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
-    pWnd->Move(CPDF_Rect(rcWindow), TRUE, FALSE);
-  }
-}
-
-CPDF_Rect CFFL_FormFiller::GetWindowRect(CPDFSDK_PageView* pPageView) {
-  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
-    return pWnd->GetWindowRect();
-  }
-
-  return CPDF_Rect(0, 0, 0, 0);
-}
-
-FX_RECT CFFL_FormFiller::GetViewBBox(CPDFSDK_PageView* pPageView,
-                                     CPDFSDK_Annot* pAnnot) {
-  ASSERT(pPageView);
-  ASSERT(pAnnot);
-
-  CPDF_Rect rcAnnot = m_pWidget->GetRect();
-
-  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
-    CPDF_Rect rcWindow = pWnd->GetWindowRect();
-    rcAnnot = PWLtoFFL(rcWindow);
-  }
-
-  CPDF_Rect rcWin = rcAnnot;
-
-  CPDF_Rect rcFocus = GetFocusBox(pPageView);
-  if (!rcFocus.IsEmpty())
-    rcWin.Union(rcFocus);
-
-  CPDF_Rect rect = CPWL_Utils::InflateRect(rcWin, 1);
-
-  return rect.GetOutterRect();
-}
-
-void CFFL_FormFiller::OnDraw(CPDFSDK_PageView* pPageView,
-                             CPDFSDK_Annot* pAnnot,
-                             CFX_RenderDevice* pDevice,
-                             CFX_Matrix* pUser2Device,
-                             FX_DWORD dwFlags) {
-  ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
-
-  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
-    CFX_Matrix mt = GetCurMatrix();
-    mt.Concat(*pUser2Device);
-    pWnd->DrawAppearance(pDevice, &mt);
-  } else {
-    CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
-    if (CFFL_IFormFiller::IsVisible(pWidget))
-      pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
-  }
-}
-
-void CFFL_FormFiller::OnDrawDeactive(CPDFSDK_PageView* pPageView,
-                                     CPDFSDK_Annot* pAnnot,
-                                     CFX_RenderDevice* pDevice,
-                                     CFX_Matrix* pUser2Device,
-                                     FX_DWORD dwFlags) {
-  CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
-  pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
-}
-
-void CFFL_FormFiller::OnCreate(CPDFSDK_Annot* pAnnot) {}
-
-void CFFL_FormFiller::OnLoad(CPDFSDK_Annot* pAnnot) {}
-
-void CFFL_FormFiller::OnDelete(CPDFSDK_Annot* pAnnot) {}
-
-void CFFL_FormFiller::OnMouseEnter(CPDFSDK_PageView* pPageView,
-                                   CPDFSDK_Annot* pAnnot) {}
-
-void CFFL_FormFiller::OnMouseExit(CPDFSDK_PageView* pPageView,
-                                  CPDFSDK_Annot* pAnnot) {
-  EndTimer();
-  ASSERT(m_pWidget);
-}
-
-FX_BOOL CFFL_FormFiller::OnLButtonDown(CPDFSDK_PageView* pPageView,
-                                       CPDFSDK_Annot* pAnnot,
-                                       FX_UINT nFlags,
-                                       const CPDF_Point& point) {
-  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, TRUE)) {
-    m_bValid = TRUE;
-    FX_RECT rect = GetViewBBox(pPageView, pAnnot);
-    InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
-
-    if (!rect.Contains((int)point.x, (int)point.y))
-      return FALSE;
-
-    return pWnd->OnLButtonDown(WndtoPWL(pPageView, point), nFlags);
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CFFL_FormFiller::OnLButtonUp(CPDFSDK_PageView* pPageView,
-                                     CPDFSDK_Annot* pAnnot,
-                                     FX_UINT nFlags,
-                                     const CPDF_Point& point) {
-  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
-    FX_RECT rcFFL = GetViewBBox(pPageView, pAnnot);
-    InvalidateRect(rcFFL.left, rcFFL.top, rcFFL.right, rcFFL.bottom);
-    pWnd->OnLButtonUp(WndtoPWL(pPageView, point), nFlags);
-    return TRUE;
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CFFL_FormFiller::OnLButtonDblClk(CPDFSDK_PageView* pPageView,
-                                         CPDFSDK_Annot* pAnnot,
-                                         FX_UINT nFlags,
-                                         const CPDF_Point& point) {
-  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
-    pWnd->OnLButtonDblClk(WndtoPWL(pPageView, point), nFlags);
-    return TRUE;
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CFFL_FormFiller::OnMouseMove(CPDFSDK_PageView* pPageView,
-                                     CPDFSDK_Annot* pAnnot,
-                                     FX_UINT nFlags,
-                                     const CPDF_Point& point) {
-  if ((m_ptOldPos.x != point.x) || (m_ptOldPos.y != point.y)) {
-    m_ptOldPos = point;
-  }
-
-  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
-    pWnd->OnMouseMove(WndtoPWL(pPageView, point), nFlags);
-    return TRUE;
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CFFL_FormFiller::OnMouseWheel(CPDFSDK_PageView* pPageView,
-                                      CPDFSDK_Annot* pAnnot,
-                                      FX_UINT nFlags,
-                                      short zDelta,
-                                      const CPDF_Point& point) {
-  if (!IsValid())
-    return FALSE;
-
-  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, TRUE)) {
-    return pWnd->OnMouseWheel(zDelta, WndtoPWL(pPageView, point), nFlags);
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CFFL_FormFiller::OnRButtonDown(CPDFSDK_PageView* pPageView,
-                                       CPDFSDK_Annot* pAnnot,
-                                       FX_UINT nFlags,
-                                       const CPDF_Point& point) {
-  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, TRUE)) {
-    pWnd->OnRButtonDown(WndtoPWL(pPageView, point), nFlags);
-    return TRUE;
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CFFL_FormFiller::OnRButtonUp(CPDFSDK_PageView* pPageView,
-                                     CPDFSDK_Annot* pAnnot,
-                                     FX_UINT nFlags,
-                                     const CPDF_Point& point) {
-  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
-    pWnd->OnRButtonUp(WndtoPWL(pPageView, point), nFlags);
-    return TRUE;
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CFFL_FormFiller::OnKeyDown(CPDFSDK_Annot* pAnnot,
-                                   FX_UINT nKeyCode,
-                                   FX_UINT nFlags) {
-  if (IsValid()) {
-    CPDFSDK_PageView* pPageView = GetCurPageView();
-    ASSERT(pPageView);
-
-    if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
-      return pWnd->OnKeyDown(nKeyCode, nFlags);
-    }
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CFFL_FormFiller::OnChar(CPDFSDK_Annot* pAnnot,
-                                FX_UINT nChar,
-                                FX_UINT nFlags) {
-  if (IsValid()) {
-    CPDFSDK_PageView* pPageView = GetCurPageView();
-    ASSERT(pPageView);
-
-    if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
-      return pWnd->OnChar(nChar, nFlags);
-    }
-  }
-
-  return FALSE;
-}
-
-void CFFL_FormFiller::SetFocusForAnnot(CPDFSDK_Annot* pAnnot, FX_UINT nFlag) {
-  CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
-  UnderlyingPageType* pPage = pWidget->GetUnderlyingPage();
-  CPDFSDK_Document* pDoc = m_pApp->GetSDKDocument();
-  CPDFSDK_PageView* pPageView = pDoc->GetPageView(pPage);
-  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, TRUE))
-    pWnd->SetFocus();
-
-  m_bValid = TRUE;
-  FX_RECT rcRect = GetViewBBox(pPageView, pAnnot);
-  InvalidateRect(rcRect.left, rcRect.top, rcRect.right, rcRect.bottom);
-}
-
-void CFFL_FormFiller::KillFocusForAnnot(CPDFSDK_Annot* pAnnot, FX_UINT nFlag) {
-  if (!IsValid())
-    return;
-
-  CPDFSDK_PageView* pPageView = GetCurPageView();
-  if (!pPageView)
-    return;
-
-  CommitData(pPageView, nFlag);
-
-  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE))
-    pWnd->KillFocus();
-
-  FX_BOOL bDestroyPDFWindow;
-  switch (m_pWidget->GetFieldType()) {
-    case FIELDTYPE_PUSHBUTTON:
-    case FIELDTYPE_CHECKBOX:
-    case FIELDTYPE_RADIOBUTTON:
-      bDestroyPDFWindow = TRUE;
-      break;
-    default:
-      bDestroyPDFWindow = FALSE;
-      break;
-  }
-  EscapeFiller(pPageView, bDestroyPDFWindow);
-}
-
-FX_BOOL CFFL_FormFiller::IsValid() const {
-  return m_bValid;
-}
-
-PWL_CREATEPARAM CFFL_FormFiller::GetCreateParam() {
-  ASSERT(m_pApp);
-
-  PWL_CREATEPARAM cp;
-  cp.pParentWnd = NULL;
-  cp.pProvider = this;
-  cp.rcRectWnd = GetPDFWindowRect();
-
-  FX_DWORD dwCreateFlags = PWS_BORDER | PWS_BACKGROUND | PWS_VISIBLE;
-  FX_DWORD dwFieldFlag = m_pWidget->GetFieldFlags();
-  if (dwFieldFlag & FIELDFLAG_READONLY) {
-    dwCreateFlags |= PWS_READONLY;
-  }
-
-  FX_COLORREF color;
-  if (m_pWidget->GetFillColor(color)) {
-    cp.sBackgroundColor =
-        CPWL_Color(GetRed(color), GetGreen(color), GetBlue(color));
-  }
-
-  if (m_pWidget->GetBorderColor(color)) {
-    cp.sBorderColor =
-        CPWL_Color(GetRed(color), GetGreen(color), GetBlue(color));
-  }
-
-  cp.sTextColor = CPWL_Color(COLORTYPE_GRAY, 0);
-
-  if (m_pWidget->GetTextColor(color)) {
-    cp.sTextColor = CPWL_Color(GetRed(color), GetGreen(color), GetBlue(color));
-  }
-
-  cp.fFontSize = m_pWidget->GetFontSize();
-  cp.dwBorderWidth = m_pWidget->GetBorderWidth();
-
-  int nBorderStyle = m_pWidget->GetBorderStyle();
-
-  switch (nBorderStyle) {
-    case BBS_SOLID:
-      cp.nBorderStyle = PBS_SOLID;
-      break;
-    case BBS_DASH:
-      cp.nBorderStyle = PBS_DASH;
-      cp.sDash = CPWL_Dash(3, 3, 0);
-      break;
-    case BBS_BEVELED:
-      cp.nBorderStyle = PBS_BEVELED;
-      cp.dwBorderWidth *= 2;
-      break;
-    case BBS_INSET:
-      cp.nBorderStyle = PBS_INSET;
-      cp.dwBorderWidth *= 2;
-      break;
-    case BBS_UNDERLINE:
-      cp.nBorderStyle = PBS_UNDERLINED;
-      break;
-  }
-
-  if (cp.fFontSize <= 0) {
-    dwCreateFlags |= PWS_AUTOFONTSIZE;
-  }
-
-  cp.dwFlags = dwCreateFlags;
-  cp.pSystemHandler = m_pApp->GetSysHandler();
-  return cp;
-}
-
-CPWL_Wnd* CFFL_FormFiller::GetPDFWindow(CPDFSDK_PageView* pPageView,
-                                        FX_BOOL bNew) {
-  ASSERT(pPageView);
-
-  auto it = m_Maps.find(pPageView);
-  const bool found = it != m_Maps.end();
-  CPWL_Wnd* pWnd = found ? it->second : nullptr;
-  if (!bNew)
-    return pWnd;
-
-  if (found) {
-    CFFL_PrivateData* pPrivateData = (CFFL_PrivateData*)pWnd->GetAttachedData();
-    if (pPrivateData->nWidgetAge != m_pWidget->GetAppearanceAge()) {
-      return ResetPDFWindow(
-          pPageView, m_pWidget->GetValueAge() == pPrivateData->nValueAge);
-    }
-  } else {
-    PWL_CREATEPARAM cp = GetCreateParam();
-    cp.hAttachedWnd = (FX_HWND)m_pWidget;
-
-    CFFL_PrivateData* pPrivateData = new CFFL_PrivateData;
-    pPrivateData->pWidget = m_pWidget;
-    pPrivateData->pPageView = pPageView;
-    pPrivateData->nWidgetAge = m_pWidget->GetAppearanceAge();
-    pPrivateData->nValueAge = 0;
-
-    cp.pAttachedData = pPrivateData;
-
-    pWnd = NewPDFWindow(cp, pPageView);
-    m_Maps[pPageView] = pWnd;
-  }
-
-  return pWnd;
-}
-
-void CFFL_FormFiller::DestroyPDFWindow(CPDFSDK_PageView* pPageView) {
-  auto it = m_Maps.find(pPageView);
-  if (it == m_Maps.end())
-    return;
-
-  CPWL_Wnd* pWnd = it->second;
-  CFFL_PrivateData* pData = (CFFL_PrivateData*)pWnd->GetAttachedData();
-  pWnd->Destroy();
-  delete pWnd;
-  delete pData;
-
-  m_Maps.erase(it);
-}
-
-CFX_Matrix CFFL_FormFiller::GetWindowMatrix(void* pAttachedData) {
-  if (CFFL_PrivateData* pPrivateData = (CFFL_PrivateData*)pAttachedData) {
-    if (pPrivateData->pPageView) {
-      CFX_Matrix mtPageView;
-      pPrivateData->pPageView->GetCurrentMatrix(mtPageView);
-      CFX_Matrix mt = GetCurMatrix();
-      mt.Concat(mtPageView);
-
-      return mt;
-    }
-  }
-  return CFX_Matrix(1, 0, 0, 1, 0, 0);
-}
-
-CFX_Matrix CFFL_FormFiller::GetCurMatrix() {
-  CFX_Matrix mt;
-
-  CPDF_Rect rcDA;
-  m_pWidget->GetPDFAnnot()->GetRect(rcDA);
-
-  switch (m_pWidget->GetRotate()) {
-    default:
-    case 0:
-      mt = CFX_Matrix(1, 0, 0, 1, 0, 0);
-      break;
-    case 90:
-      mt = CFX_Matrix(0, 1, -1, 0, rcDA.right - rcDA.left, 0);
-      break;
-    case 180:
-      mt = CFX_Matrix(-1, 0, 0, -1, rcDA.right - rcDA.left,
-                      rcDA.top - rcDA.bottom);
-      break;
-    case 270:
-      mt = CFX_Matrix(0, -1, 1, 0, 0, rcDA.top - rcDA.bottom);
-      break;
-  }
-  mt.e += rcDA.left;
-  mt.f += rcDA.bottom;
-
-  return mt;
-}
-
-CFX_WideString CFFL_FormFiller::LoadPopupMenuString(int nIndex) {
-  ASSERT(m_pApp);
-
-  return L"";
-}
-
-CPDF_Rect CFFL_FormFiller::GetPDFWindowRect() const {
-  CPDF_Rect rectAnnot;
-  m_pWidget->GetPDFAnnot()->GetRect(rectAnnot);
-
-  FX_FLOAT fWidth = rectAnnot.right - rectAnnot.left;
-  FX_FLOAT fHeight = rectAnnot.top - rectAnnot.bottom;
-  if ((m_pWidget->GetRotate() / 90) & 0x01)
-    return CPDF_Rect(0, 0, fHeight, fWidth);
-
-  return CPDF_Rect(0, 0, fWidth, fHeight);
-}
-
-CPDFSDK_PageView* CFFL_FormFiller::GetCurPageView() {
-  UnderlyingPageType* pPage = m_pAnnot->GetUnderlyingPage();
-  CPDFSDK_Document* pSDKDoc = m_pApp->GetSDKDocument();
-  return pSDKDoc ? pSDKDoc->GetPageView(pPage) : nullptr;
-}
-
-CPDF_Rect CFFL_FormFiller::GetFocusBox(CPDFSDK_PageView* pPageView) {
-  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE)) {
-    CPDF_Rect rcFocus = FFLtoWnd(pPageView, PWLtoFFL(pWnd->GetFocusRect()));
-    CPDF_Rect rcPage = pPageView->GetPDFPage()->GetPageBBox();
-    if (rcPage.Contains(rcFocus))
-      return rcFocus;
-  }
-  return CPDF_Rect(0, 0, 0, 0);
-}
-
-CPDF_Rect CFFL_FormFiller::FFLtoPWL(const CPDF_Rect& rect) {
-  CFX_Matrix mt;
-  mt.SetReverse(GetCurMatrix());
-
-  CPDF_Rect temp = rect;
-  mt.TransformRect(temp);
-
-  return temp;
-}
-
-CPDF_Rect CFFL_FormFiller::PWLtoFFL(const CPDF_Rect& rect) {
-  CFX_Matrix mt = GetCurMatrix();
-
-  CPDF_Rect temp = rect;
-  mt.TransformRect(temp);
-
-  return temp;
-}
-
-CPDF_Point CFFL_FormFiller::FFLtoPWL(const CPDF_Point& point) {
-  CFX_Matrix mt;
-  mt.SetReverse(GetCurMatrix());
-
-  CPDF_Point pt = point;
-  mt.Transform(pt.x, pt.y);
-
-  return pt;
-}
-
-CPDF_Point CFFL_FormFiller::PWLtoFFL(const CPDF_Point& point) {
-  CFX_Matrix mt = GetCurMatrix();
-
-  CPDF_Point pt = point;
-  mt.Transform(pt.x, pt.y);
-
-  return pt;
-}
-
-CPDF_Point CFFL_FormFiller::WndtoPWL(CPDFSDK_PageView* pPageView,
-                                     const CPDF_Point& pt) {
-  return FFLtoPWL(pt);
-}
-
-CPDF_Rect CFFL_FormFiller::FFLtoWnd(CPDFSDK_PageView* pPageView,
-                                    const CPDF_Rect& rect) {
-  return rect;
-}
-
-FX_BOOL CFFL_FormFiller::CommitData(CPDFSDK_PageView* pPageView,
-                                    FX_UINT nFlag) {
-  if (IsDataChanged(pPageView)) {
-    FX_BOOL bRC = TRUE;
-    FX_BOOL bExit = FALSE;
-    CFFL_IFormFiller* pIFormFiller = m_pApp->GetIFormFiller();
-    pIFormFiller->OnKeyStrokeCommit(m_pWidget, pPageView, bRC, bExit, nFlag);
-    if (bExit)
-      return TRUE;
-    if (!bRC) {
-      ResetPDFWindow(pPageView, FALSE);
-      return TRUE;
-    }
-
-    pIFormFiller->OnValidate(m_pWidget, pPageView, bRC, bExit, nFlag);
-    if (bExit)
-      return TRUE;
-    if (!bRC) {
-      ResetPDFWindow(pPageView, FALSE);
-      return TRUE;
-    }
-
-    SaveData(pPageView);
-    pIFormFiller->OnCalculate(m_pWidget, pPageView, bExit, nFlag);
-    if (bExit)
-      return TRUE;
-
-    pIFormFiller->OnFormat(m_pWidget, pPageView, bExit, nFlag);
-  }
-  return TRUE;
-}
-
-FX_BOOL CFFL_FormFiller::IsDataChanged(CPDFSDK_PageView* pPageView) {
-  return FALSE;
-}
-
-void CFFL_FormFiller::SaveData(CPDFSDK_PageView* pPageView) {}
-
-#ifdef PDF_ENABLE_XFA
-FX_BOOL CFFL_FormFiller::IsFieldFull(CPDFSDK_PageView* pPageView) {
-  return FALSE;
-}
-#endif  // PDF_ENABLE_XFA
-
-void CFFL_FormFiller::SetChangeMark() {
-  m_pApp->FFI_OnChange();
-}
-
-void CFFL_FormFiller::GetActionData(CPDFSDK_PageView* pPageView,
-                                    CPDF_AAction::AActionType type,
-                                    PDFSDK_FieldAction& fa) {
-  fa.sValue = m_pWidget->GetValue();
-}
-
-void CFFL_FormFiller::SetActionData(CPDFSDK_PageView* pPageView,
-                                    CPDF_AAction::AActionType type,
-                                    const PDFSDK_FieldAction& fa) {}
-
-FX_BOOL CFFL_FormFiller::IsActionDataChanged(CPDF_AAction::AActionType type,
-                                             const PDFSDK_FieldAction& faOld,
-                                             const PDFSDK_FieldAction& faNew) {
-  return FALSE;
-}
-
-void CFFL_FormFiller::SaveState(CPDFSDK_PageView* pPageView) {}
-
-void CFFL_FormFiller::RestoreState(CPDFSDK_PageView* pPageView) {}
-
-CPWL_Wnd* CFFL_FormFiller::ResetPDFWindow(CPDFSDK_PageView* pPageView,
-                                          FX_BOOL bRestoreValue) {
-  return GetPDFWindow(pPageView, FALSE);
-}
-
-void CFFL_FormFiller::TimerProc() {}
-
-IFX_SystemHandler* CFFL_FormFiller::GetSystemHandler() const {
-  return m_pApp->GetSysHandler();
-}
-
-void CFFL_FormFiller::EscapeFiller(CPDFSDK_PageView* pPageView,
-                                   FX_BOOL bDestroyPDFWindow) {
-  m_bValid = FALSE;
-
-  FX_RECT rcRect = GetViewBBox(pPageView, m_pWidget);
-  InvalidateRect(rcRect.left, rcRect.top, rcRect.right, rcRect.bottom);
-
-  if (bDestroyPDFWindow)
-    DestroyPDFWindow(pPageView);
-}
-
-void CFFL_FormFiller::InvalidateRect(double left,
-                                     double top,
-                                     double right,
-                                     double bottom) {
-  UnderlyingPageType* pPage = m_pWidget->GetUnderlyingPage();
-  m_pApp->FFI_Invalidate(pPage, left, top, right, bottom);
-}
-
-CFFL_Button::CFFL_Button(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pWidget)
-    : CFFL_FormFiller(pApp, pWidget), m_bMouseIn(FALSE), m_bMouseDown(FALSE) {}
-
-CFFL_Button::~CFFL_Button() {}
-
-void CFFL_Button::OnMouseEnter(CPDFSDK_PageView* pPageView,
-                               CPDFSDK_Annot* pAnnot) {
-  m_bMouseIn = TRUE;
-  FX_RECT rect = GetViewBBox(pPageView, pAnnot);
-  InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
-}
-
-void CFFL_Button::OnMouseExit(CPDFSDK_PageView* pPageView,
-                              CPDFSDK_Annot* pAnnot) {
-  m_bMouseIn = FALSE;
-
-  FX_RECT rect = GetViewBBox(pPageView, pAnnot);
-  InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
-  EndTimer();
-  ASSERT(m_pWidget);
-}
-
-FX_BOOL CFFL_Button::OnLButtonDown(CPDFSDK_PageView* pPageView,
-                                   CPDFSDK_Annot* pAnnot,
-                                   FX_UINT nFlags,
-                                   const CPDF_Point& point) {
-  CPDF_Rect rcAnnot = pAnnot->GetRect();
-  if (!rcAnnot.Contains(point.x, point.y))
-    return FALSE;
-
-  m_bMouseDown = TRUE;
-  m_bValid = TRUE;
-  FX_RECT rect = GetViewBBox(pPageView, pAnnot);
-  InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
-  return TRUE;
-}
-
-FX_BOOL CFFL_Button::OnLButtonUp(CPDFSDK_PageView* pPageView,
-                                 CPDFSDK_Annot* pAnnot,
-                                 FX_UINT nFlags,
-                                 const CPDF_Point& point) {
-  CPDF_Rect rcAnnot = pAnnot->GetRect();
-  if (!rcAnnot.Contains(point.x, point.y))
-    return FALSE;
-
-  m_bMouseDown = FALSE;
-  m_pWidget->GetPDFPage();
-
-  FX_RECT rect = GetViewBBox(pPageView, pAnnot);
-  InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
-  return TRUE;
-}
-
-FX_BOOL CFFL_Button::OnMouseMove(CPDFSDK_PageView* pPageView,
-                                 CPDFSDK_Annot* pAnnot,
-                                 FX_UINT nFlags,
-                                 const CPDF_Point& point) {
-  ASSERT(m_pApp);
-
-  return TRUE;
-}
-
-void CFFL_Button::OnDraw(CPDFSDK_PageView* pPageView,
-                         CPDFSDK_Annot* pAnnot,
-                         CFX_RenderDevice* pDevice,
-                         CFX_Matrix* pUser2Device,
-                         FX_DWORD dwFlags) {
-  ASSERT(pPageView);
-  CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
-  CPDF_FormControl* pCtrl = pWidget->GetFormControl();
-  CPDF_FormControl::HighlightingMode eHM = pCtrl->GetHighlightingMode();
-
-  if (eHM != CPDF_FormControl::Push) {
-    pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
-    return;
-  }
-
-  if (m_bMouseDown) {
-    if (pWidget->IsWidgetAppearanceValid(CPDF_Annot::Down))
-      pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Down, NULL);
-    else
-      pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
-  } else if (m_bMouseIn) {
-    if (pWidget->IsWidgetAppearanceValid(CPDF_Annot::Rollover))
-      pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Rollover,
-                              NULL);
-    else
-      pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
-  } else {
-    pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
-  }
-}
-
-void CFFL_Button::OnDrawDeactive(CPDFSDK_PageView* pPageView,
-                                 CPDFSDK_Annot* pAnnot,
-                                 CFX_RenderDevice* pDevice,
-                                 CFX_Matrix* pUser2Device,
-                                 FX_DWORD dwFlags) {
-  OnDraw(pPageView, pAnnot, pDevice, pUser2Device, dwFlags);
-}
diff --git a/fpdfsdk/src/formfiller/FFL_IFormFiller.cpp b/fpdfsdk/src/formfiller/FFL_IFormFiller.cpp
deleted file mode 100644
index 36b123e..0000000
--- a/fpdfsdk/src/formfiller/FFL_IFormFiller.cpp
+++ /dev/null
@@ -1,1024 +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
-
-#include "fpdfsdk/include/formfiller/FFL_IFormFiller.h"
-
-#include "fpdfsdk/include/formfiller/FFL_CheckBox.h"
-#include "fpdfsdk/include/formfiller/FFL_ComboBox.h"
-#include "fpdfsdk/include/formfiller/FFL_FormFiller.h"
-#include "fpdfsdk/include/formfiller/FFL_ListBox.h"
-#include "fpdfsdk/include/formfiller/FFL_PushButton.h"
-#include "fpdfsdk/include/formfiller/FFL_RadioButton.h"
-#include "fpdfsdk/include/formfiller/FFL_TextField.h"
-#include "fpdfsdk/include/fsdk_mgr.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
-
-#define FFL_MAXLISTBOXHEIGHT 140.0f
-
-CFFL_IFormFiller::CFFL_IFormFiller(CPDFDoc_Environment* pApp)
-    : m_pApp(pApp), m_bNotifying(FALSE) {}
-
-CFFL_IFormFiller::~CFFL_IFormFiller() {
-  for (auto& it : m_Maps)
-    delete it.second;
-  m_Maps.clear();
-}
-
-FX_BOOL CFFL_IFormFiller::Annot_HitTest(CPDFSDK_PageView* pPageView,
-                                        CPDFSDK_Annot* pAnnot,
-                                        CPDF_Point point) {
-  CPDF_Rect rc = pAnnot->GetRect();
-  if (rc.Contains(point.x, point.y))
-    return TRUE;
-  return FALSE;
-}
-
-FX_RECT CFFL_IFormFiller::GetViewBBox(CPDFSDK_PageView* pPageView,
-                                      CPDFSDK_Annot* pAnnot) {
-  if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
-    return pFormFiller->GetViewBBox(pPageView, pAnnot);
-
-  ASSERT(pPageView);
-
-  CPDF_Annot* pPDFAnnot = pAnnot->GetPDFAnnot();
-  CPDF_Rect rcAnnot;
-  pPDFAnnot->GetRect(rcAnnot);
-
-  CPDF_Rect rcWin = CPWL_Utils::InflateRect(rcAnnot, 1);
-  return rcWin.GetOutterRect();
-}
-
-void CFFL_IFormFiller::OnDraw(CPDFSDK_PageView* pPageView,
-                              CPDFSDK_Annot* pAnnot,
-                              CFX_RenderDevice* pDevice,
-                              CFX_Matrix* pUser2Device,
-                              FX_DWORD dwFlags) {
-  ASSERT(pPageView);
-  CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
-
-  if (IsVisible(pWidget)) {
-    if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
-      if (pFormFiller->IsValid()) {
-        pFormFiller->OnDraw(pPageView, pAnnot, pDevice, pUser2Device, dwFlags);
-        pAnnot->GetPDFPage();
-
-        CPDFSDK_Document* pDocument = m_pApp->GetSDKDocument();
-        if (pDocument->GetFocusAnnot() == pAnnot) {
-          CPDF_Rect rcFocus = pFormFiller->GetFocusBox(pPageView);
-          if (!rcFocus.IsEmpty()) {
-            CFX_PathData path;
-            path.SetPointCount(5);
-            path.SetPoint(0, rcFocus.left, rcFocus.top, FXPT_MOVETO);
-            path.SetPoint(1, rcFocus.left, rcFocus.bottom, FXPT_LINETO);
-            path.SetPoint(2, rcFocus.right, rcFocus.bottom, FXPT_LINETO);
-            path.SetPoint(3, rcFocus.right, rcFocus.top, FXPT_LINETO);
-            path.SetPoint(4, rcFocus.left, rcFocus.top, FXPT_LINETO);
-
-            CFX_GraphStateData gsd;
-            gsd.SetDashCount(1);
-            gsd.m_DashArray[0] = 1.0f;
-            gsd.m_DashPhase = 0;
-            gsd.m_LineWidth = 1.0f;
-            pDevice->DrawPath(&path, pUser2Device, &gsd, 0,
-                              ArgbEncode(255, 0, 0, 0), FXFILL_ALTERNATE);
-          }
-        }
-        return;
-      }
-    }
-
-    if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
-      pFormFiller->OnDrawDeactive(pPageView, pAnnot, pDevice, pUser2Device,
-                                  dwFlags);
-    else
-      pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
-
-    if (!IsReadOnly(pWidget) && IsFillingAllowed(pWidget))
-      pWidget->DrawShadow(pDevice, pPageView);
-  }
-}
-
-void CFFL_IFormFiller::OnCreate(CPDFSDK_Annot* pAnnot) {
-  if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
-    pFormFiller->OnCreate(pAnnot);
-  }
-}
-
-void CFFL_IFormFiller::OnLoad(CPDFSDK_Annot* pAnnot) {
-  if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
-    pFormFiller->OnLoad(pAnnot);
-  }
-}
-
-void CFFL_IFormFiller::OnDelete(CPDFSDK_Annot* pAnnot) {
-  if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
-    pFormFiller->OnDelete(pAnnot);
-  }
-
-  UnRegisterFormFiller(pAnnot);
-}
-
-void CFFL_IFormFiller::OnMouseEnter(CPDFSDK_PageView* pPageView,
-                                    CPDFSDK_Annot* pAnnot,
-                                    FX_UINT nFlag) {
-  ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
-
-  if (!m_bNotifying) {
-    CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
-    if (pWidget->GetAAction(CPDF_AAction::CursorEnter)) {
-      m_bNotifying = TRUE;
-
-      int nValueAge = pWidget->GetValueAge();
-
-      pWidget->ClearAppModified();
-
-      ASSERT(pPageView);
-
-      PDFSDK_FieldAction fa;
-      fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
-      fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
-      pWidget->OnAAction(CPDF_AAction::CursorEnter, fa, pPageView);
-      m_bNotifying = FALSE;
-
-      if (pWidget->IsAppModified()) {
-        if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE)) {
-          pFormFiller->ResetPDFWindow(pPageView,
-                                      pWidget->GetValueAge() == nValueAge);
-        }
-      }
-    }
-  }
-
-  if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, TRUE)) {
-    pFormFiller->OnMouseEnter(pPageView, pAnnot);
-  }
-}
-
-void CFFL_IFormFiller::OnMouseExit(CPDFSDK_PageView* pPageView,
-                                   CPDFSDK_Annot* pAnnot,
-                                   FX_UINT nFlag) {
-  ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
-
-  if (!m_bNotifying) {
-    CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
-    if (pWidget->GetAAction(CPDF_AAction::CursorExit)) {
-      m_bNotifying = TRUE;
-      pWidget->GetAppearanceAge();
-      int nValueAge = pWidget->GetValueAge();
-      pWidget->ClearAppModified();
-
-      ASSERT(pPageView);
-
-      PDFSDK_FieldAction fa;
-      fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
-      fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
-
-      pWidget->OnAAction(CPDF_AAction::CursorExit, fa, pPageView);
-      m_bNotifying = FALSE;
-
-      if (pWidget->IsAppModified()) {
-        if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE)) {
-          pFormFiller->ResetPDFWindow(pPageView,
-                                      nValueAge == pWidget->GetValueAge());
-        }
-      }
-    }
-  }
-
-  if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
-    pFormFiller->OnMouseExit(pPageView, pAnnot);
-  }
-}
-
-FX_BOOL CFFL_IFormFiller::OnLButtonDown(CPDFSDK_PageView* pPageView,
-                                        CPDFSDK_Annot* pAnnot,
-                                        FX_UINT nFlags,
-                                        const CPDF_Point& point) {
-  ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
-
-  if (!m_bNotifying) {
-    CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
-    if (Annot_HitTest(pPageView, pAnnot, point) &&
-        pWidget->GetAAction(CPDF_AAction::ButtonDown)) {
-      m_bNotifying = TRUE;
-      pWidget->GetAppearanceAge();
-      int nValueAge = pWidget->GetValueAge();
-      pWidget->ClearAppModified();
-
-      ASSERT(pPageView);
-
-      PDFSDK_FieldAction fa;
-      fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlags);
-      fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlags);
-      pWidget->OnAAction(CPDF_AAction::ButtonDown, fa, pPageView);
-      m_bNotifying = FALSE;
-
-      if (!IsValidAnnot(pPageView, pAnnot))
-        return TRUE;
-
-      if (pWidget->IsAppModified()) {
-        if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE)) {
-          pFormFiller->ResetPDFWindow(pPageView,
-                                      nValueAge == pWidget->GetValueAge());
-        }
-      }
-    }
-  }
-
-  if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
-    return pFormFiller->OnLButtonDown(pPageView, pAnnot, nFlags, point);
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CFFL_IFormFiller::OnLButtonUp(CPDFSDK_PageView* pPageView,
-                                      CPDFSDK_Annot* pAnnot,
-                                      FX_UINT nFlags,
-                                      const CPDF_Point& point) {
-  ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
-  CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
-  CPDFSDK_Document* pDocument = m_pApp->GetSDKDocument();
-
-  switch (pWidget->GetFieldType()) {
-    case FIELDTYPE_PUSHBUTTON:
-    case FIELDTYPE_CHECKBOX:
-    case FIELDTYPE_RADIOBUTTON:
-      if (GetViewBBox(pPageView, pAnnot).Contains((int)point.x, (int)point.y))
-        pDocument->SetFocusAnnot(pAnnot);
-      break;
-    default:
-      pDocument->SetFocusAnnot(pAnnot);
-      break;
-  }
-
-  FX_BOOL bRet = FALSE;
-
-  if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
-    bRet = pFormFiller->OnLButtonUp(pPageView, pAnnot, nFlags, point);
-  }
-
-  if (pDocument->GetFocusAnnot() == pAnnot) {
-    FX_BOOL bExit = FALSE;
-    FX_BOOL bReset = FALSE;
-    OnButtonUp(pWidget, pPageView, bReset, bExit, nFlags);
-    if (bExit)
-      return TRUE;
-#ifdef PDF_ENABLE_XFA
-    OnClick(pWidget, pPageView, bReset, bExit, nFlags);
-    if (bExit)
-      return TRUE;
-#endif  // PDF_ENABLE_XFA
-  }
-  return bRet;
-}
-
-void CFFL_IFormFiller::OnButtonUp(CPDFSDK_Widget* pWidget,
-                                  CPDFSDK_PageView* pPageView,
-                                  FX_BOOL& bReset,
-                                  FX_BOOL& bExit,
-                                  FX_UINT nFlag) {
-  ASSERT(pWidget);
-
-  if (!m_bNotifying) {
-    if (pWidget->GetAAction(CPDF_AAction::ButtonUp)) {
-      m_bNotifying = TRUE;
-      int nAge = pWidget->GetAppearanceAge();
-      int nValueAge = pWidget->GetValueAge();
-
-      ASSERT(pPageView);
-
-      PDFSDK_FieldAction fa;
-      fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
-      fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
-
-      pWidget->OnAAction(CPDF_AAction::ButtonUp, fa, pPageView);
-      m_bNotifying = FALSE;
-
-      if (!IsValidAnnot(pPageView, pWidget)) {
-        bExit = TRUE;
-        return;
-      }
-
-      if (nAge != pWidget->GetAppearanceAge()) {
-        if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE)) {
-          pFormFiller->ResetPDFWindow(pPageView,
-                                      nValueAge == pWidget->GetValueAge());
-        }
-
-        bReset = TRUE;
-      }
-    }
-  }
-}
-
-FX_BOOL CFFL_IFormFiller::OnLButtonDblClk(CPDFSDK_PageView* pPageView,
-                                          CPDFSDK_Annot* pAnnot,
-                                          FX_UINT nFlags,
-                                          const CPDF_Point& point) {
-  ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
-
-  if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
-    return pFormFiller->OnLButtonDblClk(pPageView, pAnnot, nFlags, point);
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CFFL_IFormFiller::OnMouseMove(CPDFSDK_PageView* pPageView,
-                                      CPDFSDK_Annot* pAnnot,
-                                      FX_UINT nFlags,
-                                      const CPDF_Point& point) {
-  ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
-
-  // change cursor
-  if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, TRUE)) {
-    return pFormFiller->OnMouseMove(pPageView, pAnnot, nFlags, point);
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CFFL_IFormFiller::OnMouseWheel(CPDFSDK_PageView* pPageView,
-                                       CPDFSDK_Annot* pAnnot,
-                                       FX_UINT nFlags,
-                                       short zDelta,
-                                       const CPDF_Point& point) {
-  ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
-
-  if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
-    return pFormFiller->OnMouseWheel(pPageView, pAnnot, nFlags, zDelta, point);
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CFFL_IFormFiller::OnRButtonDown(CPDFSDK_PageView* pPageView,
-                                        CPDFSDK_Annot* pAnnot,
-                                        FX_UINT nFlags,
-                                        const CPDF_Point& point) {
-  ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
-
-  if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
-    return pFormFiller->OnRButtonDown(pPageView, pAnnot, nFlags, point);
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CFFL_IFormFiller::OnRButtonUp(CPDFSDK_PageView* pPageView,
-                                      CPDFSDK_Annot* pAnnot,
-                                      FX_UINT nFlags,
-                                      const CPDF_Point& point) {
-  ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
-
-  if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
-    return pFormFiller->OnRButtonUp(pPageView, pAnnot, nFlags, point);
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CFFL_IFormFiller::OnKeyDown(CPDFSDK_Annot* pAnnot,
-                                    FX_UINT nKeyCode,
-                                    FX_UINT nFlags) {
-  ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
-
-  if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
-    return pFormFiller->OnKeyDown(pAnnot, nKeyCode, nFlags);
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CFFL_IFormFiller::OnChar(CPDFSDK_Annot* pAnnot,
-                                 FX_UINT nChar,
-                                 FX_UINT nFlags) {
-  ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
-  if (nChar == FWL_VKEY_Tab)
-    return TRUE;
-
-  if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
-    return pFormFiller->OnChar(pAnnot, nChar, nFlags);
-
-  return FALSE;
-}
-
-FX_BOOL CFFL_IFormFiller::OnSetFocus(CPDFSDK_Annot* pAnnot, FX_UINT nFlag) {
-  if (!pAnnot)
-    return FALSE;
-
-  ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
-
-  if (!m_bNotifying) {
-    CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
-    if (pWidget->GetAAction(CPDF_AAction::GetFocus)) {
-      m_bNotifying = TRUE;
-      pWidget->GetAppearanceAge();
-
-      int nValueAge = pWidget->GetValueAge();
-      pWidget->ClearAppModified();
-
-      CPDFSDK_PageView* pPageView = pAnnot->GetPageView();
-      ASSERT(pPageView);
-
-      PDFSDK_FieldAction fa;
-      fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
-      fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
-
-      CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, TRUE);
-      if (!pFormFiller)
-        return FALSE;
-      pFormFiller->GetActionData(pPageView, CPDF_AAction::GetFocus, fa);
-      pWidget->OnAAction(CPDF_AAction::GetFocus, fa, pPageView);
-      m_bNotifying = FALSE;
-
-      if (pWidget->IsAppModified()) {
-        if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE)) {
-          pFormFiller->ResetPDFWindow(pPageView,
-                                      nValueAge == pWidget->GetValueAge());
-        }
-      }
-    }
-  }
-
-  if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, TRUE))
-    pFormFiller->SetFocusForAnnot(pAnnot, nFlag);
-
-  return TRUE;
-}
-
-FX_BOOL CFFL_IFormFiller::OnKillFocus(CPDFSDK_Annot* pAnnot, FX_UINT nFlag) {
-  if (!pAnnot)
-    return FALSE;
-  ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
-
-  if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE)) {
-    pFormFiller->KillFocusForAnnot(pAnnot, nFlag);
-
-    if (!m_bNotifying) {
-      CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
-      if (pWidget->GetAAction(CPDF_AAction::LoseFocus)) {
-        m_bNotifying = TRUE;
-        pWidget->ClearAppModified();
-
-        CPDFSDK_PageView* pPageView = pWidget->GetPageView();
-        ASSERT(pPageView);
-
-        PDFSDK_FieldAction fa;
-        fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
-        fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
-
-        pFormFiller->GetActionData(pPageView, CPDF_AAction::LoseFocus, fa);
-
-        pWidget->OnAAction(CPDF_AAction::LoseFocus, fa, pPageView);
-        m_bNotifying = FALSE;
-      }
-    }
-  }
-
-  return TRUE;
-}
-
-FX_BOOL CFFL_IFormFiller::IsVisible(CPDFSDK_Widget* pWidget) {
-  return pWidget->IsVisible();
-}
-
-FX_BOOL CFFL_IFormFiller::IsReadOnly(CPDFSDK_Widget* pWidget) {
-  int nFieldFlags = pWidget->GetFieldFlags();
-  return (nFieldFlags & FIELDFLAG_READONLY) == FIELDFLAG_READONLY;
-}
-
-FX_BOOL CFFL_IFormFiller::IsFillingAllowed(CPDFSDK_Widget* pWidget) {
-  if (pWidget->GetFieldType() == FIELDTYPE_PUSHBUTTON)
-    return TRUE;
-
-  CPDF_Page* pPage = pWidget->GetPDFPage();
-  CPDF_Document* pDocument = pPage->m_pDocument;
-  FX_DWORD dwPermissions = pDocument->GetUserPermissions();
-  return (dwPermissions & FPDFPERM_FILL_FORM) ||
-         (dwPermissions & FPDFPERM_ANNOT_FORM) ||
-         (dwPermissions & FPDFPERM_MODIFY);
-}
-
-CFFL_FormFiller* CFFL_IFormFiller::GetFormFiller(CPDFSDK_Annot* pAnnot,
-                                                 FX_BOOL bRegister) {
-  auto it = m_Maps.find(pAnnot);
-  if (it != m_Maps.end())
-    return it->second;
-
-  if (!bRegister)
-    return nullptr;
-
-  CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
-  int nFieldType = pWidget->GetFieldType();
-  CFFL_FormFiller* pFormFiller;
-  switch (nFieldType) {
-    case FIELDTYPE_PUSHBUTTON:
-      pFormFiller = new CFFL_PushButton(m_pApp, pWidget);
-      break;
-    case FIELDTYPE_CHECKBOX:
-      pFormFiller = new CFFL_CheckBox(m_pApp, pWidget);
-      break;
-    case FIELDTYPE_RADIOBUTTON:
-      pFormFiller = new CFFL_RadioButton(m_pApp, pWidget);
-      break;
-    case FIELDTYPE_TEXTFIELD:
-      pFormFiller = new CFFL_TextField(m_pApp, pWidget);
-      break;
-    case FIELDTYPE_LISTBOX:
-      pFormFiller = new CFFL_ListBox(m_pApp, pWidget);
-      break;
-    case FIELDTYPE_COMBOBOX:
-      pFormFiller = new CFFL_ComboBox(m_pApp, pWidget);
-      break;
-    case FIELDTYPE_UNKNOWN:
-    default:
-      pFormFiller = nullptr;
-      break;
-  }
-
-  if (!pFormFiller)
-    return nullptr;
-
-  m_Maps[pAnnot] = pFormFiller;
-  return pFormFiller;
-}
-
-void CFFL_IFormFiller::RemoveFormFiller(CPDFSDK_Annot* pAnnot) {
-  if (pAnnot) {
-    UnRegisterFormFiller(pAnnot);
-  }
-}
-
-void CFFL_IFormFiller::UnRegisterFormFiller(CPDFSDK_Annot* pAnnot) {
-  auto it = m_Maps.find(pAnnot);
-  if (it == m_Maps.end())
-    return;
-
-  delete it->second;
-  m_Maps.erase(it);
-}
-
-void CFFL_IFormFiller::QueryWherePopup(void* pPrivateData,
-                                       FX_FLOAT fPopupMin,
-                                       FX_FLOAT fPopupMax,
-                                       int32_t& nRet,
-                                       FX_FLOAT& fPopupRet) {
-  CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
-
-  CPDF_Rect rcPageView(0, 0, 0, 0);
-  rcPageView.right = pData->pWidget->GetPDFPage()->GetPageWidth();
-  rcPageView.bottom = pData->pWidget->GetPDFPage()->GetPageHeight();
-  rcPageView.Normalize();
-
-  CPDF_Rect rcAnnot = pData->pWidget->GetRect();
-
-  FX_FLOAT fTop = 0.0f;
-  FX_FLOAT fBottom = 0.0f;
-
-  CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pData->pWidget;
-  switch (pWidget->GetRotate() / 90) {
-    default:
-    case 0:
-      fTop = rcPageView.top - rcAnnot.top;
-      fBottom = rcAnnot.bottom - rcPageView.bottom;
-      break;
-    case 1:
-      fTop = rcAnnot.left - rcPageView.left;
-      fBottom = rcPageView.right - rcAnnot.right;
-      break;
-    case 2:
-      fTop = rcAnnot.bottom - rcPageView.bottom;
-      fBottom = rcPageView.top - rcAnnot.top;
-      break;
-    case 3:
-      fTop = rcPageView.right - rcAnnot.right;
-      fBottom = rcAnnot.left - rcPageView.left;
-      break;
-  }
-
-  FX_FLOAT fFactHeight = 0;
-  FX_BOOL bBottom = TRUE;
-  FX_FLOAT fMaxListBoxHeight = 0;
-  if (fPopupMax > FFL_MAXLISTBOXHEIGHT) {
-    if (fPopupMin > FFL_MAXLISTBOXHEIGHT) {
-      fMaxListBoxHeight = fPopupMin;
-    } else {
-      fMaxListBoxHeight = FFL_MAXLISTBOXHEIGHT;
-    }
-  } else {
-    fMaxListBoxHeight = fPopupMax;
-  }
-
-  if (fBottom > fMaxListBoxHeight) {
-    fFactHeight = fMaxListBoxHeight;
-    bBottom = TRUE;
-  } else {
-    if (fTop > fMaxListBoxHeight) {
-      fFactHeight = fMaxListBoxHeight;
-      bBottom = FALSE;
-    } else {
-      if (fTop > fBottom) {
-        fFactHeight = fTop;
-        bBottom = FALSE;
-      } else {
-        fFactHeight = fBottom;
-        bBottom = TRUE;
-      }
-    }
-  }
-
-  nRet = bBottom ? 0 : 1;
-  fPopupRet = fFactHeight;
-}
-
-void CFFL_IFormFiller::OnKeyStrokeCommit(CPDFSDK_Widget* pWidget,
-                                         CPDFSDK_PageView* pPageView,
-                                         FX_BOOL& bRC,
-                                         FX_BOOL& bExit,
-                                         FX_DWORD nFlag) {
-  if (!m_bNotifying) {
-    if (pWidget->GetAAction(CPDF_AAction::KeyStroke)) {
-      m_bNotifying = TRUE;
-      pWidget->ClearAppModified();
-
-      ASSERT(pPageView);
-
-      PDFSDK_FieldAction fa;
-      fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
-      fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
-      fa.bWillCommit = TRUE;
-      fa.bKeyDown = TRUE;
-      fa.bRC = TRUE;
-
-      CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE);
-      pFormFiller->GetActionData(pPageView, CPDF_AAction::KeyStroke, fa);
-      pFormFiller->SaveState(pPageView);
-
-      PDFSDK_FieldAction faOld = fa;
-      pWidget->OnAAction(CPDF_AAction::KeyStroke, fa, pPageView);
-
-      bRC = fa.bRC;
-      m_bNotifying = FALSE;
-    }
-  }
-}
-
-void CFFL_IFormFiller::OnValidate(CPDFSDK_Widget* pWidget,
-                                  CPDFSDK_PageView* pPageView,
-                                  FX_BOOL& bRC,
-                                  FX_BOOL& bExit,
-                                  FX_DWORD nFlag) {
-  if (!m_bNotifying) {
-    if (pWidget->GetAAction(CPDF_AAction::Validate)) {
-      m_bNotifying = TRUE;
-      pWidget->ClearAppModified();
-
-      ASSERT(pPageView);
-
-      PDFSDK_FieldAction fa;
-      fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
-      fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
-      fa.bKeyDown = TRUE;
-      fa.bRC = TRUE;
-
-      CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE);
-      pFormFiller->GetActionData(pPageView, CPDF_AAction::Validate, fa);
-      pFormFiller->SaveState(pPageView);
-
-      PDFSDK_FieldAction faOld = fa;
-      pWidget->OnAAction(CPDF_AAction::Validate, fa, pPageView);
-
-      bRC = fa.bRC;
-      m_bNotifying = FALSE;
-    }
-  }
-}
-
-void CFFL_IFormFiller::OnCalculate(CPDFSDK_Widget* pWidget,
-                                   CPDFSDK_PageView* pPageView,
-                                   FX_BOOL& bExit,
-                                   FX_DWORD nFlag) {
-  if (!m_bNotifying) {
-    ASSERT(pWidget);
-    CPDFSDK_Document* pDocument = pPageView->GetSDKDocument();
-    CPDFSDK_InterForm* pInterForm =
-        (CPDFSDK_InterForm*)pDocument->GetInterForm();
-    pInterForm->OnCalculate(pWidget->GetFormField());
-
-    m_bNotifying = FALSE;
-  }
-}
-
-void CFFL_IFormFiller::OnFormat(CPDFSDK_Widget* pWidget,
-                                CPDFSDK_PageView* pPageView,
-                                FX_BOOL& bExit,
-                                FX_DWORD nFlag) {
-  if (!m_bNotifying) {
-    ASSERT(pWidget);
-    CPDFSDK_Document* pDocument = pPageView->GetSDKDocument();
-    CPDFSDK_InterForm* pInterForm =
-        (CPDFSDK_InterForm*)pDocument->GetInterForm();
-
-    FX_BOOL bFormated = FALSE;
-    CFX_WideString sValue =
-        pInterForm->OnFormat(pWidget->GetFormField(), bFormated);
-
-    if (bExit)
-      return;
-
-    if (bFormated) {
-      pInterForm->ResetFieldAppearance(pWidget->GetFormField(), sValue.c_str(),
-                                       TRUE);
-      pInterForm->UpdateField(pWidget->GetFormField());
-    }
-
-    m_bNotifying = FALSE;
-  }
-}
-
-#ifdef PDF_ENABLE_XFA
-void CFFL_IFormFiller::OnClick(CPDFSDK_Widget* pWidget,
-                               CPDFSDK_PageView* pPageView,
-                               FX_BOOL& bReset,
-                               FX_BOOL& bExit,
-                               FX_UINT nFlag) {
-  ASSERT(pWidget != NULL);
-
-  if (!m_bNotifying) {
-    if (pWidget->HasXFAAAction(PDFSDK_XFA_Click)) {
-      m_bNotifying = TRUE;
-      int nAge = pWidget->GetAppearanceAge();
-      int nValueAge = pWidget->GetValueAge();
-
-      PDFSDK_FieldAction fa;
-      fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
-      fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
-
-      pWidget->OnXFAAAction(PDFSDK_XFA_Click, fa, pPageView);
-      m_bNotifying = FALSE;
-
-      if (!IsValidAnnot(pPageView, pWidget)) {
-        bExit = TRUE;
-        return;
-      }
-
-      if (nAge != pWidget->GetAppearanceAge()) {
-        if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE)) {
-          pFormFiller->ResetPDFWindow(pPageView,
-                                      nValueAge == pWidget->GetValueAge());
-        }
-
-        bReset = TRUE;
-      }
-    }
-  }
-}
-
-void CFFL_IFormFiller::OnFull(CPDFSDK_Widget* pWidget,
-                              CPDFSDK_PageView* pPageView,
-                              FX_BOOL& bReset,
-                              FX_BOOL& bExit,
-                              FX_UINT nFlag) {
-  ASSERT(pWidget != NULL);
-
-  if (!m_bNotifying) {
-    if (pWidget->HasXFAAAction(PDFSDK_XFA_Full)) {
-      m_bNotifying = TRUE;
-      int nAge = pWidget->GetAppearanceAge();
-      int nValueAge = pWidget->GetValueAge();
-
-      PDFSDK_FieldAction fa;
-      fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
-      fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
-
-      pWidget->OnXFAAAction(PDFSDK_XFA_Full, fa, pPageView);
-      m_bNotifying = FALSE;
-
-      if (!IsValidAnnot(pPageView, pWidget)) {
-        bExit = TRUE;
-        return;
-      }
-
-      if (nAge != pWidget->GetAppearanceAge()) {
-        if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE)) {
-          pFormFiller->ResetPDFWindow(pPageView,
-                                      nValueAge == pWidget->GetValueAge());
-        }
-
-        bReset = TRUE;
-      }
-    }
-  }
-}
-
-void CFFL_IFormFiller::OnPopupPreOpen(void* pPrivateData,
-                                      FX_BOOL& bExit,
-                                      FX_DWORD nFlag) {
-  ASSERT(pPrivateData != NULL);
-  CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
-  ASSERT(pData->pWidget != NULL);
-
-  FX_BOOL bTempReset = FALSE;
-  FX_BOOL bTempExit = FALSE;
-  this->OnPreOpen(pData->pWidget, pData->pPageView, bTempReset, bTempExit,
-                  nFlag);
-
-  if (bTempReset || bTempExit) {
-    bExit = TRUE;
-  }
-}
-
-void CFFL_IFormFiller::OnPopupPostOpen(void* pPrivateData,
-                                       FX_BOOL& bExit,
-                                       FX_DWORD nFlag) {
-  ASSERT(pPrivateData != NULL);
-  CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
-  ASSERT(pData->pWidget != NULL);
-
-  FX_BOOL bTempReset = FALSE;
-  FX_BOOL bTempExit = FALSE;
-  this->OnPostOpen(pData->pWidget, pData->pPageView, bTempReset, bTempExit,
-                   nFlag);
-
-  if (bTempReset || bTempExit) {
-    bExit = TRUE;
-  }
-}
-
-void CFFL_IFormFiller::OnPreOpen(CPDFSDK_Widget* pWidget,
-                                 CPDFSDK_PageView* pPageView,
-                                 FX_BOOL& bReset,
-                                 FX_BOOL& bExit,
-                                 FX_UINT nFlag) {
-  ASSERT(pWidget != NULL);
-
-  if (!m_bNotifying) {
-    if (pWidget->HasXFAAAction(PDFSDK_XFA_PreOpen)) {
-      m_bNotifying = TRUE;
-      int nAge = pWidget->GetAppearanceAge();
-      int nValueAge = pWidget->GetValueAge();
-
-      PDFSDK_FieldAction fa;
-      fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
-      fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
-
-      pWidget->OnXFAAAction(PDFSDK_XFA_PreOpen, fa, pPageView);
-      m_bNotifying = FALSE;
-
-      if (!IsValidAnnot(pPageView, pWidget)) {
-        bExit = TRUE;
-        return;
-      }
-
-      if (nAge != pWidget->GetAppearanceAge()) {
-        if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE)) {
-          pFormFiller->ResetPDFWindow(pPageView,
-                                      nValueAge == pWidget->GetValueAge());
-        }
-
-        bReset = TRUE;
-      }
-    }
-  }
-}
-
-void CFFL_IFormFiller::OnPostOpen(CPDFSDK_Widget* pWidget,
-                                  CPDFSDK_PageView* pPageView,
-                                  FX_BOOL& bReset,
-                                  FX_BOOL& bExit,
-                                  FX_UINT nFlag) {
-  ASSERT(pWidget != NULL);
-
-  if (!m_bNotifying) {
-    if (pWidget->HasXFAAAction(PDFSDK_XFA_PostOpen)) {
-      m_bNotifying = TRUE;
-      int nAge = pWidget->GetAppearanceAge();
-      int nValueAge = pWidget->GetValueAge();
-
-      PDFSDK_FieldAction fa;
-      fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
-      fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
-
-      pWidget->OnXFAAAction(PDFSDK_XFA_PostOpen, fa, pPageView);
-      m_bNotifying = FALSE;
-
-      if (!IsValidAnnot(pPageView, pWidget)) {
-        bExit = TRUE;
-        return;
-      }
-
-      if (nAge != pWidget->GetAppearanceAge()) {
-        if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE)) {
-          pFormFiller->ResetPDFWindow(pPageView,
-                                      nValueAge == pWidget->GetValueAge());
-        }
-
-        bReset = TRUE;
-      }
-    }
-  }
-}
-#endif  // PDF_ENABLE_XFA
-
-FX_BOOL CFFL_IFormFiller::IsValidAnnot(CPDFSDK_PageView* pPageView,
-                                       CPDFSDK_Annot* pAnnot) {
-  if (pPageView)
-    return pPageView->IsValidAnnot(pAnnot->GetPDFAnnot());
-
-  return FALSE;
-}
-
-void CFFL_IFormFiller::OnBeforeKeyStroke(void* pPrivateData,
-                                         CFX_WideString& strChange,
-                                         const CFX_WideString& strChangeEx,
-                                         int nSelStart,
-                                         int nSelEnd,
-                                         FX_BOOL bKeyDown,
-                                         FX_BOOL& bRC,
-                                         FX_BOOL& bExit,
-                                         FX_DWORD nFlag) {
-  CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
-  ASSERT(pData->pWidget);
-
-  CFFL_FormFiller* pFormFiller = GetFormFiller(pData->pWidget, FALSE);
-
-#ifdef PDF_ENABLE_XFA
-  if (pFormFiller->IsFieldFull(pData->pPageView)) {
-    FX_BOOL bFullExit = FALSE;
-    FX_BOOL bFullReset = FALSE;
-    OnFull(pData->pWidget, pData->pPageView, bFullReset, bFullExit, nFlag);
-
-    if (bFullReset || bFullExit) {
-      bExit = TRUE;
-      return;
-    }
-  }
-#endif  // PDF_ENABLE_XFA
-
-  if (!m_bNotifying) {
-    if (pData->pWidget->GetAAction(CPDF_AAction::KeyStroke)) {
-      m_bNotifying = TRUE;
-      int nAge = pData->pWidget->GetAppearanceAge();
-      int nValueAge = pData->pWidget->GetValueAge();
-
-      CPDFSDK_Document* pDocument = pData->pPageView->GetSDKDocument();
-
-      PDFSDK_FieldAction fa;
-      fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
-      fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
-      fa.sChange = strChange;
-      fa.sChangeEx = strChangeEx;
-      fa.bKeyDown = bKeyDown;
-      fa.bWillCommit = FALSE;
-      fa.bRC = TRUE;
-      fa.nSelStart = nSelStart;
-      fa.nSelEnd = nSelEnd;
-
-      pFormFiller->GetActionData(pData->pPageView, CPDF_AAction::KeyStroke, fa);
-      pFormFiller->SaveState(pData->pPageView);
-
-      if (pData->pWidget->OnAAction(CPDF_AAction::KeyStroke, fa,
-                                    pData->pPageView)) {
-        if (!IsValidAnnot(pData->pPageView, pData->pWidget)) {
-          bExit = TRUE;
-          m_bNotifying = FALSE;
-          return;
-        }
-
-        if (nAge != pData->pWidget->GetAppearanceAge()) {
-          CPWL_Wnd* pWnd = pFormFiller->ResetPDFWindow(
-              pData->pPageView, nValueAge == pData->pWidget->GetValueAge());
-          pData = (CFFL_PrivateData*)pWnd->GetAttachedData();
-          bExit = TRUE;
-        }
-
-        if (fa.bRC) {
-          pFormFiller->SetActionData(pData->pPageView, CPDF_AAction::KeyStroke,
-                                     fa);
-          bRC = FALSE;
-        } else {
-          pFormFiller->RestoreState(pData->pPageView);
-          bRC = FALSE;
-        }
-
-        if (pDocument->GetFocusAnnot() != pData->pWidget) {
-          pFormFiller->CommitData(pData->pPageView, nFlag);
-          bExit = TRUE;
-        }
-      } else {
-        if (!IsValidAnnot(pData->pPageView, pData->pWidget)) {
-          bExit = TRUE;
-          m_bNotifying = FALSE;
-          return;
-        }
-      }
-
-      m_bNotifying = FALSE;
-    }
-  }
-}
diff --git a/fpdfsdk/src/formfiller/FFL_ListBox.cpp b/fpdfsdk/src/formfiller/FFL_ListBox.cpp
deleted file mode 100644
index 638618f..0000000
--- a/fpdfsdk/src/formfiller/FFL_ListBox.cpp
+++ /dev/null
@@ -1,223 +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
-
-#include "fpdfsdk/include/formfiller/FFL_ListBox.h"
-
-#include "fpdfsdk/include/formfiller/FFL_CBA_Fontmap.h"
-#include "fpdfsdk/include/formfiller/FFL_FormFiller.h"
-#include "fpdfsdk/include/formfiller/FFL_IFormFiller.h"
-#include "fpdfsdk/include/fsdk_common.h"
-#include "fpdfsdk/include/fsdk_mgr.h"
-#include "fpdfsdk/include/pdfwindow/PWL_ListBox.h"
-
-#define FFL_DEFAULTLISTBOXFONTSIZE 12.0f
-
-CFFL_ListBox::CFFL_ListBox(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pWidget)
-    : CFFL_FormFiller(pApp, pWidget), m_pFontMap(NULL) {}
-
-CFFL_ListBox::~CFFL_ListBox() {
-  delete m_pFontMap;
-}
-
-PWL_CREATEPARAM CFFL_ListBox::GetCreateParam() {
-  PWL_CREATEPARAM cp = CFFL_FormFiller::GetCreateParam();
-
-  FX_DWORD dwFieldFlag = m_pWidget->GetFieldFlags();
-
-  if (dwFieldFlag & FIELDFLAG_MULTISELECT) {
-    cp.dwFlags |= PLBS_MULTIPLESEL;
-  }
-
-  cp.dwFlags |= PWS_VSCROLL;
-
-  if (cp.dwFlags & PWS_AUTOFONTSIZE)
-    cp.fFontSize = FFL_DEFAULTLISTBOXFONTSIZE;
-
-  if (!m_pFontMap)
-    m_pFontMap = new CBA_FontMap(m_pWidget, m_pApp->GetSysHandler());
-  cp.pFontMap = m_pFontMap;
-
-  return cp;
-}
-
-CPWL_Wnd* CFFL_ListBox::NewPDFWindow(const PWL_CREATEPARAM& cp,
-                                     CPDFSDK_PageView* pPageView) {
-  CPWL_ListBox* pWnd = new CPWL_ListBox();
-  pWnd->AttachFFLData(this);
-  pWnd->Create(cp);
-
-  CFFL_IFormFiller* pIFormFiller = m_pApp->GetIFormFiller();
-  pWnd->SetFillerNotify(pIFormFiller);
-
-  for (int32_t i = 0, sz = m_pWidget->CountOptions(); i < sz; i++)
-    pWnd->AddString(m_pWidget->GetOptionLabel(i).c_str());
-
-  if (pWnd->HasFlag(PLBS_MULTIPLESEL)) {
-    m_OriginSelections.clear();
-
-    FX_BOOL bSetCaret = FALSE;
-    for (int32_t i = 0, sz = m_pWidget->CountOptions(); i < sz; i++) {
-      if (m_pWidget->IsOptionSelected(i)) {
-        if (!bSetCaret) {
-          pWnd->SetCaret(i);
-          bSetCaret = TRUE;
-        }
-        pWnd->Select(i);
-        m_OriginSelections.insert(i);
-      }
-    }
-  } else {
-    for (int i = 0, sz = m_pWidget->CountOptions(); i < sz; i++) {
-      if (m_pWidget->IsOptionSelected(i)) {
-        pWnd->Select(i);
-        break;
-      }
-    }
-  }
-
-  pWnd->SetTopVisibleIndex(m_pWidget->GetTopVisibleIndex());
-
-  return pWnd;
-}
-
-FX_BOOL CFFL_ListBox::OnChar(CPDFSDK_Annot* pAnnot,
-                             FX_UINT nChar,
-                             FX_UINT nFlags) {
-  return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
-}
-
-FX_BOOL CFFL_ListBox::IsDataChanged(CPDFSDK_PageView* pPageView) {
-  CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE);
-  if (!pListBox)
-    return FALSE;
-
-  if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT) {
-    size_t nSelCount = 0;
-    for (int32_t i = 0, sz = pListBox->GetCount(); i < sz; ++i) {
-      if (pListBox->IsItemSelected(i)) {
-        if (m_OriginSelections.count(i) == 0)
-          return TRUE;
-
-        ++nSelCount;
-      }
-    }
-
-    return nSelCount != m_OriginSelections.size();
-  }
-  return pListBox->GetCurSel() != m_pWidget->GetSelectedIndex(0);
-}
-
-void CFFL_ListBox::SaveData(CPDFSDK_PageView* pPageView) {
-  ASSERT(m_pWidget);
-
-  if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE)) {
-    CFX_IntArray aOldSelect, aNewSelect;
-
-    {
-      for (int i = 0, sz = m_pWidget->CountOptions(); i < sz; i++) {
-        if (m_pWidget->IsOptionSelected(i)) {
-          aOldSelect.Add(i);
-        }
-      }
-    }
-
-    int32_t nNewTopIndex = pListBox->GetTopVisibleIndex();
-
-    m_pWidget->ClearSelection(FALSE);
-
-    if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT) {
-      for (int32_t i = 0, sz = pListBox->GetCount(); i < sz; i++) {
-        if (pListBox->IsItemSelected(i)) {
-          m_pWidget->SetOptionSelection(i, TRUE, FALSE);
-          aNewSelect.Add(i);
-        }
-      }
-    } else {
-      m_pWidget->SetOptionSelection(pListBox->GetCurSel(), TRUE, FALSE);
-      aNewSelect.Add(pListBox->GetCurSel());
-    }
-
-    m_pWidget->SetTopVisibleIndex(nNewTopIndex);
-    m_pWidget->ResetFieldAppearance(TRUE);
-    m_pWidget->UpdateField();
-    SetChangeMark();
-  }
-}
-
-void CFFL_ListBox::GetActionData(CPDFSDK_PageView* pPageView,
-                                 CPDF_AAction::AActionType type,
-                                 PDFSDK_FieldAction& fa) {
-  switch (type) {
-    case CPDF_AAction::Validate:
-      if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT) {
-        fa.sValue = L"";
-      } else {
-        if (CPWL_ListBox* pListBox =
-                (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE)) {
-          int32_t nCurSel = pListBox->GetCurSel();
-          if (nCurSel >= 0)
-            fa.sValue = m_pWidget->GetOptionLabel(nCurSel);
-        }
-      }
-      break;
-    case CPDF_AAction::LoseFocus:
-    case CPDF_AAction::GetFocus:
-      if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT) {
-        fa.sValue = L"";
-      } else {
-        int32_t nCurSel = m_pWidget->GetSelectedIndex(0);
-        if (nCurSel >= 0)
-          fa.sValue = m_pWidget->GetOptionLabel(nCurSel);
-      }
-      break;
-    default:
-      break;
-  }
-}
-
-void CFFL_ListBox::SetActionData(CPDFSDK_PageView* pPageView,
-                                 CPDF_AAction::AActionType type,
-                                 const PDFSDK_FieldAction& fa) {}
-
-void CFFL_ListBox::SaveState(CPDFSDK_PageView* pPageView) {
-  ASSERT(pPageView);
-
-  if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE)) {
-    for (int32_t i = 0, sz = pListBox->GetCount(); i < sz; i++) {
-      if (pListBox->IsItemSelected(i)) {
-        m_State.Add(i);
-      }
-    }
-  }
-}
-
-void CFFL_ListBox::RestoreState(CPDFSDK_PageView* pPageView) {
-  if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE)) {
-    for (int i = 0, sz = m_State.GetSize(); i < sz; i++)
-      pListBox->Select(m_State[i]);
-  }
-}
-
-CPWL_Wnd* CFFL_ListBox::ResetPDFWindow(CPDFSDK_PageView* pPageView,
-                                       FX_BOOL bRestoreValue) {
-  if (bRestoreValue)
-    SaveState(pPageView);
-
-  DestroyPDFWindow(pPageView);
-
-  CPWL_Wnd* pRet = NULL;
-
-  if (bRestoreValue) {
-    RestoreState(pPageView);
-    pRet = GetPDFWindow(pPageView, FALSE);
-  } else {
-    pRet = GetPDFWindow(pPageView, TRUE);
-  }
-
-  m_pWidget->UpdateField();
-
-  return pRet;
-}
diff --git a/fpdfsdk/src/formfiller/FFL_PushButton.cpp b/fpdfsdk/src/formfiller/FFL_PushButton.cpp
deleted file mode 100644
index d5bd509..0000000
--- a/fpdfsdk/src/formfiller/FFL_PushButton.cpp
+++ /dev/null
@@ -1,38 +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
-
-#include "fpdfsdk/include/formfiller/FFL_PushButton.h"
-
-#include "fpdfsdk/include/formfiller/FFL_FormFiller.h"
-#include "fpdfsdk/include/pdfwindow/PWL_SpecialButton.h"
-
-CFFL_PushButton::CFFL_PushButton(CPDFDoc_Environment* pApp,
-                                 CPDFSDK_Annot* pAnnot)
-    : CFFL_Button(pApp, pAnnot) {}
-
-CFFL_PushButton::~CFFL_PushButton() {}
-
-CPWL_Wnd* CFFL_PushButton::NewPDFWindow(const PWL_CREATEPARAM& cp,
-                                        CPDFSDK_PageView* pPageView) {
-  CPWL_PushButton* pWnd = new CPWL_PushButton();
-  pWnd->Create(cp);
-
-  return pWnd;
-}
-
-FX_BOOL CFFL_PushButton::OnChar(CPDFSDK_Annot* pAnnot,
-                                FX_UINT nChar,
-                                FX_UINT nFlags) {
-  return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
-}
-
-void CFFL_PushButton::OnDraw(CPDFSDK_PageView* pPageView,
-                             CPDFSDK_Annot* pAnnot,
-                             CFX_RenderDevice* pDevice,
-                             CFX_Matrix* pUser2Device,
-                             FX_DWORD dwFlags) {
-  CFFL_Button::OnDraw(pPageView, pAnnot, pDevice, pUser2Device, dwFlags);
-}
diff --git a/fpdfsdk/src/formfiller/FFL_RadioButton.cpp b/fpdfsdk/src/formfiller/FFL_RadioButton.cpp
deleted file mode 100644
index 2a742c0..0000000
--- a/fpdfsdk/src/formfiller/FFL_RadioButton.cpp
+++ /dev/null
@@ -1,121 +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
-
-#include "fpdfsdk/include/formfiller/FFL_RadioButton.h"
-
-#include "fpdfsdk/include/formfiller/FFL_FormFiller.h"
-#include "fpdfsdk/include/fsdk_mgr.h"
-#include "fpdfsdk/include/pdfwindow/PWL_SpecialButton.h"
-
-CFFL_RadioButton::CFFL_RadioButton(CPDFDoc_Environment* pApp,
-                                   CPDFSDK_Annot* pWidget)
-    : CFFL_Button(pApp, pWidget) {}
-
-CFFL_RadioButton::~CFFL_RadioButton() {}
-
-CPWL_Wnd* CFFL_RadioButton::NewPDFWindow(const PWL_CREATEPARAM& cp,
-                                         CPDFSDK_PageView* pPageView) {
-  CPWL_RadioButton* pWnd = new CPWL_RadioButton();
-  pWnd->Create(cp);
-
-  pWnd->SetCheck(m_pWidget->IsChecked());
-
-  return pWnd;
-}
-
-FX_BOOL CFFL_RadioButton::OnKeyDown(CPDFSDK_Annot* pAnnot,
-                                    FX_UINT nKeyCode,
-                                    FX_UINT nFlags) {
-  switch (nKeyCode) {
-    case FWL_VKEY_Return:
-    case FWL_VKEY_Space:
-      return TRUE;
-    default:
-      return CFFL_FormFiller::OnKeyDown(pAnnot, nKeyCode, nFlags);
-  }
-}
-
-FX_BOOL CFFL_RadioButton::OnChar(CPDFSDK_Annot* pAnnot,
-                                 FX_UINT nChar,
-                                 FX_UINT nFlags) {
-  switch (nChar) {
-    case FWL_VKEY_Return:
-    case FWL_VKEY_Space: {
-      CFFL_IFormFiller* pIFormFiller = m_pApp->GetIFormFiller();
-      CPDFSDK_PageView* pPageView = pAnnot->GetPageView();
-      ASSERT(pPageView);
-
-      FX_BOOL bReset = FALSE;
-      FX_BOOL bExit = FALSE;
-
-      pIFormFiller->OnButtonUp(m_pWidget, pPageView, bReset, bExit, nFlags);
-
-      if (bReset)
-        return TRUE;
-      if (bExit)
-        return TRUE;
-
-      CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
-
-      if (CPWL_RadioButton* pWnd =
-              (CPWL_RadioButton*)GetPDFWindow(pPageView, TRUE))
-        pWnd->SetCheck(TRUE);
-      CommitData(pPageView, nFlags);
-      return TRUE;
-    }
-    default:
-      return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
-  }
-}
-
-FX_BOOL CFFL_RadioButton::OnLButtonUp(CPDFSDK_PageView* pPageView,
-                                      CPDFSDK_Annot* pAnnot,
-                                      FX_UINT nFlags,
-                                      const CPDF_Point& point) {
-  CFFL_Button::OnLButtonUp(pPageView, pAnnot, nFlags, point);
-
-  if (IsValid()) {
-    if (CPWL_RadioButton* pWnd =
-            (CPWL_RadioButton*)GetPDFWindow(pPageView, TRUE))
-      pWnd->SetCheck(TRUE);
-
-    if (!CommitData(pPageView, nFlags))
-      return FALSE;
-  }
-
-  return TRUE;
-}
-
-FX_BOOL CFFL_RadioButton::IsDataChanged(CPDFSDK_PageView* pPageView) {
-  if (CPWL_RadioButton* pWnd =
-          (CPWL_RadioButton*)GetPDFWindow(pPageView, FALSE)) {
-    return pWnd->IsChecked() != m_pWidget->IsChecked();
-  }
-
-  return FALSE;
-}
-
-void CFFL_RadioButton::SaveData(CPDFSDK_PageView* pPageView) {
-  if (CPWL_RadioButton* pWnd =
-          (CPWL_RadioButton*)GetPDFWindow(pPageView, FALSE)) {
-    FX_BOOL bNewChecked = pWnd->IsChecked();
-
-    if (bNewChecked) {
-      CPDF_FormField* pField = m_pWidget->GetFormField();
-      for (int32_t i = 0, sz = pField->CountControls(); i < sz; i++) {
-        if (CPDF_FormControl* pCtrl = pField->GetControl(i)) {
-          if (pCtrl->IsChecked()) {
-            break;
-          }
-        }
-      }
-    }
-
-    m_pWidget->SetCheck(bNewChecked, FALSE);
-    m_pWidget->UpdateField();
-    SetChangeMark();
-  }
-}
diff --git a/fpdfsdk/src/fpdf_dataavail.cpp b/fpdfsdk/src/fpdf_dataavail.cpp
deleted file mode 100644
index f4e235c..0000000
--- a/fpdfsdk/src/fpdf_dataavail.cpp
+++ /dev/null
@@ -1,169 +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
-
-#include "public/fpdf_dataavail.h"
-
-#include "fpdfsdk/include/fsdk_define.h"
-#include "public/fpdf_formfill.h"
-
-// These checks are here because core/ and public/ cannot depend on each other.
-static_assert(IPDF_DataAvail::DataError == PDF_DATA_ERROR,
-              "IPDF_DataAvail::DataError value mismatch");
-static_assert(IPDF_DataAvail::DataNotAvailable == PDF_DATA_NOTAVAIL,
-              "IPDF_DataAvail::DataNotAvailable value mismatch");
-static_assert(IPDF_DataAvail::DataAvailable == PDF_DATA_AVAIL,
-              "IPDF_DataAvail::DataAvailable value mismatch");
-
-static_assert(IPDF_DataAvail::LinearizationUnknown == PDF_LINEARIZATION_UNKNOWN,
-              "IPDF_DataAvail::LinearizationUnknown value mismatch");
-static_assert(IPDF_DataAvail::NotLinearized == PDF_NOT_LINEARIZED,
-              "IPDF_DataAvail::NotLinearized value mismatch");
-static_assert(IPDF_DataAvail::Linearized == PDF_LINEARIZED,
-              "IPDF_DataAvail::Linearized value mismatch");
-
-static_assert(IPDF_DataAvail::FormError == PDF_FORM_ERROR,
-              "IPDF_DataAvail::FormError value mismatch");
-static_assert(IPDF_DataAvail::FormNotAvailable == PDF_FORM_NOTAVAIL,
-              "IPDF_DataAvail::FormNotAvailable value mismatch");
-static_assert(IPDF_DataAvail::FormAvailable == PDF_FORM_AVAIL,
-              "IPDF_DataAvail::FormAvailable value mismatch");
-static_assert(IPDF_DataAvail::FormNotExist == PDF_FORM_NOTEXIST,
-              "IPDF_DataAvail::FormNotExist value mismatch");
-
-class CFPDF_FileAvailWrap : public IFX_FileAvail {
- public:
-  CFPDF_FileAvailWrap() { m_pfileAvail = NULL; }
-  ~CFPDF_FileAvailWrap() override {}
-
-  void Set(FX_FILEAVAIL* pfileAvail) { m_pfileAvail = pfileAvail; }
-
-  // IFX_FileAvail
-  FX_BOOL IsDataAvail(FX_FILESIZE offset, FX_DWORD size) override {
-    return m_pfileAvail->IsDataAvail(m_pfileAvail, offset, size);
-  }
-
- private:
-  FX_FILEAVAIL* m_pfileAvail;
-};
-
-class CFPDF_FileAccessWrap : public IFX_FileRead {
- public:
-  CFPDF_FileAccessWrap() { m_pFileAccess = NULL; }
-  ~CFPDF_FileAccessWrap() override {}
-
-  void Set(FPDF_FILEACCESS* pFile) { m_pFileAccess = pFile; }
-
-  // IFX_FileRead
-  FX_FILESIZE GetSize() override { return m_pFileAccess->m_FileLen; }
-
-  FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override {
-    return m_pFileAccess->m_GetBlock(m_pFileAccess->m_Param, offset,
-                                     (uint8_t*)buffer, size);
-  }
-
-  void Release() override {}
-
- private:
-  FPDF_FILEACCESS* m_pFileAccess;
-};
-
-class CFPDF_DownloadHintsWrap : public IFX_DownloadHints {
- public:
-  explicit CFPDF_DownloadHintsWrap(FX_DOWNLOADHINTS* pDownloadHints) {
-    m_pDownloadHints = pDownloadHints;
-  }
-  ~CFPDF_DownloadHintsWrap() override {}
-
- public:
-  // IFX_DownloadHints
-  void AddSegment(FX_FILESIZE offset, FX_DWORD size) override {
-    m_pDownloadHints->AddSegment(m_pDownloadHints, offset, size);
-  }
-
- private:
-  FX_DOWNLOADHINTS* m_pDownloadHints;
-};
-
-class CFPDF_DataAvail {
- public:
-  CFPDF_DataAvail() { m_pDataAvail = NULL; }
-
-  ~CFPDF_DataAvail() { delete m_pDataAvail; }
-
-  IPDF_DataAvail* m_pDataAvail;
-  CFPDF_FileAvailWrap m_FileAvail;
-  CFPDF_FileAccessWrap m_FileRead;
-};
-
-DLLEXPORT FPDF_AVAIL STDCALL FPDFAvail_Create(FX_FILEAVAIL* file_avail,
-                                              FPDF_FILEACCESS* file) {
-  CFPDF_DataAvail* pAvail = new CFPDF_DataAvail;
-  pAvail->m_FileAvail.Set(file_avail);
-  pAvail->m_FileRead.Set(file);
-  pAvail->m_pDataAvail =
-      IPDF_DataAvail::Create(&pAvail->m_FileAvail, &pAvail->m_FileRead);
-  return pAvail;
-}
-
-DLLEXPORT void STDCALL FPDFAvail_Destroy(FPDF_AVAIL avail) {
-  delete (CFPDF_DataAvail*)avail;
-}
-
-DLLEXPORT int STDCALL
-FPDFAvail_IsDocAvail(FPDF_AVAIL avail, FX_DOWNLOADHINTS* hints) {
-  if (!avail || !hints)
-    return PDF_DATA_ERROR;
-  CFPDF_DownloadHintsWrap hints_wrap(hints);
-  return ((CFPDF_DataAvail*)avail)->m_pDataAvail->IsDocAvail(&hints_wrap);
-}
-
-DLLEXPORT FPDF_DOCUMENT STDCALL
-FPDFAvail_GetDocument(FPDF_AVAIL avail, FPDF_BYTESTRING password) {
-  if (!avail)
-    return NULL;
-  CPDF_Parser* pParser = new CPDF_Parser;
-  pParser->SetPassword(password);
-
-  FX_DWORD err_code = pParser->StartAsynParse(
-      ((CFPDF_DataAvail*)avail)->m_pDataAvail->GetFileRead());
-  if (err_code) {
-    delete pParser;
-    ProcessParseError(err_code);
-    return NULL;
-  }
-  ((CFPDF_DataAvail*)avail)->m_pDataAvail->SetDocument(pParser->GetDocument());
-  CheckUnSupportError(pParser->GetDocument(), FPDF_ERR_SUCCESS);
-  return FPDFDocumentFromCPDFDocument(pParser->GetDocument());
-}
-
-DLLEXPORT int STDCALL FPDFAvail_GetFirstPageNum(FPDF_DOCUMENT doc) {
-  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(doc);
-  return pDoc ? pDoc->GetParser()->GetFirstPageNo() : 0;
-}
-
-DLLEXPORT int STDCALL FPDFAvail_IsPageAvail(FPDF_AVAIL avail,
-                                            int page_index,
-                                            FX_DOWNLOADHINTS* hints) {
-  if (!avail || !hints)
-    return PDF_DATA_ERROR;
-  CFPDF_DownloadHintsWrap hints_wrap(hints);
-  return ((CFPDF_DataAvail*)avail)
-      ->m_pDataAvail->IsPageAvail(page_index, &hints_wrap);
-}
-
-DLLEXPORT int STDCALL FPDFAvail_IsFormAvail(FPDF_AVAIL avail,
-                                            FX_DOWNLOADHINTS* hints) {
-  if (!avail || !hints)
-    return PDF_FORM_ERROR;
-  CFPDF_DownloadHintsWrap hints_wrap(hints);
-  return ((CFPDF_DataAvail*)avail)->m_pDataAvail->IsFormAvail(&hints_wrap);
-}
-
-DLLEXPORT int STDCALL FPDFAvail_IsLinearized(FPDF_AVAIL avail) {
-  if (!avail)
-    return PDF_LINEARIZATION_UNKNOWN;
-  return ((CFPDF_DataAvail*)avail)->m_pDataAvail->IsLinearizedPDF();
-}
diff --git a/fpdfsdk/src/fpdf_dataavail_embeddertest.cpp b/fpdfsdk/src/fpdf_dataavail_embeddertest.cpp
deleted file mode 100644
index 222fdc4..0000000
--- a/fpdfsdk/src/fpdf_dataavail_embeddertest.cpp
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2015 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.
-
-#include "public/fpdf_doc.h"
-#include "public/fpdfview.h"
-#include "testing/embedder_test.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-class FPDFDataAvailEmbeddertest : public EmbedderTest {};
-
-TEST_F(FPDFDataAvailEmbeddertest, TrailerUnterminated) {
-  // Document must load without crashing but is too malformed to be available.
-  EXPECT_FALSE(OpenDocument("trailer_unterminated.pdf"));
-  EXPECT_FALSE(FPDFAvail_IsDocAvail(avail_, &hints_));
-}
-
-TEST_F(FPDFDataAvailEmbeddertest, TrailerAsHexstring) {
-  // Document must load without crashing but is too malformed to be available.
-  EXPECT_FALSE(OpenDocument("trailer_as_hexstring.pdf"));
-  EXPECT_FALSE(FPDFAvail_IsDocAvail(avail_, &hints_));
-}
diff --git a/fpdfsdk/src/fpdf_flatten.cpp b/fpdfsdk/src/fpdf_flatten.cpp
deleted file mode 100644
index 50d5036..0000000
--- a/fpdfsdk/src/fpdf_flatten.cpp
+++ /dev/null
@@ -1,524 +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
-
-#include "public/fpdf_flatten.h"
-
-#include <algorithm>
-
-#include "fpdfsdk/include/fsdk_define.h"
-
-typedef CFX_ArrayTemplate<CPDF_Dictionary*> CPDF_ObjectArray;
-typedef CFX_ArrayTemplate<CPDF_Rect> CPDF_RectArray;
-
-enum FPDF_TYPE { MAX, MIN };
-enum FPDF_VALUE { TOP, LEFT, RIGHT, BOTTOM };
-
-FX_BOOL IsValiableRect(CPDF_Rect rect, CPDF_Rect rcPage) {
-  if (rect.left - rect.right > 0.000001f || rect.bottom - rect.top > 0.000001f)
-    return FALSE;
-
-  if (rect.left == 0.0f && rect.top == 0.0f && rect.right == 0.0f &&
-      rect.bottom == 0.0f)
-    return FALSE;
-
-  if (!rcPage.IsEmpty()) {
-    if (rect.left - rcPage.left < -10.000001f ||
-        rect.right - rcPage.right > 10.000001f ||
-        rect.top - rcPage.top > 10.000001f ||
-        rect.bottom - rcPage.bottom < -10.000001f)
-      return FALSE;
-  }
-
-  return TRUE;
-}
-
-FX_BOOL GetContentsRect(CPDF_Document* pDoc,
-                        CPDF_Dictionary* pDict,
-                        CPDF_RectArray* pRectArray) {
-  CPDF_Page* pPDFPage = new CPDF_Page;
-  pPDFPage->Load(pDoc, pDict, FALSE);
-  pPDFPage->ParseContent();
-
-  FX_POSITION pos = pPDFPage->GetFirstObjectPosition();
-
-  while (pos) {
-    CPDF_PageObject* pPageObject = pPDFPage->GetNextObject(pos);
-    if (!pPageObject)
-      continue;
-
-    CPDF_Rect rc;
-    rc.left = pPageObject->m_Left;
-    rc.right = pPageObject->m_Right;
-    rc.bottom = pPageObject->m_Bottom;
-    rc.top = pPageObject->m_Top;
-
-    if (IsValiableRect(rc, pDict->GetRect("MediaBox"))) {
-      pRectArray->Add(rc);
-    }
-  }
-
-  delete pPDFPage;
-  return TRUE;
-}
-
-void ParserStream(CPDF_Dictionary* pPageDic,
-                  CPDF_Dictionary* pStream,
-                  CPDF_RectArray* pRectArray,
-                  CPDF_ObjectArray* pObjectArray) {
-  if (!pStream)
-    return;
-  CPDF_Rect rect;
-  if (pStream->KeyExist("Rect"))
-    rect = pStream->GetRect("Rect");
-  else if (pStream->KeyExist("BBox"))
-    rect = pStream->GetRect("BBox");
-
-  if (IsValiableRect(rect, pPageDic->GetRect("MediaBox")))
-    pRectArray->Add(rect);
-
-  pObjectArray->Add(pStream);
-}
-
-int ParserAnnots(CPDF_Document* pSourceDoc,
-                 CPDF_Dictionary* pPageDic,
-                 CPDF_RectArray* pRectArray,
-                 CPDF_ObjectArray* pObjectArray,
-                 int nUsage) {
-  if (!pSourceDoc || !pPageDic)
-    return FLATTEN_FAIL;
-
-  GetContentsRect(pSourceDoc, pPageDic, pRectArray);
-  CPDF_Array* pAnnots = pPageDic->GetArray("Annots");
-  if (!pAnnots)
-    return FLATTEN_NOTHINGTODO;
-
-  FX_DWORD dwSize = pAnnots->GetCount();
-  for (int i = 0; i < (int)dwSize; i++) {
-    CPDF_Dictionary* pAnnotDic = ToDictionary(pAnnots->GetElementValue(i));
-    if (!pAnnotDic)
-      continue;
-
-    CFX_ByteString sSubtype = pAnnotDic->GetString("Subtype");
-    if (sSubtype == "Popup")
-      continue;
-
-    int nAnnotFlag = pAnnotDic->GetInteger("F");
-    if (nAnnotFlag & ANNOTFLAG_HIDDEN)
-      continue;
-
-    if (nUsage == FLAT_NORMALDISPLAY) {
-      if (nAnnotFlag & ANNOTFLAG_INVISIBLE)
-        continue;
-
-      ParserStream(pPageDic, pAnnotDic, pRectArray, pObjectArray);
-    } else {
-      if (nAnnotFlag & ANNOTFLAG_PRINT)
-        ParserStream(pPageDic, pAnnotDic, pRectArray, pObjectArray);
-    }
-  }
-  return FLATTEN_SUCCESS;
-}
-
-FX_FLOAT GetMinMaxValue(CPDF_RectArray& array,
-                        FPDF_TYPE type,
-                        FPDF_VALUE value) {
-  int nRects = array.GetSize();
-  FX_FLOAT fRet = 0.0f;
-
-  if (nRects <= 0)
-    return 0.0f;
-
-  FX_FLOAT* pArray = new FX_FLOAT[nRects];
-  switch (value) {
-    case LEFT: {
-      for (int i = 0; i < nRects; i++)
-        pArray[i] = CPDF_Rect(array.GetAt(i)).left;
-
-      break;
-    }
-    case TOP: {
-      for (int i = 0; i < nRects; i++)
-        pArray[i] = CPDF_Rect(array.GetAt(i)).top;
-
-      break;
-    }
-    case RIGHT: {
-      for (int i = 0; i < nRects; i++)
-        pArray[i] = CPDF_Rect(array.GetAt(i)).right;
-
-      break;
-    }
-    case BOTTOM: {
-      for (int i = 0; i < nRects; i++)
-        pArray[i] = CPDF_Rect(array.GetAt(i)).bottom;
-
-      break;
-    }
-    default:
-      break;
-  }
-  fRet = pArray[0];
-  if (type == MAX) {
-    for (int i = 1; i < nRects; i++)
-      if (fRet <= pArray[i])
-        fRet = pArray[i];
-  } else {
-    for (int i = 1; i < nRects; i++)
-      if (fRet >= pArray[i])
-        fRet = pArray[i];
-  }
-  delete[] pArray;
-  return fRet;
-}
-
-CPDF_Rect CalculateRect(CPDF_RectArray* pRectArray) {
-  CPDF_Rect rcRet;
-
-  rcRet.left = GetMinMaxValue(*pRectArray, MIN, LEFT);
-  rcRet.top = GetMinMaxValue(*pRectArray, MAX, TOP);
-  rcRet.right = GetMinMaxValue(*pRectArray, MAX, RIGHT);
-  rcRet.bottom = GetMinMaxValue(*pRectArray, MIN, BOTTOM);
-
-  return rcRet;
-}
-
-void SetPageContents(CFX_ByteString key,
-                     CPDF_Dictionary* pPage,
-                     CPDF_Document* pDocument) {
-  CPDF_Object* pContentsObj = pPage->GetStream("Contents");
-  if (!pContentsObj) {
-    pContentsObj = pPage->GetArray("Contents");
-  }
-
-  if (!pContentsObj) {
-    // Create a new contents dictionary
-    if (!key.IsEmpty()) {
-      CPDF_Stream* pNewContents = new CPDF_Stream(NULL, 0, new CPDF_Dictionary);
-      pPage->SetAtReference("Contents", pDocument,
-                            pDocument->AddIndirectObject(pNewContents));
-
-      CFX_ByteString sStream;
-      sStream.Format("q 1 0 0 1 0 0 cm /%s Do Q", key.c_str());
-      pNewContents->SetData((const uint8_t*)sStream, sStream.GetLength(), FALSE,
-                            FALSE);
-    }
-    return;
-  }
-
-  int iType = pContentsObj->GetType();
-  CPDF_Array* pContentsArray = NULL;
-
-  switch (iType) {
-    case PDFOBJ_STREAM: {
-      pContentsArray = new CPDF_Array;
-      CPDF_Stream* pContents = pContentsObj->AsStream();
-      FX_DWORD dwObjNum = pDocument->AddIndirectObject(pContents);
-      CPDF_StreamAcc acc;
-      acc.LoadAllData(pContents);
-      CFX_ByteString sStream = "q\n";
-      CFX_ByteString sBody =
-          CFX_ByteString((const FX_CHAR*)acc.GetData(), acc.GetSize());
-      sStream = sStream + sBody + "\nQ";
-      pContents->SetData((const uint8_t*)sStream, sStream.GetLength(), FALSE,
-                         FALSE);
-      pContentsArray->AddReference(pDocument, dwObjNum);
-      break;
-    }
-
-    case PDFOBJ_ARRAY: {
-      pContentsArray = pContentsObj->AsArray();
-      break;
-    }
-    default:
-      break;
-  }
-
-  if (!pContentsArray)
-    return;
-
-  FX_DWORD dwObjNum = pDocument->AddIndirectObject(pContentsArray);
-  pPage->SetAtReference("Contents", pDocument, dwObjNum);
-
-  if (!key.IsEmpty()) {
-    CPDF_Stream* pNewContents = new CPDF_Stream(NULL, 0, new CPDF_Dictionary);
-    dwObjNum = pDocument->AddIndirectObject(pNewContents);
-    pContentsArray->AddReference(pDocument, dwObjNum);
-
-    CFX_ByteString sStream;
-    sStream.Format("q 1 0 0 1 0 0 cm /%s Do Q", key.c_str());
-    pNewContents->SetData((const uint8_t*)sStream, sStream.GetLength(), FALSE,
-                          FALSE);
-  }
-}
-
-CFX_Matrix GetMatrix(CPDF_Rect rcAnnot,
-                     CPDF_Rect rcStream,
-                     const CFX_Matrix& matrix) {
-  if (rcStream.IsEmpty())
-    return CFX_Matrix();
-
-  matrix.TransformRect(rcStream);
-  rcStream.Normalize();
-
-  FX_FLOAT a = rcAnnot.Width() / rcStream.Width();
-  FX_FLOAT d = rcAnnot.Height() / rcStream.Height();
-
-  FX_FLOAT e = rcAnnot.left - rcStream.left * a;
-  FX_FLOAT f = rcAnnot.bottom - rcStream.bottom * d;
-  return CFX_Matrix(a, 0, 0, d, e, f);
-}
-
-void GetOffset(FX_FLOAT& fa,
-               FX_FLOAT& fd,
-               FX_FLOAT& fe,
-               FX_FLOAT& ff,
-               CPDF_Rect rcAnnot,
-               CPDF_Rect rcStream,
-               const CFX_Matrix& matrix) {
-  FX_FLOAT fStreamWidth = 0.0f;
-  FX_FLOAT fStreamHeight = 0.0f;
-
-  if (matrix.a != 0 && matrix.d != 0) {
-    fStreamWidth = rcStream.right - rcStream.left;
-    fStreamHeight = rcStream.top - rcStream.bottom;
-  } else {
-    fStreamWidth = rcStream.top - rcStream.bottom;
-    fStreamHeight = rcStream.right - rcStream.left;
-  }
-
-  FX_FLOAT x1 =
-      matrix.a * rcStream.left + matrix.c * rcStream.bottom + matrix.e;
-  FX_FLOAT y1 =
-      matrix.b * rcStream.left + matrix.d * rcStream.bottom + matrix.f;
-  FX_FLOAT x2 = matrix.a * rcStream.left + matrix.c * rcStream.top + matrix.e;
-  FX_FLOAT y2 = matrix.b * rcStream.left + matrix.d * rcStream.top + matrix.f;
-  FX_FLOAT x3 =
-      matrix.a * rcStream.right + matrix.c * rcStream.bottom + matrix.e;
-  FX_FLOAT y3 =
-      matrix.b * rcStream.right + matrix.d * rcStream.bottom + matrix.f;
-  FX_FLOAT x4 = matrix.a * rcStream.right + matrix.c * rcStream.top + matrix.e;
-  FX_FLOAT y4 = matrix.b * rcStream.right + matrix.d * rcStream.top + matrix.f;
-
-  FX_FLOAT left = std::min(std::min(x1, x2), std::min(x3, x4));
-  FX_FLOAT bottom = std::min(std::min(y1, y2), std::min(y3, y4));
-
-  fa = (rcAnnot.right - rcAnnot.left) / fStreamWidth;
-  fd = (rcAnnot.top - rcAnnot.bottom) / fStreamHeight;
-  fe = rcAnnot.left - left * fa;
-  ff = rcAnnot.bottom - bottom * fd;
-}
-
-DLLEXPORT int STDCALL FPDFPage_Flatten(FPDF_PAGE page, int nFlag) {
-  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
-  if (!page) {
-    return FLATTEN_FAIL;
-  }
-
-  CPDF_Document* pDocument = pPage->m_pDocument;
-  CPDF_Dictionary* pPageDict = pPage->m_pFormDict;
-
-  if (!pDocument || !pPageDict) {
-    return FLATTEN_FAIL;
-  }
-
-  CPDF_ObjectArray ObjectArray;
-  CPDF_RectArray RectArray;
-
-  int iRet = FLATTEN_FAIL;
-  iRet = ParserAnnots(pDocument, pPageDict, &RectArray, &ObjectArray, nFlag);
-  if (iRet == FLATTEN_NOTHINGTODO || iRet == FLATTEN_FAIL)
-    return iRet;
-
-  CPDF_Rect rcOriginalCB;
-  CPDF_Rect rcMerger = CalculateRect(&RectArray);
-  CPDF_Rect rcOriginalMB = pPageDict->GetRect("MediaBox");
-
-  if (pPageDict->KeyExist("CropBox"))
-    rcOriginalMB = pPageDict->GetRect("CropBox");
-
-  if (rcOriginalMB.IsEmpty()) {
-    rcOriginalMB = CPDF_Rect(0.0f, 0.0f, 612.0f, 792.0f);
-  }
-
-  rcMerger.left =
-      rcMerger.left < rcOriginalMB.left ? rcOriginalMB.left : rcMerger.left;
-  rcMerger.right =
-      rcMerger.right > rcOriginalMB.right ? rcOriginalMB.right : rcMerger.right;
-  rcMerger.top =
-      rcMerger.top > rcOriginalMB.top ? rcOriginalMB.top : rcMerger.top;
-  rcMerger.bottom = rcMerger.bottom < rcOriginalMB.bottom ? rcOriginalMB.bottom
-                                                          : rcMerger.bottom;
-
-  if (pPageDict->KeyExist("ArtBox"))
-    rcOriginalCB = pPageDict->GetRect("ArtBox");
-  else
-    rcOriginalCB = rcOriginalMB;
-
-  if (!rcOriginalMB.IsEmpty()) {
-    CPDF_Array* pMediaBox = new CPDF_Array();
-    pMediaBox->Add(new CPDF_Number(rcOriginalMB.left));
-    pMediaBox->Add(new CPDF_Number(rcOriginalMB.bottom));
-    pMediaBox->Add(new CPDF_Number(rcOriginalMB.right));
-    pMediaBox->Add(new CPDF_Number(rcOriginalMB.top));
-    pPageDict->SetAt("MediaBox", pMediaBox);
-  }
-
-  if (!rcOriginalCB.IsEmpty()) {
-    CPDF_Array* pCropBox = new CPDF_Array();
-    pCropBox->Add(new CPDF_Number(rcOriginalCB.left));
-    pCropBox->Add(new CPDF_Number(rcOriginalCB.bottom));
-    pCropBox->Add(new CPDF_Number(rcOriginalCB.right));
-    pCropBox->Add(new CPDF_Number(rcOriginalCB.top));
-    pPageDict->SetAt("ArtBox", pCropBox);
-  }
-
-  CPDF_Dictionary* pRes = pPageDict->GetDict("Resources");
-  if (!pRes) {
-    pRes = new CPDF_Dictionary;
-    pPageDict->SetAt("Resources", pRes);
-  }
-
-  CPDF_Stream* pNewXObject = new CPDF_Stream(NULL, 0, new CPDF_Dictionary);
-  FX_DWORD dwObjNum = pDocument->AddIndirectObject(pNewXObject);
-  CPDF_Dictionary* pPageXObject = pRes->GetDict("XObject");
-  if (!pPageXObject) {
-    pPageXObject = new CPDF_Dictionary;
-    pRes->SetAt("XObject", pPageXObject);
-  }
-
-  CFX_ByteString key = "";
-  int nStreams = ObjectArray.GetSize();
-
-  if (nStreams > 0) {
-    for (int iKey = 0; /*iKey < 100*/; iKey++) {
-      char sExtend[5] = {};
-      FXSYS_itoa(iKey, sExtend, 10);
-      key = CFX_ByteString("FFT") + CFX_ByteString(sExtend);
-
-      if (!pPageXObject->KeyExist(key))
-        break;
-    }
-  }
-
-  SetPageContents(key, pPageDict, pDocument);
-
-  CPDF_Dictionary* pNewXORes = NULL;
-
-  if (!key.IsEmpty()) {
-    pPageXObject->SetAtReference(key, pDocument, dwObjNum);
-    CPDF_Dictionary* pNewOXbjectDic = pNewXObject->GetDict();
-    pNewXORes = new CPDF_Dictionary;
-    pNewOXbjectDic->SetAt("Resources", pNewXORes);
-    pNewOXbjectDic->SetAtName("Type", "XObject");
-    pNewOXbjectDic->SetAtName("Subtype", "Form");
-    pNewOXbjectDic->SetAtInteger("FormType", 1);
-    pNewOXbjectDic->SetAtName("Name", "FRM");
-    CPDF_Rect rcBBox = pPageDict->GetRect("ArtBox");
-    pNewOXbjectDic->SetAtRect("BBox", rcBBox);
-  }
-
-  for (int i = 0; i < nStreams; i++) {
-    CPDF_Dictionary* pAnnotDic = ObjectArray.GetAt(i);
-    if (!pAnnotDic)
-      continue;
-
-    CPDF_Rect rcAnnot = pAnnotDic->GetRect("Rect");
-    rcAnnot.Normalize();
-
-    CFX_ByteString sAnnotState = pAnnotDic->GetString("AS");
-    CPDF_Dictionary* pAnnotAP = pAnnotDic->GetDict("AP");
-    if (!pAnnotAP)
-      continue;
-
-    CPDF_Stream* pAPStream = pAnnotAP->GetStream("N");
-    if (!pAPStream) {
-      CPDF_Dictionary* pAPDic = pAnnotAP->GetDict("N");
-      if (!pAPDic)
-        continue;
-
-      if (!sAnnotState.IsEmpty()) {
-        pAPStream = pAPDic->GetStream(sAnnotState);
-      } else {
-        auto it = pAPDic->begin();
-        if (it != pAPDic->end()) {
-          CPDF_Object* pFirstObj = it->second;
-          if (pFirstObj) {
-            if (pFirstObj->IsReference())
-              pFirstObj = pFirstObj->GetDirect();
-            if (!pFirstObj->IsStream())
-              continue;
-            pAPStream = pFirstObj->AsStream();
-          }
-        }
-      }
-    }
-    if (!pAPStream)
-      continue;
-
-    CPDF_Dictionary* pAPDic = pAPStream->GetDict();
-    CFX_Matrix matrix = pAPDic->GetMatrix("Matrix");
-
-    CPDF_Rect rcStream;
-    if (pAPDic->KeyExist("Rect"))
-      rcStream = pAPDic->GetRect("Rect");
-    else if (pAPDic->KeyExist("BBox"))
-      rcStream = pAPDic->GetRect("BBox");
-
-    if (rcStream.IsEmpty())
-      continue;
-
-    CPDF_Object* pObj = pAPStream;
-
-    if (pObj) {
-      CPDF_Dictionary* pObjDic = pObj->GetDict();
-      if (pObjDic) {
-        pObjDic->SetAtName("Type", "XObject");
-        pObjDic->SetAtName("Subtype", "Form");
-      }
-    }
-
-    CPDF_Dictionary* pXObject = pNewXORes->GetDict("XObject");
-    if (!pXObject) {
-      pXObject = new CPDF_Dictionary;
-      pNewXORes->SetAt("XObject", pXObject);
-    }
-
-    CFX_ByteString sFormName;
-    sFormName.Format("F%d", i);
-    FX_DWORD dwObjNum = pDocument->AddIndirectObject(pObj);
-    pXObject->SetAtReference(sFormName, pDocument, dwObjNum);
-
-    CPDF_StreamAcc acc;
-    acc.LoadAllData(pNewXObject);
-
-    const uint8_t* pData = acc.GetData();
-    CFX_ByteString sStream(pData, acc.GetSize());
-    CFX_ByteString sTemp;
-
-    if (matrix.IsIdentity()) {
-      matrix.a = 1.0f;
-      matrix.b = 0.0f;
-      matrix.c = 0.0f;
-      matrix.d = 1.0f;
-      matrix.e = 0.0f;
-      matrix.f = 0.0f;
-    }
-
-    CFX_Matrix m = GetMatrix(rcAnnot, rcStream, matrix);
-    sTemp.Format("q %f 0 0 %f %f %f cm /%s Do Q\n", m.a, m.d, m.e, m.f,
-                 sFormName.c_str());
-    sStream += sTemp;
-
-    pNewXObject->SetData((const uint8_t*)sStream, sStream.GetLength(), FALSE,
-                         FALSE);
-  }
-  pPageDict->RemoveAt("Annots");
-
-  ObjectArray.RemoveAll();
-  RectArray.RemoveAll();
-
-  return FLATTEN_SUCCESS;
-}
diff --git a/fpdfsdk/src/fpdf_sysfontinfo.cpp b/fpdfsdk/src/fpdf_sysfontinfo.cpp
deleted file mode 100644
index 655c4a2..0000000
--- a/fpdfsdk/src/fpdf_sysfontinfo.cpp
+++ /dev/null
@@ -1,189 +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
-
-#include "public/fpdf_sysfontinfo.h"
-
-#include "fpdfsdk/include/fsdk_define.h"
-#include "fpdfsdk/include/pdfwindow/PWL_FontMap.h"
-
-class CFX_ExternalFontInfo final : public IFX_SystemFontInfo {
- public:
-  explicit CFX_ExternalFontInfo(FPDF_SYSFONTINFO* pInfo) : m_pInfo(pInfo) {}
-
-  void Release() override {
-    if (m_pInfo->Release)
-      m_pInfo->Release(m_pInfo);
-    delete this;
-  }
-
-  FX_BOOL EnumFontList(CFX_FontMapper* pMapper) override {
-    if (m_pInfo->EnumFonts) {
-      m_pInfo->EnumFonts(m_pInfo, pMapper);
-      return TRUE;
-    }
-    return FALSE;
-  }
-
-  void* MapFont(int weight,
-                FX_BOOL bItalic,
-                int charset,
-                int pitch_family,
-                const FX_CHAR* family,
-                int& iExact) override {
-    if (m_pInfo->MapFont)
-      return m_pInfo->MapFont(m_pInfo, weight, bItalic, charset, pitch_family,
-                              family, &iExact);
-    return NULL;
-  }
-
-  void* GetFont(const FX_CHAR* family) override {
-    if (m_pInfo->GetFont)
-      return m_pInfo->GetFont(m_pInfo, family);
-    return NULL;
-  }
-
-  FX_DWORD GetFontData(void* hFont,
-                       FX_DWORD table,
-                       uint8_t* buffer,
-                       FX_DWORD size) override {
-    if (m_pInfo->GetFontData)
-      return m_pInfo->GetFontData(m_pInfo, hFont, table, buffer, size);
-    return 0;
-  }
-
-  FX_BOOL GetFaceName(void* hFont, CFX_ByteString& name) override {
-    if (!m_pInfo->GetFaceName)
-      return FALSE;
-    FX_DWORD size = m_pInfo->GetFaceName(m_pInfo, hFont, NULL, 0);
-    if (size == 0)
-      return FALSE;
-    char* buffer = FX_Alloc(char, size);
-    size = m_pInfo->GetFaceName(m_pInfo, hFont, buffer, size);
-    name = CFX_ByteString(buffer, size);
-    FX_Free(buffer);
-    return TRUE;
-  }
-
-  FX_BOOL GetFontCharset(void* hFont, int& charset) override {
-    if (m_pInfo->GetFontCharset) {
-      charset = m_pInfo->GetFontCharset(m_pInfo, hFont);
-      return TRUE;
-    }
-    return FALSE;
-  }
-
-  void DeleteFont(void* hFont) override {
-    if (m_pInfo->DeleteFont)
-      m_pInfo->DeleteFont(m_pInfo, hFont);
-  }
-
- private:
-  ~CFX_ExternalFontInfo() override {}
-
-  FPDF_SYSFONTINFO* const m_pInfo;
-};
-
-DLLEXPORT void STDCALL FPDF_AddInstalledFont(void* mapper,
-                                             const char* name,
-                                             int charset) {
-  ((CFX_FontMapper*)mapper)->AddInstalledFont(name, charset);
-}
-
-DLLEXPORT void STDCALL FPDF_SetSystemFontInfo(FPDF_SYSFONTINFO* pFontInfoExt) {
-  if (pFontInfoExt->version != 1)
-    return;
-
-  CFX_GEModule::Get()->GetFontMgr()->SetSystemFontInfo(
-      new CFX_ExternalFontInfo(pFontInfoExt));
-}
-
-DLLEXPORT const FPDF_CharsetFontMap* STDCALL FPDF_GetDefaultTTFMap() {
-  return CPWL_FontMap::defaultTTFMap;
-}
-
-struct FPDF_SYSFONTINFO_DEFAULT : public FPDF_SYSFONTINFO {
-  IFX_SystemFontInfo* m_pFontInfo;
-};
-
-static void DefaultRelease(struct _FPDF_SYSFONTINFO* pThis) {
-  ((FPDF_SYSFONTINFO_DEFAULT*)pThis)->m_pFontInfo->Release();
-}
-
-static void DefaultEnumFonts(struct _FPDF_SYSFONTINFO* pThis, void* pMapper) {
-  ((FPDF_SYSFONTINFO_DEFAULT*)pThis)
-      ->m_pFontInfo->EnumFontList((CFX_FontMapper*)pMapper);
-}
-
-static void* DefaultMapFont(struct _FPDF_SYSFONTINFO* pThis,
-                            int weight,
-                            int bItalic,
-                            int charset,
-                            int pitch_family,
-                            const char* family,
-                            int* bExact) {
-  return ((FPDF_SYSFONTINFO_DEFAULT*)pThis)
-      ->m_pFontInfo->MapFont(weight, bItalic, charset, pitch_family, family,
-                             *bExact);
-}
-
-void* DefaultGetFont(struct _FPDF_SYSFONTINFO* pThis, const char* family) {
-  return ((FPDF_SYSFONTINFO_DEFAULT*)pThis)->m_pFontInfo->GetFont(family);
-}
-
-static unsigned long DefaultGetFontData(struct _FPDF_SYSFONTINFO* pThis,
-                                        void* hFont,
-                                        unsigned int table,
-                                        unsigned char* buffer,
-                                        unsigned long buf_size) {
-  return ((FPDF_SYSFONTINFO_DEFAULT*)pThis)
-      ->m_pFontInfo->GetFontData(hFont, table, buffer, buf_size);
-}
-
-static unsigned long DefaultGetFaceName(struct _FPDF_SYSFONTINFO* pThis,
-                                        void* hFont,
-                                        char* buffer,
-                                        unsigned long buf_size) {
-  CFX_ByteString name;
-  if (!((FPDF_SYSFONTINFO_DEFAULT*)pThis)
-           ->m_pFontInfo->GetFaceName(hFont, name))
-    return 0;
-  if (name.GetLength() >= (long)buf_size)
-    return name.GetLength() + 1;
-  FXSYS_strcpy(buffer, name);
-  return name.GetLength() + 1;
-}
-
-static int DefaultGetFontCharset(struct _FPDF_SYSFONTINFO* pThis, void* hFont) {
-  int charset;
-  if (!((FPDF_SYSFONTINFO_DEFAULT*)pThis)
-           ->m_pFontInfo->GetFontCharset(hFont, charset))
-    return 0;
-  return charset;
-}
-
-static void DefaultDeleteFont(struct _FPDF_SYSFONTINFO* pThis, void* hFont) {
-  ((FPDF_SYSFONTINFO_DEFAULT*)pThis)->m_pFontInfo->DeleteFont(hFont);
-}
-
-DLLEXPORT FPDF_SYSFONTINFO* STDCALL FPDF_GetDefaultSystemFontInfo() {
-  IFX_SystemFontInfo* pFontInfo = IFX_SystemFontInfo::CreateDefault(nullptr);
-  if (!pFontInfo)
-    return NULL;
-
-  FPDF_SYSFONTINFO_DEFAULT* pFontInfoExt =
-      FX_Alloc(FPDF_SYSFONTINFO_DEFAULT, 1);
-  pFontInfoExt->DeleteFont = DefaultDeleteFont;
-  pFontInfoExt->EnumFonts = DefaultEnumFonts;
-  pFontInfoExt->GetFaceName = DefaultGetFaceName;
-  pFontInfoExt->GetFont = DefaultGetFont;
-  pFontInfoExt->GetFontCharset = DefaultGetFontCharset;
-  pFontInfoExt->GetFontData = DefaultGetFontData;
-  pFontInfoExt->MapFont = DefaultMapFont;
-  pFontInfoExt->Release = DefaultRelease;
-  pFontInfoExt->version = 1;
-  pFontInfoExt->m_pFontInfo = pFontInfo;
-  return pFontInfoExt;
-}
diff --git a/fpdfsdk/src/fpdfdoc_embeddertest.cpp b/fpdfsdk/src/fpdfdoc_embeddertest.cpp
deleted file mode 100644
index 1c66a15..0000000
--- a/fpdfsdk/src/fpdfdoc_embeddertest.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright 2015 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.
-
-#include "core/include/fxcrt/fx_string.h"
-#include "public/fpdf_doc.h"
-#include "public/fpdfview.h"
-#include "testing/embedder_test.h"
-#include "testing/fx_string_testhelpers.h"
-#include "testing/test_support.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-class FPDFDocEmbeddertest : public EmbedderTest {};
-
-TEST_F(FPDFDocEmbeddertest, DestGetPageIndex) {
-  EXPECT_TRUE(OpenDocument("named_dests.pdf"));
-
-  // NULL FPDF_DEST case.
-  EXPECT_EQ(0U, FPDFDest_GetPageIndex(document(), nullptr));
-
-  // Page number directly in item from Dests NameTree.
-  FPDF_DEST dest = FPDF_GetNamedDestByName(document(), "First");
-  EXPECT_NE(nullptr, dest);
-  EXPECT_EQ(1U, FPDFDest_GetPageIndex(document(), dest));
-
-  // Page number via object reference in item from Dests NameTree.
-  dest = FPDF_GetNamedDestByName(document(), "Next");
-  EXPECT_NE(nullptr, dest);
-  EXPECT_EQ(1U, FPDFDest_GetPageIndex(document(), dest));
-
-  // Page number directly in item from Dests dictionary.
-  dest = FPDF_GetNamedDestByName(document(), "FirstAlternate");
-  EXPECT_NE(nullptr, dest);
-  EXPECT_EQ(11U, FPDFDest_GetPageIndex(document(), dest));
-
-  // Invalid object reference in item from Dests NameTree.
-  dest = FPDF_GetNamedDestByName(document(), "LastAlternate");
-  EXPECT_NE(nullptr, dest);
-  EXPECT_EQ(0U, FPDFDest_GetPageIndex(document(), dest));
-}
-
-TEST_F(FPDFDocEmbeddertest, ActionGetFilePath) {
-  EXPECT_TRUE(OpenDocument("launch_action.pdf"));
-
-  FPDF_PAGE page = FPDF_LoadPage(document(), 0);
-  ASSERT_TRUE(page);
-
-  // The target action is nearly the size of the whole page.
-  FPDF_LINK link = FPDFLink_GetLinkAtPoint(page, 100, 100);
-  ASSERT_TRUE(link);
-
-  FPDF_ACTION action = FPDFLink_GetAction(link);
-  ASSERT_TRUE(action);
-
-  const char kExpectedResult[] = "test.pdf";
-  const unsigned long kExpectedLength = sizeof(kExpectedResult);
-  unsigned long bufsize = FPDFAction_GetFilePath(action, nullptr, 0);
-  ASSERT_EQ(kExpectedLength, bufsize);
-
-  char buf[kExpectedLength];
-  EXPECT_EQ(bufsize, FPDFAction_GetFilePath(action, buf, bufsize));
-  EXPECT_EQ(std::string(kExpectedResult), std::string(buf));
-
-  FPDF_ClosePage(page);
-}
-
-TEST_F(FPDFDocEmbeddertest, NoBookmarks) {
-  // Open a file with no bookmarks.
-  EXPECT_TRUE(OpenDocument("named_dests.pdf"));
-
-  // The non-existent top-level bookmark has no title.
-  unsigned short buf[128];
-  EXPECT_EQ(0, FPDFBookmark_GetTitle(nullptr, buf, sizeof(buf)));
-
-  // The non-existent top-level bookmark has no children.
-  EXPECT_EQ(nullptr, FPDFBookmark_GetFirstChild(document(), nullptr));
-}
-
-TEST_F(FPDFDocEmbeddertest, Bookmarks) {
-  // Open a file with two bookmarks.
-  EXPECT_TRUE(OpenDocument("bookmarks.pdf"));
-
-  // The existent top-level bookmark has no title.
-  unsigned short buf[128];
-  EXPECT_EQ(0, FPDFBookmark_GetTitle(nullptr, buf, sizeof(buf)));
-
-  FPDF_BOOKMARK child = FPDFBookmark_GetFirstChild(document(), nullptr);
-  EXPECT_NE(nullptr, child);
-  EXPECT_EQ(34, FPDFBookmark_GetTitle(child, buf, sizeof(buf)));
-  EXPECT_EQ(CFX_WideString(L"A Good Beginning"),
-            CFX_WideString::FromUTF16LE(buf, 16));
-
-  EXPECT_EQ(nullptr, FPDFBookmark_GetFirstChild(document(), child));
-
-  FPDF_BOOKMARK sibling = FPDFBookmark_GetNextSibling(document(), child);
-  EXPECT_NE(nullptr, sibling);
-  EXPECT_EQ(28, FPDFBookmark_GetTitle(sibling, buf, sizeof(buf)));
-  EXPECT_EQ(CFX_WideString(L"A Good Ending"),
-            CFX_WideString::FromUTF16LE(buf, 13));
-
-  EXPECT_EQ(nullptr, FPDFBookmark_GetNextSibling(document(), sibling));
-}
-
-TEST_F(FPDFDocEmbeddertest, FindBookmarks) {
-  // Open a file with two bookmarks.
-  EXPECT_TRUE(OpenDocument("bookmarks.pdf"));
-
-  // Find the first one, based on its known title.
-  std::unique_ptr<unsigned short, pdfium::FreeDeleter> title =
-      GetFPDFWideString(L"A Good Beginning");
-  FPDF_BOOKMARK child = FPDFBookmark_Find(document(), title.get());
-  EXPECT_NE(nullptr, child);
-
-  // Check that the string matches.
-  unsigned short buf[128];
-  EXPECT_EQ(34, FPDFBookmark_GetTitle(child, buf, sizeof(buf)));
-  EXPECT_EQ(CFX_WideString(L"A Good Beginning"),
-            CFX_WideString::FromUTF16LE(buf, 16));
-
-  // Check that it is them same as the one returned by GetFirstChild.
-  EXPECT_EQ(child, FPDFBookmark_GetFirstChild(document(), nullptr));
-
-  // Try to find one using a non-existent title.
-  std::unique_ptr<unsigned short, pdfium::FreeDeleter> bad_title =
-      GetFPDFWideString(L"A BAD Beginning");
-  EXPECT_EQ(nullptr, FPDFBookmark_Find(document(), bad_title.get()));
-}
diff --git a/fpdfsdk/src/fpdfedit_embeddertest.cpp b/fpdfsdk/src/fpdfedit_embeddertest.cpp
deleted file mode 100644
index 480ef51..0000000
--- a/fpdfsdk/src/fpdfedit_embeddertest.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-// 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.
-
-#include "public/fpdf_edit.h"
-#include "public/fpdfview.h"
-#include "testing/embedder_test.h"
-#include "testing/gmock/include/gmock/gmock-matchers.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/test_support.h"
-
-class FPDFEditEmbeddertest : public EmbedderTest, public TestSaver {};
-
-TEST_F(FPDFEditEmbeddertest, EmptyCreation) {
-  EXPECT_TRUE(CreateEmptyDocument());
-  FPDF_PAGE page = FPDFPage_New(document(), 1, 640.0, 480.0);
-  EXPECT_NE(nullptr, page);
-  EXPECT_TRUE(FPDFPage_GenerateContent(page));
-  EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
-  EXPECT_THAT(GetString(),
-              testing::MatchesRegex(
-                  "%PDF-1.7\r\n"
-                  "%\xA1\xB3\xC5\xD7\r\n"
-                  "1 0 obj\r\n"
-                  "<</Pages 2 0 R /Type/Catalog>>\r\n"
-                  "endobj\r\n"
-                  "2 0 obj\r\n"
-                  "<</Count 1/Kids\\[ 4 0 R \\]/Type/Pages>>\r\n"
-                  "endobj\r\n"
-                  "3 0 obj\r\n"
-                  "<</CreationDate\\(D:.*\\)/Creator\\(PDFium\\)>>\r\n"
-                  "endobj\r\n"
-                  "4 0 obj\r\n"
-                  "<</Contents 5 0 R /MediaBox\\[ 0 0 640 480\\]"
-                  "/Parent 2 0 R /Resources<<>>/Rotate 0/Type/Page"
-                  ">>\r\n"
-                  "endobj\r\n"
-                  "5 0 obj\r\n"
-                  "<</Filter/FlateDecode/Length 8>>stream\r\n"
-                  "x\x9C\x3\0\0\0\0\x1\r\n"
-                  "endstream\r\n"
-                  "endobj\r\n"
-                  "xref\r\n"
-                  "0 6\r\n"
-                  "0000000000 65535 f\r\n"
-                  "0000000017 00000 n\r\n"
-                  "0000000066 00000 n\r\n"
-                  "0000000122 00000 n\r\n"
-                  "0000000192 00000 n\r\n"
-                  "0000000301 00000 n\r\n"
-                  "trailer\r\n"
-                  "<<\r\n"
-                  "/Root 1 0 R\r\n"
-                  "/Info 3 0 R\r\n"
-                  "/Size 6/ID\\[<.*><.*>\\]>>\r\n"
-                  "startxref\r\n"
-                  "379\r\n"
-                  "%%EOF\r\n"));
-  FPDFPage_Delete(document(), 1);
-}
diff --git a/fpdfsdk/src/fpdfeditimg.cpp b/fpdfsdk/src/fpdfeditimg.cpp
deleted file mode 100644
index de5c72f..0000000
--- a/fpdfsdk/src/fpdfeditimg.cpp
+++ /dev/null
@@ -1,83 +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
-
-#include "public/fpdf_edit.h"
-
-#include "fpdfsdk/include/fsdk_define.h"
-
-DLLEXPORT FPDF_PAGEOBJECT STDCALL
-FPDFPageObj_NewImgeObj(FPDF_DOCUMENT document) {
-  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
-  if (!pDoc)
-    return nullptr;
-  CPDF_ImageObject* pImageObj = new CPDF_ImageObject;
-  CPDF_Image* pImg = new CPDF_Image(pDoc);
-  pImageObj->m_pImage = pImg;
-  return pImageObj;
-}
-
-DLLEXPORT FPDF_BOOL STDCALL
-FPDFImageObj_LoadJpegFile(FPDF_PAGE* pages,
-                          int nCount,
-                          FPDF_PAGEOBJECT image_object,
-                          FPDF_FILEACCESS* fileAccess) {
-  if (!image_object || !fileAccess || !pages)
-    return FALSE;
-
-  IFX_FileRead* pFile = new CPDF_CustomAccess(fileAccess);
-  CPDF_ImageObject* pImgObj = (CPDF_ImageObject*)image_object;
-  pImgObj->m_GeneralState.GetModify();
-  for (int index = 0; index < nCount; index++) {
-    CPDF_Page* pPage = CPDFPageFromFPDFPage(pages[index]);
-    if (!pPage)
-      continue;
-    pImgObj->m_pImage->ResetCache(pPage, NULL);
-  }
-  pImgObj->m_pImage->SetJpegImage(pFile);
-
-  return TRUE;
-}
-
-DLLEXPORT FPDF_BOOL STDCALL FPDFImageObj_SetMatrix(FPDF_PAGEOBJECT image_object,
-                                                   double a,
-                                                   double b,
-                                                   double c,
-                                                   double d,
-                                                   double e,
-                                                   double f) {
-  if (!image_object)
-    return FALSE;
-  CPDF_ImageObject* pImgObj = (CPDF_ImageObject*)image_object;
-  pImgObj->m_Matrix.a = (FX_FLOAT)a;
-  pImgObj->m_Matrix.b = (FX_FLOAT)b;
-  pImgObj->m_Matrix.c = (FX_FLOAT)c;
-  pImgObj->m_Matrix.d = (FX_FLOAT)d;
-  pImgObj->m_Matrix.e = (FX_FLOAT)e;
-  pImgObj->m_Matrix.f = (FX_FLOAT)f;
-  pImgObj->CalcBoundingBox();
-  return TRUE;
-}
-
-DLLEXPORT FPDF_BOOL STDCALL FPDFImageObj_SetBitmap(FPDF_PAGE* pages,
-                                                   int nCount,
-                                                   FPDF_PAGEOBJECT image_object,
-                                                   FPDF_BITMAP bitmap) {
-  if (!image_object || !bitmap || !pages)
-    return FALSE;
-  CFX_DIBitmap* pBmp = NULL;
-  pBmp = (CFX_DIBitmap*)bitmap;
-  CPDF_ImageObject* pImgObj = (CPDF_ImageObject*)image_object;
-  pImgObj->m_GeneralState.GetModify();
-  for (int index = 0; index < nCount; index++) {
-    CPDF_Page* pPage = CPDFPageFromFPDFPage(pages[index]);
-    if (!pPage)
-      continue;
-    pImgObj->m_pImage->ResetCache(pPage, NULL);
-  }
-  pImgObj->m_pImage->SetImage(pBmp, FALSE);
-  pImgObj->CalcBoundingBox();
-  return TRUE;
-}
diff --git a/fpdfsdk/src/fpdfeditpage.cpp b/fpdfsdk/src/fpdfeditpage.cpp
deleted file mode 100644
index c6d579a..0000000
--- a/fpdfsdk/src/fpdfeditpage.cpp
+++ /dev/null
@@ -1,312 +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
-
-#include "public/fpdf_edit.h"
-
-#include "fpdfsdk/include/fsdk_define.h"
-#include "public/fpdf_formfill.h"
-
-#ifdef PDF_ENABLE_XFA
-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_app.h"
-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h"
-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_page.h"
-#endif  // PDF_ENABLE_XFA
-
-#if _FX_OS_ == _FX_ANDROID_
-#include "time.h"
-#else
-#include <ctime>
-#endif
-
-DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_CreateNewDocument() {
-  CPDF_Document* pDoc = new CPDF_Document;
-  pDoc->CreateNewDoc();
-  time_t currentTime;
-
-  CFX_ByteString DateStr;
-
-  if (FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS)) {
-    if (-1 != time(&currentTime)) {
-      tm* pTM = localtime(&currentTime);
-      if (pTM) {
-        DateStr.Format("D:%04d%02d%02d%02d%02d%02d", pTM->tm_year + 1900,
-                       pTM->tm_mon + 1, pTM->tm_mday, pTM->tm_hour, pTM->tm_min,
-                       pTM->tm_sec);
-      }
-    }
-  }
-
-  CPDF_Dictionary* pInfoDict = NULL;
-  pInfoDict = pDoc->GetInfo();
-  if (pInfoDict) {
-    if (FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
-      pInfoDict->SetAt("CreationDate", new CPDF_String(DateStr, FALSE));
-    pInfoDict->SetAt("Creator", new CPDF_String(L"PDFium"));
-  }
-
-  return FPDFDocumentFromCPDFDocument(pDoc);
-}
-
-DLLEXPORT void STDCALL FPDFPage_Delete(FPDF_DOCUMENT document, int page_index) {
-  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
-  if (!pDoc || page_index < 0 || page_index >= pDoc->GetPageCount())
-    return;
-
-  pDoc->DeletePage(page_index);
-}
-
-DLLEXPORT FPDF_PAGE STDCALL FPDFPage_New(FPDF_DOCUMENT document,
-                                         int page_index,
-                                         double width,
-                                         double height) {
-  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
-  if (!pDoc)
-    return nullptr;
-
-  if (page_index < 0)
-    page_index = 0;
-  if (pDoc->GetPageCount() < page_index)
-    page_index = pDoc->GetPageCount();
-
-  CPDF_Dictionary* pPageDict = pDoc->CreateNewPage(page_index);
-  if (!pPageDict)
-    return NULL;
-  CPDF_Array* pMediaBoxArray = new CPDF_Array;
-  pMediaBoxArray->Add(new CPDF_Number(0));
-  pMediaBoxArray->Add(new CPDF_Number(0));
-  pMediaBoxArray->Add(new CPDF_Number(FX_FLOAT(width)));
-  pMediaBoxArray->Add(new CPDF_Number(FX_FLOAT(height)));
-
-  pPageDict->SetAt("MediaBox", pMediaBoxArray);
-  pPageDict->SetAt("Rotate", new CPDF_Number(0));
-  pPageDict->SetAt("Resources", new CPDF_Dictionary);
-
-#ifdef PDF_ENABLE_XFA
-  CPDFXFA_Page* pPage =
-      new CPDFXFA_Page((CPDFXFA_Document*)document, page_index);
-  pPage->LoadPDFPage(pPageDict);
-#else   // PDF_ENABLE_XFA
-  CPDF_Page* pPage = new CPDF_Page;
-  pPage->Load(pDoc, pPageDict);
-  pPage->ParseContent();
-#endif  // PDF_ENABLE_XFA
-
-  return pPage;
-}
-
-DLLEXPORT int STDCALL FPDFPage_GetRotation(FPDF_PAGE page) {
-  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
-  if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") ||
-      !pPage->m_pFormDict->GetElement("Type")->GetDirect() ||
-      pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare(
-          "Page")) {
-    return -1;
-  }
-  CPDF_Dictionary* pDict = pPage->m_pFormDict;
-  if (!pDict)
-    return -1;
-
-  while (pDict) {
-    if (pDict->KeyExist("Rotate")) {
-      CPDF_Object* pRotateObj = pDict->GetElement("Rotate")->GetDirect();
-      return pRotateObj ? pRotateObj->GetInteger() / 90 : 0;
-    }
-    if (!pDict->KeyExist("Parent"))
-      break;
-
-    pDict = ToDictionary(pDict->GetElement("Parent")->GetDirect());
-  }
-
-  return 0;
-}
-
-DLLEXPORT void STDCALL FPDFPage_InsertObject(FPDF_PAGE page,
-                                             FPDF_PAGEOBJECT page_obj) {
-  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
-  if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") ||
-      !pPage->m_pFormDict->GetElement("Type")->GetDirect() ||
-      pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare(
-          "Page")) {
-    return;
-  }
-  CPDF_PageObject* pPageObj = (CPDF_PageObject*)page_obj;
-  if (!pPageObj)
-    return;
-  FX_POSITION LastPersition = pPage->GetLastObjectPosition();
-
-  pPage->InsertObject(LastPersition, pPageObj);
-  switch (pPageObj->m_Type) {
-    case FPDF_PAGEOBJ_PATH: {
-      CPDF_PathObject* pPathObj = (CPDF_PathObject*)pPageObj;
-      pPathObj->CalcBoundingBox();
-      break;
-    }
-    case FPDF_PAGEOBJ_TEXT: {
-      //	CPDF_PathObject* pPathObj = (CPDF_PathObject*)pPageObj;
-      //	pPathObj->CalcBoundingBox();
-      break;
-    }
-    case FPDF_PAGEOBJ_IMAGE: {
-      CPDF_ImageObject* pImageObj = (CPDF_ImageObject*)pPageObj;
-      pImageObj->CalcBoundingBox();
-      break;
-    }
-    case FPDF_PAGEOBJ_SHADING: {
-      CPDF_ShadingObject* pShadingObj = (CPDF_ShadingObject*)pPageObj;
-      pShadingObj->CalcBoundingBox();
-      break;
-    }
-    case FPDF_PAGEOBJ_FORM: {
-      CPDF_FormObject* pFormObj = (CPDF_FormObject*)pPageObj;
-      pFormObj->CalcBoundingBox();
-      break;
-    }
-    default:
-      break;
-  }
-}
-
-DLLEXPORT int STDCALL FPDFPage_CountObject(FPDF_PAGE page) {
-  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
-  if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") ||
-      !pPage->m_pFormDict->GetElement("Type")->GetDirect() ||
-      pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare(
-          "Page")) {
-    return -1;
-  }
-  return pPage->CountObjects();
-}
-
-DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPage_GetObject(FPDF_PAGE page,
-                                                     int index) {
-  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
-  if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") ||
-      pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare(
-          "Page")) {
-    return NULL;
-  }
-  return pPage->GetObjectByIndex(index);
-}
-
-DLLEXPORT FPDF_BOOL STDCALL FPDFPage_HasTransparency(FPDF_PAGE page) {
-  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
-  return pPage && pPage->BackgroundAlphaNeeded();
-}
-
-DLLEXPORT FPDF_BOOL STDCALL
-FPDFPageObj_HasTransparency(FPDF_PAGEOBJECT pageObject) {
-  if (!pageObject)
-    return FALSE;
-  CPDF_PageObject* pPageObj = (CPDF_PageObject*)pageObject;
-
-  const CPDF_GeneralStateData* pGeneralState = pPageObj->m_GeneralState;
-  int blend_type =
-      pGeneralState ? pGeneralState->m_BlendType : FXDIB_BLEND_NORMAL;
-  if (blend_type != FXDIB_BLEND_NORMAL)
-    return TRUE;
-
-  CPDF_Dictionary* pSMaskDict =
-      pGeneralState ? ToDictionary(pGeneralState->m_pSoftMask) : NULL;
-  if (pSMaskDict)
-    return TRUE;
-
-  if (pGeneralState && pGeneralState->m_FillAlpha != 1.0f)
-    return TRUE;
-
-  if (pPageObj->m_Type == PDFPAGE_PATH) {
-    if (pGeneralState && pGeneralState->m_StrokeAlpha != 1.0f)
-      return TRUE;
-  }
-
-  if (pPageObj->m_Type == PDFPAGE_FORM) {
-    CPDF_FormObject* pFormObj = (CPDF_FormObject*)pPageObj;
-    if (pFormObj->m_pForm &&
-        (pFormObj->m_pForm->m_Transparency & PDFTRANS_ISOLATED))
-      return TRUE;
-    if (pFormObj->m_pForm &&
-        (!(pFormObj->m_pForm->m_Transparency & PDFTRANS_ISOLATED) &&
-         (pFormObj->m_pForm->m_Transparency & PDFTRANS_GROUP)))
-      return TRUE;
-  }
-  return FALSE;
-}
-
-DLLEXPORT FPDF_BOOL STDCALL FPDFPage_GenerateContent(FPDF_PAGE page) {
-  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
-  if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") ||
-      !pPage->m_pFormDict->GetElement("Type")->GetDirect() ||
-      pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare(
-          "Page")) {
-    return FALSE;
-  }
-  CPDF_PageContentGenerate CG(pPage);
-  CG.GenerateContent();
-
-  return TRUE;
-}
-
-DLLEXPORT void STDCALL FPDFPageObj_Transform(FPDF_PAGEOBJECT page_object,
-                                             double a,
-                                             double b,
-                                             double c,
-                                             double d,
-                                             double e,
-                                             double f) {
-  CPDF_PageObject* pPageObj = (CPDF_PageObject*)page_object;
-  if (!pPageObj)
-    return;
-
-  CFX_Matrix matrix((FX_FLOAT)a, (FX_FLOAT)b, (FX_FLOAT)c, (FX_FLOAT)d,
-                    (FX_FLOAT)e, (FX_FLOAT)f);
-  pPageObj->Transform(matrix);
-}
-DLLEXPORT void STDCALL FPDFPage_TransformAnnots(FPDF_PAGE page,
-                                                double a,
-                                                double b,
-                                                double c,
-                                                double d,
-                                                double e,
-                                                double f) {
-  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
-  if (!pPage)
-    return;
-  CPDF_AnnotList AnnotList(pPage);
-  for (size_t i = 0; i < AnnotList.Count(); ++i) {
-    CPDF_Annot* pAnnot = AnnotList.GetAt(i);
-    // transformAnnots Rectangle
-    CPDF_Rect rect;
-    pAnnot->GetRect(rect);
-    CFX_Matrix matrix((FX_FLOAT)a, (FX_FLOAT)b, (FX_FLOAT)c, (FX_FLOAT)d,
-                      (FX_FLOAT)e, (FX_FLOAT)f);
-    rect.Transform(&matrix);
-    CPDF_Array* pRectArray = NULL;
-    pRectArray = pAnnot->GetAnnotDict()->GetArray("Rect");
-    if (!pRectArray)
-      pRectArray = new CPDF_Array;
-    pRectArray->SetAt(0, new CPDF_Number(rect.left));
-    pRectArray->SetAt(1, new CPDF_Number(rect.bottom));
-    pRectArray->SetAt(2, new CPDF_Number(rect.right));
-    pRectArray->SetAt(3, new CPDF_Number(rect.top));
-    pAnnot->GetAnnotDict()->SetAt("Rect", pRectArray);
-
-    // Transform AP's rectangle
-    // To Do
-  }
-}
-
-DLLEXPORT void STDCALL FPDFPage_SetRotation(FPDF_PAGE page, int rotate) {
-  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
-  if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") ||
-      !pPage->m_pFormDict->GetElement("Type")->GetDirect() ||
-      pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare(
-          "Page")) {
-    return;
-  }
-  CPDF_Dictionary* pDict = pPage->m_pFormDict;
-  rotate %= 4;
-
-  pDict->SetAt("Rotate", new CPDF_Number(rotate * 90));
-}
diff --git a/fpdfsdk/src/fpdfformfill.cpp b/fpdfsdk/src/fpdfformfill.cpp
deleted file mode 100644
index b870d38..0000000
--- a/fpdfsdk/src/fpdfformfill.cpp
+++ /dev/null
@@ -1,743 +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
-
-#include "public/fpdf_formfill.h"
-
-#include <memory>
-
-#include "fpdfsdk/include/fsdk_define.h"
-#include "fpdfsdk/include/fsdk_mgr.h"
-#include "public/fpdfview.h"
-
-#ifdef PDF_ENABLE_XFA
-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_app.h"
-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h"
-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_page.h"
-#endif  // PDF_ENABLE_XFA
-
-namespace {
-
-CPDFSDK_Document* FormHandleToSDKDoc(FPDF_FORMHANDLE hHandle) {
-  CPDFDoc_Environment* pEnv = (CPDFDoc_Environment*)hHandle;
-  return pEnv ? pEnv->GetSDKDocument() : nullptr;
-}
-
-CPDFSDK_InterForm* FormHandleToInterForm(FPDF_FORMHANDLE hHandle) {
-  CPDFSDK_Document* pSDKDoc = FormHandleToSDKDoc(hHandle);
-  return pSDKDoc ? pSDKDoc->GetInterForm() : nullptr;
-}
-
-CPDFSDK_PageView* FormHandleToPageView(FPDF_FORMHANDLE hHandle,
-                                       FPDF_PAGE page) {
-  UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
-  if (!pPage)
-    return nullptr;
-
-  CPDFSDK_Document* pSDKDoc = FormHandleToSDKDoc(hHandle);
-  return pSDKDoc ? pSDKDoc->GetPageView(pPage, TRUE) : nullptr;
-}
-
-}  // namespace
-
-DLLEXPORT int STDCALL FPDFPage_HasFormFieldAtPoint(FPDF_FORMHANDLE hHandle,
-                                                   FPDF_PAGE page,
-                                                   double page_x,
-                                                   double page_y) {
-  if (!hHandle)
-    return -1;
-  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
-#ifdef PDF_ENABLE_XFA
-  if (pPage) {
-    CPDF_InterForm interform(pPage->m_pDocument, FALSE);
-    CPDF_FormControl* pFormCtrl = interform.GetControlAtPoint(
-        pPage, (FX_FLOAT)page_x, (FX_FLOAT)page_y, nullptr);
-    if (!pFormCtrl)
-      return -1;
-
-    CPDF_FormField* pFormField = pFormCtrl->GetField();
-    if (!pFormField)
-      return -1;
-
-    int nType = pFormField->GetFieldType();
-    return nType;
-  }
-
-  IXFA_PageView* pPageView = ((CPDFXFA_Page*)page)->GetXFAPageView();
-  if (pPageView) {
-    IXFA_WidgetHandler* pWidgetHandler = NULL;
-    IXFA_DocView* pDocView = pPageView->GetDocView();
-    if (!pDocView)
-      return -1;
-
-    pWidgetHandler = pDocView->GetWidgetHandler();
-    if (!pWidgetHandler)
-      return -1;
-
-    IXFA_Widget* pXFAAnnot = NULL;
-    IXFA_WidgetIterator* pWidgetIterator = pPageView->CreateWidgetIterator(
-        XFA_TRAVERSEWAY_Form,
-        XFA_WIDGETFILTER_Viewable | XFA_WIDGETFILTER_AllType);
-    if (!pWidgetIterator)
-      return -1;
-    pXFAAnnot = pWidgetIterator->MoveToNext();
-    while (pXFAAnnot) {
-      CFX_RectF rcBBox;
-      pWidgetHandler->GetBBox(pXFAAnnot, rcBBox, 0);
-      CFX_FloatRect rcWidget(rcBBox.left, rcBBox.top,
-                             rcBBox.left + rcBBox.width,
-                             rcBBox.top + rcBBox.height);
-      rcWidget.left -= 1.0f;
-      rcWidget.right += 1.0f;
-      rcWidget.bottom -= 1.0f;
-      rcWidget.top += 1.0f;
-
-      if (rcWidget.Contains(static_cast<FX_FLOAT>(page_x),
-                            static_cast<FX_FLOAT>(page_y))) {
-        pWidgetIterator->Release();
-        return FPDF_FORMFIELD_XFA;
-      }
-      pXFAAnnot = pWidgetIterator->MoveToNext();
-    }
-
-    pWidgetIterator->Release();
-  }
-  return -1;
-#else   // PDF_ENABLE_XFA
-  if (!pPage)
-    return -1;
-  CPDF_InterForm interform(pPage->m_pDocument, FALSE);
-  CPDF_FormControl* pFormCtrl = interform.GetControlAtPoint(
-      pPage, (FX_FLOAT)page_x, (FX_FLOAT)page_y, nullptr);
-  if (!pFormCtrl)
-    return -1;
-  CPDF_FormField* pFormField = pFormCtrl->GetField();
-  return pFormField ? pFormField->GetFieldType() : -1;
-#endif  // PDF_ENABLE_XFA
-}
-
-DLLEXPORT int STDCALL FPDPage_HasFormFieldAtPoint(FPDF_FORMHANDLE hHandle,
-                                                  FPDF_PAGE page,
-                                                  double page_x,
-                                                  double page_y) {
-  return FPDFPage_HasFormFieldAtPoint(hHandle, page, page_x, page_y);
-}
-
-DLLEXPORT int STDCALL FPDFPage_FormFieldZOrderAtPoint(FPDF_FORMHANDLE hHandle,
-                                                      FPDF_PAGE page,
-                                                      double page_x,
-                                                      double page_y) {
-  if (!hHandle)
-    return -1;
-  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
-  if (!pPage)
-    return -1;
-  CPDF_InterForm interform(pPage->m_pDocument, FALSE);
-  int z_order = -1;
-  (void)interform.GetControlAtPoint(pPage, (FX_FLOAT)page_x, (FX_FLOAT)page_y,
-                                    &z_order);
-  return z_order;
-}
-
-DLLEXPORT FPDF_FORMHANDLE STDCALL
-FPDFDOC_InitFormFillEnvironment(FPDF_DOCUMENT document,
-                                FPDF_FORMFILLINFO* formInfo) {
-#ifdef PDF_ENABLE_XFA
-  const int kRequiredVersion = 2;
-#else   // PDF_ENABLE_XFA
-  const int kRequiredVersion = 1;
-#endif  // PDF_ENABLE_XFA
-  if (!formInfo || formInfo->version != kRequiredVersion)
-    return nullptr;
-
-  UnderlyingDocumentType* pDocument = UnderlyingFromFPDFDocument(document);
-  if (!pDocument)
-    return nullptr;
-
-  CPDFDoc_Environment* pEnv = new CPDFDoc_Environment(pDocument, formInfo);
-#ifdef PDF_ENABLE_XFA
-  pEnv->SetSDKDocument(pDocument->GetSDKDocument(pEnv));
-  CPDFXFA_App* pApp = CPDFXFA_App::GetInstance();
-  pApp->AddFormFillEnv(pEnv);
-#else  // PDF_ENABLE_XFA
-  pEnv->SetSDKDocument(new CPDFSDK_Document(pDocument, pEnv));
-#endif  // PDF_ENABLE_XFA
-  return pEnv;
-}
-
-DLLEXPORT void STDCALL
-FPDFDOC_ExitFormFillEnvironment(FPDF_FORMHANDLE hHandle) {
-  if (!hHandle)
-    return;
-  CPDFDoc_Environment* pEnv = (CPDFDoc_Environment*)hHandle;
-#ifdef PDF_ENABLE_XFA
-  CPDFXFA_App* pApp = CPDFXFA_App::GetInstance();
-  pApp->RemoveFormFillEnv(pEnv);
-#else   // PDF_ENABLE_XFA
-  if (CPDFSDK_Document* pSDKDoc = pEnv->GetSDKDocument()) {
-    pEnv->SetSDKDocument(NULL);
-    delete pSDKDoc;
-  }
-#endif  // PDF_ENABLE_XFA
-  delete pEnv;
-}
-
-DLLEXPORT FPDF_BOOL STDCALL FORM_OnMouseMove(FPDF_FORMHANDLE hHandle,
-                                             FPDF_PAGE page,
-                                             int modifier,
-                                             double page_x,
-                                             double page_y) {
-  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
-  if (!pPageView)
-    return FALSE;
-
-  CPDF_Point pt((FX_FLOAT)page_x, (FX_FLOAT)page_y);
-  return pPageView->OnMouseMove(pt, modifier);
-}
-
-DLLEXPORT FPDF_BOOL STDCALL FORM_OnLButtonDown(FPDF_FORMHANDLE hHandle,
-                                               FPDF_PAGE page,
-                                               int modifier,
-                                               double page_x,
-                                               double page_y) {
-  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
-  if (!pPageView)
-    return FALSE;
-
-  CPDF_Point pt((FX_FLOAT)page_x, (FX_FLOAT)page_y);
-  return pPageView->OnLButtonDown(pt, modifier);
-}
-
-DLLEXPORT FPDF_BOOL STDCALL FORM_OnLButtonUp(FPDF_FORMHANDLE hHandle,
-                                             FPDF_PAGE page,
-                                             int modifier,
-                                             double page_x,
-                                             double page_y) {
-  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
-  if (!pPageView)
-    return FALSE;
-
-  CPDF_Point pt((FX_FLOAT)page_x, (FX_FLOAT)page_y);
-  return pPageView->OnLButtonUp(pt, modifier);
-}
-
-#ifdef PDF_ENABLE_XFA
-DLLEXPORT FPDF_BOOL STDCALL FORM_OnRButtonDown(FPDF_FORMHANDLE hHandle,
-                                               FPDF_PAGE page,
-                                               int modifier,
-                                               double page_x,
-                                               double page_y) {
-  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
-  if (!pPageView)
-    return FALSE;
-
-  CPDF_Point pt((FX_FLOAT)page_x, (FX_FLOAT)page_y);
-  return pPageView->OnRButtonDown(pt, modifier);
-}
-
-DLLEXPORT FPDF_BOOL STDCALL FORM_OnRButtonUp(FPDF_FORMHANDLE hHandle,
-                                             FPDF_PAGE page,
-                                             int modifier,
-                                             double page_x,
-                                             double page_y) {
-  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
-  if (!pPageView)
-    return FALSE;
-
-  CPDF_Point pt((FX_FLOAT)page_x, (FX_FLOAT)page_y);
-  return pPageView->OnRButtonUp(pt, modifier);
-}
-#endif  // PDF_ENABLE_XFA
-
-DLLEXPORT FPDF_BOOL STDCALL FORM_OnKeyDown(FPDF_FORMHANDLE hHandle,
-                                           FPDF_PAGE page,
-                                           int nKeyCode,
-                                           int modifier) {
-  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
-  if (!pPageView)
-    return FALSE;
-
-  return pPageView->OnKeyDown(nKeyCode, modifier);
-}
-
-DLLEXPORT FPDF_BOOL STDCALL FORM_OnKeyUp(FPDF_FORMHANDLE hHandle,
-                                         FPDF_PAGE page,
-                                         int nKeyCode,
-                                         int modifier) {
-  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
-  if (!pPageView)
-    return FALSE;
-
-  return pPageView->OnKeyUp(nKeyCode, modifier);
-}
-
-DLLEXPORT FPDF_BOOL STDCALL FORM_OnChar(FPDF_FORMHANDLE hHandle,
-                                        FPDF_PAGE page,
-                                        int nChar,
-                                        int modifier) {
-  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
-  if (!pPageView)
-    return FALSE;
-
-  return pPageView->OnChar(nChar, modifier);
-}
-
-DLLEXPORT FPDF_BOOL STDCALL FORM_ForceToKillFocus(FPDF_FORMHANDLE hHandle) {
-  CPDFSDK_Document* pSDKDoc = FormHandleToSDKDoc(hHandle);
-  if (!pSDKDoc)
-    return FALSE;
-
-  return pSDKDoc->KillFocusAnnot(0);
-}
-
-DLLEXPORT void STDCALL FPDF_FFLDraw(FPDF_FORMHANDLE hHandle,
-                                    FPDF_BITMAP bitmap,
-                                    FPDF_PAGE page,
-                                    int start_x,
-                                    int start_y,
-                                    int size_x,
-                                    int size_y,
-                                    int rotate,
-                                    int flags) {
-  if (!hHandle)
-    return;
-
-  UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
-  if (!pPage)
-    return;
-
-#ifndef PDF_ENABLE_XFA
-  CPDF_RenderOptions options;
-  if (flags & FPDF_LCD_TEXT)
-    options.m_Flags |= RENDER_CLEARTYPE;
-  else
-    options.m_Flags &= ~RENDER_CLEARTYPE;
-  // Grayscale output
-  if (flags & FPDF_GRAYSCALE) {
-    options.m_ColorMode = RENDER_COLOR_GRAY;
-    options.m_ForeColor = 0;
-    options.m_BackColor = 0xffffff;
-  }
-  options.m_AddFlags = flags >> 8;
-  options.m_pOCContext = new CPDF_OCContext(pPage->m_pDocument);
-#else   // PDF_ENABLE_XFA
-  CPDFXFA_Document* pDocument = pPage->GetDocument();
-  if (!pDocument)
-    return;
-  CPDF_Document* pPDFDoc = pDocument->GetPDFDoc();
-  if (!pPDFDoc)
-    return;
-  CPDFDoc_Environment* pEnv = (CPDFDoc_Environment*)hHandle;
-  CPDFSDK_Document* pFXDoc = pEnv->GetSDKDocument();
-  if (!pFXDoc)
-    return;
-#endif  // PDF_ENABLE_XFA
-
-  CFX_Matrix matrix;
-  pPage->GetDisplayMatrix(matrix, start_x, start_y, size_x, size_y, rotate);
-
-  FX_RECT clip;
-  clip.left = start_x;
-  clip.right = start_x + size_x;
-  clip.top = start_y;
-  clip.bottom = start_y + size_y;
-
-#ifdef _SKIA_SUPPORT_
-  std::unique_ptr<CFX_SkiaDevice> pDevice(new CFX_SkiaDevice);
-#else
-  std::unique_ptr<CFX_FxgeDevice> pDevice(new CFX_FxgeDevice);
-#endif
-  pDevice->Attach((CFX_DIBitmap*)bitmap);
-  pDevice->SaveState();
-  pDevice->SetClip_Rect(&clip);
-
-#ifndef PDF_ENABLE_XFA
-  if (CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, pPage))
-    pPageView->PageView_OnDraw(pDevice.get(), &matrix, &options);
-#else   // PDF_ENABLE_XFA
-  CPDF_RenderOptions options;
-  if (flags & FPDF_LCD_TEXT)
-    options.m_Flags |= RENDER_CLEARTYPE;
-  else
-    options.m_Flags &= ~RENDER_CLEARTYPE;
-
-  // Grayscale output
-  if (flags & FPDF_GRAYSCALE) {
-    options.m_ColorMode = RENDER_COLOR_GRAY;
-    options.m_ForeColor = 0;
-    options.m_BackColor = 0xffffff;
-  }
-  options.m_AddFlags = flags >> 8;
-  options.m_pOCContext = new CPDF_OCContext(pPDFDoc);
-
-  if (CPDFSDK_PageView* pPageView = pFXDoc->GetPageView(pPage))
-    pPageView->PageView_OnDraw(pDevice.get(), &matrix, &options, clip);
-#endif  // PDF_ENABLE_XFA
-
-  pDevice->RestoreState();
-  delete options.m_pOCContext;
-#ifdef PDF_ENABLE_XFA
-  options.m_pOCContext = NULL;
-#endif  // PDF_ENABLE_XFA
-}
-
-#ifdef PDF_ENABLE_XFA
-DLLEXPORT void STDCALL FPDF_Widget_Undo(FPDF_DOCUMENT document,
-                                        FPDF_WIDGET hWidget) {
-  if (NULL == hWidget || NULL == document)
-    return;
-
-  CPDFXFA_Document* pDocument = (CPDFXFA_Document*)document;
-  if (pDocument->GetDocType() != XFA_DOCTYPE_Dynamic &&
-      pDocument->GetDocType() != XFA_DOCTYPE_Static)
-    return;
-
-  IXFA_MenuHandler* pXFAMenuHander =
-      CPDFXFA_App::GetInstance()->GetXFAApp()->GetMenuHandler();
-  if (pXFAMenuHander == NULL)
-    return;
-
-  pXFAMenuHander->Undo((IXFA_Widget*)hWidget);
-}
-DLLEXPORT void STDCALL FPDF_Widget_Redo(FPDF_DOCUMENT document,
-                                        FPDF_WIDGET hWidget) {
-  if (NULL == hWidget || NULL == document)
-    return;
-
-  CPDFXFA_Document* pDocument = (CPDFXFA_Document*)document;
-  if (pDocument->GetDocType() != XFA_DOCTYPE_Dynamic &&
-      pDocument->GetDocType() != XFA_DOCTYPE_Static)
-    return;
-
-  IXFA_MenuHandler* pXFAMenuHander =
-      CPDFXFA_App::GetInstance()->GetXFAApp()->GetMenuHandler();
-  if (pXFAMenuHander == NULL)
-    return;
-
-  pXFAMenuHander->Redo((IXFA_Widget*)hWidget);
-}
-
-DLLEXPORT void STDCALL FPDF_Widget_SelectAll(FPDF_DOCUMENT document,
-                                             FPDF_WIDGET hWidget) {
-  if (NULL == hWidget || NULL == document)
-    return;
-
-  CPDFXFA_Document* pDocument = (CPDFXFA_Document*)document;
-  if (pDocument->GetDocType() != XFA_DOCTYPE_Dynamic &&
-      pDocument->GetDocType() != XFA_DOCTYPE_Static)
-    return;
-
-  IXFA_MenuHandler* pXFAMenuHander =
-      CPDFXFA_App::GetInstance()->GetXFAApp()->GetMenuHandler();
-  if (pXFAMenuHander == NULL)
-    return;
-
-  pXFAMenuHander->SelectAll((IXFA_Widget*)hWidget);
-}
-DLLEXPORT void STDCALL FPDF_Widget_Copy(FPDF_DOCUMENT document,
-                                        FPDF_WIDGET hWidget,
-                                        FPDF_WIDESTRING wsText,
-                                        FPDF_DWORD* size) {
-  if (NULL == hWidget || NULL == document)
-    return;
-
-  CPDFXFA_Document* pDocument = (CPDFXFA_Document*)document;
-  if (pDocument->GetDocType() != XFA_DOCTYPE_Dynamic &&
-      pDocument->GetDocType() != XFA_DOCTYPE_Static)
-    return;
-
-  IXFA_MenuHandler* pXFAMenuHander =
-      CPDFXFA_App::GetInstance()->GetXFAApp()->GetMenuHandler();
-  if (pXFAMenuHander == NULL)
-    return;
-
-  CFX_WideString wsCpText;
-  pXFAMenuHander->Copy((IXFA_Widget*)hWidget, wsCpText);
-
-  CFX_ByteString bsCpText = wsCpText.UTF16LE_Encode();
-  int len = bsCpText.GetLength() / sizeof(unsigned short);
-  if (wsText == NULL) {
-    *size = len;
-    return;
-  }
-
-  int real_size = len < *size ? len : *size;
-  if (real_size > 0) {
-    FXSYS_memcpy((void*)wsText,
-                 bsCpText.GetBuffer(real_size * sizeof(unsigned short)),
-                 real_size * sizeof(unsigned short));
-    bsCpText.ReleaseBuffer(real_size * sizeof(unsigned short));
-  }
-  *size = real_size;
-}
-DLLEXPORT void STDCALL FPDF_Widget_Cut(FPDF_DOCUMENT document,
-                                       FPDF_WIDGET hWidget,
-                                       FPDF_WIDESTRING wsText,
-                                       FPDF_DWORD* size) {
-  if (NULL == hWidget || NULL == document)
-    return;
-  CPDFXFA_Document* pDocument = (CPDFXFA_Document*)document;
-  if (pDocument->GetDocType() != XFA_DOCTYPE_Dynamic &&
-      pDocument->GetDocType() != XFA_DOCTYPE_Static)
-    return;
-
-  IXFA_MenuHandler* pXFAMenuHander =
-      CPDFXFA_App::GetInstance()->GetXFAApp()->GetMenuHandler();
-  if (pXFAMenuHander == NULL)
-    return;
-
-  CFX_WideString wsCpText;
-  pXFAMenuHander->Cut((IXFA_Widget*)hWidget, wsCpText);
-
-  CFX_ByteString bsCpText = wsCpText.UTF16LE_Encode();
-  int len = bsCpText.GetLength() / sizeof(unsigned short);
-  if (wsText == NULL) {
-    *size = len;
-    return;
-  }
-
-  int real_size = len < *size ? len : *size;
-  if (real_size > 0) {
-    FXSYS_memcpy((void*)wsText,
-                 bsCpText.GetBuffer(real_size * sizeof(unsigned short)),
-                 real_size * sizeof(unsigned short));
-    bsCpText.ReleaseBuffer(real_size * sizeof(unsigned short));
-  }
-  *size = real_size;
-}
-DLLEXPORT void STDCALL FPDF_Widget_Paste(FPDF_DOCUMENT document,
-                                         FPDF_WIDGET hWidget,
-                                         FPDF_WIDESTRING wsText,
-                                         FPDF_DWORD size) {
-  if (NULL == hWidget || NULL == document)
-    return;
-
-  CPDFXFA_Document* pDocument = (CPDFXFA_Document*)document;
-  if (pDocument->GetDocType() != XFA_DOCTYPE_Dynamic &&
-      pDocument->GetDocType() != XFA_DOCTYPE_Static)
-    return;
-
-  IXFA_MenuHandler* pXFAMenuHander =
-      CPDFXFA_App::GetInstance()->GetXFAApp()->GetMenuHandler();
-  if (pXFAMenuHander == NULL)
-    return;
-
-  CFX_WideString wstr = CFX_WideString::FromUTF16LE(wsText, size);
-  pXFAMenuHander->Paste((IXFA_Widget*)hWidget, wstr);
-}
-DLLEXPORT void STDCALL
-FPDF_Widget_ReplaceSpellCheckWord(FPDF_DOCUMENT document,
-                                  FPDF_WIDGET hWidget,
-                                  float x,
-                                  float y,
-                                  FPDF_BYTESTRING bsText) {
-  if (NULL == hWidget || NULL == document)
-    return;
-
-  CPDFXFA_Document* pDocument = (CPDFXFA_Document*)document;
-  if (pDocument->GetDocType() != XFA_DOCTYPE_Dynamic &&
-      pDocument->GetDocType() != XFA_DOCTYPE_Static)
-    return;
-
-  IXFA_MenuHandler* pXFAMenuHander =
-      CPDFXFA_App::GetInstance()->GetXFAApp()->GetMenuHandler();
-  if (pXFAMenuHander == NULL)
-    return;
-
-  CFX_PointF ptPopup;
-  ptPopup.x = x;
-  ptPopup.y = y;
-  CFX_ByteStringC bs(bsText);
-  pXFAMenuHander->ReplaceSpellCheckWord((IXFA_Widget*)hWidget, ptPopup, bs);
-}
-DLLEXPORT void STDCALL
-FPDF_Widget_GetSpellCheckWords(FPDF_DOCUMENT document,
-                               FPDF_WIDGET hWidget,
-                               float x,
-                               float y,
-                               FPDF_STRINGHANDLE* stringHandle) {
-  if (NULL == hWidget || NULL == document)
-    return;
-
-  CPDFXFA_Document* pDocument = (CPDFXFA_Document*)document;
-  if (pDocument->GetDocType() != XFA_DOCTYPE_Dynamic &&
-      pDocument->GetDocType() != XFA_DOCTYPE_Static)
-    return;
-
-  IXFA_MenuHandler* pXFAMenuHander =
-      CPDFXFA_App::GetInstance()->GetXFAApp()->GetMenuHandler();
-  if (pXFAMenuHander == NULL)
-    return;
-
-  CFX_ByteStringArray* sSuggestWords = new CFX_ByteStringArray;
-  CFX_PointF ptPopup;
-  ptPopup.x = x;
-  ptPopup.y = y;
-  pXFAMenuHander->GetSuggestWords((IXFA_Widget*)hWidget, ptPopup,
-                                  *sSuggestWords);
-  *stringHandle = (FPDF_STRINGHANDLE)sSuggestWords;
-}
-DLLEXPORT int STDCALL FPDF_StringHandleCounts(FPDF_STRINGHANDLE stringHandle) {
-  if (stringHandle == NULL)
-    return -1;
-  CFX_ByteStringArray* sSuggestWords = (CFX_ByteStringArray*)stringHandle;
-  return sSuggestWords->GetSize();
-}
-DLLEXPORT FPDF_BOOL STDCALL
-FPDF_StringHandleGetStringByIndex(FPDF_STRINGHANDLE stringHandle,
-                                  int index,
-                                  FPDF_BYTESTRING bsText,
-                                  FPDF_DWORD* size) {
-  if (stringHandle == NULL || size == NULL)
-    return FALSE;
-  int count = FPDF_StringHandleCounts(stringHandle);
-  if (index < 0 || index >= count)
-    return FALSE;
-
-  CFX_ByteStringArray sSuggestWords = *(CFX_ByteStringArray*)stringHandle;
-  int len = sSuggestWords[index].GetLength();
-
-  if (bsText == NULL) {
-    *size = len;
-    return TRUE;
-  }
-
-  int real_size = len < *size ? len : *size;
-  if (real_size > 0)
-    FXSYS_memcpy((void*)bsText, (const FX_CHAR*)(sSuggestWords[index]),
-                 real_size);
-  *size = real_size;
-
-  return TRUE;
-}
-DLLEXPORT void STDCALL
-FPDF_StringHandleRelease(FPDF_STRINGHANDLE stringHandle) {
-  if (stringHandle == NULL)
-    return;
-  CFX_ByteStringArray* sSuggestWords = (CFX_ByteStringArray*)stringHandle;
-  delete sSuggestWords;
-}
-
-DLLEXPORT FPDF_BOOL STDCALL
-FPDF_StringHandleAddString(FPDF_STRINGHANDLE stringHandle,
-                           FPDF_BYTESTRING bsText,
-                           FPDF_DWORD size) {
-  if (stringHandle == NULL || bsText == NULL || size <= 0)
-    return FALSE;
-
-  CFX_ByteStringArray* stringArr = (CFX_ByteStringArray*)stringHandle;
-  CFX_ByteString bsStr(bsText, size);
-
-  stringArr->Add(bsStr);
-  return TRUE;
-}
-#endif  // PDF_ENABLE_XFA
-
-DLLEXPORT void STDCALL FPDF_SetFormFieldHighlightColor(FPDF_FORMHANDLE hHandle,
-                                                       int fieldType,
-                                                       unsigned long color) {
-  if (CPDFSDK_InterForm* pInterForm = FormHandleToInterForm(hHandle))
-    pInterForm->SetHighlightColor(color, fieldType);
-}
-
-DLLEXPORT void STDCALL FPDF_SetFormFieldHighlightAlpha(FPDF_FORMHANDLE hHandle,
-                                                       unsigned char alpha) {
-  if (CPDFSDK_InterForm* pInterForm = FormHandleToInterForm(hHandle))
-    pInterForm->SetHighlightAlpha(alpha);
-}
-
-DLLEXPORT void STDCALL FPDF_RemoveFormFieldHighlight(FPDF_FORMHANDLE hHandle) {
-  if (CPDFSDK_InterForm* pInterForm = FormHandleToInterForm(hHandle))
-    pInterForm->RemoveAllHighLight();
-}
-
-DLLEXPORT void STDCALL FORM_OnAfterLoadPage(FPDF_PAGE page,
-                                            FPDF_FORMHANDLE hHandle) {
-  if (CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page))
-    pPageView->SetValid(TRUE);
-}
-
-DLLEXPORT void STDCALL FORM_OnBeforeClosePage(FPDF_PAGE page,
-                                              FPDF_FORMHANDLE hHandle) {
-  if (!hHandle)
-    return;
-
-  CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetSDKDocument();
-  if (!pSDKDoc)
-    return;
-
-  UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
-  if (!pPage)
-    return;
-
-  CPDFSDK_PageView* pPageView = pSDKDoc->GetPageView(pPage, FALSE);
-  if (pPageView) {
-    pPageView->SetValid(FALSE);
-    // RemovePageView() takes care of the delete for us.
-    pSDKDoc->RemovePageView(pPage);
-  }
-}
-
-DLLEXPORT void STDCALL FORM_DoDocumentJSAction(FPDF_FORMHANDLE hHandle) {
-  CPDFSDK_Document* pSDKDoc = FormHandleToSDKDoc(hHandle);
-  if (pSDKDoc && ((CPDFDoc_Environment*)hHandle)->IsJSInitiated())
-    pSDKDoc->ProcJavascriptFun();
-}
-
-DLLEXPORT void STDCALL FORM_DoDocumentOpenAction(FPDF_FORMHANDLE hHandle) {
-  CPDFSDK_Document* pSDKDoc = FormHandleToSDKDoc(hHandle);
-  if (pSDKDoc && ((CPDFDoc_Environment*)hHandle)->IsJSInitiated())
-    pSDKDoc->ProcOpenAction();
-}
-
-DLLEXPORT void STDCALL FORM_DoDocumentAAction(FPDF_FORMHANDLE hHandle,
-                                              int aaType) {
-  CPDFSDK_Document* pSDKDoc = FormHandleToSDKDoc(hHandle);
-  if (!pSDKDoc)
-    return;
-
-  CPDF_Document* pDoc = pSDKDoc->GetPDFDocument();
-  CPDF_Dictionary* pDic = pDoc->GetRoot();
-  if (!pDic)
-    return;
-
-  CPDF_AAction aa = pDic->GetDict("AA");
-  if (aa.ActionExist((CPDF_AAction::AActionType)aaType)) {
-    CPDF_Action action = aa.GetAction((CPDF_AAction::AActionType)aaType);
-    CPDFSDK_ActionHandler* pActionHandler =
-        ((CPDFDoc_Environment*)hHandle)->GetActionHander();
-    pActionHandler->DoAction_Document(action, (CPDF_AAction::AActionType)aaType,
-                                      pSDKDoc);
-  }
-}
-
-DLLEXPORT void STDCALL FORM_DoPageAAction(FPDF_PAGE page,
-                                          FPDF_FORMHANDLE hHandle,
-                                          int aaType) {
-  if (!hHandle)
-    return;
-  CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetSDKDocument();
-  UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
-  CPDF_Page* pPDFPage = CPDFPageFromFPDFPage(page);
-  if (!pPDFPage)
-    return;
-  if (pSDKDoc->GetPageView(pPage, FALSE)) {
-    CPDFDoc_Environment* pEnv = pSDKDoc->GetEnv();
-    CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander();
-    CPDF_Dictionary* pPageDict = pPDFPage->m_pFormDict;
-    CPDF_AAction aa = pPageDict->GetDict("AA");
-    if (FPDFPAGE_AACTION_OPEN == aaType) {
-      if (aa.ActionExist(CPDF_AAction::OpenPage)) {
-        CPDF_Action action = aa.GetAction(CPDF_AAction::OpenPage);
-        pActionHandler->DoAction_Page(action, CPDF_AAction::OpenPage, pSDKDoc);
-      }
-    } else {
-      if (aa.ActionExist(CPDF_AAction::ClosePage)) {
-        CPDF_Action action = aa.GetAction(CPDF_AAction::ClosePage);
-        pActionHandler->DoAction_Page(action, CPDF_AAction::ClosePage, pSDKDoc);
-      }
-    }
-  }
-}
diff --git a/fpdfsdk/src/fpdfformfill_embeddertest.cpp b/fpdfsdk/src/fpdfformfill_embeddertest.cpp
deleted file mode 100644
index aae6ea7..0000000
--- a/fpdfsdk/src/fpdfformfill_embeddertest.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright 2015 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.
-
-#include "public/fpdf_formfill.h"
-#include "testing/embedder_test.h"
-#include "testing/embedder_test_mock_delegate.h"
-#include "testing/embedder_test_timer_handling_delegate.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using testing::_;
-using testing::Return;
-
-class FPDFFormFillEmbeddertest : public EmbedderTest {};
-
-TEST_F(FPDFFormFillEmbeddertest, FirstTest) {
-  EmbedderTestMockDelegate mock;
-  EXPECT_CALL(mock, Alert(_, _, _, _)).Times(0);
-  EXPECT_CALL(mock, UnsupportedHandler(_)).Times(0);
-  EXPECT_CALL(mock, SetTimer(_, _)).Times(0);
-  EXPECT_CALL(mock, KillTimer(_)).Times(0);
-  SetDelegate(&mock);
-
-  EXPECT_TRUE(OpenDocument("hello_world.pdf"));
-  FPDF_PAGE page = LoadPage(0);
-  EXPECT_NE(nullptr, page);
-  UnloadPage(page);
-}
-
-TEST_F(FPDFFormFillEmbeddertest, BUG_487928) {
-  EmbedderTestTimerHandlingDelegate delegate;
-  SetDelegate(&delegate);
-
-  EXPECT_TRUE(OpenDocument("bug_487928.pdf"));
-  FPDF_PAGE page = LoadPage(0);
-  EXPECT_NE(nullptr, page);
-  DoOpenActions();
-  delegate.AdvanceTime(5000);
-  UnloadPage(page);
-}
-
-TEST_F(FPDFFormFillEmbeddertest, BUG_507316) {
-  EmbedderTestTimerHandlingDelegate delegate;
-  SetDelegate(&delegate);
-
-  EXPECT_TRUE(OpenDocument("bug_507316.pdf"));
-  FPDF_PAGE page = LoadAndCachePage(2);
-  EXPECT_NE(nullptr, page);
-  DoOpenActions();
-  delegate.AdvanceTime(4000);
-  UnloadPage(page);
-}
-
-TEST_F(FPDFFormFillEmbeddertest, BUG_514690) {
-  EXPECT_TRUE(OpenDocument("hello_world.pdf"));
-  FPDF_PAGE page = LoadPage(0);
-  EXPECT_NE(nullptr, page);
-
-  // Test that FORM_OnMouseMove() etc. permit null HANDLES and PAGES.
-  FORM_OnMouseMove(nullptr, page, 0, 10.0, 10.0);
-  FORM_OnMouseMove(form_handle(), nullptr, 0, 10.0, 10.0);
-
-  UnloadPage(page);
-}
-
-TEST_F(FPDFFormFillEmbeddertest, BUG_551248) {
-  EmbedderTestTimerHandlingDelegate delegate;
-  SetDelegate(&delegate);
-
-  EXPECT_TRUE(OpenDocument("bug_551248.pdf"));
-  FPDF_PAGE page = LoadPage(0);
-  EXPECT_NE(nullptr, page);
-  DoOpenActions();
-  delegate.AdvanceTime(5000);
-  UnloadPage(page);
-
-  const auto& alerts = delegate.GetAlerts();
-  ASSERT_EQ(1U, alerts.size());
-
-  EXPECT_STREQ(L"hello world", alerts[0].message.c_str());
-  EXPECT_STREQ(L"Alert", alerts[0].title.c_str());
-  EXPECT_EQ(0, alerts[0].type);
-  EXPECT_EQ(0, alerts[0].icon);
-}
diff --git a/fpdfsdk/src/fpdfppo.cpp b/fpdfsdk/src/fpdfppo.cpp
deleted file mode 100644
index 47b9101..0000000
--- a/fpdfsdk/src/fpdfppo.cpp
+++ /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
-
-#include "public/fpdf_ppo.h"
-
-#include <memory>
-
-#include "fpdfsdk/include/fsdk_define.h"
-
-class CPDF_PageOrganizer {
- public:
-  using ObjectNumberMap = std::map<FX_DWORD, FX_DWORD>;
-  CPDF_PageOrganizer();
-  ~CPDF_PageOrganizer();
-
-  FX_BOOL PDFDocInit(CPDF_Document* pDestPDFDoc, CPDF_Document* pSrcPDFDoc);
-  FX_BOOL ExportPage(CPDF_Document* pSrcPDFDoc,
-                     CFX_WordArray* nPageNum,
-                     CPDF_Document* pDestPDFDoc,
-                     int nIndex);
-  CPDF_Object* PageDictGetInheritableTag(CPDF_Dictionary* pDict,
-                                         CFX_ByteString nSrctag);
-  FX_BOOL UpdateReference(CPDF_Object* pObj,
-                          CPDF_Document* pDoc,
-                          ObjectNumberMap* pObjNumberMap);
-  FX_DWORD GetNewObjId(CPDF_Document* pDoc,
-                       ObjectNumberMap* pObjNumberMap,
-                       CPDF_Reference* pRef);
-};
-
-CPDF_PageOrganizer::CPDF_PageOrganizer() {}
-
-CPDF_PageOrganizer::~CPDF_PageOrganizer() {}
-
-FX_BOOL CPDF_PageOrganizer::PDFDocInit(CPDF_Document* pDestPDFDoc,
-                                       CPDF_Document* pSrcPDFDoc) {
-  if (!pDestPDFDoc || !pSrcPDFDoc)
-    return FALSE;
-
-  CPDF_Dictionary* pNewRoot = pDestPDFDoc->GetRoot();
-  if (!pNewRoot)
-    return FALSE;
-
-  // Set the document information
-  CPDF_Dictionary* DInfoDict = pDestPDFDoc->GetInfo();
-  if (!DInfoDict)
-    return FALSE;
-
-  CFX_ByteString producerstr;
-  producerstr.Format("PDFium");
-  DInfoDict->SetAt("Producer", new CPDF_String(producerstr, FALSE));
-
-  // Set type
-  CFX_ByteString cbRootType = pNewRoot->GetString("Type", "");
-  if (cbRootType.Equal("")) {
-    pNewRoot->SetAt("Type", new CPDF_Name("Catalog"));
-  }
-
-  CPDF_Object* pElement = pNewRoot->GetElement("Pages");
-  CPDF_Dictionary* pNewPages =
-      pElement ? ToDictionary(pElement->GetDirect()) : nullptr;
-  if (!pNewPages) {
-    pNewPages = new CPDF_Dictionary;
-    FX_DWORD NewPagesON = pDestPDFDoc->AddIndirectObject(pNewPages);
-    pNewRoot->SetAt("Pages", new CPDF_Reference(pDestPDFDoc, NewPagesON));
-  }
-
-  CFX_ByteString cbPageType = pNewPages->GetString("Type", "");
-  if (cbPageType.Equal("")) {
-    pNewPages->SetAt("Type", new CPDF_Name("Pages"));
-  }
-
-  CPDF_Array* pKeysArray = pNewPages->GetArray("Kids");
-  if (!pKeysArray) {
-    CPDF_Array* pNewKids = new CPDF_Array;
-    FX_DWORD Kidsobjnum = -1;
-    Kidsobjnum = pDestPDFDoc->AddIndirectObject(pNewKids);
-
-    pNewPages->SetAt("Kids", new CPDF_Reference(pDestPDFDoc, Kidsobjnum));
-    pNewPages->SetAt("Count", new CPDF_Number(0));
-  }
-
-  return TRUE;
-}
-
-FX_BOOL CPDF_PageOrganizer::ExportPage(CPDF_Document* pSrcPDFDoc,
-                                       CFX_WordArray* nPageNum,
-                                       CPDF_Document* pDestPDFDoc,
-                                       int nIndex) {
-  int curpage = nIndex;
-
-  std::unique_ptr<ObjectNumberMap> pObjNumberMap(new ObjectNumberMap);
-
-  for (int i = 0; i < nPageNum->GetSize(); ++i) {
-    CPDF_Dictionary* pCurPageDict = pDestPDFDoc->CreateNewPage(curpage);
-    CPDF_Dictionary* pSrcPageDict = pSrcPDFDoc->GetPage(nPageNum->GetAt(i) - 1);
-    if (!pSrcPageDict || !pCurPageDict)
-      return FALSE;
-
-    // Clone the page dictionary
-    for (const auto& it : *pSrcPageDict) {
-      const CFX_ByteString& cbSrcKeyStr = it.first;
-      CPDF_Object* pObj = it.second;
-      if (cbSrcKeyStr.Compare(("Type")) && cbSrcKeyStr.Compare(("Parent"))) {
-        if (pCurPageDict->KeyExist(cbSrcKeyStr))
-          pCurPageDict->RemoveAt(cbSrcKeyStr);
-        pCurPageDict->SetAt(cbSrcKeyStr, pObj->Clone());
-      }
-    }
-
-    // inheritable item
-    CPDF_Object* pInheritable = nullptr;
-    // 1 MediaBox  //required
-    if (!pCurPageDict->KeyExist("MediaBox")) {
-      pInheritable = PageDictGetInheritableTag(pSrcPageDict, "MediaBox");
-      if (!pInheritable) {
-        // Search the "CropBox" from source page dictionary,
-        // if not exists,we take the letter size.
-        pInheritable = PageDictGetInheritableTag(pSrcPageDict, "CropBox");
-        if (pInheritable) {
-          pCurPageDict->SetAt("MediaBox", pInheritable->Clone());
-        } else {
-          // Make the default size to be letter size (8.5'x11')
-          CPDF_Array* pArray = new CPDF_Array;
-          pArray->AddNumber(0);
-          pArray->AddNumber(0);
-          pArray->AddNumber(612);
-          pArray->AddNumber(792);
-          pCurPageDict->SetAt("MediaBox", pArray);
-        }
-      } else {
-        pCurPageDict->SetAt("MediaBox", pInheritable->Clone());
-      }
-    }
-    // 2 Resources //required
-    if (!pCurPageDict->KeyExist("Resources")) {
-      pInheritable = PageDictGetInheritableTag(pSrcPageDict, "Resources");
-      if (!pInheritable)
-        return FALSE;
-      pCurPageDict->SetAt("Resources", pInheritable->Clone());
-    }
-    // 3 CropBox  //Optional
-    if (!pCurPageDict->KeyExist("CropBox")) {
-      pInheritable = PageDictGetInheritableTag(pSrcPageDict, "CropBox");
-      if (pInheritable)
-        pCurPageDict->SetAt("CropBox", pInheritable->Clone());
-    }
-    // 4 Rotate  //Optional
-    if (!pCurPageDict->KeyExist("Rotate")) {
-      pInheritable = PageDictGetInheritableTag(pSrcPageDict, "Rotate");
-      if (pInheritable)
-        pCurPageDict->SetAt("Rotate", pInheritable->Clone());
-    }
-
-    // Update the reference
-    FX_DWORD dwOldPageObj = pSrcPageDict->GetObjNum();
-    FX_DWORD dwNewPageObj = pCurPageDict->GetObjNum();
-
-    (*pObjNumberMap)[dwOldPageObj] = dwNewPageObj;
-
-    UpdateReference(pCurPageDict, pDestPDFDoc, pObjNumberMap.get());
-    ++curpage;
-  }
-
-  return TRUE;
-}
-
-CPDF_Object* CPDF_PageOrganizer::PageDictGetInheritableTag(
-    CPDF_Dictionary* pDict,
-    CFX_ByteString nSrctag) {
-  if (!pDict || nSrctag.IsEmpty())
-    return nullptr;
-  if (!pDict->KeyExist("Parent") || !pDict->KeyExist("Type"))
-    return nullptr;
-
-  CPDF_Object* pType = pDict->GetElement("Type")->GetDirect();
-  if (!ToName(pType))
-    return nullptr;
-  if (pType->GetString().Compare("Page"))
-    return nullptr;
-
-  CPDF_Dictionary* pp = ToDictionary(pDict->GetElement("Parent")->GetDirect());
-  if (!pp)
-    return nullptr;
-
-  if (pDict->KeyExist((const char*)nSrctag))
-    return pDict->GetElement((const char*)nSrctag);
-
-  while (pp) {
-    if (pp->KeyExist((const char*)nSrctag))
-      return pp->GetElement((const char*)nSrctag);
-    if (!pp->KeyExist("Parent"))
-      break;
-    pp = ToDictionary(pp->GetElement("Parent")->GetDirect());
-  }
-  return nullptr;
-}
-
-FX_BOOL CPDF_PageOrganizer::UpdateReference(CPDF_Object* pObj,
-                                            CPDF_Document* pDoc,
-                                            ObjectNumberMap* pObjNumberMap) {
-  switch (pObj->GetType()) {
-    case PDFOBJ_REFERENCE: {
-      CPDF_Reference* pReference = pObj->AsReference();
-      FX_DWORD newobjnum = GetNewObjId(pDoc, pObjNumberMap, pReference);
-      if (newobjnum == 0)
-        return FALSE;
-      pReference->SetRef(pDoc, newobjnum);
-      break;
-    }
-    case PDFOBJ_DICTIONARY: {
-      CPDF_Dictionary* pDict = pObj->AsDictionary();
-      auto it = pDict->begin();
-      while (it != pDict->end()) {
-        const CFX_ByteString& key = it->first;
-        CPDF_Object* pNextObj = it->second;
-        ++it;
-        if (!FXSYS_strcmp(key, "Parent") || !FXSYS_strcmp(key, "Prev") ||
-            !FXSYS_strcmp(key, "First")) {
-          continue;
-        }
-        if (pNextObj) {
-          if (!UpdateReference(pNextObj, pDoc, pObjNumberMap))
-            pDict->RemoveAt(key);
-        } else {
-          return FALSE;
-        }
-      }
-      break;
-    }
-    case PDFOBJ_ARRAY: {
-      CPDF_Array* pArray = pObj->AsArray();
-      FX_DWORD count = pArray->GetCount();
-      for (FX_DWORD i = 0; i < count; ++i) {
-        CPDF_Object* pNextObj = pArray->GetElement(i);
-        if (!pNextObj)
-          return FALSE;
-        if (!UpdateReference(pNextObj, pDoc, pObjNumberMap))
-          return FALSE;
-      }
-      break;
-    }
-    case PDFOBJ_STREAM: {
-      CPDF_Stream* pStream = pObj->AsStream();
-      CPDF_Dictionary* pDict = pStream->GetDict();
-      if (pDict) {
-        if (!UpdateReference(pDict, pDoc, pObjNumberMap))
-          return FALSE;
-      } else {
-        return FALSE;
-      }
-      break;
-    }
-    default:
-      break;
-  }
-
-  return TRUE;
-}
-
-FX_DWORD CPDF_PageOrganizer::GetNewObjId(CPDF_Document* pDoc,
-                                         ObjectNumberMap* pObjNumberMap,
-                                         CPDF_Reference* pRef) {
-  if (!pRef)
-    return 0;
-
-  FX_DWORD dwObjnum = pRef->GetRefObjNum();
-  FX_DWORD dwNewObjNum = 0;
-  const auto it = pObjNumberMap->find(dwObjnum);
-  if (it != pObjNumberMap->end())
-    dwNewObjNum = it->second;
-  if (dwNewObjNum)
-    return dwNewObjNum;
-
-  CPDF_Object* pDirect = pRef->GetDirect();
-  if (!pDirect)
-    return 0;
-
-  CPDF_Object* pClone = pDirect->Clone();
-  if (!pClone)
-    return 0;
-
-  if (CPDF_Dictionary* pDictClone = pClone->AsDictionary()) {
-    if (pDictClone->KeyExist("Type")) {
-      CFX_ByteString strType = pDictClone->GetString("Type");
-      if (!FXSYS_stricmp(strType, "Pages")) {
-        pDictClone->Release();
-        return 4;
-      }
-      if (!FXSYS_stricmp(strType, "Page")) {
-        pDictClone->Release();
-        return 0;
-      }
-    }
-  }
-  dwNewObjNum = pDoc->AddIndirectObject(pClone);
-  (*pObjNumberMap)[dwObjnum] = dwNewObjNum;
-  if (!UpdateReference(pClone, pDoc, pObjNumberMap)) {
-    pClone->Release();
-    return 0;
-  }
-  return dwNewObjNum;
-}
-
-FPDF_BOOL ParserPageRangeString(CFX_ByteString rangstring,
-                                CFX_WordArray* pageArray,
-                                int nCount) {
-  if (rangstring.GetLength() != 0) {
-    rangstring.Remove(' ');
-    int nLength = rangstring.GetLength();
-    CFX_ByteString cbCompareString("0123456789-,");
-    for (int i = 0; i < nLength; ++i) {
-      if (cbCompareString.Find(rangstring[i]) == -1)
-        return FALSE;
-    }
-    CFX_ByteString cbMidRange;
-    int nStringFrom = 0;
-    int nStringTo = 0;
-    while (nStringTo < nLength) {
-      nStringTo = rangstring.Find(',', nStringFrom);
-      if (nStringTo == -1)
-        nStringTo = nLength;
-      cbMidRange = rangstring.Mid(nStringFrom, nStringTo - nStringFrom);
-      int nMid = cbMidRange.Find('-');
-      if (nMid == -1) {
-        long lPageNum = atol(cbMidRange);
-        if (lPageNum <= 0 || lPageNum > nCount)
-          return FALSE;
-        pageArray->Add((FX_WORD)lPageNum);
-      } else {
-        int nStartPageNum = atol(cbMidRange.Mid(0, nMid));
-        if (nStartPageNum == 0)
-          return FALSE;
-
-        ++nMid;
-        int nEnd = cbMidRange.GetLength() - nMid;
-        if (nEnd == 0)
-          return FALSE;
-
-        int nEndPageNum = atol(cbMidRange.Mid(nMid, nEnd));
-        if (nStartPageNum < 0 || nStartPageNum > nEndPageNum ||
-            nEndPageNum > nCount) {
-          return FALSE;
-        }
-        for (int i = nStartPageNum; i <= nEndPageNum; ++i) {
-          pageArray->Add(i);
-        }
-      }
-      nStringFrom = nStringTo + 1;
-    }
-  }
-  return TRUE;
-}
-
-DLLEXPORT FPDF_BOOL STDCALL FPDF_ImportPages(FPDF_DOCUMENT dest_doc,
-                                             FPDF_DOCUMENT src_doc,
-                                             FPDF_BYTESTRING pagerange,
-                                             int index) {
-  CPDF_Document* pDestDoc = CPDFDocumentFromFPDFDocument(dest_doc);
-  if (!dest_doc)
-    return FALSE;
-
-  CPDF_Document* pSrcDoc = CPDFDocumentFromFPDFDocument(src_doc);
-  if (!pSrcDoc)
-    return FALSE;
-
-  CFX_WordArray pageArray;
-  int nCount = pSrcDoc->GetPageCount();
-  if (pagerange) {
-    if (!ParserPageRangeString(pagerange, &pageArray, nCount))
-      return FALSE;
-  } else {
-    for (int i = 1; i <= nCount; ++i) {
-      pageArray.Add(i);
-    }
-  }
-
-  CPDF_PageOrganizer pageOrg;
-  pageOrg.PDFDocInit(pDestDoc, pSrcDoc);
-  return pageOrg.ExportPage(pSrcDoc, &pageArray, pDestDoc, index);
-}
-
-DLLEXPORT FPDF_BOOL STDCALL FPDF_CopyViewerPreferences(FPDF_DOCUMENT dest_doc,
-                                                       FPDF_DOCUMENT src_doc) {
-  CPDF_Document* pDstDoc = CPDFDocumentFromFPDFDocument(dest_doc);
-  if (!pDstDoc)
-    return FALSE;
-
-  CPDF_Document* pSrcDoc = CPDFDocumentFromFPDFDocument(src_doc);
-  if (!pSrcDoc)
-    return FALSE;
-
-  CPDF_Dictionary* pSrcDict = pSrcDoc->GetRoot();
-  pSrcDict = pSrcDict->GetDict("ViewerPreferences");
-  if (!pSrcDict)
-    return FALSE;
-
-  CPDF_Dictionary* pDstDict = pDstDoc->GetRoot();
-  if (!pDstDict)
-    return FALSE;
-
-  pDstDict->SetAt("ViewerPreferences", pSrcDict->Clone(TRUE));
-  return TRUE;
-}
diff --git a/fpdfsdk/src/fpdfsave.cpp b/fpdfsdk/src/fpdfsave.cpp
deleted file mode 100644
index c1d21c8..0000000
--- a/fpdfsdk/src/fpdfsave.cpp
+++ /dev/null
@@ -1,335 +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
-
-#include "public/fpdf_save.h"
-
-#include "core/include/fpdfapi/fpdf_serial.h"
-#include "fpdfsdk/include/fsdk_define.h"
-#include "public/fpdf_edit.h"
-
-#ifdef PDF_ENABLE_XFA
-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_app.h"
-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h"
-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h"
-#include "public/fpdf_formfill.h"
-#endif
-
-#if _FX_OS_ == _FX_ANDROID_
-#include "time.h"
-#else
-#include <ctime>
-#endif
-
-class CFX_IFileWrite final : public IFX_StreamWrite {
- public:
-  CFX_IFileWrite();
-  FX_BOOL Init(FPDF_FILEWRITE* pFileWriteStruct);
-  FX_BOOL WriteBlock(const void* pData, size_t size) override;
-  void Release() override;
-
- protected:
-  ~CFX_IFileWrite() override {}
-
-  FPDF_FILEWRITE* m_pFileWriteStruct;
-};
-
-CFX_IFileWrite::CFX_IFileWrite() {
-  m_pFileWriteStruct = NULL;
-}
-
-FX_BOOL CFX_IFileWrite::Init(FPDF_FILEWRITE* pFileWriteStruct) {
-  if (!pFileWriteStruct)
-    return FALSE;
-
-  m_pFileWriteStruct = pFileWriteStruct;
-  return TRUE;
-}
-
-FX_BOOL CFX_IFileWrite::WriteBlock(const void* pData, size_t size) {
-  if (!m_pFileWriteStruct)
-    return FALSE;
-
-  m_pFileWriteStruct->WriteBlock(m_pFileWriteStruct, pData, size);
-  return TRUE;
-}
-
-void CFX_IFileWrite::Release() {
-  delete this;
-}
-
-#ifdef PDF_ENABLE_XFA
-#define XFA_DATASETS 0
-#define XFA_FORMS 1
-
-FX_BOOL _SaveXFADocumentData(CPDFXFA_Document* pDocument,
-                             CFX_PtrArray& fileList) {
-  if (!pDocument)
-    return FALSE;
-  if (pDocument->GetDocType() != DOCTYPE_DYNAMIC_XFA &&
-      pDocument->GetDocType() != DOCTYPE_STATIC_XFA)
-    return TRUE;
-  if (!CPDFXFA_App::GetInstance()->GetXFAApp())
-    return TRUE;
-
-  IXFA_DocView* pXFADocView = pDocument->GetXFADocView();
-  if (NULL == pXFADocView)
-    return TRUE;
-
-  IXFA_DocHandler* pXFADocHandler =
-      CPDFXFA_App::GetInstance()->GetXFAApp()->GetDocHandler();
-  CPDF_Document* pPDFDocument = pDocument->GetPDFDoc();
-  if (pDocument == NULL)
-    return FALSE;
-
-  CPDF_Dictionary* pRoot = pPDFDocument->GetRoot();
-  if (pRoot == NULL)
-    return FALSE;
-  CPDF_Dictionary* pAcroForm = pRoot->GetDict("AcroForm");
-  if (NULL == pAcroForm)
-    return FALSE;
-  CPDF_Object* pXFA = pAcroForm->GetElement("XFA");
-  if (pXFA == NULL)
-    return TRUE;
-  if (pXFA->GetType() != PDFOBJ_ARRAY)
-    return FALSE;
-  CPDF_Array* pArray = pXFA->GetArray();
-  if (NULL == pArray)
-    return FALSE;
-  int size = pArray->GetCount();
-  int iFormIndex = -1;
-  int iDataSetsIndex = -1;
-  int iTemplate = -1;
-  int iLast = size - 2;
-  for (int i = 0; i < size - 1; i++) {
-    CPDF_Object* pPDFObj = pArray->GetElement(i);
-    if (pPDFObj->GetType() != PDFOBJ_STRING)
-      continue;
-    if (pPDFObj->GetString() == "form")
-      iFormIndex = i + 1;
-    else if (pPDFObj->GetString() == "datasets")
-      iDataSetsIndex = i + 1;
-    else if (pPDFObj->GetString() == "template")
-      iTemplate = i + 1;
-  }
-  IXFA_ChecksumContext* pContext = NULL;
-  // Checksum
-  pContext = XFA_Checksum_Create();
-  FXSYS_assert(pContext);
-  pContext->StartChecksum();
-
-  // template
-  if (iTemplate > -1) {
-    CPDF_Stream* pTemplateStream = pArray->GetStream(iTemplate);
-    CPDF_StreamAcc streamAcc;
-    streamAcc.LoadAllData(pTemplateStream);
-    uint8_t* pData = (uint8_t*)streamAcc.GetData();
-    FX_DWORD dwSize2 = streamAcc.GetSize();
-    IFX_FileStream* pTemplate = FX_CreateMemoryStream(pData, dwSize2);
-    pContext->UpdateChecksum((IFX_FileRead*)pTemplate);
-    pTemplate->Release();
-  }
-  CPDF_Stream* pFormStream = NULL;
-  CPDF_Stream* pDataSetsStream = NULL;
-  if (iFormIndex != -1) {
-    // Get form CPDF_Stream
-    CPDF_Object* pFormPDFObj = pArray->GetElement(iFormIndex);
-    if (pFormPDFObj->GetType() == PDFOBJ_REFERENCE) {
-      CPDF_Object* pFormDircetObj = pFormPDFObj->GetDirect();
-      if (NULL != pFormDircetObj &&
-          pFormDircetObj->GetType() == PDFOBJ_STREAM) {
-        pFormStream = (CPDF_Stream*)pFormDircetObj;
-      }
-    } else if (pFormPDFObj->GetType() == PDFOBJ_STREAM) {
-      pFormStream = (CPDF_Stream*)pFormPDFObj;
-    }
-  }
-
-  if (iDataSetsIndex != -1) {
-    // Get datasets CPDF_Stream
-    CPDF_Object* pDataSetsPDFObj = pArray->GetElement(iDataSetsIndex);
-    if (pDataSetsPDFObj->GetType() == PDFOBJ_REFERENCE) {
-      CPDF_Reference* pDataSetsRefObj = (CPDF_Reference*)pDataSetsPDFObj;
-      CPDF_Object* pDataSetsDircetObj = pDataSetsRefObj->GetDirect();
-      if (NULL != pDataSetsDircetObj &&
-          pDataSetsDircetObj->GetType() == PDFOBJ_STREAM) {
-        pDataSetsStream = (CPDF_Stream*)pDataSetsDircetObj;
-      }
-    } else if (pDataSetsPDFObj->GetType() == PDFOBJ_STREAM) {
-      pDataSetsStream = (CPDF_Stream*)pDataSetsPDFObj;
-    }
-  }
-  // end
-  // L"datasets"
-  {
-    IFX_FileStream* pDsfileWrite = FX_CreateMemoryStream();
-    if (NULL == pDsfileWrite) {
-      pContext->Release();
-      pDsfileWrite->Release();
-      return FALSE;
-    }
-    if (pXFADocHandler->SavePackage(pXFADocView->GetDoc(),
-                                    CFX_WideStringC(L"datasets"),
-                                    pDsfileWrite) &&
-        pDsfileWrite->GetSize() > 0) {
-      // Datasets
-      pContext->UpdateChecksum((IFX_FileRead*)pDsfileWrite);
-      pContext->FinishChecksum();
-      CPDF_Dictionary* pDataDict = new CPDF_Dictionary;
-      if (iDataSetsIndex != -1) {
-        if (pDataSetsStream)
-          pDataSetsStream->InitStreamFromFile(pDsfileWrite, pDataDict);
-      } else {
-        CPDF_Stream* pData = new CPDF_Stream(NULL, 0, NULL);
-        pData->InitStreamFromFile(pDsfileWrite, pDataDict);
-        pPDFDocument->AddIndirectObject(pData);
-        iLast = pArray->GetCount() - 2;
-        pArray->InsertAt(iLast, new CPDF_String("datasets", FALSE));
-        pArray->InsertAt(iLast + 1, pData, pPDFDocument);
-      }
-      fileList.Add(pDsfileWrite);
-    }
-  }
-
-  // L"form"
-  {
-    IFX_FileStream* pfileWrite = FX_CreateMemoryStream();
-    if (NULL == pfileWrite) {
-      pContext->Release();
-      return FALSE;
-    }
-    if (pXFADocHandler->SavePackage(pXFADocView->GetDoc(),
-                                    CFX_WideStringC(L"form"), pfileWrite,
-                                    pContext) &&
-        pfileWrite > 0) {
-      CPDF_Dictionary* pDataDict = new CPDF_Dictionary;
-      if (iFormIndex != -1) {
-        if (pFormStream)
-          pFormStream->InitStreamFromFile(pfileWrite, pDataDict);
-      } else {
-        CPDF_Stream* pData = new CPDF_Stream(NULL, 0, NULL);
-        pData->InitStreamFromFile(pfileWrite, pDataDict);
-        pPDFDocument->AddIndirectObject(pData);
-        iLast = pArray->GetCount() - 2;
-        pArray->InsertAt(iLast, new CPDF_String("form", FALSE));
-        pArray->InsertAt(iLast + 1, pData, pPDFDocument);
-      }
-      fileList.Add(pfileWrite);
-    }
-  }
-  pContext->Release();
-  return TRUE;
-}
-
-FX_BOOL _SendPostSaveToXFADoc(CPDFXFA_Document* pDocument) {
-  if (!pDocument)
-    return FALSE;
-
-  if (pDocument->GetDocType() != DOCTYPE_DYNAMIC_XFA &&
-      pDocument->GetDocType() != DOCTYPE_STATIC_XFA)
-    return TRUE;
-
-  IXFA_DocView* pXFADocView = pDocument->GetXFADocView();
-  if (NULL == pXFADocView)
-    return FALSE;
-  IXFA_WidgetHandler* pWidgetHander = pXFADocView->GetWidgetHandler();
-
-  CXFA_WidgetAcc* pWidgetAcc = NULL;
-  IXFA_WidgetAccIterator* pWidgetAccIterator =
-      pXFADocView->CreateWidgetAccIterator();
-  pWidgetAcc = pWidgetAccIterator->MoveToNext();
-  while (pWidgetAcc) {
-    CXFA_EventParam preParam;
-    preParam.m_eType = XFA_EVENT_PostSave;
-    pWidgetHander->ProcessEvent(pWidgetAcc, &preParam);
-    pWidgetAcc = pWidgetAccIterator->MoveToNext();
-  }
-  pWidgetAccIterator->Release();
-  pXFADocView->UpdateDocView();
-  pDocument->_ClearChangeMark();
-  return TRUE;
-}
-
-FX_BOOL _SendPreSaveToXFADoc(CPDFXFA_Document* pDocument,
-                             CFX_PtrArray& fileList) {
-  if (pDocument->GetDocType() != DOCTYPE_DYNAMIC_XFA &&
-      pDocument->GetDocType() != DOCTYPE_STATIC_XFA)
-    return TRUE;
-  IXFA_DocView* pXFADocView = pDocument->GetXFADocView();
-  if (NULL == pXFADocView)
-    return TRUE;
-  IXFA_WidgetHandler* pWidgetHander = pXFADocView->GetWidgetHandler();
-  CXFA_WidgetAcc* pWidgetAcc = NULL;
-  IXFA_WidgetAccIterator* pWidgetAccIterator =
-      pXFADocView->CreateWidgetAccIterator();
-  pWidgetAcc = pWidgetAccIterator->MoveToNext();
-  while (pWidgetAcc) {
-    CXFA_EventParam preParam;
-    preParam.m_eType = XFA_EVENT_PreSave;
-    pWidgetHander->ProcessEvent(pWidgetAcc, &preParam);
-    pWidgetAcc = pWidgetAccIterator->MoveToNext();
-  }
-  pWidgetAccIterator->Release();
-  pXFADocView->UpdateDocView();
-  return _SaveXFADocumentData(pDocument, fileList);
-}
-#endif  // PDF_ENABLE_XFA
-
-FPDF_BOOL _FPDF_Doc_Save(FPDF_DOCUMENT document,
-                         FPDF_FILEWRITE* pFileWrite,
-                         FPDF_DWORD flags,
-                         FPDF_BOOL bSetVersion,
-                         int fileVerion) {
-  CPDF_Document* pPDFDoc = CPDFDocumentFromFPDFDocument(document);
-  if (!pPDFDoc)
-    return 0;
-
-#ifdef PDF_ENABLE_XFA
-  CPDFXFA_Document* pDoc = (CPDFXFA_Document*)document;
-  CFX_PtrArray fileList;
-  _SendPreSaveToXFADoc(pDoc, fileList);
-#endif  // PDF_ENABLE_XFA
-
-  if (flags < FPDF_INCREMENTAL || flags > FPDF_REMOVE_SECURITY) {
-    flags = 0;
-  }
-
-  CPDF_Creator FileMaker(pPDFDoc);
-  if (bSetVersion)
-    FileMaker.SetFileVersion(fileVerion);
-  if (flags == FPDF_REMOVE_SECURITY) {
-    flags = 0;
-    FileMaker.RemoveSecurity();
-  }
-
-  CFX_IFileWrite* pStreamWrite = NULL;
-  FX_BOOL bRet;
-  pStreamWrite = new CFX_IFileWrite;
-  pStreamWrite->Init(pFileWrite);
-  bRet = FileMaker.Create(pStreamWrite, flags);
-#ifdef PDF_ENABLE_XFA
-  _SendPostSaveToXFADoc(pDoc);
-  for (int i = 0; i < fileList.GetSize(); i++) {
-    IFX_FileStream* pFile = (IFX_FileStream*)fileList.GetAt(i);
-    pFile->Release();
-  }
-  fileList.RemoveAll();
-#endif  // PDF_ENABLE_XFA
-  pStreamWrite->Release();
-  return bRet;
-}
-
-DLLEXPORT FPDF_BOOL STDCALL FPDF_SaveAsCopy(FPDF_DOCUMENT document,
-                                            FPDF_FILEWRITE* pFileWrite,
-                                            FPDF_DWORD flags) {
-  return _FPDF_Doc_Save(document, pFileWrite, flags, FALSE, 0);
-}
-
-DLLEXPORT FPDF_BOOL STDCALL FPDF_SaveWithVersion(FPDF_DOCUMENT document,
-                                                 FPDF_FILEWRITE* pFileWrite,
-                                                 FPDF_DWORD flags,
-                                                 int fileVersion) {
-  return _FPDF_Doc_Save(document, pFileWrite, flags, TRUE, fileVersion);
-}
diff --git a/fpdfsdk/src/fpdfview.cpp b/fpdfsdk/src/fpdfview.cpp
deleted file mode 100644
index a6c1420..0000000
--- a/fpdfsdk/src/fpdfview.cpp
+++ /dev/null
@@ -1,1198 +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
-
-#include "public/fpdfview.h"
-
-#include <memory>
-
-#include "core/include/fxcodec/fx_codec.h"
-#include "core/include/fxcrt/fx_safe_types.h"
-#include "fpdfsdk/include/fsdk_define.h"
-#include "fpdfsdk/include/fsdk_mgr.h"
-#include "fpdfsdk/include/fsdk_rendercontext.h"
-#include "fpdfsdk/include/javascript/IJavaScript.h"
-#include "public/fpdf_ext.h"
-#include "public/fpdf_progressive.h"
-#include "third_party/base/numerics/safe_conversions_impl.h"
-
-#ifdef PDF_ENABLE_XFA
-#include "core/include/fpdfapi/fpdf_module.h"
-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_app.h"
-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h"
-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_page.h"
-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h"
-#include "public/fpdf_formfill.h"
-#endif  // PDF_ENABLE_XFA
-
-UnderlyingDocumentType* UnderlyingFromFPDFDocument(FPDF_DOCUMENT doc) {
-  return static_cast<UnderlyingDocumentType*>(doc);
-}
-
-FPDF_DOCUMENT FPDFDocumentFromUnderlying(UnderlyingDocumentType* doc) {
-  return static_cast<FPDF_DOCUMENT>(doc);
-}
-
-UnderlyingPageType* UnderlyingFromFPDFPage(FPDF_PAGE page) {
-  return static_cast<UnderlyingPageType*>(page);
-}
-
-CPDF_Document* CPDFDocumentFromFPDFDocument(FPDF_DOCUMENT doc) {
-#ifdef PDF_ENABLE_XFA
-  return doc ? UnderlyingFromFPDFDocument(doc)->GetPDFDoc() : nullptr;
-#else   // PDF_ENABLE_XFA
-  return UnderlyingFromFPDFDocument(doc);
-#endif  // PDF_ENABLE_XFA
-}
-
-FPDF_DOCUMENT FPDFDocumentFromCPDFDocument(CPDF_Document* doc) {
-#ifdef PDF_ENABLE_XFA
-  return doc ? FPDFDocumentFromUnderlying(
-                   new CPDFXFA_Document(doc, CPDFXFA_App::GetInstance()))
-             : nullptr;
-#else   // PDF_ENABLE_XFA
-  return FPDFDocumentFromUnderlying(doc);
-#endif  // PDF_ENABLE_XFA
-}
-
-CPDF_Page* CPDFPageFromFPDFPage(FPDF_PAGE page) {
-#ifdef PDF_ENABLE_XFA
-  return page ? UnderlyingFromFPDFPage(page)->GetPDFPage() : nullptr;
-#else   // PDF_ENABLE_XFA
-  return UnderlyingFromFPDFPage(page);
-#endif  // PDF_ENABLE_XFA
-}
-
-#ifdef PDF_ENABLE_XFA
-CFPDF_FileStream::CFPDF_FileStream(FPDF_FILEHANDLER* pFS) {
-  m_pFS = pFS;
-  m_nCurPos = 0;
-}
-
-IFX_FileStream* CFPDF_FileStream::Retain() {
-  return this;
-}
-
-void CFPDF_FileStream::Release() {
-  if (m_pFS && m_pFS->Release)
-    m_pFS->Release(m_pFS->clientData);
-  delete this;
-}
-
-FX_FILESIZE CFPDF_FileStream::GetSize() {
-  if (m_pFS && m_pFS->GetSize)
-    return (FX_FILESIZE)m_pFS->GetSize(m_pFS->clientData);
-  return 0;
-}
-
-FX_BOOL CFPDF_FileStream::IsEOF() {
-  return m_nCurPos >= GetSize();
-}
-
-FX_BOOL CFPDF_FileStream::ReadBlock(void* buffer,
-                                    FX_FILESIZE offset,
-                                    size_t size) {
-  if (!buffer || !size || !m_pFS->ReadBlock)
-    return FALSE;
-
-  if (m_pFS->ReadBlock(m_pFS->clientData, (FPDF_DWORD)offset, buffer,
-                       (FPDF_DWORD)size) == 0) {
-    m_nCurPos = offset + size;
-    return TRUE;
-  }
-  return FALSE;
-}
-
-size_t CFPDF_FileStream::ReadBlock(void* buffer, size_t size) {
-  if (!buffer || !size || !m_pFS->ReadBlock)
-    return 0;
-
-  FX_FILESIZE nSize = GetSize();
-  if (m_nCurPos >= nSize)
-    return 0;
-  FX_FILESIZE dwAvail = nSize - m_nCurPos;
-  if (dwAvail < (FX_FILESIZE)size)
-    size = (size_t)dwAvail;
-  if (m_pFS->ReadBlock(m_pFS->clientData, (FPDF_DWORD)m_nCurPos, buffer,
-                       (FPDF_DWORD)size) == 0) {
-    m_nCurPos += size;
-    return size;
-  }
-
-  return 0;
-}
-
-FX_BOOL CFPDF_FileStream::WriteBlock(const void* buffer,
-                                     FX_FILESIZE offset,
-                                     size_t size) {
-  if (!m_pFS || !m_pFS->WriteBlock)
-    return FALSE;
-
-  if (m_pFS->WriteBlock(m_pFS->clientData, (FPDF_DWORD)offset, buffer,
-                        (FPDF_DWORD)size) == 0) {
-    m_nCurPos = offset + size;
-    return TRUE;
-  }
-  return FALSE;
-}
-
-FX_BOOL CFPDF_FileStream::Flush() {
-  if (!m_pFS || !m_pFS->Flush)
-    return TRUE;
-
-  return m_pFS->Flush(m_pFS->clientData) == 0;
-}
-#endif  // PDF_ENABLE_XFA
-
-CPDF_CustomAccess::CPDF_CustomAccess(FPDF_FILEACCESS* pFileAccess) {
-  m_FileAccess = *pFileAccess;
-#ifdef PDF_ENABLE_XFA
-  m_BufferOffset = (FX_DWORD)-1;
-#endif  // PDF_ENABLE_XFA
-}
-
-#ifdef PDF_ENABLE_XFA
-FX_BOOL CPDF_CustomAccess::GetByte(FX_DWORD pos, uint8_t& ch) {
-  if (pos >= m_FileAccess.m_FileLen)
-    return FALSE;
-  if (m_BufferOffset == (FX_DWORD)-1 || pos < m_BufferOffset ||
-      pos >= m_BufferOffset + 512) {
-    // Need to read from file access
-    m_BufferOffset = pos;
-    int size = 512;
-    if (pos + 512 > m_FileAccess.m_FileLen)
-      size = m_FileAccess.m_FileLen - pos;
-    if (!m_FileAccess.m_GetBlock(m_FileAccess.m_Param, m_BufferOffset, m_Buffer,
-                                 size))
-      return FALSE;
-  }
-  ch = m_Buffer[pos - m_BufferOffset];
-  return TRUE;
-}
-
-FX_BOOL CPDF_CustomAccess::GetBlock(FX_DWORD pos,
-                                    uint8_t* pBuf,
-                                    FX_DWORD size) {
-  if (pos + size > m_FileAccess.m_FileLen)
-    return FALSE;
-  return m_FileAccess.m_GetBlock(m_FileAccess.m_Param, pos, pBuf, size);
-}
-#endif  // PDF_ENABLE_XFA
-
-FX_BOOL CPDF_CustomAccess::ReadBlock(void* buffer,
-                                     FX_FILESIZE offset,
-                                     size_t size) {
-  if (offset < 0) {
-    return FALSE;
-  }
-  FX_SAFE_FILESIZE newPos =
-      pdfium::base::checked_cast<FX_FILESIZE, size_t>(size);
-  newPos += offset;
-  if (!newPos.IsValid() || newPos.ValueOrDie() > m_FileAccess.m_FileLen) {
-    return FALSE;
-  }
-  return m_FileAccess.m_GetBlock(m_FileAccess.m_Param, offset, (uint8_t*)buffer,
-                                 size);
-}
-
-// 0 bit: FPDF_POLICY_MACHINETIME_ACCESS
-static FX_DWORD foxit_sandbox_policy = 0xFFFFFFFF;
-
-void FSDK_SetSandBoxPolicy(FPDF_DWORD policy, FPDF_BOOL enable) {
-  switch (policy) {
-    case FPDF_POLICY_MACHINETIME_ACCESS: {
-      if (enable)
-        foxit_sandbox_policy |= 0x01;
-      else
-        foxit_sandbox_policy &= 0xFFFFFFFE;
-    } break;
-    default:
-      break;
-  }
-}
-
-FPDF_BOOL FSDK_IsSandBoxPolicyEnabled(FPDF_DWORD policy) {
-  switch (policy) {
-    case FPDF_POLICY_MACHINETIME_ACCESS:
-      return !!(foxit_sandbox_policy & 0x01);
-    default:
-      return FALSE;
-  }
-}
-
-CCodec_ModuleMgr* g_pCodecModule = nullptr;
-
-DLLEXPORT void STDCALL FPDF_InitLibrary() {
-  FPDF_InitLibraryWithConfig(nullptr);
-}
-
-DLLEXPORT void STDCALL FPDF_InitLibraryWithConfig(
-    const FPDF_LIBRARY_CONFIG* cfg) {
-  g_pCodecModule = new CCodec_ModuleMgr();
-
-  CFX_GEModule::Create(cfg ? cfg->m_pUserFontPaths : nullptr);
-  CFX_GEModule::Get()->SetCodecModule(g_pCodecModule);
-
-  CPDF_ModuleMgr::Create();
-  CPDF_ModuleMgr* pModuleMgr = CPDF_ModuleMgr::Get();
-  pModuleMgr->SetCodecModule(g_pCodecModule);
-  pModuleMgr->InitPageModule();
-  pModuleMgr->InitRenderModule();
-#ifdef PDF_ENABLE_XFA
-  CPDFXFA_App::GetInstance()->Initialize();
-#else   // PDF_ENABLE_XFA
-  pModuleMgr->LoadEmbeddedGB1CMaps();
-  pModuleMgr->LoadEmbeddedJapan1CMaps();
-  pModuleMgr->LoadEmbeddedCNS1CMaps();
-  pModuleMgr->LoadEmbeddedKorea1CMaps();
-#endif  // PDF_ENABLE_XFA
-  if (cfg && cfg->version >= 2)
-    IJS_Runtime::Initialize(cfg->m_v8EmbedderSlot, cfg->m_pIsolate);
-}
-
-DLLEXPORT void STDCALL FPDF_DestroyLibrary() {
-#ifdef PDF_ENABLE_XFA
-  CPDFXFA_App::ReleaseInstance();
-#endif  // PDF_ENABLE_XFA
-  CPDF_ModuleMgr::Destroy();
-  CFX_GEModule::Destroy();
-
-  delete g_pCodecModule;
-  g_pCodecModule = nullptr;
-}
-
-#ifndef _WIN32
-int g_LastError;
-void SetLastError(int err) {
-  g_LastError = err;
-}
-
-int GetLastError() {
-  return g_LastError;
-}
-#endif  // _WIN32
-
-void ProcessParseError(FX_DWORD err_code) {
-  // Translate FPDFAPI error code to FPDFVIEW error code
-  switch (err_code) {
-    case PDFPARSE_ERROR_FILE:
-      err_code = FPDF_ERR_FILE;
-      break;
-    case PDFPARSE_ERROR_FORMAT:
-      err_code = FPDF_ERR_FORMAT;
-      break;
-    case PDFPARSE_ERROR_PASSWORD:
-      err_code = FPDF_ERR_PASSWORD;
-      break;
-    case PDFPARSE_ERROR_HANDLER:
-      err_code = FPDF_ERR_SECURITY;
-      break;
-  }
-  SetLastError(err_code);
-}
-
-DLLEXPORT void STDCALL FPDF_SetSandBoxPolicy(FPDF_DWORD policy,
-                                             FPDF_BOOL enable) {
-  return FSDK_SetSandBoxPolicy(policy, enable);
-}
-
-DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_LoadDocument(FPDF_STRING file_path,
-                                                  FPDF_BYTESTRING password) {
-  // NOTE: the creation of the file needs to be by the embedder on the
-  // other side of this API.
-  IFX_FileRead* pFileAccess = FX_CreateFileRead((const FX_CHAR*)file_path);
-  if (!pFileAccess) {
-    return nullptr;
-  }
-
-  CPDF_Parser* pParser = new CPDF_Parser;
-  pParser->SetPassword(password);
-
-  FX_DWORD err_code = pParser->StartParse(pFileAccess);
-  if (err_code) {
-    delete pParser;
-    ProcessParseError(err_code);
-    return NULL;
-  }
-#ifdef PDF_ENABLE_XFA
-  CPDF_Document* pPDFDoc = pParser->GetDocument();
-  if (!pPDFDoc)
-    return NULL;
-
-  CPDFXFA_App* pProvider = CPDFXFA_App::GetInstance();
-  return new CPDFXFA_Document(pPDFDoc, pProvider);
-#else   // PDF_ENABLE_XFA
-  return pParser->GetDocument();
-#endif  // PDF_ENABLE_XFA
-}
-
-#ifdef PDF_ENABLE_XFA
-DLLEXPORT FPDF_BOOL STDCALL FPDF_HasXFAField(FPDF_DOCUMENT document,
-                                             int* docType) {
-  if (!document)
-    return FALSE;
-
-  CPDF_Document* pdfDoc =
-      (static_cast<CPDFXFA_Document*>(document))->GetPDFDoc();
-  if (!pdfDoc)
-    return FALSE;
-
-  CPDF_Dictionary* pRoot = pdfDoc->GetRoot();
-  if (!pRoot)
-    return FALSE;
-
-  CPDF_Dictionary* pAcroForm = pRoot->GetDict("AcroForm");
-  if (!pAcroForm)
-    return FALSE;
-
-  CPDF_Object* pXFA = pAcroForm->GetElement("XFA");
-  if (!pXFA)
-    return FALSE;
-
-  FX_BOOL bDynamicXFA = pRoot->GetBoolean("NeedsRendering", FALSE);
-
-  if (bDynamicXFA)
-    *docType = DOCTYPE_DYNAMIC_XFA;
-  else
-    *docType = DOCTYPE_STATIC_XFA;
-
-  return TRUE;
-}
-
-DLLEXPORT FPDF_BOOL STDCALL FPDF_LoadXFA(FPDF_DOCUMENT document) {
-  return document && (static_cast<CPDFXFA_Document*>(document))->LoadXFADoc();
-}
-#endif  // PDF_ENABLE_XFA
-
-class CMemFile final : public IFX_FileRead {
- public:
-  CMemFile(uint8_t* pBuf, FX_FILESIZE size) : m_pBuf(pBuf), m_size(size) {}
-
-  void Release() override { delete this; }
-  FX_FILESIZE GetSize() override { return m_size; }
-  FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override {
-    if (offset < 0) {
-      return FALSE;
-    }
-    FX_SAFE_FILESIZE newPos =
-        pdfium::base::checked_cast<FX_FILESIZE, size_t>(size);
-    newPos += offset;
-    if (!newPos.IsValid() || newPos.ValueOrDie() > (FX_DWORD)m_size) {
-      return FALSE;
-    }
-    FXSYS_memcpy(buffer, m_pBuf + offset, size);
-    return TRUE;
-  }
-
- private:
-  ~CMemFile() override {}
-
-  uint8_t* const m_pBuf;
-  const FX_FILESIZE m_size;
-};
-
-DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_LoadMemDocument(const void* data_buf,
-                                                     int size,
-                                                     FPDF_BYTESTRING password) {
-  CPDF_Parser* pParser = new CPDF_Parser;
-  pParser->SetPassword(password);
-  CMemFile* pMemFile = new CMemFile((uint8_t*)data_buf, size);
-  FX_DWORD err_code = pParser->StartParse(pMemFile);
-  if (err_code) {
-    delete pParser;
-    ProcessParseError(err_code);
-    return NULL;
-  }
-  CPDF_Document* pDoc = NULL;
-  pDoc = pParser ? pParser->GetDocument() : NULL;
-  CheckUnSupportError(pDoc, err_code);
-  return FPDFDocumentFromCPDFDocument(pParser->GetDocument());
-}
-
-DLLEXPORT FPDF_DOCUMENT STDCALL
-FPDF_LoadCustomDocument(FPDF_FILEACCESS* pFileAccess,
-                        FPDF_BYTESTRING password) {
-  CPDF_Parser* pParser = new CPDF_Parser;
-  pParser->SetPassword(password);
-  CPDF_CustomAccess* pFile = new CPDF_CustomAccess(pFileAccess);
-  FX_DWORD err_code = pParser->StartParse(pFile);
-  if (err_code) {
-    delete pParser;
-    ProcessParseError(err_code);
-    return NULL;
-  }
-  CPDF_Document* pDoc = NULL;
-  pDoc = pParser ? pParser->GetDocument() : NULL;
-  CheckUnSupportError(pDoc, err_code);
-  return FPDFDocumentFromCPDFDocument(pParser->GetDocument());
-}
-
-DLLEXPORT FPDF_BOOL STDCALL FPDF_GetFileVersion(FPDF_DOCUMENT doc,
-                                                int* fileVersion) {
-  if (!fileVersion)
-    return FALSE;
-
-  *fileVersion = 0;
-  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(doc);
-  if (!pDoc)
-    return FALSE;
-
-  CPDF_Parser* pParser = pDoc->GetParser();
-  if (!pParser)
-    return FALSE;
-
-  *fileVersion = pParser->GetFileVersion();
-  return TRUE;
-}
-
-// jabdelmalek: changed return type from FX_DWORD to build on Linux (and match
-// header).
-DLLEXPORT unsigned long STDCALL FPDF_GetDocPermissions(FPDF_DOCUMENT document) {
-  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
-  if (!pDoc)
-#ifndef PDF_ENABLE_XFA
-    return 0;
-#else   // PDF_ENABLE_XFA
-    return (FX_DWORD)-1;
-#endif  // PDF_ENABLE_XFA
-
-  CPDF_Dictionary* pDict = pDoc->GetParser()->GetEncryptDict();
-  return pDict ? pDict->GetInteger("P") : (FX_DWORD)-1;
-}
-
-DLLEXPORT int STDCALL FPDF_GetSecurityHandlerRevision(FPDF_DOCUMENT document) {
-  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
-  if (!pDoc)
-    return -1;
-
-  CPDF_Dictionary* pDict = pDoc->GetParser()->GetEncryptDict();
-  return pDict ? pDict->GetInteger("R") : -1;
-}
-
-DLLEXPORT int STDCALL FPDF_GetPageCount(FPDF_DOCUMENT document) {
-  UnderlyingDocumentType* pDoc = UnderlyingFromFPDFDocument(document);
-  return pDoc ? pDoc->GetPageCount() : 0;
-}
-
-DLLEXPORT FPDF_PAGE STDCALL FPDF_LoadPage(FPDF_DOCUMENT document,
-                                          int page_index) {
-  UnderlyingDocumentType* pDoc = UnderlyingFromFPDFDocument(document);
-  if (!pDoc)
-    return nullptr;
-
-  if (page_index < 0 || page_index >= pDoc->GetPageCount())
-    return nullptr;
-
-#ifdef PDF_ENABLE_XFA
-  return pDoc->GetPage(page_index);
-#else   // PDF_ENABLE_XFA
-  CPDF_Dictionary* pDict = pDoc->GetPage(page_index);
-  if (!pDict)
-    return NULL;
-  CPDF_Page* pPage = new CPDF_Page;
-  pPage->Load(pDoc, pDict);
-  pPage->ParseContent();
-  return pPage;
-#endif  // PDF_ENABLE_XFA
-}
-
-DLLEXPORT double STDCALL FPDF_GetPageWidth(FPDF_PAGE page) {
-  UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
-  return pPage ? pPage->GetPageWidth() : 0.0;
-}
-
-DLLEXPORT double STDCALL FPDF_GetPageHeight(FPDF_PAGE page) {
-  UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
-  return pPage ? pPage->GetPageHeight() : 0.0;
-}
-
-void DropContext(void* data) {
-  delete (CRenderContext*)data;
-}
-
-#if defined(_DEBUG) || defined(DEBUG)
-#define DEBUG_TRACE
-#endif
-
-#if defined(_WIN32)
-DLLEXPORT void STDCALL FPDF_RenderPage(HDC dc,
-                                       FPDF_PAGE page,
-                                       int start_x,
-                                       int start_y,
-                                       int size_x,
-                                       int size_y,
-                                       int rotate,
-                                       int flags) {
-  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
-  if (!pPage)
-    return;
-
-  CRenderContext* pContext = new CRenderContext;
-  pPage->SetPrivateData((void*)1, pContext, DropContext);
-
-#ifndef _WIN32_WCE
-  CFX_DIBitmap* pBitmap = nullptr;
-  FX_BOOL bBackgroundAlphaNeeded = pPage->BackgroundAlphaNeeded();
-  FX_BOOL bHasImageMask = pPage->HasImageMask();
-  if (bBackgroundAlphaNeeded || bHasImageMask) {
-    pBitmap = new CFX_DIBitmap;
-    pBitmap->Create(size_x, size_y, FXDIB_Argb);
-    pBitmap->Clear(0x00ffffff);
-#ifdef _SKIA_SUPPORT_
-    pContext->m_pDevice = new CFX_SkiaDevice;
-    ((CFX_SkiaDevice*)pContext->m_pDevice)->Attach((CFX_DIBitmap*)pBitmap);
-#else
-    pContext->m_pDevice = new CFX_FxgeDevice;
-    ((CFX_FxgeDevice*)pContext->m_pDevice)->Attach((CFX_DIBitmap*)pBitmap);
-#endif
-  } else {
-    pContext->m_pDevice = new CFX_WindowsDevice(dc);
-  }
-
-  FPDF_RenderPage_Retail(pContext, page, start_x, start_y, size_x, size_y,
-                         rotate, flags, TRUE, NULL);
-
-  if (bBackgroundAlphaNeeded || bHasImageMask) {
-    if (pBitmap) {
-      CFX_WindowsDevice WinDC(dc);
-
-      if (WinDC.GetDeviceCaps(FXDC_DEVICE_CLASS) == FXDC_PRINTER) {
-        CFX_DIBitmap* pDst = new CFX_DIBitmap;
-        int pitch = pBitmap->GetPitch();
-        pDst->Create(size_x, size_y, FXDIB_Rgb32);
-        FXSYS_memset(pDst->GetBuffer(), -1, pitch * size_y);
-        pDst->CompositeBitmap(0, 0, size_x, size_y, pBitmap, 0, 0,
-                              FXDIB_BLEND_NORMAL, NULL, FALSE, NULL);
-        WinDC.StretchDIBits(pDst, 0, 0, size_x, size_y);
-        delete pDst;
-      } else {
-        WinDC.SetDIBits(pBitmap, 0, 0);
-      }
-    }
-  }
-#else
-  // get clip region
-  RECT rect, cliprect;
-  rect.left = start_x;
-  rect.top = start_y;
-  rect.right = start_x + size_x;
-  rect.bottom = start_y + size_y;
-  GetClipBox(dc, &cliprect);
-  IntersectRect(&rect, &rect, &cliprect);
-  int width = rect.right - rect.left;
-  int height = rect.bottom - rect.top;
-
-#ifdef DEBUG_TRACE
-  {
-    char str[128];
-    memset(str, 0, sizeof(str));
-    FXSYS_snprintf(str, sizeof(str) - 1, "Rendering DIB %d x %d", width,
-                   height);
-    CPDF_ModuleMgr::Get()->ReportError(999, str);
-  }
-#endif
-
-  // Create a DIB section
-  LPVOID pBuffer;
-  BITMAPINFOHEADER bmih;
-  FXSYS_memset(&bmih, 0, sizeof bmih);
-  bmih.biSize = sizeof bmih;
-  bmih.biBitCount = 24;
-  bmih.biHeight = -height;
-  bmih.biPlanes = 1;
-  bmih.biWidth = width;
-  pContext->m_hBitmap = CreateDIBSection(dc, (BITMAPINFO*)&bmih, DIB_RGB_COLORS,
-                                         &pBuffer, NULL, 0);
-  if (!pContext->m_hBitmap) {
-#if defined(DEBUG) || defined(_DEBUG)
-    char str[128];
-    memset(str, 0, sizeof(str));
-    FXSYS_snprintf(str, sizeof(str) - 1,
-                   "Error CreateDIBSection: %d x %d, error code = %d", width,
-                   height, GetLastError());
-    CPDF_ModuleMgr::Get()->ReportError(FPDFERR_OUT_OF_MEMORY, str);
-#else
-    CPDF_ModuleMgr::Get()->ReportError(FPDFERR_OUT_OF_MEMORY, NULL);
-#endif
-  }
-  FXSYS_memset(pBuffer, 0xff, height * ((width * 3 + 3) / 4 * 4));
-
-#ifdef DEBUG_TRACE
-  { CPDF_ModuleMgr::Get()->ReportError(999, "DIBSection created"); }
-#endif
-
-  // Create a device with this external buffer
-  pContext->m_pBitmap = new CFX_DIBitmap;
-  pContext->m_pBitmap->Create(width, height, FXDIB_Rgb, (uint8_t*)pBuffer);
-  pContext->m_pDevice = new CPDF_FxgeDevice;
-  ((CPDF_FxgeDevice*)pContext->m_pDevice)->Attach(pContext->m_pBitmap);
-
-#ifdef DEBUG_TRACE
-  CPDF_ModuleMgr::Get()->ReportError(999, "Ready for PDF rendering");
-#endif
-
-  // output to bitmap device
-  FPDF_RenderPage_Retail(pContext, page, start_x - rect.left,
-                         start_y - rect.top, size_x, size_y, rotate, flags);
-
-#ifdef DEBUG_TRACE
-  CPDF_ModuleMgr::Get()->ReportError(999, "Finished PDF rendering");
-#endif
-
-  // Now output to real device
-  HDC hMemDC = CreateCompatibleDC(dc);
-  if (!hMemDC) {
-#if defined(DEBUG) || defined(_DEBUG)
-    char str[128];
-    memset(str, 0, sizeof(str));
-    FXSYS_snprintf(str, sizeof(str) - 1,
-                   "Error CreateCompatibleDC. Error code = %d", GetLastError());
-    CPDF_ModuleMgr::Get()->ReportError(FPDFERR_OUT_OF_MEMORY, str);
-#else
-    CPDF_ModuleMgr::Get()->ReportError(FPDFERR_OUT_OF_MEMORY, NULL);
-#endif
-  }
-
-  HGDIOBJ hOldBitmap = SelectObject(hMemDC, pContext->m_hBitmap);
-
-#ifdef DEBUG_TRACE
-  CPDF_ModuleMgr::Get()->ReportError(999, "Ready for screen rendering");
-#endif
-
-  BitBlt(dc, rect.left, rect.top, width, height, hMemDC, 0, 0, SRCCOPY);
-  SelectObject(hMemDC, hOldBitmap);
-  DeleteDC(hMemDC);
-
-#ifdef DEBUG_TRACE
-  CPDF_ModuleMgr::Get()->ReportError(999, "Finished screen rendering");
-#endif
-
-#endif
-  if (bBackgroundAlphaNeeded || bHasImageMask)
-    delete pBitmap;
-
-  delete pContext;
-  pPage->RemovePrivateData((void*)1);
-}
-#endif
-
-DLLEXPORT void STDCALL FPDF_RenderPageBitmap(FPDF_BITMAP bitmap,
-                                             FPDF_PAGE page,
-                                             int start_x,
-                                             int start_y,
-                                             int size_x,
-                                             int size_y,
-                                             int rotate,
-                                             int flags) {
-  if (!bitmap)
-    return;
-  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
-  if (!pPage)
-    return;
-  CRenderContext* pContext = new CRenderContext;
-  pPage->SetPrivateData((void*)1, pContext, DropContext);
-#ifdef _SKIA_SUPPORT_
-  pContext->m_pDevice = new CFX_SkiaDevice;
-
-  if (flags & FPDF_REVERSE_BYTE_ORDER)
-    ((CFX_SkiaDevice*)pContext->m_pDevice)
-        ->Attach((CFX_DIBitmap*)bitmap, 0, TRUE);
-  else
-    ((CFX_SkiaDevice*)pContext->m_pDevice)->Attach((CFX_DIBitmap*)bitmap);
-#else
-  pContext->m_pDevice = new CFX_FxgeDevice;
-
-  if (flags & FPDF_REVERSE_BYTE_ORDER)
-    ((CFX_FxgeDevice*)pContext->m_pDevice)
-        ->Attach((CFX_DIBitmap*)bitmap, 0, TRUE);
-  else
-    ((CFX_FxgeDevice*)pContext->m_pDevice)->Attach((CFX_DIBitmap*)bitmap);
-#endif
-
-  FPDF_RenderPage_Retail(pContext, page, start_x, start_y, size_x, size_y,
-                         rotate, flags, TRUE, NULL);
-
-  delete pContext;
-  pPage->RemovePrivateData((void*)1);
-}
-
-DLLEXPORT void STDCALL FPDF_ClosePage(FPDF_PAGE page) {
-  if (!page)
-    return;
-#ifdef PDF_ENABLE_XFA
-  CPDFXFA_Page* pPage = (CPDFXFA_Page*)page;
-  pPage->Release();
-#else   // PDF_ENABLE_XFA
-  CPDFSDK_PageView* pPageView =
-      (CPDFSDK_PageView*)(((CPDF_Page*)page))->GetPrivateData((void*)page);
-  if (pPageView && pPageView->IsLocked()) {
-    pPageView->TakeOverPage();
-    return;
-  }
-  delete (CPDF_Page*)page;
-#endif  // PDF_ENABLE_XFA
-}
-
-DLLEXPORT void STDCALL FPDF_CloseDocument(FPDF_DOCUMENT document) {
-#ifdef PDF_ENABLE_XFA
-  delete UnderlyingFromFPDFDocument(document);
-#else   // PDF_ENABLE_XFA
-  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
-  if (!pDoc)
-    return;
-  CPDF_Parser* pParser = pDoc->GetParser();
-  if (!pParser) {
-    delete pDoc;
-    return;
-  }
-  delete pParser;
-#endif  // PDF_ENABLE_XFA
-}
-
-DLLEXPORT unsigned long STDCALL FPDF_GetLastError() {
-  return GetLastError();
-}
-
-DLLEXPORT void STDCALL FPDF_DeviceToPage(FPDF_PAGE page,
-                                         int start_x,
-                                         int start_y,
-                                         int size_x,
-                                         int size_y,
-                                         int rotate,
-                                         int device_x,
-                                         int device_y,
-                                         double* page_x,
-                                         double* page_y) {
-  if (!page || !page_x || !page_y)
-    return;
-  UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
-#ifdef PDF_ENABLE_XFA
-  pPage->DeviceToPage(start_x, start_y, size_x, size_y, rotate, device_x,
-                      device_y, page_x, page_y);
-#else   // PDF_ENABLE_XFA
-  CFX_Matrix page2device;
-  pPage->GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y,
-                          rotate);
-  CFX_Matrix device2page;
-  device2page.SetReverse(page2device);
-  FX_FLOAT page_x_f, page_y_f;
-  device2page.Transform((FX_FLOAT)(device_x), (FX_FLOAT)(device_y), page_x_f,
-                        page_y_f);
-  *page_x = (page_x_f);
-  *page_y = (page_y_f);
-#endif  // PDF_ENABLE_XFA
-}
-
-DLLEXPORT void STDCALL FPDF_PageToDevice(FPDF_PAGE page,
-                                         int start_x,
-                                         int start_y,
-                                         int size_x,
-                                         int size_y,
-                                         int rotate,
-                                         double page_x,
-                                         double page_y,
-                                         int* device_x,
-                                         int* device_y) {
-  if (!device_x || !device_y)
-    return;
-  UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
-  if (!pPage)
-    return;
-#ifdef PDF_ENABLE_XFA
-  pPage->PageToDevice(start_x, start_y, size_x, size_y, rotate, page_x, page_y,
-                      device_x, device_y);
-#else   // PDF_ENABLE_XFA
-  CFX_Matrix page2device;
-  pPage->GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y,
-                          rotate);
-  FX_FLOAT device_x_f, device_y_f;
-  page2device.Transform(((FX_FLOAT)page_x), ((FX_FLOAT)page_y), device_x_f,
-                        device_y_f);
-  *device_x = FXSYS_round(device_x_f);
-  *device_y = FXSYS_round(device_y_f);
-#endif  // PDF_ENABLE_XFA
-}
-
-DLLEXPORT FPDF_BITMAP STDCALL FPDFBitmap_Create(int width,
-                                                int height,
-                                                int alpha) {
-  std::unique_ptr<CFX_DIBitmap> pBitmap(new CFX_DIBitmap);
-  if (!pBitmap->Create(width, height, alpha ? FXDIB_Argb : FXDIB_Rgb32)) {
-    return NULL;
-  }
-  return pBitmap.release();
-}
-
-DLLEXPORT FPDF_BITMAP STDCALL FPDFBitmap_CreateEx(int width,
-                                                  int height,
-                                                  int format,
-                                                  void* first_scan,
-                                                  int stride) {
-  FXDIB_Format fx_format;
-  switch (format) {
-    case FPDFBitmap_Gray:
-      fx_format = FXDIB_8bppRgb;
-      break;
-    case FPDFBitmap_BGR:
-      fx_format = FXDIB_Rgb;
-      break;
-    case FPDFBitmap_BGRx:
-      fx_format = FXDIB_Rgb32;
-      break;
-    case FPDFBitmap_BGRA:
-      fx_format = FXDIB_Argb;
-      break;
-    default:
-      return NULL;
-  }
-  CFX_DIBitmap* pBitmap = new CFX_DIBitmap;
-  pBitmap->Create(width, height, fx_format, (uint8_t*)first_scan, stride);
-  return pBitmap;
-}
-
-DLLEXPORT void STDCALL FPDFBitmap_FillRect(FPDF_BITMAP bitmap,
-                                           int left,
-                                           int top,
-                                           int width,
-                                           int height,
-                                           FPDF_DWORD color) {
-  if (!bitmap)
-    return;
-#ifdef _SKIA_SUPPORT_
-  CFX_SkiaDevice device;
-#else
-  CFX_FxgeDevice device;
-#endif
-  device.Attach((CFX_DIBitmap*)bitmap);
-  if (!((CFX_DIBitmap*)bitmap)->HasAlpha())
-    color |= 0xFF000000;
-  FX_RECT rect(left, top, left + width, top + height);
-  device.FillRect(&rect, color);
-}
-
-DLLEXPORT void* STDCALL FPDFBitmap_GetBuffer(FPDF_BITMAP bitmap) {
-  return bitmap ? ((CFX_DIBitmap*)bitmap)->GetBuffer() : nullptr;
-}
-
-DLLEXPORT int STDCALL FPDFBitmap_GetWidth(FPDF_BITMAP bitmap) {
-  return bitmap ? ((CFX_DIBitmap*)bitmap)->GetWidth() : 0;
-}
-
-DLLEXPORT int STDCALL FPDFBitmap_GetHeight(FPDF_BITMAP bitmap) {
-  return bitmap ? ((CFX_DIBitmap*)bitmap)->GetHeight() : 0;
-}
-
-DLLEXPORT int STDCALL FPDFBitmap_GetStride(FPDF_BITMAP bitmap) {
-  return bitmap ? ((CFX_DIBitmap*)bitmap)->GetPitch() : 0;
-}
-
-DLLEXPORT void STDCALL FPDFBitmap_Destroy(FPDF_BITMAP bitmap) {
-  delete (CFX_DIBitmap*)bitmap;
-}
-
-void FPDF_RenderPage_Retail(CRenderContext* pContext,
-                            FPDF_PAGE page,
-                            int start_x,
-                            int start_y,
-                            int size_x,
-                            int size_y,
-                            int rotate,
-                            int flags,
-                            FX_BOOL bNeedToRestore,
-                            IFSDK_PAUSE_Adapter* pause) {
-  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
-  if (!pPage)
-    return;
-
-  if (!pContext->m_pOptions)
-    pContext->m_pOptions = new CPDF_RenderOptions;
-
-  if (flags & FPDF_LCD_TEXT)
-    pContext->m_pOptions->m_Flags |= RENDER_CLEARTYPE;
-  else
-    pContext->m_pOptions->m_Flags &= ~RENDER_CLEARTYPE;
-  if (flags & FPDF_NO_NATIVETEXT)
-    pContext->m_pOptions->m_Flags |= RENDER_NO_NATIVETEXT;
-  if (flags & FPDF_RENDER_LIMITEDIMAGECACHE)
-    pContext->m_pOptions->m_Flags |= RENDER_LIMITEDIMAGECACHE;
-  if (flags & FPDF_RENDER_FORCEHALFTONE)
-    pContext->m_pOptions->m_Flags |= RENDER_FORCE_HALFTONE;
-#ifndef PDF_ENABLE_XFA
-  if (flags & FPDF_RENDER_NO_SMOOTHTEXT)
-    pContext->m_pOptions->m_Flags |= RENDER_NOTEXTSMOOTH;
-  if (flags & FPDF_RENDER_NO_SMOOTHIMAGE)
-    pContext->m_pOptions->m_Flags |= RENDER_NOIMAGESMOOTH;
-  if (flags & FPDF_RENDER_NO_SMOOTHPATH)
-    pContext->m_pOptions->m_Flags |= RENDER_NOPATHSMOOTH;
-#endif  // PDF_ENABLE_XFA
-  // Grayscale output
-  if (flags & FPDF_GRAYSCALE) {
-    pContext->m_pOptions->m_ColorMode = RENDER_COLOR_GRAY;
-    pContext->m_pOptions->m_ForeColor = 0;
-    pContext->m_pOptions->m_BackColor = 0xffffff;
-  }
-  const CPDF_OCContext::UsageType usage =
-      (flags & FPDF_PRINTING) ? CPDF_OCContext::Print : CPDF_OCContext::View;
-  pContext->m_pOptions->m_AddFlags = flags >> 8;
-  pContext->m_pOptions->m_pOCContext =
-      new CPDF_OCContext(pPage->m_pDocument, usage);
-
-  CFX_Matrix matrix;
-  pPage->GetDisplayMatrix(matrix, start_x, start_y, size_x, size_y, rotate);
-
-  FX_RECT clip;
-  clip.left = start_x;
-  clip.right = start_x + size_x;
-  clip.top = start_y;
-  clip.bottom = start_y + size_y;
-  pContext->m_pDevice->SaveState();
-  pContext->m_pDevice->SetClip_Rect(&clip);
-
-  pContext->m_pContext = new CPDF_RenderContext(pPage);
-  pContext->m_pContext->AppendObjectList(pPage, &matrix);
-
-  if (flags & FPDF_ANNOT) {
-    pContext->m_pAnnots = new CPDF_AnnotList(pPage);
-    FX_BOOL bPrinting = pContext->m_pDevice->GetDeviceClass() != FXDC_DISPLAY;
-    pContext->m_pAnnots->DisplayAnnots(pPage, pContext->m_pContext, bPrinting,
-                                       &matrix, TRUE, NULL);
-  }
-
-  pContext->m_pRenderer = new CPDF_ProgressiveRenderer(
-      pContext->m_pContext, pContext->m_pDevice, pContext->m_pOptions);
-  pContext->m_pRenderer->Start(pause);
-  if (bNeedToRestore)
-    pContext->m_pDevice->RestoreState();
-}
-
-DLLEXPORT int STDCALL FPDF_GetPageSizeByIndex(FPDF_DOCUMENT document,
-                                              int page_index,
-                                              double* width,
-                                              double* height) {
-  UnderlyingDocumentType* pDoc = UnderlyingFromFPDFDocument(document);
-  if (!pDoc)
-    return FALSE;
-
-#ifdef PDF_ENABLE_XFA
-  int count = pDoc->GetPageCount();
-  if (page_index < 0 || page_index >= count)
-    return FALSE;
-  CPDFXFA_Page* pPage = pDoc->GetPage(page_index);
-  if (!pPage)
-    return FALSE;
-  *width = pPage->GetPageWidth();
-  *height = pPage->GetPageHeight();
-#else   // PDF_ENABLE_XFA
-  CPDF_Dictionary* pDict = pDoc->GetPage(page_index);
-  if (!pDict)
-    return FALSE;
-  CPDF_Page page;
-  page.Load(pDoc, pDict);
-  *width = page.GetPageWidth();
-  *height = page.GetPageHeight();
-#endif  // PDF_ENABLE_XFA
-
-  return TRUE;
-}
-
-DLLEXPORT FPDF_BOOL STDCALL
-FPDF_VIEWERREF_GetPrintScaling(FPDF_DOCUMENT document) {
-  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
-  if (!pDoc)
-    return TRUE;
-  CPDF_ViewerPreferences viewRef(pDoc);
-  return viewRef.PrintScaling();
-}
-
-DLLEXPORT int STDCALL FPDF_VIEWERREF_GetNumCopies(FPDF_DOCUMENT document) {
-  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
-  if (!pDoc)
-    return 1;
-  CPDF_ViewerPreferences viewRef(pDoc);
-  return viewRef.NumCopies();
-}
-
-DLLEXPORT FPDF_PAGERANGE STDCALL
-FPDF_VIEWERREF_GetPrintPageRange(FPDF_DOCUMENT document) {
-  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
-  if (!pDoc)
-    return NULL;
-  CPDF_ViewerPreferences viewRef(pDoc);
-  return viewRef.PrintPageRange();
-}
-
-DLLEXPORT FPDF_DUPLEXTYPE STDCALL
-FPDF_VIEWERREF_GetDuplex(FPDF_DOCUMENT document) {
-  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
-  if (!pDoc)
-    return DuplexUndefined;
-  CPDF_ViewerPreferences viewRef(pDoc);
-  CFX_ByteString duplex = viewRef.Duplex();
-  if ("Simplex" == duplex)
-    return Simplex;
-  if ("DuplexFlipShortEdge" == duplex)
-    return DuplexFlipShortEdge;
-  if ("DuplexFlipLongEdge" == duplex)
-    return DuplexFlipLongEdge;
-  return DuplexUndefined;
-}
-
-DLLEXPORT FPDF_DWORD STDCALL FPDF_CountNamedDests(FPDF_DOCUMENT document) {
-  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
-  if (!pDoc)
-    return 0;
-
-  CPDF_Dictionary* pRoot = pDoc->GetRoot();
-  if (!pRoot)
-    return 0;
-
-  CPDF_NameTree nameTree(pDoc, "Dests");
-  pdfium::base::CheckedNumeric<FPDF_DWORD> count = nameTree.GetCount();
-  CPDF_Dictionary* pDest = pRoot->GetDict("Dests");
-  if (pDest)
-    count += pDest->GetCount();
-
-  if (!count.IsValid())
-    return 0;
-
-  return count.ValueOrDie();
-}
-
-DLLEXPORT FPDF_DEST STDCALL FPDF_GetNamedDestByName(FPDF_DOCUMENT document,
-                                                    FPDF_BYTESTRING name) {
-  if (!name || name[0] == 0)
-    return nullptr;
-
-  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
-  if (!pDoc)
-    return nullptr;
-
-  CPDF_NameTree name_tree(pDoc, "Dests");
-  return name_tree.LookupNamedDest(pDoc, name);
-}
-
-#ifdef PDF_ENABLE_XFA
-FPDF_RESULT FPDF_BStr_Init(FPDF_BSTR* str) {
-  if (!str)
-    return -1;
-
-  FXSYS_memset(str, 0, sizeof(FPDF_BSTR));
-  return 0;
-}
-
-FPDF_RESULT FPDF_BStr_Set(FPDF_BSTR* str, FPDF_LPCSTR bstr, int length) {
-  if (!str)
-    return -1;
-  if (!bstr || !length)
-    return -1;
-  if (length == -1)
-    length = FXSYS_strlen(bstr);
-
-  if (length == 0) {
-    if (str->str) {
-      FX_Free(str->str);
-      str->str = NULL;
-    }
-    str->len = 0;
-    return 0;
-  }
-
-  if (str->str && str->len < length)
-    str->str = FX_Realloc(char, str->str, length + 1);
-  else if (!str->str)
-    str->str = FX_Alloc(char, length + 1);
-
-  str->str[length] = 0;
-  if (str->str == NULL)
-    return -1;
-
-  FXSYS_memcpy(str->str, bstr, length);
-  str->len = length;
-
-  return 0;
-}
-
-FPDF_RESULT FPDF_BStr_Clear(FPDF_BSTR* str) {
-  if (!str)
-    return -1;
-
-  if (str->str) {
-    FX_Free(str->str);
-    str->str = NULL;
-  }
-  str->len = 0;
-  return 0;
-}
-#endif  // PDF_ENABLE_XFA
-
-DLLEXPORT FPDF_DEST STDCALL FPDF_GetNamedDest(FPDF_DOCUMENT document,
-                                              int index,
-                                              void* buffer,
-                                              long* buflen) {
-  if (!buffer)
-    *buflen = 0;
-
-  if (index < 0)
-    return nullptr;
-
-  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
-  if (!pDoc)
-    return nullptr;
-
-  CPDF_Dictionary* pRoot = pDoc->GetRoot();
-  if (!pRoot)
-    return nullptr;
-
-  CPDF_Object* pDestObj = nullptr;
-  CFX_ByteString bsName;
-  CPDF_NameTree nameTree(pDoc, "Dests");
-  int count = nameTree.GetCount();
-  if (index >= count) {
-    CPDF_Dictionary* pDest = pRoot->GetDict("Dests");
-    if (!pDest)
-      return nullptr;
-
-    pdfium::base::CheckedNumeric<int> checked_count = count;
-    checked_count += pDest->GetCount();
-    if (!checked_count.IsValid() || index >= checked_count.ValueOrDie())
-      return nullptr;
-
-    index -= count;
-    int i = 0;
-    for (const auto& it : *pDest) {
-      bsName = it.first;
-      pDestObj = it.second;
-      if (!pDestObj)
-        continue;
-      if (i == index)
-        break;
-      i++;
-    }
-  } else {
-    pDestObj = nameTree.LookupValue(index, bsName);
-  }
-  if (!pDestObj)
-    return nullptr;
-  if (CPDF_Dictionary* pDict = pDestObj->AsDictionary()) {
-    pDestObj = pDict->GetArray("D");
-    if (!pDestObj)
-      return nullptr;
-  }
-  if (!pDestObj->IsArray())
-    return nullptr;
-
-  CFX_WideString wsName = PDF_DecodeText(bsName);
-  CFX_ByteString utf16Name = wsName.UTF16LE_Encode();
-  unsigned int len = utf16Name.GetLength();
-  if (!buffer) {
-    *buflen = len;
-  } else if (*buflen >= len) {
-    memcpy(buffer, utf16Name.c_str(), len);
-    *buflen = len;
-  } else {
-    *buflen = -1;
-  }
-  return (FPDF_DEST)pDestObj;
-}
diff --git a/fpdfsdk/src/fpdfview_embeddertest.cpp b/fpdfsdk/src/fpdfview_embeddertest.cpp
deleted file mode 100644
index 3147c01..0000000
--- a/fpdfsdk/src/fpdfview_embeddertest.cpp
+++ /dev/null
@@ -1,230 +0,0 @@
-// Copyright 2015 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.
-
-#include <limits>
-#include <string>
-
-#include "fpdfsdk/src/fpdfview_c_api_test.h"
-#include "public/fpdfview.h"
-#include "testing/embedder_test.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-TEST(fpdf, CApiTest) {
-  EXPECT_TRUE(CheckPDFiumCApi());
-}
-
-class FPDFViewEmbeddertest : public EmbedderTest {};
-
-TEST_F(FPDFViewEmbeddertest, Document) {
-  EXPECT_TRUE(OpenDocument("about_blank.pdf"));
-  EXPECT_EQ(1, GetPageCount());
-  EXPECT_EQ(0, GetFirstPageNum());
-
-  int version;
-  EXPECT_TRUE(FPDF_GetFileVersion(document(), &version));
-  EXPECT_EQ(14, version);
-
-  EXPECT_EQ(0xFFFFFFFF, FPDF_GetDocPermissions(document()));
-  EXPECT_EQ(-1, FPDF_GetSecurityHandlerRevision(document()));
-}
-
-TEST_F(FPDFViewEmbeddertest, Page) {
-  EXPECT_TRUE(OpenDocument("about_blank.pdf"));
-  FPDF_PAGE page = LoadPage(0);
-  EXPECT_NE(nullptr, page);
-  EXPECT_EQ(612.0, FPDF_GetPageWidth(page));
-  EXPECT_EQ(792.0, FPDF_GetPageHeight(page));
-  UnloadPage(page);
-  EXPECT_EQ(nullptr, LoadPage(1));
-}
-
-TEST_F(FPDFViewEmbeddertest, ViewerRef) {
-  EXPECT_TRUE(OpenDocument("about_blank.pdf"));
-  EXPECT_TRUE(FPDF_VIEWERREF_GetPrintScaling(document()));
-  EXPECT_EQ(1, FPDF_VIEWERREF_GetNumCopies(document()));
-  EXPECT_EQ(DuplexUndefined, FPDF_VIEWERREF_GetDuplex(document()));
-}
-
-TEST_F(FPDFViewEmbeddertest, NamedDests) {
-  EXPECT_TRUE(OpenDocument("named_dests.pdf"));
-  long buffer_size;
-  char fixed_buffer[512];
-  FPDF_DEST dest;
-
-  // Query the size of the first item.
-  buffer_size = 2000000;  // Absurdly large, check not used for this case.
-  dest = FPDF_GetNamedDest(document(), 0, nullptr, &buffer_size);
-  EXPECT_NE(nullptr, dest);
-  EXPECT_EQ(12u, buffer_size);
-
-  // Try to retrieve the first item with too small a buffer.
-  buffer_size = 10;
-  dest = FPDF_GetNamedDest(document(), 0, fixed_buffer, &buffer_size);
-  EXPECT_NE(nullptr, dest);
-  EXPECT_EQ(-1, buffer_size);
-
-  // Try to retrieve the first item with correctly sized buffer. Item is
-  // taken from Dests NameTree in named_dests.pdf.
-  buffer_size = 12;
-  dest = FPDF_GetNamedDest(document(), 0, fixed_buffer, &buffer_size);
-  EXPECT_NE(nullptr, dest);
-  EXPECT_EQ(12u, buffer_size);
-  EXPECT_EQ(std::string("F\0i\0r\0s\0t\0\0\0", 12),
-            std::string(fixed_buffer, buffer_size));
-
-  // Try to retrieve the second item with ample buffer. Item is taken
-  // from Dests NameTree but has a sub-dictionary in named_dests.pdf.
-  buffer_size = sizeof(fixed_buffer);
-  dest = FPDF_GetNamedDest(document(), 1, fixed_buffer, &buffer_size);
-  EXPECT_NE(nullptr, dest);
-  EXPECT_EQ(10u, buffer_size);
-  EXPECT_EQ(std::string("N\0e\0x\0t\0\0\0", 10),
-            std::string(fixed_buffer, buffer_size));
-
-  // Try to retrieve third item with ample buffer. Item is taken
-  // from Dests NameTree but has a bad sub-dictionary in named_dests.pdf.
-  // in named_dests.pdf).
-  buffer_size = sizeof(fixed_buffer);
-  dest = FPDF_GetNamedDest(document(), 2, fixed_buffer, &buffer_size);
-  EXPECT_EQ(nullptr, dest);
-  EXPECT_EQ(sizeof(fixed_buffer), buffer_size);  // unmodified.
-
-  // Try to retrieve the forth item with ample buffer. Item is taken
-  // from Dests NameTree but has a vale of the wrong type in named_dests.pdf.
-  buffer_size = sizeof(fixed_buffer);
-  dest = FPDF_GetNamedDest(document(), 3, fixed_buffer, &buffer_size);
-  EXPECT_EQ(nullptr, dest);
-  EXPECT_EQ(sizeof(fixed_buffer), buffer_size);  // unmodified.
-
-  // Try to retrieve fifth item with ample buffer. Item taken from the
-  // old-style Dests dictionary object in named_dests.pdf.
-  buffer_size = sizeof(fixed_buffer);
-  dest = FPDF_GetNamedDest(document(), 4, fixed_buffer, &buffer_size);
-  EXPECT_NE(nullptr, dest);
-  EXPECT_EQ(30u, buffer_size);
-  EXPECT_EQ(std::string("F\0i\0r\0s\0t\0A\0l\0t\0e\0r\0n\0a\0t\0e\0\0\0", 30),
-            std::string(fixed_buffer, buffer_size));
-
-  // Try to retrieve sixth item with ample buffer. Item istaken from the
-  // old-style Dests dictionary object but has a sub-dictionary in
-  // named_dests.pdf.
-  buffer_size = sizeof(fixed_buffer);
-  dest = FPDF_GetNamedDest(document(), 5, fixed_buffer, &buffer_size);
-  EXPECT_NE(nullptr, dest);
-  EXPECT_EQ(28u, buffer_size);
-  EXPECT_EQ(std::string("L\0a\0s\0t\0A\0l\0t\0e\0r\0n\0a\0t\0e\0\0\0", 28),
-            std::string(fixed_buffer, buffer_size));
-
-  // Try to retrieve non-existent item with ample buffer.
-  buffer_size = sizeof(fixed_buffer);
-  dest = FPDF_GetNamedDest(document(), 6, fixed_buffer, &buffer_size);
-  EXPECT_EQ(nullptr, dest);
-  EXPECT_EQ(sizeof(fixed_buffer), buffer_size);  // unmodified.
-
-  // Try to underflow/overflow the integer index.
-  buffer_size = sizeof(fixed_buffer);
-  dest = FPDF_GetNamedDest(document(), std::numeric_limits<int>::max(),
-                           fixed_buffer, &buffer_size);
-  EXPECT_EQ(nullptr, dest);
-  EXPECT_EQ(sizeof(fixed_buffer), buffer_size);  // unmodified.
-
-  buffer_size = sizeof(fixed_buffer);
-  dest = FPDF_GetNamedDest(document(), std::numeric_limits<int>::min(),
-                           fixed_buffer, &buffer_size);
-  EXPECT_EQ(nullptr, dest);
-  EXPECT_EQ(sizeof(fixed_buffer), buffer_size);  // unmodified.
-
-  buffer_size = sizeof(fixed_buffer);
-  dest = FPDF_GetNamedDest(document(), -1, fixed_buffer, &buffer_size);
-  EXPECT_EQ(nullptr, dest);
-  EXPECT_EQ(sizeof(fixed_buffer), buffer_size);  // unmodified.
-}
-
-TEST_F(FPDFViewEmbeddertest, NamedDestsByName) {
-  EXPECT_TRUE(OpenDocument("named_dests.pdf"));
-
-  // Null pointer returns NULL.
-  FPDF_DEST dest = FPDF_GetNamedDestByName(document(), nullptr);
-  EXPECT_EQ(nullptr, dest);
-
-  // Empty string returns NULL.
-  dest = FPDF_GetNamedDestByName(document(), "");
-  EXPECT_EQ(nullptr, dest);
-
-  // Item from Dests NameTree.
-  dest = FPDF_GetNamedDestByName(document(), "First");
-  EXPECT_NE(nullptr, dest);
-
-  long ignore_len = 0;
-  FPDF_DEST dest_by_index =
-      FPDF_GetNamedDest(document(), 0, nullptr, &ignore_len);
-  EXPECT_EQ(dest_by_index, dest);
-
-  // Item from Dests dictionary.
-  dest = FPDF_GetNamedDestByName(document(), "FirstAlternate");
-  EXPECT_NE(nullptr, dest);
-
-  ignore_len = 0;
-  dest_by_index = FPDF_GetNamedDest(document(), 4, nullptr, &ignore_len);
-  EXPECT_EQ(dest_by_index, dest);
-
-  // Bad value type for item from Dests NameTree array.
-  dest = FPDF_GetNamedDestByName(document(), "WrongType");
-  EXPECT_EQ(nullptr, dest);
-
-  // No such destination in either Dest NameTree or dictionary.
-  dest = FPDF_GetNamedDestByName(document(), "Bogus");
-  EXPECT_EQ(nullptr, dest);
-}
-
-// The following tests pass if the document opens without crashing.
-TEST_F(FPDFViewEmbeddertest, Crasher_113) {
-  EXPECT_TRUE(OpenDocument("bug_113.pdf"));
-}
-
-TEST_F(FPDFViewEmbeddertest, Crasher_451830) {
-  // Document is damaged and can't be opened.
-  EXPECT_FALSE(OpenDocument("bug_451830.pdf"));
-}
-
-TEST_F(FPDFViewEmbeddertest, Crasher_452455) {
-  EXPECT_TRUE(OpenDocument("bug_452455.pdf"));
-  FPDF_PAGE page = LoadPage(0);
-  EXPECT_NE(nullptr, page);
-  UnloadPage(page);
-}
-
-TEST_F(FPDFViewEmbeddertest, Crasher_454695) {
-  // Document is damaged and can't be opened.
-  EXPECT_FALSE(OpenDocument("bug_454695.pdf"));
-}
-
-TEST_F(FPDFViewEmbeddertest, Crasher_572871) {
-  EXPECT_TRUE(OpenDocument("bug_572871.pdf"));
-}
-
-// The following tests pass if the document opens without infinite looping.
-TEST_F(FPDFViewEmbeddertest, Hang_298) {
-  EXPECT_FALSE(OpenDocument("bug_298.pdf"));
-}
-
-// Test if the document opens without infinite looping.
-// Previously this test will hang in a loop inside LoadAllCrossRefV4. After
-// the fix, LoadAllCrossRefV4 will return false after detecting a cross
-// reference loop. Cross references will be rebuilt successfully.
-TEST_F(FPDFViewEmbeddertest, CrossRefV4Loop) {
-  EXPECT_TRUE(OpenDocument("bug_xrefv4_loop.pdf"));
-}
-
-// The test should pass when circular references to ParseIndirectObject will not
-// cause infinite loop.
-TEST_F(FPDFViewEmbeddertest, Hang_343) {
-  EXPECT_FALSE(OpenDocument("bug_343.pdf"));
-}
-
-// The test should pass when the absence of 'Contents' field in a signature
-// dictionary will not cause an infinite loop in CPDF_SyntaxParser::GetObject().
-TEST_F(FPDFViewEmbeddertest, Hang_344) {
-  EXPECT_FALSE(OpenDocument("bug_344.pdf"));
-}
\ No newline at end of file
diff --git a/fpdfsdk/src/fpdfxfa/fpdfxfa_app.cpp b/fpdfsdk/src/fpdfxfa/fpdfxfa_app.cpp
deleted file mode 100644
index 853eb30..0000000
--- a/fpdfsdk/src/fpdfxfa/fpdfxfa_app.cpp
+++ /dev/null
@@ -1,537 +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

-

-#include "fpdfsdk/include/fsdk_define.h"

-#include "fpdfsdk/include/fsdk_mgr.h"

-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h"

-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h"

-#include "fpdfsdk/include/javascript/IJavaScript.h"

-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_app.h"

-#include "public/fpdf_formfill.h"

-

-CPDFXFA_App* CPDFXFA_App::g_pApp = NULL;

-

-CPDFXFA_App* CPDFXFA_App::GetInstance() {

-  if (!g_pApp) {

-    g_pApp = new CPDFXFA_App();

-  }

-  return g_pApp;

-}

-

-void CPDFXFA_App::ReleaseInstance() {

-  delete g_pApp;

-  g_pApp = NULL;

-}

-

-CPDFXFA_App::CPDFXFA_App()

-    : m_bJavaScriptInitialized(FALSE),

-      m_pXFAApp(NULL),

-      m_pFontMgr(NULL),

-      m_hJSERuntime(NULL),

-      m_csAppType(JS_STR_VIEWERTYPE_STANDARD) {

-  m_pEnvList.RemoveAll();

-}

-

-CPDFXFA_App::~CPDFXFA_App() {

-  delete m_pFontMgr;

-  m_pFontMgr = NULL;

-

-  delete m_pXFAApp;

-  m_pXFAApp = NULL;

-

-#ifdef PDF_ENABLE_XFA

-  FXJSE_Runtime_Release(m_hJSERuntime);

-  m_hJSERuntime = NULL;

-

-  FXJSE_Finalize();

-  BC_Library_Destory();

-#endif

-}

-

-FX_BOOL CPDFXFA_App::Initialize() {

-#ifdef PDF_ENABLE_XFA

-  BC_Library_Init();

-  FXJSE_Initialize();

-

-  m_hJSERuntime = FXJSE_Runtime_Create();

-  if (!m_hJSERuntime)

-    return FALSE;

-

-  m_pXFAApp = IXFA_App::Create(this);

-  if (!m_pXFAApp)

-    return FALSE;

-

-  m_pFontMgr = IXFA_FontMgr::CreateDefault();

-  if (!m_pFontMgr)

-    return FALSE;

-

-  m_pXFAApp->SetDefaultFontMgr(m_pFontMgr);

-#endif

-  return TRUE;

-}

-

-FX_BOOL CPDFXFA_App::AddFormFillEnv(CPDFDoc_Environment* pEnv) {

-  if (!pEnv)

-    return FALSE;

-

-  m_pEnvList.Add(pEnv);

-  return TRUE;

-}

-

-FX_BOOL CPDFXFA_App::RemoveFormFillEnv(CPDFDoc_Environment* pEnv) {

-  if (!pEnv)

-    return FALSE;

-

-  int nFind = m_pEnvList.Find(pEnv);

-  if (nFind != -1) {

-    m_pEnvList.RemoveAt(nFind);

-    return TRUE;

-  }

-

-  return FALSE;

-}

-

-void CPDFXFA_App::GetAppType(CFX_WideString& wsAppType) {

-  wsAppType = m_csAppType;

-}

-

-void CPDFXFA_App::GetAppName(CFX_WideString& wsName) {

-  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);

-  if (pEnv) {

-    wsName = pEnv->FFI_GetAppName();

-  }

-}

-

-void CPDFXFA_App::SetAppType(const CFX_WideStringC& wsAppType) {

-  m_csAppType = wsAppType;

-}

-

-void CPDFXFA_App::GetLanguage(CFX_WideString& wsLanguage) {

-  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);

-  if (pEnv) {

-    wsLanguage = pEnv->FFI_GetLanguage();

-  }

-}

-

-void CPDFXFA_App::GetPlatform(CFX_WideString& wsPlatform) {

-  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);

-  if (pEnv) {

-    wsPlatform = pEnv->FFI_GetPlatform();

-  }

-}

-

-void CPDFXFA_App::GetVariation(CFX_WideString& wsVariation) {

-  wsVariation = JS_STR_VIEWERVARIATION;

-}

-

-void CPDFXFA_App::GetVersion(CFX_WideString& wsVersion) {

-  wsVersion = JS_STR_VIEWERVERSION_XFA;

-}

-

-void CPDFXFA_App::Beep(FX_DWORD dwType) {

-  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);

-  if (pEnv) {

-    pEnv->JS_appBeep(dwType);

-  }

-}

-

-int32_t CPDFXFA_App::MsgBox(const CFX_WideStringC& wsMessage,

-                            const CFX_WideStringC& wsTitle,

-                            FX_DWORD dwIconType,

-                            FX_DWORD dwButtonType) {

-  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);

-  if (!pEnv)

-    return -1;

-

-  FX_DWORD iconType = 0;

-  int iButtonType = 0;

-  switch (dwIconType) {

-    case XFA_MBICON_Error:

-      iconType |= 0;

-      break;

-    case XFA_MBICON_Warning:

-      iconType |= 1;

-      break;

-    case XFA_MBICON_Question:

-      iconType |= 2;

-      break;

-    case XFA_MBICON_Status:

-      iconType |= 3;

-      break;

-  }

-  switch (dwButtonType) {

-    case XFA_MB_OK:

-      iButtonType |= 0;

-      break;

-    case XFA_MB_OKCancel:

-      iButtonType |= 1;

-      break;

-    case XFA_MB_YesNo:

-      iButtonType |= 2;

-      break;

-    case XFA_MB_YesNoCancel:

-      iButtonType |= 3;

-      break;

-  }

-  int32_t iRet = pEnv->JS_appAlert(wsMessage.GetPtr(), wsTitle.GetPtr(),

-                                   iButtonType, iconType);

-  switch (iRet) {

-    case 1:

-      return XFA_IDOK;

-    case 2:

-      return XFA_IDCancel;

-    case 3:

-      return XFA_IDNo;

-    case 4:

-      return XFA_IDYes;

-  }

-  return XFA_IDYes;

-}

-

-void CPDFXFA_App::Response(CFX_WideString& wsAnswer,

-                           const CFX_WideStringC& wsQuestion,

-                           const CFX_WideStringC& wsTitle,

-                           const CFX_WideStringC& wsDefaultAnswer,

-                           FX_BOOL bMark) {

-  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);

-  if (pEnv) {

-    int nLength = 2048;

-    char* pBuff = new char[nLength];

-    nLength = pEnv->JS_appResponse(wsQuestion.GetPtr(), wsTitle.GetPtr(),

-                                   wsDefaultAnswer.GetPtr(), NULL, bMark, pBuff,

-                                   nLength);

-    if (nLength > 0) {

-      nLength = nLength > 2046 ? 2046 : nLength;

-      pBuff[nLength] = 0;

-      pBuff[nLength + 1] = 0;

-      wsAnswer = CFX_WideString::FromUTF16LE(

-          reinterpret_cast<const unsigned short*>(pBuff),

-          nLength / sizeof(unsigned short));

-    }

-    delete[] pBuff;

-  }

-}

-

-int32_t CPDFXFA_App::GetCurDocumentInBatch() {

-  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);

-  if (pEnv) {

-    return pEnv->FFI_GetCurDocument();

-  }

-  return 0;

-}

-

-int32_t CPDFXFA_App::GetDocumentCountInBatch() {

-  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);

-  if (pEnv) {

-    return pEnv->FFI_GetDocumentCount();

-  }

-

-  return 0;

-}

-

-IFX_FileRead* CPDFXFA_App::DownloadURL(const CFX_WideStringC& wsURL) {

-  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);

-  if (pEnv) {

-    return pEnv->FFI_DownloadFromURL(wsURL.GetPtr());

-  }

-  return NULL;

-}

-

-FX_BOOL CPDFXFA_App::PostRequestURL(const CFX_WideStringC& wsURL,

-                                    const CFX_WideStringC& wsData,

-                                    const CFX_WideStringC& wsContentType,

-                                    const CFX_WideStringC& wsEncode,

-                                    const CFX_WideStringC& wsHeader,

-                                    CFX_WideString& wsResponse) {

-  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);

-  if (pEnv) {

-    wsResponse = pEnv->FFI_PostRequestURL(wsURL.GetPtr(), wsData.GetPtr(),

-                                          wsContentType.GetPtr(),

-                                          wsEncode.GetPtr(), wsHeader.GetPtr());

-    return TRUE;

-  }

-  return FALSE;

-}

-

-FX_BOOL CPDFXFA_App::PutRequestURL(const CFX_WideStringC& wsURL,

-                                   const CFX_WideStringC& wsData,

-                                   const CFX_WideStringC& wsEncode) {

-  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);

-  if (pEnv) {

-    return pEnv->FFI_PutRequestURL(wsURL.GetPtr(), wsData.GetPtr(),

-                                   wsEncode.GetPtr());

-  }

-  return FALSE;

-}

-

-void CPDFXFA_App::LoadString(int32_t iStringID, CFX_WideString& wsString) {

-  switch (iStringID) {

-    case XFA_IDS_ValidateFailed:

-      wsString = L"%s validate failed";

-      return;

-    case XFA_IDS_CalcOverride:

-      wsString = L"Calculate Override";

-      return;

-    case XFA_IDS_ModifyField:

-      wsString = L"Are you sure you want to modify this field?";

-      return;

-    case XFA_IDS_NotModifyField:

-      wsString = L"You are not allowed to modify this field.";

-      return;

-    case XFA_IDS_AppName:

-      wsString = L"Foxit";

-      return;

-    case XFA_IDS_ImageFilter:

-      wsString =

-          L"Image "

-          L"Files(*.bmp;*.jpg;*.png;*.gif;*.tif)|*.bmp;*.jpg;*.png;*.gif;*.tif|"

-          L"All Files(*.*)|*.*||";

-      return;

-    case XFA_IDS_UNKNOW_CATCHED:

-      wsString = L"unknown error is catched!";

-      return;

-    case XFA_IDS_Unable_TO_SET:

-      wsString = L"Unable to set ";

-      return;

-    case XFA_IDS_VALUE_EXCALMATORY:

-      wsString = L" value!";

-      return;

-    case XFA_IDS_INVALID_ENUM_VALUE:

-      wsString = L"Invalid enumerated value: ";

-      return;

-    case XFA_IDS_UNSUPPORT_METHOD:

-      wsString = L"unsupport %s method.";

-      return;

-    case XFA_IDS_UNSUPPORT_PROP:

-      wsString = L"unsupport %s property.";

-      return;

-    case XFA_IDS_INVAlID_PROP_SET:

-      wsString = L"Invalid property set operation;";

-      return;

-    case XFA_IDS_NOT_DEFAUL_VALUE:

-      wsString = L" doesn't have a default property";

-      return;

-    case XFA_IDS_UNABLE_SET_LANGUAGE:

-      wsString = L"Unable to set language value!";

-      return;

-    case XFA_IDS_UNABLE_SET_NUMPAGES:

-      wsString = L"Unable to set numPages value!";

-      return;

-    case XFA_IDS_UNABLE_SET_PLATFORM:

-      wsString = L"Unable to set platform value!";

-      return;

-    case XFA_IDS_UNABLE_SET_VALIDATIONENABLE:

-      wsString = L"Unable to set validationsEnabled value!";

-      return;

-    case XFA_IDS_UNABLE_SET_VARIATION:

-      wsString = L"Unable to set variation value!";

-      return;

-    case XFA_IDS_UNABLE_SET_VERSION:

-      wsString = L"Unable to set version value!";

-      return;

-    case XFA_IDS_UNABLE_SET_READY:

-      wsString = L"Unable to set ready value!";

-      return;

-    case XFA_IDS_NUMBER_OF_OCCUR:

-      wsString =

-          L"The element [%s] has violated its allowable number of occurrences";

-      return;

-    case XFA_IDS_UNABLE_SET_CLASS_NAME:

-      wsString = L"Unable to set className value!";

-      return;

-    case XFA_IDS_UNABLE_SET_LENGTH_VALUE:

-      wsString = L"Unable to set length value!";

-      return;

-    case XFA_IDS_UNSUPPORT_CHAR:

-      wsString = L"unsupported char '%c'";

-      return;

-    case XFA_IDS_BAD_SUFFIX:

-      wsString = L"bad suffix on number";

-      return;

-    case XFA_IDS_EXPECTED_IDENT:

-      wsString = L"expected identifier instead of '%s'";

-      return;

-    case XFA_IDS_EXPECTED_STRING:

-      wsString = L"expected '%s' instead of '%s'";

-      return;

-    case XFA_IDS_INVALIDATE_CHAR:

-      wsString = L"invalidate char '%c'";

-      return;

-    case XFA_IDS_REDEFINITION:

-      wsString = L"'%s' redefinition ";

-      return;

-    case XFA_IDS_INVALIDATE_TOKEN:

-      wsString = L"invalidate token '%s'";

-      return;

-    case XFA_IDS_INVALIDATE_EXPRESSION:

-      wsString = L"invalidate expression '%s'";

-      return;

-    case XFA_IDS_UNDEFINE_IDENTIFIER:

-      wsString = L"undefined identifier '%s'";

-      return;

-    case XFA_IDS_INVALIDATE_LEFTVALUE:

-      wsString = L"invalidate left-value '%s'";

-      return;

-    case XFA_IDS_COMPILER_ERROR:

-      wsString = L"compiler error";

-      return;

-    case XFA_IDS_CANNOT_MODIFY_VALUE:

-      wsString = L"can't modify the '%s' value";

-      return;

-    case XFA_IDS_ERROR_PARAMETERS:

-      wsString = L"function '%s' has not %d parameters";

-      return;

-    case XFA_IDS_EXPECT_ENDIF:

-      wsString = L"expected 'endif' instead of '%s'";

-      return;

-    case XFA_IDS_UNEXPECTED_EXPRESSION:

-      wsString = L"unexpected expression '%s'";

-      return;

-    case XFA_IDS_CONDITION_IS_NULL:

-      wsString = L"condition is null";

-      return;

-    case XFA_IDS_ILLEGALBREAK:

-      wsString = L"illegal break";

-      return;

-    case XFA_IDS_ILLEGALCONTINUE:

-      wsString = L"illegal continue";

-      return;

-    case XFA_IDS_EXPECTED_OPERATOR:

-      wsString = L"expected operator '%s' instead of '%s'";

-      return;

-    case XFA_IDS_DIVIDE_ZERO:

-      wsString = L"divide by zero";

-      return;

-    case XFA_IDS_CANNOT_COVERT_OBJECT:

-      wsString = L"%s.%s can not covert to object";

-      return;

-    case XFA_IDS_NOT_FOUND_CONTAINER:

-      wsString = L"can not found container '%s'";

-      return;

-    case XFA_IDS_NOT_FOUND_PROPERTY:

-      wsString = L"can not found property '%s'";

-      return;

-    case XFA_IDS_NOT_FOUND_METHOD:

-      wsString = L"can not found method '%s'";

-      return;

-    case XFA_IDS_NOT_FOUND_CONST:

-      wsString = L"can not found const '%s'";

-      return;

-    case XFA_IDS_NOT_ASSIGN_OBJECT:

-      wsString = L"can not direct assign value to object";

-      return;

-    case XFA_IDS_IVALIDATE_INSTRUCTION:

-      wsString = L"invalidate instruction";

-      return;

-    case XFA_IDS_EXPECT_NUMBER:

-      wsString = L"expected number instead of '%s'";

-      return;

-    case XFA_IDS_VALIDATE_OUT_ARRAY:

-      wsString = L"validate access index '%s' out of array";

-      return;

-    case XFA_IDS_CANNOT_ASSIGN_IDENT:

-      wsString = L"can not assign to %s";

-      return;

-    case XFA_IDS_NOT_FOUNT_FUNCTION:

-      wsString = L"can not found '%s' function";

-      return;

-    case XFA_IDS_NOT_ARRAY:

-      wsString = L"'%s' doesn't an array";

-      return;

-    case XFA_IDS_OUT_ARRAY:

-      wsString = L"out of range of '%s' array";

-      return;

-    case XFA_IDS_NOT_SUPPORT_CALC:

-      wsString = L"'%s' operator can not support array calculate";

-      return;

-    case XFA_IDS_ARGUMENT_NOT_ARRAY:

-      wsString = L"'%s' function's %d argument can not be array";

-      return;

-    case XFA_IDS_ARGUMENT_EXPECT_CONTAINER:

-      wsString = L"'%s' argument expected a container";

-      return;

-    case XFA_IDS_ACCESS_PROPERTY_IN_NOT_OBJECT:

-      wsString =

-          L"an attempt was made to reference property '%s' of a non-object in "

-          L"SOM expression %s";

-      return;

-    case XFA_IDS_FUNCTION_IS_BUILDIN:

-      wsString = L"function '%s' is buildin";

-      return;

-    case XFA_IDS_ERROR_MSG:

-      wsString = L"%s : %s";

-      return;

-    case XFA_IDS_INDEX_OUT_OF_BOUNDS:

-      wsString = L"Index value is out of bounds";

-      return;

-    case XFA_IDS_INCORRECT_NUMBER_OF_METHOD:

-      wsString = L"Incorrect number of parameters calling method '%s'";

-      return;

-    case XFA_IDS_ARGUMENT_MISMATCH:

-      wsString = L"Argument mismatch in property or function argument";

-      return;

-    case XFA_IDS_INVALID_ENUMERATE:

-      wsString = L"Invalid enumerated value: %s";

-      return;

-    case XFA_IDS_INVALID_APPEND:

-      wsString =

-          L"Invalid append operation: %s cannot have a child element of %s";

-      return;

-    case XFA_IDS_SOM_EXPECTED_LIST:

-      wsString =

-          L"SOM expression returned list when single result was expected";

-      return;

-    case XFA_IDS_NOT_HAVE_PROPERTY:

-      wsString = L"'%s' doesn't have property '%s'";

-      return;

-    case XFA_IDS_INVALID_NODE_TYPE:

-      wsString = L"Invalid node type : '%s'";

-      return;

-    case XFA_IDS_VIOLATE_BOUNDARY:

-      wsString =

-          L"The element [%s] has violated its allowable number of occurrences";

-      return;

-    case XFA_IDS_SERVER_DENY:

-      wsString = L"Server does not permit";

-      return;

-    case XFA_IDS_ValidateLimit:

-      wsString = FX_WSTRC(

-          L"Message limit exceeded. Remaining %d validation errors not "

-          L"reported.");

-      return;

-    case XFA_IDS_ValidateNullWarning:

-      wsString = FX_WSTRC(

-          L"%s cannot be left blank. To ignore validations for %s, click "

-          L"Ignore.");

-      return;

-    case XFA_IDS_ValidateNullError:

-      wsString = FX_WSTRC(L"%s cannot be left blank.");

-      return;

-    case XFA_IDS_ValidateWarning:

-      wsString = FX_WSTRC(

-          L"The value you entered for %s is invalid. To ignore validations for "

-          L"%s, click Ignore.");

-      return;

-    case XFA_IDS_ValidateError:

-      wsString = FX_WSTRC(L"The value you entered for %s is invalid.");

-      return;

-  }

-}

-

-FX_BOOL CPDFXFA_App::ShowFileDialog(const CFX_WideStringC& wsTitle,

-                                    const CFX_WideStringC& wsFilter,

-                                    CFX_WideStringArray& wsPathArr,

-                                    FX_BOOL bOpen) {

-  return FALSE;

-}

-

-IFWL_AdapterTimerMgr* CPDFXFA_App::GetTimerMgr() {

-  CXFA_FWLAdapterTimerMgr* pAdapter = NULL;

-  CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);

-  if (pEnv)

-    pAdapter = new CXFA_FWLAdapterTimerMgr(pEnv);

-  return pAdapter;

-}

diff --git a/fpdfsdk/src/fpdfxfa/fpdfxfa_doc.cpp b/fpdfsdk/src/fpdfxfa/fpdfxfa_doc.cpp
deleted file mode 100644
index 92d16b6..0000000
--- a/fpdfsdk/src/fpdfxfa/fpdfxfa_doc.cpp
+++ /dev/null
@@ -1,1261 +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

-

-#include "fpdfsdk/include/fsdk_define.h"

-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h"

-#include "fpdfsdk/include/fsdk_mgr.h"

-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_app.h"

-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h"

-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_page.h"

-#include "fpdfsdk/include/javascript/IJavaScript.h"

-#include "public/fpdf_formfill.h"

-

-#define IDS_XFA_Validate_Input                                          \

-  "At least one required field was empty. Please fill in the required " \

-  "fields\r\n(highlighted) before continuing."

-

-// submit

-#define FXFA_CONFIG 0x00000001

-#define FXFA_TEMPLATE 0x00000010

-#define FXFA_LOCALESET 0x00000100

-#define FXFA_DATASETS 0x00001000

-#define FXFA_XMPMETA 0x00010000

-#define FXFA_XFDF 0x00100000

-#define FXFA_FORM 0x01000000

-#define FXFA_PDF 0x10000000

-

-#ifndef _WIN32

-extern void SetLastError(int err);

-

-extern int GetLastError();

-#endif

-

-CPDFXFA_Document::CPDFXFA_Document(CPDF_Document* pPDFDoc,

-                                   CPDFXFA_App* pProvider)

-    : m_iDocType(DOCTYPE_PDF),

-      m_pPDFDoc(pPDFDoc),

-      m_pSDKDoc(nullptr),

-      m_pXFADoc(nullptr),

-      m_pXFADocView(nullptr),

-      m_pApp(pProvider),

-      m_pJSContext(nullptr) {

-}

-

-CPDFXFA_Document::~CPDFXFA_Document() {

-  if (m_pJSContext && m_pSDKDoc && m_pSDKDoc->GetEnv())

-    m_pSDKDoc->GetEnv()->GetJSRuntime()->ReleaseContext(m_pJSContext);

-

-  delete m_pSDKDoc;

-

-  if (m_pPDFDoc) {

-    CPDF_Parser* pParser = m_pPDFDoc->GetParser();

-    if (pParser)

-      delete pParser;

-    else

-      delete m_pPDFDoc;

-  }

-  if (m_pXFADoc) {

-    IXFA_App* pApp = m_pApp->GetXFAApp();

-    if (pApp) {

-      IXFA_DocHandler* pDocHandler = pApp->GetDocHandler();

-      if (pDocHandler) {

-        CloseXFADoc(pDocHandler);

-      }

-    }

-    delete m_pXFADoc;

-  }

-}

-

-FX_BOOL CPDFXFA_Document::LoadXFADoc() {

-  if (!m_pPDFDoc)

-    return FALSE;

-

-  m_XFAPageList.RemoveAll();

-

-  IXFA_App* pApp = m_pApp->GetXFAApp();

-  if (!pApp)

-    return FALSE;

-

-  m_pXFADoc = pApp->CreateDoc(this, m_pPDFDoc);

-  if (!m_pXFADoc) {

-    SetLastError(FPDF_ERR_XFALOAD);

-    return FALSE;

-  }

-

-  IXFA_DocHandler* pDocHandler = pApp->GetDocHandler();

-  if (!pDocHandler) {

-    SetLastError(FPDF_ERR_XFALOAD);

-    return FALSE;

-  }

-

-  pDocHandler->StartLoad(m_pXFADoc);

-  int iStatus = pDocHandler->DoLoad(m_pXFADoc, NULL);

-  if (iStatus != XFA_PARSESTATUS_Done) {

-    CloseXFADoc(pDocHandler);

-    SetLastError(FPDF_ERR_XFALOAD);

-    return FALSE;

-  }

-  pDocHandler->StopLoad(m_pXFADoc);

-  pDocHandler->SetJSERuntime(m_pXFADoc, m_pApp->GetJSERuntime());

-

-  if (pDocHandler->GetDocType(m_pXFADoc) == XFA_DOCTYPE_Dynamic)

-    m_iDocType = DOCTYPE_DYNAMIC_XFA;

-  else

-    m_iDocType = DOCTYPE_STATIC_XFA;

-

-  m_pXFADocView = pDocHandler->CreateDocView(m_pXFADoc, XFA_DOCVIEW_View);

-  if (m_pXFADocView->StartLayout() < 0) {

-    CloseXFADoc(pDocHandler);

-    SetLastError(FPDF_ERR_XFALAYOUT);

-    return FALSE;

-  }

-

-  m_pXFADocView->DoLayout(NULL);

-  m_pXFADocView->StopLayout();

-  return TRUE;

-}

-

-int CPDFXFA_Document::GetPageCount() {

-  if (!m_pPDFDoc && !m_pXFADoc)

-    return 0;

-

-  switch (m_iDocType) {

-    case DOCTYPE_PDF:

-    case DOCTYPE_STATIC_XFA:

-      if (m_pPDFDoc)

-        return m_pPDFDoc->GetPageCount();

-    case DOCTYPE_DYNAMIC_XFA:

-      if (m_pXFADoc)

-        return m_pXFADocView->CountPageViews();

-    default:

-      return 0;

-  }

-

-  return 0;

-}

-

-CPDFXFA_Page* CPDFXFA_Document::GetPage(int page_index) {

-  if (!m_pPDFDoc && !m_pXFADoc)

-    return NULL;

-

-  CPDFXFA_Page* pPage = NULL;

-  if (m_XFAPageList.GetSize()) {

-    pPage = m_XFAPageList.GetAt(page_index);

-    if (pPage)

-      pPage->AddRef();

-  } else {

-    m_XFAPageList.SetSize(GetPageCount());

-  }

-

-  if (!pPage) {

-    pPage = new CPDFXFA_Page(this, page_index);

-    FX_BOOL bRet = pPage->LoadPage();

-    if (!bRet) {

-      delete pPage;

-      return NULL;

-    }

-

-    m_XFAPageList.SetAt(page_index, pPage);

-  }

-

-  return pPage;

-}

-

-CPDFXFA_Page* CPDFXFA_Document::GetPage(IXFA_PageView* pPage) {

-  if (!pPage)

-    return NULL;

-

-  if (!m_pXFADoc)

-    return NULL;

-

-  if (m_iDocType != DOCTYPE_DYNAMIC_XFA)

-    return NULL;

-

-  int nSize = m_XFAPageList.GetSize();

-  for (int i = 0; i < nSize; i++) {

-    CPDFXFA_Page* pTempPage = m_XFAPageList.GetAt(i);

-    if (!pTempPage)

-      continue;

-    if (pTempPage->GetXFAPageView() && pTempPage->GetXFAPageView() == pPage)

-      return pTempPage;

-  }

-

-  return NULL;

-}

-

-void CPDFXFA_Document::RemovePage(CPDFXFA_Page* page) {

-  m_XFAPageList.SetAt(page->GetPageIndex(), NULL);

-}

-

-CPDFSDK_Document* CPDFXFA_Document::GetSDKDocument(

-    CPDFDoc_Environment* pFormFillEnv) {

-  if (!m_pSDKDoc && pFormFillEnv)

-    m_pSDKDoc = new CPDFSDK_Document(this, pFormFillEnv);

-  return m_pSDKDoc;

-}

-

-void CPDFXFA_Document::FXRect2PDFRect(const CFX_RectF& fxRectF,

-                                      CPDF_Rect& pdfRect) {

-  pdfRect.left = fxRectF.left;

-  pdfRect.top = fxRectF.bottom();

-  pdfRect.right = fxRectF.right();

-  pdfRect.bottom = fxRectF.top;

-}

-

-void CPDFXFA_Document::SetChangeMark(IXFA_Doc* hDoc) {

-  if (hDoc == m_pXFADoc && m_pSDKDoc) {

-    m_pSDKDoc->SetChangeMark();

-  }

-}

-

-FX_BOOL CPDFXFA_Document::GetChangeMark(IXFA_Doc* hDoc) {

-  if (hDoc == m_pXFADoc && m_pSDKDoc)

-    return m_pSDKDoc->GetChangeMark();

-  return FALSE;

-}

-

-void CPDFXFA_Document::InvalidateRect(IXFA_PageView* pPageView,

-                                      const CFX_RectF& rt,

-                                      FX_DWORD dwFlags /* = 0 */) {

-  if (!m_pXFADoc || !m_pSDKDoc)

-    return;

-

-  if (m_iDocType != DOCTYPE_DYNAMIC_XFA)

-    return;

-

-  CPDF_Rect rcPage;

-  FXRect2PDFRect(rt, rcPage);

-

-  CPDFXFA_Page* pPage = GetPage(pPageView);

-

-  if (pPage == NULL)

-    return;

-

-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();

-  if (!pEnv)

-    return;

-

-  pEnv->FFI_Invalidate((FPDF_PAGE)pPage, rcPage.left, rcPage.bottom,

-                       rcPage.right, rcPage.top);

-}

-

-void CPDFXFA_Document::InvalidateRect(IXFA_Widget* hWidget,

-                                      FX_DWORD dwFlags /* = 0 */) {

-  if (!hWidget)

-    return;

-

-  if (!m_pXFADoc || !m_pSDKDoc || !m_pXFADocView)

-    return;

-

-  if (m_iDocType != DOCTYPE_DYNAMIC_XFA)

-    return;

-

-  IXFA_WidgetHandler* pWidgetHandler = m_pXFADocView->GetWidgetHandler();

-  if (!pWidgetHandler)

-    return;

-

-  IXFA_PageView* pPageView = pWidgetHandler->GetPageView(hWidget);

-  if (!pPageView)

-    return;

-

-  CFX_RectF rect;

-  pWidgetHandler->GetRect(hWidget, rect);

-  InvalidateRect(pPageView, rect, dwFlags);

-}

-

-void CPDFXFA_Document::DisplayCaret(IXFA_Widget* hWidget,

-                                    FX_BOOL bVisible,

-                                    const CFX_RectF* pRtAnchor) {

-  if (!hWidget || pRtAnchor == NULL)

-    return;

-

-  if (!m_pXFADoc || !m_pSDKDoc || !m_pXFADocView)

-    return;

-

-  if (m_iDocType != DOCTYPE_DYNAMIC_XFA)

-    return;

-

-  IXFA_WidgetHandler* pWidgetHandler = m_pXFADocView->GetWidgetHandler();

-  if (!pWidgetHandler)

-    return;

-

-  IXFA_PageView* pPageView = pWidgetHandler->GetPageView(hWidget);

-  if (!pPageView)

-    return;

-

-  CPDFXFA_Page* pPage = GetPage(pPageView);

-

-  if (pPage == NULL)

-    return;

-

-  CPDF_Rect rcCaret;

-  FXRect2PDFRect(*pRtAnchor, rcCaret);

-

-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();

-  if (!pEnv)

-    return;

-

-  pEnv->FFI_DisplayCaret((FPDF_PAGE)pPage, bVisible, rcCaret.left, rcCaret.top,

-                         rcCaret.right, rcCaret.bottom);

-}

-

-FX_BOOL CPDFXFA_Document::GetPopupPos(IXFA_Widget* hWidget,

-                                      FX_FLOAT fMinPopup,

-                                      FX_FLOAT fMaxPopup,

-                                      const CFX_RectF& rtAnchor,

-                                      CFX_RectF& rtPopup) {

-  if (NULL == hWidget) {

-    return FALSE;

-  }

-  IXFA_PageView* pXFAPageView =

-      m_pXFADocView->GetWidgetHandler()->GetPageView(hWidget);

-  if (NULL == pXFAPageView) {

-    return FALSE;

-  }

-  CPDFXFA_Page* pPage = GetPage(pXFAPageView);

-  if (pPage == NULL)

-    return FALSE;

-

-  CXFA_WidgetAcc* pWidgetAcc =

-      m_pXFADocView->GetWidgetHandler()->GetDataAcc(hWidget);

-

-  int nRotate = 0;

-#ifdef PDF_ENABLE_XFA

-  nRotate = pWidgetAcc->GetRotate();

-#endif

-

-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();

-  if (pEnv == NULL)

-    return FALSE;

-  FS_RECTF pageViewRect;

-  pEnv->FFI_GetPageViewRect(pPage, pageViewRect);

-

-  CPDF_Rect rcAnchor;

-

-  rcAnchor.left = rtAnchor.left;

-  rcAnchor.top = rtAnchor.bottom();

-  rcAnchor.right = rtAnchor.right();

-  rcAnchor.bottom = rtAnchor.top;

-

-  int t1, t2, t;

-  FX_DWORD dwPos;

-  FX_FLOAT fPoupHeight;

-  switch (nRotate) {

-    case 90: {

-      t1 = (int)(pageViewRect.right - rcAnchor.right);

-      t2 = (int)(rcAnchor.left - pageViewRect.left);

-      if (rcAnchor.bottom < pageViewRect.bottom) {

-        rtPopup.left += rcAnchor.bottom - pageViewRect.bottom;

-      }

-

-      break;

-    }

-

-    case 180: {

-      t2 = (int)(pageViewRect.top - rcAnchor.top);

-      t1 = (int)(rcAnchor.bottom - pageViewRect.bottom);

-      if (rcAnchor.left < pageViewRect.left) {

-        rtPopup.left += rcAnchor.left - pageViewRect.left;

-      }

-      break;

-    }

-    case 270: {

-      t1 = (int)(rcAnchor.left - pageViewRect.left);

-      t2 = (int)(pageViewRect.right - rcAnchor.right);

-

-      if (rcAnchor.top > pageViewRect.top) {

-        rtPopup.left -= rcAnchor.top - pageViewRect.top;

-      }

-      break;

-    }

-    case 0:

-    default: {

-      t1 = (int)(pageViewRect.top - rcAnchor.top);

-      t2 = (int)(rcAnchor.bottom - pageViewRect.bottom);

-      if (rcAnchor.right > pageViewRect.right) {

-        rtPopup.left -= rcAnchor.right - pageViewRect.right;

-      }

-      break;

-    }

-  }

-

-  if (t1 <= 0 && t2 <= 0) {

-    return FALSE;

-  }

-  if (t1 <= 0) {

-    t = t2;

-    dwPos = 1;

-  } else if (t2 <= 0) {

-    t = t1;

-    dwPos = 0;

-  } else if (t1 > t2) {

-    t = t1;

-    dwPos = 0;

-  } else {

-    t = t2;

-    dwPos = 1;

-  }

-  if (t < fMinPopup) {

-    fPoupHeight = fMinPopup;

-  } else if (t > fMaxPopup) {

-    fPoupHeight = fMaxPopup;

-  } else {

-    fPoupHeight = (FX_FLOAT)t;

-  }

-

-  switch (nRotate) {

-    case 0:

-    case 180: {

-      if (dwPos == 0) {

-        rtPopup.top = rtAnchor.height;

-        rtPopup.height = fPoupHeight;

-      } else {

-        rtPopup.top = -fPoupHeight;

-        rtPopup.height = fPoupHeight;

-      }

-      break;

-    }

-    case 90:

-    case 270: {

-      if (dwPos == 0) {

-        rtPopup.top = rtAnchor.width;

-        rtPopup.height = fPoupHeight;

-      } else {

-        rtPopup.top = -fPoupHeight;

-        rtPopup.height = fPoupHeight;

-      }

-      break;

-    }

-    default:

-      break;

-  }

-

-  return TRUE;

-}

-

-FX_BOOL CPDFXFA_Document::PopupMenu(IXFA_Widget* hWidget,

-                                    CFX_PointF ptPopup,

-                                    const CFX_RectF* pRectExclude) {

-  if (NULL == hWidget) {

-    return FALSE;

-  }

-  IXFA_PageView* pXFAPageView =

-      m_pXFADocView->GetWidgetHandler()->GetPageView(hWidget);

-  if (pXFAPageView == NULL)

-    return FALSE;

-  CPDFXFA_Page* pPage = GetPage(pXFAPageView);

-

-  if (pPage == NULL)

-    return FALSE;

-

-  int menuFlag = 0;

-

-  IXFA_MenuHandler* pXFAMenuHander = m_pApp->GetXFAApp()->GetMenuHandler();

-  if (pXFAMenuHander->CanUndo(hWidget))

-    menuFlag |= FXFA_MEMU_UNDO;

-  if (pXFAMenuHander->CanRedo(hWidget))

-    menuFlag |= FXFA_MEMU_REDO;

-  if (pXFAMenuHander->CanPaste(hWidget))

-    menuFlag |= FXFA_MEMU_PASTE;

-  if (pXFAMenuHander->CanCopy(hWidget))

-    menuFlag |= FXFA_MEMU_COPY;

-  if (pXFAMenuHander->CanCut(hWidget))

-    menuFlag |= FXFA_MEMU_CUT;

-  if (pXFAMenuHander->CanSelectAll(hWidget))

-    menuFlag |= FXFA_MEMU_SELECTALL;

-

-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();

-  if (pEnv == NULL)

-    return FALSE;

-

-  return pEnv->FFI_PopupMenu(pPage, hWidget, menuFlag, ptPopup, NULL);

-}

-

-void CPDFXFA_Document::PageViewEvent(IXFA_PageView* pPageView,

-                                     FX_DWORD dwFlags) {

-}

-

-void CPDFXFA_Document::WidgetEvent(IXFA_Widget* hWidget,

-                                   CXFA_WidgetAcc* pWidgetData,

-                                   FX_DWORD dwEvent,

-                                   void* pParam,

-                                   void* pAdditional) {

-  if (m_iDocType != DOCTYPE_DYNAMIC_XFA || !hWidget)

-    return;

-

-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();

-  if (!pEnv)

-    return;

-

-  IXFA_PageView* pPageView =

-      m_pXFADocView->GetWidgetHandler()->GetPageView(hWidget);

-  if (pPageView == NULL)

-    return;

-

-  CPDFXFA_Page* pXFAPage = GetPage(pPageView);

-  if (pXFAPage == NULL)

-    return;

-

-  CPDFSDK_PageView* pSdkPageView = m_pSDKDoc->GetPageView(pXFAPage);

-  if (dwEvent == XFA_WIDGETEVENT_PostAdded) {

-    pSdkPageView->AddAnnot(hWidget);

-

-  } else if (dwEvent == XFA_WIDGETEVENT_PreRemoved) {

-    CPDFSDK_Annot* pAnnot = pSdkPageView->GetAnnotByXFAWidget(hWidget);

-    if (pAnnot) {

-      pSdkPageView->DeleteAnnot(pAnnot);

-    }

-  }

-}

-

-int32_t CPDFXFA_Document::CountPages(IXFA_Doc* hDoc) {

-  if (hDoc == m_pXFADoc && m_pSDKDoc) {

-    return GetPageCount();

-  }

-  return 0;

-}

-int32_t CPDFXFA_Document::GetCurrentPage(IXFA_Doc* hDoc) {

-  if (hDoc != m_pXFADoc || !m_pSDKDoc)

-    return -1;

-  if (m_iDocType != DOCTYPE_DYNAMIC_XFA)

-    return -1;

-

-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();

-  if (pEnv == NULL)

-    return -1;

-

-  return pEnv->FFI_GetCurrentPageIndex(this);

-}

-void CPDFXFA_Document::SetCurrentPage(IXFA_Doc* hDoc, int32_t iCurPage) {

-  if (hDoc != m_pXFADoc || !m_pSDKDoc)

-    return;

-  if (m_iDocType != DOCTYPE_DYNAMIC_XFA)

-    return;

-

-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();

-  if (pEnv == NULL)

-    return;

-

-  pEnv->FFI_SetCurrentPage(this, iCurPage);

-}

-FX_BOOL CPDFXFA_Document::IsCalculationsEnabled(IXFA_Doc* hDoc) {

-  if (hDoc != m_pXFADoc || !m_pSDKDoc)

-    return FALSE;

-  if (m_pSDKDoc->GetInterForm())

-    return m_pSDKDoc->GetInterForm()->IsXfaCalculateEnabled();

-

-  return FALSE;

-}

-void CPDFXFA_Document::SetCalculationsEnabled(IXFA_Doc* hDoc,

-                                              FX_BOOL bEnabled) {

-  if (hDoc != m_pXFADoc || !m_pSDKDoc)

-    return;

-  if (m_pSDKDoc->GetInterForm())

-    m_pSDKDoc->GetInterForm()->XfaEnableCalculate(bEnabled);

-}

-

-void CPDFXFA_Document::GetTitle(IXFA_Doc* hDoc, CFX_WideString& wsTitle) {

-  if (hDoc != m_pXFADoc)

-    return;

-  if (m_pPDFDoc == NULL)

-    return;

-  CPDF_Dictionary* pInfoDict = m_pPDFDoc->GetInfo();

-

-  if (pInfoDict == NULL)

-    return;

-

-  CFX_ByteString csTitle = pInfoDict->GetString("Title");

-  wsTitle = wsTitle.FromLocal(csTitle.GetBuffer(csTitle.GetLength()));

-  csTitle.ReleaseBuffer(csTitle.GetLength());

-}

-void CPDFXFA_Document::SetTitle(IXFA_Doc* hDoc,

-                                const CFX_WideStringC& wsTitle) {

-  if (hDoc != m_pXFADoc)

-    return;

-  if (m_pPDFDoc == NULL)

-    return;

-  CPDF_Dictionary* pInfoDict = m_pPDFDoc->GetInfo();

-

-  if (pInfoDict == NULL)

-    return;

-  pInfoDict->SetAt("Title", new CPDF_String(wsTitle));

-}

-void CPDFXFA_Document::ExportData(IXFA_Doc* hDoc,

-                                  const CFX_WideStringC& wsFilePath,

-                                  FX_BOOL bXDP) {

-  if (hDoc != m_pXFADoc)

-    return;

-  if (m_iDocType != DOCTYPE_DYNAMIC_XFA && m_iDocType != DOCTYPE_STATIC_XFA)

-    return;

-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();

-  if (pEnv == NULL)

-    return;

-  int fileType = bXDP ? FXFA_SAVEAS_XDP : FXFA_SAVEAS_XML;

-  CFX_ByteString bs = CFX_WideString(wsFilePath).UTF16LE_Encode();

-

-  if (wsFilePath.IsEmpty()) {

-    if (!pEnv->GetFormFillInfo() ||

-        pEnv->GetFormFillInfo()->m_pJsPlatform == NULL)

-      return;

-    CFX_WideString filepath = pEnv->JS_fieldBrowse();

-    bs = filepath.UTF16LE_Encode();

-  }

-  int len = bs.GetLength() / sizeof(unsigned short);

-  FPDF_FILEHANDLER* pFileHandler = pEnv->FFI_OpenFile(

-      bXDP ? FXFA_SAVEAS_XDP : FXFA_SAVEAS_XML,

-      (FPDF_WIDESTRING)bs.GetBuffer(len * sizeof(unsigned short)), "wb");

-  bs.ReleaseBuffer(len * sizeof(unsigned short));

-

-  if (pFileHandler == NULL)

-    return;

-

-  CFPDF_FileStream fileWrite(pFileHandler);

-

-  IXFA_DocHandler* pXFADocHander = m_pApp->GetXFAApp()->GetDocHandler();

-  CFX_ByteString content;

-  if (fileType == FXFA_SAVEAS_XML) {

-    content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n";

-    fileWrite.WriteBlock((const FX_CHAR*)content, fileWrite.GetSize(),

-                         content.GetLength());

-    CFX_WideStringC data(L"data");

-    if (pXFADocHander->SavePackage(m_pXFADocView->GetDoc(), data, &fileWrite)) {

-      // TODO: Maybe report error.

-    }

-  } else if (fileType == FXFA_SAVEAS_XDP) {

-    if (m_pPDFDoc == NULL)

-      return;

-    CPDF_Dictionary* pRoot = m_pPDFDoc->GetRoot();

-    if (pRoot == NULL)

-      return;

-    CPDF_Dictionary* pAcroForm = pRoot->GetDict("AcroForm");

-    if (NULL == pAcroForm)

-      return;

-    CPDF_Object* pXFA = pAcroForm->GetElement("XFA");

-    if (pXFA == NULL)

-      return;

-    if (pXFA->GetType() != PDFOBJ_ARRAY)

-      return;

-    CPDF_Array* pArray = pXFA->GetArray();

-    if (NULL == pArray)

-      return;

-    int size = pArray->GetCount();

-    for (int i = 1; i < size; i += 2) {

-      CPDF_Object* pPDFObj = pArray->GetElement(i);

-      CPDF_Object* pPrePDFObj = pArray->GetElement(i - 1);

-      if (pPrePDFObj->GetType() != PDFOBJ_STRING)

-        continue;

-      if (pPDFObj->GetType() != PDFOBJ_REFERENCE)

-        continue;

-      CPDF_Object* pDirectObj = pPDFObj->GetDirect();

-      if (pDirectObj->GetType() != PDFOBJ_STREAM)

-        continue;

-      if (pPrePDFObj->GetString() == "form") {

-        CFX_WideStringC form(L"form");

-        pXFADocHander->SavePackage(m_pXFADocView->GetDoc(), form, &fileWrite);

-      } else if (pPrePDFObj->GetString() == "datasets") {

-        CFX_WideStringC datasets(L"datasets");

-        pXFADocHander->SavePackage(m_pXFADocView->GetDoc(), datasets,

-                                   &fileWrite);

-      } else {

-        if (i == size - 1) {

-          CFX_WideString wPath = CFX_WideString::FromUTF16LE(

-              (unsigned short*)(const FX_CHAR*)bs,

-              bs.GetLength() / sizeof(unsigned short));

-          CFX_ByteString bPath = wPath.UTF8Encode();

-          CFX_ByteString szFormat =

-              "\n<pdf href=\"%s\" xmlns=\"http://ns.adobe.com/xdp/pdf/\"/>";

-          content.Format(szFormat, (char*)(const FX_CHAR*)bPath);

-          fileWrite.WriteBlock((const FX_CHAR*)content, fileWrite.GetSize(),

-                               content.GetLength());

-        }

-

-        CPDF_Stream* pStream = (CPDF_Stream*)pDirectObj;

-        CPDF_StreamAcc* pAcc = new CPDF_StreamAcc;

-        pAcc->LoadAllData(pStream);

-        fileWrite.WriteBlock(pAcc->GetData(), fileWrite.GetSize(),

-                             pAcc->GetSize());

-        delete pAcc;

-      }

-    }

-  }

-  if (!fileWrite.Flush()) {

-    // TODO: Report error.

-  }

-}

-void CPDFXFA_Document::ImportData(IXFA_Doc* hDoc,

-                                  const CFX_WideStringC& wsFilePath) {

-  // TODO...

-}

-

-void CPDFXFA_Document::GotoURL(IXFA_Doc* hDoc,

-                               const CFX_WideStringC& bsURL,

-                               FX_BOOL bAppend) {

-  if (hDoc != m_pXFADoc)

-    return;

-

-  if (m_iDocType != DOCTYPE_DYNAMIC_XFA)

-    return;

-

-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();

-  if (pEnv == NULL)

-    return;

-

-  CFX_WideStringC str(bsURL.GetPtr());

-

-  pEnv->FFI_GotoURL(this, str, bAppend);

-}

-

-FX_BOOL CPDFXFA_Document::IsValidationsEnabled(IXFA_Doc* hDoc) {

-  if (hDoc != m_pXFADoc || !m_pSDKDoc)

-    return FALSE;

-  if (m_pSDKDoc->GetInterForm())

-    return m_pSDKDoc->GetInterForm()->IsXfaValidationsEnabled();

-

-  return TRUE;

-}

-void CPDFXFA_Document::SetValidationsEnabled(IXFA_Doc* hDoc, FX_BOOL bEnabled) {

-  if (hDoc != m_pXFADoc || !m_pSDKDoc)

-    return;

-  if (m_pSDKDoc->GetInterForm())

-    m_pSDKDoc->GetInterForm()->XfaSetValidationsEnabled(bEnabled);

-}

-void CPDFXFA_Document::SetFocusWidget(IXFA_Doc* hDoc, IXFA_Widget* hWidget) {

-  if (hDoc != m_pXFADoc)

-    return;

-

-  if (NULL == hWidget) {

-    m_pSDKDoc->SetFocusAnnot(NULL);

-    return;

-  }

-

-  int pageViewCount = m_pSDKDoc->GetPageViewCount();

-  for (int i = 0; i < pageViewCount; i++) {

-    CPDFSDK_PageView* pPageView = m_pSDKDoc->GetPageView(i);

-    if (pPageView == NULL)

-      continue;

-    CPDFSDK_Annot* pAnnot = pPageView->GetAnnotByXFAWidget(hWidget);

-    if (pAnnot) {

-      m_pSDKDoc->SetFocusAnnot(pAnnot);

-      break;

-    }

-  }

-}

-void CPDFXFA_Document::Print(IXFA_Doc* hDoc,

-                             int32_t nStartPage,

-                             int32_t nEndPage,

-                             FX_DWORD dwOptions) {

-  if (hDoc != m_pXFADoc)

-    return;

-

-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();

-  if (pEnv == NULL)

-    return;

-

-  if (!pEnv->GetFormFillInfo() ||

-      pEnv->GetFormFillInfo()->m_pJsPlatform == NULL)

-    return;

-  if (pEnv->GetFormFillInfo()->m_pJsPlatform->Doc_print == NULL)

-    return;

-  pEnv->GetFormFillInfo()->m_pJsPlatform->Doc_print(

-      pEnv->GetFormFillInfo()->m_pJsPlatform,

-      dwOptions & XFA_PRINTOPT_ShowDialog, nStartPage, nEndPage,

-      dwOptions & XFA_PRINTOPT_CanCancel, dwOptions & XFA_PRINTOPT_ShrinkPage,

-      dwOptions & XFA_PRINTOPT_AsImage, dwOptions & XFA_PRINTOPT_ReverseOrder,

-      dwOptions & XFA_PRINTOPT_PrintAnnot);

-}

-

-void CPDFXFA_Document::GetURL(IXFA_Doc* hDoc, CFX_WideString& wsDocURL) {

-  if (hDoc != m_pXFADoc)

-    return;

-

-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();

-  if (pEnv == NULL)

-    return;

-

-  pEnv->FFI_GetURL(this, wsDocURL);

-}

-

-FX_ARGB CPDFXFA_Document::GetHighlightColor(IXFA_Doc* hDoc) {

-  if (hDoc != m_pXFADoc)

-    return 0;

-  if (m_pSDKDoc) {

-    if (CPDFSDK_InterForm* pInterForm = m_pSDKDoc->GetInterForm()) {

-      FX_COLORREF color = pInterForm->GetHighlightColor(FPDF_FORMFIELD_XFA);

-      uint8_t alpha = pInterForm->GetHighlightAlpha();

-      FX_ARGB argb = ArgbEncode((int)alpha, color);

-      return argb;

-    }

-  }

-  return 0;

-}

-

-void CPDFXFA_Document::AddDoRecord(IXFA_Widget* hWidget) {

-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();

-  if (pEnv == NULL)

-    return;

-  return;

-  // pEnv->FFI_AddDoRecord(this, hWidget);

-}

-

-FX_BOOL CPDFXFA_Document::_NotifySubmit(FX_BOOL bPrevOrPost) {

-  if (bPrevOrPost)

-    return _OnBeforeNotifySumbit();

-  else

-    _OnAfterNotifySumbit();

-  return TRUE;

-}

-

-FX_BOOL CPDFXFA_Document::_OnBeforeNotifySumbit() {

-#ifdef PDF_ENABLE_XFA

-  if (m_iDocType != DOCTYPE_DYNAMIC_XFA && m_iDocType != DOCTYPE_STATIC_XFA)

-    return TRUE;

-  if (m_pXFADocView == NULL)

-    return TRUE;

-  IXFA_WidgetHandler* pWidgetHandler = m_pXFADocView->GetWidgetHandler();

-  if (pWidgetHandler == NULL)

-    return TRUE;

-  IXFA_WidgetAccIterator* pWidgetAccIterator =

-      m_pXFADocView->CreateWidgetAccIterator();

-  if (pWidgetAccIterator) {

-    CXFA_EventParam Param;

-    Param.m_eType = XFA_EVENT_PreSubmit;

-    CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext();

-    while (pWidgetAcc) {

-      pWidgetHandler->ProcessEvent(pWidgetAcc, &Param);

-      pWidgetAcc = pWidgetAccIterator->MoveToNext();

-    }

-    pWidgetAccIterator->Release();

-  }

-  pWidgetAccIterator = m_pXFADocView->CreateWidgetAccIterator();

-  if (pWidgetAccIterator) {

-    CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext();

-    pWidgetAcc = pWidgetAccIterator->MoveToNext();

-    while (pWidgetAcc) {

-      int fRet = pWidgetAcc->ProcessValidate(-1);

-      if (fRet == XFA_EVENTERROR_Error) {

-        CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();

-        if (pEnv == NULL)

-          return FALSE;

-        CFX_WideString ws;

-        ws.FromLocal(IDS_XFA_Validate_Input);

-        CFX_ByteString bs = ws.UTF16LE_Encode();

-        int len = bs.GetLength() / sizeof(unsigned short);

-        pEnv->FFI_Alert(

-            (FPDF_WIDESTRING)bs.GetBuffer(len * sizeof(unsigned short)),

-            (FPDF_WIDESTRING)L"", 0, 1);

-        bs.ReleaseBuffer(len * sizeof(unsigned short));

-        pWidgetAccIterator->Release();

-        return FALSE;

-      }

-      pWidgetAcc = pWidgetAccIterator->MoveToNext();

-    }

-    pWidgetAccIterator->Release();

-    m_pXFADocView->UpdateDocView();

-  }

-#endif

-  return TRUE;

-}

-void CPDFXFA_Document::_OnAfterNotifySumbit() {

-  if (m_iDocType != DOCTYPE_DYNAMIC_XFA && m_iDocType != DOCTYPE_STATIC_XFA)

-    return;

-  if (m_pXFADocView == NULL)

-    return;

-  IXFA_WidgetHandler* pWidgetHandler = m_pXFADocView->GetWidgetHandler();

-  if (pWidgetHandler == NULL)

-    return;

-  IXFA_WidgetAccIterator* pWidgetAccIterator =

-      m_pXFADocView->CreateWidgetAccIterator();

-  if (pWidgetAccIterator == NULL)

-    return;

-  CXFA_EventParam Param;

-  Param.m_eType = XFA_EVENT_PostSubmit;

-

-  CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext();

-  while (pWidgetAcc) {

-    pWidgetHandler->ProcessEvent(pWidgetAcc, &Param);

-    pWidgetAcc = pWidgetAccIterator->MoveToNext();

-  }

-  pWidgetAccIterator->Release();

-  m_pXFADocView->UpdateDocView();

-}

-

-FX_BOOL CPDFXFA_Document::SubmitData(IXFA_Doc* hDoc, CXFA_Submit submit) {

-  if (!_NotifySubmit(TRUE))

-    return FALSE;

-  if (NULL == m_pXFADocView)

-    return FALSE;

-  m_pXFADocView->UpdateDocView();

-

-  FX_BOOL ret = _SubmitData(hDoc, submit);

-  _NotifySubmit(FALSE);

-  return ret;

-}

-

-IFX_FileRead* CPDFXFA_Document::OpenLinkedFile(IXFA_Doc* hDoc,

-                                               const CFX_WideString& wsLink) {

-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();

-  if (pEnv == NULL)

-    return FALSE;

-  CFX_ByteString bs = wsLink.UTF16LE_Encode();

-  int len = bs.GetLength() / sizeof(unsigned short);

-  FPDF_FILEHANDLER* pFileHandler = pEnv->FFI_OpenFile(

-      0, (FPDF_WIDESTRING)bs.GetBuffer(len * sizeof(unsigned short)), "rb");

-  bs.ReleaseBuffer(len * sizeof(unsigned short));

-

-  if (pFileHandler == NULL)

-    return NULL;

-  return new CFPDF_FileStream(pFileHandler);

-}

-FX_BOOL CPDFXFA_Document::_ExportSubmitFile(FPDF_FILEHANDLER* pFileHandler,

-                                            int fileType,

-                                            FPDF_DWORD encodeType,

-                                            FPDF_DWORD flag) {

-  if (NULL == m_pXFADocView)

-    return FALSE;

-  IXFA_DocHandler* pDocHandler = m_pApp->GetXFAApp()->GetDocHandler();

-  CFX_ByteString content;

-

-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();

-  if (pEnv == NULL)

-    return FALSE;

-

-  CFPDF_FileStream fileStream(pFileHandler);

-

-  if (fileType == FXFA_SAVEAS_XML) {

-    CFX_WideString ws;

-    ws.FromLocal("data");

-    CFX_ByteString content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n";

-    fileStream.WriteBlock((const FX_CHAR*)content, 0, content.GetLength());

-    pDocHandler->SavePackage(m_pXFADoc, ws, &fileStream);

-  } else if (fileType == FXFA_SAVEAS_XDP) {

-    if (flag == 0)

-      flag = FXFA_CONFIG | FXFA_TEMPLATE | FXFA_LOCALESET | FXFA_DATASETS |

-             FXFA_XMPMETA | FXFA_XFDF | FXFA_FORM;

-    if (m_pPDFDoc == NULL) {

-      fileStream.Flush();

-      return FALSE;

-    }

-    CPDF_Dictionary* pRoot = m_pPDFDoc->GetRoot();

-    if (pRoot == NULL) {

-      fileStream.Flush();

-      return FALSE;

-    }

-    CPDF_Dictionary* pAcroForm = pRoot->GetDict("AcroForm");

-    if (NULL == pAcroForm) {

-      fileStream.Flush();

-      return FALSE;

-    }

-    CPDF_Object* pXFA = pAcroForm->GetElement("XFA");

-    if (pXFA == NULL) {

-      fileStream.Flush();

-      return FALSE;

-    }

-    if (pXFA->GetType() != PDFOBJ_ARRAY) {

-      fileStream.Flush();

-      return FALSE;

-    }

-    CPDF_Array* pArray = pXFA->GetArray();

-    if (NULL == pArray) {

-      fileStream.Flush();

-      return FALSE;

-    }

-    int size = pArray->GetCount();

-    for (int i = 1; i < size; i += 2) {

-      CPDF_Object* pPDFObj = pArray->GetElement(i);

-      CPDF_Object* pPrePDFObj = pArray->GetElement(i - 1);

-      if (pPrePDFObj->GetType() != PDFOBJ_STRING)

-        continue;

-      if (pPDFObj->GetType() != PDFOBJ_REFERENCE)

-        continue;

-      CPDF_Object* pDirectObj = pPDFObj->GetDirect();

-      if (pDirectObj->GetType() != PDFOBJ_STREAM)

-        continue;

-      if (pPrePDFObj->GetString() == "config" && !(flag & FXFA_CONFIG))

-        continue;

-      if (pPrePDFObj->GetString() == "template" && !(flag & FXFA_TEMPLATE))

-        continue;

-      if (pPrePDFObj->GetString() == "localeSet" && !(flag & FXFA_LOCALESET))

-        continue;

-      if (pPrePDFObj->GetString() == "datasets" && !(flag & FXFA_DATASETS))

-        continue;

-      if (pPrePDFObj->GetString() == "xmpmeta" && !(flag & FXFA_XMPMETA))

-        continue;

-      if (pPrePDFObj->GetString() == "xfdf" && !(flag & FXFA_XFDF))

-        continue;

-      if (pPrePDFObj->GetString() == "form" && !(flag & FXFA_FORM))

-        continue;

-      if (pPrePDFObj->GetString() == "form") {

-        CFX_WideString ws;

-        ws.FromLocal("form");

-        pDocHandler->SavePackage(m_pXFADoc, ws, &fileStream);

-      } else if (pPrePDFObj->GetString() == "datasets") {

-        CFX_WideString ws;

-        ws.FromLocal("datasets");

-        pDocHandler->SavePackage(m_pXFADoc, ws, &fileStream);

-      } else {

-        // PDF,creator.

-        // TODO:

-      }

-    }

-  }

-  return TRUE;

-}

-

-void CPDFXFA_Document::_ClearChangeMark() {

-  if (m_pSDKDoc)

-    m_pSDKDoc->ClearChangeMark();

-}

-

-void CPDFXFA_Document::_ToXFAContentFlags(CFX_WideString csSrcContent,

-                                          FPDF_DWORD& flag) {

-  if (csSrcContent.Find(L" config ", 0) != -1)

-    flag |= FXFA_CONFIG;

-  if (csSrcContent.Find(L" template ", 0) != -1)

-    flag |= FXFA_TEMPLATE;

-  if (csSrcContent.Find(L" localeSet ", 0) != -1)

-    flag |= FXFA_LOCALESET;

-  if (csSrcContent.Find(L" datasets ", 0) != -1)

-    flag |= FXFA_DATASETS;

-  if (csSrcContent.Find(L" xmpmeta ", 0) != -1)

-    flag |= FXFA_XMPMETA;

-  if (csSrcContent.Find(L" xfdf ", 0) != -1)

-    flag |= FXFA_XFDF;

-  if (csSrcContent.Find(L" form ", 0) != -1)

-    flag |= FXFA_FORM;

-  if (flag == 0)

-    flag = FXFA_CONFIG | FXFA_TEMPLATE | FXFA_LOCALESET | FXFA_DATASETS |

-           FXFA_XMPMETA | FXFA_XFDF | FXFA_FORM;

-}

-FX_BOOL CPDFXFA_Document::_MailToInfo(CFX_WideString& csURL,

-                                      CFX_WideString& csToAddress,

-                                      CFX_WideString& csCCAddress,

-                                      CFX_WideString& csBCCAddress,

-                                      CFX_WideString& csSubject,

-                                      CFX_WideString& csMsg) {

-  CFX_WideString srcURL = csURL;

-  srcURL.TrimLeft();

-  if (0 != srcURL.Left(7).CompareNoCase(L"mailto:"))

-    return FALSE;

-  int pos = srcURL.Find(L'?', 0);

-  CFX_WideString tmp;

-  if (pos == -1) {

-    pos = srcURL.Find(L'@', 0);

-    if (pos == -1)

-      return FALSE;

-    else {

-      tmp = srcURL.Right(csURL.GetLength() - 7);

-      tmp.TrimLeft();

-      tmp.TrimRight();

-    }

-  } else {

-    tmp = srcURL.Left(pos);

-    tmp = tmp.Right(tmp.GetLength() - 7);

-    tmp.TrimLeft();

-    tmp.TrimRight();

-  }

-

-  csToAddress = tmp;

-

-  srcURL = srcURL.Right(srcURL.GetLength() - (pos + 1));

-  while (!srcURL.IsEmpty()) {

-    srcURL.TrimLeft();

-    srcURL.TrimRight();

-    pos = srcURL.Find(L'&', 0);

-    if (pos == -1)

-      tmp = srcURL;

-    else

-      tmp = srcURL.Left(pos);

-

-    tmp.TrimLeft();

-    tmp.TrimRight();

-    if (tmp.GetLength() >= 3 && 0 == tmp.Left(3).CompareNoCase(L"cc=")) {

-      tmp = tmp.Right(tmp.GetLength() - 3);

-      if (!csCCAddress.IsEmpty())

-        csCCAddress += L';';

-      csCCAddress += tmp;

-

-    } else if (tmp.GetLength() >= 4 &&

-               0 == tmp.Left(4).CompareNoCase(L"bcc=")) {

-      tmp = tmp.Right(tmp.GetLength() - 4);

-      if (!csBCCAddress.IsEmpty())

-        csBCCAddress += L';';

-      csBCCAddress += tmp;

-    } else if (tmp.GetLength() >= 8 &&

-               0 == tmp.Left(8).CompareNoCase(L"subject=")) {

-      tmp = tmp.Right(tmp.GetLength() - 8);

-      csSubject += tmp;

-    } else if (tmp.GetLength() >= 5 &&

-               0 == tmp.Left(5).CompareNoCase(L"body=")) {

-      tmp = tmp.Right(tmp.GetLength() - 5);

-      csMsg += tmp;

-    }

-    if (pos == -1)

-      srcURL = L"";

-    else

-      srcURL = srcURL.Right(csURL.GetLength() - (pos + 1));

-  }

-  csToAddress.Replace(L",", L";");

-  csCCAddress.Replace(L",", L";");

-  csBCCAddress.Replace(L",", L";");

-  return TRUE;

-}

-

-FX_BOOL CPDFXFA_Document::_SubmitData(IXFA_Doc* hDoc, CXFA_Submit submit) {

-#ifdef PDF_ENABLE_XFA

-  CFX_WideStringC csURLC;

-  submit.GetSubmitTarget(csURLC);

-  CFX_WideString csURL = csURLC;

-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();

-  if (pEnv == NULL)

-    return FALSE;

-  if (csURL.IsEmpty()) {

-    CFX_WideString ws;

-    ws.FromLocal("Submit cancelled.");

-    CFX_ByteString bs = ws.UTF16LE_Encode();

-    int len = bs.GetLength() / sizeof(unsigned short);

-    pEnv->FFI_Alert((FPDF_WIDESTRING)bs.GetBuffer(len * sizeof(unsigned short)),

-                    (FPDF_WIDESTRING)L"", 0, 4);

-    bs.ReleaseBuffer(len * sizeof(unsigned short));

-    return FALSE;

-  }

-

-  FPDF_BOOL bRet = TRUE;

-  FPDF_FILEHANDLER* pFileHandler = NULL;

-  int fileFlag = -1;

-

-  if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Xdp) {

-    CFX_WideStringC csContentC;

-    submit.GetSubmitXDPContent(csContentC);

-    CFX_WideString csContent;

-    csContent = csContentC.GetPtr();

-    csContent.TrimLeft();

-    csContent.TrimRight();

-    CFX_WideString space;

-    space.FromLocal(" ");

-    csContent = space + csContent + space;

-    FPDF_DWORD flag = 0;

-    if (submit.IsSubmitEmbedPDF())

-      flag |= FXFA_PDF;

-    _ToXFAContentFlags(csContent, flag);

-    pFileHandler = pEnv->FFI_OpenFile(FXFA_SAVEAS_XDP, NULL, "wb");

-    fileFlag = FXFA_SAVEAS_XDP;

-    _ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XDP, 0, flag);

-  } else if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Xml) {

-    pFileHandler = pEnv->FFI_OpenFile(FXFA_SAVEAS_XML, NULL, "wb");

-    fileFlag = FXFA_SAVEAS_XML;

-    _ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XML, 0);

-  } else if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Pdf) {

-    // csfilename = csDocName;

-  } else if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Formdata) {

-    return FALSE;

-  } else if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Urlencoded) {

-    pFileHandler = pEnv->FFI_OpenFile(FXFA_SAVEAS_XML, NULL, "wb");

-    fileFlag = FXFA_SAVEAS_XML;

-    _ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XML, 0);

-  } else if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Xfd) {

-    return FALSE;

-  } else {

-    return FALSE;

-  }

-  if (pFileHandler == NULL)

-    return FALSE;

-  if (0 == csURL.Left(7).CompareNoCase(L"mailto:")) {

-    CFX_WideString csToAddress;

-    CFX_WideString csCCAddress;

-    CFX_WideString csBCCAddress;

-    CFX_WideString csSubject;

-    CFX_WideString csMsg;

-

-    bRet = _MailToInfo(csURL, csToAddress, csCCAddress, csBCCAddress, csSubject,

-                       csMsg);

-    if (FALSE == bRet)

-      return FALSE;

-

-    CFX_ByteString bsTo = CFX_WideString(csToAddress).UTF16LE_Encode();

-    CFX_ByteString bsCC = CFX_WideString(csCCAddress).UTF16LE_Encode();

-    CFX_ByteString bsBcc = CFX_WideString(csBCCAddress).UTF16LE_Encode();

-    CFX_ByteString bsSubject = CFX_WideString(csSubject).UTF16LE_Encode();

-    CFX_ByteString bsMsg = CFX_WideString(csMsg).UTF16LE_Encode();

-

-    FPDF_WIDESTRING pTo = (FPDF_WIDESTRING)bsTo.GetBuffer(bsTo.GetLength());

-    FPDF_WIDESTRING pCC = (FPDF_WIDESTRING)bsCC.GetBuffer(bsCC.GetLength());

-    FPDF_WIDESTRING pBcc = (FPDF_WIDESTRING)bsBcc.GetBuffer(bsBcc.GetLength());

-    FPDF_WIDESTRING pSubject =

-        (FPDF_WIDESTRING)bsSubject.GetBuffer(bsSubject.GetLength());

-    FPDF_WIDESTRING pMsg = (FPDF_WIDESTRING)bsMsg.GetBuffer(bsMsg.GetLength());

-

-    pEnv->FFI_EmailTo(pFileHandler, pTo, pSubject, pCC, pBcc, pMsg);

-    bsTo.ReleaseBuffer();

-    bsCC.ReleaseBuffer();

-    bsBcc.ReleaseBuffer();

-    bsSubject.ReleaseBuffer();

-    bsMsg.ReleaseBuffer();

-  } else {

-    // http¡¢ftp

-    CFX_WideString ws;

-    CFX_ByteString bs = csURL.UTF16LE_Encode();

-    int len = bs.GetLength() / sizeof(unsigned short);

-    pEnv->FFI_UploadTo(

-        pFileHandler, fileFlag,

-        (FPDF_WIDESTRING)bs.GetBuffer(len * sizeof(unsigned short)));

-    bs.ReleaseBuffer(len * sizeof(unsigned short));

-  }

-

-  return bRet;

-#else

-  return TRUE;

-#endif

-}

-

-FX_BOOL CPDFXFA_Document::SetGlobalProperty(IXFA_Doc* hDoc,

-                                            const CFX_ByteStringC& szPropName,

-                                            FXJSE_HVALUE hValue) {

-  if (hDoc != m_pXFADoc)

-    return FALSE;

-

-  if (m_pSDKDoc && m_pSDKDoc->GetEnv()->GetJSRuntime())

-    return m_pSDKDoc->GetEnv()->GetJSRuntime()->SetHValueByName(szPropName,

-                                                                hValue);

-  return FALSE;

-}

-FX_BOOL CPDFXFA_Document::GetPDFScriptObject(IXFA_Doc* hDoc,

-                                             const CFX_ByteStringC& utf8Name,

-                                             FXJSE_HVALUE hValue) {

-  if (hDoc != m_pXFADoc)

-    return FALSE;

-

-  if (!m_pSDKDoc || !m_pSDKDoc->GetEnv()->GetJSRuntime())

-    return FALSE;

-

-  if (!m_pJSContext) {

-    m_pSDKDoc->GetEnv()->GetJSRuntime()->SetReaderDocument(m_pSDKDoc);

-    m_pJSContext = m_pSDKDoc->GetEnv()->GetJSRuntime()->NewContext();

-  }

-

-  return _GetHValueByName(utf8Name, hValue,

-                          m_pSDKDoc->GetEnv()->GetJSRuntime());

-}

-FX_BOOL CPDFXFA_Document::GetGlobalProperty(IXFA_Doc* hDoc,

-                                            const CFX_ByteStringC& szPropName,

-                                            FXJSE_HVALUE hValue) {

-  if (hDoc != m_pXFADoc)

-    return FALSE;

-  if (!m_pSDKDoc || !m_pSDKDoc->GetEnv()->GetJSRuntime())

-    return FALSE;

-

-  if (!m_pJSContext) {

-    m_pSDKDoc->GetEnv()->GetJSRuntime()->SetReaderDocument(m_pSDKDoc);

-    m_pJSContext = m_pSDKDoc->GetEnv()->GetJSRuntime()->NewContext();

-  }

-

-  return _GetHValueByName(szPropName, hValue,

-                          m_pSDKDoc->GetEnv()->GetJSRuntime());

-}

-FX_BOOL CPDFXFA_Document::_GetHValueByName(const CFX_ByteStringC& utf8Name,

-                                           FXJSE_HVALUE hValue,

-                                           IJS_Runtime* runTime) {

-  return runTime->GetHValueByName(utf8Name, hValue);

-}

diff --git a/fpdfsdk/src/fpdfxfa/fpdfxfa_util.cpp b/fpdfsdk/src/fpdfxfa/fpdfxfa_util.cpp
deleted file mode 100644
index dc1cf9b..0000000
--- a/fpdfsdk/src/fpdfxfa/fpdfxfa_util.cpp
+++ /dev/null
@@ -1,65 +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

-

-#include "fpdfsdk/include/fsdk_define.h"

-#include "fpdfsdk/include/fsdk_mgr.h"

-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h"

-

-CFX_PtrArray CXFA_FWLAdapterTimerMgr::ms_timerArray;

-

-FWL_ERR CXFA_FWLAdapterTimerMgr::Start(IFWL_Timer* pTimer,

-                                       FX_DWORD dwElapse,

-                                       FWL_HTIMER& hTimer,

-                                       FX_BOOL bImmediately /* = TRUE */) {

-  if (m_pEnv) {

-    uint32_t uIDEvent = m_pEnv->FFI_SetTimer(dwElapse, TimerProc);

-    CFWL_TimerInfo* pInfo = new CFWL_TimerInfo;

-    pInfo->uIDEvent = uIDEvent;

-    pInfo->pTimer = pTimer;

-    ms_timerArray.Add(pInfo);

-

-    hTimer = (FWL_HTIMER)pInfo;

-    return FWL_ERR_Succeeded;

-  }

-

-  return FWL_ERR_Indefinite;

-}

-

-FWL_ERR CXFA_FWLAdapterTimerMgr::Stop(FWL_HTIMER hTimer) {

-  if (!hTimer)

-    return FWL_ERR_Indefinite;

-

-  if (m_pEnv) {

-    CFWL_TimerInfo* pInfo = (CFWL_TimerInfo*)hTimer;

-

-    m_pEnv->FFI_KillTimer(pInfo->uIDEvent);

-

-    int32_t index = ms_timerArray.Find(pInfo);

-    if (index >= 0) {

-      ms_timerArray.RemoveAt(index);

-      delete pInfo;

-    }

-    return FWL_ERR_Succeeded;

-  }

-

-  return FWL_ERR_Indefinite;

-}

-

-void CXFA_FWLAdapterTimerMgr::TimerProc(int32_t idEvent) {

-  CFWL_TimerInfo* pInfo = NULL;

-  int32_t iCount = CXFA_FWLAdapterTimerMgr::ms_timerArray.GetSize();

-  for (int32_t i = 0; i < iCount; i++) {

-    CFWL_TimerInfo* pTemp =

-        (CFWL_TimerInfo*)CXFA_FWLAdapterTimerMgr::ms_timerArray.GetAt(i);

-    if (pTemp->uIDEvent == idEvent) {

-      pInfo = pTemp;

-      break;

-    }

-  }

-  if (pInfo) {

-    pInfo->pTimer->Run((FWL_HTIMER)pInfo);

-  }

-}

diff --git a/fpdfsdk/src/fsdk_actionhandler.cpp b/fpdfsdk/src/fsdk_actionhandler.cpp
deleted file mode 100644
index 9524b2a..0000000
--- a/fpdfsdk/src/fsdk_actionhandler.cpp
+++ /dev/null
@@ -1,631 +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
-
-#include "fpdfsdk/include/fsdk_actionhandler.h"
-#include "fpdfsdk/include/fsdk_define.h"
-#include "fpdfsdk/include/fsdk_mgr.h"
-#include "fpdfsdk/include/javascript/IJavaScript.h"
-
-CPDFSDK_ActionHandler::CPDFSDK_ActionHandler()
-    : m_pFormActionHandler(new CPDFSDK_FormActionHandler) {
-}
-
-FX_BOOL CPDFSDK_ActionHandler::DoAction_DocOpen(const CPDF_Action& action,
-                                                CPDFSDK_Document* pDocument) {
-  CFX_PtrList list;
-  return ExecuteDocumentOpenAction(action, pDocument, list);
-}
-
-FX_BOOL CPDFSDK_ActionHandler::DoAction_JavaScript(
-    const CPDF_Action& JsAction,
-    CFX_WideString csJSName,
-    CPDFSDK_Document* pDocument) {
-  if (JsAction.GetType() == CPDF_Action::JavaScript) {
-    CFX_WideString swJS = JsAction.GetJavaScript();
-    if (!swJS.IsEmpty()) {
-      RunDocumentOpenJavaScript(pDocument, csJSName, swJS);
-      return TRUE;
-    }
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CPDFSDK_ActionHandler::DoAction_FieldJavaScript(
-    const CPDF_Action& JsAction,
-    CPDF_AAction::AActionType type,
-    CPDFSDK_Document* pDocument,
-    CPDF_FormField* pFormField,
-    PDFSDK_FieldAction& data) {
-  CPDFDoc_Environment* pEnv = pDocument->GetEnv();
-  ASSERT(pEnv);
-  if (pEnv->IsJSInitiated() && JsAction.GetType() == CPDF_Action::JavaScript) {
-    CFX_WideString swJS = JsAction.GetJavaScript();
-    if (!swJS.IsEmpty()) {
-      RunFieldJavaScript(pDocument, pFormField, type, data, swJS);
-      return TRUE;
-    }
-  }
-  return FALSE;
-}
-
-FX_BOOL CPDFSDK_ActionHandler::DoAction_Page(
-    const CPDF_Action& action,
-    enum CPDF_AAction::AActionType eType,
-    CPDFSDK_Document* pDocument) {
-  CFX_PtrList list;
-  return ExecuteDocumentPageAction(action, eType, pDocument, list);
-}
-
-FX_BOOL CPDFSDK_ActionHandler::DoAction_Document(
-    const CPDF_Action& action,
-    enum CPDF_AAction::AActionType eType,
-    CPDFSDK_Document* pDocument) {
-  CFX_PtrList list;
-  return ExecuteDocumentPageAction(action, eType, pDocument, list);
-}
-
-FX_BOOL CPDFSDK_ActionHandler::DoAction_BookMark(CPDF_Bookmark* pBookMark,
-                                                 const CPDF_Action& action,
-                                                 CPDF_AAction::AActionType type,
-                                                 CPDFSDK_Document* pDocument) {
-  CFX_PtrList list;
-  return ExecuteBookMark(action, pDocument, pBookMark, list);
-}
-
-FX_BOOL CPDFSDK_ActionHandler::DoAction_Screen(const CPDF_Action& action,
-                                               CPDF_AAction::AActionType type,
-                                               CPDFSDK_Document* pDocument,
-                                               CPDFSDK_Annot* pScreen) {
-  CFX_PtrList list;
-  return ExecuteScreenAction(action, type, pDocument, pScreen, list);
-}
-
-FX_BOOL CPDFSDK_ActionHandler::DoAction_Link(const CPDF_Action& action,
-                                             CPDFSDK_Document* pDocument) {
-  CFX_PtrList list;
-  return ExecuteLinkAction(action, pDocument, list);
-}
-
-FX_BOOL CPDFSDK_ActionHandler::DoAction_Field(const CPDF_Action& action,
-                                              CPDF_AAction::AActionType type,
-                                              CPDFSDK_Document* pDocument,
-                                              CPDF_FormField* pFormField,
-                                              PDFSDK_FieldAction& data) {
-  CFX_PtrList list;
-  return ExecuteFieldAction(action, type, pDocument, pFormField, data, list);
-}
-
-FX_BOOL CPDFSDK_ActionHandler::ExecuteDocumentOpenAction(
-    const CPDF_Action& action,
-    CPDFSDK_Document* pDocument,
-    CFX_PtrList& list) {
-  CPDF_Dictionary* pDict = action.GetDict();
-  if (list.Find(pDict))
-    return FALSE;
-
-  list.AddTail(pDict);
-
-  CPDFDoc_Environment* pEnv = pDocument->GetEnv();
-  ASSERT(pEnv);
-  if (action.GetType() == CPDF_Action::JavaScript) {
-    if (pEnv->IsJSInitiated()) {
-      CFX_WideString swJS = action.GetJavaScript();
-      if (!swJS.IsEmpty()) {
-        RunDocumentOpenJavaScript(pDocument, L"", swJS);
-      }
-    }
-  } else {
-    DoAction_NoJs(action, pDocument);
-  }
-
-  for (int32_t i = 0, sz = action.GetSubActionsCount(); i < sz; i++) {
-    CPDF_Action subaction = action.GetSubAction(i);
-    if (!ExecuteDocumentOpenAction(subaction, pDocument, list))
-      return FALSE;
-  }
-
-  return TRUE;
-}
-
-FX_BOOL CPDFSDK_ActionHandler::ExecuteLinkAction(const CPDF_Action& action,
-                                                 CPDFSDK_Document* pDocument,
-                                                 CFX_PtrList& list) {
-  CPDF_Dictionary* pDict = action.GetDict();
-  if (list.Find(pDict))
-    return FALSE;
-
-  list.AddTail(pDict);
-
-  CPDFDoc_Environment* pEnv = pDocument->GetEnv();
-  ASSERT(pEnv);
-  if (action.GetType() == CPDF_Action::JavaScript) {
-    if (pEnv->IsJSInitiated()) {
-      CFX_WideString swJS = action.GetJavaScript();
-      if (!swJS.IsEmpty()) {
-        IJS_Runtime* pRuntime = pDocument->GetJsRuntime();
-        pRuntime->SetReaderDocument(pDocument);
-
-        IJS_Context* pContext = pRuntime->NewContext();
-        pContext->OnLink_MouseUp(pDocument);
-
-        CFX_WideString csInfo;
-        FX_BOOL bRet = pContext->RunScript(swJS, &csInfo);
-        if (!bRet) {
-          // FIXME: return error.
-        }
-
-        pRuntime->ReleaseContext(pContext);
-      }
-    }
-  } else {
-    DoAction_NoJs(action, pDocument);
-  }
-
-  for (int32_t i = 0, sz = action.GetSubActionsCount(); i < sz; i++) {
-    CPDF_Action subaction = action.GetSubAction(i);
-    if (!ExecuteLinkAction(subaction, pDocument, list))
-      return FALSE;
-  }
-
-  return TRUE;
-}
-
-FX_BOOL CPDFSDK_ActionHandler::ExecuteDocumentPageAction(
-    const CPDF_Action& action,
-    CPDF_AAction::AActionType type,
-    CPDFSDK_Document* pDocument,
-    CFX_PtrList& list) {
-  CPDF_Dictionary* pDict = action.GetDict();
-  if (list.Find(pDict))
-    return FALSE;
-
-  list.AddTail(pDict);
-
-  CPDFDoc_Environment* pEnv = pDocument->GetEnv();
-  ASSERT(pEnv);
-  if (action.GetType() == CPDF_Action::JavaScript) {
-    if (pEnv->IsJSInitiated()) {
-      CFX_WideString swJS = action.GetJavaScript();
-      if (!swJS.IsEmpty()) {
-        RunDocumentPageJavaScript(pDocument, type, swJS);
-      }
-    }
-  } else {
-    DoAction_NoJs(action, pDocument);
-  }
-
-  if (!IsValidDocView(pDocument))
-    return FALSE;
-
-  for (int32_t i = 0, sz = action.GetSubActionsCount(); i < sz; i++) {
-    CPDF_Action subaction = action.GetSubAction(i);
-    if (!ExecuteDocumentPageAction(subaction, type, pDocument, list))
-      return FALSE;
-  }
-
-  return TRUE;
-}
-
-FX_BOOL CPDFSDK_ActionHandler::IsValidField(CPDFSDK_Document* pDocument,
-                                            CPDF_Dictionary* pFieldDict) {
-  ASSERT(pFieldDict);
-
-  CPDFSDK_InterForm* pInterForm = pDocument->GetInterForm();
-  CPDF_InterForm* pPDFInterForm = pInterForm->GetInterForm();
-  return pPDFInterForm->GetFieldByDict(pFieldDict) != NULL;
-}
-
-FX_BOOL CPDFSDK_ActionHandler::ExecuteFieldAction(
-    const CPDF_Action& action,
-    CPDF_AAction::AActionType type,
-    CPDFSDK_Document* pDocument,
-    CPDF_FormField* pFormField,
-    PDFSDK_FieldAction& data,
-    CFX_PtrList& list) {
-  CPDF_Dictionary* pDict = action.GetDict();
-  if (list.Find(pDict))
-    return FALSE;
-
-  list.AddTail(pDict);
-
-  CPDFDoc_Environment* pEnv = pDocument->GetEnv();
-  ASSERT(pEnv);
-  if (action.GetType() == CPDF_Action::JavaScript) {
-    if (pEnv->IsJSInitiated()) {
-      CFX_WideString swJS = action.GetJavaScript();
-      if (!swJS.IsEmpty()) {
-        RunFieldJavaScript(pDocument, pFormField, type, data, swJS);
-        if (!IsValidField(pDocument, pFormField->GetFieldDict()))
-          return FALSE;
-      }
-    }
-  } else {
-    DoAction_NoJs(action, pDocument);
-  }
-
-  for (int32_t i = 0, sz = action.GetSubActionsCount(); i < sz; i++) {
-    CPDF_Action subaction = action.GetSubAction(i);
-    if (!ExecuteFieldAction(subaction, type, pDocument, pFormField, data, list))
-      return FALSE;
-  }
-
-  return TRUE;
-}
-
-FX_BOOL CPDFSDK_ActionHandler::ExecuteScreenAction(
-    const CPDF_Action& action,
-    CPDF_AAction::AActionType type,
-    CPDFSDK_Document* pDocument,
-    CPDFSDK_Annot* pScreen,
-    CFX_PtrList& list) {
-  CPDF_Dictionary* pDict = action.GetDict();
-  if (list.Find(pDict))
-    return FALSE;
-
-  list.AddTail(pDict);
-
-  CPDFDoc_Environment* pEnv = pDocument->GetEnv();
-  ASSERT(pEnv);
-  if (action.GetType() == CPDF_Action::JavaScript) {
-    if (pEnv->IsJSInitiated()) {
-      CFX_WideString swJS = action.GetJavaScript();
-      if (!swJS.IsEmpty()) {
-        IJS_Runtime* pRuntime = pDocument->GetJsRuntime();
-        pRuntime->SetReaderDocument(pDocument);
-
-        IJS_Context* pContext = pRuntime->NewContext();
-        CFX_WideString csInfo;
-        FX_BOOL bRet = pContext->RunScript(swJS, &csInfo);
-        if (!bRet) {
-          // FIXME: return error.
-        }
-
-        pRuntime->ReleaseContext(pContext);
-      }
-    }
-  } else {
-    DoAction_NoJs(action, pDocument);
-  }
-
-  for (int32_t i = 0, sz = action.GetSubActionsCount(); i < sz; i++) {
-    CPDF_Action subaction = action.GetSubAction(i);
-    if (!ExecuteScreenAction(subaction, type, pDocument, pScreen, list))
-      return FALSE;
-  }
-
-  return TRUE;
-}
-
-FX_BOOL CPDFSDK_ActionHandler::ExecuteBookMark(const CPDF_Action& action,
-                                               CPDFSDK_Document* pDocument,
-                                               CPDF_Bookmark* pBookmark,
-                                               CFX_PtrList& list) {
-  CPDF_Dictionary* pDict = action.GetDict();
-  if (list.Find(pDict))
-    return FALSE;
-
-  list.AddTail(pDict);
-
-  CPDFDoc_Environment* pEnv = pDocument->GetEnv();
-  ASSERT(pEnv);
-  if (action.GetType() == CPDF_Action::JavaScript) {
-    if (pEnv->IsJSInitiated()) {
-      CFX_WideString swJS = action.GetJavaScript();
-      if (!swJS.IsEmpty()) {
-        IJS_Runtime* pRuntime = pDocument->GetJsRuntime();
-        pRuntime->SetReaderDocument(pDocument);
-
-        IJS_Context* pContext = pRuntime->NewContext();
-        pContext->OnBookmark_MouseUp(pBookmark);
-
-        CFX_WideString csInfo;
-        FX_BOOL bRet = pContext->RunScript(swJS, &csInfo);
-        if (!bRet) {
-          // FIXME: return error.
-        }
-
-        pRuntime->ReleaseContext(pContext);
-      }
-    }
-  } else {
-    DoAction_NoJs(action, pDocument);
-  }
-
-  for (int32_t i = 0, sz = action.GetSubActionsCount(); i < sz; i++) {
-    CPDF_Action subaction = action.GetSubAction(i);
-    if (!ExecuteBookMark(subaction, pDocument, pBookmark, list))
-      return FALSE;
-  }
-
-  return TRUE;
-}
-
-void CPDFSDK_ActionHandler::DoAction_NoJs(const CPDF_Action& action,
-                                          CPDFSDK_Document* pDocument) {
-  ASSERT(pDocument);
-
-  switch (action.GetType()) {
-    case CPDF_Action::GoTo:
-      DoAction_GoTo(pDocument, action);
-      break;
-    case CPDF_Action::GoToR:
-      DoAction_GoToR(pDocument, action);
-      break;
-    case CPDF_Action::GoToE:
-      break;
-    case CPDF_Action::Launch:
-      DoAction_Launch(pDocument, action);
-      break;
-    case CPDF_Action::Thread:
-      break;
-    case CPDF_Action::URI:
-      DoAction_URI(pDocument, action);
-      break;
-    case CPDF_Action::Sound:
-      break;
-    case CPDF_Action::Movie:
-      break;
-    case CPDF_Action::Hide:
-      if (m_pFormActionHandler) {
-        m_pFormActionHandler->DoAction_Hide(action, pDocument);
-      }
-      break;
-    case CPDF_Action::Named:
-      DoAction_Named(pDocument, action);
-      break;
-    case CPDF_Action::SubmitForm:
-      if (m_pFormActionHandler) {
-        m_pFormActionHandler->DoAction_SubmitForm(action, pDocument);
-      }
-      break;
-    case CPDF_Action::ResetForm:
-      if (m_pFormActionHandler) {
-        m_pFormActionHandler->DoAction_ResetForm(action, pDocument);
-      }
-      break;
-    case CPDF_Action::ImportData:
-      if (m_pFormActionHandler) {
-        m_pFormActionHandler->DoAction_ImportData(action, pDocument);
-      }
-      break;
-    case CPDF_Action::JavaScript:
-      ASSERT(FALSE);
-      break;
-    case CPDF_Action::SetOCGState:
-      DoAction_SetOCGState(pDocument, action);
-      break;
-    case CPDF_Action::Rendition:
-      break;
-    case CPDF_Action::Trans:
-      break;
-    case CPDF_Action::GoTo3DView:
-      break;
-    default:
-      break;
-  }
-}
-
-FX_BOOL CPDFSDK_ActionHandler::IsValidDocView(CPDFSDK_Document* pDocument) {
-  ASSERT(pDocument);
-  return TRUE;
-}
-
-void CPDFSDK_ActionHandler::DoAction_GoTo(CPDFSDK_Document* pDocument,
-                                          const CPDF_Action& action) {
-  ASSERT(action);
-
-  CPDF_Document* pPDFDocument = pDocument->GetPDFDocument();
-  ASSERT(pPDFDocument);
-
-  CPDF_Dest MyDest = action.GetDest(pPDFDocument);
-  int nPageIndex = MyDest.GetPageIndex(pPDFDocument);
-  int nFitType = MyDest.GetZoomMode();
-  const CPDF_Array* pMyArray = ToArray(MyDest.GetObject());
-  float* pPosAry = nullptr;
-  int sizeOfAry = 0;
-  if (pMyArray) {
-    pPosAry = new float[pMyArray->GetCount()];
-    int j = 0;
-    for (int i = 2; i < (int)pMyArray->GetCount(); i++) {
-      pPosAry[j++] = pMyArray->GetFloat(i);
-    }
-    sizeOfAry = j;
-  }
-
-  CPDFDoc_Environment* pApp = pDocument->GetEnv();
-  pApp->FFI_DoGoToAction(nPageIndex, nFitType, pPosAry, sizeOfAry);
-  delete[] pPosAry;
-}
-
-void CPDFSDK_ActionHandler::DoAction_GoToR(CPDFSDK_Document* pDocument,
-                                           const CPDF_Action& action) {}
-
-void CPDFSDK_ActionHandler::DoAction_Launch(CPDFSDK_Document* pDocument,
-                                            const CPDF_Action& action) {}
-
-void CPDFSDK_ActionHandler::DoAction_URI(CPDFSDK_Document* pDocument,
-                                         const CPDF_Action& action) {
-  ASSERT(action);
-
-  CPDFDoc_Environment* pApp = pDocument->GetEnv();
-  CFX_ByteString sURI = action.GetURI(pDocument->GetPDFDocument());
-  pApp->FFI_DoURIAction(sURI.c_str());
-}
-
-void CPDFSDK_ActionHandler::DoAction_Named(CPDFSDK_Document* pDocument,
-                                           const CPDF_Action& action) {
-  ASSERT(action);
-
-  CFX_ByteString csName = action.GetNamedAction();
-  pDocument->GetEnv()->FFI_ExecuteNamedAction(csName);
-}
-
-void CPDFSDK_ActionHandler::DoAction_SetOCGState(CPDFSDK_Document* pDocument,
-                                                 const CPDF_Action& action) {}
-
-void CPDFSDK_ActionHandler::RunFieldJavaScript(CPDFSDK_Document* pDocument,
-                                               CPDF_FormField* pFormField,
-                                               CPDF_AAction::AActionType type,
-                                               PDFSDK_FieldAction& data,
-                                               const CFX_WideString& script) {
-  ASSERT(type != CPDF_AAction::Calculate);
-  ASSERT(type != CPDF_AAction::Format);
-
-  IJS_Runtime* pRuntime = pDocument->GetJsRuntime();
-  pRuntime->SetReaderDocument(pDocument);
-
-  IJS_Context* pContext = pRuntime->NewContext();
-  switch (type) {
-    case CPDF_AAction::CursorEnter:
-      pContext->OnField_MouseEnter(data.bModifier, data.bShift, pFormField);
-      break;
-    case CPDF_AAction::CursorExit:
-      pContext->OnField_MouseExit(data.bModifier, data.bShift, pFormField);
-      break;
-    case CPDF_AAction::ButtonDown:
-      pContext->OnField_MouseDown(data.bModifier, data.bShift, pFormField);
-      break;
-    case CPDF_AAction::ButtonUp:
-      pContext->OnField_MouseUp(data.bModifier, data.bShift, pFormField);
-      break;
-    case CPDF_AAction::GetFocus:
-      pContext->OnField_Focus(data.bModifier, data.bShift, pFormField,
-                              data.sValue);
-      break;
-    case CPDF_AAction::LoseFocus:
-      pContext->OnField_Blur(data.bModifier, data.bShift, pFormField,
-                             data.sValue);
-      break;
-    case CPDF_AAction::KeyStroke:
-      pContext->OnField_Keystroke(data.sChange, data.sChangeEx, data.bKeyDown,
-                                  data.bModifier, data.nSelEnd, data.nSelStart,
-                                  data.bShift, pFormField, data.sValue,
-                                  data.bWillCommit, data.bFieldFull, data.bRC);
-      break;
-    case CPDF_AAction::Validate:
-      pContext->OnField_Validate(data.sChange, data.sChangeEx, data.bKeyDown,
-                                 data.bModifier, data.bShift, pFormField,
-                                 data.sValue, data.bRC);
-      break;
-    default:
-      ASSERT(FALSE);
-      break;
-  }
-
-  CFX_WideString csInfo;
-  FX_BOOL bRet = pContext->RunScript(script, &csInfo);
-  if (!bRet) {
-    // FIXME: return error.
-  }
-
-  pRuntime->ReleaseContext(pContext);
-}
-
-void CPDFSDK_ActionHandler::RunDocumentOpenJavaScript(
-    CPDFSDK_Document* pDocument,
-    const CFX_WideString& sScriptName,
-    const CFX_WideString& script) {
-  IJS_Runtime* pRuntime = pDocument->GetJsRuntime();
-  pRuntime->SetReaderDocument(pDocument);
-  IJS_Context* pContext = pRuntime->NewContext();
-  pContext->OnDoc_Open(pDocument, sScriptName);
-
-  CFX_WideString csInfo;
-  FX_BOOL bRet = pContext->RunScript(script, &csInfo);
-  if (!bRet) {
-    // FIXME: return error.
-  }
-
-  pRuntime->ReleaseContext(pContext);
-}
-
-void CPDFSDK_ActionHandler::RunDocumentPageJavaScript(
-    CPDFSDK_Document* pDocument,
-    CPDF_AAction::AActionType type,
-    const CFX_WideString& script) {
-  IJS_Runtime* pRuntime = pDocument->GetJsRuntime();
-  pRuntime->SetReaderDocument(pDocument);
-
-  IJS_Context* pContext = pRuntime->NewContext();
-  switch (type) {
-    case CPDF_AAction::OpenPage:
-      pContext->OnPage_Open(pDocument);
-      break;
-    case CPDF_AAction::ClosePage:
-      pContext->OnPage_Close(pDocument);
-      break;
-    case CPDF_AAction::CloseDocument:
-      pContext->OnDoc_WillClose(pDocument);
-      break;
-    case CPDF_AAction::SaveDocument:
-      pContext->OnDoc_WillSave(pDocument);
-      break;
-    case CPDF_AAction::DocumentSaved:
-      pContext->OnDoc_DidSave(pDocument);
-      break;
-    case CPDF_AAction::PrintDocument:
-      pContext->OnDoc_WillPrint(pDocument);
-      break;
-    case CPDF_AAction::DocumentPrinted:
-      pContext->OnDoc_DidPrint(pDocument);
-      break;
-    case CPDF_AAction::PageVisible:
-      pContext->OnPage_InView(pDocument);
-      break;
-    case CPDF_AAction::PageInvisible:
-      pContext->OnPage_OutView(pDocument);
-      break;
-    default:
-      ASSERT(FALSE);
-      break;
-  }
-
-  CFX_WideString csInfo;
-  FX_BOOL bRet = pContext->RunScript(script, &csInfo);
-  if (!bRet) {
-    // FIXME: return error.
-  }
-
-  pRuntime->ReleaseContext(pContext);
-}
-
-FX_BOOL CPDFSDK_FormActionHandler::DoAction_Hide(const CPDF_Action& action,
-                                                 CPDFSDK_Document* pDocument) {
-  CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)pDocument->GetInterForm();
-  if (pInterForm->DoAction_Hide(action)) {
-    pDocument->SetChangeMark();
-    return TRUE;
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CPDFSDK_FormActionHandler::DoAction_SubmitForm(
-    const CPDF_Action& action,
-    CPDFSDK_Document* pDocument) {
-  CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)pDocument->GetInterForm();
-  return pInterForm->DoAction_SubmitForm(action);
-}
-
-FX_BOOL CPDFSDK_FormActionHandler::DoAction_ResetForm(
-    const CPDF_Action& action,
-    CPDFSDK_Document* pDocument) {
-  CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)pDocument->GetInterForm();
-  return pInterForm->DoAction_ResetForm(action);
-}
-
-FX_BOOL CPDFSDK_FormActionHandler::DoAction_ImportData(
-    const CPDF_Action& action,
-    CPDFSDK_Document* pDocument) {
-  CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)pDocument->GetInterForm();
-  if (pInterForm->DoAction_ImportData(action)) {
-    pDocument->SetChangeMark();
-    return TRUE;
-  }
-
-  return FALSE;
-}
diff --git a/fpdfsdk/src/fsdk_annothandler.cpp b/fpdfsdk/src/fsdk_annothandler.cpp
deleted file mode 100644
index 08d33a2..0000000
--- a/fpdfsdk/src/fsdk_annothandler.cpp
+++ /dev/null
@@ -1,1180 +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
-
-#include <algorithm>
-
-#include "fpdfsdk/include/formfiller/FFL_FormFiller.h"
-#include "fpdfsdk/include/fsdk_annothandler.h"
-#include "fpdfsdk/include/fsdk_define.h"
-#include "fpdfsdk/include/fsdk_mgr.h"
-
-#ifdef PDF_ENABLE_XFA
-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h"
-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h"
-#endif  // PDF_ENABLE_XFA
-
-CPDFSDK_AnnotHandlerMgr::CPDFSDK_AnnotHandlerMgr(CPDFDoc_Environment* pApp) {
-  m_pApp = pApp;
-
-  CPDFSDK_BFAnnotHandler* pHandler = new CPDFSDK_BFAnnotHandler(m_pApp);
-  pHandler->SetFormFiller(m_pApp->GetIFormFiller());
-  RegisterAnnotHandler(pHandler);
-#ifdef PDF_ENABLE_XFA
-  CPDFSDK_XFAAnnotHandler* pXFAAnnotHandler =
-      new CPDFSDK_XFAAnnotHandler(m_pApp);
-  RegisterAnnotHandler(pXFAAnnotHandler);
-#endif  // PDF_ENABLE_XFA
-}
-
-CPDFSDK_AnnotHandlerMgr::~CPDFSDK_AnnotHandlerMgr() {
-  for (int i = 0; i < m_Handlers.GetSize(); i++) {
-    IPDFSDK_AnnotHandler* pHandler = m_Handlers.GetAt(i);
-    delete pHandler;
-  }
-  m_Handlers.RemoveAll();
-  m_mapType2Handler.clear();
-}
-
-void CPDFSDK_AnnotHandlerMgr::RegisterAnnotHandler(
-    IPDFSDK_AnnotHandler* pAnnotHandler) {
-  ASSERT(!GetAnnotHandler(pAnnotHandler->GetType()));
-
-  m_Handlers.Add(pAnnotHandler);
-  m_mapType2Handler[pAnnotHandler->GetType()] = pAnnotHandler;
-}
-
-void CPDFSDK_AnnotHandlerMgr::UnRegisterAnnotHandler(
-    IPDFSDK_AnnotHandler* pAnnotHandler) {
-  m_mapType2Handler.erase(pAnnotHandler->GetType());
-  for (int i = 0, sz = m_Handlers.GetSize(); i < sz; i++) {
-    if (m_Handlers.GetAt(i) == pAnnotHandler) {
-      m_Handlers.RemoveAt(i);
-      break;
-    }
-  }
-}
-
-CPDFSDK_Annot* CPDFSDK_AnnotHandlerMgr::NewAnnot(CPDF_Annot* pAnnot,
-                                                 CPDFSDK_PageView* pPageView) {
-  ASSERT(pPageView);
-
-  if (IPDFSDK_AnnotHandler* pAnnotHandler =
-          GetAnnotHandler(pAnnot->GetSubType())) {
-    return pAnnotHandler->NewAnnot(pAnnot, pPageView);
-  }
-
-  return new CPDFSDK_BAAnnot(pAnnot, pPageView);
-}
-
-#ifdef PDF_ENABLE_XFA
-CPDFSDK_Annot* CPDFSDK_AnnotHandlerMgr::NewAnnot(IXFA_Widget* pAnnot,
-                                                 CPDFSDK_PageView* pPageView) {
-  ASSERT(pAnnot != NULL);
-  ASSERT(pPageView != NULL);
-
-  if (IPDFSDK_AnnotHandler* pAnnotHandler =
-          GetAnnotHandler(FSDK_XFAWIDGET_TYPENAME)) {
-    return pAnnotHandler->NewAnnot(pAnnot, pPageView);
-  }
-
-  return NULL;
-}
-#endif  // PDF_ENABLE_XFA
-
-void CPDFSDK_AnnotHandlerMgr::ReleaseAnnot(CPDFSDK_Annot* pAnnot) {
-  pAnnot->GetPDFPage();
-
-  if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot)) {
-    pAnnotHandler->OnRelease(pAnnot);
-    pAnnotHandler->ReleaseAnnot(pAnnot);
-  } else {
-    delete (CPDFSDK_Annot*)pAnnot;
-  }
-}
-
-void CPDFSDK_AnnotHandlerMgr::Annot_OnCreate(CPDFSDK_Annot* pAnnot) {
-  CPDF_Annot* pPDFAnnot = pAnnot->GetPDFAnnot();
-
-  CPDFSDK_DateTime curTime;
-  pPDFAnnot->GetAnnotDict()->SetAtString("M", curTime.ToPDFDateTimeString());
-  pPDFAnnot->GetAnnotDict()->SetAtNumber("F", 0);
-
-  if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot)) {
-    pAnnotHandler->OnCreate(pAnnot);
-  }
-}
-
-void CPDFSDK_AnnotHandlerMgr::Annot_OnLoad(CPDFSDK_Annot* pAnnot) {
-  ASSERT(pAnnot);
-
-  if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot)) {
-    pAnnotHandler->OnLoad(pAnnot);
-  }
-}
-
-IPDFSDK_AnnotHandler* CPDFSDK_AnnotHandlerMgr::GetAnnotHandler(
-    CPDFSDK_Annot* pAnnot) const {
-  CPDF_Annot* pPDFAnnot = pAnnot->GetPDFAnnot();
-  if (pPDFAnnot)
-    return GetAnnotHandler(pPDFAnnot->GetSubType());
-#ifdef PDF_ENABLE_XFA
-  if (pAnnot->GetXFAWidget())
-    return GetAnnotHandler(FSDK_XFAWIDGET_TYPENAME);
-#endif  // PDF_ENABLE_XFA
-  return nullptr;
-}
-
-IPDFSDK_AnnotHandler* CPDFSDK_AnnotHandlerMgr::GetAnnotHandler(
-    const CFX_ByteString& sType) const {
-  auto it = m_mapType2Handler.find(sType);
-  return it != m_mapType2Handler.end() ? it->second : nullptr;
-}
-
-void CPDFSDK_AnnotHandlerMgr::Annot_OnDraw(CPDFSDK_PageView* pPageView,
-                                           CPDFSDK_Annot* pAnnot,
-                                           CFX_RenderDevice* pDevice,
-                                           CFX_Matrix* pUser2Device,
-                                           FX_DWORD dwFlags) {
-  ASSERT(pAnnot);
-
-  if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot)) {
-    pAnnotHandler->OnDraw(pPageView, pAnnot, pDevice, pUser2Device, dwFlags);
-  } else {
-#ifdef PDF_ENABLE_XFA
-    if (pAnnot->IsXFAField())
-      return;
-#endif  // PDF_ENABLE_XFA
-    static_cast<CPDFSDK_BAAnnot*>(pAnnot)
-        ->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, nullptr);
-  }
-}
-
-FX_BOOL CPDFSDK_AnnotHandlerMgr::Annot_OnLButtonDown(
-    CPDFSDK_PageView* pPageView,
-    CPDFSDK_Annot* pAnnot,
-    FX_DWORD nFlags,
-    const CPDF_Point& point) {
-  ASSERT(pAnnot);
-
-  if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot)) {
-    return pAnnotHandler->OnLButtonDown(pPageView, pAnnot, nFlags, point);
-  }
-  return FALSE;
-}
-FX_BOOL CPDFSDK_AnnotHandlerMgr::Annot_OnLButtonUp(CPDFSDK_PageView* pPageView,
-                                                   CPDFSDK_Annot* pAnnot,
-                                                   FX_DWORD nFlags,
-                                                   const CPDF_Point& point) {
-  ASSERT(pAnnot);
-
-  if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot)) {
-    return pAnnotHandler->OnLButtonUp(pPageView, pAnnot, nFlags, point);
-  }
-  return FALSE;
-}
-FX_BOOL CPDFSDK_AnnotHandlerMgr::Annot_OnLButtonDblClk(
-    CPDFSDK_PageView* pPageView,
-    CPDFSDK_Annot* pAnnot,
-    FX_DWORD nFlags,
-    const CPDF_Point& point) {
-  ASSERT(pAnnot);
-
-  if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot)) {
-    return pAnnotHandler->OnLButtonDblClk(pPageView, pAnnot, nFlags, point);
-  }
-  return FALSE;
-}
-FX_BOOL CPDFSDK_AnnotHandlerMgr::Annot_OnMouseMove(CPDFSDK_PageView* pPageView,
-                                                   CPDFSDK_Annot* pAnnot,
-                                                   FX_DWORD nFlags,
-                                                   const CPDF_Point& point) {
-  ASSERT(pAnnot);
-
-  if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot)) {
-    return pAnnotHandler->OnMouseMove(pPageView, pAnnot, nFlags, point);
-  }
-  return FALSE;
-}
-FX_BOOL CPDFSDK_AnnotHandlerMgr::Annot_OnMouseWheel(CPDFSDK_PageView* pPageView,
-                                                    CPDFSDK_Annot* pAnnot,
-                                                    FX_DWORD nFlags,
-                                                    short zDelta,
-                                                    const CPDF_Point& point) {
-  ASSERT(pAnnot);
-
-  if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot)) {
-    return pAnnotHandler->OnMouseWheel(pPageView, pAnnot, nFlags, zDelta,
-                                       point);
-  }
-  return FALSE;
-}
-FX_BOOL CPDFSDK_AnnotHandlerMgr::Annot_OnRButtonDown(
-    CPDFSDK_PageView* pPageView,
-    CPDFSDK_Annot* pAnnot,
-    FX_DWORD nFlags,
-    const CPDF_Point& point) {
-  ASSERT(pAnnot);
-
-  if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot)) {
-    return pAnnotHandler->OnRButtonDown(pPageView, pAnnot, nFlags, point);
-  }
-  return FALSE;
-}
-FX_BOOL CPDFSDK_AnnotHandlerMgr::Annot_OnRButtonUp(CPDFSDK_PageView* pPageView,
-                                                   CPDFSDK_Annot* pAnnot,
-                                                   FX_DWORD nFlags,
-                                                   const CPDF_Point& point) {
-  ASSERT(pAnnot);
-
-  if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot)) {
-    return pAnnotHandler->OnRButtonUp(pPageView, pAnnot, nFlags, point);
-  }
-  return FALSE;
-}
-
-void CPDFSDK_AnnotHandlerMgr::Annot_OnMouseEnter(CPDFSDK_PageView* pPageView,
-                                                 CPDFSDK_Annot* pAnnot,
-                                                 FX_DWORD nFlag) {
-  ASSERT(pAnnot);
-
-  if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot)) {
-    pAnnotHandler->OnMouseEnter(pPageView, pAnnot, nFlag);
-  }
-  return;
-}
-
-void CPDFSDK_AnnotHandlerMgr::Annot_OnMouseExit(CPDFSDK_PageView* pPageView,
-                                                CPDFSDK_Annot* pAnnot,
-                                                FX_DWORD nFlag) {
-  ASSERT(pAnnot);
-
-  if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot)) {
-    pAnnotHandler->OnMouseExit(pPageView, pAnnot, nFlag);
-  }
-  return;
-}
-
-FX_BOOL CPDFSDK_AnnotHandlerMgr::Annot_OnChar(CPDFSDK_Annot* pAnnot,
-                                              FX_DWORD nChar,
-                                              FX_DWORD nFlags) {
-  if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot)) {
-    return pAnnotHandler->OnChar(pAnnot, nChar, nFlags);
-  }
-  return FALSE;
-}
-
-FX_BOOL CPDFSDK_AnnotHandlerMgr::Annot_OnKeyDown(CPDFSDK_Annot* pAnnot,
-                                                 int nKeyCode,
-                                                 int nFlag) {
-  if (!m_pApp->FFI_IsCTRLKeyDown(nFlag) && !m_pApp->FFI_IsALTKeyDown(nFlag)) {
-    CPDFSDK_PageView* pPage = pAnnot->GetPageView();
-    CPDFSDK_Annot* pFocusAnnot = pPage->GetFocusAnnot();
-    if (pFocusAnnot && (nKeyCode == FWL_VKEY_Tab)) {
-      CPDFSDK_Annot* pNext =
-          GetNextAnnot(pFocusAnnot, !m_pApp->FFI_IsSHIFTKeyDown(nFlag));
-
-      if (pNext && pNext != pFocusAnnot) {
-        CPDFSDK_Document* pDocument = pPage->GetSDKDocument();
-        pDocument->SetFocusAnnot(pNext);
-        return TRUE;
-      }
-    }
-  }
-
-  if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot)) {
-    return pAnnotHandler->OnKeyDown(pAnnot, nKeyCode, nFlag);
-  }
-  return FALSE;
-}
-FX_BOOL CPDFSDK_AnnotHandlerMgr::Annot_OnKeyUp(CPDFSDK_Annot* pAnnot,
-                                               int nKeyCode,
-                                               int nFlag) {
-  return FALSE;
-}
-
-FX_BOOL CPDFSDK_AnnotHandlerMgr::Annot_OnSetFocus(CPDFSDK_Annot* pAnnot,
-                                                  FX_DWORD nFlag) {
-  ASSERT(pAnnot);
-
-  if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot)) {
-    if (pAnnotHandler->OnSetFocus(pAnnot, nFlag)) {
-      CPDFSDK_PageView* pPage = pAnnot->GetPageView();
-      pPage->GetSDKDocument();
-      return TRUE;
-    }
-  }
-  return FALSE;
-}
-
-FX_BOOL CPDFSDK_AnnotHandlerMgr::Annot_OnKillFocus(CPDFSDK_Annot* pAnnot,
-                                                   FX_DWORD nFlag) {
-  ASSERT(pAnnot);
-  if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot))
-    return pAnnotHandler->OnKillFocus(pAnnot, nFlag);
-
-  return FALSE;
-}
-
-#ifdef PDF_ENABLE_XFA
-FX_BOOL CPDFSDK_AnnotHandlerMgr::Annot_OnChangeFocus(
-    CPDFSDK_Annot* pSetAnnot,
-    CPDFSDK_Annot* pKillAnnot) {
-  FX_BOOL bXFA = (pSetAnnot && pSetAnnot->GetXFAWidget()) ||
-                 (pKillAnnot && pKillAnnot->GetXFAWidget());
-
-  if (bXFA) {
-    if (IPDFSDK_AnnotHandler* pXFAAnnotHandler =
-            GetAnnotHandler(FSDK_XFAWIDGET_TYPENAME))
-      return pXFAAnnotHandler->OnXFAChangedFocus(pKillAnnot, pSetAnnot);
-  }
-
-  return TRUE;
-}
-#endif  // PDF_ENABLE_XFA
-
-CPDF_Rect CPDFSDK_AnnotHandlerMgr::Annot_OnGetViewBBox(
-    CPDFSDK_PageView* pPageView,
-    CPDFSDK_Annot* pAnnot) {
-  ASSERT(pAnnot);
-  if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot))
-    return pAnnotHandler->GetViewBBox(pPageView, pAnnot);
-
-  return pAnnot->GetRect();
-}
-
-FX_BOOL CPDFSDK_AnnotHandlerMgr::Annot_OnHitTest(CPDFSDK_PageView* pPageView,
-                                                 CPDFSDK_Annot* pAnnot,
-                                                 const CPDF_Point& point) {
-  ASSERT(pAnnot);
-  if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot)) {
-    if (pAnnotHandler->CanAnswer(pAnnot))
-      return pAnnotHandler->HitTest(pPageView, pAnnot, point);
-  }
-  return FALSE;
-}
-
-CPDFSDK_Annot* CPDFSDK_AnnotHandlerMgr::GetNextAnnot(CPDFSDK_Annot* pSDKAnnot,
-                                                     FX_BOOL bNext) {
-#ifdef PDF_ENABLE_XFA
-  CPDFSDK_PageView* pPageView = pSDKAnnot->GetPageView();
-  CPDFXFA_Page* pPage = pPageView->GetPDFXFAPage();
-  if (pPage == NULL)
-    return NULL;
-  if (pPage->GetPDFPage()) {  // for pdf annots.
-    CBA_AnnotIterator ai(pSDKAnnot->GetPageView(), pSDKAnnot->GetType(), "");
-    CPDFSDK_Annot* pNext =
-        bNext ? ai.GetNextAnnot(pSDKAnnot) : ai.GetPrevAnnot(pSDKAnnot);
-    return pNext;
-  }
-  // for xfa annots
-  IXFA_WidgetIterator* pWidgetIterator =
-      pPage->GetXFAPageView()->CreateWidgetIterator(
-          XFA_TRAVERSEWAY_Tranvalse, XFA_WIDGETFILTER_Visible |
-                                         XFA_WIDGETFILTER_Viewable |
-                                         XFA_WIDGETFILTER_Field);
-  if (pWidgetIterator == NULL)
-    return NULL;
-  if (pWidgetIterator->GetCurrentWidget() != pSDKAnnot->GetXFAWidget())
-    pWidgetIterator->SetCurrentWidget(pSDKAnnot->GetXFAWidget());
-  IXFA_Widget* hNextFocus = NULL;
-  hNextFocus =
-      bNext ? pWidgetIterator->MoveToNext() : pWidgetIterator->MoveToPrevious();
-  if (hNextFocus == NULL && pSDKAnnot != NULL)
-    hNextFocus = pWidgetIterator->MoveToFirst();
-
-  pWidgetIterator->Release();
-  return pPageView->GetAnnotByXFAWidget(hNextFocus);
-#else   // PDF_ENABLE_XFA
-  CBA_AnnotIterator ai(pSDKAnnot->GetPageView(), "Widget", "");
-  return bNext ? ai.GetNextAnnot(pSDKAnnot) : ai.GetPrevAnnot(pSDKAnnot);
-#endif  // PDF_ENABLE_XFA
-}
-
-FX_BOOL CPDFSDK_BFAnnotHandler::CanAnswer(CPDFSDK_Annot* pAnnot) {
-  ASSERT(pAnnot->GetType() == "Widget");
-  if (pAnnot->GetSubType() == BFFT_SIGNATURE)
-    return FALSE;
-
-  CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
-  if (!pWidget->IsVisible())
-    return FALSE;
-
-  int nFieldFlags = pWidget->GetFieldFlags();
-  if ((nFieldFlags & FIELDFLAG_READONLY) == FIELDFLAG_READONLY)
-    return FALSE;
-
-  if (pWidget->GetFieldType() == FIELDTYPE_PUSHBUTTON)
-    return TRUE;
-
-  CPDF_Page* pPage = pWidget->GetPDFPage();
-  CPDF_Document* pDocument = pPage->m_pDocument;
-  FX_DWORD dwPermissions = pDocument->GetUserPermissions();
-  return (dwPermissions & FPDFPERM_FILL_FORM) ||
-         (dwPermissions & FPDFPERM_ANNOT_FORM);
-}
-
-CPDFSDK_Annot* CPDFSDK_BFAnnotHandler::NewAnnot(CPDF_Annot* pAnnot,
-                                                CPDFSDK_PageView* pPage) {
-  CPDFSDK_Document* pSDKDoc = m_pApp->GetSDKDocument();
-  CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)pSDKDoc->GetInterForm();
-  CPDF_FormControl* pCtrl = CPDFSDK_Widget::GetFormControl(
-      pInterForm->GetInterForm(), pAnnot->GetAnnotDict());
-  if (!pCtrl)
-    return nullptr;
-
-  CPDFSDK_Widget* pWidget = new CPDFSDK_Widget(pAnnot, pPage, pInterForm);
-  pInterForm->AddMap(pCtrl, pWidget);
-  CPDF_InterForm* pPDFInterForm = pInterForm->GetInterForm();
-  if (pPDFInterForm && pPDFInterForm->NeedConstructAP())
-    pWidget->ResetAppearance(nullptr, FALSE);
-
-  return pWidget;
-}
-
-#ifdef PDF_ENABLE_XFA
-CPDFSDK_Annot* CPDFSDK_BFAnnotHandler::NewAnnot(IXFA_Widget* hWidget,
-                                                CPDFSDK_PageView* pPage) {
-  return NULL;
-}
-#endif  // PDF_ENABLE_XFA
-
-void CPDFSDK_BFAnnotHandler::ReleaseAnnot(CPDFSDK_Annot* pAnnot) {
-  ASSERT(pAnnot);
-
-  if (m_pFormFiller)
-    m_pFormFiller->OnDelete(pAnnot);
-
-  CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
-  CPDFSDK_InterForm* pInterForm = pWidget->GetInterForm();
-  CPDF_FormControl* pCtrol = pWidget->GetFormControl();
-  pInterForm->RemoveMap(pCtrol);
-
-  delete pWidget;
-}
-
-void CPDFSDK_BFAnnotHandler::OnDraw(CPDFSDK_PageView* pPageView,
-                                    CPDFSDK_Annot* pAnnot,
-                                    CFX_RenderDevice* pDevice,
-                                    CFX_Matrix* pUser2Device,
-                                    FX_DWORD dwFlags) {
-  CFX_ByteString sSubType = pAnnot->GetSubType();
-
-  if (sSubType == BFFT_SIGNATURE) {
-    static_cast<CPDFSDK_BAAnnot*>(pAnnot)
-        ->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, nullptr);
-  } else {
-    if (m_pFormFiller) {
-      m_pFormFiller->OnDraw(pPageView, pAnnot, pDevice, pUser2Device, dwFlags);
-    }
-  }
-}
-
-void CPDFSDK_BFAnnotHandler::OnMouseEnter(CPDFSDK_PageView* pPageView,
-                                          CPDFSDK_Annot* pAnnot,
-                                          FX_DWORD nFlag) {
-  CFX_ByteString sSubType = pAnnot->GetSubType();
-
-  if (sSubType == BFFT_SIGNATURE) {
-  } else {
-    if (m_pFormFiller)
-      m_pFormFiller->OnMouseEnter(pPageView, pAnnot, nFlag);
-  }
-}
-void CPDFSDK_BFAnnotHandler::OnMouseExit(CPDFSDK_PageView* pPageView,
-                                         CPDFSDK_Annot* pAnnot,
-                                         FX_DWORD nFlag) {
-  CFX_ByteString sSubType = pAnnot->GetSubType();
-
-  if (sSubType == BFFT_SIGNATURE) {
-  } else {
-    if (m_pFormFiller)
-      m_pFormFiller->OnMouseExit(pPageView, pAnnot, nFlag);
-  }
-}
-FX_BOOL CPDFSDK_BFAnnotHandler::OnLButtonDown(CPDFSDK_PageView* pPageView,
-                                              CPDFSDK_Annot* pAnnot,
-                                              FX_DWORD nFlags,
-                                              const CPDF_Point& point) {
-  CFX_ByteString sSubType = pAnnot->GetSubType();
-
-  if (sSubType == BFFT_SIGNATURE) {
-  } else {
-    if (m_pFormFiller)
-      return m_pFormFiller->OnLButtonDown(pPageView, pAnnot, nFlags, point);
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CPDFSDK_BFAnnotHandler::OnLButtonUp(CPDFSDK_PageView* pPageView,
-                                            CPDFSDK_Annot* pAnnot,
-                                            FX_DWORD nFlags,
-                                            const CPDF_Point& point) {
-  CFX_ByteString sSubType = pAnnot->GetSubType();
-
-  if (sSubType == BFFT_SIGNATURE) {
-  } else {
-    if (m_pFormFiller)
-      return m_pFormFiller->OnLButtonUp(pPageView, pAnnot, nFlags, point);
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CPDFSDK_BFAnnotHandler::OnLButtonDblClk(CPDFSDK_PageView* pPageView,
-                                                CPDFSDK_Annot* pAnnot,
-                                                FX_DWORD nFlags,
-                                                const CPDF_Point& point) {
-  CFX_ByteString sSubType = pAnnot->GetSubType();
-
-  if (sSubType == BFFT_SIGNATURE) {
-  } else {
-    if (m_pFormFiller)
-      return m_pFormFiller->OnLButtonDblClk(pPageView, pAnnot, nFlags, point);
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CPDFSDK_BFAnnotHandler::OnMouseMove(CPDFSDK_PageView* pPageView,
-                                            CPDFSDK_Annot* pAnnot,
-                                            FX_DWORD nFlags,
-                                            const CPDF_Point& point) {
-  CFX_ByteString sSubType = pAnnot->GetSubType();
-
-  if (sSubType == BFFT_SIGNATURE) {
-  } else {
-    if (m_pFormFiller)
-      return m_pFormFiller->OnMouseMove(pPageView, pAnnot, nFlags, point);
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CPDFSDK_BFAnnotHandler::OnMouseWheel(CPDFSDK_PageView* pPageView,
-                                             CPDFSDK_Annot* pAnnot,
-                                             FX_DWORD nFlags,
-                                             short zDelta,
-                                             const CPDF_Point& point) {
-  CFX_ByteString sSubType = pAnnot->GetSubType();
-
-  if (sSubType == BFFT_SIGNATURE) {
-  } else {
-    if (m_pFormFiller)
-      return m_pFormFiller->OnMouseWheel(pPageView, pAnnot, nFlags, zDelta,
-                                         point);
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CPDFSDK_BFAnnotHandler::OnRButtonDown(CPDFSDK_PageView* pPageView,
-                                              CPDFSDK_Annot* pAnnot,
-                                              FX_DWORD nFlags,
-                                              const CPDF_Point& point) {
-  CFX_ByteString sSubType = pAnnot->GetSubType();
-
-  if (sSubType == BFFT_SIGNATURE) {
-  } else {
-    if (m_pFormFiller)
-      return m_pFormFiller->OnRButtonDown(pPageView, pAnnot, nFlags, point);
-  }
-
-  return FALSE;
-}
-FX_BOOL CPDFSDK_BFAnnotHandler::OnRButtonUp(CPDFSDK_PageView* pPageView,
-                                            CPDFSDK_Annot* pAnnot,
-                                            FX_DWORD nFlags,
-                                            const CPDF_Point& point) {
-  CFX_ByteString sSubType = pAnnot->GetSubType();
-
-  if (sSubType == BFFT_SIGNATURE) {
-  } else {
-    if (m_pFormFiller)
-      return m_pFormFiller->OnRButtonUp(pPageView, pAnnot, nFlags, point);
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CPDFSDK_BFAnnotHandler::OnChar(CPDFSDK_Annot* pAnnot,
-                                       FX_DWORD nChar,
-                                       FX_DWORD nFlags) {
-  CFX_ByteString sSubType = pAnnot->GetSubType();
-
-  if (sSubType == BFFT_SIGNATURE) {
-  } else {
-    if (m_pFormFiller)
-      return m_pFormFiller->OnChar(pAnnot, nChar, nFlags);
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CPDFSDK_BFAnnotHandler::OnKeyDown(CPDFSDK_Annot* pAnnot,
-                                          int nKeyCode,
-                                          int nFlag) {
-  CFX_ByteString sSubType = pAnnot->GetSubType();
-
-  if (sSubType == BFFT_SIGNATURE) {
-  } else {
-    if (m_pFormFiller)
-      return m_pFormFiller->OnKeyDown(pAnnot, nKeyCode, nFlag);
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CPDFSDK_BFAnnotHandler::OnKeyUp(CPDFSDK_Annot* pAnnot,
-                                        int nKeyCode,
-                                        int nFlag) {
-  return FALSE;
-}
-void CPDFSDK_BFAnnotHandler::OnCreate(CPDFSDK_Annot* pAnnot) {
-  CFX_ByteString sSubType = pAnnot->GetSubType();
-
-  if (sSubType == BFFT_SIGNATURE) {
-  } else {
-    if (m_pFormFiller)
-      m_pFormFiller->OnCreate(pAnnot);
-  }
-}
-
-void CPDFSDK_BFAnnotHandler::OnLoad(CPDFSDK_Annot* pAnnot) {
-  if (pAnnot->GetSubType() == BFFT_SIGNATURE)
-    return;
-
-  CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
-  if (!pWidget->IsAppearanceValid())
-    pWidget->ResetAppearance(NULL, FALSE);
-
-  int nFieldType = pWidget->GetFieldType();
-  if (nFieldType == FIELDTYPE_TEXTFIELD || nFieldType == FIELDTYPE_COMBOBOX) {
-    FX_BOOL bFormated = FALSE;
-    CFX_WideString sValue = pWidget->OnFormat(bFormated);
-    if (bFormated && nFieldType == FIELDTYPE_COMBOBOX) {
-      pWidget->ResetAppearance(sValue.c_str(), FALSE);
-    }
-  }
-
-#ifdef PDF_ENABLE_XFA
-  CPDFSDK_PageView* pPageView = pAnnot->GetPageView();
-  CPDFSDK_Document* pSDKDoc = pPageView->GetSDKDocument();
-  CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
-  if (pDoc->GetDocType() == DOCTYPE_STATIC_XFA) {
-    if (!pWidget->IsAppearanceValid() && !pWidget->GetValue().IsEmpty())
-      pWidget->ResetAppearance(FALSE);
-  }
-#endif  // PDF_ENABLE_XFA
-  if (m_pFormFiller)
-    m_pFormFiller->OnLoad(pAnnot);
-}
-
-FX_BOOL CPDFSDK_BFAnnotHandler::OnSetFocus(CPDFSDK_Annot* pAnnot,
-                                           FX_DWORD nFlag) {
-  CFX_ByteString sSubType = pAnnot->GetSubType();
-
-  if (sSubType == BFFT_SIGNATURE) {
-  } else {
-    if (m_pFormFiller)
-      return m_pFormFiller->OnSetFocus(pAnnot, nFlag);
-  }
-
-  return TRUE;
-}
-FX_BOOL CPDFSDK_BFAnnotHandler::OnKillFocus(CPDFSDK_Annot* pAnnot,
-                                            FX_DWORD nFlag) {
-  CFX_ByteString sSubType = pAnnot->GetSubType();
-
-  if (sSubType == BFFT_SIGNATURE) {
-  } else {
-    if (m_pFormFiller)
-      return m_pFormFiller->OnKillFocus(pAnnot, nFlag);
-  }
-
-  return TRUE;
-}
-
-CPDF_Rect CPDFSDK_BFAnnotHandler::GetViewBBox(CPDFSDK_PageView* pPageView,
-                                              CPDFSDK_Annot* pAnnot) {
-  CFX_ByteString sSubType = pAnnot->GetSubType();
-
-  if (sSubType == BFFT_SIGNATURE) {
-  } else {
-    if (m_pFormFiller)
-      return m_pFormFiller->GetViewBBox(pPageView, pAnnot);
-  }
-
-  return CPDF_Rect(0, 0, 0, 0);
-}
-
-FX_BOOL CPDFSDK_BFAnnotHandler::HitTest(CPDFSDK_PageView* pPageView,
-                                        CPDFSDK_Annot* pAnnot,
-                                        const CPDF_Point& point) {
-  ASSERT(pPageView);
-  ASSERT(pAnnot);
-
-  CPDF_Rect rect = GetViewBBox(pPageView, pAnnot);
-  return rect.Contains(point.x, point.y);
-}
-
-#ifdef PDF_ENABLE_XFA
-#define FWL_WGTHITTEST_Unknown 0
-#define FWL_WGTHITTEST_Client 1     // arrow
-#define FWL_WGTHITTEST_Titlebar 11  // caption
-#define FWL_WGTHITTEST_HScrollBar 15
-#define FWL_WGTHITTEST_VScrollBar 16
-#define FWL_WGTHITTEST_Border 17
-#define FWL_WGTHITTEST_Edit 19
-#define FWL_WGTHITTEST_HyperLink 20
-
-CPDFSDK_XFAAnnotHandler::CPDFSDK_XFAAnnotHandler(CPDFDoc_Environment* pApp)
-    : m_pApp(pApp) {}
-
-CPDFSDK_Annot* CPDFSDK_XFAAnnotHandler::NewAnnot(IXFA_Widget* pAnnot,
-                                                 CPDFSDK_PageView* pPage) {
-  CPDFSDK_Document* pSDKDoc = m_pApp->GetSDKDocument();
-  CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)pSDKDoc->GetInterForm();
-  CPDFSDK_XFAWidget* pWidget = new CPDFSDK_XFAWidget(pAnnot, pPage, pInterForm);
-  pInterForm->AddXFAMap(pAnnot, pWidget);
-  return pWidget;
-}
-
-FX_BOOL CPDFSDK_XFAAnnotHandler::CanAnswer(CPDFSDK_Annot* pAnnot) {
-  return pAnnot->GetXFAWidget() != NULL;
-}
-
-void CPDFSDK_XFAAnnotHandler::OnDraw(CPDFSDK_PageView* pPageView,
-                                     CPDFSDK_Annot* pAnnot,
-                                     CFX_RenderDevice* pDevice,
-                                     CFX_Matrix* pUser2Device,
-                                     FX_DWORD dwFlags) {
-  ASSERT(pPageView != NULL);
-  ASSERT(pAnnot != NULL);
-
-  CPDFSDK_Document* pSDKDoc = pPageView->GetSDKDocument();
-  ASSERT(pSDKDoc != NULL);
-
-  IXFA_WidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
-  ASSERT(pWidgetHandler != NULL);
-
-  CFX_Graphics gs;
-  gs.Create(pDevice);
-
-  CFX_Matrix mt;
-  mt = *(CFX_Matrix*)pUser2Device;
-
-  FX_BOOL bIsHighlight = FALSE;
-  if (pSDKDoc->GetFocusAnnot() != pAnnot)
-    bIsHighlight = TRUE;
-
-  pWidgetHandler->RenderWidget(pAnnot->GetXFAWidget(), &gs, &mt, bIsHighlight);
-
-  // to do highlight and shadow
-}
-
-void CPDFSDK_XFAAnnotHandler::ReleaseAnnot(CPDFSDK_Annot* pAnnot) {
-  ASSERT(pAnnot != NULL);
-
-  CPDFSDK_XFAWidget* pWidget = (CPDFSDK_XFAWidget*)pAnnot;
-  CPDFSDK_InterForm* pInterForm = pWidget->GetInterForm();
-  ASSERT(pInterForm != NULL);
-
-  pInterForm->RemoveXFAMap(pWidget->GetXFAWidget());
-
-  delete pWidget;
-}
-
-CPDF_Rect CPDFSDK_XFAAnnotHandler::GetViewBBox(CPDFSDK_PageView* pPageView,
-                                               CPDFSDK_Annot* pAnnot) {
-  ASSERT(pAnnot != NULL);
-
-  IXFA_WidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
-  ASSERT(pWidgetHandler != NULL);
-
-  CFX_RectF rcBBox;
-  XFA_ELEMENT eType =
-      pWidgetHandler->GetDataAcc(pAnnot->GetXFAWidget())->GetUIType();
-  if (eType == XFA_ELEMENT_Signature)
-    pWidgetHandler->GetBBox(pAnnot->GetXFAWidget(), rcBBox,
-                            XFA_WIDGETSTATUS_Visible, TRUE);
-  else
-    pWidgetHandler->GetBBox(pAnnot->GetXFAWidget(), rcBBox, 0);
-
-  CFX_FloatRect rcWidget(rcBBox.left, rcBBox.top, rcBBox.left + rcBBox.width,
-                         rcBBox.top + rcBBox.height);
-  rcWidget.left -= 1.0f;
-  rcWidget.right += 1.0f;
-  rcWidget.bottom -= 1.0f;
-  rcWidget.top += 1.0f;
-
-  return rcWidget;
-}
-
-FX_BOOL CPDFSDK_XFAAnnotHandler::HitTest(CPDFSDK_PageView* pPageView,
-                                         CPDFSDK_Annot* pAnnot,
-                                         const CPDF_Point& point) {
-  if (!pPageView || !pAnnot)
-    return FALSE;
-
-  CPDFSDK_Document* pSDKDoc = pPageView->GetSDKDocument();
-  if (!pSDKDoc)
-    return FALSE;
-
-  CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
-  if (!pDoc)
-    return FALSE;
-
-  IXFA_DocView* pDocView = pDoc->GetXFADocView();
-  if (!pDocView)
-    return FALSE;
-
-  IXFA_WidgetHandler* pWidgetHandler = pDocView->GetWidgetHandler();
-  if (!pWidgetHandler)
-    return FALSE;
-
-  FX_DWORD dwHitTest =
-      pWidgetHandler->OnHitTest(pAnnot->GetXFAWidget(), point.x, point.y);
-  return (dwHitTest != FWL_WGTHITTEST_Unknown);
-}
-
-void CPDFSDK_XFAAnnotHandler::OnMouseEnter(CPDFSDK_PageView* pPageView,
-                                           CPDFSDK_Annot* pAnnot,
-                                           FX_DWORD nFlag) {
-  if (!pPageView || !pAnnot)
-    return;
-  IXFA_WidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
-  ASSERT(pWidgetHandler != NULL);
-
-  pWidgetHandler->OnMouseEnter(pAnnot->GetXFAWidget());
-}
-
-void CPDFSDK_XFAAnnotHandler::OnMouseExit(CPDFSDK_PageView* pPageView,
-                                          CPDFSDK_Annot* pAnnot,
-                                          FX_DWORD nFlag) {
-  if (!pPageView || !pAnnot)
-    return;
-
-  IXFA_WidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
-  ASSERT(pWidgetHandler != NULL);
-
-  pWidgetHandler->OnMouseExit(pAnnot->GetXFAWidget());
-}
-
-FX_BOOL CPDFSDK_XFAAnnotHandler::OnLButtonDown(CPDFSDK_PageView* pPageView,
-                                               CPDFSDK_Annot* pAnnot,
-                                               FX_DWORD nFlags,
-                                               const CPDF_Point& point) {
-  if (!pPageView || !pAnnot)
-    return FALSE;
-
-  IXFA_WidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
-  ASSERT(pWidgetHandler != NULL);
-
-  FX_BOOL bRet = FALSE;
-  bRet = pWidgetHandler->OnLButtonDown(pAnnot->GetXFAWidget(),
-                                       GetFWLFlags(nFlags), point.x, point.y);
-
-  return bRet;
-}
-
-FX_BOOL CPDFSDK_XFAAnnotHandler::OnLButtonUp(CPDFSDK_PageView* pPageView,
-                                             CPDFSDK_Annot* pAnnot,
-                                             FX_DWORD nFlags,
-                                             const CPDF_Point& point) {
-  if (!pPageView || !pAnnot)
-    return FALSE;
-
-  IXFA_WidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
-  ASSERT(pWidgetHandler != NULL);
-
-  FX_BOOL bRet = FALSE;
-  bRet = pWidgetHandler->OnLButtonUp(pAnnot->GetXFAWidget(),
-                                     GetFWLFlags(nFlags), point.x, point.y);
-
-  return bRet;
-}
-
-FX_BOOL CPDFSDK_XFAAnnotHandler::OnLButtonDblClk(CPDFSDK_PageView* pPageView,
-                                                 CPDFSDK_Annot* pAnnot,
-                                                 FX_DWORD nFlags,
-                                                 const CPDF_Point& point) {
-  if (!pPageView || !pAnnot)
-    return FALSE;
-
-  IXFA_WidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
-  ASSERT(pWidgetHandler != NULL);
-
-  FX_BOOL bRet = FALSE;
-  bRet = pWidgetHandler->OnLButtonDblClk(pAnnot->GetXFAWidget(),
-                                         GetFWLFlags(nFlags), point.x, point.y);
-
-  return bRet;
-}
-
-FX_BOOL CPDFSDK_XFAAnnotHandler::OnMouseMove(CPDFSDK_PageView* pPageView,
-                                             CPDFSDK_Annot* pAnnot,
-                                             FX_DWORD nFlags,
-                                             const CPDF_Point& point) {
-  if (!pPageView || !pAnnot)
-    return FALSE;
-
-  IXFA_WidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
-  ASSERT(pWidgetHandler != NULL);
-
-  FX_BOOL bRet = FALSE;
-  bRet = pWidgetHandler->OnMouseMove(pAnnot->GetXFAWidget(),
-                                     GetFWLFlags(nFlags), point.x, point.y);
-
-  return bRet;
-}
-
-FX_BOOL CPDFSDK_XFAAnnotHandler::OnMouseWheel(CPDFSDK_PageView* pPageView,
-                                              CPDFSDK_Annot* pAnnot,
-                                              FX_DWORD nFlags,
-                                              short zDelta,
-                                              const CPDF_Point& point) {
-  if (!pPageView || !pAnnot)
-    return FALSE;
-
-  IXFA_WidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
-  ASSERT(pWidgetHandler != NULL);
-
-  FX_BOOL bRet = FALSE;
-  bRet = pWidgetHandler->OnMouseWheel(
-      pAnnot->GetXFAWidget(), GetFWLFlags(nFlags), zDelta, point.x, point.y);
-
-  return bRet;
-}
-
-FX_BOOL CPDFSDK_XFAAnnotHandler::OnRButtonDown(CPDFSDK_PageView* pPageView,
-                                               CPDFSDK_Annot* pAnnot,
-                                               FX_DWORD nFlags,
-                                               const CPDF_Point& point) {
-  if (!pPageView || !pAnnot)
-    return FALSE;
-
-  IXFA_WidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
-  ASSERT(pWidgetHandler != NULL);
-
-  FX_BOOL bRet = FALSE;
-  bRet = pWidgetHandler->OnRButtonDown(pAnnot->GetXFAWidget(),
-                                       GetFWLFlags(nFlags), point.x, point.y);
-
-  return bRet;
-}
-
-FX_BOOL CPDFSDK_XFAAnnotHandler::OnRButtonUp(CPDFSDK_PageView* pPageView,
-                                             CPDFSDK_Annot* pAnnot,
-                                             FX_DWORD nFlags,
-                                             const CPDF_Point& point) {
-  if (!pPageView || !pAnnot)
-    return FALSE;
-
-  IXFA_WidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
-  ASSERT(pWidgetHandler != NULL);
-
-  FX_BOOL bRet = FALSE;
-  bRet = pWidgetHandler->OnRButtonUp(pAnnot->GetXFAWidget(),
-                                     GetFWLFlags(nFlags), point.x, point.y);
-
-  return bRet;
-}
-
-FX_BOOL CPDFSDK_XFAAnnotHandler::OnRButtonDblClk(CPDFSDK_PageView* pPageView,
-                                                 CPDFSDK_Annot* pAnnot,
-                                                 FX_DWORD nFlags,
-                                                 const CPDF_Point& point) {
-  if (!pPageView || !pAnnot)
-    return FALSE;
-
-  IXFA_WidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
-  ASSERT(pWidgetHandler != NULL);
-
-  FX_BOOL bRet = FALSE;
-  bRet = pWidgetHandler->OnRButtonDblClk(pAnnot->GetXFAWidget(),
-                                         GetFWLFlags(nFlags), point.x, point.y);
-
-  return bRet;
-}
-
-FX_BOOL CPDFSDK_XFAAnnotHandler::OnChar(CPDFSDK_Annot* pAnnot,
-                                        FX_DWORD nChar,
-                                        FX_DWORD nFlags) {
-  if (!pAnnot)
-    return FALSE;
-
-  IXFA_WidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
-  ASSERT(pWidgetHandler != NULL);
-
-  FX_BOOL bRet = FALSE;
-  bRet = pWidgetHandler->OnChar(pAnnot->GetXFAWidget(), nChar,
-                                GetFWLFlags(nFlags));
-
-  return bRet;
-}
-
-FX_BOOL CPDFSDK_XFAAnnotHandler::OnKeyDown(CPDFSDK_Annot* pAnnot,
-                                           int nKeyCode,
-                                           int nFlag) {
-  if (!pAnnot)
-    return FALSE;
-
-  IXFA_WidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
-  ASSERT(pWidgetHandler != NULL);
-
-  FX_BOOL bRet = FALSE;
-  bRet = pWidgetHandler->OnKeyDown(pAnnot->GetXFAWidget(), nKeyCode,
-                                   GetFWLFlags(nFlag));
-
-  return bRet;
-}
-
-FX_BOOL CPDFSDK_XFAAnnotHandler::OnKeyUp(CPDFSDK_Annot* pAnnot,
-                                         int nKeyCode,
-                                         int nFlag) {
-  if (!pAnnot)
-    return FALSE;
-
-  IXFA_WidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
-  ASSERT(pWidgetHandler != NULL);
-
-  FX_BOOL bRet = FALSE;
-  bRet = pWidgetHandler->OnKeyUp(pAnnot->GetXFAWidget(), nKeyCode,
-                                 GetFWLFlags(nFlag));
-
-  return bRet;
-}
-
-FX_BOOL CPDFSDK_XFAAnnotHandler::OnSetFocus(CPDFSDK_Annot* pAnnot,
-                                            FX_DWORD nFlag) {
-  return TRUE;
-}
-
-FX_BOOL CPDFSDK_XFAAnnotHandler::OnKillFocus(CPDFSDK_Annot* pAnnot,
-                                             FX_DWORD nFlag) {
-  return TRUE;
-}
-
-FX_BOOL CPDFSDK_XFAAnnotHandler::OnXFAChangedFocus(CPDFSDK_Annot* pOldAnnot,
-                                                   CPDFSDK_Annot* pNewAnnot) {
-  IXFA_WidgetHandler* pWidgetHandler = NULL;
-
-  if (pOldAnnot)
-    pWidgetHandler = GetXFAWidgetHandler(pOldAnnot);
-  else if (pNewAnnot)
-    pWidgetHandler = GetXFAWidgetHandler(pNewAnnot);
-
-  if (pWidgetHandler) {
-    FX_BOOL bRet = TRUE;
-    IXFA_Widget* hWidget = pNewAnnot ? pNewAnnot->GetXFAWidget() : NULL;
-    if (hWidget) {
-      IXFA_PageView* pXFAPageView = pWidgetHandler->GetPageView(hWidget);
-      if (pXFAPageView) {
-        bRet = pXFAPageView->GetDocView()->SetFocus(hWidget);
-        if (pXFAPageView->GetDocView()->GetFocusWidget() == hWidget)
-          bRet = TRUE;
-      }
-    }
-    return bRet;
-  }
-
-  return TRUE;
-}
-
-IXFA_WidgetHandler* CPDFSDK_XFAAnnotHandler::GetXFAWidgetHandler(
-    CPDFSDK_Annot* pAnnot) {
-  if (!pAnnot)
-    return NULL;
-
-  CPDFSDK_PageView* pPageView = pAnnot->GetPageView();
-  if (!pPageView)
-    return NULL;
-
-  CPDFSDK_Document* pSDKDoc = pPageView->GetSDKDocument();
-  if (!pSDKDoc)
-    return NULL;
-
-  CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
-  if (!pDoc)
-    return NULL;
-
-  IXFA_DocView* pDocView = pDoc->GetXFADocView();
-  if (!pDocView)
-    return NULL;
-
-  return pDocView->GetWidgetHandler();
-}
-
-#define FWL_KEYFLAG_Ctrl (1 << 0)
-#define FWL_KEYFLAG_Alt (1 << 1)
-#define FWL_KEYFLAG_Shift (1 << 2)
-#define FWL_KEYFLAG_LButton (1 << 3)
-#define FWL_KEYFLAG_RButton (1 << 4)
-#define FWL_KEYFLAG_MButton (1 << 5)
-
-FX_DWORD CPDFSDK_XFAAnnotHandler::GetFWLFlags(FX_DWORD dwFlag) {
-  FX_DWORD dwFWLFlag = 0;
-
-  if (dwFlag & FWL_EVENTFLAG_ControlKey)
-    dwFWLFlag |= FWL_KEYFLAG_Ctrl;
-  if (dwFlag & FWL_EVENTFLAG_LeftButtonDown)
-    dwFWLFlag |= FWL_KEYFLAG_LButton;
-  if (dwFlag & FWL_EVENTFLAG_MiddleButtonDown)
-    dwFWLFlag |= FWL_KEYFLAG_MButton;
-  if (dwFlag & FWL_EVENTFLAG_RightButtonDown)
-    dwFWLFlag |= FWL_KEYFLAG_RButton;
-  if (dwFlag & FWL_EVENTFLAG_ShiftKey)
-    dwFWLFlag |= FWL_KEYFLAG_Shift;
-  if (dwFlag & FWL_EVENTFLAG_AltKey)
-    dwFWLFlag |= FWL_KEYFLAG_Alt;
-
-  return dwFWLFlag;
-}
-#endif  // PDF_ENABLE_XFA
-
-CPDFSDK_AnnotIterator::CPDFSDK_AnnotIterator(CPDFSDK_PageView* pPageView,
-                                             bool bReverse)
-    : m_bReverse(bReverse), m_pos(0) {
-  const std::vector<CPDFSDK_Annot*>& annots = pPageView->GetAnnotList();
-  m_iteratorAnnotList.insert(m_iteratorAnnotList.begin(), annots.rbegin(),
-                             annots.rend());
-  std::stable_sort(m_iteratorAnnotList.begin(), m_iteratorAnnotList.end(),
-                   [](CPDFSDK_Annot* p1, CPDFSDK_Annot* p2) {
-                     return p1->GetLayoutOrder() < p2->GetLayoutOrder();
-                   });
-
-  CPDFSDK_Annot* pTopMostAnnot = pPageView->GetFocusAnnot();
-  if (!pTopMostAnnot)
-    return;
-
-  auto it = std::find(m_iteratorAnnotList.begin(), m_iteratorAnnotList.end(),
-                      pTopMostAnnot);
-  if (it != m_iteratorAnnotList.end()) {
-    CPDFSDK_Annot* pReaderAnnot = *it;
-    m_iteratorAnnotList.erase(it);
-    m_iteratorAnnotList.insert(m_iteratorAnnotList.begin(), pReaderAnnot);
-  }
-}
-
-CPDFSDK_AnnotIterator::~CPDFSDK_AnnotIterator() {
-}
-
-CPDFSDK_Annot* CPDFSDK_AnnotIterator::NextAnnot() {
-  if (m_pos < m_iteratorAnnotList.size())
-    return m_iteratorAnnotList[m_pos++];
-  return nullptr;
-}
-
-CPDFSDK_Annot* CPDFSDK_AnnotIterator::PrevAnnot() {
-  if (m_pos < m_iteratorAnnotList.size())
-    return m_iteratorAnnotList[m_iteratorAnnotList.size() - ++m_pos];
-  return nullptr;
-}
-
-CPDFSDK_Annot* CPDFSDK_AnnotIterator::Next() {
-  return m_bReverse ? PrevAnnot() : NextAnnot();
-}
diff --git a/fpdfsdk/src/fsdk_baseannot.cpp b/fpdfsdk/src/fsdk_baseannot.cpp
deleted file mode 100644
index 30e7022..0000000
--- a/fpdfsdk/src/fsdk_baseannot.cpp
+++ /dev/null
@@ -1,992 +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
-
-#include <algorithm>
-
-#include "core/include/fxcrt/fx_ext.h"
-#include "fpdfsdk/include/fsdk_baseannot.h"
-#include "fpdfsdk/include/fsdk_define.h"
-#include "fpdfsdk/include/fsdk_mgr.h"
-
-#ifdef PDF_ENABLE_XFA
-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h"
-#endif  // PDF_ENABLE_XFA
-
-int _gAfxGetTimeZoneInSeconds(FX_CHAR tzhour, uint8_t tzminute) {
-  return (int)tzhour * 3600 + (int)tzminute * (tzhour >= 0 ? 60 : -60);
-}
-
-FX_BOOL _gAfxIsLeapYear(int16_t year) {
-  return ((year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0)));
-}
-
-FX_WORD _gAfxGetYearDays(int16_t year) {
-  return (_gAfxIsLeapYear(year) == TRUE ? 366 : 365);
-}
-
-uint8_t _gAfxGetMonthDays(int16_t year, uint8_t month) {
-  uint8_t mDays;
-  switch (month) {
-    case 1:
-    case 3:
-    case 5:
-    case 7:
-    case 8:
-    case 10:
-    case 12:
-      mDays = 31;
-      break;
-
-    case 4:
-    case 6:
-    case 9:
-    case 11:
-      mDays = 30;
-      break;
-
-    case 2:
-      if (_gAfxIsLeapYear(year) == TRUE)
-        mDays = 29;
-      else
-        mDays = 28;
-      break;
-
-    default:
-      mDays = 0;
-      break;
-  }
-
-  return mDays;
-}
-
-CPDFSDK_DateTime::CPDFSDK_DateTime() {
-  ResetDateTime();
-}
-
-CPDFSDK_DateTime::CPDFSDK_DateTime(const CFX_ByteString& dtStr) {
-  ResetDateTime();
-
-  FromPDFDateTimeString(dtStr);
-}
-
-CPDFSDK_DateTime::CPDFSDK_DateTime(const CPDFSDK_DateTime& datetime) {
-  operator=(datetime);
-}
-
-CPDFSDK_DateTime::CPDFSDK_DateTime(const FX_SYSTEMTIME& st) {
-  operator=(st);
-}
-
-void CPDFSDK_DateTime::ResetDateTime() {
-  tzset();
-
-  time_t curTime;
-  time(&curTime);
-  struct tm* newtime;
-  // newtime = gmtime(&curTime);
-  newtime = localtime(&curTime);
-
-  dt.year = newtime->tm_year + 1900;
-  dt.month = newtime->tm_mon + 1;
-  dt.day = newtime->tm_mday;
-  dt.hour = newtime->tm_hour;
-  dt.minute = newtime->tm_min;
-  dt.second = newtime->tm_sec;
-  //  dt.tzHour = _timezone / 3600 * -1;
-  //  dt.tzMinute = (abs(_timezone) % 3600) / 60;
-}
-
-CPDFSDK_DateTime& CPDFSDK_DateTime::operator=(
-    const CPDFSDK_DateTime& datetime) {
-  FXSYS_memcpy(&dt, &datetime.dt, sizeof(FX_DATETIME));
-  return *this;
-}
-
-CPDFSDK_DateTime& CPDFSDK_DateTime::operator=(const FX_SYSTEMTIME& st) {
-  tzset();
-
-  dt.year = (int16_t)st.wYear;
-  dt.month = (uint8_t)st.wMonth;
-  dt.day = (uint8_t)st.wDay;
-  dt.hour = (uint8_t)st.wHour;
-  dt.minute = (uint8_t)st.wMinute;
-  dt.second = (uint8_t)st.wSecond;
-  //  dt.tzHour = _timezone / 3600 * -1;
-  //  dt.tzMinute = (abs(_timezone) % 3600) / 60;
-  return *this;
-}
-
-FX_BOOL CPDFSDK_DateTime::operator==(CPDFSDK_DateTime& datetime) {
-  return (FXSYS_memcmp(&dt, &datetime.dt, sizeof(FX_DATETIME)) == 0);
-}
-
-FX_BOOL CPDFSDK_DateTime::operator!=(CPDFSDK_DateTime& datetime) {
-  return (FXSYS_memcmp(&dt, &datetime.dt, sizeof(FX_DATETIME)) != 0);
-}
-
-FX_BOOL CPDFSDK_DateTime::operator>(CPDFSDK_DateTime& datetime) {
-  CPDFSDK_DateTime dt1 = ToGMT();
-  CPDFSDK_DateTime dt2 = datetime.ToGMT();
-  int d1 =
-      (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day;
-  int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) |
-           (int)dt1.dt.second;
-  int d3 =
-      (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day;
-  int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) |
-           (int)dt2.dt.second;
-
-  if (d1 > d3)
-    return TRUE;
-  if (d2 > d4)
-    return TRUE;
-  return FALSE;
-}
-
-FX_BOOL CPDFSDK_DateTime::operator>=(CPDFSDK_DateTime& datetime) {
-  CPDFSDK_DateTime dt1 = ToGMT();
-  CPDFSDK_DateTime dt2 = datetime.ToGMT();
-  int d1 =
-      (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day;
-  int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) |
-           (int)dt1.dt.second;
-  int d3 =
-      (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day;
-  int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) |
-           (int)dt2.dt.second;
-
-  if (d1 >= d3)
-    return TRUE;
-  if (d2 >= d4)
-    return TRUE;
-  return FALSE;
-}
-
-FX_BOOL CPDFSDK_DateTime::operator<(CPDFSDK_DateTime& datetime) {
-  CPDFSDK_DateTime dt1 = ToGMT();
-  CPDFSDK_DateTime dt2 = datetime.ToGMT();
-  int d1 =
-      (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day;
-  int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) |
-           (int)dt1.dt.second;
-  int d3 =
-      (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day;
-  int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) |
-           (int)dt2.dt.second;
-
-  if (d1 < d3)
-    return TRUE;
-  if (d2 < d4)
-    return TRUE;
-  return FALSE;
-}
-
-FX_BOOL CPDFSDK_DateTime::operator<=(CPDFSDK_DateTime& datetime) {
-  CPDFSDK_DateTime dt1 = ToGMT();
-  CPDFSDK_DateTime dt2 = datetime.ToGMT();
-  int d1 =
-      (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day;
-  int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) |
-           (int)dt1.dt.second;
-  int d3 =
-      (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day;
-  int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) |
-           (int)dt2.dt.second;
-
-  if (d1 <= d3)
-    return TRUE;
-  if (d2 <= d4)
-    return TRUE;
-  return FALSE;
-}
-
-CPDFSDK_DateTime::operator time_t() {
-  struct tm newtime;
-
-  newtime.tm_year = dt.year - 1900;
-  newtime.tm_mon = dt.month - 1;
-  newtime.tm_mday = dt.day;
-  newtime.tm_hour = dt.hour;
-  newtime.tm_min = dt.minute;
-  newtime.tm_sec = dt.second;
-
-  return mktime(&newtime);
-}
-
-CPDFSDK_DateTime& CPDFSDK_DateTime::FromPDFDateTimeString(
-    const CFX_ByteString& dtStr) {
-  int strLength = dtStr.GetLength();
-  if (strLength > 0) {
-    int i = 0;
-    int j, k;
-    FX_CHAR ch;
-    while (i < strLength && !std::isdigit(dtStr[i]))
-      ++i;
-
-    if (i >= strLength)
-      return *this;
-
-    j = 0;
-    k = 0;
-    while (i < strLength && j < 4) {
-      ch = dtStr[i];
-      k = k * 10 + FXSYS_toDecimalDigit(ch);
-      j++;
-      if (!std::isdigit(ch))
-        break;
-      i++;
-    }
-    dt.year = (int16_t)k;
-    if (i >= strLength || j < 4)
-      return *this;
-
-    j = 0;
-    k = 0;
-    while (i < strLength && j < 2) {
-      ch = dtStr[i];
-      k = k * 10 + FXSYS_toDecimalDigit(ch);
-      j++;
-      if (!std::isdigit(ch))
-        break;
-      i++;
-    }
-    dt.month = (uint8_t)k;
-    if (i >= strLength || j < 2)
-      return *this;
-
-    j = 0;
-    k = 0;
-    while (i < strLength && j < 2) {
-      ch = dtStr[i];
-      k = k * 10 + FXSYS_toDecimalDigit(ch);
-      j++;
-      if (!std::isdigit(ch))
-        break;
-      i++;
-    }
-    dt.day = (uint8_t)k;
-    if (i >= strLength || j < 2)
-      return *this;
-
-    j = 0;
-    k = 0;
-    while (i < strLength && j < 2) {
-      ch = dtStr[i];
-      k = k * 10 + FXSYS_toDecimalDigit(ch);
-      j++;
-      if (!std::isdigit(ch))
-        break;
-      i++;
-    }
-    dt.hour = (uint8_t)k;
-    if (i >= strLength || j < 2)
-      return *this;
-
-    j = 0;
-    k = 0;
-    while (i < strLength && j < 2) {
-      ch = dtStr[i];
-      k = k * 10 + FXSYS_toDecimalDigit(ch);
-      j++;
-      if (!std::isdigit(ch))
-        break;
-      i++;
-    }
-    dt.minute = (uint8_t)k;
-    if (i >= strLength || j < 2)
-      return *this;
-
-    j = 0;
-    k = 0;
-    while (i < strLength && j < 2) {
-      ch = dtStr[i];
-      k = k * 10 + FXSYS_toDecimalDigit(ch);
-      j++;
-      if (!std::isdigit(ch))
-        break;
-      i++;
-    }
-    dt.second = (uint8_t)k;
-    if (i >= strLength || j < 2)
-      return *this;
-
-    ch = dtStr[i++];
-    if (ch != '-' && ch != '+')
-      return *this;
-    if (ch == '-')
-      dt.tzHour = -1;
-    else
-      dt.tzHour = 1;
-    j = 0;
-    k = 0;
-    while (i < strLength && j < 2) {
-      ch = dtStr[i];
-      k = k * 10 + FXSYS_toDecimalDigit(ch);
-      j++;
-      if (!std::isdigit(ch))
-        break;
-      i++;
-    }
-    dt.tzHour *= (FX_CHAR)k;
-    if (i >= strLength || j < 2)
-      return *this;
-
-    ch = dtStr[i++];
-    if (ch != '\'')
-      return *this;
-    j = 0;
-    k = 0;
-    while (i < strLength && j < 2) {
-      ch = dtStr[i];
-      k = k * 10 + FXSYS_toDecimalDigit(ch);
-      j++;
-      if (!std::isdigit(ch))
-        break;
-      i++;
-    }
-    dt.tzMinute = (uint8_t)k;
-    if (i >= strLength || j < 2)
-      return *this;
-  }
-
-  return *this;
-}
-
-CFX_ByteString CPDFSDK_DateTime::ToCommonDateTimeString() {
-  CFX_ByteString str1;
-  str1.Format("%04d-%02d-%02d %02d:%02d:%02d ", dt.year, dt.month, dt.day,
-              dt.hour, dt.minute, dt.second);
-  if (dt.tzHour < 0)
-    str1 += "-";
-  else
-    str1 += "+";
-  CFX_ByteString str2;
-  str2.Format("%02d:%02d", abs(dt.tzHour), dt.tzMinute);
-  return str1 + str2;
-}
-
-CFX_ByteString CPDFSDK_DateTime::ToPDFDateTimeString() {
-  CFX_ByteString dtStr;
-  char tempStr[32];
-  memset(tempStr, 0, sizeof(tempStr));
-  FXSYS_snprintf(tempStr, sizeof(tempStr) - 1, "D:%04d%02d%02d%02d%02d%02d",
-                 dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second);
-  dtStr = CFX_ByteString(tempStr);
-  if (dt.tzHour < 0)
-    dtStr += CFX_ByteString("-");
-  else
-    dtStr += CFX_ByteString("+");
-  memset(tempStr, 0, sizeof(tempStr));
-  FXSYS_snprintf(tempStr, sizeof(tempStr) - 1, "%02d'%02d'", abs(dt.tzHour),
-                 dt.tzMinute);
-  dtStr += CFX_ByteString(tempStr);
-  return dtStr;
-}
-
-void CPDFSDK_DateTime::ToSystemTime(FX_SYSTEMTIME& st) {
-  CPDFSDK_DateTime dt = *this;
-  time_t t = (time_t)dt;
-  struct tm* pTime = localtime(&t);
-  if (pTime) {
-    st.wYear = (FX_WORD)pTime->tm_year + 1900;
-    st.wMonth = (FX_WORD)pTime->tm_mon + 1;
-    st.wDay = (FX_WORD)pTime->tm_mday;
-    st.wDayOfWeek = (FX_WORD)pTime->tm_wday;
-    st.wHour = (FX_WORD)pTime->tm_hour;
-    st.wMinute = (FX_WORD)pTime->tm_min;
-    st.wSecond = (FX_WORD)pTime->tm_sec;
-    st.wMilliseconds = 0;
-  }
-}
-
-CPDFSDK_DateTime CPDFSDK_DateTime::ToGMT() {
-  CPDFSDK_DateTime dt = *this;
-  dt.AddSeconds(-_gAfxGetTimeZoneInSeconds(dt.dt.tzHour, dt.dt.tzMinute));
-  dt.dt.tzHour = 0;
-  dt.dt.tzMinute = 0;
-  return dt;
-}
-
-CPDFSDK_DateTime& CPDFSDK_DateTime::AddDays(short days) {
-  if (days == 0)
-    return *this;
-
-  int16_t y = dt.year, yy;
-  uint8_t m = dt.month;
-  uint8_t d = dt.day;
-  int mdays, ydays, ldays;
-
-  ldays = days;
-  if (ldays > 0) {
-    yy = y;
-    if (((FX_WORD)m * 100 + d) > 300)
-      yy++;
-    ydays = _gAfxGetYearDays(yy);
-    while (ldays >= ydays) {
-      y++;
-      ldays -= ydays;
-      yy++;
-      mdays = _gAfxGetMonthDays(y, m);
-      if (d > mdays) {
-        m++;
-        d -= mdays;
-      }
-      ydays = _gAfxGetYearDays(yy);
-    }
-    mdays = _gAfxGetMonthDays(y, m) - d + 1;
-    while (ldays >= mdays) {
-      ldays -= mdays;
-      m++;
-      d = 1;
-      mdays = _gAfxGetMonthDays(y, m);
-    }
-    d += ldays;
-  } else {
-    ldays *= -1;
-    yy = y;
-    if (((FX_WORD)m * 100 + d) < 300)
-      yy--;
-    ydays = _gAfxGetYearDays(yy);
-    while (ldays >= ydays) {
-      y--;
-      ldays -= ydays;
-      yy--;
-      mdays = _gAfxGetMonthDays(y, m);
-      if (d > mdays) {
-        m++;
-        d -= mdays;
-      }
-      ydays = _gAfxGetYearDays(yy);
-    }
-    while (ldays >= d) {
-      ldays -= d;
-      m--;
-      mdays = _gAfxGetMonthDays(y, m);
-      d = mdays;
-    }
-    d -= ldays;
-  }
-
-  dt.year = y;
-  dt.month = m;
-  dt.day = d;
-
-  return *this;
-}
-
-CPDFSDK_DateTime& CPDFSDK_DateTime::AddSeconds(int seconds) {
-  if (seconds == 0)
-    return *this;
-
-  int n;
-  int days;
-
-  n = dt.hour * 3600 + dt.minute * 60 + dt.second + seconds;
-  if (n < 0) {
-    days = (n - 86399) / 86400;
-    n -= days * 86400;
-  } else {
-    days = n / 86400;
-    n %= 86400;
-  }
-  dt.hour = (uint8_t)(n / 3600);
-  dt.hour %= 24;
-  n %= 3600;
-  dt.minute = (uint8_t)(n / 60);
-  dt.second = (uint8_t)(n % 60);
-  if (days != 0)
-    AddDays(days);
-
-  return *this;
-}
-
-CPDFSDK_Annot::CPDFSDK_Annot(CPDFSDK_PageView* pPageView)
-    : m_pPageView(pPageView), m_bSelected(FALSE), m_nTabOrder(-1) {
-}
-
-CPDFSDK_BAAnnot::CPDFSDK_BAAnnot(CPDF_Annot* pAnnot,
-                                 CPDFSDK_PageView* pPageView)
-    : CPDFSDK_Annot(pPageView), m_pAnnot(pAnnot) {
-}
-
-CPDF_Annot* CPDFSDK_BAAnnot::GetPDFAnnot() const {
-  return m_pAnnot;
-}
-
-FX_BOOL CPDFSDK_Annot::IsSelected() {
-  return m_bSelected;
-}
-
-void CPDFSDK_Annot::SetSelected(FX_BOOL bSelected) {
-  m_bSelected = bSelected;
-}
-
-// Tab Order
-int CPDFSDK_Annot::GetTabOrder() {
-  return m_nTabOrder;
-}
-
-void CPDFSDK_Annot::SetTabOrder(int iTabOrder) {
-  m_nTabOrder = iTabOrder;
-}
-
-CPDF_Dictionary* CPDFSDK_BAAnnot::GetAnnotDict() const {
-  return m_pAnnot->GetAnnotDict();
-}
-
-void CPDFSDK_BAAnnot::SetRect(const CPDF_Rect& rect) {
-  ASSERT(rect.right - rect.left >= GetMinWidth());
-  ASSERT(rect.top - rect.bottom >= GetMinHeight());
-
-  m_pAnnot->GetAnnotDict()->SetAtRect("Rect", rect);
-}
-
-CPDF_Rect CPDFSDK_BAAnnot::GetRect() const {
-  CPDF_Rect rect;
-  m_pAnnot->GetRect(rect);
-  return rect;
-}
-
-CFX_ByteString CPDFSDK_BAAnnot::GetType() const {
-  return m_pAnnot->GetSubType();
-}
-
-CFX_ByteString CPDFSDK_BAAnnot::GetSubType() const {
-  return "";
-}
-
-void CPDFSDK_BAAnnot::DrawAppearance(CFX_RenderDevice* pDevice,
-                                     const CFX_Matrix* pUser2Device,
-                                     CPDF_Annot::AppearanceMode mode,
-                                     const CPDF_RenderOptions* pOptions) {
-  m_pAnnot->DrawAppearance(m_pPageView->GetPDFPage(), pDevice, pUser2Device,
-                           mode, pOptions);
-}
-
-FX_BOOL CPDFSDK_BAAnnot::IsAppearanceValid() {
-  return m_pAnnot->GetAnnotDict()->GetDict("AP") != NULL;
-}
-
-FX_BOOL CPDFSDK_BAAnnot::IsAppearanceValid(CPDF_Annot::AppearanceMode mode) {
-  CPDF_Dictionary* pAP = m_pAnnot->GetAnnotDict()->GetDict("AP");
-  if (!pAP)
-    return FALSE;
-
-  // Choose the right sub-ap
-  const FX_CHAR* ap_entry = "N";
-  if (mode == CPDF_Annot::Down)
-    ap_entry = "D";
-  else if (mode == CPDF_Annot::Rollover)
-    ap_entry = "R";
-  if (!pAP->KeyExist(ap_entry))
-    ap_entry = "N";
-
-  // Get the AP stream or subdirectory
-  CPDF_Object* psub = pAP->GetElementValue(ap_entry);
-  return !!psub;
-}
-
-void CPDFSDK_BAAnnot::DrawBorder(CFX_RenderDevice* pDevice,
-                                 const CFX_Matrix* pUser2Device,
-                                 const CPDF_RenderOptions* pOptions) {
-  m_pAnnot->DrawBorder(pDevice, pUser2Device, pOptions);
-}
-
-void CPDFSDK_BAAnnot::ClearCachedAP() {
-  m_pAnnot->ClearCachedAP();
-}
-
-void CPDFSDK_BAAnnot::SetContents(const CFX_WideString& sContents) {
-  if (sContents.IsEmpty())
-    m_pAnnot->GetAnnotDict()->RemoveAt("Contents");
-  else
-    m_pAnnot->GetAnnotDict()->SetAtString("Contents",
-                                          PDF_EncodeText(sContents));
-}
-
-CFX_WideString CPDFSDK_BAAnnot::GetContents() const {
-  return m_pAnnot->GetAnnotDict()->GetUnicodeText("Contents");
-}
-
-void CPDFSDK_BAAnnot::SetAnnotName(const CFX_WideString& sName) {
-  if (sName.IsEmpty())
-    m_pAnnot->GetAnnotDict()->RemoveAt("NM");
-  else
-    m_pAnnot->GetAnnotDict()->SetAtString("NM", PDF_EncodeText(sName));
-}
-
-CFX_WideString CPDFSDK_BAAnnot::GetAnnotName() const {
-  return m_pAnnot->GetAnnotDict()->GetUnicodeText("NM");
-}
-
-void CPDFSDK_BAAnnot::SetModifiedDate(const FX_SYSTEMTIME& st) {
-  CPDFSDK_DateTime dt(st);
-  CFX_ByteString str = dt.ToPDFDateTimeString();
-
-  if (str.IsEmpty())
-    m_pAnnot->GetAnnotDict()->RemoveAt("M");
-  else
-    m_pAnnot->GetAnnotDict()->SetAtString("M", str);
-}
-
-FX_SYSTEMTIME CPDFSDK_BAAnnot::GetModifiedDate() const {
-  FX_SYSTEMTIME systime;
-  CFX_ByteString str = m_pAnnot->GetAnnotDict()->GetString("M");
-
-  CPDFSDK_DateTime dt(str);
-  dt.ToSystemTime(systime);
-
-  return systime;
-}
-
-void CPDFSDK_BAAnnot::SetFlags(int nFlags) {
-  m_pAnnot->GetAnnotDict()->SetAtInteger("F", nFlags);
-}
-
-int CPDFSDK_BAAnnot::GetFlags() const {
-  return m_pAnnot->GetAnnotDict()->GetInteger("F");
-}
-
-void CPDFSDK_BAAnnot::SetAppState(const CFX_ByteString& str) {
-  if (str.IsEmpty())
-    m_pAnnot->GetAnnotDict()->RemoveAt("AS");
-  else
-    m_pAnnot->GetAnnotDict()->SetAtString("AS", str);
-}
-
-CFX_ByteString CPDFSDK_BAAnnot::GetAppState() const {
-  return m_pAnnot->GetAnnotDict()->GetString("AS");
-}
-
-void CPDFSDK_BAAnnot::SetStructParent(int key) {
-  m_pAnnot->GetAnnotDict()->SetAtInteger("StructParent", key);
-}
-
-int CPDFSDK_BAAnnot::GetStructParent() const {
-  return m_pAnnot->GetAnnotDict()->GetInteger("StructParent");
-}
-
-// border
-void CPDFSDK_BAAnnot::SetBorderWidth(int nWidth) {
-  CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArray("Border");
-
-  if (pBorder) {
-    pBorder->SetAt(2, new CPDF_Number(nWidth));
-  } else {
-    CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDict("BS");
-
-    if (!pBSDict) {
-      pBSDict = new CPDF_Dictionary;
-      m_pAnnot->GetAnnotDict()->SetAt("BS", pBSDict);
-    }
-
-    pBSDict->SetAtInteger("W", nWidth);
-  }
-}
-
-int CPDFSDK_BAAnnot::GetBorderWidth() const {
-  if (CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArray("Border")) {
-    return pBorder->GetInteger(2);
-  }
-  if (CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDict("BS")) {
-    return pBSDict->GetInteger("W", 1);
-  }
-  return 1;
-}
-
-void CPDFSDK_BAAnnot::SetBorderStyle(int nStyle) {
-  CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDict("BS");
-  if (!pBSDict) {
-    pBSDict = new CPDF_Dictionary;
-    m_pAnnot->GetAnnotDict()->SetAt("BS", pBSDict);
-  }
-
-  switch (nStyle) {
-    case BBS_SOLID:
-      pBSDict->SetAtName("S", "S");
-      break;
-    case BBS_DASH:
-      pBSDict->SetAtName("S", "D");
-      break;
-    case BBS_BEVELED:
-      pBSDict->SetAtName("S", "B");
-      break;
-    case BBS_INSET:
-      pBSDict->SetAtName("S", "I");
-      break;
-    case BBS_UNDERLINE:
-      pBSDict->SetAtName("S", "U");
-      break;
-  }
-}
-
-int CPDFSDK_BAAnnot::GetBorderStyle() const {
-  CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDict("BS");
-  if (pBSDict) {
-    CFX_ByteString sBorderStyle = pBSDict->GetString("S", "S");
-    if (sBorderStyle == "S")
-      return BBS_SOLID;
-    if (sBorderStyle == "D")
-      return BBS_DASH;
-    if (sBorderStyle == "B")
-      return BBS_BEVELED;
-    if (sBorderStyle == "I")
-      return BBS_INSET;
-    if (sBorderStyle == "U")
-      return BBS_UNDERLINE;
-  }
-
-  CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArray("Border");
-  if (pBorder) {
-    if (pBorder->GetCount() >= 4) {
-      CPDF_Array* pDP = pBorder->GetArray(3);
-      if (pDP && pDP->GetCount() > 0)
-        return BBS_DASH;
-    }
-  }
-
-  return BBS_SOLID;
-}
-
-void CPDFSDK_BAAnnot::SetBorderDash(const CFX_IntArray& array) {
-  CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDict("BS");
-  if (!pBSDict) {
-    pBSDict = new CPDF_Dictionary;
-    m_pAnnot->GetAnnotDict()->SetAt("BS", pBSDict);
-  }
-
-  CPDF_Array* pArray = new CPDF_Array;
-  for (int i = 0, sz = array.GetSize(); i < sz; i++) {
-    pArray->AddInteger(array[i]);
-  }
-
-  pBSDict->SetAt("D", pArray);
-}
-
-void CPDFSDK_BAAnnot::GetBorderDash(CFX_IntArray& array) const {
-  CPDF_Array* pDash = NULL;
-
-  CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArray("Border");
-  if (pBorder) {
-    pDash = pBorder->GetArray(3);
-  } else {
-    CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDict("BS");
-    if (pBSDict) {
-      pDash = pBSDict->GetArray("D");
-    }
-  }
-
-  if (pDash) {
-    for (int i = 0, sz = pDash->GetCount(); i < sz; i++) {
-      array.Add(pDash->GetInteger(i));
-    }
-  }
-}
-
-void CPDFSDK_BAAnnot::SetColor(FX_COLORREF color) {
-  CPDF_Array* pArray = new CPDF_Array;
-  pArray->AddNumber((FX_FLOAT)FXSYS_GetRValue(color) / 255.0f);
-  pArray->AddNumber((FX_FLOAT)FXSYS_GetGValue(color) / 255.0f);
-  pArray->AddNumber((FX_FLOAT)FXSYS_GetBValue(color) / 255.0f);
-  m_pAnnot->GetAnnotDict()->SetAt("C", pArray);
-}
-
-void CPDFSDK_BAAnnot::RemoveColor() {
-  m_pAnnot->GetAnnotDict()->RemoveAt("C");
-}
-
-FX_BOOL CPDFSDK_BAAnnot::GetColor(FX_COLORREF& color) const {
-  if (CPDF_Array* pEntry = m_pAnnot->GetAnnotDict()->GetArray("C")) {
-    int nCount = pEntry->GetCount();
-    if (nCount == 1) {
-      FX_FLOAT g = pEntry->GetNumber(0) * 255;
-
-      color = FXSYS_RGB((int)g, (int)g, (int)g);
-
-      return TRUE;
-    } else if (nCount == 3) {
-      FX_FLOAT r = pEntry->GetNumber(0) * 255;
-      FX_FLOAT g = pEntry->GetNumber(1) * 255;
-      FX_FLOAT b = pEntry->GetNumber(2) * 255;
-
-      color = FXSYS_RGB((int)r, (int)g, (int)b);
-
-      return TRUE;
-    } else if (nCount == 4) {
-      FX_FLOAT c = pEntry->GetNumber(0);
-      FX_FLOAT m = pEntry->GetNumber(1);
-      FX_FLOAT y = pEntry->GetNumber(2);
-      FX_FLOAT k = pEntry->GetNumber(3);
-
-      FX_FLOAT r = 1.0f - std::min(1.0f, c + k);
-      FX_FLOAT g = 1.0f - std::min(1.0f, m + k);
-      FX_FLOAT b = 1.0f - std::min(1.0f, y + k);
-
-      color = FXSYS_RGB((int)(r * 255), (int)(g * 255), (int)(b * 255));
-
-      return TRUE;
-    }
-  }
-
-  return FALSE;
-}
-
-void CPDFSDK_BAAnnot::WriteAppearance(const CFX_ByteString& sAPType,
-                                      const CPDF_Rect& rcBBox,
-                                      const CFX_Matrix& matrix,
-                                      const CFX_ByteString& sContents,
-                                      const CFX_ByteString& sAPState) {
-  CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDict("AP");
-
-  if (!pAPDict) {
-    pAPDict = new CPDF_Dictionary;
-    m_pAnnot->GetAnnotDict()->SetAt("AP", pAPDict);
-  }
-
-  CPDF_Stream* pStream = nullptr;
-  CPDF_Dictionary* pParentDict = nullptr;
-
-  if (sAPState.IsEmpty()) {
-    pParentDict = pAPDict;
-    pStream = pAPDict->GetStream(sAPType);
-  } else {
-    CPDF_Dictionary* pAPTypeDict = pAPDict->GetDict(sAPType);
-    if (!pAPTypeDict) {
-      pAPTypeDict = new CPDF_Dictionary;
-      pAPDict->SetAt(sAPType, pAPTypeDict);
-    }
-
-    pParentDict = pAPTypeDict;
-    pStream = pAPTypeDict->GetStream(sAPState);
-  }
-
-  if (!pStream) {
-    pStream = new CPDF_Stream(nullptr, 0, nullptr);
-
-    CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
-    int32_t objnum = pDoc->AddIndirectObject(pStream);
-    pParentDict->SetAtReference(sAPType, pDoc, objnum);
-  }
-
-  CPDF_Dictionary* pStreamDict = pStream->GetDict();
-  if (!pStreamDict) {
-    pStreamDict = new CPDF_Dictionary;
-    pStreamDict->SetAtName("Type", "XObject");
-    pStreamDict->SetAtName("Subtype", "Form");
-    pStreamDict->SetAtInteger("FormType", 1);
-    pStream->InitStream(nullptr, 0, pStreamDict);
-  }
-
-  if (pStreamDict) {
-    pStreamDict->SetAtMatrix("Matrix", matrix);
-    pStreamDict->SetAtRect("BBox", rcBBox);
-  }
-
-  pStream->SetData((uint8_t*)sContents.c_str(), sContents.GetLength(), FALSE,
-                   FALSE);
-}
-
-#define BA_ANNOT_MINWIDTH 1
-#define BA_ANNOT_MINHEIGHT 1
-
-FX_FLOAT CPDFSDK_Annot::GetMinWidth() const {
-  return BA_ANNOT_MINWIDTH;
-}
-
-FX_FLOAT CPDFSDK_Annot::GetMinHeight() const {
-  return BA_ANNOT_MINHEIGHT;
-}
-
-FX_BOOL CPDFSDK_BAAnnot::CreateFormFiller() {
-  return TRUE;
-}
-FX_BOOL CPDFSDK_BAAnnot::IsVisible() const {
-  int nFlags = GetFlags();
-  return !((nFlags & ANNOTFLAG_INVISIBLE) || (nFlags & ANNOTFLAG_HIDDEN) ||
-           (nFlags & ANNOTFLAG_NOVIEW));
-}
-
-CPDF_Action CPDFSDK_BAAnnot::GetAction() const {
-  return CPDF_Action(m_pAnnot->GetAnnotDict()->GetDict("A"));
-}
-
-void CPDFSDK_BAAnnot::SetAction(const CPDF_Action& action) {
-  ASSERT(action);
-  if ((CPDF_Action&)action !=
-      CPDF_Action(m_pAnnot->GetAnnotDict()->GetDict("A"))) {
-    CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
-    CPDF_Dictionary* pDict = action.GetDict();
-    if (pDict && pDict->GetObjNum() == 0) {
-      pDoc->AddIndirectObject(pDict);
-    }
-    m_pAnnot->GetAnnotDict()->SetAtReference("A", pDoc, pDict->GetObjNum());
-  }
-}
-
-void CPDFSDK_BAAnnot::RemoveAction() {
-  m_pAnnot->GetAnnotDict()->RemoveAt("A");
-}
-
-CPDF_AAction CPDFSDK_BAAnnot::GetAAction() const {
-  return m_pAnnot->GetAnnotDict()->GetDict("AA");
-}
-
-void CPDFSDK_BAAnnot::SetAAction(const CPDF_AAction& aa) {
-  if ((CPDF_AAction&)aa != m_pAnnot->GetAnnotDict()->GetDict("AA"))
-    m_pAnnot->GetAnnotDict()->SetAt("AA", (CPDF_AAction&)aa);
-}
-
-void CPDFSDK_BAAnnot::RemoveAAction() {
-  m_pAnnot->GetAnnotDict()->RemoveAt("AA");
-}
-
-CPDF_Action CPDFSDK_BAAnnot::GetAAction(CPDF_AAction::AActionType eAAT) {
-  CPDF_AAction AAction = GetAAction();
-
-  if (AAction.ActionExist(eAAT))
-    return AAction.GetAction(eAAT);
-
-  if (eAAT == CPDF_AAction::ButtonUp)
-    return GetAction();
-
-  return CPDF_Action();
-}
-
-#ifdef PDF_ENABLE_XFA
-FX_BOOL CPDFSDK_BAAnnot::IsXFAField() {
-  return FALSE;
-}
-#endif  // PDF_ENABLE_XFA
-
-void CPDFSDK_BAAnnot::Annot_OnDraw(CFX_RenderDevice* pDevice,
-                                   CFX_Matrix* pUser2Device,
-                                   CPDF_RenderOptions* pOptions) {
-  m_pAnnot->GetAPForm(m_pPageView->GetPDFPage(), CPDF_Annot::Normal);
-  m_pAnnot->DrawAppearance(m_pPageView->GetPDFPage(), pDevice, pUser2Device,
-                           CPDF_Annot::Normal, NULL);
-}
-
-UnderlyingPageType* CPDFSDK_Annot::GetUnderlyingPage() {
-#ifdef PDF_ENABLE_XFA
-  return GetPDFXFAPage();
-#else   // PDF_ENABLE_XFA
-  return GetPDFPage();
-#endif  // PDF_ENABLE_XFA
-}
-
-CPDF_Page* CPDFSDK_Annot::GetPDFPage() {
-  if (m_pPageView)
-    return m_pPageView->GetPDFPage();
-  return NULL;
-}
-
-#ifdef PDF_ENABLE_XFA
-CPDFXFA_Page* CPDFSDK_Annot::GetPDFXFAPage() {
-  if (m_pPageView)
-    return m_pPageView->GetPDFXFAPage();
-  return NULL;
-}
-#endif  // PDF_ENABLE_XFA
diff --git a/fpdfsdk/src/fsdk_baseform.cpp b/fpdfsdk/src/fsdk_baseform.cpp
deleted file mode 100644
index 66e8434..0000000
--- a/fpdfsdk/src/fsdk_baseform.cpp
+++ /dev/null
@@ -1,2963 +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
-
-#include "fpdfsdk/include/fsdk_baseform.h"
-
-#include <memory>
-
-#include "fpdfsdk/include/formfiller/FFL_FormFiller.h"
-#include "fpdfsdk/include/fsdk_actionhandler.h"
-#include "fpdfsdk/include/fsdk_baseannot.h"
-#include "fpdfsdk/include/fsdk_define.h"
-#include "fpdfsdk/include/fsdk_mgr.h"
-#include "fpdfsdk/include/javascript/IJavaScript.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
-
-#ifdef PDF_ENABLE_XFA
-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h"
-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h"
-#endif  // PDF_ENABLE_XFA
-
-#define IsFloatZero(f) ((f) < 0.01 && (f) > -0.01)
-#define IsFloatBigger(fa, fb) ((fa) > (fb) && !IsFloatZero((fa) - (fb)))
-#define IsFloatSmaller(fa, fb) ((fa) < (fb) && !IsFloatZero((fa) - (fb)))
-#define IsFloatEqual(fa, fb) IsFloatZero((fa) - (fb))
-
-CPDFSDK_Widget::CPDFSDK_Widget(CPDF_Annot* pAnnot,
-                               CPDFSDK_PageView* pPageView,
-                               CPDFSDK_InterForm* pInterForm)
-    : CPDFSDK_BAAnnot(pAnnot, pPageView),
-      m_pInterForm(pInterForm),
-      m_nAppAge(0),
-      m_nValueAge(0)
-#ifdef PDF_ENABLE_XFA
-      ,
-      m_hMixXFAWidget(NULL),
-      m_pWidgetHandler(NULL)
-#endif  // PDF_ENABLE_XFA
-{
-}
-
-CPDFSDK_Widget::~CPDFSDK_Widget() {}
-
-#ifdef PDF_ENABLE_XFA
-IXFA_Widget* CPDFSDK_Widget::GetMixXFAWidget() const {
-  CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
-  CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
-  if (pDoc->GetDocType() == DOCTYPE_STATIC_XFA) {
-    if (!m_hMixXFAWidget) {
-      if (IXFA_DocView* pDocView = pDoc->GetXFADocView()) {
-        CFX_WideString sName;
-        if (this->GetFieldType() == FIELDTYPE_RADIOBUTTON) {
-          sName = this->GetAnnotName();
-          if (sName.IsEmpty())
-            sName = GetName();
-        } else
-          sName = GetName();
-
-        if (!sName.IsEmpty())
-          m_hMixXFAWidget = pDocView->GetWidgetByName(sName);
-      }
-    }
-    return m_hMixXFAWidget;
-  }
-
-  return NULL;
-}
-
-IXFA_Widget* CPDFSDK_Widget::GetGroupMixXFAWidget() {
-  CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
-  CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
-  if (pDoc->GetDocType() == DOCTYPE_STATIC_XFA) {
-    if (IXFA_DocView* pDocView = pDoc->GetXFADocView()) {
-      CFX_WideString sName = GetName();
-      if (!sName.IsEmpty())
-        return pDocView->GetWidgetByName(sName);
-    }
-  }
-
-  return nullptr;
-}
-
-IXFA_WidgetHandler* CPDFSDK_Widget::GetXFAWidgetHandler() const {
-  CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
-  CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
-  if (pDoc->GetDocType() == DOCTYPE_STATIC_XFA) {
-    if (!m_pWidgetHandler) {
-      if (IXFA_DocView* pDocView = pDoc->GetXFADocView()) {
-        m_pWidgetHandler = pDocView->GetWidgetHandler();
-      }
-    }
-    return m_pWidgetHandler;
-  }
-
-  return NULL;
-}
-
-static XFA_EVENTTYPE GetXFAEventType(PDFSDK_XFAAActionType eXFAAAT) {
-  XFA_EVENTTYPE eEventType = XFA_EVENT_Unknown;
-
-  switch (eXFAAAT) {
-    case PDFSDK_XFA_Click:
-      eEventType = XFA_EVENT_Click;
-      break;
-    case PDFSDK_XFA_Full:
-      eEventType = XFA_EVENT_Full;
-      break;
-    case PDFSDK_XFA_PreOpen:
-      eEventType = XFA_EVENT_PreOpen;
-      break;
-    case PDFSDK_XFA_PostOpen:
-      eEventType = XFA_EVENT_PostOpen;
-      break;
-  }
-
-  return eEventType;
-}
-
-static XFA_EVENTTYPE GetXFAEventType(CPDF_AAction::AActionType eAAT,
-                                     FX_BOOL bWillCommit) {
-  XFA_EVENTTYPE eEventType = XFA_EVENT_Unknown;
-
-  switch (eAAT) {
-    case CPDF_AAction::CursorEnter:
-      eEventType = XFA_EVENT_MouseEnter;
-      break;
-    case CPDF_AAction::CursorExit:
-      eEventType = XFA_EVENT_MouseExit;
-      break;
-    case CPDF_AAction::ButtonDown:
-      eEventType = XFA_EVENT_MouseDown;
-      break;
-    case CPDF_AAction::ButtonUp:
-      eEventType = XFA_EVENT_MouseUp;
-      break;
-    case CPDF_AAction::GetFocus:
-      eEventType = XFA_EVENT_Enter;
-      break;
-    case CPDF_AAction::LoseFocus:
-      eEventType = XFA_EVENT_Exit;
-      break;
-    case CPDF_AAction::PageOpen:
-      break;
-    case CPDF_AAction::PageClose:
-      break;
-    case CPDF_AAction::PageVisible:
-      break;
-    case CPDF_AAction::PageInvisible:
-      break;
-    case CPDF_AAction::KeyStroke:
-      if (!bWillCommit) {
-        eEventType = XFA_EVENT_Change;
-      }
-      break;
-    case CPDF_AAction::Validate:
-      eEventType = XFA_EVENT_Validate;
-      break;
-    case CPDF_AAction::OpenPage:
-    case CPDF_AAction::ClosePage:
-    case CPDF_AAction::Format:
-    case CPDF_AAction::Calculate:
-    case CPDF_AAction::CloseDocument:
-    case CPDF_AAction::SaveDocument:
-    case CPDF_AAction::DocumentSaved:
-    case CPDF_AAction::PrintDocument:
-    case CPDF_AAction::DocumentPrinted:
-      break;
-  }
-
-  return eEventType;
-}
-
-FX_BOOL CPDFSDK_Widget::HasXFAAAction(PDFSDK_XFAAActionType eXFAAAT) {
-  if (IXFA_Widget* hWidget = this->GetMixXFAWidget()) {
-    if (IXFA_WidgetHandler* pXFAWidgetHandler = this->GetXFAWidgetHandler()) {
-      XFA_EVENTTYPE eEventType = GetXFAEventType(eXFAAAT);
-
-      if ((eEventType == XFA_EVENT_Click || eEventType == XFA_EVENT_Change) &&
-          GetFieldType() == FIELDTYPE_RADIOBUTTON) {
-        if (IXFA_Widget* hGroupWidget = GetGroupMixXFAWidget()) {
-          CXFA_WidgetAcc* pAcc = pXFAWidgetHandler->GetDataAcc(hGroupWidget);
-          if (pXFAWidgetHandler->HasEvent(pAcc, eEventType))
-            return TRUE;
-        }
-      }
-
-      {
-        CXFA_WidgetAcc* pAcc = pXFAWidgetHandler->GetDataAcc(hWidget);
-        return pXFAWidgetHandler->HasEvent(pAcc, eEventType);
-      }
-    }
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CPDFSDK_Widget::OnXFAAAction(PDFSDK_XFAAActionType eXFAAAT,
-                                     PDFSDK_FieldAction& data,
-                                     CPDFSDK_PageView* pPageView) {
-  CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
-  CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
-  if (IXFA_Widget* hWidget = GetMixXFAWidget()) {
-    XFA_EVENTTYPE eEventType = GetXFAEventType(eXFAAAT);
-
-    if (eEventType != XFA_EVENT_Unknown) {
-      if (IXFA_WidgetHandler* pXFAWidgetHandler = this->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;
-
-        if ((eEventType == XFA_EVENT_Click || eEventType == XFA_EVENT_Change) &&
-            GetFieldType() == FIELDTYPE_RADIOBUTTON) {
-          if (IXFA_Widget* hGroupWidget = GetGroupMixXFAWidget()) {
-            CXFA_WidgetAcc* pAcc = pXFAWidgetHandler->GetDataAcc(hGroupWidget);
-            param.m_pTarget = pAcc;
-            pXFAWidgetHandler->ProcessEvent(pAcc, &param);
-          }
-
-          {
-            CXFA_WidgetAcc* pAcc = pXFAWidgetHandler->GetDataAcc(hWidget);
-            param.m_pTarget = pAcc;
-            int32_t nRet = pXFAWidgetHandler->ProcessEvent(pAcc, &param);
-            return nRet == XFA_EVENTERROR_Sucess;
-          }
-        } else {
-          CXFA_WidgetAcc* pAcc = pXFAWidgetHandler->GetDataAcc(hWidget);
-          param.m_pTarget = pAcc;
-          int32_t nRet = pXFAWidgetHandler->ProcessEvent(pAcc, &param);
-          return nRet == XFA_EVENTERROR_Sucess;
-        }
-
-        if (IXFA_DocView* pDocView = pDoc->GetXFADocView()) {
-          pDocView->UpdateDocView();
-        }
-      }
-    }
-  }
-
-  return FALSE;
-}
-
-void CPDFSDK_Widget::Synchronize(FX_BOOL bSynchronizeElse) {
-  if (IXFA_Widget* hWidget = this->GetMixXFAWidget()) {
-    if (IXFA_WidgetHandler* pXFAWidgetHandler = this->GetXFAWidgetHandler()) {
-      CPDF_FormField* pFormField = GetFormField();
-      ASSERT(pFormField != NULL);
-
-      if (CXFA_WidgetAcc* pWidgetAcc = pXFAWidgetHandler->GetDataAcc(hWidget)) {
-        switch (GetFieldType()) {
-          case FIELDTYPE_CHECKBOX:
-          case FIELDTYPE_RADIOBUTTON: {
-            CPDF_FormControl* pFormCtrl = GetFormControl();
-            ASSERT(pFormCtrl != NULL);
-
-            XFA_CHECKSTATE eCheckState =
-                pFormCtrl->IsChecked() ? XFA_CHECKSTATE_On : XFA_CHECKSTATE_Off;
-            pWidgetAcc->SetCheckState(eCheckState);
-          } break;
-          case FIELDTYPE_TEXTFIELD:
-            pWidgetAcc->SetValue(pFormField->GetValue(), XFA_VALUEPICTURE_Edit);
-            break;
-          case FIELDTYPE_LISTBOX: {
-            pWidgetAcc->ClearAllSelections();
-
-            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);
-            }
-          } break;
-          case FIELDTYPE_COMBOBOX: {
-            pWidgetAcc->ClearAllSelections();
-
-            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);
-            }
-          }
-
-            pWidgetAcc->SetValue(pFormField->GetValue(), XFA_VALUEPICTURE_Edit);
-            break;
-        }
-
-        if (bSynchronizeElse)
-          pWidgetAcc->ProcessValueChanged();
-      }
-    }
-  }
-}
-
-void CPDFSDK_Widget::SynchronizeXFAValue() {
-  CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
-  CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
-  IXFA_DocView* pXFADocView = pDoc->GetXFADocView();
-  if (!pXFADocView)
-    return;
-
-  if (IXFA_Widget* hWidget = GetMixXFAWidget()) {
-    if (GetXFAWidgetHandler()) {
-      CPDFSDK_Widget::SynchronizeXFAValue(pXFADocView, hWidget, GetFormField(),
-                                          GetFormControl());
-    }
-  }
-}
-
-void CPDFSDK_Widget::SynchronizeXFAItems() {
-  CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
-  CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
-  IXFA_DocView* pXFADocView = pDoc->GetXFADocView();
-  if (!pXFADocView)
-    return;
-
-  if (IXFA_Widget* hWidget = GetMixXFAWidget()) {
-    if (GetXFAWidgetHandler())
-      SynchronizeXFAItems(pXFADocView, hWidget, GetFormField(), nullptr);
-  }
-}
-
-void CPDFSDK_Widget::SynchronizeXFAValue(IXFA_DocView* pXFADocView,
-                                         IXFA_Widget* hWidget,
-                                         CPDF_FormField* pFormField,
-                                         CPDF_FormControl* pFormControl) {
-  ASSERT(pXFADocView != NULL);
-  ASSERT(hWidget != NULL);
-
-  if (IXFA_WidgetHandler* pXFAWidgetHandler = pXFADocView->GetWidgetHandler()) {
-    ASSERT(pFormField != NULL);
-    ASSERT(pFormControl != NULL);
-
-    switch (pFormField->GetFieldType()) {
-      case FIELDTYPE_CHECKBOX: {
-        if (CXFA_WidgetAcc* pWidgetAcc =
-                pXFAWidgetHandler->GetDataAcc(hWidget)) {
-          FX_BOOL bChecked = pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On;
-
-          pFormField->CheckControl(pFormField->GetControlIndex(pFormControl),
-                                   bChecked, TRUE);
-        }
-      } break;
-      case FIELDTYPE_RADIOBUTTON: {
-        if (CXFA_WidgetAcc* pWidgetAcc =
-                pXFAWidgetHandler->GetDataAcc(hWidget)) {
-          FX_BOOL bChecked = pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On;
-
-          pFormField->CheckControl(pFormField->GetControlIndex(pFormControl),
-                                   bChecked, TRUE);
-        }
-      } break;
-      case FIELDTYPE_TEXTFIELD: {
-        if (CXFA_WidgetAcc* pWidgetAcc =
-                pXFAWidgetHandler->GetDataAcc(hWidget)) {
-          CFX_WideString sValue;
-          pWidgetAcc->GetValue(sValue, XFA_VALUEPICTURE_Display);
-          pFormField->SetValue(sValue, TRUE);
-        }
-      } break;
-      case FIELDTYPE_LISTBOX: {
-        pFormField->ClearSelection(FALSE);
-
-        if (CXFA_WidgetAcc* pWidgetAcc =
-                pXFAWidgetHandler->GetDataAcc(hWidget)) {
-          for (int i = 0, sz = pWidgetAcc->CountSelectedItems(); i < sz; i++) {
-            int nIndex = pWidgetAcc->GetSelectedItem(i);
-
-            if (nIndex > -1 && nIndex < pFormField->CountOptions()) {
-              pFormField->SetItemSelection(nIndex, TRUE, TRUE);
-            }
-          }
-        }
-      } break;
-      case FIELDTYPE_COMBOBOX: {
-        pFormField->ClearSelection(FALSE);
-
-        if (CXFA_WidgetAcc* pWidgetAcc =
-                pXFAWidgetHandler->GetDataAcc(hWidget)) {
-          for (int i = 0, sz = pWidgetAcc->CountSelectedItems(); i < sz; i++) {
-            int nIndex = pWidgetAcc->GetSelectedItem(i);
-
-            if (nIndex > -1 && nIndex < pFormField->CountOptions()) {
-              pFormField->SetItemSelection(nIndex, TRUE, TRUE);
-            }
-          }
-
-          CFX_WideString sValue;
-          pWidgetAcc->GetValue(sValue, XFA_VALUEPICTURE_Display);
-          pFormField->SetValue(sValue, TRUE);
-        }
-      } break;
-    }
-  }
-}
-
-void CPDFSDK_Widget::SynchronizeXFAItems(IXFA_DocView* pXFADocView,
-                                         IXFA_Widget* hWidget,
-                                         CPDF_FormField* pFormField,
-                                         CPDF_FormControl* pFormControl) {
-  ASSERT(pXFADocView != NULL);
-  ASSERT(hWidget != NULL);
-
-  if (IXFA_WidgetHandler* pXFAWidgetHandler = pXFADocView->GetWidgetHandler()) {
-    ASSERT(pFormField != NULL);
-
-    switch (pFormField->GetFieldType()) {
-      case FIELDTYPE_LISTBOX: {
-        pFormField->ClearSelection(FALSE);
-        pFormField->ClearOptions(TRUE);
-
-        if (CXFA_WidgetAcc* pWidgetAcc =
-                pXFAWidgetHandler->GetDataAcc(hWidget)) {
-          for (int i = 0, sz = pWidgetAcc->CountChoiceListItems(); i < sz;
-               i++) {
-            CFX_WideString swText;
-            pWidgetAcc->GetChoiceListItem(swText, i);
-
-            pFormField->InsertOption(swText, i, TRUE);
-          }
-        }
-      } break;
-      case FIELDTYPE_COMBOBOX: {
-        pFormField->ClearSelection(FALSE);
-        pFormField->ClearOptions(FALSE);
-
-        if (CXFA_WidgetAcc* pWidgetAcc =
-                pXFAWidgetHandler->GetDataAcc(hWidget)) {
-          for (int i = 0, sz = pWidgetAcc->CountChoiceListItems(); i < sz;
-               i++) {
-            CFX_WideString swText;
-            pWidgetAcc->GetChoiceListItem(swText, i);
-
-            pFormField->InsertOption(swText, i, FALSE);
-          }
-        }
-
-        pFormField->SetValue(L"", TRUE);
-      } break;
-    }
-  }
-}
-#endif  // PDF_ENABLE_XFA
-
-FX_BOOL CPDFSDK_Widget::IsWidgetAppearanceValid(
-    CPDF_Annot::AppearanceMode mode) {
-  CPDF_Dictionary* pAP = m_pAnnot->GetAnnotDict()->GetDict("AP");
-  if (!pAP)
-    return FALSE;
-
-  // Choose the right sub-ap
-  const FX_CHAR* ap_entry = "N";
-  if (mode == CPDF_Annot::Down)
-    ap_entry = "D";
-  else if (mode == CPDF_Annot::Rollover)
-    ap_entry = "R";
-  if (!pAP->KeyExist(ap_entry))
-    ap_entry = "N";
-
-  // Get the AP stream or subdirectory
-  CPDF_Object* psub = pAP->GetElementValue(ap_entry);
-  if (!psub)
-    return FALSE;
-
-  int nFieldType = GetFieldType();
-  switch (nFieldType) {
-    case FIELDTYPE_PUSHBUTTON:
-    case FIELDTYPE_COMBOBOX:
-    case FIELDTYPE_LISTBOX:
-    case FIELDTYPE_TEXTFIELD:
-    case FIELDTYPE_SIGNATURE:
-      return psub->IsStream();
-    case FIELDTYPE_CHECKBOX:
-    case FIELDTYPE_RADIOBUTTON:
-      if (CPDF_Dictionary* pSubDict = psub->AsDictionary()) {
-        return pSubDict->GetStream(GetAppState()) != NULL;
-      }
-      return FALSE;
-  }
-  return TRUE;
-}
-
-int CPDFSDK_Widget::GetFieldType() const {
-  return GetFormField()->GetFieldType();
-}
-
-FX_BOOL CPDFSDK_Widget::IsAppearanceValid() {
-#ifdef PDF_ENABLE_XFA
-  CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
-  CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
-  int nDocType = pDoc->GetDocType();
-  if (nDocType != DOCTYPE_PDF && nDocType != DOCTYPE_STATIC_XFA)
-    return TRUE;
-#endif  // PDF_ENABLE_XFA
-  return CPDFSDK_BAAnnot::IsAppearanceValid();
-}
-
-int CPDFSDK_Widget::GetFieldFlags() const {
-  CPDF_InterForm* pPDFInterForm = m_pInterForm->GetInterForm();
-  CPDF_FormControl* pFormControl =
-      pPDFInterForm->GetControlByDict(m_pAnnot->GetAnnotDict());
-  CPDF_FormField* pFormField = pFormControl->GetField();
-  return pFormField->GetFieldFlags();
-}
-
-CFX_ByteString CPDFSDK_Widget::GetSubType() const {
-  int nType = GetFieldType();
-
-  if (nType == FIELDTYPE_SIGNATURE)
-    return BFFT_SIGNATURE;
-  return CPDFSDK_Annot::GetSubType();
-}
-
-CPDF_FormField* CPDFSDK_Widget::GetFormField() const {
-  return GetFormControl()->GetField();
-}
-
-CPDF_FormControl* CPDFSDK_Widget::GetFormControl() const {
-  CPDF_InterForm* pPDFInterForm = m_pInterForm->GetInterForm();
-  return pPDFInterForm->GetControlByDict(GetAnnotDict());
-}
-
-CPDF_FormControl* CPDFSDK_Widget::GetFormControl(
-    CPDF_InterForm* pInterForm,
-    const CPDF_Dictionary* pAnnotDict) {
-  ASSERT(pAnnotDict);
-  return pInterForm->GetControlByDict(pAnnotDict);
-}
-
-int CPDFSDK_Widget::GetRotate() const {
-  CPDF_FormControl* pCtrl = GetFormControl();
-  return pCtrl->GetRotation() % 360;
-}
-
-#ifdef PDF_ENABLE_XFA
-CFX_WideString CPDFSDK_Widget::GetName() const {
-  CPDF_FormField* pFormField = GetFormField();
-  return pFormField->GetFullName();
-}
-#endif  // PDF_ENABLE_XFA
-
-FX_BOOL CPDFSDK_Widget::GetFillColor(FX_COLORREF& color) const {
-  CPDF_FormControl* pFormCtrl = GetFormControl();
-  int iColorType = 0;
-  color = FX_ARGBTOCOLORREF(pFormCtrl->GetBackgroundColor(iColorType));
-
-  return iColorType != COLORTYPE_TRANSPARENT;
-}
-
-FX_BOOL CPDFSDK_Widget::GetBorderColor(FX_COLORREF& color) const {
-  CPDF_FormControl* pFormCtrl = GetFormControl();
-  int iColorType = 0;
-  color = FX_ARGBTOCOLORREF(pFormCtrl->GetBorderColor(iColorType));
-
-  return iColorType != COLORTYPE_TRANSPARENT;
-}
-
-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);
-
-    return iColorType != COLORTYPE_TRANSPARENT;
-  }
-
-  return FALSE;
-}
-
-FX_FLOAT CPDFSDK_Widget::GetFontSize() const {
-  CPDF_FormControl* pFormCtrl = GetFormControl();
-  CPDF_DefaultAppearance pDa = pFormCtrl->GetDefaultAppearance();
-  CFX_ByteString csFont = "";
-  FX_FLOAT fFontSize = 0.0f;
-  pDa.GetFont(csFont, fFontSize);
-
-  return fFontSize;
-}
-
-int CPDFSDK_Widget::GetSelectedIndex(int nIndex) const {
-#ifdef PDF_ENABLE_XFA
-  if (IXFA_Widget* hWidget = this->GetMixXFAWidget()) {
-    if (IXFA_WidgetHandler* pXFAWidgetHandler = this->GetXFAWidgetHandler()) {
-      if (CXFA_WidgetAcc* pWidgetAcc = pXFAWidgetHandler->GetDataAcc(hWidget)) {
-        if (nIndex < pWidgetAcc->CountSelectedItems())
-          return pWidgetAcc->GetSelectedItem(nIndex);
-      }
-    }
-  }
-#endif  // PDF_ENABLE_XFA
-  CPDF_FormField* pFormField = GetFormField();
-  return pFormField->GetSelectedIndex(nIndex);
-}
-
-#ifdef PDF_ENABLE_XFA
-CFX_WideString CPDFSDK_Widget::GetValue(FX_BOOL bDisplay) const {
-  if (IXFA_Widget* hWidget = this->GetMixXFAWidget()) {
-    if (IXFA_WidgetHandler* pXFAWidgetHandler = this->GetXFAWidgetHandler()) {
-      if (CXFA_WidgetAcc* pWidgetAcc = pXFAWidgetHandler->GetDataAcc(hWidget)) {
-        CFX_WideString sValue;
-        pWidgetAcc->GetValue(sValue, bDisplay ? XFA_VALUEPICTURE_Display
-                                              : XFA_VALUEPICTURE_Edit);
-        return sValue;
-      }
-    }
-  }
-#else
-CFX_WideString CPDFSDK_Widget::GetValue() const {
-#endif  // PDF_ENABLE_XFA
-  CPDF_FormField* pFormField = GetFormField();
-  return pFormField->GetValue();
-}
-
-CFX_WideString CPDFSDK_Widget::GetDefaultValue() const {
-  CPDF_FormField* pFormField = GetFormField();
-  return pFormField->GetDefaultValue();
-}
-
-CFX_WideString CPDFSDK_Widget::GetOptionLabel(int nIndex) const {
-  CPDF_FormField* pFormField = GetFormField();
-  return pFormField->GetOptionLabel(nIndex);
-}
-
-int CPDFSDK_Widget::CountOptions() const {
-  CPDF_FormField* pFormField = GetFormField();
-  return pFormField->CountOptions();
-}
-
-FX_BOOL CPDFSDK_Widget::IsOptionSelected(int nIndex) const {
-#ifdef PDF_ENABLE_XFA
-  if (IXFA_Widget* hWidget = this->GetMixXFAWidget()) {
-    if (IXFA_WidgetHandler* pXFAWidgetHandler = this->GetXFAWidgetHandler()) {
-      if (CXFA_WidgetAcc* pWidgetAcc = pXFAWidgetHandler->GetDataAcc(hWidget)) {
-        if (nIndex > -1 && nIndex < pWidgetAcc->CountChoiceListItems())
-          return pWidgetAcc->GetItemState(nIndex);
-
-        return FALSE;
-      }
-    }
-  }
-#endif  // PDF_ENABLE_XFA
-  CPDF_FormField* pFormField = GetFormField();
-  return pFormField->IsItemSelected(nIndex);
-}
-
-int CPDFSDK_Widget::GetTopVisibleIndex() const {
-  CPDF_FormField* pFormField = GetFormField();
-  return pFormField->GetTopVisibleIndex();
-}
-
-FX_BOOL CPDFSDK_Widget::IsChecked() const {
-#ifdef PDF_ENABLE_XFA
-  if (IXFA_WidgetHandler* pXFAWidgetHandler = this->GetXFAWidgetHandler()) {
-    if (IXFA_Widget* hWidget = this->GetMixXFAWidget()) {
-      if (CXFA_WidgetAcc* pWidgetAcc = pXFAWidgetHandler->GetDataAcc(hWidget)) {
-        FX_BOOL bChecked = pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On;
-        return bChecked;
-      }
-    }
-  }
-#endif  // PDF_ENABLE_XFA
-  CPDF_FormControl* pFormCtrl = GetFormControl();
-  return pFormCtrl->IsChecked();
-}
-
-int CPDFSDK_Widget::GetAlignment() const {
-  CPDF_FormControl* pFormCtrl = GetFormControl();
-  return pFormCtrl->GetControlAlignment();
-}
-
-int CPDFSDK_Widget::GetMaxLen() const {
-  CPDF_FormField* pFormField = GetFormField();
-  return pFormField->GetMaxLen();
-}
-
-void CPDFSDK_Widget::SetCheck(FX_BOOL bChecked, FX_BOOL bNotify) {
-  CPDF_FormControl* pFormCtrl = GetFormControl();
-  CPDF_FormField* pFormField = pFormCtrl->GetField();
-  pFormField->CheckControl(pFormField->GetControlIndex(pFormCtrl), bChecked,
-                           bNotify);
-#ifdef PDF_ENABLE_XFA
-  if (!IsWidgetAppearanceValid(CPDF_Annot::Normal))
-    ResetAppearance(TRUE);
-  if (!bNotify)
-    Synchronize(TRUE);
-#endif  // PDF_ENABLE_XFA
-}
-
-void CPDFSDK_Widget::SetValue(const CFX_WideString& sValue, FX_BOOL bNotify) {
-  CPDF_FormField* pFormField = GetFormField();
-  pFormField->SetValue(sValue, bNotify);
-#ifdef PDF_ENABLE_XFA
-  if (!bNotify)
-    Synchronize(TRUE);
-#endif  // PDF_ENABLE_XFA
-}
-
-void CPDFSDK_Widget::SetDefaultValue(const CFX_WideString& sValue) {}
-void CPDFSDK_Widget::SetOptionSelection(int index,
-                                        FX_BOOL bSelected,
-                                        FX_BOOL bNotify) {
-  CPDF_FormField* pFormField = GetFormField();
-  pFormField->SetItemSelection(index, bSelected, bNotify);
-#ifdef PDF_ENABLE_XFA
-  if (!bNotify)
-    Synchronize(TRUE);
-#endif  // PDF_ENABLE_XFA
-}
-
-void CPDFSDK_Widget::ClearSelection(FX_BOOL bNotify) {
-  CPDF_FormField* pFormField = GetFormField();
-  pFormField->ClearSelection(bNotify);
-#ifdef PDF_ENABLE_XFA
-  if (!bNotify)
-    Synchronize(TRUE);
-#endif  // PDF_ENABLE_XFA
-}
-
-void CPDFSDK_Widget::SetTopVisibleIndex(int index) {}
-
-void CPDFSDK_Widget::SetAppModified() {
-  m_bAppModified = TRUE;
-}
-
-void CPDFSDK_Widget::ClearAppModified() {
-  m_bAppModified = FALSE;
-}
-
-FX_BOOL CPDFSDK_Widget::IsAppModified() const {
-  return m_bAppModified;
-}
-
-#ifdef PDF_ENABLE_XFA
-void CPDFSDK_Widget::ResetAppearance(FX_BOOL bValueChanged) {
-  switch (GetFieldType()) {
-    case FIELDTYPE_TEXTFIELD:
-    case FIELDTYPE_COMBOBOX: {
-      FX_BOOL bFormated = FALSE;
-      CFX_WideString sValue = this->OnFormat(bFormated);
-      if (bFormated)
-        this->ResetAppearance(sValue, TRUE);
-      else
-        this->ResetAppearance(NULL, TRUE);
-    } break;
-    default:
-      this->ResetAppearance(NULL, FALSE);
-      break;
-  }
-}
-#endif  // PDF_ENABLE_XFA
-
-void CPDFSDK_Widget::ResetAppearance(const FX_WCHAR* sValue,
-                                     FX_BOOL bValueChanged) {
-  SetAppModified();
-
-  m_nAppAge++;
-  if (m_nAppAge > 999999)
-    m_nAppAge = 0;
-  if (bValueChanged)
-    m_nValueAge++;
-
-  int nFieldType = GetFieldType();
-
-  switch (nFieldType) {
-    case FIELDTYPE_PUSHBUTTON:
-      ResetAppearance_PushButton();
-      break;
-    case FIELDTYPE_CHECKBOX:
-      ResetAppearance_CheckBox();
-      break;
-    case FIELDTYPE_RADIOBUTTON:
-      ResetAppearance_RadioButton();
-      break;
-    case FIELDTYPE_COMBOBOX:
-      ResetAppearance_ComboBox(sValue);
-      break;
-    case FIELDTYPE_LISTBOX:
-      ResetAppearance_ListBox();
-      break;
-    case FIELDTYPE_TEXTFIELD:
-      ResetAppearance_TextField(sValue);
-      break;
-  }
-
-  m_pAnnot->ClearCachedAP();
-}
-
-CFX_WideString CPDFSDK_Widget::OnFormat(FX_BOOL& bFormated) {
-  CPDF_FormField* pFormField = GetFormField();
-  ASSERT(pFormField);
-  return m_pInterForm->OnFormat(pFormField, bFormated);
-}
-
-void CPDFSDK_Widget::ResetFieldAppearance(FX_BOOL bValueChanged) {
-  CPDF_FormField* pFormField = GetFormField();
-  ASSERT(pFormField);
-  m_pInterForm->ResetFieldAppearance(pFormField, NULL, bValueChanged);
-}
-
-void CPDFSDK_Widget::DrawAppearance(CFX_RenderDevice* pDevice,
-                                    const CFX_Matrix* pUser2Device,
-                                    CPDF_Annot::AppearanceMode mode,
-                                    const CPDF_RenderOptions* pOptions) {
-  int nFieldType = GetFieldType();
-
-  if ((nFieldType == FIELDTYPE_CHECKBOX ||
-       nFieldType == FIELDTYPE_RADIOBUTTON) &&
-      mode == CPDF_Annot::Normal &&
-      !IsWidgetAppearanceValid(CPDF_Annot::Normal)) {
-    CFX_PathData pathData;
-
-    CPDF_Rect rcAnnot = GetRect();
-
-    pathData.AppendRect(rcAnnot.left, rcAnnot.bottom, rcAnnot.right,
-                        rcAnnot.top);
-
-    CFX_GraphStateData gsd;
-    gsd.m_LineWidth = 0.0f;
-
-    pDevice->DrawPath(&pathData, pUser2Device, &gsd, 0, 0xFFAAAAAA,
-                      FXFILL_ALTERNATE);
-  } else {
-    CPDFSDK_BAAnnot::DrawAppearance(pDevice, pUser2Device, mode, pOptions);
-  }
-}
-
-void CPDFSDK_Widget::UpdateField() {
-  CPDF_FormField* pFormField = GetFormField();
-  ASSERT(pFormField);
-  m_pInterForm->UpdateField(pFormField);
-}
-
-void CPDFSDK_Widget::DrawShadow(CFX_RenderDevice* pDevice,
-                                CPDFSDK_PageView* pPageView) {
-  int nFieldType = GetFieldType();
-  if (m_pInterForm->IsNeedHighLight(nFieldType)) {
-    CPDF_Rect rc = GetRect();
-    FX_COLORREF color = m_pInterForm->GetHighlightColor(nFieldType);
-    uint8_t alpha = m_pInterForm->GetHighlightAlpha();
-
-    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);
-
-    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() {
-  CPDF_FormControl* pControl = GetFormControl();
-  CPDF_Rect rcWindow = GetRotatedRect();
-  int32_t nLayout = 0;
-  switch (pControl->GetTextPosition()) {
-    case TEXTPOS_ICON:
-      nLayout = PPBL_ICON;
-      break;
-    case TEXTPOS_BELOW:
-      nLayout = PPBL_ICONTOPLABELBOTTOM;
-      break;
-    case TEXTPOS_ABOVE:
-      nLayout = PPBL_LABELTOPICONBOTTOM;
-      break;
-    case TEXTPOS_RIGHT:
-      nLayout = PPBL_ICONLEFTLABELRIGHT;
-      break;
-    case TEXTPOS_LEFT:
-      nLayout = PPBL_LABELLEFTICONRIGHT;
-      break;
-    case TEXTPOS_OVERLAID:
-      nLayout = PPBL_LABELOVERICON;
-      break;
-    default:
-      nLayout = PPBL_LABEL;
-      break;
-  }
-
-  CPWL_Color crBackground, crBorder;
-
-  int iColorType;
-  FX_FLOAT fc[4];
-
-  pControl->GetOriginalBackgroundColor(iColorType, fc);
-  if (iColorType > 0)
-    crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
-
-  pControl->GetOriginalBorderColor(iColorType, fc);
-  if (iColorType > 0)
-    crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
-
-  FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
-  int32_t nBorderStyle = 0;
-  CPWL_Dash dsBorder(3, 0, 0);
-  CPWL_Color crLeftTop, crRightBottom;
-
-  switch (GetBorderStyle()) {
-    case BBS_DASH:
-      nBorderStyle = PBS_DASH;
-      dsBorder = CPWL_Dash(3, 3, 0);
-      break;
-    case BBS_BEVELED:
-      nBorderStyle = PBS_BEVELED;
-      fBorderWidth *= 2;
-      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
-      crRightBottom = CPWL_Utils::DevideColor(crBackground, 2);
-      break;
-    case BBS_INSET:
-      nBorderStyle = PBS_INSET;
-      fBorderWidth *= 2;
-      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5);
-      crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75);
-      break;
-    case BBS_UNDERLINE:
-      nBorderStyle = PBS_UNDERLINED;
-      break;
-    default:
-      nBorderStyle = PBS_SOLID;
-      break;
-  }
-
-  CPDF_Rect rcClient = CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);
-
-  CPWL_Color crText(COLORTYPE_GRAY, 0);
-
-  FX_FLOAT fFontSize = 12.0f;
-  CFX_ByteString csNameTag;
-
-  CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
-  if (da.HasColor()) {
-    da.GetColor(iColorType, fc);
-    crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
-  }
-
-  if (da.HasFont())
-    da.GetFont(csNameTag, fFontSize);
-
-  CFX_WideString csWCaption;
-  CFX_WideString csNormalCaption, csRolloverCaption, csDownCaption;
-
-  if (pControl->HasMKEntry("CA")) {
-    csNormalCaption = pControl->GetNormalCaption();
-  }
-  if (pControl->HasMKEntry("RC")) {
-    csRolloverCaption = pControl->GetRolloverCaption();
-  }
-  if (pControl->HasMKEntry("AC")) {
-    csDownCaption = pControl->GetDownCaption();
-  }
-
-  CPDF_Stream* pNormalIcon = NULL;
-  CPDF_Stream* pRolloverIcon = NULL;
-  CPDF_Stream* pDownIcon = NULL;
-
-  if (pControl->HasMKEntry("I")) {
-    pNormalIcon = pControl->GetNormalIcon();
-  }
-  if (pControl->HasMKEntry("RI")) {
-    pRolloverIcon = pControl->GetRolloverIcon();
-  }
-  if (pControl->HasMKEntry("IX")) {
-    pDownIcon = pControl->GetDownIcon();
-  }
-
-  if (pNormalIcon) {
-    if (CPDF_Dictionary* pImageDict = pNormalIcon->GetDict()) {
-      if (pImageDict->GetString("Name").IsEmpty())
-        pImageDict->SetAtString("Name", "ImgA");
-    }
-  }
-
-  if (pRolloverIcon) {
-    if (CPDF_Dictionary* pImageDict = pRolloverIcon->GetDict()) {
-      if (pImageDict->GetString("Name").IsEmpty())
-        pImageDict->SetAtString("Name", "ImgB");
-    }
-  }
-
-  if (pDownIcon) {
-    if (CPDF_Dictionary* pImageDict = pDownIcon->GetDict()) {
-      if (pImageDict->GetString("Name").IsEmpty())
-        pImageDict->SetAtString("Name", "ImgC");
-    }
-  }
-
-  CPDF_IconFit iconFit = pControl->GetIconFit();
-
-  CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
-  CPDFDoc_Environment* pEnv = pDoc->GetEnv();
-
-  CBA_FontMap font_map(this, pEnv->GetSysHandler());
-  font_map.SetAPType("N");
-
-  CFX_ByteString csAP =
-      CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
-      CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
-                                     crLeftTop, crRightBottom, nBorderStyle,
-                                     dsBorder) +
-      CPWL_Utils::GetPushButtonAppStream(
-          iconFit.GetFittingBounds() ? rcWindow : rcClient, &font_map,
-          pNormalIcon, iconFit, csNormalCaption, crText, fFontSize, nLayout);
-
-  WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP);
-  if (pNormalIcon)
-    AddImageToAppearance("N", pNormalIcon);
-
-  CPDF_FormControl::HighlightingMode eHLM = pControl->GetHighlightingMode();
-  if (eHLM == CPDF_FormControl::Push || eHLM == CPDF_FormControl::Toggle) {
-    if (csRolloverCaption.IsEmpty() && !pRolloverIcon) {
-      csRolloverCaption = csNormalCaption;
-      pRolloverIcon = pNormalIcon;
-    }
-
-    font_map.SetAPType("R");
-
-    csAP = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
-           CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
-                                          crLeftTop, crRightBottom,
-                                          nBorderStyle, dsBorder) +
-           CPWL_Utils::GetPushButtonAppStream(
-               iconFit.GetFittingBounds() ? rcWindow : rcClient, &font_map,
-               pRolloverIcon, iconFit, csRolloverCaption, crText, fFontSize,
-               nLayout);
-
-    WriteAppearance("R", GetRotatedRect(), GetMatrix(), csAP);
-    if (pRolloverIcon)
-      AddImageToAppearance("R", pRolloverIcon);
-
-    if (csDownCaption.IsEmpty() && !pDownIcon) {
-      csDownCaption = csNormalCaption;
-      pDownIcon = pNormalIcon;
-    }
-
-    switch (nBorderStyle) {
-      case PBS_BEVELED: {
-        CPWL_Color crTemp = crLeftTop;
-        crLeftTop = crRightBottom;
-        crRightBottom = crTemp;
-      } break;
-      case PBS_INSET:
-        crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0);
-        crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
-        break;
-    }
-
-    font_map.SetAPType("D");
-
-    csAP = CPWL_Utils::GetRectFillAppStream(
-               rcWindow, CPWL_Utils::SubstractColor(crBackground, 0.25f)) +
-           CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
-                                          crLeftTop, crRightBottom,
-                                          nBorderStyle, dsBorder) +
-           CPWL_Utils::GetPushButtonAppStream(
-               iconFit.GetFittingBounds() ? rcWindow : rcClient, &font_map,
-               pDownIcon, iconFit, csDownCaption, crText, fFontSize, nLayout);
-
-    WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP);
-    if (pDownIcon)
-      AddImageToAppearance("D", pDownIcon);
-  } else {
-    RemoveAppearance("D");
-    RemoveAppearance("R");
-  }
-}
-
-void CPDFSDK_Widget::ResetAppearance_CheckBox() {
-  CPDF_FormControl* pControl = GetFormControl();
-  CPWL_Color crBackground, crBorder, crText;
-  int iColorType;
-  FX_FLOAT fc[4];
-
-  pControl->GetOriginalBackgroundColor(iColorType, fc);
-  if (iColorType > 0)
-    crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
-
-  pControl->GetOriginalBorderColor(iColorType, fc);
-  if (iColorType > 0)
-    crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
-
-  FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
-  int32_t nBorderStyle = 0;
-  CPWL_Dash dsBorder(3, 0, 0);
-  CPWL_Color crLeftTop, crRightBottom;
-
-  switch (GetBorderStyle()) {
-    case BBS_DASH:
-      nBorderStyle = PBS_DASH;
-      dsBorder = CPWL_Dash(3, 3, 0);
-      break;
-    case BBS_BEVELED:
-      nBorderStyle = PBS_BEVELED;
-      fBorderWidth *= 2;
-      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
-      crRightBottom = CPWL_Utils::DevideColor(crBackground, 2);
-      break;
-    case BBS_INSET:
-      nBorderStyle = PBS_INSET;
-      fBorderWidth *= 2;
-      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5);
-      crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75);
-      break;
-    case BBS_UNDERLINE:
-      nBorderStyle = PBS_UNDERLINED;
-      break;
-    default:
-      nBorderStyle = PBS_SOLID;
-      break;
-  }
-
-  CPDF_Rect rcWindow = GetRotatedRect();
-  CPDF_Rect rcClient = CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);
-
-  CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
-  if (da.HasColor()) {
-    da.GetColor(iColorType, fc);
-    crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
-  }
-
-  int32_t nStyle = 0;
-
-  CFX_WideString csWCaption = pControl->GetNormalCaption();
-  if (csWCaption.GetLength() > 0) {
-    switch (csWCaption[0]) {
-      case L'l':
-        nStyle = PCS_CIRCLE;
-        break;
-      case L'8':
-        nStyle = PCS_CROSS;
-        break;
-      case L'u':
-        nStyle = PCS_DIAMOND;
-        break;
-      case L'n':
-        nStyle = PCS_SQUARE;
-        break;
-      case L'H':
-        nStyle = PCS_STAR;
-        break;
-      default:  // L'4'
-        nStyle = PCS_CHECK;
-        break;
-    }
-  } else {
-    nStyle = PCS_CHECK;
-  }
-
-  CFX_ByteString csAP_N_ON =
-      CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
-      CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
-                                     crLeftTop, crRightBottom, nBorderStyle,
-                                     dsBorder);
-
-  CFX_ByteString csAP_N_OFF = csAP_N_ON;
-
-  switch (nBorderStyle) {
-    case PBS_BEVELED: {
-      CPWL_Color crTemp = crLeftTop;
-      crLeftTop = crRightBottom;
-      crRightBottom = crTemp;
-    } break;
-    case PBS_INSET:
-      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0);
-      crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
-      break;
-  }
-
-  CFX_ByteString csAP_D_ON =
-      CPWL_Utils::GetRectFillAppStream(
-          rcWindow, CPWL_Utils::SubstractColor(crBackground, 0.25f)) +
-      CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
-                                     crLeftTop, crRightBottom, nBorderStyle,
-                                     dsBorder);
-
-  CFX_ByteString csAP_D_OFF = csAP_D_ON;
-
-  csAP_N_ON += CPWL_Utils::GetCheckBoxAppStream(rcClient, nStyle, crText);
-  csAP_D_ON += CPWL_Utils::GetCheckBoxAppStream(rcClient, nStyle, crText);
-
-  WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_ON,
-                  pControl->GetCheckedAPState());
-  WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_OFF, "Off");
-
-  WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_ON,
-                  pControl->GetCheckedAPState());
-  WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_OFF, "Off");
-
-  CFX_ByteString csAS = GetAppState();
-  if (csAS.IsEmpty())
-    SetAppState("Off");
-}
-
-void CPDFSDK_Widget::ResetAppearance_RadioButton() {
-  CPDF_FormControl* pControl = GetFormControl();
-  CPWL_Color crBackground, crBorder, crText;
-  int iColorType;
-  FX_FLOAT fc[4];
-
-  pControl->GetOriginalBackgroundColor(iColorType, fc);
-  if (iColorType > 0)
-    crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
-
-  pControl->GetOriginalBorderColor(iColorType, fc);
-  if (iColorType > 0)
-    crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
-
-  FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
-  int32_t nBorderStyle = 0;
-  CPWL_Dash dsBorder(3, 0, 0);
-  CPWL_Color crLeftTop, crRightBottom;
-
-  switch (GetBorderStyle()) {
-    case BBS_DASH:
-      nBorderStyle = PBS_DASH;
-      dsBorder = CPWL_Dash(3, 3, 0);
-      break;
-    case BBS_BEVELED:
-      nBorderStyle = PBS_BEVELED;
-      fBorderWidth *= 2;
-      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
-      crRightBottom = CPWL_Utils::DevideColor(crBackground, 2);
-      break;
-    case BBS_INSET:
-      nBorderStyle = PBS_INSET;
-      fBorderWidth *= 2;
-      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5);
-      crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75);
-      break;
-    case BBS_UNDERLINE:
-      nBorderStyle = PBS_UNDERLINED;
-      break;
-    default:
-      nBorderStyle = PBS_SOLID;
-      break;
-  }
-
-  CPDF_Rect rcWindow = GetRotatedRect();
-  CPDF_Rect rcClient = CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);
-
-  CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
-  if (da.HasColor()) {
-    da.GetColor(iColorType, fc);
-    crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
-  }
-
-  int32_t nStyle = 0;
-
-  CFX_WideString csWCaption = pControl->GetNormalCaption();
-  if (csWCaption.GetLength() > 0) {
-    switch (csWCaption[0]) {
-      default:  // L'l':
-        nStyle = PCS_CIRCLE;
-        break;
-      case L'8':
-        nStyle = PCS_CROSS;
-        break;
-      case L'u':
-        nStyle = PCS_DIAMOND;
-        break;
-      case L'n':
-        nStyle = PCS_SQUARE;
-        break;
-      case L'H':
-        nStyle = PCS_STAR;
-        break;
-      case L'4':
-        nStyle = PCS_CHECK;
-        break;
-    }
-  } else {
-    nStyle = PCS_CIRCLE;
-  }
-
-  CFX_ByteString csAP_N_ON;
-
-  CPDF_Rect rcCenter =
-      CPWL_Utils::DeflateRect(CPWL_Utils::GetCenterSquare(rcWindow), 1.0f);
-
-  if (nStyle == PCS_CIRCLE) {
-    if (nBorderStyle == PBS_BEVELED) {
-      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
-      crRightBottom = CPWL_Utils::SubstractColor(crBackground, 0.25f);
-    } else if (nBorderStyle == PBS_INSET) {
-      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5f);
-      crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75f);
-    }
-
-    csAP_N_ON = CPWL_Utils::GetCircleFillAppStream(rcCenter, crBackground) +
-                CPWL_Utils::GetCircleBorderAppStream(
-                    rcCenter, fBorderWidth, crBorder, crLeftTop, crRightBottom,
-                    nBorderStyle, dsBorder);
-  } else {
-    csAP_N_ON = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
-                CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
-                                               crLeftTop, crRightBottom,
-                                               nBorderStyle, dsBorder);
-  }
-
-  CFX_ByteString csAP_N_OFF = csAP_N_ON;
-
-  switch (nBorderStyle) {
-    case PBS_BEVELED: {
-      CPWL_Color crTemp = crLeftTop;
-      crLeftTop = crRightBottom;
-      crRightBottom = crTemp;
-    } break;
-    case PBS_INSET:
-      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0);
-      crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
-      break;
-  }
-
-  CFX_ByteString csAP_D_ON;
-
-  if (nStyle == PCS_CIRCLE) {
-    CPWL_Color crBK = CPWL_Utils::SubstractColor(crBackground, 0.25f);
-    if (nBorderStyle == PBS_BEVELED) {
-      crLeftTop = CPWL_Utils::SubstractColor(crBackground, 0.25f);
-      crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
-      crBK = crBackground;
-    } else if (nBorderStyle == PBS_INSET) {
-      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0);
-      crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
-    }
-
-    csAP_D_ON = CPWL_Utils::GetCircleFillAppStream(rcCenter, crBK) +
-                CPWL_Utils::GetCircleBorderAppStream(
-                    rcCenter, fBorderWidth, crBorder, crLeftTop, crRightBottom,
-                    nBorderStyle, dsBorder);
-  } else {
-    csAP_D_ON = CPWL_Utils::GetRectFillAppStream(
-                    rcWindow, CPWL_Utils::SubstractColor(crBackground, 0.25f)) +
-                CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
-                                               crLeftTop, crRightBottom,
-                                               nBorderStyle, dsBorder);
-  }
-
-  CFX_ByteString csAP_D_OFF = csAP_D_ON;
-
-  csAP_N_ON += CPWL_Utils::GetRadioButtonAppStream(rcClient, nStyle, crText);
-  csAP_D_ON += CPWL_Utils::GetRadioButtonAppStream(rcClient, nStyle, crText);
-
-  WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_ON,
-                  pControl->GetCheckedAPState());
-  WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_OFF, "Off");
-
-  WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_ON,
-                  pControl->GetCheckedAPState());
-  WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_OFF, "Off");
-
-  CFX_ByteString csAS = GetAppState();
-  if (csAS.IsEmpty())
-    SetAppState("Off");
-}
-
-void CPDFSDK_Widget::ResetAppearance_ComboBox(const FX_WCHAR* sValue) {
-  CPDF_FormControl* pControl = GetFormControl();
-  CPDF_FormField* pField = pControl->GetField();
-  CFX_ByteTextBuf sBody, sLines;
-
-  CPDF_Rect rcClient = GetClientRect();
-  CPDF_Rect rcButton = rcClient;
-  rcButton.left = rcButton.right - 13;
-  rcButton.Normalize();
-
-  if (IFX_Edit* pEdit = IFX_Edit::NewEdit()) {
-    pEdit->EnableRefresh(FALSE);
-
-    CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
-    CPDFDoc_Environment* pEnv = pDoc->GetEnv();
-    CBA_FontMap font_map(this, pEnv->GetSysHandler());
-    pEdit->SetFontMap(&font_map);
-
-    CPDF_Rect rcEdit = rcClient;
-    rcEdit.right = rcButton.left;
-    rcEdit.Normalize();
-
-    pEdit->SetPlateRect(rcEdit);
-    pEdit->SetAlignmentV(1);
-
-    FX_FLOAT fFontSize = GetFontSize();
-    if (IsFloatZero(fFontSize))
-      pEdit->SetAutoFontSize(TRUE);
-    else
-      pEdit->SetFontSize(fFontSize);
-
-    pEdit->Initialize();
-
-    if (sValue) {
-      pEdit->SetText(sValue);
-    } else {
-      int32_t nCurSel = pField->GetSelectedIndex(0);
-
-      if (nCurSel < 0)
-        pEdit->SetText(pField->GetValue().c_str());
-      else
-        pEdit->SetText(pField->GetOptionLabel(nCurSel).c_str());
-    }
-
-    CPDF_Rect rcContent = pEdit->GetContentRect();
-
-    CFX_ByteString sEdit =
-        CPWL_Utils::GetEditAppStream(pEdit, CPDF_Point(0.0f, 0.0f));
-    if (sEdit.GetLength() > 0) {
-      sBody << "/Tx BMC\n"
-            << "q\n";
-      if (rcContent.Width() > rcEdit.Width() ||
-          rcContent.Height() > rcEdit.Height()) {
-        sBody << rcEdit.left << " " << rcEdit.bottom << " " << rcEdit.Width()
-              << " " << rcEdit.Height() << " re\nW\nn\n";
-      }
-
-      CPWL_Color crText = GetTextPWLColor();
-      sBody << "BT\n" << CPWL_Utils::GetColorAppStream(crText) << sEdit
-            << "ET\n"
-            << "Q\nEMC\n";
-    }
-
-    IFX_Edit::DelEdit(pEdit);
-  }
-
-  sBody << CPWL_Utils::GetDropButtonAppStream(rcButton);
-
-  CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() +
-                       sLines.GetByteString() + sBody.GetByteString();
-
-  WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
-}
-
-void CPDFSDK_Widget::ResetAppearance_ListBox() {
-  CPDF_FormControl* pControl = GetFormControl();
-  CPDF_FormField* pField = pControl->GetField();
-  CPDF_Rect rcClient = GetClientRect();
-  CFX_ByteTextBuf sBody, sLines;
-
-  if (IFX_Edit* pEdit = IFX_Edit::NewEdit()) {
-    pEdit->EnableRefresh(FALSE);
-
-    CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
-    CPDFDoc_Environment* pEnv = pDoc->GetEnv();
-
-    CBA_FontMap font_map(this, pEnv->GetSysHandler());
-    pEdit->SetFontMap(&font_map);
-
-    pEdit->SetPlateRect(CPDF_Rect(rcClient.left, 0.0f, rcClient.right, 0.0f));
-
-    FX_FLOAT fFontSize = GetFontSize();
-
-    if (IsFloatZero(fFontSize))
-      pEdit->SetFontSize(12.0f);
-    else
-      pEdit->SetFontSize(fFontSize);
-
-    pEdit->Initialize();
-
-    CFX_ByteTextBuf sList;
-    FX_FLOAT fy = rcClient.top;
-
-    int32_t nTop = pField->GetTopVisibleIndex();
-    int32_t nCount = pField->CountOptions();
-    int32_t nSelCount = pField->CountSelectedItems();
-
-    for (int32_t i = nTop; i < nCount; i++) {
-      FX_BOOL bSelected = FALSE;
-      for (int32_t j = 0; j < nSelCount; j++) {
-        if (pField->GetSelectedIndex(j) == i) {
-          bSelected = TRUE;
-          break;
-        }
-      }
-
-      pEdit->SetText(pField->GetOptionLabel(i).c_str());
-
-      CPDF_Rect rcContent = pEdit->GetContentRect();
-      FX_FLOAT fItemHeight = rcContent.Height();
-
-      if (bSelected) {
-        CPDF_Rect rcItem =
-            CPDF_Rect(rcClient.left, fy - fItemHeight, rcClient.right, fy);
-        sList << "q\n" << CPWL_Utils::GetColorAppStream(
-                              CPWL_Color(COLORTYPE_RGB, 0, 51.0f / 255.0f,
-                                         113.0f / 255.0f),
-                              TRUE)
-              << rcItem.left << " " << rcItem.bottom << " " << rcItem.Width()
-              << " " << rcItem.Height() << " re f\n"
-              << "Q\n";
-
-        sList << "BT\n" << CPWL_Utils::GetColorAppStream(
-                               CPWL_Color(COLORTYPE_GRAY, 1), TRUE)
-              << CPWL_Utils::GetEditAppStream(pEdit, CPDF_Point(0.0f, fy))
-              << "ET\n";
-      } else {
-        CPWL_Color crText = GetTextPWLColor();
-        sList << "BT\n" << CPWL_Utils::GetColorAppStream(crText, TRUE)
-              << CPWL_Utils::GetEditAppStream(pEdit, CPDF_Point(0.0f, fy))
-              << "ET\n";
-      }
-
-      fy -= fItemHeight;
-    }
-
-    if (sList.GetSize() > 0) {
-      sBody << "/Tx BMC\n"
-            << "q\n" << rcClient.left << " " << rcClient.bottom << " "
-            << rcClient.Width() << " " << rcClient.Height() << " re\nW\nn\n";
-      sBody << sList << "Q\nEMC\n";
-    }
-
-    IFX_Edit::DelEdit(pEdit);
-  }
-
-  CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() +
-                       sLines.GetByteString() + sBody.GetByteString();
-
-  WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
-}
-
-void CPDFSDK_Widget::ResetAppearance_TextField(const FX_WCHAR* sValue) {
-  CPDF_FormControl* pControl = GetFormControl();
-  CPDF_FormField* pField = pControl->GetField();
-  CFX_ByteTextBuf sBody, sLines;
-
-  if (IFX_Edit* pEdit = IFX_Edit::NewEdit()) {
-    pEdit->EnableRefresh(FALSE);
-
-    CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
-    CPDFDoc_Environment* pEnv = pDoc->GetEnv();
-
-    CBA_FontMap font_map(this, pEnv->GetSysHandler());
-    pEdit->SetFontMap(&font_map);
-
-    CPDF_Rect rcClient = GetClientRect();
-    pEdit->SetPlateRect(rcClient);
-    pEdit->SetAlignmentH(pControl->GetControlAlignment());
-
-    FX_DWORD dwFieldFlags = pField->GetFieldFlags();
-    FX_BOOL bMultiLine = (dwFieldFlags >> 12) & 1;
-
-    if (bMultiLine) {
-      pEdit->SetMultiLine(TRUE);
-      pEdit->SetAutoReturn(TRUE);
-    } else {
-      pEdit->SetAlignmentV(1);
-    }
-
-    FX_WORD subWord = 0;
-    if ((dwFieldFlags >> 13) & 1) {
-      subWord = '*';
-      pEdit->SetPasswordChar(subWord);
-    }
-
-    int nMaxLen = pField->GetMaxLen();
-    FX_BOOL bCharArray = (dwFieldFlags >> 24) & 1;
-    FX_FLOAT fFontSize = GetFontSize();
-
-#ifdef PDF_ENABLE_XFA
-    CFX_WideString sValueTmp;
-    if (!sValue && (NULL != this->GetMixXFAWidget())) {
-      sValueTmp = GetValue(TRUE);
-      sValue = sValueTmp;
-    }
-#endif  // PDF_ENABLE_XFA
-
-    if (nMaxLen > 0) {
-      if (bCharArray) {
-        pEdit->SetCharArray(nMaxLen);
-
-        if (IsFloatZero(fFontSize)) {
-          fFontSize = CPWL_Edit::GetCharArrayAutoFontSize(
-              font_map.GetPDFFont(0), rcClient, nMaxLen);
-        }
-      } else {
-        if (sValue)
-          nMaxLen = wcslen((const wchar_t*)sValue);
-        pEdit->SetLimitChar(nMaxLen);
-      }
-    }
-
-    if (IsFloatZero(fFontSize))
-      pEdit->SetAutoFontSize(TRUE);
-    else
-      pEdit->SetFontSize(fFontSize);
-
-    pEdit->Initialize();
-
-    if (sValue)
-      pEdit->SetText(sValue);
-    else
-      pEdit->SetText(pField->GetValue().c_str());
-
-    CPDF_Rect rcContent = pEdit->GetContentRect();
-
-    CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream(
-        pEdit, CPDF_Point(0.0f, 0.0f), NULL, !bCharArray, subWord);
-
-    if (sEdit.GetLength() > 0) {
-      sBody << "/Tx BMC\n"
-            << "q\n";
-      if (rcContent.Width() > rcClient.Width() ||
-          rcContent.Height() > rcClient.Height()) {
-        sBody << rcClient.left << " " << rcClient.bottom << " "
-              << rcClient.Width() << " " << rcClient.Height() << " re\nW\nn\n";
-      }
-      CPWL_Color crText = GetTextPWLColor();
-      sBody << "BT\n" << CPWL_Utils::GetColorAppStream(crText) << sEdit
-            << "ET\n"
-            << "Q\nEMC\n";
-    }
-
-    if (bCharArray) {
-      switch (GetBorderStyle()) {
-        case BBS_SOLID: {
-          CFX_ByteString sColor =
-              CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), FALSE);
-          if (sColor.GetLength() > 0) {
-            sLines << "q\n" << GetBorderWidth() << " w\n"
-                   << CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), FALSE)
-                   << " 2 J 0 j\n";
-
-            for (int32_t i = 1; i < nMaxLen; i++) {
-              sLines << rcClient.left +
-                            ((rcClient.right - rcClient.left) / nMaxLen) * i
-                     << " " << rcClient.bottom << " m\n"
-                     << rcClient.left +
-                            ((rcClient.right - rcClient.left) / nMaxLen) * i
-                     << " " << rcClient.top << " l S\n";
-            }
-
-            sLines << "Q\n";
-          }
-        } break;
-        case BBS_DASH: {
-          CFX_ByteString sColor =
-              CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), FALSE);
-          if (sColor.GetLength() > 0) {
-            CPWL_Dash dsBorder = CPWL_Dash(3, 3, 0);
-
-            sLines << "q\n" << GetBorderWidth() << " w\n"
-                   << CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), FALSE)
-                   << "[" << dsBorder.nDash << " " << dsBorder.nGap << "] "
-                   << dsBorder.nPhase << " d\n";
-
-            for (int32_t i = 1; i < nMaxLen; i++) {
-              sLines << rcClient.left +
-                            ((rcClient.right - rcClient.left) / nMaxLen) * i
-                     << " " << rcClient.bottom << " m\n"
-                     << rcClient.left +
-                            ((rcClient.right - rcClient.left) / nMaxLen) * i
-                     << " " << rcClient.top << " l S\n";
-            }
-
-            sLines << "Q\n";
-          }
-        } break;
-      }
-    }
-
-    IFX_Edit::DelEdit(pEdit);
-  }
-
-  CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() +
-                       sLines.GetByteString() + sBody.GetByteString();
-  WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
-}
-
-CPDF_Rect CPDFSDK_Widget::GetClientRect() const {
-  CPDF_Rect rcWindow = GetRotatedRect();
-  FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
-  switch (GetBorderStyle()) {
-    case BBS_BEVELED:
-    case BBS_INSET:
-      fBorderWidth *= 2.0f;
-      break;
-  }
-
-  return CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);
-}
-
-CPDF_Rect CPDFSDK_Widget::GetRotatedRect() const {
-  CPDF_Rect rectAnnot = GetRect();
-  FX_FLOAT fWidth = rectAnnot.right - rectAnnot.left;
-  FX_FLOAT fHeight = rectAnnot.top - rectAnnot.bottom;
-
-  CPDF_FormControl* pControl = GetFormControl();
-  CPDF_Rect rcPDFWindow;
-  switch (abs(pControl->GetRotation() % 360)) {
-    case 0:
-    case 180:
-    default:
-      rcPDFWindow = CPDF_Rect(0, 0, fWidth, fHeight);
-      break;
-    case 90:
-    case 270:
-      rcPDFWindow = CPDF_Rect(0, 0, fHeight, fWidth);
-      break;
-  }
-
-  return rcPDFWindow;
-}
-
-CFX_ByteString CPDFSDK_Widget::GetBackgroundAppStream() const {
-  CPWL_Color crBackground = GetFillPWLColor();
-  if (crBackground.nColorType != COLORTYPE_TRANSPARENT) {
-    return CPWL_Utils::GetRectFillAppStream(GetRotatedRect(), crBackground);
-  }
-  return "";
-}
-
-CFX_ByteString CPDFSDK_Widget::GetBorderAppStream() const {
-  CPDF_Rect rcWindow = GetRotatedRect();
-  CPWL_Color crBorder = GetBorderPWLColor();
-  CPWL_Color crBackground = GetFillPWLColor();
-  CPWL_Color crLeftTop, crRightBottom;
-
-  FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
-  int32_t nBorderStyle = 0;
-  CPWL_Dash dsBorder(3, 0, 0);
-
-  switch (GetBorderStyle()) {
-    case BBS_DASH:
-      nBorderStyle = PBS_DASH;
-      dsBorder = CPWL_Dash(3, 3, 0);
-      break;
-    case BBS_BEVELED:
-      nBorderStyle = PBS_BEVELED;
-      fBorderWidth *= 2;
-      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
-      crRightBottom = CPWL_Utils::DevideColor(crBackground, 2);
-      break;
-    case BBS_INSET:
-      nBorderStyle = PBS_INSET;
-      fBorderWidth *= 2;
-      crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5);
-      crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75);
-      break;
-    case BBS_UNDERLINE:
-      nBorderStyle = PBS_UNDERLINED;
-      break;
-    default:
-      nBorderStyle = PBS_SOLID;
-      break;
-  }
-
-  return CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
-                                        crLeftTop, crRightBottom, nBorderStyle,
-                                        dsBorder);
-}
-
-CFX_Matrix CPDFSDK_Widget::GetMatrix() const {
-  CFX_Matrix mt;
-  CPDF_FormControl* pControl = GetFormControl();
-  CPDF_Rect rcAnnot = GetRect();
-  FX_FLOAT fWidth = rcAnnot.right - rcAnnot.left;
-  FX_FLOAT fHeight = rcAnnot.top - rcAnnot.bottom;
-
-  switch (abs(pControl->GetRotation() % 360)) {
-    case 0:
-    default:
-      mt = CFX_Matrix(1, 0, 0, 1, 0, 0);
-      break;
-    case 90:
-      mt = CFX_Matrix(0, 1, -1, 0, fWidth, 0);
-      break;
-    case 180:
-      mt = CFX_Matrix(-1, 0, 0, -1, fWidth, fHeight);
-      break;
-    case 270:
-      mt = CFX_Matrix(0, -1, 1, 0, 0, fHeight);
-      break;
-  }
-
-  return mt;
-}
-
-CPWL_Color CPDFSDK_Widget::GetTextPWLColor() const {
-  CPWL_Color crText = CPWL_Color(COLORTYPE_GRAY, 0);
-
-  CPDF_FormControl* pFormCtrl = GetFormControl();
-  CPDF_DefaultAppearance da = pFormCtrl->GetDefaultAppearance();
-  if (da.HasColor()) {
-    int32_t iColorType;
-    FX_FLOAT fc[4];
-    da.GetColor(iColorType, fc);
-    crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
-  }
-
-  return crText;
-}
-
-CPWL_Color CPDFSDK_Widget::GetBorderPWLColor() const {
-  CPWL_Color crBorder;
-
-  CPDF_FormControl* pFormCtrl = GetFormControl();
-  int32_t iColorType;
-  FX_FLOAT fc[4];
-  pFormCtrl->GetOriginalBorderColor(iColorType, fc);
-  if (iColorType > 0)
-    crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
-
-  return crBorder;
-}
-
-CPWL_Color CPDFSDK_Widget::GetFillPWLColor() const {
-  CPWL_Color crFill;
-
-  CPDF_FormControl* pFormCtrl = GetFormControl();
-  int32_t iColorType;
-  FX_FLOAT fc[4];
-  pFormCtrl->GetOriginalBackgroundColor(iColorType, fc);
-  if (iColorType > 0)
-    crFill = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
-
-  return crFill;
-}
-
-void CPDFSDK_Widget::AddImageToAppearance(const CFX_ByteString& sAPType,
-                                          CPDF_Stream* pImage) {
-  CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
-  ASSERT(pDoc);
-
-  CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDict("AP");
-  CPDF_Stream* pStream = pAPDict->GetStream(sAPType);
-  CPDF_Dictionary* pStreamDict = pStream->GetDict();
-  CFX_ByteString sImageAlias = "IMG";
-
-  if (CPDF_Dictionary* pImageDict = pImage->GetDict()) {
-    sImageAlias = pImageDict->GetString("Name");
-    if (sImageAlias.IsEmpty())
-      sImageAlias = "IMG";
-  }
-
-  CPDF_Dictionary* pStreamResList = pStreamDict->GetDict("Resources");
-  if (!pStreamResList) {
-    pStreamResList = new CPDF_Dictionary();
-    pStreamDict->SetAt("Resources", pStreamResList);
-  }
-
-  if (pStreamResList) {
-    CPDF_Dictionary* pXObject = new CPDF_Dictionary;
-    pXObject->SetAtReference(sImageAlias, pDoc, pImage);
-    pStreamResList->SetAt("XObject", pXObject);
-  }
-}
-
-void CPDFSDK_Widget::RemoveAppearance(const CFX_ByteString& sAPType) {
-  if (CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDict("AP")) {
-    pAPDict->RemoveAt(sAPType);
-  }
-}
-
-FX_BOOL CPDFSDK_Widget::OnAAction(CPDF_AAction::AActionType type,
-                                  PDFSDK_FieldAction& data,
-                                  CPDFSDK_PageView* pPageView) {
-  CPDFSDK_Document* pDocument = pPageView->GetSDKDocument();
-  CPDFDoc_Environment* pEnv = pDocument->GetEnv();
-
-#ifdef PDF_ENABLE_XFA
-  CPDFXFA_Document* pDoc = pDocument->GetXFADocument();
-  if (IXFA_Widget* hWidget = GetMixXFAWidget()) {
-    XFA_EVENTTYPE eEventType = GetXFAEventType(type, data.bWillCommit);
-
-    if (eEventType != XFA_EVENT_Unknown) {
-      if (IXFA_WidgetHandler* 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 = data.sChange.GetLength() - 1; i >= 0; i--)
-          param.m_wsNewText.Insert(data.nSelStart, data.sChange[i]);
-        param.m_wsPrevText = data.sValue;
-
-        CXFA_WidgetAcc* pAcc = pXFAWidgetHandler->GetDataAcc(hWidget);
-        param.m_pTarget = pAcc;
-        int32_t nRet = pXFAWidgetHandler->ProcessEvent(pAcc, &param);
-
-        if (IXFA_DocView* pDocView = pDoc->GetXFADocView()) {
-          pDocView->UpdateDocView();
-        }
-
-        if (nRet == XFA_EVENTERROR_Sucess)
-          return TRUE;
-      }
-    }
-  }
-#endif  // PDF_ENABLE_XFA
-
-  CPDF_Action action = GetAAction(type);
-  if (action && action.GetType() != CPDF_Action::Unknown) {
-    CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander();
-    return pActionHandler->DoAction_Field(action, type, pDocument,
-                                          GetFormField(), data);
-  }
-  return FALSE;
-}
-
-CPDF_Action CPDFSDK_Widget::GetAAction(CPDF_AAction::AActionType eAAT) {
-  switch (eAAT) {
-    case CPDF_AAction::CursorEnter:
-    case CPDF_AAction::CursorExit:
-    case CPDF_AAction::ButtonDown:
-    case CPDF_AAction::ButtonUp:
-    case CPDF_AAction::GetFocus:
-    case CPDF_AAction::LoseFocus:
-    case CPDF_AAction::PageOpen:
-    case CPDF_AAction::PageClose:
-    case CPDF_AAction::PageVisible:
-    case CPDF_AAction::PageInvisible:
-      return CPDFSDK_BAAnnot::GetAAction(eAAT);
-
-    case CPDF_AAction::KeyStroke:
-    case CPDF_AAction::Format:
-    case CPDF_AAction::Validate:
-    case CPDF_AAction::Calculate: {
-      CPDF_FormField* pField = GetFormField();
-      if (CPDF_AAction aa = pField->GetAdditionalAction())
-        return aa.GetAction(eAAT);
-      return CPDFSDK_BAAnnot::GetAAction(eAAT);
-    }
-    default:
-      break;
-  }
-
-  return CPDF_Action();
-}
-
-CFX_WideString CPDFSDK_Widget::GetAlternateName() const {
-  CPDF_FormField* pFormField = GetFormField();
-  return pFormField->GetAlternateName();
-}
-
-int32_t CPDFSDK_Widget::GetAppearanceAge() const {
-  return m_nAppAge;
-}
-
-int32_t CPDFSDK_Widget::GetValueAge() const {
-  return m_nValueAge;
-}
-
-FX_BOOL CPDFSDK_Widget::HitTest(FX_FLOAT pageX, FX_FLOAT pageY) {
-  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(IXFA_Widget* pAnnot,
-                                     CPDFSDK_PageView* pPageView,
-                                     CPDFSDK_InterForm* pInterForm)
-    : CPDFSDK_Annot(pPageView), m_pInterForm(pInterForm), m_hXFAWidget(pAnnot) {
-}
-
-FX_BOOL CPDFSDK_XFAWidget::IsXFAField() {
-  return TRUE;
-}
-
-CFX_ByteString CPDFSDK_XFAWidget::GetType() const {
-  return FSDK_XFAWIDGET_TYPENAME;
-}
-
-CFX_FloatRect CPDFSDK_XFAWidget::GetRect() const {
-  CPDFSDK_PageView* pPageView = GetPageView();
-  CPDFSDK_Document* pDocument = pPageView->GetSDKDocument();
-  CPDFXFA_Document* pDoc = pDocument->GetXFADocument();
-  IXFA_DocView* pDocView = pDoc->GetXFADocView();
-  IXFA_WidgetHandler* pWidgetHandler = pDocView->GetWidgetHandler();
-
-  CFX_RectF rcBBox;
-  pWidgetHandler->GetRect(GetXFAWidget(), 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(NULL),
-#ifdef PDF_ENABLE_XFA
-      m_bXfaCalculate(TRUE),
-      m_bXfaValidationsEnabled(TRUE),
-#endif  // PDF_ENABLE_XFA
-      m_bCalculate(TRUE),
-      m_bBusy(FALSE) {
-  m_pInterForm = new CPDF_InterForm(m_pDocument->GetPDFDocument(), FALSE);
-  m_pInterForm->SetFormNotify(this);
-
-  for (int i = 0; i < kNumFieldTypes; ++i)
-    m_bNeedHightlight[i] = FALSE;
-  m_iHighlightAlpha = 0;
-}
-
-CPDFSDK_InterForm::~CPDFSDK_InterForm() {
-  delete m_pInterForm;
-  m_pInterForm = nullptr;
-  m_Map.clear();
-#ifdef PDF_ENABLE_XFA
-  m_XFAMap.RemoveAll();
-#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) 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;
-
-  CPDF_Dictionary* pControlDict = pControl->GetWidget();
-  CPDF_Document* pDocument = m_pDocument->GetPDFDocument();
-  CPDFSDK_PageView* pPage = nullptr;
-
-  if (CPDF_Dictionary* pPageDict = pControlDict->GetDict("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);
-    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->GetArray("Annots")) {
-        for (int j = 0, jsz = pAnnots->GetCount(); j < jsz; j++) {
-          CPDF_Object* pDict = pAnnots->GetElementValue(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(IXFA_Widget* hWidget,
-                                  CPDFSDK_XFAWidget* pWidget) {
-  m_XFAMap.SetAt(hWidget, pWidget);
-}
-
-void CPDFSDK_InterForm::RemoveXFAMap(IXFA_Widget* hWidget) {
-  m_XFAMap.RemoveKey(hWidget);
-}
-
-CPDFSDK_XFAWidget* CPDFSDK_InterForm::GetXFAWidget(IXFA_Widget* hWidget) {
-  CPDFSDK_XFAWidget* pWidget = NULL;
-  m_XFAMap.Lookup(hWidget, pWidget);
-
-  return pWidget;
-}
-
-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 && aAction.ActionExist(CPDF_AAction::Calculate)) {
-            CPDF_Action action = aAction.GetAction(CPDF_AAction::Calculate);
-            if (action) {
-              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 && aAction.ActionExist(CPDF_AAction::Format)) {
-    CPDF_Action action = aAction.GetAction(CPDF_AAction::Format);
-    if (action) {
-      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))
-      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)) {
-      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);
-    }
-  }
-}
-
-void CPDFSDK_InterForm::OnKeyStrokeCommit(CPDF_FormField* pFormField,
-                                          CFX_WideString& csValue,
-                                          FX_BOOL& bRC) {
-  CPDF_AAction aAction = pFormField->GetAdditionalAction();
-  if (aAction && aAction.ActionExist(CPDF_AAction::KeyStroke)) {
-    CPDF_Action action = aAction.GetAction(CPDF_AAction::KeyStroke);
-    if (action) {
-      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);
-      bRC = fa.bRC;
-    }
-  }
-}
-
-void CPDFSDK_InterForm::OnValidate(CPDF_FormField* pFormField,
-                                   CFX_WideString& csValue,
-                                   FX_BOOL& bRC) {
-  CPDF_AAction aAction = pFormField->GetAdditionalAction();
-  if (aAction && aAction.ActionExist(CPDF_AAction::Validate)) {
-    CPDF_Action action = aAction.GetAction(CPDF_AAction::Validate);
-    if (action) {
-      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);
-      bRC = fa.bRC;
-    }
-  }
-}
-
-FX_BOOL CPDFSDK_InterForm::DoAction_Hide(const CPDF_Action& action) {
-  ASSERT(action);
-
-  CPDF_ActionFields af = action.GetWidgets();
-  std::vector<CPDF_Object*> fieldObjects = af.GetAllFields();
-  std::vector<CPDF_FormField*> fields = GetFieldFromObjects(fieldObjects);
-
-  FX_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)) {
-        int 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.GetWidgets();
-    FX_DWORD 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,
-    FX_BOOL bIncludeOrExclude,
-    FX_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) {
-    CPDF_Dictionary* pMainDict = pFDF->GetRoot()->GetDict("FDF");
-    if (!pMainDict)
-      return FALSE;
-
-    // Get fields
-    CPDF_Array* pFields = pMainDict->GetArray("Fields");
-    if (!pFields)
-      return FALSE;
-
-    CFX_ByteTextBuf fdfEncodedData;
-
-    for (FX_DWORD i = 0; i < pFields->GetCount(); i++) {
-      CPDF_Dictionary* pField = pFields->GetDict(i);
-      if (!pField)
-        continue;
-      CFX_WideString name;
-      name = pField->GetUnicodeText("T");
-      CFX_ByteString name_b = CFX_ByteString::FromUnicode(name);
-      CFX_ByteString csBValue = pField->GetString("V");
-      CFX_WideString csWValue = PDF_DecodeText(csBValue);
-      CFX_ByteString csValue_b = CFX_ByteString::FromUnicode(csWValue);
-
-      fdfEncodedData = fdfEncodedData << name_b.GetBuffer(name_b.GetLength());
-      name_b.ReleaseBuffer();
-      fdfEncodedData = fdfEncodedData << "=";
-      fdfEncodedData = fdfEncodedData
-                       << csValue_b.GetBuffer(csValue_b.GetLength());
-      csValue_b.ReleaseBuffer();
-      if (i != pFields->GetCount() - 1)
-        fdfEncodedData = 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,
-    FX_BOOL bIncludeOrExclude,
-    CFX_ByteTextBuf& textBuf) {
-  std::unique_ptr<CFDF_Document> pFDF(m_pInterForm->ExportToFDF(
-      m_pDocument->GetPath(), fields, bIncludeOrExclude));
-  return pFDF ? pFDF->WriteBuf(textBuf) : FALSE;
-}
-
-#ifdef PDF_ENABLE_XFA
-void CPDFSDK_InterForm::SynchronizeField(CPDF_FormField* pFormField,
-                                         FX_BOOL bSynchronizeElse) {
-  ASSERT(pFormField != NULL);
-
-  int x = 0;
-  if (m_FieldSynchronizeMap.Lookup(pFormField, x))
-    return;
-
-  for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
-    CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
-    ASSERT(pFormCtrl != NULL);
-
-    ASSERT(m_pInterForm != NULL);
-    if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl)) {
-      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);
-  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);
-    pBuffer = NULL;
-  }
-
-  return TRUE;
-}
-
-FX_BOOL CPDFSDK_InterForm::ExportFormToFDFTextBuf(CFX_ByteTextBuf& textBuf) {
-  CFDF_Document* pFDF = m_pInterForm->ExportToFDF(m_pDocument->GetPath());
-  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);
-
-  CPDF_Dictionary* pActionDict = action.GetDict();
-  if (!pActionDict->KeyExist("Fields"))
-    return m_pInterForm->ResetForm(true);
-
-  CPDF_ActionFields af = action.GetWidgets();
-  FX_DWORD 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(const CPDF_FormField* pField,
-                                         CFX_WideString& csValue) {
-  CPDF_FormField* pFormField = (CPDF_FormField*)pField;
-  int nType = pFormField->GetFieldType();
-  if (nType == FIELDTYPE_COMBOBOX || nType == FIELDTYPE_TEXTFIELD) {
-    FX_BOOL bRC = TRUE;
-    OnKeyStrokeCommit(pFormField, csValue, bRC);
-    if (bRC) {
-      OnValidate(pFormField, csValue, bRC);
-      return bRC ? 1 : -1;
-    }
-    return -1;
-  }
-  return 0;
-}
-
-int CPDFSDK_InterForm::AfterValueChange(const CPDF_FormField* pField) {
-  CPDF_FormField* pFormField = (CPDF_FormField*)pField;
-#ifdef PDF_ENABLE_XFA
-  SynchronizeField(pFormField, FALSE);
-#endif  // PDF_ENABLE_XFA
-  int nType = pFormField->GetFieldType();
-  if (nType == FIELDTYPE_COMBOBOX || nType == FIELDTYPE_TEXTFIELD) {
-    OnCalculate(pFormField);
-    FX_BOOL bFormated = FALSE;
-    CFX_WideString sValue = OnFormat(pFormField, bFormated);
-    if (bFormated)
-      ResetFieldAppearance(pFormField, sValue.c_str(), TRUE);
-    else
-      ResetFieldAppearance(pFormField, NULL, TRUE);
-    UpdateField(pFormField);
-  }
-  return 0;
-}
-
-int CPDFSDK_InterForm::BeforeSelectionChange(const CPDF_FormField* pField,
-                                             CFX_WideString& csValue) {
-  CPDF_FormField* pFormField = (CPDF_FormField*)pField;
-  if (pFormField->GetFieldType() != FIELDTYPE_LISTBOX)
-    return 0;
-
-  FX_BOOL bRC = TRUE;
-  OnKeyStrokeCommit(pFormField, csValue, bRC);
-  if (!bRC)
-    return -1;
-
-  OnValidate(pFormField, csValue, bRC);
-  if (!bRC)
-    return -1;
-
-  return 1;
-}
-
-int CPDFSDK_InterForm::AfterSelectionChange(const CPDF_FormField* pField) {
-  CPDF_FormField* pFormField = (CPDF_FormField*)pField;
-  if (pFormField->GetFieldType() == FIELDTYPE_LISTBOX) {
-    OnCalculate(pFormField);
-    ResetFieldAppearance(pFormField, NULL, TRUE);
-    UpdateField(pFormField);
-  }
-  return 0;
-}
-
-int CPDFSDK_InterForm::AfterCheckedStatusChange(
-    const CPDF_FormField* pField,
-    const CFX_ByteArray& statusArray) {
-  CPDF_FormField* pFormField = (CPDF_FormField*)pField;
-  int nType = pFormField->GetFieldType();
-  if (nType == FIELDTYPE_CHECKBOX || nType == FIELDTYPE_RADIOBUTTON) {
-    OnCalculate(pFormField);
-    UpdateField(pFormField);
-  }
-  return 0;
-}
-
-int CPDFSDK_InterForm::BeforeFormReset(const CPDF_InterForm* pForm) {
-  return 0;
-}
-
-int CPDFSDK_InterForm::AfterFormReset(const CPDF_InterForm* pForm) {
-  OnCalculate(nullptr);
-  return 0;
-}
-
-int CPDFSDK_InterForm::BeforeFormImportData(const CPDF_InterForm* pForm) {
-  return 0;
-}
-
-int CPDFSDK_InterForm::AfterFormImportData(const CPDF_InterForm* pForm) {
-  OnCalculate(nullptr);
-  return 0;
-}
-
-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_pPageView(pPageView),
-      m_sType(sType),
-      m_sSubType(sSubType),
-      m_nTabs(BAI_STRUCTURE) {
-  CPDF_Page* pPDFPage = m_pPageView->GetPDFPage();
-  CFX_ByteString sTabs = pPDFPage->m_pFormDict->GetString("Tabs");
-
-  if (sTabs == "R") {
-    m_nTabs = BAI_ROW;
-  } else if (sTabs == "C") {
-    m_nTabs = BAI_COLUMN;
-  } else {
-    m_nTabs = BAI_STRUCTURE;
-  }
-
-  GenerateResults();
-}
-
-CBA_AnnotIterator::~CBA_AnnotIterator() {
-  m_Annots.RemoveAll();
-}
-
-CPDFSDK_Annot* CBA_AnnotIterator::GetFirstAnnot() {
-  if (m_Annots.GetSize() > 0)
-    return m_Annots[0];
-
-  return NULL;
-}
-
-CPDFSDK_Annot* CBA_AnnotIterator::GetLastAnnot() {
-  if (m_Annots.GetSize() > 0)
-    return m_Annots[m_Annots.GetSize() - 1];
-
-  return NULL;
-}
-
-CPDFSDK_Annot* CBA_AnnotIterator::GetNextAnnot(CPDFSDK_Annot* pAnnot) {
-  for (int i = 0, sz = m_Annots.GetSize(); i < sz; ++i) {
-    if (m_Annots[i] == pAnnot)
-      return (i + 1 < sz) ? m_Annots[i + 1] : m_Annots[0];
-  }
-  return NULL;
-}
-
-CPDFSDK_Annot* CBA_AnnotIterator::GetPrevAnnot(CPDFSDK_Annot* pAnnot) {
-  for (int i = 0, sz = m_Annots.GetSize(); i < sz; ++i) {
-    if (m_Annots[i] == pAnnot)
-      return (i - 1 >= 0) ? m_Annots[i - 1] : m_Annots[sz - 1];
-  }
-  return NULL;
-}
-
-int CBA_AnnotIterator::CompareByLeft(CPDFSDK_Annot* p1, CPDFSDK_Annot* p2) {
-  ASSERT(p1);
-  ASSERT(p2);
-
-  CPDF_Rect rcAnnot1 = GetAnnotRect(p1);
-  CPDF_Rect rcAnnot2 = GetAnnotRect(p2);
-
-  if (rcAnnot1.left < rcAnnot2.left)
-    return -1;
-  if (rcAnnot1.left > rcAnnot2.left)
-    return 1;
-  return 0;
-}
-
-int CBA_AnnotIterator::CompareByTop(CPDFSDK_Annot* p1, CPDFSDK_Annot* p2) {
-  ASSERT(p1);
-  ASSERT(p2);
-
-  CPDF_Rect rcAnnot1 = GetAnnotRect(p1);
-  CPDF_Rect rcAnnot2 = GetAnnotRect(p2);
-
-  if (rcAnnot1.top < rcAnnot2.top)
-    return -1;
-  if (rcAnnot1.top > rcAnnot2.top)
-    return 1;
-  return 0;
-}
-
-void CBA_AnnotIterator::GenerateResults() {
-  switch (m_nTabs) {
-    case BAI_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.Add(pAnnot);
-      }
-      break;
-    }
-    case BAI_ROW: {
-      CPDFSDK_SortAnnots 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.Add(pAnnot);
-      }
-
-      if (sa.GetSize() > 0)
-        sa.Sort(CBA_AnnotIterator::CompareByLeft);
-
-      while (sa.GetSize() > 0) {
-        int nLeftTopIndex = -1;
-        FX_FLOAT fTop = 0.0f;
-
-        for (int i = sa.GetSize() - 1; i >= 0; i--) {
-          CPDFSDK_Annot* pAnnot = sa.GetAt(i);
-          ASSERT(pAnnot);
-
-          CPDF_Rect rcAnnot = GetAnnotRect(pAnnot);
-
-          if (rcAnnot.top > fTop) {
-            nLeftTopIndex = i;
-            fTop = rcAnnot.top;
-          }
-        }
-
-        if (nLeftTopIndex >= 0) {
-          CPDFSDK_Annot* pLeftTopAnnot = sa.GetAt(nLeftTopIndex);
-          ASSERT(pLeftTopAnnot);
-
-          CPDF_Rect rcLeftTop = GetAnnotRect(pLeftTopAnnot);
-
-          m_Annots.Add(pLeftTopAnnot);
-          sa.RemoveAt(nLeftTopIndex);
-
-          CFX_ArrayTemplate<int> aSelect;
-
-          for (int i = 0, sz = sa.GetSize(); i < sz; ++i) {
-            CPDFSDK_Annot* pAnnot = sa.GetAt(i);
-            ASSERT(pAnnot);
-
-            CPDF_Rect rcAnnot = GetAnnotRect(pAnnot);
-            FX_FLOAT fCenterY = (rcAnnot.top + rcAnnot.bottom) / 2.0f;
-            if (fCenterY > rcLeftTop.bottom && fCenterY < rcLeftTop.top)
-              aSelect.Add(i);
-          }
-
-          for (int i = 0, sz = aSelect.GetSize(); i < sz; ++i)
-            m_Annots.Add(sa[aSelect[i]]);
-
-          for (int i = aSelect.GetSize() - 1; i >= 0; --i)
-              sa.RemoveAt(aSelect[i]);
-
-          aSelect.RemoveAll();
-        }
-      }
-      sa.RemoveAll();
-      break;
-    }
-    case BAI_COLUMN: {
-      CPDFSDK_SortAnnots 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.Add(pAnnot);
-      }
-
-      if (sa.GetSize() > 0)
-        sa.Sort(CBA_AnnotIterator::CompareByTop, FALSE);
-
-      while (sa.GetSize() > 0) {
-        int nLeftTopIndex = -1;
-        FX_FLOAT fLeft = -1.0f;
-
-        for (int i = sa.GetSize() - 1; i >= 0; --i) {
-          CPDFSDK_Annot* pAnnot = sa.GetAt(i);
-          ASSERT(pAnnot);
-
-          CPDF_Rect rcAnnot = GetAnnotRect(pAnnot);
-
-          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.GetAt(nLeftTopIndex);
-          ASSERT(pLeftTopAnnot);
-
-          CPDF_Rect rcLeftTop = GetAnnotRect(pLeftTopAnnot);
-
-          m_Annots.Add(pLeftTopAnnot);
-          sa.RemoveAt(nLeftTopIndex);
-
-          CFX_ArrayTemplate<int> aSelect;
-          for (int i = 0, sz = sa.GetSize(); i < sz; ++i) {
-            CPDFSDK_Annot* pAnnot = sa.GetAt(i);
-            ASSERT(pAnnot);
-
-            CPDF_Rect rcAnnot = GetAnnotRect(pAnnot);
-            FX_FLOAT fCenterX = (rcAnnot.left + rcAnnot.right) / 2.0f;
-            if (fCenterX > rcLeftTop.left && fCenterX < rcLeftTop.right)
-              aSelect.Add(i);
-          }
-
-          for (int i = 0, sz = aSelect.GetSize(); i < sz; ++i)
-            m_Annots.Add(sa[aSelect[i]]);
-
-          for (int i = aSelect.GetSize() - 1; i >= 0; --i)
-            sa.RemoveAt(aSelect[i]);
-
-          aSelect.RemoveAll();
-        }
-      }
-      sa.RemoveAll();
-      break;
-    }
-  }
-}
-
-CPDF_Rect CBA_AnnotIterator::GetAnnotRect(CPDFSDK_Annot* pAnnot) {
-  CPDF_Rect rcAnnot;
-  pAnnot->GetPDFAnnot()->GetRect(rcAnnot);
-  return rcAnnot;
-}
diff --git a/fpdfsdk/src/fsdk_mgr.cpp b/fpdfsdk/src/fsdk_mgr.cpp
deleted file mode 100644
index 6d656a0..0000000
--- a/fpdfsdk/src/fsdk_mgr.cpp
+++ /dev/null
@@ -1,1169 +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
-
-#include <algorithm>
-#include <memory>
-
-#include "fpdfsdk/include/fsdk_mgr.h"
-
-#include "fpdfsdk/include/formfiller/FFL_FormFiller.h"
-#include "fpdfsdk/include/fsdk_define.h"
-#include "fpdfsdk/include/javascript/IJavaScript.h"
-#include "public/fpdf_ext.h"
-#include "third_party/base/stl_util.h"
-
-#ifdef PDF_ENABLE_XFA
-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_app.h"
-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h"
-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_page.h"
-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h"
-#endif  // PDF_ENABLE_XFA
-
-#if _FX_OS_ == _FX_ANDROID_
-#include "time.h"
-#else
-#include <ctime>
-#endif
-
-class CFX_SystemHandler : public IFX_SystemHandler {
- public:
-  explicit CFX_SystemHandler(CPDFDoc_Environment* pEnv)
-      : m_pEnv(pEnv), m_nCharSet(-1) {}
-  ~CFX_SystemHandler() override {}
-
- public:
-  // IFX_SystemHandler
-  void InvalidateRect(FX_HWND hWnd, FX_RECT rect) override;
-  void OutputSelectedRect(void* pFormFiller, CPDF_Rect& rect) override;
-  FX_BOOL IsSelectionImplemented() override;
-  CFX_WideString GetClipboardText(FX_HWND hWnd) override { return L""; }
-  FX_BOOL SetClipboardText(FX_HWND hWnd, CFX_WideString string) override {
-    return FALSE;
-  }
-  void ClientToScreen(FX_HWND hWnd, int32_t& x, int32_t& y) override {}
-  void ScreenToClient(FX_HWND hWnd, int32_t& x, int32_t& y) override {}
-  void SetCursor(int32_t nCursorType) override;
-  FX_HMENU CreatePopupMenu() override { return NULL; }
-  FX_BOOL AppendMenuItem(FX_HMENU hMenu,
-                         int32_t nIDNewItem,
-                         CFX_WideString string) override {
-    return FALSE;
-  }
-  FX_BOOL EnableMenuItem(FX_HMENU hMenu,
-                         int32_t nIDItem,
-                         FX_BOOL bEnabled) override {
-    return FALSE;
-  }
-  int32_t TrackPopupMenu(FX_HMENU hMenu,
-                         int32_t x,
-                         int32_t y,
-                         FX_HWND hParent) override {
-    return -1;
-  }
-  void DestroyMenu(FX_HMENU hMenu) override {}
-  CFX_ByteString GetNativeTrueTypeFont(int32_t nCharset) override;
-  FX_BOOL FindNativeTrueTypeFont(int32_t nCharset,
-                                 CFX_ByteString sFontFaceName) override;
-  CPDF_Font* AddNativeTrueTypeFontToPDF(CPDF_Document* pDoc,
-                                        CFX_ByteString sFontFaceName,
-                                        uint8_t nCharset) override;
-  int32_t SetTimer(int32_t uElapse, TimerCallback lpTimerFunc) override;
-  void KillTimer(int32_t nID) override;
-  FX_BOOL IsSHIFTKeyDown(FX_DWORD nFlag) override {
-    return m_pEnv->FFI_IsSHIFTKeyDown(nFlag);
-  }
-  FX_BOOL IsCTRLKeyDown(FX_DWORD nFlag) override {
-    return m_pEnv->FFI_IsCTRLKeyDown(nFlag);
-  }
-  FX_BOOL IsALTKeyDown(FX_DWORD nFlag) override {
-    return m_pEnv->FFI_IsALTKeyDown(nFlag);
-  }
-  FX_BOOL IsINSERTKeyDown(FX_DWORD nFlag) override {
-    return m_pEnv->FFI_IsINSERTKeyDown(nFlag);
-  }
-  FX_SYSTEMTIME GetLocalTime() override;
-  int32_t GetCharSet() override { return m_nCharSet; }
-  void SetCharSet(int32_t nCharSet) override { m_nCharSet = nCharSet; }
-
- private:
-  CPDFDoc_Environment* m_pEnv;
-  int m_nCharSet;
-};
-
-void CFX_SystemHandler::SetCursor(int32_t nCursorType) {
-  m_pEnv->FFI_SetCursor(nCursorType);
-}
-
-void CFX_SystemHandler::InvalidateRect(FX_HWND hWnd, FX_RECT rect) {
-  CPDFSDK_Annot* pSDKAnnot = (CPDFSDK_Annot*)hWnd;
-  CPDFSDK_PageView* pPageView = pSDKAnnot->GetPageView();
-  UnderlyingPageType* pPage = pSDKAnnot->GetUnderlyingPage();
-  if (!pPage || !pPageView)
-    return;
-  CFX_Matrix page2device;
-  pPageView->GetCurrentMatrix(page2device);
-  CFX_Matrix device2page;
-  device2page.SetReverse(page2device);
-  FX_FLOAT left, top, right, bottom;
-  device2page.Transform((FX_FLOAT)rect.left, (FX_FLOAT)rect.top, left, top);
-  device2page.Transform((FX_FLOAT)rect.right, (FX_FLOAT)rect.bottom, right,
-                        bottom);
-  CPDF_Rect rcPDF(left, bottom, right, top);
-  rcPDF.Normalize();
-
-  m_pEnv->FFI_Invalidate(pPage, rcPDF.left, rcPDF.top, rcPDF.right,
-                         rcPDF.bottom);
-}
-void CFX_SystemHandler::OutputSelectedRect(void* pFormFiller, CPDF_Rect& rect) {
-  CFFL_FormFiller* pFFL = (CFFL_FormFiller*)pFormFiller;
-  if (pFFL) {
-    CPDF_Point leftbottom = CPDF_Point(rect.left, rect.bottom);
-    CPDF_Point righttop = CPDF_Point(rect.right, rect.top);
-    CPDF_Point ptA = pFFL->PWLtoFFL(leftbottom);
-    CPDF_Point ptB = pFFL->PWLtoFFL(righttop);
-    CPDFSDK_Annot* pAnnot = pFFL->GetSDKAnnot();
-    UnderlyingPageType* pPage = pAnnot->GetUnderlyingPage();
-    ASSERT(pPage);
-    m_pEnv->FFI_OutputSelectedRect(pPage, ptA.x, ptB.y, ptB.x, ptA.y);
-  }
-}
-
-FX_BOOL CFX_SystemHandler::IsSelectionImplemented() {
-  if (m_pEnv) {
-    FPDF_FORMFILLINFO* pInfo = m_pEnv->GetFormFillInfo();
-    if (pInfo && pInfo->FFI_OutputSelectedRect)
-      return TRUE;
-  }
-  return FALSE;
-}
-
-CFX_ByteString CFX_SystemHandler::GetNativeTrueTypeFont(int32_t nCharset) {
-  return "";
-}
-
-FX_BOOL CFX_SystemHandler::FindNativeTrueTypeFont(
-    int32_t nCharset,
-    CFX_ByteString sFontFaceName) {
-  CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr();
-  if (!pFontMgr)
-    return FALSE;
-
-  CFX_FontMapper* pFontMapper = pFontMgr->GetBuiltinMapper();
-  if (!pFontMapper)
-    return FALSE;
-
-  int nSize = pFontMapper->m_InstalledTTFonts.GetSize();
-  if (nSize == 0) {
-    pFontMapper->LoadInstalledFonts();
-    nSize = pFontMapper->m_InstalledTTFonts.GetSize();
-  }
-
-  for (int i = 0; i < nSize; ++i) {
-    if (pFontMapper->m_InstalledTTFonts[i].Compare(sFontFaceName))
-      return TRUE;
-  }
-
-  return FALSE;
-}
-
-static int CharSet2CP(int charset) {
-  if (charset == 128)
-    return 932;
-  if (charset == 134)
-    return 936;
-  if (charset == 129)
-    return 949;
-  if (charset == 136)
-    return 950;
-  return 0;
-}
-CPDF_Font* CFX_SystemHandler::AddNativeTrueTypeFontToPDF(
-    CPDF_Document* pDoc,
-    CFX_ByteString sFontFaceName,
-    uint8_t nCharset) {
-  if (pDoc) {
-    CFX_Font* pFXFont = new CFX_Font();
-    pFXFont->LoadSubst(sFontFaceName, TRUE, 0, 0, 0, CharSet2CP(nCharset),
-                       FALSE);
-    CPDF_Font* pFont = pDoc->AddFont(pFXFont, nCharset, FALSE);
-    delete pFXFont;
-    return pFont;
-  }
-
-  return NULL;
-}
-
-int32_t CFX_SystemHandler::SetTimer(int32_t uElapse,
-                                    TimerCallback lpTimerFunc) {
-  return m_pEnv->FFI_SetTimer(uElapse, lpTimerFunc);
-}
-void CFX_SystemHandler::KillTimer(int32_t nID) {
-  m_pEnv->FFI_KillTimer(nID);
-}
-
-FX_SYSTEMTIME CFX_SystemHandler::GetLocalTime() {
-  return m_pEnv->FFI_GetLocalTime();
-}
-
-CPDFDoc_Environment::CPDFDoc_Environment(UnderlyingDocumentType* pDoc,
-                                         FPDF_FORMFILLINFO* pFFinfo)
-    : m_pInfo(pFFinfo), m_pSDKDoc(NULL), m_pUnderlyingDoc(pDoc) {
-  m_pSysHandler.reset(new CFX_SystemHandler(this));
-}
-
-CPDFDoc_Environment::~CPDFDoc_Environment() {
-#ifdef PDF_ENABLE_XFA
-  CPDFXFA_App* pProvider = CPDFXFA_App::GetInstance();
-  if (pProvider->m_pEnvList.GetSize() == 0)
-    pProvider->SetJavaScriptInitialized(FALSE);
-#endif  // PDF_ENABLE_XFA
-}
-
-int CPDFDoc_Environment::JS_appAlert(const FX_WCHAR* Msg,
-                                     const FX_WCHAR* Title,
-                                     FX_UINT Type,
-                                     FX_UINT Icon) {
-  if (m_pInfo && m_pInfo->m_pJsPlatform && m_pInfo->m_pJsPlatform->app_alert) {
-    CFX_ByteString bsMsg = CFX_WideString(Msg).UTF16LE_Encode();
-    CFX_ByteString bsTitle = CFX_WideString(Title).UTF16LE_Encode();
-    FPDF_WIDESTRING pMsg = (FPDF_WIDESTRING)bsMsg.GetBuffer(bsMsg.GetLength());
-    FPDF_WIDESTRING pTitle =
-        (FPDF_WIDESTRING)bsTitle.GetBuffer(bsTitle.GetLength());
-    int ret = m_pInfo->m_pJsPlatform->app_alert(m_pInfo->m_pJsPlatform, pMsg,
-                                                pTitle, Type, Icon);
-    bsMsg.ReleaseBuffer();
-    bsTitle.ReleaseBuffer();
-    return ret;
-  }
-  return -1;
-}
-
-int CPDFDoc_Environment::JS_appResponse(const FX_WCHAR* Question,
-                                        const FX_WCHAR* Title,
-                                        const FX_WCHAR* Default,
-                                        const FX_WCHAR* cLabel,
-                                        FPDF_BOOL bPassword,
-                                        void* response,
-                                        int length) {
-  if (m_pInfo && m_pInfo->m_pJsPlatform &&
-      m_pInfo->m_pJsPlatform->app_response) {
-    CFX_ByteString bsQuestion = CFX_WideString(Question).UTF16LE_Encode();
-    CFX_ByteString bsTitle = CFX_WideString(Title).UTF16LE_Encode();
-    CFX_ByteString bsDefault = CFX_WideString(Default).UTF16LE_Encode();
-    CFX_ByteString bsLabel = CFX_WideString(cLabel).UTF16LE_Encode();
-    FPDF_WIDESTRING pQuestion =
-        (FPDF_WIDESTRING)bsQuestion.GetBuffer(bsQuestion.GetLength());
-    FPDF_WIDESTRING pTitle =
-        (FPDF_WIDESTRING)bsTitle.GetBuffer(bsTitle.GetLength());
-    FPDF_WIDESTRING pDefault =
-        (FPDF_WIDESTRING)bsDefault.GetBuffer(bsDefault.GetLength());
-    FPDF_WIDESTRING pLabel =
-        (FPDF_WIDESTRING)bsLabel.GetBuffer(bsLabel.GetLength());
-    int ret = m_pInfo->m_pJsPlatform->app_response(
-        m_pInfo->m_pJsPlatform, pQuestion, pTitle, pDefault, pLabel, bPassword,
-        response, length);
-    bsQuestion.ReleaseBuffer();
-    bsTitle.ReleaseBuffer();
-    bsDefault.ReleaseBuffer();
-    bsLabel.ReleaseBuffer();
-    return ret;
-  }
-  return -1;
-}
-
-CFX_WideString CPDFDoc_Environment::JS_fieldBrowse() {
-  if (!m_pInfo || !m_pInfo->m_pJsPlatform ||
-      !m_pInfo->m_pJsPlatform->Field_browse) {
-    return L"";
-  }
-
-  const int nRequiredLen =
-      m_pInfo->m_pJsPlatform->Field_browse(m_pInfo->m_pJsPlatform, nullptr, 0);
-  if (nRequiredLen <= 0)
-    return L"";
-
-  std::unique_ptr<char[]> pBuff(new char[nRequiredLen]);
-  memset(pBuff.get(), 0, nRequiredLen);
-  const int nActualLen = m_pInfo->m_pJsPlatform->Field_browse(
-      m_pInfo->m_pJsPlatform, pBuff.get(), nRequiredLen);
-  if (nActualLen <= 0 || nActualLen > nRequiredLen)
-    return L"";
-
-  CFX_ByteString bsRet = CFX_ByteString(pBuff.get(), nActualLen);
-  CFX_WideString wsRet = CFX_WideString::FromLocal(bsRet);
-  return wsRet;
-}
-
-CFX_WideString CPDFDoc_Environment::JS_docGetFilePath() {
-  if (!m_pInfo || !m_pInfo->m_pJsPlatform ||
-      !m_pInfo->m_pJsPlatform->Doc_getFilePath) {
-    return L"";
-  }
-
-  const int nRequiredLen = m_pInfo->m_pJsPlatform->Doc_getFilePath(
-      m_pInfo->m_pJsPlatform, nullptr, 0);
-  if (nRequiredLen <= 0)
-    return L"";
-
-  std::unique_ptr<char[]> pBuff(new char[nRequiredLen]);
-  memset(pBuff.get(), 0, nRequiredLen);
-  const int nActualLen = m_pInfo->m_pJsPlatform->Doc_getFilePath(
-      m_pInfo->m_pJsPlatform, pBuff.get(), nRequiredLen);
-  if (nActualLen <= 0 || nActualLen > nRequiredLen)
-    return L"";
-
-  CFX_ByteString bsRet = CFX_ByteString(pBuff.get(), nActualLen);
-  CFX_WideString wsRet = CFX_WideString::FromLocal(bsRet);
-  return wsRet;
-}
-
-void CPDFDoc_Environment::JS_docSubmitForm(void* formData,
-                                           int length,
-                                           const FX_WCHAR* URL) {
-  if (m_pInfo && m_pInfo->m_pJsPlatform &&
-      m_pInfo->m_pJsPlatform->Doc_submitForm) {
-    CFX_ByteString bsDestination = CFX_WideString(URL).UTF16LE_Encode();
-    FPDF_WIDESTRING pDestination =
-        (FPDF_WIDESTRING)bsDestination.GetBuffer(bsDestination.GetLength());
-    m_pInfo->m_pJsPlatform->Doc_submitForm(m_pInfo->m_pJsPlatform, formData,
-                                           length, pDestination);
-    bsDestination.ReleaseBuffer();
-  }
-}
-
-void CPDFDoc_Environment::JS_docmailForm(void* mailData,
-                                         int length,
-                                         FPDF_BOOL bUI,
-                                         const FX_WCHAR* To,
-                                         const FX_WCHAR* Subject,
-                                         const FX_WCHAR* CC,
-                                         const FX_WCHAR* BCC,
-                                         const FX_WCHAR* Msg) {
-  if (m_pInfo && m_pInfo->m_pJsPlatform && m_pInfo->m_pJsPlatform->Doc_mail) {
-    CFX_ByteString bsTo = CFX_WideString(To).UTF16LE_Encode();
-    CFX_ByteString bsCC = CFX_WideString(Subject).UTF16LE_Encode();
-    CFX_ByteString bsBcc = CFX_WideString(BCC).UTF16LE_Encode();
-    CFX_ByteString bsSubject = CFX_WideString(Subject).UTF16LE_Encode();
-    CFX_ByteString bsMsg = CFX_WideString(Msg).UTF16LE_Encode();
-    FPDF_WIDESTRING pTo = (FPDF_WIDESTRING)bsTo.GetBuffer(bsTo.GetLength());
-    FPDF_WIDESTRING pCC = (FPDF_WIDESTRING)bsCC.GetBuffer(bsCC.GetLength());
-    FPDF_WIDESTRING pBcc = (FPDF_WIDESTRING)bsBcc.GetBuffer(bsBcc.GetLength());
-    FPDF_WIDESTRING pSubject =
-        (FPDF_WIDESTRING)bsSubject.GetBuffer(bsSubject.GetLength());
-    FPDF_WIDESTRING pMsg = (FPDF_WIDESTRING)bsMsg.GetBuffer(bsMsg.GetLength());
-    m_pInfo->m_pJsPlatform->Doc_mail(m_pInfo->m_pJsPlatform, mailData, length,
-                                     bUI, pTo, pSubject, pCC, pBcc, pMsg);
-    bsTo.ReleaseBuffer();
-    bsCC.ReleaseBuffer();
-    bsBcc.ReleaseBuffer();
-    bsSubject.ReleaseBuffer();
-    bsMsg.ReleaseBuffer();
-  }
-}
-
-IJS_Runtime* CPDFDoc_Environment::GetJSRuntime() {
-  if (!IsJSInitiated())
-    return NULL;
-  if (!m_pJSRuntime)
-    m_pJSRuntime.reset(IJS_Runtime::Create(this));
-  return m_pJSRuntime.get();
-}
-
-CPDFSDK_AnnotHandlerMgr* CPDFDoc_Environment::GetAnnotHandlerMgr() {
-  if (!m_pAnnotHandlerMgr)
-    m_pAnnotHandlerMgr.reset(new CPDFSDK_AnnotHandlerMgr(this));
-  return m_pAnnotHandlerMgr.get();
-}
-
-CPDFSDK_ActionHandler* CPDFDoc_Environment::GetActionHander() {
-  if (!m_pActionHandler)
-    m_pActionHandler.reset(new CPDFSDK_ActionHandler());
-  return m_pActionHandler.get();
-}
-
-CFFL_IFormFiller* CPDFDoc_Environment::GetIFormFiller() {
-  if (!m_pIFormFiller)
-    m_pIFormFiller.reset(new CFFL_IFormFiller(this));
-  return m_pIFormFiller.get();
-}
-
-CPDFSDK_Document::CPDFSDK_Document(UnderlyingDocumentType* pDoc,
-                                   CPDFDoc_Environment* pEnv)
-    : m_pDoc(pDoc),
-      m_pFocusAnnot(nullptr),
-      m_pEnv(pEnv),
-      m_bChangeMask(FALSE),
-      m_bBeingDestroyed(FALSE) {}
-
-CPDFSDK_Document::~CPDFSDK_Document() {
-  m_bBeingDestroyed = TRUE;
-
-  for (auto& it : m_pageMap)
-    it.second->KillFocusAnnotIfNeeded();
-
-  for (auto& it : m_pageMap)
-    delete it.second;
-  m_pageMap.clear();
-}
-
-CPDFSDK_PageView* CPDFSDK_Document::GetPageView(
-    UnderlyingPageType* pUnderlyingPage,
-    FX_BOOL ReNew) {
-  auto it = m_pageMap.find(pUnderlyingPage);
-  if (it != m_pageMap.end())
-    return it->second;
-
-  if (!ReNew)
-    return nullptr;
-
-  CPDFSDK_PageView* pPageView = new CPDFSDK_PageView(this, pUnderlyingPage);
-  m_pageMap[pUnderlyingPage] = pPageView;
-  // Delay to load all the annotations, to avoid endless loop.
-  pPageView->LoadFXAnnots();
-  return pPageView;
-}
-
-CPDFSDK_PageView* CPDFSDK_Document::GetCurrentView() {
-  UnderlyingPageType* pPage =
-      UnderlyingFromFPDFPage(m_pEnv->FFI_GetCurrentPage(m_pDoc));
-  return pPage ? GetPageView(pPage, TRUE) : nullptr;
-}
-
-CPDFSDK_PageView* CPDFSDK_Document::GetPageView(int nIndex) {
-  UnderlyingPageType* pTempPage =
-      UnderlyingFromFPDFPage(m_pEnv->FFI_GetPage(m_pDoc, nIndex));
-  if (!pTempPage)
-    return nullptr;
-
-  auto it = m_pageMap.find(pTempPage);
-  return it->second;
-}
-
-void CPDFSDK_Document::ProcJavascriptFun() {
-  CPDF_Document* pPDFDoc = GetPDFDocument();
-  CPDF_DocJSActions docJS(pPDFDoc);
-  int iCount = docJS.CountJSActions();
-  if (iCount < 1)
-    return;
-  for (int i = 0; i < iCount; i++) {
-    CFX_ByteString csJSName;
-    CPDF_Action jsAction = docJS.GetJSAction(i, csJSName);
-    if (m_pEnv->GetActionHander())
-      m_pEnv->GetActionHander()->DoAction_JavaScript(
-          jsAction, CFX_WideString::FromLocal(csJSName), this);
-  }
-}
-
-FX_BOOL CPDFSDK_Document::ProcOpenAction() {
-  if (!m_pDoc)
-    return FALSE;
-
-  CPDF_Dictionary* pRoot = GetPDFDocument()->GetRoot();
-  if (!pRoot)
-    return FALSE;
-
-  CPDF_Object* pOpenAction = pRoot->GetDict("OpenAction");
-  if (!pOpenAction)
-    pOpenAction = pRoot->GetArray("OpenAction");
-
-  if (!pOpenAction)
-    return FALSE;
-
-  if (pOpenAction->IsArray())
-    return TRUE;
-
-  if (CPDF_Dictionary* pDict = pOpenAction->AsDictionary()) {
-    CPDF_Action action(pDict);
-    if (m_pEnv->GetActionHander())
-      m_pEnv->GetActionHander()->DoAction_DocOpen(action, this);
-    return TRUE;
-  }
-  return FALSE;
-}
-
-CPDF_OCContext* CPDFSDK_Document::GetOCContext() {
-  if (!m_pOccontent)
-    m_pOccontent.reset(new CPDF_OCContext(GetPDFDocument()));
-  return m_pOccontent.get();
-}
-
-void CPDFSDK_Document::RemovePageView(UnderlyingPageType* pUnderlyingPage) {
-  auto it = m_pageMap.find(pUnderlyingPage);
-  if (it == m_pageMap.end())
-    return;
-
-  CPDFSDK_PageView* pPageView = it->second;
-  if (pPageView->IsLocked())
-    return;
-
-  pPageView->KillFocusAnnotIfNeeded();
-  delete pPageView;
-  m_pageMap.erase(it);
-}
-
-UnderlyingPageType* CPDFSDK_Document::GetPage(int nIndex) {
-  return UnderlyingFromFPDFPage(m_pEnv->FFI_GetPage(m_pDoc, nIndex));
-}
-
-CPDFSDK_InterForm* CPDFSDK_Document::GetInterForm() {
-  if (!m_pInterForm)
-    m_pInterForm.reset(new CPDFSDK_InterForm(this));
-  return m_pInterForm.get();
-}
-
-void CPDFSDK_Document::UpdateAllViews(CPDFSDK_PageView* pSender,
-                                      CPDFSDK_Annot* pAnnot) {
-  for (const auto& it : m_pageMap) {
-    CPDFSDK_PageView* pPageView = it.second;
-    if (pPageView != pSender) {
-      pPageView->UpdateView(pAnnot);
-    }
-  }
-}
-
-CPDFSDK_Annot* CPDFSDK_Document::GetFocusAnnot() {
-  return m_pFocusAnnot;
-}
-
-FX_BOOL CPDFSDK_Document::SetFocusAnnot(CPDFSDK_Annot* pAnnot, FX_UINT nFlag) {
-  if (m_bBeingDestroyed)
-    return FALSE;
-
-  if (m_pFocusAnnot == pAnnot)
-    return TRUE;
-
-  if (m_pFocusAnnot) {
-    if (!KillFocusAnnot(nFlag))
-      return FALSE;
-  }
-
-  if (!pAnnot)
-    return FALSE;
-
-#ifdef PDF_ENABLE_XFA
-  CPDFSDK_Annot* pLastFocusAnnot = m_pFocusAnnot;
-#endif  // PDF_ENABLE_XFA
-  CPDFSDK_PageView* pPageView = pAnnot->GetPageView();
-  if (pPageView && pPageView->IsValid()) {
-    CPDFSDK_AnnotHandlerMgr* pAnnotHandler = m_pEnv->GetAnnotHandlerMgr();
-    if (!m_pFocusAnnot) {
-#ifdef PDF_ENABLE_XFA
-      if (!pAnnotHandler->Annot_OnChangeFocus(pAnnot, pLastFocusAnnot))
-        return FALSE;
-#endif  // PDF_ENABLE_XFA
-      if (!pAnnotHandler->Annot_OnSetFocus(pAnnot, nFlag))
-        return FALSE;
-      if (!m_pFocusAnnot) {
-        m_pFocusAnnot = pAnnot;
-        return TRUE;
-      }
-    }
-  }
-  return FALSE;
-}
-
-FX_BOOL CPDFSDK_Document::KillFocusAnnot(FX_UINT nFlag) {
-  if (m_pFocusAnnot) {
-    CPDFSDK_AnnotHandlerMgr* pAnnotHandler = m_pEnv->GetAnnotHandlerMgr();
-    CPDFSDK_Annot* pFocusAnnot = m_pFocusAnnot;
-    m_pFocusAnnot = nullptr;
-
-#ifdef PDF_ENABLE_XFA
-    if (!pAnnotHandler->Annot_OnChangeFocus(nullptr, pFocusAnnot))
-      return FALSE;
-#endif  // PDF_ENABLE_XFA
-
-    if (pAnnotHandler->Annot_OnKillFocus(pFocusAnnot, nFlag)) {
-      if (pFocusAnnot->GetType() == "Widget") {
-        CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pFocusAnnot;
-        int nFieldType = pWidget->GetFieldType();
-        if (FIELDTYPE_TEXTFIELD == nFieldType ||
-            FIELDTYPE_COMBOBOX == nFieldType) {
-          m_pEnv->FFI_OnSetFieldInputFocus(NULL, NULL, 0, FALSE);
-        }
-      }
-
-      if (!m_pFocusAnnot)
-        return TRUE;
-    } else {
-      m_pFocusAnnot = pFocusAnnot;
-    }
-  }
-  return FALSE;
-}
-
-void CPDFSDK_Document::OnCloseDocument() {
-  KillFocusAnnot();
-}
-
-FX_BOOL CPDFSDK_Document::GetPermissions(int nFlag) {
-  return GetPDFDocument()->GetUserPermissions() & nFlag;
-}
-
-IJS_Runtime* CPDFSDK_Document::GetJsRuntime() {
-  return m_pEnv->GetJSRuntime();
-}
-
-CFX_WideString CPDFSDK_Document::GetPath() {
-  return m_pEnv->JS_docGetFilePath();
-}
-
-CPDFSDK_PageView::CPDFSDK_PageView(CPDFSDK_Document* pSDKDoc,
-                                   UnderlyingPageType* page)
-    : m_page(page),
-      m_pSDKDoc(pSDKDoc),
-      m_CaptureWidget(nullptr),
-#ifndef PDF_ENABLE_XFA
-      m_bTakeOverPage(FALSE),
-#endif  // PDF_ENABLE_XFA
-      m_bEnterWidget(FALSE),
-      m_bExitWidget(FALSE),
-      m_bOnWidget(FALSE),
-      m_bValid(FALSE),
-      m_bLocked(FALSE) {
-  CPDFSDK_InterForm* pInterForm = pSDKDoc->GetInterForm();
-  if (pInterForm) {
-    CPDF_InterForm* pPDFInterForm = pInterForm->GetInterForm();
-#ifdef PDF_ENABLE_XFA
-    if (page->GetPDFPage())
-      pPDFInterForm->FixPageFields(page->GetPDFPage());
-#else   // PDF_ENABLE_XFA
-    pPDFInterForm->FixPageFields(page);
-#endif  // PDF_ENABLE_XFA
-  }
-#ifndef PDF_ENABLE_XFA
-  m_page->SetPrivateData((void*)m_page, (void*)this, nullptr);
-#endif  // PDF_ENABLE_XFA
-}
-
-CPDFSDK_PageView::~CPDFSDK_PageView() {
-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
-  CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
-  for (CPDFSDK_Annot* pAnnot : m_fxAnnotArray)
-    pAnnotHandlerMgr->ReleaseAnnot(pAnnot);
-
-  m_fxAnnotArray.clear();
-  m_pAnnotList.reset();
-#ifndef PDF_ENABLE_XFA
-  m_page->RemovePrivateData((void*)m_page);
-  if (m_bTakeOverPage) {
-    delete m_page;
-  }
-#endif  // PDF_ENABLE_XFA
-}
-
-void CPDFSDK_PageView::PageView_OnDraw(CFX_RenderDevice* pDevice,
-                                       CFX_Matrix* pUser2Device,
-#ifdef PDF_ENABLE_XFA
-                                       CPDF_RenderOptions* pOptions,
-                                       const FX_RECT& pClip) {
-#else
-                                       CPDF_RenderOptions* pOptions) {
-#endif  // PDF_ENABLE_XFA
-  m_curMatrix = *pUser2Device;
-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
-
-#ifdef PDF_ENABLE_XFA
-  CPDFXFA_Page* pPage = GetPDFXFAPage();
-  if (!pPage)
-    return;
-
-  if (pPage->GetDocument()->GetDocType() == DOCTYPE_DYNAMIC_XFA) {
-    CFX_Graphics gs;
-    gs.Create(pDevice);
-    CFX_RectF rectClip;
-    rectClip.Set(static_cast<FX_FLOAT>(pClip.left),
-                 static_cast<FX_FLOAT>(pClip.top),
-                 static_cast<FX_FLOAT>(pClip.Width()),
-                 static_cast<FX_FLOAT>(pClip.Height()));
-    gs.SetClipRect(rectClip);
-    IXFA_RenderContext* pRenderContext = XFA_RenderContext_Create();
-    if (!pRenderContext)
-      return;
-    CXFA_RenderOptions renderOptions;
-    renderOptions.m_bHighlight = TRUE;
-    IXFA_PageView* xfaView = pPage->GetXFAPageView();
-    pRenderContext->StartRender(xfaView, &gs, *pUser2Device, renderOptions);
-    pRenderContext->DoRender();
-    pRenderContext->StopRender();
-    pRenderContext->Release();
-    IXFA_DocView* docView = xfaView->GetDocView();
-    if (!docView)
-      return;
-    CPDFSDK_Annot* annot = GetFocusAnnot();
-    if (!annot)
-      return;
-    // Render the focus widget
-    docView->GetWidgetHandler()->RenderWidget(annot->GetXFAWidget(), &gs,
-                                              pUser2Device, FALSE);
-    return;
-  }
-#endif  // PDF_ENABLE_XFA
-
-  // for pdf/static xfa.
-  CPDFSDK_AnnotIterator annotIterator(this, true);
-  while (CPDFSDK_Annot* pSDKAnnot = annotIterator.Next()) {
-    CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
-    pAnnotHandlerMgr->Annot_OnDraw(this, pSDKAnnot, pDevice, pUser2Device, 0);
-  }
-}
-
-const CPDF_Annot* CPDFSDK_PageView::GetPDFAnnotAtPoint(FX_FLOAT pageX,
-                                                       FX_FLOAT pageY) {
-  for (const CPDF_Annot* pAnnot : m_pAnnotList->All()) {
-    CFX_FloatRect annotRect;
-    pAnnot->GetRect(annotRect);
-    if (annotRect.Contains(pageX, pageY))
-      return pAnnot;
-  }
-  return nullptr;
-}
-
-const CPDF_Annot* CPDFSDK_PageView::GetPDFWidgetAtPoint(FX_FLOAT pageX,
-                                                        FX_FLOAT pageY) {
-  for (const CPDF_Annot* pAnnot : m_pAnnotList->All()) {
-    if (pAnnot->GetSubType() == "Widget") {
-      CFX_FloatRect annotRect;
-      pAnnot->GetRect(annotRect);
-      if (annotRect.Contains(pageX, pageY))
-        return pAnnot;
-    }
-  }
-  return nullptr;
-}
-
-CPDFSDK_Annot* CPDFSDK_PageView::GetFXAnnotAtPoint(FX_FLOAT pageX,
-                                                   FX_FLOAT pageY) {
-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
-  CPDFSDK_AnnotHandlerMgr* pAnnotMgr = pEnv->GetAnnotHandlerMgr();
-  CPDFSDK_AnnotIterator annotIterator(this, false);
-  while (CPDFSDK_Annot* pSDKAnnot = annotIterator.Next()) {
-    CPDF_Rect rc = pAnnotMgr->Annot_OnGetViewBBox(this, pSDKAnnot);
-    if (rc.Contains(pageX, pageY))
-      return pSDKAnnot;
-  }
-
-  return nullptr;
-}
-
-CPDFSDK_Annot* CPDFSDK_PageView::GetFXWidgetAtPoint(FX_FLOAT pageX,
-                                                    FX_FLOAT pageY) {
-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
-  CPDFSDK_AnnotHandlerMgr* pAnnotMgr = pEnv->GetAnnotHandlerMgr();
-  CPDFSDK_AnnotIterator annotIterator(this, false);
-  while (CPDFSDK_Annot* pSDKAnnot = annotIterator.Next()) {
-    bool bHitTest = pSDKAnnot->GetType() == "Widget";
-#ifdef PDF_ENABLE_XFA
-    bHitTest = bHitTest || pSDKAnnot->GetType() == FSDK_XFAWIDGET_TYPENAME;
-#endif  // PDF_ENABLE_XFA
-    if (bHitTest) {
-      pAnnotMgr->Annot_OnGetViewBBox(this, pSDKAnnot);
-      CPDF_Point point(pageX, pageY);
-      if (pAnnotMgr->Annot_OnHitTest(this, pSDKAnnot, point))
-        return pSDKAnnot;
-    }
-  }
-
-  return nullptr;
-}
-
-void CPDFSDK_PageView::KillFocusAnnotIfNeeded() {
-  // if there is a focused annot on the page, we should kill the focus first.
-  if (CPDFSDK_Annot* focusedAnnot = m_pSDKDoc->GetFocusAnnot()) {
-    if (pdfium::ContainsValue(m_fxAnnotArray, focusedAnnot))
-      KillFocusAnnot();
-  }
-}
-
-FX_BOOL CPDFSDK_PageView::Annot_HasAppearance(CPDF_Annot* pAnnot) {
-  CPDF_Dictionary* pAnnotDic = pAnnot->GetAnnotDict();
-  if (pAnnotDic)
-    return pAnnotDic->KeyExist("AS");
-  return FALSE;
-}
-
-CPDFSDK_Annot* CPDFSDK_PageView::AddAnnot(CPDF_Annot* pPDFAnnot) {
-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
-  ASSERT(pEnv);
-  CPDFSDK_AnnotHandlerMgr* pAnnotHandler = pEnv->GetAnnotHandlerMgr();
-  CPDFSDK_Annot* pSDKAnnot = pAnnotHandler->NewAnnot(pPDFAnnot, this);
-  if (!pSDKAnnot)
-    return nullptr;
-
-  m_fxAnnotArray.push_back(pSDKAnnot);
-  pAnnotHandler->Annot_OnCreate(pSDKAnnot);
-  return pSDKAnnot;
-}
-
-#ifdef PDF_ENABLE_XFA
-CPDFSDK_Annot* CPDFSDK_PageView::AddAnnot(IXFA_Widget* pPDFAnnot) {
-  if (!pPDFAnnot)
-    return nullptr;
-
-  CPDFSDK_Annot* pSDKAnnot = GetAnnotByXFAWidget(pPDFAnnot);
-  if (pSDKAnnot)
-    return pSDKAnnot;
-
-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
-  CPDFSDK_AnnotHandlerMgr* pAnnotHandler = pEnv->GetAnnotHandlerMgr();
-  pSDKAnnot = pAnnotHandler->NewAnnot(pPDFAnnot, this);
-  if (!pSDKAnnot)
-    return nullptr;
-
-  m_fxAnnotArray.push_back(pSDKAnnot);
-  return pSDKAnnot;
-}
-#endif  // PDF_ENABLE_XFA
-
-CPDFSDK_Annot* CPDFSDK_PageView::AddAnnot(CPDF_Dictionary* pDict) {
-  return pDict ? AddAnnot(pDict->GetString("Subtype"), pDict) : nullptr;
-}
-
-CPDFSDK_Annot* CPDFSDK_PageView::AddAnnot(const FX_CHAR* lpSubType,
-                                          CPDF_Dictionary* pDict) {
-  return NULL;
-}
-
-FX_BOOL CPDFSDK_PageView::DeleteAnnot(CPDFSDK_Annot* pAnnot) {
-#ifdef PDF_ENABLE_XFA
-  if (!pAnnot)
-    return FALSE;
-  CPDFXFA_Page* pPage = pAnnot->GetPDFXFAPage();
-  if (!pPage || (pPage->GetDocument()->GetDocType() != DOCTYPE_STATIC_XFA &&
-                 pPage->GetDocument()->GetDocType() != DOCTYPE_DYNAMIC_XFA))
-    return FALSE;
-
-  auto it = std::find(m_fxAnnotArray.begin(), m_fxAnnotArray.end(), pAnnot);
-  if (it != m_fxAnnotArray.end())
-    m_fxAnnotArray.erase(it);
-  if (m_CaptureWidget == pAnnot)
-    m_CaptureWidget = nullptr;
-
-  return TRUE;
-#else   // PDF_ENABLE_XFA
-  return FALSE;
-#endif  // PDF_ENABLE_XFA
-}
-
-CPDF_Document* CPDFSDK_PageView::GetPDFDocument() {
-  if (m_page) {
-#ifdef PDF_ENABLE_XFA
-    return m_page->GetDocument()->GetPDFDoc();
-#else   // PDF_ENABLE_XFA
-    return m_page->m_pDocument;
-#endif  // PDF_ENABLE_XFA
-  }
-  return NULL;
-}
-
-#ifdef PDF_ENABLE_XFA
-CPDF_Page* CPDFSDK_PageView::GetPDFPage() {
-  if (m_page) {
-    return m_page->GetPDFPage();
-  }
-  return NULL;
-}
-#endif  // PDF_ENABLE_XFA
-
-size_t CPDFSDK_PageView::CountAnnots() const {
-  return m_fxAnnotArray.size();
-}
-
-CPDFSDK_Annot* CPDFSDK_PageView::GetAnnot(size_t nIndex) {
-  return nIndex < m_fxAnnotArray.size() ? m_fxAnnotArray[nIndex] : nullptr;
-}
-
-CPDFSDK_Annot* CPDFSDK_PageView::GetAnnotByDict(CPDF_Dictionary* pDict) {
-  for (CPDFSDK_Annot* pAnnot : m_fxAnnotArray) {
-    if (pAnnot->GetPDFAnnot()->GetAnnotDict() == pDict)
-      return pAnnot;
-  }
-  return nullptr;
-}
-
-#ifdef PDF_ENABLE_XFA
-CPDFSDK_Annot* CPDFSDK_PageView::GetAnnotByXFAWidget(IXFA_Widget* hWidget) {
-  if (!hWidget)
-    return nullptr;
-
-  for (CPDFSDK_Annot* pAnnot : m_fxAnnotArray) {
-    if (pAnnot->GetXFAWidget() == hWidget)
-      return pAnnot;
-  }
-  return nullptr;
-}
-#endif  // PDF_ENABLE_XFA
-
-FX_BOOL CPDFSDK_PageView::OnLButtonDown(const CPDF_Point& point,
-                                        FX_UINT nFlag) {
-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
-  ASSERT(pEnv);
-  CPDFSDK_Annot* pFXAnnot = GetFXWidgetAtPoint(point.x, point.y);
-  if (!pFXAnnot) {
-    KillFocusAnnot(nFlag);
-    return FALSE;
-  }
-
-  CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
-  FX_BOOL bRet =
-      pAnnotHandlerMgr->Annot_OnLButtonDown(this, pFXAnnot, nFlag, point);
-  if (bRet)
-    SetFocusAnnot(pFXAnnot);
-  return bRet;
-}
-
-#ifdef PDF_ENABLE_XFA
-FX_BOOL CPDFSDK_PageView::OnRButtonDown(const CPDF_Point& point,
-                                        FX_UINT nFlag) {
-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
-  ASSERT(pEnv);
-  CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
-  ASSERT(pAnnotHandlerMgr);
-
-  CPDFSDK_Annot* pFXAnnot = GetFXWidgetAtPoint(point.x, point.y);
-
-  if (pFXAnnot == NULL)
-    return FALSE;
-
-  FX_BOOL bRet =
-      pAnnotHandlerMgr->Annot_OnRButtonDown(this, pFXAnnot, nFlag, point);
-  if (bRet) {
-    SetFocusAnnot(pFXAnnot);
-  }
-  return TRUE;
-}
-
-FX_BOOL CPDFSDK_PageView::OnRButtonUp(const CPDF_Point& point, FX_UINT nFlag) {
-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
-  ASSERT(pEnv);
-  CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
-
-  CPDFSDK_Annot* pFXAnnot = GetFXWidgetAtPoint(point.x, point.y);
-
-  if (pFXAnnot == NULL)
-    return FALSE;
-
-  FX_BOOL bRet =
-      pAnnotHandlerMgr->Annot_OnRButtonUp(this, pFXAnnot, nFlag, point);
-  if (bRet) {
-    SetFocusAnnot(pFXAnnot);
-  }
-  return TRUE;
-}
-#endif  // PDF_ENABLE_XFA
-
-FX_BOOL CPDFSDK_PageView::OnLButtonUp(const CPDF_Point& point, FX_UINT nFlag) {
-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
-  ASSERT(pEnv);
-  CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
-  CPDFSDK_Annot* pFXAnnot = GetFXWidgetAtPoint(point.x, point.y);
-  CPDFSDK_Annot* pFocusAnnot = GetFocusAnnot();
-  FX_BOOL bRet = FALSE;
-  if (pFocusAnnot && pFocusAnnot != pFXAnnot) {
-    // Last focus Annot gets a chance to handle the event.
-    bRet = pAnnotHandlerMgr->Annot_OnLButtonUp(this, pFocusAnnot, nFlag, point);
-  }
-  if (pFXAnnot && !bRet)
-    bRet = pAnnotHandlerMgr->Annot_OnLButtonUp(this, pFXAnnot, nFlag, point);
-  return bRet;
-}
-
-FX_BOOL CPDFSDK_PageView::OnMouseMove(const CPDF_Point& point, int nFlag) {
-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
-  CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
-  if (CPDFSDK_Annot* pFXAnnot = GetFXWidgetAtPoint(point.x, point.y)) {
-    if (m_CaptureWidget && m_CaptureWidget != pFXAnnot) {
-      m_bExitWidget = TRUE;
-      m_bEnterWidget = FALSE;
-      pAnnotHandlerMgr->Annot_OnMouseExit(this, m_CaptureWidget, nFlag);
-    }
-    m_CaptureWidget = (CPDFSDK_Widget*)pFXAnnot;
-    m_bOnWidget = TRUE;
-    if (!m_bEnterWidget) {
-      m_bEnterWidget = TRUE;
-      m_bExitWidget = FALSE;
-      pAnnotHandlerMgr->Annot_OnMouseEnter(this, pFXAnnot, nFlag);
-    }
-    pAnnotHandlerMgr->Annot_OnMouseMove(this, pFXAnnot, nFlag, point);
-    return TRUE;
-  }
-  if (m_bOnWidget) {
-    m_bOnWidget = FALSE;
-    m_bExitWidget = TRUE;
-    m_bEnterWidget = FALSE;
-    if (m_CaptureWidget) {
-      pAnnotHandlerMgr->Annot_OnMouseExit(this, m_CaptureWidget, nFlag);
-      m_CaptureWidget = NULL;
-    }
-  }
-  return FALSE;
-}
-
-FX_BOOL CPDFSDK_PageView::OnMouseWheel(double deltaX,
-                                       double deltaY,
-                                       const CPDF_Point& point,
-                                       int nFlag) {
-  if (CPDFSDK_Annot* pAnnot = GetFXWidgetAtPoint(point.x, point.y)) {
-    CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
-    CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
-    return pAnnotHandlerMgr->Annot_OnMouseWheel(this, pAnnot, nFlag,
-                                                (int)deltaY, point);
-  }
-  return FALSE;
-}
-
-FX_BOOL CPDFSDK_PageView::OnChar(int nChar, FX_UINT nFlag) {
-  if (CPDFSDK_Annot* pAnnot = GetFocusAnnot()) {
-    CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
-    CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
-    return pAnnotHandlerMgr->Annot_OnChar(pAnnot, nChar, nFlag);
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CPDFSDK_PageView::OnKeyDown(int nKeyCode, int nFlag) {
-  if (CPDFSDK_Annot* pAnnot = GetFocusAnnot()) {
-    CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
-    CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
-    return pAnnotHandlerMgr->Annot_OnKeyDown(pAnnot, nKeyCode, nFlag);
-  }
-  return FALSE;
-}
-
-FX_BOOL CPDFSDK_PageView::OnKeyUp(int nKeyCode, int nFlag) {
-  return FALSE;
-}
-
-void CPDFSDK_PageView::LoadFXAnnots() {
-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
-#ifdef PDF_ENABLE_XFA
-  CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
-#else
-  FX_BOOL enableAPUpdate = CPDF_InterForm::UpdatingAPEnabled();
-  // Disable the default AP construction.
-  CPDF_InterForm::EnableUpdateAP(FALSE);
-  m_pAnnotList.reset(new CPDF_AnnotList(m_page));
-  CPDF_InterForm::EnableUpdateAP(enableAPUpdate);
-  const size_t nCount = m_pAnnotList->Count();
-#endif  // PDF_ENABLE_XFA
-
-  SetLock(TRUE);
-
-#ifdef PDF_ENABLE_XFA
-  m_page->AddRef();
-  if (m_pSDKDoc->GetXFADocument()->GetDocType() == DOCTYPE_DYNAMIC_XFA) {
-    IXFA_PageView* pageView = NULL;
-    pageView = m_page->GetXFAPageView();
-    ASSERT(pageView != NULL);
-
-    IXFA_WidgetIterator* pWidgetHander = pageView->CreateWidgetIterator(
-        XFA_TRAVERSEWAY_Form, XFA_WIDGETFILTER_Visible |
-                                  XFA_WIDGETFILTER_Viewable |
-                                  XFA_WIDGETFILTER_AllType);
-    if (!pWidgetHander) {
-      m_page->Release();
-      SetLock(FALSE);
-      return;
-    }
-
-    while (IXFA_Widget* pXFAAnnot = pWidgetHander->MoveToNext()) {
-      CPDFSDK_Annot* pAnnot = pAnnotHandlerMgr->NewAnnot(pXFAAnnot, this);
-      if (!pAnnot)
-        continue;
-
-      m_fxAnnotArray.push_back(pAnnot);
-      pAnnotHandlerMgr->Annot_OnLoad(pAnnot);
-    }
-    pWidgetHander->Release();
-  } else {
-    CPDF_Page* pPage = m_page->GetPDFPage();
-    ASSERT(pPage != NULL);
-    FX_BOOL enableAPUpdate = CPDF_InterForm::UpdatingAPEnabled();
-    // Disable the default AP construction.
-    CPDF_InterForm::EnableUpdateAP(FALSE);
-    m_pAnnotList.reset(new CPDF_AnnotList(pPage));
-    CPDF_InterForm::EnableUpdateAP(enableAPUpdate);
-
-    const size_t nCount = m_pAnnotList->Count();
-    for (size_t i = 0; i < nCount; ++i) {
-      CPDF_Annot* pPDFAnnot = m_pAnnotList->GetAt(i);
-      CheckUnSupportAnnot(GetPDFDocument(), pPDFAnnot);
-
-      CPDFSDK_Annot* pAnnot = pAnnotHandlerMgr->NewAnnot(pPDFAnnot, this);
-      if (!pAnnot)
-        continue;
-      m_fxAnnotArray.push_back(pAnnot);
-      pAnnotHandlerMgr->Annot_OnLoad(pAnnot);
-    }
-  }
-  m_page->Release();
-#else   // PDF_ENABLE_XFA
-  for (size_t i = 0; i < nCount; ++i) {
-    CPDF_Annot* pPDFAnnot = m_pAnnotList->GetAt(i);
-    CPDF_Document* pDoc = GetPDFDocument();
-    CheckUnSupportAnnot(pDoc, pPDFAnnot);
-    CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
-    CPDFSDK_Annot* pAnnot = pAnnotHandlerMgr->NewAnnot(pPDFAnnot, this);
-    if (!pAnnot)
-      continue;
-    m_fxAnnotArray.push_back(pAnnot);
-    pAnnotHandlerMgr->Annot_OnLoad(pAnnot);
-  }
-#endif  // PDF_ENABLE_XFA
-
-  SetLock(FALSE);
-}
-
-void CPDFSDK_PageView::UpdateRects(CFX_RectArray& rects) {
-  for (int i = 0; i < rects.GetSize(); i++) {
-    CPDF_Rect rc = rects.GetAt(i);
-    CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
-    pEnv->FFI_Invalidate(m_page, rc.left, rc.top, rc.right, rc.bottom);
-  }
-}
-
-void CPDFSDK_PageView::UpdateView(CPDFSDK_Annot* pAnnot) {
-  CPDF_Rect rcWindow = pAnnot->GetRect();
-  CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
-  pEnv->FFI_Invalidate(m_page, rcWindow.left, rcWindow.top, rcWindow.right,
-                       rcWindow.bottom);
-}
-
-int CPDFSDK_PageView::GetPageIndex() {
-  if (m_page) {
-#ifdef PDF_ENABLE_XFA
-    CPDF_Dictionary* pDic = m_page->GetPDFPage()->m_pFormDict;
-#else   // PDF_ENABLE_XFA
-    CPDF_Dictionary* pDic = m_page->m_pFormDict;
-#endif  // PDF_ENABLE_XFA
-    CPDF_Document* pDoc = m_pSDKDoc->GetPDFDocument();
-    if (pDoc && pDic) {
-      return pDoc->GetPageIndex(pDic->GetObjNum());
-    }
-  }
-  return -1;
-}
-
-bool CPDFSDK_PageView::IsValidAnnot(const CPDF_Annot* p) const {
-  if (!p)
-    return false;
-
-  const auto& annots = m_pAnnotList->All();
-  return pdfium::ContainsValue(annots, p);
-}
-
-CPDFSDK_Annot* CPDFSDK_PageView::GetFocusAnnot() {
-  CPDFSDK_Annot* pFocusAnnot = m_pSDKDoc->GetFocusAnnot();
-  if (!pFocusAnnot)
-    return nullptr;
-
-  for (CPDFSDK_Annot* pAnnot : m_fxAnnotArray) {
-    if (pAnnot == pFocusAnnot)
-      return pAnnot;
-  }
-  return nullptr;
-}
diff --git a/fpdfsdk/src/fsdk_rendercontext.cpp b/fpdfsdk/src/fsdk_rendercontext.cpp
deleted file mode 100644
index 3b671ca..0000000
--- a/fpdfsdk/src/fsdk_rendercontext.cpp
+++ /dev/null
@@ -1,47 +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
-
-#include "fpdfsdk/include/fsdk_rendercontext.h"
-
-void CRenderContext::Clear() {
-  m_pDevice = NULL;
-  m_pContext = NULL;
-  m_pRenderer = NULL;
-  m_pAnnots = NULL;
-  m_pOptions = NULL;
-#ifdef _WIN32_WCE
-  m_pBitmap = NULL;
-  m_hBitmap = NULL;
-#endif
-}
-
-CRenderContext::~CRenderContext() {
-  delete m_pRenderer;
-  delete m_pContext;
-  delete m_pDevice;
-  delete m_pAnnots;
-  delete m_pOptions->m_pOCContext;
-  delete m_pOptions;
-#ifdef _WIN32_WCE
-  delete m_pBitmap;
-  if (m_hBitmap)
-    DeleteObject(m_hBitmap);
-#endif
-}
-
-IFSDK_PAUSE_Adapter::IFSDK_PAUSE_Adapter(IFSDK_PAUSE* IPause) {
-  m_IPause = IPause;
-}
-
-IFSDK_PAUSE_Adapter::~IFSDK_PAUSE_Adapter() {
-}
-
-FX_BOOL IFSDK_PAUSE_Adapter::NeedToPauseNow() {
-  if (m_IPause->NeedToPauseNow) {
-    return m_IPause->NeedToPauseNow(m_IPause);
-  }
-  return FALSE;
-}
diff --git a/fpdfsdk/src/fxedit/fxet_ap.cpp b/fpdfsdk/src/fxedit/fxet_ap.cpp
deleted file mode 100644
index 2803b60..0000000
--- a/fpdfsdk/src/fxedit/fxet_ap.cpp
+++ /dev/null
@@ -1,205 +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
-
-#include "core/include/fpdfapi/fpdf_resource.h"
-#include "fpdfsdk/include/fxedit/fx_edit.h"
-#include "fpdfsdk/include/fxedit/fxet_edit.h"
-
-CFX_ByteString GetPDFWordString(IFX_Edit_FontMap* pFontMap,
-                                int32_t nFontIndex,
-                                FX_WORD Word,
-                                FX_WORD SubWord) {
-  CFX_ByteString sWord;
-  if (CPDF_Font* pPDFFont = pFontMap->GetPDFFont(nFontIndex)) {
-    if (SubWord > 0) {
-      Word = SubWord;
-    } else {
-      FX_DWORD dwCharCode = -1;
-
-      if (pPDFFont->IsUnicodeCompatible())
-        dwCharCode = pPDFFont->CharCodeFromUnicode(Word);
-      else
-        dwCharCode = pFontMap->CharCodeFromUnicode(nFontIndex, Word);
-
-      if (dwCharCode > 0) {
-        pPDFFont->AppendChar(sWord, dwCharCode);
-        return sWord;
-      }
-    }
-
-    pPDFFont->AppendChar(sWord, Word);
-  }
-
-  return sWord;
-}
-
-static CFX_ByteString GetWordRenderString(const CFX_ByteString& strWords) {
-  if (strWords.GetLength() > 0)
-    return PDF_EncodeString(strWords) + " Tj\n";
-
-  return "";
-}
-
-static CFX_ByteString GetFontSetString(IFX_Edit_FontMap* pFontMap,
-                                       int32_t nFontIndex,
-                                       FX_FLOAT fFontSize) {
-  CFX_ByteTextBuf sRet;
-
-  if (pFontMap) {
-    CFX_ByteString sFontAlias = pFontMap->GetPDFFontAlias(nFontIndex);
-
-    if (sFontAlias.GetLength() > 0 && fFontSize > 0)
-      sRet << "/" << sFontAlias << " " << fFontSize << " Tf\n";
-  }
-
-  return sRet.GetByteString();
-}
-
-CFX_ByteString IFX_Edit::GetEditAppearanceStream(
-    IFX_Edit* pEdit,
-    const CPDF_Point& ptOffset,
-    const CPVT_WordRange* pRange /* = NULL*/,
-    FX_BOOL bContinuous /* = TRUE*/,
-    FX_WORD SubWord /* = 0*/) {
-  CFX_ByteTextBuf sEditStream, sWords;
-
-  CPDF_Point ptOld(0.0f, 0.0f), ptNew(0.0f, 0.0f);
-  int32_t nCurFontIndex = -1;
-
-  if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator()) {
-    if (pRange)
-      pIterator->SetAt(pRange->BeginPos);
-    else
-      pIterator->SetAt(0);
-
-    CPVT_WordPlace oldplace;
-
-    while (pIterator->NextWord()) {
-      CPVT_WordPlace place = pIterator->GetAt();
-
-      if (pRange && place.WordCmp(pRange->EndPos) > 0)
-        break;
-
-      if (bContinuous) {
-        if (place.LineCmp(oldplace) != 0) {
-          if (sWords.GetSize() > 0) {
-            sEditStream << GetWordRenderString(sWords.GetByteString());
-            sWords.Clear();
-          }
-
-          CPVT_Word word;
-          if (pIterator->GetWord(word)) {
-            ptNew = CPDF_Point(word.ptWord.x + ptOffset.x,
-                               word.ptWord.y + ptOffset.y);
-          } else {
-            CPVT_Line line;
-            pIterator->GetLine(line);
-            ptNew = CPDF_Point(line.ptLine.x + ptOffset.x,
-                               line.ptLine.y + ptOffset.y);
-          }
-
-          if (ptNew.x != ptOld.x || ptNew.y != ptOld.y) {
-            sEditStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y
-                        << " Td\n";
-
-            ptOld = ptNew;
-          }
-        }
-
-        CPVT_Word word;
-        if (pIterator->GetWord(word)) {
-          if (word.nFontIndex != nCurFontIndex) {
-            if (sWords.GetSize() > 0) {
-              sEditStream << GetWordRenderString(sWords.GetByteString());
-              sWords.Clear();
-            }
-            sEditStream << GetFontSetString(pEdit->GetFontMap(),
-                                            word.nFontIndex, word.fFontSize);
-            nCurFontIndex = word.nFontIndex;
-          }
-
-          sWords << GetPDFWordString(pEdit->GetFontMap(), nCurFontIndex,
-                                     word.Word, SubWord);
-        }
-
-        oldplace = place;
-      } else {
-        CPVT_Word word;
-        if (pIterator->GetWord(word)) {
-          ptNew = CPDF_Point(word.ptWord.x + ptOffset.x,
-                             word.ptWord.y + ptOffset.y);
-
-          if (ptNew.x != ptOld.x || ptNew.y != ptOld.y) {
-            sEditStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y
-                        << " Td\n";
-            ptOld = ptNew;
-          }
-
-          if (word.nFontIndex != nCurFontIndex) {
-            sEditStream << GetFontSetString(pEdit->GetFontMap(),
-                                            word.nFontIndex, word.fFontSize);
-            nCurFontIndex = word.nFontIndex;
-          }
-
-          sEditStream << GetWordRenderString(GetPDFWordString(
-              pEdit->GetFontMap(), nCurFontIndex, word.Word, SubWord));
-        }
-      }
-    }
-
-    if (sWords.GetSize() > 0) {
-      sEditStream << GetWordRenderString(sWords.GetByteString());
-      sWords.Clear();
-    }
-  }
-
-  CFX_ByteTextBuf sAppStream;
-  if (sEditStream.GetSize() > 0) {
-    int32_t nHorzScale = pEdit->GetHorzScale();
-    if (nHorzScale != 100) {
-      sAppStream << nHorzScale << " Tz\n";
-    }
-
-    FX_FLOAT fCharSpace = pEdit->GetCharSpace();
-    if (!FX_EDIT_IsFloatZero(fCharSpace)) {
-      sAppStream << fCharSpace << " Tc\n";
-    }
-
-    sAppStream << sEditStream;
-  }
-
-  return sAppStream.GetByteString();
-}
-
-CFX_ByteString IFX_Edit::GetSelectAppearanceStream(
-    IFX_Edit* pEdit,
-    const CPDF_Point& ptOffset,
-    const CPVT_WordRange* pRange) {
-  CFX_ByteTextBuf sRet;
-
-  if (pRange && pRange->IsExist()) {
-    if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator()) {
-      pIterator->SetAt(pRange->BeginPos);
-
-      while (pIterator->NextWord()) {
-        CPVT_WordPlace place = pIterator->GetAt();
-
-        if (pRange && place.WordCmp(pRange->EndPos) > 0)
-          break;
-
-        CPVT_Word word;
-        CPVT_Line line;
-        if (pIterator->GetWord(word) && pIterator->GetLine(line)) {
-          sRet << word.ptWord.x + ptOffset.x << " "
-               << line.ptLine.y + line.fLineDescent << " " << word.fWidth << " "
-               << line.fLineAscent - line.fLineDescent << " re\nf\n";
-        }
-      }
-    }
-  }
-
-  return sRet.GetByteString();
-}
diff --git a/fpdfsdk/src/fxedit/fxet_edit.cpp b/fpdfsdk/src/fxedit/fxet_edit.cpp
deleted file mode 100644
index 0e66b0e..0000000
--- a/fpdfsdk/src/fxedit/fxet_edit.cpp
+++ /dev/null
@@ -1,3030 +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
-
-#include "fpdfsdk/include/fxedit/fxet_edit.h"
-
-#include <algorithm>
-
-#include "core/include/fpdfapi/fpdf_resource.h"
-
-#define FX_EDIT_UNDO_MAXITEM 10000
-
-CFX_Edit_Iterator::CFX_Edit_Iterator(CFX_Edit* pEdit,
-                                     IPDF_VariableText_Iterator* pVTIterator)
-    : m_pEdit(pEdit), m_pVTIterator(pVTIterator) {}
-
-CFX_Edit_Iterator::~CFX_Edit_Iterator() {}
-
-FX_BOOL CFX_Edit_Iterator::NextWord() {
-  return m_pVTIterator->NextWord();
-}
-
-FX_BOOL CFX_Edit_Iterator::NextLine() {
-  return m_pVTIterator->NextLine();
-}
-
-FX_BOOL CFX_Edit_Iterator::NextSection() {
-  return m_pVTIterator->NextSection();
-}
-
-FX_BOOL CFX_Edit_Iterator::PrevWord() {
-  return m_pVTIterator->PrevWord();
-}
-
-FX_BOOL CFX_Edit_Iterator::PrevLine() {
-  return m_pVTIterator->PrevLine();
-}
-
-FX_BOOL CFX_Edit_Iterator::PrevSection() {
-  return m_pVTIterator->PrevSection();
-}
-
-FX_BOOL CFX_Edit_Iterator::GetWord(CPVT_Word& word) const {
-  ASSERT(m_pEdit);
-
-  if (m_pVTIterator->GetWord(word)) {
-    word.ptWord = m_pEdit->VTToEdit(word.ptWord);
-    return TRUE;
-  }
-  return FALSE;
-}
-
-FX_BOOL CFX_Edit_Iterator::GetLine(CPVT_Line& line) const {
-  ASSERT(m_pEdit);
-
-  if (m_pVTIterator->GetLine(line)) {
-    line.ptLine = m_pEdit->VTToEdit(line.ptLine);
-    return TRUE;
-  }
-  return FALSE;
-}
-
-FX_BOOL CFX_Edit_Iterator::GetSection(CPVT_Section& section) const {
-  ASSERT(m_pEdit);
-
-  if (m_pVTIterator->GetSection(section)) {
-    section.rcSection = m_pEdit->VTToEdit(section.rcSection);
-    return TRUE;
-  }
-  return FALSE;
-}
-
-void CFX_Edit_Iterator::SetAt(int32_t nWordIndex) {
-  m_pVTIterator->SetAt(nWordIndex);
-}
-
-void CFX_Edit_Iterator::SetAt(const CPVT_WordPlace& place) {
-  m_pVTIterator->SetAt(place);
-}
-
-const CPVT_WordPlace& CFX_Edit_Iterator::GetAt() const {
-  return m_pVTIterator->GetAt();
-}
-
-IFX_Edit* CFX_Edit_Iterator::GetEdit() const {
-  return m_pEdit;
-}
-
-CFX_Edit_Provider::CFX_Edit_Provider(IFX_Edit_FontMap* pFontMap)
-    : m_pFontMap(pFontMap) {
-  ASSERT(m_pFontMap);
-}
-
-CFX_Edit_Provider::~CFX_Edit_Provider() {}
-
-IFX_Edit_FontMap* CFX_Edit_Provider::GetFontMap() {
-  return m_pFontMap;
-}
-
-int32_t CFX_Edit_Provider::GetCharWidth(int32_t nFontIndex,
-                                        FX_WORD word,
-                                        int32_t nWordStyle) {
-  if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex)) {
-    FX_DWORD charcode = word;
-
-    if (pPDFFont->IsUnicodeCompatible())
-      charcode = pPDFFont->CharCodeFromUnicode(word);
-    else
-      charcode = m_pFontMap->CharCodeFromUnicode(nFontIndex, word);
-
-    if (charcode != -1)
-      return pPDFFont->GetCharWidthF(charcode);
-  }
-
-  return 0;
-}
-
-int32_t CFX_Edit_Provider::GetTypeAscent(int32_t nFontIndex) {
-  if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex))
-    return pPDFFont->GetTypeAscent();
-
-  return 0;
-}
-
-int32_t CFX_Edit_Provider::GetTypeDescent(int32_t nFontIndex) {
-  if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex))
-    return pPDFFont->GetTypeDescent();
-
-  return 0;
-}
-
-int32_t CFX_Edit_Provider::GetWordFontIndex(FX_WORD word,
-                                            int32_t charset,
-                                            int32_t nFontIndex) {
-  return m_pFontMap->GetWordFontIndex(word, charset, nFontIndex);
-}
-
-int32_t CFX_Edit_Provider::GetDefaultFontIndex() {
-  return 0;
-}
-
-FX_BOOL CFX_Edit_Provider::IsLatinWord(FX_WORD word) {
-  return FX_EDIT_ISLATINWORD(word);
-}
-
-CFX_Edit_Refresh::CFX_Edit_Refresh() {}
-
-CFX_Edit_Refresh::~CFX_Edit_Refresh() {}
-
-void CFX_Edit_Refresh::BeginRefresh() {
-  m_RefreshRects.Empty();
-  m_OldLineRects = m_NewLineRects;
-}
-
-void CFX_Edit_Refresh::Push(const CPVT_WordRange& linerange,
-                            const CPDF_Rect& rect) {
-  m_NewLineRects.Add(linerange, rect);
-}
-
-void CFX_Edit_Refresh::NoAnalyse() {
-  {
-    for (int32_t i = 0, sz = m_OldLineRects.GetSize(); i < sz; i++)
-      if (CFX_Edit_LineRect* pOldRect = m_OldLineRects.GetAt(i))
-        m_RefreshRects.Add(pOldRect->m_rcLine);
-  }
-
-  {
-    for (int32_t i = 0, sz = m_NewLineRects.GetSize(); i < sz; i++)
-      if (CFX_Edit_LineRect* pNewRect = m_NewLineRects.GetAt(i))
-        m_RefreshRects.Add(pNewRect->m_rcLine);
-  }
-}
-
-void CFX_Edit_Refresh::Analyse(int32_t nAlignment) {
-  FX_BOOL bLineTopChanged = FALSE;
-  CPDF_Rect rcResult;
-  FX_FLOAT fWidthDiff;
-
-  int32_t szMax = std::max(m_OldLineRects.GetSize(), m_NewLineRects.GetSize());
-  int32_t i = 0;
-
-  while (i < szMax) {
-    CFX_Edit_LineRect* pOldRect = m_OldLineRects.GetAt(i);
-    CFX_Edit_LineRect* pNewRect = m_NewLineRects.GetAt(i);
-
-    if (pOldRect) {
-      if (pNewRect) {
-        if (bLineTopChanged) {
-          rcResult = pOldRect->m_rcLine;
-          rcResult.Union(pNewRect->m_rcLine);
-          m_RefreshRects.Add(rcResult);
-        } else {
-          if (*pNewRect != *pOldRect) {
-            if (!pNewRect->IsSameTop(*pOldRect) ||
-                !pNewRect->IsSameHeight(*pOldRect)) {
-              bLineTopChanged = TRUE;
-              continue;
-            }
-
-            if (nAlignment == 0) {
-              if (pNewRect->m_wrLine.BeginPos != pOldRect->m_wrLine.BeginPos) {
-                rcResult = pOldRect->m_rcLine;
-                rcResult.Union(pNewRect->m_rcLine);
-                m_RefreshRects.Add(rcResult);
-              } else {
-                if (!pNewRect->IsSameLeft(*pOldRect)) {
-                  rcResult = pOldRect->m_rcLine;
-                  rcResult.Union(pNewRect->m_rcLine);
-                } else {
-                  fWidthDiff =
-                      pNewRect->m_rcLine.Width() - pOldRect->m_rcLine.Width();
-                  rcResult = pNewRect->m_rcLine;
-                  if (fWidthDiff > 0.0f) {
-                    rcResult.left = rcResult.right - fWidthDiff;
-                  } else {
-                    rcResult.left = rcResult.right;
-                    rcResult.right += (-fWidthDiff);
-                  }
-                }
-                m_RefreshRects.Add(rcResult);
-              }
-            } else {
-              rcResult = pOldRect->m_rcLine;
-              rcResult.Union(pNewRect->m_rcLine);
-              m_RefreshRects.Add(rcResult);
-            }
-          }
-        }
-      } else {
-        m_RefreshRects.Add(pOldRect->m_rcLine);
-      }
-    } else {
-      if (pNewRect) {
-        m_RefreshRects.Add(pNewRect->m_rcLine);
-      }
-    }
-    i++;
-  }
-}
-
-void CFX_Edit_Refresh::AddRefresh(const CPDF_Rect& rect) {
-  m_RefreshRects.Add(rect);
-}
-
-const CFX_Edit_RectArray* CFX_Edit_Refresh::GetRefreshRects() const {
-  return &m_RefreshRects;
-}
-
-void CFX_Edit_Refresh::EndRefresh() {
-  m_RefreshRects.Empty();
-}
-
-CFX_Edit_Undo::CFX_Edit_Undo(int32_t nBufsize)
-    : m_nCurUndoPos(0),
-      m_nBufSize(nBufsize),
-      m_bModified(FALSE),
-      m_bVirgin(TRUE),
-      m_bWorking(FALSE) {}
-
-CFX_Edit_Undo::~CFX_Edit_Undo() {
-  Reset();
-}
-
-FX_BOOL CFX_Edit_Undo::CanUndo() const {
-  return m_nCurUndoPos > 0;
-}
-
-void CFX_Edit_Undo::Undo() {
-  m_bWorking = TRUE;
-
-  if (m_nCurUndoPos > 0) {
-    IFX_Edit_UndoItem* pItem = m_UndoItemStack.GetAt(m_nCurUndoPos - 1);
-    pItem->Undo();
-
-    m_nCurUndoPos--;
-    m_bModified = (m_nCurUndoPos != 0);
-  }
-
-  m_bWorking = FALSE;
-}
-
-FX_BOOL CFX_Edit_Undo::CanRedo() const {
-  return m_nCurUndoPos < m_UndoItemStack.GetSize();
-}
-
-void CFX_Edit_Undo::Redo() {
-  m_bWorking = TRUE;
-
-  int32_t nStackSize = m_UndoItemStack.GetSize();
-
-  if (m_nCurUndoPos < nStackSize) {
-    IFX_Edit_UndoItem* pItem = m_UndoItemStack.GetAt(m_nCurUndoPos);
-    pItem->Redo();
-
-    m_nCurUndoPos++;
-    m_bModified = (m_nCurUndoPos != 0);
-  }
-
-  m_bWorking = FALSE;
-}
-
-FX_BOOL CFX_Edit_Undo::IsWorking() const {
-  return m_bWorking;
-}
-
-void CFX_Edit_Undo::AddItem(IFX_Edit_UndoItem* pItem) {
-  ASSERT(!m_bWorking);
-  ASSERT(pItem);
-  ASSERT(m_nBufSize > 1);
-
-  if (m_nCurUndoPos < m_UndoItemStack.GetSize())
-    RemoveTails();
-
-  if (m_UndoItemStack.GetSize() >= m_nBufSize) {
-    RemoveHeads();
-    m_bVirgin = FALSE;
-  }
-
-  m_UndoItemStack.Add(pItem);
-  m_nCurUndoPos = m_UndoItemStack.GetSize();
-
-  m_bModified = (m_nCurUndoPos != 0);
-}
-
-FX_BOOL CFX_Edit_Undo::IsModified() const {
-  return m_bVirgin ? m_bModified : TRUE;
-}
-
-IFX_Edit_UndoItem* CFX_Edit_Undo::GetItem(int32_t nIndex) {
-  if (nIndex >= 0 && nIndex < m_UndoItemStack.GetSize())
-    return m_UndoItemStack.GetAt(nIndex);
-
-  return NULL;
-}
-
-void CFX_Edit_Undo::RemoveHeads() {
-  ASSERT(m_UndoItemStack.GetSize() > 1);
-
-  delete m_UndoItemStack.GetAt(0);
-  m_UndoItemStack.RemoveAt(0);
-}
-
-void CFX_Edit_Undo::RemoveTails() {
-  for (int32_t i = m_UndoItemStack.GetSize() - 1; i >= m_nCurUndoPos; i--) {
-    delete m_UndoItemStack.GetAt(i);
-    m_UndoItemStack.RemoveAt(i);
-  }
-}
-
-void CFX_Edit_Undo::Reset() {
-  for (int32_t i = 0, sz = m_UndoItemStack.GetSize(); i < sz; i++) {
-    delete m_UndoItemStack.GetAt(i);
-  }
-  m_nCurUndoPos = 0;
-  m_UndoItemStack.RemoveAll();
-}
-
-CFX_Edit_GroupUndoItem::CFX_Edit_GroupUndoItem(const CFX_WideString& sTitle)
-    : m_sTitle(sTitle) {}
-
-CFX_Edit_GroupUndoItem::~CFX_Edit_GroupUndoItem() {
-  for (int i = 0, sz = m_Items.GetSize(); i < sz; i++) {
-    delete m_Items[i];
-  }
-
-  m_Items.RemoveAll();
-}
-
-void CFX_Edit_GroupUndoItem::AddUndoItem(CFX_Edit_UndoItem* pUndoItem) {
-  pUndoItem->SetFirst(FALSE);
-  pUndoItem->SetLast(FALSE);
-
-  m_Items.Add(pUndoItem);
-
-  if (m_sTitle.IsEmpty())
-    m_sTitle = pUndoItem->GetUndoTitle();
-}
-
-void CFX_Edit_GroupUndoItem::UpdateItems() {
-  if (m_Items.GetSize() > 0) {
-    CFX_Edit_UndoItem* pFirstItem = m_Items[0];
-    pFirstItem->SetFirst(TRUE);
-
-    CFX_Edit_UndoItem* pLastItem = m_Items[m_Items.GetSize() - 1];
-    pLastItem->SetLast(TRUE);
-  }
-}
-
-void CFX_Edit_GroupUndoItem::Undo() {
-  for (int i = m_Items.GetSize() - 1; i >= 0; i--) {
-    CFX_Edit_UndoItem* pUndoItem = m_Items[i];
-    pUndoItem->Undo();
-  }
-}
-
-void CFX_Edit_GroupUndoItem::Redo() {
-  for (int i = 0, sz = m_Items.GetSize(); i < sz; i++) {
-    CFX_Edit_UndoItem* pUndoItem = m_Items[i];
-    pUndoItem->Redo();
-  }
-}
-
-CFX_WideString CFX_Edit_GroupUndoItem::GetUndoTitle() {
-  return m_sTitle;
-}
-
-CFXEU_InsertWord::CFXEU_InsertWord(CFX_Edit* pEdit,
-                                   const CPVT_WordPlace& wpOldPlace,
-                                   const CPVT_WordPlace& wpNewPlace,
-                                   FX_WORD word,
-                                   int32_t charset,
-                                   const CPVT_WordProps* pWordProps)
-    : m_pEdit(pEdit),
-      m_wpOld(wpOldPlace),
-      m_wpNew(wpNewPlace),
-      m_Word(word),
-      m_nCharset(charset),
-      m_WordProps() {
-  if (pWordProps)
-    m_WordProps = *pWordProps;
-}
-
-CFXEU_InsertWord::~CFXEU_InsertWord() {}
-
-void CFXEU_InsertWord::Redo() {
-  if (m_pEdit) {
-    m_pEdit->SelectNone();
-    m_pEdit->SetCaret(m_wpOld);
-    m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, FALSE, TRUE);
-  }
-}
-
-void CFXEU_InsertWord::Undo() {
-  if (m_pEdit) {
-    m_pEdit->SelectNone();
-    m_pEdit->SetCaret(m_wpNew);
-    m_pEdit->Backspace(FALSE, TRUE);
-  }
-}
-
-CFXEU_InsertReturn::CFXEU_InsertReturn(CFX_Edit* pEdit,
-                                       const CPVT_WordPlace& wpOldPlace,
-                                       const CPVT_WordPlace& wpNewPlace,
-                                       const CPVT_SecProps* pSecProps,
-                                       const CPVT_WordProps* pWordProps)
-    : m_pEdit(pEdit),
-      m_wpOld(wpOldPlace),
-      m_wpNew(wpNewPlace),
-      m_SecProps(),
-      m_WordProps() {
-  if (pSecProps)
-    m_SecProps = *pSecProps;
-  if (pWordProps)
-    m_WordProps = *pWordProps;
-}
-
-CFXEU_InsertReturn::~CFXEU_InsertReturn() {}
-
-void CFXEU_InsertReturn::Redo() {
-  if (m_pEdit) {
-    m_pEdit->SelectNone();
-    m_pEdit->SetCaret(m_wpOld);
-    m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, FALSE, TRUE);
-  }
-}
-
-void CFXEU_InsertReturn::Undo() {
-  if (m_pEdit) {
-    m_pEdit->SelectNone();
-    m_pEdit->SetCaret(m_wpNew);
-    m_pEdit->Backspace(FALSE, TRUE);
-  }
-}
-
-CFXEU_Backspace::CFXEU_Backspace(CFX_Edit* pEdit,
-                                 const CPVT_WordPlace& wpOldPlace,
-                                 const CPVT_WordPlace& wpNewPlace,
-                                 FX_WORD word,
-                                 int32_t charset,
-                                 const CPVT_SecProps& SecProps,
-                                 const CPVT_WordProps& WordProps)
-    : m_pEdit(pEdit),
-      m_wpOld(wpOldPlace),
-      m_wpNew(wpNewPlace),
-      m_Word(word),
-      m_nCharset(charset),
-      m_SecProps(SecProps),
-      m_WordProps(WordProps) {}
-
-CFXEU_Backspace::~CFXEU_Backspace() {}
-
-void CFXEU_Backspace::Redo() {
-  if (m_pEdit) {
-    m_pEdit->SelectNone();
-    m_pEdit->SetCaret(m_wpOld);
-    m_pEdit->Backspace(FALSE, TRUE);
-  }
-}
-
-void CFXEU_Backspace::Undo() {
-  if (m_pEdit) {
-    m_pEdit->SelectNone();
-    m_pEdit->SetCaret(m_wpNew);
-    if (m_wpNew.SecCmp(m_wpOld) != 0) {
-      m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, FALSE, TRUE);
-    } else {
-      m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, FALSE, TRUE);
-    }
-  }
-}
-
-CFXEU_Delete::CFXEU_Delete(CFX_Edit* pEdit,
-                           const CPVT_WordPlace& wpOldPlace,
-                           const CPVT_WordPlace& wpNewPlace,
-                           FX_WORD word,
-                           int32_t charset,
-                           const CPVT_SecProps& SecProps,
-                           const CPVT_WordProps& WordProps,
-                           FX_BOOL bSecEnd)
-    : m_pEdit(pEdit),
-      m_wpOld(wpOldPlace),
-      m_wpNew(wpNewPlace),
-      m_Word(word),
-      m_nCharset(charset),
-      m_SecProps(SecProps),
-      m_WordProps(WordProps),
-      m_bSecEnd(bSecEnd) {}
-
-CFXEU_Delete::~CFXEU_Delete() {}
-
-void CFXEU_Delete::Redo() {
-  if (m_pEdit) {
-    m_pEdit->SelectNone();
-    m_pEdit->SetCaret(m_wpOld);
-    m_pEdit->Delete(FALSE, TRUE);
-  }
-}
-
-void CFXEU_Delete::Undo() {
-  if (m_pEdit) {
-    m_pEdit->SelectNone();
-    m_pEdit->SetCaret(m_wpNew);
-    if (m_bSecEnd) {
-      m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, FALSE, TRUE);
-    } else {
-      m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, FALSE, TRUE);
-    }
-  }
-}
-
-CFXEU_Clear::CFXEU_Clear(CFX_Edit* pEdit,
-                         const CPVT_WordRange& wrSel,
-                         const CFX_WideString& swText)
-    : m_pEdit(pEdit), m_wrSel(wrSel), m_swText(swText) {}
-
-CFXEU_Clear::~CFXEU_Clear() {}
-
-void CFXEU_Clear::Redo() {
-  if (m_pEdit) {
-    m_pEdit->SelectNone();
-    m_pEdit->SetSel(m_wrSel.BeginPos, m_wrSel.EndPos);
-    m_pEdit->Clear(FALSE, TRUE);
-  }
-}
-
-void CFXEU_Clear::Undo() {
-  if (m_pEdit) {
-    m_pEdit->SelectNone();
-    m_pEdit->SetCaret(m_wrSel.BeginPos);
-    m_pEdit->InsertText(m_swText.c_str(), DEFAULT_CHARSET, NULL, NULL, FALSE,
-                        TRUE);
-    m_pEdit->SetSel(m_wrSel.BeginPos, m_wrSel.EndPos);
-  }
-}
-
-CFXEU_ClearRich::CFXEU_ClearRich(CFX_Edit* pEdit,
-                                 const CPVT_WordPlace& wpOldPlace,
-                                 const CPVT_WordPlace& wpNewPlace,
-                                 const CPVT_WordRange& wrSel,
-                                 FX_WORD word,
-                                 int32_t charset,
-                                 const CPVT_SecProps& SecProps,
-                                 const CPVT_WordProps& WordProps)
-    : m_pEdit(pEdit),
-      m_wpOld(wpOldPlace),
-      m_wpNew(wpNewPlace),
-      m_wrSel(wrSel),
-      m_Word(word),
-      m_nCharset(charset),
-      m_SecProps(SecProps),
-      m_WordProps(WordProps) {}
-
-CFXEU_ClearRich::~CFXEU_ClearRich() {}
-
-void CFXEU_ClearRich::Redo() {
-  if (m_pEdit && IsLast()) {
-    m_pEdit->SelectNone();
-    m_pEdit->SetSel(m_wrSel.BeginPos, m_wrSel.EndPos);
-    m_pEdit->Clear(FALSE, TRUE);
-  }
-}
-
-void CFXEU_ClearRich::Undo() {
-  if (m_pEdit) {
-    m_pEdit->SelectNone();
-    m_pEdit->SetCaret(m_wpOld);
-    if (m_wpNew.SecCmp(m_wpOld) != 0) {
-      m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, FALSE, FALSE);
-    } else {
-      m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, FALSE, FALSE);
-    }
-
-    if (IsFirst()) {
-      m_pEdit->PaintInsertText(m_wrSel.BeginPos, m_wrSel.EndPos);
-      m_pEdit->SetSel(m_wrSel.BeginPos, m_wrSel.EndPos);
-    }
-  }
-}
-CFXEU_InsertText::CFXEU_InsertText(CFX_Edit* pEdit,
-                                   const CPVT_WordPlace& wpOldPlace,
-                                   const CPVT_WordPlace& wpNewPlace,
-                                   const CFX_WideString& swText,
-                                   int32_t charset,
-                                   const CPVT_SecProps* pSecProps,
-                                   const CPVT_WordProps* pWordProps)
-    : m_pEdit(pEdit),
-      m_wpOld(wpOldPlace),
-      m_wpNew(wpNewPlace),
-      m_swText(swText),
-      m_nCharset(charset),
-      m_SecProps(),
-      m_WordProps() {
-  if (pSecProps)
-    m_SecProps = *pSecProps;
-  if (pWordProps)
-    m_WordProps = *pWordProps;
-}
-
-CFXEU_InsertText::~CFXEU_InsertText() {}
-
-void CFXEU_InsertText::Redo() {
-  if (m_pEdit && IsLast()) {
-    m_pEdit->SelectNone();
-    m_pEdit->SetCaret(m_wpOld);
-    m_pEdit->InsertText(m_swText.c_str(), m_nCharset, &m_SecProps, &m_WordProps,
-                        FALSE, TRUE);
-  }
-}
-
-void CFXEU_InsertText::Undo() {
-  if (m_pEdit) {
-    m_pEdit->SelectNone();
-    m_pEdit->SetSel(m_wpOld, m_wpNew);
-    m_pEdit->Clear(FALSE, TRUE);
-  }
-}
-
-CFXEU_SetSecProps::CFXEU_SetSecProps(CFX_Edit* pEdit,
-                                     const CPVT_WordPlace& place,
-                                     EDIT_PROPS_E ep,
-                                     const CPVT_SecProps& oldsecprops,
-                                     const CPVT_WordProps& oldwordprops,
-                                     const CPVT_SecProps& newsecprops,
-                                     const CPVT_WordProps& newwordprops,
-                                     const CPVT_WordRange& range)
-    : m_pEdit(pEdit),
-      m_wpPlace(place),
-      m_wrPlace(range),
-      m_eProps(ep),
-      m_OldSecProps(oldsecprops),
-      m_NewSecProps(newsecprops),
-      m_OldWordProps(oldwordprops),
-      m_NewWordProps(newwordprops) {}
-
-CFXEU_SetSecProps::~CFXEU_SetSecProps() {}
-
-void CFXEU_SetSecProps::Redo() {
-  if (m_pEdit) {
-    m_pEdit->SetSecProps(m_eProps, m_wpPlace, &m_NewSecProps, &m_NewWordProps,
-                         m_wrPlace, FALSE);
-    if (IsLast()) {
-      m_pEdit->SelectNone();
-      m_pEdit->PaintSetProps(m_eProps, m_wrPlace);
-      m_pEdit->SetSel(m_wrPlace.BeginPos, m_wrPlace.EndPos);
-    }
-  }
-}
-
-void CFXEU_SetSecProps::Undo() {
-  if (m_pEdit) {
-    m_pEdit->SetSecProps(m_eProps, m_wpPlace, &m_OldSecProps, &m_OldWordProps,
-                         m_wrPlace, FALSE);
-    if (IsFirst()) {
-      m_pEdit->SelectNone();
-      m_pEdit->PaintSetProps(m_eProps, m_wrPlace);
-      m_pEdit->SetSel(m_wrPlace.BeginPos, m_wrPlace.EndPos);
-    }
-  }
-}
-
-CFXEU_SetWordProps::CFXEU_SetWordProps(CFX_Edit* pEdit,
-                                       const CPVT_WordPlace& place,
-                                       EDIT_PROPS_E ep,
-                                       const CPVT_WordProps& oldprops,
-                                       const CPVT_WordProps& newprops,
-                                       const CPVT_WordRange& range)
-    : m_pEdit(pEdit),
-      m_wpPlace(place),
-      m_wrPlace(range),
-      m_eProps(ep),
-      m_OldWordProps(oldprops),
-      m_NewWordProps(newprops) {}
-
-CFXEU_SetWordProps::~CFXEU_SetWordProps() {}
-
-void CFXEU_SetWordProps::Redo() {
-  if (m_pEdit) {
-    m_pEdit->SetWordProps(m_eProps, m_wpPlace, &m_NewWordProps, m_wrPlace,
-                          FALSE);
-    if (IsLast()) {
-      m_pEdit->SelectNone();
-      m_pEdit->PaintSetProps(m_eProps, m_wrPlace);
-      m_pEdit->SetSel(m_wrPlace.BeginPos, m_wrPlace.EndPos);
-    }
-  }
-}
-
-void CFXEU_SetWordProps::Undo() {
-  if (m_pEdit) {
-    m_pEdit->SetWordProps(m_eProps, m_wpPlace, &m_OldWordProps, m_wrPlace,
-                          FALSE);
-    if (IsFirst()) {
-      m_pEdit->SelectNone();
-      m_pEdit->PaintSetProps(m_eProps, m_wrPlace);
-      m_pEdit->SetSel(m_wrPlace.BeginPos, m_wrPlace.EndPos);
-    }
-  }
-}
-
-CFX_Edit::CFX_Edit(IPDF_VariableText* pVT)
-    : m_pVT(pVT),
-      m_pNotify(NULL),
-      m_pOprNotify(NULL),
-      m_pVTProvide(NULL),
-      m_wpCaret(-1, -1, -1),
-      m_wpOldCaret(-1, -1, -1),
-      m_SelState(),
-      m_ptScrollPos(0, 0),
-      m_ptRefreshScrollPos(0, 0),
-      m_bEnableScroll(FALSE),
-      m_pIterator(NULL),
-      m_ptCaret(0.0f, 0.0f),
-      m_Undo(FX_EDIT_UNDO_MAXITEM),
-      m_nAlignment(0),
-      m_bNotifyFlag(FALSE),
-      m_bEnableOverflow(FALSE),
-      m_bEnableRefresh(TRUE),
-      m_rcOldContent(0.0f, 0.0f, 0.0f, 0.0f),
-      m_bEnableUndo(TRUE),
-      m_bNotify(TRUE),
-      m_bOprNotify(FALSE),
-      m_pGroupUndoItem(NULL) {
-  ASSERT(pVT);
-}
-
-CFX_Edit::~CFX_Edit() {
-  delete m_pVTProvide;
-  m_pVTProvide = NULL;
-  delete m_pIterator;
-  m_pIterator = NULL;
-  ASSERT(!m_pGroupUndoItem);
-}
-
-void CFX_Edit::Initialize() {
-  m_pVT->Initialize();
-  SetCaret(m_pVT->GetBeginWordPlace());
-  SetCaretOrigin();
-}
-
-void CFX_Edit::SetFontMap(IFX_Edit_FontMap* pFontMap) {
-  delete m_pVTProvide;
-  m_pVT->SetProvider(m_pVTProvide = new CFX_Edit_Provider(pFontMap));
-}
-
-void CFX_Edit::SetVTProvider(IPDF_VariableText_Provider* pProvider) {
-  m_pVT->SetProvider(pProvider);
-}
-
-void CFX_Edit::SetNotify(IFX_Edit_Notify* pNotify) {
-  m_pNotify = pNotify;
-}
-
-void CFX_Edit::SetOprNotify(IFX_Edit_OprNotify* pOprNotify) {
-  m_pOprNotify = pOprNotify;
-}
-
-IFX_Edit_Iterator* CFX_Edit::GetIterator() {
-  if (!m_pIterator)
-    m_pIterator = new CFX_Edit_Iterator(this, m_pVT->GetIterator());
-
-  return m_pIterator;
-}
-
-IPDF_VariableText* CFX_Edit::GetVariableText() {
-  return m_pVT;
-}
-
-IFX_Edit_FontMap* CFX_Edit::GetFontMap() {
-  if (m_pVTProvide)
-    return m_pVTProvide->GetFontMap();
-
-  return NULL;
-}
-
-void CFX_Edit::SetPlateRect(const CPDF_Rect& rect, FX_BOOL bPaint) {
-  m_pVT->SetPlateRect(rect);
-  m_ptScrollPos = CPDF_Point(rect.left, rect.top);
-  if (bPaint)
-    Paint();
-}
-
-void CFX_Edit::SetAlignmentH(int32_t nFormat, FX_BOOL bPaint) {
-  m_pVT->SetAlignment(nFormat);
-  if (bPaint)
-    Paint();
-}
-
-void CFX_Edit::SetAlignmentV(int32_t nFormat, FX_BOOL bPaint) {
-  m_nAlignment = nFormat;
-  if (bPaint)
-    Paint();
-}
-
-void CFX_Edit::SetPasswordChar(FX_WORD wSubWord, FX_BOOL bPaint) {
-  m_pVT->SetPasswordChar(wSubWord);
-  if (bPaint)
-    Paint();
-}
-
-void CFX_Edit::SetLimitChar(int32_t nLimitChar, FX_BOOL bPaint) {
-  m_pVT->SetLimitChar(nLimitChar);
-  if (bPaint)
-    Paint();
-}
-
-void CFX_Edit::SetCharArray(int32_t nCharArray, FX_BOOL bPaint) {
-  m_pVT->SetCharArray(nCharArray);
-  if (bPaint)
-    Paint();
-}
-
-void CFX_Edit::SetCharSpace(FX_FLOAT fCharSpace, FX_BOOL bPaint) {
-  m_pVT->SetCharSpace(fCharSpace);
-  if (bPaint)
-    Paint();
-}
-
-void CFX_Edit::SetHorzScale(int32_t nHorzScale, FX_BOOL bPaint) {
-  m_pVT->SetHorzScale(nHorzScale);
-  if (bPaint)
-    Paint();
-}
-
-void CFX_Edit::SetMultiLine(FX_BOOL bMultiLine, FX_BOOL bPaint) {
-  m_pVT->SetMultiLine(bMultiLine);
-  if (bPaint)
-    Paint();
-}
-
-void CFX_Edit::SetAutoReturn(FX_BOOL bAuto, FX_BOOL bPaint) {
-  m_pVT->SetAutoReturn(bAuto);
-  if (bPaint)
-    Paint();
-}
-
-void CFX_Edit::SetLineLeading(FX_FLOAT fLineLeading, FX_BOOL bPaint) {
-  m_pVT->SetLineLeading(fLineLeading);
-  if (bPaint)
-    Paint();
-}
-
-void CFX_Edit::SetAutoFontSize(FX_BOOL bAuto, FX_BOOL bPaint) {
-  m_pVT->SetAutoFontSize(bAuto);
-  if (bPaint)
-    Paint();
-}
-
-void CFX_Edit::SetFontSize(FX_FLOAT fFontSize, FX_BOOL bPaint) {
-  m_pVT->SetFontSize(fFontSize);
-  if (bPaint)
-    Paint();
-}
-
-void CFX_Edit::SetAutoScroll(FX_BOOL bAuto, FX_BOOL bPaint) {
-  m_bEnableScroll = bAuto;
-  if (bPaint)
-    Paint();
-}
-
-void CFX_Edit::SetTextOverflow(FX_BOOL bAllowed, FX_BOOL bPaint) {
-  m_bEnableOverflow = bAllowed;
-  if (bPaint)
-    Paint();
-}
-
-void CFX_Edit::SetSel(int32_t nStartChar, int32_t nEndChar) {
-  if (m_pVT->IsValid()) {
-    if (nStartChar == 0 && nEndChar < 0) {
-      SelectAll();
-    } else if (nStartChar < 0) {
-      SelectNone();
-    } else {
-      if (nStartChar < nEndChar) {
-        SetSel(m_pVT->WordIndexToWordPlace(nStartChar),
-               m_pVT->WordIndexToWordPlace(nEndChar));
-      } else {
-        SetSel(m_pVT->WordIndexToWordPlace(nEndChar),
-               m_pVT->WordIndexToWordPlace(nStartChar));
-      }
-    }
-  }
-}
-
-void CFX_Edit::SetSel(const CPVT_WordPlace& begin, const CPVT_WordPlace& end) {
-  if (m_pVT->IsValid()) {
-    SelectNone();
-
-    m_SelState.Set(begin, end);
-
-    SetCaret(m_SelState.EndPos);
-
-    if (m_SelState.IsExist()) {
-      ScrollToCaret();
-      CPVT_WordRange wr(m_SelState.BeginPos, m_SelState.EndPos);
-      Refresh(RP_OPTIONAL, &wr);
-      SetCaretInfo();
-    } else {
-      ScrollToCaret();
-      SetCaretInfo();
-    }
-  }
-}
-
-void CFX_Edit::GetSel(int32_t& nStartChar, int32_t& nEndChar) const {
-  nStartChar = -1;
-  nEndChar = -1;
-
-  if (m_pVT->IsValid()) {
-    if (m_SelState.IsExist()) {
-      if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos) < 0) {
-        nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos);
-        nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos);
-      } else {
-        nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos);
-        nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos);
-      }
-    } else {
-      nStartChar = m_pVT->WordPlaceToWordIndex(m_wpCaret);
-      nEndChar = m_pVT->WordPlaceToWordIndex(m_wpCaret);
-    }
-  }
-}
-
-int32_t CFX_Edit::GetCaret() const {
-  if (m_pVT->IsValid())
-    return m_pVT->WordPlaceToWordIndex(m_wpCaret);
-
-  return -1;
-}
-
-CPVT_WordPlace CFX_Edit::GetCaretWordPlace() const {
-  return m_wpCaret;
-}
-
-CFX_WideString CFX_Edit::GetText() const {
-  CFX_WideString swRet;
-
-  if (m_pVT->IsValid()) {
-    if (IPDF_VariableText_Iterator* pIterator = m_pVT->GetIterator()) {
-      FX_BOOL bRich = m_pVT->IsRichText();
-
-      pIterator->SetAt(0);
-
-      CPVT_Word wordinfo;
-      CPVT_WordPlace oldplace = pIterator->GetAt();
-      while (pIterator->NextWord()) {
-        CPVT_WordPlace place = pIterator->GetAt();
-
-        if (pIterator->GetWord(wordinfo)) {
-          if (bRich) {
-            swRet += wordinfo.Word;
-          } else {
-            swRet += wordinfo.Word;
-          }
-        }
-
-        if (oldplace.SecCmp(place) != 0) {
-          swRet += 0x0D;
-          swRet += 0x0A;
-        }
-
-        oldplace = place;
-      }
-    }
-  }
-
-  return swRet;
-}
-
-CFX_WideString CFX_Edit::GetRangeText(const CPVT_WordRange& range) const {
-  CFX_WideString swRet;
-
-  if (m_pVT->IsValid()) {
-    FX_BOOL bRich = m_pVT->IsRichText();
-
-    if (IPDF_VariableText_Iterator* pIterator = m_pVT->GetIterator()) {
-      CPVT_WordRange wrTemp = range;
-      m_pVT->UpdateWordPlace(wrTemp.BeginPos);
-      m_pVT->UpdateWordPlace(wrTemp.EndPos);
-      pIterator->SetAt(wrTemp.BeginPos);
-
-      CPVT_Word wordinfo;
-      CPVT_WordPlace oldplace = wrTemp.BeginPos;
-      while (pIterator->NextWord()) {
-        CPVT_WordPlace place = pIterator->GetAt();
-        if (place.WordCmp(wrTemp.EndPos) > 0)
-          break;
-
-        if (pIterator->GetWord(wordinfo)) {
-          if (bRich) {
-            swRet += wordinfo.Word;
-          } else {
-            swRet += wordinfo.Word;
-          }
-        }
-
-        if (oldplace.SecCmp(place) != 0) {
-          swRet += 0x0D;
-          swRet += 0x0A;
-        }
-
-        oldplace = place;
-      }
-    }
-  }
-
-  return swRet;
-}
-
-CFX_WideString CFX_Edit::GetSelText() const {
-  return GetRangeText(m_SelState.ConvertToWordRange());
-}
-
-int32_t CFX_Edit::GetTotalWords() const {
-  return m_pVT->GetTotalWords();
-}
-
-int32_t CFX_Edit::GetTotalLines() const {
-  int32_t nLines = 0;
-
-  if (IPDF_VariableText_Iterator* pIterator = m_pVT->GetIterator()) {
-    pIterator->SetAt(0);
-    while (pIterator->NextLine())
-      nLines++;
-  }
-
-  return nLines + 1;
-}
-
-CPVT_WordRange CFX_Edit::GetSelectWordRange() const {
-  return m_SelState.ConvertToWordRange();
-}
-
-CPVT_WordRange CFX_Edit::CombineWordRange(const CPVT_WordRange& wr1,
-                                          const CPVT_WordRange& wr2) {
-  CPVT_WordRange wrRet;
-
-  if (wr1.BeginPos.WordCmp(wr2.BeginPos) < 0) {
-    wrRet.BeginPos = wr1.BeginPos;
-  } else {
-    wrRet.BeginPos = wr2.BeginPos;
-  }
-
-  if (wr1.EndPos.WordCmp(wr2.EndPos) < 0) {
-    wrRet.EndPos = wr2.EndPos;
-  } else {
-    wrRet.EndPos = wr1.EndPos;
-  }
-
-  return wrRet;
-}
-
-FX_BOOL CFX_Edit::IsRichText() const {
-  return m_pVT->IsRichText();
-}
-
-void CFX_Edit::SetRichText(FX_BOOL bRichText, FX_BOOL bPaint) {
-  m_pVT->SetRichText(bRichText);
-  if (bPaint)
-    Paint();
-}
-
-FX_BOOL CFX_Edit::SetRichFontIndex(int32_t nFontIndex) {
-  CPVT_WordProps WordProps;
-  WordProps.nFontIndex = nFontIndex;
-  return SetRichTextProps(EP_FONTINDEX, NULL, &WordProps);
-}
-
-FX_BOOL CFX_Edit::SetRichFontSize(FX_FLOAT fFontSize) {
-  CPVT_WordProps WordProps;
-  WordProps.fFontSize = fFontSize;
-  return SetRichTextProps(EP_FONTSIZE, NULL, &WordProps);
-}
-
-FX_BOOL CFX_Edit::SetRichTextColor(FX_COLORREF dwColor) {
-  CPVT_WordProps WordProps;
-  WordProps.dwWordColor = dwColor;
-  return SetRichTextProps(EP_WORDCOLOR, NULL, &WordProps);
-}
-
-FX_BOOL CFX_Edit::SetRichTextScript(int32_t nScriptType) {
-  CPVT_WordProps WordProps;
-  WordProps.nScriptType = nScriptType;
-  return SetRichTextProps(EP_SCRIPTTYPE, NULL, &WordProps);
-}
-
-FX_BOOL CFX_Edit::SetRichTextBold(FX_BOOL bBold) {
-  CPVT_WordProps WordProps;
-  if (bBold)
-    WordProps.nWordStyle |= PVTWORD_STYLE_BOLD;
-  return SetRichTextProps(EP_BOLD, NULL, &WordProps);
-}
-
-FX_BOOL CFX_Edit::SetRichTextItalic(FX_BOOL bItalic) {
-  CPVT_WordProps WordProps;
-  if (bItalic)
-    WordProps.nWordStyle |= PVTWORD_STYLE_ITALIC;
-  return SetRichTextProps(EP_ITALIC, NULL, &WordProps);
-}
-
-FX_BOOL CFX_Edit::SetRichTextUnderline(FX_BOOL bUnderline) {
-  CPVT_WordProps WordProps;
-  if (bUnderline)
-    WordProps.nWordStyle |= PVTWORD_STYLE_UNDERLINE;
-  return SetRichTextProps(EP_UNDERLINE, NULL, &WordProps);
-}
-
-FX_BOOL CFX_Edit::SetRichTextCrossout(FX_BOOL bCrossout) {
-  CPVT_WordProps WordProps;
-  if (bCrossout)
-    WordProps.nWordStyle |= PVTWORD_STYLE_CROSSOUT;
-  return SetRichTextProps(EP_CROSSOUT, NULL, &WordProps);
-}
-
-FX_BOOL CFX_Edit::SetRichTextCharSpace(FX_FLOAT fCharSpace) {
-  CPVT_WordProps WordProps;
-  WordProps.fCharSpace = fCharSpace;
-  return SetRichTextProps(EP_CHARSPACE, NULL, &WordProps);
-}
-
-FX_BOOL CFX_Edit::SetRichTextHorzScale(int32_t nHorzScale) {
-  CPVT_WordProps WordProps;
-  WordProps.nHorzScale = nHorzScale;
-  return SetRichTextProps(EP_HORZSCALE, NULL, &WordProps);
-}
-
-FX_BOOL CFX_Edit::SetRichTextLineLeading(FX_FLOAT fLineLeading) {
-  CPVT_SecProps SecProps;
-  SecProps.fLineLeading = fLineLeading;
-  return SetRichTextProps(EP_LINELEADING, &SecProps, NULL);
-}
-
-FX_BOOL CFX_Edit::SetRichTextLineIndent(FX_FLOAT fLineIndent) {
-  CPVT_SecProps SecProps;
-  SecProps.fLineIndent = fLineIndent;
-  return SetRichTextProps(EP_LINEINDENT, &SecProps, NULL);
-}
-
-FX_BOOL CFX_Edit::SetRichTextAlignment(int32_t nAlignment) {
-  CPVT_SecProps SecProps;
-  SecProps.nAlignment = nAlignment;
-  return SetRichTextProps(EP_ALIGNMENT, &SecProps, NULL);
-}
-
-FX_BOOL CFX_Edit::SetRichTextProps(EDIT_PROPS_E eProps,
-                                   const CPVT_SecProps* pSecProps,
-                                   const CPVT_WordProps* pWordProps) {
-  FX_BOOL bSet = FALSE;
-  FX_BOOL bSet1, bSet2;
-  if (m_pVT->IsValid() && m_pVT->IsRichText()) {
-    if (IPDF_VariableText_Iterator* pIterator = m_pVT->GetIterator()) {
-      CPVT_WordRange wrTemp = m_SelState.ConvertToWordRange();
-
-      m_pVT->UpdateWordPlace(wrTemp.BeginPos);
-      m_pVT->UpdateWordPlace(wrTemp.EndPos);
-      pIterator->SetAt(wrTemp.BeginPos);
-
-      BeginGroupUndo(L"");
-      bSet = SetSecProps(eProps, wrTemp.BeginPos, pSecProps, pWordProps, wrTemp,
-                         TRUE);
-
-      while (pIterator->NextWord()) {
-        CPVT_WordPlace place = pIterator->GetAt();
-        if (place.WordCmp(wrTemp.EndPos) > 0)
-          break;
-        bSet1 = SetSecProps(eProps, place, pSecProps, pWordProps, wrTemp, TRUE);
-        bSet2 = SetWordProps(eProps, place, pWordProps, wrTemp, TRUE);
-
-        if (!bSet)
-          bSet = (bSet1 || bSet2);
-      }
-
-      EndGroupUndo();
-
-      if (bSet) {
-        PaintSetProps(eProps, wrTemp);
-      }
-    }
-  }
-
-  return bSet;
-}
-
-void CFX_Edit::PaintSetProps(EDIT_PROPS_E eProps, const CPVT_WordRange& wr) {
-  switch (eProps) {
-    case EP_LINELEADING:
-    case EP_LINEINDENT:
-    case EP_ALIGNMENT:
-      RearrangePart(wr);
-      ScrollToCaret();
-      Refresh(RP_ANALYSE);
-      SetCaretOrigin();
-      SetCaretInfo();
-      break;
-    case EP_WORDCOLOR:
-    case EP_UNDERLINE:
-    case EP_CROSSOUT:
-      Refresh(RP_OPTIONAL, &wr);
-      break;
-    case EP_FONTINDEX:
-    case EP_FONTSIZE:
-    case EP_SCRIPTTYPE:
-    case EP_CHARSPACE:
-    case EP_HORZSCALE:
-    case EP_BOLD:
-    case EP_ITALIC:
-      RearrangePart(wr);
-      ScrollToCaret();
-
-      CPVT_WordRange wrRefresh(m_pVT->GetSectionBeginPlace(wr.BeginPos),
-                               m_pVT->GetSectionEndPlace(wr.EndPos));
-      Refresh(RP_ANALYSE, &wrRefresh);
-
-      SetCaretOrigin();
-      SetCaretInfo();
-      break;
-  }
-}
-
-FX_BOOL CFX_Edit::SetSecProps(EDIT_PROPS_E eProps,
-                              const CPVT_WordPlace& place,
-                              const CPVT_SecProps* pSecProps,
-                              const CPVT_WordProps* pWordProps,
-                              const CPVT_WordRange& wr,
-                              FX_BOOL bAddUndo) {
-  if (m_pVT->IsValid() && m_pVT->IsRichText()) {
-    if (IPDF_VariableText_Iterator* pIterator = m_pVT->GetIterator()) {
-      FX_BOOL bSet = FALSE;
-      CPVT_Section secinfo;
-      CPVT_Section OldSecinfo;
-
-      CPVT_WordPlace oldplace = pIterator->GetAt();
-
-      if (eProps == EP_LINELEADING || eProps == EP_LINEINDENT ||
-          eProps == EP_ALIGNMENT) {
-        if (pSecProps) {
-          pIterator->SetAt(place);
-          if (pIterator->GetSection(secinfo)) {
-            if (bAddUndo)
-              OldSecinfo = secinfo;
-
-            switch (eProps) {
-              case EP_LINELEADING:
-                if (!FX_EDIT_IsFloatEqual(secinfo.SecProps.fLineLeading,
-                                          pSecProps->fLineLeading)) {
-                  secinfo.SecProps.fLineLeading = pSecProps->fLineLeading;
-                  bSet = TRUE;
-                }
-                break;
-              case EP_LINEINDENT:
-                if (!FX_EDIT_IsFloatEqual(secinfo.SecProps.fLineIndent,
-                                          pSecProps->fLineIndent)) {
-                  secinfo.SecProps.fLineIndent = pSecProps->fLineIndent;
-                  bSet = TRUE;
-                }
-                break;
-              case EP_ALIGNMENT:
-                if (secinfo.SecProps.nAlignment != pSecProps->nAlignment) {
-                  secinfo.SecProps.nAlignment = pSecProps->nAlignment;
-                  bSet = TRUE;
-                }
-                break;
-              default:
-                break;
-            }
-          }
-        }
-      } else {
-        if (pWordProps && place == m_pVT->GetSectionBeginPlace(place)) {
-          pIterator->SetAt(place);
-          if (pIterator->GetSection(secinfo)) {
-            if (bAddUndo)
-              OldSecinfo = secinfo;
-
-            switch (eProps) {
-              case EP_FONTINDEX:
-                if (secinfo.WordProps.nFontIndex != pWordProps->nFontIndex) {
-                  secinfo.WordProps.nFontIndex = pWordProps->nFontIndex;
-                  bSet = TRUE;
-                }
-                break;
-              case EP_FONTSIZE:
-                if (!FX_EDIT_IsFloatEqual(secinfo.WordProps.fFontSize,
-                                          pWordProps->fFontSize)) {
-                  secinfo.WordProps.fFontSize = pWordProps->fFontSize;
-                  bSet = TRUE;
-                }
-                break;
-              case EP_WORDCOLOR:
-                if (secinfo.WordProps.dwWordColor != pWordProps->dwWordColor) {
-                  secinfo.WordProps.dwWordColor = pWordProps->dwWordColor;
-                  bSet = TRUE;
-                }
-                break;
-              case EP_SCRIPTTYPE:
-                if (secinfo.WordProps.nScriptType != pWordProps->nScriptType) {
-                  secinfo.WordProps.nScriptType = pWordProps->nScriptType;
-                  bSet = TRUE;
-                }
-                break;
-              case EP_CHARSPACE:
-                if (!FX_EDIT_IsFloatEqual(secinfo.WordProps.fCharSpace,
-                                          pWordProps->fCharSpace)) {
-                  secinfo.WordProps.fCharSpace = pWordProps->fCharSpace;
-                  bSet = TRUE;
-                }
-                break;
-              case EP_HORZSCALE:
-                if (secinfo.WordProps.nHorzScale != pWordProps->nHorzScale) {
-                  secinfo.WordProps.nHorzScale = pWordProps->nHorzScale;
-                  bSet = TRUE;
-                }
-                break;
-              case EP_UNDERLINE:
-                if (pWordProps->nWordStyle & PVTWORD_STYLE_UNDERLINE) {
-                  if ((secinfo.WordProps.nWordStyle &
-                       PVTWORD_STYLE_UNDERLINE) == 0) {
-                    secinfo.WordProps.nWordStyle |= PVTWORD_STYLE_UNDERLINE;
-                    bSet = TRUE;
-                  }
-                } else {
-                  if ((secinfo.WordProps.nWordStyle &
-                       PVTWORD_STYLE_UNDERLINE) != 0) {
-                    secinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_UNDERLINE;
-                    bSet = TRUE;
-                  }
-                }
-                break;
-              case EP_CROSSOUT:
-                if (pWordProps->nWordStyle & PVTWORD_STYLE_CROSSOUT) {
-                  if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT) ==
-                      0) {
-                    secinfo.WordProps.nWordStyle |= PVTWORD_STYLE_CROSSOUT;
-                    bSet = TRUE;
-                  }
-                } else {
-                  if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT) !=
-                      0) {
-                    secinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_CROSSOUT;
-                    bSet = TRUE;
-                  }
-                }
-                break;
-              case EP_BOLD:
-                if (pWordProps->nWordStyle & PVTWORD_STYLE_BOLD) {
-                  if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_BOLD) ==
-                      0) {
-                    secinfo.WordProps.nWordStyle |= PVTWORD_STYLE_BOLD;
-                    bSet = TRUE;
-                  }
-                } else {
-                  if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_BOLD) !=
-                      0) {
-                    secinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_BOLD;
-                    bSet = TRUE;
-                  }
-                }
-                break;
-              case EP_ITALIC:
-                if (pWordProps->nWordStyle & PVTWORD_STYLE_ITALIC) {
-                  if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_ITALIC) ==
-                      0) {
-                    secinfo.WordProps.nWordStyle |= PVTWORD_STYLE_ITALIC;
-                    bSet = TRUE;
-                  }
-                } else {
-                  if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_ITALIC) !=
-                      0) {
-                    secinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_ITALIC;
-                    bSet = TRUE;
-                  }
-                }
-                break;
-              default:
-                break;
-            }
-          }
-        }
-      }
-
-      if (bSet) {
-        pIterator->SetSection(secinfo);
-
-        if (bAddUndo && m_bEnableUndo) {
-          AddEditUndoItem(new CFXEU_SetSecProps(
-              this, place, eProps, OldSecinfo.SecProps, OldSecinfo.WordProps,
-              secinfo.SecProps, secinfo.WordProps, wr));
-        }
-      }
-
-      pIterator->SetAt(oldplace);
-
-      return bSet;
-    }
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CFX_Edit::SetWordProps(EDIT_PROPS_E eProps,
-                               const CPVT_WordPlace& place,
-                               const CPVT_WordProps* pWordProps,
-                               const CPVT_WordRange& wr,
-                               FX_BOOL bAddUndo) {
-  if (m_pVT->IsValid() && m_pVT->IsRichText()) {
-    if (IPDF_VariableText_Iterator* pIterator = m_pVT->GetIterator()) {
-      FX_BOOL bSet = FALSE;
-      CPVT_Word wordinfo;
-      CPVT_Word OldWordinfo;
-
-      CPVT_WordPlace oldplace = pIterator->GetAt();
-
-      if (pWordProps) {
-        pIterator->SetAt(place);
-        if (pIterator->GetWord(wordinfo)) {
-          if (bAddUndo)
-            OldWordinfo = wordinfo;
-
-          switch (eProps) {
-            case EP_FONTINDEX:
-              if (wordinfo.WordProps.nFontIndex != pWordProps->nFontIndex) {
-                if (IFX_Edit_FontMap* pFontMap = GetFontMap()) {
-                  wordinfo.WordProps.nFontIndex = pFontMap->GetWordFontIndex(
-                      wordinfo.Word, wordinfo.nCharset, pWordProps->nFontIndex);
-                }
-                bSet = TRUE;
-              }
-              break;
-            case EP_FONTSIZE:
-              if (!FX_EDIT_IsFloatEqual(wordinfo.WordProps.fFontSize,
-                                        pWordProps->fFontSize)) {
-                wordinfo.WordProps.fFontSize = pWordProps->fFontSize;
-                bSet = TRUE;
-              }
-              break;
-            case EP_WORDCOLOR:
-              if (wordinfo.WordProps.dwWordColor != pWordProps->dwWordColor) {
-                wordinfo.WordProps.dwWordColor = pWordProps->dwWordColor;
-                bSet = TRUE;
-              }
-              break;
-            case EP_SCRIPTTYPE:
-              if (wordinfo.WordProps.nScriptType != pWordProps->nScriptType) {
-                wordinfo.WordProps.nScriptType = pWordProps->nScriptType;
-                bSet = TRUE;
-              }
-              break;
-            case EP_CHARSPACE:
-              if (!FX_EDIT_IsFloatEqual(wordinfo.WordProps.fCharSpace,
-                                        pWordProps->fCharSpace)) {
-                wordinfo.WordProps.fCharSpace = pWordProps->fCharSpace;
-                bSet = TRUE;
-              }
-              break;
-            case EP_HORZSCALE:
-              if (wordinfo.WordProps.nHorzScale != pWordProps->nHorzScale) {
-                wordinfo.WordProps.nHorzScale = pWordProps->nHorzScale;
-                bSet = TRUE;
-              }
-              break;
-            case EP_UNDERLINE:
-              if (pWordProps->nWordStyle & PVTWORD_STYLE_UNDERLINE) {
-                if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE) ==
-                    0) {
-                  wordinfo.WordProps.nWordStyle |= PVTWORD_STYLE_UNDERLINE;
-                  bSet = TRUE;
-                }
-              } else {
-                if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE) !=
-                    0) {
-                  wordinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_UNDERLINE;
-                  bSet = TRUE;
-                }
-              }
-              break;
-            case EP_CROSSOUT:
-              if (pWordProps->nWordStyle & PVTWORD_STYLE_CROSSOUT) {
-                if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT) ==
-                    0) {
-                  wordinfo.WordProps.nWordStyle |= PVTWORD_STYLE_CROSSOUT;
-                  bSet = TRUE;
-                }
-              } else {
-                if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT) !=
-                    0) {
-                  wordinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_CROSSOUT;
-                  bSet = TRUE;
-                }
-              }
-              break;
-            case EP_BOLD:
-              if (pWordProps->nWordStyle & PVTWORD_STYLE_BOLD) {
-                if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_BOLD) == 0) {
-                  wordinfo.WordProps.nWordStyle |= PVTWORD_STYLE_BOLD;
-                  bSet = TRUE;
-                }
-              } else {
-                if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_BOLD) != 0) {
-                  wordinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_BOLD;
-                  bSet = TRUE;
-                }
-              }
-              break;
-            case EP_ITALIC:
-              if (pWordProps->nWordStyle & PVTWORD_STYLE_ITALIC) {
-                if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_ITALIC) ==
-                    0) {
-                  wordinfo.WordProps.nWordStyle |= PVTWORD_STYLE_ITALIC;
-                  bSet = TRUE;
-                }
-              } else {
-                if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_ITALIC) !=
-                    0) {
-                  wordinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_ITALIC;
-                  bSet = TRUE;
-                }
-              }
-              break;
-            default:
-              break;
-          }
-        }
-      }
-
-      if (bSet) {
-        pIterator->SetWord(wordinfo);
-
-        if (bAddUndo && m_bEnableUndo) {
-          AddEditUndoItem(new CFXEU_SetWordProps(this, place, eProps,
-                                                 OldWordinfo.WordProps,
-                                                 wordinfo.WordProps, wr));
-        }
-      }
-
-      pIterator->SetAt(oldplace);
-      return bSet;
-    }
-  }
-
-  return FALSE;
-}
-
-void CFX_Edit::SetText(const FX_WCHAR* text,
-                       int32_t charset,
-                       const CPVT_SecProps* pSecProps,
-                       const CPVT_WordProps* pWordProps) {
-  SetText(text, charset, pSecProps, pWordProps, TRUE, TRUE);
-}
-
-FX_BOOL CFX_Edit::InsertWord(FX_WORD word,
-                             int32_t charset,
-                             const CPVT_WordProps* pWordProps) {
-  return InsertWord(word, charset, pWordProps, TRUE, TRUE);
-}
-
-FX_BOOL CFX_Edit::InsertReturn(const CPVT_SecProps* pSecProps,
-                               const CPVT_WordProps* pWordProps) {
-  return InsertReturn(pSecProps, pWordProps, TRUE, TRUE);
-}
-
-FX_BOOL CFX_Edit::Backspace() {
-  return Backspace(TRUE, TRUE);
-}
-
-FX_BOOL CFX_Edit::Delete() {
-  return Delete(TRUE, TRUE);
-}
-
-FX_BOOL CFX_Edit::Clear() {
-  return Clear(TRUE, TRUE);
-}
-
-FX_BOOL CFX_Edit::InsertText(const FX_WCHAR* text,
-                             int32_t charset,
-                             const CPVT_SecProps* pSecProps,
-                             const CPVT_WordProps* pWordProps) {
-  return InsertText(text, charset, pSecProps, pWordProps, TRUE, TRUE);
-}
-
-FX_FLOAT CFX_Edit::GetFontSize() const {
-  return m_pVT->GetFontSize();
-}
-
-FX_WORD CFX_Edit::GetPasswordChar() const {
-  return m_pVT->GetPasswordChar();
-}
-
-int32_t CFX_Edit::GetCharArray() const {
-  return m_pVT->GetCharArray();
-}
-
-CPDF_Rect CFX_Edit::GetPlateRect() const {
-  return m_pVT->GetPlateRect();
-}
-
-CPDF_Rect CFX_Edit::GetContentRect() const {
-  return VTToEdit(m_pVT->GetContentRect());
-}
-
-int32_t CFX_Edit::GetHorzScale() const {
-  return m_pVT->GetHorzScale();
-}
-
-FX_FLOAT CFX_Edit::GetCharSpace() const {
-  return m_pVT->GetCharSpace();
-}
-
-CPVT_WordRange CFX_Edit::GetWholeWordRange() const {
-  if (m_pVT->IsValid())
-    return CPVT_WordRange(m_pVT->GetBeginWordPlace(), m_pVT->GetEndWordPlace());
-
-  return CPVT_WordRange();
-}
-
-CPVT_WordRange CFX_Edit::GetVisibleWordRange() const {
-  if (m_bEnableOverflow)
-    return GetWholeWordRange();
-
-  if (m_pVT->IsValid()) {
-    CPDF_Rect rcPlate = m_pVT->GetPlateRect();
-
-    CPVT_WordPlace place1 =
-        m_pVT->SearchWordPlace(EditToVT(CPDF_Point(rcPlate.left, rcPlate.top)));
-    CPVT_WordPlace place2 = m_pVT->SearchWordPlace(
-        EditToVT(CPDF_Point(rcPlate.right, rcPlate.bottom)));
-
-    return CPVT_WordRange(place1, place2);
-  }
-
-  return CPVT_WordRange();
-}
-
-CPVT_WordPlace CFX_Edit::SearchWordPlace(const CPDF_Point& point) const {
-  if (m_pVT->IsValid()) {
-    return m_pVT->SearchWordPlace(EditToVT(point));
-  }
-
-  return CPVT_WordPlace();
-}
-
-void CFX_Edit::Paint() {
-  if (m_pVT->IsValid()) {
-    RearrangeAll();
-    ScrollToCaret();
-    Refresh(RP_NOANALYSE);
-    SetCaretOrigin();
-    SetCaretInfo();
-  }
-}
-
-void CFX_Edit::RearrangeAll() {
-  if (m_pVT->IsValid()) {
-    m_pVT->UpdateWordPlace(m_wpCaret);
-    m_pVT->RearrangeAll();
-    m_pVT->UpdateWordPlace(m_wpCaret);
-    SetScrollInfo();
-    SetContentChanged();
-  }
-}
-
-void CFX_Edit::RearrangePart(const CPVT_WordRange& range) {
-  if (m_pVT->IsValid()) {
-    m_pVT->UpdateWordPlace(m_wpCaret);
-    m_pVT->RearrangePart(range);
-    m_pVT->UpdateWordPlace(m_wpCaret);
-    SetScrollInfo();
-    SetContentChanged();
-  }
-}
-
-void CFX_Edit::SetContentChanged() {
-  if (m_bNotify && m_pNotify) {
-    CPDF_Rect rcContent = m_pVT->GetContentRect();
-    if (rcContent.Width() != m_rcOldContent.Width() ||
-        rcContent.Height() != m_rcOldContent.Height()) {
-      if (!m_bNotifyFlag) {
-        m_bNotifyFlag = TRUE;
-        m_pNotify->IOnContentChange(rcContent);
-        m_bNotifyFlag = FALSE;
-      }
-      m_rcOldContent = rcContent;
-    }
-  }
-}
-
-void CFX_Edit::SelectAll() {
-  if (m_pVT->IsValid()) {
-    m_SelState = CFX_Edit_Select(GetWholeWordRange());
-    SetCaret(m_SelState.EndPos);
-
-    ScrollToCaret();
-    CPVT_WordRange wrVisible = GetVisibleWordRange();
-    Refresh(RP_OPTIONAL, &wrVisible);
-    SetCaretInfo();
-  }
-}
-
-void CFX_Edit::SelectNone() {
-  if (m_pVT->IsValid()) {
-    if (m_SelState.IsExist()) {
-      CPVT_WordRange wrTemp = m_SelState.ConvertToWordRange();
-      m_SelState.Default();
-      Refresh(RP_OPTIONAL, &wrTemp);
-    }
-  }
-}
-
-FX_BOOL CFX_Edit::IsSelected() const {
-  return m_SelState.IsExist();
-}
-
-CPDF_Point CFX_Edit::VTToEdit(const CPDF_Point& point) const {
-  CPDF_Rect rcContent = m_pVT->GetContentRect();
-  CPDF_Rect rcPlate = m_pVT->GetPlateRect();
-
-  FX_FLOAT fPadding = 0.0f;
-
-  switch (m_nAlignment) {
-    case 0:
-      fPadding = 0.0f;
-      break;
-    case 1:
-      fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f;
-      break;
-    case 2:
-      fPadding = rcPlate.Height() - rcContent.Height();
-      break;
-  }
-
-  return CPDF_Point(point.x - (m_ptScrollPos.x - rcPlate.left),
-                    point.y - (m_ptScrollPos.y + fPadding - rcPlate.top));
-}
-
-CPDF_Point CFX_Edit::EditToVT(const CPDF_Point& point) const {
-  CPDF_Rect rcContent = m_pVT->GetContentRect();
-  CPDF_Rect rcPlate = m_pVT->GetPlateRect();
-
-  FX_FLOAT fPadding = 0.0f;
-
-  switch (m_nAlignment) {
-    case 0:
-      fPadding = 0.0f;
-      break;
-    case 1:
-      fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f;
-      break;
-    case 2:
-      fPadding = rcPlate.Height() - rcContent.Height();
-      break;
-  }
-
-  return CPDF_Point(point.x + (m_ptScrollPos.x - rcPlate.left),
-                    point.y + (m_ptScrollPos.y + fPadding - rcPlate.top));
-}
-
-CPDF_Rect CFX_Edit::VTToEdit(const CPDF_Rect& rect) const {
-  CPDF_Point ptLeftBottom = VTToEdit(CPDF_Point(rect.left, rect.bottom));
-  CPDF_Point ptRightTop = VTToEdit(CPDF_Point(rect.right, rect.top));
-
-  return CPDF_Rect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x, ptRightTop.y);
-}
-
-CPDF_Rect CFX_Edit::EditToVT(const CPDF_Rect& rect) const {
-  CPDF_Point ptLeftBottom = EditToVT(CPDF_Point(rect.left, rect.bottom));
-  CPDF_Point ptRightTop = EditToVT(CPDF_Point(rect.right, rect.top));
-
-  return CPDF_Rect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x, ptRightTop.y);
-}
-
-void CFX_Edit::SetScrollInfo() {
-  if (m_bNotify && m_pNotify) {
-    CPDF_Rect rcPlate = m_pVT->GetPlateRect();
-    CPDF_Rect rcContent = m_pVT->GetContentRect();
-
-    if (!m_bNotifyFlag) {
-      m_bNotifyFlag = TRUE;
-      m_pNotify->IOnSetScrollInfoX(rcPlate.left, rcPlate.right, rcContent.left,
-                                   rcContent.right, rcPlate.Width() / 3,
-                                   rcPlate.Width());
-
-      m_pNotify->IOnSetScrollInfoY(rcPlate.bottom, rcPlate.top,
-                                   rcContent.bottom, rcContent.top,
-                                   rcPlate.Height() / 3, rcPlate.Height());
-      m_bNotifyFlag = FALSE;
-    }
-  }
-}
-
-void CFX_Edit::SetScrollPosX(FX_FLOAT fx) {
-  if (!m_bEnableScroll)
-    return;
-
-  if (m_pVT->IsValid()) {
-    if (!FX_EDIT_IsFloatEqual(m_ptScrollPos.x, fx)) {
-      m_ptScrollPos.x = fx;
-      Refresh(RP_NOANALYSE);
-
-      if (m_bNotify && m_pNotify) {
-        if (!m_bNotifyFlag) {
-          m_bNotifyFlag = TRUE;
-          m_pNotify->IOnSetScrollPosX(fx);
-          m_bNotifyFlag = FALSE;
-        }
-      }
-    }
-  }
-}
-
-void CFX_Edit::SetScrollPosY(FX_FLOAT fy) {
-  if (!m_bEnableScroll)
-    return;
-
-  if (m_pVT->IsValid()) {
-    if (!FX_EDIT_IsFloatEqual(m_ptScrollPos.y, fy)) {
-      m_ptScrollPos.y = fy;
-      Refresh(RP_NOANALYSE);
-
-      if (m_bNotify && m_pNotify) {
-        if (!m_bNotifyFlag) {
-          m_bNotifyFlag = TRUE;
-          m_pNotify->IOnSetScrollPosY(fy);
-          m_bNotifyFlag = FALSE;
-        }
-      }
-    }
-  }
-}
-
-void CFX_Edit::SetScrollPos(const CPDF_Point& point) {
-  SetScrollPosX(point.x);
-  SetScrollPosY(point.y);
-  SetScrollLimit();
-  SetCaretInfo();
-}
-
-CPDF_Point CFX_Edit::GetScrollPos() const {
-  return m_ptScrollPos;
-}
-
-void CFX_Edit::SetScrollLimit() {
-  if (m_pVT->IsValid()) {
-    CPDF_Rect rcContent = m_pVT->GetContentRect();
-    CPDF_Rect rcPlate = m_pVT->GetPlateRect();
-
-    if (rcPlate.Width() > rcContent.Width()) {
-      SetScrollPosX(rcPlate.left);
-    } else {
-      if (FX_EDIT_IsFloatSmaller(m_ptScrollPos.x, rcContent.left)) {
-        SetScrollPosX(rcContent.left);
-      } else if (FX_EDIT_IsFloatBigger(m_ptScrollPos.x,
-                                       rcContent.right - rcPlate.Width())) {
-        SetScrollPosX(rcContent.right - rcPlate.Width());
-      }
-    }
-
-    if (rcPlate.Height() > rcContent.Height()) {
-      SetScrollPosY(rcPlate.top);
-    } else {
-      if (FX_EDIT_IsFloatSmaller(m_ptScrollPos.y,
-                                 rcContent.bottom + rcPlate.Height())) {
-        SetScrollPosY(rcContent.bottom + rcPlate.Height());
-      } else if (FX_EDIT_IsFloatBigger(m_ptScrollPos.y, rcContent.top)) {
-        SetScrollPosY(rcContent.top);
-      }
-    }
-  }
-}
-
-void CFX_Edit::ScrollToCaret() {
-  SetScrollLimit();
-
-  if (m_pVT->IsValid()) {
-    CPDF_Point ptHead(0, 0);
-    CPDF_Point ptFoot(0, 0);
-
-    if (IPDF_VariableText_Iterator* pIterator = m_pVT->GetIterator()) {
-      pIterator->SetAt(m_wpCaret);
-
-      CPVT_Word word;
-      CPVT_Line line;
-      if (pIterator->GetWord(word)) {
-        ptHead.x = word.ptWord.x + word.fWidth;
-        ptHead.y = word.ptWord.y + word.fAscent;
-        ptFoot.x = word.ptWord.x + word.fWidth;
-        ptFoot.y = word.ptWord.y + word.fDescent;
-      } else if (pIterator->GetLine(line)) {
-        ptHead.x = line.ptLine.x;
-        ptHead.y = line.ptLine.y + line.fLineAscent;
-        ptFoot.x = line.ptLine.x;
-        ptFoot.y = line.ptLine.y + line.fLineDescent;
-      }
-    }
-
-    CPDF_Point ptHeadEdit = VTToEdit(ptHead);
-    CPDF_Point ptFootEdit = VTToEdit(ptFoot);
-
-    CPDF_Rect rcPlate = m_pVT->GetPlateRect();
-
-    if (!FX_EDIT_IsFloatEqual(rcPlate.left, rcPlate.right)) {
-      if (FX_EDIT_IsFloatSmaller(ptHeadEdit.x, rcPlate.left) ||
-          FX_EDIT_IsFloatEqual(ptHeadEdit.x, rcPlate.left)) {
-        SetScrollPosX(ptHead.x);
-      } else if (FX_EDIT_IsFloatBigger(ptHeadEdit.x, rcPlate.right)) {
-        SetScrollPosX(ptHead.x - rcPlate.Width());
-      }
-    }
-
-    if (!FX_EDIT_IsFloatEqual(rcPlate.top, rcPlate.bottom)) {
-      if (FX_EDIT_IsFloatSmaller(ptFootEdit.y, rcPlate.bottom) ||
-          FX_EDIT_IsFloatEqual(ptFootEdit.y, rcPlate.bottom)) {
-        if (FX_EDIT_IsFloatSmaller(ptHeadEdit.y, rcPlate.top)) {
-          SetScrollPosY(ptFoot.y + rcPlate.Height());
-        }
-      } else if (FX_EDIT_IsFloatBigger(ptHeadEdit.y, rcPlate.top)) {
-        if (FX_EDIT_IsFloatBigger(ptFootEdit.y, rcPlate.bottom)) {
-          SetScrollPosY(ptHead.y);
-        }
-      }
-    }
-  }
-}
-
-void CFX_Edit::Refresh(REFRESH_PLAN_E ePlan,
-                       const CPVT_WordRange* pRange1,
-                       const CPVT_WordRange* pRange2) {
-  if (m_bEnableRefresh && m_pVT->IsValid()) {
-    m_Refresh.BeginRefresh();
-    RefreshPushLineRects(GetVisibleWordRange());
-
-    m_Refresh.NoAnalyse();
-    m_ptRefreshScrollPos = m_ptScrollPos;
-
-    if (m_bNotify && m_pNotify) {
-      if (!m_bNotifyFlag) {
-        m_bNotifyFlag = TRUE;
-        if (const CFX_Edit_RectArray* pRects = m_Refresh.GetRefreshRects()) {
-          for (int32_t i = 0, sz = pRects->GetSize(); i < sz; i++)
-            m_pNotify->IOnInvalidateRect(pRects->GetAt(i));
-        }
-        m_bNotifyFlag = FALSE;
-      }
-    }
-
-    m_Refresh.EndRefresh();
-  }
-}
-
-void CFX_Edit::RefreshPushLineRects(const CPVT_WordRange& wr) {
-  if (m_pVT->IsValid()) {
-    if (IPDF_VariableText_Iterator* pIterator = m_pVT->GetIterator()) {
-      CPVT_WordPlace wpBegin = wr.BeginPos;
-      m_pVT->UpdateWordPlace(wpBegin);
-      CPVT_WordPlace wpEnd = wr.EndPos;
-      m_pVT->UpdateWordPlace(wpEnd);
-      pIterator->SetAt(wpBegin);
-
-      CPVT_Line lineinfo;
-      do {
-        if (!pIterator->GetLine(lineinfo))
-          break;
-        if (lineinfo.lineplace.LineCmp(wpEnd) > 0)
-          break;
-
-        CPDF_Rect rcLine(lineinfo.ptLine.x,
-                         lineinfo.ptLine.y + lineinfo.fLineDescent,
-                         lineinfo.ptLine.x + lineinfo.fLineWidth,
-                         lineinfo.ptLine.y + lineinfo.fLineAscent);
-
-        m_Refresh.Push(CPVT_WordRange(lineinfo.lineplace, lineinfo.lineEnd),
-                       VTToEdit(rcLine));
-      } while (pIterator->NextLine());
-    }
-  }
-}
-
-void CFX_Edit::RefreshPushRandomRects(const CPVT_WordRange& wr) {
-  if (m_pVT->IsValid()) {
-    if (IPDF_VariableText_Iterator* pIterator = m_pVT->GetIterator()) {
-      CPVT_WordRange wrTemp = wr;
-
-      m_pVT->UpdateWordPlace(wrTemp.BeginPos);
-      m_pVT->UpdateWordPlace(wrTemp.EndPos);
-      pIterator->SetAt(wrTemp.BeginPos);
-
-      CPVT_Word wordinfo;
-      CPVT_Line lineinfo;
-      CPVT_WordPlace place;
-
-      while (pIterator->NextWord()) {
-        place = pIterator->GetAt();
-        if (place.WordCmp(wrTemp.EndPos) > 0)
-          break;
-
-        pIterator->GetWord(wordinfo);
-        pIterator->GetLine(lineinfo);
-
-        if (place.LineCmp(wrTemp.BeginPos) == 0 ||
-            place.LineCmp(wrTemp.EndPos) == 0) {
-          CPDF_Rect rcWord(wordinfo.ptWord.x,
-                           lineinfo.ptLine.y + lineinfo.fLineDescent,
-                           wordinfo.ptWord.x + wordinfo.fWidth,
-                           lineinfo.ptLine.y + lineinfo.fLineAscent);
-
-          m_Refresh.AddRefresh(VTToEdit(rcWord));
-        } else {
-          CPDF_Rect rcLine(lineinfo.ptLine.x,
-                           lineinfo.ptLine.y + lineinfo.fLineDescent,
-                           lineinfo.ptLine.x + lineinfo.fLineWidth,
-                           lineinfo.ptLine.y + lineinfo.fLineAscent);
-
-          m_Refresh.AddRefresh(VTToEdit(rcLine));
-
-          pIterator->NextLine();
-        }
-      }
-    }
-  }
-}
-
-void CFX_Edit::RefreshWordRange(const CPVT_WordRange& wr) {
-  if (IPDF_VariableText_Iterator* pIterator = m_pVT->GetIterator()) {
-    CPVT_WordRange wrTemp = wr;
-
-    m_pVT->UpdateWordPlace(wrTemp.BeginPos);
-    m_pVT->UpdateWordPlace(wrTemp.EndPos);
-    pIterator->SetAt(wrTemp.BeginPos);
-
-    CPVT_Word wordinfo;
-    CPVT_Line lineinfo;
-    CPVT_WordPlace place;
-
-    while (pIterator->NextWord()) {
-      place = pIterator->GetAt();
-      if (place.WordCmp(wrTemp.EndPos) > 0)
-        break;
-
-      pIterator->GetWord(wordinfo);
-      pIterator->GetLine(lineinfo);
-
-      if (place.LineCmp(wrTemp.BeginPos) == 0 ||
-          place.LineCmp(wrTemp.EndPos) == 0) {
-        CPDF_Rect rcWord(wordinfo.ptWord.x,
-                         lineinfo.ptLine.y + lineinfo.fLineDescent,
-                         wordinfo.ptWord.x + wordinfo.fWidth,
-                         lineinfo.ptLine.y + lineinfo.fLineAscent);
-
-        if (m_bNotify && m_pNotify) {
-          if (!m_bNotifyFlag) {
-            m_bNotifyFlag = TRUE;
-            CPDF_Rect rcRefresh = VTToEdit(rcWord);
-            m_pNotify->IOnInvalidateRect(&rcRefresh);
-            m_bNotifyFlag = FALSE;
-          }
-        }
-      } else {
-        CPDF_Rect rcLine(lineinfo.ptLine.x,
-                         lineinfo.ptLine.y + lineinfo.fLineDescent,
-                         lineinfo.ptLine.x + lineinfo.fLineWidth,
-                         lineinfo.ptLine.y + lineinfo.fLineAscent);
-
-        if (m_bNotify && m_pNotify) {
-          if (!m_bNotifyFlag) {
-            m_bNotifyFlag = TRUE;
-            CPDF_Rect rcRefresh = VTToEdit(rcLine);
-            m_pNotify->IOnInvalidateRect(&rcRefresh);
-            m_bNotifyFlag = FALSE;
-          }
-        }
-
-        pIterator->NextLine();
-      }
-    }
-  }
-}
-
-void CFX_Edit::SetCaret(const CPVT_WordPlace& place) {
-  m_wpOldCaret = m_wpCaret;
-  m_wpCaret = place;
-}
-
-void CFX_Edit::SetCaretInfo() {
-  if (m_bNotify && m_pNotify) {
-    if (!m_bNotifyFlag) {
-      CPDF_Point ptHead(0.0f, 0.0f), ptFoot(0.0f, 0.0f);
-
-      if (IPDF_VariableText_Iterator* pIterator = m_pVT->GetIterator()) {
-        pIterator->SetAt(m_wpCaret);
-        CPVT_Word word;
-        CPVT_Line line;
-        if (pIterator->GetWord(word)) {
-          ptHead.x = word.ptWord.x + word.fWidth;
-          ptHead.y = word.ptWord.y + word.fAscent;
-          ptFoot.x = word.ptWord.x + word.fWidth;
-          ptFoot.y = word.ptWord.y + word.fDescent;
-        } else if (pIterator->GetLine(line)) {
-          ptHead.x = line.ptLine.x;
-          ptHead.y = line.ptLine.y + line.fLineAscent;
-          ptFoot.x = line.ptLine.x;
-          ptFoot.y = line.ptLine.y + line.fLineDescent;
-        }
-      }
-
-      m_bNotifyFlag = TRUE;
-      m_pNotify->IOnSetCaret(!m_SelState.IsExist(), VTToEdit(ptHead),
-                             VTToEdit(ptFoot), m_wpCaret);
-      m_bNotifyFlag = FALSE;
-    }
-  }
-
-  SetCaretChange();
-}
-
-void CFX_Edit::SetCaretChange() {
-  if (m_wpCaret == m_wpOldCaret)
-    return;
-
-  if (m_bNotify && m_pVT->IsRichText() && m_pNotify) {
-    CPVT_SecProps SecProps;
-    CPVT_WordProps WordProps;
-
-    if (IPDF_VariableText_Iterator* pIterator = m_pVT->GetIterator()) {
-      pIterator->SetAt(m_wpCaret);
-      CPVT_Word word;
-      CPVT_Section section;
-
-      if (pIterator->GetSection(section)) {
-        SecProps = section.SecProps;
-        WordProps = section.WordProps;
-      }
-
-      if (pIterator->GetWord(word)) {
-        WordProps = word.WordProps;
-      }
-    }
-
-    if (!m_bNotifyFlag) {
-      m_bNotifyFlag = TRUE;
-      m_pNotify->IOnCaretChange(SecProps, WordProps);
-      m_bNotifyFlag = FALSE;
-    }
-  }
-}
-
-void CFX_Edit::SetCaret(int32_t nPos) {
-  if (m_pVT->IsValid()) {
-    SelectNone();
-    SetCaret(m_pVT->WordIndexToWordPlace(nPos));
-    m_SelState.Set(m_wpCaret, m_wpCaret);
-
-    ScrollToCaret();
-    SetCaretOrigin();
-    SetCaretInfo();
-  }
-}
-
-void CFX_Edit::OnMouseDown(const CPDF_Point& point,
-                           FX_BOOL bShift,
-                           FX_BOOL bCtrl) {
-  if (m_pVT->IsValid()) {
-    SelectNone();
-    SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
-    m_SelState.Set(m_wpCaret, m_wpCaret);
-
-    ScrollToCaret();
-    SetCaretOrigin();
-    SetCaretInfo();
-  }
-}
-
-void CFX_Edit::OnMouseMove(const CPDF_Point& point,
-                           FX_BOOL bShift,
-                           FX_BOOL bCtrl) {
-  if (m_pVT->IsValid()) {
-    SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
-
-    if (m_wpCaret != m_wpOldCaret) {
-      m_SelState.SetEndPos(m_wpCaret);
-
-      ScrollToCaret();
-      CPVT_WordRange wr(m_wpOldCaret, m_wpCaret);
-      Refresh(RP_OPTIONAL, &wr);
-      SetCaretOrigin();
-      SetCaretInfo();
-    }
-  }
-}
-
-void CFX_Edit::OnVK_UP(FX_BOOL bShift, FX_BOOL bCtrl) {
-  if (m_pVT->IsValid()) {
-    SetCaret(m_pVT->GetUpWordPlace(m_wpCaret, m_ptCaret));
-
-    if (bShift) {
-      if (m_SelState.IsExist())
-        m_SelState.SetEndPos(m_wpCaret);
-      else
-        m_SelState.Set(m_wpOldCaret, m_wpCaret);
-
-      if (m_wpOldCaret != m_wpCaret) {
-        ScrollToCaret();
-        CPVT_WordRange wr(m_wpOldCaret, m_wpCaret);
-        Refresh(RP_OPTIONAL, &wr);
-        SetCaretInfo();
-      }
-    } else {
-      SelectNone();
-
-      ScrollToCaret();
-      SetCaretInfo();
-    }
-  }
-}
-
-void CFX_Edit::OnVK_DOWN(FX_BOOL bShift, FX_BOOL bCtrl) {
-  if (m_pVT->IsValid()) {
-    SetCaret(m_pVT->GetDownWordPlace(m_wpCaret, m_ptCaret));
-
-    if (bShift) {
-      if (m_SelState.IsExist())
-        m_SelState.SetEndPos(m_wpCaret);
-      else
-        m_SelState.Set(m_wpOldCaret, m_wpCaret);
-
-      if (m_wpOldCaret != m_wpCaret) {
-        ScrollToCaret();
-        CPVT_WordRange wr(m_wpOldCaret, m_wpCaret);
-        Refresh(RP_OPTIONAL, &wr);
-        SetCaretInfo();
-      }
-    } else {
-      SelectNone();
-
-      ScrollToCaret();
-      SetCaretInfo();
-    }
-  }
-}
-
-void CFX_Edit::OnVK_LEFT(FX_BOOL bShift, FX_BOOL bCtrl) {
-  if (m_pVT->IsValid()) {
-    if (bShift) {
-      if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
-          m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret))
-        SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
-
-      SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
-
-      if (m_SelState.IsExist())
-        m_SelState.SetEndPos(m_wpCaret);
-      else
-        m_SelState.Set(m_wpOldCaret, m_wpCaret);
-
-      if (m_wpOldCaret != m_wpCaret) {
-        ScrollToCaret();
-        CPVT_WordRange wr(m_wpOldCaret, m_wpCaret);
-        Refresh(RP_OPTIONAL, &wr);
-        SetCaretInfo();
-      }
-    } else {
-      if (m_SelState.IsExist()) {
-        if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos) < 0)
-          SetCaret(m_SelState.BeginPos);
-        else
-          SetCaret(m_SelState.EndPos);
-
-        SelectNone();
-        ScrollToCaret();
-        SetCaretInfo();
-      } else {
-        if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
-            m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret))
-          SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
-
-        SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
-
-        ScrollToCaret();
-        SetCaretOrigin();
-        SetCaretInfo();
-      }
-    }
-  }
-}
-
-void CFX_Edit::OnVK_RIGHT(FX_BOOL bShift, FX_BOOL bCtrl) {
-  if (m_pVT->IsValid()) {
-    if (bShift) {
-      SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
-
-      if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
-          m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret))
-        SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
-
-      if (m_SelState.IsExist())
-        m_SelState.SetEndPos(m_wpCaret);
-      else
-        m_SelState.Set(m_wpOldCaret, m_wpCaret);
-
-      if (m_wpOldCaret != m_wpCaret) {
-        ScrollToCaret();
-        CPVT_WordRange wr(m_wpOldCaret, m_wpCaret);
-        Refresh(RP_OPTIONAL, &wr);
-        SetCaretInfo();
-      }
-    } else {
-      if (m_SelState.IsExist()) {
-        if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos) > 0)
-          SetCaret(m_SelState.BeginPos);
-        else
-          SetCaret(m_SelState.EndPos);
-
-        SelectNone();
-        ScrollToCaret();
-        SetCaretInfo();
-      } else {
-        SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
-
-        if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
-            m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret))
-          SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
-
-        ScrollToCaret();
-        SetCaretOrigin();
-        SetCaretInfo();
-      }
-    }
-  }
-}
-
-void CFX_Edit::OnVK_HOME(FX_BOOL bShift, FX_BOOL bCtrl) {
-  if (m_pVT->IsValid()) {
-    if (bShift) {
-      if (bCtrl)
-        SetCaret(m_pVT->GetBeginWordPlace());
-      else
-        SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));
-
-      if (m_SelState.IsExist())
-        m_SelState.SetEndPos(m_wpCaret);
-      else
-        m_SelState.Set(m_wpOldCaret, m_wpCaret);
-
-      ScrollToCaret();
-      CPVT_WordRange wr(m_wpOldCaret, m_wpCaret);
-      Refresh(RP_OPTIONAL, &wr);
-      SetCaretInfo();
-    } else {
-      if (m_SelState.IsExist()) {
-        if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos) < 0)
-          SetCaret(m_SelState.BeginPos);
-        else
-          SetCaret(m_SelState.EndPos);
-
-        SelectNone();
-        ScrollToCaret();
-        SetCaretInfo();
-      } else {
-        if (bCtrl)
-          SetCaret(m_pVT->GetBeginWordPlace());
-        else
-          SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));
-
-        ScrollToCaret();
-        SetCaretOrigin();
-        SetCaretInfo();
-      }
-    }
-  }
-}
-
-void CFX_Edit::OnVK_END(FX_BOOL bShift, FX_BOOL bCtrl) {
-  if (m_pVT->IsValid()) {
-    if (bShift) {
-      if (bCtrl)
-        SetCaret(m_pVT->GetEndWordPlace());
-      else
-        SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));
-
-      if (m_SelState.IsExist())
-        m_SelState.SetEndPos(m_wpCaret);
-      else
-        m_SelState.Set(m_wpOldCaret, m_wpCaret);
-
-      ScrollToCaret();
-      CPVT_WordRange wr(m_wpOldCaret, m_wpCaret);
-      Refresh(RP_OPTIONAL, &wr);
-      SetCaretInfo();
-    } else {
-      if (m_SelState.IsExist()) {
-        if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos) > 0)
-          SetCaret(m_SelState.BeginPos);
-        else
-          SetCaret(m_SelState.EndPos);
-
-        SelectNone();
-        ScrollToCaret();
-        SetCaretInfo();
-      } else {
-        if (bCtrl)
-          SetCaret(m_pVT->GetEndWordPlace());
-        else
-          SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));
-
-        ScrollToCaret();
-        SetCaretOrigin();
-        SetCaretInfo();
-      }
-    }
-  }
-}
-
-void CFX_Edit::SetText(const FX_WCHAR* text,
-                       int32_t charset,
-                       const CPVT_SecProps* pSecProps,
-                       const CPVT_WordProps* pWordProps,
-                       FX_BOOL bAddUndo,
-                       FX_BOOL bPaint) {
-  Empty();
-  DoInsertText(CPVT_WordPlace(0, 0, -1), text, charset, pSecProps, pWordProps);
-  if (bPaint)
-    Paint();
-  if (m_bOprNotify && m_pOprNotify)
-    m_pOprNotify->OnSetText(m_wpCaret, m_wpOldCaret);
-}
-
-FX_BOOL CFX_Edit::InsertWord(FX_WORD word,
-                             int32_t charset,
-                             const CPVT_WordProps* pWordProps,
-                             FX_BOOL bAddUndo,
-                             FX_BOOL bPaint) {
-  if (IsTextOverflow())
-    return FALSE;
-
-  if (m_pVT->IsValid()) {
-    m_pVT->UpdateWordPlace(m_wpCaret);
-
-    SetCaret(m_pVT->InsertWord(
-        m_wpCaret, word, GetCharSetFromUnicode(word, charset), pWordProps));
-    m_SelState.Set(m_wpCaret, m_wpCaret);
-
-    if (m_wpCaret != m_wpOldCaret) {
-      if (bAddUndo && m_bEnableUndo) {
-        AddEditUndoItem(new CFXEU_InsertWord(this, m_wpOldCaret, m_wpCaret,
-                                             word, charset, pWordProps));
-      }
-
-      if (bPaint)
-        PaintInsertText(m_wpOldCaret, m_wpCaret);
-
-      if (m_bOprNotify && m_pOprNotify)
-        m_pOprNotify->OnInsertWord(m_wpCaret, m_wpOldCaret);
-
-      return TRUE;
-    }
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CFX_Edit::InsertReturn(const CPVT_SecProps* pSecProps,
-                               const CPVT_WordProps* pWordProps,
-                               FX_BOOL bAddUndo,
-                               FX_BOOL bPaint) {
-  if (IsTextOverflow())
-    return FALSE;
-
-  if (m_pVT->IsValid()) {
-    m_pVT->UpdateWordPlace(m_wpCaret);
-    SetCaret(m_pVT->InsertSection(m_wpCaret, pSecProps, pWordProps));
-    m_SelState.Set(m_wpCaret, m_wpCaret);
-
-    if (m_wpCaret != m_wpOldCaret) {
-      if (bAddUndo && m_bEnableUndo) {
-        AddEditUndoItem(new CFXEU_InsertReturn(this, m_wpOldCaret, m_wpCaret,
-                                               pSecProps, pWordProps));
-      }
-
-      if (bPaint) {
-        RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret));
-        ScrollToCaret();
-        CPVT_WordRange wr(m_wpOldCaret, GetVisibleWordRange().EndPos);
-        Refresh(RP_ANALYSE, &wr);
-        SetCaretOrigin();
-        SetCaretInfo();
-      }
-
-      if (m_bOprNotify && m_pOprNotify)
-        m_pOprNotify->OnInsertReturn(m_wpCaret, m_wpOldCaret);
-
-      return TRUE;
-    }
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CFX_Edit::Backspace(FX_BOOL bAddUndo, FX_BOOL bPaint) {
-  if (m_pVT->IsValid()) {
-    if (m_wpCaret == m_pVT->GetBeginWordPlace())
-      return FALSE;
-
-    CPVT_Section section;
-    CPVT_Word word;
-
-    if (bAddUndo) {
-      if (IPDF_VariableText_Iterator* pIterator = m_pVT->GetIterator()) {
-        pIterator->SetAt(m_wpCaret);
-        pIterator->GetSection(section);
-        pIterator->GetWord(word);
-      }
-    }
-
-    m_pVT->UpdateWordPlace(m_wpCaret);
-    SetCaret(m_pVT->BackSpaceWord(m_wpCaret));
-    m_SelState.Set(m_wpCaret, m_wpCaret);
-
-    if (m_wpCaret != m_wpOldCaret) {
-      if (bAddUndo && m_bEnableUndo) {
-        if (m_wpCaret.SecCmp(m_wpOldCaret) != 0)
-          AddEditUndoItem(new CFXEU_Backspace(
-              this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
-              section.SecProps, section.WordProps));
-        else
-          AddEditUndoItem(new CFXEU_Backspace(
-              this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
-              section.SecProps, word.WordProps));
-      }
-
-      if (bPaint) {
-        RearrangePart(CPVT_WordRange(m_wpCaret, m_wpOldCaret));
-        ScrollToCaret();
-
-        CPVT_WordRange wr;
-        if (m_wpCaret.SecCmp(m_wpOldCaret) != 0)
-          wr = CPVT_WordRange(m_pVT->GetPrevWordPlace(m_wpCaret),
-                              GetVisibleWordRange().EndPos);
-        else if (m_wpCaret.LineCmp(m_wpOldCaret) != 0)
-          wr = CPVT_WordRange(m_pVT->GetLineBeginPlace(m_wpCaret),
-                              m_pVT->GetSectionEndPlace(m_wpCaret));
-        else
-          wr = CPVT_WordRange(m_pVT->GetPrevWordPlace(m_wpCaret),
-                              m_pVT->GetSectionEndPlace(m_wpCaret));
-
-        Refresh(RP_ANALYSE, &wr);
-
-        SetCaretOrigin();
-        SetCaretInfo();
-      }
-
-      if (m_bOprNotify && m_pOprNotify)
-        m_pOprNotify->OnBackSpace(m_wpCaret, m_wpOldCaret);
-
-      return TRUE;
-    }
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CFX_Edit::Delete(FX_BOOL bAddUndo, FX_BOOL bPaint) {
-  if (m_pVT->IsValid()) {
-    if (m_wpCaret == m_pVT->GetEndWordPlace())
-      return FALSE;
-
-    CPVT_Section section;
-    CPVT_Word word;
-
-    if (bAddUndo) {
-      if (IPDF_VariableText_Iterator* pIterator = m_pVT->GetIterator()) {
-        pIterator->SetAt(m_pVT->GetNextWordPlace(m_wpCaret));
-        pIterator->GetSection(section);
-        pIterator->GetWord(word);
-      }
-    }
-
-    m_pVT->UpdateWordPlace(m_wpCaret);
-    FX_BOOL bSecEnd = (m_wpCaret == m_pVT->GetSectionEndPlace(m_wpCaret));
-
-    SetCaret(m_pVT->DeleteWord(m_wpCaret));
-    m_SelState.Set(m_wpCaret, m_wpCaret);
-
-    if (bAddUndo && m_bEnableUndo) {
-      if (bSecEnd)
-        AddEditUndoItem(new CFXEU_Delete(
-            this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
-            section.SecProps, section.WordProps, bSecEnd));
-      else
-        AddEditUndoItem(new CFXEU_Delete(
-            this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
-            section.SecProps, word.WordProps, bSecEnd));
-    }
-
-    if (bPaint) {
-      RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret));
-      ScrollToCaret();
-
-      CPVT_WordRange wr;
-      if (bSecEnd)
-        wr = CPVT_WordRange(m_pVT->GetPrevWordPlace(m_wpOldCaret),
-                            GetVisibleWordRange().EndPos);
-      else if (m_wpCaret.LineCmp(m_wpOldCaret) != 0)
-        wr = CPVT_WordRange(m_pVT->GetLineBeginPlace(m_wpCaret),
-                            m_pVT->GetSectionEndPlace(m_wpCaret));
-      else
-        wr = CPVT_WordRange(m_pVT->GetPrevWordPlace(m_wpOldCaret),
-                            m_pVT->GetSectionEndPlace(m_wpCaret));
-
-      Refresh(RP_ANALYSE, &wr);
-
-      SetCaretOrigin();
-      SetCaretInfo();
-    }
-
-    if (m_bOprNotify && m_pOprNotify)
-      m_pOprNotify->OnDelete(m_wpCaret, m_wpOldCaret);
-
-    return TRUE;
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CFX_Edit::Empty() {
-  if (m_pVT->IsValid()) {
-    m_pVT->DeleteWords(GetWholeWordRange());
-    SetCaret(m_pVT->GetBeginWordPlace());
-
-    return TRUE;
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CFX_Edit::Clear(FX_BOOL bAddUndo, FX_BOOL bPaint) {
-  if (m_pVT->IsValid()) {
-    if (m_SelState.IsExist()) {
-      CPVT_WordRange range = m_SelState.ConvertToWordRange();
-
-      if (bAddUndo && m_bEnableUndo) {
-        if (m_pVT->IsRichText()) {
-          BeginGroupUndo(L"");
-
-          if (IPDF_VariableText_Iterator* pIterator = m_pVT->GetIterator()) {
-            pIterator->SetAt(range.EndPos);
-
-            CPVT_Word wordinfo;
-            CPVT_Section secinfo;
-            do {
-              CPVT_WordPlace place = pIterator->GetAt();
-              if (place.WordCmp(range.BeginPos) <= 0)
-                break;
-
-              CPVT_WordPlace oldplace = m_pVT->GetPrevWordPlace(place);
-
-              if (oldplace.SecCmp(place) != 0) {
-                if (pIterator->GetSection(secinfo)) {
-                  AddEditUndoItem(new CFXEU_ClearRich(
-                      this, oldplace, place, range, wordinfo.Word,
-                      wordinfo.nCharset, secinfo.SecProps, secinfo.WordProps));
-                }
-              } else {
-                if (pIterator->GetWord(wordinfo)) {
-                  oldplace = m_pVT->AdjustLineHeader(oldplace, TRUE);
-                  place = m_pVT->AdjustLineHeader(place, TRUE);
-
-                  AddEditUndoItem(new CFXEU_ClearRich(
-                      this, oldplace, place, range, wordinfo.Word,
-                      wordinfo.nCharset, secinfo.SecProps, wordinfo.WordProps));
-                }
-              }
-            } while (pIterator->PrevWord());
-          }
-          EndGroupUndo();
-        } else {
-          AddEditUndoItem(new CFXEU_Clear(this, range, GetSelText()));
-        }
-      }
-
-      SelectNone();
-      SetCaret(m_pVT->DeleteWords(range));
-      m_SelState.Set(m_wpCaret, m_wpCaret);
-
-      if (bPaint) {
-        RearrangePart(range);
-        ScrollToCaret();
-
-        CPVT_WordRange wr(m_wpOldCaret, GetVisibleWordRange().EndPos);
-        Refresh(RP_ANALYSE, &wr);
-
-        SetCaretOrigin();
-        SetCaretInfo();
-      }
-
-      if (m_bOprNotify && m_pOprNotify)
-        m_pOprNotify->OnClear(m_wpCaret, m_wpOldCaret);
-
-      return TRUE;
-    }
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CFX_Edit::InsertText(const FX_WCHAR* text,
-                             int32_t charset,
-                             const CPVT_SecProps* pSecProps,
-                             const CPVT_WordProps* pWordProps,
-                             FX_BOOL bAddUndo,
-                             FX_BOOL bPaint) {
-  if (IsTextOverflow())
-    return FALSE;
-
-  m_pVT->UpdateWordPlace(m_wpCaret);
-  SetCaret(DoInsertText(m_wpCaret, text, charset, pSecProps, pWordProps));
-  m_SelState.Set(m_wpCaret, m_wpCaret);
-
-  if (m_wpCaret != m_wpOldCaret) {
-    if (bAddUndo && m_bEnableUndo) {
-      AddEditUndoItem(new CFXEU_InsertText(this, m_wpOldCaret, m_wpCaret, text,
-                                           charset, pSecProps, pWordProps));
-    }
-
-    if (bPaint)
-      PaintInsertText(m_wpOldCaret, m_wpCaret);
-
-    if (m_bOprNotify && m_pOprNotify)
-      m_pOprNotify->OnInsertText(m_wpCaret, m_wpOldCaret);
-
-    return TRUE;
-  }
-  return FALSE;
-}
-
-void CFX_Edit::PaintInsertText(const CPVT_WordPlace& wpOld,
-                               const CPVT_WordPlace& wpNew) {
-  if (m_pVT->IsValid()) {
-    RearrangePart(CPVT_WordRange(wpOld, wpNew));
-    ScrollToCaret();
-
-    CPVT_WordRange wr;
-    if (m_wpCaret.LineCmp(wpOld) != 0)
-      wr = CPVT_WordRange(m_pVT->GetLineBeginPlace(wpOld),
-                          m_pVT->GetSectionEndPlace(wpNew));
-    else
-      wr = CPVT_WordRange(wpOld, m_pVT->GetSectionEndPlace(wpNew));
-    Refresh(RP_ANALYSE, &wr);
-    SetCaretOrigin();
-    SetCaretInfo();
-  }
-}
-
-FX_BOOL CFX_Edit::Redo() {
-  if (m_bEnableUndo) {
-    if (m_Undo.CanRedo()) {
-      m_Undo.Redo();
-      return TRUE;
-    }
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CFX_Edit::Undo() {
-  if (m_bEnableUndo) {
-    if (m_Undo.CanUndo()) {
-      m_Undo.Undo();
-      return TRUE;
-    }
-  }
-
-  return FALSE;
-}
-
-void CFX_Edit::SetCaretOrigin() {
-  if (m_pVT->IsValid()) {
-    if (IPDF_VariableText_Iterator* pIterator = m_pVT->GetIterator()) {
-      pIterator->SetAt(m_wpCaret);
-      CPVT_Word word;
-      CPVT_Line line;
-      if (pIterator->GetWord(word)) {
-        m_ptCaret.x = word.ptWord.x + word.fWidth;
-        m_ptCaret.y = word.ptWord.y;
-      } else if (pIterator->GetLine(line)) {
-        m_ptCaret.x = line.ptLine.x;
-        m_ptCaret.y = line.ptLine.y;
-      }
-    }
-  }
-}
-
-int32_t CFX_Edit::WordPlaceToWordIndex(const CPVT_WordPlace& place) const {
-  if (m_pVT->IsValid())
-    return m_pVT->WordPlaceToWordIndex(place);
-
-  return -1;
-}
-
-CPVT_WordPlace CFX_Edit::WordIndexToWordPlace(int32_t index) const {
-  if (m_pVT->IsValid())
-    return m_pVT->WordIndexToWordPlace(index);
-
-  return CPVT_WordPlace();
-}
-
-FX_BOOL CFX_Edit::IsTextFull() const {
-  int32_t nTotalWords = m_pVT->GetTotalWords();
-  int32_t nLimitChar = m_pVT->GetLimitChar();
-  int32_t nCharArray = m_pVT->GetCharArray();
-
-  return IsTextOverflow() || (nLimitChar > 0 && nTotalWords >= nLimitChar) ||
-         (nCharArray > 0 && nTotalWords >= nCharArray);
-}
-
-FX_BOOL CFX_Edit::IsTextOverflow() const {
-  if (!m_bEnableScroll && !m_bEnableOverflow) {
-    CPDF_Rect rcPlate = m_pVT->GetPlateRect();
-    CPDF_Rect rcContent = m_pVT->GetContentRect();
-
-    if (m_pVT->IsMultiLine() && GetTotalLines() > 1) {
-      if (FX_EDIT_IsFloatBigger(rcContent.Height(), rcPlate.Height()))
-        return TRUE;
-    }
-
-    if (FX_EDIT_IsFloatBigger(rcContent.Width(), rcPlate.Width()))
-      return TRUE;
-  }
-
-  return FALSE;
-}
-
-CPVT_WordPlace CFX_Edit::GetLineBeginPlace(const CPVT_WordPlace& place) const {
-  return m_pVT->GetLineBeginPlace(place);
-}
-
-CPVT_WordPlace CFX_Edit::GetLineEndPlace(const CPVT_WordPlace& place) const {
-  return m_pVT->GetLineEndPlace(place);
-}
-
-CPVT_WordPlace CFX_Edit::GetSectionBeginPlace(
-    const CPVT_WordPlace& place) const {
-  return m_pVT->GetSectionBeginPlace(place);
-}
-
-CPVT_WordPlace CFX_Edit::GetSectionEndPlace(const CPVT_WordPlace& place) const {
-  return m_pVT->GetSectionEndPlace(place);
-}
-
-FX_BOOL CFX_Edit::CanUndo() const {
-  if (m_bEnableUndo) {
-    return m_Undo.CanUndo();
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CFX_Edit::CanRedo() const {
-  if (m_bEnableUndo) {
-    return m_Undo.CanRedo();
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CFX_Edit::IsModified() const {
-  if (m_bEnableUndo) {
-    return m_Undo.IsModified();
-  }
-
-  return FALSE;
-}
-
-void CFX_Edit::EnableRefresh(FX_BOOL bRefresh) {
-  m_bEnableRefresh = bRefresh;
-}
-
-void CFX_Edit::EnableUndo(FX_BOOL bUndo) {
-  m_bEnableUndo = bUndo;
-}
-
-void CFX_Edit::EnableNotify(FX_BOOL bNotify) {
-  m_bNotify = bNotify;
-}
-
-void CFX_Edit::EnableOprNotify(FX_BOOL bNotify) {
-  m_bOprNotify = bNotify;
-}
-
-FX_FLOAT CFX_Edit::GetLineTop(const CPVT_WordPlace& place) const {
-  if (IPDF_VariableText_Iterator* pIterator = m_pVT->GetIterator()) {
-    CPVT_WordPlace wpOld = pIterator->GetAt();
-
-    pIterator->SetAt(place);
-    CPVT_Line line;
-    pIterator->GetLine(line);
-
-    pIterator->SetAt(wpOld);
-
-    return line.ptLine.y + line.fLineAscent;
-  }
-
-  return 0.0f;
-}
-
-FX_FLOAT CFX_Edit::GetLineBottom(const CPVT_WordPlace& place) const {
-  if (IPDF_VariableText_Iterator* pIterator = m_pVT->GetIterator()) {
-    CPVT_WordPlace wpOld = pIterator->GetAt();
-
-    pIterator->SetAt(place);
-    CPVT_Line line;
-    pIterator->GetLine(line);
-
-    pIterator->SetAt(wpOld);
-
-    return line.ptLine.y + line.fLineDescent;
-  }
-
-  return 0.0f;
-}
-
-CPVT_WordPlace CFX_Edit::DoInsertText(const CPVT_WordPlace& place,
-                                      const FX_WCHAR* text,
-                                      int32_t charset,
-                                      const CPVT_SecProps* pSecProps,
-                                      const CPVT_WordProps* pWordProps) {
-  CPVT_WordPlace wp = place;
-
-  if (m_pVT->IsValid()) {
-    CFX_WideString sText = text;
-
-    for (int32_t i = 0, sz = sText.GetLength(); i < sz; i++) {
-      FX_WORD word = sText[i];
-      switch (word) {
-        case 0x0D:
-          wp = m_pVT->InsertSection(wp, pSecProps, pWordProps);
-          if (sText[i + 1] == 0x0A)
-            i++;
-          break;
-        case 0x0A:
-          wp = m_pVT->InsertSection(wp, pSecProps, pWordProps);
-          if (sText[i + 1] == 0x0D)
-            i++;
-          break;
-        case 0x09:
-          word = 0x20;
-        default:
-          wp = m_pVT->InsertWord(wp, word, GetCharSetFromUnicode(word, charset),
-                                 pWordProps);
-          break;
-      }
-    }
-  }
-
-  return wp;
-}
-
-int32_t CFX_Edit::GetCharSetFromUnicode(FX_WORD word, int32_t nOldCharset) {
-  if (IFX_Edit_FontMap* pFontMap = GetFontMap())
-    return pFontMap->CharSetFromUnicode(word, nOldCharset);
-  return nOldCharset;
-}
-
-void CFX_Edit::BeginGroupUndo(const CFX_WideString& sTitle) {
-  ASSERT(!m_pGroupUndoItem);
-
-  m_pGroupUndoItem = new CFX_Edit_GroupUndoItem(sTitle);
-}
-
-void CFX_Edit::EndGroupUndo() {
-  m_pGroupUndoItem->UpdateItems();
-  m_Undo.AddItem(m_pGroupUndoItem);
-  if (m_bOprNotify && m_pOprNotify)
-    m_pOprNotify->OnAddUndo(m_pGroupUndoItem);
-  m_pGroupUndoItem = NULL;
-}
-
-void CFX_Edit::AddEditUndoItem(CFX_Edit_UndoItem* pEditUndoItem) {
-  if (m_pGroupUndoItem) {
-    m_pGroupUndoItem->AddUndoItem(pEditUndoItem);
-  } else {
-    m_Undo.AddItem(pEditUndoItem);
-    if (m_bOprNotify && m_pOprNotify)
-      m_pOprNotify->OnAddUndo(pEditUndoItem);
-  }
-}
-
-void CFX_Edit::AddUndoItem(IFX_Edit_UndoItem* pUndoItem) {
-  m_Undo.AddItem(pUndoItem);
-  if (m_bOprNotify && m_pOprNotify)
-    m_pOprNotify->OnAddUndo(pUndoItem);
-}
diff --git a/fpdfsdk/src/fxedit/fxet_module.cpp b/fpdfsdk/src/fxedit/fxet_module.cpp
deleted file mode 100644
index 889b0f8..0000000
--- a/fpdfsdk/src/fxedit/fxet_module.cpp
+++ /dev/null
@@ -1,31 +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
-
-#include "fpdfsdk/include/fxedit/fxet_edit.h"
-#include "fpdfsdk/include/fxedit/fxet_list.h"
-
-IFX_Edit* IFX_Edit::NewEdit() {
-  if (IPDF_VariableText* pVT = IPDF_VariableText::NewVariableText()) {
-    return new CFX_Edit(pVT);
-  }
-
-  return NULL;
-}
-
-void IFX_Edit::DelEdit(IFX_Edit* pEdit) {
-  IPDF_VariableText::DelVariableText(pEdit->GetVariableText());
-
-  delete (CFX_Edit*)pEdit;
-}
-
-IFX_List* IFX_List::NewList() {
-  return new CFX_ListCtrl();
-}
-
-void IFX_List::DelList(IFX_List* pList) {
-  ASSERT(pList);
-  delete (CFX_ListCtrl*)pList;
-}
diff --git a/fpdfsdk/src/fxedit/fxet_pageobjs.cpp b/fpdfsdk/src/fxedit/fxet_pageobjs.cpp
deleted file mode 100644
index 1868767..0000000
--- a/fpdfsdk/src/fxedit/fxet_pageobjs.cpp
+++ /dev/null
@@ -1,658 +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
-
-#include "core/include/fpdfapi/fpdf_pageobj.h"
-#include "core/include/fpdfapi/fpdf_render.h"
-#include "fpdfsdk/include/fx_systemhandler.h"
-#include "fpdfsdk/include/fxedit/fx_edit.h"
-#include "fpdfsdk/include/fxedit/fxet_edit.h"
-
-#define FX_EDIT_UNDERLINEHALFWIDTH 0.5f
-#define FX_EDIT_CROSSOUTHALFWIDTH 0.5f
-
-CPDF_Rect GetUnderLineRect(const CPVT_Word& word) {
-  return CPDF_Rect(word.ptWord.x, word.ptWord.y + word.fDescent * 0.5f,
-                   word.ptWord.x + word.fWidth,
-                   word.ptWord.y + word.fDescent * 0.25f);
-}
-
-CPDF_Rect GetCrossoutRect(const CPVT_Word& word) {
-  return CPDF_Rect(word.ptWord.x,
-                   word.ptWord.y + (word.fAscent + word.fDescent) * 0.5f +
-                       word.fDescent * 0.25f,
-                   word.ptWord.x + word.fWidth,
-                   word.ptWord.y + (word.fAscent + word.fDescent) * 0.5f);
-}
-
-static void DrawTextString(CFX_RenderDevice* pDevice,
-                           const CPDF_Point& pt,
-                           CPDF_Font* pFont,
-                           FX_FLOAT fFontSize,
-                           CFX_Matrix* pUser2Device,
-                           const CFX_ByteString& str,
-                           FX_ARGB crTextFill,
-                           FX_ARGB crTextStroke,
-                           int32_t nHorzScale) {
-  FX_FLOAT x = pt.x, y = pt.y;
-  pUser2Device->Transform(x, y);
-
-  if (pFont) {
-    if (nHorzScale != 100) {
-      CFX_Matrix mt(nHorzScale / 100.0f, 0, 0, 1, 0, 0);
-      mt.Concat(*pUser2Device);
-
-      CPDF_RenderOptions ro;
-      ro.m_Flags = RENDER_CLEARTYPE;
-      ro.m_ColorMode = RENDER_COLOR_NORMAL;
-
-      if (crTextStroke != 0) {
-        CPDF_Point pt1(0, 0), pt2(1, 0);
-        pUser2Device->Transform(pt1.x, pt1.y);
-        pUser2Device->Transform(pt2.x, pt2.y);
-        CFX_GraphStateData gsd;
-        gsd.m_LineWidth =
-            (FX_FLOAT)FXSYS_fabs((pt2.x + pt2.y) - (pt1.x + pt1.y));
-
-        CPDF_TextRenderer::DrawTextString(pDevice, x, y, pFont, fFontSize, &mt,
-                                          str, crTextFill, crTextStroke, &gsd,
-                                          &ro);
-      } else {
-        CPDF_TextRenderer::DrawTextString(pDevice, x, y, pFont, fFontSize, &mt,
-                                          str, crTextFill, 0, NULL, &ro);
-      }
-    } else {
-      CPDF_RenderOptions ro;
-      ro.m_Flags = RENDER_CLEARTYPE;
-      ro.m_ColorMode = RENDER_COLOR_NORMAL;
-
-      if (crTextStroke != 0) {
-        CPDF_Point pt1(0, 0), pt2(1, 0);
-        pUser2Device->Transform(pt1.x, pt1.y);
-        pUser2Device->Transform(pt2.x, pt2.y);
-        CFX_GraphStateData gsd;
-        gsd.m_LineWidth =
-            (FX_FLOAT)FXSYS_fabs((pt2.x + pt2.y) - (pt1.x + pt1.y));
-
-        CPDF_TextRenderer::DrawTextString(pDevice, x, y, pFont, fFontSize,
-                                          pUser2Device, str, crTextFill,
-                                          crTextStroke, &gsd, &ro);
-      } else {
-        CPDF_TextRenderer::DrawTextString(pDevice, x, y, pFont, fFontSize,
-                                          pUser2Device, str, crTextFill, 0,
-                                          NULL, &ro);
-      }
-    }
-  }
-}
-
-void IFX_Edit::DrawUnderline(CFX_RenderDevice* pDevice,
-                             CFX_Matrix* pUser2Device,
-                             IFX_Edit* pEdit,
-                             FX_COLORREF color,
-                             const CPDF_Rect& rcClip,
-                             const CPDF_Point& ptOffset,
-                             const CPVT_WordRange* pRange) {
-  pDevice->SaveState();
-
-  if (!rcClip.IsEmpty()) {
-    CPDF_Rect rcTemp = rcClip;
-    pUser2Device->TransformRect(rcTemp);
-    FX_RECT rcDevClip;
-    rcDevClip.left = (int32_t)rcTemp.left;
-    rcDevClip.right = (int32_t)rcTemp.right;
-    rcDevClip.top = (int32_t)rcTemp.top;
-    rcDevClip.bottom = (int32_t)rcTemp.bottom;
-    pDevice->SetClip_Rect(&rcDevClip);
-  }
-
-  if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator()) {
-    if (pEdit->GetFontMap()) {
-      if (pRange)
-        pIterator->SetAt(pRange->BeginPos);
-      else
-        pIterator->SetAt(0);
-
-      while (pIterator->NextWord()) {
-        CPVT_WordPlace place = pIterator->GetAt();
-        if (pRange && place.WordCmp(pRange->EndPos) > 0)
-          break;
-
-        CPVT_Word word;
-        if (pIterator->GetWord(word)) {
-          CFX_PathData pathUnderline;
-          CPDF_Rect rcUnderline = GetUnderLineRect(word);
-          rcUnderline.left += ptOffset.x;
-          rcUnderline.right += ptOffset.x;
-          rcUnderline.top += ptOffset.y;
-          rcUnderline.bottom += ptOffset.y;
-          pathUnderline.AppendRect(rcUnderline.left, rcUnderline.bottom,
-                                   rcUnderline.right, rcUnderline.top);
-
-          pDevice->DrawPath(&pathUnderline, pUser2Device, NULL, color, 0,
-                            FXFILL_WINDING);
-        }
-      }
-    }
-  }
-
-  pDevice->RestoreState();
-}
-
-void IFX_Edit::DrawEdit(CFX_RenderDevice* pDevice,
-                        CFX_Matrix* pUser2Device,
-                        IFX_Edit* pEdit,
-                        FX_COLORREF crTextFill,
-                        FX_COLORREF crTextStroke,
-                        const CPDF_Rect& rcClip,
-                        const CPDF_Point& ptOffset,
-                        const CPVT_WordRange* pRange,
-                        IFX_SystemHandler* pSystemHandler,
-                        void* pFFLData) {
-  FX_BOOL bContinuous = pEdit->GetCharArray() == 0;
-  if (pEdit->GetCharSpace() > 0.0f)
-    bContinuous = FALSE;
-
-  FX_WORD SubWord = pEdit->GetPasswordChar();
-  FX_FLOAT fFontSize = pEdit->GetFontSize();
-  CPVT_WordRange wrSelect = pEdit->GetSelectWordRange();
-  int32_t nHorzScale = pEdit->GetHorzScale();
-
-  FX_COLORREF crCurFill = crTextFill;
-  FX_COLORREF crOldFill = crCurFill;
-
-  FX_BOOL bSelect = FALSE;
-  const FX_COLORREF crWhite = ArgbEncode(255, 255, 255, 255);
-  const FX_COLORREF crSelBK = ArgbEncode(255, 0, 51, 113);
-
-  CFX_ByteTextBuf sTextBuf;
-  int32_t nFontIndex = -1;
-  CPDF_Point ptBT(0.0f, 0.0f);
-
-  pDevice->SaveState();
-
-  if (!rcClip.IsEmpty()) {
-    CPDF_Rect rcTemp = rcClip;
-    pUser2Device->TransformRect(rcTemp);
-    FX_RECT rcDevClip;
-    rcDevClip.left = (int32_t)rcTemp.left;
-    rcDevClip.right = (int32_t)rcTemp.right;
-    rcDevClip.top = (int32_t)rcTemp.top;
-    rcDevClip.bottom = (int32_t)rcTemp.bottom;
-    pDevice->SetClip_Rect(&rcDevClip);
-  }
-
-  if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator()) {
-    if (IFX_Edit_FontMap* pFontMap = pEdit->GetFontMap()) {
-      if (pRange)
-        pIterator->SetAt(pRange->BeginPos);
-      else
-        pIterator->SetAt(0);
-
-      CPVT_WordPlace oldplace;
-
-      while (pIterator->NextWord()) {
-        CPVT_WordPlace place = pIterator->GetAt();
-        if (pRange && place.WordCmp(pRange->EndPos) > 0)
-          break;
-
-        if (wrSelect.IsExist()) {
-          bSelect = place.WordCmp(wrSelect.BeginPos) > 0 &&
-                    place.WordCmp(wrSelect.EndPos) <= 0;
-          if (bSelect) {
-            crCurFill = crWhite;
-          } else {
-            crCurFill = crTextFill;
-          }
-        }
-        if (pSystemHandler && pSystemHandler->IsSelectionImplemented()) {
-          crCurFill = crTextFill;
-          crOldFill = crCurFill;
-        }
-        CPVT_Word word;
-        if (pIterator->GetWord(word)) {
-          if (bSelect) {
-            CPVT_Line line;
-            pIterator->GetLine(line);
-
-            if (pSystemHandler && pSystemHandler->IsSelectionImplemented()) {
-              CPDF_Rect rc(word.ptWord.x, line.ptLine.y + line.fLineDescent,
-                           word.ptWord.x + word.fWidth,
-                           line.ptLine.y + line.fLineAscent);
-              rc.Intersect(rcClip);
-              pSystemHandler->OutputSelectedRect(pFFLData, rc);
-            } else {
-              CFX_PathData pathSelBK;
-              pathSelBK.AppendRect(word.ptWord.x,
-                                   line.ptLine.y + line.fLineDescent,
-                                   word.ptWord.x + word.fWidth,
-                                   line.ptLine.y + line.fLineAscent);
-
-              pDevice->DrawPath(&pathSelBK, pUser2Device, NULL, crSelBK, 0,
-                                FXFILL_WINDING);
-            }
-          }
-
-          if (bContinuous) {
-            if (place.LineCmp(oldplace) != 0 || word.nFontIndex != nFontIndex ||
-                crOldFill != crCurFill) {
-              if (sTextBuf.GetLength() > 0) {
-                DrawTextString(pDevice, CPDF_Point(ptBT.x + ptOffset.x,
-                                                   ptBT.y + ptOffset.y),
-                               pFontMap->GetPDFFont(nFontIndex), fFontSize,
-                               pUser2Device, sTextBuf.GetByteString(),
-                               crOldFill, crTextStroke, nHorzScale);
-
-                sTextBuf.Clear();
-              }
-              nFontIndex = word.nFontIndex;
-              ptBT = word.ptWord;
-              crOldFill = crCurFill;
-            }
-
-            sTextBuf << GetPDFWordString(pFontMap, word.nFontIndex, word.Word,
-                                         SubWord);
-          } else {
-            DrawTextString(
-                pDevice, CPDF_Point(word.ptWord.x + ptOffset.x,
-                                    word.ptWord.y + ptOffset.y),
-                pFontMap->GetPDFFont(word.nFontIndex), fFontSize, pUser2Device,
-                GetPDFWordString(pFontMap, word.nFontIndex, word.Word, SubWord),
-                crCurFill, crTextStroke, nHorzScale);
-          }
-          oldplace = place;
-        }
-      }
-
-      if (sTextBuf.GetLength() > 0) {
-        DrawTextString(
-            pDevice, CPDF_Point(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
-            pFontMap->GetPDFFont(nFontIndex), fFontSize, pUser2Device,
-            sTextBuf.GetByteString(), crOldFill, crTextStroke, nHorzScale);
-      }
-    }
-  }
-
-  pDevice->RestoreState();
-}
-
-void IFX_Edit::DrawRichEdit(CFX_RenderDevice* pDevice,
-                            CFX_Matrix* pUser2Device,
-                            IFX_Edit* pEdit,
-                            const CPDF_Rect& rcClip,
-                            const CPDF_Point& ptOffset,
-                            const CPVT_WordRange* pRange) {
-  CPVT_WordRange wrSelect = pEdit->GetSelectWordRange();
-
-  FX_COLORREF crCurText = ArgbEncode(255, 0, 0, 0);
-  FX_COLORREF crOld = crCurText;
-  FX_BOOL bSelect = FALSE;
-  const FX_COLORREF crWhite = ArgbEncode(255, 255, 255, 255);
-  const FX_COLORREF crSelBK = ArgbEncode(255, 0, 51, 113);
-
-  CFX_ByteTextBuf sTextBuf;
-  CPVT_WordProps wp;
-  CPDF_Point ptBT(0.0f, 0.0f);
-
-  pDevice->SaveState();
-
-  if (!rcClip.IsEmpty()) {
-    CPDF_Rect rcTemp = rcClip;
-    pUser2Device->TransformRect(rcTemp);
-    FX_RECT rcDevClip;
-    rcDevClip.left = (int32_t)rcTemp.left;
-    rcDevClip.right = (int32_t)rcTemp.right;
-    rcDevClip.top = (int32_t)rcTemp.top;
-    rcDevClip.bottom = (int32_t)rcTemp.bottom;
-    pDevice->SetClip_Rect(&rcDevClip);
-  }
-
-  if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator()) {
-    if (IFX_Edit_FontMap* pFontMap = pEdit->GetFontMap()) {
-      if (pRange)
-        pIterator->SetAt(pRange->BeginPos);
-      else
-        pIterator->SetAt(0);
-
-      CPVT_WordPlace oldplace;
-
-      while (pIterator->NextWord()) {
-        CPVT_WordPlace place = pIterator->GetAt();
-        if (pRange && place.WordCmp(pRange->EndPos) > 0)
-          break;
-
-        CPVT_Word word;
-        if (pIterator->GetWord(word)) {
-          word.WordProps.fFontSize = word.fFontSize;
-
-          crCurText = ArgbEncode(255, word.WordProps.dwWordColor);
-
-          if (wrSelect.IsExist()) {
-            bSelect = place.WordCmp(wrSelect.BeginPos) > 0 &&
-                      place.WordCmp(wrSelect.EndPos) <= 0;
-            if (bSelect) {
-              crCurText = crWhite;
-            }
-          }
-
-          if (bSelect) {
-            CPVT_Line line;
-            pIterator->GetLine(line);
-
-            CFX_PathData pathSelBK;
-            pathSelBK.AppendRect(word.ptWord.x + ptOffset.x,
-                                 line.ptLine.y + line.fLineDescent + ptOffset.y,
-                                 word.ptWord.x + word.fWidth + ptOffset.x,
-                                 line.ptLine.y + line.fLineAscent + ptOffset.y);
-
-            pDevice->DrawPath(&pathSelBK, pUser2Device, NULL, crSelBK, 0,
-                              FXFILL_WINDING);
-          }
-
-          if (place.LineCmp(oldplace) != 0 ||
-              word.WordProps.fCharSpace > 0.0f ||
-              word.WordProps.nHorzScale != 100 ||
-              FXSYS_memcmp(&word.WordProps, &wp, sizeof(CPVT_WordProps)) != 0 ||
-              crOld != crCurText) {
-            if (sTextBuf.GetLength() > 0) {
-              DrawTextString(
-                  pDevice, CPDF_Point(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
-                  pFontMap->GetPDFFont(wp.nFontIndex), wp.fFontSize,
-                  pUser2Device, sTextBuf.GetByteString(), crOld, 0,
-                  wp.nHorzScale);
-
-              sTextBuf.Clear();
-            }
-            wp = word.WordProps;
-            ptBT = word.ptWord;
-            crOld = crCurText;
-          }
-
-          sTextBuf << GetPDFWordString(pFontMap, word.WordProps.nFontIndex,
-                                       word.Word, 0);
-
-          if (word.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE) {
-            CFX_PathData pathUnderline;
-            CPDF_Rect rcUnderline = GetUnderLineRect(word);
-            pathUnderline.AppendRect(rcUnderline.left, rcUnderline.bottom,
-                                     rcUnderline.right, rcUnderline.top);
-
-            pDevice->DrawPath(&pathUnderline, pUser2Device, NULL, crCurText, 0,
-                              FXFILL_WINDING);
-          }
-
-          if (word.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT) {
-            CFX_PathData pathCrossout;
-            CPDF_Rect rcCrossout = GetCrossoutRect(word);
-            pathCrossout.AppendRect(rcCrossout.left, rcCrossout.bottom,
-                                    rcCrossout.right, rcCrossout.top);
-
-            pDevice->DrawPath(&pathCrossout, pUser2Device, NULL, crCurText, 0,
-                              FXFILL_WINDING);
-          }
-
-          oldplace = place;
-        }
-      }
-
-      if (sTextBuf.GetLength() > 0) {
-        DrawTextString(
-            pDevice, CPDF_Point(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
-            pFontMap->GetPDFFont(wp.nFontIndex), wp.fFontSize, pUser2Device,
-            sTextBuf.GetByteString(), crOld, 0, wp.nHorzScale);
-      }
-    }
-  }
-
-  pDevice->RestoreState();
-}
-
-static void AddRectToPageObjects(CPDF_PageObjects* pPageObjs,
-                                 FX_COLORREF crFill,
-                                 const CPDF_Rect& rcFill) {
-  CPDF_PathObject* pPathObj = new CPDF_PathObject;
-  CPDF_PathData* pPathData = pPathObj->m_Path.GetModify();
-  pPathData->AppendRect(rcFill.left, rcFill.bottom, rcFill.right, rcFill.top);
-
-  FX_FLOAT rgb[3];
-  rgb[0] = FXARGB_R(crFill) / 255.0f;
-  rgb[1] = FXARGB_G(crFill) / 255.0f;
-  rgb[2] = FXARGB_B(crFill) / 255.0f;
-  pPathObj->m_ColorState.SetFillColor(
-      CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB), rgb, 3);
-
-  pPathObj->m_FillType = FXFILL_ALTERNATE;
-  pPathObj->m_bStroke = FALSE;
-
-  pPageObjs->InsertObject(pPageObjs->GetLastObjectPosition(), pPathObj);
-}
-
-static CPDF_TextObject* AddTextObjToPageObjects(CPDF_PageObjects* pPageObjs,
-                                                FX_COLORREF crText,
-                                                CPDF_Font* pFont,
-                                                FX_FLOAT fFontSize,
-                                                FX_FLOAT fCharSpace,
-                                                int32_t nHorzScale,
-                                                const CPDF_Point& point,
-                                                const CFX_ByteString& text) {
-  CPDF_TextObject* pTxtObj = new CPDF_TextObject;
-
-  CPDF_TextStateData* pTextStateData = pTxtObj->m_TextState.GetModify();
-  pTextStateData->m_pFont = pFont;
-  pTextStateData->m_FontSize = fFontSize;
-  pTextStateData->m_CharSpace = fCharSpace;
-  pTextStateData->m_WordSpace = 0;
-  pTextStateData->m_TextMode = 0;
-  pTextStateData->m_Matrix[0] = nHorzScale / 100.0f;
-  pTextStateData->m_Matrix[1] = 0;
-  pTextStateData->m_Matrix[2] = 0;
-  pTextStateData->m_Matrix[3] = 1;
-
-  FX_FLOAT rgb[3];
-  rgb[0] = FXARGB_R(crText) / 255.0f;
-  rgb[1] = FXARGB_G(crText) / 255.0f;
-  rgb[2] = FXARGB_B(crText) / 255.0f;
-  pTxtObj->m_ColorState.SetFillColor(
-      CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB), rgb, 3);
-  pTxtObj->m_ColorState.SetStrokeColor(
-      CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB), rgb, 3);
-
-  pTxtObj->SetPosition(point.x, point.y);
-  pTxtObj->SetText(text);
-
-  pPageObjs->InsertObject(pPageObjs->GetLastObjectPosition(), pTxtObj);
-
-  return pTxtObj;
-}
-
-void IFX_Edit::GeneratePageObjects(
-    CPDF_PageObjects* pPageObjects,
-    IFX_Edit* pEdit,
-    const CPDF_Point& ptOffset,
-    const CPVT_WordRange* pRange,
-    FX_COLORREF crText,
-    CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray) {
-  FX_FLOAT fFontSize = pEdit->GetFontSize();
-
-  int32_t nOldFontIndex = -1;
-
-  CFX_ByteTextBuf sTextBuf;
-  CPDF_Point ptBT(0.0f, 0.0f);
-
-  ObjArray.RemoveAll();
-
-  if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator()) {
-    if (IFX_Edit_FontMap* pFontMap = pEdit->GetFontMap()) {
-      if (pRange)
-        pIterator->SetAt(pRange->BeginPos);
-      else
-        pIterator->SetAt(0);
-
-      CPVT_WordPlace oldplace;
-
-      while (pIterator->NextWord()) {
-        CPVT_WordPlace place = pIterator->GetAt();
-        if (pRange && place.WordCmp(pRange->EndPos) > 0)
-          break;
-
-        CPVT_Word word;
-        if (pIterator->GetWord(word)) {
-          if (place.LineCmp(oldplace) != 0 ||
-              nOldFontIndex != word.nFontIndex) {
-            if (sTextBuf.GetLength() > 0) {
-              ObjArray.Add(AddTextObjToPageObjects(
-                  pPageObjects, crText, pFontMap->GetPDFFont(nOldFontIndex),
-                  fFontSize, 0.0f, 100,
-                  CPDF_Point(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
-                  sTextBuf.GetByteString()));
-
-              sTextBuf.Clear();
-            }
-
-            ptBT = word.ptWord;
-            nOldFontIndex = word.nFontIndex;
-          }
-
-          sTextBuf << GetPDFWordString(pFontMap, word.nFontIndex, word.Word, 0);
-          oldplace = place;
-        }
-      }
-
-      if (sTextBuf.GetLength() > 0) {
-        ObjArray.Add(AddTextObjToPageObjects(
-            pPageObjects, crText, pFontMap->GetPDFFont(nOldFontIndex),
-            fFontSize, 0.0f, 100,
-            CPDF_Point(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
-            sTextBuf.GetByteString()));
-      }
-    }
-  }
-}
-
-void IFX_Edit::GenerateRichPageObjects(
-    CPDF_PageObjects* pPageObjects,
-    IFX_Edit* pEdit,
-    const CPDF_Point& ptOffset,
-    const CPVT_WordRange* pRange,
-    CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray) {
-  FX_COLORREF crCurText = ArgbEncode(255, 0, 0, 0);
-  FX_COLORREF crOld = crCurText;
-
-  CFX_ByteTextBuf sTextBuf;
-  CPVT_WordProps wp;
-  CPDF_Point ptBT(0.0f, 0.0f);
-
-  ObjArray.RemoveAll();
-
-  if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator()) {
-    if (IFX_Edit_FontMap* pFontMap = pEdit->GetFontMap()) {
-      if (pRange)
-        pIterator->SetAt(pRange->BeginPos);
-      else
-        pIterator->SetAt(0);
-
-      CPVT_WordPlace oldplace;
-
-      while (pIterator->NextWord()) {
-        CPVT_WordPlace place = pIterator->GetAt();
-        if (pRange && place.WordCmp(pRange->EndPos) > 0)
-          break;
-
-        CPVT_Word word;
-        if (pIterator->GetWord(word)) {
-          word.WordProps.fFontSize = word.fFontSize;
-
-          crCurText = ArgbEncode(255, word.WordProps.dwWordColor);
-
-          if (place.LineCmp(oldplace) != 0 ||
-              word.WordProps.fCharSpace > 0.0f ||
-              word.WordProps.nHorzScale != 100 ||
-              FXSYS_memcmp(&word.WordProps, &wp, sizeof(CPVT_WordProps)) != 0 ||
-              crOld != crCurText) {
-            if (sTextBuf.GetLength() > 0) {
-              ObjArray.Add(AddTextObjToPageObjects(
-                  pPageObjects, crOld, pFontMap->GetPDFFont(wp.nFontIndex),
-                  wp.fFontSize, wp.fCharSpace, wp.nHorzScale,
-                  CPDF_Point(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
-                  sTextBuf.GetByteString()));
-
-              sTextBuf.Clear();
-            }
-
-            wp = word.WordProps;
-            ptBT = word.ptWord;
-            crOld = crCurText;
-          }
-
-          sTextBuf << GetPDFWordString(pFontMap, word.WordProps.nFontIndex,
-                                       word.Word, 0);
-
-          if (word.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE) {
-            CPDF_Rect rcUnderline = GetUnderLineRect(word);
-            rcUnderline.left += ptOffset.x;
-            rcUnderline.right += ptOffset.x;
-            rcUnderline.top += ptOffset.y;
-            rcUnderline.bottom += ptOffset.y;
-
-            AddRectToPageObjects(pPageObjects, crCurText, rcUnderline);
-          }
-
-          if (word.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT) {
-            CPDF_Rect rcCrossout = GetCrossoutRect(word);
-            rcCrossout.left += ptOffset.x;
-            rcCrossout.right += ptOffset.x;
-            rcCrossout.top += ptOffset.y;
-            rcCrossout.bottom += ptOffset.y;
-
-            AddRectToPageObjects(pPageObjects, crCurText, rcCrossout);
-          }
-
-          oldplace = place;
-        }
-      }
-
-      if (sTextBuf.GetLength() > 0) {
-        ObjArray.Add(AddTextObjToPageObjects(
-            pPageObjects, crOld, pFontMap->GetPDFFont(wp.nFontIndex),
-            wp.fFontSize, wp.fCharSpace, wp.nHorzScale,
-            CPDF_Point(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
-            sTextBuf.GetByteString()));
-      }
-    }
-  }
-}
-
-void IFX_Edit::GenerateUnderlineObjects(CPDF_PageObjects* pPageObjects,
-                                        IFX_Edit* pEdit,
-                                        const CPDF_Point& ptOffset,
-                                        const CPVT_WordRange* pRange,
-                                        FX_COLORREF color) {
-  if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator()) {
-    if (pEdit->GetFontMap()) {
-      if (pRange)
-        pIterator->SetAt(pRange->BeginPos);
-      else
-        pIterator->SetAt(0);
-
-      CPVT_WordPlace oldplace;
-
-      while (pIterator->NextWord()) {
-        CPVT_WordPlace place = pIterator->GetAt();
-        if (pRange && place.WordCmp(pRange->EndPos) > 0)
-          break;
-
-        CPVT_Word word;
-        if (pIterator->GetWord(word)) {
-          CPDF_Rect rcUnderline = GetUnderLineRect(word);
-          rcUnderline.left += ptOffset.x;
-          rcUnderline.right += ptOffset.x;
-          rcUnderline.top += ptOffset.y;
-          rcUnderline.bottom += ptOffset.y;
-          AddRectToPageObjects(pPageObjects, color, rcUnderline);
-        }
-      }
-    }
-  }
-}
diff --git a/fpdfsdk/src/javascript/Consts.cpp b/fpdfsdk/src/javascript/Consts.cpp
deleted file mode 100644
index 7f6b8f8..0000000
--- a/fpdfsdk/src/javascript/Consts.cpp
+++ /dev/null
@@ -1,295 +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
-
-#include "Consts.h"
-
-#include "JS_Define.h"
-#include "JS_Object.h"
-#include "JS_Value.h"
-#include "fpdfsdk/include/javascript/IJavaScript.h"
-
-/* ------------------------------ border ------------------------------ */
-
-BEGIN_JS_STATIC_CONST(CJS_Border)
-JS_STATIC_CONST_ENTRY_STRING(L"s", L"solid")
-JS_STATIC_CONST_ENTRY_STRING(L"b", L"beveled")
-JS_STATIC_CONST_ENTRY_STRING(L"d", L"dashed")
-JS_STATIC_CONST_ENTRY_STRING(L"i", L"inset")
-JS_STATIC_CONST_ENTRY_STRING(L"u", L"underline")
-END_JS_STATIC_CONST()
-
-IMPLEMENT_JS_CLASS_CONST(CJS_Border, border)
-
-/* ------------------------------ display ------------------------------ */
-
-BEGIN_JS_STATIC_CONST(CJS_Display)
-JS_STATIC_CONST_ENTRY_NUMBER(L"visible", 0)
-JS_STATIC_CONST_ENTRY_NUMBER(L"hidden", 1)
-JS_STATIC_CONST_ENTRY_NUMBER(L"noPrint", 2)
-JS_STATIC_CONST_ENTRY_NUMBER(L"noView", 3)
-END_JS_STATIC_CONST()
-
-IMPLEMENT_JS_CLASS_CONST(CJS_Display, display)
-
-/* ------------------------------ font ------------------------------ */
-
-BEGIN_JS_STATIC_CONST(CJS_Font)
-JS_STATIC_CONST_ENTRY_STRING(L"Times", L"Times-Roman")
-JS_STATIC_CONST_ENTRY_STRING(L"TimesB", L"Times-Bold")
-JS_STATIC_CONST_ENTRY_STRING(L"TimesI", L"Times-Italic")
-JS_STATIC_CONST_ENTRY_STRING(L"TimesBI", L"Times-BoldItalic")
-JS_STATIC_CONST_ENTRY_STRING(L"Helv", L"Helvetica")
-JS_STATIC_CONST_ENTRY_STRING(L"HelvB", L"Helvetica-Bold")
-JS_STATIC_CONST_ENTRY_STRING(L"HelvI", L"Helvetica-Oblique")
-JS_STATIC_CONST_ENTRY_STRING(L"HelvBI", L"Helvetica-BoldOblique")
-JS_STATIC_CONST_ENTRY_STRING(L"Cour", L"Courier")
-JS_STATIC_CONST_ENTRY_STRING(L"CourB", L"Courier-Bold")
-JS_STATIC_CONST_ENTRY_STRING(L"CourI", L"Courier-Oblique")
-JS_STATIC_CONST_ENTRY_STRING(L"CourBI", L"Courier-BoldOblique")
-JS_STATIC_CONST_ENTRY_STRING(L"Symbol", L"Symbol")
-JS_STATIC_CONST_ENTRY_STRING(L"ZapfD", L"ZapfDingbats")
-END_JS_STATIC_CONST()
-
-IMPLEMENT_JS_CLASS_CONST(CJS_Font, font)
-
-/* ------------------------------ highlight ------------------------------ */
-
-BEGIN_JS_STATIC_CONST(CJS_Highlight)
-JS_STATIC_CONST_ENTRY_STRING(L"n", L"none")
-JS_STATIC_CONST_ENTRY_STRING(L"i", L"invert")
-JS_STATIC_CONST_ENTRY_STRING(L"p", L"push")
-JS_STATIC_CONST_ENTRY_STRING(L"o", L"outline")
-END_JS_STATIC_CONST()
-
-IMPLEMENT_JS_CLASS_CONST(CJS_Highlight, highlight)
-
-/* ------------------------------ position ------------------------------ */
-
-BEGIN_JS_STATIC_CONST(CJS_Position)
-JS_STATIC_CONST_ENTRY_NUMBER(L"textOnly", 0)
-JS_STATIC_CONST_ENTRY_NUMBER(L"iconOnly", 1)
-JS_STATIC_CONST_ENTRY_NUMBER(L"iconTextV", 2)
-JS_STATIC_CONST_ENTRY_NUMBER(L"textIconV", 3)
-JS_STATIC_CONST_ENTRY_NUMBER(L"iconTextH", 4)
-JS_STATIC_CONST_ENTRY_NUMBER(L"textIconH", 5)
-JS_STATIC_CONST_ENTRY_NUMBER(L"overlay", 6)
-END_JS_STATIC_CONST()
-
-IMPLEMENT_JS_CLASS_CONST(CJS_Position, position)
-
-/* ------------------------------ scaleHow ------------------------------ */
-
-BEGIN_JS_STATIC_CONST(CJS_ScaleHow)
-JS_STATIC_CONST_ENTRY_NUMBER(L"proportional", 0)
-JS_STATIC_CONST_ENTRY_NUMBER(L"anamorphic", 1)
-END_JS_STATIC_CONST()
-
-IMPLEMENT_JS_CLASS_CONST(CJS_ScaleHow, scaleHow)
-
-/* ------------------------------ scaleWhen ------------------------------ */
-
-BEGIN_JS_STATIC_CONST(CJS_ScaleWhen)
-JS_STATIC_CONST_ENTRY_NUMBER(L"always", 0)
-JS_STATIC_CONST_ENTRY_NUMBER(L"never", 1)
-JS_STATIC_CONST_ENTRY_NUMBER(L"tooBig", 2)
-JS_STATIC_CONST_ENTRY_NUMBER(L"tooSmall", 3)
-END_JS_STATIC_CONST()
-
-IMPLEMENT_JS_CLASS_CONST(CJS_ScaleWhen, scaleWhen)
-
-/* ------------------------------ style ------------------------------ */
-
-BEGIN_JS_STATIC_CONST(CJS_Style)
-JS_STATIC_CONST_ENTRY_STRING(L"ch", L"check")
-JS_STATIC_CONST_ENTRY_STRING(L"cr", L"cross")
-JS_STATIC_CONST_ENTRY_STRING(L"di", L"diamond")
-JS_STATIC_CONST_ENTRY_STRING(L"ci", L"circle")
-JS_STATIC_CONST_ENTRY_STRING(L"st", L"star")
-JS_STATIC_CONST_ENTRY_STRING(L"sq", L"square")
-END_JS_STATIC_CONST()
-
-IMPLEMENT_JS_CLASS_CONST(CJS_Style, style)
-
-/* ------------------------------ zoomtype ------------------------------ */
-
-BEGIN_JS_STATIC_CONST(CJS_Zoomtype)
-JS_STATIC_CONST_ENTRY_STRING(L"none", L"NoVary")
-JS_STATIC_CONST_ENTRY_STRING(L"fitP", L"FitPage")
-JS_STATIC_CONST_ENTRY_STRING(L"fitW", L"FitWidth")
-JS_STATIC_CONST_ENTRY_STRING(L"fitH", L"FitHeight")
-JS_STATIC_CONST_ENTRY_STRING(L"fitV", L"FitVisibleWidth")
-JS_STATIC_CONST_ENTRY_STRING(L"pref", L"Preferred")
-JS_STATIC_CONST_ENTRY_STRING(L"refW", L"ReflowWidth")
-END_JS_STATIC_CONST()
-
-IMPLEMENT_JS_CLASS_CONST(CJS_Zoomtype, zoomtype)
-
-/* ------------------------------ CJS_GlobalConsts ------------------------- */
-
-static void DefineGlobalConstString(CJS_Runtime* pRuntime,
-                                    const wchar_t* pConstName,
-                                    const wchar_t* pValue) {
-  FXJS_DefineGlobalConst(pRuntime->GetIsolate(), pConstName,
-                         FXJS_NewString(pRuntime->GetIsolate(), pValue));
-}
-
-void CJS_GlobalConsts::DefineJSObjects(CJS_Runtime* pRuntime) {
-  DefineGlobalConstString(
-      pRuntime, L"IDS_GREATER_THAN",
-      L"Invalid value: must be greater than or equal to % s.");
-  DefineGlobalConstString(
-      pRuntime, L"IDS_GT_AND_LT",
-      L"Invalid value: must be greater than or equal to % s "
-      L"and less than or equal to % s.");
-  DefineGlobalConstString(pRuntime, L"IDS_LESS_THAN",
-                          L"Invalid value: must be less than or equal to % s.");
-  DefineGlobalConstString(pRuntime, L"IDS_INVALID_MONTH", L"**Invalid**");
-  DefineGlobalConstString(
-      pRuntime, L"IDS_INVALID_DATE",
-      L"Invalid date / time: please ensure that the date / time exists.Field");
-  DefineGlobalConstString(
-      pRuntime, L"IDS_INVALID_VALUE",
-      L"The value entered does not match the format of the field");
-  DefineGlobalConstString(pRuntime, L"IDS_AM", L"am");
-  DefineGlobalConstString(pRuntime, L"IDS_PM", L"pm");
-  DefineGlobalConstString(
-      pRuntime, L"IDS_MONTH_INFO",
-      L"January[1] February[2] March[3] April[4] May[5] "
-      L"June[6] July[7] August[8] September[9] October[10] "
-      L"November[11] December[12] Sept[9] Jan[1] Feb[2] Mar[3] "
-      L"Apr[4] Jun[6] Jul[7] Aug[8] Sep[9] Oct[10] Nov[11] "
-      L"Dec[12]");
-  DefineGlobalConstString(pRuntime, L"IDS_STARTUP_CONSOLE_MSG", L"** ^ _ ^ **");
-}
-
-/* ------------------------------ CJS_GlobalArrays  ------------------------ */
-
-void DefineGlobalConstStringArray(CJS_Runtime* pRuntime,
-                                  const wchar_t* sConstName,
-                                  const wchar_t** pValues,
-                                  size_t nValues) {
-  CJS_Array array(pRuntime);
-  for (size_t i = 0; i < nValues; ++i) {
-    array.SetElement(i, CJS_Value(pRuntime, pValues[i]));
-  }
-  CJS_PropValue prop(pRuntime);
-  prop << array;
-  FXJS_DefineGlobalConst(pRuntime->GetIsolate(), sConstName, prop.ToV8Value());
-}
-
-void CJS_GlobalArrays::DefineJSObjects(CJS_Runtime* pRuntime) {
-  {
-    const FX_WCHAR* ArrayName = L"RE_NUMBER_ENTRY_DOT_SEP";
-    const FX_WCHAR* ArrayContent[] = {L"[+-]?\\d*\\.?\\d*"};
-    DefineGlobalConstStringArray(pRuntime, ArrayName, ArrayContent,
-                                 FX_ArraySize(ArrayContent));
-  }
-
-  {
-    const FX_WCHAR* ArrayName = L"RE_NUMBER_COMMIT_DOT_SEP";
-    const FX_WCHAR* ArrayContent[] = {
-        L"[+-]?\\d+(\\.\\d+)?", /* -1.0 or -1 */
-        L"[+-]?\\.\\d+",        /* -.1 */
-        L"[+-]?\\d+\\."         /* -1. */
-    };
-    DefineGlobalConstStringArray(pRuntime, ArrayName, ArrayContent,
-                                 FX_ArraySize(ArrayContent));
-  }
-
-  {
-    const FX_WCHAR* ArrayName = L"RE_NUMBER_ENTRY_COMMA_SEP";
-    const FX_WCHAR* ArrayContent[] = {L"[+-]?\\d*,?\\d*"};
-
-    DefineGlobalConstStringArray(pRuntime, ArrayName, ArrayContent,
-                                 FX_ArraySize(ArrayContent));
-  }
-
-  {
-    const FX_WCHAR* ArrayName = L"RE_NUMBER_COMMIT_COMMA_SEP";
-    const FX_WCHAR* ArrayContent[] = {
-        L"[+-]?\\d+([.,]\\d+)?", /* -1,0 or -1 */
-        L"[+-]?[.,]\\d+",        /* -,1 */
-        L"[+-]?\\d+[.,]"         /* -1, */
-    };
-    DefineGlobalConstStringArray(pRuntime, ArrayName, ArrayContent,
-                                 FX_ArraySize(ArrayContent));
-  }
-
-  {
-    const FX_WCHAR* ArrayName = L"RE_ZIP_ENTRY";
-    const FX_WCHAR* ArrayContent[] = {L"\\d{0,5}"};
-    DefineGlobalConstStringArray(pRuntime, ArrayName, ArrayContent,
-                                 FX_ArraySize(ArrayContent));
-  }
-
-  {
-    const FX_WCHAR* ArrayName = L"RE_ZIP_COMMIT";
-    const FX_WCHAR* ArrayContent[] = {L"\\d{5}"};
-    DefineGlobalConstStringArray(pRuntime, ArrayName, ArrayContent,
-                                 FX_ArraySize(ArrayContent));
-  }
-
-  {
-    const FX_WCHAR* ArrayName = L"RE_ZIP4_ENTRY";
-    const FX_WCHAR* ArrayContent[] = {L"\\d{0,5}(\\.|[- ])?\\d{0,4}"};
-    DefineGlobalConstStringArray(pRuntime, ArrayName, ArrayContent,
-                                 FX_ArraySize(ArrayContent));
-  }
-
-  {
-    const FX_WCHAR* ArrayName = L"RE_ZIP4_COMMIT";
-    const FX_WCHAR* ArrayContent[] = {L"\\d{5}(\\.|[- ])?\\d{4}"};
-    DefineGlobalConstStringArray(pRuntime, ArrayName, ArrayContent,
-                                 FX_ArraySize(ArrayContent));
-  }
-
-  {
-    const FX_WCHAR* ArrayName = L"RE_PHONE_ENTRY";
-    const FX_WCHAR* ArrayContent[] = {
-        L"\\d{0,3}(\\.|[- ])?\\d{0,3}(\\.|[- ])?\\d{0,4}", /* 555-1234 or 408
-                                                              555-1234 */
-        L"\\(\\d{0,3}",                                    /* (408 */
-        L"\\(\\d{0,3}\\)(\\.|[- ])?\\d{0,3}(\\.|[- ])?\\d{0,4}", /* (408)
-                                                                    555-1234 */
-        /* (allow the addition of parens as an afterthought) */
-        L"\\(\\d{0,3}(\\.|[- ])?\\d{0,3}(\\.|[- ])?\\d{0,4}", /* (408 555-1234
-                                                                 */
-        L"\\d{0,3}\\)(\\.|[- ])?\\d{0,3}(\\.|[- ])?\\d{0,4}", /* 408) 555-1234
-                                                                 */
-        L"011(\\.|[- \\d])*" /* international */
-    };
-    DefineGlobalConstStringArray(pRuntime, ArrayName, ArrayContent,
-                                 FX_ArraySize(ArrayContent));
-  }
-
-  {
-    const FX_WCHAR* ArrayName = L"RE_PHONE_COMMIT";
-    const FX_WCHAR* ArrayContent[] = {
-        L"\\d{3}(\\.|[- ])?\\d{4}",                        /* 555-1234 */
-        L"\\d{3}(\\.|[- ])?\\d{3}(\\.|[- ])?\\d{4}",       /* 408 555-1234 */
-        L"\\(\\d{3}\\)(\\.|[- ])?\\d{3}(\\.|[- ])?\\d{4}", /* (408) 555-1234 */
-        L"011(\\.|[- \\d])*"                               /* international */
-    };
-    DefineGlobalConstStringArray(pRuntime, ArrayName, ArrayContent,
-                                 FX_ArraySize(ArrayContent));
-  }
-
-  {
-    const FX_WCHAR* ArrayName = L"RE_SSN_ENTRY";
-    const FX_WCHAR* ArrayContent[] = {
-        L"\\d{0,3}(\\.|[- ])?\\d{0,2}(\\.|[- ])?\\d{0,4}"};
-    DefineGlobalConstStringArray(pRuntime, ArrayName, ArrayContent,
-                                 FX_ArraySize(ArrayContent));
-  }
-
-  {
-    const FX_WCHAR* ArrayName = L"RE_SSN_COMMIT";
-    const FX_WCHAR* ArrayContent[] = {
-        L"\\d{3}(\\.|[- ])?\\d{2}(\\.|[- ])?\\d{4}"};
-    DefineGlobalConstStringArray(pRuntime, ArrayName, ArrayContent,
-                                 FX_ArraySize(ArrayContent));
-  }
-}
diff --git a/fpdfsdk/src/javascript/Document.cpp b/fpdfsdk/src/javascript/Document.cpp
deleted file mode 100644
index 1040c34..0000000
--- a/fpdfsdk/src/javascript/Document.cpp
+++ /dev/null
@@ -1,1651 +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
-
-#include "Document.h"
-
-#include "Field.h"
-#include "Icon.h"
-#include "JS_Context.h"
-#include "JS_Define.h"
-#include "JS_EventHandler.h"
-#include "JS_Object.h"
-#include "JS_Runtime.h"
-#include "JS_Value.h"
-#include "app.h"
-#include "fpdfsdk/include/fsdk_mgr.h"  // For CPDFDoc_Environment.
-#include "fpdfsdk/include/javascript/IJavaScript.h"
-#include "resource.h"
-#include "third_party/base/numerics/safe_math.h"
-
-static v8::Isolate* GetIsolate(IJS_Context* cc) {
-  CJS_Context* pContext = (CJS_Context*)cc;
-  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
-  return pRuntime->GetIsolate();
-}
-
-BEGIN_JS_STATIC_CONST(CJS_PrintParamsObj)
-END_JS_STATIC_CONST()
-
-BEGIN_JS_STATIC_PROP(CJS_PrintParamsObj)
-END_JS_STATIC_PROP()
-
-BEGIN_JS_STATIC_METHOD(CJS_PrintParamsObj)
-END_JS_STATIC_METHOD()
-
-IMPLEMENT_JS_CLASS(CJS_PrintParamsObj, PrintParamsObj)
-
-PrintParamsObj::PrintParamsObj(CJS_Object* pJSObject)
-    : CJS_EmbedObj(pJSObject) {
-  bUI = TRUE;
-  nStart = 0;
-  nEnd = 0;
-  bSilent = FALSE;
-  bShrinkToFit = FALSE;
-  bPrintAsImage = FALSE;
-  bReverse = FALSE;
-  bAnnotations = TRUE;
-}
-
-/* ---------------------- Document ---------------------- */
-
-#define MINWIDTH 5.0f
-#define MINHEIGHT 5.0f
-
-BEGIN_JS_STATIC_CONST(CJS_Document)
-END_JS_STATIC_CONST()
-
-BEGIN_JS_STATIC_PROP(CJS_Document)
-JS_STATIC_PROP_ENTRY(ADBE)
-JS_STATIC_PROP_ENTRY(author)
-JS_STATIC_PROP_ENTRY(baseURL)
-JS_STATIC_PROP_ENTRY(bookmarkRoot)
-JS_STATIC_PROP_ENTRY(calculate)
-JS_STATIC_PROP_ENTRY(Collab)
-JS_STATIC_PROP_ENTRY(creationDate)
-JS_STATIC_PROP_ENTRY(creator)
-JS_STATIC_PROP_ENTRY(delay)
-JS_STATIC_PROP_ENTRY(dirty)
-JS_STATIC_PROP_ENTRY(documentFileName)
-JS_STATIC_PROP_ENTRY(external)
-JS_STATIC_PROP_ENTRY(filesize)
-JS_STATIC_PROP_ENTRY(icons)
-JS_STATIC_PROP_ENTRY(info)
-JS_STATIC_PROP_ENTRY(keywords)
-JS_STATIC_PROP_ENTRY(layout)
-JS_STATIC_PROP_ENTRY(media)
-JS_STATIC_PROP_ENTRY(modDate)
-JS_STATIC_PROP_ENTRY(mouseX)
-JS_STATIC_PROP_ENTRY(mouseY)
-JS_STATIC_PROP_ENTRY(numFields)
-JS_STATIC_PROP_ENTRY(numPages)
-JS_STATIC_PROP_ENTRY(pageNum)
-JS_STATIC_PROP_ENTRY(pageWindowRect)
-JS_STATIC_PROP_ENTRY(path)
-JS_STATIC_PROP_ENTRY(producer)
-JS_STATIC_PROP_ENTRY(subject)
-JS_STATIC_PROP_ENTRY(title)
-JS_STATIC_PROP_ENTRY(zoom)
-JS_STATIC_PROP_ENTRY(zoomType)
-END_JS_STATIC_PROP()
-
-BEGIN_JS_STATIC_METHOD(CJS_Document)
-JS_STATIC_METHOD_ENTRY(addAnnot)
-JS_STATIC_METHOD_ENTRY(addField)
-JS_STATIC_METHOD_ENTRY(addLink)
-JS_STATIC_METHOD_ENTRY(addIcon)
-JS_STATIC_METHOD_ENTRY(calculateNow)
-JS_STATIC_METHOD_ENTRY(closeDoc)
-JS_STATIC_METHOD_ENTRY(createDataObject)
-JS_STATIC_METHOD_ENTRY(deletePages)
-JS_STATIC_METHOD_ENTRY(exportAsText)
-JS_STATIC_METHOD_ENTRY(exportAsFDF)
-JS_STATIC_METHOD_ENTRY(exportAsXFDF)
-JS_STATIC_METHOD_ENTRY(extractPages)
-JS_STATIC_METHOD_ENTRY(getAnnot)
-JS_STATIC_METHOD_ENTRY(getAnnots)
-JS_STATIC_METHOD_ENTRY(getAnnot3D)
-JS_STATIC_METHOD_ENTRY(getAnnots3D)
-JS_STATIC_METHOD_ENTRY(getField)
-JS_STATIC_METHOD_ENTRY(getIcon)
-JS_STATIC_METHOD_ENTRY(getLinks)
-JS_STATIC_METHOD_ENTRY(getNthFieldName)
-JS_STATIC_METHOD_ENTRY(getOCGs)
-JS_STATIC_METHOD_ENTRY(getPageBox)
-JS_STATIC_METHOD_ENTRY(getPageNthWord)
-JS_STATIC_METHOD_ENTRY(getPageNthWordQuads)
-JS_STATIC_METHOD_ENTRY(getPageNumWords)
-JS_STATIC_METHOD_ENTRY(getPrintParams)
-JS_STATIC_METHOD_ENTRY(getURL)
-JS_STATIC_METHOD_ENTRY(importAnFDF)
-JS_STATIC_METHOD_ENTRY(importAnXFDF)
-JS_STATIC_METHOD_ENTRY(importTextData)
-JS_STATIC_METHOD_ENTRY(insertPages)
-JS_STATIC_METHOD_ENTRY(mailForm)
-JS_STATIC_METHOD_ENTRY(print)
-JS_STATIC_METHOD_ENTRY(removeField)
-JS_STATIC_METHOD_ENTRY(replacePages)
-JS_STATIC_METHOD_ENTRY(resetForm)
-JS_STATIC_METHOD_ENTRY(removeIcon)
-JS_STATIC_METHOD_ENTRY(saveAs)
-JS_STATIC_METHOD_ENTRY(submitForm)
-JS_STATIC_METHOD_ENTRY(mailDoc)
-END_JS_STATIC_METHOD()
-
-IMPLEMENT_JS_CLASS(CJS_Document, Document)
-
-void CJS_Document::InitInstance(IJS_Runtime* pIRuntime) {
-  CJS_Runtime* pRuntime = static_cast<CJS_Runtime*>(pIRuntime);
-  Document* pDoc = static_cast<Document*>(GetEmbedObject());
-  pDoc->AttachDoc(pRuntime->GetReaderDocument());
-  pDoc->SetIsolate(pRuntime->GetIsolate());
-}
-
-/* --------------------------------- Document ---------------------------------
- */
-
-Document::Document(CJS_Object* pJSObject)
-    : CJS_EmbedObj(pJSObject),
-      m_isolate(NULL),
-      m_pDocument(NULL),
-      m_cwBaseURL(L""),
-      m_bDelay(FALSE) {}
-
-Document::~Document() {
-  for (int i = 0; i < m_DelayData.GetSize(); i++) {
-    delete m_DelayData.GetAt(i);
-  }
-
-  m_DelayData.RemoveAll();
-}
-
-// the total number of fileds in document.
-FX_BOOL Document::numFields(IJS_Context* cc,
-                            CJS_PropValue& vp,
-                            CFX_WideString& sError) {
-  if (vp.IsSetting()) {
-    CJS_Context* pContext = static_cast<CJS_Context*>(cc);
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY);
-    return FALSE;
-  }
-  CPDFSDK_InterForm* pInterForm = m_pDocument->GetInterForm();
-  CPDF_InterForm* pPDFForm = pInterForm->GetInterForm();
-  vp << (int)pPDFForm->CountFields();
-  return TRUE;
-}
-
-FX_BOOL Document::dirty(IJS_Context* cc,
-                        CJS_PropValue& vp,
-                        CFX_WideString& sError) {
-  if (vp.IsGetting()) {
-    if (m_pDocument->GetChangeMark())
-      vp << true;
-    else
-      vp << false;
-  } else {
-    bool bChanged = false;
-
-    vp >> bChanged;
-
-    if (bChanged)
-      m_pDocument->SetChangeMark();
-    else
-      m_pDocument->ClearChangeMark();
-  }
-
-  return TRUE;
-}
-
-FX_BOOL Document::ADBE(IJS_Context* cc,
-                       CJS_PropValue& vp,
-                       CFX_WideString& sError) {
-  if (vp.IsGetting()) {
-    vp.SetNull();
-  } else {
-  }
-
-  return TRUE;
-}
-
-FX_BOOL Document::pageNum(IJS_Context* cc,
-                          CJS_PropValue& vp,
-                          CFX_WideString& sError) {
-  if (vp.IsGetting()) {
-    if (CPDFSDK_PageView* pPageView = m_pDocument->GetCurrentView()) {
-      vp << pPageView->GetPageIndex();
-    }
-  } else {
-    int iPageCount = m_pDocument->GetPageCount();
-    int iPageNum = 0;
-    vp >> iPageNum;
-
-    CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
-    if (iPageNum >= 0 && iPageNum < iPageCount) {
-      pEnv->JS_docgotoPage(iPageNum);
-    } else if (iPageNum >= iPageCount) {
-      pEnv->JS_docgotoPage(iPageCount - 1);
-    } else if (iPageNum < 0) {
-      pEnv->JS_docgotoPage(0);
-    }
-  }
-
-  return TRUE;
-}
-
-FX_BOOL Document::addAnnot(IJS_Context* cc,
-                           const std::vector<CJS_Value>& params,
-                           CJS_Value& vRet,
-                           CFX_WideString& sError) {
-  // Not supported.
-  return TRUE;
-}
-
-FX_BOOL Document::addField(IJS_Context* cc,
-                           const std::vector<CJS_Value>& params,
-                           CJS_Value& vRet,
-                           CFX_WideString& sError) {
-  // Not supported.
-  return TRUE;
-}
-
-FX_BOOL Document::exportAsText(IJS_Context* cc,
-                               const std::vector<CJS_Value>& params,
-                               CJS_Value& vRet,
-                               CFX_WideString& sError) {
-  // Unsafe, not supported.
-  return TRUE;
-}
-
-FX_BOOL Document::exportAsFDF(IJS_Context* cc,
-                              const std::vector<CJS_Value>& params,
-                              CJS_Value& vRet,
-                              CFX_WideString& sError) {
-  // Unsafe, not supported.
-  return TRUE;
-}
-
-FX_BOOL Document::exportAsXFDF(IJS_Context* cc,
-                               const std::vector<CJS_Value>& params,
-                               CJS_Value& vRet,
-                               CFX_WideString& sError) {
-  // Unsafe, not supported.
-  return TRUE;
-}
-
-// Maps a field object in PDF document to a JavaScript variable
-// comment:
-// note: the paremter cName, this is clue how to treat if the cName is not a
-// valiable filed name in this document
-
-FX_BOOL Document::getField(IJS_Context* cc,
-                           const std::vector<CJS_Value>& params,
-                           CJS_Value& vRet,
-                           CFX_WideString& sError) {
-  CJS_Context* pContext = (CJS_Context*)cc;
-  if (params.size() < 1) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
-    return FALSE;
-  }
-
-  CFX_WideString wideName = params[0].ToCFXWideString();
-
-  CPDFSDK_InterForm* pInterForm = m_pDocument->GetInterForm();
-  CPDF_InterForm* pPDFForm = pInterForm->GetInterForm();
-  if (pPDFForm->CountFields(wideName) <= 0) {
-    vRet.SetNull();
-    return TRUE;
-  }
-
-  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
-  v8::Local<v8::Object> pFieldObj = FXJS_NewFxDynamicObj(
-      pRuntime->GetIsolate(), pRuntime, CJS_Field::g_nObjDefnID);
-
-  v8::Isolate* isolate = GetIsolate(cc);
-  CJS_Field* pJSField = (CJS_Field*)FXJS_GetPrivate(isolate, pFieldObj);
-  Field* pField = (Field*)pJSField->GetEmbedObject();
-  pField->AttachField(this, wideName);
-
-  vRet = pJSField;
-  return TRUE;
-}
-
-// Gets the name of the nth field in the document
-FX_BOOL Document::getNthFieldName(IJS_Context* cc,
-                                  const std::vector<CJS_Value>& params,
-                                  CJS_Value& vRet,
-                                  CFX_WideString& sError) {
-  CJS_Context* pContext = (CJS_Context*)cc;
-  if (params.size() != 1) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
-    return FALSE;
-  }
-
-  int nIndex = params[0].ToInt();
-  if (nIndex < 0) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSVALUEERROR);
-    return FALSE;
-  }
-
-  CPDFSDK_InterForm* pInterForm = m_pDocument->GetInterForm();
-  CPDF_InterForm* pPDFForm = pInterForm->GetInterForm();
-  CPDF_FormField* pField = pPDFForm->GetField(nIndex);
-  if (!pField)
-    return FALSE;
-
-  vRet = pField->GetFullName().c_str();
-  return TRUE;
-}
-
-FX_BOOL Document::importAnFDF(IJS_Context* cc,
-                              const std::vector<CJS_Value>& params,
-                              CJS_Value& vRet,
-                              CFX_WideString& sError) {
-  // Unsafe, not supported.
-  return TRUE;
-}
-
-FX_BOOL Document::importAnXFDF(IJS_Context* cc,
-                               const std::vector<CJS_Value>& params,
-                               CJS_Value& vRet,
-                               CFX_WideString& sError) {
-  // Unsafe, not supported.
-  return TRUE;
-}
-
-FX_BOOL Document::importTextData(IJS_Context* cc,
-                                 const std::vector<CJS_Value>& params,
-                                 CJS_Value& vRet,
-                                 CFX_WideString& sError) {
-  // Unsafe, not supported.
-  return TRUE;
-}
-
-// exports the form data and mails the resulting fdf file as an attachment to
-// all recipients.
-// comment: need reader supports
-// note:
-// int CPDFSDK_Document::mailForm(FX_BOOL bUI,String cto,string ccc,string
-// cbcc,string cSubject,string cms);
-
-FX_BOOL Document::mailForm(IJS_Context* cc,
-                           const std::vector<CJS_Value>& params,
-                           CJS_Value& vRet,
-                           CFX_WideString& sError) {
-  if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS))
-    return FALSE;
-
-  int iLength = params.size();
-
-  FX_BOOL bUI = iLength > 0 ? params[0].ToBool() : TRUE;
-  CFX_WideString cTo = iLength > 1 ? params[1].ToCFXWideString() : L"";
-  CFX_WideString cCc = iLength > 2 ? params[2].ToCFXWideString() : L"";
-  CFX_WideString cBcc = iLength > 3 ? params[3].ToCFXWideString() : L"";
-  CFX_WideString cSubject = iLength > 4 ? params[4].ToCFXWideString() : L"";
-  CFX_WideString cMsg = iLength > 5 ? params[5].ToCFXWideString() : L"";
-
-  CPDFSDK_InterForm* pInterForm =
-      (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
-  CFX_ByteTextBuf textBuf;
-  if (!pInterForm->ExportFormToFDFTextBuf(textBuf))
-    return FALSE;
-
-  CJS_Context* pContext = (CJS_Context*)cc;
-  CPDFDoc_Environment* pEnv = pContext->GetReaderApp();
-  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
-
-  pRuntime->BeginBlock();
-  pEnv->JS_docmailForm(textBuf.GetBuffer(), textBuf.GetLength(), bUI,
-                       cTo.c_str(), cSubject.c_str(), cCc.c_str(), cBcc.c_str(),
-                       cMsg.c_str());
-  pRuntime->EndBlock();
-  return TRUE;
-}
-
-FX_BOOL Document::print(IJS_Context* cc,
-                        const std::vector<CJS_Value>& params,
-                        CJS_Value& vRet,
-                        CFX_WideString& sError) {
-  FX_BOOL bUI = TRUE;
-  int nStart = 0;
-  int nEnd = 0;
-  FX_BOOL bSilent = FALSE;
-  FX_BOOL bShrinkToFit = FALSE;
-  FX_BOOL bPrintAsImage = FALSE;
-  FX_BOOL bReverse = FALSE;
-  FX_BOOL bAnnotations = FALSE;
-
-  int nlength = params.size();
-  if (nlength == 9) {
-    if (params[8].GetType() == CJS_Value::VT_fxobject) {
-      v8::Local<v8::Object> pObj = params[8].ToV8Object();
-      {
-        if (FXJS_GetObjDefnID(pObj) == CJS_PrintParamsObj::g_nObjDefnID) {
-          if (CJS_Object* pJSObj = params[8].ToCJSObject()) {
-            if (PrintParamsObj* pprintparamsObj =
-                    (PrintParamsObj*)pJSObj->GetEmbedObject()) {
-              bUI = pprintparamsObj->bUI;
-              nStart = pprintparamsObj->nStart;
-              nEnd = pprintparamsObj->nEnd;
-              bSilent = pprintparamsObj->bSilent;
-              bShrinkToFit = pprintparamsObj->bShrinkToFit;
-              bPrintAsImage = pprintparamsObj->bPrintAsImage;
-              bReverse = pprintparamsObj->bReverse;
-              bAnnotations = pprintparamsObj->bAnnotations;
-            }
-          }
-        }
-      }
-    }
-  } else {
-    if (nlength >= 1)
-      bUI = params[0].ToBool();
-    if (nlength >= 2)
-      nStart = params[1].ToInt();
-    if (nlength >= 3)
-      nEnd = params[2].ToInt();
-    if (nlength >= 4)
-      bSilent = params[3].ToBool();
-    if (nlength >= 5)
-      bShrinkToFit = params[4].ToBool();
-    if (nlength >= 6)
-      bPrintAsImage = params[5].ToBool();
-    if (nlength >= 7)
-      bReverse = params[6].ToBool();
-    if (nlength >= 8)
-      bAnnotations = params[7].ToBool();
-  }
-
-  if (CPDFDoc_Environment* pEnv = m_pDocument->GetEnv()) {
-    pEnv->JS_docprint(bUI, nStart, nEnd, bSilent, bShrinkToFit, bPrintAsImage,
-                      bReverse, bAnnotations);
-    return TRUE;
-  }
-  return FALSE;
-}
-
-// removes the specified field from the document.
-// comment:
-// note: if the filed name is not retional, adobe is dumb for it.
-
-FX_BOOL Document::removeField(IJS_Context* cc,
-                              const std::vector<CJS_Value>& params,
-                              CJS_Value& vRet,
-                              CFX_WideString& sError) {
-  if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) ||
-        m_pDocument->GetPermissions(FPDFPERM_ANNOT_FORM)))
-    return FALSE;
-
-  CJS_Context* pContext = (CJS_Context*)cc;
-  if (params.size() != 1) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
-    return FALSE;
-  }
-
-  CFX_WideString sFieldName = params[0].ToCFXWideString();
-  CPDFSDK_InterForm* pInterForm =
-      (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
-
-  std::vector<CPDFSDK_Widget*> widgets;
-  pInterForm->GetWidgets(sFieldName, &widgets);
-
-  if (widgets.empty())
-    return TRUE;
-
-  for (CPDFSDK_Widget* pWidget : widgets) {
-    CPDF_Rect rcAnnot = pWidget->GetRect();
-    --rcAnnot.left;
-    --rcAnnot.bottom;
-    ++rcAnnot.right;
-    ++rcAnnot.top;
-
-    CFX_RectArray aRefresh;
-    aRefresh.Add(rcAnnot);
-
-    UnderlyingPageType* pPage = pWidget->GetUnderlyingPage();
-    ASSERT(pPage);
-
-    CPDFSDK_PageView* pPageView = m_pDocument->GetPageView(pPage);
-    pPageView->DeleteAnnot(pWidget);
-    pPageView->UpdateRects(aRefresh);
-  }
-  m_pDocument->SetChangeMark();
-
-  return TRUE;
-}
-
-// reset filed values within a document.
-// comment:
-// note: if the fields names r not rational, aodbe is dumb for it.
-
-FX_BOOL Document::resetForm(IJS_Context* cc,
-                            const std::vector<CJS_Value>& params,
-                            CJS_Value& vRet,
-                            CFX_WideString& sError) {
-  if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) ||
-        m_pDocument->GetPermissions(FPDFPERM_ANNOT_FORM) ||
-        m_pDocument->GetPermissions(FPDFPERM_FILL_FORM)))
-    return FALSE;
-
-  CPDFSDK_InterForm* pInterForm =
-      (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
-  CPDF_InterForm* pPDFForm = pInterForm->GetInterForm();
-  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
-  CJS_Array aName(pRuntime);
-
-  if (params.empty()) {
-    pPDFForm->ResetForm(TRUE);
-    m_pDocument->SetChangeMark();
-    return TRUE;
-  }
-
-  switch (params[0].GetType()) {
-    default:
-      aName.Attach(params[0].ToV8Array());
-      break;
-    case CJS_Value::VT_string:
-      aName.SetElement(0, params[0]);
-      break;
-  }
-
-  std::vector<CPDF_FormField*> aFields;
-  for (int i = 0, isz = aName.GetLength(); i < isz; ++i) {
-    CJS_Value valElement(pRuntime);
-    aName.GetElement(i, valElement);
-    CFX_WideString swVal = valElement.ToCFXWideString();
-    for (int j = 0, jsz = pPDFForm->CountFields(swVal); j < jsz; ++j)
-      aFields.push_back(pPDFForm->GetField(j, swVal));
-  }
-
-  if (!aFields.empty()) {
-    pPDFForm->ResetForm(aFields, TRUE, TRUE);
-    m_pDocument->SetChangeMark();
-  }
-
-  return TRUE;
-}
-
-FX_BOOL Document::saveAs(IJS_Context* cc,
-                         const std::vector<CJS_Value>& params,
-                         CJS_Value& vRet,
-                         CFX_WideString& sError) {
-  // Unsafe, not supported.
-  return TRUE;
-}
-
-FX_BOOL Document::submitForm(IJS_Context* cc,
-                             const std::vector<CJS_Value>& params,
-                             CJS_Value& vRet,
-                             CFX_WideString& sError) {
-  CJS_Context* pContext = (CJS_Context*)cc;
-  int nSize = params.size();
-  if (nSize < 1) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
-    return FALSE;
-  }
-
-  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
-  v8::Isolate* isolate = pRuntime->GetIsolate();
-  CJS_Array aFields(pRuntime);
-  CFX_WideString strURL;
-  FX_BOOL bFDF = TRUE;
-  FX_BOOL bEmpty = FALSE;
-
-  CJS_Value v = params[0];
-  if (v.GetType() == CJS_Value::VT_string) {
-    strURL = params[0].ToCFXWideString();
-    if (nSize > 1)
-      bFDF = params[1].ToBool();
-    if (nSize > 2)
-      bEmpty = params[2].ToBool();
-    if (nSize > 3)
-      aFields.Attach(params[3].ToV8Array());
-  } else if (v.GetType() == CJS_Value::VT_object) {
-    v8::Local<v8::Object> pObj = params[0].ToV8Object();
-    v8::Local<v8::Value> pValue = FXJS_GetObjectElement(isolate, pObj, L"cURL");
-    if (!pValue.IsEmpty())
-      strURL =
-          CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
-
-    pValue = FXJS_GetObjectElement(isolate, pObj, L"bFDF");
-    bFDF = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToBool();
-
-    pValue = FXJS_GetObjectElement(isolate, pObj, L"bEmpty");
-    bEmpty = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToBool();
-
-    pValue = FXJS_GetObjectElement(isolate, pObj, L"aFields");
-    aFields.Attach(
-        CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToV8Array());
-  }
-
-  CPDFSDK_InterForm* pInterForm =
-      (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
-  CPDF_InterForm* pPDFInterForm = pInterForm->GetInterForm();
-  FX_BOOL bAll = (aFields.GetLength() == 0);
-  if (bAll && bEmpty) {
-    if (pPDFInterForm->CheckRequiredFields(nullptr, true)) {
-      pRuntime->BeginBlock();
-      pInterForm->SubmitForm(strURL, FALSE);
-      pRuntime->EndBlock();
-    }
-    return TRUE;
-  }
-
-  std::vector<CPDF_FormField*> fieldObjects;
-  for (int i = 0, sz = aFields.GetLength(); i < sz; ++i) {
-    CJS_Value valName(pRuntime);
-    aFields.GetElement(i, valName);
-
-    CFX_WideString sName = valName.ToCFXWideString();
-    CPDF_InterForm* pPDFForm = pInterForm->GetInterForm();
-    for (int j = 0, jsz = pPDFForm->CountFields(sName); j < jsz; ++j) {
-      CPDF_FormField* pField = pPDFForm->GetField(j, sName);
-      if (!bEmpty && pField->GetValue().IsEmpty())
-        continue;
-
-      fieldObjects.push_back(pField);
-    }
-  }
-
-  if (pPDFInterForm->CheckRequiredFields(&fieldObjects, true)) {
-    pRuntime->BeginBlock();
-    pInterForm->SubmitFields(strURL, fieldObjects, TRUE, !bFDF);
-    pRuntime->EndBlock();
-  }
-  return TRUE;
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////////
-
-void Document::AttachDoc(CPDFSDK_Document* pDoc) {
-  m_pDocument = pDoc;
-}
-
-CPDFSDK_Document* Document::GetReaderDoc() {
-  return m_pDocument;
-}
-
-FX_BOOL Document::bookmarkRoot(IJS_Context* cc,
-                               CJS_PropValue& vp,
-                               CFX_WideString& sError) {
-  return TRUE;
-}
-
-FX_BOOL Document::mailDoc(IJS_Context* cc,
-                          const std::vector<CJS_Value>& params,
-                          CJS_Value& vRet,
-                          CFX_WideString& sError) {
-  FX_BOOL bUI = TRUE;
-  CFX_WideString cTo = L"";
-  CFX_WideString cCc = L"";
-  CFX_WideString cBcc = L"";
-  CFX_WideString cSubject = L"";
-  CFX_WideString cMsg = L"";
-
-  if (params.size() >= 1)
-    bUI = params[0].ToBool();
-  if (params.size() >= 2)
-    cTo = params[1].ToCFXWideString();
-  if (params.size() >= 3)
-    cCc = params[2].ToCFXWideString();
-  if (params.size() >= 4)
-    cBcc = params[3].ToCFXWideString();
-  if (params.size() >= 5)
-    cSubject = params[4].ToCFXWideString();
-  if (params.size() >= 6)
-    cMsg = params[5].ToCFXWideString();
-
-  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
-  v8::Isolate* isolate = pRuntime->GetIsolate();
-
-  if (params.size() >= 1 && params[0].GetType() == CJS_Value::VT_object) {
-    v8::Local<v8::Object> pObj = params[0].ToV8Object();
-
-    v8::Local<v8::Value> pValue = FXJS_GetObjectElement(isolate, pObj, L"bUI");
-    bUI = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToInt();
-
-    pValue = FXJS_GetObjectElement(isolate, pObj, L"cTo");
-    cTo = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
-
-    pValue = FXJS_GetObjectElement(isolate, pObj, L"cCc");
-    cCc = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
-
-    pValue = FXJS_GetObjectElement(isolate, pObj, L"cBcc");
-    cBcc =
-        CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
-
-    pValue = FXJS_GetObjectElement(isolate, pObj, L"cSubject");
-    cSubject =
-        CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
-
-    pValue = FXJS_GetObjectElement(isolate, pObj, L"cMsg");
-    cMsg =
-        CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
-  }
-
-  pRuntime->BeginBlock();
-  CPDFDoc_Environment* pEnv = pRuntime->GetReaderApp();
-  pEnv->JS_docmailForm(NULL, 0, bUI, cTo.c_str(), cSubject.c_str(), cCc.c_str(),
-                       cBcc.c_str(), cMsg.c_str());
-  pRuntime->EndBlock();
-
-  return TRUE;
-}
-
-FX_BOOL Document::author(IJS_Context* cc,
-                         CJS_PropValue& vp,
-                         CFX_WideString& sError) {
-  CPDF_Dictionary* pDictionary = m_pDocument->GetPDFDocument()->GetInfo();
-  if (!pDictionary)
-    return FALSE;
-
-  if (vp.IsGetting()) {
-    vp << pDictionary->GetUnicodeText("Author");
-    return TRUE;
-  } else {
-    if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY))
-      return FALSE;
-
-    CFX_WideString csAuthor;
-    vp >> csAuthor;
-    pDictionary->SetAtString("Author", PDF_EncodeText(csAuthor));
-    m_pDocument->SetChangeMark();
-    return TRUE;
-  }
-}
-
-FX_BOOL Document::info(IJS_Context* cc,
-                       CJS_PropValue& vp,
-                       CFX_WideString& sError) {
-  CPDF_Dictionary* pDictionary = m_pDocument->GetPDFDocument()->GetInfo();
-  if (!pDictionary)
-    return FALSE;
-
-  CFX_WideString cwAuthor = pDictionary->GetUnicodeText("Author");
-  CFX_WideString cwTitle = pDictionary->GetUnicodeText("Title");
-  CFX_WideString cwSubject = pDictionary->GetUnicodeText("Subject");
-  CFX_WideString cwKeywords = pDictionary->GetUnicodeText("Keywords");
-  CFX_WideString cwCreator = pDictionary->GetUnicodeText("Creator");
-  CFX_WideString cwProducer = pDictionary->GetUnicodeText("Producer");
-  CFX_WideString cwCreationDate = pDictionary->GetUnicodeText("CreationDate");
-  CFX_WideString cwModDate = pDictionary->GetUnicodeText("ModDate");
-  CFX_WideString cwTrapped = pDictionary->GetUnicodeText("Trapped");
-
-  v8::Isolate* isolate = GetIsolate(cc);
-  if (vp.IsGetting()) {
-    CJS_Context* pContext = (CJS_Context*)cc;
-    CJS_Runtime* pRuntime = pContext->GetJSRuntime();
-    v8::Local<v8::Object> pObj =
-        FXJS_NewFxDynamicObj(pRuntime->GetIsolate(), pRuntime, -1);
-    FXJS_PutObjectString(isolate, pObj, L"Author", cwAuthor.c_str());
-    FXJS_PutObjectString(isolate, pObj, L"Title", cwTitle.c_str());
-    FXJS_PutObjectString(isolate, pObj, L"Subject", cwSubject.c_str());
-    FXJS_PutObjectString(isolate, pObj, L"Keywords", cwKeywords.c_str());
-    FXJS_PutObjectString(isolate, pObj, L"Creator", cwCreator.c_str());
-    FXJS_PutObjectString(isolate, pObj, L"Producer", cwProducer.c_str());
-    FXJS_PutObjectString(isolate, pObj, L"CreationDate",
-                         cwCreationDate.c_str());
-    FXJS_PutObjectString(isolate, pObj, L"ModDate", cwModDate.c_str());
-    FXJS_PutObjectString(isolate, pObj, L"Trapped", cwTrapped.c_str());
-
-    // It's to be compatible to non-standard info dictionary.
-    for (const auto& it : *pDictionary) {
-      const CFX_ByteString& bsKey = it.first;
-      CPDF_Object* pValueObj = it.second;
-      CFX_WideString wsKey = CFX_WideString::FromUTF8(bsKey, bsKey.GetLength());
-
-      if (pValueObj->IsString() || pValueObj->IsName()) {
-        FXJS_PutObjectString(isolate, pObj, wsKey.c_str(),
-                             pValueObj->GetUnicodeText().c_str());
-      } else if (pValueObj->IsNumber()) {
-        FXJS_PutObjectNumber(isolate, pObj, wsKey.c_str(),
-                             (float)pValueObj->GetNumber());
-      } else if (pValueObj->IsBoolean()) {
-        FXJS_PutObjectBoolean(isolate, pObj, wsKey.c_str(),
-                              (bool)pValueObj->GetInteger());
-      }
-    }
-    vp << pObj;
-  }
-  return TRUE;
-}
-
-FX_BOOL Document::creationDate(IJS_Context* cc,
-                               CJS_PropValue& vp,
-                               CFX_WideString& sError) {
-  CPDF_Dictionary* pDictionary = m_pDocument->GetPDFDocument()->GetInfo();
-  if (!pDictionary)
-    return FALSE;
-
-  if (vp.IsGetting()) {
-    vp << pDictionary->GetUnicodeText("CreationDate");
-  } else {
-    if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY))
-      return FALSE;
-
-    CFX_WideString csCreationDate;
-    vp >> csCreationDate;
-    pDictionary->SetAtString("CreationDate", PDF_EncodeText(csCreationDate));
-    m_pDocument->SetChangeMark();
-  }
-  return TRUE;
-}
-
-FX_BOOL Document::creator(IJS_Context* cc,
-                          CJS_PropValue& vp,
-                          CFX_WideString& sError) {
-  CPDF_Dictionary* pDictionary = m_pDocument->GetPDFDocument()->GetInfo();
-  if (!pDictionary)
-    return FALSE;
-
-  if (vp.IsGetting()) {
-    vp << pDictionary->GetUnicodeText("Creator");
-  } else {
-    if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY))
-      return FALSE;
-
-    CFX_WideString csCreator;
-    vp >> csCreator;
-    pDictionary->SetAtString("Creator", PDF_EncodeText(csCreator));
-    m_pDocument->SetChangeMark();
-  }
-  return TRUE;
-}
-
-FX_BOOL Document::delay(IJS_Context* cc,
-                        CJS_PropValue& vp,
-                        CFX_WideString& sError) {
-  if (vp.IsGetting()) {
-    vp << m_bDelay;
-  } else {
-    if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY))
-      return FALSE;
-
-    vp >> m_bDelay;
-    if (m_bDelay) {
-      for (int i = 0, sz = m_DelayData.GetSize(); i < sz; i++)
-        delete m_DelayData.GetAt(i);
-
-      m_DelayData.RemoveAll();
-    } else {
-      CFX_ArrayTemplate<CJS_DelayData*> DelayDataToProcess;
-      for (int i = 0, sz = m_DelayData.GetSize(); i < sz; i++) {
-        if (CJS_DelayData* pData = m_DelayData.GetAt(i)) {
-          DelayDataToProcess.Add(pData);
-          m_DelayData.SetAt(i, NULL);
-        }
-      }
-      m_DelayData.RemoveAll();
-      for (int i = 0, sz = DelayDataToProcess.GetSize(); i < sz; i++) {
-        CJS_DelayData* pData = DelayDataToProcess.GetAt(i);
-        Field::DoDelay(m_pDocument, pData);
-        DelayDataToProcess.SetAt(i, NULL);
-        delete pData;
-      }
-    }
-  }
-  return TRUE;
-}
-
-FX_BOOL Document::keywords(IJS_Context* cc,
-                           CJS_PropValue& vp,
-                           CFX_WideString& sError) {
-  CPDF_Dictionary* pDictionary = m_pDocument->GetPDFDocument()->GetInfo();
-  if (!pDictionary)
-    return FALSE;
-
-  if (vp.IsGetting()) {
-    vp << pDictionary->GetUnicodeText("Keywords");
-  } else {
-    if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY))
-      return FALSE;
-
-    CFX_WideString csKeywords;
-    vp >> csKeywords;
-    pDictionary->SetAtString("Keywords", PDF_EncodeText(csKeywords));
-    m_pDocument->SetChangeMark();
-  }
-  return TRUE;
-}
-
-FX_BOOL Document::modDate(IJS_Context* cc,
-                          CJS_PropValue& vp,
-                          CFX_WideString& sError) {
-  CPDF_Dictionary* pDictionary = m_pDocument->GetPDFDocument()->GetInfo();
-  if (!pDictionary)
-    return FALSE;
-
-  if (vp.IsGetting()) {
-    vp << pDictionary->GetUnicodeText("ModDate");
-  } else {
-    if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY))
-      return FALSE;
-
-    CFX_WideString csmodDate;
-    vp >> csmodDate;
-    pDictionary->SetAtString("ModDate", PDF_EncodeText(csmodDate));
-    m_pDocument->SetChangeMark();
-  }
-  return TRUE;
-}
-
-FX_BOOL Document::producer(IJS_Context* cc,
-                           CJS_PropValue& vp,
-                           CFX_WideString& sError) {
-  CPDF_Dictionary* pDictionary = m_pDocument->GetPDFDocument()->GetInfo();
-  if (!pDictionary)
-    return FALSE;
-
-  if (vp.IsGetting()) {
-    vp << pDictionary->GetUnicodeText("Producer");
-  } else {
-    if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY))
-      return FALSE;
-
-    CFX_WideString csproducer;
-    vp >> csproducer;
-    pDictionary->SetAtString("Producer", PDF_EncodeText(csproducer));
-    m_pDocument->SetChangeMark();
-  }
-  return TRUE;
-}
-
-FX_BOOL Document::subject(IJS_Context* cc,
-                          CJS_PropValue& vp,
-                          CFX_WideString& sError) {
-  CPDF_Dictionary* pDictionary = m_pDocument->GetPDFDocument()->GetInfo();
-  if (!pDictionary)
-    return FALSE;
-
-  if (vp.IsGetting()) {
-    vp << pDictionary->GetUnicodeText("Subject");
-  } else {
-    if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY))
-      return FALSE;
-
-    CFX_WideString cssubject;
-    vp >> cssubject;
-    pDictionary->SetAtString("Subject", PDF_EncodeText(cssubject));
-    m_pDocument->SetChangeMark();
-  }
-  return TRUE;
-}
-
-FX_BOOL Document::title(IJS_Context* cc,
-                        CJS_PropValue& vp,
-                        CFX_WideString& sError) {
-  if (!m_pDocument || !m_pDocument->GetUnderlyingDocument())
-    return FALSE;
-
-  CPDF_Dictionary* pDictionary = m_pDocument->GetPDFDocument()->GetInfo();
-  if (!pDictionary)
-    return FALSE;
-
-  if (vp.IsGetting()) {
-    vp << pDictionary->GetUnicodeText("Title");
-  } else {
-    if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY))
-      return FALSE;
-
-    CFX_WideString cstitle;
-    vp >> cstitle;
-    pDictionary->SetAtString("Title", PDF_EncodeText(cstitle));
-    m_pDocument->SetChangeMark();
-  }
-  return TRUE;
-}
-
-FX_BOOL Document::numPages(IJS_Context* cc,
-                           CJS_PropValue& vp,
-                           CFX_WideString& sError) {
-  if (vp.IsSetting()) {
-    CJS_Context* pContext = static_cast<CJS_Context*>(cc);
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY);
-    return FALSE;
-  }
-  vp << m_pDocument->GetPageCount();
-  return TRUE;
-}
-
-FX_BOOL Document::external(IJS_Context* cc,
-                           CJS_PropValue& vp,
-                           CFX_WideString& sError) {
-  // In Chrome case,should always return true.
-  if (vp.IsGetting()) {
-    vp << true;
-  }
-  return TRUE;
-}
-
-FX_BOOL Document::filesize(IJS_Context* cc,
-                           CJS_PropValue& vp,
-                           CFX_WideString& sError) {
-  if (vp.IsSetting()) {
-    CJS_Context* pContext = static_cast<CJS_Context*>(cc);
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY);
-    return FALSE;
-  }
-  vp << 0;
-  return TRUE;
-}
-
-FX_BOOL Document::mouseX(IJS_Context* cc,
-                         CJS_PropValue& vp,
-                         CFX_WideString& sError) {
-  return TRUE;
-}
-
-FX_BOOL Document::mouseY(IJS_Context* cc,
-                         CJS_PropValue& vp,
-                         CFX_WideString& sError) {
-  return TRUE;
-}
-
-FX_BOOL Document::baseURL(IJS_Context* cc,
-                          CJS_PropValue& vp,
-                          CFX_WideString& sError) {
-  if (vp.IsGetting()) {
-    vp << m_cwBaseURL;
-  } else {
-    vp >> m_cwBaseURL;
-  }
-  return TRUE;
-}
-
-FX_BOOL Document::calculate(IJS_Context* cc,
-                            CJS_PropValue& vp,
-                            CFX_WideString& sError) {
-  CPDFSDK_InterForm* pInterForm =
-      (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
-
-  if (vp.IsGetting()) {
-    if (pInterForm->IsCalculateEnabled())
-      vp << true;
-    else
-      vp << false;
-  } else {
-    bool bCalculate;
-    vp >> bCalculate;
-
-    pInterForm->EnableCalculate(bCalculate);
-  }
-
-  return TRUE;
-}
-
-FX_BOOL Document::documentFileName(IJS_Context* cc,
-                                   CJS_PropValue& vp,
-                                   CFX_WideString& sError) {
-  if (vp.IsSetting()) {
-    CJS_Context* pContext = static_cast<CJS_Context*>(cc);
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY);
-    return FALSE;
-  }
-  CFX_WideString wsFilePath = m_pDocument->GetPath();
-  int32_t i = wsFilePath.GetLength() - 1;
-  for (; i >= 0; i--) {
-    if (wsFilePath.GetAt(i) == L'\\' || wsFilePath.GetAt(i) == L'/')
-      break;
-  }
-  if (i >= 0 && i < wsFilePath.GetLength() - 1) {
-    vp << (wsFilePath.GetBuffer(wsFilePath.GetLength()) + i + 1);
-  } else {
-    vp << L"";
-  }
-  return TRUE;
-}
-
-FX_BOOL Document::path(IJS_Context* cc,
-                       CJS_PropValue& vp,
-                       CFX_WideString& sError) {
-  if (vp.IsSetting()) {
-    CJS_Context* pContext = static_cast<CJS_Context*>(cc);
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY);
-    return FALSE;
-  }
-  vp << app::SysPathToPDFPath(m_pDocument->GetPath());
-  return TRUE;
-}
-
-FX_BOOL Document::pageWindowRect(IJS_Context* cc,
-                                 CJS_PropValue& vp,
-                                 CFX_WideString& sError) {
-  return TRUE;
-}
-
-FX_BOOL Document::layout(IJS_Context* cc,
-                         CJS_PropValue& vp,
-                         CFX_WideString& sError) {
-  return TRUE;
-}
-
-FX_BOOL Document::addLink(IJS_Context* cc,
-                          const std::vector<CJS_Value>& params,
-                          CJS_Value& vRet,
-                          CFX_WideString& sError) {
-  return TRUE;
-}
-
-FX_BOOL Document::closeDoc(IJS_Context* cc,
-                           const std::vector<CJS_Value>& params,
-                           CJS_Value& vRet,
-                           CFX_WideString& sError) {
-  return TRUE;
-}
-
-FX_BOOL Document::getPageBox(IJS_Context* cc,
-                             const std::vector<CJS_Value>& params,
-                             CJS_Value& vRet,
-                             CFX_WideString& sError) {
-  return TRUE;
-}
-
-FX_BOOL Document::getAnnot(IJS_Context* cc,
-                           const std::vector<CJS_Value>& params,
-                           CJS_Value& vRet,
-                           CFX_WideString& sError) {
-  return TRUE;
-}
-
-FX_BOOL Document::getAnnots(IJS_Context* cc,
-                            const std::vector<CJS_Value>& params,
-                            CJS_Value& vRet,
-                            CFX_WideString& sError) {
-  vRet.SetNull();
-  return TRUE;
-}
-
-FX_BOOL Document::getAnnot3D(IJS_Context* cc,
-                             const std::vector<CJS_Value>& params,
-                             CJS_Value& vRet,
-                             CFX_WideString& sError) {
-  vRet.SetNull();
-  return TRUE;
-}
-
-FX_BOOL Document::getAnnots3D(IJS_Context* cc,
-                              const std::vector<CJS_Value>& params,
-                              CJS_Value& vRet,
-                              CFX_WideString& sError) {
-  vRet = CJS_Value::VT_undefined;
-  return TRUE;
-}
-
-FX_BOOL Document::getOCGs(IJS_Context* cc,
-                          const std::vector<CJS_Value>& params,
-                          CJS_Value& vRet,
-                          CFX_WideString& sError) {
-  return TRUE;
-}
-
-FX_BOOL Document::getLinks(IJS_Context* cc,
-                           const std::vector<CJS_Value>& params,
-                           CJS_Value& vRet,
-                           CFX_WideString& sError) {
-  return TRUE;
-}
-
-bool Document::IsEnclosedInRect(CFX_FloatRect rect, CFX_FloatRect LinkRect) {
-  return (rect.left <= LinkRect.left && rect.top <= LinkRect.top &&
-          rect.right >= LinkRect.right && rect.bottom >= LinkRect.bottom);
-}
-
-FX_BOOL Document::addIcon(IJS_Context* cc,
-                          const std::vector<CJS_Value>& params,
-                          CJS_Value& vRet,
-                          CFX_WideString& sError) {
-  CJS_Context* pContext = (CJS_Context*)cc;
-  if (params.size() != 2) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
-    return FALSE;
-  }
-  CFX_WideString swIconName = params[0].ToCFXWideString();
-
-  if (params[1].GetType() != CJS_Value::VT_object) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSTYPEERROR);
-    return FALSE;
-  }
-
-  v8::Local<v8::Object> pJSIcon = params[1].ToV8Object();
-  if (FXJS_GetObjDefnID(pJSIcon) != CJS_Icon::g_nObjDefnID) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSTYPEERROR);
-    return FALSE;
-  }
-
-  CJS_EmbedObj* pEmbedObj = params[1].ToCJSObject()->GetEmbedObject();
-  if (!pEmbedObj) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSTYPEERROR);
-    return FALSE;
-  }
-
-  m_IconList.push_back(std::unique_ptr<IconElement>(
-      new IconElement(swIconName, (Icon*)pEmbedObj)));
-  return TRUE;
-}
-
-FX_BOOL Document::icons(IJS_Context* cc,
-                        CJS_PropValue& vp,
-                        CFX_WideString& sError) {
-  if (vp.IsSetting()) {
-    CJS_Context* pContext = static_cast<CJS_Context*>(cc);
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY);
-    return FALSE;
-  }
-
-  if (m_IconList.empty()) {
-    vp.SetNull();
-    return TRUE;
-  }
-
-  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
-  CJS_Array Icons(pRuntime);
-
-  int i = 0;
-  for (const auto& pIconElement : m_IconList) {
-    v8::Local<v8::Object> pObj = FXJS_NewFxDynamicObj(
-        pRuntime->GetIsolate(), pRuntime, CJS_Icon::g_nObjDefnID);
-    if (pObj.IsEmpty())
-      return FALSE;
-
-    CJS_Icon* pJS_Icon = (CJS_Icon*)FXJS_GetPrivate(m_isolate, pObj);
-    if (!pJS_Icon)
-      return FALSE;
-
-    Icon* pIcon = (Icon*)pJS_Icon->GetEmbedObject();
-    if (!pIcon)
-      return FALSE;
-
-    pIcon->SetStream(pIconElement->IconStream->GetStream());
-    pIcon->SetIconName(pIconElement->IconName);
-    Icons.SetElement(i++, CJS_Value(pRuntime, pJS_Icon));
-  }
-
-  vp << Icons;
-  return TRUE;
-}
-
-FX_BOOL Document::getIcon(IJS_Context* cc,
-                          const std::vector<CJS_Value>& params,
-                          CJS_Value& vRet,
-                          CFX_WideString& sError) {
-  CJS_Context* pContext = (CJS_Context*)cc;
-  if (params.size() != 1) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
-    return FALSE;
-  }
-
-  if (m_IconList.empty())
-    return FALSE;
-
-  CFX_WideString swIconName = params[0].ToCFXWideString();
-  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
-
-  for (const auto& pIconElement : m_IconList) {
-    if (pIconElement->IconName == swIconName) {
-      Icon* pRetIcon = pIconElement->IconStream;
-
-      v8::Local<v8::Object> pObj = FXJS_NewFxDynamicObj(
-          pRuntime->GetIsolate(), pRuntime, CJS_Icon::g_nObjDefnID);
-      if (pObj.IsEmpty())
-        return FALSE;
-
-      CJS_Icon* pJS_Icon = (CJS_Icon*)FXJS_GetPrivate(m_isolate, pObj);
-      if (!pJS_Icon)
-        return FALSE;
-
-      Icon* pIcon = (Icon*)pJS_Icon->GetEmbedObject();
-      if (!pIcon)
-        return FALSE;
-
-      pIcon->SetIconName(swIconName);
-      pIcon->SetStream(pRetIcon->GetStream());
-      vRet = pJS_Icon;
-      return TRUE;
-    }
-  }
-
-  return FALSE;
-}
-
-FX_BOOL Document::removeIcon(IJS_Context* cc,
-                             const std::vector<CJS_Value>& params,
-                             CJS_Value& vRet,
-                             CFX_WideString& sError) {
-  // Unsafe, no supported.
-  return TRUE;
-}
-
-FX_BOOL Document::createDataObject(IJS_Context* cc,
-                                   const std::vector<CJS_Value>& params,
-                                   CJS_Value& vRet,
-                                   CFX_WideString& sError) {
-  // Unsafe, not implemented.
-  return TRUE;
-}
-
-FX_BOOL Document::media(IJS_Context* cc,
-                        CJS_PropValue& vp,
-                        CFX_WideString& sError) {
-  return TRUE;
-}
-
-FX_BOOL Document::calculateNow(IJS_Context* cc,
-                               const std::vector<CJS_Value>& params,
-                               CJS_Value& vRet,
-                               CFX_WideString& sError) {
-  if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) ||
-        m_pDocument->GetPermissions(FPDFPERM_ANNOT_FORM) ||
-        m_pDocument->GetPermissions(FPDFPERM_FILL_FORM)))
-    return FALSE;
-
-  CPDFSDK_InterForm* pInterForm =
-      (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
-  pInterForm->OnCalculate();
-  return TRUE;
-}
-
-FX_BOOL Document::Collab(IJS_Context* cc,
-                         CJS_PropValue& vp,
-                         CFX_WideString& sError) {
-  return TRUE;
-}
-
-FX_BOOL Document::getPageNthWord(IJS_Context* cc,
-                                 const std::vector<CJS_Value>& params,
-                                 CJS_Value& vRet,
-                                 CFX_WideString& sError) {
-  if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS))
-    return FALSE;
-
-  int nPageNo = params.size() > 0 ? params[0].ToInt() : 0;
-  int nWordNo = params.size() > 1 ? params[1].ToInt() : 0;
-  bool bStrip = params.size() > 2 ? params[2].ToBool() : true;
-
-  CPDF_Document* pDocument = m_pDocument->GetPDFDocument();
-  if (!pDocument)
-    return FALSE;
-
-  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
-  if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount()) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSVALUEERROR);
-    return FALSE;
-  }
-
-  CPDF_Dictionary* pPageDict = pDocument->GetPage(nPageNo);
-  if (!pPageDict)
-    return FALSE;
-
-  CPDF_Page page;
-  page.Load(pDocument, pPageDict);
-  page.StartParse();
-  page.ParseContent();
-
-  FX_POSITION pos = page.GetFirstObjectPosition();
-
-  int nWords = 0;
-
-  CFX_WideString swRet;
-
-  while (pos) {
-    if (CPDF_PageObject* pPageObj = page.GetNextObject(pos)) {
-      if (pPageObj->m_Type == PDFPAGE_TEXT) {
-        int nObjWords = CountWords((CPDF_TextObject*)pPageObj);
-
-        if (nWords + nObjWords >= nWordNo) {
-          swRet = GetObjWordStr((CPDF_TextObject*)pPageObj, nWordNo - nWords);
-          break;
-        }
-
-        nWords += nObjWords;
-      }
-    }
-  }
-
-  if (bStrip) {
-    swRet.TrimLeft();
-    swRet.TrimRight();
-  }
-
-  vRet = swRet.c_str();
-  return TRUE;
-}
-
-FX_BOOL Document::getPageNthWordQuads(IJS_Context* cc,
-                                      const std::vector<CJS_Value>& params,
-                                      CJS_Value& vRet,
-                                      CFX_WideString& sError) {
-  if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS))
-    return FALSE;
-
-  return FALSE;
-}
-
-FX_BOOL Document::getPageNumWords(IJS_Context* cc,
-                                  const std::vector<CJS_Value>& params,
-                                  CJS_Value& vRet,
-                                  CFX_WideString& sError) {
-  if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS))
-    return FALSE;
-
-  int nPageNo = params.size() > 0 ? params[0].ToInt() : 0;
-
-  CPDF_Document* pDocument = m_pDocument->GetPDFDocument();
-  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
-  if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount()) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSVALUEERROR);
-    return FALSE;
-  }
-
-  CPDF_Dictionary* pPageDict = pDocument->GetPage(nPageNo);
-  if (!pPageDict)
-    return FALSE;
-
-  CPDF_Page page;
-  page.Load(pDocument, pPageDict);
-  page.StartParse();
-  page.ParseContent();
-
-  FX_POSITION pos = page.GetFirstObjectPosition();
-
-  int nWords = 0;
-
-  while (pos) {
-    if (CPDF_PageObject* pPageObj = page.GetNextObject(pos)) {
-      if (pPageObj->m_Type == PDFPAGE_TEXT) {
-        CPDF_TextObject* pTextObj = (CPDF_TextObject*)pPageObj;
-        nWords += CountWords(pTextObj);
-      }
-    }
-  }
-
-  vRet = nWords;
-
-  return TRUE;
-}
-
-FX_BOOL Document::getPrintParams(IJS_Context* cc,
-                                 const std::vector<CJS_Value>& params,
-                                 CJS_Value& vRet,
-                                 CFX_WideString& sError) {
-  CJS_Context* pContext = (CJS_Context*)cc;
-  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
-  v8::Local<v8::Object> pRetObj = FXJS_NewFxDynamicObj(
-      pRuntime->GetIsolate(), pRuntime, CJS_PrintParamsObj::g_nObjDefnID);
-
-  // Not implemented yet.
-
-  vRet = pRetObj;
-  return TRUE;
-}
-
-#define ISLATINWORD(u) (u != 0x20 && u <= 0x28FF)
-
-int Document::CountWords(CPDF_TextObject* pTextObj) {
-  if (!pTextObj)
-    return 0;
-
-  int nWords = 0;
-
-  CPDF_Font* pFont = pTextObj->GetFont();
-  if (!pFont)
-    return 0;
-
-  FX_BOOL bIsLatin = FALSE;
-
-  for (int i = 0, sz = pTextObj->CountChars(); i < sz; i++) {
-    FX_DWORD charcode = -1;
-    FX_FLOAT kerning;
-
-    pTextObj->GetCharInfo(i, charcode, kerning);
-    CFX_WideString swUnicode = pFont->UnicodeFromCharCode(charcode);
-
-    FX_WORD unicode = 0;
-    if (swUnicode.GetLength() > 0)
-      unicode = swUnicode[0];
-
-    if (ISLATINWORD(unicode) && bIsLatin)
-      continue;
-
-    bIsLatin = ISLATINWORD(unicode);
-    if (unicode != 0x20)
-      nWords++;
-  }
-
-  return nWords;
-}
-
-CFX_WideString Document::GetObjWordStr(CPDF_TextObject* pTextObj,
-                                       int nWordIndex) {
-  CFX_WideString swRet;
-
-  CPDF_Font* pFont = pTextObj->GetFont();
-  if (!pFont)
-    return L"";
-
-  int nWords = 0;
-  FX_BOOL bIsLatin = FALSE;
-
-  for (int i = 0, sz = pTextObj->CountChars(); i < sz; i++) {
-    FX_DWORD charcode = -1;
-    FX_FLOAT kerning;
-
-    pTextObj->GetCharInfo(i, charcode, kerning);
-    CFX_WideString swUnicode = pFont->UnicodeFromCharCode(charcode);
-
-    FX_WORD unicode = 0;
-    if (swUnicode.GetLength() > 0)
-      unicode = swUnicode[0];
-
-    if (ISLATINWORD(unicode) && bIsLatin) {
-    } else {
-      bIsLatin = ISLATINWORD(unicode);
-      if (unicode != 0x20)
-        nWords++;
-    }
-
-    if (nWords - 1 == nWordIndex)
-      swRet += unicode;
-  }
-
-  return swRet;
-}
-
-FX_BOOL Document::zoom(IJS_Context* cc,
-                       CJS_PropValue& vp,
-                       CFX_WideString& sError) {
-  return TRUE;
-}
-
-/**
-(none,  NoVary)
-(fitP,  FitPage)
-(fitW,  FitWidth)
-(fitH,  FitHeight)
-(fitV,  FitVisibleWidth)
-(pref,  Preferred)
-(refW,  ReflowWidth)
-*/
-
-FX_BOOL Document::zoomType(IJS_Context* cc,
-                           CJS_PropValue& vp,
-                           CFX_WideString& sError) {
-  return TRUE;
-}
-
-FX_BOOL Document::deletePages(IJS_Context* cc,
-                              const std::vector<CJS_Value>& params,
-                              CJS_Value& vRet,
-                              CFX_WideString& sError) {
-  // Unsafe, no supported.
-  return TRUE;
-}
-
-FX_BOOL Document::extractPages(IJS_Context* cc,
-                               const std::vector<CJS_Value>& params,
-                               CJS_Value& vRet,
-                               CFX_WideString& sError) {
-  // Unsafe, not supported.
-  return TRUE;
-}
-
-FX_BOOL Document::insertPages(IJS_Context* cc,
-                              const std::vector<CJS_Value>& params,
-                              CJS_Value& vRet,
-                              CFX_WideString& sError) {
-  // Unsafe, not supported.
-  return TRUE;
-}
-
-FX_BOOL Document::replacePages(IJS_Context* cc,
-                               const std::vector<CJS_Value>& params,
-                               CJS_Value& vRet,
-                               CFX_WideString& sError) {
-  // Unsafe, not supported.
-  return TRUE;
-}
-
-FX_BOOL Document::getURL(IJS_Context* cc,
-                         const std::vector<CJS_Value>& params,
-                         CJS_Value& vRet,
-                         CFX_WideString& sError) {
-  // Unsafe, not supported.
-  return TRUE;
-}
-
-void Document::AddDelayData(CJS_DelayData* pData) {
-  m_DelayData.Add(pData);
-}
-
-void Document::DoFieldDelay(const CFX_WideString& sFieldName,
-                            int nControlIndex) {
-  CFX_DWordArray DelArray;
-  CFX_ArrayTemplate<CJS_DelayData*> DelayDataForFieldAndControlIndex;
-
-  for (int i = 0, sz = m_DelayData.GetSize(); i < sz; i++) {
-    if (CJS_DelayData* pData = m_DelayData.GetAt(i)) {
-      if (pData->sFieldName == sFieldName &&
-          pData->nControlIndex == nControlIndex) {
-        DelayDataForFieldAndControlIndex.Add(pData);
-        m_DelayData.SetAt(i, NULL);
-        DelArray.Add(i);
-      }
-    }
-  }
-
-  for (int j = DelArray.GetSize() - 1; j >= 0; j--) {
-    m_DelayData.RemoveAt(DelArray[j]);
-  }
-
-  for (int i = 0, sz = DelayDataForFieldAndControlIndex.GetSize(); i < sz;
-       i++) {
-    CJS_DelayData* pData = DelayDataForFieldAndControlIndex.GetAt(i);
-    Field::DoDelay(m_pDocument, pData);
-    DelayDataForFieldAndControlIndex.SetAt(i, NULL);
-    delete pData;
-  }
-}
-
-CJS_Document* Document::GetCJSDoc() const {
-  return static_cast<CJS_Document*>(m_pJSObject);
-}
diff --git a/fpdfsdk/src/javascript/Document.h b/fpdfsdk/src/javascript/Document.h
deleted file mode 100644
index 2295fd7..0000000
--- a/fpdfsdk/src/javascript/Document.h
+++ /dev/null
@@ -1,364 +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_SRC_JAVASCRIPT_DOCUMENT_H_
-#define FPDFSDK_SRC_JAVASCRIPT_DOCUMENT_H_
-
-#include <list>
-#include <memory>
-
-#include "JS_Define.h"
-
-class PrintParamsObj : public CJS_EmbedObj {
- public:
-  PrintParamsObj(CJS_Object* pJSObject);
-  ~PrintParamsObj() override {}
-
- public:
-  FX_BOOL bUI;
-  int nStart;
-  int nEnd;
-  FX_BOOL bSilent;
-  FX_BOOL bShrinkToFit;
-  FX_BOOL bPrintAsImage;
-  FX_BOOL bReverse;
-  FX_BOOL bAnnotations;
-};
-
-class CJS_PrintParamsObj : public CJS_Object {
- public:
-  CJS_PrintParamsObj(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
-  ~CJS_PrintParamsObj() override {}
-
-  DECLARE_JS_CLASS();
-};
-
-class Icon;
-class Field;
-
-struct IconElement {
-  IconElement(const CFX_WideString& name, Icon* stream)
-      : IconName(name), IconStream(stream) {}
-
-  CFX_WideString IconName;
-  Icon* IconStream;
-};
-
-struct CJS_DelayData;
-struct CJS_DelayAnnot;
-struct CJS_AnnotObj;
-
-class Document : public CJS_EmbedObj {
- public:
-  Document(CJS_Object* pJSObject);
-  ~Document() override;
-
-  FX_BOOL ADBE(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL author(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL baseURL(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL bookmarkRoot(IJS_Context* cc,
-                       CJS_PropValue& vp,
-                       CFX_WideString& sError);
-  FX_BOOL calculate(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL Collab(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL creationDate(IJS_Context* cc,
-                       CJS_PropValue& vp,
-                       CFX_WideString& sError);
-  FX_BOOL creator(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL delay(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL dirty(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL documentFileName(IJS_Context* cc,
-                           CJS_PropValue& vp,
-                           CFX_WideString& sError);
-  FX_BOOL external(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL filesize(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL icons(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL info(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL keywords(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL layout(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL media(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL modDate(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL mouseX(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL mouseY(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL numFields(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL numPages(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL pageNum(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL pageWindowRect(IJS_Context* cc,
-                         CJS_PropValue& vp,
-                         CFX_WideString& sError);
-  FX_BOOL path(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL producer(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL subject(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL title(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL zoom(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL zoomType(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-
-  FX_BOOL addAnnot(IJS_Context* cc,
-                   const std::vector<CJS_Value>& params,
-                   CJS_Value& vRet,
-                   CFX_WideString& sError);
-  FX_BOOL addField(IJS_Context* cc,
-                   const std::vector<CJS_Value>& params,
-                   CJS_Value& vRet,
-                   CFX_WideString& sError);
-  FX_BOOL addLink(IJS_Context* cc,
-                  const std::vector<CJS_Value>& params,
-                  CJS_Value& vRet,
-                  CFX_WideString& sError);
-  FX_BOOL addIcon(IJS_Context* cc,
-                  const std::vector<CJS_Value>& params,
-                  CJS_Value& vRet,
-                  CFX_WideString& sError);
-  FX_BOOL calculateNow(IJS_Context* cc,
-                       const std::vector<CJS_Value>& params,
-                       CJS_Value& vRet,
-                       CFX_WideString& sError);
-  FX_BOOL closeDoc(IJS_Context* cc,
-                   const std::vector<CJS_Value>& params,
-                   CJS_Value& vRet,
-                   CFX_WideString& sError);
-  FX_BOOL createDataObject(IJS_Context* cc,
-                           const std::vector<CJS_Value>& params,
-                           CJS_Value& vRet,
-                           CFX_WideString& sError);
-  FX_BOOL deletePages(IJS_Context* cc,
-                      const std::vector<CJS_Value>& params,
-                      CJS_Value& vRet,
-                      CFX_WideString& sError);
-  FX_BOOL exportAsText(IJS_Context* cc,
-                       const std::vector<CJS_Value>& params,
-                       CJS_Value& vRet,
-                       CFX_WideString& sError);
-  FX_BOOL exportAsFDF(IJS_Context* cc,
-                      const std::vector<CJS_Value>& params,
-                      CJS_Value& vRet,
-                      CFX_WideString& sError);
-  FX_BOOL exportAsXFDF(IJS_Context* cc,
-                       const std::vector<CJS_Value>& params,
-                       CJS_Value& vRet,
-                       CFX_WideString& sError);
-  FX_BOOL extractPages(IJS_Context* cc,
-                       const std::vector<CJS_Value>& params,
-                       CJS_Value& vRet,
-                       CFX_WideString& sError);
-  FX_BOOL getAnnot(IJS_Context* cc,
-                   const std::vector<CJS_Value>& params,
-                   CJS_Value& vRet,
-                   CFX_WideString& sError);
-  FX_BOOL getAnnots(IJS_Context* cc,
-                    const std::vector<CJS_Value>& params,
-                    CJS_Value& vRet,
-                    CFX_WideString& sError);
-  FX_BOOL getAnnot3D(IJS_Context* cc,
-                     const std::vector<CJS_Value>& params,
-                     CJS_Value& vRet,
-                     CFX_WideString& sError);
-  FX_BOOL getAnnots3D(IJS_Context* cc,
-                      const std::vector<CJS_Value>& params,
-                      CJS_Value& vRet,
-                      CFX_WideString& sError);
-  FX_BOOL getField(IJS_Context* cc,
-                   const std::vector<CJS_Value>& params,
-                   CJS_Value& vRet,
-                   CFX_WideString& sError);
-  FX_BOOL getIcon(IJS_Context* cc,
-                  const std::vector<CJS_Value>& params,
-                  CJS_Value& vRet,
-                  CFX_WideString& sError);
-  FX_BOOL getLinks(IJS_Context* cc,
-                   const std::vector<CJS_Value>& params,
-                   CJS_Value& vRet,
-                   CFX_WideString& sError);
-  FX_BOOL getNthFieldName(IJS_Context* cc,
-                          const std::vector<CJS_Value>& params,
-                          CJS_Value& vRet,
-                          CFX_WideString& sError);
-  FX_BOOL getOCGs(IJS_Context* cc,
-                  const std::vector<CJS_Value>& params,
-                  CJS_Value& vRet,
-                  CFX_WideString& sError);
-  FX_BOOL getPageBox(IJS_Context* cc,
-                     const std::vector<CJS_Value>& params,
-                     CJS_Value& vRet,
-                     CFX_WideString& sError);
-  FX_BOOL getPageNthWord(IJS_Context* cc,
-                         const std::vector<CJS_Value>& params,
-                         CJS_Value& vRet,
-                         CFX_WideString& sError);
-  FX_BOOL getPageNthWordQuads(IJS_Context* cc,
-                              const std::vector<CJS_Value>& params,
-                              CJS_Value& vRet,
-                              CFX_WideString& sError);
-  FX_BOOL getPageNumWords(IJS_Context* cc,
-                          const std::vector<CJS_Value>& params,
-                          CJS_Value& vRet,
-                          CFX_WideString& sError);
-  FX_BOOL getPrintParams(IJS_Context* cc,
-                         const std::vector<CJS_Value>& params,
-                         CJS_Value& vRet,
-                         CFX_WideString& sError);
-  FX_BOOL getURL(IJS_Context* cc,
-                 const std::vector<CJS_Value>& params,
-                 CJS_Value& vRet,
-                 CFX_WideString& sError);
-  FX_BOOL importAnFDF(IJS_Context* cc,
-                      const std::vector<CJS_Value>& params,
-                      CJS_Value& vRet,
-                      CFX_WideString& sError);
-  FX_BOOL importAnXFDF(IJS_Context* cc,
-                       const std::vector<CJS_Value>& params,
-                       CJS_Value& vRet,
-                       CFX_WideString& sError);
-  FX_BOOL importTextData(IJS_Context* cc,
-                         const std::vector<CJS_Value>& params,
-                         CJS_Value& vRet,
-                         CFX_WideString& sError);
-  FX_BOOL insertPages(IJS_Context* cc,
-                      const std::vector<CJS_Value>& params,
-                      CJS_Value& vRet,
-                      CFX_WideString& sError);
-  FX_BOOL mailForm(IJS_Context* cc,
-                   const std::vector<CJS_Value>& params,
-                   CJS_Value& vRet,
-                   CFX_WideString& sError);
-  FX_BOOL print(IJS_Context* cc,
-                const std::vector<CJS_Value>& params,
-                CJS_Value& vRet,
-                CFX_WideString& sError);
-  FX_BOOL removeField(IJS_Context* cc,
-                      const std::vector<CJS_Value>& params,
-                      CJS_Value& vRet,
-                      CFX_WideString& sError);
-  FX_BOOL replacePages(IJS_Context* cc,
-                       const std::vector<CJS_Value>& params,
-                       CJS_Value& vRet,
-                       CFX_WideString& sError);
-  FX_BOOL resetForm(IJS_Context* cc,
-                    const std::vector<CJS_Value>& params,
-                    CJS_Value& vRet,
-                    CFX_WideString& sError);
-  FX_BOOL saveAs(IJS_Context* cc,
-                 const std::vector<CJS_Value>& params,
-                 CJS_Value& vRet,
-                 CFX_WideString& sError);
-  FX_BOOL submitForm(IJS_Context* cc,
-                     const std::vector<CJS_Value>& params,
-                     CJS_Value& vRet,
-                     CFX_WideString& sError);
-  FX_BOOL mailDoc(IJS_Context* cc,
-                  const std::vector<CJS_Value>& params,
-                  CJS_Value& vRet,
-                  CFX_WideString& sError);
-  FX_BOOL removeIcon(IJS_Context* cc,
-                     const std::vector<CJS_Value>& params,
-                     CJS_Value& vRet,
-                     CFX_WideString& sError);
-
-  void AttachDoc(CPDFSDK_Document* pDoc);
-  CPDFSDK_Document* GetReaderDoc();
-  void AddDelayData(CJS_DelayData* pData);
-  void DoFieldDelay(const CFX_WideString& sFieldName, int nControlIndex);
-  void SetIsolate(v8::Isolate* isolate) { m_isolate = isolate; }
-  CJS_Document* GetCJSDoc() const;
-
- private:
-  bool IsEnclosedInRect(CFX_FloatRect rect, CFX_FloatRect LinkRect);
-  int CountWords(CPDF_TextObject* pTextObj);
-  CFX_WideString GetObjWordStr(CPDF_TextObject* pTextObj, int nWordIndex);
-
-  v8::Isolate* m_isolate;
-  std::list<std::unique_ptr<IconElement>> m_IconList;
-  CPDFSDK_Document* m_pDocument;
-  CFX_WideString m_cwBaseURL;
-  bool m_bDelay;
-  CFX_ArrayTemplate<CJS_DelayData*> m_DelayData;
-};
-
-class CJS_Document : public CJS_Object {
- public:
-  explicit CJS_Document(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
-  ~CJS_Document() override {}
-
-  // CJS_Object
-  void InitInstance(IJS_Runtime* pIRuntime) override;
-
-  DECLARE_JS_CLASS();
-
-  JS_STATIC_PROP(ADBE, Document);
-  JS_STATIC_PROP(author, Document);
-  JS_STATIC_PROP(baseURL, Document);
-  JS_STATIC_PROP(bookmarkRoot, Document);
-  JS_STATIC_PROP(calculate, Document);
-  JS_STATIC_PROP(Collab, Document);
-  JS_STATIC_PROP(creationDate, Document);
-  JS_STATIC_PROP(creator, Document);
-  JS_STATIC_PROP(delay, Document);
-  JS_STATIC_PROP(dirty, Document);
-  JS_STATIC_PROP(documentFileName, Document);
-  JS_STATIC_PROP(external, Document);
-  JS_STATIC_PROP(filesize, Document);
-  JS_STATIC_PROP(icons, Document);
-  JS_STATIC_PROP(info, Document);
-  JS_STATIC_PROP(keywords, Document);
-  JS_STATIC_PROP(layout, Document);
-  JS_STATIC_PROP(media, Document);
-  JS_STATIC_PROP(modDate, Document);
-  JS_STATIC_PROP(mouseX, Document);
-  JS_STATIC_PROP(mouseY, Document);
-  JS_STATIC_PROP(numFields, Document);
-  JS_STATIC_PROP(numPages, Document);
-  JS_STATIC_PROP(pageNum, Document);
-  JS_STATIC_PROP(pageWindowRect, Document);
-  JS_STATIC_PROP(path, Document);
-  JS_STATIC_PROP(producer, Document);
-  JS_STATIC_PROP(subject, Document);
-  JS_STATIC_PROP(title, Document);
-  JS_STATIC_PROP(zoom, Document);
-  JS_STATIC_PROP(zoomType, Document);
-
-  JS_STATIC_METHOD(addAnnot, Document);
-  JS_STATIC_METHOD(addField, Document);
-  JS_STATIC_METHOD(addLink, Document);
-  JS_STATIC_METHOD(addIcon, Document);
-  JS_STATIC_METHOD(calculateNow, Document);
-  JS_STATIC_METHOD(closeDoc, Document);
-  JS_STATIC_METHOD(createDataObject, Document);
-  JS_STATIC_METHOD(deletePages, Document);
-  JS_STATIC_METHOD(exportAsText, Document);
-  JS_STATIC_METHOD(exportAsFDF, Document);
-  JS_STATIC_METHOD(exportAsXFDF, Document);
-  JS_STATIC_METHOD(extractPages, Document);
-  JS_STATIC_METHOD(getAnnot, Document);
-  JS_STATIC_METHOD(getAnnots, Document);
-  JS_STATIC_METHOD(getAnnot3D, Document);
-  JS_STATIC_METHOD(getAnnots3D, Document);
-  JS_STATIC_METHOD(getField, Document);
-  JS_STATIC_METHOD(getIcon, Document);
-  JS_STATIC_METHOD(getLinks, Document);
-  JS_STATIC_METHOD(getNthFieldName, Document);
-  JS_STATIC_METHOD(getOCGs, Document);
-  JS_STATIC_METHOD(getPageBox, Document);
-  JS_STATIC_METHOD(getPageNthWord, Document);
-  JS_STATIC_METHOD(getPageNthWordQuads, Document);
-  JS_STATIC_METHOD(getPageNumWords, Document);
-  JS_STATIC_METHOD(getPrintParams, Document);
-  JS_STATIC_METHOD(getURL, Document);
-  JS_STATIC_METHOD(importAnFDF, Document);
-  JS_STATIC_METHOD(importAnXFDF, Document);
-  JS_STATIC_METHOD(importTextData, Document);
-  JS_STATIC_METHOD(insertPages, Document);
-  JS_STATIC_METHOD(mailForm, Document);
-  JS_STATIC_METHOD(print, Document);
-  JS_STATIC_METHOD(removeField, Document);
-  JS_STATIC_METHOD(replacePages, Document);
-  JS_STATIC_METHOD(removeIcon, Document);
-  JS_STATIC_METHOD(resetForm, Document);
-  JS_STATIC_METHOD(saveAs, Document);
-  JS_STATIC_METHOD(submitForm, Document);
-  JS_STATIC_METHOD(mailDoc, Document);
-};
-
-#endif  // FPDFSDK_SRC_JAVASCRIPT_DOCUMENT_H_
diff --git a/fpdfsdk/src/javascript/Field.cpp b/fpdfsdk/src/javascript/Field.cpp
deleted file mode 100644
index 7baefd1..0000000
--- a/fpdfsdk/src/javascript/Field.cpp
+++ /dev/null
@@ -1,3628 +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
-
-#include "Field.h"
-
-#include "Document.h"
-#include "Icon.h"
-#include "JS_Context.h"
-#include "JS_Define.h"
-#include "JS_EventHandler.h"
-#include "JS_Object.h"
-#include "JS_Runtime.h"
-#include "JS_Value.h"
-#include "PublicMethods.h"
-#include "color.h"
-#include "fpdfsdk/include/fsdk_mgr.h"  // For CPDFDoc_Environment.
-#include "fpdfsdk/include/javascript/IJavaScript.h"
-
-BEGIN_JS_STATIC_CONST(CJS_Field)
-END_JS_STATIC_CONST()
-
-BEGIN_JS_STATIC_PROP(CJS_Field)
-JS_STATIC_PROP_ENTRY(alignment)
-JS_STATIC_PROP_ENTRY(borderStyle)
-JS_STATIC_PROP_ENTRY(buttonAlignX)
-JS_STATIC_PROP_ENTRY(buttonAlignY)
-JS_STATIC_PROP_ENTRY(buttonFitBounds)
-JS_STATIC_PROP_ENTRY(buttonPosition)
-JS_STATIC_PROP_ENTRY(buttonScaleHow)
-JS_STATIC_PROP_ENTRY(buttonScaleWhen)
-JS_STATIC_PROP_ENTRY(calcOrderIndex)
-JS_STATIC_PROP_ENTRY(charLimit)
-JS_STATIC_PROP_ENTRY(comb)
-JS_STATIC_PROP_ENTRY(commitOnSelChange)
-JS_STATIC_PROP_ENTRY(currentValueIndices)
-JS_STATIC_PROP_ENTRY(defaultStyle)
-JS_STATIC_PROP_ENTRY(defaultValue)
-JS_STATIC_PROP_ENTRY(doNotScroll)
-JS_STATIC_PROP_ENTRY(doNotSpellCheck)
-JS_STATIC_PROP_ENTRY(delay)
-JS_STATIC_PROP_ENTRY(display)
-JS_STATIC_PROP_ENTRY(doc)
-JS_STATIC_PROP_ENTRY(editable)
-JS_STATIC_PROP_ENTRY(exportValues)
-JS_STATIC_PROP_ENTRY(hidden)
-JS_STATIC_PROP_ENTRY(fileSelect)
-JS_STATIC_PROP_ENTRY(fillColor)
-JS_STATIC_PROP_ENTRY(lineWidth)
-JS_STATIC_PROP_ENTRY(highlight)
-JS_STATIC_PROP_ENTRY(multiline)
-JS_STATIC_PROP_ENTRY(multipleSelection)
-JS_STATIC_PROP_ENTRY(name)
-JS_STATIC_PROP_ENTRY(numItems)
-JS_STATIC_PROP_ENTRY(page)
-JS_STATIC_PROP_ENTRY(password)
-JS_STATIC_PROP_ENTRY(print)
-JS_STATIC_PROP_ENTRY(radiosInUnison)
-JS_STATIC_PROP_ENTRY(readonly)
-JS_STATIC_PROP_ENTRY(rect)
-JS_STATIC_PROP_ENTRY(required)
-JS_STATIC_PROP_ENTRY(richText)
-JS_STATIC_PROP_ENTRY(richValue)
-JS_STATIC_PROP_ENTRY(rotation)
-JS_STATIC_PROP_ENTRY(strokeColor)
-JS_STATIC_PROP_ENTRY(style)
-JS_STATIC_PROP_ENTRY(submitName)
-JS_STATIC_PROP_ENTRY(textColor)
-JS_STATIC_PROP_ENTRY(textFont)
-JS_STATIC_PROP_ENTRY(textSize)
-JS_STATIC_PROP_ENTRY(type)
-JS_STATIC_PROP_ENTRY(userName)
-JS_STATIC_PROP_ENTRY(value)
-JS_STATIC_PROP_ENTRY(valueAsString)
-JS_STATIC_PROP_ENTRY(source)
-END_JS_STATIC_PROP()
-
-BEGIN_JS_STATIC_METHOD(CJS_Field)
-JS_STATIC_METHOD_ENTRY(browseForFileToSubmit)
-JS_STATIC_METHOD_ENTRY(buttonGetCaption)
-JS_STATIC_METHOD_ENTRY(buttonGetIcon)
-JS_STATIC_METHOD_ENTRY(buttonImportIcon)
-JS_STATIC_METHOD_ENTRY(buttonSetCaption)
-JS_STATIC_METHOD_ENTRY(buttonSetIcon)
-JS_STATIC_METHOD_ENTRY(checkThisBox)
-JS_STATIC_METHOD_ENTRY(clearItems)
-JS_STATIC_METHOD_ENTRY(defaultIsChecked)
-JS_STATIC_METHOD_ENTRY(deleteItemAt)
-JS_STATIC_METHOD_ENTRY(getArray)
-JS_STATIC_METHOD_ENTRY(getItemAt)
-JS_STATIC_METHOD_ENTRY(getLock)
-JS_STATIC_METHOD_ENTRY(insertItemAt)
-JS_STATIC_METHOD_ENTRY(isBoxChecked)
-JS_STATIC_METHOD_ENTRY(isDefaultChecked)
-JS_STATIC_METHOD_ENTRY(setAction)
-JS_STATIC_METHOD_ENTRY(setFocus)
-JS_STATIC_METHOD_ENTRY(setItems)
-JS_STATIC_METHOD_ENTRY(setLock)
-JS_STATIC_METHOD_ENTRY(signatureGetModifications)
-JS_STATIC_METHOD_ENTRY(signatureGetSeedValue)
-JS_STATIC_METHOD_ENTRY(signatureInfo)
-JS_STATIC_METHOD_ENTRY(signatureSetSeedValue)
-JS_STATIC_METHOD_ENTRY(signatureSign)
-JS_STATIC_METHOD_ENTRY(signatureValidate)
-END_JS_STATIC_METHOD()
-
-IMPLEMENT_JS_CLASS(CJS_Field, Field)
-
-void CJS_Field::InitInstance(IJS_Runtime* pIRuntime) {
-  CJS_Runtime* pRuntime = static_cast<CJS_Runtime*>(pIRuntime);
-  Field* pField = static_cast<Field*>(GetEmbedObject());
-  pField->SetIsolate(pRuntime->GetIsolate());
-}
-
-Field::Field(CJS_Object* pJSObject)
-    : CJS_EmbedObj(pJSObject),
-      m_pJSDoc(NULL),
-      m_pDocument(NULL),
-      m_nFormControlIndex(-1),
-      m_bCanSet(FALSE),
-      m_bDelay(FALSE),
-      m_isolate(NULL) {}
-
-Field::~Field() {}
-
-// note: iControlNo = -1, means not a widget.
-void Field::ParseFieldName(const std::wstring& strFieldNameParsed,
-                           std::wstring& strFieldName,
-                           int& iControlNo) {
-  int iStart = strFieldNameParsed.find_last_of(L'.');
-  if (iStart == -1) {
-    strFieldName = strFieldNameParsed;
-    iControlNo = -1;
-    return;
-  }
-  std::wstring suffixal = strFieldNameParsed.substr(iStart + 1);
-  iControlNo = FXSYS_wtoi(suffixal.c_str());
-  if (iControlNo == 0) {
-    int iStart;
-    while ((iStart = suffixal.find_last_of(L" ")) != -1) {
-      suffixal.erase(iStart, 1);
-    }
-
-    if (suffixal.compare(L"0") != 0) {
-      strFieldName = strFieldNameParsed;
-      iControlNo = -1;
-      return;
-    }
-  }
-  strFieldName = strFieldNameParsed.substr(0, iStart);
-}
-
-FX_BOOL Field::AttachField(Document* pDocument,
-                           const CFX_WideString& csFieldName) {
-  m_pJSDoc = pDocument;
-  m_pDocument = pDocument->GetReaderDoc();
-  m_bCanSet = m_pDocument->GetPermissions(FPDFPERM_FILL_FORM) ||
-              m_pDocument->GetPermissions(FPDFPERM_ANNOT_FORM) ||
-              m_pDocument->GetPermissions(FPDFPERM_MODIFY);
-
-  CPDFSDK_InterForm* pRDInterForm = m_pDocument->GetInterForm();
-  CPDF_InterForm* pInterForm = pRDInterForm->GetInterForm();
-  CFX_WideString swFieldNameTemp = csFieldName;
-  swFieldNameTemp.Replace(L"..", L".");
-
-  if (pInterForm->CountFields(swFieldNameTemp) <= 0) {
-    std::wstring strFieldName;
-    int iControlNo = -1;
-    ParseFieldName(swFieldNameTemp.c_str(), strFieldName, iControlNo);
-    if (iControlNo == -1)
-      return FALSE;
-
-    m_FieldName = strFieldName.c_str();
-    m_nFormControlIndex = iControlNo;
-    return TRUE;
-  }
-
-  m_FieldName = swFieldNameTemp;
-  m_nFormControlIndex = -1;
-
-  return TRUE;
-}
-
-std::vector<CPDF_FormField*> Field::GetFormFields(
-    CPDFSDK_Document* pDocument,
-    const CFX_WideString& csFieldName) {
-  std::vector<CPDF_FormField*> fields;
-  CPDFSDK_InterForm* pReaderInterForm = pDocument->GetInterForm();
-  CPDF_InterForm* pInterForm = pReaderInterForm->GetInterForm();
-  for (int i = 0, sz = pInterForm->CountFields(csFieldName); i < sz; ++i) {
-    if (CPDF_FormField* pFormField = pInterForm->GetField(i, csFieldName))
-      fields.push_back(pFormField);
-  }
-  return fields;
-}
-
-std::vector<CPDF_FormField*> Field::GetFormFields(
-    const CFX_WideString& csFieldName) const {
-  return Field::GetFormFields(m_pDocument, csFieldName);
-}
-
-void Field::UpdateFormField(CPDFSDK_Document* pDocument,
-                            CPDF_FormField* pFormField,
-                            FX_BOOL bChangeMark,
-                            FX_BOOL bResetAP,
-                            FX_BOOL bRefresh) {
-  std::vector<CPDFSDK_Widget*> widgets;
-  CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)pDocument->GetInterForm();
-  pInterForm->GetWidgets(pFormField, &widgets);
-
-  if (bResetAP) {
-    int nFieldType = pFormField->GetFieldType();
-    if (nFieldType == FIELDTYPE_COMBOBOX || nFieldType == FIELDTYPE_TEXTFIELD) {
-      for (CPDFSDK_Widget* pWidget : widgets) {
-        FX_BOOL bFormatted = FALSE;
-        CFX_WideString sValue = pWidget->OnFormat(bFormatted);
-        pWidget->ResetAppearance(bFormatted ? sValue.c_str() : nullptr, FALSE);
-      }
-    } else {
-      for (CPDFSDK_Widget* pWidget : widgets) {
-        pWidget->ResetAppearance(nullptr, FALSE);
-      }
-    }
-  }
-
-  if (bRefresh) {
-    for (CPDFSDK_Widget* pWidget : widgets) {
-      CPDFSDK_Document* pDoc = pWidget->GetInterForm()->GetDocument();
-      pDoc->UpdateAllViews(nullptr, pWidget);
-    }
-  }
-
-  if (bChangeMark)
-    pDocument->SetChangeMark();
-}
-
-void Field::UpdateFormControl(CPDFSDK_Document* pDocument,
-                              CPDF_FormControl* pFormControl,
-                              FX_BOOL bChangeMark,
-                              FX_BOOL bResetAP,
-                              FX_BOOL bRefresh) {
-  ASSERT(pFormControl);
-
-  CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)pDocument->GetInterForm();
-  CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormControl);
-
-  if (pWidget) {
-    if (bResetAP) {
-      int nFieldType = pWidget->GetFieldType();
-      if (nFieldType == FIELDTYPE_COMBOBOX ||
-          nFieldType == FIELDTYPE_TEXTFIELD) {
-        FX_BOOL bFormated = FALSE;
-        CFX_WideString sValue = pWidget->OnFormat(bFormated);
-        if (bFormated)
-          pWidget->ResetAppearance(sValue.c_str(), FALSE);
-        else
-          pWidget->ResetAppearance(NULL, FALSE);
-      } else {
-        pWidget->ResetAppearance(NULL, FALSE);
-      }
-    }
-
-    if (bRefresh) {
-      CPDFSDK_InterForm* pInterForm = pWidget->GetInterForm();
-      CPDFSDK_Document* pDoc = pInterForm->GetDocument();
-      pDoc->UpdateAllViews(NULL, pWidget);
-    }
-  }
-
-  if (bChangeMark)
-    pDocument->SetChangeMark();
-}
-
-CPDFSDK_Widget* Field::GetWidget(CPDFSDK_Document* pDocument,
-                                 CPDF_FormControl* pFormControl) {
-  CPDFSDK_InterForm* pInterForm =
-      static_cast<CPDFSDK_InterForm*>(pDocument->GetInterForm());
-  return pInterForm ? pInterForm->GetWidget(pFormControl) : nullptr;
-}
-
-FX_BOOL Field::ValueIsOccur(CPDF_FormField* pFormField,
-                            CFX_WideString csOptLabel) {
-  for (int i = 0, sz = pFormField->CountOptions(); i < sz; i++) {
-    if (csOptLabel.Compare(pFormField->GetOptionLabel(i)) == 0)
-      return TRUE;
-  }
-
-  return FALSE;
-}
-
-CPDF_FormControl* Field::GetSmartFieldControl(CPDF_FormField* pFormField) {
-  if (!pFormField->CountControls() ||
-      m_nFormControlIndex >= pFormField->CountControls())
-    return NULL;
-
-  if (m_nFormControlIndex < 0)
-    return pFormField->GetControl(0);
-
-  return pFormField->GetControl(m_nFormControlIndex);
-}
-
-FX_BOOL Field::alignment(IJS_Context* cc,
-                         CJS_PropValue& vp,
-                         CFX_WideString& sError) {
-  ASSERT(m_pDocument);
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    CFX_ByteString alignStr;
-    vp >> alignStr;
-
-    if (m_bDelay) {
-      AddDelay_String(FP_ALIGNMENT, alignStr);
-    } else {
-      Field::SetAlignment(m_pDocument, m_FieldName, m_nFormControlIndex,
-                          alignStr);
-    }
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD)
-      return FALSE;
-
-    CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
-    if (!pFormControl)
-      return FALSE;
-
-    switch (pFormControl->GetControlAlignment()) {
-      case 1:
-        vp << L"center";
-        break;
-      case 0:
-        vp << L"left";
-        break;
-      case 2:
-        vp << L"right";
-        break;
-      default:
-        vp << L"";
-    }
-  }
-
-  return TRUE;
-}
-
-void Field::SetAlignment(CPDFSDK_Document* pDocument,
-                         const CFX_WideString& swFieldName,
-                         int nControlIndex,
-                         const CFX_ByteString& string) {
-  // Not supported.
-}
-
-FX_BOOL Field::borderStyle(IJS_Context* cc,
-                           CJS_PropValue& vp,
-                           CFX_WideString& sError) {
-  ASSERT(m_pDocument);
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    CFX_ByteString strType = "";
-    vp >> strType;
-
-    if (m_bDelay) {
-      AddDelay_String(FP_BORDERSTYLE, strType);
-    } else {
-      Field::SetBorderStyle(m_pDocument, m_FieldName, m_nFormControlIndex,
-                            strType);
-    }
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    if (!pFormField)
-      return FALSE;
-
-    CPDFSDK_Widget* pWidget =
-        GetWidget(m_pDocument, GetSmartFieldControl(pFormField));
-    if (!pWidget)
-      return FALSE;
-
-    int nBorderstyle = pWidget->GetBorderStyle();
-
-    switch (nBorderstyle) {
-      case BBS_SOLID:
-        vp << L"solid";
-        break;
-      case BBS_DASH:
-        vp << L"dashed";
-        break;
-      case BBS_BEVELED:
-        vp << L"beveled";
-        break;
-      case BBS_INSET:
-        vp << L"inset";
-        break;
-      case BBS_UNDERLINE:
-        vp << L"underline";
-        break;
-      default:
-        vp << L"";
-        break;
-    }
-  }
-
-  return TRUE;
-}
-
-void Field::SetBorderStyle(CPDFSDK_Document* pDocument,
-                           const CFX_WideString& swFieldName,
-                           int nControlIndex,
-                           const CFX_ByteString& string) {
-  ASSERT(pDocument);
-
-  int nBorderStyle = 0;
-
-  if (string == "solid")
-    nBorderStyle = BBS_SOLID;
-  else if (string == "beveled")
-    nBorderStyle = BBS_BEVELED;
-  else if (string == "dashed")
-    nBorderStyle = BBS_DASH;
-  else if (string == "inset")
-    nBorderStyle = BBS_INSET;
-  else if (string == "underline")
-    nBorderStyle = BBS_UNDERLINE;
-  else
-    return;
-
-  std::vector<CPDF_FormField*> FieldArray =
-      GetFormFields(pDocument, swFieldName);
-  for (CPDF_FormField* pFormField : FieldArray) {
-    if (nControlIndex < 0) {
-      FX_BOOL bSet = FALSE;
-      for (int i = 0, sz = pFormField->CountControls(); i < sz; ++i) {
-        if (CPDFSDK_Widget* pWidget =
-                GetWidget(pDocument, pFormField->GetControl(i))) {
-          if (pWidget->GetBorderStyle() != nBorderStyle) {
-            pWidget->SetBorderStyle(nBorderStyle);
-            bSet = TRUE;
-          }
-        }
-      }
-      if (bSet)
-        UpdateFormField(pDocument, pFormField, TRUE, TRUE, TRUE);
-    } else {
-      if (nControlIndex >= pFormField->CountControls())
-        return;
-      if (CPDF_FormControl* pFormControl =
-              pFormField->GetControl(nControlIndex)) {
-        if (CPDFSDK_Widget* pWidget = GetWidget(pDocument, pFormControl)) {
-          if (pWidget->GetBorderStyle() != nBorderStyle) {
-            pWidget->SetBorderStyle(nBorderStyle);
-            UpdateFormControl(pDocument, pFormControl, TRUE, TRUE, TRUE);
-          }
-        }
-      }
-    }
-  }
-}
-
-FX_BOOL Field::buttonAlignX(IJS_Context* cc,
-                            CJS_PropValue& vp,
-                            CFX_WideString& sError) {
-  ASSERT(m_pDocument);
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    int nVP;
-    vp >> nVP;
-
-    if (m_bDelay) {
-      AddDelay_Int(FP_BUTTONALIGNX, nVP);
-    } else {
-      Field::SetButtonAlignX(m_pDocument, m_FieldName, m_nFormControlIndex,
-                             nVP);
-    }
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    if (pFormField->GetFieldType() != FIELDTYPE_PUSHBUTTON)
-      return FALSE;
-
-    CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
-    if (!pFormControl)
-      return FALSE;
-
-    CPDF_IconFit IconFit = pFormControl->GetIconFit();
-
-    FX_FLOAT fLeft, fBottom;
-    IconFit.GetIconPosition(fLeft, fBottom);
-
-    vp << (int32_t)fLeft;
-  }
-
-  return TRUE;
-}
-
-void Field::SetButtonAlignX(CPDFSDK_Document* pDocument,
-                            const CFX_WideString& swFieldName,
-                            int nControlIndex,
-                            int number) {
-  // Not supported.
-}
-
-FX_BOOL Field::buttonAlignY(IJS_Context* cc,
-                            CJS_PropValue& vp,
-                            CFX_WideString& sError) {
-  ASSERT(m_pDocument);
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    int nVP;
-    vp >> nVP;
-
-    if (m_bDelay) {
-      AddDelay_Int(FP_BUTTONALIGNY, nVP);
-    } else {
-      Field::SetButtonAlignY(m_pDocument, m_FieldName, m_nFormControlIndex,
-                             nVP);
-    }
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    if (pFormField->GetFieldType() != FIELDTYPE_PUSHBUTTON)
-      return FALSE;
-
-    CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
-    if (!pFormControl)
-      return FALSE;
-
-    CPDF_IconFit IconFit = pFormControl->GetIconFit();
-
-    FX_FLOAT fLeft, fBottom;
-    IconFit.GetIconPosition(fLeft, fBottom);
-
-    vp << (int32_t)fBottom;
-  }
-
-  return TRUE;
-}
-
-void Field::SetButtonAlignY(CPDFSDK_Document* pDocument,
-                            const CFX_WideString& swFieldName,
-                            int nControlIndex,
-                            int number) {
-  // Not supported.
-}
-
-FX_BOOL Field::buttonFitBounds(IJS_Context* cc,
-                               CJS_PropValue& vp,
-                               CFX_WideString& sError) {
-  ASSERT(m_pDocument);
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    bool bVP;
-    vp >> bVP;
-
-    if (m_bDelay) {
-      AddDelay_Bool(FP_BUTTONFITBOUNDS, bVP);
-    } else {
-      Field::SetButtonFitBounds(m_pDocument, m_FieldName, m_nFormControlIndex,
-                                bVP);
-    }
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    if (pFormField->GetFieldType() != FIELDTYPE_PUSHBUTTON)
-      return FALSE;
-
-    CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
-    if (!pFormControl)
-      return FALSE;
-
-    CPDF_IconFit IconFit = pFormControl->GetIconFit();
-    vp << IconFit.GetFittingBounds();
-  }
-
-  return TRUE;
-}
-
-void Field::SetButtonFitBounds(CPDFSDK_Document* pDocument,
-                               const CFX_WideString& swFieldName,
-                               int nControlIndex,
-                               bool b) {
-  // Not supported.
-}
-
-FX_BOOL Field::buttonPosition(IJS_Context* cc,
-                              CJS_PropValue& vp,
-                              CFX_WideString& sError) {
-  ASSERT(m_pDocument);
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    int nVP;
-    vp >> nVP;
-
-    if (m_bDelay) {
-      AddDelay_Int(FP_BUTTONPOSITION, nVP);
-    } else {
-      Field::SetButtonPosition(m_pDocument, m_FieldName, m_nFormControlIndex,
-                               nVP);
-    }
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    if (pFormField->GetFieldType() != FIELDTYPE_PUSHBUTTON)
-      return FALSE;
-
-    CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
-    if (!pFormControl)
-      return FALSE;
-
-    vp << pFormControl->GetTextPosition();
-  }
-  return TRUE;
-}
-
-void Field::SetButtonPosition(CPDFSDK_Document* pDocument,
-                              const CFX_WideString& swFieldName,
-                              int nControlIndex,
-                              int number) {
-  // Not supported.
-}
-
-FX_BOOL Field::buttonScaleHow(IJS_Context* cc,
-                              CJS_PropValue& vp,
-                              CFX_WideString& sError) {
-  ASSERT(m_pDocument);
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    int nVP;
-    vp >> nVP;
-
-    if (m_bDelay) {
-      AddDelay_Int(FP_BUTTONSCALEHOW, nVP);
-    } else {
-      Field::SetButtonScaleHow(m_pDocument, m_FieldName, m_nFormControlIndex,
-                               nVP);
-    }
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    if (pFormField->GetFieldType() != FIELDTYPE_PUSHBUTTON)
-      return FALSE;
-
-    CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
-    if (!pFormControl)
-      return FALSE;
-
-    CPDF_IconFit IconFit = pFormControl->GetIconFit();
-    if (IconFit.IsProportionalScale())
-      vp << (int32_t)0;
-    else
-      vp << (int32_t)1;
-  }
-
-  return TRUE;
-}
-
-void Field::SetButtonScaleHow(CPDFSDK_Document* pDocument,
-                              const CFX_WideString& swFieldName,
-                              int nControlIndex,
-                              int number) {
-  // Not supported.
-}
-
-FX_BOOL Field::buttonScaleWhen(IJS_Context* cc,
-                               CJS_PropValue& vp,
-                               CFX_WideString& sError) {
-  ASSERT(m_pDocument);
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    int nVP;
-    vp >> nVP;
-
-    if (m_bDelay) {
-      AddDelay_Int(FP_BUTTONSCALEWHEN, nVP);
-    } else {
-      Field::SetButtonScaleWhen(m_pDocument, m_FieldName, m_nFormControlIndex,
-                                nVP);
-    }
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    if (pFormField->GetFieldType() != FIELDTYPE_PUSHBUTTON)
-      return FALSE;
-
-    CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
-    if (!pFormControl)
-      return FALSE;
-
-    CPDF_IconFit IconFit = pFormControl->GetIconFit();
-    int ScaleM = IconFit.GetScaleMethod();
-    switch (ScaleM) {
-      case CPDF_IconFit::Always:
-        vp << (int32_t)CPDF_IconFit::Always;
-        break;
-      case CPDF_IconFit::Bigger:
-        vp << (int32_t)CPDF_IconFit::Bigger;
-        break;
-      case CPDF_IconFit::Never:
-        vp << (int32_t)CPDF_IconFit::Never;
-        break;
-      case CPDF_IconFit::Smaller:
-        vp << (int32_t)CPDF_IconFit::Smaller;
-        break;
-    }
-  }
-
-  return TRUE;
-}
-
-void Field::SetButtonScaleWhen(CPDFSDK_Document* pDocument,
-                               const CFX_WideString& swFieldName,
-                               int nControlIndex,
-                               int number) {
-  // Not supported.
-}
-
-FX_BOOL Field::calcOrderIndex(IJS_Context* cc,
-                              CJS_PropValue& vp,
-                              CFX_WideString& sError) {
-  ASSERT(m_pDocument);
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    int nVP;
-    vp >> nVP;
-
-    if (m_bDelay) {
-      AddDelay_Int(FP_CALCORDERINDEX, nVP);
-    } else {
-      Field::SetCalcOrderIndex(m_pDocument, m_FieldName, m_nFormControlIndex,
-                               nVP);
-    }
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    if (pFormField->GetFieldType() != FIELDTYPE_COMBOBOX &&
-        pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD) {
-      return FALSE;
-    }
-
-    CPDFSDK_InterForm* pRDInterForm = m_pDocument->GetInterForm();
-    CPDF_InterForm* pInterForm = pRDInterForm->GetInterForm();
-    vp << (int32_t)pInterForm->FindFieldInCalculationOrder(pFormField);
-  }
-
-  return TRUE;
-}
-
-void Field::SetCalcOrderIndex(CPDFSDK_Document* pDocument,
-                              const CFX_WideString& swFieldName,
-                              int nControlIndex,
-                              int number) {
-  // Not supported.
-}
-
-FX_BOOL Field::charLimit(IJS_Context* cc,
-                         CJS_PropValue& vp,
-                         CFX_WideString& sError) {
-  ASSERT(m_pDocument);
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    int nVP;
-    vp >> nVP;
-
-    if (m_bDelay) {
-      AddDelay_Int(FP_CHARLIMIT, nVP);
-    } else {
-      Field::SetCharLimit(m_pDocument, m_FieldName, m_nFormControlIndex, nVP);
-    }
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD)
-      return FALSE;
-
-    vp << (int32_t)pFormField->GetMaxLen();
-  }
-  return TRUE;
-}
-
-void Field::SetCharLimit(CPDFSDK_Document* pDocument,
-                         const CFX_WideString& swFieldName,
-                         int nControlIndex,
-                         int number) {
-  // Not supported.
-}
-
-FX_BOOL Field::comb(IJS_Context* cc,
-                    CJS_PropValue& vp,
-                    CFX_WideString& sError) {
-  ASSERT(m_pDocument);
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    bool bVP;
-    vp >> bVP;
-
-    if (m_bDelay) {
-      AddDelay_Bool(FP_COMB, bVP);
-    } else {
-      Field::SetComb(m_pDocument, m_FieldName, m_nFormControlIndex, bVP);
-    }
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD)
-      return FALSE;
-
-    if (pFormField->GetFieldFlags() & FIELDFLAG_COMB)
-      vp << true;
-    else
-      vp << false;
-  }
-
-  return TRUE;
-}
-
-void Field::SetComb(CPDFSDK_Document* pDocument,
-                    const CFX_WideString& swFieldName,
-                    int nControlIndex,
-                    bool b) {
-  // Not supported.
-}
-
-FX_BOOL Field::commitOnSelChange(IJS_Context* cc,
-                                 CJS_PropValue& vp,
-                                 CFX_WideString& sError) {
-  ASSERT(m_pDocument);
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    bool bVP;
-    vp >> bVP;
-
-    if (m_bDelay) {
-      AddDelay_Bool(FP_COMMITONSELCHANGE, bVP);
-    } else {
-      Field::SetCommitOnSelChange(m_pDocument, m_FieldName, m_nFormControlIndex,
-                                  bVP);
-    }
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    if (pFormField->GetFieldType() != FIELDTYPE_COMBOBOX &&
-        pFormField->GetFieldType() != FIELDTYPE_LISTBOX) {
-      return FALSE;
-    }
-
-    if (pFormField->GetFieldFlags() & FIELDFLAG_COMMITONSELCHANGE)
-      vp << true;
-    else
-      vp << false;
-  }
-
-  return TRUE;
-}
-
-void Field::SetCommitOnSelChange(CPDFSDK_Document* pDocument,
-                                 const CFX_WideString& swFieldName,
-                                 int nControlIndex,
-                                 bool b) {
-  // Not supported.
-}
-
-FX_BOOL Field::currentValueIndices(IJS_Context* cc,
-                                   CJS_PropValue& vp,
-                                   CFX_WideString& sError) {
-  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    CFX_DWordArray array;
-
-    if (vp.GetType() == CJS_Value::VT_number) {
-      int iSelecting = 0;
-      vp >> iSelecting;
-      array.Add(iSelecting);
-    } else if (vp.IsArrayObject()) {
-      CJS_Array SelArray(pRuntime);
-      CJS_Value SelValue(pRuntime);
-      int iSelecting;
-      vp >> SelArray;
-      for (int i = 0, sz = SelArray.GetLength(); i < sz; i++) {
-        SelArray.GetElement(i, SelValue);
-        iSelecting = SelValue.ToInt();
-        array.Add(iSelecting);
-      }
-    }
-
-    if (m_bDelay) {
-      AddDelay_WordArray(FP_CURRENTVALUEINDICES, array);
-    } else {
-      Field::SetCurrentValueIndices(m_pDocument, m_FieldName,
-                                    m_nFormControlIndex, array);
-    }
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    if (pFormField->GetFieldType() != FIELDTYPE_COMBOBOX &&
-        pFormField->GetFieldType() != FIELDTYPE_LISTBOX) {
-      return FALSE;
-    }
-
-    if (pFormField->CountSelectedItems() == 1) {
-      vp << pFormField->GetSelectedIndex(0);
-    } else if (pFormField->CountSelectedItems() > 1) {
-      CJS_Array SelArray(pRuntime);
-      for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz; i++) {
-        SelArray.SetElement(
-            i, CJS_Value(pRuntime, pFormField->GetSelectedIndex(i)));
-      }
-      vp << SelArray;
-    } else {
-      vp << -1;
-    }
-  }
-
-  return TRUE;
-}
-
-void Field::SetCurrentValueIndices(CPDFSDK_Document* pDocument,
-                                   const CFX_WideString& swFieldName,
-                                   int nControlIndex,
-                                   const CFX_DWordArray& array) {
-  ASSERT(pDocument);
-
-  std::vector<CPDF_FormField*> FieldArray =
-      GetFormFields(pDocument, swFieldName);
-  for (CPDF_FormField* pFormField : FieldArray) {
-    int nFieldType = pFormField->GetFieldType();
-    if (nFieldType == FIELDTYPE_COMBOBOX || nFieldType == FIELDTYPE_LISTBOX) {
-      FX_DWORD dwFieldFlags = pFormField->GetFieldFlags();
-      pFormField->ClearSelection(TRUE);
-
-      for (int i = 0, sz = array.GetSize(); i < sz; i++) {
-        if (i > 0 && !(dwFieldFlags & (1 << 21))) {
-          break;
-        }
-
-        int iSelecting = (int32_t)array.GetAt(i);
-        if (iSelecting < pFormField->CountOptions() &&
-            !pFormField->IsItemSelected(iSelecting))
-          pFormField->SetItemSelection(iSelecting, TRUE);
-      }
-      UpdateFormField(pDocument, pFormField, TRUE, TRUE, TRUE);
-    }
-  }
-}
-
-FX_BOOL Field::defaultStyle(IJS_Context* cc,
-                            CJS_PropValue& vp,
-                            CFX_WideString& sError) {
-  return FALSE;
-}
-
-void Field::SetDefaultStyle(CPDFSDK_Document* pDocument,
-                            const CFX_WideString& swFieldName,
-                            int nControlIndex) {
-  // Not supported.
-}
-
-FX_BOOL Field::defaultValue(IJS_Context* cc,
-                            CJS_PropValue& vp,
-                            CFX_WideString& sError) {
-  ASSERT(m_pDocument);
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    CFX_WideString WideStr;
-    vp >> WideStr;
-
-    if (m_bDelay) {
-      AddDelay_WideString(FP_DEFAULTVALUE, WideStr);
-    } else {
-      Field::SetDefaultValue(m_pDocument, m_FieldName, m_nFormControlIndex,
-                             WideStr);
-    }
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    if (pFormField->GetFieldType() == FIELDTYPE_PUSHBUTTON ||
-        pFormField->GetFieldType() == FIELDTYPE_SIGNATURE) {
-      return FALSE;
-    }
-
-    vp << pFormField->GetDefaultValue();
-  }
-  return TRUE;
-}
-
-void Field::SetDefaultValue(CPDFSDK_Document* pDocument,
-                            const CFX_WideString& swFieldName,
-                            int nControlIndex,
-                            const CFX_WideString& string) {
-  // Not supported.
-}
-
-FX_BOOL Field::doNotScroll(IJS_Context* cc,
-                           CJS_PropValue& vp,
-                           CFX_WideString& sError) {
-  ASSERT(m_pDocument);
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    bool bVP;
-    vp >> bVP;
-
-    if (m_bDelay) {
-      AddDelay_Bool(FP_DONOTSCROLL, bVP);
-    } else {
-      Field::SetDoNotScroll(m_pDocument, m_FieldName, m_nFormControlIndex, bVP);
-    }
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD)
-      return FALSE;
-
-    if (pFormField->GetFieldFlags() & FIELDFLAG_DONOTSCROLL)
-      vp << true;
-    else
-      vp << false;
-  }
-
-  return TRUE;
-}
-
-void Field::SetDoNotScroll(CPDFSDK_Document* pDocument,
-                           const CFX_WideString& swFieldName,
-                           int nControlIndex,
-                           bool b) {
-  // Not supported.
-}
-
-FX_BOOL Field::doNotSpellCheck(IJS_Context* cc,
-                               CJS_PropValue& vp,
-                               CFX_WideString& sError) {
-  ASSERT(m_pDocument);
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    bool bVP;
-    vp >> bVP;
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD &&
-        pFormField->GetFieldType() != FIELDTYPE_COMBOBOX) {
-      return FALSE;
-    }
-
-    if (pFormField->GetFieldFlags() & FIELDFLAG_DONOTSPELLCHECK)
-      vp << true;
-    else
-      vp << false;
-  }
-
-  return TRUE;
-}
-
-void Field::SetDelay(FX_BOOL bDelay) {
-  m_bDelay = bDelay;
-
-  if (!m_bDelay) {
-    if (m_pJSDoc)
-      m_pJSDoc->DoFieldDelay(m_FieldName, m_nFormControlIndex);
-  }
-}
-
-FX_BOOL Field::delay(IJS_Context* cc,
-                     CJS_PropValue& vp,
-                     CFX_WideString& sError) {
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    bool bVP;
-    vp >> bVP;
-
-    SetDelay(bVP);
-  } else {
-    vp << m_bDelay;
-  }
-  return TRUE;
-}
-
-FX_BOOL Field::display(IJS_Context* cc,
-                       CJS_PropValue& vp,
-                       CFX_WideString& sError) {
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    int nVP;
-    vp >> nVP;
-
-    if (m_bDelay) {
-      AddDelay_Int(FP_DISPLAY, nVP);
-    } else {
-      Field::SetDisplay(m_pDocument, m_FieldName, m_nFormControlIndex, nVP);
-    }
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    ASSERT(pFormField);
-    CPDFSDK_InterForm* pInterForm =
-        (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
-    CPDFSDK_Widget* pWidget =
-        pInterForm->GetWidget(GetSmartFieldControl(pFormField));
-    if (!pWidget)
-      return FALSE;
-
-    FX_DWORD dwFlag = pWidget->GetFlags();
-
-    if (ANNOTFLAG_INVISIBLE & dwFlag || ANNOTFLAG_HIDDEN & dwFlag) {
-      vp << (int32_t)1;
-    } else {
-      if (ANNOTFLAG_PRINT & dwFlag) {
-        if (ANNOTFLAG_NOVIEW & dwFlag) {
-          vp << (int32_t)3;
-        } else {
-          vp << (int32_t)0;
-        }
-      } else {
-        vp << (int32_t)2;
-      }
-    }
-  }
-
-  return TRUE;
-}
-
-void Field::SetDisplay(CPDFSDK_Document* pDocument,
-                       const CFX_WideString& swFieldName,
-                       int nControlIndex,
-                       int number) {
-  CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)pDocument->GetInterForm();
-  std::vector<CPDF_FormField*> FieldArray =
-      GetFormFields(pDocument, swFieldName);
-  for (CPDF_FormField* pFormField : FieldArray) {
-    if (nControlIndex < 0) {
-      FX_BOOL bSet = FALSE;
-      for (int i = 0, sz = pFormField->CountControls(); i < sz; ++i) {
-        CPDF_FormControl* pFormControl = pFormField->GetControl(i);
-        ASSERT(pFormControl);
-
-        if (CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormControl)) {
-          FX_DWORD dwFlag = pWidget->GetFlags();
-          switch (number) {
-            case 0:
-              dwFlag &= (~ANNOTFLAG_INVISIBLE);
-              dwFlag &= (~ANNOTFLAG_HIDDEN);
-              dwFlag &= (~ANNOTFLAG_NOVIEW);
-              dwFlag |= ANNOTFLAG_PRINT;
-              break;
-            case 1:
-              dwFlag &= (~ANNOTFLAG_INVISIBLE);
-              dwFlag &= (~ANNOTFLAG_NOVIEW);
-              dwFlag |= (ANNOTFLAG_HIDDEN | ANNOTFLAG_PRINT);
-              break;
-            case 2:
-              dwFlag &= (~ANNOTFLAG_INVISIBLE);
-              dwFlag &= (~ANNOTFLAG_PRINT);
-              dwFlag &= (~ANNOTFLAG_HIDDEN);
-              dwFlag &= (~ANNOTFLAG_NOVIEW);
-              break;
-            case 3:
-              dwFlag |= ANNOTFLAG_NOVIEW;
-              dwFlag |= ANNOTFLAG_PRINT;
-              dwFlag &= (~ANNOTFLAG_HIDDEN);
-              break;
-          }
-
-          if (dwFlag != pWidget->GetFlags()) {
-            pWidget->SetFlags(dwFlag);
-            bSet = TRUE;
-          }
-        }
-      }
-
-      if (bSet)
-        UpdateFormField(pDocument, pFormField, TRUE, FALSE, TRUE);
-    } else {
-      if (nControlIndex >= pFormField->CountControls())
-        return;
-      if (CPDF_FormControl* pFormControl =
-              pFormField->GetControl(nControlIndex)) {
-        if (CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormControl)) {
-          FX_DWORD dwFlag = pWidget->GetFlags();
-          switch (number) {
-            case 0:
-              dwFlag &= (~ANNOTFLAG_INVISIBLE);
-              dwFlag &= (~ANNOTFLAG_HIDDEN);
-              dwFlag &= (~ANNOTFLAG_NOVIEW);
-              dwFlag |= ANNOTFLAG_PRINT;
-              break;
-            case 1:
-              dwFlag &= (~ANNOTFLAG_INVISIBLE);
-              dwFlag &= (~ANNOTFLAG_NOVIEW);
-              dwFlag |= (ANNOTFLAG_HIDDEN | ANNOTFLAG_PRINT);
-              break;
-            case 2:
-              dwFlag &= (~ANNOTFLAG_INVISIBLE);
-              dwFlag &= (~ANNOTFLAG_PRINT);
-              dwFlag &= (~ANNOTFLAG_HIDDEN);
-              dwFlag &= (~ANNOTFLAG_NOVIEW);
-              break;
-            case 3:
-              dwFlag |= ANNOTFLAG_NOVIEW;
-              dwFlag |= ANNOTFLAG_PRINT;
-              dwFlag &= (~ANNOTFLAG_HIDDEN);
-              break;
-          }
-          if (dwFlag != pWidget->GetFlags()) {
-            pWidget->SetFlags(dwFlag);
-            UpdateFormControl(pDocument, pFormControl, TRUE, FALSE, TRUE);
-          }
-        }
-      }
-    }
-  }
-}
-
-FX_BOOL Field::doc(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
-  if (!vp.IsGetting()) {
-    return FALSE;
-  }
-  vp << m_pJSDoc->GetCJSDoc();
-  return TRUE;
-}
-
-FX_BOOL Field::editable(IJS_Context* cc,
-                        CJS_PropValue& vp,
-                        CFX_WideString& sError) {
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    bool bVP;
-    vp >> bVP;
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    if (pFormField->GetFieldType() != FIELDTYPE_COMBOBOX)
-      return FALSE;
-
-    if (pFormField->GetFieldFlags() & FIELDFLAG_EDIT)
-      vp << true;
-    else
-      vp << false;
-  }
-
-  return TRUE;
-}
-
-FX_BOOL Field::exportValues(IJS_Context* cc,
-                            CJS_PropValue& vp,
-                            CFX_WideString& sError) {
-  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-  if (FieldArray.empty())
-    return FALSE;
-
-  CPDF_FormField* pFormField = FieldArray[0];
-  if (pFormField->GetFieldType() != FIELDTYPE_CHECKBOX &&
-      pFormField->GetFieldType() != FIELDTYPE_RADIOBUTTON) {
-    return FALSE;
-  }
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    if (!vp.IsArrayObject())
-      return FALSE;
-  } else {
-    CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
-    CJS_Array ExportValusArray(pRuntime);
-    if (m_nFormControlIndex < 0) {
-      for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
-        CPDF_FormControl* pFormControl = pFormField->GetControl(i);
-        ExportValusArray.SetElement(
-            i, CJS_Value(pRuntime, pFormControl->GetExportValue().c_str()));
-      }
-    } else {
-      if (m_nFormControlIndex >= pFormField->CountControls())
-        return FALSE;
-
-      CPDF_FormControl* pFormControl =
-          pFormField->GetControl(m_nFormControlIndex);
-      if (!pFormControl)
-        return FALSE;
-
-      ExportValusArray.SetElement(
-          0, CJS_Value(pRuntime, pFormControl->GetExportValue().c_str()));
-    }
-    vp << ExportValusArray;
-  }
-  return TRUE;
-}
-
-FX_BOOL Field::fileSelect(IJS_Context* cc,
-                          CJS_PropValue& vp,
-                          CFX_WideString& sError) {
-  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-  if (FieldArray.empty())
-    return FALSE;
-
-  CPDF_FormField* pFormField = FieldArray[0];
-  if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD)
-    return FALSE;
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    bool bVP;
-    vp >> bVP;
-  } else {
-    if (pFormField->GetFieldFlags() & FIELDFLAG_FILESELECT)
-      vp << true;
-    else
-      vp << false;
-  }
-  return TRUE;
-}
-
-FX_BOOL Field::fillColor(IJS_Context* cc,
-                         CJS_PropValue& vp,
-                         CFX_WideString& sError) {
-  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
-  CJS_Array crArray(pRuntime);
-  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-  if (FieldArray.empty())
-    return FALSE;
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    if (!vp.IsArrayObject())
-      return FALSE;
-
-    vp >> crArray;
-
-    CPWL_Color color;
-    color::ConvertArrayToPWLColor(crArray, color);
-    if (m_bDelay) {
-      AddDelay_Color(FP_FILLCOLOR, color);
-    } else {
-      Field::SetFillColor(m_pDocument, m_FieldName, m_nFormControlIndex, color);
-    }
-  } else {
-    CPDF_FormField* pFormField = FieldArray[0];
-    ASSERT(pFormField);
-    CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
-    if (!pFormControl)
-      return FALSE;
-
-    int iColorType;
-    pFormControl->GetBackgroundColor(iColorType);
-
-    CPWL_Color color;
-    if (iColorType == COLORTYPE_TRANSPARENT) {
-      color = CPWL_Color(COLORTYPE_TRANSPARENT);
-    } else if (iColorType == COLORTYPE_GRAY) {
-      color = CPWL_Color(COLORTYPE_GRAY,
-                         pFormControl->GetOriginalBackgroundColor(0));
-    } else if (iColorType == COLORTYPE_RGB) {
-      color =
-          CPWL_Color(COLORTYPE_RGB, pFormControl->GetOriginalBackgroundColor(0),
-                     pFormControl->GetOriginalBackgroundColor(1),
-                     pFormControl->GetOriginalBackgroundColor(2));
-    } else if (iColorType == COLORTYPE_CMYK) {
-      color = CPWL_Color(COLORTYPE_CMYK,
-                         pFormControl->GetOriginalBackgroundColor(0),
-                         pFormControl->GetOriginalBackgroundColor(1),
-                         pFormControl->GetOriginalBackgroundColor(2),
-                         pFormControl->GetOriginalBackgroundColor(3));
-    } else {
-      return FALSE;
-    }
-
-    color::ConvertPWLColorToArray(color, crArray);
-    vp << crArray;
-  }
-
-  return TRUE;
-}
-
-void Field::SetFillColor(CPDFSDK_Document* pDocument,
-                         const CFX_WideString& swFieldName,
-                         int nControlIndex,
-                         const CPWL_Color& color) {
-  // Not supported.
-}
-
-FX_BOOL Field::hidden(IJS_Context* cc,
-                      CJS_PropValue& vp,
-                      CFX_WideString& sError) {
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    bool bVP;
-    vp >> bVP;
-
-    if (m_bDelay) {
-      AddDelay_Bool(FP_HIDDEN, bVP);
-    } else {
-      Field::SetHidden(m_pDocument, m_FieldName, m_nFormControlIndex, bVP);
-    }
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    ASSERT(pFormField);
-    CPDFSDK_InterForm* pInterForm =
-        (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
-    CPDFSDK_Widget* pWidget =
-        pInterForm->GetWidget(GetSmartFieldControl(pFormField));
-    if (!pWidget)
-      return FALSE;
-
-    FX_DWORD dwFlags = pWidget->GetFlags();
-
-    if (ANNOTFLAG_INVISIBLE & dwFlags || ANNOTFLAG_HIDDEN & dwFlags)
-      vp << true;
-    else
-      vp << false;
-  }
-
-  return TRUE;
-}
-
-void Field::SetHidden(CPDFSDK_Document* pDocument,
-                      const CFX_WideString& swFieldName,
-                      int nControlIndex,
-                      bool b) {
-  CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)pDocument->GetInterForm();
-  std::vector<CPDF_FormField*> FieldArray =
-      GetFormFields(pDocument, swFieldName);
-  for (CPDF_FormField* pFormField : FieldArray) {
-    if (nControlIndex < 0) {
-      FX_BOOL bSet = FALSE;
-      for (int i = 0, sz = pFormField->CountControls(); i < sz; ++i) {
-        if (CPDFSDK_Widget* pWidget =
-                pInterForm->GetWidget(pFormField->GetControl(i))) {
-          FX_DWORD dwFlags = pWidget->GetFlags();
-
-          if (b) {
-            dwFlags &= (~ANNOTFLAG_INVISIBLE);
-            dwFlags &= (~ANNOTFLAG_NOVIEW);
-            dwFlags |= (ANNOTFLAG_HIDDEN | ANNOTFLAG_PRINT);
-          } else {
-            dwFlags &= (~ANNOTFLAG_INVISIBLE);
-            dwFlags &= (~ANNOTFLAG_HIDDEN);
-            dwFlags &= (~ANNOTFLAG_NOVIEW);
-            dwFlags |= ANNOTFLAG_PRINT;
-          }
-
-          if (dwFlags != pWidget->GetFlags()) {
-            pWidget->SetFlags(dwFlags);
-            bSet = TRUE;
-          }
-        }
-      }
-
-      if (bSet)
-        UpdateFormField(pDocument, pFormField, TRUE, FALSE, TRUE);
-    } else {
-      if (nControlIndex >= pFormField->CountControls())
-        return;
-      if (CPDF_FormControl* pFormControl =
-              pFormField->GetControl(nControlIndex)) {
-        if (CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormControl)) {
-          FX_DWORD dwFlags = pWidget->GetFlags();
-
-          if (b) {
-            dwFlags &= (~ANNOTFLAG_INVISIBLE);
-            dwFlags &= (~ANNOTFLAG_NOVIEW);
-            dwFlags |= (ANNOTFLAG_HIDDEN | ANNOTFLAG_PRINT);
-          } else {
-            dwFlags &= (~ANNOTFLAG_INVISIBLE);
-            dwFlags &= (~ANNOTFLAG_HIDDEN);
-            dwFlags &= (~ANNOTFLAG_NOVIEW);
-            dwFlags |= ANNOTFLAG_PRINT;
-          }
-
-          if (dwFlags != pWidget->GetFlags()) {
-            pWidget->SetFlags(dwFlags);
-            UpdateFormControl(pDocument, pFormControl, TRUE, FALSE, TRUE);
-          }
-        }
-      }
-    }
-  }
-}
-
-FX_BOOL Field::highlight(IJS_Context* cc,
-                         CJS_PropValue& vp,
-                         CFX_WideString& sError) {
-  ASSERT(m_pDocument);
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    CFX_ByteString strMode;
-    vp >> strMode;
-
-    if (m_bDelay) {
-      AddDelay_String(FP_HIGHLIGHT, strMode);
-    } else {
-      Field::SetHighlight(m_pDocument, m_FieldName, m_nFormControlIndex,
-                          strMode);
-    }
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    if (pFormField->GetFieldType() != FIELDTYPE_PUSHBUTTON)
-      return FALSE;
-
-    CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
-    if (!pFormControl)
-      return FALSE;
-
-    int eHM = pFormControl->GetHighlightingMode();
-    switch (eHM) {
-      case CPDF_FormControl::None:
-        vp << L"none";
-        break;
-      case CPDF_FormControl::Push:
-        vp << L"push";
-        break;
-      case CPDF_FormControl::Invert:
-        vp << L"invert";
-        break;
-      case CPDF_FormControl::Outline:
-        vp << L"outline";
-        break;
-      case CPDF_FormControl::Toggle:
-        vp << L"toggle";
-        break;
-    }
-  }
-
-  return TRUE;
-}
-
-void Field::SetHighlight(CPDFSDK_Document* pDocument,
-                         const CFX_WideString& swFieldName,
-                         int nControlIndex,
-                         const CFX_ByteString& string) {
-  // Not supported.
-}
-
-FX_BOOL Field::lineWidth(IJS_Context* cc,
-                         CJS_PropValue& vp,
-                         CFX_WideString& sError) {
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    int iWidth;
-    vp >> iWidth;
-
-    if (m_bDelay) {
-      AddDelay_Int(FP_LINEWIDTH, iWidth);
-    } else {
-      Field::SetLineWidth(m_pDocument, m_FieldName, m_nFormControlIndex,
-                          iWidth);
-    }
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    ASSERT(pFormField);
-    CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
-    if (!pFormControl)
-      return FALSE;
-
-    CPDFSDK_InterForm* pInterForm =
-        (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
-    if (!pFormField->CountControls())
-      return FALSE;
-
-    CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormField->GetControl(0));
-    if (!pWidget)
-      return FALSE;
-
-    vp << (int32_t)pWidget->GetBorderWidth();
-  }
-
-  return TRUE;
-}
-
-void Field::SetLineWidth(CPDFSDK_Document* pDocument,
-                         const CFX_WideString& swFieldName,
-                         int nControlIndex,
-                         int number) {
-  CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)pDocument->GetInterForm();
-
-  std::vector<CPDF_FormField*> FieldArray =
-      GetFormFields(pDocument, swFieldName);
-  for (CPDF_FormField* pFormField : FieldArray) {
-    if (nControlIndex < 0) {
-      FX_BOOL bSet = FALSE;
-      for (int i = 0, sz = pFormField->CountControls(); i < sz; ++i) {
-        CPDF_FormControl* pFormControl = pFormField->GetControl(i);
-        ASSERT(pFormControl);
-
-        if (CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormControl)) {
-          if (number != pWidget->GetBorderWidth()) {
-            pWidget->SetBorderWidth(number);
-            bSet = TRUE;
-          }
-        }
-      }
-      if (bSet)
-        UpdateFormField(pDocument, pFormField, TRUE, TRUE, TRUE);
-    } else {
-      if (nControlIndex >= pFormField->CountControls())
-        return;
-      if (CPDF_FormControl* pFormControl =
-              pFormField->GetControl(nControlIndex)) {
-        if (CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormControl)) {
-          if (number != pWidget->GetBorderWidth()) {
-            pWidget->SetBorderWidth(number);
-            UpdateFormControl(pDocument, pFormControl, TRUE, TRUE, TRUE);
-          }
-        }
-      }
-    }
-  }
-}
-
-FX_BOOL Field::multiline(IJS_Context* cc,
-                         CJS_PropValue& vp,
-                         CFX_WideString& sError) {
-  ASSERT(m_pDocument);
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    bool bVP;
-    vp >> bVP;
-
-    if (m_bDelay) {
-      AddDelay_Bool(FP_MULTILINE, bVP);
-    } else {
-      Field::SetMultiline(m_pDocument, m_FieldName, m_nFormControlIndex, bVP);
-    }
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD)
-      return FALSE;
-
-    if (pFormField->GetFieldFlags() & FIELDFLAG_MULTILINE)
-      vp << true;
-    else
-      vp << false;
-  }
-
-  return TRUE;
-}
-
-void Field::SetMultiline(CPDFSDK_Document* pDocument,
-                         const CFX_WideString& swFieldName,
-                         int nControlIndex,
-                         bool b) {
-  // Not supported.
-}
-
-FX_BOOL Field::multipleSelection(IJS_Context* cc,
-                                 CJS_PropValue& vp,
-                                 CFX_WideString& sError) {
-  ASSERT(m_pDocument);
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    bool bVP;
-    vp >> bVP;
-
-    if (m_bDelay) {
-      AddDelay_Bool(FP_MULTIPLESELECTION, bVP);
-    } else {
-      Field::SetMultipleSelection(m_pDocument, m_FieldName, m_nFormControlIndex,
-                                  bVP);
-    }
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    if (pFormField->GetFieldType() != FIELDTYPE_LISTBOX)
-      return FALSE;
-
-    if (pFormField->GetFieldFlags() & FIELDFLAG_MULTISELECT)
-      vp << true;
-    else
-      vp << false;
-  }
-
-  return TRUE;
-}
-
-void Field::SetMultipleSelection(CPDFSDK_Document* pDocument,
-                                 const CFX_WideString& swFieldName,
-                                 int nControlIndex,
-                                 bool b) {
-  // Not supported.
-}
-
-FX_BOOL Field::name(IJS_Context* cc,
-                    CJS_PropValue& vp,
-                    CFX_WideString& sError) {
-  if (!vp.IsGetting())
-    return FALSE;
-
-  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-  if (FieldArray.empty())
-    return FALSE;
-
-  vp << m_FieldName;
-
-  return TRUE;
-}
-
-FX_BOOL Field::numItems(IJS_Context* cc,
-                        CJS_PropValue& vp,
-                        CFX_WideString& sError) {
-  if (!vp.IsGetting())
-    return FALSE;
-
-  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-  if (FieldArray.empty())
-    return FALSE;
-
-  CPDF_FormField* pFormField = FieldArray[0];
-  if (pFormField->GetFieldType() != FIELDTYPE_COMBOBOX &&
-      pFormField->GetFieldType() != FIELDTYPE_LISTBOX) {
-    return FALSE;
-  }
-
-  vp << (int32_t)pFormField->CountOptions();
-  return TRUE;
-}
-
-FX_BOOL Field::page(IJS_Context* cc,
-                    CJS_PropValue& vp,
-                    CFX_WideString& sError) {
-  if (!vp.IsGetting())
-    return FALSE;
-
-  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-  if (FieldArray.empty())
-    return FALSE;
-
-  CPDF_FormField* pFormField = FieldArray[0];
-  if (!pFormField)
-    return FALSE;
-
-  std::vector<CPDFSDK_Widget*> widgets;
-  m_pDocument->GetInterForm()->GetWidgets(pFormField, &widgets);
-
-  if (widgets.empty()) {
-    vp << (int32_t)-1;
-    return TRUE;
-  }
-
-  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
-  CJS_Array PageArray(pRuntime);
-  for (size_t i = 0; i < widgets.size(); ++i) {
-    CPDFSDK_PageView* pPageView = widgets[i]->GetPageView();
-    if (!pPageView)
-      return FALSE;
-
-    PageArray.SetElement(
-        i, CJS_Value(pRuntime, (int32_t)pPageView->GetPageIndex()));
-  }
-
-  vp << PageArray;
-  return TRUE;
-}
-
-FX_BOOL Field::password(IJS_Context* cc,
-                        CJS_PropValue& vp,
-                        CFX_WideString& sError) {
-  ASSERT(m_pDocument);
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    bool bVP;
-    vp >> bVP;
-
-    if (m_bDelay) {
-      AddDelay_Bool(FP_PASSWORD, bVP);
-    } else {
-      Field::SetPassword(m_pDocument, m_FieldName, m_nFormControlIndex, bVP);
-    }
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD)
-      return FALSE;
-
-    if (pFormField->GetFieldFlags() & FIELDFLAG_PASSWORD)
-      vp << true;
-    else
-      vp << false;
-  }
-
-  return TRUE;
-}
-
-void Field::SetPassword(CPDFSDK_Document* pDocument,
-                        const CFX_WideString& swFieldName,
-                        int nControlIndex,
-                        bool b) {
-  // Not supported.
-}
-
-FX_BOOL Field::print(IJS_Context* cc,
-                     CJS_PropValue& vp,
-                     CFX_WideString& sError) {
-  CPDFSDK_InterForm* pInterForm =
-      (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
-  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-  if (FieldArray.empty())
-    return FALSE;
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    bool bVP;
-    vp >> bVP;
-
-    for (CPDF_FormField* pFormField : FieldArray) {
-      if (m_nFormControlIndex < 0) {
-        FX_BOOL bSet = FALSE;
-        for (int i = 0, sz = pFormField->CountControls(); i < sz; ++i) {
-          if (CPDFSDK_Widget* pWidget =
-                  pInterForm->GetWidget(pFormField->GetControl(i))) {
-            FX_DWORD dwFlags = pWidget->GetFlags();
-            if (bVP)
-              dwFlags |= ANNOTFLAG_PRINT;
-            else
-              dwFlags &= ~ANNOTFLAG_PRINT;
-
-            if (dwFlags != pWidget->GetFlags()) {
-              pWidget->SetFlags(dwFlags);
-              bSet = TRUE;
-            }
-          }
-        }
-
-        if (bSet)
-          UpdateFormField(m_pDocument, pFormField, TRUE, FALSE, TRUE);
-      } else {
-        if (m_nFormControlIndex >= pFormField->CountControls())
-          return FALSE;
-        if (CPDF_FormControl* pFormControl =
-                pFormField->GetControl(m_nFormControlIndex)) {
-          if (CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormControl)) {
-            FX_DWORD dwFlags = pWidget->GetFlags();
-            if (bVP)
-              dwFlags |= ANNOTFLAG_PRINT;
-            else
-              dwFlags &= ~ANNOTFLAG_PRINT;
-
-            if (dwFlags != pWidget->GetFlags()) {
-              pWidget->SetFlags(dwFlags);
-              UpdateFormControl(m_pDocument,
-                                pFormField->GetControl(m_nFormControlIndex),
-                                TRUE, FALSE, TRUE);
-            }
-          }
-        }
-      }
-    }
-  } else {
-    CPDF_FormField* pFormField = FieldArray[0];
-    CPDFSDK_Widget* pWidget =
-        pInterForm->GetWidget(GetSmartFieldControl(pFormField));
-    if (!pWidget)
-      return FALSE;
-
-    if (pWidget->GetFlags() & ANNOTFLAG_PRINT)
-      vp << true;
-    else
-      vp << false;
-  }
-
-  return TRUE;
-}
-
-FX_BOOL Field::radiosInUnison(IJS_Context* cc,
-                              CJS_PropValue& vp,
-                              CFX_WideString& sError) {
-  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-  if (FieldArray.empty())
-    return FALSE;
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    bool bVP;
-    vp >> bVP;
-
-  } else {
-    CPDF_FormField* pFormField = FieldArray[0];
-    if (pFormField->GetFieldType() != FIELDTYPE_RADIOBUTTON)
-      return FALSE;
-
-    if (pFormField->GetFieldFlags() & FIELDFLAG_RADIOSINUNISON)
-      vp << true;
-    else
-      vp << false;
-  }
-
-  return TRUE;
-}
-
-FX_BOOL Field::readonly(IJS_Context* cc,
-                        CJS_PropValue& vp,
-                        CFX_WideString& sError) {
-  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-  if (FieldArray.empty())
-    return FALSE;
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    bool bVP;
-    vp >> bVP;
-
-  } else {
-    CPDF_FormField* pFormField = FieldArray[0];
-    if (pFormField->GetFieldFlags() & FIELDFLAG_READONLY)
-      vp << true;
-    else
-      vp << false;
-  }
-
-  return TRUE;
-}
-
-FX_BOOL Field::rect(IJS_Context* cc,
-                    CJS_PropValue& vp,
-                    CFX_WideString& sError) {
-  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
-  CJS_Value Upper_Leftx(pRuntime);
-  CJS_Value Upper_Lefty(pRuntime);
-  CJS_Value Lower_Rightx(pRuntime);
-  CJS_Value Lower_Righty(pRuntime);
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-    if (!vp.IsArrayObject())
-      return FALSE;
-
-    CJS_Array rcArray(pRuntime);
-    vp >> rcArray;
-    rcArray.GetElement(0, Upper_Leftx);
-    rcArray.GetElement(1, Upper_Lefty);
-    rcArray.GetElement(2, Lower_Rightx);
-    rcArray.GetElement(3, Lower_Righty);
-
-    FX_FLOAT pArray[4] = {0.0f, 0.0f, 0.0f, 0.0f};
-    pArray[0] = (FX_FLOAT)Upper_Leftx.ToInt();
-    pArray[1] = (FX_FLOAT)Lower_Righty.ToInt();
-    pArray[2] = (FX_FLOAT)Lower_Rightx.ToInt();
-    pArray[3] = (FX_FLOAT)Upper_Lefty.ToInt();
-
-    CPDF_Rect crRect(pArray);
-    if (m_bDelay) {
-      AddDelay_Rect(FP_RECT, crRect);
-    } else {
-      Field::SetRect(m_pDocument, m_FieldName, m_nFormControlIndex, crRect);
-    }
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    CPDFSDK_InterForm* pInterForm =
-        (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
-    CPDFSDK_Widget* pWidget =
-        pInterForm->GetWidget(GetSmartFieldControl(pFormField));
-    if (!pWidget)
-      return FALSE;
-
-    CFX_FloatRect crRect = pWidget->GetRect();
-    Upper_Leftx = (int32_t)crRect.left;
-    Upper_Lefty = (int32_t)crRect.top;
-    Lower_Rightx = (int32_t)crRect.right;
-    Lower_Righty = (int32_t)crRect.bottom;
-
-    CJS_Array rcArray(pRuntime);
-    rcArray.SetElement(0, Upper_Leftx);
-    rcArray.SetElement(1, Upper_Lefty);
-    rcArray.SetElement(2, Lower_Rightx);
-    rcArray.SetElement(3, Lower_Righty);
-    vp << rcArray;
-  }
-  return TRUE;
-}
-
-void Field::SetRect(CPDFSDK_Document* pDocument,
-                    const CFX_WideString& swFieldName,
-                    int nControlIndex,
-                    const CPDF_Rect& rect) {
-  CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)pDocument->GetInterForm();
-
-  std::vector<CPDF_FormField*> FieldArray =
-      GetFormFields(pDocument, swFieldName);
-  for (CPDF_FormField* pFormField : FieldArray) {
-    if (nControlIndex < 0) {
-      FX_BOOL bSet = FALSE;
-      for (int i = 0, sz = pFormField->CountControls(); i < sz; ++i) {
-        CPDF_FormControl* pFormControl = pFormField->GetControl(i);
-        ASSERT(pFormControl);
-
-        if (CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormControl)) {
-          CPDF_Rect crRect = rect;
-
-          CPDF_Page* pPDFPage = pWidget->GetPDFPage();
-          crRect.Intersect(pPDFPage->GetPageBBox());
-
-          if (!crRect.IsEmpty()) {
-            CPDF_Rect rcOld = pWidget->GetRect();
-            if (crRect.left != rcOld.left || crRect.right != rcOld.right ||
-                crRect.top != rcOld.top || crRect.bottom != rcOld.bottom) {
-              pWidget->SetRect(crRect);
-              bSet = TRUE;
-            }
-          }
-        }
-      }
-
-      if (bSet)
-        UpdateFormField(pDocument, pFormField, TRUE, TRUE, TRUE);
-    } else {
-      if (nControlIndex >= pFormField->CountControls())
-        return;
-      if (CPDF_FormControl* pFormControl =
-              pFormField->GetControl(nControlIndex)) {
-        if (CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormControl)) {
-          CPDF_Rect crRect = rect;
-
-          CPDF_Page* pPDFPage = pWidget->GetPDFPage();
-          crRect.Intersect(pPDFPage->GetPageBBox());
-
-          if (!crRect.IsEmpty()) {
-            CPDF_Rect rcOld = pWidget->GetRect();
-            if (crRect.left != rcOld.left || crRect.right != rcOld.right ||
-                crRect.top != rcOld.top || crRect.bottom != rcOld.bottom) {
-              pWidget->SetRect(crRect);
-              UpdateFormControl(pDocument, pFormControl, TRUE, TRUE, TRUE);
-            }
-          }
-        }
-      }
-    }
-  }
-}
-
-FX_BOOL Field::required(IJS_Context* cc,
-                        CJS_PropValue& vp,
-                        CFX_WideString& sError) {
-  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-  if (FieldArray.empty())
-    return FALSE;
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    bool bVP;
-    vp >> bVP;
-
-  } else {
-    CPDF_FormField* pFormField = FieldArray[0];
-    if (pFormField->GetFieldType() == FIELDTYPE_PUSHBUTTON)
-      return FALSE;
-
-    if (pFormField->GetFieldFlags() & FIELDFLAG_REQUIRED)
-      vp << true;
-    else
-      vp << false;
-  }
-
-  return TRUE;
-}
-
-FX_BOOL Field::richText(IJS_Context* cc,
-                        CJS_PropValue& vp,
-                        CFX_WideString& sError) {
-  ASSERT(m_pDocument);
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    bool bVP;
-    vp >> bVP;
-
-    if (m_bDelay) {
-      AddDelay_Bool(FP_RICHTEXT, bVP);
-    } else {
-      Field::SetRichText(m_pDocument, m_FieldName, m_nFormControlIndex, bVP);
-    }
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD)
-      return FALSE;
-
-    if (pFormField->GetFieldFlags() & FIELDFLAG_RICHTEXT)
-      vp << true;
-    else
-      vp << false;
-  }
-
-  return TRUE;
-}
-
-void Field::SetRichText(CPDFSDK_Document* pDocument,
-                        const CFX_WideString& swFieldName,
-                        int nControlIndex,
-                        bool b) {
-  // Not supported.
-}
-
-FX_BOOL Field::richValue(IJS_Context* cc,
-                         CJS_PropValue& vp,
-                         CFX_WideString& sError) {
-  return TRUE;
-}
-
-void Field::SetRichValue(CPDFSDK_Document* pDocument,
-                         const CFX_WideString& swFieldName,
-                         int nControlIndex) {
-  // Not supported.
-}
-
-FX_BOOL Field::rotation(IJS_Context* cc,
-                        CJS_PropValue& vp,
-                        CFX_WideString& sError) {
-  ASSERT(m_pDocument);
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    int nVP;
-    vp >> nVP;
-
-    if (m_bDelay) {
-      AddDelay_Int(FP_ROTATION, nVP);
-    } else {
-      Field::SetRotation(m_pDocument, m_FieldName, m_nFormControlIndex, nVP);
-    }
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
-    if (!pFormControl)
-      return FALSE;
-
-    vp << (int32_t)pFormControl->GetRotation();
-  }
-
-  return TRUE;
-}
-
-void Field::SetRotation(CPDFSDK_Document* pDocument,
-                        const CFX_WideString& swFieldName,
-                        int nControlIndex,
-                        int number) {
-  // Not supported.
-}
-
-FX_BOOL Field::strokeColor(IJS_Context* cc,
-                           CJS_PropValue& vp,
-                           CFX_WideString& sError) {
-  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
-  CJS_Array crArray(pRuntime);
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    if (!vp.IsArrayObject())
-      return FALSE;
-
-    vp >> crArray;
-
-    CPWL_Color color;
-    color::ConvertArrayToPWLColor(crArray, color);
-
-    if (m_bDelay) {
-      AddDelay_Color(FP_STROKECOLOR, color);
-    } else {
-      Field::SetStrokeColor(m_pDocument, m_FieldName, m_nFormControlIndex,
-                            color);
-    }
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
-    if (!pFormControl)
-      return FALSE;
-
-    int iColorType;
-    pFormControl->GetBorderColor(iColorType);
-
-    CPWL_Color color;
-    if (iColorType == COLORTYPE_TRANSPARENT) {
-      color = CPWL_Color(COLORTYPE_TRANSPARENT);
-    } else if (iColorType == COLORTYPE_GRAY) {
-      color =
-          CPWL_Color(COLORTYPE_GRAY, pFormControl->GetOriginalBorderColor(0));
-    } else if (iColorType == COLORTYPE_RGB) {
-      color = CPWL_Color(COLORTYPE_RGB, pFormControl->GetOriginalBorderColor(0),
-                         pFormControl->GetOriginalBorderColor(1),
-                         pFormControl->GetOriginalBorderColor(2));
-    } else if (iColorType == COLORTYPE_CMYK) {
-      color =
-          CPWL_Color(COLORTYPE_CMYK, pFormControl->GetOriginalBorderColor(0),
-                     pFormControl->GetOriginalBorderColor(1),
-                     pFormControl->GetOriginalBorderColor(2),
-                     pFormControl->GetOriginalBorderColor(3));
-    } else {
-      return FALSE;
-    }
-
-    color::ConvertPWLColorToArray(color, crArray);
-    vp << crArray;
-  }
-  return TRUE;
-}
-
-void Field::SetStrokeColor(CPDFSDK_Document* pDocument,
-                           const CFX_WideString& swFieldName,
-                           int nControlIndex,
-                           const CPWL_Color& color) {
-  // Not supported.
-}
-
-FX_BOOL Field::style(IJS_Context* cc,
-                     CJS_PropValue& vp,
-                     CFX_WideString& sError) {
-  ASSERT(m_pDocument);
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    CFX_ByteString csBCaption;
-    vp >> csBCaption;
-
-    if (m_bDelay) {
-      AddDelay_String(FP_STYLE, csBCaption);
-    } else {
-      Field::SetStyle(m_pDocument, m_FieldName, m_nFormControlIndex,
-                      csBCaption);
-    }
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    if (pFormField->GetFieldType() != FIELDTYPE_RADIOBUTTON &&
-        pFormField->GetFieldType() != FIELDTYPE_CHECKBOX) {
-      return FALSE;
-    }
-
-    CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
-    if (!pFormControl)
-      return FALSE;
-
-    CFX_WideString csWCaption = pFormControl->GetNormalCaption();
-    CFX_ByteString csBCaption;
-
-    switch (csWCaption[0]) {
-      case L'l':
-        csBCaption = "circle";
-        break;
-      case L'8':
-        csBCaption = "cross";
-        break;
-      case L'u':
-        csBCaption = "diamond";
-        break;
-      case L'n':
-        csBCaption = "square";
-        break;
-      case L'H':
-        csBCaption = "star";
-        break;
-      default:  // L'4'
-        csBCaption = "check";
-        break;
-    }
-    vp << csBCaption;
-  }
-
-  return TRUE;
-}
-
-void Field::SetStyle(CPDFSDK_Document* pDocument,
-                     const CFX_WideString& swFieldName,
-                     int nControlIndex,
-                     const CFX_ByteString& string) {
-  // Not supported.
-}
-
-FX_BOOL Field::submitName(IJS_Context* cc,
-                          CJS_PropValue& vp,
-                          CFX_WideString& sError) {
-  return TRUE;
-}
-
-FX_BOOL Field::textColor(IJS_Context* cc,
-                         CJS_PropValue& vp,
-                         CFX_WideString& sError) {
-  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
-  CJS_Array crArray(pRuntime);
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    if (!vp.IsArrayObject())
-      return FALSE;
-
-    vp >> crArray;
-
-    CPWL_Color color;
-    color::ConvertArrayToPWLColor(crArray, color);
-
-    if (m_bDelay) {
-      AddDelay_Color(FP_TEXTCOLOR, color);
-    } else {
-      Field::SetTextColor(m_pDocument, m_FieldName, m_nFormControlIndex, color);
-    }
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
-    if (!pFormControl)
-      return FALSE;
-
-    int iColorType;
-    FX_ARGB color;
-    CPDF_DefaultAppearance FieldAppearance =
-        pFormControl->GetDefaultAppearance();
-    FieldAppearance.GetColor(color, iColorType);
-    int32_t a, r, g, b;
-    ArgbDecode(color, a, r, g, b);
-
-    CPWL_Color crRet =
-        CPWL_Color(COLORTYPE_RGB, r / 255.0f, g / 255.0f, b / 255.0f);
-
-    if (iColorType == COLORTYPE_TRANSPARENT)
-      crRet = CPWL_Color(COLORTYPE_TRANSPARENT);
-
-    color::ConvertPWLColorToArray(crRet, crArray);
-    vp << crArray;
-  }
-  return TRUE;
-}
-
-void Field::SetTextColor(CPDFSDK_Document* pDocument,
-                         const CFX_WideString& swFieldName,
-                         int nControlIndex,
-                         const CPWL_Color& color) {
-  // Not supported.
-}
-
-FX_BOOL Field::textFont(IJS_Context* cc,
-                        CJS_PropValue& vp,
-                        CFX_WideString& sError) {
-  ASSERT(m_pDocument);
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    CFX_ByteString csFontName;
-    vp >> csFontName;
-    if (csFontName.IsEmpty())
-      return FALSE;
-
-    if (m_bDelay) {
-      AddDelay_String(FP_TEXTFONT, csFontName);
-    } else {
-      Field::SetTextFont(m_pDocument, m_FieldName, m_nFormControlIndex,
-                         csFontName);
-    }
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    ASSERT(pFormField);
-    CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
-    if (!pFormControl)
-      return FALSE;
-
-    int nFieldType = pFormField->GetFieldType();
-
-    if (nFieldType == FIELDTYPE_PUSHBUTTON ||
-        nFieldType == FIELDTYPE_COMBOBOX || nFieldType == FIELDTYPE_LISTBOX ||
-        nFieldType == FIELDTYPE_TEXTFIELD) {
-      CPDF_Font* pFont = pFormControl->GetDefaultControlFont();
-      if (!pFont)
-        return FALSE;
-
-      vp << pFont->GetBaseFont();
-    } else {
-      return FALSE;
-    }
-  }
-
-  return TRUE;
-}
-
-void Field::SetTextFont(CPDFSDK_Document* pDocument,
-                        const CFX_WideString& swFieldName,
-                        int nControlIndex,
-                        const CFX_ByteString& string) {
-  // Not supported.
-}
-
-FX_BOOL Field::textSize(IJS_Context* cc,
-                        CJS_PropValue& vp,
-                        CFX_WideString& sError) {
-  ASSERT(m_pDocument);
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    int nVP;
-    vp >> nVP;
-
-    if (m_bDelay) {
-      AddDelay_Int(FP_TEXTSIZE, nVP);
-    } else {
-      Field::SetTextSize(m_pDocument, m_FieldName, m_nFormControlIndex, nVP);
-    }
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    ASSERT(pFormField);
-    CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
-    if (!pFormControl)
-      return FALSE;
-
-    CPDF_DefaultAppearance FieldAppearance =
-        pFormControl->GetDefaultAppearance();
-
-    CFX_ByteString csFontNameTag;
-    FX_FLOAT fFontSize;
-    FieldAppearance.GetFont(csFontNameTag, fFontSize);
-
-    vp << (int)fFontSize;
-  }
-
-  return TRUE;
-}
-
-void Field::SetTextSize(CPDFSDK_Document* pDocument,
-                        const CFX_WideString& swFieldName,
-                        int nControlIndex,
-                        int number) {
-  // Not supported.
-}
-
-FX_BOOL Field::type(IJS_Context* cc,
-                    CJS_PropValue& vp,
-                    CFX_WideString& sError) {
-  if (!vp.IsGetting())
-    return FALSE;
-
-  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-  if (FieldArray.empty())
-    return FALSE;
-
-  CPDF_FormField* pFormField = FieldArray[0];
-  switch (pFormField->GetFieldType()) {
-    case FIELDTYPE_UNKNOWN:
-      vp << L"unknown";
-      break;
-    case FIELDTYPE_PUSHBUTTON:
-      vp << L"button";
-      break;
-    case FIELDTYPE_CHECKBOX:
-      vp << L"checkbox";
-      break;
-    case FIELDTYPE_RADIOBUTTON:
-      vp << L"radiobutton";
-      break;
-    case FIELDTYPE_COMBOBOX:
-      vp << L"combobox";
-      break;
-    case FIELDTYPE_LISTBOX:
-      vp << L"listbox";
-      break;
-    case FIELDTYPE_TEXTFIELD:
-      vp << L"text";
-      break;
-    case FIELDTYPE_SIGNATURE:
-      vp << L"signature";
-      break;
-    default:
-      vp << L"unknown";
-      break;
-  }
-
-  return TRUE;
-}
-
-FX_BOOL Field::userName(IJS_Context* cc,
-                        CJS_PropValue& vp,
-                        CFX_WideString& sError) {
-  ASSERT(m_pDocument);
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    CFX_WideString swName;
-    vp >> swName;
-
-    if (m_bDelay) {
-      AddDelay_WideString(FP_USERNAME, swName);
-    } else {
-      Field::SetUserName(m_pDocument, m_FieldName, m_nFormControlIndex, swName);
-    }
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    vp << (CFX_WideString)pFormField->GetAlternateName();
-  }
-
-  return TRUE;
-}
-
-void Field::SetUserName(CPDFSDK_Document* pDocument,
-                        const CFX_WideString& swFieldName,
-                        int nControlIndex,
-                        const CFX_WideString& string) {
-  // Not supported.
-}
-
-FX_BOOL Field::value(IJS_Context* cc,
-                     CJS_PropValue& vp,
-                     CFX_WideString& sError) {
-  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
-
-  if (vp.IsSetting()) {
-    if (!m_bCanSet)
-      return FALSE;
-
-    CJS_WideStringArray strArray;
-
-    if (vp.IsArrayObject()) {
-      CJS_Array ValueArray(pRuntime);
-      vp.ConvertToArray(ValueArray);
-      for (int i = 0, sz = ValueArray.GetLength(); i < sz; i++) {
-        CJS_Value ElementValue(pRuntime);
-        ValueArray.GetElement(i, ElementValue);
-        strArray.Add(ElementValue.ToCFXWideString());
-      }
-    } else {
-      CFX_WideString swValue;
-      vp >> swValue;
-      strArray.Add(swValue);
-    }
-
-    if (m_bDelay) {
-      AddDelay_WideStringArray(FP_VALUE, strArray);
-    } else {
-      Field::SetValue(m_pDocument, m_FieldName, m_nFormControlIndex, strArray);
-    }
-  } else {
-    std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-    if (FieldArray.empty())
-      return FALSE;
-
-    CPDF_FormField* pFormField = FieldArray[0];
-    switch (pFormField->GetFieldType()) {
-      case FIELDTYPE_PUSHBUTTON:
-        return FALSE;
-      case FIELDTYPE_COMBOBOX:
-      case FIELDTYPE_TEXTFIELD: {
-        CFX_WideString swValue = pFormField->GetValue();
-
-        double dRet;
-        FX_BOOL bDot;
-        if (CJS_PublicMethods::ConvertStringToNumber(swValue.c_str(), dRet,
-                                                     bDot)) {
-          if (bDot)
-            vp << dRet;
-          else
-            vp << dRet;
-        } else {
-          vp << swValue;
-        }
-      } break;
-      case FIELDTYPE_LISTBOX: {
-        if (pFormField->CountSelectedItems() > 1) {
-          CJS_Array ValueArray(pRuntime);
-          CJS_Value ElementValue(pRuntime);
-          int iIndex;
-          for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz; i++) {
-            iIndex = pFormField->GetSelectedIndex(i);
-            ElementValue = pFormField->GetOptionValue(iIndex).c_str();
-            if (FXSYS_wcslen(ElementValue.ToCFXWideString().c_str()) == 0)
-              ElementValue = pFormField->GetOptionLabel(iIndex).c_str();
-            ValueArray.SetElement(i, ElementValue);
-          }
-          vp << ValueArray;
-        } else {
-          CFX_WideString swValue = pFormField->GetValue();
-
-          double dRet;
-          FX_BOOL bDot;
-          if (CJS_PublicMethods::ConvertStringToNumber(swValue.c_str(), dRet,
-                                                       bDot)) {
-            if (bDot)
-              vp << dRet;
-            else
-              vp << dRet;
-          } else {
-            vp << swValue;
-          }
-        }
-      } break;
-      case FIELDTYPE_CHECKBOX:
-      case FIELDTYPE_RADIOBUTTON: {
-        FX_BOOL bFind = FALSE;
-        for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
-          if (!pFormField->GetControl(i)->IsChecked())
-            continue;
-
-          CFX_WideString swValue = pFormField->GetControl(i)->GetExportValue();
-          double dRet;
-          FX_BOOL bDotDummy;
-          if (CJS_PublicMethods::ConvertStringToNumber(swValue.c_str(), dRet,
-                                                       bDotDummy)) {
-            vp << dRet;
-          } else {
-            vp << swValue;
-          }
-
-          bFind = TRUE;
-          break;
-        }
-        if (!bFind)
-          vp << L"Off";
-      } break;
-      default:
-        vp << pFormField->GetValue();
-        break;
-    }
-  }
-
-  return TRUE;
-}
-
-void Field::SetValue(CPDFSDK_Document* pDocument,
-                     const CFX_WideString& swFieldName,
-                     int nControlIndex,
-                     const CJS_WideStringArray& strArray) {
-  ASSERT(pDocument);
-
-  if (strArray.GetSize() < 1)
-    return;
-
-  std::vector<CPDF_FormField*> FieldArray =
-      GetFormFields(pDocument, swFieldName);
-
-  for (CPDF_FormField* pFormField : FieldArray) {
-    if (pFormField->GetFullName().Compare(swFieldName) != 0)
-      continue;
-
-    switch (pFormField->GetFieldType()) {
-      case FIELDTYPE_TEXTFIELD:
-      case FIELDTYPE_COMBOBOX:
-        if (pFormField->GetValue() != strArray.GetAt(0)) {
-          CFX_WideString WideString = strArray.GetAt(0);
-          pFormField->SetValue(strArray.GetAt(0), TRUE);
-          UpdateFormField(pDocument, pFormField, TRUE, FALSE, TRUE);
-        }
-        break;
-      case FIELDTYPE_CHECKBOX:  // mantis: 0004493
-      case FIELDTYPE_RADIOBUTTON: {
-        if (pFormField->GetValue() != strArray.GetAt(0)) {
-          pFormField->SetValue(strArray.GetAt(0), TRUE);
-          UpdateFormField(pDocument, pFormField, TRUE, FALSE, TRUE);
-        }
-      } break;
-      case FIELDTYPE_LISTBOX: {
-        FX_BOOL bModified = FALSE;
-
-        for (int i = 0, sz = strArray.GetSize(); i < sz; i++) {
-          int iIndex = pFormField->FindOption(strArray.GetAt(i));
-
-          if (!pFormField->IsItemSelected(iIndex)) {
-            bModified = TRUE;
-            break;
-          }
-        }
-
-        if (bModified) {
-          pFormField->ClearSelection(TRUE);
-          for (int i = 0, sz = strArray.GetSize(); i < sz; i++) {
-            int iIndex = pFormField->FindOption(strArray.GetAt(i));
-            pFormField->SetItemSelection(iIndex, TRUE, TRUE);
-          }
-
-          UpdateFormField(pDocument, pFormField, TRUE, FALSE, TRUE);
-        }
-      } break;
-      default:
-        break;
-    }
-  }
-}
-
-FX_BOOL Field::valueAsString(IJS_Context* cc,
-                             CJS_PropValue& vp,
-                             CFX_WideString& sError) {
-  if (!vp.IsGetting())
-    return FALSE;
-
-  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-  if (FieldArray.empty())
-    return FALSE;
-
-  CPDF_FormField* pFormField = FieldArray[0];
-  if (pFormField->GetFieldType() == FIELDTYPE_PUSHBUTTON)
-    return FALSE;
-
-  if (pFormField->GetFieldType() == FIELDTYPE_CHECKBOX) {
-    if (!pFormField->CountControls())
-      return FALSE;
-
-    if (pFormField->GetControl(0)->IsChecked())
-      vp << L"Yes";
-    else
-      vp << L"Off";
-  } else if (pFormField->GetFieldType() == FIELDTYPE_RADIOBUTTON &&
-             !(pFormField->GetFieldFlags() & FIELDFLAG_RADIOSINUNISON)) {
-    for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
-      if (pFormField->GetControl(i)->IsChecked()) {
-        vp << pFormField->GetControl(i)->GetExportValue().c_str();
-        break;
-      } else {
-        vp << L"Off";
-      }
-    }
-  } else if (pFormField->GetFieldType() == FIELDTYPE_LISTBOX &&
-             (pFormField->CountSelectedItems() > 1)) {
-    vp << L"";
-  } else {
-    vp << pFormField->GetValue().c_str();
-  }
-
-  return TRUE;
-}
-
-FX_BOOL Field::browseForFileToSubmit(IJS_Context* cc,
-                                     const std::vector<CJS_Value>& params,
-                                     CJS_Value& vRet,
-                                     CFX_WideString& sError) {
-  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-  if (FieldArray.empty())
-    return FALSE;
-
-  CPDF_FormField* pFormField = FieldArray[0];
-  CPDFDoc_Environment* pApp = m_pDocument->GetEnv();
-  if ((pFormField->GetFieldFlags() & FIELDFLAG_FILESELECT) &&
-      (pFormField->GetFieldType() == FIELDTYPE_TEXTFIELD)) {
-    CFX_WideString wsFileName = pApp->JS_fieldBrowse();
-    if (!wsFileName.IsEmpty()) {
-      pFormField->SetValue(wsFileName);
-      UpdateFormField(m_pDocument, pFormField, TRUE, TRUE, TRUE);
-    }
-    return TRUE;
-  }
-  return FALSE;
-}
-
-FX_BOOL Field::buttonGetCaption(IJS_Context* cc,
-                                const std::vector<CJS_Value>& params,
-                                CJS_Value& vRet,
-                                CFX_WideString& sError) {
-  int nface = 0;
-  int iSize = params.size();
-  if (iSize >= 1)
-    nface = params[0].ToInt();
-
-  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-  if (FieldArray.empty())
-    return FALSE;
-
-  CPDF_FormField* pFormField = FieldArray[0];
-  if (pFormField->GetFieldType() != FIELDTYPE_PUSHBUTTON)
-    return FALSE;
-
-  CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
-  if (!pFormControl)
-    return FALSE;
-
-  if (nface == 0)
-    vRet = pFormControl->GetNormalCaption().c_str();
-  else if (nface == 1)
-    vRet = pFormControl->GetDownCaption().c_str();
-  else if (nface == 2)
-    vRet = pFormControl->GetRolloverCaption().c_str();
-  else
-    return FALSE;
-
-  return TRUE;
-}
-
-FX_BOOL Field::buttonGetIcon(IJS_Context* cc,
-                             const std::vector<CJS_Value>& params,
-                             CJS_Value& vRet,
-                             CFX_WideString& sError) {
-  int nface = 0;
-  int iSize = params.size();
-  if (iSize >= 1)
-    nface = params[0].ToInt();
-
-  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-  if (FieldArray.empty())
-    return FALSE;
-
-  CPDF_FormField* pFormField = FieldArray[0];
-  if (pFormField->GetFieldType() != FIELDTYPE_PUSHBUTTON)
-    return FALSE;
-
-  CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
-  if (!pFormControl)
-    return FALSE;
-
-  CJS_Context* pContext = (CJS_Context*)cc;
-  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
-  v8::Local<v8::Object> pObj = FXJS_NewFxDynamicObj(
-      pRuntime->GetIsolate(), pRuntime, CJS_Icon::g_nObjDefnID);
-  ASSERT(pObj.IsEmpty() == FALSE);
-
-  CJS_Icon* pJS_Icon = (CJS_Icon*)FXJS_GetPrivate(pRuntime->GetIsolate(), pObj);
-  Icon* pIcon = (Icon*)pJS_Icon->GetEmbedObject();
-
-  CPDF_Stream* pIconStream = NULL;
-  if (nface == 0)
-    pIconStream = pFormControl->GetNormalIcon();
-  else if (nface == 1)
-    pIconStream = pFormControl->GetDownIcon();
-  else if (nface == 2)
-    pIconStream = pFormControl->GetRolloverIcon();
-  else
-    return FALSE;
-
-  pIcon->SetStream(pIconStream);
-  vRet = pJS_Icon;
-
-  return TRUE;
-}
-
-FX_BOOL Field::buttonImportIcon(IJS_Context* cc,
-                                const std::vector<CJS_Value>& params,
-                                CJS_Value& vRet,
-                                CFX_WideString& sError) {
-  return TRUE;
-}
-
-FX_BOOL Field::buttonSetCaption(IJS_Context* cc,
-                                const std::vector<CJS_Value>& params,
-                                CJS_Value& vRet,
-                                CFX_WideString& sError) {
-  return FALSE;
-}
-
-FX_BOOL Field::buttonSetIcon(IJS_Context* cc,
-                             const std::vector<CJS_Value>& params,
-                             CJS_Value& vRet,
-                             CFX_WideString& sError) {
-  return FALSE;
-}
-
-FX_BOOL Field::checkThisBox(IJS_Context* cc,
-                            const std::vector<CJS_Value>& params,
-                            CJS_Value& vRet,
-                            CFX_WideString& sError) {
-  ASSERT(m_pDocument);
-
-  if (!m_bCanSet)
-    return FALSE;
-
-  int iSize = params.size();
-  if (iSize < 1)
-    return FALSE;
-
-  int nWidget = params[0].ToInt();
-
-  FX_BOOL bCheckit = TRUE;
-  if (iSize >= 2)
-    bCheckit = params[1].ToBool();
-
-  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-  if (FieldArray.empty())
-    return FALSE;
-
-  CPDF_FormField* pFormField = FieldArray[0];
-  if (pFormField->GetFieldType() != FIELDTYPE_CHECKBOX &&
-      pFormField->GetFieldType() != FIELDTYPE_RADIOBUTTON)
-    return FALSE;
-  if (nWidget < 0 || nWidget >= pFormField->CountControls())
-    return FALSE;
-  if (pFormField->GetFieldType() == FIELDTYPE_RADIOBUTTON)
-    pFormField->CheckControl(nWidget, bCheckit, TRUE);
-  else
-    pFormField->CheckControl(nWidget, bCheckit, TRUE);
-
-  UpdateFormField(m_pDocument, pFormField, TRUE, TRUE, TRUE);
-  return TRUE;
-}
-
-FX_BOOL Field::clearItems(IJS_Context* cc,
-                          const std::vector<CJS_Value>& params,
-                          CJS_Value& vRet,
-                          CFX_WideString& sError) {
-  return TRUE;
-}
-
-FX_BOOL Field::defaultIsChecked(IJS_Context* cc,
-                                const std::vector<CJS_Value>& params,
-                                CJS_Value& vRet,
-                                CFX_WideString& sError) {
-  if (!m_bCanSet)
-    return FALSE;
-
-  int iSize = params.size();
-  if (iSize < 1)
-    return FALSE;
-
-  int nWidget = params[0].ToInt();
-
-  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-  if (FieldArray.empty())
-    return FALSE;
-
-  CPDF_FormField* pFormField = FieldArray[0];
-  if (nWidget < 0 || nWidget >= pFormField->CountControls()) {
-    vRet = FALSE;
-    return FALSE;
-  }
-  vRet = pFormField->GetFieldType() == FIELDTYPE_CHECKBOX ||
-         pFormField->GetFieldType() == FIELDTYPE_RADIOBUTTON;
-
-  return TRUE;
-}
-
-FX_BOOL Field::deleteItemAt(IJS_Context* cc,
-                            const std::vector<CJS_Value>& params,
-                            CJS_Value& vRet,
-                            CFX_WideString& sError) {
-  return TRUE;
-}
-
-int JS_COMPARESTRING(CFX_WideString* ps1, CFX_WideString* ps2) {
-  return ps1->Compare(*ps2);
-}
-
-FX_BOOL Field::getArray(IJS_Context* cc,
-                        const std::vector<CJS_Value>& params,
-                        CJS_Value& vRet,
-                        CFX_WideString& sError) {
-  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-  if (FieldArray.empty())
-    return FALSE;
-
-  CGW_ArrayTemplate<CFX_WideString*> swSort;
-
-  for (CPDF_FormField* pFormField : FieldArray)
-    swSort.Add(new CFX_WideString(pFormField->GetFullName()));
-  swSort.Sort(JS_COMPARESTRING);
-
-  CJS_Context* pContext = (CJS_Context*)cc;
-  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
-  ASSERT(pRuntime);
-
-  CJS_Array FormFieldArray(pRuntime);
-  for (int j = 0, jsz = swSort.GetSize(); j < jsz; j++) {
-    std::unique_ptr<CFX_WideString> pStr(swSort.GetAt(j));
-    v8::Local<v8::Object> pObj = FXJS_NewFxDynamicObj(
-        pRuntime->GetIsolate(), pRuntime, CJS_Field::g_nObjDefnID);
-    ASSERT(!pObj.IsEmpty());
-
-    CJS_Field* pJSField =
-        (CJS_Field*)FXJS_GetPrivate(pRuntime->GetIsolate(), pObj);
-    Field* pField = (Field*)pJSField->GetEmbedObject();
-    pField->AttachField(m_pJSDoc, *pStr);
-
-    CJS_Value FormFieldValue(pRuntime);
-    FormFieldValue = pJSField;
-    FormFieldArray.SetElement(j, FormFieldValue);
-  }
-
-  vRet = FormFieldArray;
-  swSort.RemoveAll();
-  return TRUE;
-}
-
-FX_BOOL Field::getItemAt(IJS_Context* cc,
-                         const std::vector<CJS_Value>& params,
-                         CJS_Value& vRet,
-                         CFX_WideString& sError) {
-  int iSize = params.size();
-
-  int nIdx = -1;
-  if (iSize >= 1)
-    nIdx = params[0].ToInt();
-
-  FX_BOOL bExport = TRUE;
-  if (iSize >= 2)
-    bExport = params[1].ToBool();
-
-  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-  if (FieldArray.empty())
-    return FALSE;
-
-  CPDF_FormField* pFormField = FieldArray[0];
-  if ((pFormField->GetFieldType() == FIELDTYPE_LISTBOX) ||
-      (pFormField->GetFieldType() == FIELDTYPE_COMBOBOX)) {
-    if (nIdx == -1 || nIdx > pFormField->CountOptions())
-      nIdx = pFormField->CountOptions() - 1;
-    if (bExport) {
-      CFX_WideString strval = pFormField->GetOptionValue(nIdx);
-      if (strval.IsEmpty())
-        vRet = pFormField->GetOptionLabel(nIdx).c_str();
-      else
-        vRet = strval.c_str();
-    } else {
-      vRet = pFormField->GetOptionLabel(nIdx).c_str();
-    }
-  } else {
-    return FALSE;
-  }
-
-  return TRUE;
-}
-
-FX_BOOL Field::getLock(IJS_Context* cc,
-                       const std::vector<CJS_Value>& params,
-                       CJS_Value& vRet,
-                       CFX_WideString& sError) {
-  return FALSE;
-}
-
-FX_BOOL Field::insertItemAt(IJS_Context* cc,
-                            const std::vector<CJS_Value>& params,
-                            CJS_Value& vRet,
-                            CFX_WideString& sError) {
-  return TRUE;
-}
-
-FX_BOOL Field::isBoxChecked(IJS_Context* cc,
-                            const std::vector<CJS_Value>& params,
-                            CJS_Value& vRet,
-                            CFX_WideString& sError) {
-  int nIndex = -1;
-  if (params.size() >= 1)
-    nIndex = params[0].ToInt();
-
-  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-  if (FieldArray.empty())
-    return FALSE;
-
-  CPDF_FormField* pFormField = FieldArray[0];
-  if (nIndex < 0 || nIndex >= pFormField->CountControls()) {
-    vRet = FALSE;
-    return FALSE;
-  }
-
-  if ((pFormField->GetFieldType() == FIELDTYPE_CHECKBOX) ||
-      (pFormField->GetFieldType() == FIELDTYPE_RADIOBUTTON)) {
-    if (pFormField->GetControl(nIndex)->IsChecked() != 0)
-      vRet = TRUE;
-    else
-      vRet = FALSE;
-  } else {
-    vRet = FALSE;
-  }
-
-  return TRUE;
-}
-
-FX_BOOL Field::isDefaultChecked(IJS_Context* cc,
-                                const std::vector<CJS_Value>& params,
-                                CJS_Value& vRet,
-                                CFX_WideString& sError) {
-  int nIndex = -1;
-  if (params.size() >= 1)
-    nIndex = params[0].ToInt();
-
-  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-  if (FieldArray.empty())
-    return FALSE;
-
-  CPDF_FormField* pFormField = FieldArray[0];
-  if (nIndex < 0 || nIndex >= pFormField->CountControls()) {
-    vRet = FALSE;
-    return FALSE;
-  }
-  if ((pFormField->GetFieldType() == FIELDTYPE_CHECKBOX) ||
-      (pFormField->GetFieldType() == FIELDTYPE_RADIOBUTTON)) {
-    if (pFormField->GetControl(nIndex)->IsDefaultChecked() != 0)
-      vRet = TRUE;
-    else
-      vRet = FALSE;
-  } else {
-    vRet = FALSE;
-  }
-
-  return TRUE;
-}
-
-FX_BOOL Field::setAction(IJS_Context* cc,
-                         const std::vector<CJS_Value>& params,
-                         CJS_Value& vRet,
-                         CFX_WideString& sError) {
-  return TRUE;
-}
-
-FX_BOOL Field::setFocus(IJS_Context* cc,
-                        const std::vector<CJS_Value>& params,
-                        CJS_Value& vRet,
-                        CFX_WideString& sError) {
-  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
-  if (FieldArray.empty())
-    return FALSE;
-
-  CPDF_FormField* pFormField = FieldArray[0];
-  int32_t nCount = pFormField->CountControls();
-  if (nCount < 1)
-    return FALSE;
-
-  CPDFSDK_InterForm* pInterForm =
-      (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
-  CPDFSDK_Widget* pWidget = NULL;
-  if (nCount == 1) {
-    pWidget = pInterForm->GetWidget(pFormField->GetControl(0));
-  } else {
-    CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
-    UnderlyingPageType* pPage = UnderlyingFromFPDFPage(
-        pEnv->FFI_GetCurrentPage(m_pDocument->GetUnderlyingDocument()));
-    if (!pPage)
-      return FALSE;
-    if (CPDFSDK_PageView* pCurPageView = m_pDocument->GetPageView(pPage)) {
-      for (int32_t i = 0; i < nCount; i++) {
-        if (CPDFSDK_Widget* pTempWidget =
-                pInterForm->GetWidget(pFormField->GetControl(i))) {
-          if (pTempWidget->GetPDFPage() == pCurPageView->GetPDFPage()) {
-            pWidget = pTempWidget;
-            break;
-          }
-        }
-      }
-    }
-  }
-
-  if (pWidget) {
-    m_pDocument->SetFocusAnnot(pWidget);
-  }
-
-  return TRUE;
-}
-
-FX_BOOL Field::setItems(IJS_Context* cc,
-                        const std::vector<CJS_Value>& params,
-                        CJS_Value& vRet,
-                        CFX_WideString& sError) {
-  return TRUE;
-}
-
-FX_BOOL Field::setLock(IJS_Context* cc,
-                       const std::vector<CJS_Value>& params,
-                       CJS_Value& vRet,
-                       CFX_WideString& sError) {
-  return FALSE;
-}
-
-FX_BOOL Field::signatureGetModifications(IJS_Context* cc,
-                                         const std::vector<CJS_Value>& params,
-                                         CJS_Value& vRet,
-                                         CFX_WideString& sError) {
-  return FALSE;
-}
-
-FX_BOOL Field::signatureGetSeedValue(IJS_Context* cc,
-                                     const std::vector<CJS_Value>& params,
-                                     CJS_Value& vRet,
-                                     CFX_WideString& sError) {
-  return FALSE;
-}
-
-FX_BOOL Field::signatureInfo(IJS_Context* cc,
-                             const std::vector<CJS_Value>& params,
-                             CJS_Value& vRet,
-                             CFX_WideString& sError) {
-  return FALSE;
-}
-
-FX_BOOL Field::signatureSetSeedValue(IJS_Context* cc,
-                                     const std::vector<CJS_Value>& params,
-                                     CJS_Value& vRet,
-                                     CFX_WideString& sError) {
-  return FALSE;
-}
-
-FX_BOOL Field::signatureSign(IJS_Context* cc,
-                             const std::vector<CJS_Value>& params,
-                             CJS_Value& vRet,
-                             CFX_WideString& sError) {
-  return FALSE;
-}
-
-FX_BOOL Field::signatureValidate(IJS_Context* cc,
-                                 const std::vector<CJS_Value>& params,
-                                 CJS_Value& vRet,
-                                 CFX_WideString& sError) {
-  return FALSE;
-}
-
-FX_BOOL Field::source(IJS_Context* cc,
-                      CJS_PropValue& vp,
-                      CFX_WideString& sError) {
-  if (vp.IsGetting()) {
-    vp << (CJS_Object*)NULL;
-  }
-
-  return TRUE;
-}
-
-void Field::AddDelay_Int(enum FIELD_PROP prop, int32_t n) {
-  CJS_DelayData* pNewData = new CJS_DelayData;
-  pNewData->sFieldName = m_FieldName;
-  pNewData->nControlIndex = m_nFormControlIndex;
-  pNewData->eProp = prop;
-  pNewData->num = n;
-
-  m_pJSDoc->AddDelayData(pNewData);
-}
-
-void Field::AddDelay_Bool(enum FIELD_PROP prop, bool b) {
-  CJS_DelayData* pNewData = new CJS_DelayData;
-  pNewData->sFieldName = m_FieldName;
-  pNewData->nControlIndex = m_nFormControlIndex;
-  pNewData->eProp = prop;
-  pNewData->b = b;
-
-  m_pJSDoc->AddDelayData(pNewData);
-}
-
-void Field::AddDelay_String(enum FIELD_PROP prop,
-                            const CFX_ByteString& string) {
-  CJS_DelayData* pNewData = new CJS_DelayData;
-  pNewData->sFieldName = m_FieldName;
-  pNewData->nControlIndex = m_nFormControlIndex;
-  pNewData->eProp = prop;
-  pNewData->string = string;
-
-  m_pJSDoc->AddDelayData(pNewData);
-}
-
-void Field::AddDelay_WideString(enum FIELD_PROP prop,
-                                const CFX_WideString& string) {
-  CJS_DelayData* pNewData = new CJS_DelayData;
-  pNewData->sFieldName = m_FieldName;
-  pNewData->nControlIndex = m_nFormControlIndex;
-  pNewData->eProp = prop;
-  pNewData->widestring = string;
-
-  m_pJSDoc->AddDelayData(pNewData);
-}
-
-void Field::AddDelay_Rect(enum FIELD_PROP prop, const CPDF_Rect& rect) {
-  CJS_DelayData* pNewData = new CJS_DelayData;
-  pNewData->sFieldName = m_FieldName;
-  pNewData->nControlIndex = m_nFormControlIndex;
-  pNewData->eProp = prop;
-  pNewData->rect = rect;
-
-  m_pJSDoc->AddDelayData(pNewData);
-}
-
-void Field::AddDelay_Color(enum FIELD_PROP prop, const CPWL_Color& color) {
-  CJS_DelayData* pNewData = new CJS_DelayData;
-  pNewData->sFieldName = m_FieldName;
-  pNewData->nControlIndex = m_nFormControlIndex;
-  pNewData->eProp = prop;
-  pNewData->color = color;
-
-  m_pJSDoc->AddDelayData(pNewData);
-}
-
-void Field::AddDelay_WordArray(enum FIELD_PROP prop,
-                               const CFX_DWordArray& array) {
-  CJS_DelayData* pNewData = new CJS_DelayData;
-  pNewData->sFieldName = m_FieldName;
-  pNewData->nControlIndex = m_nFormControlIndex;
-  pNewData->eProp = prop;
-
-  for (int i = 0, sz = array.GetSize(); i < sz; i++)
-    pNewData->wordarray.Add(array.GetAt(i));
-
-  m_pJSDoc->AddDelayData(pNewData);
-}
-
-void Field::AddDelay_WideStringArray(enum FIELD_PROP prop,
-                                     const CJS_WideStringArray& array) {
-  CJS_DelayData* pNewData = new CJS_DelayData;
-  pNewData->sFieldName = m_FieldName;
-  pNewData->nControlIndex = m_nFormControlIndex;
-  pNewData->eProp = prop;
-  for (int i = 0, sz = array.GetSize(); i < sz; i++)
-    pNewData->widestringarray.Add(array.GetAt(i));
-
-  m_pJSDoc->AddDelayData(pNewData);
-}
-
-void Field::DoDelay(CPDFSDK_Document* pDocument, CJS_DelayData* pData) {
-  ASSERT(pDocument);
-
-  switch (pData->eProp) {
-    case FP_ALIGNMENT:
-      Field::SetAlignment(pDocument, pData->sFieldName, pData->nControlIndex,
-                          pData->string);
-      break;
-    case FP_BORDERSTYLE:
-      Field::SetBorderStyle(pDocument, pData->sFieldName, pData->nControlIndex,
-                            pData->string);
-      break;
-    case FP_BUTTONALIGNX:
-      Field::SetButtonAlignX(pDocument, pData->sFieldName, pData->nControlIndex,
-                             pData->num);
-      break;
-    case FP_BUTTONALIGNY:
-      Field::SetButtonAlignY(pDocument, pData->sFieldName, pData->nControlIndex,
-                             pData->num);
-      break;
-    case FP_BUTTONFITBOUNDS:
-      Field::SetButtonFitBounds(pDocument, pData->sFieldName,
-                                pData->nControlIndex, pData->b);
-      break;
-    case FP_BUTTONPOSITION:
-      Field::SetButtonPosition(pDocument, pData->sFieldName,
-                               pData->nControlIndex, pData->num);
-      break;
-    case FP_BUTTONSCALEHOW:
-      Field::SetButtonScaleHow(pDocument, pData->sFieldName,
-                               pData->nControlIndex, pData->num);
-      break;
-    case FP_BUTTONSCALEWHEN:
-      Field::SetButtonScaleWhen(pDocument, pData->sFieldName,
-                                pData->nControlIndex, pData->num);
-      break;
-    case FP_CALCORDERINDEX:
-      Field::SetCalcOrderIndex(pDocument, pData->sFieldName,
-                               pData->nControlIndex, pData->num);
-      break;
-    case FP_CHARLIMIT:
-      Field::SetCharLimit(pDocument, pData->sFieldName, pData->nControlIndex,
-                          pData->num);
-      break;
-    case FP_COMB:
-      Field::SetComb(pDocument, pData->sFieldName, pData->nControlIndex,
-                     pData->b);
-      break;
-    case FP_COMMITONSELCHANGE:
-      Field::SetCommitOnSelChange(pDocument, pData->sFieldName,
-                                  pData->nControlIndex, pData->b);
-      break;
-    case FP_CURRENTVALUEINDICES:
-      Field::SetCurrentValueIndices(pDocument, pData->sFieldName,
-                                    pData->nControlIndex, pData->wordarray);
-      break;
-    case FP_DEFAULTVALUE:
-      Field::SetDefaultValue(pDocument, pData->sFieldName, pData->nControlIndex,
-                             pData->widestring);
-      break;
-    case FP_DONOTSCROLL:
-      Field::SetDoNotScroll(pDocument, pData->sFieldName, pData->nControlIndex,
-                            pData->b);
-      break;
-    case FP_DISPLAY:
-      Field::SetDisplay(pDocument, pData->sFieldName, pData->nControlIndex,
-                        pData->num);
-      break;
-    case FP_FILLCOLOR:
-      Field::SetFillColor(pDocument, pData->sFieldName, pData->nControlIndex,
-                          pData->color);
-      break;
-    case FP_HIDDEN:
-      Field::SetHidden(pDocument, pData->sFieldName, pData->nControlIndex,
-                       pData->b);
-      break;
-    case FP_HIGHLIGHT:
-      Field::SetHighlight(pDocument, pData->sFieldName, pData->nControlIndex,
-                          pData->string);
-      break;
-    case FP_LINEWIDTH:
-      Field::SetLineWidth(pDocument, pData->sFieldName, pData->nControlIndex,
-                          pData->num);
-      break;
-    case FP_MULTILINE:
-      Field::SetMultiline(pDocument, pData->sFieldName, pData->nControlIndex,
-                          pData->b);
-      break;
-    case FP_MULTIPLESELECTION:
-      Field::SetMultipleSelection(pDocument, pData->sFieldName,
-                                  pData->nControlIndex, pData->b);
-      break;
-    case FP_PASSWORD:
-      Field::SetPassword(pDocument, pData->sFieldName, pData->nControlIndex,
-                         pData->b);
-      break;
-    case FP_RECT:
-      Field::SetRect(pDocument, pData->sFieldName, pData->nControlIndex,
-                     pData->rect);
-      break;
-    case FP_RICHTEXT:
-      Field::SetRichText(pDocument, pData->sFieldName, pData->nControlIndex,
-                         pData->b);
-      break;
-    case FP_RICHVALUE:
-      break;
-    case FP_ROTATION:
-      Field::SetRotation(pDocument, pData->sFieldName, pData->nControlIndex,
-                         pData->num);
-      break;
-    case FP_STROKECOLOR:
-      Field::SetStrokeColor(pDocument, pData->sFieldName, pData->nControlIndex,
-                            pData->color);
-      break;
-    case FP_STYLE:
-      Field::SetStyle(pDocument, pData->sFieldName, pData->nControlIndex,
-                      pData->string);
-      break;
-    case FP_TEXTCOLOR:
-      Field::SetTextColor(pDocument, pData->sFieldName, pData->nControlIndex,
-                          pData->color);
-      break;
-    case FP_TEXTFONT:
-      Field::SetTextFont(pDocument, pData->sFieldName, pData->nControlIndex,
-                         pData->string);
-      break;
-    case FP_TEXTSIZE:
-      Field::SetTextSize(pDocument, pData->sFieldName, pData->nControlIndex,
-                         pData->num);
-      break;
-    case FP_USERNAME:
-      Field::SetUserName(pDocument, pData->sFieldName, pData->nControlIndex,
-                         pData->widestring);
-      break;
-    case FP_VALUE:
-      Field::SetValue(pDocument, pData->sFieldName, pData->nControlIndex,
-                      pData->widestringarray);
-      break;
-  }
-}
-
-void Field::AddField(CPDFSDK_Document* pDocument,
-                     int nPageIndex,
-                     int nFieldType,
-                     const CFX_WideString& sName,
-                     const CPDF_Rect& rcCoords) {
-  // Not supported.
-}
diff --git a/fpdfsdk/src/javascript/Field.h b/fpdfsdk/src/javascript/Field.h
deleted file mode 100644
index cd81795..0000000
--- a/fpdfsdk/src/javascript/Field.h
+++ /dev/null
@@ -1,584 +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_SRC_JAVASCRIPT_FIELD_H_
-#define FPDFSDK_SRC_JAVASCRIPT_FIELD_H_
-
-#include <string>  // For std::wstring.
-
-#include "JS_Define.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Wnd.h"  // For CPWL_Color.
-
-class CPDFSDK_Widget;
-class Document;
-
-enum FIELD_PROP {
-  FP_ALIGNMENT,
-  FP_BORDERSTYLE,
-  FP_BUTTONALIGNX,
-  FP_BUTTONALIGNY,
-  FP_BUTTONFITBOUNDS,
-  FP_BUTTONPOSITION,
-  FP_BUTTONSCALEHOW,
-  FP_BUTTONSCALEWHEN,
-  FP_CALCORDERINDEX,
-  FP_CHARLIMIT,
-  FP_COMB,
-  FP_COMMITONSELCHANGE,
-  FP_CURRENTVALUEINDICES,
-  FP_DEFAULTVALUE,
-  FP_DONOTSCROLL,
-  FP_DISPLAY,
-  FP_FILLCOLOR,
-  FP_HIDDEN,
-  FP_HIGHLIGHT,
-  FP_LINEWIDTH,
-  FP_MULTILINE,
-  FP_MULTIPLESELECTION,
-  FP_PASSWORD,
-  FP_RECT,
-  FP_RICHTEXT,
-  FP_RICHVALUE,
-  FP_ROTATION,
-  FP_STROKECOLOR,
-  FP_STYLE,
-  FP_TEXTCOLOR,
-  FP_TEXTFONT,
-  FP_TEXTSIZE,
-  FP_USERNAME,
-  FP_VALUE
-};
-
-class CJS_WideStringArray {
- public:
-  CJS_WideStringArray() {}
-  virtual ~CJS_WideStringArray() {
-    for (int i = 0, sz = m_Data.GetSize(); i < sz; i++)
-      delete m_Data.GetAt(i);
-    m_Data.RemoveAll();
-  }
-
-  void Add(const CFX_WideString& string) {
-    m_Data.Add(new CFX_WideString(string));
-  }
-
-  int GetSize() const { return m_Data.GetSize(); }
-
-  CFX_WideString GetAt(int i) const { return *m_Data.GetAt(i); }
-
- private:
-  CFX_ArrayTemplate<CFX_WideString*> m_Data;
-};
-
-struct CJS_DelayData {
-  CFX_WideString sFieldName;
-  int nControlIndex;
-  enum FIELD_PROP eProp;
-  int32_t num;
-  bool b;
-  CFX_ByteString string;
-  CFX_WideString widestring;
-  CPDF_Rect rect;
-  CPWL_Color color;
-  CFX_DWordArray wordarray;
-  CJS_WideStringArray widestringarray;
-};
-
-class Field : public CJS_EmbedObj {
- public:
-  explicit Field(CJS_Object* pJSObject);
-  ~Field() override;
-
-  FX_BOOL alignment(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL borderStyle(IJS_Context* cc,
-                      CJS_PropValue& vp,
-                      CFX_WideString& sError);
-  FX_BOOL buttonAlignX(IJS_Context* cc,
-                       CJS_PropValue& vp,
-                       CFX_WideString& sError);
-  FX_BOOL buttonAlignY(IJS_Context* cc,
-                       CJS_PropValue& vp,
-                       CFX_WideString& sError);
-  FX_BOOL buttonFitBounds(IJS_Context* cc,
-                          CJS_PropValue& vp,
-                          CFX_WideString& sError);
-  FX_BOOL buttonPosition(IJS_Context* cc,
-                         CJS_PropValue& vp,
-                         CFX_WideString& sError);
-  FX_BOOL buttonScaleHow(IJS_Context* cc,
-                         CJS_PropValue& vp,
-                         CFX_WideString& sError);
-  FX_BOOL buttonScaleWhen(IJS_Context* cc,
-                          CJS_PropValue& vp,
-                          CFX_WideString& sError);
-  FX_BOOL calcOrderIndex(IJS_Context* cc,
-                         CJS_PropValue& vp,
-                         CFX_WideString& sError);
-  FX_BOOL charLimit(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL comb(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL commitOnSelChange(IJS_Context* cc,
-                            CJS_PropValue& vp,
-                            CFX_WideString& sError);
-  FX_BOOL currentValueIndices(IJS_Context* cc,
-                              CJS_PropValue& vp,
-                              CFX_WideString& sError);
-  FX_BOOL defaultStyle(IJS_Context* cc,
-                       CJS_PropValue& vp,
-                       CFX_WideString& sError);
-  FX_BOOL defaultValue(IJS_Context* cc,
-                       CJS_PropValue& vp,
-                       CFX_WideString& sError);
-  FX_BOOL doNotScroll(IJS_Context* cc,
-                      CJS_PropValue& vp,
-                      CFX_WideString& sError);
-  FX_BOOL doNotSpellCheck(IJS_Context* cc,
-                          CJS_PropValue& vp,
-                          CFX_WideString& sError);
-  FX_BOOL delay(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL display(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL doc(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL editable(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL exportValues(IJS_Context* cc,
-                       CJS_PropValue& vp,
-                       CFX_WideString& sError);
-  FX_BOOL fileSelect(IJS_Context* cc,
-                     CJS_PropValue& vp,
-                     CFX_WideString& sError);
-  FX_BOOL fillColor(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL hidden(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL highlight(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL lineWidth(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL multiline(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL multipleSelection(IJS_Context* cc,
-                            CJS_PropValue& vp,
-                            CFX_WideString& sError);
-  FX_BOOL name(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL numItems(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL page(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL password(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL print(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL radiosInUnison(IJS_Context* cc,
-                         CJS_PropValue& vp,
-                         CFX_WideString& sError);
-  FX_BOOL readonly(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL rect(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL required(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL richText(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL richValue(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL rotation(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL strokeColor(IJS_Context* cc,
-                      CJS_PropValue& vp,
-                      CFX_WideString& sError);
-  FX_BOOL style(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL submitName(IJS_Context* cc,
-                     CJS_PropValue& vp,
-                     CFX_WideString& sError);
-  FX_BOOL textColor(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL textFont(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL textSize(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL type(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL userName(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL value(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL valueAsString(IJS_Context* cc,
-                        CJS_PropValue& vp,
-                        CFX_WideString& sError);
-  FX_BOOL source(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-
-  FX_BOOL browseForFileToSubmit(IJS_Context* cc,
-                                const std::vector<CJS_Value>& params,
-                                CJS_Value& vRet,
-                                CFX_WideString& sError);
-  FX_BOOL buttonGetCaption(IJS_Context* cc,
-                           const std::vector<CJS_Value>& params,
-                           CJS_Value& vRet,
-                           CFX_WideString& sError);
-  FX_BOOL buttonGetIcon(IJS_Context* cc,
-                        const std::vector<CJS_Value>& params,
-                        CJS_Value& vRet,
-                        CFX_WideString& sError);
-  FX_BOOL buttonImportIcon(IJS_Context* cc,
-                           const std::vector<CJS_Value>& params,
-                           CJS_Value& vRet,
-                           CFX_WideString& sError);
-  FX_BOOL buttonSetCaption(IJS_Context* cc,
-                           const std::vector<CJS_Value>& params,
-                           CJS_Value& vRet,
-                           CFX_WideString& sError);
-  FX_BOOL buttonSetIcon(IJS_Context* cc,
-                        const std::vector<CJS_Value>& params,
-                        CJS_Value& vRet,
-                        CFX_WideString& sError);
-  FX_BOOL checkThisBox(IJS_Context* cc,
-                       const std::vector<CJS_Value>& params,
-                       CJS_Value& vRet,
-                       CFX_WideString& sError);
-  FX_BOOL clearItems(IJS_Context* cc,
-                     const std::vector<CJS_Value>& params,
-                     CJS_Value& vRet,
-                     CFX_WideString& sError);
-  FX_BOOL defaultIsChecked(IJS_Context* cc,
-                           const std::vector<CJS_Value>& params,
-                           CJS_Value& vRet,
-                           CFX_WideString& sError);
-  FX_BOOL deleteItemAt(IJS_Context* cc,
-                       const std::vector<CJS_Value>& params,
-                       CJS_Value& vRet,
-                       CFX_WideString& sError);
-  FX_BOOL getArray(IJS_Context* cc,
-                   const std::vector<CJS_Value>& params,
-                   CJS_Value& vRet,
-                   CFX_WideString& sError);
-  FX_BOOL getItemAt(IJS_Context* cc,
-                    const std::vector<CJS_Value>& params,
-                    CJS_Value& vRet,
-                    CFX_WideString& sError);
-  FX_BOOL getLock(IJS_Context* cc,
-                  const std::vector<CJS_Value>& params,
-                  CJS_Value& vRet,
-                  CFX_WideString& sError);
-  FX_BOOL insertItemAt(IJS_Context* cc,
-                       const std::vector<CJS_Value>& params,
-                       CJS_Value& vRet,
-                       CFX_WideString& sError);
-  FX_BOOL isBoxChecked(IJS_Context* cc,
-                       const std::vector<CJS_Value>& params,
-                       CJS_Value& vRet,
-                       CFX_WideString& sError);
-  FX_BOOL isDefaultChecked(IJS_Context* cc,
-                           const std::vector<CJS_Value>& params,
-                           CJS_Value& vRet,
-                           CFX_WideString& sError);
-  FX_BOOL setAction(IJS_Context* cc,
-                    const std::vector<CJS_Value>& params,
-                    CJS_Value& vRet,
-                    CFX_WideString& sError);
-  FX_BOOL setFocus(IJS_Context* cc,
-                   const std::vector<CJS_Value>& params,
-                   CJS_Value& vRet,
-                   CFX_WideString& sError);
-  FX_BOOL setItems(IJS_Context* cc,
-                   const std::vector<CJS_Value>& params,
-                   CJS_Value& vRet,
-                   CFX_WideString& sError);
-  FX_BOOL setLock(IJS_Context* cc,
-                  const std::vector<CJS_Value>& params,
-                  CJS_Value& vRet,
-                  CFX_WideString& sError);
-  FX_BOOL signatureGetModifications(IJS_Context* cc,
-                                    const std::vector<CJS_Value>& params,
-                                    CJS_Value& vRet,
-                                    CFX_WideString& sError);
-  FX_BOOL signatureGetSeedValue(IJS_Context* cc,
-                                const std::vector<CJS_Value>& params,
-                                CJS_Value& vRet,
-                                CFX_WideString& sError);
-  FX_BOOL signatureInfo(IJS_Context* cc,
-                        const std::vector<CJS_Value>& params,
-                        CJS_Value& vRet,
-                        CFX_WideString& sError);
-  FX_BOOL signatureSetSeedValue(IJS_Context* cc,
-                                const std::vector<CJS_Value>& params,
-                                CJS_Value& vRet,
-                                CFX_WideString& sError);
-  FX_BOOL signatureSign(IJS_Context* cc,
-                        const std::vector<CJS_Value>& params,
-                        CJS_Value& vRet,
-                        CFX_WideString& sError);
-  FX_BOOL signatureValidate(IJS_Context* cc,
-                            const std::vector<CJS_Value>& params,
-                            CJS_Value& vRet,
-                            CFX_WideString& sError);
-
-  static void SetAlignment(CPDFSDK_Document* pDocument,
-                           const CFX_WideString& swFieldName,
-                           int nControlIndex,
-                           const CFX_ByteString& string);
-  static void SetBorderStyle(CPDFSDK_Document* pDocument,
-                             const CFX_WideString& swFieldName,
-                             int nControlIndex,
-                             const CFX_ByteString& string);
-  static void SetButtonAlignX(CPDFSDK_Document* pDocument,
-                              const CFX_WideString& swFieldName,
-                              int nControlIndex,
-                              int number);
-  static void SetButtonAlignY(CPDFSDK_Document* pDocument,
-                              const CFX_WideString& swFieldName,
-                              int nControlIndex,
-                              int number);
-  static void SetButtonFitBounds(CPDFSDK_Document* pDocument,
-                                 const CFX_WideString& swFieldName,
-                                 int nControlIndex,
-                                 bool b);
-  static void SetButtonPosition(CPDFSDK_Document* pDocument,
-                                const CFX_WideString& swFieldName,
-                                int nControlIndex,
-                                int number);
-  static void SetButtonScaleHow(CPDFSDK_Document* pDocument,
-                                const CFX_WideString& swFieldName,
-                                int nControlIndex,
-                                int number);
-  static void SetButtonScaleWhen(CPDFSDK_Document* pDocument,
-                                 const CFX_WideString& swFieldName,
-                                 int nControlIndex,
-                                 int number);
-  static void SetCalcOrderIndex(CPDFSDK_Document* pDocument,
-                                const CFX_WideString& swFieldName,
-                                int nControlIndex,
-                                int number);
-  static void SetCharLimit(CPDFSDK_Document* pDocument,
-                           const CFX_WideString& swFieldName,
-                           int nControlIndex,
-                           int number);
-  static void SetComb(CPDFSDK_Document* pDocument,
-                      const CFX_WideString& swFieldName,
-                      int nControlIndex,
-                      bool b);
-  static void SetCommitOnSelChange(CPDFSDK_Document* pDocument,
-                                   const CFX_WideString& swFieldName,
-                                   int nControlIndex,
-                                   bool b);
-  static void SetCurrentValueIndices(CPDFSDK_Document* pDocument,
-                                     const CFX_WideString& swFieldName,
-                                     int nControlIndex,
-                                     const CFX_DWordArray& array);
-  static void SetDefaultStyle(CPDFSDK_Document* pDocument,
-                              const CFX_WideString& swFieldName,
-                              int nControlIndex);
-  static void SetDefaultValue(CPDFSDK_Document* pDocument,
-                              const CFX_WideString& swFieldName,
-                              int nControlIndex,
-                              const CFX_WideString& string);
-  static void SetDoNotScroll(CPDFSDK_Document* pDocument,
-                             const CFX_WideString& swFieldName,
-                             int nControlIndex,
-                             bool b);
-  static void SetDisplay(CPDFSDK_Document* pDocument,
-                         const CFX_WideString& swFieldName,
-                         int nControlIndex,
-                         int number);
-  static void SetFillColor(CPDFSDK_Document* pDocument,
-                           const CFX_WideString& swFieldName,
-                           int nControlIndex,
-                           const CPWL_Color& color);
-  static void SetHidden(CPDFSDK_Document* pDocument,
-                        const CFX_WideString& swFieldName,
-                        int nControlIndex,
-                        bool b);
-  static void SetHighlight(CPDFSDK_Document* pDocument,
-                           const CFX_WideString& swFieldName,
-                           int nControlIndex,
-                           const CFX_ByteString& string);
-  static void SetLineWidth(CPDFSDK_Document* pDocument,
-                           const CFX_WideString& swFieldName,
-                           int nControlIndex,
-                           int number);
-  static void SetMultiline(CPDFSDK_Document* pDocument,
-                           const CFX_WideString& swFieldName,
-                           int nControlIndex,
-                           bool b);
-  static void SetMultipleSelection(CPDFSDK_Document* pDocument,
-                                   const CFX_WideString& swFieldName,
-                                   int nControlIndex,
-                                   bool b);
-  static void SetPassword(CPDFSDK_Document* pDocument,
-                          const CFX_WideString& swFieldName,
-                          int nControlIndex,
-                          bool b);
-  static void SetRect(CPDFSDK_Document* pDocument,
-                      const CFX_WideString& swFieldName,
-                      int nControlIndex,
-                      const CPDF_Rect& rect);
-  static void SetRichText(CPDFSDK_Document* pDocument,
-                          const CFX_WideString& swFieldName,
-                          int nControlIndex,
-                          bool b);
-  static void SetRichValue(CPDFSDK_Document* pDocument,
-                           const CFX_WideString& swFieldName,
-                           int nControlIndex);
-  static void SetRotation(CPDFSDK_Document* pDocument,
-                          const CFX_WideString& swFieldName,
-                          int nControlIndex,
-                          int number);
-  static void SetStrokeColor(CPDFSDK_Document* pDocument,
-                             const CFX_WideString& swFieldName,
-                             int nControlIndex,
-                             const CPWL_Color& color);
-  static void SetStyle(CPDFSDK_Document* pDocument,
-                       const CFX_WideString& swFieldName,
-                       int nControlIndex,
-                       const CFX_ByteString& string);
-  static void SetTextColor(CPDFSDK_Document* pDocument,
-                           const CFX_WideString& swFieldName,
-                           int nControlIndex,
-                           const CPWL_Color& color);
-  static void SetTextFont(CPDFSDK_Document* pDocument,
-                          const CFX_WideString& swFieldName,
-                          int nControlIndex,
-                          const CFX_ByteString& string);
-  static void SetTextSize(CPDFSDK_Document* pDocument,
-                          const CFX_WideString& swFieldName,
-                          int nControlIndex,
-                          int number);
-  static void SetUserName(CPDFSDK_Document* pDocument,
-                          const CFX_WideString& swFieldName,
-                          int nControlIndex,
-                          const CFX_WideString& string);
-  static void SetValue(CPDFSDK_Document* pDocument,
-                       const CFX_WideString& swFieldName,
-                       int nControlIndex,
-                       const CJS_WideStringArray& strArray);
-
-  static void AddField(CPDFSDK_Document* pDocument,
-                       int nPageIndex,
-                       int nFieldType,
-                       const CFX_WideString& sName,
-                       const CPDF_Rect& rcCoords);
-
-  static void UpdateFormField(CPDFSDK_Document* pDocument,
-                              CPDF_FormField* pFormField,
-                              FX_BOOL bChangeMark,
-                              FX_BOOL bResetAP,
-                              FX_BOOL bRefresh);
-  static void UpdateFormControl(CPDFSDK_Document* pDocument,
-                                CPDF_FormControl* pFormControl,
-                                FX_BOOL bChangeMark,
-                                FX_BOOL bResetAP,
-                                FX_BOOL bRefresh);
-
-  static CPDFSDK_Widget* GetWidget(CPDFSDK_Document* pDocument,
-                                   CPDF_FormControl* pFormControl);
-  static std::vector<CPDF_FormField*> GetFormFields(
-      CPDFSDK_Document* pDocument,
-      const CFX_WideString& csFieldName);
-
-  static void DoDelay(CPDFSDK_Document* pDocument, CJS_DelayData* pData);
-
-  FX_BOOL AttachField(Document* pDocument, const CFX_WideString& csFieldName);
-  void SetDelay(FX_BOOL bDelay);
-  void SetIsolate(v8::Isolate* isolate) { m_isolate = isolate; }
-
- protected:
-  void ParseFieldName(const std::wstring& strFieldNameParsed,
-                      std::wstring& strFieldName,
-                      int& iControlNo);
-  std::vector<CPDF_FormField*> GetFormFields(
-      const CFX_WideString& csFieldName) const;
-  CPDF_FormControl* GetSmartFieldControl(CPDF_FormField* pFormField);
-  FX_BOOL ValueIsOccur(CPDF_FormField* pFormField, CFX_WideString csOptLabel);
-
-  void AddDelay_Int(enum FIELD_PROP prop, int32_t n);
-  void AddDelay_Bool(enum FIELD_PROP prop, bool b);
-  void AddDelay_String(enum FIELD_PROP prop, const CFX_ByteString& string);
-  void AddDelay_WideString(enum FIELD_PROP prop, const CFX_WideString& string);
-  void AddDelay_Rect(enum FIELD_PROP prop, const CPDF_Rect& rect);
-  void AddDelay_Color(enum FIELD_PROP prop, const CPWL_Color& color);
-  void AddDelay_WordArray(enum FIELD_PROP prop, const CFX_DWordArray& array);
-  void AddDelay_WideStringArray(enum FIELD_PROP prop,
-                                const CJS_WideStringArray& array);
-
-  void DoDelay();
-
- public:
-  Document* m_pJSDoc;
-  CPDFSDK_Document* m_pDocument;
-  CFX_WideString m_FieldName;
-  int m_nFormControlIndex;
-  FX_BOOL m_bCanSet;
-
-  FX_BOOL m_bDelay;
-  v8::Isolate* m_isolate;
-};
-
-class CJS_Field : public CJS_Object {
- public:
-  explicit CJS_Field(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
-  ~CJS_Field(void) override {}
-
-  void InitInstance(IJS_Runtime* pIRuntime) override;
-
-  DECLARE_JS_CLASS();
-  JS_STATIC_PROP(alignment, Field);
-  JS_STATIC_PROP(borderStyle, Field);
-  JS_STATIC_PROP(buttonAlignX, Field);
-  JS_STATIC_PROP(buttonAlignY, Field);
-  JS_STATIC_PROP(buttonFitBounds, Field);
-  JS_STATIC_PROP(buttonPosition, Field);
-  JS_STATIC_PROP(buttonScaleHow, Field);
-  JS_STATIC_PROP(buttonScaleWhen, Field);
-  JS_STATIC_PROP(calcOrderIndex, Field);
-  JS_STATIC_PROP(charLimit, Field);
-  JS_STATIC_PROP(comb, Field);
-  JS_STATIC_PROP(commitOnSelChange, Field);
-  JS_STATIC_PROP(currentValueIndices, Field);
-  JS_STATIC_PROP(defaultStyle, Field);
-  JS_STATIC_PROP(defaultValue, Field);
-  JS_STATIC_PROP(doNotScroll, Field);
-  JS_STATIC_PROP(doNotSpellCheck, Field);
-  JS_STATIC_PROP(delay, Field);
-  JS_STATIC_PROP(display, Field);
-  JS_STATIC_PROP(doc, Field);
-  JS_STATIC_PROP(editable, Field);
-  JS_STATIC_PROP(exportValues, Field);
-  JS_STATIC_PROP(fileSelect, Field);
-  JS_STATIC_PROP(fillColor, Field);
-  JS_STATIC_PROP(hidden, Field);
-  JS_STATIC_PROP(highlight, Field);
-  JS_STATIC_PROP(lineWidth, Field);
-  JS_STATIC_PROP(multiline, Field);
-  JS_STATIC_PROP(multipleSelection, Field);
-  JS_STATIC_PROP(name, Field);
-  JS_STATIC_PROP(numItems, Field);
-  JS_STATIC_PROP(page, Field);
-  JS_STATIC_PROP(password, Field);
-  JS_STATIC_PROP(print, Field);
-  JS_STATIC_PROP(radiosInUnison, Field);
-  JS_STATIC_PROP(readonly, Field);
-  JS_STATIC_PROP(rect, Field);
-  JS_STATIC_PROP(required, Field);
-  JS_STATIC_PROP(richText, Field);
-  JS_STATIC_PROP(richValue, Field);
-  JS_STATIC_PROP(rotation, Field);
-  JS_STATIC_PROP(strokeColor, Field);
-  JS_STATIC_PROP(style, Field);
-  JS_STATIC_PROP(submitName, Field);
-  JS_STATIC_PROP(textColor, Field);
-  JS_STATIC_PROP(textFont, Field);
-  JS_STATIC_PROP(textSize, Field);
-  JS_STATIC_PROP(type, Field);
-  JS_STATIC_PROP(userName, Field);
-  JS_STATIC_PROP(value, Field);
-  JS_STATIC_PROP(valueAsString, Field);
-  JS_STATIC_PROP(source, Field);
-
-  JS_STATIC_METHOD(browseForFileToSubmit, Field);
-  JS_STATIC_METHOD(buttonGetCaption, Field);
-  JS_STATIC_METHOD(buttonGetIcon, Field);
-  JS_STATIC_METHOD(buttonImportIcon, Field);
-  JS_STATIC_METHOD(buttonSetCaption, Field);
-  JS_STATIC_METHOD(buttonSetIcon, Field);
-  JS_STATIC_METHOD(checkThisBox, Field);
-  JS_STATIC_METHOD(clearItems, Field);
-  JS_STATIC_METHOD(defaultIsChecked, Field);
-  JS_STATIC_METHOD(deleteItemAt, Field);
-  JS_STATIC_METHOD(getArray, Field);
-  JS_STATIC_METHOD(getItemAt, Field);
-  JS_STATIC_METHOD(getLock, Field);
-  JS_STATIC_METHOD(insertItemAt, Field);
-  JS_STATIC_METHOD(isBoxChecked, Field);
-  JS_STATIC_METHOD(isDefaultChecked, Field);
-  JS_STATIC_METHOD(setAction, Field);
-  JS_STATIC_METHOD(setFocus, Field);
-  JS_STATIC_METHOD(setItems, Field);
-  JS_STATIC_METHOD(setLock, Field);
-  JS_STATIC_METHOD(signatureGetModifications, Field);
-  JS_STATIC_METHOD(signatureGetSeedValue, Field);
-  JS_STATIC_METHOD(signatureInfo, Field);
-  JS_STATIC_METHOD(signatureSetSeedValue, Field);
-  JS_STATIC_METHOD(signatureSign, Field);
-  JS_STATIC_METHOD(signatureValidate, Field);
-};
-
-#endif  // FPDFSDK_SRC_JAVASCRIPT_FIELD_H_
diff --git a/fpdfsdk/src/javascript/JS_Context.cpp b/fpdfsdk/src/javascript/JS_Context.cpp
deleted file mode 100644
index 9dbf5ed..0000000
--- a/fpdfsdk/src/javascript/JS_Context.cpp
+++ /dev/null
@@ -1,284 +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
-
-#include "JS_Context.h"
-
-#include "JS_EventHandler.h"
-#include "JS_Runtime.h"
-#include "fpdfsdk/include/javascript/IJavaScript.h"
-#include "resource.h"
-
-/* -------------------------- CJS_Context -------------------------- */
-
-CJS_Context::CJS_Context(CJS_Runtime* pRuntime)
-    : m_pRuntime(pRuntime), m_bBusy(FALSE), m_bMsgBoxEnable(TRUE) {
-  m_pEventHandler = new CJS_EventHandler(this);
-}
-
-CJS_Context::~CJS_Context() {
-  delete m_pEventHandler;
-}
-
-CPDFSDK_Document* CJS_Context::GetReaderDocument() {
-  return m_pRuntime->GetReaderDocument();
-}
-
-CPDFDoc_Environment* CJS_Context::GetReaderApp() {
-  return m_pRuntime->GetReaderApp();
-}
-
-FX_BOOL CJS_Context::RunScript(const CFX_WideString& script,
-                               CFX_WideString* info) {
-  v8::Isolate::Scope isolate_scope(m_pRuntime->GetIsolate());
-#ifdef PDF_ENABLE_XFA
-  v8::Locker locker(m_pRuntime->GetIsolate());
-#endif  // PDF_ENABLE_XFA
-  v8::HandleScope handle_scope(m_pRuntime->GetIsolate());
-  v8::Local<v8::Context> context = m_pRuntime->NewJSContext();
-  v8::Context::Scope context_scope(context);
-
-  if (m_bBusy) {
-    *info = JSGetStringFromID(this, IDS_STRING_JSBUSY);
-    return FALSE;
-  }
-  m_bBusy = TRUE;
-
-  ASSERT(m_pEventHandler->IsValid());
-  CJS_Runtime::FieldEvent event(m_pEventHandler->TargetName(),
-                                m_pEventHandler->EventType());
-  if (!m_pRuntime->AddEventToSet(event)) {
-    *info = JSGetStringFromID(this, IDS_STRING_JSEVENT);
-    return FALSE;
-  }
-
-  CFX_WideString sErrorMessage;
-  int nRet = 0;
-  if (script.GetLength() > 0) {
-    nRet = m_pRuntime->Execute(this, script.c_str(), &sErrorMessage);
-  }
-
-  if (nRet < 0) {
-    *info += sErrorMessage;
-  } else {
-    *info = JSGetStringFromID(this, IDS_STRING_RUN);
-  }
-
-  m_pRuntime->RemoveEventFromSet(event);
-  m_pEventHandler->Destroy();
-  m_bBusy = FALSE;
-
-  return nRet >= 0;
-}
-
-void CJS_Context::OnApp_Init() {
-  m_pEventHandler->OnApp_Init();
-}
-
-void CJS_Context::OnDoc_Open(CPDFSDK_Document* pDoc,
-                             const CFX_WideString& strTargetName) {
-  m_pEventHandler->OnDoc_Open(pDoc, strTargetName);
-}
-
-void CJS_Context::OnDoc_WillPrint(CPDFSDK_Document* pDoc) {
-  m_pEventHandler->OnDoc_WillPrint(pDoc);
-}
-
-void CJS_Context::OnDoc_DidPrint(CPDFSDK_Document* pDoc) {
-  m_pEventHandler->OnDoc_DidPrint(pDoc);
-}
-
-void CJS_Context::OnDoc_WillSave(CPDFSDK_Document* pDoc) {
-  m_pEventHandler->OnDoc_WillSave(pDoc);
-}
-
-void CJS_Context::OnDoc_DidSave(CPDFSDK_Document* pDoc) {
-  m_pEventHandler->OnDoc_DidSave(pDoc);
-}
-
-void CJS_Context::OnDoc_WillClose(CPDFSDK_Document* pDoc) {
-  m_pEventHandler->OnDoc_WillClose(pDoc);
-}
-
-void CJS_Context::OnPage_Open(CPDFSDK_Document* pTarget) {
-  m_pEventHandler->OnPage_Open(pTarget);
-}
-
-void CJS_Context::OnPage_Close(CPDFSDK_Document* pTarget) {
-  m_pEventHandler->OnPage_Close(pTarget);
-}
-
-void CJS_Context::OnPage_InView(CPDFSDK_Document* pTarget) {
-  m_pEventHandler->OnPage_InView(pTarget);
-}
-
-void CJS_Context::OnPage_OutView(CPDFSDK_Document* pTarget) {
-  m_pEventHandler->OnPage_OutView(pTarget);
-}
-
-void CJS_Context::OnField_MouseDown(FX_BOOL bModifier,
-                                    FX_BOOL bShift,
-                                    CPDF_FormField* pTarget) {
-  m_pEventHandler->OnField_MouseDown(bModifier, bShift, pTarget);
-}
-
-void CJS_Context::OnField_MouseEnter(FX_BOOL bModifier,
-                                     FX_BOOL bShift,
-                                     CPDF_FormField* pTarget) {
-  m_pEventHandler->OnField_MouseEnter(bModifier, bShift, pTarget);
-}
-
-void CJS_Context::OnField_MouseExit(FX_BOOL bModifier,
-                                    FX_BOOL bShift,
-                                    CPDF_FormField* pTarget) {
-  m_pEventHandler->OnField_MouseExit(bModifier, bShift, pTarget);
-}
-
-void CJS_Context::OnField_MouseUp(FX_BOOL bModifier,
-                                  FX_BOOL bShift,
-                                  CPDF_FormField* pTarget) {
-  m_pEventHandler->OnField_MouseUp(bModifier, bShift, pTarget);
-}
-
-void CJS_Context::OnField_Focus(FX_BOOL bModifier,
-                                FX_BOOL bShift,
-                                CPDF_FormField* pTarget,
-                                const CFX_WideString& Value) {
-  m_pEventHandler->OnField_Focus(bModifier, bShift, pTarget, Value);
-}
-
-void CJS_Context::OnField_Blur(FX_BOOL bModifier,
-                               FX_BOOL bShift,
-                               CPDF_FormField* pTarget,
-                               const CFX_WideString& Value) {
-  m_pEventHandler->OnField_Blur(bModifier, bShift, pTarget, Value);
-}
-
-void CJS_Context::OnField_Calculate(CPDF_FormField* pSource,
-                                    CPDF_FormField* pTarget,
-                                    CFX_WideString& Value,
-                                    FX_BOOL& bRc) {
-  m_pEventHandler->OnField_Calculate(pSource, pTarget, Value, bRc);
-}
-
-void CJS_Context::OnField_Format(CPDF_FormField* pTarget,
-                                 CFX_WideString& Value,
-                                 FX_BOOL bWillCommit) {
-  m_pEventHandler->OnField_Format(pTarget, Value, bWillCommit);
-}
-
-void CJS_Context::OnField_Keystroke(CFX_WideString& strChange,
-                                    const CFX_WideString& strChangeEx,
-                                    FX_BOOL bKeyDown,
-                                    FX_BOOL bModifier,
-                                    int& nSelEnd,
-                                    int& nSelStart,
-                                    FX_BOOL bShift,
-                                    CPDF_FormField* pTarget,
-                                    CFX_WideString& Value,
-                                    FX_BOOL bWillCommit,
-                                    FX_BOOL bFieldFull,
-                                    FX_BOOL& bRc) {
-  m_pEventHandler->OnField_Keystroke(
-      strChange, strChangeEx, bKeyDown, bModifier, nSelEnd, nSelStart, bShift,
-      pTarget, Value, bWillCommit, bFieldFull, bRc);
-}
-
-void CJS_Context::OnField_Validate(CFX_WideString& strChange,
-                                   const CFX_WideString& strChangeEx,
-                                   FX_BOOL bKeyDown,
-                                   FX_BOOL bModifier,
-                                   FX_BOOL bShift,
-                                   CPDF_FormField* pTarget,
-                                   CFX_WideString& Value,
-                                   FX_BOOL& bRc) {
-  m_pEventHandler->OnField_Validate(strChange, strChangeEx, bKeyDown, bModifier,
-                                    bShift, pTarget, Value, bRc);
-}
-
-void CJS_Context::OnScreen_Focus(FX_BOOL bModifier,
-                                 FX_BOOL bShift,
-                                 CPDFSDK_Annot* pScreen) {
-  m_pEventHandler->OnScreen_Focus(bModifier, bShift, pScreen);
-}
-
-void CJS_Context::OnScreen_Blur(FX_BOOL bModifier,
-                                FX_BOOL bShift,
-                                CPDFSDK_Annot* pScreen) {
-  m_pEventHandler->OnScreen_Blur(bModifier, bShift, pScreen);
-}
-
-void CJS_Context::OnScreen_Open(FX_BOOL bModifier,
-                                FX_BOOL bShift,
-                                CPDFSDK_Annot* pScreen) {
-  m_pEventHandler->OnScreen_Open(bModifier, bShift, pScreen);
-}
-
-void CJS_Context::OnScreen_Close(FX_BOOL bModifier,
-                                 FX_BOOL bShift,
-                                 CPDFSDK_Annot* pScreen) {
-  m_pEventHandler->OnScreen_Close(bModifier, bShift, pScreen);
-}
-
-void CJS_Context::OnScreen_MouseDown(FX_BOOL bModifier,
-                                     FX_BOOL bShift,
-                                     CPDFSDK_Annot* pScreen) {
-  m_pEventHandler->OnScreen_MouseDown(bModifier, bShift, pScreen);
-}
-
-void CJS_Context::OnScreen_MouseUp(FX_BOOL bModifier,
-                                   FX_BOOL bShift,
-                                   CPDFSDK_Annot* pScreen) {
-  m_pEventHandler->OnScreen_MouseUp(bModifier, bShift, pScreen);
-}
-
-void CJS_Context::OnScreen_MouseEnter(FX_BOOL bModifier,
-                                      FX_BOOL bShift,
-                                      CPDFSDK_Annot* pScreen) {
-  m_pEventHandler->OnScreen_MouseEnter(bModifier, bShift, pScreen);
-}
-
-void CJS_Context::OnScreen_MouseExit(FX_BOOL bModifier,
-                                     FX_BOOL bShift,
-                                     CPDFSDK_Annot* pScreen) {
-  m_pEventHandler->OnScreen_MouseExit(bModifier, bShift, pScreen);
-}
-
-void CJS_Context::OnScreen_InView(FX_BOOL bModifier,
-                                  FX_BOOL bShift,
-                                  CPDFSDK_Annot* pScreen) {
-  m_pEventHandler->OnScreen_InView(bModifier, bShift, pScreen);
-}
-
-void CJS_Context::OnScreen_OutView(FX_BOOL bModifier,
-                                   FX_BOOL bShift,
-                                   CPDFSDK_Annot* pScreen) {
-  m_pEventHandler->OnScreen_OutView(bModifier, bShift, pScreen);
-}
-
-void CJS_Context::OnBookmark_MouseUp(CPDF_Bookmark* pBookMark) {
-  m_pEventHandler->OnBookmark_MouseUp(pBookMark);
-}
-
-void CJS_Context::OnLink_MouseUp(CPDFSDK_Document* pTarget) {
-  m_pEventHandler->OnLink_MouseUp(pTarget);
-}
-
-void CJS_Context::OnConsole_Exec() {
-  m_pEventHandler->OnConsole_Exec();
-}
-
-void CJS_Context::OnExternal_Exec() {
-  m_pEventHandler->OnExternal_Exec();
-}
-
-void CJS_Context::OnBatchExec(CPDFSDK_Document* pTarget) {
-  m_pEventHandler->OnBatchExec(pTarget);
-}
-
-void CJS_Context::OnMenu_Exec(CPDFSDK_Document* pTarget,
-                              const CFX_WideString& strTargetName) {
-  m_pEventHandler->OnMenu_Exec(pTarget, strTargetName);
-}
diff --git a/fpdfsdk/src/javascript/JS_Context.h b/fpdfsdk/src/javascript/JS_Context.h
deleted file mode 100644
index 93ef152..0000000
--- a/fpdfsdk/src/javascript/JS_Context.h
+++ /dev/null
@@ -1,137 +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_SRC_JAVASCRIPT_JS_CONTEXT_H_
-#define FPDFSDK_SRC_JAVASCRIPT_JS_CONTEXT_H_
-
-#include "core/include/fxcrt/fx_string.h"
-#include "core/include/fxcrt/fx_system.h"
-#include "fpdfsdk/include/javascript/IJavaScript.h"
-
-class CJS_EventHandler;
-class CJS_Runtime;
-
-class CJS_Context : public IJS_Context {
- public:
-  explicit CJS_Context(CJS_Runtime* pRuntime);
-  ~CJS_Context() override;
-
-  // IJS_Context
-  FX_BOOL RunScript(const CFX_WideString& script,
-                    CFX_WideString* info) override;
-  void OnApp_Init() override;
-  void OnDoc_Open(CPDFSDK_Document* pDoc,
-                  const CFX_WideString& strTargetName) override;
-  void OnDoc_WillPrint(CPDFSDK_Document* pDoc) override;
-  void OnDoc_DidPrint(CPDFSDK_Document* pDoc) override;
-  void OnDoc_WillSave(CPDFSDK_Document* pDoc) override;
-  void OnDoc_DidSave(CPDFSDK_Document* pDoc) override;
-  void OnDoc_WillClose(CPDFSDK_Document* pDoc) override;
-  void OnPage_Open(CPDFSDK_Document* pTarget) override;
-  void OnPage_Close(CPDFSDK_Document* pTarget) override;
-  void OnPage_InView(CPDFSDK_Document* pTarget) override;
-  void OnPage_OutView(CPDFSDK_Document* pTarget) override;
-  void OnField_MouseDown(FX_BOOL bModifier,
-                         FX_BOOL bShift,
-                         CPDF_FormField* pTarget) override;
-  void OnField_MouseEnter(FX_BOOL bModifier,
-                          FX_BOOL bShift,
-                          CPDF_FormField* pTarget) override;
-  void OnField_MouseExit(FX_BOOL bModifier,
-                         FX_BOOL bShift,
-                         CPDF_FormField* pTarget) override;
-  void OnField_MouseUp(FX_BOOL bModifier,
-                       FX_BOOL bShift,
-                       CPDF_FormField* pTarget) override;
-  void OnField_Focus(FX_BOOL bModifier,
-                     FX_BOOL bShift,
-                     CPDF_FormField* pTarget,
-                     const CFX_WideString& Value) override;
-  void OnField_Blur(FX_BOOL bModifier,
-                    FX_BOOL bShift,
-                    CPDF_FormField* pTarget,
-                    const CFX_WideString& Value) override;
-  void OnField_Calculate(CPDF_FormField* pSource,
-                         CPDF_FormField* pTarget,
-                         CFX_WideString& Value,
-                         FX_BOOL& bRc) override;
-  void OnField_Format(CPDF_FormField* pTarget,
-                      CFX_WideString& Value,
-                      FX_BOOL bWillCommit) override;
-  void OnField_Keystroke(CFX_WideString& strChange,
-                         const CFX_WideString& strChangeEx,
-                         FX_BOOL bKeyDown,
-                         FX_BOOL bModifier,
-                         int& nSelEnd,
-                         int& nSelStart,
-                         FX_BOOL bShift,
-                         CPDF_FormField* pTarget,
-                         CFX_WideString& Value,
-                         FX_BOOL bWillCommit,
-                         FX_BOOL bFieldFull,
-                         FX_BOOL& bRc) override;
-  void OnField_Validate(CFX_WideString& strChange,
-                        const CFX_WideString& strChangeEx,
-                        FX_BOOL bKeyDown,
-                        FX_BOOL bModifier,
-                        FX_BOOL bShift,
-                        CPDF_FormField* pTarget,
-                        CFX_WideString& Value,
-                        FX_BOOL& bRc) override;
-  void OnScreen_Focus(FX_BOOL bModifier,
-                      FX_BOOL bShift,
-                      CPDFSDK_Annot* pScreen) override;
-  void OnScreen_Blur(FX_BOOL bModifier,
-                     FX_BOOL bShift,
-                     CPDFSDK_Annot* pScreen) override;
-  void OnScreen_Open(FX_BOOL bModifier,
-                     FX_BOOL bShift,
-                     CPDFSDK_Annot* pScreen) override;
-  void OnScreen_Close(FX_BOOL bModifier,
-                      FX_BOOL bShift,
-                      CPDFSDK_Annot* pScreen) override;
-  void OnScreen_MouseDown(FX_BOOL bModifier,
-                          FX_BOOL bShift,
-                          CPDFSDK_Annot* pScreen) override;
-  void OnScreen_MouseUp(FX_BOOL bModifier,
-                        FX_BOOL bShift,
-                        CPDFSDK_Annot* pScreen) override;
-  void OnScreen_MouseEnter(FX_BOOL bModifier,
-                           FX_BOOL bShift,
-                           CPDFSDK_Annot* pScreen) override;
-  void OnScreen_MouseExit(FX_BOOL bModifier,
-                          FX_BOOL bShift,
-                          CPDFSDK_Annot* pScreen) override;
-  void OnScreen_InView(FX_BOOL bModifier,
-                       FX_BOOL bShift,
-                       CPDFSDK_Annot* pScreen) override;
-  void OnScreen_OutView(FX_BOOL bModifier,
-                        FX_BOOL bShift,
-                        CPDFSDK_Annot* pScreen) override;
-  void OnBookmark_MouseUp(CPDF_Bookmark* pBookMark) override;
-  void OnLink_MouseUp(CPDFSDK_Document* pTarget) override;
-  void OnMenu_Exec(CPDFSDK_Document* pTarget,
-                   const CFX_WideString& strTargetName) override;
-  void OnBatchExec(CPDFSDK_Document* pTarget) override;
-  void OnConsole_Exec() override;
-  void OnExternal_Exec() override;
-  void EnableMessageBox(FX_BOOL bEnable) override { m_bMsgBoxEnable = bEnable; }
-
-  FX_BOOL IsMsgBoxEnabled() const { return m_bMsgBoxEnable; }
-
-  CPDFDoc_Environment* GetReaderApp();
-  CJS_Runtime* GetJSRuntime() const { return m_pRuntime; }
-  CJS_EventHandler* GetEventHandler() const { return m_pEventHandler; }
-  CPDFSDK_Document* GetReaderDocument();
-
- private:
-  CJS_Runtime* m_pRuntime;
-  CJS_EventHandler* m_pEventHandler;
-  FX_BOOL m_bBusy;
-  FX_BOOL m_bMsgBoxEnable;
-};
-
-#endif  // FPDFSDK_SRC_JAVASCRIPT_JS_CONTEXT_H_
diff --git a/fpdfsdk/src/javascript/JS_EventHandler.h b/fpdfsdk/src/javascript/JS_EventHandler.h
deleted file mode 100644
index 2af19d9..0000000
--- a/fpdfsdk/src/javascript/JS_EventHandler.h
+++ /dev/null
@@ -1,220 +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_SRC_JAVASCRIPT_JS_EVENTHANDLER_H_
-#define FPDFSDK_SRC_JAVASCRIPT_JS_EVENTHANDLER_H_
-
-#include "core/include/fxcrt/fx_string.h"
-#include "core/include/fxcrt/fx_system.h"
-
-class CJS_Context;
-class CPDFSDK_Annot;
-class CPDFSDK_Document;
-class CPDF_Bookmark;
-class CPDF_FormField;
-class Field;
-
-enum JS_EVENT_T {
-  JET_UNKNOWN,
-  JET_APP_INIT,
-  JET_DOC_OPEN,
-  JET_DOC_WILLPRINT,
-  JET_DOC_DIDPRINT,
-  JET_DOC_WILLSAVE,
-  JET_DOC_DIDSAVE,
-  JET_DOC_WILLCLOSE,
-  JET_PAGE_OPEN,
-  JET_PAGE_CLOSE,
-  JET_PAGE_INVIEW,
-  JET_PAGE_OUTVIEW,
-  JET_FIELD_MOUSEDOWN,
-  JET_FIELD_MOUSEUP,
-  JET_FIELD_MOUSEENTER,
-  JET_FIELD_MOUSEEXIT,
-  JET_FIELD_FOCUS,
-  JET_FIELD_BLUR,
-  JET_FIELD_KEYSTROKE,
-  JET_FIELD_VALIDATE,
-  JET_FIELD_CALCULATE,
-  JET_FIELD_FORMAT,
-  JET_SCREEN_FOCUS,
-  JET_SCREEN_BLUR,
-  JET_SCREEN_OPEN,
-  JET_SCREEN_CLOSE,
-  JET_SCREEN_MOUSEDOWN,
-  JET_SCREEN_MOUSEUP,
-  JET_SCREEN_MOUSEENTER,
-  JET_SCREEN_MOUSEEXIT,
-  JET_SCREEN_INVIEW,
-  JET_SCREEN_OUTVIEW,
-  JET_BATCH_EXEC,
-  JET_MENU_EXEC,
-  JET_CONSOLE_EXEC,
-  JET_EXTERNAL_EXEC,
-  JET_BOOKMARK_MOUSEUP,
-  JET_LINK_MOUSEUP
-};
-
-class CJS_EventHandler {
- public:
-  CJS_EventHandler(CJS_Context* pContext);
-  virtual ~CJS_EventHandler();
-
-  void OnApp_Init();
-
-  void OnDoc_Open(CPDFSDK_Document* pDoc, const CFX_WideString& strTargetName);
-  void OnDoc_WillPrint(CPDFSDK_Document* pDoc);
-  void OnDoc_DidPrint(CPDFSDK_Document* pDoc);
-  void OnDoc_WillSave(CPDFSDK_Document* pDoc);
-  void OnDoc_DidSave(CPDFSDK_Document* pDoc);
-  void OnDoc_WillClose(CPDFSDK_Document* pDoc);
-
-  void OnPage_Open(CPDFSDK_Document* pDoc);
-  void OnPage_Close(CPDFSDK_Document* pDoc);
-  void OnPage_InView(CPDFSDK_Document* pTarget);
-  void OnPage_OutView(CPDFSDK_Document* pTarget);
-
-  void OnField_Calculate(CPDF_FormField* pSource,
-                         CPDF_FormField* pTarget,
-                         CFX_WideString& Value,
-                         FX_BOOL& bRc);
-  void OnField_Format(CPDF_FormField* pTarget,
-                      CFX_WideString& Value,
-                      FX_BOOL bWillCommit);
-  void OnField_Keystroke(CFX_WideString& strChange,
-                         const CFX_WideString& strChangeEx,
-                         FX_BOOL KeyDown,
-                         FX_BOOL bModifier,
-                         int& nSelEnd,
-                         int& nSelStart,
-                         FX_BOOL bShift,
-                         CPDF_FormField* pTarget,
-                         CFX_WideString& Value,
-                         FX_BOOL bWillCommit,
-                         FX_BOOL bFieldFull,
-                         FX_BOOL& bRc);
-  void OnField_Validate(CFX_WideString& strChange,
-                        const CFX_WideString& strChangeEx,
-                        FX_BOOL bKeyDown,
-                        FX_BOOL bModifier,
-                        FX_BOOL bShift,
-                        CPDF_FormField* pTarget,
-                        CFX_WideString& Value,
-                        FX_BOOL& bRc);
-
-  void OnField_MouseDown(FX_BOOL bModifier,
-                         FX_BOOL bShift,
-                         CPDF_FormField* pTarget);
-  void OnField_MouseEnter(FX_BOOL bModifier,
-                          FX_BOOL bShift,
-                          CPDF_FormField* pTarget);
-  void OnField_MouseExit(FX_BOOL bModifier,
-                         FX_BOOL bShift,
-                         CPDF_FormField* pTarget);
-  void OnField_MouseUp(FX_BOOL bModifier,
-                       FX_BOOL bShift,
-                       CPDF_FormField* pTarget);
-  void OnField_Blur(FX_BOOL bModifier,
-                    FX_BOOL bShift,
-                    CPDF_FormField* pTarget,
-                    const CFX_WideString& Value);
-  void OnField_Focus(FX_BOOL bModifier,
-                     FX_BOOL bShift,
-                     CPDF_FormField* pTarget,
-                     const CFX_WideString& Value);
-
-  void OnScreen_Focus(FX_BOOL bModifier,
-                      FX_BOOL bShift,
-                      CPDFSDK_Annot* pScreen);
-  void OnScreen_Blur(FX_BOOL bModifier, FX_BOOL bShift, CPDFSDK_Annot* pScreen);
-  void OnScreen_Open(FX_BOOL bModifier, FX_BOOL bShift, CPDFSDK_Annot* pScreen);
-  void OnScreen_Close(FX_BOOL bModifier,
-                      FX_BOOL bShift,
-                      CPDFSDK_Annot* pScreen);
-  void OnScreen_MouseDown(FX_BOOL bModifier,
-                          FX_BOOL bShift,
-                          CPDFSDK_Annot* pScreen);
-  void OnScreen_MouseUp(FX_BOOL bModifier,
-                        FX_BOOL bShift,
-                        CPDFSDK_Annot* pScreen);
-  void OnScreen_MouseEnter(FX_BOOL bModifier,
-                           FX_BOOL bShift,
-                           CPDFSDK_Annot* pScreen);
-  void OnScreen_MouseExit(FX_BOOL bModifier,
-                          FX_BOOL bShift,
-                          CPDFSDK_Annot* pScreen);
-  void OnScreen_InView(FX_BOOL bModifier,
-                       FX_BOOL bShift,
-                       CPDFSDK_Annot* pScreen);
-  void OnScreen_OutView(FX_BOOL bModifier,
-                        FX_BOOL bShift,
-                        CPDFSDK_Annot* pScreen);
-
-  void OnBookmark_MouseUp(CPDF_Bookmark* pBookMark);
-  void OnLink_MouseUp(CPDFSDK_Document* pTarget);
-
-  void OnMenu_Exec(CPDFSDK_Document* pTarget,
-                   const CFX_WideString& strTargetName);
-  void OnBatchExec(CPDFSDK_Document* pTarget);
-  void OnConsole_Exec();
-  void OnExternal_Exec();
-
- public:
-  void Initial(JS_EVENT_T type);
-  void Destroy();
-  FX_BOOL IsValid();
-
-  CFX_WideString& Change();
-  CFX_WideString ChangeEx();
-  int CommitKey();
-  FX_BOOL FieldFull();
-  FX_BOOL KeyDown();
-  FX_BOOL Modifier();
-  const FX_WCHAR* Name();
-  const FX_WCHAR* Type();
-  FX_BOOL& Rc();
-  int& SelEnd();
-  int& SelStart();
-  FX_BOOL Shift();
-  Field* Source();
-  Field* Target_Field();
-  CFX_WideString& Value();
-  FX_BOOL WillCommit();
-  CFX_WideString TargetName();
-
-  JS_EVENT_T EventType() { return m_eEventType; }
-
- public:
-  CJS_Context* m_pJSContext;
-  JS_EVENT_T m_eEventType;
-  FX_BOOL m_bValid;
-
-  CFX_WideString m_strTargetName;
-  CFX_WideString m_strSourceName;
-  CFX_WideString* m_pWideStrChange;
-  CFX_WideString m_WideStrChangeDu;
-  CFX_WideString m_WideStrChangeEx;
-  int m_nCommitKey;
-  FX_BOOL m_bKeyDown;
-  FX_BOOL m_bModifier;
-  FX_BOOL m_bShift;
-  int* m_pISelEnd;
-  int m_nSelEndDu;
-  int* m_pISelStart;
-  int m_nSelStartDu;
-  FX_BOOL m_bWillCommit;
-  CFX_WideString* m_pValue;
-  FX_BOOL m_bFieldFull;
-  FX_BOOL* m_pbRc;
-  FX_BOOL m_bRcDu;
-
-  CPDFSDK_Document* m_pSourceDoc;
-  CPDF_Bookmark* m_pTargetBookMark;
-  CPDFSDK_Document* m_pTargetDoc;
-  CPDFSDK_Annot* m_pTargetAnnot;
-};
-
-#endif  // FPDFSDK_SRC_JAVASCRIPT_JS_EVENTHANDLER_H_
diff --git a/fpdfsdk/src/javascript/JS_GlobalData.cpp b/fpdfsdk/src/javascript/JS_GlobalData.cpp
deleted file mode 100644
index 4d6edc8..0000000
--- a/fpdfsdk/src/javascript/JS_GlobalData.cpp
+++ /dev/null
@@ -1,490 +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
-
-#include "JS_GlobalData.h"
-
-#include "core/include/fdrm/fx_crypt.h"
-#include "fpdfsdk/include/javascript/IJavaScript.h"
-
-#define JS_MAXGLOBALDATA (1024 * 4 - 8)
-
-/* --------------------- CJS_GlobalVariableArray --------------------- */
-
-CJS_GlobalVariableArray::CJS_GlobalVariableArray() {}
-
-CJS_GlobalVariableArray::~CJS_GlobalVariableArray() {
-  Empty();
-}
-
-void CJS_GlobalVariableArray::Copy(const CJS_GlobalVariableArray& array) {
-  Empty();
-  for (int i = 0, sz = array.Count(); i < sz; i++) {
-    CJS_KeyValue* pOldObjData = array.GetAt(i);
-    switch (pOldObjData->nType) {
-      case JS_GLOBALDATA_TYPE_NUMBER: {
-        CJS_KeyValue* pNewObjData = new CJS_KeyValue;
-        pNewObjData->sKey = pOldObjData->sKey;
-        pNewObjData->nType = pOldObjData->nType;
-        pNewObjData->dData = pOldObjData->dData;
-        Add(pNewObjData);
-      } break;
-      case JS_GLOBALDATA_TYPE_BOOLEAN: {
-        CJS_KeyValue* pNewObjData = new CJS_KeyValue;
-        pNewObjData->sKey = pOldObjData->sKey;
-        pNewObjData->nType = pOldObjData->nType;
-        pNewObjData->bData = pOldObjData->bData;
-        Add(pNewObjData);
-      } break;
-      case JS_GLOBALDATA_TYPE_STRING: {
-        CJS_KeyValue* pNewObjData = new CJS_KeyValue;
-        pNewObjData->sKey = pOldObjData->sKey;
-        pNewObjData->nType = pOldObjData->nType;
-        pNewObjData->sData = pOldObjData->sData;
-        Add(pNewObjData);
-      } break;
-      case JS_GLOBALDATA_TYPE_OBJECT: {
-        CJS_KeyValue* pNewObjData = new CJS_KeyValue;
-        pNewObjData->sKey = pOldObjData->sKey;
-        pNewObjData->nType = pOldObjData->nType;
-        pNewObjData->objData.Copy(pOldObjData->objData);
-        Add(pNewObjData);
-      } break;
-      case JS_GLOBALDATA_TYPE_NULL: {
-        CJS_KeyValue* pNewObjData = new CJS_KeyValue;
-        pNewObjData->sKey = pOldObjData->sKey;
-        pNewObjData->nType = pOldObjData->nType;
-        Add(pNewObjData);
-      } break;
-    }
-  }
-}
-
-void CJS_GlobalVariableArray::Add(CJS_KeyValue* p) {
-  array.Add(p);
-}
-
-int CJS_GlobalVariableArray::Count() const {
-  return array.GetSize();
-}
-
-CJS_KeyValue* CJS_GlobalVariableArray::GetAt(int index) const {
-  return array.GetAt(index);
-}
-
-void CJS_GlobalVariableArray::Empty() {
-  for (int i = 0, sz = array.GetSize(); i < sz; i++)
-    delete array.GetAt(i);
-  array.RemoveAll();
-}
-
-/* -------------------------- CJS_GlobalData -------------------------- */
-
-#define READER_JS_GLOBALDATA_FILENAME L"Reader_JsGlobal.Data"
-#define PHANTOM_JS_GLOBALDATA_FILENAME L"Phantom_JsGlobal.Data"
-#define SDK_JS_GLOBALDATA_FILENAME L"SDK_JsGlobal.Data"
-
-static const uint8_t JS_RC4KEY[] = {
-    0x19, 0xa8, 0xe8, 0x01, 0xf6, 0xa8, 0xb6, 0x4d, 0x82, 0x04, 0x45, 0x6d,
-    0xb4, 0xcf, 0xd7, 0x77, 0x67, 0xf9, 0x75, 0x9f, 0xf0, 0xe0, 0x1e, 0x51,
-    0xee, 0x46, 0xfd, 0x0b, 0xc9, 0x93, 0x25, 0x55, 0x4a, 0xee, 0xe0, 0x16,
-    0xd0, 0xdf, 0x8c, 0xfa, 0x2a, 0xa9, 0x49, 0xfd, 0x97, 0x1c, 0x0e, 0x22,
-    0x13, 0x28, 0x7c, 0xaf, 0xc4, 0xfc, 0x9c, 0x12, 0x65, 0x8c, 0x4e, 0x5b,
-    0x04, 0x75, 0x89, 0xc9, 0xb1, 0xed, 0x50, 0xca, 0x96, 0x6f, 0x1a, 0x7a,
-    0xfe, 0x58, 0x5d, 0xec, 0x19, 0x4a, 0xf6, 0x35, 0x6a, 0x97, 0x14, 0x00,
-    0x0e, 0xd0, 0x6b, 0xbb, 0xd5, 0x75, 0x55, 0x8b, 0x6e, 0x6b, 0x19, 0xa0,
-    0xf8, 0x77, 0xd5, 0xa3};
-
-CJS_GlobalData* CJS_GlobalData::g_Instance = nullptr;
-
-// static
-CJS_GlobalData* CJS_GlobalData::GetRetainedInstance(CPDFDoc_Environment* pApp) {
-  if (!g_Instance) {
-    g_Instance = new CJS_GlobalData();
-  }
-  ++g_Instance->m_RefCount;
-  return g_Instance;
-}
-
-void CJS_GlobalData::Release() {
-  if (!--m_RefCount) {
-    delete g_Instance;
-    g_Instance = nullptr;
-  }
-}
-
-CJS_GlobalData::CJS_GlobalData() : m_RefCount(0) {
-  m_sFilePath += SDK_JS_GLOBALDATA_FILENAME;
-  LoadGlobalPersistentVariables();
-}
-
-CJS_GlobalData::~CJS_GlobalData() {
-  SaveGlobalPersisitentVariables();
-  for (int i = 0, sz = m_arrayGlobalData.GetSize(); i < sz; i++)
-    delete m_arrayGlobalData.GetAt(i);
-
-  m_arrayGlobalData.RemoveAll();
-}
-
-int CJS_GlobalData::FindGlobalVariable(const FX_CHAR* propname) {
-  for (int i = 0, sz = m_arrayGlobalData.GetSize(); i < sz; i++) {
-    CJS_GlobalData_Element* pTemp = m_arrayGlobalData.GetAt(i);
-    if (pTemp->data.sKey[0] == *propname && pTemp->data.sKey == propname)
-      return i;
-  }
-  return -1;
-}
-
-CJS_GlobalData_Element* CJS_GlobalData::GetGlobalVariable(
-    const FX_CHAR* propname) {
-  ASSERT(propname);
-
-  int nFind = FindGlobalVariable(propname);
-  return nFind >= 0 ? m_arrayGlobalData.GetAt(nFind) : nullptr;
-}
-
-void CJS_GlobalData::SetGlobalVariableNumber(const FX_CHAR* propname,
-                                             double dData) {
-  ASSERT(propname);
-  CFX_ByteString sPropName = propname;
-  sPropName.TrimLeft();
-  sPropName.TrimRight();
-  if (sPropName.GetLength() == 0)
-    return;
-
-  if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
-    pData->data.nType = JS_GLOBALDATA_TYPE_NUMBER;
-    pData->data.dData = dData;
-  } else {
-    CJS_GlobalData_Element* pNewData = new CJS_GlobalData_Element;
-    pNewData->data.sKey = sPropName;
-    pNewData->data.nType = JS_GLOBALDATA_TYPE_NUMBER;
-    pNewData->data.dData = dData;
-    m_arrayGlobalData.Add(pNewData);
-  }
-}
-
-void CJS_GlobalData::SetGlobalVariableBoolean(const FX_CHAR* propname,
-                                              bool bData) {
-  ASSERT(propname);
-  CFX_ByteString sPropName = propname;
-
-  sPropName.TrimLeft();
-  sPropName.TrimRight();
-
-  if (sPropName.GetLength() == 0)
-    return;
-
-  if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
-    pData->data.nType = JS_GLOBALDATA_TYPE_BOOLEAN;
-    pData->data.bData = bData;
-  } else {
-    CJS_GlobalData_Element* pNewData = new CJS_GlobalData_Element;
-    pNewData->data.sKey = sPropName;
-    pNewData->data.nType = JS_GLOBALDATA_TYPE_BOOLEAN;
-    pNewData->data.bData = bData;
-
-    m_arrayGlobalData.Add(pNewData);
-  }
-}
-
-void CJS_GlobalData::SetGlobalVariableString(const FX_CHAR* propname,
-                                             const CFX_ByteString& sData) {
-  ASSERT(propname);
-  CFX_ByteString sPropName = propname;
-
-  sPropName.TrimLeft();
-  sPropName.TrimRight();
-
-  if (sPropName.GetLength() == 0)
-    return;
-
-  if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
-    pData->data.nType = JS_GLOBALDATA_TYPE_STRING;
-    pData->data.sData = sData;
-  } else {
-    CJS_GlobalData_Element* pNewData = new CJS_GlobalData_Element;
-    pNewData->data.sKey = sPropName;
-    pNewData->data.nType = JS_GLOBALDATA_TYPE_STRING;
-    pNewData->data.sData = sData;
-
-    m_arrayGlobalData.Add(pNewData);
-  }
-}
-
-void CJS_GlobalData::SetGlobalVariableObject(
-    const FX_CHAR* propname,
-    const CJS_GlobalVariableArray& array) {
-  ASSERT(propname);
-  CFX_ByteString sPropName = propname;
-
-  sPropName.TrimLeft();
-  sPropName.TrimRight();
-
-  if (sPropName.GetLength() == 0)
-    return;
-
-  if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
-    pData->data.nType = JS_GLOBALDATA_TYPE_OBJECT;
-    pData->data.objData.Copy(array);
-  } else {
-    CJS_GlobalData_Element* pNewData = new CJS_GlobalData_Element;
-    pNewData->data.sKey = sPropName;
-    pNewData->data.nType = JS_GLOBALDATA_TYPE_OBJECT;
-    pNewData->data.objData.Copy(array);
-
-    m_arrayGlobalData.Add(pNewData);
-  }
-}
-
-void CJS_GlobalData::SetGlobalVariableNull(const FX_CHAR* propname) {
-  ASSERT(propname);
-  CFX_ByteString sPropName = propname;
-
-  sPropName.TrimLeft();
-  sPropName.TrimRight();
-
-  if (sPropName.GetLength() == 0)
-    return;
-
-  if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
-    pData->data.nType = JS_GLOBALDATA_TYPE_NULL;
-  } else {
-    CJS_GlobalData_Element* pNewData = new CJS_GlobalData_Element;
-    pNewData->data.sKey = sPropName;
-    pNewData->data.nType = JS_GLOBALDATA_TYPE_NULL;
-
-    m_arrayGlobalData.Add(pNewData);
-  }
-}
-
-FX_BOOL CJS_GlobalData::SetGlobalVariablePersistent(const FX_CHAR* propname,
-                                                    FX_BOOL bPersistent) {
-  ASSERT(propname);
-  CFX_ByteString sPropName = propname;
-
-  sPropName.TrimLeft();
-  sPropName.TrimRight();
-
-  if (sPropName.GetLength() == 0)
-    return FALSE;
-
-  if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
-    pData->bPersistent = bPersistent;
-    return TRUE;
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CJS_GlobalData::DeleteGlobalVariable(const FX_CHAR* propname) {
-  ASSERT(propname);
-  CFX_ByteString sPropName = propname;
-
-  sPropName.TrimLeft();
-  sPropName.TrimRight();
-
-  if (sPropName.GetLength() == 0)
-    return FALSE;
-
-  int nFind = FindGlobalVariable(sPropName);
-
-  if (nFind >= 0) {
-    delete m_arrayGlobalData.GetAt(nFind);
-    m_arrayGlobalData.RemoveAt(nFind);
-    return TRUE;
-  }
-
-  return FALSE;
-}
-
-int32_t CJS_GlobalData::GetSize() const {
-  return m_arrayGlobalData.GetSize();
-}
-
-CJS_GlobalData_Element* CJS_GlobalData::GetAt(int index) const {
-  return m_arrayGlobalData.GetAt(index);
-}
-
-void CJS_GlobalData::LoadGlobalPersistentVariables() {
-  uint8_t* pBuffer = NULL;
-  int32_t nLength = 0;
-
-  LoadFileBuffer(m_sFilePath.c_str(), pBuffer, nLength);
-  CRYPT_ArcFourCryptBlock(pBuffer, nLength, JS_RC4KEY, sizeof(JS_RC4KEY));
-
-  if (pBuffer) {
-    uint8_t* p = pBuffer;
-    FX_WORD wType = *((FX_WORD*)p);
-    p += sizeof(FX_WORD);
-
-    // FX_WORD wTemp = (FX_WORD)(('X' << 8) | 'F');
-
-    if (wType == (FX_WORD)(('X' << 8) | 'F')) {
-      FX_WORD wVersion = *((FX_WORD*)p);
-      p += sizeof(FX_WORD);
-
-      ASSERT(wVersion <= 2);
-
-      FX_DWORD dwCount = *((FX_DWORD*)p);
-      p += sizeof(FX_DWORD);
-
-      FX_DWORD dwSize = *((FX_DWORD*)p);
-      p += sizeof(FX_DWORD);
-
-      if (dwSize == nLength - sizeof(FX_WORD) * 2 - sizeof(FX_DWORD) * 2) {
-        for (int32_t i = 0, sz = dwCount; i < sz; i++) {
-          if (p > pBuffer + nLength)
-            break;
-
-          FX_DWORD dwNameLen = *((FX_DWORD*)p);
-          p += sizeof(FX_DWORD);
-
-          if (p + dwNameLen > pBuffer + nLength)
-            break;
-
-          CFX_ByteString sEntry = CFX_ByteString(p, dwNameLen);
-          p += sizeof(char) * dwNameLen;
-
-          FX_WORD wDataType = *((FX_WORD*)p);
-          p += sizeof(FX_WORD);
-
-          switch (wDataType) {
-            case JS_GLOBALDATA_TYPE_NUMBER: {
-              double dData = 0;
-              switch (wVersion) {
-                case 1: {
-                  FX_DWORD dwData = *((FX_DWORD*)p);
-                  p += sizeof(FX_DWORD);
-                  dData = dwData;
-                } break;
-                case 2: {
-                  dData = *((double*)p);
-                  p += sizeof(double);
-                } break;
-              }
-              SetGlobalVariableNumber(sEntry, dData);
-              SetGlobalVariablePersistent(sEntry, TRUE);
-            } break;
-            case JS_GLOBALDATA_TYPE_BOOLEAN: {
-              FX_WORD wData = *((FX_WORD*)p);
-              p += sizeof(FX_WORD);
-              SetGlobalVariableBoolean(sEntry, (bool)(wData == 1));
-              SetGlobalVariablePersistent(sEntry, TRUE);
-            } break;
-            case JS_GLOBALDATA_TYPE_STRING: {
-              FX_DWORD dwLength = *((FX_DWORD*)p);
-              p += sizeof(FX_DWORD);
-
-              if (p + dwLength > pBuffer + nLength)
-                break;
-
-              SetGlobalVariableString(sEntry, CFX_ByteString(p, dwLength));
-              SetGlobalVariablePersistent(sEntry, TRUE);
-              p += sizeof(char) * dwLength;
-            } break;
-            case JS_GLOBALDATA_TYPE_NULL: {
-              SetGlobalVariableNull(sEntry);
-              SetGlobalVariablePersistent(sEntry, TRUE);
-            }
-          }
-        }
-      }
-    }
-    FX_Free(pBuffer);
-  }
-}
-
-void CJS_GlobalData::SaveGlobalPersisitentVariables() {
-  FX_DWORD nCount = 0;
-  CFX_BinaryBuf sData;
-
-  for (int i = 0, sz = m_arrayGlobalData.GetSize(); i < sz; i++) {
-    CJS_GlobalData_Element* pElement = m_arrayGlobalData.GetAt(i);
-    if (pElement->bPersistent) {
-      CFX_BinaryBuf sElement;
-      MakeByteString(pElement->data.sKey, &pElement->data, sElement);
-
-      if (sData.GetSize() + sElement.GetSize() > JS_MAXGLOBALDATA)
-        break;
-
-      sData.AppendBlock(sElement.GetBuffer(), sElement.GetSize());
-      nCount++;
-    }
-  }
-
-  CFX_BinaryBuf sFile;
-
-  FX_WORD wType = (FX_WORD)(('X' << 8) | 'F');
-  sFile.AppendBlock(&wType, sizeof(FX_WORD));
-  FX_WORD wVersion = 2;
-  sFile.AppendBlock(&wVersion, sizeof(FX_WORD));
-  sFile.AppendBlock(&nCount, sizeof(FX_DWORD));
-  FX_DWORD dwSize = sData.GetSize();
-  sFile.AppendBlock(&dwSize, sizeof(FX_DWORD));
-
-  sFile.AppendBlock(sData.GetBuffer(), sData.GetSize());
-
-  CRYPT_ArcFourCryptBlock(sFile.GetBuffer(), sFile.GetSize(), JS_RC4KEY,
-                          sizeof(JS_RC4KEY));
-  WriteFileBuffer(m_sFilePath.c_str(), (const FX_CHAR*)sFile.GetBuffer(),
-                  sFile.GetSize());
-}
-
-void CJS_GlobalData::LoadFileBuffer(const FX_WCHAR* sFilePath,
-                                    uint8_t*& pBuffer,
-                                    int32_t& nLength) {
-  // UnSupport.
-}
-
-void CJS_GlobalData::WriteFileBuffer(const FX_WCHAR* sFilePath,
-                                     const FX_CHAR* pBuffer,
-                                     int32_t nLength) {
-  // UnSupport.
-}
-
-void CJS_GlobalData::MakeByteString(const CFX_ByteString& name,
-                                    CJS_KeyValue* pData,
-                                    CFX_BinaryBuf& sData) {
-  FX_WORD wType = (FX_WORD)pData->nType;
-  switch (wType) {
-    case JS_GLOBALDATA_TYPE_NUMBER: {
-      FX_DWORD dwNameLen = (FX_DWORD)name.GetLength();
-      sData.AppendBlock(&dwNameLen, sizeof(FX_DWORD));
-      sData.AppendString(name);
-      sData.AppendBlock(&wType, sizeof(FX_WORD));
-
-      double dData = pData->dData;
-      sData.AppendBlock(&dData, sizeof(double));
-    } break;
-    case JS_GLOBALDATA_TYPE_BOOLEAN: {
-      FX_DWORD dwNameLen = (FX_DWORD)name.GetLength();
-      sData.AppendBlock(&dwNameLen, sizeof(FX_DWORD));
-      sData.AppendString(name);
-      sData.AppendBlock(&wType, sizeof(FX_WORD));
-
-      FX_WORD wData = (FX_WORD)pData->bData;
-      sData.AppendBlock(&wData, sizeof(FX_WORD));
-    } break;
-    case JS_GLOBALDATA_TYPE_STRING: {
-      FX_DWORD dwNameLen = (FX_DWORD)name.GetLength();
-      sData.AppendBlock(&dwNameLen, sizeof(FX_DWORD));
-      sData.AppendString(name);
-      sData.AppendBlock(&wType, sizeof(FX_WORD));
-
-      FX_DWORD dwDataLen = (FX_DWORD)pData->sData.GetLength();
-      sData.AppendBlock(&dwDataLen, sizeof(FX_DWORD));
-      sData.AppendString(pData->sData);
-    } break;
-    case JS_GLOBALDATA_TYPE_NULL: {
-      FX_DWORD dwNameLen = (FX_DWORD)name.GetLength();
-      sData.AppendBlock(&dwNameLen, sizeof(FX_DWORD));
-      sData.AppendString(name);
-      sData.AppendBlock(&wType, sizeof(FX_DWORD));
-    } break;
-    default:
-      break;
-  }
-}
diff --git a/fpdfsdk/src/javascript/JS_GlobalData.h b/fpdfsdk/src/javascript/JS_GlobalData.h
deleted file mode 100644
index 6a07fa8..0000000
--- a/fpdfsdk/src/javascript/JS_GlobalData.h
+++ /dev/null
@@ -1,106 +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_SRC_JAVASCRIPT_JS_GLOBALDATA_H_
-#define FPDFSDK_SRC_JAVASCRIPT_JS_GLOBALDATA_H_
-
-#include "core/include/fxcrt/fx_basic.h"
-
-#define JS_GLOBALDATA_TYPE_NUMBER 0
-#define JS_GLOBALDATA_TYPE_BOOLEAN 1
-#define JS_GLOBALDATA_TYPE_STRING 2
-#define JS_GLOBALDATA_TYPE_OBJECT 3
-#define JS_GLOBALDATA_TYPE_NULL 4
-
-class CJS_KeyValue;
-class CPDFDoc_Environment;
-
-class CJS_GlobalVariableArray {
- public:
-  CJS_GlobalVariableArray();
-  virtual ~CJS_GlobalVariableArray();
-
-  void Add(CJS_KeyValue* p);
-  int Count() const;
-  CJS_KeyValue* GetAt(int index) const;
-  void Copy(const CJS_GlobalVariableArray& array);
-
-  void Empty();
-
- private:
-  CFX_ArrayTemplate<CJS_KeyValue*> array;
-};
-
-class CJS_KeyValue {
- public:
-  CJS_KeyValue() {}
-  virtual ~CJS_KeyValue() {}
-
-  CFX_ByteString sKey;
-  int nType;  // 0:int 1:bool 2:string 3:obj
-  double dData;
-  bool bData;
-  CFX_ByteString sData;
-  CJS_GlobalVariableArray objData;
-};
-
-class CJS_GlobalData_Element {
- public:
-  CJS_GlobalData_Element() {}
-  virtual ~CJS_GlobalData_Element() {}
-
-  CJS_KeyValue data;
-  FX_BOOL bPersistent;
-};
-
-class CJS_GlobalData {
- public:
-  static CJS_GlobalData* GetRetainedInstance(CPDFDoc_Environment* pApp);
-  void Release();
-
-  void SetGlobalVariableNumber(const FX_CHAR* propname, double dData);
-  void SetGlobalVariableBoolean(const FX_CHAR* propname, bool bData);
-  void SetGlobalVariableString(const FX_CHAR* propname,
-                               const CFX_ByteString& sData);
-  void SetGlobalVariableObject(const FX_CHAR* propname,
-                               const CJS_GlobalVariableArray& array);
-  void SetGlobalVariableNull(const FX_CHAR* propname);
-
-  FX_BOOL SetGlobalVariablePersistent(const FX_CHAR* propname,
-                                      FX_BOOL bPersistent);
-  FX_BOOL DeleteGlobalVariable(const FX_CHAR* propname);
-
-  int32_t GetSize() const;
-  CJS_GlobalData_Element* GetAt(int index) const;
-
- private:
-  static CJS_GlobalData* g_Instance;
-
-  CJS_GlobalData();
-  ~CJS_GlobalData();
-
-  void LoadGlobalPersistentVariables();
-  void SaveGlobalPersisitentVariables();
-
-  CJS_GlobalData_Element* GetGlobalVariable(const FX_CHAR* propname);
-  int FindGlobalVariable(const FX_CHAR* propname);
-
-  void LoadFileBuffer(const FX_WCHAR* sFilePath,
-                      uint8_t*& pBuffer,
-                      int32_t& nLength);
-  void WriteFileBuffer(const FX_WCHAR* sFilePath,
-                       const FX_CHAR* pBuffer,
-                       int32_t nLength);
-  void MakeByteString(const CFX_ByteString& name,
-                      CJS_KeyValue* pData,
-                      CFX_BinaryBuf& sData);
-
-  size_t m_RefCount;
-  CFX_ArrayTemplate<CJS_GlobalData_Element*> m_arrayGlobalData;
-  CFX_WideString m_sFilePath;
-};
-
-#endif  // FPDFSDK_SRC_JAVASCRIPT_JS_GLOBALDATA_H_
diff --git a/fpdfsdk/src/javascript/JS_Object.cpp b/fpdfsdk/src/javascript/JS_Object.cpp
deleted file mode 100644
index 058ec02..0000000
--- a/fpdfsdk/src/javascript/JS_Object.cpp
+++ /dev/null
@@ -1,159 +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
-
-#include "JS_Object.h"
-
-#include "JS_Context.h"
-#include "JS_Define.h"
-#include "fpdfsdk/include/fsdk_mgr.h"  // For CPDFDoc_Environment.
-#include "fpdfsdk/include/javascript/IJavaScript.h"
-
-namespace {
-
-int FXJS_MsgBox(CPDFDoc_Environment* pApp,
-                const FX_WCHAR* swMsg,
-                const FX_WCHAR* swTitle,
-                FX_UINT nType,
-                FX_UINT nIcon) {
-  if (!pApp)
-    return 0;
-
-  if (CPDFSDK_Document* pDoc = pApp->GetSDKDocument())
-    pDoc->KillFocusAnnot();
-
-  return pApp->JS_appAlert(swMsg, swTitle, nType, nIcon);
-}
-
-}  // namespace
-
-CJS_EmbedObj::CJS_EmbedObj(CJS_Object* pJSObject) : m_pJSObject(pJSObject) {}
-
-CJS_EmbedObj::~CJS_EmbedObj() {
-  m_pJSObject = NULL;
-}
-
-int CJS_EmbedObj::MsgBox(CPDFDoc_Environment* pApp,
-                         const FX_WCHAR* swMsg,
-                         const FX_WCHAR* swTitle,
-                         FX_UINT nType,
-                         FX_UINT nIcon) {
-  return FXJS_MsgBox(pApp, swMsg, swTitle, nType, nIcon);
-}
-
-void CJS_EmbedObj::Alert(CJS_Context* pContext, const FX_WCHAR* swMsg) {
-  CJS_Object::Alert(pContext, swMsg);
-}
-
-void FreeObject(const v8::WeakCallbackInfo<CJS_Object>& data) {
-  CJS_Object* pJSObj = data.GetParameter();
-  pJSObj->ExitInstance();
-  delete pJSObj;
-  FXJS_FreePrivate(data.GetInternalField(0));
-}
-
-void DisposeObject(const v8::WeakCallbackInfo<CJS_Object>& data) {
-  CJS_Object* pJSObj = data.GetParameter();
-  pJSObj->Dispose();
-  data.SetSecondPassCallback(FreeObject);
-}
-
-CJS_Object::CJS_Object(v8::Local<v8::Object> pObject) {
-  m_pIsolate = pObject->GetIsolate();
-  m_pV8Object.Reset(m_pIsolate, pObject);
-}
-
-CJS_Object::~CJS_Object() {
-}
-
-void CJS_Object::MakeWeak() {
-  m_pV8Object.SetWeak(this, DisposeObject,
-                      v8::WeakCallbackType::kInternalFields);
-}
-
-void CJS_Object::Dispose() {
-  m_pV8Object.Reset();
-}
-
-int CJS_Object::MsgBox(CPDFDoc_Environment* pApp,
-                       const FX_WCHAR* swMsg,
-                       const FX_WCHAR* swTitle,
-                       FX_UINT nType,
-                       FX_UINT nIcon) {
-  return FXJS_MsgBox(pApp, swMsg, swTitle, nType, nIcon);
-}
-
-void CJS_Object::Alert(CJS_Context* pContext, const FX_WCHAR* swMsg) {
-  if (pContext->IsMsgBoxEnabled()) {
-    CPDFDoc_Environment* pApp = pContext->GetReaderApp();
-    if (pApp)
-      pApp->JS_appAlert(swMsg, NULL, 0, 3);
-  }
-}
-
-CJS_Timer::CJS_Timer(CJS_EmbedObj* pObj,
-                     CPDFDoc_Environment* pApp,
-                     CJS_Runtime* pRuntime,
-                     int nType,
-                     const CFX_WideString& script,
-                     FX_DWORD dwElapse,
-                     FX_DWORD dwTimeOut)
-    : m_nTimerID(0),
-      m_pEmbedObj(pObj),
-      m_bProcessing(false),
-      m_bValid(true),
-      m_nType(nType),
-      m_dwTimeOut(dwTimeOut),
-      m_swJScript(script),
-      m_pRuntime(pRuntime),
-      m_pApp(pApp) {
-  IFX_SystemHandler* pHandler = m_pApp->GetSysHandler();
-  m_nTimerID = pHandler->SetTimer(dwElapse, TimerProc);
-  (*GetGlobalTimerMap())[m_nTimerID] = this;
-  m_pRuntime->AddObserver(this);
-}
-
-CJS_Timer::~CJS_Timer() {
-  CJS_Runtime* pRuntime = GetRuntime();
-  if (pRuntime)
-    pRuntime->RemoveObserver(this);
-  KillJSTimer();
-}
-
-void CJS_Timer::KillJSTimer() {
-  if (m_nTimerID) {
-    if (m_bValid) {
-      IFX_SystemHandler* pHandler = m_pApp->GetSysHandler();
-      pHandler->KillTimer(m_nTimerID);
-    }
-    GetGlobalTimerMap()->erase(m_nTimerID);
-    m_nTimerID = 0;
-  }
-}
-
-// static
-void CJS_Timer::TimerProc(int idEvent) {
-  const auto it = GetGlobalTimerMap()->find(idEvent);
-  if (it != GetGlobalTimerMap()->end()) {
-    CJS_Timer* pTimer = it->second;
-    if (!pTimer->m_bProcessing) {
-      CFX_AutoRestorer<bool> scoped_processing(&pTimer->m_bProcessing);
-      pTimer->m_bProcessing = true;
-      if (pTimer->m_pEmbedObj)
-        pTimer->m_pEmbedObj->TimerProc(pTimer);
-    }
-  }
-}
-
-// static
-CJS_Timer::TimerMap* CJS_Timer::GetGlobalTimerMap() {
-  // Leak the timer array at shutdown.
-  static auto* s_TimerMap = new TimerMap;
-  return s_TimerMap;
-}
-
-void CJS_Timer::OnDestroyed() {
-  m_bValid = false;
-}
diff --git a/fpdfsdk/src/javascript/JS_Object.h b/fpdfsdk/src/javascript/JS_Object.h
deleted file mode 100644
index fe9e5ec..0000000
--- a/fpdfsdk/src/javascript/JS_Object.h
+++ /dev/null
@@ -1,116 +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_SRC_JAVASCRIPT_JS_OBJECT_H_
-#define FPDFSDK_SRC_JAVASCRIPT_JS_OBJECT_H_
-
-#include <map>
-#include <memory>
-
-#include "JS_Runtime.h"
-#include "fpdfsdk/include/fsdk_define.h"  // For FX_UINT
-#include "fpdfsdk/include/jsapi/fxjs_v8.h"
-
-class CJS_Context;
-class CJS_Object;
-class CJS_Timer;
-class CPDFDoc_Environment;
-class CJS_EmbedObj {
- public:
-  explicit CJS_EmbedObj(CJS_Object* pJSObject);
-  virtual ~CJS_EmbedObj();
-
-  virtual void TimerProc(CJS_Timer* pTimer) {}
-
-  CJS_Object* GetJSObject() const { return m_pJSObject; }
-
-  int MsgBox(CPDFDoc_Environment* pApp,
-             const FX_WCHAR* swMsg,
-             const FX_WCHAR* swTitle,
-             FX_UINT nType,
-             FX_UINT nIcon);
-  void Alert(CJS_Context* pContext, const FX_WCHAR* swMsg);
-
- protected:
-  CJS_Object* m_pJSObject;
-};
-
-class CJS_Object {
- public:
-  explicit CJS_Object(v8::Local<v8::Object> pObject);
-  virtual ~CJS_Object();
-
-  void MakeWeak();
-  void Dispose();
-
-  virtual FX_BOOL IsType(const FX_CHAR* sClassName) { return TRUE; }
-  virtual CFX_ByteString GetClassName() { return ""; }
-
-  virtual void InitInstance(IJS_Runtime* pIRuntime) {}
-  virtual void ExitInstance() {}
-
-  v8::Local<v8::Object> ToV8Object() { return m_pV8Object.Get(m_pIsolate); }
-
-  // Takes ownership of |pObj|.
-  void SetEmbedObject(CJS_EmbedObj* pObj) { m_pEmbedObj.reset(pObj); }
-  CJS_EmbedObj* GetEmbedObject() const { return m_pEmbedObj.get(); }
-
-  static int MsgBox(CPDFDoc_Environment* pApp,
-                    const FX_WCHAR* swMsg,
-                    const FX_WCHAR* swTitle,
-                    FX_UINT nType,
-                    FX_UINT nIcon);
-  static void Alert(CJS_Context* pContext, const FX_WCHAR* swMsg);
-
-  v8::Isolate* GetIsolate() { return m_pIsolate; }
-
- protected:
-  std::unique_ptr<CJS_EmbedObj> m_pEmbedObj;
-  v8::Global<v8::Object> m_pV8Object;
-  v8::Isolate* m_pIsolate;
-};
-
-class CJS_Timer : public CJS_Runtime::Observer {
- public:
-  CJS_Timer(CJS_EmbedObj* pObj,
-            CPDFDoc_Environment* pApp,
-            CJS_Runtime* pRuntime,
-            int nType,
-            const CFX_WideString& script,
-            FX_DWORD dwElapse,
-            FX_DWORD dwTimeOut);
-  ~CJS_Timer() override;
-
-  void KillJSTimer();
-
-  int GetType() const { return m_nType; }
-  FX_DWORD GetTimeOut() const { return m_dwTimeOut; }
-  CJS_Runtime* GetRuntime() const { return m_bValid ? m_pRuntime : nullptr; }
-  CFX_WideString GetJScript() const { return m_swJScript; }
-
-  static void TimerProc(int idEvent);
-
- private:
-  using TimerMap = std::map<FX_UINT, CJS_Timer*>;
-  static TimerMap* GetGlobalTimerMap();
-
-  // CJS_Runtime::Observer
-  void OnDestroyed() override;
-
-  FX_DWORD m_nTimerID;
-  CJS_EmbedObj* const m_pEmbedObj;
-  bool m_bProcessing;
-  bool m_bValid;
-
-  // data
-  const int m_nType;  // 0:Interval; 1:TimeOut
-  const FX_DWORD m_dwTimeOut;
-  const CFX_WideString m_swJScript;
-  CJS_Runtime* const m_pRuntime;
-  CPDFDoc_Environment* const m_pApp;
-};
-
-#endif  // FPDFSDK_SRC_JAVASCRIPT_JS_OBJECT_H_
diff --git a/fpdfsdk/src/javascript/JS_Runtime.cpp b/fpdfsdk/src/javascript/JS_Runtime.cpp
deleted file mode 100644
index ba6d748..0000000
--- a/fpdfsdk/src/javascript/JS_Runtime.cpp
+++ /dev/null
@@ -1,337 +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
-
-#include "JS_Runtime.h"
-
-#include "Consts.h"
-#include "Document.h"
-#include "Field.h"
-#include "Icon.h"
-#include "JS_Context.h"
-#include "JS_Define.h"
-#include "JS_EventHandler.h"
-#include "JS_GlobalData.h"
-#include "JS_Object.h"
-#include "JS_Value.h"
-#include "PublicMethods.h"
-#include "app.h"
-#include "color.h"
-#include "console.h"
-#include "event.h"
-#include "fpdfsdk/include/fsdk_mgr.h"  // For CPDFDoc_Environment.
-#include "fpdfsdk/include/javascript/IJavaScript.h"
-#include "global.h"
-#include "report.h"
-#include "util.h"
-#include "third_party/base/stl_util.h"
-
-#ifdef PDF_ENABLE_XFA
-#include "fpdfsdk/include/fpdfxfa/fpdfxfa_app.h"
-#include "xfa/src/fxjse/src/value.h"
-#endif  // PDF_ENABLE_XFA
-
-// static
-void IJS_Runtime::Initialize(unsigned int slot, void* isolate) {
-  FXJS_Initialize(slot, reinterpret_cast<v8::Isolate*>(isolate));
-}
-
-// static
-IJS_Runtime* IJS_Runtime::Create(CPDFDoc_Environment* pEnv) {
-  return new CJS_Runtime(pEnv);
-}
-
-// static
-CJS_Runtime* CJS_Runtime::FromContext(const IJS_Context* cc) {
-  const CJS_Context* pContext = static_cast<const CJS_Context*>(cc);
-  return pContext->GetJSRuntime();
-}
-
-CJS_Runtime::CJS_Runtime(CPDFDoc_Environment* pApp)
-    : m_pApp(pApp),
-      m_pDocument(NULL),
-      m_bBlocking(FALSE),
-      m_isolate(NULL),
-      m_isolateManaged(false) {
-#ifndef PDF_ENABLE_XFA
-  IPDF_JSPLATFORM* pPlatform = m_pApp->GetFormFillInfo()->m_pJsPlatform;
-  if (pPlatform->version <= 2) {
-    unsigned int embedderDataSlot = 0;
-    v8::Isolate* pExternalIsolate = nullptr;
-    if (pPlatform->version == 2) {
-      pExternalIsolate = reinterpret_cast<v8::Isolate*>(pPlatform->m_isolate);
-      embedderDataSlot = pPlatform->m_v8EmbedderSlot;
-#else
-  if (CPDFXFA_App::GetInstance()->GetJSERuntime()) {
-    // TODO(tsepez): CPDFXFA_App should also use the embedder provided isolate.
-    m_isolate = (v8::Isolate*)CPDFXFA_App::GetInstance()->GetJSERuntime();
-  } else {
-    IPDF_JSPLATFORM* pPlatform = m_pApp->GetFormFillInfo()->m_pJsPlatform;
-    if (pPlatform->version <= 2) {
-      unsigned int embedderDataSlot = 0;
-      v8::Isolate* pExternalIsolate = nullptr;
-      if (pPlatform->version == 2) {
-        pExternalIsolate = reinterpret_cast<v8::Isolate*>(pPlatform->m_isolate);
-        embedderDataSlot = pPlatform->m_v8EmbedderSlot;
-      }
-      FXJS_Initialize(embedderDataSlot, pExternalIsolate);
-#endif
-    }
-#ifndef PDF_ENABLE_XFA
-    FXJS_Initialize(embedderDataSlot, pExternalIsolate);
-#else
-    m_isolateManaged = FXJS_GetIsolate(&m_isolate);
-  }
-
-  v8::Isolate* isolate = m_isolate;
-  v8::Isolate::Scope isolate_scope(isolate);
-  v8::Locker locker(isolate);
-  v8::HandleScope handle_scope(isolate);
-  if (CPDFXFA_App::GetInstance()->IsJavaScriptInitialized()) {
-    CJS_Context* pContext = (CJS_Context*)NewContext();
-    FXJS_InitializeRuntime(GetIsolate(), this, &m_context, &m_StaticObjects);
-    ReleaseContext(pContext);
-    return;
-#endif
-  }
-#ifndef PDF_ENABLE_XFA
-  m_isolateManaged = FXJS_GetIsolate(&m_isolate);
-#else
-
-#endif
-  if (m_isolateManaged || FXJS_GlobalIsolateRefCount() == 0)
-    DefineJSObjects();
-
-#ifdef PDF_ENABLE_XFA
-  CPDFXFA_App::GetInstance()->SetJavaScriptInitialized(TRUE);
-
-#endif
-  CJS_Context* pContext = (CJS_Context*)NewContext();
-  FXJS_InitializeRuntime(GetIsolate(), this, &m_context, &m_StaticObjects);
-  ReleaseContext(pContext);
-}
-
-CJS_Runtime::~CJS_Runtime() {
-  for (auto* obs : m_observers)
-    obs->OnDestroyed();
-
-  for (int i = 0, sz = m_ContextArray.GetSize(); i < sz; i++)
-    delete m_ContextArray.GetAt(i);
-
-  m_ContextArray.RemoveAll();
-#ifndef PDF_ENABLE_XFA
-  FXJS_ReleaseRuntime(GetIsolate(), &m_context, &m_StaticObjects);
-#endif
-
-  m_pApp = NULL;
-  m_pDocument = NULL;
-  m_context.Reset();
-
-  if (m_isolateManaged)
-    m_isolate->Dispose();
-}
-
-void CJS_Runtime::DefineJSObjects() {
-  v8::Isolate::Scope isolate_scope(GetIsolate());
-#ifdef PDF_ENABLE_XFA
-  v8::Locker locker(GetIsolate());
-#endif
-  v8::HandleScope handle_scope(GetIsolate());
-  v8::Local<v8::Context> context = v8::Context::New(GetIsolate());
-  v8::Context::Scope context_scope(context);
-
-  // The call order determines the "ObjDefID" assigned to each class.
-  // ObjDefIDs 0 - 2
-  CJS_Border::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_STATIC);
-  CJS_Display::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_STATIC);
-  CJS_Font::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_STATIC);
-
-  // ObjDefIDs 3 - 5
-  CJS_Highlight::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_STATIC);
-  CJS_Position::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_STATIC);
-  CJS_ScaleHow::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_STATIC);
-
-  // ObjDefIDs 6 - 8
-  CJS_ScaleWhen::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_STATIC);
-  CJS_Style::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_STATIC);
-  CJS_Zoomtype::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_STATIC);
-
-  // ObjDefIDs 9 - 11
-  CJS_App::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_STATIC);
-  CJS_Color::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_STATIC);
-  CJS_Console::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_STATIC);
-
-  // ObjDefIDs 12 - 14
-  CJS_Document::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_GLOBAL);
-  CJS_Event::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_STATIC);
-  CJS_Field::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_DYNAMIC);
-
-  // ObjDefIDs 15 - 17
-  CJS_Global::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_STATIC);
-  CJS_Icon::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_DYNAMIC);
-  CJS_Util::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_STATIC);
-
-  // ObjDefIDs 18 - 20 (these can't fail, return void).
-  CJS_PublicMethods::DefineJSObjects(GetIsolate());
-  CJS_GlobalConsts::DefineJSObjects(this);
-  CJS_GlobalArrays::DefineJSObjects(this);
-
-  // ObjDefIDs 21 - 22.
-  CJS_TimerObj::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_DYNAMIC);
-  CJS_PrintParamsObj::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_DYNAMIC);
-}
-
-IJS_Context* CJS_Runtime::NewContext() {
-  CJS_Context* p = new CJS_Context(this);
-  m_ContextArray.Add(p);
-  return p;
-}
-
-void CJS_Runtime::ReleaseContext(IJS_Context* pContext) {
-  CJS_Context* pJSContext = (CJS_Context*)pContext;
-
-  for (int i = 0, sz = m_ContextArray.GetSize(); i < sz; i++) {
-    if (pJSContext == m_ContextArray.GetAt(i)) {
-      delete pJSContext;
-      m_ContextArray.RemoveAt(i);
-      break;
-    }
-  }
-}
-
-IJS_Context* CJS_Runtime::GetCurrentContext() {
-  if (!m_ContextArray.GetSize())
-    return NULL;
-  return m_ContextArray.GetAt(m_ContextArray.GetSize() - 1);
-}
-
-void CJS_Runtime::SetReaderDocument(CPDFSDK_Document* pReaderDoc) {
-  if (m_pDocument != pReaderDoc) {
-    v8::Isolate::Scope isolate_scope(m_isolate);
-#ifdef PDF_ENABLE_XFA
-    v8::Locker locker(m_isolate);
-#endif
-    v8::HandleScope handle_scope(m_isolate);
-    v8::Local<v8::Context> context =
-        v8::Local<v8::Context>::New(m_isolate, m_context);
-    v8::Context::Scope context_scope(context);
-
-    m_pDocument = pReaderDoc;
-    if (pReaderDoc) {
-      v8::Local<v8::Object> pThis = FXJS_GetThisObj(GetIsolate());
-      if (!pThis.IsEmpty()) {
-        if (FXJS_GetObjDefnID(pThis) == CJS_Document::g_nObjDefnID) {
-          if (CJS_Document* pJSDocument =
-                  (CJS_Document*)FXJS_GetPrivate(GetIsolate(), pThis)) {
-            if (Document* pDocument = (Document*)pJSDocument->GetEmbedObject())
-              pDocument->AttachDoc(pReaderDoc);
-          }
-        }
-      }
-    }
-  }
-}
-
-int CJS_Runtime::Execute(IJS_Context* cc,
-                         const wchar_t* script,
-                         CFX_WideString* info) {
-  FXJSErr error = {};
-  int nRet = FXJS_Execute(m_isolate, cc, script, &error);
-  if (nRet < 0) {
-    info->Format(L"[ Line: %05d { %s } ] : %s", error.linnum - 1, error.srcline,
-                 error.message);
-  }
-  return nRet;
-}
-
-bool CJS_Runtime::AddEventToSet(const FieldEvent& event) {
-  return m_FieldEventSet.insert(event).second;
-}
-
-void CJS_Runtime::RemoveEventFromSet(const FieldEvent& event) {
-  m_FieldEventSet.erase(event);
-}
-
-v8::Local<v8::Context> CJS_Runtime::NewJSContext() {
-  return v8::Local<v8::Context>::New(m_isolate, m_context);
-}
-
-#ifdef PDF_ENABLE_XFA
-CFX_WideString ChangeObjName(const CFX_WideString& str) {
-  CFX_WideString sRet = str;
-  sRet.Replace(L"_", L".");
-  return sRet;
-}
-FX_BOOL CJS_Runtime::GetHValueByName(const CFX_ByteStringC& utf8Name,
-                                     FXJSE_HVALUE hValue) {
-#ifdef PDF_ENABLE_XFA
-  const FX_CHAR* name = utf8Name.GetCStr();
-
-  v8::Locker lock(GetIsolate());
-  v8::Isolate::Scope isolate_scope(GetIsolate());
-  v8::HandleScope handle_scope(GetIsolate());
-  v8::Local<v8::Context> old_context = GetIsolate()->GetCurrentContext();
-  v8::Local<v8::Context> context =
-      v8::Local<v8::Context>::New(GetIsolate(), m_context);
-  v8::Context::Scope context_scope(context);
-
-  // Caution: We're about to hand to XFA an object that in order to invoke
-  // methods will require that the current v8::Context always has a pointer
-  // to a CJS_Runtime in its embedder data slot. Unfortunately, XFA creates
-  // its own v8::Context which has not initialized the embedder data slot.
-  // Do so now.
-  // TODO(tsepez): redesign PDF-side objects to not rely on v8::Context's
-  // embedder data slots, and/or to always use the right context.
-  FXJS_SetRuntimeForV8Context(old_context, this);
-
-  v8::Local<v8::Value> propvalue =
-      context->Global()->Get(v8::String::NewFromUtf8(
-          GetIsolate(), name, v8::String::kNormalString, utf8Name.GetLength()));
-
-  if (propvalue.IsEmpty()) {
-    FXJSE_Value_SetUndefined(hValue);
-    return FALSE;
-  }
-  ((CFXJSE_Value*)hValue)->ForceSetValue(propvalue);
-#endif
-
-  return TRUE;
-}
-FX_BOOL CJS_Runtime::SetHValueByName(const CFX_ByteStringC& utf8Name,
-                                     FXJSE_HVALUE hValue) {
-#ifdef PDF_ENABLE_XFA
-  if (utf8Name.IsEmpty() || hValue == NULL)
-    return FALSE;
-  const FX_CHAR* name = utf8Name.GetCStr();
-  v8::Isolate* pIsolate = GetIsolate();
-  v8::Locker lock(pIsolate);
-  v8::Isolate::Scope isolate_scope(pIsolate);
-  v8::HandleScope handle_scope(pIsolate);
-  v8::Local<v8::Context> context =
-      v8::Local<v8::Context>::New(pIsolate, m_context);
-  v8::Context::Scope context_scope(context);
-
-  // v8::Local<v8::Context> tmpCotext =
-  // v8::Local<v8::Context>::New(GetIsolate(), m_context);
-  v8::Local<v8::Value> propvalue = v8::Local<v8::Value>::New(
-      GetIsolate(), ((CFXJSE_Value*)hValue)->DirectGetValue());
-  context->Global()->Set(
-      v8::String::NewFromUtf8(pIsolate, name, v8::String::kNormalString,
-                              utf8Name.GetLength()),
-      propvalue);
-#endif
-  return TRUE;
-}
-
-#endif
-void CJS_Runtime::AddObserver(Observer* observer) {
-  ASSERT(!pdfium::ContainsKey(m_observers, observer));
-  m_observers.insert(observer);
-}
-
-void CJS_Runtime::RemoveObserver(Observer* observer) {
-  ASSERT(pdfium::ContainsKey(m_observers, observer));
-  m_observers.erase(observer);
-}
diff --git a/fpdfsdk/src/javascript/JS_Runtime.h b/fpdfsdk/src/javascript/JS_Runtime.h
deleted file mode 100644
index decc553..0000000
--- a/fpdfsdk/src/javascript/JS_Runtime.h
+++ /dev/null
@@ -1,86 +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_SRC_JAVASCRIPT_JS_RUNTIME_H_
-#define FPDFSDK_SRC_JAVASCRIPT_JS_RUNTIME_H_
-
-#include <set>
-#include <utility>
-#include <vector>
-
-#include "JS_EventHandler.h"
-#include "core/include/fxcrt/fx_basic.h"
-#include "fpdfsdk/include/javascript/IJavaScript.h"
-#include "fpdfsdk/include/jsapi/fxjs_v8.h"
-
-class CJS_Context;
-
-class CJS_Runtime : public IJS_Runtime {
- public:
-  class Observer {
-   public:
-    virtual void OnDestroyed() = 0;
-
-   protected:
-    virtual ~Observer() {}
-  };
-
-  using FieldEvent = std::pair<CFX_WideString, JS_EVENT_T>;
-
-  static CJS_Runtime* FromContext(const IJS_Context* cc);
-
-  explicit CJS_Runtime(CPDFDoc_Environment* pApp);
-  ~CJS_Runtime() override;
-
-  // IJS_Runtime
-  IJS_Context* NewContext() override;
-  void ReleaseContext(IJS_Context* pContext) override;
-  IJS_Context* GetCurrentContext() override;
-  void SetReaderDocument(CPDFSDK_Document* pReaderDoc) override;
-  CPDFSDK_Document* GetReaderDocument() override { return m_pDocument; }
-  int Execute(IJS_Context* cc,
-              const wchar_t* script,
-              CFX_WideString* info) override;
-
-  CPDFDoc_Environment* GetReaderApp() const { return m_pApp; }
-
-  // Returns true if the event isn't already found in the set.
-  bool AddEventToSet(const FieldEvent& event);
-  void RemoveEventFromSet(const FieldEvent& event);
-
-  void BeginBlock() { m_bBlocking = TRUE; }
-  void EndBlock() { m_bBlocking = FALSE; }
-  FX_BOOL IsBlocking() const { return m_bBlocking; }
-
-  v8::Isolate* GetIsolate() const { return m_isolate; }
-  v8::Local<v8::Context> NewJSContext();
-
-#ifdef PDF_ENABLE_XFA
-  FX_BOOL GetHValueByName(const CFX_ByteStringC& utf8Name,
-                          FXJSE_HVALUE hValue) override;
-  FX_BOOL SetHValueByName(const CFX_ByteStringC& utf8Name,
-                          FXJSE_HVALUE hValue) override;
-#endif  // PDF_ENABLE_XFA
-
-  void AddObserver(Observer* observer);
-  void RemoveObserver(Observer* observer);
-
- private:
-  void DefineJSObjects();
-
-  CFX_ArrayTemplate<CJS_Context*> m_ContextArray;
-  CPDFDoc_Environment* m_pApp;
-  CPDFSDK_Document* m_pDocument;
-  FX_BOOL m_bBlocking;
-  std::set<FieldEvent> m_FieldEventSet;
-  v8::Isolate* m_isolate;
-  bool m_isolateManaged;
-  v8::Global<v8::Context> m_context;
-  std::vector<v8::Global<v8::Object>*> m_StaticObjects;
-  std::set<Observer*> m_observers;
-};
-
-#endif  // FPDFSDK_SRC_JAVASCRIPT_JS_RUNTIME_H_
diff --git a/fpdfsdk/src/javascript/JS_Runtime_Stub.cpp b/fpdfsdk/src/javascript/JS_Runtime_Stub.cpp
deleted file mode 100644
index e9d5a22..0000000
--- a/fpdfsdk/src/javascript/JS_Runtime_Stub.cpp
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright 2015 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 <memory>
-
-#include "fpdfsdk/include/fsdk_mgr.h"  // For CPDFDoc_Environment.
-#include "fpdfsdk/include/javascript/IJavaScript.h"
-
-class CJS_ContextStub final : public IJS_Context {
- public:
-  CJS_ContextStub() {}
-  ~CJS_ContextStub() override {}
-
-  // IJS_Context:
-  FX_BOOL RunScript(const CFX_WideString& script,
-                    CFX_WideString* info) override {
-    return FALSE;
-  }
-
-  void OnApp_Init() override {}
-  void OnDoc_Open(CPDFSDK_Document* pDoc,
-                  const CFX_WideString& strTargetName) override {}
-  void OnDoc_WillPrint(CPDFSDK_Document* pDoc) override {}
-  void OnDoc_DidPrint(CPDFSDK_Document* pDoc) override {}
-  void OnDoc_WillSave(CPDFSDK_Document* pDoc) override {}
-  void OnDoc_DidSave(CPDFSDK_Document* pDoc) override {}
-  void OnDoc_WillClose(CPDFSDK_Document* pDoc) override {}
-  void OnPage_Open(CPDFSDK_Document* pTarget) override {}
-  void OnPage_Close(CPDFSDK_Document* pTarget) override {}
-  void OnPage_InView(CPDFSDK_Document* pTarget) override {}
-  void OnPage_OutView(CPDFSDK_Document* pTarget) override {}
-  void OnField_MouseDown(FX_BOOL bModifier,
-                         FX_BOOL bShift,
-                         CPDF_FormField* pTarget) override {}
-  void OnField_MouseEnter(FX_BOOL bModifier,
-                          FX_BOOL bShift,
-                          CPDF_FormField* pTarget) override {}
-  void OnField_MouseExit(FX_BOOL bModifier,
-                         FX_BOOL bShift,
-                         CPDF_FormField* pTarget) override {}
-  void OnField_MouseUp(FX_BOOL bModifier,
-                       FX_BOOL bShift,
-                       CPDF_FormField* pTarget) override {}
-  void OnField_Focus(FX_BOOL bModifier,
-                     FX_BOOL bShift,
-                     CPDF_FormField* pTarget,
-                     const CFX_WideString& Value) override {}
-  void OnField_Blur(FX_BOOL bModifier,
-                    FX_BOOL bShift,
-                    CPDF_FormField* pTarget,
-                    const CFX_WideString& Value) override {}
-  void OnField_Calculate(CPDF_FormField* pSource,
-                         CPDF_FormField* pTarget,
-                         CFX_WideString& Value,
-                         FX_BOOL& bRc) override {}
-  void OnField_Format(CPDF_FormField* pTarget,
-                      CFX_WideString& Value,
-                      FX_BOOL bWillCommit) override {}
-  void OnField_Keystroke(CFX_WideString& strChange,
-                         const CFX_WideString& strChangeEx,
-                         FX_BOOL KeyDown,
-                         FX_BOOL bModifier,
-                         int& nSelEnd,
-                         int& nSelStart,
-                         FX_BOOL bShift,
-                         CPDF_FormField* pTarget,
-                         CFX_WideString& Value,
-                         FX_BOOL bWillCommit,
-                         FX_BOOL bFieldFull,
-                         FX_BOOL& bRc) override {}
-  void OnField_Validate(CFX_WideString& strChange,
-                        const CFX_WideString& strChangeEx,
-                        FX_BOOL bKeyDown,
-                        FX_BOOL bModifier,
-                        FX_BOOL bShift,
-                        CPDF_FormField* pTarget,
-                        CFX_WideString& Value,
-                        FX_BOOL& bRc) override {}
-  void OnScreen_Focus(FX_BOOL bModifier,
-                      FX_BOOL bShift,
-                      CPDFSDK_Annot* pScreen) override {}
-  void OnScreen_Blur(FX_BOOL bModifier,
-                     FX_BOOL bShift,
-                     CPDFSDK_Annot* pScreen) override {}
-  void OnScreen_Open(FX_BOOL bModifier,
-                     FX_BOOL bShift,
-                     CPDFSDK_Annot* pScreen) override {}
-  void OnScreen_Close(FX_BOOL bModifier,
-                      FX_BOOL bShift,
-                      CPDFSDK_Annot* pScreen) override {}
-  void OnScreen_MouseDown(FX_BOOL bModifier,
-                          FX_BOOL bShift,
-                          CPDFSDK_Annot* pScreen) override {}
-  void OnScreen_MouseUp(FX_BOOL bModifier,
-                        FX_BOOL bShift,
-                        CPDFSDK_Annot* pScreen) override {}
-  void OnScreen_MouseEnter(FX_BOOL bModifier,
-                           FX_BOOL bShift,
-                           CPDFSDK_Annot* pScreen) override {}
-  void OnScreen_MouseExit(FX_BOOL bModifier,
-                          FX_BOOL bShift,
-                          CPDFSDK_Annot* pScreen) override {}
-  void OnScreen_InView(FX_BOOL bModifier,
-                       FX_BOOL bShift,
-                       CPDFSDK_Annot* pScreen) override {}
-  void OnScreen_OutView(FX_BOOL bModifier,
-                        FX_BOOL bShift,
-                        CPDFSDK_Annot* pScreen) override {}
-  void OnBookmark_MouseUp(CPDF_Bookmark* pBookMark) override {}
-  void OnLink_MouseUp(CPDFSDK_Document* pTarget) override {}
-  void OnMenu_Exec(CPDFSDK_Document* pTarget, const CFX_WideString&) override {}
-  void OnBatchExec(CPDFSDK_Document* pTarget) override {}
-  void OnConsole_Exec() override {}
-  void OnExternal_Exec() override {}
-  void EnableMessageBox(FX_BOOL bEnable) override {}
-};
-
-class CJS_RuntimeStub final : public IJS_Runtime {
- public:
-  CJS_RuntimeStub() : m_pDoc(nullptr) {}
-  ~CJS_RuntimeStub() override {}
-
-  IJS_Context* NewContext() override {
-    if (!m_pContext)
-      m_pContext.reset(new CJS_ContextStub());
-    return GetCurrentContext();
-  }
-
-  IJS_Context* GetCurrentContext() override { return m_pContext.get(); }
-  void ReleaseContext(IJS_Context* pContext) override {}
-
-  void SetReaderDocument(CPDFSDK_Document* pReaderDoc) override {
-    m_pDoc = pReaderDoc;
-  }
-  CPDFSDK_Document* GetReaderDocument() override { return m_pDoc; }
-
-#ifdef PDF_ENABLE_XFA
-  virtual FX_BOOL GetHValueByName(const CFX_ByteStringC&,
-                                  FXJSE_HVALUE) override {
-    return FALSE;
-  }
-
-  virtual FX_BOOL SetHValueByName(const CFX_ByteStringC&,
-                                  FXJSE_HVALUE) override {
-    return FALSE;
-  }
-#endif  // PDF_ENABLE_XFA
-
-  int Execute(IJS_Context* cc,
-              const wchar_t* script,
-              CFX_WideString* info) override {
-    return 0;
-  }
-
- protected:
-  CPDFSDK_Document* m_pDoc;
-  std::unique_ptr<CJS_ContextStub> m_pContext;
-};
-
-// static
-void IJS_Runtime::Initialize(unsigned int slot, void* isolate) {
-}
-
-// static
-IJS_Runtime* IJS_Runtime::Create(CPDFDoc_Environment* pEnv) {
-  return new CJS_RuntimeStub;
-}
diff --git a/fpdfsdk/src/javascript/JS_Value.cpp b/fpdfsdk/src/javascript/JS_Value.cpp
deleted file mode 100644
index bd00adc..0000000
--- a/fpdfsdk/src/javascript/JS_Value.cpp
+++ /dev/null
@@ -1,871 +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
-
-#include "JS_Value.h"
-
-#include <time.h>
-#include <cmath>
-#include <limits>
-
-#include "Document.h"
-#include "JS_Define.h"
-#include "JS_Object.h"
-
-static const FX_DWORD g_nan[2] = {0, 0x7FF80000};
-static double GetNan() {
-  return *(double*)g_nan;
-}
-
-/* ---------------------------- CJS_Value ---------------------------- */
-
-CJS_Value::CJS_Value(CJS_Runtime* pRuntime)
-    : m_eType(VT_unknown), m_pJSRuntime(pRuntime) {
-}
-
-CJS_Value::CJS_Value(CJS_Runtime* pRuntime, v8::Local<v8::Value> pValue, Type t)
-    : m_eType(t), m_pValue(pValue), m_pJSRuntime(pRuntime) {
-}
-
-CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const int& iValue)
-    : m_pJSRuntime(pRuntime) {
-  operator=(iValue);
-}
-
-CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const bool& bValue)
-    : m_pJSRuntime(pRuntime) {
-  operator=(bValue);
-}
-
-CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const float& fValue)
-    : m_pJSRuntime(pRuntime) {
-  operator=(fValue);
-}
-
-CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const double& dValue)
-    : m_pJSRuntime(pRuntime) {
-  operator=(dValue);
-}
-
-CJS_Value::CJS_Value(CJS_Runtime* pRuntime, v8::Local<v8::Object> pJsObj)
-    : m_pJSRuntime(pRuntime) {
-  operator=(pJsObj);
-}
-
-CJS_Value::CJS_Value(CJS_Runtime* pRuntime, CJS_Object* pJsObj)
-    : m_pJSRuntime(pRuntime) {
-  operator=(pJsObj);
-}
-
-CJS_Value::CJS_Value(CJS_Runtime* pRuntime, CJS_Document* pJsDoc)
-    : m_pJSRuntime(pRuntime) {
-  m_eType = VT_object;
-  if (pJsDoc)
-    m_pValue = pJsDoc->ToV8Object();
-}
-
-CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const FX_WCHAR* pWstr)
-    : m_pJSRuntime(pRuntime) {
-  operator=(pWstr);
-}
-
-CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const FX_CHAR* pStr)
-    : m_pJSRuntime(pRuntime) {
-  operator=(pStr);
-}
-
-CJS_Value::CJS_Value(CJS_Runtime* pRuntime, CJS_Array& array)
-    : m_pJSRuntime(pRuntime) {
-  operator=(array);
-}
-
-CJS_Value::~CJS_Value() {}
-
-void CJS_Value::Attach(v8::Local<v8::Value> pValue, Type t) {
-  m_pValue = pValue;
-  m_eType = t;
-}
-
-void CJS_Value::Attach(CJS_Value* pValue) {
-  if (pValue)
-    Attach(pValue->ToV8Value(), pValue->GetType());
-}
-
-void CJS_Value::Detach() {
-  m_pValue = v8::Local<v8::Value>();
-  m_eType = VT_unknown;
-}
-
-/* ----------------------------------------------------------------------------------------
- */
-
-int CJS_Value::ToInt() const {
-  return FXJS_ToInt32(m_pJSRuntime->GetIsolate(), m_pValue);
-}
-
-bool CJS_Value::ToBool() const {
-  return FXJS_ToBoolean(m_pJSRuntime->GetIsolate(), m_pValue);
-}
-
-double CJS_Value::ToDouble() const {
-  return FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pValue);
-}
-
-float CJS_Value::ToFloat() const {
-  return (float)ToDouble();
-}
-
-CJS_Object* CJS_Value::ToCJSObject() const {
-  v8::Local<v8::Object> pObj =
-      FXJS_ToObject(m_pJSRuntime->GetIsolate(), m_pValue);
-  return (CJS_Object*)FXJS_GetPrivate(m_pJSRuntime->GetIsolate(), pObj);
-}
-
-v8::Local<v8::Object> CJS_Value::ToV8Object() const {
-  return FXJS_ToObject(m_pJSRuntime->GetIsolate(), m_pValue);
-}
-
-CFX_WideString CJS_Value::ToCFXWideString() const {
-  return FXJS_ToString(m_pJSRuntime->GetIsolate(), m_pValue);
-}
-
-CFX_ByteString CJS_Value::ToCFXByteString() const {
-  return CFX_ByteString::FromUnicode(ToCFXWideString());
-}
-
-v8::Local<v8::Value> CJS_Value::ToV8Value() const {
-  return m_pValue;
-}
-
-v8::Local<v8::Array> CJS_Value::ToV8Array() const {
-  if (IsArrayObject())
-    return v8::Local<v8::Array>::Cast(
-        FXJS_ToObject(m_pJSRuntime->GetIsolate(), m_pValue));
-  return v8::Local<v8::Array>();
-}
-
-/* ----------------------------------------------------------------------------------------
- */
-
-void CJS_Value::operator=(int iValue) {
-  m_pValue = FXJS_NewNumber(m_pJSRuntime->GetIsolate(), iValue);
-  m_eType = VT_number;
-}
-
-void CJS_Value::operator=(bool bValue) {
-  m_pValue = FXJS_NewBoolean(m_pJSRuntime->GetIsolate(), bValue);
-  m_eType = VT_boolean;
-}
-
-void CJS_Value::operator=(double dValue) {
-  m_pValue = FXJS_NewNumber(m_pJSRuntime->GetIsolate(), dValue);
-  m_eType = VT_number;
-}
-
-void CJS_Value::operator=(float fValue) {
-  m_pValue = FXJS_NewNumber(m_pJSRuntime->GetIsolate(), fValue);
-  m_eType = VT_number;
-}
-
-void CJS_Value::operator=(v8::Local<v8::Object> pObj) {
-  m_pValue = FXJS_NewObject(m_pJSRuntime->GetIsolate(), pObj);
-  m_eType = VT_fxobject;
-}
-
-void CJS_Value::operator=(CJS_Object* pObj) {
-  if (pObj)
-    operator=(pObj->ToV8Object());
-}
-
-void CJS_Value::operator=(CJS_Document* pJsDoc) {
-  m_eType = VT_object;
-  if (pJsDoc) {
-    m_pValue = pJsDoc->ToV8Object();
-  }
-}
-
-void CJS_Value::operator=(const FX_WCHAR* pWstr) {
-  m_pValue = FXJS_NewString(m_pJSRuntime->GetIsolate(), (wchar_t*)pWstr);
-  m_eType = VT_string;
-}
-
-void CJS_Value::SetNull() {
-  m_pValue = FXJS_NewNull();
-  m_eType = VT_null;
-}
-
-void CJS_Value::operator=(const FX_CHAR* pStr) {
-  operator=(CFX_WideString::FromLocal(pStr).c_str());
-}
-
-void CJS_Value::operator=(CJS_Array& array) {
-  m_pValue =
-      FXJS_NewObject2(m_pJSRuntime->GetIsolate(), (v8::Local<v8::Array>)array);
-  m_eType = VT_object;
-}
-
-void CJS_Value::operator=(CJS_Date& date) {
-  m_pValue = FXJS_NewDate(m_pJSRuntime->GetIsolate(), (double)date);
-  m_eType = VT_date;
-}
-
-void CJS_Value::operator=(CJS_Value value) {
-  m_pValue = value.ToV8Value();
-  m_eType = value.m_eType;
-  m_pJSRuntime = value.m_pJSRuntime;
-}
-
-/* ----------------------------------------------------------------------------------------
- */
-
-CJS_Value::Type CJS_Value::GetType() const {
-  if (m_pValue.IsEmpty())
-    return VT_unknown;
-  if (m_pValue->IsString())
-    return VT_string;
-  if (m_pValue->IsNumber())
-    return VT_number;
-  if (m_pValue->IsBoolean())
-    return VT_boolean;
-  if (m_pValue->IsDate())
-    return VT_date;
-  if (m_pValue->IsObject())
-    return VT_object;
-  if (m_pValue->IsNull())
-    return VT_null;
-  if (m_pValue->IsUndefined())
-    return VT_undefined;
-  return VT_unknown;
-}
-
-FX_BOOL CJS_Value::IsArrayObject() const {
-  if (m_pValue.IsEmpty())
-    return FALSE;
-  return m_pValue->IsArray();
-}
-
-FX_BOOL CJS_Value::IsDateObject() const {
-  if (m_pValue.IsEmpty())
-    return FALSE;
-  return m_pValue->IsDate();
-}
-
-// CJS_Value::operator CJS_Array()
-FX_BOOL CJS_Value::ConvertToArray(CJS_Array& array) const {
-  if (IsArrayObject()) {
-    array.Attach(FXJS_ToArray(m_pJSRuntime->GetIsolate(), m_pValue));
-    return TRUE;
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CJS_Value::ConvertToDate(CJS_Date& date) const {
-  // 	if (GetType() == VT_date)
-  // 	{
-  // 		date = (double)(*this);
-  // 		return TRUE;
-  // 	}
-
-  if (IsDateObject()) {
-    date.Attach(m_pValue);
-    return TRUE;
-  }
-
-  return FALSE;
-}
-
-/* ---------------------------- CJS_PropValue ---------------------------- */
-
-CJS_PropValue::CJS_PropValue(const CJS_Value& value)
-    : CJS_Value(value), m_bIsSetting(0) {}
-
-CJS_PropValue::CJS_PropValue(CJS_Runtime* pRuntime)
-    : CJS_Value(pRuntime), m_bIsSetting(0) {
-}
-
-CJS_PropValue::~CJS_PropValue() {
-}
-
-void CJS_PropValue::operator<<(int iValue) {
-  ASSERT(!m_bIsSetting);
-  CJS_Value::operator=(iValue);
-}
-
-void CJS_PropValue::operator>>(int& iValue) const {
-  ASSERT(m_bIsSetting);
-  iValue = CJS_Value::ToInt();
-}
-
-void CJS_PropValue::operator<<(bool bValue) {
-  ASSERT(!m_bIsSetting);
-  CJS_Value::operator=(bValue);
-}
-
-void CJS_PropValue::operator>>(bool& bValue) const {
-  ASSERT(m_bIsSetting);
-  bValue = CJS_Value::ToBool();
-}
-
-void CJS_PropValue::operator<<(double dValue) {
-  ASSERT(!m_bIsSetting);
-  CJS_Value::operator=(dValue);
-}
-
-void CJS_PropValue::operator>>(double& dValue) const {
-  ASSERT(m_bIsSetting);
-  dValue = CJS_Value::ToDouble();
-}
-
-void CJS_PropValue::operator<<(CJS_Object* pObj) {
-  ASSERT(!m_bIsSetting);
-  CJS_Value::operator=(pObj);
-}
-
-void CJS_PropValue::operator>>(CJS_Object*& ppObj) const {
-  ASSERT(m_bIsSetting);
-  ppObj = CJS_Value::ToCJSObject();
-}
-
-void CJS_PropValue::operator<<(CJS_Document* pJsDoc) {
-  ASSERT(!m_bIsSetting);
-  CJS_Value::operator=(pJsDoc);
-}
-
-void CJS_PropValue::operator>>(CJS_Document*& ppJsDoc) const {
-  ASSERT(m_bIsSetting);
-  ppJsDoc = static_cast<CJS_Document*>(CJS_Value::ToCJSObject());
-}
-
-void CJS_PropValue::operator<<(v8::Local<v8::Object> pObj) {
-  ASSERT(!m_bIsSetting);
-  CJS_Value::operator=(pObj);
-}
-
-void CJS_PropValue::operator>>(v8::Local<v8::Object>& ppObj) const {
-  ASSERT(m_bIsSetting);
-  ppObj = CJS_Value::ToV8Object();
-}
-
-void CJS_PropValue::StartSetting() {
-  m_bIsSetting = 1;
-}
-
-void CJS_PropValue::StartGetting() {
-  m_bIsSetting = 0;
-}
-void CJS_PropValue::operator<<(CFX_ByteString string) {
-  ASSERT(!m_bIsSetting);
-  CJS_Value::operator=(string.c_str());
-}
-
-void CJS_PropValue::operator>>(CFX_ByteString& string) const {
-  ASSERT(m_bIsSetting);
-  string = CJS_Value::ToCFXByteString();
-}
-
-void CJS_PropValue::operator<<(const FX_WCHAR* c_string) {
-  ASSERT(!m_bIsSetting);
-  CJS_Value::operator=(c_string);
-}
-
-void CJS_PropValue::operator>>(CFX_WideString& wide_string) const {
-  ASSERT(m_bIsSetting);
-  wide_string = CJS_Value::ToCFXWideString();
-}
-
-void CJS_PropValue::operator<<(CFX_WideString wide_string) {
-  ASSERT(!m_bIsSetting);
-  CJS_Value::operator=(wide_string.c_str());
-}
-
-void CJS_PropValue::operator>>(CJS_Array& array) const {
-  ASSERT(m_bIsSetting);
-  ConvertToArray(array);
-}
-
-void CJS_PropValue::operator<<(CJS_Array& array) {
-  ASSERT(!m_bIsSetting);
-  CJS_Value::operator=(array);
-}
-
-void CJS_PropValue::operator>>(CJS_Date& date) const {
-  ASSERT(m_bIsSetting);
-  ConvertToDate(date);
-}
-
-void CJS_PropValue::operator<<(CJS_Date& date) {
-  ASSERT(!m_bIsSetting);
-  CJS_Value::operator=(date);
-}
-
-CJS_PropValue::operator v8::Local<v8::Value>() const {
-  return m_pValue;
-}
-
-CJS_Array::CJS_Array(CJS_Runtime* pRuntime) : m_pJSRuntime(pRuntime) {
-}
-
-CJS_Array::~CJS_Array() {}
-
-void CJS_Array::Attach(v8::Local<v8::Array> pArray) {
-  m_pArray = pArray;
-}
-
-FX_BOOL CJS_Array::IsAttached() {
-  return FALSE;
-}
-
-void CJS_Array::GetElement(unsigned index, CJS_Value& value) {
-  if (m_pArray.IsEmpty())
-    return;
-  v8::Local<v8::Value> p =
-      FXJS_GetArrayElement(m_pJSRuntime->GetIsolate(), m_pArray, index);
-  value.Attach(p, CJS_Value::VT_object);
-}
-
-void CJS_Array::SetElement(unsigned index, CJS_Value value) {
-  if (m_pArray.IsEmpty())
-    m_pArray = FXJS_NewArray(m_pJSRuntime->GetIsolate());
-
-  FXJS_PutArrayElement(m_pJSRuntime->GetIsolate(), m_pArray, index,
-                       value.ToV8Value());
-}
-
-int CJS_Array::GetLength() {
-  if (m_pArray.IsEmpty())
-    return 0;
-  return FXJS_GetArrayLength(m_pArray);
-}
-
-CJS_Array::operator v8::Local<v8::Array>() {
-  if (m_pArray.IsEmpty())
-    m_pArray = FXJS_NewArray(m_pJSRuntime->GetIsolate());
-
-  return m_pArray;
-}
-
-CJS_Date::CJS_Date(CJS_Runtime* pRuntime) : m_pJSRuntime(pRuntime) {
-}
-
-CJS_Date::CJS_Date(CJS_Runtime* pRuntime, double dMsecTime)
-    : m_pJSRuntime(pRuntime) {
-  m_pDate = FXJS_NewDate(pRuntime->GetIsolate(), dMsecTime);
-}
-
-CJS_Date::CJS_Date(CJS_Runtime* pRuntime,
-                   int year,
-                   int mon,
-                   int day,
-                   int hour,
-                   int min,
-                   int sec)
-    : m_pJSRuntime(pRuntime) {
-  m_pDate = FXJS_NewDate(pRuntime->GetIsolate(),
-                         MakeDate(year, mon, day, hour, min, sec, 0));
-}
-
-double CJS_Date::MakeDate(int year,
-                          int mon,
-                          int day,
-                          int hour,
-                          int min,
-                          int sec,
-                          int ms) {
-  return JS_MakeDate(JS_MakeDay(year, mon, day),
-                     JS_MakeTime(hour, min, sec, ms));
-}
-
-CJS_Date::~CJS_Date() {}
-
-FX_BOOL CJS_Date::IsValidDate() {
-  if (m_pDate.IsEmpty())
-    return FALSE;
-  return !JS_PortIsNan(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate));
-}
-
-void CJS_Date::Attach(v8::Local<v8::Value> pDate) {
-  m_pDate = pDate;
-}
-
-int CJS_Date::GetYear() {
-  if (IsValidDate())
-    return JS_GetYearFromTime(
-        JS_LocalTime(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate)));
-
-  return 0;
-}
-
-void CJS_Date::SetYear(int iYear) {
-  double date = MakeDate(iYear, GetMonth(), GetDay(), GetHours(), GetMinutes(),
-                         GetSeconds(), 0);
-  FXJS_ValueCopy(m_pDate, FXJS_NewDate(m_pJSRuntime->GetIsolate(), date));
-}
-
-int CJS_Date::GetMonth() {
-  if (IsValidDate())
-    return JS_GetMonthFromTime(
-        JS_LocalTime(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate)));
-
-  return 0;
-}
-
-void CJS_Date::SetMonth(int iMonth) {
-  double date = MakeDate(GetYear(), iMonth, GetDay(), GetHours(), GetMinutes(),
-                         GetSeconds(), 0);
-  FXJS_ValueCopy(m_pDate, FXJS_NewDate(m_pJSRuntime->GetIsolate(), date));
-}
-
-int CJS_Date::GetDay() {
-  if (IsValidDate())
-    return JS_GetDayFromTime(
-        JS_LocalTime(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate)));
-
-  return 0;
-}
-
-void CJS_Date::SetDay(int iDay) {
-  double date = MakeDate(GetYear(), GetMonth(), iDay, GetHours(), GetMinutes(),
-                         GetSeconds(), 0);
-  FXJS_ValueCopy(m_pDate, FXJS_NewDate(m_pJSRuntime->GetIsolate(), date));
-}
-
-int CJS_Date::GetHours() {
-  if (IsValidDate())
-    return JS_GetHourFromTime(
-        JS_LocalTime(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate)));
-
-  return 0;
-}
-
-void CJS_Date::SetHours(int iHours) {
-  double date = MakeDate(GetYear(), GetMonth(), GetDay(), iHours, GetMinutes(),
-                         GetSeconds(), 0);
-  FXJS_ValueCopy(m_pDate, FXJS_NewDate(m_pJSRuntime->GetIsolate(), date));
-}
-
-int CJS_Date::GetMinutes() {
-  if (IsValidDate())
-    return JS_GetMinFromTime(
-        JS_LocalTime(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate)));
-
-  return 0;
-}
-
-void CJS_Date::SetMinutes(int minutes) {
-  double date = MakeDate(GetYear(), GetMonth(), GetDay(), GetHours(), minutes,
-                         GetSeconds(), 0);
-  FXJS_ValueCopy(m_pDate, FXJS_NewDate(m_pJSRuntime->GetIsolate(), date));
-}
-
-int CJS_Date::GetSeconds() {
-  if (IsValidDate())
-    return JS_GetSecFromTime(
-        JS_LocalTime(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate)));
-
-  return 0;
-}
-
-void CJS_Date::SetSeconds(int seconds) {
-  double date = MakeDate(GetYear(), GetMonth(), GetDay(), GetHours(),
-                         GetMinutes(), seconds, 0);
-  FXJS_ValueCopy(m_pDate, FXJS_NewDate(m_pJSRuntime->GetIsolate(), date));
-}
-
-CJS_Date::operator v8::Local<v8::Value>() {
-  return m_pDate;
-}
-
-CJS_Date::operator double() const {
-  if (m_pDate.IsEmpty())
-    return 0.0;
-  return FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate);
-}
-
-CFX_WideString CJS_Date::ToString() const {
-  if (m_pDate.IsEmpty())
-    return L"";
-  return FXJS_ToString(m_pJSRuntime->GetIsolate(), m_pDate);
-}
-
-double _getLocalTZA() {
-  if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
-    return 0;
-  time_t t = 0;
-  time(&t);
-  localtime(&t);
-#if _MSC_VER >= 1900
-  // In gcc and in Visual Studio prior to VS 2015 'timezone' is a global
-  // variable declared in time.h. That variable was deprecated and in VS 2015
-  // is removed, with _get_timezone replacing it.
-  long timezone = 0;
-  _get_timezone(&timezone);
-#endif
-  return (double)(-(timezone * 1000));
-}
-
-int _getDaylightSavingTA(double d) {
-  if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
-    return 0;
-  time_t t = (time_t)(d / 1000);
-  struct tm* tmp = localtime(&t);
-  if (!tmp)
-    return 0;
-  if (tmp->tm_isdst > 0)
-    // One hour.
-    return (int)60 * 60 * 1000;
-  return 0;
-}
-
-double _Mod(double x, double y) {
-  double r = fmod(x, y);
-  if (r < 0)
-    r += y;
-  return r;
-}
-
-int _isfinite(double v) {
-#if _MSC_VER
-  return ::_finite(v);
-#else
-  return std::fabs(v) < std::numeric_limits<double>::max();
-#endif
-}
-
-double _toInteger(double n) {
-  return (n >= 0) ? FXSYS_floor(n) : -FXSYS_floor(-n);
-}
-
-bool _isLeapYear(int year) {
-  return (year % 4 == 0) && ((year % 100 != 0) || (year % 400 != 0));
-}
-
-int _DayFromYear(int y) {
-  return (int)(365 * (y - 1970.0) + FXSYS_floor((y - 1969.0) / 4) -
-               FXSYS_floor((y - 1901.0) / 100) +
-               FXSYS_floor((y - 1601.0) / 400));
-}
-
-double _TimeFromYear(int y) {
-  return 86400000.0 * _DayFromYear(y);
-}
-
-double _TimeFromYearMonth(int y, int m) {
-  static int daysMonth[12] = {
-      0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
-  static int leapDaysMonth[12] = {
-      0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335};
-  int* pMonth = daysMonth;
-  if (_isLeapYear(y))
-    pMonth = leapDaysMonth;
-  return _TimeFromYear(y) + ((double)pMonth[m]) * 86400000;
-}
-
-int _Day(double t) {
-  return (int)FXSYS_floor(t / 86400000);
-}
-
-int _YearFromTime(double t) {
-  // estimate the time.
-  int y = 1970 + static_cast<int>(t / (365.2425 * 86400000));
-  if (_TimeFromYear(y) <= t) {
-    while (_TimeFromYear(y + 1) <= t)
-      y++;
-  } else
-    while (_TimeFromYear(y) > t)
-      y--;
-  return y;
-}
-
-int _DayWithinYear(double t) {
-  int year = _YearFromTime(t);
-  int day = _Day(t);
-  return day - _DayFromYear(year);
-}
-
-int _MonthFromTime(double t) {
-  int day = _DayWithinYear(t);
-  int year = _YearFromTime(t);
-  if (0 <= day && day < 31)
-    return 0;
-  if (31 <= day && day < 59 + _isLeapYear(year))
-    return 1;
-  if ((59 + _isLeapYear(year)) <= day && day < (90 + _isLeapYear(year)))
-    return 2;
-  if ((90 + _isLeapYear(year)) <= day && day < (120 + _isLeapYear(year)))
-    return 3;
-  if ((120 + _isLeapYear(year)) <= day && day < (151 + _isLeapYear(year)))
-    return 4;
-  if ((151 + _isLeapYear(year)) <= day && day < (181 + _isLeapYear(year)))
-    return 5;
-  if ((181 + _isLeapYear(year)) <= day && day < (212 + _isLeapYear(year)))
-    return 6;
-  if ((212 + _isLeapYear(year)) <= day && day < (243 + _isLeapYear(year)))
-    return 7;
-  if ((243 + _isLeapYear(year)) <= day && day < (273 + _isLeapYear(year)))
-    return 8;
-  if ((273 + _isLeapYear(year)) <= day && day < (304 + _isLeapYear(year)))
-    return 9;
-  if ((304 + _isLeapYear(year)) <= day && day < (334 + _isLeapYear(year)))
-    return 10;
-  if ((334 + _isLeapYear(year)) <= day && day < (365 + _isLeapYear(year)))
-    return 11;
-
-  return -1;
-}
-
-int _DateFromTime(double t) {
-  int day = _DayWithinYear(t);
-  int year = _YearFromTime(t);
-  bool leap = _isLeapYear(year);
-  int month = _MonthFromTime(t);
-  switch (month) {
-    case 0:
-      return day + 1;
-    case 1:
-      return day - 30;
-    case 2:
-      return day - 58 - leap;
-    case 3:
-      return day - 89 - leap;
-    case 4:
-      return day - 119 - leap;
-    case 5:
-      return day - 150 - leap;
-    case 6:
-      return day - 180 - leap;
-    case 7:
-      return day - 211 - leap;
-    case 8:
-      return day - 242 - leap;
-    case 9:
-      return day - 272 - leap;
-    case 10:
-      return day - 303 - leap;
-    case 11:
-      return day - 333 - leap;
-    default:
-      return 0;
-  }
-}
-
-double JS_GetDateTime() {
-  if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
-    return 0;
-  time_t t = time(NULL);
-  struct tm* pTm = localtime(&t);
-
-  int year = pTm->tm_year + 1900;
-  double t1 = _TimeFromYear(year);
-
-  return t1 + pTm->tm_yday * 86400000.0 + pTm->tm_hour * 3600000.0 +
-         pTm->tm_min * 60000.0 + pTm->tm_sec * 1000.0;
-}
-
-int JS_GetYearFromTime(double dt) {
-  return _YearFromTime(dt);
-}
-
-int JS_GetMonthFromTime(double dt) {
-  return _MonthFromTime(dt);
-}
-
-int JS_GetDayFromTime(double dt) {
-  return _DateFromTime(dt);
-}
-
-int JS_GetHourFromTime(double dt) {
-  return (int)_Mod(FXSYS_floor((double)(dt / (60 * 60 * 1000))), 24);
-}
-
-int JS_GetMinFromTime(double dt) {
-  return (int)_Mod(FXSYS_floor((double)(dt / (60 * 1000))), 60);
-}
-
-int JS_GetSecFromTime(double dt) {
-  return (int)_Mod(FXSYS_floor((double)(dt / 1000)), 60);
-}
-
-double JS_DateParse(const wchar_t* string) {
-  v8::Isolate* pIsolate = v8::Isolate::GetCurrent();
-  v8::Isolate::Scope isolate_scope(pIsolate);
-  v8::HandleScope scope(pIsolate);
-
-  v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
-
-  // Use the built-in object method.
-  v8::Local<v8::Value> v =
-      context->Global()
-          ->Get(context, v8::String::NewFromUtf8(pIsolate, "Date",
-                                                 v8::NewStringType::kNormal)
-                             .ToLocalChecked())
-          .ToLocalChecked();
-  if (v->IsObject()) {
-    v8::Local<v8::Object> o = v->ToObject(context).ToLocalChecked();
-    v = o->Get(context, v8::String::NewFromUtf8(pIsolate, "parse",
-                                                v8::NewStringType::kNormal)
-                            .ToLocalChecked()).ToLocalChecked();
-    if (v->IsFunction()) {
-      v8::Local<v8::Function> funC = v8::Local<v8::Function>::Cast(v);
-
-      const int argc = 1;
-      v8::Local<v8::String> timeStr = FXJS_WSToJSString(pIsolate, string);
-      v8::Local<v8::Value> argv[argc] = {timeStr};
-      v = funC->Call(context, context->Global(), argc, argv).ToLocalChecked();
-      if (v->IsNumber()) {
-        double date = v->ToNumber(context).ToLocalChecked()->Value();
-        if (!_isfinite(date))
-          return date;
-        return date + _getLocalTZA() + _getDaylightSavingTA(date);
-      }
-    }
-  }
-  return 0;
-}
-
-double JS_MakeDay(int nYear, int nMonth, int nDate) {
-  if (!_isfinite(nYear) || !_isfinite(nMonth) || !_isfinite(nDate))
-    return GetNan();
-  double y = _toInteger(nYear);
-  double m = _toInteger(nMonth);
-  double dt = _toInteger(nDate);
-  double ym = y + FXSYS_floor((double)m / 12);
-  double mn = _Mod(m, 12);
-
-  double t = _TimeFromYearMonth((int)ym, (int)mn);
-
-  if (_YearFromTime(t) != ym || _MonthFromTime(t) != mn ||
-      _DateFromTime(t) != 1)
-    return GetNan();
-  return _Day(t) + dt - 1;
-}
-
-double JS_MakeTime(int nHour, int nMin, int nSec, int nMs) {
-  if (!_isfinite(nHour) || !_isfinite(nMin) || !_isfinite(nSec) ||
-      !_isfinite(nMs))
-    return GetNan();
-
-  double h = _toInteger(nHour);
-  double m = _toInteger(nMin);
-  double s = _toInteger(nSec);
-  double milli = _toInteger(nMs);
-
-  return h * 3600000 + m * 60000 + s * 1000 + milli;
-}
-
-double JS_MakeDate(double day, double time) {
-  if (!_isfinite(day) || !_isfinite(time))
-    return GetNan();
-
-  return day * 86400000 + time;
-}
-
-bool JS_PortIsNan(double d) {
-  return d != d;
-}
-
-double JS_LocalTime(double d) {
-  return JS_GetDateTime() + _getDaylightSavingTA(d);
-}
diff --git a/fpdfsdk/src/javascript/JS_Value.h b/fpdfsdk/src/javascript/JS_Value.h
deleted file mode 100644
index 8517b76..0000000
--- a/fpdfsdk/src/javascript/JS_Value.h
+++ /dev/null
@@ -1,211 +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_SRC_JAVASCRIPT_JS_VALUE_H_
-#define FPDFSDK_SRC_JAVASCRIPT_JS_VALUE_H_
-
-#include "core/include/fxcrt/fx_basic.h"
-#include "fpdfsdk/include/jsapi/fxjs_v8.h"
-
-class CJS_Array;
-class CJS_Date;
-class CJS_Document;
-class CJS_Object;
-class CJS_Runtime;
-
-class CJS_Value {
- public:
-  enum Type {
-    VT_unknown,
-    VT_string,
-    VT_number,
-    VT_boolean,
-    VT_date,
-    VT_object,
-    VT_fxobject,
-    VT_null,
-    VT_undefined
-  };
-
-  CJS_Value(CJS_Runtime* pRuntime);
-  CJS_Value(CJS_Runtime* pRuntime, v8::Local<v8::Value> pValue, Type t);
-  CJS_Value(CJS_Runtime* pRuntime, const int& iValue);
-  CJS_Value(CJS_Runtime* pRuntime, const double& dValue);
-  CJS_Value(CJS_Runtime* pRuntime, const float& fValue);
-  CJS_Value(CJS_Runtime* pRuntime, const bool& bValue);
-  CJS_Value(CJS_Runtime* pRuntime, v8::Local<v8::Object>);
-  CJS_Value(CJS_Runtime* pRuntime, CJS_Object*);
-  CJS_Value(CJS_Runtime* pRuntime, CJS_Document*);
-  CJS_Value(CJS_Runtime* pRuntime, const FX_CHAR* pStr);
-  CJS_Value(CJS_Runtime* pRuntime, const FX_WCHAR* pWstr);
-  CJS_Value(CJS_Runtime* pRuntime, CJS_Array& array);
-
-  ~CJS_Value();
-
-  void SetNull();
-  void Attach(v8::Local<v8::Value> pValue, Type t);
-  void Attach(CJS_Value* pValue);
-  void Detach();
-
-  Type GetType() const;
-  int ToInt() const;
-  bool ToBool() const;
-  double ToDouble() const;
-  float ToFloat() const;
-  CJS_Object* ToCJSObject() const;
-  CFX_WideString ToCFXWideString() const;
-  CFX_ByteString ToCFXByteString() const;
-  v8::Local<v8::Object> ToV8Object() const;
-  v8::Local<v8::Array> ToV8Array() const;
-  v8::Local<v8::Value> ToV8Value() const;
-
-  void operator=(int iValue);
-  void operator=(bool bValue);
-  void operator=(double);
-  void operator=(float);
-  void operator=(CJS_Object*);
-  void operator=(CJS_Document*);
-  void operator=(v8::Local<v8::Object>);
-  void operator=(CJS_Array&);
-  void operator=(CJS_Date&);
-  void operator=(const FX_WCHAR* pWstr);
-  void operator=(const FX_CHAR* pStr);
-  void operator=(CJS_Value value);
-
-  FX_BOOL IsArrayObject() const;
-  FX_BOOL IsDateObject() const;
-  FX_BOOL ConvertToArray(CJS_Array&) const;
-  FX_BOOL ConvertToDate(CJS_Date&) const;
-
-  CJS_Runtime* GetJSRuntime() const { return m_pJSRuntime; }
-
- protected:
-  Type m_eType;
-  v8::Local<v8::Value> m_pValue;
-  CJS_Runtime* m_pJSRuntime;
-};
-
-class CJS_PropValue : public CJS_Value {
- public:
-  CJS_PropValue(const CJS_Value&);
-  CJS_PropValue(CJS_Runtime* pRuntime);
-  ~CJS_PropValue();
-
-  FX_BOOL IsSetting() const { return m_bIsSetting; }
-  FX_BOOL IsGetting() const { return !m_bIsSetting; }
-
-  void operator<<(int);
-  void operator>>(int&) const;
-  void operator<<(bool);
-  void operator>>(bool&) const;
-  void operator<<(double);
-  void operator>>(double&) const;
-  void operator<<(CJS_Object* pObj);
-  void operator>>(CJS_Object*& ppObj) const;
-  void operator<<(CJS_Document* pJsDoc);
-  void operator>>(CJS_Document*& ppJsDoc) const;
-  void operator<<(CFX_ByteString);
-  void operator>>(CFX_ByteString&) const;
-  void operator<<(CFX_WideString);
-  void operator>>(CFX_WideString&) const;
-  void operator<<(const FX_WCHAR* c_string);
-  void operator<<(v8::Local<v8::Object>);
-  void operator>>(v8::Local<v8::Object>&) const;
-  void operator>>(CJS_Array& array) const;
-  void operator<<(CJS_Array& array);
-  void operator<<(CJS_Date& date);
-  void operator>>(CJS_Date& date) const;
-  operator v8::Local<v8::Value>() const;
-  void StartSetting();
-  void StartGetting();
-
- private:
-  FX_BOOL m_bIsSetting;
-};
-
-class CJS_Array {
- public:
-  CJS_Array(CJS_Runtime* pRuntime);
-  virtual ~CJS_Array();
-
-  void Attach(v8::Local<v8::Array> pArray);
-  void GetElement(unsigned index, CJS_Value& value);
-  void SetElement(unsigned index, CJS_Value value);
-  int GetLength();
-  FX_BOOL IsAttached();
-  operator v8::Local<v8::Array>();
-
-  CJS_Runtime* GetJSRuntime() const { return m_pJSRuntime; }
-
- private:
-  v8::Local<v8::Array> m_pArray;
-  CJS_Runtime* m_pJSRuntime;
-};
-
-class CJS_Date {
-  friend class CJS_Value;
-
- public:
-  CJS_Date(CJS_Runtime* pRuntime);
-  CJS_Date(CJS_Runtime* pRuntime, double dMsec_time);
-  CJS_Date(CJS_Runtime* pRuntime,
-           int year,
-           int mon,
-           int day,
-           int hour,
-           int min,
-           int sec);
-  virtual ~CJS_Date();
-  void Attach(v8::Local<v8::Value> pDate);
-
-  int GetYear();
-  void SetYear(int iYear);
-
-  int GetMonth();
-  void SetMonth(int iMonth);
-
-  int GetDay();
-  void SetDay(int iDay);
-
-  int GetHours();
-  void SetHours(int iHours);
-
-  int GetMinutes();
-  void SetMinutes(int minutes);
-
-  int GetSeconds();
-  void SetSeconds(int seconds);
-
-  operator v8::Local<v8::Value>();
-  operator double() const;
-
-  CFX_WideString ToString() const;
-
-  static double
-  MakeDate(int year, int mon, int mday, int hour, int min, int sec, int ms);
-
-  FX_BOOL IsValidDate();
-
- protected:
-  v8::Local<v8::Value> m_pDate;
-  CJS_Runtime* m_pJSRuntime;
-};
-
-double JS_GetDateTime();
-int JS_GetYearFromTime(double dt);
-int JS_GetMonthFromTime(double dt);
-int JS_GetDayFromTime(double dt);
-int JS_GetHourFromTime(double dt);
-int JS_GetMinFromTime(double dt);
-int JS_GetSecFromTime(double dt);
-double JS_DateParse(const wchar_t* string);
-double JS_MakeDay(int nYear, int nMonth, int nDay);
-double JS_MakeTime(int nHour, int nMin, int nSec, int nMs);
-double JS_MakeDate(double day, double time);
-bool JS_PortIsNan(double d);
-double JS_LocalTime(double d);
-
-#endif  // FPDFSDK_SRC_JAVASCRIPT_JS_VALUE_H_
diff --git a/fpdfsdk/src/javascript/PublicMethods.cpp b/fpdfsdk/src/javascript/PublicMethods.cpp
deleted file mode 100644
index d2f7fb0..0000000
--- a/fpdfsdk/src/javascript/PublicMethods.cpp
+++ /dev/null
@@ -1,2067 +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
-
-#include "PublicMethods.h"
-
-#include <algorithm>
-
-#include "Field.h"
-#include "JS_Context.h"
-#include "JS_Define.h"
-#include "JS_EventHandler.h"
-#include "JS_Object.h"
-#include "JS_Runtime.h"
-#include "JS_Value.h"
-#include "color.h"
-#include "core/include/fxcrt/fx_ext.h"
-#include "fpdfsdk/include/fsdk_mgr.h"  // For CPDFDoc_Environment.
-#include "fpdfsdk/include/javascript/IJavaScript.h"
-#include "resource.h"
-#include "util.h"
-
-#define DOUBLE_CORRECT 0.000000000000001
-
-BEGIN_JS_STATIC_GLOBAL_FUN(CJS_PublicMethods)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFNumber_Format)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFNumber_Keystroke)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFPercent_Format)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFPercent_Keystroke)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_FormatEx)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_KeystrokeEx)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_Format)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_Keystroke)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_FormatEx)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_KeystrokeEx)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_Format)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_Keystroke)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_Format)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_Keystroke)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_KeystrokeEx)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFSimple)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFMakeNumber)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFSimple_Calculate)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFRange_Validate)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFMergeChange)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFParseDateEx)
-JS_STATIC_GLOBAL_FUN_ENTRY(AFExtractNums)
-END_JS_STATIC_GLOBAL_FUN()
-
-IMPLEMENT_JS_STATIC_GLOBAL_FUN(CJS_PublicMethods)
-
-static const FX_WCHAR* const months[] = {L"Jan",
-                                         L"Feb",
-                                         L"Mar",
-                                         L"Apr",
-                                         L"May",
-                                         L"Jun",
-                                         L"Jul",
-                                         L"Aug",
-                                         L"Sep",
-                                         L"Oct",
-                                         L"Nov",
-                                         L"Dec"};
-
-static const FX_WCHAR* const fullmonths[] = {L"January",
-                                             L"February",
-                                             L"March",
-                                             L"April",
-                                             L"May",
-                                             L"June",
-                                             L"July",
-                                             L"August",
-                                             L"September",
-                                             L"October",
-                                             L"November",
-                                             L"December"};
-
-FX_BOOL CJS_PublicMethods::IsNumber(const FX_WCHAR* string) {
-  CFX_WideString sTrim = StrTrim(string);
-  const FX_WCHAR* pTrim = sTrim.c_str();
-  const FX_WCHAR* p = pTrim;
-
-  FX_BOOL bDot = FALSE;
-  FX_BOOL bKXJS = FALSE;
-
-  wchar_t c;
-  while ((c = *p)) {
-    if (c == '.' || c == ',') {
-      if (bDot)
-        return FALSE;
-      bDot = TRUE;
-    } else if (c == '-' || c == '+') {
-      if (p != pTrim)
-        return FALSE;
-    } else if (c == 'e' || c == 'E') {
-      if (bKXJS)
-        return FALSE;
-
-      p++;
-      c = *p;
-      if (c == '+' || c == '-') {
-        bKXJS = TRUE;
-      } else {
-        return FALSE;
-      }
-    } else if (!FXSYS_iswdigit(c)) {
-      return FALSE;
-    }
-    p++;
-  }
-
-  return TRUE;
-}
-
-FX_BOOL CJS_PublicMethods::maskSatisfied(wchar_t c_Change, wchar_t c_Mask) {
-  switch (c_Mask) {
-    case L'9':
-      return FXSYS_iswdigit(c_Change);
-    case L'A':
-      return FXSYS_iswalpha(c_Change);
-    case L'O':
-      return FXSYS_iswalnum(c_Change);
-    case L'X':
-      return TRUE;
-    default:
-      return (c_Change == c_Mask);
-  }
-}
-
-FX_BOOL CJS_PublicMethods::isReservedMaskChar(wchar_t ch) {
-  return ch == L'9' || ch == L'A' || ch == L'O' || ch == L'X';
-}
-
-double CJS_PublicMethods::AF_Simple(const FX_WCHAR* sFuction,
-                                    double dValue1,
-                                    double dValue2) {
-  if (FXSYS_wcsicmp(sFuction, L"AVG") == 0 ||
-      FXSYS_wcsicmp(sFuction, L"SUM") == 0) {
-    return dValue1 + dValue2;
-  }
-  if (FXSYS_wcsicmp(sFuction, L"PRD") == 0) {
-    return dValue1 * dValue2;
-  }
-  if (FXSYS_wcsicmp(sFuction, L"MIN") == 0) {
-    return std::min(dValue1, dValue2);
-  }
-  if (FXSYS_wcsicmp(sFuction, L"MAX") == 0) {
-    return std::max(dValue1, dValue2);
-  }
-  return dValue1;
-}
-
-CFX_WideString CJS_PublicMethods::StrLTrim(const FX_WCHAR* pStr) {
-  while (*pStr && *pStr == L' ')
-    pStr++;
-
-  return pStr;
-}
-
-CFX_WideString CJS_PublicMethods::StrRTrim(const FX_WCHAR* pStr) {
-  const FX_WCHAR* p = pStr;
-  while (*p)
-    p++;
-  while (p > pStr && *(p - 1) == L' ')
-    p--;
-
-  return CFX_WideString(pStr, p - pStr);
-}
-
-CFX_WideString CJS_PublicMethods::StrTrim(const FX_WCHAR* pStr) {
-  return StrRTrim(StrLTrim(pStr).c_str());
-}
-
-CFX_ByteString CJS_PublicMethods::StrLTrim(const FX_CHAR* pStr) {
-  while (*pStr && *pStr == ' ')
-    pStr++;
-
-  return pStr;
-}
-
-CFX_ByteString CJS_PublicMethods::StrRTrim(const FX_CHAR* pStr) {
-  const FX_CHAR* p = pStr;
-  while (*p)
-    p++;
-  while (p > pStr && *(p - 1) == L' ')
-    p--;
-
-  return CFX_ByteString(pStr, p - pStr);
-}
-
-CFX_ByteString CJS_PublicMethods::StrTrim(const FX_CHAR* pStr) {
-  return StrRTrim(StrLTrim(pStr));
-}
-
-double CJS_PublicMethods::ParseNumber(const FX_WCHAR* swSource,
-                                      FX_BOOL& bAllDigits,
-                                      FX_BOOL& bDot,
-                                      FX_BOOL& bSign,
-                                      FX_BOOL& bKXJS) {
-  bDot = FALSE;
-  bSign = FALSE;
-  bKXJS = FALSE;
-
-  FX_BOOL bDigitExist = FALSE;
-
-  const FX_WCHAR* p = swSource;
-  wchar_t c;
-
-  const FX_WCHAR* pStart = NULL;
-  const FX_WCHAR* pEnd = NULL;
-
-  while ((c = *p)) {
-    if (!pStart && c != L' ') {
-      pStart = p;
-    }
-
-    pEnd = p;
-    p++;
-  }
-
-  if (!pStart) {
-    bAllDigits = FALSE;
-    return 0;
-  }
-
-  while (pEnd != pStart) {
-    if (*pEnd == L' ')
-      pEnd--;
-    else
-      break;
-  }
-
-  double dRet = 0;
-  p = pStart;
-  bAllDigits = TRUE;
-  CFX_WideString swDigits;
-
-  while (p <= pEnd) {
-    c = *p;
-
-    if (FXSYS_iswdigit(c)) {
-      swDigits += c;
-      bDigitExist = TRUE;
-    } else {
-      switch (c) {
-        case L' ':
-          bAllDigits = FALSE;
-          break;
-        case L'.':
-        case L',':
-          if (!bDot) {
-            if (bDigitExist) {
-              swDigits += L'.';
-            } else {
-              swDigits += L'0';
-              swDigits += L'.';
-              bDigitExist = TRUE;
-            }
-
-            bDot = TRUE;
-            break;
-          }
-        case 'e':
-        case 'E':
-          if (!bKXJS) {
-            p++;
-            c = *p;
-            if (c == '+' || c == '-') {
-              bKXJS = TRUE;
-              swDigits += 'e';
-              swDigits += c;
-            }
-            break;
-          }
-        case L'-':
-          if (!bDigitExist && !bSign) {
-            swDigits += c;
-            bSign = TRUE;
-            break;
-          }
-        default:
-          bAllDigits = FALSE;
-
-          if (p != pStart && !bDot && bDigitExist) {
-            swDigits += L'.';
-            bDot = TRUE;
-          } else {
-            bDot = FALSE;
-            bDigitExist = FALSE;
-            swDigits = L"";
-          }
-          break;
-      }
-    }
-
-    p++;
-  }
-
-  if (swDigits.GetLength() > 0 && swDigits.GetLength() < 17) {
-    CFX_ByteString sDigits = swDigits.UTF8Encode();
-
-    if (bKXJS) {
-      dRet = atof(sDigits);
-    } else {
-      if (bDot) {
-        char* pStopString;
-        dRet = ::strtod(sDigits, &pStopString);
-      } else {
-        dRet = atol(sDigits);
-      }
-    }
-  }
-
-  return dRet;
-}
-
-double CJS_PublicMethods::ParseStringToNumber(const FX_WCHAR* swSource) {
-  FX_BOOL bAllDigits = FALSE;
-  FX_BOOL bDot = FALSE;
-  FX_BOOL bSign = FALSE;
-  FX_BOOL bKXJS = FALSE;
-
-  return ParseNumber(swSource, bAllDigits, bDot, bSign, bKXJS);
-}
-
-FX_BOOL CJS_PublicMethods::ConvertStringToNumber(const FX_WCHAR* swSource,
-                                                 double& dRet,
-                                                 FX_BOOL& bDot) {
-  FX_BOOL bAllDigits = FALSE;
-  FX_BOOL bSign = FALSE;
-  FX_BOOL bKXJS = FALSE;
-
-  dRet = ParseNumber(swSource, bAllDigits, bDot, bSign, bKXJS);
-
-  return bAllDigits;
-}
-
-CJS_Array CJS_PublicMethods::AF_MakeArrayFromList(CJS_Runtime* pRuntime,
-                                                  CJS_Value val) {
-  CJS_Array StrArray(pRuntime);
-  if (val.IsArrayObject()) {
-    val.ConvertToArray(StrArray);
-    return StrArray;
-  }
-  CFX_WideString wsStr = val.ToCFXWideString();
-  CFX_ByteString t = CFX_ByteString::FromUnicode(wsStr);
-  const char* p = (const char*)t;
-
-  int ch = ',';
-  int nIndex = 0;
-
-  while (*p) {
-    const char* pTemp = strchr(p, ch);
-    if (!pTemp) {
-      StrArray.SetElement(nIndex, CJS_Value(pRuntime, StrTrim(p).c_str()));
-      break;
-    }
-
-    char* pSub = new char[pTemp - p + 1];
-    strncpy(pSub, p, pTemp - p);
-    *(pSub + (pTemp - p)) = '\0';
-
-    StrArray.SetElement(nIndex, CJS_Value(pRuntime, StrTrim(pSub).c_str()));
-    delete[] pSub;
-
-    nIndex++;
-    p = ++pTemp;
-  }
-  return StrArray;
-}
-
-int CJS_PublicMethods::ParseStringInteger(const CFX_WideString& string,
-                                          int nStart,
-                                          int& nSkip,
-                                          int nMaxStep) {
-  int nRet = 0;
-  nSkip = 0;
-  for (int i = nStart, sz = string.GetLength(); i < sz; i++) {
-    if (i - nStart > 10)
-      break;
-
-    FX_WCHAR c = string.GetAt(i);
-    if (!FXSYS_iswdigit(c))
-      break;
-
-    nRet = nRet * 10 + FXSYS_toDecimalDigitWide(c);
-    nSkip = i - nStart + 1;
-    if (nSkip >= nMaxStep)
-      break;
-  }
-
-  return nRet;
-}
-
-CFX_WideString CJS_PublicMethods::ParseStringString(
-    const CFX_WideString& string,
-    int nStart,
-    int& nSkip) {
-  CFX_WideString swRet;
-  nSkip = 0;
-  for (int i = nStart, sz = string.GetLength(); i < sz; i++) {
-    FX_WCHAR c = string.GetAt(i);
-    if (!FXSYS_iswdigit(c))
-      break;
-
-    swRet += c;
-    nSkip = i - nStart + 1;
-  }
-
-  return swRet;
-}
-
-double CJS_PublicMethods::ParseNormalDate(const CFX_WideString& value,
-                                          bool* bWrongFormat) {
-  double dt = JS_GetDateTime();
-
-  int nYear = JS_GetYearFromTime(dt);
-  int nMonth = JS_GetMonthFromTime(dt) + 1;
-  int nDay = JS_GetDayFromTime(dt);
-  int nHour = JS_GetHourFromTime(dt);
-  int nMin = JS_GetMinFromTime(dt);
-  int nSec = JS_GetSecFromTime(dt);
-
-  int number[3];
-
-  int nSkip = 0;
-  int nLen = value.GetLength();
-  int nIndex = 0;
-  int i = 0;
-  while (i < nLen) {
-    if (nIndex > 2)
-      break;
-
-    FX_WCHAR c = value.GetAt(i);
-    if (FXSYS_iswdigit(c)) {
-      number[nIndex++] = ParseStringInteger(value, i, nSkip, 4);
-      i += nSkip;
-    } else {
-      i++;
-    }
-  }
-
-  if (nIndex == 2) {
-    // case2: month/day
-    // case3: day/month
-    if ((number[0] >= 1 && number[0] <= 12) &&
-        (number[1] >= 1 && number[1] <= 31)) {
-      nMonth = number[0];
-      nDay = number[1];
-    } else if ((number[0] >= 1 && number[0] <= 31) &&
-               (number[1] >= 1 && number[1] <= 12)) {
-      nDay = number[0];
-      nMonth = number[1];
-    }
-
-    if (bWrongFormat)
-      *bWrongFormat = false;
-  } else if (nIndex == 3) {
-    // case1: year/month/day
-    // case2: month/day/year
-    // case3: day/month/year
-
-    if (number[0] > 12 && (number[1] >= 1 && number[1] <= 12) &&
-        (number[2] >= 1 && number[2] <= 31)) {
-      nYear = number[0];
-      nMonth = number[1];
-      nDay = number[2];
-    } else if ((number[0] >= 1 && number[0] <= 12) &&
-               (number[1] >= 1 && number[1] <= 31) && number[2] > 31) {
-      nMonth = number[0];
-      nDay = number[1];
-      nYear = number[2];
-    } else if ((number[0] >= 1 && number[0] <= 31) &&
-               (number[1] >= 1 && number[1] <= 12) && number[2] > 31) {
-      nDay = number[0];
-      nMonth = number[1];
-      nYear = number[2];
-    }
-
-    if (bWrongFormat)
-      *bWrongFormat = false;
-  } else {
-    if (bWrongFormat)
-      *bWrongFormat = true;
-    return dt;
-  }
-
-  CFX_WideString swTemp;
-  swTemp.Format(L"%d/%d/%d %d:%d:%d", nMonth, nDay, nYear, nHour, nMin, nSec);
-  return JS_DateParse(swTemp.c_str());
-}
-
-double CJS_PublicMethods::MakeRegularDate(const CFX_WideString& value,
-                                          const CFX_WideString& format,
-                                          bool* bWrongFormat) {
-  double dt = JS_GetDateTime();
-
-  if (format.IsEmpty() || value.IsEmpty())
-    return dt;
-
-  int nYear = JS_GetYearFromTime(dt);
-  int nMonth = JS_GetMonthFromTime(dt) + 1;
-  int nDay = JS_GetDayFromTime(dt);
-  int nHour = JS_GetHourFromTime(dt);
-  int nMin = JS_GetMinFromTime(dt);
-  int nSec = JS_GetSecFromTime(dt);
-
-  int nYearSub = 99;  // nYear - 2000;
-
-  FX_BOOL bPm = FALSE;
-  FX_BOOL bExit = FALSE;
-  bool bBadFormat = false;
-
-  int i = 0;
-  int j = 0;
-
-  while (i < format.GetLength()) {
-    if (bExit)
-      break;
-
-    FX_WCHAR c = format.GetAt(i);
-    switch (c) {
-      case ':':
-      case '.':
-      case '-':
-      case '\\':
-      case '/':
-        i++;
-        j++;
-        break;
-
-      case 'y':
-      case 'm':
-      case 'd':
-      case 'H':
-      case 'h':
-      case 'M':
-      case 's':
-      case 't': {
-        int oldj = j;
-        int nSkip = 0;
-        int remaining = format.GetLength() - i - 1;
-
-        if (remaining == 0 || format.GetAt(i + 1) != c) {
-          switch (c) {
-            case 'y':
-              i++;
-              j++;
-              break;
-            case 'm':
-              nMonth = ParseStringInteger(value, j, nSkip, 2);
-              i++;
-              j += nSkip;
-              break;
-            case 'd':
-              nDay = ParseStringInteger(value, j, nSkip, 2);
-              i++;
-              j += nSkip;
-              break;
-            case 'H':
-              nHour = ParseStringInteger(value, j, nSkip, 2);
-              i++;
-              j += nSkip;
-              break;
-            case 'h':
-              nHour = ParseStringInteger(value, j, nSkip, 2);
-              i++;
-              j += nSkip;
-              break;
-            case 'M':
-              nMin = ParseStringInteger(value, j, nSkip, 2);
-              i++;
-              j += nSkip;
-              break;
-            case 's':
-              nSec = ParseStringInteger(value, j, nSkip, 2);
-              i++;
-              j += nSkip;
-              break;
-            case 't':
-              bPm = (j < value.GetLength() && value.GetAt(j) == 'p');
-              i++;
-              j++;
-              break;
-          }
-        } else if (remaining == 1 || format.GetAt(i + 2) != c) {
-          switch (c) {
-            case 'y':
-              nYear = ParseStringInteger(value, j, nSkip, 4);
-              i += 2;
-              j += nSkip;
-              break;
-            case 'm':
-              nMonth = ParseStringInteger(value, j, nSkip, 2);
-              i += 2;
-              j += nSkip;
-              break;
-            case 'd':
-              nDay = ParseStringInteger(value, j, nSkip, 2);
-              i += 2;
-              j += nSkip;
-              break;
-            case 'H':
-              nHour = ParseStringInteger(value, j, nSkip, 2);
-              i += 2;
-              j += nSkip;
-              break;
-            case 'h':
-              nHour = ParseStringInteger(value, j, nSkip, 2);
-              i += 2;
-              j += nSkip;
-              break;
-            case 'M':
-              nMin = ParseStringInteger(value, j, nSkip, 2);
-              i += 2;
-              j += nSkip;
-              break;
-            case 's':
-              nSec = ParseStringInteger(value, j, nSkip, 2);
-              i += 2;
-              j += nSkip;
-              break;
-            case 't':
-              bPm = (j + 1 < value.GetLength() && value.GetAt(j) == 'p' &&
-                     value.GetAt(j + 1) == 'm');
-              i += 2;
-              j += 2;
-              break;
-          }
-        } else if (remaining == 2 || format.GetAt(i + 3) != c) {
-          switch (c) {
-            case 'm': {
-              CFX_WideString sMonth = ParseStringString(value, j, nSkip);
-              FX_BOOL bFind = FALSE;
-              for (int m = 0; m < 12; m++) {
-                if (sMonth.CompareNoCase(months[m]) == 0) {
-                  nMonth = m + 1;
-                  i += 3;
-                  j += nSkip;
-                  bFind = TRUE;
-                  break;
-                }
-              }
-
-              if (!bFind) {
-                nMonth = ParseStringInteger(value, j, nSkip, 3);
-                i += 3;
-                j += nSkip;
-              }
-            } break;
-            case 'y':
-              break;
-            default:
-              i += 3;
-              j += 3;
-              break;
-          }
-        } else if (remaining == 3 || format.GetAt(i + 4) != c) {
-          switch (c) {
-            case 'y':
-              nYear = ParseStringInteger(value, j, nSkip, 4);
-              j += nSkip;
-              i += 4;
-              break;
-            case 'm': {
-              FX_BOOL bFind = FALSE;
-
-              CFX_WideString sMonth = ParseStringString(value, j, nSkip);
-              sMonth.MakeLower();
-
-              for (int m = 0; m < 12; m++) {
-                CFX_WideString sFullMonths = fullmonths[m];
-                sFullMonths.MakeLower();
-
-                if (sFullMonths.Find(sMonth.c_str(), 0) != -1) {
-                  nMonth = m + 1;
-                  i += 4;
-                  j += nSkip;
-                  bFind = TRUE;
-                  break;
-                }
-              }
-
-              if (!bFind) {
-                nMonth = ParseStringInteger(value, j, nSkip, 4);
-                i += 4;
-                j += nSkip;
-              }
-            } break;
-            default:
-              i += 4;
-              j += 4;
-              break;
-          }
-        } else {
-          if (j >= value.GetLength() || format.GetAt(i) != value.GetAt(j)) {
-            bBadFormat = true;
-            bExit = TRUE;
-          }
-          i++;
-          j++;
-        }
-
-        if (oldj == j) {
-          bBadFormat = true;
-          bExit = TRUE;
-        }
-      }
-
-      break;
-      default:
-        if (value.GetLength() <= j) {
-          bExit = TRUE;
-        } else if (format.GetAt(i) != value.GetAt(j)) {
-          bBadFormat = true;
-          bExit = TRUE;
-        }
-
-        i++;
-        j++;
-        break;
-    }
-  }
-
-  if (bPm)
-    nHour += 12;
-
-  if (nYear >= 0 && nYear <= nYearSub)
-    nYear += 2000;
-
-  if (nMonth < 1 || nMonth > 12)
-    bBadFormat = true;
-
-  if (nDay < 1 || nDay > 31)
-    bBadFormat = true;
-
-  if (nHour < 0 || nHour > 24)
-    bBadFormat = true;
-
-  if (nMin < 0 || nMin > 60)
-    bBadFormat = true;
-
-  if (nSec < 0 || nSec > 60)
-    bBadFormat = true;
-
-  double dRet = 0;
-
-  if (bBadFormat) {
-    dRet = ParseNormalDate(value, &bBadFormat);
-  } else {
-    dRet = JS_MakeDate(JS_MakeDay(nYear, nMonth - 1, nDay),
-                       JS_MakeTime(nHour, nMin, nSec, 0));
-
-    if (JS_PortIsNan(dRet)) {
-      dRet = JS_DateParse(value.c_str());
-    }
-  }
-
-  if (JS_PortIsNan(dRet)) {
-    dRet = ParseNormalDate(value, &bBadFormat);
-  }
-
-  if (bWrongFormat)
-    *bWrongFormat = bBadFormat;
-  return dRet;
-}
-
-CFX_WideString CJS_PublicMethods::MakeFormatDate(double dDate,
-                                                 const CFX_WideString& format) {
-  CFX_WideString sRet = L"", sPart = L"";
-
-  int nYear = JS_GetYearFromTime(dDate);
-  int nMonth = JS_GetMonthFromTime(dDate) + 1;
-  int nDay = JS_GetDayFromTime(dDate);
-  int nHour = JS_GetHourFromTime(dDate);
-  int nMin = JS_GetMinFromTime(dDate);
-  int nSec = JS_GetSecFromTime(dDate);
-
-  int i = 0;
-  while (i < format.GetLength()) {
-    FX_WCHAR c = format.GetAt(i);
-    int remaining = format.GetLength() - i - 1;
-    sPart = L"";
-    switch (c) {
-      case 'y':
-      case 'm':
-      case 'd':
-      case 'H':
-      case 'h':
-      case 'M':
-      case 's':
-      case 't':
-        if (remaining == 0 || format.GetAt(i + 1) != c) {
-          switch (c) {
-            case 'y':
-              sPart += c;
-              break;
-            case 'm':
-              sPart.Format(L"%d", nMonth);
-              break;
-            case 'd':
-              sPart.Format(L"%d", nDay);
-              break;
-            case 'H':
-              sPart.Format(L"%d", nHour);
-              break;
-            case 'h':
-              sPart.Format(L"%d", nHour > 12 ? nHour - 12 : nHour);
-              break;
-            case 'M':
-              sPart.Format(L"%d", nMin);
-              break;
-            case 's':
-              sPart.Format(L"%d", nSec);
-              break;
-            case 't':
-              sPart += nHour > 12 ? 'p' : 'a';
-              break;
-          }
-          i++;
-        } else if (remaining == 1 || format.GetAt(i + 2) != c) {
-          switch (c) {
-            case 'y':
-              sPart.Format(L"%02d", nYear - (nYear / 100) * 100);
-              break;
-            case 'm':
-              sPart.Format(L"%02d", nMonth);
-              break;
-            case 'd':
-              sPart.Format(L"%02d", nDay);
-              break;
-            case 'H':
-              sPart.Format(L"%02d", nHour);
-              break;
-            case 'h':
-              sPart.Format(L"%02d", nHour > 12 ? nHour - 12 : nHour);
-              break;
-            case 'M':
-              sPart.Format(L"%02d", nMin);
-              break;
-            case 's':
-              sPart.Format(L"%02d", nSec);
-              break;
-            case 't':
-              sPart = nHour > 12 ? L"pm" : L"am";
-              break;
-          }
-          i += 2;
-        } else if (remaining == 2 || format.GetAt(i + 3) != c) {
-          switch (c) {
-            case 'm':
-              i += 3;
-              if (nMonth > 0 && nMonth <= 12)
-                sPart += months[nMonth - 1];
-              break;
-            default:
-              i += 3;
-              sPart += c;
-              sPart += c;
-              sPart += c;
-              break;
-          }
-        } else if (remaining == 3 || format.GetAt(i + 4) != c) {
-          switch (c) {
-            case 'y':
-              sPart.Format(L"%04d", nYear);
-              i += 4;
-              break;
-            case 'm':
-              i += 4;
-              if (nMonth > 0 && nMonth <= 12)
-                sPart += fullmonths[nMonth - 1];
-              break;
-            default:
-              i += 4;
-              sPart += c;
-              sPart += c;
-              sPart += c;
-              sPart += c;
-              break;
-          }
-        } else {
-          i++;
-          sPart += c;
-        }
-        break;
-      default:
-        i++;
-        sPart += c;
-        break;
-    }
-
-    sRet += sPart;
-  }
-
-  return sRet;
-}
-
-/* -------------------------------------------------------------------------- */
-
-// function AFNumber_Format(nDec, sepStyle, negStyle, currStyle, strCurrency,
-// bCurrencyPrepend)
-FX_BOOL CJS_PublicMethods::AFNumber_Format(IJS_Context* cc,
-                                           const std::vector<CJS_Value>& params,
-                                           CJS_Value& vRet,
-                                           CFX_WideString& sError) {
-#if _FX_OS_ != _FX_ANDROID_
-  CJS_Context* pContext = (CJS_Context*)cc;
-  if (params.size() != 6) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
-    return FALSE;
-  }
-
-  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
-  CJS_EventHandler* pEvent = pContext->GetEventHandler();
-  if (!pEvent->m_pValue)
-    return FALSE;
-
-  CFX_WideString& Value = pEvent->Value();
-  CFX_ByteString strValue = StrTrim(CFX_ByteString::FromUnicode(Value));
-  if (strValue.IsEmpty())
-    return TRUE;
-
-  int iDec = params[0].ToInt();
-  int iSepStyle = params[1].ToInt();
-  int iNegStyle = params[2].ToInt();
-  // params[3] is iCurrStyle, it's not used.
-  std::wstring wstrCurrency(params[4].ToCFXWideString().c_str());
-  FX_BOOL bCurrencyPrepend = params[5].ToBool();
-
-  if (iDec < 0)
-    iDec = -iDec;
-
-  if (iSepStyle < 0 || iSepStyle > 3)
-    iSepStyle = 0;
-
-  if (iNegStyle < 0 || iNegStyle > 3)
-    iNegStyle = 0;
-
-  //////////////////////////////////////////////////////
-  // for processing decimal places
-  strValue.Replace(",", ".");
-  double dValue = atof(strValue);
-  if (iDec > 0)
-    dValue += DOUBLE_CORRECT;
-
-  int iDec2;
-  int iNegative = 0;
-
-  strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
-  if (strValue.IsEmpty()) {
-    dValue = 0;
-    strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
-    if (strValue.IsEmpty()) {
-      strValue = "0";
-      iDec2 = 1;
-    }
-  }
-
-  if (iDec2 < 0) {
-    for (int iNum = 0; iNum < abs(iDec2); iNum++) {
-      strValue = "0" + strValue;
-    }
-    iDec2 = 0;
-  }
-  int iMax = strValue.GetLength();
-  if (iDec2 > iMax) {
-    for (int iNum = 0; iNum <= iDec2 - iMax; iNum++) {
-      strValue += "0";
-    }
-    iMax = iDec2 + 1;
-  }
-  ///////////////////////////////////////////////////////
-  // for processing seperator style
-  if (iDec2 < iMax) {
-    if (iSepStyle == 0 || iSepStyle == 1) {
-      strValue.Insert(iDec2, '.');
-      iMax++;
-    } else if (iSepStyle == 2 || iSepStyle == 3) {
-      strValue.Insert(iDec2, ',');
-      iMax++;
-    }
-
-    if (iDec2 == 0)
-      strValue.Insert(iDec2, '0');
-  }
-  if (iSepStyle == 0 || iSepStyle == 2) {
-    char cSeperator;
-    if (iSepStyle == 0)
-      cSeperator = ',';
-    else
-      cSeperator = '.';
-
-    for (int iDecPositive = iDec2 - 3; iDecPositive > 0; iDecPositive -= 3) {
-      strValue.Insert(iDecPositive, cSeperator);
-      iMax++;
-    }
-  }
-
-  //////////////////////////////////////////////////////////////////////
-  // for processing currency string
-
-  Value = CFX_WideString::FromLocal(strValue);
-  std::wstring strValue2 = Value.c_str();
-
-  if (bCurrencyPrepend)
-    strValue2 = wstrCurrency + strValue2;
-  else
-    strValue2 = strValue2 + wstrCurrency;
-
-  /////////////////////////////////////////////////////////////////////////
-  // for processing negative style
-  if (iNegative) {
-    if (iNegStyle == 0) {
-      strValue2.insert(0, L"-");
-    }
-    if (iNegStyle == 2 || iNegStyle == 3) {
-      strValue2.insert(0, L"(");
-      strValue2.insert(strValue2.length(), L")");
-    }
-    if (iNegStyle == 1 || iNegStyle == 3) {
-      if (Field* fTarget = pEvent->Target_Field()) {
-        CJS_Array arColor(pRuntime);
-        CJS_Value vColElm(pRuntime);
-        vColElm = L"RGB";
-        arColor.SetElement(0, vColElm);
-        vColElm = 1;
-        arColor.SetElement(1, vColElm);
-        vColElm = 0;
-        arColor.SetElement(2, vColElm);
-
-        arColor.SetElement(3, vColElm);
-
-        CJS_PropValue vProp(pRuntime);
-        vProp.StartGetting();
-        vProp << arColor;
-        vProp.StartSetting();
-        fTarget->textColor(cc, vProp, sError);  // red
-      }
-    }
-  } else {
-    if (iNegStyle == 1 || iNegStyle == 3) {
-      if (Field* fTarget = pEvent->Target_Field()) {
-        CJS_Array arColor(pRuntime);
-        CJS_Value vColElm(pRuntime);
-        vColElm = L"RGB";
-        arColor.SetElement(0, vColElm);
-        vColElm = 0;
-        arColor.SetElement(1, vColElm);
-        arColor.SetElement(2, vColElm);
-        arColor.SetElement(3, vColElm);
-
-        CJS_PropValue vProp(pRuntime);
-        vProp.StartGetting();
-        fTarget->textColor(cc, vProp, sError);
-
-        CJS_Array aProp(pRuntime);
-        vProp.ConvertToArray(aProp);
-
-        CPWL_Color crProp;
-        CPWL_Color crColor;
-        color::ConvertArrayToPWLColor(aProp, crProp);
-        color::ConvertArrayToPWLColor(arColor, crColor);
-
-        if (crColor != crProp) {
-          CJS_PropValue vProp2(pRuntime);
-          vProp2.StartGetting();
-          vProp2 << arColor;
-          vProp2.StartSetting();
-          fTarget->textColor(cc, vProp2, sError);
-        }
-      }
-    }
-  }
-  Value = strValue2.c_str();
-#endif
-  return TRUE;
-}
-
-// function AFNumber_Keystroke(nDec, sepStyle, negStyle, currStyle, strCurrency,
-// bCurrencyPrepend)
-FX_BOOL CJS_PublicMethods::AFNumber_Keystroke(
-    IJS_Context* cc,
-    const std::vector<CJS_Value>& params,
-    CJS_Value& vRet,
-    CFX_WideString& sError) {
-  CJS_Context* pContext = (CJS_Context*)cc;
-  CJS_EventHandler* pEvent = pContext->GetEventHandler();
-
-  if (params.size() < 2)
-    return FALSE;
-  int iSepStyle = params[1].ToInt();
-
-  if (iSepStyle < 0 || iSepStyle > 3)
-    iSepStyle = 0;
-  if (!pEvent->m_pValue)
-    return FALSE;
-  CFX_WideString& val = pEvent->Value();
-  CFX_WideString& w_strChange = pEvent->Change();
-  CFX_WideString w_strValue = val;
-
-  if (pEvent->WillCommit()) {
-    CFX_WideString wstrChange = w_strChange;
-    CFX_WideString wstrValue = StrLTrim(w_strValue.c_str());
-    if (wstrValue.IsEmpty())
-      return TRUE;
-
-    CFX_WideString swTemp = wstrValue;
-    swTemp.Replace(L",", L".");
-    if (!IsNumber(swTemp.c_str())) {
-      pEvent->Rc() = FALSE;
-      sError = JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE);
-      Alert(pContext, sError.c_str());
-      return TRUE;
-    }
-    return TRUE;  // it happens after the last keystroke and before validating,
-  }
-
-  std::wstring w_strValue2 = w_strValue.c_str();
-  std::wstring w_strChange2 = w_strChange.c_str();
-  std::wstring w_strSelected;
-  if (-1 != pEvent->SelStart())
-    w_strSelected = w_strValue2.substr(pEvent->SelStart(),
-                                       (pEvent->SelEnd() - pEvent->SelStart()));
-  bool bHasSign = (w_strValue2.find('-') != std::wstring::npos) &&
-                  (w_strSelected.find('-') == std::wstring::npos);
-  if (bHasSign) {
-    // can't insert "change" in front to sign postion.
-    if (pEvent->SelStart() == 0) {
-      FX_BOOL& bRc = pEvent->Rc();
-      bRc = FALSE;
-      return TRUE;
-    }
-  }
-
-  char cSep = L'.';
-
-  switch (iSepStyle) {
-    case 0:
-    case 1:
-      cSep = L'.';
-      break;
-    case 2:
-    case 3:
-      cSep = L',';
-      break;
-  }
-
-  bool bHasSep = (w_strValue2.find(cSep) != std::wstring::npos);
-  for (std::wstring::iterator it = w_strChange2.begin();
-       it != w_strChange2.end(); it++) {
-    if (*it == cSep) {
-      if (bHasSep) {
-        FX_BOOL& bRc = pEvent->Rc();
-        bRc = FALSE;
-        return TRUE;
-      }
-      bHasSep = TRUE;
-      continue;
-    }
-    if (*it == L'-') {
-      if (bHasSign) {
-        FX_BOOL& bRc = pEvent->Rc();
-        bRc = FALSE;
-        return TRUE;
-      }
-      // sign's position is not correct
-      if (it != w_strChange2.begin()) {
-        FX_BOOL& bRc = pEvent->Rc();
-        bRc = FALSE;
-        return TRUE;
-      }
-      if (pEvent->SelStart() != 0) {
-        FX_BOOL& bRc = pEvent->Rc();
-        bRc = FALSE;
-        return TRUE;
-      }
-      bHasSign = TRUE;
-      continue;
-    }
-
-    if (!FXSYS_iswdigit(*it)) {
-      FX_BOOL& bRc = pEvent->Rc();
-      bRc = FALSE;
-      return TRUE;
-    }
-  }
-
-  std::wstring w_prefix = w_strValue2.substr(0, pEvent->SelStart());
-  std::wstring w_postfix;
-  if (pEvent->SelEnd() < (int)w_strValue2.length())
-    w_postfix = w_strValue2.substr(pEvent->SelEnd());
-  w_strValue2 = w_prefix + w_strChange2 + w_postfix;
-  w_strValue = w_strValue2.c_str();
-  val = w_strValue;
-  return TRUE;
-}
-
-// function AFPercent_Format(nDec, sepStyle)
-FX_BOOL CJS_PublicMethods::AFPercent_Format(
-    IJS_Context* cc,
-    const std::vector<CJS_Value>& params,
-    CJS_Value& vRet,
-    CFX_WideString& sError) {
-#if _FX_OS_ != _FX_ANDROID_
-  CJS_Context* pContext = (CJS_Context*)cc;
-  CJS_EventHandler* pEvent = pContext->GetEventHandler();
-
-  if (params.size() != 2) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
-    return FALSE;
-  }
-  if (!pEvent->m_pValue)
-    return FALSE;
-
-  CFX_WideString& Value = pEvent->Value();
-  CFX_ByteString strValue = StrTrim(CFX_ByteString::FromUnicode(Value));
-  if (strValue.IsEmpty())
-    return TRUE;
-
-  int iDec = params[0].ToInt();
-  if (iDec < 0)
-    iDec = -iDec;
-
-  int iSepStyle = params[1].ToInt();
-  if (iSepStyle < 0 || iSepStyle > 3)
-    iSepStyle = 0;
-
-  //////////////////////////////////////////////////////
-  // for processing decimal places
-  double dValue = atof(strValue);
-  dValue *= 100;
-  if (iDec > 0)
-    dValue += DOUBLE_CORRECT;
-
-  int iDec2;
-  int iNegative = 0;
-  strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
-  if (strValue.IsEmpty()) {
-    dValue = 0;
-    strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
-  }
-
-  if (iDec2 < 0) {
-    for (int iNum = 0; iNum < abs(iDec2); iNum++) {
-      strValue = "0" + strValue;
-    }
-    iDec2 = 0;
-  }
-  int iMax = strValue.GetLength();
-  if (iDec2 > iMax) {
-    for (int iNum = 0; iNum <= iDec2 - iMax; iNum++) {
-      strValue += "0";
-    }
-    iMax = iDec2 + 1;
-  }
-  ///////////////////////////////////////////////////////
-  // for processing seperator style
-  if (iDec2 < iMax) {
-    if (iSepStyle == 0 || iSepStyle == 1) {
-      strValue.Insert(iDec2, '.');
-      iMax++;
-    } else if (iSepStyle == 2 || iSepStyle == 3) {
-      strValue.Insert(iDec2, ',');
-      iMax++;
-    }
-
-    if (iDec2 == 0)
-      strValue.Insert(iDec2, '0');
-  }
-  if (iSepStyle == 0 || iSepStyle == 2) {
-    char cSeperator;
-    if (iSepStyle == 0)
-      cSeperator = ',';
-    else
-      cSeperator = '.';
-
-    for (int iDecPositive = iDec2 - 3; iDecPositive > 0; iDecPositive -= 3) {
-      strValue.Insert(iDecPositive, cSeperator);
-      iMax++;
-    }
-  }
-  ////////////////////////////////////////////////////////////////////
-  // negative mark
-  if (iNegative)
-    strValue = "-" + strValue;
-  strValue += "%";
-  Value = CFX_WideString::FromLocal(strValue);
-#endif
-  return TRUE;
-}
-// AFPercent_Keystroke(nDec, sepStyle)
-FX_BOOL CJS_PublicMethods::AFPercent_Keystroke(
-    IJS_Context* cc,
-    const std::vector<CJS_Value>& params,
-    CJS_Value& vRet,
-    CFX_WideString& sError) {
-  return AFNumber_Keystroke(cc, params, vRet, sError);
-}
-
-// function AFDate_FormatEx(cFormat)
-FX_BOOL CJS_PublicMethods::AFDate_FormatEx(IJS_Context* cc,
-                                           const std::vector<CJS_Value>& params,
-                                           CJS_Value& vRet,
-                                           CFX_WideString& sError) {
-  CJS_Context* pContext = (CJS_Context*)cc;
-  CJS_EventHandler* pEvent = pContext->GetEventHandler();
-
-  if (params.size() != 1) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
-    return FALSE;
-  }
-  if (!pEvent->m_pValue)
-    return FALSE;
-
-  CFX_WideString& val = pEvent->Value();
-  CFX_WideString strValue = val;
-  if (strValue.IsEmpty())
-    return TRUE;
-
-  CFX_WideString sFormat = params[0].ToCFXWideString();
-  double dDate = 0.0f;
-
-  if (strValue.Find(L"GMT") != -1) {
-    // for GMT format time
-    // such as "Tue Aug 11 14:24:16 GMT+08002009"
-    dDate = MakeInterDate(strValue);
-  } else {
-    dDate = MakeRegularDate(strValue, sFormat, nullptr);
-  }
-
-  if (JS_PortIsNan(dDate)) {
-    CFX_WideString swMsg;
-    swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(),
-                 sFormat.c_str());
-    Alert(pContext, swMsg.c_str());
-    return FALSE;
-  }
-
-  val = MakeFormatDate(dDate, sFormat);
-  return TRUE;
-}
-
-double CJS_PublicMethods::MakeInterDate(CFX_WideString strValue) {
-  int nHour;
-  int nMin;
-  int nSec;
-  int nYear;
-  int nMonth;
-  int nDay;
-
-  CFX_WideStringArray wsArray;
-  CFX_WideString sMonth = L"";
-  CFX_WideString sTemp = L"";
-  int nSize = strValue.GetLength();
-
-  for (int i = 0; i < nSize; i++) {
-    FX_WCHAR c = strValue.GetAt(i);
-    if (c == L' ' || c == L':') {
-      wsArray.Add(sTemp);
-      sTemp = L"";
-      continue;
-    }
-
-    sTemp += c;
-  }
-
-  wsArray.Add(sTemp);
-  if (wsArray.GetSize() != 8)
-    return 0;
-
-  sTemp = wsArray[1];
-  if (sTemp.Compare(L"Jan") == 0)
-    nMonth = 1;
-  if (sTemp.Compare(L"Feb") == 0)
-    nMonth = 2;
-  if (sTemp.Compare(L"Mar") == 0)
-    nMonth = 3;
-  if (sTemp.Compare(L"Apr") == 0)
-    nMonth = 4;
-  if (sTemp.Compare(L"May") == 0)
-    nMonth = 5;
-  if (sTemp.Compare(L"Jun") == 0)
-    nMonth = 6;
-  if (sTemp.Compare(L"Jul") == 0)
-    nMonth = 7;
-  if (sTemp.Compare(L"Aug") == 0)
-    nMonth = 8;
-  if (sTemp.Compare(L"Sep") == 0)
-    nMonth = 9;
-  if (sTemp.Compare(L"Oct") == 0)
-    nMonth = 10;
-  if (sTemp.Compare(L"Nov") == 0)
-    nMonth = 11;
-  if (sTemp.Compare(L"Dec") == 0)
-    nMonth = 12;
-
-  nDay = (int)ParseStringToNumber(wsArray[2].c_str());
-  nHour = (int)ParseStringToNumber(wsArray[3].c_str());
-  nMin = (int)ParseStringToNumber(wsArray[4].c_str());
-  nSec = (int)ParseStringToNumber(wsArray[5].c_str());
-  nYear = (int)ParseStringToNumber(wsArray[7].c_str());
-
-  double dRet = JS_MakeDate(JS_MakeDay(nYear, nMonth - 1, nDay),
-                            JS_MakeTime(nHour, nMin, nSec, 0));
-
-  if (JS_PortIsNan(dRet)) {
-    dRet = JS_DateParse(strValue.c_str());
-  }
-
-  return dRet;
-}
-
-// AFDate_KeystrokeEx(cFormat)
-FX_BOOL CJS_PublicMethods::AFDate_KeystrokeEx(
-    IJS_Context* cc,
-    const std::vector<CJS_Value>& params,
-    CJS_Value& vRet,
-    CFX_WideString& sError) {
-  CJS_Context* pContext = (CJS_Context*)cc;
-  CJS_EventHandler* pEvent = pContext->GetEventHandler();
-
-  if (params.size() != 1) {
-    sError = L"AFDate_KeystrokeEx's parameters' size r not correct";
-    return FALSE;
-  }
-
-  if (pEvent->WillCommit()) {
-    if (!pEvent->m_pValue)
-      return FALSE;
-    CFX_WideString strValue = pEvent->Value();
-    if (strValue.IsEmpty())
-      return TRUE;
-
-    CFX_WideString sFormat = params[0].ToCFXWideString();
-    bool bWrongFormat = FALSE;
-    double dRet = MakeRegularDate(strValue, sFormat, &bWrongFormat);
-    if (bWrongFormat || JS_PortIsNan(dRet)) {
-      CFX_WideString swMsg;
-      swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(),
-                   sFormat.c_str());
-      Alert(pContext, swMsg.c_str());
-      pEvent->Rc() = FALSE;
-      return TRUE;
-    }
-  }
-  return TRUE;
-}
-
-FX_BOOL CJS_PublicMethods::AFDate_Format(IJS_Context* cc,
-                                         const std::vector<CJS_Value>& params,
-                                         CJS_Value& vRet,
-                                         CFX_WideString& sError) {
-  CJS_Context* pContext = (CJS_Context*)cc;
-  if (params.size() != 1) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
-    return FALSE;
-  }
-
-  int iIndex = params[0].ToInt();
-  const FX_WCHAR* cFormats[] = {L"m/d",
-                                L"m/d/yy",
-                                L"mm/dd/yy",
-                                L"mm/yy",
-                                L"d-mmm",
-                                L"d-mmm-yy",
-                                L"dd-mmm-yy",
-                                L"yy-mm-dd",
-                                L"mmm-yy",
-                                L"mmmm-yy",
-                                L"mmm d, yyyy",
-                                L"mmmm d, yyyy",
-                                L"m/d/yy h:MM tt",
-                                L"m/d/yy HH:MM"};
-
-  if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
-    iIndex = 0;
-
-  std::vector<CJS_Value> newParams;
-  newParams.push_back(
-      CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
-  return AFDate_FormatEx(cc, newParams, vRet, sError);
-}
-
-// AFDate_KeystrokeEx(cFormat)
-FX_BOOL CJS_PublicMethods::AFDate_Keystroke(
-    IJS_Context* cc,
-    const std::vector<CJS_Value>& params,
-    CJS_Value& vRet,
-    CFX_WideString& sError) {
-  CJS_Context* pContext = (CJS_Context*)cc;
-  if (params.size() != 1) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
-    return FALSE;
-  }
-
-  int iIndex = params[0].ToInt();
-  const FX_WCHAR* cFormats[] = {L"m/d",
-                                L"m/d/yy",
-                                L"mm/dd/yy",
-                                L"mm/yy",
-                                L"d-mmm",
-                                L"d-mmm-yy",
-                                L"dd-mmm-yy",
-                                L"yy-mm-dd",
-                                L"mmm-yy",
-                                L"mmmm-yy",
-                                L"mmm d, yyyy",
-                                L"mmmm d, yyyy",
-                                L"m/d/yy h:MM tt",
-                                L"m/d/yy HH:MM"};
-
-  if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
-    iIndex = 0;
-
-  std::vector<CJS_Value> newParams;
-  newParams.push_back(
-      CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
-  return AFDate_KeystrokeEx(cc, newParams, vRet, sError);
-}
-
-// function AFTime_Format(ptf)
-FX_BOOL CJS_PublicMethods::AFTime_Format(IJS_Context* cc,
-                                         const std::vector<CJS_Value>& params,
-                                         CJS_Value& vRet,
-                                         CFX_WideString& sError) {
-  CJS_Context* pContext = (CJS_Context*)cc;
-  if (params.size() != 1) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
-    return FALSE;
-  }
-
-  int iIndex = params[0].ToInt();
-  const FX_WCHAR* cFormats[] = {L"HH:MM", L"h:MM tt", L"HH:MM:ss",
-                                L"h:MM:ss tt"};
-
-  if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
-    iIndex = 0;
-
-  std::vector<CJS_Value> newParams;
-  newParams.push_back(
-      CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
-  return AFDate_FormatEx(cc, newParams, vRet, sError);
-}
-
-FX_BOOL CJS_PublicMethods::AFTime_Keystroke(
-    IJS_Context* cc,
-    const std::vector<CJS_Value>& params,
-    CJS_Value& vRet,
-    CFX_WideString& sError) {
-  CJS_Context* pContext = (CJS_Context*)cc;
-  if (params.size() != 1) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
-    return FALSE;
-  }
-
-  int iIndex = params[0].ToInt();
-  const FX_WCHAR* cFormats[] = {L"HH:MM", L"h:MM tt", L"HH:MM:ss",
-                                L"h:MM:ss tt"};
-
-  if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
-    iIndex = 0;
-
-  std::vector<CJS_Value> newParams;
-  newParams.push_back(
-      CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
-  return AFDate_KeystrokeEx(cc, newParams, vRet, sError);
-}
-
-FX_BOOL CJS_PublicMethods::AFTime_FormatEx(IJS_Context* cc,
-                                           const std::vector<CJS_Value>& params,
-                                           CJS_Value& vRet,
-                                           CFX_WideString& sError) {
-  return AFDate_FormatEx(cc, params, vRet, sError);
-}
-
-FX_BOOL CJS_PublicMethods::AFTime_KeystrokeEx(
-    IJS_Context* cc,
-    const std::vector<CJS_Value>& params,
-    CJS_Value& vRet,
-    CFX_WideString& sError) {
-  return AFDate_KeystrokeEx(cc, params, vRet, sError);
-}
-
-// function AFSpecial_Format(psf)
-FX_BOOL CJS_PublicMethods::AFSpecial_Format(
-    IJS_Context* cc,
-    const std::vector<CJS_Value>& params,
-    CJS_Value& vRet,
-    CFX_WideString& sError) {
-  CJS_Context* pContext = (CJS_Context*)cc;
-
-  if (params.size() != 1) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
-    return FALSE;
-  }
-
-  std::string cFormat;
-  int iIndex = params[0].ToInt();
-
-  CJS_EventHandler* pEvent = pContext->GetEventHandler();
-  if (!pEvent->m_pValue)
-    return FALSE;
-  CFX_WideString& Value = pEvent->Value();
-  std::string strSrc = CFX_ByteString::FromUnicode(Value).c_str();
-
-  switch (iIndex) {
-    case 0:
-      cFormat = "99999";
-      break;
-    case 1:
-      cFormat = "99999-9999";
-      break;
-    case 2: {
-      std::string NumberStr;
-      util::printx("9999999999", strSrc, NumberStr);
-      if (NumberStr.length() >= 10)
-        cFormat = "(999) 999-9999";
-      else
-        cFormat = "999-9999";
-      break;
-    }
-    case 3:
-      cFormat = "999-99-9999";
-      break;
-  }
-
-  std::string strDes;
-  util::printx(cFormat, strSrc, strDes);
-  Value = CFX_WideString::FromLocal(strDes.c_str());
-  return TRUE;
-}
-
-// function AFSpecial_KeystrokeEx(mask)
-FX_BOOL CJS_PublicMethods::AFSpecial_KeystrokeEx(
-    IJS_Context* cc,
-    const std::vector<CJS_Value>& params,
-    CJS_Value& vRet,
-    CFX_WideString& sError) {
-  CJS_Context* pContext = (CJS_Context*)cc;
-  CJS_EventHandler* pEvent = pContext->GetEventHandler();
-
-  if (params.size() < 1) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
-    return FALSE;
-  }
-
-  if (!pEvent->m_pValue)
-    return FALSE;
-  CFX_WideString& valEvent = pEvent->Value();
-
-  CFX_WideString wstrMask = params[0].ToCFXWideString();
-  if (wstrMask.IsEmpty())
-    return TRUE;
-
-  const size_t wstrMaskLen = wstrMask.GetLength();
-  const std::wstring wstrValue = valEvent.c_str();
-
-  if (pEvent->WillCommit()) {
-    if (wstrValue.empty())
-      return TRUE;
-    size_t iIndexMask = 0;
-    for (const auto& w_Value : wstrValue) {
-      if (!maskSatisfied(w_Value, wstrMask[iIndexMask]))
-        break;
-      iIndexMask++;
-    }
-
-    if (iIndexMask != wstrMaskLen ||
-        (iIndexMask != wstrValue.size() && wstrMaskLen != 0)) {
-      Alert(
-          pContext,
-          JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE).c_str());
-      pEvent->Rc() = FALSE;
-    }
-    return TRUE;
-  }
-
-  CFX_WideString& wideChange = pEvent->Change();
-  std::wstring wChange = wideChange.c_str();
-  if (wChange.empty())
-    return TRUE;
-
-  int iIndexMask = pEvent->SelStart();
-
-  size_t combined_len = wstrValue.length() + wChange.length() -
-                        (pEvent->SelEnd() - pEvent->SelStart());
-  if (combined_len > wstrMaskLen) {
-    Alert(pContext,
-          JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
-    pEvent->Rc() = FALSE;
-    return TRUE;
-  }
-
-  if (iIndexMask >= wstrMaskLen && (!wChange.empty())) {
-    Alert(pContext,
-          JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
-    pEvent->Rc() = FALSE;
-    return TRUE;
-  }
-
-  for (std::wstring::iterator it = wChange.begin(); it != wChange.end(); it++) {
-    if (iIndexMask >= wstrMaskLen) {
-      Alert(pContext,
-            JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
-      pEvent->Rc() = FALSE;
-      return TRUE;
-    }
-    wchar_t w_Mask = wstrMask[iIndexMask];
-    if (!isReservedMaskChar(w_Mask)) {
-      *it = w_Mask;
-    }
-    wchar_t w_Change = *it;
-    if (!maskSatisfied(w_Change, w_Mask)) {
-      pEvent->Rc() = FALSE;
-      return TRUE;
-    }
-    iIndexMask++;
-  }
-
-  wideChange = wChange.c_str();
-  return TRUE;
-}
-
-// function AFSpecial_Keystroke(psf)
-FX_BOOL CJS_PublicMethods::AFSpecial_Keystroke(
-    IJS_Context* cc,
-    const std::vector<CJS_Value>& params,
-    CJS_Value& vRet,
-    CFX_WideString& sError) {
-  CJS_Context* pContext = (CJS_Context*)cc;
-  if (params.size() != 1) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
-    return FALSE;
-  }
-
-  CJS_EventHandler* pEvent = pContext->GetEventHandler();
-  if (!pEvent->m_pValue)
-    return FALSE;
-
-  std::string cFormat;
-  int iIndex = params[0].ToInt();
-  CFX_WideString& val = pEvent->Value();
-  std::string strSrc = CFX_ByteString::FromUnicode(val).c_str();
-  std::wstring wstrChange = pEvent->Change().c_str();
-
-  switch (iIndex) {
-    case 0:
-      cFormat = "99999";
-      break;
-    case 1:
-      // cFormat = "99999-9999";
-      cFormat = "999999999";
-      break;
-    case 2: {
-      std::string NumberStr;
-      util::printx("9999999999", strSrc, NumberStr);
-      if (strSrc.length() + wstrChange.length() > 7)
-        // cFormat = "(999) 999-9999";
-        cFormat = "9999999999";
-      else
-        // cFormat = "999-9999";
-        cFormat = "9999999";
-      break;
-    }
-    case 3:
-      // cFormat = "999-99-9999";
-      cFormat = "999999999";
-      break;
-  }
-
-  std::vector<CJS_Value> params2;
-  params2.push_back(CJS_Value(CJS_Runtime::FromContext(cc), cFormat.c_str()));
-  return AFSpecial_KeystrokeEx(cc, params2, vRet, sError);
-}
-
-FX_BOOL CJS_PublicMethods::AFMergeChange(IJS_Context* cc,
-                                         const std::vector<CJS_Value>& params,
-                                         CJS_Value& vRet,
-                                         CFX_WideString& sError) {
-  CJS_Context* pContext = (CJS_Context*)cc;
-  CJS_EventHandler* pEventHandler = pContext->GetEventHandler();
-
-  if (params.size() != 1) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
-    return FALSE;
-  }
-
-  CFX_WideString swValue;
-  if (pEventHandler->m_pValue)
-    swValue = pEventHandler->Value();
-
-  if (pEventHandler->WillCommit()) {
-    vRet = swValue.c_str();
-    return TRUE;
-  }
-
-  CFX_WideString prefix, postfix;
-
-  if (pEventHandler->SelStart() >= 0)
-    prefix = swValue.Mid(0, pEventHandler->SelStart());
-  else
-    prefix = L"";
-
-  if (pEventHandler->SelEnd() >= 0 &&
-      pEventHandler->SelEnd() <= swValue.GetLength())
-    postfix = swValue.Mid(pEventHandler->SelEnd(),
-                          swValue.GetLength() - pEventHandler->SelEnd());
-  else
-    postfix = L"";
-
-  vRet = (prefix + pEventHandler->Change() + postfix).c_str();
-
-  return TRUE;
-}
-
-FX_BOOL CJS_PublicMethods::AFParseDateEx(IJS_Context* cc,
-                                         const std::vector<CJS_Value>& params,
-                                         CJS_Value& vRet,
-                                         CFX_WideString& sError) {
-  CJS_Context* pContext = (CJS_Context*)cc;
-  ASSERT(pContext);
-
-  if (params.size() != 2) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
-    return FALSE;
-  }
-
-  CFX_WideString sValue = params[0].ToCFXWideString();
-  CFX_WideString sFormat = params[1].ToCFXWideString();
-
-  double dDate = MakeRegularDate(sValue, sFormat, nullptr);
-
-  if (JS_PortIsNan(dDate)) {
-    CFX_WideString swMsg;
-    swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(),
-                 sFormat.c_str());
-    Alert((CJS_Context*)cc, swMsg.c_str());
-    return FALSE;
-  }
-
-  vRet = dDate;
-  return TRUE;
-}
-
-FX_BOOL CJS_PublicMethods::AFSimple(IJS_Context* cc,
-                                    const std::vector<CJS_Value>& params,
-                                    CJS_Value& vRet,
-                                    CFX_WideString& sError) {
-  if (params.size() != 3) {
-    CJS_Context* pContext = (CJS_Context*)cc;
-    ASSERT(pContext);
-
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
-    return FALSE;
-  }
-
-  vRet = (double)AF_Simple(params[0].ToCFXWideString().c_str(),
-                           params[1].ToDouble(), params[2].ToDouble());
-  return TRUE;
-}
-
-FX_BOOL CJS_PublicMethods::AFMakeNumber(IJS_Context* cc,
-                                        const std::vector<CJS_Value>& params,
-                                        CJS_Value& vRet,
-                                        CFX_WideString& sError) {
-  if (params.size() != 1) {
-    CJS_Context* pContext = (CJS_Context*)cc;
-    ASSERT(pContext);
-
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
-    return FALSE;
-  }
-  vRet = ParseStringToNumber(params[0].ToCFXWideString().c_str());
-  return TRUE;
-}
-
-FX_BOOL CJS_PublicMethods::AFSimple_Calculate(
-    IJS_Context* cc,
-    const std::vector<CJS_Value>& params,
-    CJS_Value& vRet,
-    CFX_WideString& sError) {
-  CJS_Context* pContext = (CJS_Context*)cc;
-  if (params.size() != 2) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
-    return FALSE;
-  }
-
-  CJS_Value params1 = params[1];
-  if (!params1.IsArrayObject() && params1.GetType() != CJS_Value::VT_string) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
-    return FALSE;
-  }
-
-  CPDFSDK_Document* pReaderDoc = pContext->GetReaderDocument();
-  CPDFSDK_InterForm* pReaderInterForm = pReaderDoc->GetInterForm();
-  CPDF_InterForm* pInterForm = pReaderInterForm->GetInterForm();
-
-  CFX_WideString sFunction = params[0].ToCFXWideString();
-  double dValue = wcscmp(sFunction.c_str(), L"PRD") == 0 ? 1.0 : 0.0;
-
-  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
-  CJS_Array FieldNameArray = AF_MakeArrayFromList(pRuntime, params1);
-  int nFieldsCount = 0;
-
-  for (int i = 0, isz = FieldNameArray.GetLength(); i < isz; i++) {
-    CJS_Value jsValue(pRuntime);
-    FieldNameArray.GetElement(i, jsValue);
-    CFX_WideString wsFieldName = jsValue.ToCFXWideString();
-
-    for (int j = 0, jsz = pInterForm->CountFields(wsFieldName); j < jsz; j++) {
-      if (CPDF_FormField* pFormField = pInterForm->GetField(j, wsFieldName)) {
-        double dTemp = 0.0;
-
-        switch (pFormField->GetFieldType()) {
-          case FIELDTYPE_TEXTFIELD:
-          case FIELDTYPE_COMBOBOX: {
-            dTemp = ParseStringToNumber(pFormField->GetValue().c_str());
-            break;
-          }
-          case FIELDTYPE_PUSHBUTTON: {
-            dTemp = 0.0;
-            break;
-          }
-          case FIELDTYPE_CHECKBOX:
-          case FIELDTYPE_RADIOBUTTON: {
-            dTemp = 0.0;
-            for (int c = 0, csz = pFormField->CountControls(); c < csz; c++) {
-              if (CPDF_FormControl* pFormCtrl = pFormField->GetControl(c)) {
-                if (pFormCtrl->IsChecked()) {
-                  dTemp +=
-                      ParseStringToNumber(pFormCtrl->GetExportValue().c_str());
-                  break;
-                }
-              }
-            }
-            break;
-          }
-          case FIELDTYPE_LISTBOX: {
-            if (pFormField->CountSelectedItems() > 1)
-              break;
-
-            dTemp = ParseStringToNumber(pFormField->GetValue().c_str());
-            break;
-          }
-          default:
-            break;
-        }
-
-        if (i == 0 && j == 0 && (wcscmp(sFunction.c_str(), L"MIN") == 0 ||
-                                 wcscmp(sFunction.c_str(), L"MAX") == 0))
-          dValue = dTemp;
-
-        dValue = AF_Simple(sFunction.c_str(), dValue, dTemp);
-
-        nFieldsCount++;
-      }
-    }
-  }
-
-  if (wcscmp(sFunction.c_str(), L"AVG") == 0 && nFieldsCount > 0)
-    dValue /= nFieldsCount;
-
-  dValue = (double)floor(dValue * FXSYS_pow((double)10, (double)6) + 0.49) /
-           FXSYS_pow((double)10, (double)6);
-  CJS_Value jsValue(pRuntime, dValue);
-  if (pContext->GetEventHandler()->m_pValue)
-    pContext->GetEventHandler()->Value() = jsValue.ToCFXWideString();
-
-  return TRUE;
-}
-
-/* This function validates the current event to ensure that its value is
-** within the specified range. */
-
-FX_BOOL CJS_PublicMethods::AFRange_Validate(
-    IJS_Context* cc,
-    const std::vector<CJS_Value>& params,
-    CJS_Value& vRet,
-    CFX_WideString& sError) {
-  CJS_Context* pContext = (CJS_Context*)cc;
-  CJS_EventHandler* pEvent = pContext->GetEventHandler();
-
-  if (params.size() != 4) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
-    return FALSE;
-  }
-
-  if (!pEvent->m_pValue)
-    return FALSE;
-  if (pEvent->Value().IsEmpty())
-    return TRUE;
-  double dEentValue = atof(CFX_ByteString::FromUnicode(pEvent->Value()));
-  FX_BOOL bGreaterThan = params[0].ToBool();
-  double dGreaterThan = params[1].ToDouble();
-  FX_BOOL bLessThan = params[2].ToBool();
-  double dLessThan = params[3].ToDouble();
-  CFX_WideString swMsg;
-
-  if (bGreaterThan && bLessThan) {
-    if (dEentValue < dGreaterThan || dEentValue > dLessThan)
-      swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE1).c_str(),
-                   params[1].ToCFXWideString().c_str(),
-                   params[3].ToCFXWideString().c_str());
-  } else if (bGreaterThan) {
-    if (dEentValue < dGreaterThan)
-      swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE2).c_str(),
-                   params[1].ToCFXWideString().c_str());
-  } else if (bLessThan) {
-    if (dEentValue > dLessThan)
-      swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE3).c_str(),
-                   params[3].ToCFXWideString().c_str());
-  }
-
-  if (!swMsg.IsEmpty()) {
-    Alert(pContext, swMsg.c_str());
-    pEvent->Rc() = FALSE;
-  }
-  return TRUE;
-}
-
-FX_BOOL CJS_PublicMethods::AFExtractNums(IJS_Context* cc,
-                                         const std::vector<CJS_Value>& params,
-                                         CJS_Value& vRet,
-                                         CFX_WideString& sError) {
-  CJS_Context* pContext = (CJS_Context*)cc;
-  if (params.size() != 1) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
-    return FALSE;
-  }
-
-  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
-  CJS_Array nums(pRuntime);
-
-  CFX_WideString str = params[0].ToCFXWideString();
-  CFX_WideString sPart;
-
-  if (str.GetAt(0) == L'.' || str.GetAt(0) == L',')
-    str = L"0" + str;
-
-  int nIndex = 0;
-  for (int i = 0, sz = str.GetLength(); i < sz; i++) {
-    FX_WCHAR wc = str.GetAt(i);
-    if (FXSYS_iswdigit(wc)) {
-      sPart += wc;
-    } else {
-      if (sPart.GetLength() > 0) {
-        nums.SetElement(nIndex, CJS_Value(pRuntime, sPart.c_str()));
-        sPart = L"";
-        nIndex++;
-      }
-    }
-  }
-
-  if (sPart.GetLength() > 0) {
-    nums.SetElement(nIndex, CJS_Value(pRuntime, sPart.c_str()));
-  }
-
-  if (nums.GetLength() > 0)
-    vRet = nums;
-  else
-    vRet.SetNull();
-
-  return TRUE;
-}
diff --git a/fpdfsdk/src/javascript/PublicMethods.h b/fpdfsdk/src/javascript/PublicMethods.h
deleted file mode 100644
index 013c4ce..0000000
--- a/fpdfsdk/src/javascript/PublicMethods.h
+++ /dev/null
@@ -1,181 +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_SRC_JAVASCRIPT_PUBLICMETHODS_H_
-#define FPDFSDK_SRC_JAVASCRIPT_PUBLICMETHODS_H_
-
-#include "JS_Define.h"
-
-class CJS_PublicMethods : public CJS_Object {
- public:
-  explicit CJS_PublicMethods(v8::Local<v8::Object> pObject)
-      : CJS_Object(pObject) {}
-  ~CJS_PublicMethods() override {}
-
- public:
-  static FX_BOOL AFNumber_Format(IJS_Context* cc,
-                                 const std::vector<CJS_Value>& params,
-                                 CJS_Value& vRet,
-                                 CFX_WideString& sError);
-  static FX_BOOL AFNumber_Keystroke(IJS_Context* cc,
-                                    const std::vector<CJS_Value>& params,
-                                    CJS_Value& vRet,
-                                    CFX_WideString& sError);
-  static FX_BOOL AFPercent_Format(IJS_Context* cc,
-                                  const std::vector<CJS_Value>& params,
-                                  CJS_Value& vRet,
-                                  CFX_WideString& sError);
-  static FX_BOOL AFPercent_Keystroke(IJS_Context* cc,
-                                     const std::vector<CJS_Value>& params,
-                                     CJS_Value& vRet,
-                                     CFX_WideString& sError);
-  static FX_BOOL AFDate_FormatEx(IJS_Context* cc,
-                                 const std::vector<CJS_Value>& params,
-                                 CJS_Value& vRet,
-                                 CFX_WideString& sError);
-  static FX_BOOL AFDate_KeystrokeEx(IJS_Context* cc,
-                                    const std::vector<CJS_Value>& params,
-                                    CJS_Value& vRet,
-                                    CFX_WideString& sError);
-  static FX_BOOL AFDate_Format(IJS_Context* cc,
-                               const std::vector<CJS_Value>& params,
-                               CJS_Value& vRet,
-                               CFX_WideString& sError);
-  static FX_BOOL AFDate_Keystroke(IJS_Context* cc,
-                                  const std::vector<CJS_Value>& params,
-                                  CJS_Value& vRet,
-                                  CFX_WideString& sError);
-  static FX_BOOL AFTime_FormatEx(IJS_Context* cc,
-                                 const std::vector<CJS_Value>& params,
-                                 CJS_Value& vRet,
-                                 CFX_WideString& sError);  //
-  static FX_BOOL AFTime_KeystrokeEx(IJS_Context* cc,
-                                    const std::vector<CJS_Value>& params,
-                                    CJS_Value& vRet,
-                                    CFX_WideString& sError);
-  static FX_BOOL AFTime_Format(IJS_Context* cc,
-                               const std::vector<CJS_Value>& params,
-                               CJS_Value& vRet,
-                               CFX_WideString& sError);
-  static FX_BOOL AFTime_Keystroke(IJS_Context* cc,
-                                  const std::vector<CJS_Value>& params,
-                                  CJS_Value& vRet,
-                                  CFX_WideString& sError);
-  static FX_BOOL AFSpecial_Format(IJS_Context* cc,
-                                  const std::vector<CJS_Value>& params,
-                                  CJS_Value& vRet,
-                                  CFX_WideString& sError);
-  static FX_BOOL AFSpecial_Keystroke(IJS_Context* cc,
-                                     const std::vector<CJS_Value>& params,
-                                     CJS_Value& vRet,
-                                     CFX_WideString& sError);
-  static FX_BOOL AFSpecial_KeystrokeEx(IJS_Context* cc,
-                                       const std::vector<CJS_Value>& params,
-                                       CJS_Value& vRet,
-                                       CFX_WideString& sError);  //
-  static FX_BOOL AFSimple(IJS_Context* cc,
-                          const std::vector<CJS_Value>& params,
-                          CJS_Value& vRet,
-                          CFX_WideString& sError);
-  static FX_BOOL AFMakeNumber(IJS_Context* cc,
-                              const std::vector<CJS_Value>& params,
-                              CJS_Value& vRet,
-                              CFX_WideString& sError);
-  static FX_BOOL AFSimple_Calculate(IJS_Context* cc,
-                                    const std::vector<CJS_Value>& params,
-                                    CJS_Value& vRet,
-                                    CFX_WideString& sError);
-  static FX_BOOL AFRange_Validate(IJS_Context* cc,
-                                  const std::vector<CJS_Value>& params,
-                                  CJS_Value& vRet,
-                                  CFX_WideString& sError);
-  static FX_BOOL AFMergeChange(IJS_Context* cc,
-                               const std::vector<CJS_Value>& params,
-                               CJS_Value& vRet,
-                               CFX_WideString& sError);
-  static FX_BOOL AFParseDateEx(IJS_Context* cc,
-                               const std::vector<CJS_Value>& params,
-                               CJS_Value& vRet,
-                               CFX_WideString& sError);
-  static FX_BOOL AFExtractNums(IJS_Context* cc,
-                               const std::vector<CJS_Value>& params,
-                               CJS_Value& vRet,
-                               CFX_WideString& sError);
-
- public:
-  JS_STATIC_GLOBAL_FUN(AFNumber_Format);
-  JS_STATIC_GLOBAL_FUN(AFNumber_Keystroke);
-  JS_STATIC_GLOBAL_FUN(AFPercent_Format);
-  JS_STATIC_GLOBAL_FUN(AFPercent_Keystroke);
-  JS_STATIC_GLOBAL_FUN(AFDate_FormatEx);
-  JS_STATIC_GLOBAL_FUN(AFDate_KeystrokeEx);
-  JS_STATIC_GLOBAL_FUN(AFDate_Format);
-  JS_STATIC_GLOBAL_FUN(AFDate_Keystroke);
-  JS_STATIC_GLOBAL_FUN(AFTime_FormatEx);
-  JS_STATIC_GLOBAL_FUN(AFTime_KeystrokeEx);
-  JS_STATIC_GLOBAL_FUN(AFTime_Format);
-  JS_STATIC_GLOBAL_FUN(AFTime_Keystroke);
-  JS_STATIC_GLOBAL_FUN(AFSpecial_Format);
-  JS_STATIC_GLOBAL_FUN(AFSpecial_Keystroke);
-  JS_STATIC_GLOBAL_FUN(AFSpecial_KeystrokeEx);
-  JS_STATIC_GLOBAL_FUN(AFSimple);
-  JS_STATIC_GLOBAL_FUN(AFMakeNumber);
-  JS_STATIC_GLOBAL_FUN(AFSimple_Calculate);
-  JS_STATIC_GLOBAL_FUN(AFRange_Validate);
-  JS_STATIC_GLOBAL_FUN(AFMergeChange);
-  JS_STATIC_GLOBAL_FUN(AFParseDateEx);
-  JS_STATIC_GLOBAL_FUN(AFExtractNums);
-
-  JS_STATIC_DECLARE_GLOBAL_FUN();
-
- public:
-  static int ParseStringInteger(const CFX_WideString& string,
-                                int nStart,
-                                int& nSkip,
-                                int nMaxStep);
-  static CFX_WideString ParseStringString(const CFX_WideString& string,
-                                          int nStart,
-                                          int& nSkip);
-  static double MakeRegularDate(const CFX_WideString& value,
-                                const CFX_WideString& format,
-                                bool* bWrongFormat);
-  static CFX_WideString MakeFormatDate(double dDate,
-                                       const CFX_WideString& format);
-  static FX_BOOL ConvertStringToNumber(const FX_WCHAR* swSource,
-                                       double& dRet,
-                                       FX_BOOL& bDot);
-  static double ParseStringToNumber(const FX_WCHAR* swSource);
-  static double ParseNormalDate(const CFX_WideString& value,
-                                bool* bWrongFormat);
-  static double MakeInterDate(CFX_WideString strValue);
-  static double ParseNumber(const FX_WCHAR* swSource,
-                            FX_BOOL& bAllDigits,
-                            FX_BOOL& bDot,
-                            FX_BOOL& bSign,
-                            FX_BOOL& bKXJS);
-
- public:
-  static CFX_WideString StrLTrim(const FX_WCHAR* pStr);
-  static CFX_WideString StrRTrim(const FX_WCHAR* pStr);
-  static CFX_WideString StrTrim(const FX_WCHAR* pStr);
-
-  static CFX_ByteString StrLTrim(const FX_CHAR* pStr);
-  static CFX_ByteString StrRTrim(const FX_CHAR* pStr);
-  static CFX_ByteString StrTrim(const FX_CHAR* pStr);
-
-  static FX_BOOL IsNumber(const FX_CHAR* string);
-  static FX_BOOL IsNumber(const FX_WCHAR* string);
-
-  static FX_BOOL maskSatisfied(wchar_t c_Change, wchar_t c_Mask);
-  static FX_BOOL isReservedMaskChar(wchar_t ch);
-
-  static double AF_Simple(const FX_WCHAR* sFuction,
-                          double dValue1,
-                          double dValue2);
-  static CJS_Array AF_MakeArrayFromList(CJS_Runtime* pRuntime, CJS_Value val);
-};
-
-#endif  // FPDFSDK_SRC_JAVASCRIPT_PUBLICMETHODS_H_
diff --git a/fpdfsdk/src/javascript/app.cpp b/fpdfsdk/src/javascript/app.cpp
deleted file mode 100644
index 1473edb..0000000
--- a/fpdfsdk/src/javascript/app.cpp
+++ /dev/null
@@ -1,833 +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
-
-#include "app.h"
-
-#include <memory>
-
-#include "Document.h"
-#include "JS_Context.h"
-#include "JS_Define.h"
-#include "JS_EventHandler.h"
-#include "JS_Object.h"
-#include "JS_Runtime.h"
-#include "JS_Value.h"
-#include "fpdfsdk/include/fsdk_mgr.h"  // For CPDFDoc_Environment.
-#include "fpdfsdk/include/javascript/IJavaScript.h"
-#include "resource.h"
-
-BEGIN_JS_STATIC_CONST(CJS_TimerObj)
-END_JS_STATIC_CONST()
-
-BEGIN_JS_STATIC_PROP(CJS_TimerObj)
-END_JS_STATIC_PROP()
-
-BEGIN_JS_STATIC_METHOD(CJS_TimerObj)
-END_JS_STATIC_METHOD()
-
-IMPLEMENT_JS_CLASS(CJS_TimerObj, TimerObj)
-
-TimerObj::TimerObj(CJS_Object* pJSObject)
-    : CJS_EmbedObj(pJSObject), m_pTimer(NULL) {}
-
-TimerObj::~TimerObj() {}
-
-void TimerObj::SetTimer(CJS_Timer* pTimer) {
-  m_pTimer = pTimer;
-}
-
-CJS_Timer* TimerObj::GetTimer() const {
-  return m_pTimer;
-}
-
-#define JS_STR_VIEWERTYPE L"pdfium"
-#define JS_STR_VIEWERVARIATION L"Full"
-#define JS_STR_PLATFORM L"WIN"
-#define JS_STR_LANGUANGE L"ENU"
-#define JS_NUM_VIEWERVERSION 8
-#ifdef PDF_ENABLE_XFA
-#define JS_NUM_VIEWERVERSION_XFA 11
-#endif  // PDF_ENABLE_XFA
-#define JS_NUM_FORMSVERSION 7
-
-BEGIN_JS_STATIC_CONST(CJS_App)
-END_JS_STATIC_CONST()
-
-BEGIN_JS_STATIC_PROP(CJS_App)
-JS_STATIC_PROP_ENTRY(activeDocs)
-JS_STATIC_PROP_ENTRY(calculate)
-JS_STATIC_PROP_ENTRY(formsVersion)
-JS_STATIC_PROP_ENTRY(fs)
-JS_STATIC_PROP_ENTRY(fullscreen)
-JS_STATIC_PROP_ENTRY(language)
-JS_STATIC_PROP_ENTRY(media)
-JS_STATIC_PROP_ENTRY(platform)
-JS_STATIC_PROP_ENTRY(runtimeHighlight)
-JS_STATIC_PROP_ENTRY(viewerType)
-JS_STATIC_PROP_ENTRY(viewerVariation)
-JS_STATIC_PROP_ENTRY(viewerVersion)
-END_JS_STATIC_PROP()
-
-BEGIN_JS_STATIC_METHOD(CJS_App)
-JS_STATIC_METHOD_ENTRY(alert)
-JS_STATIC_METHOD_ENTRY(beep)
-JS_STATIC_METHOD_ENTRY(browseForDoc)
-JS_STATIC_METHOD_ENTRY(clearInterval)
-JS_STATIC_METHOD_ENTRY(clearTimeOut)
-JS_STATIC_METHOD_ENTRY(execDialog)
-JS_STATIC_METHOD_ENTRY(execMenuItem)
-JS_STATIC_METHOD_ENTRY(findComponent)
-JS_STATIC_METHOD_ENTRY(goBack)
-JS_STATIC_METHOD_ENTRY(goForward)
-JS_STATIC_METHOD_ENTRY(launchURL)
-JS_STATIC_METHOD_ENTRY(mailMsg)
-JS_STATIC_METHOD_ENTRY(newFDF)
-JS_STATIC_METHOD_ENTRY(newDoc)
-JS_STATIC_METHOD_ENTRY(openDoc)
-JS_STATIC_METHOD_ENTRY(openFDF)
-JS_STATIC_METHOD_ENTRY(popUpMenuEx)
-JS_STATIC_METHOD_ENTRY(popUpMenu)
-JS_STATIC_METHOD_ENTRY(response)
-JS_STATIC_METHOD_ENTRY(setInterval)
-JS_STATIC_METHOD_ENTRY(setTimeOut)
-END_JS_STATIC_METHOD()
-
-IMPLEMENT_JS_CLASS(CJS_App, app)
-
-app::app(CJS_Object* pJSObject)
-    : CJS_EmbedObj(pJSObject), m_bCalculate(true), m_bRuntimeHighLight(false) {}
-
-app::~app() {
-  for (int i = 0, sz = m_aTimer.GetSize(); i < sz; i++)
-    delete m_aTimer[i];
-
-  m_aTimer.RemoveAll();
-}
-
-FX_BOOL app::activeDocs(IJS_Context* cc,
-                        CJS_PropValue& vp,
-                        CFX_WideString& sError) {
-  if (!vp.IsGetting())
-    return FALSE;
-
-  CJS_Context* pContext = (CJS_Context*)cc;
-  CPDFDoc_Environment* pApp = pContext->GetReaderApp();
-  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
-  CPDFSDK_Document* pCurDoc = pContext->GetReaderDocument();
-  CJS_Array aDocs(pRuntime);
-  if (CPDFSDK_Document* pDoc = pApp->GetSDKDocument()) {
-    CJS_Document* pJSDocument = NULL;
-    if (pDoc == pCurDoc) {
-      v8::Local<v8::Object> pObj = FXJS_GetThisObj(pRuntime->GetIsolate());
-      if (FXJS_GetObjDefnID(pObj) == CJS_Document::g_nObjDefnID)
-        pJSDocument =
-            (CJS_Document*)FXJS_GetPrivate(pRuntime->GetIsolate(), pObj);
-    } else {
-      v8::Local<v8::Object> pObj = FXJS_NewFxDynamicObj(
-          pRuntime->GetIsolate(), pRuntime, CJS_Document::g_nObjDefnID);
-      pJSDocument =
-          (CJS_Document*)FXJS_GetPrivate(pRuntime->GetIsolate(), pObj);
-      ASSERT(pJSDocument);
-    }
-    aDocs.SetElement(0, CJS_Value(pRuntime, pJSDocument));
-  }
-  if (aDocs.GetLength() > 0)
-    vp << aDocs;
-  else
-    vp.SetNull();
-
-  return TRUE;
-}
-
-FX_BOOL app::calculate(IJS_Context* cc,
-                       CJS_PropValue& vp,
-                       CFX_WideString& sError) {
-  if (vp.IsSetting()) {
-    bool bVP;
-    vp >> bVP;
-    m_bCalculate = (FX_BOOL)bVP;
-
-    CJS_Context* pContext = (CJS_Context*)cc;
-    CPDFDoc_Environment* pApp = pContext->GetReaderApp();
-    CJS_Runtime* pRuntime = pContext->GetJSRuntime();
-    CJS_Array aDocs(pRuntime);
-    if (CPDFSDK_Document* pDoc = pApp->GetSDKDocument())
-      pDoc->GetInterForm()->EnableCalculate((FX_BOOL)m_bCalculate);
-  } else {
-    vp << (bool)m_bCalculate;
-  }
-  return TRUE;
-}
-
-FX_BOOL app::formsVersion(IJS_Context* cc,
-                          CJS_PropValue& vp,
-                          CFX_WideString& sError) {
-  if (vp.IsGetting()) {
-    vp << JS_NUM_FORMSVERSION;
-    return TRUE;
-  }
-
-  return FALSE;
-}
-
-FX_BOOL app::viewerType(IJS_Context* cc,
-                        CJS_PropValue& vp,
-                        CFX_WideString& sError) {
-  if (vp.IsGetting()) {
-    vp << JS_STR_VIEWERTYPE;
-    return TRUE;
-  }
-
-  return FALSE;
-}
-
-FX_BOOL app::viewerVariation(IJS_Context* cc,
-                             CJS_PropValue& vp,
-                             CFX_WideString& sError) {
-  if (vp.IsGetting()) {
-    vp << JS_STR_VIEWERVARIATION;
-    return TRUE;
-  }
-
-  return FALSE;
-}
-
-FX_BOOL app::viewerVersion(IJS_Context* cc,
-                           CJS_PropValue& vp,
-                           CFX_WideString& sError) {
-  if (!vp.IsGetting())
-    return FALSE;
-#ifdef PDF_ENABLE_XFA
-  CJS_Context* pContext = (CJS_Context*)cc;
-  CPDFSDK_Document* pCurDoc = pContext->GetReaderDocument();
-  CPDFXFA_Document* pDoc = pCurDoc->GetXFADocument();
-  if (pDoc->GetDocType() == 1 || pDoc->GetDocType() == 2) {
-    vp << JS_NUM_VIEWERVERSION_XFA;
-    return TRUE;
-  }
-#endif  // PDF_ENABLE_XFA
-  vp << JS_NUM_VIEWERVERSION;
-  return TRUE;
-}
-
-FX_BOOL app::platform(IJS_Context* cc,
-                      CJS_PropValue& vp,
-                      CFX_WideString& sError) {
-  if (!vp.IsGetting())
-    return FALSE;
-#ifdef PDF_ENABLE_XFA
-  CPDFDoc_Environment* pEnv =
-      static_cast<CJS_Context*>(cc)->GetJSRuntime()->GetReaderApp();
-  if (!pEnv)
-    return FALSE;
-  CFX_WideString platfrom = pEnv->FFI_GetPlatform();
-  if (!platfrom.IsEmpty()) {
-    vp << platfrom;
-    return TRUE;
-  }
-#endif
-  vp << JS_STR_PLATFORM;
-  return TRUE;
-}
-
-FX_BOOL app::language(IJS_Context* cc,
-                      CJS_PropValue& vp,
-                      CFX_WideString& sError) {
-  if (!vp.IsGetting())
-    return FALSE;
-#ifdef PDF_ENABLE_XFA
-  CPDFDoc_Environment* pEnv =
-      static_cast<CJS_Context*>(cc)->GetJSRuntime()->GetReaderApp();
-  if (!pEnv)
-    return FALSE;
-  CFX_WideString language = pEnv->FFI_GetLanguage();
-  if (!language.IsEmpty()) {
-    vp << language;
-    return TRUE;
-  }
-#endif
-  vp << JS_STR_LANGUANGE;
-  return TRUE;
-}
-
-// creates a new fdf object that contains no data
-// comment: need reader support
-// note:
-// CFDF_Document * CPDFDoc_Environment::NewFDF();
-FX_BOOL app::newFDF(IJS_Context* cc,
-                    const std::vector<CJS_Value>& params,
-                    CJS_Value& vRet,
-                    CFX_WideString& sError) {
-  return TRUE;
-}
-// opens a specified pdf document and returns its document object
-// comment:need reader support
-// note: as defined in js reference, the proto of this function's fourth
-// parmeters, how old an fdf document while do not show it.
-// CFDF_Document * CPDFDoc_Environment::OpenFDF(string strPath,bool bUserConv);
-
-FX_BOOL app::openFDF(IJS_Context* cc,
-                     const std::vector<CJS_Value>& params,
-                     CJS_Value& vRet,
-                     CFX_WideString& sError) {
-  return TRUE;
-}
-
-FX_BOOL app::alert(IJS_Context* cc,
-                   const std::vector<CJS_Value>& params,
-                   CJS_Value& vRet,
-                   CFX_WideString& sError) {
-  int iSize = params.size();
-  if (iSize < 1)
-    return FALSE;
-
-  CFX_WideString swMsg = L"";
-  CFX_WideString swTitle = L"";
-  int iIcon = 0;
-  int iType = 0;
-
-  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
-  v8::Isolate* isolate = pRuntime->GetIsolate();
-
-  if (iSize == 1) {
-    if (params[0].GetType() == CJS_Value::VT_object) {
-      v8::Local<v8::Object> pObj = params[0].ToV8Object();
-      {
-        v8::Local<v8::Value> pValue =
-            FXJS_GetObjectElement(isolate, pObj, L"cMsg");
-        swMsg = CJS_Value(pRuntime, pValue, CJS_Value::VT_unknown)
-                    .ToCFXWideString();
-
-        pValue = FXJS_GetObjectElement(isolate, pObj, L"cTitle");
-        swTitle = CJS_Value(pRuntime, pValue, CJS_Value::VT_unknown)
-                      .ToCFXWideString();
-
-        pValue = FXJS_GetObjectElement(isolate, pObj, L"nIcon");
-        iIcon = CJS_Value(pRuntime, pValue, CJS_Value::VT_unknown).ToInt();
-
-        pValue = FXJS_GetObjectElement(isolate, pObj, L"nType");
-        iType = CJS_Value(pRuntime, pValue, CJS_Value::VT_unknown).ToInt();
-      }
-
-      if (swMsg == L"") {
-        CJS_Array carray(pRuntime);
-        if (params[0].ConvertToArray(carray)) {
-          int iLength = carray.GetLength();
-          CJS_Value* pValue = new CJS_Value(pRuntime);
-          for (int i = 0; i < iLength; ++i) {
-            carray.GetElement(i, *pValue);
-            swMsg += (*pValue).ToCFXWideString();
-            if (i < iLength - 1)
-              swMsg += L",  ";
-          }
-
-          delete pValue;
-        }
-      }
-
-      if (swTitle == L"")
-        swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
-    } else if (params[0].GetType() == CJS_Value::VT_boolean) {
-      FX_BOOL bGet = params[0].ToBool();
-      if (bGet)
-        swMsg = L"true";
-      else
-        swMsg = L"false";
-
-      swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
-    } else {
-      swMsg = params[0].ToCFXWideString();
-      swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
-    }
-  } else {
-    if (params[0].GetType() == CJS_Value::VT_boolean) {
-      FX_BOOL bGet = params[0].ToBool();
-      if (bGet)
-        swMsg = L"true";
-      else
-        swMsg = L"false";
-    } else {
-      swMsg = params[0].ToCFXWideString();
-    }
-    swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
-
-    for (int i = 1; i < iSize; i++) {
-      if (i == 1)
-        iIcon = params[i].ToInt();
-      if (i == 2)
-        iType = params[i].ToInt();
-      if (i == 3)
-        swTitle = params[i].ToCFXWideString();
-    }
-  }
-
-  pRuntime->BeginBlock();
-  vRet = MsgBox(pRuntime->GetReaderApp(), swMsg.c_str(), swTitle.c_str(), iType,
-                iIcon);
-  pRuntime->EndBlock();
-  return TRUE;
-}
-
-FX_BOOL app::beep(IJS_Context* cc,
-                  const std::vector<CJS_Value>& params,
-                  CJS_Value& vRet,
-                  CFX_WideString& sError) {
-  if (params.size() == 1) {
-    CJS_Context* pContext = (CJS_Context*)cc;
-    CJS_Runtime* pRuntime = pContext->GetJSRuntime();
-    CPDFDoc_Environment* pEnv = pRuntime->GetReaderApp();
-    pEnv->JS_appBeep(params[0].ToInt());
-    return TRUE;
-  }
-
-  sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
-  return FALSE;
-}
-
-FX_BOOL app::findComponent(IJS_Context* cc,
-                           const std::vector<CJS_Value>& params,
-                           CJS_Value& vRet,
-                           CFX_WideString& sError) {
-  return TRUE;
-}
-
-FX_BOOL app::popUpMenuEx(IJS_Context* cc,
-                         const std::vector<CJS_Value>& params,
-                         CJS_Value& vRet,
-                         CFX_WideString& sError) {
-  return FALSE;
-}
-
-FX_BOOL app::fs(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
-  return FALSE;
-}
-
-FX_BOOL app::setInterval(IJS_Context* cc,
-                         const std::vector<CJS_Value>& params,
-                         CJS_Value& vRet,
-                         CFX_WideString& sError) {
-  CJS_Context* pContext = (CJS_Context*)cc;
-  if (params.size() > 2 || params.size() == 0) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
-    return FALSE;
-  }
-
-  CFX_WideString script = params.size() > 0 ? params[0].ToCFXWideString() : L"";
-  if (script.IsEmpty()) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE);
-    return TRUE;
-  }
-
-  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
-  FX_DWORD dwInterval = params.size() > 1 ? params[1].ToInt() : 1000;
-
-  CPDFDoc_Environment* pApp = pRuntime->GetReaderApp();
-  ASSERT(pApp);
-  CJS_Timer* pTimer =
-      new CJS_Timer(this, pApp, pRuntime, 0, script, dwInterval, 0);
-  m_aTimer.Add(pTimer);
-
-  v8::Local<v8::Object> pRetObj = FXJS_NewFxDynamicObj(
-      pRuntime->GetIsolate(), pRuntime, CJS_TimerObj::g_nObjDefnID);
-  CJS_TimerObj* pJS_TimerObj =
-      (CJS_TimerObj*)FXJS_GetPrivate(pRuntime->GetIsolate(), pRetObj);
-  TimerObj* pTimerObj = (TimerObj*)pJS_TimerObj->GetEmbedObject();
-  pTimerObj->SetTimer(pTimer);
-
-  vRet = pRetObj;
-  return TRUE;
-}
-
-FX_BOOL app::setTimeOut(IJS_Context* cc,
-                        const std::vector<CJS_Value>& params,
-                        CJS_Value& vRet,
-                        CFX_WideString& sError) {
-  if (params.size() > 2 || params.size() == 0) {
-    sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
-    return FALSE;
-  }
-
-  CJS_Context* pContext = (CJS_Context*)cc;
-  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
-
-  CFX_WideString script = params.size() > 0 ? params[0].ToCFXWideString() : L"";
-  if (script.IsEmpty()) {
-    sError =
-        JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSAFNUMBER_KEYSTROKE);
-    return TRUE;
-  }
-
-  FX_DWORD dwTimeOut = params.size() > 1 ? params[1].ToInt() : 1000;
-
-  CPDFDoc_Environment* pApp = pRuntime->GetReaderApp();
-  ASSERT(pApp);
-
-  CJS_Timer* pTimer =
-      new CJS_Timer(this, pApp, pRuntime, 1, script, dwTimeOut, dwTimeOut);
-  m_aTimer.Add(pTimer);
-
-  v8::Local<v8::Object> pRetObj = FXJS_NewFxDynamicObj(
-      pRuntime->GetIsolate(), pRuntime, CJS_TimerObj::g_nObjDefnID);
-  CJS_TimerObj* pJS_TimerObj =
-      (CJS_TimerObj*)FXJS_GetPrivate(pRuntime->GetIsolate(), pRetObj);
-  TimerObj* pTimerObj = (TimerObj*)pJS_TimerObj->GetEmbedObject();
-  pTimerObj->SetTimer(pTimer);
-
-  vRet = pRetObj;
-  return TRUE;
-}
-
-FX_BOOL app::clearTimeOut(IJS_Context* cc,
-                          const std::vector<CJS_Value>& params,
-                          CJS_Value& vRet,
-                          CFX_WideString& sError) {
-  CJS_Context* pContext = (CJS_Context*)cc;
-  if (params.size() != 1) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
-    return FALSE;
-  }
-
-  if (params[0].GetType() == CJS_Value::VT_fxobject) {
-    v8::Local<v8::Object> pObj = params[0].ToV8Object();
-    if (FXJS_GetObjDefnID(pObj) == CJS_TimerObj::g_nObjDefnID) {
-      if (CJS_Object* pJSObj = params[0].ToCJSObject()) {
-        if (TimerObj* pTimerObj = (TimerObj*)pJSObj->GetEmbedObject()) {
-          if (CJS_Timer* pTimer = pTimerObj->GetTimer()) {
-            pTimer->KillJSTimer();
-
-            for (int i = 0, sz = m_aTimer.GetSize(); i < sz; i++) {
-              if (m_aTimer[i] == pTimer) {
-                m_aTimer.RemoveAt(i);
-                break;
-              }
-            }
-
-            delete pTimer;
-            pTimerObj->SetTimer(NULL);
-          }
-        }
-      }
-    }
-  }
-
-  return TRUE;
-}
-
-FX_BOOL app::clearInterval(IJS_Context* cc,
-                           const std::vector<CJS_Value>& params,
-                           CJS_Value& vRet,
-                           CFX_WideString& sError) {
-  CJS_Context* pContext = (CJS_Context*)cc;
-  if (params.size() != 1) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
-    return FALSE;
-  }
-
-  if (params[0].GetType() == CJS_Value::VT_fxobject) {
-    v8::Local<v8::Object> pObj = params[0].ToV8Object();
-    if (FXJS_GetObjDefnID(pObj) == CJS_TimerObj::g_nObjDefnID) {
-      if (CJS_Object* pJSObj = params[0].ToCJSObject()) {
-        if (TimerObj* pTimerObj = (TimerObj*)pJSObj->GetEmbedObject()) {
-          if (CJS_Timer* pTimer = pTimerObj->GetTimer()) {
-            pTimer->KillJSTimer();
-
-            for (int i = 0, sz = m_aTimer.GetSize(); i < sz; i++) {
-              if (m_aTimer[i] == pTimer) {
-                m_aTimer.RemoveAt(i);
-                break;
-              }
-            }
-
-            delete pTimer;
-            pTimerObj->SetTimer(NULL);
-          }
-        }
-      }
-    }
-  }
-
-  return TRUE;
-}
-
-FX_BOOL app::execMenuItem(IJS_Context* cc,
-                          const std::vector<CJS_Value>& params,
-                          CJS_Value& vRet,
-                          CFX_WideString& sError) {
-  return FALSE;
-}
-
-void app::TimerProc(CJS_Timer* pTimer) {
-  CJS_Runtime* pRuntime = pTimer->GetRuntime();
-
-  switch (pTimer->GetType()) {
-    case 0:  // interval
-      if (pRuntime)
-        RunJsScript(pRuntime, pTimer->GetJScript());
-      break;
-    case 1:
-      if (pTimer->GetTimeOut() > 0) {
-        if (pRuntime)
-          RunJsScript(pRuntime, pTimer->GetJScript());
-        pTimer->KillJSTimer();
-      }
-      break;
-  }
-}
-
-void app::RunJsScript(CJS_Runtime* pRuntime, const CFX_WideString& wsScript) {
-  if (!pRuntime->IsBlocking()) {
-    IJS_Context* pContext = pRuntime->NewContext();
-    pContext->OnExternal_Exec();
-    CFX_WideString wtInfo;
-    pContext->RunScript(wsScript, &wtInfo);
-    pRuntime->ReleaseContext(pContext);
-  }
-}
-
-FX_BOOL app::goBack(IJS_Context* cc,
-                    const std::vector<CJS_Value>& params,
-                    CJS_Value& vRet,
-                    CFX_WideString& sError) {
-  // Not supported.
-  return TRUE;
-}
-
-FX_BOOL app::goForward(IJS_Context* cc,
-                       const std::vector<CJS_Value>& params,
-                       CJS_Value& vRet,
-                       CFX_WideString& sError) {
-  // Not supported.
-  return TRUE;
-}
-
-FX_BOOL app::mailMsg(IJS_Context* cc,
-                     const std::vector<CJS_Value>& params,
-                     CJS_Value& vRet,
-                     CFX_WideString& sError) {
-  if (params.size() < 1)
-    return FALSE;
-
-  FX_BOOL bUI = TRUE;
-  CFX_WideString cTo = L"";
-  CFX_WideString cCc = L"";
-  CFX_WideString cBcc = L"";
-  CFX_WideString cSubject = L"";
-  CFX_WideString cMsg = L"";
-
-  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
-  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
-  v8::Isolate* isolate = pRuntime->GetIsolate();
-
-  if (params[0].GetType() == CJS_Value::VT_object) {
-    v8::Local<v8::Object> pObj = params[0].ToV8Object();
-
-    v8::Local<v8::Value> pValue = FXJS_GetObjectElement(isolate, pObj, L"bUI");
-    bUI = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToBool();
-
-    pValue = FXJS_GetObjectElement(isolate, pObj, L"cTo");
-    cTo = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
-
-    pValue = FXJS_GetObjectElement(isolate, pObj, L"cCc");
-    cCc = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
-
-    pValue = FXJS_GetObjectElement(isolate, pObj, L"cBcc");
-    cBcc =
-        CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
-
-    pValue = FXJS_GetObjectElement(isolate, pObj, L"cSubject");
-    cSubject =
-        CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
-
-    pValue = FXJS_GetObjectElement(isolate, pObj, L"cMsg");
-    cMsg =
-        CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
-  } else {
-    if (params.size() < 2)
-      return FALSE;
-
-    bUI = params[0].ToBool();
-    cTo = params[1].ToCFXWideString();
-
-    if (params.size() >= 3)
-      cCc = params[2].ToCFXWideString();
-    if (params.size() >= 4)
-      cBcc = params[3].ToCFXWideString();
-    if (params.size() >= 5)
-      cSubject = params[4].ToCFXWideString();
-    if (params.size() >= 6)
-      cMsg = params[5].ToCFXWideString();
-  }
-
-  pRuntime->BeginBlock();
-  pContext->GetReaderApp()->JS_docmailForm(NULL, 0, bUI, cTo.c_str(),
-                                           cSubject.c_str(), cCc.c_str(),
-                                           cBcc.c_str(), cMsg.c_str());
-  pRuntime->EndBlock();
-
-  return FALSE;
-}
-
-FX_BOOL app::launchURL(IJS_Context* cc,
-                       const std::vector<CJS_Value>& params,
-                       CJS_Value& vRet,
-                       CFX_WideString& sError) {
-  // Unsafe, not supported.
-  return TRUE;
-}
-
-FX_BOOL app::runtimeHighlight(IJS_Context* cc,
-                              CJS_PropValue& vp,
-                              CFX_WideString& sError) {
-  if (vp.IsSetting()) {
-    vp >> m_bRuntimeHighLight;
-  } else {
-    vp << m_bRuntimeHighLight;
-  }
-
-  return TRUE;
-}
-
-FX_BOOL app::fullscreen(IJS_Context* cc,
-                        CJS_PropValue& vp,
-                        CFX_WideString& sError) {
-  return FALSE;
-}
-
-FX_BOOL app::popUpMenu(IJS_Context* cc,
-                       const std::vector<CJS_Value>& params,
-                       CJS_Value& vRet,
-                       CFX_WideString& sError) {
-  return FALSE;
-}
-
-FX_BOOL app::browseForDoc(IJS_Context* cc,
-                          const std::vector<CJS_Value>& params,
-                          CJS_Value& vRet,
-                          CFX_WideString& sError) {
-  // Unsafe, not supported.
-  return TRUE;
-}
-
-CFX_WideString app::SysPathToPDFPath(const CFX_WideString& sOldPath) {
-  CFX_WideString sRet = L"/";
-
-  for (int i = 0, sz = sOldPath.GetLength(); i < sz; i++) {
-    wchar_t c = sOldPath.GetAt(i);
-    if (c == L':') {
-    } else {
-      if (c == L'\\') {
-        sRet += L"/";
-      } else {
-        sRet += c;
-      }
-    }
-  }
-
-  return sRet;
-}
-
-FX_BOOL app::newDoc(IJS_Context* cc,
-                    const std::vector<CJS_Value>& params,
-                    CJS_Value& vRet,
-                    CFX_WideString& sError) {
-  return FALSE;
-}
-
-FX_BOOL app::openDoc(IJS_Context* cc,
-                     const std::vector<CJS_Value>& params,
-                     CJS_Value& vRet,
-                     CFX_WideString& sError) {
-  return FALSE;
-}
-
-FX_BOOL app::response(IJS_Context* cc,
-                      const std::vector<CJS_Value>& params,
-                      CJS_Value& vRet,
-                      CFX_WideString& sError) {
-  CFX_WideString swQuestion = L"";
-  CFX_WideString swLabel = L"";
-  CFX_WideString swTitle = L"PDF";
-  CFX_WideString swDefault = L"";
-  bool bPassWord = false;
-
-  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
-  v8::Isolate* isolate = pRuntime->GetIsolate();
-
-  int iLength = params.size();
-  if (iLength > 0 && params[0].GetType() == CJS_Value::VT_object) {
-    v8::Local<v8::Object> pObj = params[0].ToV8Object();
-    v8::Local<v8::Value> pValue =
-        FXJS_GetObjectElement(isolate, pObj, L"cQuestion");
-    swQuestion =
-        CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
-
-    pValue = FXJS_GetObjectElement(isolate, pObj, L"cTitle");
-    swTitle =
-        CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
-
-    pValue = FXJS_GetObjectElement(isolate, pObj, L"cDefault");
-    swDefault =
-        CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
-
-    pValue = FXJS_GetObjectElement(isolate, pObj, L"cLabel");
-    swLabel =
-        CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
-
-    pValue = FXJS_GetObjectElement(isolate, pObj, L"bPassword");
-    bPassWord = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToBool();
-  } else {
-    switch (iLength) {
-      case 5:
-        swLabel = params[4].ToCFXWideString();
-      // FALLTHROUGH
-      case 4:
-        bPassWord = params[3].ToBool();
-      // FALLTHROUGH
-      case 3:
-        swDefault = params[2].ToCFXWideString();
-      // FALLTHROUGH
-      case 2:
-        swTitle = params[1].ToCFXWideString();
-      // FALLTHROUGH
-      case 1:
-        swQuestion = params[0].ToCFXWideString();
-      // FALLTHROUGH
-      default:
-        break;
-    }
-  }
-
-  CJS_Context* pContext = (CJS_Context*)cc;
-  CPDFDoc_Environment* pApp = pContext->GetReaderApp();
-
-  const int MAX_INPUT_BYTES = 2048;
-  std::unique_ptr<char[]> pBuff(new char[MAX_INPUT_BYTES + 2]);
-  memset(pBuff.get(), 0, MAX_INPUT_BYTES + 2);
-  int nLengthBytes = pApp->JS_appResponse(
-      swQuestion.c_str(), swTitle.c_str(), swDefault.c_str(), swLabel.c_str(),
-      bPassWord, pBuff.get(), MAX_INPUT_BYTES);
-  if (nLengthBytes <= 0) {
-    vRet.SetNull();
-    return FALSE;
-  }
-  nLengthBytes = std::min(nLengthBytes, MAX_INPUT_BYTES);
-
-  CFX_WideString ret_string = CFX_WideString::FromUTF16LE(
-      (unsigned short*)pBuff.get(), nLengthBytes / sizeof(unsigned short));
-  vRet = ret_string.c_str();
-  return TRUE;
-}
-
-FX_BOOL app::media(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
-  return FALSE;
-}
-
-FX_BOOL app::execDialog(IJS_Context* cc,
-                        const std::vector<CJS_Value>& params,
-                        CJS_Value& vRet,
-                        CFX_WideString& sError) {
-  return TRUE;
-}
diff --git a/fpdfsdk/src/javascript/app.h b/fpdfsdk/src/javascript/app.h
deleted file mode 100644
index 1eef13e..0000000
--- a/fpdfsdk/src/javascript/app.h
+++ /dev/null
@@ -1,212 +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_SRC_JAVASCRIPT_APP_H_
-#define FPDFSDK_SRC_JAVASCRIPT_APP_H_
-
-#include "JS_Define.h"
-
-class CJS_Runtime;
-
-/* ---------------------------- TimerObj ---------------------------- */
-
-class CJS_Timer;
-
-class TimerObj : public CJS_EmbedObj {
- public:
-  TimerObj(CJS_Object* pJSObject);
-  ~TimerObj() override;
-
- public:
-  void SetTimer(CJS_Timer* pTimer);
-  CJS_Timer* GetTimer() const;
-
- private:
-  CJS_Timer* m_pTimer;
-};
-
-class CJS_TimerObj : public CJS_Object {
- public:
-  CJS_TimerObj(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
-  ~CJS_TimerObj() override {}
-
-  DECLARE_JS_CLASS();
-};
-
-class app : public CJS_EmbedObj {
- public:
-  app(CJS_Object* pJSObject);
-  ~app() override;
-
- public:
-  FX_BOOL activeDocs(IJS_Context* cc,
-                     CJS_PropValue& vp,
-                     CFX_WideString& sError);
-  FX_BOOL calculate(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL formsVersion(IJS_Context* cc,
-                       CJS_PropValue& vp,
-                       CFX_WideString& sError);
-  FX_BOOL fs(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL fullscreen(IJS_Context* cc,
-                     CJS_PropValue& vp,
-                     CFX_WideString& sError);
-  FX_BOOL language(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL media(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL platform(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL runtimeHighlight(IJS_Context* cc,
-                           CJS_PropValue& vp,
-                           CFX_WideString& sError);
-  FX_BOOL viewerType(IJS_Context* cc,
-                     CJS_PropValue& vp,
-                     CFX_WideString& sError);
-  FX_BOOL viewerVariation(IJS_Context* cc,
-                          CJS_PropValue& vp,
-                          CFX_WideString& sError);
-  FX_BOOL viewerVersion(IJS_Context* cc,
-                        CJS_PropValue& vp,
-                        CFX_WideString& sError);
-
-  FX_BOOL alert(IJS_Context* cc,
-                const std::vector<CJS_Value>& params,
-                CJS_Value& vRet,
-                CFX_WideString& sError);
-  FX_BOOL beep(IJS_Context* cc,
-               const std::vector<CJS_Value>& params,
-               CJS_Value& vRet,
-               CFX_WideString& sError);
-  FX_BOOL browseForDoc(IJS_Context* cc,
-                       const std::vector<CJS_Value>& params,
-                       CJS_Value& vRet,
-                       CFX_WideString& sError);
-  FX_BOOL clearInterval(IJS_Context* cc,
-                        const std::vector<CJS_Value>& params,
-                        CJS_Value& vRet,
-                        CFX_WideString& sError);
-  FX_BOOL clearTimeOut(IJS_Context* cc,
-                       const std::vector<CJS_Value>& params,
-                       CJS_Value& vRet,
-                       CFX_WideString& sError);
-  FX_BOOL execDialog(IJS_Context* cc,
-                     const std::vector<CJS_Value>& params,
-                     CJS_Value& vRet,
-                     CFX_WideString& sError);
-  FX_BOOL execMenuItem(IJS_Context* cc,
-                       const std::vector<CJS_Value>& params,
-                       CJS_Value& vRet,
-                       CFX_WideString& sError);
-  FX_BOOL findComponent(IJS_Context* cc,
-                        const std::vector<CJS_Value>& params,
-                        CJS_Value& vRet,
-                        CFX_WideString& sError);
-  FX_BOOL goBack(IJS_Context* cc,
-                 const std::vector<CJS_Value>& params,
-                 CJS_Value& vRet,
-                 CFX_WideString& sError);
-  FX_BOOL goForward(IJS_Context* cc,
-                    const std::vector<CJS_Value>& params,
-                    CJS_Value& vRet,
-                    CFX_WideString& sError);
-  FX_BOOL launchURL(IJS_Context* cc,
-                    const std::vector<CJS_Value>& params,
-                    CJS_Value& vRet,
-                    CFX_WideString& sError);
-  FX_BOOL mailMsg(IJS_Context* cc,
-                  const std::vector<CJS_Value>& params,
-                  CJS_Value& vRet,
-                  CFX_WideString& sError);
-  FX_BOOL newFDF(IJS_Context* cc,
-                 const std::vector<CJS_Value>& params,
-                 CJS_Value& vRet,
-                 CFX_WideString& sError);
-  FX_BOOL newDoc(IJS_Context* cc,
-                 const std::vector<CJS_Value>& params,
-                 CJS_Value& vRet,
-                 CFX_WideString& sError);
-  FX_BOOL openDoc(IJS_Context* cc,
-                  const std::vector<CJS_Value>& params,
-                  CJS_Value& vRet,
-                  CFX_WideString& sError);
-  FX_BOOL openFDF(IJS_Context* cc,
-                  const std::vector<CJS_Value>& params,
-                  CJS_Value& vRet,
-                  CFX_WideString& sError);
-  FX_BOOL popUpMenuEx(IJS_Context* cc,
-                      const std::vector<CJS_Value>& params,
-                      CJS_Value& vRet,
-                      CFX_WideString& sError);
-  FX_BOOL popUpMenu(IJS_Context* cc,
-                    const std::vector<CJS_Value>& params,
-                    CJS_Value& vRet,
-                    CFX_WideString& sError);
-  FX_BOOL response(IJS_Context* cc,
-                   const std::vector<CJS_Value>& params,
-                   CJS_Value& vRet,
-                   CFX_WideString& sError);
-  FX_BOOL setInterval(IJS_Context* cc,
-                      const std::vector<CJS_Value>& params,
-                      CJS_Value& vRet,
-                      CFX_WideString& sError);
-  FX_BOOL setTimeOut(IJS_Context* cc,
-                     const std::vector<CJS_Value>& params,
-                     CJS_Value& vRet,
-                     CFX_WideString& sError);
-
-  static CFX_WideString SysPathToPDFPath(const CFX_WideString& sOldPath);
-
- private:
-  // CJS_EmbedObj
-  void TimerProc(CJS_Timer* pTimer) override;
-  void RunJsScript(CJS_Runtime* pRuntime, const CFX_WideString& wsScript);
-
-  bool m_bCalculate;
-  bool m_bRuntimeHighLight;
-  CFX_ArrayTemplate<CJS_Timer*> m_aTimer;
-};
-
-class CJS_App : public CJS_Object {
- public:
-  explicit CJS_App(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
-  ~CJS_App() override {}
-
-  DECLARE_JS_CLASS();
-
-  JS_STATIC_PROP(activeDocs, app);
-  JS_STATIC_PROP(calculate, app);
-  JS_STATIC_PROP(formsVersion, app);
-  JS_STATIC_PROP(fs, app);
-  JS_STATIC_PROP(fullscreen, app);
-  JS_STATIC_PROP(language, app);
-  JS_STATIC_PROP(media, app);
-  JS_STATIC_PROP(platform, app);
-  JS_STATIC_PROP(runtimeHighlight, app);
-  JS_STATIC_PROP(viewerType, app);
-  JS_STATIC_PROP(viewerVariation, app);
-  JS_STATIC_PROP(viewerVersion, app);
-
-  JS_STATIC_METHOD(alert, app);
-  JS_STATIC_METHOD(beep, app);
-  JS_STATIC_METHOD(browseForDoc, app);
-  JS_STATIC_METHOD(clearInterval, app);
-  JS_STATIC_METHOD(clearTimeOut, app);
-  JS_STATIC_METHOD(execDialog, app);
-  JS_STATIC_METHOD(execMenuItem, app);
-  JS_STATIC_METHOD(findComponent, app);
-  JS_STATIC_METHOD(goBack, app);
-  JS_STATIC_METHOD(goForward, app);
-  JS_STATIC_METHOD(launchURL, app);
-  JS_STATIC_METHOD(mailMsg, app);
-  JS_STATIC_METHOD(newFDF, app);
-  JS_STATIC_METHOD(newDoc, app);
-  JS_STATIC_METHOD(openDoc, app);
-  JS_STATIC_METHOD(openFDF, app);
-  JS_STATIC_METHOD(popUpMenuEx, app);
-  JS_STATIC_METHOD(popUpMenu, app);
-  JS_STATIC_METHOD(response, app);
-  JS_STATIC_METHOD(setInterval, app);
-  JS_STATIC_METHOD(setTimeOut, app);
-};
-
-#endif  // FPDFSDK_SRC_JAVASCRIPT_APP_H_
diff --git a/fpdfsdk/src/javascript/color.cpp b/fpdfsdk/src/javascript/color.cpp
deleted file mode 100644
index b9c4804..0000000
--- a/fpdfsdk/src/javascript/color.cpp
+++ /dev/null
@@ -1,222 +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
-
-#include "color.h"
-
-#include "JS_Context.h"
-#include "JS_Define.h"
-#include "JS_EventHandler.h"
-#include "JS_Object.h"
-#include "JS_Runtime.h"
-#include "JS_Value.h"
-#include "fpdfsdk/include/javascript/IJavaScript.h"
-
-/* -------------------------- color -------------------------- */
-
-BEGIN_JS_STATIC_CONST(CJS_Color)
-END_JS_STATIC_CONST()
-
-BEGIN_JS_STATIC_PROP(CJS_Color)
-JS_STATIC_PROP_ENTRY(black)
-JS_STATIC_PROP_ENTRY(blue)
-JS_STATIC_PROP_ENTRY(cyan)
-JS_STATIC_PROP_ENTRY(dkGray)
-JS_STATIC_PROP_ENTRY(gray)
-JS_STATIC_PROP_ENTRY(green)
-JS_STATIC_PROP_ENTRY(ltGray)
-JS_STATIC_PROP_ENTRY(magenta)
-JS_STATIC_PROP_ENTRY(red)
-JS_STATIC_PROP_ENTRY(transparent)
-JS_STATIC_PROP_ENTRY(white)
-JS_STATIC_PROP_ENTRY(yellow)
-END_JS_STATIC_PROP()
-
-BEGIN_JS_STATIC_METHOD(CJS_Color)
-JS_STATIC_METHOD_ENTRY(convert)
-JS_STATIC_METHOD_ENTRY(equal)
-END_JS_STATIC_METHOD()
-
-IMPLEMENT_JS_CLASS(CJS_Color, color)
-
-color::color(CJS_Object* pJSObject) : CJS_EmbedObj(pJSObject) {
-  m_crTransparent = CPWL_Color(COLORTYPE_TRANSPARENT);
-  m_crBlack = CPWL_Color(COLORTYPE_GRAY, 0);
-  m_crWhite = CPWL_Color(COLORTYPE_GRAY, 1);
-  m_crRed = CPWL_Color(COLORTYPE_RGB, 1, 0, 0);
-  m_crGreen = CPWL_Color(COLORTYPE_RGB, 0, 1, 0);
-  m_crBlue = CPWL_Color(COLORTYPE_RGB, 0, 0, 1);
-  m_crCyan = CPWL_Color(COLORTYPE_CMYK, 1, 0, 0, 0);
-  m_crMagenta = CPWL_Color(COLORTYPE_CMYK, 0, 1, 0, 0);
-  m_crYellow = CPWL_Color(COLORTYPE_CMYK, 0, 0, 1, 0);
-  m_crDKGray = CPWL_Color(COLORTYPE_GRAY, 0.25);
-  m_crGray = CPWL_Color(COLORTYPE_GRAY, 0.5);
-  m_crLTGray = CPWL_Color(COLORTYPE_GRAY, 0.75);
-}
-
-color::~color() {
-}
-
-void color::ConvertPWLColorToArray(const CPWL_Color& color, CJS_Array& array) {
-  switch (color.nColorType) {
-    case COLORTYPE_TRANSPARENT:
-      array.SetElement(0, CJS_Value(array.GetJSRuntime(), "T"));
-      break;
-    case COLORTYPE_GRAY:
-      array.SetElement(0, CJS_Value(array.GetJSRuntime(), "G"));
-      array.SetElement(1, CJS_Value(array.GetJSRuntime(), color.fColor1));
-      break;
-    case COLORTYPE_RGB:
-      array.SetElement(0, CJS_Value(array.GetJSRuntime(), "RGB"));
-      array.SetElement(1, CJS_Value(array.GetJSRuntime(), color.fColor1));
-      array.SetElement(2, CJS_Value(array.GetJSRuntime(), color.fColor2));
-      array.SetElement(3, CJS_Value(array.GetJSRuntime(), color.fColor3));
-      break;
-    case COLORTYPE_CMYK:
-      array.SetElement(0, CJS_Value(array.GetJSRuntime(), "CMYK"));
-      array.SetElement(1, CJS_Value(array.GetJSRuntime(), color.fColor1));
-      array.SetElement(2, CJS_Value(array.GetJSRuntime(), color.fColor2));
-      array.SetElement(3, CJS_Value(array.GetJSRuntime(), color.fColor3));
-      array.SetElement(4, CJS_Value(array.GetJSRuntime(), color.fColor4));
-      break;
-  }
-}
-
-void color::ConvertArrayToPWLColor(CJS_Array& array, CPWL_Color& color) {
-  int nArrayLen = array.GetLength();
-  if (nArrayLen < 1)
-    return;
-
-  CJS_Value value(array.GetJSRuntime());
-  array.GetElement(0, value);
-  CFX_ByteString sSpace = value.ToCFXByteString();
-
-  double d1 = 0;
-  double d2 = 0;
-  double d3 = 0;
-  double d4 = 0;
-
-  if (nArrayLen > 1) {
-    array.GetElement(1, value);
-    d1 = value.ToDouble();
-  }
-
-  if (nArrayLen > 2) {
-    array.GetElement(2, value);
-    d2 = value.ToDouble();
-  }
-
-  if (nArrayLen > 3) {
-    array.GetElement(3, value);
-    d3 = value.ToDouble();
-  }
-
-  if (nArrayLen > 4) {
-    array.GetElement(4, value);
-    d4 = value.ToDouble();
-  }
-
-  if (sSpace == "T") {
-    color = CPWL_Color(COLORTYPE_TRANSPARENT);
-  } else if (sSpace == "G") {
-    color = CPWL_Color(COLORTYPE_GRAY, (FX_FLOAT)d1);
-  } else if (sSpace == "RGB") {
-    color = CPWL_Color(COLORTYPE_RGB, (FX_FLOAT)d1, (FX_FLOAT)d2, (FX_FLOAT)d3);
-  } else if (sSpace == "CMYK") {
-    color = CPWL_Color(COLORTYPE_CMYK, (FX_FLOAT)d1, (FX_FLOAT)d2, (FX_FLOAT)d3,
-                       (FX_FLOAT)d4);
-  }
-}
-
-#define JS_IMPLEMENT_COLORPROP(prop, var)                 \
-  FX_BOOL color::prop(IJS_Context* cc, CJS_PropValue& vp, \
-                      CFX_WideString& sError) {           \
-    CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); \
-    CJS_Array array(pRuntime);                            \
-    if (vp.IsGetting()) {                                 \
-      ConvertPWLColorToArray(var, array);                 \
-      vp << array;                                        \
-    } else {                                              \
-      if (!vp.ConvertToArray(array))                      \
-        return FALSE;                                     \
-      ConvertArrayToPWLColor(array, var);                 \
-    }                                                     \
-    return TRUE;                                          \
-  }
-
-JS_IMPLEMENT_COLORPROP(transparent, m_crTransparent)
-JS_IMPLEMENT_COLORPROP(black, m_crBlack)
-JS_IMPLEMENT_COLORPROP(white, m_crWhite)
-JS_IMPLEMENT_COLORPROP(red, m_crRed)
-JS_IMPLEMENT_COLORPROP(green, m_crGreen)
-JS_IMPLEMENT_COLORPROP(blue, m_crBlue)
-JS_IMPLEMENT_COLORPROP(cyan, m_crCyan)
-JS_IMPLEMENT_COLORPROP(magenta, m_crMagenta)
-JS_IMPLEMENT_COLORPROP(yellow, m_crYellow)
-JS_IMPLEMENT_COLORPROP(dkGray, m_crDKGray)
-JS_IMPLEMENT_COLORPROP(gray, m_crGray)
-JS_IMPLEMENT_COLORPROP(ltGray, m_crLTGray)
-
-FX_BOOL color::convert(IJS_Context* cc,
-                       const std::vector<CJS_Value>& params,
-                       CJS_Value& vRet,
-                       CFX_WideString& sError) {
-  int iSize = params.size();
-  if (iSize < 2)
-    return FALSE;
-
-  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
-  CJS_Array aSource(pRuntime);
-  if (!params[0].ConvertToArray(aSource))
-    return FALSE;
-
-  CPWL_Color crSource;
-  ConvertArrayToPWLColor(aSource, crSource);
-
-  CFX_ByteString sDestSpace = params[1].ToCFXByteString();
-  int nColorType = COLORTYPE_TRANSPARENT;
-
-  if (sDestSpace == "T") {
-    nColorType = COLORTYPE_TRANSPARENT;
-  } else if (sDestSpace == "G") {
-    nColorType = COLORTYPE_GRAY;
-  } else if (sDestSpace == "RGB") {
-    nColorType = COLORTYPE_RGB;
-  } else if (sDestSpace == "CMYK") {
-    nColorType = COLORTYPE_CMYK;
-  }
-
-  CJS_Array aDest(pRuntime);
-  CPWL_Color crDest = crSource;
-  crDest.ConvertColorType(nColorType);
-  ConvertPWLColorToArray(crDest, aDest);
-  vRet = aDest;
-
-  return TRUE;
-}
-
-FX_BOOL color::equal(IJS_Context* cc,
-                     const std::vector<CJS_Value>& params,
-                     CJS_Value& vRet,
-                     CFX_WideString& sError) {
-  if (params.size() < 2)
-    return FALSE;
-
-  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
-  CJS_Array array1(pRuntime);
-  CJS_Array array2(pRuntime);
-  if (!params[0].ConvertToArray(array1))
-    return FALSE;
-  if (!params[1].ConvertToArray(array2))
-    return FALSE;
-
-  CPWL_Color color1;
-  CPWL_Color color2;
-  ConvertArrayToPWLColor(array1, color1);
-  ConvertArrayToPWLColor(array2, color2);
-  color1.ConvertColorType(color2.nColorType);
-  vRet = color1 == color2;
-  return TRUE;
-}
diff --git a/fpdfsdk/src/javascript/color.h b/fpdfsdk/src/javascript/color.h
deleted file mode 100644
index 0cc3f3c..0000000
--- a/fpdfsdk/src/javascript/color.h
+++ /dev/null
@@ -1,85 +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_SRC_JAVASCRIPT_COLOR_H_
-#define FPDFSDK_SRC_JAVASCRIPT_COLOR_H_
-
-#include "JS_Define.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Wnd.h"  // For CPWL_Color.
-
-class color : public CJS_EmbedObj {
- public:
-  color(CJS_Object* pJSObject);
-  ~color() override;
-
-  FX_BOOL black(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL blue(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL cyan(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL dkGray(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL gray(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL green(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL ltGray(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL magenta(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL red(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL transparent(IJS_Context* cc,
-                      CJS_PropValue& vp,
-                      CFX_WideString& sError);
-  FX_BOOL white(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL yellow(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-
-  FX_BOOL convert(IJS_Context* cc,
-                  const std::vector<CJS_Value>& params,
-                  CJS_Value& vRet,
-                  CFX_WideString& sError);
-  FX_BOOL equal(IJS_Context* cc,
-                const std::vector<CJS_Value>& params,
-                CJS_Value& vRet,
-                CFX_WideString& sError);
-
- public:
-  static void ConvertPWLColorToArray(const CPWL_Color& color, CJS_Array& array);
-  static void ConvertArrayToPWLColor(CJS_Array& array, CPWL_Color& color);
-
- private:
-  CPWL_Color m_crTransparent;
-  CPWL_Color m_crBlack;
-  CPWL_Color m_crWhite;
-  CPWL_Color m_crRed;
-  CPWL_Color m_crGreen;
-  CPWL_Color m_crBlue;
-  CPWL_Color m_crCyan;
-  CPWL_Color m_crMagenta;
-  CPWL_Color m_crYellow;
-  CPWL_Color m_crDKGray;
-  CPWL_Color m_crGray;
-  CPWL_Color m_crLTGray;
-};
-
-class CJS_Color : public CJS_Object {
- public:
-  CJS_Color(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
-  ~CJS_Color() override {}
-
-  DECLARE_JS_CLASS();
-
-  JS_STATIC_PROP(black, color);
-  JS_STATIC_PROP(blue, color);
-  JS_STATIC_PROP(cyan, color);
-  JS_STATIC_PROP(dkGray, color);
-  JS_STATIC_PROP(gray, color);
-  JS_STATIC_PROP(green, color);
-  JS_STATIC_PROP(ltGray, color);
-  JS_STATIC_PROP(magenta, color);
-  JS_STATIC_PROP(red, color);
-  JS_STATIC_PROP(transparent, color);
-  JS_STATIC_PROP(white, color);
-  JS_STATIC_PROP(yellow, color);
-
-  JS_STATIC_METHOD(convert, color);
-  JS_STATIC_METHOD(equal, color);
-};
-
-#endif  // FPDFSDK_SRC_JAVASCRIPT_COLOR_H_
diff --git a/fpdfsdk/src/javascript/console.cpp b/fpdfsdk/src/javascript/console.cpp
deleted file mode 100644
index 072e5b7..0000000
--- a/fpdfsdk/src/javascript/console.cpp
+++ /dev/null
@@ -1,66 +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
-
-#include "console.h"
-
-#include "JS_Context.h"
-#include "JS_Define.h"
-#include "JS_EventHandler.h"
-#include "JS_Object.h"
-#include "JS_Value.h"
-#include "fpdfsdk/include/javascript/IJavaScript.h"
-
-/* ------------------------ console ------------------------ */
-
-BEGIN_JS_STATIC_CONST(CJS_Console)
-END_JS_STATIC_CONST()
-
-BEGIN_JS_STATIC_PROP(CJS_Console)
-END_JS_STATIC_PROP()
-
-BEGIN_JS_STATIC_METHOD(CJS_Console)
-JS_STATIC_METHOD_ENTRY(clear)
-JS_STATIC_METHOD_ENTRY(hide)
-JS_STATIC_METHOD_ENTRY(println)
-JS_STATIC_METHOD_ENTRY(show)
-END_JS_STATIC_METHOD()
-
-IMPLEMENT_JS_CLASS(CJS_Console, console)
-
-console::console(CJS_Object* pJSObject) : CJS_EmbedObj(pJSObject) {}
-
-console::~console() {}
-
-FX_BOOL console::clear(IJS_Context* cc,
-                       const std::vector<CJS_Value>& params,
-                       CJS_Value& vRet,
-                       CFX_WideString& sError) {
-  return TRUE;
-}
-
-FX_BOOL console::hide(IJS_Context* cc,
-                      const std::vector<CJS_Value>& params,
-                      CJS_Value& vRet,
-                      CFX_WideString& sError) {
-  return TRUE;
-}
-
-FX_BOOL console::println(IJS_Context* cc,
-                         const std::vector<CJS_Value>& params,
-                         CJS_Value& vRet,
-                         CFX_WideString& sError) {
-  if (params.size() < 1) {
-    return FALSE;
-  }
-  return TRUE;
-}
-
-FX_BOOL console::show(IJS_Context* cc,
-                      const std::vector<CJS_Value>& params,
-                      CJS_Value& vRet,
-                      CFX_WideString& sError) {
-  return TRUE;
-}
diff --git a/fpdfsdk/src/javascript/console.h b/fpdfsdk/src/javascript/console.h
deleted file mode 100644
index f490104..0000000
--- a/fpdfsdk/src/javascript/console.h
+++ /dev/null
@@ -1,49 +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_SRC_JAVASCRIPT_CONSOLE_H_
-#define FPDFSDK_SRC_JAVASCRIPT_CONSOLE_H_
-
-#include "JS_Define.h"
-
-class console : public CJS_EmbedObj {
- public:
-  console(CJS_Object* pJSObject);
-  ~console() override;
-
- public:
-  FX_BOOL clear(IJS_Context* cc,
-                const std::vector<CJS_Value>& params,
-                CJS_Value& vRet,
-                CFX_WideString& sError);
-  FX_BOOL hide(IJS_Context* cc,
-               const std::vector<CJS_Value>& params,
-               CJS_Value& vRet,
-               CFX_WideString& sError);
-  FX_BOOL println(IJS_Context* cc,
-                  const std::vector<CJS_Value>& params,
-                  CJS_Value& vRet,
-                  CFX_WideString& sError);
-  FX_BOOL show(IJS_Context* cc,
-               const std::vector<CJS_Value>& params,
-               CJS_Value& vRet,
-               CFX_WideString& sError);
-};
-
-class CJS_Console : public CJS_Object {
- public:
-  CJS_Console(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
-  ~CJS_Console() override {}
-
-  DECLARE_JS_CLASS();
-
-  JS_STATIC_METHOD(clear, console);
-  JS_STATIC_METHOD(hide, console);
-  JS_STATIC_METHOD(println, console);
-  JS_STATIC_METHOD(show, console);
-};
-
-#endif  // FPDFSDK_SRC_JAVASCRIPT_CONSOLE_H_
diff --git a/fpdfsdk/src/javascript/event.h b/fpdfsdk/src/javascript/event.h
deleted file mode 100644
index 7ebe571..0000000
--- a/fpdfsdk/src/javascript/event.h
+++ /dev/null
@@ -1,76 +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_SRC_JAVASCRIPT_EVENT_H_
-#define FPDFSDK_SRC_JAVASCRIPT_EVENT_H_
-
-#include "JS_Define.h"
-
-class event : public CJS_EmbedObj {
- public:
-  event(CJS_Object* pJSObject);
-  ~event() override;
-
- public:
-  FX_BOOL change(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL changeEx(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL commitKey(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL fieldFull(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL keyDown(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL modifier(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL name(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL rc(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL richChange(IJS_Context* cc,
-                     CJS_PropValue& vp,
-                     CFX_WideString& sError);
-  FX_BOOL richChangeEx(IJS_Context* cc,
-                       CJS_PropValue& vp,
-                       CFX_WideString& sError);
-  FX_BOOL richValue(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL selEnd(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL selStart(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL shift(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL source(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL target(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL targetName(IJS_Context* cc,
-                     CJS_PropValue& vp,
-                     CFX_WideString& sError);
-  FX_BOOL type(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL value(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
-  FX_BOOL willCommit(IJS_Context* cc,
-                     CJS_PropValue& vp,
-                     CFX_WideString& sError);
-};
-
-class CJS_Event : public CJS_Object {
- public:
-  CJS_Event(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
-  ~CJS_Event() override {}
-
-  DECLARE_JS_CLASS();
-  JS_STATIC_PROP(change, event);
-  JS_STATIC_PROP(changeEx, event);
-  JS_STATIC_PROP(commitKey, event);
-  JS_STATIC_PROP(fieldFull, event);
-  JS_STATIC_PROP(keyDown, event);
-  JS_STATIC_PROP(modifier, event);
-  JS_STATIC_PROP(name, event);
-  JS_STATIC_PROP(rc, event);
-  JS_STATIC_PROP(richChange, event);
-  JS_STATIC_PROP(richChangeEx, event);
-  JS_STATIC_PROP(richValue, event);
-  JS_STATIC_PROP(selEnd, event);
-  JS_STATIC_PROP(selStart, event);
-  JS_STATIC_PROP(shift, event);
-  JS_STATIC_PROP(source, event);
-  JS_STATIC_PROP(target, event);
-  JS_STATIC_PROP(targetName, event);
-  JS_STATIC_PROP(type, event);
-  JS_STATIC_PROP(value, event);
-  JS_STATIC_PROP(willCommit, event);
-};
-
-#endif  // FPDFSDK_SRC_JAVASCRIPT_EVENT_H_
diff --git a/fpdfsdk/src/javascript/global.cpp b/fpdfsdk/src/javascript/global.cpp
deleted file mode 100644
index 7a43b67..0000000
--- a/fpdfsdk/src/javascript/global.cpp
+++ /dev/null
@@ -1,519 +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
-
-#include "global.h"
-
-#include "JS_Context.h"
-#include "JS_Define.h"
-#include "JS_EventHandler.h"
-#include "JS_GlobalData.h"
-#include "JS_Object.h"
-#include "JS_Value.h"
-#include "core/include/fxcrt/fx_ext.h"
-#include "fpdfsdk/include/javascript/IJavaScript.h"
-#include "resource.h"
-
-/* ---------------------------- global ---------------------------- */
-
-// Helper class for compile-time calculation of hash values in order to
-// avoid having global object initializers.
-template <unsigned ACC, wchar_t... Ns>
-struct CHash;
-
-// Only needed to hash single-character strings.
-template <wchar_t N>
-struct CHash<N> {
-  static const unsigned value = N;
-};
-
-template <unsigned ACC, wchar_t N>
-struct CHash<ACC, N> {
-  static const unsigned value = (ACC * 1313LLU + N) & 0xFFFFFFFF;
-};
-
-template <unsigned ACC, wchar_t N, wchar_t... Ns>
-struct CHash<ACC, N, Ns...> {
-  static const unsigned value = CHash<CHash<ACC, N>::value, Ns...>::value;
-};
-
-const unsigned int JSCONST_nStringHash =
-    CHash<'s', 't', 'r', 'i', 'n', 'g'>::value;
-const unsigned int JSCONST_nNumberHash =
-    CHash<'n', 'u', 'm', 'b', 'e', 'r'>::value;
-const unsigned int JSCONST_nBoolHash =
-    CHash<'b', 'o', 'o', 'l', 'e', 'a', 'n'>::value;
-const unsigned int JSCONST_nDateHash = CHash<'d', 'a', 't', 'e'>::value;
-const unsigned int JSCONST_nObjectHash =
-    CHash<'o', 'b', 'j', 'e', 'c', 't'>::value;
-const unsigned int JSCONST_nFXobjHash = CHash<'f', 'x', 'o', 'b', 'j'>::value;
-const unsigned int JSCONST_nNullHash = CHash<'n', 'u', 'l', 'l'>::value;
-const unsigned int JSCONST_nUndefHash =
-    CHash<'u', 'n', 'd', 'e', 'f', 'i', 'n', 'e', 'd'>::value;
-
-static unsigned JS_CalcHash(const wchar_t* main) {
-  return (unsigned)FX_HashCode_String_GetW(main, FXSYS_wcslen(main));
-}
-
-#ifdef _DEBUG
-class HashVerify {
- public:
-  HashVerify();
-} g_hashVerify;
-
-HashVerify::HashVerify() {
-  ASSERT(JSCONST_nStringHash == JS_CalcHash(kFXJSValueNameString));
-  ASSERT(JSCONST_nNumberHash == JS_CalcHash(kFXJSValueNameNumber));
-  ASSERT(JSCONST_nBoolHash == JS_CalcHash(kFXJSValueNameBoolean));
-  ASSERT(JSCONST_nDateHash == JS_CalcHash(kFXJSValueNameDate));
-  ASSERT(JSCONST_nObjectHash == JS_CalcHash(kFXJSValueNameObject));
-  ASSERT(JSCONST_nFXobjHash == JS_CalcHash(kFXJSValueNameFxobj));
-  ASSERT(JSCONST_nNullHash == JS_CalcHash(kFXJSValueNameNull));
-  ASSERT(JSCONST_nUndefHash == JS_CalcHash(kFXJSValueNameUndefined));
-}
-#endif
-
-BEGIN_JS_STATIC_CONST(CJS_Global)
-END_JS_STATIC_CONST()
-
-BEGIN_JS_STATIC_PROP(CJS_Global)
-END_JS_STATIC_PROP()
-
-BEGIN_JS_STATIC_METHOD(CJS_Global)
-JS_STATIC_METHOD_ENTRY(setPersistent)
-END_JS_STATIC_METHOD()
-
-IMPLEMENT_SPECIAL_JS_CLASS(CJS_Global, JSGlobalAlternate, global);
-
-void CJS_Global::InitInstance(IJS_Runtime* pIRuntime) {
-  CJS_Runtime* pRuntime = static_cast<CJS_Runtime*>(pIRuntime);
-  JSGlobalAlternate* pGlobal =
-      static_cast<JSGlobalAlternate*>(GetEmbedObject());
-  pGlobal->Initial(pRuntime->GetReaderApp());
-}
-
-JSGlobalAlternate::JSGlobalAlternate(CJS_Object* pJSObject)
-    : CJS_EmbedObj(pJSObject), m_pApp(NULL) {
-}
-
-JSGlobalAlternate::~JSGlobalAlternate() {
-  DestroyGlobalPersisitentVariables();
-  m_pGlobalData->Release();
-}
-
-void JSGlobalAlternate::Initial(CPDFDoc_Environment* pApp) {
-  m_pApp = pApp;
-  m_pGlobalData = CJS_GlobalData::GetRetainedInstance(pApp);
-  UpdateGlobalPersistentVariables();
-}
-
-FX_BOOL JSGlobalAlternate::QueryProperty(const FX_WCHAR* propname) {
-  return CFX_WideString(propname) != L"setPersistent";
-}
-
-FX_BOOL JSGlobalAlternate::DelProperty(IJS_Context* cc,
-                                       const FX_WCHAR* propname,
-                                       CFX_WideString& sError) {
-  auto it = m_mapGlobal.find(CFX_ByteString::FromUnicode(propname));
-  if (it == m_mapGlobal.end())
-    return FALSE;
-
-  it->second->bDeleted = TRUE;
-  return TRUE;
-}
-
-FX_BOOL JSGlobalAlternate::DoProperty(IJS_Context* cc,
-                                      const FX_WCHAR* propname,
-                                      CJS_PropValue& vp,
-                                      CFX_WideString& sError) {
-  if (vp.IsSetting()) {
-    CFX_ByteString sPropName = CFX_ByteString::FromUnicode(propname);
-    switch (vp.GetType()) {
-      case CJS_Value::VT_number: {
-        double dData;
-        vp >> dData;
-        return SetGlobalVariables(sPropName, JS_GLOBALDATA_TYPE_NUMBER, dData,
-                                  false, "", v8::Local<v8::Object>(), FALSE);
-      }
-      case CJS_Value::VT_boolean: {
-        bool bData;
-        vp >> bData;
-        return SetGlobalVariables(sPropName, JS_GLOBALDATA_TYPE_BOOLEAN, 0,
-                                  bData, "", v8::Local<v8::Object>(), FALSE);
-      }
-      case CJS_Value::VT_string: {
-        CFX_ByteString sData;
-        vp >> sData;
-        return SetGlobalVariables(sPropName, JS_GLOBALDATA_TYPE_STRING, 0,
-                                  false, sData, v8::Local<v8::Object>(), FALSE);
-      }
-      case CJS_Value::VT_object: {
-        v8::Local<v8::Object> pData;
-        vp >> pData;
-        return SetGlobalVariables(sPropName, JS_GLOBALDATA_TYPE_OBJECT, 0,
-                                  false, "", pData, FALSE);
-      }
-      case CJS_Value::VT_null: {
-        return SetGlobalVariables(sPropName, JS_GLOBALDATA_TYPE_NULL, 0, false,
-                                  "", v8::Local<v8::Object>(), FALSE);
-      }
-      case CJS_Value::VT_undefined: {
-        DelProperty(cc, propname, sError);
-        return TRUE;
-      }
-      default:
-        break;
-    }
-  } else {
-    auto it = m_mapGlobal.find(CFX_ByteString::FromUnicode(propname));
-    if (it == m_mapGlobal.end()) {
-      vp.SetNull();
-      return TRUE;
-    }
-    JSGlobalData* pData = it->second;
-    if (pData->bDeleted) {
-      vp.SetNull();
-      return TRUE;
-    }
-    switch (pData->nType) {
-      case JS_GLOBALDATA_TYPE_NUMBER:
-        vp << pData->dData;
-        return TRUE;
-      case JS_GLOBALDATA_TYPE_BOOLEAN:
-        vp << pData->bData;
-        return TRUE;
-      case JS_GLOBALDATA_TYPE_STRING:
-        vp << pData->sData;
-        return TRUE;
-      case JS_GLOBALDATA_TYPE_OBJECT: {
-        v8::Local<v8::Object> obj = v8::Local<v8::Object>::New(
-            vp.GetJSRuntime()->GetIsolate(), pData->pData);
-        vp << obj;
-        return TRUE;
-      }
-      case JS_GLOBALDATA_TYPE_NULL:
-        vp.SetNull();
-        return TRUE;
-      default:
-        break;
-    }
-  }
-  return FALSE;
-}
-
-FX_BOOL JSGlobalAlternate::setPersistent(IJS_Context* cc,
-                                         const std::vector<CJS_Value>& params,
-                                         CJS_Value& vRet,
-                                         CFX_WideString& sError) {
-  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
-  if (params.size() != 2) {
-    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
-    return FALSE;
-  }
-
-  auto it = m_mapGlobal.find(params[0].ToCFXByteString());
-  if (it != m_mapGlobal.end()) {
-    JSGlobalData* pData = it->second;
-    if (!pData->bDeleted) {
-      pData->bPersistent = params[1].ToBool();
-      return TRUE;
-    }
-  }
-
-  sError = JSGetStringFromID(pContext, IDS_STRING_JSNOGLOBAL);
-  return FALSE;
-}
-
-void JSGlobalAlternate::UpdateGlobalPersistentVariables() {
-  for (int i = 0, sz = m_pGlobalData->GetSize(); i < sz; i++) {
-    CJS_GlobalData_Element* pData = m_pGlobalData->GetAt(i);
-    switch (pData->data.nType) {
-      case JS_GLOBALDATA_TYPE_NUMBER:
-        SetGlobalVariables(pData->data.sKey, JS_GLOBALDATA_TYPE_NUMBER,
-                           pData->data.dData, false, "",
-                           v8::Local<v8::Object>(), pData->bPersistent == 1);
-        FXJS_PutObjectNumber(NULL, m_pJSObject->ToV8Object(),
-                             pData->data.sKey.UTF8Decode().c_str(),
-                             pData->data.dData);
-        break;
-      case JS_GLOBALDATA_TYPE_BOOLEAN:
-        SetGlobalVariables(pData->data.sKey, JS_GLOBALDATA_TYPE_BOOLEAN, 0,
-                           (bool)(pData->data.bData == 1), "",
-                           v8::Local<v8::Object>(), pData->bPersistent == 1);
-        FXJS_PutObjectBoolean(NULL, m_pJSObject->ToV8Object(),
-                              pData->data.sKey.UTF8Decode().c_str(),
-                              (bool)(pData->data.bData == 1));
-        break;
-      case JS_GLOBALDATA_TYPE_STRING:
-        SetGlobalVariables(pData->data.sKey, JS_GLOBALDATA_TYPE_STRING, 0,
-                           false, pData->data.sData, v8::Local<v8::Object>(),
-                           pData->bPersistent == 1);
-        FXJS_PutObjectString(NULL, m_pJSObject->ToV8Object(),
-                             pData->data.sKey.UTF8Decode().c_str(),
-                             pData->data.sData.UTF8Decode().c_str());
-        break;
-      case JS_GLOBALDATA_TYPE_OBJECT: {
-        v8::Isolate* pRuntime = m_pJSObject->ToV8Object()->GetIsolate();
-        v8::Local<v8::Object> pObj = FXJS_NewFxDynamicObj(pRuntime, NULL, -1);
-
-        PutObjectProperty(pObj, &pData->data);
-
-        SetGlobalVariables(pData->data.sKey, JS_GLOBALDATA_TYPE_OBJECT, 0,
-                           false, "", pObj, pData->bPersistent == 1);
-        FXJS_PutObjectObject(NULL, m_pJSObject->ToV8Object(),
-                             pData->data.sKey.UTF8Decode().c_str(), pObj);
-
-      } break;
-      case JS_GLOBALDATA_TYPE_NULL:
-        SetGlobalVariables(pData->data.sKey, JS_GLOBALDATA_TYPE_NULL, 0, false,
-                           "", v8::Local<v8::Object>(),
-                           pData->bPersistent == 1);
-        FXJS_PutObjectNull(NULL, m_pJSObject->ToV8Object(),
-                           pData->data.sKey.UTF8Decode().c_str());
-        break;
-    }
-  }
-}
-
-void JSGlobalAlternate::CommitGlobalPersisitentVariables(IJS_Context* cc) {
-  for (auto it = m_mapGlobal.begin(); it != m_mapGlobal.end(); ++it) {
-    CFX_ByteString name = it->first;
-    JSGlobalData* pData = it->second;
-    if (pData->bDeleted) {
-      m_pGlobalData->DeleteGlobalVariable(name);
-    } else {
-      switch (pData->nType) {
-        case JS_GLOBALDATA_TYPE_NUMBER:
-          m_pGlobalData->SetGlobalVariableNumber(name, pData->dData);
-          m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
-          break;
-        case JS_GLOBALDATA_TYPE_BOOLEAN:
-          m_pGlobalData->SetGlobalVariableBoolean(name, pData->bData);
-          m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
-          break;
-        case JS_GLOBALDATA_TYPE_STRING:
-          m_pGlobalData->SetGlobalVariableString(name, pData->sData);
-          m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
-          break;
-        case JS_GLOBALDATA_TYPE_OBJECT:
-          {
-            CJS_GlobalVariableArray array;
-            v8::Local<v8::Object> obj = v8::Local<v8::Object>::New(
-                GetJSObject()->GetIsolate(), pData->pData);
-            ObjectToArray(cc, obj, array);
-            m_pGlobalData->SetGlobalVariableObject(name, array);
-            m_pGlobalData->SetGlobalVariablePersistent(name,
-                                                       pData->bPersistent);
-          }
-          break;
-        case JS_GLOBALDATA_TYPE_NULL:
-          m_pGlobalData->SetGlobalVariableNull(name);
-          m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
-          break;
-      }
-    }
-  }
-}
-
-void JSGlobalAlternate::ObjectToArray(IJS_Context* cc,
-                                      v8::Local<v8::Object> pObj,
-                                      CJS_GlobalVariableArray& array) {
-  v8::Isolate* isolate = pObj->GetIsolate();
-  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
-
-  v8::Local<v8::Array> pKeyList = FXJS_GetObjectElementNames(isolate, pObj);
-  int nObjElements = pKeyList->Length();
-  for (int i = 0; i < nObjElements; i++) {
-    CFX_WideString ws =
-        FXJS_ToString(isolate, FXJS_GetArrayElement(isolate, pKeyList, i));
-    CFX_ByteString sKey = ws.UTF8Encode();
-
-    v8::Local<v8::Value> v = FXJS_GetObjectElement(isolate, pObj, ws.c_str());
-    switch (GET_VALUE_TYPE(v)) {
-      case CJS_Value::VT_number: {
-        CJS_KeyValue* pObjElement = new CJS_KeyValue;
-        pObjElement->nType = JS_GLOBALDATA_TYPE_NUMBER;
-        pObjElement->sKey = sKey;
-        pObjElement->dData = FXJS_ToNumber(isolate, v);
-        array.Add(pObjElement);
-      } break;
-      case CJS_Value::VT_boolean: {
-        CJS_KeyValue* pObjElement = new CJS_KeyValue;
-        pObjElement->nType = JS_GLOBALDATA_TYPE_BOOLEAN;
-        pObjElement->sKey = sKey;
-        pObjElement->dData = FXJS_ToBoolean(isolate, v);
-        array.Add(pObjElement);
-      } break;
-      case CJS_Value::VT_string: {
-        CFX_ByteString sValue =
-            CJS_Value(pRuntime, v, CJS_Value::VT_string).ToCFXByteString();
-        CJS_KeyValue* pObjElement = new CJS_KeyValue;
-        pObjElement->nType = JS_GLOBALDATA_TYPE_STRING;
-        pObjElement->sKey = sKey;
-        pObjElement->sData = sValue;
-        array.Add(pObjElement);
-      } break;
-      case CJS_Value::VT_object: {
-        CJS_KeyValue* pObjElement = new CJS_KeyValue;
-        pObjElement->nType = JS_GLOBALDATA_TYPE_OBJECT;
-        pObjElement->sKey = sKey;
-        ObjectToArray(cc, FXJS_ToObject(isolate, v), pObjElement->objData);
-        array.Add(pObjElement);
-      } break;
-      case CJS_Value::VT_null: {
-        CJS_KeyValue* pObjElement = new CJS_KeyValue;
-        pObjElement->nType = JS_GLOBALDATA_TYPE_NULL;
-        pObjElement->sKey = sKey;
-        array.Add(pObjElement);
-      } break;
-      default:
-        break;
-    }
-  }
-}
-
-void JSGlobalAlternate::PutObjectProperty(v8::Local<v8::Object> pObj,
-                                          CJS_KeyValue* pData) {
-  for (int i = 0, sz = pData->objData.Count(); i < sz; i++) {
-    CJS_KeyValue* pObjData = pData->objData.GetAt(i);
-    switch (pObjData->nType) {
-      case JS_GLOBALDATA_TYPE_NUMBER:
-        FXJS_PutObjectNumber(NULL, pObj, pObjData->sKey.UTF8Decode().c_str(),
-                             pObjData->dData);
-        break;
-      case JS_GLOBALDATA_TYPE_BOOLEAN:
-        FXJS_PutObjectBoolean(NULL, pObj, pObjData->sKey.UTF8Decode().c_str(),
-                              pObjData->bData == 1);
-        break;
-      case JS_GLOBALDATA_TYPE_STRING:
-        FXJS_PutObjectString(NULL, pObj, pObjData->sKey.UTF8Decode().c_str(),
-                             pObjData->sData.UTF8Decode().c_str());
-        break;
-      case JS_GLOBALDATA_TYPE_OBJECT: {
-        v8::Isolate* pRuntime = m_pJSObject->ToV8Object()->GetIsolate();
-        v8::Local<v8::Object> pNewObj =
-            FXJS_NewFxDynamicObj(pRuntime, NULL, -1);
-        PutObjectProperty(pNewObj, pObjData);
-        FXJS_PutObjectObject(NULL, pObj, pObjData->sKey.UTF8Decode().c_str(),
-                             pNewObj);
-      } break;
-      case JS_GLOBALDATA_TYPE_NULL:
-        FXJS_PutObjectNull(NULL, pObj, pObjData->sKey.UTF8Decode().c_str());
-        break;
-    }
-  }
-}
-
-void JSGlobalAlternate::DestroyGlobalPersisitentVariables() {
-  for (const auto& pair : m_mapGlobal) {
-    delete pair.second;
-  }
-  m_mapGlobal.clear();
-}
-
-FX_BOOL JSGlobalAlternate::SetGlobalVariables(const FX_CHAR* propname,
-                                              int nType,
-                                              double dData,
-                                              bool bData,
-                                              const CFX_ByteString& sData,
-                                              v8::Local<v8::Object> pData,
-                                              bool bDefaultPersistent) {
-  if (!propname)
-    return FALSE;
-
-  auto it = m_mapGlobal.find(propname);
-  if (it != m_mapGlobal.end()) {
-    JSGlobalData* pTemp = it->second;
-    if (pTemp->bDeleted || pTemp->nType != nType) {
-      pTemp->dData = 0;
-      pTemp->bData = 0;
-      pTemp->sData = "";
-      pTemp->nType = nType;
-    }
-
-    pTemp->bDeleted = FALSE;
-    switch (nType) {
-      case JS_GLOBALDATA_TYPE_NUMBER: {
-        pTemp->dData = dData;
-      } break;
-      case JS_GLOBALDATA_TYPE_BOOLEAN: {
-        pTemp->bData = bData;
-      } break;
-      case JS_GLOBALDATA_TYPE_STRING: {
-        pTemp->sData = sData;
-      } break;
-      case JS_GLOBALDATA_TYPE_OBJECT: {
-        pTemp->pData.Reset(pData->GetIsolate(), pData);
-      } break;
-      case JS_GLOBALDATA_TYPE_NULL:
-        break;
-      default:
-        return FALSE;
-    }
-    return TRUE;
-  }
-
-  JSGlobalData* pNewData = NULL;
-
-  switch (nType) {
-    case JS_GLOBALDATA_TYPE_NUMBER: {
-      pNewData = new JSGlobalData;
-      pNewData->nType = JS_GLOBALDATA_TYPE_NUMBER;
-      pNewData->dData = dData;
-      pNewData->bPersistent = bDefaultPersistent;
-    } break;
-    case JS_GLOBALDATA_TYPE_BOOLEAN: {
-      pNewData = new JSGlobalData;
-      pNewData->nType = JS_GLOBALDATA_TYPE_BOOLEAN;
-      pNewData->bData = bData;
-      pNewData->bPersistent = bDefaultPersistent;
-    } break;
-    case JS_GLOBALDATA_TYPE_STRING: {
-      pNewData = new JSGlobalData;
-      pNewData->nType = JS_GLOBALDATA_TYPE_STRING;
-      pNewData->sData = sData;
-      pNewData->bPersistent = bDefaultPersistent;
-    } break;
-    case JS_GLOBALDATA_TYPE_OBJECT: {
-      pNewData = new JSGlobalData;
-      pNewData->nType = JS_GLOBALDATA_TYPE_OBJECT;
-      pNewData->pData.Reset(pData->GetIsolate(), pData);
-      pNewData->bPersistent = bDefaultPersistent;
-    } break;
-    case JS_GLOBALDATA_TYPE_NULL: {
-      pNewData = new JSGlobalData;
-      pNewData->nType = JS_GLOBALDATA_TYPE_NULL;
-      pNewData->bPersistent = bDefaultPersistent;
-    } break;
-    default:
-      return FALSE;
-  }
-
-  m_mapGlobal[propname] = pNewData;
-  return TRUE;
-}
-
-CJS_Value::Type GET_VALUE_TYPE(v8::Local<v8::Value> p) {
-  const unsigned int nHash = JS_CalcHash(FXJS_GetTypeof(p));
-
-  if (nHash == JSCONST_nUndefHash)
-    return CJS_Value::VT_undefined;
-  if (nHash == JSCONST_nNullHash)
-    return CJS_Value::VT_null;
-  if (nHash == JSCONST_nStringHash)
-    return CJS_Value::VT_string;
-  if (nHash == JSCONST_nNumberHash)
-    return CJS_Value::VT_number;
-  if (nHash == JSCONST_nBoolHash)
-    return CJS_Value::VT_boolean;
-  if (nHash == JSCONST_nDateHash)
-    return CJS_Value::VT_date;
-  if (nHash == JSCONST_nObjectHash)
-    return CJS_Value::VT_object;
-  if (nHash == JSCONST_nFXobjHash)
-    return CJS_Value::VT_fxobject;
-
-  return CJS_Value::VT_unknown;
-}
diff --git a/fpdfsdk/src/javascript/global.h b/fpdfsdk/src/javascript/global.h
deleted file mode 100644
index 6d2f632..0000000
--- a/fpdfsdk/src/javascript/global.h
+++ /dev/null
@@ -1,91 +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_SRC_JAVASCRIPT_GLOBAL_H_
-#define FPDFSDK_SRC_JAVASCRIPT_GLOBAL_H_
-
-#include <map>
-
-#include "JS_Define.h"
-
-class CJS_GlobalData;
-class CJS_GlobalVariableArray;
-class CJS_KeyValue;
-
-struct JSGlobalData {
-  JSGlobalData() {
-    nType = 0;
-    dData = 0;
-    bData = FALSE;
-    sData = "";
-    bPersistent = FALSE;
-    bDeleted = FALSE;
-  }
-
-  ~JSGlobalData() { pData.Reset(); }
-  int nType;  // 0:int 1:bool 2:string 3:obj
-  double dData;
-  bool bData;
-  CFX_ByteString sData;
-  v8::Global<v8::Object> pData;
-  bool bPersistent;
-  bool bDeleted;
-};
-
-class JSGlobalAlternate : public CJS_EmbedObj {
- public:
-  JSGlobalAlternate(CJS_Object* pJSObject);
-  ~JSGlobalAlternate() override;
-
-  FX_BOOL setPersistent(IJS_Context* cc,
-                        const std::vector<CJS_Value>& params,
-                        CJS_Value& vRet,
-                        CFX_WideString& sError);
-  FX_BOOL QueryProperty(const FX_WCHAR* propname);
-  FX_BOOL DoProperty(IJS_Context* cc,
-                     const FX_WCHAR* propname,
-                     CJS_PropValue& vp,
-                     CFX_WideString& sError);
-  FX_BOOL DelProperty(IJS_Context* cc,
-                      const FX_WCHAR* propname,
-                      CFX_WideString& sError);
-  void Initial(CPDFDoc_Environment* pApp);
-
- private:
-  void UpdateGlobalPersistentVariables();
-  void CommitGlobalPersisitentVariables(IJS_Context* cc);
-  void DestroyGlobalPersisitentVariables();
-  FX_BOOL SetGlobalVariables(const FX_CHAR* propname,
-                             int nType,
-                             double dData,
-                             bool bData,
-                             const CFX_ByteString& sData,
-                             v8::Local<v8::Object> pData,
-                             bool bDefaultPersistent);
-  void ObjectToArray(IJS_Context* cc,
-                     v8::Local<v8::Object> pObj,
-                     CJS_GlobalVariableArray& array);
-  void PutObjectProperty(v8::Local<v8::Object> obj, CJS_KeyValue* pData);
-
-  std::map<CFX_ByteString, JSGlobalData*> m_mapGlobal;
-  CFX_WideString m_sFilePath;
-  CJS_GlobalData* m_pGlobalData;
-  CPDFDoc_Environment* m_pApp;
-};
-
-class CJS_Global : public CJS_Object {
- public:
-  explicit CJS_Global(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
-  ~CJS_Global() override {}
-
-  // CJS_Object
-  void InitInstance(IJS_Runtime* pIRuntime) override;
-
-  DECLARE_SPECIAL_JS_CLASS();
-  JS_SPECIAL_STATIC_METHOD(setPersistent, JSGlobalAlternate, global);
-};
-
-#endif  // FPDFSDK_SRC_JAVASCRIPT_GLOBAL_H_
diff --git a/fpdfsdk/src/javascript/report.cpp b/fpdfsdk/src/javascript/report.cpp
deleted file mode 100644
index 2ec07fb..0000000
--- a/fpdfsdk/src/javascript/report.cpp
+++ /dev/null
@@ -1,47 +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
-
-#include "report.h"
-
-#include "JS_Define.h"
-#include "JS_Object.h"
-#include "JS_Value.h"
-#include "fpdfsdk/include/javascript/IJavaScript.h"
-
-/* ---------------------- report ---------------------- */
-
-BEGIN_JS_STATIC_CONST(CJS_Report)
-END_JS_STATIC_CONST()
-
-BEGIN_JS_STATIC_PROP(CJS_Report)
-END_JS_STATIC_PROP()
-
-BEGIN_JS_STATIC_METHOD(CJS_Report)
-JS_STATIC_METHOD_ENTRY(save)
-JS_STATIC_METHOD_ENTRY(writeText)
-END_JS_STATIC_METHOD()
-
-IMPLEMENT_JS_CLASS(CJS_Report, Report)
-
-Report::Report(CJS_Object* pJSObject) : CJS_EmbedObj(pJSObject) {}
-
-Report::~Report() {}
-
-FX_BOOL Report::writeText(IJS_Context* cc,
-                          const std::vector<CJS_Value>& params,
-                          CJS_Value& vRet,
-                          CFX_WideString& sError) {
-  // Unsafe, not supported.
-  return TRUE;
-}
-
-FX_BOOL Report::save(IJS_Context* cc,
-                     const std::vector<CJS_Value>& params,
-                     CJS_Value& vRet,
-                     CFX_WideString& sError) {
-  // Unsafe, not supported.
-  return TRUE;
-}
diff --git a/fpdfsdk/src/javascript/report.h b/fpdfsdk/src/javascript/report.h
deleted file mode 100644
index 36d1f68..0000000
--- a/fpdfsdk/src/javascript/report.h
+++ /dev/null
@@ -1,39 +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_SRC_JAVASCRIPT_REPORT_H_
-#define FPDFSDK_SRC_JAVASCRIPT_REPORT_H_
-
-#include "JS_Define.h"
-
-class Report : public CJS_EmbedObj {
- public:
-  Report(CJS_Object* pJSObject);
-  ~Report() override;
-
- public:
-  FX_BOOL save(IJS_Context* cc,
-               const std::vector<CJS_Value>& params,
-               CJS_Value& vRet,
-               CFX_WideString& sError);
-  FX_BOOL writeText(IJS_Context* cc,
-                    const std::vector<CJS_Value>& params,
-                    CJS_Value& vRet,
-                    CFX_WideString& sError);
-};
-
-class CJS_Report : public CJS_Object {
- public:
-  CJS_Report(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
-  ~CJS_Report() override {}
-
-  DECLARE_JS_CLASS();
-
-  JS_STATIC_METHOD(save, Report)
-  JS_STATIC_METHOD(writeText, Report);
-};
-
-#endif  // FPDFSDK_SRC_JAVASCRIPT_REPORT_H_
diff --git a/fpdfsdk/src/javascript/util.cpp b/fpdfsdk/src/javascript/util.cpp
deleted file mode 100644
index fd08d49..0000000
--- a/fpdfsdk/src/javascript/util.cpp
+++ /dev/null
@@ -1,552 +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
-
-#include "fpdfsdk/src/javascript/util.h"
-
-#include <time.h>
-
-#include "core/include/fxcrt/fx_ext.h"
-#include "fpdfsdk/include/javascript/IJavaScript.h"
-#include "fpdfsdk/src/javascript/JS_Context.h"
-#include "fpdfsdk/src/javascript/JS_Define.h"
-#include "fpdfsdk/src/javascript/JS_EventHandler.h"
-#include "fpdfsdk/src/javascript/JS_Object.h"
-#include "fpdfsdk/src/javascript/JS_Runtime.h"
-#include "fpdfsdk/src/javascript/JS_Value.h"
-#include "fpdfsdk/src/javascript/PublicMethods.h"
-#include "fpdfsdk/src/javascript/resource.h"
-
-#if _FX_OS_ == _FX_ANDROID_
-#include <ctype.h>
-#endif
-
-BEGIN_JS_STATIC_CONST(CJS_Util)
-END_JS_STATIC_CONST()
-
-BEGIN_JS_STATIC_PROP(CJS_Util)
-END_JS_STATIC_PROP()
-
-BEGIN_JS_STATIC_METHOD(CJS_Util)
-JS_STATIC_METHOD_ENTRY(printd)
-JS_STATIC_METHOD_ENTRY(printf)
-JS_STATIC_METHOD_ENTRY(printx)
-JS_STATIC_METHOD_ENTRY(scand)
-JS_STATIC_METHOD_ENTRY(byteToChar)
-END_JS_STATIC_METHOD()
-
-IMPLEMENT_JS_CLASS(CJS_Util, util)
-
-util::util(CJS_Object* pJSObject) : CJS_EmbedObj(pJSObject) {}
-
-util::~util() {
-}
-
-struct stru_TbConvert {
-  const FX_WCHAR* lpszJSMark;
-  const FX_WCHAR* lpszCppMark;
-};
-
-const stru_TbConvert fcTable[] = {
-    {L"mmmm", L"%B"},
-    {L"mmm", L"%b"},
-    {L"mm", L"%m"},
-    //"m"
-    {L"dddd", L"%A"},
-    {L"ddd", L"%a"},
-    {L"dd", L"%d"},
-    //"d",   "%w",
-    {L"yyyy", L"%Y"},
-    {L"yy", L"%y"},
-    {L"HH", L"%H"},
-    //"H"
-    {L"hh", L"%I"},
-    //"h"
-    {L"MM", L"%M"},
-    //"M"
-    {L"ss", L"%S"},
-    //"s
-    {L"TT", L"%p"},
-//"t"
-#if defined(_WIN32)
-    {L"tt", L"%p"},
-    {L"h", L"%#I"},
-#else
-    {L"tt", L"%P"},
-    {L"h", L"%l"},
-#endif
-};
-
-#define UTIL_INT 0
-#define UTIL_DOUBLE 1
-#define UTIL_STRING 2
-
-int util::ParstDataType(std::wstring* sFormat) {
-  bool bPercent = FALSE;
-  for (size_t i = 0; i < sFormat->length(); ++i) {
-    wchar_t c = (*sFormat)[i];
-    if (c == L'%') {
-      bPercent = true;
-      continue;
-    }
-
-    if (bPercent) {
-      if (c == L'c' || c == L'C' || c == L'd' || c == L'i' || c == L'o' ||
-          c == L'u' || c == L'x' || c == L'X') {
-        return UTIL_INT;
-      }
-      if (c == L'e' || c == L'E' || c == L'f' || c == L'g' || c == L'G') {
-        return UTIL_DOUBLE;
-      }
-      if (c == L's' || c == L'S') {
-        // Map s to S since we always deal internally
-        // with wchar_t strings.
-        (*sFormat)[i] = L'S';
-        return UTIL_STRING;
-      }
-      if (c == L'.' || c == L'+' || c == L'-' || c == L'#' || c == L' ' ||
-          FXSYS_iswdigit(c)) {
-        continue;
-      }
-      break;
-    }
-  }
-
-  return -1;
-}
-
-FX_BOOL util::printf(IJS_Context* cc,
-                     const std::vector<CJS_Value>& params,
-                     CJS_Value& vRet,
-                     CFX_WideString& sError) {
-  int iSize = params.size();
-  if (iSize < 1)
-    return FALSE;
-  std::wstring c_ConvChar(params[0].ToCFXWideString().c_str());
-  std::vector<std::wstring> c_strConvers;
-  int iOffset = 0;
-  int iOffend = 0;
-  c_ConvChar.insert(c_ConvChar.begin(), L'S');
-  while (iOffset != -1) {
-    iOffend = c_ConvChar.find(L"%", iOffset + 1);
-    std::wstring strSub;
-    if (iOffend == -1)
-      strSub = c_ConvChar.substr(iOffset);
-    else
-      strSub = c_ConvChar.substr(iOffset, iOffend - iOffset);
-    c_strConvers.push_back(strSub);
-    iOffset = iOffend;
-  }
-
-  std::wstring c_strResult;
-
-  // for(int iIndex = 1;iIndex < params.size();iIndex++)
-  std::wstring c_strFormat;
-  for (int iIndex = 0; iIndex < (int)c_strConvers.size(); iIndex++) {
-    c_strFormat = c_strConvers[iIndex];
-    if (iIndex == 0) {
-      c_strResult = c_strFormat;
-      continue;
-    }
-
-    CFX_WideString strSegment;
-    if (iIndex >= iSize) {
-      c_strResult += c_strFormat;
-      continue;
-    }
-
-    switch (ParstDataType(&c_strFormat)) {
-      case UTIL_INT:
-        strSegment.Format(c_strFormat.c_str(), params[iIndex].ToInt());
-        break;
-      case UTIL_DOUBLE:
-        strSegment.Format(c_strFormat.c_str(), params[iIndex].ToDouble());
-        break;
-      case UTIL_STRING:
-        strSegment.Format(c_strFormat.c_str(),
-                          params[iIndex].ToCFXWideString().c_str());
-        break;
-      default:
-        strSegment.Format(L"%S", c_strFormat.c_str());
-        break;
-    }
-    c_strResult += strSegment.GetBuffer(strSegment.GetLength() + 1);
-  }
-
-  c_strResult.erase(c_strResult.begin());
-  vRet = c_strResult.c_str();
-  return TRUE;
-}
-
-FX_BOOL util::printd(IJS_Context* cc,
-                     const std::vector<CJS_Value>& params,
-                     CJS_Value& vRet,
-                     CFX_WideString& sError) {
-  int iSize = params.size();
-  if (iSize < 2)
-    return FALSE;
-
-  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
-  CJS_Value p1(pRuntime);
-  p1 = params[0];
-
-  CJS_Value p2 = params[1];
-  CJS_Date jsDate(pRuntime);
-  if (!p2.ConvertToDate(jsDate)) {
-    sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPRINT1);
-    return FALSE;
-  }
-
-  if (!jsDate.IsValidDate()) {
-    sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPRINT2);
-    return FALSE;
-  }
-
-  if (p1.GetType() == CJS_Value::VT_number) {
-    int nFormat = p1.ToInt();
-    CFX_WideString swResult;
-
-    switch (nFormat) {
-      case 0:
-        swResult.Format(L"D:%04d%02d%02d%02d%02d%02d", jsDate.GetYear(),
-                        jsDate.GetMonth() + 1, jsDate.GetDay(),
-                        jsDate.GetHours(), jsDate.GetMinutes(),
-                        jsDate.GetSeconds());
-        break;
-      case 1:
-        swResult.Format(L"%04d.%02d.%02d %02d:%02d:%02d", jsDate.GetYear(),
-                        jsDate.GetMonth() + 1, jsDate.GetDay(),
-                        jsDate.GetHours(), jsDate.GetMinutes(),
-                        jsDate.GetSeconds());
-        break;
-      case 2:
-        swResult.Format(L"%04d/%02d/%02d %02d:%02d:%02d", jsDate.GetYear(),
-                        jsDate.GetMonth() + 1, jsDate.GetDay(),
-                        jsDate.GetHours(), jsDate.GetMinutes(),
-                        jsDate.GetSeconds());
-        break;
-      default:
-        return FALSE;
-    }
-
-    vRet = swResult.c_str();
-    return TRUE;
-  }
-  if (p1.GetType() == CJS_Value::VT_string) {
-    std::basic_string<wchar_t> cFormat = p1.ToCFXWideString().c_str();
-
-    bool bXFAPicture = false;
-    if (iSize > 2) {
-      bXFAPicture = params[2].ToBool();
-    }
-
-    if (bXFAPicture) {
-      return FALSE;  // currently, it doesn't support XFAPicture.
-    }
-
-    for (size_t i = 0; i < sizeof(fcTable) / sizeof(stru_TbConvert); ++i) {
-      int iStart = 0;
-      int iEnd;
-      while ((iEnd = cFormat.find(fcTable[i].lpszJSMark, iStart)) != -1) {
-        cFormat.replace(iEnd, FXSYS_wcslen(fcTable[i].lpszJSMark),
-                        fcTable[i].lpszCppMark);
-        iStart = iEnd;
-      }
-    }
-
-    int iYear, iMonth, iDay, iHour, iMin, iSec;
-    iYear = jsDate.GetYear();
-    iMonth = jsDate.GetMonth();
-    iDay = jsDate.GetDay();
-    iHour = jsDate.GetHours();
-    iMin = jsDate.GetMinutes();
-    iSec = jsDate.GetSeconds();
-
-    struct tm time = {};
-    time.tm_year = iYear - 1900;
-    time.tm_mon = iMonth;
-    time.tm_mday = iDay;
-    time.tm_hour = iHour;
-    time.tm_min = iMin;
-    time.tm_sec = iSec;
-
-    struct stru_TbConvertAd {
-      const FX_WCHAR* lpszJSMark;
-      int iValue;
-    };
-
-    stru_TbConvertAd cTableAd[] = {
-        {L"m", iMonth + 1}, {L"d", iDay},
-        {L"H", iHour},      {L"h", iHour > 12 ? iHour - 12 : iHour},
-        {L"M", iMin},       {L"s", iSec},
-    };
-
-    for (size_t i = 0; i < sizeof(cTableAd) / sizeof(stru_TbConvertAd); ++i) {
-      wchar_t tszValue[10];
-      CFX_WideString sValue;
-      sValue.Format(L"%d", cTableAd[i].iValue);
-      memcpy(tszValue, (wchar_t*)sValue.GetBuffer(sValue.GetLength() + 1),
-             (sValue.GetLength() + 1) * sizeof(wchar_t));
-
-      int iStart = 0;
-      int iEnd;
-      while ((iEnd = cFormat.find(cTableAd[i].lpszJSMark, iStart)) != -1) {
-        if (iEnd > 0) {
-          if (cFormat[iEnd - 1] == L'%') {
-            iStart = iEnd + 1;
-            continue;
-          }
-        }
-        cFormat.replace(iEnd, FXSYS_wcslen(cTableAd[i].lpszJSMark), tszValue);
-        iStart = iEnd;
-      }
-    }
-
-    CFX_WideString strFormat;
-    wchar_t buf[64] = {};
-    strFormat = wcsftime(buf, 64, cFormat.c_str(), &time);
-    cFormat = buf;
-    vRet = cFormat.c_str();
-    return TRUE;
-  }
-  return FALSE;
-}
-
-void util::printd(const std::wstring& cFormat2,
-                  CJS_Date jsDate,
-                  bool bXFAPicture,
-                  std::wstring& cPurpose) {
-  std::wstring cFormat = cFormat2;
-
-  if (bXFAPicture) {
-    return;  // currently, it doesn't support XFAPicture.
-  }
-
-  for (size_t i = 0; i < sizeof(fcTable) / sizeof(stru_TbConvert); ++i) {
-    int iStart = 0;
-    int iEnd;
-    while ((iEnd = cFormat.find(fcTable[i].lpszJSMark, iStart)) != -1) {
-      cFormat.replace(iEnd, FXSYS_wcslen(fcTable[i].lpszJSMark),
-                      fcTable[i].lpszCppMark);
-      iStart = iEnd;
-    }
-  }
-
-  int iYear, iMonth, iDay, iHour, iMin, iSec;
-  iYear = jsDate.GetYear();
-  iMonth = jsDate.GetMonth();
-  iDay = jsDate.GetDay();
-  iHour = jsDate.GetHours();
-  iMin = jsDate.GetMinutes();
-  iSec = jsDate.GetSeconds();
-
-  struct tm time = {};
-  time.tm_year = iYear - 1900;
-  time.tm_mon = iMonth;
-  time.tm_mday = iDay;
-  time.tm_hour = iHour;
-  time.tm_min = iMin;
-  time.tm_sec = iSec;
-  //  COleDateTime cppTm(iYear,iMonth+1,iDay,iHour,iMin,iSec);
-  // CString strFormat = cppTm.Format(cFormat.c_str());
-
-  struct stru_TbConvertAd {
-    const FX_WCHAR* lpszJSMark;
-    int iValue;
-  };
-
-  stru_TbConvertAd cTableAd[] = {
-      {L"m", iMonth + 1}, {L"d", iDay},
-      {L"H", iHour},      {L"h", iHour > 12 ? iHour - 12 : iHour},
-      {L"M", iMin},       {L"s", iSec},
-  };
-
-  // cFormat = strFormat.GetBuffer(strFormat.GetLength()+1);
-  for (size_t i = 0; i < sizeof(cTableAd) / sizeof(stru_TbConvertAd); ++i) {
-    wchar_t tszValue[10];
-    CFX_WideString sValue;
-    sValue.Format(L"%d", cTableAd[i].iValue);
-    memcpy(tszValue, (wchar_t*)sValue.GetBuffer(sValue.GetLength() + 1),
-           sValue.GetLength() * sizeof(wchar_t));
-
-    int iStart = 0;
-    int iEnd;
-    while ((iEnd = cFormat.find(cTableAd[i].lpszJSMark, iStart)) != -1) {
-      if (iEnd > 0) {
-        if (cFormat[iEnd - 1] == L'%') {
-          iStart = iEnd + 1;
-          continue;
-        }
-      }
-      cFormat.replace(iEnd, FXSYS_wcslen(cTableAd[i].lpszJSMark), tszValue);
-      iStart = iEnd;
-    }
-  }
-
-  CFX_WideString strFormat;
-  wchar_t buf[64] = {};
-  strFormat = wcsftime(buf, 64, cFormat.c_str(), &time);
-  cFormat = buf;
-  cPurpose = cFormat;
-}
-
-FX_BOOL util::printx(IJS_Context* cc,
-                     const std::vector<CJS_Value>& params,
-                     CJS_Value& vRet,
-                     CFX_WideString& sError) {
-  int iSize = params.size();
-  if (iSize < 2)
-    return FALSE;
-  CFX_WideString sFormat = params[0].ToCFXWideString();
-  CFX_WideString sSource = params[1].ToCFXWideString();
-  std::string cFormat = CFX_ByteString::FromUnicode(sFormat).c_str();
-  std::string cSource = CFX_ByteString::FromUnicode(sSource).c_str();
-  std::string cDest;
-  printx(cFormat, cSource, cDest);
-  vRet = cDest.c_str();
-  return TRUE;
-}
-
-void util::printx(const std::string& cFormat,
-                  const std::string& cSource2,
-                  std::string& cPurpose) {
-  std::string cSource(cSource2);
-  if (!cPurpose.empty())
-    // cPurpose.clear();
-    cPurpose.erase();
-  int itSource = 0;
-  int iSize = cSource.size();
-  for (int iIndex = 0; iIndex < (int)cFormat.size() && itSource < iSize;
-       iIndex++) {
-    char letter = cFormat[iIndex];
-    switch (letter) {
-      case '?':
-        cPurpose += cSource[itSource];
-        itSource++;
-        break;
-      case 'X': {
-        while (itSource < iSize) {
-          if (std::isdigit(cSource[itSource]) ||
-              (cSource[itSource] >= 'a' && cSource[itSource] <= 'z') ||
-              (cSource[itSource] >= 'A' && cSource[itSource] <= 'Z')) {
-            cPurpose += cSource[itSource];
-            itSource++;
-            break;
-          }
-          itSource++;
-        }
-        break;
-      } break;
-      case 'A': {
-        while (itSource < iSize) {
-          if ((cSource[itSource] >= 'a' && cSource[itSource] <= 'z') ||
-              (cSource[itSource] >= 'A' && cSource[itSource] <= 'Z')) {
-            cPurpose += cSource[itSource];
-            itSource++;
-            break;
-          }
-          itSource++;
-        }
-        break;
-      } break;
-      case '9': {
-        while (itSource < iSize) {
-          if (std::isdigit(cSource[itSource])) {
-            cPurpose += cSource[itSource];
-            itSource++;
-            break;
-          }
-          itSource++;
-        }
-        break;
-      }
-      case '*': {
-        cPurpose.append(cSource, itSource, iSize - itSource);
-        itSource = iSize - 1;
-        break;
-      }
-      case '\\':
-        break;
-      case '>': {
-        for (char& c : cSource)
-          c = toupper(c);
-        break;
-      }
-      case '<': {
-        for (char& c : cSource)
-          c = tolower(c);
-        break;
-      }
-      case '=':
-        break;
-      default:
-        cPurpose += letter;
-        break;
-    }
-  }
-}
-
-FX_BOOL util::scand(IJS_Context* cc,
-                    const std::vector<CJS_Value>& params,
-                    CJS_Value& vRet,
-                    CFX_WideString& sError) {
-  int iSize = params.size();
-  if (iSize < 2)
-    return FALSE;
-
-  CFX_WideString sFormat = params[0].ToCFXWideString();
-  CFX_WideString sDate = params[1].ToCFXWideString();
-  double dDate = JS_GetDateTime();
-  if (sDate.GetLength() > 0) {
-    dDate = CJS_PublicMethods::MakeRegularDate(sDate, sFormat, nullptr);
-  }
-
-  if (!JS_PortIsNan(dDate)) {
-    vRet = CJS_Date(CJS_Runtime::FromContext(cc), dDate);
-  } else {
-    vRet.SetNull();
-  }
-
-  return TRUE;
-}
-
-int64_t FX_atoi64(const char* nptr) {
-  int c;         /* current char */
-  int64_t total; /* current total */
-  int sign;      /* if '-', then negative, otherwise positive */
-
-  /* skip whitespace */
-  while (isspace((int)(unsigned char)*nptr))
-    ++nptr;
-
-  c = (int)(unsigned char)*nptr++;
-  sign = c; /* save sign indication */
-  if (c == '-' || c == '+')
-    c = (int)(unsigned char)*nptr++; /* skip sign */
-
-  total = 0;
-
-  while (isdigit(c)) {
-    total = 10 * total + FXSYS_toDecimalDigit(c); /* accumulate digit */
-    c = (int)(unsigned char)*nptr++; /* get next char */
-  }
-
-  return sign == '-' ? -total : total;
-}
-
-FX_BOOL util::byteToChar(IJS_Context* cc,
-                         const std::vector<CJS_Value>& params,
-                         CJS_Value& vRet,
-                         CFX_WideString& sError) {
-  int iSize = params.size();
-  if (iSize == 0)
-    return FALSE;
-  int nByte = params[0].ToInt();
-  unsigned char cByte = (unsigned char)nByte;
-  CFX_WideString csValue;
-  csValue.Format(L"%c", cByte);
-  vRet = csValue.c_str();
-  return TRUE;
-}
diff --git a/fpdfsdk/src/javascript/util.h b/fpdfsdk/src/javascript/util.h
deleted file mode 100644
index 7b9a18c..0000000
--- a/fpdfsdk/src/javascript/util.h
+++ /dev/null
@@ -1,68 +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_SRC_JAVASCRIPT_UTIL_H_
-#define FPDFSDK_SRC_JAVASCRIPT_UTIL_H_
-
-#include <string>  // For std::wstring.
-
-#include "JS_Define.h"
-
-class util : public CJS_EmbedObj {
- public:
-  util(CJS_Object* pJSObject);
-  ~util() override;
-
- public:
-  FX_BOOL printd(IJS_Context* cc,
-                 const std::vector<CJS_Value>& params,
-                 CJS_Value& vRet,
-                 CFX_WideString& sError);
-  FX_BOOL printf(IJS_Context* cc,
-                 const std::vector<CJS_Value>& params,
-                 CJS_Value& vRet,
-                 CFX_WideString& sError);
-  FX_BOOL printx(IJS_Context* cc,
-                 const std::vector<CJS_Value>& params,
-                 CJS_Value& vRet,
-                 CFX_WideString& sError);
-  FX_BOOL scand(IJS_Context* cc,
-                const std::vector<CJS_Value>& params,
-                CJS_Value& vRet,
-                CFX_WideString& sError);
-  FX_BOOL byteToChar(IJS_Context* cc,
-                     const std::vector<CJS_Value>& params,
-                     CJS_Value& vRet,
-                     CFX_WideString& sError);
-
- public:
-  static void printd(const std::wstring& cFormat,
-                     CJS_Date Date,
-                     bool bXFAPicture,
-                     std::wstring& cPurpose);
-  static void printx(const std::string& cFormat,
-                     const std::string& cSource,
-                     std::string& cPurpose);
-  static int ParstDataType(std::wstring* sFormat);
-};
-
-class CJS_Util : public CJS_Object {
- public:
-  CJS_Util(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
-  ~CJS_Util() override {}
-
-  DECLARE_JS_CLASS();
-
-  JS_STATIC_METHOD(printd, util);
-  JS_STATIC_METHOD(printf, util);
-  JS_STATIC_METHOD(printx, util);
-  JS_STATIC_METHOD(scand, util);
-  JS_STATIC_METHOD(byteToChar, util);
-};
-
-int64_t FX_atoi64(const char* nptr);
-
-#endif  // FPDFSDK_SRC_JAVASCRIPT_UTIL_H_
diff --git a/fpdfsdk/src/jsapi/fxjs_v8.cpp b/fpdfsdk/src/jsapi/fxjs_v8.cpp
deleted file mode 100644
index b06f747..0000000
--- a/fpdfsdk/src/jsapi/fxjs_v8.cpp
+++ /dev/null
@@ -1,778 +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
-
-#include "fpdfsdk/include/jsapi/fxjs_v8.h"
-
-#include "core/include/fxcrt/fx_basic.h"
-
-const wchar_t kFXJSValueNameString[] = L"string";
-const wchar_t kFXJSValueNameNumber[] = L"number";
-const wchar_t kFXJSValueNameBoolean[] = L"boolean";
-const wchar_t kFXJSValueNameDate[] = L"date";
-const wchar_t kFXJSValueNameObject[] = L"object";
-const wchar_t kFXJSValueNameFxobj[] = L"fxobj";
-const wchar_t kFXJSValueNameNull[] = L"null";
-const wchar_t kFXJSValueNameUndefined[] = L"undefined";
-
-// Keep this consistent with the values defined in gin/public/context_holder.h
-// (without actually requiring a dependency on gin itself for the standalone
-// embedders of PDFIum). The value we want to use is:
-//   kPerContextDataStartIndex + kEmbedderPDFium, which is 3.
-static const unsigned int kPerContextDataIndex = 3u;
-static unsigned int g_embedderDataSlot = 1u;
-static v8::Isolate* g_isolate = nullptr;
-static size_t g_isolate_ref_count = 0;
-static FXJS_ArrayBufferAllocator* g_arrayBufferAllocator = nullptr;
-static v8::Global<v8::ObjectTemplate>* g_DefaultGlobalObjectTemplate = nullptr;
-
-class CFXJS_PerObjectData {
- public:
-  explicit CFXJS_PerObjectData(int nObjDefID)
-      : m_ObjDefID(nObjDefID), m_pPrivate(nullptr) {}
-
-  const int m_ObjDefID;
-  void* m_pPrivate;
-};
-
-class CFXJS_ObjDefinition {
- public:
-  static int MaxID(v8::Isolate* pIsolate) {
-    return FXJS_PerIsolateData::Get(pIsolate)->m_ObjectDefnArray.size();
-  }
-
-  static CFXJS_ObjDefinition* ForID(v8::Isolate* pIsolate, int id) {
-    // Note: GetAt() halts if out-of-range even in release builds.
-    return FXJS_PerIsolateData::Get(pIsolate)->m_ObjectDefnArray[id];
-  }
-
-  CFXJS_ObjDefinition(v8::Isolate* isolate,
-                      const wchar_t* sObjName,
-                      FXJSOBJTYPE eObjType,
-                      FXJS_CONSTRUCTOR pConstructor,
-                      FXJS_DESTRUCTOR pDestructor)
-      : m_ObjName(sObjName),
-        m_ObjType(eObjType),
-        m_pConstructor(pConstructor),
-        m_pDestructor(pDestructor),
-        m_pIsolate(isolate) {
-    v8::Isolate::Scope isolate_scope(isolate);
-    v8::HandleScope handle_scope(isolate);
-
-    v8::Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(isolate);
-    fun->InstanceTemplate()->SetInternalFieldCount(2);
-    m_FunctionTemplate.Reset(isolate, fun);
-
-    v8::Local<v8::Signature> sig = v8::Signature::New(isolate, fun);
-    m_Signature.Reset(isolate, sig);
-  }
-
-  int AssignID() {
-    FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(m_pIsolate);
-    pData->m_ObjectDefnArray.push_back(this);
-    return pData->m_ObjectDefnArray.size() - 1;
-  }
-
-  v8::Local<v8::ObjectTemplate> GetInstanceTemplate() {
-    v8::EscapableHandleScope scope(m_pIsolate);
-    v8::Local<v8::FunctionTemplate> function =
-        m_FunctionTemplate.Get(m_pIsolate);
-    return scope.Escape(function->InstanceTemplate());
-  }
-
-  v8::Local<v8::Signature> GetSignature() {
-    v8::EscapableHandleScope scope(m_pIsolate);
-    return scope.Escape(m_Signature.Get(m_pIsolate));
-  }
-
-  const wchar_t* const m_ObjName;
-  const FXJSOBJTYPE m_ObjType;
-  const FXJS_CONSTRUCTOR m_pConstructor;
-  const FXJS_DESTRUCTOR m_pDestructor;
-
-  v8::Isolate* m_pIsolate;
-  v8::Global<v8::FunctionTemplate> m_FunctionTemplate;
-  v8::Global<v8::Signature> m_Signature;
-};
-
-static v8::Local<v8::ObjectTemplate> GetGlobalObjectTemplate(
-    v8::Isolate* pIsolate) {
-  int maxID = CFXJS_ObjDefinition::MaxID(pIsolate);
-  for (int i = 0; i < maxID; ++i) {
-    CFXJS_ObjDefinition* pObjDef = CFXJS_ObjDefinition::ForID(pIsolate, i);
-    if (pObjDef->m_ObjType == FXJSOBJTYPE_GLOBAL)
-      return pObjDef->GetInstanceTemplate();
-  }
-  if (!g_DefaultGlobalObjectTemplate) {
-    g_DefaultGlobalObjectTemplate = new v8::Global<v8::ObjectTemplate>;
-    g_DefaultGlobalObjectTemplate->Reset(pIsolate,
-                                         v8::ObjectTemplate::New(pIsolate));
-  }
-  return g_DefaultGlobalObjectTemplate->Get(pIsolate);
-}
-
-void* FXJS_ArrayBufferAllocator::Allocate(size_t length) {
-  return calloc(1, length);
-}
-
-void* FXJS_ArrayBufferAllocator::AllocateUninitialized(size_t length) {
-  return malloc(length);
-}
-
-void FXJS_ArrayBufferAllocator::Free(void* data, size_t length) {
-  free(data);
-}
-
-void FXJS_Initialize(unsigned int embedderDataSlot, v8::Isolate* pIsolate) {
-  if (g_isolate) {
-    ASSERT(g_embedderDataSlot == embedderDataSlot);
-    ASSERT(g_isolate == pIsolate);
-    return;
-  }
-  g_embedderDataSlot = embedderDataSlot;
-  g_isolate = pIsolate;
-}
-
-void FXJS_Release() {
-  ASSERT(!g_isolate || g_isolate_ref_count == 0);
-  delete g_DefaultGlobalObjectTemplate;
-  g_DefaultGlobalObjectTemplate = nullptr;
-  g_isolate = nullptr;
-
-  delete g_arrayBufferAllocator;
-  g_arrayBufferAllocator = nullptr;
-}
-
-bool FXJS_GetIsolate(v8::Isolate** pResultIsolate) {
-  if (g_isolate) {
-    *pResultIsolate = g_isolate;
-    return false;
-  }
-  // Provide backwards compatibility when no external isolate.
-  if (!g_arrayBufferAllocator)
-    g_arrayBufferAllocator = new FXJS_ArrayBufferAllocator();
-  v8::Isolate::CreateParams params;
-  params.array_buffer_allocator = g_arrayBufferAllocator;
-  *pResultIsolate = v8::Isolate::New(params);
-  return true;
-}
-
-size_t FXJS_GlobalIsolateRefCount() {
-  return g_isolate_ref_count;
-}
-
-// static
-void FXJS_PerIsolateData::SetUp(v8::Isolate* pIsolate) {
-  if (!pIsolate->GetData(g_embedderDataSlot))
-    pIsolate->SetData(g_embedderDataSlot, new FXJS_PerIsolateData());
-}
-
-// static
-FXJS_PerIsolateData* FXJS_PerIsolateData::Get(v8::Isolate* pIsolate) {
-  return static_cast<FXJS_PerIsolateData*>(
-      pIsolate->GetData(g_embedderDataSlot));
-}
-
-int FXJS_DefineObj(v8::Isolate* pIsolate,
-                   const wchar_t* sObjName,
-                   FXJSOBJTYPE eObjType,
-                   FXJS_CONSTRUCTOR pConstructor,
-                   FXJS_DESTRUCTOR pDestructor) {
-  v8::Isolate::Scope isolate_scope(pIsolate);
-  v8::HandleScope handle_scope(pIsolate);
-
-  FXJS_PerIsolateData::SetUp(pIsolate);
-  CFXJS_ObjDefinition* pObjDef = new CFXJS_ObjDefinition(
-      pIsolate, sObjName, eObjType, pConstructor, pDestructor);
-  return pObjDef->AssignID();
-}
-
-void FXJS_DefineObjMethod(v8::Isolate* pIsolate,
-                          int nObjDefnID,
-                          const wchar_t* sMethodName,
-                          v8::FunctionCallback pMethodCall) {
-  v8::Isolate::Scope isolate_scope(pIsolate);
-  v8::HandleScope handle_scope(pIsolate);
-  CFX_ByteString bsMethodName = CFX_WideString(sMethodName).UTF8Encode();
-  CFXJS_ObjDefinition* pObjDef =
-      CFXJS_ObjDefinition::ForID(pIsolate, nObjDefnID);
-  pObjDef->GetInstanceTemplate()->Set(
-      v8::String::NewFromUtf8(pIsolate, bsMethodName.c_str(),
-                              v8::NewStringType::kNormal).ToLocalChecked(),
-      v8::FunctionTemplate::New(pIsolate, pMethodCall, v8::Local<v8::Value>(),
-                                pObjDef->GetSignature()),
-      v8::ReadOnly);
-}
-
-void FXJS_DefineObjProperty(v8::Isolate* pIsolate,
-                            int nObjDefnID,
-                            const wchar_t* sPropName,
-                            v8::AccessorGetterCallback pPropGet,
-                            v8::AccessorSetterCallback pPropPut) {
-  v8::Isolate::Scope isolate_scope(pIsolate);
-  v8::HandleScope handle_scope(pIsolate);
-  CFX_ByteString bsPropertyName = CFX_WideString(sPropName).UTF8Encode();
-  CFXJS_ObjDefinition* pObjDef =
-      CFXJS_ObjDefinition::ForID(pIsolate, nObjDefnID);
-  pObjDef->GetInstanceTemplate()->SetAccessor(
-      v8::String::NewFromUtf8(pIsolate, bsPropertyName.c_str(),
-                              v8::NewStringType::kNormal).ToLocalChecked(),
-      pPropGet, pPropPut);
-}
-
-void FXJS_DefineObjAllProperties(v8::Isolate* pIsolate,
-                                 int nObjDefnID,
-                                 v8::NamedPropertyQueryCallback pPropQurey,
-                                 v8::NamedPropertyGetterCallback pPropGet,
-                                 v8::NamedPropertySetterCallback pPropPut,
-                                 v8::NamedPropertyDeleterCallback pPropDel) {
-  v8::Isolate::Scope isolate_scope(pIsolate);
-  v8::HandleScope handle_scope(pIsolate);
-  CFXJS_ObjDefinition* pObjDef =
-      CFXJS_ObjDefinition::ForID(pIsolate, nObjDefnID);
-  pObjDef->GetInstanceTemplate()->SetNamedPropertyHandler(pPropGet, pPropPut,
-                                                          pPropQurey, pPropDel);
-}
-
-void FXJS_DefineObjConst(v8::Isolate* pIsolate,
-                         int nObjDefnID,
-                         const wchar_t* sConstName,
-                         v8::Local<v8::Value> pDefault) {
-  v8::Isolate::Scope isolate_scope(pIsolate);
-  v8::HandleScope handle_scope(pIsolate);
-  CFX_ByteString bsConstName = CFX_WideString(sConstName).UTF8Encode();
-  CFXJS_ObjDefinition* pObjDef =
-      CFXJS_ObjDefinition::ForID(pIsolate, nObjDefnID);
-  pObjDef->GetInstanceTemplate()->Set(pIsolate, bsConstName.c_str(), pDefault);
-}
-
-void FXJS_DefineGlobalMethod(v8::Isolate* pIsolate,
-                             const wchar_t* sMethodName,
-                             v8::FunctionCallback pMethodCall) {
-  v8::Isolate::Scope isolate_scope(pIsolate);
-  v8::HandleScope handle_scope(pIsolate);
-  CFX_ByteString bsMethodName = CFX_WideString(sMethodName).UTF8Encode();
-  GetGlobalObjectTemplate(pIsolate)->Set(
-      v8::String::NewFromUtf8(pIsolate, bsMethodName.c_str(),
-                              v8::NewStringType::kNormal).ToLocalChecked(),
-      v8::FunctionTemplate::New(pIsolate, pMethodCall), v8::ReadOnly);
-}
-
-void FXJS_DefineGlobalConst(v8::Isolate* pIsolate,
-                            const wchar_t* sConstName,
-                            v8::Local<v8::Value> pDefault) {
-  v8::Isolate::Scope isolate_scope(pIsolate);
-  v8::HandleScope handle_scope(pIsolate);
-  CFX_ByteString bsConst = CFX_WideString(sConstName).UTF8Encode();
-  GetGlobalObjectTemplate(pIsolate)->Set(
-      v8::String::NewFromUtf8(pIsolate, bsConst.c_str(),
-                              v8::NewStringType::kNormal).ToLocalChecked(),
-      pDefault, v8::ReadOnly);
-}
-
-void FXJS_InitializeRuntime(
-    v8::Isolate* pIsolate,
-    IJS_Runtime* pIRuntime,
-    v8::Global<v8::Context>* pV8PersistentContext,
-    std::vector<v8::Global<v8::Object>*>* pStaticObjects) {
-  if (pIsolate == g_isolate)
-    ++g_isolate_ref_count;
-
-  v8::Isolate::Scope isolate_scope(pIsolate);
-#ifdef PDF_ENABLE_XFA
-  v8::Locker locker(pIsolate);
-#endif  // PDF_ENABLE_XFA
-  v8::HandleScope handle_scope(pIsolate);
-  v8::Local<v8::Context> v8Context =
-      v8::Context::New(pIsolate, NULL, GetGlobalObjectTemplate(pIsolate));
-  v8::Context::Scope context_scope(v8Context);
-
-  FXJS_PerIsolateData::SetUp(pIsolate);
-  v8Context->SetAlignedPointerInEmbedderData(kPerContextDataIndex, pIRuntime);
-
-  int maxID = CFXJS_ObjDefinition::MaxID(pIsolate);
-  pStaticObjects->resize(maxID + 1);
-  for (int i = 0; i < maxID; ++i) {
-    CFXJS_ObjDefinition* pObjDef = CFXJS_ObjDefinition::ForID(pIsolate, i);
-    if (pObjDef->m_ObjType == FXJSOBJTYPE_GLOBAL) {
-      v8Context->Global()
-          ->GetPrototype()
-          ->ToObject(v8Context)
-          .ToLocalChecked()
-          ->SetAlignedPointerInInternalField(0, new CFXJS_PerObjectData(i));
-
-      if (pObjDef->m_pConstructor)
-        pObjDef->m_pConstructor(pIRuntime, v8Context->Global()
-                                               ->GetPrototype()
-                                               ->ToObject(v8Context)
-                                               .ToLocalChecked());
-    } else if (pObjDef->m_ObjType == FXJSOBJTYPE_STATIC) {
-      CFX_ByteString bs = CFX_WideString(pObjDef->m_ObjName).UTF8Encode();
-      v8::Local<v8::String> m_ObjName =
-          v8::String::NewFromUtf8(pIsolate, bs.c_str(),
-                                  v8::NewStringType::kNormal,
-                                  bs.GetLength()).ToLocalChecked();
-
-      v8::Local<v8::Object> obj = FXJS_NewFxDynamicObj(pIsolate, pIRuntime, i);
-      v8Context->Global()->Set(v8Context, m_ObjName, obj).FromJust();
-      pStaticObjects->at(i) = new v8::Global<v8::Object>(pIsolate, obj);
-    }
-  }
-  pV8PersistentContext->Reset(pIsolate, v8Context);
-}
-
-void FXJS_ReleaseRuntime(v8::Isolate* pIsolate,
-                         v8::Global<v8::Context>* pV8PersistentContext,
-                         std::vector<v8::Global<v8::Object>*>* pStaticObjects) {
-  v8::Isolate::Scope isolate_scope(pIsolate);
-#ifdef PDF_ENABLE_XFA
-  v8::Locker locker(pIsolate);
-#endif  // PDF_ENABLE_XFA
-  v8::HandleScope handle_scope(pIsolate);
-  v8::Local<v8::Context> context =
-      v8::Local<v8::Context>::New(pIsolate, *pV8PersistentContext);
-  v8::Context::Scope context_scope(context);
-
-  FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(pIsolate);
-  if (!pData)
-    return;
-
-#ifdef PDF_ENABLE_XFA
-  // XFA, if present, should have already cleaned itself up.
-  FXSYS_assert(!pData->m_pFXJSERuntimeData);
-#endif  // PDF_ENABLE_XFA
-
-  int maxID = CFXJS_ObjDefinition::MaxID(pIsolate);
-  for (int i = 0; i < maxID; ++i) {
-    CFXJS_ObjDefinition* pObjDef = CFXJS_ObjDefinition::ForID(pIsolate, i);
-    v8::Local<v8::Object> pObj;
-    if (pObjDef->m_ObjType == FXJSOBJTYPE_GLOBAL) {
-      pObj =
-          context->Global()->GetPrototype()->ToObject(context).ToLocalChecked();
-    } else if (pStaticObjects->at(i) && !pStaticObjects->at(i)->IsEmpty()) {
-      pObj = v8::Local<v8::Object>::New(pIsolate, *pStaticObjects->at(i));
-      delete pStaticObjects->at(i);
-      pStaticObjects->at(i) = nullptr;
-    }
-
-    if (!pObj.IsEmpty()) {
-      if (pObjDef->m_pDestructor)
-        pObjDef->m_pDestructor(pObj);
-      FXJS_FreePrivate(pObj);
-    }
-  }
-
-  if (pIsolate == g_isolate && --g_isolate_ref_count > 0)
-    return;
-
-  for (int i = 0; i < maxID; ++i)
-    delete CFXJS_ObjDefinition::ForID(pIsolate, i);
-
-  pIsolate->SetData(g_embedderDataSlot, nullptr);
-  delete pData;
-}
-
-IJS_Runtime* FXJS_GetRuntimeFromIsolate(v8::Isolate* pIsolate) {
-  v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
-  return static_cast<IJS_Runtime*>(
-      context->GetAlignedPointerFromEmbedderData(kPerContextDataIndex));
-}
-
-#ifdef PDF_ENABLE_XFA
-void FXJS_SetRuntimeForV8Context(v8::Local<v8::Context> v8Context,
-                                 IJS_Runtime* pIRuntime) {
-  v8Context->SetAlignedPointerInEmbedderData(kPerContextDataIndex, pIRuntime);
-}
-#endif  // PDF_ENABLE_XFA
-
-int FXJS_Execute(v8::Isolate* pIsolate,
-                 IJS_Context* pJSContext,
-                 const wchar_t* script,
-                 FXJSErr* pError) {
-  v8::Isolate::Scope isolate_scope(pIsolate);
-  v8::TryCatch try_catch(pIsolate);
-  CFX_ByteString bsScript = CFX_WideString(script).UTF8Encode();
-  v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
-  v8::Local<v8::Script> compiled_script;
-  if (!v8::Script::Compile(
-           context, v8::String::NewFromUtf8(
-                        pIsolate, bsScript.c_str(), v8::NewStringType::kNormal,
-                        bsScript.GetLength()).ToLocalChecked())
-           .ToLocal(&compiled_script)) {
-    v8::String::Utf8Value error(try_catch.Exception());
-    // TODO(tsepez): return error via pError->message.
-    return -1;
-  }
-
-  v8::Local<v8::Value> result;
-  if (!compiled_script->Run(context).ToLocal(&result)) {
-    v8::String::Utf8Value error(try_catch.Exception());
-    // TODO(tsepez): return error via pError->message.
-    return -1;
-  }
-  return 0;
-}
-
-v8::Local<v8::Object> FXJS_NewFxDynamicObj(v8::Isolate* pIsolate,
-                                           IJS_Runtime* pIRuntime,
-                                           int nObjDefnID) {
-  v8::Isolate::Scope isolate_scope(pIsolate);
-  v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
-  if (nObjDefnID == -1) {
-    v8::Local<v8::ObjectTemplate> objTempl = v8::ObjectTemplate::New(pIsolate);
-    v8::Local<v8::Object> obj;
-    if (!objTempl->NewInstance(context).ToLocal(&obj))
-      return v8::Local<v8::Object>();
-    return obj;
-  }
-
-  FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(pIsolate);
-  if (!pData)
-    return v8::Local<v8::Object>();
-
-  if (nObjDefnID < 0 || nObjDefnID >= CFXJS_ObjDefinition::MaxID(pIsolate))
-    return v8::Local<v8::Object>();
-
-  CFXJS_ObjDefinition* pObjDef =
-      CFXJS_ObjDefinition::ForID(pIsolate, nObjDefnID);
-  v8::Local<v8::Object> obj;
-  if (!pObjDef->GetInstanceTemplate()->NewInstance(context).ToLocal(&obj))
-    return v8::Local<v8::Object>();
-
-  obj->SetAlignedPointerInInternalField(0, new CFXJS_PerObjectData(nObjDefnID));
-  if (pObjDef->m_pConstructor)
-    pObjDef->m_pConstructor(pIRuntime, obj);
-
-  return obj;
-}
-
-v8::Local<v8::Object> FXJS_GetThisObj(v8::Isolate* pIsolate) {
-  v8::Isolate::Scope isolate_scope(pIsolate);
-  if (!FXJS_PerIsolateData::Get(pIsolate))
-    return v8::Local<v8::Object>();
-
-  // Return the global object.
-  v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
-  return context->Global()->GetPrototype()->ToObject(context).ToLocalChecked();
-}
-
-int FXJS_GetObjDefnID(v8::Local<v8::Object> pObj) {
-  if (pObj.IsEmpty() || !pObj->InternalFieldCount())
-    return -1;
-  CFXJS_PerObjectData* pPerObjectData = static_cast<CFXJS_PerObjectData*>(
-      pObj->GetAlignedPointerFromInternalField(0));
-  if (pPerObjectData)
-    return pPerObjectData->m_ObjDefID;
-  return -1;
-}
-
-void FXJS_Error(v8::Isolate* pIsolate, const CFX_WideString& message) {
-  // Conversion from pdfium's wchar_t wide-strings to v8's uint16_t
-  // wide-strings isn't handled by v8, so use UTF8 as a common
-  // intermediate format.
-  CFX_ByteString utf8_message = message.UTF8Encode();
-  pIsolate->ThrowException(
-      v8::String::NewFromUtf8(pIsolate, utf8_message.c_str(),
-                              v8::NewStringType::kNormal).ToLocalChecked());
-}
-
-const wchar_t* FXJS_GetTypeof(v8::Local<v8::Value> pObj) {
-  if (pObj.IsEmpty())
-    return NULL;
-  if (pObj->IsString())
-    return kFXJSValueNameString;
-  if (pObj->IsNumber())
-    return kFXJSValueNameNumber;
-  if (pObj->IsBoolean())
-    return kFXJSValueNameBoolean;
-  if (pObj->IsDate())
-    return kFXJSValueNameDate;
-  if (pObj->IsObject())
-    return kFXJSValueNameObject;
-  if (pObj->IsNull())
-    return kFXJSValueNameNull;
-  if (pObj->IsUndefined())
-    return kFXJSValueNameUndefined;
-  return NULL;
-}
-
-void FXJS_SetPrivate(v8::Isolate* pIsolate,
-                     v8::Local<v8::Object> pObj,
-                     void* p) {
-  if (pObj.IsEmpty() || !pObj->InternalFieldCount())
-    return;
-  CFXJS_PerObjectData* pPerObjectData = static_cast<CFXJS_PerObjectData*>(
-      pObj->GetAlignedPointerFromInternalField(0));
-  if (!pPerObjectData)
-    return;
-  pPerObjectData->m_pPrivate = p;
-}
-
-void* FXJS_GetPrivate(v8::Isolate* pIsolate, v8::Local<v8::Object> pObj) {
-  if (pObj.IsEmpty())
-    return nullptr;
-  CFXJS_PerObjectData* pPerObjectData = nullptr;
-  if (pObj->InternalFieldCount()) {
-    pPerObjectData = static_cast<CFXJS_PerObjectData*>(
-        pObj->GetAlignedPointerFromInternalField(0));
-  } else {
-    // It could be a global proxy object.
-    v8::Local<v8::Value> v = pObj->GetPrototype();
-    v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
-    if (v->IsObject()) {
-      pPerObjectData = static_cast<CFXJS_PerObjectData*>(
-          v->ToObject(context)
-              .ToLocalChecked()
-              ->GetAlignedPointerFromInternalField(0));
-    }
-  }
-  return pPerObjectData ? pPerObjectData->m_pPrivate : nullptr;
-}
-
-void FXJS_FreePrivate(void* pPerObjectData) {
-  delete static_cast<CFXJS_PerObjectData*>(pPerObjectData);
-}
-
-void FXJS_FreePrivate(v8::Local<v8::Object> pObj) {
-  if (pObj.IsEmpty() || !pObj->InternalFieldCount())
-    return;
-  FXJS_FreePrivate(pObj->GetAlignedPointerFromInternalField(0));
-  pObj->SetAlignedPointerInInternalField(0, NULL);
-}
-
-v8::Local<v8::String> FXJS_WSToJSString(v8::Isolate* pIsolate,
-                                        const wchar_t* PropertyName,
-                                        int Len) {
-  CFX_WideString ws = CFX_WideString(PropertyName, Len);
-  CFX_ByteString bs = ws.UTF8Encode();
-  if (!pIsolate)
-    pIsolate = v8::Isolate::GetCurrent();
-  return v8::String::NewFromUtf8(pIsolate, bs.c_str(),
-                                 v8::NewStringType::kNormal).ToLocalChecked();
-}
-
-v8::Local<v8::Value> FXJS_GetObjectElement(v8::Isolate* pIsolate,
-                                           v8::Local<v8::Object> pObj,
-                                           const wchar_t* PropertyName) {
-  if (pObj.IsEmpty())
-    return v8::Local<v8::Value>();
-  v8::Local<v8::Value> val;
-  if (!pObj->Get(pIsolate->GetCurrentContext(),
-                 FXJS_WSToJSString(pIsolate, PropertyName)).ToLocal(&val))
-    return v8::Local<v8::Value>();
-  return val;
-}
-
-v8::Local<v8::Array> FXJS_GetObjectElementNames(v8::Isolate* pIsolate,
-                                                v8::Local<v8::Object> pObj) {
-  if (pObj.IsEmpty())
-    return v8::Local<v8::Array>();
-  v8::Local<v8::Array> val;
-  if (!pObj->GetPropertyNames(pIsolate->GetCurrentContext()).ToLocal(&val))
-    return v8::Local<v8::Array>();
-  return val;
-}
-
-void FXJS_PutObjectString(v8::Isolate* pIsolate,
-                          v8::Local<v8::Object> pObj,
-                          const wchar_t* PropertyName,
-                          const wchar_t* sValue) {
-  if (pObj.IsEmpty())
-    return;
-  pObj->Set(pIsolate->GetCurrentContext(),
-            FXJS_WSToJSString(pIsolate, PropertyName),
-            FXJS_WSToJSString(pIsolate, sValue)).FromJust();
-}
-
-void FXJS_PutObjectNumber(v8::Isolate* pIsolate,
-                          v8::Local<v8::Object> pObj,
-                          const wchar_t* PropertyName,
-                          int nValue) {
-  if (pObj.IsEmpty())
-    return;
-  pObj->Set(pIsolate->GetCurrentContext(),
-            FXJS_WSToJSString(pIsolate, PropertyName),
-            v8::Int32::New(pIsolate, nValue)).FromJust();
-}
-
-void FXJS_PutObjectNumber(v8::Isolate* pIsolate,
-                          v8::Local<v8::Object> pObj,
-                          const wchar_t* PropertyName,
-                          float fValue) {
-  if (pObj.IsEmpty())
-    return;
-  pObj->Set(pIsolate->GetCurrentContext(),
-            FXJS_WSToJSString(pIsolate, PropertyName),
-            v8::Number::New(pIsolate, (double)fValue)).FromJust();
-}
-
-void FXJS_PutObjectNumber(v8::Isolate* pIsolate,
-                          v8::Local<v8::Object> pObj,
-                          const wchar_t* PropertyName,
-                          double dValue) {
-  if (pObj.IsEmpty())
-    return;
-  pObj->Set(pIsolate->GetCurrentContext(),
-            FXJS_WSToJSString(pIsolate, PropertyName),
-            v8::Number::New(pIsolate, (double)dValue)).FromJust();
-}
-
-void FXJS_PutObjectBoolean(v8::Isolate* pIsolate,
-                           v8::Local<v8::Object> pObj,
-                           const wchar_t* PropertyName,
-                           bool bValue) {
-  if (pObj.IsEmpty())
-    return;
-  pObj->Set(pIsolate->GetCurrentContext(),
-            FXJS_WSToJSString(pIsolate, PropertyName),
-            v8::Boolean::New(pIsolate, bValue)).FromJust();
-}
-
-void FXJS_PutObjectObject(v8::Isolate* pIsolate,
-                          v8::Local<v8::Object> pObj,
-                          const wchar_t* PropertyName,
-                          v8::Local<v8::Object> pPut) {
-  if (pObj.IsEmpty())
-    return;
-  pObj->Set(pIsolate->GetCurrentContext(),
-            FXJS_WSToJSString(pIsolate, PropertyName), pPut).FromJust();
-}
-
-void FXJS_PutObjectNull(v8::Isolate* pIsolate,
-                        v8::Local<v8::Object> pObj,
-                        const wchar_t* PropertyName) {
-  if (pObj.IsEmpty())
-    return;
-  pObj->Set(pIsolate->GetCurrentContext(),
-            FXJS_WSToJSString(pIsolate, PropertyName),
-            v8::Local<v8::Object>()).FromJust();
-}
-
-v8::Local<v8::Array> FXJS_NewArray(v8::Isolate* pIsolate) {
-  return v8::Array::New(pIsolate);
-}
-
-unsigned FXJS_PutArrayElement(v8::Isolate* pIsolate,
-                              v8::Local<v8::Array> pArray,
-                              unsigned index,
-                              v8::Local<v8::Value> pValue) {
-  if (pArray.IsEmpty())
-    return 0;
-  if (pArray->Set(pIsolate->GetCurrentContext(), index, pValue).IsNothing())
-    return 0;
-  return 1;
-}
-
-v8::Local<v8::Value> FXJS_GetArrayElement(v8::Isolate* pIsolate,
-                                          v8::Local<v8::Array> pArray,
-                                          unsigned index) {
-  if (pArray.IsEmpty())
-    return v8::Local<v8::Value>();
-  v8::Local<v8::Value> val;
-  if (!pArray->Get(pIsolate->GetCurrentContext(), index).ToLocal(&val))
-    return v8::Local<v8::Value>();
-  return val;
-}
-
-unsigned FXJS_GetArrayLength(v8::Local<v8::Array> pArray) {
-  if (pArray.IsEmpty())
-    return 0;
-  return pArray->Length();
-}
-
-v8::Local<v8::Value> FXJS_NewNumber(v8::Isolate* pIsolate, int number) {
-  return v8::Int32::New(pIsolate, number);
-}
-
-v8::Local<v8::Value> FXJS_NewNumber(v8::Isolate* pIsolate, double number) {
-  return v8::Number::New(pIsolate, number);
-}
-
-v8::Local<v8::Value> FXJS_NewNumber(v8::Isolate* pIsolate, float number) {
-  return v8::Number::New(pIsolate, (float)number);
-}
-
-v8::Local<v8::Value> FXJS_NewBoolean(v8::Isolate* pIsolate, bool b) {
-  return v8::Boolean::New(pIsolate, b);
-}
-
-v8::Local<v8::Value> FXJS_NewObject(v8::Isolate* pIsolate,
-                                    v8::Local<v8::Object> pObj) {
-  if (pObj.IsEmpty())
-    return v8::Local<v8::Value>();
-  return pObj->Clone();
-}
-
-v8::Local<v8::Value> FXJS_NewObject2(v8::Isolate* pIsolate,
-                                     v8::Local<v8::Array> pObj) {
-  if (pObj.IsEmpty())
-    return v8::Local<v8::Value>();
-  return pObj->Clone();
-}
-
-v8::Local<v8::Value> FXJS_NewString(v8::Isolate* pIsolate,
-                                    const wchar_t* string) {
-  return FXJS_WSToJSString(pIsolate, string);
-}
-
-v8::Local<v8::Value> FXJS_NewNull() {
-  return v8::Local<v8::Value>();
-}
-
-v8::Local<v8::Value> FXJS_NewDate(v8::Isolate* pIsolate, double d) {
-  return v8::Date::New(pIsolate->GetCurrentContext(), d).ToLocalChecked();
-}
-
-int FXJS_ToInt32(v8::Isolate* pIsolate, v8::Local<v8::Value> pValue) {
-  if (pValue.IsEmpty())
-    return 0;
-  v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
-  return pValue->ToInt32(context).ToLocalChecked()->Value();
-}
-
-bool FXJS_ToBoolean(v8::Isolate* pIsolate, v8::Local<v8::Value> pValue) {
-  if (pValue.IsEmpty())
-    return false;
-  v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
-  return pValue->ToBoolean(context).ToLocalChecked()->Value();
-}
-
-double FXJS_ToNumber(v8::Isolate* pIsolate, v8::Local<v8::Value> pValue) {
-  if (pValue.IsEmpty())
-    return 0.0;
-  v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
-  return pValue->ToNumber(context).ToLocalChecked()->Value();
-}
-
-v8::Local<v8::Object> FXJS_ToObject(v8::Isolate* pIsolate,
-                                    v8::Local<v8::Value> pValue) {
-  if (pValue.IsEmpty())
-    return v8::Local<v8::Object>();
-  v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
-  return pValue->ToObject(context).ToLocalChecked();
-}
-
-CFX_WideString FXJS_ToString(v8::Isolate* pIsolate,
-                             v8::Local<v8::Value> pValue) {
-  if (pValue.IsEmpty())
-    return L"";
-  v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
-  v8::String::Utf8Value s(pValue->ToString(context).ToLocalChecked());
-  return CFX_WideString::FromUTF8(*s, s.length());
-}
-
-v8::Local<v8::Array> FXJS_ToArray(v8::Isolate* pIsolate,
-                                  v8::Local<v8::Value> pValue) {
-  if (pValue.IsEmpty())
-    return v8::Local<v8::Array>();
-  v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
-  return v8::Local<v8::Array>::Cast(pValue->ToObject(context).ToLocalChecked());
-}
-
-void FXJS_ValueCopy(v8::Local<v8::Value>& pTo, v8::Local<v8::Value> pFrom) {
-  pTo = pFrom;
-}
-
-
diff --git a/fpdfsdk/src/jsapi/fxjs_v8_embeddertest.cpp b/fpdfsdk/src/jsapi/fxjs_v8_embeddertest.cpp
deleted file mode 100644
index 8fce27b..0000000
--- a/fpdfsdk/src/jsapi/fxjs_v8_embeddertest.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2015 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.
-
-#include "testing/js_embedder_test.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-
-const wchar_t kScript[] = L"fred = 7";
-
-}  // namespace
-
-class FXJSV8EmbedderTest : public JSEmbedderTest {};
-
-TEST_F(FXJSV8EmbedderTest, Getters) {
-  v8::Isolate::Scope isolate_scope(isolate());
-#ifdef PDF_ENABLE_XFA
-  v8::Locker locker(isolate());
-#endif  // PDF_ENABLE_XFA
-  v8::HandleScope handle_scope(isolate());
-  v8::Context::Scope context_scope(GetV8Context());
-
-  FXJSErr error;
-  int sts = FXJS_Execute(isolate(), nullptr, kScript, &error);
-  EXPECT_EQ(0, sts);
-
-  v8::Local<v8::Object> This = FXJS_GetThisObj(isolate());
-  v8::Local<v8::Value> fred = FXJS_GetObjectElement(isolate(), This, L"fred");
-  EXPECT_TRUE(fred->IsNumber());
-}
diff --git a/fpdfsdk/src/pdfwindow/PWL_Button.cpp b/fpdfsdk/src/pdfwindow/PWL_Button.cpp
deleted file mode 100644
index 5c78383..0000000
--- a/fpdfsdk/src/pdfwindow/PWL_Button.cpp
+++ /dev/null
@@ -1,40 +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
-
-#include "fpdfsdk/include/pdfwindow/PWL_Button.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Wnd.h"
-
-CPWL_Button::CPWL_Button() : m_bMouseDown(FALSE) {}
-
-CPWL_Button::~CPWL_Button() {
-}
-
-CFX_ByteString CPWL_Button::GetClassName() const {
-  return "CPWL_Button";
-}
-
-void CPWL_Button::OnCreate(PWL_CREATEPARAM& cp) {
-  cp.eCursorType = FXCT_HAND;
-}
-
-FX_BOOL CPWL_Button::OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) {
-  CPWL_Wnd::OnLButtonDown(point, nFlag);
-
-  m_bMouseDown = TRUE;
-  SetCapture();
-
-  return TRUE;
-}
-
-FX_BOOL CPWL_Button::OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag) {
-  CPWL_Wnd::OnLButtonUp(point, nFlag);
-
-  ReleaseCapture();
-  m_bMouseDown = FALSE;
-
-  return TRUE;
-}
diff --git a/fpdfsdk/src/pdfwindow/PWL_Edit.cpp b/fpdfsdk/src/pdfwindow/PWL_Edit.cpp
deleted file mode 100644
index 8ddb7df..0000000
--- a/fpdfsdk/src/pdfwindow/PWL_Edit.cpp
+++ /dev/null
@@ -1,1187 +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
-
-#include "fpdfsdk/include/pdfwindow/PWL_Edit.h"
-
-#include "core/include/fxcrt/fx_safe_types.h"
-#include "core/include/fxcrt/fx_xml.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Caret.h"
-#include "fpdfsdk/include/pdfwindow/PWL_EditCtrl.h"
-#include "fpdfsdk/include/pdfwindow/PWL_FontMap.h"
-#include "fpdfsdk/include/pdfwindow/PWL_ScrollBar.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Wnd.h"
-#include "public/fpdf_fwlevent.h"
-
-CPWL_Edit::CPWL_Edit()
-    : m_pFillerNotify(NULL), m_pSpellCheck(NULL), m_bFocus(FALSE) {
-  m_pFormFiller = NULL;
-}
-
-CPWL_Edit::~CPWL_Edit() {
-  ASSERT(m_bFocus == FALSE);
-}
-
-CFX_ByteString CPWL_Edit::GetClassName() const {
-  return PWL_CLASSNAME_EDIT;
-}
-
-void CPWL_Edit::OnDestroy() {}
-
-void CPWL_Edit::SetText(const FX_WCHAR* csText) {
-  CFX_WideString swText = csText;
-
-  if (HasFlag(PES_RICH)) {
-    CFX_ByteString sValue = CFX_ByteString::FromUnicode(swText);
-
-    if (CXML_Element* pXML =
-            CXML_Element::Parse(sValue.c_str(), sValue.GetLength())) {
-      int32_t nCount = pXML->CountChildren();
-      FX_BOOL bFirst = TRUE;
-
-      swText.Empty();
-
-      for (int32_t i = 0; i < nCount; i++) {
-        if (CXML_Element* pSubElement = pXML->GetElement(i)) {
-          CFX_ByteString tag = pSubElement->GetTagName();
-          if (tag.EqualNoCase("p")) {
-            int nChild = pSubElement->CountChildren();
-            CFX_WideString swSection;
-            for (int32_t j = 0; j < nChild; j++) {
-              swSection += pSubElement->GetContent(j);
-            }
-
-            if (bFirst)
-              bFirst = FALSE;
-            else
-              swText += FWL_VKEY_Return;
-            swText += swSection;
-          }
-        }
-      }
-
-      delete pXML;
-    }
-  }
-
-  m_pEdit->SetText(swText.c_str());
-}
-
-void CPWL_Edit::RePosChildWnd() {
-  if (CPWL_ScrollBar* pVSB = GetVScrollBar()) {
-    CPDF_Rect rcWindow = m_rcOldWindow;
-    CPDF_Rect rcVScroll =
-        CPDF_Rect(rcWindow.right, rcWindow.bottom,
-                  rcWindow.right + PWL_SCROLLBAR_WIDTH, rcWindow.top);
-    pVSB->Move(rcVScroll, TRUE, FALSE);
-  }
-
-  if (m_pEditCaret && !HasFlag(PES_TEXTOVERFLOW))
-    m_pEditCaret->SetClipRect(CPWL_Utils::InflateRect(
-        GetClientRect(), 1.0f));  //+1 for caret beside border
-
-  CPWL_EditCtrl::RePosChildWnd();
-}
-
-CPDF_Rect CPWL_Edit::GetClientRect() const {
-  CPDF_Rect rcClient = CPWL_Utils::DeflateRect(
-      GetWindowRect(), (FX_FLOAT)(GetBorderWidth() + GetInnerBorderWidth()));
-
-  if (CPWL_ScrollBar* pVSB = GetVScrollBar()) {
-    if (pVSB->IsVisible()) {
-      rcClient.right -= PWL_SCROLLBAR_WIDTH;
-    }
-  }
-
-  return rcClient;
-}
-
-void CPWL_Edit::SetAlignFormatH(PWL_EDIT_ALIGNFORMAT_H nFormat,
-                                FX_BOOL bPaint) {
-  m_pEdit->SetAlignmentH((int32_t)nFormat, bPaint);
-}
-
-void CPWL_Edit::SetAlignFormatV(PWL_EDIT_ALIGNFORMAT_V nFormat,
-                                FX_BOOL bPaint) {
-  m_pEdit->SetAlignmentV((int32_t)nFormat, bPaint);
-}
-
-FX_BOOL CPWL_Edit::CanSelectAll() const {
-  return GetSelectWordRange() != m_pEdit->GetWholeWordRange();
-}
-
-FX_BOOL CPWL_Edit::CanClear() const {
-  return !IsReadOnly() && m_pEdit->IsSelected();
-}
-
-FX_BOOL CPWL_Edit::CanCopy() const {
-  return !HasFlag(PES_PASSWORD) && !HasFlag(PES_NOREAD) &&
-         m_pEdit->IsSelected();
-}
-
-FX_BOOL CPWL_Edit::CanCut() const {
-  return CanCopy() && !IsReadOnly();
-}
-
-FX_BOOL CPWL_Edit::CanPaste() const {
-  if (IsReadOnly())
-    return FALSE;
-
-  CFX_WideString swClipboard;
-  if (IFX_SystemHandler* pSH = GetSystemHandler())
-    swClipboard = pSH->GetClipboardText(GetAttachedHWnd());
-
-  return !swClipboard.IsEmpty();
-}
-
-void CPWL_Edit::CopyText() {
-  if (!CanCopy())
-    return;
-
-  CFX_WideString str = m_pEdit->GetSelText();
-
-  if (IFX_SystemHandler* pSH = GetSystemHandler())
-    pSH->SetClipboardText(GetAttachedHWnd(), str);
-}
-
-void CPWL_Edit::PasteText() {
-  if (!CanPaste())
-    return;
-
-  CFX_WideString swClipboard;
-  if (IFX_SystemHandler* pSH = GetSystemHandler())
-    swClipboard = pSH->GetClipboardText(GetAttachedHWnd());
-
-  if (m_pFillerNotify) {
-    FX_BOOL bRC = TRUE;
-    FX_BOOL bExit = FALSE;
-    CFX_WideString strChangeEx;
-    int nSelStart = 0;
-    int nSelEnd = 0;
-    GetSel(nSelStart, nSelEnd);
-    m_pFillerNotify->OnBeforeKeyStroke(GetAttachedData(), swClipboard,
-                                       strChangeEx, nSelStart, nSelEnd, TRUE,
-                                       bRC, bExit, 0);
-    if (!bRC)
-      return;
-    if (bExit)
-      return;
-  }
-
-  if (swClipboard.GetLength() > 0) {
-    Clear();
-    InsertText(swClipboard.c_str());
-  }
-}
-
-void CPWL_Edit::CutText() {
-  if (!CanCut())
-    return;
-
-  CFX_WideString str = m_pEdit->GetSelText();
-
-  if (IFX_SystemHandler* pSH = GetSystemHandler())
-    pSH->SetClipboardText(GetAttachedHWnd(), str);
-
-  m_pEdit->Clear();
-}
-
-void CPWL_Edit::OnCreated() {
-  CPWL_EditCtrl::OnCreated();
-
-  if (CPWL_ScrollBar* pScroll = GetVScrollBar()) {
-    pScroll->RemoveFlag(PWS_AUTOTRANSPARENT);
-    pScroll->SetTransparency(255);
-  }
-
-  SetParamByFlag();
-
-  m_rcOldWindow = GetWindowRect();
-
-  m_pEdit->SetOprNotify(this);
-  m_pEdit->EnableOprNotify(TRUE);
-}
-
-void CPWL_Edit::SetParamByFlag() {
-  if (HasFlag(PES_RIGHT)) {
-    m_pEdit->SetAlignmentH(2, FALSE);
-  } else if (HasFlag(PES_MIDDLE)) {
-    m_pEdit->SetAlignmentH(1, FALSE);
-  } else {
-    m_pEdit->SetAlignmentH(0, FALSE);
-  }
-
-  if (HasFlag(PES_BOTTOM)) {
-    m_pEdit->SetAlignmentV(2, FALSE);
-  } else if (HasFlag(PES_CENTER)) {
-    m_pEdit->SetAlignmentV(1, FALSE);
-  } else {
-    m_pEdit->SetAlignmentV(0, FALSE);
-  }
-
-  if (HasFlag(PES_PASSWORD)) {
-    m_pEdit->SetPasswordChar('*', FALSE);
-  }
-
-  m_pEdit->SetMultiLine(HasFlag(PES_MULTILINE), FALSE);
-  m_pEdit->SetAutoReturn(HasFlag(PES_AUTORETURN), FALSE);
-  m_pEdit->SetAutoFontSize(HasFlag(PWS_AUTOFONTSIZE), FALSE);
-  m_pEdit->SetAutoScroll(HasFlag(PES_AUTOSCROLL), FALSE);
-  m_pEdit->EnableUndo(HasFlag(PES_UNDO));
-
-  if (HasFlag(PES_TEXTOVERFLOW)) {
-    SetClipRect(CPDF_Rect(0.0f, 0.0f, 0.0f, 0.0f));
-    m_pEdit->SetTextOverflow(TRUE, FALSE);
-  } else {
-    if (m_pEditCaret) {
-      m_pEditCaret->SetClipRect(CPWL_Utils::InflateRect(
-          GetClientRect(), 1.0f));  //+1 for caret beside border
-    }
-  }
-
-  if (HasFlag(PES_SPELLCHECK)) {
-    m_pSpellCheck = GetCreationParam().pSpellCheck;
-  }
-}
-
-void CPWL_Edit::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) {
-  CPWL_Wnd::GetThisAppearanceStream(sAppStream);
-
-  CPDF_Rect rcClient = GetClientRect();
-  CFX_ByteTextBuf sLine;
-
-  int32_t nCharArray = m_pEdit->GetCharArray();
-
-  if (nCharArray > 0) {
-    switch (GetBorderStyle()) {
-      case PBS_SOLID: {
-        sLine << "q\n" << GetBorderWidth() << " w\n"
-              << CPWL_Utils::GetColorAppStream(GetBorderColor(), FALSE)
-              << " 2 J 0 j\n";
-
-        for (int32_t i = 1; i < nCharArray; i++) {
-          sLine << rcClient.left +
-                       ((rcClient.right - rcClient.left) / nCharArray) * i
-                << " " << rcClient.bottom << " m\n"
-                << rcClient.left +
-                       ((rcClient.right - rcClient.left) / nCharArray) * i
-                << " " << rcClient.top << " l S\n";
-        }
-
-        sLine << "Q\n";
-      } break;
-      case PBS_DASH: {
-        sLine << "q\n" << GetBorderWidth() << " w\n"
-              << CPWL_Utils::GetColorAppStream(GetBorderColor(), FALSE)
-              << " 2 J 0 j\n"
-              << "[" << GetBorderDash().nDash << " " << GetBorderDash().nGap
-              << "] " << GetBorderDash().nPhase << " d\n";
-
-        for (int32_t i = 1; i < nCharArray; i++) {
-          sLine << rcClient.left +
-                       ((rcClient.right - rcClient.left) / nCharArray) * i
-                << " " << rcClient.bottom << " m\n"
-                << rcClient.left +
-                       ((rcClient.right - rcClient.left) / nCharArray) * i
-                << " " << rcClient.top << " l S\n";
-        }
-
-        sLine << "Q\n";
-      } break;
-    }
-  }
-
-  sAppStream << sLine;
-
-  CFX_ByteTextBuf sText;
-
-  CPDF_Point ptOffset = CPDF_Point(0.0f, 0.0f);
-
-  CPVT_WordRange wrWhole = m_pEdit->GetWholeWordRange();
-  CPVT_WordRange wrSelect = GetSelectWordRange();
-  CPVT_WordRange wrVisible =
-      (HasFlag(PES_TEXTOVERFLOW) ? wrWhole : m_pEdit->GetVisibleWordRange());
-  CPVT_WordRange wrSelBefore(wrWhole.BeginPos, wrSelect.BeginPos);
-  CPVT_WordRange wrSelAfter(wrSelect.EndPos, wrWhole.EndPos);
-
-  CPVT_WordRange wrTemp =
-      CPWL_Utils::OverlapWordRange(GetSelectWordRange(), wrVisible);
-  CFX_ByteString sEditSel =
-      CPWL_Utils::GetEditSelAppStream(m_pEdit, ptOffset, &wrTemp);
-
-  if (sEditSel.GetLength() > 0)
-    sText << CPWL_Utils::GetColorAppStream(PWL_DEFAULT_SELBACKCOLOR)
-          << sEditSel;
-
-  wrTemp = CPWL_Utils::OverlapWordRange(wrVisible, wrSelBefore);
-  CFX_ByteString sEditBefore = CPWL_Utils::GetEditAppStream(
-      m_pEdit, ptOffset, &wrTemp, !HasFlag(PES_CHARARRAY),
-      m_pEdit->GetPasswordChar());
-
-  if (sEditBefore.GetLength() > 0)
-    sText << "BT\n" << CPWL_Utils::GetColorAppStream(GetTextColor())
-          << sEditBefore << "ET\n";
-
-  wrTemp = CPWL_Utils::OverlapWordRange(wrVisible, wrSelect);
-  CFX_ByteString sEditMid = CPWL_Utils::GetEditAppStream(
-      m_pEdit, ptOffset, &wrTemp, !HasFlag(PES_CHARARRAY),
-      m_pEdit->GetPasswordChar());
-
-  if (sEditMid.GetLength() > 0)
-    sText << "BT\n"
-          << CPWL_Utils::GetColorAppStream(CPWL_Color(COLORTYPE_GRAY, 1))
-          << sEditMid << "ET\n";
-
-  wrTemp = CPWL_Utils::OverlapWordRange(wrVisible, wrSelAfter);
-  CFX_ByteString sEditAfter = CPWL_Utils::GetEditAppStream(
-      m_pEdit, ptOffset, &wrTemp, !HasFlag(PES_CHARARRAY),
-      m_pEdit->GetPasswordChar());
-
-  if (sEditAfter.GetLength() > 0)
-    sText << "BT\n" << CPWL_Utils::GetColorAppStream(GetTextColor())
-          << sEditAfter << "ET\n";
-
-  if (HasFlag(PES_SPELLCHECK)) {
-    CFX_ByteString sSpellCheck = CPWL_Utils::GetSpellCheckAppStream(
-        m_pEdit, m_pSpellCheck, ptOffset, &wrVisible);
-    if (sSpellCheck.GetLength() > 0)
-      sText << CPWL_Utils::GetColorAppStream(CPWL_Color(COLORTYPE_RGB, 1, 0, 0),
-                                             FALSE)
-            << sSpellCheck;
-  }
-
-  if (sText.GetLength() > 0) {
-    CPDF_Rect rcClient = GetClientRect();
-    sAppStream << "q\n/Tx BMC\n";
-
-    if (!HasFlag(PES_TEXTOVERFLOW))
-      sAppStream << rcClient.left << " " << rcClient.bottom << " "
-                 << rcClient.right - rcClient.left << " "
-                 << rcClient.top - rcClient.bottom << " re W n\n";
-
-    sAppStream << sText;
-
-    sAppStream << "EMC\nQ\n";
-  }
-}
-
-void CPWL_Edit::DrawThisAppearance(CFX_RenderDevice* pDevice,
-                                   CFX_Matrix* pUser2Device) {
-  CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device);
-
-  CPDF_Rect rcClient = GetClientRect();
-  CFX_ByteTextBuf sLine;
-
-  int32_t nCharArray = m_pEdit->GetCharArray();
-  FX_SAFE_INT32 nCharArraySafe = nCharArray;
-  nCharArraySafe -= 1;
-  nCharArraySafe *= 2;
-
-  if (nCharArray > 0 && nCharArraySafe.IsValid()) {
-    switch (GetBorderStyle()) {
-      case PBS_SOLID: {
-        CFX_GraphStateData gsd;
-        gsd.m_LineWidth = (FX_FLOAT)GetBorderWidth();
-
-        CFX_PathData path;
-        path.SetPointCount(nCharArraySafe.ValueOrDie());
-
-        for (int32_t i = 0; i < nCharArray - 1; i++) {
-          path.SetPoint(
-              i * 2,
-              rcClient.left +
-                  ((rcClient.right - rcClient.left) / nCharArray) * (i + 1),
-              rcClient.bottom, FXPT_MOVETO);
-          path.SetPoint(
-              i * 2 + 1,
-              rcClient.left +
-                  ((rcClient.right - rcClient.left) / nCharArray) * (i + 1),
-              rcClient.top, FXPT_LINETO);
-        }
-        if (path.GetPointCount() > 0)
-          pDevice->DrawPath(
-              &path, pUser2Device, &gsd, 0,
-              CPWL_Utils::PWLColorToFXColor(GetBorderColor(), 255),
-              FXFILL_ALTERNATE);
-      } break;
-      case PBS_DASH: {
-        CFX_GraphStateData gsd;
-        gsd.m_LineWidth = (FX_FLOAT)GetBorderWidth();
-
-        gsd.SetDashCount(2);
-        gsd.m_DashArray[0] = (FX_FLOAT)GetBorderDash().nDash;
-        gsd.m_DashArray[1] = (FX_FLOAT)GetBorderDash().nGap;
-        gsd.m_DashPhase = (FX_FLOAT)GetBorderDash().nPhase;
-
-        CFX_PathData path;
-        path.SetPointCount(nCharArraySafe.ValueOrDie());
-
-        for (int32_t i = 0; i < nCharArray - 1; i++) {
-          path.SetPoint(
-              i * 2,
-              rcClient.left +
-                  ((rcClient.right - rcClient.left) / nCharArray) * (i + 1),
-              rcClient.bottom, FXPT_MOVETO);
-          path.SetPoint(
-              i * 2 + 1,
-              rcClient.left +
-                  ((rcClient.right - rcClient.left) / nCharArray) * (i + 1),
-              rcClient.top, FXPT_LINETO);
-        }
-        if (path.GetPointCount() > 0)
-          pDevice->DrawPath(
-              &path, pUser2Device, &gsd, 0,
-              CPWL_Utils::PWLColorToFXColor(GetBorderColor(), 255),
-              FXFILL_ALTERNATE);
-      } break;
-    }
-  }
-
-  CPDF_Rect rcClip;
-  CPVT_WordRange wrRange = m_pEdit->GetVisibleWordRange();
-  CPVT_WordRange* pRange = NULL;
-
-  if (!HasFlag(PES_TEXTOVERFLOW)) {
-    rcClip = GetClientRect();
-    pRange = &wrRange;
-  }
-  IFX_SystemHandler* pSysHandler = GetSystemHandler();
-  IFX_Edit::DrawEdit(
-      pDevice, pUser2Device, m_pEdit,
-      CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()),
-      CPWL_Utils::PWLColorToFXColor(GetTextStrokeColor(), GetTransparency()),
-      rcClip, CPDF_Point(0.0f, 0.0f), pRange, pSysHandler, m_pFormFiller);
-
-  if (HasFlag(PES_SPELLCHECK)) {
-    CPWL_Utils::DrawEditSpellCheck(pDevice, pUser2Device, m_pEdit, rcClip,
-                                   CPDF_Point(0.0f, 0.0f), pRange,
-                                   GetCreationParam().pSpellCheck);
-  }
-}
-
-FX_BOOL CPWL_Edit::OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) {
-  CPWL_Wnd::OnLButtonDown(point, nFlag);
-
-  if (HasFlag(PES_TEXTOVERFLOW) || ClientHitTest(point)) {
-    if (m_bMouseDown)
-      InvalidateRect();
-
-    m_bMouseDown = TRUE;
-    SetCapture();
-
-    m_pEdit->OnMouseDown(point, IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
-  }
-
-  return TRUE;
-}
-
-FX_BOOL CPWL_Edit::OnLButtonDblClk(const CPDF_Point& point, FX_DWORD nFlag) {
-  CPWL_Wnd::OnLButtonDblClk(point, nFlag);
-
-  if (HasFlag(PES_TEXTOVERFLOW) || ClientHitTest(point)) {
-    m_pEdit->SelectAll();
-  }
-
-  return TRUE;
-}
-
-#define WM_PWLEDIT_UNDO 0x01
-#define WM_PWLEDIT_REDO 0x02
-#define WM_PWLEDIT_CUT 0x03
-#define WM_PWLEDIT_COPY 0x04
-#define WM_PWLEDIT_PASTE 0x05
-#define WM_PWLEDIT_DELETE 0x06
-#define WM_PWLEDIT_SELECTALL 0x07
-#define WM_PWLEDIT_SUGGEST 0x08
-
-FX_BOOL CPWL_Edit::OnRButtonUp(const CPDF_Point& point, FX_DWORD nFlag) {
-  if (m_bMouseDown)
-    return FALSE;
-
-  CPWL_Wnd::OnRButtonUp(point, nFlag);
-
-  if (!HasFlag(PES_TEXTOVERFLOW) && !ClientHitTest(point))
-    return TRUE;
-
-  IFX_SystemHandler* pSH = GetSystemHandler();
-  if (!pSH)
-    return FALSE;
-
-  SetFocus();
-
-  CPVT_WordRange wrLatin = GetLatinWordsRange(point);
-  CFX_WideString swLatin = m_pEdit->GetRangeText(wrLatin);
-
-  FX_HMENU hPopup = pSH->CreatePopupMenu();
-  if (!hPopup)
-    return FALSE;
-
-  CFX_ByteStringArray sSuggestWords;
-  CPDF_Point ptPopup = point;
-
-  if (!IsReadOnly()) {
-    if (HasFlag(PES_SPELLCHECK) && !swLatin.IsEmpty()) {
-      if (m_pSpellCheck) {
-        CFX_ByteString sLatin = CFX_ByteString::FromUnicode(swLatin);
-
-        if (!m_pSpellCheck->CheckWord(sLatin)) {
-          m_pSpellCheck->SuggestWords(sLatin, sSuggestWords);
-
-          int32_t nSuggest = sSuggestWords.GetSize();
-
-          for (int32_t nWord = 0; nWord < nSuggest; nWord++) {
-            pSH->AppendMenuItem(hPopup, WM_PWLEDIT_SUGGEST + nWord,
-                                sSuggestWords[nWord].UTF8Decode());
-          }
-
-          if (nSuggest > 0)
-            pSH->AppendMenuItem(hPopup, 0, L"");
-
-          ptPopup = GetWordRightBottomPoint(wrLatin.EndPos);
-        }
-      }
-    }
-  }
-
-  IPWL_Provider* pProvider = GetProvider();
-
-  if (HasFlag(PES_UNDO)) {
-    pSH->AppendMenuItem(
-        hPopup, WM_PWLEDIT_UNDO,
-        pProvider ? pProvider->LoadPopupMenuString(0) : L"&Undo");
-    pSH->AppendMenuItem(
-        hPopup, WM_PWLEDIT_REDO,
-        pProvider ? pProvider->LoadPopupMenuString(1) : L"&Redo");
-    pSH->AppendMenuItem(hPopup, 0, L"");
-
-    if (!m_pEdit->CanUndo())
-      pSH->EnableMenuItem(hPopup, WM_PWLEDIT_UNDO, FALSE);
-    if (!m_pEdit->CanRedo())
-      pSH->EnableMenuItem(hPopup, WM_PWLEDIT_REDO, FALSE);
-  }
-
-  pSH->AppendMenuItem(hPopup, WM_PWLEDIT_CUT,
-                      pProvider ? pProvider->LoadPopupMenuString(2) : L"Cu&t");
-  pSH->AppendMenuItem(hPopup, WM_PWLEDIT_COPY,
-                      pProvider ? pProvider->LoadPopupMenuString(3) : L"&Copy");
-  pSH->AppendMenuItem(
-      hPopup, WM_PWLEDIT_PASTE,
-      pProvider ? pProvider->LoadPopupMenuString(4) : L"&Paste");
-  pSH->AppendMenuItem(
-      hPopup, WM_PWLEDIT_DELETE,
-      pProvider ? pProvider->LoadPopupMenuString(5) : L"&Delete");
-
-  CFX_WideString swText = pSH->GetClipboardText(GetAttachedHWnd());
-  if (swText.IsEmpty())
-    pSH->EnableMenuItem(hPopup, WM_PWLEDIT_PASTE, FALSE);
-
-  if (!m_pEdit->IsSelected()) {
-    pSH->EnableMenuItem(hPopup, WM_PWLEDIT_CUT, FALSE);
-    pSH->EnableMenuItem(hPopup, WM_PWLEDIT_COPY, FALSE);
-    pSH->EnableMenuItem(hPopup, WM_PWLEDIT_DELETE, FALSE);
-  }
-
-  if (IsReadOnly()) {
-    pSH->EnableMenuItem(hPopup, WM_PWLEDIT_CUT, FALSE);
-    pSH->EnableMenuItem(hPopup, WM_PWLEDIT_DELETE, FALSE);
-    pSH->EnableMenuItem(hPopup, WM_PWLEDIT_PASTE, FALSE);
-  }
-
-  if (HasFlag(PES_PASSWORD)) {
-    pSH->EnableMenuItem(hPopup, WM_PWLEDIT_CUT, FALSE);
-    pSH->EnableMenuItem(hPopup, WM_PWLEDIT_COPY, FALSE);
-  }
-
-  if (HasFlag(PES_NOREAD)) {
-    pSH->EnableMenuItem(hPopup, WM_PWLEDIT_CUT, FALSE);
-    pSH->EnableMenuItem(hPopup, WM_PWLEDIT_COPY, FALSE);
-  }
-
-  pSH->AppendMenuItem(hPopup, 0, L"");
-  pSH->AppendMenuItem(
-      hPopup, WM_PWLEDIT_SELECTALL,
-      pProvider ? pProvider->LoadPopupMenuString(6) : L"&Select All");
-
-  if (m_pEdit->GetTotalWords() == 0) {
-    pSH->EnableMenuItem(hPopup, WM_PWLEDIT_SELECTALL, FALSE);
-  }
-
-  int32_t x, y;
-  PWLtoWnd(ptPopup, x, y);
-  pSH->ClientToScreen(GetAttachedHWnd(), x, y);
-  pSH->SetCursor(FXCT_ARROW);
-  int32_t nCmd = pSH->TrackPopupMenu(hPopup, x, y, GetAttachedHWnd());
-
-  switch (nCmd) {
-    case WM_PWLEDIT_UNDO:
-      Undo();
-      break;
-    case WM_PWLEDIT_REDO:
-      Redo();
-      break;
-    case WM_PWLEDIT_CUT:
-      CutText();
-      break;
-    case WM_PWLEDIT_COPY:
-      CopyText();
-      break;
-    case WM_PWLEDIT_PASTE:
-      PasteText();
-      break;
-    case WM_PWLEDIT_DELETE:
-      Clear();
-      break;
-    case WM_PWLEDIT_SELECTALL:
-      SelectAll();
-      break;
-    case WM_PWLEDIT_SUGGEST + 0:
-      SetSel(m_pEdit->WordPlaceToWordIndex(wrLatin.BeginPos),
-             m_pEdit->WordPlaceToWordIndex(wrLatin.EndPos));
-      ReplaceSel(sSuggestWords[0].UTF8Decode().c_str());
-      break;
-    case WM_PWLEDIT_SUGGEST + 1:
-      SetSel(m_pEdit->WordPlaceToWordIndex(wrLatin.BeginPos),
-             m_pEdit->WordPlaceToWordIndex(wrLatin.EndPos));
-      ReplaceSel(sSuggestWords[1].UTF8Decode().c_str());
-      break;
-    case WM_PWLEDIT_SUGGEST + 2:
-      SetSel(m_pEdit->WordPlaceToWordIndex(wrLatin.BeginPos),
-             m_pEdit->WordPlaceToWordIndex(wrLatin.EndPos));
-      ReplaceSel(sSuggestWords[2].UTF8Decode().c_str());
-      break;
-    case WM_PWLEDIT_SUGGEST + 3:
-      SetSel(m_pEdit->WordPlaceToWordIndex(wrLatin.BeginPos),
-             m_pEdit->WordPlaceToWordIndex(wrLatin.EndPos));
-      ReplaceSel(sSuggestWords[3].UTF8Decode().c_str());
-      break;
-    case WM_PWLEDIT_SUGGEST + 4:
-      SetSel(m_pEdit->WordPlaceToWordIndex(wrLatin.BeginPos),
-             m_pEdit->WordPlaceToWordIndex(wrLatin.EndPos));
-      ReplaceSel(sSuggestWords[4].UTF8Decode().c_str());
-      break;
-    default:
-      break;
-  }
-
-  pSH->DestroyMenu(hPopup);
-
-  return TRUE;
-}
-
-void CPWL_Edit::OnSetFocus() {
-  SetEditCaret(TRUE);
-
-  if (!IsReadOnly()) {
-    if (IPWL_FocusHandler* pFocusHandler = GetFocusHandler())
-      pFocusHandler->OnSetFocus(this);
-  }
-
-  m_bFocus = TRUE;
-}
-
-void CPWL_Edit::OnKillFocus() {
-  ShowVScrollBar(FALSE);
-
-  m_pEdit->SelectNone();
-  SetCaret(FALSE, CPDF_Point(0.0f, 0.0f), CPDF_Point(0.0f, 0.0f));
-
-  SetCharSet(0);
-
-  if (!IsReadOnly()) {
-    if (IPWL_FocusHandler* pFocusHandler = GetFocusHandler())
-      pFocusHandler->OnKillFocus(this);
-  }
-
-  m_bFocus = FALSE;
-}
-
-void CPWL_Edit::SetHorzScale(int32_t nHorzScale, FX_BOOL bPaint /* = TRUE*/) {
-  m_pEdit->SetHorzScale(nHorzScale, bPaint);
-}
-
-void CPWL_Edit::SetCharSpace(FX_FLOAT fCharSpace, FX_BOOL bPaint /* = TRUE*/) {
-  m_pEdit->SetCharSpace(fCharSpace, bPaint);
-}
-
-void CPWL_Edit::SetLineLeading(FX_FLOAT fLineLeading,
-                               FX_BOOL bPaint /* = TRUE*/) {
-  m_pEdit->SetLineLeading(fLineLeading, bPaint);
-}
-
-CFX_ByteString CPWL_Edit::GetSelectAppearanceStream(
-    const CPDF_Point& ptOffset) const {
-  CPVT_WordRange wr = GetSelectWordRange();
-  return CPWL_Utils::GetEditSelAppStream(m_pEdit, ptOffset, &wr);
-}
-
-CPVT_WordRange CPWL_Edit::GetSelectWordRange() const {
-  if (m_pEdit->IsSelected()) {
-    int32_t nStart = -1;
-    int32_t nEnd = -1;
-
-    m_pEdit->GetSel(nStart, nEnd);
-
-    CPVT_WordPlace wpStart = m_pEdit->WordIndexToWordPlace(nStart);
-    CPVT_WordPlace wpEnd = m_pEdit->WordIndexToWordPlace(nEnd);
-
-    return CPVT_WordRange(wpStart, wpEnd);
-  }
-
-  return CPVT_WordRange();
-}
-
-CFX_ByteString CPWL_Edit::GetTextAppearanceStream(
-    const CPDF_Point& ptOffset) const {
-  CFX_ByteTextBuf sRet;
-  CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream(m_pEdit, ptOffset);
-
-  if (sEdit.GetLength() > 0) {
-    sRet << "BT\n" << CPWL_Utils::GetColorAppStream(GetTextColor()) << sEdit
-         << "ET\n";
-  }
-
-  return sRet.GetByteString();
-}
-
-CFX_ByteString CPWL_Edit::GetCaretAppearanceStream(
-    const CPDF_Point& ptOffset) const {
-  if (m_pEditCaret)
-    return m_pEditCaret->GetCaretAppearanceStream(ptOffset);
-
-  return CFX_ByteString();
-}
-
-CPDF_Point CPWL_Edit::GetWordRightBottomPoint(const CPVT_WordPlace& wpWord) {
-  CPDF_Point pt(0.0f, 0.0f);
-
-  if (IFX_Edit_Iterator* pIterator = m_pEdit->GetIterator()) {
-    CPVT_WordPlace wpOld = pIterator->GetAt();
-    pIterator->SetAt(wpWord);
-    CPVT_Word word;
-    if (pIterator->GetWord(word)) {
-      pt = CPDF_Point(word.ptWord.x + word.fWidth,
-                      word.ptWord.y + word.fDescent);
-    }
-
-    pIterator->SetAt(wpOld);
-  }
-
-  return pt;
-}
-
-FX_BOOL CPWL_Edit::IsTextFull() const {
-  return m_pEdit->IsTextFull();
-}
-
-FX_FLOAT CPWL_Edit::GetCharArrayAutoFontSize(CPDF_Font* pFont,
-                                             const CPDF_Rect& rcPlate,
-                                             int32_t nCharArray) {
-  if (pFont && !pFont->IsStandardFont()) {
-    FX_RECT rcBBox;
-    pFont->GetFontBBox(rcBBox);
-
-    CPDF_Rect rcCell = rcPlate;
-    FX_FLOAT xdiv = rcCell.Width() / nCharArray * 1000.0f / rcBBox.Width();
-    FX_FLOAT ydiv = -rcCell.Height() * 1000.0f / rcBBox.Height();
-
-    return xdiv < ydiv ? xdiv : ydiv;
-  }
-
-  return 0.0f;
-}
-
-void CPWL_Edit::SetCharArray(int32_t nCharArray) {
-  if (HasFlag(PES_CHARARRAY) && nCharArray > 0) {
-    m_pEdit->SetCharArray(nCharArray);
-    m_pEdit->SetTextOverflow(TRUE);
-
-    if (HasFlag(PWS_AUTOFONTSIZE)) {
-      if (IFX_Edit_FontMap* pFontMap = GetFontMap()) {
-        FX_FLOAT fFontSize = GetCharArrayAutoFontSize(
-            pFontMap->GetPDFFont(0), GetClientRect(), nCharArray);
-        if (fFontSize > 0.0f) {
-          m_pEdit->SetAutoFontSize(FALSE);
-          m_pEdit->SetFontSize(fFontSize);
-        }
-      }
-    }
-  }
-}
-
-void CPWL_Edit::SetLimitChar(int32_t nLimitChar) {
-  m_pEdit->SetLimitChar(nLimitChar);
-}
-
-void CPWL_Edit::ReplaceSel(const FX_WCHAR* csText) {
-  m_pEdit->Clear();
-  m_pEdit->InsertText(csText);
-}
-
-CPDF_Rect CPWL_Edit::GetFocusRect() const {
-  return CPDF_Rect();
-}
-
-void CPWL_Edit::ShowVScrollBar(FX_BOOL bShow) {
-  if (CPWL_ScrollBar* pScroll = GetVScrollBar()) {
-    if (bShow) {
-      if (!pScroll->IsVisible()) {
-        pScroll->SetVisible(TRUE);
-        CPDF_Rect rcWindow = GetWindowRect();
-        m_rcOldWindow = rcWindow;
-        rcWindow.right += PWL_SCROLLBAR_WIDTH;
-        Move(rcWindow, TRUE, TRUE);
-      }
-    } else {
-      if (pScroll->IsVisible()) {
-        pScroll->SetVisible(FALSE);
-        Move(m_rcOldWindow, TRUE, TRUE);
-      }
-    }
-  }
-}
-
-FX_BOOL CPWL_Edit::IsVScrollBarVisible() const {
-  if (CPWL_ScrollBar* pScroll = GetVScrollBar()) {
-    return pScroll->IsVisible();
-  }
-
-  return FALSE;
-}
-
-void CPWL_Edit::EnableSpellCheck(FX_BOOL bEnabled) {
-  if (bEnabled)
-    AddFlag(PES_SPELLCHECK);
-  else
-    RemoveFlag(PES_SPELLCHECK);
-}
-
-FX_BOOL CPWL_Edit::OnKeyDown(FX_WORD nChar, FX_DWORD nFlag) {
-  if (m_bMouseDown)
-    return TRUE;
-
-  if (nChar == FWL_VKEY_Delete) {
-    if (m_pFillerNotify) {
-      FX_BOOL bRC = TRUE;
-      FX_BOOL bExit = FALSE;
-      CFX_WideString strChange;
-      CFX_WideString strChangeEx;
-
-      int nSelStart = 0;
-      int nSelEnd = 0;
-      GetSel(nSelStart, nSelEnd);
-
-      if (nSelStart == nSelEnd)
-        nSelEnd = nSelStart + 1;
-      m_pFillerNotify->OnBeforeKeyStroke(GetAttachedData(), strChange,
-                                         strChangeEx, nSelStart, nSelEnd, TRUE,
-                                         bRC, bExit, nFlag);
-      if (!bRC)
-        return FALSE;
-      if (bExit)
-        return FALSE;
-    }
-  }
-
-  FX_BOOL bRet = CPWL_EditCtrl::OnKeyDown(nChar, nFlag);
-
-  // In case of implementation swallow the OnKeyDown event.
-  if (IsProceedtoOnChar(nChar, nFlag))
-    return TRUE;
-
-  return bRet;
-}
-
-/**
-*In case of implementation swallow the OnKeyDown event.
-*If the event is swallowed, implementation may do other unexpected things, which
-*is not the control means to do.
-*/
-FX_BOOL CPWL_Edit::IsProceedtoOnChar(FX_WORD nKeyCode, FX_DWORD nFlag) {
-  FX_BOOL bCtrl = IsCTRLpressed(nFlag);
-  FX_BOOL bAlt = IsALTpressed(nFlag);
-  if (bCtrl && !bAlt) {
-    // hot keys for edit control.
-    switch (nKeyCode) {
-      case 'C':
-      case 'V':
-      case 'X':
-      case 'A':
-      case 'Z':
-        return TRUE;
-      default:
-        break;
-    }
-  }
-  // control characters.
-  switch (nKeyCode) {
-    case FWL_VKEY_Escape:
-    case FWL_VKEY_Back:
-    case FWL_VKEY_Return:
-    case FWL_VKEY_Space:
-      return TRUE;
-    default:
-      return FALSE;
-  }
-}
-
-FX_BOOL CPWL_Edit::OnChar(FX_WORD nChar, FX_DWORD nFlag) {
-  if (m_bMouseDown)
-    return TRUE;
-
-  FX_BOOL bRC = TRUE;
-  FX_BOOL bExit = FALSE;
-
-  if (!IsCTRLpressed(nFlag)) {
-    if (m_pFillerNotify) {
-      CFX_WideString swChange;
-
-      int nSelStart = 0;
-      int nSelEnd = 0;
-      GetSel(nSelStart, nSelEnd);
-
-      switch (nChar) {
-        case FWL_VKEY_Back:
-          if (nSelStart == nSelEnd)
-            nSelStart = nSelEnd - 1;
-          break;
-        case FWL_VKEY_Return:
-          break;
-        default:
-          swChange += nChar;
-          break;
-      }
-
-      CFX_WideString strChangeEx;
-      m_pFillerNotify->OnBeforeKeyStroke(GetAttachedData(), swChange,
-                                         strChangeEx, nSelStart, nSelEnd, TRUE,
-                                         bRC, bExit, nFlag);
-    }
-  }
-
-  if (!bRC)
-    return TRUE;
-  if (bExit)
-    return FALSE;
-
-  if (IFX_Edit_FontMap* pFontMap = GetFontMap()) {
-    int32_t nOldCharSet = GetCharSet();
-    int32_t nNewCharSet = pFontMap->CharSetFromUnicode(nChar, DEFAULT_CHARSET);
-    if (nOldCharSet != nNewCharSet) {
-      SetCharSet(nNewCharSet);
-    }
-  }
-
-  return CPWL_EditCtrl::OnChar(nChar, nFlag);
-}
-
-FX_BOOL CPWL_Edit::OnMouseWheel(short zDelta,
-                                const CPDF_Point& point,
-                                FX_DWORD nFlag) {
-  if (HasFlag(PES_MULTILINE)) {
-    CPDF_Point ptScroll = GetScrollPos();
-
-    if (zDelta > 0) {
-      ptScroll.y += GetFontSize();
-    } else {
-      ptScroll.y -= GetFontSize();
-    }
-    SetScrollPos(ptScroll);
-
-    return TRUE;
-  }
-
-  return FALSE;
-}
-
-void CPWL_Edit::OnInsertReturn(const CPVT_WordPlace& place,
-                               const CPVT_WordPlace& oldplace) {
-  if (HasFlag(PES_SPELLCHECK)) {
-    m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
-                                               GetLatinWordsRange(place)));
-  }
-
-  if (m_pEditNotify) {
-    m_pEditNotify->OnInsertReturn(place, oldplace);
-  }
-}
-
-void CPWL_Edit::OnBackSpace(const CPVT_WordPlace& place,
-                            const CPVT_WordPlace& oldplace) {
-  if (HasFlag(PES_SPELLCHECK)) {
-    m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
-                                               GetLatinWordsRange(place)));
-  }
-
-  if (m_pEditNotify) {
-    m_pEditNotify->OnBackSpace(place, oldplace);
-  }
-}
-
-void CPWL_Edit::OnDelete(const CPVT_WordPlace& place,
-                         const CPVT_WordPlace& oldplace) {
-  if (HasFlag(PES_SPELLCHECK)) {
-    m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
-                                               GetLatinWordsRange(place)));
-  }
-
-  if (m_pEditNotify) {
-    m_pEditNotify->OnDelete(place, oldplace);
-  }
-}
-
-void CPWL_Edit::OnClear(const CPVT_WordPlace& place,
-                        const CPVT_WordPlace& oldplace) {
-  if (HasFlag(PES_SPELLCHECK)) {
-    m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
-                                               GetLatinWordsRange(place)));
-  }
-
-  if (m_pEditNotify) {
-    m_pEditNotify->OnClear(place, oldplace);
-  }
-}
-
-void CPWL_Edit::OnInsertWord(const CPVT_WordPlace& place,
-                             const CPVT_WordPlace& oldplace) {
-  if (HasFlag(PES_SPELLCHECK)) {
-    m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
-                                               GetLatinWordsRange(place)));
-  }
-
-  if (m_pEditNotify) {
-    m_pEditNotify->OnInsertWord(place, oldplace);
-  }
-}
-
-void CPWL_Edit::OnSetText(const CPVT_WordPlace& place,
-                          const CPVT_WordPlace& oldplace) {}
-
-void CPWL_Edit::OnInsertText(const CPVT_WordPlace& place,
-                             const CPVT_WordPlace& oldplace) {
-  if (HasFlag(PES_SPELLCHECK)) {
-    m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
-                                               GetLatinWordsRange(place)));
-  }
-
-  if (m_pEditNotify) {
-    m_pEditNotify->OnInsertText(place, oldplace);
-  }
-}
-
-void CPWL_Edit::OnAddUndo(IFX_Edit_UndoItem* pUndoItem) {
-  if (m_pEditNotify) {
-    m_pEditNotify->OnAddUndo(this);
-  }
-}
-
-CPVT_WordRange CPWL_Edit::CombineWordRange(const CPVT_WordRange& wr1,
-                                           const CPVT_WordRange& wr2) {
-  CPVT_WordRange wrRet;
-
-  if (wr1.BeginPos.WordCmp(wr2.BeginPos) < 0) {
-    wrRet.BeginPos = wr1.BeginPos;
-  } else {
-    wrRet.BeginPos = wr2.BeginPos;
-  }
-
-  if (wr1.EndPos.WordCmp(wr2.EndPos) < 0) {
-    wrRet.EndPos = wr2.EndPos;
-  } else {
-    wrRet.EndPos = wr1.EndPos;
-  }
-
-  return wrRet;
-}
-
-CPVT_WordRange CPWL_Edit::GetLatinWordsRange(const CPDF_Point& point) const {
-  return GetSameWordsRange(m_pEdit->SearchWordPlace(point), TRUE, FALSE);
-}
-
-CPVT_WordRange CPWL_Edit::GetLatinWordsRange(
-    const CPVT_WordPlace& place) const {
-  return GetSameWordsRange(place, TRUE, FALSE);
-}
-
-CPVT_WordRange CPWL_Edit::GetArabicWordsRange(
-    const CPVT_WordPlace& place) const {
-  return GetSameWordsRange(place, FALSE, TRUE);
-}
-
-#define PWL_ISARABICWORD(word) \
-  ((word >= 0x0600 && word <= 0x06FF) || (word >= 0xFB50 && word <= 0xFEFC))
-
-CPVT_WordRange CPWL_Edit::GetSameWordsRange(const CPVT_WordPlace& place,
-                                            FX_BOOL bLatin,
-                                            FX_BOOL bArabic) const {
-  CPVT_WordRange range;
-
-  if (IFX_Edit_Iterator* pIterator = m_pEdit->GetIterator()) {
-    CPVT_Word wordinfo;
-    CPVT_WordPlace wpStart(place), wpEnd(place);
-    pIterator->SetAt(place);
-
-    if (bLatin) {
-      while (pIterator->NextWord()) {
-        if (!pIterator->GetWord(wordinfo) ||
-            !FX_EDIT_ISLATINWORD(wordinfo.Word)) {
-          break;
-        }
-
-        wpEnd = pIterator->GetAt();
-      }
-    } else if (bArabic) {
-      while (pIterator->NextWord()) {
-        if (!pIterator->GetWord(wordinfo) || !PWL_ISARABICWORD(wordinfo.Word))
-          break;
-
-        wpEnd = pIterator->GetAt();
-      }
-    }
-
-    pIterator->SetAt(place);
-
-    if (bLatin) {
-      do {
-        if (!pIterator->GetWord(wordinfo) ||
-            !FX_EDIT_ISLATINWORD(wordinfo.Word)) {
-          break;
-        }
-
-        wpStart = pIterator->GetAt();
-      } while (pIterator->PrevWord());
-    } else if (bArabic) {
-      do {
-        if (!pIterator->GetWord(wordinfo) || !PWL_ISARABICWORD(wordinfo.Word))
-          break;
-
-        wpStart = pIterator->GetAt();
-      } while (pIterator->PrevWord());
-    }
-
-    range.Set(wpStart, wpEnd);
-  }
-
-  return range;
-}
-
-void CPWL_Edit::GeneratePageObjects(
-    CPDF_PageObjects* pPageObjects,
-    const CPDF_Point& ptOffset,
-    CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray) {
-  IFX_Edit::GeneratePageObjects(
-      pPageObjects, m_pEdit, ptOffset, NULL,
-      CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()),
-      ObjArray);
-}
-
-void CPWL_Edit::GeneratePageObjects(CPDF_PageObjects* pPageObjects,
-                                    const CPDF_Point& ptOffset) {
-  CFX_ArrayTemplate<CPDF_TextObject*> ObjArray;
-  IFX_Edit::GeneratePageObjects(
-      pPageObjects, m_pEdit, ptOffset, NULL,
-      CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()),
-      ObjArray);
-}
diff --git a/fpdfsdk/src/pdfwindow/PWL_EditCtrl.cpp b/fpdfsdk/src/pdfwindow/PWL_EditCtrl.cpp
deleted file mode 100644
index c505c7e..0000000
--- a/fpdfsdk/src/pdfwindow/PWL_EditCtrl.cpp
+++ /dev/null
@@ -1,624 +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
-
-#include "fpdfsdk/include/pdfwindow/PWL_EditCtrl.h"
-
-#include "fpdfsdk/include/pdfwindow/PWL_Caret.h"
-#include "fpdfsdk/include/pdfwindow/PWL_FontMap.h"
-#include "fpdfsdk/include/pdfwindow/PWL_ScrollBar.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Wnd.h"
-#include "public/fpdf_fwlevent.h"
-
-#define IsFloatZero(f) ((f) < 0.0001 && (f) > -0.0001)
-#define IsFloatBigger(fa, fb) ((fa) > (fb) && !IsFloatZero((fa) - (fb)))
-#define IsFloatSmaller(fa, fb) ((fa) < (fb) && !IsFloatZero((fa) - (fb)))
-#define IsFloatEqual(fa, fb) IsFloatZero((fa) - (fb))
-
-CPWL_EditCtrl::CPWL_EditCtrl()
-    : m_pEdit(NULL),
-      m_pEditCaret(NULL),
-      m_bMouseDown(FALSE),
-      m_pEditNotify(NULL),
-      m_nCharSet(DEFAULT_CHARSET),
-      m_nCodePage(0) {
-  m_pEdit = IFX_Edit::NewEdit();
-  ASSERT(m_pEdit);
-}
-
-CPWL_EditCtrl::~CPWL_EditCtrl() {
-  IFX_Edit::DelEdit(m_pEdit);
-}
-
-void CPWL_EditCtrl::OnCreate(PWL_CREATEPARAM& cp) {
-  cp.eCursorType = FXCT_VBEAM;
-}
-
-void CPWL_EditCtrl::OnCreated() {
-  SetFontSize(GetCreationParam().fFontSize);
-
-  m_pEdit->SetFontMap(GetFontMap());
-  m_pEdit->SetNotify(this);
-  m_pEdit->Initialize();
-}
-
-FX_BOOL CPWL_EditCtrl::IsWndHorV() {
-  CFX_Matrix mt = GetWindowMatrix();
-  CPDF_Point point1(0, 1);
-  CPDF_Point point2(1, 1);
-
-  mt.Transform(point1.x, point1.y);
-  mt.Transform(point2.x, point2.y);
-
-  return point2.y == point1.y;
-}
-
-void CPWL_EditCtrl::SetCursor() {
-  if (IsValid()) {
-    if (IFX_SystemHandler* pSH = GetSystemHandler()) {
-      if (IsWndHorV())
-        pSH->SetCursor(FXCT_VBEAM);
-      else
-        pSH->SetCursor(FXCT_HBEAM);
-    }
-  }
-}
-
-void CPWL_EditCtrl::RePosChildWnd() {
-  m_pEdit->SetPlateRect(GetClientRect());
-}
-
-void CPWL_EditCtrl::OnNotify(CPWL_Wnd* pWnd,
-                             FX_DWORD msg,
-                             intptr_t wParam,
-                             intptr_t lParam) {
-  CPWL_Wnd::OnNotify(pWnd, msg, wParam, lParam);
-
-  switch (msg) {
-    case PNM_SETSCROLLINFO:
-      switch (wParam) {
-        case SBT_VSCROLL:
-          if (CPWL_Wnd* pChild = GetVScrollBar()) {
-            pChild->OnNotify(pWnd, PNM_SETSCROLLINFO, wParam, lParam);
-          }
-          break;
-      }
-      break;
-    case PNM_SETSCROLLPOS:
-      switch (wParam) {
-        case SBT_VSCROLL:
-          if (CPWL_Wnd* pChild = GetVScrollBar()) {
-            pChild->OnNotify(pWnd, PNM_SETSCROLLPOS, wParam, lParam);
-          }
-          break;
-      }
-      break;
-    case PNM_SCROLLWINDOW: {
-      FX_FLOAT fPos = *(FX_FLOAT*)lParam;
-      switch (wParam) {
-        case SBT_VSCROLL:
-          m_pEdit->SetScrollPos(CPDF_Point(m_pEdit->GetScrollPos().x, fPos));
-          break;
-      }
-    } break;
-    case PNM_SETCARETINFO: {
-      if (PWL_CARET_INFO* pCaretInfo = (PWL_CARET_INFO*)wParam) {
-        SetCaret(pCaretInfo->bVisible, pCaretInfo->ptHead, pCaretInfo->ptFoot);
-      }
-    } break;
-  }
-}
-
-void CPWL_EditCtrl::CreateChildWnd(const PWL_CREATEPARAM& cp) {
-  if (!IsReadOnly())
-    CreateEditCaret(cp);
-}
-
-void CPWL_EditCtrl::CreateEditCaret(const PWL_CREATEPARAM& cp) {
-  if (!m_pEditCaret) {
-    m_pEditCaret = new CPWL_Caret;
-    m_pEditCaret->SetInvalidRect(GetClientRect());
-
-    PWL_CREATEPARAM ecp = cp;
-    ecp.pParentWnd = this;
-    ecp.dwFlags = PWS_CHILD | PWS_NOREFRESHCLIP;
-    ecp.dwBorderWidth = 0;
-    ecp.nBorderStyle = PBS_SOLID;
-    ecp.rcRectWnd = CPDF_Rect(0, 0, 0, 0);
-
-    m_pEditCaret->Create(ecp);
-  }
-}
-
-void CPWL_EditCtrl::SetFontSize(FX_FLOAT fFontSize) {
-  m_pEdit->SetFontSize(fFontSize);
-}
-
-FX_FLOAT CPWL_EditCtrl::GetFontSize() const {
-  return m_pEdit->GetFontSize();
-}
-
-FX_BOOL CPWL_EditCtrl::OnKeyDown(FX_WORD nChar, FX_DWORD nFlag) {
-  if (m_bMouseDown)
-    return TRUE;
-
-  FX_BOOL bRet = CPWL_Wnd::OnKeyDown(nChar, nFlag);
-
-  // FILTER
-  switch (nChar) {
-    default:
-      return FALSE;
-    case FWL_VKEY_Delete:
-    case FWL_VKEY_Up:
-    case FWL_VKEY_Down:
-    case FWL_VKEY_Left:
-    case FWL_VKEY_Right:
-    case FWL_VKEY_Home:
-    case FWL_VKEY_End:
-    case FWL_VKEY_Insert:
-    case 'C':
-    case 'V':
-    case 'X':
-    case 'A':
-    case 'Z':
-    case 'c':
-    case 'v':
-    case 'x':
-    case 'a':
-    case 'z':
-      break;
-  }
-
-  if (nChar == FWL_VKEY_Delete) {
-    if (m_pEdit->IsSelected())
-      nChar = FWL_VKEY_Unknown;
-  }
-
-  switch (nChar) {
-    case FWL_VKEY_Delete:
-      Delete();
-      return TRUE;
-    case FWL_VKEY_Insert:
-      if (IsSHIFTpressed(nFlag))
-        PasteText();
-      return TRUE;
-    case FWL_VKEY_Up:
-      m_pEdit->OnVK_UP(IsSHIFTpressed(nFlag), FALSE);
-      return TRUE;
-    case FWL_VKEY_Down:
-      m_pEdit->OnVK_DOWN(IsSHIFTpressed(nFlag), FALSE);
-      return TRUE;
-    case FWL_VKEY_Left:
-      m_pEdit->OnVK_LEFT(IsSHIFTpressed(nFlag), FALSE);
-      return TRUE;
-    case FWL_VKEY_Right:
-      m_pEdit->OnVK_RIGHT(IsSHIFTpressed(nFlag), FALSE);
-      return TRUE;
-    case FWL_VKEY_Home:
-      m_pEdit->OnVK_HOME(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
-      return TRUE;
-    case FWL_VKEY_End:
-      m_pEdit->OnVK_END(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
-      return TRUE;
-    case FWL_VKEY_Unknown:
-      if (!IsSHIFTpressed(nFlag))
-        Clear();
-      else
-        CutText();
-      return TRUE;
-    default:
-      break;
-  }
-
-  return bRet;
-}
-
-FX_BOOL CPWL_EditCtrl::OnChar(FX_WORD nChar, FX_DWORD nFlag) {
-  if (m_bMouseDown)
-    return TRUE;
-
-  CPWL_Wnd::OnChar(nChar, nFlag);
-
-  // FILTER
-  switch (nChar) {
-    case 0x0A:
-    case 0x1B:
-      return FALSE;
-    default:
-      break;
-  }
-
-  FX_BOOL bCtrl = IsCTRLpressed(nFlag);
-  FX_BOOL bAlt = IsALTpressed(nFlag);
-  FX_BOOL bShift = IsSHIFTpressed(nFlag);
-
-  FX_WORD word = nChar;
-
-  if (bCtrl && !bAlt) {
-    switch (nChar) {
-      case 'C' - 'A' + 1:
-        CopyText();
-        return TRUE;
-      case 'V' - 'A' + 1:
-        PasteText();
-        return TRUE;
-      case 'X' - 'A' + 1:
-        CutText();
-        return TRUE;
-      case 'A' - 'A' + 1:
-        SelectAll();
-        return TRUE;
-      case 'Z' - 'A' + 1:
-        if (bShift)
-          Redo();
-        else
-          Undo();
-        return TRUE;
-      default:
-        if (nChar < 32)
-          return FALSE;
-    }
-  }
-
-  if (IsReadOnly())
-    return TRUE;
-
-  if (m_pEdit->IsSelected() && word == FWL_VKEY_Back)
-    word = FWL_VKEY_Unknown;
-
-  Clear();
-
-  switch (word) {
-    case FWL_VKEY_Back:
-      Backspace();
-      break;
-    case FWL_VKEY_Return:
-      InsertReturn();
-      break;
-    case FWL_VKEY_Unknown:
-      break;
-    default:
-      if (IsINSERTpressed(nFlag))
-        Delete();
-      InsertWord(word, GetCharSet());
-      break;
-  }
-
-  return TRUE;
-}
-
-FX_BOOL CPWL_EditCtrl::OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) {
-  CPWL_Wnd::OnLButtonDown(point, nFlag);
-
-  if (ClientHitTest(point)) {
-    if (m_bMouseDown)
-      InvalidateRect();
-
-    m_bMouseDown = TRUE;
-    SetCapture();
-
-    m_pEdit->OnMouseDown(point, IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
-  }
-
-  return TRUE;
-}
-
-FX_BOOL CPWL_EditCtrl::OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag) {
-  CPWL_Wnd::OnLButtonUp(point, nFlag);
-
-  if (m_bMouseDown) {
-    // can receive keybord message
-    if (ClientHitTest(point) && !IsFocused())
-      SetFocus();
-
-    ReleaseCapture();
-    m_bMouseDown = FALSE;
-  }
-
-  return TRUE;
-}
-
-FX_BOOL CPWL_EditCtrl::OnMouseMove(const CPDF_Point& point, FX_DWORD nFlag) {
-  CPWL_Wnd::OnMouseMove(point, nFlag);
-
-  if (m_bMouseDown)
-    m_pEdit->OnMouseMove(point, FALSE, FALSE);
-
-  return TRUE;
-}
-
-CPDF_Rect CPWL_EditCtrl::GetContentRect() const {
-  return m_pEdit->GetContentRect();
-}
-
-void CPWL_EditCtrl::SetEditCaret(FX_BOOL bVisible) {
-  CPDF_Point ptHead(0, 0), ptFoot(0, 0);
-
-  if (bVisible) {
-    GetCaretInfo(ptHead, ptFoot);
-  }
-
-  CPVT_WordPlace wpTemp = m_pEdit->GetCaretWordPlace();
-  IOnSetCaret(bVisible, ptHead, ptFoot, wpTemp);
-}
-
-void CPWL_EditCtrl::GetCaretInfo(CPDF_Point& ptHead, CPDF_Point& ptFoot) const {
-  if (IFX_Edit_Iterator* pIterator = m_pEdit->GetIterator()) {
-    pIterator->SetAt(m_pEdit->GetCaret());
-    CPVT_Word word;
-    CPVT_Line line;
-    if (pIterator->GetWord(word)) {
-      ptHead.x = word.ptWord.x + word.fWidth;
-      ptHead.y = word.ptWord.y + word.fAscent;
-      ptFoot.x = word.ptWord.x + word.fWidth;
-      ptFoot.y = word.ptWord.y + word.fDescent;
-    } else if (pIterator->GetLine(line)) {
-      ptHead.x = line.ptLine.x;
-      ptHead.y = line.ptLine.y + line.fLineAscent;
-      ptFoot.x = line.ptLine.x;
-      ptFoot.y = line.ptLine.y + line.fLineDescent;
-    }
-  }
-}
-
-void CPWL_EditCtrl::GetCaretPos(int32_t& x, int32_t& y) const {
-  CPDF_Point ptHead(0, 0), ptFoot(0, 0);
-
-  GetCaretInfo(ptHead, ptFoot);
-
-  PWLtoWnd(ptHead, x, y);
-}
-
-void CPWL_EditCtrl::SetCaret(FX_BOOL bVisible,
-                             const CPDF_Point& ptHead,
-                             const CPDF_Point& ptFoot) {
-  if (m_pEditCaret) {
-    if (!IsFocused() || m_pEdit->IsSelected())
-      bVisible = FALSE;
-
-    m_pEditCaret->SetCaret(bVisible, ptHead, ptFoot);
-  }
-}
-
-CFX_WideString CPWL_EditCtrl::GetText() const {
-  return m_pEdit->GetText();
-}
-
-void CPWL_EditCtrl::SetSel(int32_t nStartChar, int32_t nEndChar) {
-  m_pEdit->SetSel(nStartChar, nEndChar);
-}
-
-void CPWL_EditCtrl::GetSel(int32_t& nStartChar, int32_t& nEndChar) const {
-  m_pEdit->GetSel(nStartChar, nEndChar);
-}
-
-void CPWL_EditCtrl::Clear() {
-  if (!IsReadOnly())
-    m_pEdit->Clear();
-}
-
-void CPWL_EditCtrl::SelectAll() {
-  m_pEdit->SelectAll();
-}
-
-void CPWL_EditCtrl::Paint() {
-  if (m_pEdit)
-    m_pEdit->Paint();
-}
-
-void CPWL_EditCtrl::EnableRefresh(FX_BOOL bRefresh) {
-  if (m_pEdit)
-    m_pEdit->EnableRefresh(bRefresh);
-}
-
-int32_t CPWL_EditCtrl::GetCaret() const {
-  if (m_pEdit)
-    return m_pEdit->GetCaret();
-
-  return -1;
-}
-
-void CPWL_EditCtrl::SetCaret(int32_t nPos) {
-  if (m_pEdit)
-    m_pEdit->SetCaret(nPos);
-}
-
-int32_t CPWL_EditCtrl::GetTotalWords() const {
-  if (m_pEdit)
-    return m_pEdit->GetTotalWords();
-
-  return 0;
-}
-
-void CPWL_EditCtrl::SetScrollPos(const CPDF_Point& point) {
-  if (m_pEdit)
-    m_pEdit->SetScrollPos(point);
-}
-
-CPDF_Point CPWL_EditCtrl::GetScrollPos() const {
-  if (m_pEdit)
-    return m_pEdit->GetScrollPos();
-
-  return CPDF_Point(0.0f, 0.0f);
-}
-
-CPDF_Font* CPWL_EditCtrl::GetCaretFont() const {
-  int32_t nFontIndex = 0;
-
-  if (IFX_Edit_Iterator* pIterator = m_pEdit->GetIterator()) {
-    pIterator->SetAt(m_pEdit->GetCaret());
-    CPVT_Word word;
-    CPVT_Section section;
-    if (pIterator->GetWord(word)) {
-      nFontIndex = word.nFontIndex;
-    } else if (HasFlag(PES_RICH)) {
-      if (pIterator->GetSection(section)) {
-        nFontIndex = section.WordProps.nFontIndex;
-      }
-    }
-  }
-
-  if (IFX_Edit_FontMap* pFontMap = GetFontMap())
-    return pFontMap->GetPDFFont(nFontIndex);
-
-  return NULL;
-}
-
-FX_FLOAT CPWL_EditCtrl::GetCaretFontSize() const {
-  FX_FLOAT fFontSize = GetFontSize();
-
-  if (IFX_Edit_Iterator* pIterator = m_pEdit->GetIterator()) {
-    pIterator->SetAt(m_pEdit->GetCaret());
-    CPVT_Word word;
-    CPVT_Section section;
-    if (pIterator->GetWord(word)) {
-      fFontSize = word.fFontSize;
-    } else if (HasFlag(PES_RICH)) {
-      if (pIterator->GetSection(section)) {
-        fFontSize = section.WordProps.fFontSize;
-      }
-    }
-  }
-
-  return fFontSize;
-}
-
-void CPWL_EditCtrl::SetText(const FX_WCHAR* csText) {
-  m_pEdit->SetText(csText);
-}
-
-void CPWL_EditCtrl::CopyText() {}
-
-void CPWL_EditCtrl::PasteText() {}
-
-void CPWL_EditCtrl::CutText() {}
-
-void CPWL_EditCtrl::ShowVScrollBar(FX_BOOL bShow) {}
-
-void CPWL_EditCtrl::InsertText(const FX_WCHAR* csText) {
-  if (!IsReadOnly())
-    m_pEdit->InsertText(csText);
-}
-
-void CPWL_EditCtrl::InsertWord(FX_WORD word, int32_t nCharset) {
-  if (!IsReadOnly())
-    m_pEdit->InsertWord(word, nCharset);
-}
-
-void CPWL_EditCtrl::InsertReturn() {
-  if (!IsReadOnly())
-    m_pEdit->InsertReturn();
-}
-
-void CPWL_EditCtrl::Delete() {
-  if (!IsReadOnly())
-    m_pEdit->Delete();
-}
-
-void CPWL_EditCtrl::Backspace() {
-  if (!IsReadOnly())
-    m_pEdit->Backspace();
-}
-
-FX_BOOL CPWL_EditCtrl::CanUndo() const {
-  return !IsReadOnly() && m_pEdit->CanUndo();
-}
-
-FX_BOOL CPWL_EditCtrl::CanRedo() const {
-  return !IsReadOnly() && m_pEdit->CanRedo();
-}
-
-void CPWL_EditCtrl::Redo() {
-  if (CanRedo())
-    m_pEdit->Redo();
-}
-
-void CPWL_EditCtrl::Undo() {
-  if (CanUndo())
-    m_pEdit->Undo();
-}
-
-void CPWL_EditCtrl::IOnSetScrollInfoY(FX_FLOAT fPlateMin,
-                                      FX_FLOAT fPlateMax,
-                                      FX_FLOAT fContentMin,
-                                      FX_FLOAT fContentMax,
-                                      FX_FLOAT fSmallStep,
-                                      FX_FLOAT fBigStep) {
-  PWL_SCROLL_INFO Info;
-
-  Info.fPlateWidth = fPlateMax - fPlateMin;
-  Info.fContentMin = fContentMin;
-  Info.fContentMax = fContentMax;
-  Info.fSmallStep = fSmallStep;
-  Info.fBigStep = fBigStep;
-
-  OnNotify(this, PNM_SETSCROLLINFO, SBT_VSCROLL, (intptr_t)&Info);
-
-  if (IsFloatBigger(Info.fPlateWidth, Info.fContentMax - Info.fContentMin) ||
-      IsFloatEqual(Info.fPlateWidth, Info.fContentMax - Info.fContentMin)) {
-    ShowVScrollBar(FALSE);
-  } else {
-    ShowVScrollBar(TRUE);
-  }
-}
-
-void CPWL_EditCtrl::IOnSetScrollPosY(FX_FLOAT fy) {
-  OnNotify(this, PNM_SETSCROLLPOS, SBT_VSCROLL, (intptr_t)&fy);
-}
-
-void CPWL_EditCtrl::IOnSetCaret(FX_BOOL bVisible,
-                                const CPDF_Point& ptHead,
-                                const CPDF_Point& ptFoot,
-                                const CPVT_WordPlace& place) {
-  PWL_CARET_INFO cInfo;
-  cInfo.bVisible = bVisible;
-  cInfo.ptHead = ptHead;
-  cInfo.ptFoot = ptFoot;
-
-  OnNotify(this, PNM_SETCARETINFO, (intptr_t)&cInfo, (intptr_t)NULL);
-}
-
-void CPWL_EditCtrl::IOnCaretChange(const CPVT_SecProps& secProps,
-                                   const CPVT_WordProps& wordProps) {}
-
-void CPWL_EditCtrl::IOnContentChange(const CPDF_Rect& rcContent) {
-  if (IsValid()) {
-    if (m_pEditNotify) {
-      m_pEditNotify->OnContentChange(rcContent);
-    }
-  }
-}
-
-void CPWL_EditCtrl::IOnInvalidateRect(CPDF_Rect* pRect) {
-  InvalidateRect(pRect);
-}
-
-int32_t CPWL_EditCtrl::GetCharSet() const {
-  return m_nCharSet < 0 ? DEFAULT_CHARSET : m_nCharSet;
-}
-
-void CPWL_EditCtrl::GetTextRange(const CPDF_Rect& rect,
-                                 int32_t& nStartChar,
-                                 int32_t& nEndChar) const {
-  nStartChar = m_pEdit->WordPlaceToWordIndex(
-      m_pEdit->SearchWordPlace(CPDF_Point(rect.left, rect.top)));
-  nEndChar = m_pEdit->WordPlaceToWordIndex(
-      m_pEdit->SearchWordPlace(CPDF_Point(rect.right, rect.bottom)));
-}
-
-CFX_WideString CPWL_EditCtrl::GetText(int32_t& nStartChar,
-                                      int32_t& nEndChar) const {
-  CPVT_WordPlace wpStart = m_pEdit->WordIndexToWordPlace(nStartChar);
-  CPVT_WordPlace wpEnd = m_pEdit->WordIndexToWordPlace(nEndChar);
-  return m_pEdit->GetRangeText(CPVT_WordRange(wpStart, wpEnd));
-}
-
-void CPWL_EditCtrl::SetReadyToInput() {
-  if (m_bMouseDown) {
-    ReleaseCapture();
-    m_bMouseDown = FALSE;
-  }
-}
diff --git a/fpdfsdk/src/pdfwindow/PWL_FontMap.cpp b/fpdfsdk/src/pdfwindow/PWL_FontMap.cpp
deleted file mode 100644
index 89a75b2..0000000
--- a/fpdfsdk/src/pdfwindow/PWL_FontMap.cpp
+++ /dev/null
@@ -1,498 +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
-
-#include "fpdfsdk/include/pdfwindow/PWL_FontMap.h"
-
-#include "core/include/fpdfapi/fpdf_module.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Wnd.h"
-
-namespace {
-
-const char kDefaultFontName[] = "Helvetica";
-
-const char* const g_sDEStandardFontName[] = {"Courier",
-                                             "Courier-Bold",
-                                             "Courier-BoldOblique",
-                                             "Courier-Oblique",
-                                             "Helvetica",
-                                             "Helvetica-Bold",
-                                             "Helvetica-BoldOblique",
-                                             "Helvetica-Oblique",
-                                             "Times-Roman",
-                                             "Times-Bold",
-                                             "Times-Italic",
-                                             "Times-BoldItalic",
-                                             "Symbol",
-                                             "ZapfDingbats"};
-
-}  // namespace
-
-CPWL_FontMap::CPWL_FontMap(IFX_SystemHandler* pSystemHandler)
-    : m_pPDFDoc(NULL), m_pSystemHandler(pSystemHandler) {
-  ASSERT(m_pSystemHandler);
-}
-
-CPWL_FontMap::~CPWL_FontMap() {
-  delete m_pPDFDoc;
-  m_pPDFDoc = NULL;
-
-  Empty();
-}
-
-void CPWL_FontMap::SetSystemHandler(IFX_SystemHandler* pSystemHandler) {
-  m_pSystemHandler = pSystemHandler;
-}
-
-CPDF_Document* CPWL_FontMap::GetDocument() {
-  if (!m_pPDFDoc) {
-    if (CPDF_ModuleMgr::Get()) {
-      m_pPDFDoc = new CPDF_Document;
-      m_pPDFDoc->CreateNewDoc();
-    }
-  }
-
-  return m_pPDFDoc;
-}
-
-CPDF_Font* CPWL_FontMap::GetPDFFont(int32_t nFontIndex) {
-  if (nFontIndex >= 0 && nFontIndex < m_aData.GetSize()) {
-    if (CPWL_FontMap_Data* pData = m_aData.GetAt(nFontIndex)) {
-      return pData->pFont;
-    }
-  }
-
-  return NULL;
-}
-
-CFX_ByteString CPWL_FontMap::GetPDFFontAlias(int32_t nFontIndex) {
-  if (nFontIndex >= 0 && nFontIndex < m_aData.GetSize()) {
-    if (CPWL_FontMap_Data* pData = m_aData.GetAt(nFontIndex)) {
-      return pData->sFontName;
-    }
-  }
-
-  return "";
-}
-
-FX_BOOL CPWL_FontMap::KnowWord(int32_t nFontIndex, FX_WORD word) {
-  if (nFontIndex >= 0 && nFontIndex < m_aData.GetSize()) {
-    if (m_aData.GetAt(nFontIndex)) {
-      return CharCodeFromUnicode(nFontIndex, word) >= 0;
-    }
-  }
-
-  return FALSE;
-}
-
-int32_t CPWL_FontMap::GetWordFontIndex(FX_WORD word,
-                                       int32_t nCharset,
-                                       int32_t nFontIndex) {
-  if (nFontIndex > 0) {
-    if (KnowWord(nFontIndex, word))
-      return nFontIndex;
-  } else {
-    if (const CPWL_FontMap_Data* pData = GetFontMapData(0)) {
-      if (nCharset == DEFAULT_CHARSET || pData->nCharset == SYMBOL_CHARSET ||
-          nCharset == pData->nCharset) {
-        if (KnowWord(0, word))
-          return 0;
-      }
-    }
-  }
-
-  int32_t nNewFontIndex =
-      GetFontIndex(GetNativeFontName(nCharset), nCharset, TRUE);
-  if (nNewFontIndex >= 0) {
-    if (KnowWord(nNewFontIndex, word))
-      return nNewFontIndex;
-  }
-  nNewFontIndex = GetFontIndex("Arial Unicode MS", DEFAULT_CHARSET, FALSE);
-  if (nNewFontIndex >= 0) {
-    if (KnowWord(nNewFontIndex, word))
-      return nNewFontIndex;
-  }
-  return -1;
-}
-
-int32_t CPWL_FontMap::CharCodeFromUnicode(int32_t nFontIndex, FX_WORD word) {
-  if (CPWL_FontMap_Data* pData = m_aData.GetAt(nFontIndex)) {
-    if (pData->pFont) {
-      if (pData->pFont->IsUnicodeCompatible()) {
-        int nCharCode = pData->pFont->CharCodeFromUnicode(word);
-        pData->pFont->GlyphFromCharCode(nCharCode);
-        return nCharCode;
-      }
-      if (word < 0xFF)
-        return word;
-    }
-  }
-  return -1;
-}
-
-CFX_ByteString CPWL_FontMap::GetNativeFontName(int32_t nCharset) {
-  // searching native font is slow, so we must save time
-  for (int32_t i = 0, sz = m_aNativeFont.GetSize(); i < sz; i++) {
-    if (CPWL_FontMap_Native* pData = m_aNativeFont.GetAt(i)) {
-      if (pData->nCharset == nCharset)
-        return pData->sFontName;
-    }
-  }
-
-  CFX_ByteString sNew = GetNativeFont(nCharset);
-
-  if (!sNew.IsEmpty()) {
-    CPWL_FontMap_Native* pNewData = new CPWL_FontMap_Native;
-    pNewData->nCharset = nCharset;
-    pNewData->sFontName = sNew;
-
-    m_aNativeFont.Add(pNewData);
-  }
-
-  return sNew;
-}
-
-void CPWL_FontMap::Empty() {
-  {
-    for (int32_t i = 0, sz = m_aData.GetSize(); i < sz; i++)
-      delete m_aData.GetAt(i);
-
-    m_aData.RemoveAll();
-  }
-  {
-    for (int32_t i = 0, sz = m_aNativeFont.GetSize(); i < sz; i++)
-      delete m_aNativeFont.GetAt(i);
-
-    m_aNativeFont.RemoveAll();
-  }
-}
-
-void CPWL_FontMap::Initialize() {
-  GetFontIndex(kDefaultFontName, ANSI_CHARSET, FALSE);
-}
-
-FX_BOOL CPWL_FontMap::IsStandardFont(const CFX_ByteString& sFontName) {
-  for (int32_t i = 0; i < FX_ArraySize(g_sDEStandardFontName); ++i) {
-    if (sFontName == g_sDEStandardFontName[i])
-      return TRUE;
-  }
-
-  return FALSE;
-}
-
-int32_t CPWL_FontMap::FindFont(const CFX_ByteString& sFontName,
-                               int32_t nCharset) {
-  for (int32_t i = 0, sz = m_aData.GetSize(); i < sz; i++) {
-    if (CPWL_FontMap_Data* pData = m_aData.GetAt(i)) {
-      if (nCharset == DEFAULT_CHARSET || nCharset == pData->nCharset) {
-        if (sFontName.IsEmpty() || pData->sFontName == sFontName)
-          return i;
-      }
-    }
-  }
-
-  return -1;
-}
-
-int32_t CPWL_FontMap::GetFontIndex(const CFX_ByteString& sFontName,
-                                   int32_t nCharset,
-                                   FX_BOOL bFind) {
-  int32_t nFontIndex = FindFont(EncodeFontAlias(sFontName, nCharset), nCharset);
-  if (nFontIndex >= 0)
-    return nFontIndex;
-
-  CFX_ByteString sAlias;
-  CPDF_Font* pFont = NULL;
-  if (bFind)
-    pFont = FindFontSameCharset(sAlias, nCharset);
-
-  if (!pFont) {
-    CFX_ByteString sTemp = sFontName;
-    pFont = AddFontToDocument(GetDocument(), sTemp, nCharset);
-    sAlias = EncodeFontAlias(sTemp, nCharset);
-  }
-  AddedFont(pFont, sAlias);
-  return AddFontData(pFont, sAlias, nCharset);
-}
-
-int32_t CPWL_FontMap::GetPWLFontIndex(FX_WORD word, int32_t nCharset) {
-  int32_t nFind = -1;
-
-  for (int32_t i = 0, sz = m_aData.GetSize(); i < sz; i++) {
-    if (CPWL_FontMap_Data* pData = m_aData.GetAt(i)) {
-      if (pData->nCharset == nCharset) {
-        nFind = i;
-        break;
-      }
-    }
-  }
-
-  CPDF_Font* pNewFont = GetPDFFont(nFind);
-
-  if (!pNewFont)
-    return -1;
-
-  CFX_ByteString sAlias = EncodeFontAlias("Arial_Chrome", nCharset);
-  AddedFont(pNewFont, sAlias);
-
-  return AddFontData(pNewFont, sAlias, nCharset);
-}
-
-CPDF_Font* CPWL_FontMap::FindFontSameCharset(CFX_ByteString& sFontAlias,
-                                             int32_t nCharset) {
-  return NULL;
-}
-
-int32_t CPWL_FontMap::AddFontData(CPDF_Font* pFont,
-                                  const CFX_ByteString& sFontAlias,
-                                  int32_t nCharset) {
-  CPWL_FontMap_Data* pNewData = new CPWL_FontMap_Data;
-  pNewData->pFont = pFont;
-  pNewData->sFontName = sFontAlias;
-  pNewData->nCharset = nCharset;
-
-  m_aData.Add(pNewData);
-
-  return m_aData.GetSize() - 1;
-}
-
-void CPWL_FontMap::AddedFont(CPDF_Font* pFont,
-                             const CFX_ByteString& sFontAlias) {}
-
-CFX_ByteString CPWL_FontMap::GetFontName(int32_t nFontIndex) {
-  if (nFontIndex >= 0 && nFontIndex < m_aData.GetSize()) {
-    if (CPWL_FontMap_Data* pData = m_aData.GetAt(nFontIndex)) {
-      return pData->sFontName;
-    }
-  }
-
-  return "";
-}
-
-CFX_ByteString CPWL_FontMap::GetNativeFont(int32_t nCharset) {
-  if (nCharset == DEFAULT_CHARSET)
-    nCharset = GetNativeCharset();
-
-  CFX_ByteString sFontName = GetDefaultFontByCharset(nCharset);
-  if (m_pSystemHandler) {
-    if (m_pSystemHandler->FindNativeTrueTypeFont(nCharset, sFontName))
-      return sFontName;
-
-    sFontName = m_pSystemHandler->GetNativeTrueTypeFont(nCharset);
-  }
-  return sFontName;
-}
-
-CPDF_Font* CPWL_FontMap::AddFontToDocument(CPDF_Document* pDoc,
-                                           CFX_ByteString& sFontName,
-                                           uint8_t nCharset) {
-  if (IsStandardFont(sFontName))
-    return AddStandardFont(pDoc, sFontName);
-
-  return AddSystemFont(pDoc, sFontName, nCharset);
-}
-
-CPDF_Font* CPWL_FontMap::AddStandardFont(CPDF_Document* pDoc,
-                                         CFX_ByteString& sFontName) {
-  if (!pDoc)
-    return NULL;
-
-  CPDF_Font* pFont = NULL;
-
-  if (sFontName == "ZapfDingbats") {
-    pFont = pDoc->AddStandardFont(sFontName, NULL);
-  } else {
-    CPDF_FontEncoding fe(PDFFONT_ENCODING_WINANSI);
-    pFont = pDoc->AddStandardFont(sFontName, &fe);
-  }
-
-  return pFont;
-}
-
-CPDF_Font* CPWL_FontMap::AddSystemFont(CPDF_Document* pDoc,
-                                       CFX_ByteString& sFontName,
-                                       uint8_t nCharset) {
-  if (!pDoc)
-    return NULL;
-
-  if (sFontName.IsEmpty())
-    sFontName = GetNativeFont(nCharset);
-  if (nCharset == DEFAULT_CHARSET)
-    nCharset = GetNativeCharset();
-
-  if (m_pSystemHandler)
-    return m_pSystemHandler->AddNativeTrueTypeFontToPDF(pDoc, sFontName,
-                                                        nCharset);
-
-  return NULL;
-}
-
-CFX_ByteString CPWL_FontMap::EncodeFontAlias(const CFX_ByteString& sFontName,
-                                             int32_t nCharset) {
-  CFX_ByteString sPostfix;
-  sPostfix.Format("_%02X", nCharset);
-  return EncodeFontAlias(sFontName) + sPostfix;
-}
-
-CFX_ByteString CPWL_FontMap::EncodeFontAlias(const CFX_ByteString& sFontName) {
-  CFX_ByteString sRet = sFontName;
-  sRet.Remove(' ');
-  return sRet;
-}
-
-int32_t CPWL_FontMap::GetFontMapCount() const {
-  return m_aData.GetSize();
-}
-
-const CPWL_FontMap_Data* CPWL_FontMap::GetFontMapData(int32_t nIndex) const {
-  if (nIndex >= 0 && nIndex < m_aData.GetSize()) {
-    return m_aData.GetAt(nIndex);
-  }
-
-  return NULL;
-}
-
-int32_t CPWL_FontMap::GetNativeCharset() {
-  uint8_t nCharset = ANSI_CHARSET;
-  int32_t iCodePage = FXSYS_GetACP();
-  switch (iCodePage) {
-    case 932:  // Japan
-      nCharset = SHIFTJIS_CHARSET;
-      break;
-    case 936:  // Chinese (PRC, Singapore)
-      nCharset = GB2312_CHARSET;
-      break;
-    case 950:  // Chinese (Taiwan; Hong Kong SAR, PRC)
-      nCharset = GB2312_CHARSET;
-      break;
-    case 1252:  // Windows 3.1 Latin 1 (US, Western Europe)
-      nCharset = ANSI_CHARSET;
-      break;
-    case 874:  // Thai
-      nCharset = THAI_CHARSET;
-      break;
-    case 949:  // Korean
-      nCharset = HANGUL_CHARSET;
-      break;
-    case 1200:  // Unicode (BMP of ISO 10646)
-      nCharset = ANSI_CHARSET;
-      break;
-    case 1250:  // Windows 3.1 Eastern European
-      nCharset = EASTEUROPE_CHARSET;
-      break;
-    case 1251:  // Windows 3.1 Cyrillic
-      nCharset = RUSSIAN_CHARSET;
-      break;
-    case 1253:  // Windows 3.1 Greek
-      nCharset = GREEK_CHARSET;
-      break;
-    case 1254:  // Windows 3.1 Turkish
-      nCharset = TURKISH_CHARSET;
-      break;
-    case 1255:  // Hebrew
-      nCharset = HEBREW_CHARSET;
-      break;
-    case 1256:  // Arabic
-      nCharset = ARABIC_CHARSET;
-      break;
-    case 1257:  // Baltic
-      nCharset = BALTIC_CHARSET;
-      break;
-    case 1258:  // Vietnamese
-      nCharset = VIETNAMESE_CHARSET;
-      break;
-    case 1361:  // Korean(Johab)
-      nCharset = JOHAB_CHARSET;
-      break;
-  }
-  return nCharset;
-}
-
-const CPWL_FontMap::CharsetFontMap CPWL_FontMap::defaultTTFMap[] = {
-    {ANSI_CHARSET, "Helvetica"},      {GB2312_CHARSET, "SimSun"},
-    {CHINESEBIG5_CHARSET, "MingLiU"}, {SHIFTJIS_CHARSET, "MS Gothic"},
-    {HANGUL_CHARSET, "Batang"},       {RUSSIAN_CHARSET, "Arial"},
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ || \
-    _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
-    {EASTEUROPE_CHARSET, "Arial"},
-#else
-    {EASTEUROPE_CHARSET, "Tahoma"},
-#endif
-    {ARABIC_CHARSET, "Arial"},        {-1, NULL}};
-
-CFX_ByteString CPWL_FontMap::GetDefaultFontByCharset(int32_t nCharset) {
-  int i = 0;
-  while (defaultTTFMap[i].charset != -1) {
-    if (nCharset == defaultTTFMap[i].charset)
-      return defaultTTFMap[i].fontname;
-    ++i;
-  }
-  return "";
-}
-
-int32_t CPWL_FontMap::CharSetFromUnicode(FX_WORD word, int32_t nOldCharset) {
-  if (m_pSystemHandler && (-1 != m_pSystemHandler->GetCharSet()))
-    return m_pSystemHandler->GetCharSet();
-  // to avoid CJK Font to show ASCII
-  if (word < 0x7F)
-    return ANSI_CHARSET;
-  // follow the old charset
-  if (nOldCharset != DEFAULT_CHARSET)
-    return nOldCharset;
-
-  // find new charset
-  if ((word >= 0x4E00 && word <= 0x9FA5) ||
-      (word >= 0xE7C7 && word <= 0xE7F3) ||
-      (word >= 0x3000 && word <= 0x303F) ||
-      (word >= 0x2000 && word <= 0x206F)) {
-    return GB2312_CHARSET;
-  }
-
-  if (((word >= 0x3040) && (word <= 0x309F)) ||
-      ((word >= 0x30A0) && (word <= 0x30FF)) ||
-      ((word >= 0x31F0) && (word <= 0x31FF)) ||
-      ((word >= 0xFF00) && (word <= 0xFFEF))) {
-    return SHIFTJIS_CHARSET;
-  }
-
-  if (((word >= 0xAC00) && (word <= 0xD7AF)) ||
-      ((word >= 0x1100) && (word <= 0x11FF)) ||
-      ((word >= 0x3130) && (word <= 0x318F))) {
-    return HANGUL_CHARSET;
-  }
-
-  if (word >= 0x0E00 && word <= 0x0E7F)
-    return THAI_CHARSET;
-
-  if ((word >= 0x0370 && word <= 0x03FF) || (word >= 0x1F00 && word <= 0x1FFF))
-    return GREEK_CHARSET;
-
-  if ((word >= 0x0600 && word <= 0x06FF) || (word >= 0xFB50 && word <= 0xFEFC))
-    return ARABIC_CHARSET;
-
-  if (word >= 0x0590 && word <= 0x05FF)
-    return HEBREW_CHARSET;
-
-  if (word >= 0x0400 && word <= 0x04FF)
-    return RUSSIAN_CHARSET;
-
-  if (word >= 0x0100 && word <= 0x024F)
-    return EASTEUROPE_CHARSET;
-
-  if (word >= 0x1E00 && word <= 0x1EFF)
-    return VIETNAMESE_CHARSET;
-
-  return ANSI_CHARSET;
-}
-
-CPWL_DocFontMap::CPWL_DocFontMap(IFX_SystemHandler* pSystemHandler,
-                                 CPDF_Document* pAttachedDoc)
-    : CPWL_FontMap(pSystemHandler), m_pAttachedDoc(pAttachedDoc) {}
-
-CPWL_DocFontMap::~CPWL_DocFontMap() {}
-
-CPDF_Document* CPWL_DocFontMap::GetDocument() {
-  return m_pAttachedDoc;
-}
diff --git a/fpdfsdk/src/pdfwindow/PWL_IconList.cpp b/fpdfsdk/src/pdfwindow/PWL_IconList.cpp
deleted file mode 100644
index c6849d0..0000000
--- a/fpdfsdk/src/pdfwindow/PWL_IconList.cpp
+++ /dev/null
@@ -1,500 +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
-
-#include "fpdfsdk/include/pdfwindow/PWL_IconList.h"
-
-#include "fpdfsdk/include/pdfwindow/PWL_Label.h"
-#include "fpdfsdk/include/pdfwindow/PWL_ListCtrl.h"
-#include "fpdfsdk/include/pdfwindow/PWL_ScrollBar.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Wnd.h"
-#include "public/fpdf_fwlevent.h"
-
-#define PWL_IconList_ITEM_ICON_LEFTMARGIN 10.0f
-#define PWL_IconList_ITEM_WIDTH 20.0f
-#define PWL_IconList_ITEM_HEIGHT 20.0f
-#define PWL_IconList_ITEM_SPACE 4.0f
-
-CPWL_IconList_Item::CPWL_IconList_Item()
-    : m_nIconIndex(-1), m_pData(NULL), m_bSelected(FALSE), m_pText(NULL) {}
-
-CPWL_IconList_Item::~CPWL_IconList_Item() {}
-
-CFX_ByteString CPWL_IconList_Item::GetClassName() const {
-  return "CPWL_IconList_Item";
-}
-
-FX_FLOAT CPWL_IconList_Item::GetItemHeight(FX_FLOAT fLimitWidth) {
-  return PWL_IconList_ITEM_HEIGHT;
-}
-
-void CPWL_IconList_Item::DrawThisAppearance(CFX_RenderDevice* pDevice,
-                                            CFX_Matrix* pUser2Device) {
-  CPDF_Rect rcClient = GetClientRect();
-
-  if (m_bSelected) {
-    if (IsEnabled()) {
-      CPWL_Utils::DrawFillRect(
-          pDevice, pUser2Device, rcClient,
-          CPWL_Utils::PWLColorToFXColor(PWL_DEFAULT_SELBACKCOLOR,
-                                        GetTransparency()));
-    } else {
-      CPWL_Utils::DrawFillRect(
-          pDevice, pUser2Device, rcClient,
-          CPWL_Utils::PWLColorToFXColor(PWL_DEFAULT_LIGHTGRAYCOLOR,
-                                        GetTransparency()));
-    }
-  }
-
-  CPDF_Rect rcIcon = rcClient;
-  rcIcon.left += PWL_IconList_ITEM_ICON_LEFTMARGIN;
-  rcIcon.right = rcIcon.left + PWL_IconList_ITEM_WIDTH;
-
-  CPWL_Utils::DrawIconAppStream(pDevice, pUser2Device, m_nIconIndex, rcIcon,
-                                m_crIcon, m_pText->GetTextColor(),
-                                GetTransparency());
-}
-
-void CPWL_IconList_Item::SetSelect(FX_BOOL bSelected) {
-  m_bSelected = bSelected;
-
-  if (bSelected)
-    m_pText->SetTextColor(PWL_DEFAULT_WHITECOLOR);
-  else
-    m_pText->SetTextColor(PWL_DEFAULT_BLACKCOLOR);
-}
-
-FX_BOOL CPWL_IconList_Item::IsSelected() const {
-  return m_bSelected;
-}
-
-void CPWL_IconList_Item::CreateChildWnd(const PWL_CREATEPARAM& cp) {
-  m_pText = new CPWL_Label;
-
-  PWL_CREATEPARAM lcp = cp;
-  lcp.pParentWnd = this;
-  lcp.dwFlags = PWS_CHILD | PWS_VISIBLE | PES_LEFT | PES_CENTER;
-  lcp.sTextColor = PWL_DEFAULT_BLACKCOLOR;
-  lcp.fFontSize = 12;
-  m_pText->Create(lcp);
-}
-
-void CPWL_IconList_Item::SetData(void* pData) {
-  m_pData = pData;
-}
-
-void CPWL_IconList_Item::SetIcon(int32_t nIconIndex) {
-  m_nIconIndex = nIconIndex;
-}
-
-void CPWL_IconList_Item::SetText(const CFX_WideString& str) {
-  m_pText->SetText(str.c_str());
-}
-
-CFX_WideString CPWL_IconList_Item::GetText() const {
-  return m_pText->GetText();
-}
-
-void CPWL_IconList_Item::RePosChildWnd() {
-  CPDF_Rect rcClient = GetClientRect();
-
-  rcClient.left +=
-      (PWL_IconList_ITEM_ICON_LEFTMARGIN + PWL_IconList_ITEM_WIDTH +
-       PWL_IconList_ITEM_ICON_LEFTMARGIN);
-
-  m_pText->Move(rcClient, TRUE, FALSE);
-}
-
-void CPWL_IconList_Item::SetIconFillColor(const CPWL_Color& color) {
-  m_crIcon = color;
-}
-
-void CPWL_IconList_Item::OnEnabled() {
-  if (m_bSelected)
-    m_pText->SetTextColor(PWL_DEFAULT_WHITECOLOR);
-  else
-    m_pText->SetTextColor(PWL_DEFAULT_BLACKCOLOR);
-
-  InvalidateRect();
-}
-
-void CPWL_IconList_Item::OnDisabled() {
-  m_pText->SetTextColor(PWL_DEFAULT_HEAVYGRAYCOLOR);
-
-  InvalidateRect();
-}
-
-CPWL_IconList_Content::CPWL_IconList_Content(int32_t nListCount)
-    : m_nSelectIndex(-1),
-      m_pNotify(NULL),
-      m_bEnableNotify(TRUE),
-      m_bMouseDown(FALSE),
-      m_nListCount(nListCount) {}
-
-CPWL_IconList_Content::~CPWL_IconList_Content() {}
-
-void CPWL_IconList_Content::CreateChildWnd(const PWL_CREATEPARAM& cp) {
-  for (int32_t i = 0; i < m_nListCount; i++) {
-    CPWL_IconList_Item* pNewItem = new CPWL_IconList_Item();
-
-    PWL_CREATEPARAM icp = cp;
-    icp.pParentWnd = this;
-    icp.dwFlags = PWS_CHILD | PWS_VISIBLE | PWS_NOREFRESHCLIP;
-    pNewItem->Create(icp);
-  }
-
-  SetItemSpace(PWL_IconList_ITEM_SPACE);
-  ResetContent(0);
-
-  if (CPWL_Wnd* pParent = GetParentWindow()) {
-    CPDF_Rect rcScroll = GetScrollArea();
-    GetScrollPos();
-
-    PWL_SCROLL_INFO sInfo;
-    sInfo.fContentMin = rcScroll.bottom;
-    sInfo.fContentMax = rcScroll.top;
-    sInfo.fPlateWidth = GetClientRect().Height();
-    sInfo.fSmallStep = 13.0f;
-    sInfo.fBigStep = sInfo.fPlateWidth;
-
-    pParent->OnNotify(this, PNM_SETSCROLLINFO, SBT_VSCROLL, (intptr_t)&sInfo);
-  }
-}
-
-FX_BOOL CPWL_IconList_Content::OnLButtonDown(const CPDF_Point& point,
-                                             FX_DWORD nFlag) {
-  SetFocus();
-
-  SetCapture();
-  m_bMouseDown = TRUE;
-
-  int32_t nItemIndex = FindItemIndex(point);
-  SetSelect(nItemIndex);
-  ScrollToItem(nItemIndex);
-
-  return TRUE;
-}
-
-FX_BOOL CPWL_IconList_Content::OnLButtonUp(const CPDF_Point& point,
-                                           FX_DWORD nFlag) {
-  m_bMouseDown = FALSE;
-  ReleaseCapture();
-
-  return TRUE;
-}
-
-FX_BOOL CPWL_IconList_Content::OnMouseMove(const CPDF_Point& point,
-                                           FX_DWORD nFlag) {
-  if (m_bMouseDown) {
-    int32_t nItemIndex = FindItemIndex(point);
-    SetSelect(nItemIndex);
-    ScrollToItem(nItemIndex);
-  }
-
-  return TRUE;
-}
-
-FX_BOOL CPWL_IconList_Content::OnKeyDown(FX_WORD nChar, FX_DWORD nFlag) {
-  switch (nChar) {
-    case FWL_VKEY_Up:
-      if (m_nSelectIndex > 0) {
-        int32_t nItemIndex = m_nSelectIndex - 1;
-        SetSelect(nItemIndex);
-        ScrollToItem(nItemIndex);
-      }
-      return TRUE;
-    case FWL_VKEY_Down:
-      if (m_nSelectIndex < m_nListCount - 1) {
-        int32_t nItemIndex = m_nSelectIndex + 1;
-        SetSelect(nItemIndex);
-        ScrollToItem(nItemIndex);
-      }
-      return TRUE;
-  }
-
-  return FALSE;
-}
-
-int32_t CPWL_IconList_Content::FindItemIndex(const CPDF_Point& point) {
-  int32_t nIndex = 0;
-  for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
-    if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
-      CPDF_Rect rcWnd = pChild->ChildToParent(pChild->GetWindowRect());
-
-      if (point.y < rcWnd.top) {
-        nIndex = i;
-      }
-    }
-  }
-
-  return nIndex;
-}
-
-void CPWL_IconList_Content::ScrollToItem(int32_t nItemIndex) {
-  CPDF_Rect rcClient = GetClientRect();
-
-  if (CPWL_IconList_Item* pItem = GetListItem(nItemIndex)) {
-    CPDF_Rect rcOrigin = pItem->GetWindowRect();
-    CPDF_Rect rcWnd = pItem->ChildToParent(rcOrigin);
-
-    if (!(rcWnd.bottom > rcClient.bottom && rcWnd.top < rcClient.top)) {
-      CPDF_Point ptScroll = GetScrollPos();
-
-      if (rcWnd.top > rcClient.top) {
-        ptScroll.y = rcOrigin.top;
-      } else if (rcWnd.bottom < rcClient.bottom) {
-        ptScroll.y = rcOrigin.bottom + rcClient.Height();
-      }
-
-      SetScrollPos(ptScroll);
-      ResetFace();
-      InvalidateRect();
-      if (CPWL_Wnd* pParent = GetParentWindow()) {
-        pParent->OnNotify(this, PNM_SETSCROLLPOS, SBT_VSCROLL,
-                          (intptr_t)&ptScroll.y);
-      }
-    }
-  }
-}
-
-void CPWL_IconList_Content::SetSelect(int32_t nIndex) {
-  if (m_nSelectIndex != nIndex) {
-    SelectItem(m_nSelectIndex, FALSE);
-    SelectItem(nIndex, TRUE);
-    m_nSelectIndex = nIndex;
-
-    if (IPWL_IconList_Notify* pNotify = GetNotify())
-      pNotify->OnNoteListSelChanged(nIndex);
-  }
-}
-
-int32_t CPWL_IconList_Content::GetSelect() const {
-  return m_nSelectIndex;
-}
-
-IPWL_IconList_Notify* CPWL_IconList_Content::GetNotify() const {
-  if (m_bEnableNotify)
-    return m_pNotify;
-  return NULL;
-}
-
-void CPWL_IconList_Content::SetNotify(IPWL_IconList_Notify* pNotify) {
-  m_pNotify = pNotify;
-}
-
-void CPWL_IconList_Content::EnableNotify(FX_BOOL bNotify) {
-  m_bEnableNotify = bNotify;
-}
-
-void CPWL_IconList_Content::SelectItem(int32_t nItemIndex, FX_BOOL bSelect) {
-  if (CPWL_IconList_Item* pItem = GetListItem(nItemIndex)) {
-    pItem->SetSelect(bSelect);
-    pItem->InvalidateRect();
-  }
-}
-
-CPWL_IconList_Item* CPWL_IconList_Content::GetListItem(
-    int32_t nItemIndex) const {
-  if (nItemIndex >= 0 && nItemIndex < m_aChildren.GetSize()) {
-    if (CPWL_Wnd* pChild = m_aChildren.GetAt(nItemIndex)) {
-      if (pChild->GetClassName() == "CPWL_IconList_Item") {
-        return (CPWL_IconList_Item*)pChild;
-      }
-    }
-  }
-
-  return NULL;
-}
-
-void CPWL_IconList_Content::SetListData(int32_t nItemIndex, void* pData) {
-  if (CPWL_IconList_Item* pItem = GetListItem(nItemIndex))
-    pItem->SetData(pData);
-}
-
-void CPWL_IconList_Content::SetListIcon(int32_t nItemIndex,
-                                        int32_t nIconIndex) {
-  if (CPWL_IconList_Item* pItem = GetListItem(nItemIndex))
-    pItem->SetIcon(nIconIndex);
-}
-
-void CPWL_IconList_Content::SetListString(int32_t nItemIndex,
-                                          const CFX_WideString& str) {
-  if (CPWL_IconList_Item* pItem = GetListItem(nItemIndex))
-    pItem->SetText(str);
-}
-
-CFX_WideString CPWL_IconList_Content::GetListString(int32_t nItemIndex) const {
-  if (CPWL_IconList_Item* pItem = GetListItem(nItemIndex))
-    return pItem->GetText();
-
-  return L"";
-}
-
-void CPWL_IconList_Content::SetIconFillColor(const CPWL_Color& color) {
-  for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
-    if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
-      if (pChild->GetClassName() == "CPWL_IconList_Item") {
-        CPWL_IconList_Item* pItem = (CPWL_IconList_Item*)pChild;
-        pItem->SetIconFillColor(color);
-        pItem->InvalidateRect();
-      }
-    }
-  }
-}
-
-CPWL_IconList::CPWL_IconList(int32_t nListCount)
-    : m_pListContent(NULL), m_nListCount(nListCount) {}
-
-CPWL_IconList::~CPWL_IconList() {}
-
-void CPWL_IconList::RePosChildWnd() {
-  CPWL_Wnd::RePosChildWnd();
-
-  if (m_pListContent)
-    m_pListContent->Move(GetClientRect(), TRUE, FALSE);
-}
-
-void CPWL_IconList::CreateChildWnd(const PWL_CREATEPARAM& cp) {
-  m_pListContent = new CPWL_IconList_Content(m_nListCount);
-
-  PWL_CREATEPARAM ccp = cp;
-  ccp.pParentWnd = this;
-  ccp.dwFlags = PWS_CHILD | PWS_VISIBLE;
-  m_pListContent->Create(ccp);
-}
-
-void CPWL_IconList::OnCreated() {
-  if (CPWL_ScrollBar* pScrollBar = GetVScrollBar()) {
-    pScrollBar->RemoveFlag(PWS_AUTOTRANSPARENT);
-    pScrollBar->SetTransparency(255);
-    pScrollBar->SetNotifyForever(TRUE);
-  }
-}
-
-void CPWL_IconList::OnNotify(CPWL_Wnd* pWnd,
-                             FX_DWORD msg,
-                             intptr_t wParam,
-                             intptr_t lParam) {
-  CPWL_Wnd::OnNotify(pWnd, msg, wParam, lParam);
-
-  if (wParam == SBT_VSCROLL) {
-    switch (msg) {
-      case PNM_SETSCROLLINFO:
-        if (PWL_SCROLL_INFO* pInfo = (PWL_SCROLL_INFO*)lParam) {
-          if (CPWL_ScrollBar* pScrollBar = GetVScrollBar()) {
-            if (pInfo->fContentMax - pInfo->fContentMin > pInfo->fPlateWidth) {
-              if (!pScrollBar->IsVisible()) {
-                pScrollBar->SetVisible(TRUE);
-                RePosChildWnd();
-              } else {
-              }
-            } else {
-              if (pScrollBar->IsVisible()) {
-                pScrollBar->SetVisible(FALSE);
-                RePosChildWnd();
-              }
-
-              if (m_pListContent)
-                m_pListContent->SetScrollPos(CPDF_Point(0.0f, 0.0f));
-            }
-
-            pScrollBar->OnNotify(pWnd, PNM_SETSCROLLINFO, wParam, lParam);
-          }
-        }
-        return;
-      case PNM_SCROLLWINDOW:
-        if (m_pListContent) {
-          m_pListContent->SetScrollPos(CPDF_Point(0.0f, *(FX_FLOAT*)lParam));
-          m_pListContent->ResetFace();
-          m_pListContent->InvalidateRect(NULL);
-        }
-        return;
-      case PNM_SETSCROLLPOS:
-        if (CPWL_ScrollBar* pScrollBar = GetVScrollBar())
-          pScrollBar->OnNotify(pWnd, PNM_SETSCROLLPOS, wParam, lParam);
-        return;
-    }
-  }
-}
-
-void CPWL_IconList::SetSelect(int32_t nIndex) {
-  m_pListContent->SetSelect(nIndex);
-}
-
-void CPWL_IconList::SetTopItem(int32_t nIndex) {
-  m_pListContent->ScrollToItem(nIndex);
-}
-
-int32_t CPWL_IconList::GetSelect() const {
-  return m_pListContent->GetSelect();
-}
-
-void CPWL_IconList::SetNotify(IPWL_IconList_Notify* pNotify) {
-  m_pListContent->SetNotify(pNotify);
-}
-
-void CPWL_IconList::EnableNotify(FX_BOOL bNotify) {
-  m_pListContent->EnableNotify(bNotify);
-}
-
-void CPWL_IconList::SetListData(int32_t nItemIndex, void* pData) {
-  m_pListContent->SetListData(nItemIndex, pData);
-}
-
-void CPWL_IconList::SetListIcon(int32_t nItemIndex, int32_t nIconIndex) {
-  m_pListContent->SetListIcon(nItemIndex, nIconIndex);
-}
-
-void CPWL_IconList::SetListString(int32_t nItemIndex,
-                                  const CFX_WideString& str) {
-  m_pListContent->SetListString(nItemIndex, str);
-}
-
-CFX_WideString CPWL_IconList::GetListString(int32_t nItemIndex) const {
-  return m_pListContent->GetListString(nItemIndex);
-}
-
-void CPWL_IconList::SetIconFillColor(const CPWL_Color& color) {
-  m_pListContent->SetIconFillColor(color);
-}
-
-FX_BOOL CPWL_IconList::OnMouseWheel(short zDelta,
-                                    const CPDF_Point& point,
-                                    FX_DWORD nFlag) {
-  CPDF_Point ptScroll = m_pListContent->GetScrollPos();
-  CPDF_Rect rcScroll = m_pListContent->GetScrollArea();
-  CPDF_Rect rcContents = m_pListContent->GetClientRect();
-
-  if (rcScroll.top - rcScroll.bottom > rcContents.Height()) {
-    CPDF_Point ptNew = ptScroll;
-
-    if (zDelta > 0)
-      ptNew.y += 30;
-    else
-      ptNew.y -= 30;
-
-    if (ptNew.y > rcScroll.top)
-      ptNew.y = rcScroll.top;
-    if (ptNew.y < rcScroll.bottom + rcContents.Height())
-      ptNew.y = rcScroll.bottom + rcContents.Height();
-    if (ptNew.y < rcScroll.bottom)
-      ptNew.y = rcScroll.bottom;
-
-    if (ptNew.y != ptScroll.y) {
-      m_pListContent->SetScrollPos(ptNew);
-      m_pListContent->ResetFace();
-      m_pListContent->InvalidateRect(NULL);
-
-      if (CPWL_ScrollBar* pScrollBar = GetVScrollBar())
-        pScrollBar->OnNotify(this, PNM_SETSCROLLPOS, SBT_VSCROLL,
-                             (intptr_t)&ptNew.y);
-
-      return TRUE;
-    }
-  }
-
-  return FALSE;
-}
diff --git a/fpdfsdk/src/pdfwindow/PWL_Label.cpp b/fpdfsdk/src/pdfwindow/PWL_Label.cpp
deleted file mode 100644
index 4f8a0dd..0000000
--- a/fpdfsdk/src/pdfwindow/PWL_Label.cpp
+++ /dev/null
@@ -1,150 +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
-
-#include "fpdfsdk/include/pdfwindow/PWL_Label.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Wnd.h"
-
-CPWL_Label::CPWL_Label() : m_pEdit(NULL) {
-  m_pEdit = IFX_Edit::NewEdit();
-  ASSERT(m_pEdit);
-}
-
-CPWL_Label::~CPWL_Label() {
-  IFX_Edit::DelEdit(m_pEdit);
-}
-
-CFX_ByteString CPWL_Label::GetClassName() const {
-  return "CPWL_Label";
-}
-
-void CPWL_Label::OnCreated() {
-  SetParamByFlag();
-  SetFontSize(GetCreationParam().fFontSize);
-
-  m_pEdit->SetFontMap(GetFontMap());
-  m_pEdit->Initialize();
-
-  if (HasFlag(PES_TEXTOVERFLOW)) {
-    SetClipRect(CPDF_Rect(0.0f, 0.0f, 0.0f, 0.0f));
-    m_pEdit->SetTextOverflow(TRUE);
-  }
-}
-
-void CPWL_Label::SetText(const FX_WCHAR* csText) {
-  m_pEdit->SetText(csText);
-}
-
-void CPWL_Label::RePosChildWnd() {
-  m_pEdit->SetPlateRect(GetClientRect());
-}
-
-void CPWL_Label::SetFontSize(FX_FLOAT fFontSize) {
-  m_pEdit->SetFontSize(fFontSize);
-}
-
-FX_FLOAT CPWL_Label::GetFontSize() const {
-  return m_pEdit->GetFontSize();
-}
-
-void CPWL_Label::SetParamByFlag() {
-  if (HasFlag(PES_LEFT)) {
-    m_pEdit->SetAlignmentH(0);
-  } else if (HasFlag(PES_MIDDLE)) {
-    m_pEdit->SetAlignmentH(1);
-  } else if (HasFlag(PES_RIGHT)) {
-    m_pEdit->SetAlignmentH(2);
-  } else {
-    m_pEdit->SetAlignmentH(0);
-  }
-
-  if (HasFlag(PES_TOP)) {
-    m_pEdit->SetAlignmentV(0);
-  } else if (HasFlag(PES_CENTER)) {
-    m_pEdit->SetAlignmentV(1);
-  } else if (HasFlag(PES_BOTTOM)) {
-    m_pEdit->SetAlignmentV(2);
-  } else {
-    m_pEdit->SetAlignmentV(0);
-  }
-
-  if (HasFlag(PES_PASSWORD)) {
-    m_pEdit->SetPasswordChar('*');
-  }
-
-  m_pEdit->SetMultiLine(HasFlag(PES_MULTILINE));
-  m_pEdit->SetAutoReturn(HasFlag(PES_AUTORETURN));
-  m_pEdit->SetAutoFontSize(HasFlag(PWS_AUTOFONTSIZE));
-  m_pEdit->SetAutoScroll(HasFlag(PES_AUTOSCROLL));
-}
-
-void CPWL_Label::DrawThisAppearance(CFX_RenderDevice* pDevice,
-                                    CFX_Matrix* pUser2Device) {
-  CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device);
-
-  GetClientRect();
-
-  CPDF_Rect rcClip;
-  CPVT_WordRange wrRange = m_pEdit->GetVisibleWordRange();
-  CPVT_WordRange* pRange = NULL;
-
-  if (!HasFlag(PES_TEXTOVERFLOW)) {
-    rcClip = GetClientRect();
-    pRange = &wrRange;
-  }
-  IFX_SystemHandler* pSysHandler = GetSystemHandler();
-  IFX_Edit::DrawEdit(
-      pDevice, pUser2Device, m_pEdit,
-      CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()),
-      CPWL_Utils::PWLColorToFXColor(GetTextStrokeColor(), GetTransparency()),
-      rcClip, CPDF_Point(0.0f, 0.0f), pRange, pSysHandler, NULL);
-}
-
-void CPWL_Label::SetHorzScale(int32_t nHorzScale) {
-  m_pEdit->SetHorzScale(nHorzScale);
-}
-
-void CPWL_Label::SetCharSpace(FX_FLOAT fCharSpace) {
-  m_pEdit->SetCharSpace(fCharSpace);
-}
-
-CPDF_Rect CPWL_Label::GetContentRect() const {
-  return m_pEdit->GetContentRect();
-}
-
-void CPWL_Label::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) {
-  CPWL_Wnd::GetThisAppearanceStream(sAppStream);
-
-  sAppStream << GetTextAppearanceStream(CPDF_Point(0.0f, 0.0f));
-}
-
-CFX_ByteString CPWL_Label::GetTextAppearanceStream(
-    const CPDF_Point& ptOffset) const {
-  CFX_ByteTextBuf sRet;
-  CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream(m_pEdit, ptOffset);
-
-  if (sEdit.GetLength() > 0) {
-    sRet << "BT\n" << CPWL_Utils::GetColorAppStream(GetTextColor()) << sEdit
-         << "ET\n";
-  }
-
-  return sRet.GetByteString();
-}
-
-CFX_WideString CPWL_Label::GetText() const {
-  return m_pEdit->GetText();
-}
-
-void CPWL_Label::SetLimitChar(int32_t nLimitChar) {
-  m_pEdit->SetLimitChar(nLimitChar);
-}
-
-int32_t CPWL_Label::GetTotalWords() {
-  if (m_pEdit)
-    return m_pEdit->GetTotalWords();
-
-  return 0;
-}
diff --git a/fpdfsdk/src/pdfwindow/PWL_ListBox.cpp b/fpdfsdk/src/pdfwindow/PWL_ListBox.cpp
deleted file mode 100644
index e3e83f9..0000000
--- a/fpdfsdk/src/pdfwindow/PWL_ListBox.cpp
+++ /dev/null
@@ -1,532 +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
-
-#include "fpdfsdk/include/pdfwindow/PWL_ListBox.h"
-
-#include "fpdfsdk/include/pdfwindow/PWL_Edit.h"
-#include "fpdfsdk/include/pdfwindow/PWL_EditCtrl.h"
-#include "fpdfsdk/include/pdfwindow/PWL_ScrollBar.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Wnd.h"
-#include "public/fpdf_fwlevent.h"
-
-#define IsFloatZero(f) ((f) < 0.0001 && (f) > -0.0001)
-#define IsFloatBigger(fa, fb) ((fa) > (fb) && !IsFloatZero((fa) - (fb)))
-#define IsFloatSmaller(fa, fb) ((fa) < (fb) && !IsFloatZero((fa) - (fb)))
-#define IsFloatEqual(fa, fb) IsFloatZero((fa) - (fb))
-
-CPWL_List_Notify::CPWL_List_Notify(CPWL_ListBox* pList) : m_pList(pList) {
-  ASSERT(m_pList);
-}
-
-CPWL_List_Notify::~CPWL_List_Notify() {}
-
-void CPWL_List_Notify::IOnSetScrollInfoY(FX_FLOAT fPlateMin,
-                                         FX_FLOAT fPlateMax,
-                                         FX_FLOAT fContentMin,
-                                         FX_FLOAT fContentMax,
-                                         FX_FLOAT fSmallStep,
-                                         FX_FLOAT fBigStep) {
-  PWL_SCROLL_INFO Info;
-
-  Info.fPlateWidth = fPlateMax - fPlateMin;
-  Info.fContentMin = fContentMin;
-  Info.fContentMax = fContentMax;
-  Info.fSmallStep = fSmallStep;
-  Info.fBigStep = fBigStep;
-
-  m_pList->OnNotify(m_pList, PNM_SETSCROLLINFO, SBT_VSCROLL, (intptr_t)&Info);
-
-  if (CPWL_ScrollBar* pScroll = m_pList->GetVScrollBar()) {
-    if (IsFloatBigger(Info.fPlateWidth, Info.fContentMax - Info.fContentMin) ||
-        IsFloatEqual(Info.fPlateWidth, Info.fContentMax - Info.fContentMin)) {
-      if (pScroll->IsVisible()) {
-        pScroll->SetVisible(FALSE);
-        m_pList->RePosChildWnd();
-      }
-    } else {
-      if (!pScroll->IsVisible()) {
-        pScroll->SetVisible(TRUE);
-        m_pList->RePosChildWnd();
-      }
-    }
-  }
-}
-
-void CPWL_List_Notify::IOnSetScrollPosY(FX_FLOAT fy) {
-  m_pList->OnNotify(m_pList, PNM_SETSCROLLPOS, SBT_VSCROLL, (intptr_t)&fy);
-}
-
-void CPWL_List_Notify::IOnInvalidateRect(CPDF_Rect* pRect) {
-  m_pList->InvalidateRect(pRect);
-}
-
-CPWL_ListBox::CPWL_ListBox()
-    : m_pList(NULL),
-      m_pListNotify(NULL),
-      m_bMouseDown(FALSE),
-      m_bHoverSel(FALSE),
-      m_pFillerNotify(NULL) {
-  m_pList = IFX_List::NewList();
-}
-
-CPWL_ListBox::~CPWL_ListBox() {
-  IFX_List::DelList(m_pList);
-  delete m_pListNotify;
-  m_pListNotify = NULL;
-}
-
-CFX_ByteString CPWL_ListBox::GetClassName() const {
-  return "CPWL_ListBox";
-}
-
-void CPWL_ListBox::OnCreated() {
-  if (m_pList) {
-    delete m_pListNotify;
-
-    m_pList->SetFontMap(GetFontMap());
-    m_pList->SetNotify(m_pListNotify = new CPWL_List_Notify(this));
-
-    SetHoverSel(HasFlag(PLBS_HOVERSEL));
-    m_pList->SetMultipleSel(HasFlag(PLBS_MULTIPLESEL));
-    m_pList->SetFontSize(GetCreationParam().fFontSize);
-
-    m_bHoverSel = HasFlag(PLBS_HOVERSEL);
-  }
-}
-
-void CPWL_ListBox::OnDestroy() {
-  delete m_pListNotify;
-  m_pListNotify = NULL;
-}
-
-void CPWL_ListBox::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) {
-  CPWL_Wnd::GetThisAppearanceStream(sAppStream);
-
-  CFX_ByteTextBuf sListItems;
-
-  if (m_pList) {
-    CPDF_Rect rcPlate = m_pList->GetPlateRect();
-    for (int32_t i = 0, sz = m_pList->GetCount(); i < sz; i++) {
-      CPDF_Rect rcItem = m_pList->GetItemRect(i);
-
-      if (rcItem.bottom > rcPlate.top || rcItem.top < rcPlate.bottom)
-        continue;
-
-      CPDF_Point ptOffset(rcItem.left, (rcItem.top + rcItem.bottom) * 0.5f);
-      if (m_pList->IsItemSelected(i)) {
-        sListItems << CPWL_Utils::GetRectFillAppStream(
-            rcItem, PWL_DEFAULT_SELBACKCOLOR);
-        CFX_ByteString sItem =
-            CPWL_Utils::GetEditAppStream(m_pList->GetItemEdit(i), ptOffset);
-        if (sItem.GetLength() > 0) {
-          sListItems << "BT\n"
-                     << CPWL_Utils::GetColorAppStream(PWL_DEFAULT_SELTEXTCOLOR)
-                     << sItem << "ET\n";
-        }
-      } else {
-        CFX_ByteString sItem =
-            CPWL_Utils::GetEditAppStream(m_pList->GetItemEdit(i), ptOffset);
-        if (sItem.GetLength() > 0) {
-          sListItems << "BT\n" << CPWL_Utils::GetColorAppStream(GetTextColor())
-                     << sItem << "ET\n";
-        }
-      }
-    }
-  }
-
-  if (sListItems.GetLength() > 0) {
-    CFX_ByteTextBuf sClip;
-    CPDF_Rect rcClient = GetClientRect();
-
-    sClip << "q\n";
-    sClip << rcClient.left << " " << rcClient.bottom << " "
-          << rcClient.right - rcClient.left << " "
-          << rcClient.top - rcClient.bottom << " re W n\n";
-
-    sClip << sListItems << "Q\n";
-
-    sAppStream << "/Tx BMC\n" << sClip << "EMC\n";
-  }
-}
-
-void CPWL_ListBox::DrawThisAppearance(CFX_RenderDevice* pDevice,
-                                      CFX_Matrix* pUser2Device) {
-  CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device);
-
-  if (m_pList) {
-    CPDF_Rect rcPlate = m_pList->GetPlateRect();
-    CPDF_Rect rcList = GetListRect();
-    CPDF_Rect rcClient = GetClientRect();
-
-    for (int32_t i = 0, sz = m_pList->GetCount(); i < sz; i++) {
-      CPDF_Rect rcItem = m_pList->GetItemRect(i);
-      if (rcItem.bottom > rcPlate.top || rcItem.top < rcPlate.bottom)
-        continue;
-
-      CPDF_Point ptOffset(rcItem.left, (rcItem.top + rcItem.bottom) * 0.5f);
-      if (IFX_Edit* pEdit = m_pList->GetItemEdit(i)) {
-        CPDF_Rect rcContent = pEdit->GetContentRect();
-        if (rcContent.Width() > rcClient.Width())
-          rcItem.Intersect(rcList);
-        else
-          rcItem.Intersect(rcClient);
-      }
-
-      if (m_pList->IsItemSelected(i)) {
-        IFX_SystemHandler* pSysHandler = GetSystemHandler();
-        if (pSysHandler && pSysHandler->IsSelectionImplemented()) {
-          IFX_Edit::DrawEdit(
-              pDevice, pUser2Device, m_pList->GetItemEdit(i),
-              CPWL_Utils::PWLColorToFXColor(GetTextColor()),
-              CPWL_Utils::PWLColorToFXColor(GetTextStrokeColor()), rcList,
-              ptOffset, NULL, pSysHandler, m_pFormFiller);
-          pSysHandler->OutputSelectedRect(m_pFormFiller, rcItem);
-        } else {
-          CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rcItem,
-                                   ArgbEncode(255, 0, 51, 113));
-          IFX_Edit::DrawEdit(pDevice, pUser2Device, m_pList->GetItemEdit(i),
-                             ArgbEncode(255, 255, 255, 255), 0, rcList,
-                             ptOffset, NULL, pSysHandler, m_pFormFiller);
-        }
-      } else {
-        IFX_SystemHandler* pSysHandler = GetSystemHandler();
-        IFX_Edit::DrawEdit(pDevice, pUser2Device, m_pList->GetItemEdit(i),
-                           CPWL_Utils::PWLColorToFXColor(GetTextColor()),
-                           CPWL_Utils::PWLColorToFXColor(GetTextStrokeColor()),
-                           rcList, ptOffset, NULL, pSysHandler, NULL);
-      }
-    }
-  }
-}
-
-FX_BOOL CPWL_ListBox::OnKeyDown(FX_WORD nChar, FX_DWORD nFlag) {
-  CPWL_Wnd::OnKeyDown(nChar, nFlag);
-
-  if (!m_pList)
-    return FALSE;
-
-  switch (nChar) {
-    default:
-      return FALSE;
-    case FWL_VKEY_Up:
-    case FWL_VKEY_Down:
-    case FWL_VKEY_Home:
-    case FWL_VKEY_Left:
-    case FWL_VKEY_End:
-    case FWL_VKEY_Right:
-      break;
-  }
-
-  switch (nChar) {
-    case FWL_VKEY_Up:
-      m_pList->OnVK_UP(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
-      break;
-    case FWL_VKEY_Down:
-      m_pList->OnVK_DOWN(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
-      break;
-    case FWL_VKEY_Home:
-      m_pList->OnVK_HOME(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
-      break;
-    case FWL_VKEY_Left:
-      m_pList->OnVK_LEFT(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
-      break;
-    case FWL_VKEY_End:
-      m_pList->OnVK_END(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
-      break;
-    case FWL_VKEY_Right:
-      m_pList->OnVK_RIGHT(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
-      break;
-    case FWL_VKEY_Delete:
-      break;
-  }
-
-  FX_BOOL bExit = FALSE;
-  OnNotifySelChanged(TRUE, bExit, nFlag);
-
-  return TRUE;
-}
-
-FX_BOOL CPWL_ListBox::OnChar(FX_WORD nChar, FX_DWORD nFlag) {
-  CPWL_Wnd::OnChar(nChar, nFlag);
-
-  if (!m_pList)
-    return FALSE;
-
-  if (!m_pList->OnChar(nChar, IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag)))
-    return FALSE;
-
-  FX_BOOL bExit = FALSE;
-  OnNotifySelChanged(TRUE, bExit, nFlag);
-
-  return TRUE;
-}
-
-FX_BOOL CPWL_ListBox::OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) {
-  CPWL_Wnd::OnLButtonDown(point, nFlag);
-
-  if (ClientHitTest(point)) {
-    m_bMouseDown = TRUE;
-    SetFocus();
-    SetCapture();
-
-    if (m_pList)
-      m_pList->OnMouseDown(point, IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
-  }
-
-  return TRUE;
-}
-
-FX_BOOL CPWL_ListBox::OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag) {
-  CPWL_Wnd::OnLButtonUp(point, nFlag);
-
-  if (m_bMouseDown) {
-    ReleaseCapture();
-    m_bMouseDown = FALSE;
-  }
-
-  FX_BOOL bExit = FALSE;
-  OnNotifySelChanged(FALSE, bExit, nFlag);
-
-  return TRUE;
-}
-
-void CPWL_ListBox::SetHoverSel(FX_BOOL bHoverSel) {
-  m_bHoverSel = bHoverSel;
-}
-
-FX_BOOL CPWL_ListBox::OnMouseMove(const CPDF_Point& point, FX_DWORD nFlag) {
-  CPWL_Wnd::OnMouseMove(point, nFlag);
-
-  if (m_bHoverSel && !IsCaptureMouse() && ClientHitTest(point)) {
-    if (m_pList)
-      m_pList->Select(m_pList->GetItemIndex(point));
-  }
-
-  if (m_bMouseDown) {
-    if (m_pList)
-      m_pList->OnMouseMove(point, IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
-  }
-
-  return TRUE;
-}
-
-void CPWL_ListBox::OnNotify(CPWL_Wnd* pWnd,
-                            FX_DWORD msg,
-                            intptr_t wParam,
-                            intptr_t lParam) {
-  CPWL_Wnd::OnNotify(pWnd, msg, wParam, lParam);
-
-  FX_FLOAT fPos;
-
-  switch (msg) {
-    case PNM_SETSCROLLINFO:
-      switch (wParam) {
-        case SBT_VSCROLL:
-          if (CPWL_Wnd* pChild = GetVScrollBar()) {
-            pChild->OnNotify(pWnd, PNM_SETSCROLLINFO, wParam, lParam);
-          }
-          break;
-      }
-      break;
-    case PNM_SETSCROLLPOS:
-      switch (wParam) {
-        case SBT_VSCROLL:
-          if (CPWL_Wnd* pChild = GetVScrollBar()) {
-            pChild->OnNotify(pWnd, PNM_SETSCROLLPOS, wParam, lParam);
-          }
-          break;
-      }
-      break;
-    case PNM_SCROLLWINDOW:
-      fPos = *(FX_FLOAT*)lParam;
-      switch (wParam) {
-        case SBT_VSCROLL:
-          if (m_pList)
-            m_pList->SetScrollPos(CPDF_Point(0, fPos));
-          break;
-      }
-      break;
-  }
-}
-
-void CPWL_ListBox::KillFocus() {
-  CPWL_Wnd::KillFocus();
-}
-
-void CPWL_ListBox::RePosChildWnd() {
-  CPWL_Wnd::RePosChildWnd();
-
-  if (m_pList)
-    m_pList->SetPlateRect(GetListRect());
-}
-
-void CPWL_ListBox::OnNotifySelChanged(FX_BOOL bKeyDown,
-                                      FX_BOOL& bExit,
-                                      FX_DWORD nFlag) {
-  if (!m_pFillerNotify)
-    return;
-
-  FX_BOOL bRC = TRUE;
-  CFX_WideString swChange = GetText();
-  CFX_WideString strChangeEx;
-  int nSelStart = 0;
-  int nSelEnd = swChange.GetLength();
-  m_pFillerNotify->OnBeforeKeyStroke(GetAttachedData(), swChange, strChangeEx,
-                                     nSelStart, nSelEnd, bKeyDown, bRC, bExit,
-                                     nFlag);
-}
-
-CPDF_Rect CPWL_ListBox::GetFocusRect() const {
-  if (m_pList && m_pList->IsMultipleSel()) {
-    CPDF_Rect rcCaret = m_pList->GetItemRect(m_pList->GetCaret());
-    rcCaret.Intersect(GetClientRect());
-    return rcCaret;
-  }
-
-  return CPWL_Wnd::GetFocusRect();
-}
-
-void CPWL_ListBox::AddString(const FX_WCHAR* string) {
-  if (m_pList) {
-    m_pList->AddString(string);
-  }
-}
-
-CFX_WideString CPWL_ListBox::GetText() const {
-  if (m_pList)
-    return m_pList->GetText();
-
-  return L"";
-}
-
-void CPWL_ListBox::SetFontSize(FX_FLOAT fFontSize) {
-  if (m_pList)
-    m_pList->SetFontSize(fFontSize);
-}
-
-FX_FLOAT CPWL_ListBox::GetFontSize() const {
-  if (m_pList)
-    return m_pList->GetFontSize();
-  return 0.0f;
-}
-
-void CPWL_ListBox::Select(int32_t nItemIndex) {
-  if (m_pList)
-    m_pList->Select(nItemIndex);
-}
-
-void CPWL_ListBox::SetCaret(int32_t nItemIndex) {
-  if (m_pList)
-    m_pList->SetCaret(nItemIndex);
-}
-
-void CPWL_ListBox::SetTopVisibleIndex(int32_t nItemIndex) {
-  if (m_pList)
-    m_pList->SetTopItem(nItemIndex);
-}
-
-void CPWL_ListBox::ScrollToListItem(int32_t nItemIndex) {
-  if (m_pList)
-    m_pList->ScrollToListItem(nItemIndex);
-}
-
-void CPWL_ListBox::ResetContent() {
-  if (m_pList)
-    m_pList->Empty();
-}
-
-void CPWL_ListBox::Reset() {
-  if (m_pList)
-    m_pList->Cancel();
-}
-
-FX_BOOL CPWL_ListBox::IsMultipleSel() const {
-  if (m_pList)
-    return m_pList->IsMultipleSel();
-
-  return FALSE;
-}
-
-int32_t CPWL_ListBox::GetCaretIndex() const {
-  if (m_pList)
-    return m_pList->GetCaret();
-
-  return -1;
-}
-
-int32_t CPWL_ListBox::GetCurSel() const {
-  if (m_pList)
-    return m_pList->GetSelect();
-
-  return -1;
-}
-
-FX_BOOL CPWL_ListBox::IsItemSelected(int32_t nItemIndex) const {
-  if (m_pList)
-    return m_pList->IsItemSelected(nItemIndex);
-
-  return FALSE;
-}
-
-int32_t CPWL_ListBox::GetTopVisibleIndex() const {
-  if (m_pList) {
-    m_pList->ScrollToListItem(m_pList->GetFirstSelected());
-    return m_pList->GetTopItem();
-  }
-
-  return -1;
-}
-
-int32_t CPWL_ListBox::GetCount() const {
-  if (m_pList)
-    return m_pList->GetCount();
-
-  return 0;
-}
-
-int32_t CPWL_ListBox::FindNext(int32_t nIndex, FX_WCHAR nChar) const {
-  if (m_pList)
-    return m_pList->FindNext(nIndex, nChar);
-
-  return nIndex;
-}
-
-CPDF_Rect CPWL_ListBox::GetContentRect() const {
-  if (m_pList)
-    return m_pList->GetContentRect();
-
-  return CPDF_Rect();
-}
-
-FX_FLOAT CPWL_ListBox::GetFirstHeight() const {
-  if (m_pList)
-    return m_pList->GetFirstHeight();
-
-  return 0.0f;
-}
-
-CPDF_Rect CPWL_ListBox::GetListRect() const {
-  return CPWL_Utils::DeflateRect(
-      GetWindowRect(), (FX_FLOAT)(GetBorderWidth() + GetInnerBorderWidth()));
-}
-
-FX_BOOL CPWL_ListBox::OnMouseWheel(short zDelta,
-                                   const CPDF_Point& point,
-                                   FX_DWORD nFlag) {
-  if (!m_pList)
-    return FALSE;
-
-  if (zDelta < 0) {
-    m_pList->OnVK_DOWN(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
-  } else {
-    m_pList->OnVK_UP(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
-  }
-
-  FX_BOOL bExit = FALSE;
-  OnNotifySelChanged(FALSE, bExit, nFlag);
-  return TRUE;
-}
diff --git a/fpdfsdk/src/pdfwindow/PWL_ListCtrl.cpp b/fpdfsdk/src/pdfwindow/PWL_ListCtrl.cpp
deleted file mode 100644
index 6d9627b..0000000
--- a/fpdfsdk/src/pdfwindow/PWL_ListCtrl.cpp
+++ /dev/null
@@ -1,205 +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
-
-#include "fpdfsdk/include/pdfwindow/PWL_ListCtrl.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Wnd.h"
-
-CPWL_ListCtrl::CPWL_ListCtrl()
-    : m_rcContent(0, 0, 0, 0),
-      m_ptScroll(0, 0),
-      m_fItemSpace(0.0f),
-      m_fTopSpace(0.0f),
-      m_fBottomSpace(0.0f) {}
-
-CPWL_ListCtrl::~CPWL_ListCtrl() {}
-
-void CPWL_ListCtrl::SetScrollPos(const CPDF_Point& point) {
-  m_ptScroll = point;
-
-  if (m_ptScroll.x < m_rcContent.left)
-    m_ptScroll.x = m_rcContent.left;
-
-  if (m_ptScroll.x > m_rcContent.right)
-    m_ptScroll.x = m_rcContent.right;
-
-  if (m_ptScroll.y > m_rcContent.top)
-    m_ptScroll.y = m_rcContent.top;
-
-  if (m_ptScroll.y < m_rcContent.bottom)
-    m_ptScroll.y = m_rcContent.bottom;
-}
-
-CPDF_Point CPWL_ListCtrl::GetScrollPos() const {
-  return m_ptScroll;
-}
-
-CPDF_Rect CPWL_ListCtrl::GetScrollArea() const {
-  return m_rcContent;
-}
-
-void CPWL_ListCtrl::ResetFace() {
-  ResetAll(FALSE, 0);
-}
-
-void CPWL_ListCtrl::ResetContent(int32_t nStart) {
-  if (nStart < 0)
-    nStart = 0;
-  if (nStart >= 0 && nStart < m_aChildren.GetSize())
-    ResetAll(TRUE, nStart);
-}
-
-FX_FLOAT CPWL_ListCtrl::GetContentsHeight(FX_FLOAT fLimitWidth) {
-  FX_FLOAT fRet = m_fTopSpace;
-
-  FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
-
-  if (fLimitWidth > fBorderWidth * 2) {
-    for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
-      if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
-        FX_FLOAT fLeft = pChild->GetItemLeftMargin();
-        FX_FLOAT fRight = pChild->GetItemRightMargin();
-
-        fRet += pChild->GetItemHeight(fLimitWidth - fBorderWidth * 2 - fLeft -
-                                      fRight);
-        fRet += m_fItemSpace;
-      }
-    }
-
-    fRet -= m_fItemSpace;
-  }
-
-  fRet += m_fBottomSpace;
-
-  return fRet;
-}
-
-void CPWL_ListCtrl::ResetAll(FX_BOOL bMove, int32_t nStart) {
-  CPDF_Rect rcClient = GetClientRect();
-
-  FX_FLOAT fWidth = rcClient.Width();
-
-  FX_FLOAT fy = 0.0f - m_fTopSpace;
-
-  if (nStart - 1 >= 0 && nStart - 1 < m_aChildren.GetSize())
-    if (CPWL_Wnd* pChild = m_aChildren.GetAt(nStart - 1))
-      fy = pChild->GetWindowRect().bottom - m_fItemSpace;
-
-  for (int32_t i = nStart, sz = m_aChildren.GetSize(); i < sz; i++) {
-    if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
-      FX_FLOAT fLeft = pChild->GetItemLeftMargin();
-      FX_FLOAT fRight = pChild->GetItemRightMargin();
-
-      pChild->SetChildMatrix(CFX_Matrix(1, 0, 0, 1,
-                                        rcClient.left - m_ptScroll.x,
-                                        rcClient.top - m_ptScroll.y));
-
-      if (bMove) {
-        FX_FLOAT fItemHeight = pChild->GetItemHeight(fWidth - fLeft - fRight);
-        pChild->Move(CPDF_Rect(fLeft, fy - fItemHeight, fWidth - fRight, fy),
-                     TRUE, FALSE);
-        fy -= fItemHeight;
-        fy -= m_fItemSpace;
-      }
-    }
-  }
-
-  fy += m_fItemSpace;
-
-  fy -= m_fBottomSpace;
-
-  if (bMove) {
-    m_rcContent.left = 0;
-    m_rcContent.top = 0;
-    m_rcContent.right = fWidth;
-    m_rcContent.bottom = fy;
-  }
-}
-
-void CPWL_ListCtrl::SetItemSpace(FX_FLOAT fSpace) {
-  m_fItemSpace = fSpace;
-}
-
-void CPWL_ListCtrl::SetTopSpace(FX_FLOAT fSpace) {
-  m_fTopSpace = fSpace;
-}
-
-void CPWL_ListCtrl::SetBottomSpace(FX_FLOAT fSpace) {
-  m_fBottomSpace = fSpace;
-}
-
-void CPWL_ListCtrl::RePosChildWnd() {
-  ResetFace();
-}
-
-void CPWL_ListCtrl::DrawChildAppearance(CFX_RenderDevice* pDevice,
-                                        CFX_Matrix* pUser2Device) {
-  pDevice->SaveState();
-  CPDF_Rect rcClient = GetClientRect();
-  CPDF_Rect rcTemp = rcClient;
-  pUser2Device->TransformRect(rcTemp);
-  FX_RECT rcClip((int32_t)rcTemp.left, (int32_t)rcTemp.bottom,
-                 (int32_t)rcTemp.right, (int32_t)rcTemp.top);
-
-  pDevice->SetClip_Rect(&rcClip);
-
-  for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
-    if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
-      CPDF_Rect rcChild = pChild->ChildToParent(pChild->GetWindowRect());
-      if (!(rcChild.top < rcClient.bottom || rcChild.bottom > rcClient.top)) {
-        CFX_Matrix mt = pChild->GetChildMatrix();
-        if (mt.IsIdentity()) {
-          pChild->DrawAppearance(pDevice, pUser2Device);
-        } else {
-          mt.Concat(*pUser2Device);
-          pChild->DrawAppearance(pDevice, &mt);
-        }
-      }
-    }
-  }
-
-  pDevice->RestoreState();
-}
-
-int32_t CPWL_ListCtrl::GetItemIndex(CPWL_Wnd* pItem) {
-  for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
-    if (pItem == m_aChildren.GetAt(i))
-      return i;
-  }
-
-  return -1;
-}
-
-CPDF_Point CPWL_ListCtrl::InToOut(const CPDF_Point& point) const {
-  CPDF_Rect rcClient = GetClientRect();
-
-  return CPDF_Point(point.x + rcClient.left - m_ptScroll.x,
-                    point.y + rcClient.top - m_ptScroll.y);
-}
-
-CPDF_Point CPWL_ListCtrl::OutToIn(const CPDF_Point& point) const {
-  CPDF_Rect rcClient = GetClientRect();
-
-  return CPDF_Point(point.x - rcClient.left + m_ptScroll.x,
-                    point.y - rcClient.top + m_ptScroll.y);
-}
-
-CPDF_Rect CPWL_ListCtrl::InToOut(const CPDF_Rect& rect) const {
-  CPDF_Rect rcClient = GetClientRect();
-
-  return CPDF_Rect(rect.left + rcClient.left - m_ptScroll.x,
-                   rect.bottom + rcClient.top - m_ptScroll.y,
-                   rect.right + rcClient.left - m_ptScroll.x,
-                   rect.top + rcClient.top - m_ptScroll.y);
-}
-
-CPDF_Rect CPWL_ListCtrl::OutToIn(const CPDF_Rect& rect) const {
-  CPDF_Rect rcClient = GetClientRect();
-
-  return CPDF_Rect(rect.left - rcClient.left + m_ptScroll.x,
-                   rect.bottom - rcClient.top + m_ptScroll.y,
-                   rect.right - rcClient.left + m_ptScroll.x,
-                   rect.top - rcClient.top + m_ptScroll.y);
-}
diff --git a/fpdfsdk/src/pdfwindow/PWL_Note.cpp b/fpdfsdk/src/pdfwindow/PWL_Note.cpp
deleted file mode 100644
index 760967b..0000000
--- a/fpdfsdk/src/pdfwindow/PWL_Note.cpp
+++ /dev/null
@@ -1,1509 +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
-
-#include "fpdfsdk/include/pdfwindow/PWL_Note.h"
-
-#include "fpdfsdk/include/pdfwindow/PWL_Button.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Caret.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Edit.h"
-#include "fpdfsdk/include/pdfwindow/PWL_EditCtrl.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Label.h"
-#include "fpdfsdk/include/pdfwindow/PWL_ListCtrl.h"
-#include "fpdfsdk/include/pdfwindow/PWL_ScrollBar.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Wnd.h"
-
-#define POPUP_ITEM_HEAD_BOTTOM 3.0f
-#define POPUP_ITEM_BOTTOMWIDTH 1.0f
-#define POPUP_ITEM_SIDEMARGIN 3.0f
-#define POPUP_ITEM_SPACE 4.0f
-#define POPUP_ITEM_TEXT_INDENT 2.0f
-#define POPUP_ITEM_BORDERCOLOR \
-  CPWL_Color(COLORTYPE_RGB, 80 / 255.0f, 80 / 255.0f, 80 / 255.0f)
-
-#define IsFloatZero(f) ((f) < 0.0001 && (f) > -0.0001)
-#define IsFloatBigger(fa, fb) ((fa) > (fb) && !IsFloatZero((fa) - (fb)))
-#define IsFloatSmaller(fa, fb) ((fa) < (fb) && !IsFloatZero((fa) - (fb)))
-#define IsFloatEqual(fa, fb) IsFloatZero((fa) - (fb))
-
-CPWL_Note_Options::CPWL_Note_Options() : m_pText(NULL) {}
-
-CPWL_Note_Options::~CPWL_Note_Options() {}
-
-void CPWL_Note_Options::SetTextColor(const CPWL_Color& color) {
-  CPWL_Wnd::SetTextColor(color);
-
-  if (m_pText)
-    m_pText->SetTextColor(color);
-}
-
-void CPWL_Note_Options::RePosChildWnd() {
-  if (IsValid()) {
-    CPDF_Rect rcClient = GetClientRect();
-
-    if (rcClient.Width() > 15.0f) {
-      rcClient.right -= 15.0f;
-      m_pText->Move(rcClient, TRUE, FALSE);
-      m_pText->SetVisible(TRUE);
-    } else {
-      m_pText->Move(CPDF_Rect(0, 0, 0, 0), TRUE, FALSE);
-      m_pText->SetVisible(FALSE);
-    }
-  }
-}
-
-void CPWL_Note_Options::CreateChildWnd(const PWL_CREATEPARAM& cp) {
-  m_pText = new CPWL_Label;
-  PWL_CREATEPARAM tcp = cp;
-  tcp.pParentWnd = this;
-  tcp.dwFlags = PWS_CHILD | PWS_VISIBLE;
-  m_pText->Create(tcp);
-}
-
-void CPWL_Note_Options::SetText(const CFX_WideString& sText) {
-  m_pText->SetText(sText.c_str());
-}
-
-void CPWL_Note_Options::DrawThisAppearance(CFX_RenderDevice* pDevice,
-                                           CFX_Matrix* pUser2Device) {
-  CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device);
-
-  CPDF_Rect rcClient = GetClientRect();
-  rcClient.left = rcClient.right - 15.0f;
-
-  CPDF_Point ptCenter = CPDF_Point((rcClient.left + rcClient.right) * 0.5f,
-                                   (rcClient.top + rcClient.bottom) * 0.5f);
-
-  CPDF_Point pt1(ptCenter.x - 2.0f, ptCenter.y + 2.0f * 0.5f);
-  CPDF_Point pt2(ptCenter.x + 2.0f, ptCenter.y + 2.0f * 0.5f);
-  CPDF_Point pt3(ptCenter.x, ptCenter.y - 3.0f * 0.5f);
-
-  CFX_PathData path;
-
-  path.SetPointCount(4);
-  path.SetPoint(0, pt1.x, pt1.y, FXPT_MOVETO);
-  path.SetPoint(1, pt2.x, pt2.y, FXPT_LINETO);
-  path.SetPoint(2, pt3.x, pt3.y, FXPT_LINETO);
-  path.SetPoint(3, pt1.x, pt1.y, FXPT_LINETO);
-
-  pDevice->DrawPath(
-      &path, pUser2Device, NULL,
-      CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()), 0,
-      FXFILL_ALTERNATE);
-}
-
-CPDF_Rect CPWL_Note_Options::GetContentRect() const {
-  CPDF_Rect rcText = m_pText->GetContentRect();
-  rcText.right += 15.0f;
-  return rcText;
-}
-
-CPWL_Note_Edit::CPWL_Note_Edit()
-    : m_bEnableNotify(TRUE),
-      m_fOldItemHeight(0.0f),
-      m_bSizeChanged(FALSE),
-      m_fOldMin(0.0f),
-      m_fOldMax(0.0f) {}
-
-CPWL_Note_Edit::~CPWL_Note_Edit() {}
-
-void CPWL_Note_Edit::RePosChildWnd() {
-  m_bEnableNotify = FALSE;
-  CPWL_Edit::RePosChildWnd();
-  m_bEnableNotify = TRUE;
-
-  m_fOldItemHeight = GetContentRect().Height();
-}
-
-void CPWL_Note_Edit::SetText(const FX_WCHAR* csText) {
-  m_bEnableNotify = FALSE;
-  CPWL_Edit::SetText(csText);
-  m_bEnableNotify = TRUE;
-  m_fOldItemHeight = GetContentRect().Height();
-}
-
-void CPWL_Note_Edit::OnSetFocus() {
-  m_bEnableNotify = FALSE;
-  CPWL_Edit::OnSetFocus();
-  m_bEnableNotify = TRUE;
-
-  EnableSpellCheck(TRUE);
-}
-
-void CPWL_Note_Edit::OnKillFocus() {
-  EnableSpellCheck(FALSE);
-
-  if (CPWL_Wnd* pParent = GetParentWindow()) {
-    if (CPWL_Wnd* pGrand = pParent->GetParentWindow()) {
-      ASSERT(pGrand->GetClassName() == "CPWL_NoteItem");
-
-      CPWL_NoteItem* pNoteItem = (CPWL_NoteItem*)pGrand;
-
-      pNoteItem->OnContentsValidate();
-    }
-  }
-
-  CPWL_Edit::OnKillFocus();
-}
-
-void CPWL_Note_Edit::OnNotify(CPWL_Wnd* pWnd,
-                              FX_DWORD msg,
-                              intptr_t wParam,
-                              intptr_t lParam) {
-  if (m_bEnableNotify) {
-    if (wParam == SBT_VSCROLL) {
-      switch (msg) {
-        case PNM_SETSCROLLINFO:
-          if (PWL_SCROLL_INFO* pInfo = (PWL_SCROLL_INFO*)lParam) {
-            if (!IsFloatEqual(pInfo->fContentMax, m_fOldMax) ||
-                !IsFloatEqual(pInfo->fContentMin, m_fOldMin)) {
-              m_bSizeChanged = TRUE;
-              if (CPWL_Wnd* pParent = GetParentWindow()) {
-                pParent->OnNotify(this, PNM_NOTEEDITCHANGED, 0, 0);
-              }
-
-              m_fOldMax = pInfo->fContentMax;
-              m_fOldMin = pInfo->fContentMin;
-              return;
-            }
-          }
-      }
-    }
-  }
-
-  CPWL_Edit::OnNotify(pWnd, msg, wParam, lParam);
-
-  if (m_bEnableNotify) {
-    switch (msg) {
-      case PNM_SETCARETINFO:
-        if (PWL_CARET_INFO* pInfo = (PWL_CARET_INFO*)wParam) {
-          PWL_CARET_INFO newInfo = *pInfo;
-          newInfo.bVisible = TRUE;
-          newInfo.ptHead = ChildToParent(pInfo->ptHead);
-          newInfo.ptFoot = ChildToParent(pInfo->ptFoot);
-
-          if (CPWL_Wnd* pParent = GetParentWindow()) {
-            pParent->OnNotify(this, PNM_SETCARETINFO, (intptr_t)&newInfo, 0);
-          }
-        }
-        break;
-    }
-  }
-}
-
-FX_FLOAT CPWL_Note_Edit::GetItemHeight(FX_FLOAT fLimitWidth) {
-  if (fLimitWidth > 0) {
-    if (!m_bSizeChanged)
-      return m_fOldItemHeight;
-
-    m_bSizeChanged = FALSE;
-
-    EnableNotify(FALSE);
-    EnableRefresh(FALSE);
-    m_pEdit->EnableNotify(FALSE);
-
-    Move(CPDF_Rect(0, 0, fLimitWidth, 0), TRUE, FALSE);
-    FX_FLOAT fRet = GetContentRect().Height();
-
-    m_pEdit->EnableNotify(TRUE);
-    EnableNotify(TRUE);
-    EnableRefresh(TRUE);
-
-    return fRet;
-  }
-
-  return 0;
-}
-
-FX_FLOAT CPWL_Note_Edit::GetItemLeftMargin() {
-  return POPUP_ITEM_TEXT_INDENT;
-}
-
-FX_FLOAT CPWL_Note_Edit::GetItemRightMargin() {
-  return POPUP_ITEM_TEXT_INDENT;
-}
-
-CPWL_Note_LBBox::CPWL_Note_LBBox() {}
-
-CPWL_Note_LBBox::~CPWL_Note_LBBox() {}
-
-void CPWL_Note_LBBox::DrawThisAppearance(CFX_RenderDevice* pDevice,
-                                         CFX_Matrix* pUser2Device) {
-  CPDF_Rect rcClient = GetClientRect();
-
-  CFX_GraphStateData gsd;
-  gsd.m_LineWidth = 1.0f;
-
-  CFX_PathData pathCross;
-
-  pathCross.SetPointCount(4);
-  pathCross.SetPoint(0, rcClient.left, rcClient.top, FXPT_MOVETO);
-  pathCross.SetPoint(1, rcClient.right, rcClient.bottom, FXPT_LINETO);
-  pathCross.SetPoint(2, rcClient.left,
-                     rcClient.bottom + rcClient.Height() * 0.5f, FXPT_MOVETO);
-  pathCross.SetPoint(3, rcClient.left + rcClient.Width() * 0.5f,
-                     rcClient.bottom, FXPT_LINETO);
-
-  pDevice->DrawPath(
-      &pathCross, pUser2Device, &gsd, 0,
-      CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()),
-      FXFILL_ALTERNATE);
-}
-
-CPWL_Note_RBBox::CPWL_Note_RBBox() {}
-
-CPWL_Note_RBBox::~CPWL_Note_RBBox() {}
-
-void CPWL_Note_RBBox::DrawThisAppearance(CFX_RenderDevice* pDevice,
-                                         CFX_Matrix* pUser2Device) {
-  CPDF_Rect rcClient = GetClientRect();
-
-  CFX_GraphStateData gsd;
-  gsd.m_LineWidth = 1.0f;
-
-  CFX_PathData pathCross;
-
-  pathCross.SetPointCount(4);
-  pathCross.SetPoint(0, rcClient.right, rcClient.top, FXPT_MOVETO);
-  pathCross.SetPoint(1, rcClient.left, rcClient.bottom, FXPT_LINETO);
-  pathCross.SetPoint(2, rcClient.right,
-                     rcClient.bottom + rcClient.Height() * 0.5f, FXPT_MOVETO);
-  pathCross.SetPoint(3, rcClient.left + rcClient.Width() * 0.5f,
-                     rcClient.bottom, FXPT_LINETO);
-
-  pDevice->DrawPath(
-      &pathCross, pUser2Device, &gsd, 0,
-      CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()),
-      FXFILL_ALTERNATE);
-}
-
-CPWL_Note_Icon::CPWL_Note_Icon() : m_nType(0) {}
-
-CPWL_Note_Icon::~CPWL_Note_Icon() {}
-
-void CPWL_Note_Icon::SetIconType(int32_t nType) {
-  m_nType = nType;
-}
-
-void CPWL_Note_Icon::DrawThisAppearance(CFX_RenderDevice* pDevice,
-                                        CFX_Matrix* pUser2Device) {
-  CPWL_Utils::DrawIconAppStream(pDevice, pUser2Device, m_nType, GetClientRect(),
-                                GetBackgroundColor(), PWL_DEFAULT_BLACKCOLOR,
-                                GetTransparency());
-}
-
-CPWL_Note_CloseBox::CPWL_Note_CloseBox() : m_bMouseDown(FALSE) {}
-
-CPWL_Note_CloseBox::~CPWL_Note_CloseBox() {}
-
-void CPWL_Note_CloseBox::DrawThisAppearance(CFX_RenderDevice* pDevice,
-                                            CFX_Matrix* pUser2Device) {
-  CPWL_Button::DrawThisAppearance(pDevice, pUser2Device);
-
-  CPDF_Rect rcClient = GetClientRect();
-  rcClient = CPWL_Utils::DeflateRect(rcClient, 2.0f);
-
-  CFX_GraphStateData gsd;
-  gsd.m_LineWidth = 1.0f;
-
-  CFX_PathData pathCross;
-
-  if (m_bMouseDown) {
-    rcClient.left += 0.5f;
-    rcClient.right += 0.5f;
-    rcClient.top -= 0.5f;
-    rcClient.bottom -= 0.5f;
-  }
-
-  pathCross.SetPointCount(4);
-  pathCross.SetPoint(0, rcClient.left, rcClient.bottom, FXPT_MOVETO);
-  pathCross.SetPoint(1, rcClient.right, rcClient.top, FXPT_LINETO);
-  pathCross.SetPoint(2, rcClient.left, rcClient.top, FXPT_MOVETO);
-  pathCross.SetPoint(3, rcClient.right, rcClient.bottom, FXPT_LINETO);
-
-  pDevice->DrawPath(
-      &pathCross, pUser2Device, &gsd, 0,
-      CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()),
-      FXFILL_ALTERNATE);
-}
-
-FX_BOOL CPWL_Note_CloseBox::OnLButtonDown(const CPDF_Point& point,
-                                          FX_DWORD nFlag) {
-  SetBorderStyle(PBS_INSET);
-  InvalidateRect(NULL);
-
-  m_bMouseDown = TRUE;
-
-  return CPWL_Button::OnLButtonDown(point, nFlag);
-}
-
-FX_BOOL CPWL_Note_CloseBox::OnLButtonUp(const CPDF_Point& point,
-                                        FX_DWORD nFlag) {
-  m_bMouseDown = FALSE;
-
-  SetBorderStyle(PBS_BEVELED);
-  InvalidateRect(NULL);
-
-  return CPWL_Button::OnLButtonUp(point, nFlag);
-}
-
-CPWL_Note_Contents::CPWL_Note_Contents() : m_pEdit(NULL) {}
-
-CPWL_Note_Contents::~CPWL_Note_Contents() {}
-
-CFX_ByteString CPWL_Note_Contents::GetClassName() const {
-  return "CPWL_Note_Contents";
-}
-
-void CPWL_Note_Contents::CreateChildWnd(const PWL_CREATEPARAM& cp) {
-  m_pEdit = new CPWL_Note_Edit;
-  PWL_CREATEPARAM ecp = cp;
-  ecp.pParentWnd = this;
-  ecp.dwFlags = PWS_VISIBLE | PWS_CHILD | PES_MULTILINE | PES_AUTORETURN |
-                PES_TEXTOVERFLOW | PES_UNDO | PES_SPELLCHECK;
-
-  m_pEdit->EnableNotify(FALSE);
-  m_pEdit->Create(ecp);
-  m_pEdit->EnableNotify(TRUE);
-}
-
-void CPWL_Note_Contents::SetText(const CFX_WideString& sText) {
-  if (m_pEdit) {
-    m_pEdit->EnableNotify(FALSE);
-    m_pEdit->SetText(sText.c_str());
-    m_pEdit->EnableNotify(TRUE);
-    OnNotify(m_pEdit, PNM_NOTEEDITCHANGED, 0, 0);
-  }
-}
-
-CFX_WideString CPWL_Note_Contents::GetText() const {
-  if (m_pEdit)
-    return m_pEdit->GetText();
-
-  return L"";
-}
-
-CPWL_NoteItem* CPWL_Note_Contents::CreateSubItem() {
-  CPWL_NoteItem* pNoteItem = new CPWL_NoteItem;
-  PWL_CREATEPARAM icp = GetCreationParam();
-  icp.pParentWnd = this;
-  icp.dwFlags = PWS_CHILD | PWS_VISIBLE | PWS_BACKGROUND;
-  pNoteItem->Create(icp);
-
-  pNoteItem->OnCreateNoteItem();
-
-  pNoteItem->ResetSubjectName(m_aChildren.GetSize() - 1);
-
-  FX_SYSTEMTIME st;
-  if (IFX_SystemHandler* pSH = GetSystemHandler())
-    st = pSH->GetLocalTime();
-  pNoteItem->SetDateTime(st);
-
-  pNoteItem->SetContents(L"");
-
-  OnNotify(pNoteItem, PNM_NOTEEDITCHANGED, 0, 0);
-
-  return pNoteItem;
-}
-
-int32_t CPWL_Note_Contents::CountSubItems() const {
-  return m_aChildren.GetSize() - 1;
-}
-
-IPWL_NoteItem* CPWL_Note_Contents::GetSubItems(int32_t index) const {
-  int32_t nIndex = index + 1;
-
-  if (nIndex > 0 && nIndex < m_aChildren.GetSize()) {
-    if (CPWL_Wnd* pChild = m_aChildren.GetAt(nIndex)) {
-      ASSERT(pChild->GetClassName() == "CPWL_NoteItem");
-      CPWL_NoteItem* pItem = (CPWL_NoteItem*)pChild;
-      return pItem;
-    }
-  }
-  return NULL;
-}
-
-void CPWL_Note_Contents::DeleteSubItem(IPWL_NoteItem* pNoteItem) {
-  int32_t nIndex = GetItemIndex((CPWL_NoteItem*)pNoteItem);
-
-  if (nIndex > 0) {
-    if (CPWL_NoteItem* pPWLNoteItem = (CPWL_NoteItem*)pNoteItem) {
-      pPWLNoteItem->KillFocus();
-      pPWLNoteItem->Destroy();
-      delete pPWLNoteItem;
-    }
-
-    for (int32_t i = nIndex, sz = m_aChildren.GetSize(); i < sz; i++) {
-      if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
-        ASSERT(pChild->GetClassName() == "CPWL_NoteItem");
-        CPWL_NoteItem* pItem = (CPWL_NoteItem*)pChild;
-        pItem->ResetSubjectName(i);
-      }
-    }
-
-    OnNotify(this, PNM_NOTEEDITCHANGED, 0, 0);
-  }
-}
-
-IPWL_NoteItem* CPWL_Note_Contents::GetHitNoteItem(const CPDF_Point& point) {
-  CPDF_Point pt = ParentToChild(point);
-
-  for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
-    if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
-      if (pChild->GetClassName() == "CPWL_NoteItem") {
-        CPWL_NoteItem* pNoteItem = (CPWL_NoteItem*)pChild;
-        if (IPWL_NoteItem* pRet = pNoteItem->GetHitNoteItem(pt))
-          return pRet;
-      }
-    }
-  }
-  return NULL;
-}
-
-void CPWL_Note_Contents::OnNotify(CPWL_Wnd* pWnd,
-                                  FX_DWORD msg,
-                                  intptr_t wParam,
-                                  intptr_t lParam) {
-  switch (msg) {
-    case PNM_NOTEEDITCHANGED: {
-      int32_t nIndex = GetItemIndex(pWnd);
-      if (nIndex < 0)
-        nIndex = 0;
-
-      m_pEdit->EnableNotify(FALSE);
-      ResetContent(nIndex);
-      m_pEdit->EnableNotify(TRUE);
-
-      for (int32_t i = nIndex + 1, sz = m_aChildren.GetSize(); i < sz; i++) {
-        if (CPWL_Wnd* pChild = m_aChildren.GetAt(i))
-          pChild->OnNotify(this, PNM_NOTERESET, 0, 0);
-      }
-
-      if (CPWL_Wnd* pParent = GetParentWindow()) {
-        pParent->OnNotify(this, PNM_NOTEEDITCHANGED, 0, 0);
-      }
-    }
-      return;
-    case PNM_SCROLLWINDOW:
-      SetScrollPos(CPDF_Point(0.0f, *(FX_FLOAT*)lParam));
-      ResetFace();
-      InvalidateRect(NULL);
-      return;
-    case PNM_SETCARETINFO:
-      if (PWL_CARET_INFO* pInfo = (PWL_CARET_INFO*)wParam) {
-        PWL_CARET_INFO newInfo = *pInfo;
-        newInfo.bVisible = TRUE;
-        newInfo.ptHead = ChildToParent(pInfo->ptHead);
-        newInfo.ptFoot = ChildToParent(pInfo->ptFoot);
-
-        if (CPWL_Wnd* pParent = GetParentWindow()) {
-          pParent->OnNotify(this, PNM_SETCARETINFO, (intptr_t)&newInfo, 0);
-        }
-      }
-      return;
-    case PNM_NOTERESET: {
-      m_pEdit->EnableNotify(FALSE);
-      ResetContent(0);
-      m_pEdit->EnableNotify(TRUE);
-
-      for (int32_t i = 1, sz = m_aChildren.GetSize(); i < sz; i++) {
-        if (CPWL_Wnd* pChild = m_aChildren.GetAt(i))
-          pChild->OnNotify(this, PNM_NOTERESET, 0, 0);
-      }
-
-      m_pEdit->EnableNotify(FALSE);
-      ResetContent(0);
-      m_pEdit->EnableNotify(TRUE);
-    }
-      return;
-  }
-
-  CPWL_Wnd::OnNotify(pWnd, msg, wParam, lParam);
-}
-
-FX_BOOL CPWL_Note_Contents::OnLButtonDown(const CPDF_Point& point,
-                                          FX_DWORD nFlag) {
-  if (CPWL_Wnd::OnLButtonDown(point, nFlag))
-    return TRUE;
-
-  if (!m_pEdit->IsFocused()) {
-    m_pEdit->SetFocus();
-  }
-
-  return TRUE;
-}
-
-void CPWL_Note_Contents::SetEditFocus(FX_BOOL bLast) {
-  if (!m_pEdit->IsFocused()) {
-    m_pEdit->SetFocus();
-    m_pEdit->SetCaret(bLast ? m_pEdit->GetTotalWords() : 0);
-  }
-}
-
-CPWL_Edit* CPWL_Note_Contents::GetEdit() const {
-  return m_pEdit;
-}
-
-void CPWL_Note_Contents::EnableModify(FX_BOOL bEnabled) {
-  if (!bEnabled)
-    m_pEdit->AddFlag(PWS_READONLY);
-  else
-    m_pEdit->RemoveFlag(PWS_READONLY);
-
-  for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
-    if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
-      if (pChild->GetClassName() == "CPWL_NoteItem") {
-        CPWL_NoteItem* pNoteItem = (CPWL_NoteItem*)pChild;
-        pNoteItem->EnableModify(bEnabled);
-      }
-    }
-  }
-}
-
-void CPWL_Note_Contents::EnableRead(FX_BOOL bEnabled) {
-  if (!bEnabled)
-    m_pEdit->AddFlag(PES_NOREAD);
-  else
-    m_pEdit->RemoveFlag(PES_NOREAD);
-
-  for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
-    if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
-      if (pChild->GetClassName() == "CPWL_NoteItem") {
-        CPWL_NoteItem* pNoteItem = (CPWL_NoteItem*)pChild;
-        pNoteItem->EnableRead(bEnabled);
-      }
-    }
-  }
-}
-
-CPWL_NoteItem::CPWL_NoteItem()
-    : m_pSubject(NULL),
-      m_pDateTime(NULL),
-      m_pContents(NULL),
-      m_pPrivateData(NULL),
-      m_sAuthor(L""),
-      m_fOldItemHeight(0.0f),
-      m_bSizeChanged(FALSE),
-      m_bAllowModify(TRUE) {}
-
-CPWL_NoteItem::~CPWL_NoteItem() {}
-
-CFX_ByteString CPWL_NoteItem::GetClassName() const {
-  return "CPWL_NoteItem";
-}
-
-void CPWL_NoteItem::CreateChildWnd(const PWL_CREATEPARAM& cp) {
-  CPWL_Color sTextColor;
-
-  if (CPWL_Utils::IsBlackOrWhite(GetBackgroundColor()))
-    sTextColor = PWL_DEFAULT_WHITECOLOR;
-  else
-    sTextColor = PWL_DEFAULT_BLACKCOLOR;
-
-  m_pSubject = new CPWL_Label;
-  PWL_CREATEPARAM scp = cp;
-  scp.pParentWnd = this;
-  scp.dwFlags = PWS_VISIBLE | PWS_CHILD | PES_LEFT | PES_TOP;
-  scp.sTextColor = sTextColor;
-  m_pSubject->Create(scp);
-
-  m_pDateTime = new CPWL_Label;
-  PWL_CREATEPARAM dcp = cp;
-  dcp.pParentWnd = this;
-  dcp.dwFlags = PWS_VISIBLE | PWS_CHILD | PES_RIGHT | PES_TOP;
-  dcp.sTextColor = sTextColor;
-  m_pDateTime->Create(dcp);
-
-  m_pContents = new CPWL_Note_Contents;
-  PWL_CREATEPARAM ccp = cp;
-  ccp.pParentWnd = this;
-  ccp.sBackgroundColor =
-      CPWL_Color(COLORTYPE_RGB, 240 / 255.0f, 240 / 255.0f, 240 / 255.0f);
-  ccp.dwFlags = PWS_VISIBLE | PWS_CHILD | PWS_BACKGROUND;
-  m_pContents->Create(ccp);
-  m_pContents->SetItemSpace(POPUP_ITEM_SPACE);
-  m_pContents->SetTopSpace(POPUP_ITEM_SPACE);
-  m_pContents->SetBottomSpace(POPUP_ITEM_SPACE);
-}
-
-void CPWL_NoteItem::RePosChildWnd() {
-  if (IsValid()) {
-    CPDF_Rect rcClient = GetClientRect();
-
-    CPDF_Rect rcSubject = rcClient;
-    rcSubject.left += POPUP_ITEM_TEXT_INDENT;
-    rcSubject.top = rcClient.top;
-    rcSubject.right =
-        PWL_MIN(rcSubject.left + m_pSubject->GetContentRect().Width() + 1.0f,
-                rcClient.right);
-    rcSubject.bottom = rcSubject.top - m_pSubject->GetContentRect().Height();
-    rcSubject.Normalize();
-    m_pSubject->Move(rcSubject, TRUE, FALSE);
-    m_pSubject->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcSubject));
-
-    CPDF_Rect rcDate = rcClient;
-    rcDate.right -= POPUP_ITEM_TEXT_INDENT;
-    rcDate.left =
-        PWL_MAX(rcDate.right - m_pDateTime->GetContentRect().Width() - 1.0f,
-                rcSubject.right);
-    rcDate.bottom = rcDate.top - m_pDateTime->GetContentRect().Height();
-    rcDate.Normalize();
-    m_pDateTime->Move(rcDate, TRUE, FALSE);
-    m_pDateTime->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcDate));
-
-    CPDF_Rect rcContents = rcClient;
-    rcContents.left += 1.0f;
-    rcContents.right -= 1.0f;
-    rcContents.top = rcDate.bottom - POPUP_ITEM_HEAD_BOTTOM;
-    rcContents.bottom += POPUP_ITEM_BOTTOMWIDTH;
-    rcContents.Normalize();
-    m_pContents->Move(rcContents, TRUE, FALSE);
-    m_pContents->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcContents));
-  }
-
-  SetClipRect(CPWL_Utils::InflateRect(GetWindowRect(), 1.0f));
-}
-
-void CPWL_NoteItem::SetPrivateData(void* pData) {
-  m_pPrivateData = pData;
-}
-
-void CPWL_NoteItem::SetBkColor(const CPWL_Color& color) {
-  CPWL_Color sBK = color;
-  SetBackgroundColor(sBK);
-
-  CPWL_Color sTextColor;
-
-  if (CPWL_Utils::IsBlackOrWhite(sBK))
-    sTextColor = PWL_DEFAULT_WHITECOLOR;
-  else
-    sTextColor = PWL_DEFAULT_BLACKCOLOR;
-
-  SetTextColor(sTextColor);
-  if (m_pSubject)
-    m_pSubject->SetTextColor(sTextColor);
-  if (m_pDateTime)
-    m_pDateTime->SetTextColor(sTextColor);
-
-  InvalidateRect(nullptr);
-
-  if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
-    pNotify->OnSetBkColor(this);
-  }
-}
-
-void CPWL_NoteItem::SetSubjectName(const CFX_WideString& sName) {
-  if (m_pSubject) {
-    m_pSubject->SetText(sName.c_str());
-  }
-
-  if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
-    pNotify->OnSetSubjectName(this);
-  }
-}
-
-void CPWL_NoteItem::SetAuthorName(const CFX_WideString& sName) {
-  m_sAuthor = sName;
-  ResetSubjectName(-1);
-
-  if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
-    pNotify->OnSetAuthorName(this);
-  }
-}
-
-void CPWL_NoteItem::ResetSubjectName(int32_t nItemIndex) {
-  if (nItemIndex < 0) {
-    if (CPWL_Wnd* pParent = GetParentWindow()) {
-      ASSERT(pParent->GetClassName() == "CPWL_Note_Contents");
-
-      CPWL_Note_Contents* pContents = (CPWL_Note_Contents*)pParent;
-      nItemIndex = pContents->GetItemIndex(this);
-    }
-  }
-
-  const CPWL_Note* pNote = GetNote();
-  CFX_WideString sSubject;
-  sSubject.Format(pNote->GetReplyString().c_str(), nItemIndex);
-
-  if (!m_sAuthor.IsEmpty()) {
-    sSubject += L" - ";
-    sSubject += m_sAuthor;
-  }
-  SetSubjectName(sSubject);
-  RePosChildWnd();
-}
-
-void CPWL_NoteItem::SetDateTime(FX_SYSTEMTIME time) {
-  m_dtNote = time;
-
-  CFX_WideString swTime;
-  swTime.Format(L"%04d-%02d-%02d %02d:%02d:%02d", time.wYear, time.wMonth,
-                time.wDay, time.wHour, time.wMinute, time.wSecond);
-  if (m_pDateTime) {
-    m_pDateTime->SetText(swTime.c_str());
-  }
-
-  RePosChildWnd();
-
-  if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
-    pNotify->OnSetDateTime(this);
-  }
-}
-
-void CPWL_NoteItem::SetContents(const CFX_WideString& sContents) {
-  if (m_pContents) {
-    m_pContents->SetText(sContents);
-  }
-
-  if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
-    pNotify->OnSetContents(this);
-  }
-}
-
-CPWL_NoteItem* CPWL_NoteItem::GetParentNoteItem() const {
-  if (CPWL_Wnd* pParent = GetParentWindow()) {
-    if (CPWL_Wnd* pGrand = pParent->GetParentWindow()) {
-      ASSERT(pGrand->GetClassName() == "CPWL_NoteItem");
-      return (CPWL_NoteItem*)pGrand;
-    }
-  }
-
-  return NULL;
-}
-
-IPWL_NoteItem* CPWL_NoteItem::GetParentItem() const {
-  return GetParentNoteItem();
-}
-
-CPWL_Edit* CPWL_NoteItem::GetEdit() const {
-  if (m_pContents)
-    return m_pContents->GetEdit();
-  return NULL;
-}
-
-void* CPWL_NoteItem::GetPrivateData() const {
-  return m_pPrivateData;
-}
-
-CFX_WideString CPWL_NoteItem::GetAuthorName() const {
-  return m_sAuthor;
-}
-
-CPWL_Color CPWL_NoteItem::GetBkColor() const {
-  return GetBackgroundColor();
-}
-
-CFX_WideString CPWL_NoteItem::GetContents() const {
-  if (m_pContents)
-    return m_pContents->GetText();
-
-  return L"";
-}
-
-FX_SYSTEMTIME CPWL_NoteItem::GetDateTime() const {
-  return m_dtNote;
-}
-
-CFX_WideString CPWL_NoteItem::GetSubjectName() const {
-  if (m_pSubject)
-    return m_pSubject->GetText();
-
-  return L"";
-}
-
-CPWL_NoteItem* CPWL_NoteItem::CreateNoteItem() {
-  if (m_pContents)
-    return m_pContents->CreateSubItem();
-
-  return NULL;
-}
-
-IPWL_NoteItem* CPWL_NoteItem::CreateSubItem() {
-  return CreateNoteItem();
-}
-
-int32_t CPWL_NoteItem::CountSubItems() const {
-  if (m_pContents)
-    return m_pContents->CountSubItems();
-
-  return 0;
-}
-
-IPWL_NoteItem* CPWL_NoteItem::GetSubItems(int32_t index) const {
-  if (m_pContents)
-    return m_pContents->GetSubItems(index);
-
-  return NULL;
-}
-
-void CPWL_NoteItem::DeleteSubItem(IPWL_NoteItem* pNoteItem) {
-  KillFocus();
-
-  if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
-    pNotify->OnItemDelete(pNoteItem);
-  }
-
-  if (m_pContents)
-    m_pContents->DeleteSubItem(pNoteItem);
-}
-
-IPWL_NoteItem* CPWL_NoteItem::GetHitNoteItem(const CPDF_Point& point) {
-  CPDF_Point pt = ParentToChild(point);
-
-  if (WndHitTest(pt)) {
-    if (m_pContents) {
-      if (IPWL_NoteItem* pNoteItem = m_pContents->GetHitNoteItem(pt))
-        return pNoteItem;
-    }
-
-    return this;
-  }
-
-  return NULL;
-}
-
-IPWL_NoteItem* CPWL_NoteItem::GetFocusedNoteItem() const {
-  if (const CPWL_Wnd* pWnd = GetFocused()) {
-    if (pWnd->GetClassName() == "CPWL_Edit") {
-      if (CPWL_Wnd* pParent = pWnd->GetParentWindow()) {
-        ASSERT(pParent->GetClassName() == "CPWL_Note_Contents");
-
-        if (CPWL_Wnd* pGrand = pParent->GetParentWindow()) {
-          ASSERT(pGrand->GetClassName() == "CPWL_NoteItem");
-          return (CPWL_NoteItem*)pGrand;
-        }
-      }
-    }
-  }
-
-  return NULL;
-}
-
-FX_FLOAT CPWL_NoteItem::GetItemHeight(FX_FLOAT fLimitWidth) {
-  if (fLimitWidth > 0) {
-    if (!m_bSizeChanged)
-      return m_fOldItemHeight;
-
-    m_bSizeChanged = FALSE;
-
-    FX_FLOAT fRet = m_pDateTime->GetContentRect().Height();
-    FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
-    if (fLimitWidth > fBorderWidth * 2)
-      fRet += m_pContents->GetContentsHeight(fLimitWidth - fBorderWidth * 2);
-    fRet += POPUP_ITEM_HEAD_BOTTOM + POPUP_ITEM_BOTTOMWIDTH + fBorderWidth * 2;
-
-    return m_fOldItemHeight = fRet;
-  }
-
-  return 0;
-}
-
-FX_FLOAT CPWL_NoteItem::GetItemLeftMargin() {
-  return POPUP_ITEM_SIDEMARGIN;
-}
-
-FX_FLOAT CPWL_NoteItem::GetItemRightMargin() {
-  return POPUP_ITEM_SIDEMARGIN;
-}
-
-FX_BOOL CPWL_NoteItem::OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) {
-  if (!m_pContents->WndHitTest(m_pContents->ParentToChild(point))) {
-    SetNoteFocus(FALSE);
-  }
-
-  CPWL_Wnd::OnLButtonDown(point, nFlag);
-
-  return TRUE;
-}
-
-FX_BOOL CPWL_NoteItem::OnRButtonUp(const CPDF_Point& point, FX_DWORD nFlag) {
-  if (!m_pContents->WndHitTest(m_pContents->ParentToChild(point))) {
-    SetNoteFocus(FALSE);
-    PopupNoteItemMenu(point);
-
-    return TRUE;
-  }
-
-  return CPWL_Wnd::OnRButtonUp(point, nFlag);
-}
-
-void CPWL_NoteItem::OnNotify(CPWL_Wnd* pWnd,
-                             FX_DWORD msg,
-                             intptr_t wParam,
-                             intptr_t lParam) {
-  switch (msg) {
-    case PNM_NOTEEDITCHANGED:
-      m_bSizeChanged = TRUE;
-
-      if (CPWL_Wnd* pParent = GetParentWindow()) {
-        pParent->OnNotify(this, PNM_NOTEEDITCHANGED, 0, 0);
-      }
-      return;
-    case PNM_SETCARETINFO:
-      if (PWL_CARET_INFO* pInfo = (PWL_CARET_INFO*)wParam) {
-        PWL_CARET_INFO newInfo = *pInfo;
-        newInfo.bVisible = TRUE;
-        newInfo.ptHead = ChildToParent(pInfo->ptHead);
-        newInfo.ptFoot = ChildToParent(pInfo->ptFoot);
-
-        if (CPWL_Wnd* pParent = GetParentWindow()) {
-          pParent->OnNotify(this, PNM_SETCARETINFO, (intptr_t)&newInfo, 0);
-        }
-      }
-      return;
-    case PNM_NOTERESET:
-      m_bSizeChanged = TRUE;
-      m_pContents->OnNotify(this, PNM_NOTERESET, 0, 0);
-
-      return;
-  }
-
-  CPWL_Wnd::OnNotify(pWnd, msg, wParam, lParam);
-}
-
-void CPWL_NoteItem::PopupNoteItemMenu(const CPDF_Point& point) {
-  if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
-    int32_t x, y;
-    PWLtoWnd(point, x, y);
-    if (IFX_SystemHandler* pSH = GetSystemHandler())
-      pSH->ClientToScreen(GetAttachedHWnd(), x, y);
-    pNotify->OnPopupMenu(this, x, y);
-  }
-}
-
-const CPWL_Note* CPWL_NoteItem::GetNote() const {
-  if (const CPWL_Wnd* pRoot = GetRootWnd()) {
-    ASSERT(pRoot->GetClassName() == "CPWL_NoteItem");
-    CPWL_NoteItem* pNoteItem = (CPWL_NoteItem*)pRoot;
-    if (pNoteItem->IsTopItem()) {
-      return (CPWL_Note*)pNoteItem;
-    }
-  }
-
-  return NULL;
-}
-
-IPWL_NoteNotify* CPWL_NoteItem::GetNoteNotify() const {
-  if (const CPWL_Note* pNote = GetNote())
-    return pNote->GetNoteNotify();
-
-  return NULL;
-}
-
-void CPWL_NoteItem::OnCreateNoteItem() {
-  if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
-    pNotify->OnItemCreate(this);
-  }
-}
-
-void CPWL_NoteItem::OnContentsValidate() {
-  if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
-    pNotify->OnSetContents(this);
-  }
-}
-
-void CPWL_NoteItem::SetNoteFocus(FX_BOOL bLast) {
-  m_pContents->SetEditFocus(bLast);
-}
-
-void CPWL_NoteItem::EnableModify(FX_BOOL bEnabled) {
-  m_pContents->EnableModify(bEnabled);
-  m_bAllowModify = bEnabled;
-}
-
-void CPWL_NoteItem::EnableRead(FX_BOOL bEnabled) {
-  m_pContents->EnableRead(bEnabled);
-}
-
-CPWL_Note::CPWL_Note(IPopup_Note* pPopupNote,
-                     IPWL_NoteNotify* pNoteNotify,
-                     IPWL_NoteHandler* pNoteHandler)
-    : m_pAuthor(NULL),
-      m_pIcon(NULL),
-      m_pCloseBox(NULL),
-      m_pLBBox(NULL),
-      m_pRBBox(NULL),
-      m_pContentsBar(NULL),
-      m_pOptions(NULL),
-      m_pNoteNotify(pNoteNotify),
-      m_bResizing(FALSE),
-      m_bEnableNotify(TRUE) {}
-
-CPWL_Note::~CPWL_Note() {}
-
-IPWL_NoteItem* CPWL_Note::Reply() {
-  return CreateNoteItem();
-}
-
-void CPWL_Note::EnableNotify(FX_BOOL bEnabled) {
-  m_bEnableNotify = bEnabled;
-}
-
-void CPWL_Note::RePosChildWnd() {
-  RePosNoteChildren();
-  m_pContents->OnNotify(this, PNM_NOTERESET, 0, 0);
-  ResetScrollBar();
-  m_pContents->OnNotify(this, PNM_NOTERESET, 0, 0);
-  OnNotify(this, PNM_NOTEEDITCHANGED, 0, 0);
-  if (const CPWL_Wnd* pWnd = GetFocused()) {
-    if (pWnd->GetClassName() == "CPWL_Edit") {
-      CPWL_Edit* pEdit = (CPWL_Edit*)pWnd;
-      pEdit->SetCaret(pEdit->GetCaret());
-    }
-  }
-}
-
-FX_BOOL CPWL_Note::ResetScrollBar() {
-  FX_BOOL bScrollChanged = FALSE;
-
-  if (ScrollBarShouldVisible()) {
-    if (!m_pContentsBar->IsVisible()) {
-      m_pContentsBar->SetVisible(TRUE);
-      if (m_pContentsBar->IsVisible()) {
-        m_pContentsBar->InvalidateRect(NULL);
-        bScrollChanged = TRUE;
-      }
-    }
-  } else {
-    if (m_pContentsBar->IsVisible()) {
-      m_pContentsBar->SetVisible(FALSE);
-      m_pContentsBar->InvalidateRect(NULL);
-
-      bScrollChanged = TRUE;
-    }
-  }
-
-  if (bScrollChanged) {
-    CPDF_Rect rcNote = GetClientRect();
-    CPDF_Rect rcContents = m_pContents->GetWindowRect();
-    rcContents.right = rcNote.right - 3.0f;
-    if (m_pContentsBar->IsVisible())
-      rcContents.right -= PWL_SCROLLBAR_WIDTH;
-    m_pContents->Move(rcContents, TRUE, TRUE);
-    m_pContents->SetScrollPos(CPDF_Point(0.0f, 0.0f));
-    m_pContents->InvalidateRect(NULL);
-  }
-
-  return bScrollChanged;
-}
-
-FX_BOOL CPWL_Note::ScrollBarShouldVisible() {
-  CPDF_Rect rcContentsFact = m_pContents->GetScrollArea();
-  CPDF_Rect rcContentsClient = m_pContents->GetClientRect();
-
-  return rcContentsFact.Height() > rcContentsClient.Height();
-}
-
-void CPWL_Note::SetOptionsText(const CFX_WideString& sText) {
-  if (m_pOptions)
-    m_pOptions->SetText(sText);
-
-  RePosNoteChildren();
-}
-
-void CPWL_Note::RePosNoteChildren() {
-  if (m_bResizing)
-    return;
-
-  m_bResizing = TRUE;
-
-  if (IsValid()) {
-    CPDF_Rect rcClient = GetClientRect();
-
-    CPDF_Rect rcIcon = rcClient;
-    rcIcon.top -= 2.0f;
-    rcIcon.right = rcIcon.left + 14.0f;
-    rcIcon.bottom = rcIcon.top - 14.0f;
-    rcIcon.Normalize();
-    m_pIcon->Move(rcIcon, TRUE, FALSE);
-    m_pIcon->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcIcon));
-
-    CPDF_Rect rcCloseBox = rcClient;
-    rcCloseBox.right -= 1.0f;
-    rcCloseBox.top -= 1.0f;
-    rcCloseBox.left = rcCloseBox.right - 14.0f;
-    rcCloseBox.bottom = rcCloseBox.top - 14.0f;
-    rcCloseBox.Normalize();
-    m_pCloseBox->Move(rcCloseBox, TRUE, FALSE);
-    m_pCloseBox->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcCloseBox));
-
-    CPDF_Rect rcDate = rcClient;
-    rcDate.right = rcCloseBox.left - POPUP_ITEM_TEXT_INDENT;
-    rcDate.left =
-        PWL_MAX(rcDate.right - m_pDateTime->GetContentRect().Width() - 1.0f,
-                rcIcon.right + 1.0f);
-    rcDate.top = rcClient.top - 2.0f;
-    rcDate.bottom = rcDate.top - m_pDateTime->GetContentRect().Height();
-    rcDate.Normalize();
-    m_pDateTime->Move(rcDate, TRUE, FALSE);
-    m_pDateTime->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcDate));
-
-    CPDF_Rect rcSubject = rcClient;
-    rcSubject.top = rcClient.top - 2.0f;
-    rcSubject.left = rcIcon.right + POPUP_ITEM_TEXT_INDENT;
-    rcSubject.right =
-        PWL_MIN(rcSubject.left + m_pSubject->GetContentRect().Width() + 1.0f,
-                rcDate.left - 1.0f);
-    rcSubject.bottom = rcSubject.top - m_pSubject->GetContentRect().Height();
-    rcSubject.Normalize();
-    m_pSubject->Move(rcSubject, TRUE, FALSE);
-    m_pSubject->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcSubject));
-
-    CPDF_Rect rcOptions = rcClient;
-    rcOptions.left =
-        PWL_MAX(rcOptions.right - m_pOptions->GetContentRect().Width(),
-                rcIcon.right + 1.0f);
-    rcOptions.top = rcSubject.bottom - 4.0f;
-    rcOptions.bottom = rcOptions.top - m_pOptions->GetContentRect().Height();
-    rcOptions.Normalize();
-    m_pOptions->Move(rcOptions, TRUE, FALSE);
-    m_pOptions->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcOptions));
-
-    CPDF_Rect rcAuthor = rcClient;
-    rcAuthor.top = rcSubject.bottom - 4.0f;
-    rcAuthor.left = rcSubject.left;
-    rcAuthor.right =
-        PWL_MIN(rcSubject.left + m_pAuthor->GetContentRect().Width() + 1.0f,
-                rcOptions.left - 1.0f);
-    rcAuthor.bottom = rcAuthor.top - m_pAuthor->GetContentRect().Height();
-    rcAuthor.Normalize();
-    m_pAuthor->Move(rcAuthor, TRUE, FALSE);
-    m_pAuthor->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcAuthor));
-
-    CPDF_Rect rcLBBox = rcClient;
-    rcLBBox.top = rcLBBox.bottom + 7.0f;
-    rcLBBox.right = rcLBBox.left + 7.0f;
-    rcLBBox.Normalize();
-    m_pLBBox->Move(rcLBBox, TRUE, FALSE);
-    m_pLBBox->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcLBBox));
-
-    CPDF_Rect rcRBBox = rcClient;
-    rcRBBox.top = rcRBBox.bottom + 7.0f;
-    rcRBBox.left = rcRBBox.right - 7.0f;
-    rcRBBox.Normalize();
-    m_pRBBox->Move(rcRBBox, TRUE, FALSE);
-    m_pRBBox->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcRBBox));
-
-    CPDF_Rect rcContents = rcClient;
-    rcContents.top = rcAuthor.bottom - POPUP_ITEM_HEAD_BOTTOM;
-    rcContents.left += 3.0f;
-    rcContents.right -= 3.0f;
-    if (m_pContentsBar->IsVisible())
-      rcContents.right -= PWL_SCROLLBAR_WIDTH;
-    rcContents.bottom += 14.0f;
-    rcContents.Normalize();
-    m_pContents->Move(rcContents, FALSE, FALSE);
-    m_pContents->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcContents));
-
-    CPDF_Rect rcContentsBar = rcContents;
-    rcContentsBar.right = rcClient.right - 3.0f;
-    rcContentsBar.left = rcContentsBar.right - PWL_SCROLLBAR_WIDTH;
-    rcContentsBar.Normalize();
-    m_pContentsBar->Move(rcContentsBar, TRUE, FALSE);
-  }
-
-  m_bResizing = FALSE;
-}
-
-void CPWL_Note::CreateChildWnd(const PWL_CREATEPARAM& cp) {
-  CPWL_NoteItem::CreateChildWnd(cp);
-
-  CPWL_Color sTextColor;
-
-  if (CPWL_Utils::IsBlackOrWhite(GetBackgroundColor()))
-    sTextColor = PWL_DEFAULT_WHITECOLOR;
-  else
-    sTextColor = PWL_DEFAULT_BLACKCOLOR;
-
-  m_pAuthor = new CPWL_Label;
-  PWL_CREATEPARAM acp = cp;
-  acp.pParentWnd = this;
-  acp.dwFlags = PWS_VISIBLE | PWS_CHILD | PES_LEFT | PES_TOP;
-  acp.sTextColor = sTextColor;
-  m_pAuthor->Create(acp);
-
-  m_pCloseBox = new CPWL_Note_CloseBox;
-  PWL_CREATEPARAM ccp = cp;
-  ccp.pParentWnd = this;
-  ccp.dwBorderWidth = 2;
-  ccp.nBorderStyle = PBS_BEVELED;
-  ccp.dwFlags = PWS_VISIBLE | PWS_CHILD | PWS_BORDER;
-  ccp.sTextColor = sTextColor;
-  m_pCloseBox->Create(ccp);
-
-  m_pIcon = new CPWL_Note_Icon;
-  PWL_CREATEPARAM icp = cp;
-  icp.pParentWnd = this;
-  icp.dwFlags = PWS_VISIBLE | PWS_CHILD;
-  m_pIcon->Create(icp);
-
-  m_pOptions = new CPWL_Note_Options;
-  PWL_CREATEPARAM ocp = cp;
-  ocp.pParentWnd = this;
-  ocp.dwFlags = PWS_CHILD | PWS_VISIBLE;
-  ocp.sTextColor = sTextColor;
-  m_pOptions->Create(ocp);
-
-  m_pLBBox = new CPWL_Note_LBBox;
-  PWL_CREATEPARAM lcp = cp;
-  lcp.pParentWnd = this;
-  lcp.dwFlags = PWS_VISIBLE | PWS_CHILD;
-  lcp.eCursorType = FXCT_NESW;
-  lcp.sTextColor = sTextColor;
-  m_pLBBox->Create(lcp);
-
-  m_pRBBox = new CPWL_Note_RBBox;
-  PWL_CREATEPARAM rcp = cp;
-  rcp.pParentWnd = this;
-  rcp.dwFlags = PWS_VISIBLE | PWS_CHILD;
-  rcp.eCursorType = FXCT_NWSE;
-  rcp.sTextColor = sTextColor;
-  m_pRBBox->Create(rcp);
-
-  m_pContentsBar = new CPWL_ScrollBar(SBT_VSCROLL);
-  PWL_CREATEPARAM scp = cp;
-  scp.pParentWnd = this;
-  scp.sBackgroundColor =
-      CPWL_Color(COLORTYPE_RGB, 240 / 255.0f, 240 / 255.0f, 240 / 255.0f);
-  scp.dwFlags = PWS_CHILD | PWS_VISIBLE | PWS_BACKGROUND;
-  m_pContentsBar->Create(scp);
-  m_pContentsBar->SetNotifyForever(TRUE);
-}
-
-void CPWL_Note::SetSubjectName(const CFX_WideString& sName) {
-  CPWL_NoteItem::SetSubjectName(sName);
-  RePosChildWnd();
-}
-
-void CPWL_Note::SetAuthorName(const CFX_WideString& sName) {
-  if (m_pAuthor) {
-    m_pAuthor->SetText(sName.c_str());
-    RePosChildWnd();
-  }
-
-  if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
-    pNotify->OnSetAuthorName(this);
-  }
-}
-
-CFX_WideString CPWL_Note::GetAuthorName() const {
-  if (m_pAuthor)
-    return m_pAuthor->GetText();
-
-  return L"";
-}
-
-FX_BOOL CPWL_Note::OnMouseWheel(short zDelta,
-                                const CPDF_Point& point,
-                                FX_DWORD nFlag) {
-  CPDF_Point ptScroll = m_pContents->GetScrollPos();
-  CPDF_Rect rcScroll = m_pContents->GetScrollArea();
-  CPDF_Rect rcContents = m_pContents->GetClientRect();
-
-  if (rcScroll.top - rcScroll.bottom > rcContents.Height()) {
-    CPDF_Point ptNew = ptScroll;
-
-    if (zDelta > 0)
-      ptNew.y += 30;
-    else
-      ptNew.y -= 30;
-
-    if (ptNew.y > rcScroll.top)
-      ptNew.y = rcScroll.top;
-    if (ptNew.y < rcScroll.bottom + rcContents.Height())
-      ptNew.y = rcScroll.bottom + rcContents.Height();
-    if (ptNew.y < rcScroll.bottom)
-      ptNew.y = rcScroll.bottom;
-
-    if (ptNew.y != ptScroll.y) {
-      m_pContents->OnNotify(this, PNM_NOTERESET, 0, 0);
-      m_pContents->OnNotify(this, PNM_SCROLLWINDOW, SBT_VSCROLL,
-                            (intptr_t)&ptNew.y);
-      m_pContentsBar->OnNotify(this, PNM_SETSCROLLPOS, SBT_VSCROLL,
-                               (intptr_t)&ptNew.y);
-
-      return TRUE;
-    }
-  }
-
-  return FALSE;
-}
-
-void CPWL_Note::OnNotify(CPWL_Wnd* pWnd,
-                         FX_DWORD msg,
-                         intptr_t wParam,
-                         intptr_t lParam) {
-  switch (msg) {
-    case PNM_NOTEEDITCHANGED: {
-      CPDF_Rect rcScroll = m_pContents->GetScrollArea();
-
-      PWL_SCROLL_INFO sInfo;
-      sInfo.fContentMin = rcScroll.bottom;
-      sInfo.fContentMax = rcScroll.top;
-      sInfo.fPlateWidth = m_pContents->GetClientRect().Height();
-      sInfo.fSmallStep = 13.0f;
-      sInfo.fBigStep = sInfo.fPlateWidth;
-
-      if (FXSYS_memcmp(&m_OldScrollInfo, &sInfo, sizeof(PWL_SCROLL_INFO)) !=
-          0) {
-        FX_BOOL bScrollChanged = FALSE;
-
-        if (lParam < 3) {
-          bScrollChanged = ResetScrollBar();
-          if (bScrollChanged) {
-            lParam++;
-            m_pContents->OnNotify(this, PNM_NOTERESET, 0, 0);
-            OnNotify(this, PNM_NOTEEDITCHANGED, 0, lParam);
-          }
-        }
-
-        if (!bScrollChanged) {
-          if (m_pContentsBar->IsVisible()) {
-            m_pContentsBar->OnNotify(pWnd, PNM_SETSCROLLINFO, SBT_VSCROLL,
-                                     (intptr_t)&sInfo);
-            m_OldScrollInfo = sInfo;
-
-            CPDF_Point ptScroll = m_pContents->GetScrollPos();
-            CPDF_Point ptOld = ptScroll;
-
-            if (ptScroll.y > sInfo.fContentMax)
-              ptScroll.y = sInfo.fContentMax;
-            if (ptScroll.y < sInfo.fContentMin + sInfo.fPlateWidth)
-              ptScroll.y = sInfo.fContentMin + sInfo.fPlateWidth;
-            if (ptScroll.y < sInfo.fContentMin)
-              ptScroll.y = sInfo.fContentMin;
-
-            if (ptOld.y != ptScroll.y) {
-              m_pContentsBar->OnNotify(this, PNM_SETSCROLLPOS, SBT_VSCROLL,
-                                       (intptr_t)&ptScroll.y);
-              m_pContentsBar->InvalidateRect(NULL);
-              m_pContents->OnNotify(this, PNM_SCROLLWINDOW, SBT_VSCROLL,
-                                    (intptr_t)&ptScroll.y);
-            }
-          }
-        }
-      }
-    }
-
-      m_pContents->InvalidateRect(NULL);
-
-      return;
-    case PNM_SCROLLWINDOW:
-      if (m_pContents)
-        m_pContents->OnNotify(pWnd, msg, wParam, lParam);
-      return;
-    case PNM_SETSCROLLPOS:
-      if (m_pContentsBar)
-        m_pContentsBar->OnNotify(pWnd, PNM_SETSCROLLPOS, wParam, lParam);
-      return;
-  }
-
-  if (msg == PNM_SETCARETINFO && IsValid()) {
-    if (PWL_CARET_INFO* pInfo = (PWL_CARET_INFO*)wParam) {
-      if (m_pContents) {
-        CPDF_Rect rcClient = m_pContents->GetClientRect();
-        if (pInfo->ptHead.y > rcClient.top) {
-          CPDF_Point pt = m_pContents->OutToIn(pInfo->ptHead);
-          m_pContents->OnNotify(this, PNM_SCROLLWINDOW, SBT_VSCROLL,
-                                (intptr_t)&pt.y);
-
-          CPDF_Point ptScroll = m_pContents->GetScrollPos();
-          m_pContentsBar->OnNotify(this, PNM_SETSCROLLPOS, SBT_VSCROLL,
-                                   (intptr_t)&ptScroll.y);
-
-          return;
-        }
-
-        if (pInfo->ptFoot.y < rcClient.bottom) {
-          CPDF_Point pt = m_pContents->OutToIn(pInfo->ptFoot);
-          pt.y += rcClient.Height();
-          m_pContents->OnNotify(this, PNM_SCROLLWINDOW, SBT_VSCROLL,
-                                (intptr_t)&pt.y);
-
-          CPDF_Point ptScroll = m_pContents->GetScrollPos();
-          m_pContentsBar->OnNotify(this, PNM_SETSCROLLPOS, SBT_VSCROLL,
-                                   (intptr_t)&ptScroll.y);
-
-          return;
-        }
-      }
-    }
-  }
-
-  CPWL_NoteItem::OnNotify(pWnd, msg, wParam, lParam);
-}
-
-void CPWL_Note::SetBkColor(const CPWL_Color& color) {
-  CPWL_NoteItem::SetBkColor(color);
-
-  CPWL_Color sBK = color;
-  CPWL_Color sTextColor;
-  if (CPWL_Utils::IsBlackOrWhite(sBK))
-    sTextColor = PWL_DEFAULT_WHITECOLOR;
-  else
-    sTextColor = PWL_DEFAULT_BLACKCOLOR;
-
-  if (m_pCloseBox)
-    m_pCloseBox->SetTextColor(sTextColor);
-  if (m_pAuthor)
-    m_pAuthor->SetTextColor(sTextColor);
-  if (m_pOptions)
-    m_pOptions->SetTextColor(sTextColor);
-  if (m_pLBBox)
-    m_pLBBox->SetTextColor(sTextColor);
-  if (m_pRBBox)
-    m_pRBBox->SetTextColor(sTextColor);
-}
-
-FX_BOOL CPWL_Note::OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) {
-  if (m_pOptions->WndHitTest(m_pOptions->ParentToChild(point))) {
-    if (IPWL_NoteNotify* pNotify = GetNoteNotify()) {
-      int32_t x, y;
-      PWLtoWnd(point, x, y);
-      if (IFX_SystemHandler* pSH = GetSystemHandler())
-        pSH->ClientToScreen(GetAttachedHWnd(), x, y);
-      KillFocus();
-      pNotify->OnPopupMenu(x, y);
-
-      return TRUE;
-    }
-  }
-
-  return CPWL_Wnd::OnLButtonDown(point, nFlag);
-}
-
-FX_BOOL CPWL_Note::OnRButtonUp(const CPDF_Point& point, FX_DWORD nFlag) {
-  return CPWL_Wnd::OnRButtonUp(point, nFlag);
-}
-
-const CPWL_Note* CPWL_Note::GetNote() const {
-  return this;
-}
-
-IPWL_NoteNotify* CPWL_Note::GetNoteNotify() const {
-  return m_bEnableNotify ? m_pNoteNotify : nullptr;
-}
-
-void CPWL_Note::SetIconType(int32_t nType) {
-  if (m_pIcon)
-    m_pIcon->SetIconType(nType);
-}
-
-void CPWL_Note::EnableModify(FX_BOOL bEnabled) {
-  m_pContents->EnableModify(bEnabled);
-}
-
-void CPWL_Note::EnableRead(FX_BOOL bEnabled) {
-  m_pContents->EnableRead(bEnabled);
-}
-
-CFX_WideString CPWL_Note::GetReplyString() const {
-  return m_sReplyString;
-}
-
-void CPWL_Note::SetReplyString(const CFX_WideString& string) {
-  m_sReplyString = string;
-}
diff --git a/fpdfsdk/src/pdfwindow/PWL_Signature.cpp b/fpdfsdk/src/pdfwindow/PWL_Signature.cpp
deleted file mode 100644
index f7c73d0..0000000
--- a/fpdfsdk/src/pdfwindow/PWL_Signature.cpp
+++ /dev/null
@@ -1,176 +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
-
-#include "fpdfsdk/include/pdfwindow/PWL_Icon.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Label.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Signature.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Wnd.h"
-
-CPWL_Signature_Image::CPWL_Signature_Image() : m_pImage(NULL) {}
-
-CPWL_Signature_Image::~CPWL_Signature_Image() {}
-
-void CPWL_Signature_Image::SetImage(CFX_DIBSource* pImage) {
-  m_pImage = pImage;
-}
-
-CFX_DIBSource* CPWL_Signature_Image::GetImage() {
-  return m_pImage;
-}
-
-void CPWL_Signature_Image::DrawThisAppearance(CFX_RenderDevice* pDevice,
-                                              CFX_Matrix* pUser2Device) {
-  CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device);
-
-  if (m_pImage) {
-    CPDF_Rect rcClient = GetClientRect();
-
-    FX_FLOAT x, y;
-    pUser2Device->Transform(rcClient.left, rcClient.top, x, y);
-
-    pDevice->StretchDIBits(m_pImage, (int32_t)x, (int32_t)y,
-                           (int32_t)rcClient.Width(),
-                           (int32_t)rcClient.Height());
-  }
-}
-
-void CPWL_Signature_Image::GetThisAppearanceStream(
-    CFX_ByteTextBuf& sAppStream) {
-  sAppStream << CPWL_Image::GetImageAppStream();
-}
-
-void CPWL_Signature_Image::GetScale(FX_FLOAT& fHScale, FX_FLOAT& fVScale) {
-  FX_FLOAT fImageW, fImageH;
-
-  GetImageSize(fImageW, fImageH);
-
-  CPDF_Rect rcClient = GetClientRect();
-
-  fHScale = rcClient.Width() / fImageW;
-  fVScale = rcClient.Height() / fImageH;
-}
-
-CPWL_Signature::CPWL_Signature()
-    : m_pText(NULL),
-      m_pDescription(NULL),
-      m_pImage(NULL),
-      m_bTextExist(TRUE),
-      m_bImageExist(FALSE),
-      m_bFlagExist(TRUE) {}
-
-CPWL_Signature::~CPWL_Signature() {}
-
-void CPWL_Signature::SetTextFlag(FX_BOOL bTextExist) {
-  m_bTextExist = bTextExist;
-
-  RePosChildWnd();
-}
-
-void CPWL_Signature::SetImageFlag(FX_BOOL bImageExist) {
-  m_bImageExist = bImageExist;
-
-  RePosChildWnd();
-}
-
-void CPWL_Signature::SetFoxitFlag(FX_BOOL bFlagExist) {
-  m_bFlagExist = bFlagExist;
-}
-
-void CPWL_Signature::SetText(const FX_WCHAR* sText) {
-  m_pText->SetText(sText);
-
-  RePosChildWnd();
-}
-
-void CPWL_Signature::SetDescription(const FX_WCHAR* string) {
-  m_pDescription->SetText(string);
-
-  RePosChildWnd();
-}
-
-void CPWL_Signature::SetImage(CFX_DIBSource* pImage) {
-  m_pImage->SetImage(pImage);
-
-  RePosChildWnd();
-}
-
-void CPWL_Signature::SetImageStream(CPDF_Stream* pStream,
-                                    const FX_CHAR* sImageAlias) {
-  m_pImage->SetPDFStream(pStream);
-  m_pImage->SetImageAlias(sImageAlias);
-
-  RePosChildWnd();
-}
-
-void CPWL_Signature::RePosChildWnd() {
-  CPDF_Rect rcClient = GetClientRect();
-
-  CPDF_Rect rcText = rcClient;
-  CPDF_Rect rcDescription = rcClient;
-
-  FX_BOOL bTextVisible = m_bTextExist && m_pText->GetText().GetLength() > 0;
-
-  if ((bTextVisible || m_bImageExist) &&
-      m_pDescription->GetText().GetLength() > 0) {
-    if (rcClient.Width() >= rcClient.Height()) {
-      rcText.right = rcText.left + rcClient.Width() / 2.0f;
-      rcDescription.left = rcDescription.right - rcClient.Width() / 2.0f;
-    } else {
-      rcText.bottom = rcText.top - rcClient.Height() / 2.0f;
-      rcDescription.top = rcDescription.bottom + rcClient.Height() / 2.0f;
-    }
-  }
-
-  m_pText->SetVisible(bTextVisible);
-  m_pImage->SetVisible(m_bImageExist);
-
-  m_pText->Move(rcText, TRUE, FALSE);
-  m_pImage->Move(rcText, TRUE, FALSE);
-  m_pDescription->Move(rcDescription, TRUE, FALSE);
-}
-
-void CPWL_Signature::CreateChildWnd(const PWL_CREATEPARAM& cp) {
-  m_pImage = new CPWL_Signature_Image;
-  PWL_CREATEPARAM icp = cp;
-  icp.pParentWnd = this;
-  icp.dwFlags = PWS_CHILD | PWS_VISIBLE;
-  icp.sTextColor = CPWL_Color(COLORTYPE_GRAY, 0);
-  m_pImage->Create(icp);
-
-  m_pText = new CPWL_Label;
-  PWL_CREATEPARAM acp = cp;
-  acp.pParentWnd = this;
-  acp.dwFlags = PWS_CHILD | PWS_VISIBLE | PWS_AUTOFONTSIZE | PES_MULTILINE |
-                PES_AUTORETURN | PES_MIDDLE | PES_CENTER;
-  acp.sTextColor = CPWL_Color(COLORTYPE_GRAY, 0);
-  m_pText->Create(acp);
-
-  m_pDescription = new CPWL_Label;
-  PWL_CREATEPARAM dcp = cp;
-  dcp.pParentWnd = this;
-  dcp.dwFlags = PWS_CHILD | PWS_VISIBLE | PWS_AUTOFONTSIZE | PES_MULTILINE |
-                PES_AUTORETURN | PES_LEFT | PES_CENTER;
-  dcp.sTextColor = CPWL_Color(COLORTYPE_GRAY, 0);
-  m_pDescription->Create(dcp);
-}
-
-void CPWL_Signature::DrawThisAppearance(CFX_RenderDevice* pDevice,
-                                        CFX_Matrix* pUser2Device) {
-  CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device);
-
-  if (m_bFlagExist) {
-    CPWL_Utils::DrawIconAppStream(
-        pDevice, pUser2Device, PWL_ICONTYPE_FOXIT,
-        CPWL_Utils::GetCenterSquare(GetClientRect()),
-        CPWL_Color(COLORTYPE_RGB, 0.91f, 0.855f, 0.92f),
-        CPWL_Color(COLORTYPE_TRANSPARENT), 255);
-  }
-}
-
-void CPWL_Signature::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) {
-  CPWL_Wnd::GetThisAppearanceStream(sAppStream);
-}
diff --git a/fpdfsdk/src/pdfwindow/PWL_SpecialButton.cpp b/fpdfsdk/src/pdfwindow/PWL_SpecialButton.cpp
deleted file mode 100644
index 52f25fc..0000000
--- a/fpdfsdk/src/pdfwindow/PWL_SpecialButton.cpp
+++ /dev/null
@@ -1,80 +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
-
-#include "fpdfsdk/include/pdfwindow/PWL_Button.h"
-#include "fpdfsdk/include/pdfwindow/PWL_SpecialButton.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Wnd.h"
-
-CPWL_PushButton::CPWL_PushButton() {}
-
-CPWL_PushButton::~CPWL_PushButton() {}
-
-CFX_ByteString CPWL_PushButton::GetClassName() const {
-  return "CPWL_PushButton";
-}
-
-CPDF_Rect CPWL_PushButton::GetFocusRect() const {
-  return CPWL_Utils::DeflateRect(GetWindowRect(), (FX_FLOAT)GetBorderWidth());
-}
-
-CPWL_CheckBox::CPWL_CheckBox() : m_bChecked(FALSE) {}
-
-CPWL_CheckBox::~CPWL_CheckBox() {}
-
-CFX_ByteString CPWL_CheckBox::GetClassName() const {
-  return "CPWL_CheckBox";
-}
-
-void CPWL_CheckBox::SetCheck(FX_BOOL bCheck) {
-  m_bChecked = bCheck;
-}
-
-FX_BOOL CPWL_CheckBox::IsChecked() const {
-  return m_bChecked;
-}
-
-FX_BOOL CPWL_CheckBox::OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag) {
-  if (IsReadOnly())
-    return FALSE;
-
-  SetCheck(!IsChecked());
-  return TRUE;
-}
-
-FX_BOOL CPWL_CheckBox::OnChar(FX_WORD nChar, FX_DWORD nFlag) {
-  SetCheck(!IsChecked());
-  return TRUE;
-}
-
-CPWL_RadioButton::CPWL_RadioButton() : m_bChecked(FALSE) {}
-
-CPWL_RadioButton::~CPWL_RadioButton() {}
-
-CFX_ByteString CPWL_RadioButton::GetClassName() const {
-  return "CPWL_RadioButton";
-}
-
-FX_BOOL CPWL_RadioButton::OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag) {
-  if (IsReadOnly())
-    return FALSE;
-
-  SetCheck(TRUE);
-  return TRUE;
-}
-
-void CPWL_RadioButton::SetCheck(FX_BOOL bCheck) {
-  m_bChecked = bCheck;
-}
-
-FX_BOOL CPWL_RadioButton::IsChecked() const {
-  return m_bChecked;
-}
-
-FX_BOOL CPWL_RadioButton::OnChar(FX_WORD nChar, FX_DWORD nFlag) {
-  SetCheck(TRUE);
-  return TRUE;
-}
diff --git a/fpdfsdk/src/pdfwindow/PWL_Wnd.cpp b/fpdfsdk/src/pdfwindow/PWL_Wnd.cpp
deleted file mode 100644
index d0aaa78..0000000
--- a/fpdfsdk/src/pdfwindow/PWL_Wnd.cpp
+++ /dev/null
@@ -1,1037 +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
-
-#include <map>
-
-#include "fpdfsdk/include/pdfwindow/PWL_ScrollBar.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
-#include "fpdfsdk/include/pdfwindow/PWL_Wnd.h"
-
-static std::map<int32_t, CPWL_Timer*>& GetPWLTimeMap() {
-  // Leak the object at shutdown.
-  static auto timeMap = new std::map<int32_t, CPWL_Timer*>;
-  return *timeMap;
-}
-
-CPWL_Timer::CPWL_Timer(CPWL_TimerHandler* pAttached,
-                       IFX_SystemHandler* pSystemHandler)
-    : m_nTimerID(0), m_pAttached(pAttached), m_pSystemHandler(pSystemHandler) {
-  ASSERT(m_pAttached);
-  ASSERT(m_pSystemHandler);
-}
-
-CPWL_Timer::~CPWL_Timer() {
-  KillPWLTimer();
-}
-
-int32_t CPWL_Timer::SetPWLTimer(int32_t nElapse) {
-  if (m_nTimerID != 0)
-    KillPWLTimer();
-  m_nTimerID = m_pSystemHandler->SetTimer(nElapse, TimerProc);
-
-  GetPWLTimeMap()[m_nTimerID] = this;
-  return m_nTimerID;
-}
-
-void CPWL_Timer::KillPWLTimer() {
-  if (m_nTimerID == 0)
-    return;
-
-  m_pSystemHandler->KillTimer(m_nTimerID);
-  GetPWLTimeMap().erase(m_nTimerID);
-  m_nTimerID = 0;
-}
-
-void CPWL_Timer::TimerProc(int32_t idEvent) {
-  auto it = GetPWLTimeMap().find(idEvent);
-  if (it == GetPWLTimeMap().end())
-    return;
-
-  CPWL_Timer* pTimer = it->second;
-  if (pTimer->m_pAttached)
-    pTimer->m_pAttached->TimerProc();
-}
-
-CPWL_TimerHandler::CPWL_TimerHandler() : m_pTimer(NULL) {}
-
-CPWL_TimerHandler::~CPWL_TimerHandler() {
-  delete m_pTimer;
-}
-
-void CPWL_TimerHandler::BeginTimer(int32_t nElapse) {
-  if (!m_pTimer)
-    m_pTimer = new CPWL_Timer(this, GetSystemHandler());
-
-  if (m_pTimer)
-    m_pTimer->SetPWLTimer(nElapse);
-}
-
-void CPWL_TimerHandler::EndTimer() {
-  if (m_pTimer)
-    m_pTimer->KillPWLTimer();
-}
-
-void CPWL_TimerHandler::TimerProc() {}
-
-class CPWL_MsgControl {
-  friend class CPWL_Wnd;
-
- public:
-  explicit CPWL_MsgControl(CPWL_Wnd* pWnd) {
-    m_pCreatedWnd = pWnd;
-    Default();
-  }
-
-  ~CPWL_MsgControl() {
-    Default();
-  }
-
-  void Default() {
-    m_aMousePath.RemoveAll();
-    m_aKeyboardPath.RemoveAll();
-    m_pMainMouseWnd = NULL;
-    m_pMainKeyboardWnd = NULL;
-  }
-
-  FX_BOOL IsWndCreated(const CPWL_Wnd* pWnd) const {
-    return m_pCreatedWnd == pWnd;
-  }
-
-  FX_BOOL IsMainCaptureMouse(const CPWL_Wnd* pWnd) const {
-    return pWnd == m_pMainMouseWnd;
-  }
-
-  FX_BOOL IsWndCaptureMouse(const CPWL_Wnd* pWnd) const {
-    if (pWnd) {
-      for (int32_t i = 0, sz = m_aMousePath.GetSize(); i < sz; i++) {
-        if (m_aMousePath.GetAt(i) == pWnd)
-          return TRUE;
-      }
-    }
-
-    return FALSE;
-  }
-
-  FX_BOOL IsMainCaptureKeyboard(const CPWL_Wnd* pWnd) const {
-    return pWnd == m_pMainKeyboardWnd;
-  }
-
-  FX_BOOL IsWndCaptureKeyboard(const CPWL_Wnd* pWnd) const {
-    if (pWnd) {
-      for (int32_t i = 0, sz = m_aKeyboardPath.GetSize(); i < sz; i++) {
-        if (m_aKeyboardPath.GetAt(i) == pWnd)
-          return TRUE;
-      }
-    }
-
-    return FALSE;
-  }
-
-  void SetFocus(CPWL_Wnd* pWnd) {
-    m_aKeyboardPath.RemoveAll();
-
-    if (pWnd) {
-      m_pMainKeyboardWnd = pWnd;
-
-      CPWL_Wnd* pParent = pWnd;
-      while (pParent) {
-        m_aKeyboardPath.Add(pParent);
-        pParent = pParent->GetParentWindow();
-      }
-
-      pWnd->OnSetFocus();
-    }
-  }
-
-  void KillFocus() {
-    if (m_aKeyboardPath.GetSize() > 0)
-      if (CPWL_Wnd* pWnd = m_aKeyboardPath.GetAt(0))
-        pWnd->OnKillFocus();
-
-    m_pMainKeyboardWnd = NULL;
-    m_aKeyboardPath.RemoveAll();
-  }
-
-  void SetCapture(CPWL_Wnd* pWnd) {
-    m_aMousePath.RemoveAll();
-
-    if (pWnd) {
-      m_pMainMouseWnd = pWnd;
-
-      CPWL_Wnd* pParent = pWnd;
-      while (pParent) {
-        m_aMousePath.Add(pParent);
-        pParent = pParent->GetParentWindow();
-      }
-    }
-  }
-
-  void ReleaseCapture() {
-    m_pMainMouseWnd = NULL;
-    m_aMousePath.RemoveAll();
-  }
-
- private:
-  CFX_ArrayTemplate<CPWL_Wnd*> m_aMousePath;
-  CFX_ArrayTemplate<CPWL_Wnd*> m_aKeyboardPath;
-  CPWL_Wnd* m_pCreatedWnd;
-  CPWL_Wnd* m_pMainMouseWnd;
-  CPWL_Wnd* m_pMainKeyboardWnd;
-};
-
-CPWL_Wnd::CPWL_Wnd()
-    : m_pVScrollBar(NULL),
-      m_rcWindow(),
-      m_rcClip(),
-      m_bCreated(FALSE),
-      m_bVisible(FALSE),
-      m_bNotifying(FALSE),
-      m_bEnabled(TRUE) {}
-
-CPWL_Wnd::~CPWL_Wnd() {
-  ASSERT(m_bCreated == FALSE);
-}
-
-CFX_ByteString CPWL_Wnd::GetClassName() const {
-  return "CPWL_Wnd";
-}
-
-void CPWL_Wnd::Create(const PWL_CREATEPARAM& cp) {
-  if (!IsValid()) {
-    m_sPrivateParam = cp;
-
-    OnCreate(m_sPrivateParam);
-
-    m_sPrivateParam.rcRectWnd.Normalize();
-    m_rcWindow = m_sPrivateParam.rcRectWnd;
-    m_rcClip = CPWL_Utils::InflateRect(m_rcWindow, 1.0f);
-
-    CreateMsgControl();
-
-    if (m_sPrivateParam.pParentWnd)
-      m_sPrivateParam.pParentWnd->OnNotify(this, PNM_ADDCHILD);
-
-    PWL_CREATEPARAM ccp = m_sPrivateParam;
-
-    ccp.dwFlags &= 0xFFFF0000L;  // remove sub styles
-    ccp.mtChild = CFX_Matrix(1, 0, 0, 1, 0, 0);
-
-    CreateScrollBar(ccp);
-    CreateChildWnd(ccp);
-
-    m_bVisible = HasFlag(PWS_VISIBLE);
-
-    OnCreated();
-
-    RePosChildWnd();
-    m_bCreated = TRUE;
-  }
-}
-
-void CPWL_Wnd::OnCreate(PWL_CREATEPARAM& cp) {}
-
-void CPWL_Wnd::OnCreated() {}
-
-void CPWL_Wnd::OnDestroy() {}
-
-void CPWL_Wnd::InvalidateFocusHandler(IPWL_FocusHandler* handler) {
-  if (m_sPrivateParam.pFocusHandler == handler)
-    m_sPrivateParam.pFocusHandler = nullptr;
-}
-
-void CPWL_Wnd::InvalidateProvider(IPWL_Provider* provider) {
-  if (m_sPrivateParam.pProvider == provider)
-    m_sPrivateParam.pProvider = nullptr;
-}
-
-void CPWL_Wnd::Destroy() {
-  KillFocus();
-
-  OnDestroy();
-
-  if (m_bCreated) {
-    for (int32_t i = m_aChildren.GetSize() - 1; i >= 0; i--) {
-      if (CPWL_Wnd* pChild = m_aChildren[i]) {
-        pChild->Destroy();
-        delete pChild;
-        pChild = NULL;
-      }
-    }
-
-    if (m_sPrivateParam.pParentWnd)
-      m_sPrivateParam.pParentWnd->OnNotify(this, PNM_REMOVECHILD);
-    m_bCreated = FALSE;
-  }
-
-  DestroyMsgControl();
-
-  FXSYS_memset(&m_sPrivateParam, 0, sizeof(PWL_CREATEPARAM));
-  m_aChildren.RemoveAll();
-  m_pVScrollBar = NULL;
-}
-
-void CPWL_Wnd::Move(const CPDF_Rect& rcNew, FX_BOOL bReset, FX_BOOL bRefresh) {
-  if (IsValid()) {
-    CPDF_Rect rcOld = GetWindowRect();
-
-    m_rcWindow = rcNew;
-    m_rcWindow.Normalize();
-
-    if (rcOld.left != rcNew.left || rcOld.right != rcNew.right ||
-        rcOld.top != rcNew.top || rcOld.bottom != rcNew.bottom) {
-      if (bReset) {
-        RePosChildWnd();
-      }
-    }
-    if (bRefresh) {
-      InvalidateRectMove(rcOld, rcNew);
-    }
-
-    m_sPrivateParam.rcRectWnd = m_rcWindow;
-  }
-}
-
-void CPWL_Wnd::InvalidateRectMove(const CPDF_Rect& rcOld,
-                                  const CPDF_Rect& rcNew) {
-  CPDF_Rect rcUnion = rcOld;
-  rcUnion.Union(rcNew);
-
-  InvalidateRect(&rcUnion);
-}
-
-void CPWL_Wnd::GetAppearanceStream(CFX_ByteTextBuf& sAppStream) {
-  if (IsValid() && IsVisible()) {
-    GetThisAppearanceStream(sAppStream);
-    GetChildAppearanceStream(sAppStream);
-  }
-}
-
-// if don't set,Get default apperance stream
-void CPWL_Wnd::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) {
-  CPDF_Rect rectWnd = GetWindowRect();
-  if (!rectWnd.IsEmpty()) {
-    CFX_ByteTextBuf sThis;
-
-    if (HasFlag(PWS_BACKGROUND))
-      sThis << CPWL_Utils::GetRectFillAppStream(rectWnd, GetBackgroundColor());
-
-    if (HasFlag(PWS_BORDER)) {
-      sThis << CPWL_Utils::GetBorderAppStream(
-          rectWnd, (FX_FLOAT)GetBorderWidth(), GetBorderColor(),
-          GetBorderLeftTopColor(GetBorderStyle()),
-          GetBorderRightBottomColor(GetBorderStyle()), GetBorderStyle(),
-          GetBorderDash());
-    }
-
-    sAppStream << sThis;
-  }
-}
-
-void CPWL_Wnd::GetChildAppearanceStream(CFX_ByteTextBuf& sAppStream) {
-  for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
-    if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
-      pChild->GetAppearanceStream(sAppStream);
-    }
-  }
-}
-
-void CPWL_Wnd::DrawAppearance(CFX_RenderDevice* pDevice,
-                              CFX_Matrix* pUser2Device) {
-  if (IsValid() && IsVisible()) {
-    DrawThisAppearance(pDevice, pUser2Device);
-    DrawChildAppearance(pDevice, pUser2Device);
-  }
-}
-
-void CPWL_Wnd::DrawThisAppearance(CFX_RenderDevice* pDevice,
-                                  CFX_Matrix* pUser2Device) {
-  CPDF_Rect rectWnd = GetWindowRect();
-  if (!rectWnd.IsEmpty()) {
-    if (HasFlag(PWS_BACKGROUND)) {
-      CPDF_Rect rcClient = CPWL_Utils::DeflateRect(
-          rectWnd, (FX_FLOAT)(GetBorderWidth() + GetInnerBorderWidth()));
-      CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rcClient,
-                               GetBackgroundColor(), GetTransparency());
-    }
-
-    if (HasFlag(PWS_BORDER))
-      CPWL_Utils::DrawBorder(pDevice, pUser2Device, rectWnd,
-                             (FX_FLOAT)GetBorderWidth(), GetBorderColor(),
-                             GetBorderLeftTopColor(GetBorderStyle()),
-                             GetBorderRightBottomColor(GetBorderStyle()),
-                             GetBorderStyle(), GetTransparency());
-  }
-}
-
-void CPWL_Wnd::DrawChildAppearance(CFX_RenderDevice* pDevice,
-                                   CFX_Matrix* pUser2Device) {
-  for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
-    if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
-      CFX_Matrix mt = pChild->GetChildMatrix();
-      if (mt.IsIdentity()) {
-        pChild->DrawAppearance(pDevice, pUser2Device);
-      } else {
-        mt.Concat(*pUser2Device);
-        pChild->DrawAppearance(pDevice, &mt);
-      }
-    }
-  }
-}
-
-void CPWL_Wnd::InvalidateRect(CPDF_Rect* pRect) {
-  if (IsValid()) {
-    CPDF_Rect rcRefresh = pRect ? *pRect : GetWindowRect();
-
-    if (!HasFlag(PWS_NOREFRESHCLIP)) {
-      CPDF_Rect rcClip = GetClipRect();
-      if (!rcClip.IsEmpty()) {
-        rcRefresh.Intersect(rcClip);
-      }
-    }
-
-    FX_RECT rcWin = PWLtoWnd(rcRefresh);
-    rcWin.left -= PWL_INVALIDATE_INFLATE;
-    rcWin.top -= PWL_INVALIDATE_INFLATE;
-    rcWin.right += PWL_INVALIDATE_INFLATE;
-    rcWin.bottom += PWL_INVALIDATE_INFLATE;
-
-    if (IFX_SystemHandler* pSH = GetSystemHandler()) {
-      if (FX_HWND hWnd = GetAttachedHWnd()) {
-        pSH->InvalidateRect(hWnd, rcWin);
-      }
-    }
-  }
-}
-
-#define PWL_IMPLEMENT_KEY_METHOD(key_method_name)                      \
-  FX_BOOL CPWL_Wnd::key_method_name(FX_WORD nChar, FX_DWORD nFlag) {   \
-    if (IsValid() && IsVisible() && IsEnabled()) {                     \
-      if (IsWndCaptureKeyboard(this)) {                                \
-        for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) { \
-          if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {               \
-            if (IsWndCaptureKeyboard(pChild)) {                        \
-              return pChild->key_method_name(nChar, nFlag);            \
-            }                                                          \
-          }                                                            \
-        }                                                              \
-      }                                                                \
-    }                                                                  \
-    return FALSE;                                                      \
-  }
-
-#define PWL_IMPLEMENT_MOUSE_METHOD(mouse_method_name)                        \
-  FX_BOOL CPWL_Wnd::mouse_method_name(const CPDF_Point& point,               \
-                                      FX_DWORD nFlag) {                      \
-    if (IsValid() && IsVisible() && IsEnabled()) {                           \
-      if (IsWndCaptureMouse(this)) {                                         \
-        for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {       \
-          if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {                     \
-            if (IsWndCaptureMouse(pChild)) {                                 \
-              return pChild->mouse_method_name(pChild->ParentToChild(point), \
-                                               nFlag);                       \
-            }                                                                \
-          }                                                                  \
-        }                                                                    \
-        SetCursor();                                                         \
-      } else {                                                               \
-        for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {       \
-          if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {                     \
-            if (pChild->WndHitTest(pChild->ParentToChild(point))) {          \
-              return pChild->mouse_method_name(pChild->ParentToChild(point), \
-                                               nFlag);                       \
-            }                                                                \
-          }                                                                  \
-        }                                                                    \
-        if (WndHitTest(point))                                               \
-          SetCursor();                                                       \
-      }                                                                      \
-    }                                                                        \
-    return FALSE;                                                            \
-  }
-
-PWL_IMPLEMENT_KEY_METHOD(OnKeyDown)
-PWL_IMPLEMENT_KEY_METHOD(OnKeyUp)
-PWL_IMPLEMENT_KEY_METHOD(OnChar)
-
-PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonDblClk)
-PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonDown)
-PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonUp)
-PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonDblClk)
-PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonDown)
-PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonUp)
-PWL_IMPLEMENT_MOUSE_METHOD(OnRButtonDown)
-PWL_IMPLEMENT_MOUSE_METHOD(OnRButtonUp)
-PWL_IMPLEMENT_MOUSE_METHOD(OnMouseMove)
-
-FX_BOOL CPWL_Wnd::OnMouseWheel(short zDelta,
-                               const CPDF_Point& point,
-                               FX_DWORD nFlag) {
-  if (IsValid() && IsVisible() && IsEnabled()) {
-    SetCursor();
-    if (IsWndCaptureKeyboard(this)) {
-      for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
-        if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
-          if (IsWndCaptureKeyboard(pChild)) {
-            return pChild->OnMouseWheel(zDelta, pChild->ParentToChild(point),
-                                        nFlag);
-          }
-        }
-      }
-    }
-  }
-  return FALSE;
-}
-
-void CPWL_Wnd::AddChild(CPWL_Wnd* pWnd) {
-  m_aChildren.Add(pWnd);
-}
-
-void CPWL_Wnd::RemoveChild(CPWL_Wnd* pWnd) {
-  for (int32_t i = m_aChildren.GetSize() - 1; i >= 0; i--) {
-    if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
-      if (pChild == pWnd) {
-        m_aChildren.RemoveAt(i);
-        break;
-      }
-    }
-  }
-}
-
-void CPWL_Wnd::OnNotify(CPWL_Wnd* pWnd,
-                        FX_DWORD msg,
-                        intptr_t wParam,
-                        intptr_t lParam) {
-  switch (msg) {
-    case PNM_ADDCHILD:
-      AddChild(pWnd);
-      break;
-    case PNM_REMOVECHILD:
-      RemoveChild(pWnd);
-      break;
-    default:
-      break;
-  }
-}
-
-FX_BOOL CPWL_Wnd::IsValid() const {
-  return m_bCreated;
-}
-
-const PWL_CREATEPARAM& CPWL_Wnd::GetCreationParam() const {
-  return m_sPrivateParam;
-}
-
-CPWL_Wnd* CPWL_Wnd::GetParentWindow() const {
-  return m_sPrivateParam.pParentWnd;
-}
-
-CPDF_Rect CPWL_Wnd::GetWindowRect() const {
-  return m_rcWindow;
-}
-
-CPDF_Rect CPWL_Wnd::GetClientRect() const {
-  CPDF_Rect rcWindow = GetWindowRect();
-  CPDF_Rect rcClient = CPWL_Utils::DeflateRect(
-      rcWindow, (FX_FLOAT)(GetBorderWidth() + GetInnerBorderWidth()));
-  if (CPWL_ScrollBar* pVSB = GetVScrollBar())
-    rcClient.right -= pVSB->GetScrollBarWidth();
-
-  rcClient.Normalize();
-  return rcWindow.Contains(rcClient) ? rcClient : CPDF_Rect();
-}
-
-CPDF_Point CPWL_Wnd::GetCenterPoint() const {
-  CPDF_Rect rcClient = GetClientRect();
-  return CPDF_Point((rcClient.left + rcClient.right) * 0.5f,
-                    (rcClient.top + rcClient.bottom) * 0.5f);
-}
-
-FX_BOOL CPWL_Wnd::HasFlag(FX_DWORD dwFlags) const {
-  return (m_sPrivateParam.dwFlags & dwFlags) != 0;
-}
-
-void CPWL_Wnd::RemoveFlag(FX_DWORD dwFlags) {
-  m_sPrivateParam.dwFlags &= ~dwFlags;
-}
-
-void CPWL_Wnd::AddFlag(FX_DWORD dwFlags) {
-  m_sPrivateParam.dwFlags |= dwFlags;
-}
-
-CPWL_Color CPWL_Wnd::GetBackgroundColor() const {
-  return m_sPrivateParam.sBackgroundColor;
-}
-
-void CPWL_Wnd::SetBackgroundColor(const CPWL_Color& color) {
-  m_sPrivateParam.sBackgroundColor = color;
-}
-
-void CPWL_Wnd::SetTextColor(const CPWL_Color& color) {
-  m_sPrivateParam.sTextColor = color;
-}
-
-void CPWL_Wnd::SetTextStrokeColor(const CPWL_Color& color) {
-  m_sPrivateParam.sTextStrokeColor = color;
-}
-
-CPWL_Color CPWL_Wnd::GetTextColor() const {
-  return m_sPrivateParam.sTextColor;
-}
-
-CPWL_Color CPWL_Wnd::GetTextStrokeColor() const {
-  return m_sPrivateParam.sTextStrokeColor;
-}
-
-int32_t CPWL_Wnd::GetBorderStyle() const {
-  return m_sPrivateParam.nBorderStyle;
-}
-
-void CPWL_Wnd::SetBorderStyle(int32_t nBorderStyle) {
-  if (HasFlag(PWS_BORDER))
-    m_sPrivateParam.nBorderStyle = nBorderStyle;
-}
-
-int32_t CPWL_Wnd::GetBorderWidth() const {
-  if (HasFlag(PWS_BORDER))
-    return m_sPrivateParam.dwBorderWidth;
-
-  return 0;
-}
-
-int32_t CPWL_Wnd::GetInnerBorderWidth() const {
-  return 0;
-}
-
-CPWL_Color CPWL_Wnd::GetBorderColor() const {
-  if (HasFlag(PWS_BORDER))
-    return m_sPrivateParam.sBorderColor;
-
-  return CPWL_Color();
-}
-
-const CPWL_Dash& CPWL_Wnd::GetBorderDash() const {
-  return m_sPrivateParam.sDash;
-}
-
-void* CPWL_Wnd::GetAttachedData() const {
-  return m_sPrivateParam.pAttachedData;
-}
-
-CPWL_ScrollBar* CPWL_Wnd::GetVScrollBar() const {
-  if (HasFlag(PWS_VSCROLL))
-    return m_pVScrollBar;
-
-  return NULL;
-}
-
-void CPWL_Wnd::CreateScrollBar(const PWL_CREATEPARAM& cp) {
-  CreateVScrollBar(cp);
-}
-
-void CPWL_Wnd::CreateVScrollBar(const PWL_CREATEPARAM& cp) {
-  if (!m_pVScrollBar && HasFlag(PWS_VSCROLL)) {
-    PWL_CREATEPARAM scp = cp;
-
-    // flags
-    scp.dwFlags =
-        PWS_CHILD | PWS_BACKGROUND | PWS_AUTOTRANSPARENT | PWS_NOREFRESHCLIP;
-
-    scp.pParentWnd = this;
-    scp.sBackgroundColor = PWL_DEFAULT_WHITECOLOR;
-    scp.eCursorType = FXCT_ARROW;
-    scp.nTransparency = PWL_SCROLLBAR_TRANSPARANCY;
-
-    m_pVScrollBar = new CPWL_ScrollBar(SBT_VSCROLL);
-    m_pVScrollBar->Create(scp);
-  }
-}
-
-void CPWL_Wnd::SetCapture() {
-  if (CPWL_MsgControl* pMsgCtrl = GetMsgControl())
-    pMsgCtrl->SetCapture(this);
-}
-
-void CPWL_Wnd::ReleaseCapture() {
-  for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++)
-    if (CPWL_Wnd* pChild = m_aChildren.GetAt(i))
-      pChild->ReleaseCapture();
-
-  if (CPWL_MsgControl* pMsgCtrl = GetMsgControl())
-    pMsgCtrl->ReleaseCapture();
-}
-
-void CPWL_Wnd::SetFocus() {
-  if (CPWL_MsgControl* pMsgCtrl = GetMsgControl()) {
-    if (!pMsgCtrl->IsMainCaptureKeyboard(this))
-      pMsgCtrl->KillFocus();
-    pMsgCtrl->SetFocus(this);
-  }
-}
-
-void CPWL_Wnd::KillFocus() {
-  if (CPWL_MsgControl* pMsgCtrl = GetMsgControl()) {
-    if (pMsgCtrl->IsWndCaptureKeyboard(this))
-      pMsgCtrl->KillFocus();
-  }
-}
-
-void CPWL_Wnd::OnSetFocus() {}
-
-void CPWL_Wnd::OnKillFocus() {}
-
-FX_BOOL CPWL_Wnd::WndHitTest(const CPDF_Point& point) const {
-  return IsValid() && IsVisible() && GetWindowRect().Contains(point.x, point.y);
-}
-
-FX_BOOL CPWL_Wnd::ClientHitTest(const CPDF_Point& point) const {
-  return IsValid() && IsVisible() && GetClientRect().Contains(point.x, point.y);
-}
-
-const CPWL_Wnd* CPWL_Wnd::GetRootWnd() const {
-  if (m_sPrivateParam.pParentWnd)
-    return m_sPrivateParam.pParentWnd->GetRootWnd();
-
-  return this;
-}
-
-void CPWL_Wnd::SetVisible(FX_BOOL bVisible) {
-  if (IsValid()) {
-    for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
-      if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
-        pChild->SetVisible(bVisible);
-      }
-    }
-
-    if (bVisible != m_bVisible) {
-      m_bVisible = bVisible;
-      RePosChildWnd();
-      InvalidateRect();
-    }
-  }
-}
-
-void CPWL_Wnd::SetClipRect(const CPDF_Rect& rect) {
-  m_rcClip = rect;
-  m_rcClip.Normalize();
-}
-
-const CPDF_Rect& CPWL_Wnd::GetClipRect() const {
-  return m_rcClip;
-}
-
-FX_BOOL CPWL_Wnd::IsReadOnly() const {
-  return HasFlag(PWS_READONLY);
-}
-
-void CPWL_Wnd::RePosChildWnd() {
-  CPDF_Rect rcContent = CPWL_Utils::DeflateRect(
-      GetWindowRect(), (FX_FLOAT)(GetBorderWidth() + GetInnerBorderWidth()));
-
-  CPWL_ScrollBar* pVSB = GetVScrollBar();
-
-  CPDF_Rect rcVScroll =
-      CPDF_Rect(rcContent.right - PWL_SCROLLBAR_WIDTH, rcContent.bottom,
-                rcContent.right - 1.0f, rcContent.top);
-
-  if (pVSB)
-    pVSB->Move(rcVScroll, TRUE, FALSE);
-}
-
-void CPWL_Wnd::CreateChildWnd(const PWL_CREATEPARAM& cp) {}
-
-void CPWL_Wnd::SetCursor() {
-  if (IsValid()) {
-    if (IFX_SystemHandler* pSH = GetSystemHandler()) {
-      int32_t nCursorType = GetCreationParam().eCursorType;
-      pSH->SetCursor(nCursorType);
-    }
-  }
-}
-
-void CPWL_Wnd::CreateMsgControl() {
-  if (!m_sPrivateParam.pMsgControl)
-    m_sPrivateParam.pMsgControl = new CPWL_MsgControl(this);
-}
-
-void CPWL_Wnd::DestroyMsgControl() {
-  if (CPWL_MsgControl* pMsgControl = GetMsgControl())
-    if (pMsgControl->IsWndCreated(this))
-      delete pMsgControl;
-}
-
-CPWL_MsgControl* CPWL_Wnd::GetMsgControl() const {
-  return m_sPrivateParam.pMsgControl;
-}
-
-FX_BOOL CPWL_Wnd::IsCaptureMouse() const {
-  return IsWndCaptureMouse(this);
-}
-
-FX_BOOL CPWL_Wnd::IsWndCaptureMouse(const CPWL_Wnd* pWnd) const {
-  if (CPWL_MsgControl* pCtrl = GetMsgControl())
-    return pCtrl->IsWndCaptureMouse(pWnd);
-
-  return FALSE;
-}
-
-FX_BOOL CPWL_Wnd::IsWndCaptureKeyboard(const CPWL_Wnd* pWnd) const {
-  if (CPWL_MsgControl* pCtrl = GetMsgControl())
-    return pCtrl->IsWndCaptureKeyboard(pWnd);
-
-  return FALSE;
-}
-
-FX_BOOL CPWL_Wnd::IsFocused() const {
-  if (CPWL_MsgControl* pCtrl = GetMsgControl())
-    return pCtrl->IsMainCaptureKeyboard(this);
-
-  return FALSE;
-}
-
-CPDF_Rect CPWL_Wnd::GetFocusRect() const {
-  return CPWL_Utils::InflateRect(GetWindowRect(), 1);
-}
-
-FX_FLOAT CPWL_Wnd::GetFontSize() const {
-  return m_sPrivateParam.fFontSize;
-}
-
-void CPWL_Wnd::SetFontSize(FX_FLOAT fFontSize) {
-  m_sPrivateParam.fFontSize = fFontSize;
-}
-
-IFX_SystemHandler* CPWL_Wnd::GetSystemHandler() const {
-  return m_sPrivateParam.pSystemHandler;
-}
-
-IPWL_FocusHandler* CPWL_Wnd::GetFocusHandler() const {
-  return m_sPrivateParam.pFocusHandler;
-}
-
-IPWL_Provider* CPWL_Wnd::GetProvider() const {
-  return m_sPrivateParam.pProvider;
-}
-
-IFX_Edit_FontMap* CPWL_Wnd::GetFontMap() const {
-  return m_sPrivateParam.pFontMap;
-}
-
-CPWL_Color CPWL_Wnd::GetBorderLeftTopColor(int32_t nBorderStyle) const {
-  CPWL_Color color;
-
-  switch (nBorderStyle) {
-    case PBS_SOLID:
-      break;
-    case PBS_DASH:
-      break;
-    case PBS_BEVELED:
-      color = CPWL_Color(COLORTYPE_GRAY, 1);
-      break;
-    case PBS_INSET:
-      color = CPWL_Color(COLORTYPE_GRAY, 0.5f);
-      break;
-    case PBS_UNDERLINED:
-      break;
-  }
-
-  return color;
-}
-
-CPWL_Color CPWL_Wnd::GetBorderRightBottomColor(int32_t nBorderStyle) const {
-  CPWL_Color color;
-
-  switch (nBorderStyle) {
-    case PBS_SOLID:
-      break;
-    case PBS_DASH:
-      break;
-    case PBS_BEVELED:
-      color = CPWL_Utils::DevideColor(GetBackgroundColor(), 2);
-      break;
-    case PBS_INSET:
-      color = CPWL_Color(COLORTYPE_GRAY, 0.75f);
-      break;
-    case PBS_UNDERLINED:
-      break;
-  }
-
-  return color;
-}
-
-int32_t CPWL_Wnd::GetTransparency() {
-  return m_sPrivateParam.nTransparency;
-}
-
-void CPWL_Wnd::SetTransparency(int32_t nTransparency) {
-  for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
-    if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
-      pChild->SetTransparency(nTransparency);
-    }
-  }
-
-  m_sPrivateParam.nTransparency = nTransparency;
-}
-
-CFX_Matrix CPWL_Wnd::GetWindowMatrix() const {
-  CFX_Matrix mt = GetChildToRoot();
-
-  if (IPWL_Provider* pProvider = GetProvider()) {
-    mt.Concat(pProvider->GetWindowMatrix(GetAttachedData()));
-    return mt;
-  }
-
-  return mt;
-}
-
-void CPWL_Wnd::PWLtoWnd(const CPDF_Point& point, int32_t& x, int32_t& y) const {
-  CFX_Matrix mt = GetWindowMatrix();
-  CPDF_Point pt = point;
-  mt.Transform(pt.x, pt.y);
-  x = (int32_t)(pt.x + 0.5);
-  y = (int32_t)(pt.y + 0.5);
-}
-
-FX_RECT CPWL_Wnd::PWLtoWnd(const CPDF_Rect& rect) const {
-  CPDF_Rect rcTemp = rect;
-  CFX_Matrix mt = GetWindowMatrix();
-  mt.TransformRect(rcTemp);
-  return FX_RECT((int32_t)(rcTemp.left + 0.5), (int32_t)(rcTemp.bottom + 0.5),
-                 (int32_t)(rcTemp.right + 0.5), (int32_t)(rcTemp.top + 0.5));
-}
-
-FX_HWND CPWL_Wnd::GetAttachedHWnd() const {
-  return m_sPrivateParam.hAttachedWnd;
-}
-
-CPDF_Point CPWL_Wnd::ChildToParent(const CPDF_Point& point) const {
-  CFX_Matrix mt = GetChildMatrix();
-  if (mt.IsIdentity())
-    return point;
-
-  CPDF_Point pt = point;
-  mt.Transform(pt.x, pt.y);
-  return pt;
-}
-
-CPDF_Rect CPWL_Wnd::ChildToParent(const CPDF_Rect& rect) const {
-  CFX_Matrix mt = GetChildMatrix();
-  if (mt.IsIdentity())
-    return rect;
-
-  CPDF_Rect rc = rect;
-  mt.TransformRect(rc);
-  return rc;
-}
-
-CPDF_Point CPWL_Wnd::ParentToChild(const CPDF_Point& point) const {
-  CFX_Matrix mt = GetChildMatrix();
-  if (mt.IsIdentity())
-    return point;
-
-  mt.SetReverse(mt);
-  CPDF_Point pt = point;
-  mt.Transform(pt.x, pt.y);
-  return pt;
-}
-
-CPDF_Rect CPWL_Wnd::ParentToChild(const CPDF_Rect& rect) const {
-  CFX_Matrix mt = GetChildMatrix();
-  if (mt.IsIdentity())
-    return rect;
-
-  mt.SetReverse(mt);
-  CPDF_Rect rc = rect;
-  mt.TransformRect(rc);
-  return rc;
-}
-
-CFX_Matrix CPWL_Wnd::GetChildToRoot() const {
-  CFX_Matrix mt(1, 0, 0, 1, 0, 0);
-  if (HasFlag(PWS_CHILD)) {
-    const CPWL_Wnd* pParent = this;
-    while (pParent) {
-      mt.Concat(pParent->GetChildMatrix());
-      pParent = pParent->GetParentWindow();
-    }
-  }
-  return mt;
-}
-
-CFX_Matrix CPWL_Wnd::GetChildMatrix() const {
-  if (HasFlag(PWS_CHILD))
-    return m_sPrivateParam.mtChild;
-
-  return CFX_Matrix(1, 0, 0, 1, 0, 0);
-}
-
-void CPWL_Wnd::SetChildMatrix(const CFX_Matrix& mt) {
-  m_sPrivateParam.mtChild = mt;
-}
-
-const CPWL_Wnd* CPWL_Wnd::GetFocused() const {
-  if (CPWL_MsgControl* pMsgCtrl = GetMsgControl()) {
-    return pMsgCtrl->m_pMainKeyboardWnd;
-  }
-
-  return NULL;
-}
-
-void CPWL_Wnd::EnableWindow(FX_BOOL bEnable) {
-  if (m_bEnabled != bEnable) {
-    for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
-      if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
-        pChild->EnableWindow(bEnable);
-      }
-    }
-
-    m_bEnabled = bEnable;
-
-    if (bEnable)
-      OnEnabled();
-    else
-      OnDisabled();
-  }
-}
-
-FX_BOOL CPWL_Wnd::IsEnabled() {
-  return m_bEnabled;
-}
-
-void CPWL_Wnd::OnEnabled() {}
-
-void CPWL_Wnd::OnDisabled() {}
-
-FX_BOOL CPWL_Wnd::IsCTRLpressed(FX_DWORD nFlag) const {
-  if (IFX_SystemHandler* pSystemHandler = GetSystemHandler()) {
-    return pSystemHandler->IsCTRLKeyDown(nFlag);
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CPWL_Wnd::IsSHIFTpressed(FX_DWORD nFlag) const {
-  if (IFX_SystemHandler* pSystemHandler = GetSystemHandler()) {
-    return pSystemHandler->IsSHIFTKeyDown(nFlag);
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CPWL_Wnd::IsALTpressed(FX_DWORD nFlag) const {
-  if (IFX_SystemHandler* pSystemHandler = GetSystemHandler()) {
-    return pSystemHandler->IsALTKeyDown(nFlag);
-  }
-
-  return FALSE;
-}
-
-FX_BOOL CPWL_Wnd::IsINSERTpressed(FX_DWORD nFlag) const {
-  if (IFX_SystemHandler* pSystemHandler = GetSystemHandler()) {
-    return pSystemHandler->IsINSERTKeyDown(nFlag);
-  }
-
-  return FALSE;
-}