Only create widgets if really needed.

Currently the GetWidget call will create a backing widget for a control behind
the scenes if it doesn't exist. This can cause more work to be done then needed
as we may need to create the page and any supporting structures. This created
structure will then be torn down as we don't need it anymore once we're done
with the widget.

For the instances where setting the value on the widget will have no effect (as
we'll destroy it anyway) we can tell GetWidget() to not create the widget and
return without doing any work.

BUG=pdfium:632709

Review-Url: https://codereview.chromium.org/2251453002
diff --git a/fpdfsdk/fsdk_baseform.cpp b/fpdfsdk/fsdk_baseform.cpp
index 0b2c997..2eda2de 100644
--- a/fpdfsdk/fsdk_baseform.cpp
+++ b/fpdfsdk/fsdk_baseform.cpp
@@ -2061,7 +2061,8 @@
   return (CPDFSDK_Widget*)pIterator->GetPrevAnnot(pWidget);
 }
 
-CPDFSDK_Widget* CPDFSDK_InterForm::GetWidget(CPDF_FormControl* pControl) const {
+CPDFSDK_Widget* CPDFSDK_InterForm::GetWidget(CPDF_FormControl* pControl,
+                                             bool createIfNeeded) const {
   if (!pControl || !m_pInterForm)
     return nullptr;
 
@@ -2069,9 +2070,10 @@
   const auto it = m_Map.find(pControl);
   if (it != m_Map.end())
     pWidget = it->second;
-
   if (pWidget)
     return pWidget;
+  if (!createIfNeeded)
+    return nullptr;
 
   CPDF_Dictionary* pControlDict = pControl->GetWidget();
   CPDF_Document* pDocument = m_pDocument->GetPDFDocument();
@@ -2093,6 +2095,7 @@
 
   if (!pPage)
     return nullptr;
+
   return (CPDFSDK_Widget*)pPage->GetAnnotByDict(pControlDict);
 }
 
@@ -2112,7 +2115,7 @@
   for (int i = 0, sz = pField->CountControls(); i < sz; ++i) {
     CPDF_FormControl* pFormCtrl = pField->GetControl(i);
     ASSERT(pFormCtrl);
-    CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl);
+    CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl, true);
     if (pWidget)
       widgets->push_back(pWidget);
   }
@@ -2277,7 +2280,6 @@
 
         IJS_Context* pContext = pRuntime->NewContext();
         pContext->OnField_Format(pFormField, Value, TRUE);
-
         CFX_WideString sInfo;
         FX_BOOL bRet = pContext->RunScript(script, &sInfo);
         pRuntime->ReleaseContext(pContext);
@@ -2299,7 +2301,7 @@
   for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
     CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
     ASSERT(pFormCtrl);
-    if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl))
+    if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl, false))
       pWidget->ResetAppearance(sValue, bValueChanged);
   }
 }
@@ -2309,7 +2311,7 @@
     CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
     ASSERT(pFormCtrl);
 
-    if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl)) {
+    if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl, false)) {
       CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
       CFFL_IFormFiller* pIFormFiller = pEnv->GetIFormFiller();
       UnderlyingPageType* pPage = pWidget->GetUnderlyingPage();
@@ -2379,7 +2381,7 @@
       CPDF_FormControl* pControl = pField->GetControl(i);
       ASSERT(pControl);
 
-      if (CPDFSDK_Widget* pWidget = GetWidget(pControl)) {
+      if (CPDFSDK_Widget* pWidget = GetWidget(pControl, false)) {
         uint32_t nFlags = pWidget->GetFlags();
         nFlags &= ~ANNOTFLAG_INVISIBLE;
         nFlags &= ~ANNOTFLAG_NOVIEW;
@@ -2502,7 +2504,7 @@
                                          FX_BOOL bSynchronizeElse) {
   for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
     CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
-    if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl)) {
+    if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl, false)) {
       pWidget->Synchronize(bSynchronizeElse);
     }
   }
