PageRenderTime 70ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 2ms

/TEMPLATE/Reports/class/pchart2/class/pDraw.class.php

https://bitbucket.org/Lahiru_LCB/sep_wd_07
PHP | 5363 lines | 4329 code | 922 blank | 112 comment | 2009 complexity | 13ffc408e253cc133be311d5c20035d7 MD5 | raw file
Possible License(s): LGPL-3.0, GPL-3.0, LGPL-2.1

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /*
  3. pDraw - class extension with drawing methods
  4. Version : 2.1.1
  5. Made by : Jean-Damien POGOLOTTI
  6. Last Update : 28/03/11
  7. This file can be distributed under the license you can find at :
  8. http://www.pchart.net/license
  9. You can find the whole class documentation on the pChart web site.
  10. */
  11. define("DIRECTION_VERTICAL" , 690001);
  12. define("DIRECTION_HORIZONTAL" , 690002);
  13. define("SCALE_POS_LEFTRIGHT" , 690101);
  14. define("SCALE_POS_TOPBOTTOM" , 690102);
  15. define("SCALE_MODE_FLOATING" , 690201);
  16. define("SCALE_MODE_START0" , 690202);
  17. define("SCALE_MODE_ADDALL" , 690203);
  18. define("SCALE_MODE_ADDALL_START0" , 690204);
  19. define("SCALE_MODE_MANUAL" , 690205);
  20. define("SCALE_SKIP_NONE" , 690301);
  21. define("SCALE_SKIP_SAME" , 690302);
  22. define("SCALE_SKIP_NUMBERS" , 690303);
  23. define("TEXT_ALIGN_TOPLEFT" , 690401);
  24. define("TEXT_ALIGN_TOPMIDDLE" , 690402);
  25. define("TEXT_ALIGN_TOPRIGHT" , 690403);
  26. define("TEXT_ALIGN_MIDDLELEFT" , 690404);
  27. define("TEXT_ALIGN_MIDDLEMIDDLE" , 690405);
  28. define("TEXT_ALIGN_MIDDLERIGHT" , 690406);
  29. define("TEXT_ALIGN_BOTTOMLEFT" , 690407);
  30. define("TEXT_ALIGN_BOTTOMMIDDLE" , 690408);
  31. define("TEXT_ALIGN_BOTTOMRIGHT" , 690409);
  32. define("POSITION_TOP" , 690501);
  33. define("POSITION_BOTTOM" , 690502);
  34. define("LABEL_POS_LEFT" , 690601);
  35. define("LABEL_POS_CENTER" , 690602);
  36. define("LABEL_POS_RIGHT" , 690603);
  37. define("LABEL_POS_TOP" , 690604);
  38. define("LABEL_POS_BOTTOM" , 690605);
  39. define("LABEL_POS_INSIDE" , 690606);
  40. define("LABEL_POS_OUTSIDE" , 690607);
  41. define("ORIENTATION_HORIZONTAL" , 690701);
  42. define("ORIENTATION_VERTICAL" , 690702);
  43. define("LEGEND_NOBORDER" , 690800);
  44. define("LEGEND_BOX" , 690801);
  45. define("LEGEND_ROUND" , 690802);
  46. define("LEGEND_VERTICAL" , 690901);
  47. define("LEGEND_HORIZONTAL" , 690902);
  48. define("LEGEND_FAMILY_BOX" , 691051);
  49. define("LEGEND_FAMILY_CIRCLE" , 691052);
  50. define("LEGEND_FAMILY_LINE" , 691053);
  51. define("DISPLAY_AUTO" , 691001);
  52. define("DISPLAY_MANUAL" , 691002);
  53. define("LABELING_ALL" , 691011);
  54. define("LABELING_DIFFERENT" , 691012);
  55. define("BOUND_MIN" , 691021);
  56. define("BOUND_MAX" , 691022);
  57. define("BOUND_BOTH" , 691023);
  58. define("BOUND_LABEL_POS_TOP" , 691031);
  59. define("BOUND_LABEL_POS_BOTTOM" , 691032);
  60. define("BOUND_LABEL_POS_AUTO" , 691033);
  61. define("CAPTION_LEFT_TOP" , 691041);
  62. define("CAPTION_RIGHT_BOTTOM" , 691042);
  63. define("GRADIENT_SIMPLE" , 691051);
  64. define("GRADIENT_EFFECT_CAN" , 691052);
  65. define("LABEL_TITLE_NOBACKGROUND" , 691061);
  66. define("LABEL_TITLE_BACKGROUND" , 691062);
  67. define("LABEL_POINT_NONE" , 691071);
  68. define("LABEL_POINT_CIRCLE" , 691072);
  69. define("LABEL_POINT_BOX" , 691073);
  70. define("PI" , 3.14159265);
  71. define("ALL" , 69);
  72. define("NONE" , 31);
  73. define("AUTO" , 690000);
  74. define("OUT_OF_SIGHT" , -10000000000000);
  75. class pDraw
  76. {
  77. /* Returns the number of drawable series */
  78. function countDrawableSeries()
  79. {
  80. $Results = 0;
  81. $Data = $this->DataSet->getData();
  82. foreach($Data["Series"] as $SerieName => $Serie)
  83. { if ( $Serie["isDrawable"] == TRUE && $SerieName != $Data["Abscissa"] ) { $Results++; } }
  84. return($Results);
  85. }
  86. /* Fix box coordinates */
  87. function fixBoxCoordinates($Xa,$Ya,$Xb,$Yb)
  88. {
  89. $X1 = min($Xa,$Xb); $Y1 = min($Ya,$Yb);
  90. $X2 = max($Xa,$Xb); $Y2 = max($Ya,$Yb);
  91. return(array($X1,$Y1,$X2,$Y2));
  92. }
  93. /* Draw a polygon */
  94. function drawPolygon($Points,$Format="")
  95. {
  96. $R = isset($Format["R"]) ? $Format["R"] : 0;
  97. $G = isset($Format["G"]) ? $Format["G"] : 0;
  98. $B = isset($Format["B"]) ? $Format["B"] : 0;
  99. $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100;
  100. $NoBorder = isset($Format["NoBorder"]) ? $Format["NoBorder"] : FALSE;
  101. $BorderR = isset($Format["BorderR"]) ? $Format["BorderR"] : $R;
  102. $BorderG = isset($Format["BorderG"]) ? $Format["BorderG"] : $G;
  103. $BorderB = isset($Format["BorderB"]) ? $Format["BorderB"] : $B;
  104. $BorderAlpha = isset($Format["Alpha"]) ? $Format["Alpha"] : $Alpha / 2;
  105. $Surrounding = isset($Format["Surrounding"]) ? $Format["Surrounding"] : NULL;
  106. $SkipX = isset($Format["SkipX"]) ? $Format["SkipX"] : OUT_OF_SIGHT;
  107. $SkipY = isset($Format["SkipY"]) ? $Format["SkipY"] : OUT_OF_SIGHT;
  108. /* Calling the ImageFilledPolygon() function over the $Points array will round it */
  109. $Backup = $Points;
  110. if ( $Surrounding != NULL ) { $BorderR = $R+$Surrounding; $BorderG = $G+$Surrounding; $BorderB = $B+$Surrounding; }
  111. if ( $SkipX != OUT_OF_SIGHT ) { $SkipX = floor($SkipX); }
  112. if ( $SkipY != OUT_OF_SIGHT ) { $SkipY = floor($SkipY); }
  113. $RestoreShadow = $this->Shadow;
  114. if ( $this->Shadow && $this->ShadowX != 0 && $this->ShadowY != 0 )
  115. {
  116. $this->Shadow = FALSE;
  117. for($i=0;$i<=count($Points)-1;$i=$i+2)
  118. { $Shadow[] = $Points[$i] + $this->ShadowX; $Shadow[] = $Points[$i+1] + $this->ShadowY; }
  119. $this->drawPolygon($Shadow,array("R"=>$this->ShadowR,"G"=>$this->ShadowG,"B"=>$this->ShadowB,"Alpha"=>$this->Shadowa,"NoBorder"=>TRUE));
  120. }
  121. $FillColor = $this->allocateColor($this->Picture,$R,$G,$B,$Alpha);
  122. if ( count($Points) >= 6 )
  123. { ImageFilledPolygon($this->Picture,$Points,count($Points)/2,$FillColor); }
  124. if ( !$NoBorder )
  125. {
  126. $Points = $Backup;
  127. $BorderSettings = array("R"=>$BorderR,"G"=>$BorderG,"B"=>$BorderB,"Alpha"=>$BorderAlpha);
  128. for($i=0;$i<=count($Points)-1;$i=$i+2)
  129. {
  130. if ( isset($Points[$i+2]) )
  131. {
  132. if ( !($Points[$i] == $Points[$i+2] && $Points[$i] == $SkipX ) && !($Points[$i+1] == $Points[$i+3] && $Points[$i+1] == $SkipY ) )
  133. $this->drawLine($Points[$i],$Points[$i+1],$Points[$i+2],$Points[$i+3],$BorderSettings);
  134. }
  135. else
  136. {
  137. if ( !($Points[$i] == $Points[0] && $Points[$i] == $SkipX ) && !($Points[$i+1] == $Points[1] && $Points[$i+1] == $SkipY ) )
  138. $this->drawLine($Points[$i],$Points[$i+1],$Points[0],$Points[1],$BorderSettings);
  139. }
  140. }
  141. }
  142. $this->Shadow = $RestoreShadow;
  143. }
  144. /* Apply AALias correction to the rounded box boundaries */
  145. function offsetCorrection($Value,$Mode)
  146. {
  147. $Value = round($Value,1);
  148. if ( $Value == 0 && $Mode == 1 ) { return(.9); }
  149. if ( $Value == 0 ) { return(0); }
  150. if ( $Mode == 1)
  151. { if ( $Value == 1 ) { return(.9); }; if ( $Value == .1 ) { return(.9); }; if ( $Value == .2 ) { return(.8); }; if ( $Value == .3 ) { return(.8); }; if ( $Value == .4 ) { return(.7); }; if ( $Value == .5 ) { return(.5); }; if ( $Value == .6 ) { return(.8); }; if ( $Value == .7 ) { return(.7); }; if ( $Value == .8 ) { return(.6); }; if ( $Value == .9 ) { return(.9); }; }
  152. if ( $Mode == 2)
  153. { if ( $Value == 1 ) { return(.9); }; if ( $Value == .1 ) { return(.1); }; if ( $Value == .2 ) { return(.2); }; if ( $Value == .3 ) { return(.3); }; if ( $Value == .4 ) { return(.4); }; if ( $Value == .5 ) { return(.5); }; if ( $Value == .6 ) { return(.8); }; if ( $Value == .7 ) { return(.7); }; if ( $Value == .8 ) { return(.8); }; if ( $Value == .9 ) { return(.9); }; }
  154. if ( $Mode == 3)
  155. { if ( $Value == 1 ) { return(.1); }; if ( $Value == .1 ) { return(.1); }; if ( $Value == .2 ) { return(.2); }; if ( $Value == .3 ) { return(.3); }; if ( $Value == .4 ) { return(.4); }; if ( $Value == .5 ) { return(.9); }; if ( $Value == .6 ) { return(.6); }; if ( $Value == .7 ) { return(.7); }; if ( $Value == .8 ) { return(.4); }; if ( $Value == .9 ) { return(.5); }; }
  156. if ( $Mode == 4)
  157. { if ( $Value == 1 ) { return(-1); }; if ( $Value == .1 ) { return(.1); }; if ( $Value == .2 ) { return(.2); }; if ( $Value == .3 ) { return(.3); }; if ( $Value == .4 ) { return(.1); }; if ( $Value == .5 ) { return(-.1); }; if ( $Value == .6 ) { return(.8); }; if ( $Value == .7 ) { return(.1); }; if ( $Value == .8 ) { return(.1); }; if ( $Value == .9 ) { return(.1); }; }
  158. }
  159. /* Draw a rectangle with rounded corners */
  160. function drawRoundedRectangle($X1,$Y1,$X2,$Y2,$Radius,$Format="")
  161. {
  162. $R = isset($Format["R"]) ? $Format["R"] : 0;
  163. $G = isset($Format["G"]) ? $Format["G"] : 0;
  164. $B = isset($Format["B"]) ? $Format["B"] : 0;
  165. $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100;
  166. list($X1,$Y1,$X2,$Y2) = $this->fixBoxCoordinates($X1,$Y1,$X2,$Y2);
  167. if ( $X2 - $X1 < $Radius ) { $Radius = floor((($X2-$X1))/2); }
  168. if ( $Y2 - $Y1 < $Radius ) { $Radius = floor((($Y2-$Y1))/2); }
  169. $Color = array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"NoBorder"=>TRUE);
  170. if ( $Radius <= 0 ) { $this->drawRectangle($X1,$Y1,$X2,$Y2,$Color); return(0); }
  171. if ( $this->Antialias )
  172. {
  173. $this->drawLine($X1+$Radius,$Y1,$X2-$Radius,$Y1,$Color);
  174. $this->drawLine($X2,$Y1+$Radius,$X2,$Y2-$Radius,$Color);
  175. $this->drawLine($X2-$Radius,$Y2,$X1+$Radius,$Y2,$Color);
  176. $this->drawLine($X1,$Y1+$Radius,$X1,$Y2-$Radius,$Color);
  177. }
  178. else
  179. {
  180. $Color = $this->allocateColor($this->Picture,$R,$G,$B,$Alpha);
  181. imageline($this->Picture,$X1+$Radius,$Y1,$X2-$Radius,$Y1,$Color);
  182. imageline($this->Picture,$X2,$Y1+$Radius,$X2,$Y2-$Radius,$Color);
  183. imageline($this->Picture,$X2-$Radius,$Y2,$X1+$Radius,$Y2,$Color);
  184. imageline($this->Picture,$X1,$Y1+$Radius,$X1,$Y2-$Radius,$Color);
  185. }
  186. $Step = 360 / (2 * PI * $Radius);
  187. for($i=0;$i<=90;$i=$i+$Step)
  188. {
  189. $X = cos(($i+180)*PI/180) * $Radius + $X1 + $Radius;
  190. $Y = sin(($i+180)*PI/180) * $Radius + $Y1 + $Radius;
  191. $this->drawAntialiasPixel($X,$Y,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha));
  192. $X = cos(($i+90)*PI/180) * $Radius + $X1 + $Radius;
  193. $Y = sin(($i+90)*PI/180) * $Radius + $Y2 - $Radius;
  194. $this->drawAntialiasPixel($X,$Y,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha));
  195. $X = cos($i*PI/180) * $Radius + $X2 - $Radius;
  196. $Y = sin($i*PI/180) * $Radius + $Y2 - $Radius;
  197. $this->drawAntialiasPixel($X,$Y,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha));
  198. $X = cos(($i+270)*PI/180) * $Radius + $X2 - $Radius;
  199. $Y = sin(($i+270)*PI/180) * $Radius + $Y1 + $Radius;
  200. $this->drawAntialiasPixel($X,$Y,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha));
  201. }
  202. }
  203. /* Draw a rectangle with rounded corners */
  204. function drawRoundedFilledRectangle($X1,$Y1,$X2,$Y2,$Radius,$Format="")
  205. {
  206. $R = isset($Format["R"]) ? $Format["R"] : 0;
  207. $G = isset($Format["G"]) ? $Format["G"] : 0;
  208. $B = isset($Format["B"]) ? $Format["B"] : 0;
  209. $BorderR = isset($Format["BorderR"]) ? $Format["BorderR"] : -1;
  210. $BorderG = isset($Format["BorderG"]) ? $Format["BorderG"] : -1;
  211. $BorderB = isset($Format["BorderB"]) ? $Format["BorderB"] : -1;
  212. $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100;
  213. $Surrounding = isset($Format["Surrounding"]) ? $Format["Surrounding"] : NULL;
  214. /* Temporary fix for AA issue */
  215. $Y1 = floor($Y1); $Y2 = floor($Y2); $X1 = floor($X1); $X2 = floor($X2);
  216. if ( $Surrounding != NULL ) { $BorderR = $R+$Surrounding; $BorderG = $G+$Surrounding; $BorderB = $B+$Surrounding; }
  217. if ( $BorderR == -1 ) { $BorderR = $R; $BorderG = $G; $BorderB = $B; }
  218. list($X1,$Y1,$X2,$Y2) = $this->fixBoxCoordinates($X1,$Y1,$X2,$Y2);
  219. if ( $X2 - $X1 < $Radius*2 ) { $Radius = floor((($X2-$X1))/4); }
  220. if ( $Y2 - $Y1 < $Radius*2 ) { $Radius = floor((($Y2-$Y1))/4); }
  221. $RestoreShadow = $this->Shadow;
  222. if ( $this->Shadow && $this->ShadowX != 0 && $this->ShadowY != 0 )
  223. {
  224. $this->Shadow = FALSE;
  225. $this->drawRoundedFilledRectangle($X1+$this->ShadowX,$Y1+$this->ShadowY,$X2+$this->ShadowX,$Y2+$this->ShadowY,$Radius,array("R"=>$this->ShadowR,"G"=>$this->ShadowG,"B"=>$this->ShadowB,"Alpha"=>$this->Shadowa));
  226. }
  227. $Color = array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"NoBorder"=>TRUE);
  228. if ( $Radius <= 0 ) { $this->drawFilledRectangle($X1,$Y1,$X2,$Y2,$Color); return(0); }
  229. $YTop = $Y1+$Radius;
  230. $YBottom = $Y2-$Radius;
  231. $Step = 360 / (2 * PI * $Radius);
  232. $Positions = ""; $Radius--; $MinY = ""; $MaxY = "";
  233. for($i=0;$i<=90;$i=$i+$Step)
  234. {
  235. $Xp1 = cos(($i+180)*PI/180) * $Radius + $X1 + $Radius;
  236. $Xp2 = cos(((90-$i)+270)*PI/180) * $Radius + $X2 - $Radius;
  237. $Yp = floor(sin(($i+180)*PI/180) * $Radius + $YTop);
  238. if ( $MinY == "" || $Yp > $MinY ) { $MinY = $Yp; }
  239. if ( $Xp2 >= floor($X2) ) { $Xp2--; }
  240. $Xp1++;
  241. if ( !isset($Positions[$Yp]) )
  242. { $Positions[$Yp]["X1"] = $Xp1; $Positions[$Yp]["X2"] = $Xp2; }
  243. else
  244. { $Positions[$Yp]["X1"] = ($Positions[$Yp]["X1"]+$Xp1)/2; $Positions[$Yp]["X2"] = ($Positions[$Yp]["X2"]+$Xp2)/2; }
  245. $Xp1 = cos(($i+90)*PI/180) * $Radius + $X1 + $Radius;
  246. $Xp2 = cos((90-$i)*PI/180) * $Radius + $X2 - $Radius;
  247. $Yp = floor(sin(($i+90)*PI/180) * $Radius + $YBottom);
  248. if ( $MaxY == "" || $Yp < $MaxY ) { $MaxY = $Yp; }
  249. if ( $Xp2 >= floor($X2) ) { $Xp2--; }
  250. $Xp1++;
  251. if ( !isset($Positions[$Yp]) )
  252. { $Positions[$Yp]["X1"] = $Xp1; $Positions[$Yp]["X2"] = $Xp2; }
  253. else
  254. { $Positions[$Yp]["X1"] = ($Positions[$Yp]["X1"]+$Xp1)/2; $Positions[$Yp]["X2"] = ($Positions[$Yp]["X2"]+$Xp2)/2; }
  255. }
  256. $ManualColor = $this->allocateColor($this->Picture,$R,$G,$B,$Alpha);
  257. foreach($Positions as $Yp => $Bounds)
  258. {
  259. $X1 = $Bounds["X1"]; $X1Dec = $this->getFirstDecimal($X1); if ( $X1Dec != 0 ) { $X1 = floor($X1)+1; }
  260. $X2 = $Bounds["X2"]; $X2Dec = $this->getFirstDecimal($X2); if ( $X2Dec != 0 ) { $X2 = floor($X2)-1; }
  261. imageline($this->Picture,$X1,$Yp,$X2,$Yp,$ManualColor);
  262. }
  263. $this->drawFilledRectangle($X1,$MinY+1,floor($X2),$MaxY-1,$Color);
  264. $Radius++;
  265. $this->drawRoundedRectangle($X1,$Y1,$X2+1,$Y2-1,$Radius,array("R"=>$BorderR,"G"=>$BorderG,"B"=>$BorderB,"Alpha"=>$Alpha));
  266. $this->Shadow = $RestoreShadow;
  267. }
  268. /* Draw a rectangle with rounded corners */
  269. function drawRoundedFilledRectangle_deprecated($X1,$Y1,$X2,$Y2,$Radius,$Format="")
  270. {
  271. $R = isset($Format["R"]) ? $Format["R"] : 0;
  272. $G = isset($Format["G"]) ? $Format["G"] : 0;
  273. $B = isset($Format["B"]) ? $Format["B"] : 0;
  274. $BorderR = isset($Format["BorderR"]) ? $Format["BorderR"] : -1;
  275. $BorderG = isset($Format["BorderG"]) ? $Format["BorderG"] : -1;
  276. $BorderB = isset($Format["BorderB"]) ? $Format["BorderB"] : -1;
  277. $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100;
  278. $Surrounding = isset($Format["Surrounding"]) ? $Format["Surrounding"] : NULL;
  279. if ( $Surrounding != NULL ) { $BorderR = $R+$Surrounding; $BorderG = $G+$Surrounding; $BorderB = $B+$Surrounding; }
  280. if ( $BorderR == -1 ) { $BorderR = $R; $BorderG = $G; $BorderB = $B; }
  281. list($X1,$Y1,$X2,$Y2) = $this->fixBoxCoordinates($X1,$Y1,$X2,$Y2);
  282. if ( $X2 - $X1 < $Radius ) { $Radius = floor((($X2-$X1)+2)/2); }
  283. if ( $Y2 - $Y1 < $Radius ) { $Radius = floor((($Y2-$Y1)+2)/2); }
  284. $RestoreShadow = $this->Shadow;
  285. if ( $this->Shadow && $this->ShadowX != 0 && $this->ShadowY != 0 )
  286. {
  287. $this->Shadow = FALSE;
  288. $this->drawRoundedFilledRectangle($X1+$this->ShadowX,$Y1+$this->ShadowY,$X2+$this->ShadowX,$Y2+$this->ShadowY,$Radius,array("R"=>$this->ShadowR,"G"=>$this->ShadowG,"B"=>$this->ShadowB,"Alpha"=>$this->Shadowa));
  289. }
  290. if ( $this->getFirstDecimal($X2) >= 5 ) { $XOffset2 = 1; } else { $XOffset2 = 0; }
  291. if ( $this->getFirstDecimal($X1) <= 5 ) { $XOffset1 = 1; } else { $XOffset1 = 0; }
  292. if ( !$this->Antialias ) { $XOffset1 = 1; $XOffset2 = 1; }
  293. $YTop = floor($Y1+$Radius);
  294. $YBottom = floor($Y2-$Radius);
  295. $this->drawFilledRectangle($X1-$XOffset1,$YTop,$X2+$XOffset2,$YBottom,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"NoBorder"=>TRUE));
  296. $Step = 360 / (2 * PI * $Radius);
  297. $Color = $this->allocateColor($this->Picture,$R,$G,$B,$Alpha);
  298. $Color2 = $this->allocateColor($this->Picture,255,0,0,$Alpha);
  299. $Drawn = "";
  300. if ( $Alpha < 100 ) { $Drawn[$YTop] = FALSE; }
  301. if ( $Alpha < 100 ) { $Drawn[$YBottom] = TRUE; }
  302. for($i=0;$i<=90;$i=$i+$Step)
  303. {
  304. $Xp1 = cos(($i+180)*PI/180) * $Radius + $X1 + $Radius;
  305. $Xp2 = cos(((90-$i)+270)*PI/180) * $Radius + $X2 - $Radius;
  306. $Yp = sin(($i+180)*PI/180) * $Radius + $YTop;
  307. if ( $this->getFirstDecimal($Xp1) > 5 ) { $XOffset1 = 1; } else { $XOffset1 = 0; }
  308. if ( $this->getFirstDecimal($Xp2) > 5 ) { $XOffset2 = 1; } else { $XOffset2 = 0; }
  309. if ( $this->getFirstDecimal($Yp) > 5 ) { $YOffset = 1; } else { $YOffset = 0; }
  310. if ( !isset($Drawn[$Yp+$YOffset]) || $Alpha == 100 )
  311. imageline($this->Picture,$Xp1+$XOffset1,$Yp+$YOffset,$Xp2+$XOffset2,$Yp+$YOffset,$Color);
  312. $Drawn[$Yp+$YOffset] = $Xp2;
  313. $Xp1 = cos(($i+90)*PI/180) * $Radius + $X1 + $Radius;
  314. $Xp2 = cos((90-$i)*PI/180) * $Radius + $X2 - $Radius;
  315. $Yp = sin(($i+90)*PI/180) * $Radius + $YBottom;
  316. if ( $this->getFirstDecimal($Xp1) > 7 ) { $XOffset1 = 1; } else { $XOffset1 = 0; }
  317. if ( $this->getFirstDecimal($Xp2) > 7 ) { $XOffset2 = 1; } else { $XOffset2 = 0; }
  318. if ( $this->getFirstDecimal($Yp) > 5 ) { $YOffset = 1; } else { $YOffset = 0; }
  319. if ( !isset($Drawn[$Yp+$YOffset]) || $Alpha == 100 )
  320. imageline($this->Picture,$Xp1+$XOffset1,$Yp+$YOffset,$Xp2+$XOffset2,$Yp+$YOffset,$Color);
  321. $Drawn[$Yp+$YOffset] = $Xp2;
  322. }
  323. $this->drawRoundedRectangle($X1,$Y1,$X2,$Y2,$Radius,array("R"=>$BorderR,"G"=>$BorderG,"B"=>$BorderB,"Alpha"=>$Alpha));
  324. $this->Shadow = $RestoreShadow;
  325. }
  326. /* Draw a rectangle */
  327. function drawRectangle($X1,$Y1,$X2,$Y2,$Format="")
  328. {
  329. $R = isset($Format["R"]) ? $Format["R"] : 0;
  330. $G = isset($Format["G"]) ? $Format["G"] : 0;
  331. $B = isset($Format["B"]) ? $Format["B"] : 0;
  332. $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100;
  333. $Ticks = isset($Format["Ticks"]) ? $Format["Ticks"] : NULL;
  334. $NoAngle = isset($Format["NoAngle"]) ? $Format["NoAngle"] : FALSE;
  335. if ($X1 > $X2) { list($X1, $X2) = array($X2, $X1); }
  336. if ($Y1 > $Y2) { list($Y1, $Y2) = array($Y2, $Y1); }
  337. if ( $this->Antialias )
  338. {
  339. if ( $NoAngle )
  340. {
  341. $this->drawLine($X1+1,$Y1,$X2-1,$Y1,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"Ticks"=>$Ticks));
  342. $this->drawLine($X2,$Y1+1,$X2,$Y2-1,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"Ticks"=>$Ticks));
  343. $this->drawLine($X2-1,$Y2,$X1+1,$Y2,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"Ticks"=>$Ticks));
  344. $this->drawLine($X1,$Y1+1,$X1,$Y2-1,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"Ticks"=>$Ticks));
  345. }
  346. else
  347. {
  348. $this->drawLine($X1+1,$Y1,$X2-1,$Y1,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"Ticks"=>$Ticks));
  349. $this->drawLine($X2,$Y1,$X2,$Y2,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"Ticks"=>$Ticks));
  350. $this->drawLine($X2-1,$Y2,$X1+1,$Y2,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"Ticks"=>$Ticks));
  351. $this->drawLine($X1,$Y1,$X1,$Y2,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"Ticks"=>$Ticks));
  352. }
  353. }
  354. else
  355. {
  356. $Color = $this->allocateColor($this->Picture,$R,$G,$B,$Alpha);
  357. imagerectangle($this->Picture,$X1,$Y1,$X2,$Y2,$Color);
  358. }
  359. }
  360. /* Draw a filled rectangle */
  361. function drawFilledRectangle($X1,$Y1,$X2,$Y2,$Format="")
  362. {
  363. $R = isset($Format["R"]) ? $Format["R"] : 0;
  364. $G = isset($Format["G"]) ? $Format["G"] : 0;
  365. $B = isset($Format["B"]) ? $Format["B"] : 0;
  366. $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100;
  367. $BorderR = isset($Format["BorderR"]) ? $Format["BorderR"] : -1;
  368. $BorderG = isset($Format["BorderG"]) ? $Format["BorderG"] : -1;
  369. $BorderB = isset($Format["BorderB"]) ? $Format["BorderB"] : -1;
  370. $BorderAlpha = isset($Format["BorderAlpha"]) ? $Format["BorderAlpha"] : $Alpha;
  371. $Surrounding = isset($Format["Surrounding"]) ? $Format["Surrounding"] : NULL;
  372. $Ticks = isset($Format["Ticks"]) ? $Format["Ticks"] : NULL;
  373. $NoAngle = isset($Format["NoAngle"]) ? $Format["NoAngle"] : NULL;
  374. $Dash = isset($Format["Dash"]) ? $Format["Dash"] : FALSE;
  375. $DashStep = isset($Format["DashStep"]) ? $Format["DashStep"] : 4;
  376. $DashR = isset($Format["DashR"]) ? $Format["DashR"] : 0;
  377. $DashG = isset($Format["DashG"]) ? $Format["DashG"] : 0;
  378. $DashB = isset($Format["DashB"]) ? $Format["DashB"] : 0;
  379. $NoBorder = isset($Format["NoBorder"]) ? $Format["NoBorder"] : FALSE;
  380. if ( $Surrounding != NULL ) { $BorderR = $R+$Surrounding; $BorderG = $G+$Surrounding; $BorderB = $B+$Surrounding; }
  381. if ($X1 > $X2) { list($X1, $X2) = array($X2, $X1); }
  382. if ($Y1 > $Y2) { list($Y1, $Y2) = array($Y2, $Y1); }
  383. $RestoreShadow = $this->Shadow;
  384. if ( $this->Shadow && $this->ShadowX != 0 && $this->ShadowY != 0 )
  385. {
  386. $this->Shadow = FALSE;
  387. $this->drawFilledRectangle($X1+$this->ShadowX,$Y1+$this->ShadowY,$X2+$this->ShadowX,$Y2+$this->ShadowY,array("R"=>$this->ShadowR,"G"=>$this->ShadowG,"B"=>$this->ShadowB,"Alpha"=>$this->Shadowa,"Ticks"=>$Ticks,"NoAngle"=>$NoAngle));
  388. }
  389. $Color = $this->allocateColor($this->Picture,$R,$G,$B,$Alpha);
  390. if ( $NoAngle )
  391. {
  392. imagefilledrectangle($this->Picture,ceil($X1)+1,ceil($Y1),floor($X2)-1,floor($Y2),$Color);
  393. imageline($this->Picture,ceil($X1),ceil($Y1)+1,ceil($X1),floor($Y2)-1,$Color);
  394. imageline($this->Picture,floor($X2),ceil($Y1)+1,floor($X2),floor($Y2)-1,$Color);
  395. }
  396. else
  397. imagefilledrectangle($this->Picture,ceil($X1),ceil($Y1),floor($X2),floor($Y2),$Color);
  398. if ( $Dash )
  399. {
  400. if ( $BorderR != -1 ) { $iX1=$X1+1; $iY1=$Y1+1; $iX2=$X2-1; $iY2=$Y2-1; } else { $iX1=$X1; $iY1=$Y1; $iX2=$X2; $iY2=$Y2; }
  401. $Color = $this->allocateColor($this->Picture,$DashR,$DashG,$DashB,$Alpha);
  402. $Y=$iY1-$DashStep;
  403. for($X=$iX1; $X<=$iX2+($iY2-$iY1); $X=$X+$DashStep)
  404. {
  405. $Y=$Y+$DashStep;
  406. if ( $X > $iX2 ) { $Xa = $X-($X-$iX2); $Ya = $iY1+($X-$iX2); } else { $Xa = $X; $Ya = $iY1; }
  407. if ( $Y > $iY2 ) { $Xb = $iX1+($Y-$iY2); $Yb = $Y-($Y-$iY2); } else { $Xb = $iX1; $Yb = $Y; }
  408. imageline($this->Picture,$Xa,$Ya,$Xb,$Yb,$Color);
  409. }
  410. }
  411. if ( $this->Antialias && !$NoBorder )
  412. {
  413. if ( $X1 < ceil($X1) )
  414. {
  415. $AlphaA = $Alpha * (ceil($X1) - $X1);
  416. $Color = $this->allocateColor($this->Picture,$R,$G,$B,$AlphaA);
  417. imageline($this->Picture,ceil($X1)-1,ceil($Y1),ceil($X1)-1,floor($Y2),$Color);
  418. }
  419. if ( $Y1 < ceil($Y1) )
  420. {
  421. $AlphaA = $Alpha * (ceil($Y1) - $Y1);
  422. $Color = $this->allocateColor($this->Picture,$R,$G,$B,$AlphaA);
  423. imageline($this->Picture,ceil($X1),ceil($Y1)-1,floor($X2),ceil($Y1)-1,$Color);
  424. }
  425. if ( $X2 > floor($X2) )
  426. {
  427. $AlphaA = $Alpha * (.5-($X2 - floor($X2)));
  428. $Color = $this->allocateColor($this->Picture,$R,$G,$B,$AlphaA);
  429. imageline($this->Picture,floor($X2)+1,ceil($Y1),floor($X2)+1,floor($Y2),$Color);
  430. }
  431. if ( $Y2 > floor($Y2) )
  432. {
  433. $AlphaA = $Alpha * (.5-($Y2 - floor($Y2)));
  434. $Color = $this->allocateColor($this->Picture,$R,$G,$B,$AlphaA);
  435. imageline($this->Picture,ceil($X1),floor($Y2)+1,floor($X2),floor($Y2)+1,$Color);
  436. }
  437. }
  438. if ( $BorderR != -1 )
  439. $this->drawRectangle($X1,$Y1,$X2,$Y2,array("R"=>$BorderR,"G"=>$BorderG,"B"=>$BorderB,"Alpha"=>$BorderAlpha,"Ticks"=>$Ticks,"NoAngle"=>$NoAngle));
  440. $this->Shadow = $RestoreShadow;
  441. }
  442. /* Draw a rectangular marker of the specified size */
  443. function drawRectangleMarker($X,$Y,$Format="")
  444. {
  445. $Size = isset($Format["Size"]) ? $Format["Size"] : 4;
  446. $HalfSize = floor($Size/2);
  447. $this->drawFilledRectangle($X-$HalfSize,$Y-$HalfSize,$X+$HalfSize,$Y+$HalfSize,$Format);
  448. }
  449. /* Drawn a spline based on the bezier function */
  450. function drawSpline($Coordinates,$Format="")
  451. {
  452. $R = isset($Format["R"]) ? $Format["R"] : 0;
  453. $G = isset($Format["G"]) ? $Format["G"] : 0;
  454. $B = isset($Format["B"]) ? $Format["B"] : 0;
  455. $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100;
  456. $Force = isset($Format["Force"]) ? $Format["Force"] : 30;
  457. $Forces = isset($Format["Forces"]) ? $Format["Forces"] : NULL;
  458. $ShowC = isset($Format["ShowControl"]) ? $Format["ShowControl"] : FALSE;
  459. $Ticks = isset($Format["Ticks"]) ? $Format["Ticks"] : NULL;
  460. $PathOnly = isset($Format["PathOnly"]) ? $Format["PathOnly"] : FALSE;
  461. $Weight = isset($Format["Weight"]) ? $Format["Weight"] : NULL;
  462. $Cpt = NULL; $Mode = NULL; $Result = "";
  463. for($i=1;$i<=count($Coordinates)-1;$i++)
  464. {
  465. $X1 = $Coordinates[$i-1][0]; $Y1 = $Coordinates[$i-1][1];
  466. $X2 = $Coordinates[$i][0]; $Y2 = $Coordinates[$i][1];
  467. if ( $Forces != NULL ) { $Force = $Forces[$i]; }
  468. /* First segment */
  469. if ( $i == 1 )
  470. { $Xv1 = $X1; $Yv1 = $Y1; }
  471. else
  472. {
  473. $Angle1 = $this->getAngle($XLast,$YLast,$X1,$Y1);
  474. $Angle2 = $this->getAngle($X1,$Y1,$X2,$Y2);
  475. $XOff = cos($Angle2 * PI / 180) * $Force + $X1;
  476. $YOff = sin($Angle2 * PI / 180) * $Force + $Y1;
  477. $Xv1 = cos($Angle1 * PI / 180) * $Force + $XOff;
  478. $Yv1 = sin($Angle1 * PI / 180) * $Force + $YOff;
  479. }
  480. /* Last segment */
  481. if ( $i == count($Coordinates)-1 )
  482. { $Xv2 = $X2; $Yv2 = $Y2; }
  483. else
  484. {
  485. $Angle1 = $this->getAngle($X2,$Y2,$Coordinates[$i+1][0],$Coordinates[$i+1][1]);
  486. $Angle2 = $this->getAngle($X1,$Y1,$X2,$Y2);
  487. $XOff = cos(($Angle2+180) * PI / 180) * $Force + $X2;
  488. $YOff = sin(($Angle2+180) * PI / 180) * $Force + $Y2;
  489. $Xv2 = cos(($Angle1+180) * PI / 180) * $Force + $XOff;
  490. $Yv2 = sin(($Angle1+180) * PI / 180) * $Force + $YOff;
  491. }
  492. $Path = $this->drawBezier($X1,$Y1,$X2,$Y2,$Xv1,$Yv1,$Xv2,$Yv2,$Format);
  493. if ($PathOnly) { $Result[] = $Path; }
  494. $XLast = $X1; $YLast = $Y1;
  495. }
  496. return($Result);
  497. }
  498. /* Draw a bezier curve with two controls points */
  499. function drawBezier($X1,$Y1,$X2,$Y2,$Xv1,$Yv1,$Xv2,$Yv2,$Format="")
  500. {
  501. $R = isset($Format["R"]) ? $Format["R"] : 0;
  502. $G = isset($Format["G"]) ? $Format["G"] : 0;
  503. $B = isset($Format["B"]) ? $Format["B"] : 0;
  504. $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100;
  505. $ShowC = isset($Format["ShowControl"]) ? $Format["ShowControl"] : FALSE;
  506. $Segments = isset($Format["Segments"]) ? $Format["Segments"] : NULL;
  507. $Ticks = isset($Format["Ticks"]) ? $Format["Ticks"] : NULL;
  508. $NoDraw = isset($Format["NoDraw"]) ? $Format["NoDraw"] : FALSE;
  509. $PathOnly = isset($Format["PathOnly"]) ? $Format["PathOnly"] : FALSE;
  510. $Weight = isset($Format["Weight"]) ? $Format["Weight"] : NULL;
  511. $DrawArrow = isset($Format["DrawArrow"]) ? $Format["DrawArrow"] : FALSE;
  512. $ArrowSize = isset($Format["ArrowSize"]) ? $Format["ArrowSize"] : 10;
  513. $ArrowRatio = isset($Format["ArrowRatio"]) ? $Format["ArrowRatio"] : .5;
  514. $ArrowTwoHeads = isset($Format["ArrowTwoHeads"]) ? $Format["ArrowTwoHeads"] : FALSE;
  515. if ( $Segments == NULL )
  516. {
  517. $Length = $this->getLength($X1,$Y1,$X2,$Y2);
  518. $Precision = ($Length*125)/1000;
  519. }
  520. else
  521. $Precision = $Segments;
  522. $P[0]["X"] = $X1; $P[0]["Y"] = $Y1;
  523. $P[1]["X"] = $Xv1; $P[1]["Y"] = $Yv1;
  524. $P[2]["X"] = $Xv2; $P[2]["Y"] = $Yv2;
  525. $P[3]["X"] = $X2; $P[3]["Y"] = $Y2;
  526. /* Compute the bezier points */
  527. $Q = ""; $ID = 0; $Path = "";
  528. for($i=0;$i<=$Precision;$i=$i+1)
  529. {
  530. $u = $i / $Precision;
  531. $C = "";
  532. $C[0] = (1 - $u) * (1 - $u) * (1 - $u);
  533. $C[1] = ($u * 3) * (1 - $u) * (1 - $u);
  534. $C[2] = 3 * $u * $u * (1 - $u);
  535. $C[3] = $u * $u * $u;
  536. for($j=0;$j<=3;$j++)
  537. {
  538. if ( !isset($Q[$ID]) ) { $Q[$ID] = ""; }
  539. if ( !isset($Q[$ID]["X"]) ) { $Q[$ID]["X"] = 0; }
  540. if ( !isset($Q[$ID]["Y"]) ) { $Q[$ID]["Y"] = 0; }
  541. $Q[$ID]["X"] = $Q[$ID]["X"] + $P[$j]["X"] * $C[$j];
  542. $Q[$ID]["Y"] = $Q[$ID]["Y"] + $P[$j]["Y"] * $C[$j];
  543. }
  544. $ID++;
  545. }
  546. $Q[$ID]["X"] = $X2; $Q[$ID]["Y"] = $Y2;
  547. if ( !$NoDraw )
  548. {
  549. /* Display the control points */
  550. if ( $ShowC && !$PathOnly )
  551. {
  552. $Xv1 = floor($Xv1); $Yv1 = floor($Yv1); $Xv2 = floor($Xv2); $Yv2 = floor($Yv2);
  553. $this->drawLine($X1,$Y1,$X2,$Y2,array("R"=>0,"G"=>0,"B"=>0,"Alpha"=>30));
  554. $MyMarkerSettings = array("R"=>255,"G"=>0,"B"=>0,"BorderR"=>255,"BorderB"=>255,"BorderG"=>255,"Size"=>4);
  555. $this->drawRectangleMarker($Xv1,$Yv1,$MyMarkerSettings);
  556. $this->drawText($Xv1+4,$Yv1,"v1");
  557. $MyMarkerSettings = array("R"=>0,"G"=>0,"B"=>255,"BorderR"=>255,"BorderB"=>255,"BorderG"=>255,"Size"=>4);
  558. $this->drawRectangleMarker($Xv2,$Yv2,$MyMarkerSettings);
  559. $this->drawText($Xv2+4,$Yv2,"v2");
  560. }
  561. /* Draw the bezier */
  562. $LastX = NULL; $LastY = NULL; $Cpt = NULL; $Mode = NULL; $ArrowS = NULL;
  563. foreach ($Q as $Key => $Point)
  564. {
  565. $X = $Point["X"]; $Y = $Point["Y"];
  566. /* Get the first segment */
  567. if ( $ArrowS == NULL && $LastX != NULL && $LastY != NULL )
  568. { $ArrowS["X2"] = $LastX; $ArrowS["Y2"] = $LastY; $ArrowS["X1"] = $X; $ArrowS["Y1"] = $Y; }
  569. if ( $LastX != NULL && $LastY != NULL && !$PathOnly)
  570. list($Cpt,$Mode) = $this->drawLine($LastX,$LastY,$X,$Y,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"Ticks"=>$Ticks,"Cpt"=>$Cpt,"Mode"=>$Mode,"Weight"=>$Weight));
  571. /* Get the last segment */
  572. $ArrowE["X1"] = $LastX; $ArrowE["Y1"] = $LastY; $ArrowE["X2"] = $X; $ArrowE["Y2"] = $Y;
  573. $LastX = $X; $LastY = $Y;
  574. }
  575. if ( $DrawArrow && !$PathOnly )
  576. {
  577. $ArrowSettings = array("FillR"=>$R,"FillG"=>$G,"FillB"=>$B,"Alpha"=>$Alpha,"Size"=>$ArrowSize,"Ratio"=>$ArrowRatio);
  578. if ( $ArrowTwoHeads )
  579. $this->drawArrow($ArrowS["X1"],$ArrowS["Y1"],$ArrowS["X2"],$ArrowS["Y2"],$ArrowSettings);
  580. $this->drawArrow($ArrowE["X1"],$ArrowE["Y1"],$ArrowE["X2"],$ArrowE["Y2"],$ArrowSettings);
  581. }
  582. }
  583. return($Q);
  584. }
  585. /* Draw a line between two points */
  586. function drawLine($X1,$Y1,$X2,$Y2,$Format="")
  587. {
  588. $R = isset($Format["R"]) ? $Format["R"] : 0;
  589. $G = isset($Format["G"]) ? $Format["G"] : 0;
  590. $B = isset($Format["B"]) ? $Format["B"] : 0;
  591. $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100;
  592. $Ticks = isset($Format["Ticks"]) ? $Format["Ticks"] : NULL;
  593. $Cpt = isset($Format["Cpt"]) ? $Format["Cpt"] : 1;
  594. $Mode = isset($Format["Mode"]) ? $Format["Mode"] : 1;
  595. $Weight = isset($Format["Weight"]) ? $Format["Weight"] : NULL;
  596. if ( $this->Antialias == FALSE && $Ticks == NULL )
  597. {
  598. if ( $this->Shadow && $this->ShadowX != 0 && $this->ShadowY != 0 )
  599. {
  600. $ShadowColor = $this->allocateColor($this->Picture,$this->ShadowR,$this->ShadowG,$this->ShadowB,$this->Shadowa);
  601. imageline($this->Picture,$X1+$this->ShadowX,$Y1+$this->ShadowY,$X2+$this->ShadowX,$Y2+$this->ShadowY,$ShadowColor);
  602. }
  603. $Color = $this->allocateColor($this->Picture,$R,$G,$B,$Alpha);
  604. imageline($this->Picture,$X1,$Y1,$X2,$Y2,$Color);
  605. return(0);
  606. }
  607. $Distance = sqrt(($X2-$X1)*($X2-$X1)+($Y2-$Y1)*($Y2-$Y1));
  608. if ( $Distance == 0 ) { return(-1); }
  609. /* Derivative algorithm for overweighted lines, re-route to polygons primitives */
  610. if ( $Weight != NULL )
  611. {
  612. $Angle = $this->getAngle($X1,$Y1,$X2,$Y2);
  613. $PolySettings = array ("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"BorderAlpha"=>$Alpha);
  614. if ( $Ticks == NULL )
  615. {
  616. $Points = "";
  617. $Points[] = cos(deg2rad($Angle-90)) * $Weight + $X1; $Points[] = sin(deg2rad($Angle-90)) * $Weight + $Y1;
  618. $Points[] = cos(deg2rad($Angle+90)) * $Weight + $X1; $Points[] = sin(deg2rad($Angle+90)) * $Weight + $Y1;
  619. $Points[] = cos(deg2rad($Angle+90)) * $Weight + $X2; $Points[] = sin(deg2rad($Angle+90)) * $Weight + $Y2;
  620. $Points[] = cos(deg2rad($Angle-90)) * $Weight + $X2; $Points[] = sin(deg2rad($Angle-90)) * $Weight + $Y2;
  621. $this->drawPolygon($Points,$PolySettings);
  622. }
  623. else
  624. {
  625. for($i=0;$i<=$Distance;$i=$i+$Ticks*2)
  626. {
  627. $Xa = (($X2-$X1)/$Distance) * $i + $X1; $Ya = (($Y2-$Y1)/$Distance) * $i + $Y1;
  628. $Xb = (($X2-$X1)/$Distance) * ($i+$Ticks) + $X1; $Yb = (($Y2-$Y1)/$Distance) * ($i+$Ticks) + $Y1;
  629. $Points = "";
  630. $Points[] = cos(deg2rad($Angle-90)) * $Weight + $Xa; $Points[] = sin(deg2rad($Angle-90)) * $Weight + $Ya;
  631. $Points[] = cos(deg2rad($Angle+90)) * $Weight + $Xa; $Points[] = sin(deg2rad($Angle+90)) * $Weight + $Ya;
  632. $Points[] = cos(deg2rad($Angle+90)) * $Weight + $Xb; $Points[] = sin(deg2rad($Angle+90)) * $Weight + $Yb;
  633. $Points[] = cos(deg2rad($Angle-90)) * $Weight + $Xb; $Points[] = sin(deg2rad($Angle-90)) * $Weight + $Yb;
  634. $this->drawPolygon($Points,$PolySettings);
  635. }
  636. }
  637. return(1);
  638. }
  639. $XStep = ($X2-$X1) / $Distance;
  640. $YStep = ($Y2-$Y1) / $Distance;
  641. for($i=0;$i<=$Distance;$i++)
  642. {
  643. $X = $i * $XStep + $X1;
  644. $Y = $i * $YStep + $Y1;
  645. if ( $Ticks != NULL )
  646. {
  647. if ( $Cpt % $Ticks == 0 )
  648. { $Cpt = 0; if ( $Mode == 1 ) { $Mode = 0; } else { $Mode = 1; } }
  649. if ( $Mode == 1 )
  650. $this->drawAntialiasPixel($X,$Y,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha));
  651. $Cpt++;
  652. }
  653. else
  654. $this->drawAntialiasPixel($X,$Y,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha));
  655. }
  656. return(array($Cpt,$Mode));
  657. }
  658. /* Draw a circle */
  659. function drawCircle($Xc,$Yc,$Height,$Width,$Format="")
  660. {
  661. $R = isset($Format["R"]) ? $Format["R"] : 0;
  662. $G = isset($Format["G"]) ? $Format["G"] : 0;
  663. $B = isset($Format["B"]) ? $Format["B"] : 0;
  664. $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100;
  665. $Ticks = isset($Format["Ticks"]) ? $Format["Ticks"] : NULL;
  666. $Height = abs($Height);
  667. $Width = abs($Width);
  668. if ( $Height == 0 ) { $Height = 1; }
  669. if ( $Width == 0 ) { $Width = 1; }
  670. $Xc = floor($Xc); $Yc = floor($Yc);
  671. $RestoreShadow = $this->Shadow;
  672. if ( $this->Shadow && $this->ShadowX != 0 && $this->ShadowY != 0 )
  673. {
  674. $this->Shadow = FALSE;
  675. $this->drawCircle($Xc+$this->ShadowX,$Yc+$this->ShadowY,$Height,$Width,array("R"=>$this->ShadowR,"G"=>$this->ShadowG,"B"=>$this->ShadowB,"Alpha"=>$this->Shadowa,"Ticks"=>$Ticks));
  676. }
  677. if ( $Width == 0 ) { $Width = $Height; }
  678. if ( $R < 0 ) { $R = 0; } if ( $R > 255 ) { $R = 255; }
  679. if ( $G < 0 ) { $G = 0; } if ( $G > 255 ) { $G = 255; }
  680. if ( $B < 0 ) { $B = 0; } if ( $B > 255 ) { $B = 255; }
  681. $Step = 360 / (2 * PI * max($Width,$Height));
  682. $Mode = 1; $Cpt = 1;
  683. for($i=0;$i<=360;$i=$i+$Step)
  684. {
  685. $X = cos($i*PI/180) * $Height + $Xc;
  686. $Y = sin($i*PI/180) * $Width + $Yc;
  687. if ( $Ticks != NULL )
  688. {
  689. if ( $Cpt % $Ticks == 0 )
  690. { $Cpt = 0; if ( $Mode == 1 ) { $Mode = 0; } else { $Mode = 1; } }
  691. if ( $Mode == 1 )
  692. $this->drawAntialiasPixel($X,$Y,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha));
  693. $Cpt++;
  694. }
  695. else
  696. $this->drawAntialiasPixel($X,$Y,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha));
  697. }
  698. $this->Shadow = $RestoreShadow;
  699. }
  700. /* Draw a filled circle */
  701. function drawFilledCircle($X,$Y,$Radius,$Format="")
  702. {
  703. $R = isset($Format["R"]) ? $Format["R"] : 0;
  704. $G = isset($Format["G"]) ? $Format["G"] : 0;
  705. $B = isset($Format["B"]) ? $Format["B"] : 0;
  706. $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100;
  707. $BorderR = isset($Format["BorderR"]) ? $Format["BorderR"] : -1;
  708. $BorderG = isset($Format["BorderG"]) ? $Format["BorderG"] : -1;
  709. $BorderB = isset($Format["BorderB"]) ? $Format["BorderB"] : -1;
  710. $BorderAlpha = isset($Format["BorderAlpha"]) ? $Format["BorderAlpha"] : $Alpha;
  711. $Ticks = isset($Format["Ticks"]) ? $Format["Ticks"] : NULL;
  712. $Surrounding = isset($Format["Surrounding"]) ? $Format["Surrounding"] : NULL;
  713. if ( $Radius == 0 ) { $Radius = 1; }
  714. if ( $Surrounding != NULL ) { $BorderR = $R+$Surrounding; $BorderG = $G+$Surrounding; $BorderB = $B+$Surrounding; }
  715. $X = floor($X); $Y = floor($Y);
  716. $Radius = abs($Radius);
  717. $RestoreShadow = $this->Shadow;
  718. if ( $this->Shadow && $this->ShadowX != 0 && $this->ShadowY != 0 )
  719. {
  720. $this->Shadow = FALSE;
  721. $this->drawFilledCircle($X+$this->ShadowX,$Y+$this->ShadowY,$Radius,array("R"=>$this->ShadowR,"G"=>$this->ShadowG,"B"=>$this->ShadowB,"Alpha"=>$this->Shadowa,"Ticks"=>$Ticks));
  722. }
  723. $this->Mask = "";
  724. $Color = $this->allocateColor($this->Picture,$R,$G,$B,$Alpha);
  725. for ($i=0; $i<=$Radius*2; $i++)
  726. {
  727. $Slice = sqrt($Radius * $Radius - ($Radius - $i) * ($Radius - $i));
  728. $XPos = floor($Slice);
  729. $YPos = $Y + $i - $Radius;
  730. $AAlias = $Slice - floor($Slice);
  731. $this->Mask[$X-$XPos][$YPos] = TRUE;
  732. $this->Mask[$X+$XPos][$YPos] = TRUE;
  733. imageline($this->Picture,$X-$XPos,$YPos,$X+$XPos,$YPos,$Color);
  734. }
  735. if ( $this->Antialias )
  736. $this->drawCircle($X,$Y,$Radius,$Radius,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"Ticks"=>$Ticks));
  737. $this->Mask = "";
  738. if ( $BorderR != -1 )
  739. $this->drawCircle($X,$Y,$Radius,$Radius,array("R"=>$BorderR,"G"=>$BorderG,"B"=>$BorderB,"Alpha"=>$BorderAlpha,"Ticks"=>$Ticks));
  740. $this->Shadow = $RestoreShadow;
  741. }
  742. /* Write text */
  743. function drawText($X,$Y,$Text,$Format="")
  744. {
  745. $R = isset($Format["R"]) ? $Format["R"] : $this->FontColorR;
  746. $G = isset($Format["G"]) ? $Format["G"] : $this->FontColorG;
  747. $B = isset($Format["B"]) ? $Format["B"] : $this->FontColorB;
  748. $Angle = isset($Format["Angle"]) ? $Format["Angle"] : 0;
  749. $Align = isset($Format["Align"]) ? $Format["Align"] : TEXT_ALIGN_BOTTOMLEFT;
  750. $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : $this->FontColorA;
  751. $FontName = isset($Format["FontName"]) ? $Format["FontName"] : $this->FontName;
  752. $FontSize = isset($Format["FontSize"]) ? $Format["FontSize"] : $this->FontSize;
  753. $ShowOrigine = isset($Format["ShowOrigine"]) ? $Format["ShowOrigine"] : FALSE;
  754. $TOffset = isset($Format["TOffset"]) ? $Format["TOffset"] : 2;
  755. $DrawBox = isset($Format["DrawBox"]) ? $Format["DrawBox"] : FALSE;
  756. $DrawBoxBorder = isset($Format["DrawBoxBorder"]) ? $Format["DrawBoxBorder"] : TRUE;
  757. $BorderOffset = isset($Format["BorderOffset"]) ? $Format["BorderOffset"] : 6;
  758. $BoxRounded = isset($Format["BoxRounded"]) ? $Format["BoxRounded"] : FALSE;
  759. $RoundedRadius = isset($Format["RoundedRadius"]) ? $Format["RoundedRadius"] : 6;
  760. $BoxR = isset($Format["BoxR"]) ? $Format["BoxR"] : 255;
  761. $BoxG = isset($Format["BoxG"]) ? $Format["BoxG"] : 255;
  762. $BoxB = isset($Format["BoxB"]) ? $Format["BoxB"] : 255;
  763. $BoxAlpha = isset($Format["BoxAlpha"]) ? $Format["BoxAlpha"] : 50;
  764. $BoxSurrounding = isset($Format["BoxSurrounding"]) ? $Format["BoxSurrounding"] : "";
  765. $BoxBorderR = isset($Format["BoxR"]) ? $Format["BoxR"] : 0;
  766. $BoxBorderG = isset($Format["BoxG"]) ? $Format["BoxG"] : 0;
  767. $BoxBorderB = isset($Format["BoxB"]) ? $Format["BoxB"] : 0;
  768. $BoxBorderAlpha = isset($Format["BoxAlpha"]) ? $Format["BoxAlpha"] : 50;
  769. $NoShadow = isset($Format["NoShadow"]) ? $Format["NoShadow"] : FALSE;
  770. $Shadow = $this->Shadow;
  771. if ( $NoShadow ) { $this->Shadow = FALSE; }
  772. if ( $BoxSurrounding != "" ) { $BoxBorderR = $BoxR - $BoxSurrounding; $BoxBorderG = $BoxG - $BoxSurrounding; $BoxBorderB = $BoxB - $BoxSurrounding; $BoxBorderAlpha = $Boxalpha; }
  773. if ( $ShowOrigine )
  774. {
  775. $MyMarkerSettings = array("R"=>255,"G"=>0,"B"=>0,"BorderR"=>255,"BorderB"=>255,"BorderG"=>255,"Size"=>4);
  776. $this->drawRectangleMarker($X,$Y,$MyMarkerSettings);
  777. }
  778. $TxtPos = $this->getTextBox($X,$Y,$FontName,$FontSize,$Angle,$Text);
  779. if ( $DrawBox && ($Angle == 0 || $Angle == 90 || $Angle == 180 || $Angle == 270))
  780. {
  781. $T[0]["X"]=0;$T[0]["Y"]=0;$T[1]["X"]=0;$T[1]["Y"]=0;$T[2]["X"]=0;$T[2]["Y"]=0;$T[3]["X"]=0;$T[3]["Y"]=0;
  782. if ( $Angle == 0 ) { $T[0]["X"]=-$TOffset;$T[0]["Y"]=$TOffset;$T[1]["X"]=$TOffset;$T[1]["Y"]=$TOffset;$T[2]["X"]=$TOffset;$T[2]["Y"]=-$TOffset;$T[3]["X"]=-$TOffset;$T[3]["Y"]=-$TOffset; }
  783. $X1 = min($TxtPos[0]["X"],$TxtPos[1]["X"],$TxtPos[2]["X"],$TxtPos[3]["X"]) - $BorderOffset + 3;
  784. $Y1 = min($TxtPos[0]["Y"],$TxtPos[1]["Y"],$TxtPos[2]["Y"],$TxtPos[3]["Y"]) - $BorderOffset;
  785. $X2 = max($TxtPos[0]["X"],$TxtPos[1]["X"],$TxtPos[2]["X"],$TxtPos[3]["X"]) + $BorderOffset + 3;
  786. $Y2 = max($TxtPos[0]["Y"],$TxtPos[1]["Y"],$TxtPos[2]["Y"],$TxtPos[3]["Y"]) + $BorderOffset - 3;
  787. $X1 = $X1 - $TxtPos[$Align]["X"] + $X + $T[0]["X"];
  788. $Y1 = $Y1 - $TxtPos[$Align]["Y"] + $Y + $T[0]["Y"];
  789. $X2 = $X2 - $TxtPos[$Align]["X"] + $X + $T[0]["X"];
  790. $Y2 = $Y2 - $TxtPos[$Align]["Y"] + $Y + $T[0]["Y"];
  791. $Settings = array("R"=>$BoxR,"G"=>$BoxG,"B"=>$BoxB,"Alpha"=>$BoxAlpha,"BorderR"=>$BoxBorderR,"BorderG"=>$BoxBorderG,"BorderB"=>$BoxBorderB,"BorderAlpha"=>$BoxBorderAlpha);
  792. if ( $BoxRounded )
  793. { $this->drawRoundedFilledRectangle($X1,$Y1,$X2,$Y2,$RoundedRadius,$Settings); }
  794. else
  795. { $this->drawFilledRectangle($X1,$Y1,$X2,$Y2,$Settings); }
  796. }
  797. $X = $X - $TxtPos[$Align]["X"] + $X;
  798. $Y = $Y - $TxtPos[$Align]["Y"] + $Y;
  799. if ( $this->Shadow && $this->ShadowX != 0 && $this->ShadowY != 0 )
  800. {
  801. $C_ShadowColor = $this->allocateColor($this->Picture,$this->ShadowR,$this->ShadowG,$this->ShadowB,$this->Shadowa);
  802. imagettftext($this->Picture,$FontSize,$Angle,$X+$this->ShadowX,$Y+$this->ShadowY,$C_ShadowColor,$FontName,$Text);
  803. }
  804. $C_TextColor = $this->AllocateColor($this->Picture,$R,$G,$B,$Alpha);
  805. imagettftext($this->Picture,$FontSize,$Angle,$X,$Y,$C_TextColor,$FontName,$Text);
  806. $this->Shadow = $Shadow;
  807. return($TxtPos);
  808. }
  809. /* Draw a gradient within a defined area */
  810. function drawGradientArea($X1,$Y1,$X2,$Y2,$Direction,$Format="")
  811. {
  812. $StartR = isset($Format["StartR"]) ? $Format["StartR"] : 90;
  813. $StartG = isset($Format["StartG"]) ? $Format["StartG"] : 90;
  814. $StartB = isset($Format["StartB"]) ? $Format["StartB"] : 90;
  815. $EndR = isset($Format["EndR"]) ? $Format["EndR"] : 0;
  816. $EndG = isset($Format["EndG"]) ? $Format["EndG"] : 0;
  817. $EndB = isset($Format["EndB"]) ? $Format["EndB"] : 0;
  818. $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100;
  819. $Levels = isset($Format["Levels"]) ? $Format["Levels"] : NULL;
  820. $Shadow = $this->Shadow;
  821. $this->Shadow = FALSE;
  822. if ( $StartR == $EndR && $StartG == $EndG && $StartB == $EndB )
  823. {
  824. $this->drawFilledRectangle($X1,$Y1,$X2,$Y2,array("R"=>$StartR,"G"=>$StartG,"B"=>$StartB,"Alpha"=>$Alpha));
  825. return(0);
  826. }
  827. if ( $Levels != NULL )
  828. { $EndR=$StartR+$Levels; $EndG=$StartG+$Levels; $EndB=$StartB+$Levels; }
  829. if ($X1 > $X2) { list($X1, $X2) = array($X2, $X1); }
  830. if ($Y1 > $Y2) { list($Y1, $Y2) = array($Y2, $Y1); }
  831. if ( $Direction == DIRECTION_VERTICAL ) { $Width = abs($Y2-$Y1); }
  832. if ( $Direction == DIRECTION_HORIZONTAL ) { $Width = abs($X2-$X1); }
  833. $Step = max(abs($EndR-$StartR),abs($EndG-$StartG),abs($EndB-$StartB));
  834. $StepSize = $Width/$Step;
  835. $RStep = ($EndR-$StartR)/$Step;
  836. $GStep = ($EndG-$StartG)/$Step;
  837. $BStep = ($EndB-$StartB)/$Step;
  838. $R=$StartR;$G=$StartG;$B=$StartB;
  839. switch($Direction)
  840. {
  841. case DIRECTION_VERTICAL:
  842. $StartY = $Y1; $EndY = floor($Y2)+1; $LastY2 = $StartY;
  843. for($i=0;$i<=$Step;$i++)
  844. {
  845. $Y2 = floor($StartY + ($i * $StepSize));
  846. if ($Y2 > $EndY) { $Y2 = $EndY; }
  847. if (($Y1 != $Y2 && $Y1 < $Y2) || $Y2 == $EndY)
  848. {
  849. $Color = array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha);
  850. $this->drawFilledRectangle($X1,$Y1,$X2,$Y2,$Color);
  851. $LastY2 = max($LastY2,$Y2);
  852. $Y1 = $Y2+1;
  853. }
  854. $R = $R + $RStep; $G = $G + $GStep; $B = $B + $BStep;
  855. }
  856. if ( $LastY2 < $EndY && isset($Color)) { for ($i=$LastY2+1;$i<=$EndY;$i++) { $this->drawLine($X1,$i,$X2,$i,$Color); } }
  857. break;
  858. case DIRECTION_HORIZONTAL:
  859. $StartX = $X1; $EndX = $X2;
  860. for($i=0;$i<=$Step;$i++)
  861. {
  862. $X2 = floor($StartX + ($i * $StepSize));
  863. if ($X2 > $EndX) { $X2 = $EndX; }
  864. if (($X1 != $X2 && $X1 < $X2) || $X2 == $EndX)
  865. {
  866. $Color = array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha);
  867. $this->drawFilledRectangle($X1,$Y1,$X2,$Y2,$Color);
  868. $X1 = $X2+1;
  869. }
  870. $R = $R + $RStep; $G = $G + $GStep; $B = $B + $BStep;
  871. }
  872. if ( $X2 < $EndX && isset($Color)) { $this->drawFilledRectangle($X2,$Y1,$EndX,$Y2,$Color); }
  873. break;
  874. }
  875. $this->Shadow = $Shadow;
  876. }
  877. /* Draw an aliased pixel */
  878. function drawAntialiasPixel($X,$Y,$Format="")
  879. {
  880. $R = isset($Format["R"]) ? $Format["R"] : 0;
  881. $G = isset($Format["G"]) ? $Format["G"] : 0;
  882. $B = isset($Format["B"]) ? $Format["B"] : 0;
  883. $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100;
  884. if ( $X < 0 || $Y < 0 || $X >= $this->XSize || $Y >= $this->YSize )
  885. return(-1);
  886. if ( $R < 0 ) { $R = 0; } if ( $R > 255 ) { $R = 255; }
  887. if ( $G < 0 ) { $G = 0; } if ( $G > 255 ) { $G = 255; }
  888. if ( $B < 0 ) { $B = 0; } if ( $B > 255 ) { $B = 255; }
  889. if ( !$this->Antialias )
  890. {
  891. if ( $this->Shadow && $this->ShadowX != 0 && $this->ShadowY != 0 )
  892. {
  893. $ShadowColor = $this->allocateColor($this->Picture,$this->ShadowR,$this->ShadowG,$this->ShadowB,$this->Shadowa);
  894. imagesetpixel($this->Picture,$X+$this->ShadowX,$Y+$this->ShadowY,$ShadowColor);
  895. }
  896. $PlotColor = $this->allocateColor($this->Picture,$R,$G,$B,$Alpha);
  897. imagesetpixel($this->Picture,$X,$Y,$PlotColor);
  898. return(0);
  899. }
  900. $Plot = "";
  901. $Xi = floor($X);
  902. $Yi = floor($Y);
  903. if ( $Xi == $X && $Yi == $Y)
  904. {
  905. if ( $Alpha == 100 )
  906. $this->drawAlphaPixel($X,$Y,100,$R,$G,$B);
  907. else
  908. $this->drawAlphaPixel($X,$Y,$Alpha,$R,$G,$B);
  909. }
  910. else
  911. {
  912. $Alpha1 = (((1 - ($X - floor($X))) * (1 - ($Y - floor($Y))) * 100) / 100) * $Alpha;
  913. if ( $Alpha1 > $this->AntialiasQuality ) { $this->drawAlphaPixel($Xi,$Yi,$Alpha1,$R,$G,$B); }
  914. $Alpha2 = ((($X - floor($X)) * (1 - ($Y - floor($Y))) * 100) / 100) * $Alpha;
  915. if ( $Alpha2 > $this->AntialiasQuality ) { $this->drawAlphaPixel($Xi+1,$Yi,$Alpha2,$R,$G,$B); }
  916. $Alpha3 = (((1 - ($X - floor($X))) * ($Y - floor($Y)) * 100) / 100) * $Alpha;
  917. if ( $Alpha3 > $this->AntialiasQuality ) { $this->drawAlphaPixel($Xi,$Yi+1,$Alpha3,$R,$G,$B); }
  918. $Alpha4 = ((($X - floor($X)) * ($Y - floor($Y)) * 100) / 100) * $Alpha;
  919. if ( $Alpha4 > $this->AntialiasQuality ) { $this->drawAlphaPixel($Xi+1,$Yi+1,$Alpha4,$R,$G,$B); }
  920. }
  921. }
  922. /* Draw a semi-transparent pixel */
  923. function drawAlphaPixel($X,$Y,$Alpha,$R,$G,$B)
  924. {
  925. if ( isset($this->Mask[$X])) { if ( isset($this->Mask[$X][$Y]) ) { return(0); } }
  926. if ( $X < 0 || $Y < 0 || $X >= $this->XSize || $Y >= $this->YSize )
  927. return(-1);
  928. if ( $R < 0 ) { $R = 0; } if ( $R > 255 ) { $R = 255; }
  929. if ( $G < 0 ) { $G = 0; } if ( $G > 255 ) { $G = 255; }
  930. if ( $B < 0 ) { $B = 0; } if ( $B > 255 ) { $B = 255; }
  931. if ( $this->Shadow && $this->ShadowX != 0 && $this->ShadowY != 0 )
  932. {
  933. $AlphaFactor = floor(($Alpha / 100) * $this->Shadowa);
  934. $ShadowColor = $this->allocateColor($this->Picture,$this->ShadowR,$this->ShadowG,$this->ShadowB,$AlphaFactor);
  935. imagesetpixel($this->Picture,$X+$this->ShadowX,$Y+$this->ShadowY,$ShadowColor);
  936. }
  937. $C_Aliased = $this->allocateColor($this->Picture,$R,$G,$B,$Alpha);
  938. imagesetpixel($this->Picture,$X,$Y,$C_Aliased);
  939. }
  940. /* Convert apha to base 10 */
  941. function convertAlpha($AlphaValue)
  942. { return((127/100)*(100-$AlphaValue)); }
  943. /* Allocate a color with transparency */
  944. function allocateColor($Picture,$R,$G,$B,$Alpha=100)
  945. {
  946. if ( $R < 0 ) { $R = 0; } if ( $R > 255 ) { $R = 255; }
  947. if ( $G < 0 ) { $G = 0; } if ( $G > 255 ) { $G = 255; }
  948. if ( $B < 0 ) { $B = 0; } if ( $B > 255 ) { $B = 255; }
  949. if ( $Alpha < 0 ) { $Alpha = 0; }
  950. if ( $Alpha > 100) { $Alpha = 100; }
  951. $Alpha = $this->convertAlpha($Alpha);
  952. return(imagecolorallocatealpha($Picture,$R,$G,$B,$Alpha));
  953. }
  954. /* Load a PNG file and draw it over the chart */
  955. function drawFromPNG($X,$Y,$FileName)
  956. { $this->drawFromPicture(1,$FileName,$X,$Y); }
  957. /* Load a GIF file and draw it over the chart */
  958. function drawFromGIF($X,$Y,$FileName)
  959. { $this->drawFromPicture(2,$FileName,$X,$Y); }
  960. /* Load a JPEG file and draw it over the chart */
  961. function drawFromJPG($X,$Y,$FileName)
  962. { $this->drawFromPicture(3,$FileName,$X,$Y); }
  963. function getPicInfo($FileName)
  964. {
  965. $

Large files files are truncated, but you can click here to view the full file