|
|
 |
imagettfbbox (PHP 3 >= 3.0.1, PHP 4, PHP 5) imagettfbbox -- Give the bounding box of a text using TrueType fonts Descriptionarray imagettfbbox ( float size, float angle, string fontfile, string text )
This function calculates and returns the bounding box in pixels
for a TrueType text.
- text
The string to be measured. - size
The font size in pixels. - fontfile
The name of the TrueType font file (can be a URL). Depending on
which version of the GD library that PHP is using, it may attempt to
search for files that do not begin with a leading '/' by appending
'.ttf' to the filename and searching along a library-defined font path.
- angle
Angle in degrees in which text will be
measured.
imagettfbbox() returns an array with 8
elements representing four points making the bounding box of the
text:
The points are relative to the text
regardless of the angle, so "upper left" means in the top
left-hand corner seeing the text horizontally.
This function requires both the GD library and the FreeType
library.
See also imagettftext().
User Contributed Notes
imagettfbbox
php@da dot mcbf dot net
30-Apr-2005 09:37
Pretty trivial, but still might save someone some trouble: on my system (Debian Linux), the absolute path to the font file had to be specified. I tried it relative to the current webpage and that did not work.
vegard at I dot DONT dot WANT dot SPAM dot programmer dot no
04-Apr-2005 08:37
Here is a function that wordwraps text you want to print, allows to specify where the text should be printed, what the maximum width should be, and returns the height used.
<?php
function printWordWrapped(&$image, $top, $left, $maxWidth, $font, $color, $text, $textSize) {
$words = explode(' ', strip_tags($text)); $line = '';
while (count($words) > 0) {
$dimensions = imagettfbbox($textSize, 0, $font, $line.' '.$words[0]);
$lineWidth = $dimensions[2] - $dimensions[0]; if ($lineWidth > $maxWidth) { $lines[] = $line; $line = ''; }
$line .= ' '.$words[0]; $words = array_slice($words, 1); }
if ($line != '') { $lines[] = $line; } $lineHeight = $dimensions[1] - $dimensions[7]; $height = count($lines) * $lineHeight; $i = 0;
foreach ($lines as $line) {
imagettftext($image, $textSize, 0, $left, $top + $lineHeight * $i, $color, $font, $line);
$i++;
}
return $height;
}
?>
ryan at retronetworks dot com
28-Mar-2005 09:46
Here is a function that lets you write a string with your own "font tracking" level (the amount of pixels separating each character). It uses imagettfbbox to determine the width of each character, so it doesn't discriminate against the skinnier of characters. For this example, let $t = the amount of distance in pixels you want to separate each character from its neighbors.
<?php
function ImageTTFTextWithTracking($im, $size, $angle, $t, $x, $y, $color, $font, $text) {
$numchar = strlen($text);
for($i = 0; $i < $numchar; $i++) {
$char[$i] = substr($text, $i, 1);
imagettftext($im, $size, $angle, ($x + $w + ($i * $t)), $y, $color, $font, $char[$i]);
$width = imagettfbbox($size, $angle, $font, $char[$i]);
$w = $w + $width[2];
}
}
?>
Be aware that it currently does not work for angles other than the 0 default (I have no need for that).
soukhinov at mail dot ru
15-Mar-2005 06:00
I have tryed all of fixes
The David Eder's fix is the only working fix.
The "jtopland at hive dot no"s fix is good enough, but it not working with angle = 180 degrees.
webmaster at funfragforce dot de
10-Mar-2005 08:50
Here a little code snippet to align the text to horizontally center:
<?php
$insert = imagecreatefromgif("test.gif");
$text="TEST";
$font="arial.ttf";
$col=ImageColorAllocate ($insert, 0, 0, 0);
$bbox=imagettfbbox (12, 0, $font, $text);
$xcorr=0-$bbox[6];
$mase=$bbox[2]+$xcorr;
$width=imagesx($insert);
$new=($width-$mase)/2;
imagettftext ($insert, 12, 0, $new, 50, $col, $font, $text);
imagegif($insert,"",100);
?>
helloktk at naver dot com
24-Jun-2004 08:55
Here is a function which moves the center of text's bounding
box to a given pivot point (px,py) and rotates text about
that point.
<?php
$width=500;
$height=400;
$fontpath = 'c:/windows/fonts/arial.ttf';
$text = 'Finally, I have a roated text box';
$fontsize = 20;
$angle = 30.0;
$image = imagecreatetruecolor($width,$height);
imagefill($image, 0, 0, 0xDDDDDD);
$bbox = imagettfbbox($fontsize, 0, $fontpath, $text);
$x0= $bbox[6];
$y0=-$bbox[7];
$bbox[5]=-$bbox[5]+$bbox[1];
$bbox[7]=-$bbox[7]+$bbox[3];
$bbox[1]=0;
$bbox[3]=0;
$sx=imagesx($image);
$sy=imagesy($image);
$xc=($bbox[0]+$bbox[2])/2.0;
$yc=($bbox[1]+$bbox[7])/2.0;
$rad=$angle*pi()/180.0;
$sa=sin($rad);
$ca=cos($rad);
$x1=$x0-$xc;
$y1=$y0-$yc;
$px=$sx/2.0;
$py=$sy/2.0;
$x2= intval( $x1*$ca+$y1*$sa+$px+0.5);
$y2= intval(-$x1*$sa+$y1*$ca+$py+0.5);
imagettftext($image,$fontsize,$angle,$x2,$y2,0xFF,$fontpath,$text);
rotbbox($bbox,$angle,$px,$py);
for($i=0;$i<4;$i++){
$x0=$bbox[2*$i+0];
$y0=$bbox[2*$i+1];
$j=$i+1;
if($j==4) $j=0;
$x1=$bbox[2*$j+0];
$y1=$bbox[2*$j+1];
imageline($image,$x0,$y0,$x1,$y1,0xFF0000);
}
imagepng($image);
function rotbbox(&$bbox,$angle,$px,$py){
$xc=($bbox[0]+$bbox[2])/2.0;
$yc=($bbox[1]+$bbox[7])/2.0;
$rad=$angle*pi()/180.0;
$sa=sin($rad);
$ca=cos($rad);
for ($i=0;$i<4;$i++){
$x=$bbox[$i*2+0]-$xc;
$y=$bbox[$i*2+1]-$yc;
$bbox[$i*2+0]= intval( $ca*$x+$sa*$y+$px+0.5);
$bbox[$i*2+1]= intval(-$sa*$x+$ca*$y+$py+0.5);
}
}
?>
jrisken at mn dot rr dot com
09-Mar-2004 04:12
I took Magicaltux's word wrap procedure and modified it in two ways. I changed the order of processing so that the string plotting function is called only once for each word instead of for every character. And I wrote the results to a string scalar instead of a string array, with embedded breaks <br> at line ends. It should run pretty fast. Mine breaks only on spaces, but hyphens could easily be added.
I'm new to PHP so I apologize for my idiosyncratic formatting conventions.
<?
function myWordWrap($txt,$font,$size,$width)
{
$txt.=" "; $spaces=array();
$wids=array();
$i=0;
while(true)
{
$j=strpos(substr($txt,$i)," ");
if(!($j===false))
{
$spaces[]=$j+$i;
$bbox=imagettfbbox($size,0,$font,substr($txt,$i,$j+1));
$left=($bbox[0]>$bbox[6])?$bbox[6]:$bbox[0];
$right=($bbox[2]>$bbox[4])?$bbox[2]:$bbox[4];
$wids[]=$right-$left;
$i=$j+$i+1;
}
else break;
}
$lastspace=-1;
$cum=0;
$t2="";
for($i=0;$i<count($spaces);$i++)
{
if((($cum>0)&&($cum+$wids[$i])>$width)) {
$t2.="<br>";
$cum=0;
$i--;
}
else
{
$t2.=substr($txt,$lastspace+1,$spaces[$i]-$lastspace);
$cum+=$wids[$i];
$lastspace=$spaces[$i];
}
}
return $t2;
}
?>
LB
11-Feb-2004 09:55
the oliver dot martin at onemail dot fixbbox function is just lacking a small thing:
the coordonates for top and left have to be the opposite, because the imagettftext x and y coordonates are calculated from the top left of the image and set the bottom left of the first character.
The correct function is:
function fixbbox($bbox)
{
$tmp_bbox["left"] = min($bbox[0],$bbox[2],$bbox[4],$bbox[6]);
$tmp_bbox["top"] = min($bbox[1],$bbox[3],$bbox[5],$bbox[7]);
$tmp_bbox["width"] = max($bbox[0],$bbox[2],$bbox[4],$bbox[6]) -
min($bbox[0],$bbox[2],$bbox[4],$bbox[6]) + 1;
$tmp_bbox["height"] = max($bbox[1],$bbox[3],$bbox[5],$bbox[7]) - min($bbox[1],$bbox[3],$bbox[5],$bbox[7]);
$tmp_bbox["left"] = 0 - $tmp_bbox["left"];
$tmp_bbox["top"] = 0 - $tmp_bbox["top"];
return $tmp_bbox;
}
And it works for any rotated text.
David Eder
10-Feb-2004 11:46
As "oliver dot martin at onemail dot at" noted above, imagettfbbox() does not work correctly in php 4.3.4. To remedy this, I've written a short function that uses trig to calculate the bounding box from rotating a non-rotated piece of text.
Hopefully, this comment will be obsolete soon, but for now, ...
function imagettfbbox_t($size, $angle, $fontfile, $text)
{
// compute size with a zero angle
$coords = imagettfbbox($size, 0, $fontfile, $text);
// convert angle to radians
$a = $angle * M_PI / 180;
// compute some usefull values
$ca = cos($a);
$sa = sin($a);
$ret = array();
// perform transformations
for($i = 0; $i < 7; $i += 2)
{
$ret[$i] = round($coords[$i] * $ca + $coords[$i+1] * $sa);
$ret[$i+1] = round($coords[$i+1] * $ca - $coords[$i] * $sa);
}
return $ret;
}
jtopland at hive dot no
08-Feb-2004 04:26
Finally managed to make a fixed version of imagettfbbox().
All angles returns correct values.
Except that imagettftext() returns different trackings (space between each character) when rotating.
<?php
$font = "d://www//tahoma.ttf";
$text = "Finally, I can center rotated text!";
$size = 20;
$angle = 20;
$image = imagecreatetruecolor(500, 400);
imagefill($image, 0, 0, hexdec("dddddd"));
imageline($image, 0, 0, imagesx($image), imagesy($image), hexdec("000000"));
imageline($image, imagesx($image), 0, 0, imagesy($image), hexdec("000000"));
$bbox = imagettfbbox_fixed($size, $angle, $font, $text);
imagettftext($image, $size, $angle, imagesx($image) / 2 - $bbox['width'] / 2, imagesy($image) / 2 + $bbox['height'] / 2, hexdec("0000ff"), $font, $text);
imagepng($image);
function imagettfbbox_fixed($size, $angle, $font, $text)
{
$bbox = imagettfbbox($size, 0, $font, $text);
$angle = pi() * 2 - $angle * pi() * 2 / 360;
for ($i=0; $i<4; $i++)
{
$x = $bbox[$i * 2];
$y = $bbox[$i * 2 + 1];
$bbox[$i * 2] = cos($angle) * $x - sin($angle) * $y;
$bbox[$i * 2 + 1] = sin($angle) * $x + cos($angle) * $y;
}
$bbox['width'] = $bbox[0] + $bbox[4];
$bbox['height'] = $bbox[1] - $bbox[5];
return $bbox;
}
?>
oliver dot martin at onemail dot at
09-Jan-2004 03:13
The original fixbox function by <php at deathz0rz dot homeunix dot net> doesn't work when the text is rotated, as it assumes that the upper left corner of the text is also the upper left corner of the bounding box. Same goes for the lower right corner. Here is my corrected version of it:
<?
function fixbbox($bbox)
{
$tmp_bbox["left"] = min($bbox[0],$bbox[2],$bbox[4],$bbox[6]);
$tmp_bbox["top"] = min($bbox[1],$bbox[3],$bbox[5],$bbox[7]);
$tmp_bbox["width"] = max($bbox[0],$bbox[2],$bbox[4],$bbox[6]) - min($bbox[0],$bbox[2],$bbox[4],$bbox[6]);
$tmp_bbox["height"] = max($bbox[1],$bbox[3],$bbox[5],$bbox[7]) - min($bbox[1],$bbox[3],$bbox[5],$bbox[7]);
return $tmp_bbox;
}
?>
However, be aware that this might not be very useful, as gd-2.0.8 introduces a bug which renders the results of imagettfbbox() useless when the text is rotated. This is still not fixed in the the php-4.3.4 bundled version (2.0.15 compatible).
MagicalTux at FF.ST
22-Dec-2003 02:09
One use of this function is to do some WordWrap =p
I wrote a little function to make a basic wordwrap : it returns an array with each line in a row.
You just have to display each row on a different line (calling many times imagettftext) to get a good result.
The character ^ is assumed as a linebreak.
<?php
function im_wordwrap($txt,$font,$size,$width) {
$sep=array(' ','-'); $res=array();
$buf='';
for($i=0;$i<strlen($txt);$i++) {
$l=$txt{$i};
if ($l=='^') {
$res[]=$buf;
$buf='';
continue;
}
$t=$buf.$l;
$bbox=imagettfbbox($size,0,$font,$t);
$left=($bbox[0]>$bbox[6])?$bbox[6]:$bbox[0]; $right=($bbox[2]>$bbox[4])?$bbox[2]:$bbox[4]; $w=$right-$left; if ($w>$width) {
if ($buf=='') return false; $fp=false;
foreach($sep as $s) {
$p=strrpos($buf,$s);
if (($p!==false) and ($p>$fp)) $fp=$p;
}
if ($fp===false) {
$res[]=$buf;
$buf='';
$i--; continue;
}
$res[]=substr($buf,0,$fp+1);
$buf=substr($buf,$fp+1);
$i--;
continue;
}
$buf.=$l;
}
if ($buf!='') $res[]=$buf;
return $res;
}
?>
php at deathz0rz dot homeunix dot net
14-Dec-2003 08:38
The array this function returns is very strange, at least, i think so... So i created this function that 'fixes' the bounding box array into some human-understandable format
<?php
function fixbbox($bbox)
{
$xcorr=0-$bbox[6]; $ycorr=0-$bbox[7]; $tmp_bbox['left']=$bbox[6]+$xcorr;
$tmp_bbox['top']=$bbox[7]+$ycorr;
$tmp_bbox['width']=$bbox[2]+$xcorr;
$tmp_bbox['height']=$bbox[3]+$ycorr;
return $tmp_bbox;
}
?>
Brian at NOSPAM at PrintsMadeEasy dot com
04-Sep-2002 03:12
There seems to be a little confusion regarding the font coordinate system. PHP's TTF functions will make more sense after you understand the principals of font creation. This guy wrote a really good overview...
http://pfaedit.sourceforge.net/overview.html
| |