text - 为什么 HTML5 Canvas 的 "width"对象中的 "actualBoundingBoxLeft + actualBoundingBoxRight"和 "TextMetrics"之间存在差异?

标签 text html5-canvas 2d

当我调用 measureText (如代码片段所示)时,我得到以下结果:

{
  "width": 45.43333435058594,
  "actualBoundingBoxLeft": 0,
  "actualBoundingBoxRight": 45.35,
  "actualBoundingBoxAscent": 18,
  "actualBoundingBoxDescent": 0
}

如果 actualBoundingBoxLeft 为零,为什么 widthactualBoundingBoxRight 之间存在差异?

c2d = document.getElementById('canvas').getContext('2d');
c2d.direction = 'ltr';
c2d.font = '24px serif';
console.log (c2d.measureText('TeX'));
<canvas id="canvas"></canvas>

最佳答案

希望我能得到你的要求,我会尝试一下。

width 属性给出 the text's advance width 。所占空间不包括左侧和右侧轴承。

-宽度属性

内联框的宽度(以 CSS 像素为单位)。 (文本的提前宽度。)

-actualBoundingBoxLeft属性

textAlign 属性指定的对齐点到给定文本边框左侧的平行于基线的距离(以 CSS 像素为单位);正数表示从给定对齐点向左移动的距离。

其中还给出了注释:

The sum of this value and the next (actualBoundingBoxRight) can be wider than the width of the inline box (width), in particular with slanted fonts where characters overhang their advance width.

-actualBoundingBoxRight属性

textAlign 属性指定的对齐点到给定文本边框右侧的平行于基线的距离(以 CSS 像素为单位);正数表示从给定对齐点向右的距离。


一些示例

使用 Canvas 的 measuereText 中的数据进行 f(正常左侧,斜体右侧):

f left-righ bearing and advance width

错误:交换了中间和底部宽度线(蓝色)的位置,但没有更新标签。对于图中的标签,“中”是“底部”,“底部”是“中间”。稍后我会尽力抽出时间上传新的。

尤其是倾斜的版本很好地体现了这一点。 textBaseline(灰色水平线)之后并从 textAlign(灰色垂直线)开始的蓝线显示字形的宽度值。这就是字体使“打字头”前进的程度。

边界框左/右是水平扩展的极端。如果把它看成一个矩形。上升和下降也是如此。它们是上/下的极端。但是,由于字体的“重叠”(字距调整等),它不是代表高级宽度的宽度的因素。

框宽度之和为 111 + 39 = 150,但宽度仅为 72.28


至于你的示例,这么小的字体很难捕捉到。 (相对而言)。将 for 增加到 1024px 或任何可以提供更清晰结果的值。分数和路径计算是如此之小,以至于人们会错过微妙的像素分数。 1024px:

  actualBoundingBoxAscent  :  747
  ​actualBoundingBoxDescent :   14
  ​actualBoundingBoxLeft    :  -10
  ​actualBoundingBoxRight   : 1933.5
  ​width                    : 1938.5

考虑到总宽度,差异 (1933.5 + -10 = 1923.5) 仍然很小,但至少存在于服务对象中。

另一个带有 + 的示例:

enter image description here

据观察,字形使文本前进比它在绘制像素中占据的位置要多得多。甚至可能出现字形根本不推进文本的情况。它们仍然可以单独存在于文本中,但它的定义在某种程度上适用于之前的字形...例如 dấu hỏi上面的钩子(Hook)宽度为零。

enter image description here

但有些仍然被定义为前进字符,例如:

enter image description here

该示例的另一个有趣之处在于,看看 Descent 是如何为负的(不会低于 textBaseline),并且 Ascent 也存在。从逻辑上讲,当人们看到它时,但可能是一个陷阱。

可以在 Canvas 上扩大测试规模,但必须仔细观察。自从我在卡瓦斯工作以来已经太久了。这是一个近距离 View ,但尚未验证或检查线条的精确度(精确到像素)。

如果正确,它会显示一个微妙的差异,其中 宽度 在使用 24px 字体的 TeX 末尾前进。

enter image description here

关于text - 为什么 HTML5 Canvas 的 "width"对象中的 "actualBoundingBoxLeft + actualBoundingBoxRight"和 "TextMetrics"之间存在差异?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65287369/

相关文章:

javascript - 将日期转换为文本

linux - Sed错误:sed:-e表达式#1,字符12:`s'的未知选项

javascript - 如何使用 HTML5 水平翻转图像

python - python 中的二维列表数组

python - 从文本文件中获取矩阵的行、列平均值

json - 如何将aws-sdk-go的输出设置为“text”?

javascript - 输入数据不是有效图像。 - Azure 认知服务 - Javascript - Canvas

javascript - 如何在 Canvas 中获得更多光标位置

c# - 使用 C# 访问二维数组时出错

java - 如何用Java中的Canvas根据屏幕的宽度和高度绘制字符串或矩形