【问题标题】:Determining the y placement of a character for rendering text确定用于呈现文本的字符的 y 位置
【发布时间】:2012-05-30 14:17:08
【问题描述】:

我一直在研究我自己的位图字体渲染器,虽然我相信我的字符间距可能正确,但我不确定如何确定字符的 y 位置。例如,如果字母 'a' 的 y 位置为 0,那么 '*' 或 ',' 会有什么?我一直在使用 winapi 函数GetCharABCWidthsFloatW 来确定字符之间的间距,还有其他函数可以用来确定某种 y 偏移吗?

我正在对我的位图图像进行最佳拟合,因此它们的大小并不总是相同。

【问题讨论】:

  • 字体的位图高度不一样吗?
  • 好点,我正在做最适合我的位图图像,所以它们并不总是相同的大小..
  • 也许有某种偏移表?与基线有偏移,因此您可以使用同一个表格来放置像“g”这样的字母。
  • 这个偏移量表是如何生成的?我想使用字体信息而不是猜测并检查表格的类型。

标签: c++ winapi text typography bitmap-fonts


【解决方案1】:

一般字体信息:

您正在寻找的是如何将文本放置标准化为“基线”或“原点”(相同的概念)。根据您的坐标系,您可以使用上升 (ascender) 或下降 (descender) 来执行此操作。

http://www.freetype.org/freetype2/docs/tutorial/step2.html

这提供了一组非常好的与排版相关的示例图像。

一般位图字体信息:

现在,对于位图图像,确保它们都正确排列的最简单方法是在精灵表中为每个字符的位图表示具有相同的高度(宽度应该不同,但取决于实际字符宽度)。如果您这样做,那么您可以简单地根据该共享高度排列所有内容。

但是,如果要剪裁字符周围多余的空白,则需要将剪裁的值与字形一起存储在某些结构中,以便确定偏移量。如果 API 为您执行此操作,它们可能具有上升/下降、原点/基线或行高类型的方法,您可以在其中基于字符获取完整尺寸,以便正确执行此操作。

API 特定信息
编辑:根据其他答案,这里是您的 API 特定问题的相关链接:

GetTextMetrics:
http://msdn.microsoft.com/en-us/library/dd144941(v=vs.85).aspx

TEXTMETRIC 结构:
http://msdn.microsoft.com/en-us/library/dd145132(v=vs.85).aspx

tmAscent 或 tmDescent 可用于帮助偏移 y 坐标。

【讨论】:

    【解决方案2】:

    如果我理解正确:每个字形的位图最初的高度相同。然后修剪每个字形周围的所有空闲空间,为每个字符创建一个最小的位图。

    在这种情况下,答案很简单。创建修剪位图时,请记住从左侧和顶部(或左侧和底部,取决于您定位字形的方式)移除了多少像素。绘制位图时,您可以使用保存的值调整坐标。

    但是,如果您尝试使用字体指标来确定要从每个位图中修剪多少,则不能。

    【讨论】:

      【解决方案3】:

      GetTextMetrics 是正确答案。但demorge 可能想说,您需要用于 Y 坐标的字段是 tmAscent(查看结构。)

      总高度为 tmHeight。 tmAscent 是从顶部到基线的距离。而tmDescent是基线到字体底部的距离。

      所以在大多数情况下,如果 (x, y) 坐标参考文本的左上角,则需要添加 tmAscent。如果 y 坐标是底部,则减去 tmDescent(+ 或 - 也取决于您是否反转视口,但您可以测试并查看得到的结果。)

      无论您写“a”、“*”还是“j”,该信息都有效。所有字符的基线都是相同的。

      【讨论】:

      • 我怎样才能知道一个特定的角色有多少上升或下降?我将一个字符写入位图,然后为每个字符创建一个最佳位图并保存。所以在位图上,每一个都有不同的高度。
      • 一种字体中的所有字符都具有相同的上升和下降。如果您想优化位图,您必须自己做一些额外的工作(即对生成的位图进行自动裁剪。)此外,您不能真正创建一个小矩形并期望角色完美适合(除非你在终端使用像 Courier 这样的字体)。大多数字体到处“泄漏”。计算出正确的盒子真的很难。
      【解决方案4】:

      每个字符本身都应该通过文本渲染 API 正确地在 y 方向偏移(TextOut、DrawText 等),因此您应该有一个恒定的偏移量。我总是使用GetTextExtentPoint32获取字符串“Ag”的指标来获取一般指标,此外您可以尝试GetTextMetrics。

      【讨论】:

      • 我查看了GetTextMetrics,但我需要获取特定于字符的信息,这就是字体的信息。如何使用来自GetTextExtentPoint32 的信息来抵消y?
      猜你喜欢
      • 1970-01-01
      • 2017-07-25
      • 1970-01-01
      • 2022-01-20
      • 2021-10-04
      • 1970-01-01
      • 2012-05-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多