我正在尝试创建位图字体渲染器,但是,我在渲染实际的单个字母位置时遇到问题。
我将通过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,我会在我得到正确的字母位置后修复它。)
答案 0 :(得分:2)
KERNINGPAIR
的文档似乎非常简单。如果通过wFirst
和wSecond
成员在表格中出现当前字符和后续字符,请将iKernAmount
添加到您为下一个字符前进的像素数。
我建议使用std::map<std::pair<wchar_t,wchar_t>,int>
的结果创建GetKerningPairs
以便快速查找。您已注意到GetKerningPairs
不会为每个可能的字符组合返回结果。此信息来自字体本身,字体设计者可以指示哪些字符对需要调整。这些信息很可能完全丢失,或者缺少对您来说显而易见的字符对。
确保在调用任何这些函数之前执行SetMapMode(hdc,MM_TEXT)
,因为映射模式会影响结果。
答案 1 :(得分:0)
一种常见的解决方案是创建一个字母对宽度表。所以字母“Ti”将比MN更接近。这是一个快速制作的表格,并且可以获得成本优异的结果。