斜体字宽度计算 与混合排版

VC/MFC/C++/C/Linux/Java 专栏收录该内容
123 篇文章 0 订阅

/*
问题1:
我要计算出一个字符串的宽度,再画出来。
先是 SelectObject(hdc, font);
然后 用GetTextExtentPoint32计算宽度。

发现对于同样的字体,同样的大小,是斜体字的时候,计算出来的宽度和非斜体字一样。画出来的斜体效
果是最右边的字少了一块。

解决办法1:

倾斜文本后面紧跟普通的文本时,如果不做任何处理的情况下 斜字文本的最后面字符和正常文本的开头
字符会发生重叠。(这就是问题1中的问题)
若要解决此问题,必须在描画正常文字的时候,补偿第一个字符串的尾随字符多余量。
TrueType 字体使用 GetCharABCWidths 检索这些值。

下面的代码示例输出倾斜的文本中的字符串"fff",并立即在它后面使用 ggg 常规 (非倾斜)
文本中的字符串。 如果您不执行补偿这两个子字符串通常会重叠。

// Sample call to the contrived example below:
ItalicAndRegular(hDC, 0, 0, 12);

// Outputs the italic string "fff" immediately followed by the non-italic
// string "ggg" at position x, y.  The fonts are created at the specified
// point size and using the Times New Roman font for this contrived
// example.
*/
void COptFontTest::DrawTest4(CDC *pDC)
//void ItalicAndRegular(HDC hDC, int x, int y, int iPointSize)
{
 HDC hDC = pDC->GetSafeHdc();
 int x = 100;
 int y = 200;
 int iPointSize = 20;
 LOGFONT lf;
 HFONT hOldFont;
 HFONT hFontRegular = NULL;
 HFONT hFontItalic = NULL;
 SIZE size;
 int lpy;
 ABC abc1;
 ABC abc2;
 CString strFFF = _T("fff");
 // 如果是汉字
 strFFF = _T("如果是汉字");
 CString strGGG = _T("ggg");
 strGGG = _T("也没有问题");

 // Get the vertical DPI of the device.
 lpy = GetDeviceCaps(hDC, LOGPIXELSY);

 // Create a regular (non-italic) font.
 ZeroMemory(&lf, sizeof(lf));
 lf.lfHeight = -MulDiv(iPointSize, lpy, 72 );
 lf.lfItalic = FALSE;
 lf.lfCharSet = DEFAULT_CHARSET;
 lstrcpy(lf.lfFaceName, TEXT("Times New Roman"));
 hFontRegular = CreateFontIndirect(&lf);

 // Create an italic font.
 ZeroMemory(&lf, sizeof(lf));
 lf.lfHeight = -MulDiv(iPointSize, lpy, 72 );
 lf.lfItalic = TRUE;
 lf.lfCharSet = DEFAULT_CHARSET;
 lstrcpy(lf.lfFaceName, TEXT("Times New Roman"));
 hFontItalic = CreateFontIndirect(&lf);

 // Output an italic string.
 hOldFont = (HFONT)SelectObject(hDC, hFontItalic);
 TextOut(hDC, x, y, strFFF, strFFF.GetLength());

 // Get the base width of the italic string *and* the overhang of
 // the last italic character if any (abc1.abcC).
 GetTextExtentPoint32(hDC, strFFF, strFFF.GetLength(), &size);
 GetCharABCWidths(hDC, 'f', 'f', &abc1);

 // Immediately follow the italic string with a non-italic string,
 // taking into account the base width of the italic string, the
 // overhang of the trailing italic character if any (abc1.abcC),
 // and the underhang  of the leading non-italic character if any
 // (abc2.abcA).
 SelectObject(hDC, hFontRegular);
 GetCharABCWidths(hDC, 'g', 'g', &abc2);
 TextOut(hDC, x + size.cx - abc1.abcC - abc2.abcA, y, strGGG,
  strGGG.GetLength());

 // Clean up.
 SelectObject(hDC, hOldFont);
 DeleteObject(hFontItalic);
 DeleteObject(hFontRegular);

 return;
}

 

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值