linea21-externals
[ class tree: linea21-externals ] [ index: linea21-externals ] [ all elements ]

Source for file gd.class.php

Documentation is available at gd.class.php

  1. <?php
  2. /*
  3.  * This work is hereby released into the Public Domain.
  4.  * To view a copy of the public domain dedication,
  5.  * visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
  6.  * Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
  7.  *
  8.  */
  9.  
  10. require_once dirname(__FILE__)."/../Driver.class.php";
  11.  
  12. /**
  13.  * Draw your objects
  14.  *
  15.  * @package linea21.externals
  16.  * @subpackage artichow
  17.  */
  18.  
  19. class awGDDriver extends Driver {
  20.     
  21.     /**
  22.      * A GD resource
  23.      *
  24.      * @var $resource 
  25.      */
  26.     var $resource;
  27.     
  28.      function awGDDriver({
  29.         parent::Driver();
  30.         
  31.         $this->driverString 'gd';
  32.     }
  33.  
  34.      function init(&$image{
  35.         
  36.         if($this->resource === NULL{
  37.             
  38.             $this->setImageSize($image->width$image->height);
  39.             
  40.             // Create image
  41.             $this->resource = imagecreatetruecolor($this->imageWidth$this->imageHeight);
  42.             if(!$this->resource{
  43.                 awImage::drawError("Class Image: Unable to create a graph.");
  44.             }
  45.             
  46.             imagealphablending($this->resourceTRUE);
  47.             
  48.             // Antialiasing is now handled by the Driver object
  49.             $this->setAntiAliasing($image->getAntiAliasing());
  50.             
  51.             // Original color
  52.             $this->filledRectangle(
  53.                 new awWhite,
  54.                 new awLine(
  55.                     new awPoint(00),
  56.                     new awPoint($this->imageWidth$this->imageHeight)
  57.                 )
  58.             );
  59.             
  60.             $shadow $image->shadow;
  61.             if($shadow !== NULL{
  62.                 $shadow $shadow->getSpace();
  63.                 $p1 new awPoint($shadow->left$shadow->top);
  64.                 $p2 new awPoint($this->imageWidth $shadow->right 1$this->imageHeight $shadow->bottom 1);
  65.                 
  66.                 
  67.                 // Draw image background
  68.                 $this->filledRectangle($image->getBackground()new awLine($p1$p2));
  69.                 
  70.                 // Draw image border
  71.                 $image->border->rectangle($this$p1$p2);
  72.             }
  73.             
  74.         }
  75.     }
  76.     
  77.      function initFromFile(&$fileImage$file{
  78.         
  79.         $image @getimagesize((string)$file);
  80.         
  81.         if($image and in_array($image[2]array(23))) {
  82.         
  83.             $fileImage->setSize($image[0]$image[1]);
  84.             
  85.             switch($image[2]{
  86.             
  87.                 case :
  88.                     $this->resource = imagecreatefromjpeg($file);
  89.                     break;
  90.             
  91.                 case :
  92.                     $this->resource = imagecreatefrompng($file);
  93.                     break;
  94.             
  95.             }
  96.  
  97.             $this->setImageSize($fileImage->width$fileImage->height);
  98.         else {
  99.             awImage::drawError("Class FileImage: Artichow does not support the format of this image (must be in PNG or JPEG)");
  100.         }
  101.     }
  102.     
  103.      function setImageSize($width$height{
  104.     
  105.         $this->imageWidth $width;
  106.         $this->imageHeight $height;
  107.     
  108.     }
  109.     
  110.      function setPosition($x$y{
  111.         
  112.         // Calculate absolute position
  113.         $this->round($x $this->imageWidth $this->2);
  114.         $this->round($y $this->imageHeight $this->2);
  115.     
  116.     }
  117.     
  118.      function setAbsPosition($x$y{
  119.         
  120.         $this->$x;
  121.         $this->$y;
  122.     
  123.     }
  124.     
  125.      function movePosition($x$y{
  126.  
  127.         $this->+= (int)$x;
  128.         $this->+= (int)$y;
  129.     
  130.     }
  131.     
  132.      function setSize($w$h{
  133.     
  134.         // Calcul absolute size
  135.         $this->round($w $this->imageWidth);
  136.         $this->round($h $this->imageHeight);
  137.         
  138.         return $this->getSize();
  139.     
  140.     }
  141.     
  142.      function setAbsSize($w$h{
  143.     
  144.         $this->$w;
  145.         $this->$h;
  146.         
  147.         return $this->getSize();
  148.     
  149.     }
  150.     
  151.      function getSize({
  152.         
  153.         return array($this->w$this->h);
  154.     
  155.     }
  156.     
  157.      function setAntiAliasing($bool{
  158.         
  159.         if(function_exists('imageantialias')) {
  160.             imageantialias($this->resource(bool)$bool);
  161.  
  162.             $this->antiAliasing = (bool)$bool;
  163.         elseif($bool == true{
  164.             awImage::drawErrorFile('missing-anti-aliasing');
  165.         }
  166.     }
  167.     
  168.      function getColor($color{
  169.  
  170.         if($color->alpha === or function_exists('imagecolorallocatealpha'=== FALSE{
  171.             $gdColor imagecolorallocate($this->resource$color->red$color->green$color->blue);
  172.         else {
  173.             $gdColor imagecolorallocatealpha($this->resource$color->red$color->green$color->blue$color->alpha);
  174.         }
  175.  
  176.         return $gdColor;
  177.     }
  178.     
  179.      function copyImage(&$image$p1$p2{
  180.     
  181.         list($x1$y1$p1->getLocation();
  182.         list($x2$y2$p2->getLocation();
  183.     
  184.         $driver $image->getDriver();
  185.         imagecopy($this->resource$driver->resource$this->$x1$this->$y100$x2 $x1$y2 $y1);
  186.     
  187.     }
  188.     
  189.      function copyResizeImage(&$image$d1$d2$s1$s2$resample TRUE{
  190.         
  191.         if($resample{
  192.             $function 'imagecopyresampled';
  193.         else {
  194.             $function 'imagecopyresized';
  195.         }
  196.         
  197.         $driver $image->getDriver();
  198.     
  199.         $function(
  200.             $this->resource,
  201.             $driver->resource,
  202.             $this->$d1->x$this->$d1->y,
  203.             $s1->x$s1->y,
  204.             $d2->$d1->x$d2->$d1->y,
  205.             $s2->$s1->x$s2->$s1->y
  206.         );
  207.     
  208.     }
  209.     
  210.      function string(&$text$point$width NULL{
  211.         
  212.         $font $text->getFont();
  213.         
  214.         // Can we deal with that font?
  215.         if($this->isCompatibleWithFont($font=== FALSE{
  216.             awImage::drawError('Class GDDriver: Incompatible font type (\''.get_class($font).'\')');
  217.         }
  218.         
  219.         // Check which FontDriver to use
  220.         if(is_a($font'awPHPFont')) {
  221.             $fontDriver $this->phpFontDriver;
  222.         else {
  223.             $fontDriver $this->fileFontDriver;
  224.         }
  225.         
  226.         if($text->getBackground(!== NULL or $text->border->visible()) {
  227.         
  228.             list($left$right$top$bottom$text->getPadding();
  229.  
  230.             $textWidth $fontDriver->getTextWidth($text$this);
  231.             $textHeight $fontDriver->getTextHeight($text$this);
  232.             
  233.             $x1 floor($point->$left);
  234.             $y1 floor($point->$top);
  235.             $x2 $x1 $textWidth $left $right;
  236.             $y2 $y1 $textHeight $top $bottom;
  237.             
  238.             $this->filledRectangle(
  239.                 $text->getBackground(),
  240.                 awLine::build($x1$y1$x2$y2)
  241.             );
  242.             
  243.             $text->border->rectangle(
  244.                 $this,
  245.                 new awPoint($x1 1$y1 1),
  246.                 new awPoint($x2 1$y2 1)
  247.             );
  248.             
  249.         }
  250.         
  251.         $fontDriver->string($this$text$point$width);
  252.         
  253.     }
  254.     
  255.      function point($color$p{
  256.     
  257.         if($p->isHidden(=== FALSE{
  258.             $rgb $this->getColor($color);
  259.             imagesetpixel($this->resource$this->round($p->x)$this->round($p->y)$rgb);
  260.         }
  261.     
  262.     }
  263.     
  264.      function line($color$line{
  265.     
  266.         if($line->thickness and $line->isHidden(=== FALSE{
  267.     
  268.             $rgb $this->getColor($color);
  269.             $thickness $line->thickness;
  270.             
  271.             list($p1$p2$line->getLocation();
  272.             
  273.             $this->startThickness($thickness);
  274.             
  275.             switch($line->getStyle()) {
  276.             
  277.                 case LINE_SOLID :
  278.                     imageline($this->resource$this->round($p1->x)$this->round($p1->y)$this->round($p2->x)$this->round($p2->y)$rgb);
  279.                     break;
  280.                     
  281.                 case LINE_DOTTED :
  282.                     $size sqrt(pow($p2->$p1->y2pow($p2->$p1->x2));
  283.                     $cos ($p2->$p1->x$size;
  284.                     $sin ($p2->$p1->y$size;
  285.                     for($i 0$i <= $size$i += 2{
  286.                         $p new awPoint(
  287.                             round($i $cos $p1->x),
  288.                             round($i $sin $p1->y)
  289.                         );
  290.                         $this->point($color$p);
  291.                     }
  292.                     break;
  293.                     
  294.                 case LINE_DASHED :
  295.                     $width $p2->$p1->x;
  296.                     $height $p2->$p1->y;
  297.                     $size sqrt(pow($height2pow($width2));
  298.                     
  299.                     if($size == 0{
  300.                         return;
  301.                     }
  302.                     
  303.                     $cos $width $size;
  304.                     $sin $height $size;
  305.                     
  306.                     $functionX ($width  0'min' 'max';
  307.                     $functionY ($height 0'min' 'max';
  308.                     
  309.                     for($i 0$i <= $size$i += 6{
  310.                         
  311.                         $t1 new awPoint(
  312.                             round($i $cos $p1->x),
  313.                             round($i $sin $p1->y)
  314.                         );
  315.                         
  316.                         $t2 new awPoint(
  317.                             round($functionX(($i 3$cos$width$p1->x),
  318.                             round($functionY(($i 3$sin$height$p1->y)
  319.                         );
  320.                         
  321.                         $this->line($colornew awLine($t1$t2));
  322.                         
  323.                     }
  324.                     break;
  325.             
  326.             }
  327.             
  328.             $this->stopThickness($thickness);
  329.             
  330.         }
  331.         
  332.     }
  333.     
  334.      function arc($color$center$width$height$from$to{
  335.     
  336.         imagefilledarc(
  337.             $this->resource,
  338.             $this->$center->x$this->$center->y,
  339.             $width$height,
  340.             $from$to,
  341.             $this->getColor($color),
  342.             IMG_ARC_EDGED IMG_ARC_NOFILL
  343.         );
  344.     
  345.     }
  346.     
  347.      function filledArc($color$center$width$height$from$to{
  348.     
  349.         imagefilledarc(
  350.             $this->resource,
  351.             $this->$center->x$this->$center->y,
  352.             $width$height,
  353.             $from$to,
  354.             $this->getColor($color),
  355.             IMG_ARC_PIE
  356.         );
  357.     
  358.     }
  359.     
  360.      function ellipse($color$center$width$height{
  361.     
  362.         list($x$y$center->getLocation();
  363.     
  364.         $rgb $this->getColor($color);
  365.         imageellipse(
  366.             $this->resource,
  367.             $this->$x,
  368.             $this->$y,
  369.             $width,
  370.             $height,
  371.             $rgb
  372.         );
  373.         
  374.     }
  375.     
  376.      function filledEllipse($background$center$width$height{
  377.     
  378.         if(is_a($background'awColor')) {
  379.     
  380.             list($x$y$center->getLocation();
  381.         
  382.             $rgb $this->getColor($background);
  383.             
  384.             imagefilledellipse(
  385.                 $this->resource,
  386.                 $this->$x,
  387.                 $this->$y,
  388.                 $width,
  389.                 $height,
  390.                 $rgb
  391.             );
  392.             
  393.         else if(is_a($background'awGradient')) {
  394.     
  395.             list($x$y$center->getLocation();
  396.             
  397.             $x1 $x round($width 2);
  398.             $y1 $y round($height 2);
  399.             $x2 $x1 $width;
  400.             $y2 $y1 $height;
  401.         
  402.             $gradientDriver new awGDGradientDriver($this);
  403.             $gradientDriver->filledEllipse(
  404.                 $background,
  405.                 $x1$y1,
  406.                 $x2$y2
  407.             );
  408.         
  409.         }
  410.         
  411.     }
  412.     
  413.      function rectangle($color$line{
  414.     
  415.         list($p1$p2$line->getLocation();
  416.         
  417.         switch($line->getStyle()) {
  418.         
  419.             case LINE_SOLID :
  420.                 $thickness $line->getThickness();
  421.                 $this->startThickness($thickness);
  422.                 $rgb $this->getColor($color);
  423.                 imagerectangle($this->resource$this->$p1->x$this->$p1->y$this->$p2->x$this->$p2->y$rgb);
  424.                 $this->stopThickness($thickness);
  425.                 break;
  426.             
  427.             default :
  428.                 
  429.                 
  430.                 $side new Line($p1$p2);
  431.                 
  432.                 
  433.                 // Top side
  434.                 $side->setLocation(
  435.                     new awPoint($p1->x$p1->y),
  436.                     new awPoint($p2->x$p1->y)
  437.                 );
  438.                 $this->line($color$side);
  439.                 
  440.                 // Right side
  441.                 $side->setLocation(
  442.                     new awPoint($p2->x$p1->y),
  443.                     new awPoint($p2->x$p2->y)
  444.                 );
  445.                 $this->line($color$side);
  446.                 
  447.                 // Bottom side
  448.                 $side->setLocation(
  449.                     new awPoint($p1->x$p2->y),
  450.                     new awPoint($p2->x$p2->y)
  451.                 );
  452.                 $this->line($color$side);
  453.                 
  454.                 // Left side
  455.                 $side->setLocation(
  456.                     new awPoint($p1->x$p1->y),
  457.                     new awPoint($p1->x$p2->y)
  458.                 );
  459.                 $this->line($color$side);
  460.             
  461.                 break;
  462.         
  463.         }
  464.     
  465.     }
  466.     
  467.      function filledRectangle($background$line{
  468.     
  469.         $p1 $line->p1;
  470.         $p2 $line->p2;
  471.     
  472.         if(is_a($background'awColor')) {
  473.             $rgb $this->getColor($background);
  474.             imagefilledrectangle($this->resource$this->$p1->x$this->$p1->y$this->$p2->x$this->$p2->y$rgb);
  475.         else if(is_a($background'awGradient')) {
  476.             $gradientDriver new awGDGradientDriver($this);
  477.             $gradientDriver->filledRectangle($background$p1$p2);
  478.         }
  479.     
  480.     }
  481.     
  482.      function polygon($color&$polygon{
  483.         
  484.         switch($polygon->getStyle()) {
  485.         
  486.             case POLYGON_SOLID :
  487.                 $thickness $polygon->getThickness();
  488.                 $this->startThickness($thickness);
  489.                 $points $this->getPolygonPoints($polygon);
  490.                 $rgb $this->getColor($color);
  491.                 imagepolygon($this->resource$points$polygon->count()$rgb);
  492.                 $this->stopThickness($thickness);
  493.                 break;
  494.                 
  495.             default :
  496.             
  497.                 if($polygon->count(1{
  498.                 
  499.                     $prev $polygon->get(0);
  500.                     
  501.                     $line new awLine;
  502.                     $line->setStyle($polygon->getStyle());
  503.                     $line->setThickness($polygon->getThickness());
  504.                     
  505.                     for($i 1$i $polygon->count()$i++{
  506.                         $current $polygon->get($i);
  507.                         $line->setLocation($prev$current);
  508.                         $this->line($color$line);
  509.                         $prev $current;
  510.                     }
  511.                     
  512.                     // Close the polygon
  513.                     $line->setLocation($prev$polygon->get(0));
  514.                     $this->line($color$line);
  515.                     
  516.                 }
  517.         
  518.         }
  519.         
  520.     }
  521.     
  522.      function filledPolygon($background&$polygon{
  523.         
  524.         if(is_a($background'awColor')) {
  525.             
  526.             $points $this->getPolygonPoints($polygon);
  527.             $rgb $this->getColor($background);
  528.             
  529.             imagefilledpolygon($this->resource$points$polygon->count()$rgb);
  530.             
  531.         else if(is_a($background'awGradient')) {
  532.             
  533.             $gradientDriver new awGDGradientDriver($this);
  534.             $gradientDriver->filledPolygon($background$polygon);
  535.             
  536.         }
  537.  
  538.     }
  539.  
  540.      function send(&$image{
  541.  
  542.         $this->drawImage($image);
  543.  
  544.     }
  545.     
  546.      function get(&$image{
  547.         
  548.         return $this->drawImage($imageTRUEFALSE);
  549.         
  550.     }
  551.     
  552.      function getTextWidth(&$text{
  553.         $font $text->getFont();
  554.         
  555.         if(is_a($font'awPHPFont')) {
  556.             $fontDriver $this->phpFontDriver;
  557.         else {
  558.             $fontDriver $this->fileFontDriver;
  559.         }
  560.         
  561.         return $fontDriver->getTextWidth($text$this);
  562.     }
  563.     
  564.      function getTextHeight(&$text{
  565.         $font $text->getFont();
  566.         
  567.         if(is_a($font'awPHPFont')) {
  568.             $fontDriver $this->phpFontDriver;
  569.         else {
  570.             $fontDriver $this->fileFontDriver;
  571.         }
  572.         
  573.         return $fontDriver->getTextHeight($text$this);
  574.     }
  575.     
  576.      function isCompatibleWithFont(&$font{
  577.         if(is_a($font'awFDBFont')) {
  578.             return FALSE;
  579.         else {
  580.             return TRUE;
  581.         }
  582.     }
  583.     
  584.      function drawImage(&$image$return FALSE$header TRUE{
  585.         
  586.         $format $image->getFormatString();
  587.         
  588.         // Test if format is available
  589.         if((imagetypes($image->getFormat()) === FALSE{
  590.             awImage::drawError("Class Image: Format '".$format."' is not available on your system. Check that your PHP has been compiled with the good libraries.");
  591.         }
  592.     
  593.         // Get some infos about this image
  594.         switch($format{
  595.             case 'jpeg' :
  596.                 $function 'imagejpeg';
  597.                 break;
  598.             case 'png' :
  599.                 $function 'imagepng';
  600.                 break;
  601.             case 'gif' :
  602.                 $function 'imagegif';
  603.                 break;
  604.         }
  605.         
  606.         // Send headers to the browser
  607.         if($header === TRUE{
  608.             $image->sendHeaders();
  609.         }
  610.         
  611.         if($return{
  612.             ob_start();
  613.         }
  614.         
  615.         $function($this->resource);
  616.         
  617.         if($return{
  618.             return ob_get_clean();
  619.         }
  620.     }
  621.     
  622.      function getPolygonPoints(&$polygon{
  623.         
  624.         $points array();
  625.         
  626.         foreach($polygon->all(as $point{
  627.             $points[$point->$this->x;
  628.             $points[$point->$this->y;
  629.         }
  630.         
  631.         return $points;
  632.         
  633.     }
  634.     
  635.      function startThickness($thickness{
  636.         
  637.         if($thickness 1{
  638.         
  639.             // Beurk :'(
  640.             if($this->antiAliasing and function_exists('imageantialias')) {
  641.                 imageantialias($this->resourceFALSE);
  642.             }
  643.             imagesetthickness($this->resource$thickness);
  644.             
  645.         }
  646.         
  647.     }
  648.     
  649.      function stopThickness($thickness{
  650.         
  651.         if($thickness 1{
  652.         
  653.             if($this->antiAliasing and function_exists('imageantialias')) {
  654.                 imageantialias($this->resourceTRUE);
  655.             }
  656.             imagesetthickness($this->resource1);
  657.             
  658.         }
  659.         
  660.     }
  661.     
  662.  
  663. }
  664.  
  665. registerClass('GDDriver');
  666.  
  667. /**
  668.  * To your gradients
  669.  *
  670.  * @package linea21.externals
  671.  * @subpackage artichow
  672.  */
  673.  
  674.  
  675.     /**
  676.      * A driver
  677.      *
  678.      * @var awGDDriver 
  679.      */
  680.     var $driver;
  681.  
  682.     /**
  683.      * Build your GDGradientDriver
  684.      *
  685.      * @var $driver 
  686.      */
  687.      function awGDGradientDriver($driver{
  688.     
  689.         $this->driver = $driver;
  690.         
  691.     }
  692.     
  693.      function drawFilledFlatTriangle($gradient$a$b$c{
  694.     
  695.         if($gradient->angle !== 0{
  696.             awImage::drawError("Class GDGradientDriver: Flat triangles can only be used with 0 degree gradients.");
  697.         }
  698.     
  699.         // Look for right-angled triangle
  700.         if($a->!== $b->and $b->!== $c->x{
  701.             awImage::drawError("Class GDGradientDriver: Not right-angled flat triangles are not supported yet.");
  702.         }
  703.         
  704.         if($a->=== $b->x{
  705.             $d $a;
  706.             $e $c;
  707.         else {
  708.             $d $c;
  709.             $e $a;
  710.         }
  711.         
  712.         $this->init($gradient$b->$d->y);
  713.     
  714.         for($i $c->1$i $b->y$i++{
  715.             
  716.             $color $this->color($i $d->y);
  717.             $pos ($i $d->y($b->$d->y);
  718.             
  719.             $p1 new awPoint($e->x$i);
  720.             $p2 new awPoint(floor($e->$pos ($e->$d->x))$i);
  721.             
  722.             $this->driver->filledRectangle($colornew awLine($p1$p2));
  723.             
  724.             unset($color);
  725.             
  726.         }
  727.     
  728.     }
  729.     
  730.      function drawFilledTriangle($gradient&$polygon{
  731.         
  732.         if($gradient->angle === 0{
  733.             $this->drawFilledTriangleVertically($gradient$polygon);
  734.         elseif($gradient->angle === 90{
  735.             $this->drawFilledTriangleHorizontally($gradient$polygon);
  736.         }
  737.         
  738.     }
  739.     
  740.      function drawFilledTriangleVertically($gradient&$polygon{
  741.         list($yMin$yMax$polygon->getBoxYRange();
  742.         
  743.         $this->init($gradient$yMax $yMin);
  744.         
  745.         // Get the triangle line we will draw our lines from
  746.         $fromLine NULL;
  747.         $lines $polygon->getLines();
  748.                 
  749.         $count count($lines);
  750.                     
  751.         // Pick the side of the triangle going from the top
  752.         // to the bottom of the surrounding box
  753.         for($i 0$i $count$i++{
  754.             if($lines[$i]->isTopToBottom($polygon)) {
  755.                 list($fromLinearray_splice($lines$i1);
  756.                 break;
  757.             }
  758.         }
  759.         
  760.         // If for some reason the three points are aligned,
  761.         // $fromLine will still be NULL
  762.         if($fromLine === NULL{
  763.             return;
  764.         }
  765.                         
  766.         $fillLine NULL;
  767.         for($y round($yMin)$y round($yMax)$y++{
  768.             
  769.             $fromX $fromLine->getXFrom($y);
  770.             
  771.             $toX array();
  772.             foreach($lines as $line{
  773.                 $xValue $line->getXFrom($y);
  774.                 
  775.                 if(!is_null($xValue)) {
  776.                     $toX[$xValue;
  777.                 }
  778.             }
  779.             
  780.             if(count($toX=== 1{
  781.                 $fillLine new Line(
  782.                     new Point($fromX$y),
  783.                     new Point($toX[0]$y)
  784.                 );
  785.             else {
  786.             
  787.                 $line1 new Line(
  788.                     new Point($fromX$y),
  789.                     new Point($toX[0]$y)
  790.                 );
  791.                 $line2 new  Line(
  792.                     new Point($fromX$y),
  793.                     new Point($toX[1]$y)
  794.                 );
  795.             
  796.                 if($line1->getSize($line2->getSize()) {
  797.                     $fillLine $line1;
  798.                 else {
  799.                     $fillLine $line2;
  800.                 }
  801.             }
  802.             
  803.             if(!$fillLine->isPoint()) {
  804.                 $color $this->color($y $yMin);
  805.                 $this->driver->line($color$fillLine);
  806.                 
  807.                 unset($color);
  808.             }
  809.         }
  810.     
  811.     }
  812.     
  813.      function drawFilledTriangleHorizontally($gradient&$polygon{
  814.         list($xMin$xMax$polygon->getBoxXRange();
  815.         
  816.         $this->init($gradient$xMax $xMin);
  817.         
  818.         // Get the triangle line we will draw our lines from
  819.         $fromLine NULL;
  820.         $lines $polygon->getLines();
  821.                 
  822.         $count count($lines);
  823.                     
  824.         // Pick the side of the triangle going all the way
  825.         // from the left side to the right side of the surrounding box
  826.         for($i 0$i $count$i++{
  827.             if($lines[$i]->isLeftToRight($polygon)) {
  828.                 list($fromLinearray_splice($lines$i1);
  829.                 break;
  830.             }
  831.         }
  832.         
  833.         // If for some reason the three points are aligned,
  834.         // $fromLine will still be NULL
  835.         if($fromLine === NULL{
  836.             return;
  837.         }
  838.  
  839.         $fillLine NULL;
  840.         for($x round($xMin)$x round($xMax)$x++{
  841.             
  842.             $fromY floor($fromLine->getYFrom($x));
  843.             
  844.             $toY array();
  845.             foreach($lines as $line{
  846.                 $yValue $line->getYFrom($x);
  847.                 
  848.                 if(!is_null($yValue)) {
  849.                     $toY[floor($yValue);
  850.                 }
  851.             }
  852.             
  853.             if(count($toY=== 1{
  854.                 $fillLine new Line(
  855.                     new Point($x$fromY),
  856.                     new Point($x$toY[0])
  857.                 );
  858.             else {
  859.             
  860.                 $line1 new Line(
  861.                     new Point($x$fromY),
  862.                     new Point($x$toY[0])
  863.                 );
  864.                 $line2 new  Line(
  865.                     new Point($x$fromY),
  866.                     new Point($x$toY[1])
  867.                 );
  868.             
  869.                 if($line1->getSize($line2->getSize()) {
  870.                     $fillLine $line1;
  871.                 else {
  872.                     $fillLine $line2;
  873.                 }
  874.             }
  875.             
  876.             $color $this->color($x $xMin);
  877.             if($fillLine->isPoint()) {
  878.                 $this->driver->point($color$fillLine->p1);
  879.             elseif($fillLine->getSize(>= 1{
  880.                 $this->driver->line($color$fillLine);
  881.             }
  882.             unset($color);
  883.         }
  884.     
  885.     }
  886.     
  887.      function filledRectangle($gradient$p1$p2{
  888.     
  889.         list($x1$y1$p1->getLocation();
  890.         list($x2$y2$p2->getLocation();
  891.     
  892.         if($y1 $y2{
  893.             $y1 ^= $y2 ^= $y1 ^= $y2;
  894.         }
  895.     
  896.         if($x2 $x1{
  897.             $x1 ^= $x2 ^= $x1 ^= $x2;
  898.         }
  899.         
  900.         if(is_a($gradient'awLinearGradient')) {
  901.             $this->rectangleLinearGradient($gradientnew awPoint($x1$y1)new awPoint($x2$y2));
  902.         else {
  903.             awImage::drawError("Class GDGradientDriver: This gradient is not supported by rectangles.");
  904.         }
  905.     
  906.     }
  907.     
  908.      function filledPolygon($gradient&$polygon{
  909.     
  910.         if(is_a($gradient'awLinearGradient')) {
  911.             $this->polygonLinearGradient($gradient$polygon);
  912.         else {
  913.             awImage::drawError("Class GDGradientDriver: This gradient is not supported by polygons.");
  914.         }
  915.     
  916.     }
  917.     
  918.      function rectangleLinearGradient(&$gradient$p1$p2{
  919.     
  920.         list($x1$y1$p1->getLocation();
  921.         list($x2$y2$p2->getLocation();
  922.     
  923.         if($y1 $y2 0{
  924.         
  925.             if($gradient->angle === 0{
  926.             
  927.                 $this->init($gradient$y1 $y2);
  928.         
  929.                 for($i $y2$i <= $y1$i++{
  930.                 
  931.                     $color $this->color($i $y2);
  932.                     
  933.                     $p1 new awPoint($x1$i);
  934.                     $p2 new awPoint($x2$i);
  935.             
  936.                     $this->driver->filledRectangle($colornew awLine($p1$p2));
  937.                     
  938.                     unset($color);
  939.                     
  940.                 }
  941.                 
  942.             else if($gradient->angle === 90{
  943.             
  944.                 $this->init($gradient$x2 $x1);
  945.         
  946.                 for($i $x1$i <= $x2$i++{
  947.                 
  948.                     $color $this->color($i $x1);
  949.                     
  950.                     $p1 new awPoint($i$y2);
  951.                     $p2 new awPoint($i$y1);
  952.             
  953.                     $this->driver->filledRectangle($colornew awLine($p1$p2));
  954.                     
  955.                     unset($color);
  956.                     
  957.                 }
  958.                 
  959.             }
  960.             
  961.         }
  962.     
  963.     }
  964.     
  965.      function filledEllipse($gradient$x1$y1$x2$y2{
  966.     
  967.         if($y1 $y2{
  968.             $y1 ^= $y2 ^= $y1 ^= $y2;
  969.         }
  970.     
  971.         if($x2 $x1{
  972.             $x1 ^= $x2 ^= $x1 ^= $x2;
  973.         }
  974.         
  975.         if(is_a($gradient'awRadialGradient')) {
  976.             $this->ellipseRadialGradient($gradient$x1$y1$x2$y2);
  977.         else if(is_a($gradient'awLinearGradient')) {
  978.             $this->ellipseLinearGradient($gradient$x1$y1$x2$y2);
  979.         else {
  980.             awImage::drawError("Class GDGradientDriver: This gradient is not supported by ellipses.");
  981.         }
  982.     
  983.     }
  984.     
  985.      function ellipseRadialGradient($gradient$x1$y1$x2$y2{
  986.     
  987.         if($y1 $y2 0{
  988.     
  989.             if($y1 $y2 != $x2 $x1{
  990.                 awImage::drawError("Class GDGradientDriver: Radial gradients are only implemented on circle, not ellipses.");
  991.             }
  992.             
  993.             $c new awPoint($x1 ($x2 $x12$y1 ($y2 $y12)
  994.             $r ($x2 $x12;
  995.             $ok array();
  996.             
  997.             // Init gradient
  998.             $this->init($gradient$r);
  999.             
  1000.             for($i 0$i <= $r$i += 0.45{
  1001.             
  1002.                 $p ceil((M_PI $i));
  1003.                 
  1004.                 if($p 0{
  1005.                     $interval 360 $p;
  1006.                 else {
  1007.                     $interval 360;
  1008.                 }
  1009.                 
  1010.                 $color $this->color($i);
  1011.                 
  1012.                 for($j 0$j 360$j += $interval{
  1013.                 
  1014.                     $rad ($j 360(M_PI);
  1015.                     
  1016.                     $x round($i cos($rad));
  1017.                     $y round($i sin($rad));
  1018.                     
  1019.                     $l sqrt($x $x $y $y);
  1020.                     
  1021.                     if($l <= $r{
  1022.                     
  1023.                         if(
  1024.                             array_key_exists((int)$x$ok=== FALSE or
  1025.                             array_key_exists((int)$y$ok[$x]=== FALSE
  1026.                         {
  1027.                         
  1028.                             // Print the point
  1029.                             $this->driver->point($colornew awPoint($c->$x$c->$y));
  1030.                             
  1031.                             $ok[(int)$x][(int)$yTRUE;
  1032.                         
  1033.                         }
  1034.                         
  1035.                     }
  1036.                 
  1037.                 }
  1038.                 
  1039.                 unset($color);
  1040.             
  1041.             }
  1042.         
  1043.         }
  1044.     
  1045.     }
  1046.     
  1047.      function ellipseLinearGradient($gradient$x1$y1$x2$y2{
  1048.     
  1049.         // Gauche->droite : 90°
  1050.     
  1051.         if($y1 $y2 0{
  1052.     
  1053.             if($y1 $y2 != $x2 $x1{
  1054.                 awImage::drawError("Class GDGradientDriver: Linear gradients are only implemented on circle, not ellipses.");
  1055.             }
  1056.             
  1057.             $r ($x2 $x12;
  1058.             
  1059.             // Init gradient
  1060.             $this->init($gradient$x2 $x1);
  1061.             
  1062.             for($i = -$r$i <= $r$i++{
  1063.                 
  1064.                 $h sin(acos($i $r)) $r;
  1065.                 
  1066.                 $color $this->color($i $r);
  1067.                 
  1068.                 if($gradient->angle === 90{
  1069.                 
  1070.                     // Print the line
  1071.                     $p1 new awPoint(
  1072.                         $x1 $i $r,
  1073.                         round(max($y2 $r $h 1$y2))
  1074.                     );
  1075.                     
  1076.                     $p2 new awPoint(
  1077.                         $x1 $i $r,
  1078.                         round(min($y1 $r $h 1$y1))
  1079.                     );
  1080.                     
  1081.                 else {
  1082.                 
  1083.                     // Print the line
  1084.                     $p1 new awPoint(
  1085.                         round(max($x1 $r $h 1$x1)),
  1086.                         $y2 $i $r
  1087.                     );
  1088.                     
  1089.                     $p2 new awPoint(
  1090.                         round(min($x2 $r $h 1$x2)),
  1091.                         $y2 $i $r
  1092.                     );
  1093.                     
  1094.                 }
  1095.                 
  1096.                 $this->driver->filledRectangle($colornew awLine($p1$p2));
  1097.                 
  1098.                 unset($color);
  1099.             
  1100.             }
  1101.         
  1102.         }
  1103.     
  1104.     }
  1105.     
  1106.      function polygonLinearGradient(&$gradient&$polygon{
  1107.     
  1108.         $count $polygon->count();
  1109.         
  1110.         if($count >= 4{
  1111.         
  1112.             $left $polygon->get(0);
  1113.             $right $polygon->get($count 1);
  1114.             
  1115.             if($gradient->angle === 0{
  1116.             
  1117.                 // Get polygon maximum and minimum
  1118.                 $offset $polygon->get(0);
  1119.                 $max $min $offset->y;
  1120.                 for($i 1$i $count 1$i++{
  1121.                     $offset $polygon->get($i);
  1122.                     $max max($max$offset->y);
  1123.                     $min min($min$offset->y);
  1124.                 }
  1125.                 
  1126.                 $this->init($gradient$max $min);
  1127.             
  1128.                 $prev $polygon->get(1);
  1129.                 
  1130.                 $sum 0;
  1131.             
  1132.                 for($i 2$i $count 1$i++{
  1133.                 
  1134.                     $current $polygon->get($i);
  1135.                     
  1136.                     $interval 1;
  1137.                     
  1138.                     if($i !== $count 2{
  1139.                         $current->-= $interval;
  1140.                     }
  1141.                     
  1142.                     if($current->$prev->0{
  1143.                 
  1144.                         // Draw rectangle
  1145.                         $x1 $prev->x;
  1146.                         $x2 $current->x;
  1147.                         $y1 max($prev->y$current->y);
  1148.                         $y2 $left->y;
  1149.                         
  1150.                         $gradient new awLinearGradient(
  1151.                             $this->color($max $min ($y2 $y1)),
  1152.                             $this->color($max $min),
  1153.                             0
  1154.                         );
  1155.                         
  1156.                         if($y1 $y2{
  1157.                             $y2 $y1;
  1158.                         }
  1159.                         
  1160.                         $this->driver->filledRectangle(
  1161.                             $gradient,
  1162.                             awLine::build($x1$y1$x2$y2)
  1163.                         );
  1164.                         
  1165.                         $top ($prev->$current->y$current $prev;
  1166.                         $bottom ($prev->>= $current->y$current $prev;
  1167.                         
  1168.                         $gradient new awLinearGradient(
  1169.                             $this->color($bottom->$min),
  1170.                             $this->color($max $min ($y2 $y1)),
  1171.                             0
  1172.                         );
  1173.                         
  1174.     
  1175.                         $gradientDriver new awGDGradientDriver($this->driver);
  1176.                         $gradientDriver->drawFilledFlatTriangle(
  1177.                             $gradient,
  1178.                             new awPoint($prev->xmin($prev->y$current->y)),
  1179.                             $top,
  1180.                             new awPoint($current->xmin($prev->y$current->y))
  1181.                         );
  1182.                         unset($gradientDriver);
  1183.                         
  1184.                         $sum += $current->$prev->x;
  1185.                         
  1186.                     }
  1187.                     
  1188.                     $prev $current;
  1189.                     $prev->+= $interval;
  1190.                 
  1191.                 }
  1192.             
  1193.             else if($gradient->angle === 90{
  1194.                 
  1195.                 $width $right->$left->x;
  1196.                 $this->init($gradient$width);
  1197.                 
  1198.                 $pos 1;
  1199.                 $next $polygon->get($pos++);
  1200.                 
  1201.                 $this->next($polygon$pos$prev$next);
  1202.             
  1203.                 for($i 0$i <= $width$i++{
  1204.                 
  1205.                     $x $left->$i;
  1206.                     
  1207.                     $y1 round($prev->($next->$prev->y(($i $left->$prev->x($next->$prev->x)));
  1208.                     $y2 $left->y;
  1209.                 
  1210.                     // Draw line
  1211.                     $color $this->color($i);
  1212.                     // YaPB : PHP does not handle alpha on lines
  1213.                     $this->driver->filledRectangle($colorawLine::build($x$y1$x$y2));
  1214.  
  1215.                     unset($color);
  1216.                     
  1217.                     // Jump to next point
  1218.                     if($next->== $i $left->x{
  1219.                     
  1220.                         $this->next($polygon$pos$prev$next);
  1221.                         
  1222.                     }
  1223.                 
  1224.                 }
  1225.     
  1226.             }
  1227.             
  1228.         else if($count === 3{
  1229.             $this->drawFilledTriangle(
  1230.                 $gradient,
  1231.                 $polygon
  1232.             );
  1233.         }
  1234.     
  1235.     }
  1236.     
  1237.      function next($polygon&$pos&$prev&$next{
  1238.     
  1239.         do {
  1240.             $prev $next;
  1241.             $next $polygon->get($pos++);
  1242.         }
  1243.         while($next->$prev->== and $pos $polygon->count());
  1244.         
  1245.     }
  1246.     
  1247.     /**
  1248.      * Start colors
  1249.      *
  1250.      * @var int 
  1251.      */
  1252.     var $r1$g1$b1$a1;
  1253.     
  1254.     /**
  1255.      * Stop colors
  1256.      *
  1257.      * @var int 
  1258.      */
  1259.     var $r2$g2$b2$a2;
  1260.     
  1261.     /**
  1262.      * Gradient size in pixels
  1263.      *
  1264.      * @var int 
  1265.      */
  1266.     var $size;
  1267.     
  1268.     
  1269.      function init($gradient$size{
  1270.         
  1271.         list(
  1272.             $this->r1$this->g1$this->b1$this->a1
  1273.         $gradient->from->rgba();
  1274.         
  1275.         list(
  1276.             $this->r2$this->g2$this->b2$this->a2
  1277.         $gradient->to->rgba();
  1278.         
  1279.         $this->size $size;
  1280.     }
  1281.     
  1282.      function color($pos{
  1283.     
  1284.         return new awColor(
  1285.             $this->getRed($pos),
  1286.             $this->getGreen($pos),
  1287.             $this->getBlue($pos),
  1288.             $this->getAlpha($pos)
  1289.         );
  1290.         
  1291.     }
  1292.     
  1293.     
  1294.      function getRed($pos{
  1295.         if((float)$this->size !== 0.0{
  1296.             return (int)round($this->r1 ($pos $this->size($this->r2 $this->r1));
  1297.         else {
  1298.             return 0;
  1299.         }
  1300.     }
  1301.     
  1302.      function getGreen($pos{
  1303.         if((float)$this->size !== 0.0{
  1304.             return (int)round($this->g1 ($pos $this->size($this->g2 $this->g1));
  1305.         else {
  1306.             return 0;
  1307.         }
  1308.     }
  1309.     
  1310.      function getBlue($pos{
  1311.         if((float)$this->size !== 0.0{
  1312.             return (int)round($this->b1 ($pos $this->size($this->b2 $this->b1));
  1313.         else {
  1314.             return 0;
  1315.         }
  1316.     }
  1317.     
  1318.      function getAlpha($pos{
  1319.         if((float)$this->size !== 0.0{
  1320.             return (int)round(($this->a1 ($pos $this->size($this->a2 $this->a1)) 127 100);
  1321.         else {
  1322.             return 0;
  1323.         }
  1324.     }
  1325.  
  1326. }
  1327.  
  1328. registerClass('GDGradientDriver');
  1329.  
  1330. /*
  1331.  * Check for GD2
  1332.  */
  1333. if(function_exists('imagecreatetruecolor'=== FALSE{
  1334.     awImage::drawErrorFile('missing-gd2');
  1335. }
  1336.  
  1337. ?>

Documentation generated on Fri, 16 Oct 2009 09:33:02 +0200 by phpDocumentor 1.4.1