3

I'm using DirectWrite to render some text to a window. Everything seems to work except positioning when using different font sizes: I'd expect 2 texts with font size v1 and v2 and both with (x, y) = (0, 0) to be at the top left but as you can see:

enter image description here

neither "Test" nor "X" are really at the top left.

Is there a way to make this work?

4

3 回答 3

8

欢迎来到字体世界。字体可能是最难使用的东西,因为字体本身有惊喜(有很多新标准应该解决所有问题,但只会混淆更多,因为几乎没有字体 100% 支持它,即使是一些“经典”字体也有其中的部分/错误信息)GDI、GDI+、DirectDraw 由于数学、坐标舍入、抗锯齿等原因,不会在以像素为单位的相同位置绘制字体......(如果你用自由类型)。

当您尝试打印字体时,还有其他 pb。所以解决这个问题的唯一方法是我。甚至不要尝试在某些像素坐标处绘制字体。在屏幕上绘制字体、图片、线条渲染良好,尽力将它们转换为打印坐标以进行导出,但不要期望控制字体中的像素,一切都是近似值。

PS:不要相信字体的内部字段。在 Arial 上,它们对所有其他字体都很好,有些字体丢失或初始化为零,但“有趣”的部分并不总是相同的字段不存在,这取决于字体。如果您之前通过字体尝试过,您只能使用这些字段。是的,字体很棒!

于 2013-08-12T10:28:32.443 回答
2

@evilruff 所指的术语称为“内部领先”。您可以使用IDWriteFontFace::GetMetrics或可能使用IDWriteFontFace::GetDesignGlyphMetrics来获取此值(对于 GetMetrics,您正在寻找的值最有可能metrics.ascent - metrics.capHeight)。

这里的值是字体设计单位,而不是像素(任何类型)。您可以通过除以metrics.designUnitsPerEm;将这些值转换为 em 高度 通常,DirectWrite 中的字体大小由(小写)m 的像素大小指定;因此,如果将 ems 中的值乘以字体大小,则应该得到以像素为单位的值。

于 2013-08-07T18:36:19.393 回答
0

我假设您将 IDWriteTextLayout 与 DrawTextLayout 结合使用(而不是创建自己的 DWRITE_GLYPH_RUN)。IDWriteTextLayout 将字形对齐到它们的布局单元格(包括完整的上升和行间距),而不是字形墨迹,这几乎适用于所有文本布局,无论是 Web 浏览器、文字处理器还是简单的编辑控件。如果他们没有(而不是对齐到字母的顶部),那么像 Ťhis 这样的单词中的变音符号将被剪掉。

如果您总是想对齐墨迹,请创建一个 IDWriteTextLayout,调用 IDWriteTextLayout::GetOverhangMetrics,然后调用原点等于负 DWRITE_OVERHANG_METRICS::left&top 的 DrawTextLayout。如果您想始终与 cap-height 对齐(这样“hello”和“Hello”都将绘制在相同的垂直坐标上),那么 Eric 的方法将起作用。

于 2013-09-21T02:27:39.120 回答