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 / Graph / Element.php < prev    next >
Encoding:
PHP Script  |  2008-07-02  |  21.7 KB  |  763 lines

  1. <?php
  2.  
  3. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  4.  
  5. /**
  6.  * Image_Graph - Main class for the graph creation.
  7.  *
  8.  * PHP versions 4 and 5
  9.  *
  10.  * LICENSE: This library is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU Lesser General Public License as published by
  12.  * the Free Software Foundation; either version 2.1 of the License, or (at your
  13.  * option) any later version. This library is distributed in the hope that it
  14.  * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
  15.  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
  16.  * General Public License for more details. You should have received a copy of
  17.  * the GNU Lesser General Public License along with this library; if not, write
  18.  * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  19.  * 02111-1307 USA
  20.  *
  21.  * @category   Images
  22.  * @package    Image_Graph
  23.  * @author     Jesper Veggerby <pear.nosey@veggerby.dk>
  24.  * @copyright  Copyright (C) 2003, 2004 Jesper Veggerby Hansen
  25.  * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
  26.  * @version    CVS: $Id: Element.php,v 1.18 2006/02/28 22:48:07 nosey Exp $
  27.  * @link       http://pear.php.net/package/Image_Graph
  28.  */
  29.  
  30. /**
  31.  * Include file Common.php
  32.  */
  33. require_once 'Image/Graph/Common.php';
  34.  
  35. /**
  36.  * Representation of a element.
  37.  *
  38.  * The Image_Graph_Element can be drawn on the canvas, ie it has coordinates,
  39.  * {@link Image_Graph_Line}, {@link Image_Graph_Fill}, border and background -
  40.  * although not all of these may apply to all children.
  41.  *
  42.  * @category   Images
  43.  * @package    Image_Graph
  44.  * @author     Jesper Veggerby <pear.nosey@veggerby.dk>
  45.  * @copyright  Copyright (C) 2003, 2004 Jesper Veggerby Hansen
  46.  * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
  47.  * @version    Release: 0.7.2
  48.  * @link       http://pear.php.net/package/Image_Graph
  49.  * @abstract
  50.  */
  51. class Image_Graph_Element extends Image_Graph_Common
  52. {
  53.  
  54.     /**
  55.      * The leftmost pixel of the element on the canvas
  56.      * @var int
  57.      * @access private
  58.      */
  59.     var $_left = 0;
  60.  
  61.     /**
  62.      * The topmost pixel of the element on the canvas
  63.      * @var int
  64.      * @access private
  65.      */
  66.     var $_top = 0;
  67.  
  68.     /**
  69.      * The rightmost pixel of the element on the canvas
  70.      * @var int
  71.      * @access private
  72.      */
  73.     var $_right = 0;
  74.  
  75.     /**
  76.      * The bottommost pixel of the element on the canvas
  77.      * @var int
  78.      * @access private
  79.      */
  80.     var $_bottom = 0;
  81.  
  82.     /**
  83.      * Background of the element. Default: None
  84.      * @var FillStyle
  85.      * @access private
  86.      */
  87.     var $_background = null;
  88.  
  89.     /**
  90.      * Borderstyle of the element. Default: None
  91.      * @var LineStyle
  92.      * @access private
  93.      */
  94.     var $_borderStyle = null;
  95.  
  96.     /**
  97.      * Line style of the element. Default: None
  98.      * @var LineStyle
  99.      * @access private
  100.      */
  101.     var $_lineStyle = 'black';
  102.  
  103.     /**
  104.      * Fill style of the element. Default: None
  105.      * @var FillStyle
  106.      * @access private
  107.      */
  108.     var $_fillStyle = 'white';
  109.  
  110.     /**
  111.      * Font of the element. Default: Standard font - FONT
  112.      * @var Font
  113.      * @access private
  114.      * @see $IMAGE_GRAPH_FONT
  115.      */
  116.     var $_font = null;
  117.  
  118.     /**
  119.      * Font options
  120.      * @var array
  121.      * @access private
  122.      */
  123.     var $_fontOptions = array();
  124.  
  125.     /**
  126.      * Default font options
  127.      * 
  128.      * This option is included for performance reasons. The value is calculated
  129.      * before output and reused in default cases to avoid unnecessary recursive
  130.      * calls.
  131.      * 
  132.      * @var array
  133.      * @access private
  134.      */
  135.     var $_defaultFontOptions = false;
  136.  
  137.     /**
  138.      * Shadows options of the element
  139.      * @var mixed
  140.      * @access private
  141.      */
  142.     var $_shadow = false;
  143.  
  144.     /**
  145.      * The padding displayed on the element
  146.      * @var int
  147.      * @access private
  148.      */
  149.     var $_padding = array('left' => 0, 'top' => 0, 'right' => 0, 'bottom' => 0);
  150.  
  151.     /**
  152.      * Sets the background fill style of the element
  153.      *
  154.      * @param Image_Graph_Fill $background The background
  155.      * @see Image_Graph_Fill
  156.      */
  157.     function setBackground(& $background)
  158.     {
  159.         if (!is_a($background, 'Image_Graph_Fill')) {
  160.             $this->_error(
  161.                 'Could not set background for ' . get_class($this) . ': ' .
  162.                 get_class($background), array('background' => &$background)
  163.             );
  164.         } else {
  165.             $this->_background =& $background;
  166.             $this->add($background);
  167.         }
  168.     }
  169.  
  170.     /**
  171.      * Shows shadow on the element
  172.      */
  173.     function showShadow($color = 'black@0.2', $size = 5)
  174.     {
  175.         $this->_shadow = array(
  176.             'color' => $color,
  177.             'size' => $size
  178.         );
  179.     }
  180.  
  181.     /**
  182.      * Sets the background color of the element.
  183.      *
  184.      * See colors.txt in the docs/ folder for a list of available named colors.
  185.      *
  186.      * @param mixed $color The color
  187.      */
  188.     function setBackgroundColor($color)
  189.     {
  190.         $this->_background = $color;
  191.     }
  192.  
  193.      /**
  194.      * Gets the background fill style of the element
  195.      *
  196.      * @return int A GD fillstyle representing the background style
  197.      * @see Image_Graph_Fill
  198.      * @access private
  199.      */
  200.     function _getBackground()
  201.     {
  202.         if (is_object($this->_background)) {
  203.             $this->_canvas->setFill($this->_background->_getFillStyle());
  204.         } elseif ($this->_background != null) {
  205.             $this->_canvas->setFill($this->_background);
  206.         } else {
  207.             return false;
  208.         }
  209.         return true;
  210.     }
  211.  
  212.     /**
  213.      * Sets the border line style of the element
  214.      *
  215.      * @param Image_Graph_Line $borderStyle The line style of the border
  216.      * @see Image_Graph_Line
  217.      */
  218.     function setBorderStyle(& $borderStyle)
  219.     {
  220.         if (!is_a($borderStyle, 'Image_Graph_Line')) {
  221.             $this->_error(
  222.                 'Could not set border style for ' . get_class($this) . ': ' .
  223.                 get_class($borderStyle), array('borderstyle' => &$borderStyle)
  224.             );
  225.         } else {
  226.             $this->_borderStyle =& $borderStyle;
  227.             $this->add($borderStyle);
  228.         }
  229.     }
  230.  
  231.     /**
  232.      * Sets the border color of the element.
  233.      *
  234.      * See colors.txt in the docs/ folder for a list of available named colors.
  235.      * @param mixed $color The color
  236.      */
  237.     function setBorderColor($color)
  238.     {
  239.         $this->_borderStyle = $color;
  240.     }
  241.  
  242.     /**
  243.      * Gets the border line style of the element
  244.      *
  245.      * @return int A GD linestyle representing the borders line style
  246.      * @see Image_Graph_Line
  247.      * @access private
  248.      */
  249.     function _getBorderStyle()
  250.     {
  251.         if (is_object($this->_borderStyle)) {
  252.             $result = $this->_borderStyle->_getLineStyle();
  253.             $this->_canvas->setLineThickness($result['thickness']);
  254.             $this->_canvas->setLineColor($result['color']);
  255.         } elseif ($this->_borderStyle != null) {
  256.             $this->_canvas->setLineThickness(1);
  257.             $this->_canvas->setLineColor($this->_borderStyle);
  258.         } else {
  259.             return false;
  260.         }
  261.         return true;
  262.     }
  263.  
  264.     /**
  265.      * Sets the line style of the element
  266.      *
  267.      * @param Image_Graph_Line $lineStyle The line style of the element
  268.      * @see Image_Graph_Line
  269.      */
  270.     function setLineStyle(& $lineStyle)
  271.     {
  272.         if (!is_object($lineStyle)) {
  273.             $this->_error(
  274.                 'Could not set line style for ' . get_class($this) . ': ' .
  275.                 get_class($lineStyle), array('linestyle' => &$lineStyle)
  276.             );
  277.         } else {
  278.             $this->_lineStyle =& $lineStyle;
  279.             $this->add($lineStyle);
  280.         }
  281.     }
  282.  
  283.     /**
  284.      * Sets the line color of the element.
  285.      *
  286.      * See colors.txt in the docs/ folder for a list of available named colors.
  287.      *
  288.      * @param mixed $color The color
  289.      */
  290.     function setLineColor($color)
  291.     {
  292.         $this->_lineStyle = $color;
  293.     }
  294.  
  295.     /**
  296.      * Gets the line style of the element
  297.      *
  298.      * @return int A GD linestyle representing the line style
  299.      * @see Image_Graph_Line
  300.      * @access private
  301.      */
  302.     function _getLineStyle($ID = false)
  303.     {
  304.         if (is_object($this->_lineStyle)) {
  305.             $result = $this->_lineStyle->_getLineStyle($ID);
  306.             if (is_array($result)) {
  307.                 $this->_canvas->setLineThickness($result['thickness']);
  308.                 $this->_canvas->setLineColor($result['color']);
  309.             } else {
  310.                 $this->_canvas->setLineThickness(1);
  311.                 $this->_canvas->setLineColor($result);
  312.             }
  313.         } elseif ($this->_lineStyle != null) {
  314.             $this->_canvas->setLineThickness(1);
  315.             $this->_canvas->setLineColor($this->_lineStyle);
  316.         } else {
  317.             return false;
  318.         }
  319.         return true;
  320.     }
  321.  
  322.     /**
  323.      * Sets the fill style of the element
  324.      *
  325.      * @param Image_Graph_Fill $fillStyle The fill style of the element
  326.      * @see Image_Graph_Fill
  327.      */
  328.     function setFillStyle(& $fillStyle)
  329.     {
  330.         if (!is_a($fillStyle, 'Image_Graph_Fill')) {
  331.             $this->_error(
  332.                 'Could not set fill style for ' . get_class($this) . ': ' .
  333.                 get_class($fillStyle), array('fillstyle' => &$fillStyle)
  334.             );
  335.         } else {
  336.             $this->_fillStyle =& $fillStyle;
  337.             $this->add($fillStyle);
  338.         }
  339.     }
  340.  
  341.     /**
  342.      * Sets the fill color of the element.
  343.      *
  344.      * See colors.txt in the docs/ folder for a list of available named colors.
  345.      *
  346.      * @param mixed $color The color
  347.      */
  348.     function setFillColor($color)
  349.     {
  350.         $this->_fillStyle = $color;
  351.     }
  352.  
  353.  
  354.     /**
  355.      * Gets the fill style of the element
  356.      *
  357.      * @return int A GD filestyle representing the fill style
  358.      * @see Image_Graph_Fill
  359.      * @access private
  360.      */
  361.     function _getFillStyle($ID = false)
  362.     {
  363.         if (is_object($this->_fillStyle)) {
  364.             $this->_canvas->setFill($this->_fillStyle->_getFillStyle($ID));
  365.         } elseif ($this->_fillStyle != null) {
  366.             $this->_canvas->setFill($this->_fillStyle);
  367.         } else {
  368.             return false;
  369.         }
  370.         return true;
  371.     }
  372.  
  373.     /**
  374.      * Gets the font of the element.
  375.      *
  376.      * If not font has been set, the parent font is propagated through it's
  377.      * children.
  378.      *
  379.      * @return array An associated array used for canvas
  380.      * @access private
  381.      */
  382.     function _getFont($options = false)
  383.     {
  384.         if (($options === false) && ($this->_defaultFontOptions !== false)) {
  385.             return $this->_defaultFontOptions;
  386.         }
  387.         
  388.         if ($options === false) {
  389.             $saveDefault = true;
  390.         } else {
  391.             $saveDefault = false;
  392.         }
  393.         
  394.         if ($options === false) {
  395.             $options = $this->_fontOptions;
  396.         } else {
  397.             $options = array_merge($this->_fontOptions, $options);
  398.         }
  399.  
  400.         if ($this->_font == null) {
  401.             $result = $this->_parent->_getFont($options);
  402.         } else {
  403.             $result = $this->_font->_getFont($options);
  404.         }
  405.  
  406.         if ((isset($result['size'])) && (isset($result['size_rel']))) {
  407.             $result['size'] += $result['size_rel'];
  408.             unset($result['size_rel']);
  409.         }
  410.         
  411.         if ($saveDefault) {
  412.             $this->_defaultFontOptions = $result;
  413.         }
  414.         
  415.         return $result;
  416.     }
  417.  
  418.     /**
  419.      * Sets the font of the element
  420.      *
  421.      * @param Image_Graph_Font $font The font of the element
  422.      * @see Image_Graph_Font
  423.      */
  424.     function setFont(& $font)
  425.     {
  426.         if (!is_a($font, 'Image_Graph_Font')) {
  427.             $this->_error('Invalid font set on ' . get_class($this));
  428.         } else {
  429.             $this->_font =& $font;
  430.             $this->add($font);
  431.         }
  432.     }
  433.  
  434.     /**
  435.      * Sets the font size
  436.      *
  437.      * @param int $size The size of the font
  438.      */
  439.     function setFontSize($size)
  440.     {
  441.         $this->_fontOptions['size'] = $size;
  442.     }
  443.  
  444.     /**
  445.      * Sets the font angle
  446.      *
  447.      * @param int $angle The angle of the font
  448.      */
  449.     function setFontAngle($angle)
  450.     {
  451.         if ($angle == 'vertical') {
  452.             $this->_fontOptions['vertical'] = true;
  453.             $this->_fontOptions['angle'] = 90;
  454.         } else {
  455.             $this->_fontOptions['angle'] = $angle;
  456.         }
  457.     }
  458.  
  459.     /**
  460.      * Sets the font color
  461.      *
  462.      * @param mixed $color The color of the font
  463.      */
  464.     function setFontColor($color)
  465.     {
  466.         $this->_fontOptions['color'] = $color;
  467.     }
  468.  
  469.     /**
  470.      * Clip the canvas to the coordinates of the element
  471.      * 
  472.      * @param $enable bool Whether clipping should be enabled or disabled
  473.      * @access protected
  474.      */
  475.     function _clip($enable)
  476.     {
  477.         $this->_canvas->setClipping(
  478.             ($enable ?
  479.                 array(
  480.                     'x0' => min($this->_left, $this->_right),
  481.                     'y0' => min($this->_top, $this->_bottom),
  482.                     'x1' => max($this->_left, $this->_right),
  483.                     'y1' => max($this->_top, $this->_bottom)
  484.                 )
  485.                 : false
  486.             )
  487.         );
  488.     }
  489.  
  490.     /**
  491.      * Sets the coordinates of the element
  492.      *
  493.      * @param int $left The leftmost pixel of the element on the canvas
  494.      * @param int $top The topmost pixel of the element on the canvas
  495.      * @param int $right The rightmost pixel of the element on the canvas
  496.      * @param int $bottom The bottommost pixel of the element on the canvas
  497.      * @access private
  498.      */
  499.     function _setCoords($left, $top, $right, $bottom)
  500.     {
  501.         if ($left === false) {
  502.             $left = $this->_left;
  503.         }
  504.         
  505.         if ($top === false) {
  506.             $top = $this->_top;
  507.         }
  508.  
  509.         if ($right === false) {
  510.             $right = $this->_right;
  511.         }
  512.         
  513.         if ($bottom === false) {
  514.             $bottom = $this->_bottom;
  515.         }
  516.         
  517.         $this->_left = min($left, $right);
  518.         $this->_top = min($top, $bottom);
  519.         $this->_right = max($left, $right);
  520.         $this->_bottom = max($top, $bottom);        
  521.     }
  522.  
  523.     /**
  524.      * Moves the element
  525.      *
  526.      * @param int $deltaX Number of pixels to move the element to the right
  527.      *   (negative values move to the left)
  528.      * @param int $deltaY Number of pixels to move the element downwards
  529.      *   (negative values move upwards)
  530.      * @access private
  531.      */
  532.     function _move($deltaX, $deltaY)
  533.     {
  534.         $this->_left += $deltaX;
  535.         $this->_right += $deltaX;
  536.         $this->_top += $deltaY;
  537.         $this->_bottom += $deltaY;
  538.     }
  539.  
  540.     /**
  541.      * Sets the width of the element relative to the left side
  542.      *
  543.      * @param int $width Number of pixels the element should be in width
  544.      * @access private
  545.      */
  546.     function _setWidth($width)
  547.     {
  548.         $this->_right = $this->_left + $width;
  549.     }
  550.  
  551.     /**
  552.      * Sets the height of the element relative to the top
  553.      *
  554.      * @param int $width Number of pixels the element should be in height
  555.      * @access private
  556.      */
  557.     function _setHeight($height)
  558.     {
  559.         $this->_bottom = $this->_top + $height;
  560.     }
  561.  
  562.     /**
  563.      * Sets padding of the element
  564.      *
  565.      * @param mixed $padding Number of pixels the element should be padded with
  566.      * or an array of paddings (left, top, right and bottom as index)
  567.      */
  568.     function setPadding($padding)
  569.     {
  570.         if (is_array($padding)) {
  571.             $this->_padding = array();
  572.             $this->_padding['left'] = (isset($padding['left']) ? $padding['left'] : 0);         
  573.             $this->_padding['top'] = (isset($padding['top']) ? $padding['top'] : 0);         
  574.             $this->_padding['right'] = (isset($padding['right']) ? $padding['right'] : 0);         
  575.             $this->_padding['bottom'] = (isset($padding['bottom']) ? $padding['bottom'] : 0);         
  576.         }
  577.         else {
  578.             $this->_padding = array(
  579.                 'left' => $padding,
  580.                 'top' => $padding,
  581.                 'right' => $padding,
  582.                 'bottom' => $padding
  583.             );
  584.         }
  585.     }
  586.  
  587.     /**
  588.      * The width of the element on the canvas
  589.      *
  590.      * @return int Number of pixels representing the width of the element
  591.      */
  592.     function width()
  593.     {
  594.         return abs($this->_right - $this->_left) + 1;
  595.     }
  596.  
  597.     /**
  598.      * The height of the element on the canvas
  599.      *
  600.      * @return int Number of pixels representing the height of the element
  601.      */
  602.     function height()
  603.     {
  604.         return abs($this->_bottom - $this->_top) + 1;
  605.     }
  606.  
  607.     /**
  608.      * Left boundary of the background fill area
  609.      *
  610.      * @return int Leftmost position on the canvas
  611.      * @access private
  612.      */
  613.     function _fillLeft()
  614.     {
  615.         return $this->_left + $this->_padding['left'];
  616.     }
  617.  
  618.     /**
  619.      * Top boundary of the background fill area
  620.      *
  621.      * @return int Topmost position on the canvas
  622.      * @access private
  623.      */
  624.     function _fillTop()
  625.     {
  626.         return $this->_top + $this->_padding['top'];
  627.     }
  628.  
  629.     /**
  630.      * Right boundary of the background fill area
  631.      *
  632.      * @return int Rightmost position on the canvas
  633.      * @access private
  634.      */
  635.     function _fillRight()
  636.     {
  637.         return $this->_right - $this->_padding['right'];
  638.     }
  639.  
  640.     /**
  641.      * Bottom boundary of the background fill area
  642.      *
  643.      * @return int Bottommost position on the canvas
  644.      * @access private
  645.      */
  646.     function _fillBottom()
  647.     {
  648.         return $this->_bottom - $this->_padding['bottom'];
  649.     }
  650.  
  651.     /**
  652.      * Returns the filling width of the element on the canvas
  653.      *
  654.      * @return int Filling width
  655.      * @access private
  656.      */
  657.     function _fillWidth()
  658.     {
  659.         return $this->_fillRight() - $this->_fillLeft() + 1;
  660.     }
  661.  
  662.     /**
  663.      * Returns the filling height of the element on the canvas
  664.      *
  665.      * @return int Filling height
  666.      * @access private
  667.      */
  668.     function _fillHeight()
  669.     {
  670.         return $this->_fillBottom() - $this->_fillTop() + 1;
  671.     }
  672.  
  673.     /**
  674.      * Draws a shadow 'around' the element
  675.      * 
  676.      * Not implemented yet.
  677.      *
  678.      * @access private
  679.      */
  680.     function _displayShadow()
  681.     {        
  682.         if (is_array($this->_shadow)) {
  683.             $this->_canvas->startGroup(get_class($this) . '_shadow');
  684.             $this->_canvas->setFillColor($this->_shadow['color']);        
  685.             $this->_canvas->addVertex(array('x' => $this->_right + 1, 'y' => $this->_top + $this->_shadow['size']));
  686.             $this->_canvas->addVertex(array('x' => $this->_right + $this->_shadow['size'], 'y' => $this->_top + $this->_shadow['size']));
  687.             $this->_canvas->addVertex(array('x' => $this->_right + $this->_shadow['size'], 'y' => $this->_bottom + $this->_shadow['size']));
  688.             $this->_canvas->addVertex(array('x' => $this->_left + $this->_shadow['size'], 'y' => $this->_bottom + $this->_shadow['size']));
  689.             $this->_canvas->addVertex(array('x' => $this->_left + $this->_shadow['size'], 'y' => $this->_bottom + 1));
  690.             $this->_canvas->addVertex(array('x' => $this->_right + 1, 'y' => $this->_bottom + 1));
  691.             $this->_canvas->polygon(array('connect' => true));            
  692.             $this->_canvas->endGroup();
  693.         }
  694.     }
  695.  
  696.     /**
  697.      * Writes text to the canvas.
  698.      *
  699.      * @param int $x The x position relative to alignment
  700.      * @param int $y The y position relative to alignment
  701.      * @param string $text The text
  702.      * @param int $alignmen The text alignment (both vertically and horizontally)
  703.      */
  704.     function write($x, $y, $text, $alignment = false, $font = false)
  705.     {
  706.         if (($font === false) && ($this->_defaultFontOptions !== false)) {
  707.             $font = $this->_defaultFontOptions;
  708.         } else {
  709.             $font = $this->_getFont($font);
  710.         }
  711.  
  712.         if ($alignment === false) {
  713.             $alignment = IMAGE_GRAPH_ALIGN_LEFT + IMAGE_GRAPH_ALIGN_TOP;
  714.         }
  715.         
  716.         $align = array();      
  717.         
  718.         if (($alignment & IMAGE_GRAPH_ALIGN_TOP) != 0) {
  719.             $align['vertical'] = 'top';
  720.         } else if (($alignment & IMAGE_GRAPH_ALIGN_BOTTOM) != 0) {       
  721.             $align['vertical'] = 'bottom';
  722.         } else {
  723.             $align['vertical'] = 'center';
  724.         }
  725.  
  726.         if (($alignment & IMAGE_GRAPH_ALIGN_LEFT) != 0) {
  727.             $align['horizontal'] = 'left';
  728.         } else if (($alignment & IMAGE_GRAPH_ALIGN_RIGHT) != 0) {       
  729.             $align['horizontal'] = 'right';
  730.         } else {
  731.             $align['horizontal'] = 'center';
  732.         }
  733.  
  734.         $this->_canvas->setFont($font);
  735.         $this->_canvas->addText(array('x' => $x, 'y' => $y, 'text' => $text, 'alignment' => $align));
  736.     }
  737.  
  738.     /**
  739.      * Output the element to the canvas
  740.      *
  741.      * @return bool Was the output 'good' (true) or 'bad' (false).
  742.      * @see Image_Graph_Common
  743.      * @access private
  744.      */
  745.     function _done()
  746.     {
  747.         $background = $this->_getBackground();
  748.         $border = $this->_getBorderStyle();
  749.         if (($background) || ($border)) {
  750.             $this->_canvas->rectangle(array('x0' => $this->_left, 'y0' => $this->_top, 'x1' => $this->_right, 'y1' => $this->_bottom));
  751.         }
  752.  
  753.         $result = parent::_done();
  754.         
  755.         if ($this->_shadow !== false) {
  756.             $this->_displayShadow();
  757.         }
  758.  
  759.         return $result;
  760.     }
  761.  
  762. }
  763. ?>