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-26 18:18:17 +01:00
// pour les rectangles avec point ou tiret http://fr.php.net/manual/fr/function.imagesetstyle.php
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 ;
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' ,
);
2010-11-29 16:05:45 +01:00
/* array of color names => hex color
because some svg creator uses them
*/
2010-11-26 18:18:17 +01:00
private $colors = array (
'black' => '#000000' ,
'red' => '#FF0000' ,
'white' => '#FFFFFF' ,
'turquoise' => '#00FFFF' ,
2010-11-29 16:05:45 +01:00
'grey' => '#CCCCCC' ,
2010-11-26 18:18:17 +01:00
'light grey' => '#C0C0C0' ,
'light blue' => '#0000FF' ,
'dark grey' => '#808080' ,
'dark blue' => '#0000A0' ,
'light purple' => '#FF0080' ,
'orange' => '#FF8040' ,
'dark purple' => '#800080' ,
'brown' => '#804000' ,
'yellow' => '#FFFF00' ,
'burgundy' => '#800000' ,
'pastel green' => '#00FF00' ,
'forest green' => '#808000' ,
'pink' => '#FF00FF' ,
'grass green' => '#408080' ,
);
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-30 13:17:40 +01:00
//if($this->_debug) $this->_log->message('Ouverture du fichier contentant : '.$svg);
2010-11-29 16:05:45 +01:00
$this -> _svgXML = simplexml_load_string ( $svg );
2010-11-26 13:00:12 +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 );
}
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 );
}
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 );
}
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 )){
if ( $this -> _debug ) $this -> _log -> message ( 'Passage de showDesc en ' . $showDesc );
$this -> _showDesc = $showDesc ;
} else {
if ( $this -> _debug ) $this -> _log -> error ( 'Erreur dans la fonction showDesc, doit recevoir booléen, a reçu : ' . $showDesc );
}
}
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 )){
if ( $this -> _debug ) $this -> _log -> message ( 'Passage de x en ' . $x );
$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 )){
if ( $this -> _debug ) $this -> _log -> message ( 'Passage de y en ' . $y );
$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 )){
if ( $this -> _debug ) $this -> _log -> message ( 'Passage de width en ' . $width );
$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 )){
if ( $this -> _debug ) $this -> _log -> message ( 'Passage de height en ' . $height );
$this -> _height = $height ;
} else {
if ( $this -> _debug ) $this -> _log -> error ( 'Erreur dans la fonction setHeight, doit recevoir int, a reçu : ' . $height );
}
}
/* return width and height from the SVG */
private function _getImageSize (){
$imageSize = array ();
$imageSize [ 'width' ] = $this -> _svgXML -> attributes () -> width ;
$imageSize [ 'height' ] = $this -> _svgXML -> attributes () -> height ;
if ( $this -> _debug ) $this -> _log -> message ( 'taille de l\'image : largeur : ' . $imageSize [ 'width' ] . ' - longueur : ' . $imageSize [ 'height' ]);
return $imageSize ;
}
2010-11-29 16:05:45 +01:00
/*
* @ return int final image width
*/
2010-11-26 13:00:12 +01:00
private function _getImageWidth (){
return isset ( $this -> _width ) ? $this -> _width : $this -> _svgXML -> attributes () -> width ;
}
2010-11-29 16:05:45 +01:00
/*
* @ return int final image height
*/
2010-11-26 13:00:12 +01:00
private function _getImageHeight (){
return isset ( $this -> _height ) ? $this -> _height : $this -> _svgXML -> attributes () -> height ;
}
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 ){
if ( strlen ( $colorCode ) == 7 ){
if ( $this -> _debug ) $this -> _log -> message ( 'Parse Color ' . $colorCode );
return array (
base_convert ( substr ( $colorCode , 1 , 2 ), 16 , 10 ),
base_convert ( substr ( $colorCode , 3 , 2 ), 16 , 10 ),
base_convert ( substr ( $colorCode , 5 , 2 ), 16 , 10 ),
);
}
if ( strlen ( $colorCode ) == 4 ){
if ( $this -> _debug ) $this -> _log -> message ( 'Parse Color ' . $colorCode );
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 ),
);
}
if ( $this -> _debug ) $this -> _log -> error ( 'Couleur mal indiquée ' . $colorCode );
return array ( 0 , 0 , 0 );
}
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 )){
2010-11-26 18:18:17 +01:00
$arrayColor = $this -> _parseColor ( $this -> colors [ $color ]);
} else {
$arrayColor = $this -> _parseColor ( $color );
}
2010-11-26 16:07:16 +01:00
return imagecolorallocate ( $this -> _image , $arrayColor [ 0 ], $arrayColor [ 1 ], $arrayColor [ 2 ] );
}
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 ;
}
if ( $this -> _debug ) $this -> _log -> message ( 'nouveaux tirets : ' . implode ( '-' , $tiret ));
return $tiret ;
}
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 ;
foreach ( $imageNode -> attributes () as $name => $value ){
switch ( $name ){
case 'x' : $x = $value ; break ;
case 'y' : $y = $value ; break ;
case 'width' : $width = $value ; break ;
case 'height' : $height = $value ; break ;
case 'href' :
case 'xlink:href' : $href = $value ; break ;
2010-11-29 16:50:24 +01:00
//case 'r' : $r = $value; break; // no, use transform instead !
2010-11-29 16:05:45 +01:00
case 'transform' : $transform = $value ;
2010-11-26 13:00:12 +01:00
case 'style' : if ( strripos ( $value , 'display: none' ) || strripos ( $value , 'display:none' )) return ; break ;
}
}
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 ;
if ( $this -> _debug ) $this -> _log -> message ( 'Image - x : ' . $x . ' - y : ' . $y . ' - largeur : ' . $width . ' - longueur : ' . $height . ' - url : ' . $href . ' - angle : ' . $r );
$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
}
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 ;
}
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 ){
2010-11-30 13:17:40 +01:00
if ( preg_match ( '/[-]?(\d+)/' , $string , $array )) {
//if(preg_match('/[-]?(\d+)/', $string, $array)) {
return $array [ 0 ];
//return $array[1];
2010-11-26 18:18:17 +01:00
} else {
return 0 ;
}
}
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 );
}
}
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 ;
if ( $this -> _debug ) $this -> _log -> message ( 'ax : ' . $ax . ', ay : ' . $ay );
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 );
}
}
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 ){
// imagesetbrush
// imagesetstyle (pour dotted, dashed etc)
2010-11-26 20:37:48 +01:00
$path = '' ;
$strokeWidth = 1 ;
$fill = '' ;
$stroke = '' ;
2010-11-29 18:03:06 +01:00
$strokeDasharray = '' ;
2010-11-26 20:37:48 +01:00
foreach ( $pathNode -> attributes () as $name => $value ){
switch ( $name ){
2010-11-29 16:05:45 +01:00
case 'd' : case 'points' : $path = $value ; break ;
2010-11-26 20:37:48 +01:00
case 'stroke' : $stroke = $value ; break ;
case 'fill' : $fill = ( $value == 'none' ) ? '' : $value ; break ;
case 'stroke-width' : $strokeWidth = $value ; break ;
2010-11-29 18:03:06 +01:00
case 'stroke-dasharray' : $strokeDasharray = $value ; break ;
2010-11-26 20:37:48 +01:00
case 'style' : if ( strripos ( $value , 'display: none' ) || strripos ( $value , 'display:none' )) return ; break ;
}
}
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 ));
$colorStroke = $stroke != '' ? $this -> _allocateColor (( string ) $stroke ) : $this -> _allocateColor ( 'black' );
$colorFill = $fill != '' ? $this -> _allocateColor (( string ) $fill ) : $this -> _allocateColor ( 'black' );
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
if ( array_key_exists ( $pathArray [ 0 ], $this -> pathType )){
reset ( $pathArray );
$j = 0 ;
do {
if ( array_key_exists ( $pathArray [ $j ], $this -> pathType )){
$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 ]));
if ( $this -> _debug ) $this -> _log -> message ( 'Path reconstruit ! ' . implode ( ', ' , $pathArray ));
}
2010-11-26 20:37:48 +01:00
$nbArray = count ( $pathArray );
$nbLine = (( $nbArray - 1 ) / 2 ) - 1 ;
2010-11-29 18:03:06 +01:00
2010-11-26 21:35:01 +01:00
$i = 0 ;
$lastX = 0 ;
$lastY = 0 ;
while ( $i < $nbArray ) {
// Changement de départ
2010-11-30 13:17:40 +01:00
if ( strtolower ( substr ( $pathArray [ $i ], 0 , 1 )) == 'm' ){
2010-11-26 21:35:01 +01:00
$lastX = $this -> _parseInt ( $pathArray [ $i ]);
$lastY = $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' )){
2010-11-26 21:35:01 +01:00
$newX = $this -> _parseInt ( $pathArray [ $i ]);
$newY = $this -> _parseInt ( $pathArray [ $i + 1 ]);
2010-11-29 18:03:06 +01:00
$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' )){
2010-11-26 21:35:01 +01:00
$newX = $this -> _parseInt ( $pathArray [ $i ]);
2010-11-29 18:03:06 +01:00
$this -> _drawLine ( $lastX , $lastY , $newX , $lastY , IMG_COLOR_STYLED );
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' )){
2010-11-26 21:35:01 +01:00
$newY = $this -> _parseInt ( $pathArray [ $i ]);
2010-11-29 18:03:06 +01:00
$this -> _drawLine ( $lastX , $lastY , $lastX , $newY , IMG_COLOR_STYLED );
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' )){
2010-11-29 16:05:45 +01:00
$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 ]);
2010-11-30 13:17:40 +01:00
if ( $this -> _debug ) $this -> _log -> message ( 'Drawing curve : ' . $lastX . ' - ' . $lastY . ' - ' . $control1x . ' - ' . $control1y . ' - ' . $control2x . ' - ' . $control2y . ' - ' . $newX . ' - ' . $newY );
$this -> _drawCurve ( $lastX , $lastY , $control1x , $control1y , $control2x , $control2y , $newX , $newY , IMG_COLOR_STYLED );
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' );
2010-11-29 18:03:06 +01:00
$this -> _drawLine ( $lastX , $lastY , $this -> _parseInt ( $pathArray [ 0 ]) , $this -> _parseInt ( $pathArray [ 1 ]) , IMG_COLOR_STYLED );
2010-11-30 13:17:40 +01:00
$lastOpe = 'z' ; //utile?
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 ;
}
2010-11-26 21:35:01 +01:00
if ( $this -> _debug ) $this -> _log -> message ( 'counter :' . $i );
2010-11-26 18:18:17 +01:00
}
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
}
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 = '' ;
foreach ( $circleNode -> attributes () as $name => $value ){
switch ( $name ){
case 'cx' : $x = $value ; break ;
case 'cy' : $y = $value ; break ;
case 'r' : $r = $value ; break ;
case 'fill' : $fill = ( $value == 'none' ) ? '' : $value ; break ;
case 'stroke' : $stroke = $value ; break ;
case 'style' : if ( strripos ( $value , 'display: none' ) || strripos ( $value , 'display:none' )) return ; break ;
2010-11-26 16:07:16 +01:00
case 'stroke-width' : $strokeWidth = $value ; break ;
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
if ( $fill == '' ){
imagearc ( $this -> _image , $x , $y , $r * 2 , $r * 2 , 0 , 359.9 , $colorStroke );
//imageellipse ($this->_image , $x , $y , $r*2 , $r*2, $colorStroke );
2010-11-26 13:00:12 +01:00
} else {
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-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
}
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' ;
foreach ( $textNode -> attributes () as $name => $value ){
switch ( $name ){
case 'x' : $x = $value ; break ;
case 'y' : $y = $value ; break ;
//case 'r': $r = $value; break; // todo
case 'fill' : $fill = $value ; break ;
case 'font-size' : $fontSize = $value ; break ;
case 'font-family' : $fontFamily = $value ; break ;
case 'font-style' : $fontStyle = $value ; break ;
case 'font-weight' : $fontWeight = $value ; break ;
}
}
if ( $textNode == '' )
return ;
$colorStroke = $this -> _allocateColor (( string ) $fill );
imagestring ( $this -> _image , 2 , $x , $y , $textNode , $fill );
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 = '' ;
2010-11-26 13:00:12 +01:00
foreach ( $rectNode -> attributes () as $name => $value ){
switch ( $name ){
2010-11-26 16:07:16 +01:00
// imagesetstyle (pour dotted, dashed etc)
2010-11-26 13:00:12 +01:00
case 'x' : $x = $value ; break ;
case 'y' : $y = $value ; break ;
case 'r' : $r = $value ; break ;
case 'width' : $width = $value ; break ;
case 'height' : $height = $value ; break ;
case 'fill' : $fill = ( $value == 'none' ) ? '' : $value ; break ;
case 'stroke' : $stroke = $value ; break ;
2010-11-26 16:07:16 +01:00
case 'stroke-width' : $strokeWidth = $value ; break ;
2010-11-29 18:03:06 +01:00
case 'stroke-dasharray' : $strokeDasharray = $value ; break ;
2010-11-26 13:00:12 +01:00
case 'style' : if ( strripos ( $value , 'display: none' ) || strripos ( $value , 'display:none' )) return ; break ;
}
}
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' );
2010-11-26 13:00:12 +01:00
if ( $this -> _debug ) $this -> _log -> message ( 'Rectangle - x : ' . $x . ' - y : ' . $y . ' - width : ' . $width . ' - height : ' . $height . ' - fill : ' . $colorFill [ 0 ] . '-' . $colorFill [ 1 ] . '-' . $colorFill [ 2 ] . ' - stroke : ' . $colorStroke [ 0 ] . '-' . $colorStroke [ 1 ] . '-' . $colorStroke [ 2 ]);
if ( $fill == '' ){
2010-11-29 18:03:06 +01:00
imagerectangle ( $this -> _image , $x , $y , $x + $width , $y + $height , IMG_COLOR_STYLED );
2010-11-26 13:00:12 +01:00
} else {
2010-11-26 16:07:16 +01:00
imagefilledrectangle ( $this -> _image , $x , $y , $x + $width , $y + $height , $colorFill );
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-29 18:03:06 +01:00
imagesetstyle ( $this -> _image , $this -> _getDashedStroke ( 10 , 0 , $colorStroke ));
2010-11-26 13:00:12 +01:00
}
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 ;
foreach ( $polyNode -> attributes () as $name => $value ){
switch ( $name ){
// imagesetstyle (pour dotted, dashed etc)
case 'points' : $points = $value ; break ;
case 'fill' : $fill = ( $value == 'none' ) ? '' : $value ; break ;
case 'stroke' : $stroke = $value ; break ;
case 'stroke-width' : $strokeWidth = $value ; break ;
case 'style' : if ( strripos ( $value , 'display: none' ) || strripos ( $value , 'display:none' )) return ; break ;
}
}
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' );
if ( $fill == '' ){
imagepolygon ( $this -> _image , $pointArray , count ( $pointArray ) / 2 , $colorStroke );
} else {
imagefilledpolygon ( $this -> _image , $pointArray , count ( $pointArray ) / 2 , $colorFill );
}
imagecolordeallocate ( $this -> _image , $colorStroke );
imagecolordeallocate ( $this -> _image , $colorFill );
imagesetthickness ( $this -> _image , 1 );
}
/*
* 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
/*
* ignore group for the moment
* acts like ungrouped
*/
private function _parseGroup ( $groupNode ){
foreach ( $groupNode -> children () as $element ){
$this -> _chooseParse ( $element );
}
}
/*
* 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 );
//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
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 );
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
}
}