位图字体渲染和字距调整

发布于 2024-10-10 01:28:06 字数 1199 浏览 3 评论 0 原文

我正在尝试创建位图字体渲染器,但是,我在渲染实际的单个字母位置时遇到问题。

我将通过 GetCharABCWidthsFloat 和 GetTextMetricsW 获取字体字符信息,但是,我不确定如何正确使用 ABC 宽度......或者我是否需要更多信息来执行此操作?

我不想使用 FreeType 或任何其他库来执行此操作,我尝试使用 C++\Windows 提供的标准功能来执行此操作。

如果没有字距调整信息,字母将不会显示正确。例如,看看“Times new roman”,其中“f”和“t”彼此相邻。如果字母间距不正确,它们看起来就会相距太远。 算法示例 ---

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

I am attempting to create a bitmap font renderer, however, I am having problems rendering the actual individual letter placements.

I will obtain the font character information via GetCharABCWidthsFloat and GetTextMetricsW, however, I am unsure how to use the ABC width's properly ... or do I need more information to do this?

I do not want to use FreeType or any other libraries's to do this, I am trying to do this with standard functionality available through C++\Windows.

Without the kerning information, the letters will not appear correct. For example, take a look at "Times new roman" when an "f" and a "t" are placed next to each other. Without the correct letter spacing, they will look too far apart.
algorithm example ---

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;
}

Here is an example of what it looks like, you can notice the bad spacing between characters. (Ignore the texture UV's, I am going to fix that after I get the letter placement correct).

http://img88.imageshack.us/img88/4015/njpjp2.png

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

只为一人 2024-10-17 01:28:06

KERNINGPAIR 的文档看起来非常简单。如果当前字符和后续字符都通过 wFirstwSecond 成员出现在表中,请将 iKernAmount 添加到您要计算的像素数。提前下一个字符。

我建议使用 GetKerningPairs 的结果创建一个 std::map,int> 以便快速查找。您已经注意到,GetKerningPairs 不会返回每种可能的字符组合的结果。该信息来自字体本身,由字体设计者指示哪些字符对需要调整。这些信息很可能完全丢失,或者丢失对您来说似乎显而易见的字符对。

请确保在调用任何这些函数之前执行 SetMapMode(hdc,MM_TEXT),因为映射模式会影响结果。

The documentation for KERNINGPAIR seems pretty straightforward. If both the current character and the following character occur in the table via the wFirst and wSecond members, add the iKernAmount to the number of pixels you advance for the next character.

I would suggest creating a std::map<std::pair<wchar_t,wchar_t>,int> with the results from GetKerningPairs for quick lookup. You have noticed that GetKerningPairs does not return a result for every possible combination of characters. This information is coming from the font itself, and it is up to the font designer to indicate which character pairs are in need of adjustment. It is quite possible for this information to be missing entirely, or to be missing character pairs that seem obvious to you.

Make sure you do SetMapMode(hdc,MM_TEXT) before calling any of these functions, since the mapping mode affects the results.

°如果伤别离去 2024-10-17 01:28:06

一种常见的解决方案是创建字母对宽度表。因此,字母“Ti”的排列位置会比“MN”靠得更近。这是一张制作速度很快的桌子,并且以成本为代价产生了不错的结果。

One common solution is to create a letter pair width table. So the letters 'Ti' would be placed closer together than say MN. It's a quick table to make and yields decent to excellent results for the cost.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文