Print jobs are either rendered as they are created, or they are written to a spool file as EMF records. In the case of EMF records, rendering takes place when the EMF print processor (localspl.dll) plays back the records. Rendering consists of a series of calls to the user-mode GDI drawing functions, beginning with CreateDC. The call to CreateDC starts a chain of actions involving the graphics rendering engine (GRE), also known as kernel-mode GDI, and the printer graphics DLL.

Interaction between GDI and the Printer Graphics DLL
The preceding figure shows the interaction between kernel-mode GDI and the printer graphics DLL after CreateDC is called.
At this point, a drawing surface has been created and rendering can begin.
For each document to be rendered, GDI calls the following functions in the printer graphics DLL:
DrvStartDoc
For each physical page {
DrvStartPage
DrvStartBanding
For each banding surface {
DrvQueryPerBandInfo
Rendering operations
DrvNextBand
}
DrvSendPage
}
DrvEndDoc
With the exception of DrvQueryPerBandInfo, these functions are intended to allow the printer graphics DLL to send control sequences to the printer hardware (by calling EngWritePrinter), and to perform any internal operations needed to initialize or complete processing of a document, page, or band.
The printer graphics DLL is responsible for sending the rendered image (that is, the contents of the drawing surface) to the printer at appropriate times (by calling EngWritePrinter), as follows:
The drawing surface is a GDI-supplied or driver-supplied bitmap. The printer graphics DLL might hook some drawing functions (see Surface Negotiation). If page banding is in use, the DrvNextBand function should send drawing surface contents. If banding is not in use, the DrvSendPage function should send the drawing surface contents.
The drawing surface is within the device. The printer graphics DLL hooks all drawing functions (see Surface Negotiation), and these functions send image data to the printer during rendering operations. Page banding is not used.
If you anticipate that any graphics DDI function provided by a printer graphics DLL could potentially take more than five seconds to execute, you should include code that calls EngCheckAbort at least every five seconds to see if the print job should be terminated.
After GDI calls DrvEndDoc to indicate that a document has been completely rendered, it calls DrvDisableSurface. If DrvEnableSurface called EngCreateBitmap, then DrvDisableSurface must call EngDeleteSurface.
GDI calls a printer graphics DLL's DrvDisablePDEV function when an application calls DeleteDC.
If an application calls ResetDC function during the printing of a document, GDI creates a new device context and calls the printer graphics DLL's DrvEnablePDEV function for the new context. Then GDI calls the DrvResetPDEV function, so the graphics DLL can update the new context with information from the old one. Next, DrvDisableSurface and DrvDisablePDEV are called for the old context, followed by DrvEnableSurface for the new context. Finally, GDI calls DrvStartDoc and rendering resumes on a new page.
GDI calls DrvDisableDriver prior to unloading the printer graphics DLL.
If printer hardware supports drawing operations that are not supported by GDI drawing functions, the printer graphics DLL can provide a DrvDrawEscape function.
A printer graphics DLL can provide a DrvEscape function if it is necessary to support drawing or non-drawing operations that are not available through GDI functions. For example, the Microsoft Postscript printer driver uses escapes to support Postscript injection points. Or, an application might need to obtain a fax machine's phone number. The DrvEscape function is also used for indicating the operations supported by the DrvDrawEscape function.
CreateDC, ResetDC, and DeleteDC are described in the Platform SDK documentation.