AssFace has asked for the wisdom of the Perl Monks concerning the following question:

I have some code in which I am taking a string and putting it over top of an image. This is running on a Linux server (DreamHost, if that matters).
I am doing this with GD, something like:
$img->string(gdSmallFont, 10, 12, $long_string, $white);
My issue is that $long_string might be longer than the width of the image. I actually check this and then insert a newline in a spot I deem appropriate and then put that into the image - except that the newline (\n - and I even tried \n\r and \r\n and even \r\n\r) is not showing up in the image (they are in the string, but the image continues to plow them through the edge of the frame and it has no line breaks).

Is there a special character that I need to use for GD to respond to the line breaks?

Or perhaps I missed something in the string output where you could define more than just its left corner position, text, and color?
(meaning, definite a smaller rectangle that it should be put into that would fit in the image?)

(on a side note, when I try and load an external TT font, GD fails with an out of memory error - not sure why, hence why the above is just using the default gd system font)

There are some odd things afoot now, in the Villa Straylight.

Replies are listed 'Best First'.
Re: Newline in GD?
by pc88mxer (Vicar) on Mar 13, 2008 at 22:37 UTC
    I'm pretty sure you have to implement line breaks yourself with multiple calls to ->string, e.g.
    my $y = 12; $img->string(gdSmallFont, 10, $y, $line1, $color); $y += $delta; $img->string(gdSmallFont, 10, $y, $line2, $color); $y += $delta; $img->string(gdSmallFont, 10, $y, $line3, $color); ...
      Good to know - I was looking at the example for $img->stringFT and saw they were using newlines (\r\n) in their example code, so I just assumed (bad) that the string call would as well. (as I noted, the TT load fails for me on the server with an out of memory exception, so my first guess is that it is not setup to handle true type, so the stringFT is out - which is what lead me to the regular string route.

      I will just do it the longer way as you say, but was hoping I was wrong and missing something that would do it - thanks for the fast reply!

      There are some odd things afoot now, in the Villa Straylight.
Re: Newline in GD?
by nefigah (Monk) on Mar 13, 2008 at 22:44 UTC

    I would say pc88 is right--in most graphics libraries where you have to render text, the basic text rendering function creates one line and only one line. Change your current code that adds newlines to instead break up the string and throw it in an array, and then have a loop call $img->string on each array element.

    I'm a peripheral visionary... I can see into the future, but just way off to the side.

Re: Newline in GD?
by zentara (Archbishop) on Mar 14, 2008 at 13:47 UTC
    If you read "perldoc GD::Text", there is a way to get the current width of the string in pixels:
    $gd_text->width(string) return the length of a string in pixels, without changing the current value of the text. Returns the width of string rendered in the cur rent font and size. On failure, returns undef.
    So.... you could write a simple loop, to make your string fit the width of the graphic, and when it approaches the limit, shift your next string down by 1.5 times the height of your font, which you can obtain from $gd_text->get('height').

    You should be able to print nicely wrapped text, breaking on whole words, with a clever loop to construct and test current string width in pixels.

    I'm not really a human, but I play one on earth. Cogito ergo sum a bum