Here is my latest patch to add a new page-breaker. This actually adds 2 page breakers now:
ly:page-turn-breaking will only allow page turns at specified places within the score. By default, a page turn can only appear at the end of a score. This can be altered in two ways: 1) by adding \allowPageTurn or \pageTurn in certain places throughout the score 2) by adding Page_turn_engraver to a Staff (or Voice) context. Page_turn_engraver will scan the context for noteheads. Wherever there is a sufficiently long gap in noteheads, a page turn will be permitted. This length is tuned by the context property minPageTurnLength ly:optimal-breaking does not care about page turns. The main advantage over the current page breaker is that it is capable of changing the horizontal spacing so that the vertical spacing is better. If you use this, you probably want to set ragged-last-bottom = ##f. I propose that ly:optimal-breaking be eventually made the default page breaker (I'm sure there are plenty of issues to work out first, though). Both page-breakers can be tuned with the (book-wide) paper block variables "page-spacing-weight" (default 1.0) which specifies the importance of good page spacing relative to line spacing and "blank-last-page-force" (default 0) which specifies the penalty for ending the piece on a left-hand page. ly:page-turn-breaking will also consider leaving blank pages mid-score. The penalty for these pages can be tuned with "blank-page-force" (default 10). The new files are attached in a tar archive (I cc to Han-Wen just in case the list strips it). There are 13 of them, so I thought it would be easier. 2006-07-25 Joe Neeman <[EMAIL PROTECTED]> * scm/page.scm (make-page): make it friendlier to call (esp. from C++) * scm/layout-page-layout.scm (make-page-from-systems): new function (optimal-page-breaks): use the new page-breaking calling convention * scm/define-context-properties.scm (all-user-translation-properties): add revokePageTurns * lily/paper-column-engraver.cc (stop_translation_timestep): add revokePageTurns functionality. If there is a special barline within the breakable region, break there instead of at the end of the region. * lily/paper-book.cc (pages): use the new page-breaking calling convention
page_breaking_newfiles.tar.gz
Description: application/compressed-tar
Index: ChangeLog =================================================================== RCS file: /sources/lilypond/lilypond/ChangeLog,v retrieving revision 1.5202 diff -u -r1.5202 ChangeLog --- ChangeLog 25 Jul 2006 01:16:05 -0000 1.5202 +++ ChangeLog 25 Jul 2006 01:34:03 -0000 @@ -1,5 +1,19 @@ 2006-07-25 Joe Neeman <[EMAIL PROTECTED]> + * scm/page.scm (make-page): make it friendlier to call (esp. from C++) + + * scm/layout-page-layout.scm (make-page-from-systems): new function + (optimal-page-breaks): use the new page-breaking calling convention + + * scm/define-context-properties.scm (all-user-translation-properties): + add revokePageTurns + + * lily/paper-column-engraver.cc (stop_translation_timestep): add + revokePageTurns functionality. If there is a special barline within + the breakable region, break there instead of at the end of the region. + + * lily/paper-book.cc (pages): use the new page-breaking calling convention + * lily/grob.cc: * lily/gourlay-breaking.cc: Oops, these should have been included in my last commit Index: lily/paper-book.cc =================================================================== RCS file: /sources/lilypond/lilypond/lily/paper-book.cc,v retrieving revision 1.132 diff -u -r1.132 paper-book.cc --- lily/paper-book.cc 15 Feb 2006 13:02:17 -0000 1.132 +++ lily/paper-book.cc 25 Jul 2006 01:24:47 -0000 @@ -381,7 +381,7 @@ pages_ = SCM_EOL; SCM proc = paper_->c_variable ("page-breaking"); - pages_ = scm_apply_0 (proc, scm_list_2 (systems (), self_scm ())); + pages_ = scm_apply_0 (proc, scm_list_1(self_scm ())); return pages_; } Index: lily/paper-column-engraver.cc =================================================================== RCS file: /sources/lilypond/lilypond/lily/paper-column-engraver.cc,v retrieving revision 1.19 diff -u -r1.19 paper-column-engraver.cc --- lily/paper-column-engraver.cc 11 Jul 2006 05:58:00 -0000 1.19 +++ lily/paper-column-engraver.cc 25 Jul 2006 01:24:47 -0000 @@ -8,6 +8,7 @@ #include "paper-column-engraver.hh" #include "system.hh" +#include "international.hh" #include "item.hh" #include "paper-column.hh" #include "staff-spacing.hh" @@ -26,9 +27,9 @@ musical_column_ = 0; breaks_ = 0; system_ = 0; - first_ = true; + last_special_barline_column_ = 0; last_breakable_column_ = 0; - last_breakable_moment_ = Moment (-1); + first_ = true; } void @@ -84,6 +85,7 @@ ly_symbol2scm ("spacing-wishes"), gi.grob ()); } + void Paper_column_engraver::acknowledge_note_spacing (Grob_info gi) { @@ -169,6 +171,56 @@ } } +/* return either + - the last column with a special (ie. not "|" or "") barline + - the last column + after the given moment +*/ +Paper_column* +Paper_column_engraver::find_turnable_column (Moment after_this) +{ + if (last_special_barline_column_) + { + Moment m = *unsmob_moment (last_special_barline_column_->get_property ("when")); + if (m >= after_this) + return last_special_barline_column_; + } + if (last_breakable_column_) + { + Moment m = *unsmob_moment (last_breakable_column_->get_property ("when")); + if (m >= after_this) + return last_breakable_column_; + } + return 0; +} + +void +Paper_column_engraver::revoke_page_turns (Moment after_this, Real new_penalty) +{ + if (!page_turnable_columns_.size ()) + return; + + for (vsize i = page_turnable_columns_.size () - 1; i--;) + { + Paper_column *col = page_turnable_columns_[i]; + Moment mom = *unsmob_moment (col->get_property ("when")); + if (mom >= after_this) + { + if (isinf (new_penalty)) + { + col->del_property ( ly_symbol2scm ("page-turn-permission")); + page_turnable_columns_.erase (page_turnable_columns_.begin () + i); + } + else + { + Real prev_pen = robust_scm2double (col->get_property ("page-turn-penalty"), 0); + if (new_penalty > prev_pen) + col->set_property ("page-turn-penalty", scm_from_double (new_penalty)); + } + } + } +} + void Paper_column_engraver::stop_translation_timestep () { @@ -194,25 +246,50 @@ { breaks_++; last_breakable_column_ = command_column_; - last_breakable_moment_ = now_mom (); + + SCM which_bar = get_property ("whichBar"); + if (scm_is_string (which_bar)) + { + string bar = ly_scm2string (which_bar); + if (bar != "" && bar != "|") + last_special_barline_column_ = command_column_; + } + if (! (breaks_%8)) progress_indication ("[" + to_string (breaks_) + "]"); } SCM page_br = get_property ("allowPageTurn"); - if (scm_is_pair (page_br) && last_breakable_moment_ >= Rational (0)) + if (scm_is_pair (page_br) && last_breakable_column_) { SCM pen = scm_cdr (page_br); Moment *m = unsmob_moment (scm_car (page_br)); - if (m && scm_is_number (pen) && *m <= last_breakable_moment_) + if (m) { - last_breakable_column_->set_property ("page-turn-permission", ly_symbol2scm ("allow")); - last_breakable_column_->set_property ("page-turn-penalty", pen); + Paper_column *turn = find_turnable_column (*m); + if (turn) + { + turn->set_property ("page-turn-permission", ly_symbol2scm ("allow")); + turn->set_property ("page-turn-penalty", pen); + page_turnable_columns_.push_back (turn); + } } } + /* The page-turn-engraver is allowed to change its mind and revoke previously-allowed + page turns (for example if there is a volta repeat where a turn is inconvenient) */ + SCM revokes = get_property ("revokePageTurns"); + if (scm_is_pair (revokes)) + { + Moment *start = unsmob_moment (scm_car (revokes)); + Real pen = robust_scm2double (scm_cdr (revokes), infinity_f); + if (start) + revoke_page_turns (*start, pen); + } + context ()->get_score_context ()->unset_property (ly_symbol2scm ("forbidBreak")); context ()->get_score_context ()->unset_property (ly_symbol2scm ("allowPageTurn")); + context ()->get_score_context ()->unset_property (ly_symbol2scm ("revokePageTurns")); first_ = false; break_events_.clear (); @@ -249,9 +326,13 @@ /* accept */ "break-event", /* read */ "forbidBreak " - "allowPageTurn", + "allowPageTurn " + "revokePageTurns " + , /* write */ "forbidBreak " "allowPageTurn " + "revokePageTurns " "currentCommandColumn " - "currentMusicalColumn"); + "currentMusicalColumn " + ); Index: lily/include/paper-column-engraver.hh =================================================================== RCS file: /sources/lilypond/lilypond/lily/include/paper-column-engraver.hh,v retrieving revision 1.9 diff -u -r1.9 paper-column-engraver.hh --- lily/include/paper-column-engraver.hh 9 May 2006 02:15:56 -0000 1.9 +++ lily/include/paper-column-engraver.hh 25 Jul 2006 01:24:49 -0000 @@ -17,6 +17,9 @@ void set_columns (Paper_column *, Paper_column *); TRANSLATOR_DECLARATIONS (Paper_column_engraver); + Paper_column *find_turnable_column (Moment after_this); + void revoke_page_turns (Moment after_this, Real new_penalty); + protected: void stop_translation_timestep (); void start_translation_timestep (); @@ -38,8 +41,9 @@ bool first_; Moment last_moment_; - Moment last_breakable_moment_; + Paper_column *last_special_barline_column_; Paper_column *last_breakable_column_; + vector<Paper_column*> page_turnable_columns_; public: }; Index: ly/paper-defaults.ly =================================================================== RCS file: /sources/lilypond/lilypond/ly/paper-defaults.ly,v retrieving revision 1.25 diff -u -r1.25 paper-defaults.ly --- ly/paper-defaults.ly 15 Jul 2006 10:32:44 -0000 1.25 +++ ly/paper-defaults.ly 25 Jul 2006 01:24:49 -0000 @@ -76,6 +76,12 @@ %% ragged-last-bottom= ##t + %% + %% settings for the page breaker + %% + blank-last-page-force = 0 + blank-last-force = 10 + #(define font-defaults '((font-encoding . fetaMusic))) Index: scm/define-context-properties.scm =================================================================== RCS file: /sources/lilypond/lilypond/scm/define-context-properties.scm,v retrieving revision 1.79 diff -u -r1.79 define-context-properties.scm --- scm/define-context-properties.scm 20 Jul 2006 09:29:42 -0000 1.79 +++ scm/define-context-properties.scm 25 Jul 2006 01:24:49 -0000 @@ -339,6 +339,7 @@ (restNumberThreshold ,number? "If a multimeasure rest has more measures than this, a number is printed. ") + (revokePageTurns ,pair? "Signals to the paper-column-engraver to revoke (or increase the penalties for) all the page turns within a time interval. Used to disable page turns that occur within an unturnable volta repeat.") (shapeNoteStyles ,vector? "Vector of symbols, listing style for each note head relative to the tonic (qv.) of the scale.") (skipBars ,boolean? "If set to true, then Index: scm/layout-page-layout.scm =================================================================== RCS file: /sources/lilypond/lilypond/scm/layout-page-layout.scm,v retrieving revision 1.19 diff -u -r1.19 layout-page-layout.scm --- scm/layout-page-layout.scm 24 Jul 2006 11:50:27 -0000 1.19 +++ scm/layout-page-layout.scm 25 Jul 2006 01:24:49 -0000 @@ -13,7 +13,7 @@ #:use-module (scm page) #:use-module (scm layout-page-dump) #:use-module (lily) - #:export (post-process-pages optimal-page-breaks)) + #:export (post-process-pages optimal-page-breaks make-page-from-systems)) (define (post-process-pages layout pages) (if (ly:output-def-lookup layout 'write-page-layout #f) @@ -160,6 +160,19 @@ (+ y topskip)) (cdr space-result))))) +(define (make-page-from-systems p-book lines p-num ragged? last?) + (let* + ((page (make-page + p-book + 'lines lines + 'page-number p-num + 'prev prev + 'is-last last?)) + (height (page-printable-height page)) + (posns (cdr (space-systems height lines ragged? (ly:paper-book-paper p-book))))) + (page-set-property! page 'configuration posns) + page)) + (define (walk-paths done-lines best-paths current-lines last? current-best paper-book page-alist) "Return the best optimal-page-break-node that contains @@ -170,8 +183,7 @@ CURRENT-BEST is the best result sofar, or #f." (let* ((paper (ly:paper-book-paper paper-book)) (this-page (make-page - page-alist - 'paper-book paper-book + paper-book 'is-last last? 'page-number (if (null? best-paths) (ly:output-def-lookup paper 'first-page-number) @@ -258,9 +270,10 @@ paper-book page-alist)))) -(define-public (optimal-page-breaks lines paper-book) +(define-public (optimal-page-breaks paper-book) "Return pages as a list starting with 1st page. Each page is a 'page Prob." (let* ((paper (ly:paper-book-paper paper-book)) + (lines (ly:paper-book-systems paper-book)) (page-alist (layout->page-init paper)) (force-equalization-factor (ly:output-def-lookup paper 'verticalequalizationfactor 0.3))) Index: scm/page.scm =================================================================== RCS file: /sources/lilypond/lilypond/scm/page.scm,v retrieving revision 1.13 diff -u -r1.13 page.scm --- scm/page.scm 24 Jul 2006 11:50:27 -0000 1.13 +++ scm/page.scm 25 Jul 2006 01:24:49 -0000 @@ -37,10 +37,11 @@ (define page-module (current-module)) -(define (make-page init . args) +(define (make-page p-book . args) (let* ((p (apply ly:make-prob (append - (list 'page init) + (list 'page (layout->page-init (ly:paper-book-paper p-book)) + 'paper-book p-book) args)))) (page-set-property! p 'head-stencil (page-header p)) @@ -196,7 +197,6 @@ ((p-book (page-property page 'paper-book)) (layout (ly:paper-book-paper p-book)) (scopes (ly:paper-book-scopes p-book)) - (lines (page-lines page)) (number (page-page-number page)) (last? (page-property page 'is-last)) ) Index: ly/declarations-init.ly =================================================================== RCS file: /sources/lilypond/lilypond/ly/declarations-init.ly,v retrieving revision 1.100 diff -u -r1.100 declarations-init.ly --- ly/declarations-init.ly 9 May 2006 02:15:56 -0000 1.100 +++ ly/declarations-init.ly 25 Jul 2006 02:31:56 -0000 @@ -46,6 +46,7 @@ (make-music 'PageBreakEvent 'break-permission 'force) (make-music 'PageTurnEvent 'break-permission 'force))) noPageTurn = #(make-event-chord (list (make-music 'PageTurnEvent 'break-permission '()))) +allowPageTurn = #(make-event-chord (list (make-music 'PageTurnEvent 'break-permission 'allow))) stopStaff = #(make-event-chord (list (make-span-event 'StaffSpanEvent STOP))) startStaff = #(make-event-chord (list (make-span-event 'StaffSpanEvent START)))
_______________________________________________ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel