]> git.llucax.com Git - mecon/meconlib.git/blob - lib/MECON/Graph/external/jpgraph/src/jpgraph_gradient.php
- Correccion de bugs
[mecon/meconlib.git] / lib / MECON / Graph / external / jpgraph / src / jpgraph_gradient.php
1 <?php
2 /*=======================================================================
3 // File:        JPGRAPH_GRADIENT.PHP
4 // Description: Create a color gradient
5 // Created:     2003-02-01
6 // Author:      Johan Persson (johanp@aditus.nu)
7 // Ver:         $Id: jpgraph_gradient.php,v 1.1.2.5 2003/08/23 23:15:06 aditus Exp $
8 //
9 // License:     This code is released under QPL
10 // Copyright (C) 2003 Johan Persson
11 //========================================================================
12 */
13
14   
15 //===================================================
16 // CLASS Gradient
17 // Description: Handles gradient fills. This is to be
18 // considered a "friend" class of Class Image.
19 //===================================================
20 class Gradient {
21     var $img=null;
22     var $numcolors=100;
23 //---------------
24 // CONSTRUCTOR
25     function Gradient(&$img) {
26         $this->img = $img;
27     }
28
29
30     function SetNumColors($aNum) {
31         $this->numcolors=$aNum;
32     }
33 //---------------
34 // PUBLIC METHODS       
35     // Produce a gradient filled rectangle with a smooth transition between
36     // two colors.
37     // ($xl,$yt)        Top left corner
38     // ($xr,$yb)        Bottom right
39     // $from_color      Starting color in gradient
40     // $to_color        End color in the gradient
41     // $style           Which way is the gradient oriented?
42     function FilledRectangle($xl,$yt,$xr,$yb,$from_color,$to_color,$style=1) {
43         switch( $style ) {      
44             case 1:  // HORIZONTAL
45                 $steps = abs($xr-$xl);
46                 $delta = $xr>=$xl ? 1 : -1;
47                 $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors);
48                 for( $i=0, $x=$xl; $i < $steps; ++$i ) {
49                     $this->img->current_color = $colors[$i];
50                     $this->img->Line($x,$yt,$x,$yb);
51                     $x += $delta;
52                 }
53                 break;
54
55             case 2: // VERTICAL
56                 $steps = abs($yb-$yt);
57                 $delta = $yb>=$yt ? 1 : -1;
58                 $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors);
59                 for($i=0,$y=$yt; $i < $steps; ++$i) {
60                     $this->img->current_color = $colors[$i];
61                     $this->img->Line($xl,$y,$xr,$y);
62                     $y += $delta;
63                 }
64                 break;
65
66             case 3: // VERTICAL FROM MIDDLE
67                 $steps = abs($yb-$yt)/2;
68                 $delta = $yb >= $yt ? 1 : -1;
69                 $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors);
70                 for($y=$yt, $i=0; $i < $steps;  ++$i) {
71                     $this->img->current_color = $colors[$i];
72                     $this->img->Line($xl,$y,$xr,$y);
73                     $y += $delta;
74                 }
75                 --$i;
76                 for($j=0; $j < $steps; ++$j, --$i) {
77                     $this->img->current_color = $colors[$i];
78                     $this->img->Line($xl,$y,$xr,$y);
79                     $y += $delta;
80                 }
81                 $this->img->Line($xl,$y,$xr,$y);
82                 break;
83
84             case 4: // HORIZONTAL FROM MIDDLE
85                 $steps = abs($xr-$xl)/2;
86                 $delta = $xr>=$xl ? 1 : -1;
87                 $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors);
88                 for($x=$xl, $i=0; $i < $steps; ++$i) {
89                     $this->img->current_color = $colors[$i];
90                     $this->img->Line($x,$yb,$x,$yt);
91                     $x += $delta;
92                 }
93                 --$i;
94                 for($j=0; $j < $steps; ++$j, --$i) {
95                     $this->img->current_color = $colors[$i];
96                     $this->img->Line($x,$yb,$x,$yt);
97                     $x += $delta;
98                 }
99                 $this->img->Line($x,$yb,$x,$yt);                
100                 break;
101
102             case 6: // HORIZONTAL WIDER MIDDLE
103                 $diff = round(abs($xr-$xl));
104                 $steps = floor(abs($diff)/3);
105                 $firststep = $diff - 2*$steps ; 
106                 // $steps = abs($xr-$xl)/3;
107                 $delta = $xr >= $xl ? 1 : -1;
108                 $this->GetColArray($from_color,$to_color,$firststep,$colors,$this->numcolors);
109                 for($x=$xl, $i=0; $i < $firststep; ++$i) {
110                     $this->img->current_color = $colors[$i];
111                     $this->img->Line($x,$yb,$x,$yt);
112                     $x += $delta;
113                 }
114                 --$i;
115                 $this->img->current_color = $colors[$i];
116                 for($j=0; $j< $steps; ++$j) {
117                     $this->img->Line($x,$yb,$x,$yt);
118                     $x += $delta;
119                 }
120                 
121                 for($j=0; $j < $steps; ++$j, --$i) {
122                     $this->img->current_color = $colors[$i];                            
123                     $this->img->Line($x,$yb,$x,$yt);    
124                     $x += $delta;
125                 }                               
126                 break;
127
128             case 7: // VERTICAL WIDER MIDDLE
129                 $diff = round(abs($yb-$yt));
130                 $steps = floor(abs($diff)/3);
131                 $firststep = $diff - 2*$steps ; 
132                 $delta = $yb >= $yt? 1 : -1;
133                 $this->GetColArray($from_color,$to_color,$firststep,$colors,$this->numcolors);
134                 for($y=$yt, $i=0; $i < $firststep;  ++$i) {
135                     $this->img->current_color = $colors[$i];
136                     $this->img->Line($xl,$y,$xr,$y);
137                     $y += $delta;
138                 }
139                 --$i;
140                 $this->img->current_color = $colors[$i];
141                 for($j=0; $j < $steps; ++$j) {
142                     $this->img->Line($xl,$y,$xr,$y);
143                     $y += $delta;
144                 }
145                 for($j=0; $j < $steps; ++$j, --$i) {
146                     $this->img->current_color = $colors[$i];                            
147                     $this->img->Line($xl,$y,$xr,$y);
148                     $y += $delta;
149                 }                               
150                 break;      
151
152             case 8:  // LEFT REFLECTION
153                 $steps1 = round(0.3*abs($xr-$xl));
154                 $delta = $xr>=$xl ? 1 : -1;             
155
156                 $this->GetColArray($from_color.':1.3',$to_color,$steps1,$colors,$this->numcolors);
157                 for($x=$xl, $i=0; $i < $steps1; ++$i) {
158                     $this->img->current_color = $colors[$i];
159                     $this->img->Line($x,$yb,$x,$yt);
160                     $x += $delta;
161                 }
162                 $steps2 = max(1,round(0.08*abs($xr-$xl)));
163                 $this->img->SetColor($to_color);
164                 for($j=0; $j< $steps2; ++$j) {
165                     $this->img->Line($x,$yb,$x,$yt);
166                     $x += $delta;
167                 }
168                 $steps = abs($xr-$xl)-$steps1-$steps2;
169                 $this->GetColArray($to_color,$from_color,$steps,$colors,$this->numcolors);   
170                 for($i=0; $i < $steps; ++$i) {
171                     $this->img->current_color = $colors[$i];
172                     $this->img->Line($x,$yb,$x,$yt);
173                     $x += $delta;
174                 }
175                 break;
176
177             case 9:  // RIGHT REFLECTION
178                 $steps1 = round(0.7*abs($xr-$xl));
179                 $delta = $xr>=$xl ? 1 : -1;             
180
181                 $this->GetColArray($from_color,$to_color,$steps1,$colors,$this->numcolors);
182                 for($x=$xl, $i=0; $i < $steps1; ++$i) {
183                     $this->img->current_color = $colors[$i];
184                     $this->img->Line($x,$yb,$x,$yt);
185                     $x += $delta;
186                 }
187                 $steps2 = max(1,round(0.08*abs($xr-$xl)));
188                 $this->img->SetColor($to_color);
189                 for($j=0; $j< $steps2; ++$j) {
190                     $this->img->Line($x,$yb,$x,$yt);
191                     $x += $delta;
192                 }
193                 $steps = abs($xr-$xl)-$steps1-$steps2;
194                 $this->GetColArray($to_color,$from_color.':1.3',$steps,$colors,$this->numcolors);   
195                 for($i=0; $i < $steps; ++$i) {
196                     $this->img->current_color = $colors[$i];
197                     $this->img->Line($x,$yb,$x,$yt);
198                     $x += $delta;
199                 }
200                 break;
201
202
203             case 5: // Rectangle
204                 $steps = floor(min(($yb-$yt)+1,($xr-$xl)+1)/2); 
205                 $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors);
206                 $dx = ($xr-$xl)/2;
207                 $dy = ($yb-$yt)/2;
208                 $x=$xl;$y=$yt;$x2=$xr;$y2=$yb;
209                 for($x=$xl, $i=0; $x < $xl+$dx && $y < $yt+$dy ; ++$x, ++$y, --$x2, --$y2, ++$i) {
210                     assert( $i < count($colors));
211                     $this->img->current_color = $colors[$i];                    
212                     $this->img->Rectangle($x,$y,$x2,$y2);
213                 }
214                 $this->img->Line($x,$y,$x2,$y2);
215                 break;
216
217             default:
218                 die("JpGraph Error: Unknown gradient style (=$style).");
219                 break;
220         }
221     }
222
223     // Fill a special case of a polygon with a flat bottom
224     // with a gradient. Can be used for filled line plots.
225     // Please note that this is NOT a generic gradient polygon fill
226     // routine. It assumes that the bottom is flat (like a drawing
227     // of a mountain)
228     function FilledFlatPolygon($pts,$from_color,$to_color) {
229         if( count($pts) == 0 ) return;
230         
231         $maxy=$pts[1];
232         $miny=$pts[1];          
233         $n = count($pts) ;
234         for( $i=0, $idx=0; $i < $n; $i += 2) {
235             $x = round($pts[$i]);
236             $y = round($pts[$i+1]);
237             $miny = min($miny,$y);
238             $maxy = max($maxy,$y);
239         }
240             
241         $colors = array();
242         $this->GetColArray($from_color,$to_color,abs($maxy-$miny)+1,$colors,$this->numcolors);
243         for($i=$miny, $idx=0; $i <= $maxy; ++$i ) {
244             $colmap[$i] = $colors[$idx++]; 
245         }
246
247         $n = count($pts)/2 ;
248         $idx = 0 ;
249         while( $idx < $n-1 ) {
250             $p1 = array(round($pts[$idx*2]),round($pts[$idx*2+1]));
251             $p2 = array(round($pts[++$idx*2]),round($pts[$idx*2+1]));
252                 
253             // Find the largest rectangle we can fill
254             $y = max($p1[1],$p2[1]) ;
255             for($yy=$maxy; $yy >= $y; --$yy) {
256                 $this->img->current_color = $colmap[$yy];
257                 $this->img->Line($p1[0],$yy,$p2[0],$yy);
258             }
259             
260             if( $p1[1] == $p2[1] ) continue; 
261
262             // Fill the rest using lines (slow...)
263             $slope = ($p2[0]-$p1[0])/($p1[1]-$p2[1]);
264             $x1 = $p1[0];
265             $x2 = $p2[0];
266             $start = $y;
267             if( $p1[1] > $p2[1] ) {
268                 while( $y >= $p2[1] ) {
269                     $x1=$slope*($start-$y)+$p1[0];
270                     $this->img->current_color = $colmap[$y];
271                     $this->img->Line($x1,$y,$x2,$y);
272                     --$y;
273                 } 
274             }
275             else {
276                 while( $y >= $p1[1] ) {
277                     $x2=$p2[0]+$slope*($start-$y);
278                     $this->img->current_color = $colmap[$y];
279                     $this->img->Line($x1,$y,$x2,$y);
280                     --$y;
281                 } 
282             }
283         }
284     }
285
286 //---------------
287 // PRIVATE METHODS      
288     // Add to the image color map the necessary colors to do the transition
289     // between the two colors using $numcolors intermediate colors
290     function GetColArray($from_color,$to_color,$arr_size,&$colors,$numcols=100) {
291         if( $arr_size==0 ) return;
292         // If color is given as text get it's corresponding r,g,b values
293         $from_color = $this->img->rgb->Color($from_color);
294         $to_color = $this->img->rgb->Color($to_color);
295                 
296         $rdelta=($to_color[0]-$from_color[0])/$numcols;
297         $gdelta=($to_color[1]-$from_color[1])/$numcols;
298         $bdelta=($to_color[2]-$from_color[2])/$numcols;
299         $colorsperstep  = $numcols/$arr_size;
300         $prevcolnum     = -1;
301         for ($i=0; $i < $arr_size; ++$i) {
302             $colnum = floor($colorsperstep*$i);
303             if ( $colnum == $prevcolnum ) 
304                 $colors[$i]     = $colidx;
305             else {
306                 $r = floor($from_color[0] + $colnum*$rdelta);
307                 $g = floor($from_color[1] + $colnum*$gdelta);
308                 $b = floor($from_color[2] + $colnum*$bdelta);
309                 $colidx = $this->img->rgb->Allocate(sprintf("#%02x%02x%02x",$r,$g,$b));
310                 $colors[$i] = $colidx;
311             }
312             $prevcolnum = $colnum;
313         }
314     }   
315 } // Class
316
317 ?>