Make FPDF_FormHandle be represented as an incomplete type.

Make consistent with other public API types.

Introduce CPDFSDKFormFillEnvironmentFromFPDFFormHandle() and
FPDFFormHandleFromCPDFSDKFormFillEnvironment() helper functions.
Use these to kill off some casts in the process.

Change-Id: I6230ecdb4cecd03076f5e24c8cc49c45ad694da7
Reviewed-on: https://pdfium-review.googlesource.com/39250
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/fpdfsdk/cpdfsdk_annotiterator_embeddertest.cpp b/fpdfsdk/cpdfsdk_annotiterator_embeddertest.cpp
index 879a365..161ae95 100644
--- a/fpdfsdk/cpdfsdk_annotiterator_embeddertest.cpp
+++ b/fpdfsdk/cpdfsdk_annotiterator_embeddertest.cpp
@@ -40,7 +40,7 @@
   CFX_FloatRect RightTop(401, 401, 421, 421);
 
   CPDFSDK_FormFillEnvironment* pFormFillEnv =
-      static_cast<CPDFSDK_FormFillEnvironment*>(form_handle());
+      CPDFSDKFormFillEnvironmentFromFPDFFormHandle(form_handle());
 
   {
     // Page 0 specifies "row order".
diff --git a/fpdfsdk/cpdfsdk_helpers.h b/fpdfsdk/cpdfsdk_helpers.h
index 4fd85cf..5de947a 100644
--- a/fpdfsdk/cpdfsdk_helpers.h
+++ b/fpdfsdk/cpdfsdk_helpers.h
@@ -38,6 +38,7 @@
 class CPDF_StructTree;
 class CPDF_TextPage;
 class CPDF_TextPageFind;
+class CPDFSDK_FormFillEnvironment;
 class IPDFSDK_PauseAdapter;
 class FX_PATHPOINT;
 
@@ -197,6 +198,15 @@
   return reinterpret_cast<CPDF_TextPageFind*>(handle);
 }
 
+inline FPDF_FORMHANDLE FPDFFormHandleFromCPDFSDKFormFillEnvironment(
+    CPDFSDK_FormFillEnvironment* handle) {
+  return reinterpret_cast<FPDF_FORMHANDLE>(handle);
+}
+inline CPDFSDK_FormFillEnvironment*
+CPDFSDKFormFillEnvironmentFromFPDFFormHandle(FPDF_FORMHANDLE handle) {
+  return reinterpret_cast<CPDFSDK_FormFillEnvironment*>(handle);
+}
+
 ByteString CFXByteStringFromFPDFWideString(FPDF_WIDESTRING wide_string);
 
 #ifdef PDF_ENABLE_XFA
diff --git a/fpdfsdk/fpdf_formfill.cpp b/fpdfsdk/fpdf_formfill.cpp
index d529a5b..3a74bc3 100644
--- a/fpdfsdk/fpdf_formfill.cpp
+++ b/fpdfsdk/fpdf_formfill.cpp
@@ -143,14 +143,9 @@
 
 namespace {
 
-CPDFSDK_FormFillEnvironment* HandleToCPDFSDKEnvironment(
-    FPDF_FORMHANDLE handle) {
-  return static_cast<CPDFSDK_FormFillEnvironment*>(handle);
-}
-
 CPDFSDK_InterForm* FormHandleToInterForm(FPDF_FORMHANDLE hHandle) {
   CPDFSDK_FormFillEnvironment* pFormFillEnv =
-      HandleToCPDFSDKEnvironment(hHandle);
+      CPDFSDKFormFillEnvironmentFromFPDFFormHandle(hHandle);
   return pFormFillEnv ? pFormFillEnv->GetInterForm() : nullptr;
 }
 
@@ -161,7 +156,7 @@
     return nullptr;
 
   CPDFSDK_FormFillEnvironment* pFormFillEnv =
-      HandleToCPDFSDKEnvironment(hHandle);
+      CPDFSDKFormFillEnvironmentFromFPDFFormHandle(hHandle);
   return pFormFillEnv ? pFormFillEnv->GetPageView(pPage, true) : nullptr;
 }
 
@@ -326,8 +321,10 @@
   // this and can just return the old Env. Otherwise, we'll end up setting a new
   // environment into the XFADocument and, that could get weird.
   auto* pContext = static_cast<CPDFXFA_Context*>(pDocument->GetExtension());
