Merge CXFA_WidgetAcc into CXFA_Node

This CL merges CXFA_WidgetAcc into CXFA_Node.

Change-Id: Iab52ca7f98c9dcd4ab089c61b8f1324a565bf647
Reviewed-on: https://pdfium-review.googlesource.com/23610
Reviewed-by: Henrique Nakashima <hnakashima@chromium.org>
Commit-Queue: dsinclair <dsinclair@chromium.org>
diff --git a/BUILD.gn b/BUILD.gn
index 3ddf167..9795f25 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -2094,8 +2094,6 @@
       "xfa/fxfa/cxfa_texttabstopscontext.h",
       "xfa/fxfa/cxfa_textuserdata.cpp",
       "xfa/fxfa/cxfa_textuserdata.h",
-      "xfa/fxfa/cxfa_widgetacc.cpp",
-      "xfa/fxfa/cxfa_widgetacc.h",
       "xfa/fxfa/fxfa.h",
       "xfa/fxfa/fxfa_basic.h",
     ]
@@ -2828,8 +2826,11 @@
       "xfa/fxfa/parser/xfa_utils.h",
     ]
     deps = [
+      ":fxcrt",
       ":fxjs",
+      ":xfa_fde",
       ":xfa_fgas",
+      ":xfa_fxfa",
     ]
     configs += [
       ":pdfium_core_config",
diff --git a/fpdfsdk/cpdfsdk_widget.cpp b/fpdfsdk/cpdfsdk_widget.cpp
index 393d119..5b89109 100644
--- a/fpdfsdk/cpdfsdk_widget.cpp
+++ b/fpdfsdk/cpdfsdk_widget.cpp
@@ -38,7 +38,6 @@
 #include "xfa/fxfa/cxfa_ffdocview.h"
 #include "xfa/fxfa/cxfa_ffwidget.h"
 #include "xfa/fxfa/cxfa_ffwidgethandler.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
 #include "xfa/fxfa/parser/cxfa_node.h"
 #endif  // PDF_ENABLE_XFA
 
diff --git a/fpdfsdk/fpdfsave.cpp b/fpdfsdk/fpdfsave.cpp
index b95850f..d12a66a 100644
--- a/fpdfsdk/fpdfsave.cpp
+++ b/fpdfsdk/fpdfsave.cpp
@@ -32,7 +32,6 @@
 #include "xfa/fxfa/cxfa_ffdocview.h"
 #include "xfa/fxfa/cxfa_ffwidgethandler.h"
 #include "xfa/fxfa/cxfa_readynodeiterator.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
 #include "xfa/fxfa/parser/cxfa_object.h"
 #endif
 
diff --git a/fxjs/xfa/cjx_boolean.cpp b/fxjs/xfa/cjx_boolean.cpp
index 6f62fcb..6abcd3c 100644
--- a/fxjs/xfa/cjx_boolean.cpp
+++ b/fxjs/xfa/cjx_boolean.cpp
@@ -7,7 +7,6 @@
 #include "fxjs/xfa/cjx_boolean.h"
 
 #include "fxjs/cfxjse_value.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
 #include "xfa/fxfa/parser/cxfa_boolean.h"
 
 CJX_Boolean::CJX_Boolean(CXFA_Boolean* node) : CJX_Content(node) {}
diff --git a/fxjs/xfa/cjx_draw.cpp b/fxjs/xfa/cjx_draw.cpp
index 9d1e76c..77d058f 100644
--- a/fxjs/xfa/cjx_draw.cpp
+++ b/fxjs/xfa/cjx_draw.cpp
@@ -7,7 +7,6 @@
 #include "fxjs/xfa/cjx_draw.h"
 
 #include "fxjs/cfxjse_value.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
 #include "xfa/fxfa/parser/cxfa_draw.h"
 
 CJX_Draw::CJX_Draw(CXFA_Draw* node) : CJX_Container(node) {}
diff --git a/fxjs/xfa/cjx_eventpseudomodel.cpp b/fxjs/xfa/cjx_eventpseudomodel.cpp
index b12e82e..3b2d977 100644
--- a/fxjs/xfa/cjx_eventpseudomodel.cpp
+++ b/fxjs/xfa/cjx_eventpseudomodel.cpp
@@ -13,7 +13,6 @@
 #include "xfa/fxfa/cxfa_eventparam.h"
 #include "xfa/fxfa/cxfa_ffnotify.h"
 #include "xfa/fxfa/cxfa_ffwidgethandler.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
 #include "xfa/fxfa/parser/cscript_eventpseudomodel.h"
 
 namespace {
diff --git a/fxjs/xfa/cjx_exclgroup.cpp b/fxjs/xfa/cjx_exclgroup.cpp
index afee17a..fbce784 100644
--- a/fxjs/xfa/cjx_exclgroup.cpp
+++ b/fxjs/xfa/cjx_exclgroup.cpp
@@ -13,7 +13,6 @@
 #include "fxjs/js_resources.h"
 #include "xfa/fxfa/cxfa_eventparam.h"
 #include "xfa/fxfa/cxfa_ffnotify.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
 #include "xfa/fxfa/fxfa.h"
 #include "xfa/fxfa/parser/cxfa_document.h"
 #include "xfa/fxfa/parser/cxfa_exclgroup.h"
diff --git a/fxjs/xfa/cjx_field.cpp b/fxjs/xfa/cjx_field.cpp
index e27f153..9433127 100644
--- a/fxjs/xfa/cjx_field.cpp
+++ b/fxjs/xfa/cjx_field.cpp
@@ -13,7 +13,6 @@
 #include "fxjs/js_resources.h"
 #include "xfa/fxfa/cxfa_eventparam.h"
 #include "xfa/fxfa/cxfa_ffnotify.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
 #include "xfa/fxfa/fxfa.h"
 #include "xfa/fxfa/parser/cxfa_document.h"
 #include "xfa/fxfa/parser/cxfa_field.h"
diff --git a/fxjs/xfa/cjx_node.cpp b/fxjs/xfa/cjx_node.cpp
index ff07545..6458a33 100644
--- a/fxjs/xfa/cjx_node.cpp
+++ b/fxjs/xfa/cjx_node.cpp
@@ -16,7 +16,6 @@
 #include "third_party/base/ptr_util.h"
 #include "xfa/fxfa/cxfa_eventparam.h"
 #include "xfa/fxfa/cxfa_ffnotify.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
 #include "xfa/fxfa/parser/cxfa_document.h"
 #include "xfa/fxfa/parser/cxfa_node.h"
 #include "xfa/fxfa/parser/cxfa_simple_parser.h"
diff --git a/fxjs/xfa/cjx_object.cpp b/fxjs/xfa/cjx_object.cpp
index 73ec3fa..0c57392 100644
--- a/fxjs/xfa/cjx_object.cpp
+++ b/fxjs/xfa/cjx_object.cpp
@@ -21,7 +21,6 @@
 #include "third_party/base/ptr_util.h"
 #include "xfa/fxfa/cxfa_ffnotify.h"
 #include "xfa/fxfa/cxfa_ffwidget.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
 #include "xfa/fxfa/parser/cxfa_border.h"
 #include "xfa/fxfa/parser/cxfa_datavalue.h"
 #include "xfa/fxfa/parser/cxfa_document.h"
diff --git a/xfa/fxfa/cxfa_ffbarcode.cpp b/xfa/fxfa/cxfa_ffbarcode.cpp
index caef3df..86b0618 100644
--- a/xfa/fxfa/cxfa_ffbarcode.cpp
+++ b/xfa/fxfa/cxfa_ffbarcode.cpp
@@ -17,7 +17,6 @@
 #include "xfa/fxfa/cxfa_ffpageview.h"
 #include "xfa/fxfa/cxfa_ffwidget.h"
 #include "xfa/fxfa/cxfa_fwladapterwidgetmgr.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
 #include "xfa/fxfa/parser/cxfa_border.h"
 
 namespace {
diff --git a/xfa/fxfa/cxfa_ffcheckbutton.h b/xfa/fxfa/cxfa_ffcheckbutton.h
index 2ee2a7d..230695f 100644
--- a/xfa/fxfa/cxfa_ffcheckbutton.h
+++ b/xfa/fxfa/cxfa_ffcheckbutton.h
@@ -9,7 +9,7 @@
 
 #include "xfa/fxfa/cxfa_fffield.h"
 #include "xfa/fxfa/cxfa_ffpageview.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
+#include "xfa/fxfa/parser/cxfa_node.h"
 
 class CXFA_FFCheckButton : public CXFA_FFField {
  public:
diff --git a/xfa/fxfa/cxfa_ffcombobox.cpp b/xfa/fxfa/cxfa_ffcombobox.cpp
index fcb8eb1..7e9a855 100644
--- a/xfa/fxfa/cxfa_ffcombobox.cpp
+++ b/xfa/fxfa/cxfa_ffcombobox.cpp
@@ -14,7 +14,6 @@
 #include "xfa/fwl/cfwl_notedriver.h"
 #include "xfa/fxfa/cxfa_eventparam.h"
 #include "xfa/fxfa/cxfa_ffdocview.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
 #include "xfa/fxfa/parser/cxfa_para.h"
 
 namespace {
diff --git a/xfa/fxfa/cxfa_fffield.cpp b/xfa/fxfa/cxfa_fffield.cpp
index 64e8e00..8ac2876 100644
--- a/xfa/fxfa/cxfa_fffield.cpp
+++ b/xfa/fxfa/cxfa_fffield.cpp
@@ -22,7 +22,6 @@
 #include "xfa/fxfa/cxfa_ffwidget.h"
 #include "xfa/fxfa/cxfa_fwltheme.h"
 #include "xfa/fxfa/cxfa_textlayout.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
 #include "xfa/fxfa/parser/cxfa_border.h"
 #include "xfa/fxfa/parser/cxfa_calculate.h"
 #include "xfa/fxfa/parser/cxfa_caption.h"
diff --git a/xfa/fxfa/cxfa_ffimage.cpp b/xfa/fxfa/cxfa_ffimage.cpp
index 608ca3c..a5a2ee7 100644
--- a/xfa/fxfa/cxfa_ffimage.cpp
+++ b/xfa/fxfa/cxfa_ffimage.cpp
@@ -6,12 +6,12 @@
 
 #include "xfa/fxfa/cxfa_ffimage.h"
 
+#include "core/fxge/dib/cfx_dibitmap.h"
 #include "xfa/fxfa/cxfa_ffapp.h"
 #include "xfa/fxfa/cxfa_ffdoc.h"
 #include "xfa/fxfa/cxfa_ffdraw.h"
 #include "xfa/fxfa/cxfa_ffpageview.h"
 #include "xfa/fxfa/cxfa_ffwidget.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
 #include "xfa/fxfa/parser/cxfa_image.h"
 #include "xfa/fxfa/parser/cxfa_para.h"
 #include "xfa/fxfa/parser/cxfa_value.h"
diff --git a/xfa/fxfa/cxfa_ffimageedit.cpp b/xfa/fxfa/cxfa_ffimageedit.cpp
index 3ef05e9..8b97c2b 100644
--- a/xfa/fxfa/cxfa_ffimageedit.cpp
+++ b/xfa/fxfa/cxfa_ffimageedit.cpp
@@ -8,6 +8,7 @@
 
 #include <utility>
 
+#include "core/fxge/dib/cfx_dibitmap.h"
 #include "third_party/base/ptr_util.h"
 #include "xfa/fwl/cfwl_app.h"
 #include "xfa/fwl/cfwl_messagemouse.h"
@@ -18,7 +19,6 @@
 #include "xfa/fxfa/cxfa_fffield.h"
 #include "xfa/fxfa/cxfa_ffpageview.h"
 #include "xfa/fxfa/cxfa_ffwidget.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
 #include "xfa/fxfa/parser/cxfa_border.h"
 #include "xfa/fxfa/parser/cxfa_image.h"
 #include "xfa/fxfa/parser/cxfa_para.h"
diff --git a/xfa/fxfa/cxfa_fflistbox.cpp b/xfa/fxfa/cxfa_fflistbox.cpp
index 12a2c8a..64fb8e5 100644
--- a/xfa/fxfa/cxfa_fflistbox.cpp
+++ b/xfa/fxfa/cxfa_fflistbox.cpp
@@ -14,7 +14,6 @@
 #include "xfa/fwl/cfwl_notedriver.h"
 #include "xfa/fwl/cfwl_widget.h"
 #include "xfa/fxfa/cxfa_eventparam.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
 #include "xfa/fxfa/parser/cxfa_para.h"
 
 namespace {
diff --git a/xfa/fxfa/cxfa_ffpasswordedit.cpp b/xfa/fxfa/cxfa_ffpasswordedit.cpp
index d639d1e..15bd5fa 100644
--- a/xfa/fxfa/cxfa_ffpasswordedit.cpp
+++ b/xfa/fxfa/cxfa_ffpasswordedit.cpp
@@ -11,7 +11,6 @@
 #include "xfa/fwl/cfwl_edit.h"
 #include "xfa/fwl/cfwl_notedriver.h"
 #include "xfa/fxfa/cxfa_ffdoc.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
 #include "xfa/fxfa/parser/cxfa_node.h"
 
 CXFA_FFPasswordEdit::CXFA_FFPasswordEdit(CXFA_Node* pNode)
diff --git a/xfa/fxfa/cxfa_ffpushbutton.cpp b/xfa/fxfa/cxfa_ffpushbutton.cpp
index ce05cf5..d4d591f 100644
--- a/xfa/fxfa/cxfa_ffpushbutton.cpp
+++ b/xfa/fxfa/cxfa_ffpushbutton.cpp
@@ -18,7 +18,6 @@
 #include "xfa/fxfa/cxfa_ffwidget.h"
 #include "xfa/fxfa/cxfa_textlayout.h"
 #include "xfa/fxfa/cxfa_textprovider.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
 #include "xfa/fxfa/parser/cxfa_border.h"
 #include "xfa/fxfa/parser/cxfa_caption.h"
 #include "xfa/fxfa/parser/cxfa_edge.h"
diff --git a/xfa/fxfa/cxfa_fftext.cpp b/xfa/fxfa/cxfa_fftext.cpp
index 0574964..7ae3cb6 100644
--- a/xfa/fxfa/cxfa_fftext.cpp
+++ b/xfa/fxfa/cxfa_fftext.cpp
@@ -17,7 +17,6 @@
 #include "xfa/fxfa/cxfa_pieceline.h"
 #include "xfa/fxfa/cxfa_textlayout.h"
 #include "xfa/fxfa/cxfa_textpiece.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
 #include "xfa/fxfa/parser/cxfa_margin.h"
 #include "xfa/fxgraphics/cxfa_graphics.h"
 
diff --git a/xfa/fxfa/cxfa_fftextedit.cpp b/xfa/fxfa/cxfa_fftextedit.cpp
index 8464aa9..89a7c901 100644
--- a/xfa/fxfa/cxfa_fftextedit.cpp
+++ b/xfa/fxfa/cxfa_fftextedit.cpp
@@ -19,7 +19,6 @@
 #include "xfa/fxfa/cxfa_eventparam.h"
 #include "xfa/fxfa/cxfa_ffapp.h"
 #include "xfa/fxfa/cxfa_ffdoc.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
 #include "xfa/fxfa/parser/cxfa_node.h"
 #include "xfa/fxfa/parser/cxfa_para.h"
 
diff --git a/xfa/fxfa/cxfa_ffwidget.cpp b/xfa/fxfa/cxfa_ffwidget.cpp
index fa3136c..c3e0d4d 100644
--- a/xfa/fxfa/cxfa_ffwidget.cpp
+++ b/xfa/fxfa/cxfa_ffwidget.cpp
@@ -25,7 +25,6 @@
 #include "xfa/fxfa/cxfa_ffdocview.h"
 #include "xfa/fxfa/cxfa_ffpageview.h"
 #include "xfa/fxfa/cxfa_imagerenderer.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
 #include "xfa/fxfa/parser/cxfa_border.h"
 #include "xfa/fxfa/parser/cxfa_box.h"
 #include "xfa/fxfa/parser/cxfa_image.h"
diff --git a/xfa/fxfa/cxfa_fwltheme.cpp b/xfa/fxfa/cxfa_fwltheme.cpp
index a3679f8..c7c521e 100644
--- a/xfa/fxfa/cxfa_fwltheme.cpp
+++ b/xfa/fxfa/cxfa_fwltheme.cpp
@@ -24,7 +24,6 @@
 #include "xfa/fwl/cfwl_themetext.h"
 #include "xfa/fxfa/cxfa_ffapp.h"
 #include "xfa/fxfa/cxfa_ffwidget.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
 #include "xfa/fxfa/parser/cxfa_para.h"
 #include "xfa/fxgraphics/cxfa_gecolor.h"
 
diff --git a/xfa/fxfa/cxfa_textprovider.cpp b/xfa/fxfa/cxfa_textprovider.cpp
index 9ea0838..d1f9256 100644
--- a/xfa/fxfa/cxfa_textprovider.cpp
+++ b/xfa/fxfa/cxfa_textprovider.cpp
@@ -28,7 +28,6 @@
 #include "xfa/fxfa/cxfa_ffwidget.h"
 #include "xfa/fxfa/cxfa_fontmgr.h"
 #include "xfa/fxfa/cxfa_fwladapterwidgetmgr.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
 #include "xfa/fxfa/parser/cxfa_caption.h"
 #include "xfa/fxfa/parser/cxfa_font.h"
 #include "xfa/fxfa/parser/cxfa_items.h"
diff --git a/xfa/fxfa/cxfa_widgetacc.cpp b/xfa/fxfa/cxfa_widgetacc.cpp
deleted file mode 100644
index 0e73dfb..0000000
--- a/xfa/fxfa/cxfa_widgetacc.cpp
+++ /dev/null
@@ -1,2500 +0,0 @@
-// 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 "xfa/fxfa/cxfa_widgetacc.h"
-
-#include <algorithm>
-#include <tuple>
-#include <vector>
-
-#include "core/fxcrt/cfx_decimal.h"
-#include "core/fxcrt/cfx_memorystream.h"
-#include "core/fxcrt/fx_extension.h"
-#include "core/fxcrt/xml/cfx_xmlelement.h"
-#include "core/fxcrt/xml/cfx_xmlnode.h"
-#include "fxjs/cfxjse_engine.h"
-#include "fxjs/xfa/cjx_object.h"
-#include "third_party/base/stl_util.h"
-#include "xfa/fde/cfde_textout.h"
-#include "xfa/fxfa/cxfa_ffapp.h"
-#include "xfa/fxfa/cxfa_ffdoc.h"
-#include "xfa/fxfa/cxfa_ffdocview.h"
-#include "xfa/fxfa/cxfa_ffnotify.h"
-#include "xfa/fxfa/cxfa_ffwidget.h"
-#include "xfa/fxfa/cxfa_fontmgr.h"
-#include "xfa/fxfa/cxfa_textlayout.h"
-#include "xfa/fxfa/cxfa_textprovider.h"
-#include "xfa/fxfa/parser/cxfa_bind.h"
-#include "xfa/fxfa/parser/cxfa_border.h"
-#include "xfa/fxfa/parser/cxfa_calculate.h"
-#include "xfa/fxfa/parser/cxfa_caption.h"
-#include "xfa/fxfa/parser/cxfa_comb.h"
-#include "xfa/fxfa/parser/cxfa_decimal.h"
-#include "xfa/fxfa/parser/cxfa_document.h"
-#include "xfa/fxfa/parser/cxfa_event.h"
-#include "xfa/fxfa/parser/cxfa_font.h"
-#include "xfa/fxfa/parser/cxfa_format.h"
-#include "xfa/fxfa/parser/cxfa_image.h"
-#include "xfa/fxfa/parser/cxfa_items.h"
-#include "xfa/fxfa/parser/cxfa_layoutprocessor.h"
-#include "xfa/fxfa/parser/cxfa_localevalue.h"
-#include "xfa/fxfa/parser/cxfa_margin.h"
-#include "xfa/fxfa/parser/cxfa_measurement.h"
-#include "xfa/fxfa/parser/cxfa_node.h"
-#include "xfa/fxfa/parser/cxfa_para.h"
-#include "xfa/fxfa/parser/cxfa_picture.h"
-#include "xfa/fxfa/parser/cxfa_script.h"
-#include "xfa/fxfa/parser/cxfa_stroke.h"
-#include "xfa/fxfa/parser/cxfa_ui.h"
-#include "xfa/fxfa/parser/cxfa_validate.h"
-#include "xfa/fxfa/parser/cxfa_value.h"
-#include "xfa/fxfa/parser/xfa_utils.h"
-
-class CXFA_WidgetLayoutData {
- public:
-  CXFA_WidgetLayoutData() : m_fWidgetHeight(-1) {}
-  virtual ~CXFA_WidgetLayoutData() {}
-
-  float m_fWidgetHeight;
-};
-
-namespace {
-
-constexpr uint8_t g_inv_base64[128] = {
-    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62,  255,
-    255, 255, 63,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  255, 255,
-    255, 255, 255, 255, 255, 0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
-    10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,
-    25,  255, 255, 255, 255, 255, 255, 26,  27,  28,  29,  30,  31,  32,  33,
-    34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48,
-    49,  50,  51,  255, 255, 255, 255, 255,
-};
-
-uint8_t* XFA_RemoveBase64Whitespace(const uint8_t* pStr, int32_t iLen) {
-  uint8_t* pCP;
-  int32_t i = 0, j = 0;
-  if (iLen == 0) {
-    iLen = strlen((char*)pStr);
-  }
-  pCP = FX_Alloc(uint8_t, iLen + 1);
-  for (; i < iLen; i++) {
-    if ((pStr[i] & 128) == 0) {
-      if (g_inv_base64[pStr[i]] != 0xFF || pStr[i] == '=') {
-        pCP[j++] = pStr[i];
-      }
-    }
-  }
-  pCP[j] = '\0';
-  return pCP;
-}
-
-int32_t XFA_Base64Decode(const char* pStr, uint8_t* pOutBuffer) {
-  if (!pStr) {
-    return 0;
-  }
-  uint8_t* pBuffer =
-      XFA_RemoveBase64Whitespace((uint8_t*)pStr, strlen((char*)pStr));
-  if (!pBuffer) {
-    return 0;
-  }
-  int32_t iLen = strlen((char*)pBuffer);
-  int32_t i = 0, j = 0;
-  uint32_t dwLimb = 0;
-  for (; i + 3 < iLen; i += 4) {
-    if (pBuffer[i] == '=' || pBuffer[i + 1] == '=' || pBuffer[i + 2] == '=' ||
-        pBuffer[i + 3] == '=') {
-      if (pBuffer[i] == '=' || pBuffer[i + 1] == '=') {
-        break;
-      }
-      if (pBuffer[i + 2] == '=') {
-        dwLimb = ((uint32_t)g_inv_base64[pBuffer[i]] << 6) |
-                 ((uint32_t)g_inv_base64[pBuffer[i + 1]]);
-        pOutBuffer[j] = (uint8_t)(dwLimb >> 4) & 0xFF;
-        j++;
-      } else {
-        dwLimb = ((uint32_t)g_inv_base64[pBuffer[i]] << 12) |
-                 ((uint32_t)g_inv_base64[pBuffer[i + 1]] << 6) |
-                 ((uint32_t)g_inv_base64[pBuffer[i + 2]]);
-        pOutBuffer[j] = (uint8_t)(dwLimb >> 10) & 0xFF;
-        pOutBuffer[j + 1] = (uint8_t)(dwLimb >> 2) & 0xFF;
-        j += 2;
-      }
-    } else {
-      dwLimb = ((uint32_t)g_inv_base64[pBuffer[i]] << 18) |
-               ((uint32_t)g_inv_base64[pBuffer[i + 1]] << 12) |
-               ((uint32_t)g_inv_base64[pBuffer[i + 2]] << 6) |
-               ((uint32_t)g_inv_base64[pBuffer[i + 3]]);
-      pOutBuffer[j] = (uint8_t)(dwLimb >> 16) & 0xff;
-      pOutBuffer[j + 1] = (uint8_t)(dwLimb >> 8) & 0xff;
-      pOutBuffer[j + 2] = (uint8_t)(dwLimb)&0xff;
-      j += 3;
-    }
-  }
-  FX_Free(pBuffer);
-  return j;
-}
-
-FXCODEC_IMAGE_TYPE XFA_GetImageType(const WideString& wsType) {
-  WideString wsContentType(wsType);
-  wsContentType.MakeLower();
-  if (wsContentType == L"image/jpg")
-    return FXCODEC_IMAGE_JPG;
-  if (wsContentType == L"image/png")
-    return FXCODEC_IMAGE_PNG;
-  if (wsContentType == L"image/gif")
-    return FXCODEC_IMAGE_GIF;
-  if (wsContentType == L"image/bmp")
-    return FXCODEC_IMAGE_BMP;
-  if (wsContentType == L"image/tif")
-    return FXCODEC_IMAGE_TIF;
-  return FXCODEC_IMAGE_UNKNOWN;
-}
-
-RetainPtr<CFX_DIBitmap> XFA_LoadImageData(CXFA_FFDoc* pDoc,
-                                          CXFA_Image* pImage,
-                                          bool& bNameImage,
-                                          int32_t& iImageXDpi,
-                                          int32_t& iImageYDpi) {
-  WideString wsHref = pImage->GetHref();
-  WideString wsImage = pImage->GetContent();
-  if (wsHref.IsEmpty() && wsImage.IsEmpty())
-    return nullptr;
-
-  FXCODEC_IMAGE_TYPE type = XFA_GetImageType(pImage->GetContentType());
-  ByteString bsContent;
-  uint8_t* pImageBuffer = nullptr;
-  RetainPtr<IFX_SeekableReadStream> pImageFileRead;
-  if (wsImage.GetLength() > 0) {
-    XFA_AttributeEnum iEncoding = pImage->GetTransferEncoding();
-    if (iEncoding == XFA_AttributeEnum::Base64) {
-      ByteString bsData = wsImage.UTF8Encode();
-      int32_t iLength = bsData.GetLength();
-      pImageBuffer = FX_Alloc(uint8_t, iLength);
-      int32_t iRead = XFA_Base64Decode(bsData.c_str(), pImageBuffer);
-      if (iRead > 0) {
-        pImageFileRead =
-            pdfium::MakeRetain<CFX_MemoryStream>(pImageBuffer, iRead, false);
-      }
-    } else {
-      bsContent = ByteString::FromUnicode(wsImage);
-      pImageFileRead = pdfium::MakeRetain<CFX_MemoryStream>(
-          const_cast<uint8_t*>(bsContent.raw_str()), bsContent.GetLength(),
-          false);
-    }
-  } else {
-    WideString wsURL = wsHref;
-    if (wsURL.Left(7) != L"http://" && wsURL.Left(6) != L"ftp://") {
-      RetainPtr<CFX_DIBitmap> pBitmap =
-          pDoc->GetPDFNamedImage(wsURL.AsStringView(), iImageXDpi, iImageYDpi);
-      if (pBitmap) {
-        bNameImage = true;
-        return pBitmap;
-      }
-    }
-    pImageFileRead = pDoc->GetDocEnvironment()->OpenLinkedFile(pDoc, wsURL);
-  }
-  if (!pImageFileRead) {
-    FX_Free(pImageBuffer);
-    return nullptr;
-  }
-  bNameImage = false;
-  RetainPtr<CFX_DIBitmap> pBitmap =
-      XFA_LoadImageFromBuffer(pImageFileRead, type, iImageXDpi, iImageYDpi);
-  FX_Free(pImageBuffer);
-  return pBitmap;
-}
-
-class CXFA_TextLayoutData : public CXFA_WidgetLayoutData {
- public:
-  CXFA_TextLayoutData() {}
-  ~CXFA_TextLayoutData() override {}
-
-  CXFA_TextLayout* GetTextLayout() const { return m_pTextLayout.get(); }
-  CXFA_TextProvider* GetTextProvider() const { return m_pTextProvider.get(); }
-
-  void LoadText(CXFA_FFDoc* doc, CXFA_WidgetAcc* pAcc) {
-    if (m_pTextLayout)
-      return;
-
-    m_pTextProvider = pdfium::MakeUnique<CXFA_TextProvider>(
-        pAcc->GetNode(), XFA_TEXTPROVIDERTYPE_Text);
-    m_pTextLayout =
-        pdfium::MakeUnique<CXFA_TextLayout>(doc, m_pTextProvider.get());
-  }
-
- private:
-  std::unique_ptr<CXFA_TextLayout> m_pTextLayout;
-  std::unique_ptr<CXFA_TextProvider> m_pTextProvider;
-};
-
-class CXFA_ImageLayoutData : public CXFA_WidgetLayoutData {
- public:
-  CXFA_ImageLayoutData()
-      : m_bNamedImage(false), m_iImageXDpi(0), m_iImageYDpi(0) {}
-
-  ~CXFA_ImageLayoutData() override {}
-
-  bool LoadImageData(CXFA_FFDoc* doc, CXFA_WidgetAcc* pAcc) {
-    if (m_pDIBitmap)
-      return true;
-
-    CXFA_Value* value = pAcc->GetNode()->GetFormValueIfExists();
-    if (!value)
-      return false;
-
-    CXFA_Image* image = value->GetImageIfExists();
-    if (!image)
-      return false;
-
-    pAcc->SetImageImage(XFA_LoadImageData(doc, image, m_bNamedImage,
-                                          m_iImageXDpi, m_iImageYDpi));
-    return !!m_pDIBitmap;
-  }
-
-  RetainPtr<CFX_DIBitmap> m_pDIBitmap;
-  bool m_bNamedImage;
-  int32_t m_iImageXDpi;
-  int32_t m_iImageYDpi;
-};
-
-class CXFA_FieldLayoutData : public CXFA_WidgetLayoutData {
- public:
-  CXFA_FieldLayoutData() {}
-  ~CXFA_FieldLayoutData() override {}
-
-  bool LoadCaption(CXFA_FFDoc* doc, CXFA_WidgetAcc* pAcc) {
-    if (m_pCapTextLayout)
-      return true;
-    CXFA_Caption* caption = pAcc->GetNode()->GetCaptionIfExists();
-    if (!caption || caption->IsHidden())
-      return false;
-
-    m_pCapTextProvider = pdfium::MakeUnique<CXFA_TextProvider>(
-        pAcc->GetNode(), XFA_TEXTPROVIDERTYPE_Caption);
-    m_pCapTextLayout =
-        pdfium::MakeUnique<CXFA_TextLayout>(doc, m_pCapTextProvider.get());
-    return true;
-  }
-
-  std::unique_ptr<CXFA_TextLayout> m_pCapTextLayout;
-  std::unique_ptr<CXFA_TextProvider> m_pCapTextProvider;
-  std::unique_ptr<CFDE_TextOut> m_pTextOut;
-  std::vector<float> m_FieldSplitArray;
-};
-
-class CXFA_TextEditData : public CXFA_FieldLayoutData {};
-
-class CXFA_ImageEditData : public CXFA_FieldLayoutData {
- public:
-  CXFA_ImageEditData()
-      : m_bNamedImage(false), m_iImageXDpi(0), m_iImageYDpi(0) {}
-
-  ~CXFA_ImageEditData() override {}
-
-  bool LoadImageData(CXFA_FFDoc* doc, CXFA_WidgetAcc* pAcc) {
-    if (m_pDIBitmap)
-      return true;
-
-    CXFA_Value* value = pAcc->GetNode()->GetFormValueIfExists();
-    if (!value)
-      return false;
-
-    CXFA_Image* image = value->GetImageIfExists();
-    if (!image)
-      return false;
-
-    pAcc->SetImageEditImage(XFA_LoadImageData(doc, image, m_bNamedImage,
-                                              m_iImageXDpi, m_iImageYDpi));
-    return !!m_pDIBitmap;
-  }
-
-  RetainPtr<CFX_DIBitmap> m_pDIBitmap;
-  bool m_bNamedImage;
-  int32_t m_iImageXDpi;
-  int32_t m_iImageYDpi;
-};
-
-bool SplitDateTime(const WideString& wsDateTime,
-                   WideString& wsDate,
-                   WideString& wsTime) {
-  wsDate = L"";
-  wsTime = L"";
-  if (wsDateTime.IsEmpty())
-    return false;
-
-  auto nSplitIndex = wsDateTime.Find('T');
-  if (!nSplitIndex.has_value())
-    nSplitIndex = wsDateTime.Find(' ');
-  if (!nSplitIndex.has_value())
-    return false;
-
-  wsDate = wsDateTime.Left(nSplitIndex.value());
-  if (!wsDate.IsEmpty()) {
-    if (!std::any_of(wsDate.begin(), wsDate.end(), std::iswdigit))
-      return false;
-  }
-  wsTime = wsDateTime.Right(wsDateTime.GetLength() - nSplitIndex.value() - 1);
-  if (!wsTime.IsEmpty()) {
-    if (!std::any_of(wsTime.begin(), wsTime.end(), std::iswdigit))
-      return false;
-  }
-  return true;
-}
-
-}  // namespace
-
-CXFA_WidgetAcc::CXFA_WidgetAcc(CXFA_Node* pNode) : m_pNode(pNode) {
-  ASSERT(m_pNode);
-}
-
-CXFA_WidgetAcc::~CXFA_WidgetAcc() = default;
-
-void CXFA_WidgetAcc::ResetData() {
-  WideString wsValue;
-  switch (m_pNode->GetUIType()) {
-    case XFA_Element::ImageEdit: {
-      CXFA_Value* imageValue = m_pNode->GetDefaultValueIfExists();
-      CXFA_Image* image = imageValue ? imageValue->GetImageIfExists() : nullptr;
-      WideString wsContentType, wsHref;
-      if (image) {
-        wsValue = image->GetContent();
-        wsContentType = image->GetContentType();
-        wsHref = image->GetHref();
-      }
-      SetImageEdit(wsContentType, wsHref, wsValue);
-      break;
-    }
-    case XFA_Element::ExclGroup: {
-      CXFA_Node* pNextChild = m_pNode->GetFirstContainerChild();
-      while (pNextChild) {
-        CXFA_Node* pChild = pNextChild;
-        if (!pChild->IsWidgetReady())
-          continue;
-
-        CXFA_WidgetAcc* pAcc = pChild->GetWidgetAcc();
-        bool done = false;
-        if (wsValue.IsEmpty()) {
-          CXFA_Value* defValue = pAcc->GetNode()->GetDefaultValueIfExists();
-          if (defValue) {
-            wsValue = defValue->GetChildValueContent();
-            SetValue(XFA_VALUEPICTURE_Raw, wsValue);
-            pAcc->SetValue(XFA_VALUEPICTURE_Raw, wsValue);
-            done = true;
-          }
-        }
-        if (!done) {
-          CXFA_Items* pItems =
-              pChild->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
-          if (!pItems)
-            continue;
-
-          WideString itemText;
-          if (pItems->CountChildren(XFA_Element::Unknown, false) > 1) {
-            itemText =
-                pItems->GetChild<CXFA_Node>(1, XFA_Element::Unknown, false)
-                    ->JSObject()
-                    ->GetContent(false);
-          }
-          pAcc->SetValue(XFA_VALUEPICTURE_Raw, itemText);
-        }
-        pNextChild = pChild->GetNextContainerSibling();
-      }
-      break;
-    }
-    case XFA_Element::ChoiceList:
-      ClearAllSelections();
-    default: {
-      CXFA_Value* defValue = m_pNode->GetDefaultValueIfExists();
-      if (defValue)
-        wsValue = defValue->GetChildValueContent();
-
-      SetValue(XFA_VALUEPICTURE_Raw, wsValue);
-      break;
-    }
-  }
-}
-
-void CXFA_WidgetAcc::SetImageEdit(const WideString& wsContentType,
-                                  const WideString& wsHref,
-                                  const WideString& wsData) {
-  CXFA_Value* formValue = m_pNode->GetFormValueIfExists();
-  CXFA_Image* image = formValue ? formValue->GetImageIfExists() : nullptr;
-  if (image) {
-    image->SetContentType(WideString(wsContentType));
-    image->SetHref(wsHref);
-  }
-
-  m_pNode->JSObject()->SetContent(wsData, GetFormatDataValue(wsData), true,
-                                  false, true);
-
-  CXFA_Node* pBind = m_pNode->GetBindData();
-  if (!pBind) {
-    if (image)
-      image->SetTransferEncoding(XFA_AttributeEnum::Base64);
-    return;
-  }
-  pBind->JSObject()->SetCData(XFA_Attribute::ContentType, wsContentType, false,
-                              false);
-  CXFA_Node* pHrefNode = pBind->GetFirstChild();
-  if (pHrefNode) {
-    pHrefNode->JSObject()->SetCData(XFA_Attribute::Value, wsHref, false, false);
-  } else {
-    CFX_XMLNode* pXMLNode = pBind->GetXMLMappingNode();
-    ASSERT(pXMLNode && pXMLNode->GetType() == FX_XMLNODE_Element);
-    static_cast<CFX_XMLElement*>(pXMLNode)->SetString(L"href", wsHref);
-  }
-}
-
-CXFA_FFWidget* CXFA_WidgetAcc::GetNextWidget(CXFA_FFWidget* pWidget) {
-  return static_cast<CXFA_FFWidget*>(pWidget->GetNext());
-}
-
-void CXFA_WidgetAcc::UpdateUIDisplay(CXFA_FFDocView* docView,
-                                     CXFA_FFWidget* pExcept) {
-  CXFA_FFWidget* pWidget = docView->GetWidgetForNode(m_pNode);
-  for (; pWidget; pWidget = GetNextWidget(pWidget)) {
-    if (pWidget == pExcept || !pWidget->IsLoaded() ||
-        (m_pNode->GetUIType() != XFA_Element::CheckButton &&
-         pWidget->IsFocused())) {
-      continue;
-    }
-    pWidget->UpdateFWLData();
-    pWidget->AddInvalidateRect();
-  }
-}
-
-void CXFA_WidgetAcc::CalcCaptionSize(CXFA_FFDoc* doc, CFX_SizeF& szCap) {
-  CXFA_Caption* caption = m_pNode->GetCaptionIfExists();
-  if (!caption || !caption->IsVisible())
-    return;
-
-  LoadCaption(doc);
-
-  XFA_Element eUIType = m_pNode->GetUIType();
-  XFA_AttributeEnum iCapPlacement = caption->GetPlacementType();
-  float fCapReserve = caption->GetReserve();
-  const bool bVert = iCapPlacement == XFA_AttributeEnum::Top ||
-                     iCapPlacement == XFA_AttributeEnum::Bottom;
-  const bool bReserveExit = fCapReserve > 0.01;
-  CXFA_TextLayout* pCapTextLayout =
-      static_cast<CXFA_FieldLayoutData*>(m_pLayoutData.get())
-          ->m_pCapTextLayout.get();
-  if (pCapTextLayout) {
-    if (!bVert && eUIType != XFA_Element::Button)
-      szCap.width = fCapReserve;
-
-    CFX_SizeF minSize;
-    szCap = pCapTextLayout->CalcSize(minSize, szCap);
-    if (bReserveExit)
-      bVert ? szCap.height = fCapReserve : szCap.width = fCapReserve;
-  } else {
-    float fFontSize = 10.0f;
-    CXFA_Font* font = caption->GetFontIfExists();
-    if (font) {
-      fFontSize = font->GetFontSize();
-    } else {
-      CXFA_Font* widgetfont = m_pNode->GetFontIfExists();
-      if (widgetfont)
-        fFontSize = widgetfont->GetFontSize();
-    }
-
-    if (bVert) {
-      szCap.height = fCapReserve > 0 ? fCapReserve : fFontSize;
-    } else {
-      szCap.width = fCapReserve > 0 ? fCapReserve : 0;
-      szCap.height = fFontSize;
-    }
-  }
-
-  CXFA_Margin* captionMargin = caption->GetMarginIfExists();
-  if (!captionMargin)
-    return;
-
-  float fLeftInset = captionMargin->GetLeftInset();
-  float fTopInset = captionMargin->GetTopInset();
-  float fRightInset = captionMargin->GetRightInset();
-  float fBottomInset = captionMargin->GetBottomInset();
-  if (bReserveExit) {
-    bVert ? (szCap.width += fLeftInset + fRightInset)
-          : (szCap.height += fTopInset + fBottomInset);
-  } else {
-    szCap.width += fLeftInset + fRightInset;
-    szCap.height += fTopInset + fBottomInset;
-  }
-}
-
-bool CXFA_WidgetAcc::CalculateFieldAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size) {
-  CFX_SizeF szCap;
-  CalcCaptionSize(doc, szCap);
-
-  CFX_RectF rtUIMargin = m_pNode->GetUIMargin();
-  size.width += rtUIMargin.left + rtUIMargin.width;
-  size.height += rtUIMargin.top + rtUIMargin.height;
-  if (szCap.width > 0 && szCap.height > 0) {
-    CXFA_Caption* caption = m_pNode->GetCaptionIfExists();
-    XFA_AttributeEnum placement = caption ? caption->GetPlacementType()
-                                          : CXFA_Caption::kDefaultPlacementType;
-    switch (placement) {
-      case XFA_AttributeEnum::Left:
-      case XFA_AttributeEnum::Right:
-      case XFA_AttributeEnum::Inline: {
-        size.width += szCap.width;
-        size.height = std::max(size.height, szCap.height);
-      } break;
-      case XFA_AttributeEnum::Top:
-      case XFA_AttributeEnum::Bottom: {
-        size.height += szCap.height;
-        size.width = std::max(size.width, szCap.width);
-      }
-      default:
-        break;
-    }
-  }
-  return CalculateWidgetAutoSize(size);
-}
-
-bool CXFA_WidgetAcc::CalculateWidgetAutoSize(CFX_SizeF& size) {
-  CXFA_Margin* margin = m_pNode->GetMarginIfExists();
-  if (margin) {
-    size.width += margin->GetLeftInset() + margin->GetRightInset();
-    size.height += margin->GetTopInset() + margin->GetBottomInset();
-  }
-
-  CXFA_Para* para = m_pNode->GetParaIfExists();
-  if (para)
-    size.width += para->GetMarginLeft() + para->GetTextIndent();
-
-  Optional<float> width = m_pNode->TryWidth();
-  if (width) {
-    size.width = *width;
-  } else {
-    Optional<float> min = m_pNode->TryMinWidth();
-    if (min)
-      size.width = std::max(size.width, *min);
-
-    Optional<float> max = m_pNode->TryMaxWidth();
-    if (max && *max > 0)
-      size.width = std::min(size.width, *max);
-  }
-
-  Optional<float> height = m_pNode->TryHeight();
-  if (height) {
-    size.height = *height;
-  } else {
-    Optional<float> min = m_pNode->TryMinHeight();
-    if (min)
-      size.height = std::max(size.height, *min);
-
-    Optional<float> max = m_pNode->TryMaxHeight();
-    if (max && *max > 0)
-      size.height = std::min(size.height, *max);
-  }
-  return true;
-}
-
-void CXFA_WidgetAcc::CalculateTextContentSize(CXFA_FFDoc* doc,
-                                              CFX_SizeF& size) {
-  float fFontSize = m_pNode->GetFontSize();
-  WideString wsText = GetValue(XFA_VALUEPICTURE_Display);
-  if (wsText.IsEmpty()) {
-    size.height += fFontSize;
-    return;
-  }
-
-  wchar_t wcEnter = '\n';
-  wchar_t wsLast = wsText[wsText.GetLength() - 1];
-  if (wsLast == wcEnter)
-    wsText = wsText + wcEnter;
-
-  CXFA_FieldLayoutData* layoutData =
-      static_cast<CXFA_FieldLayoutData*>(m_pLayoutData.get());
-  if (!layoutData->m_pTextOut) {
-    layoutData->m_pTextOut = pdfium::MakeUnique<CFDE_TextOut>();
-    CFDE_TextOut* pTextOut = layoutData->m_pTextOut.get();
-    pTextOut->SetFont(GetFDEFont(doc));
-    pTextOut->SetFontSize(fFontSize);
-    pTextOut->SetLineBreakTolerance(fFontSize * 0.2f);
-    pTextOut->SetLineSpace(m_pNode->GetLineHeight());
-
-    FDE_TextStyle dwStyles;
-    dwStyles.last_line_height_ = true;
-    if (m_pNode->GetUIType() == XFA_Element::TextEdit && IsMultiLine())
-      dwStyles.line_wrap_ = true;
-
-    pTextOut->SetStyles(dwStyles);
-  }
-  layoutData->m_pTextOut->CalcLogicSize(wsText, size);
-}
-
-bool CXFA_WidgetAcc::CalculateTextEditAutoSize(CXFA_FFDoc* doc,
-                                               CFX_SizeF& size) {
-  if (size.width > 0) {
-    CFX_SizeF szOrz = size;
-    CFX_SizeF szCap;
-    CalcCaptionSize(doc, szCap);
-    bool bCapExit = szCap.width > 0.01 && szCap.height > 0.01;
-    XFA_AttributeEnum iCapPlacement = XFA_AttributeEnum::Unknown;
-    if (bCapExit) {
-      CXFA_Caption* caption = m_pNode->GetCaptionIfExists();
-      iCapPlacement = caption ? caption->GetPlacementType()
-                              : CXFA_Caption::kDefaultPlacementType;
-      switch (iCapPlacement) {
-        case XFA_AttributeEnum::Left:
-        case XFA_AttributeEnum::Right:
-        case XFA_AttributeEnum::Inline: {
-          size.width -= szCap.width;
-        }
-        default:
-          break;
-      }
-    }
-    CFX_RectF rtUIMargin = m_pNode->GetUIMargin();
-    size.width -= rtUIMargin.left + rtUIMargin.width;
-    CXFA_Margin* margin = m_pNode->GetMarginIfExists();
-    if (margin)
-      size.width -= margin->GetLeftInset() + margin->GetRightInset();
-
-    CalculateTextContentSize(doc, size);
-    size.height += rtUIMargin.top + rtUIMargin.height;
-    if (bCapExit) {
-      switch (iCapPlacement) {
-        case XFA_AttributeEnum::Left:
-        case XFA_AttributeEnum::Right:
-        case XFA_AttributeEnum::Inline: {
-          size.height = std::max(size.height, szCap.height);
-        } break;
-        case XFA_AttributeEnum::Top:
-        case XFA_AttributeEnum::Bottom: {
-          size.height += szCap.height;
-        }
-        default:
-          break;
-      }
-    }
-    size.width = szOrz.width;
-    return CalculateWidgetAutoSize(size);
-  }
-  CalculateTextContentSize(doc, size);
-  return CalculateFieldAutoSize(doc, size);
-}
-
-bool CXFA_WidgetAcc::CalculateCheckButtonAutoSize(CXFA_FFDoc* doc,
-                                                  CFX_SizeF& size) {
-  float fCheckSize = GetCheckButtonSize();
-  size = CFX_SizeF(fCheckSize, fCheckSize);
-  return CalculateFieldAutoSize(doc, size);
-}
-
-bool CXFA_WidgetAcc::CalculatePushButtonAutoSize(CXFA_FFDoc* doc,
-                                                 CFX_SizeF& size) {
-  CalcCaptionSize(doc, size);
-  return CalculateWidgetAutoSize(size);
-}
-
-CFX_SizeF CXFA_WidgetAcc::CalculateImageSize(float img_width,
-                                             float img_height,
-                                             float dpi_x,
-                                             float dpi_y) {
-  CFX_RectF rtImage(0, 0, XFA_UnitPx2Pt(img_width, dpi_x),
-                    XFA_UnitPx2Pt(img_height, dpi_y));
-
-  CFX_RectF rtFit;
-  Optional<float> width = m_pNode->TryWidth();
-  if (width) {
-    rtFit.width = *width;
-    GetWidthWithoutMargin(rtFit.width);
-  } else {
-    rtFit.width = rtImage.width;
-  }
-
-  Optional<float> height = m_pNode->TryHeight();
-  if (height) {
-    rtFit.height = *height;
-    GetHeightWithoutMargin(rtFit.height);
-  } else {
-    rtFit.height = rtImage.height;
-  }
-
-  return rtFit.Size();
-}
-
-bool CXFA_WidgetAcc::CalculateImageAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size) {
-  if (!GetImageImage())
-    LoadImageImage(doc);
-
-  size.clear();
-  RetainPtr<CFX_DIBitmap> pBitmap = GetImageImage();
-  if (!pBitmap)
-    return CalculateWidgetAutoSize(size);
-
-  int32_t iImageXDpi = 0;
-  int32_t iImageYDpi = 0;
-  GetImageDpi(iImageXDpi, iImageYDpi);
-
-  size = CalculateImageSize(pBitmap->GetWidth(), pBitmap->GetHeight(),
-                            iImageXDpi, iImageYDpi);
-  return CalculateWidgetAutoSize(size);
-}
-
-bool CXFA_WidgetAcc::CalculateImageEditAutoSize(CXFA_FFDoc* doc,
-                                                CFX_SizeF& size) {
-  if (!GetImageEditImage())
-    LoadImageEditImage(doc);
-
-  size.clear();
-  RetainPtr<CFX_DIBitmap> pBitmap = GetImageEditImage();
-  if (!pBitmap)
-    return CalculateFieldAutoSize(doc, size);
-
-  int32_t iImageXDpi = 0;
-  int32_t iImageYDpi = 0;
-  GetImageEditDpi(iImageXDpi, iImageYDpi);
-
-  size = CalculateImageSize(pBitmap->GetWidth(), pBitmap->GetHeight(),
-                            iImageXDpi, iImageYDpi);
-  return CalculateFieldAutoSize(doc, size);
-}
-
-bool CXFA_WidgetAcc::LoadImageImage(CXFA_FFDoc* doc) {
-  InitLayoutData();
-  return static_cast<CXFA_ImageLayoutData*>(m_pLayoutData.get())
-      ->LoadImageData(doc, this);
-}
-
-bool CXFA_WidgetAcc::LoadImageEditImage(CXFA_FFDoc* doc) {
-  InitLayoutData();
-  return static_cast<CXFA_ImageEditData*>(m_pLayoutData.get())
-      ->LoadImageData(doc, this);
-}
-
-void CXFA_WidgetAcc::GetImageDpi(int32_t& iImageXDpi, int32_t& iImageYDpi) {
-  CXFA_ImageLayoutData* pData =
-      static_cast<CXFA_ImageLayoutData*>(m_pLayoutData.get());
-  iImageXDpi = pData->m_iImageXDpi;
-  iImageYDpi = pData->m_iImageYDpi;
-}
-
-void CXFA_WidgetAcc::GetImageEditDpi(int32_t& iImageXDpi, int32_t& iImageYDpi) {
-  CXFA_ImageEditData* pData =
-      static_cast<CXFA_ImageEditData*>(m_pLayoutData.get());
-  iImageXDpi = pData->m_iImageXDpi;
-  iImageYDpi = pData->m_iImageYDpi;
-}
-
-void CXFA_WidgetAcc::LoadText(CXFA_FFDoc* doc) {
-  InitLayoutData();
-  static_cast<CXFA_TextLayoutData*>(m_pLayoutData.get())->LoadText(doc, this);
-}
-
-float CXFA_WidgetAcc::CalculateWidgetAutoWidth(float fWidthCalc) {
-  CXFA_Margin* margin = m_pNode->GetMarginIfExists();
-  if (margin)
-    fWidthCalc += margin->GetLeftInset() + margin->GetRightInset();
-
-  Optional<float> min = m_pNode->TryMinWidth();
-  if (min)
-    fWidthCalc = std::max(fWidthCalc, *min);
-
-  Optional<float> max = m_pNode->TryMaxWidth();
-  if (max && *max > 0)
-    fWidthCalc = std::min(fWidthCalc, *max);
-
-  return fWidthCalc;
-}
-
-float CXFA_WidgetAcc::GetWidthWithoutMargin(float fWidthCalc) {
-  CXFA_Margin* margin = m_pNode->GetMarginIfExists();
-  if (margin)
-    fWidthCalc -= margin->GetLeftInset() + margin->GetRightInset();
-  return fWidthCalc;
-}
-
-float CXFA_WidgetAcc::CalculateWidgetAutoHeight(float fHeightCalc) {
-  CXFA_Margin* margin = m_pNode->GetMarginIfExists();
-  if (margin)
-    fHeightCalc += margin->GetTopInset() + margin->GetBottomInset();
-
-  Optional<float> min = m_pNode->TryMinHeight();
-  if (min)
-    fHeightCalc = std::max(fHeightCalc, *min);
-
-  Optional<float> max = m_pNode->TryMaxHeight();
-  if (max && *max > 0)
-    fHeightCalc = std::min(fHeightCalc, *max);
-
-  return fHeightCalc;
-}
-
-float CXFA_WidgetAcc::GetHeightWithoutMargin(float fHeightCalc) {
-  CXFA_Margin* margin = m_pNode->GetMarginIfExists();
-  if (margin)
-    fHeightCalc -= margin->GetTopInset() + margin->GetBottomInset();
-  return fHeightCalc;
-}
-
-void CXFA_WidgetAcc::StartWidgetLayout(CXFA_FFDoc* doc,
-                                       float& fCalcWidth,
-                                       float& fCalcHeight) {
-  InitLayoutData();
-
-  XFA_Element eUIType = m_pNode->GetUIType();
-  if (eUIType == XFA_Element::Text) {
-    m_pLayoutData->m_fWidgetHeight = m_pNode->TryHeight().value_or(-1);
-    StartTextLayout(doc, fCalcWidth, fCalcHeight);
-    return;
-  }
-  if (fCalcWidth > 0 && fCalcHeight > 0)
-    return;
-
-  m_pLayoutData->m_fWidgetHeight = -1;
-  float fWidth = 0;
-  if (fCalcWidth > 0 && fCalcHeight < 0) {
-    Optional<float> height = m_pNode->TryHeight();
-    if (height)
-      fCalcHeight = *height;
-    else
-      CalculateAccWidthAndHeight(doc, eUIType, fCalcWidth, fCalcHeight);
-
-    m_pLayoutData->m_fWidgetHeight = fCalcHeight;
-    return;
-  }
-  if (fCalcWidth < 0 && fCalcHeight < 0) {
-    Optional<float> height;
-    Optional<float> width = m_pNode->TryWidth();
-    if (width) {
-      fWidth = *width;
-
-      height = m_pNode->TryHeight();
-      if (height)
-        fCalcHeight = *height;
-    }
-    if (!width || !height)
-      CalculateAccWidthAndHeight(doc, eUIType, fWidth, fCalcHeight);
-
-    fCalcWidth = fWidth;
-  }
-  m_pLayoutData->m_fWidgetHeight = fCalcHeight;
-}
-
-void CXFA_WidgetAcc::CalculateAccWidthAndHeight(CXFA_FFDoc* doc,
-                                                XFA_Element eUIType,
-                                                float& fWidth,
-                                                float& fCalcHeight) {
-  CFX_SizeF sz(fWidth, m_pLayoutData->m_fWidgetHeight);
-  switch (eUIType) {
-    case XFA_Element::Barcode:
-    case XFA_Element::ChoiceList:
-    case XFA_Element::Signature:
-      CalculateFieldAutoSize(doc, sz);
-      break;
-    case XFA_Element::ImageEdit:
-      CalculateImageEditAutoSize(doc, sz);
-      break;
-    case XFA_Element::Button:
-      CalculatePushButtonAutoSize(doc, sz);
-      break;
-    case XFA_Element::CheckButton:
-      CalculateCheckButtonAutoSize(doc, sz);
-      break;
-    case XFA_Element::DateTimeEdit:
-    case XFA_Element::NumericEdit:
-    case XFA_Element::PasswordEdit:
-    case XFA_Element::TextEdit:
-      CalculateTextEditAutoSize(doc, sz);
-      break;
-    case XFA_Element::Image:
-      CalculateImageAutoSize(doc, sz);
-      break;
-    case XFA_Element::Arc:
-    case XFA_Element::Line:
-    case XFA_Element::Rectangle:
-    case XFA_Element::Subform:
-    case XFA_Element::ExclGroup:
-      CalculateWidgetAutoSize(sz);
-      break;
-    default:
-      break;
-  }
-  fWidth = sz.width;
-  m_pLayoutData->m_fWidgetHeight = sz.height;
-  fCalcHeight = sz.height;
-}
-
-bool CXFA_WidgetAcc::FindSplitPos(CXFA_FFDocView* docView,
-                                  int32_t iBlockIndex,
-                                  float& fCalcHeight) {
-  XFA_Element eUIType = m_pNode->GetUIType();
-  if (eUIType == XFA_Element::Subform)
-    return false;
-
-  if (eUIType != XFA_Element::Text && eUIType != XFA_Element::TextEdit &&
-      eUIType != XFA_Element::NumericEdit &&
-      eUIType != XFA_Element::PasswordEdit) {
-    fCalcHeight = 0;
-    return true;
-  }
-
-  float fTopInset = 0;
-  float fBottomInset = 0;
-  if (iBlockIndex == 0) {
-    CXFA_Margin* margin = m_pNode->GetMarginIfExists();
-    if (margin) {
-      fTopInset = margin->GetTopInset();
-      fBottomInset = margin->GetBottomInset();
-    }
-
-    CFX_RectF rtUIMargin = m_pNode->GetUIMargin();
-    fTopInset += rtUIMargin.top;
-    fBottomInset += rtUIMargin.width;
-  }
-  if (eUIType == XFA_Element::Text) {
-    float fHeight = fCalcHeight;
-    if (iBlockIndex == 0) {
-      fCalcHeight = fCalcHeight - fTopInset;
-      if (fCalcHeight < 0)
-        fCalcHeight = 0;
-    }
-
-    CXFA_TextLayout* pTextLayout =
-        static_cast<CXFA_TextLayoutData*>(m_pLayoutData.get())->GetTextLayout();
-    fCalcHeight =
-        pTextLayout->DoLayout(iBlockIndex, fCalcHeight, fCalcHeight,
-                              m_pLayoutData->m_fWidgetHeight - fTopInset);
-    if (fCalcHeight != 0) {
-      if (iBlockIndex == 0)
-        fCalcHeight = fCalcHeight + fTopInset;
-      if (fabs(fHeight - fCalcHeight) < XFA_FLOAT_PERCISION)
-        return false;
-    }
-    return true;
-  }
-  XFA_AttributeEnum iCapPlacement = XFA_AttributeEnum::Unknown;
-  float fCapReserve = 0;
-  if (iBlockIndex == 0) {
-    CXFA_Caption* caption = m_pNode->GetCaptionIfExists();
-    if (caption && !caption->IsHidden()) {
-      iCapPlacement = caption->GetPlacementType();
-      fCapReserve = caption->GetReserve();
-    }
-    if (iCapPlacement == XFA_AttributeEnum::Top &&
-        fCalcHeight < fCapReserve + fTopInset) {
-      fCalcHeight = 0;
-      return true;
-    }
-    if (iCapPlacement == XFA_AttributeEnum::Bottom &&
-        m_pLayoutData->m_fWidgetHeight - fCapReserve - fBottomInset) {
-      fCalcHeight = 0;
-      return true;
-    }
-    if (iCapPlacement != XFA_AttributeEnum::Top)
-      fCapReserve = 0;
-  }
-  CXFA_FieldLayoutData* pFieldData =
-      static_cast<CXFA_FieldLayoutData*>(m_pLayoutData.get());
-  int32_t iLinesCount = 0;
-  float fHeight = m_pLayoutData->m_fWidgetHeight;
-  if (GetValue(XFA_VALUEPICTURE_Display).IsEmpty()) {
-    iLinesCount = 1;
-  } else {
-    if (!pFieldData->m_pTextOut) {
-      // TODO(dsinclair): Inline fWidth when the 2nd param of
-      // CalculateAccWidthAndHeight isn't a ref-param.
-      float fWidth = m_pNode->TryWidth().value_or(0);
-      CalculateAccWidthAndHeight(docView->GetDoc(), eUIType, fWidth, fHeight);
-    }
-    iLinesCount = pFieldData->m_pTextOut->GetTotalLines();
-  }
-  std::vector<float>* pFieldArray = &pFieldData->m_FieldSplitArray;
-  int32_t iFieldSplitCount = pdfium::CollectionSize<int32_t>(*pFieldArray);
-  for (int32_t i = 0; i < iBlockIndex * 3; i += 3) {
-    iLinesCount -= (int32_t)(*pFieldArray)[i + 1];
-    fHeight -= (*pFieldArray)[i + 2];
-  }
-  if (iLinesCount == 0)
-    return false;
-
-  float fLineHeight = m_pNode->GetLineHeight();
-  float fFontSize = m_pNode->GetFontSize();
-  float fTextHeight = iLinesCount * fLineHeight - fLineHeight + fFontSize;
-  float fSpaceAbove = 0;
-  float fStartOffset = 0;
-  if (fHeight > 0.1f && iBlockIndex == 0) {
-    fStartOffset = fTopInset;
-    fHeight -= (fTopInset + fBottomInset);
-    CXFA_Para* para = m_pNode->GetParaIfExists();
-    if (para) {
-      fSpaceAbove = para->GetSpaceAbove();
-      float fSpaceBelow = para->GetSpaceBelow();
-      fHeight -= (fSpaceAbove + fSpaceBelow);
-      switch (para->GetVerticalAlign()) {
-        case XFA_AttributeEnum::Top:
-          fStartOffset += fSpaceAbove;
-          break;
-        case XFA_AttributeEnum::Middle:
-          fStartOffset += ((fHeight - fTextHeight) / 2 + fSpaceAbove);
-          break;
-        case XFA_AttributeEnum::Bottom:
-          fStartOffset += (fHeight - fTextHeight + fSpaceAbove);
-          break;
-        default:
-          NOTREACHED();
-          break;
-      }
-    }
-    if (fStartOffset < 0.1f)
-      fStartOffset = 0;
-  }
-  for (int32_t i = iBlockIndex - 1; iBlockIndex > 0 && i < iBlockIndex; i++) {
-    fStartOffset = (*pFieldArray)[i * 3] - (*pFieldArray)[i * 3 + 2];
-    if (fStartOffset < 0.1f)
-      fStartOffset = 0;
-  }
-  if (iFieldSplitCount / 3 == (iBlockIndex + 1))
-    (*pFieldArray)[0] = fStartOffset;
-  else
-    pFieldArray->push_back(fStartOffset);
-
-  XFA_VERSION version = docView->GetDoc()->GetXFADoc()->GetCurVersionMode();
-  bool bCanSplitNoContent = false;
-  XFA_AttributeEnum eLayoutMode = GetNode()
-                                      ->GetParent()
-                                      ->JSObject()
-                                      ->TryEnum(XFA_Attribute::Layout, true)
-                                      .value_or(XFA_AttributeEnum::Position);
-  if ((eLayoutMode == XFA_AttributeEnum::Position ||
-       eLayoutMode == XFA_AttributeEnum::Tb ||
-       eLayoutMode == XFA_AttributeEnum::Row ||
-       eLayoutMode == XFA_AttributeEnum::Table) &&
-      version > XFA_VERSION_208) {
-    bCanSplitNoContent = true;
-  }
-  if ((eLayoutMode == XFA_AttributeEnum::Tb ||
-       eLayoutMode == XFA_AttributeEnum::Row ||
-       eLayoutMode == XFA_AttributeEnum::Table) &&
-      version <= XFA_VERSION_208) {
-    if (fStartOffset < fCalcHeight) {
-      bCanSplitNoContent = true;
-    } else {
-      fCalcHeight = 0;
-      return true;
-    }
-  }
-  if (bCanSplitNoContent) {
-    if ((fCalcHeight - fTopInset - fSpaceAbove < fLineHeight)) {
-      fCalcHeight = 0;
-      return true;
-    }
-    if (fStartOffset + XFA_FLOAT_PERCISION >= fCalcHeight) {
-      if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
-        (*pFieldArray)[iBlockIndex * 3 + 1] = 0;
-        (*pFieldArray)[iBlockIndex * 3 + 2] = fCalcHeight;
-      } else {
-        pFieldArray->push_back(0);
-        pFieldArray->push_back(fCalcHeight);
-      }
-      return false;
-    }
-    if (fCalcHeight - fStartOffset < fLineHeight) {
-      fCalcHeight = fStartOffset;
-      if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
-        (*pFieldArray)[iBlockIndex * 3 + 1] = 0;
-        (*pFieldArray)[iBlockIndex * 3 + 2] = fCalcHeight;
-      } else {
-        pFieldArray->push_back(0);
-        pFieldArray->push_back(fCalcHeight);
-      }
-      return true;
-    }
-    float fTextNum =
-        fCalcHeight + XFA_FLOAT_PERCISION - fCapReserve - fStartOffset;
-    int32_t iLineNum =
-        (int32_t)((fTextNum + (fLineHeight - fFontSize)) / fLineHeight);
-    if (iLineNum >= iLinesCount) {
-      if (fCalcHeight - fStartOffset - fTextHeight >= fFontSize) {
-        if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
-          (*pFieldArray)[iBlockIndex * 3 + 1] = (float)iLinesCount;
-          (*pFieldArray)[iBlockIndex * 3 + 2] = fCalcHeight;
-        } else {
-          pFieldArray->push_back((float)iLinesCount);
-          pFieldArray->push_back(fCalcHeight);
-        }
-        return false;
-      }
-      if (fHeight - fStartOffset - fTextHeight < fFontSize) {
-        iLineNum -= 1;
-        if (iLineNum == 0) {
-          fCalcHeight = 0;
-          return true;
-        }
-      } else {
-        iLineNum = (int32_t)(fTextNum / fLineHeight);
-      }
-    }
-    if (iLineNum > 0) {
-      float fSplitHeight = iLineNum * fLineHeight + fCapReserve + fStartOffset;
-      if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
-        (*pFieldArray)[iBlockIndex * 3 + 1] = (float)iLineNum;
-        (*pFieldArray)[iBlockIndex * 3 + 2] = fSplitHeight;
-      } else {
-        pFieldArray->push_back((float)iLineNum);
-        pFieldArray->push_back(fSplitHeight);
-      }
-      if (fabs(fSplitHeight - fCalcHeight) < XFA_FLOAT_PERCISION)
-        return false;
-
-      fCalcHeight = fSplitHeight;
-      return true;
-    }
-  }
-  fCalcHeight = 0;
-  return true;
-}
-
-void CXFA_WidgetAcc::InitLayoutData() {
-  if (m_pLayoutData)
-    return;
-
-  switch (m_pNode->GetUIType()) {
-    case XFA_Element::Text:
-      m_pLayoutData = pdfium::MakeUnique<CXFA_TextLayoutData>();
-      return;
-    case XFA_Element::TextEdit:
-      m_pLayoutData = pdfium::MakeUnique<CXFA_TextEditData>();
-      return;
-    case XFA_Element::Image:
-      m_pLayoutData = pdfium::MakeUnique<CXFA_ImageLayoutData>();
-      return;
-    case XFA_Element::ImageEdit:
-      m_pLayoutData = pdfium::MakeUnique<CXFA_ImageEditData>();
-      return;
-    default:
-      break;
-  }
-  if (m_pNode && m_pNode->GetElementType() == XFA_Element::Field) {
-    m_pLayoutData = pdfium::MakeUnique<CXFA_FieldLayoutData>();
-    return;
-  }
-  m_pLayoutData = pdfium::MakeUnique<CXFA_WidgetLayoutData>();
-}
-
-void CXFA_WidgetAcc::StartTextLayout(CXFA_FFDoc* doc,
-                                     float& fCalcWidth,
-                                     float& fCalcHeight) {
-  LoadText(doc);
-
-  CXFA_TextLayout* pTextLayout =
-      static_cast<CXFA_TextLayoutData*>(m_pLayoutData.get())->GetTextLayout();
-  float fTextHeight = 0;
-  if (fCalcWidth > 0 && fCalcHeight > 0) {
-    float fWidth = GetWidthWithoutMargin(fCalcWidth);
-    pTextLayout->StartLayout(fWidth);
-    fTextHeight = fCalcHeight;
-    fTextHeight = GetHeightWithoutMargin(fTextHeight);
-    pTextLayout->DoLayout(0, fTextHeight, -1, fTextHeight);
-    return;
-  }
-  if (fCalcWidth > 0 && fCalcHeight < 0) {
-    float fWidth = GetWidthWithoutMargin(fCalcWidth);
-    pTextLayout->StartLayout(fWidth);
-  }
-
-  if (fCalcWidth < 0 && fCalcHeight < 0) {
-    Optional<float> width = m_pNode->TryWidth();
-    if (width) {
-      pTextLayout->StartLayout(GetWidthWithoutMargin(*width));
-      fCalcWidth = *width;
-    } else {
-      float fMaxWidth = CalculateWidgetAutoWidth(pTextLayout->StartLayout(-1));
-      pTextLayout->StartLayout(GetWidthWithoutMargin(fMaxWidth));
-      fCalcWidth = fMaxWidth;
-    }
-  }
-
-  if (m_pLayoutData->m_fWidgetHeight < 0) {
-    m_pLayoutData->m_fWidgetHeight = pTextLayout->GetLayoutHeight();
-    m_pLayoutData->m_fWidgetHeight =
-        CalculateWidgetAutoHeight(m_pLayoutData->m_fWidgetHeight);
-  }
-  fTextHeight = m_pLayoutData->m_fWidgetHeight;
-  fTextHeight = GetHeightWithoutMargin(fTextHeight);
-  pTextLayout->DoLayout(0, fTextHeight, -1, fTextHeight);
-  fCalcHeight = m_pLayoutData->m_fWidgetHeight;
-}
-
-bool CXFA_WidgetAcc::LoadCaption(CXFA_FFDoc* doc) {
-  InitLayoutData();
-  return static_cast<CXFA_FieldLayoutData*>(m_pLayoutData.get())
-      ->LoadCaption(doc, this);
-}
-
-CXFA_TextLayout* CXFA_WidgetAcc::GetCaptionTextLayout() {
-  return m_pLayoutData
-             ? static_cast<CXFA_FieldLayoutData*>(m_pLayoutData.get())
-                   ->m_pCapTextLayout.get()
-             : nullptr;
-}
-
-CXFA_TextLayout* CXFA_WidgetAcc::GetTextLayout() {
-  return m_pLayoutData
-             ? static_cast<CXFA_TextLayoutData*>(m_pLayoutData.get())
-                   ->GetTextLayout()
-             : nullptr;
-}
-
-RetainPtr<CFX_DIBitmap> CXFA_WidgetAcc::GetImageImage() {
-  return m_pLayoutData
-             ? static_cast<CXFA_ImageLayoutData*>(m_pLayoutData.get())
-                   ->m_pDIBitmap
-             : nullptr;
-}
-
-RetainPtr<CFX_DIBitmap> CXFA_WidgetAcc::GetImageEditImage() {
-  return m_pLayoutData
-             ? static_cast<CXFA_ImageEditData*>(m_pLayoutData.get())
-                   ->m_pDIBitmap
-             : nullptr;
-}
-
-void CXFA_WidgetAcc::SetImageImage(const RetainPtr<CFX_DIBitmap>& newImage) {
-  CXFA_ImageLayoutData* pData =
-      static_cast<CXFA_ImageLayoutData*>(m_pLayoutData.get());
-  if (pData->m_pDIBitmap != newImage)
-    pData->m_pDIBitmap = newImage;
-}
-
-void CXFA_WidgetAcc::SetImageEditImage(
-    const RetainPtr<CFX_DIBitmap>& newImage) {
-  CXFA_ImageEditData* pData =
-      static_cast<CXFA_ImageEditData*>(m_pLayoutData.get());
-  if (pData->m_pDIBitmap != newImage)
-    pData->m_pDIBitmap = newImage;
-}
-
-RetainPtr<CFGAS_GEFont> CXFA_WidgetAcc::GetFDEFont(CXFA_FFDoc* doc) {
-  WideString wsFontName = L"Courier";
-  uint32_t dwFontStyle = 0;
-  CXFA_Font* font = m_pNode->GetFontIfExists();
-  if (font) {
-    if (font->IsBold())
-      dwFontStyle |= FXFONT_BOLD;
-    if (font->IsItalic())
-      dwFontStyle |= FXFONT_ITALIC;
-
-    wsFontName = font->GetTypeface();
-  }
-  return doc->GetApp()->GetXFAFontMgr()->GetFont(doc, wsFontName.AsStringView(),
-                                                 dwFontStyle);
-}
-
-bool CXFA_WidgetAcc::IsOpenAccess() const {
-  return m_pNode && m_pNode->IsOpenAccess();
-}
-
-XFA_AttributeEnum CXFA_WidgetAcc::GetButtonHighlight() {
-  CXFA_Node* pUIChild = m_pNode->GetUIChild();
-  if (pUIChild)
-    return pUIChild->JSObject()->GetEnum(XFA_Attribute::Highlight);
-  return XFA_AttributeEnum::Inverted;
-}
-
-bool CXFA_WidgetAcc::HasButtonRollover() const {
-  CXFA_Items* pItems =
-      m_pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
-  if (!pItems)
-    return false;
-
-  for (CXFA_Node* pText = pItems->GetFirstChild(); pText;
-       pText = pText->GetNextSibling()) {
-    if (pText->JSObject()->GetCData(XFA_Attribute::Name) == L"rollover")
-      return !pText->JSObject()->GetContent(false).IsEmpty();
-  }
-  return false;
-}
-
-bool CXFA_WidgetAcc::HasButtonDown() const {
-  CXFA_Items* pItems =
-      m_pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
-  if (!pItems)
-    return false;
-
-  for (CXFA_Node* pText = pItems->GetFirstChild(); pText;
-       pText = pText->GetNextSibling()) {
-    if (pText->JSObject()->GetCData(XFA_Attribute::Name) == L"down")
-      return !pText->JSObject()->GetContent(false).IsEmpty();
-  }
-  return false;
-}
-
-bool CXFA_WidgetAcc::IsCheckButtonRound() {
-  CXFA_Node* pUIChild = m_pNode->GetUIChild();
-  if (pUIChild)
-    return pUIChild->JSObject()->GetEnum(XFA_Attribute::Shape) ==
-           XFA_AttributeEnum::Round;
-  return false;
-}
-
-XFA_AttributeEnum CXFA_WidgetAcc::GetCheckButtonMark() {
-  CXFA_Node* pUIChild = m_pNode->GetUIChild();
-  if (pUIChild)
-    return pUIChild->JSObject()->GetEnum(XFA_Attribute::Mark);
-  return XFA_AttributeEnum::Default;
-}
-
-bool CXFA_WidgetAcc::IsRadioButton() {
-  CXFA_Node* pParent = m_pNode->GetParent();
-  return pParent && pParent->GetElementType() == XFA_Element::ExclGroup;
-}
-
-float CXFA_WidgetAcc::GetCheckButtonSize() {
-  CXFA_Node* pUIChild = m_pNode->GetUIChild();
-  if (pUIChild) {
-    return pUIChild->JSObject()
-        ->GetMeasure(XFA_Attribute::Size)
-        .ToUnit(XFA_Unit::Pt);
-  }
-  return CXFA_Measurement(10, XFA_Unit::Pt).ToUnit(XFA_Unit::Pt);
-}
-
-bool CXFA_WidgetAcc::IsAllowNeutral() {
-  CXFA_Node* pUIChild = m_pNode->GetUIChild();
-  return pUIChild &&
-         pUIChild->JSObject()->GetBoolean(XFA_Attribute::AllowNeutral);
-}
-
-XFA_CHECKSTATE CXFA_WidgetAcc::GetCheckState() {
-  WideString wsValue = m_pNode->GetRawValue();
-  if (wsValue.IsEmpty())
-    return XFA_CHECKSTATE_Off;
-
-  auto* pItems = m_pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
-  if (!pItems)
-    return XFA_CHECKSTATE_Off;
-
-  CXFA_Node* pText = pItems->GetFirstChild();
-  int32_t i = 0;
-  while (pText) {
-    Optional<WideString> wsContent = pText->JSObject()->TryContent(false, true);
-    if (wsContent && *wsContent == wsValue)
-      return static_cast<XFA_CHECKSTATE>(i);
-
-    i++;
-    pText = pText->GetNextSibling();
-  }
-  return XFA_CHECKSTATE_Off;
-}
-
-void CXFA_WidgetAcc::SetCheckState(XFA_CHECKSTATE eCheckState, bool bNotify) {
-  CXFA_Node* node = m_pNode->GetExclGroupIfExists();
-  if (!node) {
-    CXFA_Items* pItems =
-        m_pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
-    if (!pItems)
-      return;
-
-    int32_t i = -1;
-    CXFA_Node* pText = pItems->GetFirstChild();
-    WideString wsContent;
-    while (pText) {
-      i++;
-      if (i == eCheckState) {
-        wsContent = pText->JSObject()->GetContent(false);
-        break;
-      }
-      pText = pText->GetNextSibling();
-    }
-    m_pNode->SyncValue(wsContent, bNotify);
-
-    return;
-  }
-
-  WideString wsValue;
-  if (eCheckState != XFA_CHECKSTATE_Off) {
-    if (CXFA_Items* pItems =
-            m_pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false)) {
-      CXFA_Node* pText = pItems->GetFirstChild();
-      if (pText)
-        wsValue = pText->JSObject()->GetContent(false);
-    }
-  }
-  CXFA_Node* pChild = node->GetFirstChild();
-  for (; pChild; pChild = pChild->GetNextSibling()) {
-    if (pChild->GetElementType() != XFA_Element::Field)
-      continue;
-
-    CXFA_Items* pItem =
-        pChild->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
-    if (!pItem)
-      continue;
-
-    CXFA_Node* pItemchild = pItem->GetFirstChild();
-    if (!pItemchild)
-      continue;
-
-    WideString text = pItemchild->JSObject()->GetContent(false);
-    WideString wsChildValue = text;
-    if (wsValue != text) {
-      pItemchild = pItemchild->GetNextSibling();
-      if (pItemchild)
-        wsChildValue = pItemchild->JSObject()->GetContent(false);
-      else
-        wsChildValue.clear();
-    }
-    pChild->SyncValue(wsChildValue, bNotify);
-  }
-  node->SyncValue(wsValue, bNotify);
-}
-
-CXFA_Node* CXFA_WidgetAcc::GetSelectedMember() {
-  CXFA_Node* pSelectedMember = nullptr;
-  WideString wsState = m_pNode->GetRawValue();
-  if (wsState.IsEmpty())
-    return pSelectedMember;
-
-  for (CXFA_Node* pNode = ToNode(m_pNode->GetFirstChild()); pNode;
-       pNode = pNode->GetNextSibling()) {
-    CXFA_WidgetAcc widgetData(pNode);
-    if (widgetData.GetCheckState() == XFA_CHECKSTATE_On) {
-      pSelectedMember = pNode;
-      break;
-    }
-  }
-  return pSelectedMember;
-}
-
-CXFA_Node* CXFA_WidgetAcc::SetSelectedMember(const WideStringView& wsName,
-                                             bool bNotify) {
-  uint32_t nameHash = FX_HashCode_GetW(wsName, false);
-  for (CXFA_Node* pNode = ToNode(m_pNode->GetFirstChild()); pNode;
-       pNode = pNode->GetNextSibling()) {
-    if (pNode->GetNameHash() == nameHash) {
-      CXFA_WidgetAcc widgetData(pNode);
-      widgetData.SetCheckState(XFA_CHECKSTATE_On, bNotify);
-      return pNode;
-    }
-  }
-  return nullptr;
-}
-
-void CXFA_WidgetAcc::SetSelectedMemberByValue(const WideStringView& wsValue,
-                                              bool bNotify,
-                                              bool bScriptModify,
-                                              bool bSyncData) {
-  WideString wsExclGroup;
-  for (CXFA_Node* pNode = m_pNode->GetFirstChild(); pNode;
-       pNode = pNode->GetNextSibling()) {
-    if (pNode->GetElementType() != XFA_Element::Field)
-      continue;
-
-    CXFA_Items* pItem =
-        pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
-    if (!pItem)
-      continue;
-
-    CXFA_Node* pItemchild = pItem->GetFirstChild();
-    if (!pItemchild)
-      continue;
-
-    WideString wsChildValue = pItemchild->JSObject()->GetContent(false);
-    if (wsValue != wsChildValue) {
-      pItemchild = pItemchild->GetNextSibling();
-      if (pItemchild)
-        wsChildValue = pItemchild->JSObject()->GetContent(false);
-      else
-        wsChildValue.clear();
-    } else {
-      wsExclGroup = wsValue;
-    }
-    pNode->JSObject()->SetContent(wsChildValue, wsChildValue, bNotify,
-                                  bScriptModify, false);
-  }
-  m_pNode->JSObject()->SetContent(wsExclGroup, wsExclGroup, bNotify,
-                                  bScriptModify, bSyncData);
-}
-
-CXFA_Node* CXFA_WidgetAcc::GetExclGroupFirstMember() {
-  CXFA_Node* pExcl = GetNode();
-  if (!pExcl)
-    return nullptr;
-
-  CXFA_Node* pNode = pExcl->GetFirstChild();
-  while (pNode) {
-    if (pNode->GetElementType() == XFA_Element::Field)
-      return pNode;
-
-    pNode = pNode->GetNextSibling();
-  }
-  return nullptr;
-}
-CXFA_Node* CXFA_WidgetAcc::GetExclGroupNextMember(CXFA_Node* pNode) {
-  if (!pNode)
-    return nullptr;
-
-  CXFA_Node* pNodeField = pNode->GetNextSibling();
-  while (pNodeField) {
-    if (pNodeField->GetElementType() == XFA_Element::Field)
-      return pNodeField;
-
-    pNodeField = pNodeField->GetNextSibling();
-  }
-  return nullptr;
-}
-
-bool CXFA_WidgetAcc::IsChoiceListCommitOnSelect() {
-  CXFA_Node* pUIChild = m_pNode->GetUIChild();
-  if (pUIChild) {
-    return pUIChild->JSObject()->GetEnum(XFA_Attribute::CommitOn) ==
-           XFA_AttributeEnum::Select;
-  }
-  return true;
-}
-
-bool CXFA_WidgetAcc::IsChoiceListAllowTextEntry() {
-  CXFA_Node* pUIChild = m_pNode->GetUIChild();
-  return pUIChild && pUIChild->JSObject()->GetBoolean(XFA_Attribute::TextEntry);
-}
-
-bool CXFA_WidgetAcc::IsChoiceListMultiSelect() {
-  CXFA_Node* pUIChild = m_pNode->GetUIChild();
-  if (pUIChild) {
-    return pUIChild->JSObject()->GetEnum(XFA_Attribute::Open) ==
-           XFA_AttributeEnum::MultiSelect;
-  }
-  return false;
-}
-
-bool CXFA_WidgetAcc::IsListBox() {
-  CXFA_Node* pUIChild = m_pNode->GetUIChild();
-  if (!pUIChild)
-    return false;
-
-  XFA_AttributeEnum attr = pUIChild->JSObject()->GetEnum(XFA_Attribute::Open);
-  return attr == XFA_AttributeEnum::Always ||
-         attr == XFA_AttributeEnum::MultiSelect;
-}
-
-int32_t CXFA_WidgetAcc::CountChoiceListItems(bool bSaveValue) {
-  std::vector<CXFA_Node*> pItems;
-  int32_t iCount = 0;
-  for (CXFA_Node* pNode = m_pNode->GetFirstChild(); pNode;
-       pNode = pNode->GetNextSibling()) {
-    if (pNode->GetElementType() != XFA_Element::Items)
-      continue;
-    iCount++;
-    pItems.push_back(pNode);
-    if (iCount == 2)
-      break;
-  }
-  if (iCount == 0)
-    return 0;
-
-  CXFA_Node* pItem = pItems[0];
-  if (iCount > 1) {
-    bool bItemOneHasSave =
-        pItems[0]->JSObject()->GetBoolean(XFA_Attribute::Save);
-    bool bItemTwoHasSave =
-        pItems[1]->JSObject()->GetBoolean(XFA_Attribute::Save);
-    if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave)
-      pItem = pItems[1];
-  }
-  return pItem->CountChildren(XFA_Element::Unknown, false);
-}
-
-Optional<WideString> CXFA_WidgetAcc::GetChoiceListItem(int32_t nIndex,
-                                                       bool bSaveValue) {
-  std::vector<CXFA_Node*> pItemsArray;
-  int32_t iCount = 0;
-  for (CXFA_Node* pNode = m_pNode->GetFirstChild(); pNode;
-       pNode = pNode->GetNextSibling()) {
-    if (pNode->GetElementType() != XFA_Element::Items)
-      continue;
-
-    ++iCount;
-    pItemsArray.push_back(pNode);
-    if (iCount == 2)
-      break;
-  }
-  if (iCount == 0)
-    return {};
-
-  CXFA_Node* pItems = pItemsArray[0];
-  if (iCount > 1) {
-    bool bItemOneHasSave =
-        pItemsArray[0]->JSObject()->GetBoolean(XFA_Attribute::Save);
-    bool bItemTwoHasSave =
-        pItemsArray[1]->JSObject()->GetBoolean(XFA_Attribute::Save);
-    if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave)
-      pItems = pItemsArray[1];
-  }
-  if (!pItems)
-    return {};
-
-  CXFA_Node* pItem =
-      pItems->GetChild<CXFA_Node>(nIndex, XFA_Element::Unknown, false);
-  if (pItem)
-    return {pItem->JSObject()->GetContent(false)};
-  return {};
-}
-
-std::vector<WideString> CXFA_WidgetAcc::GetChoiceListItems(bool bSaveValue) {
-  std::vector<CXFA_Node*> items;
-  for (CXFA_Node* pNode = m_pNode->GetFirstChild(); pNode && items.size() < 2;
-       pNode = pNode->GetNextSibling()) {
-    if (pNode->GetElementType() == XFA_Element::Items)
-      items.push_back(pNode);
-  }
-  if (items.empty())
-    return std::vector<WideString>();
-
-  CXFA_Node* pItem = items.front();
-  if (items.size() > 1) {
-    bool bItemOneHasSave =
-        items[0]->JSObject()->GetBoolean(XFA_Attribute::Save);
-    bool bItemTwoHasSave =
-        items[1]->JSObject()->GetBoolean(XFA_Attribute::Save);
-    if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave)
-      pItem = items[1];
-  }
-
-  std::vector<WideString> wsTextArray;
-  for (CXFA_Node* pNode = pItem->GetFirstChild(); pNode;
-       pNode = pNode->GetNextSibling()) {
-    wsTextArray.emplace_back(pNode->JSObject()->GetContent(false));
-  }
-  return wsTextArray;
-}
-
-int32_t CXFA_WidgetAcc::CountSelectedItems() {
-  std::vector<WideString> wsValueArray = GetSelectedItemsValue();
-  if (IsListBox() || !IsChoiceListAllowTextEntry())
-    return pdfium::CollectionSize<int32_t>(wsValueArray);
-
-  int32_t iSelected = 0;
-  std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
-  for (const auto& value : wsValueArray) {
-    if (pdfium::ContainsValue(wsSaveTextArray, value))
-      iSelected++;
-  }
-  return iSelected;
-}
-
-int32_t CXFA_WidgetAcc::GetSelectedItem(int32_t nIndex) {
-  std::vector<WideString> wsValueArray = GetSelectedItemsValue();
-  if (!pdfium::IndexInBounds(wsValueArray, nIndex))
-    return -1;
-
-  std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
-  auto it = std::find(wsSaveTextArray.begin(), wsSaveTextArray.end(),
-                      wsValueArray[nIndex]);
-  return it != wsSaveTextArray.end() ? it - wsSaveTextArray.begin() : -1;
-}
-
-std::vector<int32_t> CXFA_WidgetAcc::GetSelectedItems() {
-  std::vector<int32_t> iSelArray;
-  std::vector<WideString> wsValueArray = GetSelectedItemsValue();
-  std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
-  for (const auto& value : wsValueArray) {
-    auto it = std::find(wsSaveTextArray.begin(), wsSaveTextArray.end(), value);
-    if (it != wsSaveTextArray.end())
-      iSelArray.push_back(it - wsSaveTextArray.begin());
-  }
-  return iSelArray;
-}
-
-std::vector<WideString> CXFA_WidgetAcc::GetSelectedItemsValue() {
-  std::vector<WideString> wsSelTextArray;
-  WideString wsValue = m_pNode->GetRawValue();
-  if (IsChoiceListMultiSelect()) {
-    if (!wsValue.IsEmpty()) {
-      size_t iStart = 0;
-      size_t iLength = wsValue.GetLength();
-      auto iEnd = wsValue.Find(L'\n', iStart);
-      iEnd = (!iEnd.has_value()) ? iLength : iEnd;
-      while (iEnd >= iStart) {
-        wsSelTextArray.push_back(wsValue.Mid(iStart, iEnd.value() - iStart));
-        iStart = iEnd.value() + 1;
-        if (iStart >= iLength)
-          break;
-        iEnd = wsValue.Find(L'\n', iStart);
-        if (!iEnd.has_value())
-          wsSelTextArray.push_back(wsValue.Mid(iStart, iLength - iStart));
-      }
-    }
-  } else {
-    wsSelTextArray.push_back(wsValue);
-  }
-  return wsSelTextArray;
-}
-
-bool CXFA_WidgetAcc::GetItemState(int32_t nIndex) {
-  std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
-  return pdfium::IndexInBounds(wsSaveTextArray, nIndex) &&
-         pdfium::ContainsValue(GetSelectedItemsValue(),
-                               wsSaveTextArray[nIndex]);
-}
-
-void CXFA_WidgetAcc::SetItemState(int32_t nIndex,
-                                  bool bSelected,
-                                  bool bNotify,
-                                  bool bScriptModify,
-                                  bool bSyncData) {
-  std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
-  if (!pdfium::IndexInBounds(wsSaveTextArray, nIndex))
-    return;
-
-  int32_t iSel = -1;
-  std::vector<WideString> wsValueArray = GetSelectedItemsValue();
-  auto it = std::find(wsValueArray.begin(), wsValueArray.end(),
-                      wsSaveTextArray[nIndex]);
-  if (it != wsValueArray.end())
-    iSel = it - wsValueArray.begin();
-
-  if (IsChoiceListMultiSelect()) {
-    if (bSelected) {
-      if (iSel < 0) {
-        WideString wsValue = m_pNode->GetRawValue();
-        if (!wsValue.IsEmpty()) {
-          wsValue += L"\n";
-        }
-        wsValue += wsSaveTextArray[nIndex];
-        m_pNode->JSObject()->SetContent(wsValue, wsValue, bNotify,
-                                        bScriptModify, bSyncData);
-      }
-    } else if (iSel >= 0) {
-      std::vector<int32_t> iSelArray = GetSelectedItems();
-      auto it = std::find(iSelArray.begin(), iSelArray.end(), nIndex);
-      if (it != iSelArray.end())
-        iSelArray.erase(it);
-      SetSelectedItems(iSelArray, bNotify, bScriptModify, bSyncData);
-    }
-  } else {
-    if (bSelected) {
-      if (iSel < 0) {
-        WideString wsSaveText = wsSaveTextArray[nIndex];
-        m_pNode->JSObject()->SetContent(wsSaveText,
-                                        GetFormatDataValue(wsSaveText), bNotify,
-                                        bScriptModify, bSyncData);
-      }
-    } else if (iSel >= 0) {
-      m_pNode->JSObject()->SetContent(WideString(), WideString(), bNotify,
-                                      bScriptModify, bSyncData);
-    }
-  }
-}
-
-void CXFA_WidgetAcc::SetSelectedItems(const std::vector<int32_t>& iSelArray,
-                                      bool bNotify,
-                                      bool bScriptModify,
-                                      bool bSyncData) {
-  WideString wsValue;
-  int32_t iSize = pdfium::CollectionSize<int32_t>(iSelArray);
-  if (iSize >= 1) {
-    std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
-    WideString wsItemValue;
-    for (int32_t i = 0; i < iSize; i++) {
-      wsItemValue = (iSize == 1) ? wsSaveTextArray[iSelArray[i]]
-                                 : wsSaveTextArray[iSelArray[i]] + L"\n";
-      wsValue += wsItemValue;
-    }
-  }
-  WideString wsFormat(wsValue);
-  if (!IsChoiceListMultiSelect())
-    wsFormat = GetFormatDataValue(wsValue);
-
-  m_pNode->JSObject()->SetContent(wsValue, wsFormat, bNotify, bScriptModify,
-                                  bSyncData);
-}
-
-void CXFA_WidgetAcc::ClearAllSelections() {
-  CXFA_Node* pBind = m_pNode->GetBindData();
-  if (!pBind || !IsChoiceListMultiSelect()) {
-    m_pNode->SyncValue(WideString(), false);
-    return;
-  }
-
-  while (CXFA_Node* pChildNode = pBind->GetFirstChild())
-    pBind->RemoveChild(pChildNode, true);
-}
-
-void CXFA_WidgetAcc::InsertItem(const WideString& wsLabel,
-                                const WideString& wsValue,
-                                bool bNotify) {
-  int32_t nIndex = -1;
-  WideString wsNewValue(wsValue);
-  if (wsNewValue.IsEmpty())
-    wsNewValue = wsLabel;
-
-  std::vector<CXFA_Node*> listitems;
-  for (CXFA_Node* pItem = m_pNode->GetFirstChild(); pItem;
-       pItem = pItem->GetNextSibling()) {
-    if (pItem->GetElementType() == XFA_Element::Items)
-      listitems.push_back(pItem);
-  }
-  if (listitems.empty()) {
-    CXFA_Node* pItems = m_pNode->CreateSamePacketNode(XFA_Element::Items);
-    m_pNode->InsertChild(-1, pItems);
-    InsertListTextItem(pItems, wsLabel, nIndex);
-    CXFA_Node* pSaveItems = m_pNode->CreateSamePacketNode(XFA_Element::Items);
-    m_pNode->InsertChild(-1, pSaveItems);
-    pSaveItems->JSObject()->SetBoolean(XFA_Attribute::Save, true, false);
-    InsertListTextItem(pSaveItems, wsNewValue, nIndex);
-  } else if (listitems.size() > 1) {
-    for (int32_t i = 0; i < 2; i++) {
-      CXFA_Node* pNode = listitems[i];
-      bool bHasSave = pNode->JSObject()->GetBoolean(XFA_Attribute::Save);
-      if (bHasSave)
-        InsertListTextItem(pNode, wsNewValue, nIndex);
-      else
-        InsertListTextItem(pNode, wsLabel, nIndex);
-    }
-  } else {
-    CXFA_Node* pNode = listitems[0];
-    pNode->JSObject()->SetBoolean(XFA_Attribute::Save, false, false);
-    pNode->JSObject()->SetEnum(XFA_Attribute::Presence,
-                               XFA_AttributeEnum::Visible, false);
-    CXFA_Node* pSaveItems = m_pNode->CreateSamePacketNode(XFA_Element::Items);
-    m_pNode->InsertChild(-1, pSaveItems);
-    pSaveItems->JSObject()->SetBoolean(XFA_Attribute::Save, true, false);
-    pSaveItems->JSObject()->SetEnum(XFA_Attribute::Presence,
-                                    XFA_AttributeEnum::Hidden, false);
-    CXFA_Node* pListNode = pNode->GetFirstChild();
-    int32_t i = 0;
-    while (pListNode) {
-      InsertListTextItem(pSaveItems, pListNode->JSObject()->GetContent(false),
-                         i);
-      ++i;
-
-      pListNode = pListNode->GetNextSibling();
-    }
-    InsertListTextItem(pNode, wsLabel, nIndex);
-    InsertListTextItem(pSaveItems, wsNewValue, nIndex);
-  }
-  if (!bNotify)
-    return;
-
-  m_pNode->GetDocument()->GetNotify()->OnWidgetListItemAdded(
-      m_pNode, wsLabel.c_str(), wsValue.c_str(), nIndex);
-}
-
-void CXFA_WidgetAcc::GetItemLabel(const WideStringView& wsValue,
-                                  WideString& wsLabel) {
-  int32_t iCount = 0;
-  std::vector<CXFA_Node*> listitems;
-  CXFA_Node* pItems = m_pNode->GetFirstChild();
-  for (; pItems; pItems = pItems->GetNextSibling()) {
-    if (pItems->GetElementType() != XFA_Element::Items)
-      continue;
-    iCount++;
-    listitems.push_back(pItems);
-  }
-
-  if (iCount <= 1) {
-    wsLabel = wsValue;
-    return;
-  }
-
-  CXFA_Node* pLabelItems = listitems[0];
-  bool bSave = pLabelItems->JSObject()->GetBoolean(XFA_Attribute::Save);
-  CXFA_Node* pSaveItems = nullptr;
-  if (bSave) {
-    pSaveItems = pLabelItems;
-    pLabelItems = listitems[1];
-  } else {
-    pSaveItems = listitems[1];
-  }
-  iCount = 0;
-
-  int32_t iSearch = -1;
-  for (CXFA_Node* pChildItem = pSaveItems->GetFirstChild(); pChildItem;
-       pChildItem = pChildItem->GetNextSibling()) {
-    if (pChildItem->JSObject()->GetContent(false) == wsValue) {
-      iSearch = iCount;
-      break;
-    }
-    iCount++;
-  }
-  if (iSearch < 0)
-    return;
-
-  CXFA_Node* pText =
-      pLabelItems->GetChild<CXFA_Node>(iSearch, XFA_Element::Unknown, false);
-  if (pText)
-    wsLabel = pText->JSObject()->GetContent(false);
-}
-
-WideString CXFA_WidgetAcc::GetItemValue(const WideStringView& wsLabel) {
-  int32_t iCount = 0;
-  std::vector<CXFA_Node*> listitems;
-  for (CXFA_Node* pItems = m_pNode->GetFirstChild(); pItems;
-       pItems = pItems->GetNextSibling()) {
-    if (pItems->GetElementType() != XFA_Element::Items)
-      continue;
-    iCount++;
-    listitems.push_back(pItems);
-  }
-  if (iCount <= 1)
-    return WideString(wsLabel);
-
-  CXFA_Node* pLabelItems = listitems[0];
-  bool bSave = pLabelItems->JSObject()->GetBoolean(XFA_Attribute::Save);
-  CXFA_Node* pSaveItems = nullptr;
-  if (bSave) {
-    pSaveItems = pLabelItems;
-    pLabelItems = listitems[1];
-  } else {
-    pSaveItems = listitems[1];
-  }
-  iCount = 0;
-
-  int32_t iSearch = -1;
-  WideString wsContent;
-  CXFA_Node* pChildItem = pLabelItems->GetFirstChild();
-  for (; pChildItem; pChildItem = pChildItem->GetNextSibling()) {
-    if (pChildItem->JSObject()->GetContent(false) == wsLabel) {
-      iSearch = iCount;
-      break;
-    }
-    iCount++;
-  }
-  if (iSearch < 0)
-    return L"";
-
-  CXFA_Node* pText =
-      pSaveItems->GetChild<CXFA_Node>(iSearch, XFA_Element::Unknown, false);
-  return pText ? pText->JSObject()->GetContent(false) : L"";
-}
-
-bool CXFA_WidgetAcc::DeleteItem(int32_t nIndex,
-                                bool bNotify,
-                                bool bScriptModify) {
-  bool bSetValue = false;
-  CXFA_Node* pItems = m_pNode->GetFirstChild();
-  for (; pItems; pItems = pItems->GetNextSibling()) {
-    if (pItems->GetElementType() != XFA_Element::Items)
-      continue;
-
-    if (nIndex < 0) {
-      while (CXFA_Node* pNode = pItems->GetFirstChild()) {
-        pItems->RemoveChild(pNode, true);
-      }
-    } else {
-      if (!bSetValue && pItems->JSObject()->GetBoolean(XFA_Attribute::Save)) {
-        SetItemState(nIndex, false, true, bScriptModify, true);
-        bSetValue = true;
-      }
-      int32_t i = 0;
-      CXFA_Node* pNode = pItems->GetFirstChild();
-      while (pNode) {
-        if (i == nIndex) {
-          pItems->RemoveChild(pNode, true);
-          break;
-        }
-        i++;
-        pNode = pNode->GetNextSibling();
-      }
-    }
-  }
-  if (bNotify)
-    m_pNode->GetDocument()->GetNotify()->OnWidgetListItemRemoved(m_pNode,
-                                                                 nIndex);
-  return true;
-}
-
-bool CXFA_WidgetAcc::IsHorizontalScrollPolicyOff() {
-  CXFA_Node* pUIChild = m_pNode->GetUIChild();
-  if (pUIChild) {
-    return pUIChild->JSObject()->GetEnum(XFA_Attribute::HScrollPolicy) ==
-           XFA_AttributeEnum::Off;
-  }
-  return false;
-}
-
-bool CXFA_WidgetAcc::IsVerticalScrollPolicyOff() {
-  CXFA_Node* pUIChild = m_pNode->GetUIChild();
-  if (pUIChild) {
-    return pUIChild->JSObject()->GetEnum(XFA_Attribute::VScrollPolicy) ==
-           XFA_AttributeEnum::Off;
-  }
-  return false;
-}
-
-Optional<int32_t> CXFA_WidgetAcc::GetNumberOfCells() {
-  CXFA_Node* pUIChild = m_pNode->GetUIChild();
-  if (!pUIChild)
-    return {};
-  if (CXFA_Comb* pNode =
-          pUIChild->GetChild<CXFA_Comb>(0, XFA_Element::Comb, false))
-    return {pNode->JSObject()->GetInteger(XFA_Attribute::NumberOfCells)};
-  return {};
-}
-
-WideString CXFA_WidgetAcc::GetPasswordChar() {
-  CXFA_Node* pUIChild = m_pNode->GetUIChild();
-  return pUIChild ? pUIChild->JSObject()->GetCData(XFA_Attribute::PasswordChar)
-                  : L"*";
-}
-
-bool CXFA_WidgetAcc::IsMultiLine() {
-  CXFA_Node* pUIChild = m_pNode->GetUIChild();
-  return pUIChild && pUIChild->JSObject()->GetBoolean(XFA_Attribute::MultiLine);
-}
-
-std::pair<XFA_Element, int32_t> CXFA_WidgetAcc::GetMaxChars() {
-  if (CXFA_Value* pNode =
-          m_pNode->GetChild<CXFA_Value>(0, XFA_Element::Value, false)) {
-    if (CXFA_Node* pChild = pNode->GetFirstChild()) {
-      switch (pChild->GetElementType()) {
-        case XFA_Element::Text:
-          return {XFA_Element::Text,
-                  pChild->JSObject()->GetInteger(XFA_Attribute::MaxChars)};
-        case XFA_Element::ExData: {
-          int32_t iMax =
-              pChild->JSObject()->GetInteger(XFA_Attribute::MaxLength);
-          return {XFA_Element::ExData, iMax < 0 ? 0 : iMax};
-        }
-        default:
-          break;
-      }
-    }
-  }
-  return {XFA_Element::Unknown, 0};
-}
-
-int32_t CXFA_WidgetAcc::GetFracDigits() {
-  CXFA_Value* pNode =
-      m_pNode->GetChild<CXFA_Value>(0, XFA_Element::Value, false);
-  if (!pNode)
-    return -1;
-
-  CXFA_Decimal* pChild =
-      pNode->GetChild<CXFA_Decimal>(0, XFA_Element::Decimal, false);
-  if (!pChild)
-    return -1;
-
-  return pChild->JSObject()
-      ->TryInteger(XFA_Attribute::FracDigits, true)
-      .value_or(-1);
-}
-
-int32_t CXFA_WidgetAcc::GetLeadDigits() {
-  CXFA_Value* pNode =
-      m_pNode->GetChild<CXFA_Value>(0, XFA_Element::Value, false);
-  if (!pNode)
-    return -1;
-
-  CXFA_Decimal* pChild =
-      pNode->GetChild<CXFA_Decimal>(0, XFA_Element::Decimal, false);
-  if (!pChild)
-    return -1;
-
-  return pChild->JSObject()
-      ->TryInteger(XFA_Attribute::LeadDigits, true)
-      .value_or(-1);
-}
-
-bool CXFA_WidgetAcc::SetValue(XFA_VALUEPICTURE eValueType,
-                              const WideString& wsValue) {
-  if (wsValue.IsEmpty()) {
-    m_pNode->SyncValue(wsValue, true);
-    return true;
-  }
-
-  m_pNode->SetPreNull(m_pNode->IsNull());
-  m_pNode->SetIsNull(false);
-
-  WideString wsNewText(wsValue);
-  WideString wsPicture = GetPictureContent(eValueType);
-  bool bValidate = true;
-  bool bSyncData = false;
-  CXFA_Node* pNode = m_pNode->GetUIChild();
-  if (!pNode)
-    return true;
-
-  XFA_Element eType = pNode->GetElementType();
-  if (!wsPicture.IsEmpty()) {
-    CXFA_LocaleMgr* pLocalMgr = m_pNode->GetDocument()->GetLocalMgr();
-    IFX_Locale* pLocale = m_pNode->GetLocale();
-    CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(GetNode());
-    bValidate =
-        widgetValue.ValidateValue(wsValue, wsPicture, pLocale, &wsPicture);
-    if (bValidate) {
-      widgetValue = CXFA_LocaleValue(widgetValue.GetType(), wsNewText,
-                                     wsPicture, pLocale, pLocalMgr);
-      wsNewText = widgetValue.GetValue();
-      if (eType == XFA_Element::NumericEdit)
-        wsNewText = NumericLimit(wsNewText, GetLeadDigits(), GetFracDigits());
-
-      bSyncData = true;
-    }
-  } else {
-    if (eType == XFA_Element::NumericEdit) {
-      if (wsNewText != L"0")
-        wsNewText = NumericLimit(wsNewText, GetLeadDigits(), GetFracDigits());
-
-      bSyncData = true;
-    }
-  }
-  if (eType != XFA_Element::NumericEdit || bSyncData)
-    m_pNode->SyncValue(wsNewText, true);
-
-  return bValidate;
-}
-
-WideString CXFA_WidgetAcc::GetPictureContent(XFA_VALUEPICTURE ePicture) {
-  if (ePicture == XFA_VALUEPICTURE_Raw)
-    return L"";
-
-  CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(GetNode());
-  switch (ePicture) {
-    case XFA_VALUEPICTURE_Display: {
-      if (CXFA_Format* pFormat =
-              m_pNode->GetChild<CXFA_Format>(0, XFA_Element::Format, false)) {
-        if (CXFA_Picture* pPicture = pFormat->GetChild<CXFA_Picture>(
-                0, XFA_Element::Picture, false)) {
-          Optional<WideString> picture =
-              pPicture->JSObject()->TryContent(false, true);
-          if (picture)
-            return *picture;
-        }
-      }
-
-      IFX_Locale* pLocale = m_pNode->GetLocale();
-      if (!pLocale)
-        return L"";
-
-      uint32_t dwType = widgetValue.GetType();
-      switch (dwType) {
-        case XFA_VT_DATE:
-          return pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium);
-        case XFA_VT_TIME:
-          return pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium);
-        case XFA_VT_DATETIME:
-          return pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium) +
-                 L"T" +
-                 pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium);
-        case XFA_VT_DECIMAL:
-        case XFA_VT_FLOAT:
-        default:
-          return L"";
-      }
-    }
-    case XFA_VALUEPICTURE_Edit: {
-      CXFA_Ui* pUI = m_pNode->GetChild<CXFA_Ui>(0, XFA_Element::Ui, false);
-      if (pUI) {
-        if (CXFA_Picture* pPicture =
-                pUI->GetChild<CXFA_Picture>(0, XFA_Element::Picture, false)) {
-          Optional<WideString> picture =
-              pPicture->JSObject()->TryContent(false, true);
-          if (picture)
-            return *picture;
-        }
-      }
-
-      IFX_Locale* pLocale = m_pNode->GetLocale();
-      if (!pLocale)
-        return L"";
-
-      uint32_t dwType = widgetValue.GetType();
-      switch (dwType) {
-        case XFA_VT_DATE:
-          return pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Short);
-        case XFA_VT_TIME:
-          return pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Short);
-        case XFA_VT_DATETIME:
-          return pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Short) +
-                 L"T" +
-                 pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Short);
-        default:
-          return L"";
-      }
-    }
-    case XFA_VALUEPICTURE_DataBind: {
-      CXFA_Bind* bind = m_pNode->GetBindIfExists();
-      if (bind)
-        return bind->GetPicture();
-      break;
-    }
-    default:
-      break;
-  }
-  return L"";
-}
-
-WideString CXFA_WidgetAcc::GetValue(XFA_VALUEPICTURE eValueType) {
-  WideString wsValue = m_pNode->JSObject()->GetContent(false);
-
-  if (eValueType == XFA_VALUEPICTURE_Display)
-    GetItemLabel(wsValue.AsStringView(), wsValue);
-
-  WideString wsPicture = GetPictureContent(eValueType);
-  CXFA_Node* pNode = m_pNode->GetUIChild();
-  if (!pNode)
-    return wsValue;
-
-  switch (m_pNode->GetUIChild()->GetElementType()) {
-    case XFA_Element::ChoiceList: {
-      if (eValueType == XFA_VALUEPICTURE_Display) {
-        int32_t iSelItemIndex = GetSelectedItem(0);
-        if (iSelItemIndex >= 0) {
-          wsValue = GetChoiceListItem(iSelItemIndex, false).value_or(L"");
-          wsPicture.clear();
-        }
-      }
-    } break;
-    case XFA_Element::NumericEdit:
-      if (eValueType != XFA_VALUEPICTURE_Raw && wsPicture.IsEmpty()) {
-        IFX_Locale* pLocale = m_pNode->GetLocale();
-        if (eValueType == XFA_VALUEPICTURE_Display && pLocale)
-          wsValue = FormatNumStr(NormalizeNumStr(wsValue), pLocale);
-      }
-      break;
-    default:
-      break;
-  }
-  if (wsPicture.IsEmpty())
-    return wsValue;
-
-  if (IFX_Locale* pLocale = m_pNode->GetLocale()) {
-    CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(GetNode());
-    CXFA_LocaleMgr* pLocalMgr = m_pNode->GetDocument()->GetLocalMgr();
-    switch (widgetValue.GetType()) {
-      case XFA_VT_DATE: {
-        WideString wsDate, wsTime;
-        if (SplitDateTime(wsValue, wsDate, wsTime)) {
-          CXFA_LocaleValue date(XFA_VT_DATE, wsDate, pLocalMgr);
-          if (date.FormatPatterns(wsValue, wsPicture, pLocale, eValueType))
-            return wsValue;
-        }
-        break;
-      }
-      case XFA_VT_TIME: {
-        WideString wsDate, wsTime;
-        if (SplitDateTime(wsValue, wsDate, wsTime)) {
-          CXFA_LocaleValue time(XFA_VT_TIME, wsTime, pLocalMgr);
-          if (time.FormatPatterns(wsValue, wsPicture, pLocale, eValueType))
-            return wsValue;
-        }
-        break;
-      }
-      default:
-        break;
-    }
-    widgetValue.FormatPatterns(wsValue, wsPicture, pLocale, eValueType);
-  }
-  return wsValue;
-}
-
-WideString CXFA_WidgetAcc::GetNormalizeDataValue(const WideString& wsValue) {
-  if (wsValue.IsEmpty())
-    return L"";
-
-  WideString wsPicture = GetPictureContent(XFA_VALUEPICTURE_DataBind);
-  if (wsPicture.IsEmpty())
-    return wsValue;
-
-  ASSERT(GetNode());
-  CXFA_LocaleMgr* pLocalMgr = GetNode()->GetDocument()->GetLocalMgr();
-  IFX_Locale* pLocale = m_pNode->GetLocale();
-  CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(GetNode());
-  if (widgetValue.ValidateValue(wsValue, wsPicture, pLocale, &wsPicture)) {
-    widgetValue = CXFA_LocaleValue(widgetValue.GetType(), wsValue, wsPicture,
-                                   pLocale, pLocalMgr);
-    return widgetValue.GetValue();
-  }
-  return wsValue;
-}
-
-WideString CXFA_WidgetAcc::GetFormatDataValue(const WideString& wsValue) {
-  if (wsValue.IsEmpty())
-    return L"";
-
-  WideString wsPicture = GetPictureContent(XFA_VALUEPICTURE_DataBind);
-  if (wsPicture.IsEmpty())
-    return wsValue;
-
-  WideString wsFormattedValue = wsValue;
-  if (IFX_Locale* pLocale = m_pNode->GetLocale()) {
-    ASSERT(GetNode());
-    CXFA_Value* pNodeValue =
-        GetNode()->GetChild<CXFA_Value>(0, XFA_Element::Value, false);
-    if (!pNodeValue)
-      return wsValue;
-
-    CXFA_Node* pValueChild = pNodeValue->GetFirstChild();
-    if (!pValueChild)
-      return wsValue;
-
-    int32_t iVTType = XFA_VT_NULL;
-    switch (pValueChild->GetElementType()) {
-      case XFA_Element::Decimal:
-        iVTType = XFA_VT_DECIMAL;
-        break;
-      case XFA_Element::Float:
-        iVTType = XFA_VT_FLOAT;
-        break;
-      case XFA_Element::Date:
-        iVTType = XFA_VT_DATE;
-        break;
-      case XFA_Element::Time:
-        iVTType = XFA_VT_TIME;
-        break;
-      case XFA_Element::DateTime:
-        iVTType = XFA_VT_DATETIME;
-        break;
-      case XFA_Element::Boolean:
-        iVTType = XFA_VT_BOOLEAN;
-        break;
-      case XFA_Element::Integer:
-        iVTType = XFA_VT_INTEGER;
-        break;
-      case XFA_Element::Text:
-        iVTType = XFA_VT_TEXT;
-        break;
-      default:
-        iVTType = XFA_VT_NULL;
-        break;
-    }
-    CXFA_LocaleMgr* pLocalMgr = GetNode()->GetDocument()->GetLocalMgr();
-    CXFA_LocaleValue widgetValue(iVTType, wsValue, pLocalMgr);
-    switch (widgetValue.GetType()) {
-      case XFA_VT_DATE: {
-        WideString wsDate, wsTime;
-        if (SplitDateTime(wsValue, wsDate, wsTime)) {
-          CXFA_LocaleValue date(XFA_VT_DATE, wsDate, pLocalMgr);
-          if (date.FormatPatterns(wsFormattedValue, wsPicture, pLocale,
-                                  XFA_VALUEPICTURE_DataBind)) {
-            return wsFormattedValue;
-          }
-        }
-        break;
-      }
-      case XFA_VT_TIME: {
-        WideString wsDate, wsTime;
-        if (SplitDateTime(wsValue, wsDate, wsTime)) {
-          CXFA_LocaleValue time(XFA_VT_TIME, wsTime, pLocalMgr);
-          if (time.FormatPatterns(wsFormattedValue, wsPicture, pLocale,
-                                  XFA_VALUEPICTURE_DataBind)) {
-            return wsFormattedValue;
-          }
-        }
-        break;
-      }
-      default:
-        break;
-    }
-    widgetValue.FormatPatterns(wsFormattedValue, wsPicture, pLocale,
-                               XFA_VALUEPICTURE_DataBind);
-  }
-  return wsFormattedValue;
-}
-
-WideString CXFA_WidgetAcc::NormalizeNumStr(const WideString& wsValue) {
-  if (wsValue.IsEmpty())
-    return L"";
-
-  WideString wsOutput = wsValue;
-  wsOutput.TrimLeft('0');
-
-  if (!wsOutput.IsEmpty() && wsOutput.Contains('.') && GetFracDigits() != -1) {
-    wsOutput.TrimRight(L"0");
-    wsOutput.TrimRight(L".");
-  }
-  if (wsOutput.IsEmpty() || wsOutput[0] == '.')
-    wsOutput.InsertAtFront('0');
-
-  return wsOutput;
-}
-
-WideString CXFA_WidgetAcc::FormatNumStr(const WideString& wsValue,
-                                        IFX_Locale* pLocale) {
-  if (wsValue.IsEmpty())
-    return L"";
-
-  WideString wsSrcNum = wsValue;
-  WideString wsGroupSymbol =
-      pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Grouping);
-  bool bNeg = false;
-  if (wsSrcNum[0] == '-') {
-    bNeg = true;
-    wsSrcNum.Delete(0, 1);
-  }
-
-  auto dot_index = wsSrcNum.Find('.');
-  dot_index = !dot_index.has_value() ? wsSrcNum.GetLength() : dot_index;
-
-  if (dot_index.value() < 1)
-    return L"";
-
-  size_t nPos = dot_index.value() % 3;
-  WideString wsOutput;
-  for (size_t i = 0; i < dot_index.value(); i++) {
-    if (i % 3 == nPos && i != 0)
-      wsOutput += wsGroupSymbol;
-
-    wsOutput += wsSrcNum[i];
-  }
-  if (dot_index.value() < wsSrcNum.GetLength()) {
-    wsOutput += pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal);
-    wsOutput += wsSrcNum.Right(wsSrcNum.GetLength() - dot_index.value() - 1);
-  }
-  if (bNeg)
-    return pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus) + wsOutput;
-
-  return wsOutput;
-}
-
-void CXFA_WidgetAcc::InsertListTextItem(CXFA_Node* pItems,
-                                        const WideString& wsText,
-                                        int32_t nIndex) {
-  CXFA_Node* pText = pItems->CreateSamePacketNode(XFA_Element::Text);
-  pItems->InsertChild(nIndex, pText);
-  pText->JSObject()->SetContent(wsText, wsText, false, false, false);
-}
-
-WideString CXFA_WidgetAcc::NumericLimit(const WideString& wsValue,
-                                        int32_t iLead,
-                                        int32_t iTread) const {
-  if ((iLead == -1) && (iTread == -1))
-    return wsValue;
-
-  WideString wsRet;
-  int32_t iLead_ = 0, iTread_ = -1;
-  int32_t iCount = wsValue.GetLength();
-  if (iCount == 0)
-    return wsValue;
-
-  int32_t i = 0;
-  if (wsValue[i] == L'-') {
-    wsRet += L'-';
-    i++;
-  }
-  for (; i < iCount; i++) {
-    wchar_t wc = wsValue[i];
-    if (FXSYS_isDecimalDigit(wc)) {
-      if (iLead >= 0) {
-        iLead_++;
-        if (iLead_ > iLead)
-          return L"0";
-      } else if (iTread_ >= 0) {
-        iTread_++;
-        if (iTread_ > iTread) {
-          if (iTread != -1) {
-            CFX_Decimal wsDeci = CFX_Decimal(wsValue.AsStringView());
-            wsDeci.SetScale(iTread);
-            wsRet = wsDeci;
-          }
-          return wsRet;
-        }
-      }
-    } else if (wc == L'.') {
-      iTread_ = 0;
-      iLead = -1;
-    }
-    wsRet += wc;
-  }
-  return wsRet;
-}
diff --git a/xfa/fxfa/cxfa_widgetacc.h b/xfa/fxfa/cxfa_widgetacc.h
deleted file mode 100644
index 8e03018..0000000
--- a/xfa/fxfa/cxfa_widgetacc.h
+++ /dev/null
@@ -1,209 +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 XFA_FXFA_CXFA_WIDGETACC_H_
-#define XFA_FXFA_CXFA_WIDGETACC_H_
-
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include "core/fxcrt/fx_coordinates.h"
-#include "core/fxcrt/fx_string.h"
-#include "core/fxcrt/fx_system.h"
-#include "core/fxcrt/retain_ptr.h"
-#include "core/fxge/dib/cfx_dibitmap.h"
-#include "core/fxge/fx_dib.h"
-#include "xfa/fxfa/fxfa_basic.h"
-
-enum XFA_CHECKSTATE {
-  XFA_CHECKSTATE_On = 0,
-  XFA_CHECKSTATE_Off = 1,
-  XFA_CHECKSTATE_Neutral = 2,
-};
-
-enum XFA_VALUEPICTURE {
-  XFA_VALUEPICTURE_Raw = 0,
-  XFA_VALUEPICTURE_Display,
-  XFA_VALUEPICTURE_Edit,
-  XFA_VALUEPICTURE_DataBind,
-};
-
-class CFGAS_GEFont;
-class CXFA_Bind;
-class CXFA_Border;
-class CXFA_Calculate;
-class CXFA_Caption;
-class CXFA_Event;
-class CXFA_EventParam;
-class CXFA_FFApp;
-class CXFA_FFDoc;
-class CXFA_FFDocView;
-class CXFA_FFWidget;
-class CXFA_Font;
-class CXFA_Margin;
-class CXFA_Node;
-class CXFA_Script;
-class CXFA_Para;
-class CXFA_TextLayout;
-class CXFA_Value;
-class CXFA_Validate;
-class CXFA_WidgetLayoutData;
-class IFX_Locale;
-
-class CXFA_WidgetAcc {
- public:
-  explicit CXFA_WidgetAcc(CXFA_Node* pNode);
-  ~CXFA_WidgetAcc();
-
-  void ResetData();
-
-  CXFA_FFWidget* GetNextWidget(CXFA_FFWidget* pWidget);
-  void StartWidgetLayout(CXFA_FFDoc* doc,
-                         float& fCalcWidth,
-                         float& fCalcHeight);
-  bool FindSplitPos(CXFA_FFDocView* docView,
-                    int32_t iBlockIndex,
-                    float& fCalcHeight);
-
-  bool LoadCaption(CXFA_FFDoc* doc);
-  CXFA_TextLayout* GetCaptionTextLayout();
-
-  void LoadText(CXFA_FFDoc* doc);
-  CXFA_TextLayout* GetTextLayout();
-
-  bool LoadImageImage(CXFA_FFDoc* doc);
-  bool LoadImageEditImage(CXFA_FFDoc* doc);
-  void GetImageDpi(int32_t& iImageXDpi, int32_t& iImageYDpi);
-  void GetImageEditDpi(int32_t& iImageXDpi, int32_t& iImageYDpi);
-
-  RetainPtr<CFX_DIBitmap> GetImageImage();
-  RetainPtr<CFX_DIBitmap> GetImageEditImage();
-  void SetImageEdit(const WideString& wsContentType,
-                    const WideString& wsHref,
-                    const WideString& wsData);
-  void SetImageImage(const RetainPtr<CFX_DIBitmap>& newImage);
-  void SetImageEditImage(const RetainPtr<CFX_DIBitmap>& newImage);
-  void UpdateUIDisplay(CXFA_FFDocView* docView, CXFA_FFWidget* pExcept);
-
-  RetainPtr<CFGAS_GEFont> GetFDEFont(CXFA_FFDoc* doc);
-
-  CXFA_Node* GetNode() const { return m_pNode; }
-
-  bool IsOpenAccess() const;
-  bool IsListBox();
-  bool IsAllowNeutral();
-  bool IsRadioButton();
-  bool IsChoiceListAllowTextEntry();
-  bool IsMultiLine();
-
-  XFA_AttributeEnum GetButtonHighlight();
-  bool HasButtonRollover() const;
-  bool HasButtonDown() const;
-
-  bool IsCheckButtonRound();
-  XFA_AttributeEnum GetCheckButtonMark();
-  float GetCheckButtonSize();
-
-  XFA_CHECKSTATE GetCheckState();
-  void SetCheckState(XFA_CHECKSTATE eCheckState, bool bNotify);
-
-  CXFA_Node* GetSelectedMember();
-  CXFA_Node* SetSelectedMember(const WideStringView& wsName, bool bNotify);
-  void SetSelectedMemberByValue(const WideStringView& wsValue,
-                                bool bNotify,
-                                bool bScriptModify,
-                                bool bSyncData);
-
-  CXFA_Node* GetExclGroupFirstMember();
-  CXFA_Node* GetExclGroupNextMember(CXFA_Node* pNode);
-
-  int32_t CountChoiceListItems(bool bSaveValue);
-  Optional<WideString> GetChoiceListItem(int32_t nIndex, bool bSaveValue);
-  bool IsChoiceListMultiSelect();
-  bool IsChoiceListCommitOnSelect();
-  std::vector<WideString> GetChoiceListItems(bool bSaveValue);
-
-  int32_t CountSelectedItems();
-  int32_t GetSelectedItem(int32_t nIndex);
-  std::vector<int32_t> GetSelectedItems();
-  std::vector<WideString> GetSelectedItemsValue();
-  void SetSelectedItems(const std::vector<int32_t>& iSelArray,
-                        bool bNotify,
-                        bool bScriptModify,
-                        bool bSyncData);
-  void InsertItem(const WideString& wsLabel,
-                  const WideString& wsValue,
-                  bool bNotify);
-  bool DeleteItem(int32_t nIndex, bool bNotify, bool bScriptModify);
-  void ClearAllSelections();
-
-  bool GetItemState(int32_t nIndex);
-  void SetItemState(int32_t nIndex,
-                    bool bSelected,
-                    bool bNotify,
-                    bool bScriptModify,
-                    bool bSyncData);
-
-  WideString GetItemValue(const WideStringView& wsLabel);
-
-  bool IsHorizontalScrollPolicyOff();
-  bool IsVerticalScrollPolicyOff();
-  Optional<int32_t> GetNumberOfCells();
-
-  bool SetValue(XFA_VALUEPICTURE eValueType, const WideString& wsValue);
-  WideString GetValue(XFA_VALUEPICTURE eValueType);
-
-  WideString GetPictureContent(XFA_VALUEPICTURE ePicture);
-  WideString GetNormalizeDataValue(const WideString& wsValue);
-  WideString GetFormatDataValue(const WideString& wsValue);
-  WideString NormalizeNumStr(const WideString& wsValue);
-
-  WideString GetPasswordChar();
-  std::pair<XFA_Element, int32_t> GetMaxChars();
-  int32_t GetFracDigits();
-  int32_t GetLeadDigits();
-
-  WideString NumericLimit(const WideString& wsValue,
-                          int32_t iLead,
-                          int32_t iTread) const;
-
- private:
-  void CalcCaptionSize(CXFA_FFDoc* doc, CFX_SizeF& szCap);
-  bool CalculateFieldAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size);
-  bool CalculateWidgetAutoSize(CFX_SizeF& size);
-  bool CalculateTextEditAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size);
-  bool CalculateCheckButtonAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size);
-  bool CalculatePushButtonAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size);
-  CFX_SizeF CalculateImageSize(float img_width,
-                               float img_height,
-                               float dpi_x,
-                               float dpi_y);
-  bool CalculateImageEditAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size);
-  bool CalculateImageAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size);
-  float CalculateWidgetAutoHeight(float fHeightCalc);
-  float CalculateWidgetAutoWidth(float fWidthCalc);
-  float GetWidthWithoutMargin(float fWidthCalc);
-  float GetHeightWithoutMargin(float fHeightCalc);
-  void CalculateTextContentSize(CXFA_FFDoc* doc, CFX_SizeF& size);
-  void CalculateAccWidthAndHeight(CXFA_FFDoc* doc,
-                                  XFA_Element eUIType,
-                                  float& fWidth,
-                                  float& fCalcHeight);
-  void InitLayoutData();
-  void StartTextLayout(CXFA_FFDoc* doc, float& fCalcWidth, float& fCalcHeight);
-
-  void InsertListTextItem(CXFA_Node* pItems,
-                          const WideString& wsText,
-                          int32_t nIndex);
-  WideString FormatNumStr(const WideString& wsValue, IFX_Locale* pLocale);
-  void GetItemLabel(const WideStringView& wsValue, WideString& wsLabel);
-
-  std::unique_ptr<CXFA_WidgetLayoutData> m_pLayoutData;
-  CXFA_Node* m_pNode;
-};
-
-#endif  // XFA_FXFA_CXFA_WIDGETACC_H_
diff --git a/xfa/fxfa/parser/cxfa_localevalue.h b/xfa/fxfa/parser/cxfa_localevalue.h
index 60de601..44db7b1 100644
--- a/xfa/fxfa/parser/cxfa_localevalue.h
+++ b/xfa/fxfa/parser/cxfa_localevalue.h
@@ -9,7 +9,7 @@
 
 #include "core/fxcrt/fx_string.h"
 #include "core/fxcrt/fx_system.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
