copy-annotations.test 9.59 KB
#!/usr/bin/env perl
require 5.008;
use warnings;
use strict;

unshift(@INC, '.');
require qpdf_test_helpers;

chdir("qpdf") or die "chdir testdir failed: $!\n";

require TestDriver;

cleanup();

my $td = new TestDriver('copy-annotations');

my $n_tests = 48;

$td->runtest("complex copy annotations",
             {$td->COMMAND =>
                  "qpdf --qdf --static-id --no-original-object-ids" .
                  " fxo-red.pdf --overlay form-fields-and-annotations.pdf" .
                  " --repeat=1 -- a.pdf"},
             {$td->STRING => "", $td->EXIT_STATUS => 0},
             $td->NORMALIZE_NEWLINES);
$td->runtest("check output",
             {$td->FILE => "a.pdf"},
             {$td->FILE => "overlay-copy-annotations.pdf"});

foreach my $page (1, 2, 5, 6)
{
    $td->runtest("copy annotations single page ($page)",
                 {$td->COMMAND =>
                      "qpdf --qdf --static-id --no-original-object-ids" .
                      " --pages . $page --" .
                      " fxo-red.pdf --overlay minimal.pdf --repeat=1 --" .
                      " --overlay form-fields-and-annotations.pdf" .
                      " --repeat=1 -- a.pdf"},
                 {$td->STRING => "", $td->EXIT_STATUS => 0},
                 $td->NORMALIZE_NEWLINES);
    $td->runtest("check output",
                 {$td->FILE => "a.pdf"},
                 {$td->FILE => "overlay-copy-annotations-p$page.pdf"});
}

$td->runtest("copy annotations no acroform from foreign file",
             {$td->COMMAND =>
                  "qpdf --qdf --static-id --no-original-object-ids" .
                   " annotations-no-acroform.pdf --pages . 1,1 -- a.pdf"},
             {$td->STRING => "", $td->EXIT_STATUS => 0},
             $td->NORMALIZE_NEWLINES);

$td->runtest("get json no acroform",
             {$td->COMMAND =>
                  "qpdf --json annotations-no-acroform.pdf"},
             {$td->FILE => "annotations-no-acroform.json",
                  $td->EXIT_STATUS => 0},
             $td->NORMALIZE_NEWLINES);

$td->runtest("check output",
             {$td->FILE => "a.pdf"},
             {$td->FILE => "annotations-same-file.out.pdf"});

# PDF:Table 164:P
$td->runtest("copy annotations with /P entry",
             {$td->COMMAND =>
                  "qpdf --qdf --static-id --no-original-object-ids" .
                   " annotations-no-acroform-with-p.pdf --pages . 1,1 -- a.pdf"},
             {$td->STRING => "", $td->EXIT_STATUS => 0},
             $td->NORMALIZE_NEWLINES);

$td->runtest("check output",
             {$td->FILE => "a.pdf"},
             {$td->FILE => "annotations-no-acroform-with-p.out.pdf"},
             $td->EXPECT_FAILURE);

$td->runtest("copy annotations no acroform from foreign file",
             {$td->COMMAND =>
                  "qpdf --qdf --static-id --no-original-object-ids minimal.pdf" .
                   " --pages annotations-no-acroform.pdf 1,1 -- a.pdf"},
             {$td->STRING => "", $td->EXIT_STATUS => 0},
             $td->NORMALIZE_NEWLINES);

$td->runtest("check output",
             {$td->FILE => "a.pdf"},
             {$td->FILE => "annotations-foreign-file.out.pdf"});



foreach my $d ([1, "appearances-1.pdf"],
               [2, "appearances-1-rotated.pdf"])
{
    my ($n, $file1) = @$d;
    $td->runtest("copy/transfer with defaults",
                 {$td->COMMAND => "test_driver 80 $file1 minimal.pdf"},
                 {$td->STRING => "test 80 done\n", $td->EXIT_STATUS => 0},
                 $td->NORMALIZE_NEWLINES);
    $td->runtest("check output A",
                 {$td->FILE => "a.pdf"},
                 {$td->FILE => "test80a$n.pdf"});
    $td->runtest("check output B",
                 {$td->FILE => "b.pdf"},
                 {$td->FILE => "test80b$n.pdf"});
}

$td->runtest("page extraction with fields",
             {$td->COMMAND =>
                  "qpdf --static-id --empty" .
                  " --pages fields-two-pages.pdf -- a.pdf"},
             {$td->STRING => "", $td->EXIT_STATUS => 0},
             $td->NORMALIZE_NEWLINES);
$td->runtest("check output",
             {$td->FILE => "a.pdf"},
             {$td->FILE => "fields-pages-out.pdf"});
$td->runtest("page splitting with fields",
             {$td->COMMAND =>
                  "qpdf --static-id" .
                  " --split-pages fields-two-pages.pdf split-out.pdf"},
             {$td->STRING => "", $td->EXIT_STATUS => 0},
             $td->NORMALIZE_NEWLINES);
for (my $i = 1; $i <= 2; ++$i)
{
    $td->runtest("check output",
                 {$td->FILE => "split-out-$i.pdf"},
                 {$td->FILE => "fields-split-$i.pdf"});
}
$td->runtest("keeping some fields",
             {$td->COMMAND =>
                  "qpdf --static-id fields-two-pages.pdf" .
                  " --pages . 1 minimal.pdf -- a.pdf"},
             {$td->STRING => "", $td->EXIT_STATUS => 0},
             $td->NORMALIZE_NEWLINES);
