summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKore Nordmann <github@kore-nordmann.de>2006-09-06 09:34:53 +0000
committerKore Nordmann <github@kore-nordmann.de>2006-09-06 09:34:53 +0000
commitb7b8d6da07309da4e16397f662a4e2db46c0869a (patch)
treea76a982bef0844f6d3d0eeb7089a7e8a5dfb2ee0 /src
parent4e50ab6291dc2430ef9ce4cc42c100c021e1a3b0 (diff)
downloadzetacomponents-graph-b7b8d6da07309da4e16397f662a4e2db46c0869a.zip
zetacomponents-graph-b7b8d6da07309da4e16397f662a4e2db46c0869a.tar.gz
- Enhanced font configuration
- Use Free Type 2 by default now, fallback to native ttf, if not available - Use t1lib for PostScript Type1 fonts - Throw an exception, if some texts could not be rendered with minimum font size
Diffstat (limited to 'src')
-rw-r--r--src/driver/gd.php184
-rw-r--r--src/exceptions/font_rendering.php25
-rw-r--r--src/graph.php5
-rw-r--r--src/graph_autoload.php4
-rw-r--r--src/math/boundings.php (renamed from src/structs/boundings.php)18
-rw-r--r--src/options/font.php15
-rw-r--r--src/options/gd_driver.php6
7 files changed, 206 insertions, 51 deletions
diff --git a/src/driver/gd.php b/src/driver/gd.php
index c4770ce..6d066e6 100644
--- a/src/driver/gd.php
+++ b/src/driver/gd.php
@@ -40,6 +40,16 @@ class ezcGraphGdDriver extends ezcGraphDriver
*/
protected $strings = array();
+ /**
+ * Contains ressources for already loaded ps fonts.
+ * array(
+ * path => ressource
+ * )
+ *
+ * @var array
+ */
+ protected $psFontRessources = array();
+
public function __construct( array $options = array() )
{
$this->options = new ezcGraphGdDriverOptions( $options );
@@ -196,6 +206,114 @@ class ezcGraphGdDriver extends ezcGraphDriver
);
}
+ /**
+ * Returns boundings of text
+ *
+ * @param float $size Textsize
+ * @param ezcGraphFontOptions $font Font
+ * @param string $text Text
+ * @return ezcGraphBoundings Boundings of text
+ */
+ protected function getTextBoundings( $size, ezcGraphFontOptions $font, $text )
+ {
+ switch( $font->type )
+ {
+ case ezcGraph::PS_FONT:
+ if ( !isset( $this->psFontRessources[$font->path] ) )
+ {
+ $this->psFontRessources[$font->path] = imagePsLoadFont( $font->path );
+ }
+
+ $boundings = imagePsBBox( $text, $this->psFontRessources[$font->path], $size );
+ return new ezcGraphBoundings(
+ $boundings[0],
+ $boundings[1],
+ $boundings[2],
+ $boundings[3]
+ );
+ case ezcGraph::TTF_FONT:
+ switch ( true )
+ {
+ case function_exists( 'imageftbbox' ) && !$this->options->forceNativeTTF:
+ $boundings = imageFtBBox( $size, 0, $font->path, $text );
+ return new ezcGraphBoundings(
+ $boundings[0],
+ $boundings[1],
+ $boundings[4],
+ $boundings[5]
+ );
+ case function_exists( 'imagettfbbox' ):
+ $boundings = imageTtfBBox( $size, 0, $font->path, $text );
+ return new ezcGraphBoundings(
+ $boundings[0],
+ $boundings[1],
+ $boundings[4],
+ $boundings[5]
+ );
+ }
+ break;
+ }
+ }
+
+ /**
+ * Render text depending of font type and available font extensions
+ *
+ * @param ressource $image Image ressource
+ * @param string $text Text
+ * @param ezcGraphFontOptions $font Font
+ * @param ezcGraphCoordinate $position Position
+ * @param float $size Textsize
+ * @param ezcGraphColor $color Textcolor
+ * @return void
+ */
+ protected function renderText( $image, $text, ezcGraphFontOptions $font, ezcGraphCoordinate $position, $size )
+ {
+ switch( $font->type )
+ {
+ case ezcGraph::PS_FONT:
+ imagePsText(
+ $image,
+ $text,
+ $this->psFontRessources[$font->path],
+ $size,
+ $this->allocate( $font->color ),
+ 1,
+ $position->x,
+ $position->y
+ );
+ break;
+ case ezcGraph::TTF_FONT:
+ switch ( true )
+ {
+ case function_exists( 'imagefttext' ) && !$this->options->forceNativeTTF:
+ imageFtText(
+ $image,
+ $size,
+ 0,
+ $position->x,
+ $position->y,
+ $this->allocate( $font->color ),
+ $font->path,
+ $text
+ );
+ break;
+ case function_exists( 'imagettftext' ):
+ imageTtfText(
+ $image,
+ $size,
+ 0,
+ $position->x,
+ $position->y,
+ $this->allocate( $font->color ),
+ $font->path,
+ $text
+ );
+ break;
+ }
+ break;
+ }
+ }
+
protected function testFitStringInTextBox( $string, ezcGraphCoordinate $position, $width, $height, $size )
{
// Tokenize String
@@ -209,10 +327,10 @@ class ezcGraphGdDriver extends ezcGraphDriver
$selectedLine = $lines[$line];
$selectedLine[] = $token;
- $boundings = imagettfbbox( $size, 0, $this->options->font->path, implode( ' ', $selectedLine ) );
+ $boundings = $this->getTextBoundings( $size, $this->options->font, implode( ' ', $selectedLine ) );
// Check if line is too long
- if ( $boundings[2] > $width )
+ if ( $boundings->width > $width )
{
if ( count( $selectedLine ) == 1 )
{
@@ -240,8 +358,8 @@ class ezcGraphGdDriver extends ezcGraphDriver
}
// Check width of last line
- $boundings = imagettfbbox( $size, 0, $this->options->font->path, implode( ' ', $lines[$line] ) );
- if ( $boundings[2] > $width ) {
+ $boundings = $this->getTextBoundings( $size, $this->options->font, implode( ' ', $lines[$line] ) );
+ if ( $boundings->width > $width ) {
return false;
}
@@ -290,12 +408,12 @@ class ezcGraphGdDriver extends ezcGraphDriver
'width' => $width,
'height' => $height,
'align' => $align,
- 'options' => $this->options->font,
+ 'font' => $this->options->font,
);
}
else
{
- // @TODO: Try to fit text in box with minimum font size
+ throw new ezcGraphFontRenderingException( $string, $this->options->font->minFontSize, $width, $height );
}
}
@@ -305,9 +423,7 @@ class ezcGraphGdDriver extends ezcGraphDriver
foreach ( $this->strings as $text )
{
- $size = $text['options']->minimalUsedFont;
- $font = $text['options']->path;
- $drawColor = $this->allocate( $text['options']->color );
+ $size = $text['font']->minimalUsedFont;
$completeHeight = count( $text['text'] ) * $size + ( count( $text['text'] ) - 1 ) * $this->options->lineSpacing;
@@ -330,45 +446,45 @@ class ezcGraphGdDriver extends ezcGraphDriver
foreach ( $text['text'] as $line )
{
$string = implode( ' ', $line );
- $boundings = imagettfbbox( $size, 0, $font, $string );
+ $boundings = $this->getTextBoundings( $size, $text['font'], $string );
$text['position']->y += $size;
switch ( true )
{
case ( $text['align'] & ezcGraph::LEFT ):
- imagettftext(
+ $this->renderText(
$image,
- $size,
- 0,
- $text['position']->x,
- $text['position']->y + $yOffset,
- $drawColor,
- $font,
- $string
+ $string,
+ $text['font'],
+ new ezcGraphCoordinate(
+ $text['position']->x,
+ $text['position']->y + $yOffset
+ ),
+ $size
);
break;
case ( $text['align'] & ezcGraph::RIGHT ):
- imagettftext(
+ $this->renderText(
$image,
- $size,
- 0,
- $text['position']->x + ( $text['width'] - $boundings[2] ),
- $text['position']->y + $yOffset,
- $drawColor,
- $font,
- $string
+ $string,
+ $text['font'],
+ new ezcGraphCoordinate(
+ $text['position']->x + ( $text['width'] - $boundings->width ),
+ $text['position']->y + $yOffset
+ ),
+ $size
);
break;
case ( $text['align'] & ezcGraph::CENTER ):
- imagettftext(
+ $this->renderText(
$image,
- $size,
- 0,
- $text['position']->x + ( ( $text['width'] - $boundings[2] ) / 2 ),
- $text['position']->y + $yOffset,
- $drawColor,
- $font,
- $string
+ $string,
+ $text['font'],
+ new ezcGraphCoordinate(
+ $text['position']->x + ( ( $text['width'] - $boundings->width ) / 2 ),
+ $text['position']->y + $yOffset
+ ),
+ $size
);
break;
}
diff --git a/src/exceptions/font_rendering.php b/src/exceptions/font_rendering.php
new file mode 100644
index 0000000..7bebe2a
--- /dev/null
+++ b/src/exceptions/font_rendering.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * File containing the ezcGraphFontRenderingException class
+ *
+ * @package Graph
+ * @version //autogen//
+ * @copyright Copyright (C) 2005, 2006 eZ systems as. All rights reserved.
+ * @license http://ez.no/licenses/new_bsd New BSD License
+ */
+/**
+ * Exception thrown when it is not possible to render a string beacause of
+ * minimum font size in the desinated bounding box.
+ *
+ * @package Graph
+ * @version //autogen//
+ */
+class ezcGraphFontRenderingException extends ezcGraphException
+{
+ public function __construct( $string, $size, $width, $height )
+ {
+ parent::__construct( "Could not fit string <{$string}> with font size <{$size}> in box <{$width} * {$height}>." );
+ }
+}
+
+?>
diff --git a/src/graph.php b/src/graph.php
index f0a652b..0a9ffac 100644
--- a/src/graph.php
+++ b/src/graph.php
@@ -38,11 +38,6 @@ class ezcGraph
const TTF_FONT = 1;
// PostScript Type1 fonts
const PS_FONT = 2;
- // FreeType 2 fonts
- const FT2_FONT = 3;
- // Native GD bitmap fonts
- const GD_FONT = 4;
-
}
?>
diff --git a/src/graph_autoload.php b/src/graph_autoload.php
index cc89d22..f415aa6 100644
--- a/src/graph_autoload.php
+++ b/src/graph_autoload.php
@@ -46,6 +46,8 @@ return array(
'ezcGraphAxisBoxedLabelRenderer' => 'Graph/renderer/axis_label_boxed.php',
'ezcGraphDriver' => 'Graph/interfaces/driver.php',
+ 'ezcGraphFontRenderingException' => 'Graph/exceptions/font_rendering.php',
+ 'ezcGraphUnknownFontTypeException' => 'Graph/exceptions/font_type.php',
'ezcGraphDriverOptions' => 'Graph/options/driver.php',
'ezcGraphGdDriver' => 'Graph/driver/gd.php',
'ezcGraphGdDriverOptions' => 'Graph/options/gd_driver.php',
@@ -91,8 +93,8 @@ return array(
'ezcGraphMatrixInvalidDimensionsException' => 'Graph/exceptions/invalid_dimensions.php',
'ezcGraphMatrixOutOfBoundingsException' => 'Graph/exceptions/out_of_boundings.php',
'ezcGraphPolynom' => 'Graph/math/polynom.php',
+ 'ezcGraphBoundings' => 'Graph/math/boundings.php',
- 'ezcGraphBoundings' => 'Graph/structs/boundings.php',
'ezcGraphCoordinate' => 'Graph/structs/coordinate.php',
);
diff --git a/src/structs/boundings.php b/src/math/boundings.php
index ee58305..78ce6cb 100644
--- a/src/structs/boundings.php
+++ b/src/math/boundings.php
@@ -39,17 +39,17 @@ class ezcGraphBoundings
/**
* Throws a BasePropertyNotFound exception.
*/
- public function __set( $name, $value )
- {
- throw new ezcBasePropertyNotFoundException( $name );
- }
-
- /**
- * Throws a BasePropertyNotFound exception.
- */
public function __get( $name )
{
- throw new ezcBasePropertyNotFoundException( $name );
+ switch ( $name )
+ {
+ case 'width':
+ return $this->x1 - $this->x0;
+ case 'height':
+ return $this->y1 - $this->y0;
+ default:
+ throw new ezcBasePropertyNotFoundException( $name );
+ }
}
}
diff --git a/src/options/font.php b/src/options/font.php
index 9f3b744..2da92ad 100644
--- a/src/options/font.php
+++ b/src/options/font.php
@@ -106,8 +106,19 @@ class ezcGraphFontOptions extends ezcBaseOptions
case 'path':
if ( is_file( $propertyValue ) && is_readable( $propertyValue ) )
{
- $this->properties['path'] = $propertyValue;
- // @TODO: Autodetect font type
+ $this->properties['path'] = realpath( $propertyValue );
+ $parts = pathinfo( $this->properties['path'] );
+ switch ( strtolower( $parts['extension'] ) )
+ {
+ case 'pfb':
+ $this->properties['type'] = ezcGraph::PS_FONT;
+ break;
+ case 'ttf':
+ $this->properties['type'] = ezcGraph::TTF_FONT;
+ break;
+ default:
+ throw new ezcGraphUnknownFontTypeException( $propertyValue, $parts['extension'] );
+ }
}
else
{
diff --git a/src/options/gd_driver.php b/src/options/gd_driver.php
index a6e756d..2faddd7 100644
--- a/src/options/gd_driver.php
+++ b/src/options/gd_driver.php
@@ -21,6 +21,8 @@
* Background image to put the graph on
* @property string $resampleFunction
* Function used to resample / resize images
+ * @property bool $forceNativeTTF
+ * Force use of native ttf functions instead of free type 2
*
* @package Graph
*/
@@ -41,6 +43,7 @@ class ezcGraphGdDriverOptions extends ezcGraphDriverOptions
$this->properties['supersampling'] = 2;
$this->properties['background'] = false;
$this->properties['resampleFunction'] = 'imagecopyresampled';
+ $this->properties['forceNativeTTF'] = false;
parent::__construct( $options );
}
@@ -95,6 +98,9 @@ class ezcGraphGdDriverOptions extends ezcGraphDriverOptions
throw new ezcBaseValueException( $propertyName, $propertyValue, 'function' );
}
break;
+ case 'forceNativeTTF':
+ $this->properties['forceNativeTTF'] = (bool) $propertyValue;
+ break;
default:
parent::__set( $propertyName, $propertyValue );
break;
OpenPOWER on IntegriCloud