Portable Cairo GC for SWT

July 19, 2008 – 4:18 am

For several years I have been impressed with the work Romain Guy did to popularize some of the advanced graphic capabilities of Swing. It was his post on transparent windows on Mac OS that pointed me in the direction of the JNA API which I ended up using to prototype support for the Mac OS unified toolbar with SWT.

Some of his early experimentations with AlphaComposite drew my attention to how poor the SWT API actually was in the arena of advanced graphics. At the time, most of my time was spent inside the linux Kernel or in server based Java applications, so I wasn’t overly bothered by it.

In the last two years, I gradually shifted my focus back to client side applications, as part of a rather large modeling and simulation project. Being the architect for the project, I had to make a decision about which technology to use for the dashboard module (a GUI application that controls distributed simulation environments). Considering the heavy investment in OSGi for the distributed server architecture, I decided to use SWT/JFace.

Spending again a great deal of time in and around SWT, I was again stumped by some of its shortcomings and the lack of interest from the SWT team (don’t get me going on this one) to fill some blatant gaps when compared with Swing. The absence of support for Porter-Duff composition in SWT, despite support by all the major GUI platforms once again hit me in the face.

Having seen the power of this simple abstraction in the Swing world, I quickly added support for Composition to the current GC definition.

public interface Composition {
    public CompositionContext createContext(PaletteData srcColorModel,
            PaletteData dstColorModel,
            int hints);

    public void dispose();
}
public abstract class CompositionContext extends Resource {
    CompositionContext(Device device) {
        this.device = device;
    }
    public abstract void compose(ImageData src,
                                            ImageData dstIn,
                                            ImageData dstOut);
    public abstract void dispose();
}

With this as a starting point, it was easy to create an AlphaComposition implementation based on the Carbon API. The problem with SWT is that any change made to it must be created for all supported platforms in order to have a chance to be accepted by the team (S. Northover reminds me as a very strict father watching very closely over the fate of his prodigal sun…). To avoid have to build n different implementations, I decided to explore the possibility of building a portable GC implementation based on Cairo. So a couple weeks ago I started chipping away at the Linux GC implementation.

The first thing I built was a new version of the AlphaComposition, this time taking advantage of Cairo, rather than using Quartz directly. I also quickly added support for radial gradients (the current SWT Pattern implementation only support linear gradients), as this early screen capture shows.

The GC is implemented in two parts: the portable GC itself which contains code that relies only on Cairo, and a driver that bridges with the platform for code that cannot be portable (for example, the instantiation of a Cairo surface, or the translation of the clipping area from Cairo to platform coordinates). As I work on a Mac Book Pro, the first of these drivers is for Mac OS.

At this point, I am able to run most of the GraphicsExample application (I will replace this Windows screenshot with an equivalent Cairo/Mac OS version). I still have some bugs in the region handling code and clipping (Path and Region) is not working. Working on the source code, I was wondering about performance: considering that there might be less JNI calls involved in performing some actions (one Cairo call being implemented by multiple Quartz calls), I am curious to see if that translates in an actually faster GC than the current Carbon based one.
Read the following article for more information on Porter-Duff compositing.
Enter this code
  1. 2 Responses to “Portable Cairo GC for SWT”

  2. This looks really interesting. What I’d love to see is a cross platform widget in SWT that uses Cairo to provide a Graphics2D implementation for drawing on the widget’s surface. Then it would be trivial to get third party libraries that rely on Java2D (for example, JFreeChart) working nicely in SWT.

    Right now in JFreeChart, we have some experimental code to support SWT, but the SWTGraphics2D implementation is backed directly by SWT’s GC, so the implementation is partial. I’ll be keeping an eye on the improvements you are making.

    Regards,

    Dave Gilbert
    JFreeChart Project Leader

    By dgilbert on Jul 22, 2008

  3. I have been following your work on JFreeChart, and saw what you and other people have done to have a Graphics2D in SWT. I never thought about it, but this is a really great idea. I actually do have some parts towards that goal, as I am building a widget for which I build a couple of libraries that needed some of the things you find in Graphics2D. Rather than create my own API, I basically implemented the Java2D api for Paint and Composites. I’ll have to think about that one.

    By laurent on Jul 22, 2008

You must be logged in to post a comment.