Skip to content
PrinterArchive

Guides · Intermediate

Windows GDI Printing

Windows GDI printing is the classic Microsoft Windows print path, in which an application draws to a printer device context using the same device-independent Graphics Device Interface (GDI) it uses for the screen. Windows routes the drawing operations through the graphics engine, records them in Enhanced Metafile (EMF) spool files by default, then plays them back through a GDI-based printer driver that converts them into device-specific data such as PCL or PostScript. The spooler, print processor, language monitors, and port monitors carry the resulting stream to the hardware. Microsoft now documents this path as legacy, preferring the IPP inbox class driver with Print Support Apps for new development on Windows 10 and 11.

By PrinterArchive EditorialEdited by PrinterArchive Editorial

Overview

Windows GDI printing is the classic Microsoft Windows print path, in which an application produces printed output using the Graphics Device Interface (GDI) — the same device-independent drawing API it uses to draw to the screen. Instead of a screen device context, the application draws to a printer device context (DC), and Windows routes the resulting drawing operations through the graphics engine, the print spooler, a GDI-based printer driver, and a port monitor to the hardware.

Microsoft's documentation calls this the GDI print path (also the Win32 print path), one of two primary print paths in Windows; the other is the XPS print path, which originates in Windows Presentation Foundation (WPF) applications or the XPS Print API. The defining trait of the GDI path is device independence: an application issues high-level calls such as TextOut, BitBlt, and LineTo, and the printer driver — not the application — converts them into device-specific commands such as PCL or PostScript.

A central feature of the GDI path is EMF (Enhanced Metafile) spooling. Rather than rendering final device data immediately, GDI can record the application's drawing calls into an EMF spool file, return control to the application quickly, and later replay those records through GDI and the driver on a background spooler thread to produce the device-ready stream.

Microsoft's own documentation now flags this path as legacy: driver-side pages carry a banner stating that the modern print platform — the IPP inbox class driver plus Print Support Apps (PSA) — is the preferred means of communicating with printers in Windows 10 and 11.

History

GDI is one of the original graphics subsystems of Windows and has always presented a device-independent drawing model backed by device-specific drivers. Microsoft's older device-context documentation describes GDI as implemented historically in Gdi.dll, working with a per-device driver DLL; the period examples it gives name Vga.dll for a VGA display and Epson9.dll for an Epson FX-80 printer — illustrating the original design in which each output device supplied its own driver and GDI mediated between the application and that driver.

In the Windows NT line, the graphics subsystem — including GDI and the window manager — resides in the kernel-mode component win32k.sys. Microsoft security bulletins describe win32k.sys as "the kernel part of the Windows subsystem," containing the window manager and "the Graphics Device Interface (GDI), a library of functions for graphics output devices," and acting as a wrapper for DirectX support implemented in another driver (dxgkrnl.sys). The user-mode client library is gdi32.dll, which thunks into the kernel-mode engine.

Successive releases added capabilities to the print path: client-side rendering (Windows Vista, enabled by default), the parallel XPS print path (Windows Vista, via WPF and the .NET Framework), user-mode-only printer graphics DLLs (Windows Vista), and Printer Driver Isolation (Windows 7). Microsoft's documented execution-mode table lists Windows NT 4.0 as the earliest operating system in which graphics DLLs ran in kernel mode. The exact first-release date of GDI is not stated as a single sentence in the primary documentation reviewed and is left unasserted here.

Architecture

