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.42';
4              
5             =head1 NAME
6              
7             PDF::Create - Create PDF files.
8              
9             =head1 VERSION
10              
11             Version 1.42
12              
13             =cut
14              
15 18     18   44074 use 5.006;
  18         45  
16 18     18   66 use strict; use warnings;
  18     18   16  
  18         338  
  18         60  
  18         23  
  18         534  
17              
18 18     18   75 use Carp qw(confess croak cluck carp);
  18         19  
  18         1432  
19 18     18   9644 use Data::Dumper;
  18         126915  
  18         1054  
20 18     18   7135 use FileHandle;
  18         133136  
  18         89  
21 18     18   4774 use Scalar::Util qw(weaken);
  18         23  
  18         1256  
22              
23 18     18   7319 use PDF::Image::GIF;
  18         33  
  18         486  
24 18     18   5696 use PDF::Image::JPEG;
  18         31  
  18         453  
25 18     18   7131 use PDF::Create::Page;
  18         50  
  18         1452  
26 18     18   7501 use PDF::Create::Outline;
  18         31  
  18         99950  
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 68279 my ($this, %params) = @_;
171              
172             # validate constructor keys
173 42         4205 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         4022 foreach (keys %params) {
187             croak "Invalid constructor key '$_' received."
188 138 100       8401 unless (exists $valid_constructor_keys{$_});
189             }
190              
191 34 100 66     3964 if (exists $params{PageMode} && defined $params{PageMode}) {
192             # validate PageMode key value
193 26         4025 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       7886 unless (exists $valid_page_mode_values{$params{PageMode}});
200             }
201              
202 33 100 66     3971 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     4037 my $class = ref($this) || $this;
209 32         3782 my $self = {};
210 32         3876 bless $self, $class;
211              
212 32         3875 $self->{'data'} = '';
213 32   100     4193 $self->{'version'} = $params{'Version'} || "1.2";
214 32         3915 $self->{'trailer'} = {};
215              
216 32         4027 $self->{'pages'} = PDF::Create::Page->new();
217 32         3928 $self->{'current_page'} = $self->{'pages'};
218             # circular reference
219 32         3903 $self->{'pages'}->{'pdf'} = $self;
220 32         4126 weaken $self->{pages}{pdf};
221 32         3842 $self->{'page_count'} = 0;
222 32         3861 $self->{'outline_count'} = 0;
223              
224             # cross-reference table start address
225 32         4004 $self->{'crossreftblstartaddr'} = 0;
226 32         3946 $self->{'generation_number'} = 0;
227 32         3755 $self->{'object_number'} = 0;
228              
229 32 100       3968 if ( defined $params{'fh'} ) {
    100          
230 1         2 $self->{'fh'} = $params{'fh'};
231             } elsif ( defined $params{'filename'} ) {
232 26         3965 $self->{'filename'} = $params{'filename'};
233 26         4172 my $fh = FileHandle->new( "> $self->{'filename'}" );
234 26 50       107099 carp "PDF::Create.pm: $self->{'filename'}: $!\n" unless defined $fh;
235 26         3782 binmode $fh, ':utf8';
236 26         7475 $self->{'fh'} = $fh;
237             }
238              
239 32         3836 $self->{'catalog'} = {};
240 32 100       3750 $self->{'catalog'}{'PageMode'} = $params{'PageMode'} if defined $params{'PageMode'};
241              
242             # Header: add version
243 32         3829 $self->add_version;
244              
245             # Info
246 32 100       3932 $self->{'Author'} = $params{'Author'} if defined $params{'Author'};
247 32 50       3723 $self->{'Creator'} = $params{'Creator'} if defined $params{'Creator'};
248 32 100       3853 $self->{'Title'} = $params{'Title'} if defined $params{'Title'};
249 32 50       3819 $self->{'Subject'} = $params{'Subject'} if defined $params{'Subject'};
250 32 50       3799 $self->{'Keywords'} = $params{'Keywords'} if defined $params{'Keywords'};
251              
252             # TODO: Default creation date from system date
253 32 50       3885 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       3710 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         3861 debug( 1, "Debugging level $DEBUG" );
267 32         9687 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 9045 my ($self, %params) = @_;
336              
337 51         5626 my %valid_new_page_parameters = map { $_ => 1 } (qw/Parent Resources MediaBox CropBox ArtBox TrimBox BleedBox Rotate/);
  408         89580  