diff --git a/fpdfsdk/include/fsdk_baseform.h b/fpdfsdk/include/fsdk_baseform.h
index c5f45e7..8eee56c 100644
--- a/fpdfsdk/include/fsdk_baseform.h
+++ b/fpdfsdk/include/fsdk_baseform.h
@@ -263,7 +263,8 @@
   FX_BOOL HighlightWidgets();
 
   CPDFSDK_Widget* GetSibling(CPDFSDK_Widget* pWidget, FX_BOOL bNext) const;
-  CPDFSDK_Widget* GetWidget(CPDF_FormControl* pControl) const;
+  CPDFSDK_Widget* GetWidget(CPDF_FormControl* pControl,
+                            bool createIfNeeded) const;
   void GetWidgets(const CFX_WideString& sFieldName,
                   std::vector<CPDFSDK_Widget*>* widgets) const;
   void GetWidgets(CPDF_FormField* pField,
diff --git a/fpdfsdk/javascript/Field.cpp b/fpdfsdk/javascript/Field.cpp
index 8528881..20c41c6 100644
--- a/fpdfsdk/javascript/Field.cpp
+++ b/fpdfsdk/javascript/Field.cpp
@@ -262,7 +262,7 @@
   ASSERT(pFormControl);
 
   CPDFSDK_InterForm* pForm = pDocument->GetInterForm();
-  CPDFSDK_Widget* pWidget = pForm->GetWidget(pFormControl);
+  CPDFSDK_Widget* pWidget = pForm->GetWidget(pFormControl, false);
 
   if (pWidget) {
     if (bResetAP) {
@@ -292,10 +292,12 @@
 }
 
 CPDFSDK_Widget* Field::GetWidget(CPDFSDK_Document* pDocument,
-                                 CPDF_FormControl* pFormControl) {
+                                 CPDF_FormControl* pFormControl,
+                                 bool createIfNeeded) {
   CPDFSDK_InterForm* pInterForm =
       static_cast<CPDFSDK_InterForm*>(pDocument->GetInterForm());
-  return pInterForm ? pInterForm->GetWidget(pFormControl) : nullptr;
+  return pInterForm ? pInterForm->GetWidget(pFormControl, createIfNeeded)
+                    : nullptr;
 }
 
 FX_BOOL Field::ValueIsOccur(CPDF_FormField* pFormField,
@@ -403,7 +405,7 @@
       return FALSE;
 
     CPDFSDK_Widget* pWidget =
-        GetWidget(m_pDocument, GetSmartFieldControl(pFormField));
+        GetWidget(m_pDocument, GetSmartFieldControl(pFormField), false);
     if (!pWidget)
       return FALSE;
 
@@ -459,7 +461,7 @@
       FX_BOOL bSet = FALSE;
       for (int i = 0, sz = pFormField->CountControls(); i < sz; ++i) {
         if (CPDFSDK_Widget* pWidget =
-                GetWidget(pDocument, pFormField->GetControl(i))) {
+                GetWidget(pDocument, pFormField->GetControl(i), false)) {
           if (pWidget->GetBorderStyle() != nBorderStyle) {
             pWidget->SetBorderStyle(nBorderStyle);
             bSet = TRUE;
@@ -473,7 +475,8 @@
         return;
       if (CPDF_FormControl* pFormControl =
               pFormField->GetControl(nControlIndex)) {
-        if (CPDFSDK_Widget* pWidget = GetWidget(pDocument, pFormControl)) {
+        if (CPDFSDK_Widget* pWidget =
+                GetWidget(pDocument, pFormControl, false)) {
           if (pWidget->GetBorderStyle() != nBorderStyle) {
             pWidget->SetBorderStyle(nBorderStyle);
             UpdateFormControl(pDocument, pFormControl, TRUE, TRUE, TRUE);
@@ -1208,7 +1211,7 @@
     ASSERT(pFormField);
     CPDFSDK_InterForm* pInterForm = m_pDocument->GetInterForm();
     CPDFSDK_Widget* pWidget =
-        pInterForm->GetWidget(GetSmartFieldControl(pFormField));
+        pInterForm->GetWidget(GetSmartFieldControl(pFormField), true);
     if (!pWidget)
       return FALSE;
 
@@ -1246,7 +1249,8 @@
         CPDF_FormControl* pFormControl = pFormField->GetControl(i);
         ASSERT(pFormControl);
 
-        if (CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormControl)) {
+        if (CPDFSDK_Widget* pWidget =
+                pInterForm->GetWidget(pFormControl, true)) {
           uint32_t dwFlag = pWidget->GetFlags();
           switch (number) {
             case 0:
@@ -1287,7 +1291,8 @@
         return;
       if (CPDF_FormControl* pFormControl =
               pFormField->GetControl(nControlIndex)) {
-        if (CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormControl)) {
+        if (CPDFSDK_Widget* pWidget =
+                pInterForm->GetWidget(pFormControl, true)) {
           uint32_t dwFlag = pWidget->GetFlags();
           switch (number) {
             case 0:
@@ -1525,7 +1530,7 @@
     ASSERT(pFormField);
     CPDFSDK_InterForm* pInterForm = m_pDocument->GetInterForm();
     CPDFSDK_Widget* pWidget =
-        pInterForm->GetWidget(GetSmartFieldControl(pFormField));
+        pInterForm->GetWidget(GetSmartFieldControl(pFormField), false);
     if (!pWidget)
       return FALSE;
 
@@ -1552,7 +1557,7 @@
       FX_BOOL bSet = FALSE;
       for (int i = 0, sz = pFormField->CountControls(); i < sz; ++i) {
         if (CPDFSDK_Widget* pWidget =
-                pInterForm->GetWidget(pFormField->GetControl(i))) {
+                pInterForm->GetWidget(pFormField->GetControl(i), false)) {
           uint32_t dwFlags = pWidget->GetFlags();
 
           if (b) {
@@ -1580,7 +1585,8 @@
         return;
       if (CPDF_FormControl* pFormControl =
               pFormField->GetControl(nControlIndex)) {
-        if (CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormControl)) {
+        if (CPDFSDK_Widget* pWidget =
+                pInterForm->GetWidget(pFormControl, false)) {
           uint32_t dwFlags = pWidget->GetFlags();
 
           if (b) {
@@ -1696,7 +1702,8 @@
     if (!pFormField->CountControls())
       return FALSE;
 
-    CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormField->GetControl(0));
+    CPDFSDK_Widget* pWidget =
+        pInterForm->GetWidget(pFormField->GetControl(0), false);
     if (!pWidget)
       return FALSE;
 
@@ -1720,7 +1727,8 @@
         CPDF_FormControl* pFormControl = pFormField->GetControl(i);
         ASSERT(pFormControl);
 
-        if (CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormControl)) {
+        if (CPDFSDK_Widget* pWidget =
+                pInterForm->GetWidget(pFormControl, false)) {
           if (number != pWidget->GetBorderWidth()) {
             pWidget->SetBorderWidth(number);
             bSet = TRUE;
@@ -1734,7 +1742,8 @@
         return;
       if (CPDF_FormControl* pFormControl =
               pFormField->GetControl(nControlIndex)) {
-        if (CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormControl)) {
+        if (CPDFSDK_Widget* pWidget =
+                pInterForm->GetWidget(pFormControl, false)) {
           if (number != pWidget->GetBorderWidth()) {
             pWidget->SetBorderWidth(number);
             UpdateFormControl(pDocument, pFormControl, TRUE, TRUE, TRUE);
@@ -1965,7 +1974,7 @@
         FX_BOOL bSet = FALSE;
         for (int i = 0, sz = pFormField->CountControls(); i < sz; ++i) {
           if (CPDFSDK_Widget* pWidget =
-                  pInterForm->GetWidget(pFormField->GetControl(i))) {
+                  pInterForm->GetWidget(pFormField->GetControl(i), false)) {
             uint32_t dwFlags = pWidget->GetFlags();
             if (bVP)
               dwFlags |= ANNOTFLAG_PRINT;
@@ -1986,7 +1995,8 @@
           return FALSE;
         if (CPDF_FormControl* pFormControl =
                 pFormField->GetControl(m_nFormControlIndex)) {
-          if (CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormControl)) {
+          if (CPDFSDK_Widget* pWidget =
+                  pInterForm->GetWidget(pFormControl, true)) {
             uint32_t dwFlags = pWidget->GetFlags();
             if (bVP)
               dwFlags |= ANNOTFLAG_PRINT;
@@ -2006,7 +2016,7 @@
   } else {
     CPDF_FormField* pFormField = FieldArray[0];
     CPDFSDK_Widget* pWidget =
-        pInterForm->GetWidget(GetSmartFieldControl(pFormField));
+        pInterForm->GetWidget(GetSmartFieldControl(pFormField), true);
     if (!pWidget)
       return FALSE;
 
@@ -2118,7 +2128,7 @@
     CPDF_FormField* pFormField = FieldArray[0];
     CPDFSDK_InterForm* pInterForm = m_pDocument->GetInterForm();
     CPDFSDK_Widget* pWidget =
-        pInterForm->GetWidget(GetSmartFieldControl(pFormField));
+        pInterForm->GetWidget(GetSmartFieldControl(pFormField), true);
     if (!pWidget)
       return FALSE;
 
@@ -2152,7 +2162,8 @@
         CPDF_FormControl* pFormControl = pFormField->GetControl(i);
         ASSERT(pFormControl);
 
-        if (CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormControl)) {
+        if (CPDFSDK_Widget* pWidget =
+                pInterForm->GetWidget(pFormControl, false)) {
           CFX_FloatRect crRect = rect;
 
           CPDF_Page* pPDFPage = pWidget->GetPDFPage();
@@ -2176,7 +2187,8 @@
         return;
       if (CPDF_FormControl* pFormControl =
               pFormField->GetControl(nControlIndex)) {
-        if (CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormControl)) {
+        if (CPDFSDK_Widget* pWidget =
+                pInterForm->GetWidget(pFormControl, false)) {
           CFX_FloatRect crRect = rect;
 
           CPDF_Page* pPDFPage = pWidget->GetPDFPage();
@@ -3250,7 +3262,7 @@
   CPDFSDK_InterForm* pInterForm = m_pDocument->GetInterForm();
   CPDFSDK_Widget* pWidget = nullptr;
   if (nCount == 1) {
-    pWidget = pInterForm->GetWidget(pFormField->GetControl(0));
+    pWidget = pInterForm->GetWidget(pFormField->GetControl(0), false);
   } else {
     CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
     UnderlyingPageType* pPage = UnderlyingFromFPDFPage(
@@ -3261,7 +3273,7 @@
             m_pDocument->GetPageView(pPage, true)) {
       for (int32_t i = 0; i < nCount; i++) {
         if (CPDFSDK_Widget* pTempWidget =
-                pInterForm->GetWidget(pFormField->GetControl(i))) {
+                pInterForm->GetWidget(pFormField->GetControl(i), false)) {
           if (pTempWidget->GetPDFPage() == pCurPageView->GetPDFPage()) {
             pWidget = pTempWidget;
             break;
diff --git a/fpdfsdk/javascript/Field.h b/fpdfsdk/javascript/Field.h
index 5697865..3d1b0ff 100644
--- a/fpdfsdk/javascript/Field.h
+++ b/fpdfsdk/javascript/Field.h
@@ -425,7 +425,8 @@
                                 FX_BOOL bRefresh);
 
   static CPDFSDK_Widget* GetWidget(CPDFSDK_Document* pDocument,
-                                   CPDF_FormControl* pFormControl);
+                                   CPDF_FormControl* pFormControl,
+                                   bool createIfNeeded);
   static std::vector<CPDF_FormField*> GetFormFields(
       CPDFSDK_Document* pDocument,
       const CFX_WideString& csFieldName);