Add tests for CBA_AnnotIterator.

I'm about to replace the sort() that underlies this class,
so I first want to be sure I don't disrupt the order.

R=thestig@chromium.org

Review URL: https://codereview.chromium.org/1652533002 .
diff --git a/BUILD.gn b/BUILD.gn
index 3539a95..c7b7b4a 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -759,6 +759,7 @@
     "fpdfsdk/src/fpdfview_c_api_test.c",
     "fpdfsdk/src/fpdfview_c_api_test.h",
     "fpdfsdk/src/fpdfview_embeddertest.cpp",
+    "fpdfsdk/src/fsdk_baseform_embeddertest.cpp",
     "testing/embedder_test.cpp",
     "testing/embedder_test.h",
     "testing/embedder_test_mock_delegate.h",
diff --git a/fpdfsdk/include/fsdk_mgr.h b/fpdfsdk/include/fsdk_mgr.h
index a314be8..4b07cc3 100644
--- a/fpdfsdk/include/fsdk_mgr.h
+++ b/fpdfsdk/include/fsdk_mgr.h
@@ -228,6 +228,8 @@
 
 class CPDFSDK_Document {
  public:
+  static CPDFSDK_Document* FromFPDFFormHandle(FPDF_FORMHANDLE hHandle);
+
   CPDFSDK_Document(UnderlyingDocumentType* pDoc, CPDFDoc_Environment* pEnv);
   ~CPDFSDK_Document();
 
diff --git a/fpdfsdk/src/fpdfformfill.cpp b/fpdfsdk/src/fpdfformfill.cpp
index d347397..9dc5b70 100644
--- a/fpdfsdk/src/fpdfformfill.cpp
+++ b/fpdfsdk/src/fpdfformfill.cpp
@@ -14,13 +14,8 @@
 
 namespace {
 
-CPDFSDK_Document* FormHandleToSDKDoc(FPDF_FORMHANDLE hHandle) {
-  CPDFDoc_Environment* pEnv = (CPDFDoc_Environment*)hHandle;
-  return pEnv ? pEnv->GetSDKDocument() : nullptr;
-}
-
 CPDFSDK_InterForm* FormHandleToInterForm(FPDF_FORMHANDLE hHandle) {
-  CPDFSDK_Document* pSDKDoc = FormHandleToSDKDoc(hHandle);
+  CPDFSDK_Document* pSDKDoc = CPDFSDK_Document::FromFPDFFormHandle(hHandle);
   return pSDKDoc ? pSDKDoc->GetInterForm() : nullptr;
 }
 
@@ -30,7 +25,7 @@
   if (!pPage)
     return nullptr;
 
-  CPDFSDK_Document* pSDKDoc = FormHandleToSDKDoc(hHandle);
+  CPDFSDK_Document* pSDKDoc = CPDFSDK_Document::FromFPDFFormHandle(hHandle);
   return pSDKDoc ? pSDKDoc->GetPageView(pPage, TRUE) : nullptr;
 }
 
@@ -180,7 +175,7 @@
 }
 
 DLLEXPORT FPDF_BOOL STDCALL FORM_ForceToKillFocus(FPDF_FORMHANDLE hHandle) {
-  CPDFSDK_Document* pSDKDoc = FormHandleToSDKDoc(hHandle);
+  CPDFSDK_Document* pSDKDoc = CPDFSDK_Document::FromFPDFFormHandle(hHandle);
   if (!pSDKDoc)
     return FALSE;
 
@@ -290,20 +285,20 @@
 }
 
 DLLEXPORT void STDCALL FORM_DoDocumentJSAction(FPDF_FORMHANDLE hHandle) {
-  CPDFSDK_Document* pSDKDoc = FormHandleToSDKDoc(hHandle);
+  CPDFSDK_Document* pSDKDoc = CPDFSDK_Document::FromFPDFFormHandle(hHandle);
   if (pSDKDoc && ((CPDFDoc_Environment*)hHandle)->IsJSInitiated())
     pSDKDoc->ProcJavascriptFun();
 }
 
 DLLEXPORT void STDCALL FORM_DoDocumentOpenAction(FPDF_FORMHANDLE hHandle) {
-  CPDFSDK_Document* pSDKDoc = FormHandleToSDKDoc(hHandle);
+  CPDFSDK_Document* pSDKDoc = CPDFSDK_Document::FromFPDFFormHandle(hHandle);
   if (pSDKDoc && ((CPDFDoc_Environment*)hHandle)->IsJSInitiated())
     pSDKDoc->ProcOpenAction();
 }
 
 DLLEXPORT void STDCALL FORM_DoDocumentAAction(FPDF_FORMHANDLE hHandle,
                                               int aaType) {
-  CPDFSDK_Document* pSDKDoc = FormHandleToSDKDoc(hHandle);
+  CPDFSDK_Document* pSDKDoc = CPDFSDK_Document::FromFPDFFormHandle(hHandle);
   if (!pSDKDoc)
     return;
 
diff --git a/fpdfsdk/src/fsdk_baseform_embeddertest.cpp b/fpdfsdk/src/fsdk_baseform_embeddertest.cpp
new file mode 100644
index 0000000..109b22f
--- /dev/null
+++ b/fpdfsdk/src/fsdk_baseform_embeddertest.cpp
@@ -0,0 +1,115 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "fpdfsdk/include/fsdk_baseform.h"
+#include "fpdfsdk/include/fsdk_define.h"
+#include "fpdfsdk/include/fsdk_mgr.h"
+#include "testing/embedder_test.h"
+#include "testing/embedder_test_mock_delegate.h"
+#include "testing/embedder_test_timer_handling_delegate.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+void CheckRect(const CPDF_Rect& actual, const CPDF_Rect& expected) {
+  EXPECT_EQ(expected.left, actual.left);
+  EXPECT_EQ(expected.bottom, actual.bottom);
+  EXPECT_EQ(expected.right, actual.right);
+  EXPECT_EQ(expected.top, actual.top);
+}
+
+}  // namespace
+
+class FSDKBaseFormEmbeddertest : public EmbedderTest {};
+
+TEST_F(FSDKBaseFormEmbeddertest, CBA_AnnotIterator) {
+  EXPECT_TRUE(OpenDocument("annotiter.pdf"));
+  EXPECT_TRUE(LoadPage(0));
+  EXPECT_TRUE(LoadPage(1));
+  EXPECT_TRUE(LoadPage(2));
+
+  CPDF_Rect LeftBottom(200, 200, 220, 220);
+  CPDF_Rect RightBottom(400, 201, 420, 221);
+  CPDF_Rect LeftTop(201, 400, 221, 420);
+  CPDF_Rect RightTop(401, 401, 421, 421);
+
+  CPDFSDK_Document* pSDKDoc =
+      CPDFSDK_Document::FromFPDFFormHandle(form_handle());
+  {
+    // Page 0 specifies "row order".
+    CBA_AnnotIterator iter(pSDKDoc->GetPageView(0), "Widget", "");
+    CPDFSDK_Annot* pAnnot = iter.GetFirstAnnot();
+    CheckRect(pAnnot->GetRect(), RightTop);
+    pAnnot = iter.GetNextAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), LeftTop);
+    pAnnot = iter.GetNextAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), RightBottom);
+    pAnnot = iter.GetNextAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), LeftBottom);
+    pAnnot = iter.GetNextAnnot(pAnnot);
+    EXPECT_EQ(iter.GetFirstAnnot(), pAnnot);
+
+    pAnnot = iter.GetLastAnnot();
+    CheckRect(pAnnot->GetRect(), LeftBottom);
+    pAnnot = iter.GetPrevAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), RightBottom);
+    pAnnot = iter.GetPrevAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), LeftTop);
+    pAnnot = iter.GetPrevAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), RightTop);
+    pAnnot = iter.GetPrevAnnot(pAnnot);
+    EXPECT_EQ(iter.GetLastAnnot(), pAnnot);
+  }
+  {
+    // Page 1 specifies "column order"
+    CBA_AnnotIterator iter(pSDKDoc->GetPageView(1), "Widget", "");
+    CPDFSDK_Annot* pAnnot = iter.GetFirstAnnot();
+    CheckRect(pAnnot->GetRect(), RightTop);
+    pAnnot = iter.GetNextAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), RightBottom);
+    pAnnot = iter.GetNextAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), LeftTop);
+    pAnnot = iter.GetNextAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), LeftBottom);
+    pAnnot = iter.GetNextAnnot(pAnnot);
+    EXPECT_EQ(iter.GetFirstAnnot(), pAnnot);
+
+    pAnnot = iter.GetLastAnnot();
+    CheckRect(pAnnot->GetRect(), LeftBottom);
+    pAnnot = iter.GetPrevAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), LeftTop);
+    pAnnot = iter.GetPrevAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), RightBottom);
+    pAnnot = iter.GetPrevAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), RightTop);
+    pAnnot = iter.GetPrevAnnot(pAnnot);
+    EXPECT_EQ(iter.GetLastAnnot(), pAnnot);
+  }
+  {
+    // Page 2 specifies "struct order"
+    CBA_AnnotIterator iter(pSDKDoc->GetPageView(2), "Widget", "");
+    CPDFSDK_Annot* pAnnot = iter.GetFirstAnnot();
+    CheckRect(pAnnot->GetRect(), LeftBottom);
+    pAnnot = iter.GetNextAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), RightTop);
+    pAnnot = iter.GetNextAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), LeftTop);
+    pAnnot = iter.GetNextAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), RightBottom);
+    pAnnot = iter.GetNextAnnot(pAnnot);
+    EXPECT_EQ(iter.GetFirstAnnot(), pAnnot);
+
+    pAnnot = iter.GetLastAnnot();
+    CheckRect(pAnnot->GetRect(), RightBottom);
+    pAnnot = iter.GetPrevAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), LeftTop);
+    pAnnot = iter.GetPrevAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), RightTop);
+    pAnnot = iter.GetPrevAnnot(pAnnot);
+    CheckRect(pAnnot->GetRect(), LeftBottom);
+    pAnnot = iter.GetPrevAnnot(pAnnot);
+    EXPECT_EQ(iter.GetLastAnnot(), pAnnot);
+  }
+}
diff --git a/fpdfsdk/src/fsdk_mgr.cpp b/fpdfsdk/src/fsdk_mgr.cpp
index 3299b8f..25783a8 100644
--- a/fpdfsdk/src/fsdk_mgr.cpp
+++ b/fpdfsdk/src/fsdk_mgr.cpp
@@ -378,6 +378,13 @@
   return m_pIFormFiller.get();
 }
 