+#include "xfa/fxfa/parser/cxfa_node.h"
 
 class IFX_Locale;
 class CFX_DateTime;
diff --git a/xfa/fxfa/parser/cxfa_node.cpp b/xfa/fxfa/parser/cxfa_node.cpp
index ba882a2..988d1e2 100644
--- a/xfa/fxfa/parser/cxfa_node.cpp
+++ b/xfa/fxfa/parser/cxfa_node.cpp
@@ -6,6 +6,7 @@
 
 #include "xfa/fxfa/parser/cxfa_node.h"
 
+#include <algorithm>
 #include <map>
 #include <memory>
 #include <set>
@@ -20,26 +21,35 @@
 #include "core/fxcrt/xml/cfx_xmlelement.h"
 #include "core/fxcrt/xml/cfx_xmlnode.h"
 #include "core/fxcrt/xml/cfx_xmltext.h"
+#include "core/fxge/dib/cfx_dibitmap.h"
 #include "fxjs/cfxjse_engine.h"
 #include "fxjs/cfxjse_value.h"
 #include "fxjs/xfa/cjx_node.h"
 #include "third_party/base/logging.h"
 #include "third_party/base/ptr_util.h"
 #include "third_party/base/stl_util.h"
+#include "xfa/fde/cfde_textout.h"
+#include "xfa/fgas/font/cfgas_fontmgr.h"
 #include "xfa/fxfa/cxfa_eventparam.h"
 #include "xfa/fxfa/cxfa_ffapp.h"
 #include "xfa/fxfa/cxfa_ffdocview.h"
 #include "xfa/fxfa/cxfa_ffnotify.h"
 #include "xfa/fxfa/cxfa_ffwidget.h"
