placeFormXObject: allow control of shrink/expand (fixes #409)

This commit is contained in:
Jay Berkenbilt 2020-04-03 16:48:20 -04:00
parent b76b73b229
commit 4f3b89991b
11 changed files with 2016 additions and 17 deletions

View File

@ -1,3 +1,11 @@
2020-04-03 Jay Berkenbilt <ejb@ql.org>
* Add two extra optional arguments to
QPDFPageObjectHelper::placeFormXObject to control whether the
placed item is allowed to be shrunk or expanded to fit within or
maximally fill the destination rectangle. Prior to this change,
placeFormXObject might shrink it but would never expand it.
2020-04-02 Jay Berkenbilt <ejb@ql.org>
* Add method QPDFObjectHandle::unsafeShallowCopy for copying only

View File

@ -209,27 +209,33 @@ class QPDFPageObjectHelper: public QPDFObjectHelper
// Return content stream text that will place the given form
// XObject (fo) using the resource name "name" on this page
// centered within the given rectangle and shrunk to fit if
// necessary. If invert_transformations is true, the effect of any
// rotation (/Rotate) and scaling (/UserUnit) applied to the
// current page will be inverted in the form XObject placement.
// This will cause the form XObject's absolute orientation to be
// preserved. You could overlay one page on another by calling
// getFormXObjectForPage on the original page,
// QPDFObjectHandle::getUniqueResourceName on the destination
// page's Resources dictionary to generate a name for the
// resulting object, and calling placeFormXObject on the
// centered within the given rectangle. If invert_transformations
// is true, the effect of any rotation (/Rotate) and scaling
// (/UserUnit) applied to the current page will be inverted in the
// form XObject placement. This will cause the form XObject's
// absolute orientation to be preserved. You could overlay one
// page on another by calling getFormXObjectForPage on the
// original page, QPDFObjectHandle::getUniqueResourceName on the
// destination page's Resources dictionary to generate a name for
// the resulting object, and calling placeFormXObject on the
// destination page. Then insert the new fo (or, if it comes from
// a different file, the result of calling copyForeignObject on
// it) into the resources dictionary using name, and append or
// prepend the content to the page's content streams. See the
// overlay/underlay code in qpdf.cc or
// examples/pdf-overlay-page.cc for an example.
// examples/pdf-overlay-page.cc for an example. From qpdf 10.0.0,
// the allow_shrink and allow_expand parameters control whether
// the form XObject is allowed to be shrunk or expanded to stay
// within or maximally fill the destination rectangle. The default
// values are for backward compatibility with the pre-10.0.0
// behavior.
QPDF_DLL
std::string placeFormXObject(
QPDFObjectHandle fo, std::string const& name,
QPDFObjectHandle::Rectangle rect,
bool invert_transformations = true);
bool invert_transformations = true,
bool allow_shrink = true,
bool allow_expand = false);
private:
static void

View File

