lilypond-devel
[Top][All Lists]
Advanced

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

Re: setting the number of pages for a score


From: Joe Neeman
Subject: Re: setting the number of pages for a score
Date: Fri, 10 Feb 2006 13:06:17 +1100
User-agent: Mozilla Thunderbird 1.0.7 (X11/20051121)

Han-Wen Nienhuys wrote:

I don't understand; how do you use line breaking in the page-breaker? Within the current architecture, the vertical formatting step is non reversible, so you can't really figure out the height of one line-break configuration (which requires vertical formatting), and then try with another set of line-breaks.

My current code involves having Grob::fixup_refpoint and Grob::handle_broken_dependencies store their previous state. I added Grob::undo_fixup_refpoint, Grob::undo_broken_dependencies and Grob::undo_break_processing to revert to the previous state. Something is going wrong though -- it's either a problem with my implementation or it's something happening in scheme callbacks that I haven't traced yet. After 5 or 6 re-line-breaks, object_alist_'s start to disappear and I get systems with empty extent.

There's probably also some caching happening with the Y-extent callbacks, but I'm not up to the point of worrying about that yet.

Doing that would require some copy-on-write mechanism, so can you store the pre-line-break state of the formatting problem and run the line-breaking/formatting-step in on a copy. That's sort of hairy, although it should be doable: all state is maintained as Scheme alists. It's a matter of copying each grob, and doing a global pointer subsititution. Of course, there will be some details, and the copy-on-write would have to function across \score boundaries, since a page may have multiple \scores.

Do you think it's actually necessary to copy the C++ grobs, or would it be sufficient to capture the scheme state? I only ever need to undo one level, so I didn't think capturing the scheme state would be too hard.

Let A_{k,n} = (a_{k,n,1}, ... a_{k,n,k}) be the optimal set of line breaks for k systems and n potential breakpoints. a_{k,n,k} = n (it is the end of
   the piece)

   Then A_{k+1, m} is contructed from
                        min_ {k <= j < m} ( W(A_{k,j} :: m) )
   where by A::m we denote appending m to the list A


OK, I think I get this, but I would expect j to run from k + 1, upwards as the number of breakpoints is always at least one more than the number of systems.

Yes. I guess I didn't count break[0] as a potential breakpoint since it's the beginning of the piece... or something. Indices confuse me ;)

The code looks good, I'm actually surprised at how simple it is!

I expect that a full optimal page layout module is still far away, but we could roll out constrained line breaking relatively easily. For a lot of music, specifying a system count will make it easy to force a piece onto a number of pages, with a few well-placed \pageBreaks. Much easier than it is now anyway. What do you think?

Yes, I think that might be possible without too much work. Maybe we could allow the user to specify a global page-break-system-extent. We then do the page breaking assuming all music systems have that Y-extent. For 95% of the music I would use this for, that would be acceptable since Y-extents don't vary too much. I think the main problem would be if there are sections with more or less staves than other sections. But this could work in the meantime.

I had started to write my page breaker in C++ because I thought it would be slow. But maybe with this simplified version, it would be much easier to write it in scheme ... so should I add scheme bindings to the line breaker?

...which reminds me: in order to allow line breaking to happen after the number of systems is decided, I attach a patch that will delay Gourlay_breaking until/unless ly:paper-book-systems is called.

Joe
Index: lily/paper-score.cc
===================================================================
RCS file: /sources/lilypond/lilypond/lily/paper-score.cc,v
retrieving revision 1.95
diff -r1.95 paper-score.cc
31c31
<   paper_systems_ = SCM_EOL;
---
>   paper_systems_ = SCM_BOOL_F;
94,98d93
< 
<   std::vector<Column_x_positions> breaking = calc_breaking ();
<   system_->break_into_pieces (breaking);
< 
<   paper_systems_ = system_->get_paper_systems ();
114c109
< Paper_score::get_paper_systems () const
---
> Paper_score::get_paper_systems ()
115a111,116
>   if (scm_is_bool (paper_systems_))
>     {
>       std::vector<Column_x_positions> breaking = calc_breaking ();
>       system_->break_into_pieces (breaking);
>       paper_systems_ = system_->get_paper_systems ();
>     }
Index: lily/include/paper-score.hh
===================================================================
RCS file: /sources/lilypond/lilypond/lily/include/paper-score.hh,v
retrieving revision 1.38
diff -r1.38 paper-score.hh
33c33
<   SCM get_paper_systems () const;
---
>   SCM get_paper_systems ();

reply via email to

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