PHP
downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

imagettftext> <imagetruecolortopalette
Last updated: Fri, 20 Jun 2008

view this page in

imagettfbbox

(PHP 4, PHP 5)

imagettfbbox — Retourne le rectangle entourant un texte et dessiné avec une police TrueType

Description

array imagettfbbox ( float $size , float $angle , string $fontfile , string $text )

Calcule et retourne le rectangle entourant le texte text , écrit avec une police truetype.

Liste de paramètres

size

La taille de la police, en pixels

angle

L'angle, en degrés, dans lequel le paramètre text sera mesuré

fontfile

Le nom de la police TrueType (peut être une URL). Suivant la version de la bibliothèque GD utilisée par PHP, ce paramètre peut chercher des fichiers qui ne commence pas par un slash ("/") de fin mais plutôt .ttf et cherchera tout le long des chemins de fonts définis.

text

La chaîne à mesurer

Valeurs de retour

imagettfbbox() retourne un tableau avec 8 éléments représentant les 4 sommets du rectangle ainsi défini :

0 Coin inférieur gauche, abscisse
1 Coin inférieur gauche, ordonnée
2 Coin inférieur droit, abscisse
3 Coin inférieur droit, ordonnée
4 Coin supérieur droit, abscisse
5 Coin supérieur droit, ordonnée
6 Coin supérieur gauche, abscisse
7 Coin supérieur gauche, ordonnée

Les positions des points sont relatives au texte text, indépendamment de l'angle : coin supérieur gauche faire référence au coin supérieur gauche du texte écrit horizontalement.

Voir aussi

Note: Cette fonction nécessite la bibliothèque GD et la bibliothèque » FreeType.

Voir aussi



imagettftext> <imagetruecolortopalette
Last updated: Fri, 20 Jun 2008
 
add a note add a note User Contributed Notes
imagettfbbox
Stefan at colulus dot com
30-May-2008 08:13
I worked out a script that allows the transfer of alphanumeric data to be placed on an image. The HTML feature is img src and the php feature is imagettftext. This simple code will increment from 1 to 3 on images.

code:

<?php
//ImageCall.php -- This script will call a script to produce the image.
for($next = 1;$next < 4; $next++){
print
"Image $next:<br>";
print
"<img src = 'Image.php?\$text=$next'>";
print
"<br><br>";
}
?>

<?php
//Image.php -- This script creates a square image and places the text on it.

// image size and color
$im = ImageCreate(77,77);
$color1 = ImageColorAllocate($im,0x66,0xCC,0x00);
$color2 = ImageColorAllocate($im,0x33,0x66,0x00);
$color3 = ImageColorAllocate($im,0x00,0x99,0x00);
$color4 = ImageColorAllocate($im,0x3D,0x3D,0x3D);

// image creation
ImageFilledRectangle($im,1,1,76,76,$color1);
ImageFilledpolygon($im, array (76,1,1,76,76,76),3,$color2);
ImageFilledRectangle($im,5,5,72,72,$color3);

// determine numeric center of image
$size = ImageTTFBBox(45,0,'impact',$_GET['$text']);
$X = (77 - (abs($size[2]- $size[0])))/2;
$Y = ((77 - (abs($size[5] - $size[3])))/2 + (abs($size[5] - $size[3])));

//places numeric information on image
ImageTTFText($im,45,0,($X-1),$Y,$color4,'impact',$_GET['$text']);

//returns completed image to calling script
Header('Content-Type: image/png');
Imagepng($im);

?>
Valentijn de Pagter
16-May-2008 07:14
If you're looking for easy text alignment, you need to use the imagettfbbox() command. When given the correct parameters, it will return the boundaries of your to-be-made text field in an array, which will allow you to calculate the x and y coordinate that you need to use for centering or aligning your text.

A horizontal centering example:

<?php

$tb
= imagettfbbox(17, 0, 'airlock.ttf', 'Hello world!');

?>

$tb would contain:

