Imagettfbbox вычисляет неправильный прямоугольник, когда текст начинается с номера

Проблема заключается в том, что при использовании imagettfbbox для вычисления текстовых размеров возвращается слишком маленький прямоугольник, когда ввод текста начинается с цифр. Это мой код:

$fontSize = 150;
$font = "font/courier_new.ttf";
$text = $_GET["text"];

//Determine font dimensions
$bbox = imagettfbbox($fontSize, 0, $font, $text);   
$bbox["width"]=  abs($bbox[4]-$bbox[0]);
$bbox["height"]= abs($bbox[5]-$bbox[1]);

$im = imagecreatetruecolor($bbox["width"], $bbox["height"]);

echo "<b>Image size:</b>\n";
print_r($bbox);

// This part makes transparent background
imagesavealpha($im, true);
$bg = imagecolorallocatealpha($im, 254, 254, 254,127); 
$text_color= imagecolorallocate($im, 0, 0, 0);
imagealphablending($im, false);
imagefilledrectangle($im, 0, 0, imagesx($im), imagesy($im), $bg );
imagealphablending($im, true); 


header("X-Img-Size: ".$bbox["width"]."x".$bbox["height"]."");

imagettftext($im, $fontSize, 0, 0, $bbox["height"], $text_color, $font, $text);

// This is output    
header("Content-Type: text/html");  
ob_start();
imagepng($im);
$image_data = ob_get_contents();
ob_end_clean();
imagedestroy($im);

echo "<img src=\"data:image/png;base64,".base64_encode($image_data)."\" />";

Онлайн-тест здесь

Это результаты, которые я получаю для ввода текста:

image description

image description

image description

Как я могу это исправить?

Ответы

Ответ 1

Проблема была вызвана неправильным представлением. Значения imagettfbbox также определяют , где вы должны начать рисовать, и часто эти координаты даже отрицательны. Я всегда предполагал, что вы можете начать с координат [0, 0]. Это неверно, координаты чертежа могут быть отрицательными.

Эта функция, также упоминаемая в комментариях и исходящая из вкладок пользователей PHP.net, вычисляет начальные координаты, а также ширину и высоту (что было правильно в рассматриваемом коде).

// Source: http://php.net/manual/en/function.imagettfbbox.php#75407
function imagettfbboxextended($size, $angle, $fontfile, $text) {
    /*this function extends imagettfbbox and includes within the returned array
    the actual text width and height as well as the x and y coordinates the
    text should be drawn from to render correctly.  This currently only works
    for an angle of zero and corrects the issue of hanging letters e.g. jpqg*/
    $bbox = imagettfbbox($size, $angle, $fontfile, $text);

    //calculate x baseline
    if($bbox[0] >= -1) {
        $bbox['x'] = abs($bbox[0] + 1) * -1;
    } else {
        //$bbox['x'] = 0;
        $bbox['x'] = abs($bbox[0] + 2);
    }

    //calculate actual text width
    $bbox['width'] = abs($bbox[2] - $bbox[0]);
    if($bbox[0] < -1) {
        $bbox['width'] = abs($bbox[2]) + abs($bbox[0]) - 1;
    }

    //calculate y baseline
    $bbox['y'] = abs($bbox[5] + 1);

    //calculate actual text height
    $bbox['height'] = abs($bbox[7]) - abs($bbox[1]);
    if($bbox[3] > 0) {
        $bbox['height'] = abs($bbox[7] - $bbox[1]) - 1;
    }

    return $bbox;
}

Но необходимо, чтобы вы использовали координаты x и y, заданные этой функцией при рисовании:

imagettftext($im, $fontSize, 0, $bbox["x"], $bbox["y"], $text_color, $font, $text);