File Coverage

blib/lib/PDF/Create.pm
Criterion Covered Total %
statement 602 618 97.4
branch 182 234 77.7
condition 110 144 76.3
subroutine 50 52 96.1
pod 12 41 29.2
total 956 1089 87.7


line stmt bran cond sub pod time code
1             package PDF::Create;
2              
3             our $VERSION = '1.43';
4              
5             =head1 NAME
6              
7             PDF::Create - Create PDF files.
8              
9             =head1 VERSION
10              
11             Version 1.43
12              
13             =cut
14              
15 18     18   101213 use 5.006;
  18         168  
16 18     18   112 use strict; use warnings;
  18     18   35  
  18         590  
  18         108  
  18         54  
  18         646  
17              
18 18     18   108 use Carp qw(confess croak cluck carp);
  18         34  
  18         1453  
19 18     18   8233 use Data::Dumper;
  18         119141  
  18         1329  
20 18     18   5338 use FileHandle;
  18         152766  
  18         118  
21 18     18   6218 use Scalar::Util qw(weaken);
  18         53  
  18         1427  
22              
23 18     18   6939 use PDF::Image::GIF;
  18         55  
  18         606  
24 18     18   5371 use PDF::Image::JPEG;
  18         54  
  18         633  
25 18     18   6929 use PDF::Create::Page;
  18         66  
  18         1084  
26 18     18   6347 use PDF::Create::Outline;
  18         47  
  18         120753  
