line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package PDF::Imposition::Schema; |
2
|
9
|
|
|
9
|
|
91350
|
use strict; |
|
9
|
|
|
|
|
24
|
|
|
9
|
|
|
|
|
300
|
|
3
|
9
|
|
|
9
|
|
51
|
use warnings; |
|
9
|
|
|
|
|
21
|
|
|
9
|
|
|
|
|
303
|
|
4
|
|
|
|
|
|
|
|
5
|
9
|
|
|
9
|
|
57
|
use File::Basename qw/fileparse/; |
|
9
|
|
|
|
|
31
|
|
|
9
|
|
|
|
|
614
|
|
6
|
9
|
|
|
9
|
|
62
|
use File::Spec; |
|
9
|
|
|
|
|
17
|
|
|
9
|
|
|
|
|
272
|
|
7
|
9
|
|
|
9
|
|
765
|
use PDF::API2; |
|
9
|
|
|
|
|
228672
|
|
|
9
|
|
|
|
|
230
|
|
8
|
9
|
|
|
9
|
|
57
|
use File::Temp (); |
|
9
|
|
|
|
|
19
|
|
|
9
|
|
|
|
|
201
|
|
9
|
9
|
|
|
9
|
|
597
|
use File::Copy; |
|
9
|
|
|
|
|
2397
|
|
|
9
|
|
|
|
|
740
|
|
10
|
9
|
|
|
9
|
|
69
|
use POSIX (); |
|
9
|
|
|
|
|
25
|
|
|
9
|
|
|
|
|
280
|
|
11
|
9
|
|
|
9
|
|
54
|
use Types::Standard qw/Int Bool Num HashRef Str Maybe Object Enum/; |
|
9
|
|
|
|
|
18
|
|
|
9
|
|
|
|
|
102
|
|
12
|
|
|
|
|
|
|
|
13
|
9
|
|
|
9
|
|
13081
|
use Moo::Role; |
|
9
|
|
|
|
|
23
|
|
|
9
|
|
|
|
|
64
|
|
14
|
|
|
|
|
|
|
requires qw(_do_impose); |
15
|
|
|
|
|
|
|
|
16
|
9
|
|
|
9
|
|
3852
|
use constant { DEBUG => $ENV{AMW_DEBUG} }; |
|
9
|
|
|
|
|
23
|
|
|
9
|
|
|
|
|
21057
|
|
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
=head1 NAME |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
PDF::Imposition::Schema - Role for the imposition schemas. |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
=head1 SYNOPSIS |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
This class provides the shared method for real imposition schemas and |
25
|
|
|
|
|
|
|
can't me called directly. |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
Consuming classes must provide a C<_do_impose> method. |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
use PDF::Imposition; |
30
|
|
|
|
|
|
|
my $imposer = PDF::Imposition->new(file => "test.pdf", |
31
|
|
|
|
|
|
|
# either use |
32
|
|
|
|
|
|
|
outfile => "out.pdf", |
33
|
|
|
|
|
|
|
# or suffix |
34
|
|
|
|
|
|
|
suffix => "-2up" |
35
|
|
|
|
|
|
|
); |
36
|
|
|
|
|
|
|
$imposer->impose; |
37
|
|
|
|
|
|
|
or |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
use PDF::Imposition; |
40
|
|
|
|
|
|
|
my $imposer = PDF::Imposition->new(); |
41
|
|
|
|
|
|
|
$imposer->file("test.pdf"); |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
$imposer->outfile("out.pdf"); |
44
|
|
|
|
|
|
|
# or |
45
|
|
|
|
|
|
|
$imposer->suffix("-imp"); |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
$imposer->impose; |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
=head1 METHODS |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
=head2 Read/write accessors |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
All the following accessors accept an argument, which sets the |
54
|
|
|
|
|
|
|
value. |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
=head3 file |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
Unsurprisingly, the input file, which must exist. |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
=cut |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
has _version => (is => 'ro', |
63
|
|
|
|
|
|
|
isa => Str, |
64
|
|
|
|
|
|
|
default => sub { 'PDF::Imposition' }); |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
has file => (is => 'rw', |
67
|
|
|
|
|
|
|
isa => sub { die "$_[0] is not a pdf" unless $_[0] && $_[0] =~ m/\.pdf\z/i }); |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
has _tmp_dir => (is => 'ro', |
70
|
|
|
|
|
|
|
default => sub { File::Temp->newdir(CLEANUP => 1); }); |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
=head3 outfile |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
The destination file of the imposition. You may prefer to use the |
75
|
|
|
|
|
|
|
suffix method below, which takes care of the filename. |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
=head3 suffix |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
The suffix of the file. By default, '-imp', so test.pdf imposed will |
80
|
|
|
|
|
|
|
be saved as 'test-imp.pdf'. If test-imp.pdf already exists, it will be |
81
|
|
|
|
|
|
|
replaced merciless. |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
=cut |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
has outfile => (is => 'rw', |
86
|
|
|
|
|
|
|
isa => sub { die "$_[0] is not a pdf file" |
87
|
|
|
|
|
|
|
unless $_[0] && $_[0] =~ m/\.pdf\z/i }); |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
has suffix => (is => 'rw', |
90
|
|
|
|
|
|
|
isa => Str, |
91
|
|
|
|
|
|
|
default => sub { '-imp' }); |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
=head3 signature($num_or_range) |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
The signature, must be a multiple of the C option |
96
|
|
|
|
|
|
|
(usually 4 or 8), or a range, like the string "20-100". If a range is |
97
|
|
|
|
|
|
|
selected, the signature is determined heuristically to minimize the |
98
|
|
|
|
|
|
|
white pages left on the last signature. The wider the range, the better |
99
|
|
|
|
|
|
|
the results. |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
=cut |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
has signature => (is => 'rw', |
104
|
|
|
|
|
|
|
isa => Str, |
105
|
|
|
|
|
|
|
default => sub { '0' }); |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
=head3 pages_per_sheet |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
The number of logical pages which fit on a sheet, recto-verso. Default |
110
|
|
|
|
|
|
|
to 1. Subclasses usually change this and ignore your option unless |
111
|
|
|
|
|
|
|
otherwise specified. |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
=head3 title |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
The title to set in the PDF meta information. Defaults to the basename. |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
=cut |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
has pages_per_sheet => (is => 'ro', |
120
|
|
|
|
|
|
|
default => sub { 1 }, |
121
|
|
|
|
|
|
|
isa => Enum[qw/1 2 4 8 16 32/]); |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
sub _optimize_signature { |
124
|
475
|
|
|
475
|
|
576806
|
my ($self, $sig, $total_pages) = @_; |
125
|
475
|
100
|
|
|
|
1404
|
unless ($total_pages) { |
126
|
25
|
|
|
|
|
408
|
$total_pages = $self->total_pages; |
127
|
|
|
|
|
|
|
} |
128
|
470
|
50
|
|
|
|
1405
|
return 0 unless $sig; |
129
|
470
|
50
|
|
|
|
1452
|
my $ppsheet = $self->pages_per_sheet or die; |
130
|
470
|
|
|
|
|
735
|
print "# pages per sheet is $ppsheet\n" if DEBUG; |
131
|
470
|
100
|
|
|
|
1710
|
if ($sig =~ m/^[0-9]+$/s) { |
132
|
17
|
50
|
|
|
|
67
|
die "Signature must be a multiple of $ppsheet" if $sig % $ppsheet; |
133
|
17
|
|
|
|
|
144
|
return $sig; |
134
|
|
|
|
|
|
|
} |
135
|
453
|
|
|
|
|
769
|
my ($min, $max); |
136
|
453
|
50
|
|
|
|
2172
|
if ($sig =~ m/^([0-9]+)?-([0-9]+)?$/s) { |
137
|
453
|
|
66
|
|
|
1521
|
$min = $1 || $ppsheet; |
138
|
453
|
|
33
|
|
|
1180
|
$max = $2 || $total_pages; |
139
|
453
|
|
|
|
|
1110
|
$min = $min + (($ppsheet - ($min % $ppsheet)) % $ppsheet); |
140
|
453
|
|
|
|
|
836
|
$max = $max + (($ppsheet - ($max % $ppsheet)) % $ppsheet); |
141
|
453
|
50
|
|
|
|
887
|
die "Bad range $max - $min" unless $max > $min; |
142
|
453
|
50
|
|
|
|
995
|
die "bad min $min" if $min % $ppsheet; |
143
|
453
|
50
|
|
|
|
914
|
die "bad max $max" if $max % $ppsheet; |
144
|
|
|
|
|
|
|
} |
145
|
|
|
|
|
|
|
else { |
146
|
0
|
|
|
|
|
0
|
die "Unrecognized range $sig"; |
147
|
|
|
|
|
|
|
} |
148
|
453
|
|
|
|
|
626
|
my $signature = 0; |
149
|
453
|
|
|
|
|
760
|
my $roundedpages = $total_pages + (($ppsheet - ($total_pages % $ppsheet)) % $ppsheet); |
150
|
453
|
|
|
|
|
619
|
my $needed = $roundedpages - $total_pages; |
151
|
453
|
50
|
|
|
|
844
|
die "Something is wrong" if $roundedpages % $ppsheet; |
152
|
453
|
100
|
|
|
|
935
|
if ($roundedpages <= $min) { |
153
|
90
|
100
|
|
|
|
313
|
wantarray ? return ($roundedpages, $needed) : return $roundedpages; |
154
|
|
|
|
|
|
|
} |
155
|
363
|
|
|
|
|
765
|
$signature = $self->_find_signature($roundedpages, $max); |
156
|
363
|
100
|
|
|
|
693
|
if ($roundedpages > $max) { |
157
|
340
|
|
|
|
|
701
|
while ($signature < $min) { |
158
|
344
|
|
|
|
|
467
|
$roundedpages += $ppsheet; |
159
|
344
|
|
|
|
|
418
|
$needed += $ppsheet; |
160
|
344
|
|
|
|
|
624
|
$signature = $self->_find_signature($roundedpages, $max) |
161
|
|
|
|
|
|
|
} |
162
|
|
|
|
|
|
|
} |
163
|
|
|
|
|
|
|
# warn "Needed $needed blank pages"; |
164
|
363
|
100
|
|
|
|
1257
|
wantarray ? return ($signature, $needed) : return $signature; |
165
|
|
|
|
|
|
|
} |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
sub _find_signature { |
168
|
707
|
|
|
707
|
|
1203
|
my ($self, $num, $max) = @_; |
169
|
707
|
50
|
|
|
|
1430
|
my $ppsheet = $self->pages_per_sheet or die; |
170
|
707
|
50
|
|
|
|
1387
|
die "not a multiple of $ppsheet" if $num % $ppsheet; |
171
|
707
|
50
|
|
|
|
1191
|
die "uh?" unless $num; |
172
|
707
|
|
|
|
|
978
|
my $i = $max; |
173
|
707
|
|
|
|
|
1290
|
while ($i > 0) { |
174
|
|
|
|
|
|
|
# check if the the pagenumber is divisible by the signature |
175
|
|
|
|
|
|
|
# with modulo 0 |
176
|
|
|
|
|
|
|
# warn "trying $i for $num / max $max\n"; |
177
|
5528
|
100
|
|
|
|
8989
|
if (($num % $i) == 0) { |
178
|
707
|
|
|
|
|
1795
|
return $i; |
179
|
|
|
|
|
|
|
} |
180
|
4821
|
|
|
|
|
7526
|
$i -= $ppsheet; |
181
|
|
|
|
|
|
|
} |
182
|
0
|
|
|
|
|
0
|
warn "_find_signature loop ended with no result\n"; |
183
|
|
|
|
|
|
|
} |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
=head2 Internal methods accessors |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
The following methods are used internally but documented for schema's |
190
|
|
|
|
|
|
|
authors. |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
=head3 dimensions |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
Returns an hashref with the original pdf dimensions in points. |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
{ w => 800, h => 600 } |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
=head3 orig_width |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
=head3 orig_height |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
=head3 total_pages |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
Returns the number of pages |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
=cut |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
has dimensions => (is => 'lazy', |
210
|
|
|
|
|
|
|
isa => HashRef[Num]); |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
sub _build_dimensions { |
213
|
63
|
|
|
63
|
|
904
|
my $self = shift; |
214
|
63
|
|
|
|
|
1128
|
my $pdf = $self->in_pdf_obj; |
215
|
63
|
|
|
|
|
896
|
my ($x, $y, $w, $h) = $pdf->openpage(1)->get_mediabox; # use the first page |
216
|
63
|
50
|
|
|
|
304508
|
warn $self->file . "use x-y offset, cannot proceed safely" if ($x + $y); |
217
|
63
|
50
|
33
|
|
|
597
|
die "Cannot retrieve paper dimensions" unless $w && $h; |
218
|
63
|
|
|
|
|
1594
|
my %dimensions = ( |
219
|
|
|
|
|
|
|
w => sprintf('%.2f', $w), |
220
|
|
|
|
|
|
|
h => sprintf('%.2f', $h), |
221
|
|
|
|
|
|
|
); |
222
|
|
|
|
|
|
|
# return a copy |
223
|
63
|
|
|
|
|
1937
|
return \%dimensions; |
224
|
|
|
|
|
|
|
} |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
has total_pages => (is => 'lazy', |
227
|
|
|
|
|
|
|
isa => Int); |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
sub _build_total_pages { |
230
|
96
|
|
|
96
|
|
1531
|
my $self = shift; |
231
|
96
|
|
|
|
|
1636
|
my $count = $self->in_pdf_obj->pages; |
232
|
91
|
|
|
|
|
4022
|
return $count; |
233
|
|
|
|
|
|
|
} |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
sub orig_width { |
236
|
483
|
|
|
483
|
1
|
16000
|
return shift->dimensions->{w}; |
237
|
|
|
|
|
|
|
} |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
sub orig_height { |
240
|
298
|
|
|
298
|
1
|
11759
|
return shift->dimensions->{h}; |
241
|
|
|
|
|
|
|
} |
242
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
=head3 in_pdf_obj |
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
Internal usage. It's the PDF::API2 object used as source. |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
=head3 out_pdf_obj |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
Internal usage. The PDF::API2 object used as output. |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
=cut |
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
has in_pdf_obj => (is => 'lazy', |
256
|
|
|
|
|
|
|
isa => Maybe[Object]); |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
has _in_pdf_object_is_open => (is => 'rw', isa => Bool); |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
sub _build_in_pdf_obj { |
261
|
96
|
|
|
96
|
|
1371
|
my $self = shift; |
262
|
96
|
|
|
|
|
199
|
my $input; |
263
|
96
|
100
|
|
|
|
1676
|
if ($self->file) { |
264
|
91
|
50
|
|
|
|
2032
|
die "File " . $self->file . " doesn't exists" unless -f $self->file; |
265
|
91
|
|
|
|
|
2357
|
print $self->file . ": building in_pdf_obj\n" if DEBUG; |
266
|
91
|
|
|
|
|
2106
|
my ($basename, $path, $suff) = fileparse($self->file, qr{\.pdf}i); |
267
|
91
|
|
|
|
|
5073
|
my $tmpfile = File::Spec->catfile($self->_tmp_dir, |
268
|
|
|
|
|
|
|
$basename . $suff); |
269
|
91
|
50
|
|
|
|
2939
|
copy($self->file, $tmpfile) or die "copy to $tmpfile failed $!"; |
270
|
|
|
|
|
|
|
|
271
|
91
|
|
|
|
|
39977
|
eval { |
272
|
91
|
|
|
|
|
934
|
$input = PDF::API2->open($tmpfile); |
273
|
|
|
|
|
|
|
}; |
274
|
91
|
50
|
|
|
|
4010522
|
if ($@) { |
275
|
0
|
|
|
|
|
0
|
die "Couldn't open $tmpfile $@"; |
276
|
|
|
|
|
|
|
} |
277
|
|
|
|
|
|
|
else { |
278
|
91
|
|
|
|
|
236
|
print "$tmpfile built\n" if DEBUG; |
279
|
|
|
|
|
|
|
} |
280
|
91
|
|
|
|
|
3763
|
$self->_in_pdf_object_is_open(1); |
281
|
|
|
|
|
|
|
} |
282
|
96
|
|
|
|
|
5696
|
return $input; |
283
|
|
|
|
|
|
|
} |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
has out_pdf_obj => (is => 'lazy', |
286
|
|
|
|
|
|
|
isa => Maybe[Object]); |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
has _out_pdf_object_is_open => (is => 'rw', isa => Bool); |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
has title => (is => 'ro', |
291
|
|
|
|
|
|
|
isa => Maybe[Str]); |
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
sub _build_out_pdf_obj { |
294
|
64
|
|
|
64
|
|
1268
|
my $self = shift; |
295
|
64
|
|
|
|
|
140
|
my $pdf; |
296
|
64
|
50
|
|
|
|
1230
|
if ($self->file) { |
297
|
64
|
100
|
|
|
|
1476
|
die "File " . $self->file . " is not a file" unless -f $self->file; |
298
|
63
|
|
|
|
|
1742
|
print $self->file . ": building out_pdf_object\n" if DEBUG; |
299
|
63
|
|
|
|
|
720
|
$pdf = PDF::API2->new(); |
300
|
63
|
|
|
|
|
56779
|
my %info = ( |
301
|
|
|
|
|
|
|
$self->in_pdf_obj->info, |
302
|
|
|
|
|
|
|
Creator => $self->_version, |
303
|
|
|
|
|
|
|
CreationDate => $self->_orig_file_timestamp, |
304
|
|
|
|
|
|
|
ModDate => $self->_now_timestamp, |
305
|
|
|
|
|
|
|
); |
306
|
63
|
|
|
|
|
546
|
$pdf->info(%info); |
307
|
63
|
|
|
|
|
11960
|
$self->_out_pdf_object_is_open(1); |
308
|
|
|
|
|
|
|
} |
309
|
63
|
|
|
|
|
3549
|
return $pdf; |
310
|
|
|
|
|
|
|
} |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
=head3 get_imported_page($pagenumber) |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
Retrieve the page form object from the input pdf to the output pdf, |
315
|
|
|
|
|
|
|
and return it. The method return undef if the page is out of range. |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
=cut |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
sub get_imported_page { |
321
|
936
|
|
|
936
|
1
|
2791
|
my ($self, $page) = @_; |
322
|
936
|
50
|
66
|
|
|
26690
|
if ((!defined $page) || ($page <= 0) || ($page > $self->total_pages)) { |
|
|
|
66
|
|
|
|
|
323
|
101
|
|
|
|
|
289
|
return undef; |
324
|
|
|
|
|
|
|
} |
325
|
835
|
|
|
|
|
22559
|
return $self->out_pdf_obj->importPageIntoForm($self->in_pdf_obj, $page) |
326
|
|
|
|
|
|
|
} |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
=head3 impose |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
Do the job and leave the output in C<< $self->outfile >>, cleaning up |
331
|
|
|
|
|
|
|
the internal objects. |
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
=cut |
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
sub impose { |
336
|
64
|
|
|
64
|
1
|
185
|
my $self = shift; |
337
|
64
|
|
|
|
|
321
|
my $out = $self->output_filename; |
338
|
64
|
|
|
|
|
506
|
$self->_do_impose; |
339
|
63
|
|
|
|
|
24958
|
$self->out_pdf_obj->saveas($out); |
340
|
63
|
|
|
|
|
5471202
|
$self->out_pdf_obj->end; |
341
|
63
|
|
|
|
|
2673
|
$self->_out_pdf_object_is_open(0); |
342
|
63
|
|
|
|
|
3998
|
$self->in_pdf_obj->end; |
343
|
63
|
|
|
|
|
847970
|
$self->_in_pdf_object_is_open(0); |
344
|
63
|
|
|
|
|
3899
|
$self->outfile($out); |
345
|
63
|
|
|
|
|
1143
|
return $out; |
346
|
|
|
|
|
|
|
} |
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
=head3 output_filename |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
If outfile is not provided, use the suffix provided and return the |
351
|
|
|
|
|
|
|
filename. |
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
=cut |
354
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
sub output_filename { |
356
|
69
|
|
|
69
|
1
|
892
|
my $self = shift; |
357
|
69
|
|
|
|
|
1829
|
my $out = $self->outfile; |
358
|
69
|
100
|
|
|
|
804
|
unless ($out) { |
359
|
43
|
|
|
|
|
842
|
my ($name, $path, $suffix) = fileparse($self->file, qr{\.pdf}i); |
360
|
43
|
50
|
|
|
|
1890
|
die $self->file . " has a suffix not recognized" unless $suffix; |
361
|
43
|
|
|
|
|
926
|
$out = File::Spec->catfile($path, $name . $self->suffix . $suffix); |
362
|
|
|
|
|
|
|
} |
363
|
69
|
|
|
|
|
941
|
return $out; |
364
|
|
|
|
|
|
|
} |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
sub _orig_file_timestamp { |
368
|
63
|
|
|
63
|
|
62493
|
my $self = shift; |
369
|
63
|
|
|
|
|
1730
|
my $mtime = (stat($self->file))[9]; |
370
|
63
|
|
|
|
|
2785
|
return $self->_format_timestamp($mtime); |
371
|
|
|
|
|
|
|
} |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
sub _now_timestamp { |
374
|
63
|
|
|
63
|
|
344
|
return shift->_format_timestamp(time()); |
375
|
|
|
|
|
|
|
} |
376
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
sub _format_timestamp { |
378
|
126
|
|
|
126
|
|
376
|
my ($self, $epoc) = @_; |
379
|
126
|
|
|
|
|
8098
|
return POSIX::strftime(q{%Y%m%d%H%M%S+00'00'}, localtime($epoc)); |
380
|
|
|
|
|
|
|
} |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
=head3 computed_signature |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
Return the actual number of signature, resolving 0 to the nearer |
385
|
|
|
|
|
|
|
signature. |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
=head3 total_output_pages |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
Return the computed number of pages of the output, taking in account |
390
|
|
|
|
|
|
|
the signature handling. |
391
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
=head3 DEMOLISH |
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
Object cleanup. |
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
=head3 DEBUG |
397
|
|
|
|
|
|
|
|
398
|
|
|
|
|
|
|
Constant picked from AMW_DEBUG environment. |
399
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
=cut |
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
sub computed_signature { |
403
|
131
|
|
|
131
|
1
|
25725
|
my $self = shift; |
404
|
131
|
|
100
|
|
|
2491
|
my $signature = $self->signature || 0; |
405
|
131
|
100
|
|
|
|
1580
|
if ($signature) { |
406
|
25
|
|
|
|
|
382
|
return $self->_optimize_signature($self->signature) + 0; |
407
|
|
|
|
|
|
|
} |
408
|
|
|
|
|
|
|
else { |
409
|
106
|
|
|
|
|
1872
|
my $pages = $self->total_pages; |
410
|
106
|
|
|
|
|
2446
|
my $ppsheet = $self->pages_per_sheet; |
411
|
106
|
|
|
|
|
934
|
return $pages + (($ppsheet - ($pages % $ppsheet)) % $ppsheet); |
412
|
|
|
|
|
|
|
} |
413
|
|
|
|
|
|
|
} |
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
sub total_output_pages { |
416
|
45
|
|
|
45
|
1
|
235
|
my $self = shift; |
417
|
45
|
|
|
|
|
849
|
my $pages = $self->total_pages; |
418
|
45
|
|
|
|
|
403
|
my $signature = $self->computed_signature; |
419
|
45
|
|
|
|
|
204
|
return $pages + (($signature - ($pages % $signature)) % $signature); |
420
|
|
|
|
|
|
|
} |
421
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
=head3 cropmarks_options |
423
|
|
|
|
|
|
|
|
424
|
|
|
|
|
|
|
By default, cropmarks are centered and twoside is true. |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
=cut |
427
|
|
|
|
|
|
|
|
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
sub cropmarks_options { |
430
|
0
|
|
|
0
|
1
|
0
|
my %options = ( |
431
|
|
|
|
|
|
|
top => 1, |
432
|
|
|
|
|
|
|
bottom => 1, |
433
|
|
|
|
|
|
|
inner => 1, |
434
|
|
|
|
|
|
|
outer => 1, |
435
|
|
|
|
|
|
|
twoside => 1, |
436
|
|
|
|
|
|
|
); |
437
|
0
|
|
|
|
|
0
|
return %options; |
438
|
|
|
|
|
|
|
} |
439
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
sub DEMOLISH { |
441
|
118
|
|
|
118
|
1
|
953949
|
my $self = shift; |
442
|
118
|
50
|
|
|
|
2305
|
if ($self->_out_pdf_object_is_open) { |
443
|
0
|
|
|
|
|
0
|
print $self->file . ": closing outpdf object\n" if DEBUG; |
444
|
0
|
|
|
|
|
0
|
$self->out_pdf_obj->end; |
445
|
|
|
|
|
|
|
} |
446
|
118
|
100
|
|
|
|
3551
|
if ($self->_in_pdf_object_is_open) { |
447
|
28
|
|
|
|
|
233
|
print $self->file . ": closing inpdf object\n" if DEBUG; |
448
|
28
|
|
|
|
|
475
|
$self->in_pdf_obj->end; |
449
|
|
|
|
|
|
|
} |
450
|
|
|
|
|
|
|
} |
451
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
1; |
453
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
=head1 SEE ALSO |
455
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
L |
457
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
=cut |
459
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
|