|
|
| |
PDF::Builder::Content(3) |
User Contributed Perl Documentation |
PDF::Builder::Content(3) |
PDF::Builder::Content - Methods for adding graphics and text to a PDF
# Start with a PDF page (new or opened)
my $pdf = PDF::Builder->new();
my $page = $pdf->page();
# Add new content object(s)
my $content = $page->gfx();
# and/or (as separate object name)
my $content = $page->text();
# Then call the methods below to add graphics and text to the page.
# Note that negative coordinates can have unpredictable effects, so
# keep your coordinates non-negative!
These methods add content to streams output for text or
graphics objects. Unless otherwise restricted by a check that we are in or
out of text mode, many methods listed here apply equally to text and
graphics streams. It is possible that there are some which have no
effect in one stream type or the other, but are currently lacking a check to
prevent them from being inserted into an inapplicable stream.
All public methods listed, except as otherwise noted, return
$self.
The methods in this section change the coordinate system for the current content
object relative to the rest of the document. Note: the changes are
relative to the original page coordinates (and thus, absolute), not to
the previous position! Thus, "translate(10, 10);
translate(10, 10);" ends up only moving the
origin to "[10, 10]", rather than to
"[20, 20]". There is one call,
"transform_rel()", which makes your changes
relative to the previous position.
If you call more than one of these methods, the PDF specification
recommends calling them in the following order: translate, rotate, scale,
skew. Each change builds on the last, and you can get unexpected results
when calling them in a different order.
CAUTION: a text object ($content) behaves a bit
differently. Individual translate, rotate, scale, and skew calls cancel
out any previous settings. If you want to combine multiple
transformations for text, use the
"transform" call.
- $content->translate($dx,$dy)
- Moves the origin along the x and y axes by $dx and
$dy respectively.
- $content->rotate($degrees)
- Rotates the coordinate system counter-clockwise (anti-clockwise) around
the current origin. Use a negative argument to rotate clockwise. Note that
360 degrees will be treated as 0 degrees.
Note: Unless you have already moved (translated) the
origin, it is, and will remain, at the lower left corner of the visible
sheet. It will not automatically shift to another corner. For
example, a rotation of +90 degrees (counter-clockwise) will leave the
entire visible sheet in negative Y territory (0 at the left edge,
-original_width at the right edge), while X remains in positive
territory (0 at bottom, +original_height at the top edge).
This "rotate()" call permits
any angle. Do not confuse it with the page rotation
"rotate" call, which only permits
increments of 90 degrees (with opposite sign!), but does shift
the origin to another corner of the sheet.
- $content->scale($sx,$sy)
- Scales (stretches) the coordinate systems along the x and y axes. Separate
multipliers are provided for x and y.
- $content->skew($skx,$sky)
- Skews the coordinate system by $skx degrees
(counter-clockwise/anti-clockwise) from the x axis and
$sky degrees (clockwise) from the y axis. Note
that 360 degrees will be treated the same as 0 degrees.
- $content->transform(%opts)
- Use one or more of the given %opts:
$content->transform(
-translate => [$dx,$dy],
-rotate => $degrees,
-scale => [$sx,$sy],
-skew => [$skx,$sky],
-matrix => [$a, $b, $c, $d, $e, $f],
-point => [$x,$y]
)
A six element list may be given
("-matrix") for a further
transformation matrix:
$a = cos(rot) * scale factor for X
$b = sin(rot) * tan(skew for X)
$c = -sin(rot) * tan(skew for Y)
$d = cos(rot) * scale factor for Y
$e = translation for X
$f = translation for Y
Performs multiple coordinate transformations at once, in the
order recommended by the PDF specification (translate, rotate, scale,
skew). This is equivalent to making each transformation separately,
in the indicated order. A matrix of 6 values may also be
given ("-matrix"). The transformation
matrix is updated. A "-point" may be
given (a point to be multiplied [transformed] by the completed
matrix).
- $content->transform_rel(%opts)
- Makes transformations similarly to
"transform", except that it adds
to the previously set values, rather than replacing them (except
for scale, which multiplies the new values with the old).
Unlike "transform",
"-matrix" and
"-point" are not supported.
- $content->matrix($a, $b, $c, $d, $e, $f)
- (Advanced) Sets the current transformation matrix manually. Unless
you have a particular need to enter transformations manually, you should
use the "transform" method instead.
$a = cos(rot) * scale factor for X
$b = sin(rot) * tan(skew for X)
$c = -sin(rot) * tan(skew for Y)
$d = cos(rot) * scale factor for Y
$e = translation for X
$f = translation for Y
In text mode, the text matrix is returned. In graphics
mode, $self is returned.
The following calls also affect the text state.
- $content->linewidth($width)
- Sets the width of the stroke. This is the line drawn in graphics mode, or
the outline of a character in text mode (with appropriate
"render" mode). If no
$width is given, the current setting is
returned. If the width is being set, $self
is returned so that calls may be chained.
- $content->linecap($style)
- Sets the style to be used at the end of a stroke. This applies to lines
which come to a free-floating end, not to "joins"
("corners") in polylines (see
"linejoin").
- 0 = Butt Cap
- The stroke ends at the end of the path, with no projection.
- 1 = Round Cap
- A semicircular arc is drawn around the end of the path with a diameter
equal to the line width, and is filled in.
- 2 = Projecting Square Cap
- The stroke continues past the end of the path for half the line
width.
If no $style is given, the current setting
is returned. If the style is being set, $self
is returned so that calls may be chained.
- $content->linejoin($style)
- Sets the style of join to be used at corners of a path (within a
multisegment polyline).
- 0 = Miter Join
- The outer edges of the strokes extend until they meet, up to the limit
specified by miterlimit. If the limit would be surpassed, a
bevel join is used instead. For a given linewidth, the more acute
the angle is (closer to 0 degrees), the higher the ratio of miter length
to linewidth will be, and that's what miterlimit controls.
- 1 = Round Join
- A filled circle with a diameter equal to the linewidth is drawn
around the corner point, producing a rounded corner. The arc will meet up
with the sides of the line in a smooth tangent.
- 2 = Bevel Join
- A filled triangle is drawn to fill in the notch between the two
strokes.
If no $style is given, the current setting
is returned. If the style is being set, $self
is returned so that calls may be chained.
- $content->miterlimit($ratio)
- Sets the miter limit when the line join style is a miter join.
The ratio is the maximum length of the miter (inner to outer
corner) divided by the line width. Any miter above this ratio will be
converted to a bevel join. The practical effect is that lines
meeting at shallow angles are chopped off instead of producing long
pointed corners.
The default miter limit is 10.0 (approximately 11.5 degree
cutoff angle). The smaller the limit, the larger the cutoff angle.
If no $ratio is given, the current
setting is returned. If the ratio is being set,
$self is returned so that calls may be
chained.
- $content->linedash()
- $content->linedash($length)
- $content->linedash($dash_length, $gap_length, ...)
- $content->linedash(-pattern => [$dash_length, $gap_length, ...],
-shift => $offset)
- Sets the line dash pattern.
If called without any arguments, a solid line will be
drawn.
If called with one argument, the dashes and gaps (strokes and
spaces) will have equal lengths.
If called with two or more arguments, the arguments represent
alternating dash and gap lengths.
If called with a hash of arguments, the -pattern array
may have one or more elements, specifying the dash and gap lengths. A
dash phase may be set (-shift), which is a positive
integer specifying the distance into the pattern at which to start
the dashed line. Note that if you wish to give a shift amount,
using "-shift", you need to use
"-pattern" instead of one or two
elements.
If an odd number of dash array elements are given, the
list is repeated by the reader software to form an even number of
elements (pairs).
If a single argument of -1 is given, the current
setting is returned. This is an array consisting of two elements:
an anonymous array containing the dash pattern (default: empty), and the
shift (offset) amount (default: 0). If the dash pattern is being
set, $self is returned so that
calls may be chained.
- $content->flatness($tolerance)
- (Advanced) Sets the maximum variation in output pixels when drawing
curves. The defined range of $tolerance is 0 to
100, with 0 meaning use the device default flatness.
According to the PDF specification, you should not try to force visible
line segments (the curve's approximation); results will be unpredictable.
Usually, results for different flatness settings will be indistinguishable
to the eye.
The $tolerance value is silently
clamped to be between 0 and 100.
If no $tolerance is given, the current
setting is returned. If the tolerance is being set,
$self is returned so that calls may be
chained.
- $content->egstate($object)
- (Advanced) Adds an Extended Graphic State object containing
additional state parameters.
- $content->move($x,$y)
- Starts a new path at the specified coordinates. Note that multiple x,y
pairs can be given, although this isn't that useful (only the last
pair would have an effect).
- $content->close()
- Closes and ends the current path by extending a line from the current
position to the starting position.
- $content->endpath()
- Ends the current path without explicitly enclosing it. That is, unlike
"close", there is no line segment
drawn back to the starting position.
Straight line constructs
Note: None of these will actually be visible until
you call "stroke" or
"fill". They are merely setting up the
path to draw.
- $content->line($x,$y)
- $content->line($x,$y, $x2,$y2,...)
- Extends the path in a line from the current coordinates to the
specified coordinates, and updates the current position to be the new
coordinates.
Multiple additional
"[$x,$y]" pairs are permitted, to draw
joined multiple line segments. Note that this is not equivalent
to a polyline (see "poly"), because
the first "[$x,$y]" pair in a polyline
is a move operation. Also, the
"linecap" setting will be used rather
than the "linejoin" setting for
treating the ends of segments.
- $content->hline($x)
- $content->vline($y)
- Shortcuts for drawing horizontal and vertical lines from the current
position. They are like "line()", but to
the new x and current y ("hline"), or to
the the current x and new y
("vline").
- $content->poly($x1,$y1, ..., $xn,$yn)
- This is a shortcut for creating a polyline path. It moves to
"[$x1,$y1]", and then extends the path
in line segments along the specified coordinates. The current position is
changed to the last "[$x,$y]" pair
given.
The difference between a polyline and a
"line" with multiple
"[$x,$y]" pairs is that the first pair
in a polyline are a move, while in a line they are a draw.
Also, "linejoin" instead of
"linecap" is used to control the
appearance of the ends of line segments.
- $content->rect($x,$y, $w,$h)
- $content->rect($x1,$y1, $w1,$h1, ..., $xn,$yn, $wn,$hn)
- This creates paths for one or more rectangles, with their lower left
points at "[$x,$y]" and specified widths
(+x direction) and heights (+y direction). Negative widths and heights are
permitted, which draw to the left (-x) and below (-y) the given corner
point, respectively. The current position is changed to the
"[$x,$y]" of the last rectangle given.
Note that this is the starting point of the rectangle, not the end
point.
- $content->rectxy($x1,$y1, $x2,$y2)
- This creates a rectangular path, with
"[$x1,$y1]" and
"[$x2,$y2]" specifying opposite
corners. They can be Lower Left and Upper Right, or Upper Left and
Lower Right, in either order, so long as they are diagonally opposite each
other. The current position is changed to the
"[$x1,$y1]" (first) pair.
Curved line constructs
Note: None of these will actually be visible until
you call "stroke" or
"fill". They are merely setting up the
path to draw.
- $content->circle($xc,$yc, $radius)
- This creates a circular path centered on
"[$xc,$yc]" with the specified radius.
It does not change the current position.
- $content->ellipse($xc,$yc, $rx,$ry)
- This creates a closed elliptical path centered on
"[$xc,$yc]", with axis radii
(semidiameters) specified by $rx (x axis) and
$ry (y axis), respectively. It does not change the
current position.
- $content->arc($xc,$yc, $rx,$ry, $alpha,$beta, $move, $dir)
- $content->arc($xc,$yc, $rx,$ry, $alpha,$beta, $move)
- This extends the path along an arc of an ellipse centered at
"[$xc,$yc]". The semidiameters of the
elliptical curve are $rx (x axis) and
$ry (y axis), respectively, and the arc sweeps
from $alpha degrees to
$beta degrees. The current position is then set to
the endpoint of the arc.
Set $move to a true value if
this arc is the beginning of a new path instead of the continuation of
an existing path. Either way, the current position will be updated to
the end of the arc. Use "$rx == $ry"
for a circular arc.
The optional $dir arc sweep direction
defaults to 0 (false), for a counter-clockwise/anti-clockwise
sweep. Set to 1 (true) for a clockwise sweep.
- $content->pie($xc,$yc, $rx,$ry, $alpha,$beta, $dir)
- $content->pie($xc,$yc, $rx,$ry, $alpha,$beta)
- Creates a pie-shaped path from an ellipse centered on
"[$xc,$yc]". The x-axis and y-axis
semidiameters of the ellipse are $rx and
$ry, respectively, and the arc sweeps from
$alpha degrees to $beta
degrees. It does not change the current position. Depending on the sweep
angles and direction, this can draw either the pie "slice" or
the remaining pie (with slice removed). Use "$rx ==
$ry" for a circular pie. Use a different
"[$xc,$yc]" for the slice, to offset it
from the remaining pie.
The optional $dir arc sweep direction
defaults to 0 (false), for a counter-clockwise/anti-clockwise
sweep. Set to 1 (true) for a clockwise sweep.
This is a shortcut to draw a section of elliptical (or
circular) arc and connect it to the center of the ellipse or circle, to
form a pie shape.
- $content->curve($cx1,$cy1, $cx2,$cy2, $x,$y)
- This extends the path in a curve from the current point to
"[$x,$y]", using the two specified
control points to create a cubic Bezier curve, and updates the
current position to be the new point
("[$x,$y]").
Within a text object, the text's baseline follows the
Bezier curve.
Note that while multiple sets of three
"[x,y]" pairs are permitted, these are
treated as independent cubic Bezier curves. There is no attempt
made to smoothly blend one curve into the next!
- $content->qbspline($cx1,$cy1, $x,$y)
- This extends the path in a curve from the current point to
"[$x,$y]", using the two specified
points to create a quadratic Bezier curve, and updates the current
position to be the new point.
Internally, these splines are one or more cubic Bezier curves
(see "curve") with the two control
points synthesized from the two given points (a control point and the
end point of a quadratic Bezier curve).
Note that while multiple sets of two
"[x,y]" pairs are permitted, these are
treated as independent quadratic Bezier curves. There is no
attempt made to smoothly blend one curve into the next!
Further note that this "spline" does not match the
common definition of a spline being a continuous curve passing
through all the given points! It is a piecewise
non-continuous cubic Bezier curve. Use with care, and do not make
assumptions about splines for you or your readers. You may wish to use
the "bspline" call to have a
continuously smooth spline to pass through all given points.
Pairs of points (control point and end point) are consumed in
a loop. If one point or coordinate is left over at the end, it is
discarded (as usual practice for excess data to a routine). There is no
check for duplicate points or other degeneracies.
- $content->bspline($ptsRef, %opts)
- $content->bspline($ptsRef)
- This extends the path in a curve from the current point to the end of a
list of coordinate pairs in the array referenced by
$ptsRef. Smoothly continuous cubic Bezier splines
are used to create a curve that passes through all the given
points. Multiple control points are synthesized; they are not supplied in
the call. The current position is updated to the last point.
Internally, these splines are one cubic Bezier curve (see
"curve") per pair of input points,
with the two control points synthesized from the tangent through each
point as set by the polyline that would connect each point to its
neighbors. The intent is that the resulting curve should follow
reasonably closely a polyline that would connect the points, and should
avoid any major excursions. See the discussions below for the handling
of the control points at the endpoints (current point and last input
point). The point at the end of the last line or curve drawn becomes the
new current point.
%opts
- -firstseg => 'mode'
- where mode is
- curve
- This is the default behavior. This forces the first segment (from
the current point to the first given point) to be drawn as a cubic Bezier
curve. This means that the direction of the curve coming off the current
point is unconstrained (it will end up being a reflection of the tangent
at the first given point).
- line1
- This forces the first segment (from the current point to the first given
point) to be drawn as a curve, with the tangent at the current point to be
constrained as parallel to the polyline segment.
- line2
- This forces the first segment (from the current point to the first given
point) to be drawn as a line segment. This also sets the tangent through
the first given point as a continuation of the line, as well as
constraining the direction of the line at the current point.
- constraint1
- This forces the first segment (from the current point to the first given
point) to not be drawn, but to be an invisible curve (like
mode=line1) to leave the tangent at the first given point unconstrained. A
move will be made to the first given point, and the current point
is otherwise ignored.
- constraint2
- This forces the first segment (from the current point to the first given
point) to not be drawn, but to be an invisible line (like
mode=line2) to constrain the tangent at the first given point. A
move will be made to the first given point, and the current point
is otherwise ignored.
- -lastseg => 'mode'
- where mode is
- curve
- This is the default behavior. This forces the last segment (to the
last given input point) to be drawn as a cubic Bezier curve. This means
that the direction of the curve goin to the last point is unconstrained
(it will end up being a reflection of the tangent at the next-to-last
given point).
- line1
- This forces the last segment (to the last given input point) to be drawn
as a curve with the the tangent through the last given point parallel to
the polyline segment, thus constraining the direction of the line at the
last point.
- line2
- This forces the last segment (to the last given input point) to be drawn
as a line segment. This also sets the tangent through the next-to-last
given point as a back continuation of the line, as well as constraining
the direction of the line at the last point.
- constraint1
- This forces the last segment (to the last given input point) to not
be drawn, but to be an invisible curve (like mode=line1) to leave the
tangent at the next-to-last given point unconstrained. The last given
input point is ignored, and next-to-last point becomes the new current
point.
- constraint2
- This forces the last segment (to the last given input point) to not
be drawn, but to be an invisible line (like mode=line2) to constrain the
tangent at the next-to-last given point. The last given input point is
ignored, and next-to-last point becomes the new current point.
- -ratio => n
- n is the ratio of the length from a point to a control point to the
length of the polyline segment on that side of the given point. It must be
greater than 0.1, and the default is 0.3333 (1/3).
- -colinear => 'mode'
- This describes how to handle the middle segment when there are four or
more colinear points in the input set. A mode of 'line' specifies
that a line segment will be drawn between each of the interior colinear
points. A mode of 'curve' (this is the default) will draw a Bezier
curve between each of those points.
"-colinear" applies only to
interior runs of colinear points, between curves. It does not apply to
runs at the beginning or end of the point list, which are drawn as line
segments or linear constraints regardless of -firstseg and
-lastseg settings.
- -debug => N
- If N is 0 (the default), only the spline is returned. If it is
greater than 0, a number of additional items will be drawn: (N>0) the
points, (N>1) a green solid polyline connecting them, (N>2) blue
original tangent lines at each interior point, and (N>3) red dashed
lines and hollow points representing the Bezier control points.
Special cases
Adjacent points which are duplicates are consolidated. An extra
coordinate at the end of the input point list (not a full
"[x,y]" pair) will, as usual, be
ignored.
- 0 given points (after duplicate consolidation)
- This leaves only the current point (unchanged), so it is a no-op.
- 1 given point (after duplicate consolidation)
- This leaves the current point and one point, so it is rendered as a line,
regardless of %opt flags.
- 2 given points (after duplicate consolidation)
- This leaves the current point, an intermediate point, and the end point.
If the three points are colinear, two line segments will be drawn.
Otherwise, both segments are curves (through the tangent at the
intermediate point). If either end segment mode is requested to be a line
or constraint, it is treated as a line1 mode request instead.
- N colinear points at beginning or end
- N colinear points at beginning or end of the point set causes
N-1 line segments ("line2" or
"constraint2", regardless of the
settings of "-firstseg",
"-lastseg", and
"-colinear".
- $content->bogen($x1,$y1, $x2,$y2, $radius, $move, $larger,
$reverse)
- $content->bogen($x1,$y1, $x2,$y2, $radius, $move, $larger)
- $content->bogen($x1,$y1, $x2,$y2, $radius, $move)
- $content->bogen($x1,$y1, $x2,$y2, $radius)
- (German for bow, as in a segment (arc) of a circle. This is a
segment of a circle defined by the intersection of two circles of a given
radius, with the two intersection points as inputs. There are four
possible resulting arcs, which can be selected with
$larger and $reverse.)
This extends the path along an arc of a circle of the
specified radius between "[$x1,$y1]"
to "[$x2,$y2]". The current position
is then set to the endpoint of the arc
("[$x2,$y2]").
Set $move to a true value if
this arc is the beginning of a new path instead of the continuation of
an existing path. Note that the default ($move =
false) is not a straight line to P1 and then the
arc, but a blending into the curve from the current point. It will often
not pass through P1!
Set $larger to a true value to
draw the larger ("outer") arc between the two points, instead
of the smaller one. Both arcs are drawn clockwise from P1
to P2. The default value of false draws the smaller
arc.
Set $reverse to a true value to
draw the mirror image of the specified arc (flip it over, so that its
center point is on the other side of the line connecting the two
points). Both arcs are drawn counter-clockwise from P1 to
P2. The default (false) draws clockwise arcs.
The $radius value cannot be smaller
than half the distance from
"[$x1,$y1]" to
"[$x2,$y2]". If it is too small, the
radius will be set to half the distance between the points (resulting in
an arc that is a semicircle). This is a silent error.
- $content->stroke()
- Strokes the current path.
- $content->fill($use_even_odd_fill)
- Fill the current path's enclosed area. It does not stroke
the enclosing path around the area.
If the path intersects with itself, the nonzero winding rule
will be used to determine which part of the path is filled in. This
basically fills in everything inside the path. If you would
prefer to use the even-odd rule, pass a true argument. This
basically will fill alternating closed sub-areas.
See the PDF Specification, section 8.5.3.3, for more details
on filling.
- $content->fillstroke($use_even_odd_fill)
- Fill the enclosed area and then stroke the current path.
- $content->clip($use_even_odd_fill)
- $content->clip()
- Modifies the current clipping path by intersecting it with the current
path. Initially (a fresh page), the clipping path is the entire media.
Each definition of a path, and a
"clip()" call, intersects the new path
with the existing clip path, so the resulting clip path is no larger than
the new path, and may even be empty if the intersection is null.
If any $use_even_odd_fill parameter is
given, use even-odd fill (W*) instead of winding-rule fill
(W). It is common usage to make the
"endpath()" call (n) after the
"clip()" call, to clear the path
(unless you want to reuse that path, such as to fill and/or stroke it to
show the clip path). If you want to clip text glyphs, it gets rather
complicated, as a clip port cannot be created within a text object (that
will have an effect on text). See the object discussion in
"Rendering Order" in PDF::Builder::Docs.
my $grfxC1 = $page->gfx();
my $textC = $page->text();
my $grfxC2 = $page->gfx();
...
$grfxC1->save();
$grfxC1->endpath();
$grfxC1->rect(...);
$grfxC1->clip();
$grfxC1->endpath();
...
$textC-> output text to be clipped
...
$grfxC2->restore();
- $content->fillcolor($color)
- $content->strokecolor($color)
- Sets the fill (enclosed area) or stroke (path) color. The interior of text
characters are filled, and (if ordered by
"render") the outline is stroked.
# Use a named color
# -> RGB color model
# there are many hundreds of named colors defined in
# PDF::Builder::Resource::Colors
$content->fillcolor('blue');
# Use an RGB color (# followed by 3, 6, 9, or 12 hex digits)
# -> RGB color model
# This maps to 0-1.0 values for red, green, and blue
$content->fillcolor('#FF0000'); # red
# Use a CMYK color (% followed by 4, 8, 12, or 16 hex digits)
# -> CMYK color model
# This maps to 0-1.0 values for cyan, magenta, yellow, and black
$content->fillcolor('%FF000000'); # cyan
# Use an HSV color (! followed by 3, 6, 9, or 12 hex digits)
# -> RGB color model
# This maps to 0-360 degrees for the hue, and 0-1.0 values for
# saturation and value
$content->fillcolor('!FF0000');
# Use an HSL color (& followed by 3, 6, 9, or 12 hex digits)
# -> L*a*b color model
# This maps to 0-360 degrees for the hue, and 0-1.0 values for
# saturation and lightness. Note that 360 degrees = 0 degrees (wraps)
$content->fillcolor('&FF0000');
# Use an L*a*b color ($ followed by 3, 6, 9, or 12 hex digits)
# -> L*a*b color model
# This maps to 0-100 for L, -100 to 100 for a and b
$content->fillcolor('$FF0000');
In all cases, if too few digits are given, the given digits
are silently right-padded with 0's (zeros). If an incorrect number of
digits are given, the next lowest number of expected digits are used,
and the remaining digits are silently ignored.
# A single number between 0.0 (black) and 1.0 (white) is an alternate way
# of specifying a gray scale.
$content->fillcolor(0.5);
# Three array elements between 0.0 and 1.0 is an alternate way of specifying
# an RGB color.
$content->fillcolor(0.3, 0.59, 0.11);
# Four array elements between 0.0 and 1.0 is an alternate way of specifying
# a CMYK color.
$content->fillcolor(0.1, 0.9, 0.3, 1.0);
In all cases, if a number is less than 0, it is silently
turned into a 0. If a number is greater than 1, it is silently turned
into a 1. This "clamps" all values to the range 0.0-1.0.
# A single reference is treated as a pattern or shading space.
# Two or more entries with the first element a Perl reference, is treated
# as either an indexed colorspace reference plus color-index(es), or
# as a custom colorspace reference plus parameter(s).
If no value was passed in, the current fill color (or stroke
color) array is returned, otherwise
$self is returned.
- $content->shade($shade, @coord)
- Sets the shading matrix.
- $shade
- A hash reference that includes a
"name()" method for the shade name.
- @coord
- An array of 4 items: X-translation, Y-translation, X-scaled and
translated, Y-scaled and translated.
- $content->image($image_object, $x,$y, $width,$height)
- $content->image($image_object, $x,$y, $scale)
- $content->image($image_object, $x,$y)
- $content->image($image_object)
-
# Example
my $image_object = $pdf->image_jpeg($my_image_file);
$content->image($image_object, 100, 200);
Places an image on the page in the specified location
(specifies the lower left corner of the image). The default location is
"[0,0]".
If coordinate transformations have been made (see
Coordinate Transformations above), the position and scale
will be relative to the updated coordinates. Otherwise,
"[0,0]" will represent the bottom left
corner of the page, and $width and
$height will be measured at 72dpi.
For example, if you have a 600x600 image that you would like
to be shown at 600dpi (i.e., one inch square), set the width and height
to 72. (72 Big Points is one inch)
- $content->formimage($form_object, $x,$y, $scaleX, $scaleY)
- $content->formimage($form_object, $x,$y, $scale)
- $content->formimage($form_object, $x,$y)
- $content->formimage($form_object)
- Places an XObject on the page in the specified location (giving the lower
left corner of the image) and scale (applied to the image's native height
and width). If no scale is given, use 1 for both X and Y. If one scale is
given, use for both X and Y. If two scales given, they are for
(separately) X and Y. In general, you should not greatly distort an image
by using greatly different scaling factors in X and Y, although it is now
possible for when that effect is desirable. The
"$x,$y" default is
"[0,0]".
Note that while this method is named form image,
it is also used for the pseudoimages created by the barcode routines.
Images are naturally dimensionless (1 point square) and need at some
point to be scaled up to the desired point size. Barcodes are naturally
sized in points, and should be scaled at approximately 1.
Therefore, it would greatly overscale barcodes to multiply by image
width and height within
"formimage", and require scaling of
1/width and 1/height in the call. So, we leave scaling alone within
"formimage" and have the user manually
scale images by the image width and height (in pixels) in the
call to "formimage".
Text State Parameters
All of the following parameters that take a size are applied
before any scaling takes place, so you don't need to adjust values to
counteract scaling.
- $spacing = $content->charspace($spacing)
- Sets additional spacing between characters in a line. This is in
points, and is initially zero. It may be positive to give an
expanded effect to words, or it may be negative to give a
condensed effect to words. If $spacing is
given, the current setting is replaced by that value and
$self is returned (to permit chaining). If
$spacing is not given, the current setting is
returned.
CAUTION: be careful about using
"charspace" if you are using a
connected font. This might include Arabic, Devanagari, Latin cursive
handwriting, and so on. You don't want to leave gaps between characters,
or cause overlaps. For such fonts and typefaces, set the
"charspace" spacing to 0.
- $spacing = $content->wordspace($spacing)
- Sets additional spacing between words in a line. This is in
points and is initially zero (i.e., just the width of the space,
without anything extra). It may be negative to close up sentences a bit.
If $spacing is given, the current setting is
replaced by that value and $self is
returned (to permit chaining). If $spacing
is not given, the current setting is returned.
Note that it is a limitation of the PDF specification (as of
version 1.7, section 9.3.3) that only spacing with an ASCII space (x20)
is adjusted. Neither required blanks (xA0) nor any multiple-byte spaces
(including thin and wide spaces) are currently adjusted.
- $scale = $content->hscale($scale)
- Sets the percentage of horizontal text scaling (relative sizing,
not spacing). This is initally 100 (percent, i.e., no scaling). A
scale of greater than 100 will stretch the text, while less than 100 will
compress it. If $scale is given, the current
setting is replaced by that value and $self is
returned (to permit chaining). If $scale is
not given, the current setting is returned.
Note that scaling affects all of the character widths,
interletter spacing, and interword spacing. It is inadvisable to stretch
or compress text by a large amount, as it will quickly make the text
unreadable. If your objective is to justify text, you will usually be
better off using "charspace" and
"wordspace" to expand (or slightly
condense) a line to fill a desired width. Also see the
"text_justify()" calls for this
purpose.
- $leading = $content->leading($leading)
- $leading = $content->leading()
- Sets the text leading, which is the distance between baselines. This is
initially zero (i.e., the lines will be printed on top of each
other). The unit of leading is points. If $leading
is given, the current setting is replaced by that value and
$self is returned (to permit chaining). If
$leading is not given, the current setting is
returned.
Note that "leading" here is
defined as used in electronic typesetting and the PDF specification,
which is the full interline spacing (text baseline to text baseline
distance, in points). In cold metal typesetting, leading was
usually the extra spacing between lines beyond the font height
itself, created by inserting lead (type alloy) shims.
- $leading = $content->lead($leading)
- $leading = $content->lead()
- Deprecated, to be removed after March 2023. Use
"leading()" now.
Note that the "$self-"{'
lead'}> internal variable is no longer available, having been
replaced by "$self-"{'
leading'}>.
- $mode = $content->render($mode)
- Sets the text rendering mode.
- 0 = Fill text
- 1 = Stroke text (outline)
- 2 = Fill, then stroke text
- 3 = Neither fill nor stroke text (invisible)
- 4 = Fill text and add to path for clipping
- 5 = Stroke text and add to path for clipping
- 6 = Fill, then stroke text and add to path for clipping
- 7 = Add text to path for clipping
If $mode is given, the current setting is
replaced by that value and $self is returned
(to permit chaining). If $mode is not given, the
current setting is returned.
- $dist = $content->rise($dist)
- Adjusts the baseline up or down from its current location. This is
initially zero. A $dist greater than 0 moves the
baseline up the page (y increases).
Use this for creating superscripts or subscripts (usually
along with an adjustment to the font size). If
$dist is given, the current setting is replaced
by that value and $self is returned (to
permit chaining). If $dist is not given, the
current setting is returned.
- %state = $content->textstate(charspace => $value, wordspace =>
$value, ...)
- This is a shortcut for setting multiple text state parameters at once. If
any parameters are set, an empty hash is returned. This can
also be used without arguments to retrieve the current text state settings
(a hash of the state is returned).
Note: This does not work with the
"save" and
"restore" commands.
- $content->font($font_object, $size)
- Sets the font and font size.
# Example (12 point Helvetica)
my $pdf = PDF::Builder->new();
my $fontname = $pdf->corefont('Helvetica');
$content->font($fontname, 12);
Positioning Text
- $content->distance($dx,$dy)
- This moves to the start of the previously-written line, plus an offset by
the given amounts, which are both required.
"[0,0]" would overwrite the previous
line, while "[0,36]" would place the new
line 36pt above the old line (higher y). The
$dx moves to the right, if positive.
"distance" is analogous to
graphic's "move", except that it is
relative to the beginning of the previous text write, not to the
coordinate origin. Note that subsequent text writes will be
relative to this new starting (left) point and Y position! E.g., if you
give a non-zero $dx, subsequent lines will be
indented by that amount.
- $content->cr()
- $content->cr($vertical_offset)
- $content->cr(0)
- If passed without an argument, moves (down) to the start of the
next line (distance set by
"leading"). This is similar to
"nl()".
If passed with an argument, the
"leading" distance is ignored and the
next line starts that far up the page (positive value) or
down the page (negative value) from the current line.
"Y" increases upward, so a negative value would normally be
used to get to the next line down.
An argument of 0 would simply return to the start of
the present line, overprinting it with new text. That is, it acts as a
simple carriage return, without a linefeed.
- $content->nl()
- $content->nl($indent)
- $content->nl(0)
- Moves to the start of the next line (see
"leading"). If
$indent is not given, or is 0, there is no
indentation. Otherwise, indent by that amount (outdent if a
negative value). The unit of measure is hundredths of a "unit of text
space", or roughly 88 per em.
- ($tx,$ty) = $content->textpos()
- Returns the current text position on the page (where next write
will happen) as an array.
Note: This does not affect the PDF in any way. It only
tells you where the the next write will occur.
- $width = $content->advancewidth($string, %opts)
- $width = $content->advancewidth($string)
- Options %opts:
- font => $f3_TimesRoman
- Change the font used, overriding $self->{'
font'}. The font must have been previously created (i.e., is not the
name). Example: use Times-Roman.
- fontsize => 12
- Change the font size, overriding $self->{'
fontsize'}. Example: 12 pt font.
- wordspace => 0.8
- Change the additional word spacing, overriding
$self->wordspace(). Example: add 0.8 pt
between words.
- charspace => -2.1
- Change the additional character spacing, overriding
$self->charspace(). Example: subtract
2.1 pt between letters, to condense the text.
- hscale => 125
- Change the horizontal scaling factor, overriding
$self->hscale(). Example: stretch text
to 125% of its natural width.
Returns the width of the $string based
on all currently set text-state attributes. These can optionally be
overridden with %opts. Note that these
values temporarily replace the existing values,
not scaling them up or down. For example, if
the existing charspace is 2, and you give in options a value of 3, the value
used is 3, not 5.
Note: This does not affect the PDF in any way. It only
tells you how much horizontal space a text string will take up.
Rendering Text
Single Lines
- $width = $content->text($text, %opts)
- $width = $content->text($text)
- Adds text to the page (left justified). The width used (in points) is
returned.
Options:
- -indent => $distance
- Indents the text by the number of points (A value less than 0 gives an
outdent).
- -underline => 'none'
- -underline => 'auto'
- -underline => $distance
- -underline => [$distance, $thickness, ...]
- Underlines the text. $distance is the number of
units beneath the baseline, and $thickness is the
width of the line. Multiple underlines can be made by passing several
distances and thicknesses. A value of 'none' means no underlining (is the
default).
Example:
# 3 underlines:
# distance 4, thickness 1, color red
# distance 7, thickness 1.5, color yellow
# distance 11, thickness 2, color (strokecolor default)
-underline=>[4,[1,'red'],7,[1.5,'yellow'],11,2],
- -strikethru => 'none'
- -strikethru => 'auto'
- -strikethru => $distance
- -strikethru => [$distance, $thickness, ...]
- Strikes through the text (like HTML s tag). A value of 'auto'
places the line about 30% of the font size above the baseline, or a
specified $distance (above the baseline) and
$thickness (in points). Multiple strikethroughs
can be made by passing several distances and thicknesses. A value of
'none' means no strikethrough. It is the default.
Example:
# 2 strikethroughs:
# distance 4, thickness 1, color red
# distance 7, thickness 1.5, color yellow
-strikethru=>[4,[1,'red'],7,[1.5,'yellow']],
- $width = $content->textHS($HSarray, $settings, %opts)
- $width = $content->textHS($HSarray, $settings)
- Takes an array of hashes produced by HarfBuzz::Shaper and outputs them to
the PDF output file. HarfBuzz outputs glyph CIDs and positioning
information. It may rearrange and swap characters (glyphs), and the result
may bear no resemblance to the original Unicode point list. You should see
examples/HarfBuzz.pl, which shows a number of examples with Latin and
non-Latin text, as well as vertical writing.
examples/resources/HarfBuzz_example.pdf is available in case you want to
see some examples and don't yet have HarfBuzz::Shaper installed.
- $HSarray
- This is the reference to array of hashes produced by HarfBuzz::Shaper,
normally unchanged after being created (but can be modified). See
"Using Shaper" in PDF::Builder::Docs for some things that can be
done.
- $settings
- This a reference to a hash of various pieces of information that
"textHS()" needs in order to function.
They include:
- script => 'script_name'
- This is the standard 4 letter code (e.g., 'Latn') for the script (alphabet
and writing system) you're using. Currently, only Latn (Western writing
systems) do kerning, and 'Latn' is the default. HarfBuzz::Shaper will
usually be able to figure out from the Unicode points used what the script
is, and you might be able to use the
"set_script()" call to override its
guess. However, PDF::Builder and HarfBuzz::Shaper do not talk to each
other about the script being used.
- features => array_of_features
- This item is required, but may be empty, e.g.,
"$settings->{'features'} = ();". It
can include switches using the standard HarfBuzz naming, and a + or -
switch, such as '-liga' to turn off ligatures. '-liga' and '-kern',
to turn off ligatures and kerning, are the only features supported
currently. Note that this is separate from any switches for
features that you send to HarfBuzz::Shaper (with
"$hb->add_features()", etc.) when you
run it (before "textHS()").
- language => 'language_code'
- This item is optional and currently does not appear to have any
substantial effect with HarfBuzz::Shaper. It is the standard code for the
language to be used, such as 'en' or 'en_US'. You might need to define
this for HarfBuzz::Shaper, in case that system can't surmise the language
rules to be used.
- dir => 'flag'
- Tell "textHS()" whether this text is to
be written in a Left-To-Right manner (L, the default),
Right-To-Left (R), Top-To-Bottom (T), or Bottom-To-Top
(B). From the script used (Unicode points), HarfBuzz::Shaper can
usually figure out what direction to write text in. Also, HarfBuzz::Shaper
does not share its information with PDF::Builder -- you need to separately
specify the direction, unless you want to accept the default LTR
direction. You can use HarfBuzz::Shaper's
"get_direction()" call (in addition to
"get_language()" and
"get_script()") to see what HarfBuzz
thinks is the correct text direction.
"set_direction()" may be used to
override Shaper's guess as to the direction.
By the way, if the direction is RTL, HarfBuzz will reverse the
text and return an array with the last character first (to be written
LTR). Likewise, for BTT, HarfBuzz will reverse the text and return a
string to be written from the top down. Languages which are normally
written horizontally are usually set vertically with direction TTB. If
setting text vertically, ligatures and kerning, as well as character
connectivity for cursive scripts, are automatically turned off, so don't
let the direction default to LTR or RTL in the Shaper call, and then try
to fix it up in "textHS()".
- align => 'flag'
- Given the current output location, align the text at the Beginning
of the line (left for LTR, right for RTL), Centered at the
location, or at the End of the line (right for LTR, left for RTL).
The default is B. Centered is analogous to using
"text_center()", and End is
analogous to using "text_right()".
Similar alignments are done for TTB and BTT.
- dump => flag
- Set to 1, it prints out positioning and glyph CID information (to STDOUT)
for each glyph in the chunk. The default is 0 (no information dump).
- -minKern => amount (default 1)
- If the amount of kerning (font character width differs from glyph
ax value) is larger than this many character grid units, use the
unaltered ax for the width ("textHS()"
will output a kern amount in the TJ operation). Otherwise, ignore kerning
and use ax of the actual character width. The intent is to avoid bloating
the PDF code with unnecessary tiny kerning adjustments in the TJ
operation.
- %opts
- This a hash of options.
- -underline => underlining_instructions
- See "text()" for available
instructions.
- -strikethru => strikethrough_instructions
- See "text()" for available
instructions.
- -strokecolor => line_color
- Color specification (e.g., 'green', '#FF3377') for underline or
strikethrough, if not given in an array with their instructions.
Text is sent separately to HarfBuzz::Shaper in 'chunks'
('segments') of a single script (alphabet), a single direction (LTR, RTL,
TTB, or BTT), a single font file, and a single font size. A chunk may
consist of a large amount of text, but at present,
"textHS()" can only output a single line.
For long lines that need to be split into column-width lines, the best way
may be to take the array of hashes returned by HarfBuzz::Shaper and split it
into smaller chunks at spaces and other whitespace. You may have to query
the font to see what the glyph CIDs are for space and anything else
used.
It is expected that when
"textHS()" is called, that the font and
font size have already been set in PDF::Builder code, as this information is
needed to interpret what HarfBuzz::Shaper is returning, and to write it to
the PDF file. Needless to say, the font should be opened from the same file
as was given to HarfBuzz::Shaper
("ttfont()" only, with .ttf or .otf
files), and the font size must be the same. The appropriate location on the
page must also already have been specified.
NOTE: as HarfBuzz::Shaper is still in its early days, it is
possible that there will be major changes in its API. We hope that all
changes will be upwardly compatible, but do not control this package and
cannot guarantee that there will not be any incompatible changes that in
turn require changes to PDF::Builder
("textHS()").
- $width = $content->advancewidthHS($HSarray, $settings, %opts)
- $width = $content->advancewidthHS($HSarray, $settings)
- Returns text chunk width (in points) for Shaper-defined glyph array. This
is the horizontal width for LTR and RTL direction, and the vertical height
for TTB and BTT direction. Note: You must define the font and font
size before calling
"advancewidthHS()".
- $HSarray
- The array reference of glyphs created by the HarfBuzz::Shaper call. See
"textHS()" for details.
- $settings
- the hash reference of settings. See
"textHS()" for details.
- dir => 'L' etc.
- the direction of the text, to know which "advance" value to sum
up.
- %opts
- Options. Unlike "advancewidth()", you
cannot override the font, font size, etc. used by HarfBuzz::Shaper to
calculate the glyph list.
- -doKern => flag (default 1)
- If 1, cancel minor kerns per "-minKern"
setting. This flag should be 0 (false) if -kern was passed to
HarfBuzz::Shaper (do not kern text). This is treated as 0 if an ax
override setting is given.
- -minKern => amount (default 1)
- If the amount of kerning (font character width differs from glyph
ax value) is larger than this many character grid units, use the
unaltered ax for the width ("textHS()"
will output a kern amount in the TJ operation). Otherwise, ignore kerning
and use ax of the actual character width. The intent is to avoid bloating
the PDF code with unnecessary tiny kerning adjustments in the TJ
operation.
Returns total width in points.
- $content->save()
- Saves the current graphics state on a PDF stack. See PDF definition
8.4.2 through 8.4.4 for details. This includes the line width, the line
cap style, line join style, miter limit, line dash pattern, stroke color,
fill color, current transformation matrix, current clipping port,
flatness, and dictname. This method applies to both text and
gfx objects.
- $content->restore()
- Restores the most recently saved graphics state (see
"save"), removing it from the stack. You
cannot restore the graphics state (pop it off the stack) unless you
have done at least one save (pushed it on the stack). This method
applies to both text and gfx objects.
- $content->add(@content)
- Add raw content (arbitrary string(s)) to the PDF stream. You will
generally want to use the other methods in this class instead, unless this
is in order to implement some PDF operation that PDF::Builder does not
natively support. An array of multiple strings may be given; they will be
concatenated with spaces between them.
Be careful when doing this, as you are dabbling in the black
arts, directly setting PDF operations!
One interesting use is to split up an overly long object
stream that is giving your editor problems when exploring a PDF file.
Add a newline add("\n") every few hundred bytes of
output or so, to do this. Note that you must use double quotes
(quotation marks), rather than single quotes (apostrophes).
Use extreme care if inserting BT and ET markers
into the PDF stream. You may want to use
"textstart()" and
"textend()" calls instead, and even
then, there are many side effects either way. It is generally not useful
to suspend text mode with ET/textend and BT/textstart, but it is
possible, if you really need to do it.
Another, useful, case is when your input PDF is from the
Chrome browser printing a page to PDF with headers and/or
footers. In some versions, this leaves the PDF page with a strange
scaling (such as the page height in points divided by 3300) and the
Y-axis flipped so 0 is at the top. This causes problems when trying to
add additional text or graphics in a new text or graphics record, where
text is flipped (mirrored) upsidedown and at the wrong end of the page.
If this happens, you might be able to cure it by adding
$scale = .23999999; # example, 792/3300, examine PDF or experiment!
...
if ($scale != 1) {
my @pageDim = $page->mediabox(); # e.g., 0 0 612 792
my $size_page = $pageDim[3]/$scale; # 3300 = 792/.23999999
my $invScale = 1.0/$scale; # 4.16666684
$text->add("$invScale 0 0 -$invScale 0 $size_page cm");
}
as the first output to the $text
stream. Unfortunately, it is difficult to predict exactly what
$scale should be, as it may be 3300 units per
page, or a fixed amount. You may need to examine an uncompressed PDF
file stream to see what is being used. It might be possible to
get the input (original) PDF into a string and look for a certain
pattern of "cm" output
.2399999 0 0 -.23999999 0 792 cm
or similar, which is not within a save/restore (q/Q). If the
stream is already compressed, this might not be possible.
- $content->addNS(@content)
- Like "add()", but does not make
sure there is a space between each element and before and after the new
content. It is up to you to ensure that any necessary spaces in the
PDF stream are placed there explicitly!
- $content->compressFlate()
- Marks content for compression on output. This is done automatically in
nearly all cases, so you shouldn't need to call this yourself.
The "new()" call can set the
-compress parameter to 'flate' (default) to compress all object
streams, or 'none' to suppress compression and allow you to examine the
output in an editor.
- $content->textstart()
- Starts a text object (ignored if already in a text object). You will
likely want to use the "text()" method
(text context, not text output) instead.
Note that calling this method, besides outputting a BT
marker, will reset most text settings to their default values. In
addition, BT itself will reset some transformation matrices.
- $content->textend()
- Ends a text object (ignored if not in a text object).
Note that calling this method, besides outputting an ET
marker, will output any accumulated poststream content.
Visit the GSP FreeBSD Man Page Interface. Output converted with ManDoc. |