如何指定不同方向的字体高度?
使用 GDI 创建字体的常见方法是使用所需的点大小和目标设备的垂直分辨率 (DPI),如下所示:
LOGFONT lf = {0};
lf.lfHeight = -MulDiv(point_size, GetDeviceCaps(hdc, LOGPIXELSY), 72);
...
HFONT hfont = CreateFontIndirect(&lf);
假设默认 MM_TEXT
映射模式,这会将 point_size 转换为像素高度所需的设备。 (这是一个常见的近似值。实际上,一英寸有 72.27 点,而不是 72。)(减号表示我想指定实际字符高度,而不是单元格高度。)
如果我想创建横向字体--也就是说,方向和擒纵机构为 90 度 - 我是否使用 LOGPIXELSX
而不是 LOGPIXELSY
? 对于我所针对的某些打印机,水平和垂直分辨率是不同的。
一般来说,如果我想要 theta
角度,我是否需要结合 LOGPIXELSX
和 LOGPIXELSY
? 我正在考虑这样的事情:
// Given theta in degrees (e.g., theta = 45.0) ...
double theta_radians = theta * 2.0 * pi / 360.0;
int dpi = static_cast<int>(GetDeviceCaps(hdc, LOGPIXELSX) * sin(theta_radians) +
GetDeviceCaps(hdc, LOGPIXELSY) * cos(theta_radians) +
0.5);
LOGFONT lf = {0};
lf.lfHeight = -MulDiv(point_size, dpi, 72);
// Set escapement and orientation to theta in tenths of a degree.
lf.lfEscapement = lf.lfOrientation = static_cast<LONG>(theta * 10.0 + 0.5);
...
这对我来说很直观,但我想知道这是否真的是 GDI 字体映射器和打印机驱动程序的工作方式。
The common way to create a font with GDI is to use the desired point size and the target device's vertical resolution (DPI) like this:
LOGFONT lf = {0};
lf.lfHeight = -MulDiv(point_size, GetDeviceCaps(hdc, LOGPIXELSY), 72);
...
HFONT hfont = CreateFontIndirect(&lf);
Assuming the default MM_TEXT
mapping mode, this converts point_size into the pixel height for the desired device. (This is a common approximation. There are actually 72.27 points in an inch, not 72.) (The minus sign means I want to specify the actual character height, not the cell height.)
If I want to create a sideways font--that is, one with an orientation and escapement of 90 degrees--do I use LOGPIXELSX
rather than LOGPIXELSY
? For some of the printers I'm targeting, the horizontal and vertical resolutions are different.
Generally, if I want an angle of theta
, do I combine LOGPIXELSX
and LOGPIXELSY
? I'm thinking of something like this:
// Given theta in degrees (e.g., theta = 45.0) ...
double theta_radians = theta * 2.0 * pi / 360.0;
int dpi = static_cast<int>(GetDeviceCaps(hdc, LOGPIXELSX) * sin(theta_radians) +
GetDeviceCaps(hdc, LOGPIXELSY) * cos(theta_radians) +
0.5);
LOGFONT lf = {0};
lf.lfHeight = -MulDiv(point_size, dpi, 72);
// Set escapement and orientation to theta in tenths of a degree.
lf.lfEscapement = lf.lfOrientation = static_cast<LONG>(theta * 10.0 + 0.5);
...
This makes intuitive sense to me, but I'm wondering if this is really how the GDI font mapper and printer drivers work.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
1)有72点/英寸。 (以前是 72.27,但已更改。)
2)按照您的方式组合 LOGPIXELSX 和 LOGPIXELSY 很好,但是
3) 字体映射器在映射字体时不会考虑擒纵和方向。 LOGPIXELS 值将仅用作坐标转换的一部分。
http://msdn.microsoft.com/en-us/library /ms969909(loband).aspx
不确定“打印机驱动程序如何工作”,因为该语句可能包含许多可能的驱动程序和打印机。
他们可以用方形像素进行光栅化,然后拉伸到非方形。 他们可以改变字形曲线。 他们可以做点别的事。
1) There are 72 points/inch. (it used to be 72.27 but was changed.)
2) Combining LOGPIXELSX and LOGPIXELSY in the way that you do is fine, but
3) The font mapper doesn't look at escapement and orientation when mapping fonts. The LOGPIXELS values will only be used as part of the coordinate transformation.
http://msdn.microsoft.com/en-us/library/ms969909(loband).aspx
Not sure about how the "printer drivers work" because the statement could include many possible drivers and printers.
They could rasterize with square pixels, then stretch to non-square. They could transform glyph curves. They could do something else.