Array
(
    [0] => 0 // lower left X coordinate
    [1] => -1 // lower left Y coordinate
    [2] => 198 // lower right X coordinate
    [3] => -1 // lower right Y coordinate
    [4] => 198 // upper right X coordinate
    [5] => -20 // upper right Y coordinate
    [6] => 0 // upper left X coordinate
    [7] => -20 // upper left Y coordinate
)

For horizontal alignment, we need to substract the "text box's" width { $tb[2] or $tb[4] } from the image's width and then substract by two.

Saying you have a 200px wide image, you could do something like this:

<?php

$x
= ceil((200 - $tb[2]) / 2); // lower left X coordinate for text
imagettftext($im, 17, 0, $x, $y, $tc, 'airlock.ttf', 'Hello world!'); // write text to image

?>

This'll give you perfect horizontal center alignment for your text, give or take 1 pixel. Have fun!
mihai.draghicioiu at gmailcom
15-Apr-2008 12:57
To get the height for a line of text, I've found it useful to do:

<?php

$bbox
= imagettfbbox($size, 0, $ttf, " \n "); // space, newline, space

$height = $bbox[3] - $bbox[5];

?>

I hope this helps. Before, I used the string "Tj", but that sometimes fell short, especially for crazy fonts.
heshan at sjtu dot edu dot cn
07-Jan-2008 01:18
the imagettfbbox and imagettftext quirks are:

1. imagettfbbox and imagettftext have the same return value and both of them are wrong for angle not equal to zero.
2. imagettfbbox returns the correct bounding box when angle is zero.
3. the bounding box has a coordinate system that the x gets bigger from left to right and y gets bigger from top to bottom.
4. the "base point" used in imagettftext is the origin in the bounding box coordinate system.
5. when the angle is other than 0, it is actually rotated in the coordinate system with respect to the base point. so if we know the bounding box coordinate when angle is zero, we can get the new bounding box coordinate by doing the rotation by math equations manually.
6. to have pixel level accuracy, we should also be aware of another thing. suppose the axis is like this: |_|_|_|, the bounding box coordinate uses point on the vertical line while image function uses point on the horizontal line, so there is a 1 pixel difference you should take care of.

The following snippet creates minimal images containing a letter of different font and rotation angle. This is especially useful in captcha scripts.

<?php

function create_font_image( $size, $angle, $font, $char )
{
   
$rect = imagettfbbox( $size, 0, $font, $char );
    if(
0 == $angle ) {
       
$imh = $rect[1] - $rect[7];
       
$imw = $rect[2] - $rect[0];
       
$bx = -1 - $rect[0];
       
$by = -1 - $rect[7];
    } else {
       
$rad = deg2rad( $angle );
       
$sin = sin( $rad );
       
$cos = cos( $rad );
        if(
$angle > 0 ) {
           
$tmp = $rect[6] * $cos + $rect[7] * $sin;
           
$bx = -1 - round( $tmp );
           
$imw = round( $rect[2] * $cos + $rect[3] * $sin - $tmp );
           
$tmp = $rect[5] * $cos - $rect[4] * $sin;
           
$by = -1 - round( $tmp );
           
$imh = round( $rect[1] * $cos - $rect[0] * $sin - $tmp );
        } else {
           
$tmp = $rect[0] * $cos + $rect[1] * $sin;
           
$bx = -1 - round( $tmp );
           
$imw = round( $rect[4] * $cos + $rect[5] * $sin - $tmp );
           
$tmp = $rect[7] * $cos - $rect[6] * $sin;
           
$by = -1 - round( $tmp );
           
$imh = round( $rect[3] * $cos - $rect[2] * $sin - $tmp );
        }
    }
   
$im = imagecreatetruecolor( $imw, $imh );
   
imagefill( $im, 0, 0, imagecolorallocate( $im, 255, 0, 255 ) );
   
imagettftext( $im, $size, $angle, $bx, $by, imagecolorallocate( $im, 0, 0, 0 ), $font, $char );
   
imagegif( $im, trim( $font, './' ) . ord( $char ) . $angle . '.gif' );
   
imagedestroy( $im );
}

$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
$angles = array( -30, -20, -10, 0, 10, 20, 30 );
$fonts = array( './latinwide.ttf', './verdana.ttf', './times.ttf', './broadway.ttf' );
foreach(
$angles as $angle )
    foreach(
$fonts as $font )
        for(
$i = 0; $i < strlen( $chars ); ++$i )
           
