Update pdfium to Chrome 114.0.5735.130 pdfium

pdfium last commit id: 9505810f6

Bug: 279055389
Test: Build the code and flash the device and check Print functionality
Test: atest FrameworksCoreTests
Test: atest CtsPrintTestCases
Test: atest CtsPdfTestCases
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:3e2fb7d98efb4ba7b51fd84e9a0ae04f8c0f7805)
Merged-In: I2efabeec0d0fa3925bcbeebf36031cee6f7f9fc4
Change-Id: I2efabeec0d0fa3925bcbeebf36031cee6f7f9fc4
diff --git a/testing/resources/CMYK-alpha.jpf b/testing/resources/CMYK-alpha.jpf
new file mode 100644
index 0000000..538e6d6
--- /dev/null
+++ b/testing/resources/CMYK-alpha.jpf
Binary files differ
diff --git a/testing/resources/CMYK.jpf b/testing/resources/CMYK.jpf
new file mode 100644
index 0000000..00f2ef9
--- /dev/null
+++ b/testing/resources/CMYK.jpf
Binary files differ
diff --git a/testing/resources/RGB-alpha.jp2 b/testing/resources/RGB-alpha.jp2
new file mode 100644
index 0000000..4ab41da
--- /dev/null
+++ b/testing/resources/RGB-alpha.jp2
Binary files differ
diff --git a/testing/resources/RGB.jp2 b/testing/resources/RGB.jp2
new file mode 100644
index 0000000..7b7d428
--- /dev/null
+++ b/testing/resources/RGB.jp2
Binary files differ
diff --git a/testing/resources/annot_javascript.in b/testing/resources/annot_javascript.in
new file mode 100644
index 0000000..fe9ac46
--- /dev/null
+++ b/testing/resources/annot_javascript.in
@@ -0,0 +1,42 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /Fields [4 0 R]
+  >>
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /MediaBox [0 0 612 792]
+  /Kids [3 0 R]
+  /Count 1
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 612 792]
+  /Annots [4 0 R]
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /Rect [85 721 153 735]
+  /FT /Tx
+  /P 3 0 R
+  /T (Widget)
+  /AA <<
+    /F <<
+      /JS (AFDate_FormatEx\("yyyy-mm-dd"\);)
+      /S /JavaScript
+    >>
+  >>
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/annot_javascript.pdf b/testing/resources/annot_javascript.pdf
new file mode 100644
index 0000000..fbeb5df
--- /dev/null
+++ b/testing/resources/annot_javascript.pdf
@@ -0,0 +1,53 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /Fields [4 0 R]
+  >>
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /MediaBox [0 0 612 792]
+  /Kids [3 0 R]
+  /Count 1
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 612 792]
+  /Annots [4 0 R]
+>>
+endobj
+4 0 obj <<
+  /Type /Annot
+  /Subtype /Widget
+  /Rect [85 721 153 735]
+  /FT /Tx
+  /P 3 0 R
+  /T (Widget)
+  /AA <<
+    /F <<
+      /JS (AFDate_FormatEx\("yyyy-mm-dd"\);)
+      /S /JavaScript
+    >>
+  >>
+>>
+endobj
+xref
+0 5
+0000000000 65535 f 
+0000000015 00000 n 
+0000000108 00000 n 
+0000000197 00000 n 
+0000000292 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 5
+>>
+startxref
+504
+%%EOF
diff --git a/testing/resources/annots.in b/testing/resources/annots.in
new file mode 100644
index 0000000..cf575f5
--- /dev/null
+++ b/testing/resources/annots.in
@@ -0,0 +1,362 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /Fields [23 0 R]
+    /DR <<
+      /Font <<
+        /F1 7 0 R
+      >>
+    >>
+  >>
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 2
+  /Kids [3 0 R 4 0 R]
+  /MediaBox [0 0 612 792]
+  /CropBox [0 0 612 792]
+  /Resources <<
+    /Font <<
+      /F1 7 0 R
+      /F2 8 0 R
+    >>
+    /ProcSet [/PDF /Text /ImageC]
+    /ExtGState <<
+      /GS0 24 0 R
+    >>
+  >>
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 5 0 R
+  /Annots [15 0 R 16 0 R 17 0 R 18 0 R 19 0 R 20 0 R 21 0 R 22 0 R 23 0 R]
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 6 0 R
+  /Annots [15 0 R 16 0 R 26 0 R]
+>>
+endobj
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+BT
+70 700 Td
+/F1 18 Tf
+(Link Annotations - Page 1) Tj
+0 -65 Td
+/F2 14 Tf
+(1. Link with destination to first page) Tj
+10 -20 Td
+/F2 14 Tf
+(2. Link with destination to second page) Tj
+-12 -84 Td
+/F2 10 Tf
+(PDF Reference, Version 1.7, Section 8.4.5 defines Annotations) Tj
+2 -53 Td
+(3.  An example of Highlight with text notes) Tj
+0 -18 Td
+(https://pdfium.googlesource.com/pdfium is link in plain text, not link annotation. These are referred to) Tj
+0 -17 Td
+(as WebLinks in PDFium.)Tj
+ET
+endstream
+endobj
+{{object 6 0}} <<
+  {{streamlen}}
+>>
+stream
+BT
+70 700 Td
+/F1 18 Tf
+(Link Annotations - Page 2) Tj
+0 -65 Td
+/F2 14 Tf
+(1. Link with destination to first page) Tj
+10 -20 Td
+/F2 14 Tf
+(2. Link with destination to second page) Tj
+ET
+endstream
+endobj
+{{object 7 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Times-Roman
+>>
+endobj
+{{object 8 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+>>
+endobj
+{{object 9 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  {{streamlen}}
+  /BBox [293 530 349 542]
+  /Resources <<
+    /XObject <<
+      /Form0 10 0 R
+    >>
+    /ExtGState <<
+      /GS0 25 0 R
+    >>
+  >>
+>>
+stream
+/GS0 gs
+/Form0 Do
+endstream
+endobj
+{{object 10 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /Group <<
+    /S /Transparency
+  >>
+  {{streamlen}}
+  /BBox [293 530 349 542]
+>>
+stream
+1.0 1.0 0.0 rg
+293 530 m
+349 530 l
+349 542 l
+293 542 l
+h f
+endstream
+endobj
+{{object 11 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  {{streamlen}}
+  /BBox [83 440 178 453]
+  /Resources <<
+    /XObject <<
+      /Form0 12 0 R
+    >>
+    /ExtGState <<
+      /GS0 25 0 R
+    >>
+  >>
+>>
+stream
+/GS0 gs
+/Form0 Do
+endstream
+endobj
+{{object 12 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /Group <<
+    /S /Transparency
+  >>
+  {{streamlen}}
+  /BBox [83 440 178 453]
+>>
+stream
+0.0 1.0 1.0 rg
+83 440 m
+178 440 l
+178 453 l
+83 453 l
+h f
+endstream
+endobj
+{{object 13 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  {{streamlen}}
+  /BBox [149 476 191 487]
+  /Resources <<
+    /XObject <<
+      /Form0 14 0 R
+    >>
+    /ExtGState <<
+      /GS0 25 0 R
+    >>
+  >>
+>>
+stream
+/GS0 gs
+/Form0 Do
+endstream
+endobj
+{{object 14 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /Group <<
+    /S /Transparency
+  >>
+  {{streamlen}}
+  /BBox [149 476 191 487]
+>>
+stream
+0.0 1.0 0.0 rg
+149 476 m
+191 476 l
+191 487 l
+149 487 l
+h f
+endstream
+endobj
+{{object 15 0}} <<
+  /Type /Annot
+  /Subtype /Link
+  /BS <<
+    /W 0
+  >>
+  /Rect [69 633 542 653]
+  /Dest [3 0 R /XYZ 200 725 0]
+  /F 4
+>>
+endobj
+{{object 16 0}} <<
+  /Type /Annot
+  /Subtype /Link
+  /BS <<
+    /W 0
+  >>
+  /Rect [80 613 542 633]
+  /Dest [4 0 R /XYZ 200 725 0]
+  /F 4
+>>
+endobj
+{{object 17 0}} <<
+  /Type /Annot
+  /Subtype /Link
+  /BS <<
+    /W 0
+  >>
+  /Rect [66 529 196 544]
+  /A <<
+    /Type /Action
+    /URI (https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/pdf_reference_1-7.pdf)
+    /S /URI
+  >>
+  /F 4
+>>
+endobj
+{{object 18 0}} <<
+  /Type /Annot
+  /Subtype /Link
+  /BS <<
+    /W 0
+  >>
+  /Rect [83 440 178 453]
+  /QuadPoints [83 453 178 453 83 440 178 440]
+  /A <<
+    /Type /Action
+    /URI (https://cs.chromium.org/chromium/src/third_party/pdfium/public/fpdf_text.h)
+    /S /URI
+  >>
+  /F 4
+>>
+endobj
+{{object 19 0}} <<
+  /Type /Annot
+  /Subtype /Highlight
+  /AP <<
+    /N 9 0 R
+  >>
+  /NM (Highlight-1)
+  /F 4
+  /QuadPoints [293 542 349 542 293 530 349 530]
+  /P 3 0 R
+  /C [1 0.90196 0]
+  /Rect [293 530 349 542]
+>>
+endobj
+{{object 20 0}} <<
+  /Type /Annot
+  /Subtype /Highlight
+  /AP <<
+    /N 11 0 R
+  >>
+  /NM (Highlight-2)
+  /F 4
+  /QuadPoints [83 453 178 453 83 440 178 440]
+  /P 3 0 R
+  /C [0.26667 0.78431 0.96078]
+  /Rect [83 440 178 453]
+>>
+endobj
+{{object 21 0}} <<
+  /Type /Annot
+  /Subtype /Popup
+  /Parent 22 0 R
+  /Rect [191 377 443 488]
+>>
+endobj
+{{object 22 0}} <<
+  /Type /Annot
+  /Subtype /Highlight
+  /Popup 21 0 R
+  /AP <<
+    /N 13 0 R
+  >>
+  /NM (Highlight-With-Popup-1)
+  /Contents (Text Note)
+  /QuadPoints [149 487 191 487 149 476 191 476]
+  /P 3 0 R
+  /C [0.14902 0.90196 0]
+  /Rect [149 476 191 487]
+  /F 4
+>>
+endobj
+{{object 23 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Ch
+  /Ff 131072
+  /T (Combo1)
+  /DA (0 0 0 rg /F1 12 Tf)
+  /Rect [70 350 170 380]
+  /Opt [(Highlight) (Link) (Popup) (Widget)]
+>>
+endobj
+{{object 24 0}} <<
+  /ca 1
+  /Type /ExtGState
+  /CA 1
+  /BM /Normal
+>>
+endobj
+{{object 25 0}} <<
+  /ca 1
+  /Type /ExtGState
+  /CA 1
+  /AIS false
+  /BM /Multiply
+>>
+endobj
+{{object 26 0}} <<
+  /Type /Annot
+  /Subtype /Square
+  /Border [0 0 2]
+  /C [1 0 0]
+  /F 4
+  /P 3 0 R
+  /Rect [50 100 60 120]
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/annots.pdf b/testing/resources/annots.pdf
new file mode 100644
index 0000000..745346c
--- /dev/null
+++ b/testing/resources/annots.pdf
@@ -0,0 +1,395 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /Fields [23 0 R]
+    /DR <<
+      /Font <<
+        /F1 7 0 R
+      >>
+    >>
+  >>
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /Count 2
+  /Kids [3 0 R 4 0 R]
+  /MediaBox [0 0 612 792]
+  /CropBox [0 0 612 792]
+  /Resources <<
+    /Font <<
+      /F1 7 0 R
+      /F2 8 0 R
+    >>
+    /ProcSet [/PDF /Text /ImageC]
+    /ExtGState <<
+      /GS0 24 0 R
+    >>
+  >>
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 5 0 R
+  /Annots [15 0 R 16 0 R 17 0 R 18 0 R 19 0 R 20 0 R 21 0 R 22 0 R 23 0 R]
+>>
+endobj
+4 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 6 0 R
+  /Annots [15 0 R 16 0 R 26 0 R]
+>>
+endobj
+5 0 obj <<
+  /Length 486
+>>
+stream
+BT
+70 700 Td
+/F1 18 Tf
+(Link Annotations - Page 1) Tj
+0 -65 Td
+/F2 14 Tf
+(1. Link with destination to first page) Tj
+10 -20 Td
+/F2 14 Tf
+(2. Link with destination to second page) Tj
+-12 -84 Td
+/F2 10 Tf
+(PDF Reference, Version 1.7, Section 8.4.5 defines Annotations) Tj
+2 -53 Td
+(3.  An example of Highlight with text notes) Tj
+0 -18 Td
+(https://pdfium.googlesource.com/pdfium is link in plain text, not link annotation. These are referred to) Tj
+0 -17 Td
+(as WebLinks in PDFium.)Tj
+ET
+endstream
+endobj
+6 0 obj <<
+  /Length 185
+>>
+stream
+BT
+70 700 Td
+/F1 18 Tf
+(Link Annotations - Page 2) Tj
+0 -65 Td
+/F2 14 Tf
+(1. Link with destination to first page) Tj
+10 -20 Td
+/F2 14 Tf
+(2. Link with destination to second page) Tj
+ET
+endstream
+endobj
+7 0 obj <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Times-Roman
+>>
+endobj
+8 0 obj <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+>>
+endobj
+9 0 obj <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /Length 18
+  /BBox [293 530 349 542]
+  /Resources <<
+    /XObject <<
+      /Form0 10 0 R
+    >>
+    /ExtGState <<
+      /GS0 25 0 R
+    >>
+  >>
+>>
+stream
+/GS0 gs
+/Form0 Do
+endstream
+endobj
+10 0 obj <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /Group <<
+    /S /Transparency
+  >>
+  /Length 59
+  /BBox [293 530 349 542]
+>>
+stream
+1.0 1.0 0.0 rg
+293 530 m
+349 530 l
+349 542 l
+293 542 l
+h f
+endstream
+endobj
+11 0 obj <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /Length 18
+  /BBox [83 440 178 453]
+  /Resources <<
+    /XObject <<
+      /Form0 12 0 R
+    >>
+    /ExtGState <<
+      /GS0 25 0 R
+    >>
+  >>
+>>
+stream
+/GS0 gs
+/Form0 Do
+endstream
+endobj
+12 0 obj <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /Group <<
+    /S /Transparency
+  >>
+  /Length 57
+  /BBox [83 440 178 453]
+>>
+stream
+0.0 1.0 1.0 rg
+83 440 m
+178 440 l
+178 453 l
+83 453 l
+h f
+endstream
+endobj
+13 0 obj <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /Length 18
+  /BBox [149 476 191 487]
+  /Resources <<
+    /XObject <<
+      /Form0 14 0 R
+    >>
+    /ExtGState <<
+      /GS0 25 0 R
+    >>
+  >>
+>>
+stream
+/GS0 gs
+/Form0 Do
+endstream
+endobj
+14 0 obj <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /Group <<
+    /S /Transparency
+  >>
+  /Length 59
+  /BBox [149 476 191 487]
+>>
+stream
+0.0 1.0 0.0 rg
+149 476 m
+191 476 l
+191 487 l
+149 487 l
+h f
+endstream
+endobj
+15 0 obj <<
+  /Type /Annot
+  /Subtype /Link
+  /BS <<
+    /W 0
+  >>
+  /Rect [69 633 542 653]
+  /Dest [3 0 R /XYZ 200 725 0]
+  /F 4
+>>
+endobj
+16 0 obj <<
+  /Type /Annot
+  /Subtype /Link
+  /BS <<
+    /W 0
+  >>
+  /Rect [80 613 542 633]
+  /Dest [4 0 R /XYZ 200 725 0]
+  /F 4
+>>
+endobj
+17 0 obj <<
+  /Type /Annot
+  /Subtype /Link
+  /BS <<
+    /W 0
+  >>
+  /Rect [66 529 196 544]
+  /A <<
+    /Type /Action
+    /URI (https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/pdf_reference_1-7.pdf)
+    /S /URI
+  >>
+  /F 4
+>>
+endobj
+18 0 obj <<
+  /Type /Annot
+  /Subtype /Link
+  /BS <<
+    /W 0
+  >>
+  /Rect [83 440 178 453]
+  /QuadPoints [83 453 178 453 83 440 178 440]
+  /A <<
+    /Type /Action
+    /URI (https://cs.chromium.org/chromium/src/third_party/pdfium/public/fpdf_text.h)
+    /S /URI
+  >>
+  /F 4
+>>
+endobj
+19 0 obj <<
+  /Type /Annot
+  /Subtype /Highlight
+  /AP <<
+    /N 9 0 R
+  >>
+  /NM (Highlight-1)
+  /F 4
+  /QuadPoints [293 542 349 542 293 530 349 530]
+  /P 3 0 R
+  /C [1 0.90196 0]
+  /Rect [293 530 349 542]
+>>
+endobj
+20 0 obj <<
+  /Type /Annot
+  /Subtype /Highlight
+  /AP <<
+    /N 11 0 R
+  >>
+  /NM (Highlight-2)
+  /F 4
+  /QuadPoints [83 453 178 453 83 440 178 440]
+  /P 3 0 R
+  /C [0.26667 0.78431 0.96078]
+  /Rect [83 440 178 453]
+>>
+endobj
+21 0 obj <<
+  /Type /Annot
+  /Subtype /Popup
+  /Parent 22 0 R
+  /Rect [191 377 443 488]
+>>
+endobj
+22 0 obj <<
+  /Type /Annot
+  /Subtype /Highlight
+  /Popup 21 0 R
+  /AP <<
+    /N 13 0 R
+  >>
+  /NM (Highlight-With-Popup-1)
+  /Contents (Text Note)
+  /QuadPoints [149 487 191 487 149 476 191 476]
+  /P 3 0 R
+  /C [0.14902 0.90196 0]
+  /Rect [149 476 191 487]
+  /F 4
+>>
+endobj
+23 0 obj <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Ch
+  /Ff 131072
+  /T (Combo1)
+  /DA (0 0 0 rg /F1 12 Tf)
+  /Rect [70 350 170 380]
+  /Opt [(Highlight) (Link) (Popup) (Widget)]
+>>
+endobj
+24 0 obj <<
+  /ca 1
+  /Type /ExtGState
+  /CA 1
+  /BM /Normal
+>>
+endobj
+25 0 obj <<
+  /ca 1
+  /Type /ExtGState
+  /CA 1
+  /AIS false
+  /BM /Multiply
+>>
+endobj
+26 0 obj <<
+  /Type /Annot
+  /Subtype /Square
+  /Border [0 0 2]
+  /C [1 0 0]
+  /F 4
+  /P 3 0 R
+  /Rect [50 100 60 120]
+>>
+endobj
+xref
+0 27
+0000000000 65535 f 
+0000000015 00000 n 
+0000000169 00000 n 
+0000000439 00000 n 
+0000000583 00000 n 
+0000000685 00000 n 
+0000001223 00000 n 
+0000001460 00000 n 
+0000001538 00000 n 
+0000001614 00000 n 
+0000001864 00000 n 
+0000002087 00000 n 
+0000002337 00000 n 
+0000002557 00000 n 
+0000002808 00000 n 
+0000003031 00000 n 
+0000003171 00000 n 
+0000003311 00000 n 
+0000003558 00000 n 
+0000003842 00000 n 
+0000004059 00000 n 
+0000004286 00000 n 
+0000004384 00000 n 
+0000004659 00000 n 
+0000004849 00000 n 
+0000004920 00000 n 
+0000005006 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 27
+>>
+startxref
+5135
+%%EOF
diff --git a/testing/resources/annots_action_handling.in b/testing/resources/annots_action_handling.in
new file mode 100644
index 0000000..e5c728b
--- /dev/null
+++ b/testing/resources/annots_action_handling.in
@@ -0,0 +1,132 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /Names 12 0 R
+  /AcroForm [6 0 R 7 0 R]
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 2
+  /Kids [3 0 R 4 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Annots [6 0 R 7 0 R 8 0 R 9 0 R 10 0 R 11 0 R]
+  /Contents 5 0 R
+  /Tabs /R
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Tabs /R
+>>
+endobj
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+BT
+70 340 Td
+14 Tf
+(External Link ) Tj
+0 -35 Td
+14 Tf
+(Internal Link ) Tj
+0 -35 Td
+14 Tf
+(Link1 to top ) Tj
+0 -35 Td
+14 Tf
+(Link2 to top ) Tj
+ET
+endstream
+endobj
+{{object 6 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Tx
+  /Parent 3 0 R
+  /T (TextField)
+  /Rect [69 670 220 690]
+>>
+endobj
+{{object 7 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Btn
+  /Rect [69 360 220 380]
+  /A <<
+    /URI (https://www.google.com)
+    /S /URI
+  >>
+  /F 4
+  /T (button)
+  /Ff 65536
+>>
+endobj
+{{object 8 0}} <<
+  /Type /Annot
+  /Subtype /Link
+  /Rect [69 338 180 358]
+  /A <<
+    /Type /Action
+    /S /URI
+    /URI (https://cs.chromium.org/)
+  >>
+  /F 4
+>>
+endobj
+{{object 9 0}} <<
+  /Type /Annot
+  /Subtype /Link
+  /Rect [69 305 180 325]
+  /BS <<
+    /W 0
+  >>
+  /Dest [4 0 R /XYZ 200 725 0]
+  /F 4
+>>
+{{object 10 0}} <<
+  /Type /Annot
+  /Subtype /Link
+  /Rect [69 270 180 290]
+  /BS <<
+    /W 0
+  >>
+  /Dest /top
+  /F 4
+>>
+{{object 11 0}} <<
+  /Type /Annot
+  /Subtype /Link
+  /Rect [69 235 180 255]
+  /BS <<
+    /W 0
+  >>
+  /Dest (target10)
+  /F 4
+>>
+{{object 12 0}} <<
+  /Dests 13 0 R
+>>
+endobj
+{{object 13 0}} <<
+  /Names [
+    (target10) 14 0 R
+    /top 14 0 R
+  ]
+>>
+endobj
+{{object 14 0}} <<
+  /D [3 0 R /XYZ 100 200 0]
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
\ No newline at end of file
diff --git a/testing/resources/annots_action_handling.pdf b/testing/resources/annots_action_handling.pdf
new file mode 100644
index 0000000..b8b6c2a
--- /dev/null
+++ b/testing/resources/annots_action_handling.pdf
@@ -0,0 +1,153 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /Names 12 0 R
+  /AcroForm [6 0 R 7 0 R]
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /Count 2
+  /Kids [3 0 R 4 0 R]
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Annots [6 0 R 7 0 R 8 0 R 9 0 R 10 0 R 11 0 R]
+  /Contents 5 0 R
+  /Tabs /R
+>>
+endobj
+4 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Tabs /R
+>>
+endobj
+5 0 obj <<
+  /Length 145
+>>
+stream
+BT
+70 340 Td
+14 Tf
+(External Link ) Tj
+0 -35 Td
+14 Tf
+(Internal Link ) Tj
+0 -35 Td
+14 Tf
+(Link1 to top ) Tj
+0 -35 Td
+14 Tf
+(Link2 to top ) Tj
+ET
+endstream
+endobj
+6 0 obj <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Tx
+  /Parent 3 0 R
+  /T (TextField)
+  /Rect [69 670 220 690]
+>>
+endobj
+7 0 obj <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Btn
+  /Rect [69 360 220 380]
+  /A <<
+    /URI (https://www.google.com)
+    /S /URI
+  >>
+  /F 4
+  /T (button)
+  /Ff 65536
+>>
+endobj
+8 0 obj <<
+  /Type /Annot
+  /Subtype /Link
+  /Rect [69 338 180 358]
+  /A <<
+    /Type /Action
+    /S /URI
+    /URI (https://cs.chromium.org/)
+  >>
+  /F 4
+>>
+endobj
+9 0 obj <<
+  /Type /Annot
+  /Subtype /Link
+  /Rect [69 305 180 325]
+  /BS <<
+    /W 0
+  >>
+  /Dest [4 0 R /XYZ 200 725 0]
+  /F 4
+>>
+10 0 obj <<
+  /Type /Annot
+  /Subtype /Link
+  /Rect [69 270 180 290]
+  /BS <<
+    /W 0
+  >>
+  /Dest /top
+  /F 4
+>>
+11 0 obj <<
+  /Type /Annot
+  /Subtype /Link
+  /Rect [69 235 180 255]
+  /BS <<
+    /W 0
+  >>
+  /Dest (target10)
+  /F 4
+>>
+12 0 obj <<
+  /Dests 13 0 R
+>>
+endobj
+13 0 obj <<
+  /Names [
+    (target10) 14 0 R
+    /top 14 0 R
+  ]
+>>
+endobj
+14 0 obj <<
+  /D [3 0 R /XYZ 100 200 0]
+>>
+endobj
+xref
+0 15
+0000000000 65535 f 
+0000000015 00000 n 
+0000000110 00000 n 
+0000000179 00000 n 
+0000000309 00000 n 
+0000000371 00000 n 
+0000000568 00000 n 
+0000000691 00000 n 
+0000000874 00000 n 
+0000001038 00000 n 
+0000001170 00000 n 
+0000001285 00000 n 
+0000001406 00000 n 
+0000001444 00000 n 
+0000001519 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 15
+>>
+startxref
+1569
+%%EOF
\ No newline at end of file
diff --git a/testing/resources/bad_dict_keys.in b/testing/resources/bad_dict_keys.in
new file mode 100644
index 0000000..3f53c28
--- /dev/null
+++ b/testing/resources/bad_dict_keys.in
@@ -0,0 +1,23 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /MediaBox [0 0 300 300]
+  /Count 1
+  /Kids [3 0 R]
+  / [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/bad_dict_keys.pdf b/testing/resources/bad_dict_keys.pdf
new file mode 100644
index 0000000..b55c434
--- /dev/null
+++ b/testing/resources/bad_dict_keys.pdf
@@ -0,0 +1,33 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /MediaBox [0 0 300 300]
+  /Count 1
+  /Kids [3 0 R]
+  / [3 0 R]
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+>>
+endobj
+xref
+0 4
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000169 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 4
+>>
+startxref
+220
+%%EOF
diff --git a/testing/resources/bigtable_mini.in b/testing/resources/bigtable_mini.in
new file mode 100644
index 0000000..7e80992
--- /dev/null
+++ b/testing/resources/bigtable_mini.in
@@ -0,0 +1,113 @@
+{{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 612 792]
+  /Resources <<
+    /ProcSet [/PDF /ImageB /Text]
+    /Font <<
+      /F1 5 0 R
+      /F2 6 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q BT
+1 0 0 1 250 667 Tm
+/F2 8.96638 Tf
+-243.635 -15.84 Td
+(f)Tj
+/F1 8.96638 Tf
+4.55491 0 Td
+(f)Tj
+2.87476 0 Td
+(ay)Tj
+7.79253 0 Td
+(,jef)Tj
+11.506 0 Td
+(f,sanjay)Tj
+27.4558 0 Td
+(,wilsonh,k)Tj
+37.1801 0 Td
+(err)Tj
+9.58372 0 Td
+(,m3b,tushar)Tj
+41.8537 0 Td
+(,k)Tj
+11.6349 0 Td
+(es,gruber)Tj
+/F2 8.96638 Tf
+32.9694 0 Td
+(g)Tj
+/F1 8.96638 Tf
+4.55491 0 Td
+(@google.com)Tj
+ET Q
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Times-Roman
+>>
+endobj
+{{object 6 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /FirstChar 102
+  /BaseFont /RFSQHQ+CMSY9
+  /FontDescriptor 7 0 R
+  /LastChar 103
+  /Widths [508 508]
+>>
+endobj
+{{object 7 0}} <<
+  /Type /FontDescriptor
+  /Ascent 750
+  /CapHeight 750
+  /CharSet (/braceleft/braceright)
+  /Descent -250
+  /Flags 4
+  /FontBBox [0 -250 440 750]
+  /FontFile3 8 0 R
+  /FontName /RFSQHQ+CMSY9
+  /ItalicAngle 0
+  /StemV 65
+>>
+endobj
+{{object 8 0}} <<
+  /Subtype /Type1C
+  /Filter [/ASCII85Decode /FlateDecode]
+  {{streamlen}}
+>>
+stream
+GhQY<?t!MPA7Xa1EXNBL#h4%k%?@du#q5_5B)EgioL"p)pKs!j9@_A!X@n"A#^s/nr,0aY?!i,5R?>nA
+43BRuTX#t%4ekD2_c]pSd*g?I_(dmV-o3k<:Veup,U50*Ylr.i;$bHCc:fghe5L>1a\`<FkpTR<8hEdi
+.SEJ:>O%`N>>SLd>,:)GT9<BBa2#L+Pa9V1&Ao("^^P</!u&Ql7PhdY9T5#6IePGiOgOaNdLsRg)OHi+
+n+a.f[/4_7lnp:OXP)%6XER"WK`:C2*&F%pl[L]/LH0S#rJk:S[coEjaA0p=l`BI4BP[$LCn09862jKs
+Y)F7W^!5B(h.[kDUY*1W\e@l8mE%N?^8RN2qNUCce!bWPjLtF8=4Zg,R,1!:HR6^V/b\TIh0Z`11`hZZ
+*BO'Za1C[ph)dSm>aE#>k-A'_h4)!bqJD$jjj@/_bu*BN?.Ud@HV0Y&l1Vg$1F)e^]:6ER3IV(Tbj1;S
+BposQ0Df/MDiTcoYO4BSY\&*%<aJs1;J/:.>?>$UG7-pseF)R.T'a;@,PN5BX]sWQf<*o6H:RGZ*f^Pj
+qkd,*mVA#1lAJeH\%d!)GAm3[%_gAF5OB8mr>(pE^5_Fj[i?3Bq0X7/D)6E](`9a_gaUoK~>
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/bigtable_mini.pdf b/testing/resources/bigtable_mini.pdf
new file mode 100644
index 0000000..adb3e02
--- /dev/null
+++ b/testing/resources/bigtable_mini.pdf
@@ -0,0 +1,128 @@
+%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 612 792]
+  /Resources <<
+    /ProcSet [/PDF /ImageB /Text]
+    /Font <<
+      /F1 5 0 R
+      /F2 6 0 R
+    >>
+  >>
+>>
+endobj
+4 0 obj <<
+  /Length 374
+>>
+stream
+q BT
+1 0 0 1 250 667 Tm
+/F2 8.96638 Tf
+-243.635 -15.84 Td
+(f)Tj
+/F1 8.96638 Tf
+4.55491 0 Td
+(f)Tj
+2.87476 0 Td
+(ay)Tj
+7.79253 0 Td
+(,jef)Tj
+11.506 0 Td
+(f,sanjay)Tj
+27.4558 0 Td
+(,wilsonh,k)Tj
+37.1801 0 Td
+(err)Tj
+9.58372 0 Td
+(,m3b,tushar)Tj
+41.8537 0 Td
+(,k)Tj
+11.6349 0 Td
+(es,gruber)Tj
+/F2 8.96638 Tf
+32.9694 0 Td
+(g)Tj
+/F1 8.96638 Tf
+4.55491 0 Td
+(@google.com)Tj
+ET Q
+endstream
+endobj
+5 0 obj <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Times-Roman
+>>
+endobj
+6 0 obj <<
+  /Type /Font
+  /Subtype /Type1
+  /FirstChar 102
+  /BaseFont /RFSQHQ+CMSY9
+  /FontDescriptor 7 0 R
+  /LastChar 103
+  /Widths [508 508]
+>>
+endobj
+7 0 obj <<
+  /Type /FontDescriptor
+  /Ascent 750
+  /CapHeight 750
+  /CharSet (/braceleft/braceright)
+  /Descent -250
+  /Flags 4
+  /FontBBox [0 -250 440 750]
+  /FontFile3 8 0 R
+  /FontName /RFSQHQ+CMSY9
+  /ItalicAngle 0
+  /StemV 65
+>>
+endobj
+8 0 obj <<
+  /Subtype /Type1C
+  /Filter [/ASCII85Decode /FlateDecode]
+  /Length 640
+>>
+stream
+GhQY<?t!MPA7Xa1EXNBL#h4%k%?@du#q5_5B)EgioL"p)pKs!j9@_A!X@n"A#^s/nr,0aY?!i,5R?>nA
+43BRuTX#t%4ekD2_c]pSd*g?I_(dmV-o3k<:Veup,U50*Ylr.i;$bHCc:fghe5L>1a\`<FkpTR<8hEdi
+.SEJ:>O%`N>>SLd>,:)GT9<BBa2#L+Pa9V1&Ao("^^P</!u&Ql7PhdY9T5#6IePGiOgOaNdLsRg)OHi+
+n+a.f[/4_7lnp:OXP)%6XER"WK`:C2*&F%pl[L]/LH0S#rJk:S[coEjaA0p=l`BI4BP[$LCn09862jKs
+Y)F7W^!5B(h.[kDUY*1W\e@l8mE%N?^8RN2qNUCce!bWPjLtF8=4Zg,R,1!:HR6^V/b\TIh0Z`11`hZZ
+*BO'Za1C[ph)dSm>aE#>k-A'_h4)!bqJD$jjj@/_bu*BN?.Ud@HV0Y&l1Vg$1F)e^]:6ER3IV(Tbj1;S
+BposQ0Df/MDiTcoYO4BSY\&*%<aJs1;J/:.>?>$UG7-pseF)R.T'a;@,PN5BX]sWQf<*o6H:RGZ*f^Pj
+qkd,*mVA#1lAJeH\%d!)GAm3[%_gAF5OB8mr>(pE^5_Fj[i?3Bq0X7/D)6E](`9a_gaUoK~>
+endstream
+endobj
+xref
+0 9
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000131 00000 n 
+0000000333 00000 n 
+0000000759 00000 n 
+0000000837 00000 n 
+0000000993 00000 n 
+0000001234 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 9
+>>
+startxref
+1985
+%%EOF
diff --git a/testing/resources/bookmarks.in b/testing/resources/bookmarks.in
index 793f6ae..b0489a5 100644
--- a/testing/resources/bookmarks.in
+++ b/testing/resources/bookmarks.in
@@ -2,7 +2,7 @@
 {{object 1 0}} <<
   /Type /Catalog
   /Pages 2 0 R
-  /Outlines 14 0 R
+  /Outlines 8 0 R
 >>
 endobj
 {{object 2 0}} <<
@@ -19,9 +19,11 @@
   /Type /Page
   /Parent 2 0 R
   /Resources <<
-    /Font <</F1 15 0 R>>
+    /Font <<
+      /F1 5 0 R
+    >>
   >>
-  /Contents [21 0 R]
+  /Contents [6 0 R]
   /MediaBox [0 0 612 792]
 >>
 endobj
@@ -30,46 +32,24 @@
   /Type /Page
   /Parent 2 0 R
   /Resources  <<
-    /Font <</F1 15 0 R>>
+    /Font <<
+      /F1 5 0 R
+    >>
   >>
-  /Contents [22 0 R]
+  /Contents [7 0 R]
   /MediaBox [0 0 612 792]
 >>
 endobj
-% First bookmark
-{{object 10 0}} <<
-  /Title (A Good Beginning)
-  /Parent 14 0 R
-  /Next 11 0 R
-  /Dest (foo)
->>
-endobj
-% Last bookmark
-{{object 11 0}} <<
-  /Title (A Good Ending)
-  /Parent 14 0 R
-  /Prev 10 0 R
-  /Dest (bar)
->>
-endobj
-% Root bookmark
-{{object 14 0}} <<
-  /Type /Outlines
-  /First 10 0 R
-  /Last  11 0 R
-  /Count 2
->>
-endobj
 % Font resource.
-{{object 15 0}} <<
+{{object 5 0}} <<
   /Type /Font
   /Subtype /Type1
   /BaseFont /Arial
 >>
 endobj
 % Content for page 0.
-{{object 21 0}} <<
-  /Length 0
+{{object 6 0}} <<
+  {{streamlen}}
 >>
 stream
 BT
@@ -79,8 +59,8 @@
 endstream
 endobj
 % Content for page 1.
-{{object 22 0}} <<
-  /Length 0
+{{object 7 0}} <<
+  {{streamlen}}
 >>
 stream
 BT
@@ -89,6 +69,72 @@
 ET
 endstream
 endobj
+% Root bookmark
+{{object 8 0}} <<
+  /Type /Outlines
+  /Count 3
+  /First 9 0 R
+  /Last 12 0 R
+>>
+endobj
+% First child bookmark (leaf node)
+{{object 9 0}} <<
+  /Title (A Good Beginning)
+  /Parent 8 0 R
+  /Next 10 0 R
+  /Dest (foo)
+>>
+endobj
+% Second child bookmark (open)
+{{object 10 0}} <<
+  /Title (Open Middle)
+  /Parent 8 0 R
+  /First 11 0 R
+  /Last 11 0 R
+  /Prev 9 0 R
+  /Next 12 0 R
+  /Count 1
+  /A <<
+    /Type /Action
+    /S /URI
+    /URI (https://theplay.test)
+  >>
+>>
+endobj
+% First grandchild bookmark
+{{object 11 0}} <<
+  /Title (Open Middle Descendant)
+  /Parent 10 0 R
+  /Dest [3 0 R /XYZ 100 200 0]
+>>
+endobj
+% Third child bookmark (closed)
+{{object 12 0}} <<
+  /Title (A Good Closed Ending)
+  /Parent 8 0 R
+  /First 13 0 R
+  /Last 14 0 R
+  /Prev 10 0 R
+  /Count -2
+  /Dest (bar)
+>>
+endobj
+% Second grandchild bookmark
+{{object 13 0}} <<
+  /Title (A Good Closed Ending Descendant)
+  /Parent 12 0 R
+  /Next 14 0 R
+  /Dest (bar)
+>>
+endobj
+% Third grandchild bookmark
+{{object 14 0}} <<
+  /Title (A Good Closed Ending Descendant 2)
+  /Parent 12 0 R
+  /Prev 13 0 R
+  /Dest (bar)
+>>
+endobj
 {{xref}}
 {{trailer}}
 {{startxref}}
diff --git a/testing/resources/bookmarks.pdf b/testing/resources/bookmarks.pdf
index 8c2eb5a..757f859 100644
--- a/testing/resources/bookmarks.pdf
+++ b/testing/resources/bookmarks.pdf
@@ -3,7 +3,7 @@
 1 0 obj <<
   /Type /Catalog
   /Pages 2 0 R
-  /Outlines 14 0 R
+  /Outlines 8 0 R
 >>
 endobj
 2 0 obj <<
@@ -20,9 +20,11 @@
   /Type /Page
   /Parent 2 0 R
   /Resources <<
-    /Font <</F1 15 0 R>>
+    /Font <<
+      /F1 5 0 R
+    >>
   >>
-  /Contents [21 0 R]
+  /Contents [6 0 R]
   /MediaBox [0 0 612 792]
 >>
 endobj
@@ -31,46 +33,24 @@
   /Type /Page
   /Parent 2 0 R
   /Resources  <<
-    /Font <</F1 15 0 R>>
+    /Font <<
+      /F1 5 0 R
+    >>
   >>
-  /Contents [22 0 R]
+  /Contents [7 0 R]
   /MediaBox [0 0 612 792]
 >>
 endobj
-% First bookmark
-10 0 obj <<
-  /Title (A Good Beginning)
-  /Parent 14 0 R
-  /Next 11 0 R
-  /Dest (foo)
->>
-endobj
-% Last bookmark
-11 0 obj <<
-  /Title (A Good Ending)
-  /Parent 14 0 R
-  /Prev 10 0 R
-  /Dest (bar)
->>
-endobj
-% Root bookmark
-14 0 obj <<
-  /Type /Outlines
-  /First 10 0 R
-  /Last  11 0 R
-  /Count 2
->>
-endobj
 % Font resource.
-15 0 obj <<
+5 0 obj <<
   /Type /Font
   /Subtype /Type1
   /BaseFont /Arial
 >>
 endobj
 % Content for page 0.
-21 0 obj <<
-  /Length 0
+6 0 obj <<
+  /Length 37
 >>
 stream
 BT
@@ -80,8 +60,8 @@
 endstream
 endobj
 % Content for page 1.
-22 0 obj <<
-  /Length 0
+7 0 obj <<
+  /Length 37
 >>
 stream
 BT
@@ -90,32 +70,93 @@
 ET
 endstream
 endobj
+% Root bookmark
+8 0 obj <<
+  /Type /Outlines
+  /Count 3
+  /First 9 0 R
+  /Last 12 0 R
+>>
+endobj
+% First child bookmark (leaf node)
+9 0 obj <<
+  /Title (A Good Beginning)
+  /Parent 8 0 R
+  /Next 10 0 R
+  /Dest (foo)
+>>
+endobj
+% Second child bookmark (open)
+10 0 obj <<
+  /Title (Open Middle)
+  /Parent 8 0 R
+  /First 11 0 R
+  /Last 11 0 R
+  /Prev 9 0 R
+  /Next 12 0 R
+  /Count 1
+  /A <<
+    /Type /Action
+    /S /URI
+    /URI (https://theplay.test)
+  >>
+>>
+endobj
+% First grandchild bookmark
+11 0 obj <<
+  /Title (Open Middle Descendant)
+  /Parent 10 0 R
+  /Dest [3 0 R /XYZ 100 200 0]
+>>
+endobj
+% Third child bookmark (closed)
+12 0 obj <<
+  /Title (A Good Closed Ending)
+  /Parent 8 0 R
+  /First 13 0 R
+  /Last 14 0 R
+  /Prev 10 0 R
+  /Count -2
+  /Dest (bar)
+>>
+endobj
+% Second grandchild bookmark
+13 0 obj <<
+  /Title (A Good Closed Ending Descendant)
+  /Parent 12 0 R
+  /Next 14 0 R
+  /Dest (bar)
+>>
+endobj
+% Third grandchild bookmark
+14 0 obj <<
+  /Title (A Good Closed Ending Descendant 2)
+  /Parent 12 0 R
+  /Prev 13 0 R
+  /Dest (bar)
+>>
+endobj
 xref
-0 23
+0 15
 0000000000 65535 f 
 0000000015 00000 n 
-0000000087 00000 n 
-0000000185 00000 n 
-0000000346 00000 n 
-0000000000 65535 f 
-0000000000 65535 f 
-0000000000 65535 f 
-0000000000 65535 f 
-0000000000 65535 f 
-0000000508 00000 n 
-0000000620 00000 n 
-0000000000 65535 f 
-0000000000 65535 f 
-0000000729 00000 n 
-0000000829 00000 n 
-0000000000 65535 f 
-0000000000 65535 f 
-0000000000 65535 f 
-0000000000 65535 f 
-0000000000 65535 f 
-0000000924 00000 n 
-0000001034 00000 n 
-trailer<< /Root 1 0 R /Size 23 >>
+0000000086 00000 n 
+0000000184 00000 n 
+0000000355 00000 n 
+0000000527 00000 n 
+0000000621 00000 n 
+0000000731 00000 n 
+0000000835 00000 n 
+0000000950 00000 n 
+0000001075 00000 n 
+0000001310 00000 n 
+0000001446 00000 n 
+0000001617 00000 n 
+0000001756 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 15
+>>
 startxref
-1122
+1869
 %%EOF
diff --git a/testing/resources/bug_1055869.in b/testing/resources/bug_1055869.in
new file mode 100644
index 0000000..26cbf5f
--- /dev/null
+++ b/testing/resources/bug_1055869.in
@@ -0,0 +1,62 @@
+{{header}}
+{{include xfa_catalog_1_0.fragment}}
+{{include xfa_object_2_0.fragment}}
+{{include xfa_preamble_3_0.fragment}}
+{{include xfa_config_4_0.fragment}}
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+<template xmlns="http://www.xfa.org/schema/xfa-template/2.6/">
+  <subform layout="tb" locale="en_US" name="form1" restoreState="auto">
+    <pageSet>
+      <pageArea id="Page1" name="Page1">
+        <contentArea h="10.5in" w="8in" x="0.25in" y="0.25in"/>
+        <medium long="11in" short="8.5in" stock="letter"/>
+      </pageArea>
+    </pageSet>
+    <subform h="10.5in" w="8in" name="subform2">
+      <field h="10mm" name="choiceList0" w="50mm" x="5mm" y="50mm">
+        <ui>
+          <choiceList/>
+        </ui>
+        <items>
+          <text>Single</text>
+        </items>
+      </field>
+      <field name="choiceList1" h="200mm" w="200mm" x="1mm" y="1mm">
+        <ui>
+          <textEdit/>
+        </ui>
+        <value>
+          <text>pdfium</text>
+        </value>
+        <event activity="change">
+          <script contentType="application/x-javascript">
+            change_count += 1;
+            if (change_count == 2) {
+                f1 = xfa.resolveNode("xfa.form..choiceList0");
+                xfa.host.setFocus(f1);
+                xfa.template.remerge();
+                xfa.host.openList(f1);
+            }
+          </script>
+        </event>
+      </field>
+    </subform>
+    <event activity="docReady">
+      <script contentType="application/x-javascript">
+        change_count = 0;
+      </script>
+    </event>
+  </subform>
+</template>
+endstream
+endobj
+{{include xfa_locale_6_0.fragment}}
+{{include xfa_postamble_7_0.fragment}}
+{{include xfa_pages_8_0.fragment}}
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/bug_1055869.pdf b/testing/resources/bug_1055869.pdf
new file mode 100644
index 0000000..832d029
--- /dev/null
+++ b/testing/resources/bug_1055869.pdf
@@ -0,0 +1,271 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /AcroForm 2 0 R
+  /Extensions <<
+    /ADBE <<
+      /BaseVersion /1.7
+      /ExtensionLevel 8
+    >>
+  >>
+  /NeedsRendering true
+  /Pages 8 0 R
+  /Type /Catalog
+>>
+endobj
+2 0 obj <<
+  /XFA [
+    (preamble)
+    3 0 R
+    (config)
+    4 0 R
+    (template)
+    5 0 R
+    (localeSet)
+    6 0 R
+    (postamble)
+    7 0 R
+  ]
+>>
+endobj
+3 0 obj <<
+  /Length 124
+>>
+stream
+<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/" timeStamp="2018-02-23T21:37:11Z" uuid="21482798-7bf0-40a4-bc5d-3cefdccf32b5">
+endstream
+endobj
+4 0 obj <<
+  /Length 642
+>>
+stream
+<config xmlns="http://www.xfa.org/schema/xci/3.0/">
+<agent name="designer">
+  <destination>pdf</destination>
+  <pdf>
+    <fontInfo/>
+  </pdf>
+</agent>
+<present>
+  <pdf>
+    <version>1.7</version>
+    <adobeExtensionLevel>8</adobeExtensionLevel>
+    <renderPolicy>client</renderPolicy>
+    <scriptModel>XFA</scriptModel>
+    <interactive>1</interactive>
+  </pdf>
+  <xdp>
+    <packets>*</packets>
+  </xdp>
+  <destination>pdf</destination>
+  <script>
+    <runScripts>server</runScripts>
+  </script>
+</present>
+<acrobat>
+  <acrobat7>
+    <dynamicRender>required</dynamicRender>
+  </acrobat7>
+  <validate>preSubmit</validate>
+</acrobat>
+</config>
+endstream
+endobj
+5 0 obj <<
+  /Length 1361
+>>
+stream
+<template xmlns="http://www.xfa.org/schema/xfa-template/2.6/">
+  <subform layout="tb" locale="en_US" name="form1" restoreState="auto">
+    <pageSet>
+      <pageArea id="Page1" name="Page1">
+        <contentArea h="10.5in" w="8in" x="0.25in" y="0.25in"/>
+        <medium long="11in" short="8.5in" stock="letter"/>
+      </pageArea>
+    </pageSet>
+    <subform h="10.5in" w="8in" name="subform2">
+      <field h="10mm" name="choiceList0" w="50mm" x="5mm" y="50mm">
+        <ui>
+          <choiceList/>
+        </ui>
+        <items>
+          <text>Single</text>
+        </items>
+      </field>
+      <field name="choiceList1" h="200mm" w="200mm" x="1mm" y="1mm">
+        <ui>
+          <textEdit/>
+        </ui>
+        <value>
+          <text>pdfium</text>
+        </value>
+        <event activity="change">
+          <script contentType="application/x-javascript">
+            change_count += 1;
+            if (change_count == 2) {
+                f1 = xfa.resolveNode("xfa.form..choiceList0");
+                xfa.host.setFocus(f1);
+                xfa.template.remerge();
+                xfa.host.openList(f1);
+            }
+          </script>
+        </event>
+      </field>
+    </subform>
+    <event activity="docReady">
+      <script contentType="application/x-javascript">
+        change_count = 0;
+      </script>
+    </event>
+  </subform>
+</template>
+endstream
+endobj
+6 0 obj <<
+  /Length 3455
+>>
+stream
+<localeSet xmlns="http://www.xfa.org/schema/xfa-locale-set/2.7/">
+  <locale name="en_US" desc="English (United States)">
+    <calendarSymbols name="gregorian">
+      <monthNames>
+        <month>January</month>
+        <month>February</month>
+        <month>March</month>
+        <month>April</month>
+        <month>May</month>
+        <month>June</month>
+        <month>July</month>
+        <month>August</month>
+        <month>September</month>
+        <month>October</month>
+        <month>November</month>
+        <month>December</month>
+      </monthNames>
+      <monthNames abbr="1">
+        <month>Jan</month>
+        <month>Feb</month>
+        <month>Mar</month>
+        <month>Apr</month>
+        <month>May</month>
+        <month>Jun</month>
+        <month>Jul</month>
+        <month>Aug</month>
+        <month>Sep</month>
+        <month>Oct</month>
+        <month>Nov</month>
+        <month>Dec</month>
+      </monthNames>
+      <dayNames>
+        <day>Sunday</day>
+        <day>Monday</day>
+        <day>Tuesday</day>
+        <day>Wednesday</day>
+        <day>Thursday</day>
+        <day>Friday</day>
+        <day>Saturday</day>
+      </dayNames>
+      <dayNames abbr="1">
+        <day>Sun</day>
+        <day>Mon</day>
+        <day>Tue</day>
+        <day>Wed</day>
+        <day>Thu</day>
+        <day>Fri</day>
+        <day>Sat</day>
+      </dayNames>
+      <meridiemNames>
+        <meridiem>AM</meridiem>
+        <meridiem>PM</meridiem>
+      </meridiemNames>
+      <eraNames>
+        <era>BC</era>
+        <era>AD</era>
+      </eraNames>
+    </calendarSymbols>
+    <datePatterns>
+      <datePattern name="full">EEEE, MMMM D, YYYY</datePattern>
+      <datePattern name="long">MMMM D, YYYY</datePattern>
+      <datePattern name="med">MMM D, YYYY</datePattern>
+      <datePattern name="short">M/D/YY</datePattern>
+    </datePatterns>
+    <timePatterns>
+      <timePattern name="full">h:MM:SS A Z</timePattern>
+      <timePattern name="long">h:MM:SS A Z</timePattern>
+      <timePattern name="med">h:MM:SS A</timePattern>
+      <timePattern name="short">h:MM A</timePattern>
+    </timePatterns>
+    <dateTimeSymbols>GyMdkHmsSEDFwWahKzZ</dateTimeSymbols>
+    <numberPatterns>
+      <numberPattern name="numeric">z,zz9.zzz</numberPattern>
+      <numberPattern name="currency">$z,zz9.99|($z,zz9.99)</numberPattern>
+      <numberPattern name="percent">z,zz9%</numberPattern>
+    </numberPatterns>
+    <numberSymbols>
+      <numberSymbol name="decimal">.</numberSymbol>
+      <numberSymbol name="grouping">,</numberSymbol>
+      <numberSymbol name="percent">%</numberSymbol>
+      <numberSymbol name="minus">-</numberSymbol>
+      <numberSymbol name="zero">0</numberSymbol>
+    </numberSymbols>
+    <currencySymbols>
+      <currencySymbol name="symbol">$</currencySymbol>
+      <currencySymbol name="isoname">USD</currencySymbol>
+      <currencySymbol name="decimal">.</currencySymbol>
+    </currencySymbols>
+    <typefaces>
+      <typeface name="Myriad Pro"/>
+      <typeface name="Minion Pro"/>
+      <typeface name="Courier Std"/>
+      <typeface name="Adobe Pi Std"/>
+      <typeface name="Adobe Hebrew"/>
+      <typeface name="Adobe Arabic"/>
+      <typeface name="Adobe Thai"/>
+      <typeface name="Kozuka Gothic Pro-VI M"/>
+      <typeface name="Kozuka Mincho Pro-VI R"/>
+      <typeface name="Adobe Ming Std L"/>
+      <typeface name="Adobe Song Std L"/>
+      <typeface name="Adobe Myungjo Std M"/>
+    </typefaces>
+  </locale>
+</localeSet>
+endstream
+endobj
+7 0 obj <<
+  /Length 11
+>>
+stream
+</xdp:xdp>
+endstream
+endobj
+8 0 obj <<
+  /Type /Pages
+  /Count 1
+  /Kids [9 0 R]
+>>
+endobj
+9 0 obj <<
+  /Type /Page
+  /Parent 8 0 R
+  /MediaBox [0 0 612 792]
+>>
+endobj
+xref
+0 10
+0000000000 65535 f 
+0000000015 00000 n 
+0000000199 00000 n 
+0000000358 00000 n 
+0000000534 00000 n 
+0000001228 00000 n 
+0000002642 00000 n 
+0000006150 00000 n 
+0000006212 00000 n 
+0000006275 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 10
+>>
+startxref
+6352
+%%EOF
diff --git a/testing/resources/bug_1058653.in b/testing/resources/bug_1058653.in
new file mode 100644
index 0000000..5973c54
--- /dev/null
+++ b/testing/resources/bug_1058653.in
@@ -0,0 +1,73 @@
+{{header}}
+{{include xfa_catalog_1_0.fragment}}
+{{include xfa_object_2_0.fragment}}
+{{include xfa_preamble_3_0.fragment}}
+{{include xfa_config_4_0.fragment}}
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+<template xmlns="http://www.xfa.org/schema/xfa-template/2.6/">
+  <subform layout="tb" locale="en_US" name="form1" restoreState="auto">
+    <pageSet>
+      <pageArea id="Page1" name="Page1">
+        <contentArea h="10.5in" w="8in" x="0.25in" y="0.25in"/>
+        <medium long="11in" short="8.5in" stock="letter"/>
+      </pageArea>
+    </pageSet>
+    <subform h="10.5in" w="8in" name="subform2">
+      <field name="f1" h="10mm" w="10mm" x="20mm" y="20mm">
+        <ui>
+          <choiceList/>
+        </ui>
+        <items save="1">
+          <text>aaaaaaaaaa</text>
+        </items>
+      </field>
+      <subform name="f4" x="1mm" y="1mm">
+        <occur max="-1"/>
+        <field name="f2" h="350mm" w="200mm">
+          <ui>
+            <choiceList textEntry="1">
+            </choiceList>
+          </ui>
+          <items>
+                <text>Albania</text>
+                <text>Andorra</text>
+                <text>Armenia</text>
+          </items>
+          <event activity="change">
+            <script contentType="application/x-javascript">
+              a += 1;
+              if (a == 2) {
+                  c = xfa.resolveNode("xfa.form..f1");
+                  xfa.host.setFocus(c);
+                  d = xfa.resolveNode("xfa.form..f4");
+                  d.instanceManager.addInstance(1);
+                  d.instanceManager.removeInstance(0);
+                  xfa.host.openList(c);
+              }
+            </script>
+          </event>
+        </field>
+      </subform>
+    </subform>
+    <event activity="docReady">
+      <script contentType="application/x-javascript">
+        a = 0;
+        f2 = xfa.resolveNode("xfa.form..f2");
+        f2.rawValue = "minhtttttt";
+        xfa.host.setFocus(f2);
+      </script>
+    </event>
+  </subform>
+</template>
+endstream
+endobj
+{{include xfa_locale_6_0.fragment}}
+{{include xfa_postamble_7_0.fragment}}
+{{include xfa_pages_8_0.fragment}}
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/bug_1058653.pdf b/testing/resources/bug_1058653.pdf
new file mode 100644
index 0000000..f278dfb
--- /dev/null
+++ b/testing/resources/bug_1058653.pdf
@@ -0,0 +1,282 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /AcroForm 2 0 R
+  /Extensions <<
+    /ADBE <<
+      /BaseVersion /1.7
+      /ExtensionLevel 8
+    >>
+  >>
+  /NeedsRendering true
+  /Pages 8 0 R
+  /Type /Catalog
+>>
+endobj
+2 0 obj <<
+  /XFA [
+    (preamble)
+    3 0 R
+    (config)
+    4 0 R
+    (template)
+    5 0 R
+    (localeSet)
+    6 0 R
+    (postamble)
+    7 0 R
+  ]
+>>
+endobj
+3 0 obj <<
+  /Length 124
+>>
+stream
+<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/" timeStamp="2018-02-23T21:37:11Z" uuid="21482798-7bf0-40a4-bc5d-3cefdccf32b5">
+endstream
+endobj
+4 0 obj <<
+  /Length 642
+>>
+stream
+<config xmlns="http://www.xfa.org/schema/xci/3.0/">
+<agent name="designer">
+  <destination>pdf</destination>
+  <pdf>
+    <fontInfo/>
+  </pdf>
+</agent>
+<present>
+  <pdf>
+    <version>1.7</version>
+    <adobeExtensionLevel>8</adobeExtensionLevel>
+    <renderPolicy>client</renderPolicy>
+    <scriptModel>XFA</scriptModel>
+    <interactive>1</interactive>
+  </pdf>
+  <xdp>
+    <packets>*</packets>
+  </xdp>
+  <destination>pdf</destination>
+  <script>
+    <runScripts>server</runScripts>
+  </script>
+</present>
+<acrobat>
+  <acrobat7>
+    <dynamicRender>required</dynamicRender>
+  </acrobat7>
+  <validate>preSubmit</validate>
+</acrobat>
+</config>
+endstream
+endobj
+5 0 obj <<
+  /Length 1772
+>>
+stream
+<template xmlns="http://www.xfa.org/schema/xfa-template/2.6/">
+  <subform layout="tb" locale="en_US" name="form1" restoreState="auto">
+    <pageSet>
+      <pageArea id="Page1" name="Page1">
+        <contentArea h="10.5in" w="8in" x="0.25in" y="0.25in"/>
+        <medium long="11in" short="8.5in" stock="letter"/>
+      </pageArea>
+    </pageSet>
+    <subform h="10.5in" w="8in" name="subform2">
+      <field name="f1" h="10mm" w="10mm" x="20mm" y="20mm">
+        <ui>
+          <choiceList/>
+        </ui>
+        <items save="1">
+          <text>aaaaaaaaaa</text>
+        </items>
+      </field>
+      <subform name="f4" x="1mm" y="1mm">
+        <occur max="-1"/>
+        <field name="f2" h="350mm" w="200mm">
+          <ui>
+            <choiceList textEntry="1">
+            </choiceList>
+          </ui>
+          <items>
+                <text>Albania</text>
+                <text>Andorra</text>
+                <text>Armenia</text>
+          </items>
+          <event activity="change">
+            <script contentType="application/x-javascript">
+              a += 1;
+              if (a == 2) {
+                  c = xfa.resolveNode("xfa.form..f1");
+                  xfa.host.setFocus(c);
+                  d = xfa.resolveNode("xfa.form..f4");
+                  d.instanceManager.addInstance(1);
+                  d.instanceManager.removeInstance(0);
+                  xfa.host.openList(c);
+              }
+            </script>
+          </event>
+        </field>
+      </subform>
+    </subform>
+    <event activity="docReady">
+      <script contentType="application/x-javascript">
+        a = 0;
+        f2 = xfa.resolveNode("xfa.form..f2");
+        f2.rawValue = "minhtttttt";
+        xfa.host.setFocus(f2);
+      </script>
+    </event>
+  </subform>
+</template>
+endstream
+endobj
+6 0 obj <<
+  /Length 3455
+>>
+stream
+<localeSet xmlns="http://www.xfa.org/schema/xfa-locale-set/2.7/">
+  <locale name="en_US" desc="English (United States)">
+    <calendarSymbols name="gregorian">
+      <monthNames>
+        <month>January</month>
+        <month>February</month>
+        <month>March</month>
+        <month>April</month>
+        <month>May</month>
+        <month>June</month>
+        <month>July</month>
+        <month>August</month>
+        <month>September</month>
+        <month>October</month>
+        <month>November</month>
+        <month>December</month>
+      </monthNames>
+      <monthNames abbr="1">
+        <month>Jan</month>
+        <month>Feb</month>
+        <month>Mar</month>
+        <month>Apr</month>
+        <month>May</month>
+        <month>Jun</month>
+        <month>Jul</month>
+        <month>Aug</month>
+        <month>Sep</month>
+        <month>Oct</month>
+        <month>Nov</month>
+        <month>Dec</month>
+      </monthNames>
+      <dayNames>
+        <day>Sunday</day>
+        <day>Monday</day>
+        <day>Tuesday</day>
+        <day>Wednesday</day>
+        <day>Thursday</day>
+        <day>Friday</day>
+        <day>Saturday</day>
+      </dayNames>
+      <dayNames abbr="1">
+        <day>Sun</day>
+        <day>Mon</day>
+        <day>Tue</day>
+        <day>Wed</day>
+        <day>Thu</day>
+        <day>Fri</day>
+        <day>Sat</day>
+      </dayNames>
+      <meridiemNames>
+        <meridiem>AM</meridiem>
+        <meridiem>PM</meridiem>
+      </meridiemNames>
+      <eraNames>
+        <era>BC</era>
+        <era>AD</era>
+      </eraNames>
+    </calendarSymbols>
+    <datePatterns>
+      <datePattern name="full">EEEE, MMMM D, YYYY</datePattern>
+      <datePattern name="long">MMMM D, YYYY</datePattern>
+      <datePattern name="med">MMM D, YYYY</datePattern>
+      <datePattern name="short">M/D/YY</datePattern>
+    </datePatterns>
+    <timePatterns>
+      <timePattern name="full">h:MM:SS A Z</timePattern>
+      <timePattern name="long">h:MM:SS A Z</timePattern>
+      <timePattern name="med">h:MM:SS A</timePattern>
+      <timePattern name="short">h:MM A</timePattern>
+    </timePatterns>
+    <dateTimeSymbols>GyMdkHmsSEDFwWahKzZ</dateTimeSymbols>
+    <numberPatterns>
+      <numberPattern name="numeric">z,zz9.zzz</numberPattern>
+      <numberPattern name="currency">$z,zz9.99|($z,zz9.99)</numberPattern>
+      <numberPattern name="percent">z,zz9%</numberPattern>
+    </numberPatterns>
+    <numberSymbols>
+      <numberSymbol name="decimal">.</numberSymbol>
+      <numberSymbol name="grouping">,</numberSymbol>
+      <numberSymbol name="percent">%</numberSymbol>
+      <numberSymbol name="minus">-</numberSymbol>
+      <numberSymbol name="zero">0</numberSymbol>
+    </numberSymbols>
+    <currencySymbols>
+      <currencySymbol name="symbol">$</currencySymbol>
+      <currencySymbol name="isoname">USD</currencySymbol>
+      <currencySymbol name="decimal">.</currencySymbol>
+    </currencySymbols>
+    <typefaces>
+      <typeface name="Myriad Pro"/>
+      <typeface name="Minion Pro"/>
+      <typeface name="Courier Std"/>
+      <typeface name="Adobe Pi Std"/>
+      <typeface name="Adobe Hebrew"/>
+      <typeface name="Adobe Arabic"/>
+      <typeface name="Adobe Thai"/>
+      <typeface name="Kozuka Gothic Pro-VI M"/>
+      <typeface name="Kozuka Mincho Pro-VI R"/>
+      <typeface name="Adobe Ming Std L"/>
+      <typeface name="Adobe Song Std L"/>
+      <typeface name="Adobe Myungjo Std M"/>
+    </typefaces>
+  </locale>
+</localeSet>
+endstream
+endobj
+7 0 obj <<
+  /Length 11
+>>
+stream
+</xdp:xdp>
+endstream
+endobj
+8 0 obj <<
+  /Type /Pages
+  /Count 1
+  /Kids [9 0 R]
+>>
+endobj
+9 0 obj <<
+  /Type /Page
+  /Parent 8 0 R
+  /MediaBox [0 0 612 792]
+>>
+endobj
+xref
+0 10
+0000000000 65535 f 
+0000000015 00000 n 
+0000000199 00000 n 
+0000000358 00000 n 
+0000000534 00000 n 
+0000001228 00000 n 
+0000003053 00000 n 
+0000006561 00000 n 
+0000006623 00000 n 
+0000006686 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 10
+>>
+startxref
+6763
+%%EOF
diff --git a/testing/resources/bug_1124998.pdf b/testing/resources/bug_1124998.pdf
new file mode 100644
index 0000000..4368222
--- /dev/null
+++ b/testing/resources/bug_1124998.pdf
Binary files differ
diff --git a/testing/resources/bug_1229106.in b/testing/resources/bug_1229106.in
new file mode 100644
index 0000000..7ffe9bf
--- /dev/null
+++ b/testing/resources/bug_1229106.in
@@ -0,0 +1,68 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 4
+  /Kids [3 0 R 3 0 R 5 0 R 5 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 612 792]
+  /Rotate 90
+  /Contents 4 0 R
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+0 1 -1 0 792 0 cm
+0 0 0 rg
+100 400 150 50 re f
+1 0 0 rg
+0 180 100 50 re f
+0 1 0 rg
+0 742 100 50 re f
+0 0 1 rg
+692 742 100 50 re f
+1 0 1 rg
+692 180 100 50 re f
+Q
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 792 612]
+  /Contents 6 0 R
+>>
+endobj
+{{object 6 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+0 0 0 rg
+100 220 150 50 re f
+1 0 0 rg
+0 0 100 50 re f
+0 1 0 rg
+0 562 100 50 re f
+0 0 1 rg
+692 562 100 50 re f
+1 0 1 rg
+692 0 100 50 re f
+Q
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/bug_1229106.pdf b/testing/resources/bug_1229106.pdf
new file mode 100644
index 0000000..e0d625c
--- /dev/null
+++ b/testing/resources/bug_1229106.pdf
@@ -0,0 +1,81 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /Count 4
+  /Kids [3 0 R 3 0 R 5 0 R 5 0 R]
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 612 792]
+  /Rotate 90
+  /Contents 4 0 R
+>>
+endobj
+4 0 obj <<
+  /Length 163
+>>
+stream
+q
+0 1 -1 0 792 0 cm
+0 0 0 rg
+100 400 150 50 re f
+1 0 0 rg
+0 180 100 50 re f
+0 1 0 rg
+0 742 100 50 re f
+0 0 1 rg
+692 742 100 50 re f
+1 0 1 rg
+692 180 100 50 re f
+Q
+endstream
+endobj
+5 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 792 612]
+  /Contents 6 0 R
+>>
+endobj
+6 0 obj <<
+  /Length 141
+>>
+stream
+q
+0 0 0 rg
+100 220 150 50 re f
+1 0 0 rg
+0 0 100 50 re f
+0 1 0 rg
+0 562 100 50 re f
+0 0 1 rg
+692 562 100 50 re f
+1 0 1 rg
+692 0 100 50 re f
+Q
+endstream
+endobj
+xref
+0 7
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000149 00000 n 
+0000000257 00000 n 
+0000000472 00000 n 
+0000000567 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 7
+>>
+startxref
+760
+%%EOF
diff --git a/testing/resources/bug_1296920.in b/testing/resources/bug_1296920.in
new file mode 100644
index 0000000..5c9da58
--- /dev/null
+++ b/testing/resources/bug_1296920.in
@@ -0,0 +1,115 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /StructTreeRoot 6 0 R
+  /MarkInfo <<
+    /Marked true
+  >>
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Contents 4 0 R
+  /MediaBox [0 0 100 100]
+  /Parent 2 0 R
+  /Resources <<
+    /Font <<
+      /F1 5 0 R
+    >>
+  >>
+  /StructParents 0
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+/P <</MCID 1>> BDC
+BT
+/F1 12 Tf
+1 0 0 1 20 50 Tm
+(Hello) Tj
+ET
+EMC
+/P <</MCID 2>> BDC
+BT
+/F1 12 Tf
+1 0 0 1 50 50 Tm
+(World) Tj
+ET
+EMC
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+>>
+endobj
+{{object 6 0}} <<
+  /Type /StructTreeRoot
+  /K [9 0 R]
+  /ParentTree 7 0 R
+>>
+endobj
+{{object 7 0}} <<
+  /Nums [0 8 0 R 1 10 0 R]
+>>
+endobj
+{{object 8 0}}
+[12 0 R 13 0 R]
+endobj
+{{object 9 0}} <<
+  /Type /StructElem
+  /S /Document
+  /P 6 0 R
+  /K [10 0 R]
+>>
+endobj
+{{object 10 0}} <<
+  /Type /StructElem
+  /S /Part
+  /P 9 0 R
+  /K [11 0 R]
+>>
+endobj
+{{object 11 0}} <<
+  /Type /StructElem
+  /S /Div
+  /P 10 0 R
+  /K [12 0 R 13 0 R 14 0 R]
+>>
+endobj
+{{object 12 0}} <<
+  /Type /StructElem
+  /S /P
+  /P 11 0 R
+  /K 1
+  /Pg 3 0 R
+>>
+endobj
+{{object 13 0}} <<
+  /Type /StructElem
+  /S /P
+  /P 11 0 R
+  /K 2
+  /Pg 3 0 R
+>>
+endobj
+{{object 14 0}} <<
+  /Type /StructElem
+  /S /Div
+  /P 11 0 R
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/bug_1296920.pdf b/testing/resources/bug_1296920.pdf
new file mode 100644
index 0000000..92d778c
--- /dev/null
+++ b/testing/resources/bug_1296920.pdf
@@ -0,0 +1,136 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /StructTreeRoot 6 0 R
+  /MarkInfo <<
+    /Marked true
+  >>
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Contents 4 0 R
+  /MediaBox [0 0 100 100]
+  /Parent 2 0 R
+  /Resources <<
+    /Font <<
+      /F1 5 0 R
+    >>
+  >>
+  /StructParents 0
+>>
+endobj
+4 0 obj <<
+  /Length 134
+>>
+stream
+/P <</MCID 1>> BDC
+BT
+/F1 12 Tf
+1 0 0 1 20 50 Tm
+(Hello) Tj
+ET
+EMC
+/P <</MCID 2>> BDC
+BT
+/F1 12 Tf
+1 0 0 1 50 50 Tm
+(World) Tj
+ET
+EMC
+endstream
+endobj
+5 0 obj <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+>>
+endobj
+6 0 obj <<
+  /Type /StructTreeRoot
+  /K [9 0 R]
+  /ParentTree 7 0 R
+>>
+endobj
+7 0 obj <<
+  /Nums [0 8 0 R 1 10 0 R]
+>>
+endobj
+8 0 obj
+[12 0 R 13 0 R]
+endobj
+9 0 obj <<
+  /Type /StructElem
+  /S /Document
+  /P 6 0 R
+  /K [10 0 R]
+>>
+endobj
+10 0 obj <<
+  /Type /StructElem
+  /S /Part
+  /P 9 0 R
+  /K [11 0 R]
+>>
+endobj
+11 0 obj <<
+  /Type /StructElem
+  /S /Div
+  /P 10 0 R
+  /K [12 0 R 13 0 R 14 0 R]
+>>
+endobj
+12 0 obj <<
+  /Type /StructElem
+  /S /P
+  /P 11 0 R
+  /K 1
+  /Pg 3 0 R
+>>
+endobj
+13 0 obj <<
+  /Type /StructElem
+  /S /P
+  /P 11 0 R
+  /K 2
+  /Pg 3 0 R
+>>
+endobj
+14 0 obj <<
+  /Type /StructElem
+  /S /Div
+  /P 11 0 R
+>>
+endobj
+xref
+0 15
+0000000000 65535 f 
+0000000015 00000 n 
+0000000129 00000 n 
+0000000192 00000 n 
+0000000363 00000 n 
+0000000549 00000 n 
+0000000625 00000 n 
+0000000703 00000 n 
+0000000751 00000 n 
+0000000782 00000 n 
+0000000863 00000 n 
+0000000941 00000 n 
+0000001033 00000 n 
+0000001114 00000 n 
+0000001195 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 15
+>>
+startxref
+1259
+%%EOF
diff --git a/testing/resources/bug_1301.pdf b/testing/resources/bug_1301.pdf
index 285c7f7..8c6e45f 100644
--- a/testing/resources/bug_1301.pdf
+++ b/testing/resources/bug_1301.pdf
@@ -217,7 +217,7 @@
 endobj
 9 0 obj <<
   /Type /Page
-  /Parent 2 0 R
+  /Parent 8 0 R
   /MediaBox [0 0 612 792]
 >>
 endobj
diff --git a/testing/resources/bug_1302455.in b/testing/resources/bug_1302455.in
new file mode 100644
index 0000000..1e18f12
--- /dev/null
+++ b/testing/resources/bug_1302455.in
@@ -0,0 +1,75 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /DR 4 0 R
+    /Fields [6 0 R 7 0 R]
+  >>
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Kids [3 0 R]
+  /Count 1
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Annots [6 0 R 7 0 R]
+  /MediaBox [0 0 300 300]
+  /Resources 4 0 R
+>>
+endobj
+{{object 4 0}} <<
+  /Font <<
+    /F1 5 0 R
+  >>
+>>
+endobj
+{{object 5 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+>>
+endobj
+{{object 6 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Tx
+  /AP <<
+    /N 8 0 R
+  >>
+  /F 4
+  /Rect [100 100 200 130]
+  /T (Text Box 1)
+>>
+endobj
+{{object 7 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Tx
+  /AP <<
+    /N 8 0 R
+  >>
+  /F 4
+  /Rect [100 160 200 190]
+  /T (Text Box 2)
+>>
+endobj
+{{object 8 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /BBox [0 0 100 30]
+  {{streamlen}}
+>>
+stream
+1 0 0 rg
+0 0 100 30 re f
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/bug_1302455.pdf b/testing/resources/bug_1302455.pdf
new file mode 100644
index 0000000..a9782c4
--- /dev/null
+++ b/testing/resources/bug_1302455.pdf
@@ -0,0 +1,90 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /DR 4 0 R
+    /Fields [6 0 R 7 0 R]
+  >>
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /Kids [3 0 R]
+  /Count 1
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Annots [6 0 R 7 0 R]
+  /MediaBox [0 0 300 300]
+  /Resources 4 0 R
+>>
+endobj
+4 0 obj <<
+  /Font <<
+    /F1 5 0 R
+  >>
+>>
+endobj
+5 0 obj <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+>>
+endobj
+6 0 obj <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Tx
+  /AP <<
+    /N 8 0 R
+  >>
+  /F 4
+  /Rect [100 100 200 130]
+  /T (Text Box 1)
+>>
+endobj
+7 0 obj <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Tx
+  /AP <<
+    /N 8 0 R
+  >>
+  /F 4
+  /Rect [100 160 200 190]
+  /T (Text Box 2)
+>>
+endobj
+8 0 obj <<
+  /Type /XObject
+  /Subtype /Form
+  /BBox [0 0 100 30]
+  /Length 25
+>>
+stream
+1 0 0 rg
+0 0 100 30 re f
+endstream
+endobj
+xref
+0 9
+0000000000 65535 f 
+0000000015 00000 n 
+0000000128 00000 n 
+0000000191 00000 n 
+0000000311 00000 n 
+0000000362 00000 n 
+0000000438 00000 n 
+0000000581 00000 n 
+0000000724 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 9
+>>
+startxref
+855
+%%EOF
diff --git a/testing/resources/bug_1324189.in b/testing/resources/bug_1324189.in
new file mode 100644
index 0000000..45fceba
--- /dev/null
+++ b/testing/resources/bug_1324189.in
@@ -0,0 +1,16 @@
+{{header}}
+{{object 1 0}} <
+  /Type /Catalog
+>>
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
+{{xref}}
+trailer <<
+  /Root 1 0 R
+  /Prev -200
+  {{trailersize}}
+>>
+{{startxref}}
+%%EOF
diff --git a/testing/resources/bug_1324189.pdf b/testing/resources/bug_1324189.pdf
new file mode 100644
index 0000000..9652398
--- /dev/null
+++ b/testing/resources/bug_1324189.pdf
@@ -0,0 +1,28 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <
+  /Type /Catalog
+>>
+xref
+0 2
+0000000000 65535 f 
+0000000015 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 2
+>>
+startxref
+45
+%%EOF
+xref
+0 2
+0000000000 65535 f 
+0000000015 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Prev -200
+  /Size 2
+>>
+startxref
+151
+%%EOF
diff --git a/testing/resources/bug_1324503.in b/testing/resources/bug_1324503.in
new file mode 100644
index 0000000..a46d142
--- /dev/null
+++ b/testing/resources/bug_1324503.in
@@ -0,0 +1,16 @@
+{{header}}
+{{object 1 0}} <
+  /Type /Catalog
+>>
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
+{{xref}}
+trailer <<
+  /Root 1 0 R
+  /XRefStm -1
+  {{trailersize}}
+>>
+{{startxref}}
+%%EOF
diff --git a/testing/resources/bug_1324503.pdf b/testing/resources/bug_1324503.pdf
new file mode 100644
index 0000000..2ce7425
--- /dev/null
+++ b/testing/resources/bug_1324503.pdf
@@ -0,0 +1,28 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <
+  /Type /Catalog
+>>
+xref
+0 2
+0000000000 65535 f 
+0000000015 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 2
+>>
+startxref
+45
+%%EOF
+xref
+0 2
+0000000000 65535 f 
+0000000015 00000 n 
+trailer <<
+  /Root 1 0 R
+  /XRefStm -1
+  /Size 2
+>>
+startxref
+151
+%%EOF
diff --git a/testing/resources/bug_1327884.pdf b/testing/resources/bug_1327884.pdf
new file mode 100644
index 0000000..0e28c06
--- /dev/null
+++ b/testing/resources/bug_1327884.pdf
@@ -0,0 +1,6 @@
+%PDF
+1 0 obj<</Pages 2 0 R/AcroForm<</XFA 30 0 R>>>>2 0 obj<</>
+30 0 obj<<>>stream
+<xdp xmlns="http://ns.adobe.com/xdp/"><con0ig><acrobat><acrobat0></acrobat0></acrobat></con0ig><template><desc e=""use=" .[use=&quot;*&quot;]"
+endobj
+trailer<</Root 1 0 R>>
\ No newline at end of file
diff --git a/testing/resources/bug_1328389.in b/testing/resources/bug_1328389.in
new file mode 100644
index 0000000..3370ce7
--- /dev/null
+++ b/testing/resources/bug_1328389.in
@@ -0,0 +1,24 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Kids [3 0 R]
+  /Count 1
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 100 100]
+  % https://crbug.com/1328389
+  /Foo /
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/bug_1328389.pdf b/testing/resources/bug_1328389.pdf
new file mode 100644
index 0000000..e45a7a8
--- /dev/null
+++ b/testing/resources/bug_1328389.pdf
@@ -0,0 +1,34 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /Kids [3 0 R]
+  /Count 1
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 100 100]
+  % https://crbug.com/1328389
+  /Foo /
+>>
+endobj
+xref
+0 4
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000131 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 4
+>>
+startxref
+247
+%%EOF
diff --git a/testing/resources/bug_1333298.in b/testing/resources/bug_1333298.in
new file mode 100644
index 0000000..5b45ed9
--- /dev/null
+++ b/testing/resources/bug_1333298.in
@@ -0,0 +1,28 @@
+{{header}}
+{{include xfa_catalog_1_0.fragment}}
+{{include xfa_object_2_0.fragment}}
+{{include xfa_preamble_3_0.fragment}}
+{{include xfa_config_4_0.fragment}}
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+<template>
+  <subform>
+    <desc name="N01" use=" .[N01.use=&quot; .[N01.#use]&quot;]"/>
+    <proto>
+      <proto>
+        <bindItems/>
+      </proto>
+    </proto>
+  </subform>
+</template>
+endstream
+endobj
+{{include xfa_locale_6_0.fragment}}
+{{include xfa_postamble_7_0.fragment}}
+{{include xfa_pages_8_0.fragment}}
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/bug_1333298.pdf b/testing/resources/bug_1333298.pdf
new file mode 100644
index 0000000..c003ca9
--- /dev/null
+++ b/testing/resources/bug_1333298.pdf
@@ -0,0 +1,237 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /AcroForm 2 0 R
+  /Extensions <<
+    /ADBE <<
+      /BaseVersion /1.7
+      /ExtensionLevel 8
+    >>
+  >>
+  /NeedsRendering true
+  /Pages 8 0 R
+  /Type /Catalog
+>>
+endobj
+2 0 obj <<
+  /XFA [
+    (preamble)
+    3 0 R
+    (config)
+    4 0 R
+    (template)
+    5 0 R
+    (localeSet)
+    6 0 R
+    (postamble)
+    7 0 R
+  ]
+>>
+endobj
+3 0 obj <<
+  /Length 124
+>>
+stream
+<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/" timeStamp="2018-02-23T21:37:11Z" uuid="21482798-7bf0-40a4-bc5d-3cefdccf32b5">
+endstream
+endobj
+4 0 obj <<
+  /Length 642
+>>
+stream
+<config xmlns="http://www.xfa.org/schema/xci/3.0/">
+<agent name="designer">
+  <destination>pdf</destination>
+  <pdf>
+    <fontInfo/>
+  </pdf>
+</agent>
+<present>
+  <pdf>
+    <version>1.7</version>
+    <adobeExtensionLevel>8</adobeExtensionLevel>
+    <renderPolicy>client</renderPolicy>
+    <scriptModel>XFA</scriptModel>
+    <interactive>1</interactive>
+  </pdf>
+  <xdp>
+    <packets>*</packets>
+  </xdp>
+  <destination>pdf</destination>
+  <script>
+    <runScripts>server</runScripts>
+  </script>
+</present>
+<acrobat>
+  <acrobat7>
+    <dynamicRender>required</dynamicRender>
+  </acrobat7>
+  <validate>preSubmit</validate>
+</acrobat>
+</config>
+endstream
+endobj
+5 0 obj <<
+  /Length 189
+>>
+stream
+<template>
+  <subform>
+    <desc name="N01" use=" .[N01.use=&quot; .[N01.#use]&quot;]"/>
+    <proto>
+      <proto>
+        <bindItems/>
+      </proto>
+    </proto>
+  </subform>
+</template>
+endstream
+endobj
+6 0 obj <<
+  /Length 3455
+>>
+stream
+<localeSet xmlns="http://www.xfa.org/schema/xfa-locale-set/2.7/">
+  <locale name="en_US" desc="English (United States)">
+    <calendarSymbols name="gregorian">
+      <monthNames>
+        <month>January</month>
+        <month>February</month>
+        <month>March</month>
+        <month>April</month>
+        <month>May</month>
+        <month>June</month>
+        <month>July</month>
+        <month>August</month>
+        <month>September</month>
+        <month>October</month>
+        <month>November</month>
+        <month>December</month>
+      </monthNames>
+      <monthNames abbr="1">
+        <month>Jan</month>
+        <month>Feb</month>
+        <month>Mar</month>
+        <month>Apr</month>
+        <month>May</month>
+        <month>Jun</month>
+        <month>Jul</month>
+        <month>Aug</month>
+        <month>Sep</month>
+        <month>Oct</month>
+        <month>Nov</month>
+        <month>Dec</month>
+      </monthNames>
+      <dayNames>
+        <day>Sunday</day>
+        <day>Monday</day>
+        <day>Tuesday</day>
+        <day>Wednesday</day>
+        <day>Thursday</day>
+        <day>Friday</day>
+        <day>Saturday</day>
+      </dayNames>
+      <dayNames abbr="1">
+        <day>Sun</day>
+        <day>Mon</day>
+        <day>Tue</day>
+        <day>Wed</day>
+        <day>Thu</day>
+        <day>Fri</day>
+        <day>Sat</day>
+      </dayNames>
+      <meridiemNames>
+        <meridiem>AM</meridiem>
+        <meridiem>PM</meridiem>
+      </meridiemNames>
+      <eraNames>
+        <era>BC</era>
+        <era>AD</era>
+      </eraNames>
+    </calendarSymbols>
+    <datePatterns>
+      <datePattern name="full">EEEE, MMMM D, YYYY</datePattern>
+      <datePattern name="long">MMMM D, YYYY</datePattern>
+      <datePattern name="med">MMM D, YYYY</datePattern>
+      <datePattern name="short">M/D/YY</datePattern>
+    </datePatterns>
+    <timePatterns>
+      <timePattern name="full">h:MM:SS A Z</timePattern>
+      <timePattern name="long">h:MM:SS A Z</timePattern>
+      <timePattern name="med">h:MM:SS A</timePattern>
+      <timePattern name="short">h:MM A</timePattern>
+    </timePatterns>
+    <dateTimeSymbols>GyMdkHmsSEDFwWahKzZ</dateTimeSymbols>
+    <numberPatterns>
+      <numberPattern name="numeric">z,zz9.zzz</numberPattern>
+      <numberPattern name="currency">$z,zz9.99|($z,zz9.99)</numberPattern>
+      <numberPattern name="percent">z,zz9%</numberPattern>
+    </numberPatterns>
+    <numberSymbols>
+      <numberSymbol name="decimal">.</numberSymbol>
+      <numberSymbol name="grouping">,</numberSymbol>
+      <numberSymbol name="percent">%</numberSymbol>
+      <numberSymbol name="minus">-</numberSymbol>
+      <numberSymbol name="zero">0</numberSymbol>
+    </numberSymbols>
+    <currencySymbols>
+      <currencySymbol name="symbol">$</currencySymbol>
+      <currencySymbol name="isoname">USD</currencySymbol>
+      <currencySymbol name="decimal">.</currencySymbol>
+    </currencySymbols>
+    <typefaces>
+      <typeface name="Myriad Pro"/>
+      <typeface name="Minion Pro"/>
+      <typeface name="Courier Std"/>
+      <typeface name="Adobe Pi Std"/>
+      <typeface name="Adobe Hebrew"/>
+      <typeface name="Adobe Arabic"/>
+      <typeface name="Adobe Thai"/>
+      <typeface name="Kozuka Gothic Pro-VI M"/>
+      <typeface name="Kozuka Mincho Pro-VI R"/>
+      <typeface name="Adobe Ming Std L"/>
+      <typeface name="Adobe Song Std L"/>
+      <typeface name="Adobe Myungjo Std M"/>
+    </typefaces>
+  </locale>
+</localeSet>
+endstream
+endobj
+7 0 obj <<
+  /Length 11
+>>
+stream
+</xdp:xdp>
+endstream
+endobj
+8 0 obj <<
+  /Type /Pages
+  /Count 1
+  /Kids [9 0 R]
+>>
+endobj
+9 0 obj <<
+  /Type /Page
+  /Parent 8 0 R
+  /MediaBox [0 0 612 792]
+>>
+endobj
+xref
+0 10
+0000000000 65535 f 
+0000000015 00000 n 
+0000000199 00000 n 
+0000000358 00000 n 
+0000000534 00000 n 
+0000001228 00000 n 
+0000001469 00000 n 
+0000004977 00000 n 
+0000005039 00000 n 
+0000005102 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 10
+>>
+startxref
+5179
+%%EOF
diff --git a/testing/resources/bug_1388_2.pdf b/testing/resources/bug_1388_2.pdf
new file mode 100644
index 0000000..1fee088
--- /dev/null
+++ b/testing/resources/bug_1388_2.pdf
@@ -0,0 +1,80 @@
+%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 200 200]
+  /Resources <<
+    /ProcSet [/PDF /Text]
+    /Font <<
+      /TT2 5 0 R
+    >>
+  >>
+>>
+endobj
+4 0 obj <<
+  /Length 40
+>>
+stream
+BT
+/TT2 12 Tf
+40 100 Td
+[(X  X)] TJ
+ET
+endstream
+endobj
+5 0 obj <<
+  /Type /Font
+  /Subtype /TrueType
+  /BaseFont /TimesNewRomanPSMT
+  /Encoding /WinAnsiEncoding
+  /FirstChar 31
+  /FontDescriptor 6 0 R
+  /LastChar 252
+>>
+endobj
+6 0 obj <<
+  /Type /FontDescriptor
+  /Ascent 891
+  /CapHeight 656
+  /Descent -216
+  /Flags 34
+  /FontBBox [-568 -307 2000 1007]
+  /FontFamily (Times New Roman)
+  /FontName /TimesNewRomanPSMT
+  /FontStretch /Normal
+  /FontWeight 400
+  /ItalicAngle 0
+  /MissingWidth 778
+  /StemV 82
+  /XHeight -546
+>>
+endobj
+xref
+0 7
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000131 00000 n 
+0000000310 00000 n 
+0000000401 00000 n 
+0000000573 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 7
+>>
+startxref
+880
+%%EOF
diff --git a/testing/resources/bug_1396264.in b/testing/resources/bug_1396264.in
new file mode 100644
index 0000000..db1fc5a
--- /dev/null
+++ b/testing/resources/bug_1396264.in
@@ -0,0 +1,86 @@
+{{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 100 200]
+  /Resources <<
+    /XObject <<
+      % Both images are BGRA.
+      /ImBlue 5 0 R
+      /ImRed 6 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+100 0 0 100 0 0 cm
+/ImBlue Do
+Q
+q
+100 0 0 100 0 100 cm
+/ImRed Do
+Q
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter [/ASCIIHexDecode /JPXDecode]
+  /Height 64
+  /Width 64
+  {{streamlen}}
+>>
+stream
+0000000c6a5020200d0a870a00000014667479706a703220000000006a7032200000004f6a7032
+68000000166968647200000040000000400004070700000000000f636f6c720100000000001000
+000022636465660004000000000001000100000002000200000003000300010000000000c06a70
+3263ff4fff51003200000000004000000040000000000000000000000040000000400000000000
+0000000004070101070101070101070101ff52000c00000001010504040001ff5c001340404848
+50484850484850484850484850ff640025000143726561746564206279204f70656e4a50454720
+76657273696f6e20322e332e30ff90000a0000000000360001ff93cfb41008908a6fdf801801ca
+bf00cfb40c01cabf0000000000000000000000000000000000000000ffd9
+endstream
+endobj
+{{object 6 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter [/ASCIIHexDecode /JPXDecode]
+  /Height 64
+  /Width 64
+  {{streamlen}}
+>>
+stream
+0000000c6a5020200d0a870a00000014667479706a703220000000006a7032200000004f6a7032
+68000000166968647200000040000000400004070700000000000f636f6c720100000000001000
+000022636465660004000000000001000100000002000200000003000300010000000000c06a70
+3263ff4fff51003200000000004000000040000000000000000000000040000000400000000000
+0000000004070101070101070101070101ff52000c00000001010504040001ff5c001340404848
+50484850484850484850484850ff640025000143726561746564206279204f70656e4a50454720
+76657273696f6e20322e332e30ff90000a0000000000360001ff93cfb41008908a6f00df801801
+cabfcfb40c01cabf0000000000000000000000000000000000000000ffd9
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/bug_1396264.pdf b/testing/resources/bug_1396264.pdf
new file mode 100644
index 0000000..9c2bddc
--- /dev/null
+++ b/testing/resources/bug_1396264.pdf
@@ -0,0 +1,99 @@
+%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 100 200]
+  /Resources <<
+    /XObject <<
+      % Both images are BGRA.
+      /ImBlue 5 0 R
+      /ImRed 6 0 R
+    >>
+  >>
+>>
+endobj
+4 0 obj <<
+  /Length 69
+>>
+stream
+q
+100 0 0 100 0 0 cm
+/ImBlue Do
+Q
+q
+100 0 0 100 0 100 cm
+/ImRed Do
+Q
+endstream
+endobj
+5 0 obj <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter [/ASCIIHexDecode /JPXDecode]
+  /Height 64
+  /Width 64
+  /Length 614
+>>
+stream
+0000000c6a5020200d0a870a00000014667479706a703220000000006a7032200000004f6a7032
+68000000166968647200000040000000400004070700000000000f636f6c720100000000001000
+000022636465660004000000000001000100000002000200000003000300010000000000c06a70
+3263ff4fff51003200000000004000000040000000000000000000000040000000400000000000
+0000000004070101070101070101070101ff52000c00000001010504040001ff5c001340404848
+50484850484850484850484850ff640025000143726561746564206279204f70656e4a50454720
+76657273696f6e20322e332e30ff90000a0000000000360001ff93cfb41008908a6fdf801801ca
+bf00cfb40c01cabf0000000000000000000000000000000000000000ffd9
+endstream
+endobj
+6 0 obj <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter [/ASCIIHexDecode /JPXDecode]
+  /Height 64
+  /Width 64
+  /Length 614
+>>
+stream
+0000000c6a5020200d0a870a00000014667479706a703220000000006a7032200000004f6a7032
+68000000166968647200000040000000400004070700000000000f636f6c720100000000001000
+000022636465660004000000000001000100000002000200000003000300010000000000c06a70
+3263ff4fff51003200000000004000000040000000000000000000000040000000400000000000
+0000000004070101070101070101070101ff52000c00000001010504040001ff5c001340404848
+50484850484850484850484850ff640025000143726561746564206279204f70656e4a50454720
+76657273696f6e20322e332e30ff90000a0000000000360001ff93cfb41008908a6f00df801801
+cabfcfb40c01cabf0000000000000000000000000000000000000000ffd9
+endstream
+endobj
+xref
+0 7
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000131 00000 n 
+0000000339 00000 n 
+0000000459 00000 n 
+0000001271 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 7
+>>
+startxref
+2083
+%%EOF
diff --git a/testing/resources/bug_1469.jp2 b/testing/resources/bug_1469.jp2
new file mode 100644
index 0000000..b84a029
--- /dev/null
+++ b/testing/resources/bug_1469.jp2
Binary files differ
diff --git a/testing/resources/bug_1506.in b/testing/resources/bug_1506.in
new file mode 100644
index 0000000..63c4c4d
--- /dev/null
+++ b/testing/resources/bug_1506.in
@@ -0,0 +1,60 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /Names <<
+    /Dests 7 0 R
+  >>
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 4
+  /Kids [
+    3 0 R
+    4 0 R
+  ]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Pages
+  /Parent 2 0 R
+  /Count 2
+  /Kids [
+    5 0 R
+    5 0 R
+  ]
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Pages
+  /Parent 2 0 R
+  /Count 2
+  /Kids [
+    5 0 R
+    6 0 R
+  ]
+>>
+endobj
+{{object 5 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 100 200]
+>>
+endobj
+{{object 6 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 100 300]
+>>
+endobj
+{{object 7 0}} <<
+  /Names [
+    (First) [6 0 R]
+  ]
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/bug_1506.pdf b/testing/resources/bug_1506.pdf
new file mode 100644
index 0000000..7395fe1
--- /dev/null
+++ b/testing/resources/bug_1506.pdf
@@ -0,0 +1,74 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /Names <<
+    /Dests 7 0 R
+  >>
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /Count 4
+  /Kids [
+    3 0 R
+    4 0 R
+  ]
+>>
+endobj
+3 0 obj <<
+  /Type /Pages
+  /Parent 2 0 R
+  /Count 2
+  /Kids [
+    5 0 R
+    5 0 R
+  ]
+>>
+endobj
+4 0 obj <<
+  /Type /Pages
+  /Parent 2 0 R
+  /Count 2
+  /Kids [
+    5 0 R
+    6 0 R
+  ]
+>>
+endobj
+5 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 100 200]
+>>
+endobj
+6 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 100 300]
+>>
+endobj
+7 0 obj <<
+  /Names [
+    (First) [6 0 R]
+  ]
+>>
+endobj
+xref
+0 8
+0000000000 65535 f 
+0000000015 00000 n 
+0000000102 00000 n 
+0000000183 00000 n 
+0000000280 00000 n 
+0000000377 00000 n 
+0000000454 00000 n 
+0000000531 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 8
+>>
+startxref
+587
+%%EOF
diff --git a/testing/resources/bug_1549.in b/testing/resources/bug_1549.in
new file mode 100644
index 0000000..18285ca
--- /dev/null
+++ b/testing/resources/bug_1549.in
@@ -0,0 +1,63 @@
+{{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
+  /MediaBox [0 0 100 150]
+  /Contents 4 0 R
+  /Resources 5 0 R
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+20 0 0 20 0 100 cm
+/Im1 Do
+Q
+BT
+/Cs1 cs
+1 0 0 0 scn
+30 20 50 40 re f
+ET
+endstream
+endobj
+{{object 5 0}} <<
+  /ColorSpace <<
+    /Cs1 /DeviceCMYK
+  >>
+  /ProcSet [/PDF /ImageB]
+  /XObject <<
+    /Im1 6 0 R
+  >>
+>>
+endobj
+{{object 6 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 1
+  /Height 1
+  /BitsPerComponent 8
+  /ColorSpace /DeviceGray
+  /Filter /ASCIIHexDecode
+  {{streamlen}}
+>>
+stream
+33
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/bug_1549.pdf b/testing/resources/bug_1549.pdf
new file mode 100644
index 0000000..946ba43
--- /dev/null
+++ b/testing/resources/bug_1549.pdf
@@ -0,0 +1,76 @@
+%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
+  /MediaBox [0 0 100 150]
+  /Contents 4 0 R
+  /Resources 5 0 R
+>>
+endobj
+4 0 obj <<
+  /Length 74
+>>
+stream
+q
+20 0 0 20 0 100 cm
+/Im1 Do
+Q
+BT
+/Cs1 cs
+1 0 0 0 scn
+30 20 50 40 re f
+ET
+endstream
+endobj
+5 0 obj <<
+  /ColorSpace <<
+    /Cs1 /DeviceCMYK
+  >>
+  /ProcSet [/PDF /ImageB]
+  /XObject <<
+    /Im1 6 0 R
+  >>
+>>
+endobj
+6 0 obj <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 1
+  /Height 1
+  /BitsPerComponent 8
+  /ColorSpace /DeviceGray
+  /Filter /ASCIIHexDecode
+  /Length 3
+>>
+stream
+33
+endstream
+endobj
+xref
+0 7
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000131 00000 n 
+0000000245 00000 n 
+0000000370 00000 n 
+0000000494 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 7
+>>
+startxref
+679
+%%EOF
diff --git a/testing/resources/bug_1558.in b/testing/resources/bug_1558.in
new file mode 100644
index 0000000..439038c
--- /dev/null
+++ b/testing/resources/bug_1558.in
@@ -0,0 +1,54 @@
+{{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
+    >>
+  >>
+  /Contents 5 0 R
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Times-Roman
+>>
+endobj
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+12 40 100 30 re
+W
+n
+0 g
+BT
+20 100 Td
+/F1 12 Tf
+(Clipped Text) Tj
+0 -50 Td
+/F1 12 Tf
+(Unclipped Text) Tj
+ET
+Q
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/bug_1558.pdf b/testing/resources/bug_1558.pdf
new file mode 100644
index 0000000..2feec46
--- /dev/null
+++ b/testing/resources/bug_1558.pdf
@@ -0,0 +1,66 @@
+%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
+    >>
+  >>
+  /Contents 5 0 R
+>>
+endobj
+4 0 obj <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Times-Roman
+>>
+endobj
+5 0 obj <<
+  /Length 111
+>>
+stream
+q
+12 40 100 30 re
+W
+n
+0 g
+BT
+20 100 Td
+/F1 12 Tf
+(Clipped Text) Tj
+0 -50 Td
+/F1 12 Tf
+(Unclipped Text) Tj
+ET
+Q
+endstream
+endobj
+xref
+0 6
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000157 00000 n 
+0000000283 00000 n 
+0000000361 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 6
+>>
+startxref
+524
+%%EOF
diff --git a/testing/resources/bug_1574.in b/testing/resources/bug_1574.in
new file mode 100644
index 0000000..5d7a08d
--- /dev/null
+++ b/testing/resources/bug_1574.in
@@ -0,0 +1,60 @@
+{{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
+  /MediaBox [0 0 200 300]
+  /Resources <<
+    /Font <<
+      /F1 4 0 R
+    >>
+  >>
+  /Contents 5 0 R
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Times-Roman
+>>
+endobj
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+0 0 50 75 re
+W* n
+1 1 1 rg
+0 150 m
+100 150 l
+100 0 l
+0 0 l
+0 150 l
+h
+f*
+q
+0 0 0 rg
+BT
+20 50 Td
+/F1 12 Tf
+(Text) Tj
+ET
+Q
+Q
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/bug_1574.pdf b/testing/resources/bug_1574.pdf
new file mode 100644
index 0000000..df27418
--- /dev/null
+++ b/testing/resources/bug_1574.pdf
@@ -0,0 +1,72 @@
+%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
+  /MediaBox [0 0 200 300]
+  /Resources <<
+    /Font <<
+      /F1 4 0 R
+    >>
+  >>
+  /Contents 5 0 R
+>>
+endobj
+4 0 obj <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Times-Roman
+>>
+endobj
+5 0 obj <<
+  /Length 124
+>>
+stream
+q
+0 0 50 75 re
+W* n
+1 1 1 rg
+0 150 m
+100 150 l
+100 0 l
+0 0 l
+0 150 l
+h
+f*
+q
+0 0 0 rg
+BT
+20 50 Td
+/F1 12 Tf
+(Text) Tj
+ET
+Q
+Q
+endstream
+endobj
+xref
+0 6
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000131 00000 n 
+0000000283 00000 n 
+0000000361 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 6
+>>
+startxref
+537
+%%EOF
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
diff --git a/testing/resources/bug_1646.pdf b/testing/resources/bug_1646.pdf
new file mode 100644
index 0000000..8728c1b
--- /dev/null
+++ b/testing/resources/bug_1646.pdf
@@ -0,0 +1,77 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Pages
+  /Count 1
+  /Kids[ 3 0 R ]
+>>
+endobj
+2 0 obj <<
+  /Type /Catalog
+  /Pages 1 0 R
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 1 0 R
+  /Resources 6 0 R
+  /MediaBox[ 0 0 64 64]
+  /Contents[ 5 0 R ]
+>>
+endobj
+4 0 obj <<
+  /Type /XObject
+  /Subtype /Image
+  /Name /I1
+  /Width 5000
+  /Height 5000
+  /BitsPerComponent 8
+  /ColorSpace /DeviceCMYK
+  /Filter [/ASCIIHexDecode /FlateDecode /DCTDecode]
+  /Decode [1.0 0.0 1.0 0.0 1.0 0.0 1.0 0.0]
+  /Length 734
+>>
+stream
+789cedcd3d4ec2001806e00f680529d4165a643671f112c6901095b09838b01983899bd7e02c9ec
+2c143f8b37802af50cba81770799eef9ddebcc9d7bc355f515c2faf96d1e974e2b2bd68be23bfd8
+3edd3fc436f69acf5844afdbdda795b44907699a24e9b0df3f188c86a35136ccb2713e29c679996
+759312bca6955d7f5e8e8783eabe693aaae9a97a806d3dd74972c4e625dc6a68c5519cd6bd4ede3
+f8edb0adabe26f1bcd47e4c922d6b18955c4793cdf9ddedc9e3dfe9d01000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000fc835ef
+3fe03ce2e1eba
+endstream
+endobj
+5 0 obj <<
+/Length 28
+>>
+stream
+q
+64 0 0 64 0 0 cm
+/I1 Do
+Q
+endstream
+endobj
+6 0 obj <<
+  /ProcSet [/PDF /ImageC]
+  /XObject<</I1 4 0 R >>
+>>
+endobj
+xref
+0 7
+0000000000 65535 f 
+0000000015 00000 n 
+0000000079 00000 n 
+0000000132 00000 n 
+0000000247 00000 n 
+0000001253 00000 n 
+0000001330 00000 n 
+trailer <<
+  /Size 7
+  /Root 2 0 R
+>>
+startxref
+1402
+%%EOF
diff --git a/testing/resources/bug_1752_truetype_font.fragment b/testing/resources/bug_1752_truetype_font.fragment
new file mode 100644
index 0000000..5dc8ea7
--- /dev/null
+++ b/testing/resources/bug_1752_truetype_font.fragment
@@ -0,0 +1,184 @@
+789ced5b0b7054d779fecf7decae9ebb1292102c4877b968179090848431
+60d95aa45d21211e42d2925df1b056da95b4a0d7689757c60fe23c4cd638
+76d2c44d1c9a382e75e28431579452d9a169ea3ab1f31aa74e26f5b46eea
+f1d86de201c7751c9a3ab0dbfffcf7ac9040c4c4339d691b16eefdbff39f
+73feff3fff77cebde7de0bc000a0104f0a682d2ddd5b3efc93879e00b865
+2d6a176df4f95b6039d4022cf82996dd1b3bb675bd19cc6e07a83f07c0ee
+dad81568ea3fb7e202d65fc2e35bdbba6aea0e157ce1d758f7356cdfdb3f
+121ecf5d9c857512da604dfd07125ad9b79d5900793e2c4b03e383236b72
+4a7201e40480f5cc60383e0e25a0a3ade7b0bf6370f8f0c06b254f3e0890
+df8b012e1b8a8623d26b3ff80bec5b85f56b865091f74b3989e50896970e
+8d240e2d5fabf4a03f1b96970d8ff587d5f50ab6cd6fc572c948f8d0b8d4
+0c7f86ed8f62591b0d8f446b7bbe588709c0b2551a1f8b27c00eff82fe8f
+71fbe313d1f181334ffe3b40ce32b4b91078ae58f6ed2b7f7bfcc777da1b
+7e03e5dc0dc08b2bbe1912722740fabcdaa3fe008b3690c0fc613fdb8397
+3127ea3ff2a2da439666feb249930d4b40a6b2040e980fbbb0ebf7a08f34
+b23a9f3d0c2ad8d447d57ad4979b52fe071890c0264939aaa4a88a2429af
+c27d692f1c4a631f17efb865dbd66de0850db0d18cc1f6a014d4807df95f
+311665937a96670272a4f3e023c75fc7f816e3510fcfabf9703746fcbc12
+c7c383e59fc0dd3c12712c12a368c012a332ce21e03349a1f2c6348f6143
+3a9d7e36335e6681e9a13389c639fb77755ee6fac98a6ab1dab26ea0e5ff
+d29f77e3ce9e5030d0ddd5b9bd63dbd62d9bdb37b5b56e6cf1fb9a9b3678
+1befb8bde1b6f5ebd6debae69655b535d52bab9679dc154bf525aef2d2a2
+02873d3f2f273bcb66b5a88a2c31a8d20cd6eb37e40aada025acfbf570eb
+ca2acd5f3ae45b59e5d75b7a0d2dac192814b7deda4a2a3d6c68bd9ae146
+119ea1ee35bcd872e0aa965eb3a577ba2573680dd0c05de89af1239fae4d
+b19eed41c40ffaf490665c20bc85b0e2a6421e165c2eec4151f16835bfd1
+726028e9efc518d9644e76b3de1ccd5e590593d93908731019cbf4f149b6
+ec0e46405ae65f3f89133c8fbbc591fac311a3637bd0ef73ba5ca195556d
+46beeea32a68269386a5d9b092492dc6438707b4c9aa6f278f4d39a0afb7
+3237a247c2bb82861cc6be49d99f4cde6f14541acb759fb1fcc3af97e2c8
+a34695eef31b95dc6a7be7b49ff62b2e99a15638742df91bc0e1e817cecf
+d68485c652e1f80d706848cd06eb0cbaf8cfd982b94e265b74ad25d99b0c
+4fa58ff4e99a434f4ee6e626c7fd986ee808a289a9f4330f388d966321c3
+d13bc4d687c4d05b3adb8d79db77060da9a2451b0aa306ff36eaaeb54e57
+c1749b8eeb5503a605938319d6781a3b8249cd9f7cc0e772bafc3eac7619
+47b607797a1e98d2a0cf791abc35952143eae535dfced4140778cd914c8d
+a9f4626275e4b8bd2b9834948ab688eec7cc3f10368ef4e12cdbcb09d21d
+46fe45a74b4f161668eb6a42d49647d116896986eac66461af991d70fef0
+2e490715f22f9ae282131db80b0ab5753a9ae176fcbabf57fc3d30548a06
+344c786ba53921ba8386d787c01b16ccf9276b6bb047b817898bf98854a3
+461f378af4a669962939b1ae207511dd8ca26603ef66a29751e3a7f585e9
+ebf59921705bfaf6e0d3509f7e7572b5e6fccb7a580d211f6f5cd28cb3cd
+ed4f0623034679af3382eb6f400b3a5d8637844c87f46034c4a71f6668f9
+ab4e9a24219a33ddc1f62ebd7d7b4f70ad08c4ace0e6940aff5566f4a0d3
+348313d1b055d8b4a0e49443d8d0810aad0581ded48067c35a61c3c38109
+272d9fc04d0d5a903921d31ac330966bfea84fb4e3e55946553ead9a5b33
+d62cbc88769a5b9dae90cbfcadac92b05a138eb1878d27b5355385972bac
+b0e13c6d6e2515cf65299ffc5a508fea217d4833bc1d413e369e1ecab248
+06e55c70d53dab3423599826706175a6c09369b4543a6726d7d84865be6c
+0ca95bc7c982ebea085675188c37d8490bd6897329e49cad479569e9f7f7
+751a6dd7766d339df29e499bdede95e431eb224ec08414e0d1b61753d185
+73b777ae0a9cb2deb0a8d0927a5b24a977051b9c9483cee0ddce0ff31116
+423b6bef6e5a593529b1a6499d1ddd3ee96547bb7a8278256d7ada8137fc
+a3ddc1d312939a7b9b42934bb13ef8b486f725d24a5ccb95bca0f102b7d6
+89051bb5773eed053842b50a29a8dc3fc58074b68c8e41ff9464ea1ca623
+3739f2e24dbf7f4a316bbc99d60aea6ca6ee08e9e837099c2c3e0abe0e4b
+879064bcadf8b5089f2077858692bd21bec8a004d3837f99c1f43b305dfa
+1d934cb2e41ad97ab4c9c8d19bb8be91eb1b4dbd85ebad38355909c3eeb3
+b9c3a5a82dfc9e33e9b8c05319c28b49d2f1c64a6f3acb55af054063bfd2
+d8c31abb57631a2b0b94d7cb81f232662f6b2c3b5526efece80934f66ceb
+917a583010ea08066a83de205e9183ca873a7604b41deced1d6c07eb0e04
+3aba03e3ddacbc9bd5767bbb8f74ffb8fbd56eb5760bdb226d0d6c8cb404
+1a5b4eb5482dac3db0a9a32dd086725bc7d640fd56b615e1e68ef640793b
+b3b737b69f6a97bb3a3a03b775b24ed611d8ded111b87529bb271c290fde
+cd0ec6cbca0fc43794ef8fd79527f0f8d3389b8ab397e36c417d69c08a51
+5be474f9486c41f970cc5dbe2f767bf9de586bf95763acc7cd6cee56b7d4
+ea3eea7ec12ddfab3fa4bfa8cbf3ea0bbd230195c901850f586676b9513e
+25cb91ddabcb0ff5b3bedd7a7978777d79efee15e577e2b107f1d4ee1776
+4b2feffec56e6951c41928a92f0e38eaed01bb7d9b5d2ab7bf6897ecf6b4
+5db2e02626809bf7c018dc0ba7e057a038801d29612a9b620f4f76775556
+b64f59d378dfcbead869b0a34645173f7bb7f71896a306047a76062719fb
+54e8e30f3e084d8bdb8d3a5c36bd8b43ed4684af1f0e8e20702c9e2c81a6
+503c5e59b9279ed85f5959194f54f25fdc04f17822612a78cd7e5193a98e
+9b656a453dafd4a0aab2740f80a50872a00377d2f3613f9d67fd945628e2
+327d7ef6395594be88fbecb330efd267d31752f7a6f6a6cea537a53ef0ae
+d27c1661f5c077c617211f2de7a5ce5c4aa5df4df7a6df9525c865f7a7df
+91bd902fdd92fe35eef3f3b0dde7e021b81f77f5c7e104bc010f4c1b7b1c
+9e8047b1eea3b0775af705f812b6fa347cfc8a4f560c5f049f5a40852afa
+13811fb25cd6c292ec59898f5be2cf1552440de0538215aa2719d4349cb6
+2af75ea89bb4a8af349c962584302973b5cad5a7ad9623971a4e33aeaf2f
+701554b80a5c3e494b2d659f4f0da981f7bee1537e04e2c94175aae7d06a
+1e54794b14ab2d4fceb7672b6a9e140be5e529aa0c4a2134d63716aeaba9
+2c28847505856cfebaba55b52ed925ebac3e8bc91e8b5556761997cf3df5
+8c74db13d2fa54cf899632d713ec3ba9dbd473eff9a421f6cd7f3ed49ff2
+037fe2791eb9fc0e66d50ea5f864d5e7bdc56ab31539162eb42b45396565
+457679896e5de0702cd8177ad9c1d63b986c7730bbea70d8014af78540b6
+2fdc17b263409550da48f194d6dcb967f79dbb775f09aea0feca9f55b5f3
+5c9a525c64b11697b1e2224577cd73d5adb965b5bb922d6026d29f675f61
+6ea67eeae8935f4ebdfbf6e5d414cb3f79fc1b4fbfc33cc6d7cf9c51cf9e
+fae67d4f2ec85e6c7cfab957e4d6d18f1cda7bf97397df3a9afce8ddfc49
+ebeef479e5457c529d0f6e6f916c2fceb2cba50be6412c344fc9b5c442b9
+f3a643a5c856d5b22550e080faba5b8bf399ae41c1eac2a5f575f3ad6e79
+ddf9d43bccf2cef1bfdf7d723cf537a93fff2a6b7cf91727379d5297a79e
+4bbd957a23f5a3f58f2d59c03ec9865e63dd533b8e77107fcff32761cca7
+0d9f7597798bf215c852b20a0ad5bc7d215556f2f785942bc962ebd69939
+610e58ce0a5c1ac80e70e905f59ada93da9f7a281563cfb200bbebd9d485
+d49b6f3f2f754abf4c3d92fa887a36f5c9d409369f95ff8ecf5ac67dcabf
+459f3910f0aeb264673305170e9373f32c59b1d0cb16b6dec2b22ccc0e96
+c72c52a16cb130495263214966d9b110bb86bb3dbb89bc69e256d5f2d88a
+5de621fff6d28bf2aacbf74bdd974f4a87d5b38fa7d63e76f922cc8a230b
+5abc95fca158c128b27378146de8dfd268b9d3326679c8f2658b2507c390
+58a1198719014e68f43ec335ce693de398dd3b455e3b2f3f853e2fbff715
+c1b57a1b72ed84dbbd5abe546493162c70dae4458bc1190b210fb9b905c8
+b8a2ce8f85d479b386397b7ccc55309b7b8e9189ba5b71bc4decbf126f7f
+29753af599b3ec43bf7cf3fb2d7f3795fa5dea9fd84296f727c7527f2b2b
+97eb2bdcec18eb7f83edf8ab1d8f75d3e4f879ea259d9de6592963a3d3cf
+ff35d02b30c31c9d1058c2b5fe2d816558c432ef0b70e6b05502ab789d0b
+086c416e13025ba153d205b641b1f4b8c0595024bd26703668f23a8173a0
+4cfebcc0b9e05336089c07d5caeb02e7c30a35c6df7e28fc9abb87a2e298
+41213c2cb084ad9e125886b5f05d811528648b0556a194dd26b0051cac4f
+602b9c60770b6c8315d20181b360993425703678a5ff1438071ae41e8173
+e1a8fcd702e7c12ee51302e7433732dc0c63300e8761026230084390000d
+eaa01656e159838d583b86fa618862a90d46a11faa116d40cd30cacee95e
+712a455146d1d6013c47b025348f8d1f9e880d0e25b4bada5575dac6b1b1
+c1e1a8d636da5fad6d181ed63a79555ceb8cc6a31307a211ecb015fd25f0
+d0a00bc2e82f8eaab1c498d6151e45c83d0cc27ef41d462fd0191ddc3f1c
+46b0057b8c52cfc3381a33d6116c3388f18de259839578cc617bcbd8e858
+e2f0388634121e8c8d0e6a2bb519ee7e7f303b68a87174c19d6b98b26a4c
+dc6aac884ec46363a3daaaeadad5578ccc3271b5fd1825308c47026d8631
+79511ac004ec43dd180cfc1e32b8d9084adefe30ca3eaa9fa05471bb098a
+334a6d6214693f6912d8de2cefc5944e50db089efbb1c61c539c5348238e
+c5b5b096980847a223e1897ddad8c02c2ac3a3116d247c58eb8b6a13d1c1
+583c119d8846b4d8a8d61f9d488451eedd3f118b4762fd094c4bbcfa46f8
+ca0cef5a86b8c7b92cf868f6f1f9384a698ca2bd9119fd7dd1786c70544b
+44c3a89dd9d8cc4c1fe5ee5ab391b9cd9ad670947d87b5691791992ef8aa
+48a091f5780dabc1b18c91a96a347485c66ad28f60fd381ea3623ad460e7
+44627c7d4d4dff58245a3d4899aeee1f1ba919af414f6335571b3f487faa
+d1d0ece863b3927ac55907b2cdc3d94f5cc7716a9a8b364633238e2dba85
+85d9799ac09643d8f320b60bd352cf047af0e0c1ea11918698491405dc31
+3116d9df9f8877e1fa8ef547e335ddd840e46ea26b68ec607f388e56360b
+d7a36494d3b19f263577c9933e44546cc090c2d8ce2ccdee53859aab1764
+1d2d48d88c8e47e348d5fed14874424b0c45b50de3e17e14a2a64acbacd8
+baeadaebe5363cc379353a98c09cd420893383e099db8c53b719fcb8b6bb
+f0bc3213c48c3c85c979f5d8c460cdb01940bc66735bb37f6b977f250530
+fd363c3d800b7fae5f36dd0f25580a15e0060f2c83e5b0827432de1fb2f1
+da6e4da7717fcae89e05500265d89ad7f27b92223c3080e97b2bb779045e
+07b5fff0045ed923d103755085e730b40c4e44f7c19ee17062142f140ac5
+95265bd9c0b66ce8d47834a851454c0aa2d935a63f05ef68337bcfc4d670
+df813854f50d1f1c80f5788e83b7bf7f641c368fc71371e89cd8373100c1
+03e1c47ebab7aad45bc511570a9ffcce5f85c9aee66b677a4cb57466a2cd
+2a9c4fc348ec5df03138069fa5279d937006cec173f043f829bc82a33f0f
+efc225a6e0734b115bc496b22ab69a35301fdbccbad92e1661c32cc1ee62
+1fc3adcb67d97176829d6467d839f61cfb21fb297b85bd8e23445feca899
+0bf688287f5e94bf2fe4bf9952924c69f98c29ad6b85fcb9296d1f13f267
+a6cc8a08f98e29b38f9832275fc8e3a6cc5d21e4b890c25fde2e215f3265
+7eab90df32a57db5905f37a54313f21121df356541a7908690174d59d820
+e47d42be60ca7922be79dd423e2ae4aba62c720b392ca4a82f12fd8b579b
+792c16f5c58f09993265499d908f9bed4a4ed0572986ab80efbfaecc7366
+d683f955ad0816e1fae173a76a468bb90e45cc23b3673edae4f617ced1ce
+fc92f5fe6d78ab20ecc2750b109973857fd0df4c6fadf0199ce54fc069dc
+2b7f1f7e06afc15bf01eb3b04256c656b035ac896d653d6c804db07bf029
+fd11f6387b8a3dc3becb5e623f676fb28b9224e54b0b25b75427dd216d92
+82d2809490ee931e96be249d949e915e907e26bd2ebd23839c2f2f9257c8
+6be516b95bee93c7e57be463f2a3f2d7e4b3f273f24bf2abf25bf225255b
+2955dc740de2e35f2eae461cc994158e2d8455c256c216c236c256c25984
+6d84b3096711ce219c4d3897700ee13cc2b984f309e711b613ce27ec206c
+275c40d841b8907001e179844d568b08cf235c4cb8887009e162c2f30997
+102e253c9ff002c2a5627670bc80b093f042f13d956327617a32200d3e17
+115e4cb89c7019618d70396117618df012c22ec23a61f3abf252c23ae10a
+c24b09bb095710f61076135e46df7115d2015dc5394b1ec193423c790453
+0a31e5115c29c49547b0a5105b1ec197427c7904630a31e6119c29c49947
+b0a6106b1ec19b42bc7904730a31e711dc29c49d47b0a7107b1ec19f42fc
+7904830a31e8111c2ac4a147b0a8108b1ec1a3423c7a04930a31e9115c2a
+c4a547b0a9109b1ec1a7427c7a04a30a31ea119c2ac4a947b0aa10ab1ec1
+ab42bc7a04b30a31eb11dc2ac4ad47b0ab10bb1ec1af42fc7a04c30a31ec
+111c2bc4b147b0ac10cb1ec1b3423c7b04d312c645f76dba365dffda928b
+635b8277e03adc2635c126dc30eec1add104de5db91d09cfa654845485b4
+086915d226760759624720d1acc920751a59a691751ad96e46fb3f1aed42
+9c87593463ae1fab8ad19a77d2aa1b8eeec62c67d3aed58d7bba357007de
+cb3af17e3970c33e149101791a29d3489d4696697433aa9b51fd7145558a
+ab967f2a5a7add98148caa90ae45ef17c78d58b3095bfcbad6002dd0f1be
+5615c85ccd32489946ea34bae9fda6f79bdeffb8bc97a0652bf03df0dcbe
+2df884605e4f6b710f753dbf0a64aea2ca740419a4fe3ff352848cf1b71f
+da9c3e3257faa5d7d857a63952a63dddb476d3daff656b85b89ef81bc3b2
+396c49b4de3276326faee50fdcab0cd7750e9657c0b5bf9916b2708c0b71
+7c6e7c8eaa83b5b807f441e66d22902500f3dda14a670b9dad7436ff7f41
+169db3df375b32fd3b8bd2eb5e49fed077a33c42f3dd28ccba2facc15d6c
+cf7572957bd548de5f9379476825cd152e9661b6e67ec7aacc8966eec66b
+e9d97a748e1833ed2d94ad7cccc7b539ff43da70f441de3dcb74175d046c
+3ac38cb26d2259a0cc13c400dc37c7f79bb5f4fdc647df6f3ae0ca571736
+03c375309b85a5482c9e80fc7dd18951cc3f40e66deecc5925d1584b690e
+306812f23e60f44e8af35984f9e707ff22a5a6cf43161e38163a67beec58
+684edf789ef87c71ccc8d2ec3979e376f89584c7b662ce8c9b6b3ba35567
+651f5eb9a7f43fb89cf97f80fe1b5550eca6
diff --git a/testing/resources/bug_1768.in b/testing/resources/bug_1768.in
new file mode 100644
index 0000000..3f06f7f
--- /dev/null
+++ b/testing/resources/bug_1768.in
@@ -0,0 +1,317 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /MarkInfo <<
+    /Marked true
+  >>
+  /StructTreeRoot 6 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+  /MediaBox [0 0 612 792]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 4 0 R
+  /Resources <<
+    /ProcSet [/PDF /Text]
+    /Font <<
+      /F1 5 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q /P << /MCID 0 >> BDC Q
+q
+0 0 612 792 re W n
+BT 8 0 0 8 72 712.75 Tm /F1 1 Tf (AAA) Tj ET EMC
+/P << /MCID 1 >> BDC BT 8 0 0 8 532.8 712.75 Tm /F1 1 Tf (111) Tj ET EMC
+
+0.2835 w 2 J
+72 659.03 332.64 24.56 re S
+72 622.98 332.64 36.06 re S
+404.64 622.98 85.68 36.06 re S
+404.64 659.03 85.68 24.56 re S
+490.32 622.98 85.68 36.06 re S
+490.32 659.03 85.68 24.56 re S
+
+/P << /MCID 2 >> BDC BT 10 0 0 10 257.37 667.84 Tm /F1 1 Tf (2) Tj ET EMC
+/P << /MCID 3 >> BDC BT 10 0 0 10 428.73 667.84 Tm /F1 1 Tf (3) Tj ET EMC
+/P << /MCID 4 >> BDC BT 10 0 0 10 514.41 667.84 Tm /F1 1 Tf (4) Tj ET EMC
+/P << /MCID 5 >> BDC BT 10 0 0 10 259.87 637.54 Tm /F1 1 Tf (BB) Tj ET EMC
+/P << /MCID 6 >> BDC BT 10 0 0 10 431.23 637.54 Tm /F1 1 Tf (CC) Tj ET EMC
+/P << /MCID 7 >> BDC BT 10 0 0 10 528.16 637.54 Tm /F1 1 Tf (DD) Tj ET EMC
+Q
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Times-Roman
+>>
+endobj
+{{object 6 0}} <<
+  /Type /StructTreeRoot
+  /K 7 0 R
+>>
+endobj
+{{object 7 0}} <<
+  /Type /StructElem
+  /S /Document
+  /P 6 0 R
+  /K [8 0 R]
+>>
+endobj
+{{object 8 0}} <<
+  /Type /StructElem
+  /S /Document
+  /P 7 0 R
+  /K [9 0 R 10 0 R]
+>>
+endobj
+{{object 9 0}} <<
+  /Type /StructElem
+  /S /Table
+  /P 8 0 R
+  /K [11 0 R]
+>>
+endobj
+{{object 10 0}} <<
+  /Type /StructElem
+  /S /Table
+  /P 8 0 R
+  /K [21 0 R 22 0 R]
+>>
+endobj
+{{object 11 0}} <<
+  /Type /StructElem
+  /S /TR
+  /P 9 0 R
+  /K [12 0 R]
+>>
+endobj
+{{object 12 0}} <<
+  /Type /StructElem
+  /S /TD
+  /P 11 0 R
+  /K [13 0 R]
+>>
+endobj
+{{object 13 0}} <<
+  /Type /StructElem
+  /S /Table
+  /P 12 0 R
+  /K [14 0 R]
+>>
+endobj
+{{object 14 0}} <<
+  /Type /StructElem
+  /S /TR
+  /P 13 0 R
+  /K [15 0 R 16 0 R]
+>>
+endobj
+{{object 15 0}} <<
+  /Type /StructElem
+  /S /TD
+  /P 14 0 R
+  /K [17 0 R]
+>>
+endobj
+{{object 16 0}} <<
+  /Type /StructElem
+  /S /TD
+  /P 14 0 R
+  /K [19 0 R]
+>>
+endobj
+{{object 17 0}} <<
+  /Type /StructElem
+  /S /P
+  /P 15 0 R
+  /K [18 0 R]
+>>
+endobj
+{{object 18 0}} <<
+  /Type /StructElem
+  /S /Span
+  /Pg 3 0 R
+  /P 17 0 R
+  /K 0
+>>
+endobj
+{{object 19 0}} <<
+  /Type /StructElem
+  /S /P
+  /P 16 0 R
+  /K [20 0 R]
+>>
+endobj
+{{object 20 0}} <<
+  /Type /StructElem
+  /S /Span
+  /Pg 3 0 R
+  /P 19 0 R
+  /K 1
+>>
+endobj
+{{object 21 0}} <<
+  /Type /StructElem
+  /S /TR
+  /P 10 0 R
+  /K [23 0 R 24 0 R 25 0 R]
+>>
+endobj
+{{object 22 0}} <<
+  /Type /StructElem
+  /S /TR
+  /P 10 0 R
+  /K [32 0 R 33 0 R 34 0 R]
+>>
+endobj
+{{object 23 0}} <<
+  /Type /StructElem
+  /S /TD
+  /P 21 0 R
+  /K [26 0 R]
+>>
+endobj
+{{object 24 0}} <<
+  /Type /StructElem
+  /S /TD
+  /P 21 0 R
+  /K [28 0 R]
+>>
+endobj
+{{object 25 0}} <<
+  /Type /StructElem
+  /S /TD
+  /P 21 0 R
+  /K [30 0 R]
+>>
+endobj
+{{object 26 0}} <<
+  /Type /StructElem
+  /S /P
+  /P 23 0 R
+  /K [27 0 R]
+>>
+endobj
+{{object 27 0}} <<
+  /Type /StructElem
+  /S /Span
+  /Pg 3 0 R
+  /P 26 0 R
+  /K 2
+>>
+endobj
+{{object 28 0}} <<
+  /Type /StructElem
+  /S /P
+  /P 24 0 R
+  /K [29 0 R]
+>>
+endobj
+{{object 29 0}} <<
+  /Type /StructElem
+  /S /Span
+  /Pg 3 0 R
+  /P 28 0 R
+  /K 3
+>>
+endobj
+{{object 30 0}} <<
+  /Type /StructElem
+  /S /P
+  /P 25 0 R
+  /K [31 0 R]
+>>
+endobj
+{{object 31 0}} <<
+  /Type /StructElem
+  /S /Span
+  /Pg 3 0 R
+  /P 30 0 R
+  /K 4
+>>
+endobj
+{{object 32 0}} <<
+  /Type /StructElem
+  /S /TD
+  /P 22 0 R
+  /K [35 0 R]
+>>
+endobj
+{{object 33 0}} <<
+  /Type /StructElem
+  /S /TD
+  /P 22 0 R
+  /K [37 0 R]
+>>
+endobj
+{{object 34 0}} <<
+  /Type /StructElem
+  /S /TD
+  /P 22 0 R
+  /K [39 0 R]
+>>
+endobj
+{{object 35 0}} <<
+  /Type /StructElem
+  /S /P
+  /P 32 0 R
+  /K [36 0 R]
+>>
+endobj
+{{object 36 0}} <<
+  /Type /StructElem
+  /S /Span
+  /Pg 3 0 R
+  /P 35 0 R
+  /K 5
+>>
+endobj
+{{object 37 0}} <<
+  /Type /StructElem
+  /S /P
+  /P 33 0 R
+  /K [38 0 R]
+>>
+endobj
+{{object 38 0}} <<
+  /Type /StructElem
+  /S /Span
+  /Pg 3 0 R
+  /P 37 0 R
+  /K 6
+>>
+endobj
+{{object 39 0}} <<
+  /Type /StructElem
+  /S /P
+  /P 34 0 R
+  /K [40 0 R]
+>>
+endobj
+{{object 40 0}} <<
+  /Type /StructElem
+  /S /Span
+  /Pg 3 0 R
+  /P 39 0 R
+  /K 7
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/bug_1768.pdf b/testing/resources/bug_1768.pdf
new file mode 100644
index 0000000..32b1644
--- /dev/null
+++ b/testing/resources/bug_1768.pdf
@@ -0,0 +1,364 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /MarkInfo <<
+    /Marked true
+  >>
+  /StructTreeRoot 6 0 R
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+  /MediaBox [0 0 612 792]
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 4 0 R
+  /Resources <<
+    /ProcSet [/PDF /Text]
+    /Font <<
+      /F1 5 0 R
+    >>
+  >>
+>>
+endobj
+4 0 obj <<
+  /Length 812
+>>
+stream
+q /P << /MCID 0 >> BDC Q
+q
+0 0 612 792 re W n
+BT 8 0 0 8 72 712.75 Tm /F1 1 Tf (AAA) Tj ET EMC
+/P << /MCID 1 >> BDC BT 8 0 0 8 532.8 712.75 Tm /F1 1 Tf (111) Tj ET EMC
+
+0.2835 w 2 J
+72 659.03 332.64 24.56 re S
+72 622.98 332.64 36.06 re S
+404.64 622.98 85.68 36.06 re S
+404.64 659.03 85.68 24.56 re S
+490.32 622.98 85.68 36.06 re S
+490.32 659.03 85.68 24.56 re S
+
+/P << /MCID 2 >> BDC BT 10 0 0 10 257.37 667.84 Tm /F1 1 Tf (2) Tj ET EMC
+/P << /MCID 3 >> BDC BT 10 0 0 10 428.73 667.84 Tm /F1 1 Tf (3) Tj ET EMC
+/P << /MCID 4 >> BDC BT 10 0 0 10 514.41 667.84 Tm /F1 1 Tf (4) Tj ET EMC
+/P << /MCID 5 >> BDC BT 10 0 0 10 259.87 637.54 Tm /F1 1 Tf (BB) Tj ET EMC
+/P << /MCID 6 >> BDC BT 10 0 0 10 431.23 637.54 Tm /F1 1 Tf (CC) Tj ET EMC
+/P << /MCID 7 >> BDC BT 10 0 0 10 528.16 637.54 Tm /F1 1 Tf (DD) Tj ET EMC
+Q
+endstream
+endobj
+5 0 obj <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Times-Roman
+>>
+endobj
+6 0 obj <<
+  /Type /StructTreeRoot
+  /K 7 0 R
+>>
+endobj
+7 0 obj <<
+  /Type /StructElem
+  /S /Document
+  /P 6 0 R
+  /K [8 0 R]
+>>
+endobj
+8 0 obj <<
+  /Type /StructElem
+  /S /Document
+  /P 7 0 R
+  /K [9 0 R 10 0 R]
+>>
+endobj
+9 0 obj <<
+  /Type /StructElem
+  /S /Table
+  /P 8 0 R
+  /K [11 0 R]
+>>
+endobj
+10 0 obj <<
+  /Type /StructElem
+  /S /Table
+  /P 8 0 R
+  /K [21 0 R 22 0 R]
+>>
+endobj
+11 0 obj <<
+  /Type /StructElem
+  /S /TR
+  /P 9 0 R
+  /K [12 0 R]
+>>
+endobj
+12 0 obj <<
+  /Type /StructElem
+  /S /TD
+  /P 11 0 R
+  /K [13 0 R]
+>>
+endobj
+13 0 obj <<
+  /Type /StructElem
+  /S /Table
+  /P 12 0 R
+  /K [14 0 R]
+>>
+endobj
+14 0 obj <<
+  /Type /StructElem
+  /S /TR
+  /P 13 0 R
+  /K [15 0 R 16 0 R]
+>>
+endobj
+15 0 obj <<
+  /Type /StructElem
+  /S /TD
+  /P 14 0 R
+  /K [17 0 R]
+>>
+endobj
+16 0 obj <<
+  /Type /StructElem
+  /S /TD
+  /P 14 0 R
+  /K [19 0 R]
+>>
+endobj
+17 0 obj <<
+  /Type /StructElem
+  /S /P
+  /P 15 0 R
+  /K [18 0 R]
+>>
+endobj
+18 0 obj <<
+  /Type /StructElem
+  /S /Span
+  /Pg 3 0 R
+  /P 17 0 R
+  /K 0
+>>
+endobj
+19 0 obj <<
+  /Type /StructElem
+  /S /P
+  /P 16 0 R
+  /K [20 0 R]
+>>
+endobj
+20 0 obj <<
+  /Type /StructElem
+  /S /Span
+  /Pg 3 0 R
+  /P 19 0 R
+  /K 1
+>>
+endobj
+21 0 obj <<
+  /Type /StructElem
+  /S /TR
+  /P 10 0 R
+  /K [23 0 R 24 0 R 25 0 R]
+>>
+endobj
+22 0 obj <<
+  /Type /StructElem
+  /S /TR
+  /P 10 0 R
+  /K [32 0 R 33 0 R 34 0 R]
+>>
+endobj
+23 0 obj <<
+  /Type /StructElem
+  /S /TD
+  /P 21 0 R
+  /K [26 0 R]
+>>
+endobj
+24 0 obj <<
+  /Type /StructElem
+  /S /TD
+  /P 21 0 R
+  /K [28 0 R]
+>>
+endobj
+25 0 obj <<
+  /Type /StructElem
+  /S /TD
+  /P 21 0 R
+  /K [30 0 R]
+>>
+endobj
+26 0 obj <<
+  /Type /StructElem
+  /S /P
+  /P 23 0 R
+  /K [27 0 R]
+>>
+endobj
+27 0 obj <<
+  /Type /StructElem
+  /S /Span
+  /Pg 3 0 R
+  /P 26 0 R
+  /K 2
+>>
+endobj
+28 0 obj <<
+  /Type /StructElem
+  /S /P
+  /P 24 0 R
+  /K [29 0 R]
+>>
+endobj
+29 0 obj <<
+  /Type /StructElem
+  /S /Span
+  /Pg 3 0 R
+  /P 28 0 R
+  /K 3
+>>
+endobj
+30 0 obj <<
+  /Type /StructElem
+  /S /P
+  /P 25 0 R
+  /K [31 0 R]
+>>
+endobj
+31 0 obj <<
+  /Type /StructElem
+  /S /Span
+  /Pg 3 0 R
+  /P 30 0 R
+  /K 4
+>>
+endobj
+32 0 obj <<
+  /Type /StructElem
+  /S /TD
+  /P 22 0 R
+  /K [35 0 R]
+>>
+endobj
+33 0 obj <<
+  /Type /StructElem
+  /S /TD
+  /P 22 0 R
+  /K [37 0 R]
+>>
+endobj
+34 0 obj <<
+  /Type /StructElem
+  /S /TD
+  /P 22 0 R
+  /K [39 0 R]
+>>
+endobj
+35 0 obj <<
+  /Type /StructElem
+  /S /P
+  /P 32 0 R
+  /K [36 0 R]
+>>
+endobj
+36 0 obj <<
+  /Type /StructElem
+  /S /Span
+  /Pg 3 0 R
+  /P 35 0 R
+  /K 5
+>>
+endobj
+37 0 obj <<
+  /Type /StructElem
+  /S /P
+  /P 33 0 R
+  /K [38 0 R]
+>>
+endobj
+38 0 obj <<
+  /Type /StructElem
+  /S /Span
+  /Pg 3 0 R
+  /P 37 0 R
+  /K 6
+>>
+endobj
+39 0 obj <<
+  /Type /StructElem
+  /S /P
+  /P 34 0 R
+  /K [40 0 R]
+>>
+endobj
+40 0 obj <<
+  /Type /StructElem
+  /S /Span
+  /Pg 3 0 R
+  /P 39 0 R
+  /K 7
+>>
+endobj
+xref
+0 41
+0000000000 65535 f 
+0000000015 00000 n 
+0000000129 00000 n 
+0000000218 00000 n 
+0000000370 00000 n 
+0000001234 00000 n 
+0000001312 00000 n 
+0000001368 00000 n 
+0000001448 00000 n 
+0000001535 00000 n 
+0000001613 00000 n 
+0000001699 00000 n 
+0000001775 00000 n 
+0000001852 00000 n 
+0000001932 00000 n 
+0000002016 00000 n 
+0000002093 00000 n 
+0000002170 00000 n 
+0000002246 00000 n 
+0000002330 00000 n 
+0000002406 00000 n 
+0000002490 00000 n 
+0000002581 00000 n 
+0000002672 00000 n 
+0000002749 00000 n 
+0000002826 00000 n 
+0000002903 00000 n 
+0000002979 00000 n 
+0000003063 00000 n 
+0000003139 00000 n 
+0000003223 00000 n 
+0000003299 00000 n 
+0000003383 00000 n 
+0000003460 00000 n 
+0000003537 00000 n 
+0000003614 00000 n 
+0000003690 00000 n 
+0000003774 00000 n 
+0000003850 00000 n 
+0000003934 00000 n 
+0000004010 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 41
+>>
+startxref
+4094
+%%EOF
diff --git a/testing/resources/bug_1769.in b/testing/resources/bug_1769.in
new file mode 100644
index 0000000..a6f6682
--- /dev/null
+++ b/testing/resources/bug_1769.in
@@ -0,0 +1,72 @@
+{{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 612 792]
+  /Resources <<
+    /XObject <<
+      /Im1 5 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+1000 0 0 1000 50 100 cm
+/Im1 Do
+Q
+q
+1 0 0 1 200 100 cm
+/Im1 Do
+Q
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 100 100]
+  /Resources <<
+    /Font <<
+      /F1 6 0 R
+    >>
+  >>
+{{streamlen}}
+>>
+stream
+0.001 0 0 0.001 0 0 cm
+BT
+/F1 24 Tf
+(w) Tj
+(o) Tj
+(r) Tj
+(l) Tj
+(d) Tj
+ET
+endstream
+endobj
+{{object 6 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/bug_1769.pdf b/testing/resources/bug_1769.pdf
new file mode 100644
index 0000000..3a9fba1
--- /dev/null
+++ b/testing/resources/bug_1769.pdf
@@ -0,0 +1,85 @@
+%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 612 792]
+  /Resources <<
+    /XObject <<
+      /Im1 5 0 R
+    >>
+  >>
+>>
+endobj
+4 0 obj <<
+  /Length 67
+>>
+stream
+q
+1000 0 0 1000 50 100 cm
+/Im1 Do
+Q
+q
+1 0 0 1 200 100 cm
+/Im1 Do
+Q
+endstream
+endobj
+5 0 obj <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 100 100]
+  /Resources <<
+    /Font <<
+      /F1 6 0 R
+    >>
+  >>
+/Length 74
+>>
+stream
+0.001 0 0 0.001 0 0 cm
+BT
+/F1 24 Tf
+(w) Tj
+(o) Tj
+(r) Tj
+(l) Tj
+(d) Tj
+ET
+endstream
+endobj
+6 0 obj <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+>>
+endobj
+xref
+0 7
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000131 00000 n 
+0000000287 00000 n 
+0000000405 00000 n 
+0000000655 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 7
+>>
+startxref
+731
+%%EOF
diff --git a/testing/resources/bug_1919.pdf b/testing/resources/bug_1919.pdf
new file mode 100644
index 0000000..8331e0d
--- /dev/null
+++ b/testing/resources/bug_1919.pdf
Binary files differ
diff --git a/testing/resources/bug_306123.pdf b/testing/resources/bug_306123.pdf
index 5bd1900..8b542cc 100644
--- a/testing/resources/bug_306123.pdf
+++ b/testing/resources/bug_306123.pdf
@@ -1243,7 +1243,7 @@
 endobj
 9 0 obj <<
   /Type /Page
-  /Parent 2 0 R
+  /Parent 8 0 R
   /MediaBox [0 0 612 792]
 >>
 endobj
diff --git a/testing/resources/bug_481363.in b/testing/resources/bug_481363.in
index 32a724d..1e05346 100644
--- a/testing/resources/bug_481363.in
+++ b/testing/resources/bug_481363.in
@@ -29,7 +29,7 @@
 100 500 100 100 re b
 endstream
 endobj
-{{object 5 0)) <<
+{{object 5 0}} <<
   /Type /Font
   /Subtype /Type1
   /BaseFont /He
diff --git a/testing/resources/bug_481363.pdf b/testing/resources/bug_481363.pdf
index 53468a0..8263b3f 100644
--- a/testing/resources/bug_481363.pdf
+++ b/testing/resources/bug_481363.pdf
@@ -30,7 +30,7 @@
 100 500 100 100 re b
 endstream
 endobj
-{{object 5 0)) <<
+5 0 obj <<
   /Type /Font
   /Subtype /Type1
   /BaseFont /He
@@ -51,12 +51,12 @@
 0000000078 00000 n 
 0000000253 00000 n 
 0000000306 00000 n 
-0000000000 65535 f 
-0000000517 00000 n 
+0000000400 00000 n 
+0000000510 00000 n 
 trailer <<
   /Size 0
   /Root 3 0 R
 >>
 startxref
-621
+614
 %%EOF
diff --git a/testing/resources/bug_674771.in b/testing/resources/bug_674771.in
new file mode 100644
index 0000000..3352f30
--- /dev/null
+++ b/testing/resources/bug_674771.in
@@ -0,0 +1,56 @@
+{{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 792 612]
+  /Resources <<
+    /ProcSet [/PDF /ImageB]
+    /XObject <<
+      /Im0 5 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+400 0 0 300 60 100 cm
+/Im0 Do
+Q
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 1
+  /Decode [0.0 1.0]
+  /Filter [/ASCIIHexDecode /JBIG2Decode]
+  /Height 400
+  /ImageMask true
+  /Width 400
+  {{streamlen}}
+>>
+stream
+000000003000010000001300000dea00000353000017110000171151000000000001260001000000
+3500000dea000003530000000000000000020003fffdff02fefefeff7f86530fb6c922cfff7fff7f
+ff7fff7fff7fff7fff7fff7fffac
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/bug_674771.pdf b/testing/resources/bug_674771.pdf
new file mode 100644
index 0000000..6b2dab8
--- /dev/null
+++ b/testing/resources/bug_674771.pdf
@@ -0,0 +1,68 @@
+%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 792 612]
+  /Resources <<
+    /ProcSet [/PDF /ImageB]
+    /XObject <<
+      /Im0 5 0 R
+    >>
+  >>
+>>
+endobj
+4 0 obj <<
+  /Length 34
+>>
+stream
+q
+400 0 0 300 60 100 cm
+/Im0 Do
+Q
+endstream
+endobj
+5 0 obj <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 1
+  /Decode [0.0 1.0]
+  /Filter [/ASCIIHexDecode /JBIG2Decode]
+  /Height 400
+  /ImageMask true
+  /Width 400
+  /Length 191
+>>
+stream
+000000003000010000001300000dea00000353000017110000171151000000000001260001000000
+3500000dea000003530000000000000000020003fffdff02fefefeff7f86530fb6c922cfff7fff7f
+ff7fff7fff7fff7fff7fff7fffac
+endstream
+endobj
+xref
+0 6
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000131 00000 n 
+0000000317 00000 n 
+0000000402 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 6
+>>
+startxref
+808
+%%EOF
diff --git a/testing/resources/bug_680376.in b/testing/resources/bug_680376.in
index c21df24..32daee1 100644
--- a/testing/resources/bug_680376.in
+++ b/testing/resources/bug_680376.in
@@ -85,8 +85,8 @@
 >>
 endobj
 % Old-style top-level Dests dictionary. Note that FirstAlternate
-% intentionally references non-exisstant page 11 and LastAlternate
-% intentionally references non-existant object 999.
+% intentionally references non-existent page 11 and LastAlternate
+% intentionally references non-existent object 999.
 {{object 14 0}} <<
   /FirstAlternate [11 /XYZ 200 400 800]
   /LastAlternate  <</D [999 0 R /XYZ 0 0 -200]>>
diff --git a/testing/resources/bug_680376.pdf b/testing/resources/bug_680376.pdf
index fb01c57..8d7a884 100644
--- a/testing/resources/bug_680376.pdf
+++ b/testing/resources/bug_680376.pdf
@@ -1,5 +1,5 @@
 %PDF-1.7
-% ò¤ô
+% ò¤ô
 1 0 obj <<
   /Type /Catalog
   /Pages 2 0 R
@@ -86,8 +86,8 @@
 >>
 endobj
 % Old-style top-level Dests dictionary. Note that FirstAlternate
-% intentionally references non-exisstant page 11 and LastAlternate
-% intentionally references non-existant object 999.
+% intentionally references non-existent page 11 and LastAlternate
+% intentionally references non-existent object 999.
 14 0 obj <<
   /FirstAlternate [11 /XYZ 200 400 800]
   /LastAlternate  <</D [999 0 R /XYZ 0 0 -200]>>
@@ -138,19 +138,19 @@
 0000000903 00000 n 
 0000000993 00000 n 
 0000000000 65535 f 
-0000001287 00000 n 
-0000001415 00000 n 
+0000001286 00000 n 
+0000001414 00000 n 
 0000000000 65535 f 
 0000000000 65535 f 
 0000000000 65535 f 
 0000000000 65535 f 
 0000000000 65535 f 
-0000001510 00000 n 
-0000001620 00000 n 
+0000001509 00000 n 
+0000001619 00000 n 
 trailer <<
   /Size 6
   /Root 1 0 R
 >>
 startxref
-1708
+1707
 %%EOF
diff --git a/testing/resources/bug_765384.in b/testing/resources/bug_765384.in
index e7e46c7..69256bc 100644
--- a/testing/resources/bug_765384.in
+++ b/testing/resources/bug_765384.in
@@ -66,7 +66,7 @@
   /JS 21 0 R
 >>
 endobj
-% JS program to exexute
+% JS program to execute
 {{object 21 0}} <<
 >>
 stream
diff --git a/testing/resources/bug_765384.pdf b/testing/resources/bug_765384.pdf
index e820fcc..41e042d 100644
--- a/testing/resources/bug_765384.pdf
+++ b/testing/resources/bug_765384.pdf
@@ -67,7 +67,7 @@
   /JS 21 0 R
 >>
 endobj
-% JS program to exexute
+% JS program to execute
 21 0 obj <<
 >>
 stream
diff --git a/testing/resources/bug_821454.in b/testing/resources/bug_821454.in
index 168c983..ee7f20c 100644
--- a/testing/resources/bug_821454.in
+++ b/testing/resources/bug_821454.in
@@ -1,71 +1,63 @@
 {{header}}
-{{object 1 0}}
-<<
+{{object 1 0}} <<
   /Type /Catalog
   /Pages 2 0 R
-  /Names 14 0 R
-  /AcroForm << /Fields [ 8 0 R 9 0 R ] >>
+  /Names 7 0 R
+  /AcroForm <<
+    /Fields [ 5 0 R 6 0 R ]
+  >>
 >>
 endobj
-{{object 2 0}}
-<<
+{{object 2 0}} <<
   /Type /Pages
   /Count 1
   /Kids [ 3 0 R ]
 >>
 endobj
-{{object 3 0}}
-<<
+{{object 3 0}} <<
   /Type /Page
   /Parent 2 0 R
-  /Contents 6 0 R
+  /Contents 4 0 R
   /MediaBox [ 0 0 300 600 ]
-  /Annots [ 8 0 R 9 0 R ]
+  /Annots [ 5 0 R 6 0 R ]
 >>
 endobj
-{{object 6 0}}
-<<
-{{streamlen}}
+{{object 4 0}} <<
+  {{streamlen}}
 >>
 stream
 endstream
 endobj
-{{object 8 0}}
-<<
+{{object 5 0}} <<
   /Type /Annot
   /Subtype /Link
   /Rect [ 100 350 200 380 ]
   /Dest (target10)
 >>
 endobj
-{{object 9 0}}
-<<
+{{object 6 0}} <<
   /Type /Annot
   /Subtype /Link
   /Rect [ 100 400 200 430 ]
   /Dest (target100)
 >>
 endobj
-{{object 14 0}}
-<<
-  /Dests 15 0 R
+{{object 7 0}} <<
+  /Dests 8 0 R
 >>
 endobj
-{{object 15 0}}
-<<
+{{object 8 0}} <<
   /Names [
-    (target10) 16 0 R
-    (target100) 17 0 R
+    (target10) 9 0 R
+    (target100) 10 0 R
   ]
 >>
 endobj
-{{object 16 0}}
-<<
+{{object 9 0}} <<
   /D [3 0 R /XYZ 100 200 0]
 >>
 endobj
-{{object 17 0}}
-<<
+{{object 10 0}} <<
   /D [3 0 R /XYZ 150 250 0]
 >>
 endobj
diff --git a/testing/resources/bug_821454.pdf b/testing/resources/bug_821454.pdf
index d6229a5..1e11c13 100644
--- a/testing/resources/bug_821454.pdf
+++ b/testing/resources/bug_821454.pdf
@@ -1,96 +1,84 @@
 %PDF-1.7
 % ò¤ô
-1 0 obj
-<<
+1 0 obj <<
   /Type /Catalog
   /Pages 2 0 R
-  /Names 14 0 R
-  /AcroForm << /Fields [ 8 0 R 9 0 R ] >>
+  /Names 7 0 R
+  /AcroForm <<
+    /Fields [ 5 0 R 6 0 R ]
+  >>
 >>
 endobj
-2 0 obj
-<<
+2 0 obj <<
   /Type /Pages
   /Count 1
   /Kids [ 3 0 R ]
 >>
 endobj
-3 0 obj
-<<
+3 0 obj <<
   /Type /Page
   /Parent 2 0 R
-  /Contents 6 0 R
+  /Contents 4 0 R
   /MediaBox [ 0 0 300 600 ]
-  /Annots [ 8 0 R 9 0 R ]
+  /Annots [ 5 0 R 6 0 R ]
 >>
 endobj
-6 0 obj
-<<
-/Length 0
+4 0 obj <<
+  /Length 0
 >>
 stream
 endstream
 endobj
-8 0 obj
-<<
+5 0 obj <<
   /Type /Annot
   /Subtype /Link
   /Rect [ 100 350 200 380 ]
   /Dest (target10)
 >>
 endobj
-9 0 obj
-<<
+6 0 obj <<
   /Type /Annot
   /Subtype /Link
   /Rect [ 100 400 200 430 ]
   /Dest (target100)
 >>
 endobj
-14 0 obj
-<<
-  /Dests 15 0 R
+7 0 obj <<
+  /Dests 8 0 R
 >>
 endobj
-15 0 obj
-<<
+8 0 obj <<
   /Names [
-    (target10) 16 0 R
-    (target100) 17 0 R
+    (target10) 9 0 R
+    (target100) 10 0 R
   ]
 >>
 endobj
-16 0 obj
-<<
+9 0 obj <<
   /D [3 0 R /XYZ 100 200 0]
 >>
 endobj
-17 0 obj
-<<
+10 0 obj <<
   /D [3 0 R /XYZ 150 250 0]
 >>
 endobj
 xref
-0 18
+0 11
 0000000000 65535 f 
 0000000015 00000 n 
-0000000126 00000 n 
-0000000191 00000 n 
-0000000000 65535 f 
-0000000000 65535 f 
-0000000314 00000 n 
-0000000000 65535 f 
-0000000362 00000 n 
-0000000462 00000 n 
-0000000000 65535 f 
-0000000000 65535 f 
-0000000000 65535 f 
-0000000000 65535 f 
-0000000563 00000 n 
-0000000601 00000 n 
-0000000683 00000 n 
-0000000733 00000 n 
-trailer<< /Root 1 0 R /Size 18 >>
+0000000131 00000 n 
+0000000196 00000 n 
+0000000319 00000 n 
+0000000369 00000 n 
+0000000469 00000 n 
+0000000570 00000 n 
+0000000606 00000 n 
+0000000686 00000 n 
+0000000735 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 11
+>>
 startxref
-783
+785
 %%EOF
diff --git a/testing/resources/bug_889099.in b/testing/resources/bug_889099.in
new file mode 100644
index 0000000..77ae5f4
--- /dev/null
+++ b/testing/resources/bug_889099.in
@@ -0,0 +1,64 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /Fields [4 0 R]
+    /DR 5 0 R
+  >>
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources 5 0 R
+  /MediaBox [0 0 300 -400]
+  /Contents 7 0 R
+  /Annots [4 0 R]
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Tx
+  /DA (0 0 0 rg /F1 12 Tf)
+  /F 4
+  /Rect [100 100 200 -130]
+  /T (Text Box)
+  /V (Good :])
+>>
+endobj
+{{object 5 0}} <<
+  /Font <<
+    /F1 6 0 R
+  >>
+>>
+endobj
+{{object 6 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+>>
+endobj
+{{object 7 0}} <<
+  {{streamlen}}
+>>
+stream
+BT
+0 0 0 rg
+/F1 12 Tf
+100 150 Td
+(Bad :[) Tj
+ET
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/bug_889099.pdf b/testing/resources/bug_889099.pdf
new file mode 100644
index 0000000..a406cd1
--- /dev/null
+++ b/testing/resources/bug_889099.pdf
@@ -0,0 +1,78 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /Fields [4 0 R]
+    /DR 5 0 R
+  >>
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources 5 0 R
+  /MediaBox [0 0 300 -400]
+  /Contents 7 0 R
+  /Annots [4 0 R]
+>>
+endobj
+4 0 obj <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Tx
+  /DA (0 0 0 rg /F1 12 Tf)
+  /F 4
+  /Rect [100 100 200 -130]
+  /T (Text Box)
+  /V (Good :])
+>>
+endobj
+5 0 obj <<
+  /Font <<
+    /F1 6 0 R
+  >>
+>>
+endobj
+6 0 obj <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+>>
+endobj
+7 0 obj <<
+  /Length 48
+>>
+stream
+BT
+0 0 0 rg
+/F1 12 Tf
+100 150 Td
+(Bad :[) Tj
+ET
+endstream
+endobj
+xref
+0 8
+0000000000 65535 f 
+0000000015 00000 n 
+0000000122 00000 n 
+0000000185 00000 n 
+0000000318 00000 n 
+0000000475 00000 n 
+0000000526 00000 n 
+0000000602 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 8
+>>
+startxref
+701
+%%EOF
diff --git a/testing/resources/bug_921.in b/testing/resources/bug_921.in
index a0c2e73..ccd44fb 100644
--- a/testing/resources/bug_921.in
+++ b/testing/resources/bug_921.in
@@ -43,7 +43,7 @@
 >>
 endobj
 {{object 6 0}} <<
-{{streamlen}}
+  {{streamlen}}
 >>
 stream
 BT
diff --git a/testing/resources/bug_921.pdf b/testing/resources/bug_921.pdf
index fb3950e..84e0755 100644
--- a/testing/resources/bug_921.pdf
+++ b/testing/resources/bug_921.pdf
@@ -44,7 +44,7 @@
 >>
 endobj
 6 0 obj <<
-/Length 2784
+  /Length 2784
 >>
 stream
 BT
@@ -68,7 +68,10 @@
 0000000287 00000 n 
 0000000412 00000 n 
 0000000593 00000 n 
-trailer<< /Root 1 0 R /Size 7 >>
+trailer <<
+  /Root 1 0 R
+  /Size 7
+>>
 startxref
-3428
+3430
 %%EOF
diff --git a/testing/resources/bug_925981.in b/testing/resources/bug_925981.in
index 3d6e37a..f5f8ebe 100644
--- a/testing/resources/bug_925981.in
+++ b/testing/resources/bug_925981.in
@@ -36,7 +36,7 @@
 >>
 endobj
 {{object 6 0}} <<
-{{streamlen}}
+  {{streamlen}}
 >>
 stream
 BT
diff --git a/testing/resources/bug_925981.pdf b/testing/resources/bug_925981.pdf
index 8d856e1..5c35e38 100644
--- a/testing/resources/bug_925981.pdf
+++ b/testing/resources/bug_925981.pdf
@@ -37,7 +37,7 @@
 >>
 endobj
 6 0 obj <<
-/Length 83
+  /Length 83
 >>
 stream
 BT
@@ -64,11 +64,11 @@
 0000000309 00000 n 
 0000000387 00000 n 
 0000000463 00000 n 
-0000000595 00000 n 
+0000000597 00000 n 
 trailer <<
   /Root 1 0 R
   /Size 8
 >>
 startxref
-646
+648
 %%EOF
diff --git a/testing/resources/bug_972518.pdf b/testing/resources/bug_972518.pdf
index 51185f5..fde54f8 100644
--- a/testing/resources/bug_972518.pdf
+++ b/testing/resources/bug_972518.pdf
@@ -60,7 +60,7 @@
 endobj
 9 0 obj <<
   /Type /Page
-  /Parent 2 0 R
+  /Parent 8 0 R
   /MediaBox [0 0 612 792]
 >>
 endobj
diff --git a/testing/resources/dashed_lines.in b/testing/resources/dashed_lines.in
new file mode 100644
index 0000000..b4f74bb
--- /dev/null
+++ b/testing/resources/dashed_lines.in
@@ -0,0 +1,37 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /MediaBox [0 0 200 100]
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 4 0 R
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+0 0 0 rg
+10 25 m 190 25 l S
+[6 5 4 3 2 1] 5 d
+10 50 m 190 50 l S
+[] 0 d
+10 75 m 190 75 l S
+Q
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/dashed_lines.pdf b/testing/resources/dashed_lines.pdf
new file mode 100644
index 0000000..f40a591
--- /dev/null
+++ b/testing/resources/dashed_lines.pdf
@@ -0,0 +1,48 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /MediaBox [0 0 200 100]
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 4 0 R
+>>
+endobj
+4 0 obj <<
+  /Length 95
+>>
+stream
+q
+0 0 0 rg
+10 25 m 190 25 l S
+[6 5 4 3 2 1] 5 d
+10 50 m 190 50 l S
+[] 0 d
+10 75 m 190 75 l S
+Q
+endstream
+endobj
+xref
+0 5
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000157 00000 n 
+0000000226 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 5
+>>
+startxref
+372
+%%EOF
diff --git a/testing/resources/docmdp.in b/testing/resources/docmdp.in
new file mode 100644
index 0000000..a8fe283
--- /dev/null
+++ b/testing/resources/docmdp.in
@@ -0,0 +1,88 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /Fields [7 0 R]
+    /SigFlags 3
+  >>
+>>
+endobj
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /MediaBox [0 0 200 300]
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 4 0 R
+  /Annots [7 0 R]
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+0 0 0 rg
+0 290 10 10 re B*
+10 150 50 30 re B*
+0 0 1 rg
+190 290 10 10 re B*
+70 232 50 30 re B*
+0 1 0 rg
+190 0 10 10 re B*
+130 150 50 30 re B*
+1 0 0 rg
+0 0 10 10 re B*
+70 67 50 30 re B*
+Q
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /Sig
+  /Reference [
+    <<
+      /Type /SigRef
+      /TransformMethod /DocMDP
+      /TransformParams <<
+        /Type /TransformParams
+        /P 1
+        /V /1.2
+      >>
+    >>
+  ]
+>>
+endobj
+{{object 6 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /BBox [0 0 0 0]
+  /Length 0
+>>
+stream
+endstream
+endobj
+{{object 7 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Sig
+  /F 132
+  /Rect [0 0 0 0]
+  /P 3 0 R
+  /T (Signature1)
+  /V 5 0 R
+  /DV 5 0 R
+  /AP <<
+    /N 6 0 R
+  >>
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/docmdp.pdf b/testing/resources/docmdp.pdf
new file mode 100644
index 0000000..0191a00
--- /dev/null
+++ b/testing/resources/docmdp.pdf
@@ -0,0 +1,102 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /Fields [7 0 R]
+    /SigFlags 3
+  >>
+>>
+endobj
+endobj
+2 0 obj <<
+  /Type /Pages
+  /MediaBox [0 0 200 300]
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 4 0 R
+  /Annots [7 0 R]
+>>
+endobj
+4 0 obj <<
+  /Length 188
+>>
+stream
+q
+0 0 0 rg
+0 290 10 10 re B*
+10 150 50 30 re B*
+0 0 1 rg
+190 290 10 10 re B*
+70 232 50 30 re B*
+0 1 0 rg
+190 0 10 10 re B*
+130 150 50 30 re B*
+1 0 0 rg
+0 0 10 10 re B*
+70 67 50 30 re B*
+Q
+endstream
+endobj
+5 0 obj <<
+  /Type /Sig
+  /Reference [
+    <<
+      /Type /SigRef
+      /TransformMethod /DocMDP
+      /TransformParams <<
+        /Type /TransformParams
+        /P 1
+        /V /1.2
+      >>
+    >>
+  ]
+>>
+endobj
+6 0 obj <<
+  /Type /XObject
+  /Subtype /Form
+  /BBox [0 0 0 0]
+  /Length 0
+>>
+stream
+endstream
+endobj
+7 0 obj <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Sig
+  /F 132
+  /Rect [0 0 0 0]
+  /P 3 0 R
+  /T (Signature1)
+  /V 5 0 R
+  /DV 5 0 R
+  /AP <<
+    /N 6 0 R
+  >>
+>>
+endobj
+xref
+0 8
+0000000000 65535 f 
+0000000015 00000 n 
+0000000131 00000 n 
+0000000220 00000 n 
+0000000307 00000 n 
+0000000547 00000 n 
+0000000760 00000 n 
+0000000862 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 8
+>>
+startxref
+1034
+%%EOF
diff --git a/testing/resources/embedded_attachments_invalid_data.in b/testing/resources/embedded_attachments_invalid_data.in
new file mode 100644
index 0000000..26545a4
--- /dev/null
+++ b/testing/resources/embedded_attachments_invalid_data.in
@@ -0,0 +1,41 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Names 4 0 R
+  /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
+  /MediaBox [0 0 612 792]
+  /Resources <<
+    /ProcSet [/PDF]
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  /EmbeddedFiles 5 0 R
+>>
+endobj
+{{object 5 0}} <<
+  /Names [(1.txt) 6 0 R]
+>>
+endobj
+{{object 6 0}} <<
+  /Type /Filespec
+  /Desc ()
+  /F (1.txt)
+  /UF (1.txt)
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/embedded_attachments_invalid_data.pdf b/testing/resources/embedded_attachments_invalid_data.pdf
new file mode 100644
index 0000000..8a830e2
--- /dev/null
+++ b/testing/resources/embedded_attachments_invalid_data.pdf
@@ -0,0 +1,54 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Names 4 0 R
+  /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
+  /MediaBox [0 0 612 792]
+  /Resources <<
+    /ProcSet [/PDF]
+  >>
+>>
+endobj
+4 0 obj <<
+  /EmbeddedFiles 5 0 R
+>>
+endobj
+5 0 obj <<
+  /Names [(1.txt) 6 0 R]
+>>
+endobj
+6 0 obj <<
+  /Type /Filespec
+  /Desc ()
+  /F (1.txt)
+  /UF (1.txt)
+>>
+endobj
+xref
+0 7
+0000000000 65535 f 
+0000000015 00000 n 
+0000000083 00000 n 
+0000000146 00000 n 
+0000000264 00000 n 
+0000000308 00000 n 
+0000000354 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 7
+>>
+startxref
+431
+%%EOF
diff --git a/testing/resources/find_text_consecutive.in b/testing/resources/find_text_consecutive.in
index 9e35e1d..d484584 100644
--- a/testing/resources/find_text_consecutive.in
+++ b/testing/resources/find_text_consecutive.in
@@ -29,7 +29,7 @@
 >>
 endobj
 {{object 5 0}} <<
-{{streamlen}}
+  {{streamlen}}
 >>
 stream
 BT
diff --git a/testing/resources/find_text_consecutive.pdf b/testing/resources/find_text_consecutive.pdf
index 5083d75..bd78380 100644
--- a/testing/resources/find_text_consecutive.pdf
+++ b/testing/resources/find_text_consecutive.pdf
@@ -30,7 +30,7 @@
 >>
 endobj
 5 0 obj <<
-/Length 51
+  /Length 51
 >>
 stream
 BT
@@ -53,5 +53,5 @@
   /Size 6
 >>
 startxref
-465
+467
 %%EOF
diff --git a/testing/resources/fonts/SymbolNeu.ttf b/testing/resources/fonts/SymbolNeu.ttf
new file mode 100644
index 0000000..08932c9
--- /dev/null
+++ b/testing/resources/fonts/SymbolNeu.ttf
Binary files differ
diff --git a/testing/resources/get_page_aaction.in b/testing/resources/get_page_aaction.in
new file mode 100644
index 0000000..83f0c01
--- /dev/null
+++ b/testing/resources/get_page_aaction.in
@@ -0,0 +1,50 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Kids [
+    3 0 R
+    4 0 R
+  ]
+  /Count 2
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 612 792]
+  /AA <<
+    /O <<
+      /F (\\\\127.0.0.1\\c$\\Program Files\\test.exe)
+      /D [1 /Fit]
+      /S /GoToE
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 612 792]
+  /AA <<
+    /O <<
+      /F (\\\\127.0.0.1\\c$\\Program Files\\test_page_two_open.exe)
+      /D [1 /Fit]
+      /S /GoToE
+    >>
+    /C <<
+      /F (\\\\127.0.0.1\\c$\\Program Files\\test_page_two_close.exe)
+      /D [1 /Fit]
+      /S /GoToE
+    >>
+  >>
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/get_page_aaction.pdf b/testing/resources/get_page_aaction.pdf
new file mode 100644
index 0000000..7d46651
--- /dev/null
+++ b/testing/resources/get_page_aaction.pdf
@@ -0,0 +1,61 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /Kids [
+    3 0 R
+    4 0 R
+  ]
+  /Count 2
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 612 792]
+  /AA <<
+    /O <<
+      /F (\\\\127.0.0.1\\c$\\Program Files\\test.exe)
+      /D [1 /Fit]
+      /S /GoToE
+    >>
+  >>
+>>
+endobj
+4 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 612 792]
+  /AA <<
+    /O <<
+      /F (\\\\127.0.0.1\\c$\\Program Files\\test_page_two_open.exe)
+      /D [1 /Fit]
+      /S /GoToE
+    >>
+    /C <<
+      /F (\\\\127.0.0.1\\c$\\Program Files\\test_page_two_close.exe)
+      /D [1 /Fit]
+      /S /GoToE
+    >>
+  >>
+>>
+endobj
+xref
+0 5
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000149 00000 n 
+0000000345 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 5
+>>
+startxref
+675
+%%EOF
diff --git a/testing/resources/gotoe_action.in b/testing/resources/gotoe_action.in
new file mode 100644
index 0000000..04b7cf0
--- /dev/null
+++ b/testing/resources/gotoe_action.in
@@ -0,0 +1,48 @@
+{{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
+  /Annots [4 0 R]
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Annot
+  /Subtype /Link
+  /FT /Tx
+  /Ff 29360128
+  /A 5 0 R
+  /T (txtName)
+  /F 4
+  /M (D:20150514070426+05'30')
+  /Rect [1 1 199 199]
+  /BS  <<
+    /W 1
+    /S /S
+  >>
+  /DA (/Helv 0 Tf 0 0 0 rg)
+  /V ()
+>>
+endobj
+{{object 5 0}} <<
+  /S /GoToE
+  /D [1 /Fit]
+  /F (ExampleFile.pdf)
+>>
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/gotoe_action.pdf b/testing/resources/gotoe_action.pdf
new file mode 100644
index 0000000..8d588e0
--- /dev/null
+++ b/testing/resources/gotoe_action.pdf
@@ -0,0 +1,60 @@
+%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
+  /Annots [4 0 R]
+>>
+endobj
+4 0 obj <<
+  /Type /Annot
+  /Subtype /Link
+  /FT /Tx
+  /Ff 29360128
+  /A 5 0 R
+  /T (txtName)
+  /F 4
+  /M (D:20150514070426+05'30')
+  /Rect [1 1 199 199]
+  /BS  <<
+    /W 1
+    /S /S
+  >>
+  /DA (/Helv 0 Tf 0 0 0 rg)
+  /V ()
+>>
+endobj
+5 0 obj <<
+  /S /GoToE
+  /D [1 /Fit]
+  /F (ExampleFile.pdf)
+>>
+>>
+endobj
+xref
+0 6
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000157 00000 n 
+0000000226 00000 n 
+0000000460 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 6
+>>
+startxref
+533
+%%EOF
diff --git a/testing/resources/gray-alpha.jp2 b/testing/resources/gray-alpha.jp2
new file mode 100644
index 0000000..f5e3f34
--- /dev/null
+++ b/testing/resources/gray-alpha.jp2
Binary files differ
diff --git a/testing/resources/gray.jp2 b/testing/resources/gray.jp2
new file mode 100644
index 0000000..53293bd
--- /dev/null
+++ b/testing/resources/gray.jp2
Binary files differ
diff --git a/testing/resources/hebrew_mirrored.in b/testing/resources/hebrew_mirrored.in
new file mode 100644
index 0000000..09ede5d
--- /dev/null
+++ b/testing/resources/hebrew_mirrored.in
@@ -0,0 +1,160 @@
+{{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 200 200]
+  /Resources <<
+    /ProcSet [/PDF /Text]
+    /Font <<
+      /F1 5 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+BT
+/F1 12 Tf
+150 160 Td
+[<01>2<02>2<03>-4<02>2<04>5<05>]TJ
+ET
+
+BT
+0 100 Td
+-1 0 0 1 50 40 Tm
+[<01>5<05>]TJ
+ET
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /Font
+  /Subtype /TrueType
+  /BaseFont /BAAAAA+NotoSansHebrew-Regular
+  /FirstChar 0
+  /FontDescriptor 6 0 R
+  /LastChar 5
+  /ToUnicode 8 0 R
+  /Widths [600 294 235 645 397 542]
+>>
+endobj
+{{object 6 0}} <<
+  /Type /FontDescriptor
+  /Ascent 1069
+  /CapHeight 869
+  /Descent -293
+  /Flags 4
+  /FontBBox [-210 -252 716 869]
+  /FontFile2 7 0 R
+  /FontName /BAAAAA+NotoSansHebrew-Regular
+  /ItalicAngle 0
+  /StemV 80
+>>
+endobj
+{{object 7 0}} <<
+  /Filter [/ASCII85Decode /FlateDecode]
+  {{streamlen}}
+>>
+stream
+GhVOeCMXsCFZt#(%p<i9AU.uO6]Ye/ifKHXbLV!I1<gsgHY$Eg-tbPt@rk=Ap?l+FQ/u;^8JASXVQS>V
+nuG<j"nF$,Rii%*89oFrq6<34,1m)cJ0IF5(22*&"c<?^q>^jZEkc[.-qdl^dk1F&,fKT9F2)eaH/1QX
+<gN4)W0n]g:798;]<j42dYR+b7&$II`er0Do2PVi55OH.DU&3oF7^D>=p%W;pT6OOkC.gL0;aQZ%EQ]$
+CMpO/ouiOe*=oqMFW5p^ge<JWIt[XVg[cqr8aR%^g[TKTpYK&S\F4)WJbd&hhE(,./q'ef/\k-FOKm`h
+f=q)o6_0Sd-Ap"u/`'bn6!o+8Zu;5]Q^2D[J,6jbf.d4Ck't7.im"Z=^^/7D4VXdnJ*hX.ia&@S<Zl_D
+Xq`#Xlf3.[Q6GL-.IS+nj<JEQ1+=HefoeH8Qi0[)c<.\^P$4LTD?DamV./;?-PDR^8[b$k8'^LB2C4&'
+NUg=HC6k8A'.Knb7Wh)elDCX74)L`tc?`Z\Sb;i$>AElUWZdj+!8FWu:gnKPdkmGSM;%q39@mC[7<ZEH
+BP,jX746Y[8VL'e=mlrkg+[&/4Xn#1'(72pCc`cXNN+/Z0?DM&g%BgA@co7e)9J3X;X\\(5@"=N^/d""
+T`@poCcT@G`,Q43B>^KnLk;$<#C1`ZRI:qa#-tMr)R?VE.RR\7=sKe@N)#YuA]JfMaHgYN/!?c&OsZTe
+^cXe0%l-1*krrj[$8W`Wl)*K?>t9dJirfrR7MYH\=XPN5Q2qL_I4eudg4b]KRT\<OAl/T-PZ'?3dZ$p;
+<A/YSC[`O')u&1O:[moi)'2=Vd5KR72=0E6LAR(+/#@80mS5hidn)NRbS3]PMfW2+=&LegaZXffSM\+*
+%@ESe'CB7@?)cYMPG3X<A98q?pK.WHgPW4%FOOV*1/i@`;U-_0)m/crX^pV$",X/"BsMn?;R::1,iO?7
+d*"n-c#gLp.bPO!Jk.*r-gP*5[&0>a[qOG`>on_9`Lhgl?)c@P!H#2#PFffIEAQP^TS_DS:Xem?lK2!M
+h#c+\A=NN1)ZW-WA38,70l'k`MSW-$8rA0><3W]ffk"ZqCrdIAQBE9>j@mZ'<HHGofhsV-;mOl@]Mb1L
+qSIIYnkLM"Z97EVYElh]%[>>bb#jgf**OlY[IHaK5,@C./bHbDalE":hWu.1N,@;S&gl,n3:<uV$;N?L
+*(2O_s!JrF=fbn$ki"!LOY9qefX_V\<NFjuO0ngY8TpJ(,;39KIP'3^N)o:sU^S>oeCuK%7\,dgAiUN1
+E!0r_=$ol73>k&7]_*E"mUSrX[62980+uUk50ME#I*V:L4N8s+bi=/qMstu,ntJ5f[(HSa5@JhaGYD:Q
+]auqs7`nFM/]DAtfVG=ND6[_hnTB=9[;GHTf&F!MBNQP7P.LnAZ2VP"Ploh`?NTa8nEUYFj3^8B4<?t>
+4SBp^*fhF-*fhL/*r?NkO.Sgf4:WJt*n-E0W]KmAKl)1[L<V@'WjXmHBl;cn9--aK@lTjrE@*#k?-6on
+,:;=;+3B=[oI&q3p0&\dDEW8m^^H(gHjR8,7ldq.4hG]/>/mf;Hl1F^:B&.Xiqu!h(RA"GpXOmI2eJ(p
+-Ufu7H4'I5!71?\VoB`KajX::mq>=Rr&Q;g]E7s$-kZ.E)/3T4mfoT]_V3^s3J#ALKI7nF?TacHK]qhj
+L<ncjl]HN[$fPFZ;`(\GZEhSIf%/9H@>qA*jpO7b7bY=!,<-,5gQ6!\>V]AQ)^-GB`&C"Q_Tt5F^2b04
+H^dXF*&#KkrUdWPo<maGSjIV2C<A6%Y#l1eDB-11=5MCe/mQ;H^`5k(:$aRZO01rVm/hX\fYmD8f*Dj@
+M@i=qKg0)_(>4O.G!a5^E2>bO$]QiDc\2C6pdgJSEti>7EGJ-(WqC@QJiDd@NbtVSKCL`LBr7+Q7e(#%
+mfT9"IKcR0OZpuAD#Y..(\(Ya*`U>DQ9W"+'>%SR14Rbu3okUD1UoZtSAfKYf.IftGdnZe:>-X$>r]=V
+G-"HZ$ThCqcd_nA%GR%YOrq)?cB9h+fAIVB(kUJ,MLq_e+>iX=AF@bgIcap`;p5$2F+]o@5&$NLhu:.I
+2<(<.=8A484n4$P`>fQKA"tBRWbq]tDur6ODulS&f!BB<ZPSc21WW3#buP0(+9gU#Z,bH/SFFh24G?`5
+dOt)^QkNbrnhfi)90SEq&n`q[F;s7b!nXc$g#@aPQN3qbFeWl+!e=Zt`EF'M1(Bm%7HR8DbV4gg<TZ"1
+'QY,(Ci/)_["1h766XD'&ADrraHq=DH%OF$jsfp?jsbDCGm`Bc4nAYbhNNN6HSW+QHSVNRk<)"p3=KZH
+@5,_A#.Kh(3M>-L01N,n^DOYar*o;enr(m9jVO\;jVOZqjVO[\jEPdIJ4jW(1Ou\+n/U@A-XG!&R,,`f
+2W1\3O?*%L7g,>@T`!f8eMl#PBrq/m2=C@'l+[6\!TC@KAA[MWaFrFRGAPIZkLE8R^YhJV5O]iFIg_\G
+iO=6VK\u;C'>=b?fe%PhWL9K1abNRi>otj#+Z';<n+i%OCHc:GQ`]p-obCOtip.a^cf<UjY!FG)PRTLL
++"jYG+4_li`+jB7`VE<s"4AVj".>pGko/fq8/"=:R5@Xn#Q]c2U1bel!_n`0,C>VAYsbZH&PH@FJ$f#/
+0td=Kg'>AR25F7&YOo!<mI]$*rRjT2aR!Q]%Fi)aOtJSn?+UM2'/_)[:p`0l2g4bJBatZEkin+Um_FDG
+q;M6)[I9OhMIS=<lFaD[8\^p:_H)J0l0'R9&ZuGO_>dFFCb.uJQlb(Q4<5Au742_H^C[$nr;0XJ4b3Tg
+[;48b%t<.Gdkk?8S<Vi`;Poe&S_S0PK8iOs+@Vd0N*gN+=Plp50G^#i&Kg"CSmrqAknTi"D:*>YSUrma
+g=r&8<Pj&ND`$13'HCOjG_kBC'T)*ekL$!:6XuRpIX?)+^V5+S2cXNJB2ec80tlUL?G#q-m,hbS%$"V@
+p"JQ?igh1:m'G\$*s_?+,4a,JI@3GnX*+U"_Zr.(+*>1jkFAnU9>ZXAU\g3ArglE9&,uBU"0[/n3+!B'
+W[)MC"?*YACpqa=bi'p-F[R+Y&Jh':>DS9I;-PEL7\\5FC1<[_U$dQmm+CP5IQgiD>SQGm;oRG4k5.U/
+0D?:mI/C=6)f;AM:/Ut^\F':\li2"qaZh<t\"cP;!(<3T?G(>oo5D,:=$o+C?]KqCU?geEFjWG&V"PRp
+&9$#`m3'G9"&tosqAZg/@%\C2I=Z6p1:0Yl"+@)T)so1U@.,fWm/arHR8d:MJXMQVC8K5]=Jm_KIXjdB
+83[K$Qla[fJ0ST]0*O=-3O'X`"r\'Q&`>h%Y8I@YUo\`'^eHY_XTc5&7^\ik\4-8s4VZgTU@:6TdipBk
+I9NLLkSE!O'mP*-*Z_.eTF%\P6@O])QsDsH.[1,u#K\!Fdp$""eZ=M1#$Z$(ZO5i+BWp@?TH^qnB%D7/
+h#sWFD^p`NF:Yfb85;E[:q^5Oc;Ss`!7br9/Ss$74_<U(m:SQ#s-3*J/tuGNgXsJtKtqF1bXL_J,7?@i
+'BEj1Ilon*aW+o61dn83AfE7FcXE_u9)ggC=\p"(7u!%6Y7^]'TMPP?@sg_akMgC`EYfUsdCeJO#2(2D
+hQ;Br<4m&15-"(TYi[P!iN8/Ok#@VVm[UO"bZs@LQZDI&pjXBX+4dX`csI+Oe#J=,^c=d&n:"<LdpP?/
+57NYh_**Nu%GYGtPrZ:2pA@k$5I#/DZ?u(p.mKdY_mpagr"[aHSA,e@EE+%EftN*$X1t;gS`@?f>ZH3j
+dG.dX,4]pij-88?@>Es&4"OKq4Pb_H)9:8fq`(0Ie[V>KnkIYS^43jk=+).,aXsOX(4cqM6KaT:7HMS5
+5VqW;.CtD!kNC3=e+gS7q$"nkh'kl'g`'1Rk*3jhL&JE!FZWhT#NI(1R)?@JnB0)&ZC7m>1Wud3mOB<F
+<?1UlEeaPIK4D$_#X<cE%HM2B7nrD$SI/J?MJ9$\[%L0[X#c.:>Z)WgX'F4+E];'H25pPfMT*QlPBH<B
+2jEaIeeu%@g_SZi^/+`r>koI@22thoJ$T#-Ig:8=C[r)9A@gh.nJ+P$rtk!a7oB995m%NRR_tlI7kn;C
+L?s85#0T`VHa<+&O5K'$Eo(6pn-XUq4Y6-9Re-B$rhtBq!Tfi]GEbPb2*A\G,P/,p;d\J77]S.F#9J`B
+DopA\Sjp8ME&Btm*&[^S4k/0Z~>
+endstream
+endobj
+{{object 8 0}} <<
+  {{streamlen}}
+>>
+stream
+/CIDInit/ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo<<
+/Registry (Adobe)
+/Ordering (UCS)
+/Supplement 0
+>> def
+/CMapName/Adobe-Identity-UCS def
+/CMapType 2 def
+1 begincodespacerange
+<00> <FF>
+endcodespacerange
+5 beginbfchar
+<01> <05DF>
+<02> <05D9>
+<03> <05DE>
+<04> <05E0>
+<05> <05D1>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/hebrew_mirrored.pdf b/testing/resources/hebrew_mirrored.pdf
new file mode 100644
index 0000000..1134350
--- /dev/null
+++ b/testing/resources/hebrew_mirrored.pdf
@@ -0,0 +1,175 @@
+%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 200 200]
+  /Resources <<
+    /ProcSet [/PDF /Text]
+    /Font <<
+      /F1 5 0 R
+    >>
+  >>
+>>
+endobj
+4 0 obj <<
+  /Length 110
+>>
+stream
+BT
+/F1 12 Tf
+150 160 Td
+[<01>2<02>2<03>-4<02>2<04>5<05>]TJ
+ET
+
+BT
+0 100 Td
+-1 0 0 1 50 40 Tm
+[<01>5<05>]TJ
+ET
+endstream
+endobj
+5 0 obj <<
+  /Type /Font
+  /Subtype /TrueType
+  /BaseFont /BAAAAA+NotoSansHebrew-Regular
+  /FirstChar 0
+  /FontDescriptor 6 0 R
+  /LastChar 5
+  /ToUnicode 8 0 R
+  /Widths [600 294 235 645 397 542]
+>>
+endobj
+6 0 obj <<
+  /Type /FontDescriptor
+  /Ascent 1069
+  /CapHeight 869
+  /Descent -293
+  /Flags 4
+  /FontBBox [-210 -252 716 869]
+  /FontFile2 7 0 R
+  /FontName /BAAAAA+NotoSansHebrew-Regular
+  /ItalicAngle 0
+  /StemV 80
+>>
+endobj
+7 0 obj <<
+  /Filter [/ASCII85Decode /FlateDecode]
+  /Length 4240
+>>
+stream
+GhVOeCMXsCFZt#(%p<i9AU.uO6]Ye/ifKHXbLV!I1<gsgHY$Eg-tbPt@rk=Ap?l+FQ/u;^8JASXVQS>V
+nuG<j"nF$,Rii%*89oFrq6<34,1m)cJ0IF5(22*&"c<?^q>^jZEkc[.-qdl^dk1F&,fKT9F2)eaH/1QX
+<gN4)W0n]g:798;]<j42dYR+b7&$II`er0Do2PVi55OH.DU&3oF7^D>=p%W;pT6OOkC.gL0;aQZ%EQ]$
+CMpO/ouiOe*=oqMFW5p^ge<JWIt[XVg[cqr8aR%^g[TKTpYK&S\F4)WJbd&hhE(,./q'ef/\k-FOKm`h
+f=q)o6_0Sd-Ap"u/`'bn6!o+8Zu;5]Q^2D[J,6jbf.d4Ck't7.im"Z=^^/7D4VXdnJ*hX.ia&@S<Zl_D
+Xq`#Xlf3.[Q6GL-.IS+nj<JEQ1+=HefoeH8Qi0[)c<.\^P$4LTD?DamV./;?-PDR^8[b$k8'^LB2C4&'
+NUg=HC6k8A'.Knb7Wh)elDCX74)L`tc?`Z\Sb;i$>AElUWZdj+!8FWu:gnKPdkmGSM;%q39@mC[7<ZEH
+BP,jX746Y[8VL'e=mlrkg+[&/4Xn#1'(72pCc`cXNN+/Z0?DM&g%BgA@co7e)9J3X;X\\(5@"=N^/d""
+T`@poCcT@G`,Q43B>^KnLk;$<#C1`ZRI:qa#-tMr)R?VE.RR\7=sKe@N)#YuA]JfMaHgYN/!?c&OsZTe
+^cXe0%l-1*krrj[$8W`Wl)*K?>t9dJirfrR7MYH\=XPN5Q2qL_I4eudg4b]KRT\<OAl/T-PZ'?3dZ$p;
+<A/YSC[`O')u&1O:[moi)'2=Vd5KR72=0E6LAR(+/#@80mS5hidn)NRbS3]PMfW2+=&LegaZXffSM\+*
+%@ESe'CB7@?)cYMPG3X<A98q?pK.WHgPW4%FOOV*1/i@`;U-_0)m/crX^pV$",X/"BsMn?;R::1,iO?7
+d*"n-c#gLp.bPO!Jk.*r-gP*5[&0>a[qOG`>on_9`Lhgl?)c@P!H#2#PFffIEAQP^TS_DS:Xem?lK2!M
+h#c+\A=NN1)ZW-WA38,70l'k`MSW-$8rA0><3W]ffk"ZqCrdIAQBE9>j@mZ'<HHGofhsV-;mOl@]Mb1L
+qSIIYnkLM"Z97EVYElh]%[>>bb#jgf**OlY[IHaK5,@C./bHbDalE":hWu.1N,@;S&gl,n3:<uV$;N?L
+*(2O_s!JrF=fbn$ki"!LOY9qefX_V\<NFjuO0ngY8TpJ(,;39KIP'3^N)o:sU^S>oeCuK%7\,dgAiUN1
+E!0r_=$ol73>k&7]_*E"mUSrX[62980+uUk50ME#I*V:L4N8s+bi=/qMstu,ntJ5f[(HSa5@JhaGYD:Q
+]auqs7`nFM/]DAtfVG=ND6[_hnTB=9[;GHTf&F!MBNQP7P.LnAZ2VP"Ploh`?NTa8nEUYFj3^8B4<?t>
+4SBp^*fhF-*fhL/*r?NkO.Sgf4:WJt*n-E0W]KmAKl)1[L<V@'WjXmHBl;cn9--aK@lTjrE@*#k?-6on
+,:;=;+3B=[oI&q3p0&\dDEW8m^^H(gHjR8,7ldq.4hG]/>/mf;Hl1F^:B&.Xiqu!h(RA"GpXOmI2eJ(p
+-Ufu7H4'I5!71?\VoB`KajX::mq>=Rr&Q;g]E7s$-kZ.E)/3T4mfoT]_V3^s3J#ALKI7nF?TacHK]qhj
+L<ncjl]HN[$fPFZ;`(\GZEhSIf%/9H@>qA*jpO7b7bY=!,<-,5gQ6!\>V]AQ)^-GB`&C"Q_Tt5F^2b04
+H^dXF*&#KkrUdWPo<maGSjIV2C<A6%Y#l1eDB-11=5MCe/mQ;H^`5k(:$aRZO01rVm/hX\fYmD8f*Dj@
+M@i=qKg0)_(>4O.G!a5^E2>bO$]QiDc\2C6pdgJSEti>7EGJ-(WqC@QJiDd@NbtVSKCL`LBr7+Q7e(#%
+mfT9"IKcR0OZpuAD#Y..(\(Ya*`U>DQ9W"+'>%SR14Rbu3okUD1UoZtSAfKYf.IftGdnZe:>-X$>r]=V
+G-"HZ$ThCqcd_nA%GR%YOrq)?cB9h+fAIVB(kUJ,MLq_e+>iX=AF@bgIcap`;p5$2F+]o@5&$NLhu:.I
+2<(<.=8A484n4$P`>fQKA"tBRWbq]tDur6ODulS&f!BB<ZPSc21WW3#buP0(+9gU#Z,bH/SFFh24G?`5
+dOt)^QkNbrnhfi)90SEq&n`q[F;s7b!nXc$g#@aPQN3qbFeWl+!e=Zt`EF'M1(Bm%7HR8DbV4gg<TZ"1
+'QY,(Ci/)_["1h766XD'&ADrraHq=DH%OF$jsfp?jsbDCGm`Bc4nAYbhNNN6HSW+QHSVNRk<)"p3=KZH
+@5,_A#.Kh(3M>-L01N,n^DOYar*o;enr(m9jVO\;jVOZqjVO[\jEPdIJ4jW(1Ou\+n/U@A-XG!&R,,`f
+2W1\3O?*%L7g,>@T`!f8eMl#PBrq/m2=C@'l+[6\!TC@KAA[MWaFrFRGAPIZkLE8R^YhJV5O]iFIg_\G
+iO=6VK\u;C'>=b?fe%PhWL9K1abNRi>otj#+Z';<n+i%OCHc:GQ`]p-obCOtip.a^cf<UjY!FG)PRTLL
++"jYG+4_li`+jB7`VE<s"4AVj".>pGko/fq8/"=:R5@Xn#Q]c2U1bel!_n`0,C>VAYsbZH&PH@FJ$f#/
+0td=Kg'>AR25F7&YOo!<mI]$*rRjT2aR!Q]%Fi)aOtJSn?+UM2'/_)[:p`0l2g4bJBatZEkin+Um_FDG
+q;M6)[I9OhMIS=<lFaD[8\^p:_H)J0l0'R9&ZuGO_>dFFCb.uJQlb(Q4<5Au742_H^C[$nr;0XJ4b3Tg
+[;48b%t<.Gdkk?8S<Vi`;Poe&S_S0PK8iOs+@Vd0N*gN+=Plp50G^#i&Kg"CSmrqAknTi"D:*>YSUrma
+g=r&8<Pj&ND`$13'HCOjG_kBC'T)*ekL$!:6XuRpIX?)+^V5+S2cXNJB2ec80tlUL?G#q-m,hbS%$"V@
+p"JQ?igh1:m'G\$*s_?+,4a,JI@3GnX*+U"_Zr.(+*>1jkFAnU9>ZXAU\g3ArglE9&,uBU"0[/n3+!B'
+W[)MC"?*YACpqa=bi'p-F[R+Y&Jh':>DS9I;-PEL7\\5FC1<[_U$dQmm+CP5IQgiD>SQGm;oRG4k5.U/
+0D?:mI/C=6)f;AM:/Ut^\F':\li2"qaZh<t\"cP;!(<3T?G(>oo5D,:=$o+C?]KqCU?geEFjWG&V"PRp
+&9$#`m3'G9"&tosqAZg/@%\C2I=Z6p1:0Yl"+@)T)so1U@.,fWm/arHR8d:MJXMQVC8K5]=Jm_KIXjdB
+83[K$Qla[fJ0ST]0*O=-3O'X`"r\'Q&`>h%Y8I@YUo\`'^eHY_XTc5&7^\ik\4-8s4VZgTU@:6TdipBk
+I9NLLkSE!O'mP*-*Z_.eTF%\P6@O])QsDsH.[1,u#K\!Fdp$""eZ=M1#$Z$(ZO5i+BWp@?TH^qnB%D7/
+h#sWFD^p`NF:Yfb85;E[:q^5Oc;Ss`!7br9/Ss$74_<U(m:SQ#s-3*J/tuGNgXsJtKtqF1bXL_J,7?@i
+'BEj1Ilon*aW+o61dn83AfE7FcXE_u9)ggC=\p"(7u!%6Y7^]'TMPP?@sg_akMgC`EYfUsdCeJO#2(2D
+hQ;Br<4m&15-"(TYi[P!iN8/Ok#@VVm[UO"bZs@LQZDI&pjXBX+4dX`csI+Oe#J=,^c=d&n:"<LdpP?/
+57NYh_**Nu%GYGtPrZ:2pA@k$5I#/DZ?u(p.mKdY_mpagr"[aHSA,e@EE+%EftN*$X1t;gS`@?f>ZH3j
+dG.dX,4]pij-88?@>Es&4"OKq4Pb_H)9:8fq`(0Ie[V>KnkIYS^43jk=+).,aXsOX(4cqM6KaT:7HMS5
+5VqW;.CtD!kNC3=e+gS7q$"nkh'kl'g`'1Rk*3jhL&JE!FZWhT#NI(1R)?@JnB0)&ZC7m>1Wud3mOB<F
+<?1UlEeaPIK4D$_#X<cE%HM2B7nrD$SI/J?MJ9$\[%L0[X#c.:>Z)WgX'F4+E];'H25pPfMT*QlPBH<B
+2jEaIeeu%@g_SZi^/+`r>koI@22thoJ$T#-Ig:8=C[r)9A@gh.nJ+P$rtk!a7oB995m%NRR_tlI7kn;C
+L?s85#0T`VHa<+&O5K'$Eo(6pn-XUq4Y6-9Re-B$rhtBq!Tfi]GEbPb2*A\G,P/,p;d\J77]S.F#9J`B
+DopA\Sjp8ME&Btm*&[^S4k/0Z~>
+endstream
+endobj
+8 0 obj <<
+  /Length 377
+>>
+stream
+/CIDInit/ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo<<
+/Registry (Adobe)
+/Ordering (UCS)
+/Supplement 0
+>> def
+/CMapName/Adobe-Identity-UCS def
+/CMapType 2 def
+1 begincodespacerange
+<00> <FF>
+endcodespacerange
+5 beginbfchar
+<01> <05DF>
+<02> <05D9>
+<03> <05DE>
+<04> <05E0>
+<05> <05D1>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+endstream
+endobj
+xref
+0 9
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000131 00000 n 
+0000000309 00000 n 
+0000000471 00000 n 
+0000000678 00000 n 
+0000000905 00000 n 
+0000005238 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 9
+>>
+startxref
+5667
+%%EOF
diff --git a/testing/resources/hello_world.in b/testing/resources/hello_world.in
index d3cf265..754820a 100644
--- a/testing/resources/hello_world.in
+++ b/testing/resources/hello_world.in
@@ -6,9 +6,9 @@
 endobj
 {{object 2 0}} <<
   /Type /Pages
-  /MediaBox [ 0 0 200 200 ]
+  /MediaBox [0 0 200 200]
   /Count 1
-  /Kids [ 3 0 R ]
+  /Kids [3 0 R]
 >>
 endobj
 {{object 3 0}} <<
@@ -36,6 +36,7 @@
 >>
 endobj
 {{object 6 0}} <<
+  % Note this object deliberately does not use {{streamlen}}.
 >>
 stream
 BT
diff --git a/testing/resources/hello_world.pdf b/testing/resources/hello_world.pdf
index dcde8f7..48c714b 100644
--- a/testing/resources/hello_world.pdf
+++ b/testing/resources/hello_world.pdf
@@ -7,9 +7,9 @@
 endobj
 2 0 obj <<
   /Type /Pages
-  /MediaBox [ 0 0 200 200 ]
+  /MediaBox [0 0 200 200]
   /Count 1
-  /Kids [ 3 0 R ]
+  /Kids [3 0 R]
 >>
 endobj
 3 0 obj <<
@@ -37,6 +37,7 @@
 >>
 endobj
 6 0 obj <<
+  % Note this object deliberately does not use /Length 83.
 >>
 stream
 BT
@@ -54,11 +55,14 @@
 0000000000 65535 f 
 0000000015 00000 n 
 0000000068 00000 n 
-0000000161 00000 n 
-0000000303 00000 n 
-0000000381 00000 n 
-0000000457 00000 n 
-trailer<< /Root 1 0 R /Size 7 >>
+0000000157 00000 n 
+0000000299 00000 n 
+0000000377 00000 n 
+0000000453 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 7
+>>
 startxref
-578
+633
 %%EOF
diff --git a/testing/resources/hello_world_2_pages.in b/testing/resources/hello_world_2_pages.in
new file mode 100644
index 0000000..ec33354
--- /dev/null
+++ b/testing/resources/hello_world_2_pages.in
@@ -0,0 +1,67 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 2
+  /Kids [3 0 R 4 0 R]
+  /MediaBox [0 0 200 200]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <<
+      /F1 5 0 R
+      /F2 6 0 R
+    >>
+  >>
+  /Contents 7 0 R
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <<
+      /F1 5 0 R
+      /F2 6 0 R
+    >>
+  >>
+  /Contents 7 0 R
+>>
+endobj
+{{object 5 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Times-Roman
+>>
+endobj
+{{object 6 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+>>
+endobj
+{{object 7 0}} <<
+  {{streamlen}}
+>>
+stream
+BT
+20 50 Td
+/F1 12 Tf
+(Hello, world!) Tj
+0 50 Td
+/F2 16 Tf
+(Goodbye, world!) Tj
+ET
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/hello_world_2_pages.pdf b/testing/resources/hello_world_2_pages.pdf
new file mode 100644
index 0000000..4942e3a
--- /dev/null
+++ b/testing/resources/hello_world_2_pages.pdf
@@ -0,0 +1,81 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /MediaBox [0 0 200 200]
+  /Count 2
+  /Kids [3 0 R 4 0 R]
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <<
+      /F1 5 0 R
+      /F2 6 0 R
+    >>
+  >>
+  /Contents 7 0 R
+>>
+endobj
+4 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <<
+      /F1 5 0 R
+      /F2 6 0 R
+    >>
+  >>
+  /Contents 7 0 R
+>>
+endobj
+5 0 obj <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Times-Roman
+>>
+endobj
+6 0 obj <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+>>
+endobj
+7 0 obj <<
+  /Length 83
+>>
+stream
+BT
+20 50 Td
+/F1 12 Tf
+(Hello, world!) Tj
+0 50 Td
+/F2 16 Tf
+(Goodbye, world!) Tj
+ET
+endstream
+endobj
+xref
+0 8
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000163 00000 n 
+0000000305 00000 n 
+0000000447 00000 n 
+0000000525 00000 n 
+0000000601 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 8
+>>
+startxref
+735
+%%EOF
diff --git a/testing/resources/hello_world_2_pages_shared_resources_dict.in b/testing/resources/hello_world_2_pages_shared_resources_dict.in
new file mode 100644
index 0000000..9c30780
--- /dev/null
+++ b/testing/resources/hello_world_2_pages_shared_resources_dict.in
@@ -0,0 +1,64 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 2
+  /Kids [3 0 R 4 0 R]
+  /MediaBox [0 0 200 200]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources 5 0 R
+  /Contents 8 0 R
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources 5 0 R
+  /Contents 8 0 R
+>>
+endobj
+{{object 5 0}} <<
+  /Font <<
+    /F1 6 0 R
+    /F2 7 0 R
+  >>
+>>
+endobj
+{{object 6 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Times-Roman
+>>
+endobj
+{{object 7 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+>>
+endobj
+{{object 8 0}} <<
+  {{streamlen}}
+>>
+stream
+BT
+20 50 Td
+/F1 12 Tf
+(Hello, world!) Tj
+0 50 Td
+/F2 16 Tf
+(Goodbye, world!) Tj
+ET
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/hello_world_2_pages_shared_resources_dict.pdf b/testing/resources/hello_world_2_pages_shared_resources_dict.pdf
new file mode 100644
index 0000000..06b2531
--- /dev/null
+++ b/testing/resources/hello_world_2_pages_shared_resources_dict.pdf
@@ -0,0 +1,79 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /Count 2
+  /Kids [3 0 R 4 0 R]
+  /MediaBox [0 0 200 200]
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources 5 0 R
+  /Contents 8 0 R
+>>
+endobj
+4 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources 5 0 R
+  /Contents 8 0 R
+>>
+endobj
+5 0 obj <<
+  /Font <<
+    /F1 6 0 R
+    /F2 7 0 R
+  >>
+>>
+endobj
+6 0 obj <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Times-Roman
+>>
+endobj
+7 0 obj <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+>>
+endobj
+8 0 obj <<
+  /Length 83
+>>
+stream
+BT
+20 50 Td
+/F1 12 Tf
+(Hello, world!) Tj
+0 50 Td
+/F2 16 Tf
+(Goodbye, world!) Tj
+ET
+endstream
+endobj
+xref
+0 9
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000163 00000 n 
+0000000251 00000 n 
+0000000339 00000 n 
+0000000404 00000 n 
+0000000482 00000 n 
+0000000558 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 9
+>>
+startxref
+692
+%%EOF
diff --git a/testing/resources/hello_world_2_pages_split_streams.in b/testing/resources/hello_world_2_pages_split_streams.in
new file mode 100644
index 0000000..ef68f5c
--- /dev/null
+++ b/testing/resources/hello_world_2_pages_split_streams.in
@@ -0,0 +1,75 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 2
+  /Kids [3 0 R 4 0 R]
+  /MediaBox [0 0 200 200]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <<
+      /F1 5 0 R
+      /F2 6 0 R
+    >>
+  >>
+  /Contents 7 0 R
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <<
+      /F1 5 0 R
+      /F2 6 0 R
+    >>
+  >>
+  /Contents 7 0 R
+>>
+endobj
+{{object 5 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Times-Roman
+>>
+endobj
+{{object 6 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+>>
+endobj
+{{object 7 0}} [8 0 R 9 0 R]
+{{object 8 0}} <<
+  {{streamlen}}
+>>
+stream
+BT
+20 50 Td
+/F1 12 Tf
+(Hello, world!) Tj
+endstream
+endobj
+{{object 9 0}} <<
+  {{streamlen}}
+>>
+stream
+BT
+20 100 Td
+/F2 16 Tf
+(Goodbye, world!) Tj
+ET
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/hello_world_2_pages_split_streams.pdf b/testing/resources/hello_world_2_pages_split_streams.pdf
new file mode 100644
index 0000000..3ac829f
--- /dev/null
+++ b/testing/resources/hello_world_2_pages_split_streams.pdf
@@ -0,0 +1,91 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /Count 2
+  /Kids [3 0 R 4 0 R]
+  /MediaBox [0 0 200 200]
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <<
+      /F1 5 0 R
+      /F2 6 0 R
+    >>
+  >>
+  /Contents 7 0 R
+>>
+endobj
+4 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <<
+      /F1 5 0 R
+      /F2 6 0 R
+    >>
+  >>
+  /Contents 7 0 R
+>>
+endobj
+5 0 obj <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Times-Roman
+>>
+endobj
+6 0 obj <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+>>
+endobj
+7 0 obj [8 0 R 9 0 R]
+8 0 obj <<
+  /Length 41
+>>
+stream
+BT
+20 50 Td
+/F1 12 Tf
+(Hello, world!) Tj
+endstream
+endobj
+9 0 obj <<
+  /Length 47
+>>
+stream
+BT
+20 100 Td
+/F2 16 Tf
+(Goodbye, world!) Tj
+ET
+endstream
+endobj
+xref
+0 10
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000163 00000 n 
+0000000305 00000 n 
+0000000447 00000 n 
+0000000525 00000 n 
+0000000601 00000 n 
+0000000623 00000 n 
+0000000715 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 10
+>>
+startxref
+813
+%%EOF
diff --git a/testing/resources/ink_annot.in b/testing/resources/ink_annot.in
new file mode 100644
index 0000000..da90b29
--- /dev/null
+++ b/testing/resources/ink_annot.in
@@ -0,0 +1,48 @@
+{{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
+  /MediaBox [0 0 612 792]
+  /Annots [
+    4 0 R 5 0 R
+  ]
+  /Tabs /R
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Annot
+  /Subtype /Ink
+  /NM (Ink-1)
+  /F 4
+  /InkList [[159 296 350 411 472 243.42]]
+  /P 3 0 R
+  /C [1 0.90196 0]
+  /Rect [293 530 349 542]
+>>
+endobj
+{{object 5 0}} <<
+  /Type /Annot
+  /Subtype /Ink
+  /NM (Ink-2)
+  /F 4
+  /InkList [[259 396 450 511 572 343 42]]
+  /P 3 0 R
+  /C [1 0.90196 0]
+  /Rect [293 530 349 542]
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/ink_annot.pdf b/testing/resources/ink_annot.pdf
new file mode 100644
index 0000000..306f28d
--- /dev/null
+++ b/testing/resources/ink_annot.pdf
@@ -0,0 +1,60 @@
+%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
+  /MediaBox [0 0 612 792]
+  /Annots [
+    4 0 R 5 0 R
+  ]
+  /Tabs /R
+>>
+endobj
+4 0 obj <<
+  /Type /Annot
+  /Subtype /Ink
+  /NM (Ink-1)
+  /F 4
+  /InkList [[159 296 350 411 472 243.42]]
+  /P 3 0 R
+  /C [1 0.90196 0]
+  /Rect [293 530 349 542]
+>>
+endobj
+5 0 obj <<
+  /Type /Annot
+  /Subtype /Ink
+  /NM (Ink-2)
+  /F 4
+  /InkList [[259 396 450 511 572 343 42]]
+  /P 3 0 R
+  /C [1 0.90196 0]
+  /Rect [293 530 349 542]
+>>
+endobj
+xref
+0 6
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000131 00000 n 
+0000000251 00000 n 
+0000000422 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 6
+>>
+startxref
+593
+%%EOF
diff --git a/testing/resources/javascript/annot_properties.in b/testing/resources/javascript/annot_properties.in
index 939365c..e143ac8 100644
--- a/testing/resources/javascript/annot_properties.in
+++ b/testing/resources/javascript/annot_properties.in
@@ -74,6 +74,15 @@
 } catch (e) {
   app.alert("ERROR: " + e);
 }
+app.alert("Test setting empty name under changed name");
+try {
+  var annot = this.getAnnot(0, "nonesuch");
+  annot.name = "";
+  app.alert("name after empty name change: " + annot.name);
+} catch (e) {
+  app.alert("ERROR: " + e);
+}
+
 endstream
 endobj
 {{object 22 0}} <<
diff --git a/testing/resources/javascript/annot_properties_expected.txt b/testing/resources/javascript/annot_properties_expected.txt
index 54548e6..252fd2b 100644
--- a/testing/resources/javascript/annot_properties_expected.txt
+++ b/testing/resources/javascript/annot_properties_expected.txt
@@ -14,3 +14,5 @@
 Alert: SUCCESS: Document.getAnnot: Object no longer exists.
 Alert: Test lookup under changed name
 Alert: nonesuch after name change: object
+Alert: Test setting empty name under changed name
+Alert: name after empty name change: 
diff --git a/testing/resources/javascript/app_methods.in b/testing/resources/javascript/app_methods.in
index 81fa660..1c01e84 100644
--- a/testing/resources/javascript/app_methods.in
+++ b/testing/resources/javascript/app_methods.in
@@ -19,6 +19,7 @@
   /Parent 2 0 R
   /MediaBox [0 0 612 792]
 >>
+endobj
 % OpenAction action
 {{object 10 0}} <<
   /Type /Action
@@ -26,7 +27,7 @@
   /JS 11 0 R
 >>
 endobj
-% JS program to exexute
+% JS program to execute
 {{object 11 0}} <<
   {{streamlen}}
 >>
@@ -34,7 +35,8 @@
 {{include expect.js}}
 
 try {
-  expect("app.alert('message', 1, 2, 'title')", 0);
+  // Test unicode support, no particular reason for these CJK characters.
+  expect("app.alert('message \u4023', 1, 2, 'title \u4024')", 0);
   expect("app.alert({'cMsg': 'message', 'cTitle': 'title'})", 0);
   expect("app.alert({'cMsg': 'message', 'cTitle': 'title', 'nIcon': 3, 'nType': 4})", 0);
   expect("app.alert(undefined)", 0);
diff --git a/testing/resources/javascript/app_methods_expected.txt b/testing/resources/javascript/app_methods_expected.txt
index 015ff28..86fb3a9 100644
--- a/testing/resources/javascript/app_methods_expected.txt
+++ b/testing/resources/javascript/app_methods_expected.txt
@@ -1,5 +1,5 @@
-title[icon=1,type=2]: message
-Alert: PASS: app.alert('message', 1, 2, 'title') = 0
+title 䀤[icon=1,type=2]: message 䀣
+Alert: PASS: app.alert('message 䀣', 1, 2, 'title 䀤') = 0
 title: message
 Alert: PASS: app.alert({'cMsg': 'message', 'cTitle': 'title'}) = 0
 title[icon=3,type=4]: message
diff --git a/testing/resources/javascript/app_properties.in b/testing/resources/javascript/app_properties.in
index 1355e64..290fc24 100644
--- a/testing/resources/javascript/app_properties.in
+++ b/testing/resources/javascript/app_properties.in
@@ -25,6 +25,7 @@
   >>
   /MediaBox [0 0 612 792]
 >>
+endobj
 % Page number 1.
 {{object 4 0}} <<
   /Type /Page
@@ -34,6 +35,7 @@
   >>
   /MediaBox [0 0 612 792]
 >>
+endobj
 % Page number 2.
 {{object 5 0}} <<
   /Type /Page
@@ -43,6 +45,7 @@
   >>
   /MediaBox [0 0 612 792]
 >>
+endobj
 % Page number 3.
 {{object 6 0}} <<
   /Type /Page
@@ -52,6 +55,7 @@
   >>
   /MediaBox [0 0 612 792]
 >>
+endobj
 
 % Info
 {{object 9 0}} <<
@@ -66,7 +70,7 @@
   /JS 11 0 R
 >>
 endobj
-% JS program to exexute
+% JS program to execute
 {{object 11 0}} <<
   {{streamlen}}
 >>
diff --git a/testing/resources/javascript/apply.in b/testing/resources/javascript/apply.in
index d944e83..e8ec5e2 100644
--- a/testing/resources/javascript/apply.in
+++ b/testing/resources/javascript/apply.in
@@ -23,6 +23,7 @@
   /Contents [21 0 R]
   /MediaBox [0 0 612 792]
 >>
+endobj
 % OpenAction action
 {{object 10 0}} <<
   /Type /Action
@@ -30,7 +31,7 @@
   /JS 11 0 R
 >>
 endobj
-% JS program to exexute
+% JS program to execute
 {{object 11 0}} <<
   {{streamlen}}
 >>
diff --git a/testing/resources/javascript/array_buffer.in b/testing/resources/javascript/array_buffer.in
index 06371ba..3790c6c 100644
--- a/testing/resources/javascript/array_buffer.in
+++ b/testing/resources/javascript/array_buffer.in
@@ -23,6 +23,7 @@
   /Contents [21 0 R]
   /MediaBox [0 0 612 792]
 >>
+endobj
 % OpenAction action
 {{object 10 0}} <<
   /Type /Action
@@ -30,7 +31,7 @@
   /JS 11 0 R
 >>
 endobj
-% JS program to exexute
+% JS program to execute
 {{object 11 0}} <<
   {{streamlen}}
 >>
diff --git a/testing/resources/javascript/bug_1098213.in b/testing/resources/javascript/bug_1098213.in
new file mode 100644
index 0000000..0c99311
--- /dev/null
+++ b/testing/resources/javascript/bug_1098213.in
@@ -0,0 +1,65 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /OpenAction 8 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 2
+  /Kids [
+    3 0 R
+    4 0 R
+  ]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /CropBox [179 173 200 75]
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /CropBox [127 214 186 29]
+  /Annots [
+    5 0 R
+    6 0 R
+    7 0 R
+  ]
+>>
+endobj
+{{object 5 0}} <<
+  /Type /Annot
+>
+endobj
+{{object 6 0}} <<
+  /Type /Annot
+>>
+endobj
+{{object 7 0}} <<
+  /Type /Annot
+>>
+endobj
+{{object 8 0}} <<
+  /Type /Action
+  /S /JavaScript
+  /JS (
+    Object.defineProperty(Array.prototype, 1, {
+      set: (v) => {
+        Object.defineProperty(Array.prototype, 1, {
+          get: () => {}
+        });
+      }
+    });
+    try { this.getAnnots(); } catch (e) { app.alert('Caught: ' + e); }
+    app.alert('Done');
+  )
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/bug_1098213_expected.txt b/testing/resources/javascript/bug_1098213_expected.txt
new file mode 100644
index 0000000..9de1818
--- /dev/null
+++ b/testing/resources/javascript/bug_1098213_expected.txt
@@ -0,0 +1 @@
+Alert: Done
diff --git a/testing/resources/javascript/bug_1142688.in b/testing/resources/javascript/bug_1142688.in
new file mode 100644
index 0000000..6d3825d
--- /dev/null
+++ b/testing/resources/javascript/bug_1142688.in
@@ -0,0 +1,78 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 5 0 R
+  /AcroForm <<
+    /Fields [
+      3 0 R
+      2 0 R
+    ]
+  >>
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Tx
+  /T (tf1)
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Tx
+  /T (tf0)
+  /AA <<
+    /F 10 0 R
+  >>
+>>
+endobj
+{{object 5 0}} <<
+  /Type /Pages
+  /Count 2
+  /Kids [
+    8 0 R
+    9 0 R
+  ]
+>>
+endobj
+{{object 8 0}} <<
+  /Type /Page
+  /Parent 5 0 R
+  /Annots [3 0 R]
+>>
+endobj
+{{object 9 0}} <<
+  /Type /Page
+  /Parent 5 0 R
+  /Annots [2 0 R]
+>>
+endobj
+{{object 10 0}} <<
+  /Type /Action
+  /S /JavaScript
+  /JS 13 0 R
+>>
+{{object 13 0}} <<
+  {{streamlen}}
+>>
+stream
+function f3() {
+  // Setup dubious values in event recorder.
+  try { AFSpecial_Format(2); } catch(e) {}
+  try { AFNumber_Format(-302907477,0,1,-6,"",true); } catch(e) {}
+
+  // Exhaust call stack, then do work upon exiting each frame. The
+  // objective is to get any call() made under the covers to throw
+  // with a stack size exception.
+  try { f3(); } catch(e) {}
+  try { AFDate_Keystroke("yymm-dd"); } catch(e) {}
+}
+f3();
+app.alert('Done.');
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/bug_1142688_expected.txt b/testing/resources/javascript/bug_1142688_expected.txt
new file mode 100644
index 0000000..7cb32ca
--- /dev/null
+++ b/testing/resources/javascript/bug_1142688_expected.txt
@@ -0,0 +1 @@
+Alert: Done.
diff --git a/testing/resources/javascript/bug_1314658.in b/testing/resources/javascript/bug_1314658.in
new file mode 100644
index 0000000..f05b3ed
--- /dev/null
+++ b/testing/resources/javascript/bug_1314658.in
@@ -0,0 +1,29 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /]
+  /Subtype /Widget
+  /T (0)
+  /FT /Ch
+  /AA <<
+    /F 5 0 R
+  >>
+  /Annots 4 0 R
+4 0 obj [3 0 R /Ff 393216]
+  /AP<</N<<>>
+stream
+{{object 5 0}} <<
+  /JS (app.alert('done'))
+>>
+endobj
+{{trailer}}
+%%EOF
diff --git a/testing/resources/javascript/bug_1314658_expected.txt b/testing/resources/javascript/bug_1314658_expected.txt
new file mode 100644
index 0000000..daa1eca
--- /dev/null
+++ b/testing/resources/javascript/bug_1314658_expected.txt
@@ -0,0 +1 @@
+Alert: done
diff --git a/testing/resources/javascript/bug_1335681.in b/testing/resources/javascript/bug_1335681.in
new file mode 100644
index 0000000..254e596
--- /dev/null
+++ b/testing/resources/javascript/bug_1335681.in
@@ -0,0 +1,38 @@
+{{header}}
+{{object 1 0}} <<
+  /Pages 1 0 R
+  /OpenAction 2 0 R
+  /Names <<
+      /Dests 3 0 R
+  >>
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Action
+  /S /JavaScript
+  /JS (
+    app.alert\("Starting"\);
+    this.gotoNamedDest\(""\);
+  )
+>>
+endobj
+{{object 3 0}} <<
+  /Kids 4 0 R
+>>
+endobj
+{{object 4 0}} [
+  << >>
+  << >>
+  <<
+    /Kids [
+      <<
+        /Limits 4 0 R
+      >>
+    ]
+  >>
+]
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/bug_1335681_expected.txt b/testing/resources/javascript/bug_1335681_expected.txt
new file mode 100644
index 0000000..80a6951
--- /dev/null
+++ b/testing/resources/javascript/bug_1335681_expected.txt
@@ -0,0 +1 @@
+Alert: Starting
diff --git a/testing/resources/javascript/bug_1358075.in b/testing/resources/javascript/bug_1358075.in
new file mode 100644
index 0000000..b503bf2
--- /dev/null
+++ b/testing/resources/javascript/bug_1358075.in
@@ -0,0 +1,39 @@
+{{header}}
+{{object 1 0}} <<
+  /Pages 1 0 R
+  /OpenAction 2 0 R
+  /Names <<
+    /Dests 3 0 R
+  >>
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Action
+  /S /JavaScript
+  /JS (
+        this.gotoNamedDest\("2"\);
+        app.alert\("completed"\);
+  )
+>>
+endobj
+{{object 3 0}} <<
+  /Kids 4 0 R
+>>
+endobj
+{{object 4 0}} [
+  (1)
+  (3)
+  <<
+    /Kids [
+      <<
+        /Limits 4 0 R
+        /Names [(2) []]
+      >>
+    ]
+  >>
+]
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/bug_1358075_expected.txt b/testing/resources/javascript/bug_1358075_expected.txt
new file mode 100644
index 0000000..13d460b
--- /dev/null
+++ b/testing/resources/javascript/bug_1358075_expected.txt
@@ -0,0 +1 @@
+Alert: completed
diff --git a/testing/resources/javascript/bug_1445426.evt b/testing/resources/javascript/bug_1445426.evt
new file mode 100644
index 0000000..265e85b
--- /dev/null
+++ b/testing/resources/javascript/bug_1445426.evt
@@ -0,0 +1,3 @@
+mousedown,left,202,697
+mouseup,left,202,697
+keycode,40
diff --git a/testing/resources/javascript/bug_1445426.in b/testing/resources/javascript/bug_1445426.in
new file mode 100644
index 0000000..1483da7
--- /dev/null
+++ b/testing/resources/javascript/bug_1445426.in
@@ -0,0 +1,114 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm 4 0 R
+  /OpenAction 40 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 2
+  /Kids [
+    32 0 R
+    34 0 R
+  ]
+>>
+endobj
+% Forms
+{{object 4 0}} <<
+  /Fields [
+    10 0 R
+    11 0 R
+  ]
+>>
+endobj
+% Fields
+{{object 10 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Tx
+  /T (Field_TextEdit)
+  /Rect [0 0 612 792]
+>>
+{{object 11 0}} <<
+  /T (Field_ComboBox)
+  /Parent 4 0 R
+  /Kids [12 0 R]
+  /Opt [(a) (b) (c) (d)]
+  /V [(a)]
+>>
+endobj
+{{object 12 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Ch
+  /Ff 131072
+  /Parent 11 0 R
+  /Kids [13 0 R]
+>>
+endobj
+{{object 13 0}} <<
+  /Parent 12 0 R
+  /Type /Annot
+  /Subtype /Widget
+  /Rect [0 0 612 792]
+  /AA << /K 20 0 R >>
+>>
+endobj
+% Pages
+{{object 32 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 612 792]
+  /Annots [13 0 R]
+
+>>
+endobj
+{{object 34 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 612 792]
+  /Annots [10 0 R]
+>>
+endobj
+% Document JS Action
+{{object 40 0}} <<
+  /Type /Action
+  /S /JavaScript
+  /JS 41 0 R
+>>
+endobj
+% JS program to exexute
+{{object 41 0}} <<
+  {{streamlen}}
+>>
+stream
+var field_text = this.getField("Field_TextEdit");
+var field_combobox = this.getField("Field_ComboBox");
+field_combobox.setFocus();
+this.__defineGetter__("filesize", function new_getter(){
+                                    field_text.setFocus();
+                                    field_combobox.borderStyle="dashed";
+                                    field_combobox.setFocus();
+                                  });
+endstream
+endobj
+% OpenAction action
+{{object 20 0}} <<
+  /S /JavaScript
+  /JS 21 0 R
+>>
+endobj
+% JS program to exexute
+{{object 21 0}} <<
+  {{streamlen}}
+>>
+stream
+var t = this.filesize;
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/bug_361.in b/testing/resources/javascript/bug_361.in
index 4af86a6..386142a 100644
--- a/testing/resources/javascript/bug_361.in
+++ b/testing/resources/javascript/bug_361.in
@@ -24,10 +24,12 @@
   /Contents [21 0 R]
   /MediaBox [0 0 612 792]
 >>
+endobj
 % Forms
 {{object 4 0}} <<
   /Fields [5 0 R]
 >>
+endobj
 % Field
 {{object 5 0}} <<
  /FT /Tx
@@ -36,6 +38,7 @@
  /Subtype /Widget
  /Rect [100 200 150 250]
 >>
+endobj
 % OpenAction action
 {{object 10 0}} <<
   /Type /Action
@@ -43,7 +46,7 @@
   /JS 11 0 R
 >>
 endobj
-% JS program to exexute
+% JS program to execute
 {{object 11 0}} <<
   {{streamlen}}
 >>
diff --git a/testing/resources/javascript/bug_492_1.in b/testing/resources/javascript/bug_492_1.in
index 9d48ad5..4b8026f 100644
--- a/testing/resources/javascript/bug_492_1.in
+++ b/testing/resources/javascript/bug_492_1.in
@@ -50,7 +50,7 @@
   /JS 21 0 R
 >>
 endobj
-% JS program to exexute
+% JS program to execute
 {{object 21 0}} <<
   {{streamlen}}
 >>
diff --git a/testing/resources/javascript/bug_494057.in b/testing/resources/javascript/bug_494057.in
index bbfa13e..3615d03 100644
--- a/testing/resources/javascript/bug_494057.in
+++ b/testing/resources/javascript/bug_494057.in
@@ -87,7 +87,7 @@
   /JS 11 0 R
 >>
 endobj
-% JS program to exexute
+% JS program to execute
 {{object 11 0}} <<
   {{streamlen}}
 >>
diff --git a/testing/resources/javascript/bug_679642.in b/testing/resources/javascript/bug_679642.in
index 644a259..b63cb70 100644
--- a/testing/resources/javascript/bug_679642.in
+++ b/testing/resources/javascript/bug_679642.in
@@ -86,7 +86,7 @@
   /JS 11 0 R
 >>
 endobj
-% JS program to exexute
+% JS program to execute
 {{object 11 0}} <<
   {{streamlen}}
 >>
diff --git a/testing/resources/javascript/bug_679643.in b/testing/resources/javascript/bug_679643.in
index c60fc0f..5ebe312 100644
--- a/testing/resources/javascript/bug_679643.in
+++ b/testing/resources/javascript/bug_679643.in
@@ -86,7 +86,7 @@
   /JS 11 0 R
 >>
 endobj
-% JS program to exexute
+% JS program to execute
 {{object 11 0}} <<
   {{streamlen}}
 >>
diff --git a/testing/resources/javascript/bug_695826.in b/testing/resources/javascript/bug_695826.in
index e17eaf1..9d32be7 100644
--- a/testing/resources/javascript/bug_695826.in
+++ b/testing/resources/javascript/bug_695826.in
@@ -23,6 +23,7 @@
   /Contents [21 0 R]
   /MediaBox [0 0 612 792]
 >>
+endobj
 % OpenAction action
 {{object 10 0}} <<
   /Type /Action
@@ -30,7 +31,7 @@
   /JS 11 0 R
 >>
 endobj
-% JS program to exexute
+% JS program to execute
 {{object 11 0}} <<
   {{streamlen}}
 >>
diff --git a/testing/resources/javascript/bug_735912.in b/testing/resources/javascript/bug_735912.in
index 06bd9a3..f3db5a2 100644
--- a/testing/resources/javascript/bug_735912.in
+++ b/testing/resources/javascript/bug_735912.in
@@ -53,7 +53,7 @@
   /JS 31 0 R
 >>
 endobj
-% JS program to exexute
+% JS program to execute
 {{object 31 0}} <<
   {{streamlen}}
 >>
@@ -69,7 +69,7 @@
   /JS 35 0 R
 >>
 endobj
-% JS program to exexute
+% JS program to execute
 {{object 35 0}} <<
   {{streamlen}}
 >>
@@ -85,7 +85,7 @@
   /JS 37 0 R
 >>
 endobj
-% JS program to exexute
+% JS program to execute
 {{object 37 0}} <<
   {{streamlen}}
 >>
diff --git a/testing/resources/javascript/bug_740166.in b/testing/resources/javascript/bug_740166.in
index 425374d..6f0c829 100644
--- a/testing/resources/javascript/bug_740166.in
+++ b/testing/resources/javascript/bug_740166.in
@@ -24,10 +24,12 @@
   /Contents [21 0 R]
   /MediaBox [0 0 612 792]
 >>
+endobj
 % Forms
 {{object 4 0}} <<
   /Fields [5 0 R]
 >>
+endobj
 % Field
 {{object 5 0}} <<
  /FT /Tx
@@ -36,6 +38,7 @@
  /Subtype /Widget
  /Rect [100 200 150 250]
 >>
+endobj
 % OpenAction action
 {{object 10 0}} <<
   /Type /Action
@@ -43,7 +46,7 @@
   /JS 11 0 R
 >>
 endobj
-% JS program to exexute
+% JS program to execute
 {{object 11 0}} <<
   {{streamlen}}
 >>
diff --git a/testing/resources/javascript/bug_959274_1.in b/testing/resources/javascript/bug_959274_1.in
index 74909c0..9efb9dc 100644
--- a/testing/resources/javascript/bug_959274_1.in
+++ b/testing/resources/javascript/bug_959274_1.in
@@ -23,6 +23,7 @@
   /Contents [21 0 R]
   /MediaBox [0 0 612 792]
 >>
+endobj
 % OpenAction action
 {{object 10 0}} <<
   /Type /Action
diff --git a/testing/resources/javascript/color_methods.in b/testing/resources/javascript/color_methods.in
index bf03bb4..44afced 100644
--- a/testing/resources/javascript/color_methods.in
+++ b/testing/resources/javascript/color_methods.in
@@ -27,7 +27,7 @@
   /JS 11 0 R
 >>
 endobj
-% JS program to exexute
+% JS program to execute
 {{object 11 0}} <<
   {{streamlen}}
 >>
diff --git a/testing/resources/javascript/color_properties.in b/testing/resources/javascript/color_properties.in
index 7d09656..0fea81e 100644
--- a/testing/resources/javascript/color_properties.in
+++ b/testing/resources/javascript/color_properties.in
@@ -20,6 +20,7 @@
   /Contents [21 0 R]
   /MediaBox [0 0 612 792]
 >>
+endobj
 % OpenAction action
 {{object 10 0}} <<
   /Type /Action
@@ -27,7 +28,7 @@
   /JS 11 0 R
 >>
 endobj
-% JS program to exexute
+% JS program to execute
 {{object 11 0}} <<
   {{streamlen}}
 >>
diff --git a/testing/resources/javascript/console_methods.in b/testing/resources/javascript/console_methods.in
index 0fbba3f..0dc74e3 100644
--- a/testing/resources/javascript/console_methods.in
+++ b/testing/resources/javascript/console_methods.in
@@ -27,7 +27,7 @@
   /JS 11 0 R
 >>
 endobj
-% JS program to exexute
+% JS program to execute
 {{object 11 0}} <<
   {{streamlen}}
 >>
diff --git a/testing/resources/javascript/constructor.in b/testing/resources/javascript/constructor.in
index 1211f89..90c41c0 100644
--- a/testing/resources/javascript/constructor.in
+++ b/testing/resources/javascript/constructor.in
@@ -19,6 +19,7 @@
   /Parent 2 0 R
   /MediaBox [0 0 612 792]
 >>
+endobj
 % OpenAction action
 {{object 10 0}} <<
   /Type /Action
@@ -26,34 +27,18 @@
   /JS 11 0 R
 >>
 endobj
-% JS program to exexute
+% JS program to execute
 {{object 11 0}} <<
   {{streamlen}}
 >>
 stream
-function testIllegalConstructor(name, allowed) {
-  const constructorString = name + ".constructor";
-  let constructor;
-  try {
-    constructor = eval(constructorString);
-  } catch (e) {
-    app.alert("FAIL: No such " + constructorString);
-    return;
-  }
-  try {
-    constructor();
-    app.alert("FAIL: " + constructorString + "(): returned");
-  } catch (e) {
-    app.alert("PASS: " + constructorString + "(): " + e);
-  }
-  try {
-    new constructor;
-    app.alert("FAIL: new " + constructorString + ": returned");
-  } catch (e) {
-    app.alert("PASS: new " + constructorString + ": " + e);
-  }
-}
+{{include constructor.js}}
+
+// Global objects
 testIllegalConstructor("this");
+testIllegalConstructor("globalThis");
+
+// Static objects
 testIllegalConstructor("app");
 testIllegalConstructor("event");
 testIllegalConstructor("font");
@@ -69,6 +54,11 @@
 testIllegalConstructor("zoomtype");
 testIllegalConstructor("scaleHow");
 testIllegalConstructor("scaleWhen");
+
+// Dynamic objects
+timer1 = app.setTimeOut("var marked = true", 1000);
+testLegalConstructor("timer1");
+
 endstream
 endobj
 {{xref}}
diff --git a/testing/resources/javascript/constructor.js b/testing/resources/javascript/constructor.js
new file mode 100644
index 0000000..f8c98aa
--- /dev/null
+++ b/testing/resources/javascript/constructor.js
@@ -0,0 +1,49 @@
+// Copyright 2020 The PDFium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function testLegalConstructor(name, allowed) {
+  const constructorString = name + ".constructor";
+  var constructor;
+  try {
+    constructor = eval(constructorString);
+  } catch (e) {
+    app.alert("FAIL: No such " + constructorString);
+    return;
+  }
+  try {
+    constructor();
+    app.alert("FAIL: " + constructorString + "(): returned");
+  } catch (e) {
+    app.alert("PASS: " + constructorString + "(): " + e);
+  }
+  try {
+    var thing = new constructor;
+    app.alert("PASS: new " + constructorString + ": " + thing);
+  } catch (e) {
+    app.alert("FAIL: new " + constructorString + ": " + e);
+  }
+}
+
+function testIllegalConstructor(name, allowed) {
+  const constructorString = name + ".constructor";
+  var constructor;
+  try {
+    constructor = eval(constructorString);
+  } catch (e) {
+    app.alert("FAIL: No such " + constructorString);
+    return;
+  }
+  try {
+    constructor();
+    app.alert("FAIL: " + constructorString + "(): returned");
+  } catch (e) {
+    app.alert("PASS: " + constructorString + "(): " + e);
+  }
+  try {
+    new constructor;
+    app.alert("FAIL: new " + constructorString + ": returned");
+  } catch (e) {
+    app.alert("PASS: new " + constructorString + ": " + e);
+  }
+}
diff --git a/testing/resources/javascript/constructor_expected.txt b/testing/resources/javascript/constructor_expected.txt
index af03337..8c58aad 100644
--- a/testing/resources/javascript/constructor_expected.txt
+++ b/testing/resources/javascript/constructor_expected.txt
@@ -1,5 +1,7 @@
 Alert: PASS: this.constructor(): illegal constructor
 Alert: PASS: new this.constructor: not a dynamic object
+Alert: PASS: globalThis.constructor(): illegal constructor
+Alert: PASS: new globalThis.constructor: not a dynamic object
 Alert: PASS: app.constructor(): illegal constructor
 Alert: PASS: new app.constructor: not a dynamic object
 Alert: PASS: event.constructor(): illegal constructor
@@ -30,3 +32,5 @@
 Alert: PASS: new scaleHow.constructor: not a dynamic object
 Alert: PASS: scaleWhen.constructor(): illegal constructor
 Alert: PASS: new scaleWhen.constructor: not a dynamic object
+Alert: PASS: timer1.constructor(): illegal constructor
+Alert: PASS: new timer1.constructor: [object Object]
diff --git a/testing/resources/javascript/consts.in b/testing/resources/javascript/consts.in
index dbfd579..b4180ff 100644
--- a/testing/resources/javascript/consts.in
+++ b/testing/resources/javascript/consts.in
@@ -23,6 +23,7 @@
   /Contents [21 0 R]
   /MediaBox [0 0 612 792]
 >>
+endobj
 % OpenAction action
 {{object 10 0}} <<
   /Type /Action
@@ -30,7 +31,7 @@
   /JS 11 0 R
 >>
 endobj
-% JS program to exexute
+% JS program to execute
 {{object 11 0}} <<
   {{streamlen}}
 >>
diff --git a/testing/resources/javascript/document_methods.in b/testing/resources/javascript/document_methods.in
index 9571e55..5db9775 100644
--- a/testing/resources/javascript/document_methods.in
+++ b/testing/resources/javascript/document_methods.in
@@ -26,6 +26,7 @@
   /MediaBox [0 0 612 792]
   /Contents 8 0 R
 >>
+endobj
 % Page number 1.
 {{object 4 0}} <<
   /Type /Page
@@ -35,6 +36,7 @@
   >>
   /MediaBox [0 0 612 792]
 >>
+endobj
 % Page number 2.
 {{object 5 0}} <<
   /Type /Page
@@ -44,6 +46,7 @@
   >>
   /MediaBox [0 0 612 792]
 >>
+endobj
 % Page number 3.
 {{object 6 0}} <<
   /Type /Page
@@ -53,6 +56,7 @@
   >>
   /MediaBox [0 0 612 792]
 >>
+endobj
 % Contents of the page.
 {{object 8 0}} <<
   {{streamlen}}
@@ -78,7 +82,7 @@
   /JS 11 0 R
 >>
 endobj
-% JS program to exexute
+% JS program to execute
 {{object 11 0}} <<
   {{streamlen}}
 >>
diff --git a/testing/resources/javascript/document_properties.in b/testing/resources/javascript/document_properties.in
index fa7d92a..44a108b 100644
--- a/testing/resources/javascript/document_properties.in
+++ b/testing/resources/javascript/document_properties.in
@@ -25,6 +25,7 @@
   >>
   /MediaBox [0 0 612 792]
 >>
+endobj
 % Page number 1.
 {{object 4 0}} <<
   /Type /Page
@@ -34,6 +35,7 @@
   >>
   /MediaBox [0 0 612 792]
 >>
+endobj
 % Page number 2.
 {{object 5 0}} <<
   /Type /Page
@@ -43,6 +45,7 @@
   >>
   /MediaBox [0 0 612 792]
 >>
+endobj
 % Page number 3.
 {{object 6 0}} <<
   /Type /Page
@@ -52,6 +55,7 @@
   >>
   /MediaBox [0 0 612 792]
 >>
+endobj
 
 % Info
 {{object 9 0}} <<
@@ -66,7 +70,7 @@
   /JS 11 0 R
 >>
 endobj
-% JS program to exexute
+% JS program to execute
 {{object 11 0}} <<
   {{streamlen}}
 >>
diff --git a/testing/resources/javascript/document_properties_expected.txt b/testing/resources/javascript/document_properties_expected.txt
index 5bab82f..ba89da0 100644
--- a/testing/resources/javascript/document_properties_expected.txt
+++ b/testing/resources/javascript/document_properties_expected.txt
@@ -237,13 +237,13 @@
 Alert: this.zoomType = 3; yields 3
 Alert: *** Getting properties ***
 Alert: this.ADBE is undefined undefined
-Alert: this.author is string 3
+Alert: this.author is string Joe Random Author
 Alert: this.baseURL is string 3
 Alert: this.bookmarkRoot is undefined undefined
 Alert: this.calculate is boolean true
 Alert: this.Collab is undefined undefined
-Alert: this.creationDate is string 3
-Alert: this.creator is string 3
+Alert: this.creationDate is string 
+Alert: this.creator is string Joe Random Creator
 Alert: this.delay is boolean true
 Alert: this.dirty is boolean true
 Alert: this.documentFileName is string 
@@ -251,10 +251,10 @@
 Alert: this.filesize is number 0
 Alert: this.icons is undefined undefined
 Alert: this.info is object [object Object]
-Alert: this.keywords is string 3
+Alert: this.keywords is string 
 Alert: this.layout is undefined undefined
 Alert: this.media is undefined undefined
-Alert: this.modDate is string 3
+Alert: this.modDate is string 
 Alert: this.mouseX is undefined undefined
 Alert: this.mouseY is undefined undefined
 Alert: this.numFields is number 0
@@ -262,9 +262,9 @@
 Alert: this.pageNum is undefined undefined
 Alert: this.pageWindowRect is undefined undefined
 Alert: this.path is string /myfile.pdf
-Alert: this.producer is string 3
-Alert: this.subject is string 3
-Alert: this.title is string 3
+Alert: this.producer is string 
+Alert: this.subject is string 
+Alert: this.title is string 
 Alert: this.URL is string myfile.pdf
 Alert: this.zoom is undefined undefined
 Alert: this.zoomType is undefined undefined
diff --git a/testing/resources/javascript/expect.js b/testing/resources/javascript/expect.js
index 832f1d6..a7a5643 100644
--- a/testing/resources/javascript/expect.js
+++ b/testing/resources/javascript/expect.js
@@ -1,3 +1,7 @@
+// Copyright 2022 The PDFium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
 function expect(expression, expected) {
   try {
     var actual = eval(expression);
diff --git a/testing/resources/javascript/field.fragment b/testing/resources/javascript/field.fragment
index 335e1ae..ff8f7f4 100644
--- a/testing/resources/javascript/field.fragment
+++ b/testing/resources/javascript/field.fragment
@@ -46,6 +46,7 @@
     10 0 R
     11 0 R
     12 0 R
+    13 0 R
   ]
 >>
 endobj
@@ -68,6 +69,9 @@
   /Parent 5 0 R
   /T (MyPushButton)
   /Rect [220 221 240 241]
+  /MK <<
+    /TP 4
+  >>
 >>
 endobj
 {{object 8 0}} <<
@@ -132,6 +136,20 @@
   /V ("/path/to/file.pdf")
 >>
 endobj
+% Questionable TP value.
+{{object 13 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Btn
+  /Ff 65536
+  /Parent 5 0 R
+  /T (MyBadPushButton)
+  /Rect [400 421 440 441]
+  /MK <<
+    /TP 7
+  >>
+>>
+endobj
 % OpenAction action
 {{object 15 0}} <<
   /Type /Action
diff --git a/testing/resources/javascript/field_methods.in b/testing/resources/javascript/field_methods.in
index 81b9eed..4684552 100644
--- a/testing/resources/javascript/field_methods.in
+++ b/testing/resources/javascript/field_methods.in
@@ -1,7 +1,7 @@
 {{header}}
 {{include field.fragment}}
 
-% JS program to exexute
+% JS program to execute
 {{object 16 0}} <<
   {{streamlen}}
 >>
@@ -51,7 +51,18 @@
 testGetArray();
 
 expect("this.getField('MyField.MyPushButton').buttonGetCaption()", "");
+expect("this.getField('MyField.MyPushButton').buttonGetCaption(0)", "");
+expect("this.getField('MyField.MyPushButton').buttonGetCaption(1)", "");
+expect("this.getField('MyField.MyPushButton').buttonGetCaption(2)", "");
+expectError("this.getField('MyField.MyPushButton').buttonGetCaption(3)")
+expectError("this.getField('MyField.MyMultiSelect').buttonGetCaption()")
+
 expect("this.getField('MyField.MyPushButton').buttonGetIcon()", "[object Object]");
+expect("this.getField('MyField.MyPushButton').buttonGetIcon(0)", "[object Object]");
+expect("this.getField('MyField.MyPushButton').buttonGetIcon(1)", "[object Object]");
+expectError("this.getField('MyField.MyPushButton').buttonGetIcon(3)");
+expectError("this.getField('MyField.MyMultiSelect').buttonGetIcon()");
+
 expect("this.getField('MyField.MyPushButton').buttonImportIcon()", undefined);
 
 expect("this.getField('MyField.MyFile').browseForFileToSubmit()", undefined);
diff --git a/testing/resources/javascript/field_methods_expected.txt b/testing/resources/javascript/field_methods_expected.txt
index 8d7ec84..99dbf09 100644
--- a/testing/resources/javascript/field_methods_expected.txt
+++ b/testing/resources/javascript/field_methods_expected.txt
@@ -8,7 +8,8 @@
 Alert: dotdot1 is 
 Alert: dotdot2 is MyField.MyPushButton
 Alert: dotdot3 is MyField
-Alert: found 7 sub-fields:
+Alert: found 8 sub-fields:
+Alert: MyField.MyBadPushButton
 Alert: MyField.MyCheckBox
 Alert: MyField.MyFile
 Alert: MyField.MyMultiSelect
@@ -17,7 +18,16 @@
 Alert: MyField.MySingleSelect
 Alert: MyField.MyText
 Alert: PASS: this.getField('MyField.MyPushButton').buttonGetCaption() = 
+Alert: PASS: this.getField('MyField.MyPushButton').buttonGetCaption(0) = 
+Alert: PASS: this.getField('MyField.MyPushButton').buttonGetCaption(1) = 
+Alert: PASS: this.getField('MyField.MyPushButton').buttonGetCaption(2) = 
+Alert: PASS: this.getField('MyField.MyPushButton').buttonGetCaption(3) threw Field.buttonGetCaption: Incorrect parameter value.
+Alert: PASS: this.getField('MyField.MyMultiSelect').buttonGetCaption() threw Field.buttonGetCaption: Object is of the wrong type.
 Alert: PASS: this.getField('MyField.MyPushButton').buttonGetIcon() = [object Object]
+Alert: PASS: this.getField('MyField.MyPushButton').buttonGetIcon(0) = [object Object]
+Alert: PASS: this.getField('MyField.MyPushButton').buttonGetIcon(1) = [object Object]
+Alert: PASS: this.getField('MyField.MyPushButton').buttonGetIcon(3) threw Field.buttonGetIcon: Incorrect parameter value.
+Alert: PASS: this.getField('MyField.MyMultiSelect').buttonGetIcon() threw Field.buttonGetIcon: Object is of the wrong type.
 Alert: PASS: this.getField('MyField.MyPushButton').buttonImportIcon() = undefined
 Alert: PASS: this.getField('MyField.MyFile').browseForFileToSubmit() = undefined
 Alert: PASS: this.getField('MyField.MyMultiSelect').getItemAt(0) = foo
diff --git a/testing/resources/javascript/field_properties.in b/testing/resources/javascript/field_properties.in
index 2126384..3887787 100644
--- a/testing/resources/javascript/field_properties.in
+++ b/testing/resources/javascript/field_properties.in
@@ -1,6 +1,6 @@
 {{header}}
 {{include field.fragment}}
-% JS program to exexute
+% JS program to execute
 {{object 16 0}} <<
   {{streamlen}}
 >>
@@ -11,6 +11,7 @@
     var field = this.getField("MyField");
     var text = this.getField("MyField.MyText");
     var button = this.getField("MyField.MyPushButton");
+    var badbutton = this.getField("MyField.MyBadPushButton");
     var radio = this.getField("MyField.MyRadio");
     var list = this.getField("MyField.MyMultiSelect");
     var check = this.getField("MyField.MyCheckBox");
@@ -23,6 +24,7 @@
     testFieldPropertiesCase(field);
     testTextPropertiesCase(text);
     testPushButtonPropertiesCase(button);
+    testBadPushButtonPropertiesCase(badbutton);
     testRadioButtonPropertiesCase(radio);
     testCheckBoxPropertiesCase(check);
     testListBoxPropertiesCase(list);
@@ -68,7 +70,7 @@
     testROProperty(field, "page", 0);
     testRIProperty(field, "password", false, 42);
     testRWProperty(field, "print", true, false);
-    testRIProperty(field, "readonly", false, true);
+    testRWProperty(field, "readonly", false, true);
     testROProperty(field, "rect", [200,221,220,201]);
     // testROProperty(field, "required", "clams");
     testRIProperty(field, "richText", false, true);
@@ -94,7 +96,7 @@
     testRIProperty(field, "buttonAlignX", 0, 50);
     testRIProperty(field, "buttonAlignY", 0, 50);
     testRIProperty(field, "buttonFitBounds", false);
-    testRIProperty(field, "buttonPosition", 0);
+    testRIProperty(field, "buttonPosition", 4);
     testRIProperty(field, "buttonScaleHow", 0);
     testRIProperty(field, "buttonScaleWhen", 0);
     testRIProperty(field, "highlight", "invert");
@@ -104,11 +106,19 @@
   }
 }
 
+function testBadPushButtonPropertiesCase(field) {
+  try {
+    testRIProperty(field, "buttonPosition", 7); // not checked.
+  } catch (e) {
+    app.alert("Unexpected error: " + e);
+  }
+}
+
 function testRadioButtonPropertiesCase(field) {
   try {
-    testROProperty(field, "exportValues", "N");
+    testROProperty(field, "exportValues", "Yes");
     testRIProperty(field, "radiosInUnison", false);
-    testRIProperty(field, "style", "check");
+    testRIProperty(field, "style", "circle");
     testROProperty(field, "type", "radiobutton");
     testRIProperty(field, "value", "Off");
     testROProperty(field, "valueAsString", "Off");
@@ -119,7 +129,7 @@
 
 function testCheckBoxPropertiesCase(field) {
   try {
-    testROProperty(field, "exportValues", "N");
+    testROProperty(field, "exportValues", "Yes");
     testRIProperty(field, "style", "check");
     testROProperty(field, "type", "checkbox");
     testRIProperty(field, "value", "Off");
diff --git a/testing/resources/javascript/field_properties_expected.txt b/testing/resources/javascript/field_properties_expected.txt
index 3b2e6f6..2c57daf 100644
--- a/testing/resources/javascript/field_properties_expected.txt
+++ b/testing/resources/javascript/field_properties_expected.txt
@@ -51,7 +51,7 @@
 Alert: PASS: print = true
 Alert: PASS: print = false
 Alert: PASS: readonly = false
-Alert: PASS: readonly = false
+Alert: PASS: readonly = true
 Alert: PASS: rect = 200,221,220,201
 Alert: PASS: rect threw Field.rect: Incorrect parameter value.
 Alert: PASS: richText = false
@@ -84,8 +84,8 @@
 Alert: PASS: buttonAlignY = 0
 Alert: PASS: buttonFitBounds = false
 Alert: PASS: buttonFitBounds = false
-Alert: PASS: buttonPosition = 0
-Alert: PASS: buttonPosition = 0
+Alert: PASS: buttonPosition = 4
+Alert: PASS: buttonPosition = 4
 Alert: PASS: buttonScaleHow = false
 Alert: PASS: buttonScaleHow = false
 Alert: PASS: buttonScaleWhen = 0
@@ -94,19 +94,21 @@
 Alert: PASS: highlight = invert
 Alert: PASS: type = button
 Alert: PASS: type threw Field.type: Operation not supported.
-Alert: PASS: exportValues = N
+Alert: PASS: buttonPosition = 7
+Alert: PASS: buttonPosition = 7
+Alert: PASS: exportValues = Yes
 Alert: PASS: exportValues threw Field.exportValues: Object no longer exists.
 Alert: PASS: radiosInUnison = false
 Alert: PASS: radiosInUnison = false
-Alert: PASS: style = check
-Alert: PASS: style = check
+Alert: PASS: style = circle
+Alert: PASS: style = circle
 Alert: PASS: type = radiobutton
 Alert: PASS: type threw Field.type: Operation not supported.
 Alert: PASS: value = Off
 Alert: PASS: value = Off
 Alert: PASS: valueAsString = Off
 Alert: PASS: valueAsString threw Field.valueAsString: Operation not supported.
-Alert: PASS: exportValues = N
+Alert: PASS: exportValues = Yes
 Alert: PASS: exportValues threw Field.exportValues: Object no longer exists.
 Alert: PASS: style = check
 Alert: PASS: style = check
diff --git a/testing/resources/javascript/foreground_task.in b/testing/resources/javascript/foreground_task.in
new file mode 100644
index 0000000..dd5444a
--- /dev/null
+++ b/testing/resources/javascript/foreground_task.in
@@ -0,0 +1,43 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /OpenAction 10 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [
+    3 0 R
+  ]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 612 792]
+>>
+endobj
+{{object 10 0}} <<
+  /Type /Action
+  /S /JavaScript
+  /JS 11 0 R
+>>
+endobj
+{{object 11 0}} <<
+  {{streamlen}}
+>>
+stream
+try {
+  gc({type: 'major', execution: 'async'}).then(() => { app.alert('Resolved') });
+  app.alert('Posted');
+} catch (e) {
+  app.alert('Error: ' + e);
+}
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/foreground_task_expected.txt b/testing/resources/javascript/foreground_task_expected.txt
new file mode 100644
index 0000000..d40e100
--- /dev/null
+++ b/testing/resources/javascript/foreground_task_expected.txt
@@ -0,0 +1,2 @@
+Alert: Posted
+Alert: Resolved
diff --git a/testing/resources/javascript/globals.in b/testing/resources/javascript/globals.in
index de67392..bbca813 100644
--- a/testing/resources/javascript/globals.in
+++ b/testing/resources/javascript/globals.in
@@ -23,6 +23,7 @@
   /Contents [21 0 R]
   /MediaBox [0 0 612 792]
 >>
+endobj
 % OpenAction action
 {{object 10 0}} <<
   /Type /Action
@@ -30,7 +31,7 @@
   /JS 11 0 R
 >>
 endobj
-% JS program to exexute
+% JS program to execute
 {{object 11 0}} <<
   {{streamlen}}
 >>
@@ -58,7 +59,11 @@
 
   // Test null and undefined.
   { "name": "null_var", "value": null },
-  { "name": "undefined_var", "value": undefined }
+  { "name": "undefined_var", "value": undefined },
+
+  // Test to show unicode currently handled.
+  { "name": "unicode_var", "value": "\u4025\u4026_string" },
+  { "name": "\u4025\u4026_var", "value": "string" },
 ];
 
 function setup_global() {
diff --git a/testing/resources/javascript/globals_expected.txt b/testing/resources/javascript/globals_expected.txt
index fcebd70..9e80a62 100644
--- a/testing/resources/javascript/globals_expected.txt
+++ b/testing/resources/javascript/globals_expected.txt
@@ -10,17 +10,20 @@
 Alert:   object_var = undefined
 Alert:   null_var = undefined
 Alert:   undefined_var = undefined
+Alert:   unicode_var = undefined
+Alert:   䀥䀦_var = undefined
 Alert: ************ After Setup ************
 Alert: Enumerable Globals:
 Alert:   setPersistent = function setPersistent() { [native code] }, own property = true
-Alert:   true_var = true, own property = true
 Alert:   false_var = false, own property = true
-Alert:   zero_var = 0, own property = true
-Alert:   number_var = -3.918, own property = true
-Alert:   string_var = This is a string, own property = true
-Alert:   object_var = [object Object], own property = true
 Alert:   null_var = null, own property = true
-Alert:   undefined_var = undefined, own property = true
+Alert:   number_var = -3.918, own property = true
+Alert:   object_var = [object Object], own property = true
+Alert:   string_var = This is a string, own property = true
+Alert:   true_var = true, own property = true
+Alert:   unicode_var = 䀥䀦_string, own property = true
+Alert:   zero_var = 0, own property = true
+Alert:   䀥䀦_var = string, own property = true
 Alert: Expected Globals:
 Alert:   true_var = true
 Alert:   false_var = false
@@ -33,6 +36,8 @@
 Alert:     blue
 Alert:   null_var = null
 Alert:   undefined_var = undefined
+Alert:   unicode_var = 䀥䀦_string
+Alert:   䀥䀦_var = string
 Alert: ************ After Deletion ************
 Alert: Enumerable Globals:
 Alert:   setPersistent = function setPersistent() { [native code] }, own property = true
@@ -45,18 +50,21 @@
 Alert:   object_var = undefined
 Alert:   null_var = undefined
 Alert:   undefined_var = undefined
+Alert:   unicode_var = undefined
+Alert:   䀥䀦_var = undefined
 Alert: For undefined_var: Set Persistent: ERROR: global.setPersistent: Global value not found.
 Alert: ************ After Setup and Persist false ************
 Alert: Enumerable Globals:
 Alert:   setPersistent = function setPersistent() { [native code] }, own property = true
-Alert:   true_var = true, own property = true
 Alert:   false_var = false, own property = true
-Alert:   zero_var = 0, own property = true
-Alert:   number_var = -3.918, own property = true
-Alert:   string_var = This is a string, own property = true
-Alert:   object_var = [object Object], own property = true
 Alert:   null_var = null, own property = true
-Alert:   undefined_var = undefined, own property = true
+Alert:   number_var = -3.918, own property = true
+Alert:   object_var = [object Object], own property = true
+Alert:   string_var = This is a string, own property = true
+Alert:   true_var = true, own property = true
+Alert:   unicode_var = 䀥䀦_string, own property = true
+Alert:   zero_var = 0, own property = true
+Alert:   䀥䀦_var = string, own property = true
 Alert: Expected Globals:
 Alert:   true_var = true
 Alert:   false_var = false
@@ -69,6 +77,8 @@
 Alert:     blue
 Alert:   null_var = null
 Alert:   undefined_var = undefined
+Alert:   unicode_var = 䀥䀦_string
+Alert:   䀥䀦_var = string
 Alert: For true_var: Set Persistent: ERROR: global.setPersistent: Global value not found.
 Alert: For false_var: Set Persistent: ERROR: global.setPersistent: Global value not found.
 Alert: For zero_var: Set Persistent: ERROR: global.setPersistent: Global value not found.
@@ -77,6 +87,8 @@
 Alert: For object_var: Set Persistent: ERROR: global.setPersistent: Global value not found.
 Alert: For null_var: Set Persistent: ERROR: global.setPersistent: Global value not found.
 Alert: For undefined_var: Set Persistent: ERROR: global.setPersistent: Global value not found.
+Alert: For unicode_var: Set Persistent: ERROR: global.setPersistent: Global value not found.
+Alert: For 䀥䀦_var: Set Persistent: ERROR: global.setPersistent: Global value not found.
 Alert: ************ After Delete and Persist ************
 Alert: Enumerable Globals:
 Alert:   setPersistent = function setPersistent() { [native code] }, own property = true
@@ -89,18 +101,21 @@
 Alert:   object_var = undefined
 Alert:   null_var = undefined
 Alert:   undefined_var = undefined
+Alert:   unicode_var = undefined
+Alert:   䀥䀦_var = undefined
 Alert: For undefined_var: Set Persistent: ERROR: global.setPersistent: Global value not found.
 Alert: ************ After Setup and Persist true ************
 Alert: Enumerable Globals:
 Alert:   setPersistent = function setPersistent() { [native code] }, own property = true
-Alert:   true_var = true, own property = true
 Alert:   false_var = false, own property = true
-Alert:   zero_var = 0, own property = true
-Alert:   number_var = -3.918, own property = true
-Alert:   string_var = This is a string, own property = true
-Alert:   object_var = [object Object], own property = true
 Alert:   null_var = null, own property = true
-Alert:   undefined_var = undefined, own property = true
+Alert:   number_var = -3.918, own property = true
+Alert:   object_var = [object Object], own property = true
+Alert:   string_var = This is a string, own property = true
+Alert:   true_var = true, own property = true
+Alert:   unicode_var = 䀥䀦_string, own property = true
+Alert:   zero_var = 0, own property = true
+Alert:   䀥䀦_var = string, own property = true
 Alert: Expected Globals:
 Alert:   true_var = true
 Alert:   false_var = false
@@ -113,3 +128,5 @@
 Alert:     blue
 Alert:   null_var = null
 Alert:   undefined_var = undefined
+Alert:   unicode_var = 䀥䀦_string
+Alert:   䀥䀦_var = string
diff --git a/testing/resources/javascript/immutable_proto.in b/testing/resources/javascript/immutable_proto.in
new file mode 100644
index 0000000..61885c5
--- /dev/null
+++ b/testing/resources/javascript/immutable_proto.in
@@ -0,0 +1,43 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /OpenAction 10 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [
+    3 0 R
+  ]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 612 792]
+>>
+endobj
+% OpenAction action
+{{object 10 0}} <<
+  /Type /Action
+  /S /JavaScript
+  /JS 11 0 R
+>>
+endobj
+{{object 11 0}} <<
+  {{streamlen}}
+>>
+stream
+{{include expect.js}}
+expect("this.__proto__", "[object Object]");
+expect("app.__proto__", "[object Object]");
+expectError("this.__proto__ = {}");
+expectError("app.__proto__ = this");
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/immutable_proto_expected.txt b/testing/resources/javascript/immutable_proto_expected.txt
new file mode 100644
index 0000000..7e7c670
--- /dev/null
+++ b/testing/resources/javascript/immutable_proto_expected.txt
@@ -0,0 +1,4 @@
+Alert: PASS: this.__proto__ = [object Object]
+Alert: PASS: app.__proto__ = [object Object]
+Alert: PASS: this.__proto__ = {} threw TypeError: Immutable prototype object '[object global]' cannot have their prototype set
+Alert: PASS: app.__proto__ = this threw TypeError: Immutable prototype object '[object Object]' cannot have their prototype set
diff --git a/testing/resources/javascript/mouse_events.in b/testing/resources/javascript/mouse_events.in
index 4c6935e..b7b5a6d 100644
--- a/testing/resources/javascript/mouse_events.in
+++ b/testing/resources/javascript/mouse_events.in
@@ -24,6 +24,7 @@
   /Contents [21 0 R]
   /MediaBox [0 0 612 792]
 >>
+endobj
 % Forms
 {{object 4 0}} <<
   /Fields [
@@ -32,6 +33,7 @@
     7 0 R
   ]
 >>
+endobj
 % Field with actions:
 % Cursor enter: E
 % Cursor exit: X
@@ -54,6 +56,7 @@
    /Bl 15 0 R
  >>
 >>
+endobj
 {{object 6 0}} <<
  /Type /Annot
  /Subtype /Widget
diff --git a/testing/resources/javascript/named_action.in b/testing/resources/javascript/named_action.in
new file mode 100644
index 0000000..ba8d28b
--- /dev/null
+++ b/testing/resources/javascript/named_action.in
@@ -0,0 +1,33 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /OpenAction 10 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [
+    3 0 R
+  ]
+>>
+endobj
+% Page number 0.
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 612 792]
+>>
+endobj
+% OpenAction action - not really JS, but generates text under test env.
+{{object 10 0}} <<
+  /Type /Action
+  /S /Named
+  /N (Print)
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/named_action_expected.txt b/testing/resources/javascript/named_action_expected.txt
new file mode 100644
index 0000000..1099a7f
--- /dev/null
+++ b/testing/resources/javascript/named_action_expected.txt
@@ -0,0 +1 @@
+Execute named action: Print
diff --git a/testing/resources/javascript/property_test_helpers.js b/testing/resources/javascript/property_test_helpers.js
index 47a25ef..0e405fc 100644
--- a/testing/resources/javascript/property_test_helpers.js
+++ b/testing/resources/javascript/property_test_helpers.js
@@ -1,4 +1,4 @@
-// Copyright 2019 PDFium Authors. All rights reserved.
+// Copyright 2019 The PDFium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/testing/resources/javascript/public_methods_expected.txt b/testing/resources/javascript/public_methods_expected.txt
index 17abeff..70cd8ee 100644
--- a/testing/resources/javascript/public_methods_expected.txt
+++ b/testing/resources/javascript/public_methods_expected.txt
@@ -21,11 +21,11 @@
 Alert: **********************
 Alert: PASS: AFDate_KeystrokeEx() threw AFDate_KeystrokeEx: AFDate_KeystrokeEx's parameter size not correct
 Alert: PASS: AFDate_KeystrokeEx(1, 2) threw AFDate_KeystrokeEx: AFDate_KeystrokeEx's parameter size not correct
-[icon=3,type=0]: The input value can't be parsed as a valid date/time (2).
+AFDate_KeystrokeEx[icon=3,type=0]: The input value can't be parsed as a valid date/time (2).
 Alert: PASS: AFDate_KeystrokeEx(2) = x
-[icon=3,type=0]: The input value can't be parsed as a valid date/time (blooey).
+AFDate_KeystrokeEx[icon=3,type=0]: The input value can't be parsed as a valid date/time (blooey).
 Alert: PASS: AFDate_KeystrokeEx('blooey') = x
-[icon=3,type=0]: The input value can't be parsed as a valid date/time (m/d).
+AFDate_KeystrokeEx[icon=3,type=0]: The input value can't be parsed as a valid date/time (m/d).
 Alert: PASS: AFDate_KeystrokeEx('m/d') = x
 Alert: **********************
 Alert: PASS: AFExtractNums() threw AFExtractNums: Incorrect number of parameters passed to function.
@@ -50,7 +50,7 @@
 Alert: **********************
 Alert: PASS: AFNumber_Keystroke() threw AFNumber_Keystroke: Incorrect number of parameters passed to function.
 Alert: PASS: AFNumber_Keystroke(1) threw AFNumber_Keystroke: Incorrect number of parameters passed to function.
-[icon=3,type=0]: The input value is invalid.
+AFNumber_Keystroke[icon=3,type=0]: The input value is invalid.
 Alert: PASS: AFNumber_Keystroke(1, 2) threw AFNumber_Keystroke: The input value is invalid.
 Alert: PASS: AFNumber_Keystroke(1, 2) = 123
 Alert: PASS: AFNumber_Keystroke(1, 2, 3) = 123
@@ -277,19 +277,19 @@
 Alert: **********************
 Alert: PASS: AFPercent_Keystroke() threw AFPercent_Keystroke: Incorrect number of parameters passed to function.
 Alert: PASS: AFPercent_Keystroke(1) threw AFPercent_Keystroke: Incorrect number of parameters passed to function.
-[icon=3,type=0]: The input value is invalid.
+AFNumber_Keystroke[icon=3,type=0]: The input value is invalid.
 Alert: PASS: AFPercent_Keystroke(1, 0) threw AFPercent_Keystroke: The input value is invalid.
 Alert: PASS: AFPercent_Keystroke(1, 0) = .123
 Alert: **********************
 Alert: PASS: AFRange_Validate() threw AFRange_Validate: Incorrect number of parameters passed to function.
 Alert: PASS: AFRange_Validate(1, 2, 3, 4, 5) threw AFRange_Validate: Incorrect number of parameters passed to function.
-[icon=3,type=0]: The input value must be greater than or equal to 2 and less than or equal to 4.
+AFRange_Validate[icon=3,type=0]: The input value must be greater than or equal to 2 and less than or equal to 4.
 Alert: PASS: AFRange_Validate(true, 2, true, 4) = 1
-[icon=3,type=0]: The input value must be greater than or equal to 2 and less than or equal to 4.
+AFRange_Validate[icon=3,type=0]: The input value must be greater than or equal to 2 and less than or equal to 4.
 Alert: PASS: AFRange_Validate(true, 2, true, 4) = 5
-[icon=3,type=0]: The input value must be greater than or equal to 2.
+AFRange_Validate[icon=3,type=0]: The input value must be greater than or equal to 2.
 Alert: PASS: AFRange_Validate(true, 2, false, 4) = 1
-[icon=3,type=0]: The input value must be less than or equal to 4.
+AFRange_Validate[icon=3,type=0]: The input value must be less than or equal to 4.
 Alert: PASS: AFRange_Validate(false, 2, true, 4) = 5
 Alert: PASS: AFRange_Validate(true, 2, true, 4) = 3
 Alert: PASS: AFRange_Validate(false, 2, true, 4) = 1
@@ -345,11 +345,11 @@
 Alert: **********************
 Alert: PASS: AFSpecial_KeystrokeEx() threw AFSpecial_KeystrokeEx: Incorrect number of parameters passed to function.
 Alert: PASS: AFSpecial_KeystrokeEx('') = 12345
-[icon=3,type=0]: The input value is invalid.
+AFSpecial_KeystrokeEx[icon=3,type=0]: The input value is invalid.
 Alert: PASS: AFSpecial_KeystrokeEx('9999') = 123
-[icon=3,type=0]: The input value is too long.
+AFSpecial_KeystrokeEx[icon=3,type=0]: The input value is too long.
 Alert: PASS: AFSpecial_KeystrokeEx('9999') = 12345
-[icon=3,type=0]: The input value is invalid.
+AFSpecial_KeystrokeEx[icon=3,type=0]: The input value is invalid.
 Alert: PASS: AFSpecial_KeystrokeEx('9999') = abcd
 Alert: PASS: AFSpecial_KeystrokeEx('9999') = 1234
 Alert: PASS: AFSpecial_KeystrokeEx('XXXX') = abcd
@@ -385,13 +385,13 @@
 Alert: PASS: AFSpecial_KeystrokeEx() threw AFSpecial_KeystrokeEx: Incorrect number of parameters passed to function.
 Alert: PASS: AFSpecial_KeystrokeEx('') = 12345
 Alert: PASS: AFSpecial_KeystrokeEx('9999') = 123
-[icon=3,type=0]: The input value is too long.
+AFSpecial_KeystrokeEx[icon=3,type=0]: The input value is too long.
 Alert: PASS: AFSpecial_KeystrokeEx('9999') = 12345
-[icon=3,type=0]: The input value is too long.
+AFSpecial_KeystrokeEx[icon=3,type=0]: The input value is too long.
 Alert: PASS: AFSpecial_KeystrokeEx('9999') = abcd
-[icon=3,type=0]: The input value is too long.
+AFSpecial_KeystrokeEx[icon=3,type=0]: The input value is too long.
 Alert: PASS: AFSpecial_KeystrokeEx('9999') = 1234
-[icon=3,type=0]: The input value is too long.
+AFSpecial_KeystrokeEx[icon=3,type=0]: The input value is too long.
 Alert: PASS: AFSpecial_KeystrokeEx('XXXX') = abcd
 Alert: **********************
 Alert: PASS: AFMergeChange() threw AFMergeChange: Incorrect number of parameters passed to function.
diff --git a/testing/resources/javascript/unsupported.in b/testing/resources/javascript/unsupported.in
index 4d1ad5e..eccfbab 100644
--- a/testing/resources/javascript/unsupported.in
+++ b/testing/resources/javascript/unsupported.in
@@ -19,6 +19,7 @@
   /Parent 2 0 R
   /MediaBox [0 0 612 792]
 >>
+endobj
 % OpenAction action
 {{object 10 0}} <<
   /Type /Action
@@ -26,7 +27,7 @@
   /JS 11 0 R
 >>
 endobj
-% JS program to exexute
+% JS program to execute
 {{object 11 0}} <<
   {{streamlen}}
 >>
diff --git a/testing/resources/javascript/util_bytetochar.in b/testing/resources/javascript/util_bytetochar.in
index 531e679..23dc423 100644
--- a/testing/resources/javascript/util_bytetochar.in
+++ b/testing/resources/javascript/util_bytetochar.in
@@ -23,6 +23,7 @@
   /Contents [21 0 R]
   /MediaBox [0 0 612 792]
 >>
+endobj
 % OpenAction action
 {{object 10 0}} <<
   /Type /Action
@@ -30,7 +31,7 @@
   /JS 11 0 R
 >>
 endobj
-% JS program to exexute
+% JS program to execute
 {{object 11 0}} <<
   {{streamlen}}
 >>
diff --git a/testing/resources/javascript/util_printd.in b/testing/resources/javascript/util_printd.in
index e4c8afc..d0d17b4 100644
--- a/testing/resources/javascript/util_printd.in
+++ b/testing/resources/javascript/util_printd.in
@@ -23,6 +23,7 @@
   /Contents [21 0 R]
   /MediaBox [0 0 612 792]
 >>
+endobj
 % OpenAction action
 {{object 10 0}} <<
   /Type /Action
@@ -30,7 +31,7 @@
   /JS 11 0 R
 >>
 endobj
-% JS program to exexute
+% JS program to execute
 {{object 11 0}} <<
   {{streamlen}}
 >>
diff --git a/testing/resources/javascript/util_printx.in b/testing/resources/javascript/util_printx.in
index 3002051..84d4846 100644
--- a/testing/resources/javascript/util_printx.in
+++ b/testing/resources/javascript/util_printx.in
@@ -23,6 +23,7 @@
   /Contents [21 0 R]
   /MediaBox [0 0 612 792]
 >>
+endobj
 % OpenAction action
 {{object 10 0}} <<
   /Type /Action
@@ -30,7 +31,7 @@
   /JS 11 0 R
 >>
 endobj
-% JS program to exexute
+% JS program to execute
 {{object 11 0}} <<
   {{streamlen}}
 >>
diff --git a/testing/resources/javascript/util_scand.in b/testing/resources/javascript/util_scand.in
index 25462d0..344aacd 100644
--- a/testing/resources/javascript/util_scand.in
+++ b/testing/resources/javascript/util_scand.in
@@ -27,7 +27,7 @@
   /JS 11 0 R
 >>
 endobj
-% JS program to exexute
+% JS program to execute
 {{object 11 0}} <<
   {{streamlen}}
 >>
diff --git a/testing/resources/javascript/v8_features.in b/testing/resources/javascript/v8_features.in
index 3d90473..8a5b6af 100644
--- a/testing/resources/javascript/v8_features.in
+++ b/testing/resources/javascript/v8_features.in
@@ -19,6 +19,7 @@
   /Parent 2 0 R
   /MediaBox [0 0 612 792]
 >>
+endobj
 % OpenAction action
 {{object 10 0}} <<
   /Type /Action
@@ -26,7 +27,7 @@
   /JS 11 0 R
 >>
 endobj
-% JS program to exexute
+% JS program to execute
 {{object 11 0}} <<
   {{streamlen}}
 >>
diff --git a/testing/resources/javascript/xfa_specific/bug_1004106.in b/testing/resources/javascript/xfa_specific/bug_1004106.in
new file mode 100644
index 0000000..926c39b
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1004106.in
@@ -0,0 +1,65 @@
+{{header}}
+{{include ../../xfa_catalog_1_0.fragment}}
+{{include ../../xfa_object_2_0.fragment}}
+{{include ../../xfa_preamble_3_0.fragment}}
+{{include ../../xfa_config_4_0.fragment}}
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+<template>
+  <subform layout="tb" name="subform1">
+    <pageSet id="page" relation="orderedOccurrence">
+      <occur initial="1" max="1" min="1"/>
+      <pageArea id="Page1" name="Page1">
+        <occur max="1" min="1"/>
+        <contentArea h="100mm" w="200mm" x="0.25in" y="0.25in"/>
+        <medium long="297mm" short="210mm" stock="a4"/>
+      </pageArea>
+    </pageSet>
+    <subform layout="tb" name="subform2">
+      <variables name="vara">
+      </variables>
+      <occur initial="1" max="10" min="0" name="occur1">
+      </occur>
+      <field h="10mm" name="field1" w="40mm" x="10mm" y="10mm">
+        <event activity="ready" ref="$form">
+          <script contentType="application/x-javascript">
+            var ref = [];
+
+            app.test = function () {
+              var arr = []
+              var v1 = 1;
+              st = {};
+              var v2 = [0, st, 2, 3];
+              var v3 = [0, "poc", {}];
+              st.toString = function(){
+                for (var i = 0; i != 8; i++) v3.push({});
+                return "poc";
+              }
+
+              // Trigger
+              pfm_rt.Oneof(1, v1, v2, v3);
+            }
+          </script>
+        </event>
+      </field>
+      <field h="10mm" name="field2" w="40mm" x="10mm" y="10mm">
+        <event activity="ready" ref="$form">
+          <script contentType="application/x-formcalc">
+            app.test();
+          </script>
+        </event>
+      </field>
+    </subform>
+  </subform>
+</template>
+endstream
+endobj
+{{include ../../xfa_locale_6_0.fragment}}
+{{include ../../xfa_postamble_7_0.fragment}}
+{{include ../../xfa_pages_8_0.fragment}}
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/xfa_specific/bug_1026991.evt b/testing/resources/javascript/xfa_specific/bug_1026991.evt
new file mode 100644
index 0000000..37d9022
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1026991.evt
@@ -0,0 +1,5 @@
+mousemove,0,0
+mousedown,left,0,0
+mouseup,left,0,0
+charcode,80
+mousemove,0,200
\ No newline at end of file
diff --git a/testing/resources/javascript/xfa_specific/bug_1026991.in b/testing/resources/javascript/xfa_specific/bug_1026991.in
new file mode 100644
index 0000000..4fb7657
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1026991.in
@@ -0,0 +1,65 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /XFA 4 0 R
+  >>
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 612 792]
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+<xdp xmlns="http://ns.adobe.com/xdp/">
+  <config>
+    <acrobat>
+      <acrobat7>
+        <dynamicRender>required</dynamicRender>
+      </acrobat7>
+    </acrobat>
+    <present>
+      <pdf>
+        <interactive>1</interactive>
+      </pdf>
+    </present>
+  </config>
+  <template>
+    <subform>
+      <bookend leader="$"/>
+      <keep intact="none" previous="contentArea"/>
+      <field name="N01" minH="32in">
+        <ui>
+          <choiceList>
+            <margin rightInset="8in"/>
+          </choiceList>
+        </ui>
+      </field>
+      <field minH="32in">
+        <event activity="change">
+          <script>
+            $host.setFocus("N01")
+          </script>
+        </event>
+      </field>
+    </subform>
+  </template>
+</xdp>
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/xfa_specific/bug_1039629.evt b/testing/resources/javascript/xfa_specific/bug_1039629.evt
new file mode 100644
index 0000000..96d37be
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1039629.evt
@@ -0,0 +1,3 @@
+mousedown,left,295,187
+mouseup,left,295,187
+keycode,40
\ No newline at end of file
diff --git a/testing/resources/javascript/xfa_specific/bug_1039629.in b/testing/resources/javascript/xfa_specific/bug_1039629.in
new file mode 100644
index 0000000..a911db6
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1039629.in
@@ -0,0 +1,188 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /AcroForm 3 0 R
+  /Pages 5 0 R
+  /NeedsRendering true
+>>
+endobj
+{{object 3 0}} <<
+  /XFA [
+    (preamble) 7 0 R
+    (config) 8 0 R
+    (template) 9 0 R
+    (form) 10 0 R
+    (postamble) 11 0 R
+  ]
+>>
+endobj
+{{object 5 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [ 12 0 R ]
+>>
+endobj
+{{object 7 0}} <<
+  {{streamlen}}
+>>
+stream
+<?xml version="1.0" encoding="UTF-8"?>
+<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/" timeStamp="2007-08-07T18:35:24Z" uuid="3b6c6ea3-3edf-40f5-90ff-51ee202e15b4">
+endstream
+endobj
+{{object 8 0}} <<
+  {{streamlen}}
+>>
+stream
+<config xmlns="http://www.xfa.org/schema/xci/2.6/">
+  <agent name="designer">
+    <destination>pdf</destination>
+    <pdf>
+      <!--  [0..n]  -->
+      <fontInfo/>
+    </pdf>
+  </agent>
+  <present>
+    <!--  [0..n]  -->
+    <pdf>
+      <!--  [0..n]  -->
+      <version>1.7</version>
+      <renderPolicy>client</renderPolicy>
+      <creator>Adobe LiveCycle Designer ES 8.1</creator>
+      <producer>Adobe LiveCycle Designer ES 8.1</producer>
+      <scriptModel>XFA</scriptModel>
+      <interactive>1</interactive>
+      <tagged>1</tagged>
+      <fontInfo>
+        <embed>1</embed>
+      </fontInfo>
+      <compression>
+        <level>6</level>
+        <compressLogicalStructure>1</compressLogicalStructure>
+      </compression>
+      <linearized>1</linearized>
+      <viewerPreferences>
+        <addViewerPreferences>0</addViewerPreferences>
+        <duplexOption>simplex</duplexOption>
+        <numberOfCopies>0</numberOfCopies>
+      </viewerPreferences>
+    </pdf>
+    <cache>
+      <macroCache/>
+      <renderCache/>
+    </cache>
+    <incrementalMerge/>
+    <script>
+      <runScripts/>
+      <exclude/>
+      <currentPage/>
+    </script>
+    <copies/>
+    <layout/>
+    <xdp>
+      <packets>*</packets>
+    </xdp>
+    <destination>pdf</destination>
+  </present>
+  <psMap/>
+  <acrobat>
+    <acrobat7>
+      <dynamicRender>required</dynamicRender>
+    </acrobat7>
+  </acrobat>
+</config>
+endstream
+endobj
+{{object 9 0}} <<
+  {{streamlen}}
+>>
+stream
+<template xmlns="http://www.xfa.org/schema/xfa-template/2.6/">
+  <subform name="form1">
+    <pageSet>
+      <pageArea id="Page1" name="Page1">
+        <contentArea h="10.5in" w="8in" x="0.25in" y="0.25in"/>
+        <medium long="11in" short="8.5in" stock="letter"/>
+      </pageArea>
+    </pageSet>
+    <subform h="10.5in" w="8in">
+      <field h="9.0001mm" name="ChoiceList" w="47.625mm" x="6.35mm" y="92.075mm">
+        <ui>
+          <choiceList/>
+        </ui>
+        <items>
+          <text>Foo</text>
+        </items>
+      </field>
+      <field h="100mm" name="ChoiceList1" w="100mm" x="0mm" y="0mm">
+      <ui>
+        <choiceList open="onEntry"/>
+      </ui>
+      <items>
+        <text>1111111111111</text>
+        <text>222222222222222</text>
+      </items>
+      <event activity="change">
+        <script contentType="application/x-javascript">
+        a += 1;
+        if (a == 2) {
+            list1 = xfa.resolveNode("ChoiceList");
+            xfa.host.setFocus(list1);
+            xfa.template.remerge();
+            xfa.host.openList(list1);
+        }
+        </script>
+      </event>
+    </field>
+  </subform>
+    <event activity="docReady">
+      <script contentType="application/x-javascript">
+        a = 0;
+      </script>
+    </event>
+  </subform>
+</template>
+endstream
+endobj
+{{object 10 0}} <<
+  {{streamlen}}
+>>
+stream
+<form xmlns="http://www.xfa.org/schema/xfa-form/2.6/">
+</form>
+endstream
+endobj
+{{object 11 0}} <<
+  {{streamlen}}
+>>
+stream
+</xdp:xdp>
+endstream
+endobj
+{{object 12 0}} <<
+  /Type /Page
+  /Contents 13 0 R
+  /CropBox [ 0.0 0.0 612.0 792.0 ]
+  /MediaBox [ 0.0 0.0 612.0 792.0 ]
+  /Parent 5 0 R
+  /Resources <<
+    /Font <<
+      /T1_0 14 0 R
+    >>
+    /ProcSet [ /PDF /Text ]
+  >>
+  /Rotate 0
+  /StructParents 0
+>>
+endobj
+{{object 14 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+  /Encoding /WinAnsiEncoding
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/xfa_specific/bug_1040329.in b/testing/resources/javascript/xfa_specific/bug_1040329.in
new file mode 100644
index 0000000..7117084
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1040329.in
@@ -0,0 +1,99 @@
+{{header}}
+{{object 1 0}} <<
+  /Pages 2 0 R
+  /NeedsRendering true
+  /AcroForm <</XFA 5 0 R>>
+  /OpenAction 3 0 R
+  /Type /Catalog
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [ 4 0 R ]
+>>
+endobj
+{{object 3 0}} <<
+  /S /JavaScript
+  /JS (
+  )
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [ 0 0 795 842 ]
+>>
+endobj
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
+<template >
+  <subform allowMacro="0" layout="lr" mergeMode="consumeData" name="subform_0" >
+    <pageSet >
+      <occur initial="1" max="10" min="0" ></occur>
+      <pageArea >
+        <contentArea h="0.75in" w="0.25in" x="0.25in" y="0.25in" ></contentArea>
+        <subform allowMacro="0" layout="row" mergeMode="consumeData" name="subform_1" >
+          <event activity="initialize" >
+            <script contentType="application/x-javascript">
+            </script>
+          </event>
+          <field name="field_1" >
+            <bind match="dataRef" ref="a" ></bind>
+            <calculate >
+              <script contentType="application/x-javascript">
+                var f=xfa.resolveNode("xfa.form.subform_0");
+                xfa.host.setFocus(f);
+                f.mark ="square";
+              </script>
+            </calculate>
+            <event activity="docReady" >
+              <script contentType="application/x-javascript">
+                xfa.host.resetData(this);
+              </script>
+            </event>
+          </field>
+        </subform>
+      </pageArea>
+    </pageSet>
+    <field name="field_2" >
+      <bind match="dataRef" ref="a" ></bind>
+      <calculate >
+        <script contentType="application/x-javascript">
+          xfa.host.setFocus(this);
+        </script>
+      </calculate>
+      <items presence="hidden" save="0" >
+        <text >a</text>
+        <text >b</text>
+        <text >c</text>
+      </items>
+      <ui >
+        <choiceList commitOn="exit" open="onEntry" textEntry="1" ></choiceList>
+      </ui>
+      <value override="0" >
+        <text >a</text>
+      </value>
+      <event activity="initialize" >
+        <script contentType="application/x-javascript">
+        </script>
+      </event>
+      <event activity="change" >
+        <script contentType="application/x-javascript">
+          xfa.form.remerge();
+          xfa.host.openList(this);
+        </script>
+      </event>
+    </field>
+  </subform>
+</template>
+</xdp:xdp>
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/xfa_specific/bug_1042915.evt b/testing/resources/javascript/xfa_specific/bug_1042915.evt
new file mode 100644
index 0000000..c0cea89
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1042915.evt
@@ -0,0 +1,8 @@
+mousedown,left,0,0
+mouseup,left,0,0
+keycode,9
+keycode,9
+mousedown,left,0,0
+mouseup,left,0,0
+mousedown,left,0,0
+mouseup,left,0,0
\ No newline at end of file
diff --git a/testing/resources/javascript/xfa_specific/bug_1042915.pdf b/testing/resources/javascript/xfa_specific/bug_1042915.pdf
new file mode 100644
index 0000000..36a2c8b
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1042915.pdf
Binary files differ
diff --git a/testing/resources/javascript/xfa_specific/bug_1042915_expected.txt b/testing/resources/javascript/xfa_specific/bug_1042915_expected.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1042915_expected.txt
diff --git a/testing/resources/javascript/xfa_specific/bug_1043508.in b/testing/resources/javascript/xfa_specific/bug_1043508.in
new file mode 100644
index 0000000..2afe129
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1043508.in
@@ -0,0 +1,62 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /XFA 4 0 R
+  >>
+  /NeedsRendering true
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 3 3]
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+<xdp xmlns="http://ns.adobe.com/xdp/">
+<config>
+  <acrobat>
+    <acrobat7>
+      <dynamicRender>required</dynamicRender>
+    </acrobat7>
+  </acrobat>
+</config>
+<template>
+  <subform>
+    <breakBefore>
+      <script>
+        $.#field[1]=2
+      </script>
+    </breakBefore>
+    <field>
+      <ui>
+        <choiceList open="multiSelect"></choiceList>
+      </ui>
+    </field>
+    <field>
+      <event activity="change">
+        <script>
+          $host.openList(&quot;$form.#field[0]&quot;)
+        </script>
+      </event>
+    </field>
+  </subform>
+</template>
+</xdp>
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
\ No newline at end of file
diff --git a/testing/resources/javascript/xfa_specific/bug_1043510.evt b/testing/resources/javascript/xfa_specific/bug_1043510.evt
index 891a49d..08e98cf 100644
--- a/testing/resources/javascript/xfa_specific/bug_1043510.evt
+++ b/testing/resources/javascript/xfa_specific/bug_1043510.evt
@@ -1 +1 @@
-mousedoubleclick,left,0,0
\ No newline at end of file
+mousedoubleclick,left,0,0
diff --git a/testing/resources/javascript/xfa_specific/bug_1047914.evt b/testing/resources/javascript/xfa_specific/bug_1047914.evt
new file mode 100644
index 0000000..45b948d
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1047914.evt
@@ -0,0 +1,4 @@
+mousedown,left,0,2
+mouseup,left,0,2
+mousedown,left,0,2
+mouseup,left,0,2
\ No newline at end of file
diff --git a/testing/resources/javascript/xfa_specific/bug_1047914.in b/testing/resources/javascript/xfa_specific/bug_1047914.in
new file mode 100644
index 0000000..969d7a0
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1047914.in
@@ -0,0 +1,47 @@
+{{header}}
+{{object 1 0}} <<
+  /AcroForm <<
+    /XFA 2 0 R
+  >>
+>>
+endobj
+{{object 2 0}} <<
+  {{streamlen}}
+>>
+stream
+<xdp xmlns="http://ns.adobe.com/xdp/">
+  <config>
+    <acrobat>
+      <acrobat7>
+        <dynamicRender>required</dynamicRender>
+      </acrobat7>
+    </acrobat>
+    <present>
+      <pdf>
+        <interactive>1</interactive>
+      </pdf>
+    </present>
+  </config>
+  <template>
+    <subform>
+      <bookend leader="$"></bookend>
+      <keep previous="pageArea"></keep>
+      <field anchorType="middleCenter">
+        <ui>
+          <choiceList open="multiSelect">
+            <border><edge stroke="raised"></edge></border>
+            <margin></margin>
+          </choiceList>
+        </ui>
+        <items save="1"><float>41.0</float></items>
+        <items><float>43.0</float><integer>44</integer></items>
+      </field>
+    </subform>
+  </template>
+</xdp>
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
\ No newline at end of file
diff --git a/testing/resources/javascript/xfa_specific/bug_1052651.evt b/testing/resources/javascript/xfa_specific/bug_1052651.evt
new file mode 100644
index 0000000..e88ef06
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1052651.evt
@@ -0,0 +1,4 @@
+mousemove,100,100
+mousedown,left,100,100
+mouseup,left,100,100
+charcode,96
diff --git a/testing/resources/javascript/xfa_specific/bug_1052651.in b/testing/resources/javascript/xfa_specific/bug_1052651.in
new file mode 100644
index 0000000..a26312d
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1052651.in
@@ -0,0 +1,168 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /AcroForm 3 0 R
+  /Pages 5 0 R
+  /NeedsRendering true
+>>
+endobj
+{{object 3 0}} <<
+  /DA (/Helv 0 Tf 0 g )
+  /DR <<
+    /Font <<
+      /Helv 9 0 R
+    >>
+  >>
+  /XFA [
+    (preamble) 10 0 R
+    (config) 11 0 R
+    (template) 12 0 R
+    (form) 13 0 R
+    (postamble) 14 0 R
+  ]
+>>
+endobj
+{{object 5 0}}  <<
+  /Type /Pages
+  /Count 1
+  /Kids [6 0 R]
+>>
+endobj
+{{object 6 0}} <<
+  /Type /Page
+  /CropBox [0.0 0.0 612.0 792.0]
+  /MediaBox [0.0 0.0 612.0 792.0]
+  /Parent 5 0 R
+  /Resources <<
+    /ProcSet [/PDF /Text]
+  >>
+  /Rotate 0
+  /StructParents 0
+>>
+endobj
+{{object 8 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+  /Encoding /WinAnsiEncoding
+>>
+endobj
+{{object 9 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+  /Encoding /WinAnsiEncoding
+>>
+endobj
+{{object 10 0}} <<
+  {{streamlen}}
+>>
+stream
+<?xml version="1.0" encoding="UTF-8"?>
+<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
+endstream
+endobj
+{{object 11 0}} <<
+  {{streamlen}}
+>>
+stream
+<config xmlns="http://www.xfa.org/schema/xci/2.6/">
+  <agent name="designer">
+    <destination>pdf</destination>
+    <pdf>
+      <fontInfo/>
+    </pdf>
+  </agent>
+  <present>
+    <pdf>
+      <version>1.7</version>
+      <renderPolicy>client</renderPolicy>
+      <scriptModel>XFA</scriptModel>
+      <interactive>1</interactive>
+    </pdf>
+    <xdp>
+      <packets>*</packets>
+    </xdp>
+    <destination>pdf</destination>
+  </present>
+  <acrobat>
+    <acrobat7>
+      <dynamicRender>required</dynamicRender>
+    </acrobat7>
+  </acrobat>
+</config>
+endstream
+endobj
+{{object 12 0}} <<
+  {{streamlen}}
+>>
+stream
+<template xmlns="http://www.xfa.org/schema/xfa-template/2.6/">
+  <subform layout="tb" locale="en_US" name="form1" restoreState="auto">
+    <pageSet>
+      <pageArea id="Page1" name="Page1">
+        <contentArea h="10.5in" w="8in" x="0.25in" y="0.25in"/>
+        <medium long="11in" short="8.5in" stock="letter"/>
+      </pageArea>
+    </pageSet>
+    <subform h="10.5in" w="8in" name="subform2">
+      <field h="9.0001mm" name="field1" w="47.625mm" x="6.35mm" y="92.075mm">
+        <ui>
+          <choiceList/>
+        </ui>
+        <items save="1">
+          <text>Single</text>
+          <text>Married</text>
+          <text>Other</text>
+        </items>
+      </field>
+      <field name="field2" h="200mm" w="200mm" x="1mm" y="1mm">
+        <ui>
+          <textEdit/>
+        </ui>
+        <value>
+          <text>pdfium</text>
+        </value>
+        <event activity="change">
+          <script contentType="application/x-javascript">
+            f2_change = f2_change + 1;
+            if (f2_change == 2) {
+                xfa.event.cancelAction = true;
+                f1 = xfa.resolveNode("xfa.form..field1");
+                xfa.host.setFocus(f1);
+                xfa.template.remerge();
+                xfa.host.openList(f1);
+            }
+          </script>
+        </event>
+      </field>
+    </subform>
+    <event activity="docReady">
+      <script contentType="application/x-javascript">
+        f2_change = 0;
+        f2 = xfa.resolveNode("xfa.form..field2");
+        xfa.host.setFocus(f2);
+     </script>
+    </event>
+  </subform>
+</template>
+endstream
+endobj
+{{object 13 0}} <<
+  {{streamlen}}
+>>
+stream
+<form xmlns="http://www.xfa.org/schema/xfa-form/2.6/"></form>
+endstream
+endobj
+{{object 14 0}} <<
+ {{streamlen}}
+>>
+stream
+</xdp:xdp>
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/xfa_specific/bug_1052786.in b/testing/resources/javascript/xfa_specific/bug_1052786.in
new file mode 100644
index 0000000..b9dd5e9
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1052786.in
@@ -0,0 +1,168 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /AcroForm 3 0 R
+  /Pages 5 0 R
+  /NeedsRendering true
+>>
+endobj
+{{object 3 0}} <<
+  /DA (/Helv 0 Tf 0 g )
+  /DR <<
+    /Font <<
+      /Helv 9 0 R
+    >>
+  >>
+  /XFA [
+    (preamble) 10 0 R
+    (config) 11 0 R
+    (template) 12 0 R
+    (form) 13 0 R
+    (postamble) 14 0 R
+  ]
+>>
+endobj
+{{object 5 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [6 0 R]
+>>
+endobj
+{{object 6 0}} <<
+  /Type /Page
+  /CropBox [0.0 0.0 612.0 792.0]
+  /MediaBox [0.0 0.0 612.0 792.0]
+  /Parent 5 0 R
+  /Resources <<
+    /ProcSet [/PDF /Text]
+  >>
+  /Rotate 0
+>>
+endobj
+{{object 8 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+  /Encoding /WinAnsiEncoding
+>>
+endobj
+{{object 9 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+  /Encoding /WinAnsiEncoding
+>>
+endobj
+{{object 10 0}} <<
+  {{streamlen}}
+>>
+stream
+<?xml version="1.0" encoding="UTF-8"?>
+<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
+endstream
+endobj
+{{object 11 0}} <<
+  {{streamlen}}
+>>
+stream
+<config xmlns="http://www.xfa.org/schema/xci/2.6/">
+  <agent name="designer">
+    <destination>pdf</destination>
+    <pdf>
+      <fontInfo/>
+    </pdf>
+  </agent>
+  <present>
+    <pdf>
+      <version>1.7</version>
+      <renderPolicy>client</renderPolicy>
+      <scriptModel>XFA</scriptModel>
+      <interactive>1</interactive>
+    </pdf>
+    <xdp>
+      <packets>*</packets>
+    </xdp>
+    <destination>pdf</destination>
+  </present>
+  <psMap/>
+  <acrobat>
+    <acrobat7>
+      <dynamicRender>required</dynamicRender>
+    </acrobat7>
+  </acrobat>
+</config>
+endstream
+endobj
+{{object 12 0}} <<
+  {{streamlen}}
+>>
+stream
+<template xmlns="http://www.xfa.org/schema/xfa-template/2.6/">
+  <subform layout="tb" locale="en_US" name="form1" restoreState="auto">
+    <pageSet>
+      <pageArea id="Page1" name="Page1">
+        <contentArea h="10.5in" w="8in" x="0.25in" y="0.25in"/>
+        <medium long="11in" short="8.5in" stock="letter"/>
+      </pageArea>
+    </pageSet>
+    <subform h="10.5in" w="8in" name="subform2">
+      <field h="9.0001mm" name="choiceList0" w="47.625mm" x="6.35mm" y="92.075mm">
+        <ui>
+          <choiceList/>
+        </ui>
+        <items save="1">
+          <text>Single</text>
+          <text>Married</text>
+          <text>Other</text>
+        </items>
+      </field>
+      <field name="choiceList1" h="10mm" w="1mm" x="5mm" y="50mm">
+        <ui>
+          <textEdit hScrollPolicy="off" vScrollPolicy="off" multiLine="0"/>
+        </ui>
+      <value>
+        <text maxChars="6">pdfium</text>
+      </value>
+      <event activity="full">
+        <script contentType="application/x-javascript">
+          full_count += 1;
+          if (full_count == 2) {
+            f1 = xfa.resolveNode("xfa.form..choiceList0");
+            xfa.host.setFocus(f1);
+            xfa.template.remerge();
+            xfa.host.openList(f1);
+          }
+        </script>
+      </event>
+    </field>
+  </subform>
+    <event activity="docReady">
+      <script contentType="application/x-javascript">
+        full_count = 0;
+        choiceList1 = xfa.resolveNode("xfa.form..choiceList1");
+        choiceList1.rawValue = "12345888888888888888";
+        xfa.host.setFocus(choiceList1);
+      </script>
+    </event>
+  </subform>
+</template>
+endstream
+endobj
+{{object 13 0}} <<
+  {{streamlen}}
+>>
+stream
+<form xmlns="http://www.xfa.org/schema/xfa-form/2.6/"></form>
+endstream
+endobj
+{{object 14 0}} <<
+  {{streamlen}}
+>>
+stream
+</xdp:xdp>
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/xfa_specific/bug_1053617.in b/testing/resources/javascript/xfa_specific/bug_1053617.in
new file mode 100644
index 0000000..1e98bdc
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1053617.in
@@ -0,0 +1,155 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /AcroForm 2 0 R
+  /Pages 3 0 R
+  /Extensions <<
+    /ADBE <<
+      /BaseVersion /1.7
+      /ExtensionLevel 8
+    >>
+  >>
+  /NeedsRendering true
+>>
+endobj
+{{object 2 0}} <<
+  /XFA [
+    (preamble) 5 0 R
+    (config) 6 0 R
+    (template) 7 0 R
+    (postamble) 9 0 R
+  ]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [4 0 R]
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 612 792]
+>>
+endobj
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
+endstream
+endobj
+{{object 6 0}} <<
+  {{streamlen}}
+>>
+stream
+<config xmlns="http://www.xfa.org/schema/xci/3.0/">
+<agent name="designer">
+  <destination>pdf</destination>
+  <pdf>
+    <fontInfo/>
+  </pdf>
+</agent>
+<present>
+  <pdf>
+    <version>1.7</version>
+    <adobeExtensionLevel>8</adobeExtensionLevel>
+    <renderPolicy>client</renderPolicy>
+    <scriptModel>XFA</scriptModel>
+    <interactive>1</interactive>
+  </pdf>
+  <xdp>
+    <packets>*</packets>
+  </xdp>
+  <destination>pdf</destination>
+  <script>
+    <runScripts>server</runScripts>
+  </script>
+</present>
+<acrobat>
+  <acrobat7>
+    <dynamicRender>required</dynamicRender>
+  </acrobat7>
+  <validate>preSubmit</validate>
+</acrobat>
+</config>
+endstream
+endobj
+{{object 7 0}} <<
+  {{streamlen}}
+>>
+stream
+<template xmlns="http://www.xfa.org/schema/xfa-template/2.6/">
+  <subform name="form1">
+    <pageSet>
+      <pageArea id="Page1" name="Page1">
+        <contentArea h="10.5in" w="8in" x="0.25in" y="0.25in"/>
+        <medium long="11in" short="8.5in" stock="letter"/>
+      </pageArea>
+    </pageSet>
+    <subform h="10.5in" w="8in" name="subform2">
+      <field name="f1" h="10mm" w="10mm" x="20mm" y="20mm">
+        <ui>
+          <choiceList/>
+        </ui>
+        <items save="1">
+          <text>Single</text>
+        </items>
+      </field>
+      <subform name="f4" x="5mm" y="5mm">
+          <occur max="-1"/>
+          <field name="f2" h="10mm" w="10mm" x="1mm" y="1mm">
+            <ui>
+              <dateTimeEdit/>
+            </ui>
+            <value>
+              <date/>
+            </value>
+            <format>
+              <picture>date{MM/DD/YY}</picture>
+            </format>
+            <event activity="initialize">
+              <script contentType="application/x-javascript">
+                this.rawValue = "2020" + "-" + "12" + "-" + "10";
+              </script>
+            </event>
+            <event activity="change">
+              <script contentType="application/x-javascript">
+                a = a + 1;
+                if (a == 2) {
+                  xfa.event.cancelAction = true;
+                  c = xfa.resolveNode("xfa.form..f1");
+                  xfa.host.setFocus(c);
+                  d = xfa.resolveNode("xfa.form..f4");
+                  d.instanceManager.addInstance(1);
+                  d.instanceManager.removeInstance(0);
+                  xfa.host.openList(c);
+                }
+              </script>
+            </event>
+          </field>
+      </subform>
+    </subform>
+    <event activity="docReady">
+      <script contentType="application/x-javascript">
+        a = 0;
+        b = xfa.resolveNode("xfa.form..f2");
+        xfa.host.setFocus(b);
+      </script>
+    </event>
+  </subform>
+</template>
+endstream
+endobj
+{{object 9 0}} <<
+  {{streamlen}}
+>>
+stream
+</xdp:xdp>
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/xfa_specific/bug_1054429.evt b/testing/resources/javascript/xfa_specific/bug_1054429.evt
new file mode 100644
index 0000000..86e0905
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1054429.evt
@@ -0,0 +1,2 @@
+mousedown,left,61,51
+keycode,46
\ No newline at end of file
diff --git a/testing/resources/javascript/xfa_specific/bug_1054429.in b/testing/resources/javascript/xfa_specific/bug_1054429.in
new file mode 100644
index 0000000..7295e5f
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1054429.in
@@ -0,0 +1,147 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /AcroForm 2 0 R
+  /Pages 3 0 R
+  /Extensions <<
+    /ADBE <<
+      /BaseVersion /1.7
+      /ExtensionLevel 8
+    >>
+  >>
+  /NeedsRendering true
+>>
+endobj
+{{object 2 0}} <<
+  /XFA [
+    (preamble) 5 0 R
+    (config) 6 0 R
+    (template) 7 0 R
+    (postamble) 9 0 R
+  ]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [4 0 R]
+>>
+endobj
+{{object 4 0}} <<
+ /Type /Page
+ /Parent 2 0 R
+ /MediaBox [0 0 612 792]
+>>
+endobj
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
+endstream
+endobj
+{{object 6 0}} <<
+  {{streamlen}}
+>>
+stream
+<config xmlns="http://www.xfa.org/schema/xci/3.0/">
+<agent name="designer">
+  <destination>pdf</destination>
+  <pdf>
+    <fontInfo/>
+  </pdf>
+</agent>
+<present>
+  <pdf>
+    <version>1.7</version>
+    <adobeExtensionLevel>8</adobeExtensionLevel>
+    <renderPolicy>client</renderPolicy>
+    <scriptModel>XFA</scriptModel>
+    <interactive>1</interactive>
+  </pdf>
+  <xdp>
+    <packets>*</packets>
+  </xdp>
+  <destination>pdf</destination>
+  <script>
+    <runScripts>server</runScripts>
+  </script>
+</present>
+<acrobat>
+  <acrobat7>
+    <dynamicRender>required</dynamicRender>
+  </acrobat7>
+  <validate>preSubmit</validate>
+</acrobat>
+</config>
+endstream
+endobj
+{{object 7 0}} <<
+  {{streamlen}}
+>>
+stream
+<template xmlns="http://www.xfa.org/schema/xfa-template/2.6/">
+  <subform layout="tb" locale="en_US" name="form1" restoreState="auto">
+    <pageSet>
+      <pageArea id="Page1" name="Page1">
+        <contentArea h="10.5in" w="8in" x="0.25in" y="0.25in"/>
+        <medium long="11in" short="8.5in" stock="letter"/>
+      </pageArea>
+    </pageSet>
+    <subform h="10.5in" w="8in" name="subform2">
+      <field h="10mm" name="f1" w="40mm" x="5mm" y="90mm">
+        <ui>
+          <choiceList/>
+        </ui>
+        <items save="1">
+          <text>Single</text>
+        </items>
+      </field>
+      <subform name="f4" x="5mm" y="5mm">
+          <occur max="-1"/>
+          <field name="f2" h="300mm" w="300mm" x="1mm" y="1mm">
+            <ui>
+              <textEdit/>
+            </ui>
+            <value>
+              <text>pdfiummmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm</text>
+            </value>
+            <event activity="change">
+              <script contentType="application/x-javascript">
+                a = a + 1;
+                if (a == 2)  {
+                    xfa.event.cancelAction = true;
+                    b = xfa.resolveNode("xfa.form..f1");
+                    xfa.host.setFocus(b);
+                    d = xfa.resolveNode("xfa.form..f4");
+                    d.instanceManager.addInstance(1);
+                    d.instanceManager.removeInstance(0);
+                    xfa.host.openList(b);
+                }
+              </script>
+            </event>
+          </field>
+      </subform>
+    </subform>
+    <event activity="docReady">
+      <script contentType="application/x-javascript">
+        a = 0;
+        c = xfa.resolveNode("xfa.form..f2");
+        xfa.host.setFocus(c);
+      </script>
+    </event>
+  </subform>
+</template>
+endstream
+endobj
+{{object 9 0}} <<
+  {{streamlen}}
+>>
+stream
+</xdp:xdp>
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/xfa_specific/bug_1060549.evt b/testing/resources/javascript/xfa_specific/bug_1060549.evt
new file mode 100644
index 0000000..cee75e2
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1060549.evt
@@ -0,0 +1,3 @@
+mousedown,left,82,130
+mousedown,left,82,130
+keycode,09
\ No newline at end of file
diff --git a/testing/resources/javascript/xfa_specific/bug_1060549.in b/testing/resources/javascript/xfa_specific/bug_1060549.in
new file mode 100644
index 0000000..2652548
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1060549.in
@@ -0,0 +1,59 @@
+{{header}}
+{{include ../../xfa_catalog_1_0.fragment}}
+{{include ../../xfa_object_2_0.fragment}}
+{{include ../../xfa_preamble_3_0.fragment}}
+{{include ../../xfa_config_4_0.fragment}}
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+<template xmlns="http://www.xfa.org/schema/xfa-template/2.6/">
+  <subform layout="tb" locale="en_US" name="form1" restoreState="auto">
+    <subform h="10.5in" w="8in" name="subform2">
+      <field h="10mm" name="field1" w="10mm" x="0mm" y="20mm">
+        <ui>
+          <choiceList/>
+        </ui>
+        <items>
+          <text>aaaaaaaaaaaaaaaaaaaaa</text>
+        </items>
+      </field>
+      <field name="field2" h="20mm" w="50mm" x="0mm" y="30mm">
+        <ui>
+            <textEdit>
+            </textEdit>
+        </ui>
+      </field>
+      <subform name="subform3" x="0mm" y="5mm">
+        <occur max="-1"/>
+          <traversal>
+              <traverse operation="next" ref="$xfa.(eval('if (aa == 1) {aa=2;xfa.host.setFocus(cc);bb();xfa.host.openList(cc);}') == 0)"/>
+          </traversal>
+      </subform>
+    </subform>
+    <event activity="initialize">
+      <script contentType="application/x-javascript">
+        aa = 1;
+      </script>
+    </event>
+    <event activity="docReady">
+      <script contentType="application/x-javascript">
+        bb = function() {
+            dd = xfa.resolveNode("xfa.form..subform3");
+            dd.instanceManager.addInstance(1);
+            dd.instanceManager.removeInstance(0);
+        }
+        cc = xfa.resolveNode("xfa.form..field1");
+      </script>
+    </event>
+  </subform>
+</template>
+endstream
+endobj
+{{include ../../xfa_locale_6_0.fragment}}
+{{include ../../xfa_postamble_7_0.fragment}}
+{{include ../../xfa_pages_8_0.fragment}}
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/xfa_specific/bug_1069700.evt b/testing/resources/javascript/xfa_specific/bug_1069700.evt
new file mode 100644
index 0000000..069f712
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1069700.evt
@@ -0,0 +1,3 @@
+mousedown,left,200,200
+mouseup,left,200,200
+keycode,9,shift
diff --git a/testing/resources/javascript/xfa_specific/bug_1069700.in b/testing/resources/javascript/xfa_specific/bug_1069700.in
new file mode 100644
index 0000000..1dd6ba8
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1069700.in
@@ -0,0 +1,73 @@
+{{header}}
+{{include ../../xfa_catalog_1_0.fragment}}
+{{include ../../xfa_object_2_0.fragment}}
+{{include ../../xfa_preamble_3_0.fragment}}
+{{include ../../xfa_config_4_0.fragment}}
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+<template xmlns="http://www.xfa.org/schema/xfa-template/2.6/">
+  <subform name="form1">
+    <pageSet>
+      <pageArea id="Page1" name="Page1">
+        <contentArea h="10.5in" w="8in" x="0.25in" y="0.25in"/>
+        <medium long="11in" short="8.5in" stock="letter"/>
+      </pageArea>
+    </pageSet>
+    <subform h="10.5in" w="8in" name="subform2">
+      <field h="10mm" name="DropDownList1" w="10mm" x="0mm" y="20mm">
+        <ui>
+          <choiceList/>
+        </ui>
+        <items save="1">
+          <text>Single</text>
+          <text>Married</text>
+          <text>Other</text>
+        </items>
+      </field>
+      <field h="200mm" name="DropDownList2" w="2mm" x="0mm" y="30mm">
+        <ui>
+          <textEdit/>
+       </ui>
+      </field>
+      <subform name="subform3" x="0mm" y="5mm">
+        <occur max="-1"/>
+        <traversal>
+          <traverse operation="next" ref="$xfa.(eval('try { if (aaaa == 1) {bb();} } catch(e){}') == 0)"/>
+        </traversal>
+      </subform>
+      <bookend leader="$"/>
+      <keep intact="none" previous="contentArea"/>
+    </subform>
+    <subform name="subform4" x="0mm">
+      <occur max="-1"/>
+      <field name="choiceList3" minH="32in">
+        <ui>
+          <choiceList/>
+        </ui>
+      </field>
+    </subform>
+    <event activity="docReady">
+      <script contentType="application/x-javascript">
+        aaaa = 1;
+        bb = function() {
+          xfa.host.setFocus(f1);
+          d = xfa.resolveNode("xfa.form..subform4");
+          d.instanceManager.addInstance(1);
+          xfa.host.openList(f1);
+        }
+        f1 = xfa.resolveNode("xfa.form..DropDownList1");
+      </script>
+    </event>
+  </subform>
+</template>
+endstream
+endobj
+{{include ../../xfa_locale_6_0.fragment}}
+{{include ../../xfa_postamble_7_0.fragment}}
+{{include ../../xfa_pages_8_0.fragment}}
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/xfa_specific/bug_1069789.evt b/testing/resources/javascript/xfa_specific/bug_1069789.evt
new file mode 100644
index 0000000..768f6a9
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1069789.evt
@@ -0,0 +1 @@
+mousedown,right,200,200
\ No newline at end of file
diff --git a/testing/resources/javascript/xfa_specific/bug_1069789.in b/testing/resources/javascript/xfa_specific/bug_1069789.in
new file mode 100644
index 0000000..2cb09db
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1069789.in
@@ -0,0 +1,51 @@
+{{header}}
+{{include ../../xfa_catalog_1_0.fragment}}
+{{include ../../xfa_object_2_0.fragment}}
+{{include ../../xfa_preamble_3_0.fragment}}
+{{include ../../xfa_config_4_0.fragment}}
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+<template xmlns="http://www.xfa.org/schema/xfa-template/2.6/">
+  <subform name="form1">
+    <pageSet>
+      <pageArea id="Page1" name="Page1">
+        <contentArea h="10.5in" w="8in" x="0.25in" y="0.25in"/>
+        <medium long="11in" short="8.5in" stock="letter"/>
+      </pageArea>
+    </pageSet>
+    <subform h="10.5in" w="8in" name="subform2">
+      <field h="10mm" name="DropDownList1" w="10mm" x="0mm" y="20mm">
+        <ui>
+          <choiceList/>
+        </ui>
+        <items>
+          <text>Single</text>
+        </items>
+      </field>
+      <field h="200mm" name="DropDownList2" w="200mm" x="0mm" y="30mm">
+        <ui>
+          <textEdit/>
+        </ui>
+        <event activity="enter">
+          <script contentType="application/x-javascript">
+            f1 = xfa.resolveNode("xfa.form..DropDownList1");
+            xfa.host.setFocus(f1);
+            xfa.template.remerge();
+            xfa.host.openList(f1);
+          </script>
+        </event>
+      </field>
+    </subform>
+  </subform>
+</template>
+endstream
+endobj
+{{include ../../xfa_locale_6_0.fragment}}
+{{include ../../xfa_postamble_7_0.fragment}}
+{{include ../../xfa_pages_8_0.fragment}}
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/xfa_specific/bug_1082597.in b/testing/resources/javascript/xfa_specific/bug_1082597.in
new file mode 100644
index 0000000..91a0ef0
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1082597.in
@@ -0,0 +1,150 @@
+{{header}}
+{{include ../../xfa_catalog_1_0.fragment}}
+{{include ../../xfa_object_2_0.fragment}}
+{{include ../../xfa_preamble_3_0.fragment}}
+{{include ../../xfa_config_4_0.fragment}}
+{{object 5 0}} <<
+  {{streanlen}}
+>>
+stream
+<template>
+ <subform layout="tb" name="my_doc">
+  <pageSet id="page" relation="orderedOccurrence">
+   <occur initial="1" max="4" min="1"/>
+   <pageArea id="Page1" name="Page1">
+    <occur max="1" min="1"/>
+    <contentArea h="100mm" w="200mm" x="0.25in" y="0.25in"/>
+    <medium long="297mm" short="210mm" stock="a4"/>
+   </pageArea>
+   <pageArea id="Page2" name="Page2">
+    <occur max="1" min="1"/>
+    <contentArea h="100mm" w="200mm" x="0.25in" y="0.25in"/>
+    <medium long="297mm" short="210mm" stock="a4"/>
+   </pageArea>
+  </pageSet>
+  <event activity="docReady" ref="$host">
+   <script contentType="application/x-javascript">
+    xfa.event.emit();
+    var f=xfa.resolveNode("xfa.form.my_doc.page1_form.combox");
+    xfa.record.nodes.append(this);
+    xfa.form.remerge();
+    xfa.host.setFocus(f);
+    app.alert('Done');
+   </script>
+  </event>
+  <subform layout="tb" name="subform_push_button_1">
+   <occur initial="1" max="10" min="0" name="occur_subform_push_button_1"/>
+   <field h="10mm" name="push_button" w="40mm" x="30mm" y="500mm">
+    <ui>
+     <button highlight="push"/>
+    </ui>
+    <caption>
+     <value>
+      <text>Button</text>
+     </value>
+    </caption>
+    <items>
+     <text name="down">Down Text</text>
+     <text name="rollover">Rollover Text</text>
+    </items>
+   </field>
+  </subform>
+  <subform layout="tb" name="subform_checkbutton_group_0">
+   <occur initial="1" max="10" min="0" name="occur_subform_checkbutton_group_0"/>
+   <exclGroup layout="tb" name="checkbutton_group">
+    <field h="10mm" name="checkbutton_check1" w="40mm" x="30mm" y="600mm">
+     <ui>
+      <checkButton shape="round">
+       <border>
+        <edge/>
+       </border>
+      </checkButton>
+     </ui>
+     <items>
+      <integer>1</integer>
+     </items>
+     <value>
+      <text>Select 1</text>
+     </value>
+     <caption placement="left">
+      <value>
+       <text>Option 1</text>
+      </value>
+     </caption>
+     <event activity="ready" ref="$layout">
+      <script contentType="application/x-javascript">
+      </script>
+     </event>
+    </field>
+    <field h="10mm" name="checkbutton_check2" w="40mm" x="30mm" y="600mm">
+     <ui>
+      <checkButton shape="round">
+       <border>
+        <edge/>
+       </border>
+      </checkButton>
+     </ui>
+     <items>
+      <integer>2</integer>
+     </items>
+     <value>
+      <text>Select 2</text>
+     </value>
+     <caption placement="left">
+      <value>
+       <text>Option 2</text>
+      </value>
+     </caption>
+    </field>
+   </exclGroup>
+  </subform>
+  <subform layout="tb" name="page2_form">
+   <occur initial="1" max="3" min="0"/>
+   <field h="10mm" name="textedit" w="40mm" x="20mm" y="20mm">
+    <ui>
+     <textEdit/>
+    </ui>
+    <value>
+     <text>CLGT.</text>
+    </value>
+   </field>
+  </subform>
+  <subform layout="tb" name="page1_form">
+   <occur initial="1" max="3" min="0"/>
+   <field h="10mm" name="combox" w="40mm" x="10mm" y="10mm">
+    <ui>
+     <choiceList open="onEntry">
+      <border>
+       <edge/>
+      </border>
+     </choiceList>
+    </ui>
+    <items save="1">
+     <text>apples</text>
+     <text>bananas</text>
+     <text>pears</text>
+    </items>
+    <value>
+     <text>
+      apples
+     </text>
+    </value>
+    <event activity="enter" name="event__enter">
+     <script contentType="application/x-javascript">
+      xfa.host.setFocus(0);
+      xfa.host.openList(this);
+     </script>
+    </event>
+   </field>
+  </subform>
+ </subform>
+</template>
+endstream
+endobj
+{{include ../../xfa_locale_6_0.fragment}}
+{{include ../../xfa_postamble_7_0.fragment}}
+{{include ../../xfa_pages_8_0.fragment}}
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/xfa_specific/bug_1082597_expected.txt b/testing/resources/javascript/xfa_specific/bug_1082597_expected.txt
new file mode 100644
index 0000000..3cb772d
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1082597_expected.txt
@@ -0,0 +1,3 @@
+Alert: Done
+Alert: Done
+Alert: Done
diff --git a/testing/resources/javascript/xfa_specific/bug_1109108.evt b/testing/resources/javascript/xfa_specific/bug_1109108.evt
new file mode 100644
index 0000000..7d58927
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1109108.evt
@@ -0,0 +1 @@
+keycode,9
diff --git a/testing/resources/javascript/xfa_specific/bug_1109108.in b/testing/resources/javascript/xfa_specific/bug_1109108.in
new file mode 100644
index 0000000..550112e
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1109108.in
@@ -0,0 +1,64 @@
+{{header}}
+{{include ../../xfa_catalog_1_0.fragment}}
+{{include ../../xfa_object_2_0.fragment}}
+{{include ../../xfa_preamble_3_0.fragment}}
+{{include ../../xfa_config_4_0.fragment}}
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+<template>
+  <subform name="s1">
+    <subform name="s5">
+      <field name="field_28">
+        <calculate>
+          <script contentType="application/x-javascript">
+            var f=xfa.resolveNode("xfa.form.s1.s5.s6.field_35");
+            f.relevant ="print";
+          </script>
+        </calculate>
+        <ui>
+          <textEdit/>
+        </ui>
+        <value>
+          <text>CLGT.</text>
+        </value>
+      </field>
+      <subform name="s6">
+        <field name="field_35">
+          <ui>
+            <choiceList open="onEntry">
+              <border>
+                <edge/>
+              </border>
+            </choiceList>
+          </ui>
+          <items save="1">
+            <text>apples</text>
+            <text>bananas</text>
+            <text>pears</text>
+          </items>
+          <value>
+            <text>apples</text>
+          </value>
+          <event activity="change">
+            <script contentType="application/x-javascript">
+              xfa.template.remerge();
+              xfa.host.openList(this);
+              app.alert('remerged');
+            </script>
+          </event>
+        </field>
+      </subform>
+    </subform>
+  </subform>
+</template>
+endstream
+endobj
+{{include ../../xfa_locale_6_0.fragment}}
+{{include ../../xfa_postamble_7_0.fragment}}
+{{include ../../xfa_pages_8_0.fragment}}
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/xfa_specific/bug_1109108_expected.txt b/testing/resources/javascript/xfa_specific/bug_1109108_expected.txt
new file mode 100644
index 0000000..86c4845
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1109108_expected.txt
@@ -0,0 +1,2 @@
+Alert: remerged
+Alert: remerged
diff --git a/testing/resources/javascript/xfa_specific/bug_1137668.evt b/testing/resources/javascript/xfa_specific/bug_1137668.evt
new file mode 100644
index 0000000..d4b67d8
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1137668.evt
@@ -0,0 +1,9 @@
+keycode,9,shift
+mousedown,left,50,50
+keycode,9
+mousemove,50,50
+mousedown,left,50,50
+keycode,9
+mousemove,20,20
+mousedown,left,20,20
+mousedown,right,20,20
diff --git a/testing/resources/javascript/xfa_specific/bug_1137668.in b/testing/resources/javascript/xfa_specific/bug_1137668.in
new file mode 100644
index 0000000..11014e7
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1137668.in
@@ -0,0 +1,338 @@
+{{header}}
+{{include ../../xfa_catalog_1_0.fragment}}
+{{include ../../xfa_object_2_0.fragment}}
+{{include ../../xfa_preamble_3_0.fragment}}
+{{include ../../xfa_config_4_0.fragment}}
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+<template>
+  <subform name="s1">
+    <subform name="s5">
+      <subform name="s6">
+        <event activity="enter">
+          <script contentType="application/x-javascript">
+            xfa.template.remerge();
+            xfa.form.remerge();
+          </script>
+        </event>
+        <field name="field_31">
+          <ui>
+            <button highlight="push"/>
+          </ui>
+          <caption>
+            <value>
+              <text>
+                Button
+              </text>
+            </value>
+          </caption>
+          <items>
+            <text name="down">
+              Down Text
+            </text>
+            <text name="rollover">
+              Rollover Text
+            </text>
+          </items>
+        </field>
+        <field name="field_32">
+          <ui>
+            <barcode/>
+          </ui>
+          <value>
+            <text>
+              test
+            </text>
+          </value>
+        </field>
+        <field name="field_33">
+          <ui>
+            <checkButton shape="round">
+              <border>
+                <edge/>
+              </border>
+            </checkButton>
+          </ui>
+          <items>
+            <integer>
+              2
+            </integer>
+          </items>
+          <value>
+            <text>
+              Select 2
+            </text>
+          </value>
+          <caption placement="left">
+            <value>
+              <text>
+                Option 2
+              </text>
+            </value>
+          </caption>
+        </field>
+        <field name="field_34">
+          <ui>
+            <textEdit/>
+          </ui>
+          <value>
+            <text>
+              CLGT.
+            </text>
+          </value>
+          <event activity="ready">
+            <script contentType="application/x-javascript">
+            </script>
+          </event>
+          <event activity="enter">
+            <script contentType="application/x-javascript">
+            </script>
+          </event>
+          <event activity="initialize">
+            <script contentType="application/x-javascript">
+            </script>
+          </event>
+        </field>
+        <field name="field_35">
+          <validate>
+            <script contentType="application/x-javascript">
+            </script>
+          </validate>
+          <calculate>
+            <script contentType="application/x-javascript">
+            </script>
+          </calculate>
+          <ui>
+            <choiceList open="onEntry">
+              <border><edge/></border>
+            </choiceList>
+          </ui>
+          <items save="1">
+            <text>apples</text>
+            <text>bananas</text>
+            <text>pears</text>
+          </items>
+          <value>
+            <text>apples</text>
+          </value>
+          <event activity="docClose">
+            <script contentType="application/x-javascript">
+            </script>
+          </event>
+          <event activity="initialize">
+            <script contentType="application/x-javascript">
+            </script>
+          </event>
+          <event activity="change">
+            <script contentType="application/x-javascript">
+            </script>
+          </event>
+        </field>
+        <subform name="s7">
+          <field name="field_36">
+            <ui>
+              <dateTimeEdit>
+                <comb numberOfCells="8"/>
+                <border hand="right">
+                  <edge/>
+                </border>
+              </dateTimeEdit>
+            </ui>
+          </field>
+          <field name="field_37">
+            <validate>
+              <script contentType="application/x-javascript">
+              </script>
+            </validate>
+            <calculate>
+              <script contentType="application/x-javascript">
+              </script>
+            </calculate>
+            <ui>
+              <button highlight="push"/>
+            </ui>
+            <caption>
+              <value>
+                <text>
+                  Button
+                </text>
+              </value>
+            </caption>
+            <items>
+              <text name="down">
+                Down Text
+              </text>
+              <text name="rollover">
+                Rollover Text
+              </text>
+            </items>
+            <event activity="docClose">
+              <script contentType="application/x-javascript">
+              </script>
+            </event>
+            <event activity="change">
+              <script contentType="application/x-javascript">
+              </script>
+            </event>
+            <event activity="exit">
+              <script contentType="application/x-javascript">
+              </script>
+            </event>
+          </field>
+          <field name="field_38">
+            <validate>
+              <script contentType="application/x-javascript">
+              </script>
+            </validate>
+            <calculate>
+              <script contentType="application/x-javascript">
+              </script>
+            </calculate>
+            <ui>
+              <barcode/>
+            </ui>
+            <value>
+              <text>
+                test
+              </text>
+            </value>
+            <event activity="initialize">
+              <script contentType="application/x-javascript">
+              </script>
+            </event>
+            <event activity="change">
+              <script contentType="application/x-javascript">
+              </script>
+            </event>
+            <event activity="ready">
+              <script contentType="application/x-javascript">
+              </script>
+            </event>
+          </field>
+          <field name="field_39">
+            <validate>
+              <script contentType="application/x-javascript">
+              </script>
+            </validate>
+            <calculate>
+              <script contentType="application/x-javascript">
+              </script>
+            </calculate>
+            <ui>
+              <checkButton shape="round">
+                <border>
+                  <edge/>
+                </border>
+              </checkButton>
+            </ui>
+            <items>
+              <integer>
+                2
+              </integer>
+            </items>
+            <value>
+              <text>
+                Select 2
+              </text>
+            </value>
+            <caption placement="left">
+              <value>
+                <text>
+                  Option 2
+                </text>
+              </value>
+            </caption>
+            <event activity="enter">
+              <script contentType="application/x-javascript">
+              </script>
+            </event>
+            <event activity="ready">
+              <script contentType="application/x-javascript">
+              </script>
+            </event>
+            <event activity="change">
+              <script contentType="application/x-javascript">
+              </script>
+            </event>
+          </field>
+          <field name="field_40">
+            <validate>
+              <script contentType="application/x-javascript">
+              </script>
+            </validate>
+            <calculate>
+              <script contentType="application/x-javascript">
+              </script>
+            </calculate>
+            <ui>
+              <textEdit/>
+            </ui>
+            <value>
+              <text>
+                CLGT.
+              </text>
+            </value>
+            <event activity="ready">
+              <script contentType="application/x-javascript">
+              </script>
+            </event>
+            <event activity="docClose">
+              <script contentType="application/x-javascript">
+              </script>
+            </event>
+            <event activity="exit">
+              <script contentType="application/x-javascript">
+              </script>
+            </event>
+          </field>
+          <field name="field_41">
+            <validate>
+              <script contentType="application/x-javascript">
+              </script>
+            </validate>
+            <calculate>
+              <script contentType="application/x-javascript">
+              </script>
+            </calculate>
+            <ui>
+              <choiceList open="onEntry">
+                <border><edge/></border>
+              </choiceList>
+            </ui>
+            <items save="1">
+              <text>apples</text>
+              <text>bananas</text>
+              <text>pears</text>
+            </items>
+            <value>
+              <text>apples</text>
+            </value>
+            <event activity="docClose">
+              <script contentType="application/x-javascript">
+              </script>
+            </event>
+            <event activity="initialize">
+              <script contentType="application/x-javascript">
+              </script>
+            </event>
+            <event activity="initialize">
+              <script contentType="application/x-javascript">
+              </script>
+            </event>
+          </field>
+        </subform>
+      </subform>
+    </subform>
+  </subform>
+</template>
+endstream
+endobj
+{{include ../../xfa_locale_6_0.fragment}}
+{{include ../../xfa_postamble_7_0.fragment}}
+{{include ../../xfa_pages_8_0.fragment}}
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/xfa_specific/bug_1164158.in b/testing/resources/javascript/xfa_specific/bug_1164158.in
new file mode 100644
index 0000000..28b7eff
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1164158.in
@@ -0,0 +1,37 @@
+{{header}}
+{{include ../../xfa_catalog_1_0.fragment}}
+{{include ../../xfa_object_2_0.fragment}}
+{{include ../../xfa_preamble_3_0.fragment}}
+{{include ../../xfa_config_4_0.fragment}}
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+<template xmlns="http://www.xfa.org/schema/xfa-template/3.3/">
+  <subform>
+    <pageSet relation="simplexPaginated">
+      <pageArea pagePosition="last">
+        <subform>
+          <subform layout="table">
+            <subform layout="row">
+              <field />
+              <field colSpan="4294967295" presence="inactive" />
+            </subform>
+          </subform>
+        </subform>
+      </pageArea>
+      <pageArea>
+        <contentArea />
+      </pageArea>
+    </pageSet>
+  </subform>
+</template>
+endstream
+endobj
+{{include ../../xfa_locale_6_0.fragment}}
+{{include ../../xfa_postamble_7_0.fragment}}
+{{include ../../xfa_pages_8_0.fragment}}
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/xfa_specific/bug_1248901.in b/testing/resources/javascript/xfa_specific/bug_1248901.in
new file mode 100644
index 0000000..8e2638a
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1248901.in
@@ -0,0 +1,47 @@
+{{header}}
+{{include ../../xfa_catalog_1_0.fragment}}
+{{include ../../xfa_object_2_0.fragment}}
+{{include ../../xfa_preamble_3_0.fragment}}
+{{include ../../xfa_config_4_0.fragment}}
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+stream
+<template xmlns="http://www.xfa.org/schema/xfa-template/2.6/">
+  <subform layout="tb" locale="en_US" name="form1" restoreState="auto">
+    <pageSet>
+      <pageArea id="Page1" name="Page1">
+        <contentArea h="10.5in" w="8in" x="0.25in" y="0.25in"/>
+        <medium long="11in" short="8.5in" stock="letter"/>
+      </pageArea>
+    </pageSet>
+    <subform h="10.5in" w="8in" name="subform2">
+      <field h="9.0001mm" name="field1" w="47.625mm" x="6.35mm" y="92.075mm">
+        <ui>
+          <choiceList/>
+        </ui>
+      </field>
+    </subform>
+    <event activity="docReady" ref="$host">
+      <script contentType="application/x-javascript">
+        try {
+          var form1 = xfa.resolveNode("xfa.form.form1");
+          var tmp = xfa.resolveNode("xfa.form..field1");
+          tmp.nodes.append(this);
+        } catch (e) {
+          app.alert("PASS: Caught: " + e);
+        }
+     </script>
+    </event>
+  </subform>
+</template>
+endstream
+endobj
+{{include ../../xfa_locale_6_0.fragment}}
+{{include ../../xfa_postamble_7_0.fragment}}
+{{include ../../xfa_pages_8_0.fragment}}
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/xfa_specific/bug_1248901_expected.txt b/testing/resources/javascript/xfa_specific/bug_1248901_expected.txt
new file mode 100644
index 0000000..abf828c
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1248901_expected.txt
@@ -0,0 +1 @@
+Alert: PASS: Caught: XFAObject.append: Operation would create a cycle.
diff --git a/testing/resources/javascript/xfa_specific/bug_1312736.in b/testing/resources/javascript/xfa_specific/bug_1312736.in
new file mode 100644
index 0000000..f388810
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1312736.in
@@ -0,0 +1,40 @@
+{{header}}
+{{include ../../xfa_catalog_1_0.fragment}}
+{{include ../../xfa_object_2_0.fragment}}
+{{object 3 0}} <<
+  {{streamlen}}
+>>
+stream
+<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
+<template x="">
+  <subform>
+    <pageSet>
+      <pageArea>
+        <contentArea/>
+        <exclGroup name="0">
+          <field>
+            <ui><checkButton/></ui>
+            <items><textEdit/></items>
+          </field>
+        </exclGroup>
+        <subform name="Sho0">
+          <event activity="initialize">
+            <script contentType="application/x-javascript">
+              Sho0.presence=0;
+              app.alert("done");
+            </script>
+          </event>
+        </subform>
+      </pageArea>
+    </pageSet>
+  </subform>
+</template>
+endstream
+endobj
+{{object 8 0} <<
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/xfa_specific/bug_1312736_expected.txt b/testing/resources/javascript/xfa_specific/bug_1312736_expected.txt
new file mode 100644
index 0000000..daa1eca
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1312736_expected.txt
@@ -0,0 +1 @@
+Alert: done
diff --git a/testing/resources/javascript/xfa_specific/bug_1444238.evt b/testing/resources/javascript/xfa_specific/bug_1444238.evt
new file mode 100644
index 0000000..adca35a
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1444238.evt
@@ -0,0 +1,3 @@
+mousedown,left,91,539
+mouseup,left,91,539
+charcode,32
diff --git a/testing/resources/javascript/xfa_specific/bug_1444238.in b/testing/resources/javascript/xfa_specific/bug_1444238.in
new file mode 100644
index 0000000..675178c
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1444238.in
@@ -0,0 +1,149 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm 4 0 R
+  /OpenAction 40 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 2
+  /Kids [
+    32 0 R
+    34 0 R
+  ]
+>>
+endobj
+% Forms
+{{object 4 0}} <<
+  /XFA 43 0 R
+  /Fields [
+    10 0 R
+    11 0 R
+  ]
+>>
+endobj
+% Fields
+{{object 10 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Tx
+  /T (MyField5)
+  /V (myfield_5)
+  /Rect [0 500 600 600]
+>>
+% Fields
+{{object 11 0}} <<
+  /T (MyField3)
+  /Parent 4 0 R
+  /Kids [12 0 R]
+  /Opt [(a) (b) (c) (d)]
+  /V [(a) (b) (c)]
+>>
+endobj
+% Fields
+{{object 12 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Ch
+  /Ff 131072
+  /Parent 11 0 R
+  /Kids [13 0 R]
+>>
+endobj
+% Fields
+{{object 13 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /Parent 12 0 R
+  /Rect [0 400 600 600]
+>>
+endobj
+% Fields
+{{object 14 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /Parent 12 0 R
+  /Rect [100 400 500 500]
+>>
+endobj
+% Page number 2.
+{{object 32 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 612 792]
+  /Annots [13 0 R]
+
+>>
+endobj
+{{object 34 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 612 792]
+  /Annots [10 0 R]
+>>
+endobj
+% Document JS Action
+{{object 40 0}} <<
+  /Type /Action
+  /S /JavaScript
+  /JS 41 0 R
+>>
+endobj
+% JS program to exexute
+{{object 41 0}} <<
+>>
+stream
+var f5 = this.getField("MyField5");
+var f3 = this.getField("MyField3");
+f3.setFocus();
+this.__defineGetter__("pageNum",function o(){f5.setFocus(); f3.borderStyle="dashed"; f3.setFocus();});
+endstream
+endobj
+{{object 43 0}} <<
+  {{streamlen}}
+>>
+stream
+<?xml version="1.0" encoding="UTF-8"?>
+<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
+<config></config>
+<template xmlns="http://www.xfa.org/schema/xfa-template/2.8/">
+  <subform layout="tb" locale="en_US">
+    <pageSet>
+      <pageArea id="Page1" name="Page1">
+        <contentArea h="268.939mm" w="203.2mm" x="6.35mm" y="6.35mm"/>
+        <medium long="792pt" short="612pt" stock="default"/>
+      </pageArea>
+    </pageSet>
+    <field h="9.0001mm" name="MyField3" w="47.625mm" x="120mm" y="120mm">
+      <ui>
+        <choiceList open="onEntry">
+          <border>
+            <edge/>
+          </border>
+        </choiceList>
+      </ui>
+      <items save="1">
+        <text>apples</text>
+        <text>bananas</text>
+        <text>pears</text>
+      </items>
+      <value>
+        <text>apples</text>
+      </value>
+      <event activity="preOpen">
+        <script contentType="application/x-javascript">
+            var aa = this.pageNum;
+        </script>
+      </event>
+    </field>
+  </subform>
+</template>
+</xdp:xdp>
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/xfa_specific/bug_980116.evt b/testing/resources/javascript/xfa_specific/bug_980116.evt
new file mode 100644
index 0000000..a5025fa
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_980116.evt
@@ -0,0 +1,4 @@
+mousemove,50,50
+mousedown,left,50,50
+mouseup,left,50,50
+keycode,9
diff --git a/testing/resources/javascript/xfa_specific/bug_980116.in b/testing/resources/javascript/xfa_specific/bug_980116.in
new file mode 100644
index 0000000..11bcbf2
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_980116.in
@@ -0,0 +1,58 @@
+{{header}}
+{{include ../../xfa_catalog_1_0.fragment}}
+{{include ../../xfa_object_2_0.fragment}}
+{{include ../../xfa_preamble_3_0.fragment}}
+{{include ../../xfa_config_4_0.fragment}}
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+<template xmlns="http://www.xfa.org/schema/xfa-template/2.6/">
+  <subform layout="tb" locale="en_US" name="form1" restoreState="auto">
+    <pageSet>
+      <pageArea id="Page1" name="Page1">
+        <contentArea h="10.5in" w="8in" x="0.25in" y="0.25in"/>
+        <medium long="11in" short="8.5in" stock="letter"/>
+      </pageArea>
+    </pageSet>
+    <subform h="10.5in" w="8in">
+      <field h="3mm" name="DropDownList1" w="3mm" x="0mm" y="1mm">
+        <ui>
+          <choiceList/>
+        </ui>
+        <items save="1">
+          <text>Single</text>
+          <text>Married</text>
+          <text>Other</text>
+        </items>
+      </field>
+      <field h="500.0001mm" name="DropDownList2" w="500.625mm" x="0mm" y="0mm">
+        <ui>
+          <textEdit></textEdit>
+        </ui>
+        <value>
+          <text>Employee</text>
+        </value>
+      </field>
+    </subform>
+    <traversal>
+        <traverse operation="first" ref="$xfa.(eval('xfa.host.setFocus(field_DropDownList1); xfa.template.remerge(); xfa.host.openList(field_DropDownList1);') == 0)"/>
+    </traversal>
+    <event activity="docReady">
+      <script contentType="application/x-javascript">
+        field_DropDownList1 = xfa.resolveNode("xfa.form..DropDownList1");
+        field_DropDownList2 = xfa.resolveNode("xfa.form..DropDownList2");
+        xfa.host.setFocus(field_DropDownList2);
+      </script>
+    </event>
+  </subform>
+</template>
+endstream
+endobj
+{{include ../../xfa_locale_6_0.fragment}}
+{{include ../../xfa_postamble_7_0.fragment}}
+{{include ../../xfa_pages_8_0.fragment}}
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/xfa_specific/bug_980161.evt b/testing/resources/javascript/xfa_specific/bug_980161.evt
new file mode 100644
index 0000000..a5025fa
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_980161.evt
@@ -0,0 +1,4 @@
+mousemove,50,50
+mousedown,left,50,50
+mouseup,left,50,50
+keycode,9
diff --git a/testing/resources/javascript/xfa_specific/bug_980161.in b/testing/resources/javascript/xfa_specific/bug_980161.in
new file mode 100644
index 0000000..058444d
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_980161.in
@@ -0,0 +1,55 @@
+{{header}}
+{{include ../../xfa_catalog_1_0.fragment}}
+{{include ../../xfa_object_2_0.fragment}}
+{{include ../../xfa_preamble_3_0.fragment}}
+{{include ../../xfa_config_4_0.fragment}}
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+<template xmlns="http://www.xfa.org/schema/xfa-template/2.6/">
+  <subform layout="tb" locale="en_US" name="form1" restoreState="auto">
+    <pageSet>
+      <pageArea id="Page1" name="Page1">
+        <contentArea h="10.5in" w="8in" x="0.25in" y="0.25in"/>
+        <medium long="11in" short="8.5in" stock="letter"/>
+      </pageArea>
+    </pageSet>
+    <subform h="10.5in" w="8in">
+      <field h="3mm" name="DropDownList1" w="3mm" x="0mm" y="1mm">
+        <ui>
+          <choiceList/>
+        </ui>
+        <items save="1">
+          <text>Single</text>
+          <text>Married</text>
+          <text>Other</text>
+        </items>
+      </field>
+      <field h="500.0001mm" name="DropDownList2" w="500.625mm" x="0mm" y="0mm">
+        <ui>
+          <textEdit></textEdit>
+        </ui>
+        <traversal>
+          <traverse operation="next" ref="$xfa.(eval('xfa.host.setFocus(field_DropDownList1); xfa.template.remerge(); xfa.host.openList(field_DropDownList1);') == 0)"/>
+        </traversal>
+      </field>
+    </subform>
+    <event activity="docReady">
+      <script contentType="application/x-javascript">
+        field_DropDownList1 = xfa.resolveNode("xfa.form..DropDownList1");
+        field_DropDownList2 = xfa.resolveNode("xfa.form..DropDownList2");
+        xfa.host.setFocus(field_DropDownList2);
+      </script>
+    </event>
+  </subform>
+</template>
+endstream
+endobj
+{{include ../../xfa_locale_6_0.fragment}}
+{{include ../../xfa_postamble_7_0.fragment}}
+{{include ../../xfa_pages_8_0.fragment}}
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/xfa_specific/cross_engine_apply.in b/testing/resources/javascript/xfa_specific/cross_engine_apply.in
index cdaad2a..3a41708 100644
--- a/testing/resources/javascript/xfa_specific/cross_engine_apply.in
+++ b/testing/resources/javascript/xfa_specific/cross_engine_apply.in
@@ -46,6 +46,7 @@
 endobj
 {{include ../../xfa_locale_6_0.fragment}}
 {{include ../../xfa_postamble_7_0.fragment}}
+{{include ../../xfa_pages_8_0.fragment}}
 {{xref}}
 {{trailer}}
 {{startxref}}
diff --git a/testing/resources/javascript/xfa_specific/dump_tree.js b/testing/resources/javascript/xfa_specific/dump_tree.js
new file mode 100644
index 0000000..171c72a
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/dump_tree.js
@@ -0,0 +1,22 @@
+// Copyright 2020 The PDFium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Note: Be sure that this file is only included inside a CDATA block,
+// otherwise the less-than comparision below will break the XML parse.
+
+function dumpTree(node, level) {
+  level = level || 0;
+  var indentation = "| ".repeat(level);
+  try {
+    app.alert(indentation + node.className);
+    var children = node.nodes;
+    if (children) {
+      for (var i = 0; i < children.length; ++i) {
+        dumpTree(children.item(i), level + 1);
+      }
+    }
+  } catch (e) {
+    app.alert(indentation + "Error: " + e);
+  }
+}
diff --git a/testing/resources/javascript/xfa_specific/instance_manager.in b/testing/resources/javascript/xfa_specific/instance_manager.in
new file mode 100644
index 0000000..fe3d776
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/instance_manager.in
@@ -0,0 +1,99 @@
+{{header}}
+{{include ../../xfa_catalog_1_0.fragment}}
+{{include ../../xfa_object_2_0.fragment}}
+{{include ../../xfa_preamble_3_0.fragment}}
+{{include ../../xfa_config_4_0.fragment}}
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+<template xmlns="http://www.xfa.org/schema/xfa-template/2.6/">
+  <subform layout="tb" locale="en_US" name="form1" restoreState="auto">
+    <pageSet>
+      <pageArea id="Page1" name="Page1">
+        <contentArea h="10.5in" w="8in" x="0.25in" y="0.25in"/>
+        <medium long="11in" short="8.5in" stock="letter"/>
+      </pageArea>
+    </pageSet>
+    <subform h="10.5in" w="8in" name="subform2">
+      <field h="9.0001mm" name="field1" w="47.625mm" x="6.35mm" y="92.075mm">
+        <ui>
+          <choiceList/>
+        </ui>
+        <items save="1">
+          <text>Single</text>
+          <text>Married</text>
+          <text>Other</text>
+        </items>
+      </field>
+      <field name="field3" h="10.625mm" w="30.625mm" x="5mm" y="50mm">
+      </field>
+      <subform name="field4" x="5mm" y="5mm">
+        <occur max="-1"/>
+        <field name="field5" w="64.77mm" h="6.35mm">
+        </field>
+      </subform>
+    </subform>
+    <event activity="docReady">
+      <script contentType="application/x-javascript"><![CDATA[
+        {{include ../expect.js}}
+        {{include ../property_test_helpers.js}}
+        {{include dump_tree.js}}
+
+        var mgr = xfa.resolveNode("xfa.form..field4").instanceManager;
+        dumpTree(mgr);
+
+        testRWProperty(mgr, "count", 1, 12);
+        testROProperty(mgr, "min", 1);
+        testROProperty(mgr, "max", -1);
+
+        expectError("mgr.setInstances()");
+        expectError("mgr.setInstances(-10)");
+        expectError("mgr.setInstances('clams')");
+        expectError("mgr.setInstances([1, 2, 3])");
+        // setInstances(10000000) will hang or hit OOM.
+        expect("mgr.setInstances(4)", undefined);
+        expect("mgr.count", 4);
+        expect("mgr.setInstances(2)", undefined);
+        expect("mgr.count", 2);
+
+        expectError("mgr.moveInstance()");
+        expectError("mgr.moveInstance(0)");
+        expectError("mgr.moveInstance('clams')");
+        expectError("mgr.moveInstance([1, 2, 3])");
+        expect("mgr.moveInstance(0, 1)", undefined);
+        expect("mgr.count", 2);
+
+        expectError("mgr.addInstance(1, 2, 3)");
+        expect("mgr.addInstance().className", "subform");
+        expect("mgr.addInstance(true).className", "subform");
+        expect("mgr.count", 4);
+
+        expectError("mgr.insertInstance()");
+        expectError("mgr.insertInstance(1, 2, 3)");
+        expect("mgr.insertInstance(1, true).className", "subform");
+        expect("mgr.count", 5);
+
+        expectError("mgr.removeInstance()");
+        expectError("mgr.removeInstance(1, 2)");
+        expect("mgr.removeInstance(0)", undefined);
+        expect("mgr.removeInstance(0)", undefined);
+        expect("mgr.removeInstance(0)", undefined);
+        expect("mgr.removeInstance(0)", undefined);
+        expect("mgr.count", 1);
+
+        expectError("mgr.removeInstance(0)");
+        expect("mgr.count", 1);
+      ]]></script>
+    </event>
+  </subform>
+</template>
+endstream
+endobj
+{{include ../../xfa_locale_6_0.fragment}}
+{{include ../../xfa_postamble_7_0.fragment}}
+{{include ../../xfa_pages_8_0.fragment}}
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/xfa_specific/instance_manager_expected.txt b/testing/resources/javascript/xfa_specific/instance_manager_expected.txt
new file mode 100644
index 0000000..d39657f
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/instance_manager_expected.txt
@@ -0,0 +1,39 @@
+Alert: instanceManager
+Alert: | occur
+Alert: PASS: count = 1
+Alert: PASS: count = 12
+Alert: PASS: min = 1
+Alert: PASS: min threw Error: Invalid property set operation.
+Alert: PASS: max = -1
+Alert: PASS: max threw Error: Invalid property set operation.
+Alert: PASS: mgr.setInstances() threw XFAObject.setInstances: Incorrect number of parameters passed to function.
+Alert: PASS: mgr.setInstances(-10) threw Error: The element [min] has violated its allowable number of occurrences.
+Alert: PASS: mgr.setInstances('clams') threw Error: The element [min] has violated its allowable number of occurrences.
+Alert: PASS: mgr.setInstances([1, 2, 3]) threw Error: The element [min] has violated its allowable number of occurrences.
+Alert: PASS: mgr.setInstances(4) = undefined
+Alert: PASS: mgr.count = 4
+Alert: PASS: mgr.setInstances(2) = undefined
+Alert: PASS: mgr.count = 2
+Alert: PASS: mgr.moveInstance() threw XFAObject.moveInstance: Incorrect number of parameters passed to function.
+Alert: PASS: mgr.moveInstance(0) threw XFAObject.moveInstance: Incorrect number of parameters passed to function.
+Alert: PASS: mgr.moveInstance('clams') threw XFAObject.moveInstance: Incorrect number of parameters passed to function.
+Alert: PASS: mgr.moveInstance([1, 2, 3]) threw XFAObject.moveInstance: Incorrect number of parameters passed to function.
+Alert: PASS: mgr.moveInstance(0, 1) = undefined
+Alert: PASS: mgr.count = 2
+Alert: PASS: mgr.addInstance(1, 2, 3) threw XFAObject.addInstance: Incorrect number of parameters passed to function.
+Alert: PASS: mgr.addInstance().className = subform
+Alert: PASS: mgr.addInstance(true).className = subform
+Alert: PASS: mgr.count = 4
+Alert: PASS: mgr.insertInstance() threw XFAObject.insertInstance: Incorrect number of parameters passed to function.
+Alert: PASS: mgr.insertInstance(1, 2, 3) threw XFAObject.insertInstance: Incorrect number of parameters passed to function.
+Alert: PASS: mgr.insertInstance(1, true).className = subform
+Alert: PASS: mgr.count = 5
+Alert: PASS: mgr.removeInstance() threw XFAObject.removeInstance: Incorrect number of parameters passed to function.
+Alert: PASS: mgr.removeInstance(1, 2) threw XFAObject.removeInstance: Incorrect number of parameters passed to function.
+Alert: PASS: mgr.removeInstance(0) = undefined
+Alert: PASS: mgr.removeInstance(0) = undefined
+Alert: PASS: mgr.removeInstance(0) = undefined
+Alert: PASS: mgr.removeInstance(0) = undefined
+Alert: PASS: mgr.count = 1
+Alert: PASS: mgr.removeInstance(0) threw XFAObject.removeInstance: Too many occurrences.
+Alert: PASS: mgr.count = 1
diff --git a/testing/resources/javascript/xfa_specific/mixed_widgets.evt b/testing/resources/javascript/xfa_specific/mixed_widgets.evt
new file mode 100644
index 0000000..f4ee07d
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/mixed_widgets.evt
@@ -0,0 +1,5 @@
+mousemove,302,302
+mousedown,left,302,302
+mouseup,left,302,302
+charcode,65
+charcode,66
diff --git a/testing/resources/javascript/xfa_specific/mixed_widgets.in b/testing/resources/javascript/xfa_specific/mixed_widgets.in
new file mode 100644
index 0000000..2974112
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/mixed_widgets.in
@@ -0,0 +1,48 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /NeedsRendering true
+  /AcroForm <<
+    /Fields [6 0 R]
+    /XFA 5 0 R
+  >>
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [4 0 R]
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 512 512]
+  /Annots [6 0 R]
+>>
+endobj
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+<xdp xmlns="http://ns.adobe.com/xdp/">
+  <template>
+    <subform x="0pt" y="0pt" w="198pt" h="198pt">
+      <field name="MyBox"/>
+    </subform>
+  </template>
+</xdp>
+endstream
+endobj
+{{object 6 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Tx
+  /Rect [200 200 512 512]
+  /T (MyBox)
+>>
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/xfa_specific/popup_menu.evt b/testing/resources/javascript/xfa_specific/popup_menu.evt
new file mode 100644
index 0000000..7820426
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/popup_menu.evt
@@ -0,0 +1,5 @@
+mousemove,20,20
+mousedown,left,20,20
+mouseup,left,20,20
+mousedown,right,20,20
+mouseup,right,20,20
diff --git a/testing/resources/javascript/xfa_specific/popup_menu.in b/testing/resources/javascript/xfa_specific/popup_menu.in
new file mode 100644
index 0000000..52f7a45
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/popup_menu.in
@@ -0,0 +1,40 @@
+{{header}}
+{{include ../../xfa_catalog_1_0.fragment}}
+{{include ../../xfa_object_2_0.fragment}}
+{{include ../../xfa_preamble_3_0.fragment}}
+{{include ../../xfa_config_4_0.fragment}}
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+<template xmlns="http://www.xfa.org/schema/xfa-template/3.3/">
+  <subform name="form1" layout="tb" locale="en_US" restoreState="auto">
+    <pageSet>
+      <pageArea name="Page1" id="Page1">
+        <contentArea x="18pt" y="18pt" w="612pt" h="792pt"/>
+        <medium stock="default" short="612pt" long="792pt"/>
+      </pageArea>
+    </pageSet>
+    <subform w="576pt" h="756pt" name="Page1">
+      <field name="ImageField1" y="0pt" x="0pt" w="425pt" h="80pt">
+        <ui>
+          <choiceList open="userControl"/>
+        </ui>
+        <items save="1">
+          <text>clams</text>
+          <text>oysters</text>
+          <text>crabs</text>
+        </items>
+      </field>
+    </subform>
+  </subform>
+</template>
+endstream
+endobj
+{{include ../../xfa_locale_6_0.fragment}}
+{{include ../../xfa_postamble_7_0.fragment}}
+{{include ../../xfa_pages_8_0.fragment}}
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/xfa_specific/popup_menu_expected.txt b/testing/resources/javascript/xfa_specific/popup_menu_expected.txt
new file mode 100644
index 0000000..dc856e9
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/popup_menu_expected.txt
@@ -0,0 +1 @@
+Popup: x=20.0, y=20.0, flags=0x0
diff --git a/testing/resources/javascript/xfa_specific/xfa_exclgroup.in b/testing/resources/javascript/xfa_specific/xfa_exclgroup.in
new file mode 100644
index 0000000..1a29352
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/xfa_exclgroup.in
@@ -0,0 +1,86 @@
+{{header}}
+{{include ../../xfa_catalog_1_0.fragment}}
+{{include ../../xfa_object_2_0.fragment}}
+{{include ../../xfa_preamble_3_0.fragment}}
+{{include ../../xfa_config_4_0.fragment}}
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+<template>
+  <subform layout="tb">
+    <exclGroup name="RadioButtonList" layout="lr-tb">
+      <field w="30mm" h="6mm" name="yes">
+        <ui>
+          <checkButton shape="round">
+          </checkButton>
+        </ui>
+        <items>
+          <text>Agree</text>
+        </items>
+      </field>
+      <field w="30mm" h="6mm" name="no">
+        <ui>
+          <checkButton shape="round">
+          </checkButton>
+        </ui>
+        <items>
+          <text>Disagree</text>
+        </items>
+      </field>
+      <validate nullTest="error"/>
+    </exclGroup>
+    <event activity="initialize">
+      <script contentType="application/x-javascript"><![CDATA[
+        {{include ../expect.js}}
+        expect("RadioButtonList.className", "exclGroup");
+
+        expectError("RadioButtonList.execEvent()");
+        expectError("RadioButtonList.execEvent(1, 2)");
+        expect("RadioButtonList.execEvent('nonesuch')", null);
+        expect("RadioButtonList.execEvent('calculate')", null);
+        expect("RadioButtonList.execEvent('change')", null);
+        expect("RadioButtonList.execEvent('click')", null);
+        expect("RadioButtonList.execEvent('enter')", null);
+        expect("RadioButtonList.execEvent('exit')", null);
+        expect("RadioButtonList.execEvent('full')", null);
+        expect("RadioButtonList.execEvent('indexChange')", null);
+        expect("RadioButtonList.execEvent('initialize')", null);
+        expect("RadioButtonList.execEvent('mouseDown')", null);
+        expect("RadioButtonList.execEvent('mouseEnter')", null);
+        expect("RadioButtonList.execEvent('mouseExit')", null);
+        expect("RadioButtonList.execEvent('mouseUp')", null);
+        expect("RadioButtonList.execEvent('postOpen')", null);
+        expect("RadioButtonList.execEvent('preOpen')", null);
+        expect("RadioButtonList.execEvent('preSign')", null);
+        expect("RadioButtonList.execEvent('validate')", null);
+
+        expectError("RadioButtonList.execInitialize('badarg')");
+        expect("RadioButtonList.execInitialize()", null);
+
+        expectError("RadioButtonList.execCalculate('badarg')");
+        expect("RadioButtonList.execCalculate()", null);
+
+        expectError("RadioButtonList.execValidate('badarg')");
+        expect("RadioButtonList.execValidate()", true);
+
+        expectError("RadioButtonList.selectedMember('badarg')");
+        expect("RadioButtonList.selectedMember()", null);
+
+        expect("RadioButtonList.defaultValue",  undefined);
+        expect("RadioButtonList.rawValue", null);
+        expect("RadioButtonList.transient", undefined);
+        expect("RadioButtonList.errorText", undefined);
+      ]]></script>
+    </event>
+  </subform>
+</template>
+endstream
+endobj
+{{include ../../xfa_locale_6_0.fragment}}
+{{include ../../xfa_postamble_7_0.fragment}}
+{{include ../../xfa_pages_8_0.fragment}}
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/xfa_specific/xfa_exclgroup_expected.txt b/testing/resources/javascript/xfa_specific/xfa_exclgroup_expected.txt
new file mode 100644
index 0000000..7ca5a78
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/xfa_exclgroup_expected.txt
@@ -0,0 +1,32 @@
+Alert: PASS: RadioButtonList.className = exclGroup
+Alert: PASS: RadioButtonList.execEvent() threw XFAObject.execEvent: Incorrect number of parameters passed to function.
+Alert: PASS: RadioButtonList.execEvent(1, 2) threw XFAObject.execEvent: Incorrect number of parameters passed to function.
+Alert: PASS: RadioButtonList.execEvent('nonesuch') = undefined
+Alert: PASS: RadioButtonList.execEvent('calculate') = undefined
+Alert: PASS: RadioButtonList.execEvent('change') = undefined
+Alert: PASS: RadioButtonList.execEvent('click') = undefined
+Alert: PASS: RadioButtonList.execEvent('enter') = undefined
+Alert: PASS: RadioButtonList.execEvent('exit') = undefined
+Alert: PASS: RadioButtonList.execEvent('full') = undefined
+Alert: PASS: RadioButtonList.execEvent('indexChange') = undefined
+Alert: PASS: RadioButtonList.execEvent('initialize') = undefined
+Alert: PASS: RadioButtonList.execEvent('mouseDown') = undefined
+Alert: PASS: RadioButtonList.execEvent('mouseEnter') = undefined
+Alert: PASS: RadioButtonList.execEvent('mouseExit') = undefined
+Alert: PASS: RadioButtonList.execEvent('mouseUp') = undefined
+Alert: PASS: RadioButtonList.execEvent('postOpen') = undefined
+Alert: PASS: RadioButtonList.execEvent('preOpen') = undefined
+Alert: PASS: RadioButtonList.execEvent('preSign') = undefined
+Alert: PASS: RadioButtonList.execEvent('validate') = undefined
+Alert: PASS: RadioButtonList.execInitialize('badarg') threw XFAObject.execInitialize: Incorrect number of parameters passed to function.
+Alert: PASS: RadioButtonList.execInitialize() = undefined
+Alert: PASS: RadioButtonList.execCalculate('badarg') threw XFAObject.execCalculate: Incorrect number of parameters passed to function.
+Alert: PASS: RadioButtonList.execCalculate() = undefined
+Alert: PASS: RadioButtonList.execValidate('badarg') threw XFAObject.execValidate: Incorrect number of parameters passed to function.
+Alert: PASS: RadioButtonList.execValidate() = true
+Alert: PASS: RadioButtonList.selectedMember('badarg') threw XFAObject.selectedMember: Incorrect number of parameters passed to function.
+Alert: PASS: RadioButtonList.selectedMember() = null
+Alert: PASS: RadioButtonList.defaultValue = undefined
+Alert: PASS: RadioButtonList.rawValue = null
+Alert: PASS: RadioButtonList.transient = undefined
+Alert: PASS: RadioButtonList.errorText = undefined
diff --git a/testing/resources/javascript/xfa_specific/xfa_field.in b/testing/resources/javascript/xfa_specific/xfa_field.in
new file mode 100644
index 0000000..a358921
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/xfa_field.in
@@ -0,0 +1,92 @@
+{{header}}
+{{include ../../xfa_catalog_1_0.fragment}}
+{{include ../../xfa_object_2_0.fragment}}
+{{include ../../xfa_preamble_3_0.fragment}}
+{{include ../../xfa_config_4_0.fragment}}
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+<template>
+  <subform layout="tb" name="subform1">
+    <pageSet id="page" relation="orderedOccurrence">
+      <occur initial="1" max="1" min="1"/>
+      <pageArea id="Page1" name="Page1">
+        <occur max="1" min="1"/>
+        <contentArea h="100mm" w="200mm" x="0.25in" y="0.25in"/>
+        <medium long="297mm" short="210mm" stock="a4"/>
+      </pageArea>
+    </pageSet>
+    <subform layout="tb" name="subform2">
+      <occur initial="1" max="10" min="0" name="occur1">
+      </occur>
+      <field name="field1" h="10mm"  w="40mm" x="10mm" y="12mm" border="solid">
+        <items>
+          <text>and a one</text>
+          <text>and a two</text>
+        </items>
+        <event activity="ready" ref="$form">
+          <script contentType="application/x-javascript"><![CDATA[
+            {{include ../expect.js}}
+            {{include ../property_test_helpers.js}}
+            var field = xfa.resolveNode("field1");
+            testRWProperty(field, "x", "10mm", "11mm");
+            testRWProperty(field, "y", "12mm", "13mm");
+            testRWProperty(field, "h", "10mm", "2in");
+            testRWProperty(field, "w", "40mm", "3in");
+            testRWProperty(field, "fontColor", "0,0,0", "42,62,4");
+            testRWProperty(field, "fillColor", "255,255,255", "41,61,11");
+            testRWProperty(field, "borderColor", "0,0,0", "241,161,11");
+            // TODO(tsepez): find a way to make this be defined.
+            // testRWProperty(field, "borderWidth", "1", "4");
+            testRWProperty(field, "mandatory", "disabled", "solid");
+            testRWProperty(field, "mandatoryMessage", "", "keep out");
+            testROProperty(field, "dataNode", "[object XFAObject]");
+            testROProperty(field, "length", 2);
+
+            expectError("field.execInitialize('phooey')");
+            expect("field.execInitialize()", undefined);
+
+            expectError("field.execEvent()");
+            expectError("field.execEvent(1, 2)");
+            expect("field.execEvent('validate')", true);
+
+            expectError("field.deleteItem()");
+            expectError("field.deleteItem(1, 2)");
+            expect("field.deleteItem(1)", true);
+            expect("field.deleteItem(137)", true);  // silently ignored?
+
+            expectError("field.getSaveItem()");
+            expectError("field.getSaveItem(1, 2)");
+            expect("field.getSaveItem(0)", "and a one");
+            expect("field.getSaveItem(137)", null);
+
+            expectError("field.getItemState()");
+            expectError("field.getItemState(1, 2)");
+            expect("field.getItemState(0)", false);
+            expect("field.getItemState(1)", false);
+            expect("field.getItemState(137)", false);
+            expect("field.getItemState(-137)", false);
+
+            expectError("field.setItemState()");
+            expectError("field.setItemState(1, 2, 3)");
+            expect("field.setItemState(0, 1)", undefined);
+            expect("field.getItemState(0)", true);
+            expect("field.setItemState(0, 0)", undefined);
+            expect("field.getItemState(0)", false);
+
+          ]]></script>
+        </event>
+      </field>
+    </subform>
+  </subform>
+</template>
+endstream
+endobj
+{{include ../../xfa_locale_6_0.fragment}}
+{{include ../../xfa_postamble_7_0.fragment}}
+{{include ../../xfa_pages_8_0.fragment}}
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/xfa_specific/xfa_field_expected.txt b/testing/resources/javascript/xfa_specific/xfa_field_expected.txt
new file mode 100644
index 0000000..645518a
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/xfa_field_expected.txt
@@ -0,0 +1,47 @@
+Alert: PASS: x = 10mm
+Alert: PASS: x = 11mm
+Alert: PASS: y = 12mm
+Alert: PASS: y = 13mm
+Alert: PASS: h = 10mm
+Alert: PASS: h = 2in
+Alert: PASS: w = 40mm
+Alert: PASS: w = 3in
+Alert: PASS: fontColor = 0,0,0
+Alert: PASS: fontColor = 42,62,4
+Alert: PASS: fillColor = 255,255,255
+Alert: PASS: fillColor = 41,61,11
+Alert: PASS: borderColor = 0,0,0
+Alert: PASS: borderColor = 241,161,11
+Alert: PASS: mandatory = disabled
+Alert: PASS: mandatory = solid
+Alert: PASS: mandatoryMessage = 
+Alert: PASS: mandatoryMessage = keep out
+Alert: PASS: dataNode = [object XFAObject]
+Alert: PASS: dataNode threw Error: Invalid property set operation.
+Alert: PASS: length = 2
+Alert: PASS: length threw Error: Invalid property set operation.
+Alert: PASS: field.execInitialize('phooey') threw XFAObject.execInitialize: Incorrect number of parameters passed to function.
+Alert: PASS: field.execInitialize() = undefined
+Alert: PASS: field.execEvent() threw XFAObject.execEvent: Incorrect number of parameters passed to function.
+Alert: PASS: field.execEvent(1, 2) threw XFAObject.execEvent: Incorrect number of parameters passed to function.
+Alert: PASS: field.execEvent('validate') = true
+Alert: PASS: field.deleteItem() threw XFAObject.deleteItem: Incorrect number of parameters passed to function.
+Alert: PASS: field.deleteItem(1, 2) threw XFAObject.deleteItem: Incorrect number of parameters passed to function.
+Alert: PASS: field.deleteItem(1) = true
+Alert: PASS: field.deleteItem(137) = true
+Alert: PASS: field.getSaveItem() threw XFAObject.getSaveItem: Incorrect number of parameters passed to function.
+Alert: PASS: field.getSaveItem(1, 2) threw XFAObject.getSaveItem: Incorrect number of parameters passed to function.
+Alert: PASS: field.getSaveItem(0) = and a one
+Alert: PASS: field.getSaveItem(137) = null
+Alert: PASS: field.getItemState() threw XFAObject.getItemState: Incorrect number of parameters passed to function.
+Alert: PASS: field.getItemState(1, 2) threw XFAObject.getItemState: Incorrect number of parameters passed to function.
+Alert: PASS: field.getItemState(0) = false
+Alert: PASS: field.getItemState(1) = false
+Alert: PASS: field.getItemState(137) = false
+Alert: PASS: field.getItemState(-137) = false
+Alert: PASS: field.setItemState() threw XFAObject.setItemState: Incorrect number of parameters passed to function.
+Alert: PASS: field.setItemState(1, 2, 3) threw XFAObject.setItemState: Incorrect number of parameters passed to function.
+Alert: PASS: field.setItemState(0, 1) = undefined
+Alert: PASS: field.getItemState(0) = true
+Alert: PASS: field.setItemState(0, 0) = undefined
+Alert: PASS: field.getItemState(0) = false
diff --git a/testing/resources/javascript/xfa_specific/xfa_form.in b/testing/resources/javascript/xfa_specific/xfa_form.in
new file mode 100644
index 0000000..e21688f
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/xfa_form.in
@@ -0,0 +1,61 @@
+{{header}}
+{{include ../../xfa_catalog_1_0.fragment}}
+{{include ../../xfa_object_2_0.fragment}}
+{{include ../../xfa_preamble_3_0.fragment}}
+{{include ../../xfa_config_4_0.fragment}}
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+<form>
+</form>
+<template>
+  <subform layout="tb" name="my_subform">
+    <pageSet id="page" relation="orderedOccurrence">
+      <occur initial="1" max="1" min="1"/>
+      <pageArea id="Page1" name="Page1">
+        <occur max="1" min="1"/>
+        <contentArea h="100mm" w="200mm" x="0.25in" y="0.25in"/>
+      </pageArea>
+      <pageArea id="Page2" name="Page2">
+        <occur max="1" min="1"/>
+        <contentArea h="100mm" w="200mm" x="0.25in" y="0.25in"/>
+      </pageArea>
+    </pageSet>
+    <event activity="docReady" ref="$host">
+      <script contentType="application/x-javascript">
+        {{include ../expect.js}}
+        {{include ../property_test_helpers.js}}
+        var my_form = xfa.resolveNode("#form");
+        testRWProperty(my_form, "checksum", "", "11");
+        expect("typeof my_form.execInitialize", "function");
+        expect("typeof my_form.execCalculate", "function");
+        expect("typeof my_form.execValidate", "function");
+        expectError("my_form.execInitialize('nonesuch')");
+        expect("my_form.execInitialize()", undefined);
+        expectError("my_form.execCalculate('nonesuch')");
+        expect("my_form.execCalculate()", undefined);
+        expectError("my_form.execValidate('nonesuch')");
+        expect("my_form.execValidate()", true);
+        expectError("my_form.formNodes()");
+        expectError("my_form.formNodes(1, 2)");
+        expectError("my_form.formNodes('nonesuch')");
+        expect("my_form.formNodes(my_subform)", "[object XFAObject]");
+        expectError("my_form.remerge(1)");
+        expect("my_form.remerge()", true);
+        expectError("my_form.recalculate()");
+        expectError("my_form.recalculate(1, 2)");
+        expect("my_form.recalculate(0)", undefined);
+      </script>
+    </event>
+  </subform>
+</template>
+endstream
+endobj
+{{include ../../xfa_locale_6_0.fragment}}
+{{include ../../xfa_postamble_7_0.fragment}}
+{{include ../../xfa_pages_8_0.fragment}}
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/xfa_specific/xfa_form_expected.txt b/testing/resources/javascript/xfa_specific/xfa_form_expected.txt
new file mode 100644
index 0000000..191d702
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/xfa_form_expected.txt
@@ -0,0 +1,20 @@
+Alert: PASS: checksum = 
+Alert: PASS: checksum = 11
+Alert: PASS: typeof my_form.execInitialize = function
+Alert: PASS: typeof my_form.execCalculate = function
+Alert: PASS: typeof my_form.execValidate = function
+Alert: PASS: my_form.execInitialize('nonesuch') threw XFAObject.execInitialize: Incorrect number of parameters passed to function.
+Alert: PASS: my_form.execInitialize() = undefined
+Alert: PASS: my_form.execCalculate('nonesuch') threw XFAObject.execCalculate: Incorrect number of parameters passed to function.
+Alert: PASS: my_form.execCalculate() = undefined
+Alert: PASS: my_form.execValidate('nonesuch') threw XFAObject.execValidate: Incorrect number of parameters passed to function.
+Alert: PASS: my_form.execValidate() = true
+Alert: PASS: my_form.formNodes() threw XFAObject.formNodes: Incorrect number of parameters passed to function.
+Alert: PASS: my_form.formNodes(1, 2) threw XFAObject.formNodes: Incorrect number of parameters passed to function.
+Alert: PASS: my_form.formNodes('nonesuch') threw XFAObject.formNodes: Incorrect parameter value.
+Alert: PASS: my_form.formNodes(my_subform) = [object XFAObject]
+Alert: PASS: my_form.remerge(1) threw XFAObject.remerge: Incorrect number of parameters passed to function.
+Alert: FAIL: my_form.remerge() = undefined, expected true 
+Alert: PASS: my_form.recalculate() threw XFAObject.recalculate: Incorrect number of parameters passed to function.
+Alert: PASS: my_form.recalculate(1, 2) threw XFAObject.recalculate: Incorrect number of parameters passed to function.
+Alert: PASS: my_form.recalculate(0) = undefined
diff --git a/testing/resources/javascript/xfa_specific/xfa_globalobject.in b/testing/resources/javascript/xfa_specific/xfa_globalobject.in
new file mode 100644
index 0000000..be1f3be
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/xfa_globalobject.in
@@ -0,0 +1,41 @@
+{{header}}
+{{include ../../xfa_catalog_1_0.fragment}}
+{{include ../../xfa_object_2_0.fragment}}
+{{include ../../xfa_preamble_3_0.fragment}}
+{{include ../../xfa_config_4_0.fragment}}
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+<template>
+  <subform layout="tb" name="my_doc">
+    <pageSet id="page" relation="orderedOccurrence">
+      <occur initial="1" max="1" min="1"/>
+      <pageArea id="Page1" name="Page1">
+        <occur max="1" min="1"/>
+        <contentArea h="100mm" w="200mm" x="0.25in" y="0.25in"/>
+      </pageArea>
+      <pageArea id="Page2" name="Page2">
+        <occur max="1" min="1"/>
+        <contentArea h="100mm" w="200mm" x="0.25in" y="0.25in"/>
+      </pageArea>
+    </pageSet>
+    <event activity="docReady" ref="$host">
+      <script contentType="application/x-javascript">
+        app.alert('We search non-xfa global space on missing prop: ' + (app == xfa.app));
+        app.alert('Global toString says ' + toString());
+        app.alert('toString.apply to bad object is ' + toString.apply(xfa));
+        app.alert('toString.apply to bad non-xfa object is ' + toString.apply(app));
+      </script>
+    </event>
+  </subform>
+</template>
+endstream
+endobj
+{{include ../../xfa_locale_6_0.fragment}}
+{{include ../../xfa_postamble_7_0.fragment}}
+{{include ../../xfa_pages_8_0.fragment}}
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/xfa_specific/xfa_globalobject_expected.txt b/testing/resources/javascript/xfa_specific/xfa_globalobject_expected.txt
new file mode 100644
index 0000000..6384afe
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/xfa_globalobject_expected.txt
@@ -0,0 +1,4 @@
+Alert: We search non-xfa global space on missing prop: true
+Alert: Global toString says [object Root]
+Alert: toString.apply to bad object is [object Root]
+Alert: toString.apply to bad non-xfa object is [object Root]
diff --git a/testing/resources/javascript/xfa_specific/xfa_host_pseudomodel_expected.txt b/testing/resources/javascript/xfa_specific/xfa_host_pseudomodel_expected.txt
index 3835e4a..6c1359d 100644
--- a/testing/resources/javascript/xfa_specific/xfa_host_pseudomodel_expected.txt
+++ b/testing/resources/javascript/xfa_specific/xfa_host_pseudomodel_expected.txt
@@ -52,7 +52,7 @@
 Alert: PASS: xfa.host.pageDown('ignored arg') = undefined
 Alert: PASS: xfa.host.print(1, 2, 3, 4, 5, 6, 7) threw XFAObject.print: Incorrect number of parameters passed to function.
 Alert: PASS: xfa.host.print(1, 2, 3, 4, 5, 6, 7, 8, 9) threw XFAObject.print: Incorrect number of parameters passed to function.
-Doc Print: 1, 1, 1, 2, 4, 8, 16, 32
+Doc Print: 1, 1, 1, 1, 1, 1, 1, 1
 Alert: PASS: xfa.host.print(true, 1, 1, true, true, true, true, true) = undefined
 Alert: PASS: xfa.host.response() threw XFAObject.response: Incorrect number of parameters passed to function.
 Alert: PASS: xfa.host.response(1, 2, 3, 4, 5) threw XFAObject.response: Incorrect number of parameters passed to function.
diff --git a/testing/resources/javascript/xfa_specific/xfa_items.in b/testing/resources/javascript/xfa_specific/xfa_items.in
new file mode 100644
index 0000000..f1ee317
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/xfa_items.in
@@ -0,0 +1,196 @@
+{{header}}
+{{include ../../xfa_catalog_1_0.fragment}}
+{{include ../../xfa_object_2_0.fragment}}
+{{include ../../xfa_preamble_3_0.fragment}}
+{{include ../../xfa_config_4_0.fragment}}
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+<template xmlns="http://www.xfa.org/schema/xfa-template/2.6/">
+  <subform name="form1">
+    <pageSet>
+      <pageArea id="Page1" name="Page1">
+        <contentArea h="10.5in" w="8in" x="0.25in" y="0.25in"/>
+        <medium long="11in" short="8.5in" stock="letter"/>
+      </pageArea>
+    </pageSet>
+    <field h="9.0001mm" name="field1" w="47.625mm" x="6.35mm" y="92.075mm">
+      <ui>
+        <choiceList/>
+      </ui>
+      <items nonesuch="3">
+        <arc name="arc1"></arc>
+        <boolean name="bool0">0</boolean>
+        <boolean name="bool1">1</boolean>
+        <boolean name="boolbad">bad</boolean>
+        <boolean name="booltruenottrue">true</boolean>
+        <date name="date0"></date>
+        <date name="date1">2020-02-02</date>
+        <date name="date2">2039-12-01</date>
+        <date name="datebad">bad</date>
+        <dateTime name="datetime0"></dateTime>
+        <dateTime name="datetime1">2020-02-02T12:34:56</dateTime>
+        <dateTime name="datetime2">2039-12-01T12:34:56</dateTime>
+        <dateTime name="datetimebad">bad</dateTime>
+        <decimal name="decimal0"></decimal>
+        <decimal name="decimal1">42.0000000000000000001</decimal>
+        <decimal name="decimalbad">bad</decimal>
+        <exData name="ex0"></exData>
+        <exData name="ex1"><![CDATA[YZYZYZYZYZYZYZYZYZYZYZYZYZYZ]]></exData>
+        <float name="float0">-12.34</float>
+        <float name="float1">-12.34</float>
+        <float name="floatbad">bad</float>
+        <image name="image0">ABABABABABABABABA</image>
+        <image name="image1"><![CDATA[ABABABABABABABABA]]></image>
+        <integer name="int0"></integer>
+        <integer name="int1">1234</integer>
+        <integer name="intbad">bad</integer>
+        <line name="line0"></line>
+        <rectangle name="rect0"></rectangle>
+        <text name="text0"></text>
+        <text name="text1">Ahoy !!!</text>
+        <time name="time0"></time>
+        <time name="time1">12:34:56</time>
+        <goop name="goop0">Nonsense nodes not allowed here</goop>
+      </items>
+    </field>
+    <event activity="docReady">
+      <script contentType="application/x-javascript"><![CDATA[
+        {{include ../expect.js}}
+        {{include dump_tree.js}}
+
+        itemlist = xfa.resolveNode("form1.field1.#items");
+        dumpTree(itemlist);
+
+        arc1 = itemlist.resolveNode("arc1");
+
+        bool0 = itemlist.resolveNode("bool0");
+        expect("bool0.value", false);
+        bool0.value = 1;
+        expect("bool0.value", true);
+
+        bool1 = itemlist.resolveNode("bool1");
+        expect("bool1.value", true);
+        bool1.value = 0;
+        expect("bool1.value", false);
+
+        boolbad = itemlist.resolveNode("boolbad");
+        expect("boolbad.value", false);
+
+        booltruenottrue = itemlist.resolveNode("booltruenottrue");
+        expect("booltruenottrue.value", false);
+
+        // TODO(tsepez): confirm if this is correct.
+        booltruenottrue.value = true;
+        expect("booltruenottrue.value", false);
+
+        booltruenottrue.value = "zerp";
+        expect("booltruenottrue.value", false);
+        booltruenottrue.value = "1";
+        expect("booltruenottrue.value", true);
+        booltruenottrue.value = "10";
+        expect("booltruenottrue.value", true);
+        booltruenottrue.value = "1zerp";
+        expect("booltruenottrue.value", true);
+
+        // Date is just a node, and allows any text within.
+        date0 = itemlist.resolveNode("date0");
+        expect("date0.value", null);
+
+        date1 = itemlist.resolveNode("date1");
+        expect("date1.value", "2020-02-02");
+
+        date2 = itemlist.resolveNode("date2");
+        expect("date2.value", "2039-12-01");
+
+        datebad = itemlist.resolveNode("datebad");
+        expect("datebad.value", "bad");
+
+        // These are pretty much just nodes, and allow any text within.
+        // Just check that they parsed and that we can retrieve them.
+        datetime0 = itemlist.resolveNode("datetime0");
+        expect("datetime0", "[object XFAObject]");
+
+        datetime1 = itemlist.resolveNode("datetime1");
+        expect("datetime1", "[object XFAObject]");
+
+        datetime2 = itemlist.resolveNode("datetime2");
+        expect("datetime2", "[object XFAObject]");
+
+        datetimebad = itemlist.resolveNode("datetimebad");
+        expect("datetimebad", "[object XFAObject]");
+
+        decimal0 = itemlist.resolveNode("decimal0");
+        expect("decimal0", "[object XFAObject]");
+
+        decimal1 = itemlist.resolveNode("decimal1");
+        expect("decimal1", "[object XFAObject]");
+
+        decimalbad = itemlist.resolveNode("decimalbad");
+        expect("decimalbad", "[object XFAObject]");
+
+        ex0 = itemlist.resolveNode("ex0");
+        expect("ex0", "[object XFAObject]");
+
+        ex1 = itemlist.resolveNode("ex1");
+        expect("ex1", "[object XFAObject]");
+
+        float0 = itemlist.resolveNode("float0");
+        expect("float0", "[object XFAObject]");
+
+        float1 = itemlist.resolveNode("float1");
+        expect("float1", "[object XFAObject]");
+
+        floatbad = itemlist.resolveNode("floatbad");
+        expect("floatbad", "[object XFAObject]");
+
+        image0 = itemlist.resolveNode("image0");
+        expect("image0", "[object XFAObject]");
+
+        image1 = itemlist.resolveNode("image1");
+        expect("image1", "[object XFAObject]");
+
+        int0 = itemlist.resolveNode("int0");
+        expect("int0", "[object XFAObject]");
+
+        int1 = itemlist.resolveNode("int1");
+        expect("int1", "[object XFAObject]");
+
+        intbad = itemlist.resolveNode("intbad");
+        expect("intbad", "[object XFAObject]");
+
+        line0 = itemlist.resolveNode("line0");
+        expect("line0", "[object XFAObject]");
+
+        rect0 = itemlist.resolveNode("rect0");
+        expect("rect0", "[object XFAObject]");
+
+        text0 = itemlist.resolveNode("text0");
+        expect("text0", "[object XFAObject]");
+
+        text1 = itemlist.resolveNode("text1");
+        expect("text1", "[object XFAObject]");
+
+        time0 = itemlist.resolveNode("time0");
+        expect("time0", "[object XFAObject]");
+
+        time1 = itemlist.resolveNode("time1");
+        expect("time1", "[object XFAObject]");
+
+        // The parser is picky and won't let fake nodes in here.
+        goop0 = itemlist.resolveNode("goop0");
+        expect("goop0", null);
+      ]]></script>
+    </event>
+  </subform>
+</template>
+endstream
+endobj
+{{include ../../xfa_locale_6_0.fragment}}
+{{include ../../xfa_postamble_7_0.fragment}}
+{{include ../../xfa_pages_8_0.fragment}}
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/xfa_specific/xfa_items_expected.txt b/testing/resources/javascript/xfa_specific/xfa_items_expected.txt
new file mode 100644
index 0000000..cc0c7c5
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/xfa_items_expected.txt
@@ -0,0 +1,80 @@
+Alert: items
+Alert: | arc
+Alert: | boolean
+Alert: | boolean
+Alert: | boolean
+Alert: | boolean
+Alert: | date
+Alert: | date
+Alert: | | #text
+Alert: | date
+Alert: | | #text
+Alert: | date
+Alert: | | #text
+Alert: | dateTime
+Alert: | dateTime
+Alert: | | #text
+Alert: | dateTime
+Alert: | | #text
+Alert: | dateTime
+Alert: | | #text
+Alert: | decimal
+Alert: | decimal
+Alert: | decimal
+Alert: | exData
+Alert: | exData
+Alert: | float
+Alert: | float
+Alert: | float
+Alert: | image
+Alert: | | #text
+Alert: | image
+Alert: | | #text
+Alert: | integer
+Alert: | integer
+Alert: | integer
+Alert: | line
+Alert: | rectangle
+Alert: | text
+Alert: | text
+Alert: | time
+Alert: | time
+Alert: PASS: bool0.value = false
+Alert: PASS: bool0.value = true
+Alert: PASS: bool1.value = true
+Alert: PASS: bool1.value = false
+Alert: PASS: boolbad.value = false
+Alert: PASS: booltruenottrue.value = false
+Alert: PASS: booltruenottrue.value = false
+Alert: PASS: booltruenottrue.value = false
+Alert: PASS: booltruenottrue.value = true
+Alert: PASS: booltruenottrue.value = true
+Alert: PASS: booltruenottrue.value = true
+Alert: PASS: date0.value = null
+Alert: PASS: date1.value = 2020-02-02
+Alert: PASS: date2.value = 2039-12-01
+Alert: PASS: datebad.value = bad
+Alert: PASS: datetime0 = [object XFAObject]
+Alert: PASS: datetime1 = [object XFAObject]
+Alert: PASS: datetime2 = [object XFAObject]
+Alert: PASS: datetimebad = [object XFAObject]
+Alert: PASS: decimal0 = [object XFAObject]
+Alert: PASS: decimal1 = [object XFAObject]
+Alert: PASS: decimalbad = [object XFAObject]
+Alert: PASS: ex0 = [object XFAObject]
+Alert: PASS: ex1 = [object XFAObject]
+Alert: PASS: float0 = [object XFAObject]
+Alert: PASS: float1 = [object XFAObject]
+Alert: PASS: floatbad = [object XFAObject]
+Alert: PASS: image0 = [object XFAObject]
+Alert: PASS: image1 = [object XFAObject]
+Alert: PASS: int0 = [object XFAObject]
+Alert: PASS: int1 = [object XFAObject]
+Alert: PASS: intbad = [object XFAObject]
+Alert: PASS: line0 = [object XFAObject]
+Alert: PASS: rect0 = [object XFAObject]
+Alert: PASS: text0 = [object XFAObject]
+Alert: PASS: text1 = [object XFAObject]
+Alert: PASS: time0 = [object XFAObject]
+Alert: PASS: time1 = [object XFAObject]
+Alert: PASS: goop0 = null
diff --git a/testing/resources/javascript/xfa_specific/xfa_log_pseudomodel.in b/testing/resources/javascript/xfa_specific/xfa_log_pseudomodel.in
index 2de417e..a3f28fc 100644
--- a/testing/resources/javascript/xfa_specific/xfa_log_pseudomodel.in
+++ b/testing/resources/javascript/xfa_specific/xfa_log_pseudomodel.in
@@ -40,6 +40,7 @@
 endobj
 {{include ../../xfa_locale_6_0.fragment}}
 {{include ../../xfa_postamble_7_0.fragment}}
+{{include ../../xfa_pages_8_0.fragment}}
 {{xref}}
 {{trailer}}
 {{startxref}}
diff --git a/testing/resources/javascript/xfa_specific/xfa_node.in b/testing/resources/javascript/xfa_specific/xfa_node.in
index 7157993..a0e9b25 100644
--- a/testing/resources/javascript/xfa_specific/xfa_node.in
+++ b/testing/resources/javascript/xfa_specific/xfa_node.in
@@ -7,6 +7,7 @@
   {{streamlen}}
 >>
 stream
+<goop viscosity="sludge">Spurious Nonsense</goop>
 <template>
   <subform layout="tb" name="my_doc">
     <pageSet id="page" relation="orderedOccurrence">
@@ -21,9 +22,13 @@
       </pageArea>
     </pageSet>
     <event activity="docReady" ref="$host">
-      <script contentType="application/x-javascript">
+      <script contentType="application/x-javascript"><![CDATA[
         {{include ../expect.js}}
         {{include ../property_test_helpers.js}}
+        {{include dump_tree.js}}
+
+        dumpTree(xfa);
+
         testROProperty(my_doc, "isContainer", true);
         testROProperty(my_doc, "isNull", false);
         testROProperty(my_doc, "model", "[object XFAObject]");
@@ -74,7 +79,35 @@
         // Test free-form attributes outside of the XFA schema.
         expect("my_doc.setAttribute('fake_value', 'fake_attr')", undefined);
         expect("my_doc.getAttribute('fake_attr')", 'fake_value');
-      </script>
+
+        // Test magic "xfa" property bound to all nodes.
+        expect("my_doc.xfa == xfa", true);
+
+        // Test "packet" nodes which are unrecognized tags at XDP level.
+        expect("goop", undefined);
+        var goop = this.resolveNode('#packet');
+        expect("goop.className", "packet");
+        expect("goop.viscosity", undefined);
+        expectError("goop.getAttribute()");
+        expectError("goop.getAttribute(1, 2)");
+        expect("goop.getAttribute('nonesuch')", "");
+        expect("goop.getAttribute('viscosity')", "sludge");
+        expectError("goop.setAttribute()");
+        expectError("goop.setAttribute(1)");
+        expectError("goop.setAttribute(1, 2, 3)");
+
+        // Remember, args to setAttribute() are backwards from what one might
+        // typically expect ...
+        expect("goop.setAttribute(7, 'ph')", undefined);
+        expect("goop.getAttribute('ph')", 7);
+
+        expect("goop.content", "Spurious Nonsense");
+        expect("goop.content = ' for All'", " for All");
+
+        // TODO(tsepez): assigning new content seems to append although it
+        // wasn't included in the return value of the assignment above.
+        expect("goop.content", "Spurious Nonsense for All");
+      ]]></script>
     </event>
   </subform>
 </template>
diff --git a/testing/resources/javascript/xfa_specific/xfa_node_expected.txt b/testing/resources/javascript/xfa_specific/xfa_node_expected.txt
index 68b73a9..8455004 100644
--- a/testing/resources/javascript/xfa_specific/xfa_node_expected.txt
+++ b/testing/resources/javascript/xfa_specific/xfa_node_expected.txt
@@ -1,3 +1,200 @@
+Alert: xfa
+Alert: | config
+Alert: | | agent
+Alert: | | | destination
+Alert: | | | | #text
+Alert: | | | pdf
+Alert: | | | | fontInfo
+Alert: | | present
+Alert: | | | pdf
+Alert: | | | | version
+Alert: | | | | | #text
+Alert: | | | | adobeExtensionLevel
+Alert: | | | | | #text
+Alert: | | | | renderPolicy
+Alert: | | | | | #text
+Alert: | | | | scriptModel
+Alert: | | | | | #text
+Alert: | | | | interactive
+Alert: | | | | | #text
+Alert: | | | xdp
+Alert: | | | | packets
+Alert: | | | | | #text
+Alert: | | | destination
+Alert: | | | | #text
+Alert: | | | script
+Alert: | | | | #text
+Alert: | | acrobat
+Alert: | | | acrobat7
+Alert: | | | | dynamicRender
+Alert: | | | | | #text
+Alert: | | | validate
+Alert: | | | | #text
+Alert: | packet
+Alert: | template
+Alert: | | subform
+Alert: | | | event
+Alert: | | | | script
+Alert: | | | | | #text
+Alert: | localeSet
+Alert: | | locale
+Alert: | | | calendarSymbols
+Alert: | | | | monthNames
+Alert: | | | | | month
+Alert: | | | | | | #text
+Alert: | | | | | month
+Alert: | | | | | | #text
+Alert: | | | | | month
+Alert: | | | | | | #text
+Alert: | | | | | month
+Alert: | | | | | | #text
+Alert: | | | | | month
+Alert: | | | | | | #text
+Alert: | | | | | month
+Alert: | | | | | | #text
+Alert: | | | | | month
+Alert: | | | | | | #text
+Alert: | | | | | month
+Alert: | | | | | | #text
+Alert: | | | | | month
+Alert: | | | | | | #text
+Alert: | | | | | month
+Alert: | | | | | | #text
+Alert: | | | | | month
+Alert: | | | | | | #text
+Alert: | | | | | month
+Alert: | | | | | | #text
+Alert: | | | | monthNames
+Alert: | | | | | month
+Alert: | | | | | | #text
+Alert: | | | | | month
+Alert: | | | | | | #text
+Alert: | | | | | month
+Alert: | | | | | | #text
+Alert: | | | | | month
+Alert: | | | | | | #text
+Alert: | | | | | month
+Alert: | | | | | | #text
+Alert: | | | | | month
+Alert: | | | | | | #text
+Alert: | | | | | month
+Alert: | | | | | | #text
+Alert: | | | | | month
+Alert: | | | | | | #text
+Alert: | | | | | month
+Alert: | | | | | | #text
+Alert: | | | | | month
+Alert: | | | | | | #text
+Alert: | | | | | month
+Alert: | | | | | | #text
+Alert: | | | | | month
+Alert: | | | | | | #text
+Alert: | | | | dayNames
+Alert: | | | | | day
+Alert: | | | | | | #text
+Alert: | | | | | day
+Alert: | | | | | | #text
+Alert: | | | | | day
+Alert: | | | | | | #text
+Alert: | | | | | day
+Alert: | | | | | | #text
+Alert: | | | | | day
+Alert: | | | | | | #text
+Alert: | | | | | day
+Alert: | | | | | | #text
+Alert: | | | | | day
+Alert: | | | | | | #text
+Alert: | | | | dayNames
+Alert: | | | | | day
+Alert: | | | | | | #text
+Alert: | | | | | day
+Alert: | | | | | | #text
+Alert: | | | | | day
+Alert: | | | | | | #text
+Alert: | | | | | day
+Alert: | | | | | | #text
+Alert: | | | | | day
+Alert: | | | | | | #text
+Alert: | | | | | day
+Alert: | | | | | | #text
+Alert: | | | | | day
+Alert: | | | | | | #text
+Alert: | | | | meridiemNames
+Alert: | | | | | meridiem
+Alert: | | | | | | #text
+Alert: | | | | | meridiem
+Alert: | | | | | | #text
+Alert: | | | | eraNames
+Alert: | | | | | era
+Alert: | | | | | | #text
+Alert: | | | | | era
+Alert: | | | | | | #text
+Alert: | | | datePatterns
+Alert: | | | | datePattern
+Alert: | | | | | #text
+Alert: | | | | datePattern
+Alert: | | | | | #text
+Alert: | | | | datePattern
+Alert: | | | | | #text
+Alert: | | | | datePattern
+Alert: | | | | | #text
+Alert: | | | timePatterns
+Alert: | | | | timePattern
+Alert: | | | | | #text
+Alert: | | | | timePattern
+Alert: | | | | | #text
+Alert: | | | | timePattern
+Alert: | | | | | #text
+Alert: | | | | timePattern
+Alert: | | | | | #text
+Alert: | | | dateTimeSymbols
+Alert: | | | | #text
+Alert: | | | numberPatterns
+Alert: | | | | numberPattern
+Alert: | | | | | #text
+Alert: | | | | numberPattern
+Alert: | | | | | #text
+Alert: | | | | numberPattern
+Alert: | | | | | #text
+Alert: | | | numberSymbols
+Alert: | | | | numberSymbol
+Alert: | | | | | #text
+Alert: | | | | numberSymbol
+Alert: | | | | | #text
+Alert: | | | | numberSymbol
+Alert: | | | | | #text
+Alert: | | | | numberSymbol
+Alert: | | | | | #text
+Alert: | | | | numberSymbol
+Alert: | | | | | #text
+Alert: | | | currencySymbols
+Alert: | | | | currencySymbol
+Alert: | | | | | #text
+Alert: | | | | currencySymbol
+Alert: | | | | | #text
+Alert: | | | | currencySymbol
+Alert: | | | | | #text
+Alert: | | | typefaces
+Alert: | | | | typeface
+Alert: | | | | typeface
+Alert: | | | | typeface
+Alert: | | | | typeface
+Alert: | | | | typeface
+Alert: | | | | typeface
+Alert: | | | | typeface
+Alert: | | | | typeface
+Alert: | | | | typeface
+Alert: | | | | typeface
+Alert: | | | | typeface
+Alert: | | | | typeface
+Alert: | dataModel
+Alert: | | dataGroup
+Alert: | | | dataGroup
+Alert: | form
+Alert: | | subform
+Alert: | | | event
+Alert: | | | | script
+Alert: | | | | | #text
 Alert: PASS: isContainer = true
 Alert: PASS: isContainer threw Error: Invalid property set operation.
 Alert: PASS: isNull = false
@@ -49,3 +246,19 @@
 Alert: PASS: my_doc.getAttribute('ns') = something
 Alert: PASS: my_doc.setAttribute('fake_value', 'fake_attr') = undefined
 Alert: PASS: my_doc.getAttribute('fake_attr') = fake_value
+Alert: PASS: my_doc.xfa == xfa = true
+Alert: PASS: goop = undefined
+Alert: PASS: goop.className = packet
+Alert: PASS: goop.viscosity = undefined
+Alert: PASS: goop.getAttribute() threw XFAObject.getAttribute: Incorrect number of parameters passed to function.
+Alert: PASS: goop.getAttribute(1, 2) threw XFAObject.getAttribute: Incorrect number of parameters passed to function.
+Alert: PASS: goop.getAttribute('nonesuch') = 
+Alert: PASS: goop.getAttribute('viscosity') = sludge
+Alert: PASS: goop.setAttribute() threw XFAObject.setAttribute: Incorrect number of parameters passed to function.
+Alert: PASS: goop.setAttribute(1) threw XFAObject.setAttribute: Incorrect number of parameters passed to function.
+Alert: PASS: goop.setAttribute(1, 2, 3) threw XFAObject.setAttribute: Incorrect number of parameters passed to function.
+Alert: PASS: goop.setAttribute(7, 'ph') = null
+Alert: PASS: goop.getAttribute('ph') = 7
+Alert: PASS: goop.content = Spurious Nonsense
+Alert: PASS: goop.content = ' for All' =  for All
+Alert: PASS: goop.content = Spurious Nonsense for All
diff --git a/testing/resources/javascript/xfa_specific/xfa_template.in b/testing/resources/javascript/xfa_specific/xfa_template.in
new file mode 100644
index 0000000..60ad46d
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/xfa_template.in
@@ -0,0 +1,60 @@
+{{header}}
+{{include ../../xfa_catalog_1_0.fragment}}
+{{include ../../xfa_object_2_0.fragment}}
+{{include ../../xfa_preamble_3_0.fragment}}
+{{include ../../xfa_config_4_0.fragment}}
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+<template>
+  <subform layout="tb" name="my_doc">
+    <pageSet id="page" relation="orderedOccurrence">
+      <occur initial="1" max="1" min="1"/>
+      <pageArea id="Page1" name="Page1">
+        <occur max="1" min="1"/>
+        <contentArea h="100mm" w="200mm" x="0.25in" y="0.25in"/>
+      </pageArea>
+      <pageArea id="Page2" name="Page2">
+        <occur max="1" min="1"/>
+        <contentArea h="100mm" w="200mm" x="0.25in" y="0.25in"/>
+      </pageArea>
+    </pageSet>
+    <event activity="docReady" ref="$host">
+      <script contentType="application/x-javascript"><![CDATA[
+        {{include ../expect.js}}
+        template0 = xfa.resolveNode("#template");
+        expect("template0.className", "template");
+
+        expectError("template0.execCalculate(1)");
+        expect("template0.execCalculate()", false);
+
+        expectError("template0.execInitialize(1)", false);
+        expect("template0.execInitialize()", false);
+
+        expectError("template0.execValidate(1)", false);
+        expect("template0.execValidate()", false);
+
+        expectError("template0.formNodes()", undefined);
+        expectError("template0.formNodes(1, 2)", undefined);
+        expect("template0.formNodes(true)", true);
+
+        expectError("template0.recalculate()", undefined);
+        expectError("template0.recalculate(1, 2)", undefined);
+        expect("template0.recalculate(true)", true);
+
+        expectError("template0.remerge(1)", undefined);
+        expect("template0.remerge()", undefined);
+      ]]></script>
+    </event>
+  </subform>
+</template>
+endstream
+endobj
+{{include ../../xfa_locale_6_0.fragment}}
+{{include ../../xfa_postamble_7_0.fragment}}
+{{include ../../xfa_pages_8_0.fragment}}
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/xfa_specific/xfa_template_expected.txt b/testing/resources/javascript/xfa_specific/xfa_template_expected.txt
new file mode 100644
index 0000000..9bb1ffd
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/xfa_template_expected.txt
@@ -0,0 +1,15 @@
+Alert: PASS: template0.className = template
+Alert: PASS: template0.execCalculate(1) threw XFAObject.execCalculate: Incorrect number of parameters passed to function.
+Alert: PASS: template0.execCalculate() = false
+Alert: PASS: template0.execInitialize(1) threw XFAObject.execInitialize: Incorrect number of parameters passed to function.
+Alert: PASS: template0.execInitialize() = false
+Alert: PASS: template0.execValidate(1) threw XFAObject.execValidate: Incorrect number of parameters passed to function.
+Alert: PASS: template0.execValidate() = false
+Alert: PASS: template0.formNodes() threw XFAObject.formNodes: Incorrect number of parameters passed to function.
+Alert: PASS: template0.formNodes(1, 2) threw XFAObject.formNodes: Incorrect number of parameters passed to function.
+Alert: PASS: template0.formNodes(true) = true
+Alert: PASS: template0.recalculate() threw XFAObject.recalculate: Incorrect number of parameters passed to function.
+Alert: PASS: template0.recalculate(1, 2) threw XFAObject.recalculate: Incorrect number of parameters passed to function.
+Alert: PASS: template0.recalculate(true) = true
+Alert: PASS: template0.remerge(1) threw XFAObject.remerge: Incorrect number of parameters passed to function.
+Alert: PASS: template0.remerge() = undefined
diff --git a/testing/resources/javascript/xfa_specific/xfa_variables.in b/testing/resources/javascript/xfa_specific/xfa_variables.in
new file mode 100644
index 0000000..6bfdb97
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/xfa_variables.in
@@ -0,0 +1,76 @@
+{{header}}
+{{include ../../xfa_catalog_1_0.fragment}}
+{{include ../../xfa_object_2_0.fragment}}
+{{include ../../xfa_preamble_3_0.fragment}}
+{{include ../../xfa_config_4_0.fragment}}
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+<template>
+  <subform layout="tb" name="my_doc">
+    <variables>
+      <text name="xx01">123</text>
+      <text name="xx02">456</text>
+      <integer name="xx03">123</integer>
+      <integer name="xx04">456</integer>
+    </variables>
+    <pageSet id="page" relation="orderedOccurrence">
+      <occur initial="1" max="1" min="1"/>
+      <pageArea id="Page1" name="Page1">
+        <occur max="1" min="1"/>
+        <contentArea h="100mm" w="200mm" x="0.25in" y="0.25in"/>
+      </pageArea>
+      <pageArea id="Page2" name="Page2">
+        <occur max="1" min="1"/>
+        <contentArea h="100mm" w="200mm" x="0.25in" y="0.25in"/>
+      </pageArea>
+    </pageSet>
+    <event activity="docReady" ref="$host">
+      <script name="my_script" contentType="application/x-javascript"><![CDATA[
+        {{include ../expect.js}}
+        try {
+          var script1 = xfa.resolveNode('template..my_script');
+          var script2 = xfa.resolveNode('template..their_script');
+          var script3 = xfa.resolveNode('template..other_script');
+          app.alert('First, poke at a script node itsef');
+          expect('script1.stateless', '0');
+          expectError('script1.stateless = 42');
+          app.alert('We search variables context ' + (xx01.value + xx02.value));
+          app.alert('We search variables context ' + (xx03.value + xx04.value));
+          app.alert('We resolve off of script1 ' + (script1.xx01.value + script1.xx02.value));
+          app.alert('We resolve off of script2 ' + (script2.xx01.value + script2.xx02.value));
+          app.alert('We resolve off of script3 ' + (script3.xx01.value + script3.xx02.value));
+          app.alert('We resolve off of script1 ' + script1.nonesuch);
+          app.alert('We resolve off of script2 ' + script2.nonesuch);
+          app.alert('We resolve off of script3 ' + script3.nonesuch);
+        } catch (e) {
+          app.alert('Error: ' + e);
+        }
+      ]]></script>
+    </event>
+  </subform>
+  <subform layout="tb" name="their_doc">
+    <variables>
+      <text name="xx01">78</text>
+      <text name="xx02">90</text>
+      <integer name="xx03">78</integer>
+      <integer name="xx04">90</integer>
+      <script name="other_script">
+        var xx01 = "chips";
+      </script>
+    </variables>
+    <script name="their_script">
+      var xx01 = "clams";
+    </script>
+  </subform>
+</template>
+endstream
+endobj
+{{include ../../xfa_locale_6_0.fragment}}
+{{include ../../xfa_postamble_7_0.fragment}}
+{{include ../../xfa_pages_8_0.fragment}}
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/xfa_specific/xfa_variables_expected.txt b/testing/resources/javascript/xfa_specific/xfa_variables_expected.txt
new file mode 100644
index 0000000..75a457f
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/xfa_variables_expected.txt
@@ -0,0 +1,11 @@
+Alert: First, poke at a script node itsef
+Alert: PASS: script1.stateless = 0
+Alert: PASS: script1.stateless = 42 threw Error: Invalid property set operation.
+Alert: We search variables context 123456
+Alert: We search variables context 579
+Alert: We resolve off of script1 123456
+Alert: We resolve off of script2 7890
+Alert: We resolve off of script3 7890
+Alert: We resolve off of script1 undefined
+Alert: We resolve off of script2 undefined
+Alert: We resolve off of script3 undefined
diff --git a/testing/resources/jpx_lzw.in b/testing/resources/jpx_lzw.in
new file mode 100644
index 0000000..46914c1
--- /dev/null
+++ b/testing/resources/jpx_lzw.in
@@ -0,0 +1,55 @@
+{{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 612 792]
+  /Resources <<
+    /XObject <<
+      /Im0 5 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+612 0 0 792 0 0 cm
+/Im0 Do
+Q
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /Filter [/ASCIIHexDecode /LZWDecode /JPXDecode]
+  /Width 612
+  /Height 792
+  {{streamlen}}
+>>
+stream
+80002040c351404020068290e0a8100028663a1e4e06a380c8410d004522d0d16c68d10d0b1a4d06
+439408061881008c8000181c0f180003cc66f361c80330084358d1a31bfc9eff288005f189549a51
+30a24ae5947a44b00e0100d3ea3507f948000c86d400a040200002ff2e0002640201209050b35a2c
+f69b4bfe5625af10ce465309d0ca6410188f220279c0ca6e251408a47101d8ca72399a4de6e100c8
+5c33170c1fe9000432303faf3fd26cf5a14022502a2bdfe7f369a0b480980c12097d1801be801c05
+0005c57bf818daa6ee5fed9801
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/jpx_lzw.pdf b/testing/resources/jpx_lzw.pdf
new file mode 100644
index 0000000..8735018
--- /dev/null
+++ b/testing/resources/jpx_lzw.pdf
@@ -0,0 +1,67 @@
+%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 612 792]
+  /Resources <<
+    /XObject <<
+      /Im0 5 0 R
+    >>
+  >>
+>>
+endobj
+4 0 obj <<
+  /Length 31
+>>
+stream
+q
+612 0 0 792 0 0 cm
+/Im0 Do
+Q
+endstream
+endobj
+5 0 obj <<
+  /Type /XObject
+  /Subtype /Image
+  /Filter [/ASCIIHexDecode /LZWDecode /JPXDecode]
+  /Width 612
+  /Height 792
+  /Length 432
+>>
+stream
+80002040c351404020068290e0a8100028663a1e4e06a380c8410d004522d0d16c68d10d0b1a4d06
+439408061881008c8000181c0f180003cc66f361c80330084358d1a31bfc9eff288005f189549a51
+30a24ae5947a44b00e0100d3ea3507f948000c86d400a040200002ff2e0002640201209050b35a2c
+f69b4bfe5625af10ce465309d0ca6410188f220279c0ca6e251408a47101d8ca72399a4de6e100c8
+5c33170c1fe9000432303faf3fd26cf5a14022502a2bdfe7f369a0b480980c12097d1801be801c05
+0005c57bf818daa6ee5fed9801
+endstream
+endobj
+xref
+0 6
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000131 00000 n 
+0000000287 00000 n 
+0000000369 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 6
+>>
+startxref
+965
+%%EOF
diff --git a/testing/resources/js.pdf b/testing/resources/js.pdf
index 07e9b75..8d64866 100644
--- a/testing/resources/js.pdf
+++ b/testing/resources/js.pdf
@@ -22,7 +22,6 @@
 4 0 obj <<
   /Names [
     (normal) 5 0 R
-    (encoded_subtype) 6 0 R
     (no_type) 7 0 R
     (wrongtype) 8 0 R
     (wrongsubtype) 9 0 R
@@ -36,12 +35,6 @@
   /JS 11 0 R
 >>
 endobj
-6 0 obj <<
-  /Type /Action
-  /S /J#61v#61Script
-  /JS 11 0 R
->>
-endobj
 7 0 obj <<
   /S /JavaScript
   /JS 12 0 R
diff --git a/testing/resources/line_annot.in b/testing/resources/line_annot.in
new file mode 100644
index 0000000..0778169
--- /dev/null
+++ b/testing/resources/line_annot.in
@@ -0,0 +1,50 @@
+{{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
+  /MediaBox [0 0 612 792]
+  /Annots [
+    4 0 R 5 0 R
+  ]
+  /Tabs /R
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Annot
+  /Subtype /Line
+  /NM (Line-1)
+  /F 4
+  /L [159 296 472 243.42]
+  /P 3 0 R
+  /C [1 0.90196 0]
+  /Rect [293 530 349 542]
+  /Border [0.25 0.5 2]
+>>
+endobj
+{{object 5 0}} <<
+  /Type /Annot
+  /Subtype /Line
+  /NM (Line-2)
+  /F 4
+  /L [159 296 472]
+  /P 3 0 R
+  /C [1 0.90196 0]
+  /Rect [293 530 349 542]
+  /Border [0.25 0.5]
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/line_annot.pdf b/testing/resources/line_annot.pdf
new file mode 100644
index 0000000..7a7fee3
--- /dev/null
+++ b/testing/resources/line_annot.pdf
@@ -0,0 +1,62 @@
+%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
+  /MediaBox [0 0 612 792]
+  /Annots [
+    4 0 R 5 0 R
+  ]
+  /Tabs /R
+>>
+endobj
+4 0 obj <<
+  /Type /Annot
+  /Subtype /Line
+  /NM (Line-1)
+  /F 4
+  /L [159 296 472 243.42]
+  /P 3 0 R
+  /C [1 0.90196 0]
+  /Rect [293 530 349 542]
+  /Border [0.25 0.5 2]
+>>
+endobj
+5 0 obj <<
+  /Type /Annot
+  /Subtype /Line
+  /NM (Line-2)
+  /F 4
+  /L [159 296 472]
+  /P 3 0 R
+  /C [1 0.90196 0]
+  /Rect [293 530 349 542]
+  /Border [0.25 0.5]
+>>
+endobj
+xref
+0 6
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000131 00000 n 
+0000000251 00000 n 
+0000000431 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 6
+>>
+startxref
+602
+%%EOF
diff --git a/testing/resources/link_annots.in b/testing/resources/link_annots.in
deleted file mode 100644
index 076069c..0000000
--- a/testing/resources/link_annots.in
+++ /dev/null
@@ -1,333 +0,0 @@
-{{header}}
-{{object 1 0}} <<
-  /Type /Catalog
-  /Pages 2 0 R
->>
-endobj
-{{object 2 0}} <<
-  /Type /Pages
-  /Count 2
-  /Kids [3 0 R 4 0 R]
-  /MediaBox [0 0 612 792]
-  /CropBox [0 0 612 792]
-  /Resources <<
-    /Font <<
-      /F1 7 0 R
-      /F2 8 0 R
-    >>
-    /ProcSet [/PDF /Text /ImageC]
-    /ExtGState <<
-      /GS0 23 0 R
-    >>
-  >>
->>
-endobj
-{{object 3 0}} <<
-  /Type /Page
-  /Parent 2 0 R
-  /Contents 5 0 R
-  /Annots [15 0 R 16 0 R 17 0 R 18 0 R 19 0 R 20 0 R 21 0 R 22 0 R]
->>
-endobj
-{{object 4 0}} <<
-  /Type /Page
-  /Parent 2 0 R
-  /Contents 6 0 R
-  /Annots [15 0 R 16 0 R]
->>
-endobj
-{{object 5 0}} <<
-  {{streamlen}}
->>
-stream
-BT
-70 700 Td
-/F1 18 Tf
-(Link Annotations - Page 1) Tj
-0 -65 Td
-/F2 14 Tf
-(1. Link with destination to first page) Tj
-10 -20 Td
-/F2 14 Tf
-(2. Link with destination to second page) Tj
--12 -84 Td
-/F2 10 Tf
-(PDF Reference, Version 1.7, Section 8.4.5 defines Annotations) Tj
-2 -53 Td
-(3.  An example of Highlight with text notes) Tj
-0 -18 Td
-(https://pdfium.googlesource.com/pdfium is link in plain text, not link annotation. These are referred to) Tj
-0 -17 Td
-(as WebLinks in PDFium.)Tj
-ET
-endstream
-endobj
-{{object 6 0}} <<
-  {{streamlen}}
->>
-stream
-BT
-70 700 Td
-/F1 18 Tf
-(Link Annotations - Page 2) Tj
-0 -65 Td
-/F2 14 Tf
-(1. Link with destination to first page) Tj
-10 -20 Td
-/F2 14 Tf
-(2. Link with destination to second page) Tj
-ET
-endstream
-endobj
-{{object 7 0}} <<
-  /Type /Font
-  /Subtype /Type1
-  /BaseFont /Times-Roman
->>
-endobj
-{{object 8 0}} <<
-  /Type /Font
-  /Subtype /Type1
-  /BaseFont /Helvetica
->>
-endobj
-{{object 9 0}} <<
-  /Type /XObject
-  /Subtype /Form
-  /FormType 1
-  {{streamlen}}
-  /BBox [293 530 349 542]
-  /Resources <<
-    /XObject <<
-      /Form0 10 0 R
-    >>
-    /ExtGState <<
-      /GS0 24 0 R
-    >>
-  >>
->>
-stream
-/GS0 gs
-/Form0 Do
-endstream
-endobj
-{{object 10 0}} <<
-  /Type /XObject
-  /Subtype /Form
-  /FormType 1
-  /Group <<
-    /S /Transparency
-  >>
-  {{streamlen}}
-  /BBox [293 530 349 542]
->>
-stream
-1.0 1.0 0.0 rg
-293 530 m
-349 530 l
-349 542 l
-293 542 l
-h f
-endstream
-endobj
-{{object 11 0}} <<
-  /Type /XObject
-  /Subtype /Form
-  /FormType 1
-  {{streamlen}}
-  /BBox [83 440 178 453]
-  /Resources <<
-    /XObject <<
-      /Form0 12 0 R
-    >>
-    /ExtGState <<
-      /GS0 24 0 R
-    >>
-  >>
->>
-stream
-/GS0 gs
-/Form0 Do
-endstream
-endobj
-{{object 12 0}} <<
-  /Type /XObject
-  /Subtype /Form
-  /FormType 1
-  /Group <<
-    /S /Transparency
-  >>
-  {{streamlen}}
-  /BBox [83 440 178 453]
->>
-stream
-0.0 1.0 1.0 rg
-83 440 m
-178 440 l
-178 453 l
-83 453 l
-h f
-endstream
-endobj
-{{object 13 0}} <<
-  /Type /XObject
-  /Subtype /Form
-  /FormType 1
-  {{streamlen}}
-  /BBox [149 476 191 487]
-  /Resources <<
-    /XObject <<
-      /Form0 14 0 R
-    >>
-    /ExtGState <<
-      /GS0 24 0 R
-    >>
-  >>
->>
-stream
-/GS0 gs
-/Form0 Do
-endstream
-endobj
-{{object 14 0}} <<
-  /Type /XObject
-  /Subtype /Form
-  /FormType 1
-  /Group <<
-    /S /Transparency
-  >>
-  {{streamlen}}
-  /BBox [149 476 191 487]
->>
-stream
-0.0 1.0 0.0 rg
-149 476 m
-191 476 l
-191 487 l
-149 487 l
-h f
-endstream
-endobj
-{{object 15 0}} <<
-  /Type /Annot
-  /Subtype /Link
-  /BS <<
-    /W 0
-  >>
-  /Rect [69 633 542 653]
-  /Dest [3 0 R /XYZ 200 725 0]
-  /F 4
->>
-endobj
-{{object 16 0}} <<
-  /Type /Annot
-  /Subtype /Link
-  /BS <<
-    /W 0
-  >>
-  /Rect [80 613 542 633]
-  /Dest [4 0 R /XYZ 200 725 0]
-  /F 4
->>
-endobj
-{{object 17 0}} <<
-  /Type /Annot
-  /Subtype /Link
-  /BS <<
-    /W 0
-  >>
-  /Rect [66 529 196 544]
-  /A <<
-    /Type /Action
-    /URI (https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/pdf_reference_1-7.pdf)
-    /S /URI
-  >>
-  /F 4
->>
-endobj
-{{object 18 0}} <<
-  /Type /Annot
-  /Subtype /Link
-  /BS <<
-    /W 0
-  >>
-  /Rect [83 440 178 453]
-  /QuadPoints [83 453 178 453 83 440 178 440]
-  /A <<
-    /Type /Action
-    /URI (https://cs.chromium.org/chromium/src/third_party/pdfium/public/fpdf_text.h)
-    /S /URI
-  >>
-  /F 4
->>
-endobj
-{{object 19 0}} <<
-  /Type /Annot
-  /Subtype /Highlight
-  /AP <<
-    /N 9 0 R
-  >>
-  /NM (Highlight-1)
-  /F 4
-  /QuadPoints [293 542 349 542 293 530 349 530]
-  /P 3 0 R
-  /C [1 0.90196 0]
-  /Rect [293 530 349 542]
->>
-endobj
-{{object 20 0}} <<
-  /Type /Annot
-  /Subtype /Highlight
-  /AP <<
-    /N 11 0 R
-  >>
-  /NM (Highlight-2)
-  /F 4
-  /QuadPoints [83 453 178 453 83 440 178 440]
-  /P 3 0 R
-  /C [0.26667 0.78431 0.96078]
-  /Rect [83 440 178 453]
->>
-endobj
-{{object 21 0}} <<
-  /Type /Annot
-  /Subtype /Popup
-  /Parent 22 0 R
-  /Rect [191 377 443 488]
->>
-endobj
-{{object 22 0}} <<
-  /Type /Annot
-  /Subtype /Highlight
-  /Popup 21 0 R
-  /AP <<
-    /N 13 0 R
-  >>
-  /NM (Highlight-With-Popup-1)
-  /Contents (Text Note)
-  /QuadPoints [149 487 191 487 149 476 191 476]
-  /P 3 0 R
-  /C [0.14902 0.90196 0]
-  /Rect [149 476 191 487]
-  /F 4
->>
-endobj
-{{object 23 0}} <<
-  /ca 1
-  /Type /ExtGState
-  /CA 1
-  /BM /Normal
->>
-endobj
-{{object 24 0}} <<
-  /ca 1
-  /Type /ExtGState
-  /CA 1
-  /AIS false
-  /BM /Multiply
->>
-endobj
-{{xref}}
-{{trailer}}
-{{startxref}}
-%%EOF
diff --git a/testing/resources/link_annots.pdf b/testing/resources/link_annots.pdf
deleted file mode 100644
index b964bf5..0000000
--- a/testing/resources/link_annots.pdf
+++ /dev/null
@@ -1,364 +0,0 @@
-%PDF-1.7
-% ò¤ô
-1 0 obj <<
-  /Type /Catalog
-  /Pages 2 0 R
->>
-endobj
-2 0 obj <<
-  /Type /Pages
-  /Count 2
-  /Kids [3 0 R 4 0 R]
-  /MediaBox [0 0 612 792]
-  /CropBox [0 0 612 792]
-  /Resources <<
-    /Font <<
-      /F1 7 0 R
-      /F2 8 0 R
-    >>
-    /ProcSet [/PDF /Text /ImageC]
-    /ExtGState <<
-      /GS0 23 0 R
-    >>
-  >>
->>
-endobj
-3 0 obj <<
-  /Type /Page
-  /Parent 2 0 R
-  /Contents 5 0 R
-  /Annots [15 0 R 16 0 R 17 0 R 18 0 R 19 0 R 20 0 R 21 0 R 22 0 R]
->>
-endobj
-4 0 obj <<
-  /Type /Page
-  /Parent 2 0 R
-  /Contents 6 0 R
-  /Annots [15 0 R 16 0 R]
->>
-endobj
-5 0 obj <<
-  /Length 486
->>
-stream
-BT
-70 700 Td
-/F1 18 Tf
-(Link Annotations - Page 1) Tj
-0 -65 Td
-/F2 14 Tf
-(1. Link with destination to first page) Tj
-10 -20 Td
-/F2 14 Tf
-(2. Link with destination to second page) Tj
--12 -84 Td
-/F2 10 Tf
-(PDF Reference, Version 1.7, Section 8.4.5 defines Annotations) Tj
-2 -53 Td
-(3.  An example of Highlight with text notes) Tj
-0 -18 Td
-(https://pdfium.googlesource.com/pdfium is link in plain text, not link annotation. These are referred to) Tj
-0 -17 Td
-(as WebLinks in PDFium.)Tj
-ET
-endstream
-endobj
-6 0 obj <<
-  /Length 185
->>
-stream
-BT
-70 700 Td
-/F1 18 Tf
-(Link Annotations - Page 2) Tj
-0 -65 Td
-/F2 14 Tf
-(1. Link with destination to first page) Tj
-10 -20 Td
-/F2 14 Tf
-(2. Link with destination to second page) Tj
-ET
-endstream
-endobj
-7 0 obj <<
-  /Type /Font
-  /Subtype /Type1
-  /BaseFont /Times-Roman
->>
-endobj
-8 0 obj <<
-  /Type /Font
-  /Subtype /Type1
-  /BaseFont /Helvetica
->>
-endobj
-9 0 obj <<
-  /Type /XObject
-  /Subtype /Form
-  /FormType 1
-  /Length 18
-  /BBox [293 530 349 542]
-  /Resources <<
-    /XObject <<
-      /Form0 10 0 R
-    >>
-    /ExtGState <<
-      /GS0 24 0 R
-    >>
-  >>
->>
-stream
-/GS0 gs
-/Form0 Do
-endstream
-endobj
-10 0 obj <<
-  /Type /XObject
-  /Subtype /Form
-  /FormType 1
-  /Group <<
-    /S /Transparency
-  >>
-  /Length 59
-  /BBox [293 530 349 542]
->>
-stream
-1.0 1.0 0.0 rg
-293 530 m
-349 530 l
-349 542 l
-293 542 l
-h f
-endstream
-endobj
-11 0 obj <<
-  /Type /XObject
-  /Subtype /Form
-  /FormType 1
-  /Length 18
-  /BBox [83 440 178 453]
-  /Resources <<
-    /XObject <<
-      /Form0 12 0 R
-    >>
-    /ExtGState <<
-      /GS0 24 0 R
-    >>
-  >>
->>
-stream
-/GS0 gs
-/Form0 Do
-endstream
-endobj
-12 0 obj <<
-  /Type /XObject
-  /Subtype /Form
-  /FormType 1
-  /Group <<
-    /S /Transparency
-  >>
-  /Length 57
-  /BBox [83 440 178 453]
->>
-stream
-0.0 1.0 1.0 rg
-83 440 m
-178 440 l
-178 453 l
-83 453 l
-h f
-endstream
-endobj
-13 0 obj <<
-  /Type /XObject
-  /Subtype /Form
-  /FormType 1
-  /Length 18
-  /BBox [149 476 191 487]
-  /Resources <<
-    /XObject <<
-      /Form0 14 0 R
-    >>
-    /ExtGState <<
-      /GS0 24 0 R
-    >>
-  >>
->>
-stream
-/GS0 gs
-/Form0 Do
-endstream
-endobj
-14 0 obj <<
-  /Type /XObject
-  /Subtype /Form
-  /FormType 1
-  /Group <<
-    /S /Transparency
-  >>
-  /Length 59
-  /BBox [149 476 191 487]
->>
-stream
-0.0 1.0 0.0 rg
-149 476 m
-191 476 l
-191 487 l
-149 487 l
-h f
-endstream
-endobj
-15 0 obj <<
-  /Type /Annot
-  /Subtype /Link
-  /BS <<
-    /W 0
-  >>
-  /Rect [69 633 542 653]
-  /Dest [3 0 R /XYZ 200 725 0]
-  /F 4
->>
-endobj
-16 0 obj <<
-  /Type /Annot
-  /Subtype /Link
-  /BS <<
-    /W 0
-  >>
-  /Rect [80 613 542 633]
-  /Dest [4 0 R /XYZ 200 725 0]
-  /F 4
->>
-endobj
-17 0 obj <<
-  /Type /Annot
-  /Subtype /Link
-  /BS <<
-    /W 0
-  >>
-  /Rect [66 529 196 544]
-  /A <<
-    /Type /Action
-    /URI (https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/pdf_reference_1-7.pdf)
-    /S /URI
-  >>
-  /F 4
->>
-endobj
-18 0 obj <<
-  /Type /Annot
-  /Subtype /Link
-  /BS <<
-    /W 0
-  >>
-  /Rect [83 440 178 453]
-  /QuadPoints [83 453 178 453 83 440 178 440]
-  /A <<
-    /Type /Action
-    /URI (https://cs.chromium.org/chromium/src/third_party/pdfium/public/fpdf_text.h)
-    /S /URI
-  >>
-  /F 4
->>
-endobj
-19 0 obj <<
-  /Type /Annot
-  /Subtype /Highlight
-  /AP <<
-    /N 9 0 R
-  >>
-  /NM (Highlight-1)
-  /F 4
-  /QuadPoints [293 542 349 542 293 530 349 530]
-  /P 3 0 R
-  /C [1 0.90196 0]
-  /Rect [293 530 349 542]
->>
-endobj
-20 0 obj <<
-  /Type /Annot
-  /Subtype /Highlight
-  /AP <<
-    /N 11 0 R
-  >>
-  /NM (Highlight-2)
-  /F 4
-  /QuadPoints [83 453 178 453 83 440 178 440]
-  /P 3 0 R
-  /C [0.26667 0.78431 0.96078]
-  /Rect [83 440 178 453]
->>
-endobj
-21 0 obj <<
-  /Type /Annot
-  /Subtype /Popup
-  /Parent 22 0 R
-  /Rect [191 377 443 488]
->>
-endobj
-22 0 obj <<
-  /Type /Annot
-  /Subtype /Highlight
-  /Popup 21 0 R
-  /AP <<
-    /N 13 0 R
-  >>
-  /NM (Highlight-With-Popup-1)
-  /Contents (Text Note)
-  /QuadPoints [149 487 191 487 149 476 191 476]
-  /P 3 0 R
-  /C [0.14902 0.90196 0]
-  /Rect [149 476 191 487]
-  /F 4
->>
-endobj
-23 0 obj <<
-  /ca 1
-  /Type /ExtGState
-  /CA 1
-  /BM /Normal
->>
-endobj
-24 0 obj <<
-  /ca 1
-  /Type /ExtGState
-  /CA 1
-  /AIS false
-  /BM /Multiply
->>
-endobj
-xref
-0 25
-0000000000 65535 f 
-0000000015 00000 n 
-0000000068 00000 n 
-0000000338 00000 n 
-0000000475 00000 n 
-0000000570 00000 n 
-0000001108 00000 n 
-0000001345 00000 n 
-0000001423 00000 n 
-0000001499 00000 n 
-0000001749 00000 n 
-0000001972 00000 n 
-0000002222 00000 n 
-0000002442 00000 n 
-0000002693 00000 n 
-0000002916 00000 n 
-0000003056 00000 n 
-0000003196 00000 n 
-0000003443 00000 n 
-0000003727 00000 n 
-0000003944 00000 n 
-0000004171 00000 n 
-0000004269 00000 n 
-0000004544 00000 n 
-0000004615 00000 n 
-trailer <<
-  /Root 1 0 R
-  /Size 25
->>
-startxref
-4701
-%%EOF
diff --git a/testing/resources/listbox_form.in b/testing/resources/listbox_form.in
index 354d841..054f21b 100644
--- a/testing/resources/listbox_form.in
+++ b/testing/resources/listbox_form.in
@@ -3,7 +3,7 @@
   /Type /Catalog
   /Pages 2 0 R
   /AcroForm <<
-    /Fields [ 8 0 R 9 0 R 10 0 R 11 0 R 12 0 R ]
+    /Fields [8 0 R 9 0 R 10 0 R 11 0 R 12 0 R 13 0 R 14 0 R]
     /DR 4 0 R
   >>
 >>
@@ -11,16 +11,16 @@
 {{object 2 0}} <<
   /Type /Pages
   /Count 1
-  /Kids [ 3 0 R ]
+  /Kids [3 0 R]
 >>
 endobj
 {{object 3 0}} <<
   /Type /Page
   /Parent 2 0 R
   /Resources 4 0 R
-  /MediaBox [ 0 0 300 600 ]
+  /MediaBox [0 0 300 600]
   /Contents 7 0 R
-  /Annots [ 8 0 R 9 0 R 10 0 R 11 0 R 12 0 R ]
+  /Annots [8 0 R 9 0 R 10 0 R 11 0 R 12 0 R 13 0 R 14 0 R]
 >>
 endobj
 {{object 4 0}} <<
@@ -56,7 +56,7 @@
   /Ff 0
   /T (Listbox_SingleSelect)
   /DA (0 0 0 rg /F1 12 Tf)
-  /Rect [ 100 350 200 380 ]
+  /Rect [100 350 200 380]
   /Opt [[(foo) (Foo)] [(bar) (Bar)] [(qux) (Qux)]]
 >>
 endobj
@@ -67,7 +67,7 @@
   /Ff 2097152
   /T (Listbox_MultiSelect)
   /DA (0 0 0 rg /F1 12 Tf)
-  /Rect [ 100 400 200 430 ]
+  /Rect [100 400 200 430]
   /Opt [(Apple) (Banana) (Cherry) (Date) (Elderberry) (Fig) (Guava) (Honeydew)
         (Indian Fig) (Jackfruit) (Kiwi) (Lemon) (Mango) (Nectarine) (Orange)
         (Persimmon) (Quince) (Raspberry) (Strawberry) (Tamarind) (Ugli Fruit)
@@ -82,7 +82,7 @@
   /Ff 1
   /T (Listbox_ReadOnly)
   /DA (0 0 0 rg /F1 12 Tf)
-  /Rect [ 100 500 200 530 ]
+  /Rect [100 500 200 530]
   /Opt [(Dog) (Elephant) (Frog)]
 >>
 endobj
@@ -91,24 +91,49 @@
   /Subtype /Widget
   /FT /Ch
   /Ff 2097152
-  /T (Listbox_MultiSelectMultipleSelected)
+  /T (Listbox_MultiSelectMultipleIndices)
   /DA (0 0 0 rg /F1 12 Tf)
-  /Rect [ 100 200 200 230 ]
-  /Opt [(Alpha) (Beta) (Gamma) (Delta) (Epsilon)]
-  /V [(Epsilon) (Gamma)]
+  /Rect [100 250 200 280]
+  /Opt [(Albania) (Belgium) (Croatia) (Denmark) (Estonia)]
+  /I [1 3]
 >>
 endobj
 {{object 12 0}} <<
   /Type /Annot
   /Subtype /Widget
   /FT /Ch
+  /Ff 2097152
+  /T (Listbox_MultiSelectMultipleValues)
+  /DA (0 0 0 rg /F1 12 Tf)
+  /Rect [100 200 200 230]
+  /Opt [(Alpha) (Beta) (Gamma) (Delta) (Epsilon)]
+  /V [(Epsilon) (Gamma)]
+>>
+endobj
+{{object 13 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Ch
+  /Ff 2097152
+  /T (Listbox_MultiSelectMultipleMismatch)
+  /DA (0 0 0 rg /F1 12 Tf)
+  /Rect [100 150 200 180]
+  /Opt [(Alligator) (Bear) (Cougar) (Deer) (Echidna)]
+  /V [(Alligator) (Cougar)]
+  /I [1 3 4]
+>>
+endobj
+{{object 14 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Ch
   /Ff 0
   /T (Listbox_SingleSelectLastSelected)
   /DA (0 0 0 rg /F1 12 Tf)
-  /Rect [ 100 100 200 130 ]
+  /Rect [100 100 200 130]
   /Opt [(Alberta) (British Columbia) (Manitoba) (New Brunswick)
         (Newfoundland and Labrador) (Nova Scotia) (Ontario)
-        (Prince Edward Island) (Quebec) (Saskatchewan) ]
+        (Prince Edward Island) (Quebec) (Saskatchewan)]
   /V (Saskatchewan)
   /TI 9
 >>
diff --git a/testing/resources/listbox_form.pdf b/testing/resources/listbox_form.pdf
index 9e1393e..10c5702 100644
--- a/testing/resources/listbox_form.pdf
+++ b/testing/resources/listbox_form.pdf
@@ -4,7 +4,7 @@
   /Type /Catalog
   /Pages 2 0 R
   /AcroForm <<
-    /Fields [ 8 0 R 9 0 R 10 0 R 11 0 R 12 0 R ]
+    /Fields [8 0 R 9 0 R 10 0 R 11 0 R 12 0 R 13 0 R 14 0 R]
     /DR 4 0 R
   >>
 >>
@@ -12,16 +12,16 @@
 2 0 obj <<
   /Type /Pages
   /Count 1
-  /Kids [ 3 0 R ]
+  /Kids [3 0 R]
 >>
 endobj
 3 0 obj <<
   /Type /Page
   /Parent 2 0 R
   /Resources 4 0 R
-  /MediaBox [ 0 0 300 600 ]
+  /MediaBox [0 0 300 600]
   /Contents 7 0 R
-  /Annots [ 8 0 R 9 0 R 10 0 R 11 0 R 12 0 R ]
+  /Annots [8 0 R 9 0 R 10 0 R 11 0 R 12 0 R 13 0 R 14 0 R]
 >>
 endobj
 4 0 obj <<
@@ -57,7 +57,7 @@
   /Ff 0
   /T (Listbox_SingleSelect)
   /DA (0 0 0 rg /F1 12 Tf)
-  /Rect [ 100 350 200 380 ]
+  /Rect [100 350 200 380]
   /Opt [[(foo) (Foo)] [(bar) (Bar)] [(qux) (Qux)]]
 >>
 endobj
@@ -68,7 +68,7 @@
   /Ff 2097152
   /T (Listbox_MultiSelect)
   /DA (0 0 0 rg /F1 12 Tf)
-  /Rect [ 100 400 200 430 ]
+  /Rect [100 400 200 430]
   /Opt [(Apple) (Banana) (Cherry) (Date) (Elderberry) (Fig) (Guava) (Honeydew)
         (Indian Fig) (Jackfruit) (Kiwi) (Lemon) (Mango) (Nectarine) (Orange)
         (Persimmon) (Quince) (Raspberry) (Strawberry) (Tamarind) (Ugli Fruit)
@@ -83,7 +83,7 @@
   /Ff 1
   /T (Listbox_ReadOnly)
   /DA (0 0 0 rg /F1 12 Tf)
-  /Rect [ 100 500 200 530 ]
+  /Rect [100 500 200 530]
   /Opt [(Dog) (Elephant) (Frog)]
 >>
 endobj
@@ -92,47 +92,74 @@
   /Subtype /Widget
   /FT /Ch
   /Ff 2097152
-  /T (Listbox_MultiSelectMultipleSelected)
+  /T (Listbox_MultiSelectMultipleIndices)
   /DA (0 0 0 rg /F1 12 Tf)
-  /Rect [ 100 200 200 230 ]
-  /Opt [(Alpha) (Beta) (Gamma) (Delta) (Epsilon)]
-  /V [(Epsilon) (Gamma)]
+  /Rect [100 250 200 280]
+  /Opt [(Albania) (Belgium) (Croatia) (Denmark) (Estonia)]
+  /I [1 3]
 >>
 endobj
 12 0 obj <<
   /Type /Annot
   /Subtype /Widget
   /FT /Ch
+  /Ff 2097152
+  /T (Listbox_MultiSelectMultipleValues)
+  /DA (0 0 0 rg /F1 12 Tf)
+  /Rect [100 200 200 230]
+  /Opt [(Alpha) (Beta) (Gamma) (Delta) (Epsilon)]
+  /V [(Epsilon) (Gamma)]
+>>
+endobj
+13 0 obj <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Ch
+  /Ff 2097152
+  /T (Listbox_MultiSelectMultipleMismatch)
+  /DA (0 0 0 rg /F1 12 Tf)
+  /Rect [100 150 200 180]
+  /Opt [(Alligator) (Bear) (Cougar) (Deer) (Echidna)]
+  /V [(Alligator) (Cougar)]
+  /I [1 3 4]
+>>
+endobj
+14 0 obj <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Ch
   /Ff 0
   /T (Listbox_SingleSelectLastSelected)
   /DA (0 0 0 rg /F1 12 Tf)
-  /Rect [ 100 100 200 130 ]
+  /Rect [100 100 200 130]
   /Opt [(Alberta) (British Columbia) (Manitoba) (New Brunswick)
         (Newfoundland and Labrador) (Nova Scotia) (Ontario)
-        (Prince Edward Island) (Quebec) (Saskatchewan) ]
+        (Prince Edward Island) (Quebec) (Saskatchewan)]
   /V (Saskatchewan)
   /TI 9
 >>
 endobj
 xref
-0 13
+0 15
 0000000000 65535 f 
 0000000015 00000 n 
-0000000151 00000 n 
-0000000216 00000 n 
-0000000379 00000 n 
-0000000414 00000 n 
-0000000447 00000 n 
-0000000523 00000 n 
-0000000625 00000 n 
-0000000832 00000 n 
-0000001302 00000 n 
-0000001488 00000 n 
-0000001741 00000 n 
+0000000163 00000 n 
+0000000226 00000 n 
+0000000399 00000 n 
+0000000434 00000 n 
+0000000467 00000 n 
+0000000543 00000 n 
+0000000645 00000 n 
+0000000850 00000 n 
+0000001318 00000 n 
+0000001502 00000 n 
+0000001747 00000 n 
+0000001996 00000 n 
+0000002267 00000 n 
 trailer <<
   /Root 1 0 R
-  /Size 13
+  /Size 15
 >>
 startxref
-2119
+2642
 %%EOF
diff --git a/testing/resources/marked_content_id.in b/testing/resources/marked_content_id.in
new file mode 100644
index 0000000..ebc217f
--- /dev/null
+++ b/testing/resources/marked_content_id.in
@@ -0,0 +1,235 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /MarkInfo <<
+    /Marked true
+  >>
+  /Pages 2 0 R
+  /StructTreeRoot 11 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Contents 4 0 R
+  /MediaBox [0 0 612 792]
+  /Parent 2 0 R
+  /Resources <<
+    /ProcSet [/PDF /Text /ImageC]
+    /ColorSpace <<
+      /CS0 /DeviceRGB
+    >>
+    /Font <<
+      /TT0 5 0 R
+    >>
+    /XObject <<
+      /Im0 9 0 R
+    >>
+  >>
+  /StructParents 0
+  /Tabs /S
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+/Artifact <<
+  /Type /Layout
+  /BBox [408 516 411 522 ]
+>>
+BDC
+q
+18 40 576 734 re
+W n
+BT
+/CS0 cs 0 0 0  scn
+/TT0 1 Tf
+3 Tr 12 0 0 12 408.3599 516 Tm
+(!)Tj
+ET
+EMC
+/Figure <<
+  /MCID 0
+>>
+BDC
+/ClipSpan
+BMC
+Q
+q
+/Clip
+BMC
+203.52 516 204.96 204 re
+W n
+EMC
+q
+/Perceptual ri
+204.96 0 0 204 203.52 516 cm
+/Im0 Do
+Q
+EMC
+EMC
+Q
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /Font
+  /Subtype /TrueType
+  /BaseFont /KPRGOG+Calibri
+  /FirstChar 33
+  /FontDescriptor 6 0 R
+  /LastChar 33
+  /ToUnicode 8 0 R
+  /Widths [226]
+>>
+endobj
+{{object 6 0}} <<
+  /Type /FontDescriptor
+  /Ascent 952
+  /AvgWidth 521
+  /CapHeight 644
+  /Descent -269
+  /Flags 4
+  /FontBBox [-503 -307 1240 1026]
+  /FontFile2 7 0 R
+  /FontName /KPRGOG+Calibri
+  /ItalicAngle 0
+  /MaxWidth 1328
+  /StemV 0
+  /XHeight 476
+>>
+endobj
+{{object 7 0}} <<
+  /Filter [/ASCII85Decode /FlateDecode]
+  {{streamlen}}
+>>
+stream
+GhOYs.SXL4?t`qUAme0T9e9ZP"3(Hd+dJWtR0Mc^!/VL0WJN&85/SHb2Tl(-5ik^jKM"^O8Hk>#!@0XF
+nrmMQ2*caF2mEF!5/SB`<ldqX9ndPSE^5#N*5h&A+<]SBUVVNeJe#T[$]OJp46d]&Jj98Q)'RR_N+Q$s
+&7@KA^s9^uV"GVZTScj%Z64ENVLB-%'.NJL2I@=I3P\P)?e:eKd2..*\c;[%\!usuLDc2s#rI26AhNtn
+^UG$s\/,#AokOTk)[8bg-SVgp!L942WeSUc0X(R4"+qe&KRog"#T4I])&W>f1LFVQ"3(C(K-c.'K-*pZ
+TV<PGMsrI+Z\u%:/*SdVWiMO*)]RHbR@:''/+G?F`D"M"m?ilmjHu<'?m9bf+?h%AV*@i$rdWUglBL\R
+N*58<pdKG\=IE\FKQM'1"bNLLD=hAlRG$8\=ZP+lbak!2F'OuJYm\^3MTH3FE!XRCM9612s1Q\"pZiJC
+hf!.nSDR84frS]M<L@E<EA4Z%Z0dX:OOUR:oF0ar(1?):((_2??l'I:d;Xs<gEnBP1.+N1'OoX#?V"9)
+62f*K!":%>J09&cGAZN]SBRe'9J-<tdVIk~>
+endstream
+endobj
+{{object 8 0}} <<
+  {{streamlen}}
+>>
+stream
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo <<
+  /Registry (Adobe)
+  /Ordering (UCS)
+  /Supplement 0
+>> def
+/CMapName /Adobe-Identity-UCS def
+/CMapType 2 def
+1 begincodespacerange
+<00><FF>
+endcodespacerange
+1 beginbfrange
+<21><21><0009>
+endbfrange
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+endstream
+endobj
+{{object 9 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter [/ASCII85Decode /FlateDecode]
+  /Height 272
+  /Intent /Perceptual
+  /Interpolate true
+  /SMask 10 0 R
+  /Width 273
+  {{streamlen}}
+>>
+stream
+GhVQ=BrkT/*<>Tnp)[K];NNO';(,Y,e3[reZBQQ?W!Kf<[A?;p.U_Il/M348;ME%+5X5%[`$K.l1b(tG
+TLMZ2+XWWp'13=j`\iPk)E1o?VW[ZsH+/!EYO=ZTq+Z;[m[Z0.gc9$0IqH7cL&Ks6zzzzzzzzzzzzzzz
+zzzzzzzzzzzi5kWPD5!Dac`&SeQ0\"gG?d2ed.;V%H`m^)\?kGADd=@:VD4jXEa<PJG,W`gbI)ZrQ!rE
+mq<cX8_p>e&W:iIMjU]Ac;PpMX%H8<GhV0ff3+WZ!HIIKD_2kcp(LEsJoBS&([m(jN>?9X4Isl\@B)VH
+ei?PN:-bUd:es1a46`.c4#oSK[[&N_Hpg#E(2et8dNjOo4Y\o6mC?8&0=r[0BSDQNBl[LHrrinESN2aM
+H]X[shFSd6Yp6u;/h'+G@dCrba%Fh+VIeW!SI"c<255j-(s+rVNHr1p8m8/;H/)Q#PhA/;iZ1`M;dHTj
+,*\s38\+d-:.HfJ"C2Z>LZMr;Er#sg8DXB?B*?@&/POJ=2Rp.acH1S'c:0h%Qf1/p(_WUYP..Hoq_lC7
+UqW'>J9UIja/=74H/IfJ0UNSK>[EA-iM;_7B;s#=jF65n=VC>ZS])C]u!<LrVP)Et-hQ^Ki?[<aU2WMi
+S[rGk5[#g-0I/C3k+d75h;$Ti8O+(Nt:dX;_GD?E)V!:\B9uBJN?e@>&4d!kgpFji7r5#KakOp4$nkmf
+'eOsCc@\^uX=/66#_jB5In+iQ57QP'hMiSe,i3Xk*8\MecZ[,s'^[&c+h!T9k85jhM&'r-%R25'SVHGB
+9k#XV_9R?#BDhfJLT,ZreD`jrr^qk`H-eIGW^[0@]]-7aBA\.>nnFsQ4`1G];\9@kt4\_Dgq4'8WPj-$
+u_lHNB^YCR9OEk;6NgF<)V&<.s$'T[U:/UA%GD$h=^Ge@VWtFutQ*iBll8J2VF878mS2e6qqssAI](5J
+ultb2`,%T8rR55Z(#hPT3c<3mQMD:rt@imcuhsQg'BB=mCc:obN[AW,VDr*/VCRGZ"VEEVs;/)_0AF;K
+CQS/T404*C@0Nr`kqmB+F&\k[a]3Mg4VAc.Jp05hk`Z?*&@jO2FR5eB8Qb7E`RXE\'mVP$=jZKk*a-=<
+o%<4Nj@9i1H+#gG_VS)(L\KPin1iabgE7Rl\`Hnt3e%u-@inXMl4,7JE5H'\>oG^]C/R82DqN.[/Z5TT
+Abj7/s5$+-\4KuJ!k$S"+oTc3@p]Cu:HCjQ\("LiV_\<pFcgMmJOGPL:Eg0]dUOb12i[T3@EV3=[Gl<O
+319HoCeUAPU>_cY5<G-Cl1?HM]9Fn;I+]GPt/j6b2q=os6KKn7dH[!G?F5"qpMQYU9=f^:m*H#&h#at!
+.Sc!,=c/W3>>8DB5aX)9EcKD*"9$<a19Z+H\fSQr'66$]N*AZ0%faVTGMT):eO*;([PPH$Lo>Ia.Dap7
+iQ7:[SR.Kt$nE;_eKDNmrSVYbTnei/am)MoEVY'#Z=EA*'B!![Bi\U1Xrq<r\/OJT(2s*J#Au5LrZ)c>
+-(V<:Ebf4dId6D-GdA-8uEa81%C#-u'fc&FYfU)VT2jqjEd^V#G65A,L)s5aq"(iVq5.b\DbPtR`F6:H
+J_p+*[1W>Oo_ofZZj>'MId`I8I*8epRQi,B$O&pXGCu"2s2f@43DHi6pg+r;^M=rN<4OWmC'u"Zq,9h=
+.;lAdFZM77U$fM9<Elh+ZD,n'-&",C^cCE>XU>iMX=?LaD1=,@qo8dg/Ses-NXqkT%9NRcJ^$.bA@T-;
+dBg6iBe%]J62X9a(XZ!F3XY7EgQG`YM1Hp%jI;53^`H0$jf:6@!PibJ?l[O&ZY(FDnq(4%U8'gO<>.9V
+)RHV,l_Y.'.$;Bk^_tl+Je#)m:?Iroo^Y)DNJ)(dpH!)%Bit]Q!Ramb%Qf#Dd5][2Kzzzzzzzzzzzzzz
+zzzzzzzzzz!!!#Ws20Ni!j00"QN~>
+endstream
+endobj
+{{object 10 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceGray
+  /Filter [/ASCII85Decode /FlateDecode]
+  /Height 272
+  /Interpolate true
+  /Width 273
+  {{streamlen}}
+>>
+stream
+GhVQ$0b"*_!!8hNrdD20"'P[)zzzzzzzzzzzzzzzzz!8pQUgs,iQ~>
+endstream
+endobj
+{{object 11 0}} <<
+  /Type /StructTreeRoot
+  /K 12 0 R
+  /ParentTree <<
+    /Nums [0 13 0 R]
+  >>
+  /ParentTreeNextKey 1
+>>
+endobj
+{{object 12 0}} <<
+  /S /Figure
+  /P 11 0 R
+  /A 14 0 R
+  /Alt (Hello!\000)
+  /K 0
+  /Pg 3 0 R
+>>
+endobj
+{{object 13 0}}
+  [12 0 R]
+endobj
+{{object 14 0}} <<
+  /BBox [204 516 408 720]
+  /InlineAlign /Center
+  /O /Layout
+  /Placement /Block
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/marked_content_id.pdf b/testing/resources/marked_content_id.pdf
index ddbf11f..cf80171 100644
--- a/testing/resources/marked_content_id.pdf
+++ b/testing/resources/marked_content_id.pdf
Binary files differ
diff --git a/testing/resources/matte.in b/testing/resources/matte.in
new file mode 100644
index 0000000..57d8e13
--- /dev/null
+++ b/testing/resources/matte.in
@@ -0,0 +1,172 @@
+{{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
+  /MediaBox [0 0 100 150]
+  /Contents [4 0 R]
+  /Resources <<
+    /XObject <<
+      /Mask 5 0 R
+      /NoMask 7 0 R
+      /MaskTooFewComps 9 0 R
+      /MaskTooManyComps 11 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+40 0 0 60 0 0 cm
+/Mask Do
+Q
+q
+40 0 0 60 50 0 cm
+/NoMask Do
+Q
+q
+40 0 0 60 0 90 cm
+/MaskTooFewComps Do
+Q
+q
+40 0 0 60 50 90 cm
+/MaskTooManyComps Do
+Q
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 50
+  /Height 50
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  /SMask 6 0 R
+  {{streamlen}}
+>>
+stream
+789cedc2310d00000c03a07f2aaab3ea7bcf03842655555555555555f5bf01cc7818dc
+endstream
+endobj
+{{object 6 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 50
+  /Height 50
+  /BitsPerComponent 8
+  /ColorSpace /DeviceGray
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  /Matte [0.0 0.2 1]
+  {{streamlen}}
+>>
+stream
+789cabaa1a05a3808e4061148c027a028351300ae809a246c128a027e0020065c9c90d
+endstream
+endobj
+{{object 7 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 50
+  /Height 50
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  /SMask 8 0 R
+  {{streamlen}}
+>>
+stream
+789cedc2310d00000c03a07f2aaab3ea7bcf03842655555555555555f5bf01cc7818dc
+endstream
+endobj
+{{object 8 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 50
+  /Height 50
+  /BitsPerComponent 8
+  /ColorSpace /DeviceGray
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  {{streamlen}}
+>>
+stream
+789cabaa1a05a3808e4061148c027a028351300ae809a246c128a027e0020065c9c90d
+endstream
+endobj
+{{object 9 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 50
+  /Height 50
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  /SMask 10 0 R
+  {{streamlen}}
+>>
+stream
+789cedc2310d00000c03a07f2aaab3ea7bcf03842655555555555555f5bf01cc7818dc
+endstream
+endobj
+{{object 10 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 50
+  /Height 50
+  /BitsPerComponent 8
+  /ColorSpace /DeviceGray
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  /Matte [0.0 0.2]
+  {{streamlen}}
+>>
+stream
+789cabaa1a05a3808e4061148c027a028351300ae809a246c128a027e0020065c9c90d
+endstream
+endobj
+{{object 11 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 50
+  /Height 50
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  /SMask 12 0 R
+  {{streamlen}}
+>>
+stream
+789cedc2310d00000c03a07f2aaab3ea7bcf03842655555555555555f5bf01cc7818dc
+endstream
+endobj
+{{object 12 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 50
+  /Height 50
+  /BitsPerComponent 8
+  /ColorSpace /DeviceGray
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  /Matte [0.0 0.2 1 0.5]
+  {{streamlen}}
+>>
+stream
+789cabaa1a05a3808e4061148c027a028351300ae809a246c128a027e0020065c9c90d
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/matte.pdf b/testing/resources/matte.pdf
new file mode 100644
index 0000000..05d1ecd
--- /dev/null
+++ b/testing/resources/matte.pdf
@@ -0,0 +1,191 @@
+%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
+  /MediaBox [0 0 100 150]
+  /Contents [4 0 R]
+  /Resources <<
+    /XObject <<
+      /Mask 5 0 R
+      /NoMask 7 0 R
+      /MaskTooFewComps 9 0 R
+      /MaskTooManyComps 11 0 R
+    >>
+  >>
+>>
+endobj
+4 0 obj <<
+  /Length 149
+>>
+stream
+q
+40 0 0 60 0 0 cm
+/Mask Do
+Q
+q
+40 0 0 60 50 0 cm
+/NoMask Do
+Q
+q
+40 0 0 60 0 90 cm
+/MaskTooFewComps Do
+Q
+q
+40 0 0 60 50 90 cm
+/MaskTooManyComps Do
+Q
+endstream
+endobj
+5 0 obj <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 50
+  /Height 50
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  /SMask 6 0 R
+  /Length 71
+>>
+stream
+789cedc2310d00000c03a07f2aaab3ea7bcf03842655555555555555f5bf01cc7818dc
+endstream
+endobj
+6 0 obj <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 50
+  /Height 50
+  /BitsPerComponent 8
+  /ColorSpace /DeviceGray
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  /Matte [0.0 0.2 1]
+  /Length 71
+>>
+stream
+789cabaa1a05a3808e4061148c027a028351300ae809a246c128a027e0020065c9c90d
+endstream
+endobj
+7 0 obj <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 50
+  /Height 50
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  /SMask 8 0 R
+  /Length 71
+>>
+stream
+789cedc2310d00000c03a07f2aaab3ea7bcf03842655555555555555f5bf01cc7818dc
+endstream
+endobj
+8 0 obj <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 50
+  /Height 50
+  /BitsPerComponent 8
+  /ColorSpace /DeviceGray
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  /Length 71
+>>
+stream
+789cabaa1a05a3808e4061148c027a028351300ae809a246c128a027e0020065c9c90d
+endstream
+endobj
+9 0 obj <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 50
+  /Height 50
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  /SMask 10 0 R
+  /Length 71
+>>
+stream
+789cedc2310d00000c03a07f2aaab3ea7bcf03842655555555555555f5bf01cc7818dc
+endstream
+endobj
+10 0 obj <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 50
+  /Height 50
+  /BitsPerComponent 8
+  /ColorSpace /DeviceGray
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  /Matte [0.0 0.2]
+  /Length 71
+>>
+stream
+789cabaa1a05a3808e4061148c027a028351300ae809a246c128a027e0020065c9c90d
+endstream
+endobj
+11 0 obj <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 50
+  /Height 50
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  /SMask 12 0 R
+  /Length 71
+>>
+stream
+789cedc2310d00000c03a07f2aaab3ea7bcf03842655555555555555f5bf01cc7818dc
+endstream
+endobj
+12 0 obj <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 50
+  /Height 50
+  /BitsPerComponent 8
+  /ColorSpace /DeviceGray
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  /Matte [0.0 0.2 1 0.5]
+  /Length 71
+>>
+stream
+789cabaa1a05a3808e4061148c027a028351300ae809a246c128a027e0020065c9c90d
+endstream
+endobj
+xref
+0 13
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000131 00000 n 
+0000000370 00000 n 
+0000000571 00000 n 
+0000000856 00000 n 
+0000001148 00000 n 
+0000001433 00000 n 
+0000001704 00000 n 
+0000001990 00000 n 
+0000002281 00000 n 
+0000002568 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 13
+>>
+startxref
+2865
+%%EOF
diff --git a/testing/resources/mona_lisa.fragment b/testing/resources/mona_lisa.fragment
new file mode 100644
index 0000000..873677d
--- /dev/null
+++ b/testing/resources/mona_lisa.fragment
@@ -0,0 +1,109 @@
+/9j/4AAQSkZJRgABAQEAZABkAAD//gBSRmlsZSBzb3VyY2U6IGh0dHA6Ly9jb21tb25zLndpa2lt
+ZWRpYS5vcmcvd2lraS9GaWxlOk1vbmFfTGlzYV9mYWNlXzgwMHg4MDBweC5qcGf/2wBDAAYEBQYF
+BAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUo
+KSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo
+KCgoKCgoKCgoKCgoKCj/wAARCAB4AHgDAREAAhEBAxEB/8QAHAAAAgIDAQEAAAAAAAAAAAAABQYE
+BwEDCAIA/8QAOxAAAgECBQIEBAQFAwMFAAAAAQIDBBEABRIhMQZBEyJRYQcycYEUkaGxFUJiwfAj
+JOEWF9ElM1LC8f/EABoBAAIDAQEAAAAAAAAAAAAAAAIDAQQFAAb/xAAvEQACAgICAgAEBQQCAwAA
+AAAAAQIRAyESMQRBBRMiUTJhcaGxFCNSgZHwweHx/9oADAMBAAIRAxEAPwBqiIChT5t7gEYwX1ss
+JUbY0ErKBHpFu498Q3fRKTMmJVNm2POo9/tiG2kTFG+FfIAq9t2ta2BtvsKtkqKmDE2UgMDiUn2C
+3ugTnvVGRdPy6M2zKFJxv+HivLN6i6LuPvbDsalPaRPy29Cw/wAYOn1kPgUmYS3OxZUjJvwbFrgY
+fHx8hziqCVF8V+namVUnSvojzqlp9SkD3QkYGWKa62SsY5ZVmVDmlMKnLamCqgvu8bBgPYjkH64U
+3x/FpkcWF4yT8oG4337YBzdUgVHezEwN1N1BxzurslJGI1uSpJG3bvjlew2bYUN+fS+Cj12DJkqE
+WNgOeL4OM66AaNscXkb2vziVK47ZD0IkcG1r/X/PthVWFZLRNKqAAdiCT9cC19jk77MRpqILKNjf
+i/tbCpcug40SooAz6tNyfLsOPbBQhslsrH4n/ECXLa+Tp7IZvBrxaOprEXU0Fx8if1+/a/ri3i8e
+1zn1/P8A6Ba6oR8h6YqY8szKshpauaWdNCzBHkZifmYk778ffAZvIU5Qg3pMsQg4xbS2KmcZQKPU
+aqmqItVhqeEqL9rnGhjzc3SaZXyY63QGDvSuJaScofVfMp57YsOPLUkLUnHcQplXUFfQZrFV5bK2
+XZkll8SEWRx6MnBB9D+mEywppqW0N+by/U6Y+EvXdP1rlrJKkVNnVMAtVTLsrDgSJ30nj2O3pjLz
+4XhlXr0d+JWh6eJQCy2b6DEOKAT+55hQrYsNrW98TH2S2ToAATYG5GwI4wUqSYPZuSEBNXAIBO2E
+8eO0TZ8UZVtf5hvbE7RHYkQRG6kix7f2wuMnexjr0SvDZiqpf6dsH30D12bIKe77gna7W7bYHbbC
+tIFdf9R0/R3S9VmcrIJFHh06t/PKR5Rbk+v0GLMISk1CK2wE03begP8ACHommhy6LM8zjhqM0qf9
+eeoljEjhm3sL7D7b++KmXK8+Tin9K0l+hcUflwTrbLXFHCABftYdvtthbjRHNgjOsoiqKaaJ9Tqy
+kFWAKn88Vsip6HwlfZzV8R+kKeikeSjS128wCD+2NT4f57yfTP0I8jCltFWyJJEXul0vYkLce4Jx
+tqSfRRoJ9K5/WdNdSUOb5a7iWmbUVPEkZI1o3qCt/wBMBmxLLjcP+P1IjOpWztvJa+lzTJ6PMqF9
+dJVxLLG47qwuPpbi2MqP0Opd9ByV9E2KNWF97AbNiWlu2crN8cIABIFxyL7YW2yTZGhlNr7eltsc
+nZD0ZkpyI++1+cMcVVg3sUUWMxRtHpbVc3GKr4voYrM063k32YEi9t9zhiTXRDJVHAzSB3uoK2F/
+bEwm4u7OaT0UL8cs9TqHPsqyZEH+nWxaWvuus7KB6keYn6Dti5gySm5Zn0kyflrGlBdtl7dNWp6F
+FY2awU39RjFxx1aNHJ9g6pdWa5LX3J9MS27aE0uyHXiSRCFN9rG3OEThyGxaQi9UdOpXwyCW1muD
+b/PbC4J4ZckNdTVM5u63y5cpzeemilCQDzebuff9bY9R4eV5cak+zMzxUJUhVmbUNQt6W9bC++Lp
+WaSOjvgT1JK/w+ho5mtHl9Y1OD6o1pB9hrP5Yy/Mhxm697Gp3Wy0aXNhNMsIYi29u1j2v37Yq7fZ
+LetB01arE5DKVQaRY8m+/wDbHUxTnvQRplvbcaTuL+/GIXdMY2bwbxFd2wXNtUD07KMyvqid3WGn
+LvqszF0PIB8o/LfEairZNT9D109mYzSmMiRaJUkMbjmxIDCx+hwacpNEKadk3Nq38HlE8oGpvw7s
+thvcKdsLlG6TCUt0jkbrCsaXramzCGSNr10MmkfNrUqtxfsQBtjS8eP9hwf2f7jJ25KS+6Lv/wC6
+VBDlQq0lSipEm/DhqpZSddr2IRG08H5iDtxjGXi5XJQjt1fa6L7yQrkx1n6p0dKSZwIwAE4vca+B
+Y973B++KXJyfFd9B/LS2xLTq7NKbIWzvOfHpaeRxGFWkknILfKCFsBe3rg/lKWR48cr/ADbpHcmo
+3JAOLrjqHPcwio8uyeaohcj/AHUaSJGBv5jrUabW4P64tT8XHjjynk39tX+wr5km6jErP4oUM8Od
++JUfM/zC99/rjT+GZYvHSRV8lNSViSmmF2XUrM1wQefe2NTsp7uix/hJWFKDNaUMViM0E5AYgsNJ
+Ui/2GKHmR/C/ZPWi5MkzgykxMYlABszCxuP32xVUFsGWR+w1Lm0cNJHGAJRIw3U302bfbne2Ipds
+SOXT9UKqEsHLJqBH0HbFKVqSTLqaadByJ/D1FgbW2vhuO07BbXRydQZocvqqclJCW31XA3IsSe1z
+fbFiWHndC1krQfyLrl6TI5KKFNFTGDaULfU1yGJ/NQCe2AyYJJ/T0Hjkktk2l6tmoTmVI0zSrBEq
+wySG5RmZthc8AXIxPy3KCZy1Oijxoi67yiKUf7eHNI1Z73DDxRck+v8A4xou/wCnlXbi/wCBqf1x
+17OwP4TBW05RJqiJTJ4jBQu7X3O4Nj7jHmFBTjyTNNzcHRo6ioUk6ckprBYGlBFxfYf/AIMdwaWi
+LTeyblGXRnLYYWqaiOwsdDDf87jELFyVSOlNx/Caa5abKKdjCZGL3LNI5YnC5pQdRQULkrZyz8Yc
+wNZ1G3hFrIeB2/y2PRfCYccNv2Z/lu5UhEcuXErWYHdibbE/2xq1ZRHz4VpNP1BVU1I0i+PRlyq2
+a5V1P/2/XFPyopQTfoJLk9Fy5TRVkMjvLTVMpA3ZrHew/I/bvijyW9kSg0uiWIK2PSYaGpYA7Cwv
+xyT3xzURLvsaukq2opJSKiCWJGJtZCdz9sJlFdpjMc2tMbJMxQqbyMCb8jAPI1sclZyPmMBZ2ZZW
+GkeJqLaix4A+mNODr0IaNbMYiDDJIAbgMBbUpAO4F9r3/K+J2yaT7AGeVdTYtHIG1Pu3qTcbn7n8
+sWMUVQSb5C3mFayrGYXa8bhyrdiDdbHvxh0YJ6GznpUdk9I9QJmuUUciOC00aEXO1iAf748jNPHc
+H6dGy6nUgN8QOuafpqloqGty+tkr5m3iiFw68albhhxxv64b4+CedaaSX3ETlHG7e7GLpPMzU9OU
+lZVRS0krhv8AQlPnUajpv72thTSg2rug/wASTFzrTNZTCywgkr9sLjHnJX6Dk6WjmLrCoaozeWR7
+sdR2btvwceq8VVjSRlZvxAaWcNEpK2f+axPGLCEMNdLVMkWYRmJn8UkqpHuLf87emByxuLvoh7Lb
+ynM8wphrSSrjB8xW1lJ2/wA7YoNKnQDeg7H1DXooAmrFckWUbn9rdsQ8a9CqDtB1XUJvUzh1202s
+Dv625tgJwXVEptK7CY6jlqoisTygggGy7geuFcFdkcm/pbOdpa7xpQzCXzeQG2s27WONCMKHHppn
+lHhqg1KbhhtfjkG37euJBe2Q81y92y8vM6HUy2AI8p3P9t//ADgoZVy0iYJ3QqThI4NBVZJmc3bk
+qB6fXFlNt2Ntca9l5fA7qWlzTp6PJ6ipNPmVIDGrgjV4d/Kwvza9vtjznxXBKGR5K+mX8ml4mVTg
+oe0WR1OlR4UUZrcwqHUXSdcvjk29yLAfljN0pW/5LXoh5DA1NMZszrKyrn07LKiokYHoFHJuNyTi
+ZSjJrVV+oKX52LvXGcwDxI42BYgjbfe22H+Pi5y2LyTpUc/Z9KZcwZ2Yl2a/t7DHqMKSjSMvK9gy
+VlvZCRtp+vqcNQtumFMhDfjIWifS9wb3taxwvJJKLOirLlpljjdYiulnF/KfNuNhx9+cZnPTdC3H
+VBCSjUxqZFOlPMCU77knb2xHNN7YFM30ckEQIAXTfY6fMLd8Tr2CyfJnsUKlIULNfsPl55PpxiJQ
+V2FG0ikqKoLlRpRlbSCjC4O/Fr8k+98aEo/caHaWYyOVMOXBRIWCSHYj6ffCZxXabIoL5hl0/wD0
+5WySJQNEkQmURhiWCkG1jyQL++EJrmtjIqip8x8JpnnkRXZyQNPC27n12tjSiq0TrtkGOtlocziq
+sullp54SGjkDWa+3+Wwc4KUeM9pkW4SuLOi+kfjrlz9PxwZ0r0+ZIgWTSl0f+ofX0x5/P8Kywf8A
+a3H+DRx+VCf4tMEZ/wDEuOoB/A6UjI80kjC/5emBx/DZ95Dp511ErvMuojVvppr1EzXJfgL32vzj
+Sx+Lw70V5ZL62LVXSy+O5ZjIxNy9tgMXLVUV3FoinQiG+7WNiB++D7AJuWzGJ1K3BUcn7EYiULVE
+xdOy6qLNoTl1LIWEr2XSVIsGNr77d7jb9cZrwtXE7l7DdVXxVETeV4ybKoQ727m3bfCfkxUrBcrV
+UQBXwq7GJZmXRqKActf0+ww2Ka0C4Jn1TnETVI0sCC1iBGPU/p+3ptjpJvs5QS9i1Q0IVUctAlmu
+PCjB/ckg4a5xYwPUpiiZ1srPqHnbw9TahyABzta+Ikv8URFm+oqA0Eo8VDGV0MqkEDm4P14++EO0
+9DE12UbnlGtPn1VTh2aNJLIVTc+VSARtv5gMa2KVwUgX2BZUu6nURcXJY73w7sGSoO9ARUcnWuUQ
+5giyUk1QIXRvl84Ki/3IxW8vl8mTi6dB4GlkXItXqb4WU8JY0EcSWO5AuAMZGH4nKL4z2Wsnjp7R
+AynonTIgnjUpcCygj8v3wefzk1pnQxv2TOrOlBT5S/gRqiqoJ2tbfck+mEeN5vLJ9TGSxaKlqKfw
+igdGUgHy25B4xvRmn0UZRNog8GjSWQeQFjbttYYlTTlR0o0rLL6OzCiqMshK1FPSLpWO7garj5u3
+YnnFDKppvt//AEFRTHVYacgQ0udQSMynWGS4tzzqxUtydyQTiq0YfpseHLWawaYC6u3kPoCvub4O
+OWvpbI4ezbTdJxC0r1XhIx1aW8oUn1v/AJvivPzI39DsdHx5PtUVPoneOVpayRKlKZfCaJiCdyTv
+ck2F/uMaXKnpavYiiMnW1Y9OwqxTtO6C0ynQoIuo1AA78/8AGHy8aL6YN0eM16rr5qeHxggpp0Cz
+aYwLMrndTyLGx9MQvHjvfR1+hPramevr6iaSZpJJZS2vgsext9hixGKjFJE22fZbltZmtctLQwy1
+FQ+yJGNRv+1vfHTyQhHnkdImMJSfFLZevw3+EUcEyV2czh6lfkVR5EbtYnk+/tjB8n4m8v0YVS/c
+u4vGUPql2XFJl5MAWYaibD5f8tjIk0XEjNNkSIxa2jfa/wCWBa+xNkHPMnSajdbgEIwIbv6XHpgV
+qXJBJXo5zqsnEWdGjIWS8oVSG+XU9h9bb3HbHpoZ+WHn+RQljqVEHqOkENFDSqiMq1UxW3JF7H7X
+Xj64d487lyv0hWRar8wJk0arVCJ2RUJJ1MdlbixPobYt5HcW0V0iysiyTMa6ro2pqOi0RvdHjk1K
++2wIBJIxk5pwjabewoxd2hpHRvU1TmFFXVGZapoTdjqKge3Nj2H0AxXl5eOMWlHsOOCTY7ZjUTUm
+VwrLL+JrVGyKCdbD1P8ALz3OMzDH63JaTLkp8Y17KG6k8OOKopKGIvII1GuxBtxb2G55/vj0HjqT
+lym/ZTlVUhPqqA/wWREVS8Uha+m+w2IB/LjGgprmhDTI2awuuVUxmLqI49Kqex1E2PvucdGVzdE1
+SsG0ccktSqxX1Dvbgep/PBt0rOirejpj4C9IJQ5TLWTxXnqW1K9iCYx8ot6Hn7jHmfifkPNlUU9L
++TVwY/lw/Nl009Ivg2CgWsRccHFSNpWiW7dGWijuBGLXbAPYa12bWj0wGx78WxMlUQU9i91AqpSz
+CUnwyp498VcjldD8Zz7EIaTOqd6dkll/EukjWuCQbkqSeNyfXtvj0D5TxvkvVlZ1FiP1DXvJmwic
+qRCWN/fUf73xqePjUcdr2UMsvqPa5LVVVG88dNK8RYBNKni3Jt62wXz4xbi2FxbV0Fum80qKevSn
+qZXpp1kChilib8bYR5GFSi5R2LafRfGW9RR1FHFBUxzyGMJTuIxpAfgAXtfb19748/ODT2WYz0e6
+l6GOnWVzXxr4nhp8urUb3BBa/wBzhP1ctfuE6rZVOe0aNCskauXSO7Kw0rIO2/pe36Y1sGRp02Vp
+xdWKeeS02V5PGs0aLUMRaPuSMaGLnlyWnoBpRVsQayplq5DJMQVDHSnZfYY0IxSWhTdlp/B3pMZt
+RzVksPiXa2+1gP2A2NxvjH+JeY8clCJf8TEmuTOm+k8pGU5VBT69ciLubW1H1AxhOTcm37LcpWHw
+BYDa/e+Du9AL7mDGRp3IOq9sQ4vom/Z9UJqW1rEbHvgZHJ7EvrVo48qqBJJa6FTcHk9vU4RdzikW
+I9MpSopZ6itCUdGoUEkuyhUDXW9zfbgbcXxtQmlG5S3/AOCrkT6iiZknw5paurmq5JRmFbK5Z1SI
+yxq1727Ltfe57YXk+JTSUIql+4C8ZW5NhvOsloaOkZMwzGKIR/8AtJNVrCL8GyxrueRtfAYcuSTk
+4x3+l/yFOMUtspvq5MtjrUejqF8YfM0c0rgenzqP0ON7xnkcWpr+DPy1eiT0v17XZUwhqJmeEEBJ
+lVQwP9RNwdu/IwryPAhkuUdMnHlcdMtTJ/iHPDCGzFEZJPKr+EmpbDctpA59TvjMn4bb+mi1GQKp
+0myd2rM8rqengC6pUldW2K7WUEkX+vNhbA5az/Rhi2/0ohfRuWim+r83Gd59PVxK0dKvkp47Wsg9
+vfnHofGwfIxqDdv2Uck+UrQMjjaQrCpbzDg84baQNM6J+Due02Vwfgc5XRS2DxS6SFF+dQ/Kx+2P
+M/EcDlk+bD/Zq+PlShxZfFPXUtTRGqpqiOSMjV4isCCPrx3xm8lX2D4uyTSFpRrIIU4OKs6TrROA
+TQe/IGHqOhLbs1SeGgYHn62H1wuSDTbK862rqGOOZDLrYA/JJpAJG4v22v72xWWJzmmh/wAxQVMq
+PMetMloJJHaMZhU2IjhtaFe3H83bnGvj+HZsi/xX7lV+RFO3sWM++JOdVkfgzVy5fSqDppqRLEDi
+5tsP0Pti/g+F4obrl+bEy8lvrQjVuc1Uxv8AiZyp/pA3+u+NKOCEVVFdzb7YPeeRyLs7G9zra+DS
+SAb9mI9QG1irHcDg46jhx6Unlqf/AEzYTIC8bjctYElSODtc7+n0xUz41H+5/wB/UtYJuX0P/v5A
+3rmeq/i38PqleMU41OjC12Nz+gNh9cT4UY8OcfYnNafF+hZbbzXv7W74t0IDmQQJJI81TfSGAuDx
+te+/+cYRlbWkGl9xsjzYitpIqYMksqDQNfyKCbk32vYHn/5DFT5Sabl6GqdPQcyjNJTI6ZfO1KsV
+tbU8ugsx33HDADfj88V8mBNXJXY6GV9Idss+IWf5epi/iaT6AAyVFOCRe1hdbeo5v2xVfiQ7imv9
+jVlT7C8HxZro95IKCcKbF4y4J/Q/TAf0kv8AIJzh3REz74pVE1NIbU9DDGt5JSS+/ZFIFy1+w3+g
+3wEfDcpV2BLyIpfSVD1D1f40FU5m8JpzaOJV8SZ151MSdMYNztuxxq4PD4ta6/4/19ytPNYjPXSy
+E+CCt99iSxPqTycaKikV07C2X5bClI1bVgtHTjdb7SPvZfzt+uFSnLkox7YVLshVcaRKseka7NyN
+gbL/AM4bFtnPQLWOQm6q5ABJ8p49T7e+D5AbZ6VvmNh2sL8Y6yVYRy+qemqaadLiSFw4sObdt8RJ
+cotP2HGTi7XZ/9k=
diff --git a/testing/resources/multiple_form_types.in b/testing/resources/multiple_form_types.in
new file mode 100644
index 0000000..ec6af63
--- /dev/null
+++ b/testing/resources/multiple_form_types.in
@@ -0,0 +1,131 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /Fields [8 0 R 9 0 R 10 0 R 11 0 R 12 0 R]
+    /DR 4 0 R
+  >>
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources 4 0 R
+  /MediaBox [0 0 300 600]
+  /Contents 6 0 R
+  /Annots [7 0 R 8 0 R 9 0 R 10 0 R 11 0 R 13 0 R]
+>>
+endobj
+{{object 4 0}} <<
+  /Font <<
+    /F1 5 0 R
+  >>
+>>
+endobj
+{{object 5 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+>>
+endobj
+{{object 6 0}} <<
+  {{streamlen}}
+>>
+stream
+BT
+0 0 0 rg
+/F1 12 Tf
+100 450 Td
+(Test Form) Tj
+ET
+endstream
+endobj
+{{object 7 0}} <<
+  /Type /Annot
+  /Subtype /Link
+  /BS <<
+    /W 0
+  >>
+  /Rect [100 450 160 460]
+  /A <<
+    /Type /Action
+    /URI (https://www.cs.chromium.org/)
+    /S /URI
+  >>
+  /F 4
+>>
+endobj
+{{object 8 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Ch
+  /Ff 393216
+  /T (Combo_Editable)
+  /DA (0 0 0 rg /F1 12 Tf)
+  /Rect [100 400 200 430]
+  /Opt [[(foo) (Foo)] [(bar) (Bar)] [(qux) (Qux)]]
+>>
+endobj
+{{object 9 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Ch
+  /Ff 2097152
+  /T (Listbox_MultiSelectMultipleSelected)
+  /DA (0 0 0 rg /F1 12 Tf)
+  /Rect [100 350 200 380]
+  /Opt [(Alpha) (Beta) (Gamma) (Delta) (Epsilon)]
+  /V [(Epsilon) (Gamma)]
+>>
+endobj
+{{object 10 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Tx
+  /T (Text Box)
+  /DA (0 0 0 rg /F1 12 Tf)
+  /Rect [100 300 200 330]
+>>
+endobj
+{{object 11 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Btn
+  /F 4
+  /P 3 0 R
+  /Rect [135 250 155 270]
+  /T (Checkbox)
+>>
+endobj
+{{object 12 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Btn
+  /Ff 32768
+  /T (radioButton)
+  /TU (radioButton1)
+  /Kids [13 0 R]
+  /V /value3
+>>
+endobj
+{{object 13 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Btn
+  /F 4
+  /P 3 0 R
+  /Parent 12 0 R
+  /Rect [85 50 105 70]
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/multiple_form_types.pdf b/testing/resources/multiple_form_types.pdf
new file mode 100644
index 0000000..da83c9e
--- /dev/null
+++ b/testing/resources/multiple_form_types.pdf
@@ -0,0 +1,151 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /Fields [8 0 R 9 0 R 10 0 R 11 0 R 12 0 R]
+    /DR 4 0 R
+  >>
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources 4 0 R
+  /MediaBox [0 0 300 600]
+  /Contents 6 0 R
+  /Annots [7 0 R 8 0 R 9 0 R 10 0 R 11 0 R 13 0 R]
+>>
+endobj
+4 0 obj <<
+  /Font <<
+    /F1 5 0 R
+  >>
+>>
+endobj
+5 0 obj <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+>>
+endobj
+6 0 obj <<
+  /Length 51
+>>
+stream
+BT
+0 0 0 rg
+/F1 12 Tf
+100 450 Td
+(Test Form) Tj
+ET
+endstream
+endobj
+7 0 obj <<
+  /Type /Annot
+  /Subtype /Link
+  /BS <<
+    /W 0
+  >>
+  /Rect [100 450 160 460]
+  /A <<
+    /Type /Action
+    /URI (https://www.cs.chromium.org/)
+    /S /URI
+  >>
+  /F 4
+>>
+endobj
+8 0 obj <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Ch
+  /Ff 393216
+  /T (Combo_Editable)
+  /DA (0 0 0 rg /F1 12 Tf)
+  /Rect [100 400 200 430]
+  /Opt [[(foo) (Foo)] [(bar) (Bar)] [(qux) (Qux)]]
+>>
+endobj
+9 0 obj <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Ch
+  /Ff 2097152
+  /T (Listbox_MultiSelectMultipleSelected)
+  /DA (0 0 0 rg /F1 12 Tf)
+  /Rect [100 350 200 380]
+  /Opt [(Alpha) (Beta) (Gamma) (Delta) (Epsilon)]
+  /V [(Epsilon) (Gamma)]
+>>
+endobj
+10 0 obj <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Tx
+  /T (Text Box)
+  /DA (0 0 0 rg /F1 12 Tf)
+  /Rect [100 300 200 330]
+>>
+endobj
+11 0 obj <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Btn
+  /F 4
+  /P 3 0 R
+  /Rect [135 250 155 270]
+  /T (Checkbox)
+>>
+endobj
+12 0 obj <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Btn
+  /Ff 32768
+  /T (radioButton)
+  /TU (radioButton1)
+  /Kids [13 0 R]
+  /V /value3
+>>
+endobj
+13 0 obj <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Btn
+  /F 4
+  /P 3 0 R
+  /Parent 12 0 R
+  /Rect [85 50 105 70]
+>>
+endobj
+xref
+0 14
+0000000000 65535 f 
+0000000015 00000 n 
+0000000149 00000 n 
+0000000212 00000 n 
+0000000377 00000 n 
+0000000428 00000 n 
+0000000504 00000 n 
+0000000606 00000 n 
+0000000798 00000 n 
+0000001002 00000 n 
+0000001252 00000 n 
+0000001387 00000 n 
+0000001514 00000 n 
+0000001663 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 14
+>>
+startxref
+1788
+%%EOF
diff --git a/testing/resources/named_dests.in b/testing/resources/named_dests.in
index a97aebe..c71f2cc 100644
--- a/testing/resources/named_dests.in
+++ b/testing/resources/named_dests.in
@@ -64,8 +64,8 @@
 >>
 endobj
 % Old-style top-level Dests dictionary. Note that FirstAlternate
-% intentionally references non-exisstant page 11 and LastAlternate
-% intentionally references non-existant object 999.
+% intentionally references non-existent page 11 and LastAlternate
+% intentionally references non-existent object 999.
 {{object 14 0}} <<
   /FirstAlternate [11 /XYZ 200 400 800]
   /LastAlternate  <</D [999 0 R /XYZ 0 0 -200]>>
diff --git a/testing/resources/named_dests.pdf b/testing/resources/named_dests.pdf
index b99cead..ddcc985 100644
--- a/testing/resources/named_dests.pdf
+++ b/testing/resources/named_dests.pdf
@@ -65,8 +65,8 @@
 >>
 endobj
 % Old-style top-level Dests dictionary. Note that FirstAlternate
-% intentionally references non-exisstant page 11 and LastAlternate
-% intentionally references non-existant object 999.
+% intentionally references non-existent page 11 and LastAlternate
+% intentionally references non-existent object 999.
 14 0 obj <<
   /FirstAlternate [11 /XYZ 200 400 800]
   /LastAlternate  <</D [999 0 R /XYZ 0 0 -200]>>
@@ -117,16 +117,19 @@
 0000000638 00000 n 
 0000000766 00000 n 
 0000000000 65535 f 
-0000001060 00000 n 
-0000001188 00000 n 
+0000001059 00000 n 
+0000001187 00000 n 
 0000000000 65535 f 
 0000000000 65535 f 
 0000000000 65535 f 
 0000000000 65535 f 
 0000000000 65535 f 
-0000001283 00000 n 
-0000001393 00000 n 
-trailer<< /Root 1 0 R /Size 23 >>
+0000001282 00000 n 
+0000001392 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 23
+>>
 startxref
-1481
+1480
 %%EOF
diff --git a/testing/resources/named_dests_old_style.in b/testing/resources/named_dests_old_style.in
new file mode 100644
index 0000000..70e45ed
--- /dev/null
+++ b/testing/resources/named_dests_old_style.in
@@ -0,0 +1,55 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /Dests 6 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 2
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <<
+      /F1 5 0 R
+    >>
+  >>
+  /Contents [4 0 R]
+  /MediaBox [0 0 612 792]
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+BT
+/F1 20 Tf
+100 600 TD (Page1)Tj
+ET
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Arial
+>>
+endobj
+% Old-style top-level Dests dictionary. Note that FirstAlternate
+% intentionally references non-existent page 11 and LastAlternate
+% intentionally references non-existent object 999.
+{{object 6 0}} <<
+  /FirstAlternate [11 /XYZ 200 400 800]
+  /LastAlternate  <<
+    /D [999 0 R /XYZ 0 0 -200]
+  >>
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/named_dests_old_style.pdf b/testing/resources/named_dests_old_style.pdf
new file mode 100644
index 0000000..df7f04a
--- /dev/null
+++ b/testing/resources/named_dests_old_style.pdf
@@ -0,0 +1,68 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /Dests 6 0 R
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /Count 2
+  /Kids [3 0 R]
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <<
+      /F1 5 0 R
+    >>
+  >>
+  /Contents [4 0 R]
+  /MediaBox [0 0 612 792]
+>>
+endobj
+4 0 obj <<
+  /Length 37
+>>
+stream
+BT
+/F1 20 Tf
+100 600 TD (Page1)Tj
+ET
+endstream
+endobj
+5 0 obj <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Arial
+>>
+endobj
+% Old-style top-level Dests dictionary. Note that FirstAlternate
+% intentionally references non-existent page 11 and LastAlternate
+% intentionally references non-existent object 999.
+6 0 obj <<
+  /FirstAlternate [11 /XYZ 200 400 800]
+  /LastAlternate  <<
+    /D [999 0 R /XYZ 0 0 -200]
+  >>
+>>
+endobj
+xref
+0 7
+0000000000 65535 f 
+0000000015 00000 n 
+0000000083 00000 n 
+0000000146 00000 n 
+0000000300 00000 n 
+0000000388 00000 n 
+0000000643 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 7
+>>
+startxref
+761
+%%EOF
diff --git a/testing/resources/no_page_count.in b/testing/resources/no_page_count.in
new file mode 100644
index 0000000..e6b1a2d
--- /dev/null
+++ b/testing/resources/no_page_count.in
@@ -0,0 +1,50 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /MediaBox [0 0 200 200]
+  /Kids [3 0 R 3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Pages
+  /Kids [4 0 R 4 0 R 4 0 R]
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <<
+      /F1 5 0 R
+    >>
+  >>
+  /Contents 6 0 R
+>>
+endobj
+{{object 5 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Times-Roman
+>>
+endobj
+
+{{object 6 0}} <<
+  {{streamlen}}
+>>
+stream
+BT
+20 50 Td
+/F1 12 Tf
+(Hello, world!) Tj
+ET
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/no_page_count.pdf b/testing/resources/no_page_count.pdf
new file mode 100644
index 0000000..885df8c
--- /dev/null
+++ b/testing/resources/no_page_count.pdf
@@ -0,0 +1,63 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /MediaBox [0 0 200 200]
+  /Kids [3 0 R 3 0 R]
+>>
+endobj
+3 0 obj <<
+  /Type /Pages
+  /Kids [4 0 R 4 0 R 4 0 R]
+>>
+endobj
+4 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <<
+      /F1 5 0 R
+    >>
+  >>
+  /Contents 6 0 R
+>>
+endobj
+5 0 obj <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Times-Roman
+>>
+endobj
+
+6 0 obj <<
+  /Length 44
+>>
+stream
+BT
+20 50 Td
+/F1 12 Tf
+(Hello, world!) Tj
+ET
+endstream
+endobj
+xref
+0 7
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000152 00000 n 
+0000000216 00000 n 
+0000000342 00000 n 
+0000000421 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 7
+>>
+startxref
+516
+%%EOF
diff --git a/testing/resources/non_hex_file_id.in b/testing/resources/non_hex_file_id.in
new file mode 100644
index 0000000..7a93439
--- /dev/null
+++ b/testing/resources/non_hex_file_id.in
@@ -0,0 +1,26 @@
+{{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
+>>
+endobj
+{{xref}}
+trailer <<
+  /Root 1 0 R
+  /ID [(permanent non-hex) (changing non-hex)]
+  {{trailersize}}
+>>
+{{startxref}}
+%%EOF
diff --git a/testing/resources/non_hex_file_id.pdf b/testing/resources/non_hex_file_id.pdf
new file mode 100644
index 0000000..6f11eb6
--- /dev/null
+++ b/testing/resources/non_hex_file_id.pdf
@@ -0,0 +1,33 @@
+%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
+>>
+endobj
+xref
+0 4
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000161 00000 n 
+trailer <<
+  /Root 1 0 R
+  /ID [(permanent non-hex) (changing non-hex)]
+  /Size 4
+>>
+startxref
+212
+%%EOF
diff --git a/testing/resources/page_tree_empty_node.in b/testing/resources/page_tree_empty_node.in
new file mode 100644
index 0000000..4a9b901
--- /dev/null
+++ b/testing/resources/page_tree_empty_node.in
@@ -0,0 +1,40 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /MediaBox [0 0 200 200]
+  /Kids [3 0 R 4 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Pages
+  /Count 0
+  /Kids []
+  /Parent 2 0 R
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Pages
+  /Count 2
+  /Kids [5 0 R 6 0 R]
+  /Parent 2 0 R
+>>
+endobj
+{{object 5 0}} <<
+  /Type /Page
+  /Parent 4 0 R
+>>
+endobj
+{{object 6 0}} <<
+  /Type /Page
+  /Parent 4 0 R
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/page_tree_empty_node.pdf b/testing/resources/page_tree_empty_node.pdf
new file mode 100644
index 0000000..bf80a1a
--- /dev/null
+++ b/testing/resources/page_tree_empty_node.pdf
@@ -0,0 +1,53 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /MediaBox [0 0 200 200]
+  /Kids [3 0 R 4 0 R]
+>>
+endobj
+3 0 obj <<
+  /Type /Pages
+  /Count 0
+  /Kids []
+  /Parent 2 0 R
+>>
+endobj
+4 0 obj <<
+  /Type /Pages
+  /Count 2
+  /Kids [5 0 R 6 0 R]
+  /Parent 2 0 R
+>>
+endobj
+5 0 obj <<
+  /Type /Page
+  /Parent 4 0 R
+>>
+endobj
+6 0 obj <<
+  /Type /Page
+  /Parent 4 0 R
+>>
+endobj
+xref
+0 7
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000152 00000 n 
+0000000226 00000 n 
+0000000311 00000 n 
+0000000362 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 7
+>>
+startxref
+413
+%%EOF
diff --git a/testing/resources/pixel/axial_shading_point_at_border_no_extend_expected_skia.pdf.0.png b/testing/resources/pixel/axial_shading_point_at_border_no_extend_expected_skia.pdf.0.png
new file mode 100644
index 0000000..6c4c9b7
--- /dev/null
+++ b/testing/resources/pixel/axial_shading_point_at_border_no_extend_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1012369.in b/testing/resources/pixel/bug_1012369.in
index 7f56d35..db1fc5a 100644
--- a/testing/resources/pixel/bug_1012369.in
+++ b/testing/resources/pixel/bug_1012369.in
@@ -46,7 +46,7 @@
   /Filter [/ASCIIHexDecode /JPXDecode]
   /Height 64
   /Width 64
-{{streamlen}}
+  {{streamlen}}
 >>
 stream
 0000000c6a5020200d0a870a00000014667479706a703220000000006a7032200000004f6a7032
@@ -67,7 +67,7 @@
   /Filter [/ASCIIHexDecode /JPXDecode]
   /Height 64
   /Width 64
-{{streamlen}}
+  {{streamlen}}
 >>
 stream
 0000000c6a5020200d0a870a00000014667479706a703220000000006a7032200000004f6a7032
diff --git a/testing/resources/pixel/bug_1015233.in b/testing/resources/pixel/bug_1015233.in
new file mode 100644
index 0000000..aba521f
--- /dev/null
+++ b/testing/resources/pixel/bug_1015233.in
@@ -0,0 +1,113 @@
+{{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 600 200]
+  /Resources <<
+    /ProcSet [/PDF /ImageC]
+    /ColorSpace <<
+      /C1 [/Pattern]
+    >>
+    /Pattern <<
+      /P1 5 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+0.24 0 0 0.24 0 0 cm
+/C1 cs
+/P1 scn
+888 400 108 60 re
+f*
+0 0 0 rg
+888 460 m
+888 400 l
+S
+/C1 cs
+/P1 scn
+1536 400 108 60 re
+f*
+0 0 0 rg
+1536 460 m
+1536 400 l
+S
+/C1 cs
+/P1 scn
+2184 400 108 60 re
+f*
+0 0 0 rg
+2184 460 m
+2184 400 l
+S
+Q
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /Pattern
+  /PaintType 1
+  /PatternType 1
+  /TilingType 1
+  /BBox [0 0 128 32]
+  /Matrix [0.202488 0 0 -0.449947 0 791.999]
+  /Resources <<
+    /ProcSet [/PDF /ImageC]
+    /XObject <<
+      /R17 6 0 R
+    >>
+  >>
+  /XStep 128
+  /YStep 32
+  {{streamlen}}
+>>
+stream
+0.24 0 0 0.24 0 0 cm
+q
+0 134 534 -134 re
+W n
+q 533.333 0 0 -133.333 0 133.333 cm
+/R17 Do
+Q
+Q
+endstream
+endobj
+{{object 6 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /DecodeParms <<
+    /Columns 128
+    /Colors 3
+    /Predictor 15
+  >>
+  /Filter [/ASCII85Decode /FlateDecode]
+  /Height 32
+  /Width 128
+  {{streamlen}}
+>>
+stream
+Gb"0JYmJ3"&-Ti)eYrN1j:2;&T!_s\O.TqV*k'Yd:%,W`r[n(QqR?*8l/0q(V12/<QMrK7>Pbi$Ds?0-
+^SQEPrg*O8rEK--oPa!Od_DW.CH2@W5h#c57fSeR/cAoM\+FV'hpVPkGl`cd*^p
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1015233_expected.pdf.0.png b/testing/resources/pixel/bug_1015233_expected.pdf.0.png
new file mode 100644
index 0000000..aa39e7e
--- /dev/null
+++ b/testing/resources/pixel/bug_1015233_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1015233_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1015233_expected_skia.pdf.0.png
new file mode 100644
index 0000000..1a2a736
--- /dev/null
+++ b/testing/resources/pixel/bug_1015233_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1021762_expected.pdf.0.png b/testing/resources/pixel/bug_1021762_expected.pdf.0.png
index 39d531a..6c436c7 100644
--- a/testing/resources/pixel/bug_1021762_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_1021762_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1072440.in b/testing/resources/pixel/bug_1072440.in
new file mode 100644
index 0000000..1ef4fd6
--- /dev/null
+++ b/testing/resources/pixel/bug_1072440.in
@@ -0,0 +1,39 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /Fields [4 0 R]
+  >>
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Annots [4 0 R]
+  /MediaBox [0 0 200 200]
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Tx
+  /F 4
+  /Ff 8388608
+  /MaxLen 2
+  /P 3 0 R
+  /Rect [70 90 130 110]
+  /T (zip code)
+  /V (11111)
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1072440_expected.pdf.0.png b/testing/resources/pixel/bug_1072440_expected.pdf.0.png
new file mode 100644
index 0000000..ef8b63d
--- /dev/null
+++ b/testing/resources/pixel/bug_1072440_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1072440_expected_mac.pdf.0.png b/testing/resources/pixel/bug_1072440_expected_mac.pdf.0.png
new file mode 100644
index 0000000..28d1ef0
--- /dev/null
+++ b/testing/resources/pixel/bug_1072440_expected_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1072440_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1072440_expected_skia.pdf.0.png
new file mode 100644
index 0000000..6ce4fbe
--- /dev/null
+++ b/testing/resources/pixel/bug_1072440_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1099446.in b/testing/resources/pixel/bug_1099446.in
new file mode 100644
index 0000000..49d6dae
--- /dev/null
+++ b/testing/resources/pixel/bug_1099446.in
@@ -0,0 +1,65 @@
+{{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
+  /Contents 4 0 R
+  /MediaBox [0 0 200 200]
+  /Resources <<
+    /ExtGState <<
+      /G1 5 0 R
+    >>
+    /Pattern <<
+      /P1 6 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+200 0 m
+0 200 l
+/G1 gs
+/P1 SCN
+/P1 S
+endstream
+endobj
+{{object 5 0}} <<
+  /BM /Diff
+>>
+endobj
+{{object 6 0}} <<
+  /Type /Pattern
+  /PatternType 1
+  /Resources <<
+    /ExtGState <<
+      /G1 5 0 R
+    >>
+    /Pattern <<
+      /P1 6 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+200 0 m
+0 200 l
+/G3 gs
+/P1 S
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1099446_expected.pdf.0.png b/testing/resources/pixel/bug_1099446_expected.pdf.0.png
new file mode 100644
index 0000000..1074bd8
--- /dev/null
+++ b/testing/resources/pixel/bug_1099446_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1116869.in b/testing/resources/pixel/bug_1116869.in
new file mode 100644
index 0000000..d123e38
--- /dev/null
+++ b/testing/resources/pixel/bug_1116869.in
@@ -0,0 +1,117 @@
+{{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 5 0 R
+  /MediaBox [0 0 400 400]
+  /Resources <<
+    /Font <<
+      /F1 4 0 R
+    >>
+    /Pattern <<
+      /P1 6 0 R
+    >>
+    /XObject <<
+      /X10 9 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Times-Roman
+>>
+endobj
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+/X10 Do
+endstream
+endobj
+{{object 6 0}} <<
+  /Type /Pattern
+  /PatternType 2
+  /Shading 7 0 R
+>>
+endobj
+{{object 7 0}} <<
+  /ShadingType 2
+  /ColorSpace /DeviceCMYK
+  /Coords [0.0 0.0 1.0 0.0]
+  /Extend [true true]
+  /Function 8 0 R
+>>
+endobj
+{{object 8 0}} <<
+  /FunctionType 0
+  /BitsPerSample 1
+  /Domain [0.0 1.0]
+  /Filter /ASCIIHexDecode
+  /Range [0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0]
+  /Size [2]
+  {{streamlen}}
+>>
+stream
+ff
+endstream
+endobj
+{{object 9 0}} <<
+  /Subtype /Form
+  /Resources <<
+    /ExtGState <<
+      /G7 10 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+q
+0 0 m
+3 31 l
+/G7 gs
+f
+endstream
+endobj
+{{object 10 0}} <<
+  /SMas <<
+    /G 11 0 R
+  >>
+>>
+endobj
+{{object 11 0}} <<
+  {{streamlen}}
+>>
+stream
+1 1 2 2 re
+W
+100 100 200 200 re s
+W
+0 g
+/F1 12 Tf
+0 0 60 30 re
+W
+m 100 100
+130 150 200 200 250 230 c
+/Pattern cs
+/P1 scn
+(ABC) Tj
+Q
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1116869_expected.pdf.0.png b/testing/resources/pixel/bug_1116869_expected.pdf.0.png
new file mode 100644
index 0000000..1ff3f1f
--- /dev/null
+++ b/testing/resources/pixel/bug_1116869_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1128284.in b/testing/resources/pixel/bug_1128284.in
new file mode 100644
index 0000000..0dfda97
--- /dev/null
+++ b/testing/resources/pixel/bug_1128284.in
@@ -0,0 +1,94 @@
+{{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
+  /Resources <<
+    /Font <<
+      /F1 5 0 R
+    >>
+  >>
+  /MediaBox [0 0 200 200]
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+0 g
+BT
+/F1 .1 Tf 1 0 0 1 100 100 Tm
+[(a)16000(b)17000(c)]TJ
+ET
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /Font
+  /Subtype /Type3
+  /CharProcs <<
+    /a97 6 0 R
+    /a98 7 0 R
+    /a99 6 0 R
+  >>
+  /Encoding 8 0 R
+  /FirstChar 97
+  /FontBBox [0 0 100 100]
+  /LastChar 99
+  /Widths [-100 -50 -75]
+>>
+endobj
+{{object 6 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 7 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+6 0 0 48 6 0 cm
+BI
+/W 6
+/H 48
+/BPC 1
+/IM true
+ID
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+EI
+Q
+endstream
+endobj
+{{object 8 0}} <<
+  /Type /Encoding
+  /BaseEncoding /WinAnsiEncoding
+  /Differences [97 /a97 /a98 /a99]
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1128284_expected.pdf.0.png b/testing/resources/pixel/bug_1128284_expected.pdf.0.png
new file mode 100644
index 0000000..6a0df39
--- /dev/null
+++ b/testing/resources/pixel/bug_1128284_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_113910_expected.pdf.0.png b/testing/resources/pixel/bug_113910_expected.pdf.0.png
index 57c6f08..250ea73 100644
--- a/testing/resources/pixel/bug_113910_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_113910_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_113910_expected_mac.pdf.0.png b/testing/resources/pixel/bug_113910_expected_mac.pdf.0.png
index 5b21f5a..f6d8fca 100644
--- a/testing/resources/pixel/bug_113910_expected_mac.pdf.0.png
+++ b/testing/resources/pixel/bug_113910_expected_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_113910_expected_skia.pdf.0.png b/testing/resources/pixel/bug_113910_expected_skia.pdf.0.png
new file mode 100644
index 0000000..3c3cd81
--- /dev/null
+++ b/testing/resources/pixel/bug_113910_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_113910_expected_win.pdf.0.png b/testing/resources/pixel/bug_113910_expected_win.pdf.0.png
deleted file mode 100644
index 1ff9194..0000000
--- a/testing/resources/pixel/bug_113910_expected_win.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_1161.in b/testing/resources/pixel/bug_1161.in
index 1f02ab5..f3317e1 100644
--- a/testing/resources/pixel/bug_1161.in
+++ b/testing/resources/pixel/bug_1161.in
@@ -21,7 +21,7 @@
 >>
 endobj
 {{object 5 0}} <<
-{{streamlen}}
+  {{streamlen}}
 >>
 stream
 q 1 0 0 1 50 50 cm /X0 Do Q
@@ -48,20 +48,20 @@
 endstream
 endobj
 {{object 7 0}} <<
-/Type /ExtGState
-/ca 0.2
-/CA 1
+  /Type /ExtGState
+  /ca 0.2
+  /CA 1
 >>
 endobj
 {{object 8 0}} <<
-/Type /Pattern
-/TilingType 1
-/PatternType 1
-/BBox [0 0 18 18]
-/PaintType 1
-/YStep 18
-/XStep 18
-{{streamlen}}
+  /Type /Pattern
+  /TilingType 1
+  /PatternType 1
+  /BBox [0 0 18 18]
+  /PaintType 1
+  /YStep 18
+  /XStep 18
+  {{streamlen}}
 >>
 stream
 0 0 0 rg
diff --git a/testing/resources/pixel/bug_1161_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1161_expected_skia.pdf.0.png
new file mode 100644
index 0000000..f6a4fee
--- /dev/null
+++ b/testing/resources/pixel/bug_1161_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1236805.in b/testing/resources/pixel/bug_1236805.in
new file mode 100644
index 0000000..564f048
--- /dev/null
+++ b/testing/resources/pixel/bug_1236805.in
@@ -0,0 +1,86 @@
+{{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
+  /Contents 6 0 R
+  /CropBox [0 0 612 792]
+  /MediaBox [0 0 612 792]
+  /Parent 2 0 R
+  /Resources 7 0 R
+>>
+endobj
+{{object 6 0}} <<
+  {{streamlen}}
+ >>
+stream
+BT
+/T4 1 Tf
+0.12 0 0 -0.12 99.84 684.1801 Tm
+0 g
+/GS1 gs
+0 Tc
+0 Tw
+()Tj
+ET
+endstream
+endobj
+{{object 7 0}} <<
+  /Font <<
+    /T4 11 0 R
+  >>
+  /ProcSet [/PDF /Text]
+>>
+endobj
+{{object 11 0}} <<
+  /Type /Font
+  /Subtype /Type3
+  /CharProcs 12 0 R
+  /Encoding 13 0 R
+  /FirstChar 0
+  /FontBBox [4 -19 53 56]
+  /FontMatrix [1 0.0112920878908041593329204334 0 -1 0 0]
+  /LastChar 4
+  /Name /T4
+  /Widths [60 38 38 38 21]
+>>
+endobj
+{{object 12 0}} <<
+   /CV 17 0 R
+>>
+endobj
+{{object 13 0}} <<
+   /Type /Encoding
+   /Differences [0 /A0 /CU /CV /D2 /CY]
+ >>
+endobj
+{{object 17 0}} <<
+  {{streamlen}}
+>>
+stream
+38 0 5 -19 32 56 d1
+q
+27 0 0 75 5.1 -19.1 cm
+BI
+/W 27
+/H 75
+/BPC 1
+/IM true
+ID
+EI
+Q
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1236805_expected.pdf.0.png b/testing/resources/pixel/bug_1236805_expected.pdf.0.png
new file mode 100644
index 0000000..7d4eebe
--- /dev/null
+++ b/testing/resources/pixel/bug_1236805_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1236_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1236_expected_skia.pdf.0.png
new file mode 100644
index 0000000..248125f
--- /dev/null
+++ b/testing/resources/pixel/bug_1236_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1237898.in b/testing/resources/pixel/bug_1237898.in
new file mode 100644
index 0000000..c45e4c6
--- /dev/null
+++ b/testing/resources/pixel/bug_1237898.in
@@ -0,0 +1,60 @@
+{{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
+  /Annots [4 0 R]
+  /MediaBox [0 0 100 100]
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Btn
+  /Ff 65536
+  /P 3 0 R
+  /BS <<
+    /S /S
+    /W 1
+  >>
+  /MK <<
+    /I 5 0 R
+  >>
+  /N 6 0 R
+  /Rect [1 2 3 4]
+  /T (foo)
+  /TU (bar)
+>>
+endobj
+{{object 5 0}} <<
+  /Type /XObject
+  /Name /F#e9M
+  /FormType 1
+  {{streamlen}}
+>>
+stream
+endstream
+endobj
+{{object 6 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  {{streamlen}}
+>>
+stream
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1237898_expected.pdf.0.png b/testing/resources/pixel/bug_1237898_expected.pdf.0.png
new file mode 100644
index 0000000..319932a
--- /dev/null
+++ b/testing/resources/pixel/bug_1237898_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1241587.in b/testing/resources/pixel/bug_1241587.in
new file mode 100644
index 0000000..61b1637
--- /dev/null
+++ b/testing/resources/pixel/bug_1241587.in
@@ -0,0 +1,78 @@
+{{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
+  /MediaBox [0 0 100 100]
+  /Resources <<
+    /Font <<
+      /F1 5 0 R
+    >>
+  >>
+  /Contents 4 0 R
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+BT
+/F1 1 Tf
+(s) Tj
+ET
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /Font
+  /Subtype /Type3
+  /CharProcs <<
+    /s 6 0 R
+  >>
+  /Encoding <<
+    /Differences [115 /s]
+  >>
+  /FirstChar 115
+  /FontBBox [0 0 1 2]
+  /LastChar 115
+  /Resources <<
+    /XObject <<
+      /Im1 7 0 R
+    >>
+  >>
+>>
+endobj
+{{object 6 0}} <<
+  {{streamlen}}
+>>
+stream
+/Im1 Do
+endstream
+endobj
+{{object 7 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 50
+  /Height 50
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  {{streamlen}}
+>>
+stream
+789cedc2310d00000c03a07f2aaab3ea7bcf03842655555555555555f5bf01cc7818dc
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1241587_expected.pdf.0.png b/testing/resources/pixel/bug_1241587_expected.pdf.0.png
new file mode 100644
index 0000000..319932a
--- /dev/null
+++ b/testing/resources/pixel/bug_1241587_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1258634.in b/testing/resources/pixel/bug_1258634.in
new file mode 100644
index 0000000..4f6c778
--- /dev/null
+++ b/testing/resources/pixel/bug_1258634.in
@@ -0,0 +1,52 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Kids [3 0 R]
+  /Count 1
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 4 0 R
+  /Resources <<
+    /XObject <</Im25 5 0 R>>
+    /ProcSet [/PDF /Text /ImageC /ImageI]
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+50 0 0 50 0 0 cm
+/Im25 Do
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 447
+  /BitsPerComponent 8
+  /Name /X
+  /Height 150
+  /Decode [0.0 255.0]
+  /Filter [/ASCII85Decode /FlateDecode /JPXDecode]
+  {{streamlen}}
+>>
+stream
+GhQG_Yti1j&;L4+&hHI;8ZC3n%U"m$jU!\c,9XuY,s^4`#\,T>=L,1U+n6>\!><`+M:^s'mTe/j=LRYs
+s8.3L+D^;KgeV9U!5mR3B@E<uP']`:c-mCld>-<04O@hs(t9_.OHhdR,`!m>B3Y]5fsTr<!RNbrCD*'p
+pBsV>I8B!]N0Qp5:2ZMS"Y$P]`Nj1F-AG$1/&,f>CDqEZc>b%B?K"ua*C"PE8JAWBAF'tm-j$q6qGfBk
+e[sGH+nbX3p>#O@GMK5P5JOj(TmQF;al^NZ[gDFm:K9qc8>D89+cSi-LGT>%=t\92mfZn.~>
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1258634_expected.pdf.0.png b/testing/resources/pixel/bug_1258634_expected.pdf.0.png
new file mode 100644
index 0000000..f6d66eb
--- /dev/null
+++ b/testing/resources/pixel/bug_1258634_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1258968.in b/testing/resources/pixel/bug_1258968.in
new file mode 100644
index 0000000..bb1318f
--- /dev/null
+++ b/testing/resources/pixel/bug_1258968.in
@@ -0,0 +1,211 @@
+{{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
+  /Contents 12 0 R
+  /MediaBox [0 0 720 540]
+  /Parent 2 0 R
+  /Resources <<
+    /Pattern <<
+      /P1 10 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Mask
+  /BC [1.0]
+  /S /Luminosity
+>>
+endobj
+{{object 5 0}} <<
+  /Type /ExtGState
+  /AIS true
+  /BM /Normal
+  /CA 1.0
+  /OP false
+  /OPM 1
+  /SA true
+  /SMask 4 0 R
+  /ca 1.0
+  /op false
+>>
+endobj
+{{object 6 0}} <<
+  /Bounds [0.300003]
+  /Domain [0.0 1.0]
+  /Encode [0.0 1.0 0.0 1.0]
+  /FunctionType 3
+  /Functions [8 0 R 9 0 R]
+  /Range [0.0 1.0 0.0 1.0 0.0 1.0]
+>>
+endobj
+{{object 7 0}} <<
+  /Filter [/ASCII85Decode /FlateDecode]
+  /N 3
+  {{streamlen}}
+>>
+stream
+GhS^SG>qPn(5L5LGC#t-0Q\.Xmqi'h]h+J9$H('f6Q':!Tns3j'o47^;QNDg`.65@8?@VV+Wr1@%nI7.
+@PE\<W+8BL8pko0n)`[*a1^BaBCBp9fmB@!/c[/h!%oo,Q3&2"-fBc+]@!CJA*DQ/!!>@!!-8.-XR+0H
+0X#F<P-:cF4^6tMr^F#G!@3-O1A2$Oe%u&3BiZQf!!!]a@S8U,RjI''&Z=^t1<&ri&Q9?@`=/N[bSMQR
+@X0[UI:f6M5+gLsbj9Em>K#Nk1YM#/0mAP#F,l>,@O+4W,ro4*Y)%"S==[+5c5#jgEGR[kR10.R,dn(?
+XCMp4M3u3l%s8]Y&ccmHUb=^d$Pm^P"QDeZB4U/r\OjmE\fOM:DJj+-T_i\Kdl7D[EA3TAb2fnnmMY8W
+9O9m_T?mF,1?.$977FX>\$N=o[P0H9U/:l4nS_%TgX#LIjAXAI>43QA^[fQ]!.ZdOWm.t:C^IKLZu6(4
+rn\_TXo/5jMYboTs2B7sid"*2#VtdA9lkAs9t21/M7B4nl[Ltn%=Rb0'Cg7\Q\Y"F8Rr1W"E\Y>=;bfj
+69[OoPKDh2NW2,Zs#BMOo.UO5,]`Z"SgYdL1hBouP,R2!2HR]=i6f*Js4"u:)"o>*SnjH:N?80Yc3-]2
+;ZZH100iBj!/]M^meZC#$c#74n]ctkS,>DCT*5,iY&K*iOj-Vs'^$MU:1jn/3M4pAf+O_W!D!8A:]RL\
+'BfI,?ib(p")n:4^^gR!E"EIZ!Z"<2l$s:b5p9>@8jF9H#'PSZYR`RB-I;fhJ9Gl9>Qe-D%<)shJbrgh
+9Rpb`(;'hZ&-QDb1.6[-+>l\/15%2$#35o4630n2'Fi#K8IuCF6A<bjW!o\ZlC\5U'D*ku)S-2[K*J!\
+cknSKr<g5j&XW]"@22lL2ME$Q/*me%_^jXj3"%?hMrCdW%GUq*KA5=Bn-sUJ*eg6&EsP$e#RsX$N"H9R
+NW^L[80Yo@ef^e[2:@#^+Iu%6EXNaRArsJM%#TY2UPr%[-m-qo'FU1[>(\:peY/"rg/-V(>Gs:+/F"IK
+N)iCeU@$@BkU:Nc3Yu(RY!sL"T0cmS&"tAtY;$k&%ASid`V<i80e&JiQu^Cl9Io6,AcOWIRDWL=$<TZs
+,;ohN`!W^pfNRVrm!7q?FoqOF8&VCc/9"q*(`X&fKWE*5`LXmUi[/XQGU^9`hB!blBB/UR(&17G-b^Ze
+JR9Nj'6FP@KQ'6b@6L<=cpG69GX-LF,SDtjG/Oq9Qai&X6Te,V8fT(i--;5W8FE9UP*!&9FI70$FI2W_
+9IB(e?-"a2!I63+M0t0XM#9_o,%2\S/&@NR.o@tI-8?q=>S8]h/a4aq;R/Qn>4SJ"^Z:=f?:m`1?&C)=
+7]Ke[[+'o]S2<[g>WPD:?+O;;W:Vt3.2f4GNf9kE>GbNbTZe^ME=,%[Ups?*PRWjHb%8]u'gpNJqGL7j
+A^kXsIFMD&)-JKC#h_>nHJ,X1UGRY$6h@.Nd4/fWBZ%3$E[l+4EZDVAE\2<aEqAionh0JQq,7#hq'#QX
+$?QGIKiEcn$LJ02'iBhmMBRkfML-'k/']P?PoQ#j8u5--PjU!<ap-"^b,^a;.ebF=WMlhAX(86[Wa&Gi
+;5L8'W2?LoWLd%Z<hlTRWH$IgeBY*XV9@:ml"Tc.H8g7Q?!5uR?)W3;]ha&B6W[cc7Zg0@`^<IP-:9Rd
+ZV%PsF&kq..o<9CX'+b[2I;lHSZKLt]173S7oq'9B9Q*&cBPKEY-2_oDR8a54gLZc?C"oMhJI\"5!qP7
+IujS'"5(EC+PEFET\g;=Zn^V[mP,\866"SqnVeBF7Z9pYY/WKAc,O6?1m7p',*R26kGDF[0rE]"HV?Ym
+=du7U24E>[QSJ4j0/DuQs4,!%Jn7etESHXml".EVZGZ6eQ(\r5C9Q/.CPm8-od8uWlOPn^2LLu0RqZ(Y
+gN_K/[Nc21,FD?R\8$f-F0f(dGK0'Q]oB_@re15'%`T!X%S%P:QKTs[/88?Em\o*cF?JJ@l9oiRGM;LB
+lE'EtFDc&Hm%Wa]FueV=l)O3@id/iA\XT!+hsHZ_]XtlSCA/)WLkiH0WCNSYN9;tB3mU<&)I?!Ac!Ia5
+f&!I?0DM2gr-c$NN;0FJZ@&-hBDlZF<r7%:PPi>rlhhh0(^0=13Wn>+^VCk@&!gr`jXk<[!^XOd4+\LX
+lNUu*Iij7K#nEpFGnOj5=r>s,7L=t\3u[fRgb$/_r;JIbA\r"a&X!a2&PWl/OWKXMOeYdN;6-I06n:`J
+UH;qh0bH-q@ciu'0&O3e,1\f`,^+EdmY\Xlf2aB(9Nud#:,7hIG;:3[*uTPbr]N&nfta+Nn4hQ+0["KL
+m:&4g]<J?gdi:kQ-"f!\0sNKR.`jDZ8()LbF)lEo%+h%Sa*j*0PHliQ4uFb]E9^n9A6Nb0/j2Ds1f&jm
+b3R>Lc,e'Fa>D*laW/R2ce=dEbP10Ab(d3'A9S<XU7\DkTq64uE%K$YV`s9<DFEp74R"t7?>mPDrg*K(
+!j@3Z=.r["<co.W(ToD2>OB#u^`$l\_O@X8RVRi5:9=%nG@WjFIHpYNMTgr-MdC7VgsB3*;S9/WI&$GU
+jq<L`I`]YXLJ@Y(UGd0PpMI1j;S2%#.D,4uR9<[8g&#ejq=Ur8^T.*EEGORb^'^?e^"Y6qGh[t^4)[>]
+.:$(Q3PH_W7p?_AWjM'AcFBFsWi`;qm3:m0mM`26W9L82Wng_Q^+Qs6W8=YjFgpr0/\C3?YkJRoFkPNT
+:M!nd^3BIbqsPNo51%lRdnkH(F"le8PK&EuT!'#=2]YdY<-IKC@G]tj,G@W=Rr"R_N[c-QBSN"1c-s^B
+O59`Rj-u&Ej-BeL[+;PCi4/:Odr49]*BrG3U?a)bABT2NhsETr3E=c;[H4mB[O8PFG!pN_SG#&#e`kG+
+l?e``&"c]`;h%jACrJEO\`.[gk6oS]?-'Z4F"uq=GZS/%rC^"SDKgkXpKdL-I.`BKPtO9C4m0"0?9NAS
+rn?W&N9fjiCi6WQ>5+Wb_>8pcI5ZLjrO2YF2skL+%P/JW2s<AKnWq4t/%9qFh\]NX1bcRYps)FsaQOZ<
+SZ058G@0.K\[QO-h#m;%dYC^2WuicTCA:[+a4=+WdBd=(A%dr@*oA&PNBd:hqks0%`D=QNW[H=DS#.a6
+c:iRZhgE$5l,9pPB+$LA5>2$hqmkSTms]9PV0=h4G2`]*`T")_0,7e7IV&2PCG'l"dHgGV$hL35']'gT
+bBVe50(RiZ6LK3eqjJ&l+$)X_IseJf^:6`/%I9DR"T~>
+endstream
+endobj
+{{object 8 0}} <<
+  /BitsPerSample 8
+  /Decode [0.0 1.0 0.0 1.0 0.0 1.0]
+  /Domain [0.0 1.0]
+  /Encode [0.0 255.0]
+  /FunctionType 0
+  /Order 1
+  /Range [0.0 1.0 0.0 1.0 0.0 1.0]
+  /Size [256]
+  /Filter [/ASCII85Decode /FlateDecode]
+  {{streamlen}}
+>>
+stream
+GhP$l@s8#P'EukPrU7.2gU>qX[P\^,dq&..1\:=oP+ts]GDY.=PP0gGgdV+ET?;OHG1/`sLjOlq&KI(L
+f!-\HkIq7B&uVaYlSQoV!1g7^3I>]d(N>LlkRoLPlerR``AJ^1laUAaDW2FL2e\0<i3#5WL\l>3'D.A9
+M'G,`P1C:/jXGM1k<+/Y<ITd+C5-&Q2`uGFGN-<%UC[-5cTgAE^1[]9/&(8Tpb%$RVd?*)i\rOj:o!r(
+Y;jmc/hX\'%se]<CW\igDcUQPK,?@ZehBR,ZQ@)Q]b/9f-Fo9Pdsk?A?l!fgUNnD0]niMN^"bAV"XS'/
+=;>VRB!'mj@tXe1W1qj\;-c$4D6r7E%]l8Y~>
+endstream
+endobj
+{{object 9 0}} <<
+  /BitsPerSample 8
+  /Decode [0.0 1.0 0.0 1.0 0.0 1.0]
+  /Domain [0.0 1.0]
+  /Encode [0.0 255.0]
+  /FunctionType 0
+  /Order 1
+  /Range [0.0 1.0 0.0 1.0 0.0 1.0]
+  /Size [256]
+  /Filter [/ASCII85Decode /FlateDecode]
+  {{streamlen}}
+>>
+stream
+GhW&pn(7TS56iq>1%`hbn&#3T)[V<.!'@^]o`~>
+endstream
+endobj
+{{object 10 0}} <<
+  /Type /Pattern
+  /BBox [-79.0947 -75.3227 29.2131 32.9851]
+  /Matrix [2.58008 0.0 0.0 -2.58008 0.0 540.0]
+  /PaintType 1
+  /PatternType 1
+  /Resources <<
+    /ExtGState << /GS0 5 0 R >>
+    /Shading << /Sh0 13 0 R >>
+  >>
+  /TilingType 3
+  /XStep 108.308
+  /YStep 108.308
+  {{streamlen}}
+>>
+stream
+/GS0 gs
+BX /Sh0 sh EX Q
+Q
+endstream
+endobj
+{{object 11 0}} <<
+  /Type /Pattern
+  /BBox [0.0 0.0 10.0 10.0]
+  /Matrix [0.899994 0.0 0.0 -0.899994 0.0 540.0]
+  /PaintType 1
+  /PatternType 1
+  /Resources <<
+    /ExtGState << /GS0 15 0 R >>
+    /ProcSet [/PDF /ImageC]
+  >>
+  /TilingType 3
+  /XStep 10.0
+  /YStep 10.0
+  {{streamlen}}
+>>
+stream
+/GS0 gs
+endstream
+endobj
+{{object 12 0}} <<
+  {{streamlen}}
+>>
+stream
+/P1 scn
+q 1 0 0 1 24.0804 441.1595 cm
+0 0 m
+14.956 18.738 42.588 21.551 61.719 6.282 c
+B*
+endstream
+endobj
+{{object 13 0}} <<
+  /ShadingType 4
+  /AntiAlias false
+  /BitsPerComponent 8
+  /BitsPerCoordinate 32
+  /BitsPerFlag 8
+  /ColorSpace [/ICCBased 7 0 R]
+  /Decode [-79.0947 49.8358 -75.3227 76.1016 0.0 1.0]
+  /Function 6 0 R
+  /Filter [/ASCII85Decode /FlateDecode]
+  {{streamlen}}
+>>
+stream
+GhQY8J:de0msApO^RfKC56Jf5[]KL9Ib"F1@(I<ko)G&.2NW(&f'iVl^SO3H`a9ee^Y3Q0ZIY89s8Vk4
+0+)K'[da=[+W`o"m.eU#2uc&GYr(>85FqT^,V,YdJ+(;u+D](<_>cUbetB6*(-VW2^AJb.F\q5Ps&D?-
+HS=&+rElD6$-7Elci&@,$-39'=C1p_<'1hJopO.gs'@^7+R>rd\c8R"8jKJ.V#NA6dQt1DRfB!CA-K9s
+^;S%N!W[6dO+%~>
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1258968_expected.pdf.0.png b/testing/resources/pixel/bug_1258968_expected.pdf.0.png
new file mode 100644
index 0000000..0770f77
--- /dev/null
+++ b/testing/resources/pixel/bug_1258968_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1258968_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1258968_expected_skia.pdf.0.png
new file mode 100644
index 0000000..18f4279
--- /dev/null
+++ b/testing/resources/pixel/bug_1258968_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1271578.in b/testing/resources/pixel/bug_1271578.in
new file mode 100644
index 0000000..8837f5b
--- /dev/null
+++ b/testing/resources/pixel/bug_1271578.in
@@ -0,0 +1,95 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+  /MediaBox [0 0 100 100]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 4 0 R
+  /Resources <<
+    /Font <<
+      /F1 5 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+BT
+40 30 Td
+/F1 36 Tf
+(!)Tj
+ET
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /Font
+  /Subtype /TrueType
+  /BaseFont /Test
+  /FirstChar 33
+  /FontDescriptor 6 0 R
+  /LastChar 33
+  /ToUnicode 7 0 R
+  /Widths [415]
+>>
+endobj
+{{object 6 0}} <<
+  /Type /FontDescriptor
+  /Ascent 922
+  /CapHeight 1151
+  /Descent -196
+  /Flags 4
+  /FontBBox [0 -228 2000 921]
+  /FontFile2 8 0 R
+  /FontName /Test
+  /ItalicAngle 0
+  /MissingWidth 750
+  /StemV 0
+>>
+endobj
+{{object 7 0}} <<
+  {{streamlen}}
+>>
+stream
+/CIDInit /ProcSet findresource begin 12 dict begin begincmap /CIDSystemInfo <<
+/Registry (Test) /Ordering (UCS) /Supplement 0 >> def
+/CMapName /Test def
+1 begincodespacerange <21> <21> endcodespacerange
+1 beginbfrange
+<21> <21> <0629>
+endbfrange
+endcmap CMapName currentdict /CMap defineresource pop end end
+endstream
+endobj
+{{object 8 0}} <<
+  /Filter [/ASCII85Decode /FlateDecode]
+  {{streamlen}}
+  /Length1 1152
+>>
+stream
+GhV7Y6"got'R_dDS#gHM71g``Z@S[j_4%a(QV`9fkbUmea@WX0RPr-&&s@b[7(`ka2\?Q-3Jf-R,)CL5
++:'#&%pm0q>4<`1=:YRPqIXpiXEsF'?ZtVG5P+m"s7:FX!"@g9'FMfgC$OLFobW-97rRDZR3Q3#5!Kte
+`(BOQMXNDWo^*Ch6f,j"]QUX5UCu-\c8uD,Qf^N7h9H,n#J"'>H?6.=dl3,__9j/A".)HC>)PLCo/k-1
+"r["/>//RcGSl0.rOV.*\(nn.31Ne1G]h?9?>MjaN`CZpVqGa-MKe)6q>QV=&"Q?-pmAY>4Whjs`uq4c
+mV;`O*^=oD*[@G-\RA3RXTOF,W/FDeT#)as6^&HTUgHh!*X1;3AD^HB/!QKb:H@mrGO0<EmLMh\#4llE
+A';]e-+,IKG=UlFe>*J=FbK^:F'=Mm-cDb]6r/02KD#tL3CHuIn4i%?QsJjr7)5oI[)It$92\:,ce-B`
+4sGT-C-n@OG38UMfPkfOIQ-Jj@F(Y.hW2(Iq>+`)XgHXjHl9Ce9a"N+(bCO<)6AYC#4'DR1YAS5CiG&V
+?_<Lh/*K&3/;[j@/)h.n/`OYPgPCV49H9b@JeG(sUVkBV[e96!BUQ4ra!)G#ZWhGe794V,\_:dO2X50t
+2!b.710r>Oi8%b@WH:'*(#][r=j)N:=BIHST\St9pK-?]J,^S!!-4ih@f~>
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1271578_expected.pdf.0.png b/testing/resources/pixel/bug_1271578_expected.pdf.0.png
new file mode 100644
index 0000000..410bbdb
--- /dev/null
+++ b/testing/resources/pixel/bug_1271578_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1271578_expected_agg_mac.pdf.0.png b/testing/resources/pixel/bug_1271578_expected_agg_mac.pdf.0.png
new file mode 100644
index 0000000..7318ef2
--- /dev/null
+++ b/testing/resources/pixel/bug_1271578_expected_agg_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1286_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1286_expected_skia.pdf.0.png
new file mode 100644
index 0000000..b4442e4
--- /dev/null
+++ b/testing/resources/pixel/bug_1286_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1287409.pdf b/testing/resources/pixel/bug_1287409.pdf
new file mode 100644
index 0000000..3973822
--- /dev/null
+++ b/testing/resources/pixel/bug_1287409.pdf
Binary files differ
diff --git a/testing/resources/pixel/bug_1287409_expected.pdf.0.png b/testing/resources/pixel/bug_1287409_expected.pdf.0.png
new file mode 100644
index 0000000..60507e1
--- /dev/null
+++ b/testing/resources/pixel/bug_1287409_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1287409_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1287409_expected_skia.pdf.0.png
new file mode 100644
index 0000000..0b00554
--- /dev/null
+++ b/testing/resources/pixel/bug_1287409_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1288_1_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1288_1_expected_skia.pdf.0.png
new file mode 100644
index 0000000..df6b87e
--- /dev/null
+++ b/testing/resources/pixel/bug_1288_1_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1288_2_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1288_2_expected_skia.pdf.0.png
new file mode 100644
index 0000000..3a8cbee
--- /dev/null
+++ b/testing/resources/pixel/bug_1288_2_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1296_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1296_expected_skia.pdf.0.png
new file mode 100644
index 0000000..828856c
--- /dev/null
+++ b/testing/resources/pixel/bug_1296_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1304714.in b/testing/resources/pixel/bug_1304714.in
new file mode 100644
index 0000000..976d901
--- /dev/null
+++ b/testing/resources/pixel/bug_1304714.in
@@ -0,0 +1,107 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /AcroForm [4 0 R 6 0 R 8 0 R]
+  /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
+  /Annots [4 0 R 6 0 R 8 0 R]
+  /MediaBox [0 0 200 200]
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Tx
+  /P 3 0 R
+  /AP <<
+    /N 5 0 R
+  >>
+  /F 4
+  /Ff 1
+  /Rect [20 10 180 190]
+  /T (Red bottom layer)
+>>
+endobj
+{{object 5 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 160 180]
+  {{streamlen}}
+>>
+stream
+1 0 0 rg
+0 0 160 180 re
+f
+endstream
+endobj
+{{object 6 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Tx
+  /P 3 0 R
+  /AP <<
+    /N 7 0 R
+  >>
+  /F 4
+  /Ff 1
+  /Rect [80 90 130 130]
+  /T (Green middle layer)
+>>
+endobj
+{{object 7 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0.0 0.0 50 40]
+  {{streamlen}}
+>>
+stream
+0 1 0 rg
+0 0 50 40 re
+f
+Q
+endstream
+endobj
+{{object 8 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Tx
+  /P 3 0 R
+  /AP <<
+    /N 9 0 R
+  >>
+  /F 4
+  /Ff 1
+  /Rect [90 100 120 120]
+  /T (Blue top layer)
+>>
+endobj
+{{object 9 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0.0 0.0 30 20]
+  {{streamlen}}
+>>
+stream
+0 0 1 rg
+0 0 30 20 re
+f
+Q
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1304714_expected.pdf.0.png b/testing/resources/pixel/bug_1304714_expected.pdf.0.png
new file mode 100644
index 0000000..58b7600
--- /dev/null
+++ b/testing/resources/pixel/bug_1304714_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1308_1_expected.pdf.0.png b/testing/resources/pixel/bug_1308_1_expected.pdf.0.png
index 44c0446..33a45c0 100644
--- a/testing/resources/pixel/bug_1308_1_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_1308_1_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1308_1_expected_win.pdf.0.png b/testing/resources/pixel/bug_1308_1_expected_win.pdf.0.png
deleted file mode 100644
index 70d0f23..0000000
--- a/testing/resources/pixel/bug_1308_1_expected_win.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_1308_expected.pdf.0.png b/testing/resources/pixel/bug_1308_expected.pdf.0.png
index 1c36944..1013fb1 100644
--- a/testing/resources/pixel/bug_1308_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_1308_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1308_expected_mac.pdf.0.png b/testing/resources/pixel/bug_1308_expected_mac.pdf.0.png
deleted file mode 100644
index 570f992..0000000
--- a/testing/resources/pixel/bug_1308_expected_mac.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_1308_expected_win.pdf.0.png b/testing/resources/pixel/bug_1308_expected_win.pdf.0.png
deleted file mode 100644
index 0acd825..0000000
--- a/testing/resources/pixel/bug_1308_expected_win.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_1330_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1330_expected_skia.pdf.0.png
new file mode 100644
index 0000000..0ae57c7
--- /dev/null
+++ b/testing/resources/pixel/bug_1330_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1338_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1338_expected_skia.pdf.0.png
new file mode 100644
index 0000000..7698e64
--- /dev/null
+++ b/testing/resources/pixel/bug_1338_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1355.in b/testing/resources/pixel/bug_1355.in
new file mode 100644
index 0000000..a00fcf1
--- /dev/null
+++ b/testing/resources/pixel/bug_1355.in
@@ -0,0 +1,85 @@
+{{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 [6 0 R]
+  /Resources 4 0 R
+  /MediaBox [0 0 200 200]
+>>
+endobj
+{{object 4 0}} <<
+  /ProcSet [/PDF /Text]
+  /Font <<
+    /F1 5 0 R
+  >>
+>>
+endobj
+{{object 5 0}} <<
+  /Type /Font
+  /Subtype /Type0
+  /BaseFont /HonMincho-M
+  /Encoding /90pv-RKSJ-H
+  /DescendantFonts [7 0 R]
+>>
+endobj
+{{object 6 0}} <<
+  {{streamlen}}
+>>
+stream
+BT
+/F1 4 Tf
+6 0 0 6 150 150 Tm
+0 0 0 1 k
+<eb5b>Tj
+-10 0 TD
+<eb69>Tj
+0 -8 TD
+<eb6a>Tj
+ET
+endstream
+endobj
+{{object 7 0}} <<
+  /Type /Font
+  /BaseFont /HonMincho-M
+  /CIDSystemInfo <<
+    /Ordering (Japan1)
+    /Registry (Adobe)
+    /Supplement 2
+  >>
+  /DW 1000
+  /FontDescriptor 8 0 R
+  /Subtype /CIDFontType2
+  /W [1 [250] 18 19 500 54 [833] 81 [583]]
+>>
+endobj
+{{object 8 0}} <<
+  /Type /FontDescriptor
+  /Ascent 880
+  /CapHeight 709
+  /Descent -120
+  /Flags 6
+  /FontBBox [-165 -221 1066 952]
+  /FontName /HonMincho-M
+  /ItalicAngle 0
+  /StemV 81
+  /Style <<
+    /Panose <010502020500000000000000>
+  >>
+  /XHeight 450
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1355_expected.pdf.0.png b/testing/resources/pixel/bug_1355_expected.pdf.0.png
new file mode 100644
index 0000000..3bd23af
--- /dev/null
+++ b/testing/resources/pixel/bug_1355_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1355_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1355_expected_skia.pdf.0.png
new file mode 100644
index 0000000..dae811b
--- /dev/null
+++ b/testing/resources/pixel/bug_1355_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1356149.in b/testing/resources/pixel/bug_1356149.in
new file mode 100644
index 0000000..6dd6502
--- /dev/null
+++ b/testing/resources/pixel/bug_1356149.in
@@ -0,0 +1,216 @@
+{{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 100 100]
+  /Resources <<
+    /ProcSet [/PDF /Text]
+    /Font <<
+      /T1_0 5 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+BT
+/T1_0 10 Tf
+-0.02 Tc 0.02 Tw
+1 0 0 1 10 20 Tm
+[(\201)-3.6(\027\036)-5.4(\007)-6.6(\007)-5(\026)-2.5(\034\033)]TJ
+ET
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /JXUIQN+BernhardGothic-Hvy
+  /Encoding 6 0 R
+  /FirstChar 1
+  /FontDescriptor 7 0 R
+  /LastChar 173
+  /Widths [665 576 576 625 576 255 535 616 247 0 250 529 970 540 534 529 531 542
+           518 714 522 238 447 352 372 487 200 399 235 538 499 0 0 0 0 0 0 0 0 0
+           0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+           0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+           0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 543 576 535 0 0 0 0 0 0 0 0 0 0 0 620
+           0 635 561 0 0 0 0 0 0 0 0 0 0 0 0 542 0 0 332 0 0 0 0 0 0 0 0 0 0 0 0
+           500]
+>>
+endobj
+{{object 6 0}} <<
+  /Type /Encoding
+  /BaseEncoding /WinAnsiEncoding
+  /Differences [1 /H /zero /two /N /one /period /o /V /comma /.notdef
+                /quotesingle /E /W /n /d /b /u /p /fi /w /e /l /c /t /r /a
+                /space /s /i /h /T 127 /g /three /S 141 /C 143 /D /B 157 /P 160
+                /f 173 /bullet]
+>>
+endobj
+{{object 7 0}} <<
+  /Type /FontDescriptor
+  /Ascent 1000
+  /CapHeight 666
+  /CharSet (/H /zero /two /N /one /period /o /V /comma /quotesingle /E /W /n /d
+            /b /u /p /fi /w /e /l /c /t /r /a /space /s /i /h /T /g /three /S /C
+            /D /B /P /f /bullet)
+  /Descent -500
+  /Flags 4
+  /FontBBox [-500 -500 1500 1000]
+  /FontFamily (Bernhard Gothic)
+  /FontFile3 8 0 R
+  /FontName /JXUIQN+BernhardGothic-Hvy
+  /FontStretch /Normal
+  /FontWeight 700
+  /ItalicAngle 0
+  /StemV 144
+  /XHeight 472
+>>
+endobj
+{{object 8 0}} <<
+  /Subtype /Type1C
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  {{streamlen}}
+>>
+stream
+789c959769541467bac7ab68abab156d17ac11aab4aa1171178c1963d48c
+0b6e88a8b8a008ca8e022a48d3b2ef427757757575030aa24023c8ee8202
+c60ddce3763489a249266372332766726ecc7827b9f129eecb9c735f265f
+e6e3bda73f749fd3d5effb2cffe7f7fc9b2446b8112449b24161a1ebb76c
+9a1390604c498c31c6af4b352526c5cd0bccc81efed6a072a43a7984cd66
+97a92984c773710c788d8590719031be63f2d8f3130837927cffc399ab66
+bdb778f102c3f6c404c3dad414936155eac1433129d986f529717e730d2b
+83830d5b93f6259ad20d5b13d2138c1909f1810931f80282c42f229120c6
+10c4588218af217c34c42c82f02788f708e28f24b188240274c44682d8ec
+466cd3106104612288830439c140cc20e6127ec47c4d802690d8448410db
+c81d648cee0091e266d46412cdc43704311327488cc087fb1211442ef184
+f4218bc8bfb9e5b97da9d9a2691f9138e247ea20f5423b439bae6da359da
+49bfd0edd6758e9c3cf2e4a88051a65197dcd7ba978f2647078fee1a238c
+393be63ff46efaeca17e3d7a6773a9752e528feeaa9ed041c242d5936981
+0e0a79685b5007a547f76dae5f5c24903f68de210373a2c6e170b5eaba6e
+d6f6f4b277133ede1599941c15dd76e8aa99b7da6c56f67046943185d7a3
+1bc53083bc053334b0e731d3b3bf333636393926b6f340cfc7eded1ff3fa
+12f05057c224b2037828006f8d3a03be61901017b06c59dc000830e5d2d7
+2f5ef62e43061ebcab1988f40516f947ecc94b8de31787c4f9223f16ed79
+8b26821f2cfc193c2195d7db5c83340ed30453342a31e8cfa0590594d526
+5b5951ce510ef2ca7e7b52226ba645ba0cfd932aa5cb964b26314f2af392
+a4e1b06181a2154f4a8d52874ebc606b73b14edaa94a94de0663d525e045
+c25fc1a0f95c6d627e5e43dd69e9eeece1ce9f4a8f4f2d4b294c13920382
+9066f7fae27ccf3988a3d4955a074ca4ac8793c4744ed44e95cf5faaaabd
+f8d4ebcedb8647032c908b5e21b779013b6645f3fa23e0a5ae803f90f02d
+0efaefea1de6f54a473975b9a3b1b69d6b6f4a4f29114b2c2542ce5ee3a1
+d521668be79b8cfb3b37b091f1f1bb6362da6f24f348bb9e9adbf74de88f
+1c3040fc02e39e27df09ec16ae5caa6efe84fd61c997b357fc69d7ca045e
+5f5100132110f4e003e3c947608059e0a38118e8619c4d47ed8ddcb32b7b
+b787462705a615dbcb0f09a2ba8a71ba2ae57aee41cfa1d8a8c8031bf24b
+65255b90c08b42f3806464cb7055e5627ba6fda0e3434f9156d01794486f
+34af284be09d1295fbe8f191071cac00b7ef807d917c2ba853e86d6dba76
+8305adcf1768feb2546bd6525effa400387529f06433ccd2a89fabc0f444
+f977ace45010f247efa3cd681bf8a1f721f8bb9fcedfbe27982bf6f5e734
+992b8b4e7945ed0949dfc819967c0fa361dcabd730e25a6751c23dc1ee6c
+bb79b2d55959d3e0a5ff4b014c563f82a9e4139c7205f86a20013c18f57d
+dad17c546ee0c0fdcf0bd144e4b1f843e4915d6a73640af84a77e6984815
+3e7d547a8f83482cabd9b00b76a00f60210adbb2a1387bad5062a5647158
+2a4a913d4fc9d239f62be9d96c093de44b9be938cbfe23f1bcde88e5f20e
+3c60032ef43d98a9514d83f398a1008bd619ac6ca4cae8217f1a2b4fca90
+f6f262b24d140bd4a59267034c4097acd43bfa4799aad47ea57daa2dd7d6
+c044542f51104443af9dd283c6e6c239b070de45de86b920819f4645837e
+0c5aacc53189ac5c2217c8d9ba4c39af982da5511cb243245d41dbe55a7b
+072fd7c9c7ed4775b2cde610d0222d1e530b2b9be5623957673f2ce795b2
+39f4d0329c84b8564ac1b1157ad96c36c9ccc342ad1d7fb0f3e275e90655
+41c348b0cdc2f3532a658a49bc94226648f93adbf061b0f45f4fcabc784c
+aa954e8b4f3d155a5d4d2bf439c74d471daf7f86679375611a18a018cf7a
+df60005346cb5becc19499b60fed938ba503522c65068383b6dea72c0f6d
+c7ebd9725a863075d2d024aadc26490a5f2d9d96ba79e933ca49cbea24aa
+92969fcbe76c0d72b917be5a61d12c91c29590582b2e4406af2c1f3e1a65
+0d79a834a52fc4d59b83db22c244f231cc80e55872b04f3dcb381b2bb0ce
+07ae47042c0bdfbd24a75476e6086821fcc0c8a5d4b13067dc7e16f7cc9d
+2ea38b715d0ef0e27e5b9654aa33831f8d2f9559a9523a2135880f3c71b0
+f7a82aa77494fbe46675c365e155f79dbffdc4c25434e20d5ab424d5629c
+cdebb30a30f2d661e4f5c14c588869a2dad5d7cc27cb57b47ec4a1f133e6
+a251de8f83607694f02ca3293b894d8a3f101dbee3745f30bf783ab5fec5
+b7897fe1c0ebcd6b18db59da56d02c18afed699fdd51e8f05cd598d27481
+bd78e674df8d4b99117dbc7e3be679394c21610d9e72b5188b64280719ca
+b5caf5069ceb51ed1374517b84368991d675bc75b7b85fcad15960312d39
+ca5e5a7e93ef7b3969e8fc8e56b497ac4d92c3562d7ae91ffede3ef5b7c1
+090cf2be265973e333b68816340235a271d02d3a73bb727b2505cd89b69b
+5dd16d9b6533d887ae8053bd2a2b8d7dc75b2b4e2a0e2f9b6cb397f37af5
+8ff8305f17f93f3b077906f15791ff902f0a56bdd1e6210f345dd5a319f1
+d0f9cff770eb59081f3240d7e087943eb0e01fe0fdfac66f640b1e011f98
+a481bbb080893b9812179f74f642d799ce0b3d1d076279e4842ee6dc2caa
+f1d629e74dee6e8b69478550179b569ec84d5fb6d67ff6972bde5ceda969
+3d23d4ed068fceccaea2dbd2632f3c49d4597353a18bbf7c6855c79fb82d
+9b8b8c6b04bdb100c64229c6ea661779135f1a02ac0636c12ba6b6a3c6d1
+c17d7a39724d40f8ceb529058e5a4c4c08a72a609041f3d27fdf38b2552e
+b267ebec26b9c08c15543eb49a92e81831ab348d8fbcf355da0b0ee6fef7
+2f58919cff2f687474be35374c704006a5371460484b308eac87c91a75b9
+ba943917b5b1610b87a6181081783405084482d7ad87aeae5bc2a6b754da
+3e634932b76ee7cdcf9ef5dd7c72ee6c5e5ab3a0cf2c80f138740f0875e1
+73a6c2c6e1d0ff0e9399ccb47c0b7e3aeadaf3671f5f7f7ca6c69cd122cc
+c7dace9773e52c5e4eb71d29c1d555fb701e26ca422be19412291b8fb056
+5a0ea04e44e7d9e338346e1a72435e681a68a6c2cc81db7537be151c0a55
+5c6f3e738bb5d38aea4e3968e50bc7234abf3f1ff3e238b893f0015c606e
+357434f571fd1753c24f08ed680e9399baaf288e0b0e6fbd9e25c0b73255
+de2657b5b020f8ff2762d174a4c1e97a23ef77de30f5c5d7a7bbfbb19f30
+6259b7e045fc04788d537d8f910d9f48148aa625b31821c6486514ccd65a
+6b6de552934e6ab0553b5905d340e165488291b20c247297a9e71849e7eb
+9a9a9b9a0bb24ef2576024752e34f1782c977aa834df246cda971e8c2694
+d9cacab04dd017a1ede0fe14c640094cc075e4612b081a780bdf33682b6d
+4cca2b4be44276f73f1ce8bf31d0566dcd3f2dc0fc01e6f2aaa5a7f10a9b
+8d081f9c85e7db69e071b1d651d72b6c908cc6f55c6874d5e908210269a8
+d4fb7fce7dcec1b4e72f618ee0901c8e7ff12e9952e8fb158f8ed5f2fa5c
+8cacbfc224d8e822af8337e605ded851836b19b428156b6c98f847ec0572
+8e4ed9604fb2b2c318e5b1c6443a473a2ca5f252a6942b15e94498435b1a
+ac772e6037037be9dab34d156d5c7fa3718b60a525e48b5d90159ba0581e
+ff26bf8cc53e482ae3c14fd1e2c93fefc2114112b691ed96969253fcbd8c
+e09eb5dcce5c8b69bdf02b2ee319a5b7fc0a6ecb73dc963c08247bb0d3bb
+a8c6338ea1780a046db51a4fc9c03157a22fed898c8fd91dd11d7de56a77
+ef75fc8bcf300078177915f7b117db34b94c0e561660bda1ffc22b689198
+644ee261a6432bb6494f1fb0325d0e6f30f21d3f295fe13734df44e9f371
+69be86b178c17ac302bc4eba551fe65846e5ae70161f1284056db2e1e479
+b35428e5f056c02bebb8e4909a75d239a9a61a9fa8403a75b2fdb8d2ce3d
+3895b24428a3d130e18ba41cc9385c895ca94457063369a94a6aedc64550
+7063e653e5f4515be551b641aa976af8ef8b97f5233db7687566989f300c
+f67160c5aba51ea6401a4e4b1d0385ccfad02d9bb686df7efc59ff9dc70f
+2e87ade5815718988ce7974493f12c5348870c68caafd3b0b47c40036ee0
+cdeb0b4b602cd20ea73791bc8b5d70083e0dc2c09b91611b55d5d6e068e4
+9e5e8d58b72e223c2835bdb2de24a0f97014275f11138735e0c0cbd24cc7
+d25952a1f9f7bdec8b511c421575d558cf73c0bdfd070e904704b6f11f2d
+4addb55ad0a3205ccb077859dc012f0d04aa7b19643051d5bb1d9bd03c36
+48dc2a86f345e04b1f819d94c3e674b02f3b2edf3c75cc92d7c077c354aa
+ea708992c2ed4accdab3171fe55f80b3680237f20cf09f02a751ddd58f98
+0b5bf7d486723e4bd62c58752bf467935067a19acaaa0bb3d8cc9cc2d4d8
+9893adc9fc763f2aa6ff5ee63deed7af3f7d7de7e0951dcd427ad5e1cabd
+55ba4395c59527d8fafa93a7da2f651feac2da892c05bdbacd457e3a1cee
+80ba9a413abbfc127b930af9d871d65e6babacc41842067998c3128b9d6a
+899c2fc77896d2d23a2a582ba1118f44096da5acf4cacf37bdeaedade9e8
+e5f7fd48e51db048995c5266cb15018fe1090537438bbdbfc9827df3808b
+ec065f0c6b4ce434358e41be5a7b96dd64648fd0324aa7d2d212f3f67351
+b9cd0382030be5031c4bb9adba9e95ebf09fcc2a1d9a61d6ca264a2eb665
+e7b2221ebacd784ae32b228fa6f121aefb7b9f71575b2acfdf152a1c2776
+c21fdaa8c20bc50f7b70067658441da36be526b99d975df65ab95aa707bc
+39d5401739b813d7158dbe3a1d19d158c8441e28632ea4226e0f240f6dc5
+c430832712c1a4eea0f4a160844c1226438606ec6a28b3312c6c63707fd8
+c3477dfd8f1eeeea0f16f4fbfe8daa10a52e6006feef88dc24fdbf185c8e
+ee0d93a14a5d40e9b3ebd47845390e1b6acb152dcab8dcaad0e0310a7877
+7560a2dacf8cfa5fd09b4ba2
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1356149_expected.pdf.0.png b/testing/resources/pixel/bug_1356149_expected.pdf.0.png
new file mode 100644
index 0000000..93827a8
--- /dev/null
+++ b/testing/resources/pixel/bug_1356149_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1372651.evt b/testing/resources/pixel/bug_1372651.evt
new file mode 100644
index 0000000..eb762eb
--- /dev/null
+++ b/testing/resources/pixel/bug_1372651.evt
@@ -0,0 +1,4 @@
+# Open the dropdown
+mousemove,140,145
+mousedown,left,140,145
+mouseup,left,140,145
diff --git a/testing/resources/pixel/bug_1372651.in b/testing/resources/pixel/bug_1372651.in
new file mode 100644
index 0000000..95b1948
--- /dev/null
+++ b/testing/resources/pixel/bug_1372651.in
@@ -0,0 +1,71 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /AcroForm <<
+    /DA (/Helv 0 Tf 0 g)
+    /DR <<
+      /Font <<
+        /Helv 4 0 R
+      >>
+    >>
+    /Fields [5 0 R 6 0 R]
+  >>
+  /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
+  /Annots [5 0 R 6 0 R]
+  /MediaBox [0 0 200 200]
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+>>
+endobj
+{{object 5 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Ch
+  /DV (Item3)
+  /F 4
+  /Ff 131072
+  /I [2]
+  /MK <<
+    /BG [1.0]
+  >>
+  /Opt [(Item1) (Item2) (Item3)]
+  /P 3 0 R
+  /Rect [70 135 150 155]
+  /T (Dropdown)
+  /V (Item3)
+>>
+endobj
+{{object 6 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Btn
+  /F 4
+  /Ff 65536
+  /MK <<
+    /BG [0.5]
+  >>
+  /P 3 0 R
+  /Rect [50 90 150 110]
+  /T (Button)
+  /TU (Button Tooltip)
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1372651_expected.pdf.0.png b/testing/resources/pixel/bug_1372651_expected.pdf.0.png
new file mode 100644
index 0000000..c7386a1
--- /dev/null
+++ b/testing/resources/pixel/bug_1372651_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1372651_expected_mac.pdf.0.png b/testing/resources/pixel/bug_1372651_expected_mac.pdf.0.png
new file mode 100644
index 0000000..a749d63
--- /dev/null
+++ b/testing/resources/pixel/bug_1372651_expected_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1372651_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1372651_expected_skia.pdf.0.png
new file mode 100644
index 0000000..f1823f3
--- /dev/null
+++ b/testing/resources/pixel/bug_1372651_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1383708.in b/testing/resources/pixel/bug_1383708.in
new file mode 100644
index 0000000..77114f6
--- /dev/null
+++ b/testing/resources/pixel/bug_1383708.in
@@ -0,0 +1,100 @@
+{{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 200 200]
+  /Resources 5 0 R
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+100 0 0 20 50 50 cm
+/I1 Do
+Q
+q
+80 0 0 20 50 100 cm
+/I2 Do
+Q
+endstream
+endobj
+{{object 5 0}} <<
+  /ProcSet [/PDF /ImageB /ImageC /ImageI]
+  /XObject <<
+    /I1 6 0 R
+    /I2 8 0 R
+  >>
+>>
+endobj
+{{object 6 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 1
+  /ColorSpace [/Indexed /DeviceRGB 1 7 0 R]
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  /Height 5
+  /Width 177
+  {{streamlen}}
+>>
+stream
+789cfbff1f1b6860c00eb02afedf80431887215c0094ac4349
+endstream
+endobj
+{{object 7 0}} <<
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  {{streamlen}}
+>>
+stream
+789cbb70e5c6ffffffb90017e80584
+endstream
+endobj
+{{object 8 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace [/Indexed /DeviceRGB 39 9 0 R]
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  /Height 15
+  /Width 58
+  {{streamlen}}
+>>
+stream
+789c9d928b12822010454d7c5510a2166a61befdff3f0c310151a7c93bb0
+ecec70b82c03845c411405f09086b21c0e814e68dba17384ecdf5cfda264
+592a935a818d9b0196b9cd3e39174cd8470830847c9d532ebae74c7ed73c
+a514304ad37ce539c6694e984126711c3f6f3c243ffb945591e49de77997
+2b0f5d0e8dedca77e93925f82185b75f65c793bcce5c808df14564ddf083
+1b9ed57d146062a9d6a418f2f27a0ba03d49b560975cb621442a9cd47e51
+1475822ba236e8e75beab08d8ff4bf3e7d492308
+endstream
+endobj
+{{object 9 0}} <<
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  {{streamlen}}
+>>
+stream
+789c01780087ff2c3339ffcc00ffffcca97600ebd17fe7c855ffdd48cc99
+00f6e9bfffd31dd4a92398873dffffffffee93655e3eb68300ebd067d8bf
+7fdda900ffe361be8b00ffcf0dffd831ffe87ae3bd3dfff3aaddc37fbe91
+18d9a90f333333d5a100fff8beffffddae7b00c89400e7cd7feab600deb2
+24d4a000dba70092a54914
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1383708_expected.pdf.0.png b/testing/resources/pixel/bug_1383708_expected.pdf.0.png
new file mode 100644
index 0000000..800eedc
--- /dev/null
+++ b/testing/resources/pixel/bug_1383708_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1383708_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1383708_expected_skia.pdf.0.png
new file mode 100644
index 0000000..5487865
--- /dev/null
+++ b/testing/resources/pixel/bug_1383708_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1388_2_expected.pdf.0.png b/testing/resources/pixel/bug_1388_2_expected.pdf.0.png
index 422a7e2..347f3e0 100644
--- a/testing/resources/pixel/bug_1388_2_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_1388_2_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1388_2_expected_agg_mac.pdf.0.png b/testing/resources/pixel/bug_1388_2_expected_agg_mac.pdf.0.png
new file mode 100644
index 0000000..2293e85
--- /dev/null
+++ b/testing/resources/pixel/bug_1388_2_expected_agg_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1388_2_expected_mac.pdf.0.png b/testing/resources/pixel/bug_1388_2_expected_mac.pdf.0.png
deleted file mode 100644
index b1a4843..0000000
--- a/testing/resources/pixel/bug_1388_2_expected_mac.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_1388_2_expected_win.pdf.0.png b/testing/resources/pixel/bug_1388_2_expected_win.pdf.0.png
deleted file mode 100644
index 58a14f4..0000000
--- a/testing/resources/pixel/bug_1388_2_expected_win.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_1388_3_expected_agg_mac.pdf.0.png b/testing/resources/pixel/bug_1388_3_expected_agg_mac.pdf.0.png
new file mode 100644
index 0000000..3727440
--- /dev/null
+++ b/testing/resources/pixel/bug_1388_3_expected_agg_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1388_3_expected_mac.pdf.0.png b/testing/resources/pixel/bug_1388_3_expected_mac.pdf.0.png
deleted file mode 100644
index bb97a96..0000000
--- a/testing/resources/pixel/bug_1388_3_expected_mac.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_1388_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1388_expected_skia.pdf.0.png
new file mode 100644
index 0000000..eb348c8
--- /dev/null
+++ b/testing/resources/pixel/bug_1388_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1395648.in b/testing/resources/pixel/bug_1395648.in
new file mode 100644
index 0000000..6c38fb1
--- /dev/null
+++ b/testing/resources/pixel/bug_1395648.in
@@ -0,0 +1,67 @@
+{{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 80 80]
+  /Resources <<
+    /XObject <<
+      /Mask 5 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+40 5 0 60 10 10 cm
+/Mask Do
+Q
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  /Height 50
+  /SMask 6 0 R
+  /Width 50
+  {{streamlen}}
+>>
+stream
+789cedc2310d00000c03a07f2aaab3ea7bcf03842655555555555555f5bf01cc7818dc
+endstream
+endobj
+{{object 6 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceGray
+  /Height 50
+  /Matte [0.0 0.2 1]
+  /Width 50
+  {{streamlen}}
+>>
+stream
+789cabaa1a05a3808e4061148c027a028351300ae809246c128a027e0020065c9c90d
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1395648_expected.pdf.0.png b/testing/resources/pixel/bug_1395648_expected.pdf.0.png
new file mode 100644
index 0000000..4aca65e
--- /dev/null
+++ b/testing/resources/pixel/bug_1395648_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1395648_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1395648_expected_skia.pdf.0.png
new file mode 100644
index 0000000..80a944b
--- /dev/null
+++ b/testing/resources/pixel/bug_1395648_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1396266.in b/testing/resources/pixel/bug_1396266.in
new file mode 100644
index 0000000..fdeaf43
--- /dev/null
+++ b/testing/resources/pixel/bug_1396266.in
@@ -0,0 +1,98 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+
+% A page with scaled copies of a masked image. Any scaled image with an area
+% less than 8 times the stencil mask's original area (64x64 * 8 = 32,768) forces
+% bilinear interpolation of the stencil mask, which triggers the bug.
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 4 0 R
+  /MediaBox [0 0 432 288]
+  /Resources <<
+    /XObject <<
+      /Masked 5 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+
+% 32x32 image has an area of 1,024, so it is interpolated.
+q
+  32 0 0 32 64 240 cm
+  /Masked Do
+Q
+
+% 64x64 image has an area of 4,096, so it is interpolated.
+q
+  64 0 0 64 48 160 cm
+  /Masked Do
+Q
+
+% 128x128 image has an area of 16,384, so it is interpolated.
+q
+  128 0 0 128 16 16 cm
+  /Masked Do
+Q
+
+% 256x256 image has an area of 65,536, so it is not interpolated.
+q
+  256 0 0 256 160 16 cm
+  /Masked Do
+Q
+
+endstream
+endobj
+
+% A 3x3 base image with a stencil mask.
+{{object 5 0}} <<
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter /ASCIIHexDecode
+  /Height 3
+  /Mask 6 0 R
+  /Width 3
+  {{streamlen}}
+>>
+stream
+B8C3E9 7793DB C3CEEF
+8CADF2 1B74E8 BFD5FB
+C2D3FA 9FBDF8 D9E5FC
+endstream
+endobj
+
+% A 64x64 stencil mask with horizontal and vertical lines.
+{{object 6 0}} <<
+  /Subtype /Image
+  /BitsPerComponent 1
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  /Height 64
+  /ImageMask true
+  /Width 64
+  {{streamlen}}
+>>
+stream
+78DA63608080FAFF10E000E5C3687FA8388CF6818A63D0500330E802A83C41BA1EAA9E105D03554F
+36CD0C35876CFA0FD41CDAD3F2FF694D03002512CA0A
+endstream
+endobj
+
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1396266_expected.pdf.0.png b/testing/resources/pixel/bug_1396266_expected.pdf.0.png
new file mode 100644
index 0000000..6cacddf
--- /dev/null
+++ b/testing/resources/pixel/bug_1396266_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1396266_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1396266_expected_skia.pdf.0.png
new file mode 100644
index 0000000..e872c2c
--- /dev/null
+++ b/testing/resources/pixel/bug_1396266_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1402_expected.pdf.0.png b/testing/resources/pixel/bug_1402_expected.pdf.0.png
index cf913bd..751d63f 100644
--- a/testing/resources/pixel/bug_1402_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_1402_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1402_expected_mac.pdf.0.png b/testing/resources/pixel/bug_1402_expected_mac.pdf.0.png
deleted file mode 100644
index 9602820..0000000
--- a/testing/resources/pixel/bug_1402_expected_mac.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_1402_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1402_expected_skia.pdf.0.png
new file mode 100644
index 0000000..f34b78e
--- /dev/null
+++ b/testing/resources/pixel/bug_1402_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1430333.in b/testing/resources/pixel/bug_1430333.in
new file mode 100644
index 0000000..e715f8f
--- /dev/null
+++ b/testing/resources/pixel/bug_1430333.in
@@ -0,0 +1,44 @@
+{{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 200 200]
+  /Resources <<
+    /ExtGState <<
+      /A3 <<
+        /Type /ExtGState
+        /CA 0.5
+        /ca 0.5
+      >>
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+/A3 gs
+-100 10 m
+140 20 l
+b
+Q
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1430333_expected.pdf.0.png b/testing/resources/pixel/bug_1430333_expected.pdf.0.png
new file mode 100644
index 0000000..b9fc3e9
--- /dev/null
+++ b/testing/resources/pixel/bug_1430333_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1430333_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1430333_expected_skia.pdf.0.png
new file mode 100644
index 0000000..e6a1827
--- /dev/null
+++ b/testing/resources/pixel/bug_1430333_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1469.in b/testing/resources/pixel/bug_1469.in
new file mode 100644
index 0000000..8eb970d
--- /dev/null
+++ b/testing/resources/pixel/bug_1469.in
@@ -0,0 +1,98 @@
+{{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 300 100]
+  /Resources <<
+    /XObject <<
+      % All 3 images are BGRA with the same data but interpreted differently.
+      /ImNoSMaskInData 5 0 R
+      /ImSMaskInData0 6 0 R
+      /ImSMaskInData1 7 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+0 1 0 rg
+0 0 300 100 re f
+Q
+q
+64 0 0 64 0 0 cm
+/ImNoSMaskInData Do
+Q
+q
+64 0 0 64 100 0 cm
+/ImSMaskInData0 Do
+Q
+q
+64 0 0 64 200 0 cm
+/ImSMaskInData1 Do
+Q
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter /JPXDecode
+  /Height 64
+  % No /SMaskInData here.
+  /Width 64
+  {{streamlen}}
+>>
+stream
+{{include ../bug_1469.jp2}}
+endstream
+endobj
+{{object 6 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter /JPXDecode
+  /Height 64
+  /SMaskInData 0
+  /Width 64
+  {{streamlen}}
+>>
+stream
+{{include ../bug_1469.jp2}}
+endstream
+endobj
+{{object 7 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter /JPXDecode
+  /Height 64
+  /SMaskInData 1
+  /Width 64
+  {{streamlen}}
+>>
+stream
+{{include ../bug_1469.jp2}}
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1469_expected.pdf.0.png b/testing/resources/pixel/bug_1469_expected.pdf.0.png
new file mode 100644
index 0000000..a87b79d
--- /dev/null
+++ b/testing/resources/pixel/bug_1469_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1491.in b/testing/resources/pixel/bug_1491.in
new file mode 100644
index 0000000..b973b2b
--- /dev/null
+++ b/testing/resources/pixel/bug_1491.in
@@ -0,0 +1,44 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /OpenAction 6 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /MediaBox [ 0 0 200 200 ]
+  /Count 1
+  /Kids [ 3 0 R ]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Pages
+  /Parent 2 0 R
+  /Count 1
+  /Kids [ 4 0 R ]
+>>
+{{object 4 0}} <<
+  /Type /Page
+  /Parent 3 0 R
+  /Contents 5 0 R
+>>
+endobj
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+0.5 0.5 0.5 rg
+50 50 100 100 re B
+endstream
+endobj
+{{object 6 0}} <<
+  /Type /Action
+  /S /GoTo
+  /D [ 3 0 R /Fit ]
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1491_expected.pdf.0.png b/testing/resources/pixel/bug_1491_expected.pdf.0.png
new file mode 100644
index 0000000..21e9375
--- /dev/null
+++ b/testing/resources/pixel/bug_1491_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1491_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1491_expected_skia.pdf.0.png
new file mode 100644
index 0000000..69c5f08
--- /dev/null
+++ b/testing/resources/pixel/bug_1491_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1519.in b/testing/resources/pixel/bug_1519.in
new file mode 100644
index 0000000..d681156
--- /dev/null
+++ b/testing/resources/pixel/bug_1519.in
@@ -0,0 +1,48 @@
+{{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 400 400]
+  /Resources <<
+    /ExtGState <<
+      /GS1 <<
+        /ca 0.5
+      >>
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+/GS1 gs
+0 0 1 rg
+0 0 m
+130 130 l
+150 150 180 180 200 200 c
+400 400 l
+300 300 l
+400 400 l
+300 300 l
+f
+Q
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1519_expected.pdf.0.png b/testing/resources/pixel/bug_1519_expected.pdf.0.png
new file mode 100644
index 0000000..4a6cc19
--- /dev/null
+++ b/testing/resources/pixel/bug_1519_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1546.in b/testing/resources/pixel/bug_1546.in
new file mode 100644
index 0000000..fb423d0
--- /dev/null
+++ b/testing/resources/pixel/bug_1546.in
@@ -0,0 +1,77 @@
+{{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
+  /Resources <<
+    /Shading <<
+      /S0 5 0 R
+    >>
+  >>
+  /Contents 4 0 R
+  /MediaBox [0 0 200 300]
+>>
+endobj
+{{object 4 0}} <<
+  {streamlen}}
+>>
+stream
+/S0 sh
+endstream
+endobj
+{{object 5 0}} <<
+  /ShadingType 4
+  /BitsPerComponent 8
+  /BitsPerCoordinate 16
+  /BitsPerFlag 8
+  /ColorSpace /DeviceRGB
+  /Decode [-32768 32767 -32768 32767 0 1]
+  /Filter /ASCIIHexDecode
+  /Function 6 0 R
+  {{streamlen}}
+>>
+stream
+00800a800a0000800a80c8ff00806480c800
+endstream
+endobj
+{{object 6 0}} <<
+  /FunctionType 3
+  /Bounds [0.5]
+  /Domain [0 1]
+  /Encode [0 1 0 1]
+  /Functions [7 0 R 8 0 R]
+  /Range [0 1 0 1 0 1]
+>>
+endobj
+{{object 7 0}} <<
+  /FunctionType 2
+  /C0 [1 0 0]
+  /C1 [0 1 0]
+  /Domain [0 1]
+  /N 1
+  /Range [0 1 0 1 0 1]
+>>
+endobj
+{{object 8 0}} <<
+  /FunctionType 2
+  /C0 [0 1 0]
+  /C1 [0 0 1]
+  /Domain [0 1]
+  /N 1
+  /Range [0 1 0 1 0 1]
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1546_expected.pdf.0.png b/testing/resources/pixel/bug_1546_expected.pdf.0.png
new file mode 100644
index 0000000..e993bf1
--- /dev/null
+++ b/testing/resources/pixel/bug_1546_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1571.in b/testing/resources/pixel/bug_1571.in
new file mode 100644
index 0000000..b4a94e1
--- /dev/null
+++ b/testing/resources/pixel/bug_1571.in
@@ -0,0 +1,112 @@
+{{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
+  /MediaBox [0 0 200 200]
+  /Contents 4 0 R
+  /Resources <<
+    /ProcSet [/PDF /ImageB /ImageC /ImageI]
+    /ExtGState <<
+      /GS1 5 0 R
+      /GS3 6 0 R
+    >>
+    /Pattern <<
+      /Pa2 7 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+1 0 0 1 50 100 cm
+1 1 1 RG
+/GS3 gs
+/Pattern cs
+/Pa2 scn
+/GS1 gs
+-7 7 m
+-7 -7 l
+-7 -7 l
+7 -7 l
+7 -7 l
+7 7 l
+7 7 l
+-7 7 l
+h
+B*
+Q
+q
+1 0 0 1 150 100 cm
+/Pattern cs
+/Pa2 scn
+/GS1 gs
+-7 7 m
+-7 -7 l
+-7 -7 l
+7 -7 l
+7 -7 l
+7 7 l
+7 7 l
+-7 7 l
+h
+B*
+Q
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /ExtGState
+  /ca 1
+>>
+endobj
+{{object 6 0}} <<
+  /Type /ExtGState
+  /CA 0
+>>
+endobj
+{{object 7 0}} <<
+  /Type /Pattern
+  /PaintType 1
+  /PatternType 1
+  /TilingType 2
+  /BBox [0 0 0.25 0.25]
+  /Matrix [1.414 -1.414 1.414 1.414 -95.043 -381.294]
+  /PaintType 1
+  /Resources <<
+    % Acrobat requires this dictionary, even if it is empty.
+  >>
+  /XStep 0.25
+  /YStep 0.25
+  {{streamlen}}
+>>
+stream
+/DeviceRGB CS 0.941 0 0 SC
+/DeviceRGB cs 1 1 1 sc
+0 0 0.25 0.25 re
+f
+0.094 w
+0 0 m
+0.25 0 l
+0.094 w
+0.125 0 m
+0.125 0.25 l
+S
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1571_expected.pdf.0.png b/testing/resources/pixel/bug_1571_expected.pdf.0.png
new file mode 100644
index 0000000..e3d54b8
--- /dev/null
+++ b/testing/resources/pixel/bug_1571_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1638.in b/testing/resources/pixel/bug_1638.in
new file mode 100644
index 0000000..f6dea38
--- /dev/null
+++ b/testing/resources/pixel/bug_1638.in
@@ -0,0 +1,57 @@
+{{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 400 400]
+  /Resources <<
+    /ExtGState <<
+      /GS1 <<
+        /ca 1.0
+      >>
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+/GS1 gs
+0 0 1 rg
+% The 1st sub path.
+50 350 m
+200 320 l
+50 350 l
+% The 2nd sub path.
+100 300 m
+50 300 l
+200 300 l
+300 200 l
+270 230 l
+% The 3rd sub path.
+200 50 m
+350 50 l
+200 50 l
+200 100 l
+200 50 l
+f
+Q
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1638_expected.pdf.0.png b/testing/resources/pixel/bug_1638_expected.pdf.0.png
new file mode 100644
index 0000000..23a39d5
--- /dev/null
+++ b/testing/resources/pixel/bug_1638_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1638_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1638_expected_skia.pdf.0.png
new file mode 100644
index 0000000..7ef152f
--- /dev/null
+++ b/testing/resources/pixel/bug_1638_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1639_1.in b/testing/resources/pixel/bug_1639_1.in
new file mode 100644
index 0000000..f283af7
--- /dev/null
+++ b/testing/resources/pixel/bug_1639_1.in
@@ -0,0 +1,50 @@
+{{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 200 200]
+  /Resources <<
+    /ExtGState <<
+      /GS1 <<
+        /ca 1.0
+      >>
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+/GS1 gs
+0 0 1 rg
+% A horizontal path.
+20 180 m
+180 180 l
+% A vertical path.
+50 160 m
+50 100 l
+% A diagonal path.
+20 50 m
+180 100 l
+f
+Q
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1639_1_expected.pdf.0.png b/testing/resources/pixel/bug_1639_1_expected.pdf.0.png
new file mode 100644
index 0000000..2734462
--- /dev/null
+++ b/testing/resources/pixel/bug_1639_1_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1639_1_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1639_1_expected_skia.pdf.0.png
new file mode 100644
index 0000000..fa53f12
--- /dev/null
+++ b/testing/resources/pixel/bug_1639_1_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1693.in b/testing/resources/pixel/bug_1693.in
new file mode 100644
index 0000000..e59b5f8
--- /dev/null
+++ b/testing/resources/pixel/bug_1693.in
@@ -0,0 +1,101 @@
+{{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
+  /MediaBox [0 0 200 200]
+  /Resources <<
+    /ProcSet [/PDF /ImageC]
+    /ExtGState <<
+      /G3 4 0 R
+      /G8 5 0 R
+    >>
+    /Pattern <<
+      /P7 6 0 R
+    >>
+  >>
+  /Contents 7 0 R
+>>
+endobj
+{{object 4 0}} <<
+  /BM /Normal
+  /ca 1
+>>
+endobj
+{{object 5 0}} <<
+  /BM /Normal
+  /ca .5
+>>
+endobj
+{{object 6 0}} <<
+  /Type /Pattern
+  /PaintType 1
+  /PatternType 1
+  /TilingType 1
+  /BBox [0 0 400 400]
+  /Matrix [256 0 0 32 0 0]
+  /XStep 512
+  /YStep 512
+  /Resources <<
+    /ProcSet [/PDF /ImageC]
+    /ExtGState <<
+      /G3 4 0 R
+    >>
+    /XObject <<
+      /X4 8 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+q
+1 0 0 -8 0 8 cm
+/G3 gs
+/X4 Do
+Q
+endstream
+endobj
+{{object 7 0}} <<
+  {{streamlen}}
+>>
+stream
+1 1 1 RG
+1 1 1 rg
+/G3 gs
+/Pattern CS
+/Pattern cs
+/P7 SCN
+/P7 scn
+/G8 gs
+0 0 200 150 re
+f
+endstream
+endobj
+{{object 8 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 50
+  /Height 50
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  {{streamlen}}
+>>
+stream
+789cedc2310d00000c03a07f2aaab3ea7bcf03842655555555555555f5bf01cc7818dc
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1693_expected.pdf.0.png b/testing/resources/pixel/bug_1693_expected.pdf.0.png
new file mode 100644
index 0000000..d65bd0d
--- /dev/null
+++ b/testing/resources/pixel/bug_1693_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1723.in b/testing/resources/pixel/bug_1723.in
new file mode 100644
index 0000000..aac04d2
--- /dev/null
+++ b/testing/resources/pixel/bug_1723.in
@@ -0,0 +1,61 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+  /MediaBox [0 0 300 400]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents [4 0 R]
+  /Resources <<
+    /ColorSpace <<
+      /DefaultCMYK /DeviceRGB
+    >>
+    /XObject <<
+      /Img 5 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+200 0 0 300 50 50 cm
+/Img Do
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceCMYK
+  /Filter /ASCIIHexDecode
+  /Height 8
+  /Width 8
+  {{streamlen}}
+>>
+stream
+FF000000 FF000000 FF000000 FF000000   00FF0000 00FF0000 00FF0000 00FF0000
+FF000000 FF000000 FF000000 FF000000   00FF0000 00FF0000 00FF0000 00FF0000
+FF000000 FF000000 FF000000 FF000000   00FF0000 00FF0000 00FF0000 00FF0000
+FF000000 FF000000 FF000000 FF000000   00FF0000 00FF0000 00FF0000 00FF0000
+
+0000FF00 0000FF00 0000FF00 0000FF00   000000FF 000000FF 000000FF 000000FF
+0000FF00 0000FF00 0000FF00 0000FF00   000000FF 000000FF 000000FF 000000FF
+0000FF00 0000FF00 0000FF00 0000FF00   000000FF 000000FF 000000FF 000000FF
+0000FF00 0000FF00 0000FF00 0000FF00   000000FF 000000FF 000000FF 000000FF
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1723_expected.pdf.0.png b/testing/resources/pixel/bug_1723_expected.pdf.0.png
new file mode 100644
index 0000000..46dceb7
--- /dev/null
+++ b/testing/resources/pixel/bug_1723_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1733.in b/testing/resources/pixel/bug_1733.in
new file mode 100644
index 0000000..9812a03
--- /dev/null
+++ b/testing/resources/pixel/bug_1733.in
@@ -0,0 +1,107 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /MediaBox [0 0 100 100]
+  /Count 2
+  /Kids [3 0 R 4 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 5 0 R
+  /Resources <<
+    /XObject 9 0 R
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 5 0 R
+  /Resources <<
+    /XObject 10 0 R
+  >>
+>>
+endobj
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+100 0 0 100 0 0 cm
+/X1 Do
+Q
+endstream
+endobj
+{{object 6 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 1
+  /Height 1
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter /ASCIIHexDecode
+  {{streamlen}}
+>>
+stream
+FF0000
+endstream
+endobj
+{{object 7 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 1
+  /Height 1
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter /ASCIIHexDecode
+  {{streamlen}}
+>>
+stream
+FFFF00
+endstream
+endobj
+% This object stream contains two different copies of object 9 and object 10.
+% To disambiguate them, a parser must use object 11 0 below, the cross-reference
+% stream, to look up the type 2 entries. Those entries reference this object,
+% and the position of the objects within this object.
+{{object 8 0}} <<
+  /Type /ObjStm
+  /N 4
+  /First 20
+  {{streamlen}}
+>>
+stream
+9 0 9 13 10 26 10 39<</X1 6 0 R>><</X1 7 0 R>><</X1 6 0 R>><</X1 7 0 R>>
+endstream
+endobj
+{{object 11 0}} <<
+  /Type /XRef
+  /Filter /ASCIIHexDecode
+  /Root 1 0 R
+  /Size 11
+  /W [1 2 2]
+  {{streamlen}}
+>>
+stream
+00 0000 FFFF
+01 000F 0000
+01 0044 0000
+01 00A3 0000
+01 0110 0000
+01 017E 0000
+01 01CF 0000
+01 028B 0000
+01 046A 0000
+02 0008 0000
+02 0008 0003
+endstream
+endobj
+{{startxrefobj 11 0}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1733_expected.pdf.0.png b/testing/resources/pixel/bug_1733_expected.pdf.0.png
new file mode 100644
index 0000000..d96c847
--- /dev/null
+++ b/testing/resources/pixel/bug_1733_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1733_expected.pdf.1.png b/testing/resources/pixel/bug_1733_expected.pdf.1.png
new file mode 100644
index 0000000..d1490da
--- /dev/null
+++ b/testing/resources/pixel/bug_1733_expected.pdf.1.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1746.in b/testing/resources/pixel/bug_1746.in
new file mode 100644
index 0000000..ca2a4b2
--- /dev/null
+++ b/testing/resources/pixel/bug_1746.in
@@ -0,0 +1,122 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /MediaBox [0 0 200 200]
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 4 0 R
+  /Resources <<
+    /ExtGState <<
+      /GS0 8 0 R
+    >>
+    /Font <<
+      /F1 5 0 R
+    >>
+    /XObject <<
+      /Img 9 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+/GS0 gs
+q
+0 1 0 rg
+BT
+/F1 2 Tf
+1 0 0 1 50 50 Tm
+(a)Tj
+ET
+Q
+q
+0 0 1 rg
+BT
+/F1 2 Tf
+1 0 0 1 72 80 Tm
+(a)Tj
+ET
+Q
+Q
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /Font
+  /Subtype /Type3
+  /CharProcs <<
+    /a0 7 0 R
+  >>
+  /Encoding 6 0 R
+  /FirstChar 97
+  /FontBBox [0 0 1000 1000]
+  /FontMatrix [1 0 0 1 0 0]
+  /LastChar 97
+  /Widths [60]
+>>
+endobj
+{{object 6 0}} <<
+  /Type /Encoding
+  /BaseEncoding /WinAnsiEncoding
+  /Differences [97 /a0]
+>>
+endobj
+{{object 7 0}} <<
+  {{streamlen}}
+>>
+stream
+50 0 4 -1 48 45 d1
+q
+4 -1 m
+4 45 l
+48 45 l
+48 -1 l
+h
+W n
+q
+44 0 0 46 4.1 -1.1 cm
+/Img Do
+Q
+Q
+endstream
+endobj
+{{object 8 0}} <<
+  /Type /ExtGState
+  /CA 0.5
+  /ca 0.5
+>>
+endobj
+{{object 9 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 1
+  /Decode [1 0]
+  /DecodeParms [null <</Columns 44 /K -1>>]
+  /Filter [/ASCIIHexDecode /CCITTFaxDecode]
+  /Height 46
+  /ImageMask true
+  /Width 44
+  {{streamlen}}
+>>
+stream
+26a08680de081e11e187840830f4137a4df0ef4dbedbffff6ffdaf0c2f1f
+fff21b34c82e33044e7c11a09c205e105e97a5e97a5ffa5fe0a3f5ffafff
+b5c9aaa30bed27adb4ad70da4da5b6128f0c426b216818500100100a
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1746_expected.pdf.0.png b/testing/resources/pixel/bug_1746_expected.pdf.0.png
new file mode 100644
index 0000000..08c41d1
--- /dev/null
+++ b/testing/resources/pixel/bug_1746_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1746_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1746_expected_skia.pdf.0.png
new file mode 100644
index 0000000..0ab21f9
--- /dev/null
+++ b/testing/resources/pixel/bug_1746_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1750.in b/testing/resources/pixel/bug_1750.in
new file mode 100644
index 0000000..ce0f46f
--- /dev/null
+++ b/testing/resources/pixel/bug_1750.in
@@ -0,0 +1,83 @@
+{{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 200 100]
+  /Resources <<
+    /XObject <<
+      /Img1 6 0 R
+      /Img2 8 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+60 0 0 60 20 20 cm
+/Img1 Do
+Q
+q
+60 0 0 60 120 20 cm
+/Img2 Do
+Q
+endstream
+endobj
+{{object 5 0}} [
+  /Indexed
+  /DeviceGray
+  1
+  <88 cc>
+]
+endobj
+{{object 6 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 1
+  /ColorSpace 5 0 R
+  /Height 4
+  /Width 4
+  {{streamlen}}
+>>
+stream
+0000
+endstream
+endobj
+{{object 7 0}} [
+  /Indexed
+  /DeviceGray
+  3
+  <11 44 88 cc>
+]
+endobj
+{{object 8 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 1
+  /ColorSpace 7 0 R
+  /Height 4
+  /Width 4
+  {{streamlen}}
+>>
+stream
+0000
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1750_expected.pdf.0.png b/testing/resources/pixel/bug_1750_expected.pdf.0.png
new file mode 100644
index 0000000..b574e46
--- /dev/null
+++ b/testing/resources/pixel/bug_1750_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1752.in b/testing/resources/pixel/bug_1752.in
new file mode 100644
index 0000000..0ba4a41
--- /dev/null
+++ b/testing/resources/pixel/bug_1752.in
@@ -0,0 +1,75 @@
+{{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
+    >>
+  >>
+  /Contents 6 0 R
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Font
+  /Subtype /TrueType
+  /BaseFont /NotoSansRegular
+  /Encoding /WinAnsiEncoding
+  /FirstChar 65
+  /LastChar 71
+  /FontDescriptor 5 0 R
+  /Name /F1
+  /Widths [250 250 250 250 800 800 800]
+>>
+endobj
+{{object 5 0}} <<
+  /Type /FontDescriptor
+  /CapHeight 750
+  /Descent -250
+  /Flags 32
+  /FontBBox [-503 -250 1240 750]
+  /FontFile2 7 0 R
+  /FontName /NotoSansRegular
+  /FontWeight 400
+  /ItalicAngle 0
+  /StemV 52
+>>
+endobj
+{{object 6 0}} <<
+  {{streamlen}}
+>>
+stream
+BT
+20 100 Td
+/F1 70 Tf
+(ABCD) Tj
+0 -80 Td
+(EFG) Tj
+ET
+endstream
+endobj
+{{object 7 0}} <<
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  {{streamlen}}
+  /Length1 11200
+>>
+stream
+{{include ../bug_1752_truetype_font.fragment}}
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1752_expected.pdf.0.png b/testing/resources/pixel/bug_1752_expected.pdf.0.png
new file mode 100644
index 0000000..ed9be10
--- /dev/null
+++ b/testing/resources/pixel/bug_1752_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1752_expected_mac.pdf.0.png b/testing/resources/pixel/bug_1752_expected_mac.pdf.0.png
new file mode 100644
index 0000000..a8cb3ba
--- /dev/null
+++ b/testing/resources/pixel/bug_1752_expected_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1752_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1752_expected_skia.pdf.0.png
new file mode 100644
index 0000000..9cb41b8
--- /dev/null
+++ b/testing/resources/pixel/bug_1752_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1772.in b/testing/resources/pixel/bug_1772.in
new file mode 100644
index 0000000..026b713
--- /dev/null
+++ b/testing/resources/pixel/bug_1772.in
@@ -0,0 +1,93 @@
+{{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 100 100]
+  /Resources <<
+    /ProcSet [/PDF /Text]
+    /ColorSpace <<
+      /CS1 [/Pattern]
+    >>
+    /Font <<
+      /F1 5 0 R
+    >>
+    /Pattern <<
+      /P1 6 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+BT
+/CS1 CS
+/P1 SCN
+/F1 1 Tf
+1 Tr
+20 0 0 20 20 30 Tm
+(S) Tj
+ET
+BT
+/CS1 CS
+/P1 SCN
+/F1 4 Tf
+1 Tr
+5 0 0 5 50 80 Tm
+(S) Tj
+ET
+BT
+/CS1 CS
+/P1 SCN
+/F1 20 Tf
+1 Tr
+1 0 0 1 70 40 Tm
+(S) Tj
+ET
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+>>
+endobj
+{{object 6 0}} <<
+  /Type /Pattern
+  /PatternType 2
+  /Shading 7 0 R
+>>
+endobj
+{{object 7 0}} <<
+  /ShadingType 3
+  /ColorSpace /DeviceRGB
+  /Coords [0.0 0.0 0.0 0.0 0.0 0.005] % Concentric circles
+  /Function 8 0 R
+  /Extend [true true]
+ >>
+endobj
+{{object 8 0}} <<
+  /FunctionType 2
+  /Domain [0.0 1.0]
+  /C0 [0 0 0]
+  /C1 [0 1 0]
+  /N 1
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1772_expected.pdf.0.png b/testing/resources/pixel/bug_1772_expected.pdf.0.png
new file mode 100644
index 0000000..7056d87
--- /dev/null
+++ b/testing/resources/pixel/bug_1772_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1772_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1772_expected_skia.pdf.0.png
new file mode 100644
index 0000000..477b2a2
--- /dev/null
+++ b/testing/resources/pixel/bug_1772_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1774.in b/testing/resources/pixel/bug_1774.in
new file mode 100644
index 0000000..d80b429
--- /dev/null
+++ b/testing/resources/pixel/bug_1774.in
@@ -0,0 +1,47 @@
+{{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
+  /MediaBox [0 0 200 200]
+  /Contents 4 0 R
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+0.001 w
+30 150 m
+170 150 l
+S
+Q
+q
+0.01 w
+30 95 m
+170 95 l
+S
+Q
+q
+0.1 w
+30 40 m
+170 40 l
+S
+Q
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1774_expected.pdf.0.png b/testing/resources/pixel/bug_1774_expected.pdf.0.png
new file mode 100644
index 0000000..32bcba3
--- /dev/null
+++ b/testing/resources/pixel/bug_1774_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1774_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1774_expected_skia.pdf.0.png
new file mode 100644
index 0000000..40ec74e
--- /dev/null
+++ b/testing/resources/pixel/bug_1774_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1822.in b/testing/resources/pixel/bug_1822.in
new file mode 100644
index 0000000..4075bb7
--- /dev/null
+++ b/testing/resources/pixel/bug_1822.in
@@ -0,0 +1,34 @@
+{{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 400 400]
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+[1.8 1.8] 96636760 d
+1 i
+100 300 m
+200 300 l
+S
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1822_expected.pdf.0.png b/testing/resources/pixel/bug_1822_expected.pdf.0.png
new file mode 100644
index 0000000..913f33f
--- /dev/null
+++ b/testing/resources/pixel/bug_1822_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1822_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1822_expected_skia.pdf.0.png
new file mode 100644
index 0000000..2467b79
--- /dev/null
+++ b/testing/resources/pixel/bug_1822_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1845.in b/testing/resources/pixel/bug_1845.in
new file mode 100644
index 0000000..9fd8052
--- /dev/null
+++ b/testing/resources/pixel/bug_1845.in
@@ -0,0 +1,80 @@
+{{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 96 96]
+  /Resources <<
+    /XObject <<
+      /X0 5 0 R
+    >>
+  >>
+>>
+endobj
+
+% Cross formed by red horizontal rectangle overlaid with blue vertical
+% rectangle.
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+  % Red horizontal rectangle defined by clip.
+  8 32 80 32 re W* n
+  1 0 0 rg
+  0 0 96 96 re f
+Q
+q
+  % Blue vertical rectangle defined by masked image.
+  32 0 0 80 32 8 cm
+  /X0 Do
+Q
+endstream
+endobj
+
+% Single pixel image with /SMask to trigger masked image rendering.
+{{object 5 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 1
+  /Height 1
+  /ColorSpace /DeviceRGB
+  /BitsPerComponent 8
+  /SMask 6 0 R
+  /Filter /ASCIIHexDecode
+  {{streamlen}}
+>>
+stream
+00 00 FF
+endstream
+endobj
+{{object 6 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 1
+  /Height 1
+  /ColorSpace /DeviceGray
+  /BitsPerComponent 8
+  /Filter /ASCIIHexDecode
+  {{streamlen}}
+>>
+stream
+80
+endstream
+endobj
+
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1845_expected.pdf.0.png b/testing/resources/pixel/bug_1845_expected.pdf.0.png
new file mode 100644
index 0000000..b246272
--- /dev/null
+++ b/testing/resources/pixel/bug_1845_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1847.in b/testing/resources/pixel/bug_1847.in
new file mode 100644
index 0000000..42d4ef9
--- /dev/null
+++ b/testing/resources/pixel/bug_1847.in
@@ -0,0 +1,65 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /MediaBox [0 0 400 400]
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Annots [4 0 R]
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Annot
+  /Subtype /Highlight
+  /AP <<
+    /N 5 0 R
+  >>
+  /F 4
+  /P 3 0 R
+  /Rect 6 0 R
+>>
+endobj
+{{object 5 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox 6 0 R
+  /ProcSet [/PDF]
+  /Resources <<
+    /ExtGState <<
+      /R0 <<
+        /Type /ExtGState
+        /AIS false
+        /BM /Multiply
+      >>
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/R0 gs
+1 1 0 rg
+1 w
+72 305 m
+68 309 68 317 72 321 c
+132 321 l
+136 317 136 309 132 305 c
+f
+endstream
+endobj
+{{object 6 0}}
+[67 304 137 322]
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1847_expected.pdf.0.png b/testing/resources/pixel/bug_1847_expected.pdf.0.png
new file mode 100644
index 0000000..1e9d7fb
--- /dev/null
+++ b/testing/resources/pixel/bug_1847_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1847_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1847_expected_skia.pdf.0.png
new file mode 100644
index 0000000..f201f8e
--- /dev/null
+++ b/testing/resources/pixel/bug_1847_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1883.in b/testing/resources/pixel/bug_1883.in
new file mode 100644
index 0000000..79593bb
--- /dev/null
+++ b/testing/resources/pixel/bug_1883.in
@@ -0,0 +1,92 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 4
+  /Kids [3 0 R 4 0 R 5 0 R 6 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Annots [7 0 R 8 0 R]
+  /MediaBox [0 0 612 792]
+  /Parent 2 0 R
+  /Rotate 0
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Page
+  /Annots [7 0 R 8 0 R]
+  /MediaBox [0 0 792 612]
+  /Parent 2 0 R
+  /Rotate 90
+>>
+endobj
+{{object 5 0}} <<
+  /Type /Page
+  /Annots [7 0 R 8 0 R]
+  /MediaBox [0 0 612 792]
+  /Parent 2 0 R
+  /Rotate 180
+>>
+endobj
+{{object 6 0}} <<
+  /Type /Page
+  /Annots [7 0 R 8 0 R]
+  /MediaBox [0 0 792 612]
+  /Parent 2 0 R
+  /Rotate 270
+>>
+endobj
+{{object 7 0}} <<
+  /Type /Annot
+  /Subtype /Line
+  /AP <<
+    /N 9 0 R
+  >>
+  % NoRotate
+  /F 16
+  /L [100 50 100 150]
+  /P 3 0 R
+  /Rect [90 370 270 500]
+>>
+endobj
+{{object 8 0}} <<
+  /Type /Annot
+  /Subtype /Line
+  /AP <<
+    /N 9 0 R
+  >>
+  /F 0
+  /L [100 50 100 150]
+  /P 3 0 R
+  /Rect [190 470 370 600]
+>>
+endobj
+{{object 9 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 360 130]
+  {{streamlen}}
+>>
+stream
+10 w
+1 0 0 RG
+30 65 m
+150 65 l
+S
+120 45 m
+150 65 l
+120 85 l
+S
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1883_expected.pdf.0.png b/testing/resources/pixel/bug_1883_expected.pdf.0.png
new file mode 100644
index 0000000..4bc6992
--- /dev/null
+++ b/testing/resources/pixel/bug_1883_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1883_expected.pdf.1.png b/testing/resources/pixel/bug_1883_expected.pdf.1.png
new file mode 100644
index 0000000..f18c1d7
--- /dev/null
+++ b/testing/resources/pixel/bug_1883_expected.pdf.1.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1883_expected.pdf.2.png b/testing/resources/pixel/bug_1883_expected.pdf.2.png
new file mode 100644
index 0000000..a3093ff
--- /dev/null
+++ b/testing/resources/pixel/bug_1883_expected.pdf.2.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1883_expected.pdf.3.png b/testing/resources/pixel/bug_1883_expected.pdf.3.png
new file mode 100644
index 0000000..e6e3988
--- /dev/null
+++ b/testing/resources/pixel/bug_1883_expected.pdf.3.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1883_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1883_expected_skia.pdf.0.png
new file mode 100644
index 0000000..8560bfe
--- /dev/null
+++ b/testing/resources/pixel/bug_1883_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1883_expected_skia.pdf.1.png b/testing/resources/pixel/bug_1883_expected_skia.pdf.1.png
new file mode 100644
index 0000000..0660877
--- /dev/null
+++ b/testing/resources/pixel/bug_1883_expected_skia.pdf.1.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1883_expected_skia.pdf.2.png b/testing/resources/pixel/bug_1883_expected_skia.pdf.2.png
new file mode 100644
index 0000000..f0050f8
--- /dev/null
+++ b/testing/resources/pixel/bug_1883_expected_skia.pdf.2.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1883_expected_skia.pdf.3.png b/testing/resources/pixel/bug_1883_expected_skia.pdf.3.png
new file mode 100644
index 0000000..88d3e25
--- /dev/null
+++ b/testing/resources/pixel/bug_1883_expected_skia.pdf.3.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1922.in b/testing/resources/pixel/bug_1922.in
new file mode 100644
index 0000000..c7b005b
--- /dev/null
+++ b/testing/resources/pixel/bug_1922.in
@@ -0,0 +1,66 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /MediaBox [0 0 100 100]
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 5 0 R
+  /Resources <<
+    /Font <<
+      /F1 4 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Font
+  /Subtype /TrueType
+  /BaseFont /TimesNewRoman,Bold
+  /Encoding /WinAnsiEncoding
+  /FirstChar 32
+  /LastChar 121
+  /Widths [
+    230.769 307.692 538.462 538.462 538.462 1153.846 846.154 307.692
+    307.692 307.692 538.462 538.462 230.769 307.692 230.769 307.692
+    538.462 538.462 538.462 538.462 538.462 538.462 538.462 538.462
+    538.462 538.462 307.692 307.692 538.462 538.462 538.462 538.462
+    923.077 692.308 692.308 692.308 692.308 538.462 538.462 692.308
+    692.308 307.692 538.462 692.308 615.385 846.154 692.308 769.231
+    615.385 769.231 692.308 615.385 615.385 615.385 692.308 1000.000
+    692.308 615.385 615.385 307.692 307.692 307.692 615.385 538.462
+    307.692 461.538 461.538 461.538 461.538 461.538 307.692 538.462
+    538.462 307.692 307.692 615.385 307.692 769.231 538.462 461.538
+    461.538 461.538 461.538 461.538 307.692 538.462 384.615 615.385
+    461.538 461.538
+  ]
+>>
+endobj
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+2 J
+BT
+0 0 0 rg
+/F1 20 Tf
+10 40 Td
+[(U) -107.72357178 (n) -14.68963623 (i) 31.01132202
+(v) -125.67745972 (e) 14.6895752 (r) 35.90786743 (s) 57.12615967
+(i) 31.01132202 (t) -11.42520142 (y) -48.96524048]TJ
+ET
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
\ No newline at end of file
diff --git a/testing/resources/pixel/bug_1922_expected.pdf.0.png b/testing/resources/pixel/bug_1922_expected.pdf.0.png
new file mode 100644
index 0000000..73057ac
--- /dev/null
+++ b/testing/resources/pixel/bug_1922_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1922_expected_agg_mac.pdf.0.png b/testing/resources/pixel/bug_1922_expected_agg_mac.pdf.0.png
new file mode 100644
index 0000000..2caa41a
--- /dev/null
+++ b/testing/resources/pixel/bug_1922_expected_agg_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1949.in b/testing/resources/pixel/bug_1949.in
new file mode 100644
index 0000000..5e7afd3
--- /dev/null
+++ b/testing/resources/pixel/bug_1949.in
@@ -0,0 +1,133 @@
+{{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 44 24]
+  /Resources <<
+    /ExtGState <<
+      /GSHalfAlphaConstant 5 0 R
+      /GSHalfAlphaMask 6 0 R
+    >>
+    /XObject <<
+      /HalfAlphaSquare 8 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+
+% Opaque black background.
+q
+  0 0 0 rg
+  0 0 44 24 re
+  f
+Q
+
+% Transparency group drawn with constant alpha.
+q
+  1 0 0 1 4 4 cm
+  /GSHalfAlphaConstant gs
+
+  /HalfAlphaSquare Do
+Q
+
+% Transparency group drawn with a soft mask.
+q
+  1 0 0 1 24 4 cm
+  /GSHalfAlphaMask gs
+
+  /HalfAlphaSquare Do
+Q
+
+endstream
+endobj
+
+% Graphics state with a 0.5 non-stroking alpha constant.
+{{object 5 0}} <<
+  /Type /ExtGState
+  /ca 0.5
+>>
+endobj
+
+% Graphics state with a soft mask containing a 0.5 alpha central hole.
+{{object 6 0}} <<
+  /Type /ExtGState
+  /SMask <<
+    /Type /Mask
+    /S /Luminosity
+    /G 7 0 R
+  >>
+>>
+endobj
+{{object 7 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /BBox [0 0 16 16]
+  /Group <<
+    /Type /Group
+    /S /Transparency
+    /CS /DeviceGray
+    /I true
+  >>
+  {{streamlen}}
+>>
+stream
+q
+  1 g
+  0 0 16 16 re
+  f
+
+  0.5 g
+  4 4 8 8 re
+  f
+Q
+endstream
+endobj
+
+% Transparency group containing a 0.5 alpha white square.
+{{object 8 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /BBox [0 0 16 16]
+  /Group <<
+    /Type /Group
+    /S /Transparency
+    /I true
+  >>
+  /Resources <<
+    /ExtGState <<
+      /GSHalfAlphaConstant 5 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+q
+  /GSHalfAlphaConstant gs
+
+  1 1 1 rg
+  0 0 16 16 re
+  f
+Q
+endstream
+endobj
+
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1949_expected.pdf.0.png b/testing/resources/pixel/bug_1949_expected.pdf.0.png
new file mode 100644
index 0000000..c215044
--- /dev/null
+++ b/testing/resources/pixel/bug_1949_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1949_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1949_expected_skia.pdf.0.png
new file mode 100644
index 0000000..6d4ea6d
--- /dev/null
+++ b/testing/resources/pixel/bug_1949_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1963.in b/testing/resources/pixel/bug_1963.in
new file mode 100644
index 0000000..d79560b
--- /dev/null
+++ b/testing/resources/pixel/bug_1963.in
@@ -0,0 +1,73 @@
+{{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 [300 500 350 530]
+  /Resources <<
+    /XObject <<
+      /X1 5 0 R
+      /X2 6 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+  1 0 0 1 301.65 515.4 cm
+  /X1 Do
+Q
+q
+  1 0 0 1 304.05 503.7 cm
+  /X2 Do
+Q
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /BBox [301.65 515.4 342.75 527.4]
+  /Matrix [1 0 0 1 -301.65 -515.4]
+  {{streamlen}}
+>>
+stream
+1 0 0 RG
+2 w
+305.400 521.400 m
+339.000 521.400 l
+S
+endstream
+endobj
+{{object 6 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /BBox [304.05 503.7 345.15 515.7]
+  /Matrix [1 0 0 1 -304.05 -503.7]
+  {{streamlen}}
+>>
+stream
+1 0 0 RG
+2 w
+307.800 510.000 m
+341.400 509.400 l
+S
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1963_expected.pdf.0.png b/testing/resources/pixel/bug_1963_expected.pdf.0.png
new file mode 100644
index 0000000..a2aec8c
--- /dev/null
+++ b/testing/resources/pixel/bug_1963_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1963_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1963_expected_skia.pdf.0.png
new file mode 100644
index 0000000..2d9ddae
--- /dev/null
+++ b/testing/resources/pixel/bug_1963_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1966.in b/testing/resources/pixel/bug_1966.in
new file mode 100644
index 0000000..b52a6cb
--- /dev/null
+++ b/testing/resources/pixel/bug_1966.in
@@ -0,0 +1,121 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+  /MediaBox [0 0 128.571 128.571]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 7 0 R
+  /Resources <<
+    /XObject <<
+      /Im1 4 0 R
+    >>
+    /Pattern <<
+      /P1 5 0 R
+      /P2 6 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 1
+  /Filter /ASCIIHexDecode
+  /Height 40
+  /ImageMask true
+  /Width 80
+  {{streamlen}}
+>>
+stream
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000FFFF
+FFFF000000000000FFFFFFFF0FFFFFFFFFF0FFFFFFFF0FFFFFFFFFF0FFFF
+FFFF0FFFFFFFFFF0FFFFFFFF0FFFFFFFFFF0FFFFFFFF000000000000FFFF
+FFFF000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFF000000000000FFFFFFFF000000000000FFFFFFFF0FFFFFFFFFF0FFFF
+FFFF0FFFFFFFFFF0FFFFFFFF0FFFFFFFFFF0FFFFFFFF0FFFFFFFFFF0FFFF
+FFFF000000000000FFFFFFFF000000000000FFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFF
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /Pattern
+  /PaintType 1
+  /PatternType 1
+  /TilingType 1
+  /BBox [0 0 128.571 128.571]
+  /XStep 128.571
+  /YStep 128.571
+  {{streamlen}}
+>>
+stream
+q
+0.0 0.0 0.0 rg
+0 128.571 m
+128.571 128.571 l
+128.571 64 l
+0 64 l
+f
+Q
+endstream
+endobj
+{{object 6 0}} <<
+  /Type /Pattern
+  /PaintType 1
+  /PatternType 1
+  /TilingType 1
+  /BBox [0 0 128.571 128.571]
+  /XStep 128.571
+  /YStep 128.571
+  {{streamlen}}
+>>
+stream
+% second pattern
+q
+0.0 0.0 0.0 rg
+0 64 m
+128.571 64 l
+128.571 0 l
+0 0 l
+f
+Q
+endstream
+endobj
+{{object 7 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+/Pattern cs
+/P1 scn
+q
+128.571 0 0 128.571 0 0 cm
+/Im1 Do
+Q
+/P2 scn
+q
+128.571 0 0 128.571 0 0 cm
+/Im1 Do
+Q
+Q
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
\ No newline at end of file
diff --git a/testing/resources/pixel/bug_1966_expected.pdf.0.png b/testing/resources/pixel/bug_1966_expected.pdf.0.png
new file mode 100644
index 0000000..47d12bd
--- /dev/null
+++ b/testing/resources/pixel/bug_1966_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1966_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1966_expected_skia.pdf.0.png
new file mode 100644
index 0000000..134ca64
--- /dev/null
+++ b/testing/resources/pixel/bug_1966_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1972_1.in b/testing/resources/pixel/bug_1972_1.in
new file mode 100644
index 0000000..e537e94
--- /dev/null
+++ b/testing/resources/pixel/bug_1972_1.in
@@ -0,0 +1,36 @@
+{{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
+  /MediaBox [0 0 200 100]
+  /Contents 4 0 R
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+5 0 0 5 0 0 cm
+0 1 0 RG
+0 0 m
+16000 1420 l
+S
+Q
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1972_1_expected.pdf.0.png b/testing/resources/pixel/bug_1972_1_expected.pdf.0.png
new file mode 100644
index 0000000..bca30df
--- /dev/null
+++ b/testing/resources/pixel/bug_1972_1_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1972_2.in b/testing/resources/pixel/bug_1972_2.in
new file mode 100644
index 0000000..4c1ad95
--- /dev/null
+++ b/testing/resources/pixel/bug_1972_2.in
@@ -0,0 +1,36 @@
+{{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
+  /MediaBox [0 0 200 100]
+  /Contents 4 0 R
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+5 0 0 5 0 0 cm
+0 1 0 RG
+-9000 -9000 m
+500 500 l
+S
+Q
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1972_2_expected.pdf.0.png b/testing/resources/pixel/bug_1972_2_expected.pdf.0.png
new file mode 100644
index 0000000..19b8c8a
--- /dev/null
+++ b/testing/resources/pixel/bug_1972_2_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1972_3.in b/testing/resources/pixel/bug_1972_3.in
new file mode 100644
index 0000000..5d84df7
--- /dev/null
+++ b/testing/resources/pixel/bug_1972_3.in
@@ -0,0 +1,36 @@
+{{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
+  /MediaBox [0 0 200 100]
+  /Contents 4 0 R
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+5 0 0 5 0 0 cm
+0 1 0 RG
+0 0 m
+2 10000 20 9000 40 -10000 c
+S
+Q
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1972_3_expected.pdf.0.png b/testing/resources/pixel/bug_1972_3_expected.pdf.0.png
new file mode 100644
index 0000000..d0f97c9
--- /dev/null
+++ b/testing/resources/pixel/bug_1972_3_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1973.in b/testing/resources/pixel/bug_1973.in
new file mode 100644
index 0000000..1d5602d
--- /dev/null
+++ b/testing/resources/pixel/bug_1973.in
@@ -0,0 +1,81 @@
+{{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 [ 240 570 345 650 ]
+  /Resources <<
+    /XObject <<
+      /Img 5 0 R
+    >>
+  >>
+>>
+endobj
+
+% Content stream matching coordinates in form_button0.pdf.
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+  89.555968 0 0 67.166976 247.7222 576.8333 cm
+  q
+    1 0 0 rg
+    0 0 1 1 re
+    f
+  Q
+  /Img Do
+Q
+endstream
+endobj
+
+% A 1024x768 image with a single (0x00), indexed color (0x00FF00).
+{{object 5 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace [ /Indexed /DeviceRGB 0 <00FF00> ]
+  /Filter [ /ASCIIHexDecode /FlateDecode ]
+  /Height 768
+  /Width 1024
+  {{streamlen}}
+>>
+stream
+78DAEDC13101000000C2A0F54F6D067FA00000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000003E0300B40001
+endstream
+endobj
+
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1973_expected.pdf.0.png b/testing/resources/pixel/bug_1973_expected.pdf.0.png
new file mode 100644
index 0000000..8d75b62
--- /dev/null
+++ b/testing/resources/pixel/bug_1973_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1976.in b/testing/resources/pixel/bug_1976.in
new file mode 100644
index 0000000..696f5da
--- /dev/null
+++ b/testing/resources/pixel/bug_1976.in
@@ -0,0 +1,83 @@
+{{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 96 96]
+  /Resources <<
+    /XObject <<
+      /X0 5 0 R
+    >>
+  >>
+>>
+endobj
+
+% Green and red checkerboard. When scaled down, the green and red should blend
+% together into a darker yellow.
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+  % Solid green square.
+  0 1 0 rg
+  16 16 64 64 re f
+Q
+q
+  % Transparent and red checkerboard.
+  64 0 0 64 16 16 cm
+  /X0 Do
+Q
+endstream
+endobj
+
+% Single pixel image with /SMask to trigger masked image rendering.
+{{object 5 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter /ASCIIHexDecode
+  /Height 1
+  /SMask 6 0 R
+  /Width 1
+  {{streamlen}}
+>>
+stream
+FF 00 00
+endstream
+endobj
+
+% Grayscale checkerboard to trigger 8-bit to 8-bit scaling. Scaling down by a
+% multiple of 2 using nearest neighbor gives particularly bad results.
+{{object 6 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceGray
+  /Filter [/ASCII85Decode /FlateDecode]
+  /Height 128
+  /Width 128
+  {{streamlen}}
+>>
+stream
+GhVQ20b"*_#f&.lRiX?CBI7,$dqQl"iofLfkND$kkND$kkND$kkND$kkND$kkND$kkND$kkND$kkND$k
+kND$kkND$kkND$kkND$kkND$kkN@?Q?he3kdJ~>
+endstream
+endobj
+
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1976_expected.pdf.0.png b/testing/resources/pixel/bug_1976_expected.pdf.0.png
new file mode 100644
index 0000000..59bfc84
--- /dev/null
+++ b/testing/resources/pixel/bug_1976_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1983.in b/testing/resources/pixel/bug_1983.in
new file mode 100644
index 0000000..0167258
--- /dev/null
+++ b/testing/resources/pixel/bug_1983.in
@@ -0,0 +1,43 @@
+{{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 100 100]
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+20 w
+q
+1 0 0 1 20 10 cm
+1 J
+% The first dot
+10 40 m
+h
+S
+% The second dot
+50 40 m
+50 40 l
+h
+S
+Q
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1983_expected.pdf.0.png b/testing/resources/pixel/bug_1983_expected.pdf.0.png
new file mode 100644
index 0000000..ea59974
--- /dev/null
+++ b/testing/resources/pixel/bug_1983_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1983_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1983_expected_skia.pdf.0.png
new file mode 100644
index 0000000..1e341ac
--- /dev/null
+++ b/testing/resources/pixel/bug_1983_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1986.in b/testing/resources/pixel/bug_1986.in
new file mode 100644
index 0000000..9e35fb3
--- /dev/null
+++ b/testing/resources/pixel/bug_1986.in
@@ -0,0 +1,61 @@
+{{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 612 792]
+  /Resources <<
+    /XObject <<
+      /Im0 5 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+612 0 0 792 0 0 cm
+/Im0 Do
+Q
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /Filter [6 0 R /LZWDecode 7 0 R]
+  /Width 612
+  /Height 792
+  {{streamlen}}
+>>
+stream
+80002040c351404020068290e0a8100028663a1e4e06a380c8410d004522d0d16c68d10d0b1a4d06
+439408061881008c8000181c0f180003cc66f361c80330084358d1a31bfc9eff288005f189549a51
+30a24ae5947a44b00e0100d3ea3507f948000c86d400a040200002ff2e0002640201209050b35a2c
+f69b4bfe5625af10ce465309d0ca6410188f220279c0ca6e251408a47101d8ca72399a4de6e100c8
+5c33170c1fe9000432303faf3fd26cf5a14022502a2bdfe7f369a0b480980c12097d1801be801c05
+0005c57bf818daa6ee5fed9801
+endstream
+endobj
+{{object 6 0}}
+/ASCIIHexDecode
+enbobj
+{{object 7 0}}
+/JPXDecode
+enbobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1986_expected.pdf.0.png b/testing/resources/pixel/bug_1986_expected.pdf.0.png
new file mode 100644
index 0000000..e1b3d43
--- /dev/null
+++ b/testing/resources/pixel/bug_1986_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1995.in b/testing/resources/pixel/bug_1995.in
new file mode 100644
index 0000000..448fa58
--- /dev/null
+++ b/testing/resources/pixel/bug_1995.in
@@ -0,0 +1,81 @@
+{{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
+  /Group <<
+    /Type /Group
+    /S /Transparency
+  >>
+  /MediaBox [0 0 40 40]
+  /Resources <<
+    /ExtGState <<
+      /GSMask <<
+        /SMask <<
+          /Type /Mask
+          /S /Alpha
+          /G 5 0 R
+        >>
+      >>
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+  1 0 0 1 5 5 cm
+
+  % Red square.
+  1 0 0 rg
+  0 0 30 30 re
+  f
+
+  % Blue square with soft mask dictionary.
+  /GSMask gs
+  0 0 1 rg
+  0 0 30 30 re
+  f
+Q
+endstream
+endobj
+
+% Soft mask dictionary with a central hole.
+{{object 5 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /BBox [0 0 30 30]
+  /Group <<
+    /Type /Group
+    /S /Transparency
+    /I true
+  >>
+  {{streamlen}}
+>>
+stream
+q
+  0 0 0 RG
+  15 w
+  0 0 30 30 re
+  S
+Q
+endstream
+endobj
+
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_1995_expected.pdf.0.png b/testing/resources/pixel/bug_1995_expected.pdf.0.png
new file mode 100644
index 0000000..daff3e9
--- /dev/null
+++ b/testing/resources/pixel/bug_1995_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_1995_expected_skia.pdf.0.png b/testing/resources/pixel/bug_1995_expected_skia.pdf.0.png
new file mode 100644
index 0000000..97ac01f
--- /dev/null
+++ b/testing/resources/pixel/bug_1995_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_2001.pdf b/testing/resources/pixel/bug_2001.pdf
new file mode 100644
index 0000000..f73831d
--- /dev/null
+++ b/testing/resources/pixel/bug_2001.pdf
Binary files differ
diff --git a/testing/resources/pixel/bug_2001_expected.pdf.0.png b/testing/resources/pixel/bug_2001_expected.pdf.0.png
new file mode 100644
index 0000000..fd353a9
--- /dev/null
+++ b/testing/resources/pixel/bug_2001_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_237527_1.in b/testing/resources/pixel/bug_237527_1.in
new file mode 100644
index 0000000..503fa2a
--- /dev/null
+++ b/testing/resources/pixel/bug_237527_1.in
@@ -0,0 +1,37 @@
+{{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
+  /Annots [4 0 R]
+  /MediaBox [0 0 300 300]
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Annot
+  /Subtype /Link
+  /A <<
+    /Type /Action
+    /S /URI
+    /URI (www.google.com)
+  >>
+  /Border [0 0 1]
+  /C [0 1 1]
+  /H /I
+  /Rect [100 100 200 120]
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_237527_1_expected.pdf.0.png b/testing/resources/pixel/bug_237527_1_expected.pdf.0.png
new file mode 100644
index 0000000..d8c8148
--- /dev/null
+++ b/testing/resources/pixel/bug_237527_1_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_237527_1_expected_skia.pdf.0.png b/testing/resources/pixel/bug_237527_1_expected_skia.pdf.0.png
new file mode 100644
index 0000000..eef577e
--- /dev/null
+++ b/testing/resources/pixel/bug_237527_1_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_237527_2.in b/testing/resources/pixel/bug_237527_2.in
new file mode 100644
index 0000000..fd4eefa
--- /dev/null
+++ b/testing/resources/pixel/bug_237527_2.in
@@ -0,0 +1,42 @@
+{{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
+  /Annots [4 0 R]
+  /MediaBox [0 0 300 300]
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Annot
+  /Subtype /Link
+  /A <<
+    /Type /Action
+    /S /URI
+    /URI (http://www.google.com)
+  >>
+  /BS <<
+    /Type /Border
+    /S /U
+    /W 1
+  >>
+  /Border [0 0 1]
+  /C [0 1 1]
+  /H /I
+  /Rect [100 100 200 120]
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_237527_2_expected.pdf.0.png b/testing/resources/pixel/bug_237527_2_expected.pdf.0.png
new file mode 100644
index 0000000..14b04de
--- /dev/null
+++ b/testing/resources/pixel/bug_237527_2_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_304_expected.pdf.0.png b/testing/resources/pixel/bug_304_expected.pdf.0.png
index e1b3d43..62de87b 100644
--- a/testing/resources/pixel/bug_304_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_304_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_451366_expected_skia.pdf.0.png b/testing/resources/pixel/bug_451366_expected_skia.pdf.0.png
new file mode 100644
index 0000000..94b4524
--- /dev/null
+++ b/testing/resources/pixel/bug_451366_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_491_invisible_expected_skia.pdf.0.png b/testing/resources/pixel/bug_491_invisible_expected_skia.pdf.0.png
new file mode 100644
index 0000000..518a266
--- /dev/null
+++ b/testing/resources/pixel/bug_491_invisible_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_491_unspecified_expected_skia.pdf.0.png b/testing/resources/pixel/bug_491_unspecified_expected_skia.pdf.0.png
new file mode 100644
index 0000000..10665ac
--- /dev/null
+++ b/testing/resources/pixel/bug_491_unspecified_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_491_visible_expected_skia.pdf.0.png b/testing/resources/pixel/bug_491_visible_expected_skia.pdf.0.png
new file mode 100644
index 0000000..10665ac
--- /dev/null
+++ b/testing/resources/pixel/bug_491_visible_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_492.in b/testing/resources/pixel/bug_492.in
index 45c4a6f..e2922db 100644
--- a/testing/resources/pixel/bug_492.in
+++ b/testing/resources/pixel/bug_492.in
@@ -35,7 +35,7 @@
   /JS 21 0 R
 >>
 endobj
-% JS program to exexute
+% JS program to execute
 {{object 21 0}} <<
 >>
 stream
diff --git a/testing/resources/pixel/bug_524043_1_expected.pdf.0.png b/testing/resources/pixel/bug_524043_1_expected.pdf.0.png
index eabf957..a7e1fd7 100644
--- a/testing/resources/pixel/bug_524043_1_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_524043_1_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_524043_1_expected_agg_mac.pdf.0.png b/testing/resources/pixel/bug_524043_1_expected_agg_mac.pdf.0.png
new file mode 100644
index 0000000..438e9f3
--- /dev/null
+++ b/testing/resources/pixel/bug_524043_1_expected_agg_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_524043_1_expected_mac.pdf.0.png b/testing/resources/pixel/bug_524043_1_expected_mac.pdf.0.png
deleted file mode 100644
index b85b9d0..0000000
--- a/testing/resources/pixel/bug_524043_1_expected_mac.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_524043_1_expected_win.pdf.0.png b/testing/resources/pixel/bug_524043_1_expected_win.pdf.0.png
deleted file mode 100644
index b2c134a..0000000
--- a/testing/resources/pixel/bug_524043_1_expected_win.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_524043_2_expected.pdf.0.png b/testing/resources/pixel/bug_524043_2_expected.pdf.0.png
index 04304fe..4dd2672 100644
--- a/testing/resources/pixel/bug_524043_2_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_524043_2_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_524043_2_expected_agg_mac.pdf.0.png b/testing/resources/pixel/bug_524043_2_expected_agg_mac.pdf.0.png
new file mode 100644
index 0000000..e3bf21f
--- /dev/null
+++ b/testing/resources/pixel/bug_524043_2_expected_agg_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_524043_2_expected_mac.pdf.0.png b/testing/resources/pixel/bug_524043_2_expected_mac.pdf.0.png
deleted file mode 100644
index ecede7d..0000000
--- a/testing/resources/pixel/bug_524043_2_expected_mac.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_524043_2_expected_win.pdf.0.png b/testing/resources/pixel/bug_524043_2_expected_win.pdf.0.png
deleted file mode 100644
index 786d963..0000000
--- a/testing/resources/pixel/bug_524043_2_expected_win.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_524043_3_expected.pdf.0.png b/testing/resources/pixel/bug_524043_3_expected.pdf.0.png
index eabf957..a7e1fd7 100644
--- a/testing/resources/pixel/bug_524043_3_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_524043_3_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_524043_3_expected_agg_mac.pdf.0.png b/testing/resources/pixel/bug_524043_3_expected_agg_mac.pdf.0.png
new file mode 100644
index 0000000..e794355
--- /dev/null
+++ b/testing/resources/pixel/bug_524043_3_expected_agg_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_524043_3_expected_mac.pdf.0.png b/testing/resources/pixel/bug_524043_3_expected_mac.pdf.0.png
deleted file mode 100644
index b85b9d0..0000000
--- a/testing/resources/pixel/bug_524043_3_expected_mac.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_524043_3_expected_win.pdf.0.png b/testing/resources/pixel/bug_524043_3_expected_win.pdf.0.png
deleted file mode 100644
index b2c134a..0000000
--- a/testing/resources/pixel/bug_524043_3_expected_win.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_524043_4_expected.pdf.0.png b/testing/resources/pixel/bug_524043_4_expected.pdf.0.png
index eabf957..a7e1fd7 100644
--- a/testing/resources/pixel/bug_524043_4_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_524043_4_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_524043_4_expected_agg_mac.pdf.0.png b/testing/resources/pixel/bug_524043_4_expected_agg_mac.pdf.0.png
new file mode 100644
index 0000000..e794355
--- /dev/null
+++ b/testing/resources/pixel/bug_524043_4_expected_agg_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_524043_4_expected_mac.pdf.0.png b/testing/resources/pixel/bug_524043_4_expected_mac.pdf.0.png
deleted file mode 100644
index b85b9d0..0000000
--- a/testing/resources/pixel/bug_524043_4_expected_mac.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_524043_4_expected_win.pdf.0.png b/testing/resources/pixel/bug_524043_4_expected_win.pdf.0.png
deleted file mode 100644
index b2c134a..0000000
--- a/testing/resources/pixel/bug_524043_4_expected_win.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_524043_5_expected.pdf.0.png b/testing/resources/pixel/bug_524043_5_expected.pdf.0.png
index eabf957..a7e1fd7 100644
--- a/testing/resources/pixel/bug_524043_5_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_524043_5_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_524043_5_expected_agg_mac.pdf.0.png b/testing/resources/pixel/bug_524043_5_expected_agg_mac.pdf.0.png
new file mode 100644
index 0000000..e794355
--- /dev/null
+++ b/testing/resources/pixel/bug_524043_5_expected_agg_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_524043_5_expected_mac.pdf.0.png b/testing/resources/pixel/bug_524043_5_expected_mac.pdf.0.png
deleted file mode 100644
index b85b9d0..0000000
--- a/testing/resources/pixel/bug_524043_5_expected_mac.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_524043_5_expected_win.pdf.0.png b/testing/resources/pixel/bug_524043_5_expected_win.pdf.0.png
deleted file mode 100644
index b2c134a..0000000
--- a/testing/resources/pixel/bug_524043_5_expected_win.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_524043_6_expected_mac.pdf.0.png b/testing/resources/pixel/bug_524043_6_expected_mac.pdf.0.png
deleted file mode 100644
index 3edcc2d..0000000
--- a/testing/resources/pixel/bug_524043_6_expected_mac.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_524043_7_expected.pdf.0.png b/testing/resources/pixel/bug_524043_7_expected.pdf.0.png
index 04304fe..4dd2672 100644
--- a/testing/resources/pixel/bug_524043_7_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_524043_7_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_524043_7_expected_agg_mac.pdf.0.png b/testing/resources/pixel/bug_524043_7_expected_agg_mac.pdf.0.png
new file mode 100644
index 0000000..e3bf21f
--- /dev/null
+++ b/testing/resources/pixel/bug_524043_7_expected_agg_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_524043_7_expected_mac.pdf.0.png b/testing/resources/pixel/bug_524043_7_expected_mac.pdf.0.png
deleted file mode 100644
index ecede7d..0000000
--- a/testing/resources/pixel/bug_524043_7_expected_mac.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_524043_7_expected_win.pdf.0.png b/testing/resources/pixel/bug_524043_7_expected_win.pdf.0.png
deleted file mode 100644
index 786d963..0000000
--- a/testing/resources/pixel/bug_524043_7_expected_win.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_528103_expected.pdf.0.png b/testing/resources/pixel/bug_528103_expected.pdf.0.png
index 5c0c254..79240dd 100644
--- a/testing/resources/pixel/bug_528103_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_528103_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_528103_expected_agg_mac.pdf.0.png b/testing/resources/pixel/bug_528103_expected_agg_mac.pdf.0.png
new file mode 100644
index 0000000..0d23b55
--- /dev/null
+++ b/testing/resources/pixel/bug_528103_expected_agg_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_528103_expected_mac.pdf.0.png b/testing/resources/pixel/bug_528103_expected_mac.pdf.0.png
deleted file mode 100644
index cb028f9..0000000
--- a/testing/resources/pixel/bug_528103_expected_mac.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_528103_expected_win.pdf.0.png b/testing/resources/pixel/bug_528103_expected_win.pdf.0.png
deleted file mode 100644
index 8ccda23..0000000
--- a/testing/resources/pixel/bug_528103_expected_win.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_543018_1_expected.pdf.0.png b/testing/resources/pixel/bug_543018_1_expected.pdf.0.png
index eabf957..a7e1fd7 100644
--- a/testing/resources/pixel/bug_543018_1_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_543018_1_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_543018_1_expected_agg_mac.pdf.0.png b/testing/resources/pixel/bug_543018_1_expected_agg_mac.pdf.0.png
new file mode 100644
index 0000000..e794355
--- /dev/null
+++ b/testing/resources/pixel/bug_543018_1_expected_agg_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_543018_1_expected_mac.pdf.0.png b/testing/resources/pixel/bug_543018_1_expected_mac.pdf.0.png
deleted file mode 100644
index b85b9d0..0000000
--- a/testing/resources/pixel/bug_543018_1_expected_mac.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_543018_1_expected_win.pdf.0.png b/testing/resources/pixel/bug_543018_1_expected_win.pdf.0.png
deleted file mode 100644
index b2c134a..0000000
--- a/testing/resources/pixel/bug_543018_1_expected_win.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_543018_2_expected.pdf.0.png b/testing/resources/pixel/bug_543018_2_expected.pdf.0.png
index eabf957..a7e1fd7 100644
--- a/testing/resources/pixel/bug_543018_2_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_543018_2_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_543018_2_expected_agg_mac.pdf.0.png b/testing/resources/pixel/bug_543018_2_expected_agg_mac.pdf.0.png
new file mode 100644
index 0000000..e794355
--- /dev/null
+++ b/testing/resources/pixel/bug_543018_2_expected_agg_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_543018_2_expected_mac.pdf.0.png b/testing/resources/pixel/bug_543018_2_expected_mac.pdf.0.png
deleted file mode 100644
index b85b9d0..0000000
--- a/testing/resources/pixel/bug_543018_2_expected_mac.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_543018_2_expected_win.pdf.0.png b/testing/resources/pixel/bug_543018_2_expected_win.pdf.0.png
deleted file mode 100644
index b2c134a..0000000
--- a/testing/resources/pixel/bug_543018_2_expected_win.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_551258_1_expected.pdf.0.png b/testing/resources/pixel/bug_551258_1_expected.pdf.0.png
index eabf957..a7e1fd7 100644
--- a/testing/resources/pixel/bug_551258_1_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_551258_1_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_551258_1_expected_agg_mac.pdf.0.png b/testing/resources/pixel/bug_551258_1_expected_agg_mac.pdf.0.png
new file mode 100644
index 0000000..e794355
--- /dev/null
+++ b/testing/resources/pixel/bug_551258_1_expected_agg_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_551258_1_expected_mac.pdf.0.png b/testing/resources/pixel/bug_551258_1_expected_mac.pdf.0.png
deleted file mode 100644
index b85b9d0..0000000
--- a/testing/resources/pixel/bug_551258_1_expected_mac.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_551258_1_expected_win.pdf.0.png b/testing/resources/pixel/bug_551258_1_expected_win.pdf.0.png
deleted file mode 100644
index b2c134a..0000000
--- a/testing/resources/pixel/bug_551258_1_expected_win.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_554151_expected.pdf.0.png b/testing/resources/pixel/bug_554151_expected.pdf.0.png
index 08c11b0..5b99a4d 100644
--- a/testing/resources/pixel/bug_554151_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_554151_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_557223.in b/testing/resources/pixel/bug_557223.in
index acb1ff2..c0c06b6 100644
--- a/testing/resources/pixel/bug_557223.in
+++ b/testing/resources/pixel/bug_557223.in
@@ -75,7 +75,7 @@
 trailer <<
     /Info 6 0 R
     /Root 1 0 R
-    /Size 7
+    {{trailersize}}
 >>
 {{startxref}}
 %%EOF
diff --git a/testing/resources/pixel/bug_585_expected_skia.pdf.0.png b/testing/resources/pixel/bug_585_expected_skia.pdf.0.png
new file mode 100644
index 0000000..c49e21e
--- /dev/null
+++ b/testing/resources/pixel/bug_585_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_591137_expected.pdf.0.png b/testing/resources/pixel/bug_591137_expected.pdf.0.png
index 265e682..74c5c64 100644
--- a/testing/resources/pixel/bug_591137_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_591137_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_601362_expected.pdf.0.png b/testing/resources/pixel/bug_601362_expected.pdf.0.png
index 5d868d5..49db8d9 100644
--- a/testing/resources/pixel/bug_601362_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_601362_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_601362_expected_skia.pdf.0.png b/testing/resources/pixel/bug_601362_expected_skia.pdf.0.png
new file mode 100644
index 0000000..d371b3a
--- /dev/null
+++ b/testing/resources/pixel/bug_601362_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_632_expected.pdf.0.png b/testing/resources/pixel/bug_632_expected.pdf.0.png
index 3807d93..4fc6081 100644
--- a/testing/resources/pixel/bug_632_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_632_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_632_expected.pdf.1.png b/testing/resources/pixel/bug_632_expected.pdf.1.png
index 141f3d8..ee11ce6 100644
--- a/testing/resources/pixel/bug_632_expected.pdf.1.png
+++ b/testing/resources/pixel/bug_632_expected.pdf.1.png
Binary files differ
diff --git a/testing/resources/pixel/bug_632_expected_skia.pdf.1.png b/testing/resources/pixel/bug_632_expected_skia.pdf.1.png
new file mode 100644
index 0000000..002dcba
--- /dev/null
+++ b/testing/resources/pixel/bug_632_expected_skia.pdf.1.png
Binary files differ
diff --git a/testing/resources/pixel/bug_660850_expected_skia.pdf.0.png b/testing/resources/pixel/bug_660850_expected_skia.pdf.0.png
new file mode 100644
index 0000000..254f45b
--- /dev/null
+++ b/testing/resources/pixel/bug_660850_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_665467.in b/testing/resources/pixel/bug_665467.in
index 6ef2c1c..289e8de 100644
--- a/testing/resources/pixel/bug_665467.in
+++ b/testing/resources/pixel/bug_665467.in
@@ -4,96 +4,66 @@
   /Pages 2 0 R
 >>
 endobj
-
 {{object 2 0}} <<
   /Type /Pages
-  /MediaBox [ 0 0 100 100 ]
   /Count 1
-  /Kids [ 3 0 R ]
+  /Kids [3 0 R]
+  /MediaBox [0 0 100 100]
 >>
 endobj
-
 {{object 3 0}} <<
   /Type /Page
   /Parent 2 0 R
-  /Resources
-  <<
-    /Font << /F1 4 0 R >>
+  /Contents 4 0 R
+  /Resources <<
+    /Font <<
+      /F1 5 0 R
+    >>
   >>
-  /Contents 8 0 R
 >>
 endobj
-
 {{object 4 0}} <<
-  /Type /Font
-  /Subtype /TrueType
-  /BaseFont /ChromeSansMM
-  /Encoding 5 0 R
-  /FirstChar 32
-  /LastChar 255
-  /Name /F1
-  /ToUnicode 6 0 R
-  /FontDescriptor 7 0 R
->>
-endobj
-
-{{object 5 0}} <<
-  /Differences [ 161 /someunknownname ]
-  /Type /Encoding
->>
-endobj
-
-{{object 6 0}} <<
->>
-stream
-/CIDInit /ProcSet findresource begin
-12 dict begin
-begincmap
-/CIDSystemInfo
-<</Registry (Adobe)
-/Ordering (Identity)
-/Supplement 0
->> def
-/CMapName /Adobe-Identity-H def
-CMapType 2 def
-1 begincodespacerange
-<00> <FF>
-endcodespacerange
-1 beginbfchar
-<A1> <043B>
-endbfchar
-endcmap
-CMapName currentdict /CMap defineresource pop
-end
-end
-endstream
-endobj
-
-{{object 7 0}} <<
-  << /Ascent 1000
-  /CapHeight 0
-  /Descent -200
-  /Flags 32
-  /FontBBox [ -599 -207 1338 1034 ]
-  /FontName /ChromeSansMM
-  /ItalicAngle 0
-  /StemV 0
-  /Type /FontDescriptor
->>
-endobj
-
-{{object 8 0}} <<
+  {{streamlen}}
 >>
 stream
 BT
-50 50 Td /F1 15 Tf <A1> Tj
+50 50 Td
+/F1 15 Tf
+[<8C>]TJ
 ET
 endstream
 endobj
-
-{{xref}}
-trailer <<
-  /Root 1 0 R
+{{object 5 0}} <<
+  /Type /Font
+  /Subtype /TrueType
+  /BaseFont /Tahoma
+  /Encoding 6 0 R
+  /FirstChar 139
+  /FontDescriptor 7 0 R
+  /LastChar 140
+  /Widths [943 677]
 >>
+endobj
+{{object 6 0}} <<
+  /Type /Encoding
+  /Differences [
+    140 /Elcyrillic
+  ]
+>>
+endobj
+{{object 7 0}} <<
+  /Type /FontDescriptor
+  /Ascent 1034
+  /CapHeight 0
+  /Descent -207
+  /Flags 32
+  /FontBBox [-599 -207 1338 1034]
+  /FontName /Tahoma
+  /ItalicAngle 0
+  /StemV 0
+>>
+endobj
+{{xref}}
+{{trailer}}
 {{startxref}}
 %%EOF
diff --git a/testing/resources/pixel/bug_665467_expected.pdf.0.png b/testing/resources/pixel/bug_665467_expected.pdf.0.png
index e3b37b4..4532565 100644
--- a/testing/resources/pixel/bug_665467_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_665467_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_665467_expected_mac.pdf.0.png b/testing/resources/pixel/bug_665467_expected_mac.pdf.0.png
index 9f51dcb..0faddf8 100644
--- a/testing/resources/pixel/bug_665467_expected_mac.pdf.0.png
+++ b/testing/resources/pixel/bug_665467_expected_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_665467_expected_skia.pdf.0.png b/testing/resources/pixel/bug_665467_expected_skia.pdf.0.png
new file mode 100644
index 0000000..2cd13ff
--- /dev/null
+++ b/testing/resources/pixel/bug_665467_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_665467_expected_win.pdf.0.png b/testing/resources/pixel/bug_665467_expected_win.pdf.0.png
deleted file mode 100644
index 8feb717..0000000
--- a/testing/resources/pixel/bug_665467_expected_win.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_714187_expected_skia.pdf.0.png b/testing/resources/pixel/bug_714187_expected_skia.pdf.0.png
new file mode 100644
index 0000000..80cac57
--- /dev/null
+++ b/testing/resources/pixel/bug_714187_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_725389.in b/testing/resources/pixel/bug_725389.in
new file mode 100644
index 0000000..0d0818b
--- /dev/null
+++ b/testing/resources/pixel/bug_725389.in
@@ -0,0 +1,58 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /AcroForm <<
+    /Fields [4 0 R]
+  >>
+  /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Annots [4 0 R]
+  /Parent 2 0 R
+  /MediaBox [0 0 200 100]
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Tx
+  /BS <<
+    /S /S
+    /W 1
+  >>
+  /DA (/Times-Roman 12 Tf 0 0 0 rg)
+  /DR <<
+    /Font <<
+      /Times-Roman 5 0 R
+    >>
+  >>
+  /DV ()
+  /F 4
+  /Ff 0
+  /MK <<
+    /BG [1 1 1]
+  >>
+  /P 3 0 R
+  /T (Default)
+  /V (\376\377\5\321\5\327\5\350\0.\0.\0.)
+  /Rect [50 40 150 70]
+>>
+endobj
+{{object 5 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Times-Roman
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_725389_expected.pdf.0.png b/testing/resources/pixel/bug_725389_expected.pdf.0.png
new file mode 100644
index 0000000..6da1b77
--- /dev/null
+++ b/testing/resources/pixel/bug_725389_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_725389_expected_mac.pdf.0.png b/testing/resources/pixel/bug_725389_expected_mac.pdf.0.png
new file mode 100644
index 0000000..453c2c3
--- /dev/null
+++ b/testing/resources/pixel/bug_725389_expected_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_725389_expected_skia.pdf.0.png b/testing/resources/pixel/bug_725389_expected_skia.pdf.0.png
new file mode 100644
index 0000000..25ad890
--- /dev/null
+++ b/testing/resources/pixel/bug_725389_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_725389_expected_skia_mac.pdf.0.png b/testing/resources/pixel/bug_725389_expected_skia_mac.pdf.0.png
new file mode 100644
index 0000000..4a5a4b0
--- /dev/null
+++ b/testing/resources/pixel/bug_725389_expected_skia_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_733528_expected.pdf.0.png b/testing/resources/pixel/bug_733528_expected.pdf.0.png
index eaf48b5..5e178da 100644
--- a/testing/resources/pixel/bug_733528_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_733528_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_733528_expected_mac.pdf.0.png b/testing/resources/pixel/bug_733528_expected_mac.pdf.0.png
index f7c8302..992e488 100644
--- a/testing/resources/pixel/bug_733528_expected_mac.pdf.0.png
+++ b/testing/resources/pixel/bug_733528_expected_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_733528_expected_skia.pdf.0.png b/testing/resources/pixel/bug_733528_expected_skia.pdf.0.png
new file mode 100644
index 0000000..6dfa99d
--- /dev/null
+++ b/testing/resources/pixel/bug_733528_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_733528_expected_win.pdf.0.png b/testing/resources/pixel/bug_733528_expected_win.pdf.0.png
deleted file mode 100644
index a44b932..0000000
--- a/testing/resources/pixel/bug_733528_expected_win.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_736695_1_expected.pdf.0.png b/testing/resources/pixel/bug_736695_1_expected.pdf.0.png
index 99d7bd7..10bbb0d 100644
--- a/testing/resources/pixel/bug_736695_1_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_736695_1_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_736695_1_expected_skia.pdf.0.png b/testing/resources/pixel/bug_736695_1_expected_skia.pdf.0.png
new file mode 100644
index 0000000..ecb7d2b
--- /dev/null
+++ b/testing/resources/pixel/bug_736695_1_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_736695_2_expected.pdf.0.png b/testing/resources/pixel/bug_736695_2_expected.pdf.0.png
index 33ea077..4fe962d 100644
--- a/testing/resources/pixel/bug_736695_2_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_736695_2_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_736695_2_expected_mac.pdf.0.png b/testing/resources/pixel/bug_736695_2_expected_mac.pdf.0.png
index 46c7085..e46e02d 100644
--- a/testing/resources/pixel/bug_736695_2_expected_mac.pdf.0.png
+++ b/testing/resources/pixel/bug_736695_2_expected_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_736695_2_expected_skia.pdf.0.png b/testing/resources/pixel/bug_736695_2_expected_skia.pdf.0.png
new file mode 100644
index 0000000..801b157
--- /dev/null
+++ b/testing/resources/pixel/bug_736695_2_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_736695_2_expected_win.pdf.0.png b/testing/resources/pixel/bug_736695_2_expected_win.pdf.0.png
deleted file mode 100644
index ffa94f0..0000000
--- a/testing/resources/pixel/bug_736695_2_expected_win.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_736695_3_expected.pdf.0.png b/testing/resources/pixel/bug_736695_3_expected.pdf.0.png
index cbffe0a..13c9d0a 100644
--- a/testing/resources/pixel/bug_736695_3_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_736695_3_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_736695_3_expected_mac.pdf.0.png b/testing/resources/pixel/bug_736695_3_expected_mac.pdf.0.png
index 1abcd18..f15d038 100644
--- a/testing/resources/pixel/bug_736695_3_expected_mac.pdf.0.png
+++ b/testing/resources/pixel/bug_736695_3_expected_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_736695_3_expected_skia.pdf.0.png b/testing/resources/pixel/bug_736695_3_expected_skia.pdf.0.png
new file mode 100644
index 0000000..1b02f1b
--- /dev/null
+++ b/testing/resources/pixel/bug_736695_3_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_736695_3_expected_win.pdf.0.png b/testing/resources/pixel/bug_736695_3_expected_win.pdf.0.png
deleted file mode 100644
index d27a9b4..0000000
--- a/testing/resources/pixel/bug_736695_3_expected_win.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_736695_4_expected.pdf.0.png b/testing/resources/pixel/bug_736695_4_expected.pdf.0.png
index 99d7bd7..10bbb0d 100644
--- a/testing/resources/pixel/bug_736695_4_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_736695_4_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_736695_4_expected_skia.pdf.0.png b/testing/resources/pixel/bug_736695_4_expected_skia.pdf.0.png
new file mode 100644
index 0000000..ecb7d2b
--- /dev/null
+++ b/testing/resources/pixel/bug_736695_4_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_736703.in b/testing/resources/pixel/bug_736703.in
new file mode 100644
index 0000000..05c4a35
--- /dev/null
+++ b/testing/resources/pixel/bug_736703.in
@@ -0,0 +1,73 @@
+{{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
+  /Resources <<
+    /ProcSet [/PDF /Text]
+    /Font <<
+      /F4 5 0 R
+    >>
+  >>
+  /MediaBox [0 0 200 200]
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+BT
+/F4 30 Tf
+0 0 0 rg
+1 0 0 1 30 100 Tm
+[(honorably)]TJ
+ET
+Q
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /AGaramond-Regular
+  /Encoding /WinAnsiEncoding
+  /FirstChar 32
+  /FontDescriptor 6 0 R
+  /LastChar 125
+  /Widths [250 220 404 500 500 844 818 235 320 320 394 500 250 320 250 327 500
+   500 500 500 500 500 500 500 500 500 250 250 500 500 500 321 765 623 605 696
+   780 584 538 747 806 338 345 675 553 912 783 795 549 795 645 489 660 746 676
+   960 643 574 641 320 309 320 500 500 360 404 500 400 509 396 290 446 515 257
+   253 482 247 787 525 486 507 497 332 323 307 512 432 660 432 438 377 320 239
+   320]
+>>
+endobj
+{{object 6 0}} <<
+  /Type /FontDescriptor
+  /Ascent 720
+  /CapHeight 663
+  /Descent -270
+  /Flags 34
+  /FontBBox [-183 -269 1099 851]
+  /FontName /AGaramond-Regular
+  /ItalicAngle 0
+  /StemH 40
+  /StemV 74
+  /XHeight 397
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_736703_expected.pdf.0.png b/testing/resources/pixel/bug_736703_expected.pdf.0.png
new file mode 100644
index 0000000..f2fe3a1
--- /dev/null
+++ b/testing/resources/pixel/bug_736703_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_820345_expected.pdf.0.png b/testing/resources/pixel/bug_820345_expected.pdf.0.png
index e3c8e24..e89a680 100644
--- a/testing/resources/pixel/bug_820345_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_820345_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_820345_expected_agg_mac.pdf.0.png b/testing/resources/pixel/bug_820345_expected_agg_mac.pdf.0.png
new file mode 100644
index 0000000..6013c5c
--- /dev/null
+++ b/testing/resources/pixel/bug_820345_expected_agg_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_820345_expected_mac.pdf.0.png b/testing/resources/pixel/bug_820345_expected_mac.pdf.0.png
deleted file mode 100644
index 6e79402..0000000
--- a/testing/resources/pixel/bug_820345_expected_mac.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_820345_expected_win.pdf.0.png b/testing/resources/pixel/bug_820345_expected_win.pdf.0.png
deleted file mode 100644
index c3b8b43..0000000
--- a/testing/resources/pixel/bug_820345_expected_win.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_842.in b/testing/resources/pixel/bug_842.in
index 255a902..71f0104 100644
--- a/testing/resources/pixel/bug_842.in
+++ b/testing/resources/pixel/bug_842.in
@@ -24,7 +24,7 @@
 >>
 endobj
 {{object 4 0}} <<
-{{streamlen}}
+  {{streamlen}}
 >>
 stream
 q
diff --git a/testing/resources/pixel/bug_842_expected_skia.pdf.0.png b/testing/resources/pixel/bug_842_expected_skia.pdf.0.png
new file mode 100644
index 0000000..eb10aa7
--- /dev/null
+++ b/testing/resources/pixel/bug_842_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_843_expected_skia.pdf.0.png b/testing/resources/pixel/bug_843_expected_skia.pdf.0.png
new file mode 100644
index 0000000..f0c8193
--- /dev/null
+++ b/testing/resources/pixel/bug_843_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_845697_expected.pdf.0.png b/testing/resources/pixel/bug_845697_expected.pdf.0.png
index 3bc224b..15ec4dd 100644
--- a/testing/resources/pixel/bug_845697_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_845697_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_846.in b/testing/resources/pixel/bug_846.in
new file mode 100644
index 0000000..e405d67
--- /dev/null
+++ b/testing/resources/pixel/bug_846.in
@@ -0,0 +1,160 @@
+{{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
+  /Resources 4 0 R
+  /Contents 15 0 R
+  /MediaBox [0 0 200 200]
+>>
+endobj
+{{object 4 0}} <<
+  /ProcSet [/PDF /Text]
+  /Font <<
+    /F1 5 0 R
+    /F2 7 0 R
+    /F3 9 0 R
+    /F4 11 0 R
+  >>
+>>
+endobj
+{{object 5 0}} <<
+  /Type /Font
+  /Subtype /TrueType
+  /BaseFont /Arial-Bold
+  /Encoding /WinAnsiEncoding
+  /FirstChar 65
+  /FontDescriptor 6 0 R
+  /LastChar 65
+  /Widths [778]
+>>
+endobj
+{{object 6 0}} <<
+  /Type /FontDescriptor
+  /Ascent 923
+  /CapHeight 687
+  /Descent -282
+  /Flags 34
+  /FontName /Arial-Bold
+  /FontBBox 14 0 R
+  /ItalicAngle 0
+  /StemV 140.269
+  /XHeight 0
+>>
+endobj
+{{object 7 0}} <<
+  /Type /Font
+  /Subtype /TrueType
+  /BaseFont /Arial-Bold,Bold
+  /Encoding /WinAnsiEncoding
+  /FirstChar 65
+  /FontDescriptor 8 0 R
+  /LastChar 65
+  /Widths [778]
+>>
+endobj
+{{object 8 0}} <<
+  /Type /FontDescriptor
+  /Ascent 923
+  /CapHeight 687
+  /Descent -282
+  /Flags 34
+  /FontName /Arial-Bold,Bold
+  /FontBBox 14 0 R
+  /ItalicAngle 0
+  /StemV 140.269
+  /XHeight 0
+>>
+endobj
+{{object 9 0}} <<
+  /Type /Font
+  /Subtype /TrueType
+  /BaseFont /DejaVuSans-Bold
+  /Encoding /WinAnsiEncoding
+  /FirstChar 58
+  /FontDescriptor 10 0 R
+  /LastChar 65
+  /Widths 13 0 R
+>>
+endobj
+{{object 10 0}} <<
+  /Type /FontDescriptor
+  /Ascent 923
+  /CapHeight 687
+  /Descent -282
+  /Flags 34
+  /FontName /DejaVuSans-Bold
+  /FontBBox 14 0 R
+  /ItalicAngle 0
+  /StemV 140.269
+  /XHeight 0
+>>
+endobj
+{{object 11 0}} <<
+  /Type /Font
+  /Subtype /TrueType
+  /BaseFont /DejaVuSans-Bold,Bold
+  /Encoding /WinAnsiEncoding
+  /FirstChar 58
+  /FontDescriptor 12 0 R
+  /LastChar 65
+  /Widths 13 0 R
+>>
+endobj
+{{object 12 0}} <<
+  /Type /FontDescriptor
+  /Ascent 923
+  /CapHeight 687
+  /Descent -282
+  /Flags 34
+  /FontName /DejaVuSans-Bold,Bold
+  /FontBBox 14 0 R
+  /ItalicAngle 0
+  /StemV 140.269
+  /XHeight 0
+>>
+endobj
+{{object 13 0}} [250 0 0 0 0 0 0 778]
+endobj
+{{object 14 0}} [-134 -337 1193 1021]
+endobj
+{{object 15 0}} <<
+  {{streamlen}}
+>>
+stream
+BT
+/F1 2 Tf
+18 0 0 18 50 120 Tm
+(A)Tj
+ET
+BT
+/F2 2 Tf
+18 0 0 18 120 120 Tm
+(A)Tj
+ET
+BT
+/F3 2 Tf
+18 0 0 18 50 60 Tm
+(A)Tj
+ET
+BT
+/F4 2 Tf
+18 0 0 18 120 60 Tm
+(A)Tj
+ET
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_846_expected.pdf.0.png b/testing/resources/pixel/bug_846_expected.pdf.0.png
new file mode 100644
index 0000000..1ff3944
--- /dev/null
+++ b/testing/resources/pixel/bug_846_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_846_expected_mac.pdf.0.png b/testing/resources/pixel/bug_846_expected_mac.pdf.0.png
new file mode 100644
index 0000000..b405dce
--- /dev/null
+++ b/testing/resources/pixel/bug_846_expected_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_846_expected_skia.pdf.0.png b/testing/resources/pixel/bug_846_expected_skia.pdf.0.png
new file mode 100644
index 0000000..f7fa9ff
--- /dev/null
+++ b/testing/resources/pixel/bug_846_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_846_expected_skia_mac.pdf.0.png b/testing/resources/pixel/bug_846_expected_skia_mac.pdf.0.png
new file mode 100644
index 0000000..5635527
--- /dev/null
+++ b/testing/resources/pixel/bug_846_expected_skia_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_846_expected_skia_win.pdf.0.png b/testing/resources/pixel/bug_846_expected_skia_win.pdf.0.png
new file mode 100644
index 0000000..5635527
--- /dev/null
+++ b/testing/resources/pixel/bug_846_expected_skia_win.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_909762_expected.pdf.0.png b/testing/resources/pixel/bug_909762_expected.pdf.0.png
index 219c163..d01a7fc 100644
--- a/testing/resources/pixel/bug_909762_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_909762_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_909762_expected_win.pdf.0.png b/testing/resources/pixel/bug_909762_expected_win.pdf.0.png
deleted file mode 100644
index c6d2727..0000000
--- a/testing/resources/pixel/bug_909762_expected_win.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_925736_expected_agg_mac.pdf.0.png b/testing/resources/pixel/bug_925736_expected_agg_mac.pdf.0.png
new file mode 100644
index 0000000..1763451
--- /dev/null
+++ b/testing/resources/pixel/bug_925736_expected_agg_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_925736_expected_mac.pdf.0.png b/testing/resources/pixel/bug_925736_expected_mac.pdf.0.png
deleted file mode 100644
index f71efde..0000000
--- a/testing/resources/pixel/bug_925736_expected_mac.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_966263.in b/testing/resources/pixel/bug_966263.in
new file mode 100644
index 0000000..bddf328
--- /dev/null
+++ b/testing/resources/pixel/bug_966263.in
@@ -0,0 +1,132 @@
+{{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 1 0 R
+  /Contents 4 0 R
+  /MediaBox [0 0 200 400]
+  /Resources <<
+    /ProcSet [/PDF /Text]
+    /Font <<
+      /F1 5 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+BT
+/F1 1 Tf
+1 0 0 1 20 55 Tm
+(ABCD)Tj
+ET
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /Font
+  /Subtype /Type3
+  /FontBBox [0 0 600 600]
+  /FontMatrix [1 0 0 -100 0 0]
+  /CharProcs <<
+    /CA 6 0 R
+    /CB 7 0 R
+    /CC 8 0 R
+    /CD 9 0 R
+  >>
+  /Encoding <<
+    /Type /Encoding
+    /Differences [65 /CA 66 /CB 67 /CC 68 /CD]
+  >>
+  /FirstChar 65
+  /LastChar 68
+  /Widths [18 1000 18 18]
+  /Resources <<
+    /ProcSet [/PDF /ImageB]
+  >>
+>>
+endobj
+{{object 6 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+d0 0 0
+1 0 0 1 6 0 cm
+BI
+/W 1
+/H 1
+/BPC 1
+/IM true
+ID
+x
+EI
+Q
+endstream
+endobj
+{{object 7 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 8 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+6 0 0 1 2147483570 0 cm
+BI
+/W 6
+/H 1
+/BPC 1
+/IM true
+ID
+x
+EI
+Q
+endstream
+endobj
+{{object 9 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+1 0 0 6 0 21474834 cm
+BI
+/W 1
+/H 1
+/BPC 1
+/IM true
+ID
+x
+EI
+Q
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_966263_expected.pdf.0.png b/testing/resources/pixel/bug_966263_expected.pdf.0.png
new file mode 100644
index 0000000..84650b6
--- /dev/null
+++ b/testing/resources/pixel/bug_966263_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_972999.in b/testing/resources/pixel/bug_972999.in
new file mode 100644
index 0000000..6e928da
--- /dev/null
+++ b/testing/resources/pixel/bug_972999.in
@@ -0,0 +1,603 @@
+{{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 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 5 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 6 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 6 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 7 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 7 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 8 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 8 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 9 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 9 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 10 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 10 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 11 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 11 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 12 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 12 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 13 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 13 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 14 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 14 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 15 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 15 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 16 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 16 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 17 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 17 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 18 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 18 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 19 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 19 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 20 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 20 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 21 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 21 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 22 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 22 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 23 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 23 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 24 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 24 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 25 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 25 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 26 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 26 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 27 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 27 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 28 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 28 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 29 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 29 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 30 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 30 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 31 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 31 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 32 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 32 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 33 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 33 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 34 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 34 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 35 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 35 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 36 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 36 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 37 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 37 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 38 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 38 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  /Resources <<
+    /XObject <<
+      /X1 39 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+/X1 Do
+endstream
+endobj
+{{object 39 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 200 300]
+  {{streamlen}}
+>>
+stream
+q
+0 0 0 rg
+0 290 10 10 re B*
+10 150 50 30 re B*
+0 0 1 rg
+190 290 10 10 re B*
+70 232 50 30 re B*
+0 1 0 rg
+190 0 10 10 re B*
+130 150 50 30 re B*
+1 0 0 rg
+0 0 10 10 re B*
+70 67 50 30 re B*
+Q
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_972999_expected.pdf.0.png b/testing/resources/pixel/bug_972999_expected.pdf.0.png
new file mode 100644
index 0000000..ee652fa
--- /dev/null
+++ b/testing/resources/pixel/bug_972999_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_972999_expected_skia.pdf.0.png b/testing/resources/pixel/bug_972999_expected_skia.pdf.0.png
new file mode 100644
index 0000000..8a6b8ed
--- /dev/null
+++ b/testing/resources/pixel/bug_972999_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_983289.in b/testing/resources/pixel/bug_983289.in
new file mode 100644
index 0000000..438af5d
--- /dev/null
+++ b/testing/resources/pixel/bug_983289.in
@@ -0,0 +1,35 @@
+{{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
+  /MediaBox [0 0 612 792]
+  /Contents 4 0 R
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+2 0 0 2 0 0 cm
+-10926 -22396 m
+11272 23097 l
+S
+Q
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_983289_expected.pdf.0.png b/testing/resources/pixel/bug_983289_expected.pdf.0.png
new file mode 100644
index 0000000..27049d5
--- /dev/null
+++ b/testing/resources/pixel/bug_983289_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_984811_expected_agg_mac.pdf.0.png b/testing/resources/pixel/bug_984811_expected_agg_mac.pdf.0.png
new file mode 100644
index 0000000..4a217fa
--- /dev/null
+++ b/testing/resources/pixel/bug_984811_expected_agg_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_984811_expected_mac.pdf.0.png b/testing/resources/pixel/bug_984811_expected_mac.pdf.0.png
deleted file mode 100644
index e1ae9f2..0000000
--- a/testing/resources/pixel/bug_984811_expected_mac.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/bug_986108.in b/testing/resources/pixel/bug_986108.in
new file mode 100644
index 0000000..7af65f4
--- /dev/null
+++ b/testing/resources/pixel/bug_986108.in
@@ -0,0 +1,122 @@
+{{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
+  /MediaBox [0 0 200 200]
+  /Contents 4 0 R
+  /Resources <<
+    /ProcSet [/PDF /Text]
+    /ExtGState <<
+      /GS0 5 0 R
+    >>
+    /XObject <<
+      /Fm0 6 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+/GS0 gs
+/Fm0 Do
+Q
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /ExtGState
+  /OP false
+  /op false
+  /AIS false
+  /BM /Normal
+  /OPM 0
+  /CA 1.0
+  /SA true
+  /ca 1.0
+  /SMask 7 0 R
+>>
+endobj
+{{object 6 0}} <<
+  /Subtype /Form
+  {{streamlen}}
+>>
+stream
+q
+0 0 50 60 re f
+Q
+endstream
+endobj
+{{object 7 0}} <<
+  /Type /Mask
+  /BC [0.0]
+  /S /Luminosity
+  /G 8 0 R
+>>
+endobj
+{{object 8 0}} <<
+  /Subtype /Form
+  /BBox [0 411 621 -10]
+  /Resources <<
+    /XObject <<
+      /Fm0 9 0 R
+    >>
+  >>
+{{streamlen}}
+>>
+stream
+q
+0 410 500 -440 re f
+/Fm0 Do
+Q
+endstream
+endobj
+{{object 9 0}} <<
+  /Subtype /Form
+  /Resources <<
+    /Shading <<
+      /Sh0 10 0 R
+    >>
+  >>
+  {{streamlen}}
+>>
+stream
+q
+/Sh0 sh
+Q
+endstream
+endobj
+{{object 10 0}} <<
+  /ShadingType 2
+  /ColorSpace /DeviceRGB
+  /Coords [0.0 0.0 1.0 0.0]
+  /BBox [-0.1 -0.9 1.1 0.87]
+  /Extend [true true]
+  /Function 11 0 R
+  /Domain [0.0 1.0]
+>>
+endobj
+{{object 11 0}} <<
+  /FunctionType 2
+  /Domain [0.0 1.0]
+  /C0 [0.8 0.1 0.2]
+  /C1 [0.2 0.025 0.05]
+  /N 1
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/bug_986108_expected.pdf.0.png b/testing/resources/pixel/bug_986108_expected.pdf.0.png
new file mode 100644
index 0000000..f97e340
--- /dev/null
+++ b/testing/resources/pixel/bug_986108_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/checkbox_radiobutton.evt b/testing/resources/pixel/checkbox_radiobutton.evt
new file mode 100644
index 0000000..c519dcb
--- /dev/null
+++ b/testing/resources/pixel/checkbox_radiobutton.evt
@@ -0,0 +1,11 @@
+# Check the checkbox
+mousemove,145,220
+mousedown,left,145,220
+mouseup,left,145,220
+
+# Tab to radio button from checkbox
+keycode,9
+keycode,9
+
+# Press Enter to select radio button
+charcode,13
\ No newline at end of file
diff --git a/testing/resources/pixel/checkbox_radiobutton.fragment b/testing/resources/pixel/checkbox_radiobutton.fragment
new file mode 100644
index 0000000..013992e
--- /dev/null
+++ b/testing/resources/pixel/checkbox_radiobutton.fragment
@@ -0,0 +1,187 @@
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 300 300]
+  /Contents 4 0 R
+  /Annots [5 0 R 6 0 R 8 0 R 10 0 R]
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+q
+1 w
+1 0 1 RG
+1 .752941 .796078 rg
+n 135.5 250.5 19 19 re B*
+Q
+q
+2 w
+.1 .1 .1 RG
+.8 .843 1 rg
+n 136 211 18 18 re B*
+Q
+q
+2 w
+0 .501961 0 RG
+0 0 1 rg
+n
+104 110 m
+104 114.9706 99.97056 119 95 119 c
+90.02944 119 86 114.9706 86 110 c
+86 105.0294 90.02944 101 95 101 c
+99.97056 101 104 105.0294 104 110 c
+B*
+Q
+q
+2 w
+0 .501961 0 RG
+0 0 1 rg
+n
+104 60 m
+104 64.97056 99.97056 69 95 69 c
+90.02944 69 86 64.97056 86 60 c
+86 55.02944 90.02944 51 95 51 c
+99.97056 51 104 55.02944 104 60 c
+B*
+Q
+Q
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Btn
+  /Ff 1
+  /Rect [135 250 155 270]
+  /T (readOnlyCheckbox)
+  /AP <<
+    /N <<
+      /Yes 11 0 R
+    >>
+  >>
+  /AS /Off
+>>
+endobj
+{{object 6 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Btn
+  /Ff 2
+  /Rect [135 210 155 230]
+  /T (checkbox)
+  /AP <<
+    /N <<
+      /Yes 11 0 R
+    >>
+  >>
+  /AS /Off
+>>
+endobj
+{{object 7 0}} <<
+  /FT /Btn
+  /Ff 49153
+  /T (readOnlyRadioButton)
+  /Kids [8 0 R]
+>>
+endobj
+{{object 8 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /T (Widget8)
+  /FT /Btn
+  /Parent 7 0 R
+  /Rect [85 100 105 120]
+  /AP <<
+    /N <<
+      /value1 12 0 R
+    >>
+  >>
+  /AS /Off
+>>
+endobj
+{{object 9 0}} <<
+  /FT /Btn
+  /Ff 49154
+  /T (radioButton)
+  /Kids [10 0 R]
+>>
+endobj
+{{object 10 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Btn
+  /Parent 9 0 R
+  /Rect [85 50 105 70]
+  /AP <<
+    /N <<
+      /value1 12 0 R
+    >>
+  >>
+  /AS /Off
+>>
+endobj
+{{object 11 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 20 20]
+  {{streamlen}}
+>>
+stream
+q
+.1 .1 .1 rg .1 .1 .1 RG
+17.2 15.95145 m
+11.20694 10 l
+17.2 4.027746 l
+15.97225 2.8 l
+10 8.793064 l
+4.027746 2.8 l
+2.8 4.027746 l
+8.813873 10 l
+2.8 15.97225 l
+4.027746 17.2 l
+10 11.20694 l
+15.97225 17.2 l
+17.2 15.95145 l
+h
+f
+Q
+endstream
+endobj
+{{object 12 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 20 20]
+  {{streamlen}}
+>>
+stream
+q
+1 .752941 .796078 rg 1 .752941 .796078 RG
+17.2 15.95145 m
+11.20694 10 l
+17.2 4.027746 l
+15.97225 2.8 l
+10 8.793064 l
+4.027746 2.8 l
+2.8 4.027746 l
+8.813873 10 l
+2.8 15.97225 l
+4.027746 17.2 l
+10 11.20694 l
+15.97225 17.2 l
+17.2 15.95145 l
+h
+f
+Q
+endstream
+endobj
diff --git a/testing/resources/pixel/checkbox_radiobutton.in b/testing/resources/pixel/checkbox_radiobutton.in
new file mode 100644
index 0000000..116c638
--- /dev/null
+++ b/testing/resources/pixel/checkbox_radiobutton.in
@@ -0,0 +1,14 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /Fields [5 0 R 6 0 R 7 0 R 9 0 R]
+  >>
+>>
+endobj
+{{include checkbox_radiobutton.fragment}}
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/checkbox_radiobutton_expected.pdf.0.png b/testing/resources/pixel/checkbox_radiobutton_expected.pdf.0.png
new file mode 100644
index 0000000..8baabb7
--- /dev/null
+++ b/testing/resources/pixel/checkbox_radiobutton_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/checkbox_radiobutton_expected_skia.pdf.0.png b/testing/resources/pixel/checkbox_radiobutton_expected_skia.pdf.0.png
new file mode 100644
index 0000000..fe713a6
--- /dev/null
+++ b/testing/resources/pixel/checkbox_radiobutton_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/checkbox_radiobutton_hide.in b/testing/resources/pixel/checkbox_radiobutton_hide.in
new file mode 100644
index 0000000..340b6d5
--- /dev/null
+++ b/testing/resources/pixel/checkbox_radiobutton_hide.in
@@ -0,0 +1,23 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /Fields [5 0 R 6 0 R 7 0 R 9 0 R]
+  >>
+  /OpenAction 13 0 R
+>>
+endobj
+{{include checkbox_radiobutton.fragment}}
+% Make some buttons be hidden. Note that /T as an array of dict references
+% does not seem to work as expected.
+{{object 13 0}} <<
+  /Type /Action
+  /S /Hide
+  /T [(readOnlyRadioButton.Widget8) (readOnlyCheckbox)]
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/checkbox_radiobutton_hide_expected.pdf.0.png b/testing/resources/pixel/checkbox_radiobutton_hide_expected.pdf.0.png
new file mode 100644
index 0000000..361c05f
--- /dev/null
+++ b/testing/resources/pixel/checkbox_radiobutton_hide_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/checkbox_radiobutton_hide_expected_skia.pdf.0.png b/testing/resources/pixel/checkbox_radiobutton_hide_expected_skia.pdf.0.png
new file mode 100644
index 0000000..bdb2d6e
--- /dev/null
+++ b/testing/resources/pixel/checkbox_radiobutton_hide_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/checkbox_radiobutton_reset.in b/testing/resources/pixel/checkbox_radiobutton_reset.in
new file mode 100644
index 0000000..869107a
--- /dev/null
+++ b/testing/resources/pixel/checkbox_radiobutton_reset.in
@@ -0,0 +1,25 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /Fields [5 0 R 6 0 R 7 0 R 9 0 R]
+  >>
+  /OpenAction 13 0 R
+>>
+endobj
+{{include checkbox_radiobutton.fragment}}
+% Make some buttons be reset. Note that /T as an array of dict references
+% does not seem to work as expected. /Flags 1 means all fields *except*
+% those listed.
+{{object 13 0}} <<
+  /Type /Action
+  /S /ResetForm
+  /Fields [(readOnlyRadioButton.Widget8) (readOnlyCheckbox)]
+  /Flags 1
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/checkbox_radiobutton_reset_expected.pdf.0.png b/testing/resources/pixel/checkbox_radiobutton_reset_expected.pdf.0.png
new file mode 100644
index 0000000..dd94188
--- /dev/null
+++ b/testing/resources/pixel/checkbox_radiobutton_reset_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/checkbox_radiobutton_reset_expected_skia.pdf.0.png b/testing/resources/pixel/checkbox_radiobutton_reset_expected_skia.pdf.0.png
new file mode 100644
index 0000000..057ecda
--- /dev/null
+++ b/testing/resources/pixel/checkbox_radiobutton_reset_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/combobox_form.evt b/testing/resources/pixel/combobox_form.evt
new file mode 100644
index 0000000..8211937
--- /dev/null
+++ b/testing/resources/pixel/combobox_form.evt
@@ -0,0 +1,10 @@
+# Check the combobox control
+mousemove,102,410
+mousedown,left,102,410
+mouseup,left,102,410
+
+# Press Enter to open the pop-up menu
+charcode,13
+
+# Press Space to make sure that the pop-up is not dismissed
+charcode,32
\ No newline at end of file
diff --git a/testing/resources/pixel/combobox_form.in b/testing/resources/pixel/combobox_form.in
new file mode 100644
index 0000000..56adea4
--- /dev/null
+++ b/testing/resources/pixel/combobox_form.in
@@ -0,0 +1,35 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /Fields [4 0 R]
+  >>
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Annots [4 0 R]
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Ch
+  /Ff 131072
+  /T (Combo)
+  /Rect [100 400 200 430]
+  /Opt [() () ()]
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/combobox_form_expected.pdf.0.png b/testing/resources/pixel/combobox_form_expected.pdf.0.png
new file mode 100644
index 0000000..7ecd75d
--- /dev/null
+++ b/testing/resources/pixel/combobox_form_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/combobox_form_expected_skia.pdf.0.png b/testing/resources/pixel/combobox_form_expected_skia.pdf.0.png
new file mode 100644
index 0000000..4686e96
--- /dev/null
+++ b/testing/resources/pixel/combobox_form_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/font_size_expected.pdf.0.png b/testing/resources/pixel/font_size_expected.pdf.0.png
index b4506e0..91828b9 100644
--- a/testing/resources/pixel/font_size_expected.pdf.0.png
+++ b/testing/resources/pixel/font_size_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/font_size_expected_agg_mac.pdf.0.png b/testing/resources/pixel/font_size_expected_agg_mac.pdf.0.png
new file mode 100644
index 0000000..02e91d4
--- /dev/null
+++ b/testing/resources/pixel/font_size_expected_agg_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/font_size_expected_mac.pdf.0.png b/testing/resources/pixel/font_size_expected_mac.pdf.0.png
deleted file mode 100644
index dfd0690..0000000
--- a/testing/resources/pixel/font_size_expected_mac.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/font_size_expected_win.pdf.0.png b/testing/resources/pixel/font_size_expected_win.pdf.0.png
deleted file mode 100644
index a0d56aa..0000000
--- a/testing/resources/pixel/font_size_expected_win.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/generation_numbers1_expected.pdf.0.png b/testing/resources/pixel/generation_numbers1_expected.pdf.0.png
index f2d3ba9..522a738 100644
--- a/testing/resources/pixel/generation_numbers1_expected.pdf.0.png
+++ b/testing/resources/pixel/generation_numbers1_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/generation_numbers1_expected_agg_mac.pdf.0.png b/testing/resources/pixel/generation_numbers1_expected_agg_mac.pdf.0.png
new file mode 100644
index 0000000..c946aa7
--- /dev/null
+++ b/testing/resources/pixel/generation_numbers1_expected_agg_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/generation_numbers1_expected_mac.pdf.0.png b/testing/resources/pixel/generation_numbers1_expected_mac.pdf.0.png
deleted file mode 100644
index 8d973ac..0000000
--- a/testing/resources/pixel/generation_numbers1_expected_mac.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/generation_numbers1_expected_win.pdf.0.png b/testing/resources/pixel/generation_numbers1_expected_win.pdf.0.png
deleted file mode 100644
index 7f1047c..0000000
--- a/testing/resources/pixel/generation_numbers1_expected_win.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/generation_numbers2_expected.pdf.0.png b/testing/resources/pixel/generation_numbers2_expected.pdf.0.png
index f2d3ba9..522a738 100644
--- a/testing/resources/pixel/generation_numbers2_expected.pdf.0.png
+++ b/testing/resources/pixel/generation_numbers2_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/generation_numbers2_expected_agg_mac.pdf.0.png b/testing/resources/pixel/generation_numbers2_expected_agg_mac.pdf.0.png
new file mode 100644
index 0000000..c946aa7
--- /dev/null
+++ b/testing/resources/pixel/generation_numbers2_expected_agg_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/generation_numbers2_expected_mac.pdf.0.png b/testing/resources/pixel/generation_numbers2_expected_mac.pdf.0.png
deleted file mode 100644
index 8d973ac..0000000
--- a/testing/resources/pixel/generation_numbers2_expected_mac.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/generation_numbers2_expected_win.pdf.0.png b/testing/resources/pixel/generation_numbers2_expected_win.pdf.0.png
deleted file mode 100644
index 7f1047c..0000000
--- a/testing/resources/pixel/generation_numbers2_expected_win.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/image_transformer_other.in b/testing/resources/pixel/image_transformer_other.in
new file mode 100644
index 0000000..5d1f580
--- /dev/null
+++ b/testing/resources/pixel/image_transformer_other.in
@@ -0,0 +1,128 @@
+{{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 200 200]
+  /Resources <<
+    /ColorSpace <<
+      /CS0 5 0 R
+    >>
+    /XObject <<
+      /ImMonoPalette 6 0 R
+      /ImMono 7 0 R
+      /ImColor 8 0 R
+      /ImColorWithMask 9 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+-16 64 64 0 20 20 cm
+/ImMonoPalette Do
+Q
+q
+16 64 64 0 120 20 cm
+/ImMono Do
+Q
+q
+16 64 64 16 20 120 cm
+/ImColor Do
+Q
+q
+16 64 -64 16 120 120 cm
+/ImColorWithMask Do
+Q
+endstream
+endobj
+{{object 5 0}} [
+  /Indexed
+  /DeviceGray
+  0
+  <cc>
+]
+endobj
+{{object 6 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 1
+  /ColorSpace 5 0 R
+  /Height 4
+  /Width 4
+  {{streamlen}}
+>>
+stream
+0000
+endstream
+endobj
+{{object 7 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 4
+  /Height 4
+  /BitsPerComponent 8
+  /ColorSpace /DeviceGray
+  /Filter /ASCIIHexDecode
+  {{streamlen}}
+>>
+stream
+00000000
+33333333
+99999999
+cccccccc
+endstream
+endobj
+{{object 8 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter /ASCIIHexDecode
+  /Height 4
+  /Width 4
+  {{streamlen}}
+>>
+stream
+ff0000ff0000ff0000ff0000
+ff0000ff0000ff0000ff0000
+00ff0000ff0000ff0000ff00
+00ff0000ff0000ff0000ff00
+endstream
+endobj
+{{object 9 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter /ASCIIHexDecode
+  /Height 4
+  /Width 4
+  /Mask [0 255 0 0 0 0]
+  {{streamlen}}
+>>
+stream
+ff0000ff0000ff0000ff0000
+ff0000ff0000ff0000ff0000
+00ff0000ff0000ff0000ff00
+00ff0000ff0000ff0000ff00
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/image_transformer_other_expected.pdf.0.png b/testing/resources/pixel/image_transformer_other_expected.pdf.0.png
new file mode 100644
index 0000000..e9aab95
--- /dev/null
+++ b/testing/resources/pixel/image_transformer_other_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/image_transformer_other_expected_skia.pdf.0.png b/testing/resources/pixel/image_transformer_other_expected_skia.pdf.0.png
new file mode 100644
index 0000000..e65f919
--- /dev/null
+++ b/testing/resources/pixel/image_transformer_other_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/jpxdecode.in b/testing/resources/pixel/jpxdecode.in
new file mode 100644
index 0000000..d69b058
--- /dev/null
+++ b/testing/resources/pixel/jpxdecode.in
@@ -0,0 +1,177 @@
+{{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 88 128]
+  /Resources <<
+    /XObject <<
+      /ImGray 5 0 R
+      /ImGrayAlpha 6 0 R
+      /ImRGB 7 0 R
+      /ImRGBAlpha 8 0 R
+      /ImCMYK 9 0 R
+      /ImCMYKAlpha 10 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+
+% 50% gray background rectangle
+q
+  0.5 0.5 0.5 rg
+  0 0 88 128 re
+  f
+Q
+
+% grayscale, grayscale with alpha
+q
+  32 0 0 32 8 88 cm
+  /ImGray Do
+Q
+q
+  32 0 0 32 48 88 cm
+  /ImGrayAlpha Do
+Q
+
+% RGB, RGB with alpha
+q
+  32 0 0 32 8 48 cm
+  /ImRGB Do
+Q
+q
+  32 0 0 32 48 48 cm
+  /ImRGBAlpha Do
+Q
+
+% CMYK, CMYK with alpha
+q
+  32 0 0 32 8 8 cm
+  /ImCMYK Do
+Q
+q
+  32 0 0 32 48 8 cm
+  /ImCMYKAlpha Do
+Q
+
+endstream
+endobj
+
+% grayscale
+{{object 5 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceGray
+  /Filter /JPXDecode
+  /Height 4
+  /Width 4
+  {{streamlen}}
+>>
+stream
+{{include ../gray.jp2}}
+endstream
+endobj
+
+% grayscale with opacity
+{{object 6 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceGray
+  /Filter /JPXDecode
+  /Height 4
+  /SMaskInData 1
+  /Width 4
+  {{streamlen}}
+>>
+stream
+{{include ../gray-alpha.jp2}}
+endstream
+endobj
+
+% RGB
+{{object 7 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter /JPXDecode
+  /Height 4
+  /Width 4
+  {{streamlen}}
+>>
+stream
+{{include ../RGB.jp2}}
+endstream
+endobj
+
+% RGB with opacity
+{{object 8 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter /JPXDecode
+  /Height 4
+  /SMaskInData 1
+  /Width 4
+  {{streamlen}}
+>>
+stream
+{{include ../RGB-alpha.jp2}}
+endstream
+endobj
+
+% CMYK
+{{object 9 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceCMYK
+  /Filter /JPXDecode
+  /Height 4
+  /Width 4
+  {{streamlen}}
+>>
+stream
+{{include ../CMYK.jpf}}
+endstream
+endobj
+
+% CMYK with opacity.
+{{object 10 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceCMYK
+  /Filter /JPXDecode
+  /Height 4
+  /SMaskInData 1
+  /Width 4
+  {{streamlen}}
+>>
+stream
+{{include ../CMYK-alpha.jpf}}
+endstream
+endobj
+
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/jpxdecode_expected.pdf.0.png b/testing/resources/pixel/jpxdecode_expected.pdf.0.png
new file mode 100644
index 0000000..9051cb0
--- /dev/null
+++ b/testing/resources/pixel/jpxdecode_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/jpxdecode_with_mismatch_colorspace.in b/testing/resources/pixel/jpxdecode_with_mismatch_colorspace.in
new file mode 100644
index 0000000..ddf3068
--- /dev/null
+++ b/testing/resources/pixel/jpxdecode_with_mismatch_colorspace.in
@@ -0,0 +1,180 @@
+{{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 88 128]
+  /Resources <<
+    /XObject <<
+      /ImGrayCsRGB 5 0 R
+      /ImGrayCsCMYK 6 0 R
+      /ImRGBCsGray 7 0 R
+      /ImRGBCsCMYK 8 0 R
+      /ImCMYKCsGray 9 0 R
+      /ImCMYKCsRGB 10 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+
+% 50% gray background rectangle
+q
+  0.5 0.5 0.5 rg
+  0 0 88 128 re
+  f
+Q
+
+% grayscale image with RGB /ColorSpace entry
+q
+  32 0 0 32 8 88 cm
+  /ImGrayCsRGB Do
+Q
+
+% grayscale image with CMYK /ColorSpace entry
+q
+  32 0 0 32 48 88 cm
+  /ImGrayCsCMYK Do
+Q
+
+% RGB image with grayscale /ColorSpace entry
+q
+  32 0 0 32 8 48 cm
+  /ImRGBCsGray Do
+Q
+
+% RGB image with CMYK /ColorSpace entry
+q
+  32 0 0 32 48 48 cm
+  /ImRGBCsCMYK Do
+Q
+
+% CMYK image with grayscale /ColorSpace entry
+q
+  32 0 0 32 8 8 cm
+  /ImCMYKCsGray Do
+Q
+
+% CMYK image with RGB /ColorSpace entry
+q
+  32 0 0 32 48 8 cm
+  /ImCMYKCsRGB Do
+Q
+
+endstream
+endobj
+
+% grayscale image with RGB /ColorSpace
+{{object 5 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter /JPXDecode
+  /Height 4
+  /Width 4
+  {{streamlen}}
+>>
+stream
+{{include ../gray.jp2}}
+endstream
+endobj
+
+% grayscale image with CMYK /ColorSpace
+{{object 6 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceCMYK
+  /Filter /JPXDecode
+  /Height 4
+  /Width 4
+  {{streamlen}}
+>>
+stream
+{{include ../gray.jp2}}
+endstream
+endobj
+
+% RGB image with grayscale /ColorSpace
+{{object 7 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceGray
+  /Filter /JPXDecode
+  /Height 4
+  /Width 4
+  {{streamlen}}
+>>
+stream
+{{include ../RGB.jp2}}
+endstream
+endobj
+
+% RGB image with CMYK /ColorSpace
+{{object 8 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceCMYK
+  /Filter /JPXDecode
+  /Height 4
+  /Width 4
+  {{streamlen}}
+>>
+stream
+{{include ../RGB.jp2}}
+endstream
+endobj
+
+% CMYK image with grayscale /ColorSpace
+{{object 9 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceGray
+  /Filter /JPXDecode
+  /Height 4
+  /Width 4
+  {{streamlen}}
+>>
+stream
+{{include ../CMYK.jpf}}
+endstream
+endobj
+
+% CMYK image with RGB /ColorSpace
+{{object 10 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter /JPXDecode
+  /Height 4
+  /Width 4
+  {{streamlen}}
+>>
+stream
+{{include ../CMYK.jpf}}
+endstream
+endobj
+
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/jpxdecode_with_mismatch_colorspace_expected.pdf.0.png b/testing/resources/pixel/jpxdecode_with_mismatch_colorspace_expected.pdf.0.png
new file mode 100644
index 0000000..65743e0
--- /dev/null
+++ b/testing/resources/pixel/jpxdecode_with_mismatch_colorspace_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/jpxdecode_without_bitspercomponent.in b/testing/resources/pixel/jpxdecode_without_bitspercomponent.in
new file mode 100644
index 0000000..59b516f
--- /dev/null
+++ b/testing/resources/pixel/jpxdecode_without_bitspercomponent.in
@@ -0,0 +1,171 @@
+{{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 88 128]
+  /Resources <<
+    /XObject <<
+      /ImGray 5 0 R
+      /ImGrayAlpha 6 0 R
+      /ImRGB 7 0 R
+      /ImRGBAlpha 8 0 R
+      /ImCMYK 9 0 R
+      /ImCMYKAlpha 10 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+
+% 50% gray background rectangle
+q
+  0.5 0.5 0.5 rg
+  0 0 88 128 re
+  f
+Q
+
+% grayscale, grayscale with alpha
+q
+  32 0 0 32 8 88 cm
+  /ImGray Do
+Q
+q
+  32 0 0 32 48 88 cm
+  /ImGrayAlpha Do
+Q
+
+% RGB, RGB with alpha
+q
+  32 0 0 32 8 48 cm
+  /ImRGB Do
+Q
+q
+  32 0 0 32 48 48 cm
+  /ImRGBAlpha Do
+Q
+
+% CMYK, CMYK with alpha
+q
+  32 0 0 32 8 8 cm
+  /ImCMYK Do
+Q
+q
+  32 0 0 32 48 8 cm
+  /ImCMYKAlpha Do
+Q
+
+endstream
+endobj
+
+% grayscale
+{{object 5 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /ColorSpace /DeviceGray
+  /Filter /JPXDecode
+  /Height 4
+  /Width 4
+  {{streamlen}}
+>>
+stream
+{{include ../gray.jp2}}
+endstream
+endobj
+
+% grayscale with opacity
+{{object 6 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /ColorSpace /DeviceGray
+  /Filter /JPXDecode
+  /Height 4
+  /SMaskInData 1
+  /Width 4
+  {{streamlen}}
+>>
+stream
+{{include ../gray-alpha.jp2}}
+endstream
+endobj
+
+% RGB
+{{object 7 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /ColorSpace /DeviceRGB
+  /Filter /JPXDecode
+  /Height 4
+  /Width 4
+  {{streamlen}}
+>>
+stream
+{{include ../RGB.jp2}}
+endstream
+endobj
+
+% RGB with opacity
+{{object 8 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /ColorSpace /DeviceRGB
+  /Filter /JPXDecode
+  /Height 4
+  /SMaskInData 1
+  /Width 4
+  {{streamlen}}
+>>
+stream
+{{include ../RGB-alpha.jp2}}
+endstream
+endobj
+
+% CMYK
+{{object 9 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /ColorSpace /DeviceCMYK
+  /Filter /JPXDecode
+  /Height 4
+  /Width 4
+  {{streamlen}}
+>>
+stream
+{{include ../CMYK.jpf}}
+endstream
+endobj
+
+% CMYK with opacity.
+{{object 10 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /ColorSpace /DeviceCMYK
+  /Filter /JPXDecode
+  /Height 4
+  /SMaskInData 1
+  /Width 4
+  {{streamlen}}
+>>
+stream
+{{include ../CMYK-alpha.jpf}}
+endstream
+endobj
+
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/jpxdecode_without_bitspercomponent_expected.pdf.0.png b/testing/resources/pixel/jpxdecode_without_bitspercomponent_expected.pdf.0.png
new file mode 100644
index 0000000..9051cb0
--- /dev/null
+++ b/testing/resources/pixel/jpxdecode_without_bitspercomponent_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/jpxdecode_without_colorspace.in b/testing/resources/pixel/jpxdecode_without_colorspace.in
new file mode 100644
index 0000000..0ffb64f
--- /dev/null
+++ b/testing/resources/pixel/jpxdecode_without_colorspace.in
@@ -0,0 +1,171 @@
+{{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 88 128]
+  /Resources <<
+    /XObject <<
+      /ImGray 5 0 R
+      /ImGrayAlpha 6 0 R
+      /ImRGB 7 0 R
+      /ImRGBAlpha 8 0 R
+      /ImCMYK 9 0 R
+      /ImCMYKAlpha 10 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+
+% 50% gray background rectangle
+q
+  0.5 0.5 0.5 rg
+  0 0 88 128 re
+  f
+Q
+
+% grayscale, grayscale with alpha
+q
+  32 0 0 32 8 88 cm
+  /ImGray Do
+Q
+q
+  32 0 0 32 48 88 cm
+  /ImGrayAlpha Do
+Q
+
+% RGB, RGB with alpha
+q
+  32 0 0 32 8 48 cm
+  /ImRGB Do
+Q
+q
+  32 0 0 32 48 48 cm
+  /ImRGBAlpha Do
+Q
+
+% CMYK, CMYK with alpha
+q
+  32 0 0 32 8 8 cm
+  /ImCMYK Do
+Q
+q
+  32 0 0 32 48 8 cm
+  /ImCMYKAlpha Do
+Q
+
+endstream
+endobj
+
+% grayscale
+{{object 5 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /Filter /JPXDecode
+  /Height 4
+  /Width 4
+  {{streamlen}}
+>>
+stream
+{{include ../gray.jp2}}
+endstream
+endobj
+
+% grayscale with opacity
+{{object 6 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /Filter /JPXDecode
+  /Height 4
+  /SMaskInData 1
+  /Width 4
+  {{streamlen}}
+>>
+stream
+{{include ../gray-alpha.jp2}}
+endstream
+endobj
+
+% RGB
+{{object 7 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /Filter /JPXDecode
+  /Height 4
+  /Width 4
+  {{streamlen}}
+>>
+stream
+{{include ../RGB.jp2}}
+endstream
+endobj
+
+% RGB with opacity
+{{object 8 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /Filter /JPXDecode
+  /Height 4
+  /SMaskInData 1
+  /Width 4
+  {{streamlen}}
+>>
+stream
+{{include ../RGB-alpha.jp2}}
+endstream
+endobj
+
+% CMYK
+{{object 9 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /Filter /JPXDecode
+  /Height 4
+  /Width 4
+  {{streamlen}}
+>>
+stream
+{{include ../CMYK.jpf}}
+endstream
+endobj
+
+% CMYK with opacity.
+{{object 10 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /Filter /JPXDecode
+  /Height 4
+  /SMaskInData 1
+  /Width 4
+  {{streamlen}}
+>>
+stream
+{{include ../CMYK-alpha.jpf}}
+endstream
+endobj
+
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/jpxdecode_without_colorspace_expected.pdf.0.png b/testing/resources/pixel/jpxdecode_without_colorspace_expected.pdf.0.png
new file mode 100644
index 0000000..9051cb0
--- /dev/null
+++ b/testing/resources/pixel/jpxdecode_without_colorspace_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/jpxdecode_without_smaskindata.in b/testing/resources/pixel/jpxdecode_without_smaskindata.in
new file mode 100644
index 0000000..ab29a60
--- /dev/null
+++ b/testing/resources/pixel/jpxdecode_without_smaskindata.in
@@ -0,0 +1,111 @@
+{{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 48 128]
+  /Resources <<
+    /XObject <<
+      /ImGrayAlpha 5 0 R
+      /ImRGBAlpha 6 0 R
+      /ImCMYKAlpha 7 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+
+% 50% gray background rectangle
+q
+  0.5 0.5 0.5 rg
+  0 0 48 128 re
+  f
+Q
+
+% grayscale with ignored alpha
+q
+  32 0 0 32 8 88 cm
+  /ImGrayAlpha Do
+Q
+
+% RGB with ignored alpha
+q
+  32 0 0 32 8 48 cm
+  /ImRGBAlpha Do
+Q
+
+% CMYK with ignored alpha
+q
+  32 0 0 32 8 8 cm
+  /ImCMYKAlpha Do
+Q
+
+endstream
+endobj
+
+% grayscale with opacity, but the soft-mask information is not used.
+{{object 5 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceGray
+  /Filter /JPXDecode
+  /Height 4
+  /Width 4
+  {{streamlen}}
+>>
+stream
+{{include ../gray-alpha.jp2}}
+endstream
+endobj
+
+% RGB with opacity, but the soft-mask information is not used.
+{{object 6 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter /JPXDecode
+  /Height 4
+  /Width 4
+  {{streamlen}}
+>>
+stream
+{{include ../RGB-alpha.jp2}}
+endstream
+endobj
+
+% CMYK with opacity, but the soft-mask information is not used.
+{{object 7 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /BitsPerComponent 8
+  /ColorSpace /DeviceCMYK
+  /Filter /JPXDecode
+  /Height 4
+  /Width 4
+  {{streamlen}}
+>>
+stream
+{{include ../CMYK-alpha.jpf}}
+endstream
+endobj
+
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/jpxdecode_without_smaskindata_expected.pdf.0.png b/testing/resources/pixel/jpxdecode_without_smaskindata_expected.pdf.0.png
new file mode 100644
index 0000000..5405d1e
--- /dev/null
+++ b/testing/resources/pixel/jpxdecode_without_smaskindata_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/long_dashed_line.in b/testing/resources/pixel/long_dashed_line.in
new file mode 100644
index 0000000..623adfa
--- /dev/null
+++ b/testing/resources/pixel/long_dashed_line.in
@@ -0,0 +1,33 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /MediaBox [0 0 800 800]
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 4 0 R
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+[2 2] 0 d
+100 100 m
+100 -75697008 l
+S
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/long_dashed_line_expected.pdf.0.png b/testing/resources/pixel/long_dashed_line_expected.pdf.0.png
new file mode 100644
index 0000000..41b3efb
--- /dev/null
+++ b/testing/resources/pixel/long_dashed_line_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/long_dashed_line_expected_skia.pdf.0.png b/testing/resources/pixel/long_dashed_line_expected_skia.pdf.0.png
new file mode 100644
index 0000000..3ffc2d6
--- /dev/null
+++ b/testing/resources/pixel/long_dashed_line_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/matte_expected_skia.pdf.0.png b/testing/resources/pixel/matte_expected_skia.pdf.0.png
new file mode 100644
index 0000000..bdab404
--- /dev/null
+++ b/testing/resources/pixel/matte_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/password.evt b/testing/resources/pixel/password.evt
new file mode 100644
index 0000000..3051015
--- /dev/null
+++ b/testing/resources/pixel/password.evt
@@ -0,0 +1,26 @@
+mousemove,102,102
+mousedown,left,102,102
+mouseup,left,102,102
+charcode,116
+charcode,105
+charcode,103
+charcode,101
+charcode,114
+charcode,115
+charcode,115
+charcode,115
+charcode,115
+
+mousemove,102,162
+mousedown,left,102,162
+mouseup,left,102,162
+charcode,116
+charcode,105
+charcode,103
+charcode,101
+charcode,114
+charcode,115
+charcode,115
+charcode,115
+charcode,115
+
diff --git a/testing/resources/pixel/password.in b/testing/resources/pixel/password.in
new file mode 100644
index 0000000..a50f0af
--- /dev/null
+++ b/testing/resources/pixel/password.in
@@ -0,0 +1,54 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /Fields [
+      4 0 R
+      5 0 R
+    ]
+    /NeedAppearances true
+  >>
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [ 3 0 R ]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [ 0 0 300 200 ]
+  /Annots [
+    4 0 R
+    5 0 R
+  ]
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Tx
+  /T (Text Box)
+  /Rect [ 100 100 200 130 ]
+  /MaxLen 5
+  /Q 1
+>>
+endobj
+{{object 5 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Tx
+  /Ff 8192
+  /T (Password Box)
+  /Rect [ 100 160 200 190 ]
+  /MaxLen 5
+  /Q 2
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/password_expected.pdf.0.png b/testing/resources/pixel/password_expected.pdf.0.png
new file mode 100644
index 0000000..5040ef6
--- /dev/null
+++ b/testing/resources/pixel/password_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/password_expected_mac.pdf.0.png b/testing/resources/pixel/password_expected_mac.pdf.0.png
new file mode 100644
index 0000000..2f4239f
--- /dev/null
+++ b/testing/resources/pixel/password_expected_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/password_expected_skia.pdf.0.png b/testing/resources/pixel/password_expected_skia.pdf.0.png
new file mode 100644
index 0000000..01b4b68
--- /dev/null
+++ b/testing/resources/pixel/password_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/radial_shading_point_at_border_expected_skia.pdf.0.png b/testing/resources/pixel/radial_shading_point_at_border_expected_skia.pdf.0.png
new file mode 100644
index 0000000..92f2349
--- /dev/null
+++ b/testing/resources/pixel/radial_shading_point_at_border_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/radial_shading_point_at_border_no_extend_expected_skia.pdf.0.png b/testing/resources/pixel/radial_shading_point_at_border_no_extend_expected_skia.pdf.0.png
new file mode 100644
index 0000000..846a9ea
--- /dev/null
+++ b/testing/resources/pixel/radial_shading_point_at_border_no_extend_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/radial_shading_point_at_center_expected_skia.pdf.0.png b/testing/resources/pixel/radial_shading_point_at_center_expected_skia.pdf.0.png
new file mode 100644
index 0000000..756ddb8
--- /dev/null
+++ b/testing/resources/pixel/radial_shading_point_at_center_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/reset_button.evt b/testing/resources/pixel/reset_button.evt
new file mode 100644
index 0000000..1606926
--- /dev/null
+++ b/testing/resources/pixel/reset_button.evt
@@ -0,0 +1,10 @@
+# Check the checkbox
+mousemove,145,220
+mousedown,left,145,220
+mouseup,left,145,220
+
+# Tab to reset button from checkbox
+keycode,9
+
+# Press Enter to reset the form
+charcode,13
\ No newline at end of file
diff --git a/testing/resources/pixel/reset_button.in b/testing/resources/pixel/reset_button.in
new file mode 100644
index 0000000..6f93570
--- /dev/null
+++ b/testing/resources/pixel/reset_button.in
@@ -0,0 +1,97 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /Fields [5 0 R 6 0 R]
+  >>
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 300 300]
+  /Contents 4 0 R
+  /Annots [5 0 R 6 0 R]
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+2 w
+.1 .1 .1 RG
+.8 .843 1 rg
+n 136 211 18 18 re B*
+Q
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Btn
+  /F 4
+  /Ff 2
+  /P 3 0 R
+  /Rect [135 210 155 230]
+  /T (checkbox)
+  /AP <<
+    /N <<
+      /Yes 7 0 R
+    >>
+  >>
+  /AS /Off
+  /V /Off
+>>
+endobj
+{{object 6 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Btn
+  /F 4
+  /P 3 0 R
+  /Rect [135 110 185 150]
+  /T (Reset button)
+  /Ff 65536
+  /A <<
+   /S /ResetForm
+   /Fields [5 0 R]
+   /Flags 1
+  >>
+  /MK <<
+    /BC [0.0 0.0 0.4]
+    /BG [0.9 0.9 0.9]
+  >>
+>>
+endobj
+{{object 7 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 20 20]
+  {{streamlen}}
+>>
+stream
+q
+17.2 15.95145 m
+17.2 4.027746 l
+15.97225 2.8 l
+4.027746 2.8 l
+4.027746 17.2 l
+15.97225 17.2 l
+h
+f
+Q
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
\ No newline at end of file
diff --git a/testing/resources/pixel/reset_button_expected.pdf.0.png b/testing/resources/pixel/reset_button_expected.pdf.0.png
new file mode 100644
index 0000000..e36c30d
--- /dev/null
+++ b/testing/resources/pixel/reset_button_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/scrollable_widgets1.evt b/testing/resources/pixel/scrollable_widgets1.evt
new file mode 100644
index 0000000..c595cd7
--- /dev/null
+++ b/testing/resources/pixel/scrollable_widgets1.evt
@@ -0,0 +1,29 @@
+# Must move the mouse and click to give widget focus.
+mousemove,150,415
+mousedown,left,150,415
+# Scroll all the way down.
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
diff --git a/testing/resources/pixel/scrollable_widgets1.in b/testing/resources/pixel/scrollable_widgets1.in
new file mode 100644
index 0000000..9453b7c
--- /dev/null
+++ b/testing/resources/pixel/scrollable_widgets1.in
@@ -0,0 +1,52 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /Fields [5 0 R]
+    /DR <<
+      /Font <<
+        /F1 4 0 R
+      >>
+    >>
+  >>
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 300 600]
+  /Annots [5 0 R]
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+>>
+endobj
+{{object 5 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Ch
+  /Ff 2097152
+  /T (Listbox_MultiSelect)
+  /DA (0 0 0 rg /F1 12 Tf)
+  /Rect [100 400 200 430]
+  /Opt [(Apple) (Banana) (Cherry) (Date) (Elderberry) (Fig) (Guava) (Honeydew)
+        (Indian Fig) (Jackfruit) (Kiwi) (Lemon) (Mango) (Nectarine) (Orange)
+        (Persimmon) (Quince) (Raspberry) (Strawberry) (Tamarind) (Ugli Fruit)
+        (Voavanga) (Wolfberry) (Xigua) (Yangmei) (Zucchini)]
+  /V (Banana)
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/scrollable_widgets1_expected.pdf.0.png b/testing/resources/pixel/scrollable_widgets1_expected.pdf.0.png
new file mode 100644
index 0000000..7760af7
--- /dev/null
+++ b/testing/resources/pixel/scrollable_widgets1_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/scrollable_widgets1_expected_mac.pdf.0.png b/testing/resources/pixel/scrollable_widgets1_expected_mac.pdf.0.png
new file mode 100644
index 0000000..5dbdc5a
--- /dev/null
+++ b/testing/resources/pixel/scrollable_widgets1_expected_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/scrollable_widgets1_expected_skia.pdf.0.png b/testing/resources/pixel/scrollable_widgets1_expected_skia.pdf.0.png
new file mode 100644
index 0000000..d4c1f9d
--- /dev/null
+++ b/testing/resources/pixel/scrollable_widgets1_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/scrollable_widgets2.evt b/testing/resources/pixel/scrollable_widgets2.evt
new file mode 100644
index 0000000..59b8a4b
--- /dev/null
+++ b/testing/resources/pixel/scrollable_widgets2.evt
@@ -0,0 +1,34 @@
+# Must move the mouse and click to give widget focus.
+mousemove,150,415
+mousedown,left,150,415
+# Scroll all the way down and then scroll back up a bit.
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,-1
+mousewheel,150,415,0,1
+mousewheel,150,415,0,1
+mousewheel,150,415,0,1
+mousewheel,150,415,0,1
+mousewheel,150,415,0,1
diff --git a/testing/resources/pixel/scrollable_widgets2.in b/testing/resources/pixel/scrollable_widgets2.in
new file mode 100644
index 0000000..9453b7c
--- /dev/null
+++ b/testing/resources/pixel/scrollable_widgets2.in
@@ -0,0 +1,52 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /Fields [5 0 R]
+    /DR <<
+      /Font <<
+        /F1 4 0 R
+      >>
+    >>
+  >>
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 300 600]
+  /Annots [5 0 R]
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+>>
+endobj
+{{object 5 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Ch
+  /Ff 2097152
+  /T (Listbox_MultiSelect)
+  /DA (0 0 0 rg /F1 12 Tf)
+  /Rect [100 400 200 430]
+  /Opt [(Apple) (Banana) (Cherry) (Date) (Elderberry) (Fig) (Guava) (Honeydew)
+        (Indian Fig) (Jackfruit) (Kiwi) (Lemon) (Mango) (Nectarine) (Orange)
+        (Persimmon) (Quince) (Raspberry) (Strawberry) (Tamarind) (Ugli Fruit)
+        (Voavanga) (Wolfberry) (Xigua) (Yangmei) (Zucchini)]
+  /V (Banana)
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/scrollable_widgets2_expected.pdf.0.png b/testing/resources/pixel/scrollable_widgets2_expected.pdf.0.png
new file mode 100644
index 0000000..06e06ec
--- /dev/null
+++ b/testing/resources/pixel/scrollable_widgets2_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/scrollable_widgets2_expected_mac.pdf.0.png b/testing/resources/pixel/scrollable_widgets2_expected_mac.pdf.0.png
new file mode 100644
index 0000000..aa4917f
--- /dev/null
+++ b/testing/resources/pixel/scrollable_widgets2_expected_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/scrollable_widgets2_expected_skia.pdf.0.png b/testing/resources/pixel/scrollable_widgets2_expected_skia.pdf.0.png
new file mode 100644
index 0000000..dd9f6a1
--- /dev/null
+++ b/testing/resources/pixel/scrollable_widgets2_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/text_form_custom_font.in b/testing/resources/pixel/text_form_custom_font.in
new file mode 100644
index 0000000..af404e4
--- /dev/null
+++ b/testing/resources/pixel/text_form_custom_font.in
@@ -0,0 +1,81 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /DR <<
+      /Font <<
+        /TT0 5 0 R
+      >>
+    >>
+    /Fields [4 0 R]
+  >>
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Annots [4 0 R]
+  /MediaBox [0 0 200 200]
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Tx
+  /DA (1 0 0 rg /TT0 16 Tf)
+  /Rect [50 100 150 130]
+  /T (Text Box)
+  /V (      )
+>>
+endobj
+{{object 5 0}} <<
+  /Type /Font
+  /Subtype /TrueType
+  /FirstChar 32
+  /BaseFont /AAAAAD+Test
+  /FontDescriptor 6 0 R
+  /ToUnicode 7 0 R
+  /LastChar 32
+  /Widths [1055]
+>>
+endobj
+{{object 6 0}} <<
+  /Type /FontDescriptor
+  /Descent -68
+  /MissingWidth 1000
+  /CapHeight 1149
+  /StemV 0
+  /FontFile2 8 0 R
+  /Flags 4
+  /FontBBox [0 -215 1000 932]
+  /FontName /AAAAAD+Test
+  /ItalicAngle 0
+  /Ascent 933
+>>
+endobj
+{{object 7 0}} <<
+  {{streamlen}}
+>>
+stream
+{{include ../bug_1388_cmap.fragment}}
+endstream
+endobj
+{{object 8 0}} <<
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  {{streamlen}}
+>>
+stream
+{{include ../bug_1388_truetype_font.fragment}}
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/text_form_custom_font_expected.pdf.0.png b/testing/resources/pixel/text_form_custom_font_expected.pdf.0.png
new file mode 100644
index 0000000..3894ad5
--- /dev/null
+++ b/testing/resources/pixel/text_form_custom_font_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/text_form_custom_font_expected_mac.pdf.0.png b/testing/resources/pixel/text_form_custom_font_expected_mac.pdf.0.png
new file mode 100644
index 0000000..01b3dbf
--- /dev/null
+++ b/testing/resources/pixel/text_form_custom_font_expected_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/text_form_custom_font_expected_skia.pdf.0.png b/testing/resources/pixel/text_form_custom_font_expected_skia.pdf.0.png
new file mode 100644
index 0000000..47582b6
--- /dev/null
+++ b/testing/resources/pixel/text_form_custom_font_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/type3_expected.pdf.0.png b/testing/resources/pixel/type3_expected.pdf.0.png
index 6837bb8..63d9e57 100644
--- a/testing/resources/pixel/type3_expected.pdf.0.png
+++ b/testing/resources/pixel/type3_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/use_symbolneu/bug_1449.in b/testing/resources/pixel/use_symbolneu/bug_1449.in
new file mode 100644
index 0000000..603eb56
--- /dev/null
+++ b/testing/resources/pixel/use_symbolneu/bug_1449.in
@@ -0,0 +1,47 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /MediaBox [ 0 0 100 100 ]
+  /Count 1
+  /Kids [ 3 0 R ]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Resources <<
+    /Font <<
+      /F0 4 0 R
+    >>
+  >>
+  /Contents 5 0 R
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Font
+  /Subtype /TrueType
+  /BaseFont /Symbol
+  /FirstChar 31
+  /LastChar 255
+  /Name /F0
+>>
+endobj
+{{object 5 0}} <<
+ {{streamlen}}
+>>
+stream
+BT
+25 25 Td /F0 12 Tf
+-0.036  Tc (\265) Tj
+ET
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/use_symbolneu/bug_1449_expected.pdf.0.png b/testing/resources/pixel/use_symbolneu/bug_1449_expected.pdf.0.png
new file mode 100644
index 0000000..319932a
--- /dev/null
+++ b/testing/resources/pixel/use_symbolneu/bug_1449_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/barcode_test_expected_skia.pdf.0.png b/testing/resources/pixel/xfa_specific/barcode_test_expected_skia.pdf.0.png
new file mode 100644
index 0000000..3716b9c
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/barcode_test_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/barcode_test_expected_win.pdf.0.png b/testing/resources/pixel/xfa_specific/barcode_test_expected_win.pdf.0.png
deleted file mode 100644
index 23b80a7..0000000
--- a/testing/resources/pixel/xfa_specific/barcode_test_expected_win.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/bug_1282_expected_skia.pdf.0.png b/testing/resources/pixel/xfa_specific/bug_1282_expected_skia.pdf.0.png
new file mode 100644
index 0000000..a29272f
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/bug_1282_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/bug_1286970.in b/testing/resources/pixel/xfa_specific/bug_1286970.in
new file mode 100644
index 0000000..4454de7
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/bug_1286970.in
@@ -0,0 +1,31 @@
+{{header}}
+{{include ../../xfa_catalog_1_0.fragment}}
+{{include ../../xfa_object_2_0.fragment}}
+{{include ../../xfa_preamble_3_0.fragment}}
+{{include ../../xfa_config_4_0.fragment}}
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+<template xmlns="http://www.xfa.org/schema/xfa-template/3.3/">
+  <subform layout="rl-tb" name="subform1">
+    <pageSet>
+      <pageArea name="Page1" id="Page1">
+        <contentArea x="18pt" y="18pt" w="72pt" h="72pt"/>
+        <medium stock="default" short="72pt" long="72pt"/>
+      </pageArea>
+    </pageSet>
+    <subformSet>
+      <subform><field h="73pt"></field></subform>
+    </subformSet>
+  </subform>
+</template>
+endstream
+endobj
+{{include ../../xfa_locale_6_0.fragment}}
+{{include ../../xfa_postamble_7_0.fragment}}
+{{include ../../xfa_pages_8_0.fragment}}
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/xfa_specific/bug_1286970_expected.pdf.0.png b/testing/resources/pixel/xfa_specific/bug_1286970_expected.pdf.0.png
new file mode 100644
index 0000000..9b4c2d8
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/bug_1286970_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/bug_1337.in b/testing/resources/pixel/xfa_specific/bug_1337.in
new file mode 100644
index 0000000..d44a496
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/bug_1337.in
@@ -0,0 +1,38 @@
+{{header}}
+{{include ../../xfa_catalog_1_0.fragment}}
+{{include ../../xfa_object_2_0.fragment}}
+{{include ../../xfa_preamble_3_0.fragment}}
+{{include ../../xfa_config_4_0.fragment}}
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+<template xmlns="http://www.xfa.org/schema/xfa-template/3.3/">
+  <subform name="form1" layout="tb" locale="en_US" restoreState="auto">
+    <pageSet>
+      <pageArea name="Page1" id="Page1">
+        <contentArea x="18pt" y="18pt" w="612pt" h="792pt"/>
+        <medium stock="default" short="612pt" long="792pt"/>
+      </pageArea>
+    </pageSet>
+    <subform w="576pt" h="756pt" name="Page1">
+      <draw name="StaticImage1" w="250pt" h="250pt" x="10pt" y="10pt">
+        <value>
+          <image contentType="image/gif">R0lGODdh+gD6AIABAP8AAP///ywAAAAA+gD6AAAC/oSPqcvtD6OctNqLs968+w+G4kiW5omm6sq27gvH8kzX9o3n+s73/g8MCofEovGITCqXzKbzCY1Kp9Sq9YrNarfcrvcLDovH5LL5jE6r1+y2+w2Py+f0uv2Oz+v3/L7/DxgoOEhYaHiImKi4yNjo+AgZKTlJWWl5iZmpucnZ6fkJGio6SlpqeoqaqrrK2ur6ChsrO0tba3uLm6u7y9vr+wscLDxMXGx8jJysvMzc7PwMHS09TV1tfY2drb3N3e39DR4uPk5ebn6Onq6+zt7u/g4fLz9PX29/j5+vv8/f7/8PMKDAgQQLGjyIMKHChQwbOnwIMaLEiRQrWryIMaPGV40cO3r8CDKkyJEkS5o8iTKlypUsW7p8CTOmzJk0a9q8iTOnzp08e/r8CTSo0KFEixo9ijSp0qVMmzp9CjWq1KlUq1q9ijWr1q1cu3r9Cjas2LFky14oAAA7</image>
+        </value>
+        <ui>
+          <imageEdit/>
+        </ui>
+      </draw>
+    </subform>
+  </subform>
+</template>
+endstream
+endobj
+{{include ../../xfa_locale_6_0.fragment}}
+{{include ../../xfa_postamble_7_0.fragment}}
+{{include ../../xfa_pages_8_0.fragment}}
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/xfa_specific/bug_1337_expected.pdf.0.png b/testing/resources/pixel/xfa_specific/bug_1337_expected.pdf.0.png
new file mode 100644
index 0000000..c0d8380
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/bug_1337_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/bug_983137_expected_skia.pdf.0.png b/testing/resources/pixel/xfa_specific/bug_983137_expected_skia.pdf.0.png
new file mode 100644
index 0000000..7c19b45
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/bug_983137_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/dynamic_list_box_allow_multiple_selection_expected_skia.pdf.0.png b/testing/resources/pixel/xfa_specific/dynamic_list_box_allow_multiple_selection_expected_skia.pdf.0.png
new file mode 100644
index 0000000..3ccc1a2
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/dynamic_list_box_allow_multiple_selection_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/dynamic_list_box_allow_multiple_selection_expected_skia_mac.pdf.0.png b/testing/resources/pixel/xfa_specific/dynamic_list_box_allow_multiple_selection_expected_skia_mac.pdf.0.png
new file mode 100644
index 0000000..eb303b2
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/dynamic_list_box_allow_multiple_selection_expected_skia_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/dynamic_password_field_background_fill_expected.pdf.0.png b/testing/resources/pixel/xfa_specific/dynamic_password_field_background_fill_expected.pdf.0.png
index d20d7ea..c1cebee 100644
--- a/testing/resources/pixel/xfa_specific/dynamic_password_field_background_fill_expected.pdf.0.png
+++ b/testing/resources/pixel/xfa_specific/dynamic_password_field_background_fill_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/dynamic_password_field_background_fill_expected_skia.pdf.0.png b/testing/resources/pixel/xfa_specific/dynamic_password_field_background_fill_expected_skia.pdf.0.png
new file mode 100644
index 0000000..072a537
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/dynamic_password_field_background_fill_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/dynamic_password_field_background_fill_expected_win.pdf.0.png b/testing/resources/pixel/xfa_specific/dynamic_password_field_background_fill_expected_win.pdf.0.png
deleted file mode 100644
index 734b7e4..0000000
--- a/testing/resources/pixel/xfa_specific/dynamic_password_field_background_fill_expected_win.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/dynamic_table_color_and_width_expected_skia.pdf.0.png b/testing/resources/pixel/xfa_specific/dynamic_table_color_and_width_expected_skia.pdf.0.png
new file mode 100644
index 0000000..d443a35
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/dynamic_table_color_and_width_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/dynamic_table_color_and_width_expected_win.pdf.0.png b/testing/resources/pixel/xfa_specific/dynamic_table_color_and_width_expected_win.pdf.0.png
deleted file mode 100644
index eae383c..0000000
--- a/testing/resources/pixel/xfa_specific/dynamic_table_color_and_width_expected_win.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/resolve_nodes_0_expected.pdf.0.png b/testing/resources/pixel/xfa_specific/resolve_nodes_0_expected.pdf.0.png
index a3d9830..adfabbc 100644
--- a/testing/resources/pixel/xfa_specific/resolve_nodes_0_expected.pdf.0.png
+++ b/testing/resources/pixel/xfa_specific/resolve_nodes_0_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/resolve_nodes_0_expected_skia.pdf.0.png b/testing/resources/pixel/xfa_specific/resolve_nodes_0_expected_skia.pdf.0.png
new file mode 100644
index 0000000..884a23f
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/resolve_nodes_0_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/standard_symbols_expected.pdf.0.png b/testing/resources/pixel/xfa_specific/standard_symbols_expected.pdf.0.png
new file mode 100644
index 0000000..62f3156
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/standard_symbols_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/standard_symbols_expected.pdf.1.png b/testing/resources/pixel/xfa_specific/standard_symbols_expected.pdf.1.png
new file mode 100644
index 0000000..e262e83
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/standard_symbols_expected.pdf.1.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/static_list_box_caption_expected_mac.pdf.0.png b/testing/resources/pixel/xfa_specific/static_list_box_caption_expected_mac.pdf.0.png
index 7cba6b9..b9066f4 100644
--- a/testing/resources/pixel/xfa_specific/static_list_box_caption_expected_mac.pdf.0.png
+++ b/testing/resources/pixel/xfa_specific/static_list_box_caption_expected_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/static_list_box_caption_expected_skia.pdf.0.png b/testing/resources/pixel/xfa_specific/static_list_box_caption_expected_skia.pdf.0.png
new file mode 100644
index 0000000..3beefe0
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/static_list_box_caption_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/static_list_box_caption_expected_win.pdf.0.png b/testing/resources/pixel/xfa_specific/static_list_box_caption_expected_win.pdf.0.png
deleted file mode 100644
index 71edafd..0000000
--- a/testing/resources/pixel/xfa_specific/static_list_box_caption_expected_win.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_mac.pdf.0.png b/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_mac.pdf.0.png
index 58aee9e..bc87726 100644
--- a/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_mac.pdf.0.png
+++ b/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_mac.pdf.1.png b/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_mac.pdf.1.png
index ad36aa9..4dbd85a 100644
--- a/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_mac.pdf.1.png
+++ b/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_mac.pdf.1.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_skia.pdf.0.png b/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_skia.pdf.0.png
new file mode 100644
index 0000000..4b35140
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_skia.pdf.1.png b/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_skia.pdf.1.png
new file mode 100644
index 0000000..fd88db2
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_skia.pdf.1.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_win.pdf.0.png b/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_win.pdf.0.png
deleted file mode 100644
index ea939ac..0000000
--- a/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_win.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_win.pdf.1.png b/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_win.pdf.1.png
deleted file mode 100644
index c73f1a9..0000000
--- a/testing/resources/pixel/xfa_specific/static_password_field_rotate_expected_win.pdf.1.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/use_ahem/README.md b/testing/resources/pixel/xfa_specific/use_ahem/README.md
new file mode 100644
index 0000000..f3126e2
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/use_ahem/README.md
@@ -0,0 +1,2 @@
+The expected results in this directory should match those generated by running
+`pdfium_test` with the option `--font-dir=/path/to/pdfium/testing/resources/fonts`.
diff --git a/testing/resources/pixel/xfa_specific/use_ahem/bug_997412.in b/testing/resources/pixel/xfa_specific/use_ahem/bug_997412.in
new file mode 100644
index 0000000..ecda561
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/use_ahem/bug_997412.in
@@ -0,0 +1,35 @@
+{{header}}
+{{include ../../../xfa_catalog_1_0.fragment}}
+{{include ../../../xfa_object_2_0.fragment}}
+{{include ../../../xfa_preamble_3_0.fragment}}
+{{include ../../../xfa_config_4_0.fragment}}
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+<template xmlns="http://www.xfa.org/schema/xfa-template/3.3/">
+  <subform layout="rl-tb" name="subform1">
+    <pageSet>
+      <pageArea name="Page1" id="Page1">
+        <contentArea x="18pt" y="18pt" w="612pt" h="792pt"/>
+        <medium stock="default" short="612pt" long="792pt"/>
+      </pageArea>
+    </pageSet>
+    <field h="3000pt" name="Field1">
+      <font typeface="Ahem" size="20pt"/>
+      <value>
+        <text>foo
+<!-- Intentionally formatted to trigger bug //--></text>
+      </value>
+    </field>
+  </subform>
+</template>
+endstream
+endobj
+{{include ../../../xfa_locale_6_0.fragment}}
+{{include ../../../xfa_postamble_7_0.fragment}}
+{{include ../../../xfa_pages_8_0.fragment}}
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/xfa_specific/use_ahem/bug_997412_expected.pdf.0.png b/testing/resources/pixel/xfa_specific/use_ahem/bug_997412_expected.pdf.0.png
new file mode 100644
index 0000000..08c11b0
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/use_ahem/bug_997412_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/use_ahem/bug_997412_expected.pdf.1.png b/testing/resources/pixel/xfa_specific/use_ahem/bug_997412_expected.pdf.1.png
new file mode 100644
index 0000000..7734ff7
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/use_ahem/bug_997412_expected.pdf.1.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/use_ahem/bug_997412_expected_skia.pdf.1.png b/testing/resources/pixel/xfa_specific/use_ahem/bug_997412_expected_skia.pdf.1.png
new file mode 100644
index 0000000..d4da28c
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/use_ahem/bug_997412_expected_skia.pdf.1.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/use_ahem/xfa_example_expected_skia.pdf.0.png b/testing/resources/pixel/xfa_specific/use_ahem/xfa_example_expected_skia.pdf.0.png
new file mode 100644
index 0000000..5a3eb9f
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/use_ahem/xfa_example_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/use_ahem/xfa_textfield_expected_skia.pdf.0.png b/testing/resources/pixel/xfa_specific/use_ahem/xfa_textfield_expected_skia.pdf.0.png
new file mode 100644
index 0000000..ad18d26
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/use_ahem/xfa_textfield_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/xfa_bmp_image.in b/testing/resources/pixel/xfa_specific/xfa_bmp_image.in
index 9b444f1..dfd9026 100644
--- a/testing/resources/pixel/xfa_specific/xfa_bmp_image.in
+++ b/testing/resources/pixel/xfa_specific/xfa_bmp_image.in
@@ -18,7 +18,7 @@
     <subform w="576pt" h="756pt" name="Page1">
       <field name="ImageField1" w="250pt" h="250pt">
         <value>
-          <image contentType="image/bmp">Qk0qHgAAAAAAAHoAAABsAAAAMgAAADIAAAABABgAAAAAALAdAAATCwAAEwsAAAAAAAAAAAAAQkdScwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAAAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAAAAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAAAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAAAAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAAAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAAAAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAAAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAAAAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAAAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAAAAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAAAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAAAAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAAAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAAAAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAAAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAAAAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAAAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAAAAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAAAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAAAAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAAAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAAAAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAAAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAAAAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAAAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAAAAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAAAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAAAAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAAAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAAAAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAAAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAAAAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAP8AAAAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA</image>
+          <image contentType="image/bmp">Qk1mCgAAAAAAAD4AAAAoAAAAMgAAADIAAAABAAgAAAAAACgKAAATCwAAEwsAAAIAAAACAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</image>
         </value>
         <border>
           <edge thickness="0.254mm"/>
diff --git a/testing/resources/pixel/xfa_specific/xfa_bmp_image_expected_skia.pdf.0.png b/testing/resources/pixel/xfa_specific/xfa_bmp_image_expected_skia.pdf.0.png
new file mode 100644
index 0000000..2f77624
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/xfa_bmp_image_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/xfa_gif_image_expected_skia.pdf.0.png b/testing/resources/pixel/xfa_specific/xfa_gif_image_expected_skia.pdf.0.png
new file mode 100644
index 0000000..2f77624
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/xfa_gif_image_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/xfa_jpg_image_expected_skia.pdf.0.png b/testing/resources/pixel/xfa_specific/xfa_jpg_image_expected_skia.pdf.0.png
new file mode 100644
index 0000000..70dcd8e
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/xfa_jpg_image_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/xfa_node_caption_expected.pdf.0.png b/testing/resources/pixel/xfa_specific/xfa_node_caption_expected.pdf.0.png
index 6855361..4bfe7c8 100644
--- a/testing/resources/pixel/xfa_specific/xfa_node_caption_expected.pdf.0.png
+++ b/testing/resources/pixel/xfa_specific/xfa_node_caption_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/xfa_node_caption_expected.pdf.1.png b/testing/resources/pixel/xfa_specific/xfa_node_caption_expected.pdf.1.png
index 1f5c1bb..44aa0b1 100644
--- a/testing/resources/pixel/xfa_specific/xfa_node_caption_expected.pdf.1.png
+++ b/testing/resources/pixel/xfa_specific/xfa_node_caption_expected.pdf.1.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/xfa_node_caption_expected_mac.pdf.0.png b/testing/resources/pixel/xfa_specific/xfa_node_caption_expected_mac.pdf.0.png
new file mode 100644
index 0000000..4912da0
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/xfa_node_caption_expected_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/xfa_node_caption_expected_mac.pdf.1.png b/testing/resources/pixel/xfa_specific/xfa_node_caption_expected_mac.pdf.1.png
new file mode 100644
index 0000000..427b5b3
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/xfa_node_caption_expected_mac.pdf.1.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/xfa_node_caption_expected_skia.pdf.0.png b/testing/resources/pixel/xfa_specific/xfa_node_caption_expected_skia.pdf.0.png
new file mode 100644
index 0000000..fe509a8
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/xfa_node_caption_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/xfa_node_caption_expected_skia.pdf.1.png b/testing/resources/pixel/xfa_specific/xfa_node_caption_expected_skia.pdf.1.png
new file mode 100644
index 0000000..e720b9b
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/xfa_node_caption_expected_skia.pdf.1.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/xfa_node_caption_expected_skia_mac.pdf.0.png b/testing/resources/pixel/xfa_specific/xfa_node_caption_expected_skia_mac.pdf.0.png
new file mode 100644
index 0000000..384294c
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/xfa_node_caption_expected_skia_mac.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/xfa_node_caption_expected_skia_mac.pdf.1.png b/testing/resources/pixel/xfa_specific/xfa_node_caption_expected_skia_mac.pdf.1.png
new file mode 100644
index 0000000..3366bc0
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/xfa_node_caption_expected_skia_mac.pdf.1.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/xfa_node_caption_expected_skia_win.pdf.0.png b/testing/resources/pixel/xfa_specific/xfa_node_caption_expected_skia_win.pdf.0.png
new file mode 100644
index 0000000..54f04d8
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/xfa_node_caption_expected_skia_win.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/xfa_node_caption_expected_skia_win.pdf.1.png b/testing/resources/pixel/xfa_specific/xfa_node_caption_expected_skia_win.pdf.1.png
new file mode 100644
index 0000000..7691fb1
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/xfa_node_caption_expected_skia_win.pdf.1.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/xfa_node_caption_expected_win.pdf.0.png b/testing/resources/pixel/xfa_specific/xfa_node_caption_expected_win.pdf.0.png
new file mode 100644
index 0000000..ffa36fe
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/xfa_node_caption_expected_win.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/xfa_node_caption_expected_win.pdf.1.png b/testing/resources/pixel/xfa_specific/xfa_node_caption_expected_win.pdf.1.png
new file mode 100644
index 0000000..2448322
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/xfa_node_caption_expected_win.pdf.1.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/xfa_png_image_expected_skia.pdf.0.png b/testing/resources/pixel/xfa_specific/xfa_png_image_expected_skia.pdf.0.png
new file mode 100644
index 0000000..2f77624
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/xfa_png_image_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/xfa_rectangle_node_expected_skia.pdf.0.png b/testing/resources/pixel/xfa_specific/xfa_rectangle_node_expected_skia.pdf.0.png
new file mode 100644
index 0000000..99cee53
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/xfa_rectangle_node_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/xfa_tiff_deflate_image.in b/testing/resources/pixel/xfa_specific/xfa_tiff_deflate_image.in
deleted file mode 100644
index 797f84c..0000000
--- a/testing/resources/pixel/xfa_specific/xfa_tiff_deflate_image.in
+++ /dev/null
@@ -1,39 +0,0 @@
-{{header}}
-{{include ../../xfa_catalog_1_0.fragment}}
-{{include ../../xfa_object_2_0.fragment}}
-{{include ../../xfa_preamble_3_0.fragment}}
-{{include ../../xfa_config_4_0.fragment}}
-{{object 5 0}} <<
-  {{streamlen}}
->>
-stream
-<template xmlns="http://www.xfa.org/schema/xfa-template/3.3/">
-  <subform name="form1" layout="tb" locale="en_US" restoreState="auto">
-    <pageSet>
-      <pageArea name="Page1" id="Page1">
-        <contentArea x="18pt" y="18pt" w="612pt" h="792pt"/>
-        <medium stock="default" short="612pt" long="792pt"/>
-      </pageArea>
-    </pageSet>
-    <subform w="576pt" h="756pt" name="Page1">
-      <field name="ImageField1" w="250pt" h="250pt">
-        <value>
-          <image contentType="image/tiff">SUkqAAQDAAB4nO3SMQEAMAyAsPo33brYDhIFHOxAxf4OgGfcTofb6XA7HW6nw+10uJ0Ot9PhdjrcTofb6XA7HW6nw+10uJ0Ot9PhdjrcTofb6XA7HW6nw+10uJ0Ot9PhdjrcTofb6XA7HW6nw+10uJ0Ot9PhdjrcTofb6XA7HW6nw+10uJ0Ot9PhdjrcTofb6XA7HW6nw+10uJ0Ot9PhdjrcTofb6XA7HW6nw+10uJ0Ot9PhdjrcTofb6XA7HW6nw+10uJ2OAxGIP8F4nO3SMQEAMAyAsPo33brYDhIFHOxAxf4OgGfcTofb6XA7HW6nw+10uJ0Ot9PhdjrcTofb6XA7HW6nw+10uJ0Ot9PhdjrcTofb6XA7HW6nw+10uJ0Ot9PhdjrcTofb6XA7HW6nw+10uJ0Ot9PhdjrcTofb6XA7HW6nw+10uJ0Ot9PhdjrcTofb6XA7HW6nw+10uJ0Ot9PhdjrcTofb6XA7HW6nw+10uJ0Ot9PhdjrcTofb6XA7HW6nw+10uJ2OAxGIP8F4nO3SMQEAMAyAsPo33brYDhIFHOxAxf4OgGfcTofb6XA7HW6nw+10uJ0Ot9PhdjrcTofb6XA7HW6nw+10uJ0Ot9PhdjrcTofb6XA7HW6nw+10uJ0Ot9PhdjrcTofb6XA7HW6nw+10uJ0Ot9PhdjrcTofb6XA7HW6nw+10uJ0Ot9PhdjrcTofb6XA7HW6nw+10uJ0Ot9PhdjrcTofb6XA7HW6nw+10uJ0Ot9PhdjrcTofb6XA7HW6nw+10uJ2OAxGIP8F4nO3SMQEAMAyAsPo33brYDhIFHOxAxf4OgGfcTofb6XA7HW6nw+10uJ0Ot9PhdjrcTofb6XA7HW6nw+10uJ0Ot9PhdjrcTofb6XA7HW6nw+10uJ0Ot9PhdjrcTofb6XA7HW6nw+10uJ0Ot9PhdjrcTofb6XA7HW6nw+10uJ0Ot9PhdjrcTofb6XA7HW6nw+10uJ0Ot9PhdjrcTofb6XA7HW6nw+10uJ0Ot9PhdjoO69g5xxIA/gAEAAEAAAAAAAAAAAEDAAEAAAD6AAAAAQEDAAEAAAD6AAAAAgEDAAMAAADyAwAAAwEDAAEAAAAIAAAABgEDAAEAAAACAAAADQECAEIAAAAYBAAADgECABIAAABaBAAAEQEEAAQAAAAIBAAAEgEDAAEAAAABAAAAFQEDAAEAAAADAAAAFgEDAAEAAABAAAAAFwEEAAQAAAD4AwAAGgEFAAEAAADiAwAAGwEFAAEAAADqAwAAHAEDAAEAAAABAAAAKAEDAAEAAAACAAAAPQEDAAEAAAACAAAAAAAAAEgAAAABAAAASAAAAAEAAAAIAAgACADDAAAAwwAAAMMAAACzAAAACAAAAMsAAACOAQAAUQIAAC91c3IvbG9jYWwvZ29vZ2xlL2hvbWUvcmhhcnJpc29uL1BpY3R1cmVzL1JlZF9TcXVhcmVfZGVmbGF0ZS50aWZmAENyZWF0ZWQgd2l0aCBHSU1QAA==</image>
-        </value>
-        <border>
-          <edge thickness="0.254mm"/>
-          <corner thickness="0.254mm"/>
-        </border>
-      </field>
-    </subform>
-  </subform>
-</template>
-endstream
-endobj
-{{include ../../xfa_locale_6_0.fragment}}
-{{include ../../xfa_postamble_7_0.fragment}}
-{{include ../../xfa_pages_8_0.fragment}}
-{{xref}}
-{{trailer}}
-{{startxref}}
-%%EOF
diff --git a/testing/resources/pixel/xfa_specific/xfa_tiff_deflate_image_expected.pdf.0.png b/testing/resources/pixel/xfa_specific/xfa_tiff_deflate_image_expected.pdf.0.png
deleted file mode 100644
index 5204fd7..0000000
--- a/testing/resources/pixel/xfa_specific/xfa_tiff_deflate_image_expected.pdf.0.png
+++ /dev/null
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/xfa_tiff_image_expected_skia.pdf.0.png b/testing/resources/pixel/xfa_specific/xfa_tiff_image_expected_skia.pdf.0.png
new file mode 100644
index 0000000..2f77624
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/xfa_tiff_image_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/xfa_tiff_lzw_image_expected_skia.pdf.0.png b/testing/resources/pixel/xfa_specific/xfa_tiff_lzw_image_expected_skia.pdf.0.png
new file mode 100644
index 0000000..2f77624
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/xfa_tiff_lzw_image_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/xfa_specific/xfa_tiff_packbits_image_expected_skia.pdf.0.png b/testing/resources/pixel/xfa_specific/xfa_tiff_packbits_image_expected_skia.pdf.0.png
new file mode 100644
index 0000000..2f77624
--- /dev/null
+++ b/testing/resources/pixel/xfa_specific/xfa_tiff_packbits_image_expected_skia.pdf.0.png
Binary files differ
diff --git a/testing/resources/polygon_annot.in b/testing/resources/polygon_annot.in
new file mode 100644
index 0000000..069ddc1
--- /dev/null
+++ b/testing/resources/polygon_annot.in
@@ -0,0 +1,48 @@
+{{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
+  /MediaBox [0 0 612 792]
+  /Annots [
+    4 0 R 5 0 R
+  ]
+  /Tabs /R
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Annot
+  /Subtype /Polygon
+  /NM (Polygon-1)
+  /F 4
+  /Vertices [159 296 350 411 472 243.42]
+  /P 3 0 R
+  /C [1 0.90196 0]
+  /Rect [293 530 349 542]
+>>
+endobj
+{{object 5 0}} <<
+  /Type /Annot
+  /Subtype /Polygon
+  /NM (Polygon-2)
+  /F 4
+  /Vertices [259 396 450 511 572 343 42]
+  /P 3 0 R
+  /C [1 0.90196 0]
+  /Rect [293 530 349 542]
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/polygon_annot.pdf b/testing/resources/polygon_annot.pdf
new file mode 100644
index 0000000..8efaa27
--- /dev/null
+++ b/testing/resources/polygon_annot.pdf
@@ -0,0 +1,60 @@
+%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
+  /MediaBox [0 0 612 792]
+  /Annots [
+    4 0 R 5 0 R
+  ]
+  /Tabs /R
+>>
+endobj
+4 0 obj <<
+  /Type /Annot
+  /Subtype /Polygon
+  /NM (Polygon-1)
+  /F 4
+  /Vertices [159 296 350 411 472 243.42]
+  /P 3 0 R
+  /C [1 0.90196 0]
+  /Rect [293 530 349 542]
+>>
+endobj
+5 0 obj <<
+  /Type /Annot
+  /Subtype /Polygon
+  /NM (Polygon-2)
+  /F 4
+  /Vertices [259 396 450 511 572 343 42]
+  /P 3 0 R
+  /C [1 0.90196 0]
+  /Rect [293 530 349 542]
+>>
+endobj
+xref
+0 6
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000131 00000 n 
+0000000251 00000 n 
+0000000429 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 6
+>>
+startxref
+607
+%%EOF
diff --git a/testing/resources/rectangles.in b/testing/resources/rectangles.in
index 49932ff..7334516 100644
--- a/testing/resources/rectangles.in
+++ b/testing/resources/rectangles.in
@@ -6,9 +6,9 @@
 endobj
 {{object 2 0}} <<
   /Type /Pages
-  /MediaBox [ 0 0 200 300 ]
+  /MediaBox [0 0 200 300]
   /Count 1
-  /Kids [ 3 0 R ]
+  /Kids [3 0 R]
 >>
 endobj
 {{object 3 0}} <<
@@ -18,6 +18,7 @@
 >>
 endobj
 {{object 4 0}} <<
+  {{streamlen}}
 >>
 stream
 q
diff --git a/testing/resources/rectangles.pdf b/testing/resources/rectangles.pdf
index 7bad251..6911d22 100644
--- a/testing/resources/rectangles.pdf
+++ b/testing/resources/rectangles.pdf
@@ -7,9 +7,9 @@
 endobj
 2 0 obj <<
   /Type /Pages
-  /MediaBox [ 0 0 200 300 ]
+  /MediaBox [0 0 200 300]
   /Count 1
-  /Kids [ 3 0 R ]
+  /Kids [3 0 R]
 >>
 endobj
 3 0 obj <<
@@ -19,6 +19,7 @@
 >>
 endobj
 4 0 obj <<
+  /Length 188
 >>
 stream
 q
@@ -42,9 +43,12 @@
 0000000000 65535 f 
 0000000015 00000 n 
 0000000068 00000 n 
-0000000161 00000 n 
-0000000230 00000 n 
-trailer<< /Root 1 0 R /Size 5 >>
+0000000157 00000 n 
+0000000226 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 5
+>>
 startxref
-456
+466
 %%EOF
diff --git a/testing/resources/redact_annot.in b/testing/resources/redact_annot.in
new file mode 100644
index 0000000..99b7b4e
--- /dev/null
+++ b/testing/resources/redact_annot.in
@@ -0,0 +1,44 @@
+{{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 612 792]
+  /Annots [
+    5 0 R
+  ]
+  /Tabs /R
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /Annot
+  /Subtype /Redact
+  /NM (Redact-1)
+  /F 4
+  /QuadPoints [293 542 349 542 293 530 349 530]
+  /P 3 0 R
+  /C [1 0.90196 0]
+  /Rect [293 530 349 542]
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/redact_annot.pdf b/testing/resources/redact_annot.pdf
new file mode 100644
index 0000000..76c2607
--- /dev/null
+++ b/testing/resources/redact_annot.pdf
@@ -0,0 +1,56 @@
+%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 612 792]
+  /Annots [
+    5 0 R
+  ]
+  /Tabs /R
+>>
+endobj
+4 0 obj <<
+  /Length 0
+>>
+stream
+endstream
+endobj
+5 0 obj <<
+  /Type /Annot
+  /Subtype /Redact
+  /NM (Redact-1)
+  /F 4
+  /QuadPoints [293 542 349 542 293 530 349 530]
+  /P 3 0 R
+  /C [1 0.90196 0]
+  /Rect [293 530 349 542]
+>>
+endobj
+xref
+0 6
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000131 00000 n 
+0000000263 00000 n 
+0000000313 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 6
+>>
+startxref
+496
+%%EOF
diff --git a/testing/resources/rotated_image.in b/testing/resources/rotated_image.in
new file mode 100644
index 0000000..cf82fe8
--- /dev/null
+++ b/testing/resources/rotated_image.in
@@ -0,0 +1,52 @@
+{{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
+  /Contents 4 0 R
+  /Resources <<
+    /XObject <<
+      /Img 5 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+30 -30 40 40 100 100 cm
+/Img Do
+Q
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 50
+  /Height 50
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  {{streamlen}}
+>>
+stream
+789cedc2310d00000c03a07f2aaab3ea7bcf03842655555555555555f5bf01cc7818dc
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/rotated_image.pdf b/testing/resources/rotated_image.pdf
new file mode 100644
index 0000000..5bb1836
--- /dev/null
+++ b/testing/resources/rotated_image.pdf
@@ -0,0 +1,64 @@
+%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
+  /Contents 4 0 R
+  /Resources <<
+    /XObject <<
+      /Img 5 0 R
+    >>
+  >>
+>>
+endobj
+4 0 obj <<
+  /Length 36
+>>
+stream
+q
+30 -30 40 40 100 100 cm
+/Img Do
+Q
+endstream
+endobj
+5 0 obj <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 50
+  /Height 50
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  /Length 71
+>>
+stream
+789cedc2310d00000c03a07f2aaab3ea7bcf03842655555555555555f5bf01cc7818dc
+endstream
+endobj
+xref
+0 6
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000157 00000 n 
+0000000287 00000 n 
+0000000374 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 6
+>>
+startxref
+644
+%%EOF
diff --git a/testing/resources/signature_no_sub_filter.in b/testing/resources/signature_no_sub_filter.in
new file mode 100644
index 0000000..5c1d1d8
--- /dev/null
+++ b/testing/resources/signature_no_sub_filter.in
@@ -0,0 +1,100 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /MediaBox [0 0 200 300]
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 4 0 R
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+0 0 0 rg
+0 290 10 10 re B*
+10 150 50 30 re B*
+0 0 1 rg
+190 290 10 10 re B*
+70 232 50 30 re B*
+0 1 0 rg
+190 0 10 10 re B*
+130 150 50 30 re B*
+1 0 0 rg
+0 0 10 10 re B*
+70 67 50 30 re B*
+Q
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
+
+%% First incremental update adds an initial signature and update objects to
+%% refer to it.
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /Fields [7 0 R]
+    /SigFlags 3
+  >>
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 4 0 R
+  /Annots [7 0 R]
+>>
+endobj
+%% ByteRange is a pairs of integers (starting byte offset, length in bytes)
+{{object 5 0}} <<
+  /Type /Sig
+  /Filter /Adobe.PPKMS
+  % Intentionally no /SubFilter
+  /ByteRange [0 10 30 10]
+  /Contents <308006092A864886F70D010702A0803080020101>
+  /M (D:20200624093114+02'00')
+>>
+endobj
+{{object 6 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /BBox [0 0 0 0]
+  /Length 0
+>>
+stream
+endstream
+endobj
+{{object 7 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Sig
+  /F 132
+  /Rect [0 0 0 0]
+  /P 3 0 R
+  /T (Signature1)
+  /V 5 0 R
+  /DV 5 0 R
+  /AP <<
+    /N 6 0 R
+  >>
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/signature_no_sub_filter.pdf b/testing/resources/signature_no_sub_filter.pdf
new file mode 100644
index 0000000..ed305ef
--- /dev/null
+++ b/testing/resources/signature_no_sub_filter.pdf
@@ -0,0 +1,124 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /MediaBox [0 0 200 300]
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 4 0 R
+>>
+endobj
+4 0 obj <<
+  /Length 188
+>>
+stream
+q
+0 0 0 rg
+0 290 10 10 re B*
+10 150 50 30 re B*
+0 0 1 rg
+190 290 10 10 re B*
+70 232 50 30 re B*
+0 1 0 rg
+190 0 10 10 re B*
+130 150 50 30 re B*
+1 0 0 rg
+0 0 10 10 re B*
+70 67 50 30 re B*
+Q
+endstream
+endobj
+xref
+0 5
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000157 00000 n 
+0000000226 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 5
+>>
+startxref
+466
+%%EOF
+
+%% First incremental update adds an initial signature and update objects to
+%% refer to it.
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /Fields [7 0 R]
+    /SigFlags 3
+  >>
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 4 0 R
+  /Annots [7 0 R]
+>>
+endobj
+%% ByteRange is a pairs of integers (starting byte offset, length in bytes)
+5 0 obj <<
+  /Type /Sig
+  /Filter /Adobe.PPKMS
+  % Intentionally no /SubFilter
+  /ByteRange [0 10 30 10]
+  /Contents <308006092A864886F70D010702A0803080020101>
+  /M (D:20200624093114+02'00')
+>>
+endobj
+6 0 obj <<
+  /Type /XObject
+  /Subtype /Form
+  /BBox [0 0 0 0]
+  /Length 0
+>>
+stream
+endstream
+endobj
+7 0 obj <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Sig
+  /F 132
+  /Rect [0 0 0 0]
+  /P 3 0 R
+  /T (Signature1)
+  /V 5 0 R
+  /DV 5 0 R
+  /AP <<
+    /N 6 0 R
+  >>
+>>
+endobj
+xref
+0 8
+0000000000 65535 f 
+0000000726 00000 n 
+0000000068 00000 n 
+0000000835 00000 n 
+0000000226 00000 n 
+0000000998 00000 n 
+0000001199 00000 n 
+0000001301 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 8
+>>
+startxref
+1473
+%%EOF
diff --git a/testing/resources/signature_reason.in b/testing/resources/signature_reason.in
new file mode 100644
index 0000000..2c5d0f9
--- /dev/null
+++ b/testing/resources/signature_reason.in
@@ -0,0 +1,101 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /MediaBox [0 0 200 300]
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 4 0 R
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+0 0 0 rg
+0 290 10 10 re B*
+10 150 50 30 re B*
+0 0 1 rg
+190 290 10 10 re B*
+70 232 50 30 re B*
+0 1 0 rg
+190 0 10 10 re B*
+130 150 50 30 re B*
+1 0 0 rg
+0 0 10 10 re B*
+70 67 50 30 re B*
+Q
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
+
+%% First incremental update adds an initial signature and update objects to
+%% refer to it.
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /Fields [7 0 R]
+    /SigFlags 3
+  >>
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 4 0 R
+  /Annots [7 0 R]
+>>
+endobj
+%% ByteRange is a pairs of integers (starting byte offset, length in bytes)
+{{object 5 0}} <<
+  /Type /Sig
+  /Filter /Adobe.PPKMS
+  /SubFilter /ETSI.CAdES.detached
+  /ByteRange [0 10 30 10]
+  /Contents <308006092A864886F70D010702A0803080020101>
+  /M (D:20200624093114+02'00')
+  /Reason <FEFF007400650073007400200072006500610073006F006E>
+>>
+endobj
+{{object 6 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /BBox [0 0 0 0]
+  /Length 0
+>>
+stream
+endstream
+endobj
+{{object 7 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Sig
+  /F 132
+  /Rect [0 0 0 0]
+  /P 3 0 R
+  /T (Signature1)
+  /V 5 0 R
+  /DV 5 0 R
+  /AP <<
+    /N 6 0 R
+  >>
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/signature_reason.pdf b/testing/resources/signature_reason.pdf
new file mode 100644
index 0000000..3ad0205
--- /dev/null
+++ b/testing/resources/signature_reason.pdf
@@ -0,0 +1,125 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /MediaBox [0 0 200 300]
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 4 0 R
+>>
+endobj
+4 0 obj <<
+  /Length 188
+>>
+stream
+q
+0 0 0 rg
+0 290 10 10 re B*
+10 150 50 30 re B*
+0 0 1 rg
+190 290 10 10 re B*
+70 232 50 30 re B*
+0 1 0 rg
+190 0 10 10 re B*
+130 150 50 30 re B*
+1 0 0 rg
+0 0 10 10 re B*
+70 67 50 30 re B*
+Q
+endstream
+endobj
+xref
+0 5
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000157 00000 n 
+0000000226 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 5
+>>
+startxref
+466
+%%EOF
+
+%% First incremental update adds an initial signature and update objects to
+%% refer to it.
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /Fields [7 0 R]
+    /SigFlags 3
+  >>
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 4 0 R
+  /Annots [7 0 R]
+>>
+endobj
+%% ByteRange is a pairs of integers (starting byte offset, length in bytes)
+5 0 obj <<
+  /Type /Sig
+  /Filter /Adobe.PPKMS
+  /SubFilter /ETSI.CAdES.detached
+  /ByteRange [0 10 30 10]
+  /Contents <308006092A864886F70D010702A0803080020101>
+  /M (D:20200624093114+02'00')
+  /Reason <FEFF007400650073007400200072006500610073006F006E>
+>>
+endobj
+6 0 obj <<
+  /Type /XObject
+  /Subtype /Form
+  /BBox [0 0 0 0]
+  /Length 0
+>>
+stream
+endstream
+endobj
+7 0 obj <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Sig
+  /F 132
+  /Rect [0 0 0 0]
+  /P 3 0 R
+  /T (Signature1)
+  /V 5 0 R
+  /DV 5 0 R
+  /AP <<
+    /N 6 0 R
+  >>
+>>
+endobj
+xref
+0 8
+0000000000 65535 f 
+0000000726 00000 n 
+0000000068 00000 n 
+0000000835 00000 n 
+0000000226 00000 n 
+0000000998 00000 n 
+0000001262 00000 n 
+0000001364 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 8
+>>
+startxref
+1536
+%%EOF
diff --git a/testing/resources/simple_xfa.in b/testing/resources/simple_xfa.in
index b20c746..d3c2d00 100644
--- a/testing/resources/simple_xfa.in
+++ b/testing/resources/simple_xfa.in
@@ -12,6 +12,7 @@
     <pageSet>
       <pageArea name="Page1" id="Page1">
         <contentArea x="0.25in" y="0.25in" w="8in" h="10.5in" />
+        <medium long="11in" short="8.5in" stock="letter"/>
       </pageArea>
     </pageSet>
     <field name="TextField1" y="31.75mm" x="44.45mm" w="114.291mm" h="12.7mm">
diff --git a/testing/resources/simple_xfa.pdf b/testing/resources/simple_xfa.pdf
index 89f9aea..8ff5b12 100644
--- a/testing/resources/simple_xfa.pdf
+++ b/testing/resources/simple_xfa.pdf
@@ -72,7 +72,7 @@
 endstream
 endobj
 5 0 obj <<
-  /Length 482
+  /Length 541
 >>
 stream
 <template xmlns="http://www.xfa.org/schema/xfa-template/3.3/">
@@ -80,6 +80,7 @@
     <pageSet>
       <pageArea name="Page1" id="Page1">
         <contentArea x="0.25in" y="0.25in" w="8in" h="10.5in" />
+        <medium long="11in" short="8.5in" stock="letter"/>
       </pageArea>
     </pageSet>
     <field name="TextField1" y="31.75mm" x="44.45mm" w="114.291mm" h="12.7mm">
@@ -215,7 +216,7 @@
 endobj
 9 0 obj <<
   /Type /Page
-  /Parent 2 0 R
+  /Parent 8 0 R
   /MediaBox [0 0 612 792]
 >>
 endobj
@@ -227,14 +228,14 @@
 0000000358 00000 n 
 0000000534 00000 n 
 0000001228 00000 n 
-0000001762 00000 n 
-0000005270 00000 n 
-0000005332 00000 n 
-0000005395 00000 n 
+0000001821 00000 n 
+0000005329 00000 n 
+0000005391 00000 n 
+0000005454 00000 n 
 trailer <<
   /Root 1 0 R
   /Size 10
 >>
 startxref
-5472
+5531
 %%EOF
diff --git a/testing/resources/split_streams.in b/testing/resources/split_streams.in
index b134769..729c67a 100644
--- a/testing/resources/split_streams.in
+++ b/testing/resources/split_streams.in
@@ -117,7 +117,7 @@
 {{xref}}
 trailer <<
   /Root 1 0 R
-  /Size 15
+  {{trailersize}}
   /ID [<f341ae654a77acd5065a7645e596e6e6><bc37298a3f87f479229bce997ca791f7>]
 >>
 {{startxref}}
diff --git a/testing/resources/tagged_actual_text.in b/testing/resources/tagged_actual_text.in
new file mode 100644
index 0000000..9bb917b
--- /dev/null
+++ b/testing/resources/tagged_actual_text.in
@@ -0,0 +1,162 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /StructTreeRoot 8 0 R
+  /Lang (en-US)
+  /MarkInfo <<
+    /Marked true
+  >>
+>>
+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 612 792]
+  /Group <<
+    /CS /DeviceRGB
+    /I true
+    /S /Transparency
+  >>
+  /Resources <<
+    /ProcSet [/PDF /ImageC /ImageI /ImageB]
+    /XObject <<
+      /Tr8 5 0 R
+      /Im7 6 0 R
+    >>
+    /ExtGState <<
+      /EGS9 7 0 R
+    >>
+  >>
+  /StructParents 0
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+0.1 w
+/Artifact
+BMC
+q
+0 0 612 792 re
+W* n
+EMC
+/Figure<</MCID 0>>
+BDC
+Q
+q
+281 685.3 50 50 re
+W* n
+q
+49.9 0 0 50 281.1 685.4 cm
+/Im7 Do
+Q
+EMC
+Q
+q
+EGS9 gs /Tr8 Do
+Q
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /BBox [-140 395 753 395.1]
+  /Group <<
+    /CS /DeviceRGB
+    /K true
+    /S /Transparency
+  >>
+  {{streamlen}}
+>>
+stream
+endstream
+endobj
+{{object 6 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 50
+  /Height 50
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  {{streamlen}}
+>>
+stream
+789cedc13101000000c2a0f54fed6f06a00000000000000078031d4c0001
+endstream
+endobj
+{{object 7 0}} <<
+  /ca 0.5
+  /CA 0.5
+>>
+endobj
+{{object 8 0}} <<
+  /Type /StructTreeRoot
+  /ParentTree 9 0 R
+  /K [11 0 R]
+  /RoleMap <<
+    /Document /Document
+    /Standard /P
+    /Figure /Figure
+  >>
+>>
+endobj
+{{object 9 0}} <<
+  /Nums [0 [10 0 R]]
+>>
+endobj
+{{object 10 0}} <<
+  /Type /StructElem
+  /S /Figure
+  /A 13 0 R
+  /K [0]
+  /P 12 0 R
+  /ActualText <feff00410063007400750061006c00200054006500780074>
+  /Pg 3 0 R
+>>
+endobj
+{{object 11 0}} <<
+  /Type /StructElem
+  /S /Document
+  /K [12 0 R]
+  /P 8 0 R
+  /T (TitleText)
+  /Pg 3 0 R
+>>
+endobj
+{{object 12 0}} <<
+  /Type /StructElem
+  /S /Standard
+  /A 14 0 R
+  /K [10 0 R]
+  /P 11 0 R
+  /T <feff00730079006d0062006f006c003a0020003100300030006b>
+  /Pg 3 0 R
+>>
+endobj
+{{object 13 0}} <<
+  /O /Layout
+  /Placement /Block
+  /BBox [281.1 685.3 331.1 735.3]
+  /Width 99.9
+  /Height 99.9
+>>
+endobj
+{{object 14 0}} <<
+  /O /Layout
+  /Placement /Block
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/tagged_actual_text.pdf b/testing/resources/tagged_actual_text.pdf
new file mode 100644
index 0000000..634e333
--- /dev/null
+++ b/testing/resources/tagged_actual_text.pdf
@@ -0,0 +1,183 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /StructTreeRoot 8 0 R
+  /Lang (en-US)
+  /MarkInfo <<
+    /Marked true
+  >>
+>>
+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 612 792]
+  /Group <<
+    /CS /DeviceRGB
+    /I true
+    /S /Transparency
+  >>
+  /Resources <<
+    /ProcSet [/PDF /ImageC /ImageI /ImageB]
+    /XObject <<
+      /Tr8 5 0 R
+      /Im7 6 0 R
+    >>
+    /ExtGState <<
+      /EGS9 7 0 R
+    >>
+  >>
+  /StructParents 0
+>>
+endobj
+4 0 obj <<
+  /Length 162
+>>
+stream
+0.1 w
+/Artifact
+BMC
+q
+0 0 612 792 re
+W* n
+EMC
+/Figure<</MCID 0>>
+BDC
+Q
+q
+281 685.3 50 50 re
+W* n
+q
+49.9 0 0 50 281.1 685.4 cm
+/Im7 Do
+Q
+EMC
+Q
+q
+EGS9 gs /Tr8 Do
+Q
+endstream
+endobj
+5 0 obj <<
+  /Type /XObject
+  /Subtype /Form
+  /BBox [-140 395 753 395.1]
+  /Group <<
+    /CS /DeviceRGB
+    /K true
+    /S /Transparency
+  >>
+  /Length 0
+>>
+stream
+endstream
+endobj
+6 0 obj <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 50
+  /Height 50
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  /Length 61
+>>
+stream
+789cedc13101000000c2a0f54fed6f06a00000000000000078031d4c0001
+endstream
+endobj
+7 0 obj <<
+  /ca 0.5
+  /CA 0.5
+>>
+endobj
+8 0 obj <<
+  /Type /StructTreeRoot
+  /ParentTree 9 0 R
+  /K [11 0 R]
+  /RoleMap <<
+    /Document /Document
+    /Standard /P
+    /Figure /Figure
+  >>
+>>
+endobj
+9 0 obj <<
+  /Nums [0 [10 0 R]]
+>>
+endobj
+10 0 obj <<
+  /Type /StructElem
+  /S /Figure
+  /A 13 0 R
+  /K [0]
+  /P 12 0 R
+  /ActualText <feff00410063007400750061006c00200054006500780074>
+  /Pg 3 0 R
+>>
+endobj
+11 0 obj <<
+  /Type /StructElem
+  /S /Document
+  /K [12 0 R]
+  /P 8 0 R
+  /T (TitleText)
+  /Pg 3 0 R
+>>
+endobj
+12 0 obj <<
+  /Type /StructElem
+  /S /Standard
+  /A 14 0 R
+  /K [10 0 R]
+  /P 11 0 R
+  /T <feff00730079006d0062006f006c003a0020003100300030006b>
+  /Pg 3 0 R
+>>
+endobj
+13 0 obj <<
+  /O /Layout
+  /Placement /Block
+  /BBox [281.1 685.3 331.1 735.3]
+  /Width 99.9
+  /Height 99.9
+>>
+endobj
+14 0 obj <<
+  /O /Layout
+  /Placement /Block
+>>
+endobj
+xref
+0 15
+0000000000 65535 f 
+0000000015 00000 n 
+0000000145 00000 n 
+0000000208 00000 n 
+0000000556 00000 n 
+0000000770 00000 n 
+0000000952 00000 n 
+0000001212 00000 n 
+0000001253 00000 n 
+0000001412 00000 n 
+0000001454 00000 n 
+0000001619 00000 n 
+0000001730 00000 n 
+0000001897 00000 n 
+0000002015 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 15
+>>
+startxref
+2070
+%%EOF
diff --git a/testing/resources/tagged_marked_content.in b/testing/resources/tagged_marked_content.in
new file mode 100644
index 0000000..a8ea64b
--- /dev/null
+++ b/testing/resources/tagged_marked_content.in
@@ -0,0 +1,140 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /StructTreeRoot 7 0 R
+  /MarkInfo <<
+    /Type /MarkInfo
+    /Marked true
+  >>
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /StructParents 0
+  /Annots [4 0 R]
+  /Contents 5 0 R
+  /MediaBox [0 0 612 792]
+  /Resources <<
+    /ProcSet [/PDF /Text]
+    /Font <<
+      /F4 6 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Annot
+  /Subtype /Link
+  /Border [0 0 0]
+  /Dest /top
+  /F 4
+  /Rect [20 46 68 61]
+>>
+endobj
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+BT
+/P <</MCID 0 >>BDC
+/F4 16 Tf
+20 650 Td
+(Top Left) Tj
+EMC
+ET
+BT
+/P <</MCID 1 >>BDC
+/F4 16 Tf
+20 50 Td
+(Bottom Left) Tj
+EMC
+ET
+BT
+/P <</MCID 2 >>BDC
+/F4 16 Tf
+400 50 Td
+(Bottom Right) Tj
+EMC
+ET
+BT
+/P <</MCID 3 >>BDC
+/F4 16 Tf
+400 650 Td
+(Top Right) Tj
+EMC
+ET
+Q
+endstream
+endobj
+{{object 6 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Times-Roman
+>>
+endobj
+{{object 7 0}} <<
+  /Type /StructTreeRoot
+  /K [9 0 R 10 0 R 11 0 R 12 0 R]
+  /ParentTree 8 0 R
+  /ParentTreeNextKey 1
+>>
+endobj
+{{object 8 0}} <<
+  /Type /ParentTree
+  /Nums [0 [9 0 R 10 0 R 11 0 R 12 0 R]]
+>>
+endobj
+{{object 9 0}} <<
+  /Type /StructElem
+  /S /NonStruct
+  /P 7 0 R
+  /K 0
+  /ID /3
+>>
+endobj
+{{object 10 0}} <<
+  /Type /StructElem
+  /S /NonStruct
+  /P 7 0 R
+  /K <<
+      /Type /MCR
+      /MCID 1
+      /Pg 3 0 R
+     >>
+  /ID /4
+>>
+endobj
+{{object 11 0}} <<
+  /Type /StructElem
+  /S /NonStruct
+  /P 7 0 R
+  /K [
+      <<
+       /Type /MCR
+       /MCID 2
+       /Pg 3 0 R
+      >>
+      3]
+  /ID /5
+>>
+endobj
+{{object 12 0}} <<
+  /Type /StructElem
+  /S /NonStruct
+  /P 7 0 R
+  /ID /6
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/tagged_marked_content.pdf b/testing/resources/tagged_marked_content.pdf
new file mode 100644
index 0000000..92f731d
--- /dev/null
+++ b/testing/resources/tagged_marked_content.pdf
@@ -0,0 +1,159 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /StructTreeRoot 7 0 R
+  /MarkInfo <<
+    /Type /MarkInfo
+    /Marked true
+  >>
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /StructParents 0
+  /Annots [4 0 R]
+  /Contents 5 0 R
+  /MediaBox [0 0 612 792]
+  /Resources <<
+    /ProcSet [/PDF /Text]
+    /Font <<
+      /F4 6 0 R
+    >>
+  >>
+>>
+endobj
+4 0 obj <<
+  /Type /Annot
+  /Subtype /Link
+  /Border [0 0 0]
+  /Dest /top
+  /F 4
+  /Rect [20 46 68 61]
+>>
+endobj
+5 0 obj <<
+  /Length 264
+>>
+stream
+q
+BT
+/P <</MCID 0 >>BDC
+/F4 16 Tf
+20 650 Td
+(Top Left) Tj
+EMC
+ET
+BT
+/P <</MCID 1 >>BDC
+/F4 16 Tf
+20 50 Td
+(Bottom Left) Tj
+EMC
+ET
+BT
+/P <</MCID 2 >>BDC
+/F4 16 Tf
+400 50 Td
+(Bottom Right) Tj
+EMC
+ET
+BT
+/P <</MCID 3 >>BDC
+/F4 16 Tf
+400 650 Td
+(Top Right) Tj
+EMC
+ET
+Q
+endstream
+endobj
+6 0 obj <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Times-Roman
+>>
+endobj
+7 0 obj <<
+  /Type /StructTreeRoot
+  /K [9 0 R 10 0 R 11 0 R 12 0 R]
+  /ParentTree 8 0 R
+  /ParentTreeNextKey 1
+>>
+endobj
+8 0 obj <<
+  /Type /ParentTree
+  /Nums [0 [9 0 R 10 0 R 11 0 R 12 0 R]]
+>>
+endobj
+9 0 obj <<
+  /Type /StructElem
+  /S /NonStruct
+  /P 7 0 R
+  /K 0
+  /ID /3
+>>
+endobj
+10 0 obj <<
+  /Type /StructElem
+  /S /NonStruct
+  /P 7 0 R
+  /K <<
+      /Type /MCR
+      /MCID 1
+      /Pg 3 0 R
+     >>
+  /ID /4
+>>
+endobj
+11 0 obj <<
+  /Type /StructElem
+  /S /NonStruct
+  /P 7 0 R
+  /K [
+      <<
+       /Type /MCR
+       /MCID 2
+       /Pg 3 0 R
+      >>
+      3]
+  /ID /5
+>>
+endobj
+12 0 obj <<
+  /Type /StructElem
+  /S /NonStruct
+  /P 7 0 R
+  /ID /6
+>>
+endobj
+xref
+0 13
+0000000000 65535 f 
+0000000015 00000 n 
+0000000149 00000 n 
+0000000212 00000 n 
+0000000427 00000 n 
+0000000540 00000 n 
+0000000856 00000 n 
+0000000934 00000 n 
+0000001056 00000 n 
+0000001138 00000 n 
+0000001222 00000 n 
+0000001363 00000 n 
+0000001525 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 13
+>>
+startxref
+1603
+%%EOF
diff --git a/testing/resources/tagged_mcr_objr.in b/testing/resources/tagged_mcr_objr.in
new file mode 100644
index 0000000..3394633
--- /dev/null
+++ b/testing/resources/tagged_mcr_objr.in
@@ -0,0 +1,160 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /StructTreeRoot 7 0 R
+  /MarkInfo <<
+    /Type /MarkInfo
+    /Marked true
+  >>
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /StructParents 0
+  /Annots [4 0 R]
+  /Contents 5 0 R
+  /MediaBox [0 0 612 792]
+  /Resources <<
+    /ProcSet [/PDF /Text]
+    /Font <<
+      /F4 6 0 R
+    >>
+  >>
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Annot
+  /Subtype /Link
+  /Border [0 0 0]
+  /Dest /top
+  /F 4
+  /Rect [20 46 68 61]
+>>
+endobj
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+BT
+/P <</MCID 0 >>BDC
+/F4 16 Tf
+20 650 Td
+(Hello, world!) Tj
+EMC
+ET
+BT
+/P <</MCID 1 >>BDC
+/F4 16 Tf
+20 50 Td
+(Link to top) Tj
+EMC
+ET
+Q
+endstream
+endobj
+{{object 6 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Times-Roman
+>>
+endobj
+{{object 7 0}} <<
+  /Type /StructTreeRoot
+  /K 8 0 R
+  /ParentTree 9 0 R
+  /ParentTreeNextKey 1
+>>
+endobj
+{{object 8 0}} <<
+  /Type /StructElem
+  /S /Document
+  /P 7 0 R
+  /K [10 0 R 11 0 R]
+  /ID /2
+  /Lang (en-US)
+>>
+endobj
+{{object 9 0}} <<
+  /Type /ParentTree
+  /Nums [0 [13 0 R 15 0 R]]
+>>
+endobj
+{{object 10 0}} <<
+  /Type /StructElem
+  /S /NonStruct
+  /P 8 0 R
+  /K [12 0 R]
+  /ID /6
+>>
+endobj
+{{object 11 0}} <<
+  /Type /StructElem
+  /S /P
+  /P 8 0 R
+  /K [14 0 R]
+  /ID /4
+>>
+endobj
+{{object 12 0}} <<
+  /Type /StructElem
+  /S /P
+  /P 10 0 R
+  /K [13 0 R]
+  /ID /3
+>>
+endobj
+{{object 13 0}} <<
+  /Type /StructElem
+  /S /NonStruct
+  /P 12 0 R
+  /K [
+    <<
+      /Type /MCR
+      /MCID 0
+      /Pg 3 0 R
+    >>
+  ]
+  /ID /7
+>>
+endobj
+{{object 14 0}} <<
+  /Type /StructElem
+  /S /NonStruct
+  /P 11 0 R
+  /K [
+    15 0 R
+    <<
+      /Type /OBJR
+      /Obj 4 0 R
+    >>
+  ]
+  /ID /9
+>>
+endobj
+{{object 15 0}} <<
+  /Type /StructElem
+  /S /NonStruct
+  /P 14 0 R
+  /K [
+    <<
+      /Type /MCR
+      /Pg 3 0 R
+      /MCID 1
+    >>
+  ]
+  /ID /10
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/tagged_mcr_objr.pdf b/testing/resources/tagged_mcr_objr.pdf
new file mode 100644
index 0000000..a86faa7
--- /dev/null
+++ b/testing/resources/tagged_mcr_objr.pdf
@@ -0,0 +1,182 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /StructTreeRoot 7 0 R
+  /MarkInfo <<
+    /Type /MarkInfo
+    /Marked true
+  >>
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /StructParents 0
+  /Annots [4 0 R]
+  /Contents 5 0 R
+  /MediaBox [0 0 612 792]
+  /Resources <<
+    /ProcSet [/PDF /Text]
+    /Font <<
+      /F4 6 0 R
+    >>
+  >>
+>>
+endobj
+4 0 obj <<
+  /Type /Annot
+  /Subtype /Link
+  /Border [0 0 0]
+  /Dest /top
+  /F 4
+  /Rect [20 46 68 61]
+>>
+endobj
+5 0 obj <<
+  /Length 137
+>>
+stream
+q
+BT
+/P <</MCID 0 >>BDC
+/F4 16 Tf
+20 650 Td
+(Hello, world!) Tj
+EMC
+ET
+BT
+/P <</MCID 1 >>BDC
+/F4 16 Tf
+20 50 Td
+(Link to top) Tj
+EMC
+ET
+Q
+endstream
+endobj
+6 0 obj <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Times-Roman
+>>
+endobj
+7 0 obj <<
+  /Type /StructTreeRoot
+  /K 8 0 R
+  /ParentTree 9 0 R
+  /ParentTreeNextKey 1
+>>
+endobj
+8 0 obj <<
+  /Type /StructElem
+  /S /Document
+  /P 7 0 R
+  /K [10 0 R 11 0 R]
+  /ID /2
+  /Lang (en-US)
+>>
+endobj
+9 0 obj <<
+  /Type /ParentTree
+  /Nums [0 [13 0 R 15 0 R]]
+>>
+endobj
+10 0 obj <<
+  /Type /StructElem
+  /S /NonStruct
+  /P 8 0 R
+  /K [12 0 R]
+  /ID /6
+>>
+endobj
+11 0 obj <<
+  /Type /StructElem
+  /S /P
+  /P 8 0 R
+  /K [14 0 R]
+  /ID /4
+>>
+endobj
+12 0 obj <<
+  /Type /StructElem
+  /S /P
+  /P 10 0 R
+  /K [13 0 R]
+  /ID /3
+>>
+endobj
+13 0 obj <<
+  /Type /StructElem
+  /S /NonStruct
+  /P 12 0 R
+  /K [
+    <<
+      /Type /MCR
+      /MCID 0
+      /Pg 3 0 R
+    >>
+  ]
+  /ID /7
+>>
+endobj
+14 0 obj <<
+  /Type /StructElem
+  /S /NonStruct
+  /P 11 0 R
+  /K [
+    15 0 R
+    <<
+      /Type /OBJR
+      /Obj 4 0 R
+    >>
+  ]
+  /ID /9
+>>
+endobj
+15 0 obj <<
+  /Type /StructElem
+  /S /NonStruct
+  /P 14 0 R
+  /K [
+    <<
+      /Type /MCR
+      /Pg 3 0 R
+      /MCID 1
+    >>
+  ]
+  /ID /10
+>>
+endobj
+xref
+0 16
+0000000000 65535 f 
+0000000015 00000 n 
+0000000149 00000 n 
+0000000212 00000 n 
+0000000427 00000 n 
+0000000540 00000 n 
+0000000729 00000 n 
+0000000807 00000 n 
+0000000906 00000 n 
+0000001019 00000 n 
+0000001088 00000 n 
+0000001180 00000 n 
+0000001264 00000 n 
+0000001349 00000 n 
+0000001500 00000 n 
+0000001650 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 16
+>>
+startxref
+1802
+%%EOF
diff --git a/testing/resources/tagged_nested.in b/testing/resources/tagged_nested.in
new file mode 100644
index 0000000..b7d2022
--- /dev/null
+++ b/testing/resources/tagged_nested.in
@@ -0,0 +1,346 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /StructTreeRoot 5 0 R
+  /Lang (en-US)
+  /MarkInfo <<
+    /Marked true
+  >>
+>>
+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 612 792]
+  /StructParents 0
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+BT
+/Para<</MCID 0>>
+BMC
+0 0 Td
+/F1 18 Tf
+(Sample Text) Tj
+EMC
+ET
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /StructTreeRoot
+  /ParentTree 6 0 R
+  /K [8 0 R]
+  /RoleMap <<
+    /Document /Document
+    /Para /Para
+  >>
+>>
+endobj
+{{object 6 0}} <<
+  /Nums [0 [7 0 R]]
+>>
+endobj
+{{object 7 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [0]
+  /P 42 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 8 0}} <<
+  /Type /StructElem
+  /S /Document
+  /K [9 0 R]
+  /P 5 0 R
+  /T (TitleText)
+  /Pg 3 0 R
+>>
+endobj
+{{object 9 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [10 0 R]
+  /P 8 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 10 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [11 0 R]
+  /P 9 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 11 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [12 0 R]
+  /P 10 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 12 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [13 0 R]
+  /P 11 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 13 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [14 0 R]
+  /P 12 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 14 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [15 0 R]
+  /P 13 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 15 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [16 0 R]
+  /P 14 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 16 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [17 0 R]
+  /P 15 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 17 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [18 0 R]
+  /P 16 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 18 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [19 0 R]
+  /P 17 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 19 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [20 0 R]
+  /P 18 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 20 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [21 0 R]
+  /P 19 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 21 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [22 0 R]
+  /P 20 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 22 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [23 0 R]
+  /P 21 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 23 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [24 0 R]
+  /P 22 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 24 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [25 0 R]
+  /P 23 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 25 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [26 0 R]
+  /P 24 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 26 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [27 0 R]
+  /P 25 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 27 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [28 0 R]
+  /P 26 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 28 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [29 0 R]
+  /P 27 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 29 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [30 0 R]
+  /P 28 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 30 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [31 0 R]
+  /P 29 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 31 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [32 0 R]
+  /P 30 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 32 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [33 0 R]
+  /P 31 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 33 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [34 0 R]
+  /P 32 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 34 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [35 0 R]
+  /P 33 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 35 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [36 0 R]
+  /P 34 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 36 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [37 0 R]
+  /P 35 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 37 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [38 0 R]
+  /P 36 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 38 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [39 0 R]
+  /P 37 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 39 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [40 0 R]
+  /P 38 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 40 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [41 0 R]
+  /P 39 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 41 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [42 0 R]
+  /P 40 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{object 42 0}} <<
+  /Type /StructElem
+  /S /Para
+  /K [7 0 R]
+  /P 41 0 R
+  /Pg 3 0 R
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/tagged_nested.pdf b/testing/resources/tagged_nested.pdf
new file mode 100644
index 0000000..8e09360
--- /dev/null
+++ b/testing/resources/tagged_nested.pdf
@@ -0,0 +1,395 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /StructTreeRoot 5 0 R
+  /Lang (en-US)
+  /MarkInfo <<
+    /Marked true
+  >>
+>>
+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 612 792]
+  /StructParents 0
+>>
+endobj
+4 0 obj <<
+  /Length 65
+>>
+stream
+BT
+/Para<</MCID 0>>
+BMC
+0 0 Td
+/F1 18 Tf
+(Sample Text) Tj
+EMC
+ET
+endstream
+endobj
+5 0 obj <<
+  /Type /StructTreeRoot
+  /ParentTree 6 0 R
+  /K [8 0 R]
+  /RoleMap <<
+    /Document /Document
+    /Para /Para
+  >>
+>>
+endobj
+6 0 obj <<
+  /Nums [0 [7 0 R]]
+>>
+endobj
+7 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [0]
+  /P 42 0 R
+  /Pg 3 0 R
+>>
+endobj
+8 0 obj <<
+  /Type /StructElem
+  /S /Document
+  /K [9 0 R]
+  /P 5 0 R
+  /T (TitleText)
+  /Pg 3 0 R
+>>
+endobj
+9 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [10 0 R]
+  /P 8 0 R
+  /Pg 3 0 R
+>>
+endobj
+10 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [11 0 R]
+  /P 9 0 R
+  /Pg 3 0 R
+>>
+endobj
+11 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [12 0 R]
+  /P 10 0 R
+  /Pg 3 0 R
+>>
+endobj
+12 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [13 0 R]
+  /P 11 0 R
+  /Pg 3 0 R
+>>
+endobj
+13 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [14 0 R]
+  /P 12 0 R
+  /Pg 3 0 R
+>>
+endobj
+14 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [15 0 R]
+  /P 13 0 R
+  /Pg 3 0 R
+>>
+endobj
+15 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [16 0 R]
+  /P 14 0 R
+  /Pg 3 0 R
+>>
+endobj
+16 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [17 0 R]
+  /P 15 0 R
+  /Pg 3 0 R
+>>
+endobj
+17 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [18 0 R]
+  /P 16 0 R
+  /Pg 3 0 R
+>>
+endobj
+18 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [19 0 R]
+  /P 17 0 R
+  /Pg 3 0 R
+>>
+endobj
+19 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [20 0 R]
+  /P 18 0 R
+  /Pg 3 0 R
+>>
+endobj
+20 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [21 0 R]
+  /P 19 0 R
+  /Pg 3 0 R
+>>
+endobj
+21 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [22 0 R]
+  /P 20 0 R
+  /Pg 3 0 R
+>>
+endobj
+22 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [23 0 R]
+  /P 21 0 R
+  /Pg 3 0 R
+>>
+endobj
+23 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [24 0 R]
+  /P 22 0 R
+  /Pg 3 0 R
+>>
+endobj
+24 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [25 0 R]
+  /P 23 0 R
+  /Pg 3 0 R
+>>
+endobj
+25 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [26 0 R]
+  /P 24 0 R
+  /Pg 3 0 R
+>>
+endobj
+26 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [27 0 R]
+  /P 25 0 R
+  /Pg 3 0 R
+>>
+endobj
+27 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [28 0 R]
+  /P 26 0 R
+  /Pg 3 0 R
+>>
+endobj
+28 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [29 0 R]
+  /P 27 0 R
+  /Pg 3 0 R
+>>
+endobj
+29 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [30 0 R]
+  /P 28 0 R
+  /Pg 3 0 R
+>>
+endobj
+30 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [31 0 R]
+  /P 29 0 R
+  /Pg 3 0 R
+>>
+endobj
+31 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [32 0 R]
+  /P 30 0 R
+  /Pg 3 0 R
+>>
+endobj
+32 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [33 0 R]
+  /P 31 0 R
+  /Pg 3 0 R
+>>
+endobj
+33 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [34 0 R]
+  /P 32 0 R
+  /Pg 3 0 R
+>>
+endobj
+34 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [35 0 R]
+  /P 33 0 R
+  /Pg 3 0 R
+>>
+endobj
+35 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [36 0 R]
+  /P 34 0 R
+  /Pg 3 0 R
+>>
+endobj
+36 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [37 0 R]
+  /P 35 0 R
+  /Pg 3 0 R
+>>
+endobj
+37 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [38 0 R]
+  /P 36 0 R
+  /Pg 3 0 R
+>>
+endobj
+38 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [39 0 R]
+  /P 37 0 R
+  /Pg 3 0 R
+>>
+endobj
+39 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [40 0 R]
+  /P 38 0 R
+  /Pg 3 0 R
+>>
+endobj
+40 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [41 0 R]
+  /P 39 0 R
+  /Pg 3 0 R
+>>
+endobj
+41 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [42 0 R]
+  /P 40 0 R
+  /Pg 3 0 R
+>>
+endobj
+42 0 obj <<
+  /Type /StructElem
+  /S /Para
+  /K [7 0 R]
+  /P 41 0 R
+  /Pg 3 0 R
+>>
+endobj
+xref
+0 43
+0000000000 65535 f 
+0000000015 00000 n 
+0000000145 00000 n 
+0000000208 00000 n 
+0000000322 00000 n 
+0000000438 00000 n 
+0000000575 00000 n 
+0000000616 00000 n 
+0000000701 00000 n 
+0000000810 00000 n 
+0000000899 00000 n 
+0000000989 00000 n 
+0000001080 00000 n 
+0000001171 00000 n 
+0000001262 00000 n 
+0000001353 00000 n 
+0000001444 00000 n 
+0000001535 00000 n 
+0000001626 00000 n 
+0000001717 00000 n 
+0000001808 00000 n 
+0000001899 00000 n 
+0000001990 00000 n 
+0000002081 00000 n 
+0000002172 00000 n 
+0000002263 00000 n 
+0000002354 00000 n 
+0000002445 00000 n 
+0000002536 00000 n 
+0000002627 00000 n 
+0000002718 00000 n 
+0000002809 00000 n 
+0000002900 00000 n 
+0000002991 00000 n 
+0000003082 00000 n 
+0000003173 00000 n 
+0000003264 00000 n 
+0000003355 00000 n 
+0000003446 00000 n 
+0000003537 00000 n 
+0000003628 00000 n 
+0000003719 00000 n 
+0000003810 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 43
+>>
+startxref
+3900
+%%EOF
diff --git a/testing/resources/tagged_table.in b/testing/resources/tagged_table.in
new file mode 100644
index 0000000..ee298c5
--- /dev/null
+++ b/testing/resources/tagged_table.in
@@ -0,0 +1,217 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /StructTreeRoot 8 0 R
+  /Lang (en-US)
+  /MarkInfo <<
+    /Marked true
+  >>
+>>
+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 612 792]
+  /Group <<
+    /CS /DeviceRGB
+    /I true
+    /S /Transparency
+  >>
+  /Resources <<
+    /ProcSet [/PDF /ImageC /ImageI /ImageB]
+    /XObject <<
+      /Tr8 5 0 R
+      /Im7 6 0 R
+    >>
+    /ExtGState <<
+      /EGS9 7 0 R
+    >>
+  >>
+  /StructParents 0
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+0.1 w
+/Artifact
+BMC
+q
+0 0 612 792 re
+W* n
+EMC
+/Figure<</MCID 0>>
+BDC
+Q
+q
+281 685.3 50 50 re
+W* n
+q
+49.9 0 0 50 281.1 685.4 cm
+/Im7 Do
+Q
+EMC
+Q
+q
+EGS9 gs /Tr8 Do
+Q
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /BBox [-140 395 753 395.1]
+  /Group <<
+    /CS /DeviceRGB
+    /K true
+    /S /Transparency
+  >>
+  {{streamlen}}
+>>
+stream
+endstream
+endobj
+{{object 6 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 50
+  /Height 50
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  {{streamlen}}
+>>
+stream
+789cedc13101000000c2a0f54fed6f06a00000000000000078031d4c0001
+endstream
+endobj
+{{object 7 0}} <<
+  /ca 0.5
+  /CA 0.5
+>>
+endobj
+{{object 8 0}} <<
+  /Type /StructTreeRoot
+  /ParentTree 9 0 R
+  /K [10 0 R]
+  /RoleMap <<
+    /Document /Document
+    /Standard /P
+    /Figure /Figure
+  >>
+>>
+endobj
+{{object 9 0}} <<
+  /Nums [
+    0
+    [10 0 R 11 0 R 12 0 R 13 0 R 14 0 R 15 0 R 16 0 R 17 0 R]
+  ]
+>>
+endobj
+{{object 10 0}} <<
+  /Type /StructElem
+  /S /Document
+  /K [11 0 R]
+  /P 8 0 R
+  /T (TitleText)
+  /Pg 3 0 R
+  /Lang (en-US)
+>>
+endobj
+{{object 11 0}} <<
+  /Type /StructElem
+  /S /Table
+  /K [12 0 R 13 0 R]
+  /P 10 0 R
+  /Pg 3 0 R
+  /A [<<
+        /O /Table
+        /Summary ()
+      >>]
+  /ID (node12)
+  /Lang (hu)
+>>
+endobj
+{{object 12 0}} <<
+  /Type /StructElem
+  /S /TR
+  /K [14 0 R 15 0 R]
+  /P 11 0 R
+  /Pg 3 0 R
+  /ID ()
+>>
+endobj
+{{object 13 0}} <<
+  /Type /StructElem
+  /S /TR
+  /K [16 0 R 17 0 R]
+  /P 11 0 R
+  /Pg 3 0 R
+  /A <<
+      /O /Table
+     >>
+  /ID (node14)
+>>
+endobj
+{{object 14 0}} <<
+  /Type /StructElem
+  /S /TH
+  /P 12 0 R
+  /Pg 3 0 R
+  /A [<<
+        /O /Table
+        /Scope /Row
+      >>
+      <<
+        /O /Table
+        /ColSpan 2
+      >>]
+  /ID (node15)
+>>
+endobj
+{{object 15 0}} <<
+  /Type /StructElem
+  /S /TD
+  /P 12 0 R
+  /Pg 3 0 R
+  /ID (node16)
+>>
+endobj
+{{object 16 0}} <<
+  /Type /StructElem
+  /S /TH
+  /P 13 0 R
+  /Pg 3 0 R
+  /A [<<
+        /O /Table
+        /Scope /Row
+      >>]
+  /ID (node17)
+>>
+endobj
+{{object 17 0}} <<
+  /Type /StructElem
+  /S /TD
+  /P 13 0 R
+  /Pg 3 0 R
+  /A [<<
+        /O /Table
+        /ColProp (Sum)
+        /CurUSD true
+     >>]
+  /ID (node18)
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/tagged_table.pdf b/testing/resources/tagged_table.pdf
new file mode 100644
index 0000000..4428682
--- /dev/null
+++ b/testing/resources/tagged_table.pdf
@@ -0,0 +1,241 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /StructTreeRoot 8 0 R
+  /Lang (en-US)
+  /MarkInfo <<
+    /Marked true
+  >>
+>>
+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 612 792]
+  /Group <<
+    /CS /DeviceRGB
+    /I true
+    /S /Transparency
+  >>
+  /Resources <<
+    /ProcSet [/PDF /ImageC /ImageI /ImageB]
+    /XObject <<
+      /Tr8 5 0 R
+      /Im7 6 0 R
+    >>
+    /ExtGState <<
+      /EGS9 7 0 R
+    >>
+  >>
+  /StructParents 0
+>>
+endobj
+4 0 obj <<
+  /Length 162
+>>
+stream
+0.1 w
+/Artifact
+BMC
+q
+0 0 612 792 re
+W* n
+EMC
+/Figure<</MCID 0>>
+BDC
+Q
+q
+281 685.3 50 50 re
+W* n
+q
+49.9 0 0 50 281.1 685.4 cm
+/Im7 Do
+Q
+EMC
+Q
+q
+EGS9 gs /Tr8 Do
+Q
+endstream
+endobj
+5 0 obj <<
+  /Type /XObject
+  /Subtype /Form
+  /BBox [-140 395 753 395.1]
+  /Group <<
+    /CS /DeviceRGB
+    /K true
+    /S /Transparency
+  >>
+  /Length 0
+>>
+stream
+endstream
+endobj
+6 0 obj <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 50
+  /Height 50
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  /Length 61
+>>
+stream
+789cedc13101000000c2a0f54fed6f06a00000000000000078031d4c0001
+endstream
+endobj
+7 0 obj <<
+  /ca 0.5
+  /CA 0.5
+>>
+endobj
+8 0 obj <<
+  /Type /StructTreeRoot
+  /ParentTree 9 0 R
+  /K [10 0 R]
+  /RoleMap <<
+    /Document /Document
+    /Standard /P
+    /Figure /Figure
+  >>
+>>
+endobj
+9 0 obj <<
+  /Nums [
+    0
+    [10 0 R 11 0 R 12 0 R 13 0 R 14 0 R 15 0 R 16 0 R 17 0 R]
+  ]
+>>
+endobj
+10 0 obj <<
+  /Type /StructElem
+  /S /Document
+  /K [11 0 R]
+  /P 8 0 R
+  /T (TitleText)
+  /Pg 3 0 R
+  /Lang (en-US)
+>>
+endobj
+11 0 obj <<
+  /Type /StructElem
+  /S /Table
+  /K [12 0 R 13 0 R]
+  /P 10 0 R
+  /Pg 3 0 R
+  /A [<<
+        /O /Table
+        /Summary ()
+      >>]
+  /ID (node12)
+  /Lang (hu)
+>>
+endobj
+12 0 obj <<
+  /Type /StructElem
+  /S /TR
+  /K [14 0 R 15 0 R]
+  /P 11 0 R
+  /Pg 3 0 R
+  /ID ()
+>>
+endobj
+13 0 obj <<
+  /Type /StructElem
+  /S /TR
+  /K [16 0 R 17 0 R]
+  /P 11 0 R
+  /Pg 3 0 R
+  /A <<
+      /O /Table
+     >>
+  /ID (node14)
+>>
+endobj
+14 0 obj <<
+  /Type /StructElem
+  /S /TH
+  /P 12 0 R
+  /Pg 3 0 R
+  /A [<<
+        /O /Table
+        /Scope /Row
+      >>
+      <<
+        /O /Table
+        /ColSpan 2
+      >>]
+  /ID (node15)
+>>
+endobj
+15 0 obj <<
+  /Type /StructElem
+  /S /TD
+  /P 12 0 R
+  /Pg 3 0 R
+  /ID (node16)
+>>
+endobj
+16 0 obj <<
+  /Type /StructElem
+  /S /TH
+  /P 13 0 R
+  /Pg 3 0 R
+  /A [<<
+        /O /Table
+        /Scope /Row
+      >>]
+  /ID (node17)
+>>
+endobj
+17 0 obj <<
+  /Type /StructElem
+  /S /TD
+  /P 13 0 R
+  /Pg 3 0 R
+  /A [<<
+        /O /Table
+        /ColProp (Sum)
+        /CurUSD true
+     >>]
+  /ID (node18)
+>>
+endobj
+xref
+0 18
+0000000000 65535 f 
+0000000015 00000 n 
+0000000145 00000 n 
+0000000208 00000 n 
+0000000556 00000 n 
+0000000770 00000 n 
+0000000952 00000 n 
+0000001212 00000 n 
+0000001253 00000 n 
+0000001412 00000 n 
+0000001515 00000 n 
+0000001642 00000 n 
+0000001826 00000 n 
+0000001931 00000 n 
+0000002074 00000 n 
+0000002276 00000 n 
+0000002366 00000 n 
+0000002513 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 18
+>>
+startxref
+2683
+%%EOF
diff --git a/testing/resources/tagged_table_bad_elem.in b/testing/resources/tagged_table_bad_elem.in
new file mode 100644
index 0000000..c502047
--- /dev/null
+++ b/testing/resources/tagged_table_bad_elem.in
@@ -0,0 +1,153 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /StructTreeRoot 8 0 R
+  /Lang (en-US)
+  /MarkInfo <<
+    /Marked true
+  >>
+>>
+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 612 792]
+  /Group <<
+    /CS /DeviceRGB
+    /I true
+    /S /Transparency
+  >>
+  /Resources <<
+    /ProcSet [/PDF /ImageC /ImageI /ImageB]
+    /XObject <<
+      /Tr8 5 0 R
+      /Im7 6 0 R
+    >>
+    /ExtGState <<
+      /EGS9 7 0 R
+    >>
+  >>
+  /StructParents 0
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+0.1 w
+/Artifact
+BMC
+q
+0 0 612 792 re
+W* n
+EMC
+/Figure<</MCID 0>>
+BDC
+Q
+q
+281 685.3 50 50 re
+W* n
+q
+49.9 0 0 50 281.1 685.4 cm
+/Im7 Do
+Q
+EMC
+Q
+q
+EGS9 gs /Tr8 Do
+Q
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /BBox [-140 395 753 395.1]
+  /Group <<
+    /CS /DeviceRGB
+    /K true
+    /S /Transparency
+  >>
+  {{streamlen}}
+>>
+stream
+endstream
+endobj
+{{object 6 0}} <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 50
+  /Height 50
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  {{streamlen}}
+>>
+stream
+789cedc13101000000c2a0f54fed6f06a00000000000000078031d4c0001
+endstream
+endobj
+{{object 7 0}} <<
+  /ca 0.5
+  /CA 0.5
+>>
+endobj
+{{object 8 0}} <<
+  /Type /StructTreeRoot
+  /ParentTree 9 0 R
+  /K [10 0 R]
+  /RoleMap <<
+    /Document /Document
+    /Standard /P
+    /Figure /Figure
+  >>
+>>
+endobj
+{{object 9 0}} <<
+  /Nums [
+    0
+    [10 0 R 11 0 R 12 0 R]
+  ]
+>>
+endobj
+{{object 10 0}} <<
+  /Type /StructElem
+  /S /Document
+  /K [11 0 R]
+  /P 8 0 R
+  /T (TitleText)
+  /Pg 3 0 R
+  /Lang (en-US)
+>>
+endobj
+{{object 11 0}} <<
+  % Deliberately missing /Type
+  /S /Table
+  /K [12 0 R]
+  /P 10 0 R
+  /Pg 3 0 R
+  /A [(bogus type)]
+  /ID (node12)
+  /Lang (hu)
+>>
+endobj
+{{object 12 0}} <<
+  % Deliberately bad /Type.
+  /Type /NotStructElem
+  /S /TR
+  /P 11 0 R
+  /Pg 3 0 R
+  /ID ()
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/tagged_table_bad_elem.pdf b/testing/resources/tagged_table_bad_elem.pdf
new file mode 100644
index 0000000..62beee0
--- /dev/null
+++ b/testing/resources/tagged_table_bad_elem.pdf
@@ -0,0 +1,172 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /StructTreeRoot 8 0 R
+  /Lang (en-US)
+  /MarkInfo <<
+    /Marked true
+  >>
+>>
+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 612 792]
+  /Group <<
+    /CS /DeviceRGB
+    /I true
+    /S /Transparency
+  >>
+  /Resources <<
+    /ProcSet [/PDF /ImageC /ImageI /ImageB]
+    /XObject <<
+      /Tr8 5 0 R
+      /Im7 6 0 R
+    >>
+    /ExtGState <<
+      /EGS9 7 0 R
+    >>
+  >>
+  /StructParents 0
+>>
+endobj
+4 0 obj <<
+  /Length 162
+>>
+stream
+0.1 w
+/Artifact
+BMC
+q
+0 0 612 792 re
+W* n
+EMC
+/Figure<</MCID 0>>
+BDC
+Q
+q
+281 685.3 50 50 re
+W* n
+q
+49.9 0 0 50 281.1 685.4 cm
+/Im7 Do
+Q
+EMC
+Q
+q
+EGS9 gs /Tr8 Do
+Q
+endstream
+endobj
+5 0 obj <<
+  /Type /XObject
+  /Subtype /Form
+  /BBox [-140 395 753 395.1]
+  /Group <<
+    /CS /DeviceRGB
+    /K true
+    /S /Transparency
+  >>
+  /Length 0
+>>
+stream
+endstream
+endobj
+6 0 obj <<
+  /Type /XObject
+  /Subtype /Image
+  /Width 50
+  /Height 50
+  /BitsPerComponent 8
+  /ColorSpace /DeviceRGB
+  /Filter [/ASCIIHexDecode /FlateDecode]
+  /Length 61
+>>
+stream
+789cedc13101000000c2a0f54fed6f06a00000000000000078031d4c0001
+endstream
+endobj
+7 0 obj <<
+  /ca 0.5
+  /CA 0.5
+>>
+endobj
+8 0 obj <<
+  /Type /StructTreeRoot
+  /ParentTree 9 0 R
+  /K [10 0 R]
+  /RoleMap <<
+    /Document /Document
+    /Standard /P
+    /Figure /Figure
+  >>
+>>
+endobj
+9 0 obj <<
+  /Nums [
+    0
+    [10 0 R 11 0 R 12 0 R]
+  ]
+>>
+endobj
+10 0 obj <<
+  /Type /StructElem
+  /S /Document
+  /K [11 0 R]
+  /P 8 0 R
+  /T (TitleText)
+  /Pg 3 0 R
+  /Lang (en-US)
+>>
+endobj
+11 0 obj <<
+  % Deliberately missing /Type
+  /S /Table
+  /K [12 0 R]
+  /P 10 0 R
+  /Pg 3 0 R
+  /A [(bogus type)]
+  /ID (node12)
+  /Lang (hu)
+>>
+endobj
+12 0 obj <<
+  % Deliberately bad /Type.
+  /Type /NotStructElem
+  /S /TR
+  /P 11 0 R
+  /Pg 3 0 R
+  /ID ()
+>>
+endobj
+xref
+0 13
+0000000000 65535 f 
+0000000015 00000 n 
+0000000145 00000 n 
+0000000208 00000 n 
+0000000556 00000 n 
+0000000770 00000 n 
+0000000952 00000 n 
+0000001212 00000 n 
+0000001253 00000 n 
+0000001412 00000 n 
+0000001480 00000 n 
+0000001607 00000 n 
+0000001758 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 13
+>>
+startxref
+1873
+%%EOF
diff --git a/testing/resources/text_in_page_marked.in b/testing/resources/text_in_page_marked.in
index e338479..5978110 100644
--- a/testing/resources/text_in_page_marked.in
+++ b/testing/resources/text_in_page_marked.in
@@ -131,7 +131,7 @@
 {{xref}}
 trailer <<
   /Root 1 0 R
-  /Size 13
+  {{trailersize}}
   /ID [<f341ae654a77acd5065a7645e596e6e6><bc37298a3f87f479229bce997ca791f7>]
 >>
 {{startxref}}
diff --git a/testing/resources/text_in_page_marked_indirect.in b/testing/resources/text_in_page_marked_indirect.in
index 1f989f6..6004ad4 100644
--- a/testing/resources/text_in_page_marked_indirect.in
+++ b/testing/resources/text_in_page_marked_indirect.in
@@ -137,7 +137,7 @@
 {{xref}}
 trailer <<
   /Root 1 0 R
-  /Size 14
+  {{trailersize}}
   /ID [<f341ae654a77acd5065a7645e596e6e6><bc37298a3f87f479229bce997ca791f7>]
 >>
 {{startxref}}
diff --git a/testing/resources/trailer_end_trailing_space.in b/testing/resources/trailer_end_trailing_space.in
new file mode 100644
index 0000000..0233b75
--- /dev/null
+++ b/testing/resources/trailer_end_trailing_space.in
@@ -0,0 +1,86 @@
+{{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
+% Single space after endstream and endobj.
+{{object 6 0}} <<
+  {{streamlen}}
+>>
+stream
+BT
+20 50 Td
+/F1 12 Tf
+(Hello, world!) Tj
+0 50 Td
+/F2 16 Tf
+(Goodbye, world!) Tj
+ET
+endstream 
+endobj 
+% Multiple spaces after endstream and endobj.
+{{object 6 0}} <<
+  {{streamlen}}
+>>
+stream
+BT
+20 50 Td
+/F1 12 Tf
+(Hello, world!) Tj
+0 50 Td
+/F2 16 Tf
+(Goodbye, world!) Tj
+ET
+endstream  
+endobj  
+% Tab after endstream and endobj.
+{{object 6 0}} <<
+  {{streamlen}}
+>>
+stream
+BT
+20 50 Td
+/F1 12 Tf
+(Hello, world!) Tj
+0 50 Td
+/F2 16 Tf
+(Goodbye, world!) Tj
+ET
+endstream	
+endobj	
+{{object 5 0}} <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/trailer_end_trailing_space.pdf b/testing/resources/trailer_end_trailing_space.pdf
new file mode 100644
index 0000000..e0ec6e4
--- /dev/null
+++ b/testing/resources/trailer_end_trailing_space.pdf
@@ -0,0 +1,99 @@
+%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
+% Single space after endstream and endobj.
+6 0 obj <<
+  /Length 83
+>>
+stream
+BT
+20 50 Td
+/F1 12 Tf
+(Hello, world!) Tj
+0 50 Td
+/F2 16 Tf
+(Goodbye, world!) Tj
+ET
+endstream 
+endobj 
+% Multiple spaces after endstream and endobj.
+6 0 obj <<
+  /Length 83
+>>
+stream
+BT
+20 50 Td
+/F1 12 Tf
+(Hello, world!) Tj
+0 50 Td
+/F2 16 Tf
+(Goodbye, world!) Tj
+ET
+endstream  
+endobj  
+% Tab after endstream and endobj.
+6 0 obj <<
+  /Length 83
+>>
+stream
+BT
+20 50 Td
+/F1 12 Tf
+(Hello, world!) Tj
+0 50 Td
+/F2 16 Tf
+(Goodbye, world!) Tj
+ET
+endstream	
+endobj	
+5 0 obj <<
+  /Type /Font
+  /Subtype /Type1
+  /BaseFont /Helvetica
+>>
+endobj
+xref
+0 7
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000157 00000 n 
+0000000299 00000 n 
+0000000910 00000 n 
+0000000774 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 7
+>>
+startxref
+986
+%%EOF
diff --git a/testing/resources/two_signatures.in b/testing/resources/two_signatures.in
new file mode 100644
index 0000000..f18495f
--- /dev/null
+++ b/testing/resources/two_signatures.in
@@ -0,0 +1,155 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /MediaBox [0 0 200 300]
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 4 0 R
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+0 0 0 rg
+0 290 10 10 re B*
+10 150 50 30 re B*
+0 0 1 rg
+190 290 10 10 re B*
+70 232 50 30 re B*
+0 1 0 rg
+190 0 10 10 re B*
+130 150 50 30 re B*
+1 0 0 rg
+0 0 10 10 re B*
+70 67 50 30 re B*
+Q
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
+
+%% First incremental update adds an initial signature and update objects to
+%% refer to it.
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /Fields [7 0 R]
+    /SigFlags 3
+  >>
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 4 0 R
+  /Annots [7 0 R]
+>>
+endobj
+%% ByteRange is a pairs of integers (starting byte offset, length in bytes)
+{{object 5 0}} <<
+  /Type /Sig
+  /Filter /Adobe.PPKMS
+  /SubFilter /ETSI.CAdES.detached
+  /ByteRange [0 10 30 10]
+  /Contents <308006092A864886F70D010702A0803080020101>
+  /M (D:20200624093114+02'00')
+>>
+endobj
+{{object 6 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /BBox [0 0 0 0]
+  /Length 0
+>>
+stream
+endstream
+endobj
+{{object 7 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Sig
+  /F 132
+  /Rect [0 0 0 0]
+  /P 3 0 R
+  /T (Signature1)
+  /V 5 0 R
+  /DV 5 0 R
+  /AP <<
+    /N 6 0 R
+  >>
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
+
+%% Second incremental update adds a next signature and update objects once again to refer to it.
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /Fields [7 0 R 10 0 R]
+    /SigFlags 3
+  >>
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 4 0 R
+  /Annots [7 0 R 10 0 R]
+>>
+endobj
+{{object 8 0}} <<
+  /Type /Sig
+  /Filter /Adobe.PPKMS
+  /SubFilter /ETSI.CAdES.detached
+  /ByteRange [0 40 50 10]
+  /Contents <308006092A864886F70D010702A080308002010131>
+  /M (D:20200624093118+02'00')
+>>
+endobj
+{{object 9 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /BBox [0 0 0 0]
+  /Length 0
+>>
+stream
+endstream
+endobj
+{{object 10 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Sig
+  /F 132
+  /Rect [0 0 0 0]
+  /P 3 0 R
+  /T (Signature2)
+  /V 8 0 R
+  /DV 8 0 R
+  /AP <<
+    /N 9 0 R
+  >>
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/two_signatures.pdf b/testing/resources/two_signatures.pdf
new file mode 100644
index 0000000..9a033d6
--- /dev/null
+++ b/testing/resources/two_signatures.pdf
@@ -0,0 +1,195 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /MediaBox [0 0 200 300]
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 4 0 R
+>>
+endobj
+4 0 obj <<
+  /Length 188
+>>
+stream
+q
+0 0 0 rg
+0 290 10 10 re B*
+10 150 50 30 re B*
+0 0 1 rg
+190 290 10 10 re B*
+70 232 50 30 re B*
+0 1 0 rg
+190 0 10 10 re B*
+130 150 50 30 re B*
+1 0 0 rg
+0 0 10 10 re B*
+70 67 50 30 re B*
+Q
+endstream
+endobj
+xref
+0 5
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000157 00000 n 
+0000000226 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 5
+>>
+startxref
+466
+%%EOF
+
+%% First incremental update adds an initial signature and update objects to
+%% refer to it.
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /Fields [7 0 R]
+    /SigFlags 3
+  >>
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 4 0 R
+  /Annots [7 0 R]
+>>
+endobj
+%% ByteRange is a pairs of integers (starting byte offset, length in bytes)
+5 0 obj <<
+  /Type /Sig
+  /Filter /Adobe.PPKMS
+  /SubFilter /ETSI.CAdES.detached
+  /ByteRange [0 10 30 10]
+  /Contents <308006092A864886F70D010702A0803080020101>
+  /M (D:20200624093114+02'00')
+>>
+endobj
+6 0 obj <<
+  /Type /XObject
+  /Subtype /Form
+  /BBox [0 0 0 0]
+  /Length 0
+>>
+stream
+endstream
+endobj
+7 0 obj <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Sig
+  /F 132
+  /Rect [0 0 0 0]
+  /P 3 0 R
+  /T (Signature1)
+  /V 5 0 R
+  /DV 5 0 R
+  /AP <<
+    /N 6 0 R
+  >>
+>>
+endobj
+xref
+0 8
+0000000000 65535 f 
+0000000726 00000 n 
+0000000068 00000 n 
+0000000835 00000 n 
+0000000226 00000 n 
+0000000998 00000 n 
+0000001201 00000 n 
+0000001303 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 8
+>>
+startxref
+1475
+%%EOF
+
+%% Second incremental update adds a next signature and update objects once again to refer to it.
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /Fields [7 0 R 10 0 R]
+    /SigFlags 3
+  >>
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Contents 4 0 R
+  /Annots [7 0 R 10 0 R]
+>>
+endobj
+8 0 obj <<
+  /Type /Sig
+  /Filter /Adobe.PPKMS
+  /SubFilter /ETSI.CAdES.detached
+  /ByteRange [0 40 50 10]
+  /Contents <308006092A864886F70D010702A080308002010131>
+  /M (D:20200624093118+02'00')
+>>
+endobj
+9 0 obj <<
+  /Type /XObject
+  /Subtype /Form
+  /BBox [0 0 0 0]
+  /Length 0
+>>
+stream
+endstream
+endobj
+10 0 obj <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Sig
+  /F 132
+  /Rect [0 0 0 0]
+  /P 3 0 R
+  /T (Signature2)
+  /V 8 0 R
+  /DV 8 0 R
+  /AP <<
+    /N 9 0 R
+  >>
+>>
+endobj
+xref
+0 11
+0000000000 65535 f 
+0000001801 00000 n 
+0000000068 00000 n 
+0000001917 00000 n 
+0000000226 00000 n 
+0000000998 00000 n 
+0000001201 00000 n 
+0000001303 00000 n 
+0000002011 00000 n 
+0000002216 00000 n 
+0000002318 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 11
+>>
+startxref
+2491
+%%EOF
diff --git a/testing/resources/uri_action_nonascii.in b/testing/resources/uri_action_nonascii.in
new file mode 100644
index 0000000..d2ec540
--- /dev/null
+++ b/testing/resources/uri_action_nonascii.in
@@ -0,0 +1,44 @@
+{{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
+  /Annots [4 0 R]
+>>
+endobj
+{{object 4 0}} <<
+  /A 5 0 R
+  /FT /Tx
+  /Ff 29360128
+  /Type /Annot
+  /Subtype /Link
+  /F 4
+  /Rect [1 1 199 199]
+  /BS  <<
+    /W 1
+    /S /S
+  >>
+  /DA (/Helv 0 Tf 0 0 0 rg)
+  /V ()
+>>
+endobj
+{{object 5 0}} <<
+  /S /URI
+  /URI (https://example.com/\245octal\307chars)
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/uri_action_nonascii.pdf b/testing/resources/uri_action_nonascii.pdf
new file mode 100644
index 0000000..ffc084a
--- /dev/null
+++ b/testing/resources/uri_action_nonascii.pdf
@@ -0,0 +1,56 @@
+%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
+  /Annots [4 0 R]
+>>
+endobj
+4 0 obj <<
+  /A 5 0 R
+  /FT /Tx
+  /Ff 29360128
+  /Type /Annot
+  /Subtype /Link
+  /F 4
+  /Rect [1 1 199 199]
+  /BS  <<
+    /W 1
+    /S /S
+  >>
+  /DA (/Helv 0 Tf 0 0 0 rg)
+  /V ()
+>>
+endobj
+5 0 obj <<
+  /S /URI
+  /URI (https://example.com/\245octal\307chars)
+>>
+endobj
+xref
+0 6
+0000000000 65535 f 
+0000000015 00000 n 
+0000000068 00000 n 
+0000000157 00000 n 
+0000000226 00000 n 
+0000000414 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 6
+>>
+startxref
+493
+%%EOF
diff --git a/testing/resources/viewer_pref_types.in b/testing/resources/viewer_pref_types.in
new file mode 100644
index 0000000..11b8034
--- /dev/null
+++ b/testing/resources/viewer_pref_types.in
@@ -0,0 +1,36 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /ViewerPreferences <<
+    /Bool true
+    /Num 1
+    /Str (str)
+    /Name /name
+    /Null null
+    /Ref 3 0 R
+    /EmptyArray []
+    /GoodArray [true 1 (str) /name]
+    /BadArray1 [true []]
+    /BadArray2 [1 <<>>]
+    /BadArray3 [/name 3 0 R]
+    /Dict <<
+    >>
+  >>
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/viewer_pref_types.pdf b/testing/resources/viewer_pref_types.pdf
new file mode 100644
index 0000000..f74ca6f
--- /dev/null
+++ b/testing/resources/viewer_pref_types.pdf
@@ -0,0 +1,46 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /ViewerPreferences <<
+    /Bool true
+    /Num 1
+    /Str (str)
+    /Name /name
+    /Null null
+    /Ref 3 0 R
+    /EmptyArray []
+    /GoodArray [true 1 (str) /name]
+    /BadArray1 [true []]
+    /BadArray2 [1 <<>>]
+    /BadArray3 [/name 3 0 R]
+    /Dict <<
+    >>
+  >>
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+>>
+endobj
+xref
+0 4
+0000000000 65535 f 
+0000000015 00000 n 
+0000000337 00000 n 
+0000000400 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 4
+>>
+startxref
+451
+%%EOF
diff --git a/testing/resources/xfa/xfa_break_before_after.in b/testing/resources/xfa/xfa_break_before_after.in
new file mode 100644
index 0000000..1ff2f3a
--- /dev/null
+++ b/testing/resources/xfa/xfa_break_before_after.in
@@ -0,0 +1,54 @@
+{{header}}
+{{include ../xfa_catalog_1_0.fragment}}
+{{include ../xfa_object_2_0.fragment}}
+{{include ../xfa_preamble_3_0.fragment}}
+{{include ../xfa_config_4_0.fragment}}
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+<template xmlns="http://www.xfa.org/schema/xfa-template/3.0/">
+  <subform name="Form01" layout="tb" locale="en_ZA" restoreState="auto">
+    <pageSet>
+      <pageArea name="Page1" id="Page1" initialNumber="1">
+        <contentArea x="10.455mm" w="190.5mm" h="286mm"/>
+        <occur min="1" max="1"/>
+      </pageArea>
+    </pageSet>
+    <subform w="190.5mm" h="286mm" name="TForm1SubForm1">
+    </subform>
+    <subform w="190.5mm" h="286mm">
+      <breakBefore targetType="contentArea" />
+    </subform>
+    <subform w="190.5mm" h="286mm">
+      <breakAfter targetType="contentArea" />
+    </subform>
+    <subform w="190.5mm" h="286mm">
+      <breakBefore targetType="pageArea" />
+    </subform>
+    <subform w="190.5mm" h="286mm">
+      <breakAfter targetType="pageArea" />
+    </subform>
+    <subform w="190.5mm" h="286mm">
+      <breakBefore targetType="pageEven" />
+    </subform>
+    <subform w="190.5mm" h="286mm">
+      <breakAfter targetType="pageEven" />
+    </subform>
+    <subform w="190.5mm" h="286mm">
+      <breakBefore targetType="pageOdd" />
+    </subform>
+    <subform w="190.5mm" h="286mm">
+      <breakAfter targetType="pageOdd" />
+    </subform>
+  </subform>
+</template>
+endstream
+endobj
+{{include ../xfa_locale_6_0.fragment}}
+{{include ../xfa_postamble_7_0.fragment}}
+{{include ../xfa_pages_8_0.fragment}}
+{{xref}}
+{{trailer}}
+{{endxref}}
+%%EOF
diff --git a/testing/resources/xfa/xfa_break_before_after.pdf b/testing/resources/xfa/xfa_break_before_after.pdf
new file mode 100644
index 0000000..2235016
--- /dev/null
+++ b/testing/resources/xfa/xfa_break_before_after.pdf
@@ -0,0 +1,262 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /AcroForm 2 0 R
+  /Extensions <<
+    /ADBE <<
+      /BaseVersion /1.7
+      /ExtensionLevel 8
+    >>
+  >>
+  /NeedsRendering true
+  /Pages 8 0 R
+  /Type /Catalog
+>>
+endobj
+2 0 obj <<
+  /XFA [
+    (preamble)
+    3 0 R
+    (config)
+    4 0 R
+    (template)
+    5 0 R
+    (localeSet)
+    6 0 R
+    (postamble)
+    7 0 R
+  ]
+>>
+endobj
+3 0 obj <<
+  /Length 124
+>>
+stream
+<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/" timeStamp="2018-02-23T21:37:11Z" uuid="21482798-7bf0-40a4-bc5d-3cefdccf32b5">
+endstream
+endobj
+4 0 obj <<
+  /Length 642
+>>
+stream
+<config xmlns="http://www.xfa.org/schema/xci/3.0/">
+<agent name="designer">
+  <destination>pdf</destination>
+  <pdf>
+    <fontInfo/>
+  </pdf>
+</agent>
+<present>
+  <pdf>
+    <version>1.7</version>
+    <adobeExtensionLevel>8</adobeExtensionLevel>
+    <renderPolicy>client</renderPolicy>
+    <scriptModel>XFA</scriptModel>
+    <interactive>1</interactive>
+  </pdf>
+  <xdp>
+    <packets>*</packets>
+  </xdp>
+  <destination>pdf</destination>
+  <script>
+    <runScripts>server</runScripts>
+  </script>
+</present>
+<acrobat>
+  <acrobat7>
+    <dynamicRender>required</dynamicRender>
+  </acrobat7>
+  <validate>preSubmit</validate>
+</acrobat>
+</config>
+endstream
+endobj
+5 0 obj <<
+  /Length 1191
+>>
+stream
+<template xmlns="http://www.xfa.org/schema/xfa-template/3.0/">
+  <subform name="Form01" layout="tb" locale="en_ZA" restoreState="auto">
+    <pageSet>
+      <pageArea name="Page1" id="Page1" initialNumber="1">
+        <contentArea x="10.455mm" w="190.5mm" h="286mm"/>
+        <occur min="1" max="1"/>
+      </pageArea>
+    </pageSet>
+    <subform w="190.5mm" h="286mm" name="TForm1SubForm1">
+    </subform>
+    <subform w="190.5mm" h="286mm">
+      <breakBefore targetType="contentArea" />
+    </subform>
+    <subform w="190.5mm" h="286mm">
+      <breakAfter targetType="contentArea" />
+    </subform>
+    <subform w="190.5mm" h="286mm">
+      <breakBefore targetType="pageArea" />
+    </subform>
+    <subform w="190.5mm" h="286mm">
+      <breakAfter targetType="pageArea" />
+    </subform>
+    <subform w="190.5mm" h="286mm">
+      <breakBefore targetType="pageEven" />
+    </subform>
+    <subform w="190.5mm" h="286mm">
+      <breakAfter targetType="pageEven" />
+    </subform>
+    <subform w="190.5mm" h="286mm">
+      <breakBefore targetType="pageOdd" />
+    </subform>
+    <subform w="190.5mm" h="286mm">
+      <breakAfter targetType="pageOdd" />
+    </subform>
+  </subform>
+</template>
+endstream
+endobj
+6 0 obj <<
+  /Length 3455
+>>
+stream
+<localeSet xmlns="http://www.xfa.org/schema/xfa-locale-set/2.7/">
+  <locale name="en_US" desc="English (United States)">
+    <calendarSymbols name="gregorian">
+      <monthNames>
+        <month>January</month>
+        <month>February</month>
+        <month>March</month>
+        <month>April</month>
+        <month>May</month>
+        <month>June</month>
+        <month>July</month>
+        <month>August</month>
+        <month>September</month>
+        <month>October</month>
+        <month>November</month>
+        <month>December</month>
+      </monthNames>
+      <monthNames abbr="1">
+        <month>Jan</month>
+        <month>Feb</month>
+        <month>Mar</month>
+        <month>Apr</month>
+        <month>May</month>
+        <month>Jun</month>
+        <month>Jul</month>
+        <month>Aug</month>
+        <month>Sep</month>
+        <month>Oct</month>
+        <month>Nov</month>
+        <month>Dec</month>
+      </monthNames>
+      <dayNames>
+        <day>Sunday</day>
+        <day>Monday</day>
+        <day>Tuesday</day>
+        <day>Wednesday</day>
+        <day>Thursday</day>
+        <day>Friday</day>
+        <day>Saturday</day>
+      </dayNames>
+      <dayNames abbr="1">
+        <day>Sun</day>
+        <day>Mon</day>
+        <day>Tue</day>
+        <day>Wed</day>
+        <day>Thu</day>
+        <day>Fri</day>
+        <day>Sat</day>
+      </dayNames>
+      <meridiemNames>
+        <meridiem>AM</meridiem>
+        <meridiem>PM</meridiem>
+      </meridiemNames>
+      <eraNames>
+        <era>BC</era>
+        <era>AD</era>
+      </eraNames>
+    </calendarSymbols>
+    <datePatterns>
+      <datePattern name="full">EEEE, MMMM D, YYYY</datePattern>
+      <datePattern name="long">MMMM D, YYYY</datePattern>
+      <datePattern name="med">MMM D, YYYY</datePattern>
+      <datePattern name="short">M/D/YY</datePattern>
+    </datePatterns>
+    <timePatterns>
+      <timePattern name="full">h:MM:SS A Z</timePattern>
+      <timePattern name="long">h:MM:SS A Z</timePattern>
+      <timePattern name="med">h:MM:SS A</timePattern>
+      <timePattern name="short">h:MM A</timePattern>
+    </timePatterns>
+    <dateTimeSymbols>GyMdkHmsSEDFwWahKzZ</dateTimeSymbols>
+    <numberPatterns>
+      <numberPattern name="numeric">z,zz9.zzz</numberPattern>
+      <numberPattern name="currency">$z,zz9.99|($z,zz9.99)</numberPattern>
+      <numberPattern name="percent">z,zz9%</numberPattern>
+    </numberPatterns>
+    <numberSymbols>
+      <numberSymbol name="decimal">.</numberSymbol>
+      <numberSymbol name="grouping">,</numberSymbol>
+      <numberSymbol name="percent">%</numberSymbol>
+      <numberSymbol name="minus">-</numberSymbol>
+      <numberSymbol name="zero">0</numberSymbol>
+    </numberSymbols>
+    <currencySymbols>
+      <currencySymbol name="symbol">$</currencySymbol>
+      <currencySymbol name="isoname">USD</currencySymbol>
+      <currencySymbol name="decimal">.</currencySymbol>
+    </currencySymbols>
+    <typefaces>
+      <typeface name="Myriad Pro"/>
+      <typeface name="Minion Pro"/>
+      <typeface name="Courier Std"/>
+      <typeface name="Adobe Pi Std"/>
+      <typeface name="Adobe Hebrew"/>
+      <typeface name="Adobe Arabic"/>
+      <typeface name="Adobe Thai"/>
+      <typeface name="Kozuka Gothic Pro-VI M"/>
+      <typeface name="Kozuka Mincho Pro-VI R"/>
+      <typeface name="Adobe Ming Std L"/>
+      <typeface name="Adobe Song Std L"/>
+      <typeface name="Adobe Myungjo Std M"/>
+    </typefaces>
+  </locale>
+</localeSet>
+endstream
+endobj
+7 0 obj <<
+  /Length 11
+>>
+stream
+</xdp:xdp>
+endstream
+endobj
+8 0 obj <<
+  /Type /Pages
+  /Count 1
+  /Kids [9 0 R]
+>>
+endobj
+9 0 obj <<
+  /Type /Page
+  /Parent 8 0 R
+  /MediaBox [0 0 612 792]
+>>
+endobj
+xref
+0 10
+0000000000 65535 f 
+0000000015 00000 n 
+0000000199 00000 n 
+0000000358 00000 n 
+0000000534 00000 n 
+0000001228 00000 n 
+0000002472 00000 n 
+0000005980 00000 n 
+0000006042 00000 n 
+0000006105 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 10
+>>
+{{endxref}}
+%%EOF
diff --git a/testing/resources/xfa/xfa_combobox.pdf b/testing/resources/xfa/xfa_combobox.pdf
index 0989361..a4b606c 100644
--- a/testing/resources/xfa/xfa_combobox.pdf
+++ b/testing/resources/xfa/xfa_combobox.pdf
@@ -224,7 +224,7 @@
 endobj
 9 0 obj <<
   /Type /Page
-  /Parent 2 0 R
+  /Parent 8 0 R
   /MediaBox [0 0 612 792]
 >>
 endobj
diff --git a/testing/resources/xfa/xfa_date_time_edit.pdf b/testing/resources/xfa/xfa_date_time_edit.pdf
index 04ea239..33f02bd 100644
--- a/testing/resources/xfa/xfa_date_time_edit.pdf
+++ b/testing/resources/xfa/xfa_date_time_edit.pdf
@@ -219,7 +219,7 @@
 endobj
 9 0 obj <<
   /Type /Page
-  /Parent 2 0 R
+  /Parent 8 0 R
   /MediaBox [0 0 612 792]
 >>
 endobj
diff --git a/testing/resources/xfa/xfa_image_edit.in b/testing/resources/xfa/xfa_image_edit.in
index 0e36fdd..a3bdae6 100644
--- a/testing/resources/xfa/xfa_image_edit.in
+++ b/testing/resources/xfa/xfa_image_edit.in
@@ -21,7 +21,9 @@
           <imageEdit data="embed"/>
         </ui>
         <value>
-          <image contentType="image/jpg">FOOOEY</image>
+          <image contentType="image/jpg">
+            {{include ../mona_lisa.fragment}}
+          </image>
         </value>
       </field>
     </subform>
diff --git a/testing/resources/xfa/xfa_image_edit.pdf b/testing/resources/xfa/xfa_image_edit.pdf
index 7496367..d35ef5d 100644
--- a/testing/resources/xfa/xfa_image_edit.pdf
+++ b/testing/resources/xfa/xfa_image_edit.pdf
@@ -72,7 +72,7 @@
 endstream
 endobj
 5 0 obj <<
-  /Length 667
+  /Length 9005
 >>
 stream
 <template xmlns="http://www.xfa.org/schema/xfa-template/3.3/">
@@ -89,7 +89,117 @@
           <imageEdit data="embed"/>
         </ui>
         <value>
-          <image contentType="image/jpg">FOOOEY</image>
+          <image contentType="image/jpg">
+/9j/4AAQSkZJRgABAQEAZABkAAD//gBSRmlsZSBzb3VyY2U6IGh0dHA6Ly9jb21tb25zLndpa2lt
+ZWRpYS5vcmcvd2lraS9GaWxlOk1vbmFfTGlzYV9mYWNlXzgwMHg4MDBweC5qcGf/2wBDAAYEBQYF
+BAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUo
+KSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo
+KCgoKCgoKCgoKCgoKCj/wAARCAB4AHgDAREAAhEBAxEB/8QAHAAAAgIDAQEAAAAAAAAAAAAABQYE
+BwEDCAIA/8QAOxAAAgECBQIEBAQFAwMFAAAAAQIDBBEABRIhMQZBEyJRYQcycYEUkaGxFUJiwfAj
+JOEWF9ElM1LC8f/EABoBAAIDAQEAAAAAAAAAAAAAAAIDAQQFAAb/xAAvEQACAgICAgAEBQQCAwAA
+AAAAAQIRAyESMQRBBRMiUTJhcaGxFCNSgZHwweHx/9oADAMBAAIRAxEAPwBqiIChT5t7gEYwX1ss
+JUbY0ErKBHpFu498Q3fRKTMmJVNm2POo9/tiG2kTFG+FfIAq9t2ta2BtvsKtkqKmDE2UgMDiUn2C
+3ugTnvVGRdPy6M2zKFJxv+HivLN6i6LuPvbDsalPaRPy29Cw/wAYOn1kPgUmYS3OxZUjJvwbFrgY
+fHx8hziqCVF8V+namVUnSvojzqlp9SkD3QkYGWKa62SsY5ZVmVDmlMKnLamCqgvu8bBgPYjkH64U
+3x/FpkcWF4yT8oG4337YBzdUgVHezEwN1N1BxzurslJGI1uSpJG3bvjlew2bYUN+fS+Cj12DJkqE
+WNgOeL4OM66AaNscXkb2vziVK47ZD0IkcG1r/X/PthVWFZLRNKqAAdiCT9cC19jk77MRpqILKNjf
+i/tbCpcug40SooAz6tNyfLsOPbBQhslsrH4n/ECXLa+Tp7IZvBrxaOprEXU0Fx8if1+/a/ri3i8e
+1zn1/P8A6Ba6oR8h6YqY8szKshpauaWdNCzBHkZifmYk778ffAZvIU5Qg3pMsQg4xbS2KmcZQKPU
+aqmqItVhqeEqL9rnGhjzc3SaZXyY63QGDvSuJaScofVfMp57YsOPLUkLUnHcQplXUFfQZrFV5bK2
+XZkll8SEWRx6MnBB9D+mEywppqW0N+by/U6Y+EvXdP1rlrJKkVNnVMAtVTLsrDgSJ30nj2O3pjLz
+4XhlXr0d+JWh6eJQCy2b6DEOKAT+55hQrYsNrW98TH2S2ToAATYG5GwI4wUqSYPZuSEBNXAIBO2E
+8eO0TZ8UZVtf5hvbE7RHYkQRG6kix7f2wuMnexjr0SvDZiqpf6dsH30D12bIKe77gna7W7bYHbbC
+tIFdf9R0/R3S9VmcrIJFHh06t/PKR5Rbk+v0GLMISk1CK2wE03begP8ACHommhy6LM8zjhqM0qf9
+eeoljEjhm3sL7D7b++KmXK8+Tin9K0l+hcUflwTrbLXFHCABftYdvtthbjRHNgjOsoiqKaaJ9Tqy
+kFWAKn88Vsip6HwlfZzV8R+kKeikeSjS128wCD+2NT4f57yfTP0I8jCltFWyJJEXul0vYkLce4Jx
+tqSfRRoJ9K5/WdNdSUOb5a7iWmbUVPEkZI1o3qCt/wBMBmxLLjcP+P1IjOpWztvJa+lzTJ6PMqF9
+dJVxLLG47qwuPpbi2MqP0Opd9ByV9E2KNWF97AbNiWlu2crN8cIABIFxyL7YW2yTZGhlNr7eltsc
+nZD0ZkpyI++1+cMcVVg3sUUWMxRtHpbVc3GKr4voYrM063k32YEi9t9zhiTXRDJVHAzSB3uoK2F/
+bEwm4u7OaT0UL8cs9TqHPsqyZEH+nWxaWvuus7KB6keYn6Dti5gySm5Zn0kyflrGlBdtl7dNWp6F
+FY2awU39RjFxx1aNHJ9g6pdWa5LX3J9MS27aE0uyHXiSRCFN9rG3OEThyGxaQi9UdOpXwyCW1muD
+b/PbC4J4ZckNdTVM5u63y5cpzeemilCQDzebuff9bY9R4eV5cak+zMzxUJUhVmbUNQt6W9bC++Lp
+WaSOjvgT1JK/w+ho5mtHl9Y1OD6o1pB9hrP5Yy/Mhxm697Gp3Wy0aXNhNMsIYi29u1j2v37Yq7fZ
+LetB01arE5DKVQaRY8m+/wDbHUxTnvQRplvbcaTuL+/GIXdMY2bwbxFd2wXNtUD07KMyvqid3WGn
+LvqszF0PIB8o/LfEairZNT9D109mYzSmMiRaJUkMbjmxIDCx+hwacpNEKadk3Nq38HlE8oGpvw7s
+thvcKdsLlG6TCUt0jkbrCsaXramzCGSNr10MmkfNrUqtxfsQBtjS8eP9hwf2f7jJ25KS+6Lv/wC6
+VBDlQq0lSipEm/DhqpZSddr2IRG08H5iDtxjGXi5XJQjt1fa6L7yQrkx1n6p0dKSZwIwAE4vca+B
+Y973B++KXJyfFd9B/LS2xLTq7NKbIWzvOfHpaeRxGFWkknILfKCFsBe3rg/lKWR48cr/ADbpHcmo
+3JAOLrjqHPcwio8uyeaohcj/AHUaSJGBv5jrUabW4P64tT8XHjjynk39tX+wr5km6jErP4oUM8Od
++JUfM/zC99/rjT+GZYvHSRV8lNSViSmmF2XUrM1wQefe2NTsp7uix/hJWFKDNaUMViM0E5AYgsNJ
+Ui/2GKHmR/C/ZPWi5MkzgykxMYlABszCxuP32xVUFsGWR+w1Lm0cNJHGAJRIw3U302bfbne2Ipds
+SOXT9UKqEsHLJqBH0HbFKVqSTLqaadByJ/D1FgbW2vhuO07BbXRydQZocvqqclJCW31XA3IsSe1z
+fbFiWHndC1krQfyLrl6TI5KKFNFTGDaULfU1yGJ/NQCe2AyYJJ/T0Hjkktk2l6tmoTmVI0zSrBEq
+wySG5RmZthc8AXIxPy3KCZy1Oijxoi67yiKUf7eHNI1Z73DDxRck+v8A4xou/wCnlXbi/wCBqf1x
+17OwP4TBW05RJqiJTJ4jBQu7X3O4Nj7jHmFBTjyTNNzcHRo6ioUk6ckprBYGlBFxfYf/AIMdwaWi
+LTeyblGXRnLYYWqaiOwsdDDf87jELFyVSOlNx/Caa5abKKdjCZGL3LNI5YnC5pQdRQULkrZyz8Yc
+wNZ1G3hFrIeB2/y2PRfCYccNv2Z/lu5UhEcuXErWYHdibbE/2xq1ZRHz4VpNP1BVU1I0i+PRlyq2
+a5V1P/2/XFPyopQTfoJLk9Fy5TRVkMjvLTVMpA3ZrHew/I/bvijyW9kSg0uiWIK2PSYaGpYA7Cwv
+xyT3xzURLvsaukq2opJSKiCWJGJtZCdz9sJlFdpjMc2tMbJMxQqbyMCb8jAPI1sclZyPmMBZ2ZZW
+GkeJqLaix4A+mNODr0IaNbMYiDDJIAbgMBbUpAO4F9r3/K+J2yaT7AGeVdTYtHIG1Pu3qTcbn7n8
+sWMUVQSb5C3mFayrGYXa8bhyrdiDdbHvxh0YJ6GznpUdk9I9QJmuUUciOC00aEXO1iAf748jNPHc
+H6dGy6nUgN8QOuafpqloqGty+tkr5m3iiFw68albhhxxv64b4+CedaaSX3ETlHG7e7GLpPMzU9OU
+lZVRS0krhv8AQlPnUajpv72thTSg2rug/wASTFzrTNZTCywgkr9sLjHnJX6Dk6WjmLrCoaozeWR7
+sdR2btvwceq8VVjSRlZvxAaWcNEpK2f+axPGLCEMNdLVMkWYRmJn8UkqpHuLf87emByxuLvoh7Lb
+ynM8wphrSSrjB8xW1lJ2/wA7YoNKnQDeg7H1DXooAmrFckWUbn9rdsQ8a9CqDtB1XUJvUzh1202s
+Dv625tgJwXVEptK7CY6jlqoisTygggGy7geuFcFdkcm/pbOdpa7xpQzCXzeQG2s27WONCMKHHppn
+lHhqg1KbhhtfjkG37euJBe2Q81y92y8vM6HUy2AI8p3P9t//ADgoZVy0iYJ3QqThI4NBVZJmc3bk
+qB6fXFlNt2Ntca9l5fA7qWlzTp6PJ6ipNPmVIDGrgjV4d/Kwvza9vtjznxXBKGR5K+mX8ml4mVTg
+oe0WR1OlR4UUZrcwqHUXSdcvjk29yLAfljN0pW/5LXoh5DA1NMZszrKyrn07LKiokYHoFHJuNyTi
+ZSjJrVV+oKX52LvXGcwDxI42BYgjbfe22H+Pi5y2LyTpUc/Z9KZcwZ2Yl2a/t7DHqMKSjSMvK9gy
+VlvZCRtp+vqcNQtumFMhDfjIWifS9wb3taxwvJJKLOirLlpljjdYiulnF/KfNuNhx9+cZnPTdC3H
+VBCSjUxqZFOlPMCU77knb2xHNN7YFM30ckEQIAXTfY6fMLd8Tr2CyfJnsUKlIULNfsPl55PpxiJQ
+V2FG0ikqKoLlRpRlbSCjC4O/Fr8k+98aEo/caHaWYyOVMOXBRIWCSHYj6ffCZxXabIoL5hl0/wD0
+5WySJQNEkQmURhiWCkG1jyQL++EJrmtjIqip8x8JpnnkRXZyQNPC27n12tjSiq0TrtkGOtlocziq
+sullp54SGjkDWa+3+Wwc4KUeM9pkW4SuLOi+kfjrlz9PxwZ0r0+ZIgWTSl0f+ofX0x5/P8Kywf8A
+a3H+DRx+VCf4tMEZ/wDEuOoB/A6UjI80kjC/5emBx/DZ95Dp511ErvMuojVvppr1EzXJfgL32vzj
+Sx+Lw70V5ZL62LVXSy+O5ZjIxNy9tgMXLVUV3FoinQiG+7WNiB++D7AJuWzGJ1K3BUcn7EYiULVE
+xdOy6qLNoTl1LIWEr2XSVIsGNr77d7jb9cZrwtXE7l7DdVXxVETeV4ybKoQ727m3bfCfkxUrBcrV
+UQBXwq7GJZmXRqKActf0+ww2Ka0C4Jn1TnETVI0sCC1iBGPU/p+3ptjpJvs5QS9i1Q0IVUctAlmu
+PCjB/ckg4a5xYwPUpiiZ1srPqHnbw9TahyABzta+Ikv8URFm+oqA0Eo8VDGV0MqkEDm4P14++EO0
+9DE12UbnlGtPn1VTh2aNJLIVTc+VSARtv5gMa2KVwUgX2BZUu6nURcXJY73w7sGSoO9ARUcnWuUQ
+5giyUk1QIXRvl84Ki/3IxW8vl8mTi6dB4GlkXItXqb4WU8JY0EcSWO5AuAMZGH4nKL4z2Wsnjp7R
+AynonTIgnjUpcCygj8v3wefzk1pnQxv2TOrOlBT5S/gRqiqoJ2tbfck+mEeN5vLJ9TGSxaKlqKfw
+igdGUgHy25B4xvRmn0UZRNog8GjSWQeQFjbttYYlTTlR0o0rLL6OzCiqMshK1FPSLpWO7garj5u3
+YnnFDKppvt//AEFRTHVYacgQ0udQSMynWGS4tzzqxUtydyQTiq0YfpseHLWawaYC6u3kPoCvub4O
+OWvpbI4ezbTdJxC0r1XhIx1aW8oUn1v/AJvivPzI39DsdHx5PtUVPoneOVpayRKlKZfCaJiCdyTv
+ck2F/uMaXKnpavYiiMnW1Y9OwqxTtO6C0ynQoIuo1AA78/8AGHy8aL6YN0eM16rr5qeHxggpp0Cz
+aYwLMrndTyLGx9MQvHjvfR1+hPramevr6iaSZpJJZS2vgsext9hixGKjFJE22fZbltZmtctLQwy1
+FQ+yJGNRv+1vfHTyQhHnkdImMJSfFLZevw3+EUcEyV2czh6lfkVR5EbtYnk+/tjB8n4m8v0YVS/c
+u4vGUPql2XFJl5MAWYaibD5f8tjIk0XEjNNkSIxa2jfa/wCWBa+xNkHPMnSajdbgEIwIbv6XHpgV
+qXJBJXo5zqsnEWdGjIWS8oVSG+XU9h9bb3HbHpoZ+WHn+RQljqVEHqOkENFDSqiMq1UxW3JF7H7X
+Xj64d487lyv0hWRar8wJk0arVCJ2RUJJ1MdlbixPobYt5HcW0V0iysiyTMa6ro2pqOi0RvdHjk1K
++2wIBJIxk5pwjabewoxd2hpHRvU1TmFFXVGZapoTdjqKge3Nj2H0AxXl5eOMWlHsOOCTY7ZjUTUm
+VwrLL+JrVGyKCdbD1P8ALz3OMzDH63JaTLkp8Y17KG6k8OOKopKGIvII1GuxBtxb2G55/vj0HjqT
+lym/ZTlVUhPqqA/wWREVS8Uha+m+w2IB/LjGgprmhDTI2awuuVUxmLqI49Kqex1E2PvucdGVzdE1
+SsG0ccktSqxX1Dvbgep/PBt0rOirejpj4C9IJQ5TLWTxXnqW1K9iCYx8ot6Hn7jHmfifkPNlUU9L
++TVwY/lw/Nl009Ivg2CgWsRccHFSNpWiW7dGWijuBGLXbAPYa12bWj0wGx78WxMlUQU9i91AqpSz
+CUnwyp498VcjldD8Zz7EIaTOqd6dkll/EukjWuCQbkqSeNyfXtvj0D5TxvkvVlZ1FiP1DXvJmwic
+qRCWN/fUf73xqePjUcdr2UMsvqPa5LVVVG88dNK8RYBNKni3Jt62wXz4xbi2FxbV0Fum80qKevSn
+qZXpp1kChilib8bYR5GFSi5R2LafRfGW9RR1FHFBUxzyGMJTuIxpAfgAXtfb19748/ODT2WYz0e6
+l6GOnWVzXxr4nhp8urUb3BBa/wBzhP1ctfuE6rZVOe0aNCskauXSO7Kw0rIO2/pe36Y1sGRp02Vp
+xdWKeeS02V5PGs0aLUMRaPuSMaGLnlyWnoBpRVsQayplq5DJMQVDHSnZfYY0IxSWhTdlp/B3pMZt
+RzVksPiXa2+1gP2A2NxvjH+JeY8clCJf8TEmuTOm+k8pGU5VBT69ciLubW1H1AxhOTcm37LcpWHw
+BYDa/e+Du9AL7mDGRp3IOq9sQ4vom/Z9UJqW1rEbHvgZHJ7EvrVo48qqBJJa6FTcHk9vU4RdzikW
+I9MpSopZ6itCUdGoUEkuyhUDXW9zfbgbcXxtQmlG5S3/AOCrkT6iiZknw5paurmq5JRmFbK5Z1SI
+yxq1727Ltfe57YXk+JTSUIql+4C8ZW5NhvOsloaOkZMwzGKIR/8AtJNVrCL8GyxrueRtfAYcuSTk
+4x3+l/yFOMUtspvq5MtjrUejqF8YfM0c0rgenzqP0ON7xnkcWpr+DPy1eiT0v17XZUwhqJmeEEBJ
+lVQwP9RNwdu/IwryPAhkuUdMnHlcdMtTJ/iHPDCGzFEZJPKr+EmpbDctpA59TvjMn4bb+mi1GQKp
+0myd2rM8rqengC6pUldW2K7WUEkX+vNhbA5az/Rhi2/0ohfRuWim+r83Gd59PVxK0dKvkp47Wsg9
+vfnHofGwfIxqDdv2Uck+UrQMjjaQrCpbzDg84baQNM6J+Due02Vwfgc5XRS2DxS6SFF+dQ/Kx+2P
+M/EcDlk+bD/Zq+PlShxZfFPXUtTRGqpqiOSMjV4isCCPrx3xm8lX2D4uyTSFpRrIIU4OKs6TrROA
+TQe/IGHqOhLbs1SeGgYHn62H1wuSDTbK862rqGOOZDLrYA/JJpAJG4v22v72xWWJzmmh/wAxQVMq
+PMetMloJJHaMZhU2IjhtaFe3H83bnGvj+HZsi/xX7lV+RFO3sWM++JOdVkfgzVy5fSqDppqRLEDi
+5tsP0Pti/g+F4obrl+bEy8lvrQjVuc1Uxv8AiZyp/pA3+u+NKOCEVVFdzb7YPeeRyLs7G9zra+DS
+SAb9mI9QG1irHcDg46jhx6Unlqf/AEzYTIC8bjctYElSODtc7+n0xUz41H+5/wB/UtYJuX0P/v5A
+3rmeq/i38PqleMU41OjC12Nz+gNh9cT4UY8OcfYnNafF+hZbbzXv7W74t0IDmQQJJI81TfSGAuDx
+te+/+cYRlbWkGl9xsjzYitpIqYMksqDQNfyKCbk32vYHn/5DFT5Sabl6GqdPQcyjNJTI6ZfO1KsV
+tbU8ugsx33HDADfj88V8mBNXJXY6GV9Idss+IWf5epi/iaT6AAyVFOCRe1hdbeo5v2xVfiQ7imv9
+jVlT7C8HxZro95IKCcKbF4y4J/Q/TAf0kv8AIJzh3REz74pVE1NIbU9DDGt5JSS+/ZFIFy1+w3+g
+3wEfDcpV2BLyIpfSVD1D1f40FU5m8JpzaOJV8SZ151MSdMYNztuxxq4PD4ta6/4/19ytPNYjPXSy
+E+CCt99iSxPqTycaKikV07C2X5bClI1bVgtHTjdb7SPvZfzt+uFSnLkox7YVLshVcaRKseka7NyN
+gbL/AM4bFtnPQLWOQm6q5ABJ8p49T7e+D5AbZ6VvmNh2sL8Y6yVYRy+qemqaadLiSFw4sObdt8RJ
+cotP2HGTi7XZ/9k=
+          </image>
         </value>
       </field>
     </subform>
@@ -222,7 +332,7 @@
 endobj
 9 0 obj <<
   /Type /Page
-  /Parent 2 0 R
+  /Parent 8 0 R
   /MediaBox [0 0 612 792]
 >>
 endobj
@@ -234,14 +344,14 @@
 0000000358 00000 n 
 0000000534 00000 n 
 0000001228 00000 n 
-0000001947 00000 n 
-0000005455 00000 n 
-0000005517 00000 n 
-0000005580 00000 n 
+0000010286 00000 n 
+0000013794 00000 n 
+0000013856 00000 n 
+0000013919 00000 n 
 trailer <<
   /Root 1 0 R
   /Size 10
 >>
 startxref
-5657
+13996
 %%EOF
diff --git a/testing/resources/xfa/xfa_multiline_textfield.pdf b/testing/resources/xfa/xfa_multiline_textfield.pdf
index 6b7eae4..eedd6a2 100644
--- a/testing/resources/xfa/xfa_multiline_textfield.pdf
+++ b/testing/resources/xfa/xfa_multiline_textfield.pdf
@@ -221,7 +221,7 @@
 endobj
 9 0 obj <<
   /Type /Page
-  /Parent 2 0 R
+  /Parent 8 0 R
   /MediaBox [0 0 612 792]
 >>
 endobj
diff --git a/testing/resources/xfa_pages_8_0.fragment b/testing/resources/xfa_pages_8_0.fragment
index ce089c4..2a8a910 100644
--- a/testing/resources/xfa_pages_8_0.fragment
+++ b/testing/resources/xfa_pages_8_0.fragment
@@ -6,7 +6,7 @@
 endobj
 {{object 9 0}} <<
   /Type /Page
-  /Parent 2 0 R
+  /Parent 8 0 R
   /MediaBox [0 0 612 792]
 >>
 endobj