+#include "xfa/fxfa/cxfa_fontmgr.h"
+#include "xfa/fxfa/cxfa_textprovider.h"
 #include "xfa/fxfa/parser/cxfa_arraynodelist.h"
 #include "xfa/fxfa/parser/cxfa_attachnodelist.h"
 #include "xfa/fxfa/parser/cxfa_bind.h"
 #include "xfa/fxfa/parser/cxfa_border.h"
 #include "xfa/fxfa/parser/cxfa_calculate.h"
 #include "xfa/fxfa/parser/cxfa_caption.h"
+#include "xfa/fxfa/parser/cxfa_comb.h"
+#include "xfa/fxfa/parser/cxfa_decimal.h"
 #include "xfa/fxfa/parser/cxfa_document.h"
 #include "xfa/fxfa/parser/cxfa_event.h"
 #include "xfa/fxfa/parser/cxfa_font.h"
+#include "xfa/fxfa/parser/cxfa_format.h"
+#include "xfa/fxfa/parser/cxfa_image.h"
 #include "xfa/fxfa/parser/cxfa_items.h"
 #include "xfa/fxfa/parser/cxfa_keep.h"
 #include "xfa/fxfa/parser/cxfa_layoutprocessor.h"
@@ -49,6 +59,7 @@
 #include "xfa/fxfa/parser/cxfa_nodeiteratortemplate.h"
 #include "xfa/fxfa/parser/cxfa_occur.h"
 #include "xfa/fxfa/parser/cxfa_para.h"
