views:

299

answers:

1

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.

A: 

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.

Jason Harrison
Thanks for the link to the article on the font mapper. Unfortunately, it's not quite specific enough on this question. Suppose I'm using a printer that has 72 pixels per inch vertically and 144 pixels per inch horizontally. If I specify lfHeight of 10 for a normal font, I'll get text that's 10 points high. But if I specify an orientation and escapement of 90 degrees, then it's unclear whether the characters will be 5 points high or 10. It depends on whether the mapper and/or rasterizer considers the rotation when applying lfHeight.
Adrian McCarthy