File Coverage

blib/lib/PDF/API2/Page.pm
Criterion Covered Total %
statement 181 237 76.3
branch 49 96 51.0
condition 20 67 29.8
subroutine 33 40 82.5
pod 20 28 71.4
total 303 468 64.7


line stmt bran cond sub pod time code
1             package PDF::API2::Page;
2              
3 38     38   285 use base 'PDF::API2::Basic::PDF::Pages';
  38         86  
  38         4467  
4              
5 38     38   273 use strict;
  38         76  
  38         986  
6 38     38   255 use warnings;
  38         128  
  38         2002  
7              
8             our $VERSION = '2.044'; # VERSION
9              
10 38     38   256 use Carp;
  38         88  
  38         2969  
11 38     38   300 use POSIX qw(floor);
  38         79  
  38         241  
12 38     38   2765 use Scalar::Util qw(looks_like_number weaken);
  38         124  
  38         1823  
13              
14 38     38   221 use PDF::API2::Basic::PDF::Utils;
  38         88  
  38         2484  
15 38     38   24667 use PDF::API2::Content;
  38         121  
  38         1716  
16 38     38   17389 use PDF::API2::Content::Text;
  38         110  
  38         1263  
17 38     38   272 use PDF::API2::Util;
  38         102  
  38         115194  
