source: trunk/client/modules/Elezioni/grafici/jpgraph_gradient.php@ 73

Last change on this file since 73 was 2, checked in by root, 15 years ago

importo il progetto

File size: 12.7 KB
RevLine 
[2]1<?php
2/*=======================================================================
3// File: JPGRAPH_GRADIENT.PHP
4// Description: Create a color gradient
5// Created: 2003-02-01
6// Ver: $Id: jpgraph_gradient.php 1091 2009-01-18 22:57:40Z ljp $
7//
8// Copyright (c) Aditus Consulting. All rights reserved.
9//========================================================================
10*/
11
12// Styles for gradient color fill
13define("GRAD_VER",1);
14define("GRAD_VERT",1);
15define("GRAD_HOR",2);
16define("GRAD_MIDHOR",3);
17define("GRAD_MIDVER",4);
18define("GRAD_CENTER",5);
19define("GRAD_WIDE_MIDVER",6);
20define("GRAD_WIDE_MIDHOR",7);
21define("GRAD_LEFT_REFLECTION",8);
22define("GRAD_RIGHT_REFLECTION",9);
23define("GRAD_RAISED_PANEL",10);
24define("GRAD_DIAGONAL",11);
25
26//===================================================
27// CLASS Gradient
28// Description: Handles gradient fills. This is to be
29// considered a "friend" class of Class Image.
30//===================================================
31class Gradient {
32 private $img=null, $numcolors=100;
33//---------------
34// CONSTRUCTOR
35 function Gradient(&$img) {
36 $this->img = $img;
37 }
38
39
40 function SetNumColors($aNum) {
41 $this->numcolors=$aNum;
42 }
43//---------------
44// PUBLIC METHODS
45 // Produce a gradient filled rectangle with a smooth transition between
46 // two colors.
47 // ($xl,$yt) Top left corner
48 // ($xr,$yb) Bottom right
49 // $from_color Starting color in gradient
50 // $to_color End color in the gradient
51 // $style Which way is the gradient oriented?
52 function FilledRectangle($xl,$yt,$xr,$yb,$from_color,$to_color,$style=1) {
53 switch( $style ) {
54 case GRAD_VER:
55 $steps = ceil(abs($xr-$xl));
56 $delta = $xr>=$xl ? 1 : -1;
57 $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors);
58 for( $i=0, $x=$xl; $i < $steps; ++$i ) {
59 $this->img->current_color = $colors[$i];
60 $this->img->Line($x,$yt,$x,$yb);
61 $x += $delta;
62 }
63 break;
64
65 case GRAD_HOR:
66 $steps = ceil(abs($yb-$yt));
67 $delta = $yb>=$yt ? 1 : -1;
68 $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors);
69 for($i=0,$y=$yt; $i < $steps; ++$i) {
70 $this->img->current_color = $colors[$i];
71 $this->img->Line($xl,$y,$xr,$y);
72 $y += $delta;
73 }
74 break;
75
76 case GRAD_MIDHOR:
77 $steps = ceil(abs($yb-$yt)/2);
78 $delta = $yb >= $yt ? 1 : -1;
79 $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors);
80 for($y=$yt, $i=0; $i < $steps; ++$i) {
81 $this->img->current_color = $colors[$i];
82 $this->img->Line($xl,$y,$xr,$y);
83 $y += $delta;
84 }
85 --$i;
86 if( abs($yb-$yt) % 2 == 1 ) --$steps;
87 for($j=0; $j < $steps; ++$j, --$i) {
88 $this->img->current_color = $colors[$i];
89 $this->img->Line($xl,$y,$xr,$y);
90 $y += $delta;
91 }
92 $this->img->Line($xl,$y,$xr,$y);
93 break;
94
95 case GRAD_MIDVER:
96 $steps = ceil(abs($xr-$xl)/2);
97 $delta = $xr>=$xl ? 1 : -1;
98 $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors);
99 for($x=$xl, $i=0; $i < $steps; ++$i) {
100 $this->img->current_color = $colors[$i];
101 $this->img->Line($x,$yb,$x,$yt);
102 $x += $delta;
103 }
104 --$i;
105 if( abs($xr-$xl) % 2 == 1 ) --$steps;
106 for($j=0; $j < $steps; ++$j, --$i) {
107 $this->img->current_color = $colors[$i];
108 $this->img->Line($x,$yb,$x,$yt);
109 $x += $delta;
110 }
111 $this->img->Line($x,$yb,$x,$yt);
112 break;
113
114 case GRAD_WIDE_MIDVER:
115 $diff = ceil(abs($xr-$xl));
116 $steps = floor(abs($diff)/3);
117 $firststep = $diff - 2*$steps ;
118 $delta = $xr >= $xl ? 1 : -1;
119 $this->GetColArray($from_color,$to_color,$firststep,$colors,$this->numcolors);
120 for($x=$xl, $i=0; $i < $firststep; ++$i) {
121 $this->img->current_color = $colors[$i];
122 $this->img->Line($x,$yb,$x,$yt);
123 $x += $delta;
124 }
125 --$i;
126 $this->img->current_color = $colors[$i];
127 for($j=0; $j< $steps; ++$j) {
128 $this->img->Line($x,$yb,$x,$yt);
129 $x += $delta;
130 }
131
132 for($j=0; $j < $steps; ++$j, --$i) {
133 $this->img->current_color = $colors[$i];
134 $this->img->Line($x,$yb,$x,$yt);
135 $x += $delta;
136 }
137 break;
138
139 case GRAD_WIDE_MIDHOR:
140 $diff = ceil(abs($yb-$yt));
141 $steps = floor(abs($diff)/3);
142 $firststep = $diff - 2*$steps ;
143 $delta = $yb >= $yt? 1 : -1;
144 $this->GetColArray($from_color,$to_color,$firststep,$colors,$this->numcolors);
145 for($y=$yt, $i=0; $i < $firststep; ++$i) {
146 $this->img->current_color = $colors[$i];
147 $this->img->Line($xl,$y,$xr,$y);
148 $y += $delta;
149 }
150 --$i;
151 $this->img->current_color = $colors[$i];
152 for($j=0; $j < $steps; ++$j) {
153 $this->img->Line($xl,$y,$xr,$y);
154 $y += $delta;
155 }
156 for($j=0; $j < $steps; ++$j, --$i) {
157 $this->img->current_color = $colors[$i];
158 $this->img->Line($xl,$y,$xr,$y);
159 $y += $delta;
160 }
161 break;
162
163 case GRAD_LEFT_REFLECTION:
164 $steps1 = ceil(0.3*abs($xr-$xl));
165 $delta = $xr>=$xl ? 1 : -1;
166
167 $from_color = $this->img->rgb->Color($from_color);
168 $adj = 1.4;
169 $m = ($adj-1.0)*(255-min(255,min($from_color[0],min($from_color[1],$from_color[2]))));
170 $from_color2 = array(min(255,$from_color[0]+$m),
171 min(255,$from_color[1]+$m), min(255,$from_color[2]+$m));
172
173 $this->GetColArray($from_color2,$to_color,$steps1,$colors,$this->numcolors);
174 $n = count($colors);
175 for($x=$xl, $i=0; $i < $steps1 && $i < $n; ++$i) {
176 $this->img->current_color = $colors[$i];
177 $this->img->Line($x,$yb,$x,$yt);
178 $x += $delta;
179 }
180 $steps2 = max(1,ceil(0.08*abs($xr-$xl)));
181 $this->img->SetColor($to_color);
182 for($j=0; $j< $steps2; ++$j) {
183 $this->img->Line($x,$yb,$x,$yt);
184 $x += $delta;
185 }
186 $steps = abs($xr-$xl)-$steps1-$steps2;
187 $this->GetColArray($to_color,$from_color,$steps,$colors,$this->numcolors);
188 $n = count($colors);
189 for($i=0; $i < $steps && $i < $n; ++$i) {
190 $this->img->current_color = $colors[$i];
191 $this->img->Line($x,$yb,$x,$yt);
192 $x += $delta;
193 }
194 break;
195
196 case GRAD_RIGHT_REFLECTION:
197 $steps1 = ceil(0.7*abs($xr-$xl));
198 $delta = $xr>=$xl ? 1 : -1;
199
200 $this->GetColArray($from_color,$to_color,$steps1,$colors,$this->numcolors);
201 $n = count($colors);
202 for($x=$xl, $i=0; $i < $steps1 && $i < $n; ++$i) {
203 $this->img->current_color = $colors[$i];
204 $this->img->Line($x,$yb,$x,$yt);
205 $x += $delta;
206 }
207 $steps2 = max(1,ceil(0.08*abs($xr-$xl)));
208 $this->img->SetColor($to_color);
209 for($j=0; $j< $steps2; ++$j) {
210 $this->img->Line($x,$yb,$x,$yt);
211 $x += $delta;
212 }
213
214 $from_color = $this->img->rgb->Color($from_color);
215 $adj = 1.4;
216 $m = ($adj-1.0)*(255-min(255,min($from_color[0],min($from_color[1],$from_color[2]))));
217 $from_color = array(min(255,$from_color[0]+$m),
218 min(255,$from_color[1]+$m), min(255,$from_color[2]+$m));
219
220 $steps = abs($xr-$xl)-$steps1-$steps2;
221 $this->GetColArray($to_color,$from_color,$steps,$colors,$this->numcolors);
222 $n = count($colors);
223 for($i=0; $i < $steps && $i < $n; ++$i) {
224 $this->img->current_color = $colors[$i];
225 $this->img->Line($x,$yb,$x,$yt);
226 $x += $delta;
227 }
228 break;
229
230 case GRAD_CENTER:
231 $steps = ceil(min(($yb-$yt)+1,($xr-$xl)+1)/2);
232 $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors);
233 $dx = ($xr-$xl)/2;
234 $dy = ($yb-$yt)/2;
235 $x=$xl;$y=$yt;$x2=$xr;$y2=$yb;
236 $n = count($colors);
237 for($x=$xl, $i=0; $x < $xl+$dx && $y < $yt+$dy && $i < $n; ++$x, ++$y, --$x2, --$y2, ++$i) {
238 $this->img->current_color = $colors[$i];
239 $this->img->Rectangle($x,$y,$x2,$y2);
240 }
241 $this->img->Line($x,$y,$x2,$y2);
242 break;
243
244 case GRAD_RAISED_PANEL:
245 // right to left
246 $steps1 = $xr-$xl;
247 $delta = $xr>=$xl ? 1 : -1;
248 $this->GetColArray($to_color,$from_color,$steps1,$colors,$this->numcolors);
249 $n = count($colors);
250 for($x=$xl, $i=0; $i < $steps1 && $i < $n; ++$i) {
251 $this->img->current_color = $colors[$i];
252 $this->img->Line($x,$yb,$x,$yt);
253 $x += $delta;
254 }
255
256 // left to right
257 $xr -= 3;
258 $xl += 3;
259 $yb -= 3;
260 $yt += 3;
261 $steps2 = $xr-$xl;
262 $delta = $xr>=$xl ? 1 : -1;
263 for($x=$xl, $j=$steps2; $j >= 0; --$j) {
264 $this->img->current_color = $colors[$j];
265 $this->img->Line($x,$yb,$x,$yt);
266 $x += $delta;
267 }
268 break;
269
270 case GRAD_DIAGONAL:
271 // use the longer dimension to determine the required number of steps.
272 // first loop draws from one corner to the mid-diagonal and the second
273 // loop draws from the mid-diagonal to the opposing corner.
274 if($xr-$xl > $yb - $yt) {
275 // width is greater than height -> use x-dimension for steps
276 $steps = $xr-$xl;
277 $delta = $xr>=$xl ? 1 : -1;
278 $this->GetColArray($from_color,$to_color,$steps*2,$colors,$this->numcolors);
279 $n = count($colors);
280
281 for($x=$xl, $i=0; $i < $steps && $i < $n; ++$i) {
282 $this->img->current_color = $colors[$i];
283 $y = $yt+($i/$steps)*($yb-$yt)*$delta;
284 $this->img->Line($x,$yt,$xl,$y);
285 $x += $delta;
286 }
287
288 for($x=$xl, $i = 0; $i < $steps && $i < $n; ++$i) {
289 $this->img->current_color = $colors[$steps+$i];
290 $y = $yt+($i/$steps)*($yb-$yt)*$delta;
291 $this->img->Line($x,$yb,$xr,$y);
292 $x += $delta;
293 }
294 } else {
295 // height is greater than width -> use y-dimension for steps
296 $steps = $yb-$yt;
297 $delta = $yb>=$yt ? 1 : -1;
298 $this->GetColArray($from_color,$to_color,$steps*2,$colors,$this->numcolors);
299 $n = count($colors);
300
301 for($y=$yt, $i=0; $i < $steps && $i < $n; ++$i) {
302 $this->img->current_color = $colors[$i];
303 $x = $xl+($i/$steps)*($xr-$xl)*$delta;
304 $this->img->Line($x,$yt,$xl,$y);
305 $y += $delta;
306 }
307
308 for($y=$yt, $i = 0; $i < $steps && $i < $n; ++$i) {
309 $this->img->current_color = $colors[$steps+$i];
310 $x = $xl+($i/$steps)*($xr-$xl)*$delta;
311 $this->img->Line($x,$yb,$xr,$y);
312 $x += $delta;
313 }
314
315 }
316 break;
317
318 default:
319 JpGraphError::RaiseL(7001,$style);
320//("Unknown gradient style (=$style).");
321 break;
322 }
323 }
324
325 // Fill a special case of a polygon with a flat bottom
326 // with a gradient. Can be used for filled line plots.
327 // Please note that this is NOT a generic gradient polygon fill
328 // routine. It assumes that the bottom is flat (like a drawing
329 // of a mountain)
330 function FilledFlatPolygon($pts,$from_color,$to_color) {
331 if( count($pts) == 0 ) return;
332
333 $maxy=$pts[1];
334 $miny=$pts[1];
335 $n = count($pts) ;
336 for( $i=0, $idx=0; $i < $n; $i += 2) {
337 $x = round($pts[$i]);
338 $y = round($pts[$i+1]);
339 $miny = min($miny,$y);
340 $maxy = max($maxy,$y);
341 }
342
343 $colors = array();
344 $this->GetColArray($from_color,$to_color,abs($maxy-$miny)+1,$colors,$this->numcolors);
345 for($i=$miny, $idx=0; $i <= $maxy; ++$i ) {
346 $colmap[$i] = $colors[$idx++];
347 }
348
349 $n = count($pts)/2 ;
350 $idx = 0 ;
351 while( $idx < $n-1 ) {
352 $p1 = array(round($pts[$idx*2]),round($pts[$idx*2+1]));
353 $p2 = array(round($pts[++$idx*2]),round($pts[$idx*2+1]));
354
355 // Find the largest rectangle we can fill
356 $y = max($p1[1],$p2[1]) ;
357 for($yy=$maxy; $yy > $y; --$yy) {
358 $this->img->current_color = $colmap[$yy];
359 $this->img->Line($p1[0],$yy,$p2[0]-1,$yy);
360 }
361
362 if( $p1[1] == $p2[1] ) continue;
363
364 // Fill the rest using lines (slow...)
365 $slope = ($p2[0]-$p1[0])/($p1[1]-$p2[1]);
366 $x1 = $p1[0];
367 $x2 = $p2[0]-1;
368 $start = $y;
369 if( $p1[1] > $p2[1] ) {
370 while( $y >= $p2[1] ) {
371 $x1=$slope*($start-$y)+$p1[0];
372 $this->img->current_color = $colmap[$y];
373 $this->img->Line($x1,$y,$x2,$y);
374 --$y;
375 }
376 }
377 else {
378 while( $y >= $p1[1] ) {
379 $x2=$p2[0]+$slope*($start-$y);
380 $this->img->current_color = $colmap[$y];
381 $this->img->Line($x1,$y,$x2,$y);
382 --$y;
383 }
384 }
385 }
386 }
387
388//---------------
389// PRIVATE METHODS
390 // Add to the image color map the necessary colors to do the transition
391 // between the two colors using $numcolors intermediate colors
392 function GetColArray($from_color,$to_color,$arr_size,&$colors,$numcols=100) {
393 if( $arr_size==0 ) return;
394 // If color is given as text get it's corresponding r,g,b values
395 $from_color = $this->img->rgb->Color($from_color);
396 $to_color = $this->img->rgb->Color($to_color);
397
398 $rdelta=($to_color[0]-$from_color[0])/$numcols;
399 $gdelta=($to_color[1]-$from_color[1])/$numcols;
400 $bdelta=($to_color[2]-$from_color[2])/$numcols;
401 $colorsperstep = $numcols/$arr_size;
402 $prevcolnum = -1;
403 $from_alpha = $from_color[3];
404 $to_alpha = $to_color[3];
405 $adelta = ( $to_alpha - $from_alpha ) / $numcols ;
406 for ($i=0; $i < $arr_size; ++$i) {
407 $colnum = floor($colorsperstep*$i);
408 if ( $colnum == $prevcolnum )
409 $colors[$i] = $colidx;
410 else {
411 $r = floor($from_color[0] + $colnum*$rdelta);
412 $g = floor($from_color[1] + $colnum*$gdelta);
413 $b = floor($from_color[2] + $colnum*$bdelta);
414 $alpha = $from_alpha + $colnum*$adelta;
415 $colidx = $this->img->rgb->Allocate(sprintf("#%02x%02x%02x",$r,$g,$b),$alpha);
416 $colors[$i] = $colidx;
417 }
418 $prevcolnum = $colnum;
419 }
420 }
421} // Class
422
423?>
Note: See TracBrowser for help on using the repository browser.