X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fpage-turn-engraver.cc;h=d9c1bd12fa4c17b8520e0f344ef39d768cdcdc3e;hb=9e781b7dc83b60a543ce218aa1a5f139f74c760f;hp=4064efa37e2fd9f12921dfc8c5cab56df2f219c0;hpb=9e69cb84d6ee5b0a861cd97869b10e3bdf0c833c;p=lilypond.git diff --git a/lily/page-turn-engraver.cc b/lily/page-turn-engraver.cc index 4064efa37e..d9c1bd12fa 100644 --- a/lily/page-turn-engraver.cc +++ b/lily/page-turn-engraver.cc @@ -1,9 +1,20 @@ /* - page-turn-engraver.cc -- implement Page_turn_engraver + This file is part of LilyPond, the GNU music typesetter. - source file of the GNU LilyPond music typesetter + Copyright (C) 2006--2014 Joe Neeman - (c) 2006 Joe Neeman + LilyPond is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + LilyPond is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LilyPond. If not, see . */ #include "engraver.hh" @@ -18,7 +29,8 @@ #include "translator.icc" -class Page_turn_event { +class Page_turn_event +{ public: SCM permission_; Real penalty_; @@ -45,8 +57,8 @@ public: if (intersect.is_empty ()) { - ret.push_back (*this); - return ret; + ret.push_back (*this); + return ret; } Real new_pen = max (penalty_, penalty.penalty_); @@ -77,7 +89,7 @@ class Page_turn_engraver : public Engraver /* the next 3 are in sync (ie. same number of elements, etc.) */ vector breakable_moments_; - vector breakable_columns_; + vector breakable_columns_; vector special_barlines_; SCM max_permission (SCM perm1, SCM perm2); @@ -103,7 +115,7 @@ Page_turn_engraver::Page_turn_engraver () note_end_ = 0; } -Grob* +Grob * Page_turn_engraver::breakable_column (Page_turn_event const &brk) { vsize start = lower_bound (breakable_moments_, brk.duration_[LEFT], less ()); @@ -136,9 +148,9 @@ Page_turn_engraver::acknowledge_note_head (Grob_info gi) Stream_event *cause = gi.event_cause (); Duration *dur_ptr = cause - ? unsmob_duration (cause->get_property ("duration")) - : 0; - + ? unsmob_duration (cause->get_property ("duration")) + : 0; + if (!dur_ptr) return; @@ -146,9 +158,9 @@ Page_turn_engraver::acknowledge_note_head (Grob_info gi) { Real pen = penalty ((now_mom () - rest_begin_).main_part_); if (!isinf (pen)) - automatic_breaks_.push_back (Page_turn_event (rest_begin_.main_part_, - now_mom ().main_part_, - ly_symbol2scm ("allow"), 0)); + automatic_breaks_.push_back (Page_turn_event (rest_begin_.main_part_, + now_mom ().main_part_, + ly_symbol2scm ("allow"), 0)); } if (rest_begin_ <= repeat_begin_) @@ -160,7 +172,7 @@ IMPLEMENT_TRANSLATOR_LISTENER (Page_turn_engraver, break); void Page_turn_engraver::listen_break (Stream_event *ev) { - string name = ly_scm2string (scm_symbol_to_string (ev->get_property ("class"))); + string name = ly_symbol2string (scm_car (ev->get_property ("class"))); if (name == "page-turn-event") { @@ -218,9 +230,9 @@ Page_turn_engraver::stop_translation_timestep () { SCM command = scm_car (cs); if (command == ly_symbol2scm ("start-repeat")) - start = true; + start = true; else if (command == ly_symbol2scm ("end-repeat")) - end = true; + end = true; } if (end && repeat_begin_.main_part_ >= Moment (0)) @@ -229,12 +241,12 @@ Page_turn_engraver::stop_translation_timestep () Real pen = penalty ((now_mom () - rest_begin_).main_part_ + repeat_begin_rest_length_); Moment *m = unsmob_moment (get_property ("minimumRepeatLengthForPageTurn")); if (m && *m > (now_mom () - repeat_begin_)) - pen = infinity_f; + pen = infinity_f; if (pen == infinity_f) - repeat_penalties_.push_back (Page_turn_event (repeat_begin_.main_part_, now, SCM_EOL, -infinity_f)); + repeat_penalties_.push_back (Page_turn_event (repeat_begin_.main_part_, now, SCM_EOL, -infinity_f)); else - repeat_penalties_.push_back (Page_turn_event (repeat_begin_.main_part_, now, ly_symbol2scm ("allow"), pen)); + repeat_penalties_.push_back (Page_turn_event (repeat_begin_.main_part_, now, ly_symbol2scm ("allow"), pen)); repeat_begin_ = Moment (-1); } @@ -273,30 +285,30 @@ Page_turn_engraver::finalize () /* find the next applicable repeat penalty */ for (; - rep_index < repeat_penalties_.size () - && repeat_penalties_[rep_index].duration_[RIGHT] <= brk.duration_[LEFT]; - rep_index++) - ; + rep_index < repeat_penalties_.size () + && repeat_penalties_[rep_index].duration_[RIGHT] <= brk.duration_[LEFT]; + rep_index++) + ; if (rep_index >= repeat_penalties_.size () - || brk.duration_[RIGHT] <= repeat_penalties_[rep_index].duration_[LEFT]) - auto_breaks.push_back (brk); + || brk.duration_[RIGHT] <= repeat_penalties_[rep_index].duration_[LEFT]) + auto_breaks.push_back (brk); else - { - vector split = brk.penalize (repeat_penalties_[rep_index]); - - /* it's possible that the last of my newly-split events overlaps the next repeat_penalty, - in which case we need to refilter that event */ - if (rep_index < repeat_penalties_.size () - 1 - && split.size () - && split.back ().duration_[RIGHT] > repeat_penalties_[rep_index+1].duration_[LEFT]) - { - automatic_breaks_[i] = split.back (); - split.pop_back (); - i--; - } - auto_breaks.insert (auto_breaks.end (), split.begin (), split.end ()); - } + { + vector split = brk.penalize (repeat_penalties_[rep_index]); + + /* it's possible that the last of my newly-split events overlaps the next repeat_penalty, + in which case we need to refilter that event */ + if (rep_index + 1 < repeat_penalties_.size () + && split.size () + && split.back ().duration_[RIGHT] > repeat_penalties_[rep_index + 1].duration_[LEFT]) + { + automatic_breaks_[i] = split.back (); + split.pop_back (); + i--; + } + auto_breaks.insert (auto_breaks.end (), split.begin (), split.end ()); + } } /* apply the automatic breaks */ @@ -305,33 +317,43 @@ Page_turn_engraver::finalize () Page_turn_event const &brk = auto_breaks[i]; Grob *pc = breakable_column (auto_breaks[i]); if (pc) - { - SCM perm = max_permission (pc->get_property ("page-turn-permission"), brk.permission_); - Real pen = min (robust_scm2double (pc->get_property ("page-turn-penalty"), infinity_f), brk.penalty_); - pc->set_property ("page-turn-permission", perm); - pc->set_property ("page-turn-penalty", scm_from_double (pen)); - } + { + SCM perm = max_permission (pc->get_property ("page-turn-permission"), brk.permission_); + Real pen = min (robust_scm2double (pc->get_property ("page-turn-penalty"), infinity_f), brk.penalty_); + pc->set_property ("page-turn-permission", perm); + pc->set_property ("page-turn-penalty", scm_from_double (pen)); + } } + /* unless a manual break overrides it, allow a page turn at the end of the piece */ + breakable_columns_.back ()->set_property ("page-turn-permission", ly_symbol2scm ("allow")); + /* apply the manual breaks */ for (vsize i = 0; i < forced_breaks_.size (); i++) { Page_turn_event const &brk = forced_breaks_[i]; Grob *pc = breakable_column (forced_breaks_[i]); if (pc) - { - pc->set_property ("page-turn-permission", brk.permission_); - pc->set_property ("page-turn-penalty", scm_from_double (brk.penalty_)); - } + { + pc->set_property ("page-turn-permission", brk.permission_); + pc->set_property ("page-turn-penalty", scm_from_double (brk.penalty_)); + } } } ADD_ACKNOWLEDGER (Page_turn_engraver, note_head); + ADD_TRANSLATOR (Page_turn_engraver, - /* doc */ "Decide where page turns are allowed to go", - /* create */ "", + /* doc */ + "Decide where page turns are allowed to go.", + + /* create */ + "", + /* read */ - "minimumPageTurnLength " - "minimumRepeatLengthForPageTurn ", - /* write */ "" - ); + "minimumPageTurnLength " + "minimumRepeatLengthForPageTurn ", + + /* write */ + "" + );