Previous topic

Next topic

Drawing

Geometry

PDF uses the same geometry as PostScript. It starts from bottom-left
corner of page and by default is measured in points (1/72 of an inch).

Page size can be retrieved from a page object:

$width = $pdfPage->getWidth();

$height = $pdfPage->getHeight();

Colors

PDF has a powerful capabilities for colors representation.
Zend_Pdf module supports Gray Scale, RGB and CMYK color spaces.
Any of them can be used in any place, where Zend_Pdf_Color object
is required. Zend_Pdf_Color_GrayScale,
Zend_Pdf_Color_Rgb and Zend_Pdf_Color_Cmyk
classes provide this functionality:

Text Drawing

Text drawing operations also exist in the context of a PDF page. You
can draw a single line of text at any position on the page by supplying the x and y
coordinates of the baseline. Current font and current font size are used for text
drawing operations (see detailed description below).

/**

* Draw a line of text at the specified position.

*

* @param string $text

* @param float $x

* @param float $y

* @param string $charEncoding (optional) Character encoding of source

* text.Defaults to current locale.

* @throws Zend_Pdf_Exception

* @return Zend_Pdf_Page

*/

publicfunction drawText($text, $x, $y, $charEncoding = '');

Example #1 Draw a string on the page

...

$pdfPage->drawText('Hello world!', 72, 720);

...

By default, text strings are interpreted using the character encoding method of the
current locale. if you have a string that uses a different encoding method (such as a
UTF-8 string read from a file on disk, or a MacRoman string obtained from a legacy
database), you can indicate the character encoding at draw time and
Zend_Pdf will handle the conversion for you. You can supply
source strings in any encoding method supported by PHP's
» iconv()
function:

Zend_Pdf currently supports the standard 14
PDF fonts as well as your own custom TrueType fonts. Font objects are
obtained via one of two factory methods:
Zend_Pdf_Font::fontWithName($fontName) for the standard 14
PDF fonts or
Zend_Pdf_Font::fontWithPath($filePath) for custom fonts.

Example #3 Create a standard font

...

// Create new font

$font = Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_HELVETICA);

// Apply font

$pdfPage->setFont($font, 36);

...

Constants for the standard 14 PDF font names are defined in the
Zend_Pdf_Font class:

Zend_Pdf_Font::FONT_COURIER

Zend_Pdf_Font::FONT_COURIER_BOLD

Zend_Pdf_Font::FONT_COURIER_ITALIC

Zend_Pdf_Font::FONT_COURIER_BOLD_ITALIC

Zend_Pdf_Font::FONT_TIMES

Zend_Pdf_Font::FONT_TIMES_BOLD

Zend_Pdf_Font::FONT_TIMES_ITALIC

Zend_Pdf_Font::FONT_TIMES_BOLD_ITALIC

Zend_Pdf_Font::FONT_HELVETICA

Zend_Pdf_Font::FONT_HELVETICA_BOLD

Zend_Pdf_Font::FONT_HELVETICA_ITALIC

Zend_Pdf_Font::FONT_HELVETICA_BOLD_ITALIC

Zend_Pdf_Font::FONT_SYMBOL

Zend_Pdf_Font::FONT_ZAPFDINGBATS

You can also use any individual TrueType font (which usually has a '.ttf' extension) or
an OpenType font ('.otf' extension) if it contains TrueType outlines. Currently
unsupported, but planned for a future release are Mac OS X .dfont files and Microsoft
TrueType Collection ('.ttc' extension) files.

To use a TrueType font, you must provide the full file path to the font program. If the
font cannot be read for some reason, or if it is not a TrueType font, the factory method
will throw an exception:

By default, custom fonts will be embedded in the resulting PDF
document. This allows recipients to view the page as intended, even if they don't have
the proper fonts installed on their system. If you are concerned about file size, you
can request that the font program not be embedded by passing a 'do not embed' option to
the factory method:

Example #5 Create a TrueType font, but do not embed it in the PDF document

If the font program is not embedded but the recipient of the PDF file
has the font installed on their system, they will see the document as intended. If they
do not have the correct font installed, the PDF viewer application
will do its best to synthesize a replacement.

Some fonts have very specific licensing rules which prevent them from being embedded in
PDF documents. So you are not caught off-guard by this, if you try to
use a font that cannot be embedded, the factory method will throw an exception.

You can still use these fonts, but you must either pass the do not embed flag as
described above, or you can simply suppress the exception:

Example #6 Do not throw an exception for fonts that cannot be embedded

...

$font = Zend_Pdf_Font::fontWithPath(

'/path/to/unEmbeddableFont.ttf',

Zend_Pdf_Font::EMBED_SUPPRESS_EMBED_EXCEPTION

);

...

This suppression technique is preferred if you allow an end-user to choose their own
fonts. Fonts which can be embedded in the PDF document will be; those
that cannot, won't.

Font programs can be rather large, some reaching into the tens of megabytes. By default,
all embedded fonts are compressed using the Flate compression scheme, resulting in a
space savings of 50% on average. If, for some reason, you do not want to compress the
font program, you can disable it with an option:

Example #7 Do not compress an embedded font

...