@ -724,11 +724,12 @@ std::string
QPDFPageObjectHelper::placeFormXObject(
QPDFObjectHandle fo, std::string const& name,
QPDFObjectHandle::Rectangle rect,
bool invert_transformations)
bool invert_transformations,
bool allow_shrink, bool allow_expand)
{
// Calculate the transformation matrix that will place the given
// form XObject fully inside the given rectangle, shrinking and
// centering if needed.
// form XObject fully inside the given rectangle, center and
// shrinking or expanding as needed if requested.
// When rendering a form XObject, the transformation in the
// graphics state (cm) is applied first (of course -- when it is
@ -797,7 +798,17 @@ QPDFPageObjectHelper::placeFormXObject(
double scale = (xscale < yscale ? xscale : yscale);
if (scale > 1.0)
{
scale = 1.0;
if (! allow_expand)
{
scale = 1.0;
}
}
else if (scale < 1.0)
{
if (! allow_shrink)
{
scale = 1.0;
}
}
// Step 2: figure out what translation is required to get the

View File

@ -412,7 +412,7 @@ foreach my $i (@choice_values)
show_ntests();
# ----------
$td->notify("--- Form XObject, underlay, overlay ---");
$n_tests += 10;
$n_tests += 18;
$td->runtest("form xobject creation",
{$td->COMMAND => "test_driver 55 fxo-red.pdf"},
@ -433,6 +433,19 @@ foreach (my $i = 56; $i <= 59; ++$i)
{$td->FILE => "a.pdf"},
{$td->FILE => "fx-overlay-$i.pdf"});
}
foreach (my $i = 64; $i <= 67; ++$i)
{
# See comments in test_driver.cc for a verbal description of what
# the resulting files should look like.
$td->runtest("overlay shrink/expand",
{$td->COMMAND =>
"test_driver $i fxo-bigsmall.pdf fxo-smallbig.pdf"},
{$td->STRING => "test $i done\n", $td->EXIT_STATUS => 0},
$td->NORMALIZE_NEWLINES);
$td->runtest("compare files",
{$td->FILE => "a.pdf"},
{$td->FILE => "fx-overlay-$i.pdf"});
}
my @uo_cases = (
'--underlay fxo-green.pdf --repeat=z --to=1-14 --' .

View File

@ -0,0 +1,389 @@
%PDF-1.3
%¿÷¢þ
%QDF-1.0
%% Original object ID: 1 0
1 0 obj
<<
/Pages 2 0 R
/Type /Catalog
>>
endobj
%% Original object ID: 2 0
2 0 obj
<<
/Count 2
/Kids [
3 0 R
4 0 R
]
/Type /Pages
>>
endobj
%% Page 1
%% Original object ID: 3 0
3 0 obj
<<
/Contents [
5 0 R
7 0 R
9 0 R
]
/MediaBox [
0
0
612
792
]
/Parent 2 0 R
/Resources <<
/Font <<
/F1 11 0 R
>>
/ProcSet 12 0 R
/XObject <<
/Fx1 13 0 R
>>
>>
/Type /Page
>>
endobj
%% Page 2
%% Original object ID: 4 0
4 0 obj
<<
/Contents [
15 0 R
17 0 R
19 0 R
]
/MediaBox [
0
0
306
396
]
/Parent 2 0 R
/Resources <<
/Font <<
/F1 21 0 R
>>
/ProcSet 22 0 R
/XObject <<
/Fx1 23 0 R
>>
>>
/Type /Page
>>
endobj
%% Contents for page 1
%% Original object ID: 16 0
5 0 obj
<<
/Length 6 0 R
>>
stream
q
endstream
endobj
6 0 obj
2
endobj
%% Contents for page 1
%% Original object ID: 5 0
7 0 obj
<<
/Length 8 0 R
>>
stream
1 .5 0 RG
1 .5 0 rg
BT
/F1 24 Tf
72 690 Td
(big) Tj
ET
5 w
0 0 612 792 re s
246 396 60 60 re f
endstream
endobj
8 0 obj
101
endobj
%% Contents for page 1
%% Original object ID: 17 0
9 0 obj
<<
/Length 10 0 R
>>
stream
Q
q
1.00000 0.00000 0.00000 1.00000 153.00000 198.00000 cm
/Fx1 Do
Q
endstream
endobj
10 0 obj
70
endobj
%% Original object ID: 7 0
11 0 obj
<<
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
/Name /F1
/Subtype /Type1
/Type /Font
>>
endobj
%% Original object ID: 8 0
12 0 obj
[
/PDF
/Text
]
endobj
%% Original object ID: 13 0
13 0 obj
<<
/BBox [
0
0
306
396
]
/Resources <<
/Font <<
/F1 25 0 R
>>
/ProcSet 26 0 R
>>
/Subtype /Form
/Type /XObject
/Length 14 0 R
>>
stream
.5 0 .5 RG
.5 0 .5 rg
BT
/F1 24 Tf
36 345 Td
(small) Tj
ET
5 w
0 0 306 396 re s
153 198 30 30 re f
endstream
endobj
14 0 obj
105
endobj
%% Contents for page 2
%% Original object ID: 21 0
15 0 obj
<<
/Length 16 0 R
>>
stream
q
endstream
endobj
16 0 obj
2
endobj
%% Contents for page 2
%% Original object ID: 9 0
17 0 obj
<<
/Length 18 0 R
>>
stream
1 .5 0 RG
1 .5 0 rg
BT
/F1 24 Tf
36 345 Td
(small) Tj
ET
5 w
0 0 306 396 re s
153 198 30 30 re f
endstream
endobj
18 0 obj
103
endobj
%% Contents for page 2
%% Original object ID: 22 0
19 0 obj
<<
/Length 20 0 R
>>
stream
Q
q
1.00000 0.00000 0.00000 1.00000 -153.00000 -198.00000 cm
/Fx1 Do
Q
endstream
endobj
20 0 obj
72
endobj
%% Original object ID: 11 0
21 0 obj
<<
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
/Name /F1
/Subtype /Type1
/Type /Font
>>
endobj
%% Original object ID: 12 0
22 0 obj
[
/PDF
/Text
]
endobj
%% Original object ID: 18 0
23 0 obj
<<
/BBox [
0
0
612
792
]
/Resources <<
/Font <<
/F1 27 0 R
>>
/ProcSet 28 0 R
>>
/Subtype /Form
/Type /XObject
/Length 24 0 R
>>
stream
.5 0 .5 RG
.5 0 .5 rg
BT
/F1 24 Tf
72 690 Td
(big) Tj
ET
5 w
0 0 612 792 re s
246 396 60 60 re f
endstream
endobj
24 0 obj
103
endobj
%% Original object ID: 14 0
25 0 obj
<<
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
/Name /F1
/Subtype /Type1
/Type /Font
>>
endobj
%% Original object ID: 15 0
26 0 obj
[
/PDF
/Text
]
endobj
%% Original object ID: 19 0
27 0 obj
<<
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
/Name /F1
/Subtype /Type1
/Type /Font
>>
endobj
%% Original object ID: 20 0
28 0 obj
[
/PDF
/Text
]
endobj
xref
0 29
0000000000 65535 f
0000000052 00000 n
0000000133 00000 n
0000000252 00000 n
0000000554 00000 n
0000000873 00000 n
0000000930 00000 n
0000000998 00000 n
0000001154 00000 n
0000001225 00000 n
0000001351 00000 n
0000001398 00000 n
0000001544 00000 n
0000001608 00000 n
0000001924 00000 n
0000001996 00000 n
0000002055 00000 n
0000002124 00000 n
0000002284 00000 n
0000002356 00000 n
0000002485 00000 n
0000002533 00000 n
0000002680 00000 n
0000002744 00000 n
0000003058 00000 n
0000003107 00000 n
0000003254 00000 n
0000003318 00000 n
0000003465 00000 n
trailer <<
/Root 1 0 R
/Size 29
/ID [<4866f3ccc81fb28dc4a27f0f976ce937><31415926535897932384626433832795>]
>>
startxref
3501
%%EOF

View File

@ -0,0 +1,389 @@
%PDF-1.3
%¿÷¢þ
%QDF-1.0
%% Original object ID: 1 0
1 0 obj
<<
/Pages 2 0 R
/Type /Catalog
>>
endobj
%% Original object ID: 2 0
2 0 obj
<<
/Count 2
/Kids [
3 0 R
4 0 R
]
/Type /Pages
>>
endobj
%% Page 1
%% Original object ID: 3 0
3 0 obj
<<
/Contents [
5 0 R
7 0 R
9 0 R
]
/MediaBox [
0
0
612
792
]
/Parent 2 0 R
/Resources <<
/Font <<
/F1 11 0 R
>>
/ProcSet 12 0 R
/XObject <<
/Fx1 13 0 R
>>
>>
/Type /Page
>>
endobj
%% Page 2
%% Original object ID: 4 0
4 0 obj
<<
/Contents [
15 0 R
17 0 R
19 0 R
]
/MediaBox [
0
0
306
396
]
/Parent 2 0 R
/Resources <<
/Font <<
/F1 21 0 R
>>
/ProcSet 22 0 R
/XObject <<
/Fx1 23 0 R
>>
>>
/Type /Page
>>
endobj
%% Contents for page 1
%% Original object ID: 16 0
5 0 obj
<<
/Length 6 0 R
>>
stream
q
endstream
endobj
6 0 obj
2
endobj
%% Contents for page 1
%% Original object ID: 5 0
7 0 obj
<<
/Length 8 0 R
>>
stream
1 .5 0 RG
1 .5 0 rg
BT
/F1 24 Tf
72 690 Td
(big) Tj
ET
5 w
0 0 612 792 re s
246 396 60 60 re f
endstream
endobj
8 0 obj
101
endobj
%% Contents for page 1
%% Original object ID: 17 0
9 0 obj
<<
/Length 10 0 R
>>
stream
Q
q
1.00000 0.00000 0.00000 1.00000 153.00000 198.00000 cm
/Fx1 Do
Q
endstream
endobj
10 0 obj
70
endobj
%% Original object ID: 7 0
11 0 obj
<<
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
/Name /F1
/Subtype /Type1
/Type /Font
>>
endobj
%% Original object ID: 8 0
12 0 obj
[
/PDF
/Text
]
endobj
%% Original object ID: 13 0
13 0 obj
<<
/BBox [
0
0
306
396
]
/Resources <<
/Font <<
/F1 25 0 R
>>
/ProcSet 26 0 R
>>
/Subtype /Form
/Type /XObject
/Length 14 0 R
>>
stream
.5 0 .5 RG
.5 0 .5 rg
BT
/F1 24 Tf
36 345 Td
(small) Tj
ET
5 w
0 0 306 396 re s
153 198 30 30 re f
endstream
endobj
14 0 obj
105
endobj
%% Contents for page 2
%% Original object ID: 21 0
15 0 obj
<<
/Length 16 0 R
>>
stream
q
endstream
endobj
16 0 obj
2
endobj
%% Contents for page 2
%% Original object ID: 9 0
17 0 obj
<<
/Length 18 0 R
>>
stream
1 .5 0 RG
1 .5 0 rg
BT
/F1 24 Tf
36 345 Td
(small) Tj
ET
5 w
0 0 306 396 re s
153 198 30 30 re f
endstream
endobj
18 0 obj
103
endobj
%% Contents for page 2
%% Original object ID: 22 0
19 0 obj
<<
/Length 20 0 R
>>
stream
Q
q
0.50000 0.00000 0.00000 0.50000 0.00000 0.00000 cm
/Fx1 Do
Q
endstream
endobj
20 0 obj
66
endobj
%% Original object ID: 11 0
21 0 obj
<<
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
/Name /F1
/Subtype /Type1
/Type /Font
>>
endobj
%% Original object ID: 12 0
22 0 obj
[
/PDF
/Text
]
endobj
%% Original object ID: 18 0
23 0 obj
<<
/BBox [
0
0
612
792
]
/Resources <<
/Font <<
/F1 27 0 R
>>
/ProcSet 28 0 R
>>
/Subtype /Form
/Type /XObject
/Length 24 0 R
>>
stream
.5 0 .5 RG
.5 0 .5 rg
BT
/F1 24 Tf
72 690 Td
(big) Tj
ET
5 w
0 0 612 792 re s
246 396 60 60 re f
endstream
endobj
24 0 obj
103
endobj
%% Original object ID: 14 0
25 0 obj
<<
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
/Name /F1
/Subtype /Type1
/Type /Font
>>
endobj
%% Original object ID: 15 0
26 0 obj
[
/PDF
/Text
]
endobj
%% Original object ID: 19 0
27 0 obj
<<
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
/Name /F1
/Subtype /Type1
/Type /Font
>>
endobj
%% Original object ID: 20 0
28 0 obj
[
/PDF
/Text
]
endobj
xref
0 29
0000000000 65535 f
0000000052 00000 n
0000000133 00000 n
0000000252 00000 n
0000000554 00000 n
0000000873 00000 n
0000000930 00000 n
0000000998 00000 n
0000001154 00000 n
0000001225 00000 n
0000001351 00000 n
0000001398 00000 n
0000001544 00000 n
0000001608 00000 n
0000001924 00000 n
0000001996 00000 n
0000002055 00000 n
0000002124 00000 n
0000002284 00000 n
0000002356 00000 n
0000002479 00000 n
0000002527 00000 n
0000002674 00000 n
0000002738 00000 n
0000003052 00000 n
0000003101 00000 n
0000003248 00000 n
0000003312 00000 n
0000003459 00000 n
trailer <<
/Root 1 0 R
/Size 29
/ID [<4866f3ccc81fb28dc4a27f0f976ce937><31415926535897932384626433832795>]
>>
startxref
3495
%%EOF

View File

@ -0,0 +1,389 @@
%PDF-1.3
%¿÷¢þ
%QDF-1.0
%% Original object ID: 1 0
1 0 obj
<<
/Pages 2 0 R
/Type /Catalog
>>
endobj
%% Original object ID: 2 0
2 0 obj
<<
/Count 2
/Kids [
3 0 R
4 0 R
]
/Type /Pages
>>
endobj
%% Page 1
%% Original object ID: 3 0
3 0 obj
<<
/Contents [
5 0 R
7 0 R
9 0 R
]
/MediaBox [
0
0
612
792
]
/Parent 2 0 R
/Resources <<
/Font <<
/F1 11 0 R
>>
/ProcSet 12 0 R
/XObject <<
/Fx1 13 0 R
>>
>>
/Type /Page
>>
endobj
%% Page 2
%% Original object ID: 4 0
4 0 obj
<<
/Contents [
15 0 R
17 0 R
19 0 R
]
/MediaBox [
0
0
306
396
]
/Parent 2 0 R
/Resources <<
/Font <<
/F1 21 0 R
>>
/ProcSet 22 0 R
/XObject <<
/Fx1 23 0 R
>>
>>
/Type /Page
>>
endobj
%% Contents for page 1
%% Original object ID: 16 0
5 0 obj
<<
/Length 6 0 R
>>
stream
q
endstream
endobj
6 0 obj
2
endobj
%% Contents for page 1
%% Original object ID: 5 0
7 0 obj
<<
/Length 8 0 R
>>
stream
1 .5 0 RG
1 .5 0 rg
BT
/F1 24 Tf
72 690 Td
(big) Tj
ET
5 w
0 0 612 792 re s
246 396 60 60 re f
endstream
endobj
8 0 obj
101
endobj
%% Contents for page 1
%% Original object ID: 17 0
9 0 obj
<<
/Length 10 0 R
>>
stream
Q
q
2.00000 0.00000 0.00000 2.00000 0.00000 0.00000 cm
/Fx1 Do
Q
endstream
endobj
10 0 obj
66
endobj
%% Original object ID: 7 0
11 0 obj
<<
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
/Name /F1
/Subtype /Type1
/Type /Font
>>
endobj
%% Original object ID: 8 0
12 0 obj
[
/PDF
/Text
]
endobj
%% Original object ID: 13 0
13 0 obj
<<
/BBox [
0
0
306
396
]
/Resources <<
/Font <<
/F1 25 0 R
>>
/ProcSet 26 0 R
>>
/Subtype /Form
/Type /XObject
/Length 14 0 R
>>
stream
.5 0 .5 RG
.5 0 .5 rg
BT
/F1 24 Tf
36 345 Td
(small) Tj
ET
5 w
0 0 306 396 re s
153 198 30 30 re f
endstream
endobj
14 0 obj
105
endobj
%% Contents for page 2
%% Original object ID: 21 0
15 0 obj
<<
/Length 16 0 R
>>
stream
q
endstream
endobj
16 0 obj
2
endobj
%% Contents for page 2
%% Original object ID: 9 0
17 0 obj
<<
/Length 18 0 R
>>
stream
1 .5 0 RG
1 .5 0 rg
BT
/F1 24 Tf
36 345 Td
(small) Tj
ET
5 w
0 0 306 396 re s
153 198 30 30 re f
endstream
endobj
18 0 obj
103
endobj
%% Contents for page 2
%% Original object ID: 22 0
19 0 obj
<<
/Length 20 0 R
>>
stream
Q
q
1.00000 0.00000 0.00000 1.00000 -153.00000 -198.00000 cm
/Fx1 Do
Q
endstream
endobj
20 0 obj
72
endobj
%% Original object ID: 11 0
21 0 obj
<<
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
/Name /F1
/Subtype /Type1
/Type /Font
>>
endobj
%% Original object ID: 12 0
22 0 obj
[
/PDF
/Text
]
endobj
%% Original object ID: 18 0
23 0 obj
<<
/BBox [
0
0
612
792
]
/Resources <<
/Font <<
/F1 27 0 R
>>
/ProcSet 28 0 R
>>
/Subtype /Form
/Type /XObject
/Length 24 0 R
>>
stream
.5 0 .5 RG
.5 0 .5 rg
BT
/F1 24 Tf
72 690 Td
(big) Tj
ET
5 w
0 0 612 792 re s
246 396 60 60 re f
endstream
endobj
24 0 obj
103
endobj
%% Original object ID: 14 0
25 0 obj
<<
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
/Name /F1
/Subtype /Type1
/Type /Font
>>
endobj
%% Original object ID: 15 0
26 0 obj
[
/PDF
/Text
]
endobj
%% Original object ID: 19 0
27 0 obj
<<
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
/Name /F1
/Subtype /Type1
/Type /Font
>>
endobj
%% Original object ID: 20 0
28 0 obj
[
/PDF
/Text
]
endobj
xref
0 29
0000000000 65535 f
0000000052 00000 n
0000000133 00000 n
0000000252 00000 n
0000000554 00000 n
0000000873 00000 n
0000000930 00000 n
0000000998 00000 n
0000001154 00000 n
0000001225 00000 n
0000001347 00000 n
0000001394 00000 n
0000001540 00000 n
0000001604 00000 n
0000001920 00000 n
0000001992 00000 n
0000002051 00000 n
0000002120 00000 n
0000002280 00000 n
0000002352 00000 n
0000002481 00000 n
0000002529 00000 n
0000002676 00000 n
0000002740 00000 n
0000003054 00000 n
0000003103 00000 n
0000003250 00000 n
0000003314 00000 n
0000003461 00000 n
trailer <<
/Root 1 0 R
/Size 29
/ID [<4866f3ccc81fb28dc4a27f0f976ce937><31415926535897932384626433832795>]
>>
startxref
3497
%%EOF

View File

@ -0,0 +1,389 @@
%PDF-1.3
%¿÷¢þ
%QDF-1.0
%% Original object ID: 1 0
1 0 obj
<<
/Pages 2 0 R
/Type /Catalog
>>
endobj
%% Original object ID: 2 0
2 0 obj
<<
/Count 2
/Kids [
3 0 R
4 0 R
]
/Type /Pages
>>
endobj
%% Page 1
%% Original object ID: 3 0
3 0 obj
<<
/Contents [
5 0 R
7 0 R
9 0 R
]
/MediaBox [
0
0
612
792
]
/Parent 2 0 R
/Resources <<
/Font <<
/F1 11 0 R
>>
/ProcSet 12 0 R
/XObject <<
/Fx1 13 0 R
>>
>>
/Type /Page
>>
endobj
%% Page 2
%% Original object ID: 4 0
4 0 obj
<<
/Contents [
15 0 R
17 0 R
19 0 R
]
/MediaBox [
0
0
306
396
]
/Parent 2 0 R
/Resources <<
/Font <<
/F1 21 0 R
>>
/ProcSet 22 0 R
/XObject <<
/Fx1 23 0 R
>>
>>
/Type /Page
>>
endobj
%% Contents for page 1
%% Original object ID: 16 0
5 0 obj
<<
/Length 6 0 R
>>
stream
q
endstream
endobj
6 0 obj
2
endobj
%% Contents for page 1
%% Original object ID: 5 0
7 0 obj
<<
/Length 8 0 R
>>
stream
1 .5 0 RG
1 .5 0 rg
BT
/F1 24 Tf
72 690 Td
(big) Tj
ET
5 w
0 0 612 792 re s
246 396 60 60 re f
endstream
endobj
8 0 obj
101
endobj
%% Contents for page 1
%% Original object ID: 17 0
9 0 obj
<<
/Length 10 0 R
>>
stream
Q
q
2.00000 0.00000 0.00000 2.00000 0.00000 0.00000 cm
/Fx1 Do
Q
endstream
endobj
10 0 obj
66
endobj
%% Original object ID: 7 0
11 0 obj
<<
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
/Name /F1
/Subtype /Type1
/Type /Font
>>
endobj
%% Original object ID: 8 0
12 0 obj
[
/PDF
/Text
]
endobj
%% Original object ID: 13 0
13 0 obj
<<
/BBox [
0
0
306
396
]
/Resources <<
/Font <<
/F1 25 0 R
>>
/ProcSet 26 0 R
>>
/Subtype /Form
/Type /XObject
/Length 14 0 R
>>
stream
.5 0 .5 RG
.5 0 .5 rg
BT
/F1 24 Tf
36 345 Td
(small) Tj
ET
5 w
0 0 306 396 re s
153 198 30 30 re f
endstream
endobj
14 0 obj
105
endobj
%% Contents for page 2
%% Original object ID: 21 0
15 0 obj
<<
/Length 16 0 R
>>
stream
q
endstream
endobj
16 0 obj
2
endobj
%% Contents for page 2
%% Original object ID: 9 0
17 0 obj
<<
/Length 18 0 R
>>
stream
1 .5 0 RG
1 .5 0 rg
BT
/F1 24 Tf
36 345 Td
(small) Tj
ET
5 w
0 0 306 396 re s
153 198 30 30 re f
endstream
endobj
18 0 obj
103
endobj
%% Contents for page 2
%% Original object ID: 22 0
19 0 obj
<<
/Length 20 0 R
>>
stream
Q
q
0.50000 0.00000 0.00000 0.50000 0.00000 0.00000 cm
/Fx1 Do
Q
endstream
endobj
20 0 obj
66
endobj
%% Original object ID: 11 0
21 0 obj
<<
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
/Name /F1
/Subtype /Type1
/Type /Font
>>
endobj
%% Original object ID: 12 0
22 0 obj
[
/PDF
/Text
]
endobj
%% Original object ID: 18 0
23 0 obj
<<
/BBox [
0
0
612
792
]
/Resources <<
/Font <<
/F1 27 0 R
>>
/ProcSet 28 0 R
>>
/Subtype /Form
/Type /XObject
/Length 24 0 R
>>
stream
.5 0 .5 RG
.5 0 .5 rg
BT
/F1 24 Tf
72 690 Td
(big) Tj
ET
5 w
0 0 612 792 re s
246 396 60 60 re f
endstream
endobj
24 0 obj
103
endobj
%% Original object ID: 14 0
25 0 obj
<<
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
/Name /F1
/Subtype /Type1
/Type /Font
>>
endobj
%% Original object ID: 15 0
26 0 obj
[
/PDF
/Text
]
endobj
%% Original object ID: 19 0
27 0 obj
<<
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
/Name /F1
/Subtype /Type1
/Type /Font
>>
endobj
%% Original object ID: 20 0
28 0 obj
[
/PDF
/Text
]
endobj
xref
0 29
0000000000 65535 f
0000000052 00000 n
0000000133 00000 n
0000000252 00000 n
0000000554 00000 n
0000000873 00000 n
0000000930 00000 n
0000000998 00000 n
0000001154 00000 n
0000001225 00000 n
0000001347 00000 n
0000001394 00000 n
0000001540 00000 n
0000001604 00000 n
0000001920 00000 n
0000001992 00000 n
0000002051 00000 n
0000002120 00000 n
0000002280 00000 n
0000002352 00000 n
0000002475 00000 n
0000002523 00000 n
0000002670 00000 n
0000002734 00000 n
0000003048 00000 n
0000003097 00000 n
0000003244 00000 n
0000003308 00000 n
0000003455 00000 n
trailer <<
/Root 1 0 R
/Size 29
/ID [<4866f3ccc81fb28dc4a27f0f976ce937><31415926535897932384626433832795>]
>>
startxref
3491
%%EOF

View File

@ -0,0 +1,177 @@
%PDF-1.3
%¿÷¢þ
%QDF-1.0
%% Original object ID: 1 0
1 0 obj
<<
/Pages 2 0 R
/Type /Catalog
>>
endobj
%% Original object ID: 2 0
2 0 obj
<<
/Count 2
/Kids [
3 0 R
4 0 R
]
/Type /Pages
>>
endobj
%% Page 1
%% Original object ID: 3 0
3 0 obj
<<
/Contents 5 0 R
/MediaBox [
0
0
612
792
]
/Parent 2 0 R
/Resources <<
/Font <<
/F1 7 0 R
>>
/ProcSet 8 0 R
>>
/Type /Page
>>
endobj
%% Page 2
%% Original object ID: 8 0
4 0 obj
<<
/Contents 9 0 R
/MediaBox [
0
0
306
396
]
/Parent 2 0 R
/Resources <<
/Font <<
/F1 11 0 R
>>
/ProcSet 12 0 R
>>
/Type /Page
>>
endobj
%% Contents for page 1
%% Original object ID: 4 0
5 0 obj
<<
/Length 6 0 R
>>
stream
1 .5 0 RG
1 .5 0 rg
BT
/F1 24 Tf
72 690 Td
(big) Tj
ET
5 w
0 0 612 792 re s
246 396 60 60 re f
endstream
endobj
6 0 obj
101
endobj
%% Original object ID: 6 0
7 0 obj
<<
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
/Name /F1
/Subtype /Type1
/Type /Font
>>
endobj
%% Original object ID: 7 0
8 0 obj
[
/PDF
/Text
]
endobj
%% Contents for page 2
%% Original object ID: 9 0
9 0 obj
<<
/Length 10 0 R
>>
stream
1 .5 0 RG
1 .5 0 rg
BT
/F1 24 Tf
36 345 Td
(small) Tj
ET
5 w
0 0 306 396 re s
153 198 30 30 re f
endstream
endobj
10 0 obj
103
endobj
%% Original object ID: 11 0
11 0 obj
<<
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
/Name /F1
/Subtype /Type1
/Type /Font
>>
endobj
%% Original object ID: 12 0
12 0 obj
[
/PDF
/Text
]
endobj
xref
0 13
0000000000 65535 f
0000000052 00000 n
0000000133 00000 n
0000000252 00000 n
0000000481 00000 n
0000000725 00000 n
0000000881 00000 n
0000000928 00000 n
0000001073 00000 n
0000001158 00000 n
0000001317 00000 n
0000001366 00000 n
0000001513 00000 n
trailer <<
/Root 1 0 R
/Size 13
/ID [<4866f3ccc81fb28dc4a27f0f976ce937><5b260ad1f0f4ccd7895374e61eff0d55>]
>>
startxref
1549
%%EOF

View File

@ -0,0 +1,177 @@
%PDF-1.3
%¿÷¢þ
%QDF-1.0
%% Original object ID: 1 0
1 0 obj
<<
/Pages 2 0 R
/Type /Catalog
>>
endobj
%% Original object ID: 2 0
2 0 obj
<<
/Count 2
/Kids [
3 0 R
4 0 R
]
/Type /Pages
>>
endobj
%% Page 1
%% Original object ID: 3 0
3 0 obj
<<
/Contents 5 0 R
/MediaBox [
0
0
306
396
]
/Parent 2 0 R
/Resources <<
/Font <<
/F1 7 0 R
>>
/ProcSet 8 0 R
>>
/Type /Page
>>
endobj
%% Page 2
%% Original object ID: 8 0
4 0 obj
<<
/Contents 9 0 R
/MediaBox [
0
0
612
792
]
/Parent 2 0 R
/Resources <<
/Font <<
/F1 11 0 R
>>
/ProcSet 12 0 R
>>
/Type /Page
>>
endobj
%% Contents for page 1
%% Original object ID: 4 0
5 0 obj
<<
/Length 6 0 R
>>
stream
.5 0 .5 RG
.5 0 .5 rg
BT
/F1 24 Tf
36 345 Td
(small) Tj
ET
5 w
0 0 306 396 re s
153 198 30 30 re f
endstream
endobj
6 0 obj
105
endobj
%% Original object ID: 6 0
7 0 obj
<<
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
/Name /F1
/Subtype /Type1
/Type /Font
>>
endobj
%% Original object ID: 7 0
8 0 obj
[
/PDF
/Text
]
endobj
%% Contents for page 2
%% Original object ID: 9 0
9 0 obj
<<
/Length 10 0 R
>>
stream
.5 0 .5 RG
.5 0 .5 rg
BT
/F1 24 Tf
72 690 Td
(big) Tj
ET
5 w
0 0 612 792 re s
246 396 60 60 re f
endstream
endobj
10 0 obj
103
endobj
%% Original object ID: 11 0
11 0 obj
<<
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
/Name /F1
/Subtype /Type1
/Type /Font
>>
endobj
%% Original object ID: 12 0
12 0 obj
[
/PDF
/Text
]
endobj
xref
0 13
0000000000 65535 f
0000000052 00000 n
0000000133 00000 n
0000000252 00000 n
0000000481 00000 n
0000000725 00000 n
0000000885 00000 n
0000000932 00000 n
0000001077 00000 n
0000001162 00000 n
0000001321 00000 n
0000001370 00000 n
0000001517 00000 n
trailer <<
/Root 1 0 R
/Size 13
/ID [<4866f3ccc81fb28dc4a27f0f976ce937><7ac42e786a05e6c1a5adfc1c1f33e15c>]
>>
startxref
1553
%%EOF

View File

@ -2116,6 +2116,57 @@ void runtest(int n, char const* filename1, char const* arg2)
w.setOutputFilename("a.pdf");
w.write();
}
else if ((n >= 64) && (n <= 67))
{
// Placing form XObjects: expand, shrink
assert(arg2);
QPDF pdf2;
pdf2.processFile(arg2);
// Overlay file2 on file1.
// 64: allow neither shrink nor shrink
// 65: allow shrink but not expand
// 66: allow expand but not shrink
// 67: allow both shrink and expand
bool allow_shrink = ((n == 65) || (n == 67));
bool allow_expand = ((n == 66) || (n == 67));
std::vector<QPDFPageObjectHelper> pages1 =
QPDFPageDocumentHelper(pdf).getAllPages();
std::vector<QPDFPageObjectHelper> pages2 =
QPDFPageDocumentHelper(pdf2).getAllPages();
size_t npages = (pages1.size() < pages2.size()
? pages1.size() : pages2.size());
for (size_t i = 0; i < npages; ++i)
{
QPDFPageObjectHelper& ph1 = pages1.at(i);
QPDFPageObjectHelper& ph2 = pages2.at(i);
QPDFObjectHandle fo = pdf.copyForeignObject(
ph2.getFormXObjectForPage());
int min_suffix = 1;
QPDFObjectHandle resources = ph1.getAttribute("/Resources", true);
std::string name = resources.getUniqueResourceName(
"/Fx", min_suffix);
std::string content =
ph1.placeFormXObject(
fo, name, ph1.getTrimBox().getArrayAsRectangle(),
false, allow_shrink, allow_expand);
if (! content.empty())
{
resources.mergeResources(
QPDFObjectHandle::parse("<< /XObject << >> >>"));
resources.getKey("/XObject").replaceKey(name, fo);
ph1.addPageContents(
QPDFObjectHandle::newStream(&pdf, "q\n"), true);
ph1.addPageContents(
QPDFObjectHandle::newStream(&pdf, "\nQ\n" + content),
false);
}
}
QPDFWriter w(pdf, "a.pdf");
w.setQDFMode(true);
w.setStaticID(true);
w.write();
}
else
{
throw std::runtime_error(std::string("invalid test ") +