views:

83

answers:

3

I'm trying to find some sense in some old code related to printing.

When drawing a form to the printer, every size and position property get multiplied by a scale factor. The factor is calculated by the following code:

    { Printer device-specific information }
    FXScale := (GetDeviceCaps(Printer.Handle, LOGPIXELSX)/96) -
               ((2-(GetDeviceCaps(Printer.Handle, HORZRES)*2) /
               GetDeviceCaps(Printer.Handle, PHYSICALWIDTH)));
    FYScale := (GetDeviceCaps(Printer.Handle, LOGPIXELSY)/96) -
               ((2-(GetDeviceCaps(Printer.Handle, VERTRES)*2) /
               GetDeviceCaps(Printer.Handle, PHYSICALHEIGHT)));

Can anyone explain what is happending here? I guess there is some mapping between screen resolution and printer resolution, but what about the rest? Why the 2's?

A: 

Could it be a 1 inch margin on each side of the paper ?

Edelcom
Can you explain how the formula above translates to mean two inches? The printer's built-in margin is `(PhysicalWidth - HorzRes) / (2 * LogPixelsX)` inches.
Rob Kennedy
@Rob Kennedy: I was thinking, and it was just a thought that the 2 could be one inch left and 1 inch right - hence the HORZRES - which is, I think, specified in nr dots per inch, the 2 just a small border and the LOGPIXELSX being the widht of the page. Therefore the 1 inch margin thought. But obviously, this was just a thought and not tried out (hadn't got a Delphi at hand to try something).
Edelcom
+3  A: 

OK, not sure I've got the complete answer, but maybe this will help spur someone else in the right direction:

FXScale = (LogPixelsX / 96) - (2 - ((2 * HorzRes) / PhysicalWidth))
        = (LogPixelsX / 96) - (2 - (2 * (HorzRes / PhysicalWidth)))
        = (LogPixelsX / 96) - (2 * (1 - (HorzRes / PhysicalWidth)))

Since PhysicalWidth is guaranteed to be greater than or equal to HorzRes (see MS documentation), 1 - (HorzRes / PhysicalWidth) = ((PhysicalWidth - HorzRes) / PhysicalWidth). Then we have:

FXScale = (LogPixlesX / 96) - (2 * ((PhysicalWidth - HorzRes) / PhysicalWidth)
  • (LogPixelsX / 96) = Ratio of Printer DPI to Screen DPI
  • ((PhysicalWidth - HorzRes) / PhysicalWidth) = Ratio of Non-Printable Width to Total Width of Paper

So, it looks like calculate the ratio of printer DPI to screen DPI, then subtract double the ratio of non-printable width to total width of paper. Maybe the 2 is to get a little bit away from the edge of the physical limits of the printer?

Scott W
That sounds possible. There is a call to SetViewportOrgEx( ) elsewhere, with a negative offset of PhysicalOffsetX/Y. I guess the scaling will shrink everything so that nothing get clipt?
Vegar
+1  A: 

Just a tip here... don't hardcode the 96. Newer displays can run at higher res. So if you want to keep the functionality of making the printed report 'about the same' as the size on the screen, you should determine this dynamically.

Chris Thornton
Yes, i know. The code is littered with hardcoded 'magic' numbers all over. Tried to run the application at 120 dpi - not much working anywhere actually... :-/
Vegar