Rev 61 | Blame | Compare with Previous | Last modification | View Log | RSS feed
<?php/** This work is hereby released into the Public Domain.* To view a copy of the public domain dedication,* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.**/require_once dirname(__FILE__)."/../Driver.class.php";/*** Draw your objects** @package Artichow*/class awGDDriver extends Driver {/*** A GD resource** @var $resource*/public $resource;public function __construct() {parent::__construct();$this->driverString = 'gd';}public function init(awImage $image) {if($this->resource === NULL) {$this->setImageSize($image->width, $image->height);// Create image$this->resource = imagecreatetruecolor($this->imageWidth, $this->imageHeight);if(!$this->resource) {awImage::drawError("Class Image: Unable to create a graph.");}imagealphablending($this->resource, TRUE);// Antialiasing is now handled by the Driver object$this->setAntiAliasing($image->getAntiAliasing());// Original color$this->filledRectangle(new awWhite,new awLine(new awPoint(0, 0),new awPoint($this->imageWidth, $this->imageHeight)));$shadow = $image->shadow;if($shadow !== NULL) {$shadow = $shadow->getSpace();$p1 = new awPoint($shadow->left, $shadow->top);$p2 = new awPoint($this->imageWidth - $shadow->right - 1, $this->imageHeight - $shadow->bottom - 1);// Draw image background$this->filledRectangle($image->getBackground(), new awLine($p1, $p2));// Draw image border$image->border->rectangle($this, $p1, $p2);}}}public function initFromFile(awFileImage $fileImage, $file) {$image = @getimagesize((string)$file);if($image and in_array($image[2], array(2, 3))) {$fileImage->setSize($image[0], $image[1]);switch($image[2]) {case 2 :$this->resource = imagecreatefromjpeg($file);break;case 3 :$this->resource = imagecreatefrompng($file);break;}$this->setImageSize($fileImage->width, $fileImage->height);} else {awImage::drawError("Class FileImage: Artichow does not support the format of this image (must be in PNG or JPEG)");}}public function setImageSize($width, $height) {$this->imageWidth = $width;$this->imageHeight = $height;}public function setPosition($x, $y) {// Calculate absolute position$this->x = round($x * $this->imageWidth - $this->w / 2);$this->y = round($y * $this->imageHeight - $this->h / 2);}public function setAbsPosition($x, $y) {$this->x = $x;$this->y = $y;}public function movePosition($x, $y) {$this->x += (int)$x;$this->y += (int)$y;}public function setSize($w, $h) {// Calcul absolute size$this->w = round($w * $this->imageWidth);$this->h = round($h * $this->imageHeight);return $this->getSize();}public function setAbsSize($w, $h) {$this->w = $w;$this->h = $h;return $this->getSize();}public function getSize() {return array($this->w, $this->h);}public function setAntiAliasing($bool) {if(function_exists('imageantialias')) {imageantialias($this->resource, (bool)$bool);$this->antiAliasing = (bool)$bool;} else {awImage::drawErrorFile('missing-anti-aliasing');}}public function getColor(awColor $color) {if($color->alpha === 0 or function_exists('imagecolorallocatealpha') === FALSE) {$gdColor = imagecolorallocate($this->resource, $color->red, $color->green, $color->blue);} else {$gdColor = imagecolorallocatealpha($this->resource, $color->red, $color->green, $color->blue, $color->alpha);}return $gdColor;}public function copyImage(awImage $image, awPoint $p1, awPoint $p2) {list($x1, $y1) = $p1->getLocation();list($x2, $y2) = $p2->getLocation();$driver = $image->getDriver();imagecopy($this->resource, $driver->resource, $this->x + $x1, $this->y + $y1, 0, 0, $x2 - $x1, $y2 - $y1);}public function copyResizeImage(awImage $image, awPoint $d1, awPoint $d2, awPoint $s1, awPoint $s2, $resample = TRUE) {if($resample) {$function = 'imagecopyresampled';} else {$function = 'imagecopyresized';}$driver = $image->getDriver();$function($this->resource,$driver->resource,$this->x + $d1->x, $this->y + $d1->y,$s1->x, $s1->y,$d2->x - $d1->x, $d2->y - $d1->y,$s2->x - $s1->x, $s2->y - $s1->y);}public function string(awText $text, awPoint $point, $width = NULL) {$font = $text->getFont();// Can we deal with that font?if($this->isCompatibleWithFont($font) === FALSE) {awImage::drawError('Class GDDriver: Incompatible font type (\''.get_class($font).'\')');}// Check which FontDriver to useif($font instanceof awPHPFont) {$fontDriver = $this->phpFontDriver;} else {$fontDriver = $this->fileFontDriver;}if($text->getBackground() !== NULL or $text->border->visible()) {list($left, $right, $top, $bottom) = $text->getPadding();$textWidth = $fontDriver->getTextWidth($text, $this);$textHeight = $fontDriver->getTextHeight($text, $this);$x1 = floor($point->x - $left);$y1 = floor($point->y - $top);$x2 = $x1 + $textWidth + $left + $right;$y2 = $y1 + $textHeight + $top + $bottom;$this->filledRectangle($text->getBackground(),awLine::build($x1, $y1, $x2, $y2));$text->border->rectangle($this,new awPoint($x1 - 1, $y1 - 1),new awPoint($x2 + 1, $y2 + 1));}$fontDriver->string($this, $text, $point, $width);}public function point(awColor $color, awPoint $p) {if($p->isHidden() === FALSE) {$rgb = $this->getColor($color);imagesetpixel($this->resource, $this->x + round($p->x), $this->y + round($p->y), $rgb);}}public function line(awColor $color, awLine $line) {if($line->thickness > 0 and $line->isHidden() === FALSE) {$rgb = $this->getColor($color);$thickness = $line->thickness;list($p1, $p2) = $line->getLocation();$this->startThickness($thickness);switch($line->getStyle()) {case awLine::SOLID :imageline($this->resource, $this->x + round($p1->x), $this->y + round($p1->y), $this->x + round($p2->x), $this->y + round($p2->y), $rgb);break;case awLine::DOTTED :$size = sqrt(pow($p2->y - $p1->y, 2) + pow($p2->x - $p1->x, 2));$cos = ($p2->x - $p1->x) / $size;$sin = ($p2->y - $p1->y) / $size;for($i = 0; $i <= $size; $i += 2) {$p = new awPoint(round($i * $cos + $p1->x),round($i * $sin + $p1->y));$this->point($color, $p);}break;case awLine::DASHED :$width = $p2->x - $p1->x;$height = $p2->y - $p1->y;$size = sqrt(pow($height, 2) + pow($width, 2));if($size == 0) {return;}$cos = $width / $size;$sin = $height / $size;$functionX = ($width > 0) ? 'min' : 'max';$functionY = ($height > 0) ? 'min' : 'max';for($i = 0; $i <= $size; $i += 6) {$t1 = new awPoint(round($i * $cos + $p1->x),round($i * $sin + $p1->y));$t2 = new awPoint(round($functionX(($i + 3) * $cos, $width) + $p1->x),round($functionY(($i + 3) * $sin, $height) + $p1->y));$this->line($color, new awLine($t1, $t2));}break;}$this->stopThickness($thickness);}}public function arc(awColor $color, awPoint $center, $width, $height, $from, $to) {imagefilledarc($this->resource,$this->x + $center->x, $this->y + $center->y,$width, $height,$from, $to,$this->getColor($color),IMG_ARC_EDGED | IMG_ARC_NOFILL);}public function filledArc(awColor $color, awPoint $center, $width, $height, $from, $to) {imagefilledarc($this->resource,$this->x + $center->x, $this->y + $center->y,$width, $height,$from, $to,$this->getColor($color),IMG_ARC_PIE);}public function ellipse(awColor $color, awPoint $center, $width, $height) {list($x, $y) = $center->getLocation();$rgb = $this->getColor($color);imageellipse($this->resource,$this->x + $x,$this->y + $y,$width,$height,$rgb);}public function filledEllipse($background, awPoint $center, $width, $height) {if($background instanceof awColor) {list($x, $y) = $center->getLocation();$rgb = $this->getColor($background);imagefilledellipse($this->resource,$this->x + $x,$this->y + $y,$width,$height,$rgb);} else if($background instanceof awGradient) {list($x, $y) = $center->getLocation();$x1 = $x - round($width / 2);$y1 = $y - round($height / 2);$x2 = $x1 + $width;$y2 = $y1 + $height;$gradientDriver = new awGDGradientDriver($this);$gradientDriver->filledEllipse($background,$x1, $y1,$x2, $y2);}}public function rectangle(awColor $color, awLine $line) {list($p1, $p2) = $line->getLocation();switch($line->getStyle()) {case awLine::SOLID :$thickness = $line->getThickness();$this->startThickness($thickness);$rgb = $this->getColor($color);imagerectangle($this->resource, $this->x + $p1->x, $this->y + $p1->y, $this->x + $p2->x, $this->y + $p2->y, $rgb);$this->stopThickness($thickness);break;default :$side = clone $line;// Top side$side->setLocation(new awPoint($p1->x, $p1->y),new awPoint($p2->x, $p1->y));$this->line($color, $side);// Right side$side->setLocation(new awPoint($p2->x, $p1->y),new awPoint($p2->x, $p2->y));$this->line($color, $side);// Bottom side$side->setLocation(new awPoint($p1->x, $p2->y),new awPoint($p2->x, $p2->y));$this->line($color, $side);// Left side$side->setLocation(new awPoint($p1->x, $p1->y),new awPoint($p1->x, $p2->y));$this->line($color, $side);break;}}public function filledRectangle($background, awLine $line) {$p1 = $line->p1;$p2 = $line->p2;if($background instanceof awColor) {$rgb = $this->getColor($background);imagefilledrectangle($this->resource, $this->x + $p1->x, $this->y + $p1->y, $this->x + $p2->x, $this->y + $p2->y, $rgb);} else if($background instanceof awGradient) {$gradientDriver = new awGDGradientDriver($this);$gradientDriver->filledRectangle($background, $p1, $p2);}}public function polygon(awColor $color, awPolygon $polygon) {switch($polygon->getStyle()) {case awPolygon::SOLID :$thickness = $polygon->getThickness();$this->startThickness($thickness);$points = $this->getPolygonPoints($polygon);$rgb = $this->getColor($color);imagepolygon($this->resource, $points, $polygon->count(), $rgb);$this->stopThickness($thickness);break;default :if($polygon->count() > 1) {$prev = $polygon->get(0);$line = new awLine;$line->setStyle($polygon->getStyle());$line->setThickness($polygon->getThickness());for($i = 1; $i < $polygon->count(); $i++) {$current = $polygon->get($i);$line->setLocation($prev, $current);$this->line($color, $line);$prev = $current;}// Close the polygon$line->setLocation($prev, $polygon->get(0));$this->line($color, $line);}}}public function filledPolygon($background, awPolygon $polygon) {if($background instanceof awColor) {$points = $this->getPolygonPoints($polygon);$rgb = $this->getColor($background);imagefilledpolygon($this->resource, $points, $polygon->count(), $rgb);} else if($background instanceof awGradient) {$gradientDriver = new awGDGradientDriver($this);$gradientDriver->filledPolygon($background, $polygon);}}public function send(awImage $image) {$this->drawImage($image);}public function get(awImage $image) {return $this->drawImage($image, TRUE, FALSE);}public function getTextWidth(awText $text) {$font = $text->getFont();if($font instanceof awPHPFont) {$fontDriver = $this->phpFontDriver;} else {$fontDriver = $this->fileFontDriver;}return $fontDriver->getTextWidth($text, $this);}public function getTextHeight(awText $text) {$font = $text->getFont();if($font instanceof awPHPFont) {$fontDriver = $this->phpFontDriver;} else {$fontDriver = $this->fileFontDriver;}return $fontDriver->getTextHeight($text, $this);}protected function isCompatibleWithFont(awFont $font) {if($font instanceof awFDBFont) {return FALSE;} else {return TRUE;}}private function drawImage(awImage $image, $return = FALSE, $header = TRUE) {$format = $image->getFormatString();// Test if format is availableif((imagetypes() & $image->getFormat()) === FALSE) {awImage::drawError("Class Image: Format '".$format."' is not available on your system. Check that your PHP has been compiled with the good libraries.");}// Get some infos about this imageswitch($format) {case 'jpeg' :$function = 'imagejpeg';break;case 'png' :$function = 'imagepng';break;case 'gif' :$function = 'imagegif';break;}// Send headers to the browserif($header === TRUE) {$image->sendHeaders();}if($return) {ob_start();}$function($this->resource);if($return) {return ob_get_clean();}}private function getPolygonPoints(awPolygon $polygon) {$points = array();foreach($polygon->all() as $point) {$points[] = $point->x + $this->x;$points[] = $point->y + $this->y;}return $points;}private function startThickness($thickness) {if($thickness > 1) {// Beurk :'(if($this->antiAliasing and function_exists('imageantialias')) {imageantialias($this->resource, FALSE);}imagesetthickness($this->resource, $thickness);}}private function stopThickness($thickness) {if($thickness > 1) {if($this->antiAliasing and function_exists('imageantialias')) {imageantialias($this->resource, TRUE);}imagesetthickness($this->resource, 1);}}}registerClass('GDDriver');/*** To your gradients** @package Artichow*/class awGDGradientDriver {/*** A driver** @var awGDDriver*/protected $driver;/*** Build your GDGradientDriver** @var awGDDriver $driver*/public function __construct(awGDDriver $driver) {$this->driver = $driver;}public function drawFilledFlatTriangle(awGradient $gradient, awPoint $a, awPoint $b, awPoint $c) {if($gradient->angle !== 0) {awImage::drawError("Class GDGradientDriver: Flat triangles can only be used with 0 degree gradients.");}// Look for right-angled triangleif($a->x !== $b->x and $b->x !== $c->x) {awImage::drawError("Class GDGradientDriver: Not right-angled flat triangles are not supported yet.");}if($a->x === $b->x) {$d = $a;$e = $c;} else {$d = $c;$e = $a;}$this->init($gradient, $b->y - $d->y);for($i = $c->y + 1; $i < $b->y; $i++) {$color = $this->color($i - $d->y);$pos = ($i - $d->y) / ($b->y - $d->y);$p1 = new awPoint($e->x, $i);$p2 = new awPoint(1 + floor($e->x - $pos * ($e->x - $d->x)), $i);$this->driver->filledRectangle($color, new awLine($p1, $p2));unset($color);}}protected function drawFilledTriangle(awGradient $gradient, awPolygon $polygon) {if($gradient->angle === 0) {$this->drawFilledTriangleVertically($gradient, $polygon);} elseif($gradient->angle === 90) {$this->drawFilledTriangleHorizontally($gradient, $polygon);}}private function drawFilledTriangleVertically(awGradient $gradient, awPolygon $polygon) {list($yMin, $yMax) = $polygon->getBoxYRange();$this->init($gradient, $yMax - $yMin);// Get the triangle line we will draw our lines from$fromLine = NULL;$lines = $polygon->getLines();$count = count($lines);// Pick the side of the triangle going from the top// to the bottom of the surrounding boxfor($i = 0; $i < $count; $i++) {if($lines[$i]->isTopToBottom($polygon)) {list($fromLine) = array_splice($lines, $i, 1);break;}}// If for some reason the three points are aligned,// $fromLine will still be NULLif($fromLine === NULL) {return;}$fillLine = NULL;for($y = round($yMin); $y < round($yMax); $y++) {$fromX = $fromLine->getXFrom($y);$toX = array();foreach($lines as $line) {$xValue = $line->getXFrom($y);if(!is_null($xValue)) {$toX[] = $xValue;}}if(count($toX) === 1) {$fillLine = new Line(new Point($fromX, $y),new Point($toX[0], $y));} else {$line1 = new Line(new Point($fromX, $y),new Point($toX[0], $y));$line2 = new Line(new Point($fromX, $y),new Point($toX[1], $y));if($line1->getSize() < $line2->getSize()) {$fillLine = $line1;} else {$fillLine = $line2;}}if(!$fillLine->isPoint()) {$color = $this->color($y - $yMin);$this->driver->line($color, $fillLine);unset($color);}}}private function drawFilledTriangleHorizontally(awGradient $gradient, awPolygon $polygon) {list($xMin, $xMax) = $polygon->getBoxXRange();$this->init($gradient, $xMax - $xMin);// Get the triangle line we will draw our lines from$fromLine = NULL;$lines = $polygon->getLines();$count = count($lines);// Pick the side of the triangle going all the way// from the left side to the right side of the surrounding boxfor($i = 0; $i < $count; $i++) {if($lines[$i]->isLeftToRight($polygon)) {list($fromLine) = array_splice($lines, $i, 1);break;}}// If for some reason the three points are aligned,// $fromLine will still be NULLif($fromLine === NULL) {return;}$fillLine = NULL;for($x = round($xMin); $x < round($xMax); $x++) {$fromY = floor($fromLine->getYFrom($x));$toY = array();foreach($lines as $line) {$yValue = $line->getYFrom($x);if(!is_null($yValue)) {$toY[] = floor($yValue);}}if(count($toY) === 1) {$fillLine = new Line(new Point($x, $fromY),new Point($x, $toY[0]));} else {$line1 = new Line(new Point($x, $fromY),new Point($x, $toY[0]));$line2 = new Line(new Point($x, $fromY),new Point($x, $toY[1]));if($line1->getSize() < $line2->getSize()) {$fillLine = $line1;} else {$fillLine = $line2;}}$color = $this->color($x - $xMin);if($fillLine->isPoint()) {$this->driver->point($color, $fillLine->p1);} elseif($fillLine->getSize() >= 1) {$this->driver->line($color, $fillLine);}unset($color);}}public function filledRectangle(awGradient $gradient, awPoint $p1, awPoint $p2) {list($x1, $y1) = $p1->getLocation();list($x2, $y2) = $p2->getLocation();if($y1 < $y2) {$y1 ^= $y2 ^= $y1 ^= $y2;}if($x2 < $x1) {$x1 ^= $x2 ^= $x1 ^= $x2;}if($gradient instanceof awLinearGradient) {$this->rectangleLinearGradient($gradient, new awPoint($x1, $y1), new awPoint($x2, $y2));} else {awImage::drawError("Class GDGradientDriver: This gradient is not supported by rectangles.");}}public function filledPolygon(awGradient $gradient, awPolygon $polygon) {if($gradient instanceof awLinearGradient) {$this->polygonLinearGradient($gradient, $polygon);} else {awImage::drawError("Class GDGradientDriver: This gradient is not supported by polygons.");}}protected function rectangleLinearGradient(awLinearGradient $gradient, awPoint $p1, awPoint $p2) {list($x1, $y1) = $p1->getLocation();list($x2, $y2) = $p2->getLocation();if($y1 - $y2 > 0) {if($gradient->angle === 0) {$this->init($gradient, $y1 - $y2);for($i = $y2; $i <= $y1; $i++) {$color = $this->color($i - $y2);$p1 = new awPoint($x1, $i);$p2 = new awPoint($x2, $i);$this->driver->filledRectangle($color, new awLine($p1, $p2));unset($color);}} else if($gradient->angle === 90) {$this->init($gradient, $x2 - $x1);for($i = $x1; $i <= $x2; $i++) {$color = $this->color($i - $x1);$p1 = new awPoint($i, $y2);$p2 = new awPoint($i, $y1);$this->driver->filledRectangle($color, new awLine($p1, $p2));unset($color);}}}}public function filledEllipse(awGradient $gradient, $x1, $y1, $x2, $y2) {if($y1 < $y2) {$y1 ^= $y2 ^= $y1 ^= $y2;}if($x2 < $x1) {$x1 ^= $x2 ^= $x1 ^= $x2;}if($gradient instanceof awRadialGradient) {$this->ellipseRadialGradient($gradient, $x1, $y1, $x2, $y2);} else if($gradient instanceof awLinearGradient) {$this->ellipseLinearGradient($gradient, $x1, $y1, $x2, $y2);} else {awImage::drawError("Class GDGradientDriver: This gradient is not supported by ellipses.");}}protected function ellipseRadialGradient(awGradient $gradient, $x1, $y1, $x2, $y2) {if($y1 - $y2 > 0) {if($y1 - $y2 != $x2 - $x1) {awImage::drawError("Class GDGradientDriver: Radial gradients are only implemented on circle, not ellipses.");}$c = new awPoint($x1 + ($x2 - $x1) / 2, $y1 + ($y2 - $y1) / 2);$r = ($x2 - $x1) / 2;$ok = array();// Init gradient$this->init($gradient, $r);for($i = 0; $i <= $r; $i += 0.45) {$p = ceil((2 * M_PI * $i));if($p > 0) {$interval = 360 / $p;} else {$interval = 360;}$color = $this->color($i);for($j = 0; $j < 360; $j += $interval) {$rad = ($j / 360) * (2 * M_PI);$x = round($i * cos($rad));$y = round($i * sin($rad));$l = sqrt($x * $x + $y * $y);if($l <= $r) {if(array_key_exists((int)$x, $ok) === FALSE orarray_key_exists((int)$y, $ok[$x]) === FALSE) {// Print the point$this->driver->point($color, new awPoint($c->x + $x, $c->y + $y));$ok[(int)$x][(int)$y] = TRUE;}}}unset($color);}}}protected function ellipseLinearGradient(awGradient $gradient, $x1, $y1, $x2, $y2) {// Gauche->droite : 90°if($y1 - $y2 > 0) {if($y1 - $y2 != $x2 - $x1) {awImage::drawError("Class GDGradientDriver: Linear gradients are only implemented on circle, not ellipses.");}$r = ($x2 - $x1) / 2;// Init gradient$this->init($gradient, $x2 - $x1);for($i = -$r; $i <= $r; $i++) {$h = sin(acos($i / $r)) * $r;$color = $this->color($i + $r);if($gradient->angle === 90) {// Print the line$p1 = new awPoint($x1 + $i + $r,round(max($y2 + $r - $h + 1, $y2)));$p2 = new awPoint($x1 + $i + $r,round(min($y1 - $r + $h - 1, $y1)));} else {// Print the line$p1 = new awPoint(round(max($x1 + $r - $h + 1, $x1)),$y2 + $i + $r);$p2 = new awPoint(round(min($x2 - $r + $h - 1, $x2)),$y2 + $i + $r);}$this->driver->filledRectangle($color, new awLine($p1, $p2));unset($color);}}}protected function polygonLinearGradient(awLinearGradient $gradient, awPolygon $polygon) {$count = $polygon->count();if($count >= 4) {$left = $polygon->get(0);$right = $polygon->get($count - 1);if($gradient->angle === 0) {// Get polygon maximum and minimum$offset = $polygon->get(0);$max = $min = $offset->y;for($i = 1; $i < $count - 1; $i++) {$offset = $polygon->get($i);$max = max($max, $offset->y);$min = min($min, $offset->y);}$this->init($gradient, $max - $min);$prev = $polygon->get(1);$sum = 0;for($i = 2; $i < $count - 1; $i++) {$current = $polygon->get($i);$interval = 1;if($i !== $count - 2) {$current->x -= $interval;}if($current->x - $prev->x > 0) {// Draw rectangle$x1 = $prev->x;$x2 = $current->x;$y1 = max($prev->y, $current->y);$y2 = $left->y;$gradient = new awLinearGradient($this->color($max - $min - ($y2 - $y1)),$this->color($max - $min),0);if($y1 > $y2) {$y2 = $y1;}$this->driver->filledRectangle($gradient,awLine::build($x1, $y1, $x2, $y2));$top = ($prev->y < $current->y) ? $current : $prev;$bottom = ($prev->y >= $current->y) ? $current : $prev;$gradient = new awLinearGradient($this->color($bottom->y - $min),$this->color($max - $min - ($y2 - $y1)),0);$gradientDriver = new awGDGradientDriver($this->driver);$gradientDriver->drawFilledFlatTriangle($gradient,new awPoint($prev->x, min($prev->y, $current->y)),$top,new awPoint($current->x, min($prev->y, $current->y)));unset($gradientDriver);$sum += $current->x - $prev->x;}$prev = $current;$prev->x += $interval;}} else if($gradient->angle === 90) {$width = $right->x - $left->x;$this->init($gradient, $width);$pos = 1;$next = $polygon->get($pos++);$this->next($polygon, $pos, $prev, $next);for($i = 0; $i <= $width; $i++) {$x = $left->x + $i;$y1 = round($prev->y + ($next->y - $prev->y) * (($i + $left->x - $prev->x) / ($next->x - $prev->x)));$y2 = $left->y;// Draw line$color = $this->color($i);// YaPB : PHP does not handle alpha on lines$this->driver->filledRectangle($color, awLine::build($x, $y1, $x, $y2));unset($color);// Jump to next pointif($next->x == $i + $left->x) {$this->next($polygon, $pos, $prev, $next);}}}} else if($count === 3) {$this->drawFilledTriangle($gradient,$polygon);}}private function next($polygon, &$pos, &$prev, &$next) {do {$prev = $next;$next = $polygon->get($pos++);}while($next->x - $prev->x == 0 and $pos < $polygon->count());}/*** Start colors** @var int*/private $r1, $g1, $b1, $a1;/*** Stop colors** @var int*/private $r2, $g2, $b2, $a2;/*** Gradient size in pixels** @var int*/private $size;private function init(awGradient $gradient, $size) {list($this->r1, $this->g1, $this->b1, $this->a1) = $gradient->from->rgba();list($this->r2, $this->g2, $this->b2, $this->a2) = $gradient->to->rgba();$this->size = $size;}private function color($pos) {return new awColor($this->getRed($pos),$this->getGreen($pos),$this->getBlue($pos),$this->getAlpha($pos));}private function getRed($pos) {if((float)$this->size !== 0.0) {return (int)round($this->r1 + ($pos / $this->size) * ($this->r2 - $this->r1));} else {return 0;}}private function getGreen($pos) {if((float)$this->size !== 0.0) {return (int)round($this->g1 + ($pos / $this->size) * ($this->g2 - $this->g1));} else {return 0;}}private function getBlue($pos) {if((float)$this->size !== 0.0) {return (int)round($this->b1 + ($pos / $this->size) * ($this->b2 - $this->b1));} else {return 0;}}private function getAlpha($pos) {if((float)$this->size !== 0.0) {return (int)round(($this->a1 + ($pos / $this->size) * ($this->a2 - $this->a1)) / 127 * 100);} else {return 0;}}}registerClass('GDGradientDriver');/** Check for GD2*/if(function_exists('imagecreatetruecolor') === FALSE) {awImage::drawErrorFile('missing-gd2');}?>