$font = Zend_Pdf_Font::fontWithPath('/path/to/someReallyBigFont.ttf',

Zend_Pdf_Font::EMBED_DONT_COMPRESS);

...

Finally, when necessary, you can combine the embedding options by using the bitwise OR
operator:

Example #8 Combining font embedding options

...

$font = Zend_Pdf_Font::fontWithPath(

$someUserSelectedFontPath,

(Zend_Pdf_Font::EMBED_SUPPRESS_EMBED_EXCEPTION |

Zend_Pdf_Font::EMBED_DONT_COMPRESS));

...

Standard PDF fonts limitations

Standard PDF fonts use several single byte encodings internally
(see » PDF
Reference, Sixth Edition, version 1.7 Appendix D for details). They are
generally equal to Latin1 character set (except Symbol and ZapfDingbats fonts).

The nonzero winding number rule determines whether a given point is
inside a path by conceptually drawing a ray from that point to infinity
in any direction and then examining the places where a segment of the
path crosses the ray. Starting with a count of 0, the rule adds 1 each
time a path segment crosses the ray from left to right and subtracts 1
each time a segment crosses from right to left. After counting all the
crossings, if the result is 0 then the point is outside the path;
otherwise it is inside. Note: The method just described does not specify
what to do if a path segment coincides with or is tangent to the chosen
ray. Since the direction of the ray is arbitrary, the rule simply
chooses a ray that does not encounter such problem intersections. For
simple convex paths, the nonzero winding number rule defines the inside
and outside as one would intuitively expect. The more interesting cases
are those involving complex or self-intersecting paths like the ones
shown in Figure 4.10 (in a PDF Reference). For a path
consisting of a five-pointed star, drawn with five connected straight
line segments intersecting each other, the rule considers the inside to
be the entire area enclosed by the star, including the pentagon in the
center. For a path composed of two concentric circles, the areas
enclosed by both circles are considered to be inside, provided that both
are drawn in the same direction. If the circles are drawn in opposite
directions, only the "doughnut" shape between them is inside, according
to the rule; the "doughnut hole" is outside.

Zend_Pdf_Page::FILL_METHOD_EVEN_ODD

PDF reference describes this rule as follows:

An alternative to the nonzero winding number rule is the even-odd rule.
This rule determines the "insideness" of a point by drawing a ray from
that point in any direction and simply counting the number of path
segments that cross the ray, regardless of direction. If this number is
odd, the point is inside; if even, the point is outside. This yields the
same results as the nonzero winding number rule for paths with simple
shapes, but produces different results for more complex shapes. Figure
4.11 (in a PDF Reference) shows the effects of
applying the even-odd rule to complex paths. For the five-pointed star,
the rule considers the triangular points to be inside the path, but not
the pentagon in the center. For the two concentric circles, only the
"doughnut" shape between the two circles is considered inside,
regardless of the directions in which the circles are drawn.

Linear Transformations

Rotations

PDF page can be rotated before applying any draw operation.
It can be done by Zend_Pdf_Page::rotate() method:

/**

* Rotate the page.

*

* @param float $x - the X co-ordinate of rotation point

* @param float $y - the Y co-ordinate of rotation point

* @param float $angle - rotation angle

* @return Zend_Pdf_Page

*/

publicfunction rotate($x, $y, $angle);

Starting from ZF 1.8, scaling

Scaling transformation is provided by
Zend_Pdf_Page::scale() method:

/**

* Scale coordination system.

*

* @param float $xScale - X dimention scale factor

* @param float $yScale - Y dimention scale factor

* @return Zend_Pdf_Page

*/

publicfunction scale($xScale, $yScale);

Starting from ZF 1.8, translating

Coordinate system shifting is performed by
Zend_Pdf_Page::translate() method:

/**

* Translate coordination system.

*

* @param float $xShift - X coordinate shift

* @param float $yShift - Y coordinate shift

* @return Zend_Pdf_Page

*/

publicfunction translate($xShift, $yShift);

Starting from ZF 1.8, skewing

Page skewing can be done using Zend_Pdf_Page::skew()
method:

/**

* Translate coordination system.

*

* @param float $x - the X co-ordinate of axis skew point

* @param float $y - the Y co-ordinate of axis skew point

* @param float $xAngle - X axis skew angle

* @param float $yAngle - Y axis skew angle

* @return Zend_Pdf_Page

*/

publicfunction skew($x, $y, $xAngle, $yAngle);

Save/restore graphics state

At any time page graphics state (current font, font size, line color, fill color,
line style, page rotation, clip area) can be saved and then restored. Save operation
puts data to a graphics state stack, restore operation retrieves it from there.

There are two methods in Zend_Pdf_Page class for these
operations:

/**

* Save the graphics state of this page.

* This takes a snapshot of the currently applied style, position,

* clipping area and any rotation/translation/scaling that has been

* applied.

*

* @return Zend_Pdf_Page

*/

publicfunction saveGS();

/**

* Restore the graphics state that was saved with the last call to

* saveGS().

*

* @return Zend_Pdf_Page

*/

publicfunction restoreGS();

Clipping draw area

PDF and Zend_Pdf module support clipping of
draw area. Current clip area limits the regions of the page affected by painting
operators. It's a whole page initially.

Zend_Pdf_Page class provides a set of methods for clipping
operations.