You are here: 首頁 文章分類選單 PHP分享特區 計算文字在HTML中的顯示寬度

飛朵啦學習手札

本網站建議使用Firefox2.0以上,或是使用Goole瀏覽器來瀏覽,並使用1024x768解析度來觀看.

計算文字在HTML中的顯示寬度

E-mail 列印 PDF

我自己寫的js版參考以下文章做出的

http://www.rupeng.com/innersupesite/index.php/7/viewspace-583

JS版:

function arial_strlen(val, word_length){

var lencounter=0;

var sub_str = 0;

for (var i = 0; i < val.length; i++) {

if(ck_null(word_length) != '-'){

if(Math.ceil(lencounter*2) >= word_length){

return sub_str;

}

}

ch = val.substr(i,1);

 

var char_050 = ",./;'[]=-/*-!@#$%^&*()_{}:\"<>?1234567890fijlrIt";

 

asc_ch = ch.charCodeAt();

//if(ord(ch)>128){

if (ch.match(/[^\x00-\xff]/ig) != null){

lencounter++;

}else if(char_050.indexOf(ch) != -1){

lencounter+=0.5;

}else if(asc_ch>=48 && ch<=57){

lencounter+=0.55;

}else if(asc_ch>=97 && asc_ch<=122){//a~z

lencounter+=0.55;

}else if(asc_ch>=65 && asc_ch<=90){//A~Z

lencounter+=0.8;

}else{

lencounter++;

}

sub_str++;

}

return Math.ceil(lencounter*2);

}

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

php中可以使用strlen或者mb_strlen計算字符串的長度,但是這些長度計算的都是在計算機中表示的長度,並不是實際在屏幕上顯示的寬度。

最理想的實現方式是使用imagettftext計算字符串使用特定字體顯示的寬度:

function tf_strlen($str)

{

return ceil(tf_strwidth($str)/tf_strwidth('測'));

}

function tf_strwidth($str)

{

$im=ima​​gecreatetruecolor(10,10);

$r=imagettftext($im, 12, 0, 5, rand(14, 16),0, 'arial.ttf', $str);

return $r[2]-$r[0];

}

 

需要在本地計算機的字體文件夾中找到'arial.ttf',然後上傳到php頁面同級的目錄下。這樣調用tf_strlen得到的就是字符串在屏幕上的顯示寬度了。但是因為imagettftext是GD級別的操作,因此效率非常低,編寫下面的程序驗證

 

$begin=microtime(true);

$im=ima​​gecreatetruecolor(1000,1000);

for($i=0;$i<10000;$i++)

{

imagettftext($im, 12, 0, 5, rand(14, 16),0, 'arial.ttf', "rupeng.com 如鵬網在校不迷茫,畢業即輝煌");

}

$t1=microtime(true)-$begin;

echo 'imagettftext:'.$t1.'<br/>';

$begin=microtime(true);

for($i=0;$i<10000;$i++)

{

strlen("rupeng.com 如鵬網在校不迷茫,畢業即輝煌");

}

$t2=microtime(true)-$begin;

echo 'strlen:'.$t2.'<br/>';

 

echo $t1/$t2.'<br/>';

 

運行後發現imagettftext的運行時間是strlen的4000多倍,太慢了,而且CPU佔用率非常高,因此被否定。

 

經過觀察發現arial字體下,漢字的寬度是一致的,而1、i、l等字符的寬度大約是漢字的0.4倍,而阿拉伯數字(除了1)的寬度則是漢字的約0.7倍,小寫字母(除了i、l等)的寬度是漢字的約0.7倍,大寫字母則是漢字的0.8倍,其他字符也可以得出相應的倍率。因此我編寫了下面程序用來計算字符串佔的寬度(單位是1/2的中文寬度)。

 

function arial_strlen($str)

{

$lencounter=0;

for($i=0;$i<strlen($str);$i++)

{

$ch=$str[$i];

if(ord($ch)>128)

{

$i++;

$lencounter++;

}

else if($ch=='f'||$ch=='i'||$ch=='j'||$ch=='l'||$ch=='r'||$ch =='I'

||$ch=='t'||$ch=='1'

||$ch=='.'||$ch==':'||$ch==';'||$ch=='('||$ch==')'

||$ch=='*'||$ch=='!'||$ch=='\'')

{

$lencounter+=0.4;

}

else if($ch>='0'&&$ch<='9')

{

$lencounter+=0.7;

}

else if($ch>='a'&&$ch<='z')

{

$lencounter+=0.7;

}

else if($ch>='A'&&$ch<='Z')

{

$lencounter+=0.8;

}

else

{

$lencounter++;

}

}

return ceil($lencounter*2);

}

 

經過大量的測試,發現和imagettftext的運行結果非常接近,而速度則比imagettftext高很多,CPU佔用率也低很多。

解決思路對於其他語言,比如C#、Java等都適用。

 
 

新增回應


驗證碼
更新