Channel IRC # cairo suggested (thanks to the company!) To use cairo_mask () instead of cairo_paint () to draw a gradient. This results in a square instead of linear progression.
I did the following in lua. Sorry for the language, but it's easier to prototype something. This maps 1: 1 to API C and is not difficult to translate:
cairo = require("lgi").cairo s = cairo.ImageSurface(cairo.Format.ARGB32, 200, 100) c = cairo.Context(s) c:set_source_rgb(1, 1, 1) c:paint() p = cairo.Pattern.create_radial(50, 50, 0, 50, 50, 20) p:add_color_stop_rgba(0, 0, 0, 0, 1) p:add_color_stop_rgba(1, 0, 0, 0, 0) c:save() c:rectangle(0, 0, 100, 100) c:clip() c.source = p c:paint() c:restore() p = cairo.Pattern.create_radial(50, 50, 2, 50, 50, 25) p:add_color_stop_rgba(0, 0, 0, 0, 1) p:add_color_stop_rgba(1, 0, 0, 0, 0) c:translate(100, 0) c:save() c:rectangle(0, 0, 100, 100) c:clip() c.source = p c:mask(p) c:restore() s:write_to_png("test.png")
For me, the second circle (the one that was cairo_mask () 'd with a black source) looks a lot bigger than you want:
