[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Cairo based backend

From: Jonas Hahnfeld
Subject: Re: Cairo based backend
Date: Thu, 08 Jul 2021 18:09:12 +0200
User-agent: Evolution 3.40.2

Am Donnerstag, dem 08.07.2021 um 12:44 +0200 schrieb Knut Petersen:
> On 07.07.21 20:41, Jonas Hahnfeld wrote:
> > Am Mittwoch, dem 07.07.2021 um 19:42 +0200 schrieb Knut Petersen:
> >  
> > > 
> > > The cairo pdf support is old, but pdf hyperlink support
> > > unfortunately
> > > requires at least cairo 1.16.
> > Oh wow 😲 Ok, that's indeed a reason to go with at least 1.16. Which
> > is
> > fine for an optional requirement, just means that making it a hard
> > dependency will end support for some platforms.
> I think this set of rules should be acceptable:
>  * No cairo-devel: Disable cairo backend code and print a message
> during autoconf
>  * cairo-devel >=1.2 <1.16: build cairo backend without support for
> hyperlinks and pdf metadata
>  * cairo-devel >= 1.16.0: build cairo backend
> Even without the pdf hyperlinks and pdf metadata the backend could be
> of a real value if the target system does not have ghostscript 9.53+
> and rgbA colours are used. And  users should be able to test the code,
> especially it is important to know if font handling on different
> systems works as expected.

Up to your judgement, I don't really know which of the features
introduced with Cairo 1.16 are critical for LilyPond users. I still
think an explicit configure option would have some benefit (at least
for the very beginning)...

> >  
> > >  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.
> > ... or hope that we don't use GUB anymore by that time...
> Propose a less terrible solution ;-)

I hope that this is less terrible and much superior because it gives
64-bit binaries for both Windows and macOS while not dealing with all
the awkwardness of cross-compilation. But I don't want to digress this
thread, just mention that "by that time" (the Cairo backend has a
chance of becoming the default) there could be something else.

> BTW:
> Do I understand it correctly that at we have docker images
> of ubuntu 16.04, ubuntu 18.04 and ubuntu 18.04 with guile 2 for the
> automatic/manual tests, but that those tests do not include building
> with gub but only building within the native ubuntu environments? 

Yes, no automatic GUB build for each push, that would be very time-
intensive. Ubuntu 16.04 is only used for stable/2.22, Ubuntu 18.04 for
master and the jobs for Guile 2 are manual, ie you have to start them.

> >  
> > >  
> > >  
> > >  
> > > > 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.
> > Hm, ok... FYI there is png_set_error_fn which looks much nicer than
> > those long jumps.
> Yes, I'll change that. Although there should be no problem with the
> default longjmp solution as we do not use any local variables after the
> longjmp.
> > No, we're in the post-C++11 era, there are range-based loops!
> > Ok, so as far as I understand, you have one surface / context per
> > output format, right? 
> The cairo backend uses one surface/context per output file. That means
> for those formats that generate multiple files (png, svg) a new
> surface/context pair is created for every new page. Of course after the
> old surface/context pair has been killed.
> Using sets seemed to be an elegant c++ solution to me, but it's clear
> that those high level constructs are probably slower than traditional c
> constructs. I have to admit that I use guile and c++ only because they
> are the programming languages that are used in lilypond. I have never
> looked at range based loops before, but I'll do that now. Do you think
> using them would lead to faster, more elegant or more readable code?

Range-based for loops are more elegant and more readable, because they
are shorter. I don't think they're faster, the compiler will optimize
both forms to the same operations.

But actually, I think the proper solution here are "Recording Surfaces"
that sound like they are *made* for this kind of task:
-> The backend would have one recording surface that are replayed onto
N output surfaces for the different formats.

> > std::set (and even std::unordered_set) is the
> > wrong data structure for this kind of task, but as I said before I
> > would focus on PDF output for now and then the first patch doesn't
> > need
> > to bother.
> Well, postscript via cairo is only very few lines of code. svg via
> cairo succeeds for those files in our regression test selection that
> fail to compile with the traditional svg backend. The png code
> provides, besides the png files, the recipe how someone else can add
> more formats very easily in the future. Using the cairo png toy would
> also entail an indirect dependency on libpng. And to keep the whole
> thing small I already refrained from including the direct output of
> x264 videos anyway ;-)

Yes, and my proposal is to make the first step minimal, the patch will
be large enough by itself. But by having only one output format, you
don't need to bother with the additional complexities in the beginning.
Then other formats should be added incrementally, with a proper
dispatching mechanism. See above for what could facilitate this task:
1. Add (experimental) Cairo backend to produce PDFs; review and merge.
2. Refactor backend to include dispatching mechanism; might be as
simple as swapping the surface type.
3. Add as many useful backends (PS, PNG, SVG) as you want; not sure
about x264 video output...

> > 
> >  
> > > 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 in a way that only
> > > framework-
> > > cairo.scm code would be able to execute it?
> > No, AFAICT functions defined in C are currently added to the (lily)
> > module, which is basically available everywhere.
> There are functions like 'scm_c_module_define' in the guile library
> ... maybe I should have a look at those.

That function sets a *variable* in a module. The one to register
routines is scm_c_define_gsubr.


> Knut

Attachment: signature.asc
Description: This is a digitally signed message part

reply via email to

[Prev in Thread] Current Thread [Next in Thread]