338 51         5649 foreach my $key (keys %params) {
339             croak "PDF::Create.pm - new_page(): Received invalid key [$key]"
340 51 100       11200 unless (exists $valid_new_page_parameters{$key});
341             }
342              
343 50   66     6057 my $parent = $params{'Parent'} || $self->{'pages'};
344 50         6761 my $name = "Page " . ++$self->{'page_count'};
345 50         5758 my $page = $parent->add( $self->reserve( $name, "Page" ), $name );
346 50 50       5686 $page->{'resources'} = $params{'Resources'} if defined $params{'Resources'};
347 50 100       5561 $page->{'mediabox'} = $params{'MediaBox'} if defined $params{'MediaBox'};
348 50 50       5467 $page->{'cropbox'} = $params{'CropBox'} if defined $params{'CropBox'};
349 50 50       5677 $page->{'artbox'} = $params{'ArtBox'} if defined $params{'ArtBox'};
350 50 50       5784 $page->{'trimbox'} = $params{'TrimBox'} if defined $params{'TrimBox'};
351 50 50       5505 $page->{'bleedbox'} = $params{'BleedBox'} if defined $params{'BleedBox'};
352 50 50       5484 $page->{'rotate'} = $params{'Rotate'} if defined $params{'Rotate'};
353              
354 50         5875 $self->{'current_page'} = $page;
355              
356 50         16380 $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 10219 my ($self, %params) = @_;
392              
393             my %valid_font_parameters = (
394 184         30626 'Subtype' => { map { $_ => 1 } qw/Type0 Type1 Type3 TrueType/ },
395 184         30543 'Encoding' => { map { $_ => 1 } qw/MacRomanEncoding MacExpertEncoding WinAnsiEncoding Symbol/ },
396 46         3789 'BaseFont' => { map { $_ => 1 } qw/Courier Courier-Bold Courier-BoldOblique Courier-Oblique
  598         102246  
397             Helvetica Helvetica-Bold Helvetica-BoldOblique Helvetica-Oblique
398             Times-Roman Times-Bold Times-Italic Times-BoldItalic Symbol/ },
399             );
400              
401 46         4146 foreach my $key (keys %params) {
402             croak "PDF::Create.pm - font(): Received invalid key [$key]"
403 130 100       11392 unless (exists $valid_font_parameters{$key});
404 129         10998 my $value = $params{$key};
405             croak "PDF::Create.pm - font(): Received invalid value [$value] for key [$key]"
406 129 100 66     15586 if (defined $value && !(exists $valid_font_parameters{$key}->{$value}));
407             }
408              
409 42         3738 my $num = 1 + scalar keys %{ $self->{'fonts'} };
  42         8293  
