home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / Image / Canvas / PDF.php < prev    next >
Encoding:
PHP Script  |  2008-07-02  |  31.5 KB  |  1,012 lines

  1. <?php
  2.  
  3. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  4.  
  5. /**
  6.  * Class for handling output in PDF format.
  7.  * 
  8.  * Requires PHP extension PDFlib
  9.  *
  10.  * PHP versions 4 and 5
  11.  *
  12.  * LICENSE: This library is free software; you can redistribute it and/or modify
  13.  * it under the terms of the GNU Lesser General Public License as published by
  14.  * the Free Software Foundation; either version 2.1 of the License, or (at your
  15.  * option) any later version. This library is distributed in the hope that it
  16.  * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
  17.  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
  18.  * General Public License for more details. You should have received a copy of
  19.  * the GNU Lesser General Public License along with this library; if not, write
  20.  * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  21.  * 02111-1307 USA
  22.  *
  23.  * @category   Images
  24.  * @package    Image_Canvas
  25.  * @author     Jesper Veggerby <pear.nosey@veggerby.dk>
  26.  * @copyright  Copyright (C) 2003, 2004 Jesper Veggerby Hansen
  27.  * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
  28.  * @version    CVS: $Id: PDF.php,v 1.6 2006/04/11 21:12:41 nosey Exp $
  29.  * @link       http://pear.php.net/pepr/pepr-proposal-show.php?id=212
  30.  */
  31.  
  32. /**
  33.  * Include file Image/Canvas.php
  34.  */
  35. require_once 'Image/Canvas.php';
  36.  
  37. /**
  38.  * Include file Image/Canvas/Color.php
  39.  */
  40. require_once 'Image/Canvas/Color.php';
  41.  
  42. /**
  43.  * PDF Canvas class.
  44.  * 
  45.  * @category   Images
  46.  * @package    Image_Canvas
  47.  * @author     Jesper Veggerby <pear.nosey@veggerby.dk>
  48.  * @copyright  Copyright (C) 2003, 2004 Jesper Veggerby Hansen
  49.  * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
  50.  * @version    Release: @package_version@
  51.  * @link       http://pear.php.net/pepr/pepr-proposal-show.php?id=212
  52.  */
  53. class Image_Canvas_PDF extends Image_Canvas
  54. {
  55.  
  56.     /**
  57.      * The PDF document
  58.      * @var resource
  59.      * @access private
  60.      */
  61.     var $_pdf;
  62.  
  63.     /**
  64.      * The major version of PDFlib
  65.      * @var int
  66.      * @access private
  67.      */
  68.     var $_pdflib;
  69.  
  70.     /**
  71.      * The font
  72.      * @var mixed
  73.      * @access private
  74.      */
  75.     var $_pdfFont = false;
  76.  
  77.     /**
  78.      * The width of the page
  79.      * @var int
  80.      * @access private
  81.      */
  82.     var $_pageWidth;
  83.  
  84.     /**
  85.      * The height of the page
  86.      * @var int
  87.      * @access private
  88.      */
  89.     var $_pageHeight;
  90.  
  91.     /**
  92.      * Create the PDF canvas.
  93.      *
  94.      * Parameters available:
  95.      *
  96.      * 'page' Specify the page/paper format for the graph's page, available
  97.      * formats are: A0, A1, A2, A3, A4, A5, A6, B5, letter, legal, ledger,
  98.      * 11x17, cd_front, inlay, inlay_nosides
  99.      *
  100.      * 'align' Alignment of the graph on the page, available options are:
  101.      * topleft, topcenter, topright, leftcenter, center, rightcenter,
  102.      * leftbottom, centerbottom, rightbottom
  103.      *
  104.      * 'orientation' Specifies the paper orientation, default is 'portrait' and
  105.      * 'landscape' is also supported.
  106.      *
  107.      * 'creator' The creator tag of the PDF/graph
  108.      *
  109.      * 'author' The author tag of the PDF/graph
  110.      *
  111.      * 'title' The title tag of the PDF/graph
  112.      *
  113.      * 'width' The width of the graph on the page
  114.      *
  115.      * 'height' The height of the graph on the page
  116.      *
  117.      * 'left' The left offset of the graph on the page
  118.      *
  119.      * 'top' The top offset of the graph on the page
  120.      *
  121.      * 'filename' The PDF file to open/add page to, using 'filename' requires
  122.      * the commercial version of PDFlib (http://www.pdflib.com/), this has for
  123.      * obvious ($ 450) reasons not been tested
  124.      *
  125.      * 'pdf' An existing PDFlib PDF document to add the page to
  126.      *
  127.      * 'add_page' (true/false) Used together with 'pdf', to specify whether the
  128.      * canvas should add a new graph page (true) or create the graph on the
  129.      * current page (false), default is 'true'
  130.      *
  131.      * The 'page' and 'width' & 'height' can be mutually omitted, if 'page' is
  132.      * omitted the page is created using dimensions of width x height, and if
  133.      * width and height are omitted the page dimensions are used for the graph.
  134.      *
  135.      * If 'pdf' is specified, 'filename', 'creator', 'author' and 'title' has no
  136.      * effect.
  137.      *
  138.      * 'left' and 'top' are overridden by 'align'
  139.      *
  140.      * It is required either to specify 'width' & 'height' or 'page'.
  141.      *
  142.      * The PDF format/PDFlib has some limitations on the capabilities, which
  143.      * means some functionality available using other canvass (fx. alpha
  144.      * blending and gradient fills) are not supported with PDF (see Canvas.txt
  145.      * in the docs/ folder for further details)
  146.      *
  147.      * @param array $param Parameter array
  148.      */
  149.     function Image_Canvas_PDF($param)
  150.     {
  151.         if (isset($param['page'])) {
  152.             switch (strtoupper($param['page'])) {
  153.             case 'A0':
  154.                 $this->_pageWidth = 2380;
  155.                 $this->_pageHeight = 3368;
  156.                 break;
  157.  
  158.             case 'A1':
  159.                 $this->_pageWidth = 1684;
  160.                 $this->_pageHeight = 2380;
  161.                 break;
  162.  
  163.             case 'A2':
  164.                 $this->_pageWidth = 1190;
  165.                 $this->_pageHeight = 1684;
  166.                 break;
  167.  
  168.             case 'A3':
  169.                 $this->_pageWidth = 842;
  170.                 $this->_pageHeight = 1190;
  171.                 break;
  172.  
  173.             case 'A4':
  174.                 $this->_pageWidth = 595;
  175.                 $this->_pageHeight = 842;
  176.                 break;
  177.  
  178.             case 'A5':
  179.                 $this->_pageWidth = 421;
  180.                 $this->_pageHeight = 595;
  181.                 break;
  182.  
  183.             case 'A6':
  184.                 $this->_pageWidth = 297;
  185.                 $this->_pageHeight = 421;
  186.                 break;
  187.  
  188.             case 'B5':
  189.                 $this->_pageWidth = 501;
  190.                 $this->_pageHeight = 709;
  191.                 break;
  192.  
  193.             case 'LETTER':
  194.                 $this->_pageWidth = 612;
  195.                 $this->_pageHeight = 792;
  196.                 break;
  197.  
  198.             case 'LEGAL':
  199.                 $this->_pageWidth = 612;
  200.                 $this->_pageHeight = 1008;
  201.                 break;
  202.  
  203.             case 'LEDGER':
  204.                 $this->_pageWidth = 1224;
  205.                 $this->_pageHeight = 792;
  206.                 break;
  207.  
  208.             case '11X17':
  209.                 $this->_pageWidth = 792;
  210.                 $this->_pageHeight = 1224;
  211.                 break;
  212.  
  213.             case 'CD_FRONT':
  214.                 $this->_pageWidth = 337;
  215.                 $this->_pageHeight = 337;
  216.                 break;
  217.  
  218.             case 'INLAY':
  219.                 $this->_pageWidth = 425;
  220.                 $this->_pageHeight = 332;
  221.                 break;
  222.  
  223.             case 'INLAY_NOSIDES':
  224.                 $this->_pageWidth = 390;
  225.                 $this->_pageHeight = 332;
  226.                 break;
  227.             }
  228.         }
  229.  
  230.         if ((isset($param['orientation'])) && (strtoupper($param['orientation']) == 'LANDSCAPE')) {
  231.             $w = $this->_pageWidth;
  232.             $this->_pageWidth = $this->_pageHeight;
  233.             $this->_pageHeight = $w;
  234.         }
  235.  
  236.         parent::Image_Canvas($param);
  237.  
  238.         if (!$this->_pageWidth) {
  239.             $this->_pageWidth = $this->_width;
  240.         } elseif (!$this->_width) {
  241.             $this->_width = $this->_pageWidth;
  242.         }
  243.  
  244.         if (!$this->_pageHeight) {
  245.             $this->_pageHeight = $this->_height;
  246.         } elseif (!$this->_height) {
  247.             $this->_height = $this->_pageHeight;
  248.         }
  249.  
  250.         $this->_width = min($this->_width, $this->_pageWidth);
  251.         $this->_height = min($this->_height, $this->_pageHeight);
  252.  
  253.         if ((isset($param['align'])) &&
  254.             (($this->_width != $this->_pageWidth) || ($this->_height != $this->_pageHeight))
  255.         ) {
  256.             switch (strtoupper($param['align'])) {
  257.             case 'TOPLEFT':
  258.                 $this->_top = 0;
  259.                 $this->_left = 0;
  260.                 break;
  261.  
  262.             case 'TOPCENTER':
  263.                 $this->_top = 0;
  264.                 $this->_left = ($this->_pageWidth - $this->_width) / 2;
  265.                 break;
  266.  
  267.             case 'TOPRIGHT':
  268.                 $this->_top = 0;
  269.                 $this->_left = $this->_pageWidth - $this->_width;
  270.                 break;
  271.  
  272.             case 'LEFTCENTER':
  273.                 $this->_top = ($this->_pageHeight - $this->_height) / 2;
  274.                 $this->_left = 0;
  275.                 break;
  276.  
  277.             case 'CENTER':
  278.                 $this->_top = ($this->_pageHeight - $this->_height) / 2;
  279.                 $this->_left = ($this->_pageWidth - $this->_width) / 2;
  280.                 break;
  281.  
  282.             case 'RIGHTCENTER':
  283.                 $this->_top = ($this->_pageHeight - $this->_height) / 2;
  284.                 $this->_left = $this->_pageWidth - $this->_width;
  285.                 break;
  286.  
  287.             case 'LEFTBOTTOM':
  288.                 $this->_top = $this->_pageHeight - $this->_height;
  289.                 $this->_left = 0;
  290.                 break;
  291.  
  292.             case 'CENTERBOTTOM':
  293.                 $this->_top = $this->_pageHeight - $this->_height;
  294.                 $this->_left = ($this->_pageWidth - $this->_width) / 2;
  295.                 break;
  296.  
  297.             case 'RIGHTBOTTOM':
  298.                 $this->_top = $this->_pageHeight - $this->_height;
  299.                 $this->_left = $this->_pageWidth - $this->_width;
  300.                 break;
  301.             }
  302.         }
  303.  
  304.         $addPage = true;
  305.         if ((isset($param['pdf'])) && (is_resource($param['pdf']))) {
  306.             $this->_pdf =& $param['pdf'];
  307.             if ((isset($param['add_page'])) && ($param['add_page'] === false)) {
  308.                 $addPage = false;
  309.             }
  310.         } else {
  311.             $this->_pdf = pdf_new();
  312.  
  313.             if (isset($param['filename'])) {
  314.                 pdf_open_file($this->_pdf, $param['filename']);
  315.             } else {
  316.                 pdf_open_file($this->_pdf, '');
  317.             }
  318.  
  319.             pdf_set_parameter($this->_pdf, 'warning', 'true');
  320.  
  321.             pdf_set_info($this->_pdf, 'Creator', (isset($param['creator']) ? $param['creator'] : 'PEAR::Image_Canvas'));
  322.             pdf_set_info($this->_pdf, 'Author', (isset($param['author']) ? $param['author'] : 'Jesper Veggerby'));
  323.             pdf_set_info($this->_pdf, 'Title', (isset($param['title']) ? $param['title'] : 'Image_Canvas'));
  324.         }
  325.  
  326.         if ($addPage) {
  327.             pdf_begin_page($this->_pdf, $this->_pageWidth, $this->_pageHeight);
  328.         }
  329.         $this->_reset();
  330.  
  331.         $this->_pdflib = $this->_version();
  332.     }
  333.  
  334.     /**
  335.      * Get the x-point from the relative to absolute coordinates
  336.      *
  337.      * @param float $x The relative x-coordinate (in percentage of total width)
  338.      * @return float The x-coordinate as applied to the canvas
  339.      * @access private
  340.      */
  341.     function _getX($x)
  342.     {
  343.         return $this->_left + $x;
  344.     }
  345.  
  346.     /**
  347.      * Get the y-point from the relative to absolute coordinates
  348.      *
  349.      * @param float $y The relative y-coordinate (in percentage of total width)
  350.      * @return float The y-coordinate as applied to the canvas
  351.      * @access private
  352.      */
  353.     function _getY($y)
  354.     {
  355.         return $this->_pageHeight - ($this->_top + $y);
  356.     }
  357.  
  358.     /**
  359.      * Get the color index for the RGB color
  360.      *
  361.      * @param int $color The color
  362.      * @return int The GD image index of the color
  363.      * @access private
  364.      */
  365.     function _color($color = false)
  366.     {
  367.         if (($color === false) || ($color === 'opague') || ($color === 'transparent')) {
  368.             return false;
  369.         } else {
  370.             $color = Image_Canvas_Color::color2RGB($color);
  371.             $color[0] = $color[0]/255;
  372.             $color[1] = $color[1]/255;
  373.             $color[2] = $color[2]/255;
  374.             return $color;
  375.         }
  376.     }
  377.  
  378.     /**
  379.      * Get the PDF linestyle
  380.      *
  381.      * @param mixed $lineStyle The line style to return, false if the one
  382.      *   explicitly set
  383.      * @return bool True if set (so that a line should be drawn)
  384.      * @access private
  385.      */
  386.     function _setLineStyle($lineStyle = false)
  387.     {
  388.         if ($lineStyle === false) {
  389.             $lineStyle = $this->_lineStyle;
  390.         }
  391.  
  392.         if (($lineStyle == 'transparent') || ($lineStyle === false)) {
  393.             return false;
  394.         }
  395.         
  396.         if (is_array($lineStyle)) {
  397.             // TODO Implement linestyles in PDFlib (using pdf_setcolor(.., 'pattern'...); ?
  398.             reset($lineStyle);
  399.             $lineStyle = current($lineStyle);
  400.         } 
  401.  
  402.         $color = $this->_color($lineStyle);
  403.  
  404.         pdf_setlinewidth($this->_pdf, $this->_thickness);
  405.         if ($this->_pdflib < 4) {
  406.             pdf_setrgbcolor_stroke($this->_pdf, $color[0]/255, $color[1]/255, $color[2]/255);
  407.         } else {
  408.             pdf_setcolor($this->_pdf, 'stroke', 'rgb', $color[0], $color[1], $color[2], 0);
  409.         }
  410.         return true;
  411.     }
  412.  
  413.     /**
  414.      * Set the PDF fill style
  415.      *
  416.      * @param mixed $fillStyle The fillstyle to return, false if the one
  417.      *   explicitly set
  418.      * @return bool True if set (so that a line should be drawn)
  419.      * @access private
  420.      */
  421.     function _setFillStyle($fillStyle = false)
  422.     {
  423.         if ($fillStyle === false) {
  424.             $fillStyle = $this->_fillStyle;
  425.         }
  426.  
  427.         if (($fillStyle == 'transparent') || ($fillStyle === false)) {
  428.             return false;
  429.         }
  430.  
  431.         $color = $this->_color($fillStyle);
  432.  
  433.         if ($this->_pdflib < 4) {
  434.             pdf_setrgbcolor_fill($this->_pdf, $color[0]/255, $color[1]/255, $color[2]/255);
  435.         } else {
  436.             pdf_setcolor($this->_pdf, 'fill', 'rgb', $color[0], $color[1], $color[2], 0);
  437.         }
  438.         return true;
  439.     }
  440.  
  441.     /**
  442.      * Set the PDF font
  443.      *
  444.      * @access private
  445.      */
  446.     function _setFont()
  447.     {
  448.         $this->_pdfFont = false;
  449.         if (isset($this->_font['name'])) {
  450.             pdf_set_parameter($this->_pdf, 'FontOutline', $this->_font['name'] . '=' . $this->_font['file']);
  451.             $this->_pdfFont = pdf_findfont($this->_pdf, $this->_font['name'], $this->_font['encoding'], 1);
  452.  
  453.             if ($this->_pdfFont) {
  454.                 pdf_setfont($this->_pdf, $this->_pdfFont, $this->_font['size']);
  455.                 $this->_setFillStyle($this->_font['color']);
  456.             }
  457.         } else {
  458.             $this->_setFillStyle('black');
  459.         }
  460.     }
  461.  
  462.     /**
  463.      * Sets an image that should be used for filling.
  464.      *
  465.      * Image filling is not supported with PDF, filling 'transparent'
  466.      *
  467.      * @param string $filename The filename of the image to fill with
  468.      */
  469.     function setFillImage($filename)
  470.     {
  471.         $this->_fillStyle = 'transparent';
  472.     }
  473.  
  474.     /**
  475.      * Sets a gradient fill
  476.      *
  477.      * Gradient filling is not supported with PDF, end color used as solid fill.
  478.      *
  479.      * @param array $gradient Gradient fill options
  480.      */
  481.     function setGradientFill($gradient)
  482.     {
  483.         $this->_fillStyle = $gradient['end'];
  484.     }
  485.  
  486.     /**
  487.      * Sets the font options.
  488.      *
  489.      * The $font array may have the following entries:
  490.      *
  491.      * 'ttf' = the .ttf file (either the basename, filename or full path)
  492.      * If 'ttf' is specified, then the following can be specified
  493.      *
  494.      * 'size' = size in pixels
  495.      *
  496.      * 'angle' = the angle with which to write the text
  497.      *
  498.      * @param array $font The font options.
  499.      */
  500.     function setFont($fontOptions)
  501.     {
  502.         parent::setFont($fontOptions);
  503.  
  504.         if (!isset($this->_font['size'])) {
  505.             $this->_font['size'] = 12;
  506.         }
  507.  
  508.         if (!isset($this->_font['encoding'])) {
  509.             $this->_font['encoding'] = 'winansi';
  510.         }
  511.  
  512.         if (!isset($this->_font['color'])) {
  513.             $this->_font['color'] = 'black';
  514.         }
  515.     }
  516.  
  517.     /**
  518.      * Resets the canvas.
  519.      *
  520.      * Includes fillstyle, linestyle, thickness and polygon
  521.      *
  522.      * @access private
  523.      */
  524.     function _reset()
  525.     {
  526.         pdf_initgraphics($this->_pdf);
  527.         parent::_reset();
  528.     }
  529.  
  530.     /**
  531.      * Draw a line
  532.      *
  533.      * Parameter array:
  534.      * 'x0': int X start point
  535.      * 'y0': int Y start point
  536.      * 'x1': int X end point
  537.      * 'y1': int Y end point
  538.      * 'color': mixed [optional] The line color
  539.      * @param array $params Parameter array
  540.      */
  541.     function line($params)
  542.     {
  543.         $color = (isset($params['color']) ? $params['color'] : false);
  544.         if ($this->_setLineStyle($color)) {
  545.             pdf_moveto($this->_pdf, $this->_getX($params['x0']), $this->_getY($params['y0']));
  546.             pdf_lineto($this->_pdf, $this->_getX($params['x1']), $this->_getY($params['y1']));
  547.             pdf_stroke($this->_pdf);
  548.         }
  549.         parent::line($params);
  550.     }
  551.  
  552.     /**
  553.      * Parameter array:
  554.      * 'connect': bool [optional] Specifies whether the start point should be
  555.      *   connected to the endpoint (closed polygon) or not (connected line)
  556.      * 'fill': mixed [optional] The fill color
  557.      * 'line': mixed [optional] The line color
  558.      * @param array $params Parameter array
  559.      */
  560.     function polygon($params = array())
  561.     {
  562.         $connectEnds = (isset($params['connect']) ? $params['connect'] : false);
  563.         $fillColor = (isset($params['fill']) ? $params['line'] : false);
  564.         $lineColor = (isset($params['line']) ? $params['line'] : false);
  565.  
  566.         $line = $this->_setLineStyle($lineColor);
  567.         $fill = false;
  568.         if ($connectEnds) {
  569.             $fill = $this->_setFillStyle($fillColor);
  570.         }
  571.  
  572.         $first = true;
  573.         foreach ($this->_polygon as $point) {
  574.             if ($first === true) {
  575.                 pdf_moveto($this->_pdf, $point['X'], $point['Y']);
  576.                 $first = $point;
  577.             } else {
  578.                 if (isset($last['P1X'])) {
  579.                     pdf_curveto($this->_pdf,
  580.                         $last['P1X'],
  581.                         $last['P1Y'],
  582.                         $last['P2X'],
  583.                         $last['P2Y'],
  584.                         $point['X'],
  585.                         $point['Y']
  586.                     );
  587.                 } else {
  588.                     pdf_lineto($this->_pdf,
  589.                         $point['X'],
  590.                         $point['Y']
  591.                     );
  592.                 }
  593.             }
  594.             $last = $point;
  595.         }
  596.  
  597.         if ($connectEnds) {
  598.             if (isset($last['P1X'])) {
  599.                 pdf_curveto($this->_pdf,
  600.                     $last['P1X'],
  601.                     $last['P1Y'],
  602.                     $last['P2X'],
  603.                     $last['P2Y'],
  604.                     $first['X'],
  605.                     $first['Y']
  606.                 );
  607.             } else {
  608.                 pdf_lineto($this->_pdf,
  609.                     $first['X'],
  610.                     $first['Y']
  611.                 );
  612.             }
  613.         }
  614.  
  615.         if (($line) && ($fill)) {
  616.             pdf_fill_stroke($this->_pdf);
  617.         } elseif ($line) {
  618.             pdf_stroke($this->_pdf);
  619.         } elseif ($fill) {
  620.             pdf_fill($this->_pdf);
  621.         }
  622.         parent::polygon($params);
  623.     }
  624.  
  625.     /**
  626.      * Draw a rectangle
  627.      *
  628.      * Parameter array:
  629.      * 'x0': int X start point
  630.      * 'y0': int Y start point
  631.      * 'x1': int X end point
  632.      * 'y1': int Y end point
  633.      * 'fill': mixed [optional] The fill color
  634.      * 'line': mixed [optional] The line color
  635.      * @param array $params Parameter array
  636.      */
  637.     function rectangle($params)
  638.     {
  639.         $x0 = $this->_getX($params['x0']);
  640.         $y0 = $this->_getY($params['y0']);
  641.         $x1 = $this->_getX($params['x1']);
  642.         $y1 = $this->_getY($params['y1']);
  643.         $fillColor = (isset($params['fill']) ? $params['line'] : false);
  644.         $lineColor = (isset($params['line']) ? $params['line'] : false);
  645.  
  646.         $line = $this->_setLineStyle($lineColor);
  647.         $fill = $this->_setFillStyle($fillColor);
  648.         if (($line) || ($fill)) {
  649.             pdf_rect($this->_pdf, min($x0, $x1), min($y0, $y1), abs($x1 - $x0), abs($y1 - $y0));
  650.             if (($line) && ($fill)) {
  651.                 pdf_fill_stroke($this->_pdf);
  652.             } elseif ($line) {
  653.                 pdf_stroke($this->_pdf);
  654.             } elseif ($fill) {
  655.                 pdf_fill($this->_pdf);
  656.             }
  657.         }
  658.         parent::rectangle($params);
  659.     }
  660.  
  661.     /**
  662.      * Draw an ellipse
  663.      *
  664.      * Parameter array:
  665.      * 'x': int X center point
  666.      * 'y': int Y center point
  667.      * 'rx': int X radius
  668.      * 'ry': int Y radius
  669.      * 'fill': mixed [optional] The fill color
  670.      * 'line': mixed [optional] The line color
  671.      * @param array $params Parameter array
  672.      */
  673.     function ellipse($params)
  674.     {
  675.         $x = $params['x'];
  676.         $y = $params['y'];
  677.         $rx = $params['rx'];
  678.         $ry = $params['ry'];
  679.         $fillColor = (isset($params['fill']) ? $params['line'] : false);
  680.         $lineColor = (isset($params['line']) ? $params['line'] : false);
  681.  
  682.         $line = $this->_setLineStyle($lineColor);
  683.         $fill = $this->_setFillStyle($fillColor);
  684.         if (($line) || ($fill)) {
  685.             if ($rx == $ry) {
  686.                 pdf_circle($this->_pdf, $this->_getX($x), $this->_getY($y), $rx);
  687.             } else {
  688.                 pdf_moveto($this->_pdf, $this->_getX($x - $rx), $this->_getY($y));
  689.                 pdf_curveto($this->_pdf,
  690.                     $this->_getX($x - $rx), $this->_getY($y),
  691.                     $this->_getX($x - $rx), $this->_getY($y - $ry),
  692.                     $this->_getX($x), $this->_getY($y - $ry)
  693.                 );
  694.                 pdf_curveto($this->_pdf,
  695.                     $this->_getX($x), $this->_getY($y - $ry),
  696.                     $this->_getX($x + $rx), $this->_getY($y - $ry),
  697.                     $this->_getX($x + $rx), $this->_getY($y)
  698.                 );
  699.                 pdf_curveto($this->_pdf,
  700.                     $this->_getX($x + $rx), $this->_getY($y),
  701.                     $this->_getX($x + $rx), $this->_getY($y + $ry),
  702.                     $this->_getX($x), $this->_getY($y + $ry)
  703.                 );
  704.                 pdf_curveto($this->_pdf,
  705.                     $this->_getX($x), $this->_getY($y + $ry),
  706.                     $this->_getX($x - $rx), $this->_getY($y + $ry),
  707.                     $this->_getX($x - $rx), $this->_getY($y)
  708.                 );
  709.             }
  710.  
  711.             if (($line) && ($fill)) {
  712.                 pdf_fill_stroke($this->_pdf);
  713.             } elseif ($line) {
  714.                 pdf_stroke($this->_pdf);
  715.             } elseif ($fill) {
  716.                 pdf_fill($this->_pdf);
  717.             }
  718.         }
  719.         parent::ellipse($params);
  720.     }
  721.  
  722.     /**
  723.      * Draw a pie slice
  724.      *
  725.      * Parameter array:
  726.      * 'x': int X center point
  727.      * 'y': int Y center point
  728.      * 'rx': int X radius
  729.      * 'ry': int Y radius
  730.      * 'v1': int The starting angle (in degrees)
  731.      * 'v2': int The end angle (in degrees)
  732.      * 'srx': int [optional] Starting X-radius of the pie slice (i.e. for a doughnut)
  733.      * 'sry': int [optional] Starting Y-radius of the pie slice (i.e. for a doughnut)
  734.      * 'fill': mixed [optional] The fill color
  735.      * 'line': mixed [optional] The line color
  736.      * @param array $params Parameter array
  737.      */
  738.     function pieslice($params)
  739.     {
  740.         $x = $this->_getX($params['x']);
  741.         $y = $this->_getY($params['y']);
  742.         $rx = $this->_getX($params['rx']);
  743.         $ry = $this->_getY($params['ry']);
  744.         $v1 = $this->_getX($params['v1']);
  745.         $v2 = $this->_getY($params['v2']);
  746.         $srx = $this->_getX($params['srx']);
  747.         $sry = $this->_getY($params['sry']);
  748.         $fillColor = (isset($params['fill']) ? $params['line'] : false);
  749.         $lineColor = (isset($params['line']) ? $params['line'] : false);
  750.  
  751.         // TODO Implement PDFLIB::pieSlice()
  752.         parent::pieslice($params);
  753.     }
  754.  
  755.     /**
  756.      * Get the width of a text,
  757.      *
  758.      * @param string $text The text to get the width of
  759.      * @return int The width of the text
  760.      */
  761.     function textWidth($text)
  762.     {
  763.         if ($this->_pdfFont === false) {
  764.              return $this->_font['size'] * 0.7 * strlen($text);
  765.          } else {
  766.             return pdf_stringwidth($this->_pdf, $text, $this->_pdfFont, $this->_font['size']);
  767.         }
  768.     }
  769.  
  770.     /**
  771.      * Get the height of a text,
  772.      *
  773.      * @param string $text The text to get the height of
  774.      * @return int The height of the text
  775.      */
  776.     function textHeight($text)
  777.     {
  778.         if (isset($this->_font['size'])) {
  779.             return $this->_font['size'];
  780.         } else {
  781.             return 12;
  782.         }
  783.     }
  784.  
  785.     /**
  786.      * Writes text
  787.      *
  788.      * Parameter array:
  789.      * 'x': int X-point of text
  790.      * 'y': int Y-point of text
  791.      * 'text': string The text to add
  792.      * 'alignment': array [optional] Alignment
  793.      * 'color': mixed [optional] The color of the text
  794.      */
  795.     function addText($params)
  796.     {
  797.         $x = $this->_getX($params['x']);
  798.         $y = $this->_getY($params['y']);
  799.         $text = $params['text'];
  800.         $color = (isset($params['color']) ? $params['color'] : false);
  801.         $alignment = (isset($params['alignment']) ? $params['alignment'] : false);
  802.  
  803.         $this->_setFont();
  804.  
  805.         $textWidth = $this->textWidth($text);
  806.         $textHeight = $this->textHeight($text);
  807.  
  808.         if (!is_array($alignment)) {
  809.             $alignment = array('vertical' => 'top', 'horizontal' => 'left');
  810.         }
  811.         
  812.         if (!isset($alignment['vertical'])) {
  813.             $alignment['vertical'] = 'top';
  814.         }
  815.         
  816.         if (!isset($alignment['horizontal'])) {
  817.             $alignment['horizontal'] = 'left';
  818.         }
  819.  
  820.         if ($alignment['horizontal'] == 'right') {
  821.             $x = $x - $textWidth;
  822.         } elseif ($alignment['horizontal'] == 'center') {
  823.             $x = $x - ($textWidth / 2);
  824.         }
  825.  
  826.         $y -= $textHeight;
  827.  
  828.         if ($alignment['vertical'] == 'bottom') {
  829.             $y = $y + $textHeight;
  830.         } elseif ($alignment['vertical'] == 'center') {
  831.             $y = $y + ($textHeight / 2);
  832.         }
  833.  
  834.         if (($color === false) && (isset($this->_font['color']))) {
  835.             $color = $this->_font['color'];
  836.         }
  837.  
  838.         pdf_show_xy($this->_pdf, $text, $x, $y);
  839.  
  840.         parent::addText($params);
  841.     }
  842.  
  843.     /**
  844.      * Overlay image
  845.      *
  846.      * Parameter array:
  847.      * 'x': int X-point of overlayed image
  848.      * 'y': int Y-point of overlayed image
  849.      * 'filename': string The filename of the image to overlay
  850.      * 'width': int [optional] The width of the overlayed image (resizing if possible)
  851.      * 'height': int [optional] The height of the overlayed image (resizing if possible)
  852.      * 'alignment': array [optional] Alignment
  853.      */
  854.     function image($params)
  855.     {
  856.         $x = $this->_getX($params['x']);
  857.         $y = $this->_getY($params['y']);
  858.         $filename = $params['filename'];
  859.         $width = (isset($params['width']) ? $params['width'] : false);
  860.         $height = (isset($params['height']) ? $params['height'] : false);
  861.         $alignment = (isset($params['alignment']) ? $params['alignment'] : false);
  862.  
  863.         if (substr($filename, -4) == '.png') {
  864.             $type = 'png';
  865.         } elseif (substr($filename, -4) == '.jpg') {
  866.             $type = 'jpeg';
  867.         }
  868.  
  869.         $image = pdf_load_image($this->_pdf, $type, realpath($filename), '');
  870.         $width_ = pdf_get_value($this->_pdf, 'imagewidth', $image);
  871.         $height_ = pdf_get_value($this->_pdf, 'imageheight', $image);
  872.  
  873.         $outputWidth = ($width !== false ? $width : $width_);
  874.         $outputHeight = ($height !== false ? $height : $height_);
  875.  
  876.         if (!is_array($alignment)) {
  877.             $alignment = array('vertical' => 'top', 'horizontal' => 'left');
  878.         }
  879.         
  880.         if (!isset($alignment['vertical'])) {
  881.             $alignment['vertical'] = 'top';
  882.         }
  883.         
  884.         if (!isset($alignment['horizontal'])) {
  885.             $alignment['horizontal'] = 'left';
  886.         }
  887.  
  888.         if ($alignment['horizontal'] == 'right') {
  889.             $x -= $outputWidth;
  890.         } elseif ($alignment['horizontal'] == 'center') {
  891.             $x -= $outputWidth / 2;
  892.         }
  893.  
  894.         if ($alignment['vertical'] == 'top') {
  895.             $y += $outputHeight;
  896.         } elseif ($alignment['vertical'] == 'center') {
  897.             $y += $outputHeight / 2;
  898.         }
  899.         
  900.         if (($width === false) && ($height === false)) {
  901.             $scale = 1;
  902.         } else {
  903.             $scale = max(($height/$height_), ($width/$width_));
  904.         }   
  905.  
  906.         pdf_place_image($this->_pdf, $image, $x, $y, $scale);
  907.         pdf_close_image($this->_pdf, $image);
  908.         
  909.         parent::image($params);
  910.     }
  911.  
  912.     /**
  913.      * Output the result of the canvas
  914.      *
  915.      * @param array $param Parameter array
  916.      * @abstract
  917.      */
  918.     function show($param = false)
  919.     {
  920.         parent::show($param);
  921.         pdf_end_page($this->_pdf);
  922.         pdf_close($this->_pdf);
  923.  
  924.         $buf = pdf_get_buffer($this->_pdf);
  925.         $len = strlen($buf);
  926.  
  927.         header('Content-type: application/pdf');
  928.         header('Content-Length: ' . $len);
  929.         header('Content-Disposition: inline; filename=image_graph.pdf');
  930.         print $buf;
  931.  
  932.         pdf_delete($this->_pdf);
  933.     }
  934.  
  935.     /**
  936.      * Output the result of the canvas
  937.      *
  938.      * @param array $param Parameter array
  939.      * @abstract
  940.      */
  941.     function save($param = false)
  942.     {
  943.         parent::save($param);
  944.         pdf_end_page($this->_pdf);
  945.         pdf_close($this->_pdf);
  946.  
  947.         $buf = pdf_get_buffer($this->_pdf);
  948.         $len = strlen($buf);
  949.  
  950.         $fp = @fopen($param['filename'], 'wb');
  951.         if ($fp) {
  952.             fwrite($fp, $buf, strlen($buf));
  953.             fclose($fp);
  954.         }
  955.         pdf_delete($this->_pdf);
  956.     }
  957.     
  958.     /**
  959.      * Get a canvas specific HTML tag.
  960.      * 
  961.      * This method implicitly saves the canvas to the filename in the 
  962.      * filesystem path specified and parses it as URL specified by URL path
  963.      * 
  964.      * Parameter array:
  965.      * 'filename': string
  966.      * 'filepath': string Path to the file on the file system. Remember the final slash
  967.      * 'urlpath': string Path to the file available through an URL. Remember the final slash
  968.      * 'title': string The url title
  969.      */
  970.     function toHtml($params)
  971.     {
  972.         parent::toHtml($params);
  973.         return '<a href="' . $params['urlpath'] . $params['filename'] . '">' . $params['title'] . '</a>';        
  974.     }    
  975.  
  976.     /**
  977.      * Check which major version of PDFlib is installed
  978.      *
  979.      * @return int The mahor version number of PDFlib
  980.      * @access private
  981.      */
  982.     function _version()
  983.     {
  984.         $result = false;
  985.         $version = '';
  986.         if (function_exists('pdf_get_majorversion')) {
  987.             $version = pdf_get_majorversion();
  988.         } else if (function_exists('pdf_get_value')) {
  989.             $version = pdf_get_value($this->_pdf, 'major', 0);                
  990.         } else {
  991.             ob_start();
  992.             phpinfo(8);
  993.             $php_info = ob_get_contents();
  994.             ob_end_clean();
  995.  
  996.             if (ereg("<td[^>]*>PDFlib GmbH Version *<\/td><td[^>]*>([^<]*)<\/td>",
  997.                 $php_info, $result))
  998.             {
  999.                 $version = $result[1];
  1000.             }
  1001.         }               
  1002.         
  1003.         if (ereg('([0-9]{1,2})\.[0-9]{1,2}(\.[0-9]{1,2})?', trim($version), $result)) {
  1004.             return $result[1];
  1005.         } else {
  1006.             return $version;
  1007.         }
  1008.     }
  1009.  
  1010. }
  1011.  
  1012. ?>