create_font_image( 100, $angle, $font, $chars[$i] );
?>
intuz et gmx dt de
30-Aug-2007 08:45
I still got problems trying to rotate imagettftext using imagettfbbox.

It's position calculation is mostly wrong. So i tried to rotate ttftext with IMAGEROTATE.

As a special the result is in black fontcolor and transparent background.

Hope it helps sombody (thanks for function convertBoundingBox, reading below)

<?
function ImgText($text,$fontsize,$font,$angle){
$im = '';
    if(
$text){
        if(!
$fontsize || $fontsize < 1) $fontsize = 12;
        if(!
$font) $font = "fonts/arial.ttf";
       
$bbox = imagettfbbox($fontsize, 0, $font, $text);
       
$size=convertBoundingBox($bbox);
       
$im = ImageCreatetruecolor($size['width'],$size['height']);

       
$white = ImageColorAllocate($im, 255, 255, 255);
       
$black = ImageColorAllocate($im, 0,0,0);
       
       
imagefill ($im, 0, 0, $white );
       
imagettftext($im, $fontsize, 0, $size['xOffset'], $size['yOffset'], $black, $font, $text);
       
$im = imagerotate( $im,$angle, $white);
       
imagecolortransparent ($im,$white);
    }else{
       
// No text
   
}
}
?>
bushj at rpi dot edu
11-Jul-2007 06:11
Apparently the bounding box returned by imagettftext and imagettfbbox is not the same, and it appears as though imagettftext does a better job at calculating the actual bounding box (maybe because it has to render every character and it then finds out really everywhere it rendered).

So, you can create a dummy image render the text to it and get a better box. Here is an example function:
<?php
function better_imagettfbbox($size, $angle, $font, $text) {
 
$dummy = imagecreate(1, 1);
 
$black = imagecolorallocate($dummy, 0, 0, 0);
 
$bbox = imagettftext($dummy, $size, $angle, 0, 0, $black, $font, $text);
 
imagedestroy($dummy);
  return
$bbox;
}
?>
If you use this a lot, it would be better to keep one dummy image instead of continually creating and destroying images.
Ruquay
04-Jun-2007 01:12
Several comments show that the output of this function is often not what is expected, especially when the text is rotated.

For those of you who'd like a visual representation of what is happening to the bounding box as the text is rotated, take a look here:

