您问题中的代码正在调用new Canvas()
,它将假定您的屏幕是预期的输出设备,从而为不同系统上的不同行为创造潜力。
该文档明确指出 Java 2D 中的用户空间旨在为每英寸 72 个单位。FontMetrics 的 Javadoc 没有明确说明它返回的单位,但它是用户空间坐标是有意义的。这意味着您看到的 36 是 36/72 英寸,即 12.7 毫米。
更新 2:
您的问题没有说明您是如何将渲染文本发送到打印机的,因此您可能已经有一个 Graphics 或 Graphics2D 对象,可以从中获取实际输出设备上下文中的字体度量。如果你不这样做,下面的代码应该创建一个独立于屏幕的图形上下文:
BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = image.createGraphics();
FontMetrics fm = g.getFontMetrics(new Font("Arial", Font.PLAIN, 6));
int width = fm.stringWidth("Product name");
结果仍然是 36,以 1/72 英寸为单位。
更新 3:
在下图中,字符串“NCW”以 Arial 显示,由 Java 呈现。矩形的底部是基线,矩形的左下角是我告诉 Java 绘制字符串的点。矩形的宽度fm.stringWidth()
如上输出。(矩形的顶部是任意的。)您可以看到字符串宽度与文本接触基线的点无关,但也不是从最左边到最右边的填充像素的距离。相反,它是沿着基线向右推进,从这个字符串被绘制到下一个字符串通常被绘制的地方。
C 和 W 之间的间距是字距调整的一个很好的例子。字体设计者还选择让 C 的底部边缘稍微延伸到基线下方,因为除非你作弊,否则圆形在视觉上看起来与直的不对齐。请注意 N 的左侧有一些空间,而 W 的右侧则少得多。这与 C 和 W 之间的空间较小的原因相同:使其看起来正确。如果字体设计师想要,他可以让 W 延伸到盒子之外,就像 C 延伸到它下面一样。
最终结果是字母形式的视觉重量应该是均匀分布的,所以那个框的中心应该是文本的视觉中心。所以你应该可以忽略我刚才说的一切,在起点加上一半的弦宽,称之为中心,然后开心。
如果结果看起来不以您为中心,那么您可能有数学错误,或者您的打印代码中的某些内容没有按照您的想法执行,或者字体设计师根本没有根据您的喜好平衡视觉重量. 如果是后者,请随意申请一些艺术许可并将其软化到您喜欢的地方。