Windows 3.11 GDI Vector Graphics Processing

In Microsoft Windows 3.11, vector graphics were processed through the Graphics Device Interface (GDI), a core 16-bit system component that abstracted graphical hardware. Windows 3.11 did not handle vector graphics as modern scalable files like SVGs, but rather as programmatic 2D geometric primitives including lines, polylines, arcs, and polygons. Through a pipeline of mathematical definitions, logical coordinate mapping, clipping checks, and hardware driver dispatching, GDI converted high-level drawing commands into physical pixels on raster displays.

The Role of the Device Context

At the center of GDI vector drawing is the Device Context (DC). When an application needs to draw, it requests a DC handle (HDC) from GDI.EXE using functions like BeginPaint or GetDC. The DC acts as a state machine storing drawing attributes, including:

  • The Active Pen (HPEN): Defines the color, width, and style (solid, dashed, dotted) for drawing vector outlines.
  • The Active Brush (HBRUSH): Defines the fill pattern or solid color for enclosed primitives.
  • The Drawing Mode (ROP2): Defines binary raster operations (such as R2_COPYPEN or R2_XORPEN) that dictate how pen pixels combine with existing screen pixels.
  • Mapping Modes: Dictate how logical units translate into physical pixels (e.g., MM_TEXT for 1:1 pixel mapping, or metric modes like MM_LOMETRIC and MM_TWIPS).

Coordinate Translation and Mapping

Applications defined vector primitives using logical coordinates. When a function like LineTo(hDC, x, y) or Polygon(hDC, lpPoints, nCount) was called, GDI first converted these logical points into device coordinates.

In Windows 3.11, the coordinate space was constrained to signed 16-bit integers (-32,768 to 32,767). GDI calculated the final device coordinate using the window origin, viewport origin, and scale factors configured in the DC.

Clipping and Region Validation

Before any primitive could be rasterized, GDI calculated clipping regions. Windows 3.11 used a cooperative multitasking, overlapping window system where drawing operations had to be strictly confined to an application’s visible client area.

GDI intersected the vector boundaries with the window’s update region and visible region. Any portion of a line, curve, or polygon that fell outside these boundaries was mathematically clipped, preventing writes to memory belonging to other windows or the system desktop.

Rasterization Algorithms

Once coordinates were mapped and clipped, GDI or the display driver translated the continuous mathematical shapes into discrete pixels:

  • Lines and Curves: Straight lines were typically calculated using variations of Bresenham's line algorithm. Ellipses and arcs used midpoint circle/ellipse algorithms, plotting symmetrical quadrants or octants simultaneously.
  • Polygons and Fills: Complex shapes were handled using scanline conversion. GDI determined the edge intersections for each horizontal scanline across the polygon's vertical span, sorted the intersections from left to right, and filled the intervening spans using either an Alternate (odd/even) or Winding rule, depending on the active polygon fill mode.
  • Pen Styles: If a line was styled (such as dashed), GDI tracked a pattern counter along the Bresenham path, toggling pixel writes on and off according to the pen definition.

Driver Interaction and Display Output

Windows 3.11 achieved device independence through display drivers (.DRV files). When processing a vector primitive, GDI evaluated the hardware capabilities exported by the driver:

  1. Driver Acceleration: If the video driver supported hardware execution of a primitive (such as hardware-accelerated line drawing or solid fills supported by high-end graphics chips of the era), GDI passed the transformed coordinates directly to the driver's exported drawing functions.
  2. GDI Fallback Engine: If the video adapter was basic (like standard VGA), GDI's internal software rasterization engine calculated the individual pixel addresses and wrote the output directly to the display memory frame buffer using the active raster operation.

Once the rasterization was completed, the GDI function returned execution control to the application, releasing any temporary rendering structures from the 16-bit GDI local heap.