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

Documentation generated on Thu, 03 May 2012 15:04:47 +0200 by phpDocumentor 1.4.1