+#include "xfa/fxfa/parser/cxfa_picture.h"
 #include "xfa/fxfa/parser/cxfa_simple_parser.h"
 #include "xfa/fxfa/parser/cxfa_stroke.h"
 #include "xfa/fxfa/parser/cxfa_subform.h"
@@ -59,10 +70,301 @@
 #include "xfa/fxfa/parser/xfa_basic_data.h"
 #include "xfa/fxfa/parser/xfa_utils.h"
 
+class CXFA_WidgetLayoutData {
+ public:
+  CXFA_WidgetLayoutData() : m_fWidgetHeight(-1) {}
+  virtual ~CXFA_WidgetLayoutData() {}
+
+  float m_fWidgetHeight;
+};
+
 namespace {
 
 constexpr uint8_t kMaxExecuteRecursion = 2;
 
+constexpr uint8_t g_inv_base64[128] = {
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62,  255,
+    255, 255, 63,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  255, 255,
+    255, 255, 255, 255, 255, 0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
+    10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,
+    25,  255, 255, 255, 255, 255, 255, 26,  27,  28,  29,  30,  31,  32,  33,
+    34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48,
+    49,  50,  51,  255, 255, 255, 255, 255,
+};
+
+uint8_t* XFA_RemoveBase64Whitespace(const uint8_t* pStr, int32_t iLen) {
+  uint8_t* pCP;
+  int32_t i = 0, j = 0;
+  if (iLen == 0) {
+    iLen = strlen((char*)pStr);
+  }
+  pCP = FX_Alloc(uint8_t, iLen + 1);
+  for (; i < iLen; i++) {
+    if ((pStr[i] & 128) == 0) {
+      if (g_inv_base64[pStr[i]] != 0xFF || pStr[i] == '=') {
+        pCP[j++] = pStr[i];
+      }
+    }
+  }
+  pCP[j] = '\0';
+  return pCP;
+}
+
+int32_t XFA_Base64Decode(const char* pStr, uint8_t* pOutBuffer) {
+  if (!pStr) {
+    return 0;
+  }
+  uint8_t* pBuffer =
+      XFA_RemoveBase64Whitespace((uint8_t*)pStr, strlen((char*)pStr));
+  if (!pBuffer) {
+    return 0;
+  }
+  int32_t iLen = strlen((char*)pBuffer);
+  int32_t i = 0, j = 0;
+  uint32_t dwLimb = 0;
+  for (; i + 3 < iLen; i += 4) {
+    if (pBuffer[i] == '=' || pBuffer[i + 1] == '=' || pBuffer[i + 2] == '=' ||
+        pBuffer[i + 3] == '=') {
+      if (pBuffer[i] == '=' || pBuffer[i + 1] == '=') {
+        break;
+      }
+      if (pBuffer[i + 2] == '=') {
+        dwLimb = ((uint32_t)g_inv_base64[pBuffer[i]] << 6) |
+                 ((uint32_t)g_inv_base64[pBuffer[i + 1]]);
+        pOutBuffer[j] = (uint8_t)(dwLimb >> 4) & 0xFF;
+        j++;
+      } else {
+        dwLimb = ((uint32_t)g_inv_base64[pBuffer[i]] << 12) |
+                 ((uint32_t)g_inv_base64[pBuffer[i + 1]] << 6) |
+                 ((uint32_t)g_inv_base64[pBuffer[i + 2]]);
+        pOutBuffer[j] = (uint8_t)(dwLimb >> 10) & 0xFF;
+        pOutBuffer[j + 1] = (uint8_t)(dwLimb >> 2) & 0xFF;
+        j += 2;
+      }
+    } else {
+      dwLimb = ((uint32_t)g_inv_base64[pBuffer[i]] << 18) |
+               ((uint32_t)g_inv_base64[pBuffer[i + 1]] << 12) |
+               ((uint32_t)g_inv_base64[pBuffer[i + 2]] << 6) |
+               ((uint32_t)g_inv_base64[pBuffer[i + 3]]);
+      pOutBuffer[j] = (uint8_t)(dwLimb >> 16) & 0xff;
+      pOutBuffer[j + 1] = (uint8_t)(dwLimb >> 8) & 0xff;
+      pOutBuffer[j + 2] = (uint8_t)(dwLimb)&0xff;
+      j += 3;
+    }
+  }
+  FX_Free(pBuffer);
+  return j;
+}
+
+FXCODEC_IMAGE_TYPE XFA_GetImageType(const WideString& wsType) {
+  WideString wsContentType(wsType);
+  wsContentType.MakeLower();
+  if (wsContentType == L"image/jpg")
+    return FXCODEC_IMAGE_JPG;
+  if (wsContentType == L"image/png")
+    return FXCODEC_IMAGE_PNG;
+  if (wsContentType == L"image/gif")
+    return FXCODEC_IMAGE_GIF;
+  if (wsContentType == L"image/bmp")
+    return FXCODEC_IMAGE_BMP;
+  if (wsContentType == L"image/tif")
+    return FXCODEC_IMAGE_TIF;
+  return FXCODEC_IMAGE_UNKNOWN;
+}
+
+RetainPtr<CFX_DIBitmap> XFA_LoadImageData(CXFA_FFDoc* pDoc,
+                                          CXFA_Image* pImage,
+                                          bool& bNameImage,
+                                          int32_t& iImageXDpi,
+                                          int32_t& iImageYDpi) {
+  WideString wsHref = pImage->GetHref();
+  WideString wsImage = pImage->GetContent();
+  if (wsHref.IsEmpty() && wsImage.IsEmpty())
+    return nullptr;
+
+  FXCODEC_IMAGE_TYPE type = XFA_GetImageType(pImage->GetContentType());
+  ByteString bsContent;
+  uint8_t* pImageBuffer = nullptr;
+  RetainPtr<IFX_SeekableReadStream> pImageFileRead;
+  if (wsImage.GetLength() > 0) {
+    XFA_AttributeEnum iEncoding = pImage->GetTransferEncoding();
+    if (iEncoding == XFA_AttributeEnum::Base64) {
+      ByteString bsData = wsImage.UTF8Encode();
+      int32_t iLength = bsData.GetLength();
+      pImageBuffer = FX_Alloc(uint8_t, iLength);
+      int32_t iRead = XFA_Base64Decode(bsData.c_str(), pImageBuffer);
+      if (iRead > 0) {
+        pImageFileRead =
+            pdfium::MakeRetain<CFX_MemoryStream>(pImageBuffer, iRead, false);
+      }
+    } else {
+      bsContent = ByteString::FromUnicode(wsImage);
+      pImageFileRead = pdfium::MakeRetain<CFX_MemoryStream>(
+          const_cast<uint8_t*>(bsContent.raw_str()), bsContent.GetLength(),
+          false);
+    }
+  } else {
+    WideString wsURL = wsHref;
+    if (wsURL.Left(7) != L"http://" && wsURL.Left(6) != L"ftp://") {
+      RetainPtr<CFX_DIBitmap> pBitmap =
+          pDoc->GetPDFNamedImage(wsURL.AsStringView(), iImageXDpi, iImageYDpi);
+      if (pBitmap) {
+        bNameImage = true;
+        return pBitmap;
+      }
+    }
+    pImageFileRead = pDoc->GetDocEnvironment()->OpenLinkedFile(pDoc, wsURL);
+  }
+  if (!pImageFileRead) {
+    FX_Free(pImageBuffer);
+    return nullptr;
+  }
+  bNameImage = false;
+  RetainPtr<CFX_DIBitmap> pBitmap =
+      XFA_LoadImageFromBuffer(pImageFileRead, type, iImageXDpi, iImageYDpi);
+  FX_Free(pImageBuffer);
+  return pBitmap;
+}
+
+class CXFA_TextLayoutData : public CXFA_WidgetLayoutData {
+ public:
+  CXFA_TextLayoutData() {}
+  ~CXFA_TextLayoutData() override {}
+
+  CXFA_TextLayout* GetTextLayout() const { return m_pTextLayout.get(); }
+  CXFA_TextProvider* GetTextProvider() const { return m_pTextProvider.get(); }
+
+  void LoadText(CXFA_FFDoc* doc, CXFA_Node* pNode) {
+    if (m_pTextLayout)
+      return;
+
+    m_pTextProvider =
+        pdfium::MakeUnique<CXFA_TextProvider>(pNode, XFA_TEXTPROVIDERTYPE_Text);
+    m_pTextLayout =
+        pdfium::MakeUnique<CXFA_TextLayout>(doc, m_pTextProvider.get());
+  }
+
+ private:
+  std::unique_ptr<CXFA_TextLayout> m_pTextLayout;
+  std::unique_ptr<CXFA_TextProvider> m_pTextProvider;
+};
+
+class CXFA_ImageLayoutData : public CXFA_WidgetLayoutData {
+ public:
+  CXFA_ImageLayoutData()
+      : m_bNamedImage(false), m_iImageXDpi(0), m_iImageYDpi(0) {}
+
+  ~CXFA_ImageLayoutData() override {}
+
+  bool LoadImageData(CXFA_FFDoc* doc, CXFA_Node* pNode) {
+    if (m_pDIBitmap)
+      return true;
+
+    CXFA_Value* value = pNode->GetFormValueIfExists();
+    if (!value)
+      return false;
+
+    CXFA_Image* image = value->GetImageIfExists();
+    if (!image)
+      return false;
+
+    pNode->SetImageImage(XFA_LoadImageData(doc, image, m_bNamedImage,
+                                           m_iImageXDpi, m_iImageYDpi));
+    return !!m_pDIBitmap;
+  }
+
+  RetainPtr<CFX_DIBitmap> m_pDIBitmap;
+  bool m_bNamedImage;
+  int32_t m_iImageXDpi;
+  int32_t m_iImageYDpi;
+};
+
+class CXFA_FieldLayoutData : public CXFA_WidgetLayoutData {
+ public:
+  CXFA_FieldLayoutData() {}
+  ~CXFA_FieldLayoutData() override {}
+
+  bool LoadCaption(CXFA_FFDoc* doc, CXFA_Node* pNode) {
+    if (m_pCapTextLayout)
+      return true;
+    CXFA_Caption* caption = pNode->GetCaptionIfExists();
+    if (!caption || caption->IsHidden())
+      return false;
+
+    m_pCapTextProvider = pdfium::MakeUnique<CXFA_TextProvider>(
+        pNode, XFA_TEXTPROVIDERTYPE_Caption);
+    m_pCapTextLayout =
+        pdfium::MakeUnique<CXFA_TextLayout>(doc, m_pCapTextProvider.get());
+    return true;
+  }
+
+  std::unique_ptr<CXFA_TextLayout> m_pCapTextLayout;
+  std::unique_ptr<CXFA_TextProvider> m_pCapTextProvider;
+  std::unique_ptr<CFDE_TextOut> m_pTextOut;
+  std::vector<float> m_FieldSplitArray;
+};
+
+class CXFA_TextEditData : public CXFA_FieldLayoutData {};
+
+class CXFA_ImageEditData : public CXFA_FieldLayoutData {
+ public:
+  CXFA_ImageEditData()
+      : m_bNamedImage(false), m_iImageXDpi(0), m_iImageYDpi(0) {}
+
+  ~CXFA_ImageEditData() override {}
+
+  bool LoadImageData(CXFA_FFDoc* doc, CXFA_Node* pNode) {
+    if (m_pDIBitmap)
+      return true;
+
+    CXFA_Value* value = pNode->GetFormValueIfExists();
+    if (!value)
+      return false;
+
+    CXFA_Image* image = value->GetImageIfExists();
+    if (!image)
+      return false;
+
+    pNode->SetImageEditImage(XFA_LoadImageData(doc, image, m_bNamedImage,
+                                               m_iImageXDpi, m_iImageYDpi));
+    return !!m_pDIBitmap;
+  }
+
+  RetainPtr<CFX_DIBitmap> m_pDIBitmap;
+  bool m_bNamedImage;
+  int32_t m_iImageXDpi;
+  int32_t m_iImageYDpi;
+};
+
+bool SplitDateTime(const WideString& wsDateTime,
+                   WideString& wsDate,
+                   WideString& wsTime) {
+  wsDate = L"";
+  wsTime = L"";
+  if (wsDateTime.IsEmpty())
+    return false;
+
+  auto nSplitIndex = wsDateTime.Find('T');
+  if (!nSplitIndex.has_value())
+    nSplitIndex = wsDateTime.Find(' ');
+  if (!nSplitIndex.has_value())
+    return false;
+
+  wsDate = wsDateTime.Left(nSplitIndex.value());
+  if (!wsDate.IsEmpty()) {
+    if (!std::any_of(wsDate.begin(), wsDate.end(), std::iswdigit))
+      return false;
+  }
+  wsTime = wsDateTime.Right(wsDateTime.GetLength() - nSplitIndex.value() - 1);
+  if (!wsTime.IsEmpty()) {
+    if (!std::any_of(wsTime.begin(), wsTime.end(), std::iswdigit))
+      return false;
+  }
+  return true;
+}
+
 std::vector<CXFA_Node*> NodesSortedByDocumentIdx(
     const std::set<CXFA_Node*>& rgNodeSet) {
   if (rgNodeSet.empty())
@@ -360,7 +662,8 @@
       m_ePacket(ePacket),
       m_uNodeFlags(XFA_NodeFlag_None),
       m_dwNameHash(0),
-      m_pAuxNode(nullptr) {
+      m_pAuxNode(nullptr),
+      m_pNode(this) {
   ASSERT(m_pDocument);
 }
 
@@ -735,7 +1038,7 @@
     return nullptr;
 
   if (eType == XFA_Element::Field) {
-    CXFA_WidgetAcc* pFieldWidgetAcc = GetWidgetAcc();
+    CXFA_Node* pFieldWidgetAcc = GetWidgetAcc();
     if (pFieldWidgetAcc && pFieldWidgetAcc->IsChoiceListMultiSelect())
       return nullptr;
 
@@ -1829,11 +2132,6 @@
   return pExcl;
 }
 
-void CXFA_Node::SetWidgetReady() {
-  acc_ = pdfium::MakeUnique<CXFA_WidgetAcc>(AsNode());
-  is_widget_ready_ = true;
-}
-
 int32_t CXFA_Node::ProcessEvent(CXFA_FFDocView* docView,
                                 XFA_AttributeEnum iActivity,
                                 CXFA_EventParam* pEventParam) {
@@ -2457,3 +2755,2134 @@
   }
   return events;
 }
+
+void CXFA_Node::ResetData() {
+  WideString wsValue;
+  switch (m_pNode->GetUIType()) {
+    case XFA_Element::ImageEdit: {
+      CXFA_Value* imageValue = m_pNode->GetDefaultValueIfExists();
+      CXFA_Image* image = imageValue ? imageValue->GetImageIfExists() : nullptr;
+      WideString wsContentType, wsHref;
+      if (image) {
+        wsValue = image->GetContent();
+        wsContentType = image->GetContentType();
+        wsHref = image->GetHref();
+      }
+      SetImageEdit(wsContentType, wsHref, wsValue);
+      break;
+    }
+    case XFA_Element::ExclGroup: {
+      CXFA_Node* pNextChild = m_pNode->GetFirstContainerChild();
+      while (pNextChild) {
+        CXFA_Node* pChild = pNextChild;
+        if (!pChild->IsWidgetReady())
+          continue;
+
+        CXFA_Node* pAcc = pChild->GetWidgetAcc();
+        bool done = false;
+        if (wsValue.IsEmpty()) {
+          CXFA_Value* defValue = pAcc->GetNode()->GetDefaultValueIfExists();
+          if (defValue) {
+            wsValue = defValue->GetChildValueContent();
+            SetValue(XFA_VALUEPICTURE_Raw, wsValue);
+            pAcc->SetValue(XFA_VALUEPICTURE_Raw, wsValue);
+            done = true;
+          }
+        }
+        if (!done) {
+          CXFA_Items* pItems =
+              pChild->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
+          if (!pItems)
+            continue;
+
+          WideString itemText;
+          if (pItems->CountChildren(XFA_Element::Unknown, false) > 1) {
+            itemText =
+                pItems->GetChild<CXFA_Node>(1, XFA_Element::Unknown, false)
+                    ->JSObject()
+                    ->GetContent(false);
+          }
+          pAcc->SetValue(XFA_VALUEPICTURE_Raw, itemText);
+        }
+        pNextChild = pChild->GetNextContainerSibling();
+      }
+      break;
+    }
+    case XFA_Element::ChoiceList:
+      ClearAllSelections();
+    default: {
+      CXFA_Value* defValue = m_pNode->GetDefaultValueIfExists();
+      if (defValue)
+        wsValue = defValue->GetChildValueContent();
+
+      SetValue(XFA_VALUEPICTURE_Raw, wsValue);
+      break;
+    }
+  }
+}
+
+void CXFA_Node::SetImageEdit(const WideString& wsContentType,
+                             const WideString& wsHref,
+                             const WideString& wsData) {
+  CXFA_Value* formValue = m_pNode->GetFormValueIfExists();
+  CXFA_Image* image = formValue ? formValue->GetImageIfExists() : nullptr;
+  if (image) {
+    image->SetContentType(WideString(wsContentType));
+    image->SetHref(wsHref);
+  }
+
+  m_pNode->JSObject()->SetContent(wsData, GetFormatDataValue(wsData), true,
+                                  false, true);
+
+  CXFA_Node* pBind = m_pNode->GetBindData();
+  if (!pBind) {
+    if (image)
+      image->SetTransferEncoding(XFA_AttributeEnum::Base64);
+    return;
+  }
+  pBind->JSObject()->SetCData(XFA_Attribute::ContentType, wsContentType, false,
+                              false);
+  CXFA_Node* pHrefNode = pBind->GetFirstChild();
+  if (pHrefNode) {
+    pHrefNode->JSObject()->SetCData(XFA_Attribute::Value, wsHref, false, false);
+  } else {
+    CFX_XMLNode* pXMLNode = pBind->GetXMLMappingNode();
+    ASSERT(pXMLNode && pXMLNode->GetType() == FX_XMLNODE_Element);
+    static_cast<CFX_XMLElement*>(pXMLNode)->SetString(L"href", wsHref);
+  }
+}
+
+CXFA_FFWidget* CXFA_Node::GetNextWidget(CXFA_FFWidget* pWidget) {
+  return static_cast<CXFA_FFWidget*>(pWidget->GetNext());
+}
+
+void CXFA_Node::UpdateUIDisplay(CXFA_FFDocView* docView,
+                                CXFA_FFWidget* pExcept) {
+  CXFA_FFWidget* pWidget = docView->GetWidgetForNode(m_pNode);
+  for (; pWidget; pWidget = GetNextWidget(pWidget)) {
+    if (pWidget == pExcept || !pWidget->IsLoaded() ||
+        (m_pNode->GetUIType() != XFA_Element::CheckButton &&
+         pWidget->IsFocused())) {
+      continue;
+    }
+    pWidget->UpdateFWLData();
+    pWidget->AddInvalidateRect();
+  }
+}
+
+void CXFA_Node::CalcCaptionSize(CXFA_FFDoc* doc, CFX_SizeF& szCap) {
+  CXFA_Caption* caption = m_pNode->GetCaptionIfExists();
+  if (!caption || !caption->IsVisible())
+    return;
+
+  LoadCaption(doc);
+
+  XFA_Element eUIType = m_pNode->GetUIType();
+  XFA_AttributeEnum iCapPlacement = caption->GetPlacementType();
+  float fCapReserve = caption->GetReserve();
+  const bool bVert = iCapPlacement == XFA_AttributeEnum::Top ||
+                     iCapPlacement == XFA_AttributeEnum::Bottom;
+  const bool bReserveExit = fCapReserve > 0.01;
+  CXFA_TextLayout* pCapTextLayout =
+      static_cast<CXFA_FieldLayoutData*>(m_pLayoutData.get())
+          ->m_pCapTextLayout.get();
+  if (pCapTextLayout) {
+    if (!bVert && eUIType != XFA_Element::Button)
+      szCap.width = fCapReserve;
+
+    CFX_SizeF minSize;
+    szCap = pCapTextLayout->CalcSize(minSize, szCap);
+    if (bReserveExit)
+      bVert ? szCap.height = fCapReserve : szCap.width = fCapReserve;
+  } else {
+    float fFontSize = 10.0f;
+    CXFA_Font* font = caption->GetFontIfExists();
+    if (font) {
+      fFontSize = font->GetFontSize();
+    } else {
+      CXFA_Font* widgetfont = m_pNode->GetFontIfExists();
+      if (widgetfont)
+        fFontSize = widgetfont->GetFontSize();
+    }
+
+    if (bVert) {
+      szCap.height = fCapReserve > 0 ? fCapReserve : fFontSize;
+    } else {
+      szCap.width = fCapReserve > 0 ? fCapReserve : 0;
+      szCap.height = fFontSize;
+    }
+  }
+
+  CXFA_Margin* captionMargin = caption->GetMarginIfExists();
+  if (!captionMargin)
+    return;
+
+  float fLeftInset = captionMargin->GetLeftInset();
+  float fTopInset = captionMargin->GetTopInset();
+  float fRightInset = captionMargin->GetRightInset();
+  float fBottomInset = captionMargin->GetBottomInset();
+  if (bReserveExit) {
+    bVert ? (szCap.width += fLeftInset + fRightInset)
+          : (szCap.height += fTopInset + fBottomInset);
+  } else {
+    szCap.width += fLeftInset + fRightInset;
+    szCap.height += fTopInset + fBottomInset;
+  }
+}
+
+bool CXFA_Node::CalculateFieldAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size) {
+  CFX_SizeF szCap;
+  CalcCaptionSize(doc, szCap);
+
+  CFX_RectF rtUIMargin = m_pNode->GetUIMargin();
+  size.width += rtUIMargin.left + rtUIMargin.width;
+  size.height += rtUIMargin.top + rtUIMargin.height;
+  if (szCap.width > 0 && szCap.height > 0) {
+    CXFA_Caption* caption = m_pNode->GetCaptionIfExists();
+    XFA_AttributeEnum placement = caption ? caption->GetPlacementType()
+                                          : CXFA_Caption::kDefaultPlacementType;
+    switch (placement) {
+      case XFA_AttributeEnum::Left:
+      case XFA_AttributeEnum::Right:
+      case XFA_AttributeEnum::Inline: {
+        size.width += szCap.width;
+        size.height = std::max(size.height, szCap.height);
+      } break;
+      case XFA_AttributeEnum::Top:
+      case XFA_AttributeEnum::Bottom: {
+        size.height += szCap.height;
+        size.width = std::max(size.width, szCap.width);
+      }
+      default:
+        break;
+    }
+  }
+  return CalculateWidgetAutoSize(size);
+}
+
+bool CXFA_Node::CalculateWidgetAutoSize(CFX_SizeF& size) {
+  CXFA_Margin* margin = m_pNode->GetMarginIfExists();
+  if (margin) {
+    size.width += margin->GetLeftInset() + margin->GetRightInset();
+    size.height += margin->GetTopInset() + margin->GetBottomInset();
+  }
+
+  CXFA_Para* para = m_pNode->GetParaIfExists();
+  if (para)
+    size.width += para->GetMarginLeft() + para->GetTextIndent();
+
+  Optional<float> width = m_pNode->TryWidth();
+  if (width) {
+    size.width = *width;
+  } else {
+    Optional<float> min = m_pNode->TryMinWidth();
+    if (min)
+      size.width = std::max(size.width, *min);
+
+    Optional<float> max = m_pNode->TryMaxWidth();
+    if (max && *max > 0)
+      size.width = std::min(size.width, *max);
+  }
+
+  Optional<float> height = m_pNode->TryHeight();
+  if (height) {
+    size.height = *height;
+  } else {
+    Optional<float> min = m_pNode->TryMinHeight();
+    if (min)
+      size.height = std::max(size.height, *min);
+
+    Optional<float> max = m_pNode->TryMaxHeight();
+    if (max && *max > 0)
+      size.height = std::min(size.height, *max);
+  }
+  return true;
+}
+
+void CXFA_Node::CalculateTextContentSize(CXFA_FFDoc* doc, CFX_SizeF& size) {
+  float fFontSize = m_pNode->GetFontSize();
+  WideString wsText = GetValue(XFA_VALUEPICTURE_Display);
+  if (wsText.IsEmpty()) {
+    size.height += fFontSize;
+    return;
+  }
+
+  wchar_t wcEnter = '\n';
+  wchar_t wsLast = wsText[wsText.GetLength() - 1];
+  if (wsLast == wcEnter)
+    wsText = wsText + wcEnter;
+
+  CXFA_FieldLayoutData* layoutData =
+      static_cast<CXFA_FieldLayoutData*>(m_pLayoutData.get());
+  if (!layoutData->m_pTextOut) {
+    layoutData->m_pTextOut = pdfium::MakeUnique<CFDE_TextOut>();
+    CFDE_TextOut* pTextOut = layoutData->m_pTextOut.get();
+    pTextOut->SetFont(GetFDEFont(doc));
+    pTextOut->SetFontSize(fFontSize);
+    pTextOut->SetLineBreakTolerance(fFontSize * 0.2f);
+    pTextOut->SetLineSpace(m_pNode->GetLineHeight());
+
+    FDE_TextStyle dwStyles;
+    dwStyles.last_line_height_ = true;
+    if (m_pNode->GetUIType() == XFA_Element::TextEdit && IsMultiLine())
+      dwStyles.line_wrap_ = true;
+
+    pTextOut->SetStyles(dwStyles);
+  }
+  layoutData->m_pTextOut->CalcLogicSize(wsText, size);
+}
+
+bool CXFA_Node::CalculateTextEditAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size) {
+  if (size.width > 0) {
+    CFX_SizeF szOrz = size;
+    CFX_SizeF szCap;
+    CalcCaptionSize(doc, szCap);
+    bool bCapExit = szCap.width > 0.01 && szCap.height > 0.01;
+    XFA_AttributeEnum iCapPlacement = XFA_AttributeEnum::Unknown;
+    if (bCapExit) {
+      CXFA_Caption* caption = m_pNode->GetCaptionIfExists();
+      iCapPlacement = caption ? caption->GetPlacementType()
+                              : CXFA_Caption::kDefaultPlacementType;
+      switch (iCapPlacement) {
+        case XFA_AttributeEnum::Left:
+        case XFA_AttributeEnum::Right:
+        case XFA_AttributeEnum::Inline: {
+          size.width -= szCap.width;
+        }
+        default:
+          break;
+      }
+    }
+    CFX_RectF rtUIMargin = m_pNode->GetUIMargin();
+    size.width -= rtUIMargin.left + rtUIMargin.width;
+    CXFA_Margin* margin = m_pNode->GetMarginIfExists();
+    if (margin)
+      size.width -= margin->GetLeftInset() + margin->GetRightInset();
+
+    CalculateTextContentSize(doc, size);
+    size.height += rtUIMargin.top + rtUIMargin.height;
+    if (bCapExit) {
+      switch (iCapPlacement) {
+        case XFA_AttributeEnum::Left:
+        case XFA_AttributeEnum::Right:
+        case XFA_AttributeEnum::Inline: {
+          size.height = std::max(size.height, szCap.height);
+        } break;
+        case XFA_AttributeEnum::Top:
+        case XFA_AttributeEnum::Bottom: {
+          size.height += szCap.height;
+        }
+        default:
+          break;
+      }
+    }
+    size.width = szOrz.width;
+    return CalculateWidgetAutoSize(size);
+  }
+  CalculateTextContentSize(doc, size);
+  return CalculateFieldAutoSize(doc, size);
+}
+
+bool CXFA_Node::CalculateCheckButtonAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size) {
+  float fCheckSize = GetCheckButtonSize();
+  size = CFX_SizeF(fCheckSize, fCheckSize);
+  return CalculateFieldAutoSize(doc, size);
+}
+
+bool CXFA_Node::CalculatePushButtonAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size) {
+  CalcCaptionSize(doc, size);
+  return CalculateWidgetAutoSize(size);
+}
+
+CFX_SizeF CXFA_Node::CalculateImageSize(float img_width,
+                                        float img_height,
+                                        float dpi_x,
+                                        float dpi_y) {
+  CFX_RectF rtImage(0, 0, XFA_UnitPx2Pt(img_width, dpi_x),
+                    XFA_UnitPx2Pt(img_height, dpi_y));
+
+  CFX_RectF rtFit;
+  Optional<float> width = m_pNode->TryWidth();
+  if (width) {
+    rtFit.width = *width;
+    GetWidthWithoutMargin(rtFit.width);
+  } else {
+    rtFit.width = rtImage.width;
+  }
+
+  Optional<float> height = m_pNode->TryHeight();
+  if (height) {
+    rtFit.height = *height;
+    GetHeightWithoutMargin(rtFit.height);
+  } else {
+    rtFit.height = rtImage.height;
+  }
+
+  return rtFit.Size();
+}
+
+bool CXFA_Node::CalculateImageAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size) {
+  if (!GetImageImage())
+    LoadImageImage(doc);
+
+  size.clear();
+  RetainPtr<CFX_DIBitmap> pBitmap = GetImageImage();
+  if (!pBitmap)
+    return CalculateWidgetAutoSize(size);
+
+  int32_t iImageXDpi = 0;
+  int32_t iImageYDpi = 0;
+  GetImageDpi(iImageXDpi, iImageYDpi);
+
+  size = CalculateImageSize(pBitmap->GetWidth(), pBitmap->GetHeight(),
+                            iImageXDpi, iImageYDpi);
+  return CalculateWidgetAutoSize(size);
+}
+
+bool CXFA_Node::CalculateImageEditAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size) {
+  if (!GetImageEditImage())
+    LoadImageEditImage(doc);
+
+  size.clear();
+  RetainPtr<CFX_DIBitmap> pBitmap = GetImageEditImage();
+  if (!pBitmap)
+    return CalculateFieldAutoSize(doc, size);
+
+  int32_t iImageXDpi = 0;
+  int32_t iImageYDpi = 0;
+  GetImageEditDpi(iImageXDpi, iImageYDpi);
+
+  size = CalculateImageSize(pBitmap->GetWidth(), pBitmap->GetHeight(),
+                            iImageXDpi, iImageYDpi);
+  return CalculateFieldAutoSize(doc, size);
+}
+
+bool CXFA_Node::LoadImageImage(CXFA_FFDoc* doc) {
+  InitLayoutData();
+  return static_cast<CXFA_ImageLayoutData*>(m_pLayoutData.get())
+      ->LoadImageData(doc, this);
+}
+
+bool CXFA_Node::LoadImageEditImage(CXFA_FFDoc* doc) {
+  InitLayoutData();
+  return static_cast<CXFA_ImageEditData*>(m_pLayoutData.get())
+      ->LoadImageData(doc, this);
+}
+
+void CXFA_Node::GetImageDpi(int32_t& iImageXDpi, int32_t& iImageYDpi) {
+  CXFA_ImageLayoutData* pData =
+      static_cast<CXFA_ImageLayoutData*>(m_pLayoutData.get());
+  iImageXDpi = pData->m_iImageXDpi;
+  iImageYDpi = pData->m_iImageYDpi;
+}
+
+void CXFA_Node::GetImageEditDpi(int32_t& iImageXDpi, int32_t& iImageYDpi) {
+  CXFA_ImageEditData* pData =
+      static_cast<CXFA_ImageEditData*>(m_pLayoutData.get());
+  iImageXDpi = pData->m_iImageXDpi;
+  iImageYDpi = pData->m_iImageYDpi;
+}
+
+void CXFA_Node::LoadText(CXFA_FFDoc* doc) {
+  InitLayoutData();
+  static_cast<CXFA_TextLayoutData*>(m_pLayoutData.get())->LoadText(doc, this);
+}
+
+float CXFA_Node::CalculateWidgetAutoWidth(float fWidthCalc) {
+  CXFA_Margin* margin = m_pNode->GetMarginIfExists();
+  if (margin)
+    fWidthCalc += margin->GetLeftInset() + margin->GetRightInset();
+
+  Optional<float> min = m_pNode->TryMinWidth();
+  if (min)
+    fWidthCalc = std::max(fWidthCalc, *min);
+
+  Optional<float> max = m_pNode->TryMaxWidth();
+  if (max && *max > 0)
+    fWidthCalc = std::min(fWidthCalc, *max);
+
+  return fWidthCalc;
+}
+
+float CXFA_Node::GetWidthWithoutMargin(float fWidthCalc) {
+  CXFA_Margin* margin = m_pNode->GetMarginIfExists();
+  if (margin)
+    fWidthCalc -= margin->GetLeftInset() + margin->GetRightInset();
+  return fWidthCalc;
+}
+
+float CXFA_Node::CalculateWidgetAutoHeight(float fHeightCalc) {
+  CXFA_Margin* margin = m_pNode->GetMarginIfExists();
+  if (margin)
+    fHeightCalc += margin->GetTopInset() + margin->GetBottomInset();
+
+  Optional<float> min = m_pNode->TryMinHeight();
+  if (min)
+    fHeightCalc = std::max(fHeightCalc, *min);
+
+  Optional<float> max = m_pNode->TryMaxHeight();
+  if (max && *max > 0)
+    fHeightCalc = std::min(fHeightCalc, *max);
+
+  return fHeightCalc;
+}
+
+float CXFA_Node::GetHeightWithoutMargin(float fHeightCalc) {
+  CXFA_Margin* margin = m_pNode->GetMarginIfExists();
+  if (margin)
+    fHeightCalc -= margin->GetTopInset() + margin->GetBottomInset();
+  return fHeightCalc;
+}
+
+void CXFA_Node::StartWidgetLayout(CXFA_FFDoc* doc,
+                                  float& fCalcWidth,
+                                  float& fCalcHeight) {
+  InitLayoutData();
+
+  XFA_Element eUIType = m_pNode->GetUIType();
+  if (eUIType == XFA_Element::Text) {
+    m_pLayoutData->m_fWidgetHeight = m_pNode->TryHeight().value_or(-1);
+    StartTextLayout(doc, fCalcWidth, fCalcHeight);
+    return;
+  }
+  if (fCalcWidth > 0 && fCalcHeight > 0)
+    return;
+
+  m_pLayoutData->m_fWidgetHeight = -1;
+  float fWidth = 0;
+  if (fCalcWidth > 0 && fCalcHeight < 0) {
+    Optional<float> height = m_pNode->TryHeight();
+    if (height)
+      fCalcHeight = *height;
+    else
+      CalculateAccWidthAndHeight(doc, eUIType, fCalcWidth, fCalcHeight);
+
+    m_pLayoutData->m_fWidgetHeight = fCalcHeight;
+    return;
+  }
+  if (fCalcWidth < 0 && fCalcHeight < 0) {
+    Optional<float> height;
+    Optional<float> width = m_pNode->TryWidth();
+    if (width) {
+      fWidth = *width;
+
+      height = m_pNode->TryHeight();
+      if (height)
+        fCalcHeight = *height;
+    }
+    if (!width || !height)
+      CalculateAccWidthAndHeight(doc, eUIType, fWidth, fCalcHeight);
+
+    fCalcWidth = fWidth;
+  }
+  m_pLayoutData->m_fWidgetHeight = fCalcHeight;
+}
+
+void CXFA_Node::CalculateAccWidthAndHeight(CXFA_FFDoc* doc,
+                                           XFA_Element eUIType,
+                                           float& fWidth,
+                                           float& fCalcHeight) {
+  CFX_SizeF sz(fWidth, m_pLayoutData->m_fWidgetHeight);
+  switch (eUIType) {
+    case XFA_Element::Barcode:
+    case XFA_Element::ChoiceList:
+    case XFA_Element::Signature:
+      CalculateFieldAutoSize(doc, sz);
+      break;
+    case XFA_Element::ImageEdit:
+      CalculateImageEditAutoSize(doc, sz);
+      break;
+    case XFA_Element::Button:
+      CalculatePushButtonAutoSize(doc, sz);
+      break;
+    case XFA_Element::CheckButton:
+      CalculateCheckButtonAutoSize(doc, sz);
+      break;
+    case XFA_Element::DateTimeEdit:
+    case XFA_Element::NumericEdit:
+    case XFA_Element::PasswordEdit:
+    case XFA_Element::TextEdit:
+      CalculateTextEditAutoSize(doc, sz);
+      break;
+    case XFA_Element::Image:
+      CalculateImageAutoSize(doc, sz);
+      break;
+    case XFA_Element::Arc:
+    case XFA_Element::Line:
+    case XFA_Element::Rectangle:
+    case XFA_Element::Subform:
+    case XFA_Element::ExclGroup:
+      CalculateWidgetAutoSize(sz);
+      break;
+    default:
+      break;
+  }
+  fWidth = sz.width;
+  m_pLayoutData->m_fWidgetHeight = sz.height;
+  fCalcHeight = sz.height;
+}
+
+bool CXFA_Node::FindSplitPos(CXFA_FFDocView* docView,
+                             int32_t iBlockIndex,
+                             float& fCalcHeight) {
+  XFA_Element eUIType = m_pNode->GetUIType();
+  if (eUIType == XFA_Element::Subform)
+    return false;
+
+  if (eUIType != XFA_Element::Text && eUIType != XFA_Element::TextEdit &&
+      eUIType != XFA_Element::NumericEdit &&
+      eUIType != XFA_Element::PasswordEdit) {
+    fCalcHeight = 0;
+    return true;
+  }
+
+  float fTopInset = 0;
+  float fBottomInset = 0;
+  if (iBlockIndex == 0) {
+    CXFA_Margin* margin = m_pNode->GetMarginIfExists();
+    if (margin) {
+      fTopInset = margin->GetTopInset();
+      fBottomInset = margin->GetBottomInset();
+    }
+
+    CFX_RectF rtUIMargin = m_pNode->GetUIMargin();
+    fTopInset += rtUIMargin.top;
+    fBottomInset += rtUIMargin.width;
+  }
+  if (eUIType == XFA_Element::Text) {
+    float fHeight = fCalcHeight;
+    if (iBlockIndex == 0) {
+      fCalcHeight = fCalcHeight - fTopInset;
+      if (fCalcHeight < 0)
+        fCalcHeight = 0;
+    }
+
+    CXFA_TextLayout* pTextLayout =
+        static_cast<CXFA_TextLayoutData*>(m_pLayoutData.get())->GetTextLayout();
+    fCalcHeight =
+        pTextLayout->DoLayout(iBlockIndex, fCalcHeight, fCalcHeight,
+                              m_pLayoutData->m_fWidgetHeight - fTopInset);
+    if (fCalcHeight != 0) {
+      if (iBlockIndex == 0)
+        fCalcHeight = fCalcHeight + fTopInset;
+      if (fabs(fHeight - fCalcHeight) < XFA_FLOAT_PERCISION)
+        return false;
+    }
+    return true;
+  }
+  XFA_AttributeEnum iCapPlacement = XFA_AttributeEnum::Unknown;
+  float fCapReserve = 0;
+  if (iBlockIndex == 0) {
+    CXFA_Caption* caption = m_pNode->GetCaptionIfExists();
+    if (caption && !caption->IsHidden()) {
+      iCapPlacement = caption->GetPlacementType();
+      fCapReserve = caption->GetReserve();
+    }
+    if (iCapPlacement == XFA_AttributeEnum::Top &&
+        fCalcHeight < fCapReserve + fTopInset) {
+      fCalcHeight = 0;
+      return true;
+    }
+    if (iCapPlacement == XFA_AttributeEnum::Bottom &&
+        m_pLayoutData->m_fWidgetHeight - fCapReserve - fBottomInset) {
+      fCalcHeight = 0;
+      return true;
+    }
+    if (iCapPlacement != XFA_AttributeEnum::Top)
+      fCapReserve = 0;
+  }
+  CXFA_FieldLayoutData* pFieldData =
+      static_cast<CXFA_FieldLayoutData*>(m_pLayoutData.get());
+  int32_t iLinesCount = 0;
+  float fHeight = m_pLayoutData->m_fWidgetHeight;
+  if (GetValue(XFA_VALUEPICTURE_Display).IsEmpty()) {
+    iLinesCount = 1;
+  } else {
+    if (!pFieldData->m_pTextOut) {
+      // TODO(dsinclair): Inline fWidth when the 2nd param of
+      // CalculateAccWidthAndHeight isn't a ref-param.
+      float fWidth = m_pNode->TryWidth().value_or(0);
+      CalculateAccWidthAndHeight(docView->GetDoc(), eUIType, fWidth, fHeight);
+    }
+    iLinesCount = pFieldData->m_pTextOut->GetTotalLines();
+  }
+  std::vector<float>* pFieldArray = &pFieldData->m_FieldSplitArray;
+  int32_t iFieldSplitCount = pdfium::CollectionSize<int32_t>(*pFieldArray);
+  for (int32_t i = 0; i < iBlockIndex * 3; i += 3) {
+    iLinesCount -= (int32_t)(*pFieldArray)[i + 1];
+    fHeight -= (*pFieldArray)[i + 2];
+  }
+  if (iLinesCount == 0)
+    return false;
+
+  float fLineHeight = m_pNode->GetLineHeight();
+  float fFontSize = m_pNode->GetFontSize();
+  float fTextHeight = iLinesCount * fLineHeight - fLineHeight + fFontSize;
+  float fSpaceAbove = 0;
+  float fStartOffset = 0;
+  if (fHeight > 0.1f && iBlockIndex == 0) {
+    fStartOffset = fTopInset;
+    fHeight -= (fTopInset + fBottomInset);
+    CXFA_Para* para = m_pNode->GetParaIfExists();
+    if (para) {
+      fSpaceAbove = para->GetSpaceAbove();
+      float fSpaceBelow = para->GetSpaceBelow();
+      fHeight -= (fSpaceAbove + fSpaceBelow);
+      switch (para->GetVerticalAlign()) {
+        case XFA_AttributeEnum::Top:
+          fStartOffset += fSpaceAbove;
+          break;
+        case XFA_AttributeEnum::Middle:
+          fStartOffset += ((fHeight - fTextHeight) / 2 + fSpaceAbove);
+          break;
+        case XFA_AttributeEnum::Bottom:
+          fStartOffset += (fHeight - fTextHeight + fSpaceAbove);
+          break;
+        default:
+          NOTREACHED();
+          break;
+      }
+    }
+    if (fStartOffset < 0.1f)
+      fStartOffset = 0;
+  }
+  for (int32_t i = iBlockIndex - 1; iBlockIndex > 0 && i < iBlockIndex; i++) {
+    fStartOffset = (*pFieldArray)[i * 3] - (*pFieldArray)[i * 3 + 2];
+    if (fStartOffset < 0.1f)
+      fStartOffset = 0;
+  }
+  if (iFieldSplitCount / 3 == (iBlockIndex + 1))
+    (*pFieldArray)[0] = fStartOffset;
+  else
+    pFieldArray->push_back(fStartOffset);
+
+  XFA_VERSION version = docView->GetDoc()->GetXFADoc()->GetCurVersionMode();
+  bool bCanSplitNoContent = false;
+  XFA_AttributeEnum eLayoutMode = GetNode()
+                                      ->GetParent()
+                                      ->JSObject()
+                                      ->TryEnum(XFA_Attribute::Layout, true)
+                                      .value_or(XFA_AttributeEnum::Position);
+  if ((eLayoutMode == XFA_AttributeEnum::Position ||
+       eLayoutMode == XFA_AttributeEnum::Tb ||
+       eLayoutMode == XFA_AttributeEnum::Row ||
+       eLayoutMode == XFA_AttributeEnum::Table) &&
+      version > XFA_VERSION_208) {
+    bCanSplitNoContent = true;
+  }
+  if ((eLayoutMode == XFA_AttributeEnum::Tb ||
+       eLayoutMode == XFA_AttributeEnum::Row ||
+       eLayoutMode == XFA_AttributeEnum::Table) &&
+      version <= XFA_VERSION_208) {
+    if (fStartOffset < fCalcHeight) {
+      bCanSplitNoContent = true;
+    } else {
+      fCalcHeight = 0;
+      return true;
+    }
+  }
+  if (bCanSplitNoContent) {
+    if ((fCalcHeight - fTopInset - fSpaceAbove < fLineHeight)) {
+      fCalcHeight = 0;
+      return true;
+    }
+    if (fStartOffset + XFA_FLOAT_PERCISION >= fCalcHeight) {
+      if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
+        (*pFieldArray)[iBlockIndex * 3 + 1] = 0;
+        (*pFieldArray)[iBlockIndex * 3 + 2] = fCalcHeight;
+      } else {
+        pFieldArray->push_back(0);
+        pFieldArray->push_back(fCalcHeight);
+      }
+      return false;
+    }
+    if (fCalcHeight - fStartOffset < fLineHeight) {
+      fCalcHeight = fStartOffset;
+      if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
+        (*pFieldArray)[iBlockIndex * 3 + 1] = 0;
+        (*pFieldArray)[iBlockIndex * 3 + 2] = fCalcHeight;
+      } else {
+        pFieldArray->push_back(0);
+        pFieldArray->push_back(fCalcHeight);
+      }
+      return true;
+    }
+    float fTextNum =
+        fCalcHeight + XFA_FLOAT_PERCISION - fCapReserve - fStartOffset;
+    int32_t iLineNum =
+        (int32_t)((fTextNum + (fLineHeight - fFontSize)) / fLineHeight);
+    if (iLineNum >= iLinesCount) {
+      if (fCalcHeight - fStartOffset - fTextHeight >= fFontSize) {
+        if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
+          (*pFieldArray)[iBlockIndex * 3 + 1] = (float)iLinesCount;
+          (*pFieldArray)[iBlockIndex * 3 + 2] = fCalcHeight;
+        } else {
+          pFieldArray->push_back((float)iLinesCount);
+          pFieldArray->push_back(fCalcHeight);
+        }
+        return false;
+      }
+      if (fHeight - fStartOffset - fTextHeight < fFontSize) {
+        iLineNum -= 1;
+        if (iLineNum == 0) {
+          fCalcHeight = 0;
+          return true;
+        }
+      } else {
+        iLineNum = (int32_t)(fTextNum / fLineHeight);
+      }
+    }
+    if (iLineNum > 0) {
+      float fSplitHeight = iLineNum * fLineHeight + fCapReserve + fStartOffset;
+      if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
+        (*pFieldArray)[iBlockIndex * 3 + 1] = (float)iLineNum;
+        (*pFieldArray)[iBlockIndex * 3 + 2] = fSplitHeight;
+      } else {
+        pFieldArray->push_back((float)iLineNum);
+        pFieldArray->push_back(fSplitHeight);
+      }
+      if (fabs(fSplitHeight - fCalcHeight) < XFA_FLOAT_PERCISION)
+        return false;
+
+      fCalcHeight = fSplitHeight;
+      return true;
+    }
+  }
+  fCalcHeight = 0;
+  return true;
+}
+
+void CXFA_Node::InitLayoutData() {
+  if (m_pLayoutData)
+    return;
+
+  switch (m_pNode->GetUIType()) {
+    case XFA_Element::Text:
+      m_pLayoutData = pdfium::MakeUnique<CXFA_TextLayoutData>();
+      return;
+    case XFA_Element::TextEdit:
+      m_pLayoutData = pdfium::MakeUnique<CXFA_TextEditData>();
+      return;
+    case XFA_Element::Image:
+      m_pLayoutData = pdfium::MakeUnique<CXFA_ImageLayoutData>();
+      return;
+    case XFA_Element::ImageEdit:
+      m_pLayoutData = pdfium::MakeUnique<CXFA_ImageEditData>();
+      return;
+    default:
+      break;
+  }
+  if (m_pNode && m_pNode->GetElementType() == XFA_Element::Field) {
+    m_pLayoutData = pdfium::MakeUnique<CXFA_FieldLayoutData>();
+    return;
+  }
+  m_pLayoutData = pdfium::MakeUnique<CXFA_WidgetLayoutData>();
+}
+
+void CXFA_Node::StartTextLayout(CXFA_FFDoc* doc,
+                                float& fCalcWidth,
+                                float& fCalcHeight) {
+  LoadText(doc);
+
+  CXFA_TextLayout* pTextLayout =
+      static_cast<CXFA_TextLayoutData*>(m_pLayoutData.get())->GetTextLayout();
+  float fTextHeight = 0;
+  if (fCalcWidth > 0 && fCalcHeight > 0) {
+    float fWidth = GetWidthWithoutMargin(fCalcWidth);
+    pTextLayout->StartLayout(fWidth);
+    fTextHeight = fCalcHeight;
+    fTextHeight = GetHeightWithoutMargin(fTextHeight);
+    pTextLayout->DoLayout(0, fTextHeight, -1, fTextHeight);
+    return;
+  }
+  if (fCalcWidth > 0 && fCalcHeight < 0) {
+    float fWidth = GetWidthWithoutMargin(fCalcWidth);
+    pTextLayout->StartLayout(fWidth);
+  }
+
+  if (fCalcWidth < 0 && fCalcHeight < 0) {
+    Optional<float> width = m_pNode->TryWidth();
+    if (width) {
+      pTextLayout->StartLayout(GetWidthWithoutMargin(*width));
+      fCalcWidth = *width;
+    } else {
+      float fMaxWidth = CalculateWidgetAutoWidth(pTextLayout->StartLayout(-1));
+      pTextLayout->StartLayout(GetWidthWithoutMargin(fMaxWidth));
+      fCalcWidth = fMaxWidth;
+    }
+  }
+
+  if (m_pLayoutData->m_fWidgetHeight < 0) {
+    m_pLayoutData->m_fWidgetHeight = pTextLayout->GetLayoutHeight();
+    m_pLayoutData->m_fWidgetHeight =
+        CalculateWidgetAutoHeight(m_pLayoutData->m_fWidgetHeight);
+  }
+  fTextHeight = m_pLayoutData->m_fWidgetHeight;
+  fTextHeight = GetHeightWithoutMargin(fTextHeight);
+  pTextLayout->DoLayout(0, fTextHeight, -1, fTextHeight);
+  fCalcHeight = m_pLayoutData->m_fWidgetHeight;
+}
+
+bool CXFA_Node::LoadCaption(CXFA_FFDoc* doc) {
+  InitLayoutData();
+  return static_cast<CXFA_FieldLayoutData*>(m_pLayoutData.get())
+      ->LoadCaption(doc, this);
+}
+
+CXFA_TextLayout* CXFA_Node::GetCaptionTextLayout() {
+  return m_pLayoutData ? static_cast<CXFA_FieldLayoutData*>(m_pLayoutData.get())
+                             ->m_pCapTextLayout.get()
+                       : nullptr;
+}
+
+CXFA_TextLayout* CXFA_Node::GetTextLayout() {
+  return m_pLayoutData ? static_cast<CXFA_TextLayoutData*>(m_pLayoutData.get())
+                             ->GetTextLayout()
+                       : nullptr;
+}
+
+RetainPtr<CFX_DIBitmap> CXFA_Node::GetImageImage() {
+  return m_pLayoutData ? static_cast<CXFA_ImageLayoutData*>(m_pLayoutData.get())
+                             ->m_pDIBitmap
+                       : nullptr;
+}
+
+RetainPtr<CFX_DIBitmap> CXFA_Node::GetImageEditImage() {
+  return m_pLayoutData ? static_cast<CXFA_ImageEditData*>(m_pLayoutData.get())
+                             ->m_pDIBitmap
+                       : nullptr;
+}
+
+void CXFA_Node::SetImageImage(const RetainPtr<CFX_DIBitmap>& newImage) {
+  CXFA_ImageLayoutData* pData =
+      static_cast<CXFA_ImageLayoutData*>(m_pLayoutData.get());
+  if (pData->m_pDIBitmap != newImage)
+    pData->m_pDIBitmap = newImage;
+}
+
+void CXFA_Node::SetImageEditImage(const RetainPtr<CFX_DIBitmap>& newImage) {
+  CXFA_ImageEditData* pData =
+      static_cast<CXFA_ImageEditData*>(m_pLayoutData.get());
+  if (pData->m_pDIBitmap != newImage)
+    pData->m_pDIBitmap = newImage;
+}
+
+RetainPtr<CFGAS_GEFont> CXFA_Node::GetFDEFont(CXFA_FFDoc* doc) {
+  WideString wsFontName = L"Courier";
+  uint32_t dwFontStyle = 0;
+  CXFA_Font* font = m_pNode->GetFontIfExists();
+  if (font) {
+    if (font->IsBold())
+      dwFontStyle |= FXFONT_BOLD;
+    if (font->IsItalic())
+      dwFontStyle |= FXFONT_ITALIC;
+
+    wsFontName = font->GetTypeface();
+  }
+  return doc->GetApp()->GetXFAFontMgr()->GetFont(doc, wsFontName.AsStringView(),
+                                                 dwFontStyle);
+}
+
+bool CXFA_Node::IsOpenAccess() const {
+  return m_pNode && m_pNode->IsOpenAccess();
+}
+
+XFA_AttributeEnum CXFA_Node::GetButtonHighlight() {
+  CXFA_Node* pUIChild = m_pNode->GetUIChild();
+  if (pUIChild)
+    return pUIChild->JSObject()->GetEnum(XFA_Attribute::Highlight);
+  return XFA_AttributeEnum::Inverted;
+}
+
+bool CXFA_Node::HasButtonRollover() const {
+  CXFA_Items* pItems =
+      m_pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
+  if (!pItems)
+    return false;
+
+  for (CXFA_Node* pText = pItems->GetFirstChild(); pText;
+       pText = pText->GetNextSibling()) {
+    if (pText->JSObject()->GetCData(XFA_Attribute::Name) == L"rollover")
+      return !pText->JSObject()->GetContent(false).IsEmpty();
+  }
+  return false;
+}
+
+bool CXFA_Node::HasButtonDown() const {
+  CXFA_Items* pItems =
+      m_pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
+  if (!pItems)
+    return false;
+
+  for (CXFA_Node* pText = pItems->GetFirstChild(); pText;
+       pText = pText->GetNextSibling()) {
+    if (pText->JSObject()->GetCData(XFA_Attribute::Name) == L"down")
+      return !pText->JSObject()->GetContent(false).IsEmpty();
+  }
+  return false;
+}
+
+bool CXFA_Node::IsCheckButtonRound() {
+  CXFA_Node* pUIChild = m_pNode->GetUIChild();
+  if (pUIChild)
+    return pUIChild->JSObject()->GetEnum(XFA_Attribute::Shape) ==
+           XFA_AttributeEnum::Round;
+  return false;
+}
+
+XFA_AttributeEnum CXFA_Node::GetCheckButtonMark() {
+  CXFA_Node* pUIChild = m_pNode->GetUIChild();
+  if (pUIChild)
+    return pUIChild->JSObject()->GetEnum(XFA_Attribute::Mark);
+  return XFA_AttributeEnum::Default;
+}
+
+bool CXFA_Node::IsRadioButton() {
+  CXFA_Node* pParent = m_pNode->GetParent();
+  return pParent && pParent->GetElementType() == XFA_Element::ExclGroup;
+}
+
+float CXFA_Node::GetCheckButtonSize() {
+  CXFA_Node* pUIChild = m_pNode->GetUIChild();
+  if (pUIChild) {
+    return pUIChild->JSObject()
+        ->GetMeasure(XFA_Attribute::Size)
+        .ToUnit(XFA_Unit::Pt);
+  }
+  return CXFA_Measurement(10, XFA_Unit::Pt).ToUnit(XFA_Unit::Pt);
+}
+
+bool CXFA_Node::IsAllowNeutral() {
+  CXFA_Node* pUIChild = m_pNode->GetUIChild();
+  return pUIChild &&
+         pUIChild->JSObject()->GetBoolean(XFA_Attribute::AllowNeutral);
+}
+
+XFA_CHECKSTATE CXFA_Node::GetCheckState() {
+  WideString wsValue = m_pNode->GetRawValue();
+  if (wsValue.IsEmpty())
+    return XFA_CHECKSTATE_Off;
+
+  auto* pItems = m_pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
+  if (!pItems)
+    return XFA_CHECKSTATE_Off;
+
+  CXFA_Node* pText = pItems->GetFirstChild();
+  int32_t i = 0;
+  while (pText) {
+    Optional<WideString> wsContent = pText->JSObject()->TryContent(false, true);
+    if (wsContent && *wsContent == wsValue)
+      return static_cast<XFA_CHECKSTATE>(i);
+
+    i++;
+    pText = pText->GetNextSibling();
+  }
+  return XFA_CHECKSTATE_Off;
+}
+
+void CXFA_Node::SetCheckState(XFA_CHECKSTATE eCheckState, bool bNotify) {
+  CXFA_Node* node = m_pNode->GetExclGroupIfExists();
+  if (!node) {
+    CXFA_Items* pItems =
+        m_pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
+    if (!pItems)
+      return;
+
+    int32_t i = -1;
+    CXFA_Node* pText = pItems->GetFirstChild();
+    WideString wsContent;
+    while (pText) {
+      i++;
+      if (i == eCheckState) {
+        wsContent = pText->JSObject()->GetContent(false);
+        break;
+      }
+      pText = pText->GetNextSibling();
+    }
+    m_pNode->SyncValue(wsContent, bNotify);
+
+    return;
+  }
+
+  WideString wsValue;
+  if (eCheckState != XFA_CHECKSTATE_Off) {
+    if (CXFA_Items* pItems =
+            m_pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false)) {
+      CXFA_Node* pText = pItems->GetFirstChild();
+      if (pText)
+        wsValue = pText->JSObject()->GetContent(false);
+    }
+  }
+  CXFA_Node* pChild = node->GetFirstChild();
+  for (; pChild; pChild = pChild->GetNextSibling()) {
+    if (pChild->GetElementType() != XFA_Element::Field)
+      continue;
+
+    CXFA_Items* pItem =
+        pChild->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
+    if (!pItem)
+      continue;
+
+    CXFA_Node* pItemchild = pItem->GetFirstChild();
+    if (!pItemchild)
+      continue;
+
+    WideString text = pItemchild->JSObject()->GetContent(false);
+    WideString wsChildValue = text;
+    if (wsValue != text) {
+      pItemchild = pItemchild->GetNextSibling();
+      if (pItemchild)
+        wsChildValue = pItemchild->JSObject()->GetContent(false);
+      else
+        wsChildValue.clear();
+    }
+    pChild->SyncValue(wsChildValue, bNotify);
+  }
+  node->SyncValue(wsValue, bNotify);
+}
+
+CXFA_Node* CXFA_Node::GetSelectedMember() {
+  CXFA_Node* pSelectedMember = nullptr;
+  WideString wsState = m_pNode->GetRawValue();
+  if (wsState.IsEmpty())
+    return pSelectedMember;
+
+  for (CXFA_Node* pNode = ToNode(m_pNode->GetFirstChild()); pNode;
+       pNode = pNode->GetNextSibling()) {
+    if (pNode->GetCheckState() == XFA_CHECKSTATE_On) {
+      pSelectedMember = pNode;
+      break;
+    }
+  }
+  return pSelectedMember;
+}
+
+CXFA_Node* CXFA_Node::SetSelectedMember(const WideStringView& wsName,
+                                        bool bNotify) {
+  uint32_t nameHash = FX_HashCode_GetW(wsName, false);
+  for (CXFA_Node* pNode = ToNode(m_pNode->GetFirstChild()); pNode;
+       pNode = pNode->GetNextSibling()) {
+    if (pNode->GetNameHash() == nameHash) {
+      pNode->SetCheckState(XFA_CHECKSTATE_On, bNotify);
+      return pNode;
+    }
+  }
+  return nullptr;
+}
+
+void CXFA_Node::SetSelectedMemberByValue(const WideStringView& wsValue,
+                                         bool bNotify,
+                                         bool bScriptModify,
+                                         bool bSyncData) {
+  WideString wsExclGroup;
+  for (CXFA_Node* pNode = m_pNode->GetFirstChild(); pNode;
+       pNode = pNode->GetNextSibling()) {
+    if (pNode->GetElementType() != XFA_Element::Field)
+      continue;
+
+    CXFA_Items* pItem =
+        pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
+    if (!pItem)
+      continue;
+
+    CXFA_Node* pItemchild = pItem->GetFirstChild();
+    if (!pItemchild)
+      continue;
+
+    WideString wsChildValue = pItemchild->JSObject()->GetContent(false);
+    if (wsValue != wsChildValue) {
+      pItemchild = pItemchild->GetNextSibling();
+      if (pItemchild)
+        wsChildValue = pItemchild->JSObject()->GetContent(false);
+      else
+        wsChildValue.clear();
+    } else {
+      wsExclGroup = wsValue;
+    }
+    pNode->JSObject()->SetContent(wsChildValue, wsChildValue, bNotify,
+                                  bScriptModify, false);
+  }
+  m_pNode->JSObject()->SetContent(wsExclGroup, wsExclGroup, bNotify,
+                                  bScriptModify, bSyncData);
+}
+
+CXFA_Node* CXFA_Node::GetExclGroupFirstMember() {
+  CXFA_Node* pExcl = GetNode();
+  if (!pExcl)
+    return nullptr;
+
+  CXFA_Node* pNode = pExcl->GetFirstChild();
+  while (pNode) {
+    if (pNode->GetElementType() == XFA_Element::Field)
+      return pNode;
+
+    pNode = pNode->GetNextSibling();
+  }
+  return nullptr;
+}
+CXFA_Node* CXFA_Node::GetExclGroupNextMember(CXFA_Node* pNode) {
+  if (!pNode)
+    return nullptr;
+
+  CXFA_Node* pNodeField = pNode->GetNextSibling();
+  while (pNodeField) {
+    if (pNodeField->GetElementType() == XFA_Element::Field)
+      return pNodeField;
+
+    pNodeField = pNodeField->GetNextSibling();
+  }
+  return nullptr;
+}
+
+bool CXFA_Node::IsChoiceListCommitOnSelect() {
+  CXFA_Node* pUIChild = m_pNode->GetUIChild();
+  if (pUIChild) {
+    return pUIChild->JSObject()->GetEnum(XFA_Attribute::CommitOn) ==
+           XFA_AttributeEnum::Select;
+  }
+  return true;
+}
+
+bool CXFA_Node::IsChoiceListAllowTextEntry() {
+  CXFA_Node* pUIChild = m_pNode->GetUIChild();
+  return pUIChild && pUIChild->JSObject()->GetBoolean(XFA_Attribute::TextEntry);
+}
+
+bool CXFA_Node::IsChoiceListMultiSelect() {
+  CXFA_Node* pUIChild = m_pNode->GetUIChild();
+  if (pUIChild) {
+    return pUIChild->JSObject()->GetEnum(XFA_Attribute::Open) ==
+           XFA_AttributeEnum::MultiSelect;
+  }
+  return false;
+}
+
+bool CXFA_Node::IsListBox() {
+  CXFA_Node* pUIChild = m_pNode->GetUIChild();
+  if (!pUIChild)
+    return false;
+
+  XFA_AttributeEnum attr = pUIChild->JSObject()->GetEnum(XFA_Attribute::Open);
+  return attr == XFA_AttributeEnum::Always ||
+         attr == XFA_AttributeEnum::MultiSelect;
+}
+
+int32_t CXFA_Node::CountChoiceListItems(bool bSaveValue) {
+  std::vector<CXFA_Node*> pItems;
+  int32_t iCount = 0;
+  for (CXFA_Node* pNode = m_pNode->GetFirstChild(); pNode;
+       pNode = pNode->GetNextSibling()) {
+    if (pNode->GetElementType() != XFA_Element::Items)
+      continue;
+    iCount++;
+    pItems.push_back(pNode);
+    if (iCount == 2)
+      break;
+  }
+  if (iCount == 0)
+    return 0;
+
+  CXFA_Node* pItem = pItems[0];
+  if (iCount > 1) {
+    bool bItemOneHasSave =
+        pItems[0]->JSObject()->GetBoolean(XFA_Attribute::Save);
+    bool bItemTwoHasSave =
+        pItems[1]->JSObject()->GetBoolean(XFA_Attribute::Save);
+    if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave)
+      pItem = pItems[1];
+  }
+  return pItem->CountChildren(XFA_Element::Unknown, false);
+}
+
+Optional<WideString> CXFA_Node::GetChoiceListItem(int32_t nIndex,
+                                                  bool bSaveValue) {
+  std::vector<CXFA_Node*> pItemsArray;
+  int32_t iCount = 0;
+  for (CXFA_Node* pNode = m_pNode->GetFirstChild(); pNode;
+       pNode = pNode->GetNextSibling()) {
+    if (pNode->GetElementType() != XFA_Element::Items)
+      continue;
+
+    ++iCount;
+    pItemsArray.push_back(pNode);
+    if (iCount == 2)
+      break;
+  }
+  if (iCount == 0)
+    return {};
+
+  CXFA_Node* pItems = pItemsArray[0];
+  if (iCount > 1) {
+    bool bItemOneHasSave =
+        pItemsArray[0]->JSObject()->GetBoolean(XFA_Attribute::Save);
+    bool bItemTwoHasSave =
+        pItemsArray[1]->JSObject()->GetBoolean(XFA_Attribute::Save);
+    if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave)
+      pItems = pItemsArray[1];
+  }
+  if (!pItems)
+    return {};
+
+  CXFA_Node* pItem =
+      pItems->GetChild<CXFA_Node>(nIndex, XFA_Element::Unknown, false);
+  if (pItem)
+    return {pItem->JSObject()->GetContent(false)};
+  return {};
+}
+
+std::vector<WideString> CXFA_Node::GetChoiceListItems(bool bSaveValue) {
+  std::vector<CXFA_Node*> items;
+  for (CXFA_Node* pNode = m_pNode->GetFirstChild(); pNode && items.size() < 2;
+       pNode = pNode->GetNextSibling()) {
+    if (pNode->GetElementType() == XFA_Element::Items)
+      items.push_back(pNode);
+  }
+  if (items.empty())
+    return std::vector<WideString>();
+
+  CXFA_Node* pItem = items.front();
+  if (items.size() > 1) {
+    bool bItemOneHasSave =
+        items[0]->JSObject()->GetBoolean(XFA_Attribute::Save);
+    bool bItemTwoHasSave =
+        items[1]->JSObject()->GetBoolean(XFA_Attribute::Save);
+    if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave)
+      pItem = items[1];
+  }
+
+  std::vector<WideString> wsTextArray;
+  for (CXFA_Node* pNode = pItem->GetFirstChild(); pNode;
+       pNode = pNode->GetNextSibling()) {
+    wsTextArray.emplace_back(pNode->JSObject()->GetContent(false));
+  }
+  return wsTextArray;
+}
+
+int32_t CXFA_Node::CountSelectedItems() {
+  std::vector<WideString> wsValueArray = GetSelectedItemsValue();
+  if (IsListBox() || !IsChoiceListAllowTextEntry())
+    return pdfium::CollectionSize<int32_t>(wsValueArray);
+
+  int32_t iSelected = 0;
+  std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
+  for (const auto& value : wsValueArray) {
+    if (pdfium::ContainsValue(wsSaveTextArray, value))
+      iSelected++;
+  }
+  return iSelected;
+}
+
+int32_t CXFA_Node::GetSelectedItem(int32_t nIndex) {
+  std::vector<WideString> wsValueArray = GetSelectedItemsValue();
+  if (!pdfium::IndexInBounds(wsValueArray, nIndex))
+    return -1;
+
+  std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
+  auto it = std::find(wsSaveTextArray.begin(), wsSaveTextArray.end(),
+                      wsValueArray[nIndex]);
+  return it != wsSaveTextArray.end() ? it - wsSaveTextArray.begin() : -1;
+}
+
+std::vector<int32_t> CXFA_Node::GetSelectedItems() {
+  std::vector<int32_t> iSelArray;
+  std::vector<WideString> wsValueArray = GetSelectedItemsValue();
+  std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
+  for (const auto& value : wsValueArray) {
+    auto it = std::find(wsSaveTextArray.begin(), wsSaveTextArray.end(), value);
+    if (it != wsSaveTextArray.end())
+      iSelArray.push_back(it - wsSaveTextArray.begin());
+  }
+  return iSelArray;
+}
+
+std::vector<WideString> CXFA_Node::GetSelectedItemsValue() {
+  std::vector<WideString> wsSelTextArray;
+  WideString wsValue = m_pNode->GetRawValue();
+  if (IsChoiceListMultiSelect()) {
+    if (!wsValue.IsEmpty()) {
+      size_t iStart = 0;
+      size_t iLength = wsValue.GetLength();
+      auto iEnd = wsValue.Find(L'\n', iStart);
+      iEnd = (!iEnd.has_value()) ? iLength : iEnd;
+      while (iEnd >= iStart) {
+        wsSelTextArray.push_back(wsValue.Mid(iStart, iEnd.value() - iStart));
+        iStart = iEnd.value() + 1;
+        if (iStart >= iLength)
+          break;
+        iEnd = wsValue.Find(L'\n', iStart);
+        if (!iEnd.has_value())
+          wsSelTextArray.push_back(wsValue.Mid(iStart, iLength - iStart));
+      }
+    }
+  } else {
+    wsSelTextArray.push_back(wsValue);
+  }
+  return wsSelTextArray;
+}
+
+bool CXFA_Node::GetItemState(int32_t nIndex) {
+  std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
+  return pdfium::IndexInBounds(wsSaveTextArray, nIndex) &&
+         pdfium::ContainsValue(GetSelectedItemsValue(),
+                               wsSaveTextArray[nIndex]);
+}
+
+void CXFA_Node::SetItemState(int32_t nIndex,
+                             bool bSelected,
+                             bool bNotify,
+                             bool bScriptModify,
+                             bool bSyncData) {
+  std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
+  if (!pdfium::IndexInBounds(wsSaveTextArray, nIndex))
+    return;
+
+  int32_t iSel = -1;
+  std::vector<WideString> wsValueArray = GetSelectedItemsValue();
+  auto it = std::find(wsValueArray.begin(), wsValueArray.end(),
+                      wsSaveTextArray[nIndex]);
+  if (it != wsValueArray.end())
+    iSel = it - wsValueArray.begin();
+
+  if (IsChoiceListMultiSelect()) {
+    if (bSelected) {
+      if (iSel < 0) {
+        WideString wsValue = m_pNode->GetRawValue();
+        if (!wsValue.IsEmpty()) {
+          wsValue += L"\n";
+        }
+        wsValue += wsSaveTextArray[nIndex];
+        m_pNode->JSObject()->SetContent(wsValue, wsValue, bNotify,
+                                        bScriptModify, bSyncData);
+      }
+    } else if (iSel >= 0) {
+      std::vector<int32_t> iSelArray = GetSelectedItems();
+      auto it = std::find(iSelArray.begin(), iSelArray.end(), nIndex);
+      if (it != iSelArray.end())
+        iSelArray.erase(it);
+      SetSelectedItems(iSelArray, bNotify, bScriptModify, bSyncData);
+    }
+  } else {
+    if (bSelected) {
+      if (iSel < 0) {
+        WideString wsSaveText = wsSaveTextArray[nIndex];
+        m_pNode->JSObject()->SetContent(wsSaveText,
+                                        GetFormatDataValue(wsSaveText), bNotify,
+                                        bScriptModify, bSyncData);
+      }
+    } else if (iSel >= 0) {
+      m_pNode->JSObject()->SetContent(WideString(), WideString(), bNotify,
+                                      bScriptModify, bSyncData);
+    }
+  }
+}
+
+void CXFA_Node::SetSelectedItems(const std::vector<int32_t>& iSelArray,
+                                 bool bNotify,
+                                 bool bScriptModify,
+                                 bool bSyncData) {
+  WideString wsValue;
+  int32_t iSize = pdfium::CollectionSize<int32_t>(iSelArray);
+  if (iSize >= 1) {
+    std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
+    WideString wsItemValue;
+    for (int32_t i = 0; i < iSize; i++) {
+      wsItemValue = (iSize == 1) ? wsSaveTextArray[iSelArray[i]]
+                                 : wsSaveTextArray[iSelArray[i]] + L"\n";
+      wsValue += wsItemValue;
+    }
+  }
+  WideString wsFormat(wsValue);
+  if (!IsChoiceListMultiSelect())
+    wsFormat = GetFormatDataValue(wsValue);
+
+  m_pNode->JSObject()->SetContent(wsValue, wsFormat, bNotify, bScriptModify,
+                                  bSyncData);
+}
+
+void CXFA_Node::ClearAllSelections() {
+  CXFA_Node* pBind = m_pNode->GetBindData();
+  if (!pBind || !IsChoiceListMultiSelect()) {
+    m_pNode->SyncValue(WideString(), false);
+    return;
+  }
+
+  while (CXFA_Node* pChildNode = pBind->GetFirstChild())
+    pBind->RemoveChild(pChildNode, true);
+}
+
+void CXFA_Node::InsertItem(const WideString& wsLabel,
+                           const WideString& wsValue,
+                           bool bNotify) {
+  int32_t nIndex = -1;
+  WideString wsNewValue(wsValue);
+  if (wsNewValue.IsEmpty())
+    wsNewValue = wsLabel;
+
+  std::vector<CXFA_Node*> listitems;
+  for (CXFA_Node* pItem = m_pNode->GetFirstChild(); pItem;
+       pItem = pItem->GetNextSibling()) {
+    if (pItem->GetElementType() == XFA_Element::Items)
+      listitems.push_back(pItem);
+  }
+  if (listitems.empty()) {
+    CXFA_Node* pItems = m_pNode->CreateSamePacketNode(XFA_Element::Items);
+    m_pNode->InsertChild(-1, pItems);
+    InsertListTextItem(pItems, wsLabel, nIndex);
+    CXFA_Node* pSaveItems = m_pNode->CreateSamePacketNode(XFA_Element::Items);
+    m_pNode->InsertChild(-1, pSaveItems);
+    pSaveItems->JSObject()->SetBoolean(XFA_Attribute::Save, true, false);
+    InsertListTextItem(pSaveItems, wsNewValue, nIndex);
+  } else if (listitems.size() > 1) {
+    for (int32_t i = 0; i < 2; i++) {
+      CXFA_Node* pNode = listitems[i];
+      bool bHasSave = pNode->JSObject()->GetBoolean(XFA_Attribute::Save);
+      if (bHasSave)
+        InsertListTextItem(pNode, wsNewValue, nIndex);
+      else
+        InsertListTextItem(pNode, wsLabel, nIndex);
+    }
+  } else {
+    CXFA_Node* pNode = listitems[0];
+    pNode->JSObject()->SetBoolean(XFA_Attribute::Save, false, false);
+    pNode->JSObject()->SetEnum(XFA_Attribute::Presence,
+                               XFA_AttributeEnum::Visible, false);
+    CXFA_Node* pSaveItems = m_pNode->CreateSamePacketNode(XFA_Element::Items);
+    m_pNode->InsertChild(-1, pSaveItems);
+    pSaveItems->JSObject()->SetBoolean(XFA_Attribute::Save, true, false);
+    pSaveItems->JSObject()->SetEnum(XFA_Attribute::Presence,
+                                    XFA_AttributeEnum::Hidden, false);
+    CXFA_Node* pListNode = pNode->GetFirstChild();
+    int32_t i = 0;
+    while (pListNode) {
+      InsertListTextItem(pSaveItems, pListNode->JSObject()->GetContent(false),
+                         i);
+      ++i;
+
+      pListNode = pListNode->GetNextSibling();
+    }
+    InsertListTextItem(pNode, wsLabel, nIndex);
+    InsertListTextItem(pSaveItems, wsNewValue, nIndex);
+  }
+  if (!bNotify)
+    return;
+
+  m_pNode->GetDocument()->GetNotify()->OnWidgetListItemAdded(
+      m_pNode, wsLabel.c_str(), wsValue.c_str(), nIndex);
+}
+
+void CXFA_Node::GetItemLabel(const WideStringView& wsValue,
+                             WideString& wsLabel) {
+  int32_t iCount = 0;
+  std::vector<CXFA_Node*> listitems;
+  CXFA_Node* pItems = m_pNode->GetFirstChild();
+  for (; pItems; pItems = pItems->GetNextSibling()) {
+    if (pItems->GetElementType() != XFA_Element::Items)
+      continue;
+    iCount++;
+    listitems.push_back(pItems);
+  }
+
+  if (iCount <= 1) {
+    wsLabel = wsValue;
+    return;
+  }
+
+  CXFA_Node* pLabelItems = listitems[0];
+  bool bSave = pLabelItems->JSObject()->GetBoolean(XFA_Attribute::Save);
+  CXFA_Node* pSaveItems = nullptr;
+  if (bSave) {
+    pSaveItems = pLabelItems;
+    pLabelItems = listitems[1];
+  } else {
+    pSaveItems = listitems[1];
+  }
+  iCount = 0;
+
+  int32_t iSearch = -1;
+  for (CXFA_Node* pChildItem = pSaveItems->GetFirstChild(); pChildItem;
+       pChildItem = pChildItem->GetNextSibling()) {
+    if (pChildItem->JSObject()->GetContent(false) == wsValue) {
+      iSearch = iCount;
+      break;
+    }
+    iCount++;
+  }
+  if (iSearch < 0)
+    return;
+
+  CXFA_Node* pText =
+      pLabelItems->GetChild<CXFA_Node>(iSearch, XFA_Element::Unknown, false);
+  if (pText)
+    wsLabel = pText->JSObject()->GetContent(false);
+}
+
+WideString CXFA_Node::GetItemValue(const WideStringView& wsLabel) {
+  int32_t iCount = 0;
+  std::vector<CXFA_Node*> listitems;
+  for (CXFA_Node* pItems = m_pNode->GetFirstChild(); pItems;
+       pItems = pItems->GetNextSibling()) {
+    if (pItems->GetElementType() != XFA_Element::Items)
+      continue;
+    iCount++;
+    listitems.push_back(pItems);
+  }
+  if (iCount <= 1)
+    return WideString(wsLabel);
+
+  CXFA_Node* pLabelItems = listitems[0];
+  bool bSave = pLabelItems->JSObject()->GetBoolean(XFA_Attribute::Save);
+  CXFA_Node* pSaveItems = nullptr;
+  if (bSave) {
+    pSaveItems = pLabelItems;
+    pLabelItems = listitems[1];
+  } else {
+    pSaveItems = listitems[1];
+  }
+  iCount = 0;
+
+  int32_t iSearch = -1;
+  WideString wsContent;
+  CXFA_Node* pChildItem = pLabelItems->GetFirstChild();
+  for (; pChildItem; pChildItem = pChildItem->GetNextSibling()) {
+    if (pChildItem->JSObject()->GetContent(false) == wsLabel) {
+      iSearch = iCount;
+      break;
+    }
+    iCount++;
+  }
+  if (iSearch < 0)
+    return L"";
+
+  CXFA_Node* pText =
+      pSaveItems->GetChild<CXFA_Node>(iSearch, XFA_Element::Unknown, false);
+  return pText ? pText->JSObject()->GetContent(false) : L"";
+}
+
+bool CXFA_Node::DeleteItem(int32_t nIndex, bool bNotify, bool bScriptModify) {
+  bool bSetValue = false;
+  CXFA_Node* pItems = m_pNode->GetFirstChild();
+  for (; pItems; pItems = pItems->GetNextSibling()) {
+    if (pItems->GetElementType() != XFA_Element::Items)
+      continue;
+
+    if (nIndex < 0) {
+      while (CXFA_Node* pNode = pItems->GetFirstChild()) {
+        pItems->RemoveChild(pNode, true);
+      }
+    } else {
+      if (!bSetValue && pItems->JSObject()->GetBoolean(XFA_Attribute::Save)) {
+        SetItemState(nIndex, false, true, bScriptModify, true);
+        bSetValue = true;
+      }
+      int32_t i = 0;
+      CXFA_Node* pNode = pItems->GetFirstChild();
+      while (pNode) {
+        if (i == nIndex) {
+          pItems->RemoveChild(pNode, true);
+          break;
+        }
+        i++;
+        pNode = pNode->GetNextSibling();
+      }
+    }
+  }
+  if (bNotify)
+    m_pNode->GetDocument()->GetNotify()->OnWidgetListItemRemoved(m_pNode,
+                                                                 nIndex);
+  return true;
+}
+
+bool CXFA_Node::IsHorizontalScrollPolicyOff() {
+  CXFA_Node* pUIChild = m_pNode->GetUIChild();
+  if (pUIChild) {
+    return pUIChild->JSObject()->GetEnum(XFA_Attribute::HScrollPolicy) ==
+           XFA_AttributeEnum::Off;
+  }
+  return false;
+}
+
+bool CXFA_Node::IsVerticalScrollPolicyOff() {
+  CXFA_Node* pUIChild = m_pNode->GetUIChild();
+  if (pUIChild) {
+    return pUIChild->JSObject()->GetEnum(XFA_Attribute::VScrollPolicy) ==
+           XFA_AttributeEnum::Off;
+  }
+  return false;
+}
+
+Optional<int32_t> CXFA_Node::GetNumberOfCells() {
+  CXFA_Node* pUIChild = m_pNode->GetUIChild();
+  if (!pUIChild)
+    return {};
+  if (CXFA_Comb* pNode =
+          pUIChild->GetChild<CXFA_Comb>(0, XFA_Element::Comb, false))
+    return {pNode->JSObject()->GetInteger(XFA_Attribute::NumberOfCells)};
+  return {};
+}
+
+WideString CXFA_Node::GetPasswordChar() {
+  CXFA_Node* pUIChild = m_pNode->GetUIChild();
+  return pUIChild ? pUIChild->JSObject()->GetCData(XFA_Attribute::PasswordChar)
+                  : L"*";
+}
+
+bool CXFA_Node::IsMultiLine() {
+  CXFA_Node* pUIChild = m_pNode->GetUIChild();
+  return pUIChild && pUIChild->JSObject()->GetBoolean(XFA_Attribute::MultiLine);
+}
+
+std::pair<XFA_Element, int32_t> CXFA_Node::GetMaxChars() {
+  if (CXFA_Value* pNode =
+          m_pNode->GetChild<CXFA_Value>(0, XFA_Element::Value, false)) {
+    if (CXFA_Node* pChild = pNode->GetFirstChild()) {
+      switch (pChild->GetElementType()) {
+        case XFA_Element::Text:
+          return {XFA_Element::Text,
+                  pChild->JSObject()->GetInteger(XFA_Attribute::MaxChars)};
+        case XFA_Element::ExData: {
+          int32_t iMax =
+              pChild->JSObject()->GetInteger(XFA_Attribute::MaxLength);
+          return {XFA_Element::ExData, iMax < 0 ? 0 : iMax};
+        }
+        default:
+          break;
+      }
+    }
+  }
+  return {XFA_Element::Unknown, 0};
+}
+
+int32_t CXFA_Node::GetFracDigits() {
+  CXFA_Value* pNode =
+      m_pNode->GetChild<CXFA_Value>(0, XFA_Element::Value, false);
+  if (!pNode)
+    return -1;
+
+  CXFA_Decimal* pChild =
+      pNode->GetChild<CXFA_Decimal>(0, XFA_Element::Decimal, false);
+  if (!pChild)
+    return -1;
+
+  return pChild->JSObject()
+      ->TryInteger(XFA_Attribute::FracDigits, true)
+      .value_or(-1);
+}
+
+int32_t CXFA_Node::GetLeadDigits() {
+  CXFA_Value* pNode =
+      m_pNode->GetChild<CXFA_Value>(0, XFA_Element::Value, false);
+  if (!pNode)
+    return -1;
+
+  CXFA_Decimal* pChild =
+      pNode->GetChild<CXFA_Decimal>(0, XFA_Element::Decimal, false);
+  if (!pChild)
+    return -1;
+
+  return pChild->JSObject()
+      ->TryInteger(XFA_Attribute::LeadDigits, true)
+      .value_or(-1);
+}
+
+bool CXFA_Node::SetValue(XFA_VALUEPICTURE eValueType,
+                         const WideString& wsValue) {
+  if (wsValue.IsEmpty()) {
+    m_pNode->SyncValue(wsValue, true);
+    return true;
+  }
+
+  m_pNode->SetPreNull(m_pNode->IsNull());
+  m_pNode->SetIsNull(false);
+
+  WideString wsNewText(wsValue);
+  WideString wsPicture = GetPictureContent(eValueType);
+  bool bValidate = true;
+  bool bSyncData = false;
+  CXFA_Node* pNode = m_pNode->GetUIChild();
+  if (!pNode)
+    return true;
+
+  XFA_Element eType = pNode->GetElementType();
+  if (!wsPicture.IsEmpty()) {
+    CXFA_LocaleMgr* pLocalMgr = m_pNode->GetDocument()->GetLocalMgr();
+    IFX_Locale* pLocale = m_pNode->GetLocale();
+    CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(GetNode());
+    bValidate =
+        widgetValue.ValidateValue(wsValue, wsPicture, pLocale, &wsPicture);
+    if (bValidate) {
+      widgetValue = CXFA_LocaleValue(widgetValue.GetType(), wsNewText,
+                                     wsPicture, pLocale, pLocalMgr);
+      wsNewText = widgetValue.GetValue();
+      if (eType == XFA_Element::NumericEdit)
+        wsNewText = NumericLimit(wsNewText, GetLeadDigits(), GetFracDigits());
+
+      bSyncData = true;
+    }
+  } else {
+    if (eType == XFA_Element::NumericEdit) {
+      if (wsNewText != L"0")
+        wsNewText = NumericLimit(wsNewText, GetLeadDigits(), GetFracDigits());
+
+      bSyncData = true;
+    }
+  }
+  if (eType != XFA_Element::NumericEdit || bSyncData)
+    m_pNode->SyncValue(wsNewText, true);
+
+  return bValidate;
+}
+
+WideString CXFA_Node::GetPictureContent(XFA_VALUEPICTURE ePicture) {
+  if (ePicture == XFA_VALUEPICTURE_Raw)
+    return L"";
+
+  CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(GetNode());
+  switch (ePicture) {
+    case XFA_VALUEPICTURE_Display: {
+      if (CXFA_Format* pFormat =
+              m_pNode->GetChild<CXFA_Format>(0, XFA_Element::Format, false)) {
+        if (CXFA_Picture* pPicture = pFormat->GetChild<CXFA_Picture>(
+                0, XFA_Element::Picture, false)) {
+          Optional<WideString> picture =
+              pPicture->JSObject()->TryContent(false, true);
+          if (picture)
+            return *picture;
+        }
+      }
+
+      IFX_Locale* pLocale = m_pNode->GetLocale();
+      if (!pLocale)
+        return L"";
+
+      uint32_t dwType = widgetValue.GetType();
+      switch (dwType) {
+        case XFA_VT_DATE:
+          return pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium);
+        case XFA_VT_TIME:
+          return pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium);
+        case XFA_VT_DATETIME:
+          return pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium) +
+                 L"T" +
+                 pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium);
+        case XFA_VT_DECIMAL:
+        case XFA_VT_FLOAT:
+        default:
+          return L"";
+      }
+    }
+    case XFA_VALUEPICTURE_Edit: {
+      CXFA_Ui* pUI = m_pNode->GetChild<CXFA_Ui>(0, XFA_Element::Ui, false);
+      if (pUI) {
+        if (CXFA_Picture* pPicture =
+                pUI->GetChild<CXFA_Picture>(0, XFA_Element::Picture, false)) {
+          Optional<WideString> picture =
+              pPicture->JSObject()->TryContent(false, true);
+          if (picture)
+            return *picture;
+        }
+      }
+
+      IFX_Locale* pLocale = m_pNode->GetLocale();
+      if (!pLocale)
+        return L"";
+
+      uint32_t dwType = widgetValue.GetType();
+      switch (dwType) {
+        case XFA_VT_DATE:
+          return pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Short);
+        case XFA_VT_TIME:
+          return pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Short);
+        case XFA_VT_DATETIME:
+          return pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Short) +
+                 L"T" +
+                 pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Short);
+        default:
+          return L"";
+      }
+    }
+    case XFA_VALUEPICTURE_DataBind: {
+      CXFA_Bind* bind = m_pNode->GetBindIfExists();
+      if (bind)
+        return bind->GetPicture();
+      break;
+    }
+    default:
+      break;
+  }
+  return L"";
+}
+
+WideString CXFA_Node::GetValue(XFA_VALUEPICTURE eValueType) {
+  WideString wsValue = m_pNode->JSObject()->GetContent(false);
+
+  if (eValueType == XFA_VALUEPICTURE_Display)
+    GetItemLabel(wsValue.AsStringView(), wsValue);
+
+  WideString wsPicture = GetPictureContent(eValueType);
+  CXFA_Node* pNode = m_pNode->GetUIChild();
+  if (!pNode)
+    return wsValue;
+
+  switch (m_pNode->GetUIChild()->GetElementType()) {
+    case XFA_Element::ChoiceList: {
+      if (eValueType == XFA_VALUEPICTURE_Display) {
+        int32_t iSelItemIndex = GetSelectedItem(0);
+        if (iSelItemIndex >= 0) {
+          wsValue = GetChoiceListItem(iSelItemIndex, false).value_or(L"");
+          wsPicture.clear();
+        }
+      }
+    } break;
+    case XFA_Element::NumericEdit:
+      if (eValueType != XFA_VALUEPICTURE_Raw && wsPicture.IsEmpty()) {
+        IFX_Locale* pLocale = m_pNode->GetLocale();
+        if (eValueType == XFA_VALUEPICTURE_Display && pLocale)
+          wsValue = FormatNumStr(NormalizeNumStr(wsValue), pLocale);
+      }
+      break;
+    default:
+      break;
+  }
+  if (wsPicture.IsEmpty())
+    return wsValue;
+
+  if (IFX_Locale* pLocale = m_pNode->GetLocale()) {
+    CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(GetNode());
+    CXFA_LocaleMgr* pLocalMgr = m_pNode->GetDocument()->GetLocalMgr();
+    switch (widgetValue.GetType()) {
+      case XFA_VT_DATE: {
+        WideString wsDate, wsTime;
+        if (SplitDateTime(wsValue, wsDate, wsTime)) {
+          CXFA_LocaleValue date(XFA_VT_DATE, wsDate, pLocalMgr);
+          if (date.FormatPatterns(wsValue, wsPicture, pLocale, eValueType))
+            return wsValue;
+        }
+        break;
+      }
+      case XFA_VT_TIME: {
+        WideString wsDate, wsTime;
+        if (SplitDateTime(wsValue, wsDate, wsTime)) {
+          CXFA_LocaleValue time(XFA_VT_TIME, wsTime, pLocalMgr);
+          if (time.FormatPatterns(wsValue, wsPicture, pLocale, eValueType))
+            return wsValue;
+        }
+        break;
+      }
+      default:
+        break;
+    }
+    widgetValue.FormatPatterns(wsValue, wsPicture, pLocale, eValueType);
+  }
+  return wsValue;
+}
+
+WideString CXFA_Node::GetNormalizeDataValue(const WideString& wsValue) {
+  if (wsValue.IsEmpty())
+    return L"";
+
+  WideString wsPicture = GetPictureContent(XFA_VALUEPICTURE_DataBind);
+  if (wsPicture.IsEmpty())
+    return wsValue;
+
+  ASSERT(GetNode());
+  CXFA_LocaleMgr* pLocalMgr = GetNode()->GetDocument()->GetLocalMgr();
+  IFX_Locale* pLocale = m_pNode->GetLocale();
+  CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(GetNode());
+  if (widgetValue.ValidateValue(wsValue, wsPicture, pLocale, &wsPicture)) {
+    widgetValue = CXFA_LocaleValue(widgetValue.GetType(), wsValue, wsPicture,
+                                   pLocale, pLocalMgr);
+    return widgetValue.GetValue();
+  }
+  return wsValue;
+}
+
+WideString CXFA_Node::GetFormatDataValue(const WideString& wsValue) {
+  if (wsValue.IsEmpty())
+    return L"";
+
+  WideString wsPicture = GetPictureContent(XFA_VALUEPICTURE_DataBind);
+  if (wsPicture.IsEmpty())
+    return wsValue;
+
+  WideString wsFormattedValue = wsValue;
+  if (IFX_Locale* pLocale = m_pNode->GetLocale()) {
+    ASSERT(GetNode());
+    CXFA_Value* pNodeValue =
+        GetNode()->GetChild<CXFA_Value>(0, XFA_Element::Value, false);
+    if (!pNodeValue)
+      return wsValue;
+
+    CXFA_Node* pValueChild = pNodeValue->GetFirstChild();
+    if (!pValueChild)
+      return wsValue;
+
+    int32_t iVTType = XFA_VT_NULL;
+    switch (pValueChild->GetElementType()) {
+      case XFA_Element::Decimal:
+        iVTType = XFA_VT_DECIMAL;
+        break;
+      case XFA_Element::Float:
+        iVTType = XFA_VT_FLOAT;
+        break;
+      case XFA_Element::Date:
+        iVTType = XFA_VT_DATE;
+        break;
+      case XFA_Element::Time:
+        iVTType = XFA_VT_TIME;
+        break;
+      case XFA_Element::DateTime:
+        iVTType = XFA_VT_DATETIME;
+        break;
+      case XFA_Element::Boolean:
+        iVTType = XFA_VT_BOOLEAN;
+        break;
+      case XFA_Element::Integer:
+        iVTType = XFA_VT_INTEGER;
+        break;
+      case XFA_Element::Text:
+        iVTType = XFA_VT_TEXT;
+        break;
+      default:
+        iVTType = XFA_VT_NULL;
+        break;
+    }
+    CXFA_LocaleMgr* pLocalMgr = GetNode()->GetDocument()->GetLocalMgr();
+    CXFA_LocaleValue widgetValue(iVTType, wsValue, pLocalMgr);
+    switch (widgetValue.GetType()) {
+      case XFA_VT_DATE: {
+        WideString wsDate, wsTime;
+        if (SplitDateTime(wsValue, wsDate, wsTime)) {
+          CXFA_LocaleValue date(XFA_VT_DATE, wsDate, pLocalMgr);
+          if (date.FormatPatterns(wsFormattedValue, wsPicture, pLocale,
+                                  XFA_VALUEPICTURE_DataBind)) {
+            return wsFormattedValue;
+          }
+        }
+        break;
+      }
+      case XFA_VT_TIME: {
+        WideString wsDate, wsTime;
+        if (SplitDateTime(wsValue, wsDate, wsTime)) {
+          CXFA_LocaleValue time(XFA_VT_TIME, wsTime, pLocalMgr);
+          if (time.FormatPatterns(wsFormattedValue, wsPicture, pLocale,
+                                  XFA_VALUEPICTURE_DataBind)) {
+            return wsFormattedValue;
+          }
+        }
+        break;
+      }
+      default:
+        break;
+    }
+    widgetValue.FormatPatterns(wsFormattedValue, wsPicture, pLocale,
+                               XFA_VALUEPICTURE_DataBind);
+  }
+  return wsFormattedValue;
+}
+
+WideString CXFA_Node::NormalizeNumStr(const WideString& wsValue) {
+  if (wsValue.IsEmpty())
+    return L"";
+
+  WideString wsOutput = wsValue;
+  wsOutput.TrimLeft('0');
+
+  if (!wsOutput.IsEmpty() && wsOutput.Contains('.') && GetFracDigits() != -1) {
+    wsOutput.TrimRight(L"0");
+    wsOutput.TrimRight(L".");
+  }
+  if (wsOutput.IsEmpty() || wsOutput[0] == '.')
+    wsOutput.InsertAtFront('0');
+
+  return wsOutput;
+}
+
+WideString CXFA_Node::FormatNumStr(const WideString& wsValue,
+                                   IFX_Locale* pLocale) {
+  if (wsValue.IsEmpty())
+    return L"";
+
+  WideString wsSrcNum = wsValue;
+  WideString wsGroupSymbol =
+      pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Grouping);
+  bool bNeg = false;
+  if (wsSrcNum[0] == '-') {
+    bNeg = true;
+    wsSrcNum.Delete(0, 1);
+  }
+
+  auto dot_index = wsSrcNum.Find('.');
+  dot_index = !dot_index.has_value() ? wsSrcNum.GetLength() : dot_index;
+
+  if (dot_index.value() < 1)
+    return L"";
+
+  size_t nPos = dot_index.value() % 3;
+  WideString wsOutput;
+  for (size_t i = 0; i < dot_index.value(); i++) {
+    if (i % 3 == nPos && i != 0)
+      wsOutput += wsGroupSymbol;
+
+    wsOutput += wsSrcNum[i];
+  }
+  if (dot_index.value() < wsSrcNum.GetLength()) {
+    wsOutput += pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal);
+    wsOutput += wsSrcNum.Right(wsSrcNum.GetLength() - dot_index.value() - 1);
+  }
+  if (bNeg)
+    return pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus) + wsOutput;
+
+  return wsOutput;
+}
+
+void CXFA_Node::InsertListTextItem(CXFA_Node* pItems,
+                                   const WideString& wsText,
+                                   int32_t nIndex) {
+  CXFA_Node* pText = pItems->CreateSamePacketNode(XFA_Element::Text);
+  pItems->InsertChild(nIndex, pText);
+  pText->JSObject()->SetContent(wsText, wsText, false, false, false);
+}
+
+WideString CXFA_Node::NumericLimit(const WideString& wsValue,
+                                   int32_t iLead,
+                                   int32_t iTread) const {
+  if ((iLead == -1) && (iTread == -1))
+    return wsValue;
+
+  WideString wsRet;
+  int32_t iLead_ = 0, iTread_ = -1;
+  int32_t iCount = wsValue.GetLength();
+  if (iCount == 0)
+    return wsValue;
+
+  int32_t i = 0;
+  if (wsValue[i] == L'-') {
+    wsRet += L'-';
+    i++;
+  }
+  for (; i < iCount; i++) {
+    wchar_t wc = wsValue[i];
+    if (FXSYS_isDecimalDigit(wc)) {
+      if (iLead >= 0) {
+        iLead_++;
+        if (iLead_ > iLead)
+          return L"0";
+      } else if (iTread_ >= 0) {
+        iTread_++;
+        if (iTread_ > iTread) {
+          if (iTread != -1) {
+            CFX_Decimal wsDeci = CFX_Decimal(wsValue.AsStringView());
+            wsDeci.SetScale(iTread);
+            wsRet = wsDeci;
+          }
+          return wsRet;
+        }
+      }
+    } else if (wc == L'.') {
+      iTread_ = 0;
+      iLead = -1;
+    }
+    wsRet += wc;
+  }
+  return wsRet;
+}
diff --git a/xfa/fxfa/parser/cxfa_node.h b/xfa/fxfa/parser/cxfa_node.h
index 0991a53..6b6e865 100644
--- a/xfa/fxfa/parser/cxfa_node.h
+++ b/xfa/fxfa/parser/cxfa_node.h
@@ -18,6 +18,8 @@
 #include "third_party/base/optional.h"
 #include "xfa/fxfa/parser/cxfa_object.h"
 
