Subversion Repositories Applications.papyrus

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2150 mathias 1
<?php
2
/*=======================================================================
3
// File: 	JPGRAPH_MGRAPH.PHP
4
// Description: Class to handle multiple graphs in the same image
5
// Created: 	2006-01-15
6
// Ver:		$Id: jpgraph_mgraph.php 781 2006-10-08 08:07:47Z ljp $
7
//
8
// Copyright (c) Aditus Consulting. All rights reserved.
9
//========================================================================
10
*/
11
 
12
//=============================================================================
13
// CLASS MGraph
14
// Description: Create a container image that can hold several graph
15
//=============================================================================
16
class MGraph {
17
 
18
    protected $img=NULL;
19
    protected $iCnt=0,$iGraphs = array(); // image_handle, x, y, fx, fy, sizex, sizey
20
    protected $iFillColor='white', $iCurrentColor=0;
21
    protected $lm=0,$rm=0,$tm=0,$bm=0;
22
    protected $iDoFrame = FALSE, $iFrameColor = 'black', $iFrameWeight = 1;
23
    protected $iLineWeight = 1;
24
    protected $expired=false;
25
    protected $img_format='png',$image_quality=75;
26
    protected $iWidth=NULL,$iHeight=NULL;
27
    protected $background_image='',$background_image_center=true,
28
	$backround_image_format='',$background_image_mix=100,
29
	$background_image_y=NULL, $background_image_x=NULL;
30
 
31
    // Create a new instane of the combined graph
32
    function MGraph($aWidth=NULL,$aHeight=NULL) {
33
	$this->iWidth = $aWidth;
34
	$this->iHeight = $aHeight;
35
    }
36
 
37
    // Specify background fill color for the combined graph
38
    function SetFillColor($aColor) {
39
	$this->iFillColor = $aColor;
40
    }
41
 
42
    // Add a frame around the combined graph
43
    function SetFrame($aFlg,$aColor='black',$aWeight=1) {
44
	$this->iDoFrame = $aFlg;
45
	$this->iFrameColor = $aColor;
46
	$this->iFrameWeight = $aWeight;
47
    }
48
 
49
    // Specify a background image blend
50
    function SetBackgroundImageMix($aMix) {
51
	$this->background_image_mix = $aMix ;
52
    }
53
 
54
    // Specify a background image
55
    function SetBackgroundImage($aFileName,$aCenter_aX=NULL,$aY=NULL) {
56
	// Second argument can be either a boolean value or
57
	// a numeric
58
	$aCenter=TRUE;
59
	$aX=NULL;
60
 
61
	if( $GLOBALS['gd2'] && !USE_TRUECOLOR ) {
62
	    JpGraphError::RaiseL(12001);
63
//("You are using GD 2.x and are trying to use a background images on a non truecolor image. To use background images with GD 2.x you <b>must</b> enable truecolor by setting the USE_TRUECOLOR constant to TRUE. Due to a bug in GD 2.0.1 using any truetype fonts with truecolor images will result in very poor quality fonts.");
64
	}
65
	if( is_numeric($aCenter_aX) ) {
66
	    $aX=$aCenter_aX;
67
	}
68
 
69
	// Get extension to determine image type
70
	$e = explode('.',$aFileName);
71
	if( !$e ) {
72
	    JpGraphError::RaiseL(12002,$aFileName);
73
//('Incorrect file name for MGraph::SetBackgroundImage() : '.$aFileName.' Must have a valid image extension (jpg,gif,png) when using autodetection of image type');
74
	}
75
 
76
	$valid_formats = array('png', 'jpg', 'gif');
77
	$aImgFormat = strtolower($e[count($e)-1]);
78
	if ($aImgFormat == 'jpeg')  {
79
	    $aImgFormat = 'jpg';
80
	}
81
	elseif (!in_array($aImgFormat, $valid_formats) )  {
82
	    JpGraphError::RaiseL(12003,$aImgFormat,$aFileName);
83
//('Unknown file extension ($aImgFormat) in MGraph::SetBackgroundImage() for filename: '.$aFileName);
84
	}
85
 
86
	$this->background_image = $aFileName;
87
	$this->background_image_center=$aCenter;
88
	$this->background_image_format=$aImgFormat;
89
	$this->background_image_x = $aX;
90
	$this->background_image_y = $aY;
91
    }
92
 
93
 
94
    // Private helper function for backgound image
95
    function _loadBkgImage($aFile='') {
96
	if( $aFile == '' )
97
	    $aFile = $this->background_image;
98
 
99
	// Remove case sensitivity and setup appropriate function to create image
100
	// Get file extension. This should be the LAST '.' separated part of the filename
101
	$e = explode('.',$aFile);
102
	$ext = strtolower($e[count($e)-1]);
103
	if ($ext == "jpeg")  {
104
	    $ext = "jpg";
105
	}
106
 
107
	if( trim($ext) == '' )
108
	    $ext = 'png';  // Assume PNG if no extension specified
109
 
110
	$supported = imagetypes();
111
	if( ( $ext == 'jpg' && !($supported & IMG_JPG) ) ||
112
	    ( $ext == 'gif' && !($supported & IMG_GIF) ) ||
113
	    ( $ext == 'png' && !($supported & IMG_PNG) ) ) {
114
	    JpGraphError::RaiseL(12004,$aFile);//('The image format of your background image ('.$aFile.') is not supported in your system configuration. ');
115
	}
116
 
117
	if( $ext == "jpg" || $ext == "jpeg") {
118
	    $f = "imagecreatefromjpeg";
119
	    $ext = "jpg";
120
	}
121
	else {
122
	    $f = "imagecreatefrom".$ext;
123
	}
124
 
125
	$img = @$f($aFile);
126
	if( !$img ) {
127
	    JpGraphError::RaiseL(12005,$aFile);
128
//(" Can't read background image: '".$aFile."'");
129
	}
130
	return $img;
131
    }
132
 
133
    function _strokeBackgroundImage() {
134
	if( $this->background_image == '' )
135
	    return;
136
 
137
	$bkgimg = $this->_loadBkgImage();
138
	// Background width & Heoght
139
	$bw = imagesx($bkgimg);
140
	$bh = imagesy($bkgimg);
141
	// Canvas width and height
142
	$cw = imagesx($this->img);
143
	$ch = imagesy($this->img);
144
 
145
	if( $this->background_image_x === NULL || $this->background_image_y === NULL ) {
146
	    if( $this->background_image_center ) {
147
		// Center original image in the plot area
148
		$x = round($cw/2-$bw/2); $y = round($ch/2-$bh/2);
149
	    }
150
	    else {
151
		// Just copy the image from left corner, no resizing
152
		$x=0; $y=0;
153
	    }
154
	}
155
	else {
156
	    $x = $this->background_image_x;
157
	    $y = $this->background_image_y;
158
	}
159
	$this->_imageCp($bkgimg,$x,$y,0,0,$bw,$bh,$this->background_image_mix);
160
    }
161
 
162
    function _imageCp($aSrcImg,$x,$y,$fx,$fy,$w,$h,$mix=100) {
163
	imagecopymerge($this->img,$aSrcImg,$x,$y,$fx,$fy,$w,$h,$mix);
164
    }
165
 
166
    function _imageCreate($aWidth,$aHeight) {
167
	if( $aWidth <= 1 || $aHeight <= 1 ) {
168
	    JpGraphError::RaiseL(12006,$aWidth,$aHeight);
169
//("Illegal sizes specified for width or height when creating an image, (width=$aWidth, height=$aHeight)");
170
	}
171
	if( @$GLOBALS['gd2']==true && USE_TRUECOLOR ) {
172
	    $this->img = @imagecreatetruecolor($aWidth, $aHeight);
173
	    if( $this->img < 1 ) {
174
		JpGraphError::RaiseL(12011);
175
// die("<b>JpGraph Error:</b> Can't create truecolor image. Check that you really have GD2 library installed.");
176
	    }
177
	    ImageAlphaBlending($this->img,true);
178
	} else {
179
	    $this->img = @imagecreate($aWidth, $aHeight);
180
	    if( $this->img < 1 ) {
181
		JpGraphError::RaiseL(12012);
182
// die("<b>JpGraph Error:</b> Can't create image. Check that you really have the GD library installed.");
183
	    }
184
	}
185
    }
186
 
187
    function _polygon($p,$closed=FALSE) {
188
	if( $this->iLineWeight==0 ) return;
189
	$n=count($p);
190
	$oldx = $p[0];
191
	$oldy = $p[1];
192
	for( $i=2; $i < $n; $i+=2 ) {
193
	    imageline($this->img,$oldx,$oldy,$p[$i],$p[$i+1],$this->iCurrentColor);
194
	    $oldx = $p[$i];
195
	    $oldy = $p[$i+1];
196
	}
197
	if( $closed ) {
198
	    imageline($this->img,$p[$n*2-2],$p[$n*2-1],$p[0],$p[1],$this->iCurrentColor);
199
	}
200
    }
201
 
202
    function _filledPolygon($pts) {
203
	$n=count($pts);
204
	for($i=0; $i < $n; ++$i)
205
	    $pts[$i] = round($pts[$i]);
206
	imagefilledpolygon($this->img,$pts,count($pts)/2,$this->iCurrentColor);
207
    }
208
 
209
    function _rectangle($xl,$yu,$xr,$yl) {
210
	for($i=0; $i < $this->iLineWeight; ++$i )
211
	    $this->_polygon(array($xl+$i,$yu+$i,$xr-$i,$yu+$i,
212
				  $xr-$i,$yl-$i,$xl+$i,$yl-$i,
213
				  $xl+$i,$yu+$i));
214
    }
215
 
216
    function _filledRectangle($xl,$yu,$xr,$yl) {
217
	$this->_filledPolygon(array($xl,$yu,$xr,$yu,$xr,$yl,$xl,$yl));
218
    }
219
 
220
    function _setColor($aColor) {
221
	$this->iCurrentColor = $this->iRGB->Allocate($aColor);
222
    }
223
 
224
    function AddMix($aGraph,$x=0,$y=0,$mix=100,$fx=0,$fy=0,$w=0,$h=0) {
225
	$this->_gdImgHandle($aGraph->Stroke( _IMG_HANDLER),$x,$y,$fx=0,$fy=0,$w,$h,$mix);
226
    }
227
 
228
    function Add($aGraph,$x=0,$y=0,$fx=0,$fy=0,$w=0,$h=0) {
229
	$this->_gdImgHandle($aGraph->Stroke( _IMG_HANDLER),$x,$y,$fx=0,$fy=0,$w,$h);
230
    }
231
 
232
    function _gdImgHandle($agdCanvas,$x,$y,$fx=0,$fy=0,$w=0,$h=0,$mix=100) {
233
	if( $w == 0 )  $w = @imagesx($agdCanvas);
234
	if( $w === NULL ) {
235
	    JpGraphError::RaiseL(12007);
236
//('Argument to MGraph::Add() is not a valid GD image handle.');
237
	    return;
238
	}
239
	if( $h == 0 )  $h = @imagesy($agdCanvas);
240
	$this->iGraphs[$this->iCnt++] = array($agdCanvas,$x,$y,$fx,$fy,$w,$h,$mix);
241
    }
242
 
243
    function SetMargin($lm,$rm,$tm,$bm) {
244
	$this->lm = $lm;
245
	$this->rm = $rm;
246
	$this->tm = $tm;
247
	$this->bm = $bm;
248
    }
249
 
250
    function SetExpired($aFlg=true) {
251
	$this->expired = $aFlg;
252
    }
253
 
254
    // Generate image header
255
    function Headers() {
256
 
257
	// In case we are running from the command line with the client version of
258
	// PHP we can't send any headers.
259
	$sapi = php_sapi_name();
260
	if( $sapi == 'cli' )
261
	    return;
262
 
263
	if( headers_sent() ) {
264
 
265
	    echo "<table border=1><tr><td><font color=darkred size=4><b>JpGraph Error:</b>
266
HTTP headers have already been sent.</font></td></tr><tr><td><b>Explanation:</b><br>HTTP headers have already been sent back to the browser indicating the data as text before the library got a chance to send it's image HTTP header to this browser. This makes it impossible for the library to send back image data to the browser (since that would be interpretated as text by the browser and show up as junk text).<p>Most likely you have some text in your script before the call to <i>Graph::Stroke()</i>. If this texts gets sent back to the browser the browser will assume that all data is plain text. Look for any text, even spaces and newlines, that might have been sent back to the browser. <p>For example it is a common mistake to leave a blank line before the opening \"<b>&lt;?php</b>\".</td></tr></table>";
267
 
268
	die();
269
 
270
	}
271
 
272
	if ($this->expired) {
273
	    header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
274
	    header("Last-Modified: " . gmdate("D, d M Y H:i:s") . "GMT");
275
	    header("Cache-Control: no-cache, must-revalidate");
276
	    header("Pragma: no-cache");
277
	}
278
	header("Content-type: image/$this->img_format");
279
    }
280
 
281
    function SetImgFormat($aFormat,$aQuality=75) {
282
	$this->image_quality = $aQuality;
283
	$aFormat = strtolower($aFormat);
284
	$tst = true;
285
	$supported = imagetypes();
286
	if( $aFormat=="auto" ) {
287
	    if( $supported & IMG_PNG )
288
		$this->img_format="png";
289
	    elseif( $supported & IMG_JPG )
290
		$this->img_format="jpeg";
291
	    elseif( $supported & IMG_GIF )
292
		$this->img_format="gif";
293
	    else
294
		JpGraphError::RaiseL(12008);
295
//(" Your PHP (and GD-lib) installation does not appear to support any known graphic formats.".
296
	    return true;
297
	}
298
	else {
299
	    if( $aFormat=="jpeg" || $aFormat=="png" || $aFormat=="gif" ) {
300
		if( $aFormat=="jpeg" && !($supported & IMG_JPG) )
301
		    $tst=false;
302
		elseif( $aFormat=="png" && !($supported & IMG_PNG) )
303
		    $tst=false;
304
		elseif( $aFormat=="gif" && !($supported & IMG_GIF) )
305
		    $tst=false;
306
		else {
307
		    $this->img_format=$aFormat;
308
		    return true;
309
		}
310
	    }
311
	    else
312
		$tst=false;
313
	    if( !$tst )
314
		JpGraphError::RaiseL(12009,$aFormat);
315
//(" Your PHP installation does not support the chosen graphic format: $aFormat");
316
	}
317
    }
318
 
319
    // Stream image to browser or to file
320
    function Stream($aFile="") {
321
	$func="image".$this->img_format;
322
	if( $this->img_format=="jpeg" && $this->image_quality != null ) {
323
	    $res = @$func($this->img,$aFile,$this->image_quality);
324
	}
325
	else {
326
	    if( $aFile != "" ) {
327
		$res = @$func($this->img,$aFile);
328
	    }
329
	    else
330
		$res = @$func($this->img);
331
	}
332
	if( !$res )
333
	    JpGraphError::RaiseL(12010,$aFile);
334
//("Can't create or stream image to file $aFile Check that PHP has enough permission to write a file to the current directory.");
335
    }
336
 
337
    function Stroke($aFileName='') {
338
	// Find out the necessary size for the container image
339
	$w=0; $h=0;
340
	for($i=0; $i < $this->iCnt; ++$i ) {
341
	    $maxw = $this->iGraphs[$i][1]+$this->iGraphs[$i][5];
342
	    $maxh = $this->iGraphs[$i][2]+$this->iGraphs[$i][6];
343
	    $w = max( $w, $maxw );
344
	    $h = max( $h, $maxh );
345
	}
346
	$w += $this->lm+$this->rm;
347
	$h += $this->tm+$this->bm;
348
 
349
	// User specified width,height overrides
350
	if( $this->iWidth !== NULL ) $w = $this->iWidth;
351
	if( $this->iHeight!== NULL ) $h = $this->iHeight;
352
 
353
	$this->_imageCreate($w,$h);
354
	$this->iRGB = new RGB($this->img);
355
 
356
	$this->_setcolor($this->iFillColor);
357
	$this->_filledRectangle(0,0,$w-1,$h-1);
358
 
359
	$this->_strokeBackgroundImage();
360
 
361
	if( $this->iDoFrame ) {
362
	    $this->_setColor($this->iFrameColor);
363
	    $this->iLineWeight=$this->iFrameWeight;
364
	    $this->_rectangle(0,0,$w-1,$h-1);
365
	}
366
 
367
	// Copy all sub graphs to the container
368
	for($i=0; $i < $this->iCnt; ++$i ) {
369
	    $this->_imageCp($this->iGraphs[$i][0],
370
			    $this->iGraphs[$i][1]+$this->lm,$this->iGraphs[$i][2]+$this->tm,
371
			    $this->iGraphs[$i][3],$this->iGraphs[$i][4],
372
			    $this->iGraphs[$i][5],$this->iGraphs[$i][6],
373
			    $this->iGraphs[$i][7]);
374
	}
375
 
376
	// Output image
377
	if( $aFileName == _IMG_HANDLER ) {
378
	    return $this->img;
379
	}
380
	else {
381
	    $this->Headers();
382
	    $this->Stream($aFileName);
383
	}
384
    }
385
}
386
 
387
?>