[Top][All Lists]

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

Re: Getting the height of a system.

From: Han-Wen Nienhuys
Subject: Re: Getting the height of a system.
Date: Sun, 14 May 2006 12:40:42 +0200
User-agent: Thunderbird 1.5 (X11/20060313)

Joe Neeman schreef:
We discussed this a bit a long time ago but I'm getting close to actually implementing something so I thought I'd bring it up again.

Getting the Y-extent of a system is potentially destructive, causing all sorts of non-undoable caching and possibly suiciding of grobs. So I need to do make a copy of the system before I can get its Y-extent.

The problem is that there are a large number of possible lines in a score. To copy a system, I need to do a full grob substitution for every grob in that system. If each bar could be in up to N possible lines, I need to do N full copies of the entire score and N full grob substitutions in the object_alist_. If we can fit up to K bars to a line then N is approximately K(K-1)/2. In the scores I typically work with, N would be around 50-60 so this is getting pretty expensive.

It's much worse than that, because the cost of the substitution is actually proportional to the number grobs in the "long" System, i.e. the length of the entire score. It would be much much better if you could make your algorithm compute the system heights of a complete line breaking configuration.

Also, it's not completely possible to compute the height of an isolated system: some grobs (notably spanners like slur) look at the next system to decide how to format across line breaks.

So I propose the following instead. I don't know a great deal (yet) about the C++ internals of grobs so I'd appreciate knowing if this is unworkable before I spend lots of time trying to implement it.

1) add a virtual Grob *save () and virtual void restore (Grob*) function to every C++ Grob subclass. save() would be a bit like clone except that it copies the object_alist_ and, for example, broken_intos_ in the case of a Spanner.
Grob *copy = me->save ();
// make some changes to me
me->restore (copy);
and you end up with the same grob you started with.

2) save every grob in the score

3) for each possible system, using the original grobs,
        - work out the Y-extent
        - restore () every grob in that system

The advantage is that we avoid fiddling around with the object_alist_ because this clone is never used -- it exists only to save the state of the score before we mess it up with calling Y-extent. We also only have to make one copy of the system and restore it N times instead of making N copies.

Sounds like a possiblity, but have you also considered break alignments? It's not only the object_alist_ (and property_alist_, as that too will change), but also other pointers like original_.

Secondly, although it will be nicely portable, it also sounds like a lot of work. Isn't it a lot easier to simply do a fork() and let the OS clean up after us? Perhaps if the vertical spacing is completely working, we can consider doing the full-blown copy and restore. Also, for large scores, fork() is an interesting option, as we could get some benefit from using SMP.


Han-Wen Nienhuys - address@hidden -

LilyPond Software Design
 -- Code for Music Notation

reply via email to

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