+// static
+CPDFSDK_Document* CPDFSDK_Document::FromFPDFFormHandle(
+    FPDF_FORMHANDLE hHandle) {
+  CPDFDoc_Environment* pEnv = static_cast<CPDFDoc_Environment*>(hHandle);
+  return pEnv ? pEnv->GetSDKDocument() : nullptr;
+}
+
 CPDFSDK_Document::CPDFSDK_Document(UnderlyingDocumentType* pDoc,
                                    CPDFDoc_Environment* pEnv)
     : m_pDoc(pDoc),
diff --git a/pdfium.gyp b/pdfium.gyp
index bcde566..deb152f 100644
--- a/pdfium.gyp
+++ b/pdfium.gyp
@@ -752,6 +752,7 @@
         'fpdfsdk/src/fpdfview_c_api_test.c',
         'fpdfsdk/src/fpdfview_c_api_test.h',
         'fpdfsdk/src/fpdfview_embeddertest.cpp',
+        'fpdfsdk/src/fsdk_baseform_embeddertest.cpp',
         'testing/embedder_test.cpp',
         'testing/embedder_test.h',
         'testing/embedder_test_mock_delegate.h',
diff --git a/testing/resources/annotiter.in b/testing/resources/annotiter.in
new file mode 100644
index 0000000..4dc2a4e
--- /dev/null
+++ b/testing/resources/annotiter.in
@@ -0,0 +1,129 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm 20 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 3
+  /Kids [
+    10 0 R
+    11 0 R
+    12 0 R
+  ]
+>>
+endobj
+% Page number 0.
+{{object 10 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <</F1 15 0 R>>
+  >>
+  /MediaBox [0 0 612 792]
+  /Annots [
+    22 0 R
+    23 0 R
+    24 0 R
+    25 0 R
+  ]
+  /Tabs /R
+>>
+endobj
+% Page number 1.
+{{object 11 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <</F1 15 0 R>>
+  >>
+  /MediaBox [0 0 612 792]
+  /Annots [
+    22 0 R
+    23 0 R
+    24 0 R
+    25 0 R
+  ]
+  /Tabs /C
+>>
+endobj
+% Page number 2.
+{{object 12 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <</F1 15 0 R>>
+  >>
+  /MediaBox [0 0 612 792]
+  /Annots [
+    22 0 R
+    23 0 R
+    24 0 R
+    25 0 R
+  ]
+  /Tabs /S
+>>
+endobj
+% Forms
+{{object 20 0}} <<
+  /Fields [21 0 R]
+>>
+endobj
+% Fields
+{{object 21 0}} <<
+  /T (MyField)
+  /Type /Annot
+  /Subtype /Widget
+  /Rect [100 100 500 500]
+  /Kids [
+    22 0 R
+    23 0 R
+    24 0 R
+    25 0 R
+  ]
+>>
+endobj
+{{object 22 0}} <<
+  /FT /Tx
+  /Parent 5 0 R
+  /T (Sub_LeftBottom)
+  /Type /Annot
+  /Subtype /Widget
+  /Rect [200 200 220 220]
+>>
+endobj
+{{object 23 0}} <<
+  /FT /Tx
+  /Parent 5 0 R
+  /T (Sub_RightTop)
+  /Type /Annot
+  /Subtype /Widget
+  /Rect [401 401 421 421]
+>>
+endobj
+{{object 24 0}} <<
+  /FT /Tx
+  /Parent 5 0 R
+  /T (Sub_LeftTop)
+  /Type /Annot
+  /Subtype /Widget
+  /Rect [201 400 221 420]
+>>
+endobj
+{{object 25 0}} <<
+  /FT /Tx
+  /Parent 5 0 R
+  /T (Sub_RightBottom)
+  /Type /Annot
+  /Subtype /Widget
+  /Rect [400 201 420 221]
+>>
+endobj
+{{xref}}
+trailer <<
+  /Root 1 0 R
+>>
+{{startxref}}
+%%EOF
diff --git a/testing/resources/annotiter.pdf b/testing/resources/annotiter.pdf
new file mode 100644
index 0000000..2cb6d39
--- /dev/null
+++ b/testing/resources/annotiter.pdf
@@ -0,0 +1,158 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm 20 0 R
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /Count 3
+  /Kids [
+    10 0 R
+    11 0 R
+    12 0 R
+  ]
+>>
+endobj
+% Page number 0.
+10 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <</F1 15 0 R>>
+  >>
+  /MediaBox [0 0 612 792]
+  /Annots [
+    22 0 R
+    23 0 R
+    24 0 R
+    25 0 R
+  ]
+  /Tabs /R
+>>
+endobj
+% Page number 1.
+11 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <</F1 15 0 R>>
+  >>
+  /MediaBox [0 0 612 792]
+  /Annots [
+    22 0 R
+    23 0 R
+    24 0 R
+    25 0 R
+  ]
+  /Tabs /C
+>>
+endobj
+% Page number 2.
+12 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <</F1 15 0 R>>
+  >>
+  /MediaBox [0 0 612 792]
+  /Annots [
+    22 0 R
+    23 0 R
+    24 0 R
+    25 0 R
+  ]
+  /Tabs /S
+>>
+endobj
+% Forms
+20 0 obj <<
+  /Fields [21 0 R]
+>>
+endobj
+% Fields
+21 0 obj <<
+  /T (MyField)
+  /Type /Annot
+  /Subtype /Widget
+  /Rect [100 100 500 500]
+  /Kids [
+    22 0 R
+    23 0 R
+    24 0 R
+    25 0 R
+  ]
+>>
+endobj
+22 0 obj <<
+  /FT /Tx
+  /Parent 5 0 R
+  /T (Sub_LeftBottom)
+  /Type /Annot
+  /Subtype /Widget
+  /Rect [200 200 220 220]
+>>
+endobj
+23 0 obj <<
+  /FT /Tx
+  /Parent 5 0 R
+  /T (Sub_RightTop)
+  /Type /Annot
+  /Subtype /Widget
+  /Rect [401 401 421 421]
+>>
+endobj
+24 0 obj <<
+  /FT /Tx
+  /Parent 5 0 R
+  /T (Sub_LeftTop)
+  /Type /Annot
+  /Subtype /Widget
+  /Rect [201 400 221 420]
+>>
+endobj
+25 0 obj <<
+  /FT /Tx
+  /Parent 5 0 R
+  /T (Sub_RightBottom)
+  /Type /Annot
+  /Subtype /Widget
+  /Rect [400 201 420 221]
+>>
+endobj
+xref
+0 26
+0000000000 65535 f 
+0000000015 00000 n 
+0000000087 00000 n 
+0000000000 65535 f 
+0000000000 65535 f 
+0000000000 65535 f 
+0000000000 65535 f 
+0000000000 65535 f 
+0000000000 65535 f 
+0000000000 65535 f 
+0000000198 00000 n 
+0000000410 00000 n 
+0000000622 00000 n 
+0000000000 65535 f 
+0000000000 65535 f 
+0000000000 65535 f 
+0000000000 65535 f 
+0000000000 65535 f 
+0000000000 65535 f 
+0000000000 65535 f 
+0000000825 00000 n 
+0000000875 00000 n 
+0000001030 00000 n 
+0000001160 00000 n 
+0000001288 00000 n 
+0000001415 00000 n 
+trailer <<
+  /Root 1 0 R
+>>
+startxref
+1546
+%%EOF