Source for file CanvasMing.php
Documentation is available at CanvasMing.php
* Description: Class with all Chart drawing methods.
* @copyright (c) 1995-2010 by Steema Software SL. All Rights Reserved. <info@steema.com>
* @link http://www.steema.com
private $iZoomText= false;
private $xCenterOffset= 0;
private $yCenterOffset= 0;
private $rotationCenter= null;
private static $NUMCIRCLEPOINTS = 64;
public static $DARKCOLORQUANTITY = 64;
private static $DARKERCOLORQUANTITY = 128;
function __get( $property ) {
$method = "get{$property}";
function __set ( $property,$value ) {
$method = "set{$property}";
return $this->$method($value);
* Creates a new Graphics object
$this->rotationCenter = new Point3D();
$this->iPoints = array();
if ($this->chart != null) {
$this->setAspect($this->chart->getAspect());
/**************************************************************************
* Drawing methods............ *
**************************************************************************/
* Paints the image in rectangle r.
* @param transparent boolean
public function draw($r, $image, $mode, $shapeBorders, $transparent) {
/* imageAlphaBlending($image, false);
imageSaveAlpha($image, true);
//Get the sizes of both pix
$sourcefile_width=imagesx($this->img);
$sourcefile_height=imagesy($this->img);
$image_width=imagesx($image);
$image_height=imagesy($image);
if ($mode==ImageMode::$TILE) {
elseif ($mode==ImageMode::$CENTER) {
$dest_x = ( $sourcefile_width / 2 ) - ( $image_width / 2 );
$dest_y = ( $sourcefile_height / 2 ) - ( $image_height / 2 );
imagecopy($this->img, $image, $dest_x, $dest_y, 0, 0,
$image_width, $image_height);
elseif ($mode==ImageMode::$NORMAL) {
imagecopy($this->img, $image, $dest_x, $dest_y, 0, 0,
$image_width, $image_height);
imagecopyresized($this->img, $image,$dest_x, $dest_y, 0, 0,
$sourcefile_width, $sourcefile_height,
$image_width, $image_height);
if (($shapeBorders->getTopLeft()->getBorderRound() > 0) || ($shapeBorders->getBottomLeft()->getBorderRound() > 0) ||
($shapeBorders->getTopRight()->getBorderRound() > 0) || ($shapeBorders->getBottomRight()->getBorderRound() > 0)) {
$this->drawRoundedBorders($shapeBorders,null,null);
* Draws a line with an arrow head of ArrowWidth and ArrowHeight dimensions
public function arrow($filled, $fromPoint, $toPoint,
$headWidth, $headHeight, $z) {
$dx = $toPoint->getX() - $fromPoint->getX();
$dy = $fromPoint->getY() - $toPoint->getY();
$l = sqrt($dx * $dx + $dy * $dy);
if ($l > 0) { // if at least one pixel...
(int) $tmpHoriz = $headWidth;
$xb = $toPoint->getX() * $a->cosA - $toPoint->getY() * $a->sinA;
$yb = $toPoint->getX() * $a->sinA + $toPoint->getY() * $a->cosA;
$a->y = $yb - $tmpHoriz * 0.5;
$a->y = $yb + $tmpHoriz * 0.5;
$tmpHoriz4 = $tmpHoriz * 0.25;
$a->y = $yb - $tmpHoriz4;
$a->y = $yb + $tmpHoriz4;
$a->x = $fromPoint->x * $a->cosA - $fromPoint->y * $a->sinA;
$a->y = $yb - $tmpHoriz4;
$a->y = $yb + $tmpHoriz4;
$tmp = Array($ph, $pg, $pe, $pc, $this->calc3DPoint($toPoint->getX(),$toPoint->getY(),
TODO $this->polygon($tmp);
* Draws Bezier splines for the Point array p at displacement z
$this->internalBezier($z, true, $p);
* Draws Bezier splines for the Point array p
$this->internalBezier(0, false, $p);
private function internalBezier($z, $is3D, $points) {
$this->moveToXYZ($points[0]->x, $points[0]->y, $z);
$this->drawBezier($is3D, $z, $points, 2);
$this->drawBezier($is3D, $z, $points, $t);
} while (!($t > sizeof($points) - 1));
private function drawBezier($is3D, $z, $points, $first) {
$p1 = $points[$first - 2];
$p2 = $points[$first - 1];
for ($t = 1; $t < 32; $t++ ) {
$p = new TeePoint((int) ($p1->x * $mum12 + 2 * $p2->x * $mum1 * $mu +
(int) ($p1->y * $mum12 + 2 * $p2->y * $mum1 * $mu +
* Calculates and returns the XY position in pixels of the XYZ 3D
* Can be used when custom drawing using 3D XYZ coordinates are returned
return new TeePoint(($this->iZoomFactor * ($x - $this->xCenter +
($this->iOrthoX * $z))) + $this->xCenterOffset,
($this->iZoomFactor * ($y - $this->yCenter - ($this->iOrthoY *
$z))) + $this->yCenterOffset);
$zz = $z * $this->c2 - $x * $this->s2;
$tmp = $this->iZoomFactor;
$tmp /= (1 + $this->iZoomPerspec * ($zz * $this->c1 + $y * $this->s1));
return new TeePoint( (($x * $this->c2 + $z * $this->s2) * $tmp) + $this->xCenterOffset,
(($y * $this->c1 - $zz * $this->s1) * $tmp) + $this->yCenterOffset);
* Calculates and returns the XY position as double of the XYZ 3D
* Can be used when custom drawing using 3D XYZ coordinates are returned
return new PointDouble((int) ($this->iZoomFactor * ($x - $this->xCenter + ($this->iOrthoX * $z))) +
(int) ($this->iZoomFactor * ($y - $this->yCenter - ($this->iOrthoY * $z))) +
$zz = $z * $this->c2 - $x * $this->s2;
$tmp = $this->iZoomFactor;
$tmp /= (1 + $this->iZoomPerspec * ($zz * $this->c1 + $y * $this->s1));
return new PointDouble((int) (($x * $this->c2 + $z * $this->s2) * $tmp) + $this->xCenterOffset,
(int) (($y * $this->c1 - $zz * $this->s1) * $tmp) + $this->yCenterOffset);
* Calculates and returns the XY position in pixels of the point p Z 3D
* Can be used when custom drawing using 3D XYZ coordinates are returned
return $this->calc3DPos($source->getX(), $source->getY(), $source- getZ());
* Calculates and returns the XY position in pixels of the point p Z 3D
* Can be used when custom drawing using 3D XYZ coordinates are returned
return $this->calc3DPos($source->getX(), $source->getY(), $z);
* Calculates and returns the XY position in pixels of the point p with
* Z = 0 3D coordinate.<br>
* Can be used when custom drawing using 3D XYZ coordinates are returned
return $this->calc3DPos($source->x, $source->y, 0);
$PERSPECFACTOR = 1.0 / 150.0;
$perspec = $this->aspect->getPerspective();
$this->iPerspec = ($perspec > 0);
$this->iZoomPerspec = $this->iZoomFactor * $perspec * $PERSPECFACTOR / $tmp;
if (!$this->aspect->getOrthogonal()) {
$rx = - $this->aspect->getElevation();
$ry = - $this->aspect->getRotation();
$rz = $this->aspect->getTilt();
$this->c2s3 = $this->c2 * $this->s3;
$this->c2c3 = max(1E-5, $this->c2 * $this->c3);
$this->tempXX = max(1E-5, $this->s1 * $this->s2 * $this->s3 + $this->c1 * $this->c3);
$this->tempYX = ($this->c3 * $this->s1 * $this->s2 - $this->c1 * $this->s3);
$this->tempXZ = ($this->c1 * $this->s2 * $this->s3 - $this->c3 * $this->s1);
$this->tempYZ = ($this->c1 * $this->c3 * $this->s2 + $this->s1 * $this->s3);
if (!$this->rectClip==null)
$x = $this->rectClip->getX();
$y = $this->rectClip->getY();
imagecopymerge($this->tmpImg, $this->img,$x,$y,$x,$y,
$this->rectClip->getWidth(),$this->rectClip->getHeight(),100);
imagecopy($this->img,$this->tmpImg,0,0,0,0,imagesx($this->img),imagesy($this->img));
if (!$this->polygonClip==null)
* Creates a Windows GDI clipping region and selects it into
* TChart.<!-- -->Canvas device context handle.<br>
$this->rectClip=new Rectangle();
$this->rectClip->x=$left;
$this->rectClip->width=$right-$left;
$this->rectClip->height=$bottom-$top;
$this->tmpImg = imagecreatetruecolor(imagesx($this->img), imagesy($this->img));
// Converts to Transparent image
imagesavealpha($this->tmpImg, true);
/* TODO check if required or not
$trans_colour = imagecolorallocatealpha($this->tmpImg, 0, 0, 0, 127);
imagefill($this->tmpImg, 0, 0, $trans_colour);
imagecopy($this->tmpImg,$this->img,0,0,0,0,imagesx($this->img),imagesy($this->img));
* Creates a Windows GDI clipping region and selects it into
* TChart.<!-- -->Canvas device context handle.<br>
* @param polygonPoints - Array of TeePoints
/* $this->polygonClip=Array();
$this->polygonClip=$polygonPoiints;
* Paints a cone with Cone Percent.<br>
* Use <br>ONLY with OPENGL</b>.<br>
* This parameter varies the apex size
* as a percentage of the base.<br>
* @param vertical boolean
* @param darkSides boolean
* @param conePercent int varies the apex size as a percentage of the base.
public function cone($vertical, $r, $z0, $z1, $darkSides, $conePercent= 0) {
$this->internalCylinder($vertical, $r, $z0, $z1, $darkSides, $conePercent);
* Draws cylinder toggle Boolean for vertical or horizontal cylinder.
* @param vertical boolean
* @param darkSides boolean
public function cylinder($vertical, $r, $z0, $z1, $darkSides) {
$this->internalCylinder($vertical, $r, $z0, $z1, $darkSides, 100);
private function internalCylinder($vertical, $r, $z0, $z1, $dark3D, $conePercent) {
$NUMCYLINDERSIDES = 16; // 256
$STEP = 2.0 * M_PI / $NUMCYLINDERSIDES;
$STEPCOLOR = 256 / $NUMCYLINDERSIDES; // 512
$oldColor = $this->brush->getColor();
(int) $zRadius = ($z1 - $z0) / 2;
(int) $tmpMidZ = ($z1 + $z0) / 2;
(int) $radius = ($r->getRight() - $r->x) / 2;
(int) $tmpMid = ($r->getRight() + $r->x) / 2;
(int) $tmpSize = abs($r->getBottom() - $r->y);
for ($t = 0; $t < $NUMCYLINDERSIDES; $t++) {
(double) $tmpSin = sin(($t - 3) * $STEP);
(double) $tmpCos = cos(($t - 3) * $STEP);
$poly[$t] = new Point3D();
$poly[$t]->x = $tmpMid + MathUtils::round($tmpSin * $radius);
if ($r->y < $r->getBottom()) {
$poly[$t]->y = $r->getBottom();
$poly[$t]->z = $tmpMidZ - MathUtils::round($tmpCos * $zRadius);
$radius = MathUtils::round($radius * $conePercent * 0.01);
$zRadius = MathUtils::round($zRadius * $conePercent * 0.01);
$tmpPoly[1] = $this->calc3DPoint($poly[0]->x, $poly[0]->y + $tmpSize, $poly[0]->z);
$tmpSin = sin((1 - 4) * $STEP);
$tmpCos = cos((1 - 4) * $STEP);
$poly[0]->x = $tmpMid + MathUtils::round($tmpSin * $radius);
$poly[0]->z = $tmpMidZ - MathUtils::round($tmpCos * $zRadius);
$tmpPoly[0] = $this->calc3DPoint($poly[0]->x,$poly[0]->y,$poly[0]->z);
for ($t = 1; $t < $NUMCYLINDERSIDES; $t++) {
$tmpPoly[2] = $this->calc3DPoint($poly[$t]->x, $poly[$t]->y + $tmpSize,
$tmpSin = sin(($t - 3) * $STEP);
$tmpCos = cos(($t - 3) * $STEP);
$poly[$t]->x = $tmpMid + MathUtils::round($tmpSin * $radius);
$poly[$t]->z = $tmpMidZ - MathUtils::round($tmpCos * $zRadius);
$tmpPoly[3] = $this->calc3DPoint($poly[$t]->x,$poly[$t]->y,$poly[$t]->z);
$tmp = ($tmpPoly[0]->x - $tmpPoly[2]->x + $tmpPoly[1]->x -
$this->internalApplyDark($oldColor, $STEPCOLOR * $numSide);
$p = Array($tmpPoly[0], $tmpPoly[1], $tmpPoly[2], $tmpPoly[3]);
$tmpPoly[0] = $tmpPoly[3];
$tmpPoly[1] = $tmpPoly[2];
$radius = ($r->getBottom() - $r->y) / 2;
$tmpMid = ($r->getBottom() + $r->y) / 2;
$tmpSize = $r->getRight() - $r->X;
for ($t = 0; $t < $NUMCYLINDERSIDES; $t++) {
$tmpSin = sin(($t - 4) * $STEP);
$tmpCos = cos(($t - 4) * $STEP);
$poly[$t] = new Point3D();
if ($r->x < $r->getRight()) {
$poly[$t]->x = $r->getRight();
$poly[$t]->y = $tmpMid + MathUtils::round($tmpSin * $radius);
$poly[$t]->z = $tmpMidZ - MathUtils::round($tmpCos * $zRadius);
$radius = MathUtils::round($radius * $conePercent * 0.01);
$zRadius = MathUtils::round($zRadius * $conePercent * 0.01);
$tmpSize = abs($r->getRight() - $r->x);
$tmpPoly[1] = $this->calc3DPoint($poly[0]->x - $tmpSize, $poly[0]->y, $poly[0]->z);
$tmpSin = sin( -4 * $STEP);
$tmpCos = cos( -4 * $STEP);
$poly[0]->y = $tmpMid + MathUtils::round($tmpSin * $radius);
$poly[0]->z = $tmpMidZ - MathUtils::round($tmpCos * $zRadius);
$tmpPoly[0] = $this->calc3DPoint($poly[0]->x,$poly[0]->y,$poly[0]->z);
for ($t = 1; $t < $NUMCYLINDERSIDES; $t++) {
$tmpPoly[2] = $this->calc3DPoint($poly[$t]->x - $tmpSize, $poly[$t]->y,
$tmpSin = sin(($t - 4) * $STEP);
$tmpCos = cos(($t - 4) * $STEP);
$poly[$t]->y = $tmpMid + MathUtils::round($tmpSin * $radius);
$poly[$t]->z = $tmpMidZ - MathUtils::round($tmpCos * $zRadius);
$tmpPoly[3] = $this->calc3DPoint($poly[$t]->x,$poly[$t]->y,$poly[$t]->z);
$tmp = ($tmpPoly[0]->y - $tmpPoly[2]->y + $tmpPoly[1]->y -
$this->internalApplyDark($oldColor, $STEPCOLOR * $numSide);
$p = Array($tmpPoly[0], $tmpPoly[1], $tmpPoly[2], $tmpPoly[3]);
$tmpPoly[0] = $tmpPoly[3];
$tmpPoly[1] = $tmpPoly[2];
for ($t = 0; $t < $NUMCYLINDERSIDES; $t++) {
$tmpPoly[$t] = $this->calc3DPoint($poly[$t]->x,$poly[$t]->y,$poly[$t]->z);
$this->internalApplyDark($oldColor, $DARKCOLORQUANTITY);
$this->polygon($tmpPoly);
$oc = array(0xFF & ($oc >> 0x10), 0xFF & ($oc >> 0x8), 0xFF & $oc);
$ic = array(0xFF & ($ic >> 0x10), 0xFF & ($ic >> 0x8), 0xFF & $ic);
$c0 = ($oc[0] - $ic[0]) / $w;
$c1 = ($oc[1] - $ic[1]) / $w;
$c2 = ($oc[2] - $ic[2]) / $w;
$r = $oc[0] - floor($i * $c0);
$g = $oc[1] - floor($i * $c1);
$b = $oc[2] - floor($i * $c2);
$c = imagecolorallocate($image, $r, $g, $b);
imagefilledellipse($image, $cx, $cy, $w-$i, $h-$j, $c);
if($i >= $w && $j >= $h){
$oc = array(0xFF & ($oc >> 0x10), 0xFF & ($oc >> 0x8), 0xFF & $oc);
$ic = array(0xFF & ($ic >> 0x10), 0xFF & ($ic >> 0x8), 0xFF & $ic);
$c0 = ($oc[0] - $ic[0]) / $w;
$c1 = ($oc[1] - $ic[1]) / $w;
$c2 = ($oc[2] - $ic[2]) / $w;
$r = $oc[0] - floor($i * $c0);
$g = $oc[1] - floor($i * $c1);
$b = $oc[2] - floor($i * $c2);
$t = $ot - floor($i * $ct);
$c = imagecolorallocatealpha($image, $r, $g, $b, $t);
imageellipse($image, $cx, $cy, $w-$i, $h-$j, $c);
if($i >= $w && $j >= $h){
private function clipToRight($rect, $minZ, $maxZ) {
$p[0] = $this->calc3DPoint($rect->x, $rect->getBottom(), $minZ);
$p[1] = $this->calc3DPoint($rect->x, $rect->y, $minZ);
$pa = $this->calc3DPoint($rect->x, $rect->y, $maxZ);
$pb = $this->calc3DPoint($rect->getRight(), $rect->y, $minZ);
$p[2] = ($pb->getY() < $pa->getY()) ? $pb : $pa;
$p[3] = $this->calc3DPoint($rect->getRight(), $rect->y, $maxZ);
$pc = $this->calc3DPoint($rect->getRight(), $rect->getBottom(), $maxZ);
$pd = $this->calc3DPoint($rect->getRight(), $rect->y, $minZ);
$p[4] = ($pd->getX() > $pc->getX()) ? $pd : $pc;
$p[5] = $this->calc3DPoint($rect->getRight(), $rect->getBottom(), $minZ);
if ($p[5]->getX() < $p[0]->getX()) {
$p[0]->setX($p[5]->getX());
if ($pd->getY() < $p[0]->getY()) {
$p[0]->setY($pd->getY());
$c1 = imagecolorallocate($this->img, $this->getBrush()->getColor()->red,
$this->getBrush()->getColor()->green,
$this->getBrush()->getColor()->blue);
private function clipToLeft($rect, $minZ, $maxZ) {
$c1 = imagecolorallocate($this->img, $this->getBrush()->getColor()->red,
$this->getBrush()->getColor()->green,
$this->getBrush()->getColor()->blue);
/* TODO clippolygon imagepolygon($this->img, array (
$this->calc3DPoint($rect->x, $rect->getBottom(), $minZ),
$this->calc3DPoint($rect->x, $rect->getBottom(), $maxZ),
$this->calc3DPoint($rect->x, $rect->y, $maxZ),
$this->calc3DPoint($rect->getRight(), $rect->y, $maxZ),
$this->calc3DPoint($rect->getRight(), $rect->y, $minZ),
$this->calc3DPoint($rect->getRight(), $rect->getBottom(), $minZ)),
public function cuber ($rect, $z0, $z1, $darkSides) {
$this->cube($rect->getLeft(), $rect->getTop(), $rect->getRight(), $rect->getBottom(), $z0, $z1, $darkSides);
* Draws a Cube with Dark Sides.
* @param darkSides boolean
public function cube($left, $top, $right, $bottom, $z0, $z1, $darkSides) {
/* $oldColor = $this->brush->getColor();
$p0 = $this->calc3DPoint($left, $top, $z0);
$p1 = $this->calc3DPoint($right, $top, $z0);
$p2 = $this->calc3DPoint($right, $bottom, $z0);
$p3 = $this->calc3DPoint($right, $top, $z1);
$this->iPoints[3] = $this->calc3DPoint($left, $bottom, $z0);
if ($this->culling() > 0) {
$this->polygonFour(); // front-side
$this->iPoints[0] = $this->calc3DPos($left, $top, $z1);
$this->iPoints[1] = $this->calc3DPos($right, $top, $z1);
$this->iPoints[2] = $this->calc3DPos($right, $bottom, $z1);
$this->iPoints[3] = $this->calc3DPos($left, $bottom, $z1);
$this->polygonFour(); // back-side
$this->iPoints[2] = $this->calc3DPos($right, $bottom, $z1);
if ($this->culling() > 0) {
$this->internalApplyDark($oldColor, self::$DARKERCOLORQUANTITY);
$this->polygonFour(); // left-side
$this->iPoints[1] = $this->calc3DPos($left, $top, $z1);
$this->iPoints[2] = $this->calc3DPos($left, $bottom, $z1);
$this->iPoints[3] = $this->calc3DPos($left, $bottom, $z0);
$tmp = ($this->iPoints[3]->getX() - $this->iPoints[0]->getX()) *
($this->iPoints[1]->getY() - $this->iPoints[0]->getY()) -
($this->iPoints[1]->getX() - $this->iPoints[0]->getX()) *
($this->iPoints[3]->getY() - $this->iPoints[0]->getY());
$this->internalApplyDark($oldColor, self::$DARKERCOLORQUANTITY);
$this->polygonFour(); // right-side
$this->iPoints[3] = $this->calc3DPos($left, $top, $z1);
$tmp = ($p0->getX() - $p1->getX()) * ($p3->getY() - $p1->getY()) -
($p3->getX() - $p1->getX()) * ($p0->getY() - $p1->getY());
$this->internalApplyDark($oldColor, self::$DARKCOLORQUANTITY);
$this->polygonFour(); // top-side
$this->iPoints[0] = $this->calc3DPos($left, $bottom, $z0);
$this->iPoints[2] = $this->calc3DPos($right, $bottom, $z1);
$this->iPoints[1] = $this->calc3DPos($left, $bottom, $z1);
if ($this->culling() < 0) {
$this->internalApplyDark($oldColor, self::$DARKCOLORQUANTITY);
$this->brush->setColor($oldColor);
* Creates a cubic Windows GDI clipping region.
public function clipCube($rect, $minZ, $maxZ) {
if ($this->aspect->getElevation() == 270) {
if (($this->aspect->getRotation() == 270) ||
($this->aspect->getRotation() == 360)) {
$tmpLT = $this->calc3DPoint($rect->x, $rect->y, $minZ);
$tmpRB = $this->calc3DPoint($rect->getRight(), $rect->y, $maxZ);
$this->clipRectangle($tmpLT->x, $tmpLT->y, $tmpRB->x, $tmpRB->y);
if ($this->aspect->getOrthoAngle() > 90) {
$this->clipToLeft($rect, $minZ, $maxZ);
$this->clipToRight($rect, $minZ, $maxZ);
if ($this->aspect->getRotation() >= 270) {
$this->clipToRight($rect, $minZ, $maxZ);
$this->clipRectangle($rect->x + 1, $rect->y + 1, $rect->getRight() - 1,
private function culling() {
return (($this->iPoints[3]->getX() - $this->iPoints[2]->getX()) * ($this->iPoints[1]->getY() -
$this->iPoints[2]->getY())) - (($this->iPoints[1]->getX() - $this->iPoints[2]->getX()) *
($this->iPoints[3]->getY() - $this->iPoints[2]->getY()));
* Creates and initialize the image
Ming_setScale(20.0000000);
$m->setBackground(220,220,220);
$this->shape = new SWFShape();
$sqfill = $this->shape->addFill(0, 0, 0xff);
//$this->shape->setRightFill($sqfill);
$square = new SWFShape();
$sqfill = $square->addFill(0, 0, 0xff);
$square->setRightFill($sqfill);
$square->movePenTo(-250,-250);
$square->drawLineTo(250,-250);
$square->drawLineTo(250,250);
$square->drawLineTo(-250,250);
$square->drawLineTo(-250,-250);
//Now we can use that shape in a movie clip and define some actions:
$sqclip = new SWFSprite();
$i = $sqclip->add($square);
$sqclip->add(new SWFAction("stop();"));
$sqclip->add(new SWFAction("play();"));
//Next we'll create another shape and use it for a button. Rather than create a separate shape for each button action (over, down, up, and release), I've created a function to automate drawing the shapes:
function rect($r, $g, $b) {
$s->setRightFill($s->addFill($r, $g, $b));
$b->addShape(rect(0xff, 0, 0), SWFBUTTON_UP | SWFBUTTON_HIT);
$b->addShape(rect(0, 0xff, 0), SWFBUTTON_OVER);
$b->addShape(rect(0, 0, 0xff), SWFBUTTON_DOWN);
$b->addAction(new SWFAction("setTarget('/box'); gotoandplay(2);"), SWFBUTTON_MOUSEDOWN);
//Next, we define the movie and place the movie clip (sprite) and the button in the movie itself:
$m->setDimension(4000,3000);
$m->setBackground(255,0,0);
private function doBevelRect($rect, $a, $b) {
/* $topRight = new TeePoint($rect->getRight() - 1, $rect->y);
$bottomLeft = new TeePoint($rect->x, $rect->getBottom() - 1);
$bottomRight = new TeePoint($rect->getRight() - 1, $rect->getBottom() - 1);
$this->___line($a, $rect->getLocation(), $topRight);
$this->___line($a, $rect->getLocation(), $bottomLeft);
$this->___line($b, $bottomLeft, $bottomRight);
$this->___line($b, $bottomRight, $topRight);
public function doRev() {
$black = imagecolorallocate($this->img, 150, 150, 150);
$x = imagesx($this->img);
$y = imagesy($this->img)- 6;
$text = "EVALUATION VERSION";
imagefttext($this->img, 25, 45, 25, $y+ 3, $black, $font_file, $text);
* Draws an Ellipse bounding Rectangle r.
$this->ellipse($r->getX(), $r->getY(), $r->getRight(), $r->getBottom());
* Ellipse bounding Rectangle r at z depth.
$this->ellipse($r->getX(), $r->getY(), $r->getRight(), $r->getBottom(), $z);
$this->transparentEllipse($p0->getX(), $p0->getY(), $p1->getX(), $p1->getY());
* Ellipse bounding Rect (X1,Y1,X2,Y2) at Z position at angle.
public function ellipse($x1, $y1, $x2, $y2, $z= 0, $angle= 0) {
$p1 = $this->calc3DPos($x1, $y1, $z);
$p2 = $this->calc3DPos($x2, $y2, $z);
$this->ellipsePoints($p1,$p2);
// todo here draw directly the ellipse with p1 and p2 $this->ellipsePoints($p1, $p2);
// todo remove Point[] p = new Point[NUMCIRCLEPOINTS]; // : Array[0..NumCirclePoints-1] of TPoint;
for ($t = 0; $t < 3; $t++) {
$points[$t] = new TeePoint();
$xCenter = ($x2 + $x1) * 0.5;
$yCenter = ($y2 + $y1) * 0.5;
$xRadius = ($x2 - $x1) * 0.5;
$yRadius = ($y2 - $y1) * 0.5;
$tmpPiStep = 2 * M_PI / (self::$NUMCIRCLEPOINTS - 1);
// initial rotation (rotation matrix elements)
$tmpSinAngle = sin($angle);
$tmpCosAngle = cos($angle);
for ($t = 0; $t < self::$NUMCIRCLEPOINTS; $t++) {
$tmpSin = sin($t * $tmpPiStep);
$tmpCos = cos($t * $tmpPiStep);
$tmpX = $xRadius * $tmpSin;
$tmpY = $yRadius * $tmpCos;
MathUtils::round($xCenter +
MathUtils::round($yCenter +
( -$tmpX * $tmpSinAngle +
if ($this->getBrush()->getVisible()) {
$old = $this->getPen()->getVisible();
$this->getPen()->setVisible(false);
$xc = MathUtils::round($xCenter);
$yc = MathUtils::round($yCenter);
for ($t = 1; $t < self::$NUMCIRCLEPOINTS; $t++) {
// has to be in loop because the Polygon
// transforms the positions from 3d to 2d in each pass
$this->polygonz($z, $points);
// close it up with polygon from last to first
$points[1] = $p[self::$NUMCIRCLEPOINTS - 1];
$this->polygonz($z, $points);
$this->getPen()->setVisible($old);
if ($this->getPen()->getVisible()) {
$color = imagecolorallocate($this->img, $this->getBrush()->getColor()->red,
$this->getBrush()->getColor()->green,
$this->getBrush()->getColor()->blue);
// updates x,y,width,height to be used in imagefilledellipse correctly
if ($this->brush->getVisible()) {
imagefilledellipse($this->img,$x1,$y1,$tmpWidth,$tmpHeight,$color);
if ($this->getPen()->getVisible()) {
// Gets the pen color and style (dot , dashed, ...)
$penColorStyle = $this->getPenColorStyle();
imagesetstyle($this->img, $penColorStyle);
// Assign the pen width for the image
imagesetthickness ( $this->img, $this->pen->getWidth());
for ($i=0;$i<=$this->pen->getWidth();$i++)
imageellipse($this->img,$x1,$y1,$tmpWidth+$i,$tmpHeight+$i,IMG_COLOR_STYLED);
$this->ellipse($p0->getX(), $p0->getY(), $p1->getX(), $p1->getY());
* Ellipse bounding rectangle r with Z offset at angle.
$this->ellipse($r->getX(), $r->getY(), $r->getWidth(),
$r->getHeight(), $z, $angle); // $r->getRight(), $r->getBottom(), $z, $angle);
* Determines the Font Height to be used for outputted text when using the
$tmpAngle = $this->aspect->getOrthoAngle();
$tmpAngle = 180 - $tmpAngle;
$tmpSin = sin($this->aspect->getOrthoAngle() *
$tmpCos = cos($this->aspect->getOrthoAngle() *
$this->iOrthoY = ($tmpCos < 0.01) ? 1 : $tmpSin / $tmpCos;
$this->iZoomFactor = 0.01 * $this->aspect->getZoom();
$this->iZoomText = $this->aspect->getZoomText();
$this->brush->_applyDark($c, $quantity);
* @param integer line start (X)
* @param integer line start (Y)
* @param integer line end (X)
* @param integer line end (Y)
* @param Color line color
* @param integer line width
function line($x1, $y1, $x2, $y2, $color= null, $width = - 1)
$color = imagecolorallocate($this->img, $this->pen->getColor()->red,
$this->pen->getColor()->green,
$this->pen->getColor()->blue);
imageantialias($this->img,false);
// Gets the pen color and style (dot , dashed, ...)
$penColorStyle = $this->getPenColorStyle();
imagesetstyle($this->img, $penColorStyle);
// Assign the pen width for the image
$width = $this->pen->getWidth();
// imageantialias($this->img,true);
imagesetthickness ($this->img, $width);
// imageantialias($this->img,true);
imagesetthickness ($this->img, $width);
imageline($this->img, $x1, $y1, $x2, $y2, IMG_COLOR_STYLED);
// imageantialias($this->img,false);
imageantialias($this->img,true);
$this->pen->getColor()->red,
$this->pen->getColor()->green,
$this->pen->getColor()->blue);
//$this->shape->setRightFill($this->shape->addFill(0xff, 0, 0));
$this->shape->movePenTo($x1,$y1);
$this->shape->drawLineTo($x2,$y2);
* Draws a Line between co-ordinates with z depth offset.
public function _line($x0, $y0, $x1, $y1, $z= 0) {
* Draws a Line between point p0 and point p1.
* @param p0 Point is origin xy
* @param p1 Point is destination xy
public function __line($p0, $p1) {
$this->line($p0->getX(), $p0->getY(), $p1->getX(), $p1->getY());
$this->moveToXY($p1->getX(),$p1->getY()); // review
* Draws a Line between point p0 and point p1 using specific pen.
* @param pen ChartPen id the pen used
* @param p0 Point is origin xy
* @param p1 Point is destination xy
public function ___line($pen, $p0, $p1) {
// Gets the pen color and style (dot , dashed, ...)
$penColorStyle = $this->getPenColorStyle();
// imagesetstyle($this->img, $penColorStyle);
// Assign the pen width for the image
// imagesetthickness ( $this->img, $this->pen->getWidth());
$this->pen->getColor()->red,
$this->pen->getColor()->green,
$this->pen->getColor()->blue);
//$this->shape->setRightFill($this->shape->addFill(0xff, 0, 0));
$this->shape->movePenTo($p0->getX(),$p0->getY());
$this->shape->drawLineTo($p1->getX(),$p1->getY());
* Draws a line to Point with z depth offset.
public function lineTo($p, $z) {
$this->___lineTo($p->getX(), $p->getY(), $z);
* Draws a line to Point with z = 0 depth offset.
* Draws line from present position to end co-ordinates with z depth offset.
* Draws a Line to 3D Point.
* Draws line from present position to end co-ordinates with z depth offset.
* Sets the value of PenPos to x and y co-ordinates before calling LineTo.
* Sets the value of PenPos to Point p before calling LineTo.
$this->moveToXY($p->getX(), $p->getY());
* Sets the value of PenPos to x, y and z co-ordinates before calling
* Sets the value of PenPos to Point p with z depth offset before calling
$p2 = $this->calc3DPos($p->getX(), $p->getY(), $z);
* Sets the value of PenPos to 3D Point p before calling LineTo.
* Draws a Line from (X,Y,Z0) to (X,Y,Z1).
public function zLine($x, $y, $z0, $z1) {
$c1 = imagecolorallocatealpha($this->img, $this->pen->getColor()->red,
$this->pen->getColor()->green,
$this->pen->getColor()->blue,
$this->pen->getColor()->alpha);
imagesetthickness ( $this->img, $this->pen->getWidth());
$this->pen->getColor()->red,
$this->pen->getColor()->green,
$this->pen->getColor()->blue);
//$this->shape->setRightFill($this->shape->addFill(0xff, 0, 0));
$this->shape->movePenTo($p1->getX(),$p1->getY());
$this->shape->drawLineTo($p2->getX(),$p2->getY());
* Draws a Horizontal at z depth position.
$this->pen->getColor()->red,
$this->pen->getColor()->green,
$this->pen->getColor()->blue);
//$this->shape->setRightFill($this->shape->addFill(0xff, 0, 0));
$this->shape->movePenTo($p1->getX(),$p1->getY());
$this->shape->drawLineTo($p2->getX(),$p2->getY());
* Draws a Vertical Line from (X,Top) to (X,Bottom) at z depth position.
$this->pen->getColor()->red,
$this->pen->getColor()->green,
$this->pen->getColor()->blue);
//$this->shape->setRightFill($this->shape->addFill(0xff, 0, 0));
$this->shape->movePenTo($p1->getX(),$p1->getY());
$this->shape->drawLineTo($p2->getX(),$p2->getY());
* Draw a filled gray box with thick borders and darker corners.
* @param integer top left coordinate (x)
* @param integer top left coordinate (y)
* @param integer bottom right coordinate (x)
* @param integer bottom right coordinate (y)
* @param Color edge color
* @param Color corner color
public function outlinedBox($x1, $y1, $x2, $y2, $color0, $color1) {
/* if ($this->brush->getVisible()) {
if ($this->getBrush()->getGradient()->getVisible()==true) {
$colA = array($this->getBrush()->getGradient()->getStartColor()->getRed(),
$this->getBrush()->getGradient()->getStartColor()->getGreen(),
$this->getBrush()->getGradient()->getStartColor()->getBlue());
$colB = array($this->getBrush()->getGradient()->getEndColor()->getRed(),
$this->getBrush()->getGradient()->getEndColor()->getGreen(),
$this->getBrush()->getGradient()->getEndColor()->getBlue());
$penWidth=$this->getPen()->getWidth();
Gradient::imagecolorgradient(
$x1+$penWidth, $y1+$penWidth,
imagefilledrectangle($this->img, $x1, $y1, $x2, $y2, $color0->getColor($this->img));
imagerectangle($this->img, $x1, $y1, $x1 + 1, $y1 + 1, $color1->getColor($this->img));
imagerectangle($this->img, $x2 - 1, $y1, $x2, $y1 + 1, $color1->getColor($this->img));
imagerectangle($this->img, $x1, $y2 - 1, $x1 + 1, $y2, $color1->getColor($this->img));
imagerectangle($this->img, $x2 - 1, $y2 - 1, $x2, $y2, $color1->getColor($this->img));
public function paintBevel($bevel, $rect, $width, $one, $two) {
$a = new ChartPen(null,$one);
$this->doBevelRect($rect, $a, $b);
* Draws a 3D Pie slice using start Angle and end Angle and donut percent.
* @param startAngle double
* @param darkSides boolean
* @param drawSides boolean
* @param donutPercent int
/* public function pie($xCenter, $yCenter, $xRadius, $yRadius, $z0,
$z1, $startAngle, $endAngle, $darkSides, $drawSides, $donutPercent=0) {
if ($this->pie3D == null) {
$this->pie3D = new Pie3D($this);
$this->pie3D->pie($xCenter, $yCenter, $xRadius, $yRadius, $z0, $z1, $startAngle,
$endAngle, $darkSides, $drawSides, $donutPercent);
public function pie($xCenter, $yCenter, $xOffset, $yOffset, $xRadius,
$yRadius, $z0, $z1, $startAngle, $endAngle,
$darkSides, $drawSides, $donutPercent,
$bevelPercent, $edgeStyle, $last/*, Shadow shadow*/)
if ($this->pie3D == null) {
$this->pie3D = new Pie3D($this);
$this->pie3D->pie( $xCenter + $xOffset, $yCenter - $yOffset, $xRadius, $yRadius, $z0, $z1,
$startAngle, $endAngle, $darkSides, $drawSides,
$donutPercent, $bevelPercent, $edgeStyle, $last);
* Draws a vertical or horizontal Pyramid with optional dark shaded sides.
* @param vertical boolean
* @param darkSides boolean
public function pyramidRect($vertical, $r, $z0, $z1, $darkSides) {
$this->pyramid($vertical, $r->x, $r->y, $r->getRight(), $r->getBottom(), $z0, $z1,
* Draws a vertical or horizontal Pyramid with optional dark shaded sides.
* @param vertical boolean
* @param darkSides boolean
public function pyramid($vertical, $left, $top, $right, $bottom, $z0, $z1, $darkSides) {
$oldColor = $this->brush->getSolid() ? $this->brush->getColor() : $this->getBackColor();
$p0 = $this->calc3DPoint($left, $bottom, $z0);
$p1 = $this->calc3DPoint($right, $bottom, $z0);
$pTop = $this->calc3DPoint(($left + $right) / 2, $top, ($z0 + $z1) / 2);
$tmpArray = Array($p0, $pTop, $p1);
$this->polygon($tmpArray);
$p2 = $this->calc3DPoint($left, $bottom, $z1);
$tmpArray = Array($p0, $pTop, $p2);
$this->polygon($tmpArray);
$this->internalApplyDark($oldColor, self::$DARKERCOLORQUANTITY);
$p3 = $this->calc3DPoint($right, $bottom, $z1);
$tmpArray = Array($p1, $pTop, $p3);
$this->polygon($tmpArray);
if (($top < $bottom) && ($p2->y < $pTop->y)) {
$tmpArray = Array($pTop, $p2, $p3);
$this->polygon($tmpArray);
$this->internalApplyDark($oldColor, self::$DARKCOLORQUANTITY);
$this->rectangleY($left, $bottom, $right, $z0, $z1);
$p0 = $this->calc3DPoint($left, $top, $z0);
$p1 = $this->calc3DPoint($left, $bottom, $z0);
$pTop = $this->calc3DPoint($right, ($top + $bottom) / 2, ($z0 + $z1) / 2);
$tmpArray = Array($p0, $pTop, $p1);
$this->polygon($tmpArray);
$this->internalApplyDark($oldColor, self::$DARKCOLORQUANTITY);
$p2 = $this->calc3DPoint($left, $top, $z1);
$tmpArray = Array($p0, $pTop, $p2);
$this->polygon($tmpArray);
$this->internalApplyDark($oldColor, self::$DARKERCOLORQUANTITY);
$this->rectangleZ($left, $top, $bottom, $z0, $z1);
* Sets / returns the color used to fill spaces when displaying text
* or filling with brushes of different style other than bsSolid.<br>
* Brush.Visible must be set to true.
return $this->brush->getColor();
$this->brush->setColor($value);
* Draws a pyramid with a truncated apex of variable thickness.
public function pyramidTrunc($r, $startZ, $endZ, $truncX, $truncZ) {
* Draws a polygon (Point p1, Point p2) at Z depth offset.
public function plane($p1, $p2, $z0, $z1) {
$this->iPoints[0] = $this->calc3DPos($p1->getX(), $p1->getY(), $z0);
$this->iPoints[1] = $this->calc3DPos($p2->getX(), $p2->getY(), $z0);
$this->iPoints[2] = $this->calc3DPos($p2->getX(), $p2->getY(), $z1);
$this->iPoints[3] = $this->calc3DPos($p1->getX(), $p1->getY(), $z1);
* Draws a polygon (Point p1, Point p2, Point p3, Point p4) at Z depth
public function _plane($p1, $p2, $p3, $p4, $z) {
$this->iPoints[0] = $this->calc3DPos($p1->getX(), $p1->getY(), $z);
$this->iPoints[1] = $this->calc3DPos($p2->getX(), $p2->getY(), $z);
$this->iPoints[2] = $this->calc3DPos($p3->getX(), $p3->getY(), $z);
$this->iPoints[3] = $this->calc3DPos($p4->getX(), $p4->getY(), $z);
* Draws a polygon of four points.
$this->iPoints[0] = $this->calc3DPoint($p[0]->x, $p[0]->y, $z0);
$this->iPoints[1] = $this->calc3DPoint($p[1]->x, $p[1]->y, $z0);
$this->iPoints[2] = $this->calc3DPoint($p[2]->x, $p[2]->y, $z1);
$this->iPoints[3] = $this->calc3DPoint($p[3]->x, $p[3]->y, $z1);
if ($this->brush->getVisible()) {
$sqfill = $shape->addFill(0, 0, 0xff);
//$shape->setRightFill($sqfill);
$shape->movePenTo($points[0]->x,$points[0]->y);
for($ipt= 0;$ipt< sizeof($points);$ipt++ )
$shape->drawLineTo($points[$ipt]->x, $points[$ipt]->y);
$shape->drawLineTo($points[0]->x, $points[0]->y);
$c1 = imagecolorallocatealpha($this->img, $this->getBrush()->getColor()->red,
$this->getBrush()->getColor()->green,
$this->getBrush()->getColor()->blue,
$this->getBrush()->getTransparency());
$p1 = imagecolorallocatealpha($this->img, $this->getPen()->getColor()->red,
$this->getPen()->getColor()->green,
$this->getPen()->getColor()->blue,
$this->getPen()->getTransparency());
for ($tt=0;$tt < sizeof($points); $tt++) {
$tmpTeePointDouble =$points[$tt];
$tmpX=$tmpTeePointDouble->getX();
$tmpY=$tmpTeePointDouble->getY();
if (count($tmpArray2) >= 3) {
imageantialias($this->img,true);
imagefilledpolygon($this->img, $tmpArray2, count($tmpArray2)/2, $c1);
imageantialias($this->img,false);
if ($this->getPen()->getVisible()) {
// Gets the pen color and style (dot , dashed, ...)
$penColorStyle = $this->getPenColorStyle();
imagesetstyle($this->img, $penColorStyle);
// Assign the pen width for the image
imagesetthickness ( $this->img, $this->pen->getWidth());
if (count($tmpArray2) >= 3) {
imageantialias($this->img,true);
imagepolygon($this->img, $tmpArray2, count($tmpArray2)/2, $p1);
imageantialias($this->img,false);
* Draws a polygon with z position offset.
for ($t = 0; $t < sizeof($p); $t++ ) {
$p[$t] = $this->calc3DPoint($p[$t]->getX(),$p[$t]->getY(), $z);
$p = Array($p0, $p1, $p2);
if ($this->brush->getVisible()) {
$c1 = imagecolorallocatealpha($this->img, $this->getBrush()->getColor()->red,
$this->getBrush()->getColor()->green,
$this->getBrush()->getColor()->blue,
$this->getBrush()->getTransparency());
$p1 = imagecolorallocatealpha($this->img, $this->getPen()->getColor()->red,
$this->getPen()->getColor()->green,
$this->getPen()->getColor()->blue,
$this->getPen()->getTransparency());
for ($tt=0;$tt < count($this->iPointDoubles); $tt++) {
$tmpTeePoint =$this->iPointDoubles[$tt];
$tmpX=$tmpTeePoint->getX();
$tmpY=$tmpTeePoint->getY();
if (count($tmpArray2) >= 3) {
imageantialias($this->img,true);
imagefilledpolygon($this->img, $tmpArray2, count($tmpArray2)/2, $c1);
imageantialias($this->img,false);
if ($this->getPen()->getVisible()) {
// Gets the pen color and style (dot , dashed, ...)
$penColorStyle = $this->getPenColorStyle();
imagesetstyle($this->img, $penColorStyle);
// Assign the pen width for the image
imagesetthickness ( $this->img, $this->pen->getWidth());
if (count($tmpArray2) >= 3) {
imageantialias($this->img,true);
imagepolygon($this->img, $tmpArray2, count($tmpArray2)/2, $p1);
imageantialias($this->img,false);
private function polygonFour() {
if ($this->brush->getVisible()) {
$c1 = imagecolorallocatealpha($this->img, $this->getBrush()->getColor()->red,
$this->getBrush()->getColor()->green,
$this->getBrush()->getColor()->blue,
$this->getBrush()->getTransparency());
$p1 = imagecolorallocatealpha($this->img, $this->getPen()->getColor()->red,
$this->getPen()->getColor()->green,
$this->getPen()->getColor()->blue,
$this->getPen()->getTransparency());
for ($tt=0;$tt < count($this->iPoints); $tt++) {
$tmpTeePoint =$this->iPoints[$tt];
$tmpX=$tmpTeePoint->getX();
$tmpY=$tmpTeePoint->getY();
if (count($tmpArray2) >= 3) {
imageantialias($this->img,true);
imagefilledpolygon($this->img, $tmpArray2, count($tmpArray2)/2, $c1);
imageantialias($this->img,false);
if ($this->getPen()->getVisible()) {
// Gets the pen color and style (dot , dashed, ...)
$penColorStyle = $this->getPenColorStyle();
imagesetstyle($this->img, $penColorStyle);
// Assign the pen width for the image
imagesetthickness ( $this->img, $this->pen->getWidth());
if (count($tmpArray2) >= 3) {
imageantialias($this->img,true);
imagepolygon($this->img, $tmpArray2, count($tmpArray2)/2, $p1);
imageantialias($this->img,false);
* Draws a series of line segments to join point array p at z displacement.
$tmpP = Array(); //new Point[l];
for ($t = 0; $t < $l; $t++ ) {
$tmpP[$t] = $this->calc3DPoint($p[$t]->getX(),$p[$t]->getY(), $z);
for ($t = 1; $t < $l; $t++ ) {
$this->line($tmpP[$t - 1]->getX(),$tmpP[$t - 1]->getY(),
$tmpP[$t]->getX(),$tmpP[$t]->getY());
* @param integer text coordinate (x)
* @param integer text coordinate (y)
* @param Color text color
* @param string text value
* @param string font file name
* @param bitfield text alignment
public function printText($img, $px, $py, $text, $align = - 1) {
$color = $font->getBrush()->getColor();
$fontFileName = $font->getName();
$fontSize = $font->getFontSize();
$textWidth = $this->textWidth($text); // $lrx - $llx;
$textHeight = $this->textHeight($text); // $fontSize; // $lry - $ury;
if (in_array (StringAlignment::$VERTICAL_CENTER_ALIGN, $align)) {
/*if (in_array (StringAlignment::$VERTICAL_TOP_ALIGN, $align)) {
if (in_array (StringAlignment::$VERTICAL_BOTTOM_ALIGN, $align)) {
imagettftext($img, $fontSize, $angle, $px, $py, $color->getColor($img),
// $f = new SWFFont($fontFileName);
$f = new SWFFont('Arial');
$t->setColor($font->getBrush()->getColor()->getRed(),$font->getBrush()->getColor()->getGreen(),
$font->getBrush()->getColor()->getBlue(), $font->getBrush()->getColor()->getAlpha());
//$t->setHeight($fontSize);
$text = $this->img->add($t);
* Print text centered horizontally on the image.
* @param integer text coordinate (y)
* @param Color text color
* @param string text value
* @param string font file name
public function printCentered($img, $py, $color, $text, $fontFileName) {
$this->printText($img, imagesx($img) / 2, $py, $color, $text, $fontFileName,
* Print text in diagonal.
* @param integer text coordinate (x)
* @param integer text coordinate (y)
* @param Color text color
* @param string text value
$fontSize = $font->getFontSize();
$fontFileName = $font->getName();
$color = $font->getBrush()->getColor(); // $this->textColor;
list ($lx, $ly, $rx, $ry) = imageftbbox($fontSize, 0, $fontFileName,
strtoupper($text), array("linespacing" => $lineSpacing));
imagettftext($img, $fontSize, $angle, $px, $py, $color->getColor($img),
* Internal use. Calculates the projection co-ordinates for rectangle
* @param maxDepth int is the max shape depth
* @param r Rectangle is the projected shape rectangle
$this->xCenterOffset = $this->xCenter + $this->aspect->getHorizOffset();
$this->yCenterOffset = $this->yCenter + $this->aspect->getVertOffset();
public function rectangle($rect,$animations= null) {
/* $c1 = imagecolorallocatealpha($this->img, $this->getBrush()->getColor()->red,
$this->getBrush()->getColor()->green,
$this->getBrush()->getColor()->blue,
$this->getBrush()->getTransparency());
if ($this->getBrush()->getGradient()->getVisible()== true) {
$colA = array($this->getBrush()->getGradient()->getStartColor()->getRed(),
$this->getBrush()->getGradient()->getStartColor()->getGreen(),
$this->getBrush()->getGradient()->getStartColor()->getBlue());
$colB = array($this->getBrush()->getGradient()->getEndColor()->getRed(),
$this->getBrush()->getGradient()->getEndColor()->getGreen(),
$this->getBrush()->getGradient()->getEndColor()->getBlue());
$penWidth=$this->getPen()->getWidth();
Gradient::imagecolorgradient(
$rect->getX()+$penWidth, $rect->getY()+$penWidth,
$rect->getRight()-$penWidth, $rect->getHeight()-$penWidth+$rect->getY(),
$penColor = $this->getPen()->getColor();
$shape->setLine($this->getPen()->getWidth(),$penColor->getRed(), $penColor->getGreen(), $penColor->getBlue());
//$shape->setRightFill($shape->addFill($brush->getRed(),$brush->getGreen(),$brush->getBlue()));
$shape->movePenTo($rect->x,$rect->y);
$shape->drawLineTo($rect->getRight(),$rect->y);
$shape->drawLineTo($rect->getRight(),$rect->getBottom());
$shape->drawLineTo($rect->x,$rect->getBottom());
$shape->drawLineTo($rect->x,$rect->y);
for ($i= 0;$i< sizeof($animations);$i++ )
//Now we can use that shape in a movie clip and define some actions:
$sqclip = new SWFSprite();
$i = $sqclip->add($shape);
$sqclip->add(new SWFAction("stop();"));
$sqclip->add(new SWFAction("play();"));
//Next we'll create another shape and use it for a button. Rather than create a separate shape for each button action (over, down, up, and release), I've created a function to automate drawing the shapes:
function rect($r, $g, $b) {
$s->setRightFill($s->addFill($r, $g, $b));
$b->addShape(rect(0xff, 0, 0), SWFBUTTON_UP | SWFBUTTON_HIT);
$b->addShape(rect(0, 0xff, 0), SWFBUTTON_OVER);
$b->addShape(rect(0, 0, 0xff), SWFBUTTON_DOWN);
$b->addAction(new SWFAction("setTarget('/box'); gotoandplay(2);"), SWFBUTTON_MOUSEDOWN);
//Next, we define the movie and place the movie clip (sprite) and the button in the movie itself:
//$m->setDimension(4000,3000);
//$m->setBackground(255,0,0);
$i = $this->img->add($sqclip);
$i = $this->img->add($b);
//$this->img->add($shape);
// Gradient // TODO post the code into the shape..
/* if ($this->getBrush()->getGradient()->getVisible()==true) {
$this->getBrush()->getGradient()->fill($this->img,
$this->getBrush()->getGradient()->getDirection(),
$this->getBrush()->getGradient()->getStartColor(),
$this->getBrush()->getGradient()->getEndColor());
if ($this->getPen()->getVisible()) {
// Gets the pen color and style (dot , dashed, ...)
$penColorStyle = $this->getPenColorStyle();
imagesetstyle($this->img, $penColorStyle);
// Assign the pen width for the image
imagesetthickness ( $this->img, $this->pen->getWidth());
imagerectangle($this->img, $rect->x, $rect->y, $rect->getRight(),
$rect->getBottom(), IMG_COLOR_STYLED);
public function _rectangle($x, $y, $width, $height) {
* Horizontal Rectangle from Left to Right, from Z0 to Z1 position,
public function rectangleZ($left, $top, $bottom, $z0, $z1) {
$this->iPoints[0] = $this->calc3DPos($left, $top, $z0);
$this->iPoints[1] = $this->calc3DPos($left, $top, $z1);
$this->iPoints[2] = $this->calc3DPos($left, $bottom, $z1);
$this->iPoints[3] = $this->calc3DPos($left, $bottom, $z0);
$this->iPoints[0] = $this->calc3DPos($r->x, $r->y, $z);
$this->iPoints[1] = $this->calc3DPos($r->getRight(), $r->y, $z);
$this->iPoints[2] = $this->calc3DPos($r->getRight(), $r->getBottom(), $z);
$this->iPoints[3] = $this->calc3DPos($r->x, $r->getBottom(), $z);
* Horizontal Rectangle from Left to Right, from Z0 to Z1 position,
public function rectangleY($left, $top, $right, $z0, $z1) {
$this->iPoints[0] = $this->calc3DPos($left, $top, $z0);
$this->iPoints[1] = $this->calc3DPos($right, $top, $z0);
$this->iPoints[2] = $this->calc3DPos($right, $top, $z1);
$this->iPoints[3] = $this->calc3DPos($left, $top, $z1);
// With this function you will draw rounded corners rectangles with transparent colors.
// Empty (not filled) figures are allowed too!!
$color = imagecolorallocate($this->img, $this->getBrush()->getColor()->red,
$this->getBrush()->getColor()->green,
$this->getBrush()->getColor()->blue);
if ($this->getBrush()->getVisible()) {
imagefilledrectangle($this->img, $x1+$radius, $y1, $x2-$radius, $y2, $color);
imagefilledrectangle($this->img, $x1, $y1+$radius, $x1+$radius-1, $y2-$radius, $color);
imagefilledrectangle($this->img, $x2-$radius+1, $y1+$radius, $x2, $y2-$radius, $color);
imagefilledarc($this->img,$x1+$radius, $y1+$radius, $radius*2, $radius*2, 180 , 270, $color, IMG_ARC_PIE);
imagefilledarc($this->img,$x2-$radius, $y1+$radius, $radius*2, $radius*2, 270 , 360, $color, IMG_ARC_PIE);
imagefilledarc($this->img,$x1+$radius, $y2-$radius, $radius*2, $radius*2, 90 , 180, $color, IMG_ARC_PIE);
imagefilledarc($this->img,$x2-$radius, $y2-$radius, $radius*2, $radius*2, 360 , 90, $color, IMG_ARC_PIE);
imageline($this->img, $x1+$radius, $y1, $x2-$radius, $y1, $color);
imageline($this->img, $x1+$radius, $y2, $x2-$radius, $y2, $color);
imageline($this->img, $x1, $y1+$radius, $x1, $y2-$radius, $color);
imageline($this->img, $x2, $y1+$radius, $x2, $y2-$radius, $color);
imagearc($this->img,$x1+$radius, $y1+$radius, $radius*2, $radius*2, 180 , 270, $color);
imagearc($this->img,$x2-$radius, $y1+$radius, $radius*2, $radius*2, 270 , 360, $color);
imagearc($this->img,$x1+$radius, $y2-$radius, $radius*2, $radius*2, 90 , 180, $color);
imagearc($this->img,$x2-$radius, $y2-$radius, $radius*2, $radius*2, 360 , 90, $color);
$sourcefile_width=imagesx($this->img);
$sourcefile_height=imagesy($this->img);
$background = imagecreatetruecolor($sourcefile_width,$sourcefile_height);
$backcolor = new Color(0,0,0,127); // transparent
$forecolor = new Color(0,0,0,127); // transparent
if ($shapeBorders->getTopLeft()->getBorderRound() > 0) {
$endsize=$shapeBorders->getTopLeft()->getBorderRound();;
imagecopymerge($background, $this->img, 0, 0, 0, 0, $sourcefile_width, $sourcefile_height, 100);
$startx=$sourcefile_width*2-1;
$starty=$sourcefile_height*2-1;
$im_temp = imagecreatetruecolor($startx,$starty);
imagecopyresampled($im_temp, $background, 0, 0, 0, 0, $startx, $starty, $sourcefile_width, $sourcefile_height);
$bg = imagecolorallocate($im_temp,$backcolor->red,$backcolor->green, $backcolor->blue);
$fg = imagecolorallocate($im_temp,$forecolor->red,$forecolor->green, $forecolor->blue);
imagearc($im_temp, $startsize, $startsize, $arcsize, $arcsize, 180,270,$fg);
imagefilltoborder($im_temp,0,0,$fg,$bg);
imagecopyresampled($this->img, $im_temp, 0, 0, 0, 0, $sourcefile_width,$sourcefile_height,$startx, $starty);
if ($shapeBorders->getBottomLeft()->getBorderRound() > 0) {
$endsize=$shapeBorders->getBottomLeft()->getBorderRound();;
imagecopymerge($background, $this->img, 0, 0, 0, 0, $sourcefile_width, $sourcefile_height, 100);
$startx=$sourcefile_width*2-1;
$starty=$sourcefile_height*2-1;
$im_temp = imagecreatetruecolor($startx,$starty);
imagecopyresampled($im_temp, $background, 0, 0, 0, 0, $startx, $starty, $sourcefile_width, $sourcefile_height);
$bg = imagecolorallocate($im_temp,$backcolor->red,$backcolor->green, $backcolor->blue);
$fg = imagecolorallocate($im_temp,$forecolor->red,$forecolor->green, $forecolor->blue);
imagearc($im_temp, $startsize, $starty-$startsize,$arcsize, $arcsize, 90,180,$fg);
imagefilltoborder($im_temp,0,$starty,$fg,$bg);
imagecopyresampled($this->img, $im_temp, 0, 0, 0, 0, $sourcefile_width,$sourcefile_height,$startx, $starty);
if ($shapeBorders->getTopRight()->getBorderRound() > 0) {
$endsize=$shapeBorders->getTopRight()->getBorderRound();;
imagecopymerge($background, $this->img, 0, 0, 0, 0, $sourcefile_width, $sourcefile_height, 100);
$startx=$sourcefile_width*2-1;
$starty=$sourcefile_height*2-1;
$im_temp = imagecreatetruecolor($startx,$starty);
imagecopyresampled($im_temp, $background, 0, 0, 0, 0, $startx, $starty, $sourcefile_width, $sourcefile_height);
$bg = imagecolorallocate($im_temp,$backcolor->red,$backcolor->green, $backcolor->blue);
$fg = imagecolorallocate($im_temp,$forecolor->red,$forecolor->green, $forecolor->blue);
imagearc($im_temp, $startx-$startsize, $startsize,$arcsize, $arcsize, 270,360,$fg);
imagefilltoborder($im_temp,$startx,0,$fg,$bg);
imagecopyresampled($this->img, $im_temp, 0, 0, 0, 0, $sourcefile_width,$sourcefile_height,$startx, $starty);
if ($shapeBorders->getBottomRight()->getBorderRound() > 0) {
$endsize=$shapeBorders->getBottomRight()->getBorderRound();;
imagecopymerge($background, $this->img, 0, 0, 0, 0, $sourcefile_width, $sourcefile_height, 100);
$startx=$sourcefile_width*2-1;
$starty=$sourcefile_height*2-1;
$im_temp = imagecreatetruecolor($startx,$starty);
imagecopyresampled($im_temp, $background, 0, 0, 0, 0, $startx, $starty, $sourcefile_width, $sourcefile_height);
$bg = imagecolorallocate($im_temp,$backcolor->red,$backcolor->green, $backcolor->blue);
$fg = imagecolorallocate($im_temp,$forecolor->red,$forecolor->green, $forecolor->blue);
imagearc($im_temp, $startx-$startsize, $starty-$startsize,$arcsize, $arcsize, 0,90,$fg);
imagefilltoborder($im_temp,$startx,$starty,$fg,$bg);
imagecopyresampled($this->img, $im_temp, 0, 0, 0, 0, $sourcefile_width,$sourcefile_height,$startx, $starty);
imagedestroy($background);
* Draws a triangle (point p0, pointp1, pointp2) at Z position.
public function triangle($p0, $p1, $p2, $z= 0) {
$p0 = $this->calc3DPoint($p0->getX(), $p0->getY(), $z);
$p1 = $this->calc3DPoint($p1->getX(), $p1->getY(), $z);
$p2 = $this->calc3DPoint($p2->getX(), $p2->getY(), $z);
public function arc($x1,$y1,$x2,$y2,$startAngle, $sweepAngle,$filled= 0) {
$color = imagecolorallocate($this->img, $this->getBrush()->getColor()->red,
$this->getBrush()->getColor()->green,
$this->getBrush()->getColor()->blue);
if ($this->getBrush()->getVisible()) {
imagefilledarc($this->img,$x1, $y1, $x2-$x1, $y2-$y1, $startAngle , $endAngle, $color, IMG_ARC_PIE);
imagearc($this->img,$x1, $y1, $x2-$x1, $y2-$y1, $startAngle, $endAngle, $color);
* Draws a triangle (Triangle3D p).
public void triangle(Triangle3D p) {
Point[] tmp = {calc3DPoint(p.p0), calc3DPoint(p.p1), calc3DPoint(p.p2)};
* Draws a rotated text String at the specified x,y and z coordinates with
* the RotDegree rotation angle.<br>
* RotDegree values must be between 0 and 360.<br>
* The string is drawn on the Chart Drawing Canvas.
* @param rotDegree double
public function rotateLabel($x, $y, $z, $text, $rotDegree) {
// TODO z param is not considred for the moment
* Draws a rotated text String at the specified Point x,y coordinates with
* the RotDegree rotation angle.<br>
* RotDegree values must be between 0 and 360.<br>
* The string is drawn on the Chart Drawing Canvas.
* @param rotDegree double
$this->rotateLabel($p->getX(), $p->getY(), $text, $rotDegree);
$tmpCenter = $r->center();
$tmpRect->offset( - $tmpCenter->x, - $tmpCenter->y);
$result[0] = $this->rotatePoint($tmpRect->x, $tmpRect->y, $tmpCenter, $tmpCos, $tmpSin);
$result[1] = $this->rotatePoint($tmpRect->getRight(), $tmpRect->y, $tmpCenter,
$result[2] = $this->rotatePoint($tmpRect->getRight(), $tmpRect->getBottom(),
$result[3] = $this->rotatePoint($tmpRect->x, $tmpRect->getBottom(), $tmpCenter,
private function rotatePoint($ax, $ay, $tmpCenter, $tmpCos, $tmpSin) {
$p->x = $tmpCenter->x + (int) ($ax * $tmpCos + $ay * $tmpSin);
$p->y = $tmpCenter->y + (int) ( - $ax * $tmpSin + $ay * $tmpCos);
for ($t = 0; $t < $length; $t++ ) {
$result[$t] = $source[$t];
* Displays the 2D non-rotated label at the specified X Y screen
* Text is outputted to the correct internal drawing Graphics2D. <br>
* The X and Y coordinates must be valid and fit inside the Chart
* rectangle. It uses the current drawing Font attributes. <br>
* Writes text at the named x and y co-ordinates.
public function textOut($x, $y, $z, $text, $align=- 1) {
if (($this->iZoomText) && ($this->iZoomFactor != -1)) {
(double) $old = $this->font->getDrawingFont()->getSize();
(int) $tmp = (int) max(1, $this->iZoomFactor * $old);
$this->font->setSize($tmp);
if ($f->shouldDrawShadow()) {
$this->drawString(x + s.getWidth(), y + s.getHeight(), text, s.getBrush());
$this->printText($this->img, $x, $y, $text, $align); //, $f->getBrush());
* Returns the vertical text size in pixels of ChartFont f.
* @return int Height in pixels of ChartFont f.
return imagefontheight($f->getFontSize());
* Returns the horizontal text size in pixels of ChartFont f.
* @return int Width in pixels of ChartFont f.
list ($llx, $lly, $lrx, $lry, $urx, $ury, $ulx, $uly) = imageftbbox($f->getFontSize(),
0, $f->getName(), strtoupper($text), array("linespacing" => $lineSpacing));
* Returns the vertical size in pixels of the text String.
* @return int Height in pixels of the text String.
* Calculates the boundary points of the convex hull of a set of 2D xy
// find pivot point, which is known to be on the hull
// point with lowest y - if there are multiple, point with highest x
$tmpubound = $ubound - 1;
for ($lIndex = $lbound; $lIndex <= $ubound; $lIndex++ ) {
if ($p[$lIndex]->getY() == $lminY) {
if ($p[$lIndex]->getX() > $lmaxX) {
$lmaxX = $p[$lIndex]->getX();
} else if ($p[$lIndex]->getY() < $lminY) {
$lminY = $p[$lIndex]->getY();
$lmaxX = $p[$lIndex]->getX();
// put pivot into seperate variable and remove from array
$lPivot = $p[$lpivotIndex];
$p[$lpivotIndex] = $p[$ubound];
// calculate angle to pivot for each point in the array
// quicker to calculate dot product of point with a horizontal comparison vector
$langles = Array(); // Array of doubles
//double[] langles = new double[tmpubound + 1];
for ($lindex = 0; $lindex <= $tmpubound; $lindex++ ) {
$lvx = $lPivot->getX() - $p[$lindex]->getX();
$lvy = $lPivot->getY() - $p[$lindex]->getY();
// reduce to a unit-vector - length 1
$tmp = sqrt($lvx * $lvx + $lvy * $lvy);
$langles[$lindex] = ($tmp == 0) ? 0.0 : $lvx / $tmp;
// sort the points by angle
self::quickSortAngle($p, $langles, 0, $tmpubound);
// step through array to remove points that are not part of the convex hull
// assign points behind and infront of current point
$lInFront = ($t == $tmpubound) ? $lPivot : $p[$t + 1];
// work out if we are making a right or left turn using vector product
$lrightturn = (($lBehind->getX() - $p[$t]->getX()) * ($lInFront->getY() - $p[$t]->getY())) -
(($lInFront->getX() - $p[$t]->getX()) * ($lBehind->getY() - $p[$t]->getY())) < 0;
// remove point from convex hull
for ($i = $t; $i < $tmphigh; $i++ ) {
$tmpubound = $tmphigh - 1;
$t-- ; // backtrack to previous point
} while ($t != $tmpubound);
// add pivot back into points array
$p[$tmpubound] = $lPivot;
* Sort an array of points by angles.
static private function quickSortAngle($p, $angles, $low, $high) {
$midangle = $angles[($lo + $hi) / 2];
while ($angles[$lo] < $midangle) {
} while ($angles[$hi] > $midangle) {
$angles[$lo] = $angles[$hi];
// perform quicksorts on subsections
self::quickSortAngle($p, $angles, $low, $hi);
self::quickSortAngle($p, $angles, $lo, $high);
/**************************************************************************
* Gets and Sets methods..... *
**************************************************************************/
private function setAspect($value) {
$this->is3D = $this->aspect->getView3D();
$this->isOrtho = $this->aspect->getOrthogonal();
* Determines the kind of brush used to fill the Canvas draw rectangle
* The Brush.Visible method must be set to true.
* Determines the kind of brush used to fill the Canvas draw rectangle
* The Brush.Visible method must be set to true.
* @param value ChartBrush
* Returns a color from global ColorPalette array variable.
return $this->colorPalette[$index % sizeof($this->colorPalette)];
* Specifies a color from global ColorPalette array variable.
$this->colorPalette= $palette;
//$colorPalette = Array(); //sizeof($palette.length)];
/* for ($t = 0; $t < sizeof($palette); $t++) {
$this->colorPalette[$t] = $palette[$t];
$this->getChart()->doBaseInvalidate();
return sizeof($this->colorPalette);
* Determines the Font for outputted text when using the Drawing Canvas.
* Determines the Font for outputted text when using the Drawing Canvas.
$this->font->assign($value);
* Defines the Height of the Font in pixels.
$this->GraphicsGD= $value;
* Gets / Sets the alignment used when displaying text using TextOut or TextOut3D.
* @param value StringAlignment
* Indicates the kind of pen used to draw Canvas lines.
* Determines the kind of pen used to draw Canvas lines.
public function setPen($value) {
$this->pen->assign($value);
private function getPenColorStyle() {
$penColor = imagecolorallocatealpha($this->img,
$this->pen->getColor()->red,
$this->pen->getColor()->green,
$this->pen->getColor()->blue,
$this->pen->getColor()->alpha);
switch ($this->pen->getStyle()) {
return array($penColor,IMG_COLOR_TRANSPARENT);
return array($penColor,$penColor,IMG_COLOR_TRANSPARENT,IMG_COLOR_TRANSPARENT,IMG_COLOR_TRANSPARENT);
return array($penColor,$penColor,IMG_COLOR_TRANSPARENT,$penColor);
return array($penColor,$penColor,IMG_COLOR_TRANSPARENT,$penColor,IMG_COLOR_TRANSPARENT,$penColor);
default: // SOLID value 0
* Sets the Pixel location (using X,Y,Z) of the centre of rotation for use
* with the Aspect Rotation and Elevation properties.<br>
return $this->rotationCenter;
* Returns the bounding rectangle for a given array of XY points.
$r = new Rectangle($p[0]->getX(), $p[0]->getY(), 0, 0);
for ($t = 1; $t < $num; $t++ ) {
if ($p[$t]->getX() < $r->getX()) {
$r->setX($p[$t]->getX());
if ($p[$t]->getX() > $r->getRight()) {
$r->setWidth($p[$t]->getX() - $r->getX());
if ($p[$t]->getY() < $r->getY()) {
$r->setY($p[$t]->getY());
if ($p[$t]->getY() > $r->getBottom()) {
$r->setHeight($p[$t]->getY() - $r->getY());
* Obsolete. Please use Rectangle.<!-- -->Contains method.
return $rect->contains($x, $y);
* Returns true if point P is inside the vert triangle of x0y0, midxY1,
* Returns true if point P is inside the horizontal triangle.
/// Returns point "ATo" minus ADist pixels from AFrom point.
if ($To->getX() != $From->getX())
$angle = atan2($To->getY() - $From->getY(), $To->getX() - $From->getX());
if ($To->getY() < $From->getY()) $py += $distance;
* Returns true if point P is inside the ellipse bounded by Left, Top,
* Returns true if point P is inside the ellipse bounded by Rect.
$tmpWidth = (int) sqr($tmp->getX() - $rect->getX());
$tmpHeight = (int) sqr($tmp->getY() - $rect->getY());
return ($tmpWidth != 0) && ($tmpHeight != 0) &&
((sqr($p->getX() - $tmp->getX()) / $tmpWidth) +
(sqr($p->getY() - $tmp->getY()) / $tmpHeight) <= 1
* Returns true if point P is inside Poly polygon.
for ($i = 0; $i <= $tmp; $i++ ) {
if ((((($poly[$i]->getY() <= $p->getY()) && ($p->getY() < $poly[$j]->getY())) ||
(($poly[$j]->getY() <= $p->getY()) && ($p->getY() < $poly[$i]->getY()))) &&
($p->getX() < ($poly[$j]->getX() - $poly[$i]->getX()) * ($p->getY() - $poly[$i]->getY())
/ ($poly[$j]->getY() - $poly[$i]->getY()) + $poly[$i]->getX()))) {
return $this->iZoomFactor;
$this->iZoomFactor = $value;
* The X coordinate of the pixel location of the center of the 3D
* The origin of the pixel coordinate system is in the top left corner of
* Specifies the X coordinate of the pixel location of the center of the 3D
* The origin of the pixel coordinate system is in the top left corner of
* The Y coordinate of the pixel location of the center of the 3D
* The origin of the pixel coordinate system is in the top left corner of
* Specifies the Y coordinate of the pixel location of the center of the 3D
* The origin of the pixel coordinate system is in the top left corner of
* Returns a valid Windows Brush Style from anpalette of many possible
$patternPalette = Array (
return $patternPalette[$index % sizeof($patternPalette)];
* The anti-alias mode for the Graphics Pen when Custom drawing.<br>
* AntiAlias - Specifies antialiased rendering.<br>
* Default - Specifies the default mode.<br>
* HighQuality - Specifies high quality, low speed rendering.
* HighSpeed - Specifies high speed, low quality rendering.<br>
* Invalid - Specifies an invalid mode. <br>
* Sets the anti-alias mode for the Graphics Pen when Custom drawing.<br>
* AntiAlias - Specifies antialiased rendering.<br>
* Default - Specifies the default mode.<br>
* HighQuality - Specifies high quality, low speed rendering.
* HighSpeed - Specifies high speed, low quality rendering.<br>
* Invalid - Specifies an invalid mode. <br>
static private function internalGetSupports3DText() {
* Returns if Canvas supports 3D Text or not.
return self::internalGetSupports3DText();
* Returns if Canvas can do rotation and elevation of more than 90 degree.
($r->getX() + $r->getRight()) / 2,
($r->y + $r->getBottom()) / 2
$radians = (M_PI * $degrees) / 180.0;
$radiusH = $rectBounds->getWidth() / 2.0;
$radiusV = $rectBounds->getHeight() / 2.0;
$tmpX = $centrePoint->getX() + $radiusH * cos($radians);
$tmpY = $centrePoint->getY() + $radiusV * sin($radians);
$tmpY = $centrePoint->getY() - $radiusV * sin($radians);
//$tmpPoint = new PointDouble();
$tmpPoint = $this->calc3DPos($tmpX,$tmpY,$zPos);
return $this->imageReflection;
$this->imageReflection= $value;
* Converts the Color parameter to a darker color.<br>
* The HowMuch parameter indicates the quantity of dark increment.
* It is used by Bar Series and Pie Series to calculate the right color to
* draw Bar sides and Pie 3D zones.
static public function applyDark($c, $howMuch) {
return $c->applyDark($howMuch);
$rH = 50; // Reflection height
$tr = 30; // Starting transparency
$div = 1; // Size of the divider line
$li = imagecreatetruecolor($w, 1);
$bgc = imagecolorallocate($li, 255, 255, 255); // Background color
imagefilledrectangle($li, 0, 0, $w, 1, $bgc);
$bg = imagecreatetruecolor($w, $rH);
$wh = imagecolorallocate($im,255,255,255);
$im = imagerotate($im, -180, $wh);
imagecopyresampled($bg, $im, 0, 0, 0, 0, $w, $h, $w, $h);
$bg = imagecreatetruecolor($w, $rH);
for ($x = 0; $x < $w; $x++) {
imagecopy($bg, $im, $x, 0, $w-$x, 0, 1, $rH);
for($i=0; $i<=$rH; $i++){
imagecopymerge($im, $li, 0, $i, 0, 0, $w, 1, $tr);
imagecopymerge($im, $li, 0, 0, 0, 0, $w, $div, 100); // Divider
* Returns the height, in pixels, of the Chart Panel.<br>
* It should be used when using Canvas methods to draw relative to the
* <b>Note:</B> You should <b>NOT</b> use TChart.Height.
return 1050; // TODO GET SCREEN WIDTH AND HEIGHT
* Returns the width, in pixels, of the Chart Panel.
return 1680; // TODO GET SCREEN WIDTH AND HEIGHT
|