X-Git-Url: http://git.cyclocoop.org/?a=blobdiff_plain;f=includes%2Fmedia%2FSVG.php;h=6c2d98059aa5f17f9d228fe98a5e210069c367fd;hb=37013dc9207a585a82e066ddddc406a471378a33;hp=75d0ad3d86020493158e9b4c2f8453b9190b3505;hpb=497649c9045838551236530aa92aa4dce864ba65;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/media/SVG.php b/includes/media/SVG.php index 75d0ad3d86..6c2d98059a 100644 --- a/includes/media/SVG.php +++ b/includes/media/SVG.php @@ -1,9 +1,19 @@ getMetadata(); + if ( $metadata ) { + $metadata = $this->unpackMetadata( $metadata ); + if( isset( $metadata['animated'] ) ) { + return $metadata['animated']; + } + } + return false; + } + function normaliseParams( $image, &$params ) { global $wgSVGMaxSize; if ( !parent::normaliseParams( $image, $params ) ) { return false; } - # Don't make an image bigger than wgMaxSVGSize $params['physicalWidth'] = $params['width']; $params['physicalHeight'] = $params['height']; @@ -35,10 +60,8 @@ class SvgHandler extends ImageHandler { } return true; } - + function doTransform( $image, $dstPath, $dstUrl, $params, $flags = 0 ) { - global $wgSVGConverters, $wgSVGConverter, $wgSVGConverterPath; - if ( !$this->normaliseParams( $image, $params ) ) { return new TransformParameterError( $params ); } @@ -53,50 +76,146 @@ class SvgHandler extends ImageHandler { } if ( !wfMkdirParents( dirname( $dstPath ) ) ) { - return new MediaTransformError( 'thumbnail_error', $clientWidth, $clientHeight, + return new MediaTransformError( 'thumbnail_error', $clientWidth, $clientHeight, wfMsg( 'thumbnail_dest_directory' ) ); } + $status = $this->rasterize( $srcPath, $dstPath, $physicalWidth, $physicalHeight ); + if( $status === true ) { + return new ThumbnailImage( $image, $dstUrl, $clientWidth, $clientHeight, $dstPath ); + } else { + return $status; // MediaTransformError + } + } + + /* + * Transform an SVG file to PNG + * This function can be called outside of thumbnail contexts + * @param string $srcPath + * @param string $dstPath + * @param string $width + * @param string $height + * @returns TRUE/MediaTransformError + */ + public function rasterize( $srcPath, $dstPath, $width, $height ) { + global $wgSVGConverters, $wgSVGConverter, $wgSVGConverterPath; $err = false; - if( isset( $wgSVGConverters[$wgSVGConverter] ) ) { + $retval = ''; + if ( isset( $wgSVGConverters[$wgSVGConverter] ) ) { $cmd = str_replace( array( '$path/', '$width', '$height', '$input', '$output' ), array( $wgSVGConverterPath ? wfEscapeShellArg( "$wgSVGConverterPath/" ) : "", - intval( $physicalWidth ), - intval( $physicalHeight ), + intval( $width ), + intval( $height ), wfEscapeShellArg( $srcPath ), wfEscapeShellArg( $dstPath ) ), - $wgSVGConverters[$wgSVGConverter] ) . " 2>&1"; + $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 ) { - wfDebugLog( 'thumbnail', - sprintf( 'thumbnail failed on %s: error %d "%s" from "%s"', + wfDebugLog( 'thumbnail', sprintf( 'thumbnail failed on %s: error %d "%s" from "%s"', wfHostname(), $retval, trim($err), $cmd ) ); - return new MediaTransformError( 'thumbnail_error', $clientWidth, $clientHeight, $err ); - } else { - return new ThumbnailImage( $image, $dstUrl, $clientWidth, $clientHeight, $dstPath ); + return new MediaTransformError( 'thumbnail_error', $width, $height, $err ); } + return true; } - function getImageSize( $image, $path ) { - return wfGetSVGsize( $path ); + function getImageSize( $file, $path, $metadata = false ) { + if ( $metadata === false ) { + $metadata = $file->getMetaData(); + } + $metadata = $this->unpackMetaData( $metadata ); + + if ( isset( $metadata['width'] ) && isset( $metadata['height'] ) ) { + return array( $metadata['width'], $metadata['height'], 'SVG', + "width=\"{$metadata['width']}\" height=\"{$metadata['height']}\"" ); + } } - function getThumbType( $ext, $mime ) { + function getThumbType( $ext, $mime, $params = null ) { return array( 'png', 'image/png' ); } function getLongDesc( $file ) { global $wgLang; - return wfMsg( 'svg-long-desc', $file->getWidth(), $file->getHeight(), + return wfMsgExt( 'svg-long-desc', 'parseinline', + $wgLang->formatNum( $file->getWidth() ), + $wgLang->formatNum( $file->getHeight() ), $wgLang->formatSize( $file->getSize() ) ); } -} + function getMetadata( $file, $filename ) { + $metadata = array(); + try { + $metadata = SVGMetadataExtractor::getMetadata( $filename ); + } catch( Exception $e ) { + // Broken file? + wfDebug( __METHOD__ . ': ' . $e->getMessage() . "\n" ); + return '0'; + } + $metadata['version'] = self::SVG_METADATA_VERSION; + return serialize( $metadata ); + } + + function unpackMetadata( $metadata ) { + $unser = @unserialize( $metadata ); + if ( isset( $unser['version'] ) && $unser['version'] == self::SVG_METADATA_VERSION ) { + return $unser; + } else { + return false; + } + } + + function getMetadataType( $image ) { + return 'parsed-svg'; + } + + function isMetadataValid( $image, $metadata ) { + return $this->unpackMetadata( $metadata ) !== false; + } + + function visibleMetadataFields() { + $fields = array( 'title', 'description', 'animated' ); + return $fields; + } + + function formatMetadata( $file ) { + $result = array( + 'visible' => array(), + 'collapsed' => array() + ); + $metadata = $file->getMetadata(); + if ( !$metadata ) { + return false; + } + $metadata = $this->unpackMetadata( $metadata ); + if ( !$metadata ) { + return false; + } + unset( $metadata['version'] ); + unset( $metadata['metadata'] ); /* non-formatted XML */ + + /* TODO: add a formatter + $format = new FormatSVG( $metadata ); + $formatted = $format->getFormattedData(); + */ + // Sort fields into visible and collapsed + $visibleFields = $this->visibleMetadataFields(); + foreach ( $metadata as $name => $value ) { + $tag = strtolower( $name ); + self::addMeta( $result, + in_array( $tag, $visibleFields ) ? 'visible' : 'collapsed', + 'svg', + $tag, + $value + ); + } + return $result; + } +}