C# WinForm,Graphics.MeasureString 計(jì)算不準(zhǔn)確的坑

Graphics.MeasureString 可以計(jì)算出指定字符串在給定字體Font的尺寸SizeF,它的計(jì)算有坑:如果把字符串拆開(kāi)成一個(gè)一個(gè)單字字符串并逐個(gè)計(jì)算尺寸,然后把Width加起來(lái),你會(huì)發(fā)現(xiàn)并不一定等于完整的字符串計(jì)算出來(lái)的Width。

經(jīng)過(guò)一番折騰,最終發(fā)現(xiàn)關(guān)鍵在于字符串中是否有空格。

舉個(gè)例子

Graphics g = Graphics.FromHwnd(IntPtr.Zero);
string foo = "ab c";
float totalCharWidth = 0F;
for (int i = 0; i < foo.Length; i++)
{
    float charWidth = g.MeasureString(foo.Substring(i, 1), SystemFonts.DefaultFont, 9999, StringFormat.GenericTypographic).Width;
    Console.WriteLine(string.Format("Char '{0}' width : {1}", foo.Substring(i, 1), charWidth));
    totalCharWidth += charWidth;
}
Console.WriteLine(string.Format("Total Char Width  : {0}", totalCharWidth));
Console.WriteLine(string.Format("String '{0}' Width  : {1}", foo, g.MeasureString(foo, SystemFonts.DefaultFont, 9999, StringFormat.GenericTypographic).Width));

執(zhí)行結(jié)果

Char 'a' width : 6
Char 'b' width : 6
Char ' ' width : 0
Char 'c' width : 6
Total Char Width  : 18
String 'ab c' Width  : 24

字符串foo拆開(kāi)后計(jì)算出來(lái)的Width總和為16,和foo完整計(jì)算出來(lái)Width24不同,關(guān)鍵問(wèn)題顯然是空格的Width居然為0。

經(jīng)過(guò)測(cè)試,Graphics.MeasureString 計(jì)算字符串Width時(shí)會(huì)忽略掉頭尾的空格后再進(jìn)行計(jì)算,而夾在字符串中間的空格卻會(huì)納入計(jì)算(等于幫你給字符串自動(dòng)做了次.Trim(),這坑是什么操作?),因此單獨(dú)計(jì)算空格的Width實(shí)際上計(jì)算的空字符串的Width,因此為0。

所以,如果你希望單獨(dú)得到空格的準(zhǔn)確Width,簡(jiǎn)單的方法是:
1.計(jì)算出"a a"的Width1 => w1;
2.計(jì)算出"aa"的Width => w2;
3.用w1 - w2,就可以得到空格的Width。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容