Merge to XFA: Add new public APIs to find the z-order for links and widgets.

- Implement FPDFLink_GetLinkZOrderAtPoint().
- Implement FPDFPage_FormFieldZOrderAtPoint().
- Mark FPDPage_HasFormFieldAtPoint() as deprecated.
- Modify CPDF_LinkList and CPDF_InterForm to support new APIs.
- Clean up dead code in CPDF_LinkList and CPDF_InterForm.

BUG=chromium:515837
R=jun_fang@foxitsoftware.com, tsepez@chromium.org

Review URL: https://codereview.chromium.org/1278053004 .

(cherry picked from commit 24fbf134d43a7ec4226de3db601f0a617bbe428b)

Review URL: https://codereview.chromium.org/1295893005 .
diff --git a/fpdfsdk/src/fpdfdoc.cpp b/fpdfsdk/src/fpdfdoc.cpp
index 0006094..47225dd 100644
--- a/fpdfsdk/src/fpdfdoc.cpp
+++ b/fpdfsdk/src/fpdfdoc.cpp
@@ -9,11 +9,13 @@
 #include "../include/fpdfxfa/fpdfxfa_doc.h"
 #include "../include/fpdfxfa/fpdfxfa_page.h"
 
-static int THISMODULE = 0;
+namespace {
 
-static CPDF_Bookmark FindBookmark(const CPDF_BookmarkTree& tree,
-                                  CPDF_Bookmark bookmark,
-                                  const CFX_WideString& title) {
+int THISMODULE = 0;
+
+CPDF_Bookmark FindBookmark(const CPDF_BookmarkTree& tree,
+                           CPDF_Bookmark bookmark,
+                           const CFX_WideString& title) {
   if (bookmark && bookmark.GetTitle().CompareNoCase(title.c_str()) == 0) {
     // First check this item
     return bookmark;
@@ -30,6 +32,26 @@
   return CPDF_Bookmark();
 }
 
+void ReleaseLinkList(void* data) {
+  delete (CPDF_LinkList*)data;
+}
+
+CPDF_LinkList* GetLinkList(CPDF_Page* page) {
+  if (!page)
+    return nullptr;
+
+  // Link list is stored with the document
+  CPDF_Document* pDoc = page->m_pDocument;
+  CPDF_LinkList* pLinkList = (CPDF_LinkList*)pDoc->GetPrivateData(&THISMODULE);
+  if (!pLinkList) {
+    pLinkList = new CPDF_LinkList;
+    pDoc->SetPrivateData(&THISMODULE, pLinkList, ReleaseLinkList);
+  }
+  return pLinkList;
+}
+
+}  // namespace
+
 DLLEXPORT FPDF_BOOKMARK STDCALL
 FPDFBookmark_GetFirstChild(FPDF_DOCUMENT document, FPDF_BOOKMARK pDict) {
   if (!document || !pDict)
@@ -163,26 +185,35 @@
   return dest.GetPageIndex(pDoc);
 }
 
-static void ReleaseLinkList(void* data) {
-  delete (CPDF_LinkList*)data;
+DLLEXPORT FPDF_LINK STDCALL
+FPDFLink_GetLinkAtPoint(FPDF_PAGE page, double x, double y) {
+  CPDFXFA_Page* pXFAPage = (CPDFXFA_Page*)page;
+  CPDF_Page* pPage = pXFAPage->GetPDFPage();
+  if (!pPage)
+    return nullptr;
+
+  CPDF_LinkList* pLinkList = GetLinkList(pPage);
+  if (!pLinkList)
+    return nullptr;
+
+  return pLinkList->GetLinkAtPoint(pPage, (FX_FLOAT)x, (FX_FLOAT)y, nullptr)
+      .GetDict();
 }
 
-DLLEXPORT FPDF_LINK STDCALL FPDFLink_GetLinkAtPoint(FPDF_PAGE page,
-                                                    double x,
-                                                    double y) {
-  if (!page)
-    return NULL;
-  CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
+DLLEXPORT int STDCALL
+FPDFLink_GetLinkZOrderAtPoint(FPDF_PAGE page, double x, double y) {
+  CPDFXFA_Page* pXFAPage = (CPDFXFA_Page*)page;
+  CPDF_Page* pPage = pXFAPage->GetPDFPage();
   if (!pPage)
-    return NULL;
-  // Link list is stored with the document
-  CPDF_Document* pDoc = pPage->m_pDocument;
-  CPDF_LinkList* pLinkList = (CPDF_LinkList*)pDoc->GetPrivateData(&THISMODULE);
-  if (!pLinkList) {
-    pLinkList = new CPDF_LinkList(pDoc);
-    pDoc->SetPrivateData(&THISMODULE, pLinkList, ReleaseLinkList);
-  }
-  return pLinkList->GetLinkAtPoint(pPage, (FX_FLOAT)x, (FX_FLOAT)y).GetDict();
+    return -1;
+
+  CPDF_LinkList* pLinkList = GetLinkList(pPage);
+  if (!pLinkList)
+    return -1;
+
+  int z_order = -1;
+  pLinkList->GetLinkAtPoint(pPage, (FX_FLOAT)x, (FX_FLOAT)y, &z_order);
+  return z_order;
 }
 
 DLLEXPORT FPDF_DEST STDCALL FPDFLink_GetDest(FPDF_DOCUMENT document,
diff --git a/fpdfsdk/src/fpdfformfill.cpp b/fpdfsdk/src/fpdfformfill.cpp
index abb8026..51d90b7 100644
--- a/fpdfsdk/src/fpdfformfill.cpp
+++ b/fpdfsdk/src/fpdfformfill.cpp
@@ -37,32 +37,26 @@
 
 }  // namespace
 
-DLLEXPORT int STDCALL FPDPage_HasFormFieldAtPoint(FPDF_FORMHANDLE hHandle,
-                                                  FPDF_PAGE page,
-                                                  double page_x,
-                                                  double page_y) {
+DLLEXPORT int STDCALL FPDFPage_HasFormFieldAtPoint(FPDF_FORMHANDLE hHandle,
+                                                   FPDF_PAGE page,
+                                                   double page_x,
+                                                   double page_y) {
   if (!page || !hHandle)
     return -1;
+
   CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
   if (pPage) {
-    CPDF_InterForm* pInterForm = NULL;
-    pInterForm = new CPDF_InterForm(pPage->m_pDocument, FALSE);
-    if (!pInterForm)
+    CPDF_InterForm interform(pPage->m_pDocument, FALSE);
+    CPDF_FormControl* pFormCtrl = interform.GetControlAtPoint(
+        pPage, (FX_FLOAT)page_x, (FX_FLOAT)page_y, nullptr);
+    if (!pFormCtrl)
       return -1;
-    CPDF_FormControl* pFormCtrl = pInterForm->GetControlAtPoint(
-        pPage, (FX_FLOAT)page_x, (FX_FLOAT)page_y);
-    if (!pFormCtrl) {
-      delete pInterForm;
-      return -1;
-    }
+
     CPDF_FormField* pFormField = pFormCtrl->GetField();
-    if (!pFormField) {
-      delete pInterForm;
+    if (!pFormField)
       return -1;
-    }
 
     int nType = pFormField->GetFieldType();
-    delete pInterForm;
     return nType;
   }
 
@@ -109,6 +103,28 @@
   return -1;
 }
 
+DLLEXPORT int STDCALL FPDPage_HasFormFieldAtPoint(FPDF_FORMHANDLE hHandle,
+                                                  FPDF_PAGE page,
+                                                  double page_x,
+                                                  double page_y) {
+  return FPDFPage_HasFormFieldAtPoint(hHandle, page, page_x, page_y);
+}
+
+DLLEXPORT int STDCALL FPDFPage_FormFieldZOrderAtPoint(FPDF_FORMHANDLE hHandle,
+                                                      FPDF_PAGE page,
+                                                      double page_x,
+                                                      double page_y) {
+  if (!page || !hHandle)
+    return -1;
+
+  CPDF_Page* pPage = (CPDF_Page*)page;
+  CPDF_InterForm interform(pPage->m_pDocument, FALSE);
+  int z_order = -1;
+  (void)interform.GetControlAtPoint(pPage, (FX_FLOAT)page_x, (FX_FLOAT)page_y,
+                                    &z_order);
+  return z_order;
+}
+
 DLLEXPORT FPDF_FORMHANDLE STDCALL
 FPDFDOC_InitFormFillEnvironment(FPDF_DOCUMENT document,
                                 FPDF_FORMFILLINFO* formInfo) {
diff --git a/fpdfsdk/src/fpdfview_c_api_test.c b/fpdfsdk/src/fpdfview_c_api_test.c
index f96aec4..01789b4 100644
--- a/fpdfsdk/src/fpdfview_c_api_test.c
+++ b/fpdfsdk/src/fpdfview_c_api_test.c
@@ -54,6 +54,7 @@
     CHK(FPDFAction_GetURIPath);
     CHK(FPDFDest_GetPageIndex);
     CHK(FPDFLink_GetLinkAtPoint);
+    CHK(FPDFLink_GetLinkZOrderAtPoint);
     CHK(FPDFLink_GetDest);
     CHK(FPDFLink_GetAction);
     CHK(FPDFLink_Enumerate);
@@ -108,7 +109,9 @@
     CHK(FORM_OnKeyUp);
     CHK(FORM_OnChar);
     CHK(FORM_ForceToKillFocus);
-    CHK(FPDPage_HasFormFieldAtPoint);
+    CHK(FPDFPage_HasFormFieldAtPoint);
+    CHK(FPDPage_HasFormFieldAtPoint);  // DEPRECATED. Remove in the future.
+    CHK(FPDFPage_FormFieldZOrderAtPoint);
     CHK(FPDF_SetFormFieldHighlightColor);
     CHK(FPDF_SetFormFieldHighlightAlpha);
     CHK(FPDF_RemoveFormFieldHighlight);