summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKore Nordmann <github@kore-nordmann.de>2007-05-10 09:52:09 +0000
committerKore Nordmann <github@kore-nordmann.de>2007-05-10 09:52:09 +0000
commit9fe5c1ce375e75ce093ace1f251fc54bf391b5c8 (patch)
tree31e193c19dd67fd638c965d18cac99a91826dcf1 /src
parentf01b8b1bdfb55dd7e77c8b9eec8def3989a6560c (diff)
downloadzetacomponents-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.php18
-rw-r--r--src/driver/svg.php16
-rw-r--r--src/exceptions/reducement_failed.php25
-rw-r--r--src/graph_autoload.php1
-rw-r--r--src/interfaces/driver.php55
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;
OpenPOWER on IntegriCloud