diff options
author | Ryan Harrison <rharrison@chromium.org> | 2018-02-23 22:10:06 +0000 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2018-02-23 22:10:06 +0000 |
commit | 26820b47434313b187d664ef702f48b1059bacb5 (patch) | |
tree | fb46186c97fd4fbd5a418a4cdc3541fdc6562ee8 | |
parent | 3760afa05acd4955120a47b82ecf3d543541b791 (diff) | |
download | pdfium-26820b47434313b187d664ef702f48b1059bacb5.tar.xz |
Setup testing XFA using .in fileschromium/3355chromium/3354
This adds a number of {{}} style tags to the .in format that allow the
fix-up script to inject XFA related boilerplate into the PDF, instead of
having the .in file replicate this.
A simple example XFA .in file, called xfa_example.in has been added as a
template for future files to follow.
Finally a run_xfa_tests.py has been added for executing all of the tests
in testing/resources/xfa, which from what I can tell are not executed any
other way. All of the existing PDFs in that directory are currently
suppressed.
BUG=pdfium:1008
Change-Id: Ie055b6640969ce8291b4c96b401ebf6887dfa0c0
Reviewed-on: https://pdfium-review.googlesource.com/27631
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
-rw-r--r-- | testing/SUPPRESSIONS | 15 | ||||
-rw-r--r-- | testing/resources/xfa/xfa_example.in | 71 | ||||
-rw-r--r-- | testing/resources/xfa/xfa_example_expected.pdf.0.png | bin | 0 -> 4806 bytes | |||
-rwxr-xr-x | testing/tools/fixup_pdf_template.py | 191 | ||||
-rwxr-xr-x | testing/tools/run_xfa_tests.py | 16 |
5 files changed, 288 insertions, 5 deletions
diff --git a/testing/SUPPRESSIONS b/testing/SUPPRESSIONS index 1edc158161..317f370b31 100644 --- a/testing/SUPPRESSIONS +++ b/testing/SUPPRESSIONS @@ -321,3 +321,18 @@ bug_735912.in * * noxfa # bug_492.in * nov8 * +# +# XFA Tests +# +# TODO(rharrison): Create expectations for existing files. +barcode_test.pdf * * * +dynamic_list_box_allow_multiple_selection.pdf * * * +dynamic_password_field_background_fill.pdf * * * +dynamic_table_color_and_width.pdf * * * +email_recommended.pdf * * * +resolve_nodes.pdf * * * +standard_symbols.pdf * * * +static_list_box_caption.pdf * * * +static_password_field_rotate.pdf * * * +xfa_node_caption.pdf * * * + diff --git a/testing/resources/xfa/xfa_example.in b/testing/resources/xfa/xfa_example.in new file mode 100644 index 0000000000..d8be96f305 --- /dev/null +++ b/testing/resources/xfa/xfa_example.in @@ -0,0 +1,71 @@ +{{header}} + +%% Original object ID: 24 0 +{{object 1 0}} +<< + /AcroForm 2 0 R + /Extensions << + /ADBE << + /BaseVersion /1.7 + /ExtensionLevel 8 + >> + >> + /NeedsRendering true + /Type /Catalog +>> +endobj + +%% Original object ID: 32 0 +{{object 2 0}} +<< + /XFA [ + (preamble) + 3 0 R + (config) + 4 0 R + (template) + 5 0 R + (localeSet) + 6 0 R + (postamble) + 7 0 R + ] +>> +endobj + +{{xfapreamble 3 0}} +{{xfaconfig 4 0}} + +{{object 5 0}} +<< + {{streamlen}} +>> +stream +<template xmlns="http://www.xfa.org/schema/xfa-template/3.3/"> + <subform name="form1" layout="tb" locale="zh_CN" restoreState="auto"> + <pageSet> + <pageArea name="Page1" id="Page1"> + <contentArea x="0.25in" y="0.25in" w="7.75in" h="11.25in"/> + <medium stock="default" short="612pt" long="792pt"/> + </pageArea> + </pageSet> + <subform w="576pt" h="756pt" name="Page1"> + <draw name="HelloWorld" y="0.5in" x="0.5in" w="5in" h="2in"> + <value> + <text>Hello, world.</text> + </value> + </draw> + </subform> + </subform> +</template> +endstream +endobj + +{{xfalocale 6 0}} + +{{xfapostamble 7 0}} + +{{xref}} +{{trailer}} +{{startxref}} +%%EOF
\ No newline at end of file diff --git a/testing/resources/xfa/xfa_example_expected.pdf.0.png b/testing/resources/xfa/xfa_example_expected.pdf.0.png Binary files differnew file mode 100644 index 0000000000..9a682f7186 --- /dev/null +++ b/testing/resources/xfa/xfa_example_expected.pdf.0.png diff --git a/testing/tools/fixup_pdf_template.py b/testing/tools/fixup_pdf_template.py index 19f75e0263..fed0ed8e0a 100755 --- a/testing/tools/fixup_pdf_template.py +++ b/testing/tools/fixup_pdf_template.py @@ -8,12 +8,20 @@ There are several places in a PDF file where byte-offsets are required. This script replaces {{name}}-style variables in the input with calculated results - {{header}} - expands to the header comment required for PDF files. - {{xref}} - expands to a generated xref table, noting the offset. - {{trailer}} - expands to a standard trailer with "1 0 R" as the /Root. - {{startxref} - expands to a startxref directive followed by correct offset. + {{header}} - expands to the header comment required for PDF files. + {{xref}} - expands to a generated xref table, noting the offset. + {{trailer}} - expands to a standard trailer with "1 0 R" as the /Root. + {{startxref} - expands to a startxref directive followed by correct offset. {{object x y}} - expands to |x y obj| declaration, noting the offset. - {{streamlen}} - expands to |/Length n|. + {{streamlen}} - expands to |/Length n|. + {{xfapreamble x y}} - expands to an object |x y obj| containing a XML preamble + to be used in XFA docs. + {{xfaconfig x y}} - expands to an object |x y obj| containing a config XML + block to be used in XFA docs. + {{xfalocale x y}} - expands to an object |x y obj| containing a locale XML + block to be used in XFA docs. + {{xfapostamble x y}} - expands to an object |x y obj| containing a XML + posteamble to be used in XFA docs. """ import cStringIO @@ -51,6 +59,154 @@ class TemplateProcessor: STREAMLEN_TOKEN = '{{streamlen}}' STREAMLEN_REPLACEMENT = '/Length %d' + XFAPREAMBLE_PATTERN = r'\{\{xfapreamble\s+(\d+)\s+(\d+)\}\}' + XFAPREAMBLE_REPLACEMENT = '%d %d obj\n<<\n /Length %d\n>>\nstream\n%s\nendstream\nendobj\n' + XFAPREAMBLE_STREAM = '<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/" timeStamp="2018-02-23T21:37:11Z" uuid="21482798-7bf0-40a4-bc5d-3cefdccf32b5">' + + XFAPOSTAMBLE_PATTERN = r'\{\{xfapostamble\s+(\d+)\s+(\d+)\}\}' + XFAPOSTAMBLE_REPLACEMENT = '%d %d obj\n<<\n /Length %d\n>>\nstream\n%s\nendstream\nendobj\n' + XFAPOSTAMBLE_STREAM = '</xdp:xdp>' + + XFACONFIG_PATTERN = r'\{\{xfaconfig\s+(\d+)\s+(\d+)\}\}' + XFACONFIG_REPLACEMENT = '%d %d obj\n<<\n /Length %d\n>>\nstream\n%s\nendstream\nendobj\n' + XFACONFIG_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>''' + + XFALOCALE_PATTERN = r'\{\{xfalocale\s+(\d+)\s+(\d+)\}\}' + XFALOCALE_REPLACEMENT = '%d %d obj\n<<\n /Length %d\n>>\nstream\n%s\nendstream\nendobj\n' + XFALOCALE_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>''' + def __init__(self): self.streamlen_state = StreamLenState.START self.streamlens = [] @@ -109,10 +265,35 @@ class TemplateProcessor: if match: self.insert_xref_entry(int(match.group(1)), int(match.group(2))) line = re.sub(self.OBJECT_PATTERN, self.OBJECT_REPLACEMENT, line) + line = self.replace_xfa_tag(line, + self.XFAPREAMBLE_PATTERN, + self.XFAPREAMBLE_REPLACEMENT, + self.XFAPREAMBLE_STREAM) + line = self.replace_xfa_tag(line, + self.XFACONFIG_PATTERN, + self.XFACONFIG_REPLACEMENT, + self.XFACONFIG_STREAM) + line = self.replace_xfa_tag(line, + self.XFALOCALE_PATTERN, + self.XFALOCALE_REPLACEMENT, + self.XFALOCALE_STREAM) + line = self.replace_xfa_tag(line, + self.XFAPOSTAMBLE_PATTERN, + self.XFAPOSTAMBLE_REPLACEMENT, + self.XFAPOSTAMBLE_STREAM) self.offset += len(line) return line + def replace_xfa_tag(self, line, pattern, replacement, stream): + match = re.match(pattern, line) + if match: + x = int(match.group(1)) + y = int(match.group(2)) + self.insert_xref_entry(x, y) + line = replacement % (x, y, len(stream), stream) + return line + def expand_file(input_path, output_path): processor = TemplateProcessor() diff --git a/testing/tools/run_xfa_tests.py b/testing/tools/run_xfa_tests.py new file mode 100755 index 0000000000..6647cfd939 --- /dev/null +++ b/testing/tools/run_xfa_tests.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python +# Copyright 2018 The PDFium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import sys + +import test_runner + +def main(): + runner = test_runner.TestRunner('xfa') + runner.SetEnforceExpectedImages(True) + return runner.Run() + +if __name__ == '__main__': + sys.exit(main()) |