Search code examples
gdirounding-errormetafile

Specifying DPI of a GDI Device Context


I have an application that generates metafiles (EMFs). It uses the reference device (aka the screen) to render these metafiles, so the DPI of the metafile changes depending on what machine the code is running on.

Let's say my code is intending to create a metafile that is 8.5 in x 11 in. Using my development workstation as a reference, I end up with an EMF that has

  • an rclFrame of { 0, 0, 21590, 27940 } (dimensions of the metafile, in thousandths of a mm)
  • a szlDevice of { 1440, 900 } (dimensions of the reference device, in pixels)
  • a szlMillimeters of { 416, 260 } (dimensions of the reference device, in mm)

Okay, so the rclFrame tells me that the size of the EMF should be

  • 21590 / 2540 = 8.5 in wide
  • 27940 / 2540 = 11 in tall

Right on. Using this information, we can determine the physical DPI of my monitor, too, if my math is right:

  • (1440 * 25.4) / 416 = 87.9231 horizontal dpi
  • (900 * 25.4) / 260 = 87.9231 vertical dpi

The problem

Anything that plays back this metafile--an EMF-to-PDF conversion, the "Summary" page when right-click on the EMF in Windows Explorer, etc--seems to truncate the calculated DPI value, displaying 87 instead of 87.9231 (even 88 would be fine).

This results in a page that is physically sized as 8.48 in x 10.98 in (using 87 dpi) instead of 8.5 in x 11 in (using 88 dpi) when the metafile is played back.

  • Is it possible to change the DPI of the reference device so that the information stored in the metafile used to calculate the DPI comes out to a nice integer?
  • Can I create my own device context and specify its DPI? Or do I really have to use a printer to do that?

Thanks for any insight.


Solution

  • I'm curious as to how Windows knows the physical size of your monitor. You must have changed a configuration somewhere? Perhaps you can change it to more convenient values that divide out nicely.

    As implied by the name, a "Device Context" must be connected to a system device. However this does not need to be a hardware driver, it could be a device emulator such as a PDF writer print driver. I've seen at least one that lets you set an arbitrary DPI.