| [ Index ] |
|
Code source de Cr@wltr@ck 2.2.1 |
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__)."/../Graph.class.php"; 11 12 /** 13 * Draw your objects 14 * 15 * @package Artichow 16 */ 17 class awDrawer { 18 19 /** 20 * A GD resource 21 * 22 * @var $resource 23 */ 24 public $resource; 25 26 /** 27 * Image width 28 * 29 * @var int 30 */ 31 public $width; 32 33 /** 34 * Image height 35 * 36 * @var int 37 */ 38 public $height; 39 40 /** 41 * Drawer X position 42 * 43 * @var int 44 */ 45 public $x; 46 47 /** 48 * Drawer Y position 49 * 50 * @var int 51 */ 52 public $y; 53 54 private $w; 55 private $h; 56 57 /** 58 * Build your drawer 59 * 60 * @var resource $resource A GD resource 61 */ 62 public function __construct($resource) { 63 64 $this->resource = $resource; 65 66 } 67 68 /** 69 * Change the image size 70 * 71 * @param int $width Image width 72 * @param int $height Image height 73 */ 74 public function setImageSize($width, $height) { 75 76 $this->width = $width; 77 $this->height = $height; 78 79 } 80 81 /** 82 * Inform the drawer of the position of your image 83 * 84 * @param float $x Position on X axis of the center of the component 85 * @param float $y Position on Y axis of the center of the component 86 */ 87 public function setPosition($x, $y) { 88 89 // Calcul absolute position 90 $this->x = round($x * $this->width - $this->w / 2); 91 $this->y = round($y * $this->height - $this->h / 2); 92 93 } 94 95 /** 96 * Inform the drawer of the position of your image 97 * This method need absolutes values 98 * 99 * @param int $x Left-top corner X position 100 * @param int $y Left-top corner Y position 101 */ 102 public function setAbsPosition($x, $y) { 103 104 $this->x = $x; 105 $this->y = $y; 106 107 } 108 109 /** 110 * Move the position of the image 111 * 112 * @param int $x Add this value to X axis 113 * @param int $y Add this value to Y axis 114 */ 115 public function movePosition($x, $y) { 116 117 $this->x += (int)$x; 118 $this->y += (int)$y; 119 120 } 121 122 /** 123 * Inform the drawer of the size of your image 124 * Height and width must be between 0 and 1. 125 * 126 * @param int $w Image width 127 * @param int $h Image height 128 * @return array Absolute width and height of the image 129 */ 130 public function setSize($w, $h) { 131 132 // Calcul absolute size 133 $this->w = round($w * $this->width); 134 $this->h = round($h * $this->height); 135 136 return $this->getSize(); 137 138 } 139 140 /** 141 * Inform the drawer of the size of your image 142 * You can set absolute size with this method. 143 * 144 * @param int $w Image width 145 * @param int $h Image height 146 */ 147 public function setAbsSize($w, $h) { 148 149 $this->w = $w; 150 $this->h = $h; 151 152 return $this->getSize(); 153 154 } 155 156 /** 157 * Get the size of the component handled by the drawer 158 * 159 * @return array Absolute width and height of the component 160 */ 161 public function getSize() { 162 163 return array($this->w, $this->h); 164 165 } 166 167 /** 168 * Draw an image here 169 * 170 * @param awImage $image Image 171 * @param int $p1 Image top-left point 172 * @param int $p2 Image bottom-right point 173 */ 174 public function copyImage(awImage $image, awPoint $p1, awPoint $p2) { 175 176 list($x1, $y1) = $p1->getLocation(); 177 list($x2, $y2) = $p2->getLocation(); 178 179 $drawer = $image->getDrawer(); 180 imagecopy($this->resource, $drawer->resource, $this->x + $x1, $this->y + $y1, 0, 0, $x2 - $x1, $y2 - $y1); 181 182 } 183 184 /** 185 * Draw an image here 186 * 187 * @param awImage $image Image 188 * @param int $d1 Destination top-left position 189 * @param int $d2 Destination bottom-right position 190 * @param int $s1 Source top-left position 191 * @param int $s2 Source bottom-right position 192 * @param bool $resample Resample image ? (default to TRUE) 193 */ 194 public function copyResizeImage(awImage $image, awPoint $d1, awPoint $d2, awPoint $s1, awPoint $s2, $resample = TRUE) { 195 196 if($resample) { 197 $function = 'imagecopyresampled'; 198 } else { 199 $function = 'imagecopyresized'; 200 } 201 202 $drawer = $image->getDrawer(); 203 204 $function( 205 $this->resource, 206 $drawer->resource, 207 $this->x + $d1->x, $this->y + $d1->y, 208 $s1->x, $s1->y, 209 $d2->x - $d1->x, $d2->y - $d1->y, 210 $s2->x - $s1->x, $s2->y - $s1->y 211 ); 212 213 } 214 215 /** 216 * Draw a string 217 * 218 * @var awText $text Text to print 219 * @param awPoint $point Draw the text at this point 220 * @param int $width Text max width 221 */ 222 public function string(awText $text, awPoint $point, $width = NULL) { 223 224 $font = $text->getFont(); 225 226 if($text->getBackground() !== NULL or $text->border->visible()) { 227 228 list($left, $right, $top, $bottom) = $text->getPadding(); 229 230 $width = $font->getTextWidth($text); 231 $height = $font->getTextHeight($text); 232 233 $x1 = floor($point->x - $left); 234 $y1 = floor($point->y - $top); 235 $x2 = $x1 + $width + $left + $right; 236 $y2 = $y1 + $height + $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 $font->draw($this, $point, $text, $width); 252 253 } 254 255 /** 256 * Draw a pixel 257 * 258 * @param awColor $color Pixel color 259 * @param awPoint $p 260 */ 261 public function point(awColor $color, awPoint $p) { 262 263 if($p->isHidden() === FALSE) { 264 $rgb = $color->getColor($this->resource); 265 imagesetpixel($this->resource, $this->x + round($p->x), $this->y + round($p->y), $rgb); 266 } 267 268 } 269 270 /** 271 * Draw a colored line 272 * 273 * @param awColor $color Line color 274 * @param awLine $line 275 * @param int $thickness Line tickness 276 */ 277 public function line(awColor $color, awLine $line) { 278 279 if($line->thickness > 0 and $line->isHidden() === FALSE) { 280 281 $rgb = $color->getColor($this->resource); 282 $thickness = $line->thickness; 283 284 list($p1, $p2) = $line->getLocation(); 285 286 $this->startThickness($thickness); 287 288 switch($line->getStyle()) { 289 290 case awLine::SOLID : 291 imageline($this->resource, $this->x + round($p1->x), $this->y + round($p1->y), $this->x + round($p2->x), $this->y + round($p2->y), $rgb); 292 break; 293 294 case awLine::DOTTED : 295 $size = sqrt(pow($p2->y - $p1->y, 2) + pow($p2->x - $p1->x, 2)); 296 $cos = ($p2->x - $p1->x) / $size; 297 $sin = ($p2->y - $p1->y) / $size; 298 for($i = 0; $i <= $size; $i += 2) { 299 $p = new awPoint( 300 round($i * $cos + $p1->x), 301 round($i * $sin + $p1->y) 302 ); 303 $this->point($color, $p); 304 } 305 break; 306 307 case awLine::DASHED : 308 $width = $p2->x - $p1->x; 309 $height = $p2->y - $p1->y; 310 $size = sqrt(pow($height, 2) + pow($width, 2)); 311 312 if($size == 0) { 313 return; 314 } 315 316 $cos = $width / $size; 317 $sin = $height / $size; 318 319 for($i = 0; $i <= $size; $i += 6) { 320 321 $t1 = new awPoint( 322 round($i * $cos + $p1->x), 323 round($i * $sin + $p1->y) 324 ); 325 326 $function = ($height > 0) ? 'min' : 'max'; 327 $t2 = new awPoint( 328 round(min(($i + 3) * $cos, $width) + $p1->x), 329 round($function(($i + 3) * $sin, $height) + $p1->y) 330 ); 331 332 $this->line($color, new awLine($t1, $t2)); 333 334 } 335 break; 336 337 } 338 339 $this->stopThickness($thickness); 340 341 } 342 343 } 344 345 /** 346 * Draw a color arc 347 348 * @param awColor $color Arc color 349 * @param awPoint $center Point center 350 * @param int $width Ellipse width 351 * @param int $height Ellipse height 352 * @param int $from Start angle 353 * @param int $to End angle 354 */ 355 public function arc(awColor $color, awPoint $center, $width, $height, $from, $to) { 356 357 imagefilledarc( 358 $this->resource, 359 $this->x + $center->x, $this->y + $center->y, 360 $width, $height, 361 $from, $to, 362 $color->getColor($this->resource), 363 IMG_ARC_EDGED | IMG_ARC_NOFILL 364 ); 365 366 } 367 368 /** 369 * Draw an arc with a background color 370 * 371 * @param awColor $color Arc background color 372 * @param awPoint $center Point center 373 * @param int $width Ellipse width 374 * @param int $height Ellipse height 375 * @param int $from Start angle 376 * @param int $to End angle 377 */ 378 public function filledArc(awColor $color, awPoint $center, $width, $height, $from, $to) { 379 380 imagefilledarc( 381 $this->resource, 382 $this->x + $center->x, $this->y + $center->y, 383 $width, $height, 384 $from, $to, 385 $color->getColor($this->resource), 386 IMG_ARC_PIE 387 ); 388 389 } 390 391 /** 392 * Draw a colored ellipse 393 * 394 * @param awColor $color Ellipse color 395 * @param awPoint $center Ellipse center 396 * @param int $width Ellipse width 397 * @param int $height Ellipse height 398 */ 399 public function ellipse(awColor $color, awPoint $center, $width, $height) { 400 401 list($x, $y) = $center->getLocation(); 402 403 $rgb = $color->getColor($this->resource); 404 imageellipse( 405 $this->resource, 406 $this->x + $x, 407 $this->y + $y, 408 $width, 409 $height, 410 $rgb 411 ); 412 413 } 414 415 /** 416 * Draw an ellipse with a background 417 * 418 * @param mixed $background Background (can be a color or a gradient) 419 * @param awPoint $center Ellipse center 420 * @param int $width Ellipse width 421 * @param int $height Ellipse height 422 */ 423 public function filledEllipse($background, awPoint $center, $width, $height) { 424 425 if($background instanceof awColor) { 426 427 list($x, $y) = $center->getLocation(); 428 429 $rgb = $background->getColor($this->resource); 430 431 imagefilledellipse( 432 $this->resource, 433 $this->x + $x, 434 $this->y + $y, 435 $width, 436 $height, 437 $rgb 438 ); 439 440 } else if($background instanceof awGradient) { 441 442 list($x, $y) = $center->getLocation(); 443 444 $x1 = $x - round($width / 2); 445 $y1 = $y - round($height / 2); 446 $x2 = $x1 + $width; 447 $y2 = $y1 + $height; 448 449 $gradientDrawer = new awGradientDrawer($this); 450 $gradientDrawer->filledEllipse( 451 $background, 452 $x1, $y1, 453 $x2, $y2 454 ); 455 456 } 457 458 } 459 460 /** 461 * Draw a colored rectangle 462 * 463 * @param awColor $color Rectangle color 464 * @param awLine $line Rectangle diagonale 465 * @param awPoint $p2 466 */ 467 public function rectangle(awColor $color, awLine $line) { 468 469 $p1 = $line->p1; 470 $p2 = $line->p2; 471 472 switch($line->getStyle()) { 473 474 case awLine::SOLID : 475 $thickness = $line->getThickness(); 476 $this->startThickness($thickness); 477 $rgb = $color->getColor($this->resource); 478 imagerectangle($this->resource, $this->x + $p1->x, $this->y + $p1->y, $this->x + $p2->x, $this->y + $p2->y, $rgb); 479 $this->stopThickness($thickness); 480 break; 481 482 default : 483 484 // Top side 485 $line->setLocation( 486 new awPoint($p1->x, $p1->y), 487 new awPoint($p2->x, $p1->y) 488 ); 489 $this->line($color, $line); 490 491 // Right side 492 $line->setLocation( 493 new awPoint($p2->x, $p1->y), 494 new awPoint($p2->x, $p2->y) 495 ); 496 $this->line($color, $line); 497 498 // Bottom side 499 $line->setLocation( 500 new awPoint($p1->x, $p2->y), 501 new awPoint($p2->x, $p2->y) 502 ); 503 $this->line($color, $line); 504 505 // Left side 506 $line->setLocation( 507 new awPoint($p1->x, $p1->y), 508 new awPoint($p1->x, $p2->y) 509 ); 510 $this->line($color, $line); 511 512 break; 513 514 } 515 516 } 517 518 /** 519 * Draw a rectangle with a background 520 * 521 * @param mixed $background Background (can be a color or a gradient) 522 * @param awLine $line Rectangle diagonale 523 */ 524 public function filledRectangle($background, awLine $line) { 525 526 $p1 = $line->p1; 527 $p2 = $line->p2; 528 529 if($background instanceof awColor) { 530 $rgb = $background->getColor($this->resource); 531 imagefilledrectangle($this->resource, $this->x + $p1->x, $this->y + $p1->y, $this->x + $p2->x, $this->y + $p2->y, $rgb); 532 } else if($background instanceof awGradient) { 533 $gradientDrawer = new awGradientDrawer($this); 534 $gradientDrawer->filledRectangle($background, $p1, $p2); 535 } 536 537 } 538 539 /** 540 * Draw a polygon 541 * 542 * @param awColor $color Polygon color 543 * @param Polygon A polygon 544 */ 545 public function polygon(awColor $color, awPolygon $polygon) { 546 547 switch($polygon->getStyle()) { 548 549 case awPolygon::SOLID : 550 $thickness = $line->getThickness(); 551 $this->startThickness($thickness); 552 $points = $this->getPolygonPoints($polygon); 553 $rgb = $color->getColor($this->resource); 554 imagepolygon($this->resource, $points, $polygon->count(), $rgb); 555 $this->stopThickness($thickness); 556 break; 557 558 default : 559 560 if($polygon->count() > 1) { 561 562 $prev = $polygon->get(0); 563 564 $line = new awLine; 565 $line->setStyle($polygon->getStyle()); 566 $line->setThickness($polygon->getThickness()); 567 568 for($i = 1; $i < $polygon->count(); $i++) { 569 $current = $polygon->get($i); 570 $line->setLocation($prev, $current); 571 $this->line($color, $line); 572 $prev = $current; 573 } 574 575 } 576 577 } 578 579 } 580 581 /** 582 * Draw a polygon with a background 583 * 584 * @param mixed $background Background (can be a color or a gradient) 585 * @param Polygon A polygon 586 */ 587 public function filledPolygon($background, awPolygon $polygon) { 588 589 if($background instanceof awColor) { 590 $points = $this->getPolygonPoints($polygon); 591 $rgb = $background->getColor($this->resource); 592 imagefilledpolygon($this->resource, $points, $polygon->count(), $rgb); 593 } else if($background instanceof awGradient) { 594 $gradientDrawer = new awGradientDrawer($this); 595 $gradientDrawer->filledPolygon($background, $polygon); 596 } 597 598 } 599 600 private function getPolygonPoints(awPolygon $polygon) { 601 602 $points = array(); 603 604 foreach($polygon->all() as $point) { 605 $points[] = $point->x + $this->x; 606 $points[] = $point->y + $this->y; 607 } 608 609 return $points; 610 611 } 612 613 private function startThickness($thickness) { 614 615 if($thickness > 1) { 616 617 // Beurk :'( 618 if(function_exists('imageantialias')) { 619 imageantialias($this->resource, FALSE); 620 } 621 imagesetthickness($this->resource, $thickness); 622 623 } 624 625 } 626 627 private function stopThickness($thickness) { 628 629 if($thickness > 1) { 630 631 if(function_exists('imageantialias')) { 632 imageantialias($this->resource, TRUE); 633 } 634 imagesetthickness($this->resource, 1); 635 636 } 637 638 } 639 640 641 } 642 643 registerClass('Drawer'); 644 645 /** 646 * To your gradients 647 * 648 * @package Artichow 649 */ 650 651 class awGradientDrawer { 652 653 /** 654 * A drawer 655 * 656 * @var Drawer 657 */ 658 protected $drawer; 659 660 /** 661 * Build your GradientDrawer 662 * 663 * @var awDrawer $drawer 664 */ 665 public function __construct(awDrawer $drawer) { 666 667 $this->drawer = $drawer; 668 669 } 670 671 public function drawFilledFlatTriangle(awGradient $gradient, awPoint $a, awPoint $b, awPoint $c) { 672 673 if($gradient->angle !== 0) { 674 awImage::drawError("Class GradientDrawer: Flat triangles can only be used with 0 degree gradients."); 675 } 676 677 // Look for right-angled triangle 678 if($a->x !== $b->x and $b->x !== $c->x) { 679 awImage::drawError("Class GradientDrawer: Not right-angled flat triangles are not supported yet."); 680 } 681 682 if($a->x === $b->x) { 683 $d = $a; 684 $e = $c; 685 } else { 686 $d = $c; 687 $e = $a; 688 } 689 690 $this->init($gradient, $b->y - $d->y); 691 692 for($i = $c->y + 1; $i < $b->y; $i++) { 693 694 $color = $this->color($i - $d->y); 695 $pos = ($i - $d->y) / ($b->y - $d->y); 696 697 $p1 = new awPoint($e->x, $i); 698 $p2 = new awPoint(1 + floor($e->x - $pos * ($e->x - $d->x)), $i); 699 700 $this->drawer->filledRectangle($color, new awLine($p1, $p2)); 701 702 $color->free(); 703 unset($color); 704 705 } 706 707 } 708 709 public function filledRectangle(awGradient $gradient, awPoint $p1, awPoint $p2) { 710 711 list($x1, $y1) = $p1->getLocation(); 712 list($x2, $y2) = $p2->getLocation(); 713 714 if($y1 < $y2) { 715 $y1 ^= $y2 ^= $y1 ^= $y2; 716 } 717 718 if($x2 < $x1) { 719 $x1 ^= $x2 ^= $x1 ^= $x2; 720 } 721 722 if($gradient instanceof awLinearGradient) { 723 $this->rectangleLinearGradient($gradient, new awPoint($x1, $y1), new awPoint($x2, $y2)); 724 } else { 725 awImage::drawError("Class GradientDrawer: This gradient is not supported by rectangles."); 726 } 727 728 } 729 730 public function filledPolygon(awGradient $gradient, awPolygon $polygon) { 731 732 if($gradient instanceof awLinearGradient) { 733 $this->polygonLinearGradient($gradient, $polygon); 734 } else { 735 awImage::drawError("Class GradientDrawer: This gradient is not supported by polygons."); 736 } 737 738 } 739 740 protected function rectangleLinearGradient(awLinearGradient $gradient, awPoint $p1, awPoint $p2) { 741 742 list($x1, $y1) = $p1->getLocation(); 743 list($x2, $y2) = $p2->getLocation(); 744 745 if($y1 - $y2 > 0) { 746 747 if($gradient->angle === 0) { 748 749 $this->init($gradient, $y1 - $y2); 750 751 for($i = $y2; $i <= $y1; $i++) { 752 753 $color = $this->color($i - $y2); 754 755 $p1 = new awPoint($x1, $i); 756 $p2 = new awPoint($x2, $i); 757 758 $this->drawer->filledRectangle($color, new awLine($p1, $p2)); 759 760 $color->free(); 761 unset($color); 762 763 } 764 765 } else if($gradient->angle === 90) { 766 767 $this->init($gradient, $x2 - $x1); 768 769 for($i = $x1; $i <= $x2; $i++) { 770 771 $color = $this->color($i - $x1); 772 773 $p1 = new awPoint($i, $y2); 774 $p2 = new awPoint($i, $y1); 775 776 $this->drawer->filledRectangle($color, new awLine($p1, $p2)); 777 778 $color->free(); 779 unset($color); 780 781 } 782 783 } 784 785 } 786 787 } 788 789 public function filledEllipse(awGradient $gradient, $x1, $y1, $x2, $y2) { 790 791 if($y1 < $y2) { 792 $y1 ^= $y2 ^= $y1 ^= $y2; 793 } 794 795 if($x2 < $x1) { 796 $x1 ^= $x2 ^= $x1 ^= $x2; 797 } 798 799 if($gradient instanceof awRadialGradient) { 800 $this->ellipseRadialGradient($gradient, $x1, $y1, $x2, $y2); 801 } else if($gradient instanceof awLinearGradient) { 802 $this->ellipseLinearGradient($gradient, $x1, $y1, $x2, $y2); 803 } else { 804 awImage::drawError("Class GradientDrawer: This gradient is not supported by ellipses."); 805 } 806 807 } 808 809 protected function ellipseRadialGradient(awGradient $gradient, $x1, $y1, $x2, $y2) { 810 811 if($y1 - $y2 > 0) { 812 813 if($y1 - $y2 != $x2 - $x1) { 814 awImage::drawError("Class GradientDrawer: Radial gradients are only implemented on circle, not ellipses."); 815 } 816 817 $c = new awPoint($x1 + ($x2 - $x1) / 2, $y1 + ($y2 - $y1) / 2); 818 $r = ($x2 - $x1) / 2; 819 $ok = array(); 820 821 // Init gradient 822 $this->init($gradient, $r); 823 824 for($i = 0; $i <= $r; $i += 0.45) { 825 826 $p = ceil((2 * M_PI * $i)); 827 828 if($p > 0) { 829 $interval = 360 / $p; 830 } else { 831 $interval = 360; 832 } 833 834 $color = $this->color($i); 835 836 for($j = 0; $j < 360; $j += $interval) { 837 838 $rad = ($j / 360) * (2 * M_PI); 839 840 $x = round($i * cos($rad)); 841 $y = round($i * sin($rad)); 842 843 $l = sqrt($x * $x + $y * $y); 844 845 if($l <= $r) { 846 847 if( 848 array_key_exists((int)$x, $ok) === FALSE or 849 array_key_exists((int)$y, $ok[$x]) === FALSE 850 ) { 851 852 // Print the point 853 $this->drawer->point($color, new awPoint($c->x + $x, $c->y + $y)); 854 855 $ok[(int)$x][(int)$y] = TRUE; 856 857 } 858 859 } 860 861 } 862 863 $color->free(); 864 unset($color); 865 866 } 867 868 } 869 870 } 871 872 protected function ellipseLinearGradient(awGradient $gradient, $x1, $y1, $x2, $y2) { 873 874 // Gauche->droite : 90° 875 876 if($y1 - $y2 > 0) { 877 878 if($y1 - $y2 != $x2 - $x1) { 879 awImage::drawError("Class GradientDrawer: Linear gradients are only implemented on circle, not ellipses."); 880 } 881 882 $r = ($x2 - $x1) / 2; 883 884 // Init gradient 885 $this->init($gradient, $x2 - $x1); 886 887 for($i = -$r; $i <= $r; $i++) { 888 889 $h = sin(acos($i / $r)) * $r; 890 891 $color = $this->color($i + $r); 892 893 if($gradient->angle === 90) { 894 895 // Print the line 896 $p1 = new awPoint( 897 $x1 + $i + $r, 898 round(max($y2 + $r - $h + 1, $y2)) 899 ); 900 901 $p2 = new awPoint( 902 $x1 + $i + $r, 903 round(min($y1 - $r + $h - 1, $y1)) 904 ); 905 906 } else { 907 908 // Print the line 909 $p1 = new awPoint( 910 round(max($x1 + $r - $h + 1, $x1)), 911 $y2 + $i + $r 912 ); 913 914 $p2 = new awPoint( 915 round(min($x2 - $r + $h - 1, $x2)), 916 $y2 + $i + $r 917 ); 918 919 } 920 921 $this->drawer->filledRectangle($color, new awLine($p1, $p2)); 922 923 $color->free(); 924 unset($color); 925 926 } 927 928 } 929 930 } 931 932 protected function polygonLinearGradient(awLinearGradient $gradient, awPolygon $polygon) { 933 934 $count = $polygon->count(); 935 936 if($count >= 3) { 937 938 $left = $polygon->get(0); 939 $right = $polygon->get($count - 1); 940 941 if($gradient->angle === 0) { 942 943 // Get polygon maximum and minimum 944 $offset = $polygon->get(0); 945 $max = $min = $offset->y; 946 for($i = 1; $i < $count - 1; $i++) { 947 $offset = $polygon->get($i); 948 $max = max($max, $offset->y); 949 $min = min($min, $offset->y); 950 } 951 952 $this->init($gradient, $max - $min); 953 954 $prev = $polygon->get(1); 955 956 $sum = 0; 957 958 for($i = 2; $i < $count - 1; $i++) { 959 960 $current = $polygon->get($i); 961 962 $interval = 1; 963 964 if($i !== $count - 2) { 965 $current->x -= $interval; 966 } 967 968 if($current->x - $prev->x > 0) { 969 970 // Draw rectangle 971 $x1 = $prev->x; 972 $x2 = $current->x; 973 $y1 = max($prev->y, $current->y); 974 $y2 = $left->y; 975 976 $gradient = new awLinearGradient( 977 $this->color($max - $min - ($y2 - $y1)), 978 $this->color($max - $min), 979 0 980 ); 981 982 if($y1 > $y2) { 983 $y2 = $y1; 984 } 985 986 $this->drawer->filledRectangle( 987 $gradient, 988 awLine::build($x1, $y1, $x2, $y2) 989 ); 990 991 $top = ($prev->y < $current->y) ? $current : $prev; 992 $bottom = ($prev->y >= $current->y) ? $current : $prev; 993 994 $gradient = new awLinearGradient( 995 $this->color($bottom->y - $min), 996 $this->color($max - $min - ($y2 - $y1)), 997 0 998 ); 999 1000 1001 $gradientDrawer = new awGradientDrawer($this->drawer); 1002 $gradientDrawer->drawFilledFlatTriangle( 1003 $gradient, 1004 new awPoint($prev->x, min($prev->y, $current->y)), 1005 $top, 1006 new awPoint($current->x, min($prev->y, $current->y)) 1007 ); 1008 unset($gradientDrawer); 1009 1010 $sum += $current->x - $prev->x; 1011 1012 } 1013 1014 $prev = $current; 1015 $prev->x += $interval; 1016 1017 } 1018 1019 } else if($gradient->angle === 90) { 1020 1021 $width = $right->x - $left->x; 1022 $this->init($gradient, $width); 1023 1024 $pos = 1; 1025 $next = $polygon->get($pos++); 1026 1027 $this->next($polygon, $pos, $prev, $next); 1028 1029 for($i = 0; $i <= $width; $i++) { 1030 1031 $x = $left->x + $i; 1032 1033 $y1 = round($prev->y + ($next->y - $prev->y) * (($i + $left->x - $prev->x) / ($next->x - $prev->x))); 1034 $y2 = $left->y; 1035 1036 // Draw line 1037 $color = $this->color($i); 1038 // YaPB : PHP does not handle alpha on lines 1039 $this->drawer->filledRectangle($color, awLine::build($x, $y1, $x, $y2)); 1040 $color->free(); 1041 unset($color); 1042 1043 // Jump to next point 1044 if($next->x == $i + $left->x) { 1045 1046 $this->next($polygon, $pos, $prev, $next); 1047 1048 } 1049 1050 } 1051 1052 } 1053 1054 } 1055 1056 } 1057 1058 private function next($polygon, &$pos, &$prev, &$next) { 1059 1060 do { 1061 $prev = $next; 1062 $next = $polygon->get($pos++); 1063 } 1064 while($next->x - $prev->x == 0 and $pos < $polygon->count()); 1065 1066 } 1067 1068 /** 1069 * Start colors 1070 * 1071 * @var int 1072 */ 1073 private $r1, $g1, $b1, $a1; 1074 1075 /** 1076 * Stop colors 1077 * 1078 * @var int 1079 */ 1080 private $r2, $g2, $b2, $a2; 1081 1082 /** 1083 * Gradient size in pixels 1084 * 1085 * @var int 1086 */ 1087 private $size; 1088 1089 1090 private function init(awGradient $gradient, $size) { 1091 1092 list( 1093 $this->r1, $this->g1, $this->b1, $this->a1 1094 ) = $gradient->from->rgba(); 1095 1096 list( 1097 $this->r2, $this->g2, $this->b2, $this->a2 1098 ) = $gradient->to->rgba(); 1099 1100 $this->size = $size; 1101 } 1102 1103 private function color($pos) { 1104 1105 return new awColor( 1106 $this->getRed($pos), 1107 $this->getGreen($pos), 1108 $this->getBlue($pos), 1109 $this->getAlpha($pos) 1110 ); 1111 1112 } 1113 1114 1115 private function getRed($pos) { 1116 return (int)round($this->r1 + ($pos / $this->size) * ($this->r2 - $this->r1)); 1117 } 1118 1119 private function getGreen($pos) { 1120 return (int)round($this->g1 + ($pos / $this->size) * ($this->g2 - $this->g1)); 1121 } 1122 1123 private function getBlue($pos) { 1124 return (int)round($this->b1 + ($pos / $this->size) * ($this->b2 - $this->b1)); 1125 } 1126 1127 private function getAlpha($pos) { 1128 return (int)round(($this->a1 + ($pos / $this->size) * ($this->a2 - $this->a1)) / 127 * 100); 1129 } 1130 1131 } 1132 1133 registerClass('GradientDrawer'); 1134 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Thu Sep 6 14:14:11 2007 | par Balluche grâce à PHPXref 0.7 |