Using PrintTicket for print layout

The PrintTicket contains a feature PageMediaSize that describe various attributes about a piece of paper, and is intended to let users pick the paper size that they want to print on.  The PageImageableSize is what should be used for application layout.  Why the distinction?  A look at the Win32 programming model can provide the answer:

In Win32 programming, an application would typically call DocumentProperties to generate a DEVMODE, which contains some paper size information in the fields dmFormName, dmPaperSize, dmPaperWidth and dmPaperHeight.  The application would then, if needed change the DEVMODE paper fields to reflect the application's content, if the application had a notion of what paper size the content should be rendered to.  A document editor might do this, since the document has an associated paper size.  Other applications, such as internet explorer, would likely not do this, since web pages typically don't have a fixed paper size.

The application would then likely call DocumentProperties again, but this time turn on the flag to show UI, and would pass the DEVMODE it just configured as input.  The user then does their thing in the UI, and the app gets back another DEVMODE.  The app then passes this DEVMODE to CreateDC("printername"...) to get a rendering device context.  The DC can then be passed to an API GetDeviceCaps to query various information about the rendering context, including the size of hte surface, the resolution, etc.  GetDeviceCaps is how the application determines the layout on the paper, printable margins, etc.  The DC maps to a SURFACE in GDI, but the printer driver controls how the data on that surface gets translated into data on the wire to the printer.

What's interesting here is that the driver holds all the cards in a number of critical places.  The association between the size information on the DC & the size information in the DEVMODE is controlled completely by the driver, as is the association between the size information in the DC and the data sent to the printer.  This means that the user could ask for 300DPI on letter in the DEVMODE, the driver could provide a surface that's twice as large or twice the resolution in CreateDC, then reprocess the data, and send it to the printer at 300 DPI on letter paper.  In this case, the driver explicitly chose to ask the app for a larger surface, possibly to do some resolution enhancement or processing.  The printer still generates the same output that the user expects though.

For all pre-Vista drivers, the PrintTicket solution is dependent on various conversions between GDI information & PrintTicket information.  As such, it was impractical to try to remove this ability of the driver to tell the app one thing, and the user & printer another.  The result is that the PageMediaSize in the PrintTicket and PrintCapabilities reflects the user intent, but should not be used for rendering and layout.  The PageImageableArea in the PrintCapabilities maps most closely to the GetDeviceCaps, and should be used to determine page layout information by an application at rendering time.

- Ben