Source for file gd.class.php
Documentation is available at gd.class.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";  
 * @package linea21.externals  
        $this->driverString =  'gd';  
            // Antialiasing is now handled by the Driver object  
                    new awPoint($this->imageWidth, $this->imageHeight)  
            $shadow =  $image->shadow;  
                $shadow =  $shadow->getSpace();  
                $p1 =  new awPoint($shadow->left, $shadow->top);  
                $p2 =  new awPoint($this->imageWidth -  $shadow->right -  1, $this->imageHeight -  $shadow->bottom -  1);  
                $image->border->rectangle($this, $p1, $p2);  
        if($image and in_array($image[2], array(2, 3))) {  
            $fileImage->setSize($image[0], $image[1]);  
            awImage::drawError("Class FileImage: Artichow does not support the format of this image (must be in PNG or JPEG)");  
        $this->imageWidth =  $width;  
        $this->imageHeight =  $height;  
        // Calculate absolute position  
        $this->x =  round($x *  $this->imageWidth -  $this->w /  2);  
        $this->y =  round($y *  $this->imageHeight -  $this->h /  2);  
        $this->w =  round($w *  $this->imageWidth);  
        $this->h =  round($h *  $this->imageHeight);  
        return array($this->w, $this->h);  
            imageantialias($this->resource, (bool) $bool);  
            $this->antiAliasing = (bool) $bool;  
        } elseif($bool ==  true) {  
        if($color->alpha ===  0 or function_exists('imagecolorallocatealpha') ===  FALSE) {  
        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);  
            $function =  'imagecopyresampled';  
            $function =  'imagecopyresized';  
        $driver =  $image->getDriver();  
            $this->x +  $d1->x, $this->y +  $d1->y,  
            $d2->x -  $d1->x, $d2->y -  $d1->y,  
            $s2->x -  $s1->x, $s2->y -  $s1->y  
     function string(&$text, $point, $width =  NULL) {  
        $font =  $text->getFont();  
        // Can we deal with that font?  
        // Check which FontDriver to use  
        if(is_a($font, 'awPHPFont')) {  
            $fontDriver =  $this->phpFontDriver;  
            $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;  
            $text->border->rectangle(  
        $fontDriver->string($this, $text, $point, $width);  
     function point($color, $p) {  
        if($p->isHidden() ===  FALSE) {  
     function line($color, $line) {  
        if($line->thickness >  0 and $line->isHidden() ===  FALSE) {  
            $thickness =  $line->thickness;  
            list ($p1, $p2) =  $line->getLocation(); 
            $this->startThickness($thickness);  
            switch($line->getStyle()) {  
                    $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) {  
                            round($i *  $cos +  $p1->x),  
                            round($i *  $sin +  $p1->y)  
                        $this->point($color, $p);  
                    $width =  $p2->x -  $p1->x;  
                    $height =  $p2->y -  $p1->y;  
                    $functionX =  ($width  >  0) ?  'min' :  'max';  
                    $functionY =  ($height >  0) ?  'min' :  'max';  
                    for($i =  0; $i <=  $size; $i +=  6) {  
                            round($i *  $cos +  $p1->x),  
                            round($i *  $sin +  $p1->y)  
                            round($functionX(($i +  3) *  $cos, $width) +  $p1->x),  
                            round($functionY(($i +  3) *  $sin, $height) +  $p1->y)  
            $this->stopThickness($thickness);  
     function arc($color, $center, $width, $height, $from, $to) {  
            $this->x +  $center->x, $this->y +  $center->y,  
            IMG_ARC_EDGED |  IMG_ARC_NOFILL  
     function filledArc($color, $center, $width, $height, $from, $to) {  
            $this->x +  $center->x, $this->y +  $center->y,  
     function ellipse($color, $center, $width, $height) {  
        list ($x, $y) =  $center->getLocation(); 
        if(is_a($background, 'awColor')) {  
            list ($x, $y) =  $center->getLocation(); 
        } else if(is_a($background, 'awGradient')) {  
            list ($x, $y) =  $center->getLocation(); 
            $x1 =  $x -  round($width /  2);  
            $y1 =  $y -  round($height /  2);  
            $gradientDriver->filledEllipse(  
        list ($p1, $p2) =  $line->getLocation(); 
        switch($line->getStyle()) {  
                $thickness =  $line->getThickness();  
                $this->startThickness($thickness);  
                imagerectangle($this->resource, $this->x +  $p1->x, $this->y +  $p1->y, $this->x +  $p2->x, $this->y +  $p2->y, $rgb);  
                $this->stopThickness($thickness);  
                $side =  new Line($p1, $p2);  
                $this->line($color, $side);  
                $this->line($color, $side);  
                $this->line($color, $side);  
                $this->line($color, $side);  
        if(is_a($background, 'awColor')) {  
        } else if(is_a($background, 'awGradient')) {  
            $gradientDriver->filledRectangle($background, $p1, $p2);  
     function polygon($color, &$polygon) {  
        switch($polygon->getStyle()) {  
                $thickness =  $polygon->getThickness();  
                $this->startThickness($thickness);  
                $points =  $this->getPolygonPoints($polygon);  
                $this->stopThickness($thickness);  
                if($polygon->count() >  1) {  
                    $prev =  $polygon->get(0);  
                    $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);  
                    $line->setLocation($prev, $polygon->get(0));  
                    $this->line($color, $line);  
        if(is_a($background, 'awColor')) {  
            $points =  $this->getPolygonPoints($polygon);  
        } else if(is_a($background, 'awGradient')) {  
            $gradientDriver->filledPolygon($background, $polygon);  
        $this->drawImage($image);  
        return $this->drawImage($image, TRUE, FALSE);  
        $font =  $text->getFont();  
        if(is_a($font, 'awPHPFont')) {  
            $fontDriver =  $this->phpFontDriver;  
            $fontDriver =  $this->fileFontDriver;  
        return $fontDriver->getTextWidth($text, $this);  
        $font =  $text->getFont();  
        if(is_a($font, 'awPHPFont')) {  
            $fontDriver =  $this->phpFontDriver;  
            $fontDriver =  $this->fileFontDriver;  
        return $fontDriver->getTextHeight($text, $this);  
        if(is_a($font, 'awFDBFont')) {  
     function drawImage(&$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  
        // Send headers to the browser  
     function getPolygonPoints(&$polygon) {  
        foreach($polygon->all() as $point) {  
            $points[] =  $point->x +  $this->x;  
            $points[] =  $point->y +  $this->y;  
     function startThickness($thickness) {  
     function stopThickness($thickness) {  
 * @package linea21.externals  
     * Build your GDGradientDriver  
     function awGDGradientDriver($driver) {  
        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.");  
        $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);  
            $p2 =  new awPoint(1 +  floor($e->x -  $pos *  ($e->x -  $d->x)), $i);  
        if($gradient->angle ===  0) {  
            $this->drawFilledTriangleVertically($gradient, $polygon);  
        } elseif($gradient->angle ===  90) {  
            $this->drawFilledTriangleHorizontally($gradient, $polygon);  
     function drawFilledTriangleVertically($gradient, &$polygon) {  
        list ($yMin, $yMax) =  $polygon->getBoxYRange(); 
        $this->init($gradient, $yMax -  $yMin);  
        // Get the triangle line we will draw our lines from  
        $lines =  $polygon->getLines();  
        // 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)) {  
        // If for some reason the three points are aligned,  
        // $fromLine will still be NULL  
            $fromX =  $fromLine->getXFrom($y);  
            foreach($lines as $line) {  
                $xValue =  $line->getXFrom($y);  
                if($line1->getSize() <  $line2->getSize()) {  
            if(!$fillLine->isPoint()) {  
                $color =  $this->color($y -  $yMin);  
     function drawFilledTriangleHorizontally($gradient, &$polygon) {  
        list ($xMin, $xMax) =  $polygon->getBoxXRange(); 
        $this->init($gradient, $xMax -  $xMin);  
        // Get the triangle line we will draw our lines from  
        $lines =  $polygon->getLines();  
        // 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)) {  
        // If for some reason the three points are aligned,  
        // $fromLine will still be NULL  
            $fromY =  floor($fromLine->getYFrom($x));  
            foreach($lines as $line) {  
                $yValue =  $line->getYFrom($x);  
                if($line1->getSize() <  $line2->getSize()) {  
            $color =  $this->color($x -  $xMin);  
            if($fillLine->isPoint()) {  
            } elseif($fillLine->getSize() >=  1) {  
        list ($x1, $y1) =  $p1->getLocation(); 
        list ($x2, $y2) =  $p2->getLocation(); 
            $y1 ^=  $y2 ^=  $y1 ^=  $y2;  
            $x1 ^=  $x2 ^=  $x1 ^=  $x2;  
        if(is_a($gradient, 'awLinearGradient')) {  
            awImage::drawError("Class GDGradientDriver: This gradient is not supported by rectangles.");  
        if(is_a($gradient, 'awLinearGradient')) {  
            awImage::drawError("Class GDGradientDriver: This gradient is not supported by polygons.");  
        list ($x1, $y1) =  $p1->getLocation(); 
        list ($x2, $y2) =  $p2->getLocation(); 
            if($gradient->angle ===  0) {  
                $this->init($gradient, $y1 -  $y2);  
                for($i =  $y2; $i <=  $y1; $i++ ) {  
                    $color =  $this->color($i -  $y2);  
            } else if($gradient->angle ===  90) {  
                $this->init($gradient, $x2 -  $x1);  
                for($i =  $x1; $i <=  $x2; $i++ ) {  
                    $color =  $this->color($i -  $x1);  
            $y1 ^=  $y2 ^=  $y1 ^=  $y2;  
            $x1 ^=  $x2 ^=  $x1 ^=  $x2;  
        if(is_a($gradient, 'awRadialGradient')) {  
        } else if(is_a($gradient, 'awLinearGradient')) {  
            awImage::drawError("Class GDGradientDriver: This gradient is not supported by ellipses.");  
            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);   
            $this->init($gradient, $r);  
            for($i =  0; $i <=  $r; $i +=  0.45) {  
                $p =  ceil((2 *  M_PI *  $i));  
                $color =  $this->color($i);  
                for($j =  0; $j <  360; $j +=  $interval) {  
                    $rad =  ($j /  360) *  (2 *  M_PI);  
                    $l =  sqrt($x *  $x +  $y *  $y);  
                            $ok[(int) $x][(int) $y] =  TRUE;  
            if($y1 -  $y2 !=  $x2 -  $x1) {  
                awImage::drawError("Class GDGradientDriver: Linear gradients are only implemented on circle, not ellipses.");  
            $this->init($gradient, $x2 -  $x1);  
            for($i = - $r; $i <=  $r; $i++ ) {  
                $color =  $this->color($i +  $r);  
                if($gradient->angle ===  90) {  
        $count =  $polygon->count();  
            $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);  
                for($i =  2; $i <  $count -  1; $i++ ) {  
                    $current =  $polygon->get($i);  
                        $current->x -=  $interval;  
                    if($current->x -  $prev->x >  0) {  
                        $y1 =  max($prev->y, $current->y);  
                            $this->color($max -  $min -  ($y2 -  $y1)),  
                            $this->color($max -  $min),  
                        $top =  ($prev->y <  $current->y) ?  $current :  $prev;  
                        $bottom =  ($prev->y >=  $current->y) ?  $current :  $prev;  
                            $this->color($bottom->y -  $min),  
                            $this->color($max -  $min -  ($y2 -  $y1)),  
                        $gradientDriver->drawFilledFlatTriangle(  
                            new awPoint($prev->x, min($prev->y, $current->y)),  
                            new awPoint($current->x, min($prev->y, $current->y))  
                        $sum +=  $current->x -  $prev->x;  
            } else if($gradient->angle ===  90) {  
                $width =  $right->x -  $left->x;  
                $this->init($gradient, $width);  
                $next =  $polygon->get($pos++ );  
                $this->next($polygon, $pos, $prev, $next);  
                for($i =  0; $i <=  $width; $i++ ) {  
                    $y1 =  round($prev->y +  ($next->y -  $prev->y) *  (($i +  $left->x -  $prev->x) /  ($next->x -  $prev->x)));  
                    $color =  $this->color($i);  
                    // YaPB : PHP does not handle alpha on lines  
                    if($next->x ==  $i +  $left->x) {  
                        $this->next($polygon, $pos, $prev, $next);  
        } else if($count ===  3) {  
     function next($polygon, &$pos, &$prev, &$next) {  
            $next =  $polygon->get($pos++ );  
        while($next->x -  $prev->x ==  0 and $pos <  $polygon->count());  
     * Gradient size in pixels  
     function init($gradient, $size) {  
            $this->r1, $this->g1, $this->b1, $this->a1  
        ) =  $gradient->from->rgba();  
            $this->r2, $this->g2, $this->b2, $this->a2  
        ) =  $gradient->to->rgba();  
        if((float) $this->size !==  0.0) {  
            return (int) round($this->r1 +  ($pos /  $this->size) *  ($this->r2 -  $this->r1));  
     function getGreen($pos) {  
        if((float) $this->size !==  0.0) {  
            return (int) round($this->g1 +  ($pos /  $this->size) *  ($this->g2 -  $this->g1));  
        if((float) $this->size !==  0.0) {  
            return (int) round($this->b1 +  ($pos /  $this->size) *  ($this->b2 -  $this->b1));  
     function getAlpha($pos) {  
        if((float) $this->size !==  0.0) {  
            return (int) round(($this->a1 +  ($pos /  $this->size) *  ($this->a2 -  $this->a1)) /  127 *  100);  
 
 
        
       |