http://ruquay.com/sandbox/imagettf/
Nate Sweet
01-Jun-2007 09:11
An improvement to the convertBoundingBox function. The previous function was completely wrong. My confusion came from characters like "1" and "_" that are rendered to the right or below the basepoint (in the font I'm using). I ended up using mike at mikeleigh dot com's function with a fix for these characters, and a "belowBasepoint" value.
<?php
function convertBoundingBox ($bbox) {
    if (
$bbox[0] >= -1)
       
$xOffset = -abs($bbox[0] + 1);
    else
       
$xOffset = abs($bbox[0] + 2);
   
$width = abs($bbox[2] - $bbox[0]);
    if (
$bbox[0] < -1) $width = abs($bbox[2]) + abs($bbox[0]) - 1;
   
$yOffset = abs($bbox[5] + 1);
    if (
$bbox[5] >= -1) $yOffset = -$yOffset; // Fixed characters below the baseline.
   
$height = abs($bbox[7]) - abs($bbox[1]);
    if (
$bbox[3] > 0) $height = abs($bbox[7] - $bbox[1]) - 1;
    return array(
       
'width' => $width,
       
'height' => $height,
       
'xOffset' => $xOffset, // Using xCoord + xOffset with imagettftext puts the left most pixel of the text at xCoord.
       
'yOffset' => $yOffset, // Using yCoord + yOffset with imagettftext puts the top most pixel of the text at yCoord.
       
'belowBasepoint' => max(0, $bbox[1])
    );
}
?>
Nate Sweet
01-Jun-2007 09:07
It took me some time to make full use of imagettfbbox. Hopefully the following function makes it much easier to use for others.

<?php
function convertBoundingBox ($bbox) {
    if (
$bbox[0] >= -1)
       
$leftOfBasepoint = -abs($bbox[0] + 1);
    else
       
$leftOfBasepoint = abs($bbox[0] + 2);
   
$rightOfBasepoint = abs($bbox[2] - $bbox[0]);
    if (
$bbox[0] < -1) $rightOfBasepoint = abs($bbox[2]) + abs($bbox[0]) - 1;
   
$aboveBasepoint = abs($bbox[5] + 1);
   
$height = abs($bbox[7]) - abs($bbox[1]);
    if (
$bbox[3] > 0) $height = abs($bbox[7] - $bbox[1]) - 1;
   
$width = $leftOfBasepoint + $rightOfBasepoint;
   
$belowBasepoint = $height - $aboveBasepoint;
    return array(
       
'width' => $width,
       
'height' => $height,
       
'leftOfBasepoint' => $leftOfBasepoint,
       
'rightOfBasepoint' => $rightOfBasepoint,
       
'aboveBasepoint' => $aboveBasepoint,
       
'belowBasepoint' => $belowBasepoint
   
);
}
?>

Thanks goes to mike at mikeleigh dot com for providing the core of this function.

Remember, the basepoint is the x, y coords you use to draw text with imagettftext. A useful thing to do is take a string like...
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890
...and use the "aboveBasepoint" value for the height of your font. Now you can draw lines and use "the height of your font * leading" as the distance between lines of text, where leading is a number like 1.45 (for 45% leading).
Nate Sweet
30-May-2007 10:36
This script shows you side by side the difference between a font rendered at a certain size and the same font rendered at some multiple of that size and then scaled down by the same multiple. It seems to help small sizes and affects large ones less. This script lets you see if it is worth implementing for your situation. Included is the great "imagettfbboxextended" function by mike at mikeleigh dot com below.

$size = 30;
$factor = 16;

$smallSize = imagettfbboxextended($size, 0, "fonts/MPlantin.ttf", "The quick brown fox jumps over the lazy dog.");
$smallWidth = $smallSize['width'];
$smallHeight = $smallSize['height'];
$canvas = imagecreatetruecolor($smallWidth + 20, $smallHeight * 2 + 20);
imagefill($canvas, 0, 0, imagecolorallocate($canvas, 255, 255, 255));
imagettftext($canvas, $size, 0, 10 + $smallSize['x'], 10 + $smallSize['y'], imagecolorallocate($canvas, 0, 0, 0), "fonts/MPlantin.ttf", "The quick brown fox jumps over the lazy dog.");

$largeSize = imagettfbboxextended($size * $factor, 0, "fonts/MPlantin.ttf", "The quick brown fox jumps over the lazy dog.");
$largeWidth = $largeSize['width'];
$largeHeight = $largeSize['height'];
$temp = imagecreatetruecolor($largeWidth, $largeHeight);
imagefill($temp, 0, 0, imagecolorallocate($canvas, 255, 255, 255));
imagettftext($temp, $size * $factor, 0, $largeSize['x'], $largeSize['y'], imagecolorallocate($temp, 0, 0, 0), "fonts/MPlantin.ttf", "The quick brown fox jumps over the lazy dog.");
imagecopyresampled($canvas, $temp, 10 + $smallSize['x'], 10 + $smallSize['y'] + 10, 0, 0, $smallWidth, $smallHeight, $largeWidth, $largeHeight);
imagepng($temp, "temp.png");

imagepng($canvas, "test.png");

function imagettfbboxextended($size, $angle, $fontfile, $text) {
    /*this function extends imagettfbbox and includes within the returned array
    the actual text width and height as well as the x and y coordinates the
    text should be drawn from to render correctly.  This currently only works
    for an angle of zero and corrects the issue of hanging letters e.g. jpqg*/
    $bbox = imagettfbbox($size, $angle, $fontfile, $text);

    //calculate x baseline
    if($bbox[0] >= -1) {
        $bbox['x'] = abs($bbox[0] + 1) * -1;
    } else {
        //$bbox['x'] = 0;
        $bbox['x'] = abs($bbox[0] + 2);
    }

    //calculate actual text width
    $bbox['width'] = abs($bbox[2] - $bbox[0]);
    if($bbox[0] < -1) {
        $bbox['width'] = abs($bbox[2]) + abs($bbox[0]) - 1;
    }

    //calculate y baseline
    $bbox['y'] = abs($bbox[5] + 1);

    //calculate actual text height
    $bbox['height'] = abs($bbox[7]) - abs($bbox[1]);
    if($bbox[3] > 0) {
        $bbox['height'] = abs($bbox[7] - $bbox[1]) - 1;
    }

    return $bbox;
}
mike at mikeleigh dot com
28-May-2007 04:05
I have been testing this function for a while now and have come up with many of the same issues that other people have touched upon.  Not being able to calculate the width of the text correctly.  Or if a solution is found then it won't work with a hanging letter or a negative start letter like 'j'.

Like Ralph I also wanted to draw a box around some text and this would require me being pixel perfect with the font.  The trouble is I did not know which font would be used or which size.  This led me to come up with a solution which I am sharing below.

<?php
function imagettfbboxextended($size, $angle, $fontfile, $text) {
   
/*this function extends imagettfbbox and includes within the returned array
    the actual text width and height as well as the x and y coordinates the
    text should be drawn from to render correctly.  This currently only works
    for an angle of zero and corrects the issue of hanging letters e.g. jpqg*/
   
$bbox = imagettfbbox($size, $angle, $fontfile, $text);

   
//calculate x baseline
   
if($bbox[0] >= -1) {
       
$bbox['x'] = abs($bbox[0] + 1) * -1;
    } else {
       
//$bbox['x'] = 0;
       
$bbox['x'] = abs($bbox[0] + 2);
    }

   
//calculate actual text width
   
$bbox['width'] = abs($bbox[2] - $bbox[0]);
    if(
$bbox[0] < -1) {
       
$bbox['width'] = abs($bbox[2]) + abs($bbox[0]) - 1;
    }

   
//calculate y baseline
   
$bbox['y'] = abs($bbox[5] + 1);

   
//calculate actual text height
   
$bbox['height'] = abs($bbox[7]) - abs($bbox[1]);
    if(
$bbox[3] > 0) {
       
$bbox['height'] = abs($bbox[7] - $bbox[1]) - 1;
    }

    return
$bbox;
}
?>

The function above gives the correct x and y coordinates that the text should be drawn from and also gives the actual image width and height.  This has been tested with various fonts and sizes ranging from 6 up to 144 points.  Some of the output will appear to be incorrect and have an extra pixel on the right, using verdana at size 144 and outputting the character 'Q' for example.  This is not an error as this is part of the anti-aliasing of the font output.

Example Usage:
<?php
$font
= 'c:\windows\fonts\verdana.ttf';
$font_size = 144;
$text = 'jÜyZgQ';
$bbox = imagettfbboxextended($font_size, 0, $font, $text);
?>

Return Values:
Array
(
    [0] => -8
    [1] => 40
    [2] => 715
    [3] => 40
    [4] => 715
    [5] => -177
    [6] => -8
    [7] => -177
    [x] => 6
    [width] => 722
    [y] => 176
    [height] => 216
)

Further notes can be found here along with images of the output of the function http://mikeleigh.com/links/imagettfbbox
lassial dot gmail dot com
24-May-2007 01:46
Ralph Bolton commented about the difference in calculating the bounding box size vs. aligning text base line.

The workaround for this issue is to calculate the difference in height between a character going below baseline and one above the baseline. This is likely going to vary from font to font, so I'd suggest something like this:

<?php

function fontBaselineOffset($font, $fontSize)
{
//this should be above baseline
$test2="H";
//some of these additional letters should go below it
$test3="Hjgqp";

//get the dimension for these two:

$box2 = imageTTFBbox($fontSize,0,$font,$test2);
$box3 = imageTTFBbox($fontSize,0,$font,$test3);

//return the offset value

return  abs((abs($box2[5]) + abs($box2[1])) - (abs($box3[5]) + abs($box3[1])));

}
?>

This is not perfect yet. You should define a range of allowed characters that can go below baseline, compare them to the ones actually found in your string and use them instead of the string $test3 used in the example function above. This should avoid problems with letters that go further below baseline than the others (e.g. there could be a difference between 'g' and 'p')
ralphbolton at mail2sexy dot com
23-Apr-2007 06:16
There's a bit of an annoyance with measuring font sizes and drawing boxes around text. When fonts are measured using ImageTTFbbox, the correct vertical height is returned. That is, the measurement of the phrase "Hanging" will be from the top of the "H" to the bottom of the "g".

The problem is that functions like imageTTFtext align with the "line" of the text - that is, in the phrase "Hanging", the alignment is below the "H", not the bottom of the "g". That means that if you draw a rectangle behind your text, it'll be incorrectly aligned because the hanging "g" will be outside the box.

For example, this doesn't work as you might expect (because the "g" hangs below the box):
<?php
// Get the size of the font box
$textbox = imageTTFBbox($size, 0, $font, 'Hanging');
$textwidth = abs($textbox[4] - $textbox[0]);
$textheight = abs($textbox[5] - $textbox[1]);

// Now draw a rectangle on the image
$colour = ImageColorAllocate($im, 100, 100, 100);
imagefilledrectangle($im, $x, $y - $textheight, $x + $textwidth, $y, $colour );

// Now draw the text
$black = ImageColorAllocate($im, 0, 0, 0);
ImageTTFText($image['resource'], $size, 0, $x, $y, $black, $font, 'Hanging');
?>
It also seems that the rectangle in the above example is located 1 pixel to the left of the text.

I haven't found a way to resolve this problem correctly. Instead, I have enlarged the rectangle and then put the text into it. I don't think this will work absolutely correctly for all fonts, so it's not exactly a perfect solution. However, it's better than nothing! Here is a snippet of it:
<?php
$enlargex
= $textwidth * 0.08;
$enlargey = $textheight * 0.1;
$enlargey2 = $textheight * 0.5;

// Now draw a rectangle on the image
$colour = ImageColorAllocate($im, 100, 100, 100);
imagefilledrectangle($im, $x - $enlargex, $y - $textheight - $enlargey, $x + $textwidth + $enlargex, $y + $enlarge2, $colour );
?>
marclaz
31-Jul-2006 03:13
Please note that as imageTTFBbox and imageTTFText functions return an array of coordinates which could be negative numbers care must be taken with height and width calculations.

The rigth way to do that is to use the abs() function:

for an horizontal text:

$box = @imageTTFBbox($size,0,$font,$text);
$width = abs($box[4] - $box[0]);
$height = abs($box[5] - $box[1]);

Then to center your text at ($x,$y) position the code should be like that:

$x -= $width/2;
$y += $heigth/2;

imageTTFText($img,$size,0,$x,$y,$color,$font,$text);

this because (0,0) page origin is topleft page corner and (0,0) text origin is lower-left readable text corner.

Hope this help.
Nimja
08-May-2006 10:09
Warning:
james.logsdon's function has a few flaws in copying my own function. Though he did a great job in making an overall nicer looking function it does have a few flaws.

His function does not allow for long words (longer then the width) linebreaks (harder then it looks) and has a non-pixel perfect location.

The problem with the imagettfbbox function is that different letters give a different x/y top-left coordinate. At least it looks that way for the eye. I 'solved' this by putting a space in front of every line and then offset the text by the width of that space.

So, although some things of my function seem useless they do serve an important purpose.
james.logsdon at firesidemedia dot net
05-May-2006 10:32
I've modified Nimja's function a little. It doesn't support line-breaks (didn't need it in my script), but it's easy enough to add in.

