Add a test case for FPDFText_GetCharBox() returning tall char box.

Illustrate the problem in the bug with small Type3 character glyphs.

Bug: pdfium:1591
Change-Id: Iee1eb2bf8566826e3f8fba3bb073949633b8fe9c
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/73771
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Hui Yingst <nigi@chromium.org>
diff --git a/fpdfsdk/fpdf_text_embeddertest.cpp b/fpdfsdk/fpdf_text_embeddertest.cpp
index 7e7160a..56b2b27 100644
--- a/fpdfsdk/fpdf_text_embeddertest.cpp
+++ b/fpdfsdk/fpdf_text_embeddertest.cpp
@@ -1604,3 +1604,60 @@
 
   UnloadPage(page);
 }
+
+TEST_F(FPDFTextEmbedderTest, SmallType3Glyph) {
+  ASSERT_TRUE(OpenDocument("bug_1591.pdf"));
+  FPDF_PAGE page = LoadPage(0);
+  ASSERT_TRUE(page);
+
+  {
+    ScopedFPDFTextPage text_page(FPDFText_LoadPage(page));
+    ASSERT_TRUE(text_page);
+    ASSERT_EQ(5, FPDFText_CountChars(text_page.get()));
+
+    EXPECT_EQ(49u, FPDFText_GetUnicode(text_page.get(), 0));
+    EXPECT_EQ(32u, FPDFText_GetUnicode(text_page.get(), 1));
+    EXPECT_EQ(50u, FPDFText_GetUnicode(text_page.get(), 2));
+    EXPECT_EQ(32u, FPDFText_GetUnicode(text_page.get(), 3));
+    EXPECT_EQ(49u, FPDFText_GetUnicode(text_page.get(), 4));
+
+    // Check the character box size.
+    double left;
+    double right;
+    double bottom;
+    double top;
+    ASSERT_TRUE(
+        FPDFText_GetCharBox(text_page.get(), 0, &left, &right, &bottom, &top));
+    EXPECT_DOUBLE_EQ(63.439998626708984, left);
+    EXPECT_DOUBLE_EQ(65.360000610351562, right);
+    EXPECT_DOUBLE_EQ(50.0, bottom);
+    EXPECT_DOUBLE_EQ(61.520000457763672, top);
+    ASSERT_TRUE(
+        FPDFText_GetCharBox(text_page.get(), 1, &left, &right, &bottom, &top));
+    EXPECT_DOUBLE_EQ(62.007999420166016, left);
+    EXPECT_DOUBLE_EQ(62.007999420166016, right);
+    EXPECT_DOUBLE_EQ(50.0, bottom);
+    EXPECT_DOUBLE_EQ(50.0, top);
+    ASSERT_TRUE(
+        FPDFText_GetCharBox(text_page.get(), 2, &left, &right, &bottom, &top));
+    EXPECT_DOUBLE_EQ(86.0, left);
+    EXPECT_DOUBLE_EQ(88.400001525878906, right);
+    EXPECT_DOUBLE_EQ(50.0, bottom);
+    // TODO(crbug.com/pdfium/1591): The top value is too big.
+    EXPECT_DOUBLE_EQ(290.0, top);
+    ASSERT_TRUE(
+        FPDFText_GetCharBox(text_page.get(), 3, &left, &right, &bottom, &top));
+    EXPECT_DOUBLE_EQ(86.010002136230469, left);
+    EXPECT_DOUBLE_EQ(86.010002136230469, right);
+    EXPECT_DOUBLE_EQ(50.0, bottom);
+    EXPECT_DOUBLE_EQ(50.0, top);
+    ASSERT_TRUE(
+        FPDFText_GetCharBox(text_page.get(), 4, &left, &right, &bottom, &top));
+    EXPECT_DOUBLE_EQ(99.44000244140625, left);
+    EXPECT_DOUBLE_EQ(101.36000061035156, right);
+    EXPECT_DOUBLE_EQ(50.0, bottom);
+    EXPECT_DOUBLE_EQ(61.520000457763672, top);
+  }
+
+  UnloadPage(page);
+}
diff --git a/testing/resources/bug_1591.in b/testing/resources/bug_1591.in
new file mode 100644
index 0000000..7632e13
--- /dev/null
+++ b/testing/resources/bug_1591.in
@@ -0,0 +1,106 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 4 0 R
+  /MediaBox [0 0 160 400]
+  /Resources <<
+    /ProcSet [/PDF /Text]
+    /Font <<
+      /F1 5 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+0 0 0 rg
+BT
+/F1 1 Tf
+240 0 0 240 50 50 Tm
+0.2 Tw
+0.05 0 Td
+(1) Tj
+0.1 0 Td
+(2) Tj
+0.05 0 Td
+(1) Tj
+ET
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /Font
+  /Subtype /Type3
+  /CharProcs 6 0 R
+  /Encoding 7 0 R
+  /FirstChar 49
+  /FontBBox [-1 -8 28 27]
+  /FontMatrix [0.001 0 0 0.001 0 0]
+  /LastChar 50
+  /Name /F1
+  /Resources <<
+    /ProcSet [/PDF /ImageB]
+  >>
+  /Widths [8 10]
+>>
+endobj
+{{object 6 0}} <<
+  /uniE022 8 0 R
+  /uniE023 9 0 R
+>>
+endobj
+{{object 7 0}} <<
+  /Type /Encoding
+  /Differences [49 /uniE022 /uniE023]
+>>
+endobj
+{{object 8 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+6 0 0 48 6 0 cm
+BI
+/W 6
+/H 48
+/BPC 1
+/IM true
+ID
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+EI
+Q
+endstream
+endobj
+{{object 9 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+BI
+/W 4
+/H 4
+/BPC 1
+/IM true
+ID
+xx
+EI
+Q
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/bug_1591.pdf b/testing/resources/bug_1591.pdf
new file mode 100644
index 0000000..3ec0a13
--- /dev/null
+++ b/testing/resources/bug_1591.pdf
@@ -0,0 +1,122 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 4 0 R
+  /MediaBox [0 0 160 400]
+  /Resources <<
+    /ProcSet [/PDF /Text]
+    /Font <<
+      /F1 5 0 R
+    >>
+  >>
+>>
+endobj
+4 0 obj <<
+  /Length 102
+>>
+stream
+0 0 0 rg
+BT
+/F1 1 Tf
+240 0 0 240 50 50 Tm
+0.2 Tw
+0.05 0 Td
+(1) Tj
+0.1 0 Td
+(2) Tj
+0.05 0 Td
+(1) Tj
+ET
+endstream
+endobj
+5 0 obj <<
+  /Type /Font
+  /Subtype /Type3
+  /CharProcs 6 0 R
+  /Encoding 7 0 R
+  /FirstChar 49
+  /FontBBox [-1 -8 28 27]
+  /FontMatrix [0.001 0 0 0.001 0 0]
+  /LastChar 50
+  /Name /F1
+  /Resources <<
+    /ProcSet [/PDF /ImageB]
+  >>
+  /Widths [8 10]
+>>
+endobj
+6 0 obj <<
+  /uniE022 8 0 R
+  /uniE023 9 0 R
+>>
+endobj
+7 0 obj <<
+  /Type /Encoding
+  /Differences [49 /uniE022 /uniE023]
+>>
+endobj
+8 0 obj <<
+  /Length 105
+>>
+stream
+q
+6 0 0 48 6 0 cm
+BI
+/W 6
+/H 48
+/BPC 1
+/IM true
+ID
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+EI
+Q
+endstream
+endobj
+9 0 obj <<
+  /Length 42
+>>
+stream
+q
+BI
+/W 4
+/H 4
+/BPC 1
+/IM true
+ID
+xx
+EI
+Q
+endstream
+endobj
+xref
+0 10
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000131 00000 n 
+0000000309 00000 n 
+0000000463 00000 n 
+0000000724 00000 n 
+0000000779 00000 n 
+0000000856 00000 n 
+0000001013 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 10
+>>
+startxref
+1106
+%%EOF