File Coverage

blib/lib/PDF/Builder/NamedDestination.pm
Criterion Covered Total %
statement 41 100 41.0
branch 12 54 22.2
condition 8 30 26.6
subroutine 9 19 47.3
pod 6 12 50.0
total 76 215 35.3


line stmt bran cond sub pod time code
1             package PDF::Builder::NamedDestination;
2              
3 38     38   287 use base 'PDF::Builder::Basic::PDF::Dict';
  38         89  
  38         3972  
4              
5 38     38   263 use strict;
  38         103  
  38         889  
6 38     38   227 use warnings;
  38         106  
  38         1137  
7              
8 38     38   241 use Carp;
  38         76  
  38         2575  
9 38     38   312 use Encode qw(:all);
  38         112  
  38         13766  
10              
11             our $VERSION = '3.025'; # VERSION
12             our $LAST_UPDATE = '3.024'; # manually update whenever code is changed
13              
14             # TBD: do rect and border apply to Named Destinations (link, url, file)?
15             # There is nothing to implement these options. Perhaps the code was copied
16             # from Annotations and never cleaned up? Disable mention of these options
17             # for now (in the POD). Only link handles the destination page fit option.
18              
19 38     38   322 use PDF::Builder::Util;
  38         96  
  38         5090  
20 38     38   283 use PDF::Builder::Basic::PDF::Utils;
  38         106  
  38         51929  