+class CFGAS_GEFont;
+class CFX_DIBitmap;
 class CFX_XMLNode;
 class CXFA_Bind;
 class CXFA_Border;
@@ -25,21 +27,37 @@
 class CXFA_Caption;
 class CXFA_Event;
 class CXFA_EventParam;
+class CXFA_FFDoc;
 class CXFA_FFDocView;
+class CXFA_FFWidget;
 class CXFA_Font;
 class CXFA_Margin;
 class CXFA_Occur;
 class CXFA_Para;
 class CXFA_Script;
+class CXFA_TextLayout;
 class CXFA_Validate;
 class CXFA_Value;
-class CXFA_WidgetAcc;
+class CXFA_WidgetLayoutData;
 class IFX_Locale;
 
 #define XFA_NODEFILTER_Children 0x01
 #define XFA_NODEFILTER_Properties 0x02
 #define XFA_NODEFILTER_OneOfProperty 0x04
 
+enum XFA_CHECKSTATE {
+  XFA_CHECKSTATE_On = 0,
+  XFA_CHECKSTATE_Off = 1,
+  XFA_CHECKSTATE_Neutral = 2,
+};
+
+enum XFA_VALUEPICTURE {
+  XFA_VALUEPICTURE_Raw = 0,
+  XFA_VALUEPICTURE_Display,
+  XFA_VALUEPICTURE_Edit,
+  XFA_VALUEPICTURE_DataBind,
+};
+
 enum XFA_NodeFlag {
   XFA_NodeFlag_None = 0,
   XFA_NodeFlag_Initialized = 1 << 0,
@@ -304,17 +322,130 @@
   bool IsNull() const { return m_bIsNull; }
   void SetIsNull(bool val) { m_bIsNull = val; }
 
-  void SetWidgetReady();
+  void SetWidgetReady() { is_widget_ready_ = true; }
   bool IsWidgetReady() const { return is_widget_ready_; }
-  CXFA_WidgetAcc* GetWidgetAcc() {
+  // TODO(dsinclair): Remove post WidgetAcc merge.
+  CXFA_Node* GetWidgetAcc() {
     ASSERT(IsWidgetReady());
-    ASSERT(acc_.get() != nullptr);
-    return acc_.get();
+    return this;
   }
 
   std::vector<CXFA_Event*> GetEventByActivity(XFA_AttributeEnum iActivity,
                                               bool bIsFormReady);
 
+  void ResetData();
+
+  CXFA_FFWidget* GetNextWidget(CXFA_FFWidget* pWidget);
+  void StartWidgetLayout(CXFA_FFDoc* doc,
+                         float& fCalcWidth,
+                         float& fCalcHeight);
+  bool FindSplitPos(CXFA_FFDocView* docView,
+                    int32_t iBlockIndex,
+                    float& fCalcHeight);
+
+  bool LoadCaption(CXFA_FFDoc* doc);
+  CXFA_TextLayout* GetCaptionTextLayout();
+
+  void LoadText(CXFA_FFDoc* doc);
+  CXFA_TextLayout* GetTextLayout();
+
+  bool LoadImageImage(CXFA_FFDoc* doc);
+  bool LoadImageEditImage(CXFA_FFDoc* doc);
+  void GetImageDpi(int32_t& iImageXDpi, int32_t& iImageYDpi);
+  void GetImageEditDpi(int32_t& iImageXDpi, int32_t& iImageYDpi);
+
+  RetainPtr<CFX_DIBitmap> GetImageImage();
+  RetainPtr<CFX_DIBitmap> GetImageEditImage();
+  void SetImageEdit(const WideString& wsContentType,
+                    const WideString& wsHref,
+                    const WideString& wsData);
+  void SetImageImage(const RetainPtr<CFX_DIBitmap>& newImage);
+  void SetImageEditImage(const RetainPtr<CFX_DIBitmap>& newImage);
+  void UpdateUIDisplay(CXFA_FFDocView* docView, CXFA_FFWidget* pExcept);
+
+  RetainPtr<CFGAS_GEFont> GetFDEFont(CXFA_FFDoc* doc);
+
+  // TODO(dsinclair): Remove post WidgetAcc merge.
+  CXFA_Node* GetNode() { return this; }
+
+  bool IsOpenAccess() const;
+  bool IsListBox();
+  bool IsAllowNeutral();
+  bool IsRadioButton();
+  bool IsChoiceListAllowTextEntry();
+  bool IsMultiLine();
+
+  XFA_AttributeEnum GetButtonHighlight();
+  bool HasButtonRollover() const;
+  bool HasButtonDown() const;
+
+  bool IsCheckButtonRound();
+  XFA_AttributeEnum GetCheckButtonMark();
+  float GetCheckButtonSize();
+
+  XFA_CHECKSTATE GetCheckState();
+  void SetCheckState(XFA_CHECKSTATE eCheckState, bool bNotify);
+
+  CXFA_Node* GetSelectedMember();
+  CXFA_Node* SetSelectedMember(const WideStringView& wsName, bool bNotify);
+  void SetSelectedMemberByValue(const WideStringView& wsValue,
+                                bool bNotify,
+                                bool bScriptModify,
+                                bool bSyncData);
+
+  CXFA_Node* GetExclGroupFirstMember();
+  CXFA_Node* GetExclGroupNextMember(CXFA_Node* pNode);
+
+  int32_t CountChoiceListItems(bool bSaveValue);
+  Optional<WideString> GetChoiceListItem(int32_t nIndex, bool bSaveValue);
+  bool IsChoiceListMultiSelect();
+  bool IsChoiceListCommitOnSelect();
+  std::vector<WideString> GetChoiceListItems(bool bSaveValue);
+
+  int32_t CountSelectedItems();
+  int32_t GetSelectedItem(int32_t nIndex);
+  std::vector<int32_t> GetSelectedItems();
+  std::vector<WideString> GetSelectedItemsValue();
+  void SetSelectedItems(const std::vector<int32_t>& iSelArray,
+                        bool bNotify,
+                        bool bScriptModify,
+                        bool bSyncData);
+  void InsertItem(const WideString& wsLabel,
+                  const WideString& wsValue,
+                  bool bNotify);
+  bool DeleteItem(int32_t nIndex, bool bNotify, bool bScriptModify);
+  void ClearAllSelections();
+
+  bool GetItemState(int32_t nIndex);
+  void SetItemState(int32_t nIndex,
+                    bool bSelected,
+                    bool bNotify,
+                    bool bScriptModify,
+                    bool bSyncData);
+
+  WideString GetItemValue(const WideStringView& wsLabel);
+
+  bool IsHorizontalScrollPolicyOff();
+  bool IsVerticalScrollPolicyOff();
+  Optional<int32_t> GetNumberOfCells();
+
+  bool SetValue(XFA_VALUEPICTURE eValueType, const WideString& wsValue);
+  WideString GetValue(XFA_VALUEPICTURE eValueType);
+
+  WideString GetPictureContent(XFA_VALUEPICTURE ePicture);
+  WideString GetNormalizeDataValue(const WideString& wsValue);
+  WideString GetFormatDataValue(const WideString& wsValue);
+  WideString NormalizeNumStr(const WideString& wsValue);
+
+  WideString GetPasswordChar();
+  std::pair<XFA_Element, int32_t> GetMaxChars();
+  int32_t GetFracDigits();
+  int32_t GetLeadDigits();
+
+  WideString NumericLimit(const WideString& wsValue,
+                          int32_t iLead,
+                          int32_t iTread) const;
+
  protected:
   CXFA_Node(CXFA_Document* pDoc,
             XFA_PacketType ePacket,
@@ -363,6 +494,35 @@
   CXFA_Node* GetNextSameNameSiblingInternal(
       const WideStringView& wsNodeName) const;
   CXFA_Node* GetNextSameClassSiblingInternal(XFA_Element eType) const;
+  void CalcCaptionSize(CXFA_FFDoc* doc, CFX_SizeF& szCap);
+  bool CalculateFieldAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size);
+  bool CalculateWidgetAutoSize(CFX_SizeF& size);
+  bool CalculateTextEditAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size);
+  bool CalculateCheckButtonAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size);
+  bool CalculatePushButtonAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size);
+  CFX_SizeF CalculateImageSize(float img_width,
+                               float img_height,
+                               float dpi_x,
+                               float dpi_y);
+  bool CalculateImageEditAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size);
+  bool CalculateImageAutoSize(CXFA_FFDoc* doc, CFX_SizeF& size);
+  float CalculateWidgetAutoHeight(float fHeightCalc);
+  float CalculateWidgetAutoWidth(float fWidthCalc);
+  float GetWidthWithoutMargin(float fWidthCalc);
+  float GetHeightWithoutMargin(float fHeightCalc);
+  void CalculateTextContentSize(CXFA_FFDoc* doc, CFX_SizeF& size);
+  void CalculateAccWidthAndHeight(CXFA_FFDoc* doc,
+                                  XFA_Element eUIType,
+                                  float& fWidth,
+                                  float& fCalcHeight);
+  void InitLayoutData();
+  void StartTextLayout(CXFA_FFDoc* doc, float& fCalcWidth, float& fCalcHeight);
+
+  void InsertListTextItem(CXFA_Node* pItems,
+                          const WideString& wsText,
+                          int32_t nIndex);
+  WideString FormatNumStr(const WideString& wsValue, IFX_Locale* pLocale);
+  void GetItemLabel(const WideStringView& wsValue, WideString& wsLabel);
 
   const PropertyData* const m_Properties;
   const AttributeData* const m_Attributes;
@@ -383,7 +543,9 @@
   bool m_bIsNull = true;
   bool m_bPreNull = true;
   bool is_widget_ready_ = false;
-  std::unique_ptr<CXFA_WidgetAcc> acc_;
+  std::unique_ptr<CXFA_WidgetLayoutData> m_pLayoutData;
+  // TODO(dsinclair): Remove post WidgetAcc merge.
+  CXFA_Node* m_pNode;
 };
 
 #endif  // XFA_FXFA_PARSER_CXFA_NODE_H_
diff --git a/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp b/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp
index d843fa8..8b0fa40 100644
--- a/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp
+++ b/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp
@@ -16,7 +16,6 @@
 #include "fxjs/xfa/cjx_object.h"
 #include "third_party/base/logging.h"
 #include "third_party/base/stl_util.h"
-#include "xfa/fxfa/cxfa_widgetacc.h"
 #include "xfa/fxfa/parser/cxfa_bind.h"
 #include "xfa/fxfa/parser/cxfa_datagroup.h"
 #include "xfa/fxfa/parser/cxfa_document.h"