<?php

function imageWordWrapBBox ( $Text, $Width = 650, $FontSize = 10, $Font = './fonts/arial.ttf' )
{
   
$Words = split ( ' ', $Text );
   
$Lines = array ( );
   
$Line  = '';

    foreach (
$Words as $Word )
    {
       
$Box  = imagettfbbox ( $FontSize, 0, $Font, $Line . $Word );
       
$Size = $Box[4] - $Box[0];
        if (
$Size > $Width )
        {
           
$Lines[] = trim ( $Line );
           
$Line    = '';
        }
       
$Line .= $Word . ' ';
    }
   
$Lines[] = trim ( $Line );

   
$Dimensions = imagettfbbox ( $FontSize, 0, $Font, 'AJLMYabdfghjklpqry019`@$^&*(,' );
   
$lineHeight = $Dimensions[1] - $Dimensions[5];

    return array (
$lineHeight, $Lines, $lineHeight * count ( $Lines ) );
}

function
imageWordWrap ( $Text, $Width, $Color, $X = 0, $Y = 0, $FontSize = 10, $Font = './fonts/arial.ttf' )
{
   
$Data = $this->imageWordWrapBBox ( $Text, $Width, $FontSize, $Font );

    foreach (
$Data[1] as $Key => $Line )
    {
       
$locX = $X;
       
$locY = $Y + ( $Key * $Data[0] );
       
imagettftext ( $this->Image, $FontSize, 0, $locX, $locY, $Color, $Font, $Line );
    }

    return
$Data;
}
?>
toe dot cutter at telia dot com
28-Feb-2006 04:41
Neither Greg's or Henrik N's code worked for me.

