home *** CD-ROM | disk | FTP | other *** search
/ Enter 2004 June / ENTER.ISO / files / xampp-win32-1.4.5-installer.exe / xampp / Image.php < prev    next >
Encoding:
PHP Script  |  2004-03-24  |  11.3 KB  |  426 lines

  1. <?php
  2. //
  3. // +---------------------------------------------------------------------------+
  4. // | PEAR :: XML :: Transformer :: Image Namespace Handler                     |
  5. // +---------------------------------------------------------------------------+
  6. // | Copyright (c) 2002-2004 Sebastian Bergmann <sb@sebastian-bergmann.de> and |
  7. // |                         Kristian K÷hntopp <kris@koehntopp.de>.            |
  8. // +---------------------------------------------------------------------------+
  9. // | This source file is subject to version 3.00 of the PHP License,           |
  10. // | that is available at http://www.php.net/license/3_0.txt.                  |
  11. // | If you did not receive a copy of the PHP license and are unable to        |
  12. // | obtain it through the world-wide-web, please send a note to               |
  13. // | license@php.net so we can mail you a copy immediately.                    |
  14. // +---------------------------------------------------------------------------+
  15. //
  16. // $Id: Image.php,v 1.19 2004/01/01 10:31:55 sebastian Exp $
  17. //
  18.  
  19. require_once 'XML/Transformer/Namespace.php';
  20. require_once 'XML/Util.php';
  21.  
  22. define('PEAR_XML_TRANSFORMER_IMAGE_FONTPATH', '/usr/X11R6/lib/X11/fonts/truetype');
  23. define('PEAR_XML_TRANSFORMER_IMAGE_cacheDir', '/cache/gtext');
  24.  
  25. /**
  26. * Handler for the Image Namespace.
  27. *
  28. * Example:
  29. *
  30. *   <?php
  31. *   require_once 'XML/Transformer_OutputBuffer.php';
  32. *   require_once 'XML/Transformer/Namespace/Image.php';
  33. *
  34. *   $t = new XML_Transformer_OutputBuffer;
  35. *   $t->overloadNamespace('img', new XML_Transformer_Namespace_Image);
  36. *   $t->start();
  37. *   ?>
  38. *   <!-- Height and Width attributes are autogenerated -->
  39. *   <img:img src="somepng.png" alt="A sample image" />
  40. *
  41. *   <!-- Set default for all subsequent <img:gtext /> -->
  42. *   <img:gtextdefault bgcolor="888888" fgcolor="#000000"
  43. *                     font="arial.ttf" fontsize="33"
  44. *                     border="2" spacing="2"
  45. *                     split="" cacheable="yes" />
  46. *
  47. *   <!-- Render Text as PNG image -->
  48. *   <img:gtext>0123456789 Σ÷ⁿ▀─╓▄</img:gtext><br />
  49. *
  50. * Output:
  51. *
  52. *   <img alt="A sample image" height="33" src="somepng.png" width="133" />
  53. *
  54. *   <span><img alt="0123456789 Σ÷ⁿ▀─╓▄" height="41" width="338"
  55. *              src="/cache/gtext/8b91aee0403c5cdccc1dd96bd4f49fbb.png" /></span>
  56. *
  57. * @author  Sebastian Bergmann <sb@sebastian-bergmann.de>
  58. * @author  Kristian K÷hntopp <kris@koehntopp.de>
  59. * @version $Revision: 1.19 $
  60. * @access  public
  61. */
  62. class XML_Transformer_Namespace_Image extends XML_Transformer_Namespace {
  63.     // {{{ Members
  64.  
  65.     /**
  66.     * @var    boolean
  67.     * @access public
  68.     */
  69.     var $defaultNamespacePrefix = 'img';
  70.  
  71.     /**
  72.     * @var    array
  73.     * @access private
  74.     */
  75.     var $_imgAttributes          = array();
  76.  
  77.     /**
  78.     * @var    array
  79.     * @access private
  80.     */
  81.     var $_gtextAttributes        = array();
  82.  
  83.     /**
  84.     * @var    array
  85.     * @access private
  86.     */
  87.     var $_gtextDefaultAttributes = array();
  88.  
  89.     // }}}
  90.     // {{{ function start_img($attributes)
  91.  
  92.     /**
  93.     * @param  array
  94.     * @return string
  95.     * @access public
  96.     */
  97.     function start_img($attributes) {
  98.         $this->_imgAttributes = $attributes;
  99.  
  100.         return '';
  101.     }
  102.  
  103.     // }}}
  104.     // {{{ function end_img($cdata)
  105.  
  106.     /**
  107.     * @param  string
  108.     * @return string
  109.     * @access public
  110.     */
  111.     function end_img($cdata) {
  112.         $src = $this->_truePath($this->_imgAttributes['src']);
  113.  
  114.         list($w, $h, $t, $whs) = getimagesize($src);
  115.  
  116.         $this->_imgAttributes['height'] = $h;
  117.         $this->_imgAttributes['width']  = $w;
  118.  
  119.         return sprintf(
  120.           '<img %s />',
  121.           XML_Util::attributesToString($this->_imgAttributes)
  122.         );
  123.     }
  124.  
  125.     // }}}
  126.     // {{{ start_gtext($attributes)
  127.  
  128.     /**
  129.     * @param  array
  130.     * @return string
  131.     * @access public
  132.     */
  133.     function start_gtext($attributes) {
  134.         foreach ($this->_gtextDefaultAttributes as $k => $v) {
  135.             if (! isset($attributes[$k])) {
  136.                 $attributes[$k] = $v;
  137.             }
  138.         }
  139.  
  140.         if (!file_exists($attributes['font'])) {
  141.             $attributes['font'] = PEAR_XML_TRANSFORMER_IMAGE_FONTPATH . '/' . $attributes['font'];
  142.         }
  143.   
  144.         $this->_gtextAttributes = $attributes;
  145.   
  146.         return '';
  147.     }
  148.  
  149.     // }}}
  150.     // {{{ function end_gtext($cdata)
  151.  
  152.     /**
  153.     * @param  string
  154.     * @return string
  155.     * @access public
  156.     */
  157.     function end_gtext($cdata) {
  158.     if(!is_file($this->_gtextAttributes['font']))
  159.           return '<span>font \"' .
  160.             $this->_gtextAttributes['font'] .
  161.             '" not found</span>';
  162.  
  163.         switch ($this->_gtextAttributes['split']) {
  164.             case 'word': {
  165.                 $text = preg_split('/\s+/', $cdata);
  166.  
  167.                 foreach ($text as $index => $word) {
  168.                     if ($index) {
  169.                         $text[$index] = " $word";
  170.                     }
  171.                 }
  172.             }
  173.             break;
  174.  
  175.             case 'char': {
  176.                 $text = preg_split('//', $cdata);
  177.  
  178.                 foreach ($text as $index => $word) {
  179.                     if ($word == ' ' || $word == '') {
  180.                         $text[$index] = chr(160);
  181.                     }
  182.                 }
  183.             }
  184.             break;
  185.  
  186.             default: {
  187.                 $text = array(0 => $cdata);
  188.             }
  189.         }
  190.  
  191.         $r = '';
  192.  
  193.         foreach ($text as $index => $word) {
  194.             $baseline = $this->_baseline(
  195.               $this->_gtextAttributes['font'],
  196.               $this->_gtextAttributes['fontsize']
  197.             );
  198.  
  199.             $src = $this->_createImage($word,$baseline);
  200.             $alt = $this->_createAlt($word);
  201.  
  202.             $r .= sprintf(
  203.               '<%simg src="%s" alt="%s" />',
  204.               ($this->_prefix[0] != '&MAIN') ? $this->_prefix[0] . ':' : '',
  205.               $src,
  206.               addslashes($alt)
  207.             );
  208.         }
  209.  
  210.         return "<span>$r</span>";
  211.     }
  212.  
  213.     // }}}
  214.     // {{{ function start_gtextdefault($attributes)
  215.  
  216.     /**
  217.     * @param  array
  218.     * @return string
  219.     * @access public
  220.     */
  221.     function start_gtextdefault($attributes) {
  222.         $this->_gtextDefaultAttributes = $attributes;
  223.  
  224.         return '';
  225.     }
  226.  
  227.     // }}}
  228.     // {{{ function end_gtextdefault()
  229.  
  230.     /**
  231.     * @param  string
  232.     * @return string
  233.     * @access public
  234.     */
  235.     function end_gtextdefault() {
  236.         return '';
  237.     }
  238.  
  239.     // }}}
  240.     // {{{ function _baseline($font, $size)
  241.  
  242.     /**
  243.     * @param  string
  244.     * @param  integer
  245.     * @return ImageTTFBBox
  246.     * @access private
  247.     */
  248.     function _baseline($font, $size) {
  249.         $r = ImageTTFBBox(
  250.           $size,
  251.           0,
  252.           $font,
  253.           'Ggº_|╓─▄▀QqPp'
  254.         );
  255.  
  256.         return $r[1];
  257.     }
  258.  
  259.     // }}}
  260.     // {{{ function _colorString($color)
  261.  
  262.     /**
  263.     * @param  integer
  264.     * @return array
  265.     * @access private
  266.     */
  267.     function _colorString($color) {
  268.         if (substr($color, 0, 1) == '#') {
  269.             $color = substr($color, 1);
  270.         }
  271.  
  272.         $r = hexdec(substr($color, 0, 2));
  273.         $g = hexdec(substr($color, 2, 2));
  274.         $b = hexdec(substr($color, 4, 2));
  275.  
  276.         return array($r, $g, $b);
  277.     }
  278.  
  279.     // }}}
  280.     // {{{ function _createAlt($word)
  281.  
  282.     /**
  283.     * @param  string
  284.     * @return string
  285.     * @access private
  286.     */
  287.     function _createAlt($word) {
  288.         if (isset($this->_gtextAttributes['alt'])) {
  289.             return $this->_gtextAttributes['alt'];
  290.         }
  291.  
  292.         return strip_tags($word);
  293.     }
  294.  
  295.     // }}}
  296.     // {{{ function _createImage($word, $baseline)
  297.  
  298.     /**
  299.     * @param  string
  300.     * @param  integer
  301.     * @return string
  302.     * @access private
  303.     */
  304.     function _createImage($word, $baseline) {
  305.         $font         = isset($this->_gtextAttributes['font'])         ? $this->_gtextAttributes['font']         : 'arial.ttf';
  306.         $fh           = isset($this->_gtextAttributes['fontsize'])     ? $this->_gtextAttributes['fontsize']     : 12;
  307.         $bgcolor      = isset($this->_gtextAttributes['bgcolor'])      ? $this->_gtextAttributes['bgcolor']      : '#ffffff';
  308.         $fgcolor      = isset($this->_gtextAttributes['fgcolor'])      ? $this->_gtextAttributes['fgcolor']      : '#ffffff';
  309.  
  310.         $antialias    = isset($this->_gtextAttributes['antialias'])    ? $this->_gtextAttributes['antialias']    : 'yes';
  311.         $transparency = isset($this->_gtextAttributes['transparency']) ? $this->_gtextAttributes['transparency'] : 'yes';
  312.         $cacheable    = isset($this->_gtextAttributes['cacheable'])    ? $this->_gtextAttributes['cacheable']    : 'yes';
  313.  
  314.         $spacing      = isset($this->_gtextAttributes['spacing'])      ? $this->_gtextAttributes['spacing']      : 2;
  315.         $border       = isset($this->_gtextAttributes['border'])       ? $this->_gtextAttributes['border']       : 0;
  316.         $bordercolor  = isset($this->_gtextAttributes['bordercolor'])  ? $this->_gtextAttributes['bordercolor']  : '#ff0000';
  317.  
  318.         /* The cache name is derived from all attributes and cdata.
  319.          * This is very conserative and may create to many cachefiles,
  320.          * but better to err on the safe side.
  321.          */
  322.         $cachefile = md5(XML_Util::attributesToString($this->_gtextAttributes) . ':' . $word) . '.png';
  323.         $cacheDir  = $_SERVER['DOCUMENT_ROOT']
  324.                    . PEAR_XML_TRANSFORMER_IMAGE_cacheDir;
  325.         $cacheName = "$cacheDir/$cachefile";
  326.         $cacheURL  = PEAR_XML_TRANSFORMER_IMAGE_cacheDir. "/$cachefile";
  327.  
  328.         if (!is_dir($cacheDir)) {
  329.             mkdir($cacheDir, 01777);
  330.         }
  331.  
  332.         /* Don't do the same work twice. */
  333.         if (file_exists($cacheName) && $cacheable != 'no') {
  334.             return $cacheURL;
  335.         }
  336.  
  337.         $r = ImageTTFBBox(
  338.           $fh,
  339.           0,
  340.           $font,
  341.           $word
  342.         );
  343.  
  344.         $w = max(1/10*$fh, abs($r[2] - $r[0]));
  345.         $h = max(1, abs($r[7] - $r[1]));
  346.         $x = $r[0];
  347.         $y = $baseline;
  348.  
  349.         $www = $w  + 2*($spacing+$border);
  350.         $hhh = $fh + 2*($spacing+$border);
  351.  
  352.         $im = ImageCreate($www, $hhh);
  353.  
  354.         list($r, $g, $b) = $this->_colorString($bgcolor);
  355.         $bg = ImageColorAllocate($im, $r, $g, $b);
  356.  
  357.         if ($transparency != 'no') {
  358.             ImageColorTransparent($im, $bg);
  359.         }
  360.  
  361.         list($r, $g, $b) = $this->_colorString($fgcolor);
  362.         $fg = ImageColorAllocate($im, $r, $g, $b);
  363.  
  364.         if ($antialias == 'no') {
  365.             $fg = -$fg;
  366.         }
  367.  
  368.         list($r, $g, $b) = $this->_colorString($bordercolor);
  369.         $bo = ImageColorAllocate($im, $r, $g, $b);
  370.  
  371.         ImageFilledRectangle($im, 0, 0, $www, $hhh, $bg);
  372.  
  373.         if ($border > 0) {
  374.             for ($i=$border; $i>=0; $i--) {
  375.                 $x1 = $y1 = $i;
  376.                 $x2 = $www-$i-1;
  377.                 $y2 = $hhh-$i-1;
  378.  
  379.                 ImageRectangle($im, $x1, $y1, $x2, $y2, $bo);
  380.             }
  381.         }
  382.  
  383.         ImageTTFText(
  384.           $im,
  385.           $fh,
  386.           0,
  387.           -$x+$spacing+$border,
  388.           $hhh-(2+$y+$spacing+$border),
  389.           $fg,
  390.           $font,
  391.           $word
  392.         );
  393.  
  394.         ImagePNG($im, $cacheName);
  395.         ImageDestroy($im);
  396.  
  397.         return $cacheURL;
  398.     }
  399.  
  400.     // }}}
  401.     // {{{ function _truePath($path)
  402.  
  403.     /**
  404.     * @param  string
  405.     * @return string
  406.     * @access private
  407.     */
  408.     function _truePath($path) {
  409.         if (php_sapi_name() == 'apache') {
  410.             $uri = apache_lookup_uri($path);
  411.  
  412.             return $uri->filename;
  413.         } else {
  414.             return $_SERVER['DOCUMENT_ROOT'] . '/' . $path;
  415.         }
  416.     }
  417.  
  418.     // }}}
  419. }
  420.  
  421. /*
  422.  * vim600:  et sw=2 ts=2 fdm=marker
  423.  * vim<600: et sw=2 ts=2
  424.  */
  425. ?>
  426.