diff options
Diffstat (limited to 'html/jpgraph/gd_image.inc.php')
| -rw-r--r-- | html/jpgraph/gd_image.inc.php | 2304 |
1 files changed, 0 insertions, 2304 deletions
diff --git a/html/jpgraph/gd_image.inc.php b/html/jpgraph/gd_image.inc.php deleted file mode 100644 index fecc401..0000000 --- a/html/jpgraph/gd_image.inc.php +++ /dev/null @@ -1,2304 +0,0 @@ -<?php -//======================================================================= -// File: GD_IMAGE.INC.PHP -// Description: PHP Graph Plotting library. Low level image drawing routines -// Created: 2001-01-08, refactored 2008-03-29 -// Ver: $Id: gd_image.inc.php 1922 2010-01-11 11:42:50Z ljp $ -// -// Copyright (c) Asial Corporation. All rights reserved. -//======================================================================== - -require_once 'jpgraph_rgb.inc.php'; -require_once 'jpgraph_ttf.inc.php'; -require_once 'imageSmoothArc.php'; - -// Line styles -define('LINESTYLE_SOLID',1); -define('LINESTYLE_DOTTED',2); -define('LINESTYLE_DASHED',3); -define('LINESTYLE_LONGDASH',4); - -// The DEFAULT_GFORMAT sets the default graphic encoding format, i.e. -// PNG, JPG or GIF depending on what is installed on the target system -// in that order. -if( !DEFINED("DEFAULT_GFORMAT") ) { - define("DEFAULT_GFORMAT","auto"); -} - -//======================================================================== -// CLASS Image -// Description: The very coor image drawing class that encapsulates all -// calls to the GD library -// Note: The class used by the library is the decendant -// class RotImage which extends the Image class with transparent -// rotation. -//========================================================================= -class Image { - public $img=null; - public $rgb=null; - public $img_format; - public $ttf=null; - public $line_style=LINESTYLE_SOLID; - public $current_color,$current_color_name; - public $original_width=0, $original_height=0; - public $plotwidth=0,$plotheight=0; - - // for __get, __set - private $_left_margin=30,$_right_margin=30,$_top_margin=20,$_bottom_margin=30; - //private $_plotwidth=0,$_plotheight=0; - private $_width=0, $_height=0; - private $_line_weight=1; - - protected $expired=true; - protected $lastx=0, $lasty=0; - protected $obs_list=array(); - protected $font_size=12,$font_family=FF_DEFAULT, $font_style=FS_NORMAL; - protected $font_file=''; - protected $text_halign="left",$text_valign="bottom"; - protected $use_anti_aliasing=false; - protected $quality=null; - protected $colorstack=array(),$colorstackidx=0; - protected $canvascolor = 'white' ; - protected $langconv = null ; - protected $iInterlace=false; - protected $bbox_cache = array(); // STore the last found tetx bounding box - protected $ff_font0; - protected $ff_font0_bold; - protected $ff_font1; - protected $ff_font1_bold; - protected $ff_font2; - protected $ff_font2_bold; - - - //--------------- - // CONSTRUCTOR - function __construct($aWidth=0,$aHeight=0,$aFormat=DEFAULT_GFORMAT,$aSetAutoMargin=true) { - - $this->original_width = $aWidth; - $this->original_height = $aHeight; - $this->CreateImgCanvas($aWidth, $aHeight); - - if( $aSetAutoMargin ) { - $this->SetAutoMargin(); - } - - if( !$this->SetImgFormat($aFormat) ) { - JpGraphError::RaiseL(25081,$aFormat);//("JpGraph: Selected graphic format is either not supported or unknown [$aFormat]"); - } - $this->ttf = new TTF(); - $this->langconv = new LanguageConv(); - - $this->ff_font0 = imageloadfont(dirname(__FILE__) . "/fonts/FF_FONT0.gdf"); - $this->ff_font1 = imageloadfont(dirname(__FILE__) . "/fonts/FF_FONT1.gdf"); - $this->ff_font2 = imageloadfont(dirname(__FILE__) . "/fonts/FF_FONT2.gdf"); - $this->ff_font1_bold = imageloadfont(dirname(__FILE__) . "/fonts/FF_FONT1-Bold.gdf"); - $this->ff_font2_bold = imageloadfont(dirname(__FILE__) . "/fonts/FF_FONT2-Bold.gdf"); - } - - // Enable interlacing in images - function SetInterlace($aFlg=true) { - $this->iInterlace=$aFlg; - } - - // Should we use anti-aliasing. Note: This really slows down graphics! - function SetAntiAliasing($aFlg=true) { - $this->use_anti_aliasing = $aFlg; - if( function_exists('imageantialias') ) { - imageantialias($this->img,$aFlg); - } - else { - JpGraphError::RaiseL(25128);//('The function imageantialias() is not available in your PHP installation. Use the GD version that comes with PHP and not the standalone version.') - } - } - - function GetAntiAliasing() { - return $this->use_anti_aliasing ; - } - - function CreateRawCanvas($aWidth=0,$aHeight=0) { - - $aWidth *= SUPERSAMPLING_SCALE; - $aHeight *= SUPERSAMPLING_SCALE; - - if( $aWidth <= 1 || $aHeight <= 1 ) { - JpGraphError::RaiseL(25082,$aWidth,$aHeight);//("Illegal sizes specified for width or height when creating an image, (width=$aWidth, height=$aHeight)"); - } - - $this->img = @imagecreatetruecolor($aWidth, $aHeight); - if( $this->img < 1 ) { - JpGraphError::RaiseL(25126); - //die("Can't create truecolor image. Check that you really have GD2 library installed."); - } - $this->SetAlphaBlending(); - - if( $this->iInterlace ) { - imageinterlace($this->img,1); - } - if( $this->rgb != null ) { - $this->rgb->img = $this->img ; - } - else { - $this->rgb = new RGB($this->img); - } - } - - function CloneCanvasH() { - $oldimage = $this->img; - $this->CreateRawCanvas($this->width,$this->height); - imagecopy($this->img,$oldimage,0,0,0,0,$this->width,$this->height); - return $oldimage; - } - - function CreateImgCanvas($aWidth=0,$aHeight=0) { - - $old = array($this->img,$this->width,$this->height); - - $aWidth = round($aWidth); - $aHeight = round($aHeight); - - $this->width=$aWidth; - $this->height=$aHeight; - - - if( $aWidth==0 || $aHeight==0 ) { - // We will set the final size later. - // Note: The size must be specified before any other - // img routines that stroke anything are called. - $this->img = null; - $this->rgb = null; - return $old; - } - - $this->CreateRawCanvas($aWidth,$aHeight); - // Set canvas color (will also be the background color for a - // a pallett image - $this->SetColor($this->canvascolor); - $this->FilledRectangle(0,0,$this->width-1,$this->height-1); - - return $old ; - } - - function CopyCanvasH($aToHdl,$aFromHdl,$aToX,$aToY,$aFromX,$aFromY,$aWidth,$aHeight,$aw=-1,$ah=-1) { - if( $aw === -1 ) { - $aw = $aWidth; - $ah = $aHeight; - $f = 'imagecopyresized'; - } - else { - $f = 'imagecopyresampled'; - } - $f($aToHdl,$aFromHdl,$aToX,$aToY,$aFromX,$aFromY, $aWidth,$aHeight,$aw,$ah); - } - - function Copy($fromImg,$toX,$toY,$fromX,$fromY,$toWidth,$toHeight,$fromWidth=-1,$fromHeight=-1) { - $this->CopyCanvasH($this->img,$fromImg,$toX,$toY,$fromX,$fromY,$toWidth,$toHeight,$fromWidth,$fromHeight); - } - - function CopyMerge($fromImg,$toX,$toY,$fromX,$fromY,$toWidth,$toHeight,$fromWidth=-1,$fromHeight=-1,$aMix=100) { - if( $aMix == 100 ) { - $this->CopyCanvasH($this->img,$fromImg, - $toX,$toY,$fromX,$fromY,$toWidth,$toHeight,$fromWidth,$fromHeight); - } - else { - if( ($fromWidth != -1 && ($fromWidth != $toWidth)) || ($fromHeight != -1 && ($fromHeight != $fromHeight)) ) { - // Create a new canvas that will hold the re-scaled original from image - if( $toWidth <= 1 || $toHeight <= 1 ) { - JpGraphError::RaiseL(25083);//('Illegal image size when copying image. Size for copied to image is 1 pixel or less.'); - } - - $tmpimg = @imagecreatetruecolor($toWidth, $toHeight); - - if( $tmpimg < 1 ) { - JpGraphError::RaiseL(25084);//('Failed to create temporary GD canvas. Out of memory ?'); - } - $this->CopyCanvasH($tmpimg,$fromImg,0,0,0,0, - $toWidth,$toHeight,$fromWidth,$fromHeight); - $fromImg = $tmpimg; - } - imagecopymerge($this->img,$fromImg,$toX,$toY,$fromX,$fromY,$toWidth,$toHeight,$aMix); - } - } - - static function GetWidth($aImg=null) { - if( $aImg === null ) { - $aImg = $this->img; - } - return imagesx($aImg); - } - - static function GetHeight($aImg=null) { - if( $aImg === null ) { - $aImg = $this->img; - } - return imagesy($aImg); - } - - static function CreateFromString($aStr) { - $img = imagecreatefromstring($aStr); - if( $img === false ) { - JpGraphError::RaiseL(25085); - //('An image can not be created from the supplied string. It is either in a format not supported or the string is representing an corrupt image.'); - } - return $img; - } - - function SetCanvasH($aHdl) { - $this->img = $aHdl; - $this->rgb->img = $aHdl; - } - - function SetCanvasColor($aColor) { - $this->canvascolor = $aColor ; - } - - function SetAlphaBlending($aFlg=true) { - ImageAlphaBlending($this->img,$aFlg); - } - - function SetAutoMargin() { - $min_bm=5; - $lm = min(40,$this->width/7); - $rm = min(20,$this->width/10); - $tm = max(5,$this->height/7); - $bm = max($min_bm,$this->height/6); - $this->SetMargin($lm,$rm,$tm,$bm); - } - - //--------------- - // PUBLIC METHODS - - function SetFont($family,$style=FS_NORMAL,$size=10) { - $this->font_family=$family; - $this->font_style=$style; - $this->font_size=$size*SUPERSAMPLING_SCALE; - $this->font_file=''; - if( ($this->font_family==FF_FONT1 || $this->font_family==FF_FONT2) && $this->font_style==FS_BOLD ){ - ++$this->font_family; - } - if( $this->font_family > FF_FONT2+1 ) { // A TTF font so get the font file - - // Check that this PHP has support for TTF fonts - if( !function_exists('imagettfbbox') ) { - // use internal font when php is configured without '--with-ttf' - $this->font_family = FF_FONT1; -// JpGraphError::RaiseL(25087);//('This PHP build has not been configured with TTF support. You need to recompile your PHP installation with FreeType support.'); - } else { - $this->font_file = $this->ttf->File($this->font_family,$this->font_style); - } - } - } - - // Get the specific height for a text string - function GetTextHeight($txt="",$angle=0) { - $tmp = preg_split('/\n/',$txt); - $n = count($tmp); - $m=0; - for($i=0; $i< $n; ++$i) { - $m = max($m,strlen($tmp[$i])); - } - - if( $this->font_family <= FF_FONT2+1 ) { - if( $angle==0 ) { - $h = imagefontheight($this->font_family); - if( $h === false ) { - JpGraphError::RaiseL(25088);//('You have a misconfigured GD font support. The call to imagefontwidth() fails.'); - } - - return $n*$h; - } - else { - $w = @imagefontwidth($this->font_family); - if( $w === false ) { - JpGraphError::RaiseL(25088);//('You have a misconfigured GD font support. The call to imagefontwidth() fails.'); - } - - return $m*$w; - } - } - else { - $bbox = $this->GetTTFBBox($txt,$angle); - return $bbox[1]-$bbox[5]+1; - } - } - - // Estimate font height - function GetFontHeight($angle=0) { - $txt = "XOMg"; - return $this->GetTextHeight($txt,$angle); - } - - // Approximate font width with width of letter "O" - function GetFontWidth($angle=0) { - $txt = 'O'; - return $this->GetTextWidth($txt,$angle); - } - - // Get actual width of text in absolute pixels. Note that the width is the - // texts projected with onto the x-axis. Call with angle=0 to get the true - // etxt width. - function GetTextWidth($txt,$angle=0) { - - $tmp = preg_split('/\n/',$txt); - $n = count($tmp); - if( $this->font_family <= FF_FONT2+1 ) { - - $m=0; - for($i=0; $i < $n; ++$i) { - $l=strlen($tmp[$i]); - if( $l > $m ) { - $m = $l; - } - } - - if( $angle==0 ) { - $w = @imagefontwidth($this->font_family); - if( $w === false ) { - JpGraphError::RaiseL(25088);//('You have a misconfigured GD font support. The call to imagefontwidth() fails.'); - } - return $m*$w; - } - else { - // 90 degrees internal so height becomes width - $h = @imagefontheight($this->font_family); - if( $h === false ) { - JpGraphError::RaiseL(25089);//('You have a misconfigured GD font support. The call to imagefontheight() fails.'); - } - return $n*$h; - } - } - else { - // For TTF fonts we must walk through a lines and find the - // widest one which we use as the width of the multi-line - // paragraph - $m=0; - for( $i=0; $i < $n; ++$i ) { - $bbox = $this->GetTTFBBox($tmp[$i],$angle); - $mm = $bbox[2] - $bbox[0]; - if( $mm > $m ) - $m = $mm; - } - return $m; - } - } - - - // Draw text with a box around it - function StrokeBoxedText($x,$y,$txt,$dir=0,$fcolor="white",$bcolor="black", - $shadowcolor=false,$paragraph_align="left", - $xmarg=6,$ymarg=4,$cornerradius=0,$dropwidth=3) { - - $oldx = $this->lastx; - $oldy = $this->lasty; - - if( !is_numeric($dir) ) { - if( $dir=="h" ) $dir=0; - elseif( $dir=="v" ) $dir=90; - else JpGraphError::RaiseL(25090,$dir);//(" Unknown direction specified in call to StrokeBoxedText() [$dir]"); - } - - if( $this->font_family >= FF_FONT0 && $this->font_family <= FF_FONT2+1) { - $width=$this->GetTextWidth($txt,$dir) ; - $height=$this->GetTextHeight($txt,$dir) ; - } - else { - $width=$this->GetBBoxWidth($txt,$dir) ; - $height=$this->GetBBoxHeight($txt,$dir) ; - } - - $height += 2*$ymarg; - $width += 2*$xmarg; - - if( $this->text_halign=="right" ) $x -= $width; - elseif( $this->text_halign=="center" ) $x -= $width/2; - - if( $this->text_valign=="bottom" ) $y -= $height; - elseif( $this->text_valign=="center" ) $y -= $height/2; - - $olda = $this->SetAngle(0); - - if( $shadowcolor ) { - $this->PushColor($shadowcolor); - $this->FilledRoundedRectangle($x-$xmarg+$dropwidth,$y-$ymarg+$dropwidth, - $x+$width+$dropwidth,$y+$height-$ymarg+$dropwidth, - $cornerradius); - $this->PopColor(); - $this->PushColor($fcolor); - $this->FilledRoundedRectangle($x-$xmarg,$y-$ymarg, - $x+$width,$y+$height-$ymarg, - $cornerradius); - $this->PopColor(); - $this->PushColor($bcolor); - $this->RoundedRectangle($x-$xmarg,$y-$ymarg, - $x+$width,$y+$height-$ymarg,$cornerradius); - $this->PopColor(); - } - else { - if( $fcolor ) { - $oc=$this->current_color; - $this->SetColor($fcolor); - $this->FilledRoundedRectangle($x-$xmarg,$y-$ymarg,$x+$width,$y+$height-$ymarg,$cornerradius); - $this->current_color=$oc; - } - if( $bcolor ) { - $oc=$this->current_color; - $this->SetColor($bcolor); - $this->RoundedRectangle($x-$xmarg,$y-$ymarg,$x+$width,$y+$height-$ymarg,$cornerradius); - $this->current_color=$oc; - } - } - - $h=$this->text_halign; - $v=$this->text_valign; - $this->SetTextAlign("left","top"); - - $debug=false; - $this->StrokeText($x, $y, $txt, $dir, $paragraph_align,$debug); - - $bb = array($x-$xmarg,$y+$height-$ymarg,$x+$width,$y+$height-$ymarg, - $x+$width,$y-$ymarg,$x-$xmarg,$y-$ymarg); - $this->SetTextAlign($h,$v); - - $this->SetAngle($olda); - $this->lastx = $oldx; - $this->lasty = $oldy; - - return $bb; - } - - // Draw text with a box around it. This time the box will be rotated - // with the text. The previous method will just make a larger enough non-rotated - // box to hold the text inside. - function StrokeBoxedText2($x,$y,$txt,$dir=0,$fcolor="white",$bcolor="black", - $shadowcolor=false,$paragraph_align="left", - $xmarg=6,$ymarg=4,$cornerradius=0,$dropwidth=3) { - - // This version of boxed text will stroke a rotated box round the text - // thta will follow the angle of the text. - // This has two implications: - // 1) This methos will only support TTF fonts - // 2) The only two alignment that makes sense are centered or baselined - - if( $this->font_family <= FF_FONT2+1 ) { - JpGraphError::RaiseL(25131);//StrokeBoxedText2() Only support TTF fonts and not built in bitmap fonts - } - - $oldx = $this->lastx; - $oldy = $this->lasty; - $dir = $this->NormAngle($dir); - - if( !is_numeric($dir) ) { - if( $dir=="h" ) $dir=0; - elseif( $dir=="v" ) $dir=90; - else JpGraphError::RaiseL(25090,$dir);//(" Unknown direction specified in call to StrokeBoxedText() [$dir]"); - } - - $width=$this->GetTextWidth($txt,0) + 2*$xmarg; - $height=$this->GetTextHeight($txt,0) + 2*$ymarg ; - $rect_width=$this->GetBBoxWidth($txt,$dir) ; - $rect_height=$this->GetBBoxHeight($txt,$dir) ; - - $baseline_offset = $this->bbox_cache[1]-1; - - if( $this->text_halign=="center" ) { - if( $dir >= 0 && $dir <= 90 ) { - - $x -= $rect_width/2; - $x += sin($dir*M_PI/180)*$height; - $y += $rect_height/2; - - } elseif( $dir >= 270 && $dir <= 360 ) { - - $x -= $rect_width/2; - $y -= $rect_height/2; - $y += cos($dir*M_PI/180)*$height; - - } elseif( $dir >= 90 && $dir <= 180 ) { - - $x += $rect_width/2; - $y += $rect_height/2; - $y += cos($dir*M_PI/180)*$height; - - } - else { - // $dir > 180 && $dir < 270 - $x += $rect_width/2; - $x += sin($dir*M_PI/180)*$height; - $y -= $rect_height/2; - } - } - - // Rotate the box around this point - $this->SetCenter($x,$y); - $olda = $this->SetAngle(-$dir); - - // We need to use adjusted coordinats for the box to be able - // to draw the box below the baseline. This cannot be done before since - // the rotating point must be the original x,y since that is arounbf the - // point where the text will rotate and we cannot change this since - // that is where the GD/GreeType will rotate the text - - - // For smaller <14pt font we need to do some additional - // adjustments to make it look good - if( $this->font_size < 14 ) { - $x -= 2; - $y += 2; - } - else { - // $y += $baseline_offset; - } - - if( $shadowcolor ) { - $this->PushColor($shadowcolor); - $this->FilledRectangle($x-$xmarg+$dropwidth,$y+$ymarg+$dropwidth-$height, - $x+$width+$dropwidth,$y+$ymarg+$dropwidth); - //$cornerradius); - $this->PopColor(); - $this->PushColor($fcolor); - $this->FilledRectangle($x-$xmarg, $y+$ymarg-$height, - $x+$width, $y+$ymarg); - //$cornerradius); - $this->PopColor(); - $this->PushColor($bcolor); - $this->Rectangle($x-$xmarg,$y+$ymarg-$height, - $x+$width,$y+$ymarg); - //$cornerradius); - $this->PopColor(); - } - else { - if( $fcolor ) { - $oc=$this->current_color; - $this->SetColor($fcolor); - $this->FilledRectangle($x-$xmarg,$y+$ymarg-$height,$x+$width,$y+$ymarg);//,$cornerradius); - $this->current_color=$oc; - } - if( $bcolor ) { - $oc=$this->current_color; - $this->SetColor($bcolor); - $this->Rectangle($x-$xmarg,$y+$ymarg-$height,$x+$width,$y+$ymarg);//,$cornerradius); - $this->current_color=$oc; - } - } - - if( $this->font_size < 14 ) { - $x += 2; - $y -= 2; - } - else { - - // Restore the original y before we stroke the text - // $y -= $baseline_offset; - - } - - $this->SetCenter(0,0); - $this->SetAngle($olda); - - $h=$this->text_halign; - $v=$this->text_valign; - if( $this->text_halign == 'center') { - $this->SetTextAlign('center','basepoint'); - } - else { - $this->SetTextAlign('basepoint','basepoint'); - } - - $debug=false; - $this->StrokeText($x, $y, $txt, $dir, $paragraph_align,$debug); - - $bb = array($x-$xmarg, $y+$height-$ymarg, - $x+$width, $y+$height-$ymarg, - $x+$width, $y-$ymarg, - $x-$xmarg, $y-$ymarg); - - $this->SetTextAlign($h,$v); - $this->SetAngle($olda); - - $this->lastx = $oldx; - $this->lasty = $oldy; - - return $bb; - } - - // Set text alignment - function SetTextAlign($halign,$valign="bottom") { - $this->text_halign=$halign; - $this->text_valign=$valign; - } - - function _StrokeBuiltinFont($x,$y,$txt,$dir,$paragraph_align,&$aBoundingBox,$aDebug=false) { - - if( is_numeric($dir) && $dir!=90 && $dir!=0) - JpGraphError::RaiseL(25091);//(" Internal font does not support drawing text at arbitrary angle. Use TTF fonts instead."); - - $h=$this->GetTextHeight($txt); - $fh=$this->GetFontHeight(); - $w=$this->GetTextWidth($txt); - - if( $this->text_halign=="right") { - $x -= $dir==0 ? $w : $h; - } - elseif( $this->text_halign=="center" ) { - // For center we subtract 1 pixel since this makes the middle - // be prefectly in the middle - $x -= $dir==0 ? $w/2-1 : $h/2; - } - if( $this->text_valign=="top" ) { - $y += $dir==0 ? $h : $w; - } - elseif( $this->text_valign=="center" ) { - $y += $dir==0 ? $h/2 : $w/2; - } - - $use_font = $this->font_family; - - if( $dir==90 ) { - imagestringup($this->img,$use_font,$x,$y,$txt,$this->current_color); - $aBoundingBox = array(round($x),round($y),round($x),round($y-$w),round($x+$h),round($y-$w),round($x+$h),round($y)); - if( $aDebug ) { - // Draw bounding box - $this->PushColor('green'); - $this->Polygon($aBoundingBox,true); - $this->PopColor(); - } - } - else { - if( preg_match('/\n/',$txt) ) { - $tmp = preg_split('/\n/',$txt); - for($i=0; $i < count($tmp); ++$i) { - $w1 = $this->GetTextWidth($tmp[$i]); - if( $paragraph_align=="left" ) { - imagestring($this->img,$use_font,$x,$y-$h+1+$i*$fh,$tmp[$i],$this->current_color); - } - elseif( $paragraph_align=="right" ) { - imagestring($this->img,$use_font,$x+($w-$w1),$y-$h+1+$i*$fh,$tmp[$i],$this->current_color); - } - else { - imagestring($this->img,$use_font,$x+$w/2-$w1/2,$y-$h+1+$i*$fh,$tmp[$i],$this->current_color); - } - } - } - else { - //Put the text - imagestring($this->img,$use_font,$x,$y-$h+1,$txt,$this->current_color); - } - if( $aDebug ) { - // Draw the bounding rectangle and the bounding box - $p1 = array(round($x),round($y),round($x),round($y-$h),round($x+$w),round($y-$h),round($x+$w),round($y)); - - // Draw bounding box - $this->PushColor('green'); - $this->Polygon($p1,true); - $this->PopColor(); - - } - $aBoundingBox=array(round($x),round($y),round($x),round($y-$h),round($x+$w),round($y-$h),round($x+$w),round($y)); - } - } - - function AddTxtCR($aTxt) { - // If the user has just specified a '\n' - // instead of '\n\t' we have to add '\r' since - // the width will be too muchy otherwise since when - // we print we stroke the individually lines by hand. - $e = explode("\n",$aTxt); - $n = count($e); - for($i=0; $i<$n; ++$i) { - $e[$i]=str_replace("\r","",$e[$i]); - } - return implode("\n\r",$e); - } - - function NormAngle($a) { - // Normalize angle in degrees - // Normalize angle to be between 0-360 - while( $a > 360 ) - $a -= 360; - while( $a < -360 ) - $a += 360; - if( $a < 0 ) - $a = 360 + $a; - return $a; - } - - function imagettfbbox_fixed($size, $angle, $fontfile, $text) { - - - if( ! USE_LIBRARY_IMAGETTFBBOX ) { - - $bbox = @imagettfbbox($size, $angle, $fontfile, $text); - if( $bbox === false ) { - JpGraphError::RaiseL(25092,$this->font_file); - //("There is either a configuration problem with TrueType or a problem reading font file (".$this->font_file."). Make sure file exists and is in a readable place for the HTTP process. (If 'basedir' restriction is enabled in PHP then the font file must be located in the document root.). It might also be a wrongly installed FreeType library. Try uppgrading to at least FreeType 2.1.13 and recompile GD with the correct setup so it can find the new FT library."); - } - $this->bbox_cache = $bbox; - return $bbox; - } - - // The built in imagettfbbox is buggy for angles != 0 so - // we calculate this manually by getting the bounding box at - // angle = 0 and then rotate the bounding box manually - $bbox = @imagettfbbox($size, 0, $fontfile, $text); - if( $bbox === false ) { - JpGraphError::RaiseL(25092,$this->font_file); - //("There is either a configuration problem with TrueType or a problem reading font file (".$this->font_file."). Make sure file exists and is in a readable place for the HTTP process. (If 'basedir' restriction is enabled in PHP then the font file must be located in the document root.). It might also be a wrongly installed FreeType library. Try uppgrading to at least FreeType 2.1.13 and recompile GD with the correct setup so it can find the new FT library."); - } - - $angle = $this->NormAngle($angle); - - $a = $angle*M_PI/180; - $ca = cos($a); - $sa = sin($a); - $ret = array(); - - // We always add 1 pixel to the left since the left edge of the bounding - // box is sometimes coinciding with the first pixel of the text - //$bbox[0] -= 1; - //$bbox[6] -= 1; - - // For roatated text we need to add extra width for rotated - // text since the kerning and stroking of the TTF is not the same as for - // text at a 0 degree angle - - if( $angle > 0.001 && abs($angle-360) > 0.001 ) { - $h = abs($bbox[7]-$bbox[1]); - $w = abs($bbox[2]-$bbox[0]); - - $bbox[0] -= 2; - $bbox[6] -= 2; - // The width is underestimated so compensate for that - $bbox[2] += round($w*0.06); - $bbox[4] += round($w*0.06); - - // and we also need to compensate with increased height - $bbox[5] -= round($h*0.1); - $bbox[7] -= round($h*0.1); - - if( $angle > 90 ) { - // For angles > 90 we also need to extend the height further down - // by the baseline since that is also one more problem - $bbox[1] += round($h*0.15); - $bbox[3] += round($h*0.15); - - // and also make it slighty less height - $bbox[7] += round($h*0.05); - $bbox[5] += round($h*0.05); - - // And we need to move the box slightly top the rright (from a tetx perspective) - $bbox[0] += round($w*0.02); - $bbox[6] += round($w*0.02); - - if( $angle > 180 ) { - // And we need to move the box slightly to the left (from a text perspective) - $bbox[0] -= round($w*0.02); - $bbox[6] -= round($w*0.02); - $bbox[2] -= round($w*0.02); - $bbox[4] -= round($w*0.02); - - } - - } - for($i = 0; $i < 7; $i += 2) { - $ret[$i] = round($bbox[$i] * $ca + $bbox[$i+1] * $sa); - $ret[$i+1] = round($bbox[$i+1] * $ca - $bbox[$i] * $sa); - } - $this->bbox_cache = $ret; - return $ret; - } - else { - $this->bbox_cache = $bbox; - return $bbox; - } - } - - // Deprecated - function GetTTFBBox($aTxt,$aAngle=0) { - $bbox = $this->imagettfbbox_fixed($this->font_size,$aAngle,$this->font_file,$aTxt); - return $bbox; - } - - function GetBBoxTTF($aTxt,$aAngle=0) { - // Normalize the bounding box to become a minimum - // enscribing rectangle - - $aTxt = $this->AddTxtCR($aTxt); - - if( !is_readable($this->font_file) ) { - JpGraphError::RaiseL(25093,$this->font_file); - //('Can not read font file ('.$this->font_file.') in call to Image::GetBBoxTTF. Please make sure that you have set a font before calling this method and that the font is installed in the TTF directory.'); - } - $bbox = $this->imagettfbbox_fixed($this->font_size,$aAngle,$this->font_file,$aTxt); - - if( $aAngle==0 ) return $bbox; - - if( $aAngle >= 0 ) { - if( $aAngle <= 90 ) { //<=0 - $bbox = array($bbox[6],$bbox[1],$bbox[2],$bbox[1], - $bbox[2],$bbox[5],$bbox[6],$bbox[5]); - } - elseif( $aAngle <= 180 ) { //<= 2 - $bbox = array($bbox[4],$bbox[7],$bbox[0],$bbox[7], - $bbox[0],$bbox[3],$bbox[4],$bbox[3]); - } - elseif( $aAngle <= 270 ) { //<= 3 - $bbox = array($bbox[2],$bbox[5],$bbox[6],$bbox[5], - $bbox[6],$bbox[1],$bbox[2],$bbox[1]); - } - else { - $bbox = array($bbox[0],$bbox[3],$bbox[4],$bbox[3], - $bbox[4],$bbox[7],$bbox[0],$bbox[7]); - } - } - elseif( $aAngle < 0 ) { - if( $aAngle <= -270 ) { // <= -3 - $bbox = array($bbox[6],$bbox[1],$bbox[2],$bbox[1], - $bbox[2],$bbox[5],$bbox[6],$bbox[5]); - } - elseif( $aAngle <= -180 ) { // <= -2 - $bbox = array($bbox[0],$bbox[3],$bbox[4],$bbox[3], - $bbox[4],$bbox[7],$bbox[0],$bbox[7]); - } - elseif( $aAngle <= -90 ) { // <= -1 - $bbox = array($bbox[2],$bbox[5],$bbox[6],$bbox[5], - $bbox[6],$bbox[1],$bbox[2],$bbox[1]); - } - else { - $bbox = array($bbox[0],$bbox[3],$bbox[4],$bbox[3], - $bbox[4],$bbox[7],$bbox[0],$bbox[7]); - } - } - return $bbox; - } - - function GetBBoxHeight($aTxt,$aAngle=0) { - $box = $this->GetBBoxTTF($aTxt,$aAngle); - return abs($box[7]-$box[1]); - } - - function GetBBoxWidth($aTxt,$aAngle=0) { - $box = $this->GetBBoxTTF($aTxt,$aAngle); - return $box[2]-$box[0]+1; - } - - - function _StrokeTTF($x,$y,$txt,$dir,$paragraph_align,&$aBoundingBox,$debug=false) { - - // Setup default inter line margin for paragraphs to be - // 3% of the font height. - $ConstLineSpacing = 0.03 ; - - // Remember the anchor point before adjustment - if( $debug ) { - $ox=$x; - $oy=$y; - } - - if( !preg_match('/\n/',$txt) || ($dir>0 && preg_match('/\n/',$txt)) ) { - // Format a single line - - $txt = $this->AddTxtCR($txt); - $bbox=$this->GetBBoxTTF($txt,$dir); - $width = $this->GetBBoxWidth($txt,$dir); - $height = $this->GetBBoxHeight($txt,$dir); - - // The special alignment "basepoint" is mostly used internally - // in the library. This will put the anchor position at the left - // basepoint of the tetx. This is the default anchor point for - // TTF text. - - if( $this->text_valign != 'basepoint' ) { - // Align x,y ot lower left corner of bbox - - - if( $this->text_halign=='right' ) { - $x -= $width; - $x -= $bbox[0]; - } - elseif( $this->text_halign=='center' ) { - $x -= $width/2; - $x -= $bbox[0]; - } - elseif( $this->text_halign=='baseline' ) { - // This is only support for text at 90 degree !! - // Do nothing the text is drawn at baseline by default - } - - if( $this->text_valign=='top' ) { - $y -= $bbox[1]; // Adjust to bottom of text - $y += $height; - } - elseif( $this->text_valign=='center' ) { - $y -= $bbox[1]; // Adjust to bottom of text - $y += $height/2; - } - elseif( $this->text_valign=='baseline' ) { - // This is only support for text at 0 degree !! - // Do nothing the text is drawn at baseline by default - } - } - ImageTTFText ($this->img, $this->font_size, $dir, $x, $y, - $this->current_color,$this->font_file,$txt); - - // Calculate and return the co-ordinates for the bounding box - $box = $this->imagettfbbox_fixed($this->font_size,$dir,$this->font_file,$txt); - $p1 = array(); - - for($i=0; $i < 4; ++$i) { - $p1[] = round($box[$i*2]+$x); - $p1[] = round($box[$i*2+1]+$y); - } - $aBoundingBox = $p1; - - // Debugging code to highlight the bonding box and bounding rectangle - // For text at 0 degrees the bounding box and bounding rectangle are the - // same - if( $debug ) { - // Draw the bounding rectangle and the bounding box - - $p = array(); - $p1 = array(); - - for($i=0; $i < 4; ++$i) { - $p[] = $bbox[$i*2]+$x ; - $p[] = $bbox[$i*2+1]+$y; - $p1[] = $box[$i*2]+$x ; - $p1[] = $box[$i*2+1]+$y ; - } - - // Draw bounding box - $this->PushColor('green'); - $this->Polygon($p1,true); - $this->PopColor(); - - // Draw bounding rectangle - $this->PushColor('darkgreen'); - $this->Polygon($p,true); - $this->PopColor(); - - // Draw a cross at the anchor point - $this->PushColor(' |
