1<?php 2 3class Image_3D_Driver_SVG extends Image_3D_Driver 4{ 5 6 protected $_x; 7 protected $_y; 8 9 protected $_id; 10 11 protected $_gradients; 12 protected $_polygones; 13 14 public function __construct() 15 { 16 $this->_image = ''; 17 $this->_id = 1; 18 19 $this->_gradients = array(); 20 $this->_polygones = array(); 21 } 22 23 public function createImage($x, $y) 24 { 25 $this->_x = (int) $x; 26 $this->_y = (int) $y; 27 28 $this->_image = <<<EOF 29<?xml version="1.0" ?> 30<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 31 "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 32 33<svg xmlns="http://www.w3.org/2000/svg" x="0" y="0" width="{$this->_x}" height="{$this->_y}"> 34EOF; 35 36 $this->_image .= "\n\n"; 37 } 38 39 public function setBackground(Image_3D_Color $color) 40 { 41 $this->_addPolygon(sprintf("\t<polygon id=\"background%d\" points=\"0,0 %d,0 %d,%d 0,%d\" style=\"%s\" />\n", 42 $this->_id++, 43 $this->_x, 44 $this->_x, 45 $this->_y, 46 $this->_y, 47 $this->_getStyle($color))); 48 } 49 50 protected function _getStyle(Image_3D_Color $color) 51 { 52 $values = $color->getValues(); 53 54 $values[0] = (int) round($values[0] * 255); 55 $values[1] = (int) round($values[1] * 255); 56 $values[2] = (int) round($values[2] * 255); 57 $values[3] = 1 - $values[3]; 58 59 return sprintf('fill: #%02x%02x%02x; fill-opacity: %.2f; stroke: none;', $values[0], $values[1], $values[2], $values[3]); 60 } 61 62 protected function _getStop(Image_3D_Color $color, $offset = 0, $alpha = null) 63 { 64 $values = $color->getValues(); 65 66 $values[0] = (int) round($values[0] * 255); 67 $values[1] = (int) round($values[1] * 255); 68 $values[2] = (int) round($values[2] * 255); 69 if ($alpha === null) { 70 $values[3] = 1 - $values[3]; 71 } else { 72 $values[3] = 1 - $alpha; 73 } 74 75 return sprintf("\t\t\t<stop id=\"stop%d\" offset=\"%.1f\" style=\"stop-color: rgb(%d, %d, %d); stop-opacity: %.4f;\" />\n", $this->_id++, $offset, $values[0], $values[1], $values[2], $values[3]); 76 } 77 78 protected function _addGradient($string) 79 { 80 $id = 'linearGradient' . $this->_id++; 81 82 $this->_gradients[] = str_replace('[id]', $id, $string); 83 return $id; 84 } 85 86 protected function _addPolygon($string) 87 { 88 $id = 'polygon' . $this->_id++; 89 90 $this->_polygones[] = str_replace('[id]', $id, $string); 91 return $id; 92 } 93 94 public function drawPolygon(Image_3D_Polygon $polygon) 95 { 96 97 $list = ''; 98 $points = $polygon->getPoints(); 99 foreach ($points as $point) { 100 $pointarray = $point->getScreenCoordinates(); 101 102 $list .= sprintf('%.2f,%.2f ', $pointarray[0], $pointarray[1]); 103 } 104 105 $this->_addPolygon(sprintf("\t<polygon points=\"%s\" style=\"%s\" />\n", 106 substr($list, 0, -1), 107 $this->_getStyle($polygon->getColor()))); 108 } 109 110 public function drawGradientPolygon(Image_3D_Polygon $polygon) 111 { 112 $points = $polygon->getPoints(); 113 114 $list = ''; 115 116 $pointarray = array(); 117 foreach ($points as $nr => $point) { 118 $pointarray[$nr] = $point->getScreenCoordinates(); 119 120 $list .= sprintf('%.2f,%.2f ', $pointarray[$nr][0], $pointarray[$nr][1]); 121 } 122 123 // Groessen 124 $xOffset = min($pointarray[0][0], $pointarray[1][0], $pointarray[2][0]); 125 $yOffset = min($pointarray[0][1], $pointarray[1][1], $pointarray[2][1]); 126 127 $xSize = max(abs($pointarray[0][0] - $pointarray[1][0]), abs($pointarray[0][0] - $pointarray[2][0]), abs($pointarray[1][0] - $pointarray[2][0])); 128 $ySize = max(abs($pointarray[0][1] - $pointarray[1][1]), abs($pointarray[0][1] - $pointarray[2][1]), abs($pointarray[1][1] - $pointarray[2][1])); 129 130 // Base Polygon 131 $lg = $this->_addGradient(sprintf("\t\t<linearGradient id=\"[id]\" x1=\"%.2f\" y1=\"%.2f\" x2=\"%.2f\" y2=\"%.2f\">\n%s\t\t</linearGradient>\n", 132 ($pointarray[0][0] - $xOffset) / $xSize, 133 ($pointarray[0][1] - $yOffset) / $ySize, 134 ($pointarray[1][0] - $xOffset) / $xSize, 135 ($pointarray[1][1] - $yOffset) / $ySize, 136 $this->_getStop($points[0]->getColor()) . $this->_getStop($points[1]->getColor(), 1))); 137 138 $this->_addPolygon(sprintf("\t<polygon id=\"[id]\" points=\"%s\" style=\"fill: url(#%s); stroke: none; fill-opacity: 1;\" />\n", $list, $lg)); 139 140 // Overlay Polygon 141 $lg = $this->_addGradient(sprintf("\t\t<linearGradient id=\"[id]\" x1=\"%.2f\" y1=\"%.2f\" x2=\"%.2f\" y2=\"%.2f\">\n%s\t\t</linearGradient>\n", 142 ($pointarray[2][0] - $xOffset) / $xSize, 143 ($pointarray[2][1] - $yOffset) / $ySize, 144 ((($pointarray[0][0] + $pointarray[1][0]) / 2) - $xOffset) / $xSize, 145 ((($pointarray[0][1] + $pointarray[1][1]) / 2) - $yOffset) / $ySize, 146 $this->_getStop($points[2]->getColor()) . $this->_getStop($points[2]->getColor(), 1, 1))); 147 148 $this->_addPolygon(sprintf("\t<polygon id=\"[id]\" points=\"%s\" style=\"fill: url(#%s); stroke: none; fill-opacity: 1;\" />\n", $list, $lg)); 149 } 150 151 public function save($file) 152 { 153 $this->_image .= sprintf("\t<defs id=\"defs%d\">\n", $this->_id++); 154 $this->_image .= implode('', $this->_gradients); 155 $this->_image .= sprintf("\t</defs>\n\n"); 156 157 $this->_image .= implode('', $this->_polygones); 158 $this->_image .= "</svg>\n"; 159 file_put_contents($file, $this->_image); 160 } 161 162 public function getSupportedShading() 163 { 164 return array(Image_3D_Renderer::SHADE_NO, Image_3D_Renderer::SHADE_FLAT, Image_3D_Renderer::SHADE_GAUROUD); 165 } 166} 167 168?> 169