File Coverage

blib/lib/PDF/Create.pm
Criterion Covered Total %
statement 601 618 97.2
branch 182 234 77.7
condition 96 144 66.6
subroutine 50 52 96.1
pod 12 41 29.2
total 941 1089 86.4


line stmt bran cond sub pod time code
1             package PDF::Create;
2              
3             our $VERSION = '1.41';
4              
5             =head1 NAME
6              
7             PDF::Create - Create PDF files.
8              
9             =head1 VERSION
10              
11             Version 1.41
12              
13             =cut
14              
15 18     18   38757 use 5.006;
  18         37  
16 18     18   50 use strict; use warnings;
  18     18   20  
  18         293  
  18         48  
  18         21  
  18         385  
17              
18 18     18   53 use Carp qw(confess croak cluck carp);
  18         17  
  18         1061  
19 18     18   9345 use Data::Dumper;
  18         114372  
  18         857  
20 18     18   6742 use FileHandle;
  18         124463  
  18         91  
21 18     18   4148 use Scalar::Util qw(weaken);
  18         20  
  18         1263  
22              
23 18     18   6425 use PDF::Image::GIF;
  18         27  
  18         437  
24 18     18   5981 use PDF::Image::JPEG;
  18         29  
  18         449  
25 18     18   7444 use PDF::Create::Page;
  18         43  
  18         1029  
26 18     18   6743 use PDF::Create::Outline;
  18         29  
  18         94221  
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 60180 my ($this, %params) = @_;
171              
172             # validate constructor keys
173 42         4106 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         3914 foreach (keys %params) {
187             croak "Invalid constructor key '$_' received."
188 138 100       8391 unless (exists $valid_constructor_keys{$_});
189             }
190              
191 34 100 66     3928 if (exists $params{PageMode} && defined $params{PageMode}) {
192             # validate PageMode key value
193 26         3817 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       7691 unless (exists $valid_page_mode_values{$params{PageMode}});
200             }
201              
202 33 100 66     3798 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     88 unless (($params{Debug} =~ /^\d+$/) && ($params{Debug} >= 0));
206             }
207              
208 32   33     3882 my $class = ref($this) || $this;
209 32         3806 my $self = {};
210 32         3798 bless $self, $class;
211              
212 32         3818 $self->{'data'} = '';
213 32   100     3859 $self->{'version'} = $params{'Version'} || "1.2";
214 32         3819 $self->{'trailer'} = {};
215              
216 32         3909 $self->{'pages'} = PDF::Create::Page->new();
217 32         3795 $self->{'current_page'} = $self->{'pages'};
218             # circular reference
219 32         3773 $self->{'pages'}->{'pdf'} = $self;
220 32         3868 weaken $self->{pages}{pdf};
221 32         3797 $self->{'page_count'} = 0;
222 32         3763 $self->{'outline_count'} = 0;
223              
224             # cross-reference table start address
225 32         3828 $self->{'crossreftblstartaddr'} = 0;
226 32         3784 $self->{'generation_number'} = 0;
227 32         3780 $self->{'object_number'} = 0;
228              
229 32 100       3846 if ( defined $params{'fh'} ) {
    100          
230 1         2 $self->{'fh'} = $params{'fh'};
231             } elsif ( defined $params{'filename'} ) {
232 26         3779 $self->{'filename'} = $params{'filename'};
233 26         3992 my $fh = FileHandle->new( "> $self->{'filename'}" );
234 26 50       147376 carp "PDF::Create.pm: $self->{'filename'}: $!\n" unless defined $fh;
235 26         4090 binmode $fh;
236 26         7673 $self->{'fh'} = $fh;
237             }
238              
239 32         3848 $self->{'catalog'} = {};
240 32 100       3871 $self->{'catalog'}{'PageMode'} = $params{'PageMode'} if defined $params{'PageMode'};
241              
242             # Header: add version
243 32         3959 $self->add_version;
244              
245             # Info
246 32 100       4125 $self->{'Author'} = $params{'Author'} if defined $params{'Author'};
247 32 50       3842 $self->{'Creator'} = $params{'Creator'} if defined $params{'Creator'};
248 32 100       3871 $self->{'Title'} = $params{'Title'} if defined $params{'Title'};
249 32 50       3845 $self->{'Subject'} = $params{'Subject'} if defined $params{'Subject'};
250 32 50       3789 $self->{'Keywords'} = $params{'Keywords'} if defined $params{'Keywords'};
251              
252             # TODO: Default creation date from system date
253 32 50       3801 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       3794 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         3844 debug( 1, "Debugging level $DEBUG" );
267 32         9511 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 8558 my ($self, %params) = @_;
336              
337 51         5720 my %valid_new_page_parameters = map { $_ => 1 } (qw/Parent Resources MediaBox CropBox ArtBox TrimBox BleedBox Rotate/);
  408         90343  
