home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 April / CMCD0404.ISO / Software / Freeware / Programare / dotproject / lib / jpgraph / src / jpgraph_canvtools.php < prev    next >
PHP Script  |  2002-12-11  |  14KB  |  517 lines

  1. <?php
  2. /*=======================================================================
  3. // File:     JPGRAPH_CANVTOOLS.PHP
  4. // Description:    Some utilities for text and shape drawing on a canvas
  5. // Created:     2002-08-23
  6. // Author:    Johan Persson (johanp@aditus.nu)
  7. // Ver:        $Id: jpgraph_canvtools.php,v 1.1 2002/12/11 09:41:58 kripper Exp $
  8. //
  9. // License:    This code is released under QPL
  10. // Copyright (C) 2001,2002 Johan Persson
  11. //========================================================================
  12. */
  13.  
  14. DEFINE('CORNER_TOPLEFT',0);
  15. DEFINE('CORNER_TOPRIGHT',1);
  16. DEFINE('CORNER_BOTTOMRIGHT',2);
  17. DEFINE('CORNER_BOTTOMLEFT',3);
  18.  
  19.  
  20. //===================================================
  21. // CLASS CanvasScale
  22. // Description: Define a scale for canvas so we
  23. // can abstract away with absolute pixels
  24. //===================================================
  25.  
  26. class CanvasScale {
  27.     var $g;
  28.     var $w,$h;
  29.     var $ixmin=0,$ixmax=10,$iymin=0,$iymax=10;
  30.  
  31.     function CanvasScale(&$graph,$xmin=0,$xmax=10,$ymin=0,$ymax=10) {
  32.     $this->g = &$graph;
  33.     $this->w = $graph->img->width;
  34.     $this->h = $graph->img->height;
  35.     $this->ixmin = $xmin;
  36.     $this->ixmax = $xmax;
  37.     $this->iymin = $ymin;
  38.     $this->iymax = $ymax;
  39.     }
  40.     
  41.     function Set($xmin=0,$xmax=10,$ymin=0,$ymax=10) {
  42.     $this->ixmin = $xmin;
  43.     $this->ixmax = $xmax;
  44.     $this->iymin = $ymin;
  45.     $this->iymax = $ymax;
  46.     }
  47.  
  48.     function Translate($x,$y) {
  49.     $xp = round(($x-$this->ixmin)/($this->ixmax - $this->ixmin) * $this->w);
  50.     $yp = round(($y-$this->iymin)/($this->iymax - $this->iymin) * $this->h);
  51.     return array($xp,$yp);
  52.     }
  53.  
  54.     function TranslateX($x) {
  55.     $xp = round(($x-$this->ixmin)/($this->ixmax - $this->ixmin) * $this->w);
  56.     return $xp;
  57.     }
  58.  
  59.     function TranslateY($y) {
  60.     $yp = round(($y-$this->iymin)/($this->iymax - $this->iymin) * $this->h);
  61.     return $yp;
  62.     }
  63.  
  64. }
  65.  
  66.  
  67. //===================================================
  68. // CLASS Shape
  69. // Description: Methods to draw shapes on canvas
  70. //===================================================
  71. class Shape {
  72.     var $img,$scale;
  73.  
  74.     function Shape(&$aGraph,&$scale) {
  75.     $this->img = &$aGraph->img;
  76.     $this->img->SetColor('black');
  77.     $this->scale = &$scale;
  78.     }
  79.  
  80.     function SetColor($aColor) {
  81.     $this->img->SetColor($aColor);
  82.     }
  83.  
  84.     function Line($x1,$y1,$x2,$y2) {
  85.     list($x1,$y1) = $this->scale->Translate($x1,$y1);
  86.     list($x2,$y2) = $this->scale->Translate($x2,$y2);
  87.     $this->img->Line($x1,$y1,$x2,$y2);
  88.     }
  89.  
  90.     function Polygon($p,$aClosed=false) {
  91.     $n=count($p);
  92.     for($i=0; $i < $n; $i+=2 ) {
  93.        $p[$i]   = $this->scale->TranslateX($p[$i]);
  94.        $p[$i+1] = $this->scale->TranslateY($p[$i+1]);
  95.     }
  96.     $this->img->Polygon($p,$aClosed);
  97.     }
  98.  
  99.     function FilledPolygon($p) {
  100.     $n=count($p);
  101.     for($i=0; $i < $n; $i+=2 ) {
  102.        $p[$i]   = $this->scale->TranslateX($p[$i]);
  103.        $p[$i+1] = $this->scale->TranslateY($p[$i+1]);
  104.     }
  105.     $this->img->FilledPolygon($p);
  106.     }
  107.     
  108.  
  109.     // Draw a bezier curve with defining points in the $aPnts array
  110.     // using $aSteps steps.
  111.     // 0=x0, 1=y0
  112.     // 2=x1, 3=y1
  113.     // 4=x2, 5=y2
  114.     // 6=x3, 7=y3
  115.     function Bezier($p,$aSteps=40) {
  116.     $x0 = $p[0];
  117.     $y0 = $p[1];
  118.     // Calculate coefficients
  119.     $cx = 3*($p[2]-$p[0]);
  120.     $bx = 3*($p[4]-$p[2])-$cx;
  121.     $ax = $p[6]-$p[0]-$cx-$bx;
  122.     $cy = 3*($p[3]-$p[1]);
  123.     $by = 3*($p[5]-$p[3])-$cy;
  124.     $ay = $p[7]-$p[1]-$cy-$by;
  125.  
  126.     // Step size
  127.     $delta = 1.0/$aSteps;
  128.  
  129.     $x_old = $x0;
  130.     $y_old = $y0;
  131.     for($t=$delta; $t<=1.0; $t+=$delta) {
  132.         $tt = $t*$t; $ttt=$tt*$t;
  133.         $x  = $ax*$ttt + $bx*$tt + $cx*$t + $x0;
  134.         $y = $ay*$ttt + $by*$tt + $cy*$t + $y0;
  135.         $this->Line($x_old,$y_old,$x,$y);
  136.         $x_old = $x;
  137.         $y_old = $y;
  138.     }
  139.     $this->Line($x_old,$y_old,$p[6],$p[7]);
  140.     }
  141.  
  142.     function Rectangle($x1,$y1,$x2,$y2) {
  143.     list($x1,$y1) = $this->scale->Translate($x1,$y1);
  144.     list($x2,$y2)   = $this->scale->Translate($x2,$y2);
  145.     $this->img->Rectangle($x1,$y1,$x2,$y2);
  146.     }
  147.  
  148.     function FilledRectangle($x1,$y1,$x2,$y2) {
  149.     list($x1,$y1) = $this->scale->Translate($x1,$y1);
  150.     list($x2,$y2)   = $this->scale->Translate($x2,$y2);
  151.     $this->img->FilledRectangle($x1,$y1,$x2,$y2);
  152.     }
  153.     
  154.     function Circle($x1,$y1,$r) {
  155.     list($x1,$y1) = $this->scale->Translate($x1,$y1);
  156.     if( $r >= 0 )
  157.         $r   = $this->scale->TranslateX($r);
  158.     else
  159.         $r = -$r;
  160.     $this->img->Circle($x1,$y1,$r);
  161.     }
  162.  
  163.     function FilledCircle($x1,$y1,$r) {
  164.     list($x1,$y1) = $this->scale->Translate($x1,$y1);
  165.     if( $r >= 0 )
  166.         $r   = $this->scale->TranslateX($r);
  167.     else
  168.         $r = -$r;
  169.     $this->img->FilledCircle($x1,$y1,$r);
  170.     }
  171.  
  172.     function RoundedRectangle($x1,$y1,$x2,$y2,$r=null) {    
  173.     list($x1,$y1) = $this->scale->Translate($x1,$y1);
  174.     list($x2,$y2)   = $this->scale->Translate($x2,$y2);
  175.  
  176.     if( $r == null )
  177.         $r = 5;
  178.     elseif( $r >= 0 )
  179.         $r = $this->scale->TranslateX($r);
  180.     else
  181.         $r = -$r;
  182.     $this->img->RoundedRectangle($x1,$y1,$x2,$y2,$r);
  183.     }
  184.  
  185.     function FilledRoundedRectangle($x1,$y1,$x2,$y2,$r=null) {    
  186.     list($x1,$y1) = $this->scale->Translate($x1,$y1);
  187.     list($x2,$y2)   = $this->scale->Translate($x2,$y2);
  188.  
  189.     if( $r == null )
  190.         $r = 5;
  191.     elseif( $r > 0 )
  192.         $r = $this->scale->TranslateX($r);
  193.     else
  194.         $r = -$r;
  195.     $this->img->FilledRoundedRectangle($x1,$y1,$x2,$y2,$r);    
  196.     }
  197.  
  198.     function ShadowRectangle($x1,$y1,$x2,$y2,$fcolor=false,$shadow_width=null,$shadow_color=array(102,102,102)) {
  199.     list($x1,$y1) = $this->scale->Translate($x1,$y1);
  200.     list($x2,$y2) = $this->scale->Translate($x2,$y2);
  201.     if( $shadow_width == null ) 
  202.         $shadow_width=4;
  203.     else
  204.         $shadow_width=$this->scale->TranslateX($shadow_width);
  205.     $this->img->ShadowRectangle($x1,$y1,$x2,$y2,$fcolor,$shadow_width,$shadow_color);
  206.     }
  207.  
  208.     function SetTextAlign($halign,$valign="bottom") {
  209.     $this->img->SetTextAlign($halign,$valign="bottom");
  210.     }
  211.  
  212.     function StrokeText($x1,$y1,$txt,$dir=0,$paragraph_align="left") {
  213.     list($x1,$y1) = $this->scale->Translate($x1,$y1);
  214.     $this->img->StrokeText($x1,$y1,$txt,$dir,$paragraph_align);
  215.     }
  216.  
  217.     // A rounded rectangle where one of the corner has been moved "into" the
  218.     // rectangle 'iw' width and 'ih' height. Corners:
  219.     // 0=Top left, 1=top right, 2=bottom right, 3=bottom left
  220.     function IndentedRectangle($xt,$yt,$w,$h,$iw=0,$ih=0,$aCorner=3,$aFillColor="",$r=4) {
  221.     
  222.     list($xt,$yt) = $this->scale->Translate($xt,$yt);
  223.     list($w,$h)   = $this->scale->Translate($w,$h);
  224.     list($iw,$ih) = $this->scale->Translate($iw,$ih);
  225.     
  226.     $xr = $xt + $w - 0;
  227.     $yl = $yt + $h - 0;
  228.  
  229.     switch( $aCorner ) {
  230.         case 0: // Upper left
  231.         
  232.         // Bottom line, left &  right arc
  233.         $this->img->Line($xt+$r,$yl,$xr-$r,$yl);
  234.         $this->img->Arc($xt+$r,$yl-$r,$r*2,$r*2,90,180);
  235.         $this->img->Arc($xr-$r,$yl-$r,$r*2,$r*2,0,90);
  236.  
  237.         // Right line, Top right arc
  238.         $this->img->Line($xr,$yt+$r,$xr,$yl-$r);
  239.         $this->img->Arc($xr-$r,$yt+$r,$r*2,$r*2,270,360);
  240.  
  241.         // Top line, Top left arc
  242.         $this->img->Line($xt+$iw+$r,$yt,$xr-$r,$yt);
  243.         $this->img->Arc($xt+$iw+$r,$yt+$r,$r*2,$r*2,180,270);
  244.  
  245.         // Left line
  246.         $this->img->Line($xt,$yt+$ih+$r,$xt,$yl-$r);
  247.  
  248.         // Indent horizontal, Lower left arc
  249.         $this->img->Line($xt+$r,$yt+$ih,$xt+$iw-$r,$yt+$ih);
  250.         $this->img->Arc($xt+$r,$yt+$ih+$r,$r*2,$r*2,180,270);
  251.  
  252.         // Indent vertical, Indent arc
  253.         $this->img->Line($xt+$iw,$yt+$r,$xt+$iw,$yt+$ih-$r);
  254.         $this->img->Arc($xt+$iw-$r,$yt+$ih-$r,$r*2,$r*2,0,90);
  255.  
  256.         if( $aFillColor != '' ) {
  257.             $bc = $this->img->current_color_name;
  258.             $this->img->PushColor($aFillColor);
  259.             $this->img->FillToBorder($xr-$r,$yl-$r,$bc);
  260.             $this->img->PopColor();
  261.         }
  262.  
  263.         break;
  264.  
  265.         case 1: // Upper right
  266.  
  267.         // Bottom line, left &  right arc
  268.         $this->img->Line($xt+$r,$yl,$xr-$r,$yl);
  269.         $this->img->Arc($xt+$r,$yl-$r,$r*2,$r*2,90,180);
  270.         $this->img->Arc($xr-$r,$yl-$r,$r*2,$r*2,0,90);
  271.  
  272.         // Left line, Top left arc
  273.         $this->img->Line($xt,$yt+$r,$xt,$yl-$r);
  274.         $this->img->Arc($xt+$r,$yt+$r,$r*2,$r*2,180,270);
  275.  
  276.         // Top line, Top right arc
  277.         $this->img->Line($xt+$r,$yt,$xr-$iw-$r,$yt);
  278.         $this->img->Arc($xr-$iw-$r,$yt+$r,$r*2,$r*2,270,360);
  279.  
  280.         // Right line
  281.         $this->img->Line($xr,$yt+$ih+$r,$xr,$yl-$r);
  282.  
  283.         // Indent horizontal, Lower right arc
  284.         $this->img->Line($xr-$iw+$r,$yt+$ih,$xr-$r,$yt+$ih);
  285.         $this->img->Arc($xr-$r,$yt+$ih+$r,$r*2,$r*2,270,360);
  286.  
  287.         // Indent vertical, Indent arc
  288.         $this->img->Line($xr-$iw,$yt+$r,$xr-$iw,$yt+$ih-$r);
  289.         $this->img->Arc($xr-$iw+$r,$yt+$ih-$r,$r*2,$r*2,90,180);
  290.  
  291.         if( $aFillColor != '' ) {
  292.             $bc = $this->img->current_color_name;
  293.             $this->img->PushColor($aFillColor);
  294.             $this->img->FillToBorder($xt+$r,$yl-$r,$bc);
  295.             $this->img->PopColor();
  296.         }
  297.  
  298.         break;
  299.  
  300.         case 2: // Lower right
  301.         // Top line, Top left & Top right arc
  302.         $this->img->Line($xt+$r,$yt,$xr-$r,$yt);
  303.         $this->img->Arc($xt+$r,$yt+$r,$r*2,$r*2,180,270);
  304.         $this->img->Arc($xr-$r,$yt+$r,$r*2,$r*2,270,360);
  305.  
  306.         // Left line, Bottom left arc
  307.         $this->img->Line($xt,$yt+$r,$xt,$yl-$r);
  308.         $this->img->Arc($xt+$r,$yl-$r,$r*2,$r*2,90,180);
  309.  
  310.         // Bottom line, Bottom right arc
  311.         $this->img->Line($xt+$r,$yl,$xr-$iw-$r,$yl);
  312.         $this->img->Arc($xr-$iw-$r,$yl-$r,$r*2,$r*2,0,90);
  313.  
  314.         // Right line
  315.         $this->img->Line($xr,$yt+$r,$xr,$yl-$ih-$r);
  316.         
  317.         // Indent horizontal, Lower right arc
  318.         $this->img->Line($xr-$r,$yl-$ih,$xr-$iw+$r,$yl-$ih);
  319.         $this->img->Arc($xr-$r,$yl-$ih-$r,$r*2,$r*2,0,90);
  320.  
  321.         // Indent vertical, Indent arc
  322.         $this->img->Line($xr-$iw,$yl-$r,$xr-$iw,$yl-$ih+$r);
  323.         $this->img->Arc($xr-$iw+$r,$yl-$ih+$r,$r*2,$r*2,180,270);
  324.  
  325.         if( $aFillColor != '' ) {
  326.             $bc = $this->img->current_color_name;
  327.             $this->img->PushColor($aFillColor);
  328.             $this->img->FillToBorder($xt+$r,$yt+$r,$bc);
  329.             $this->img->PopColor();
  330.         }
  331.  
  332.         break;
  333.  
  334.         case 3: // Lower left
  335.         // Top line, Top left & Top right arc
  336.         $this->img->Line($xt+$r,$yt,$xr-$r,$yt);
  337.         $this->img->Arc($xt+$r,$yt+$r,$r*2,$r*2,180,270);
  338.         $this->img->Arc($xr-$r,$yt+$r,$r*2,$r*2,270,360);
  339.  
  340.         // Right line, Bottom right arc
  341.         $this->img->Line($xr,$yt+$r,$xr,$yl-$r);
  342.         $this->img->Arc($xr-$r,$yl-$r,$r*2,$r*2,0,90);
  343.  
  344.         // Bottom line, Bottom left arc
  345.         $this->img->Line($xt+$iw+$r,$yl,$xr-$r,$yl);
  346.         $this->img->Arc($xt+$iw+$r,$yl-$r,$r*2,$r*2,90,180);
  347.  
  348.         // Left line
  349.         $this->img->Line($xt,$yt+$r,$xt,$yl-$ih-$r);
  350.         
  351.         // Indent horizontal, Lower left arc
  352.         $this->img->Line($xt+$r,$yl-$ih,$xt+$iw-$r,$yl-$ih);
  353.         $this->img->Arc($xt+$r,$yl-$ih-$r,$r*2,$r*2,90,180);
  354.  
  355.         // Indent vertical, Indent arc
  356.         $this->img->Line($xt+$iw,$yl-$ih+$r,$xt+$iw,$yl-$r);
  357.         $this->img->Arc($xt+$iw-$r,$yl-$ih+$r,$r*2,$r*2,270,360);
  358.  
  359.         if( $aFillColor != '' ) {
  360.             $bc = $this->img->current_color_name;
  361.             $this->img->PushColor($aFillColor);
  362.             $this->img->FillToBorder($xr-$r,$yt+$r,$bc);
  363.             $this->img->PopColor();
  364.         }
  365.  
  366.         break;
  367.     }
  368.     }
  369. }
  370.  
  371.  
  372. //===================================================
  373. // CLASS RectangleText
  374. // Description: Draws a text paragraph inside a 
  375. // rounded, possible filled, rectangle.
  376. //===================================================
  377. class CanvasRectangleText {
  378.     var $ix,$iy,$iw,$ih,$ir=4;
  379.     var $iTxt,$iColor='black',$iFillColor='',$iFontColor='black';
  380.     var $iParaAlign='center';
  381.     var $iAutoBoxMargin=5;
  382.     var $iShadowWidth=3,$iShadowColor='';
  383.  
  384.     function CanvasRectangleText($aTxt='',$xl=0,$yt=0,$w=0,$h=0) {
  385.     $this->iTxt = new Text($aTxt);
  386.     $this->ix = $xl;
  387.     $this->iy = $yt;
  388.     $this->iw = $w;
  389.     $this->ih = $h;
  390.     }
  391.  
  392.     function SetShadow($aColor='gray',$aWidth=3) {
  393.     $this->iShadowColor = $aColor;
  394.     $this->iShadowWidth = $aWidth;
  395.     }
  396.  
  397.     function SetFont($FontFam,$aFontStyle,$aFontSize=12) {
  398.     $this->iTxt->SetFont($FontFam,$aFontStyle,$aFontSize);
  399.     }
  400.  
  401.     function SetTxt($aTxt) {
  402.     $this->iTxt->Set($aTxt);
  403.     }
  404.  
  405.     function ParagraphAlign($aParaAlign) {
  406.     $this->iParaAlign = $aParaAlign;
  407.     }
  408.  
  409.     function SetFillColor($aFillColor) {
  410.     $this->iFillColor = $aFillColor;
  411.     }
  412.  
  413.     function SetAutoMargin($aMargin) {
  414.     $this->iAutoBoxMargin=$aMargin;
  415.     }
  416.  
  417.     function SetColor($aColor) {
  418.     $this->iColor = $aColor;
  419.     }
  420.  
  421.     function SetFontColor($aColor) {
  422.     $this->iFontColor = $aColor;
  423.     }
  424.  
  425.     function SetPos($xl=0,$yt=0,$w=0,$h=0) {
  426.     $this->ix = $xl;
  427.     $this->iy = $yt;
  428.     $this->iw = $w;
  429.     $this->ih = $h;
  430.     }
  431.  
  432.     function Pos($xl=0,$yt=0,$w=0,$h=0) {
  433.     $this->ix = $xl;
  434.     $this->iy = $yt;
  435.     $this->iw = $w;
  436.     $this->ih = $h;
  437.     }
  438.  
  439.     function Set($aTxt,$xl,$yt,$w=0,$h=0) {
  440.     $this->iTxt->Set($aTxt);
  441.     $this->ix = $xl;
  442.     $this->iy = $yt;
  443.     $this->iw = $w;
  444.     $this->ih = $h;
  445.     }
  446.  
  447.     function SetCornerRadius($aRad=5) {
  448.     $this->ir = $aRad;
  449.     }
  450.  
  451.     function Stroke($aImg,$scale) {
  452.     
  453.     // If coordinates are specifed as negative this means we should
  454.     // treat them as abolsute (pixels) coordinates
  455.     if( $this->ix > 0 ) {
  456.         $this->ix = $scale->TranslateX($this->ix) ;
  457.     }
  458.     else {
  459.         $this->ix = -$this->ix;
  460.     }
  461.  
  462.     if( $this->iy > 0 ) {
  463.         $this->iy = $scale->TranslateY($this->iy) ;
  464.     }
  465.     else {
  466.         $this->iy = -$this->iy;
  467.     }
  468.         
  469.     list($this->iw,$this->ih) = $scale->Translate($this->iw,$this->ih) ;
  470.  
  471.     if( $this->iw == 0 ) 
  472.         $this->iw = round($this->iTxt->GetWidth($aImg) + $this->iAutoBoxMargin);
  473.     if( $this->ih == 0 ) {
  474.         $this->ih = round($this->iTxt->GetTextHeight($aImg) + $this->iAutoBoxMargin);
  475.     }
  476.  
  477.     if( $this->iShadowColor != '' ) {
  478.         $aImg->PushColor($this->iShadowColor);
  479.         $aImg->FilledRoundedRectangle($this->ix+$this->iShadowWidth,
  480.                       $this->iy+$this->iShadowWidth,
  481.                       $this->ix+$this->iw-1+$this->iShadowWidth,
  482.                       $this->iy+$this->ih-1+$this->iShadowWidth,
  483.                       $this->ir);
  484.         $aImg->PopColor();        
  485.     }
  486.  
  487.     if( $this->iFillColor != '' ) {
  488.         $aImg->PushColor($this->iFillColor);
  489.         $aImg->FilledRoundedRectangle($this->ix,$this->iy,
  490.                       $this->ix+$this->iw-1,
  491.                       $this->iy+$this->ih-1,
  492.                       $this->ir);
  493.         $aImg->PopColor();
  494.     }
  495.  
  496.     if( $this->iColor != '' ) {
  497.         $aImg->PushColor($this->iColor);
  498.         $aImg->RoundedRectangle($this->ix,$this->iy,
  499.                     $this->ix+$this->iw-1,
  500.                     $this->iy+$this->ih-1,
  501.                     $this->ir);
  502.         $aImg->PopColor();
  503.     }
  504.     
  505.     $this->iTxt->Align('center','center');
  506.     $this->iTxt->ParagraphAlign($this->iParaAlign);
  507.     $this->iTxt->SetColor($this->iFontColor);
  508.     $this->iTxt->Stroke($aImg, $this->ix+$this->iw/2, $this->iy+$this->ih/2);
  509.  
  510.     return array($this->iw, $this->ih);
  511.  
  512.     }
  513.  
  514. }
  515.  
  516.  
  517. ?>