I figured out that imagettfbbox gives the size (coordinates) of the whole letter (ie. with the hang on 'g' or 'j'). So it was only a matter of finding the correct index of coordinates in the array.

Note: This doesn't work on Times New Roman Italic's 'f' for some reason.

<?php

    $size
= imagettfbbox($fontsize, 0, $font, $text);
   
$dx = abs($size[2]-$size[0]);
   
$dy = abs($size[5]-$size[3]);

   
ImageTTFText($im, $fontsize, 0, abs($size[6]), abs($size[5]), $txtcolor, $font, $text);

?>
Henrik N
26-Feb-2006 10:48
Tried Greg's code below, but it didn't quite work for me. This did, however:

<?php

$size
= imagettfbbox($fontSize, 0, $font, $text);
$width = $size[2] + $size[0];
$height = abs($size[1]) + abs($size[7]);

$image = imagecreatetruecolor($width, $height);

imagettftext($image, $fontSize, 0, 0, abs($size[5]), $black, $font, $text);

?>
greg at gregoryfenton dot be
11-Feb-2006 11:23
Have a problem with imagettfbbox cutting off the hang of letters such as 'g' or 'j'??

After days trying to figure this thing out, I finally cracked it:

  $size = imagettfbbox($s,0,$font,$text);
  $dx=abs($size[0])+abs($size[2]);
  $dy=abs($size[1])+abs($size[7]);

  ImageTTFText($im, $s, 0, $dx-abs($size[0]), $dy-abs($size[1]), $black, $font, $text);

