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

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