关于精确计算字符串写屏宽度==GDI深入讨论==
问题很简单。
有一个字符串"ffff",求用GDI函数DrawText/TextOut等输出到屏幕后这个字符串占用屏幕像素的精确大小。
-------------------------------
看起来很简单,1分钟就可以写出下面代码。
pdc->SelectObject(&font);//选择你需要的字体
CString strTest = _T("ffff");//字符串可以任意指定
CSize cs=pdc->GetTextExtent(strTest);//获得字符串长度
是不是很简单?cs里面就是答案。
但是,很不幸,这个结果只是在大多数情况下有效。在字体为斜体或者自体本身为手写体(script字体)是,它的精确度就会出现问题。
当然,通过一些技巧解决部分问题,比如Yuan Feng在他的《windows图形编程》中将使用的字体先作为图片生成,然后求出图片大小,在需要求字符串长度的时候,查表累加。但是,这样只可以解决英文,如果是中文,不可能事先求出这个表(除非你的内存足够大,且用户有足够的耐心等待程序的启动)
===============
欢迎大家讨论
--------------
附:测试代码,copy到OnDraw内即可。输出后可以看到f有一部分超出了外接矩形框
CFont font;
font.CreateFont(
120, // height of font
0, // average character width
0, // angle of escapement
0, // base-line orientation angle
FW_NORMAL, // font weight
1, // italic attribute option
0, // underline attribute option
0, // strikeout attribute option
DEFAULT_CHARSET, // character set identifier
OUT_DEFAULT_PRECIS,// output precision
CLIP_DEFAULT_PRECIS,// clipping precision
DEFAULT_QUALITY, // output quality
DEFAULT_PITCH , // pitch and family
"宋体" // typeface name
);
pDC->SaveDC();
pDC->SelectObject(&font);//选择你需要的字体
CString strTest = _T("ffff");//字符串可以任意指定
CSize cs=pDC->GetTextExtent(strTest);//获得字符串长度
CRect rc(0,0,cs.cx,cs.cy);
pDC->SetBkMode(TRANSPARENT);
FrameRect(pDC->GetSafeHdc(),rc,(HBRUSH)GetStockObject(BLACK_BRUSH));
pDC->DrawText(strTest,rc,DT_LEFT|DT_NOCLIP);
pDC->RestoreDC(-1);