338 51         5810 foreach my $key (keys %params) {
339             croak "PDF::Create.pm - new_page(): Received invalid key [$key]"
340 51 100       11537 unless (exists $valid_new_page_parameters{$key});
341             }
342              
343 50   66     5795 my $parent = $params{'Parent'} || $self->{'pages'};
344 50         5792 my $name = "Page " . ++$self->{'page_count'};
345 50         5752 my $page = $parent->add( $self->reserve( $name, "Page" ), $name );
346 50 50       5764 $page->{'resources'} = $params{'Resources'} if defined $params{'Resources'};
347 50 100       5728 $page->{'mediabox'} = $params{'MediaBox'} if defined $params{'MediaBox'};
348 50 50       5723 $page->{'cropbox'} = $params{'CropBox'} if defined $params{'CropBox'};
349 50 50       5668 $page->{'artbox'} = $params{'ArtBox'} if defined $params{'ArtBox'};
350 50 50       5742 $page->{'trimbox'} = $params{'TrimBox'} if defined $params{'TrimBox'};
351 50 50       5689 $page->{'bleedbox'} = $params{'BleedBox'} if defined $params{'BleedBox'};
352 50 50       5677 $page->{'rotate'} = $params{'Rotate'} if defined $params{'Rotate'};
353              
354 50         5711 $self->{'current_page'} = $page;
355              
356 50         16632 $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 10440 my ($self, %params) = @_;
392              
393             my %valid_font_parameters = (
394 184         30247 'Subtype' => { map { $_ => 1 } qw/Type0 Type1 Type3 TrueType/ },
395 184         30241 'Encoding' => { map { $_ => 1 } qw/MacRomanEncoding MacExpertEncoding WinAnsiEncoding Symbol/ },
396 46         3865 'BaseFont' => { map { $_ => 1 } qw/Courier Courier-Bold Courier-BoldOblique Courier-Oblique
  598         98825  
397             Helvetica Helvetica-Bold Helvetica-BoldOblique Helvetica-Oblique
398             Times-Roman Times-Bold Times-Italic Times-BoldItalic Symbol/ },
399             );
400              
401 46         3974 foreach my $key (keys %params) {
402             croak "PDF::Create.pm - font(): Received invalid key [$key]"
403 129 100       11556 unless (exists $valid_font_parameters{$key});
404 128         11358 my $value = $params{$key};
405             croak "PDF::Create.pm - font(): Received invalid value [$value] for key [$key]"
406 128 100 66     15599 if (defined $value && !(exists $valid_font_parameters{$key}->{$value}));
407             }
408              
409 42         3824 my $num = 1 + scalar keys %{ $self->{'fonts'} };
  42         7640  
