]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/page-turn-engraver.cc
Run grand-replace (issue 3765)
[lilypond.git] / lily / page-turn-engraver.cc
index 4064efa37e2fd9f12921dfc8c5cab56df2f219c0..d9c1bd12fa4c17b8520e0f344ef39d768cdcdc3e 100644 (file)
@@ -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 <joeneeman@gmail.com>
 
-  (c) 2006 Joe Neeman <joeneeman@gmail.com>
+  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 <http://www.gnu.org/licenses/>.
 */
 
 #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<Rational> breakable_moments_;
-  vector<Grob*> breakable_columns_;
+  vector<Grob *> breakable_columns_;
   vector<bool> 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<Rational> ());
@@ -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<Page_turn_event> 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<Page_turn_event> 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 */
+                ""
+               );