.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.29)
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" Set up some character translations and predefined strings. \*(-- will
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
.\" double quote, and \*(R" will give a right double quote. \*(C+ will
.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
.\" nothing in troff, for use with C<>.
.tr \(*W-
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
.ie n \{\
. ds -- \(*W-
. ds PI pi
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
. ds L" ""
. ds R" ""
. ds C` ""
. ds C' ""
'br\}
.el\{\
. ds -- \|\(em\|
. ds PI \(*p
. ds L" ``
. ds R" ''
. ds C`
. ds C'
'br\}
.\"
.\" Escape single quotes in literal strings from groff's Unicode transform.
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
.\" If the F register is turned on, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.\"
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
.nr rF 0
.if \n(.g .if rF .nr rF 1
.if (\n(rF:(\n(.g==0)) \{
. if \nF \{
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
..
. if !\nF==2 \{
. nr % 0
. nr F 2
. \}
. \}
.\}
.rr rF
.\"
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
.\" Fear. Run. Save yourself. No user-serviceable parts.
. \" fudge factors for nroff and troff
.if n \{\
. ds #H 0
. ds #V .8m
. ds #F .3m
. ds #[ \f1
. ds #] \fP
.\}
.if t \{\
. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
. ds #V .6m
. ds #F 0
. ds #[ \&
. ds #] \&
.\}
. \" simple accents for nroff and troff
.if n \{\
. ds ' \&
. ds ` \&
. ds ^ \&
. ds , \&
. ds ~ ~
. ds /
.\}
.if t \{\
. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
.\}
. \" troff and (daisy-wheel) nroff accents
.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
.ds ae a\h'-(\w'a'u*4/10)'e
.ds Ae A\h'-(\w'A'u*4/10)'E
. \" corrections for vroff
.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
. \" for low resolution devices (crt and lpr)
.if \n(.H>23 .if \n(.V>19 \
\{\
. ds : e
. ds 8 ss
. ds o a
. ds d- d\h'-1'\(ga
. ds D- D\h'-1'\(hy
. ds th \o'bp'
. ds Th \o'LP'
. ds ae ae
. ds Ae AE
.\}
.rm #[ #] #H #V #F C
.\" ========================================================================
.\"
.IX Title "CAM::PDF 3pm"
.TH CAM::PDF 3pm "2016-05-29" "perl v5.22.2" "User Contributed Perl Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
.SH "NAME"
CAM::PDF \- PDF manipulation library
.SH "LICENSE"
.IX Header "LICENSE"
Copyright 2002\-2006 Clotho Advanced Media, Inc.,
.PP
Copyright 2007\-2008 Chris Dolan
.PP
This library is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.
.SH "SYNOPSIS"
.IX Header "SYNOPSIS"
.Vb 1
\& use CAM::PDF;
\&
\& my $pdf = CAM::PDF\->new(\*(Aqtest1.pdf\*(Aq);
\&
\& my $page1 = $pdf\->getPageContent(1);
\& [ ... mess with page ... ]
\& $pdf\->setPageContent(1, $page1);
\& [ ... create some new content ... ]
\& $pdf\->appendPageContent(1, $newcontent);
\&
\& my $anotherpdf = CAM::PDF\->new(\*(Aqtest2.pdf\*(Aq);
\& $pdf\->appendPDF($anotherpdf);
\&
\& my @prefs = $pdf\->getPrefs();
\& $prefs[$CAM::PDF::PREF_OPASS] = \*(Aqmypassword\*(Aq;
\& $prefs[$CAM::PDF::PREF_UPASS] = \*(Aqmypassword\*(Aq;
\& $pdf\->setPrefs(@prefs);
\&
\& $pdf\->cleanoutput(\*(Aqout1.pdf\*(Aq);
\& print $pdf\->toPDF();
.Ve
.PP
Many example programs are included in this distribution to do useful
tasks. See the \f(CW\*(C`bin\*(C'\fR subdirectory.
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
This package reads and writes any document that conforms to the \s-1PDF\s0
specification generously provided by Adobe at
(link last checked Oct 2005).
.PP
The file format through \s-1PDF 1.5\s0 is well-supported, with the exception
of the \*(L"linearized\*(R" or \*(L"optimized\*(R" output format, which this module
can read but not write. Many specific aspects of the document model
are not manipulable with this package (like fonts), but if the input
document is correctly written, then this module will preserve the
model integrity.
.PP
The \s-1PDF\s0 writing feature saves as \s-1PDF 1\s0.4\-compatible. That means that
we cannot write compressed object streams. The consequence is that
reading and then writing a \s-1PDF 1.5+\s0 document may enlarge the resulting
file by a fair margin.
.PP
This library grants you some power over the \s-1PDF\s0 security model. Note
that applications editing \s-1PDF\s0 documents via this library \s-1MUST\s0 respect
the security preferences of the document. Any violation of this
respect is contrary to Adobe's intellectual property position, as
stated in the reference manual at the above \s-1URL.\s0
.PP
Technical detail regarding corrupt PDFs: This library adheres strictly
to the \s-1PDF\s0 specification. Adobe's Acrobat Reader is more lenient,
allowing some corrupted PDFs to be viewable. Therefore, it is
possible that some PDFs may be readable by Acrobat that are illegible
to this library. In particular, files which have had line endings
converted to or from DOS/Windows style (i.e. CR-NL) may be rendered
unusable even though Acrobat does not complain. Future library
versions may relax the parser, but not yet.
.SH "API"
.IX Header "API"
.SS "Functions intended to be used externally"
.IX Subsection "Functions intended to be used externally"
.Vb 10
\& $self = CAM::PDF\->new(content | filename | \*(Aq\-\*(Aq)
\& $self\->toPDF()
\& $self\->needsSave()
\& $self\->save()
\& $self\->cleansave()
\& $self\->output(filename | \*(Aq\-\*(Aq)
\& $self\->cleanoutput(filename | \*(Aq\-\*(Aq)
\& $self\->previousRevision()
\& $self\->allRevisions()
\& $self\->preserveOrder()
\& $self\->appendObject(olddoc, oldnum, [follow=(1|0)])
\& $self\->replaceObject(newnum, olddoc, oldnum, [follow=(1|0)])
\& (olddoc can be undef in the above for adding new objects)
\& $self\->numPages()
\& $self\->getPageText(pagenum)
\& $self\->getPageDimensions(pagenum)
\& $self\->getPageContent(pagenum)
\& $self\->setPageContent(pagenum, content)
\& $self\->appendPageContent(pagenum, content)
\& $self\->deletePage(pagenum)
\& $self\->deletePages(pagenum, pagenum, ...)
\& $self\->extractPages(pagenum, pagenum, ...)
\& $self\->appendPDF(CAM::PDF object)
\& $self\->prependPDF(CAM::PDF object)
\& $self\->wrapString(string, width, fontsize, page, fontlabel)
\& $self\->getFontNames(pagenum)
\& $self\->addFont(page, fontname, fontlabel, [fontmetrics])
\& $self\->deEmbedFont(page, fontname, [newfontname])
\& $self\->deEmbedFontByBaseName(page, basename, [newfont])
\& $self\->getPrefs()
\& $self\->setPrefs()
\& $self\->canPrint()
\& $self\->canModify()
\& $self\->canCopy()
\& $self\->canAdd()
\& $self\->getFormFieldList()
\& $self\->fillFormFields(fieldname, value, [fieldname, value, ...])
\& or $self\->fillFormFields(%values)
\& $self\->clearFormFieldTriggers(fieldname, fieldname, ...)
.Ve
.PP
Note: 'clean' as in \fIcleansave()\fR and \fIcleanobject()\fR means write a fresh
\&\s-1PDF\s0 document. The alternative (e.g. \fIsave()\fR) reuses the existing doc
and just appends to it. Also note that 'clean' functions sort the
objects numerically. If you prefer that the new \s-1PDF\s0 docs more closely
resemble the old ones, call \fIpreserveOrder()\fR before \fIcleansave()\fR or
\&\fIcleanobject()\fR.
.SS "Slightly less external, but useful, functions"
.IX Subsection "Slightly less external, but useful, functions"
.Vb 10
\& $self\->toString()
\& $self\->getPage(pagenum)
\& $self\->getFont(pagenum, fontname)
\& $self\->getFonts(pagenum)
\& $self\->getStringWidth(fontdict, string)
\& $self\->getFormField(fieldname)
\& $self\->getFormFieldDict(object)
\& $self\->isLinearized()
\& $self\->decodeObject(objectnum)
\& $self\->decodeAll(any\-node)
\& $self\->decodeOne(dict\-node)
\& $self\->encodeObject(objectnum, filter)
\& $self\->encodeOne(any\-node, filter)
\& $self\->changeString(obj\-node, hashref)
.Ve
.SS "Deeper utilities"
.IX Subsection "Deeper utilities"
.Vb 12
\& $self\->pageAddName(pagenum, name, objectnum)
\& $self\->getPageObjnum(pagenum)
\& $self\->getPropertyNames(pagenum)
\& $self\->getProperty(pagenum, propname)
\& $self\->getValue(any\-node)
\& $self\->dereference(objectnum) or $self\->dereference(name,pagenum)
\& $self\->deleteObject(objectnum)
\& $self\->copyObject(obj\-node)
\& $self\->cacheObjects()
\& $self\->setObjNum(obj\-node, num)
\& $self\->getRefList(obj\-node)
\& $self\->changeRefKeys(obj\-node, hashref)
.Ve
.SS "More rarely needed utilities"
.IX Subsection "More rarely needed utilities"
.Vb 1
\& $self\->getObjValue(objectnum)
.Ve
.SS "Routines that should not be called"
.IX Subsection "Routines that should not be called"
.Vb 10
\& $self\->_startdoc()
\& $self\->delinearlize()
\& $self\->build*()
\& $self\->parse*()
\& $self\->write*()
\& $self\->*CB()
\& $self\->traverse()
\& $self\->fixDecode()
\& $self\->abbrevInlineImage()
\& $self\->unabbrevInlineImage()
\& $self\->cleanse()
\& $self\->clean()
\& $self\->createID()
.Ve
.SH "FUNCTIONS"
.IX Header "FUNCTIONS"
.SS "Object creation/manipulation"
.IX Subsection "Object creation/manipulation"
.ie n .IP "$doc\->new($package, $content)" 4
.el .IP "\f(CW$doc\fR\->new($package, \f(CW$content\fR)" 4
.IX Item "$doc->new($package, $content)"
.PD 0
.ie n .IP "$doc\->new($package, $content, $ownerpass, $userpass)" 4
.el .IP "\f(CW$doc\fR\->new($package, \f(CW$content\fR, \f(CW$ownerpass\fR, \f(CW$userpass\fR)" 4
.IX Item "$doc->new($package, $content, $ownerpass, $userpass)"
.ie n .IP "$doc\->new($package, $content, $ownerpass, $userpass, $prompt)" 4
.el .IP "\f(CW$doc\fR\->new($package, \f(CW$content\fR, \f(CW$ownerpass\fR, \f(CW$userpass\fR, \f(CW$prompt\fR)" 4
.IX Item "$doc->new($package, $content, $ownerpass, $userpass, $prompt)"
.ie n .IP "$doc\->new($package, $content, $ownerpass, $userpass, $options)" 4
.el .IP "\f(CW$doc\fR\->new($package, \f(CW$content\fR, \f(CW$ownerpass\fR, \f(CW$userpass\fR, \f(CW$options\fR)" 4
.IX Item "$doc->new($package, $content, $ownerpass, $userpass, $options)"
.PD
Instantiate a new \s-1CAM::PDF\s0 object. \f(CW$content\fR can be a document in a
string, a filename, or '\-'. The latter indicates that the document
should be read from standard input. If the document is password
protected, the passwords should be passed as additional arguments. If
they are not known, a boolean \f(CW$prompt\fR argument allows the programmer to
suggest that the constructor prompt the user for a password. This is
rudimentary prompting: passwords are in the clear on the console.
.Sp
This constructor takes an optional final argument which is a hash
reference. This hash can contain any of the following optional
parameters:
.RS 4
.ie n .IP "prompt_for_password => $boolean" 4
.el .IP "prompt_for_password => \f(CW$boolean\fR" 4
.IX Item "prompt_for_password => $boolean"
This is the same as the \f(CW$prompt\fR argument described above.
.ie n .IP "fault_tolerant => $boolean" 4
.el .IP "fault_tolerant => \f(CW$boolean\fR" 4
.IX Item "fault_tolerant => $boolean"
This flag causes the instance to be more lenient when reading the
input \s-1PDF. \s0 Currently, this only affects PDFs which cannot be
successfully decrypted.
.RE
.RS 4
.RE
.ie n .IP "$doc\->\fItoPDF()\fR" 4
.el .IP "\f(CW$doc\fR\->\fItoPDF()\fR" 4
.IX Item "$doc->toPDF()"
Serializes the data structure as a \s-1PDF\s0 document stream and returns as
in a scalar.
.ie n .IP "$doc\->\fItoString()\fR" 4
.el .IP "\f(CW$doc\fR\->\fItoString()\fR" 4
.IX Item "$doc->toString()"
Returns a serialized representation of the data structure.
Implemented via Data::Dumper.
.SS "Document reading"
.IX Subsection "Document reading"
(all of these functions are intended for internal only)
.ie n .IP "$doc\->\fIgetRootDict()\fR" 4
.el .IP "\f(CW$doc\fR\->\fIgetRootDict()\fR" 4
.IX Item "$doc->getRootDict()"
Returns the Root dictionary for the \s-1PDF.\s0
.ie n .IP "$doc\->\fIgetPagesDict()\fR" 4
.el .IP "\f(CW$doc\fR\->\fIgetPagesDict()\fR" 4
.IX Item "$doc->getPagesDict()"
Returns the root Pages dictionary for the \s-1PDF.\s0
.ie n .IP "$doc\->parseObj($string)" 4
.el .IP "\f(CW$doc\fR\->parseObj($string)" 4
.IX Item "$doc->parseObj($string)"
Use \fIparseAny()\fR instead of this, if possible.
.Sp
Given a fragment of \s-1PDF\s0 page content, parse it and return an object
Node. This can be called as a class method in most circumstances, but
is intended as an instance method.
.ie n .IP "$doc\->parseInlineImage($string)" 4
.el .IP "\f(CW$doc\fR\->parseInlineImage($string)" 4
.IX Item "$doc->parseInlineImage($string)"
.PD 0
.ie n .IP "$doc\->parseInlineImage($string, $objnum)" 4
.el .IP "\f(CW$doc\fR\->parseInlineImage($string, \f(CW$objnum\fR)" 4
.IX Item "$doc->parseInlineImage($string, $objnum)"
.ie n .IP "$doc\->parseInlineImage($string, $objnum, $gennum)" 4
.el .IP "\f(CW$doc\fR\->parseInlineImage($string, \f(CW$objnum\fR, \f(CW$gennum\fR)" 4
.IX Item "$doc->parseInlineImage($string, $objnum, $gennum)"
.PD
Given a fragment of \s-1PDF\s0 page content, parse it and return an object
Node. This can be called as a class method in some cases, but
is intended as an instance method.
.ie n .IP "$doc\->writeInlineImage($objectnode)" 4
.el .IP "\f(CW$doc\fR\->writeInlineImage($objectnode)" 4
.IX Item "$doc->writeInlineImage($objectnode)"
This is the inverse of \fIparseInlineImage()\fR, intended for use only in
the CAM::PDF::Content class.
.ie n .IP "$doc\->parseStream($string, $objnum, $gennum, $dictnode)" 4
.el .IP "\f(CW$doc\fR\->parseStream($string, \f(CW$objnum\fR, \f(CW$gennum\fR, \f(CW$dictnode\fR)" 4
.IX Item "$doc->parseStream($string, $objnum, $gennum, $dictnode)"
This should only be used by \fIparseObj()\fR, or other specialized cases.
.Sp
Given a fragment of \s-1PDF\s0 page content, parse it and return a stream
Node. This can be called as a class method in most circumstances, but
is intended as an instance method.
.Sp
The dictionary Node argument is typically the body of the object Node
that precedes this stream.
.ie n .IP "$doc\->parseDict($string)" 4
.el .IP "\f(CW$doc\fR\->parseDict($string)" 4
.IX Item "$doc->parseDict($string)"
.PD 0
.ie n .IP "$doc\->parseDict($string, $objnum)" 4
.el .IP "\f(CW$doc\fR\->parseDict($string, \f(CW$objnum\fR)" 4
.IX Item "$doc->parseDict($string, $objnum)"
.ie n .IP "$doc\->parseDict($string, $objnum, $gennum)" 4
.el .IP "\f(CW$doc\fR\->parseDict($string, \f(CW$objnum\fR, \f(CW$gennum\fR)" 4
.IX Item "$doc->parseDict($string, $objnum, $gennum)"
.PD
Use \fIparseAny()\fR instead of this, if possible.
.Sp
Given a fragment of \s-1PDF\s0 page content, parse it and return an dictionary
Node. This can be called as a class method in most circumstances, but
is intended as an instance method.
.ie n .IP "$doc\->parseArray($string)" 4
.el .IP "\f(CW$doc\fR\->parseArray($string)" 4
.IX Item "$doc->parseArray($string)"
.PD 0
.ie n .IP "$doc\->parseArray($string, $objnum)" 4
.el .IP "\f(CW$doc\fR\->parseArray($string, \f(CW$objnum\fR)" 4
.IX Item "$doc->parseArray($string, $objnum)"
.ie n .IP "$doc\->parseArray($string, $objnum, $gennum)" 4
.el .IP "\f(CW$doc\fR\->parseArray($string, \f(CW$objnum\fR, \f(CW$gennum\fR)" 4
.IX Item "$doc->parseArray($string, $objnum, $gennum)"
.PD
Use \fIparseAny()\fR instead of this, if possible.
.Sp
Given a fragment of \s-1PDF\s0 page content, parse it and return an array
Node. This can be called as a class or instance method.
.ie n .IP "$doc\->parseLabel($string)" 4
.el .IP "\f(CW$doc\fR\->parseLabel($string)" 4
.IX Item "$doc->parseLabel($string)"
.PD 0
.ie n .IP "$doc\->parseLabel($string, $objnum)" 4
.el .IP "\f(CW$doc\fR\->parseLabel($string, \f(CW$objnum\fR)" 4
.IX Item "$doc->parseLabel($string, $objnum)"
.ie n .IP "$doc\->parseLabel($string, $objnum, $gennum)" 4
.el .IP "\f(CW$doc\fR\->parseLabel($string, \f(CW$objnum\fR, \f(CW$gennum\fR)" 4
.IX Item "$doc->parseLabel($string, $objnum, $gennum)"
.PD
Use \fIparseAny()\fR instead of this, if possible.
.Sp
Given a fragment of \s-1PDF\s0 page content, parse it and return a label
Node. This can be called as a class or instance method.
.ie n .IP "$doc\->parseRef($string)" 4
.el .IP "\f(CW$doc\fR\->parseRef($string)" 4
.IX Item "$doc->parseRef($string)"
.PD 0
.ie n .IP "$doc\->parseRef($string, $objnum)" 4
.el .IP "\f(CW$doc\fR\->parseRef($string, \f(CW$objnum\fR)" 4
.IX Item "$doc->parseRef($string, $objnum)"
.ie n .IP "$doc\->parseRef($string, $objnum, $gennum)" 4
.el .IP "\f(CW$doc\fR\->parseRef($string, \f(CW$objnum\fR, \f(CW$gennum\fR)" 4
.IX Item "$doc->parseRef($string, $objnum, $gennum)"
.PD
Use \fIparseAny()\fR instead of this, if possible.
.Sp
Given a fragment of \s-1PDF\s0 page content, parse it and return a reference
Node. This can be called as a class or instance method.
.ie n .IP "$doc\->parseNum($string)" 4
.el .IP "\f(CW$doc\fR\->parseNum($string)" 4
.IX Item "$doc->parseNum($string)"
.PD 0
.ie n .IP "$doc\->parseNum($string, $objnum)" 4
.el .IP "\f(CW$doc\fR\->parseNum($string, \f(CW$objnum\fR)" 4
.IX Item "$doc->parseNum($string, $objnum)"
.ie n .IP "$doc\->parseNum($string, $objnum, $gennum)" 4
.el .IP "\f(CW$doc\fR\->parseNum($string, \f(CW$objnum\fR, \f(CW$gennum\fR)" 4
.IX Item "$doc->parseNum($string, $objnum, $gennum)"
.PD
Use \fIparseAny()\fR instead of this, if possible.
.Sp
Given a fragment of \s-1PDF\s0 page content, parse it and return a number
Node. This can be called as a class or instance method.
.ie n .IP "$doc\->parseString($string)" 4
.el .IP "\f(CW$doc\fR\->parseString($string)" 4
.IX Item "$doc->parseString($string)"
.PD 0
.ie n .IP "$doc\->parseString($string, $objnum)" 4
.el .IP "\f(CW$doc\fR\->parseString($string, \f(CW$objnum\fR)" 4
.IX Item "$doc->parseString($string, $objnum)"
.ie n .IP "$doc\->parseString($string, $objnum, $gennum)" 4
.el .IP "\f(CW$doc\fR\->parseString($string, \f(CW$objnum\fR, \f(CW$gennum\fR)" 4
.IX Item "$doc->parseString($string, $objnum, $gennum)"
.PD
Use \fIparseAny()\fR instead of this, if possible.
.Sp
Given a fragment of \s-1PDF\s0 page content, parse it and return a string
Node. This can be called as a class or instance method.
.ie n .IP "$doc\->parseHexString($string)" 4
.el .IP "\f(CW$doc\fR\->parseHexString($string)" 4
.IX Item "$doc->parseHexString($string)"
.PD 0
.ie n .IP "$doc\->parseHexString($string, $objnum)" 4
.el .IP "\f(CW$doc\fR\->parseHexString($string, \f(CW$objnum\fR)" 4
.IX Item "$doc->parseHexString($string, $objnum)"
.ie n .IP "$doc\->parseHexString($string, $objnum, $gennum)" 4
.el .IP "\f(CW$doc\fR\->parseHexString($string, \f(CW$objnum\fR, \f(CW$gennum\fR)" 4
.IX Item "$doc->parseHexString($string, $objnum, $gennum)"
.PD
Use \fIparseAny()\fR instead of this, if possible.
.Sp
Given a fragment of \s-1PDF\s0 page content, parse it and return a hex string
Node. This can be called as a class or instance method.
.ie n .IP "$doc\->parseBoolean($string)" 4
.el .IP "\f(CW$doc\fR\->parseBoolean($string)" 4
.IX Item "$doc->parseBoolean($string)"
.PD 0
.ie n .IP "$doc\->parseBoolean($string, $objnum)" 4
.el .IP "\f(CW$doc\fR\->parseBoolean($string, \f(CW$objnum\fR)" 4
.IX Item "$doc->parseBoolean($string, $objnum)"
.ie n .IP "$doc\->parseBoolean($string, $objnum, $gennum)" 4
.el .IP "\f(CW$doc\fR\->parseBoolean($string, \f(CW$objnum\fR, \f(CW$gennum\fR)" 4
.IX Item "$doc->parseBoolean($string, $objnum, $gennum)"
.PD
Use \fIparseAny()\fR instead of this, if possible.
.Sp
Given a fragment of \s-1PDF\s0 page content, parse it and return a boolean
Node. This can be called as a class or instance method.
.ie n .IP "$doc\->parseNull($string)" 4
.el .IP "\f(CW$doc\fR\->parseNull($string)" 4
.IX Item "$doc->parseNull($string)"
.PD 0
.ie n .IP "$doc\->parseNull($string, $objnum)" 4
.el .IP "\f(CW$doc\fR\->parseNull($string, \f(CW$objnum\fR)" 4
.IX Item "$doc->parseNull($string, $objnum)"
.ie n .IP "$doc\->parseNull($string, $objnum, $gennum)" 4
.el .IP "\f(CW$doc\fR\->parseNull($string, \f(CW$objnum\fR, \f(CW$gennum\fR)" 4
.IX Item "$doc->parseNull($string, $objnum, $gennum)"
.PD
Use \fIparseAny()\fR instead of this, if possible.
.Sp
Given a fragment of \s-1PDF\s0 page content, parse it and return a null
Node. This can be called as a class or instance method.
.ie n .IP "$doc\->parseAny($string)" 4
.el .IP "\f(CW$doc\fR\->parseAny($string)" 4
.IX Item "$doc->parseAny($string)"
.PD 0
.ie n .IP "$doc\->parseAny($string, $objnum)" 4
.el .IP "\f(CW$doc\fR\->parseAny($string, \f(CW$objnum\fR)" 4
.IX Item "$doc->parseAny($string, $objnum)"
.ie n .IP "$doc\->parseAny($string, $objnum, $gennum)" 4
.el .IP "\f(CW$doc\fR\->parseAny($string, \f(CW$objnum\fR, \f(CW$gennum\fR)" 4
.IX Item "$doc->parseAny($string, $objnum, $gennum)"
.PD
Given a fragment of \s-1PDF\s0 page content, parse it and return a Node of
the appropriate type. This can be called as a class or instance
method.
.SS "Data Accessors"
.IX Subsection "Data Accessors"
.ie n .IP "$doc\->getValue($object)" 4
.el .IP "\f(CW$doc\fR\->getValue($object)" 4
.IX Item "$doc->getValue($object)"
\&\fIFor \s-1INTERNAL\s0 use\fR
.Sp
Dereference a data object, return a value. Given an node object
of any kind, returns raw scalar object: hashref, arrayref, string,
number. This function follows all references, and descends into all
objects.
.ie n .IP "$doc\->getObjValue($objectnum)" 4
.el .IP "\f(CW$doc\fR\->getObjValue($objectnum)" 4
.IX Item "$doc->getObjValue($objectnum)"
\&\fIFor \s-1INTERNAL\s0 use\fR
.Sp
Dereference a data object, and return a value. Behaves just like the
\&\fIgetValue()\fR function, but used when all you know is the object number.
.ie n .IP "$doc\->dereference($objectnum)" 4
.el .IP "\f(CW$doc\fR\->dereference($objectnum)" 4
.IX Item "$doc->dereference($objectnum)"
.PD 0
.ie n .IP "$doc\->dereference($name, $pagenum)" 4
.el .IP "\f(CW$doc\fR\->dereference($name, \f(CW$pagenum\fR)" 4
.IX Item "$doc->dereference($name, $pagenum)"
.PD
\&\fIFor \s-1INTERNAL\s0 use\fR
.Sp
Dereference a data object, return a \s-1PDF\s0 object as a node. This
function makes heavy use of the internal object cache. Most (if not
all) object requests should go through this function.
.Sp
\&\f(CW$name\fR should look something like '/R12'.
.ie n .IP "$doc\->getPropertyNames($pagenum)" 4
.el .IP "\f(CW$doc\fR\->getPropertyNames($pagenum)" 4
.IX Item "$doc->getPropertyNames($pagenum)"
.PD 0
.ie n .IP "$doc\->getProperty($pagenum, $propertyname)" 4
.el .IP "\f(CW$doc\fR\->getProperty($pagenum, \f(CW$propertyname\fR)" 4
.IX Item "$doc->getProperty($pagenum, $propertyname)"
.PD
Each \s-1PDF\s0 page contains a list of resources that it uses (images,
fonts, etc). \fIgetPropertyNames()\fR returns an array of the names of
those resources. \fIgetProperty()\fR returns a node representing a
named property (most likely a reference node).
.ie n .IP "$doc\->getFont($pagenum, $fontname)" 4
.el .IP "\f(CW$doc\fR\->getFont($pagenum, \f(CW$fontname\fR)" 4
.IX Item "$doc->getFont($pagenum, $fontname)"
\&\fIFor \s-1INTERNAL\s0 use\fR
.Sp
Returns a dictionary for a given font identified by its label,
referenced by page.
.ie n .IP "$doc\->getFontNames($pagenum)" 4
.el .IP "\f(CW$doc\fR\->getFontNames($pagenum)" 4
.IX Item "$doc->getFontNames($pagenum)"
\&\fIFor \s-1INTERNAL\s0 use\fR
.Sp
Returns a list of fonts for a given page.
.ie n .IP "$doc\->getFonts($pagenum)" 4
.el .IP "\f(CW$doc\fR\->getFonts($pagenum)" 4
.IX Item "$doc->getFonts($pagenum)"
\&\fIFor \s-1INTERNAL\s0 use\fR
.Sp
Returns an array of font objects for a given page.
.ie n .IP "$doc\->getFontByBaseName($pagenum, $fontname)" 4
.el .IP "\f(CW$doc\fR\->getFontByBaseName($pagenum, \f(CW$fontname\fR)" 4
.IX Item "$doc->getFontByBaseName($pagenum, $fontname)"
\&\fIFor \s-1INTERNAL\s0 use\fR
.Sp
Returns a dictionary for a given font, referenced by page and the name
of the base font.
.ie n .IP "$doc\->getFontMetrics($properties $fontname)" 4
.el .IP "\f(CW$doc\fR\->getFontMetrics($properties \f(CW$fontname\fR)" 4
.IX Item "$doc->getFontMetrics($properties $fontname)"
\&\fIFor \s-1INTERNAL\s0 use\fR
.Sp
Returns a data structure representing the font metrics for the named
font. The property list is the results of something like the
following:
.Sp
.Vb 2
\& $self\->_buildNameTable($pagenum);
\& my $properties = $self\->{Names}\->{$pagenum};
.Ve
.Sp
Alternatively, if you know the page number, it might be easier to do:
.Sp
.Vb 2
\& my $font = $self\->dereference($fontlabel, $pagenum);
\& my $fontmetrics = $font\->{value}\->{value};
.Ve
.Sp
where the \f(CW$fontlabel\fR is something like '/Helv'. The \fIgetFontMetrics()\fR
method is useful in the cases where you've forgotten which page number
you are working on (e.g. in \s-1CAM::PDF::GS\s0), or if your property list
isn't part of any page (e.g. working with form field annotation
objects).
.ie n .IP "$doc\->addFont($pagenum, $fontname, $fontlabel)" 4
.el .IP "\f(CW$doc\fR\->addFont($pagenum, \f(CW$fontname\fR, \f(CW$fontlabel\fR)" 4
.IX Item "$doc->addFont($pagenum, $fontname, $fontlabel)"
.PD 0
.ie n .IP "$doc\->addFont($pagenum, $fontname, $fontlabel, $fontmetrics)" 4
.el .IP "\f(CW$doc\fR\->addFont($pagenum, \f(CW$fontname\fR, \f(CW$fontlabel\fR, \f(CW$fontmetrics\fR)" 4
.IX Item "$doc->addFont($pagenum, $fontname, $fontlabel, $fontmetrics)"
.PD
Adds a reference to the specified font to the page.
.Sp
If a font metrics hash is supplied (it is required for a font other
than the 14 core fonts), then it is cloned and inserted into the new
font structure. Note that if those font metrics contain references
(e.g. to the \f(CW\*(C`FontDescriptor\*(C'\fR), the referred objects are not copied \*(--
you must do that part yourself.
.Sp
For Type1 fonts, the font metrics must minimally contain the following
fields: \f(CW\*(C`Subtype\*(C'\fR, \f(CW\*(C`FirstChar\*(C'\fR, \f(CW\*(C`LastChar\*(C'\fR, \f(CW\*(C`Widths\*(C'\fR,
\&\f(CW\*(C`FontDescriptor\*(C'\fR.
.ie n .IP "$doc\->deEmbedFont($pagenum, $fontname)" 4
.el .IP "\f(CW$doc\fR\->deEmbedFont($pagenum, \f(CW$fontname\fR)" 4
.IX Item "$doc->deEmbedFont($pagenum, $fontname)"
.PD 0
.ie n .IP "$doc\->deEmbedFont($pagenum, $fontname, $basefont)" 4
.el .IP "\f(CW$doc\fR\->deEmbedFont($pagenum, \f(CW$fontname\fR, \f(CW$basefont\fR)" 4
.IX Item "$doc->deEmbedFont($pagenum, $fontname, $basefont)"
.PD
Removes embedded font data, leaving font reference intact. Returns
true if the font exists and 1) font is not embedded or 2) embedded
data was successfully discarded. Returns false if the font does not
exist, or the embedded data could not be discarded.
.Sp
The optional \f(CW$basefont\fR parameter allows you to change the font. This
is useful when some applications embed a standard font (see below) and
give it a funny name, like \f(CW\*(C`SYLXNP+Helvetica\*(C'\fR. In this example, it's
important to change the basename back to the standard \f(CW\*(C`Helvetica\*(C'\fR when
de-embedding.
.Sp
De-embedding the font does \s-1NOT\s0 remove it from the \s-1PDF\s0 document, it
just removes references to it. To get a size reduction by throwing
away unused font data, you should use the following code sometime
after this method.
.Sp
.Vb 1
\& $self\->cleanse();
.Ve
.Sp
For reference, the standard fonts are \f(CW\*(C`Times\-Roman\*(C'\fR, \f(CW\*(C`Helvetica\*(C'\fR, and
\&\f(CW\*(C`Courier\*(C'\fR (and their bold, italic and bold-italic forms) plus \f(CW\*(C`Symbol\*(C'\fR and
\&\f(CW\*(C`Zapfdingbats\*(C'\fR. (Adobe \s-1PDF\s0 Reference v1.4, p.319)
.ie n .IP "$doc\->deEmbedFontByBaseName($pagenum, $fontname)" 4
.el .IP "\f(CW$doc\fR\->deEmbedFontByBaseName($pagenum, \f(CW$fontname\fR)" 4
.IX Item "$doc->deEmbedFontByBaseName($pagenum, $fontname)"
.PD 0
.ie n .IP "$doc\->deEmbedFontByBaseName($pagenum, $fontname, $basefont)" 4
.el .IP "\f(CW$doc\fR\->deEmbedFontByBaseName($pagenum, \f(CW$fontname\fR, \f(CW$basefont\fR)" 4
.IX Item "$doc->deEmbedFontByBaseName($pagenum, $fontname, $basefont)"
.PD
Just like \fIdeEmbedFont()\fR, except that the font name parameter refers to
the name of the current base font instead of the \s-1PDF\s0 label for the
font.
.ie n .IP "$doc\->wrapString($string, $width, $fontsize, $fontmetrics)" 4
.el .IP "\f(CW$doc\fR\->wrapString($string, \f(CW$width\fR, \f(CW$fontsize\fR, \f(CW$fontmetrics\fR)" 4
.IX Item "$doc->wrapString($string, $width, $fontsize, $fontmetrics)"
.PD 0
.ie n .IP "$doc\->wrapString($string, $width, $fontsize, $pagenum, $fontlabel)" 4
.el .IP "\f(CW$doc\fR\->wrapString($string, \f(CW$width\fR, \f(CW$fontsize\fR, \f(CW$pagenum\fR, \f(CW$fontlabel\fR)" 4
.IX Item "$doc->wrapString($string, $width, $fontsize, $pagenum, $fontlabel)"
.PD
Returns an array of strings wrapped to the specified width.
.ie n .IP "$doc\->getStringWidth($fontmetrics, $string)" 4
.el .IP "\f(CW$doc\fR\->getStringWidth($fontmetrics, \f(CW$string\fR)" 4
.IX Item "$doc->getStringWidth($fontmetrics, $string)"
\&\fIFor \s-1INTERNAL\s0 use\fR
.Sp
Returns the width of the string, using the font metrics if possible.
.ie n .IP "$doc\->\fInumPages()\fR" 4
.el .IP "\f(CW$doc\fR\->\fInumPages()\fR" 4
.IX Item "$doc->numPages()"
Returns the number of pages in the \s-1PDF\s0 document.
.ie n .IP "$doc\->getPage($pagenum)" 4
.el .IP "\f(CW$doc\fR\->getPage($pagenum)" 4
.IX Item "$doc->getPage($pagenum)"
\&\fIFor \s-1INTERNAL\s0 use\fR
.Sp
Returns a dictionary for a given numbered page.
.ie n .IP "$doc\->getPageObjnum($pagenum)" 4
.el .IP "\f(CW$doc\fR\->getPageObjnum($pagenum)" 4
.IX Item "$doc->getPageObjnum($pagenum)"
\&\fIFor \s-1INTERNAL\s0 use\fR
.Sp
Return the number of the \s-1PDF\s0 object in which the specified page occurs.
.ie n .IP "$doc\->getPageText($pagenum)" 4
.el .IP "\f(CW$doc\fR\->getPageText($pagenum)" 4
.IX Item "$doc->getPageText($pagenum)"
Extracts the text from a \s-1PDF\s0 page as a string.
.ie n .IP "$doc\->getPageContentTree($pagenum)" 4
.el .IP "\f(CW$doc\fR\->getPageContentTree($pagenum)" 4
.IX Item "$doc->getPageContentTree($pagenum)"
Retrieves a parsed page content data structure, or undef if there is a
syntax error or if the page does not exist.
.ie n .IP "$doc\->getPageContent($pagenum)" 4
.el .IP "\f(CW$doc\fR\->getPageContent($pagenum)" 4
.IX Item "$doc->getPageContent($pagenum)"
Return a string with the layout contents of one page.
.ie n .IP "$doc\->getPageDimensions($pagenum)" 4
.el .IP "\f(CW$doc\fR\->getPageDimensions($pagenum)" 4
.IX Item "$doc->getPageDimensions($pagenum)"
Returns an array of \f(CW\*(C`x\*(C'\fR, \f(CW\*(C`y\*(C'\fR, \f(CW\*(C`width\*(C'\fR and \f(CW\*(C`height\*(C'\fR numbers that
define the dimensions of the specified page in points (1/72 inches).
Technically, this is the \f(CW\*(C`MediaBox\*(C'\fR dimensions, which explains why
it's possible for \f(CW\*(C`x\*(C'\fR and \f(CW\*(C`y\*(C'\fR to be non-zero, but that's a rare
case.
.Sp
For example, given a simple 8.5 by 11 inch page, this method will return
\&\f(CW\*(C`(0,0,612,792)\*(C'\fR.
.Sp
This method will \fIdie()\fR if the specified page number does not exist.
.ie n .IP "$doc\->getName($object)" 4
.el .IP "\f(CW$doc\fR\->getName($object)" 4
.IX Item "$doc->getName($object)"
\&\fIFor \s-1INTERNAL\s0 use\fR
.Sp
Given a \s-1PDF\s0 object reference, return it's name, if it has one. This
is useful for indirect references to images in particular.
.ie n .IP "$doc\->\fIgetPrefs()\fR" 4
.el .IP "\f(CW$doc\fR\->\fIgetPrefs()\fR" 4
.IX Item "$doc->getPrefs()"
Return an array of security information for the document:
.Sp
.Vb 6
\& owner password
\& user password
\& print boolean
\& modify boolean
\& copy boolean
\& add boolean
.Ve
.Sp
See the \s-1PDF\s0 reference for the intended use of the latter four booleans.
.Sp
This module publishes the array indices of these values for your
convenience:
.Sp
.Vb 6
\& $CAM::PDF::PREF_OPASS
\& $CAM::PDF::PREF_UPASS
\& $CAM::PDF::PREF_PRINT
\& $CAM::PDF::PREF_MODIFY
\& $CAM::PDF::PREF_COPY
\& $CAM::PDF::PREF_ADD
.Ve
.Sp
So, you can retrieve the value of the Copy boolean via:
.Sp
.Vb 1
\& my ($canCopy) = ($self\->getPrefs())[$CAM::PDF::PREF_COPY];
.Ve
.ie n .IP "$doc\->\fIcanPrint()\fR" 4
.el .IP "\f(CW$doc\fR\->\fIcanPrint()\fR" 4
.IX Item "$doc->canPrint()"
Return a boolean indicating whether the Print permission is enabled
on the \s-1PDF.\s0
.ie n .IP "$doc\->\fIcanModify()\fR" 4
.el .IP "\f(CW$doc\fR\->\fIcanModify()\fR" 4
.IX Item "$doc->canModify()"
Return a boolean indicating whether the Modify permission is enabled
on the \s-1PDF.\s0
.ie n .IP "$doc\->\fIcanCopy()\fR" 4
.el .IP "\f(CW$doc\fR\->\fIcanCopy()\fR" 4
.IX Item "$doc->canCopy()"
Return a boolean indicating whether the Copy permission is enabled
on the \s-1PDF.\s0
.ie n .IP "$doc\->\fIcanAdd()\fR" 4
.el .IP "\f(CW$doc\fR\->\fIcanAdd()\fR" 4
.IX Item "$doc->canAdd()"
Return a boolean indicating whether the Add permission is enabled
on the \s-1PDF.\s0
.ie n .IP "$doc\->\fIgetFormFieldList()\fR" 4
.el .IP "\f(CW$doc\fR\->\fIgetFormFieldList()\fR" 4
.IX Item "$doc->getFormFieldList()"
Return an array of the names of all of the \s-1PDF\s0 form fields. The names
are the full hierarchical names constructed as explained in the \s-1PDF\s0
reference manual. These names are useful for the \fIfillFormFields()\fR
function.
.ie n .IP "$doc\->getFormField($name)" 4
.el .IP "\f(CW$doc\fR\->getFormField($name)" 4
.IX Item "$doc->getFormField($name)"
\&\fIFor \s-1INTERNAL\s0 use\fR
.Sp
Return the object containing the form field definition for the
specified field name. \f(CW$name\fR can be either the full name or the
\&\*(L"short/alternate\*(R" name.
.ie n .IP "$doc\->getFormFieldDict($formfieldobject)" 4
.el .IP "\f(CW$doc\fR\->getFormFieldDict($formfieldobject)" 4
.IX Item "$doc->getFormFieldDict($formfieldobject)"
\&\fIFor \s-1INTERNAL\s0 use\fR
.Sp
Return a hash reference representing the accumulated property list for
a form field, including all of it's inherited properties. This should
be treated as a read-only hash! It \s-1ONLY\s0 retrieves the properties it
knows about.
.SS "Data/Object Manipulation"
.IX Subsection "Data/Object Manipulation"
.ie n .IP "$doc\->setPrefs($ownerpass, $userpass, $print?, $modify?, $copy?, $add?)" 4
.el .IP "\f(CW$doc\fR\->setPrefs($ownerpass, \f(CW$userpass\fR, \f(CW$print\fR?, \f(CW$modify\fR?, \f(CW$copy\fR?, \f(CW$add\fR?)" 4
.IX Item "$doc->setPrefs($ownerpass, $userpass, $print?, $modify?, $copy?, $add?)"
Alter the document's security information. Note that modifying these
parameters must be done respecting the intellectual property of the
original document. See Adobe's statement in the introduction of the
reference manual.
.Sp
\&\fBImportant Note:\fR Most \s-1PDF\s0 readers (Acrobat, Preview.app) only offer
one password field for opening documents. So, if the \f(CW$ownerpass\fR
and \f(CW$userpass\fR are different, those applications cannot read the
documents. (Perhaps this is a bug in \s-1CAM::PDF\s0?)
.Sp
Note: any omitted booleans default to false. So, these two are
equivalent:
.Sp
.Vb 2
\& $doc\->setPrefs(\*(Aqpassword\*(Aq, \*(Aqpassword\*(Aq);
\& $doc\->setPrefs(\*(Aqpassword\*(Aq, \*(Aqpassword\*(Aq, 0, 0, 0, 0);
.Ve
.ie n .IP "$doc\->setName($object, $name)" 4
.el .IP "\f(CW$doc\fR\->setName($object, \f(CW$name\fR)" 4
.IX Item "$doc->setName($object, $name)"
\&\fIFor \s-1INTERNAL\s0 use\fR
.Sp
Change the name of a \s-1PDF\s0 object structure.
.ie n .IP "$doc\->removeName($object)" 4
.el .IP "\f(CW$doc\fR\->removeName($object)" 4
.IX Item "$doc->removeName($object)"
\&\fIFor \s-1INTERNAL\s0 use\fR
.Sp
Delete the name of a \s-1PDF\s0 object structure.
.ie n .IP "$doc\->pageAddName($pagenum, $name, $objectnum)" 4
.el .IP "\f(CW$doc\fR\->pageAddName($pagenum, \f(CW$name\fR, \f(CW$objectnum\fR)" 4
.IX Item "$doc->pageAddName($pagenum, $name, $objectnum)"
\&\fIFor \s-1INTERNAL\s0 use\fR
.Sp
Append a named object to the metadata for a given page.
.ie n .IP "$doc\->setPageContent($pagenum, $content)" 4
.el .IP "\f(CW$doc\fR\->setPageContent($pagenum, \f(CW$content\fR)" 4
.IX Item "$doc->setPageContent($pagenum, $content)"
.PD 0
.ie n .IP "$doc\->setPageContent($pagenum, $tree\->toString)" 4
.el .IP "\f(CW$doc\fR\->setPageContent($pagenum, \f(CW$tree\fR\->toString)" 4
.IX Item "$doc->setPageContent($pagenum, $tree->toString)"
.PD
Replace the content of the specified page with a new version. This
function is often used after the \fIgetPageContent()\fR function and some
manipulation of the returned string from that function.
.Sp
If your content is a parsed tree (i.e. the result of
getPageContentTree) then you should serialize it via toString first.
.ie n .IP "$doc\->appendPageContent($pagenum, $content)" 4
.el .IP "\f(CW$doc\fR\->appendPageContent($pagenum, \f(CW$content\fR)" 4
.IX Item "$doc->appendPageContent($pagenum, $content)"
Add more content to the specified page. Note that this function does
\&\s-1NOT\s0 do any page metadata work for you (like creating font objects for
any newly defined fonts).
.ie n .IP "$doc\->extractPages($pages...)" 4
.el .IP "\f(CW$doc\fR\->extractPages($pages...)" 4
.IX Item "$doc->extractPages($pages...)"
Remove all pages from the \s-1PDF\s0 except the specified ones. Like
\&\fIdeletePages()\fR, the pages can be multiple arguments, comma separated
lists, ranges (open or closed).
.ie n .IP "$doc\->deletePages($pages...)" 4
.el .IP "\f(CW$doc\fR\->deletePages($pages...)" 4
.IX Item "$doc->deletePages($pages...)"
Remove the specified pages from the \s-1PDF. \s0 The pages can be multiple
arguments, comma separated lists, ranges (open or closed).
.ie n .IP "$doc\->deletePage($pagenum)" 4
.el .IP "\f(CW$doc\fR\->deletePage($pagenum)" 4
.IX Item "$doc->deletePage($pagenum)"
Remove the specified page from the \s-1PDF. \s0 If the \s-1PDF\s0 has only one page,
this method will fail.
.ie n .IP "$doc\->decachePages($pagenum, $pagenum, ...)" 4
.el .IP "\f(CW$doc\fR\->decachePages($pagenum, \f(CW$pagenum\fR, ...)" 4
.IX Item "$doc->decachePages($pagenum, $pagenum, ...)"
Clears cached copies of the specified page data structures. This is
useful if an operation has been performed that changes a page.
.ie n .IP "$doc\->addPageResources($pagenum, $resourcehash)" 4
.el .IP "\f(CW$doc\fR\->addPageResources($pagenum, \f(CW$resourcehash\fR)" 4
.IX Item "$doc->addPageResources($pagenum, $resourcehash)"
Add the resources from the given object to the page resource
dictionary. If the page does not have a resource dictionary, create
one. This function avoids duplicating resources where feasible.
.ie n .IP "$doc\->appendPDF($pdf)" 4
.el .IP "\f(CW$doc\fR\->appendPDF($pdf)" 4
.IX Item "$doc->appendPDF($pdf)"
Append pages from another \s-1PDF\s0 document to this one. No optimization
is done \*(-- the pieces are just appended and the internal table of
contents is updated.
.Sp
Note that this can break documents with annotations. See the
\&\fIappendpdf.pl\fR script for a workaround.
.ie n .IP "$doc\->prependPDF($pdf)" 4
.el .IP "\f(CW$doc\fR\->prependPDF($pdf)" 4
.IX Item "$doc->prependPDF($pdf)"
Just like \fIappendPDF()\fR except the new document is inserted on page 1
instead of at the end.
.ie n .IP "$doc\->duplicatePage($pagenum)" 4
.el .IP "\f(CW$doc\fR\->duplicatePage($pagenum)" 4
.IX Item "$doc->duplicatePage($pagenum)"
.PD 0
.ie n .IP "$doc\->duplicatePage($pagenum, $leaveblank)" 4
.el .IP "\f(CW$doc\fR\->duplicatePage($pagenum, \f(CW$leaveblank\fR)" 4
.IX Item "$doc->duplicatePage($pagenum, $leaveblank)"
.PD
Inserts an identical copy of the specified page into the document.
The new page's number will be \f(CW\*(C`$pagenum + 1\*(C'\fR.
.Sp
If \f(CW$leaveblank\fR is true, the new page does not get any content.
Thus, the document is broken until you subsequently call
\&\fIsetPageContent()\fR.
.ie n .IP "$doc\->createStreamObject($content)" 4
.el .IP "\f(CW$doc\fR\->createStreamObject($content)" 4
.IX Item "$doc->createStreamObject($content)"
.PD 0
.ie n .IP "$doc\->createStreamObject($content, $filter ...)" 4
.el .IP "\f(CW$doc\fR\->createStreamObject($content, \f(CW$filter\fR ...)" 4
.IX Item "$doc->createStreamObject($content, $filter ...)"
.PD
\&\fIFor \s-1INTERNAL\s0 use\fR
.Sp
Create a new Stream object. This object is \s-1NOT\s0 added to the document.
Use the \fIappendObject()\fR function to do that after calling this
function.
.ie n .IP "$doc\->\fIuninlineImages()\fR" 4
.el .IP "\f(CW$doc\fR\->\fIuninlineImages()\fR" 4
.IX Item "$doc->uninlineImages()"
.PD 0
.ie n .IP "$doc\->uninlineImages($pagenum)" 4
.el .IP "\f(CW$doc\fR\->uninlineImages($pagenum)" 4
.IX Item "$doc->uninlineImages($pagenum)"
.PD
Search the content of the specified page (or all pages if the
page number is omitted) for embedded images. If there are any, replace
them with indirect objects. This procedure uses heuristics to detect
in-line images, and is subject to confusion in extremely rare cases of text
that uses \f(CW\*(C`BI\*(C'\fR and \f(CW\*(C`ID\*(C'\fR a lot.
.ie n .IP "$doc\->appendObject($doc, $objectnum, $recurse?)" 4
.el .IP "\f(CW$doc\fR\->appendObject($doc, \f(CW$objectnum\fR, \f(CW$recurse\fR?)" 4
.IX Item "$doc->appendObject($doc, $objectnum, $recurse?)"
.PD 0
.ie n .IP "$doc\->appendObject($undef, $object, $recurse?)" 4
.el .IP "\f(CW$doc\fR\->appendObject($undef, \f(CW$object\fR, \f(CW$recurse\fR?)" 4
.IX Item "$doc->appendObject($undef, $object, $recurse?)"
.PD
Duplicate an object from another \s-1PDF\s0 document and add it to this
document, optionally descending into the object and copying any other
objects it references.
.Sp
Like \fIreplaceObject()\fR, the second form allows you to append a
newly-created block to the \s-1PDF.\s0
.ie n .IP "$doc\->replaceObject($objectnum, $doc, $objectnum, $recurse?)" 4
.el .IP "\f(CW$doc\fR\->replaceObject($objectnum, \f(CW$doc\fR, \f(CW$objectnum\fR, \f(CW$recurse\fR?)" 4
.IX Item "$doc->replaceObject($objectnum, $doc, $objectnum, $recurse?)"
.PD 0
.ie n .IP "$doc\->replaceObject($objectnum, $undef, $object)" 4
.el .IP "\f(CW$doc\fR\->replaceObject($objectnum, \f(CW$undef\fR, \f(CW$object\fR)" 4
.IX Item "$doc->replaceObject($objectnum, $undef, $object)"
.PD
Duplicate an object from another \s-1PDF\s0 document and insert it into this
document, replacing an existing object. Optionally descend into the
original object and copy any other objects it references.
.Sp
If the other document is undefined, then the object to copy is taken
to be an anonymous object that is not part of any other document.
This is useful when you've just created that anonymous object.
.ie n .IP "$doc\->deleteObject($objectnum)" 4
.el .IP "\f(CW$doc\fR\->deleteObject($objectnum)" 4
.IX Item "$doc->deleteObject($objectnum)"
Remove an object from the document. This function does \s-1NOT\s0 take care
of dependencies on this object.
.ie n .IP "$doc\->\fIcleanse()\fR" 4
.el .IP "\f(CW$doc\fR\->\fIcleanse()\fR" 4
.IX Item "$doc->cleanse()"
Remove unused objects. \fI\s-1WARNING:\s0\fR this function breaks some \s-1PDF\s0
documents because it removes objects that are strictly part of the
page model hierarchy, but which are required anyway (like some font
definition objects).
.ie n .IP "$doc\->\fIcreateID()\fR" 4
.el .IP "\f(CW$doc\fR\->\fIcreateID()\fR" 4
.IX Item "$doc->createID()"
\&\fIFor \s-1INTERNAL\s0 use\fR
.Sp
Generate a new document \s-1ID. \s0 Contrary the Adobe recommendation, this
is a random number.
.ie n .IP "$doc\->fillFormFields($name => $value, ...)" 4
.el .IP "\f(CW$doc\fR\->fillFormFields($name => \f(CW$value\fR, ...)" 4
.IX Item "$doc->fillFormFields($name => $value, ...)"
.PD 0
.ie n .IP "$doc\->fillFormFields($opts_hash, $name => $value, ...)" 4
.el .IP "\f(CW$doc\fR\->fillFormFields($opts_hash, \f(CW$name\fR => \f(CW$value\fR, ...)" 4
.IX Item "$doc->fillFormFields($opts_hash, $name => $value, ...)"
.PD
Set the default values of \s-1PDF\s0 form fields. The name should be the
full hierarchical name of the field as output by the
\&\fIgetFormFieldList()\fR function. The argument list can be a hash if you
like. A simple way to use this function is something like this:
.Sp
.Vb 3
\& my %fields = (fname => \*(AqJohn\*(Aq, lname => \*(AqSmith\*(Aq, state => \*(AqWI\*(Aq);
\& $field{zip} = 53703;
\& $self\->fillFormFields(%fields);
.Ve
.Sp
If the first argument is a hash reference, it is interpreted as
options for how to render the filled data:
.RS 4
.ie n .IP "background_color =< 'none' | $gray | [$r, $g, $b]" 4
.el .IP "background_color =< 'none' | \f(CW$gray\fR | [$r, \f(CW$g\fR, \f(CW$b\fR]" 4
.IX Item "background_color =< 'none' | $gray | [$r, $g, $b]"
Specify the background color for the text field.
.ie n .IP "max_autoscale_fontsize =< $size" 4
.el .IP "max_autoscale_fontsize =< \f(CW$size\fR" 4
.IX Item "max_autoscale_fontsize =< $size"
.PD 0
.ie n .IP "min_autoscale_fontsize =< $size" 4
.el .IP "min_autoscale_fontsize =< \f(CW$size\fR" 4
.IX Item "min_autoscale_fontsize =< $size"
.PD
If the form field is set to auto-size the text to fit, then you may
use these options to constrain the limits of that
autoscaling. Otherwise, for example, a very long string will become
arbitrarily small to fit in the box.
.RE
.RS 4
.RE
.ie n .IP "$doc\->clearFormFieldTriggers($name, $name, ...)" 4
.el .IP "\f(CW$doc\fR\->clearFormFieldTriggers($name, \f(CW$name\fR, ...)" 4
.IX Item "$doc->clearFormFieldTriggers($name, $name, ...)"
Disable any triggers set on data entry for the specified form field
names. This is useful in the case where, for example, the data entry
Javascript forbids punctuation and you want to prefill with a
hyphenated word. If you don't clear the trigger, the prefill may not
happen.
.ie n .IP "$doc\->\fIclearAnnotations()\fR" 4
.el .IP "\f(CW$doc\fR\->\fIclearAnnotations()\fR" 4
.IX Item "$doc->clearAnnotations()"
Remove all annotations from the document. If form fields are
encountered, their text is added to the appropriate page.
.ie n .IP "$doc\->\fIpreviousRevision()\fR" 4
.el .IP "\f(CW$doc\fR\->\fIpreviousRevision()\fR" 4
.IX Item "$doc->previousRevision()"
If this \s-1PDF\s0 was previously saved in append mode (that is, if
\&\f(CW\*(C`clean()\*(C'\fR was not invoked on it), return a new instance representing
that previous version. Otherwise return void. If this is an
encrypted \s-1PDF,\s0 this method assumes that previous revisions were
encrypted with the same password, which may be an incorrect
assumption.
.ie n .IP "$doc\->\fIallRevisions()\fR" 4
.el .IP "\f(CW$doc\fR\->\fIallRevisions()\fR" 4
.IX Item "$doc->allRevisions()"
Accumulate \s-1CAM::PDF\s0 instances returned by \f(CW\*(C`previousRevision\*(C'\fR until
there are no more previous revisions. Returns a list of instances
from newest to oldest including this instance as the newest.
.SS "Document Writing"
.IX Subsection "Document Writing"
.ie n .IP "$doc\->\fIpreserveOrder()\fR" 4
.el .IP "\f(CW$doc\fR\->\fIpreserveOrder()\fR" 4
.IX Item "$doc->preserveOrder()"
Try to recreate the original document as much as possible. This may
help in recreating documents which use undocumented tricks of saving
font information in adjacent objects.
.ie n .IP "$doc\->\fIisLinearized()\fR" 4
.el .IP "\f(CW$doc\fR\->\fIisLinearized()\fR" 4
.IX Item "$doc->isLinearized()"
Returns a boolean indicating whether this \s-1PDF\s0 is linearized (aka
\&\*(L"optimized\*(R").
.ie n .IP "$doc\->\fIdelinearize()\fR" 4
.el .IP "\f(CW$doc\fR\->\fIdelinearize()\fR" 4
.IX Item "$doc->delinearize()"
\&\fIFor \s-1INTERNAL\s0 use\fR
.Sp
Undo the tweaks used to make the document 'optimized'. This function
is automatically called on every save or output since this library
does not yet support linearized documents.
.ie n .IP "$doc\->\fIclean()\fR" 4
.el .IP "\f(CW$doc\fR\->\fIclean()\fR" 4
.IX Item "$doc->clean()"
Cache all parts of the document and throw away it's old structure.
This is useful for writing PDFs anew, instead of simply appending
changes to the existing documents. This is called by \fIcleansave()\fR and
\&\fIcleanoutput()\fR.
.ie n .IP "$doc\->\fIneedsSave()\fR" 4
.el .IP "\f(CW$doc\fR\->\fIneedsSave()\fR" 4
.IX Item "$doc->needsSave()"
Returns a boolean indicating whether the \fIsave()\fR method needs to be
called. Like \fIsave()\fR, this has nothing to do with whether the document
has been saved to disk, but whether the in-memory representation of
the document has been serialized.
.ie n .IP "$doc\->\fIsave()\fR" 4
.el .IP "\f(CW$doc\fR\->\fIsave()\fR" 4
.IX Item "$doc->save()"
Serialize the document into a single string. All changed document
elements are normalized, and a new index and an updated trailer are
created.
.Sp
This function operates solely in memory. It \s-1DOES NOT\s0 write the
document to a file. See the \fIoutput()\fR function for that.
.ie n .IP "$doc\->\fIcleansave()\fR" 4
.el .IP "\f(CW$doc\fR\->\fIcleansave()\fR" 4
.IX Item "$doc->cleansave()"
Call the \fIclean()\fR function, then call the \fIsave()\fR function.
.ie n .IP "$doc\->output($filename)" 4
.el .IP "\f(CW$doc\fR\->output($filename)" 4
.IX Item "$doc->output($filename)"
.PD 0
.ie n .IP "$doc\->\fIoutput()\fR" 4
.el .IP "\f(CW$doc\fR\->\fIoutput()\fR" 4
.IX Item "$doc->output()"
.PD
Save the document to a file. The \fIsave()\fR function is called first to
serialize the data structure. If no filename is specified, or if the
filename is '\-', the document is written to standard output.
.Sp
Note: it is the responsibility of the application to ensure that the
\&\s-1PDF\s0 document has either the Modify or Add permission. You can do this
like the following:
.Sp
.Vb 5
\& if ($self\->canModify()) {
\& $self\->output($outfile);
\& } else {
\& die "The PDF file denies permission to make modifications\en";
\& }
.Ve
.ie n .IP "$doc\->cleanoutput($file)" 4
.el .IP "\f(CW$doc\fR\->cleanoutput($file)" 4
.IX Item "$doc->cleanoutput($file)"
.PD 0
.ie n .IP "$doc\->\fIcleanoutput()\fR" 4
.el .IP "\f(CW$doc\fR\->\fIcleanoutput()\fR" 4
.IX Item "$doc->cleanoutput()"
.PD
Call the \fIclean()\fR function, then call the \fIoutput()\fR function to write a
fresh copy of the document to a file.
.ie n .IP "$doc\->writeObject($objnum)" 4
.el .IP "\f(CW$doc\fR\->writeObject($objnum)" 4
.IX Item "$doc->writeObject($objnum)"
Return the serialization of the specified object.
.ie n .IP "$doc\->writeString($string)" 4
.el .IP "\f(CW$doc\fR\->writeString($string)" 4
.IX Item "$doc->writeString($string)"
Return the serialization of the specified string. Works on normal or
hex strings. If encryption is desired, the string should be encrypted
before being passed here.
.ie n .IP "$doc\->writeAny($node)" 4
.el .IP "\f(CW$doc\fR\->writeAny($node)" 4
.IX Item "$doc->writeAny($node)"
Returns the serialization of the specified node. This handles all
Node types, including object Nodes.
.SS "Document Traversing"
.IX Subsection "Document Traversing"
.ie n .IP "$doc\->traverse($dereference, $node, $callbackfunc, $callbackdata)" 4
.el .IP "\f(CW$doc\fR\->traverse($dereference, \f(CW$node\fR, \f(CW$callbackfunc\fR, \f(CW$callbackdata\fR)" 4
.IX Item "$doc->traverse($dereference, $node, $callbackfunc, $callbackdata)"
Recursive traversal of a \s-1PDF\s0 data structure.
.Sp
In many cases, it's useful to apply one action to every node in an
object tree. The routines below all use this \fItraverse()\fR function.
One of the most important parameters is the first: the \f(CW$dereference\fR
boolean. If true, the traversal follows reference Nodes. If false,
it does not descend into reference Nodes.
.Sp
Optionally, you can pass in a hashref as a final argument to reduce
redundant traversing across multiple calls. Just pass in an empty
hashref the first time and pass in the same hashref each time. See
\&\f(CW\*(C`changeRefKeys()\*(C'\fR for an example.
.ie n .IP "$doc\->decodeObject($objectnum)" 4
.el .IP "\f(CW$doc\fR\->decodeObject($objectnum)" 4
.IX Item "$doc->decodeObject($objectnum)"
\&\fIFor \s-1INTERNAL\s0 use\fR
.Sp
Remove any filters (like compression, etc) from a data stream
indicated by the object number.
.ie n .IP "$doc\->decodeAll($object)" 4
.el .IP "\f(CW$doc\fR\->decodeAll($object)" 4
.IX Item "$doc->decodeAll($object)"
\&\fIFor \s-1INTERNAL\s0 use\fR
.Sp
Remove any filters from any data stream in this object or any object
referenced by it.
.ie n .IP "$doc\->decodeOne($object)" 4
.el .IP "\f(CW$doc\fR\->decodeOne($object)" 4
.IX Item "$doc->decodeOne($object)"
.PD 0
.ie n .IP "$doc\->decodeOne($object, $save?)" 4
.el .IP "\f(CW$doc\fR\->decodeOne($object, \f(CW$save\fR?)" 4
.IX Item "$doc->decodeOne($object, $save?)"
.PD
\&\fIFor \s-1INTERNAL\s0 use\fR
.Sp
Remove any filters from an object. The boolean flag \f(CW$save\fR (defaults to
false) indicates whether this removal should be permanent or just
this once. If true, the function returns success or failure. If
false, the function returns the defiltered content.
.ie n .IP "$doc\->fixDecode($streamdata, $filter, $params)" 4
.el .IP "\f(CW$doc\fR\->fixDecode($streamdata, \f(CW$filter\fR, \f(CW$params\fR)" 4
.IX Item "$doc->fixDecode($streamdata, $filter, $params)"
This is a utility method to do any tweaking after removing the filter
from a data stream.
.ie n .IP "$doc\->encodeObject($objectnum, $filter)" 4
.el .IP "\f(CW$doc\fR\->encodeObject($objectnum, \f(CW$filter\fR)" 4
.IX Item "$doc->encodeObject($objectnum, $filter)"
Apply the specified filter to the object.
.ie n .IP "$doc\->encodeOne($object, $filter)" 4
.el .IP "\f(CW$doc\fR\->encodeOne($object, \f(CW$filter\fR)" 4
.IX Item "$doc->encodeOne($object, $filter)"
Apply the specified filter to the object.
.ie n .IP "$doc\->setObjNum($object, $objectnum, $gennum)" 4
.el .IP "\f(CW$doc\fR\->setObjNum($object, \f(CW$objectnum\fR, \f(CW$gennum\fR)" 4
.IX Item "$doc->setObjNum($object, $objectnum, $gennum)"
Descend into an object and change all of the \s-1INTERNAL\s0 object number
flags to a new number. This is just for consistency of internal
accounting.
.ie n .IP "$doc\->getRefList($object)" 4
.el .IP "\f(CW$doc\fR\->getRefList($object)" 4
.IX Item "$doc->getRefList($object)"
\&\fIFor \s-1INTERNAL\s0 use\fR
.Sp
Return an array all of objects referred to in this object.
.ie n .IP "$doc\->changeRefKeys($object, $hashref)" 4
.el .IP "\f(CW$doc\fR\->changeRefKeys($object, \f(CW$hashref\fR)" 4
.IX Item "$doc->changeRefKeys($object, $hashref)"
\&\fIFor \s-1INTERNAL\s0 use\fR
.Sp
Renumber all references in an object.
.ie n .IP "$doc\->abbrevInlineImage($object)" 4
.el .IP "\f(CW$doc\fR\->abbrevInlineImage($object)" 4
.IX Item "$doc->abbrevInlineImage($object)"
Contract all image keywords to inline abbreviations.
.ie n .IP "$doc\->unabbrevInlineImage($object)" 4
.el .IP "\f(CW$doc\fR\->unabbrevInlineImage($object)" 4
.IX Item "$doc->unabbrevInlineImage($object)"
Expand all inline image abbreviations.
.ie n .IP "$doc\->changeString($object, $hashref)" 4
.el .IP "\f(CW$doc\fR\->changeString($object, \f(CW$hashref\fR)" 4
.IX Item "$doc->changeString($object, $hashref)"
Alter all instances of a given string. The hashref is a dictionary of
from-string and to-string. If the from-string looks like \f(CW\*(C`regex(...)\*(C'\fR
then it is interpreted as a Perl regular expression and is eval'ed.
Otherwise the search-and-replace is literal.
.SS "Utility functions"
.IX Subsection "Utility functions"
.ie n .IP "$doc\->rangeToArray($min, $max, $list...)" 4
.el .IP "\f(CW$doc\fR\->rangeToArray($min, \f(CW$max\fR, \f(CW$list\fR...)" 4
.IX Item "$doc->rangeToArray($min, $max, $list...)"
Converts string lists of numbers to an array. For example,
.Sp
.Vb 1
\& CAM::PDF\->rangeToArray(1, 15, \*(Aq1,3\-5,12,9\*(Aq, \*(Aq14\-\*(Aq, \*(Aq8 \- 6, \-2\*(Aq);
.Ve
.Sp
becomes
.Sp
.Vb 1
\& (1,3,4,5,12,9,14,15,8,7,6,1,2)
.Ve
.ie n .IP "$doc\->trimstr($string)" 4
.el .IP "\f(CW$doc\fR\->trimstr($string)" 4
.IX Item "$doc->trimstr($string)"
Used solely for debugging. Trims a string to a max of 40 characters,
handling nulls and non-Unix line endings.
.ie n .IP "$doc\->copyObject($node)" 4
.el .IP "\f(CW$doc\fR\->copyObject($node)" 4
.IX Item "$doc->copyObject($node)"
Clones a node via Data::Dumper and \fIeval()\fR.
.ie n .IP "$doc\->\fIcacheObjects()\fR" 4
.el .IP "\f(CW$doc\fR\->\fIcacheObjects()\fR" 4
.IX Item "$doc->cacheObjects()"
Parses all object Nodes and stores them in the cache. This is useful
for cases where you intend to do some global manipulation and want all
of the data conveniently in \s-1RAM.\s0
.ie n .IP "$doc\->asciify($string)" 4
.el .IP "\f(CW$doc\fR\->asciify($string)" 4
.IX Item "$doc->asciify($string)"
Helper class/instance method to massage a string, cleaning up some
non-ASCII problems. This is a very incomplete list. Specifically:
.RS 4
.IP "f\-i ligatures" 4
.IX Item "f-i ligatures"
.PD 0
.IP "(R) symbol" 4
.IX Item "(R) symbol"
.RE
.RS 4
.RE
.PD
.SH "COMPATIBILITY"
.IX Header "COMPATIBILITY"
This library was primarily developed against the 3rd edition of the
reference (\s-1PDF\s0 v1.4) with several important updates from 4th edition
(\s-1PDF\s0 v1.5). This library focuses most deeply on \s-1PDF\s0 v1.2 features.
Nonetheless, it should be forward and backward compatible in the
majority of cases.
.SH "PERFORMANCE"
.IX Header "PERFORMANCE"
This module is written with good speed and flexibility in mind, often
at the expense of memory consumption. Entire \s-1PDF\s0 documents are
typically slurped into \s-1RAM. \s0 As an example, simply calling
\&\f(CW\*(C`new(\*(AqPDFReference15_v15.pdf\*(Aq)\*(C'\fR (the 13.5 \s-1MB\s0 Adobe \s-1PDF\s0 Reference V1.5
document) pushes Perl to consume 89 \s-1MB\s0 of \s-1RAM\s0 on my development
machine.
.SH "SEE ALSO"
.IX Header "SEE ALSO"
There are several other \s-1PDF\s0 modules on \s-1CPAN. \s0 Below is a brief
description of a few of them. If these comments are out of date,
please inform me.
.IP "\s-1PDF::API2\s0" 4
.IX Item "PDF::API2"
As of v0.46.003, \s-1LGPL\s0 license.
.Sp
This is the leading \s-1PDF\s0 library, in my opinion.
.Sp
Excellent text and font support. This is the highest level library of
the bunch, and is the most complete implementation of the Adobe \s-1PDF\s0
spec. The author is amazingly responsive and patient.
.IP "Text::PDF" 4
.IX Item "Text::PDF"
As of v0.25, Artistic license.
.Sp
Excellent compression support (\s-1CAM::PDF\s0 cribs off this Text::PDF
feature). This has not been developed since 2003.
.IP "PDF::Reuse" 4
.IX Item "PDF::Reuse"
As of v0.32, Artistic/GPL license, like Perl itself.
.Sp
This library is not object oriented, so it can only process one \s-1PDF\s0 at
a time, while storing all data in global variables. I'm not fond of
it, but it's quite popular, so don't take my word for it!
.PP
\&\s-1CAM::PDF\s0 is the only one of these that has regression tests.
Currently, \s-1CAM::PDF\s0 has test coverage of about 50%, as reported by
\&\f(CW\*(C`Build testcover\*(C'\fR.
.PP
Additionally, PDFLib is a commercial package not on \s-1CPAN
\&\s0(www.pdflib.com). It is a C\-based library with a Perl interface.
It is designed for \s-1PDF\s0 creation, not for reuse.
.SH "INTERNALS"
.IX Header "INTERNALS"
The data structure used to represent the \s-1PDF\s0 document is composed
primarily of a hierarchy of Node objects. Every node in the document
tree has this structure:
.PP
.Vb 4
\& type =>
\& value =>
\& objnum =>