In PHP, the imagefontwidth function is used to obtain the width of a single character in the built-in fonts. It returns the character width for the default font set, which helps calculate text width and layout when using the GD library to render text. However, the default imagefontwidth only supports fixed-width built-in fonts and has limited support for international characters (such as Chinese, Japanese, Korean full-width characters), making it unable to accurately reflect their actual width.
This article will explore how to extend or customize the imagefontwidth function to support more international character widths, thereby improving the accuracy and aesthetics of text rendering.
imagefontwidth(int $font): int
Only accepts built-in GD font numbers (1 to 5)
Returns a fixed width, ignoring the actual character content
Does not support width calculation for multibyte characters, unable to distinguish half-width and full-width characters
For example:
<?php
$font = 5;
$width = imagefontwidth($font);
echo "Font $font width is $width pixels.";
?>
No matter whether the character is English or Chinese, imagefontwidth returns the same width, which can lead to layout issues.
To support more international character widths, it is necessary to bypass relying solely on imagefontwidth. Consider the following solutions:
imagettfbbox can measure the bounding box size of a string in a specified TrueType font file. It supports multilingual text and multibyte encoding.
Example:
<?php
$fontFile = 'm66.net/fonts/YourFont.ttf'; // Custom font path
$text = "你好,world!";
$fontSize = 16;
<p>$bbox = imagettfbbox($fontSize, 0, $fontFile, $text);<br>
$width = abs($bbox[2] - $bbox[0]);<br>
echo "Text width is $width pixels.";<br>
?><br>
This method can accurately obtain the text width, avoiding the limitations of imagefontwidth.
If you need to maintain compatibility with the imagefontwidth interface, you can create a custom function that returns corresponding widths based on character encoding ranges.
Example:
<?php
function extendedImageFontWidth(int $font, string $char): int {
// Standard width for built-in fonts
$baseWidth = imagefontwidth($font);
$ord = mb_ord($char, 'UTF-8');
// Rough ranges for common Chinese, Japanese, Korean characters
if (($ord >= 0x4E00 && $ord <= 0x9FFF) || // CJK Unified Ideographs
($ord >= 0x3000 && $ord <= 0x303F) || // CJK Symbols and Punctuation
($ord >= 0xFF00 && $ord <= 0xFFEF)) { // Halfwidth and Fullwidth Forms
return $baseWidth * 2; // Assume full-width characters are twice as wide
}
return $baseWidth; // Half-width characters
}
// Usage example
$font = 5;
$char1 = "A";
$char2 = "你";
echo extendedImageFontWidth($font, $char1) . "\n"; // e.g., returns 9
echo extendedImageFontWidth($font, $char2) . "\n"; // returns 18
?>
Although this approach is not perfectly precise, it balances simplicity and some degree of internationalization support.
Based on the above mapping approach, you can accurately calculate the width of an entire string:
<?php
function extendedImageFontWidth(int $font, string $char): int {
$baseWidth = imagefontwidth($font);
$ord = mb_ord($char, 'UTF-8');
if (($ord >= 0x4E00 && $ord <= 0x9FFF) ||
($ord >= 0x3000 && $ord <= 0x303F) ||
($ord >= 0xFF00 && $ord <= 0xFFEF)) {
return $baseWidth * 2;
}
return $baseWidth;
}
<p>function getTextWidth(int $font, string $text): int {<br>
$width = 0;<br>
$len = mb_strlen($text, 'UTF-8');<br>
for ($i = 0; $i < $len; $i++) {<br>
$char = mb_substr($text, $i, 1, 'UTF-8');<br>
$width += extendedImageFontWidth($font, $char);<br>
}<br>
return $width;<br>
}</p>
<p>// Example<br>
$font = 5;<br>
$text = "Hello,世界!";</p>
<p>echo "Text width: " . getTextWidth($font, $text) . " pixels.";<br>
?><br>
imagefontwidth is suitable for fixed-width built-in fonts but cannot support precise widths for multibyte international characters.
By combining imagettfbbox with custom logic, you can obtain more accurate font width information and support multiple languages.
Character width mapping allows extending existing code to estimate the width of wide characters like Chinese and Japanese, suitable for simple scenarios.
In practice, it is recommended to prioritize TrueType fonts and imagettfbbox for measuring string width to improve text rendering quality.