GDI+
gdiplus.dll is a graphical library introduced in ~2001 by Microsoft to make two-dimensional drawing easier. It runs on top of gdi32, and besides the changes in the programming model it also adds new features such as gradient fills, anti-aliasing, more extensive image handling, etc. There are two main components of GDI+: a flat C API where the main implementation rests, and C++ wrappers that reside in the (numerous) public headers associated with GDI+. As the latter are public and built into programs compiled on Windows, Wine's gdiplus focuses on the flat API.
Microsoft's GDI+ uses mostly gdi32 blt operations to copy its rendering results onto the destination device context whereas Wine's GDI+ (written summer 2007 by Evan Stade) passes calls through to their gdi32 equivalents. The latter approach has better performance and shorter development time, but sacrifices control over finer details.
TODO
Graphics
Saving and restoring of graphics state, GdipSaveGraphics()/GdipRestoreGraphics(). This is similar to SaveDC()/RestoreDC() of gdi32 but should be significantly easier as there is less state associated with a GpGraphics object than a DC. Also, there are already some good tests in the Wine tree to show how Windows does this.
- Drawing modes. This includes compositing mode, smoothing mode, etc. These modes are not easily implemented within the current Wine GDI+ paradigm, which is to let gdi32 do all the work, and AFAIK would require GDI+ taking rendering into its own hands and blt-ing the results, which is something we want to avoid (see introduction). These modes make gdiplus prettier but their absence generally doesn't break any programs, so this is a low priority.
Alpha-channel drawing. Currently all colors are flattened to opacity. The only way I see around this (besides GDI+ doing its own rendering, again) is to draw on a separate DC and then AlphaBlend (gdi32 call) that result onto the DC you actually care about. This is probably more important than some of the drawing modes listed above, as the difference between 50% transparency and opacity is the difference between seeing an entire portion of the display, but I'm not sure how much of a slowdown you would get from using the above technique, or if it would even work the way I'd expect it to.
Brushes
- Gradient brushes (both line and path). Currently they are just implemented as solid fills, where the color for the fill is the start-color of the gradient fill. A possible, easy improvement would be to use an average of the start and end colors as the solid color. I've noticed some gradient fills that go from the background color (usually white) to another color. Currently they are drawn as the background color, thus they do not show up at all. One way to fix this would be to create a bitmap of the gradient fill and then use that bitmap as a gdi32 pattern brush. Creating the bitmap would consist of a creating a DIB and drawing on it with gdi32 functions. I've tested this and compared it to native GDI+ line gradients, and it works almost perfectly from an appearance standpoint. However this would take a lot of memory. (Think of a gradient fill where the start and end points are n pixels apart. The bitmap would be O(n^2) pixels.)
- All brushes besides solid and texture (that latter equivalent to gdi32 pattern brush).
Strings
String drawing. See String Format Functions and Wine's GdipDrawString()/GdipMeasureString(). Most formatting options are currently ignored.
Images
- Image rendering, and especially metafile handling (WMF, EMF, EMF+) are not really implemented. Currently there is a quick-and-dirty implementation in place with many stub functions and dependence on OLEPicture for rendering. Given all the image formats and operations that GDI+ supports, this would be a substantial project on its own.
General
- Startup/shutdown functions. These are currently stubs. I'm not even sure what their purpose is in Windows; Wine's implementation doesn't need them.
Object locking. (see ObjectBusy error code)
- Unimplemented objects and functions. These are numerous.
Related DLLs
Helpful Links
Jose Roca's GDI+ documentation is an invaluable resource and much easier to use than MSDN.
The Mono project's GDI+ uses Cairo as a backend. Looking at their code can sometimes be better documentation than anything else on the web, although the details (like parameter checking) don't always precisely conform to Windows.
