Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 位图字体渲染和紧排_C#_C++_Algorithm_Gdi+_Rendering - Fatal编程技术网

C# 位图字体渲染和紧排

C# 位图字体渲染和紧排,c#,c++,algorithm,gdi+,rendering,C#,C++,Algorithm,Gdi+,Rendering,我正在尝试创建位图字体渲染器,但是,我在渲染实际的单个字母位置时遇到问题 我将通过GetCharABCWidthsFloat和GetTextMetricsW获得字体字符信息,但是,我不确定如何正确使用ABC宽度。。。或者我需要更多的信息来做这件事 我不想使用FreeType或任何其他库来实现这一点,我正试图通过C++\Windows提供的标准功能来实现这一点 如果没有字距信息,字母将不会显示正确。例如,看一看“Times new roman”,其中“f”和“t”相邻放置。如果没有正确的字母间距,

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

我将通过GetCharABCWidthsFloat和GetTextMetricsW获得字体字符信息,但是,我不确定如何正确使用ABC宽度。。。或者我需要更多的信息来做这件事

我不想使用FreeType或任何其他库来实现这一点,我正试图通过C++\Windows提供的标准功能来实现这一点

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

float-letterBottomLeftX=0.0f;
浮动字体高度=1.0f;
浮动字体宽度=1.0f;
浮动刻度=1.0f;
对于(U32 c=0;cgetCharacterInfo(charValue,charInfo);
//float advancedWith=(charInfo.A*scale)+(charInfo.B*scale)+(charInfo.C*scale);
字母宽度=charInfo.B*刻度;
letterHeight=textMetrics.Height*比例;
如果(c==0)
{
letterBottomLeftX=-(charInfo.A*比例);
}
//顶点放置,从LeftX开始
//纹理放置
//索引放置
LeftX+=(charInfo.A+charInfo.B+charInfo.C)*比例;
}
下面是一个示例,您可以注意到字符之间的间距很差。(忽略纹理UV,我将在获得正确的字母位置后修复它)


一种常见的解决方案是创建字母对宽度表。因此,字母“Ti”的位置比MN更接近。这是一个快速制作的表格,并以相当高的成本产生非常好的结果。

有关
内核对的文档似乎非常简单。如果当前字符和下一个字符都通过
wFirst
wssecond
成员出现在表中,请将
iKernAmount
添加到下一个字符的像素数中

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


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

是否有方法自动创建此表?它看起来像是一个黑客,只是把值放在那里,而没有查询信息。GetKerningPairs不会返回所有对的信息,即使它们需要特殊放置。我来自嵌入式游戏开发领域。实现这一点的工具是理想的,但众所周知,我们可以通过快捷方式获得结果。大体上,我只是给你一个可行的解决方案的想法。“SetMapMode(hdc,MM_文本)”应该放在哪里?我就是这样做的,我不确定它是否正确使用了它(很抱歉回复太多,这里的格式对回复来说太糟糕了)。HFONT fnt CreateFont(大小,0,0,0,FW_正常,0,0,0,ANSI_字符集,放样精度,剪裁默认精度,校样质量,FF_DONTCARE,“新罗马时代”);int nKerningPairs=GetKerningPairs(dc,0,0);KERNINGPAIR*kerningpairs=新的KERNINGPAIR[nKerningPairs];GetKerningPairs(dc、nKerningPairs、kerningpairs);另外,如果我只想通过GetKerningPairs使用信息,那么我应该为下一个字符提前位置吗?正如你所看到的,我目前正在通过GetABCWidth的B信息推进它。有人编写过位图字体渲染器吗?
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;
}