]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/keep-alive-together-engraver.cc
Imported Upstream version 2.19.45
[lilypond.git] / lily / keep-alive-together-engraver.cc
index f6ba297ccfe4b5bd8fd84776e9d62c3799a5bc8e..9b1cbe4a23a412b95cb8797e6f7dd8fdc7656704 100644 (file)
@@ -1,7 +1,7 @@
 /*
   This file is part of LilyPond, the GNU music typesetter.
 
-  Copyright (C) 2010--2012 Joe Neeman <joeneeman@gmail.com>
+  Copyright (C) 2010--2015 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
@@ -31,7 +31,7 @@ class Keep_alive_together_engraver: public Engraver
 
 public:
   TRANSLATOR_DECLARATIONS (Keep_alive_together_engraver);
-  DECLARE_ACKNOWLEDGER (hara_kiri_group_spanner);
+  void acknowledge_hara_kiri_group_spanner (Grob_info);
 
   virtual void finalize ();
 };
@@ -51,18 +51,49 @@ Keep_alive_together_engraver::finalize ()
 {
   for (vsize i = 0; i < group_spanners_.size (); ++i)
     {
-      SCM grob_array_scm = Grob_array::make_array ();
-      Grob_array *ga = unsmob_grob_array (grob_array_scm);
-
-      // It would make Hara_kiri_group_spanner::request_suicide a _little_
-      // faster if we removed each grob from its own array. It seems
-      // unnecessary for now, though.
-      ga->set_array (group_spanners_);
-      group_spanners_[i]->set_object ("keep-alive-with", grob_array_scm);
+      SCM this_layer = group_spanners_[i]->get_property ("remove-layer");
+      if (scm_is_false (this_layer))
+        continue;
+
+      SCM live_scm = Grob_array::make_array ();
+      Grob_array *live = unsmob<Grob_array> (live_scm);
+      SCM dead_scm = Grob_array::make_array ();
+      Grob_array *dead = unsmob<Grob_array> (dead_scm);
+
+      for (vsize j = 0; j < group_spanners_.size (); ++j)
+        {
+          if (i == j)
+            continue;
+          SCM that_layer = group_spanners_[j]->get_property ("remove-layer");
+          if (scm_is_false (that_layer))
+            continue;
+          if (!scm_is_integer (this_layer))
+            {
+              // Unspecified layers are kept alive by anything else
+              live->add (group_spanners_[j]);
+              continue;
+            }
+          // an explicit layer is only affected by explicit layers
+          if (!scm_is_integer (that_layer))
+            continue;
+          if (scm_is_true (scm_num_eq_p (that_layer, this_layer)))
+            live->add (group_spanners_[j]);
+          else if (scm_is_true (scm_less_p (that_layer, this_layer)))
+            dead->add (group_spanners_[j]);
+        }
+      if (!live->empty ())
+        group_spanners_[i]->set_object ("keep-alive-with", live_scm);
+      if (!dead->empty ())
+        group_spanners_[i]->set_object ("make-dead-when", dead_scm);
     }
 }
 
-ADD_ACKNOWLEDGER (Keep_alive_together_engraver, hara_kiri_group_spanner);
+
+void
+Keep_alive_together_engraver::boot ()
+{
+  ADD_ACKNOWLEDGER (Keep_alive_together_engraver, hara_kiri_group_spanner);
+}
 
 ADD_TRANSLATOR (Keep_alive_together_engraver,
                 /* doc */