X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fpaper-column-engraver.cc;h=276834951175821cdd15b9f4e14c339c07a1b2f5;hb=8d540cf685bfda800b1ea99bef1ae236dba6280d;hp=b6f249e9af0d623392838fe571e120f3ed8c3a65;hpb=e09265d8e9ad94714076ca91e63eab5c55679286;p=lilypond.git diff --git a/lily/paper-column-engraver.cc b/lily/paper-column-engraver.cc index b6f249e9af..2768349511 100644 --- a/lily/paper-column-engraver.cc +++ b/lily/paper-column-engraver.cc @@ -8,13 +8,15 @@ #include "paper-column-engraver.hh" #include "system.hh" +#include "international.hh" +#include "axis-group-interface.hh" +#include "context.hh" #include "item.hh" -#include "paper-column.hh" -#include "staff-spacing.hh" #include "note-spacing.hh" +#include "paper-column.hh" #include "pointer-group-interface.hh" -#include "context.hh" -#include "axis-group-interface.hh" +#include "staff-spacing.hh" +#include "system.hh" #include "warn.hh" #include "translator.icc" @@ -26,9 +28,9 @@ Paper_column_engraver::Paper_column_engraver () 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 @@ -40,6 +42,7 @@ Paper_column_engraver::finalize () if (command_column_) { command_column_->set_property ("line-break-permission", ly_symbol2scm ("allow")); + command_column_->set_property ("page-turn-permission", ly_symbol2scm ("allow")); system_->set_bound (RIGHT, command_column_); } } @@ -84,6 +87,7 @@ Paper_column_engraver::acknowledge_staff_spacing (Grob_info gi) ly_symbol2scm ("spacing-wishes"), gi.grob ()); } + void Paper_column_engraver::acknowledge_note_spacing (Grob_info gi) { @@ -108,12 +112,11 @@ Paper_column_engraver::set_columns (Paper_column *new_command, system_->add_column (musical_column_); } -bool -Paper_column_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Paper_column_engraver, break); +void +Paper_column_engraver::listen_break (Stream_event *ev) { - break_events_.push_back (m); - - return true; + break_events_.push_back (ev); } void @@ -122,18 +125,17 @@ Paper_column_engraver::process_music () for (vsize i = 0; i < break_events_.size (); i++) { string prefix; - SCM name = break_events_[i]->get_property ("name"); - if (name == ly_symbol2scm ("LineBreakEvent")) - prefix = "line-break"; - else if (name == ly_symbol2scm ("PageBreakEvent")) - prefix = "page-break"; - else if (name == ly_symbol2scm ("PageTurnEvent")) - prefix = "page-turn"; + SCM name_sym = break_events_[i]->get_property ("class"); + string name = ly_scm2string (scm_symbol_to_string (name_sym)); + size_t end = name.rfind ("-event"); + if (end) + prefix = name.substr (0, end); else { programming_error ("Paper_column_engraver doesn't know about this break-event"); return; } + string perm_str = prefix + "-permission"; string pen_str = prefix + "-penalty"; @@ -169,6 +171,56 @@ Paper_column_engraver::process_music () } } +/* 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 @@ Paper_column_engraver::stop_translation_timestep () { 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 @@ ADD_TRANSLATOR (Paper_column_engraver, /* accept */ "break-event", /* read */ "forbidBreak " - "allowPageTurn", + "allowPageTurn " + "revokePageTurns " + , /* write */ "forbidBreak " "allowPageTurn " + "revokePageTurns " "currentCommandColumn " - "currentMusicalColumn"); + "currentMusicalColumn " + );