21              
22             =head1 NAME
23              
24             PDF::Builder::NamedDestination - Add named destinations (views) to a PDF
25              
26             =head1 METHODS
27              
28             =over
29              
30             =item $dest = PDF::Builder::NamedDestination->new($pdf, ...)
31              
32             Creates a new named destination object. Any optional additional arguments
33             will be passed on to C.
34              
35             =back
36              
37             =head2 Destination types
38              
39             =over
40              
41             =cut
42              
43             sub new {
44 1     1 1 9 my $class = shift;
45 1         1 my $pdf = shift;
46              
47 1 50       8 $pdf = $pdf->{'pdf'} if $pdf->isa('PDF::Builder');
48 1         6 my $self = $class->SUPER::new($pdf);
49 1         29 $pdf->new_obj($self);
50              
51 1 50       3 if (@_) { # leftover arguments?
52 1         4 return $self->dest(@_);
53             }
54              
55 0         0 return $self;
56             }
57              
58             # Note: new_api() removed in favor of new():
59             # new_api($api, ...) replace with new($api->{'pdf'}, ...)
60             # Appears to be added back in, PDF::API2 2.042
61             sub new_api {
62 0     0 0 0 my ($class, $api2) = @_;
63 0         0 warnings::warnif('deprecated',
64             'Call to deprecated method new_api, replace with new');
65              
66 0         0 my $destination = $class->new($api2);
67 0         0 return $destination;
68             }
69              
70             =item $dest->dest($page, %opts)
71              
72             A destination (dest) is a particular view of a PDF, consisting of a page
73             object, the
74             location of the window on that page, and possible coordinate and zoom arguments.
75              
76             # The XYZ location takes three arguments
77             my $dest1 = PDF::Builder::NamedDestination->new($pdf);
78             $dest->dest($pdf->open_page(1), 'xyz' => [$x, $y, $zoom]);
79              
80             # The Fit location doesn't require any arguments, but one is still
81             # needed for the hash array
82             my $dest2 = PDF::Builder::NamedDestination->new($pdf);
83             $dest->dest($pdf->open_page(2), 'fit' => 1);
84              
85             See L for a listing of the available
86             locations and their syntax.
87              
88             "xyz" is the B fit setting, with position (left and top) and zoom
89             the same as the calling page's.
90              
91             =back
92              
93             =cut
94              
95             sub dest {
96 1     1 1 3 my ($self, $page, %opts) = @_;
97              
98             # copy dashed names over to preferred non-dashed names
99 1 50 33     5 if (defined $opts{'-fit'} && !defined $opts{'fit'}) { $opts{'fit'} = delete($opts{'-fit'}); }
  0         0  
100 1 50 33     4 if (defined $opts{'-fith'} && !defined $opts{'fith'}) { $opts{'fith'} = delete($opts{'-fith'}); }
  0         0  
101 1 50 33     4 if (defined $opts{'-fitb'} && !defined $opts{'fitb'}) { $opts{'fitb'} = delete($opts{'-fitb'}); }
  0         0  
102 1 50 33     3 if (defined $opts{'-fitbh'} && !defined $opts{'fitbh'}) { $opts{'fitbh'} = delete($opts{'-fitbh'}); }
  0         0  
103 1 50 33     4 if (defined $opts{'-fitv'} && !defined $opts{'fitv'}) { $opts{'fitv'} = delete($opts{'-fitv'}); }
  0         0  
104 1 50 33     4 if (defined $opts{'-fitbv'} && !defined $opts{'fitbv'}) { $opts{'fitbv'} = delete($opts{'-fitbv'}); }
  0         0  
105 1 50 33     13 if (defined $opts{'-fitr'} && !defined $opts{'fitr'}) { $opts{'fitr'} = delete($opts{'-fitr'}); }
  0         0  
106 1 50 33     4 if (defined $opts{'-xyz'} && !defined $opts{'xyz'}) { $opts{'xyz'} = delete($opts{'-xyz'}); }
  0         0  
107              
108 1 50       4 if (ref($page)) {
109             # should be only one 'fit' hash value? other options in hash?
110             # TBD: check that single values are scalars, not ARRAYREFs?
111 1 50       3 if (defined $opts{'fit'}) { # 1 value, ignored
    0          
    0          
    0          
    0          
    0          
    0          
    0          
112 1         5 $self->{'D'} = PDFArray($page, PDFName('Fit'));
113             } elsif (defined $opts{ 'fith'}) {
114             croak "Expecting scalar value for fith entry "
115 0 0       0 unless ref($opts{'fith'}) eq '';
116             $self->{'D'} = PDFArray($page, PDFName('FitH'),
117 0         0 PDFNum($opts{'fith'}));
118             } elsif (defined $opts{'fitb'}) { # 1 value, ignored
119 0         0 $self->{'D'} = PDFArray($page, PDFName('FitB'));
120             } elsif (defined $opts{'fitbh'}) {
121             croak "Expecting scalar value for fitbh entry "
122 0 0       0 unless ref($opts{'fitbh'}) eq '';
123             $self->{'D'} = PDFArray($page, PDFName('FitBH'),
124 0         0 PDFNum($opts{'fitbh'}));
125             } elsif (defined $opts{'fitv'}) {
126             croak "Expecting scalar value for fitv entry "
127 0 0       0 unless ref($opts{'fitv'}) eq '';
128             $self->{'D'} = PDFArray($page, PDFName('FitV'),
129 0         0 PDFNum($opts{'fitv'}));
130             } elsif (defined $opts{'fitbv'}) {
131             croak "Expecting scalar value for fitbv entry "
132 0 0       0 unless ref($opts{'fitbv'}) eq '';
133             $self->{'D'} = PDFArray($page, PDFName('FitBV'),
134 0         0 PDFNum($opts{'fitbv'}));
135             } elsif (defined $opts{'fitr'}) { # anon array length 4
136             croak "Insufficient parameters to ->dest(page, fitr => []) "
137             unless ref($opts{'fitr'}) eq 'ARRAY' &&
138 0 0 0     0 scalar @{$opts{'fitr'}} == 4;
  0         0  
139             $self->{'D'} = PDFArray($page, PDFName('FitR'),
140 0         0 map {PDFNum($_)} @{$opts{'fitr'}});
  0         0  
  0         0  
141             } elsif (defined $opts{'xyz'}) { # anon array length 3
142             croak "Insufficient parameters to ->dest(page, xyz => []) "
143             unless ref($opts{'xyz'}) eq 'ARRAY' &&
144 0 0 0     0 scalar @{$opts{'xyz'}} == 3;
  0         0  
145             $self->{'D'} = PDFArray($page, PDFName('XYZ'),
146 0 0       0 map {defined $_ ? PDFNum($_) : PDFNull()} @{$opts{'xyz'}});
  0         0  
  0         0  
147             } else {
148             # no "fit" option found. use default of xyz.
149 0         0 $opts{'xyz'} = [undef,undef,undef];
150             $self->{'D'} = PDFArray($page, PDFName('XYZ'),
151 0 0       0 map {defined $_ ? PDFNum($_) : PDFNull()} @{$opts{'xyz'}});
  0         0  
  0         0  
152             }
153             }
154              
155 1         4 return $self;
156             }
157              
158             =head2 Target Destinations
159              
160             =over
161              
162             =item $dest->link($page, %opts)
163              
164             A go-to (link) action changes the view to a specified destination (page,
165             location, and magnification factor).
166              
167             Parameters are as described in C.
168              
169             B C
170              
171             Originally this method was C, but recently PDF::API2 changed the name
172             to C. "goto" is added for compatibility.
173              
174             =cut
175              
176             sub link {
177 0     0 1   my $self = shift();
178 0           $self->{'S'} = PDFName('GoTo');
179 0           return $self->dest(@_);
180             }
181              
182             sub goto {
183 0     0 0   my $self = shift();
184 0           $self->{'S'} = PDFName('GoTo');
185 0           return $self->dest(@_);
186             }
187              
188             =item $dest->uri($url)
189              
190             Defines the destination as launch-url with uri C<$url>.
191              
192             B C
193              
194             Originally this method was C, but recently PDF::API2 changed the name
195             to C. "url" is retained for compatibility.
196              
197             =cut
198              
199 0     0 0   sub url { return uri(@_); } ## no critic
200              
201             sub uri {
202 0     0 1   my ($self, $uri, %opts) = @_;
203             # currently no opts
204              
205 0           $self->{'S'} = PDFName('URI');
206 0           $self->{'URI'} = PDFString($uri, 'u');
207              
208 0           return $self;
209             }
210              
211             =item $dest->launch($file)
212              
213             Defines the destination as launch-file with filepath C<$file> and
214             page-fit options %opts. The target application is run. Note that this is
215             B a PDF I a browser file -- it is a local application.
216              
217             B C
218              
219             Originally this method was C, but recently PDF::API2 changed the name
220             to C. "file" is retained for compatibility.
221              
222             =cut
223              
224 0     0 0   sub file { return launch(@_); } ## no critic
225              
226             sub launch {
227 0     0 1   my ($self, $file, %opts) = @_;
228             # currently no opts
229              
230 0           $self->{'S'} = PDFName('Launch');
231 0           $self->{'F'} = PDFString($file, 'u');
232              
233 0           return $self;
234             }
235              
236             =item $dest->pdf($pdf_file, $pagenum, %opts)
237              
238             Defines the destination as a PDF-file with filepath C<$pdf_file>, on page
239             C<$pagenum>, and options %opts (same as dest()).
240              
241             B C and C
242              
243             Originally this method was C, and had been earlier renamed to
244             C, but recently PDF::API2 changed the name to C. "pdfile" and
245             "pdf_file" are retained for compatibility. B the position and zoom
246             information is still given as a hash element in PDF::Builder, while PDF::API2
247             has changed to a position string and an array of dimensions.
248              
249             =cut
250              
251 0     0 0   sub pdf_file { return pdf(@_); } ## no critic
252             # deprecated and removed earlier, but still in PDF::API2
253 0     0 0   sub pdfile { return pdf(@_); } ## no critic
254              
255             sub pdf{
256 0     0 1   my ($self, $file, $pnum, %opts) = @_;
257              
258 0           $self->{'S'} = PDFName('GoToR');
259 0           $self->{'F'} = PDFString($file, 'u');
260              
261 0           $self->dest(PDFNum($pnum), %opts);
262              
263 0           return $self;
264             }
265              
266             =back
267              
268             =cut
269              
270             1;