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; } elseif ($bool == true) { 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 use if ($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 ); } elseif ($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); } elseif ($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); } elseif ($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 available if ((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 image switch($format) { case 'jpeg' : $function = 'imagejpeg'; break; case 'png' : $function = 'imagepng'; break; case 'gif' : $function = 'imagegif'; break; } // Send headers to the browser if ($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 triangle if ($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 box for ($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 NULL if ($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 box for ($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 NULL if ($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); } } elseif ($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); } elseif ($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 or array_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; } } elseif ($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 point if ($next->x == $i + $left->x) { $this->next($polygon, $pos, $prev, $next); } } } } elseif ($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'); }