views:

64

answers:

2

I am taking an xml feed and creating an image from the text. What I would like to do it color the link text a different color than the regular text. I am looping through the text to find the link, but cannot figure out how to color that text.

+1  A: 

imagetttftext() can only draw in a single color. You can't change it, or embed html-ish color codes, to dynamically change the text color. You'll have to split your text into multiple chunks, each drawn with a single color.

This means you'll have to calculate where each string chunk starts/stops using imagettfbbox() and adjust your coordinates in imagetttftext() accordingly.

comment followup:

Ok, so individual tag contents, with links being different colors. First step will be to pre-process the string and split it up along link boundaries, so you end up with a series of "text / link / text / link / text" chunks. After that, it's just a loop:

$start_x = 5;
$start_y = 20; // initial x/y coords of text
$fontsize = 14;
$font = 'font.ttf';
$angle = 0;

$black = imagecolorallocate($im, 0, 0, 0);
$linkcolor = imagecolorallocate($im, ?, ? ,?);

foreach ($string_chunks as $chunk) {
   // get coordinates of bounding box containing text
   $coords = imagegettfbbox($fontsize, $angle, $font, $chunk);

   $end_x = $coords[4]; // as per imagetttfbbox() doc page
   $end_y = $coords[5]; // x,y coords of top right corner of bounding box

   // figure out which color to draw in
   $color_to_draw = is_link($chunk) ? $linkcolor : $black; 

   // draw the text chunk
   imagettftext($im, $fontsize, $angle, $start_x, $start_y, $color_to_draw, $font, $chunk);

   // adjust starting coordinates to the END of the just-drawn text
   $start_x += $end_x;
   $start_y += $end_y;
}

You might need to adjust the coordinates as you go, if there isn't enough space between each chunk of text, or put a space into the string before you get its bounding box.

Marc B
The content of the xml changes so how would I calculate the position on the fly. Or is there a better way to do this rather than imagettftext?
timg
Are you drawing the literal XML source code? Or just the contents of some of the individual tags?
Marc B
Contents of the individual tags.
timg
On the $coords = imagettfbbox($im, $fontsize, $angle, $font, $chunk); line I get the error "Wrong parameter count for imagettfbbox()"
timg
Whoops, that function doesn't take the `$im` parameter (since it's not working on an image, just calculating some text stuff). Should work if you remove that.
Marc B
Ok I got that to work and have tried looping through the text and split at the http:// but the text doesn't change colors. Also using the wordwrap messes up where the text positioning. Maybe there is a better way to split the text?
timg
well, you have to supply something for `is_link()`. I just threw that in, but it's a real php function that determines if its parameter is a symlink. It's not for figuring out a piece of text is a URL. As for wordwrap, that you'll have to figure out yourself. What happens if a line is going to take up more space than your image is wide, or there's more text than the image is tall? What I've put above should be enough to get you started on this.
Marc B
A: 

I know there's imagefontwidth() and imagefontheight() to get the height and width of a character of a font. However, that only works with built-in fonts or fonts loaded with imageloadfont(), which I don't think support TTF files. But if you used this, it would be fairly easy to calculate the coordinates of each chunk.

For instance:

<?php
// Image:
$image = imagecreatetruecolor(200, 200);

// First built-in font:
$font = 1;

// X and Y coordinates of the 5th character in the 7th row:
$x = imagefontwidth($font) * 4;
$y = imagefontheight($font) * 6;

// Put character onto image, with white color:
imagestring($image, $font, $x, $y, 'H', 0xffffff);
?>

(note that even though I used 0xffffff as a color in my code, it's recommended to use imagecolorallocate() instead whenever possible)

Frxstrem
The problem with imageloadfont() is that it doesn't support ttf fonts and I need to use a ttf font for branding purposes.
timg