Accessing the cairo api

As far as I know the the ability to easily create arcs is missing from the openfl graphics api. Sure you could probably do that with curveTo, but since we’re now using cairo on native wouldn’t it be easier to implement the arc function? Meanwhile I’m wondering if there’s any straightforward way to access the cairo api on a graphics object?

Nobody want this? Or is openfl determined on not expanding the api?

I believe we use this for ellipse drawing in the API already. Where would you use this, outside the circle, ellipse, curve and cubic curve use cases?

Drawing half circles etc example.
This would be great for UI-elements, indicators, loading bars, health bars without having to do any specific math or sectioning of your circle. Processing has it already.

You could try something like:

var imageBuffer = new ImageBuffer (null, 100, 100, 32, PixelFormat.BGRA32);
var image = new Image (imageBuffer);

var surface = CairoImageSurface.fromImage (image);
var cairo = new Cairo (surface);

// perform cairo draw commands

var bitmapData = BitmapData.fromImage (image);

I think this would work. The basic concept is that you create a Lime ImageBuffer with the size you want. Using BGRA as the color order (rather than the traditional RGBA order) uses the same order that Cairo does – this requires no swizzling after a Cairo command. OpenFL uses this order on native right now for this benefit (and some other reasons).

When you create a buffer, it’s possible to wrap this with a CairoImageSurface, so Cairo commands use (or draw to) this exact data buffer. You can use Cairo or the Lime Image APIs (which is like BitmapData) to manipulate this data.

If you want to use this CairoImageSurface as a drawing source, you might set a cairo.target to it. If it is where you want to draw, then create a new Cairo instance to begin drawing.

If you want to use your Lime Image within OpenFL, BitmapData.fromImage should give you a BitmapData you can use :slight_smile:

You may also be able to use new CairoImageSurface (bitmapData.image) to work from an existing BitmapData, but I’m concerned that may result in problems with dirty flags, though perhaps setting bitmapData.image.dirty = true after you are done would do it

I tried it out but this line:
var surface = CairoImageSurface.fromImage (image);
is giving me a null object reference (Windows debug build). Do I have to activate som flag in the build?

Turns out that just using a plain old BitmapData works just fine and gave me the result I wanted:

var bmd = new BitmapData(200, 200, true, 0);
var surface = CairoImageSurface.fromImage (bmd.image);
var cairo = new Cairo (surface);
    
cairo.lineWidth = 5.0;
cairo.arc(100, 100, 50, 0, Math.PI);
cairo.stroke();
        
var bitmap = new Bitmap(bmd);
addChild(bitmap);
bitmap.x = 100;
bitmap.y = 100;

Works just fine and produces a half-circle on screen as expected.

In motion (the low fps and grey background is from capturing program).

1 Like