PDF-Builder
view release on metacpan or search on metacpan
lib/PDF/Builder/Page.pm view on Meta::CPAN
=back
If $prepend is I<true>, or the option 'prepend' is given with a I<true> value,
the content will be prepended to the page description (at the beginning of
the page's content stream).
Otherwise, it will be appended.
The default is I<false>.
=over
=item gfx('compress' => boolean_value)
=back
You may specify a compression flag saying whether the drawing instructions
are to be compressed. If not given, the default is for the overall PDF
compression setting to be used (I<on> by default).
You may have more than one I<gfx> object. They and I<text> objects will be
output as objects and streams I<in the order B<that the objects are>
defined>, with all actions pertaining
to this I<gfx> object appearing in one stream. However, note that graphics
and text objects are not fully independent of each other: the exit state
(linewidth, strokecolor, etc.) of one object is the entry state of the next
object in line to be output, and so on.
If you intermix multiple I<gfx> and I<text> objects on
a page, the results may be confusing. Say you have $gfx1, $text1, $gfx2, and
$text2 on your page (I<created in that order>). PDF::Builder will output all the
$gfx1->I<action> calls in one stream, then all the $text1->I<action> calls in
the next stream, and likewise for $gfx2 usage and finally $text2.
Then it's PDF's turn to confuse you. PDF will process the entire $gfx1 object
stream, accumulating the graphics state to the end of the stream, and using
that as the entry state into $text1. In a similar manner, $gfx2 and $text2 are
read, processed, and rendered. Thus, a change in, say, the dash pattern in the
middle of $gfx1, I<after> you have output some $gfx2, $text1, and $text2
material, may suddenly show up at the beginning of $text1 (and continue through
$gfx2 and $text2)!
It is possible to use multiple graphics objects, to avoid having to change
settings constantly, but you may want to consider resetting all your settings
at the first call to each object, so that you are starting from a known base.
This may most easily be done by using $I<type>->restore() and ->save() just
after creating $I<type>:
$text1 = $page->text();
$text1->save();
$grfx1 = $page->gfx();
$grfx1->restore();
$grfx1->save();
$text2 = $page->text();
$text2->restore();
$text2->save();
$grfx2 = $page->gfx();
$grfx1->restore();
I<Generally,> you will want to define the graphics object first, and then the
text object after that. This defines the order in which the streams will be
rendered (graphics first), which is usually desirable if you're setting a
background color, or have other graphics with which you want to overlay text
over. Sometimes, though, you may wish to overlay text with graphics, in which
case you might either define the objects text and then graphics, or define a
second graphics stream to lay over the text. Most of the time it really doesn't
matter which comes first (as text and graphics don't interact or overlay), but
in any case, be aware of states carried over from the end of one stream
into the next.
B<Alternate name:> C<graphics>
This has been added for PDF::API2 compatibility.
=back
=cut
sub graphics { return gfx(@_); } ## no critic
sub gfx {
my ($self, @params) = @_;
my ($prepend, $compress);
$prepend = $compress = 0; # default for both is False
if (scalar @params == 0) {
# gfx() call. no change
} elsif (scalar @params == 1) {
# one scalar value, $prepend
$prepend = $params[0];
} elsif ((scalar @params)%2) {
# odd number of values, can't be a hash list
carp "Invalid parameters passed to gfx or graphics call!";
} else {
# hash list with at least one element
my %hash = @params;
# copy dashed hash names to preferred undashed names
if (defined $hash{'-prepend'} && !defined $hash{'prepend'}) { $hash{'prepend'} = delete($hash{'-prepend'}); }
if (defined $hash{'-compress'} && !defined $hash{'compress'}) { $hash{'compress'} = delete($hash{'-compress'}); }
if (defined $hash{'prepend'}) { $prepend = $hash{'prepend'}; }
if (defined $hash{'compress'}) { $compress = $hash{'compress'}; }
}
if ($prepend) { $prepend = 1; }
if ($self->{' api'}->{'forcecompress'} eq 'flate' ||
$self->{' api'}->{'forcecompress'} =~ m/^[1-9]\d*$/) { $compress = 1; }
my $gfx = PDF::Builder::Content->new();
$gfx->compressFlate() if $compress;
$self->content($gfx, $prepend);
return $gfx;
}
=head3 text
$text = $page->text(%opts)
$text = $page->text($prepend)
$text = $page->text()
=over
Returns a text content object, for writing text.
See L<PDF::Builder::Content> for details.
You may specify the "prepend" flag in the old or new way. The old way is to
give a single boolean value (0 false, non-zero true). The new way is to give
a hash element named 'prepend', with the same values.
=over
=item text(boolean_value $prepend)
=item text('prepend' => boolean_value)
=back
If $prepend is I<true>, or the option 'prepend' is given with a I<true> value,
the content will be prepended to the page description (at the beginning of
the page's content stream).
Otherwise, it will be appended.
The default is I<false>.
=over
=item text('compress' => boolean_value)
=back
You may specify a compression flag saying whether the text content is
to be compressed. If not given, the default is for the overall PDF
compression setting to be used (I<on> by default).
Please see the discussion above in C<gfx()> regarding multiple graphics and
text objects on one page, how they are grouped into PDF objects and streams,
and the rendering consequences of running through one entire object (stream)
at a time, before moving on to the next. Even if you have only one graphics
and one text stream, the order in which they are defined has consequences for
how text overlays graphics or vice-versa.
The I<text> object has many settings and attributes of its own, but shares many
with graphics (I<gfx>), such as strokecolor, fillcolor, linewidth, linedash,
and the like. Thus there is some overlap in attributes, and graphics and text
calls can affect each other.
=back
=cut
sub text {
my ($self, @params) = @_;
my ($prepend, $compress);
$prepend = $compress = 0; # default for both is False
if (scalar @params == 0) {
# text() call. no change
} elsif (scalar @params == 1) {
# one scalar value, $prepend
$prepend = $params[0];
} elsif ((scalar @params)%2) {
# odd number of values, can't be a hash list
carp "Invalid parameters passed to text() call!";
} else {
# hash list with at least one element
my %hash = @params;
# copy dashed hash names to preferred undashed names
if (defined $hash{'-prepend'} && !defined $hash{'prepend'}) { $hash{'prepend'} = delete($hash{'-prepend'}); }
if (defined $hash{'-compress'} && !defined $hash{'compress'}) { $hash{'compress'} = delete($hash{'-compress'}); }
if (defined $hash{'prepend'}) { $prepend = $hash{'prepend'}; }
if (defined $hash{'compress'}) { $compress = $hash{'compress'}; }
}
if ($prepend) { $prepend = 1; }
if ($self->{' api'}->{'forcecompress'} eq 'flate' ||
$self->{' api'}->{'forcecompress'} =~ m/^[1-9]\d*$/) { $compress = 1; }
my $text = PDF::Builder::Content::Text->new();
$text->compressFlate() if $compress;
$self->content($text, $prepend);
return $text;
}
=head3 rotate, rotation
$page->rotate($deg)
=over
Rotates the page by the given degrees, which must be a multiple of 90.
An angle that is not a multiple of 90 will be rounded to the nearest 90
degrees, with a message.
Note that the rotation angle is I<clockwise> for a positive amount!
E.g., a rotation of +90 (or -270) will have the bottom edge of the paper at
the left of the screen.
After rotating the page 180 degrees, C<[0, 0]> (originally lower left corner)
will be be in the top right corner of the page, rather than the bottom left.
X will increase to the right, and Y will increase downward.
( run in 2.434 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )