views:

106

answers:

4

How can I test if a chunk exceeds the image size and wrap that text to the next line. Not sure if I am even doing this correctly with my if statement.

$text="Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem http://somelongurl.com/then-we-make-it-super-long-with-some-more/ Lorem Ipsum Lorem Ipsum Lorem Ipsum";

$string_chunks = explode(' ', $text);

foreach ($string_chunks as $chunk) {

    if($end_x + $chunk > $image_width){
        $start_x = 5;
        $start_y += 20;
    }

   $coords = imagettfbbox($fontsize, $angle, $font, $chunk);

   $end_x = $coords[0] + $coords[4] + 10;

   $color_to_draw = is_a_url($chunk) ? $linkcolor : $black; 

   imagettftext($im, $fontsize, $angle, $start_x, $start_y, $color_to_draw, $font, $chunk);

   $start_x += $end_x;
}

With this code I get:

Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem 
http://somelongurl.com/then-we-make-it-super-long-with-some-more/
Lorem Ipsum Lorem Ipsum Lorem Ipsum

What I would like to happen is something like:

Lorem Ipsum Lorem Ipsum Lorem Ipsum 
Lorem http://somelongurl.com/then-we
-make-it-super-long-with-some-more/
Lorem Ipsum Lorem Ipsum Lorem Ipsum
A: 
if($end_x + $chunk > $image_width){ 
    $start_x = 5; 
    $start_y += 20; 
} 

One main mistake, $end_x + (strlen($chunk)*$charPXsize) > $image_width Another mistake, what will happen if a row is longer than $image_width? It'll print out on the next line, but will be too long for it anyway.

Dominique
I changed my question to reflect what I would like the image to wrap like.
timg
A: 

What I've done is to iterate over the string, checking each time to see if the bounding box gets too wide. Then if it does, insert a new line and continue until you've consumed all of your text. Then write it all as one big string...

$chunks = explode(' ', $text);
$wrappedText = '';
foreach ($chunks as $chunk) {
    $coords = imagettfbbox($fontsize, $angle, $font, $wrappedText.' '.$chunk);
    $width = $coords[2] - $coords[0];
    if ($width > $myMaxWidth) {
        $wrappedText .= "\n" . $chunk;
    } else {
        $wrappedText .= ' ' . $chunk;
    }
}
imagettftext(
    $im, 
    $fontsize, 
    $angle, 
    $start_x, 
    $start_y, 
    $color_to_draw, 
    $font, 
    $wrappedText
);

Now, note that this will not color your links differently... But, you could always add a detection method in there to determine the exact position that the link will be written, and overwrite it with your color if it's there...

ircmaxell
This produces a stair stepped output, not wrapped text.
timg
It produces wrapped text. It's just not pre-computing the width (since you can't, due to TrueType Font not being fixed-width)...
ircmaxell
Ahh, I see what you mean. If you have a "word" (your URL) that's longer than the box, it'll just add each new word after to its own new line. You'd need to add another check after the width check to see if it's too long itself (and at that point split it up)
ircmaxell
After looking into this, it just repeats the first line of the text over and over.
timg
+2  A: 

Use wordwrap and pass it the fourth parameter, $cut, as true to force the URL to be broken.

Live example.

Artefacto
This would be the easiest, but I have tried and cannot seem to get it to work.
timg
@timg What's the problem? Check the link I've added.
Artefacto
Try doing that with imagettftext with exploded text, it doesn't work.
timg
@timg I'm not sure I understand what you're saying. Does `imagettftext` ignore line breaks?
Artefacto
Because I am breaking the text up to check for urls and coloring them before the imagettftext, the text is in sections and doesn't line breaks.
timg
http://codepad.viper-7.com/dBpmEI
maggie
This method works, but if I have a url that is split the second half isn't colored.
timg
+1  A: 

i guess i know what you want to achieve. i've didn't test the code below, so it could need some polish and re-thing / testing. but it should give you a good startpoint

<?php
$text = "Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem http://somelongurl.com/then-we-make-it-super-long-with-some-more/ Lorem Ipsum Lorem Ipsum Lorem Ipsum";
$string_chunks = explode(' ', $text);

foreach ($string_chunks as $chunk) {
    $_start_bit = false;
    // before anything else check if chunk is url
    $color_to_draw = is_a_url($chunk) ? $linkcolor : $black; 
    // check if chunk is to long
    if(strlen($chunk) > $image_width) {
        // if there is allredy a word in the current line
        // make the first bit $imagewidth - current line width
        if ($start_x > 5) {
            $_start_bit = substr($chunk, 0, ($image_width - $start_x));
            $chunk = str_replace($_start_bit, "", $chunk);
        }
        $_chunkbits = wordwrap($chunk, $image_width, "\n", true);
        $_chunkbits = explode("\n", $_chunkbits);
        if($_start_bit) {
            array_unshift($_chunkbits, $_start_bit);
        }
        // loop bits and draw them
        foreach ($_chunkbits as $bit) {
            if($end_x + $bit > $image_width){
                $start_x = 5;
                $start_y += 20;
            }
            $coords = imagettfbbox($fontsize, $angle, $font, $bit);
            $end_x = $coords[0] + $coords[4] + 10;
            imagettftext($im, $fontsize, $angle, $start_x, $start_y, $color_to_draw, $font, $bit);
            $start_x += $end_x;
        }
        unset($_chunkbits);
    } else {
        if($end_x + $chunk > $image_width){
            $start_x = 5;
            $start_y += 20;
        }
        $coords = imagettfbbox($fontsize, $angle, $font, $chunk);
        $end_x = $coords[0] + $coords[4] + 10;
        imagettftext($im, $fontsize, $angle, $start_x, $start_y, $color_to_draw, $font, $chunk);
        $start_x += $end_x;
    }
}
maggie