Subversion Repositories Sites.obs-saisons.fr

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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