2010-11-26 13:00:12 +01:00
< ?
2010-11-26 16:07:16 +01:00
// TODO
// prendre en compte l'opacité grâce à imagecolorallocatealpha ?
2010-11-29 16:05:45 +01:00
// ajout de title
2010-11-29 18:03:06 +01:00
// ajout de <text fill="#000000" x="541" y="258" transform="rotate(-0, 541, 258)" font-size="10" font-family="SansSerif" font-style="normal" font-weight="normal">0</text>
2010-11-26 16:07:16 +01:00
2010-11-26 13:00:12 +01:00
include 'log.php' ;
2010-11-29 16:05:45 +01:00
2010-11-26 13:00:12 +01:00
class SVGTOIMAGE {
protected $_svgXML ;
protected $_image ;
protected $_log ;
protected $_x ;
protected $_y ;
protected $_width ;
protected $_height ;
protected $_showDesc = false ;
2010-11-29 16:05:45 +01:00
protected $_desc ;
2011-03-21 11:15:20 +01:00
protected $_currentOptions = array ();
2010-11-26 13:00:12 +01:00
private $transparentColor = array ( 0 , 0 , 255 );
2010-11-29 16:50:24 +01:00
public $_debug = true ; // change to false to stop debug mode
2010-11-29 18:03:06 +01:00
2010-11-30 13:17:40 +01:00
/*
* array of path type
*/
private $pathType = array (
'm' => 'MoveTo' ,
'l' => 'LineTo' ,
'h' => 'HorizontalLineTo' ,
'v' => 'VerticalLineTo' ,
'c' => 'CurveTo' ,
'z' => 'EndingLine' ,
);
2011-03-16 11:59:32 +01:00
/* array of color names => rgb color
2010-11-29 16:05:45 +01:00
because some svg creator uses them
2011-03-16 11:59:32 +01:00
used http :// www . yoyodesign . org / doc / w3c / svg1 / types . html #ColorKeywords
2010-11-29 16:05:45 +01:00
*/
2010-11-26 18:18:17 +01:00
private $colors = array (
2011-03-16 11:59:32 +01:00
'aliceblue' => array ( 240 , 248 , 255 ),
'antiquewhite' => array ( 250 , 235 , 215 ),
'aqua' => array ( 0 , 255 , 255 ),
'aquamarine' => array ( 127 , 255 , 212 ),
'azure' => array ( 240 , 255 , 255 ),
'beige' => array ( 245 , 245 , 220 ),
'bisque' => array ( 255 , 228 , 196 ),
'black' => array ( 0 , 0 , 0 ),
'blanchedalmond' => array ( 255 , 235 , 205 ),
'blue' => array ( 0 , 0 , 255 ),
'blueviolet' => array ( 138 , 43 , 226 ),
'brown' => array ( 165 , 42 , 42 ),
'burlywood' => array ( 222 , 184 , 135 ),
'cadetblue' => array ( 95 , 158 , 160 ),
'chartreuse' => array ( 127 , 255 , 0 ),
'chocolate' => array ( 210 , 105 , 30 ),
'coral' => array ( 255 , 127 , 80 ),
'cornflowerblue' => array ( 100 , 149 , 237 ),
'cornsilk' => array ( 255 , 248 , 220 ),
'crimson' => array ( 220 , 20 , 60 ),
'cyan' => array ( 0 , 255 , 255 ),
'darkblue' => array ( 0 , 0 , 139 ),
'darkcyan' => array ( 0 , 139 , 139 ),
'darkgoldenrod' => array ( 184 , 134 , 11 ),
'darkgray' => array ( 169 , 169 , 169 ),
'darkgreen' => array ( 0 , 100 , 0 ),
'darkgrey' => array ( 169 , 169 , 169 ),
'darkkhaki' => array ( 189 , 183 , 107 ),
'darkmagenta' => array ( 139 , 0 , 139 ),
'darkolivegreen' => array ( 85 , 107 , 47 ),
'darkorange' => array ( 255 , 140 , 0 ),
'darkorchid' => array ( 153 , 50 , 204 ),
'darkred' => array ( 139 , 0 , 0 ),
'darksalmon' => array ( 233 , 150 , 122 ),
'darkseagreen' => array ( 143 , 188 , 143 ),
'darkslateblue' => array ( 72 , 61 , 139 ),
'darkslategray' => array ( 47 , 79 , 79 ),
'darkslategrey' => array ( 47 , 79 , 79 ),
'darkturquoise' => array ( 0 , 206 , 209 ),
'darkviolet' => array ( 148 , 0 , 211 ),
'deeppink' => array ( 255 , 20 , 147 ),
'deepskyblue' => array ( 0 , 191 , 255 ),
'dimgray' => array ( 105 , 105 , 105 ),
'dimgrey' => array ( 105 , 105 , 105 ),
'dodgerblue' => array ( 30 , 144 , 255 ),
'firebrick' => array ( 178 , 34 , 34 ),
'floralwhite' => array ( 255 , 250 , 240 ),
'forestgreen' => array ( 34 , 139 , 34 ),
'fuchsia' => array ( 255 , 0 , 255 ),
'gainsboro' => array ( 220 , 220 , 220 ),
'ghostwhite' => array ( 248 , 248 , 255 ),
'gold' => array ( 255 , 215 , 0 ),
'goldenrod' => array ( 218 , 165 , 32 ),
'gray' => array ( 128 , 128 , 128 ),
'grey' => array ( 128 , 128 , 128 ),
'green' => array ( 0 , 128 , 0 ),
'greenyellow' => array ( 173 , 255 , 47 ),
'honeydew' => array ( 240 , 255 , 240 ),
'hotpink' => array ( 255 , 105 , 180 ),
'indianred' => array ( 205 , 92 , 92 ),
'indigo' => array ( 75 , 0 , 130 ),
'ivory' => array ( 255 , 255 , 240 ),
'khaki' => array ( 240 , 230 , 140 ),
'lavender' => array ( 230 , 230 , 250 ),
'lavenderblush' => array ( 255 , 240 , 245 ),
'lawngreen' => array ( 124 , 252 , 0 ),
'lemonchiffon' => array ( 255 , 250 , 205 ),
'lightblue' => array ( 173 , 216 , 230 ),
'lightcoral' => array ( 240 , 128 , 128 ),
'lightcyan' => array ( 224 , 255 , 255 ),
'lightgoldenrodyellow' => array ( 250 , 250 , 210 ),
'lightgray' => array ( 211 , 211 , 211 ),
'lightgreen' => array ( 144 , 238 , 144 ),
'lightgrey' => array ( 211 , 211 , 211 ),
'lightpink' => array ( 255 , 182 , 193 ),
'lightsalmon' => array ( 255 , 160 , 122 ),
'lightseagreen' => array ( 32 , 178 , 170 ),
'lightskyblue' => array ( 135 , 206 , 250 ),
'lightslategray' => array ( 119 , 136 , 153 ),
'lightslategrey' => array ( 119 , 136 , 153 ),
'lightsteelblue' => array ( 176 , 196 , 222 ),
'lightyellow' => array ( 255 , 255 , 224 ),
'lime' => array ( 0 , 255 , 0 ),
'limegreen' => array ( 50 , 205 , 50 ),
'linen' => array ( 250 , 240 , 230 ),
'magenta' => array ( 255 , 0 , 255 ),
'maroon' => array ( 128 , 0 , 0 ),
'mediumaquamarine' => array ( 102 , 205 , 170 ),
'mediumblue' => array ( 0 , 0 , 205 ),
'mediumorchid' => array ( 186 , 85 , 211 ),
'mediumpurple' => array ( 147 , 112 , 219 ),
'mediumseagreen' => array ( 60 , 179 , 113 ),
'mediumslateblue' => array ( 123 , 104 , 238 ),
'mediumspringgreen' => array ( 0 , 250 , 154 ),
'mediumturquoise' => array ( 72 , 209 , 204 ),
'mediumvioletred' => array ( 199 , 21 , 133 ),
'midnightblue' => array ( 25 , 25 , 112 ),
'mintcream' => array ( 245 , 255 , 250 ),
'mistyrose' => array ( 255 , 228 , 225 ),
'moccasin' => array ( 255 , 228 , 181 ),
'navajowhite' => array ( 255 , 222 , 173 ),
'navy' => array ( 0 , 0 , 128 ),
'oldlace' => array ( 253 , 245 , 230 ),
'olive' => array ( 128 , 128 , 0 ),
'olivedrab' => array ( 107 , 142 , 35 ),
'orange' => array ( 255 , 165 , 0 ),
'orangered' => array ( 255 , 69 , 0 ),
'orchid' => array ( 218 , 112 , 214 ),
'palegoldenrod' => array ( 238 , 232 , 170 ),
'palegreen' => array ( 152 , 251 , 152 ),
'paleturquoise' => array ( 175 , 238 , 238 ),
'palevioletred' => array ( 219 , 112 , 147 ),
'papayawhip' => array ( 255 , 239 , 213 ),
'peachpuff' => array ( 255 , 218 , 185 ),
'peru' => array ( 205 , 133 , 63 ),
'pink' => array ( 255 , 192 , 203 ),
'plum' => array ( 221 , 160 , 221 ),
'powderblue' => array ( 176 , 224 , 230 ),
'purple' => array ( 128 , 0 , 128 ),
'red' => array ( 255 , 0 , 0 ),
'rosybrown' => array ( 188 , 143 , 143 ),
'royalblue' => array ( 65 , 105 , 225 ),
'saddlebrown' => array ( 139 , 69 , 19 ),
'salmon' => array ( 250 , 128 , 114 ),
'sandybrown' => array ( 244 , 164 , 96 ),
'seagreen' => array ( 46 , 139 , 87 ),
'seashell' => array ( 255 , 245 , 238 ),
'sienna' => array ( 160 , 82 , 45 ),
'silver' => array ( 192 , 192 , 192 ),
'skyblue' => array ( 135 , 206 , 235 ),
'slateblue' => array ( 106 , 90 , 205 ),
'slategray' => array ( 112 , 128 , 144 ),
'slategrey' => array ( 112 , 128 , 144 ),
'snow' => array ( 255 , 250 , 250 ),
'springgreen' => array ( 0 , 255 , 127 ),
'steelblue' => array ( 70 , 130 , 180 ),
'tan' => array ( 210 , 180 , 140 ),
'teal' => array ( 0 , 128 , 128 ),
'thistle' => array ( 216 , 191 , 216 ),
'tomato' => array ( 255 , 99 , 71 ),
'turquoise' => array ( 64 , 224 , 208 ),
'violet' => array ( 238 , 130 , 238 ),
'wheat' => array ( 245 , 222 , 179 ),
'white' => array ( 255 , 255 , 255 ),
'whitesmoke' => array ( 245 , 245 , 245 ),
'yellow' => array ( 255 , 255 , 0 ),
'yellowgreen' => array ( 154 , 205 , 50 )
2010-11-26 18:18:17 +01:00
);
2011-03-21 11:15:20 +01:00
/**
2010-11-29 16:05:45 +01:00
* constructor
* parse the svg with simplexml
*/
public function __construct ( $svg ){
2010-11-26 13:00:12 +01:00
if ( $this -> _debug ) $this -> _log = new Log ( 'log.dat' );
2010-11-29 16:05:45 +01:00
$this -> _svgXML = simplexml_load_string ( $svg );
2010-11-26 13:00:12 +01:00
}
2011-03-21 11:15:20 +01:00
/**
2010-11-29 16:05:45 +01:00
* Construct with a file
* @ param : string path to the file
* @ return : instance of this class
*/
2010-11-26 13:00:12 +01:00
public static function load ( $file ){
$svg = file_get_contents ( $file );
return new SVGTOIMAGE ( $svg );
}
2011-03-21 11:15:20 +01:00
/**
2010-11-29 16:05:45 +01:00
* Construct with a string
* @ param : string < svg >...</ svg >
* @ return : instance of this class
*/
2010-11-26 13:00:12 +01:00
public static function parse ( $xml ){
return new SVGTOIMAGE ( $xml );
}
2011-03-21 11:15:20 +01:00
/**
2010-11-29 16:05:45 +01:00
* Destroy the GD Image when finished
*/
2010-11-26 13:00:12 +01:00
public function __destruct (){
imagedestroy ( $this -> _image );
}
2011-03-21 11:15:20 +01:00
/**
2010-11-29 16:05:45 +01:00
* setter - option : show the description from the svg into the image if present
* @ param boolean
*/
2010-11-26 13:00:12 +01:00
public function setShowDesc ( $showDesc = true ){
if ( is_bool ( $showDesc )){
2011-03-21 11:15:20 +01:00
//if($this->_debug) $this->_log->message('Passage de showDesc en '.$showDesc);
2010-11-26 13:00:12 +01:00
$this -> _showDesc = $showDesc ;
} else {
if ( $this -> _debug ) $this -> _log -> error ( 'Erreur dans la fonction showDesc, doit recevoir booléen, a reçu : ' . $showDesc );
}
}
2011-03-21 11:15:20 +01:00
/**
2010-11-29 16:05:45 +01:00
* setter - option : origin of the final image from the svg ( default : 0 )
* @ param int
*/
2010-11-26 13:00:12 +01:00
public function setX ( $x ){
if ( is_int ( $x )){
2011-03-21 11:15:20 +01:00
//if($this->_debug) $this->_log->message('Passage de x en '.$x);
2010-11-26 13:00:12 +01:00
$this -> _x = $x ;
} else {
if ( $this -> _debug ) $this -> _log -> error ( 'Erreur dans la fonction setX, doit recevoir int, a reçu : ' . $x );
}
}
2010-11-29 16:05:45 +01:00
/*
* setter - option : origin of the final image from the svg ( default : 0 )
* @ param int
*/
2010-11-26 13:00:12 +01:00
public function setY ( $y ){
if ( is_int ( $y )){
2011-03-21 11:15:20 +01:00
//if($this->_debug) $this->_log->message('Passage de y en '.$y);
2010-11-26 13:00:12 +01:00
$this -> _y = $y ;
} else {
if ( $this -> _debug ) $this -> _log -> error ( 'Erreur dans la fonction setY, doit recevoir int, a reçu : ' . $y );
}
}
2010-11-29 16:05:45 +01:00
/*
* setter - option : width of the final image ( default : svg width )
* @ param int
*/
2010-11-26 13:00:12 +01:00
public function setWidth ( $width ){
if ( is_int ( $width )){
2011-03-21 11:15:20 +01:00
//if($this->_debug) $this->_log->message('Passage de width en '.$width);
2010-11-26 13:00:12 +01:00
$this -> _width = $width ;
} else {
if ( $this -> _debug ) $this -> _log -> error ( 'Erreur dans la fonction setWidth, doit recevoir int, a reçu : ' . $width );
}
}
2010-11-29 16:05:45 +01:00
/*
* setter - option : height of the final image ( default : svg height )
* @ param int
*/
2010-11-26 13:00:12 +01:00
public function setHeight ( $height ){
if ( is_int ( $height )){
2011-03-21 11:15:20 +01:00
//if($this->_debug) $this->_log->message('Passage de height en '.$height);
2010-11-26 13:00:12 +01:00
$this -> _height = $height ;
} else {
if ( $this -> _debug ) $this -> _log -> error ( 'Erreur dans la fonction setHeight, doit recevoir int, a reçu : ' . $height );
}
}
2010-12-01 12:38:30 +01:00
/*
* DEPRECATED
* return width and height from the SVG
*/
2010-11-26 13:00:12 +01:00
private function _getImageSize (){
$imageSize = array ();
$imageSize [ 'width' ] = $this -> _svgXML -> attributes () -> width ;
$imageSize [ 'height' ] = $this -> _svgXML -> attributes () -> height ;
2011-03-21 11:15:20 +01:00
if ( $this -> _debug ) $this -> _log -> message ( 'taille de l\'image : ' . Log :: decode ( $imageSize ));
2010-11-26 13:00:12 +01:00
return $imageSize ;
}
2011-03-16 11:59:32 +01:00
/**
* @ param string size of picture or element
* @ return int " real " size of element . To eliminate SVG with centimeters
*/
private function _getSizeType ( $value ){
$value = rtrim ( $value );
switch ( substr ( $value , - 2 , 2 )){
case 'cm' :
return $value * 30 ; // approximatively
break ;
case 'in' :
return $value * 12 ; // approximatively
break ;
case 'px' :
case 'pt' :
default :
return $value ;
}
}
2011-03-21 11:15:20 +01:00
/**
2010-11-29 16:05:45 +01:00
* @ return int final image width
*/
2010-11-26 13:00:12 +01:00
private function _getImageWidth (){
2011-03-16 11:59:32 +01:00
return isset ( $this -> _width ) ? $this -> _width : $this -> _getSizeType ( $this -> _svgXML -> attributes () -> width );
2010-11-26 13:00:12 +01:00
}
2011-03-21 11:15:20 +01:00
/**
2010-11-29 16:05:45 +01:00
* @ return int final image height
*/
2010-11-26 13:00:12 +01:00
private function _getImageHeight (){
2011-03-16 11:59:32 +01:00
return isset ( $this -> _height ) ? $this -> _height : $this -> _getSizeType ( $this -> _svgXML -> attributes () -> height );
2010-11-26 13:00:12 +01:00
}
2010-11-29 16:05:45 +01:00
/*
* @ param string Color code ( ie : #CCC , #FE4323, etc...)
* @ return array with R | G | B
*/
2010-11-26 13:00:12 +01:00
private function _parseColor ( $colorCode ){
2011-03-16 11:59:32 +01:00
if ( is_string ( $colorCode ) && strlen ( $colorCode ) == 7 ){
2011-03-21 11:15:20 +01:00
$convert = array (
2010-11-26 13:00:12 +01:00
base_convert ( substr ( $colorCode , 1 , 2 ), 16 , 10 ),
base_convert ( substr ( $colorCode , 3 , 2 ), 16 , 10 ),
base_convert ( substr ( $colorCode , 5 , 2 ), 16 , 10 ),
);
2011-03-21 11:15:20 +01:00
return $convert ;
2010-11-26 13:00:12 +01:00
}
2011-03-16 11:59:32 +01:00
if ( is_string ( $colorCode ) && strlen ( $colorCode ) == 4 ){
2010-11-26 13:00:12 +01:00
return array (
base_convert ( substr ( $colorCode , 1 , 1 ) . substr ( $colorCode , 1 , 1 ), 16 , 10 ),
base_convert ( substr ( $colorCode , 2 , 1 ) . substr ( $colorCode , 2 , 1 ), 16 , 10 ),
base_convert ( substr ( $colorCode , 3 , 1 ) . substr ( $colorCode , 3 , 1 ), 16 , 10 ),
);
}
2011-03-16 11:59:32 +01:00
if ( is_array ( $colorCode ) && count ( $colorCode ) == 3 ){
return $colorCode ;
}
2011-03-21 11:15:20 +01:00
if ( $this -> _debug ) $this -> _log -> error ( 'Couleur mal indiquée ' . Log :: decode ( $colorCode ));
2011-03-16 11:59:32 +01:00
return array ( 0 , 0 , 0 ); // !#FFF || !#FFFFFF || !array(255,255,255) then black
2010-11-26 13:00:12 +01:00
}
2011-03-21 11:15:20 +01:00
/**
2010-11-29 16:05:45 +01:00
* Allocate color to the final image thanks to _parseColor ( check if the color isn 't spelled directly ' black ' )
* @ param string color code
* @ return imageallocate on the image
*/
2010-11-26 16:07:16 +01:00
private function _allocateColor ( $color ){
2010-11-29 16:05:45 +01:00
if ( $color != '' && array_key_exists ( strtolower ( $color ), $this -> colors )){
2011-03-21 11:15:20 +01:00
$arrayColor = $this -> _parseColor ( $this -> colors [ strtolower ( $color )]);
2011-03-16 11:59:32 +01:00
} elseif ( $color != '' ){
2010-11-26 18:18:17 +01:00
$arrayColor = $this -> _parseColor ( $color );
2011-03-16 11:59:32 +01:00
} else return ;
2010-11-26 16:07:16 +01:00
return imagecolorallocate ( $this -> _image , $arrayColor [ 0 ], $arrayColor [ 1 ], $arrayColor [ 2 ] );
}
2011-03-21 11:15:20 +01:00
/**
2010-11-29 18:03:06 +01:00
* return an array to use with imagesetstyle
* @ param allocatecolorimage
* @ return array
*/
private function _getDashedStroke ( $full , $empty , $color ){
$tiret = array ();
for ( $i = 0 ; $i < $full ; $i ++ ){
$tiret [] = $color ;
}
for ( $i = 0 ; $i < $empty ; $i ++ ){
$tiret [] = IMG_COLOR_TRANSPARENT ;
}
2011-03-21 11:15:20 +01:00
if ( $this -> _debug ) $this -> _log -> message ( 'nouveaux tirets : ' . Log :: decode ( $tiret ));
2010-11-29 18:03:06 +01:00
return $tiret ;
}
2011-03-21 11:15:20 +01:00
private function _getParam ( $paramName ){
$currentOptions = $this -> _getAllParams ();
return isset ( $currentOptions [ $paramName ]) ? $currentOptions [ $paramName ] : null ;
}
private function _getAllParams (){
$newarr = array ();
foreach ( $this -> _currentOptions as $array )
$newarr = array_merge ( $newarr , $array );
return $newarr ;
}
2011-03-16 11:59:32 +01:00
/**
* @ param node $element
* @ return array options
*/
private function _getParams ( $element ){
2011-03-21 11:15:20 +01:00
$options = $this -> _getAllParams ();
2011-03-16 11:59:32 +01:00
foreach ( $element -> attributes () as $name => $value ){
switch ( $name ){
case 'x' :
case 'y' :
case 'r' :
case 'width' :
case 'height' :
$options [ $name ] = $this -> _getSizeType ( $value );
break ;
case 'cx' :
$options [ 'x' ] = $this -> _getSizeType ( $value );
break ;
case 'cy' :
$options [ 'y' ] = $this -> _getSizeType ( $value );
break ;
case 'xlink:href' :
$options [ 'href' ] = $value ;
break ;
case 'd' :
case 'points' :
$options [ 'path' ] = $value ;
break ;
case 'fill' :
$options [ 'fill' ] = ( $value == 'none' ) ? '' : $value ;
break ;
case 'stroke-width' :
$options [ 'strokeWidth' ] = $value ;
break ;
case 'stroke-dasharray' :
$options [ 'strokeDasharray' ] = $value ;
break ;
case 'font-size' :
$options [ 'fontSize' ] = $value ;
break ;
case 'font-family' :
$options [ 'fontFamily' ] = $value ;
break ;
case 'font-style' :
$options [ 'fontStyle' ] = $value ;
break ;
case 'font-weight' :
$options [ 'fontWeight' ] = $value ;
break ;
2011-03-21 11:15:20 +01:00
case 'transform' : // transform="matrix(1.006896,0,0,1.006896,0.3043,-0.708342)"
$transform = split ( '[()]' , $value );
if ( count ( $transform ) == 3 ){
$typeTransform = $transform [ 0 ];
switch ( $typeTransform ){
case 'translate' :
list ( $options [ 'originX' ], $options [ 'originY' ]) = explode ( ',' , $transform [ 1 ]);
break ;
case 'rotate' :
$options [ 'rotate' ] = $transform [ 1 ];
break ;
case 'scale' :
$options [ 'scale' ] = $transform [ 1 ];
break ;
default :
break ;
}
}
break ;
case 'style' :
$allStyle = split ( '[;:]' , $value );
$i = 0 ;
while ( $i < count ( $allStyle )) {
if ( $allStyle [ $i ] == 'display' && $allStyle [ $i + 1 ] == 'none' ) return ; // display:none? Stop looking for info
if ( $allStyle [ $i ] == 'fill' ) $options [ 'fill' ] = $allStyle [ $i + 1 ];
if ( $allStyle [ $i ] == 'stroke' ) $options [ 'stroke' ] = $allStyle [ $i + 1 ];
if ( $allStyle [ $i ] == 'stroke-width' ) $options [ 'strokeWidth' ] = $allStyle [ $i + 1 ];
$i = $i + 2 ;
}
break ;
2011-03-16 11:59:32 +01:00
default :
$options [ $name ] = $value ;
break ;
}
}
2011-03-21 11:15:20 +01:00
/* if ( $this -> _debug ){
$this -> _log -> message ( '-------- option ---------' );
foreach ( $options as $key => $value ){
$this -> _log -> message ( 'option : ' . ( string ) $key . ' -> ' . ( string ) $value );
}
$this -> _log -> message ( '------- /option/ --------' );
} */
//if($this->_debug) $this->_log->message('options : '.Log::decode($options));
2011-03-16 11:59:32 +01:00
return $options ;
}
2011-03-21 11:15:20 +01:00
/**
2010-11-29 16:05:45 +01:00
* add the given image from svg to the final image
* @ param simpleXMLElement
* @ return imagecopy
*/
2010-11-26 13:00:12 +01:00
private function _parseImage ( $imageNode ){
$x = 0 ;
$y = 0 ;
$width = 0 ;
$height = 0 ;
$href = '' ;
2010-11-29 16:05:45 +01:00
$transform = '' ;
2010-11-26 13:00:12 +01:00
$r = 0 ;
2011-03-16 11:59:32 +01:00
extract ( $this -> _getParams ( $imageNode ));
2011-03-21 11:15:20 +01:00
//case translate
if ( $this -> _getParam ( 'originX' ) !== null )
$x += $this -> _getParam ( 'originX' );
if ( $this -> _getParam ( 'originY' ) !== null )
$y += $this -> _getParam ( 'originY' );
//end translate
2010-11-29 16:05:45 +01:00
if ( $transform != '' ){
$transforms = split ( '[()]' , $transform );
$nb = count ( $transforms );
for ( $i = 0 ; $i < $nb ; $i ++ ){
// rotation
if ( $transforms [ $i ] == 'rotate' ){
$rotinfo = $transforms [ $i + 1 ];
$rotinfo = explode ( ' ' , $rotinfo );
$r = $rotinfo [ 0 ];
}
}
}
2010-11-26 13:00:12 +01:00
if ( $width == 0 || $height == 0 || $href == '' )
return ;
$imageTypeArray = explode ( '.' , $href );
$lastElementFromImageType = count ( $imageTypeArray );
$imageType = $imageTypeArray [ $lastElementFromImageType - 1 ];
if ( $imageType == 'jpg' || $imageType == 'jpeg' )
$newImage = imagecreatefromjpeg ( $href );
else if ( $imageType == 'png' )
$newImage = imagecreatefrompng ( $href );
else if ( $imageType == 'gif' )
$newImage = imagecreatefromgif ( $href );
else return ;
imagealphablending ( $newImage , true );
//rotating the image if needed
if ( $r != 0 ){
if ( $this -> _debug ){
2010-11-29 16:38:44 +01:00
if ( $newImage = imagerotate ( $newImage , - floatval ( $r ), - 1 )){
2010-11-26 13:00:12 +01:00
$this -> _log -> message ( 'Rotating image' );
2010-11-29 16:38:44 +01:00
} else
2010-11-26 13:00:12 +01:00
$this -> _log -> error ( 'Rotating image' );
} else {
$newImage = imagerotate ( $newImage , - floatval ( $r ), - 1 );
}
$blue = imagecolorallocate ( $newImage , $this -> transparentColor [ 0 ], $this -> transparentColor [ 1 ], $this -> transparentColor [ 2 ]);
imagecolortransparent ( $newImage , $blue );
}
2010-11-29 16:38:44 +01:00
$newWidth = imagesx ( $newImage );
$newHeight = imagesy ( $newImage );
2010-11-29 16:50:24 +01:00
imagecopy ( $this -> _image , $newImage ,( $newWidth == $width ) ? $x : $x - ( $newWidth - $width ) / 2 ,( $newHeight == $height ) ? $y : $y - ( $newHeight - $height ) / 2 , 0 , 0 , imagesx ( $newImage ) , imagesy ( $newImage )); // Thanks Raphael & GD for saying things wrong.
2010-11-26 13:00:12 +01:00
}
2011-03-21 11:15:20 +01:00
/**
2010-11-29 16:05:45 +01:00
* Check if the given SVG xml is W3C valid
2010-11-29 16:50:24 +01:00
* DEPRECATED and unused anymore
2010-11-29 16:05:45 +01:00
* @ param string < svg >...</ svg >
* @ return boolean
*/
2010-11-26 18:18:17 +01:00
private function _pathIsW3C ( $path ){
if ( strripos ( $path , ',' ))
return true ;
return false ;
}
2011-03-21 11:15:20 +01:00
/**
2010-11-29 16:05:45 +01:00
* small function to find int into a string - works like java parseint
* @ param string containing numbers
* @ return int
*/
2010-11-26 18:18:17 +01:00
private function _parseInt ( $string ){
2011-03-21 11:15:20 +01:00
if ( preg_match ( '/[-]?(\d+)/' , $string , $array )) return $array [ 0 ];
else return 0 ;
2010-11-26 18:18:17 +01:00
}
2011-03-21 11:15:20 +01:00
/**
2010-11-29 16:05:45 +01:00
* add a line to the final image
* @ param $x1 , $y1 , $x2 , $y2 int position of segment
* @ param imagecolorallocate color ( via _allocatecolor ! )
* @ return imageline
*/
2010-11-26 20:37:48 +01:00
private function _drawLine ( $x1 , $y1 , $x2 , $y2 , $color ){
if ( ! imageline ( $this -> _image , $x1 , $y1 , $x2 , $y2 , $color )){
if ( $this -> _debug ) $this -> _log -> error ( 'Chemin erroné : ' . $x1 . ' - ' . $y1 . ' - ' . $x2 . ' - ' . $y2 );
} else {
if ( $this -> _debug ) $this -> _log -> message ( 'Chemin : ' . $x1 . ' - ' . $y1 . ' - ' . $x2 . ' - ' . $y2 );
}
}
2011-03-21 11:15:20 +01:00
/**
2010-11-30 13:17:40 +01:00
* add a curve to the final image
* @ param $startX , $startY , $control1X , $control1Y , $control2X , $control2Y , $endX , $endY int position of start , controls and end points
* @ param imagecolorallocate color ( via _allocatecolor ! )
* @ return lots of imagesetpixel
* Algorithme de http :// www . dreamstube . com / post / Bezier - Curves - In - PHP !. aspx
*/
private function _drawCurve ( $startX , $startY , $control1X , $control1Y , $control2X , $control2Y , $endX , $endY , $color ){
$cx = 3 * ( $control1X - $startX );
$bx = 3 * ( $control2X - $control1X ) - $cx ;
$ax = $endX - $startX - $cx - $bx ;
$cy = 3 * ( $control1Y - $startY );
$by = 3 * ( $control2Y - $control1Y ) - $cy ;
$ay = $endY - $startY - $cy - $by ;
2011-03-16 11:59:32 +01:00
//if($this->_debug) $this->_log->message('ax : '.$ax.', ay : '.$ay);
2010-11-30 13:17:40 +01:00
for ( $t = 0 ; $t < 1 ; $t +=. 01 )
{
$xt = $ax * $t * $t * $t + $bx * $t * $t + $cx * $t + $startX ;
$yt = $ay * $t * $t * $t + $by * $t * $t + $cy * $t + $startY ;
imagesetpixel ( $this -> _image , $xt , $yt , $color );
}
}
2011-03-16 11:59:32 +01:00
/*EXPERIMENT*/
// Calculate the coordinate of the Bezier curve at $t = 0..1
private function _Bezier_eval ( $p1 , $p2 , $p3 , $p4 , $t ) {
// lines between successive pairs of points (degree 1)
$q1 = array (( 1 - $t ) * $p1 [ 0 ] + $t * $p2 [ 0 ],( 1 - $t ) * $p1 [ 1 ] + $t * $p2 [ 1 ]);
$q2 = array (( 1 - $t ) * $p2 [ 0 ] + $t * $p3 [ 0 ],( 1 - $t ) * $p2 [ 1 ] + $t * $p3 [ 1 ]);
$q3 = array (( 1 - $t ) * $p3 [ 0 ] + $t * $p4 [ 0 ],( 1 - $t ) * $p3 [ 1 ] + $t * $p4 [ 1 ]);
// curves between successive pairs of lines. (degree 2)
$r1 = array (( 1 - $t ) * $q1 [ 0 ] + $t * $q2 [ 0 ],( 1 - $t ) * $q1 [ 1 ] + $t * $q2 [ 1 ]);
$r2 = array (( 1 - $t ) * $q2 [ 0 ] + $t * $q3 [ 0 ],( 1 - $t ) * $q2 [ 1 ] + $t * $q3 [ 1 ]);
// final curve between the two 2-degree curves. (degree 3)
return array (( 1 - $t ) * $r1 [ 0 ] + $t * $r2 [ 0 ],( 1 - $t ) * $r1 [ 1 ] + $t * $r2 [ 1 ]);
}
// Calculate the squared distance between two points
private function _Point_distance2 ( $p1 , $p2 ) {
$dx = $p2 [ 0 ] - $p1 [ 0 ];
$dy = $p2 [ 1 ] - $p1 [ 1 ];
return $dx * $dx + $dy * $dy ;
}
// Convert the curve to a polyline
private function _Bezier_convert ( $p1 , $p2 , $p3 , $p4 , $tolerance ) {
$t1 = 0.0 ;
$prev = $p1 ;
$t2 = 0.1 ;
$tol2 = $tolerance * $tolerance ;
$result [] = $prev [ 0 ];
$result [] = $prev [ 1 ];
while ( $t1 < 1.0 ) {
if ( $t2 > 1.0 ) {
$t2 = 1.0 ;
}
$next = $this -> _Bezier_eval ( $p1 , $p2 , $p3 , $p4 , $t2 );
$dist = $this -> _Point_distance2 ( $prev , $next );
while ( $dist > $tol2 ) {
// Halve the distance until small enough
$t2 = $t1 + ( $t2 - $t1 ) * 0.5 ;
$next = $this -> _Bezier_eval ( $p1 , $p2 , $p3 , $p4 , $t2 );
$dist = $this -> _Point_distance2 ( $prev , $next );
}
// the image*polygon functions expect a flattened array of coordiantes
$result [] = $next [ 0 ];
$result [] = $next [ 1 ];
$t1 = $t2 ;
$prev = $next ;
$t2 = $t1 + 0.1 ;
}
return $result ;
}
// Draw a Bezier curve on an image
private function _Bezier_drawfilled ( $p1 , $p2 , $p3 , $p4 , $color ) {
$polygon = $this -> _Bezier_convert ( $p1 , $p2 , $p3 , $p4 , 0.1 );
return $polygon ;
}
/*END OF EXPERIMENT*/
private function _drawPolygon ( $polygon , $stroke , $fill = '' ){
2011-03-21 11:15:20 +01:00
//if($this->_debug) $this->_log->message('_drawPolygon : fill : '.$fill.' stroke:'.$stroke);
if ( $fill !== '' && count ( $polygon ) >= 6 ){
//if($this->_debug) $this->_log->message('polygon rempli : '.$fill);
imagefilledpolygon ( $this -> _image , $polygon , count ( $polygon ) / 2 , $fill );
imagepolygon ( $this -> _image , $polygon , count ( $polygon ) / 2 , $stroke );
} elseif ( count ( $polygon ) >= 6 ){
//if($this->_debug) $this->_log->message('polygon non rempli : '.$stroke);
imagepolygon ( $this -> _image , $polygon , count ( $polygon ) / 2 , $stroke );
//imagepolygon($this->_image, $polygon, count($polygon)/2, IMG_COLOR_STYLED);
} elseif ( count ( $polygon ) == 4 ){
//if($this->_debug) $this->_log->message('ligne via polygon : '.$stroke);
$this -> _drawLine ( $polygon [ 0 ], $polygon [ 1 ], $polygon [ 2 ], $polygon [ 3 ], $stroke );
2011-03-16 11:59:32 +01:00
}
}
2011-03-21 11:15:20 +01:00
/**
2010-11-29 16:05:45 +01:00
* add path / lineS / polyline whatever you name it .
* @ param simpleXMLElement
* @ return lines on the final image via _drawLine
*/
2010-11-26 16:07:16 +01:00
private function _parsePath ( $pathNode ){
2010-11-26 20:37:48 +01:00
$path = '' ;
$strokeWidth = 1 ;
$fill = '' ;
$stroke = '' ;
2010-11-29 18:03:06 +01:00
$strokeDasharray = '' ;
2011-03-21 11:15:20 +01:00
2011-03-16 11:59:32 +01:00
extract ( $this -> _getParams ( $pathNode ));
2011-03-21 11:15:20 +01:00
2010-11-30 13:17:40 +01:00
if ( strtolower ( substr ( $path , 0 , 1 )) != 'm' && ! is_numeric ( substr ( $path , 0 , 1 ))){
2010-11-26 18:18:17 +01:00
if ( $this -> _debug ) $this -> _log -> error ( 'Mauvais path rencontré : ' . $path );
return ;
}
2010-11-26 21:35:01 +01:00
2010-11-26 20:37:48 +01:00
$thickness = imagesetthickness ( $this -> _image , $this -> _parseInt ( $strokeWidth ) );
if ( $this -> _debug && ! $thickness ) $this -> _log -> error ( 'Erreur dans la mise en place de l\'épaisseur du trait' );
else $this -> _log -> message ( 'épaisseur du trait à : ' . $this -> _parseInt ( $strokeWidth ));
2011-03-21 11:15:20 +01:00
$colorStroke = $stroke != '' ? $this -> _allocateColor ( $stroke ) : $this -> _allocateColor ( 'black' );
$colorFill = $fill != '' ? $this -> _allocateColor ( $fill ) : '' ;
if ( $this -> _debug ) $this -> _log -> message ( 'colors ! fill:' . $colorFill . 'stroke:' . $colorStroke );
2010-11-29 18:03:06 +01:00
if ( $strokeDasharray != '' ){
$strokeDasharray = explode ( ',' , $strokeDasharray );
imagesetstyle ( $this -> _image , $this -> _getDashedStroke ( $strokeDasharray [ 0 ], $strokeDasharray [ 1 ], $colorStroke ));
} else
imagesetstyle ( $this -> _image , $this -> _getDashedStroke ( 10 , 0 , $colorStroke ));
2010-11-26 20:37:48 +01:00
$lastOpe = '' ;
2010-11-30 13:17:40 +01:00
$pathArray = split ( '[ ,]' , $path );
// Si le path est de format 'm 100 100 l 100 100 z' il faut recoller les morceaux
2010-11-30 18:18:38 +01:00
if ( array_key_exists ( strtolower ( $pathArray [ 0 ]), $this -> pathType )){
2010-11-30 13:17:40 +01:00
$j = 0 ;
do {
2010-11-30 18:18:38 +01:00
if ( array_key_exists ( strtolower ( $pathArray [ $j ]), $this -> pathType )){
2010-11-30 13:17:40 +01:00
$pathArray [ $j ] = $pathArray [ $j ] . $pathArray [ $j + 1 ];
$pathArray [ $j + 1 ] = '~' ;
$j ++ ;
$newNb = count ( $pathArray );
for ( $k = $j ; $k <= $newNb ; $k ++ ){
$pathArray [ $k ] = $pathArray [ $k + 1 ];
}
} else {
if ( $pathArray [ $j ] == '' || $pathArray [ $j ] == null )
unset ( $pathArray [ $j ]);
$j ++ ;
}
} while ( isset ( $pathArray [ $j ]));
2011-03-16 11:59:32 +01:00
//if($this->_debug) $this->_log->message('Path reconstruit ! '.implode(', ',$pathArray));
2010-11-30 13:17:40 +01:00
}
2010-11-26 20:37:48 +01:00
$nbArray = count ( $pathArray );
2011-03-21 11:15:20 +01:00
2011-03-16 11:59:32 +01:00
$polyPoints = array ();
2010-11-26 21:35:01 +01:00
$i = 0 ;
$lastX = 0 ;
$lastY = 0 ;
2010-12-01 12:38:30 +01:00
$lastMX = 0 ;
$lastMY = 0 ;
2010-11-26 21:35:01 +01:00
while ( $i < $nbArray ) {
// Changement de départ
2010-11-30 13:17:40 +01:00
if ( strtolower ( substr ( $pathArray [ $i ], 0 , 1 )) == 'm' ){
2011-03-16 11:59:32 +01:00
if ( isset ( $pathArray [ $i - 1 ])){
$this -> _drawPolygon ( $polyPoints , $colorStroke , $colorFill );
$polyPoints = array ();
$lastX = 0 ;
$lastY = 0 ;
$lastMX = 0 ;
$lastMY = 0 ;
}
2010-11-26 21:35:01 +01:00
$lastX = $this -> _parseInt ( $pathArray [ $i ]);
2010-12-01 12:38:30 +01:00
$lastMX = $this -> _parseInt ( $pathArray [ $i ]);
2010-11-26 21:35:01 +01:00
$lastY = $this -> _parseInt ( $pathArray [ $i + 1 ]);
2010-12-01 12:38:30 +01:00
$lastMY = $this -> _parseInt ( $pathArray [ $i + 1 ]);
2010-11-30 13:17:40 +01:00
$lastOpe = 'm' ;
2010-11-26 21:35:01 +01:00
$i = $i + 2 ;
2010-11-30 13:17:40 +01:00
// Ligne
} elseif ( strtolower ( substr ( $pathArray [ $i ], 0 , 1 )) == 'l' || ( is_numeric ( $pathArray [ $i ]) && strtolower ( $lastOpe ) == 'l' )){
2011-03-16 11:59:32 +01:00
if ( substr ( $pathArray [ $i ], 0 , 1 ) == 'L' ){
$newX = $this -> _parseInt ( $pathArray [ $i ]);
$newY = $this -> _parseInt ( $pathArray [ $i + 1 ]);
} else {
$newX = $lastX + $this -> _parseInt ( $pathArray [ $i ]);
$newY = $lastY + $this -> _parseInt ( $pathArray [ $i + 1 ]);
}
$polyPoints = array_merge ( $polyPoints , array ( $lastX , $lastY , $newX , $newY ));
//$this->_drawLine($lastX , $lastY , $newX , $newY , IMG_COLOR_STYLED);
2010-11-30 13:17:40 +01:00
$lastOpe = 'l' ;
2010-11-26 21:35:01 +01:00
$lastX = $newX ;
$lastY = $newY ;
$i = $i + 2 ;
2010-11-30 13:17:40 +01:00
// Ligne horizontale
} elseif ( strtolower ( substr ( $pathArray [ $i ], 0 , 1 )) == 'h' || ( is_numeric ( $pathArray [ $i ]) && strtolower ( $lastOpe ) == 'h' )){
2011-03-16 11:59:32 +01:00
if ( substr ( $pathArray [ $i ], 0 , 1 ) == 'H' ){
$newX = $this -> _parseInt ( $pathArray [ $i ]);
} else {
$newX = $lastX + $this -> _parseInt ( $pathArray [ $i ]);
}
//$this->_drawLine($lastX , $lastY , $newX , $lastY , IMG_COLOR_STYLED);
$polyPoints = array_merge ( $polyPoints , array ( $lastX , $lastY , $newX , $newY ));
2010-11-30 13:17:40 +01:00
$lastOpe = 'h' ;
2010-11-26 21:35:01 +01:00
$lastX = $newX ;
$i ++ ;
2010-11-30 13:17:40 +01:00
// Ligne verticale
} elseif ( strtolower ( substr ( $pathArray [ $i ], 0 , 1 )) == 'v' || ( is_numeric ( $pathArray [ $i ]) && strtolower ( $lastOpe ) == 'v' )){
2011-03-16 11:59:32 +01:00
if ( substr ( $pathArray [ $i ], 0 , 1 ) == 'V' ){
$newY = $this -> _parseInt ( $pathArray [ $i ]);
} else {
$newY = $lastY + $this -> _parseInt ( $pathArray [ $i ]);
}
//$this->_drawLine($lastX , $lastY , $lastX , $newY , IMG_COLOR_STYLED);
$polyPoints = array_merge ( $polyPoints , array ( $lastX , $lastY , $newX , $newY ));
2010-11-26 21:35:01 +01:00
$lastY = $newY ;
2010-11-30 13:17:40 +01:00
$lastOpe = 'v' ;
2010-11-26 21:35:01 +01:00
$i ++ ;
2010-11-30 13:17:40 +01:00
// Courbe
} elseif ( strtolower ( substr ( $pathArray [ $i ], 0 , 1 )) == 'c' || ( is_numeric ( $pathArray [ $i ]) && strtolower ( $lastOpe ) == 'c' )){
2011-03-16 11:59:32 +01:00
/*SPECIF !!! http://www.w3.org/TR/SVG/paths.html*/
if ( substr ( $pathArray [ $i ], 0 , 1 ) == 'C' ){
$control1x = $this -> _parseInt ( $pathArray [ $i ]);
$control1y = $this -> _parseInt ( $pathArray [ $i + 1 ]);
$control2x = $this -> _parseInt ( $pathArray [ $i + 2 ]);
$control2y = $this -> _parseInt ( $pathArray [ $i + 3 ]);
$newX = $this -> _parseInt ( $pathArray [ $i + 4 ]);
$newY = $this -> _parseInt ( $pathArray [ $i + 5 ]);
} else {
$control1x = $lastX + $this -> _parseInt ( $pathArray [ $i ]);
$control1y = $lastY + $this -> _parseInt ( $pathArray [ $i + 1 ]);
$control2x = $lastX + $this -> _parseInt ( $pathArray [ $i + 2 ]);
$control2y = $lastY + $this -> _parseInt ( $pathArray [ $i + 3 ]);
$newX = $lastX + $this -> _parseInt ( $pathArray [ $i + 4 ]);
$newY = $lastY + $this -> _parseInt ( $pathArray [ $i + 5 ]);
}
2010-11-30 13:17:40 +01:00
2011-03-16 11:59:32 +01:00
$polyPoints = array_merge ( $polyPoints , $this -> _Bezier_drawfilled ( array ( $lastX , $lastY ), array ( $control1x , $control1y ), array ( $control2x , $control2y ), array ( $newX , $newY ), $colorFill ));
2010-11-29 16:05:45 +01:00
$lastX = $newX ;
$lastY = $newY ;
2010-11-30 13:17:40 +01:00
$lastOpe = 'c' ;
2010-11-29 16:05:45 +01:00
$i = $i + 6 ;
2010-11-30 13:17:40 +01:00
// Dernière ligne droite
} elseif ( strtolower ( substr ( $pathArray [ $i ], 0 , 1 )) == 'z' || ( is_numeric ( substr ( $pathArray [ $i ], 0 , 1 )) && strtolower ( $lastOpe ) == 'z' )){
if ( $lastOpe == 'z' && $this -> _debug ) $this -> _log -> error ( '2 bouclages dans une boucle' );
2011-03-16 11:59:32 +01:00
$polyPoints = array_merge ( $polyPoints , array ( $lastX , $lastY , $lastMX , $lastMY ));
2011-03-21 11:15:20 +01:00
$lastMX = $lastX ;
$lastMY = $lastY ;
2011-03-16 11:59:32 +01:00
//$this->_drawLine($lastX , $lastY , $lastMX , $lastMY , IMG_COLOR_STYLED);
2010-12-01 12:38:30 +01:00
$lastOpe = 'z' ;
2010-11-26 21:35:01 +01:00
$i ++ ;
2010-11-30 13:17:40 +01:00
// Polyline
} else {
$lastX = $this -> _parseInt ( $pathArray [ $i + 2 ]);
$lastY = $this -> _parseInt ( $pathArray [ $i + 3 ]);
$lastOpe = 'l' ; // s'il n'a aucune lettre, c'est une polyline, donc des... lignes.
$i = $i + 2 ;
}
2011-03-16 11:59:32 +01:00
//if($this->_debug) $this->_log->message('counter :'.$i);
2010-11-26 18:18:17 +01:00
}
2011-03-16 11:59:32 +01:00
$this -> _drawPolygon ( $polyPoints , $colorStroke , $colorFill );
2010-11-26 20:37:48 +01:00
imagecolordeallocate ( $this -> _image , $colorStroke );
imagecolordeallocate ( $this -> _image , $colorFill );
imagesetthickness ( $this -> _image , 1 );
2010-11-29 18:03:06 +01:00
imagesetstyle ( $this -> _image , $this -> _getDashedStroke ( 10 , 0 , $colorStroke ));
2010-11-26 16:07:16 +01:00
}
2011-03-21 11:15:20 +01:00
/**
2010-11-29 16:05:45 +01:00
* add a circle in the final image
* @ param SimpleXMLElement
* @ return
*/
2010-11-26 13:00:12 +01:00
private function _parseCircle ( $circleNode ){
$x = 0 ;
$y = 0 ;
$r = 0 ;
2010-11-26 16:07:16 +01:00
$strokeWidth = 1 ;
2010-11-26 13:00:12 +01:00
$fill = '' ;
$stroke = '' ;
2011-03-16 11:59:32 +01:00
extract ( $this -> _getParams ( $circleNode ));
2011-03-21 11:15:20 +01:00
if ( $this -> _getParam ( 'originX' ) !== null ){
$x += $this -> _getParam ( 'originX' );
}
if ( $this -> _getParam ( 'originY' ) !== null ){
$y += $this -> _getParam ( 'originY' );
}
2010-11-26 13:00:12 +01:00
if ( $r == 0 )
return ;
2010-11-26 16:07:16 +01:00
if ( $this -> _debug ) $this -> _log -> message ( 'Cercle - x : ' . $x . ' - y : ' . $y . ' - rayon : ' . $r . '-' . $colorStroke [ 2 ] . ' - épaisseur : ' . $strokeWidth );
$thickness = imagesetthickness ( $this -> _image , ( int ) $strokeWidth );
if ( $this -> _debug && ! $thickness ) $this -> _log -> error ( 'Erreur dans la mise en place de l\'épaisseur du trait' );
2010-11-26 13:00:12 +01:00
2010-11-26 18:18:17 +01:00
$colorStroke = $this -> _allocateColor (( string ) $stroke );
$colorFill = $this -> _allocateColor (( string ) $fill );
2010-11-26 16:07:16 +01:00
2011-01-28 17:09:52 +01:00
if ( $fill != '' || ( $fill == '' && $stroke == '' )){
2010-11-26 16:07:16 +01:00
imagefilledarc ( $this -> _image , $x , $y , $r * 2 , $r * 2 , 0 , 359.9 , $colorFill , IMG_ARC_PIE );
2010-11-30 18:18:38 +01:00
//imageellipse ($this->_image , $x , $y , $r*2 , $r*2, $colorStroke );
}
if ( $stroke != '' ){
imagearc ( $this -> _image , $x , $y , $r * 2 , $r * 2 , 0 , 359.9 , $colorStroke );
2010-11-26 13:00:12 +01:00
}
2010-11-26 16:07:16 +01:00
imagecolordeallocate ( $this -> _image , $colorStroke );
imagecolordeallocate ( $this -> _image , $colorFill );
imagesetthickness ( $this -> _image , 1 );
2010-11-26 13:00:12 +01:00
}
2011-03-21 11:15:20 +01:00
/**
2010-11-29 18:03:06 +01:00
* add text in the final image < text fill = " #000000 " x = " 541 " y = " 258 " transform = " rotate(-0, 541, 258) " font - size = " 10 " font - family = " SansSerif " font - style = " normal " font - weight = " normal " > 0 </ text >
* @ param SimpleXMLElement
* @ return
*/
private function _parseText ( $textNode ){
$x = 0 ;
$y = 0 ;
$r = 0 ;
$strokeWidth = 1 ;
$fill = '' ;
$fontSize = 10 ;
$fontFamily = 'SansSerif' ;
$fontStyle = 'normal' ;
$fontWeight = 'normal' ;
2011-03-16 11:59:32 +01:00
extract ( $this -> _getParams ( $textNode ));
2011-03-21 11:15:20 +01:00
if ( $this -> _getParam ( 'originX' ) !== null ){
$x += $this -> _getParam ( 'originX' );
}
if ( $this -> _getParam ( 'originY' ) !== null ){
$y += $this -> _getParam ( 'originY' );
}
2010-11-29 18:03:06 +01:00
if ( $textNode == '' )
return ;
$colorStroke = $this -> _allocateColor (( string ) $fill );
2011-03-21 11:15:20 +01:00
imagestring ( $this -> _image , 2 , $x , $y , rtrim ( $textNode ) , $fill );
2010-11-29 18:03:06 +01:00
imagecolordeallocate ( $this -> _image , $colorStroke );
}
2010-11-29 16:05:45 +01:00
/*
* add a rectangle to the final image
* @ param simpleXMLElement
* @ return a nice rectangle !
*/
2010-11-26 13:00:12 +01:00
private function _parseRectangle ( $rectNode ){
$x = 0 ;
$y = 0 ;
$width = 0 ;
$height = 0 ;
$r = 0 ;
$fill = '' ;
$stroke = '' ;
2010-11-26 16:07:16 +01:00
$strokeWidth = 1 ;
2010-11-29 18:03:06 +01:00
$strokeDasharray = '' ;
2011-03-16 11:59:32 +01:00
extract ( $this -> _getParams ( $rectNode ));
2011-03-21 11:15:20 +01:00
//case translate
if ( $this -> _getParam ( 'originX' ) !== null )
$x += $this -> _getParam ( 'originX' );
if ( $this -> _getParam ( 'originY' ) !== null )
$y += $this -> _getParam ( 'originY' );
//end translate
2010-11-26 13:00:12 +01:00
if ( $width == 0 || $height == 0 )
return ;
2010-11-26 18:18:17 +01:00
$colorStroke = $this -> _allocateColor (( string ) $stroke );
$colorFill = $this -> _allocateColor (( string ) $fill );
2010-11-26 16:07:16 +01:00
$thickness = imagesetthickness ( $this -> _image , ( int ) $strokeWidth );
2010-11-29 18:03:06 +01:00
if ( $strokeDasharray != '' ){
$strokeDasharray = explode ( ',' , $strokeDasharray );
imagesetstyle ( $this -> _image , $this -> _getDashedStroke ( $strokeDasharray [ 0 ], $strokeDasharray [ 1 ], $colorStroke ));
} else
imagesetstyle ( $this -> _image , $this -> _getDashedStroke ( 10 , 0 , $colorStroke ));
2010-11-26 16:07:16 +01:00
if ( $this -> _debug && ! $thickness ) $this -> _log -> error ( 'Erreur dans la mise en place de l\'épaisseur du trait' );
2011-03-21 11:15:20 +01:00
2011-01-28 17:09:52 +01:00
if ( $fill != '' || ( $fill == '' && $stroke == '' )){
2010-11-26 16:07:16 +01:00
imagefilledrectangle ( $this -> _image , $x , $y , $x + $width , $y + $height , $colorFill );
2011-03-21 11:15:20 +01:00
imagerectangle ( $this -> _image , $x , $y , $x + $width , $y + $height , IMG_COLOR_STYLED );
2010-11-26 13:00:12 +01:00
}
2010-11-30 18:18:38 +01:00
if ( $stroke != '' ){
imagerectangle ( $this -> _image , $x , $y , $x + $width , $y + $height , IMG_COLOR_STYLED );
}
2010-11-26 16:07:16 +01:00
imagecolordeallocate ( $this -> _image , $colorStroke );
imagecolordeallocate ( $this -> _image , $colorFill );
imagesetthickness ( $this -> _image , 1 );
2010-11-29 18:03:06 +01:00
imagesetstyle ( $this -> _image , $this -> _getDashedStroke ( 10 , 0 , $colorStroke ));
2010-11-26 13:00:12 +01:00
}
2011-03-21 11:15:20 +01:00
private function _parseLine ( $lineNode ){
$x1 = 0 ;
$y1 = 0 ;
$x2 = 0 ;
$y2 = 0 ;
$stroke = '' ;
$strokeWidth = 1 ;
$strokeDasharray = '' ;
extract ( $this -> _getParams ( $lineNode ));
//case translate
if ( $this -> _getParam ( 'originX' ) !== null ){
$x1 += $this -> _getParam ( 'originX' );
$x2 += $this -> _getParam ( 'originX' );
}
if ( $this -> _getParam ( 'originY' ) !== null ){
$y1 += $this -> _getParam ( 'originY' );
$y2 += $this -> _getParam ( 'originY' );
}
//end translate
//case rotation
if ( $this -> _getParam ( 'rotate' ) !== null ){
}
//end rotation
//case scale
if ( $this -> _getParam ( 'scale' ) !== null ){
$xrapport = ( $x2 - $x1 ) / $this -> _getParam ( 'scale' );
$x2 += $xrapport ;
$yrapport = ( $y2 - $y1 ) / $this -> _getParam ( 'scale' );
$y2 += $yrapport ;
if ( $this -> _debug ) $this -> _log -> message ( 'scale by ' . Log :: decode ( $this -> _getParam ( 'scale' )) . ':' . Log :: decode ( $xrapport ) . ' - ' . Log :: decode ( $yrapport ));
}
//end scale
$colorStroke = $this -> _allocateColor (( string ) $stroke );
$thickness = imagesetthickness ( $this -> _image , ( int ) $strokeWidth );
if ( $strokeDasharray != '' ){
$strokeDasharray = explode ( ',' , $strokeDasharray );
imagesetstyle ( $this -> _image , $this -> _getDashedStroke ( $strokeDasharray [ 0 ], $strokeDasharray [ 1 ], $colorStroke ));
} else
imagesetstyle ( $this -> _image , $this -> _getDashedStroke ( 10 , 0 , $colorStroke ));
//if($this->_debug && !$thickness) $this->_log->error('Erreur dans la mise en place de l\'épaisseur du trait');
$this -> _drawLine ( $x1 , $y1 , $x2 , $y2 , $colorStroke );
imagecolordeallocate ( $this -> _image , $colorStroke );
imagesetthickness ( $this -> _image , 1 );
imagesetstyle ( $this -> _image , $this -> _getDashedStroke ( 10 , 0 , $colorStroke ));
}
/**
2010-11-29 16:05:45 +01:00
* add a polygon in the final image
* @ param simpleXMLElement
* @ return po - po - po - polygon !
*/
private function _parsePolygon ( $polyNode ){
$points = '' ;
$fill = '' ;
$stroke = '' ;
$strokeWidth = 1 ;
2011-03-16 11:59:32 +01:00
extract ( $this -> _getParams ( $polyNode ));
2010-11-29 16:05:45 +01:00
if ( $points == '' )
return ;
$pointArray = split ( '[ ,]' , $points );
$colorStroke = $this -> _allocateColor (( string ) $stroke );
$colorFill = $this -> _allocateColor (( string ) $fill );
$thickness = imagesetthickness ( $this -> _image , ( int ) $strokeWidth );
if ( $this -> _debug && ! $thickness ) $this -> _log -> error ( 'Erreur dans la mise en place de l\'épaisseur du trait' );
2010-11-30 18:18:38 +01:00
if ( $fill != '' ){
2010-11-29 16:05:45 +01:00
imagefilledpolygon ( $this -> _image , $pointArray , count ( $pointArray ) / 2 , $colorFill );
}
2010-11-30 18:18:38 +01:00
if ( $stroke != '' ){
imagepolygon ( $this -> _image , $pointArray , count ( $pointArray ) / 2 , $colorStroke );
}
2010-11-29 16:05:45 +01:00
imagecolordeallocate ( $this -> _image , $colorStroke );
imagecolordeallocate ( $this -> _image , $colorFill );
imagesetthickness ( $this -> _image , 1 );
}
2011-03-21 11:15:20 +01:00
/**
2010-11-29 16:05:45 +01:00
* add the description text in the final image
* @ param string the description
* @ return boolean
*/
2010-11-26 13:00:12 +01:00
private function _parseDescription ( $desc ){
if ( $this -> _debug ) $this -> _log -> message ( 'Ajout de la description : ' . $desc );
return imagestring ( $this -> _image , 2 , 10 , $this -> _getImageHeight () - 20 , $desc , imagecolorallocate ( $this -> _image , 255 , 255 , 255 ));
}
2010-11-29 16:05:45 +01:00
2011-03-16 11:59:32 +01:00
/**
* @ param node < g >
* get group attributes to pass it to children
* parse children
2010-11-29 16:05:45 +01:00
*/
private function _parseGroup ( $groupNode ){
2011-03-21 11:15:20 +01:00
$this -> _currentOptions [] = $this -> _getParams ( $groupNode );
2010-11-29 16:05:45 +01:00
foreach ( $groupNode -> children () as $element ){
$this -> _chooseParse ( $element );
}
2011-03-21 11:15:20 +01:00
unset ( $this -> _currentOptions [ count ( $this -> _currentOptions ) - 1 ]);
2010-11-29 16:05:45 +01:00
}
2011-03-21 11:15:20 +01:00
/**
2010-11-29 16:05:45 +01:00
* select what to parse
* @ param simpleXMLElement
* @ return the selected function
*/
private function _chooseParse ( $element ){
if ( $element -> getName () == 'image' )
$this -> _parseImage ( $element );
if ( $element -> getName () == 'circle' )
$this -> _parseCircle ( $element );
if ( $element -> getName () == 'rect' )
$this -> _parseRectangle ( $element );
if ( $element -> getName () == 'path' )
$this -> _parsePath ( $element );
if ( $element -> getName () == 'polygon' )
$this -> _parsePolygon ( $element );
if ( $element -> getName () == 'polyline' )
$this -> _parsePath ( $element );
2010-11-29 18:03:06 +01:00
if ( $element -> getName () == 'g' )
$this -> _parseGroup ( $element );
if ( $element -> getName () == 'text' )
$this -> _parseText ( $element );
2011-03-21 11:15:20 +01:00
if ( $element -> getName () == 'line' )
$this -> _parseLine ( $element );
2011-03-16 11:59:32 +01:00
//if($element->getName() == 'defs')
// $this->_parseDefs($element);
2010-11-29 18:03:06 +01:00
//if($element->getName() == 'title')
// $this->_parseTitle($element);
2010-11-29 16:05:45 +01:00
if ( $element -> getName () == 'desc' && $this -> _showDesc )
$this -> _desc = $element ;
}
2010-11-26 13:00:12 +01:00
2011-03-21 11:15:20 +01:00
/**
2010-11-29 16:05:45 +01:00
* parse everything , main function
* @ param string format of the ouput 'png' 'gif' jpg '
* @ param string path where you want to save the file ( with the final name ), null will just show the image but not saved on server
* @ return the image
*/
public function toImage ( $format = 'png' , $path = null ){
2010-11-26 13:00:12 +01:00
$writeDesc = null ;
$this -> _image = imagecreatetruecolor ( $this -> _getImageWidth (), $this -> _getImageHeight ());
2010-11-30 13:17:40 +01:00
imagefilledrectangle ( $this -> _image , 0 , 0 , $this -> _getImageWidth (), $this -> _getImageHeight (), $this -> _allocateColor ( 'white' ));
2010-11-26 16:07:16 +01:00
imagealphablending ( $this -> _image , true );
2010-11-26 20:37:48 +01:00
//imageantialias($this->_image, true); // On ne peut pas gérer l'épaisseur des traits si l'antialiasing est activé... lol ?
2010-11-26 13:00:12 +01:00
foreach ( $this -> _svgXML -> children () as $element ){
2010-11-29 16:05:45 +01:00
$this -> _chooseParse ( $element );
2011-03-16 11:59:32 +01:00
$this -> _currentOptions = array ();
2010-11-26 13:00:12 +01:00
}
2010-11-29 16:05:45 +01:00
if ( $this -> _showDesc && $this -> _desc != null ) $this -> _parseDescription ( $this -> _desc );
2010-11-26 16:07:16 +01:00
//imagefilter ( $this->_image , IMG_FILTER_SMOOTH, 6);
2010-11-29 16:05:45 +01:00
switch ( $format ){
2010-11-29 16:50:24 +01:00
case 'gif' :
header ( " Content-type: " . image_type_to_mime_type ( IMAGETYPE_GIF ));
return imagegif ( $this -> _image , $path );
case 'jpg' :
header ( " Content-type: " . image_type_to_mime_type ( IMAGETYPE_JPEG ));
return imagejpeg ( $this -> _image , $path );
2010-11-29 16:05:45 +01:00
case 'png' :
default :
2010-11-29 16:50:24 +01:00
header ( " Content-type: " . image_type_to_mime_type ( IMAGETYPE_PNG ));
2010-11-29 16:05:45 +01:00
return imagepng ( $this -> _image , $path );
}
2010-11-26 13:00:12 +01:00
}
}