22.5.2 将文本调整到适合按钮
我们已经接收到了用户键入的一些文本,这些文本保存在$button_text变量中,我们要做的是将它以适合按钮的最大字体打印在按钮上。通过多次调整可以达到此目标;严格地说,是经过反复的试验。
首先设置一些相关变量。首要的两个变量是按钮图像的高度和宽度:
$width_image=imagesx($im);
$height_image=imagesy($im);
其次,设置两个表示按钮边缘的宽度的变量。按钮图像是有斜边的,因此应在文本周围为斜边留有空白。如果使用的图像与此不同,这个数字将是不同的!在这个例子中,每边的空白大概是18个像素:
$width_image_wo_margins=$width_image-(2*18);
$height_image_wo_margins=$height_image-(2*18);
我们还设置了初始化字体大小。起始字体大小是32(实际上是33,但是我们会马上减小它),因为它大约是可以适合该按钮的最大字体:
$font_size=33;
使用GD2库,必须通过设置环境变量GDFONTPATH告诉脚本字体所在的位置,如下所示:
putenv('GDFONTPATH=C:\WINDOWS\Fonts');
我们还需要设置希望使用的字体名称。我们将在TrueType函数中使用这个字体,这将在以上字体路径中查找字体文件,而且将在文件名称后添加.ttf扩展名(TrueType字体)。
$fontname='arial';
请注意,根据操作系统的不同,可能要在字体名称后添加".ttf"。
如果系统没有安装Arial(我们在这个例子中使用的字体)字体,可以将其改变为其他的TrueType字体。
现在我们开始执行循环,每次字体大小递减1,如此重复,直到提交的文本基本适合按钮:
do
{
$font_size—;
//find out the size of the text at that font size
$bbox=imagettfbbox($font_size,0,$fontname,$button_text);
$right_text=$bbox[2];//right co-ordinate
$left_text=$bbox[0];//left co-ordinate
$width_text=$right_text-$left_text;//how wide is it?
$height_text=abs($bbox[7]-$bbox[1]);//how tall is it?
}
while($font_size>8&&
($height_text>$height_image_wo_margins||
$width_text>$width_image_wo_margins)
);
以上代码通过查看所谓的文本边框测试文本的大小。通过调用ImagegetttfBox()函数完成测试,该函数是TrueType字体函数之一。在计算出字体大小之后,我们将用TrueType字体(在这个例子中,我们使用的是Arial字体,但也可以使用任何你所喜欢的字体),以及调用Imagettftext()函数将文本打印在按钮上。
一段文本的边框是围绕该文本的最小可能边框。边框的一个示例如图22-6所示。
图 22-6 边框的坐标是相对于基线给出的。坐标原点是图中的(0,0)
要获取该框的大小,可以调用如下函数:
$bbox=imagettfbbox($font_size,0,$fontname,$button_text);
以上调用的意思是,“对给定的字体大小$font_size,其文本倾斜0˚,它使用TrueType字体Arial,请告诉我$button_text变量中文本的大小。”
请注意,实际上还需要将包含该字体文件的路径传递给该函数。在这个例子中,其目录与脚本所在目录相同(在默认情况下),因此不用指定其他更长的路径。
该函数将返回一个包含边框各个角的坐标的数组。数组内容如表22-1所示。
要记住数组的内容,只要记住坐标开始于边框的左下角,并且坐标系是逆时针方向的。
应当注意的是,从ImageTTFBBox()函数返回的值。这些值都是坐标值,也就是与原点的距离的相对值。然而,它们不像图像坐标,图像坐标相对于图像左上角而定,而它们是根据基线而定的。
让我们回头再看看图22-6。可以看到,我们沿大部文本的底部画了一条线。该线称为基线。一些字母在行方向上低于基线,例如,在这个例子中的字母"y"。我们称之为下行字母。
基线的左边定义为起始量度——也就是,x坐标为0,y坐标也为0。坐标位于x之上称x坐标为正,位于x之下称x坐标为负。
除此之外,事实上,文本的坐标值还有位于边框之外的可能情况。例如,文本可能实际上从x坐标值-1的地方开始。
这些事实都使我们用这些数字进行计算的时候要加倍小心。
我们将按如下步骤计算文本的宽度和高度:
$right_text=$bbox[2];//right co-ordinate
$left_text=$bbox[0];//left co-ordinate
$width_text=$right_text-$left_text;//how wide is it?
$height_text=abs($bbox[7]-$bbox[1]);//how tall is it?
完成这些操作后,我们将测试循环条件。
}while($font_size>8&&
($height_text>$height_image_wo_margins||
$width_text>$width_image_wo_margins)
);
在这里,我们测试了两组条件。首先是字体是否仍然可读——使用小于8号的字体已经没有意义,因为人的肉眼几乎不能看清按钮上的文本。第二组条件是测试文本是否适合我们为其绘制的空间。
下一步,将检查循环计算是否找到了可以接受的字体大小。如果没有找到,将报告错误:
if($height_text>$height_image_wo_margins||
$width_text>$width_image_wo_margins)
{
//no readable font size will fit on button
echo'Text given will not fit on button.<br/>';
}