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 + * 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 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)))