Use enum for tracking form field types

Within PDFium use enum class for better type safety when working with
form field types. These values will still be converted to ints as part
of the public API, since that is the existing API.

This work is preperation for extending the number of form field types
to have more specific entries for XFA.

BUG=pdfium:952,chromium:763129,chromium:592758

Change-Id: Ie6c29f02ae22be782ff36eb87d27f1a4bf2c099e
Reviewed-on: https://pdfium-review.googlesource.com/22742
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
Reviewed-by: Henrique Nakashima <hnakashima@chromium.org>
diff --git a/fpdfsdk/cpdfsdk_formfillenvironment.cpp b/fpdfsdk/cpdfsdk_formfillenvironment.cpp
index b72a10b..955c184 100644
--- a/fpdfsdk/cpdfsdk_formfillenvironment.cpp
+++ b/fpdfsdk/cpdfsdk_formfillenvironment.cpp
@@ -718,8 +718,9 @@
 
   if (pFocusAnnot->GetAnnotSubtype() == CPDF_Annot::Subtype::WIDGET) {
     CPDFSDK_Widget* pWidget = static_cast<CPDFSDK_Widget*>(pFocusAnnot.Get());
-    int nFieldType = pWidget->GetFieldType();
-    if (FIELDTYPE_TEXTFIELD == nFieldType || FIELDTYPE_COMBOBOX == nFieldType) {
+    FormFieldType fieldType = pWidget->GetFieldType();
+    if (fieldType == FormFieldType::kTextField ||
+        fieldType == FormFieldType::kComboBox) {
       OnSetFieldInputFocus(nullptr, 0, false);
     }
   }
diff --git a/fpdfsdk/cpdfsdk_interform.cpp b/fpdfsdk/cpdfsdk_interform.cpp
index 4f0012d..04ccc35 100644
--- a/fpdfsdk/cpdfsdk_interform.cpp
+++ b/fpdfsdk/cpdfsdk_interform.cpp
@@ -45,6 +45,20 @@
 #include "xfa/fxfa/cxfa_ffwidgethandler.h"
 #endif  // PDF_ENABLE_XFA
 
+namespace {
+
+bool IsFormFieldTypeComboOrText(FormFieldType fieldType) {
+  switch (fieldType) {
+    case FormFieldType::kComboBox:
+    case FormFieldType::kTextField:
+      return true;
+    default:
+      return false;
+  }
+}
+
+}  // namespace
+
 CPDFSDK_InterForm::CPDFSDK_InterForm(CPDFSDK_FormFillEnvironment* pFormFillEnv)
     : m_pFormFillEnv(pFormFillEnv),
       m_pInterForm(
@@ -55,10 +69,9 @@
 #endif  // PDF_ENABLE_XFA
       m_bCalculate(true),
       m_bBusy(false),
-      m_iHighlightAlpha(0) {
+      m_HighlightAlpha(0) {
   m_pInterForm->SetFormNotify(this);
-  for (int i = 0; i < kNumFieldTypes; ++i)
-    m_bNeedHightlight[i] = false;
+  RemoveAllHighLights();
 }
 
 CPDFSDK_InterForm::~CPDFSDK_InterForm() {
@@ -238,8 +251,8 @@
     if (!pField)
       continue;
 
-    int nType = pField->GetFieldType();
-    if (nType != FIELDTYPE_COMBOBOX && nType != FIELDTYPE_TEXTFIELD)
+    FormFieldType fieldType = pField->GetFieldType();
+    if (!IsFormFieldTypeComboOrText(fieldType))
       continue;
 
     CPDF_AAction aAction = pField->GetAdditionalAction();
@@ -278,7 +291,7 @@
   }
 
   IJS_Runtime* pRuntime = m_pFormFillEnv->GetJSRuntime();
-  if (pFormField->GetFieldType() == FIELDTYPE_COMBOBOX &&
+  if (pFormField->GetFieldType() == FormFieldType::kComboBox &&
       pFormField->CountSelectedItems() > 0) {
     int index = pFormField->GetSelectedIndex(0);
     if (index >= 0)
@@ -598,8 +611,8 @@
 
 int CPDFSDK_InterForm::BeforeValueChange(CPDF_FormField* pField,
                                          const WideString& csValue) {
-  int nType = pField->GetFieldType();
-  if (nType != FIELDTYPE_COMBOBOX && nType != FIELDTYPE_TEXTFIELD)
+  FormFieldType fieldType = pField->GetFieldType();
+  if (!IsFormFieldTypeComboOrText(fieldType))
     return 0;
 
   if (!OnKeyStrokeCommit(pField, csValue))
@@ -615,8 +628,8 @@
 #ifdef PDF_ENABLE_XFA
   SynchronizeField(pField, false);
 #endif  // PDF_ENABLE_XFA
-  int nType = pField->GetFieldType();
-  if (nType == FIELDTYPE_COMBOBOX || nType == FIELDTYPE_TEXTFIELD) {
+  FormFieldType fieldType = pField->GetFieldType();
+  if (IsFormFieldTypeComboOrText(fieldType)) {
     OnCalculate(pField);
     bool bFormatted = false;
     WideString sValue = OnFormat(pField, bFormatted);
@@ -627,7 +640,7 @@
 
 int CPDFSDK_InterForm::BeforeSelectionChange(CPDF_FormField* pField,
                                              const WideString& csValue) {
-  if (pField->GetFieldType() != FIELDTYPE_LISTBOX)
+  if (pField->GetFieldType() != FormFieldType::kListBox)
     return 0;
 
   if (!OnKeyStrokeCommit(pField, csValue))
@@ -640,7 +653,7 @@
 }
 
 void CPDFSDK_InterForm::AfterSelectionChange(CPDF_FormField* pField) {
-  if (pField->GetFieldType() != FIELDTYPE_LISTBOX)
+  if (pField->GetFieldType() != FormFieldType::kListBox)
     return;
 
   OnCalculate(pField);
@@ -649,8 +662,9 @@
 }
 
 void CPDFSDK_InterForm::AfterCheckedStatusChange(CPDF_FormField* pField) {
-  int nType = pField->GetFieldType();
-  if (nType != FIELDTYPE_CHECKBOX && nType != FIELDTYPE_RADIOBUTTON)
+  FormFieldType fieldType = pField->GetFieldType();
+  if (fieldType != FormFieldType::kCheckBox &&
+      fieldType != FormFieldType::kRadioButton)
     return;
 
   OnCalculate(pField);
@@ -673,40 +687,38 @@
   OnCalculate(nullptr);
 }
 
-bool CPDFSDK_InterForm::IsNeedHighLight(int nFieldType) {
-  if (nFieldType < 1 || nFieldType > kNumFieldTypes)
+bool CPDFSDK_InterForm::IsNeedHighLight(FormFieldType fieldType) {
+  if (fieldType == FormFieldType::kUnknown)
     return false;
-  return m_bNeedHightlight[nFieldType - 1];
+
+  return m_NeedsHighlight[static_cast<size_t>(fieldType)];
 }
 
-void CPDFSDK_InterForm::RemoveAllHighLight() {
-  for (int i = 0; i < kNumFieldTypes; ++i)
-    m_bNeedHightlight[i] = false;
+void CPDFSDK_InterForm::RemoveAllHighLights() {
+  std::fill(m_HighlightColor, m_HighlightColor + kFormFieldTypeCount,
+            FXSYS_RGB(255, 255, 255));
+  std::fill(m_NeedsHighlight, m_NeedsHighlight + kFormFieldTypeCount, false);
 }
 
-void CPDFSDK_InterForm::SetHighlightColor(FX_COLORREF clr, int nFieldType) {
-  if (nFieldType < 0 || nFieldType > kNumFieldTypes)
+void CPDFSDK_InterForm::SetHighlightColor(FX_COLORREF clr,
+                                          FormFieldType fieldType) {
+  if (fieldType == FormFieldType::kUnknown)
     return;
-  switch (nFieldType) {
-    case 0: {
-      for (int i = 0; i < kNumFieldTypes; ++i) {
-        m_aHighlightColor[i] = clr;
-        m_bNeedHightlight[i] = true;
-      }
-      break;
-    }
-    default: {
-      m_aHighlightColor[nFieldType - 1] = clr;
-      m_bNeedHightlight[nFieldType - 1] = true;
-      break;
-    }
+
+  m_HighlightColor[static_cast<size_t>(fieldType)] = clr;
+  m_NeedsHighlight[static_cast<size_t>(fieldType)] = true;
+}
+
+void CPDFSDK_InterForm::SetAllHighlightColors(FX_COLORREF clr) {
+  for (auto type : kFormFieldTypes) {
+    m_HighlightColor[static_cast<size_t>(type)] = clr;
+    m_NeedsHighlight[static_cast<size_t>(type)] = true;
   }
 }
 
-FX_COLORREF CPDFSDK_InterForm::GetHighlightColor(int nFieldType) {
-  if (nFieldType < 0 || nFieldType > kNumFieldTypes)
+FX_COLORREF CPDFSDK_InterForm::GetHighlightColor(FormFieldType fieldType) {
+  if (fieldType == FormFieldType::kUnknown)
     return FXSYS_RGB(255, 255, 255);
-  if (nFieldType == 0)
-    return m_aHighlightColor[0];
-  return m_aHighlightColor[nFieldType - 1];
+
+  return m_HighlightColor[static_cast<size_t>(fieldType)];
 }
diff --git a/fpdfsdk/cpdfsdk_interform.h b/fpdfsdk/cpdfsdk_interform.h
index dc9ac64..ee960ff 100644
--- a/fpdfsdk/cpdfsdk_interform.h
+++ b/fpdfsdk/cpdfsdk_interform.h
@@ -93,12 +93,13 @@
       const std::vector<CPDF_FormField*>& fields,
       bool bIncludeOrExclude);
 
-  bool IsNeedHighLight(int nFieldType);
-  void RemoveAllHighLight();
-  void SetHighlightAlpha(uint8_t alpha) { m_iHighlightAlpha = alpha; }
-  uint8_t GetHighlightAlpha() { return m_iHighlightAlpha; }
-  void SetHighlightColor(FX_COLORREF clr, int nFieldType);
-  FX_COLORREF GetHighlightColor(int nFieldType);
+  bool IsNeedHighLight(FormFieldType fieldType);
+  void RemoveAllHighLights();
+  void SetHighlightAlpha(uint8_t alpha) { m_HighlightAlpha = alpha; }
+  uint8_t GetHighlightAlpha() { return m_HighlightAlpha; }
+  void SetHighlightColor(FX_COLORREF clr, FormFieldType fieldType);
+  void SetAllHighlightColors(FX_COLORREF clr);
+  FX_COLORREF GetHighlightColor(FormFieldType fieldType);
 
  private:
   // IPDF_FormNotify:
@@ -127,16 +128,13 @@
   std::map<CXFA_FFWidget*, CPDFSDK_XFAWidget*> m_XFAMap;
   bool m_bXfaCalculate;
   bool m_bXfaValidationsEnabled;
-  static const int kNumFieldTypes = 7;
-#else   // PDF_ENABLE_XFA
-  static const int kNumFieldTypes = 6;
 #endif  // PDF_ENABLE_XFA
   bool m_bCalculate;
   bool m_bBusy;
 
-  FX_COLORREF m_aHighlightColor[kNumFieldTypes];
-  uint8_t m_iHighlightAlpha;
-  bool m_bNeedHightlight[kNumFieldTypes];
+  uint8_t m_HighlightAlpha;
+  FX_COLORREF m_HighlightColor[kFormFieldTypeCount];
+  bool m_NeedsHighlight[kFormFieldTypeCount];
 };
 
 #endif  // FPDFSDK_CPDFSDK_INTERFORM_H_
diff --git a/fpdfsdk/cpdfsdk_widget.cpp b/fpdfsdk/cpdfsdk_widget.cpp
index eb42ba6..2adc46f 100644
--- a/fpdfsdk/cpdfsdk_widget.cpp
+++ b/fpdfsdk/cpdfsdk_widget.cpp
@@ -77,7 +77,7 @@
     if (!m_hMixXFAWidget) {
       if (CXFA_FFDocView* pDocView = pContext->GetXFADocView()) {
         WideString sName;
-        if (GetFieldType() == FIELDTYPE_RADIOBUTTON) {
+        if (GetFieldType() == FormFieldType::kRadioButton) {
           sName = GetAnnotName();
           if (sName.IsEmpty())
             sName = GetName();
@@ -206,7 +206,7 @@
   XFA_EVENTTYPE eEventType = GetXFAEventType(eXFAAAT);
 
   if ((eEventType == XFA_EVENT_Click || eEventType == XFA_EVENT_Change) &&
-      GetFieldType() == FIELDTYPE_RADIOBUTTON) {
+      GetFieldType() == FormFieldType::kRadioButton) {
     if (CXFA_FFWidget* hGroupWidget = GetGroupMixXFAWidget()) {
       if (pXFAWidgetHandler->HasEvent(hGroupWidget->GetNode()->GetWidgetAcc(),
                                       eEventType)) {
@@ -255,7 +255,7 @@
 
   param.m_wsPrevText = data.sValue;
   if ((eEventType == XFA_EVENT_Click || eEventType == XFA_EVENT_Change) &&
-      GetFieldType() == FIELDTYPE_RADIOBUTTON) {
+      GetFieldType() == FormFieldType::kRadioButton) {
     if (CXFA_FFWidget* hGroupWidget = GetGroupMixXFAWidget()) {
       CXFA_WidgetAcc* pAcc = hGroupWidget->GetNode()->GetWidgetAcc();
       param.m_pTarget = pAcc;
@@ -286,18 +286,18 @@
 
   CPDF_FormField* pFormField = GetFormField();
   switch (GetFieldType()) {
-    case FIELDTYPE_CHECKBOX:
-    case FIELDTYPE_RADIOBUTTON: {
+    case FormFieldType::kCheckBox:
+    case FormFieldType::kRadioButton: {
       CPDF_FormControl* pFormCtrl = GetFormControl();
       XFA_CHECKSTATE eCheckState =
           pFormCtrl->IsChecked() ? XFA_CHECKSTATE_On : XFA_CHECKSTATE_Off;
       pWidgetAcc->SetCheckState(eCheckState, true);
       break;
     }
-    case FIELDTYPE_TEXTFIELD:
+    case FormFieldType::kTextField:
       pWidgetAcc->SetValue(XFA_VALUEPICTURE_Edit, pFormField->GetValue());
       break;
-    case FIELDTYPE_LISTBOX: {
+    case FormFieldType::kListBox: {
       pWidgetAcc->ClearAllSelections();
 
       for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz; i++) {
@@ -307,7 +307,7 @@
       }
       break;
     }
-    case FIELDTYPE_COMBOBOX: {
+    case FormFieldType::kComboBox: {
       pWidgetAcc->ClearAllSelections();
 
       for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz; i++) {
@@ -318,6 +318,8 @@
       pWidgetAcc->SetValue(XFA_VALUEPICTURE_Edit, pFormField->GetValue());
       break;
     }
+    default:
+      break;
   }
 
   if (bSynchronizeElse) {
@@ -360,7 +362,7 @@
   ASSERT(pFormControl);
 
   switch (pFormField->GetFieldType()) {
-    case FIELDTYPE_CHECKBOX: {
+    case FormFieldType::kCheckBox: {
       if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetNode()->GetWidgetAcc()) {
         pFormField->CheckControl(
             pFormField->GetControlIndex(pFormControl),
@@ -368,7 +370,7 @@
       }
       break;
     }
-    case FIELDTYPE_RADIOBUTTON: {
+    case FormFieldType::kRadioButton: {
       // TODO(weili): Check whether we need to handle checkbox and radio
       // button differently, otherwise, merge these two cases.
       if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetNode()->GetWidgetAcc()) {
@@ -378,14 +380,14 @@
       }
       break;
     }
-    case FIELDTYPE_TEXTFIELD: {
+    case FormFieldType::kTextField: {
       if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetNode()->GetWidgetAcc()) {
         pFormField->SetValue(pWidgetAcc->GetValue(XFA_VALUEPICTURE_Display),
                              true);
       }
       break;
     }
-    case FIELDTYPE_LISTBOX: {
+    case FormFieldType::kListBox: {
       pFormField->ClearSelection(false);
 
       if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetNode()->GetWidgetAcc()) {
@@ -399,7 +401,7 @@
       }
       break;
     }
-    case FIELDTYPE_COMBOBOX: {
+    case FormFieldType::kComboBox: {
       pFormField->ClearSelection(false);
 
       if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetNode()->GetWidgetAcc()) {
@@ -415,6 +417,8 @@
       }
       break;
     }
+    default:
+      break;
   }
 }
 
@@ -425,7 +429,7 @@
   ASSERT(hWidget);
 
   switch (pFormField->GetFieldType()) {
-    case FIELDTYPE_LISTBOX: {
+    case FormFieldType::kListBox: {
       pFormField->ClearSelection(false);
       pFormField->ClearOptions(true);
 
@@ -438,7 +442,7 @@
       }
       break;
     }
-    case FIELDTYPE_COMBOBOX: {
+    case FormFieldType::kComboBox: {
       pFormField->ClearSelection(false);
       pFormField->ClearOptions(false);
 
@@ -453,6 +457,8 @@
       pFormField->SetValue(L"", true);
       break;
     }
+    default:
+      break;
   }
 }
 #endif  // PDF_ENABLE_XFA
@@ -476,27 +482,28 @@
   if (!psub)
     return false;
 
-  int nFieldType = GetFieldType();
-  switch (nFieldType) {
-    case FIELDTYPE_PUSHBUTTON:
-    case FIELDTYPE_COMBOBOX:
-    case FIELDTYPE_LISTBOX:
-    case FIELDTYPE_TEXTFIELD:
-    case FIELDTYPE_SIGNATURE:
+  FormFieldType fieldType = GetFieldType();
+  switch (fieldType) {
+    case FormFieldType::kPushButton:
+    case FormFieldType::kComboBox:
+    case FormFieldType::kListBox:
+    case FormFieldType::kTextField:
+    case FormFieldType::kSignature:
       return psub->IsStream();
-    case FIELDTYPE_CHECKBOX:
-    case FIELDTYPE_RADIOBUTTON:
+    case FormFieldType::kCheckBox:
+    case FormFieldType::kRadioButton:
       if (CPDF_Dictionary* pSubDict = psub->AsDictionary()) {
         return !!pSubDict->GetStreamFor(GetAppState());
       }
       return false;
+    default:
+      return true;
   }
-  return true;
 }
 
-int CPDFSDK_Widget::GetFieldType() const {
+FormFieldType CPDFSDK_Widget::GetFieldType() const {
   CPDF_FormField* pField = GetFormField();
-  return pField ? pField->GetFieldType() : FIELDTYPE_UNKNOWN;
+  return pField ? pField->GetFieldType() : FormFieldType::kUnknown;
 }
 
 bool CPDFSDK_Widget::IsAppearanceValid() {
@@ -522,7 +529,7 @@
 }
 
 bool CPDFSDK_Widget::IsSignatureWidget() const {
-  return GetFieldType() == FIELDTYPE_SIGNATURE;
+  return GetFieldType() == FormFieldType::kSignature;
 }
 
 CPDF_FormField* CPDFSDK_Widget::GetFormField() const {
@@ -733,8 +740,8 @@
 #ifdef PDF_ENABLE_XFA
 void CPDFSDK_Widget::ResetAppearance(bool bValueChanged) {
   switch (GetFieldType()) {
-    case FIELDTYPE_TEXTFIELD:
-    case FIELDTYPE_COMBOBOX: {
+    case FormFieldType::kTextField:
+    case FormFieldType::kComboBox: {
       bool bFormatted = false;
       WideString sValue = OnFormat(bFormatted);
       ResetAppearance(bFormatted ? &sValue : nullptr, true);
@@ -757,24 +764,26 @@
 
   CPWL_AppStream appStream(this, GetAPDict());
   switch (GetFieldType()) {
-    case FIELDTYPE_PUSHBUTTON:
+    case FormFieldType::kPushButton:
       appStream.SetAsPushButton();
       break;
-    case FIELDTYPE_CHECKBOX:
+    case FormFieldType::kCheckBox:
       appStream.SetAsCheckBox();
       break;
-    case FIELDTYPE_RADIOBUTTON:
+    case FormFieldType::kRadioButton:
       appStream.SetAsRadioButton();
       break;
-    case FIELDTYPE_COMBOBOX:
+    case FormFieldType::kComboBox:
       appStream.SetAsComboBox(sValue);
       break;
-    case FIELDTYPE_LISTBOX:
+    case FormFieldType::kListBox:
       appStream.SetAsListBox();
       break;
-    case FIELDTYPE_TEXTFIELD:
+    case FormFieldType::kTextField:
       appStream.SetAsTextField(sValue);
       break;
+    default:
+      break;
   }
 
   m_pAnnot->ClearCachedAP();
@@ -796,10 +805,10 @@
                                     const CFX_Matrix& mtUser2Device,
                                     CPDF_Annot::AppearanceMode mode,
                                     const CPDF_RenderOptions* pOptions) {
-  int nFieldType = GetFieldType();
+  FormFieldType fieldType = GetFieldType();
 
-  if ((nFieldType == FIELDTYPE_CHECKBOX ||
-       nFieldType == FIELDTYPE_RADIOBUTTON) &&
+  if ((fieldType == FormFieldType::kCheckBox ||
+       fieldType == FormFieldType::kRadioButton) &&
       mode == CPDF_Annot::Normal &&
       !IsWidgetAppearanceValid(CPDF_Annot::Normal)) {
     CFX_PathData pathData;
@@ -827,8 +836,8 @@
 
 void CPDFSDK_Widget::DrawShadow(CFX_RenderDevice* pDevice,
                                 CPDFSDK_PageView* pPageView) {
-  int nFieldType = GetFieldType();
-  if (!m_pInterForm->IsNeedHighLight(nFieldType))
+  FormFieldType fieldType = GetFieldType();
+  if (!m_pInterForm->IsNeedHighLight(fieldType))
     return;
 
   CFX_Matrix page2device;
@@ -848,7 +857,7 @@
   FX_RECT rcDev = rcDevice.ToFxRect();
   pDevice->FillRect(
       &rcDev, ArgbEncode(static_cast<int>(m_pInterForm->GetHighlightAlpha()),
-                         m_pInterForm->GetHighlightColor(nFieldType)));
+                         m_pInterForm->GetHighlightColor(fieldType)));
 }
 
 CFX_FloatRect CPDFSDK_Widget::GetClientRect() const {
diff --git a/fpdfsdk/cpdfsdk_widget.h b/fpdfsdk/cpdfsdk_widget.h
index f57e08d..4b11150 100644
--- a/fpdfsdk/cpdfsdk_widget.h
+++ b/fpdfsdk/cpdfsdk_widget.h
@@ -71,7 +71,7 @@
 
   int GetLayoutOrder() const override;
 
-  int GetFieldType() const;
+  FormFieldType GetFieldType() const;
   int GetFieldFlags() const;
   int GetRotate() const;
 
diff --git a/fpdfsdk/cpdfsdk_widgethandler.cpp b/fpdfsdk/cpdfsdk_widgethandler.cpp
index 3eb8e5d..dcce7b6 100644
--- a/fpdfsdk/cpdfsdk_widgethandler.cpp
+++ b/fpdfsdk/cpdfsdk_widgethandler.cpp
@@ -43,7 +43,7 @@
   if ((nFieldFlags & FIELDFLAG_READONLY) == FIELDFLAG_READONLY)
     return false;
 
-  if (pWidget->GetFieldType() == FIELDTYPE_PUSHBUTTON)
+  if (pWidget->GetFieldType() == FormFieldType::kPushButton)
     return true;
 
   CPDF_Page* pPage = pWidget->GetPDFPage();
@@ -227,15 +227,16 @@
   if (!pWidget->IsAppearanceValid())
     pWidget->ResetAppearance(nullptr, false);
 
-  int nFieldType = pWidget->GetFieldType();
-  if (nFieldType == FIELDTYPE_TEXTFIELD || nFieldType == FIELDTYPE_COMBOBOX) {
+  FormFieldType fieldType = pWidget->GetFieldType();
+  if (fieldType == FormFieldType::kTextField ||
+      fieldType == FormFieldType::kComboBox) {
     bool bFormatted = false;
     CPDFSDK_Annot::ObservedPtr pObserved(pWidget);
     WideString sValue = pWidget->OnFormat(bFormatted);
     if (!pObserved)
       return;
 
-    if (bFormatted && nFieldType == FIELDTYPE_COMBOBOX)
+    if (bFormatted && fieldType == FormFieldType::kComboBox)
       pWidget->ResetAppearance(&sValue, false);
   }
 
diff --git a/fpdfsdk/formfiller/cffl_formfiller.cpp b/fpdfsdk/formfiller/cffl_formfiller.cpp
index f86cb68..d3aa37e 100644
--- a/fpdfsdk/formfiller/cffl_formfiller.cpp
+++ b/fpdfsdk/formfiller/cffl_formfiller.cpp
@@ -268,9 +268,9 @@
 
   bool bDestroyPDFWindow;
   switch (m_pWidget->GetFieldType()) {
-    case FIELDTYPE_PUSHBUTTON:
-    case FIELDTYPE_CHECKBOX:
-    case FIELDTYPE_RADIOBUTTON:
+    case FormFieldType::kPushButton:
+    case FormFieldType::kCheckBox:
+    case FormFieldType::kRadioButton:
       bDestroyPDFWindow = true;
       break;
     default:
diff --git a/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp b/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp
index 703fc47..e74f902 100644
--- a/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp
+++ b/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp
@@ -228,9 +228,9 @@
 
   bool bSetFocus;
   switch (pWidget->GetFieldType()) {
-    case FIELDTYPE_PUSHBUTTON:
-    case FIELDTYPE_CHECKBOX:
-    case FIELDTYPE_RADIOBUTTON: {
+    case FormFieldType::kPushButton:
+    case FormFieldType::kCheckBox:
+    case FormFieldType::kRadioButton: {
       FX_RECT bbox = GetViewBBox(pPageView, pAnnot->Get());
       bSetFocus =
           bbox.Contains(static_cast<int>(point.x), static_cast<int>(point.y));
@@ -455,7 +455,7 @@
 }
 
 bool CFFL_InteractiveFormFiller::IsFillingAllowed(CPDFSDK_Widget* pWidget) {
-  if (pWidget->GetFieldType() == FIELDTYPE_PUSHBUTTON)
+  if (pWidget->GetFieldType() == FormFieldType::kPushButton)
     return false;
 
   CPDF_Page* pPage = pWidget->GetPDFPage();
@@ -477,28 +477,28 @@
 
   // TODO(thestig): How do we know |pAnnot| is a CPDFSDK_Widget?
   CPDFSDK_Widget* pWidget = static_cast<CPDFSDK_Widget*>(pAnnot);
-  int nFieldType = pWidget->GetFieldType();
+  FormFieldType fieldType = pWidget->GetFieldType();
   CFFL_FormFiller* pFormFiller;
-  switch (nFieldType) {
-    case FIELDTYPE_PUSHBUTTON:
+  switch (fieldType) {
+    case FormFieldType::kPushButton:
       pFormFiller = new CFFL_PushButton(m_pFormFillEnv.Get(), pWidget);
       break;
-    case FIELDTYPE_CHECKBOX:
+    case FormFieldType::kCheckBox:
       pFormFiller = new CFFL_CheckBox(m_pFormFillEnv.Get(), pWidget);
       break;
-    case FIELDTYPE_RADIOBUTTON:
+    case FormFieldType::kRadioButton:
       pFormFiller = new CFFL_RadioButton(m_pFormFillEnv.Get(), pWidget);
       break;
-    case FIELDTYPE_TEXTFIELD:
+    case FormFieldType::kTextField:
       pFormFiller = new CFFL_TextField(m_pFormFillEnv.Get(), pWidget);
       break;
-    case FIELDTYPE_LISTBOX:
+    case FormFieldType::kListBox:
       pFormFiller = new CFFL_ListBox(m_pFormFillEnv.Get(), pWidget);
       break;
-    case FIELDTYPE_COMBOBOX:
+    case FormFieldType::kComboBox:
       pFormFiller = new CFFL_ComboBox(m_pFormFillEnv.Get(), pWidget);
       break;
-    case FIELDTYPE_UNKNOWN:
+    case FormFieldType::kUnknown:
     default:
       pFormFiller = nullptr;
       break;
diff --git a/fpdfsdk/fpdfformfill.cpp b/fpdfsdk/fpdfformfill.cpp
index 3d61336..cc2861f 100644
--- a/fpdfsdk/fpdfformfill.cpp
+++ b/fpdfsdk/fpdfformfill.cpp
@@ -44,6 +44,37 @@
               "XFA foreground form types must match");
 #endif  // PDF_ENABLE_XFA
 
+static_assert(static_cast<int>(FormFieldType::kUnknown) ==
+                  FPDF_FORMFIELD_UNKNOWN,
+              "Unknown form field types must match");
+static_assert(static_cast<int>(FormFieldType::kPushButton) ==
+                  FPDF_FORMFIELD_PUSHBUTTON,
+              "PushButton form field types must match");
+static_assert(static_cast<int>(FormFieldType::kCheckBox) ==
+                  FPDF_FORMFIELD_CHECKBOX,
+              "CheckBox form field types must match");
+static_assert(static_cast<int>(FormFieldType::kRadioButton) ==
+                  FPDF_FORMFIELD_RADIOBUTTON,
+              "RadioButton form field types must match");
+static_assert(static_cast<int>(FormFieldType::kComboBox) ==
+                  FPDF_FORMFIELD_COMBOBOX,
+              "ComboBox form field types must match");
+static_assert(static_cast<int>(FormFieldType::kListBox) ==
+                  FPDF_FORMFIELD_LISTBOX,
+              "ListBox form field types must match");
+static_assert(static_cast<int>(FormFieldType::kTextField) ==
+                  FPDF_FORMFIELD_TEXTFIELD,
+              "TextField form field types must match");
+static_assert(static_cast<int>(FormFieldType::kSignature) ==
+                  FPDF_FORMFIELD_SIGNATURE,
+              "Signature form field types must match");
+#ifdef PDF_ENABLE_XFA
+static_assert(static_cast<int>(FormFieldType::kXFA) == FPDF_FORMFIELD_XFA,
+              "XFA form field types must match");
+#endif  // PDF_ENABLE_XFA
+static_assert(kFormFieldTypeCount == FPDF_FORMFIELD_COUNT,
+              "Number of form field types must match");
+
 namespace {
 
 CPDFSDK_FormFillEnvironment* HandleToCPDFSDKEnvironment(
@@ -173,7 +204,7 @@
     if (!pFormCtrl)
       return -1;
     CPDF_FormField* pFormField = pFormCtrl->GetField();
-    return pFormField ? pFormField->GetFieldType() : -1;
+    return pFormField ? static_cast<int>(pFormField->GetFieldType()) : -1;
   }
 
 #ifdef PDF_ENABLE_XFA
@@ -199,17 +230,16 @@
   if (!pWidgetIterator)
     return -1;
 
-  CXFA_FFWidget* pXFAAnnot = pWidgetIterator->MoveToNext();
-  while (pXFAAnnot) {
+  CXFA_FFWidget* pXFAAnnot;
+  while ((pXFAAnnot = pWidgetIterator->MoveToNext()) != nullptr) {
     CFX_RectF rcBBox = pXFAAnnot->GetBBox(0);
     CFX_FloatRect rcWidget(rcBBox.left, rcBBox.top, rcBBox.left + rcBBox.width,
                            rcBBox.top + rcBBox.height);
     rcWidget.Inflate(1.0f, 1.0f);
     if (rcWidget.Contains(CFX_PointF(static_cast<float>(page_x),
                                      static_cast<float>(page_y)))) {
-      return FPDF_FORMFIELD_XFA;
+      return static_cast<int>(FormFieldType::kXFA);
     }
-    pXFAAnnot = pWidgetIterator->MoveToNext();
   }
 #endif  // PDF_ENABLE_XFA
   return -1;
@@ -663,8 +693,19 @@
 FPDF_SetFormFieldHighlightColor(FPDF_FORMHANDLE hHandle,
                                 int fieldType,
                                 unsigned long color) {
-  if (CPDFSDK_InterForm* pInterForm = FormHandleToInterForm(hHandle))
-    pInterForm->SetHighlightColor(color, fieldType);
+  CPDFSDK_InterForm* interForm = FormHandleToInterForm(hHandle);
+  if (!interForm)
+    return;
+
+  Optional<FormFieldType> cast_input = IntToFormFieldType(fieldType);
+  if (!cast_input.has_value())
+    return;
+
+  if (cast_input.value() == FormFieldType::kUnknown) {
+    interForm->SetAllHighlightColors(color);
+  } else {
+    interForm->SetHighlightColor(color, cast_input.value());
+  }
 }
 
 FPDF_EXPORT void FPDF_CALLCONV
@@ -676,7 +717,7 @@
 FPDF_EXPORT void FPDF_CALLCONV
 FPDF_RemoveFormFieldHighlight(FPDF_FORMHANDLE hHandle) {
   if (CPDFSDK_InterForm* pInterForm = FormHandleToInterForm(hHandle))
-    pInterForm->RemoveAllHighLight();
+    pInterForm->RemoveAllHighLights();
 }
 
 FPDF_EXPORT void FPDF_CALLCONV FORM_OnAfterLoadPage(FPDF_PAGE page,
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp
index 93f5912..4ebe8f9 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp
@@ -598,7 +598,7 @@
     return 0;
 
   return ArgbEncode(pInterForm->GetHighlightAlpha(),
-                    pInterForm->GetHighlightColor(FPDF_FORMFIELD_XFA));
+                    pInterForm->GetHighlightColor(FormFieldType::kXFA));
 }
 
 bool CPDFXFA_DocEnvironment::NotifySubmit(bool bPrevOrPost) {