410             $self->{'fonts'}{$num} = {
411             'Subtype' => $self->name( $params{'Subtype'} || 'Type1' ),
412             'Encoding' => $self->name( $params{'Encoding'} || 'WinAnsiEncoding' ),
413 42   100     3976 'BaseFont' => $self->name( $params{'BaseFont'} || 'Helvetica' ),
      50        
      100        
414             'Name' => $self->name("F$num"),
415             'Type' => $self->name("Font"),
416             };
417              
418 42         8919 $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 9362 my ($self, %params) = @_;
453              
454             croak "PDF::Create - new_outline(): Missing required key [Title]."
455 34 50       6241 unless (exists $params{'Title'});
456             croak "PDF::Create - new_outline(): Required key [Title] undefined."
457 34 50       6426 unless (defined $params{'Title'});
458              
459 34 100       6568 if (defined $params{Destination}) {
460             croak "PDF::Create - new_outline(): Invalid value for key [Destination]."
461 14 50       3905 unless (ref($params{Destination}) eq 'PDF::Create::Page');
462             }
463              
464 34 100       6534 if (defined $params{Parent}) {
465             croak "PDF::Create - new_outline(): Invalid value for key [Parent]."
466 18 50       6724 unless (ref($params{Parent}) eq 'PDF::Create::Outline');
467             }
468              
469 34 100       6305 unless ( defined $self->{'outlines'} ) {
470 9         1922 $self->{'outlines'} = PDF::Create::Outline->new();
471             # circular reference
472 9         1880 $self->{'outlines'}->{'pdf'} = $self;
473 9         1917 weaken $self->{'outlines'}->{'pdf'};
474 9         3837 $self->{'outlines'}->{'Status'} = 'opened';
475             }
476              
477 34   66     6379 my $parent = $params{'Parent'} || $self->{'outlines'};
478 34         6529 my $name = "Outline " . ++$self->{'outline_count'};
479 34 100       6307 $params{'Destination'} = $self->{'current_page'} unless defined $params{'Destination'};
480 34         6287 my $outline = $parent->add( $self->reserve( $name, "Outline" ), $name, %params );
481 34         18143 $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 4576 my ($self, $name) = @_;
497              
498 28         418 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       61 if (defined $name) {
516 28         49 $name = uc($name);
517             # validate page size
518 28 100       165 croak "Invalid page size name '$name' received." unless (exists $pagesizes{$name});
519             }
520             else {
521 0         0 $name = 'A4';
522             }
523              
524 27         140 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 4 my ($self, $v) = @_;
535              
536 5 50       8 if (defined $v) {
537 5 100       230 croak "ERROR: Invalid version number $v received.\n"
538             unless ($v =~ /^1\.[0,1,2,3]$/);
539 3         6 $self->{'version'} = $v;
540             }
541 3         4 $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 2498 my ($self, %params) = @_;
558              
559 15         999 debug( 2, "Closing PDF" );
560 15         929 my $raw_data = $self->flush;
561              
562 15 100 66     1042 if (defined $self->{'fh'} && defined $self->{'filename'}) {
563 14         1082 $self->{'fh'}->close;
564             }
565              
566 15         10312 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 1077 my ($self) = @_;
577              
578 15         950 debug( 2, "Flushing PDF" );
579 15         987 $self->page_stream;
580 15 100       883 $self->add_outlines if defined $self->{'outlines'};
581 15         983 $self->add_catalog;
582 15         909 $self->add_pages;
583 15         997 $self->add_info;
584 15         1271 $self->add_crossrefsection;
585 15         1086 $self->add_trailer;
586              
587 15         1889 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 22916 my ($self, $name, $type) = @_;;
598              
599 227 100       22641 $type = $name unless defined $type;
600              
601             confess "Error: an object has already been reserved using this name '$name' "
602 227 50       23621 if defined $self->{'reservations'}{$name};
603 227         22871 $self->{'object_number'}++;
604 227         23505 debug( 2, "reserve(): name=$name type=$type number=$self->{'object_number'} generation=$self->{'generation_number'}" );
605 227         23031 $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       22835 if ($type eq 'Annotation') {
613 2         4 $self->{'Annots'}{ $self->{'object_number'} } = $self->{'generation_number'};
614             }
615              
616 227         46143 [ $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 2305 my ($self, $comment) = @_;
630              
631 7 50       25 $comment = '' unless defined $comment;
632 7         35 debug( 2, "add_comment(): $comment" );
633 7         23 $self->add( "%" . $comment );
634 7         15 $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 10 my ($self, %params) = @_;
678              
679 2         6 debug( 2, "annotation(): Subtype=$params{'Subtype'}" );
680              
681 2 50       6 if ( $params{'Subtype'} eq 'Link' ) {
682 2 50       5 confess "Must specify 'URI' for Link" unless defined $params{'URI'};
683 2 50       3 confess "Must specify 'x' for Link" unless defined $params{'x'};
684 2 50       7 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       3 confess "Must specify 'h' for Link" unless defined $params{'h'};
687              
688 2         2 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         4 'URI' => $self->string( $params{'URI'} ),
694             };
695 2         3 my $x2 = $params{'x'} + $params{'w'};
696 2         3 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       7 if ( defined $params{'Border'} ) {
705             $self->{'annotations'}{$num}{'Border'} =
706 2         12 $self->verbatim( sprintf "[%f %f %f]", $params{'Border'}[0], $params{'Border'}[1], $params{'Border'}[2] );
707             }
708 2         5 $self->{'annot'}{$num}{'page_name'} = "Page " . $self->{'page_count'};
709 2         7 debug( 2, "annotation(): annotation number: $num, page name: $self->{'annot'}{$num}{'page_name'}" );
710 2         10 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 5 my ($self, $filename) = @_;
747              
748 2         3 my $num = 1 + scalar keys %{ $self->{'xobjects'} };
  2         4  
749              
750 2         3 my $image;
751             my $colorspace;
752 0         0 my @a;
753              
754 2 100 33     13 if ( $filename =~ /\.gif$/i ) {
    50          
755 1         7 $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         2 $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       10 if ($image->{colorspacesize}) {
779 1         21 $colorspace = $self->reserve("ImageColorSpace$num");
780              
781             $self->{'xobjects_colorspace'}{$num} = {
782             'Data' => $image->{colorspacedata},
783 1         4 'Length' => $self->number( $image->{colorspacesize} ),
784             };
785              
786 1         6 $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         9 $#a = -1;
794 2         3 foreach my $s ( @{ $image->{filter} } ) {
  2         7  
795 2         5 push @a, $self->name($s);
796             }
797 2 50       5 if ( $#a >= 0 ) {
798 2         6 $self->{'xobjects'}{$num}->{'Filter'} = $self->array(@a);
799             }
800              
801             # Set additional DecodeParms
802 2         4 $#a = -1;
803 2         2 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       7 if ( $image->{transparent} ) {
811 1         4 $self->{'xobjects'}{$num}->{'Mask'} = $self->array( $self->number( $image->{mask} ), $self->number( $image->{mask} ) );
812             }
813              
814 2         18 return { 'num' => $num, 'width' => $image->{width}, 'height' => $image->{height} };
815             }
816              
817             sub add_outlines {
818 5     5 0 910 my ($self, %params) = @_;
819              
820 5         935 debug( 2, "add_outlines" );
821 5         825 my $outlines = $self->reserve("Outlines");
822              
823 5         893 my ($First, $Last);
824 5         896 my @list = $self->{'outlines'}->list;
825 5         829 my $i = -1;
826 5         825 for my $outline (@list) {
827 30         5877 $i++;
828 30         5579 my $name = $outline->{'name'};
829 30 100       5700 $First = $outline->{'id'} unless defined $First;
830 30         5813 $Last = $outline->{'id'};
831 30         5707 my $content = { 'Title' => $self->string( $outline->{'Title'} ) };
832 30 100 50     5801 if ( defined $outline->{'Kids'} && scalar @{ $outline->{'Kids'} } ) {
  30         11346  
833 9         1864 my $t = $outline->{'Kids'};
834 9         1771 $$content{'First'} = $self->indirect_ref( @{ $$t[0]->{'id'} } );
  9         3582  
835 9         1860 $$content{'Last'} = $self->indirect_ref( @{ $$t[$#$t]->{'id'} } );
  9         3641  
836             }
837 30         5836 my $brothers = $outline->{'Parent'}->{'Kids'};
838 30         5548 my $j = -1;
839 30         5720 for my $brother (@$brothers) {
840 53         9895 $j++;
841 53 100       15311 last if $brother == $outline;
842             }
843 30 100       5933 $$content{'Next'} = $self->indirect_ref( @{ $$brothers[ $j + 1 ]->{'id'} } )
  16         5541  
844             if $j < $#$brothers;
845 30 100       5722 $$content{'Prev'} = $self->indirect_ref( @{ $$brothers[ $j - 1 ]->{'id'} } )
  16         5772  
846             if $j;
847             $outline->{'Parent'}->{'id'} = $outlines
848 30 100       5743 unless defined $outline->{'Parent'}->{'id'};
849 30         5734 $$content{'Parent'} = $self->indirect_ref( @{ $outline->{'Parent'}->{'id'} } );
  30         11200  
850             $$content{'Dest'} =
851 30         6057 $self->array( $self->indirect_ref( @{ $outline->{'Dest'}->{'id'} } ),
  30         12035  
852             $self->name('Fit'), $self->null, $self->null, $self->null );
853 30         5919 my $count = $outline->count;
854 30 100       6302 $$content{'Count'} = $self->number($count) if $count;
855 30         5924 my $t = $self->add_object( $self->indirect_obj( $self->dictionary(%$content), $name ) );
856 30         5779 $self->cr;
857             }
858              
859             # Type (required)
860 5         873 my $content = { 'Type' => $self->name('Outlines') };
861              
862             # Count
863 5         966 my $count = $self->{'outlines'}->count;
864 5 50       925 $$content{'Count'} = $self->number($count) if $count;
865 5         907 $$content{'First'} = $self->indirect_ref(@$First);
866 5         946 $$content{'Last'} = $self->indirect_ref(@$Last);
867 5         929 $self->add_object( $self->indirect_obj( $self->dictionary(%$content) ) );
868 5         909 $self->cr;
869             }
870              
871             sub add_pages {
872 15     15 0 885 my ($self) = @_;
873              
874 15         919 debug( 2, "add_pages():" );
875              
876             # Type (required)
877 15         891 my $content = { 'Type' => $self->name('Pages') };
878              
879             # Kids (required)
880 15         939 my $t = $self->{'pages'}->kids;
881 15 50       913 confess "Error: document MUST contains at least one page. Abort."
882             unless scalar @$t;
883              
884 15         904 my $kids = [];
885 15         920 map { push @$kids, $self->indirect_ref(@$_) } @$t;
  15         905  
886 15         903 $$content{'Kids'} = $self->array(@$kids);
887 15         942 $$content{'Count'} = $self->number( $self->{'pages'}->count );
888 15         933 $self->add_object( $self->indirect_obj( $self->dictionary(%$content) ) );
889 15         933 $self->cr;
890              
891 15         934 for my $font ( sort keys %{ $self->{'fonts'} } ) {
  15         1878  
892 34         1946 debug( 2, "add_pages(): font: $font" );
893 34         1812 $self->{'fontobj'}{$font} = $self->reserve('Font');
894 34         1824 $self->add_object( $self->indirect_obj( $self->dictionary( %{ $self->{'fonts'}{$font} } ), 'Font' ) );
  34         3853  
895 34         1960 $self->cr;
896             }
897              
898 15         901 for my $xobject (sort keys %{$self->{'xobjects'}}) {
  15         1850  
899 2         5 debug( 2, "add_pages(): xobject: $xobject" );
900 2         3 $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         9 $self->cr;
903              
904 2 100       6 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         951 for my $annotation (sort keys %{$self->{'annotations'}}) {
  15         1814  
912 2         4 $self->{'annot'}{$annotation}{'object_info'} = $self->reserve('Annotation');
913 2         2 $self->add_object( $self->indirect_obj( $self->dictionary( %{ $self->{'annotations'}{$annotation} } ), 'Annotation' ) );
  2         7  
914 2         6 $self->cr;
915             }
916              
917 15         964 for my $page ($self->{'pages'}->list) {
918 38         2813 my $name = $page->{'name'};
919 38         2794 debug( 2, "add_pages: page: $name" );
920 38 100 50     2824 my $type = 'Page' . ( defined $page->{'Kids'} && scalar @{ $page->{'Kids'} } ? 's' : '' );
921              
922             # Type (required)
923 38         2810 my $content = { 'Type' => $self->name($type) };
924              
925             # Resources (required, may be inherited). See page 195.
926 38         2798 my $resources = {};
927 38         2735 for my $k ( keys %{ $page->{'resources'} } ) {
  38         5542  
928 39         1819 my $v = $page->{'resources'}{$k};
929             ( $k eq 'ProcSet' ) && do {
930 19         926 my $l = [];
931 19 50       946 if ( ref($v) eq 'ARRAY' ) {
932 19         914 map { push @$l, $self->name($_) } @$v;
  38         1856  
933             } else {
934 0         0 push @$l, $self->name($v);
935             }
936 19         920 $$resources{'ProcSet'} = $self->array(@$l);
937             }
938             || ( $k eq 'fonts' ) && do {
939 19         913 my $l = {};
940 19         981 map { $$l{"F$_"} = $self->indirect_ref( @{ $self->{'fontobj'}{$_} } ); } keys %{ $page->{'resources'}{'fonts'} };
  37         1801  
  37         3672  
  19         1820  
941 19         961 $$resources{'Font'} = $self->dictionary(%$l);
942             }
943 39 100 33     1935 || ( $k eq 'xobjects' ) && do {
      66        
      66        
      66        
944 1         1 my $l = {};
945 2         82 map { $$l{"Image$_"} = $self->indirect_ref( @{ $self->{'xobj'}{$_} } ); }
  2         4  
946 1         1 keys %{ $page->{'resources'}{'xobjects'} };
  1         3  
947 1         4 $$resources{'XObject'} = $self->dictionary(%$l);
948             };
949             }
950 38 50       2810 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       2775 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         3 $$content{'Resources'} = [ 'ref', [ $$r[0], $$r[1] ] ];
959             } else {
960 37 100       4612 $$content{'Resources'} = $self->dictionary(%$resources)
961             if scalar keys %$resources;
962             }
963 38         2759 for my $K ( 'MediaBox', 'CropBox', 'ArtBox', 'TrimBox', 'BleedBox' ) {
964 190         13763 my $k = lc $K;
965 190 100       16574 if ( defined $page->{$k} ) {
966 15         937 my $l = [];
967 15         901 map { push @$l, $self->number($_) } @{ $page->{$k} };
  60         3701  
  15         1775  
968 15         924 $$content{$K} = $self->array(@$l);
969             }
970             }
971 38 50       2750 $$content{'Rotate'} = $self->number( $page->{'rotate'} ) if defined $page->{'rotate'};
972 38 100       2738 if ( $type eq 'Page' ) {
973 24         1891 $$content{'Parent'} = $self->indirect_ref( @{ $page->{'Parent'}{'id'} } );
  24         3775  
974              
975             # Content
976 24 100       1912 if ( defined $page->{'contents'} ) {
977 23         2150 my $contents = [];
978 23         1887 map { push @$contents, $self->indirect_ref(@$_); } @{ $page->{'contents'} };
  27         2793  
  23         3716  
979 23         1869 $$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       3783 if ( defined $self->{'annot'} ) {
986 1         2 my $Annots = '[ ';
987 1         1 my $is_annots = 0;
988 1         1 foreach my $annot_number ( keys %{ $self->{'annot'} } ) {
  1         2  
989 2 50       9 next if ( $self->{'annot'}{$annot_number}{'page_name'} ne $name );
990 2         2 $is_annots = 1;
991 2         8 debug( 2,
992             sprintf "annotation number: $annot_number, page name: $self->{'annot'}{$annot_number}{'page_name'}" );
993 2         4 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         5 debug( 2, sprintf "object_number: $object_number, generation_number: $generation_number" );
996 2         6 $Annots .= sprintf( "%s %s R ", $object_number, $generation_number );
997             }
998 1 50       4 $$content{'Annots'} = $self->verbatim( $Annots . ']' ) if ($is_annots);
999             }
1000             } else {
1001 14         931 my $kids = [];
1002 14         945 map { push @$kids, $self->indirect_ref(@$_) } @{ $page->kids };
  23         1841  
  14         928  
1003 14         996 $$content{'Kids'} = $self->array(@$kids);
1004 14         1843 $$content{'Parent'} = $self->indirect_ref( @{ $page->{'Parent'}{'id'} } )
1005 14 50       925 if defined $page->{'Parent'};
1006 14         963 $$content{'Count'} = $self->number( $page->count );
1007             }
1008 38         2889 $self->add_object( $self->indirect_obj( $self->dictionary(%$content), $name ) );
1009 38         2873 $self->cr;
1010             }
1011             }
1012              
1013             sub add_crossrefsection {
1014 15     15 0 1000 my ($self) = @_;
1015              
1016 15         946 debug( 2, "add_crossrefsection():" );
1017              
1018             # ::=
1019             # xref
1020             # +
1021 15         997 $self->{'crossrefstartpoint'} = $self->position;
1022 15         996 $self->add('xref');
1023 15         951 $self->cr;
1024             confess "Fatal error: should contains at least one cross reference subsection."
1025 15 50       1055 unless defined $self->{'crossrefsubsection'};
1026 15         950 for my $subsection ( sort keys %{ $self->{'crossrefsubsection'} } ) {
  15         1895  
1027 15         1061 $self->add_crossrefsubsection($subsection);
1028             }
1029             }
1030              
1031             sub add_crossrefsubsection {
1032 15     15 0 949 my ($self, $subsection) = @_;
1033              
1034 15         976 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         933 $self->add( 0, ' ', 1 + scalar @{ $self->{'crossrefsubsection'}{$subsection} } );
  15         1933  
1054 15         979 $self->cr;
1055 15         957 $self->add( sprintf "%010d %05d %s ", 0, 65535, 'f' );
1056 15         928 $self->cr;
1057 15         921 for my $entry ( sort { $$a[0] <=> $$b[0] } @{ $self->{'crossrefsubsection'}{$subsection} } ) {
  551         119592  
  15         1967  
1058 212 50       20583 $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         19880 $self->cr;
1062             }
1063             }
1064              
1065             sub add_trailer {
1066 15     15 0 999 my $self = shift;
1067              
1068 15         988 debug( 2, "add_trailer():" );
1069              
1070             # ::= trailer
1071             # <<
1072             # +
1073             # >>
1074             # startxref
1075             #
1076             # %%EOF
1077              
1078 15         1032 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         1006 $self->add('trailer');
1089 15         984 $self->cr;
1090 15         1324 $self->add('<<');
1091 15         1024 $self->cr;
1092 15         947 $self->{'trailer'}{'Size'} = 1;
1093 15         957 map { $self->{'trailer'}{'Size'} += scalar @{ $self->{'crossrefsubsection'}{$_} } } keys %{ $self->{'crossrefsubsection'} };
  15         940  
  15         2893  
  15         1880  
1094 15         922 $self->{'trailer'}{'Root'} = &encode( @{ $self->indirect_ref( @{ $self->{'catalog'} } ) } );
  15         943  
  15         1892  
1095 15         951 $self->{'trailer'}{'Info'} = &encode( @{ $self->indirect_ref( @{ $self->{'info'} } ) } )
  15         1833  
1096 15 50       1022 if defined $self->{'info'};
1097              
1098 15         1001 for my $k (@keys) {
1099 90 100       8409 next unless defined $self->{'trailer'}{$k};
1100             $self->add( "/$k ",
1101 45 50       2938 ref $self->{'trailer'}{$k} eq 'ARRAY' ? join( ' ', @{ $self->{'trailer'}{$k} } ) : $self->{'trailer'}{$k} );
  0         0  
1102 45         2875 $self->cr;
1103             }
1104 15         937 $self->add('>>');
1105 15         928 $self->cr;
1106 15         968 $self->add('startxref');
1107 15         957 $self->cr;
1108 15         944 $self->add( $self->{'crossrefstartpoint'} );
1109 15         942 $self->cr;
1110 15         972 $self->add('%%EOF');
1111 15         934 $self->cr;
1112             }
1113              
1114             sub cr {
1115 1564     1564 0 95417 my ($self) = @_;
1116              
1117 1564         95960 debug( 3, "cr():" );
1118 1564         95879 $self->add( &encode('cr') );
1119             }
1120              
1121             sub page_stream {
1122 562     562 0 5779 my ($self, $page) = @_;
1123              
1124 562         5921 debug( 2, "page_stream():" );
1125              
1126 562 100       6267 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     7702 && $self->{'stream_page'} == $page;
      100        
      100        
1133              
1134             # Remember the position
1135 27         2826 my $len = $self->position - $self->{'stream_pos'} + 1;
1136              
1137             # Close the stream and the object
1138 27         3052 $self->cr;
1139 27         2695 $self->add('endstream');
1140 27         2633 $self->cr;
1141 27         2705 $self->add('endobj');
1142 27         2741 $self->cr;
1143 27         2977 $self->cr;
1144              
1145             # Add the length
1146 27         2811 $self->add_object( $self->indirect_obj( $self->number($len), 'stream_length' ) );
1147 27         2951 $self->cr;
1148             }
1149              
1150             # open a new stream if needed
1151 42 100       4730 if (defined $page) {
1152              
1153             # get an object id for the stream
1154 27         2818 my $obj = $self->reserve('stream');
1155              
1156             # release it
1157 27         2836 delete $self->{'reservations'}{'stream'};
1158              
1159             # get another one for the length of this stream
1160 27         2642 my $stream_length = $self->reserve('stream_length');
1161 27         2813 push @$stream_length, 'R';
1162 27         2695 push @{ $page->{'contents'} }, $obj;
  27         5423  
1163              
1164             # write the beginning of the object
1165 27         2767 push @{ $self->{'crossrefsubsection'}{ $$obj[1] } }, [ $$obj[0], $self->position, 1 ];
  27         5531  
1166 27         2785 $self->add("$$obj[0] $$obj[1] obj");
1167 27         2712 $self->cr;
1168 27         3695 $self->add('<<');
1169 27         2795 $self->cr;
1170 27         2747 $self->add( '/Length ', join( ' ', @$stream_length ) );
1171 27         2703 $self->cr;
1172 27         2920 $self->add('>>');
1173 27         2675 $self->cr;
1174 27         2679 $self->add('stream');
1175 27         2653 $self->cr;
1176 27         2900 $self->{'stream_pos'} = $self->position;
1177 27         8365 $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 2954 my ($self, $page, $font) = @_;
1195              
1196 86         2897 $page->{'resources'}{'fonts'}{$font} = 1;
1197 86         2934 $page->{'resources'}{'ProcSet'} = [ 'PDF', 'Text' ];
1198 86         5622 $self->{'fontobj'}{$font} = 1;
1199             }
1200              
1201             sub uses_xobject {
1202 2     2 0 4 my ($self, $page, $xobject) = @_;
1203              
1204 2         4 $page->{'resources'}{'xobjects'}{$xobject} = 1;
1205 2         6 $page->{'resources'}{'ProcSet'} = [ 'PDF', 'Text' ];
1206 2         7 $self->{'xobj'}{$xobject} = 1;
1207             }
1208              
1209             sub debug {
1210 9204     9204 0 703014 my ($level, $msg) = @_;
1211              
1212 9204 50       1918047 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 171180 my $self = shift;
1220 2924         172706 my $data = join '', @_;
1221              
1222 2924         172418 $self->{'size'} += length $data;
1223 2924 100       172497 if ( defined $self->{'fh'} ) {
1224 2914         172943 my $fh = $self->{'fh'};
1225 2914         634752 print $fh $data;
1226             } else {
1227 10         14 $self->{'data'} .= $data;
1228             }
1229             }
1230              
1231             sub position {
1232 466     466 0 44391 my ($self) = @_;
1233              
1234 466         88119 $self->{'size'};
1235             }
1236              
1237             sub add_version {
1238 32     32 0 3777 my ($self) = @_;
1239              
1240 32         4301 debug( 2, "add_version(): $self->{'version'}" );
1241 32         4045 $self->add( "%PDF-" . $self->{'version'} );
1242 32         3831 $self->cr;
1243             }
1244              
1245             sub add_object {
1246 185     185 0 17004 my ($self, $v) = @_;
1247              
1248 185         17201 my $val = &encode(@$v);
1249 185         17110 $self->add($val);
1250 185         16892 $self->cr;
1251 185         17080 debug( 3, "add_object(): $v -> $val" );
1252 185         33864 [ $$v[1][0], $$v[1][1] ];
1253             }
1254              
1255             sub null {
1256 90     90 0 18030 my ($self) = @_;;
1257              
1258 90         36001 [ '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 11280 my ($self, $val) = @_;;
1269              
1270 143         26668 [ 'number', $val ];
1271             }
1272              
1273             sub name {
1274 396     396 0 34665 my ($self, $val) = @_;
1275              
1276 396         74063 [ 'name', $val ];
1277             }
1278              
1279             sub string {
1280 73     73 0 8955 my ($self, $val) = @_;
1281              
1282 73         17126 [ 'string', $val ];
1283             }
1284              
1285             sub verbatim {
1286 5     5 0 6 my ($self, $val) = @_;
1287              
1288 5         21 [ 'verbatim', $val ];
1289             }
1290              
1291             sub array {
1292 123     123 0 11455 my $self = shift;
1293              
1294 123         26927 [ 'array', [@_] ];
1295             }
1296              
1297             sub dictionary {
1298 197     197 0 15789 my $self = shift;
1299              
1300 197         35000 [ 'dictionary', {@_} ];
1301             }
1302              
1303             sub indirect_obj {
1304 185     185 0 16872 my $self = shift;
1305              
1306 185         17088 my ($id, $gen, $type, $name);
1307 185         17103 $name = $_[1];
1308             $type = $_[0][1]{'Type'}[1]
1309 185 100 66     18202 if defined $_[0][1] && ref $_[0][1] eq 'HASH' && defined $_[0][1]{'Type'};
      100        
1310              
1311 185 100 66     17531 if ( defined $name && defined $self->{'reservations'}{$name} ) {
    100 66        
1312 134         13489 ( $id, $gen ) = @{ $self->{'reservations'}{$name} };
  134         26778  
1313 134         27205 delete $self->{'reservations'}{$name};
1314             } elsif ( defined $type && defined $self->{'reservations'}{$type} ) {
1315 50         3673 ( $id, $gen ) = @{ $self->{'reservations'}{$type} };
  50         7316  
1316 50         7340 delete $self->{'reservations'}{$type};
1317             } else {
1318 1         3 $id = ++$self->{'object_number'};
1319 1         1 $gen = $self->{'generation_number'};
1320             }
1321 185         17304 debug( 3, "indirect_obj(): " . $self->position );
1322 185         17582 push @{ $self->{'crossrefsubsection'}{$gen} }, [ $id, $self->position, 1 ];
  185         34991  
1323 185         34739 [ 'object', [ $id, $gen, @_ ] ];
1324             }
1325              
1326             sub indirect_ref {
1327 313     313 0 36459 my $self = shift;
1328              
1329 313         85576 [ '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 921 my $self = shift;
1340              
1341 15         985 debug( 2, "add_info():" );
1342 15         982 my %params = @_;
1343 15 100       985 $params{'Author'} = $self->{'Author'} if defined $self->{'Author'};
1344 15 50       959 $params{'Creator'} = $self->{'Creator'} if defined $self->{'Creator'};
1345 15 100       974 $params{'Title'} = $self->{'Title'} if defined $self->{'Title'};
1346 15 50       976 $params{'Subject'} = $self->{'Subject'} if defined $self->{'Subject'};
1347 15 50       941 $params{'Keywords'} = $self->{'Keywords'} if defined $self->{'Keywords'};
1348             $params{'CreationDate'} = $self->{'CreationDate'}
1349 15 50       944 if defined $self->{'CreationDate'};
1350              
1351 15         1006 $self->{'info'} = $self->reserve('Info');
1352 15         1017 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       991 if defined $params{'Author'};
1358             $$content{'Creator'} = $self->string( $params{'Creator'} )
1359 15 50       940 if defined $params{'Creator'};
1360             $$content{'Title'} = $self->string( $params{'Title'} )
1361 15 100       1001 if defined $params{'Title'};
1362             $$content{'Subject'} = $self->string( $params{'Subject'} )
1363 15 50       951 if defined $params{'Subject'};
1364             $$content{'Keywords'} = $self->string( $params{'Keywords'} )
1365 15 50       978 if defined $params{'Keywords'};
1366             $$content{'CreationDate'} = $self->string( $params{'CreationDate'} )
1367 15 50       942 if defined $params{'CreationDate'};
1368              
1369 15         955 $self->add_object( $self->indirect_obj( $self->dictionary(%$content) ), 'Info' );
1370 15         1004 $self->cr;
1371             }
1372              
1373             sub add_catalog {
1374 15     15 0 897 my $self = shift;
1375              
1376 15         957 debug( 2, "add_catalog" );
1377 15         895 my %params = %{ $self->{'catalog'} };
  15         1878  
1378              
1379             # Type (mandatory)
1380 15         927 $self->{'catalog'} = $self->reserve('Catalog');
1381 15         1304 my $content = { 'Type' => $self->name('Catalog') };
1382              
1383             # Pages (mandatory) [indirected reference]
1384 15         917 my $pages = $self->reserve('Pages');
1385 15         939 $$content{'Pages'} = $self->indirect_ref(@$pages);
1386 15         916 $self->{'pages'}{'id'} = $$content{'Pages'}[1];
1387              
1388             # Outlines [indirected reference]
1389 5         1996 $$content{'Outlines'} = $self->indirect_ref( @{ $self->{'outlines'}->{'id'} } )
1390 15 100       917 if defined $self->{'outlines'};
1391              
1392             # PageMode
1393 15 100       1070 $$content{'PageMode'} = $self->name($params{'PageMode'}) if defined $params{'PageMode'};
1394              
1395 15         1026 $self->add_object( $self->indirect_obj( $self->dictionary(%$content) ) );
1396 15         930 $self->cr;
1397             }
1398              
1399             sub encode {
1400 6203     6203 0 529636 my ($type, $val) = @_;
1401              
1402 6203 100       524913 if ($val) {
1403 2748         260087 debug( 4, "encode(): $type $val" );
1404             } else {
1405 3455         267933 debug( 4, "encode(): $type (no val)" );
1406             }
1407              
1408 6203 100       526688 if (!$type) {
1409 1         151 cluck "PDF::Create::encode: empty argument, called by ";
1410 1         7 return 1;
1411             }
1412              
1413             ( $type eq 'null' || $type eq 'number' ) && do {
1414 1243         266730 1; # do nothing
1415             }
1416             || $type eq 'cr' && do {
1417 2915         420376 $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         15 $val = "$val";
1428             }
1429             || $type eq 'string' && do {
1430 77 100       8930 $val = '' if not defined $val;
1431             # TODO: split it. Quote parentheses.
1432 77         17128 $val = "($val)";
1433             }
1434             || $type eq 'number' && do {
1435 0         0 $val = "$val";
1436             }
1437             || $type eq 'name' && do {
1438 1128 100       90135 $val = '' if not defined $val;
1439 1128         180991 $val = "/$val";
1440             }
1441             || $type eq 'array' && do {
1442              
1443             # array, encode contents individually
1444 125         11205 my $s = '[';
1445 125         11566 for my $v (@$val) {
1446 327         11583 $s .= &encode( $$v[0], $$v[1] ) . " ";
1447             }
1448             # remove the trailing space
1449 125         10919 chop $s;
1450 125         22001 $val = $s . "]";
1451             }
1452             || $type eq 'dictionary' && do {
1453 197         16172 my $s = '<<' . &encode('cr');
1454 197         16305 for my $v ( keys %$val ) {
1455 743         66593 $s .= &encode( 'name', $v ) . " ";
1456 743         66181 $s .= &encode( ${ $$val{$v} }[0], ${ $$val{$v} }[1] ); # . " ";
  743         130771  
  743         132516  
1457 743         66564 $s .= &encode('cr');
1458             }
1459 197         32192 $val = $s . ">>";
1460             }
1461             || $type eq 'object' && do {
1462 186         17189 my $s = &encode( 'number', $$val[0] ) . " " . &encode( 'number', $$val[1] ) . " obj";
1463 186         16601 $s .= &encode('cr');
1464 186         16750 $s .= &encode( $$val[2][0], $$val[2][1] ); # . " ";
1465 186         16937 $s .= &encode('cr');
1466 186         34388 $val = $s . "endobj";
1467             }
1468             || $type eq 'ref' && do {
1469 315         37466 my $s = &encode( 'number', $$val[0] ) . " " . &encode( 'number', $$val[1] ) . " R";
1470 315         72892 $val = $s;
1471             }
1472 6202 100 100     560538 || $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         5 my $data = delete $$val{'Data'};
1474 3         6 my $s = '<<' . &encode('cr');
1475 3         8 for my $v ( keys %$val ) {
1476 22         22 $s .= &encode( 'name', $v ) . " ";
1477 22         16 $s .= &encode( ${ $$val{$v} }[0], ${ $$val{$v} }[1] ); # . " ";
  22         22  
  22         21  
1478 22         23 $s .= &encode('cr');
1479             }
1480 3         5 $s .= ">>" . &encode('cr') . "stream" . &encode('cr');
1481 3         4 $s .= $data . &encode('cr');
1482 3         18 $val = $s . "endstream" . &encode('cr');
1483             }
1484             || confess "Error: unknown type '$type'";
1485              
1486             # TODO: add type 'text';
1487 6201         1073078 $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;