18              
19             my $page_sizes = {
20             # Metric A
21             '4a0' => [ 4760, 6716 ],
22             '2a0' => [ 3368, 4760 ],
23             'a0' => [ 2380, 3368 ],
24             'a1' => [ 1684, 2380 ],
25             'a2' => [ 1190, 1684 ],
26             'a3' => [ 842, 1190 ],
27             'a4' => [ 595, 842 ],
28             'a5' => [ 421, 595 ],
29             'a6' => [ 297, 421 ],
30              
31             # Metric B
32             '4b0' => [ 5656, 8000 ],
33             '2b0' => [ 4000, 5656 ],
34             'b0' => [ 2828, 4000 ],
35             'b1' => [ 2000, 2828 ],
36             'b2' => [ 1414, 2000 ],
37             'b3' => [ 1000, 1414 ],
38             'b4' => [ 707, 1000 ],
39             'b5' => [ 500, 707 ],
40             'b6' => [ 353, 500 ],
41              
42             # US
43             'letter' => [ 612, 792 ],
44             'legal' => [ 612, 1008 ],
45             'ledger' => [ 1224, 792 ],
46             'tabloid' => [ 792, 1224 ],
47             };
48              
49             =head1 NAME
50              
51             PDF::API2::Page - Methods to interact with individual pages
52              
53             =head1 SYNOPSIS
54              
55             my $pdf = PDF::API2->new();
56              
57             # Add a page to a new or existing PDF
58             my $page = $pdf->page();
59              
60             # Set the page size
61             $page->size('letter');
62              
63             # Set prepress page boundaries
64             $page->boundaries(media => '12x18', trim => 0.5 * 72);
65              
66             # Add an image
67             my $image = $pdf->image('/path/to/file.jpg');
68             $page->object($image, $x, $y, $w, $h);
69              
70             # Add textual content
71             my $text = $page->text();
72              
73             # Add graphical content (paths and shapes)
74             my $canvas = $page->graphics();
75              
76             =cut
77              
78             sub new {
79 142     142 1 464 my ($class, $pdf, $parent, $index) = @_;
80 142         253 my $self = {};
81              
82 142 50       376 $class = ref($class) if ref($class);
83 142         637 $self = $class->SUPER::new($pdf, $parent);
84 142         490 $self->{'Type'} = PDFName('Page');
85 142         610 $self->proc_set(qw( PDF Text ImageB ImageC ImageI ));
86 142         498 delete $self->{'Count'};
87 142         370 delete $self->{'Kids'};
88 142         623 $parent->add_page($self, $index);
89 142         437 return $self;
90             }
91              
92             sub coerce {
93 0     0 0 0 my ($class, $pdf, $page) = @_;
94 0         0 my $self = $page;
95 0         0 bless $self, $class;
96 0         0 $self->{' apipdf'} = $pdf;
97 0         0 weaken $self->{' apipdf'};
98 0         0 return $self;
99             }
100              
101             # Deprecated. Marking the page as dirty should only be needed in rare cases
102             # when the page hash is being edited directly rather than through the API. In
103             # that case, the out_obj call can be made manually. There's no reason (that I
104             # can think of) to have a specific call just (and only) for Page objects.
105             sub update {
106 0     0 0 0 my $self = shift();
107 0         0 $self->{' apipdf'}->out_obj($self);
108 0         0 return $self;
109             }
110              
111             =head1 METHODS
112              
113             =head2 size
114              
115             # Set the page size using a common name
116             $page->size('letter');
117              
118             # Set the page size using coordinates in points (X1, Y1, X2, Y2)
119             $page->size([0, 0, 612, 792]);
120              
121             # Get the page coordinates in points
122             my @rectangle = $page->size();
123              
124             Set the physical page size (a.k.a. media box) when called with an argument.
125             See L below for possible values. Returns the C<$page> object.
126              
127             Returns the coordinates of the rectangle enclosing the physical page size when
128             called without arguments.
129              
130             The size method is a convenient shortcut for setting the PDF's media box when
131             print-related page boundaries aren't required. It's equivalent to the
132             following:
133              
134             # Set
135             $page = $page->boundaries(media => $size);
136              
137             # Get
138             @rectangle = $page->boundaries->{'media'}->@*;
139              
140             =cut
141              
142             sub size {
143 1     1 1 2557 my $self = shift();
144              
145             # Set
146 1 50       5 if (@_) {
147 1         5 return $self->boundaries(media => @_);
148             }
149              
150             # Get
151 0         0 my %boundaries = $self->boundaries();
152 0         0 return @{$boundaries{'media'}};
  0         0  
153             }
154              
155             =head2 boundaries
156              
157             # Set
158             $page->boundaries(
159             media => '13x19',
160             bleed => [0.75 * 72, 0.75 * 72, 12.25 * 72, 18.25 * 72],
161             trim => 0.25 * 72,
162             );
163              
164             # Get
165             %boundaries = $page->boundaries();
166             ($x1, $y1, $x2, $y2) = $page->boundaries('trim');
167              
168             Set or replace all prepress page boundaries when called with a hash containing
169             one or more page boundary definitions. Returns the C<$page> object.
170              
171             Returns the current page boundaries if called without arguments. Returns the
172             coordinates for the specified page boundary if called with one argument.
173              
174             =head3 Page Boundaries
175              
176             PDF defines five page boundaries. When creating PDFs for print shops, you'll
177             most commonly use just the media box and trim box. Traditional print shops may
178             also use the bleed box when adding printer's marks and other information.
179              
180             =over
181              
182             =item * media
183              
184             The media box defines the boundaries of the physical medium on which the page is
185             to be printed. It may include any extended area surrounding the finished page
186             for bleed, printing marks, or other such purposes. The default value is a US
187             letter page (8.5" x 11").
188              
189             =item * crop
190              
191             The crop box defines the region to which the contents of the page shall be
192             clipped (cropped) when displayed or printed. The default value is the page's
193             media box.
194              
195             This is a historical page boundary. You'll likely want to set the bleed and/or
196             trim boxes instead.
197              
198             =item * bleed
199              
200             The bleed box defines the region to which the contents of the page shall be
201             clipped when output in a production environment. This may include any extra
202             bleed area needed to accommodate the physical limitations of cutting, folding,
203             and trimming equipment. The actual printed page (media box) may include
204             printing marks that fall outside the bleed box. The default value is the page's
205             crop box.
206              
207             =item * trim
208              
209             The trim box defines the intended dimensions of the finished page after
210             trimming. It may be smaller than the media box to allow for production-related
211             content, such as printing instructions, cut marks, or color bars. The default
212             value is the page's crop box.
213              
214             =item * art
215              
216             The art box defines the extent of the page's meaningful content (including
217             potential white space) as intended by the page's creator. The default value is
218             the page's crop box.
219              
220             =back
221              
222             =head3 Page Sizes
223              
224             PDF page sizes are stored as rectangle coordinates. For convenience, PDF::API2
225             also supports a number of aliases and shortcuts that are more human-friendly.
226              
227             The following formats are available:
228              
229             =over
230              
231             =item * a standard paper size
232              
233             $page->boundaries(media => 'A4');
234              
235             Aliases for the most common paper sizes are built in (case-insensitive).
236              
237             US: Letter, Legal, Ledger, Tabloid
238              
239             Metric: 4A0, 2A0, A0 - A6, 4B0, 2B0, and B0 - B6
240              
241             =item * a "WxH" string in inches
242              
243             $page->boundaries(media => '8.5x11');
244              
245             Many US paper sizes are commonly identified by their size in inches rather than
246             by a particular name. These can be passed as strings with the width and height
247             separated by an C.
248              
249             Examples: C<4x6>, C<12x18>, C<8.5x11>
250              
251             =item * a number (in points) representing a reduction from the next-larger box
252              
253             # Note: There are 72 points per inch
254             $page->boundaries(media => '12x18', trim => 0.5 * 72);
255              
256             # Equivalent
257             $page->boundaries(media => [0, 0, 12 * 72, 18 * 72],
258             trim => [0.5 * 72, 0.5 * 72, 11.5 * 72, 17.5 * 72]);
259              
260             This example shows a 12" x 18" physical sheet that will be reduced to a final
261             size of 11" x 17" by trimming 0.5" from each edge. The smaller boundary is
262             assumed to be centered on the larger one.
263              
264             The "next-larger box" follows this order, stopping at the first defined value:
265              
266             art -> trim -> bleed -> media
267              
268             crop -> media
269              
270             This option isn't available for the media box since it is by definition the
271             largest boundary.
272              
273             =item * [$width, $height] in points
274              
275             $page->boundaries(media => [8.5 * 72, 11 * 7.2]);
276              
277             For other page or boundary sizes, the width and height (in points) can be given
278             directly as an array.
279              
280             =item * [$x1, $y1, $x2, $y2] in points
281              
282             $page->boundaries(media => [0, 0, 8.5 * 72, 11 * 72]);
283              
284             Finally, the raw coordinates of the bottom-left and top-right corners of a
285             rectangle can be specified.
286              
287             =back
288              
289             =cut
290              
291             sub _to_rectangle {
292 6     6   10 my $value = shift();
293              
294             # An array of two or four numbers in points
295 6 50       13 if (ref($value) eq 'ARRAY') {
296 0 0       0 if (@$value == 2) {
    0          
297 0         0 return (0, 0, @$value);
298             }
299             elsif (@$value == 4) {
300 0         0 return @$value;
301             }
302 0         0 croak "Page boundary array must contain two or four numbers";
303             }
304              
305             # WxH in inches
306 6 100       34 if ($value =~ /^([0-9.]+)\s*x\s*([0-9.]+)$/) {
307 2         11 my ($w, $h) = ($1, $2);
308 2 50 33     19 if (looks_like_number($w) and looks_like_number($h)) {
309 2         11 return (0, 0, $w * 72, $h * 72);
310             }
311             }
312              
313             # Common names for page sizes
314 4 50       14 if ($page_sizes->{lc $value}) {
315 4         6 return (0, 0, @{$page_sizes->{lc $value}});
  4         13  
316             }
317              
318 0 0       0 if (ref($value)) {
319 0         0 croak "Unrecognized page size";
320             }
321             else {
322 0         0 croak "Unrecognized page size: $value";
323             }
324             }
325              
326             sub boundaries {
327 6     6 1 5125 my $self = shift();
328              
329             # Get
330 6 50 33     25 unless (@_) {
331 0         0 my %boundaries;
332 0         0 foreach my $box (qw(Media Crop Bleed Trim Art)) {
333 0         0 $boundaries{lc($box)} = [$self->_bounding_box($box . 'Box')];
334             }
335 0         0 return %boundaries;
336             }
337             elsif (@_ == 1) {
338             my $box = shift();
339             my @coordinates = $self->_bounding_box(ucfirst($box) . 'Box');
340             return @coordinates;
341             }
342              
343             # Set
344 6         17 my %boxes = @_;
345 6         14 foreach my $box (qw(media crop bleed trim art)) {
346 30 100       65 next unless exists $boxes{$box};
347              
348             # Special case: A single number as the value for anything other than
349             # MediaBox means to take the next larger size and reduce it by this
350             # amount in points on all four sides, provided the larger size was also
351             # included.
352 8         13 my $value = $boxes{$box};
353 8         12 my @rectangle;
354 8 100 66     36 if ($box ne 'media' and not ref($value) and looks_like_number($value)) {
      66        
355 2 50       14 my $parent = ($box eq 'crop' ? 'media' :
    50          
    50          
356             $box eq 'bleed' ? 'media' :
357             $box eq 'trim' ? 'bleed' : 'trim');
358 2 50 33     8 $parent = 'bleed' if $parent eq 'trim' and not $boxes{'trim'};
359 2 50 33     11 $parent = 'media' if $parent eq 'bleed' and not $boxes{'bleed'};
360 2 50 33     10 $parent = 'media' if $parent eq 'bleed' and not $boxes{'bleed'};
361 2 50       7 unless ($boxes{$parent}) {
362 0         0 croak "Single-number argument for $box requires $parent";
363             }
364              
365 2         4 @rectangle = @{$boxes{$parent}};
  2         5  
366 2         5 $rectangle[0] += $value;
367 2         3 $rectangle[1] += $value;
368 2         5 $rectangle[2] -= $value;
369 2         3 $rectangle[3] -= $value;
370             }
371             else {
372 6         13 @rectangle = _to_rectangle($value);
373             }
374              
375 8         23 my $box_name = ucfirst($box) . 'Box';
376 8         25 $self->_bounding_box($box_name, @rectangle);
377 8         25 $boxes{$box} = [@rectangle];
378             }
379              
380 6         19 return $self;
381             }
382              
383             sub _bounding_box {
384 92     92   2732 my $self = shift();
385 92         129 my $type = shift();
386              
387             # Get
388 92 100       194 unless (scalar @_) {
389 46         129 my $box = $self->find_prop($type);
390 46 50       108 unless ($box) {
391             # Default to letter (for historical PDF::API2 reasons, not per the
392             # PDF specification)
393 0 0       0 return (0, 0, 612, 792) if $type eq 'MediaBox';
394              
395             # Use defaults per PDF 1.7 section 14.11.2 Page Boundaries
396 0 0       0 return $self->_bounding_box('MediaBox') if $type eq 'CropBox';
397 0         0 return $self->_bounding_box('CropBox');
398             }
399 46         149 return map { $_->val() } $box->elements();
  184         354  
400             }
401              
402             # Set
403 46         124 $self->{$type} = PDFArray(map { PDFNum(float($_)) } page_size(@_));
  184         383  
404 46         140 return $self;
405             }
406              
407             # Deprecated; use size(...) or boundaries('media', ...)
408             sub mediabox {
409 38     38 1 68979 my $self = shift();
410 38 50       113 return $self->_bounding_box('MediaBox') unless @_;
411 38         142 return $self->_bounding_box('MediaBox', page_size(@_));
412             }
413              
414             # Deprecated
415             sub get_mediabox {
416 34     34 1 190 my $self = shift();
417 34         61 return $self->_bounding_box('MediaBox');
418             }
419              
420             # Deprecated; use boundaries('crop', ...)
421             sub cropbox {
422 1     1 1 2545 my $self = shift();
423 1 50       5 return $self->_bounding_box('CropBox') unless @_;
424 1         8 return $self->_bounding_box('CropBox', page_size(@_));
425             }
426              
427             # Deprecated
428             sub get_cropbox {
429 2     2 1 24 my $self = shift();
430 2         7 return $self->_bounding_box('CropBox');
431             }
432              
433             # Deprecated; use boundaries('bleed', ...)
434             sub bleedbox {
435 1     1 1 2571 my $self = shift();
436 1 50       6 return $self->_bounding_box('BleedBox') unless @_;
437 1         6 return $self->_bounding_box('BleedBox', page_size(@_));
438             }
439              
440             # Deprecated
441             sub get_bleedbox {
442 2     2 1 19 my $self = shift();
443 2         6 return $self->_bounding_box('BleedBox');
444             }
445              
446             # Deprecated; use boundaries('trim', ...)
447             sub trimbox {
448 1     1 1 2560 my $self = shift();
449 1 50       5 return $self->_bounding_box('TrimBox') unless @_;
450 1         8 return $self->_bounding_box('TrimBox', page_size(@_));
451             }
452              
453             # Deprecated
454             sub get_trimbox {
455 2     2 1 11 my $self = shift();
456 2         8 return $self->_bounding_box('TrimBox');
457             }
458              
459             # Deprecated; use boundaries('art', ...)
460             sub artbox {
461 1     1 1 2545 my $self = shift();
462 1 50       7 return $self->_bounding_box('ArtBox') unless @_;
463 1         7 return $self->_bounding_box('ArtBox', page_size(@_));
464             }
465              
466             # Deprecated
467             sub get_artbox {
468 2     2 1 12 my $self = shift();
469 2         7 return $self->_bounding_box('ArtBox');
470             }
471              
472             =head2 rotation
473              
474             $page = $page->rotation($degrees);
475              
476             Rotates the page clockwise when displayed or printed. C<$degrees> must be a
477             multiple of 90 and may be negative for counter-clockwise rotation.
478              
479             The coordinate system follows the page rotation. In other words, after rotating
480             the page 180 degrees, [0, 0] will be in the top right corner of the page rather
481             than the bottom left, X will increase to the right, and Y will increase
482             downward.
483              
484             To create a landscape page without moving the origin, use L.
485              
486             =cut
487              
488             # Deprecated (renamed to follow the pattern of using nouns instead of verbs)
489 0     0 1 0 sub rotate { return rotation(@_) }
490              
491             sub rotation {
492 0     0 1 0 my ($self, $degrees) = @_;
493 0   0     0 $degrees //= 0;
494              
495             # Ignore rotation of 360 or more (in either direction)
496 0         0 $degrees = $degrees % 360;
497              
498 0 0 0     0 unless ( $degrees == 0
      0        
      0        
      0        
      0        
      0        
499             or $degrees == 90 or $degrees == -90
500             or $degrees == 180 or $degrees == -180
501             or $degrees == 270 or $degrees == -270) {
502 0         0 croak "Rotation must be a multiple of 90 degrees";
503             }
504              
505 0         0 $self->{'Rotate'} = PDFNum($degrees);
506              
507 0         0 return $self;
508             }
509              
510             =head2 graphics
511              
512             my $canvas = $page->graphics(%options);
513              
514             Returns a L object for drawing paths and shapes.
515              
516             The following options are available:
517              
518             =over
519              
520             =item * prepend (boolean)
521              
522             If true, place the drawing at the beginning of the page's content stream instead
523             of the end.
524              
525             =item * compress (boolean)
526              
527             Manually specify whether the drawing instructions should be compressed. If
528             unspecified, the PDF's compression setting will be used, which is on by default.
529              
530             =back
531              
532             =cut
533              
534             sub fixcontents {
535 128     128 0 234 my $self = shift();
536 128   66     517 $self->{'Contents'} = $self->{'Contents'} || PDFArray();
537 128 50       515 if (ref($self->{'Contents'}) =~ /Objind$/) {
538 0         0 $self->{'Contents'}->realise();
539             }
540 128 50       641 if (ref($self->{'Contents'}) !~ /Array$/) {
541 0         0 $self->{'Contents'} = PDFArray($self->{'Contents'});
542             }
543 128         238 return;
544             }
545              
546             sub content {
547 122     122 0 310 my ($self, $obj, $dir) = @_;
548 122 50 33     418 if (defined($dir) and $dir > 0) {
549 0         0 $self->precontent($obj);
550             }
551             else {
552 122         350 $self->addcontent($obj);
553             }
554 122 50       455 $self->{' apipdf'}->new_obj($obj) unless $obj->is_obj($self->{' apipdf'});
555 122         291 $obj->{' apipdf'} = $self->{' apipdf'};
556 122         270 $obj->{' api'} = $self->{' api'};
557 122         229 $obj->{' apipage'} = $self;
558              
559 122         421 weaken $obj->{' apipdf'};
560 122         362 weaken $obj->{' api'};
561 122         339 weaken $obj->{' apipage'};
562              
563 122         450 return $obj;
564             }
565              
566             sub addcontent {
567 122     122 0 291 my ($self, @objs) = @_;
568 122         370 $self->fixcontents();
569 122         418 $self->{'Contents'}->add_elements(@objs);
570 122         216 return;
571             }
572              
573             sub precontent {
574 0     0 0 0 my ($self, @objs) = @_;
575 0         0 $self->fixcontents();
576 0         0 unshift @{$self->{'Contents'}->val()}, @objs;
  0         0  
577 0         0 return;
578             }
579              
580             # Deprecated; replace with graphics, which adds input validation
581             sub gfx {
582 52     52 1 567 my ($self, $prepend) = @_;
583 52         169 my $graphics = $self->graphics(prepend => $prepend);
584              
585             # Delete the input validation flag
586 52         127 delete $graphics->{' graphics'};
587              
588 52         223 return $graphics;
589             }
590              
591             sub graphics {
592 104     104 1 285 my ($self, %options) = @_;
593 104         651 my $graphics = PDF::API2::Content->new();
594 104         244 $graphics->{' graphics'} = 1;
595              
596 104   66     548 $options{'compress'} //= $self->{' api'}->{'forcecompress'};
597 104 100       282 $graphics->compressFlate() if $options{'compress'};
598              
599 104 50       246 if ($options{'prepend'}) {
600 0         0 return $self->content($graphics, 1);
601             }
602             else {
603 104         328 return $self->content($graphics);
604             }
605             }
606              
607             =head2 text
608              
609             my $text = $page->text(%options);
610              
611             Returns a L object for including textual content.
612              
613             The options are the same as the L method.
614              
615             =cut
616              
617             sub text {
618 18     18 1 1054 my $self = shift();
619              
620 18         33 my %options;
621 18 50       56 if (@_ == 1) {
622             # Deprecated
623 0         0 $options{'prepend'} = shift();
624             }
625             else {
626 18         38 %options = @_;
627             }
628              
629 18         151 my $text = PDF::API2::Content::Text->new();
630              
631 18   66     120 $options{'compress'} //= $self->{' api'}->{'forcecompress'};
632 18 100       107 $text->compressFlate() if $options{'compress'};
633              
634 18 50       51 if ($options{'prepend'}) {
635 0         0 $self->content($text, 1);
636             }
637             else {
638 18         63 $self->content($text);
639             }
640              
641 18         83 return $text;
642             }
643              
644             =head2 object
645              
646             $page = $page->object($object, $x, $y, $scale_x, $scale_y);
647              
648             Places an image or other external object (a.k.a. XObject) on the page in the
649             specified location.
650              
651             For images, C<$scale_x> and C<$scale_y> represent the width and height of the
652             image on the page in points. If C<$scale_x> is omitted, it will default to 72
653             pixels per inch. If C<$scale_y> is omitted, the image will be scaled
654             proportionally based on the image dimensions.
655              
656             For other external objects, the scale is a multiplier, where 1 (the default)
657             represents 100% (i.e. no change).
658              
659             If the object to be placed depends on a coordinate transformation (e.g. rotation
660             or skew), first create a content object using L, then call
661             L after making the appropriate transformations.
662              
663             =cut
664              
665             sub object {
666 0     0 1 0 my $self = shift();
667 0         0 $self->graphics->object(@_);
668 0         0 return $self;
669             }
670              
671             =head2 annotation
672              
673             my $annotation = $page->annotation();
674              
675             Returns a new L object.
676              
677             =cut
678              
679             sub annotation {
680 6     6 1 31 my $self = shift();
681              
682 6 100 33     26 unless (exists $self->{'Annots'}) {
683 5         15 $self->{'Annots'} = PDFArray();
684 5         17 $self->{' apipdf'}->out_obj($self);
685             }
686             elsif (ref($self->{'Annots'}) =~ /Objind/) {
687             $self->{'Annots'}->realise();
688             }
689              
690 6         538 require PDF::API2::Annotation;
691 6         31 my $ant = PDF::API2::Annotation->new();
692 6         60 $self->{'Annots'}->add_elements($ant);
693 6         21 $self->{' apipdf'}->new_obj($ant);
694 6         12 $ant->{' apipdf'} = $self->{' apipdf'};
695 6         14 $ant->{' apipage'} = $self;
696 6         17 weaken $ant->{' apipdf'};
697 6         19 weaken $ant->{' apipage'};
698              
699 6 100       15 if ($self->{'Annots'}->is_obj($self->{' apipdf'})) {
700 1         10 $self->{' apipdf'}->out_obj($self->{'Annots'});
701             }
702              
703 6         24 return $ant;
704             }
705              
706             sub resource {
707 29     29 0 101 my ($self, $type, $key, $obj, $force) = @_;
708 29         161 my $dict = $self->find_prop('Resources');
709              
710 29   0     129 $dict = $dict || $self->{'Resources'} || PDFDict();
711              
712 29 50       151 $dict->realise() if ref($dict) =~ /Objind$/;
713              
714 29   66     184 $dict->{$type} = $dict->{$type} || PDFDict();
715 29 50       131 $dict->{$type}->realise if ref($dict->{$type}) =~ /Objind$/;
716              
717 29 50       90 unless (defined $obj) {
718 0   0       return $dict->{$type}->{$key} || undef;
719             }
720             else {
721 29 50       82 if ($force) {
722 0         0 $dict->{$type}->{$key} = $obj;
723             }
724             else {
725 29   33     176 $dict->{$type}->{$key} = $dict->{$type}->{$key} || $obj;
726             }
727              
728 29 50       122 $self->{' apipdf'}->out_obj($dict) if $dict->is_obj($self->{' apipdf'});
729 29 50       138 $self->{' apipdf'}->out_obj($dict->{$type}) if $dict->{$type}->is_obj($self->{' apipdf'});
730 29 50       113 $self->{' apipdf'}->out_obj($obj) if $obj->is_obj($self->{' apipdf'});
731 29         146 $self->{' apipdf'}->out_obj($self);
732              
733 29         258 return $dict;
734             }
735             }
736              
737             sub ship_out {
738 0     0 0   my ($self, $pdf) = @_;
739              
740 0           $pdf->ship_out($self);
741 0 0         if (defined $self->{'Contents'}) {
742 0           $pdf->ship_out($self->{'Contents'}->elements());
743             }
744 0           return $self;
745             }
746              
747             =head1 MIGRATION
748              
749             See L for an overview.
750              
751             =over
752              
753             =item gfx
754              
755             Replace with L.
756              
757             =item rotate
758              
759             Replace with L.
760              
761             =item mediabox
762              
763             =item get_mediabox
764              
765             Replace with L if not in a print shop environment or L
766             if more complex page boundaries are needed.
767              
768             If using page size aliases (e.g. "letter" or "A4"), check the Page Sizes section
769             to ensure that the alias you're using is still supported (you'll get an error if
770             it isn't).
771              
772             =item cropbox
773              
774             =item bleedbox
775              
776             =item trimbox
777              
778             =item artbox
779              
780             =item get_cropbox
781              
782             =item get_bleedbox
783              
784             =item get_trimbox
785              
786             =item get_artbox
787              
788             Replace with L.
789              
790             =back
791              
792             =cut
793              
794             1;