位图字体渲染和字距调整
Posted
技术标签:
【中文标题】位图字体渲染和字距调整【英文标题】:Bitmap font rendering and kerning 【发布时间】:2011-01-03 00:08:27 【问题描述】:我正在尝试创建位图字体渲染器,但是在渲染实际的单个字母位置时遇到问题。
我将通过 GetCharABCWidthsFloat 和 GetTextMetricsW 获取字体字符信息,但是,我不确定如何正确使用 ABC 宽度……还是需要更多信息才能做到这一点?
我不想使用 FreeType 或任何其他库来执行此操作,我正在尝试使用 C++\Windows 提供的标准功能来执行此操作。
没有字距调整信息,字母将不正确。例如,看一下“f”和“t”并排放置的“Times new roman”。如果没有正确的字母间距,它们看起来会相距太远。 算法示例---
float letterBottomLeftX = 0.0f;
float letterHeight = 1.0f;
float letterWidth = 1.0f;
float scale = 1.0f;
for(U32 c = 0; c < numberOfCharacters; ++c)
fon->GetCharcterInfo(charValue, charInfo);
//float advancedWith = (charInfo.A * scale) + (charInfo.B * scale) + (charInfo.C * scale);
letterWidth = charInfo.B * scale;
letterHeight = textMetrics.Height * scale;
if(c == 0)
letterBottomLeftX = -(charInfo.A * scale);
// vertex placement, beginning at letterBottomLeftX
// texture placement
// index placement
letterBottomLeftX += (charInfo.A + charInfo.B + charInfo.C) * scale;
这是一个外观示例,您可以注意到字符之间的错误间距。 (忽略纹理 UV,我将在正确放置字母后修复它)。
http://img88.imageshack.us/img88/4015/njpjp2.png
【问题讨论】:
有人写过位图字体渲染器吗? 【参考方案1】:KERNINGPAIR
的文档看起来很简单。如果当前字符和下一个字符都通过wFirst
和wSecond
成员出现在表格中,请将iKernAmount
添加到您为下一个字符前进的像素数中。
我建议使用GetKerningPairs
的结果创建一个std::map<std::pair<wchar_t,wchar_t>,int>
,以便快速查找。您已经注意到 GetKerningPairs
不会为每个可能的字符组合返回结果。此信息来自字体本身,由字体设计者指示哪些字符对需要调整。这些信息很可能完全丢失,或者丢失了对您来说很明显的字符对。
确保在调用任何这些函数之前执行SetMapMode(hdc,MM_TEXT)
,因为映射模式会影响结果。
【讨论】:
有趣。 “SetMapMode(hdc,MM_TEXT)”应该放在哪里?我就是这样做的,但我不确定它是否正确使用它(对不起,很多回复,这里的格式对于回复来说很糟糕)。 HFONT fnt CreateFont(size,0,0,0,FW_NORMAL,0,0,0,ANSI_CHARSET,OUT_TT_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,FF_DONTCARE,"Times New Roman"); int nKerningPairs = GetKerningPairs(dc, 0, 0); KERNINGPAIR * kerningpairs = new KERNINGPAIR[nKerningPairs]; GetKerningPairs(dc, nKerningPairs, kerningpairs); 另外,如果我只是想通过 GetKerningPairs 使用信息,那么我应该提前下一个字符的位置吗?如您所见,我目前正在通过 GetABCWidth 的 B 信息推进它。【参考方案2】:一种常见的解决方案是创建一个字母对宽度表。因此,字母“Ti”会比 MN 更靠近。这是一个快速制作的表格,并且可以在成本上产生不错的结果。
【讨论】:
有没有办法自动创建这个表?只在其中放置值而不以某种方式查询信息似乎是一种黑客行为。 GetKerningPairs 不会返回所有对的信息,即使它们需要特殊放置。 我来自嵌入式游戏开发领域。执行此操作的工具将是理想的,但众所周知,我们可以通过捷径获得结果。大多数情况下,我只是给你一个可行的解决方案的想法。以上是关于位图字体渲染和字距调整的主要内容,如果未能解决你的问题,请参考以下文章