diff options
author | Kore Nordmann <github@kore-nordmann.de> | 2007-05-10 09:52:09 +0000 |
---|---|---|
committer | Kore Nordmann <github@kore-nordmann.de> | 2007-05-10 09:52:09 +0000 |
commit | 9fe5c1ce375e75ce093ace1f251fc54bf391b5c8 (patch) | |
tree | 31e193c19dd67fd638c965d18cac99a91826dcf1 /src | |
parent | f01b8b1bdfb55dd7e77c8b9eec8def3989a6560c (diff) | |
download | zetacomponents-graph-9fe5c1ce375e75ce093ace1f251fc54bf391b5c8.zip zetacomponents-graph-9fe5c1ce375e75ce093ace1f251fc54bf391b5c8.tar.gz |
- Fixed issue #10746: Border size reducement algorithm fails for polygones
with edge lengths < reducement
# Modifications in comparision files because some invisible small shapes
# were not rendered any more
Diffstat (limited to 'src')
-rw-r--r-- | src/driver/flash.php | 18 | ||||
-rw-r--r-- | src/driver/svg.php | 16 | ||||
-rw-r--r-- | src/exceptions/reducement_failed.php | 25 | ||||
-rw-r--r-- | src/graph_autoload.php | 1 | ||||
-rw-r--r-- | src/interfaces/driver.php | 55 |
5 files changed, 109 insertions, 6 deletions
diff --git a/src/driver/flash.php b/src/driver/flash.php index 409b107..38c07a2 100644 --- a/src/driver/flash.php +++ b/src/driver/flash.php @@ -194,7 +194,14 @@ class ezcGraphFlashDriver extends ezcGraphDriver { // The middle of the border is on the outline of a polygon in ming, // fix that: - $points = $this->reducePolygonSize( $points, $thickness / 2 ); + try + { + $points = $this->reducePolygonSize( $points, $thickness / 2 ); + } + catch( ezcGraphReducementFailedException $e ) + { + return false; + } } $shape = new SWFShape(); @@ -616,7 +623,14 @@ class ezcGraphFlashDriver extends ezcGraphDriver if ( !$filled ) { - $reduced = $this->reduceEllipseSize( $center, $width, $height, $startAngle, $endAngle, .5 ); + try + { + $reduced = $this->reduceEllipseSize( $center, $width, $height, $startAngle, $endAngle, .5 ); + } + catch( ezcGraphReducementFailedException $e ) + { + return false; + } $startAngle = $reduced['startAngle']; $endAngle = $reduced['endAngle']; diff --git a/src/driver/svg.php b/src/driver/svg.php index daaa7c5..18ce4bd 100644 --- a/src/driver/svg.php +++ b/src/driver/svg.php @@ -332,7 +332,13 @@ class ezcGraphSvgDriver extends ezcGraphDriver { // The middle of the border is on the outline of a polygon in SVG, // fix that: - $points = $this->reducePolygonSize( $points, $thickness / 2 ); + try + { + $points = $this->reducePolygonSize( $points, $thickness / 2 ); + } catch ( ezcGraphReducementFailedException $e ) + { + return false; + } } $lastPoint = end( $points ); @@ -845,7 +851,13 @@ class ezcGraphSvgDriver extends ezcGraphDriver } else { - $reduced = $this->reduceEllipseSize( $center, $width * 2, $height * 2, $startAngle, $endAngle, .5 ); + try + { + $reduced = $this->reduceEllipseSize( $center, $width * 2, $height * 2, $startAngle, $endAngle, .5 ); + } catch ( ezcGraphReducementFailedException $e ) + { + return false; + } $arc = $this->dom->createElement( 'path' ); $arc->setAttribute( 'd', sprintf( 'M %.2f,%.2f L %.2f,%.2f A %.2f,%.2f 0 %d,1 %.2f,%.2f z', diff --git a/src/exceptions/reducement_failed.php b/src/exceptions/reducement_failed.php new file mode 100644 index 0000000..f14e88d --- /dev/null +++ b/src/exceptions/reducement_failed.php @@ -0,0 +1,25 @@ +<?php +/** + * File containing the ezcGraphReducementFailedException class + * + * @package Graph + * @version //autogen// + * @copyright Copyright (C) 2005-2007 eZ systems as. All rights reserved. + * @license http://ez.no/licenses/new_bsd New BSD License + */ +/** + * Exception thrown when a requested reducement of an ellipse or polygone + * failed because the shape was already too small. + * + * @package Graph + * @version //autogen// + */ +class ezcGraphReducementFailedException extends ezcGraphException +{ + public function __construct() + { + parent::__construct( "Reducement of shape failed, because it was already too small." ); + } +} + +?> diff --git a/src/graph_autoload.php b/src/graph_autoload.php index 1ee0bd1..12aea2b 100644 --- a/src/graph_autoload.php +++ b/src/graph_autoload.php @@ -12,6 +12,7 @@ return array( 'ezcGraphException' => 'Graph/exceptions/exception.php', 'ezcGraphDatasetAverageInvalidKeysException' => 'Graph/exceptions/invalid_keys.php', + 'ezcGraphReducementFailedException' => 'Graph/exceptions/reducement_failed.php', 'ezcGraphErrorParsingDateException' => 'Graph/exceptions/date_parsing.php', 'ezcGraphFlashBitmapBoundingsException' => 'Graph/exceptions/flash_bitmap_boundings.php', 'ezcGraphFlashBitmapTypeException' => 'Graph/exceptions/flash_bitmap_type.php', diff --git a/src/interfaces/driver.php b/src/interfaces/driver.php index 04025ac..a477eea 100644 --- a/src/interfaces/driver.php +++ b/src/interfaces/driver.php @@ -95,6 +95,7 @@ abstract class ezcGraphDriver * * @param array( ezcGraphCoordinate ) $points * @param float $size + * @throws ezcGraphReducementFailedException * @return array( ezcGraphCoordinate ) */ protected function reducePolygonSize( array $points, $size ) @@ -107,8 +108,14 @@ abstract class ezcGraphDriver { $nextPoint = ( $i + 1 ) % $pointCount; $vectors[$i] = ezcGraphVector::fromCoordinate( $points[$nextPoint] ) - ->sub( $points[$i] ) - ->unify(); + ->sub( $points[$i] ); + + // Throw exception if polygon is too small to reduce + if ( $vectors[$i]->length() < $size ) + { + throw new ezcGraphReducementFailedException(); + } + $vectors[$i]->unify(); if ( ( $vectors[$i]->x == $vectors[$i]->y ) && ( $vectors[$i]->x == 0 ) ) { @@ -218,6 +225,7 @@ abstract class ezcGraphDriver * @param mixed $startAngle * @param mixed $endAngle * @param mixed $size + * @throws ezcGraphReducementFailedException * @return array */ protected function reduceEllipseSize( ezcGraphCoordinate $center, $width, $height, $startAngle, $endAngle, $size ) @@ -254,6 +262,49 @@ abstract class ezcGraphDriver $centerMovement = clone $unifiedStartVector; $newCenter = $v->add( $centerMovement->scalar( $size / tan( ( $endAngle - $startAngle ) / 2 ) ) )->add( $center ); + // Test if center is still inside the ellipse, otherwise the sector + // was to small to be reduced + $innerBoundingBoxSize = 0.7 * min( $width, $height ); + if ( ( $newCenter->x < ( $center->x + $innerBoundingBoxSize ) ) && + ( $newCenter->x > ( $center->x - $innerBoundingBoxSize ) ) && + ( $newCenter->y < ( $center->y + $innerBoundingBoxSize ) ) && + ( $newCenter->y > ( $center->y - $innerBoundingBoxSize ) ) ) + { + // Point is in inner bounding box -> everything is OK + } + elseif ( ( $newCenter->x < ( $center->x - $width ) ) || + ( $newCenter->x > ( $center->x + $width ) ) || + ( $newCenter->y < ( $center->y - $height ) ) || + ( $newCenter->y > ( $center->y + $height ) ) ) + { + // Quick bounding box check + throw new ezcGraphReducementFailedException(); + } + else + { + // Perform exact check + $distance = new ezcGraphVector( + $newCenter->x - $center->x, + $newCenter->y - $center->y + ); + + // Convert elipse to circle for correct angle calculation + $direction = clone $distance; + $direction->y *= ( $width / $height ); + $angle = $direction->angle( new ezcGraphVector( 0, 1 ) ); + + $outerPoint = new ezcGraphVector( + sin( $angle ) * $width, + cos( $angle ) * $height + ); + + // Point is not in ellipse any more + if ( $distance->x > $outerPoint->x ) + { + throw new ezcGraphReducementFailedException(); + } + } + // Use start spanning vector and its orthogonal vector to calculate // new start point $newStartPoint = clone $oldStartPoint; |