Split text field code out of CPDF_GenerateAP::GenerateFormAP()

Move text field code into GenerateTextFieldAP(). Unlike
GenerateComboBoxAP(), GenerateTextFieldAP() takes a CPVT_VariableText
instead of a CPVT_VariableText::Provider. Though GenerateTextFieldAP()
still needs access to the Provider, so make that possible by adding
CPVT_VariableText::GetProvider().

Change-Id: Idb5bf579f4fbe0b1d2ce99c95a843e7711b037e4
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/126594
Reviewed-by: Thomas Sepez <tsepez@google.com>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfdoc/cpdf_generateap.cpp b/core/fpdfdoc/cpdf_generateap.cpp
index beb05f8..0d5a0cb 100644
--- a/core/fpdfdoc/cpdf_generateap.cpp
+++ b/core/fpdfdoc/cpdf_generateap.cpp
@@ -689,6 +689,59 @@
   ap_dict->SetNewFor<CPDF_Reference>("N", doc, normal_stream->GetObjNum());
 }
 
+ByteString GenerateTextFieldAP(const CPDF_Dictionary* annot_dict,
+                               const CFX_FloatRect& body_rect,
+                               float font_size,
+                               CPVT_VariableText& vt) {
+  RetainPtr<const CPDF_Object> v_field =
+      CPDF_FormField::GetFieldAttrForDict(annot_dict, pdfium::form_fields::kV);
+  WideString value = v_field ? v_field->GetUnicodeText() : WideString();
+  RetainPtr<const CPDF_Object> q_field =
+      CPDF_FormField::GetFieldAttrForDict(annot_dict, "Q");
+  const int32_t align = q_field ? q_field->GetInteger() : 0;
+  RetainPtr<const CPDF_Object> ff_field =
+      CPDF_FormField::GetFieldAttrForDict(annot_dict, pdfium::form_fields::kFf);
+  const uint32_t flags = ff_field ? ff_field->GetInteger() : 0;
+  RetainPtr<const CPDF_Object> max_len_field =
+      CPDF_FormField::GetFieldAttrForDict(annot_dict, "MaxLen");
+  const uint32_t max_len = max_len_field ? max_len_field->GetInteger() : 0;
+  vt.SetPlateRect(body_rect);
+  vt.SetAlignment(align);
+  if (FXSYS_IsFloatZero(font_size)) {
+    vt.SetAutoFontSize(true);
+  } else {
+    vt.SetFontSize(font_size);
+  }
+
+  bool is_multi_line = (flags >> 12) & 1;
+  if (is_multi_line) {
+    vt.SetMultiLine(true);
+    vt.SetAutoReturn(true);
+  }
+  uint16_t sub_word = 0;
+  if ((flags >> 13) & 1) {
+    sub_word = '*';
+    vt.SetPasswordChar(sub_word);
+  }
+  bool is_char_array = (flags >> 24) & 1;
+  if (is_char_array) {
+    vt.SetCharArray(max_len);
+  } else {
+    vt.SetLimitChar(max_len);
+  }
+
+  vt.Initialize();
+  vt.SetText(value);
+  vt.RearrangeAll();
+  CFX_PointF offset;
+  if (!is_multi_line) {
+    offset = CFX_PointF(
+        0.0f, (vt.GetContentRect().Height() - body_rect.Height()) / 2.0f);
+  }
+  return GenerateEditAP(vt.GetProvider()->GetFontMap(), vt.GetIterator(),
+                        offset, !is_char_array, sub_word);
+}
+
 ByteString GenerateComboBoxAP(const CPDF_Dictionary* annot_dict,
                               const CFX_FloatRect& body_rect,
                               const CFX_Color& text_color,
@@ -1320,58 +1373,11 @@
   CPVT_VariableText::Provider provider(&map);
   switch (type) {
     case CPDF_GenerateAP::kTextField: {
-      RetainPtr<const CPDF_Object> v_field =
-          CPDF_FormField::GetFieldAttrForDict(annot_dict,
-                                              pdfium::form_fields::kV);
-      WideString value = v_field ? v_field->GetUnicodeText() : WideString();
-      RetainPtr<const CPDF_Object> q_field =
-          CPDF_FormField::GetFieldAttrForDict(annot_dict, "Q");
-      const int32_t align = q_field ? q_field->GetInteger() : 0;
-      RetainPtr<const CPDF_Object> ff_field =
-          CPDF_FormField::GetFieldAttrForDict(annot_dict,
-                                              pdfium::form_fields::kFf);
-      const uint32_t flags = ff_field ? ff_field->GetInteger() : 0;
-      RetainPtr<const CPDF_Object> max_len_field =
-          CPDF_FormField::GetFieldAttrForDict(annot_dict, "MaxLen");
-      const uint32_t max_len = max_len_field ? max_len_field->GetInteger() : 0;
       CPVT_VariableText vt(&provider);
-      vt.SetPlateRect(body_rect);
-      vt.SetAlignment(align);
-      if (FXSYS_IsFloatZero(font_size)) {
-        vt.SetAutoFontSize(true);
-      } else {
-        vt.SetFontSize(font_size);
-      }
-
-      bool is_multi_line = (flags >> 12) & 1;
-      if (is_multi_line) {
-        vt.SetMultiLine(true);
-        vt.SetAutoReturn(true);
-      }
-      uint16_t sub_word = 0;
-      if ((flags >> 13) & 1) {
-        sub_word = '*';
-        vt.SetPasswordChar(sub_word);
-      }
-      bool is_char_array = (flags >> 24) & 1;
-      if (is_char_array) {
-        vt.SetCharArray(max_len);
-      } else {
-        vt.SetLimitChar(max_len);
-      }
-
-      vt.Initialize();
-      vt.SetText(value);
-      vt.RearrangeAll();
-      CFX_FloatRect content_rect = vt.GetContentRect();
-      CFX_PointF offset;
-      if (!is_multi_line) {
-        offset = CFX_PointF(
-            0.0f, (content_rect.Height() - body_rect.Height()) / 2.0f);
-      }
-      ByteString body = GenerateEditAP(&map, vt.GetIterator(), offset,
-                                       !is_char_array, sub_word);
+      ByteString body =
+          GenerateTextFieldAP(annot_dict, body_rect, font_size, vt);
       if (body.GetLength() > 0) {
+        const CFX_FloatRect content_rect = vt.GetContentRect();
         app_stream << "/Tx BMC\n" << "q\n";
         if (content_rect.Width() > body_rect.Width() ||
             content_rect.Height() > body_rect.Height()) {
diff --git a/core/fpdfdoc/cpvt_variabletext.cpp b/core/fpdfdoc/cpvt_variabletext.cpp
index c890e85..bf38bec 100644
--- a/core/fpdfdoc/cpvt_variabletext.cpp
+++ b/core/fpdfdoc/cpvt_variabletext.cpp
@@ -873,6 +873,10 @@
   m_pVTProvider = pProvider;
 }
 
+CPVT_VariableText::Provider* CPVT_VariableText::GetProvider() {
+  return m_pVTProvider;
+}
+
 CFX_PointF CPVT_VariableText::GetBTPoint() const {
   return CFX_PointF(m_rcPlate.left, m_rcPlate.top);
 }
diff --git a/core/fpdfdoc/cpvt_variabletext.h b/core/fpdfdoc/cpvt_variabletext.h
index a378dbb..01982d2 100644
--- a/core/fpdfdoc/cpvt_variabletext.h
+++ b/core/fpdfdoc/cpvt_variabletext.h
@@ -70,6 +70,7 @@
   ~CPVT_VariableText();
 
   void SetProvider(Provider* pProvider);
+  Provider* GetProvider();
   CPVT_VariableText::Iterator* GetIterator();
 
   CFX_FloatRect GetContentRect() const;