Source for file SvgDocumentRenderer.php

Documentation is available at SvgDocumentRenderer.php

  1. <?php
  2. /**
  3.  * $Source: /cvsroot/svggrapher/svggrapher/mains/SvgDocumentRenderer.php,v $
  4.  *
  5.  * SvgGrapher graph pane
  6.  *
  7.  * @version CVS: $Id: SvgDocumentRenderer.php,v 1.10 2007/10/23 09:22:53 geelweb Exp $
  8.  * @filesource
  9.  * @author Guillaume Luchet. <guillaume@geelweb.org>
  10.  * @copyright Copyright (c) 2007, Guillaume Luchet.
  11.  * @license http://opensource.org/licenses/bsd-license.php BSD License
  12.  * @package SvgGrapher
  13.  */
  14.  
  15. /**#@+
  16.  * include svg elements 
  17.  */
  18. require_once SVGGRAPHER_ELEMENTS_PATH . '/GElement.php';
  19. require_once SVGGRAPHER_ELEMENTS_PATH . '/TextElement.php';
  20. require_once SVGGRAPHER_ELEMENTS_PATH . '/LineElement.php';
  21. require_once SVGGRAPHER_ELEMENTS_PATH . '/RectElement.php';
  22. require_once SVGGRAPHER_ELEMENTS_PATH . '/AElement.php';
  23. require_once SVGGRAPHER_ELEMENTS_PATH . '/ImageElement.php';
  24. /**#@-*/
  25.  
  26. /**
  27.  * SvgDocumentRenderer
  28.  * 
  29.  * @version $Id: SvgDocumentRenderer.php,v 1.10 2007/10/23 09:22:53 geelweb Exp $
  30.  * @copyright Copyright (c) 2007, Guillaume Luchet
  31.  * @author guillaume luchet <guillaume@geelweb.org>
  32.  * @license http://opensource.org/licenses/bsd-license.php BSD License
  33.  * @package SvgGrapher
  34.  */
  35. {
  36.     // SvgDocumentRenderer::render() {{{
  37.  
  38.     /**
  39.      * render
  40.      *
  41.      * Render the svg document.
  42.      * 
  43.      * @param mixed $forceBackground if true, the elements will be added on the
  44.      *  back of the existing elements.
  45.      * @static
  46.      * @access public
  47.      * @return void 
  48.      */
  49.     public static function render($forceBackground=true) 
  50.     {
  51.         $svgGrapher = SvgGrapher::singleton();
  52.         /*$forceBackground = $forceBackground && $svgGrapher->svgGraphPane->haveChild();
  53.         if($forceBackground) {
  54.             $tmp = $svgGrapher->svgGraphPane->removeChildren();
  55.         }*/
  56.         SvgDocumentRenderer::renderTitle();
  57.         SvgDocumentRenderer::renderLabelX();
  58.         SvgDocumentRenderer::renderLabelY();
  59.         SvgDocumentRenderer::renderGridX();
  60.         SvgDocumentRenderer::renderGridY();
  61.         SvgDocumentRenderer::renderStepX();
  62.         SvgDocumentRenderer::renderStepY();
  63.         SvgDocumentRenderer::renderTagsX();
  64.         SvgDocumentRenderer::renderTagsY();
  65.         SvgDocumentRenderer::renderLegend();
  66.         /*if($forceBackground) {
  67.             $svgGrapher->svgGraphPane->appendChildren($tmp);
  68.         }*/
  69.         SvgDocumentRenderer::renderCurves();
  70.         SvgDocumentRenderer::renderLimits();
  71.     }
  72.  
  73.     // }}}
  74.     // SvgDocumentRenderer::renderTitle() {{{
  75.  
  76.     /**
  77.      * renderTitle
  78.      *
  79.      * Render the graph title.
  80.      *
  81.      * @static
  82.      * @access public
  83.      * @return void 
  84.      */
  85.     public static function renderTitle() 
  86.     {
  87.         $svgGrapher = SvgGrapher::singleton();
  88.         $display = $svgGrapher->display;
  89.         if(empty($display['title']) || !$display['title']) {
  90.             return false;
  91.         }
  92.         $text = new TextElement($svgGrapher->title, array(
  93.             'x' => $svgGrapher->boxTitle->padding['left'], 
  94.             'y' => $svgGrapher->boxTitle->padding['top'],
  95.             'style' => TITLE_STYLE));
  96.         if($svgGrapher->boxTitle->x > 0 || $svgGrapher->boxTitle->y > 0) {
  97.             $translate = sprintf('translate(%s,%s)', $svgGrapher->boxTitle->x, $svgGrapher->boxTitle->y);
  98.             $text->setAttribute('transform',$translate);
  99.         }
  100.         $svgGrapher->svgTitles->appendChild($text);
  101.     }
  102.  
  103.     // }}}
  104.     // SvgDocumentRenderer::renderGridX() {{{
  105.  
  106.     /**
  107.      * renderGridX
  108.      *
  109.      * Render the abscisses lines of the grid
  110.      * 
  111.      * @static
  112.      * @access public
  113.      * @return void 
  114.      */
  115.     public static function renderGridX() 
  116.     {
  117.         $svgGrapher = SvgGrapher::singleton();
  118.         $display = $svgGrapher->display;
  119.         if(empty($display['gridX']) || !$display['gridX']) {
  120.             return false;
  121.         }
  122.         $x = 0;
  123.         $group = new GElement();
  124.         $group->setAttribute('style', GRID_LINES_X_STYLE);
  125.  
  126.         $top = 0;
  127.         $bottom = $svgGrapher->boxGraphPane->height - 1;
  128.  
  129.         foreach ($svgGrapher->tagsX as $i => $u) {
  130.             $x = $svgGrapher->gridLineXDelta * ($i +  $svgGrapher->plotOffsetX);
  131.             $group->appendChild(new LineElement(array(
  132.                 'x1' => $x, 'y1' => $top, 'x2' => $x, 'y2' => $bottom)));
  133.         }
  134.  
  135.         $svgGrapher->svgGraphPane->appendChild($group);
  136.     }
  137.  
  138.     // }}}
  139.     // SvgDocumentRenderer::renderGridY() {{{
  140.  
  141.     /**
  142.      * renderGridY
  143.      *
  144.      * Render the ordinates lines of the grid
  145.      * 
  146.      * @static
  147.      * @access public
  148.      * @return void 
  149.      */
  150.     public static function renderGridY() 
  151.     {
  152.         $svgGrapher = SvgGrapher::singleton();
  153.         $display = $svgGrapher->display;
  154.         if(empty($display['gridX']) || !$display['gridX']) {
  155.             return false;
  156.         }
  157.         
  158.         $group = new GElement();
  159.         $group->setAttribute('style', GRID_LINES_Y_STYLE);
  160.  
  161.         $left = 0;
  162.         $right = $svgGrapher->boxGraphPane->width - 1;
  163.  
  164.         for($i = 0; $i < $svgGrapher->gridLineY; $i++) {
  165.             $v = $svgGrapher->gridLineYDelta * ($i + $svgGrapher->plotOffsetY);
  166.             $group->appendChild(new LineElement(array(
  167.                 'x1' => $left, 'y1' => $v, 'x2' => $right, 'y2' => $v)));
  168.         }
  169.         // display 0 if in range
  170.         $range = $svgGrapher->range;
  171.         if(($range['min'] < 0 && $range['max'] > 0) || ($range['min'] > 0 && $range['max'] < 0)) {
  172.             $v = $svgGrapher->boxGraphPane->height - ($svgGrapher->factorY * (0 - $range['min']));
  173.             $group->appendChild(new LineElement(array(
  174.                 'x1' => $left, 'y1' => $v, 'x2' => $right, 'y2' => $v)));
  175.         }
  176.         $svgGrapher->svgGraphPane->appendChild($group);
  177.     }
  178.  
  179.     // }}}
  180.     // SvgDocumentRenderer::renderStepX() {{{
  181.  
  182.     /**
  183.      * renderStepX
  184.      * 
  185.      * @static
  186.      * @access public
  187.      * @return void 
  188.      */
  189.     public static function renderStepX() 
  190.     {
  191.         $svgGrapher = SvgGrapher::singleton();
  192.         $display = $svgGrapher->display;
  193.         if(empty($display['stepX']) || !$display['stepX']) {
  194.             return false;
  195.         }
  196.         $x = 0;
  197.         $group = new GElement();
  198.         $group->setAttribute('style', STEP_X_STYLE);
  199.  
  200.         $top = $svgGrapher->boxGraphPane->height - 3;
  201.         $bottom = $svgGrapher->boxGraphPane->height + 3;
  202.  
  203.         foreach ($svgGrapher->tagsX as $i => $u) {
  204.             $x = $svgGrapher->gridLineXDelta * ($i +  $svgGrapher->plotOffsetX);
  205.             $group->appendChild(new LineElement(array(
  206.                 'x1' => $x, 'y1' => $top, 'x2' => $x, 'y2' => $bottom)));
  207.         }
  208.         $svgGrapher->svgGraphPane->appendChild($group);
  209.     }
  210.  
  211.     // }}}
  212.     // SvgDocumentRenderer::renderStepY() {{{
  213.  
  214.     /**
  215.      * renderStepY
  216.      * 
  217.      * @static
  218.      * @access public
  219.      * @return void 
  220.      */
  221.     public static function renderStepY() 
  222.     {
  223.         $svgGrapher = SvgGrapher::singleton();
  224.         $display = $svgGrapher->display;
  225.         if(empty($display['stepY']) || !$display['stepY']) {
  226.             return false;
  227.         }
  228.         $group = new GElement();
  229.         $group->setAttribute('style', STEP_Y_STYLE);
  230.  
  231.         $minorStep = NULL;
  232.         $left = -3;
  233.         $right = 3;
  234.  
  235.         for($i = 0; $i < $svgGrapher->gridLineY; $i++) {
  236.             $v = $svgGrapher->gridLineYDelta * ($i + $svgGrapher->plotOffsetY);
  237.             $group->appendChild(new LineElement(
  238.                 array('x1' => $left, 'y1' => $v, 'x2' => $right, 'y2' => $v)));
  239.  
  240.             if(isset($display['minorStepY']) && $display['minorStepY']) {
  241.                 if($i < $svgGrapher->gridLineY - 1 ) {
  242.                     for($mstep = 0; $mstep < $svgGrapher->minorStepY; $mstep++) {
  243.                         $m = $v + $mstep * $svgGrapher->minorStepYDelta;
  244.                         $minorStep = new LineElement(array(
  245.                             'x1' => $left, 'y1' => $m, 'x2' => 0, 'y2' => $m));
  246.                         $minorStep->setAttribute('style', MINOR_STEP_Y_STYLE);
  247.                         $group->appendChild($minorStep);
  248.                     }
  249.                 }
  250.             }
  251.         }
  252.  
  253.         $svgGrapher->svgGraphPane->appendChild($group);
  254.     }
  255.  
  256.     // }}}
  257.     // SvgDocumentRenderer::renderTagsX() {{{
  258.  
  259.     /**
  260.      * renderTagsX
  261.      *
  262.      * Render the abscisses tags
  263.      * 
  264.      * @static
  265.      * @access public
  266.      * @return void 
  267.      */
  268.     public static function renderTagsX() 
  269.     {
  270.         $svgGrapher = SvgGrapher::singleton();
  271.         $display = $svgGrapher->display;
  272.         if(empty($display['tagsX']) || !$display['tagsX']) {
  273.             return false;
  274.         }
  275.         $freqCnt = 0;
  276.         $group = new GElement(array('id'=>'tagsX', 'style'=>TAGS_X_STYLE));
  277.  
  278.         $y = $svgGrapher->boxTagsX->y;
  279.  
  280.         foreach ($svgGrapher->tagsX as $i => $text) {
  281.             if(isset($svgGrapher->rendererCallBacks['tagsX'])) {
  282.                 $text = call_user_func($svgGrapher->rendererCallBacks['tagsX'], $text);
  283.             }
  284.             $x = $svgGrapher->gridLineXDelta * ($i + $svgGrapher->plotOffsetX) + $svgGrapher->boxGraphPane->x;
  285.  
  286.             if($i > 0) {
  287.                 $freqCnt++;
  288.                 if($freqCnt == $svgGrapher->tagXGapFrequency) {
  289.                     $freqCnt = 0;
  290.                 } else { 
  291.                     continue; 
  292.                 }
  293.             }
  294.  
  295.             if ($svgGrapher->tagXRotation == 0) {
  296.                 $text = new TextElement($text, 
  297.                     array('x' => $x, 'y' => $y, 'dy' => '1em', 
  298.                     'style' => 'text-anchor: middle;'));
  299.                 $group->appendChild($text);
  300.             } else if($svgGrapher->tagXRotation > 0) {
  301.                 $text = new TextElement($text, array(
  302.                     'x' => $x, 'y' => $y, 'dy' => '1em', 
  303.                     'style' => 'text-anchor: start;'));
  304.                 $text->setAttribute('transform',"rotate({$svgGrapher->tagXRotation} $x $y)");
  305.                 $group->appendChild($text);
  306.             } else {
  307.                 $text = new TextElement($text, array(
  308.                     'x'=>$x, 'y'=>$y, 'dy'=>'1em', 
  309.                     'style'=>'text-anchor: end;'));
  310.                 $text->setAttribute('transform',"rotate({$svgGrapher->tagXRotation} $x $y)");
  311.                 $group->appendChild($text);
  312.             }
  313.         }
  314.  
  315.         $svgGrapher->svgTitles->appendChild($group);
  316.     }
  317.  
  318.     // }}}
  319.     // SvgDocumentRenderer::renderTagsY() {{{
  320.  
  321.     /**
  322.      * renderTagsY
  323.      *
  324.      * Render the ordinates tags
  325.      * 
  326.      * @static
  327.      * @access public
  328.      * @return void 
  329.      */
  330.     public static function renderTagsY() 
  331.     {
  332.         $svgGrapher = SvgGrapher::singleton();
  333.         $display = $svgGrapher->display;
  334.         if(empty($display['tagsY']) || !$display['tagsY']) {
  335.             return false;
  336.         }
  337.         $group = new GElement(array('id'=>'tagsY', 'style'=>TAGS_Y_STYLE));
  338.  
  339.         foreach ($svgGrapher->tagsY as $i => $text) {
  340.             if(isset($svgGrapher->rendererCallBacks['tagsY'])) {
  341.                 $text = call_user_func($svgGrapher->rendererCallBacks['tagsY'], $text);
  342.             }
  343.             $y = $svgGrapher->gridLineYDelta * ($i + $svgGrapher->plotOffsetY) + $svgGrapher->boxGraphPane->y;
  344.  
  345.             $text = new TextElement($text, array(
  346.                 'x'=>$svgGrapher->boxTagsY->x, 'y'=>$y));
  347.             $group->appendChild($text);
  348.         }
  349.         // display 0 if in range
  350.         $range = $svgGrapher->range;
  351.         if(($range['min'] < 0 && $range['max'] > 0) || ($range['min'] > 0 && $range['max'] < 0)) {
  352.             $text = 0;
  353.             $i=0;
  354.             if(isset($svgGrapher->rendererCallBacks['tagsY'])) {
  355.                 $text = call_user_func($svgGrapher->rendererCallBacks['tagsY'], $text);
  356.             }
  357.             $y = $svgGrapher->boxGraphPane->height - ($svgGrapher->factorY * (0 - $range['min'])) + $svgGrapher->boxGraphPane->y;
  358.             $text = new TextElement($text, array(
  359.                 'x'=>$svgGrapher->boxTagsY->x, 'y'=>$y));
  360.             $group->appendChild($text);
  361.         }
  362.  
  363.         $svgGrapher->svgTitles->appendChild($group);
  364.     }
  365.  
  366.     // }}}
  367.     // SvgDocumentRenderer::renderLabelX() {{{
  368.     
  369.     /**
  370.      * renderLabelX
  371.      * 
  372.      * Render the abscisses label
  373.      * 
  374.      * @static
  375.      * @access public
  376.      * @return void 
  377.      */
  378.     public static function renderLabelX() 
  379.     {
  380.         $svgGrapher = SvgGrapher::singleton();
  381.         $display = $svgGrapher->display;
  382.         if(empty($display['labelX']) || !$display['labelX']) {
  383.             return false;
  384.         }
  385.         $text = new TextElement($svgGrapher->labelX, array(
  386.             'x' => $svgGrapher->boxLabelX->x, 
  387.             'y' => $svgGrapher->boxLabelX->y,
  388.             'style' => LABEL_X_STYLE));
  389.         $svgGrapher->svgTitles->appendChild($text);
  390.     }
  391.     
  392.     // }}}
  393.     // SvgDocumentRenderer::renderLabelY() {{{
  394.     
  395.     /**
  396.      * renderLabelY
  397.      *
  398.      * Render the ordinates label
  399.      * 
  400.      * @static
  401.      * @access public
  402.      * @return void 
  403.      */
  404.     public static function renderLabelY() 
  405.     {
  406.         $svgGrapher = SvgGrapher::singleton();
  407.         $display = $svgGrapher->display;
  408.         if(empty($display['labelY']) || !$display['labelY']) {
  409.             return false;
  410.         }
  411.         $text = new TextElement($svgGrapher->labelY, array(
  412.             'x' => $svgGrapher->boxLabelY->x, 
  413.             'y' => $svgGrapher->boxLabelY->y,
  414.             'style'=>LABEL_Y_STYLE));
  415.         $text->setAttribute('transform',sprintf('rotate(%s %s %s)', 
  416.             $svgGrapher->labelYRotation, $svgGrapher->boxLabelY->x, $svgGrapher->boxLabelY->y));
  417.         $svgGrapher->svgTitles->appendChild($text);
  418.     }
  419.     
  420.     // }}}
  421.     // SvgDocumentRenderer::renderLimits() {{{
  422.  
  423.     /**
  424.      * renderLimits
  425.      *
  426.      * Render the limits lines (limits are only horizontals lines).
  427.      * 
  428.      * @static
  429.      * @access public
  430.      * @return void 
  431.      */
  432.     public static function renderLimits() 
  433.     {
  434.         $svgGrapher = SvgGrapher::singleton();
  435.         $display = $svgGrapher->display;
  436.         if(empty($display['limits']) || !$display['limits']) {
  437.             return false;
  438.         }
  439.         $left = 1;
  440.         $right = $svgGrapher->boxGraphPane->width - 2;
  441.  
  442.         foreach($svgGrapher->limitsLines as $name=>$params) {
  443.             if($params['value'] !== false) {
  444.                 $svgGrapher->drawHLine($params['value'], $params['color'], $name . 'limit');
  445.             }
  446.         }
  447.     }
  448.  
  449.     // }}}
  450.     // SvgDocumentRenderer::renderLegend() {{{
  451.  
  452.     /**
  453.      * renderLegend
  454.      *
  455.      * Render the legend
  456.      * 
  457.      * @static
  458.      * @access public
  459.      * @return void 
  460.      */
  461.     public static function renderLegend() 
  462.     {
  463.         $svgGrapher = SvgGrapher::singleton();
  464.         $display = $svgGrapher->display;
  465.         if(empty($display['legend']) || !$display['legend']) {
  466.             return false;
  467.         }
  468.         $width = $svgGrapher->boxLegend->width - 1;
  469.         $height = $svgGrapher->boxGraphPane->height - 1;
  470.         $separator = $svgGrapher->legendTextHeight >> 2;
  471.         $lineX = 2;
  472.         $lineY = 4;
  473.         $lineRectHeight = $svgGrapher->legendTextHeight;
  474.         $lineRectWidth = 10;
  475.         $lineTextX = $lineX + $lineRectWidth + 2;
  476.         $lineTextY = $lineY + $lineRectHeight;
  477.  
  478.         $rect = new RectElement(array('x'=>0, 'y'=>0, 'width'=>$width, 
  479.             'height'=>$height));
  480.         $rect->setAttribute('style', LEGEND_BOX_STYLE);
  481.         $svgGrapher->svgLegend->appendChild($rect);
  482.  
  483.         $legends = array();
  484.         foreach($svgGrapher->curves as $curve) {
  485.             if(!is_array($curve->legend)) {
  486.                 $legends[$curve->legend] = $curve->color;
  487.                 continue;
  488.             }
  489.             foreach($curve->legend as $key=>$text) {
  490.                 $legends[$text] = $curve->color[$key];
  491.             }
  492.         }
  493.         foreach($legends as $text=>$color) {
  494.             $legendRectStyle = sprintf(
  495.                 'stroke-width:1; stroke: #000000; fill: %s; shape-rendering:crispEdges;',
  496.                 $color);
  497.             $legendRect = new RectElement(array('x'=>$lineX, 'y'=>$lineY, 
  498.                 'width'=>$lineRectWidth, 'height'=>$lineRectHeight, 
  499.                 'style'=>$legendRectStyle));
  500.             $svgGrapher->svgLegend->appendChild($legendRect);
  501.             $legendText = new TextElement($text, array(
  502.                 'x'=>$lineTextX, 'y'=>$lineTextY, 'style'=>LEGEND_TEXT_STYLE));
  503.             $svgGrapher->svgLegend->appendChild($legendText);
  504.             
  505.             $lineY += $svgGrapher->legendTextHeight + $separator;
  506.             $lineTextY = $lineY + $lineRectHeight;
  507.         }
  508.  
  509.         $translate = sprintf('translate(%s,%s)', $svgGrapher->boxLegend->x, $svgGrapher->boxLegend->y);
  510.         $svgGrapher->svgLegend->setAttribute('transform',$translate);
  511.     }
  512.  
  513.     // }}}
  514.     // SvgDocumentRenderer::renderGraphPane() {{{
  515.  
  516.     /**
  517.      * renderGraphPane
  518.      *
  519.      * Render the graph pane
  520.      * 
  521.      * @static
  522.      * @access public
  523.      * @return void 
  524.      */
  525.     public static function renderGraphPane() 
  526.     {
  527.         $svgGrapher = SvgGrapher::singleton();
  528.         $svgGrapher->svgGraphPane->setAttribute('transform',sprintf(
  529.             'translate(%s,%s)', $svgGrapher->boxGraphPane->x, 
  530.             $svgGrapher->boxGraphPane->y));
  531.     }
  532.  
  533.     // }}}
  534.     // SvgDocumentRenderer::renderGraphPaneBox() {{{
  535.     
  536.     /**
  537.      * renderGraphPaneBox
  538.      *
  539.      * Render the graph pane box
  540.      * 
  541.      * @access public
  542.      * @return void 
  543.      */
  544.     public static function renderGraphPaneBox() 
  545.     {
  546.         $svgGrapher = SvgGrapher::singleton();
  547.         $display = $svgGrapher->display;
  548.         if(empty($display['box']) || !$display['box']) {
  549.             return false;
  550.         }
  551.         $width = $svgGrapher->boxGraphPane->width - 1;
  552.         $height = $svgGrapher->boxGraphPane->height - 1;
  553.  
  554.         $rect = new RectElement(array('x'=>0, 'y'=>0, 'width'=>$width, 
  555.             'height'=>$height, 'style'=>BOX_STYLE));
  556.         $svgGrapher->svgGraphPane->appendChild($rect);
  557.     }
  558.     
  559.     // }}}
  560.     // SvgDocumentRenderer::renderCurves() {{{
  561.     
  562.     /**
  563.      * renderCurves
  564.      *
  565.      * Render the curves
  566.      * 
  567.      * @static
  568.      * @access public
  569.      * @return void 
  570.      */
  571.     public static function renderCurves() 
  572.     {
  573.         $svgGrapher = SvgGrapher::singleton();
  574.         foreach($svgGrapher->curves as $id=>$curve) {
  575.             $curve->render();
  576.         }
  577.     } 
  578.     
  579.     // }}}
  580.     // SvgDocumentRenderer::renderW3cValidatorLink() {{{
  581.     
  582.     /**
  583.      * renderW3cValidatorLink
  584.      * 
  585.      * @static
  586.      * @access public
  587.      * @return bool 
  588.      */
  589.     public static function renderW3cValidatorLink() 
  590.     {
  591.         $svgGrapher = SvgGrapher::singleton();
  592.         if(!$svgGrapher->display['w3link']) {
  593.             return false;
  594.         }
  595.         $g = new GElement(array('id'=>'w3validatorlink'));
  596.         $a = new AElement(NULL,
  597.             array('xlink:href'=> 'http://validator.w3.org/check?uri=referer')
  598.         );
  599.         $img = new ImageElement(array(
  600.             'xlink:href'=>'http://www.w3.org/Icons/valid-svg11.png', 
  601.             'x' => $svgGrapher->boxLegend->x, 
  602.             'y' => ($svgGrapher->boxLegend->y + $svgGrapher->boxLegend->height), 
  603.             'width' => 88, 
  604.             'height' => 31));
  605.         $g->appendChild($a);
  606.         $a->appendChild($img);
  607.         $svgGrapher->svgDocument->appendChild($g);
  608.         return true;
  609.     }
  610.     
  611.     // }}}
  612. }
  613.  
  614. ?>

Documentation generated on Tue, 23 Oct 2007 11:32:08 +0200 by phpDocumentor 1.4.0