The GDI print path is built from cooperating components:

  • GDI / graphics engine (GRE). GDI is both the application-facing API (gdi32.dll) and the kernel-mode graphics rendering engine in win32k.sys. The engine performs device-independent rendering and calls the printer driver for device-specific assistance. Microsoft documentation refers to it variously as the "GDI graphics engine," "GDI rendering engine," and "graphics rendering engine (GRE)."
  • Device context (DC). A DC is a data structure defining a set of graphic objects (pen, brush, bitmap, palette, region, path, font), their attributes, and graphic modes affecting output. Applications obtain a handle (HDC) via CreateDC or GetDC and pass it to GDI drawing functions. A printer DC targets a printer rather than the screen.
  • Device driver interface (DDI). The boundary between GDI and a graphics or printer driver is the DDI. A GDI-based printer driver's rendering component is a printer graphics DLL that exports Drv-prefixed graphics DDI functions. DrvEnableDriver is exported by name (with DrvQueryDriverInfo as an optional export); the addresses of the other supported DDI functions are returned in a table from DrvEnableDriver. These functions are called by the kernel-mode graphics engine. Drivers may call back into GDI via Eng-prefixed support services.
  • Printer driver (rendering + configuration). A driver has a rendering component (converts graphics commands into the printer's data format) and a configuration component (a UI for options plus a programmatic interface reporting capabilities). Microsoft-supplied core drivers include the Universal Printer Driver (Unidrv), which renders to a GDI-managed surface and is driven by GPD (generic printer description) files, and the PostScript Printer Driver (Pscript5), driven by PPD (PostScript printer description) files; PostScript rendering targets a device-managed surface. Vendors extend these via rendering plug-ins and UI plug-ins (COM interfaces such as IPrintOemUI and IPrintOemUni).
  • Print spooler. The spooler manages the print process — locating and loading the driver, spooling drawing calls into a job, scheduling, and dispatching to a monitor. The local print provider and default print processor reside in localspl.dll.
  • Print processor. A user-mode DLL that converts a job's spooled data into a form a print monitor can accept. The default processor localspl.dll accepts input data types EMF, RAW, and TEXT and produces RAW output; the EMF print processor plays EMF records back through GDI.
  • Language and port monitors. A language monitor (for example, Pjlmon.dll for PJL) adds printer job-control commands and provides bidirectional communication. A port monitor (such as the TCP/IP port monitor TCPMON, or WSDMON for Web Services on Devices) directs the stream to the correct port via WritePort/ReadPort. If a language monitor is present, it wraps the port monitor's calls; otherwise the spooler calls the port monitor directly.
  • DEVMODE and print settings. Per-printer and per-document settings (copies, orientation, resolution, tray) travel in a DEVMODE structure; capabilities are queried via DeviceCapabilities and, in later drivers, PrintTicket and PrintCapabilities providers.

How it works

1. The application obtains a printer DC (CreateDC with the driver, device, and port, or via the common Print dialog) and brackets the job with StartDoc and EndDoc, with each page bracketed by StartPage and EndPage. 2. Between those brackets it issues ordinary GDI drawing calls — text, lines, curves, and bitmaps via BitBlt — against the printer DC, exactly as it would draw to the screen. This shared code path is the basis of WYSIWYG: the same GDI calls can render a screen preview and the printed page. 3. GDI and the driver have two options. They can render a printable image immediately and hand a device-ready stream to the spooler, or they can spool as EMF: record the drawing calls as EMF records for later playback. EMF is the default data type. 4. If EMF was spooled, the spooler reads the spool file when the job is scheduled, and the EMF print processor plays the records back to GDI. GDI re-executes them, calling the printer graphics DLL, which renders the image and writes it to the spooler as RAW data (via EngWritePrinter). The converted stream is sent onward without being re-spooled. 5. The processed stream passes to the language monitor (if any), which may inject printer-language commands such as PJL, then to the port monitor, the kernel-mode port driver, and the hardware.

GDI+ (gdiplus.dll) prints through the same mechanism: a Graphics object constructed from a printer HDC issues GDI+ calls between StartDoc and EndDoc, and the output flows through the GDI printer DC.

Data flow

The path data takes through the subsystem is:

  • Application (GDI drawing calls on a printer DC)
  • → GDI / graphics engine
  • → Job creation: the local print provider creates a spool file and data file; the job is recorded as EMF (default) or rendered immediately to RAW
  • → (if EMF, at schedule time) the EMF print processor plays records back → GDI → the printer graphics DLL renders → a RAW stream (written via EngWritePrinter)
  • → the spooler hands the stream to the language monitor (optional; adds PJL or job control) → the port monitor (WritePort)
  • → the kernel-mode port driver (parallel, serial, USB, TCP/IP, or WSD)
  • → the printer hardware

Two related conversions exist within the broader print platform: GDI-to-XPS conversion via the Microsoft XPS Document Converter (MXDC), used when a Win32/GDI application prints to an XPSDrv driver; and XPS-to-GDI conversion (XGC), used when an XPS/WPF application prints to a GDI-based (version 3) driver, in which case the XPS is converted to EMF and sent down the GDI print path.

For a shared printer, EMF records are typically produced by the client's copy of the graphics engine and spooled to a file sent to the server; the server's spooler reads the file, and the server's EMF print processor and graphics engine call the server's printer graphics DLL. Because EMF is device-independent and compact, it can transfer to a server faster than fully rendered RAW data. Windows Vista's client-side rendering shifts rendering to the client by default.

Operating system integration

GDI printing is not a bolt-on subsystem; it reuses the operating system's graphics stack. The same graphics engine in win32k.sys that renders windows also renders print jobs, and the same DDI that display drivers implement is implemented by printer graphics DLLs. Microsoft security documentation confirms that win32k.sys contains the Graphics Device Interface alongside the window manager and wraps DirectX support in dxgkrnl.sys. The user-mode side is gdi32.dll; the spooler service and localspl.dll provide job management, and monitors bridge to kernel-mode port drivers.

Historically the printer graphics DLL could run in kernel mode or user mode. Since Windows Vista, printer graphics DLLs execute only in user mode, and Microsoft recommends that new user-mode drivers call Win32 equivalents where exact equivalents exist — for example, HeapAlloc instead of EngAllocMem, and WritePrinter instead of EngWritePrinter. Later integration features include Vista client-side rendering and Windows 7 Printer Driver Isolation, in which drivers run in a process separate from the spooler.

Relationship to standards

  • Page description and printer languages. GDI output is converted by drivers and monitors into device languages such as PCL (HP Printer Control Language) and PostScript; the RAW data type carries these and other custom types. Pscript5 targets PostScript devices described by PPD files, an Adobe/PostScript convention.
  • Printer job language. Microsoft's Pjlmon.dll language monitor implements PJL for job control and bidirectional status.
  • XPS. The parallel XPS path is a fixed-layout, packaged format; MXDC and XGC convert between GDI/EMF and XPS so each kind of driver can be reached.
  • IPP. The modern print platform Microsoft now recommends is built on the Internet Printing Protocol (IPP) inbox class driver plus Print Support Apps — the going-forward direction away from bespoke GDI and XPS version-3 drivers.
  • Fonts. GDI printing handles TrueType fonts, with driver options to substitute device fonts or download them as softfonts.

EMF itself is a Microsoft-defined metafile format; it is a recording of GDI calls, not a self-contained visual format (see Common misconceptions).

Relationship to technologies

  • GDI+ and Direct2D. GDI+ prints through a GDI printer DC. Direct2D can interoperate with GDI via a DC render target (ID2D1DCRenderTarget::BindDC), letting Direct2D content reach a GDI DC.
  • EMF as an interchange format. EMF records underpin metafile features used elsewhere in Windows, but in printing they are the spool representation.
  • XPS and WPF. WPF applications spool XPS rather than EMF; when the target is a GDI driver, XGC converts the XPS to EMF and reuses the GDI path.
  • WDDM and DirectX. Modern display rendering uses the Windows Display Driver Model (WDDM) and dxgkrnl.sys. Microsoft's WDDM documentation explicitly labels "Win32 GDI and Win32k.sys" as legacy components that some applications still use — signaling GDI's maintenance status on the display side, while it remains the classic print path.

Relationship to manufacturers

The architecture is deliberately vendor-neutral and component-replaceable, so hardware vendors can add support with minimal code. In many cases a new printer requires only new data files — GPD for Unidrv or PPD for Pscript5 — used with a Microsoft-supplied core driver, rather than a full custom driver. Vendors needing custom behavior supply rendering plug-ins and UI plug-ins (COM interfaces) that hook into Unidrv or Pscript5, or historically supplied monolithic GDI drivers. Vendors can also supply custom language monitors, port monitors, and print processors, mixing them with Microsoft-supplied components — for example, a custom language monitor layered over the Microsoft port monitor. Microsoft's documentation names specific vendor devices only as examples (an Epson FX-80 driver, HP PCL, Adobe PostScript and PPD); the design does not privilege any manufacturer.

Modern relevance

GDI printing remains widely supported and in use, but Microsoft now treats it as legacy for new development. Driver-authoring pages recommend the modern print platform — the IPP inbox class driver with Print Support Apps — for customizing the Windows 10 and 11 print experience, rather than writing new GDI (version 3) or XPSDrv drivers. WDDM documentation similarly labels Win32 GDI and win32k.sys as legacy on the display side.

In practice, GDI printing still matters for existing Win32 applications that draw to printer DCs, for the large installed base of GDI, Unidrv, and Pscript5 drivers, for EMF spooling behavior and its pitfalls, and for interoperability where XPS or WPF output is converted to EMF for older drivers.

Common misconceptions

  • "EMF is a finished, device-ready picture." It is not. Per Microsoft, EMF consists of instructions to call GDI functions and represents application output as a series of GDI calls that must be replayed through GDI to render. The printer driver is not involved until the EMF print processor plays the records back.
  • "EMF is always smaller or faster." EMF is device-independent and often compact for vector content, but GDI does not compress raster data in EMF; documents heavy in raster or gradient content can produce very large EMF spool files. Microsoft's documented workaround is to disable EMF spooling ("Print directly to the printer"), which also disables print-processor features such as N-up, watermark, booklet, driver collation, and scale-to-fit.
  • "The application generates PostScript or PCL." In the GDI model the application emits device-independent GDI calls; the driver produces the device language. That separation is the point of device independence.
  • "GDI and GDI+ are the same subsystem." GDI+ is a separate API (gdiplus.dll) with its own object model, but it still prints via a GDI printer DC.
  • "GDI printing and XPS printing are unrelated silos." They are bridged: MXDC converts GDI to XPS and XGC converts XPS to EMF, so each can reach the other kind of driver.
  • "Rendering always happens on the print server." Since Windows Vista, client-side rendering is the default, moving EMF rendering to the client.

Timeline

  1. Mid-1980s–1990s

    GDI established as the device-independent Windows drawing API, mediating between applications and per-device driver DLLs; period Microsoft documentation references Gdi.dll with device drivers such as Vga.dll and a printer driver for the Epson FX-80. (Exact first-release date not asserted here.)

  2. Windows NT 4.0

    Earliest operating system in which graphics DLLs ran in kernel mode, per Microsoft's execution-mode documentation; the graphics subsystem, including GDI and the window manager, resides in the kernel-mode component win32k.sys (as described in Microsoft security bulletins).

  3. Windows 2000 and later

    Documented print-spooler architecture with EMF, RAW, and TEXT data types, the EMF print processor in localspl.dll, and printer graphics DLLs as the GDI-based driver rendering model.

  4. Windows Vista

    XPS print path introduced alongside GDI (via WPF and .NET); client-side rendering enabled by default; printer graphics DLLs restricted to user mode.

  5. Windows 7

    Printer Driver Isolation, allowing drivers to run in a process separate from the spooler.

  6. Windows 10 / 11

    Microsoft designates the modern print platform (IPP inbox class driver plus Print Support Apps) as the preferred path; GDI, and win32k GDI on the display side, treated as legacy.

Frequently asked questions

What is the Windows GDI print path?
It is the classic Windows print path in which an application draws to a printer device context using the same device-independent Graphics Device Interface used for the screen. Windows routes those drawing calls through the graphics engine, spooler, a GDI-based printer driver, and a port monitor to the hardware. Microsoft also calls it the Win32 print path.
What is EMF spooling and why does it matter?
Enhanced Metafile (EMF) spooling records an application's GDI drawing calls into a spool file instead of rendering final device data immediately. This returns control to the application quickly; the EMF print processor later replays the records through GDI and the driver on a spooler thread. EMF is the default spool data type, but GDI does not compress raster data, so raster-heavy documents can produce very large EMF files.
Is Windows GDI printing deprecated?
Microsoft documents it as legacy for new development. Driver-authoring pages recommend the modern print platform - the IPP inbox class driver with Print Support Apps - for Windows 10 and 11 rather than new GDI (version 3) or XPSDrv drivers. GDI printing remains widely supported and in use for existing applications and the large installed base of GDI drivers.
How does GDI printing relate to PostScript and PCL?
In the GDI model the application emits device-independent GDI calls, and the printer driver converts them into a device language such as PostScript or PCL. That separation is the point of device independence; the application does not generate the device language itself. The RAW spool data type carries the resulting device stream.

Source transparency (14 sources)

These references support claims made in this entry. The archive uses verified institutional and public-domain sources only; see Source policy.

Sources consulted (14)

Continue in the archive

Related reading