Hi Jonas
I saw that you opened a merge request (actually, two...),
I managed to screw up my git commands.
The first one is about *how* the backend should be added. In the previous thread, I proposed that it should be optional at first and I meant this to imply that Cairo should not become a required dependency from the beginning. Actually, I think it may be even better to only compile the backend if passing a flag to configure, say --enable-cairo. In particular the requirement on version 1.16 will cut out many active distributions, most importantly Ubuntu 18.04 used in the CI pipelines and representing, more or less, the minimum versions required for LilyPond. (Is there a particular reason for 1.16 or could the code work with older versions? Debian 9 Stretch has 1.14.8 and is supported until next year, but not really required once the backend is optional.)
The cairo pdf support is old, but pdf hyperlink support unfortunately requires at least cairo 1.16. In gub we have old cairo and libpng versions, but it should not be too hard to change the code to work with them. Something like the way we handle ghostscript - to use all lilypond features 9.53+ is required, but we accept the limits of older versions. Nevertheless, we should update cairo in gub.
The code in !837 also depends on libpng to write out images, where the use of setjmp made me frown. It appears that Cairo has a (very simple) API available for writing PNGs, any reason not to use that?
The cairo people call their png support a "toy api" and recommend to use the real library. My code uses libpng because I a) expect feature requests beyond the possibilities of that toy api and b) because I thought it would be a good idea to demonstrate how to add output support for arbitrary formats.
Briefly looking through the code, I find the macros MCRA, MCRB, MSURA, and MSURB very hard to read (no clue what they stand for). I'd have to look into it, but I hope there are nicer ways to write that.
It's just a way to save about 250 lines of code for functions that do nothing than to establish functions that loop over a set of cairo surfaces/contexts instead of writing to only one surface/context. void mcr_cairo_arc(double a, double b, double c, double d, double e) MCRA cairo_arc(*itcrs, a, b, c, d, e); MCRB would normally be written as void mcr_cairo_arc(double a, double b, double c, double d, double e) { itcrs=crs.begin(); while (itcrs != crs.end()) { cairo_arc(*itcrs, a, b, c, d, e); itcrs++; } }
Also the amount of global variables is worrying...
Ok. A c++ programmer is talking to somebody who likes to use assembly language ;-)) More worrying to me is the possibility to directly call the c++ stencil commands from everywhere in guile ... do we have a way of defining the c++ functions in cairo.cc in a way that only framework-cairo.scm code would be able to execute it? Knut