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
Comments
Anonymous
October 10, 2006
Ben:Two questions about the PageImageableArea,From the driver point of view, it should reflect the printable surface GDIINFO->ulHorzRes that DrvEnablePDEV returns, which should map to *PrintableArea in GPD config file in a GDP based driver, like MXDW or Xdsmpl driver. But when I tried PTGetPrintCapabilities() with the RC1 WDK sample driver, it always return the PrintCapabilites set with the PageImageableArea 's printable area equals the media size and OriginWidth=OriginHeight=0. But if you take a look at XDSmpl.GPD, every *PrintableArea is actually smaller than its media size. Which means, PageImageableArea doesn't reflect these values defined in XDSmpl.GPD. Is there sth wrong with XDSmpl?As a PrintCapabilites Property, PageImageableArea contains only a single paper's printable area info, but not every media size papers' listed in PageMediaSize. This means when I print a mixed paper size document, the IPrintTicketProvider::GetPrintCapabilities() need to return a bunch of different PrintCapabilities sets for different PageImageableArea'. This looks to me a single set of PrintCapabilites cannot include every device capabilities. At the same time, it's like the old DrvDeviceCapabilities() been called many times, which is not efficient. My question is, why not provide a imageable area list just like in PPD/GPD for all the media sizes in PrintCapablites? Thanks,ZoomAnonymous
June 15, 2009
PingBack from http://unemploymentofficeresource.info/story.php?id=4838Anonymous
July 28, 2011
Hi Ben,I have read all your posts about Print Tickets & I still have some questions regarding interactionwith Print Tickets. I precise that I am new in Windows Printer driver development but got quitea lots of experience in MacOsX & linux (CUPS based).I have recently take a look at the HP-GL2 printer drivers sample in the DDK & focus my intereston the unidriver mini sample (the monolithic one is great but has a big restriction regarding papersize).I would like to enhance my UI by adding an option that create automatically a Paper Size that fitthe image size at the printing resolution: let say a Fit Image Size Checkbox/Option.In that case, I would like to disable the paper size selection & track the PrintTicket that control thepage size & replace it by a page size that fit my image size at printing resolution. Do you think that it's possible ?How to have access to the device surface size ?Thank's a lot for your help.Yvan