LXXVII. PDF functions

You can use the PDF functions in PHP to create PDF files if you have the PDF library by Thomas Merz (available at http://www.pdflib.com/pdflib/index.html; you will also need the JPEG library and the TIFF library to compile this. These two libs also quite often make problems when configuring php. Follow the messages of configure to fix possible problems. If you use pdflib 2.01 check how the lib was installed. There should be file or link libpdf.so. Version 2.01 just creates a lib with the name libpdf2.01.so which cannot be found when linking the test programm in configure. You will have to create a symbolic link from libpdf.so to libpdf2.01.so.).

Version 2.20 of pdflib has introduced more changes to its API and support for chinese and japanese fonts. This unfortunately causes some changes of the pdf module of php4 (not php3). If you use pdflib 2.20 handle the in memory generation of PDF documents with care. Until pdflib 3.0 is released it might be unstable. The encoding parameter of pdf_set_font() has changed to a string. This means that instead of e.g. 4 you have to use 'winansi'.

If you use pdflib 2.30 the pdf_set_text_matrix() will have gone. It is not supported any more. In general it is a good advise to consult the release notes of the used version of pdflib for possible changes.

Since version 3.0 of pdflib you should configure pdflib with the option --enable-shared-pdflib.

Any version of PHP4 after March, 9th 2000 do not support versions of pdflib older than 3.0. PHP3 on the other hand should not be used with version newer than 2.01.

Please consult the excellent documentation for pdflib shipped with the source distribution of pdflib. It provides a very good overview of what pdflib capable of doing. Most of the functions in pdflib and the PHP module have the same name. The parameters are also identical. You should also understand some of the concepts of PDF or Postscript to efficiently use this module. All lengths and coordinates are measured in Postscript points. There are generally 72 PostScript points to an inch, but this depends on the output resolution.

There is another PHP module for pdf document creation based on FastIO's. ClibPDF. It has a slightly different API. Check the ClibPDF functions section for details.

Currently all versions of pdflib are supported. It is recommended that you use the newest version since it has more features and fixes some problems which required a patch for the old version. Unfortunately, the changes of the pdflib API in 2.x compared to 0.6 have been so severe that even some PHP functions had to be altered. Here is a list of changes:

There were some more changes with the release 2.01 of pdflib which should be covered by PHP. Some functions are not required anymore (e.g. pdf_put_image()). You will get a warning so don't be shocked.

The pdf module introduces two new types of variables (if pdflib 2.x is used it is only one new type). They are called pdfdoc and pdfinfo (pdfinfo is not existent if pdflib 2.x is used. pdfdoc is a pointer to a pdf document and almost all functions need it as its first parameter. pdfinfo contains meta data about the PDF document. It has to be set before pdf_open() is called.

Nota: The following is only TRUE for pdflib 0.6. Read the pdflib manual for newer version

In order to output text into a PDF document you will need to provide the afm file for each font. Afm files contain font metrics for a Postscript font. By default these afm files are searched for in a directory named 'fonts' relative to the directory where the PHP script is located. (Again, this was TRUE for pdflib 0.6, newer versions do not not neccessarily need the afm files.)

Most of the functions are fairly easy to use. The most difficult part is probably to create a very simple pdf document at all. The following example should help to get started. It uses the PHP functions for pdflib 0.6. It creates the file test.pdf with one page. The page contains the text "Times-Roman" in an outlined 30pt font. The text is also underlined.

Ejemplo 1. Creating a PDF document with pdflib 0.6

<?php
$fp = fopen("test.pdf", "w");
$info = PDF_get_info();
pdf_set_info_author($info, "Uwe Steinmann");
PDF_set_info_title($info, "Test for PHP wrapper of PDFlib 0.6");
PDF_set_info_author($info, "Name of Author");
pdf_set_info_creator($info, "See Author");
pdf_set_info_subject($info, "Testing");
$pdf = PDF_open($fp, $info);
PDF_begin_page($pdf, 595, 842);
PDF_add_outline($pdf, "Page 1");
pdf_set_font($pdf, "Times-Roman", 30, 4);
pdf_set_text_rendering($pdf, 1);
PDF_show_xy($pdf, "Times Roman outlined", 50, 750);
pdf_moveto($pdf, 50, 740);
pdf_lineto($pdf, 330, 740);
pdf_stroke($pdf);
PDF_end_page($pdf);
PDF_close($pdf);
fclose($fp);
echo "<A HREF=getpdf.php3>finished</A>";
?>

The PHP script getpdf.php3 just outputs the pdf document.

<?php
$fp = fopen("test.pdf", "r");
header("Content-type: application/pdf");
fpassthru($fp);
fclose($fp);
?>

Doing the same with pdflib 2.x looks like the following:

Ejemplo 2. Creating a PDF document with pdflib 2.x

<?php
$fp = fopen("test.pdf", "w");
$pdf = PDF_open($fp);
pdf_set_info_author($pdf, "Uwe Steinmann");
PDF_set_info_title($pdf, "Test for PHP wrapper of PDFlib 2.0");
PDF_set_info_author($pdf, "Name of Author");
pdf_set_info_creator($pdf, "See Author");
pdf_set_info_subject($pdf, "Testing");
PDF_begin_page($pdf, 595, 842);
PDF_add_outline($pdf, "Page 1");
pdf_set_font($pdf, "Times-Roman", 30, 4);
pdf_set_text_rendering($pdf, 1);
PDF_show_xy($pdf, "Times Roman outlined", 50, 750);
pdf_moveto($pdf, 50, 740);
pdf_lineto($pdf, 330, 740);
pdf_stroke($pdf);
PDF_end_page($pdf);
PDF_close($pdf);
fclose($fp);
echo "<A HREF=getpdf.php3>finished</A>";
?>

The PHP script getpdf.php3 is the same as above.

The pdflib distribution contains a more complex example which creates a serious of pages with an analog clock. This example converted into PHP using pdflib 2.x looks as the following (you can see the same example in the documentation for the clibpdf module):

Ejemplo 3. pdfclock example from pdflib 2.x distribution

<?php
$pdffilename = "clock.pdf";
$radius = 200;
$margin = 20;
$pagecount = 40;

$fp = fopen($pdffilename, "w");
$pdf = pdf_open($fp);
pdf_set_info_creator($pdf, "pdf_clock.php3");
pdf_set_info_author($pdf, "Uwe Steinmann");
pdf_set_info_title($pdf, "Analog Clock");

while($pagecount-- > 0) {
    pdf_begin_page($pdf, 2 * ($radius + $margin), 2 * ($radius + $margin));

    pdf_set_transition($pdf, 4);  /* wipe */ 
    pdf_set_duration($pdf, 0.5);
  
    pdf_translate($pdf, $radius + $margin, $radius + $margin);
    pdf_save($pdf);
    pdf_setrgbcolor($pdf, 0.0, 0.0, 1.0);

    /* minute strokes */
    pdf_setlinewidth($pdf, 2.0);
    for ($alpha = 0; $alpha < 360; $alpha += 6) {
        pdf_rotate($pdf, 6.0);
        pdf_moveto($pdf, $radius, 0.0);
        pdf_lineto($pdf, $radius-$margin/3, 0.0);
        pdf_stroke($pdf);
    }

    pdf_restore($pdf);
    pdf_save($pdf);

    /* 5 minute strokes */
    pdf_setlinewidth($pdf, 3.0);
    for ($alpha = 0; $alpha < 360; $alpha += 30) { 
        pdf_rotate($pdf, 30.0);
        pdf_moveto($pdf, $radius, 0.0);
        pdf_lineto($pdf, $radius-$margin, 0.0);
        pdf_stroke($pdf);
    }

    $ltime = getdate();

    /* draw hour hand */
    pdf_save($pdf);
    pdf_rotate($pdf,-(($ltime['minutes']/60.0)+$ltime['hours']-3.0)*30.0);
    pdf_moveto($pdf, -$radius/10, -$radius/20);
    pdf_lineto($pdf, $radius/2, 0.0);
    pdf_lineto($pdf, -$radius/10, $radius/20);
    pdf_closepath($pdf);
    pdf_fill($pdf);
    pdf_restore($pdf);

    /* draw minute hand */
    pdf_save($pdf);
    pdf_rotate($pdf,-(($ltime['seconds']/60.0)+$ltime['minutes']-15.0)*6.0);
    pdf_moveto($pdf, -$radius/10, -$radius/20);
    pdf_lineto($pdf, $radius * 0.8, 0.0);
    pdf_lineto($pdf, -$radius/10, $radius/20);
    pdf_closepath($pdf);
    pdf_fill($pdf);
    pdf_restore($pdf);

    /* draw second hand */
    pdf_setrgbcolor($pdf, 1.0, 0.0, 0.0);
    pdf_setlinewidth($pdf, 2);
    pdf_save($pdf);
    pdf_rotate($pdf, -(($ltime['seconds'] - 15.0) * 6.0));
    pdf_moveto($pdf, -$radius/5, 0.0);
    pdf_lineto($pdf, $radius, 0.0);
    pdf_stroke($pdf);
    pdf_restore($pdf);

    /* draw little circle at center */
    pdf_circle($pdf, 0, 0, $radius/30);
    pdf_fill($pdf);

    pdf_restore($pdf);

    pdf_end_page($pdf);
}

$pdf = pdf_close($pdf);
fclose($fp);
echo "<A HREF=getpdf.php3?filename=".$pdffilename.">finished</A>";
?>

The PHP script getpdf.php3 just outputs the pdf document.
<?php
$fp = fopen($filename, "r");
header("Content-type: application/pdf");
fpassthru($fp);
fclose($fp);
?>

Tabla de contenidos
pdf_add_annotation -- Adds annotation
pdf_add_bookmark -- Adds bookmark for current page
pdf_add_launchlink -- Add a launch annotation for current page
pdf_add_locallink -- Add a link annotation for current page
pdf_add_note -- Add a note annotation for current page
PDF_add_outline -- Adds bookmark for current page
pdf_add_pdflink -- Adds file link annotation for current page
pdf_add_thumbnail -- Adds thumbnail for current page
pdf_add_weblink -- Adds weblink for current page
PDF_arc -- Draws an arc
pdf_arcn -- Draws an arc (clockwise)
pdf_attach_file -- Adds a file attachement for current page
PDF_begin_page -- Starts new page
pdf_begin_pattern -- Starts new pattern
pdf_begin_template -- Starts new template
PDF_circle -- Draws a circle
PDF_clip -- Clips to current path
PDF_close_image -- Closes an image
pdf_close_pdi_page --  Close the page handle
pdf_close_pdi --  Close the input PDF document
PDF_close -- Closes a pdf document
PDF_closepath_fill_stroke -- Closes, fills and strokes current path
PDF_closepath_stroke -- Closes path and draws line along path
PDF_closepath -- Closes path
pdf_concat -- Concatenate a matrix to the CTM
PDF_continue_text -- Outputs text in next line
PDF_curveto -- Draws a curve
pdf_delete -- Deletes a PDF object
PDF_end_page -- Ends a page
pdf_end_pattern -- Finish pattern
pdf_end_template -- Finish template
PDF_endpath -- Ends current path
PDF_fill_stroke -- Fills and strokes current path
PDF_fill -- Fills current path
pdf_findfont -- Prepare font for later use with pdf_setfont().
pdf_get_buffer -- Fetch the buffer containig the generated PDF data.
pdf_get_font -- Deprecated: font handling
pdf_get_fontname -- Deprecated: font handling
pdf_get_fontsize -- Deprecated: font handling
pdf_get_image_height -- Returns height of an image
pdf_get_image_width -- Returns width of an image
pdf_get_majorversion --  Returns the major version number of the PDFlib
pdf_get_minorversion --  Returns the minor version number of the PDFlib
PDF_get_parameter -- Gets certain parameters
pdf_get_pdi_parameter -- Get some PDI string parameters
pdf_get_pdi_value -- Gets some PDI numerical parameters
PDF_get_value -- Gets certain numerical value
pdf_initgraphics -- Resets graphic state
PDF_lineto -- Draws a line
pdf_makespotcolor -- Makes a spotcolor
PDF_moveto -- Sets current point
pdf_new -- Creates a new pdf object
pdf_open_CCITT -- Opens a new image file with raw CCITT data
pdf_open_file -- Opens a new pdf object
PDF_open_gif -- Opens a GIF image
pdf_open_image_file -- Reads an image from a file
pdf_open_image -- Versatile function for images
PDF_open_jpeg -- Opens a JPEG image
PDF_open_memory_image -- Opens an image created with PHP's image functions
pdf_open_pdi_page --  Prepare a page
pdf_open_pdi --  Opens a PDF file
PDF_open_png --  Opens a PNG image
pdf_open_tiff -- Deprecated: Opens a TIFF image
PDF_open -- Opens a new pdf document
PDF_place_image -- Places an image on the page
pdf_place_pdi_page -- Places an image on the page
PDF_rect -- Draws a rectangle
PDF_restore -- Restores formerly saved environment
PDF_rotate -- Sets rotation
PDF_save -- Saves the current environment
PDF_scale -- Sets scaling
PDF_set_border_color -- Sets color of border around links and annotations
PDF_set_border_dash -- Sets dash style of border around links and annotations
PDF_set_border_style -- Sets style of border around links and annotations
PDF_set_char_spacing -- Sets character spacing
PDF_set_duration -- Sets duration between pages
PDF_set_font -- Selects a font face and size
PDF_set_horiz_scaling -- Sets horizontal scaling of text
pdf_set_info_author --  Fills the author field of the document
pdf_set_info_creator --  Fills the creator field of the document
pdf_set_info_keywords --  Fills the keywords field of the document
pdf_set_info_subject --  Fills the subject field of the document
pdf_set_info_title --  Fills the title field of the document
PDF_set_info -- Fills a field of the document information
PDF_set_leading -- Sets distance between text lines
PDF_set_parameter -- Sets certain parameters
PDF_set_text_matrix -- Sets the text matrix
PDF_set_text_pos -- Sets text position
PDF_set_text_rendering -- Determines how text is rendered
PDF_set_text_rise -- Sets the text rise
PDF_set_value -- Sets certain numerical value
PDF_set_word_spacing -- Sets spacing between words
pdf_setcolor -- Sets fill and stroke color
PDF_setdash -- Sets dash pattern
PDF_setflat -- Sets flatness
pdf_setfont -- Set the current font
PDF_setgray_fill -- Sets filling color to gray value
PDF_setgray_stroke -- Sets drawing color to gray value
PDF_setgray -- Sets drawing and filling color to gray value
PDF_setlinecap -- Sets linecap parameter
PDF_setlinejoin -- Sets linejoin parameter
PDF_setlinewidth -- Sets line width
pdf_setmatrix -- Sets current transformation matrix
PDF_setmiterlimit -- Sets miter limit
pdf_setpolydash -- Sets complicated dash pattern
PDF_setrgbcolor_fill -- Sets filling color to rgb color value
PDF_setrgbcolor_stroke -- Sets drawing color to rgb color value
PDF_setrgbcolor -- Sets drawing and filling color to rgb color value
PDF_show_boxed -- Output text in a box
PDF_show_xy -- Output text at given position
PDF_show -- Output text at current position
PDF_skew -- Skews the coordinate system
PDF_stringwidth -- Returns width of text using current font
PDF_stroke -- Draws line along path
PDF_translate -- Sets origin of coordinate system