Search code examples
phpimagegdcentering

Unable to horizontally center 'm' with GD2


My goal is to draw a horizontally centered m. I therefore calculate the width of the letter, substract that value from the total width and finally divide by 2. The result should be the distance from the left (or equally from the right).

However, the 'm' is always misplaced. I also noticed that some fonts may not trigger the problematic behavior. Note that my script correctly works for all other latin characters.

Arial:

Misplaced 'm'; font: Arial

Bitstream Vera Sans:

Misplaced 'm'; font: Bitstream Vera Sans

<?php

$totalWidth = 100;
$totalHeight = 100;
$font = 'Arial.ttf';

$img = imagecreatetruecolor($totalWidth, $totalHeight);
$red = imagecolorallocate($img, 255, 0, 0);

$fontSize = 100;
$bbox = imagettfbbox($fontSize, 0, $font, 'm');
$width = max($bbox[2], $bbox[4]) - max($bbox[0], $bbox[6]);

$centeredX = ($totalWidth - $width) / 2;

imagettftext($img, 100, 0, $centeredX, 100, $red, $font, 'm');
imagepng($img, 'testcase.png');
imagedestroy($img);

Solution

  • There is a small space left of each letter, and this is different each letter. Somebody on PHP.net wrote a solution for this: http://www.php.net/manual/en/function.imagettfbbox.php#97357

    You need to adjust your code a little bit.

    $totalWidth = 100;
    $totalHeight = 100;
    $font = 'Arial.ttf';
    
    // change letter to see it with different letters
    $letter = "m";
    
    $img = imagecreatetruecolor($totalWidth, $totalHeight);
    $red = imagecolorallocate($img, 255, 0, 0);
    
    $fontSize = 100;
    $bbox = calculateTextBox($fontSize, 0, $font, $letter);
    
    $centeredX = (($totalWidth - $bbox['width']) / 2);
    
    // here left coordinate is subtracted (+ negative value) from centeredX
    imagettftext($img, 100, 0, $centeredX + $bbox['left'], 100, $red, $font, $letter);
    
    header('Content-Type: image/png');
    imagepng($img);
    imagedestroy($img);