--- a/lib/pChart2.1.0/class/pDraw.class.php +++ b/lib/pChart2.1.0/class/pDraw.class.php @@ -1,1 +1,4960 @@ - +DataSet->getData(); + + foreach($Data["Series"] as $SerieName => $Serie) + { if ( $Serie["isDrawable"] == TRUE && $SerieName != $Data["Abscissa"] ) { $Results++; } } + + return($Results); + } + + /* Fix box coordinates */ + function fixBoxCoordinates($Xa,$Ya,$Xb,$Yb) + { + $X1 = min($Xa,$Xb); $Y1 = min($Ya,$Yb); + $X2 = max($Xa,$Xb); $Y2 = max($Ya,$Yb); + + return(array($X1,$Y1,$X2,$Y2)); + } + + /* Draw a polygon */ + function drawPolygon($Points,$Format="") + { + $R = isset($Format["R"]) ? $Format["R"] : 0; + $G = isset($Format["G"]) ? $Format["G"] : 0; + $B = isset($Format["B"]) ? $Format["B"] : 0; + $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100; + $NoBorder = isset($Format["NoBorder"]) ? $Format["NoBorder"] : FALSE; + $BorderR = isset($Format["BorderR"]) ? $Format["BorderR"] : $R; + $BorderG = isset($Format["BorderG"]) ? $Format["BorderG"] : $G; + $BorderB = isset($Format["BorderB"]) ? $Format["BorderB"] : $B; + $BorderAlpha = isset($Format["Alpha"]) ? $Format["Alpha"] : $Alpha / 2; + $Surrounding = isset($Format["Surrounding"]) ? $Format["Surrounding"] : NULL; + $SkipX = isset($Format["SkipX"]) ? $Format["SkipX"] : OUT_OF_SIGHT; + $SkipY = isset($Format["SkipY"]) ? $Format["SkipY"] : OUT_OF_SIGHT; + + /* Calling the ImageFilledPolygon() function over the $Points array will round it */ + $Backup = $Points; + + if ( $Surrounding != NULL ) { $BorderR = $R+$Surrounding; $BorderG = $G+$Surrounding; $BorderB = $B+$Surrounding; } + + if ( $SkipX != OUT_OF_SIGHT ) { $SkipX = floor($SkipX); } + if ( $SkipY != OUT_OF_SIGHT ) { $SkipY = floor($SkipY); } + + $RestoreShadow = $this->Shadow; + if ( $this->Shadow && $this->ShadowX != 0 && $this->ShadowY != 0 ) + { + $this->Shadow = FALSE; + for($i=0;$i<=count($Points)-1;$i=$i+2) + { $Shadow[] = $Points[$i] + $this->ShadowX; $Shadow[] = $Points[$i+1] + $this->ShadowY; } + $this->drawPolygon($Shadow,array("R"=>$this->ShadowR,"G"=>$this->ShadowG,"B"=>$this->ShadowB,"Alpha"=>$this->Shadowa,"NoBorder"=>TRUE)); + } + + $FillColor = $this->allocateColor($this->Picture,$R,$G,$B,$Alpha); + + if ( count($Points) >= 6 ) + { ImageFilledPolygon($this->Picture,$Points,count($Points)/2,$FillColor); } + + if ( !$NoBorder ) + { + $Points = $Backup; + + $BorderSettings = array("R"=>$BorderR,"G"=>$BorderG,"B"=>$BorderB,"Alpha"=>$BorderAlpha); + for($i=0;$i<=count($Points)-1;$i=$i+2) + { + if ( isset($Points[$i+2]) ) + { + if ( !($Points[$i] == $Points[$i+2] && $Points[$i] == $SkipX ) && !($Points[$i+1] == $Points[$i+3] && $Points[$i+1] == $SkipY ) ) + $this->drawLine($Points[$i],$Points[$i+1],$Points[$i+2],$Points[$i+3],$BorderSettings); + } + else + { + if ( !($Points[$i] == $Points[0] && $Points[$i] == $SkipX ) && !($Points[$i+1] == $Points[1] && $Points[$i+1] == $SkipY ) ) + $this->drawLine($Points[$i],$Points[$i+1],$Points[0],$Points[1],$BorderSettings); + } + } + } + + $this->Shadow = $RestoreShadow; + } + + /* Apply AALias correction to the rounded box boundaries */ + function offsetCorrection($Value,$Mode) + { + $Value = round($Value,1); + + if ( $Value == 0 && $Mode == 1 ) { return(.9); } + if ( $Value == 0 ) { return(0); } + + if ( $Mode == 1) + { 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); }; } + + if ( $Mode == 2) + { 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); }; } + + if ( $Mode == 3) + { 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); }; } + + if ( $Mode == 4) + { 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); }; } + } + + /* Draw a rectangle with rounded corners */ + function drawRoundedRectangle($X1,$Y1,$X2,$Y2,$Radius,$Format="") + { + $R = isset($Format["R"]) ? $Format["R"] : 0; + $G = isset($Format["G"]) ? $Format["G"] : 0; + $B = isset($Format["B"]) ? $Format["B"] : 0; + $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100; + + list($X1,$Y1,$X2,$Y2) = $this->fixBoxCoordinates($X1,$Y1,$X2,$Y2); + + if ( $X2 - $X1 < $Radius ) { $Radius = floor((($X2-$X1))/2); } + if ( $Y2 - $Y1 < $Radius ) { $Radius = floor((($Y2-$Y1))/2); } + + $Color = array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"NoBorder"=>TRUE); + + if ( $Radius <= 0 ) { $this->drawRectangle($X1,$Y1,$X2,$Y2,$Color); return(0); } + + if ( $this->Antialias ) + { + $this->drawLine($X1+$Radius,$Y1,$X2-$Radius,$Y1,$Color); + $this->drawLine($X2,$Y1+$Radius,$X2,$Y2-$Radius,$Color); + $this->drawLine($X2-$Radius,$Y2,$X1+$Radius,$Y2,$Color); + $this->drawLine($X1,$Y1+$Radius,$X1,$Y2-$Radius,$Color); + } + else + { + $Color = $this->allocateColor($this->Picture,$R,$G,$B,$Alpha); + imageline($this->Picture,$X1+$Radius,$Y1,$X2-$Radius,$Y1,$Color); + imageline($this->Picture,$X2,$Y1+$Radius,$X2,$Y2-$Radius,$Color); + imageline($this->Picture,$X2-$Radius,$Y2,$X1+$Radius,$Y2,$Color); + imageline($this->Picture,$X1,$Y1+$Radius,$X1,$Y2-$Radius,$Color); + } + + $Step = 360 / (2 * PI * $Radius); + for($i=0;$i<=90;$i=$i+$Step) + { + $X = cos(($i+180)*PI/180) * $Radius + $X1 + $Radius; + $Y = sin(($i+180)*PI/180) * $Radius + $Y1 + $Radius; + $this->drawAntialiasPixel($X,$Y,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha)); + + $X = cos(($i+90)*PI/180) * $Radius + $X1 + $Radius; + $Y = sin(($i+90)*PI/180) * $Radius + $Y2 - $Radius; + $this->drawAntialiasPixel($X,$Y,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha)); + + $X = cos($i*PI/180) * $Radius + $X2 - $Radius; + $Y = sin($i*PI/180) * $Radius + $Y2 - $Radius; + $this->drawAntialiasPixel($X,$Y,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha)); + + $X = cos(($i+270)*PI/180) * $Radius + $X2 - $Radius; + $Y = sin(($i+270)*PI/180) * $Radius + $Y1 + $Radius; + $this->drawAntialiasPixel($X,$Y,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha)); + } + } + + /* Draw a rectangle with rounded corners */ + function drawRoundedFilledRectangle($X1,$Y1,$X2,$Y2,$Radius,$Format="") + { + $R = isset($Format["R"]) ? $Format["R"] : 0; + $G = isset($Format["G"]) ? $Format["G"] : 0; + $B = isset($Format["B"]) ? $Format["B"] : 0; + $BorderR = isset($Format["BorderR"]) ? $Format["BorderR"] : -1; + $BorderG = isset($Format["BorderG"]) ? $Format["BorderG"] : -1; + $BorderB = isset($Format["BorderB"]) ? $Format["BorderB"] : -1; + $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100; + $Surrounding = isset($Format["Surrounding"]) ? $Format["Surrounding"] : NULL; + + if ( $Surrounding != NULL ) { $BorderR = $R+$Surrounding; $BorderG = $G+$Surrounding; $BorderB = $B+$Surrounding; } + if ( $BorderR == -1 ) { $BorderR = $R; $BorderG = $G; $BorderB = $B; } + + list($X1,$Y1,$X2,$Y2) = $this->fixBoxCoordinates($X1,$Y1,$X2,$Y2); + + if ( $X2 - $X1 < $Radius ) { $Radius = floor((($X2-$X1))/2); } + if ( $Y2 - $Y1 < $Radius ) { $Radius = floor((($Y2-$Y1))/2); } + + $RestoreShadow = $this->Shadow; + if ( $this->Shadow && $this->ShadowX != 0 && $this->ShadowY != 0 ) + { + $this->Shadow = FALSE; + $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)); + } + + $Color = array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"NoBorder"=>TRUE); + + if ( $Radius <= 0 ) { $this->drawFilledRectangle($X1,$Y1,$X2,$Y2,$Color); return(0); } + + $YTop = $Y1+$Radius; + $YBottom = $Y2-$Radius; + + $Step = 360 / (2 * PI * $Radius); + $Positions = ""; $Radius--; $MinY = ""; $MaxY = ""; + for($i=0;$i<=90;$i=$i+$Step) + { + $Xp1 = cos(($i+180)*PI/180) * $Radius + $X1 + $Radius; + $Xp2 = cos(((90-$i)+270)*PI/180) * $Radius + $X2 - $Radius; + $Yp = floor(sin(($i+180)*PI/180) * $Radius + $YTop); + if ( $MinY == "" || $Yp > $MinY ) { $MinY = $Yp; } + + if ( !isset($Positions[$Yp]) ) + { $Positions[$Yp]["X1"] = $Xp1; $Positions[$Yp]["X2"] = $Xp2; } + else + { $Positions[$Yp]["X1"] = min($Positions[$Yp]["X1"],$Xp1); $Positions[$Yp]["X2"] = max($Positions[$Yp]["X2"],$Xp2); } + + $Xp1 = cos(($i+90)*PI/180) * $Radius + $X1 + $Radius; + $Xp2 = cos((90-$i)*PI/180) * $Radius + $X2 - $Radius; + $Yp = floor(sin(($i+90)*PI/180) * $Radius + $YBottom); + if ( $MaxY == "" || $Yp < $MaxY ) { $MaxY = $Yp; } + + if ( !isset($Positions[$Yp]["Bottom"]) ) + { $Positions[$Yp]["X1"] = $Xp1; $Positions[$Yp]["X2"] = $Xp2; } + else + { $Positions[$Yp]["X1"] = min($Positions[$Yp]["X1"],$Xp1); $Positions[$Yp]["X2"] = max($Positions[$Yp]["X2"],$Xp2); } + } + + $ManualColor = $this->allocateColor($this->Picture,$R,$G,$B,$Alpha); + foreach($Positions as $Yp => $Bounds) + { + $X1 = $Bounds["X1"]; $X1Dec = $this->getFirstDecimal($X1); if ( $X1Dec != 0 ) { $X1 = floor($X1)+1; } + $X2 = $Bounds["X2"]; $X2Dec = $this->getFirstDecimal($X2); if ( $X2Dec != 0 ) { $X2 = floor($X2)-1; } + + imageline($this->Picture,$X1,$Yp,$X2,$Yp,$ManualColor); + } + $this->drawFilledRectangle($X1,$MinY+1,floor($X2),$MaxY-1,$Color); + + $Radius++; + $this->drawRoundedRectangle($X1,$Y1,$X2+1,$Y2-1,$Radius,array("R"=>$BorderR,"G"=>$BorderG,"B"=>$BorderB,"Alpha"=>$Alpha)); + + $this->Shadow = $RestoreShadow; + } + + /* Draw a rectangle with rounded corners */ + function drawRoundedFilledRectangle_deprecated($X1,$Y1,$X2,$Y2,$Radius,$Format="") + { + $R = isset($Format["R"]) ? $Format["R"] : 0; + $G = isset($Format["G"]) ? $Format["G"] : 0; + $B = isset($Format["B"]) ? $Format["B"] : 0; + $BorderR = isset($Format["BorderR"]) ? $Format["BorderR"] : -1; + $BorderG = isset($Format["BorderG"]) ? $Format["BorderG"] : -1; + $BorderB = isset($Format["BorderB"]) ? $Format["BorderB"] : -1; + $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100; + $Surrounding = isset($Format["Surrounding"]) ? $Format["Surrounding"] : NULL; + + if ( $Surrounding != NULL ) { $BorderR = $R+$Surrounding; $BorderG = $G+$Surrounding; $BorderB = $B+$Surrounding; } + if ( $BorderR == -1 ) { $BorderR = $R; $BorderG = $G; $BorderB = $B; } + + list($X1,$Y1,$X2,$Y2) = $this->fixBoxCoordinates($X1,$Y1,$X2,$Y2); + + if ( $X2 - $X1 < $Radius ) { $Radius = floor((($X2-$X1)+2)/2); } + if ( $Y2 - $Y1 < $Radius ) { $Radius = floor((($Y2-$Y1)+2)/2); } + + $RestoreShadow = $this->Shadow; + if ( $this->Shadow && $this->ShadowX != 0 && $this->ShadowY != 0 ) + { + $this->Shadow = FALSE; + $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)); + } + + if ( $this->getFirstDecimal($X2) >= 5 ) { $XOffset2 = 1; } else { $XOffset2 = 0; } + if ( $this->getFirstDecimal($X1) <= 5 ) { $XOffset1 = 1; } else { $XOffset1 = 0; } + + if ( !$this->Antialias ) { $XOffset1 = 1; $XOffset2 = 1; } + + $YTop = floor($Y1+$Radius); + $YBottom = floor($Y2-$Radius); + + $this->drawFilledRectangle($X1-$XOffset1,$YTop,$X2+$XOffset2,$YBottom,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"NoBorder"=>TRUE)); + + $Step = 360 / (2 * PI * $Radius); + $Color = $this->allocateColor($this->Picture,$R,$G,$B,$Alpha); + $Color2 = $this->allocateColor($this->Picture,255,0,0,$Alpha); + $Drawn = ""; + + if ( $Alpha < 100 ) { $Drawn[$YTop] = FALSE; } + if ( $Alpha < 100 ) { $Drawn[$YBottom] = TRUE; } + + for($i=0;$i<=90;$i=$i+$Step) + { + $Xp1 = cos(($i+180)*PI/180) * $Radius + $X1 + $Radius; + $Xp2 = cos(((90-$i)+270)*PI/180) * $Radius + $X2 - $Radius; + $Yp = sin(($i+180)*PI/180) * $Radius + $YTop; + + if ( $this->getFirstDecimal($Xp1) > 5 ) { $XOffset1 = 1; } else { $XOffset1 = 0; } + if ( $this->getFirstDecimal($Xp2) > 5 ) { $XOffset2 = 1; } else { $XOffset2 = 0; } + if ( $this->getFirstDecimal($Yp) > 5 ) { $YOffset = 1; } else { $YOffset = 0; } + + if ( !isset($Drawn[$Yp+$YOffset]) || $Alpha == 100 ) + imageline($this->Picture,$Xp1+$XOffset1,$Yp+$YOffset,$Xp2+$XOffset2,$Yp+$YOffset,$Color); + + $Drawn[$Yp+$YOffset] = $Xp2; + + $Xp1 = cos(($i+90)*PI/180) * $Radius + $X1 + $Radius; + $Xp2 = cos((90-$i)*PI/180) * $Radius + $X2 - $Radius; + $Yp = sin(($i+90)*PI/180) * $Radius + $YBottom; + + if ( $this->getFirstDecimal($Xp1) > 7 ) { $XOffset1 = 1; } else { $XOffset1 = 0; } + if ( $this->getFirstDecimal($Xp2) > 7 ) { $XOffset2 = 1; } else { $XOffset2 = 0; } + if ( $this->getFirstDecimal($Yp) > 5 ) { $YOffset = 1; } else { $YOffset = 0; } + + if ( !isset($Drawn[$Yp+$YOffset]) || $Alpha == 100 ) + imageline($this->Picture,$Xp1+$XOffset1,$Yp+$YOffset,$Xp2+$XOffset2,$Yp+$YOffset,$Color); + + $Drawn[$Yp+$YOffset] = $Xp2; + } + + $this->drawRoundedRectangle($X1,$Y1,$X2,$Y2,$Radius,array("R"=>$BorderR,"G"=>$BorderG,"B"=>$BorderB,"Alpha"=>$Alpha)); + + $this->Shadow = $RestoreShadow; + } + + /* Draw a rectangle */ + function drawRectangle($X1,$Y1,$X2,$Y2,$Format="") + { + $R = isset($Format["R"]) ? $Format["R"] : 0; + $G = isset($Format["G"]) ? $Format["G"] : 0; + $B = isset($Format["B"]) ? $Format["B"] : 0; + $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100; + $Ticks = isset($Format["Ticks"]) ? $Format["Ticks"] : NULL; + $NoAngle = isset($Format["NoAngle"]) ? $Format["NoAngle"] : FALSE; + + if ($X1 > $X2) { list($X1, $X2) = array($X2, $X1); } + if ($Y1 > $Y2) { list($Y1, $Y2) = array($Y2, $Y1); } + + if ( $this->Antialias ) + { + if ( $NoAngle ) + { + $this->drawLine($X1+1,$Y1,$X2-1,$Y1,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"Ticks"=>$Ticks)); + $this->drawLine($X2,$Y1+1,$X2,$Y2-1,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"Ticks"=>$Ticks)); + $this->drawLine($X2-1,$Y2,$X1+1,$Y2,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"Ticks"=>$Ticks)); + $this->drawLine($X1,$Y1+1,$X1,$Y2-1,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"Ticks"=>$Ticks)); + } + else + { + $this->drawLine($X1+1,$Y1,$X2-1,$Y1,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"Ticks"=>$Ticks)); + $this->drawLine($X2,$Y1,$X2,$Y2,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"Ticks"=>$Ticks)); + $this->drawLine($X2-1,$Y2,$X1+1,$Y2,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"Ticks"=>$Ticks)); + $this->drawLine($X1,$Y1,$X1,$Y2,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"Ticks"=>$Ticks)); + } + } + else + { + $Color = $this->allocateColor($this->Picture,$R,$G,$B,$Alpha); + imagerectangle($this->Picture,$X1,$Y1,$X2,$Y2,$Color); + } + } + + /* Draw a filled rectangle */ + function drawFilledRectangle($X1,$Y1,$X2,$Y2,$Format="") + { + $R = isset($Format["R"]) ? $Format["R"] : 0; + $G = isset($Format["G"]) ? $Format["G"] : 0; + $B = isset($Format["B"]) ? $Format["B"] : 0; + $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100; + $BorderR = isset($Format["BorderR"]) ? $Format["BorderR"] : -1; + $BorderG = isset($Format["BorderG"]) ? $Format["BorderG"] : -1; + $BorderB = isset($Format["BorderB"]) ? $Format["BorderB"] : -1; + $BorderAlpha = isset($Format["BorderAlpha"]) ? $Format["BorderAlpha"] : $Alpha; + $Surrounding = isset($Format["Surrounding"]) ? $Format["Surrounding"] : NULL; + $Ticks = isset($Format["Ticks"]) ? $Format["Ticks"] : NULL; + $NoAngle = isset($Format["NoAngle"]) ? $Format["NoAngle"] : NULL; + $Dash = isset($Format["Dash"]) ? $Format["Dash"] : FALSE; + $DashStep = isset($Format["DashStep"]) ? $Format["DashStep"] : 4; + $DashR = isset($Format["DashR"]) ? $Format["DashR"] : 0; + $DashG = isset($Format["DashG"]) ? $Format["DashG"] : 0; + $DashB = isset($Format["DashB"]) ? $Format["DashB"] : 0; + $NoBorder = isset($Format["NoBorder"]) ? $Format["NoBorder"] : FALSE; + + if ( $Surrounding != NULL ) { $BorderR = $R+$Surrounding; $BorderG = $G+$Surrounding; $BorderB = $B+$Surrounding; } + + if ($X1 > $X2) { list($X1, $X2) = array($X2, $X1); } + if ($Y1 > $Y2) { list($Y1, $Y2) = array($Y2, $Y1); } + + $RestoreShadow = $this->Shadow; + if ( $this->Shadow && $this->ShadowX != 0 && $this->ShadowY != 0 ) + { + $this->Shadow = FALSE; + $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)); + } + + $Color = $this->allocateColor($this->Picture,$R,$G,$B,$Alpha); + if ( $NoAngle ) + { + imagefilledrectangle($this->Picture,ceil($X1)+1,ceil($Y1),floor($X2)-1,floor($Y2),$Color); + imageline($this->Picture,ceil($X1),ceil($Y1)+1,ceil($X1),floor($Y2)-1,$Color); + imageline($this->Picture,floor($X2),ceil($Y1)+1,floor($X2),floor($Y2)-1,$Color); + } + else + imagefilledrectangle($this->Picture,ceil($X1),ceil($Y1),floor($X2),floor($Y2),$Color); + + if ( $Dash ) + { + if ( $BorderR != -1 ) { $iX1=$X1+1; $iY1=$Y1+1; $iX2=$X2-1; $iY2=$Y2-1; } else { $iX1=$X1; $iY1=$Y1; $iX2=$X2; $iY2=$Y2; } + + $Color = $this->allocateColor($this->Picture,$DashR,$DashG,$DashB,$Alpha); + $Y=$iY1-$DashStep; + for($X=$iX1; $X<=$iX2+($iY2-$iY1); $X=$X+$DashStep) + { + $Y=$Y+$DashStep; + if ( $X > $iX2 ) { $Xa = $X-($X-$iX2); $Ya = $iY1+($X-$iX2); } else { $Xa = $X; $Ya = $iY1; } + if ( $Y > $iY2 ) { $Xb = $iX1+($Y-$iY2); $Yb = $Y-($Y-$iY2); } else { $Xb = $iX1; $Yb = $Y; } + imageline($this->Picture,$Xa,$Ya,$Xb,$Yb,$Color); + } + } + + if ( $this->Antialias && !$NoBorder ) + { + if ( $X1 < ceil($X1) ) + { + $AlphaA = $Alpha * (ceil($X1) - $X1); + $Color = $this->allocateColor($this->Picture,$R,$G,$B,$AlphaA); + imageline($this->Picture,ceil($X1)-1,ceil($Y1),ceil($X1)-1,floor($Y2),$Color); + } + + if ( $Y1 < ceil($Y1) ) + { + $AlphaA = $Alpha * (ceil($Y1) - $Y1); + $Color = $this->allocateColor($this->Picture,$R,$G,$B,$AlphaA); + imageline($this->Picture,ceil($X1),ceil($Y1)-1,floor($X2),ceil($Y1)-1,$Color); + } + + if ( $X2 > floor($X2) ) + { + $AlphaA = $Alpha * (.5-($X2 - floor($X2))); + $Color = $this->allocateColor($this->Picture,$R,$G,$B,$AlphaA); + imageline($this->Picture,floor($X2)+1,ceil($Y1),floor($X2)+1,floor($Y2),$Color); + } + + if ( $Y2 > floor($Y2) ) + { + $AlphaA = $Alpha * (.5-($Y2 - floor($Y2))); + $Color = $this->allocateColor($this->Picture,$R,$G,$B,$AlphaA); + imageline($this->Picture,ceil($X1),floor($Y2)+1,floor($X2),floor($Y2)+1,$Color); + } + } + + if ( $BorderR != -1 ) + $this->drawRectangle($X1,$Y1,$X2,$Y2,array("R"=>$BorderR,"G"=>$BorderG,"B"=>$BorderB,"Alpha"=>$BorderAlpha,"Ticks"=>$Ticks,"NoAngle"=>$NoAngle)); + + $this->Shadow = $RestoreShadow; + } + + /* Draw a rectangular marker of the specified size */ + function drawRectangleMarker($X,$Y,$Format="") + { + $Size = isset($Format["Size"]) ? $Format["Size"] : 4; + + $HalfSize = floor($Size/2); + $this->drawFilledRectangle($X-$HalfSize,$Y-$HalfSize,$X+$HalfSize,$Y+$HalfSize,$Format); + } + + /* Drawn a spline based on the bezier function */ + function drawSpline($Coordinates,$Format="") + { + $R = isset($Format["R"]) ? $Format["R"] : 0; + $G = isset($Format["G"]) ? $Format["G"] : 0; + $B = isset($Format["B"]) ? $Format["B"] : 0; + $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100; + $Force = isset($Format["Force"]) ? $Format["Force"] : 30; + $Forces = isset($Format["Forces"]) ? $Format["Forces"] : NULL; + $ShowC = isset($Format["ShowControl"]) ? $Format["ShowControl"] : FALSE; + $Ticks = isset($Format["Ticks"]) ? $Format["Ticks"] : NULL; + $PathOnly = isset($Format["PathOnly"]) ? $Format["PathOnly"] : FALSE; + $Weight = isset($Format["Weight"]) ? $Format["Weight"] : NULL; + + $Cpt = NULL; $Mode = NULL; $Result = ""; + for($i=1;$i<=count($Coordinates)-1;$i++) + { + $X1 = $Coordinates[$i-1][0]; $Y1 = $Coordinates[$i-1][1]; + $X2 = $Coordinates[$i][0]; $Y2 = $Coordinates[$i][1]; + + if ( $Forces != NULL ) { $Force = $Forces[$i]; } + + /* First segment */ + if ( $i == 1 ) + { $Xv1 = $X1; $Yv1 = $Y1; } + else + { + $Angle1 = $this->getAngle($XLast,$YLast,$X1,$Y1); + $Angle2 = $this->getAngle($X1,$Y1,$X2,$Y2); + $XOff = cos($Angle2 * PI / 180) * $Force + $X1; + $YOff = sin($Angle2 * PI / 180) * $Force + $Y1; + + $Xv1 = cos($Angle1 * PI / 180) * $Force + $XOff; + $Yv1 = sin($Angle1 * PI / 180) * $Force + $YOff; + } + + /* Last segment */ + if ( $i == count($Coordinates)-1 ) + { $Xv2 = $X2; $Yv2 = $Y2; } + else + { + $Angle1 = $this->getAngle($X2,$Y2,$Coordinates[$i+1][0],$Coordinates[$i+1][1]); + $Angle2 = $this->getAngle($X1,$Y1,$X2,$Y2); + $XOff = cos(($Angle2+180) * PI / 180) * $Force + $X2; + $YOff = sin(($Angle2+180) * PI / 180) * $Force + $Y2; + + $Xv2 = cos(($Angle1+180) * PI / 180) * $Force + $XOff; + $Yv2 = sin(($Angle1+180) * PI / 180) * $Force + $YOff; + } + + $Path = $this->drawBezier($X1,$Y1,$X2,$Y2,$Xv1,$Yv1,$Xv2,$Yv2,$Format); + if ($PathOnly) { $Result[] = $Path; } + + $XLast = $X1; $YLast = $Y1; + } + + return($Result); + } + + /* Draw a bezier curve with two controls points */ + function drawBezier($X1,$Y1,$X2,$Y2,$Xv1,$Yv1,$Xv2,$Yv2,$Format="") + { + $R = isset($Format["R"]) ? $Format["R"] : 0; + $G = isset($Format["G"]) ? $Format["G"] : 0; + $B = isset($Format["B"]) ? $Format["B"] : 0; + $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100; + $ShowC = isset($Format["ShowControl"]) ? $Format["ShowControl"] : FALSE; + $Segments = isset($Format["Segments"]) ? $Format["Segments"] : NULL; + $Ticks = isset($Format["Ticks"]) ? $Format["Ticks"] : NULL; + $NoDraw = isset($Format["NoDraw"]) ? $Format["NoDraw"] : FALSE; + $PathOnly = isset($Format["PathOnly"]) ? $Format["PathOnly"] : FALSE; + $Weight = isset($Format["Weight"]) ? $Format["Weight"] : NULL; + $DrawArrow = isset($Format["DrawArrow"]) ? $Format["DrawArrow"] : FALSE; + $ArrowSize = isset($Format["ArrowSize"]) ? $Format["ArrowSize"] : 10; + $ArrowRatio = isset($Format["ArrowRatio"]) ? $Format["ArrowRatio"] : .5; + $ArrowTwoHeads = isset($Format["ArrowTwoHeads"]) ? $Format["ArrowTwoHeads"] : FALSE; + + if ( $Segments == NULL ) + { + $Length = $this->getLength($X1,$Y1,$X2,$Y2); + $Precision = ($Length*125)/1000; + } + else + $Precision = $Segments; + + $P[0]["X"] = $X1; $P[0]["Y"] = $Y1; + $P[1]["X"] = $Xv1; $P[1]["Y"] = $Yv1; + $P[2]["X"] = $Xv2; $P[2]["Y"] = $Yv2; + $P[3]["X"] = $X2; $P[3]["Y"] = $Y2; + + /* Compute the bezier points */ + $Q = ""; $ID = 0; $Path = ""; + for($i=0;$i<=$Precision;$i=$i+1) + { + $u = $i / $Precision; + + $C = ""; + $C[0] = (1 - $u) * (1 - $u) * (1 - $u); + $C[1] = ($u * 3) * (1 - $u) * (1 - $u); + $C[2] = 3 * $u * $u * (1 - $u); + $C[3] = $u * $u * $u; + + for($j=0;$j<=3;$j++) + { + if ( !isset($Q[$ID]) ) { $Q[$ID] = ""; } + if ( !isset($Q[$ID]["X"]) ) { $Q[$ID]["X"] = 0; } + if ( !isset($Q[$ID]["Y"]) ) { $Q[$ID]["Y"] = 0; } + + $Q[$ID]["X"] = $Q[$ID]["X"] + $P[$j]["X"] * $C[$j]; + $Q[$ID]["Y"] = $Q[$ID]["Y"] + $P[$j]["Y"] * $C[$j]; + } + $ID++; + } + $Q[$ID]["X"] = $X2; $Q[$ID]["Y"] = $Y2; + + if ( !$NoDraw ) + { + /* Display the control points */ + if ( $ShowC && !$PathOnly ) + { + $Xv1 = floor($Xv1); $Yv1 = floor($Yv1); $Xv2 = floor($Xv2); $Yv2 = floor($Yv2); + + $this->drawLine($X1,$Y1,$X2,$Y2,array("R"=>0,"G"=>0,"B"=>0,"Alpha"=>30)); + + $MyMarkerSettings = array("R"=>255,"G"=>0,"B"=>0,"BorderR"=>255,"BorderB"=>255,"BorderG"=>255,"Size"=>4); + $this->drawRectangleMarker($Xv1,$Yv1,$MyMarkerSettings); + $this->drawText($Xv1+4,$Yv1,"v1"); + $MyMarkerSettings = array("R"=>0,"G"=>0,"B"=>255,"BorderR"=>255,"BorderB"=>255,"BorderG"=>255,"Size"=>4); + $this->drawRectangleMarker($Xv2,$Yv2,$MyMarkerSettings); + $this->drawText($Xv2+4,$Yv2,"v2"); + } + + /* Draw the bezier */ + $LastX = NULL; $LastY = NULL; $Cpt = NULL; $Mode = NULL; $ArrowS = NULL; + foreach ($Q as $Key => $Point) + { + $X = $Point["X"]; $Y = $Point["Y"]; + + /* Get the first segment */ + if ( $ArrowS == NULL && $LastX != NULL && $LastY != NULL ) + { $ArrowS["X2"] = $LastX; $ArrowS["Y2"] = $LastY; $ArrowS["X1"] = $X; $ArrowS["Y1"] = $Y; } + + if ( $LastX != NULL && $LastY != NULL && !$PathOnly) + 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)); + + /* Get the last segment */ + $ArrowE["X1"] = $LastX; $ArrowE["Y1"] = $LastY; $ArrowE["X2"] = $X; $ArrowE["Y2"] = $Y; + + $LastX = $X; $LastY = $Y; + } + + if ( $DrawArrow && !$PathOnly ) + { + $ArrowSettings = array("FillR"=>$R,"FillG"=>$G,"FillB"=>$B,"Alpha"=>$Alpha,"Size"=>$ArrowSize,"Ratio"=>$ArrowRatio); + if ( $ArrowTwoHeads ) + $this->drawArrow($ArrowS["X1"],$ArrowS["Y1"],$ArrowS["X2"],$ArrowS["Y2"],$ArrowSettings); + + $this->drawArrow($ArrowE["X1"],$ArrowE["Y1"],$ArrowE["X2"],$ArrowE["Y2"],$ArrowSettings); + } + } + return($Q); + } + + /* Draw a line between two points */ + function drawLine($X1,$Y1,$X2,$Y2,$Format="") + { + $R = isset($Format["R"]) ? $Format["R"] : 0; + $G = isset($Format["G"]) ? $Format["G"] : 0; + $B = isset($Format["B"]) ? $Format["B"] : 0; + $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100; + $Ticks = isset($Format["Ticks"]) ? $Format["Ticks"] : NULL; + $Cpt = isset($Format["Cpt"]) ? $Format["Cpt"] : 1; + $Mode = isset($Format["Mode"]) ? $Format["Mode"] : 1; + $Weight = isset($Format["Weight"]) ? $Format["Weight"] : NULL; + + if ( $this->Antialias == FALSE && $Ticks == NULL ) + { + if ( $this->Shadow && $this->ShadowX != 0 && $this->ShadowY != 0 ) + { + $ShadowColor = $this->allocateColor($this->Picture,$this->ShadowR,$this->ShadowG,$this->ShadowB,$this->Shadowa); + imageline($this->Picture,$X1+$this->ShadowX,$Y1+$this->ShadowY,$X2+$this->ShadowX,$Y2+$this->ShadowY,$ShadowColor); + } + + $Color = $this->allocateColor($this->Picture,$R,$G,$B,$Alpha); + imageline($this->Picture,$X1,$Y1,$X2,$Y2,$Color); + return(0); + } + + $Distance = sqrt(($X2-$X1)*($X2-$X1)+($Y2-$Y1)*($Y2-$Y1)); + if ( $Distance == 0 ) { return(-1); } + + /* Derivative algorithm for overweighted lines, re-route to polygons primitives */ + if ( $Weight != NULL ) + { + $Angle = $this->getAngle($X1,$Y1,$X2,$Y2); + $PolySettings = array ("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"BorderAlpha"=>$Alpha); + + if ( $Ticks == NULL ) + { + $Points = ""; + $Points[] = cos(deg2rad($Angle-90)) * $Weight + $X1; $Points[] = sin(deg2rad($Angle-90)) * $Weight + $Y1; + $Points[] = cos(deg2rad($Angle+90)) * $Weight + $X1; $Points[] = sin(deg2rad($Angle+90)) * $Weight + $Y1; + $Points[] = cos(deg2rad($Angle+90)) * $Weight + $X2; $Points[] = sin(deg2rad($Angle+90)) * $Weight + $Y2; + $Points[] = cos(deg2rad($Angle-90)) * $Weight + $X2; $Points[] = sin(deg2rad($Angle-90)) * $Weight + $Y2; + + $this->drawPolygon($Points,$PolySettings); + } + else + { + for($i=0;$i<=$Distance;$i=$i+$Ticks*2) + { + $Xa = (($X2-$X1)/$Distance) * $i + $X1; $Ya = (($Y2-$Y1)/$Distance) * $i + $Y1; + $Xb = (($X2-$X1)/$Distance) * ($i+$Ticks) + $X1; $Yb = (($Y2-$Y1)/$Distance) * ($i+$Ticks) + $Y1; + + $Points = ""; + $Points[] = cos(deg2rad($Angle-90)) * $Weight + $Xa; $Points[] = sin(deg2rad($Angle-90)) * $Weight + $Ya; + $Points[] = cos(deg2rad($Angle+90)) * $Weight + $Xa; $Points[] = sin(deg2rad($Angle+90)) * $Weight + $Ya; + $Points[] = cos(deg2rad($Angle+90)) * $Weight + $Xb; $Points[] = sin(deg2rad($Angle+90)) * $Weight + $Yb; + $Points[] = cos(deg2rad($Angle-90)) * $Weight + $Xb; $Points[] = sin(deg2rad($Angle-90)) * $Weight + $Yb; + + $this->drawPolygon($Points,$PolySettings); + } + } + + return(1); + } + + $XStep = ($X2-$X1) / $Distance; + $YStep = ($Y2-$Y1) / $Distance; + + for($i=0;$i<=$Distance;$i++) + { + $X = $i * $XStep + $X1; + $Y = $i * $YStep + $Y1; + + if ( $Ticks != NULL ) + { + if ( $Cpt % $Ticks == 0 ) + { $Cpt = 0; if ( $Mode == 1 ) { $Mode = 0; } else { $Mode = 1; } } + + if ( $Mode == 1 ) + $this->drawAntialiasPixel($X,$Y,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha)); + + $Cpt++; + } + else + $this->drawAntialiasPixel($X,$Y,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha)); + } + return(array($Cpt,$Mode)); + } + + /* Draw a circle */ + function drawCircle($Xc,$Yc,$Height,$Width,$Format="") + { + $R = isset($Format["R"]) ? $Format["R"] : 0; + $G = isset($Format["G"]) ? $Format["G"] : 0; + $B = isset($Format["B"]) ? $Format["B"] : 0; + $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100; + $Ticks = isset($Format["Ticks"]) ? $Format["Ticks"] : NULL; + + $Height = abs($Height); + $Width = abs($Width); + + if ( $Height == 0 ) { $Height = 1; } + if ( $Width == 0 ) { $Width = 1; } + $Xc = floor($Xc); $Yc = floor($Yc); + + $RestoreShadow = $this->Shadow; + if ( $this->Shadow && $this->ShadowX != 0 && $this->ShadowY != 0 ) + { + $this->Shadow = FALSE; + $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)); + } + + if ( $Width == 0 ) { $Width = $Height; } + if ( $R < 0 ) { $R = 0; } if ( $R > 255 ) { $R = 255; } + if ( $G < 0 ) { $G = 0; } if ( $G > 255 ) { $G = 255; } + if ( $B < 0 ) { $B = 0; } if ( $B > 255 ) { $B = 255; } + + $Step = 360 / (2 * PI * max($Width,$Height)); + $Mode = 1; $Cpt = 1; + for($i=0;$i<=360;$i=$i+$Step) + { + $X = cos($i*PI/180) * $Height + $Xc; + $Y = sin($i*PI/180) * $Width + $Yc; + + if ( $Ticks != NULL ) + { + if ( $Cpt % $Ticks == 0 ) + { $Cpt = 0; if ( $Mode == 1 ) { $Mode = 0; } else { $Mode = 1; } } + + if ( $Mode == 1 ) + $this->drawAntialiasPixel($X,$Y,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha)); + + $Cpt++; + } + else + $this->drawAntialiasPixel($X,$Y,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha)); + + } + $this->Shadow = $RestoreShadow; + } + + /* Draw a filled circle */ + function drawFilledCircle($X,$Y,$Radius,$Format="") + { + $R = isset($Format["R"]) ? $Format["R"] : 0; + $G = isset($Format["G"]) ? $Format["G"] : 0; + $B = isset($Format["B"]) ? $Format["B"] : 0; + $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100; + $BorderR = isset($Format["BorderR"]) ? $Format["BorderR"] : -1; + $BorderG = isset($Format["BorderG"]) ? $Format["BorderG"] : -1; + $BorderB = isset($Format["BorderB"]) ? $Format["BorderB"] : -1; + $BorderAlpha = isset($Format["BorderAlpha"]) ? $Format["BorderAlpha"] : $Alpha; + $Ticks = isset($Format["Ticks"]) ? $Format["Ticks"] : NULL; + $Surrounding = isset($Format["Surrounding"]) ? $Format["Surrounding"] : NULL; + + if ( $Radius == 0 ) { $Radius = 1; } + if ( $Surrounding != NULL ) { $BorderR = $R+$Surrounding; $BorderG = $G+$Surrounding; $BorderB = $B+$Surrounding; } + $X = floor($X); $Y = floor($Y); + + $Radius = abs($Radius); + + $RestoreShadow = $this->Shadow; + if ( $this->Shadow && $this->ShadowX != 0 && $this->ShadowY != 0 ) + { + $this->Shadow = FALSE; + $this->drawFilledCircle($X+$this->ShadowX,$Y+$this->ShadowY,$Radius,array("R"=>$this->ShadowR,"G"=>$this->ShadowG,"B"=>$this->ShadowB,"Alpha"=>$this->Shadowa,"Ticks"=>$Ticks)); + } + + $this->Mask = ""; + $Color = $this->allocateColor($this->Picture,$R,$G,$B,$Alpha); + for ($i=0; $i<=$Radius*2; $i++) + { + $Slice = sqrt($Radius * $Radius - ($Radius - $i) * ($Radius - $i)); + $XPos = floor($Slice); + $YPos = $Y + $i - $Radius; + $AAlias = $Slice - floor($Slice); + + $this->Mask[$X-$XPos][$YPos] = TRUE; + $this->Mask[$X+$XPos][$YPos] = TRUE; + imageline($this->Picture,$X-$XPos,$YPos,$X+$XPos,$YPos,$Color); + } + if ( $this->Antialias ) + $this->drawCircle($X,$Y,$Radius,$Radius,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"Ticks"=>$Ticks)); + + $this->Mask = ""; + + if ( $BorderR != -1 ) + $this->drawCircle($X,$Y,$Radius,$Radius,array("R"=>$BorderR,"G"=>$BorderG,"B"=>$BorderB,"Alpha"=>$BorderAlpha,"Ticks"=>$Ticks)); + + $this->Shadow = $RestoreShadow; + } + + /* Write text */ + function drawText($X,$Y,$Text,$Format="") + { + $R = isset($Format["R"]) ? $Format["R"] : $this->FontColorR; + $G = isset($Format["G"]) ? $Format["G"] : $this->FontColorG; + $B = isset($Format["B"]) ? $Format["B"] : $this->FontColorB; + $Angle = isset($Format["Angle"]) ? $Format["Angle"] : 0; + $Align = isset($Format["Align"]) ? $Format["Align"] : TEXT_ALIGN_BOTTOMLEFT; + $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : $this->FontColorA; + $FontName = isset($Format["FontName"]) ? $Format["FontName"] : $this->FontName; + $FontSize = isset($Format["FontSize"]) ? $Format["FontSize"] : $this->FontSize; + $ShowOrigine = isset($Format["ShowOrigine"]) ? $Format["ShowOrigine"] : FALSE; + $TOffset = isset($Format["TOffset"]) ? $Format["TOffset"] : 2; + $DrawBox = isset($Format["DrawBox"]) ? $Format["DrawBox"] : FALSE; + $DrawBoxBorder = isset($Format["DrawBoxBorder"]) ? $Format["DrawBoxBorder"] : TRUE; + $BorderOffset = isset($Format["BorderOffset"]) ? $Format["BorderOffset"] : 6; + $BoxRounded = isset($Format["BoxRounded"]) ? $Format["BoxRounded"] : FALSE; + $RoundedRadius = isset($Format["RoundedRadius"]) ? $Format["RoundedRadius"] : 6; + $BoxR = isset($Format["BoxR"]) ? $Format["BoxR"] : 255; + $BoxG = isset($Format["BoxG"]) ? $Format["BoxG"] : 255; + $BoxB = isset($Format["BoxB"]) ? $Format["BoxB"] : 255; + $BoxAlpha = isset($Format["BoxAlpha"]) ? $Format["BoxAlpha"] : 50; + $BoxSurrounding = isset($Format["BoxSurrounding"]) ? $Format["BoxSurrounding"] : ""; + $BoxBorderR = isset($Format["BoxR"]) ? $Format["BoxR"] : 0; + $BoxBorderG = isset($Format["BoxG"]) ? $Format["BoxG"] : 0; + $BoxBorderB = isset($Format["BoxB"]) ? $Format["BoxB"] : 0; + $BoxBorderAlpha = isset($Format["BoxAlpha"]) ? $Format["BoxAlpha"] : 50; + $NoShadow = isset($Format["NoShadow"]) ? $Format["NoShadow"] : FALSE; + + $Shadow = $this->Shadow; + if ( $NoShadow ) { $this->Shadow = FALSE; } + + if ( $BoxSurrounding != "" ) { $BoxBorderR = $BoxR - $BoxSurrounding; $BoxBorderG = $BoxG - $BoxSurrounding; $BoxBorderB = $BoxB - $BoxSurrounding; $BoxBorderAlpha = $Boxalpha; } + + if ( $ShowOrigine ) + { + $MyMarkerSettings = array("R"=>255,"G"=>0,"B"=>0,"BorderR"=>255,"BorderB"=>255,"BorderG"=>255,"Size"=>4); + $this->drawRectangleMarker($X,$Y,$MyMarkerSettings); + } + + $TxtPos = $this->getTextBox($X,$Y,$FontName,$FontSize,$Angle,$Text); + + if ( $DrawBox && ($Angle == 0 || $Angle == 90 || $Angle == 180 || $Angle == 270)) + { + $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; + 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; } + + $X1 = min($TxtPos[0]["X"],$TxtPos[1]["X"],$TxtPos[2]["X"],$TxtPos[3]["X"]) - $BorderOffset + 3; + $Y1 = min($TxtPos[0]["Y"],$TxtPos[1]["Y"],$TxtPos[2]["Y"],$TxtPos[3]["Y"]) - $BorderOffset; + $X2 = max($TxtPos[0]["X"],$TxtPos[1]["X"],$TxtPos[2]["X"],$TxtPos[3]["X"]) + $BorderOffset + 3; + $Y2 = max($TxtPos[0]["Y"],$TxtPos[1]["Y"],$TxtPos[2]["Y"],$TxtPos[3]["Y"]) + $BorderOffset - 3; + + $X1 = $X1 - $TxtPos[$Align]["X"] + $X + $T[0]["X"]; + $Y1 = $Y1 - $TxtPos[$Align]["Y"] + $Y + $T[0]["Y"]; + $X2 = $X2 - $TxtPos[$Align]["X"] + $X + $T[0]["X"]; + $Y2 = $Y2 - $TxtPos[$Align]["Y"] + $Y + $T[0]["Y"]; + + $Settings = array("R"=>$BoxR,"G"=>$BoxG,"B"=>$BoxB,"Alpha"=>$BoxAlpha,"BorderR"=>$BoxBorderR,"BorderG"=>$BoxBorderG,"BorderB"=>$BoxBorderB,"BorderAlpha"=>$BoxBorderAlpha); + + if ( $BoxRounded ) + { $this->drawRoundedFilledRectangle($X1,$Y1,$X2,$Y2,$RoundedRadius,$Settings); } + else + { $this->drawFilledRectangle($X1,$Y1,$X2,$Y2,$Settings); } + } + + $X = $X - $TxtPos[$Align]["X"] + $X; + $Y = $Y - $TxtPos[$Align]["Y"] + $Y; + + if ( $this->Shadow && $this->ShadowX != 0 && $this->ShadowY != 0 ) + { + $C_ShadowColor = $this->allocateColor($this->Picture,$this->ShadowR,$this->ShadowG,$this->ShadowB,$this->Shadowa); + imagettftext($this->Picture,$FontSize,$Angle,$X+$this->ShadowX,$Y+$this->ShadowY,$C_ShadowColor,$FontName,$Text); + } + + $C_TextColor = $this->AllocateColor($this->Picture,$R,$G,$B,$Alpha); + imagettftext($this->Picture,$FontSize,$Angle,$X,$Y,$C_TextColor,$FontName,$Text); + + $this->Shadow = $Shadow; + + return($TxtPos); + } + + /* Draw a gradient within a defined area */ + function drawGradientArea($X1,$Y1,$X2,$Y2,$Direction,$Format="") + { + $StartR = isset($Format["StartR"]) ? $Format["StartR"] : 90; + $StartG = isset($Format["StartG"]) ? $Format["StartG"] : 90; + $StartB = isset($Format["StartB"]) ? $Format["StartB"] : 90; + $EndR = isset($Format["EndR"]) ? $Format["EndR"] : 0; + $EndG = isset($Format["EndG"]) ? $Format["EndG"] : 0; + $EndB = isset($Format["EndB"]) ? $Format["EndB"] : 0; + $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100; + $Levels = isset($Format["Levels"]) ? $Format["Levels"] : NULL; + + $Shadow = $this->Shadow; + $this->Shadow = FALSE; + + if ( $StartR == $EndR && $StartG == $EndG && $StartB == $EndB ) + { + $this->drawFilledRectangle($X1,$Y1,$X2,$Y2,array("R"=>$StartR,"G"=>$StartG,"B"=>$StartB,"Alpha"=>$Alpha)); + return(0); + } + + if ( $Levels != NULL ) + { $EndR=$StartR+$Levels; $EndG=$StartG+$Levels; $EndB=$StartB+$Levels; } + + if ($X1 > $X2) { list($X1, $X2) = array($X2, $X1); } + if ($Y1 > $Y2) { list($Y1, $Y2) = array($Y2, $Y1); } + + if ( $Direction == DIRECTION_VERTICAL ) { $Width = abs($Y2-$Y1); } + if ( $Direction == DIRECTION_HORIZONTAL ) { $Width = abs($X2-$X1); } + + $Step = max(abs($EndR-$StartR),abs($EndG-$StartG),abs($EndB-$StartB)); + $StepSize = $Width/$Step; + $RStep = ($EndR-$StartR)/$Step; + $GStep = ($EndG-$StartG)/$Step; + $BStep = ($EndB-$StartB)/$Step; + + $R=$StartR;$G=$StartG;$B=$StartB; + switch($Direction) + { + case DIRECTION_VERTICAL: + $StartY = $Y1; $EndY = floor($Y2)+1; $LastY2 = $StartY; + for($i=0;$i<=$Step;$i++) + { + $Y2 = floor($StartY + ($i * $StepSize)); + + if ($Y2 > $EndY) { $Y2 = $EndY; } + if (($Y1 != $Y2 && $Y1 < $Y2) || $Y2 == $EndY) + { + $Color = array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha); + $this->drawFilledRectangle($X1,$Y1,$X2,$Y2,$Color); + $LastY2 = max($LastY2,$Y2); + $Y1 = $Y2+1; + } + $R = $R + $RStep; $G = $G + $GStep; $B = $B + $BStep; + } + if ( $LastY2 < $EndY && isset($Color)) { for ($i=$LastY2+1;$i<=$EndY;$i++) { $this->drawLine($X1,$i,$X2,$i,$Color); } } + break; + + case DIRECTION_HORIZONTAL: + $StartX = $X1; $EndX = $X2; + for($i=0;$i<=$Step;$i++) + { + $X2 = floor($StartX + ($i * $StepSize)); + + if ($X2 > $EndX) { $X2 = $EndX; } + if (($X1 != $X2 && $X1 < $X2) || $X2 == $EndX) + { + $Color = array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha); + $this->drawFilledRectangle($X1,$Y1,$X2,$Y2,$Color); + $X1 = $X2+1; + } + $R = $R + $RStep; $G = $G + $GStep; $B = $B + $BStep; + } + if ( $X2 < $EndX && isset($Color)) { $this->drawFilledRectangle($X2,$Y1,$EndX,$Y2,$Color); } + break; + } + + $this->Shadow = $Shadow; + + } + + /* Draw an aliased pixel */ + function drawAntialiasPixel($X,$Y,$Format="") + { + $R = isset($Format["R"]) ? $Format["R"] : 0; + $G = isset($Format["G"]) ? $Format["G"] : 0; + $B = isset($Format["B"]) ? $Format["B"] : 0; + $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100; + + if ( $X < 0 || $Y < 0 || $X >= $this->XSize || $Y >= $this->YSize ) + return(-1); + + if ( $R < 0 ) { $R = 0; } if ( $R > 255 ) { $R = 255; } + if ( $G < 0 ) { $G = 0; } if ( $G > 255 ) { $G = 255; } + if ( $B < 0 ) { $B = 0; } if ( $B > 255 ) { $B = 255; } + + if ( !$this->Antialias ) + { + if ( $this->Shadow && $this->ShadowX != 0 && $this->ShadowY != 0 ) + { + $ShadowColor = $this->allocateColor($this->Picture,$this->ShadowR,$this->ShadowG,$this->ShadowB,$this->Shadowa); + imagesetpixel($this->Picture,$X+$this->ShadowX,$Y+$this->ShadowY,$ShadowColor); + } + + $PlotColor = $this->allocateColor($this->Picture,$R,$G,$B,$Alpha); + imagesetpixel($this->Picture,$X,$Y,$PlotColor); + + return(0); + } + + $Plot = ""; + $Xi = floor($X); + $Yi = floor($Y); + + if ( $Xi == $X && $Yi == $Y) + { + if ( $Alpha == 100 ) + $this->drawAlphaPixel($X,$Y,100,$R,$G,$B); + else + $this->drawAlphaPixel($X,$Y,$Alpha,$R,$G,$B); + } + else + { + $Alpha1 = (((1 - ($X - floor($X))) * (1 - ($Y - floor($Y))) * 100) / 100) * $Alpha; + if ( $Alpha1 > $this->AntialiasQuality ) { $this->drawAlphaPixel($Xi,$Yi,$Alpha1,$R,$G,$B); } + + $Alpha2 = ((($X - floor($X)) * (1 - ($Y - floor($Y))) * 100) / 100) * $Alpha; + if ( $Alpha2 > $this->AntialiasQuality ) { $this->drawAlphaPixel($Xi+1,$Yi,$Alpha2,$R,$G,$B); } + + $Alpha3 = (((1 - ($X - floor($X))) * ($Y - floor($Y)) * 100) / 100) * $Alpha; + if ( $Alpha3 > $this->AntialiasQuality ) { $this->drawAlphaPixel($Xi,$Yi+1,$Alpha3,$R,$G,$B); } + + $Alpha4 = ((($X - floor($X)) * ($Y - floor($Y)) * 100) / 100) * $Alpha; + if ( $Alpha4 > $this->AntialiasQuality ) { $this->drawAlphaPixel($Xi+1,$Yi+1,$Alpha4,$R,$G,$B); } + } + } + + /* Draw a semi-transparent pixel */ + function drawAlphaPixel($X,$Y,$Alpha,$R,$G,$B) + { + if ( isset($this->Mask[$X])) { if ( isset($this->Mask[$X][$Y]) ) { return(0); } } + + if ( $X < 0 || $Y < 0 || $X >= $this->XSize || $Y >= $this->YSize ) + return(-1); + + if ( $R < 0 ) { $R = 0; } if ( $R > 255 ) { $R = 255; } + if ( $G < 0 ) { $G = 0; } if ( $G > 255 ) { $G = 255; } + if ( $B < 0 ) { $B = 0; } if ( $B > 255 ) { $B = 255; } + + if ( $this->Shadow && $this->ShadowX != 0 && $this->ShadowY != 0 ) + { + $AlphaFactor = floor(($Alpha / 100) * $this->Shadowa); + $ShadowColor = $this->allocateColor($this->Picture,$this->ShadowR,$this->ShadowG,$this->ShadowB,$AlphaFactor); + imagesetpixel($this->Picture,$X+$this->ShadowX,$Y+$this->ShadowY,$ShadowColor); + } + + $C_Aliased = $this->allocateColor($this->Picture,$R,$G,$B,$Alpha); + imagesetpixel($this->Picture,$X,$Y,$C_Aliased); + } + + /* Convert apha to base 10 */ + function convertAlpha($AlphaValue) + { return((127/100)*(100-$AlphaValue)); } + + /* Allocate a color with transparency */ + function allocateColor($Picture,$R,$G,$B,$Alpha=100) + { + if ( $R < 0 ) { $R = 0; } if ( $R > 255 ) { $R = 255; } + if ( $G < 0 ) { $G = 0; } if ( $G > 255 ) { $G = 255; } + if ( $B < 0 ) { $B = 0; } if ( $B > 255 ) { $B = 255; } + if ( $Alpha < 0 ) { $Alpha = 0; } + if ( $Alpha > 100) { $Alpha = 100; } + + $Alpha = $this->convertAlpha($Alpha); + return(imagecolorallocatealpha($Picture,$R,$G,$B,$Alpha)); + } + + /* Load a PNG file and draw it over the chart */ + function drawFromPNG($X,$Y,$FileName) + { $this->drawFromPicture(1,$FileName,$X,$Y); } + + /* Load a GIF file and draw it over the chart */ + function drawFromGIF($X,$Y,$FileName) + { $this->drawFromPicture(2,$FileName,$X,$Y); } + + /* Load a JPEG file and draw it over the chart */ + function drawFromJPG($X,$Y,$FileName) + { $this->drawFromPicture(3,$FileName,$X,$Y); } + + function getPicInfo($FileName) + { + $Infos = getimagesize($FileName); + $Width = $Infos[0]; + $Height = $Infos[1]; + $Type = $Infos["mime"]; + + if ( $Type == "image/png") { $Type = 1; } + if ( $Type == "image/gif") { $Type = 2; } + if ( $Type == "image/jpeg ") { $Type = 3; } + + return(array($Width,$Height,$Type)); + } + + /* Generic loader function for external pictures */ + function drawFromPicture($PicType,$FileName,$X,$Y) + { + if ( file_exists($FileName)) + { + list($Width,$Height) = $this->getPicInfo($FileName); + + if ( $PicType == 1 ) + { $Raster = imagecreatefrompng($FileName); } + elseif ( $PicType == 2 ) + { $Raster = imagecreatefromgif($FileName); } + elseif ( $PicType == 3 ) + { $Raster = imagecreatefromjpeg($FileName); } + else + { return(0); } + + + $RestoreShadow = $this->Shadow; + if ( $this->Shadow && $this->ShadowX != 0 && $this->ShadowY != 0 ) + { + $this->Shadow = FALSE; + if ( $PicType == 3 ) + $this->drawFilledRectangle($X+$this->ShadowX,$Y+$this->ShadowY,$X+$Width+$this->ShadowX,$Y+$Height+$this->ShadowY,array("R"=>$this->ShadowR,"G"=>$this->ShadowG,"B"=>$this->ShadowB,"Alpha"=>$this->Shadowa)); + else + { + $TranparentID = imagecolortransparent($Raster); + for ($Xc=0;$Xc<=$Width-1;$Xc++) + { + for ($Yc=0;$Yc<=$Height-1;$Yc++) + { + $RGBa = imagecolorat($Raster,$Xc,$Yc); + $Values = imagecolorsforindex($Raster,$RGBa); + if ( $Values["alpha"] < 120 ) + { + $AlphaFactor = floor(($this->Shadowa / 100) * ((100 / 127) * (127-$Values["alpha"]))); + $this->drawAlphaPixel($X+$Xc+$this->ShadowX,$Y+$Yc+$this->ShadowY,$AlphaFactor,$this->ShadowR,$this->ShadowG,$this->ShadowB); + } + } + } + } + } + $this->Shadow = $RestoreShadow; + + imagecopy($this->Picture,$Raster,$X,$Y,0,0,$Width,$Height); + imagedestroy($Raster); + } + } + + /* Draw an arrow */ + function drawArrow($X1,$Y1,$X2,$Y2,$Format="") + { + $FillR = isset($Format["FillR"]) ? $Format["FillR"] : 0; + $FillG = isset($Format["FillG"]) ? $Format["FillG"] : 0; + $FillB = isset($Format["FillB"]) ? $Format["FillB"] : 0; + $BorderR = isset($Format["BorderR"]) ? $Format["BorderR"] : $FillR; + $BorderG = isset($Format["BorderG"]) ? $Format["BorderG"] : $FillG; + $BorderB = isset($Format["BorderB"]) ? $Format["BorderB"] : $FillB; + $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100; + $Size = isset($Format["Size"]) ? $Format["Size"] : 10; + $Ratio = isset($Format["Ratio"]) ? $Format["Ratio"] : .5; + $TwoHeads = isset($Format["TwoHeads"]) ? $Format["TwoHeads"] : FALSE; + $Ticks = isset($Format["Ticks"]) ? $Format["Ticks"] : FALSE; + + /* Calculate the line angle */ + $Angle = $this->getAngle($X1,$Y1,$X2,$Y2); + + /* Override Shadow support, this will be managed internally */ + $RestoreShadow = $this->Shadow; + if ( $this->Shadow && $this->ShadowX != 0 && $this->ShadowY != 0 ) + { + $this->Shadow = FALSE; + $this->drawArrow($X1+$this->ShadowX,$Y1+$this->ShadowY,$X2+$this->ShadowX,$Y2+$this->ShadowY,array("FillR"=>$this->ShadowR,"FillG"=>$this->ShadowG,"FillB"=>$this->ShadowB,"Alpha"=>$this->Shadowa,"Size"=>$Size,"Ratio"=>$Ratio,"TwoHeads"=>$TwoHeads,"Ticks"=>$Ticks)); + } + + /* Draw the 1st Head */ + $TailX = cos(($Angle-180)*PI/180)*$Size+$X2; + $TailY = sin(($Angle-180)*PI/180)*$Size+$Y2; + + $Points = ""; + $Points[] = $X2; $Points[] = $Y2; + $Points[] = cos(($Angle-90)*PI/180)*$Size*$Ratio+$TailX; $Points[] = sin(($Angle-90)*PI/180)*$Size*$Ratio+$TailY; + $Points[] = cos(($Angle-270)*PI/180)*$Size*$Ratio+$TailX; $Points[] = sin(($Angle-270)*PI/180)*$Size*$Ratio+$TailY; + $Points[] = $X2; $Points[] = $Y2; + + /* Visual correction */ + if ($Angle == 180 || $Angle == 360 ) { $Points[4] = $Points[2]; } + if ($Angle == 90 || $Angle == 270 ) { $Points[5] = $Points[3]; } + + $ArrowColor = $this->allocateColor($this->Picture,$FillR,$FillG,$FillB,$Alpha); + ImageFilledPolygon($this->Picture,$Points,4,$ArrowColor); + + $this->drawLine($Points[0],$Points[1],$Points[2],$Points[3],array("R"=>$BorderR,"G"=>$BorderG,"B"=>$BorderB,"Alpha"=>$Alpha)); + $this->drawLine($Points[2],$Points[3],$Points[4],$Points[5],array("R"=>$BorderR,"G"=>$BorderG,"B"=>$BorderB,"Alpha"=>$Alpha)); + $this->drawLine($Points[0],$Points[1],$Points[4],$Points[5],array("R"=>$BorderR,"G"=>$BorderG,"B"=>$BorderB,"Alpha"=>$Alpha)); + + /* Draw the second head */ + if ( $TwoHeads ) + { + $Angle = $this->getAngle($X2,$Y2,$X1,$Y1); + + $TailX2 = cos(($Angle-180)*PI/180)*$Size+$X1; + $TailY2 = sin(($Angle-180)*PI/180)*$Size+$Y1; + + $Points = ""; + $Points[] = $X1; $Points[] = $Y1; + $Points[] = cos(($Angle-90)*PI/180)*$Size*$Ratio+$TailX2; $Points[] = sin(($Angle-90)*PI/180)*$Size*$Ratio+$TailY2; + $Points[] = cos(($Angle-270)*PI/180)*$Size*$Ratio+$TailX2; $Points[] = sin(($Angle-270)*PI/180)*$Size*$Ratio+$TailY2; + $Points[] = $X1; $Points[] = $Y1; + + /* Visual correction */ + if ($Angle == 180 || $Angle == 360 ) { $Points[4] = $Points[2]; } + if ($Angle == 90 || $Angle == 270 ) { $Points[5] = $Points[3]; } + + $ArrowColor = $this->allocateColor($this->Picture,$FillR,$FillG,$FillB,$Alpha); + ImageFilledPolygon($this->Picture,$Points,4,$ArrowColor); + + $this->drawLine($Points[0],$Points[1],$Points[2],$Points[3],array("R"=>$BorderR,"G"=>$BorderG,"B"=>$BorderB,"Alpha"=>$Alpha)); + $this->drawLine($Points[2],$Points[3],$Points[4],$Points[5],array("R"=>$BorderR,"G"=>$BorderG,"B"=>$BorderB,"Alpha"=>$Alpha)); + $this->drawLine($Points[0],$Points[1],$Points[4],$Points[5],array("R"=>$BorderR,"G"=>$BorderG,"B"=>$BorderB,"Alpha"=>$Alpha)); + + $this->drawLine($TailX,$TailY,$TailX2,$TailY2,array("R"=>$BorderR,"G"=>$BorderG,"B"=>$BorderB,"Alpha"=>$Alpha,"Ticks"=>$Ticks)); + } + else + $this->drawLine($X1,$Y1,$TailX,$TailY,array("R"=>$BorderR,"G"=>$BorderG,"B"=>$BorderB,"Alpha"=>$Alpha,"Ticks"=>$Ticks)); + + /* Re-enable shadows */ + $this->Shadow = $RestoreShadow; + } + + /* Draw a label with associated arrow */ + function drawArrowLabel($X1,$Y1,$Text,$Format="") + { + $FillR = isset($Format["FillR"]) ? $Format["FillR"] : 0; + $FillG = isset($Format["FillG"]) ? $Format["FillG"] : 0; + $FillB = isset($Format["FillB"]) ? $Format["FillB"] : 0; + $BorderR = isset($Format["BorderR"]) ? $Format["BorderR"] : $FillR; + $BorderG = isset($Format["BorderG"]) ? $Format["BorderG"] : $FillG; + $BorderB = isset($Format["BorderB"]) ? $Format["BorderB"] : $FillB; + $FontName = isset($Format["FontName"]) ? $Format["FontName"] : $this->FontName; + $FontSize = isset($Format["FontSize"]) ? $Format["FontSize"] : $this->FontSize; + $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100; + $Length = isset($Format["Length"]) ? $Format["Length"] : 50; + $Angle = isset($Format["Angle"]) ? $Format["Angle"] : 315; + $Size = isset($Format["Size"]) ? $Format["Size"] : 10; + $Position = isset($Format["Position"]) ? $Format["Position"] : POSITION_TOP; + $RoundPos = isset($Format["RoundPos"]) ? $Format["RoundPos"] : FALSE; + $Ticks = isset($Format["Ticks"]) ? $Format["Ticks"] : NULL; + + $Angle = $Angle % 360; + + $X2 = sin(($Angle+180)*PI/180)*$Length+$X1; + $Y2 = cos(($Angle+180)*PI/180)*$Length+$Y1; + + if ( $RoundPos && $Angle > 0 && $Angle < 180 ) { $Y2 = ceil($Y2); } + if ( $RoundPos && $Angle > 180 ) { $Y2 = floor($Y2); } + + $this->drawArrow($X2,$Y2,$X1,$Y1,$Format); + + $Size = imagettfbbox($FontSize,0,$FontName,$Text); + $TxtWidth = max(abs($Size[2]-$Size[0]),abs($Size[0]-$Size[6])); + $TxtHeight = max(abs($Size[1]-$Size[7]),abs($Size[3]-$Size[1])); + + if ( $Angle > 0 && $Angle < 180 ) + { + $this->drawLine($X2,$Y2,$X2-$TxtWidth,$Y2,array("R"=>$BorderR,"G"=>$BorderG,"B"=>$BorderB,"Alpha"=>$Alpha,"Ticks"=>$Ticks)); + if ( $Position == POSITION_TOP ) + $this->drawText($X2,$Y2-2,$Text,array("R"=>$BorderR,"G"=>$BorderG,"B"=>$BorderB,"Alpha"=>$Alpha,"Align"=>TEXT_ALIGN_BOTTOMRIGHT)); + else + $this->drawText($X2,$Y2+4,$Text,array("R"=>$BorderR,"G"=>$BorderG,"B"=>$BorderB,"Alpha"=>$Alpha,"Align"=>TEXT_ALIGN_TOPRIGHT)); + } + else + { + $this->drawLine($X2,$Y2,$X2+$TxtWidth,$Y2,array("R"=>$BorderR,"G"=>$BorderG,"B"=>$BorderB,"Alpha"=>$Alpha,"Ticks"=>$Ticks)); + if ( $Position == POSITION_TOP ) + $this->drawText($X2,$Y2-2,$Text,array("R"=>$BorderR,"G"=>$BorderG,"B"=>$BorderB,"Alpha"=>$Alpha)); + else + $this->drawText($X2,$Y2+4,$Text,array("R"=>$BorderR,"G"=>$BorderG,"B"=>$BorderB,"Alpha"=>$Alpha,"Align"=>TEXT_ALIGN_TOPLEFT)); + } + } + + /* Draw a progress bar filled with specified % */ + function drawProgress($X,$Y,$Percent,$Format="") + { + if ( $Percent > 100 ) { $Percent = 100; } + if ( $Percent < 0 ) { $Percent = 0; } + + $Width = isset($Format["Width"]) ? $Format["Width"] : 200; + $Height = isset($Format["Height"]) ? $Format["Height"] : 20; + $Orientation = isset($Format["Orientation"]) ? $Format["Orientation"] : ORIENTATION_HORIZONTAL; + $ShowLabel = isset($Format["ShowLabel"]) ? $Format["ShowLabel"] : FALSE; + $LabelPos = isset($Format["LabelPos"]) ? $Format["LabelPos"] : LABEL_POS_INSIDE; + $Margin = isset($Format["Margin"]) ? $Format["Margin"] : 10; + $R = isset($Format["R"]) ? $Format["R"] : 130; + $G = isset($Format["G"]) ? $Format["G"] : 130; + $B = isset($Format["B"]) ? $Format["B"] : 130; + $RFade = isset($Format["RFade"]) ? $Format["RFade"] : -1; + $GFade = isset($Format["GFade"]) ? $Format["GFade"] : -1; + $BFade = isset($Format["BFade"]) ? $Format["BFade"] : -1; + $BorderR = isset($Format["BorderR"]) ? $Format["BorderR"] : $R; + $BorderG = isset($Format["BorderG"]) ? $Format["BorderG"] : $G; + $BorderB = isset($Format["BorderB"]) ? $Format["BorderB"] : $B; + $BoxBorderR = isset($Format["BoxBorderR"]) ? $Format["BoxBorderR"] : 0; + $BoxBorderG = isset($Format["BoxBorderG"]) ? $Format["BoxBorderG"] : 0; + $BoxBorderB = isset($Format["BoxBorderB"]) ? $Format["BoxBorderB"] : 0; + $BoxBackR = isset($Format["BoxBackR"]) ? $Format["BoxBackR"] : 255; + $BoxBackG = isset($Format["BoxBackG"]) ? $Format["BoxBackG"] : 255; + $BoxBackB = isset($Format["BoxBackB"]) ? $Format["BoxBackB"] : 255; + $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100; + $Surrounding = isset($Format["Surrounding"]) ? $Format["Surrounding"] : NULL; + $BoxSurrounding = isset($Format["BoxSurrounding"]) ? $Format["BoxSurrounding"] : NULL; + $NoAngle = isset($Format["NoAngle"]) ? $Format["NoAngle"] : FALSE; + + if ( $RFade != -1 && $GFade != -1 && $BFade != -1 ) + { + $RFade = (($RFade-$R)/100)*$Percent+$R; + $GFade = (($GFade-$G)/100)*$Percent+$G; + $BFade = (($BFade-$B)/100)*$Percent+$B; + } + + if ( $Surrounding != NULL ) { $BorderR = $R + $Surrounding; $BorderG = $G + $Surrounding; $BorderB = $B + $Surrounding; } + if ( $BoxSurrounding != NULL ) { $BoxBorderR = $BoxBackR + $Surrounding; $BoxBorderG = $BoxBackG + $Surrounding; $BoxBorderB = $BoxBackB + $Surrounding; } + + if ( $Orientation == ORIENTATION_VERTICAL ) + { + $InnerHeight = (($Height-2)/100)*$Percent; + $this->drawFilledRectangle($X,$Y,$X+$Width,$Y-$Height,array("R"=>$BoxBackR,"G"=>$BoxBackG,"B"=>$BoxBackB,"BorderR"=>$BoxBorderR,"BorderG"=>$BoxBorderG,"BorderB"=>$BoxBorderB,"NoAngle"=>$NoAngle)); + + $RestoreShadow = $this->Shadow; $this->Shadow = FALSE; + if ( $RFade != -1 && $GFade != -1 && $BFade != -1 ) + { + $GradientOptions = array("StartR"=>$RFade,"StartG"=>$GFade,"StartB"=>$BFade,"EndR"=>$R,"EndG"=>$G,"EndB"=>$B); + $this->drawGradientArea($X+1,$Y-1,$X+$Width-1,$Y-$InnerHeight,DIRECTION_VERTICAL,$GradientOptions); + + if ( $Surrounding ) + $this->drawRectangle($X+1,$Y-1,$X+$Width-1,$Y-$InnerHeight,array("R"=>255,"G"=>255,"B"=>255,"Alpha"=>$Surrounding)); + } + else + $this->drawFilledRectangle($X+1,$Y-1,$X+$Width-1,$Y-$InnerHeight,array("R"=>$R,"G"=>$G,"B"=>$B,"BorderR"=>$BorderR,"BorderG"=>$BorderG,"BorderB"=>$BorderB)); + + $this->Shadow = $RestoreShadow; + + if ( $ShowLabel && $LabelPos == LABEL_POS_BOTTOM ) { $this->drawText($X+($Width/2),$Y+$Margin,$Percent."%",array("Align"=>TEXT_ALIGN_TOPMIDDLE)); } + if ( $ShowLabel && $LabelPos == LABEL_POS_TOP ) { $this->drawText($X+($Width/2),$Y-$Height-$Margin,$Percent."%",array("Align"=>TEXT_ALIGN_BOTTOMMIDDLE)); } + if ( $ShowLabel && $LabelPos == LABEL_POS_INSIDE ) { $this->drawText($X+($Width/2),$Y-$InnerHeight-$Margin,$Percent."%",array("Align"=>TEXT_ALIGN