Add an embedder test for text spacing being lost when saving

Add a test to show modifying PDF pages where a text object that uses the
TJ operator to specify horizontal spacing renders correctly in memory,
but the text object loses its spacing when saved.

Bug: 410996566
Change-Id: I702c9845557bcd1b615abb972fe68edaf45ae1a2
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/144810
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Andy Phan <andyphan@chromium.org>
diff --git a/fpdfsdk/fpdf_edit_embeddertest.cpp b/fpdfsdk/fpdf_edit_embeddertest.cpp
index de56868..ae0d9d7 100644
--- a/fpdfsdk/fpdf_edit_embeddertest.cpp
+++ b/fpdfsdk/fpdf_edit_embeddertest.cpp
@@ -5102,6 +5102,31 @@
   VerifySavedDocument("form_object_with_image_removed_image");
 }
 
+TEST_F(FPDFEditEmbedderTest, Bug410996566) {
+  ASSERT_TRUE(OpenDocument("bug_410996566.pdf"));
+  ScopedPage page = LoadScopedPage(0);
+  ASSERT_TRUE(page);
+
+  {
+    ScopedFPDFPageObject obj(FPDFPage_GetObject(page.get(), 1));
+    ASSERT_TRUE(FPDFPage_RemoveObject(page.get(), obj.get()));
+  }
+  ASSERT_TRUE(FPDFPage_GenerateContent(page.get()));
+
+  static constexpr char kExpected[] = "bug_410996566";
+  {
+    ScopedFPDFBitmap bitmap = RenderPage(page.get());
+    CompareBitmapWithExpectationSuffix(bitmap.get(), kExpected);
+  }
+
+  // TODO(crbug.com/461845674): The saved doc should have the same text spacing
+  // in the remaining text object, just like the original PDF. The rendering
+  // should match `kExpected`.
+  static constexpr char kWrongSpacing[] = "bug_410996566_wrong_spacing";
+  ASSERT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
+  VerifySavedDocumentWithExpectationSuffix(kWrongSpacing);
+}
+
 TEST_F(FPDFEditEmbedderTest, Bug461845674) {
   ASSERT_TRUE(OpenDocument("bug_461845674.pdf"));
   ScopedPage page = LoadScopedPage(0);
diff --git a/testing/resources/bug_410996566.in b/testing/resources/bug_410996566.in
new file mode 100644
index 0000000..41beb92
--- /dev/null
+++ b/testing/resources/bug_410996566.in
@@ -0,0 +1,55 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /MediaBox [0 0 200 200]
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <<
+      /F1 4 0 R
+      /F2 5 0 R
+    >>
+  >>
+  /Contents 6 0 R
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Times-Roman
+>>
+endobj
+{{object 5 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+>>
+endobj
+{{object 6 0}} <<
+  {{streamlen}}
+>>
+stream
+BT
+20 50 Td
+/F1 12 Tf
+[(H) -100 (e) (l) -200 (l) (o) 150 (,) ( ) (worl) (d) -500 (!)] TJ
+0 50 Td
+/F2 16 Tf
+(Goodbye, world!) Tj
+ET
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/bug_410996566.pdf b/testing/resources/bug_410996566.pdf
new file mode 100644
index 0000000..fe33a63
--- /dev/null
+++ b/testing/resources/bug_410996566.pdf
@@ -0,0 +1,68 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /MediaBox [0 0 200 200]
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <<
+      /F1 4 0 R
+      /F2 5 0 R
+    >>
+  >>
+  /Contents 6 0 R
+>>
+endobj
+4 0 obj <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Times-Roman
+>>
+endobj
+5 0 obj <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+>>
+endobj
+6 0 obj <<
+  /Length 130
+>>
+stream
+BT
+20 50 Td
+/F1 12 Tf
+[(H) -100 (e) (l) -200 (l) (o) 150 (,) ( ) (worl) (d) -500 (!)] TJ
+0 50 Td
+/F2 16 Tf
+(Goodbye, world!) Tj
+ET
+endstream
+endobj
+xref
+0 7
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000157 00000 n 
+0000000299 00000 n 
+0000000377 00000 n 
+0000000453 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 7
+>>
+startxref
+636
+%%EOF
diff --git a/testing/resources/embedder_tests/bug_410996566.png b/testing/resources/embedder_tests/bug_410996566.png
new file mode 100644
index 0000000..ec98812
--- /dev/null
+++ b/testing/resources/embedder_tests/bug_410996566.png
Binary files differ
diff --git a/testing/resources/embedder_tests/bug_410996566_agg_mac.png b/testing/resources/embedder_tests/bug_410996566_agg_mac.png
new file mode 100644
index 0000000..f779087
--- /dev/null
+++ b/testing/resources/embedder_tests/bug_410996566_agg_mac.png
Binary files differ
diff --git a/testing/resources/embedder_tests/bug_410996566_skia.png b/testing/resources/embedder_tests/bug_410996566_skia.png
new file mode 100644
index 0000000..67baec9
--- /dev/null
+++ b/testing/resources/embedder_tests/bug_410996566_skia.png
Binary files differ
diff --git a/testing/resources/embedder_tests/bug_410996566_skia_mac.png b/testing/resources/embedder_tests/bug_410996566_skia_mac.png
new file mode 100644
index 0000000..3e888cc
--- /dev/null
+++ b/testing/resources/embedder_tests/bug_410996566_skia_mac.png
Binary files differ
diff --git a/testing/resources/embedder_tests/bug_410996566_skia_win.png b/testing/resources/embedder_tests/bug_410996566_skia_win.png
new file mode 100644
index 0000000..f8994ba
--- /dev/null
+++ b/testing/resources/embedder_tests/bug_410996566_skia_win.png
Binary files differ
diff --git a/testing/resources/embedder_tests/bug_410996566_skia_x86.png b/testing/resources/embedder_tests/bug_410996566_skia_x86.png
new file mode 100644
index 0000000..2647707
--- /dev/null
+++ b/testing/resources/embedder_tests/bug_410996566_skia_x86.png
Binary files differ
diff --git a/testing/resources/embedder_tests/bug_410996566_wrong_spacing.png b/testing/resources/embedder_tests/bug_410996566_wrong_spacing.png
new file mode 100644
index 0000000..7d2eab4
--- /dev/null
+++ b/testing/resources/embedder_tests/bug_410996566_wrong_spacing.png
Binary files differ
diff --git a/testing/resources/embedder_tests/bug_410996566_wrong_spacing_agg_mac.png b/testing/resources/embedder_tests/bug_410996566_wrong_spacing_agg_mac.png
new file mode 100644
index 0000000..2499120
--- /dev/null
+++ b/testing/resources/embedder_tests/bug_410996566_wrong_spacing_agg_mac.png
Binary files differ
diff --git a/testing/resources/embedder_tests/bug_410996566_wrong_spacing_skia.png b/testing/resources/embedder_tests/bug_410996566_wrong_spacing_skia.png
new file mode 100644
index 0000000..59bdee9
--- /dev/null
+++ b/testing/resources/embedder_tests/bug_410996566_wrong_spacing_skia.png
Binary files differ
diff --git a/testing/resources/embedder_tests/bug_410996566_wrong_spacing_skia_mac.png b/testing/resources/embedder_tests/bug_410996566_wrong_spacing_skia_mac.png
new file mode 100644
index 0000000..f7b4c70
--- /dev/null
+++ b/testing/resources/embedder_tests/bug_410996566_wrong_spacing_skia_mac.png
Binary files differ
diff --git a/testing/resources/embedder_tests/bug_410996566_wrong_spacing_skia_win.png b/testing/resources/embedder_tests/bug_410996566_wrong_spacing_skia_win.png
new file mode 100644
index 0000000..5e024c8
--- /dev/null
+++ b/testing/resources/embedder_tests/bug_410996566_wrong_spacing_skia_win.png
Binary files differ
diff --git a/testing/resources/embedder_tests/bug_410996566_wrong_spacing_skia_x86.png b/testing/resources/embedder_tests/bug_410996566_wrong_spacing_skia_x86.png
new file mode 100644
index 0000000..17164fc
--- /dev/null
+++ b/testing/resources/embedder_tests/bug_410996566_wrong_spacing_skia_x86.png
Binary files differ