$td->runtest("check output",
             {$td->COMMAND => "qpdf-test-compare a.pdf kept-some-fields.pdf"},
             {$td->FILE => "kept-some-fields.pdf", $td->EXIT_STATUS => 0});
$td->runtest("not keeping any fields",
             {$td->COMMAND =>
                  "qpdf --static-id kept-some-fields.pdf" .
                  " --pages . 2 -- a.pdf"},
             {$td->STRING => "", $td->EXIT_STATUS => 0},
             $td->NORMALIZE_NEWLINES);
$td->runtest("check output",
             {$td->FILE => "a.pdf"},
             {$td->FILE => "kept-no-fields.pdf"});
$td->runtest("other file first",
             {$td->COMMAND =>
                  "qpdf --qdf --no-original-object-ids" .
                  " --static-id fields-two-pages.pdf" .
                  " --pages ./fields-two-pages.pdf . 1 -- a.pdf"},
             {$td->STRING => "", $td->EXIT_STATUS => 0},
             $td->NORMALIZE_NEWLINES);
$td->runtest("check output",
             {$td->FILE => "a.pdf"},
             {$td->FILE => "other-file-first.pdf"});

$td->runtest("field conflict resolution",
             {$td->COMMAND =>
                  "qpdf form-fields-and-annotations.pdf" .
                  " --pages . 1,1 ./form-fields-and-annotations.pdf 1,1 --" .
                  " --qdf --static-id --no-original-object-ids a.pdf"},
             {$td->STRING => "", $td->EXIT_STATUS => 0},
             $td->NORMALIZE_NEWLINES);
$td->runtest("check output",
             {$td->FILE => "a.pdf"},
             {$td->FILE => "resolved-field-conflicts.pdf"});

# field-resource-conflict.pdf was crafted so that an appearance stream
# had an existing resource that it actually referenced in the
# appearance stream whose name, /F1_1, clashed with the result of
# resolving conflicts in /DR. It's a crazy corner case, but it if it
# ever happened, it would be really hard to track down, and it could
# arise through multiple passes through qpdf with intervening edits.
$td->runtest("appearance stream resource conflict",
             {$td->COMMAND =>
                  "qpdf field-resource-conflict.pdf" .
                  " --pages . 1,1 ./field-resource-conflict.pdf --" .
                  " --qdf --static-id --no-original-object-ids a.pdf"},
             {$td->STRING => "", $td->EXIT_STATUS => 0},
             $td->NORMALIZE_NEWLINES);
$td->runtest("check output",
             {$td->FILE => "a.pdf"},
             {$td->FILE => "resolved-appearance-conflicts.pdf"});

$td->runtest("resource conflicts + flatten",
             {$td->COMMAND =>
                  "qpdf field-resource-conflict.pdf" .
                  " --pages . 1,1 ./field-resource-conflict.pdf --" .
                  " --generate-appearances --flatten-annotations=all" .
                  " --qdf --static-id --no-original-object-ids a.pdf"},
             {$td->STRING => "", $td->EXIT_STATUS => 0},
             $td->NORMALIZE_NEWLINES);
$td->runtest("check output",
             {$td->FILE => "a.pdf"},
             {$td->FILE => "resolved-appearance-conflicts-generate.pdf"});

$td->runtest("default DA/Q",
             {$td->COMMAND =>
                  "qpdf form-fields-and-annotations.pdf" .
                  " --pages . default-da-q.pdf --" .
                  " --qdf --static-id --no-original-object-ids" .
                  " --generate-appearances a.pdf"},
             {$td->STRING => "", $td->EXIT_STATUS => 0},
             $td->NORMALIZE_NEWLINES);
$td->runtest("check output",
             {$td->FILE => "a.pdf"},
             {$td->FILE => "default-da-q-out.pdf"});

$td->runtest("DA/appearance stream errors",
             {$td->COMMAND =>
                  "qpdf field-parse-errors.pdf" .
                  " --pages ./field-parse-errors.pdf --" .
                  " --qdf --static-id --no-original-object-ids a.pdf"},
             {$td->FILE => "field-parse-errors.out", $td->EXIT_STATUS => 3},
             $td->NORMALIZE_NEWLINES);
$td->runtest("check output",
             {$td->FILE => "a.pdf"},
             {$td->FILE => "field-parse-errors-out.pdf"});

$td->runtest("Direct DR and annotations",
             {$td->COMMAND =>
                  "qpdf direct-dr.pdf --split-pages" .
                  " --qdf --static-id --no-original-object-ids" .
                  " split-out.pdf"},
             {$td->STRING => "", $td->EXIT_STATUS => 0},
             $td->NORMALIZE_NEWLINES);
$td->runtest("check output",
             {$td->FILE => "split-out-1.pdf"},
             {$td->FILE => "direct-dr-out.pdf"});

$td->runtest("Foreign link annotations",
             {$td->COMMAND =>
                  "qpdf --empty  --pages  link-annots.pdf -- --qdf --static-id --no-original-object-ids a.pdf"},
             {$td->STRING => "", $td->EXIT_STATUS => 0},
             $td->NORMALIZE_NEWLINES);
$td->runtest("check output",
             {$td->FILE => "link-annots.pdf"},
             {$td->FILE => "a.pdf"});

cleanup();
$td->report($n_tests);