27              
28             my $DEBUG = 0;
29              
30             =encoding utf8
31              
32             =head1 DESCRIPTION
33              
34             C allows you to create PDF document using a number of primitives.The
35             result is as a PDF file or stream. PDF stands for Portable Document Format.
36              
37             Documents can have several pages, a table of content, an information section and
38             many other PDF elements.
39              
40             =head1 SYNOPSIS
41              
42             C provides an easy module to create PDF output from your perl script.
43             It is designed to be easy to use and simple to install and maintain. It provides a
44             couple of subroutines to handle text, fonts, images and drawing primitives. Simple
45             documents are easy to create with the supplied routines.
46              
47             In addition to be reasonable simple C is written in pure Perl and has
48             no external dependencies (libraries, other modules, etc.). It should run on any
49             platform where perl is available.
50              
51             For complex stuff some understanding of the underlying Postscript/PDF format is
52             necessary. In this case it might be better go with the more complete L
53             modules to gain more features at the expense of a steeper learning curve.
54              
55             Example PDF creation with C (see L for details
56             of methods available on a page):
57              
58             use strict; use warnings;
59             use PDF::Create;
60              
61             my $pdf = PDF::Create->new(
62             'filename' => 'sample.pdf',
63             'Author' => 'John Doe',
64             'Title' => 'Sample PDF',
65             'CreationDate' => [ localtime ]
66             );
67              
68             # Add a A4 sized page
69             my $root = $pdf->new_page('MediaBox' => $pdf->get_page_size('A4'));
70              
71             # Add a page which inherits its attributes from $root
72             my $page1 = $root->new_page;
73              
74             # Prepare a font
75             my $font = $pdf->font('BaseFont' => 'Helvetica');
76              
77             # Prepare a Table of Content
78             my $toc = $pdf->new_outline('Title' => 'Title Page', 'Destination' => $page1);
79              
80             # Write some text
81             $page1->stringc($font, 40, 306, 426, 'PDF::Create');
82             $page1->stringc($font, 20, 306, 396, "version $PDF::Create::VERSION");
83             $page1->stringc($font, 20, 306, 300, 'by John Doe ');
84              
85             # Add another page
86             my $page2 = $root->new_page;
87              
88             # Draw some lines
89             $page2->line(0, 0, 592, 840);
90             $page2->line(0, 840, 592, 0);
91              
92             $toc->new_outline('Title' => 'Second Page', 'Destination' => $page2);
93              
94             # Close the file and write the PDF
95             $pdf->close;
96              
97             =head1 CONSTRUCTOR
98              
99             The method C create a new pdf structure for your PDF. It returns an
100             object handle which can be used to add more stuff to the PDF. The parameter keys
101             to the constructor are detailed as below:
102              
103             +--------------+------------------------------------------------------------+
104             | Key | Description |
105             +--------------+------------------------------------------------------------+
106             | | |
107             | filename | Destination file that will contain resulting PDF or '-' for|
108             | | stdout. If neither filename or fh are specified, the |
109             | | content will be stored in memory and returned when calling |
110             | | close(). |
111             | | |
112             | fh | Already opened filehandle that will contain resulting PDF. |
113             | | See comment above regarding close(). |
114             | | |
115             | Version | PDF Version to claim, can be 1.0 to 1.3 (default: 1. |
116             | | |
117             | PageMode | How the document should appear when opened.Possible values |
118             | | UseNone (Default), UseOutlines, UseThumbs and FullScreen |
119             | | |
120             | Author | The name of the person who created this document. |
121             | | |
122             | Creator | If the document was converted into a PDF document from |
123             | | another form, this is the name of the application that |
124             | | created the document. |
125             | | |
126             | Title | The title of the document. |
127             | | |
128             | Subject | The subject of the document. |
129             | | |
130             | Keywords | Keywords associated with the document. |
131             | | |
132             | CreationDate | The date the document was created.This is passed as an |
133             | | anonymous array in the same format as localtime returns. |
134             | | |
135             | Debug | The debug level, defaults to 0. It can be any positive |
136             | | integers. |
137             | | |
138             +--------------+------------------------------------------------------------+
139              
140             Example:
141              
142             my $pdf = PDF::Create->new(
143             'filename' => 'sample.pdf',
144             'Version' => 1.2,
145             'PageMode' => 'UseOutlines',
146             'Author' => 'John Doe',
147             'Title' => 'My Title',
148             'CreationDate' => [ localtime ]
149             );
150              
151             If you are writing a CGI you can send your PDF on the fly to stdout / directly to
152             the browser using '-' as filename.
153              
154             CGI Example:
155              
156             use CGI;
157             use PDF::Create;
158              
159             print CGI::header(-type => 'application/x-pdf', -attachment => 'sample.pdf');
160             my $pdf = PDF::Create->new(
161             'filename' => '-',
162             'Author' => 'John Doe',
163             'Title' => 'My title',
164             'CreationDate' => [ localtime ]
165             );
166              
167             =cut
168              
169             sub new {
170 42     42 0 69855 my ($this, %params) = @_;
171              
172             # validate constructor keys
173 42         3634 my %valid_constructor_keys = (
174             'fh' => 1,
175             'filename' => 1,
176             'Version' => 1,
177             'PageMode' => 1,
178             'Author' => 1,
179             'Creator' => 1,
180             'Title' => 1,
181             'Subject' => 1,
182             'Keywords' => 1,
183             'Debug' => 1,
184             'CreationDate' => 1,
185             );
186 42         3466 foreach (keys %params) {
187             croak "Invalid constructor key '$_' received."
188 138 100       7674 unless (exists $valid_constructor_keys{$_});
189             }
190              
191 34 100 66     3665 if (exists $params{PageMode} && defined $params{PageMode}) {
192             # validate PageMode key value
193 26         3448 my %valid_page_mode_values = (
194             'UseNone' => 1,
195             'UseOutlines' => 1,
196             'UseThumbs' => 1,
197             'FullScreen' => 1);
198             croak "Invalid value for key 'PageMode' received '". $params{PageMode} . "'"
199 26 100       6950 unless (exists $valid_page_mode_values{$params{PageMode}});
200             }
201              
202 33 100 66     3511 if (exists $params{Debug} && defined $params{Debug}) {
203             # validate Debug key value
204             croak "Invalid value for key 'Debug' received '". $params{Debug} . "'"
205 2 100 66     89 unless (($params{Debug} =~ /^\d+$/) && ($params{Debug} >= 0));
206             }
207              
208 32   33     3540 my $class = ref($this) || $this;
209 32         3704 my $self = {};
210 32         3475 bless $self, $class;
211              
212 32         3496 $self->{'data'} = '';
213 32   100     3459 $self->{'version'} = $params{'Version'} || "1.2";
214 32         3417 $self->{'trailer'} = {};
215              
216 32         3552 $self->{'pages'} = PDF::Create::Page->new();
217 32         3771 $self->{'current_page'} = $self->{'pages'};
218             # circular reference
219 32         3714 $self->{'pages'}->{'pdf'} = $self;
220 32         3733 weaken $self->{pages}{pdf};
221 32         3746 $self->{'page_count'} = 0;
222 32         3680 $self->{'outline_count'} = 0;
223              
224             # cross-reference table start address
225 32         3748 $self->{'crossreftblstartaddr'} = 0;
226 32         3726 $self->{'generation_number'} = 0;
227 32         3715 $self->{'object_number'} = 0;
228              
229 32 100       3793 if ( defined $params{'fh'} ) {
    100          
230 1         2 $self->{'fh'} = $params{'fh'};
231             } elsif ( defined $params{'filename'} ) {
232 26         3674 $self->{'filename'} = $params{'filename'};
233 26         3879 my $fh = FileHandle->new( "> $self->{'filename'}" );
234 26 50       104987 carp "PDF::Create.pm: $self->{'filename'}: $!\n" unless defined $fh;
235 26         3492 binmode $fh;
236 26         6727 $self->{'fh'} = $fh;
237             }
238              
239 32         3425 $self->{'catalog'} = {};
240 32 100       3588 $self->{'catalog'}{'PageMode'} = $params{'PageMode'} if defined $params{'PageMode'};
241              
242             # Header: add version
243 32         3627 $self->add_version;
244              
245             # Info
246 32 100       3530 $self->{'Author'} = $params{'Author'} if defined $params{'Author'};
247 32 50       3445 $self->{'Creator'} = $params{'Creator'} if defined $params{'Creator'};
248 32 100       3546 $self->{'Title'} = $params{'Title'} if defined $params{'Title'};
249 32 50       3523 $self->{'Subject'} = $params{'Subject'} if defined $params{'Subject'};
250 32 50       3632 $self->{'Keywords'} = $params{'Keywords'} if defined $params{'Keywords'};
251              
252             # TODO: Default creation date from system date
253 32 50       3626 if ( defined $params{'CreationDate'} ) {
254             $self->{'CreationDate'} =
255             sprintf "D:%4u%0.2u%0.2u%0.2u%0.2u%0.2u",
256             $params{'CreationDate'}->[5] + 1900, $params{'CreationDate'}->[4] + 1,
257             $params{'CreationDate'}->[3], $params{'CreationDate'}->[2],
258 0         0 $params{'CreationDate'}->[1], $params{'CreationDate'}->[0];
259             }
260 32 100       3487 if ( defined $params{'Debug'} ) {
261 1         2 $DEBUG = $params{'Debug'};
262              
263             # Enable stack trace for PDF::Create internal routines
264 1         2 $Carp::Internal{ ('PDF::Create') }++;
265             }
266 32         3609 debug( 1, "Debugging level $DEBUG" );
267 32         8621 return $self;
268             }
269              
270             =head1 METHODS
271              
272             =head2 new_page(%params)
273              
274             Add a page to the document using the given parameters. C must be called
275             first to initialize a root page, used as model for further pages.Returns a handle
276             to the newly created page. Parameters can be:
277              
278             +-----------+---------------------------------------------------------------+
279             | Key | Description |
280             +-----------+---------------------------------------------------------------+
281             | | |
282             | Parent | The parent of this page in the pages tree.This is page object.|
283             | | |
284             | Resources | Resources required by this page. |
285             | | |
286             | MediaBox | Rectangle specifying the natural size of the page,for example |
287             | | the dimensions of an A4 sheet of paper. The coordinates are |
288             | | measured in default user space units It must be the reference |
289             | | of 4 values array.You can use C to get to get |
290             | | the size of standard paper sizes.C knows about |
291             | | A0-A6, A4L (landscape), Letter, Legal, Broadsheet, Ledger, |
292             | | Tabloid, Executive and 36x36. |
293             | CropBox | Rectangle specifying the default clipping region for the page |
294             | | when displayed or printed. The default is the value of the |
295             | | MediaBox. |
296             | | |
297             | ArtBox | Rectangle specifying an area of the page to be used when |
298             | | placing PDF content into another application. The default is |
299             | | the value of the CropBox. [PDF 1.3] |
300             | | |
301             | TrimBox | Rectangle specifying the intended finished size of the page |
302             | | (for example, the dimensions of an A4 sheet of paper).In some |
303             | | cases,the MediaBox will be a larger rectangle, which includes |
304             | | printing instructions, cut marks or other content.The default |
305             | | is the value of the CropBox. [PDF 1.3]. |
306             | | |
307             | BleedBox | Rectangle specifying the region to which all page content |
308             | | should be clipped if the page is being output in a production |
309             | | environment. In such environments, a bleed area is desired, |
310             | | to accommodate physical limitations of cutting, folding, and |
311             | | trimming equipment. The actual printed page may include |
312             | | printer's marks that fall outside the bleed box. The default |
313             | | is the value of the CropBox.[PDF 1.3] |
314             | | |
315             | Rotate | Specifies the number of degrees the page should be rotated |
316             | | clockwise when it is displayed or printed. This value must be |
317             | | zero (the default) or a multiple of 90. The entire page, |
318             | | including contents is rotated. |
319             | | |
320             +-----------+---------------------------------------------------------------+
321              
322             Example:
323              
324             my $a4 = $pdf->new_page( 'MediaBox' => $pdf->get_page_size('A4') );
325              
326             my $page1 = $a4->new_page;
327             $page1->string($f1, 20, 306, 396, "some text on page 1");
328              
329             my $page2 = $a4->new_page;
330             $page2->string($f1, 20, 306, 396, "some text on page 2");
331              
332             =cut
333              
334             sub new_page {
335 51     51 1 10139 my ($self, %params) = @_;
336              
337 51         6684 my %valid_new_page_parameters = map { $_ => 1 } (qw/Parent Resources MediaBox CropBox ArtBox TrimBox BleedBox Rotate/);
  408         98586  
338 51         6114 foreach my $key (keys %params) {
339             croak "PDF::Create.pm - new_page(): Received invalid key [$key]"
340 51 100       12037 unless (exists $valid_new_page_parameters{$key});
341             }
342              
343 50   66     6223 my $parent = $params{'Parent'} || $self->{'pages'};
344 50         5966 my $name = "Page " . ++$self->{'page_count'};
345 50         6375 my $page = $parent->add( $self->reserve( $name, "Page" ), $name );
346 50 50       6373 $page->{'resources'} = $params{'Resources'} if defined $params{'Resources'};
347 50 100       6120 $page->{'mediabox'} = $params{'MediaBox'} if defined $params{'MediaBox'};
348 50 50       6027 $page->{'cropbox'} = $params{'CropBox'} if defined $params{'CropBox'};
349 50 50       6422 $page->{'artbox'} = $params{'ArtBox'} if defined $params{'ArtBox'};
350 50 50       6555 $page->{'trimbox'} = $params{'TrimBox'} if defined $params{'TrimBox'};
351 50 50       6338 $page->{'bleedbox'} = $params{'BleedBox'} if defined $params{'BleedBox'};
352 50 50       5969 $page->{'rotate'} = $params{'Rotate'} if defined $params{'Rotate'};
353              
354 50         5727 $self->{'current_page'} = $page;
355              
356 50         16135 $page;
357             }
358              
359             =head2 font(%params)
360              
361             Prepare a font using the given arguments. This font will be added to the document
362             only if it is used at least once before the close method is called.Parameters are
363             listed below:
364              
365             +----------+----------------------------------------------------------------+
366             | Key | Description |
367             +----------+----------------------------------------------------------------+
368             | Subtype | Type of font. PDF defines some types of fonts. It must be one |
369             | | of the predefined type Type1, Type3, TrueType or Type0.In this |
370             | | version, only Type1 is supported. This is the default value. |
371             | | |
372             | Encoding | Specifies the encoding from which the new encoding differs. |
373             | | It must be one of the predefined encodings MacRomanEncoding, |
374             | | MacExpertEncoding or WinAnsiEncoding. In this version, only |
375             | | WinAnsiEncoding is supported. This is the default value. |
376             | | |
377             | BaseFont | The PostScript name of the font. It can be one of the following|
378             | | base fonts: Courier, Courier-Bold, Courier-BoldOblique, |
379             | | Courier-Oblique, Helvetica, Helvetica-Bold, |
380             | | Helvetica-BoldOblique, Helvetica-Oblique, Times-Roman, |
381             | | Times-Bold, Times-Italic, Times-BoldItalic or Symbol. |
382             +----------+----------------------------------------------------------------+
383              
384             The ZapfDingbats font is not supported in this version.Default font is Helvetica.
385              
386             my $f1 = $pdf->font('BaseFont' => 'Helvetica');
387              
388             =cut
389              
390             sub font {
391 46     46 1 11888 my ($self, %params) = @_;
392              
393             my %valid_font_parameters = (
394 184         29939 'Subtype' => { map { $_ => 1 } qw/Type0 Type1 Type3 TrueType/ },
395 184         30239 'Encoding' => { map { $_ => 1 } qw/MacRomanEncoding MacExpertEncoding WinAnsiEncoding Symbol/ },
396 46         3763 'BaseFont' => { map { $_ => 1 } qw/Courier Courier-Bold Courier-BoldOblique Courier-Oblique
  598         95909  
397             Helvetica Helvetica-Bold Helvetica-BoldOblique Helvetica-Oblique
398             Times-Roman Times-Bold Times-Italic Times-BoldItalic Symbol/ },
399             );
400              
401 46         4068 foreach my $key (keys %params) {
402             croak "PDF::Create.pm - font(): Received invalid key [$key]"
403 128 100       11820 unless (exists $valid_font_parameters{$key});
404 127         11693 my $value = $params{$key};
405             croak "PDF::Create.pm - font(): Received invalid value [$value] for key [$key]"
406 127 100 66     15751 if (defined $value && !(exists $valid_font_parameters{$key}->{$value}));
407             }
408              
409 42         3708 my $num = 1 + scalar keys %{ $self->{'fonts'} };
  42         7580  
410             $self->{'fonts'}{$num} = {
411             'Subtype' => $self->name( $params{'Subtype'} || 'Type1' ),
412             'Encoding' => $self->name( $params{'Encoding'} || 'WinAnsiEncoding' ),
413 42   100     3913 'BaseFont' => $self->name( $params{'BaseFont'} || 'Helvetica' ),
      50        
      100        
414             'Name' => $self->name("F$num"),
415             'Type' => $self->name("Font"),
416             };
417              
418 42         8595 $num;
419             }
420              
421             =head2 new_outline(%params)
422              
423             Adds an outline to the document using the given parameters. Return the newly
424             created outline. Parameters can be:
425              
426             +-------------+-------------------------------------------------------------+
427             | Key | Description |
428             +-------------+-------------------------------------------------------------+
429             | | |
430             | Title | The title of the outline. Mandatory. |
431             | | |
432             | Destination | The Destination of this outline item. In this version,it is |
433             | | only possible to give a page as destination. The default |
434             | | destination is the current page. |
435             | | |
436             | Parent | The parent of this outline in the outlines tree. This is an |
437             | | outline object. This way you represent the tree of your |
438             | | outlines. |
439             | | |
440             +-------------+-------------------------------------------------------------+
441              
442             Example:
443              
444             my $outline = $pdf->new_outline('Title' => 'Item 1');
445             $pdf->new_outline('Title' => 'Item 1.1', 'Parent' => $outline);
446             $pdf->new_outline('Title' => 'Item 1.2', 'Parent' => $outline);
447             $pdf->new_outline('Title' => 'Item 2');
448              
449             =cut
450              
451             sub new_outline {
452 34     34 1 11525 my ($self, %params) = @_;
453              
454             croak "PDF::Create - new_outline(): Missing required key [Title]."
455 34 50       7623 unless (exists $params{'Title'});
456             croak "PDF::Create - new_outline(): Required key [Title] undefined."
457 34 50       7432 unless (defined $params{'Title'});
458              
459 34 100       7419 if (defined $params{Destination}) {
460             croak "PDF::Create - new_outline(): Invalid value for key [Destination]."
461 14 50       4405 unless (ref($params{Destination}) eq 'PDF::Create::Page');
462             }
463              
464 34 100       7516 if (defined $params{Parent}) {
465             croak "PDF::Create - new_outline(): Invalid value for key [Parent]."
466 18 50       8450 unless (ref($params{Parent}) eq 'PDF::Create::Outline');
467             }
468              
469 34 100       7403 unless ( defined $self->{'outlines'} ) {
470 9         2326 $self->{'outlines'} = PDF::Create::Outline->new();
471             # circular reference
472 9         2116 $self->{'outlines'}->{'pdf'} = $self;
473 9         2183 weaken $self->{'outlines'}->{'pdf'};
474 9         4523 $self->{'outlines'}->{'Status'} = 'opened';
475             }
476              
477 34   66     7404 my $parent = $params{'Parent'} || $self->{'outlines'};
478 34         7310 my $name = "Outline " . ++$self->{'outline_count'};
479 34 100       7405 $params{'Destination'} = $self->{'current_page'} unless defined $params{'Destination'};
480 34         7390 my $outline = $parent->add( $self->reserve( $name, "Outline" ), $name, %params );
481 34         20610 $outline;
482             }
483              
484             =head2 get_page_size($name)
485              
486             Returns the size of standard paper used for MediaBox-parameter of C.
487             C has one optional parameter to specify the paper name. Possible
488             values are a0-a6, a4l,letter,broadsheet,ledger,tabloid,legal,executive and 36x36.
489             Default is a4.
490              
491             my $root = $pdf->new_page( 'MediaBox' => $pdf->get_page_size('A4') );
492              
493             =cut
494              
495             sub get_page_size {
496 28     28 1 9041 my ($self, $name) = @_;
497              
498 28         450 my %pagesizes = (
499             'A0' => [ 0, 0, 2380, 3368 ],
500             'A1' => [ 0, 0, 1684, 2380 ],
501             'A2' => [ 0, 0, 1190, 1684 ],
502             'A3' => [ 0, 0, 842, 1190 ],
503             'A4' => [ 0, 0, 595, 842 ],
504             'A4L' => [ 0, 0, 842, 595 ],
505             'A5' => [ 0, 0, 421, 595 ],
506             'A6' => [ 0, 0, 297, 421 ],
507             'LETTER' => [ 0, 0, 612, 792 ],
508             'BROADSHEET' => [ 0, 0, 1296, 1584 ],
509             'LEDGER' => [ 0, 0, 1224, 792 ],
510             'TABLOID' => [ 0, 0, 792, 1224 ],
511             'LEGAL' => [ 0, 0, 612, 1008 ],
512             'EXECUTIVE' => [ 0, 0, 522, 756 ],
513             '36X36' => [ 0, 0, 2592, 2592 ],
514             );
515 28 50       91 if (defined $name) {
516 28         67 $name = uc($name);
517             # validate page size
518 28 100       143 croak "Invalid page size name '$name' received." unless (exists $pagesizes{$name});
519             }
520             else {
521 0         0 $name = 'A4';
522             }
523              
524 27         160 return $pagesizes{$name};
525             }
526              
527             =head2 version($number)
528              
529             Set and return version number. Valid version numbers are 1.0, 1.1, 1.2 and 1.3.
530              
531             =cut
532              
533             sub version {
534 5     5 1 10 my ($self, $v) = @_;
535              
536 5 50       7 if (defined $v) {
537 5 100       234 croak "ERROR: Invalid version number $v received.\n"
538             unless ($v =~ /^1\.[0,1,2,3]$/);
539 3         5 $self->{'version'} = $v;
540             }
541 3         8 $self->{'version'};
542             }
543              
544             =head2 close(%params)
545              
546             Close does the work of creating the PDF data from the objects collected before.
547             You must call C after you have added all the contents as most of the
548             real work building the PDF is performed there. If omit calling close you get
549             no PDF output. Returns the raw content of the PDF.
550             If C was provided when creating object of C then it does not
551             try to close the file handle. It is, therefore, advised you call C
552             rather than C.
553              
554             =cut
555              
556             sub close {
557 15     15 1 3911 my ($self, %params) = @_;
558              
559 15         1455 debug( 2, "Closing PDF" );
560 15         1389 my $raw_data = $self->flush;
561              
562 15 100 66     1271 if (defined $self->{'fh'} && defined $self->{'filename'}) {
563 14         1225 $self->{'fh'}->close;
564             }
565              
566 15         11891 return $raw_data;
567             }
568              
569             =head2 flush()
570              
571             Generate the PDF content and returns the raw content as it is.
572              
573             =cut
574              
575             sub flush {
576 15     15 1 1385 my ($self) = @_;
577              
578 15         1436 debug( 2, "Flushing PDF" );
579 15         1391 $self->page_stream;
580 15 100       1078 $self->add_outlines if defined $self->{'outlines'};
581 15         2095 $self->add_catalog;
582 15         1103 $self->add_pages;
583 15         1127 $self->add_info;
584 15         1586 $self->add_crossrefsection;
585 15         1130 $self->add_trailer;
586              
587 15         2406 return $self->{data};
588             }
589              
590             =head2 reserve($name, $type)
591              
592             Reserve the next object number for the given object type.
593              
594             =cut
595              
596             sub reserve {
597 227     227 1 26682 my ($self, $name, $type) = @_;;
598              
599 227 100       26198 $type = $name unless defined $type;
600              
601             confess "Error: an object has already been reserved using this name '$name' "
602 227 50       26131 if defined $self->{'reservations'}{$name};
603 227         26787 $self->{'object_number'}++;
604 227         27508 debug( 2, "reserve(): name=$name type=$type number=$self->{'object_number'} generation=$self->{'generation_number'}" );
605 227         27927 $self->{'reservations'}{$name} = [ $self->{'object_number'}, $self->{'generation_number'}, $type ];
606              
607              
608             # Annotations added here by Gary Lieberman.
609             #
610             # Store the Object ID and the Generation Number for later use when we write
611             # out the /Page object.
612 227 100       27486 if ($type eq 'Annotation') {
613 2         17 $self->{'Annots'}{ $self->{'object_number'} } = $self->{'generation_number'};
614             }
615              
616 227         55287 [ $self->{'object_number'}, $self->{'generation_number'} ];
617             }
618              
619             =head2 add_comment($message)
620              
621             Add comment to the document.The string will show up in the PDF as postscript-style
622             comment:
623              
624             % this is a postscript comment
625              
626             =cut
627              
628             sub add_comment {
629 7     7 1 4081 my ($self, $comment) = @_;
630              
631 7 50       35 $comment = '' unless defined $comment;
632 7         38 debug( 2, "add_comment(): $comment" );
633 7         36 $self->add( "%" . $comment );
634 7         22 $self->cr;
635             }
636              
637             =head2 annotation(%params)
638              
639             Adds an annotation object, for the time being we only do the 'Link' - 'URI' kind
640             This is a sensitive area in the PDF document where text annotations are shown or
641             links launched. C only supports URI links at this time.
642              
643             URI links have two components,the text or graphics object and the area where the
644             mouseclick should occur.
645              
646             For the object to be clicked on you'll use standard text of drawing methods. To
647             define the click-sensitive area and the destination URI.
648              
649             Example:
650              
651             # Draw a string and undeline it to show it is a link
652             $pdf->string($f1, 10, 450, 200, 'http://www.cpan.org');
653              
654             my $line = $pdf->string_underline($f1, 10, 450, 200, 'http://www.cpan.org');
655              
656             # Create the hot area with the link to open on click
657             $pdf->annotation(
658             Subtype => 'Link',
659             URI => 'http://www.cpan.org',
660             x => 450,
661             y => 200,
662             w => $l,
663             h => 15,
664             Border => [0,0,0]
665             );
666              
667             The point (x, y) is the bottom left corner of the rectangle containing hotspot
668             rectangle, (w, h) are the width and height of the hotspot rectangle. The Border
669             describes the thickness of the border surrounding the rectangle hotspot.
670              
671             The function C returns the width of the string, this can be used
672             directly for the width of the hotspot rectangle.
673              
674             =cut
675              
676             sub annotation {
677 2     2 1 18 my ($self, %params) = @_;
678              
679 2         15 debug( 2, "annotation(): Subtype=$params{'Subtype'}" );
680              
681 2 50       12 if ( $params{'Subtype'} eq 'Link' ) {
682 2 50       13 confess "Must specify 'URI' for Link" unless defined $params{'URI'};
683 2 50       9 confess "Must specify 'x' for Link" unless defined $params{'x'};
684 2 50       6 confess "Must specify 'y' for Link" unless defined $params{'y'};
685 2 50       7 confess "Must specify 'w' for Link" unless defined $params{'w'};
686 2 50       7 confess "Must specify 'h' for Link" unless defined $params{'h'};
687              
688 2         6 my $num = 1 + scalar keys %{ $self->{'annotations'} };
  2         9  
689              
690             my $action = {
691             'Type' => $self->name('Action'),
692             'S' => $self->name('URI'),
693 2         8 'URI' => $self->string( $params{'URI'} ),
694             };
695 2         8 my $x2 = $params{'x'} + $params{'w'};
696 2         6 my $y2 = $params{'y'} + $params{'h'};
697              
698             $self->{'annotations'}{$num} = {
699             'Subtype' => $self->name('Link'),
700 2         7 'Rect' => $self->verbatim( sprintf "[%f %f %f %f]", $params{'x'}, $params{'y'}, $x2, $y2 ),
701             'A' => $self->dictionary(%$action),
702             };
703              
704 2 50       11 if ( defined $params{'Border'} ) {
705             $self->{'annotations'}{$num}{'Border'} =
706 2         32 $self->verbatim( sprintf "[%f %f %f]", $params{'Border'}[0], $params{'Border'}[1], $params{'Border'}[2] );
707             }
708 2         93 $self->{'annot'}{$num}{'page_name'} = "Page " . $self->{'page_count'};
709 2         17 debug( 2, "annotation(): annotation number: $num, page name: $self->{'annot'}{$num}{'page_name'}" );
710 2         17 1;
711             } else {
712 0         0 confess "Only Annotations with Subtype 'Link' are supported for now\n";
713             }
714             }
715              
716             =head2 image($filename)
717              
718             Prepare an XObject (image) using the given arguments. This image will be added to
719             the document if it is referenced at least once before the close method is called.
720             In this version GIF,interlaced GIF and JPEG is supported. Usage of interlaced GIFs
721             are slower because they are decompressed, modified and compressed again. The gif
722             support is limited to images with a LZW minimum code size of 8. Small images with
723             few colors can have a smaller minimum code size and will not work. If you get
724             errors regarding JPEG compression, then the compression method used in your
725             JPEG file is not supported by C. Try resaving the JPEG file
726             with different compression options (for example, disable progressive
727             compression).
728              
729             Example:
730              
731             my $img = $pdf->image('image.jpg');
732              
733             $page->image(
734             image => $img,
735             xscale => 0.25, # scale image for better quality
736             yscale => 0.25,
737             xpos => 50,
738             ypos => 60,
739             xalign => 0,
740             yalign => 2,
741             );
742              
743             =cut
744              
745             sub image {
746 2     2 1 6 my ($self, $filename) = @_;
747              
748 2         3 my $num = 1 + scalar keys %{ $self->{'xobjects'} };
  2         6  
749              
750 2         5 my $image;
751             my $colorspace;
752 2         0 my @a;
753              
754 2 100 33     11 if ( $filename =~ /\.gif$/i ) {
    50          
755 1         11 $self->{'images'}{$num} = PDF::Image::GIF->new();
756             } elsif ( $filename =~ /\.jpg$/i || $filename =~ /\.jpeg$/i ) {
757 1         7 $self->{'images'}{$num} = PDF::Image::JPEG->new();
758             }
759              
760 2         3 $image = $self->{'images'}{$num};
761 2 50       6 if ( !$image->Open($filename) ) {
762 0         0 print $image->{error} . "\n";
763 0         0 return 0;
764             }
765              
766             $self->{'xobjects'}{$num} = {
767             'Subtype' => $self->name('Image'),
768             'Name' => $self->name("Image$num"),
769             'Type' => $self->name('XObject'),
770             'Width' => $self->number( $image->{width} ),
771             'Height' => $self->number( $image->{height} ),
772             'BitsPerComponent' => $self->number( $image->{bpc} ),
773             'Data' => $image->ReadData(),
774 2         6 'Length' => $self->number( $image->{imagesize} ),
775             };
776              
777             # Indexed colorspace?
778 2 100       7 if ($image->{colorspacesize}) {
779 1         7 $colorspace = $self->reserve("ImageColorSpace$num");
780              
781             $self->{'xobjects_colorspace'}{$num} = {
782             'Data' => $image->{colorspacedata},
783 1         3 'Length' => $self->number( $image->{colorspacesize} ),
784             };
785              
786 1         5 $self->{'xobjects'}{$num}->{'ColorSpace'} = $self->array( $self->name('Indexed'), $self->name( $image->{colorspace} ),
787             $self->number(255), $self->indirect_ref(@$colorspace) );
788             } else {
789 1         3 $self->{'xobjects'}{$num}->{'ColorSpace'} = $self->array( $self->name( $image->{colorspace} ) );
790             }
791              
792             # Set Filter
793 2         8 $#a = -1;
794 2         3 foreach my $s ( @{ $image->{filter} } ) {
  2         7  
795 2         3 push @a, $self->name($s);
796             }
797 2 50       5 if ( $#a >= 0 ) {
798 2         5 $self->{'xobjects'}{$num}->{'Filter'} = $self->array(@a);
799             }
800              
801             # Set additional DecodeParms
802 2         4 $#a = -1;
803 2         4 foreach my $s ( keys %{ $image->{decodeparms} } ) {
  2         8  
804 1         2 push @a, $s;
805 1         3 push @a, $self->number( $image->{decodeparms}{$s} );
806             }
807 2         6 $self->{'xobjects'}{$num}->{'DecodeParms'} = $self->array( $self->dictionary(@a) );
808              
809             # Transparent?
810 2 100       4 if ( $image->{transparent} ) {
811 1         3 $self->{'xobjects'}{$num}->{'Mask'} = $self->array( $self->number( $image->{mask} ), $self->number( $image->{mask} ) );
812             }
813              
814 2         15 return { 'num' => $num, 'width' => $image->{width}, 'height' => $image->{height} };
815             }
816              
817             sub add_outlines {
818 5     5 0 1019 my ($self, %params) = @_;
819              
820 5         991 debug( 2, "add_outlines" );
821 5         995 my $outlines = $self->reserve("Outlines");
822              
823 5         976 my ($First, $Last);
824 5         974 my @list = $self->{'outlines'}->list;
825 5         1362 my $i = -1;
826 5         1427 for my $outline (@list) {
827 30         7942 $i++;
828 30         7966 my $name = $outline->{'name'};
829 30 100       8794 $First = $outline->{'id'} unless defined $First;
830 30         8565 $Last = $outline->{'id'};
831 30         8963 my $content = { 'Title' => $self->string( $outline->{'Title'} ) };
832 30 100 50     8603 if ( defined $outline->{'Kids'} && scalar @{ $outline->{'Kids'} } ) {
  30         16688  
833 9         2160 my $t = $outline->{'Kids'};
834 9         2066 $$content{'First'} = $self->indirect_ref( @{ $$t[0]->{'id'} } );
  9         4042  
835 9         2020 $$content{'Last'} = $self->indirect_ref( @{ $$t[$#$t]->{'id'} } );
  9         4112  
836             }
837 30         7968 my $brothers = $outline->{'Parent'}->{'Kids'};
838 30         8873 my $j = -1;
839 30         8959 for my $brother (@$brothers) {
840 53         13566 $j++;
841 53 100       21412 last if $brother == $outline;
842             }
843 30 100       8439 $$content{'Next'} = $self->indirect_ref( @{ $$brothers[ $j + 1 ]->{'id'} } )
  16         9464  
844             if $j < $#$brothers;
845 30 100       7063 $$content{'Prev'} = $self->indirect_ref( @{ $$brothers[ $j - 1 ]->{'id'} } )
  16         6557  
846             if $j;
847             $outline->{'Parent'}->{'id'} = $outlines
848 30 100       6900 unless defined $outline->{'Parent'}->{'id'};
849 30         6711 $$content{'Parent'} = $self->indirect_ref( @{ $outline->{'Parent'}->{'id'} } );
  30         13292  
850             $$content{'Dest'} =
851 30         6169 $self->array( $self->indirect_ref( @{ $outline->{'Dest'}->{'id'} } ),
  30         12670  
852             $self->name('Fit'), $self->null, $self->null, $self->null );
853 30         7019 my $count = $outline->count;
854 30 100       6785 $$content{'Count'} = $self->number($count) if $count;
855 30         6965 my $t = $self->add_object( $self->indirect_obj( $self->dictionary(%$content), $name ) );
856 30         7103 $self->cr;
857             }
858              
859             # Type (required)
860 5         1039 my $content = { 'Type' => $self->name('Outlines') };
861              
862             # Count
863 5         1484 my $count = $self->{'outlines'}->count;
864 5 50       1034 $$content{'Count'} = $self->number($count) if $count;
865 5         1019 $$content{'First'} = $self->indirect_ref(@$First);
866 5         1014 $$content{'Last'} = $self->indirect_ref(@$Last);
867 5         1029 $self->add_object( $self->indirect_obj( $self->dictionary(%$content) ) );
868 5         1402 $self->cr;
869             }
870              
871             sub add_pages {
872 15     15 0 1058 my ($self) = @_;
873              
874 15         1063 debug( 2, "add_pages():" );
875              
876             # Type (required)
877 15         1062 my $content = { 'Type' => $self->name('Pages') };
878              
879             # Kids (required)
880 15         1464 my $t = $self->{'pages'}->kids;
881 15 50       1408 confess "Error: document MUST contains at least one page. Abort."
882             unless scalar @$t;
883              
884 15         1378 my $kids = [];
885 15         1429 map { push @$kids, $self->indirect_ref(@$_) } @$t;
  15         1404  
886 15         1425 $$content{'Kids'} = $self->array(@$kids);
887 15         1823 $$content{'Count'} = $self->number( $self->{'pages'}->count );
888 15         1103 $self->add_object( $self->indirect_obj( $self->dictionary(%$content) ) );
889 15         1104 $self->cr;
890              
891 15         1098 for my $font ( sort keys %{ $self->{'fonts'} } ) {
  15         2132  
892 34         2210 debug( 2, "add_pages(): font: $font" );
893 34         2259 $self->{'fontobj'}{$font} = $self->reserve('Font');
894 34         2487 $self->add_object( $self->indirect_obj( $self->dictionary( %{ $self->{'fonts'}{$font} } ), 'Font' ) );
  34         5232  
895 34         2292 $self->cr;
896             }
897              
898 15         1068 for my $xobject (sort keys %{$self->{'xobjects'}}) {
  15         2160  
899 2         7 debug( 2, "add_pages(): xobject: $xobject" );
900 2         4 $self->{'xobj'}{$xobject} = $self->reserve('XObject');
901 2         3 $self->add_object( $self->indirect_obj( $self->stream( %{ $self->{'xobjects'}{$xobject} } ), 'XObject' ) );
  2         10  
902 2         10 $self->cr;
903              
904 2 100       8 if ( defined $self->{'reservations'}{"ImageColorSpace$xobject"}) {
905             $self->add_object(
906 1         3 $self->indirect_obj( $self->stream( %{ $self->{'xobjects_colorspace'}{$xobject} } ), "ImageColorSpace$xobject" ) );
  1         16  
907 1         4 $self->cr;
908             }
909             }
910              
911 15         1085 for my $annotation (sort keys %{$self->{'annotations'}}) {
  15         2112  
912 2         7 $self->{'annot'}{$annotation}{'object_info'} = $self->reserve('Annotation');
913 2         6 $self->add_object( $self->indirect_obj( $self->dictionary( %{ $self->{'annotations'}{$annotation} } ), 'Annotation' ) );
  2         13  
914 2         13 $self->cr;
915             }
916              
917 15         1273 for my $page ($self->{'pages'}->list) {
918 38         3281 my $name = $page->{'name'};
919 38         3565 debug( 2, "add_pages: page: $name" );
920 38 100 50     3332 my $type = 'Page' . ( defined $page->{'Kids'} && scalar @{ $page->{'Kids'} } ? 's' : '' );
921              
922             # Type (required)
923 38         3312 my $content = { 'Type' => $self->name($type) };
924              
925             # Resources (required, may be inherited). See page 195.
926 38         3282 my $resources = {};
927 38         3243 for my $k ( keys %{ $page->{'resources'} } ) {
  38         6608  
928 39         2213 my $v = $page->{'resources'}{$k};
929             ( $k eq 'ProcSet' ) && do {
930 19         1115 my $l = [];
931 19 50       1128 if ( ref($v) eq 'ARRAY' ) {
932 19         1142 map { push @$l, $self->name($_) } @$v;
  38         2177  
933             } else {
934 0         0 push @$l, $self->name($v);
935             }
936 19         1112 $$resources{'ProcSet'} = $self->array(@$l);
937             }
938             || ( $k eq 'fonts' ) && do {
939 19         1095 my $l = {};
940 19         1064 map { $$l{"F$_"} = $self->indirect_ref( @{ $self->{'fontobj'}{$_} } ); } keys %{ $page->{'resources'}{'fonts'} };
  37         2142  
  37         4290  
  19         2133  
941 19         1115 $$resources{'Font'} = $self->dictionary(%$l);
942             }
943 39 100 33     2307 || ( $k eq 'xobjects' ) && do {
      66        
      66        
      100        
944 1         2 my $l = {};
945 2         3 map { $$l{"Image$_"} = $self->indirect_ref( @{ $self->{'xobj'}{$_} } ); }
  2         3  
946 1         2 keys %{ $page->{'resources'}{'xobjects'} };
  1         3  
947 1         4 $$resources{'XObject'} = $self->dictionary(%$l);
948             };
949             }
950 38 50       3280 if ( defined( $$resources{'Annotation'} ) ) {
951 0         0 my $r = $self->add_object( $self->indirect_obj( $self->dictionary(%$resources) ) );
952 0         0 $self->cr;
953 0         0 $$content{'Resources'} = [ 'ref', [ $$r[0], $$r[1] ] ];
954             }
955 38 100       3271 if ( defined( $$resources{'XObject'} ) ) {
956 1         3 my $r = $self->add_object( $self->indirect_obj( $self->dictionary(%$resources) ) );
957 1         5 $self->cr;
958 1         3 $$content{'Resources'} = [ 'ref', [ $$r[0], $$r[1] ] ];
959             } else {
960 37 100       5524 $$content{'Resources'} = $self->dictionary(%$resources)
961             if scalar keys %$resources;
962             }
963 38         3240 for my $K ( 'MediaBox', 'CropBox', 'ArtBox', 'TrimBox', 'BleedBox' ) {
964 190         16230 my $k = lc $K;
965 190 100       19525 if ( defined $page->{$k} ) {
966 15         1047 my $l = [];
967 15         1050 map { push @$l, $self->number($_) } @{ $page->{$k} };
  60         5082  
  15         2551  
968 15         1089 $$content{$K} = $self->array(@$l);
969             }
970             }
971 38 50       3358 $$content{'Rotate'} = $self->number( $page->{'rotate'} ) if defined $page->{'rotate'};
972 38 100       3310 if ( $type eq 'Page' ) {
973 24         2179 $$content{'Parent'} = $self->indirect_ref( @{ $page->{'Parent'}{'id'} } );
  24         4368  
974              
975             # Content
976 24 100       2208 if ( defined $page->{'contents'} ) {
977 23         2503 my $contents = [];
978 23         2167 map { push @$contents, $self->indirect_ref(@$_); } @{ $page->{'contents'} };
  27         3284  
  23         4298  
979 23         2214 $$content{'Contents'} = $self->array(@$contents);
980             }
981              
982             # Annotations added here by Gary Lieberman
983             #
984             # Tell the /Page object that annotations need to be drawn.
985 24 100       4374 if ( defined $self->{'annot'} ) {
986 1         3 my $Annots = '[ ';
987 1         3 my $is_annots = 0;
988 1         3 foreach my $annot_number ( keys %{ $self->{'annot'} } ) {
  1         5  
989 2 50       13 next if ( $self->{'annot'}{$annot_number}{'page_name'} ne $name );
990 2         3 $is_annots = 1;
991 2         17 debug( 2,
992             sprintf "annotation number: $annot_number, page name: $self->{'annot'}{$annot_number}{'page_name'}" );
993 2         6 my $object_number = $self->{'annot'}{$annot_number}{'object_info'}[0];
994 2         5 my $generation_number = $self->{'annot'}{$annot_number}{'object_info'}[1];
995 2         13 debug( 2, sprintf "object_number: $object_number, generation_number: $generation_number" );
996 2         14 $Annots .= sprintf( "%s %s R ", $object_number, $generation_number );
997             }
998 1 50       15 $$content{'Annots'} = $self->verbatim( $Annots . ']' ) if ($is_annots);
999             }
1000             } else {
1001 14         1067 my $kids = [];
1002 14         1049 map { push @$kids, $self->indirect_ref(@$_) } @{ $page->kids };
  23         2159  
  14         1138  
1003 14         1147 $$content{'Kids'} = $self->array(@$kids);
1004 14         2105 $$content{'Parent'} = $self->indirect_ref( @{ $page->{'Parent'}{'id'} } )
1005 14 50       1083 if defined $page->{'Parent'};
1006 14         1077 $$content{'Count'} = $self->number( $page->count );
1007             }
1008 38         3760 $self->add_object( $self->indirect_obj( $self->dictionary(%$content), $name ) );
1009 38         3833 $self->cr;
1010             }
1011             }
1012              
1013             sub add_crossrefsection {
1014 15     15 0 1540 my ($self) = @_;
1015              
1016 15         1592 debug( 2, "add_crossrefsection():" );
1017              
1018             # ::=
1019             # xref
1020             # +
1021 15         1121 $self->{'crossrefstartpoint'} = $self->position;
1022 15         1148 $self->add('xref');
1023 15         1136 $self->cr;
1024             confess "Fatal error: should contains at least one cross reference subsection."
1025 15 50       1202 unless defined $self->{'crossrefsubsection'};
1026 15         1178 for my $subsection ( sort keys %{ $self->{'crossrefsubsection'} } ) {
  15         2412  
1027 15         1255 $self->add_crossrefsubsection($subsection);
1028             }
1029             }
1030              
1031             sub add_crossrefsubsection {
1032 15     15 0 1176 my ($self, $subsection) = @_;
1033              
1034 15         1188 debug( 2, "add_crossrefsubsection():" );
1035              
1036             # ::=
1037             #
1038             #
1039             # +
1040             #
1041             # ::= |
1042             #
1043             # ::= n
1044             #
1045             # ::=
1046             # |
1047             # |
1048             #
1049             # ::=
1050             #
1051             # f
1052              
1053 15         1187 $self->add( 0, ' ', 1 + scalar @{ $self->{'crossrefsubsection'}{$subsection} } );
  15         2344  
1054 15         1233 $self->cr;
1055 15         1191 $self->add( sprintf "%010d %05d %s ", 0, 65535, 'f' );
1056 15         1225 $self->cr;
1057 15         1148 for my $entry ( sort { $$a[0] <=> $$b[0] } @{ $self->{'crossrefsubsection'}{$subsection} } ) {
  551         146097  
  15         2369  
1058 212 50       26306 $self->add( sprintf "%010d %05d %s ", $$entry[1], $subsection, $$entry[2] ? 'n' : 'f' );
1059              
1060             # printf "%010d %010x %05d n\n", $$entry[1], $$entry[1], $subsection;
1061 212         26424 $self->cr;
1062             }
1063             }
1064              
1065             sub add_trailer {
1066 15     15 0 1097 my $self = shift;
1067              
1068 15         1142 debug( 2, "add_trailer():" );
1069              
1070             # ::= trailer
1071             # <<
1072             # +
1073             # >>
1074             # startxref
1075             #
1076             # %%EOF
1077              
1078 15         1165 my @keys = (
1079             'Size', # integer (required)
1080             'Prev', # integer (req only if more than one cross-ref section)
1081             'Root', # dictionary (required)
1082             'Info', # dictionary (optional)
1083             'ID', # array (optional) (PDF 1.1)
1084             'Encrypt' # dictionary (req if encrypted) (PDF 1.1)
1085             );
1086              
1087             # TODO: should check for required fields
1088 15         1125 $self->add('trailer');
1089 15         1195 $self->cr;
1090 15         1182 $self->add('<<');
1091 15         1178 $self->cr;
1092 15         1660 $self->{'trailer'}{'Size'} = 1;
1093 15         1597 map { $self->{'trailer'}{'Size'} += scalar @{ $self->{'crossrefsubsection'}{$_} } } keys %{ $self->{'crossrefsubsection'} };
  15         1878  
  15         5066  
  15         3200  
1094 15         1630 $self->{'trailer'}{'Root'} = &encode( @{ $self->indirect_ref( @{ $self->{'catalog'} } ) } );
  15         2250  
  15         2987  
1095 15         1161 $self->{'trailer'}{'Info'} = &encode( @{ $self->indirect_ref( @{ $self->{'info'} } ) } )
  15         3001  
1096 15 50       1376 if defined $self->{'info'};
1097              
1098 15         1179 for my $k (@keys) {
1099 90 100       10740 next unless defined $self->{'trailer'}{$k};
1100             $self->add( "/$k ",
1101 45 50       3628 ref $self->{'trailer'}{$k} eq 'ARRAY' ? join( ' ', @{ $self->{'trailer'}{$k} } ) : $self->{'trailer'}{$k} );
  0         0  
1102 45         3899 $self->cr;
1103             }
1104 15         1198 $self->add('>>');
1105 15         1521 $self->cr;
1106 15         1405 $self->add('startxref');
1107 15         1185 $self->cr;
1108 15         1222 $self->add( $self->{'crossrefstartpoint'} );
1109 15         1871 $self->cr;
1110 15         1521 $self->add('%%EOF');
1111 15         1575 $self->cr;
1112             }
1113              
1114             sub cr {
1115 1564     1564 0 119463 my ($self) = @_;
1116              
1117 1564         120840 debug( 3, "cr():" );
1118 1564         118081 $self->add( &encode('cr') );
1119             }
1120              
1121             sub page_stream {
1122 562     562 0 8268 my ($self, $page) = @_;
1123              
1124 562         7971 debug( 2, "page_stream():" );
1125              
1126 562 100       7842 if (defined $self->{'reservations'}{'stream_length'}) {
1127             ## If it is the same page, use the same stream.
1128             $self->cr, return
1129             if defined $page
1130             && defined $self->{'stream_page'}
1131             && $page == $self->{'current_page'}
1132 547 100 66     9078 && $self->{'stream_page'} == $page;
      100        
      100        
1133              
1134             # Remember the position
1135 27         3634 my $len = $self->position - $self->{'stream_pos'} + 1;
1136              
1137             # Close the stream and the object
1138 27         3331 $self->cr;
1139 27         3869 $self->add('endstream');
1140 27         4162 $self->cr;
1141 27         3090 $self->add('endobj');
1142 27         3042 $self->cr;
1143 27         3239 $self->cr;
1144              
1145             # Add the length
1146 27         3323 $self->add_object( $self->indirect_obj( $self->number($len), 'stream_length' ) );
1147 27         3118 $self->cr;
1148             }
1149              
1150             # open a new stream if needed
1151 42 100       5058 if (defined $page) {
1152              
1153             # get an object id for the stream
1154 27         3022 my $obj = $self->reserve('stream');
1155              
1156             # release it
1157 27         3059 delete $self->{'reservations'}{'stream'};
1158              
1159             # get another one for the length of this stream
1160 27         3075 my $stream_length = $self->reserve('stream_length');
1161 27         3057 push @$stream_length, 'R';
1162 27         3048 push @{ $page->{'contents'} }, $obj;
  27         6865  
1163              
1164             # write the beginning of the object
1165 27         3223 push @{ $self->{'crossrefsubsection'}{ $$obj[1] } }, [ $$obj[0], $self->position, 1 ];
  27         6367  
1166 27         3455 $self->add("$$obj[0] $$obj[1] obj");
1167 27         3285 $self->cr;
1168 27         3254 $self->add('<<');
1169 27         3034 $self->cr;
1170 27         3294 $self->add( '/Length ', join( ' ', @$stream_length ) );
1171 27         3485 $self->cr;
1172 27         3074 $self->add('>>');
1173 27         2971 $self->cr;
1174 27         3027 $self->add('stream');
1175 27         3326 $self->cr;
1176 27         3369 $self->{'stream_pos'} = $self->position;
1177 27         11108 $self->{'stream_page'} = $page;
1178             }
1179             }
1180              
1181             =head2 get_data()
1182              
1183             If you did not ask the $pdf object to write its output to a file, you can pick up
1184             the pdf code by calling this method. It returns a big string. You need to call
1185             C first.
1186              
1187             =cut
1188              
1189             sub get_data {
1190 0     0 1 0 shift->{'data'};
1191             }
1192              
1193             sub uses_font {
1194 86     86 0 3543 my ($self, $page, $font) = @_;
1195              
1196 86         3575 $page->{'resources'}{'fonts'}{$font} = 1;
1197 86         3556 $page->{'resources'}{'ProcSet'} = [ 'PDF', 'Text' ];
1198 86         6959 $self->{'fontobj'}{$font} = 1;
1199             }
1200              
1201             sub uses_xobject {
1202 2     2 0 5 my ($self, $page, $xobject) = @_;
1203              
1204 2         6 $page->{'resources'}{'xobjects'}{$xobject} = 1;
1205 2         8 $page->{'resources'}{'ProcSet'} = [ 'PDF', 'Text' ];
1206 2         10 $self->{'xobj'}{$xobject} = 1;
1207             }
1208              
1209             sub debug {
1210 9204     9204 0 862025 my ($level, $msg) = @_;
1211              
1212 9204 50       2347597 return unless ( $DEBUG >= $level );
1213 0 0       0 my $s = scalar @_ ? sprintf $msg, @_ : $msg;
1214              
1215 0         0 warn "DEBUG ($level): $s\n";
1216             }
1217              
1218             sub add {
1219 2924     2924 0 209016 my $self = shift;
1220 2924         210606 my $data = join '', @_;
1221              
1222 2924         210915 $self->{'size'} += length $data;
1223 2924 100       210848 if ( defined $self->{'fh'} ) {
1224 2914         209911 my $fh = $self->{'fh'};
1225 2914         772606 print $fh $data;
1226             } else {
1227 10         16 $self->{'data'} .= $data;
1228             }
1229             }
1230              
1231             sub position {
1232 466     466 0 51981 my ($self) = @_;
1233              
1234 466         104812 $self->{'size'};
1235             }
1236              
1237             sub add_version {
1238 32     32 0 3432 my ($self) = @_;
1239              
1240 32         3638 debug( 2, "add_version(): $self->{'version'}" );
1241 32         3858 $self->add( "%PDF-" . $self->{'version'} );
1242 32         3835 $self->cr;
1243             }
1244              
1245             sub add_object {
1246 185     185 0 19852 my ($self, $v) = @_;
1247              
1248 185         19763 my $val = &encode(@$v);
1249 185         20403 $self->add($val);
1250 185         19901 $self->cr;
1251 185         21861 debug( 3, "add_object(): $v -> $val" );
1252 185         41468 [ $$v[1][0], $$v[1][1] ];
1253             }
1254              
1255             sub null {
1256 90     90 0 20530 my ($self) = @_;;
1257              
1258 90         41728 [ 'null', 'null' ];
1259             }
1260              
1261             sub boolean {
1262 0     0 0 0 my ($self, $val) = @_;
1263              
1264 0         0 [ 'boolean', $val ];
1265             }
1266              
1267             sub number {
1268 143     143 0 14036 my ($self, $val) = @_;;
1269              
1270 143         33113 [ 'number', $val ];
1271             }
1272              
1273             sub name {
1274 396     396 0 37132 my ($self, $val) = @_;
1275              
1276 396         79384 [ 'name', $val ];
1277             }
1278              
1279             sub string {
1280 73     73 0 12227 my ($self, $val) = @_;
1281              
1282 73         24038 [ 'string', $val ];
1283             }
1284              
1285             sub verbatim {
1286 5     5 0 16 my ($self, $val) = @_;
1287              
1288 5         34 [ 'verbatim', $val ];
1289             }
1290              
1291             sub array {
1292 123     123 0 13895 my $self = shift;
1293              
1294 123         34193 [ 'array', [@_] ];
1295             }
1296              
1297             sub dictionary {
1298 197     197 0 19509 my $self = shift;
1299              
1300 197         41676 [ 'dictionary', {@_} ];
1301             }
1302              
1303             sub indirect_obj {
1304 185     185 0 20799 my $self = shift;
1305              
1306 185         20467 my ($id, $gen, $type, $name);
1307 185         20454 $name = $_[1];
1308             $type = $_[0][1]{'Type'}[1]
1309 185 100 66     21309 if defined $_[0][1] && ref $_[0][1] eq 'HASH' && defined $_[0][1]{'Type'};
      100        
1310              
1311 185 100 66     20561 if ( defined $name && defined $self->{'reservations'}{$name} ) {
    100 66        
1312 134         15482 ( $id, $gen ) = @{ $self->{'reservations'}{$name} };
  134         31411  
1313 134         31397 delete $self->{'reservations'}{$name};
1314             } elsif ( defined $type && defined $self->{'reservations'}{$type} ) {
1315 50         4229 ( $id, $gen ) = @{ $self->{'reservations'}{$type} };
  50         8329  
1316 50         8825 delete $self->{'reservations'}{$type};
1317             } else {
1318 1         2 $id = ++$self->{'object_number'};
1319 1         2 $gen = $self->{'generation_number'};
1320             }
1321 185         20677 debug( 3, "indirect_obj(): " . $self->position );
1322 185         20258 push @{ $self->{'crossrefsubsection'}{$gen} }, [ $id, $self->position, 1 ];
  185         40379  
1323 185         40020 [ 'object', [ $id, $gen, @_ ] ];
1324             }
1325              
1326             sub indirect_ref {
1327 313     313 0 44945 my $self = shift;
1328              
1329 313         101059 [ 'ref', [@_] ];
1330             }
1331              
1332             sub stream {
1333 3     3 0 4 my $self = shift;
1334              
1335 3         15 [ 'stream', {@_} ];
1336             }
1337              
1338             sub add_info {
1339 15     15 0 1080 my $self = shift;
1340              
1341 15         1134 debug( 2, "add_info():" );
1342 15         1109 my %params = @_;
1343 15 100       1118 $params{'Author'} = $self->{'Author'} if defined $self->{'Author'};
1344 15 50       1092 $params{'Creator'} = $self->{'Creator'} if defined $self->{'Creator'};
1345 15 100       1156 $params{'Title'} = $self->{'Title'} if defined $self->{'Title'};
1346 15 50       1104 $params{'Subject'} = $self->{'Subject'} if defined $self->{'Subject'};
1347 15 50       1097 $params{'Keywords'} = $self->{'Keywords'} if defined $self->{'Keywords'};
1348             $params{'CreationDate'} = $self->{'CreationDate'}
1349 15 50       1091 if defined $self->{'CreationDate'};
1350              
1351 15         1120 $self->{'info'} = $self->reserve('Info');
1352 15         1142 my $content = {
1353             'Producer' => $self->string("PDF::Create version $VERSION"),
1354             'Type' => $self->name('Info')
1355             };
1356             $$content{'Author'} = $self->string( $params{'Author'} )
1357 15 100       1134 if defined $params{'Author'};
1358             $$content{'Creator'} = $self->string( $params{'Creator'} )
1359 15 50       1106 if defined $params{'Creator'};
1360             $$content{'Title'} = $self->string( $params{'Title'} )
1361 15 100       1141 if defined $params{'Title'};
1362             $$content{'Subject'} = $self->string( $params{'Subject'} )
1363 15 50       1109 if defined $params{'Subject'};
1364             $$content{'Keywords'} = $self->string( $params{'Keywords'} )
1365 15 50       1103 if defined $params{'Keywords'};
1366             $$content{'CreationDate'} = $self->string( $params{'CreationDate'} )
1367 15 50       1143 if defined $params{'CreationDate'};
1368              
1369 15         1137 $self->add_object( $self->indirect_obj( $self->dictionary(%$content) ), 'Info' );
1370 15         1231 $self->cr;
1371             }
1372              
1373             sub add_catalog {
1374 15     15 0 2017 my $self = shift;
1375              
1376 15         2271 debug( 2, "add_catalog" );
1377 15         1494 my %params = %{ $self->{'catalog'} };
  15         3058  
1378              
1379             # Type (mandatory)
1380 15         1576 $self->{'catalog'} = $self->reserve('Catalog');
1381 15         1115 my $content = { 'Type' => $self->name('Catalog') };
1382              
1383             # Pages (mandatory) [indirected reference]
1384 15         1151 my $pages = $self->reserve('Pages');
1385 15         1140 $$content{'Pages'} = $self->indirect_ref(@$pages);
1386 15         1097 $self->{'pages'}{'id'} = $$content{'Pages'}[1];
1387              
1388             # Outlines [indirected reference]
1389 5         2103 $$content{'Outlines'} = $self->indirect_ref( @{ $self->{'outlines'}->{'id'} } )
1390 15 100       1120 if defined $self->{'outlines'};
1391              
1392             # PageMode
1393 15 100       1114 $$content{'PageMode'} = $self->name($params{'PageMode'}) if defined $params{'PageMode'};
1394              
1395 15         1112 $self->add_object( $self->indirect_obj( $self->dictionary(%$content) ) );
1396 15         1091 $self->cr;
1397             }
1398              
1399             sub encode {
1400 6203     6203 0 669506 my ($type, $val) = @_;
1401              
1402 6203 100       642424 if ($val) {
1403 2748         319871 debug( 4, "encode(): $type $val" );
1404             } else {
1405 3455         331037 debug( 4, "encode(): $type (no val)" );
1406             }
1407              
1408 6203 100       648567 if (!$type) {
1409 1         221 cluck "PDF::Create::encode: empty argument, called by ";
1410 1         10 return 1;
1411             }
1412              
1413             ( $type eq 'null' || $type eq 'number' ) && do {
1414 1243         330048 1; # do nothing
1415             }
1416             || $type eq 'cr' && do {
1417 2915         515824 $val = "\n";
1418             }
1419             || $type eq 'boolean' && do {
1420 4 100       31 $val =
    100          
    100          
1421             $val eq 'true' ? $val
1422             : $val eq 'false' ? $val
1423             : $val eq '0' ? 'false'
1424             : 'true';
1425             }
1426             || $type eq 'verbatim' && do {
1427 8         44 $val = "$val";
1428             }
1429             || $type eq 'string' && do {
1430 77 100       10123 $val = '' if not defined $val;
1431             # TODO: split it. Quote parentheses.
1432 77         20665 $val = "($val)";
1433             }
1434             || $type eq 'number' && do {
1435 0         0 $val = "$val";
1436             }
1437             || $type eq 'name' && do {
1438 1128 100       110751 $val = '' if not defined $val;
1439 1128         221769 $val = "/$val";
1440             }
1441             || $type eq 'array' && do {
1442              
1443             # array, encode contents individually
1444 125         13471 my $s = '[';
1445 125         13607 for my $v (@$val) {
1446 327         14626 $s .= &encode( $$v[0], $$v[1] ) . " ";
1447             }
1448             # remove the trailing space
1449 125         14662 chop $s;
1450 125         28153 $val = $s . "]";
1451             }
1452             || $type eq 'dictionary' && do {
1453 197         19381 my $s = '<<' . &encode('cr');
1454 197         18830 for my $v ( keys %$val ) {
1455 743         82908 $s .= &encode( 'name', $v ) . " ";
1456 743         80279 $s .= &encode( ${ $$val{$v} }[0], ${ $$val{$v} }[1] ); # . " ";
  743         156542  
  743         157904  
1457 743         83865 $s .= &encode('cr');
1458             }
1459 197         40033 $val = $s . ">>";
1460             }
1461             || $type eq 'object' && do {
1462 186         19913 my $s = &encode( 'number', $$val[0] ) . " " . &encode( 'number', $$val[1] ) . " obj";
1463 186         20917 $s .= &encode('cr');
1464 186         20870 $s .= &encode( $$val[2][0], $$val[2][1] ); # . " ";
1465 186         20381 $s .= &encode('cr');
1466 186         40380 $val = $s . "endobj";
1467             }
1468             || $type eq 'ref' && do {
1469 315         44093 my $s = &encode( 'number', $$val[0] ) . " " . &encode( 'number', $$val[1] ) . " R";
1470 315         90185 $val = $s;
1471             }
1472 6202 100 100     679403 || $type eq 'stream' && do {
      66        
      66        
      100        
      66        
      100        
      66        
      100        
      66        
      100        
      33        
      66        
      66        
      66        
      100        
      100        
      100        
      100        
      100        
      100        
      66        
      100        
      66        
      100        
1473 3         6 my $data = delete $$val{'Data'};
1474 3         6 my $s = '<<' . &encode('cr');
1475 3         10 for my $v ( keys %$val ) {
1476 22         32 $s .= &encode( 'name', $v ) . " ";
1477 22         26 $s .= &encode( ${ $$val{$v} }[0], ${ $$val{$v} }[1] ); # . " ";
  22         31  
  22         28  
1478 22         30 $s .= &encode('cr');
1479             }
1480 3         6 $s .= ">>" . &encode('cr') . "stream" . &encode('cr');
1481 3         7 $s .= $data . &encode('cr');
1482 3         17 $val = $s . "endstream" . &encode('cr');
1483             }
1484             || confess "Error: unknown type '$type'";
1485              
1486             # TODO: add type 'text';
1487 6201         1314133 $val;
1488             }
1489              
1490             =head1 LIMITATIONS
1491              
1492             C comes with a couple of limitations or known caveats:
1493              
1494             =head2 PDF Size / Memory
1495              
1496             Unless using a filehandle, C assembles the entire PDF in memory.
1497             If you create very large documents on a machine with a small amount of memory
1498             your program can fail because it runs out of memory. If using a filehandle,
1499             data will be written immediately to the filehandle after each method.
1500              
1501             =head2 Small GIF images
1502              
1503             Some gif images get created with a minimal lzw code size of less than 8. C
1504             can not decode those and they must be converted.
1505              
1506             =head1 SUPPORT
1507              
1508             I support C in my spare time between work and family, so the amount
1509             of work I put in is limited.
1510              
1511             If you experience a problem make sure you are at the latest version first many of
1512             things have already been fixed.
1513              
1514             Please register bug at the CPAN bug tracking system at L or
1515             send email to C
1516              
1517             Be sure to include the following information:
1518              
1519             =over 4
1520              
1521             =item - PDF::Create Version you are running
1522              
1523             =item - Perl version (perl -v)
1524              
1525             =item - Operating System vendor and version
1526              
1527             =item - Details about your operating environment that might be related to the issue
1528             being described
1529              
1530             =item - Exact cut and pasted error or warning messages
1531              
1532             =item - The shortest, clearest code you can manage to write which reproduces the
1533             bug described.
1534              
1535             =back
1536              
1537             I appreciate patches against the latest released version of C which
1538             fix the bug.
1539              
1540             B can be submitted like bugs. If you provide patch for a feature
1541             which does not go against the C philosophy (keep it simple) then you
1542             have a good chance for it to be accepted.
1543              
1544             =head1 SEE ALSO
1545              
1546             L
1547              
1548             L Routines to produce formatted pages of mailing labels in PDF, uses L internally.
1549              
1550             L Perl interface to Haru Free PDF Library.
1551              
1552             L PDF creation from a one-file module, similar to L.
1553              
1554             L Yet another PDF creation module
1555              
1556             L A wrapper written for L.
1557              
1558             =head1 AUTHORS
1559              
1560             Fabien Tassin
1561              
1562             GIF and JPEG-support: Michael Gross (info@mdgrosse.net)
1563              
1564             Maintenance since 2007: Markus Baertschi (markus@markus.org)
1565              
1566             Currently maintained by Mohammad S Anwar (MANWAR) C<< >>
1567              
1568             =head1 REPOSITORY
1569              
1570             L
1571              
1572             =head1 COPYRIGHT
1573              
1574             Copyright 1999-2001,Fabien Tassin.All rights reserved.It may be used and modified
1575             freely, but I do request that this copyright notice remain attached to the file.
1576             You may modify this module as you wish,but if you redistribute a modified version
1577             , please attach a note listing the modifications you have made.
1578              
1579             Copyright 2007 Markus Baertschi
1580              
1581             Copyright 2010 Gary Lieberman
1582              
1583             =head1 LICENSE
1584              
1585             This is free software; you can redistribute it and / or modify it under the same
1586             terms as Perl 5.6.0.
1587              
1588             =cut
1589              
1590             1;