Provided by: libpdf-builder-perl_3.023-2_all bug

NAME

       PDF::Builder::Content - Methods for adding graphics and text to a PDF

SYNOPSIS

           # 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.

METHODS

       All public methods listed, except as otherwise noted, return $self.

   Coordinate Transformations
       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.

   Graphics State Parameters
       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.

   Path Construction (Drawing)
       $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.

   Path Painting (Drawing)
       $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();

   Colors
       $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.

   External Objects
       $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
       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.

   Advanced Methods
       $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.