0

I'd really appreciate the help of anyone with more PHP experience than me.

I'm using PHP to generate close-packed text images. So far, it works like this:

  1. First it generates a random string of x number of characters.
  2. Then it makes an image with background etc.
  3. It places the first character in a specific place (with some randomising of the size, rotation etc)
  4. Then it places the next character so that the bottom left corner of its bounding box is at the same point as the bottom right corner of the bounding box of the character before (plus some randomness etc). The code for that goes like this:

    $coords = array();
    $pos_y = $this->image_height / 2;
    
    for ($counter = 0; $counter < $this->code_length; $counter++){
        $sbox = @imagettfbbox($size, $angle, $font, $this->code[$counter]);
        if($counter == 0)
            $pos_x = $this->image_width / $this->code_length;
        else
            // element 2 is the x co-ord of the bottom right corner of the ttf box
            $pos_x = $coords[$counter-1][2];
        @imagettftext($this->image, $size, $angle, 
             $pos_x, $pos_y, $fontcolor, $font, $this->code[$counter]);
    }
    
  5. and repeat 4 for each subsequent character in the string.

What I want is for, as much as possible, every character to be touching its neighbour(s). What I've done so far works fine for characters like 'M' where the bottom corners of the glyph are more or less in the corners of the bounding box, but it's nowhere close for a letter like 'G' or 'I'.

Does anyone know of a way to get the actual dimensions of a ttf glyph rather than just the bounding box? Or can anyone think of any better way to approach this problem?

Any thoughts/ideas/advice much appreciated.

Tim Barclay
  • 807
  • 8
  • 23
  • It would be a good idea to post a bit of your code to encourage responses – cssyphus Jun 21 '13 at 14:59
  • your problem could be the rotation of the text. From [imagettftext](http://www.php.net/manual/en/function.imagettftext.php): `The points are relative to the text regardless of the angle, so "upper left" means in the top left-hand corner when you see the text horizontally.` – bitWorking Jun 21 '13 at 15:07
  • @redreggae that is part of the problem. But even ignoring rotation, the actual glyphs of letters don't all go to every corner of their bounding box - rotation just compounds that difficulty. So even if there were no rotation involved at all, a 'G' and an 'A' next to each other won't touch even if the bottom right point of the 'G' = the bottom left point of the 'A'. – Tim Barclay Jun 21 '13 at 15:14

1 Answers1

1

the bounding box is simply that - the box that indicates the min/max x and y values for the text. If you have the letter C and the letter O, making their bounding boxes touch will never make the actual letters touch, because the line the two letters are joined on has the C at the top and bottom, and the O in the middle.

If you want to make sure the letters touch, you'll have to get the glyph outline data, instead, and either use clever algorithms that find projection points for glyph 1 on glyph 2, or use a naive minmax algorithm where you put the two next to each other, rasterise them with a transparent color, see if any of the pixels coloured are darker than they should be, if so, move the letters apart by distance D, try again, if they don't overlap, move back together by distance D/2, if they overlap, move out again by D/4, if they don't, move in more by D/4, then correct with D/8, D/16, etc until the distance is less than a pixel.

Bounding box aligning is cheap and easy, what you want to do is, unfortunately, not both. It can be cheap (but then the algorithm is hard) or easy (but then the algorithm is expensive).

(should you want to give using glyph outline data a try, you can try to use FreeType2, or something like https://github.com/pomax/php-font-parser)

Mike 'Pomax' Kamermans
  • 49,297
  • 16
  • 112
  • 153
  • I suspected the answer might be something like the ones you've suggested. Thanks for pointing me to the php font parser. I'll have a look at that. – Tim Barclay Jun 22 '13 at 10:46