斜体或者字体本身为手写体 宽度计算

void COptFontTest::DrawTest1(CDC *pDC)
{

 /*
 问题很简单。
 有一个字符串 "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
 _T("宋体") //   typeface   name
 );

 pDC->SaveDC();
 pDC->SelectObject(&font);//选择你需要的字体
 //pDC->SelectObject(GetStockObject(ANSI_FIXED_FONT));
 CString   strTest   =   _T( "宋体ffff");//字符串可以任意指定
 CSize   cs;
 if(m_iTestFuncType == 0) {
  cs = pDC->GetTextExtent(strTest);//获得字符串长度
 } else if(m_iTestFuncType == 1) {
  HDC hdc = pDC->GetSafeHdc();
  //cs = pDC->GetTextExtent(strTest);//获得字符串长度
  GetTextExtentPoint32(hdc, strTest, strTest.GetLength(), &cs);
 } else if(m_iTestFuncType == 2) {
  CRect rcTmp(0,0,0,0);
  //pDC->DrawText(strTest, &rcTmp, DT_CALCRECT | DT_WORDBREAK);
  pDC->DrawText(strTest, &rcTmp, DT_CALCRECT);
  cs.cx = rcTmp.Width();
  cs.cy = rcTmp.Height();
 }
 
 ABC abc1;
 ABC abc2;
 GetCharABCWidths(pDC->GetSafeHdc(), 'f', 'f', &abc1);


 {
  CFont   font1;
  font1.CreateFont(
  120, //   height   of   font
  0, //   average   character   width
        0, //   angle   of   escapement
  0, //   base-line   orientation   angle
  FW_NORMAL, //   font   weight
  1, //   通常字体
  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
  _T("宋体") //   typeface   name
  );
  CFont *pOldFont1 = pDC->SelectObject(&font1);//选择你需要的字体
  
  GetCharABCWidths(pDC->GetSafeHdc(), 'f', 'f', &abc2);
  pDC->SelectObject(pOldFont1);
 }

 // BOOL GetTextExtentPoint32(HDC hdc, LPCTSTR lpString, int cbString, LPSIZE lpSize);
 CRect   rc(0,0,cs.cx  - abc1.abcC,cs.cy);
 pDC-> SetBkMode(TRANSPARENT);
 FrameRect(pDC-> GetSafeHdc(),rc,(HBRUSH)GetStockObject(BLACK_BRUSH));
 pDC-> DrawText(strTest,rc,DT_LEFT|DT_NOCLIP);
 pDC-> RestoreDC(-1);

 //pDC->ExtTextOut(
 }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值