-  if (pContext && pContext->GetFormFillEnv())
-    return pContext->GetFormFillEnv();
+  if (pContext && pContext->GetFormFillEnv()) {
+    return FPDFFormHandleFromCPDFSDKFormFillEnvironment(
+        pContext->GetFormFillEnv());
+  }
 #endif
 
   auto pFormFillEnv = pdfium::MakeUnique<CPDFSDK_FormFillEnvironment>(
@@ -338,13 +335,14 @@
     pContext->SetFormFillEnv(pFormFillEnv.get());
 #endif  // PDF_ENABLE_XFA
 
-  return pFormFillEnv.release();  // Caller takes ownership.
+  return FPDFFormHandleFromCPDFSDKFormFillEnvironment(
+      pFormFillEnv.release());  // Caller takes ownership.
 }
 
 FPDF_EXPORT void FPDF_CALLCONV
 FPDFDOC_ExitFormFillEnvironment(FPDF_FORMHANDLE hHandle) {
   CPDFSDK_FormFillEnvironment* pFormFillEnv =
-      HandleToCPDFSDKEnvironment(hHandle);
+      CPDFSDKFormFillEnvironmentFromFPDFFormHandle(hHandle);
   if (!pFormFillEnv)
     return;
 
@@ -363,7 +361,7 @@
 FPDF_EXPORT void FPDF_CALLCONV FORM_SetSaveCallback(FPDF_FORMHANDLE hHandle,
                                                     FORM_SAVECALLED callback) {
   CPDFSDK_FormFillEnvironment* pFormFillEnv =
-      HandleToCPDFSDKEnvironment(hHandle);
+      CPDFSDKFormFillEnvironmentFromFPDFFormHandle(hHandle);
   if (!pFormFillEnv)
     return;
 
@@ -558,7 +556,7 @@
 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
 FORM_ForceToKillFocus(FPDF_FORMHANDLE hHandle) {
   CPDFSDK_FormFillEnvironment* pFormFillEnv =
-      HandleToCPDFSDKEnvironment(hHandle);
+      CPDFSDKFormFillEnvironmentFromFPDFFormHandle(hHandle);
   if (!pFormFillEnv)
     return false;
   return pFormFillEnv->KillFocusAnnot(0);
@@ -632,7 +630,7 @@
 FPDF_EXPORT void FPDF_CALLCONV FORM_OnBeforeClosePage(FPDF_PAGE page,
                                                       FPDF_FORMHANDLE hHandle) {
   CPDFSDK_FormFillEnvironment* pFormFillEnv =
-      HandleToCPDFSDKEnvironment(hHandle);
+      CPDFSDKFormFillEnvironmentFromFPDFFormHandle(hHandle);
   if (!pFormFillEnv)
     return;
 
@@ -651,7 +649,7 @@
 FPDF_EXPORT void FPDF_CALLCONV
 FORM_DoDocumentJSAction(FPDF_FORMHANDLE hHandle) {
   CPDFSDK_FormFillEnvironment* pFormFillEnv =
-      HandleToCPDFSDKEnvironment(hHandle);
+      CPDFSDKFormFillEnvironmentFromFPDFFormHandle(hHandle);
   if (pFormFillEnv && pFormFillEnv->IsJSPlatformPresent())
     pFormFillEnv->ProcJavascriptFun();
 }
@@ -659,7 +657,7 @@
 FPDF_EXPORT void FPDF_CALLCONV
 FORM_DoDocumentOpenAction(FPDF_FORMHANDLE hHandle) {
   CPDFSDK_FormFillEnvironment* pFormFillEnv =
-      HandleToCPDFSDKEnvironment(hHandle);
+      CPDFSDKFormFillEnvironmentFromFPDFFormHandle(hHandle);
   if (pFormFillEnv && pFormFillEnv->IsJSPlatformPresent())
     pFormFillEnv->ProcOpenAction();
 }
@@ -667,7 +665,7 @@
 FPDF_EXPORT void FPDF_CALLCONV FORM_DoDocumentAAction(FPDF_FORMHANDLE hHandle,
                                                       int aaType) {
   CPDFSDK_FormFillEnvironment* pFormFillEnv =
-      HandleToCPDFSDKEnvironment(hHandle);
+      CPDFSDKFormFillEnvironmentFromFPDFFormHandle(hHandle);
   if (!pFormFillEnv)
     return;
 
@@ -681,7 +679,8 @@
   if (aa.ActionExist(type)) {
     CPDF_Action action = aa.GetAction(type);
     CPDFSDK_ActionHandler* pActionHandler =
-        HandleToCPDFSDKEnvironment(hHandle)->GetActionHandler();
+        CPDFSDKFormFillEnvironmentFromFPDFFormHandle(hHandle)
+            ->GetActionHandler();
     pActionHandler->DoAction_Document(action, type, pFormFillEnv);
   }
 }
@@ -690,7 +689,7 @@
                                                   FPDF_FORMHANDLE hHandle,
                                                   int aaType) {
   CPDFSDK_FormFillEnvironment* pFormFillEnv =
-      HandleToCPDFSDKEnvironment(hHandle);
+      CPDFSDKFormFillEnvironmentFromFPDFFormHandle(hHandle);
   if (!pFormFillEnv)
     return;
 
diff --git a/fpdfsdk/pwl/cpwl_combo_box_embeddertest.cpp b/fpdfsdk/pwl/cpwl_combo_box_embeddertest.cpp
index e4b329e..62d42f9 100644
--- a/fpdfsdk/pwl/cpwl_combo_box_embeddertest.cpp
+++ b/fpdfsdk/pwl/cpwl_combo_box_embeddertest.cpp
@@ -29,7 +29,8 @@
     m_page = LoadPage(0);
     ASSERT_TRUE(m_page);
 
-    m_pFormFillEnv = static_cast<CPDFSDK_FormFillEnvironment*>(form_handle());
+    m_pFormFillEnv =
+        CPDFSDKFormFillEnvironmentFromFPDFFormHandle(form_handle());
     CPDFSDK_AnnotIterator iter(m_pFormFillEnv->GetPageView(0),
                                CPDF_Annot::Subtype::WIDGET);
 
diff --git a/fpdfsdk/pwl/cpwl_edit_embeddertest.cpp b/fpdfsdk/pwl/cpwl_edit_embeddertest.cpp
index 43d06d3..3edbf75 100644
--- a/fpdfsdk/pwl/cpwl_edit_embeddertest.cpp
+++ b/fpdfsdk/pwl/cpwl_edit_embeddertest.cpp
@@ -28,7 +28,8 @@
     m_page = LoadPage(0);
     ASSERT_TRUE(m_page);
 
-    m_pFormFillEnv = static_cast<CPDFSDK_FormFillEnvironment*>(form_handle());
+    m_pFormFillEnv =
+        CPDFSDKFormFillEnvironmentFromFPDFFormHandle(form_handle());
     CPDFSDK_AnnotIterator iter(m_pFormFillEnv->GetPageView(0),
                                CPDF_Annot::Subtype::WIDGET);
     // Normal text field.
diff --git a/fxjs/cjs_publicmethods_embeddertest.cpp b/fxjs/cjs_publicmethods_embeddertest.cpp
index 3860455..623ce68 100644
--- a/fxjs/cjs_publicmethods_embeddertest.cpp
+++ b/fxjs/cjs_publicmethods_embeddertest.cpp
@@ -180,7 +180,8 @@
   auto* page = LoadPage(0);
   ASSERT_TRUE(page);
 
-  CJS_Runtime runtime(static_cast<CPDFSDK_FormFillEnvironment*>(form_handle()));
+  CJS_Runtime runtime(
+      CPDFSDKFormFillEnvironmentFromFPDFFormHandle(form_handle()));
   runtime.NewEventContext();
 
   WideString result;
@@ -214,7 +215,8 @@
   auto* page = LoadPage(0);
   ASSERT_TRUE(page);
 
-  CJS_Runtime runtime(static_cast<CPDFSDK_FormFillEnvironment*>(form_handle()));
+  CJS_Runtime runtime(
+      CPDFSDKFormFillEnvironmentFromFPDFFormHandle(form_handle()));
   runtime.NewEventContext();
 
   auto* handler = runtime.GetCurrentEventContext()->GetEventHandler();
diff --git a/public/fpdf_formfill.h b/public/fpdf_formfill.h
index 4a703d9..3381eed 100644
--- a/public/fpdf_formfill.h
+++ b/public/fpdf_formfill.h
@@ -10,8 +10,6 @@
 // NOLINTNEXTLINE(build/include)
 #include "fpdfview.h"
 
-typedef void* FPDF_FORMHANDLE;
-
 // These values are return values for a public API, so should not be changed
 // other than the count when adding new values.
 #define FORMTYPE_NONE 0            // Document contains no forms
diff --git a/public/fpdfview.h b/public/fpdfview.h
index a35e34a..ac109b9 100644
--- a/public/fpdfview.h
+++ b/public/fpdfview.h
@@ -44,6 +44,7 @@
 typedef const struct fpdf_dest_t__* FPDF_DEST;
 typedef struct fpdf_document_t__* FPDF_DOCUMENT;
 typedef struct fpdf_font_t__* FPDF_FONT;
+typedef struct fpdf_form_handle_t__* FPDF_FORMHANDLE;
 typedef struct fpdf_link_t__* FPDF_LINK;
 typedef struct fpdf_page_t__* FPDF_PAGE;
 typedef struct fpdf_pagelink_t__* FPDF_PAGELINK;