使用字形信息渲染字体

发布于 2024-10-08 20:44:34 字数 1077 浏览 1 评论 0原文

我调用“GetCharABCWidthsFloatW”来获取字符的宽度信息。这样我就可以获得左侧轴承、右侧轴承和高级宽度。

为了定位每个字符,我将从“xPlacement”变量开始,该变量从零开始。我将首先通过减去“左侧轴承”来调整 xPlacement 变量。绘制字符后,我将按字符的宽度将其推进(稍后我将展示对此的计算)。然后,我将通过添加当前“xPlacement”中的“右侧轴承”信息来移动 xPlacement 变量。

在我看来,这就是角色放置的代码,对吗?

重要的是纠正字符的宽度。宽度将通过先进宽度加上左侧轴承的正版本和右侧轴承的正版本来计算。如果这些值为负值,我会将其转换为正值,这样我就可以获得字符的总宽度。

这是一些关于它是如何生成的伪代码。

float xPlacement = 0.0f;
for(int i = 0; i < strlen(text); ++i)
{
 char charValue = text[i];
 GetCharWidthABC(.., .., charInfo);

 float posLeft = charInfo.leftSideBearing;
 if(charInfo.leftSideBearing < 0)
  posLeft = -charInfo.leftSideBearing;

 float posRight = charInfo.rightSideBearing;
 if(posRight < 0)
  posRight = -charInfo.rightSideBearing;

 float posWidth = posRight + posRight + charInfo.advancedWidth;

 float letterWidth = posWidth;

 xPlacement  -= charInfo.leftSideBearing;

 /* generated some vertex coordinates, using the xPlacement variable and letterWidth */

 xPlacement += letterWidth;
 xPlacement += charInfo.rightSideBearing
}

这看起来是正确的方法吗?

I call "GetCharABCWidthsFloatW" to get the width information for a character. With this I will get the leftside bearing, right side bearing and the advanced width.

For positioning each characters, I will start with a "xPlacement" variables that will begin at zero. I will first adjust the xPlacement variable by subtracting the "left side bearing". After the character is drawn, I will then advance it by the width of the character( I will show the calculation for this later). I will then move the xPlacement variable by adding the "right side bearing" information from the current "xPlacement".

This, in my opinion is all that should be code for character placement, correct?

An important thing is to correct the width of the characters. The width will be calculated by taking the advancedWidth, plus the POSITIVE version of the left side bearing and the POSITIVE version of the right side bearing. I will convert this values to positive, if they are negative so I can have the total width of the character.

Here is some pseudo code about how it is generated.

float xPlacement = 0.0f;
for(int i = 0; i < strlen(text); ++i)
{
 char charValue = text[i];
 GetCharWidthABC(.., .., charInfo);

 float posLeft = charInfo.leftSideBearing;
 if(charInfo.leftSideBearing < 0)
  posLeft = -charInfo.leftSideBearing;

 float posRight = charInfo.rightSideBearing;
 if(posRight < 0)
  posRight = -charInfo.rightSideBearing;

 float posWidth = posRight + posRight + charInfo.advancedWidth;

 float letterWidth = posWidth;

 xPlacement  -= charInfo.leftSideBearing;

 /* generated some vertex coordinates, using the xPlacement variable and letterWidth */

 xPlacement += letterWidth;
 xPlacement += charInfo.rightSideBearing
}

Does this appear to be the correct way to do this?

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

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

发布评论

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

评论(2

渔村楼浪 2024-10-15 20:44:34

由于问题标签中提到了 C#,因此您可能会对查看 .NET Framework 附带的一些非常强大的类(从版本 3.0 开始,实际上随 WPF 核心程序集附带)感兴趣。它们是:

  • GlyphTypeFace:指定物理字体与磁盘上的字体文件相对应的面。对于解析 .TTF 文件并从中构建字形很有用。
  • GlyphRun:表示来自单一字体、单一尺寸、单一渲染风格的单一面,具有许多有用的属性和方法(例如,您可以从中构建几何图形)
  • GlyphRunDrawing:表示呈现 GlyphRun 的 Drawing 对象。也许对您来说不太有趣,因为它与 WPF 渲染/合成系统更相关。

前两个类在某种程度上与技术/设备无关,除了 .NET Framework 本身之外。

Since C# is mentioned in the question tags, maybe you'll find some interest in looking at some very powerful classes that ship with .NET Framework (starting with version 3.0, in fact shipped with WPF core assemblies). They are:

  • GlyphTypeFace: Specifies a physical font face that corresponds to a font file on the disk., useful to parse a .TTF file and build glyphs from it.
  • GlyphRun: Represents a sequence of glyphs from a single face of a single font at a single size, and with a single rendering style, with many usefull properties and methods (for example, you can build a Geometry from it)
  • GlyphRunDrawing: Represents a Drawing object that renders a GlyphRun. Maybe less interesting for you because it's more tied to WPF rendering/composition system.

The two first classes are somewhat technology/device independant, except from the .NET Framework itself.

执手闯天涯 2024-10-15 20:44:34

听起来不错,但查看其是否正确的最佳方法是运行它并使用各种不同的字体查看结果。

字形度量中的左/右方位角值不包括字距调整信息。 (字距调整=允许字符“依偎”或侵占相邻的字符单元格框,以消除由悬垂的上伸部或下伸部产生的分散注意力的空白)。

字距调整数据特定于特定字符对,并且字符的顺序很重要。根据字体的不同,“AV”的字距调整偏移量可能与“VA”的字距调整偏移量不同。有些字体不包含字距调整数据,有些则包含。

有关详细信息和渲染指南,请查看可在 SourceForge 上下载的 FreeType 库的文档。 FreeType 是一个用于处理 OpenType 字体加载的例程库(很大程度上与 TrueType 兼容)。 FreeType 文档中的信息主要适用于在 Win32 GDI 中呈现 TrueType。

还可以测试使用粗体和斜体(和粗体斜体)替代字体,并在同一行文本中混合和匹配字体。如果您的算法遗漏了某些内容,这将显示字符间距问题。

Sounds about right, but the best way to see if it's right is to run it and look at the results with a variety of different fonts.

The left/right bearing values in the glyph metrics do not include kerning info. (kerning = allowing characters "snuggle up" or encroach upon the adjacent character cell box to eliminate distracting whitespace created by overhanging acenders or descenders).

Kerning data is specific to particular character pairs, and the order of the characters is significant. The kerning offset for "AV" may be different from the kerning offset for "VA" depending on the font. Some fonts do not include kerning data, some do.

For detailed info and rendering guidelines, check out the documentation of the FreeType library available for download on SourceForge. FreeType is a library of routines to handle loading of OpenType fonts (largely compatible with TrueType). The information in the FreeType docs is largely applicable to rendering TrueType in Win32 GDI.

Also test using bold and italic (and bold italic) font alternates, and mix and match fonts in the same line of text. This will show character spacing problems if your algorithm is missing something.

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