The key is the abs commands - you must account for the negative numbers in the original imagettfbbox, and if you have any, take them away from the location at the end when the text is displayed:

you need to start the x and y at a (possibly) negative number, not 0,0 as I had thought.

Hope that helps someone..
Nimja
13-Jan-2006 05:32
My previous function had 2 bugs which are now fixed:
* Align is now pixel perfect, no longer dependant on the first character. Solved by putting a space " " in front of every rendered line, making the basepoint at the exact same place every time.
* X Y Coordinates are no longer the base-point, but the perfect top/left coordinates. This made my life designing a LOT easier.

Features:
* Newline support! (both Windows and Linux)
* Paragraph support, no newlines are ignored, not even empty ones. So empty lines are properly supported.
* True top/left x/y coordinates instead of TTF basepoint.(at least as close as possible).
* Align function for Left, Center and Right
* Support for words that are longer then the supported width.

<?php
//A function for pixel precise text Wrapping
function imageTextWrapped(&$img, $x, $y, $width, $font, $color, $text, $textSize, $align="l") {
   
//Recalculate X and Y to have the proper top/left coordinates instead of TTF base-point
   
$y += $textSize;
   
$dimensions = imagettfbbox($textSize, 0, $font, " "); //use a custom string to get a fixed height.
   
$x -= $dimensions[4]-$dimensions[0];

   
$text = str_replace ("\r", '', $text); //Remove windows line-breaks
   
$srcLines = split ("\n", $text); //Split text into "lines"
   
$dstLines = Array(); // The destination lines array.
   
foreach ($srcLines as $currentL) {
       
$line = '';
       
$words = split (" ", $currentL); //Split line into words.
       
foreach ($words as $word) {
           
$dimensions = imagettfbbox($textSize, 0, $font, $line.$word);
           
$lineWidth = $dimensions[4] - $dimensions[0]; // get the length of this line, if the word is to be included
           
if ($lineWidth > $width && !empty($line) ) { // check if it is too big if the word was added, if so, then move on.
               
$dstLines[] = ' '.trim($line); //Add the line like it was without spaces.
               
$line = '';
            }
           
$line .= $word.' ';
        }
       
$dstLines[] =  ' '.trim($line); //Add the line when the line ends.
   
}
   
//Calculate lineheight by common characters.
   
$dimensions = imagettfbbox($textSize, 0, $font, "MXQJPmxqjp123"); //use a custom string to get a fixed height.
   
$lineHeight = $dimensions[1] - $dimensions[5]; // get the heightof this line

   
$align = strtolower(substr($align,0,1)); //Takes the first letter and converts to lower string. Support for Left, left and l etc.
   
foreach ($dstLines as $nr => $line) {
        if (
$align != "l") {
           
$dimensions = imagettfbbox($textSize, 0, $font, $line);
           
$lineWidth = $dimensions[4] - $dimensions[0]; // get the length of this line
           
if ($align == "r") { //If the align is Right
               
$locX = $x + $width - $lineWidth;
            } else {
//If the align is Center
               
$locX = $x + ($width/2) - ($lineWidth/2);
            }
        } else {
//if the align is Left
           
$locX = $x;
        }
       
$locY = $y + ($nr * $lineHeight);
       
//Print the line.
       
imagettftext($img, $textSize, 0, $locX, $locY, $color, $font, $line);
    }       
}

