]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/new-dynamic-engraver.cc
Don't let lyrics interfere with StaffGrouper.
[lilypond.git] / lily / new-dynamic-engraver.cc
index 54aa8a8c6df363dca7a4ec59dfd95c0d2967cf53..497fc0b7f710c145c1b44310e4d9c86618282118 100644 (file)
@@ -1,15 +1,23 @@
-/* 
-  new-dynamic-engraver.cc -- implement New_dynamic_engraver
-  
-  source file of the GNU LilyPond music typesetter
-  
-  (c) 2008--2009 Han-Wen Nienhuys <hanwen@lilypond.org>
-  
-*/
+/*
+  This file is part of LilyPond, the GNU music typesetter.
 
+  Copyright (C) 2008--2010 Han-Wen Nienhuys <hanwen@lilypond.org>
 
-#include "engraver.hh"
+  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"
 #include "hairpin.hh"
 #include "international.hh"
 #include "item.hh"
@@ -32,13 +40,17 @@ class New_dynamic_engraver : public Engraver
 protected:
   virtual void process_music ();
   virtual void stop_translation_timestep ();
+  virtual void finalize ();
+
 private:
-  SCM get_property_setting (Stream_event *evt, char const *evprop, char const *ctxprop);
+  SCM get_property_setting (Stream_event *evt, char const *evprop,
+                           char const *ctxprop);
+  string get_spanner_type (Stream_event *ev);
 
   Drul_array<Stream_event *> accepted_spanevents_drul_;
   Spanner *current_spanner_;
   Spanner *finished_spanner_;
-  
+
   Item *script_;
   Stream_event *script_event_;
   Stream_event *current_span_event_;
@@ -71,7 +83,9 @@ New_dynamic_engraver::listen_span_dynamic (Stream_event *ev)
 }
 
 SCM
-New_dynamic_engraver::get_property_setting (Stream_event *evt, char const *evprop, char const *ctxprop)
+New_dynamic_engraver::get_property_setting (Stream_event *evt,
+                                           char const *evprop,
+                                           char const *ctxprop)
 {
   SCM spanner_type = evt->get_property (evprop);
   if (spanner_type == SCM_EOL)
@@ -83,15 +97,17 @@ void
 New_dynamic_engraver::process_music ()
 {
   if (current_spanner_
-      && (accepted_spanevents_drul_[STOP] || script_event_ || accepted_spanevents_drul_[START]))
+      && (accepted_spanevents_drul_[STOP]
+         || script_event_
+         || accepted_spanevents_drul_[START]))
     {
-      Stream_eventender = accepted_spanevents_drul_[STOP];
+      Stream_event *ender = accepted_spanevents_drul_[STOP];
       if (!ender)
        ender = script_event_;
 
       if (!ender)
        ender = accepted_spanevents_drul_[START];
-      
+
       finished_spanner_ = current_spanner_;
       announce_end_grob (finished_spanner_, ender->self_scm ());
       current_spanner_ = 0;
@@ -101,22 +117,10 @@ New_dynamic_engraver::process_music ()
   if (accepted_spanevents_drul_[START])
     {
       current_span_event_ = accepted_spanevents_drul_[START];
-      
-      SCM start_sym = current_span_event_->get_property ("class");
-      string start_type;
-         
-      if (start_sym == ly_symbol2scm ("decrescendo-event"))
-       start_type = "decrescendo";
-      else if (start_sym == ly_symbol2scm ("crescendo-event"))
-       start_type = "crescendo";
-      else
-       {
-         programming_error ("unknown dynamic spanner type");
-         return;
-       }
-      
+
+      string start_type = get_spanner_type (current_span_event_);
       SCM cresc_type = get_property_setting (current_span_event_, "span-type",
-                                       (start_type + "Spanner").c_str ());
+                                            (start_type + "Spanner").c_str ());
 
       if (cresc_type == ly_symbol2scm ("text"))
        {
@@ -125,33 +129,31 @@ New_dynamic_engraver::process_music ()
                            accepted_spanevents_drul_[START]->self_scm ());
 
          SCM text = get_property_setting (current_span_event_, "span-text",
-                                       (start_type + "Text").c_str ());
+                                          (start_type + "Text").c_str ());
          if (Text_interface::is_markup (text))
-           {
-             current_spanner_->set_property ("text", text);
-           }
+           current_spanner_->set_property ("text", text);
        }
       else
        {
          if (cresc_type != ly_symbol2scm ("hairpin"))
            {
-             // Fixme: should put value in error message.
              string as_string = ly_scm_write_string (cresc_type);
              current_span_event_
                ->origin()->warning (_f ("unknown crescendo style: %s\ndefaulting to hairpin.", as_string.c_str()));
            }
          current_spanner_ = make_spanner ("Hairpin",
                                           current_span_event_->self_scm ());
-         if (finished_spanner_)
-           {
-             Pointer_group_interface::add_grob (finished_spanner_,
-                                                ly_symbol2scm ("adjacent-hairpins"),
-                                                current_spanner_);
-
-             Pointer_group_interface::add_grob (current_spanner_,
-                                                ly_symbol2scm ("adjacent-hairpins"),
-                                                finished_spanner_);
-           }
+       }
+      if (finished_spanner_)
+       {
+         if (Hairpin::has_interface (finished_spanner_))
+           Pointer_group_interface::add_grob (finished_spanner_,
+                                              ly_symbol2scm ("adjacent-spanners"),
+                                              current_spanner_);
+         if (Hairpin::has_interface (current_spanner_))
+           Pointer_group_interface::add_grob (current_spanner_,
+                                              ly_symbol2scm ("adjacent-spanners"),
+                                              finished_spanner_);
        }
     }
 
@@ -164,39 +166,61 @@ New_dynamic_engraver::process_music ()
       if (finished_spanner_)
        finished_spanner_->set_bound (RIGHT, script_);
       if (current_spanner_)
-       {
-         current_spanner_->set_bound (LEFT, script_);
-
-         if (!Hairpin::has_interface (current_spanner_))
-           set_nested_property (current_spanner_,
-                                scm_list_3 (ly_symbol2scm ("bound-details"),
-                                            ly_symbol2scm ("left"),
-                                            ly_symbol2scm ("attach-dir")
-                                            ),
-                                scm_from_int (RIGHT));
-
-       }
+       current_spanner_->set_bound (LEFT, script_);
     }
 }
 
-
-
 void
 New_dynamic_engraver::stop_translation_timestep ()
 {
   if (finished_spanner_ && !finished_spanner_->get_bound (RIGHT))
-    finished_spanner_->set_bound (RIGHT,
-                                 unsmob_grob (get_property ("currentMusicalColumn")));
+    finished_spanner_
+      ->set_bound (RIGHT,
+                  unsmob_grob (get_property ("currentMusicalColumn")));
 
   if (current_spanner_ && !current_spanner_->get_bound (LEFT))
-    current_spanner_->set_bound (LEFT,
-                                unsmob_grob (get_property ("currentMusicalColumn")));
+    current_spanner_
+      ->set_bound (LEFT,
+                  unsmob_grob (get_property ("currentMusicalColumn")));
   script_ = 0;
   script_event_ = 0;
   accepted_spanevents_drul_.set (0, 0);
   finished_spanner_ = 0;
 }
 
+void
+New_dynamic_engraver::finalize ()
+{
+  if (current_spanner_
+      && !current_spanner_->is_live ())
+    current_spanner_ = 0;
+  if (current_spanner_)
+    {
+      current_span_event_
+       ->origin ()->warning (_f ("unterminated %s",
+                                 get_spanner_type (current_span_event_)
+                                 .c_str ()));
+      current_spanner_->suicide ();
+      current_spanner_ = 0;
+    }
+}
+
+string
+New_dynamic_engraver::get_spanner_type (Stream_event *ev)
+{
+  string type;
+  SCM start_sym = ev->get_property ("class");
+
+  if (start_sym == ly_symbol2scm ("decrescendo-event"))
+    type = "decrescendo";
+  else if (start_sym == ly_symbol2scm ("crescendo-event"))
+    type = "crescendo";
+  else
+    programming_error ("unknown dynamic spanner type");
+
+  return type;
+}
+
 void
 New_dynamic_engraver::acknowledge_note_column (Grob_info info)
 {