Функция от safarov содержит небольшую ошибку, продемонстрированную для моего пользовательского случая. Если бы я послал слово больше, чем $ width, после этого было бы новое слово после каждого слова, например:
veryloooooooooooooongtextblablaOVERFLOWING
this
should
be
one
line
Причина в том, что imagettfbox всегда будет> $ width с этим «вредоносным» словом внутри текста. Мое решение состояло в том, чтобы просто проверить каждую ширину слова отдельно и при желании обрезать слово до тех пор, пока оно не будет соответствовать $ width (или отменить обрезку, если мы получим длину 0). Затем я продолжаю обычную перенос слов. Результат примерно такой:
veryloooooooooooooongtextblabla
this should be one line
Вот модифицированная функция:
function wrap($fontSize, $fontFace, $string, $width) {
$ret = "";
$arr = explode(" ", $string);
foreach ( $arr as $word ){
$testboxWord = imagettfbbox($fontSize, 0, $fontFace, $word);
// huge word larger than $width, we need to cut it internally until it fits the width
$len = strlen($word);
while ( $testboxWord[2] > $width && $len > 0) {
$word = substr($word, 0, $len);
$len--;
$testboxWord = imagettfbbox($fontSize, 0, $fontFace, $word);
}
$teststring = $ret.' '.$word;
$testboxString = imagettfbbox($fontSize, 0, $fontFace, $teststring);
if ( $testboxString[2] > $width ){
$ret.=($ret==""?"":"\n").$word;
} else {
$ret.=($ret==""?"":' ').$word;
}
}
return $ret;
}