410             $self->{'fonts'}{$num} = {
411             'Subtype' => $self->name( $params{'Subtype'} || 'Type1' ),
412             'Encoding' => $self->name( $params{'Encoding'} || 'WinAnsiEncoding' ),
413 42   100     3894 'BaseFont' => $self->name( $params{'BaseFont'} || 'Helvetica' ),
      50        
      100        
414             'Name' => $self->name("F$num"),
415             'Type' => $self->name("Font"),
416             };
417              
418 42         7773 $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 9868 my ($self, %params) = @_;
453              
454             croak "PDF::Create - new_outline(): Missing required key [Title]."
455 34 50       6628 unless (exists $params{'Title'});
456             croak "PDF::Create - new_outline(): Required key [Title] undefined."
457 34 50       6619 unless (defined $params{'Title'});
458              
459 34 100       6655 if (defined $params{Destination}) {
460             croak "PDF::Create - new_outline(): Invalid value for key [Destination]."
461 14 50       3813 unless (ref($params{Destination}) eq 'PDF::Create::Page');
462             }
463              
464 34 100       6617 if (defined $params{Parent}) {
465             croak "PDF::Create - new_outline(): Invalid value for key [Parent]."
466 18 50       7489 unless (ref($params{Parent}) eq 'PDF::Create::Outline');
467             }
468              
469 34 100       6608 unless ( defined $self->{'outlines'} ) {
470 9         1933 $self->{'outlines'} = PDF::Create::Outline->new();
471             # circular reference
472 9         1888 $self->{'outlines'}->{'pdf'} = $self;
473 9         1922 weaken $self->{'outlines'}->{'pdf'};
474 9         3752 $self->{'outlines'}->{'Status'} = 'opened';
475             }
476              
477 34   66     6672 my $parent = $params{'Parent'} || $self->{'outlines'};
478 34         6930 my $name = "Outline " . ++$self->{'outline_count'};
479 34 100       6615 $params{'Destination'} = $self->{'current_page'} unless defined $params{'Destination'};
480 34         6618 my $outline = $parent->add( $self->reserve( $name, "Outline" ), $name, %params );
481 34         19257 $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 4411 my ($self, $name) = @_;
497              
498 28         384 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       67 if (defined $name) {
516 28         45 $name = uc($name);
517             # validate page size
518 28 100       129 croak "Invalid page size name '$name' received." unless (exists $pagesizes{$name});
519             }
520             else {
521 0         0 $name = 'A4';
522             }
523              
524 27         123 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 3 my ($self, $v) = @_;
535              
536 5 50       10 if (defined $v) {
537 5 100       243 croak "ERROR: Invalid version number $v received.\n"
538             unless ($v =~ /^1\.[0,1,2,3]$/);
539 3         17 $self->{'version'} = $v;
540             }
541 3         7 $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 2542 my ($self, %params) = @_;
558              
559 15         982 debug( 2, "Closing PDF" );
560 15         983 my $raw_data = $self->flush;
561              
562 15 100 66     1145 if (defined $self->{'fh'} && defined $self->{'filename'}) {
563 14         1116 $self->{'fh'}->close;
564             }
565              
566 15         10951 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 980 my ($self) = @_;
577              
578 15         994 debug( 2, "Flushing PDF" );
579 15         979 $self->page_stream;
580 15 100       1020 $self->add_outlines if defined $self->{'outlines'};
581 15         1030 $self->add_catalog;
582 15         1047 $self->add_pages;
583 15         1087 $self->add_info;
584 15         1113 $self->add_crossrefsection;
585 15         1104 $self->add_trailer;
586              
587 15         2165 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 24074 my ($self, $name, $type) = @_;;
598              
599 227 100       24218 $type = $name unless defined $type;
600              
601             confess "Error: an object has already been reserved using this name '$name' "
602 227 50       24246 if defined $self->{'reservations'}{$name};
603 227         24090 $self->{'object_number'}++;
604 227         24881 debug( 2, "reserve(): name=$name type=$type number=$self->{'object_number'} generation=$self->{'generation_number'}" );
605 227         24607 $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       24268 if ($type eq 'Annotation') {
613 2         5 $self->{'Annots'}{ $self->{'object_number'} } = $self->{'generation_number'};
614             }
615              
616 227         48577 [ $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 2400 my ($self, $comment) = @_;
630              
631 7 50       23 $comment = '' unless defined $comment;
632 7         28 debug( 2, "add_comment(): $comment" );
633 7         26 $self->add( "%" . $comment );
634 7         16 $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 8 my ($self, %params) = @_;
678              
679 2         6 debug( 2, "annotation(): Subtype=$params{'Subtype'}" );
680              
681 2 50       5 if ( $params{'Subtype'} eq 'Link' ) {
682 2 50       4 confess "Must specify 'URI' for Link" unless defined $params{'URI'};
683 2 50       8 confess "Must specify 'x' for Link" unless defined $params{'x'};
684 2 50       4 confess "Must specify 'y' for Link" unless defined $params{'y'};
685 2 50       4 confess "Must specify 'w' for Link" unless defined $params{'w'};
686 2 50       4 confess "Must specify 'h' for Link" unless defined $params{'h'};
687              
688 2         3 my $num = 1 + scalar keys %{ $self->{'annotations'} };
  2         5  
689              
690             my $action = {
691             'Type' => $self->name('Action'),
692             'S' => $self->name('URI'),
693 2         3 'URI' => $self->string( $params{'URI'} ),
694             };
695 2         4 my $x2 = $params{'x'} + $params{'w'};
696 2         2 my $y2 = $params{'y'} + $params{'h'};
697              
698             $self->{'annotations'}{$num} = {
699             'Subtype' => $self->name('Link'),
700 2         3 'Rect' => $self->verbatim( sprintf "[%f %f %f %f]", $params{'x'}, $params{'y'}, $x2, $y2 ),
701             'A' => $self->dictionary(%$action),
702             };
703              
704 2 50       5 if ( defined $params{'Border'} ) {
705             $self->{'annotations'}{$num}{'Border'} =
706 2         14 $self->verbatim( sprintf "[%f %f %f]", $params{'Border'}[0], $params{'Border'}[1], $params{'Border'}[2] );
707             }
708 2         4 $self->{'annot'}{$num}{'page_name'} = "Page " . $self->{'page_count'};
709 2         5 debug( 2, "annotation(): annotation number: $num, page name: $self->{'annot'}{$num}{'page_name'}" );
710 2         8 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         2 my $num = 1 + scalar keys %{ $self->{'xobjects'} };
  2         6  
749              
750 2         2 my $image;
751             my $colorspace;
752 0         0 my @a;
753              
754 2 100 33     14 if ( $filename =~ /\.gif$/i ) {
    50          
755 1         9 $self->{'images'}{$num} = PDF::Image::GIF->new();
756             } elsif ( $filename =~ /\.jpg$/i || $filename =~ /\.jpeg$/i ) {
757 1         6 $self->{'images'}{$num} = PDF::Image::JPEG->new();
758             }
759              
760 2         4 $image = $self->{'images'}{$num};
761 2 50       3 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         5 'Length' => $self->number( $image->{imagesize} ),
775             };
776              
777             # Indexed colorspace?
778 2 100       21 if ($image->{colorspacesize}) {
779 1         7 $colorspace = $self->reserve("ImageColorSpace$num");
780              
781             $self->{'xobjects_colorspace'}{$num} = {
782             'Data' => $image->{colorspacedata},
783 1         6 '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         7 $#a = -1;
794 2         2 foreach my $s ( @{ $image->{filter} } ) {
  2         7  
795 2         4 push @a, $self->name($s);
796             }
797 2 50       7 if ( $#a >= 0 ) {
798 2         5 $self->{'xobjects'}{$num}->{'Filter'} = $self->array(@a);
799             }
800              
801             # Set additional DecodeParms
802 2         2 $#a = -1;
803 2         4 foreach my $s ( keys %{ $image->{decodeparms} } ) {
  2         8  
804 1         2 push @a, $s;
805 1         4 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       6 if ( $image->{transparent} ) {
811 1         5 $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 950 my ($self, %params) = @_;
819              
820 5         953 debug( 2, "add_outlines" );
821 5         955 my $outlines = $self->reserve("Outlines");
822              
823 5         952 my ($First, $Last);
824 5         987 my @list = $self->{'outlines'}->list;
825 5         951 my $i = -1;
826 5         973 for my $outline (@list) {
827 30         5878 $i++;
828 30         5866 my $name = $outline->{'name'};
829 30 100       5882 $First = $outline->{'id'} unless defined $First;
830 30         5900 $Last = $outline->{'id'};
831 30         5909 my $content = { 'Title' => $self->string( $outline->{'Title'} ) };
832 30 100 50     5912 if ( defined $outline->{'Kids'} && scalar @{ $outline->{'Kids'} } ) {
  30         11763  
833 9         1980 my $t = $outline->{'Kids'};
834 9         1938 $$content{'First'} = $self->indirect_ref( @{ $$t[0]->{'id'} } );
  9         3846  
835 9         1922 $$content{'Last'} = $self->indirect_ref( @{ $$t[$#$t]->{'id'} } );
  9         3872  
836             }
837 30         5891 my $brothers = $outline->{'Parent'}->{'Kids'};
838 30         5812 my $j = -1;
839 30         5894 for my $brother (@$brothers) {
840 53         9823 $j++;
841 53 100       15778 last if $brother == $outline;
842             }
843 30 100       5994 $$content{'Next'} = $self->indirect_ref( @{ $$brothers[ $j + 1 ]->{'id'} } )
  16         5820  
844             if $j < $#$brothers;
845 30 100       5859 $$content{'Prev'} = $self->indirect_ref( @{ $$brothers[ $j - 1 ]->{'id'} } )
  16         5943  
846             if $j;
847             $outline->{'Parent'}->{'id'} = $outlines
848 30 100       5913 unless defined $outline->{'Parent'}->{'id'};
849 30         5969 $$content{'Parent'} = $self->indirect_ref( @{ $outline->{'Parent'}->{'id'} } );
  30         12087  
850             $$content{'Dest'} =
851 30         5877 $self->array( $self->indirect_ref( @{ $outline->{'Dest'}->{'id'} } ),
  30         11811  
852             $self->name('Fit'), $self->null, $self->null, $self->null );
853 30         5943 my $count = $outline->count;
854 30 100       5941 $$content{'Count'} = $self->number($count) if $count;
855 30         5941 my $t = $self->add_object( $self->indirect_obj( $self->dictionary(%$content), $name ) );
856 30         6088 $self->cr;
857             }
858              
859             # Type (required)
860 5         1030 my $content = { 'Type' => $self->name('Outlines') };
861              
862             # Count
863 5         1038 my $count = $self->{'outlines'}->count;
864 5 50       1029 $$content{'Count'} = $self->number($count) if $count;
865 5         1017 $$content{'First'} = $self->indirect_ref(@$First);
866 5         1016 $$content{'Last'} = $self->indirect_ref(@$Last);
867 5         1028 $self->add_object( $self->indirect_obj( $self->dictionary(%$content) ) );
868 5         1044 $self->cr;
869             }
870              
871             sub add_pages {
872 15     15 0 1038 my ($self) = @_;
873              
874 15         1029 debug( 2, "add_pages():" );
875              
876             # Type (required)
877 15         1030 my $content = { 'Type' => $self->name('Pages') };
878              
879             # Kids (required)
880 15         1071 my $t = $self->{'pages'}->kids;
881 15 50       1045 confess "Error: document MUST contains at least one page. Abort."
882             unless scalar @$t;
883              
884 15         1035 my $kids = [];
885 15         1024 map { push @$kids, $self->indirect_ref(@$_) } @$t;
  15         1053  
886 15         1041 $$content{'Kids'} = $self->array(@$kids);
887 15         1058 $$content{'Count'} = $self->number( $self->{'pages'}->count );
888 15         1091 $self->add_object( $self->indirect_obj( $self->dictionary(%$content) ) );
889 15         1062 $self->cr;
890              
891 15         1030 for my $font ( sort keys %{ $self->{'fonts'} } ) {
  15         2090  
892 34         2114 debug( 2, "add_pages(): font: $font" );
893 34         2094 $self->{'fontobj'}{$font} = $self->reserve('Font');
894 34         2053 $self->add_object( $self->indirect_obj( $self->dictionary( %{ $self->{'fonts'}{$font} } ), 'Font' ) );
  34         4179  
895 34         2173 $self->cr;
896             }
897              
898 15         1041 for my $xobject (sort keys %{$self->{'xobjects'}}) {
  15         2128  
899 2         4 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         11  
902 2         12 $self->cr;
903              
904 2 100       7 if ( defined $self->{'reservations'}{"ImageColorSpace$xobject"}) {
905             $self->add_object(
906 1         2 $self->indirect_obj( $self->stream( %{ $self->{'xobjects_colorspace'}{$xobject} } ), "ImageColorSpace$xobject" ) );
  1         5  
907 1         4 $self->cr;
908             }
909             }
910              
911 15         1036 for my $annotation (sort keys %{$self->{'annotations'}}) {
  15         2133  
912 2         3 $self->{'annot'}{$annotation}{'object_info'} = $self->reserve('Annotation');
913 2         2 $self->add_object( $self->indirect_obj( $self->dictionary( %{ $self->{'annotations'}{$annotation} } ), 'Annotation' ) );
  2         6  
914 2         5 $self->cr;
915             }
916              
917 15         1098 for my $page ($self->{'pages'}->list) {
918 38         3146 my $name = $page->{'name'};
919 38         3216 debug( 2, "add_pages: page: $name" );
920 38 100 50     3190 my $type = 'Page' . ( defined $page->{'Kids'} && scalar @{ $page->{'Kids'} } ? 's' : '' );
921              
922             # Type (required)
923 38         3183 my $content = { 'Type' => $self->name($type) };
924              
925             # Resources (required, may be inherited). See page 195.
926 38         3147 my $resources = {};
927 38         3129 for my $k ( keys %{ $page->{'resources'} } ) {
  38         6340  
928 39         2109 my $v = $page->{'resources'}{$k};
929             ( $k eq 'ProcSet' ) && do {
930 19         1061 my $l = [];
931 19 50       1076 if ( ref($v) eq 'ARRAY' ) {
932 19         1085 map { push @$l, $self->name($_) } @$v;
  38         2125  
933             } else {
934 0         0 push @$l, $self->name($v);
935             }
936 19         1080 $$resources{'ProcSet'} = $self->array(@$l);
937             }
938             || ( $k eq 'fonts' ) && do {
939 19         1056 my $l = {};
940 19         1066 map { $$l{"F$_"} = $self->indirect_ref( @{ $self->{'fontobj'}{$_} } ); } keys %{ $page->{'resources'}{'fonts'} };
  37         2087  
  37         4211  
  19         2092  
941 19         1078 $$resources{'Font'} = $self->dictionary(%$l);
942             }
943 39 100 33     2222 || ( $k eq 'xobjects' ) && do {
      66        
      66        
      66        
944 1         2 my $l = {};
945 2         1 map { $$l{"Image$_"} = $self->indirect_ref( @{ $self->{'xobj'}{$_} } ); }
  2         86  
946 1         1 keys %{ $page->{'resources'}{'xobjects'} };
  1         4  
947 1         3 $$resources{'XObject'} = $self->dictionary(%$l);
948             };
949             }
950 38 50       3177 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       3191 if ( defined( $$resources{'XObject'} ) ) {
956 1         3 my $r = $self->add_object( $self->indirect_obj( $self->dictionary(%$resources) ) );
957 1         4 $self->cr;
958 1         4 $$content{'Resources'} = [ 'ref', [ $$r[0], $$r[1] ] ];
959             } else {
960 37 100       5268 $$content{'Resources'} = $self->dictionary(%$resources)
961             if scalar keys %$resources;
962             }
963 38         3162 for my $K ( 'MediaBox', 'CropBox', 'ArtBox', 'TrimBox', 'BleedBox' ) {
964 190         15686 my $k = lc $K;
965 190 100       19152 if ( defined $page->{$k} ) {
966 15         1057 my $l = [];
967 15         1052 map { push @$l, $self->number($_) } @{ $page->{$k} };
  60         4188  
  15         2072  
968 15         1064 $$content{$K} = $self->array(@$l);
969             }
970             }
971 38 50       3172 $$content{'Rotate'} = $self->number( $page->{'rotate'} ) if defined $page->{'rotate'};
972 38 100       3175 if ( $type eq 'Page' ) {
973 24         2093 $$content{'Parent'} = $self->indirect_ref( @{ $page->{'Parent'}{'id'} } );
  24         4233  
974              
975             # Content
976 24 100       2133 if ( defined $page->{'contents'} ) {
977 23         2096 my $contents = [];
978 23         2106 map { push @$contents, $self->indirect_ref(@$_); } @{ $page->{'contents'} };
  27         3165  
  23         4185  
979 23         2129 $$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       4217 if ( defined $self->{'annot'} ) {
986 1         1 my $Annots = '[ ';
987 1         1 my $is_annots = 0;
988 1         2 foreach my $annot_number ( keys %{ $self->{'annot'} } ) {
  1         3  
989 2 50       5 next if ( $self->{'annot'}{$annot_number}{'page_name'} ne $name );
990 2         2 $is_annots = 1;
991 2         5 debug( 2,
992             sprintf "annotation number: $annot_number, page name: $self->{'annot'}{$annot_number}{'page_name'}" );
993 2         3 my $object_number = $self->{'annot'}{$annot_number}{'object_info'}[0];
994 2         2 my $generation_number = $self->{'annot'}{$annot_number}{'object_info'}[1];
995 2         6 debug( 2, sprintf "object_number: $object_number, generation_number: $generation_number" );
996 2         5 $Annots .= sprintf( "%s %s R ", $object_number, $generation_number );
997             }
998 1 50       11 $$content{'Annots'} = $self->verbatim( $Annots . ']' ) if ($is_annots);
999             }
1000             } else {
1001 14         1038 my $kids = [];
1002 14         1043 map { push @$kids, $self->indirect_ref(@$_) } @{ $page->kids };
  23         2089  
  14         1055  
1003 14         1067 $$content{'Kids'} = $self->array(@$kids);
1004 14         2380 $$content{'Parent'} = $self->indirect_ref( @{ $page->{'Parent'}{'id'} } )
1005 14 50       1073 if defined $page->{'Parent'};
1006 14         1084 $$content{'Count'} = $self->number( $page->count );
1007             }
1008 38         3231 $self->add_object( $self->indirect_obj( $self->dictionary(%$content), $name ) );
1009 38         3291 $self->cr;
1010             }
1011             }
1012              
1013             sub add_crossrefsection {
1014 15     15 0 1065 my ($self) = @_;
1015              
1016 15         1085 debug( 2, "add_crossrefsection():" );
1017              
1018             # ::=
1019             # xref
1020             # +
1021 15         1090 $self->{'crossrefstartpoint'} = $self->position;
1022 15         1109 $self->add('xref');
1023 15         1070 $self->cr;
1024             confess "Fatal error: should contains at least one cross reference subsection."
1025 15 50       1094 unless defined $self->{'crossrefsubsection'};
1026 15         1084 for my $subsection ( sort keys %{ $self->{'crossrefsubsection'} } ) {
  15         2171  
1027 15         1103 $self->add_crossrefsubsection($subsection);
1028             }
1029             }
1030              
1031             sub add_crossrefsubsection {
1032 15     15 0 1066 my ($self, $subsection) = @_;
1033              
1034 15         1102 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         1065 $self->add( 0, ' ', 1 + scalar @{ $self->{'crossrefsubsection'}{$subsection} } );
  15         2168  
1054 15         1075 $self->cr;
1055 15         1104 $self->add( sprintf "%010d %05d %s ", 0, 65535, 'f' );
1056 15         1075 $self->cr;
1057 15         1093 for my $entry ( sort { $$a[0] <=> $$b[0] } @{ $self->{'crossrefsubsection'}{$subsection} } ) {
  551         136065  
  15         2207  
1058 212 50       23008 $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         22426 $self->cr;
1062             }
1063             }
1064              
1065             sub add_trailer {
1066 15     15 0 1064 my $self = shift;
1067              
1068 15         1070 debug( 2, "add_trailer():" );
1069              
1070             # ::= trailer
1071             # <<
1072             # +
1073             # >>
1074             # startxref
1075             #
1076             # %%EOF
1077              
1078 15         1088 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         1086 $self->add('trailer');
1089 15         1067 $self->cr;
1090 15         1093 $self->add('<<');
1091 15         1074 $self->cr;
1092 15         1092 $self->{'trailer'}{'Size'} = 1;
1093 15         1062 map { $self->{'trailer'}{'Size'} += scalar @{ $self->{'crossrefsubsection'}{$_} } } keys %{ $self->{'crossrefsubsection'} };
  15         1097  
  15         3180  
  15         2143  
1094 15         1084 $self->{'trailer'}{'Root'} = &encode( @{ $self->indirect_ref( @{ $self->{'catalog'} } ) } );
  15         1062  
  15         2137  
1095 15         1368 $self->{'trailer'}{'Info'} = &encode( @{ $self->indirect_ref( @{ $self->{'info'} } ) } )
  15         2129  
1096 15 50       1127 if defined $self->{'info'};
1097              
1098 15         1082 for my $k (@keys) {
1099 90 100       9694 next unless defined $self->{'trailer'}{$k};
1100             $self->add( "/$k ",
1101 45 50       3315 ref $self->{'trailer'}{$k} eq 'ARRAY' ? join( ' ', @{ $self->{'trailer'}{$k} } ) : $self->{'trailer'}{$k} );
  0         0  
1102 45         3213 $self->cr;
1103             }
1104 15         1084 $self->add('>>');
1105 15         1084 $self->cr;
1106 15         1090 $self->add('startxref');
1107 15         1090 $self->cr;
1108 15         1119 $self->add( $self->{'crossrefstartpoint'} );
1109 15         1087 $self->cr;
1110 15         1107 $self->add('%%EOF');
1111 15         1086 $self->cr;
1112             }
1113              
1114             sub cr {
1115 1564     1564 0 103074 my ($self) = @_;
1116              
1117 1564         103361 debug( 3, "cr():" );
1118 1564         104274 $self->add( &encode('cr') );
1119             }
1120              
1121             sub page_stream {
1122 562     562 0 6101 my ($self, $page) = @_;
1123              
1124 562         6181 debug( 2, "page_stream():" );
1125              
1126 562 100       6437 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     7935 && $self->{'stream_page'} == $page;
      100        
      100        
1133              
1134             # Remember the position
1135 27         2903 my $len = $self->position - $self->{'stream_pos'} + 1;
1136              
1137             # Close the stream and the object
1138 27         2905 $self->cr;
1139 27         2895 $self->add('endstream');
1140 27         2864 $self->cr;
1141 27         2884 $self->add('endobj');
1142 27         2883 $self->cr;
1143 27         2856 $self->cr;
1144              
1145             # Add the length
1146 27         2934 $self->add_object( $self->indirect_obj( $self->number($len), 'stream_length' ) );
1147 27         2943 $self->cr;
1148             }
1149              
1150             # open a new stream if needed
1151 42 100       4807 if (defined $page) {
1152              
1153             # get an object id for the stream
1154 27         2865 my $obj = $self->reserve('stream');
1155              
1156             # release it
1157 27         2891 delete $self->{'reservations'}{'stream'};
1158              
1159             # get another one for the length of this stream
1160 27         2878 my $stream_length = $self->reserve('stream_length');
1161 27         2920 push @$stream_length, 'R';
1162 27         2815 push @{ $page->{'contents'} }, $obj;
  27         5685  
1163              
1164             # write the beginning of the object
1165 27         3144 push @{ $self->{'crossrefsubsection'}{ $$obj[1] } }, [ $$obj[0], $self->position, 1 ];
  27         5694  
1166 27         2910 $self->add("$$obj[0] $$obj[1] obj");
1167 27         2879 $self->cr;
1168 27         2852 $self->add('<<');
1169 27         2851 $self->cr;
1170 27         2897 $self->add( '/Length ', join( ' ', @$stream_length ) );
1171 27         2848 $self->cr;
1172 27         2874 $self->add('>>');
1173 27         2866 $self->cr;
1174 27         2844 $self->add('stream');
1175 27         2866 $self->cr;
1176 27         2861 $self->{'stream_pos'} = $self->position;
1177 27         8548 $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 2926 my ($self, $page, $font) = @_;
1195              
1196 86         2959 $page->{'resources'}{'fonts'}{$font} = 1;
1197 86         3004 $page->{'resources'}{'ProcSet'} = [ 'PDF', 'Text' ];
1198 86         6046 $self->{'fontobj'}{$font} = 1;
1199             }
1200              
1201             sub uses_xobject {
1202 2     2 0 4 my ($self, $page, $xobject) = @_;
1203              
1204 2         8 $page->{'resources'}{'xobjects'}{$xobject} = 1;
1205 2         5 $page->{'resources'}{'ProcSet'} = [ 'PDF', 'Text' ];
1206 2         7 $self->{'xobj'}{$xobject} = 1;
1207             }
1208              
1209             sub debug {
1210 9204     9204 0 760926 my ($level, $msg) = @_;
1211              
1212 9204 50       2087442 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 185369 my $self = shift;
1220 2924         186848 my $data = join '', @_;
1221              
1222 2924         186042 $self->{'size'} += length $data;
1223 2924 100       186194 if ( defined $self->{'fh'} ) {
1224 2914         185514 my $fh = $self->{'fh'};
1225 2914         681259 print $fh $data;
1226             } else {
1227 10         11 $self->{'data'} .= $data;
1228             }
1229             }
1230              
1231             sub position {
1232 466     466 0 45802 my ($self) = @_;
1233              
1234 466         92585 $self->{'size'};
1235             }
1236              
1237             sub add_version {
1238 32     32 0 3841 my ($self) = @_;
1239              
1240 32         4107 debug( 2, "add_version(): $self->{'version'}" );
1241 32         3890 $self->add( "%PDF-" . $self->{'version'} );
1242 32         3836 $self->cr;
1243             }
1244              
1245             sub add_object {
1246 185     185 0 18031 my ($self, $v) = @_;
1247              
1248 185         18111 my $val = &encode(@$v);
1249 185         18384 $self->add($val);
1250 185         18195 $self->cr;
1251 185         18899 debug( 3, "add_object(): $v -> $val" );
1252 185         36355 [ $$v[1][0], $$v[1][1] ];
1253             }
1254              
1255             sub null {
1256 90     90 0 17546 my ($self) = @_;;
1257              
1258 90         35195 [ '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 12105 my ($self, $val) = @_;;
1269              
1270 143         29425 [ 'number', $val ];
1271             }
1272              
1273             sub name {
1274 396     396 0 35214 my ($self, $val) = @_;
1275              
1276 396         73855 [ 'name', $val ];
1277             }
1278              
1279             sub string {
1280 73     73 0 9045 my ($self, $val) = @_;
1281              
1282 73         18199 [ 'string', $val ];
1283             }
1284              
1285             sub verbatim {
1286 5     5 0 5 my ($self, $val) = @_;
1287              
1288 5         21 [ 'verbatim', $val ];
1289             }
1290              
1291             sub array {
1292 123     123 0 12111 my $self = shift;
1293              
1294 123         29502 [ 'array', [@_] ];
1295             }
1296              
1297             sub dictionary {
1298 197     197 0 17290 my $self = shift;
1299              
1300 197         36940 [ 'dictionary', {@_} ];
1301             }
1302              
1303             sub indirect_obj {
1304 185     185 0 18116 my $self = shift;
1305              
1306 185         18058 my ($id, $gen, $type, $name);
1307 185         18053 $name = $_[1];
1308             $type = $_[0][1]{'Type'}[1]
1309 185 100 66     19050 if defined $_[0][1] && ref $_[0][1] eq 'HASH' && defined $_[0][1]{'Type'};
      100        
1310              
1311 185 100 66     18783 if ( defined $name && defined $self->{'reservations'}{$name} ) {
    100 66        
1312 134         13905 ( $id, $gen ) = @{ $self->{'reservations'}{$name} };
  134         27969  
1313 134         28143 delete $self->{'reservations'}{$name};
1314             } elsif ( defined $type && defined $self->{'reservations'}{$type} ) {
1315 50         4092 ( $id, $gen ) = @{ $self->{'reservations'}{$type} };
  50         8287  
1316 50         8222 delete $self->{'reservations'}{$type};
1317             } else {
1318 1         2 $id = ++$self->{'object_number'};
1319 1         1 $gen = $self->{'generation_number'};
1320             }
1321 185         18237 debug( 3, "indirect_obj(): " . $self->position );
1322 185         18043 push @{ $self->{'crossrefsubsection'}{$gen} }, [ $id, $self->position, 1 ];
  185         36238  
1323 185         36770 [ 'object', [ $id, $gen, @_ ] ];
1324             }
1325              
1326             sub indirect_ref {
1327 313     313 0 39025 my $self = shift;
1328              
1329 313         90858 [ 'ref', [@_] ];
1330             }
1331              
1332             sub stream {
1333 3     3 0 1 my $self = shift;
1334              
1335 3         16 [ 'stream', {@_} ];
1336             }
1337              
1338             sub add_info {
1339 15     15 0 1057 my $self = shift;
1340              
1341 15         1088 debug( 2, "add_info():" );
1342 15         1079 my %params = @_;
1343 15 100       1117 $params{'Author'} = $self->{'Author'} if defined $self->{'Author'};
1344 15 50       1081 $params{'Creator'} = $self->{'Creator'} if defined $self->{'Creator'};
1345 15 100       1083 $params{'Title'} = $self->{'Title'} if defined $self->{'Title'};
1346 15 50       1086 $params{'Subject'} = $self->{'Subject'} if defined $self->{'Subject'};
1347 15 50       1099 $params{'Keywords'} = $self->{'Keywords'} if defined $self->{'Keywords'};
1348             $params{'CreationDate'} = $self->{'CreationDate'}
1349 15 50       1070 if defined $self->{'CreationDate'};
1350              
1351 15         1087 $self->{'info'} = $self->reserve('Info');
1352 15         1134 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       1127 if defined $params{'Author'};
1358             $$content{'Creator'} = $self->string( $params{'Creator'} )
1359 15 50       1101 if defined $params{'Creator'};
1360             $$content{'Title'} = $self->string( $params{'Title'} )
1361 15 100       1089 if defined $params{'Title'};
1362             $$content{'Subject'} = $self->string( $params{'Subject'} )
1363 15 50       1078 if defined $params{'Subject'};
1364             $$content{'Keywords'} = $self->string( $params{'Keywords'} )
1365 15 50       1072 if defined $params{'Keywords'};
1366             $$content{'CreationDate'} = $self->string( $params{'CreationDate'} )
1367 15 50       1087 if defined $params{'CreationDate'};
1368              
1369 15         1121 $self->add_object( $self->indirect_obj( $self->dictionary(%$content) ), 'Info' );
1370 15         1118 $self->cr;
1371             }
1372              
1373             sub add_catalog {
1374 15     15 0 1058 my $self = shift;
1375              
1376 15         1045 debug( 2, "add_catalog" );
1377 15         1025 my %params = %{ $self->{'catalog'} };
  15         2056  
1378              
1379             # Type (mandatory)
1380 15         1038 $self->{'catalog'} = $self->reserve('Catalog');
1381 15         1052 my $content = { 'Type' => $self->name('Catalog') };
1382              
1383             # Pages (mandatory) [indirected reference]
1384 15         1052 my $pages = $self->reserve('Pages');
1385 15         1036 $$content{'Pages'} = $self->indirect_ref(@$pages);
1386 15         1023 $self->{'pages'}{'id'} = $$content{'Pages'}[1];
1387              
1388             # Outlines [indirected reference]
1389 5         2029 $$content{'Outlines'} = $self->indirect_ref( @{ $self->{'outlines'}->{'id'} } )
1390 15 100       1037 if defined $self->{'outlines'};
1391              
1392             # PageMode
1393 15 100       1071 $$content{'PageMode'} = $self->name($params{'PageMode'}) if defined $params{'PageMode'};
1394              
1395 15         1080 $self->add_object( $self->indirect_obj( $self->dictionary(%$content) ) );
1396 15         1103 $self->cr;
1397             }
1398              
1399             sub encode {
1400 6203     6203 0 577459 my ($type, $val) = @_;
1401              
1402 6203 100       570283 if ($val) {
1403 2748         283481 debug( 4, "encode(): $type $val" );
1404             } else {
1405 3455         290720 debug( 4, "encode(): $type (no val)" );
1406             }
1407              
1408 6203 100       571963 if (!$type) {
1409 1         187 cluck "PDF::Create::encode: empty argument, called by ";
1410 1         6 return 1;
1411             }
1412              
1413             ( $type eq 'null' || $type eq 'number' ) && do {
1414 1243         289307 1; # do nothing
1415             }
1416             || $type eq 'cr' && do {
1417 2915         457554 $val = "\n";
1418             }
1419             || $type eq 'boolean' && do {
1420 4 100       14 $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         18 $val = "$val";
1428             }
1429             || $type eq 'string' && do {
1430 77 100       9155 $val = '' if not defined $val;
1431             # TODO: split it. Quote parentheses.
1432 77         18565 $val = "($val)";
1433             }
1434             || $type eq 'number' && do {
1435 0         0 $val = "$val";
1436             }
1437             || $type eq 'name' && do {
1438 1128 100       99571 $val = '' if not defined $val;
1439 1128         198390 $val = "/$val";
1440             }
1441             || $type eq 'array' && do {
1442              
1443             # array, encode contents individually
1444 125         12312 my $s = '[';
1445 125         12250 for my $v (@$val) {
1446 327         12621 $s .= &encode( $$v[0], $$v[1] ) . " ";
1447             }
1448             # remove the trailing space
1449 125         12294 chop $s;
1450 125         24477 $val = $s . "]";
1451             }
1452             || $type eq 'dictionary' && do {
1453 197         17495 my $s = '<<' . &encode('cr');
1454 197         17845 for my $v ( keys %$val ) {
1455 743         72425 $s .= &encode( 'name', $v ) . " ";
1456 743         72325 $s .= &encode( ${ $$val{$v} }[0], ${ $$val{$v} }[1] ); # . " ";
  743         143752  
  743         144182  
1457 743         72653 $s .= &encode('cr');
1458             }
1459 197         35054 $val = $s . ">>";
1460             }
1461             || $type eq 'object' && do {
1462 186         18551 my $s = &encode( 'number', $$val[0] ) . " " . &encode( 'number', $$val[1] ) . " obj";
1463 186         18507 $s .= &encode('cr');
1464 186         18281 $s .= &encode( $$val[2][0], $$val[2][1] ); # . " ";
1465 186         18301 $s .= &encode('cr');
1466 186         36487 $val = $s . "endobj";
1467             }
1468             || $type eq 'ref' && do {
1469 315         39793 my $s = &encode( 'number', $$val[0] ) . " " . &encode( 'number', $$val[1] ) . " R";
1470 315         79328 $val = $s;
1471             }
1472 6202 100 100     605555 || $type eq 'stream' && do {
      66        
      66        
      66        
      66        
      66        
      66        
      66        
      66        
      66        
      33        
      66        
      66        
      33        
      66        
      66        
      66        
      66        
      66        
      66        
      66        
      66        
      66        
      66        
1473 3         4 my $data = delete $$val{'Data'};
1474 3         6 my $s = '<<' . &encode('cr');
1475 3         9 for my $v ( keys %$val ) {
1476 22         21 $s .= &encode( 'name', $v ) . " ";
1477 22         17 $s .= &encode( ${ $$val{$v} }[0], ${ $$val{$v} }[1] ); # . " ";
  22         25  
  22         25  
1478 22         25 $s .= &encode('cr');
1479             }
1480 3         5 $s .= ">>" . &encode('cr') . "stream" . &encode('cr');
1481 3         6 $s .= $data . &encode('cr');
1482 3         21 $val = $s . "endstream" . &encode('cr');
1483             }
1484             || confess "Error: unknown type '$type'";
1485              
1486             # TODO: add type 'text';
1487 6201         1169238 $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;