diff options
author | Kore Nordmann <github@kore-nordmann.de> | 2006-09-06 09:34:53 +0000 |
---|---|---|
committer | Kore Nordmann <github@kore-nordmann.de> | 2006-09-06 09:34:53 +0000 |
commit | b7b8d6da07309da4e16397f662a4e2db46c0869a (patch) | |
tree | a76a982bef0844f6d3d0eeb7089a7e8a5dfb2ee0 /src | |
parent | 4e50ab6291dc2430ef9ce4cc42c100c021e1a3b0 (diff) | |
download | zetacomponents-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.php | 184 | ||||
-rw-r--r-- | src/exceptions/font_rendering.php | 25 | ||||
-rw-r--r-- | src/graph.php | 5 | ||||
-rw-r--r-- | src/graph_autoload.php | 4 | ||||
-rw-r--r-- | src/math/boundings.php (renamed from src/structs/boundings.php) | 18 | ||||
-rw-r--r-- | src/options/font.php | 15 | ||||
-rw-r--r-- | src/options/gd_driver.php | 6 |
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; |