(bug 18691) Added support for SVG rasterization using the Imagick PHP extension....
authorBryan Tong Minh <btongminh@users.mediawiki.org>
Sat, 12 Mar 2011 19:59:41 +0000 (19:59 +0000)
committerBryan Tong Minh <btongminh@users.mediawiki.org>
Sat, 12 Mar 2011 19:59:41 +0000 (19:59 +0000)
Introduced new syntax for $wgSVGConverters, if the selected converter is an array, it is assumed to be a PHP callable. Imagick support is done by SvgHandler::rasterizeImagickExt.

CREDITS
RELEASE-NOTES
includes/DefaultSettings.php
includes/media/SVG.php

diff --git a/CREDITS b/CREDITS
index 463b744..55448c8 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -65,6 +65,7 @@ following names for their contribution to the product.
 * Tom Gries
 * Trevor Parscal
 * Victor Vasiliev
+* Yesid Carrillo
 * Yuri Astrakhan
 
 == Patch Contributors ==
index 7cd82ef..4671c9e 100644 (file)
@@ -103,6 +103,8 @@ PHP if you have not done so prior to upgrading MediaWiki.
 * When $wgAllowMicrodataAttributes is true, all itemtypes are allowed, not just
   the three that were defined in the original specification.
 * (bug 14706) Added support for the Imagick PHP extension.
+* (bug 18691) Added support for SVG rasterization using the Imagick PHP 
+  extension
 
 === Bug fixes in 1.18 ===
 * (bug 23119) WikiError class and subclasses are now marked as deprecated
index a4da8a4..7e9a355 100644 (file)
@@ -660,6 +660,8 @@ $wgCustomConvertCommand = false;
  * necessary to rasterize SVGs to PNG as a fallback format.
  *
  * An external program is required to perform this conversion.
+ * If set to an array, the first item is a PHP callable and any further items
+ * are passed as parameters after $srcPath, $dstPath, $width, $height
  */
 $wgSVGConverters = array(
        'ImageMagick' => '$path/convert -background white -thumbnail $widthx$height\! $input PNG:$output',
@@ -668,6 +670,7 @@ $wgSVGConverters = array(
        'batik' => 'java -Djava.awt.headless=true -jar $path/batik-rasterizer.jar -w $width -d $output $input',
        'rsvg' => '$path/rsvg -w$width -h$height $input $output',
        'imgserv' => '$path/imgserv-wrapper -i svg -o png -w$width $input $output',
+       'ImagickExt' => array( 'SvgHandler::rasterizeImagickExt' ),
        );
 /** Pick a converter defined in $wgSVGConverters */
 $wgSVGConverter = 'ImageMagick';
index d425b94..57a9668 100644 (file)
@@ -119,19 +119,32 @@ class SvgHandler extends ImageHandler {
                $err = false;
                $retval = '';
                if ( isset( $wgSVGConverters[$wgSVGConverter] ) ) {
-                       $cmd = str_replace(
-                               array( '$path/', '$width', '$height', '$input', '$output' ),
-                               array( $wgSVGConverterPath ? wfEscapeShellArg( "$wgSVGConverterPath/" ) : "",
-                                          intval( $width ),
-                                          intval( $height ),
-                                          wfEscapeShellArg( $srcPath ),
-                                          wfEscapeShellArg( $dstPath ) ),
-                               $wgSVGConverters[$wgSVGConverter]
-                       ) . " 2>&1";
-                       wfProfileIn( 'rsvg' );
-                       wfDebug( __METHOD__.": $cmd\n" );
-                       $err = wfShellExec( $cmd, $retval );
-                       wfProfileOut( 'rsvg' );
+                       if ( is_array( $wgSVGConverters[$wgSVGConverter] ) ) {
+                               // This is a PHP callable
+                               $func = $wgSVGConverters[$wgSVGConverter][0];
+                               $args = array_merge( array( $srcPath, $dstPath, $width, $height ), 
+                                       array_slice( $wgSVGConverters[$wgSVGConverter], 1 ) );
+                               if ( !is_callable( $func ) ) {
+                                       throw new MWException( "$func is not callable" );
+                               }
+                               $err = call_user_func_array( $func, $args );
+                               $retval = (bool)$err;
+                       } else {
+                               // External command
+                               $cmd = str_replace(
+                                       array( '$path/', '$width', '$height', '$input', '$output' ),
+                                       array( $wgSVGConverterPath ? wfEscapeShellArg( "$wgSVGConverterPath/" ) : "",
+                                                  intval( $width ),
+                                                  intval( $height ),
+                                                  wfEscapeShellArg( $srcPath ),
+                                                  wfEscapeShellArg( $dstPath ) ),
+                                       $wgSVGConverters[$wgSVGConverter]
+                               ) . " 2>&1";
+                               wfProfileIn( 'rsvg' );
+                               wfDebug( __METHOD__.": $cmd\n" );
+                               $err = wfShellExec( $cmd, $retval );
+                               wfProfileOut( 'rsvg' );
+                       }
                }
                $removed = $this->removeBadFile( $dstPath, $retval );
                if ( $retval != 0 || $removed ) {
@@ -141,6 +154,20 @@ class SvgHandler extends ImageHandler {
                }
                return true;
        }
+       
+       public static function rasterizeImagickExt( $srcPath, $dstPath, $width, $height ) {
+               $im = new Imagick( $srcPath );
+               $im->setImageFormat( 'png' );
+               $im->setBackgroundColor( 'transparent' );
+               $im->setImageDepth( 8 );
+               
+               if ( !$im->thumbnailImage( intval( $width ), intval( $height ), /* fit */ false ) ) {
+                       return 'Could not resize image';
+               }
+               if ( !$im->writeImage( $dstPath ) ) {
+                       return "Could not write to $dstPath";
+               }
+       }
 
        /**
         * @param $file File