[ Most of this is generic Cairo stuff, but I also refer quite a bit to GTK+ in this mail because that's the use case I'm thinking about ] I spent most of today looking at Cairo on win32; didn't actually write any code for Cairo/Win32, but did a fair bit of experimentation with build environments and GDI+. There are basically four approaches we could take to implementing Cairo on Windows. 1. Implement it mostly as images on top of GDI. There are a few things we can use GDI for ... over alpha blending of images, solid fills, and (Over) text, but we'd mostly have a software only implementation. Because so much has to be done in software, we'd likely want to use DIB's for offscreen surfaces, so even the GDI based operations would be in software. Being mostly in software doesn't mean horribly slow, though performance on older machines won't be wonderful. (Note that with the GTK+ Windows theme engine, a lot of the drawing will be done native and not go through Cairo.) 2. Implement it on top of GDI+. The GDI+ model is somewhat richer than the GDI model... it adds antialiased primitives, and "Over" compositing of those primitives, though considerable amounts of the Cairo API would have to be done manually. Clips are bilevel in GDI+, and compositing is only "Over". It's not clear how you would do something like draw an image clipped by an antialiased mask; quite possibly it just isn't possible. So, like the GDI backend, the GDI+ backend would have to be able to fall back to software in almost any place. The early trapezoidization in Cairo might pose problems for this backend ... it's not clear that taking a path, converting it to a set of trapezoids, converting it back to a path, then rasterizing however GDI+ does internally is going to be especially efficient. Perhaps the biggest advantage of using GDI+ over GDI is that for the subset of uses that can be fully reprented within the GDI+ model, Windows would be able to do an optimal printing. Fallbacks for screen display are straightforward; when an operation is encountered that can't be handled by GDI+, we just need to get the pixels from the destination, draw, and put back. Much like we do for xlib currently. If we use DIB's for GdkPixmap when appropriate (always?) then efficiency should be OK. Fallbacks for printers are harder, much as has been discussed earlier for PS output. I think a metafile based approach is right; record the drawing operations for a page keeping track of what areas will need fallbacks, and when the page is shown, redo the drawing based on what was calculated earlier. There are some build issues with using GDI+ ... GDI+ is not yet part of the basic API supported by mingw, and while I was able to get GDI examples to build with the GDI+ headers from the Win32 Platform/SDK with a little work, the platform/SDK is a huge download to require. (Though only needed for people building from source.) There's an incomplete patch that was posted to the mingw list for adding it, but that's a long ways from working, and a clean room reimplementation of the GDI+ wrapper classes looks conceptually hard to do. Perhaps the best approach would be to use the "flat" C API, while that's not supported by Microsoft, the API is locked since the C++ API is just a set of header files around it. There is no C++ code actually in the DLL. Redoing the header files for the flat API should be pretty easy. Finally, GDI+ is not natively present on Windows98, Windows/ME or Win2k. There's a redistributable version of the DLL that it *might* be possible to bundle into an downloadable installer if you put an extra click-through screen ahead of it. 3. Implement it on top of OpenGL. OpenGL is a much closer fit to hardware capabilities than GDI+, and so there is a better chance of hardware acceleration. There's a good start on this with glitz, and I believe Tor even did an initial port of that work to WGL. But there are considerable difficulties with OpenGL. OpenGL drivers are somewhat second-class citizens on Windows, and even two good drivers may not render everything the same. Many different levels of support (no shaders? old fragment programs? New high-level shading language? How many texture units?) have to be handled. Most OpenGL is used in a single isolated context on the screen or even full-screen. It's not clear that drivers (especially for low-end hardware) are going to do good things if GTK+ started using OpenGL for drawing every menu. Another thing to consider is that since we are doing widget drawing through the WinXP theme API when drawing in GTK+, we are going to be mixing GL with GDI, which could be a problem. Text is difficult. Exactly consistency with text drawn through the GDI is needed. The simple approach is to draw text into a DIB white-on-black, copy that into a texture, and use it as a mask. But that means that the most time-critical drawing operation of all is the least accelerated. And printing isn't handled at all. An OpenGL backend would have to be augmented with a GDI or GDI+ backend for printing. 4. Implement it on top of Direct3D. This has most of the same advantages as OpenGL with some extra benefits: Direct3D is (if I recall correctly) how Microsoft is accelerating Longhorn 2D drawing, Direct3D drivers are almost always better than OpenGL drivers on Windows, and the API is probably better suited to our purpose to begin with ... lower level and less abstract. But it also has some of the disadvantages as OpenGL. Consistency of rendering may be a problem, some drivers may not like Direct3D being used on all windows, text is hard, and printing is not there at all. Direct3D does have some convenience functions for drawing text, but they don't look up to handling the full set of Uniscribe output that we'll be dealing with. If I had to take a guess at the right direction, it's to go on top of GDI+ for now (with heavy image fallbacks), and look at writing a Direct3D backend later.
Attachment:
signature.asc
Description: This is a digitally signed message part