?>
Nimja
13-Jan-2006 03:01
This is a completely rewritten function of "printWordWrapped" because it lacked a few important features. First of all, it started too high with it's text, which was easily fixed. And it has the annoying 'feature' of adding a space in front of every line. Not ideal.

But secondly, and more importantly, it didn't support long words or linebreaks. This is all fixed. And I rewrote it for cleaner code.

Please note that with the current code you could easily make a vertical align as well if you wanted to. I have not done this myself since it did not fit my own needs (and I'm slightly lazy)

Enjoy:

<?php
function imageTextWrapped(&$img, $x, $y, $width, $font, $color, $text, $textSize, $align="l") {
   
$y += $fontSize; //Correct place for the fonts.
   
$text = str_replace ("\\r", '', $text); //Remove windows line-breaks
   
$srcLines = split ("\\n", $text); //Split text into "lines"
   
$dstLines = Array(); // The destination lines array.
   
foreach ($srcLines as $currentL) {
       
$line = '';
       
$words = split (" ", $currentL); //Split line into words.
       
foreach ($words as $word) {
           
$dimensions = imagettfbbox($textSize, 0, $font, $line.' '.$word);
           
$lineWidth = $dimensions[4] - $dimensions[0]; // get the length of this line, if the word is to be included
           
if ($lineWidth > $width && !empty($line) ) { // check if it is too big if the word was added, if so, then move on.
               
$dstLines[] = trim($line); //Add the line like it was without spaces.
               
$line = '';
            }
           
$line .= $word.' ';
        }
       
$dstLines[] =  trim($line); //Add the line when the line ends.
   
}
   
//Calculate lineheight by common characters.
   
$dimensions = imagettfbbox($textSize, 0, $font, "MXQJPmxqjp123"); //use a custom string to get a fixed height.
   
$lineHeight = $dimensions[1] - $dimensions[5]; // get the heightof this line

   
$align = strtolower(substr($align,0,1)); //Takes the first letter and converts to lower string. Support for Left, left and l etc.
   
foreach ($dstLines as $nr => $line) {
        if (
$align != "l") {
           
$dimensions = imagettfbbox($textSize