Skip to content

Commit

Permalink
Added support for rescaling SVG
Browse files Browse the repository at this point in the history
  • Loading branch information
Grandt committed Nov 3, 2015
1 parent 57f3c11 commit c10bb64
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 4 deletions.
135 changes: 131 additions & 4 deletions src/PHPePub/Core/EPub.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use PHPePub\Core\Structure\OPF\Reference;
use PHPZip\Zip\File\Zip;
use RelativePath;
use SimpleXMLElement;


/**
Expand Down Expand Up @@ -620,19 +621,20 @@ function getImage($source) {
$xml = simplexml_load_string($image);
$attr = $xml->attributes();

$meta = $this->handleSVGAttribs($xml);

$mime = "image/svg+xml";
$ext = "svg";
/*
$width = $attr->width;
$height = $attr->height;

$width = $meta['width'];
$height = $meta['height'];

$ratio = $this->getImageScale($width, $height);
if ($ratio < 1) {
$attr->width = $width * $ratio;
$attr->height = $height * $ratio;
}
$image = $xml->asXML();
*/
} else {
$imageFile = imagecreatefromstring($image);
if ($imageFile !== false) {
Expand Down Expand Up @@ -2820,4 +2822,129 @@ public function getImageScale($width, $height) {

return $ratio;
}

/**
* @param $attr
* @param string $sep
*
* @return array
*/
function splitCSV($attr, $sep=',') {

if (strpos($attr, $sep) > 0) {
return preg_split('/\s*' . $sep . '\s*/', $attr);
} elseif ($sep !== ',' && strpos($attr, ',') > 0) {
return preg_split('/\s*,\s*/', $attr);
} elseif (strpos($attr, ';') > 0) {
return preg_split('/\s*;\s*/', $attr);
} else {
return preg_split('/\s+/', $attr);
}
}

/**
* Copyright WikiMedia:
* https://doc.wikimedia.org/mediawiki-core/master/php/SVGMetadataExtractor_8php_source.html
*
* @param $length
* @param int $portSize
*
* @return float
*/
public function scaleSVGUnit( $length, $portSize = 512 ) {
static $unitLength = array(
'px' => 1.0,
'pt' => 1.25,
'pc' => 15.0,
'mm' => 3.543307,
'cm' => 35.43307,
'in' => 90.0,
'em' => 16.0, // fake it?
'ex' => 12.0, // fake it?
'' => 1.0, // "User units" pixels by default
);
$matches = array();
if ( preg_match( '/^\s*(\d+(?:\.\d+)?)(em|ex|px|pt|pc|cm|mm|in|%|)\s*$/', $length, $matches ) ) {
$length = floatval( $matches[1] );
$unit = $matches[2];
if ( $unit == '%' ) {
return $length * 0.01 * $portSize;
} else {
return $length * $unitLength[$unit];
}
} else {
// Assume pixels
return floatval( $length );
}
}

/**
* @param SimpleXMLElement $svg
*
* @return array
*/
public function handleSVGAttribs($svg) {
$metadata = array();
$attr = $svg->attributes();
$viewWidth = 0;
$viewHeight = 0;
$aspect = 1.0;
$x = null;
$y = null;
$width = null;
$height = null;

if ( $attr->viewBox ) {
// min-x min-y width height
$viewBoxAttr = trim( $attr->viewBox );

$viewBox = $this->splitCSV($viewBoxAttr);
if ( count( $viewBox ) == 4 ) {
$viewWidth = $this->scaleSVGUnit( $viewBox[2] );
$viewHeight = $this->scaleSVGUnit( $viewBox[3] );
if ( $viewWidth > 0 && $viewHeight > 0 ) {
$aspect = $viewWidth / $viewHeight;
}
}
}

if ( $attr->x) {
$x = $this->scaleSVGUnit( $attr->x, 0);
$metadata['originalX'] = "".$attr->x;
}
if ( $attr->y) {
$y = $this->scaleSVGUnit( $attr->y, 0);
$metadata['originalY'] = "".$attr->y;
}

if ( $attr->width ) {
$width = $this->scaleSVGUnit( $attr->width, $viewWidth );
$metadata['originalWidth'] = "".$attr->width;
}
if ( $attr->height ) {
$height = $this->scaleSVGUnit( $attr->height, $viewHeight );
$metadata['originalHeight'] = "".$attr->height;
}

if ( !isset( $width ) && !isset( $height ) ) {
$width = 512;
$height = $width / $aspect;
} elseif ( isset( $width ) && !isset( $height ) ) {
$height = $width / $aspect;
} elseif ( isset( $height ) && !isset( $width ) ) {
$width = $height * $aspect;
}

if ( $x > 0 && $y > 0 ) {
$metadata['x'] = intval( round( $x ) );
$metadata['y'] = intval( round( $y ) );
}
if ( $width > 0 && $height > 0 ) {
$metadata['width'] = intval( round( $width ) );
$metadata['height'] = intval( round( $height ) );
$metadata['aspect'] = $aspect;
}

return $metadata;
}
}
1 change: 1 addition & 0 deletions tests/EPub.ExampleImg.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
. "<p><img src='demo/rxhVVUP.gif' alt='Animated Gif' /></p>\n"
. "<p><img src='demo/512x700_2.jpg' alt='none' /></p>\n"
. "<p><img src='demo/512x700_3.jpg' alt='Demo 2' /></p>\n"
. "<p><img src='demo/test.svg' alt='Demo SVG 1' /></p>\n"
. $bookEnd;

$book->setCoverImage('demo/512x700_1.jpg');
Expand Down
10 changes: 10 additions & 0 deletions tests/demo/test.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit c10bb64

Please sign in to comment.