Linux multi-monitor fullscreen support
[ryzomcore.git] / web / public_php / admin / jpgraph / jpgraph_gradient.php
blob356657950afb244672ff76daaa3baa4b2fa59d66
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 2006/07/07 13:37:14 powles Exp $
8 //
9 // Copyright (c) Aditus Consulting. All rights reserved.
10 //========================================================================
13 // Styles for gradient color fill
14 DEFINE("GRAD_VER",1);
15 DEFINE("GRAD_VERT",1);
16 DEFINE("GRAD_HOR",2);
17 DEFINE("GRAD_MIDHOR",3);
18 DEFINE("GRAD_MIDVER",4);
19 DEFINE("GRAD_CENTER",5);
20 DEFINE("GRAD_WIDE_MIDVER",6);
21 DEFINE("GRAD_WIDE_MIDHOR",7);
22 DEFINE("GRAD_LEFT_REFLECTION",8);
23 DEFINE("GRAD_RIGHT_REFLECTION",9);
24 DEFINE("GRAD_RAISED_PANEL",10);
27 //===================================================
28 // CLASS Gradient
29 // Description: Handles gradient fills. This is to be
30 // considered a "friend" class of Class Image.
31 //===================================================
32 class Gradient {
33 var $img=null;
34 var $numcolors=100;
35 //---------------
36 // CONSTRUCTOR
37 function __construct(&$img) {
38 $this->img = &$img;
42 function SetNumColors($aNum) {
43 $this->numcolors=$aNum;
45 //---------------
46 // PUBLIC METHODS
47 // Produce a gradient filled rectangle with a smooth transition between
48 // two colors.
49 // ($xl,$yt) Top left corner
50 // ($xr,$yb) Bottom right
51 // $from_color Starting color in gradient
52 // $to_color End color in the gradient
53 // $style Which way is the gradient oriented?
54 function FilledRectangle($xl,$yt,$xr,$yb,$from_color,$to_color,$style=1) {
55 switch( $style ) {
56 case GRAD_VER:
57 $steps = round(abs($xr-$xl));
58 $delta = $xr>=$xl ? 1 : -1;
59 $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors);
60 for( $i=0, $x=$xl; $i < $steps; ++$i ) {
61 $this->img->current_color = $colors[$i];
62 $this->img->Line($x,$yt,$x,$yb);
63 $x += $delta;
65 break;
67 case GRAD_HOR:
68 $steps = round(abs($yb-$yt));
69 $delta = $yb>=$yt ? 1 : -1;
70 $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors);
71 for($i=0,$y=$yt; $i < $steps; ++$i) {
72 $this->img->current_color = $colors[$i];
73 $this->img->Line($xl,$y,$xr,$y);
74 $y += $delta;
76 break;
78 case GRAD_MIDHOR:
79 $steps = round(abs($yb-$yt)/2);
80 $delta = $yb >= $yt ? 1 : -1;
81 $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors);
82 for($y=$yt, $i=0; $i < $steps; ++$i) {
83 $this->img->current_color = $colors[$i];
84 $this->img->Line($xl,$y,$xr,$y);
85 $y += $delta;
87 --$i;
88 if( abs($yb-$yt) % 2 == 1 ) --$steps;
89 for($j=0; $j < $steps; ++$j, --$i) {
90 $this->img->current_color = $colors[$i];
91 $this->img->Line($xl,$y,$xr,$y);
92 $y += $delta;
94 $this->img->Line($xl,$y,$xr,$y);
95 break;
97 case GRAD_MIDVER:
98 $steps = round(abs($xr-$xl)/2);
99 $delta = $xr>=$xl ? 1 : -1;
100 $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors);
101 for($x=$xl, $i=0; $i < $steps; ++$i) {
102 $this->img->current_color = $colors[$i];
103 $this->img->Line($x,$yb,$x,$yt);
104 $x += $delta;
106 --$i;
107 if( abs($xr-$xl) % 2 == 1 ) --$steps;
108 for($j=0; $j < $steps; ++$j, --$i) {
109 $this->img->current_color = $colors[$i];
110 $this->img->Line($x,$yb,$x,$yt);
111 $x += $delta;
113 $this->img->Line($x,$yb,$x,$yt);
114 break;
116 case GRAD_WIDE_MIDVER:
117 $diff = round(abs($xr-$xl));
118 $steps = floor(abs($diff)/3);
119 $firststep = $diff - 2*$steps ;
120 $delta = $xr >= $xl ? 1 : -1;
121 $this->GetColArray($from_color,$to_color,$firststep,$colors,$this->numcolors);
122 for($x=$xl, $i=0; $i < $firststep; ++$i) {
123 $this->img->current_color = $colors[$i];
124 $this->img->Line($x,$yb,$x,$yt);
125 $x += $delta;
127 --$i;
128 $this->img->current_color = $colors[$i];
129 for($j=0; $j< $steps; ++$j) {
130 $this->img->Line($x,$yb,$x,$yt);
131 $x += $delta;
134 for($j=0; $j < $steps; ++$j, --$i) {
135 $this->img->current_color = $colors[$i];
136 $this->img->Line($x,$yb,$x,$yt);
137 $x += $delta;
139 break;
141 case GRAD_WIDE_MIDHOR:
142 $diff = round(abs($yb-$yt));
143 $steps = floor(abs($diff)/3);
144 $firststep = $diff - 2*$steps ;
145 $delta = $yb >= $yt? 1 : -1;
146 $this->GetColArray($from_color,$to_color,$firststep,$colors,$this->numcolors);
147 for($y=$yt, $i=0; $i < $firststep; ++$i) {
148 $this->img->current_color = $colors[$i];
149 $this->img->Line($xl,$y,$xr,$y);
150 $y += $delta;
152 --$i;
153 $this->img->current_color = $colors[$i];
154 for($j=0; $j < $steps; ++$j) {
155 $this->img->Line($xl,$y,$xr,$y);
156 $y += $delta;
158 for($j=0; $j < $steps; ++$j, --$i) {
159 $this->img->current_color = $colors[$i];
160 $this->img->Line($xl,$y,$xr,$y);
161 $y += $delta;
163 break;
165 case GRAD_LEFT_REFLECTION:
166 $steps1 = round(0.3*abs($xr-$xl));
167 $delta = $xr>=$xl ? 1 : -1;
169 $from_color = $this->img->rgb->Color($from_color);
170 $adj = 1.4;
171 $m = ($adj-1.0)*(255-min(255,min($from_color[0],min($from_color[1],$from_color[2]))));
172 $from_color2 = array(min(255,$from_color[0]+$m),
173 min(255,$from_color[1]+$m), min(255,$from_color[2]+$m));
175 $this->GetColArray($from_color2,$to_color,$steps1,$colors,$this->numcolors);
176 $n = count($colors);
177 for($x=$xl, $i=0; $i < $steps1 && $i < $n; ++$i) {
178 $this->img->current_color = $colors[$i];
179 $this->img->Line($x,$yb,$x,$yt);
180 $x += $delta;
182 $steps2 = max(1,round(0.08*abs($xr-$xl)));
183 $this->img->SetColor($to_color);
184 for($j=0; $j< $steps2; ++$j) {
185 $this->img->Line($x,$yb,$x,$yt);
186 $x += $delta;
188 $steps = abs($xr-$xl)-$steps1-$steps2;
189 $this->GetColArray($to_color,$from_color,$steps,$colors,$this->numcolors);
190 $n = count($colors);
191 for($i=0; $i < $steps && $i < $n; ++$i) {
192 $this->img->current_color = $colors[$i];
193 $this->img->Line($x,$yb,$x,$yt);
194 $x += $delta;
196 break;
198 case GRAD_RIGHT_REFLECTION:
199 $steps1 = round(0.7*abs($xr-$xl));
200 $delta = $xr>=$xl ? 1 : -1;
202 $this->GetColArray($from_color,$to_color,$steps1,$colors,$this->numcolors);
203 $n = count($colors);
204 for($x=$xl, $i=0; $i < $steps1 && $i < $n; ++$i) {
205 $this->img->current_color = $colors[$i];
206 $this->img->Line($x,$yb,$x,$yt);
207 $x += $delta;
209 $steps2 = max(1,round(0.08*abs($xr-$xl)));
210 $this->img->SetColor($to_color);
211 for($j=0; $j< $steps2; ++$j) {
212 $this->img->Line($x,$yb,$x,$yt);
213 $x += $delta;
216 $from_color = $this->img->rgb->Color($from_color);
217 $adj = 1.4;
218 $m = ($adj-1.0)*(255-min(255,min($from_color[0],min($from_color[1],$from_color[2]))));
219 $from_color = array(min(255,$from_color[0]+$m),
220 min(255,$from_color[1]+$m), min(255,$from_color[2]+$m));
222 $steps = abs($xr-$xl)-$steps1-$steps2;
223 $this->GetColArray($to_color,$from_color,$steps,$colors,$this->numcolors);
224 $n = count($colors);
225 for($i=0; $i < $steps && $i < $n; ++$i) {
226 $this->img->current_color = $colors[$i];
227 $this->img->Line($x,$yb,$x,$yt);
228 $x += $delta;
230 break;
232 case GRAD_CENTER:
233 $steps = ceil(min(($yb-$yt)+1,($xr-$xl)+1)/2);
234 $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors);
235 $dx = ($xr-$xl)/2;
236 $dy = ($yb-$yt)/2;
237 $x=$xl;$y=$yt;$x2=$xr;$y2=$yb;
238 $n = count($colors);
239 for($x=$xl, $i=0; $x < $xl+$dx && $y < $yt+$dy && $i < $n; ++$x, ++$y, --$x2, --$y2, ++$i) {
240 $this->img->current_color = $colors[$i];
241 $this->img->Rectangle($x,$y,$x2,$y2);
243 $this->img->Line($x,$y,$x2,$y2);
244 break;
246 case GRAD_RAISED_PANEL:
247 // right to left
248 $steps1 = $xr-$xl;
249 $delta = $xr>=$xl ? 1 : -1;
250 $this->GetColArray($to_color,$from_color,$steps1,$colors,$this->numcolors);
251 $n = count($colors);
252 for($x=$xl, $i=0; $i < $steps1 && $i < $n; ++$i) {
253 $this->img->current_color = $colors[$i];
254 $this->img->Line($x,$yb,$x,$yt);
255 $x += $delta;
258 // left to right
259 $xr -= 3;
260 $xl += 3;
261 $yb -= 3;
262 $yt += 3;
263 $steps2 = $xr-$xl;
264 $delta = $xr>=$xl ? 1 : -1;
265 for($x=$xl, $j=$steps2; $j >= 0; --$j) {
266 $this->img->current_color = $colors[$j];
267 $this->img->Line($x,$yb,$x,$yt);
268 $x += $delta;
270 break;
272 default:
273 JpGraphError::RaiseL(7001,$style);
274 //("Unknown gradient style (=$style).");
275 break;
279 // Fill a special case of a polygon with a flat bottom
280 // with a gradient. Can be used for filled line plots.
281 // Please note that this is NOT a generic gradient polygon fill
282 // routine. It assumes that the bottom is flat (like a drawing
283 // of a mountain)
284 function FilledFlatPolygon($pts,$from_color,$to_color) {
285 if( count($pts) == 0 ) return;
287 $maxy=$pts[1];
288 $miny=$pts[1];
289 $n = count($pts) ;
290 for( $i=0, $idx=0; $i < $n; $i += 2) {
291 $x = round($pts[$i]);
292 $y = round($pts[$i+1]);
293 $miny = min($miny,$y);
294 $maxy = max($maxy,$y);
297 $colors = array();
298 $this->GetColArray($from_color,$to_color,abs($maxy-$miny)+1,$colors,$this->numcolors);
299 for($i=$miny, $idx=0; $i <= $maxy; ++$i ) {
300 $colmap[$i] = $colors[$idx++];
303 $n = count($pts)/2 ;
304 $idx = 0 ;
305 while( $idx < $n-1 ) {
306 $p1 = array(round($pts[$idx*2]),round($pts[$idx*2+1]));
307 $p2 = array(round($pts[++$idx*2]),round($pts[$idx*2+1]));
309 // Find the largest rectangle we can fill
310 $y = max($p1[1],$p2[1]) ;
311 for($yy=$maxy; $yy > $y; --$yy) {
312 $this->img->current_color = $colmap[$yy];
313 $this->img->Line($p1[0],$yy,$p2[0]-1,$yy);
316 if( $p1[1] == $p2[1] ) continue;
318 // Fill the rest using lines (slow...)
319 $slope = ($p2[0]-$p1[0])/($p1[1]-$p2[1]);
320 $x1 = $p1[0];
321 $x2 = $p2[0]; //-1;
322 $start = $y;
323 if( $p1[1] > $p2[1] ) {
324 while( $y >= $p2[1] ) {
325 $x1=$slope*($start-$y)+$p1[0];
326 $this->img->current_color = $colmap[$y];
327 $this->img->Line($x1,$y,$x2,$y);
328 --$y;
331 else {
332 while( $y >= $p1[1] ) {
333 $x2=$p2[0]+$slope*($start-$y);
334 $this->img->current_color = $colmap[$y];
335 $this->img->Line($x1,$y,$x2,$y);
336 --$y;
342 //---------------
343 // PRIVATE METHODS
344 // Add to the image color map the necessary colors to do the transition
345 // between the two colors using $numcolors intermediate colors
346 function GetColArray($from_color,$to_color,$arr_size,&$colors,$numcols=100) {
347 if( $arr_size==0 ) return;
348 // If color is given as text get it's corresponding r,g,b values
349 $from_color = $this->img->rgb->Color($from_color);
350 $to_color = $this->img->rgb->Color($to_color);
352 $rdelta=($to_color[0]-$from_color[0])/$numcols;
353 $gdelta=($to_color[1]-$from_color[1])/$numcols;
354 $bdelta=($to_color[2]-$from_color[2])/$numcols;
355 $colorsperstep = $numcols/$arr_size;
356 $prevcolnum = -1;
357 $from_alpha = $from_color[3];
358 $to_alpha = $to_color[3];
359 $adelta = ( $to_alpha - $from_alpha ) / $numcols ;
360 for ($i=0; $i < $arr_size; ++$i) {
361 $colnum = floor($colorsperstep*$i);
362 if ( $colnum == $prevcolnum )
363 $colors[$i] = $colidx;
364 else {
365 $r = floor($from_color[0] + $colnum*$rdelta);
366 $g = floor($from_color[1] + $colnum*$gdelta);
367 $b = floor($from_color[2] + $colnum*$bdelta);
368 $alpha = $from_alpha + $colnum*$adelta;
369 $colidx = $this->img->rgb->Allocate(sprintf("#%02x%02x%02x",$r,$g,$b),$alpha);
370 $colors[$i] = $colidx;
372 $prevcolnum = $colnum;
375 } // Class