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 - [EMAIL PROTECTED] - http://www.xs4all.nl/~hanwen
LilyPond Software Design
-- Code for Music Notation
http://www.lilypond-design.com
_______________________________________________
lilypond-devel mailing list
lilypond-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/lilypond-devel