Sunday, April 6, 2008

GDI+ Windows rendering API

Microsoft GDI+ is a part of Windows XP/Server 2003 operating system that provides 2D vector-based graphics, imaging and typography. GDI+ is an improved version of the old GDI (Graphics Device Interface), which is part of previous Windows versions. The GDI+ API programming model has been revised to make graphics programming easier and more flexible. If you want to read more about the GDI+ painting, please read this article: GDI+ painting basics.


Both are doing the same thing. Both are intermediate layers between the Windows application and the rendering hardware (which can be the video adapter or the printer). So let’s see what are the differences.

What is GDI API

GDI is a low-middle level of programming API, where you need to know about devices too. GDI uses the concept of Device Context (DC). Each rendered window has an associated device context. If you want to draw something on a window you have to get a reference to its context menu by calling the SelectObject() method. Once selected, all the drawing on that context menu is done using pens, brushes and any combination of drawing methods.

GDI API uses a stateful model. This means that once a state is set it will be used until it is changed again. For example, if a pen of red color is set all the following drawing methods will use that pen. Changing states is an expensive task, so once you set a red pen you have to draw all the red elements before switch to a blue pen. This is a good tip to optimize your rendering performance. The printer and the video adapter are using the stateful model too. This makes GDI to be a hardware-friendly API, like DirectX API which is also using the stateful model.

Microsoft Foundation Classes (MFC) from the old Visual C++ is based on GDI and is not a pretty API to work with. I hate it!

What is GDI+ API

GDI+ is a high level of programming model, which provides functions to do work for you. GDI+ is based on the old GDI so it will do GDI calls for low-level tasks. GDI+ works with graphics context (the Graphics class) that plays a similar role as device context. The graphics context is also associated with a particular window and contains information specifying how a drawing would be displayed. However, unlike device context, it does not contain information about pen, brush, font, etc. You can get an instance to a Graphics instance by calling the Control.CreateGraphics() method, handle the Paint event thru PaintEventArgs or overriding OnPaint() method of targeted control or windows form.

GDI+ API uses a stateless model. In order to draw with a new pen we simply have to pass an object of Pen class to the DrawLine() method (this method draws a line on window). We can pass different Pen objects in each call to DrawLine() method to draw the lines in different colors. GDI+ is doing all the optimizations to make full use of the hardware stateful model.

All .NET applications are using the GDI+ as the default rendering API but GDI+ is not built into .NET. Instead, .NET wraps the functions in unmanaged libraries (including gdiplus.dll and gdi32.dll). Beside the fact that GDI+ API is easier and more flexible than GDI, there are many more new features added to the API like: alpha-blending, gradient brushes, transformations and subpixel antialiasing. Anyway, GDI+ doesn’t expose all the functionality of GDI, which means you need to fall back on unmanaged calls if you need to perform tasks like overwriting arbitrary areas of the screen.

Overall, GDI+ is a little bit slower than the old GDI but provides better rendering quality and clean code. The GDI+ dynamic library can be shipped with an application and used under older versions of Windows.

GDI+ API capabilities

Let's see what the GDI+ API can really do for us to improve the Windows rendering.
  • 2D vector graphics. Vector graphics is based on graphic primitives like: lines, curves and shapes, all defined as a set of points on a coordinates system. Everything is relative regarding the origin of the coordinate system. Considering this, vector-based graphics can be scaled without losing details, which is a good thing, but rendering vector-based graphics demands a lot of CPU calculation.
  • Imaging. GDI+ can handle different types of bitmaps, including icons, PNG and JPEG formats and perform different image operations like: stretching and skewing.
  • Typography. Typography is responsible for manipulating fonts and anything related to them: sizes, styles, decoration. One of the new features in GDI+ is subpixel antialiasing, which gives text rendered on an LCD screen a smoother appearance.

GDI+ API Namespaces

GDI+ API is based on 40 classes, 50 enumerations, and 6 structures, all written in C++ (unmanaged code) and grouped into five namespaces:
  • System.Drawing. Provides the basic GDI+ graphics functionality, including the Graphics class you use to perform all your painting, and definitions for basic types like the Point, Rectangle, Color, Font, Pen, Brush, and Bitmap
  • System.Drawing.Drawing2D. Provides classes for more advanced two-dimensional painting, including types for blending, patterns, and gradients, the GraphicsPath, and enumerations that let you set the quality level of your rendering
  • System.Drawing.Imaging. Provides classes for manipulating bitmap and vector images
  • System.Drawing.Text. A small namespace that includes classes that let you access the currently installed fonts
  • System.Drawing.Printing. Provides types for rendering GDI+ content to the printer, including the PrintDocument class that represents an in-memory document you plan to print and the PrinterSettings class that exposes printer settings

kick it on

1 comment:

Christian said...

If you you wanna make your life easier you can have a look at the Drawing Board open source component at: . It is a 2D vector graphic editor assembly. It manages simple graphic objects like rectangles, lines and ellipses, other than images and RTF text. It shows most of the capabilities of GDI+, such as color transparency, pen style, start/end line cap and so on.