]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/rest-collision.cc
* Documentation/user/music-glossary.itely: add Finnish author.
[lilypond.git] / lily / rest-collision.cc
index 49e85e2d955e2c50a776e154706510381e8996dc..e80e0d9cd751c57a7d59aa00d8b7a24191b8d436 100644 (file)
@@ -3,12 +3,12 @@
 
   source file of the GNU LilyPond music typesetter
 
-  (c)  1997--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+  (c) 1997--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
 */
 
 #include <math.h>              // ceil.
 
-#include "debug.hh"
+#include "warn.hh"
 #include "rest-collision.hh"
 #include "note-column.hh"
 #include "stem.hh"
@@ -29,17 +29,11 @@ Rest_collision::force_shift_callback (SCM element_smob, SCM axis)
 
   Grob * rc = unsmob_grob (them->get_grob_property ("rest-collision"));
 
-  if (rc)
+  if (rc && !to_boolean (rc->get_grob_property ("positioning-done")))
     {
-      /*
-       Done: destruct pointers, so we do the shift only once.
-
-       TODO: use rest-collision-done
-      */
-      SCM elts = rc->get_grob_property ("elements");
-      rc->set_grob_property ("elements", SCM_EOL);
+      rc->set_grob_property ("positioning-done", SCM_BOOL_T);
 
-      do_shift (rc, elts);
+      do_shift (rc);
     }
   
   return gh_double2scm (0.0);
@@ -52,7 +46,8 @@ Rest_collision::add_column (Grob*me,Grob *p)
   Pointer_group_interface::add_grob (me, ly_symbol2scm ("elements"), p);
 
   /*
-    only add callback for the rests, since we don't move anything else.
+    only add callback for the rests, since we don't move anything
+    else.
 
  (not?)
   */
@@ -81,13 +76,15 @@ head_characteristic (Grob * col)
 
   TODO: look at horizontal-shift to determine ordering between rests
   for more than two voices.
+
+  TODO: look at previous note to determine vertical position?
+  
  */
 SCM
-Rest_collision::do_shift (Grob *me, SCM elts)
+Rest_collision::do_shift (Grob *me)
 {
-  /*
-    ugh. -> score  elt type
-   */
+  SCM elts = me->get_grob_property ("elements");
+
   Link_array<Grob> rests;
   Link_array<Grob> notes;
 
@@ -116,8 +113,14 @@ Rest_collision::do_shift (Grob *me, SCM elts)
 
   // no partners to collide with
   if (rests.size () + notes.size () < 2)
-    return SCM_UNSPECIFIED;
-
+    {
+      if (rests.size () == 1
+         && Note_column::dir (rests[0]))
+       {
+         Note_column::translate_rests (rests[0],
+                                       4 * Note_column::dir (rests[0]));
+       }
+    }
   // meisjes met meisjes
   if (!notes.size ()) 
     {
@@ -145,7 +148,12 @@ Rest_collision::do_shift (Grob *me, SCM elts)
            {
              Grob* r = unsmob_grob (rests[i-1]->get_grob_property ("rest"));
              if (r)
-               r->suicide ();
+               {
+                 Grob * d = unsmob_grob (r->get_grob_property ("dot"));
+                 if (d)
+                   d->suicide();
+                 r->suicide ();
+               }
              rests[i-1]->suicide ();
            }
        }
@@ -195,13 +203,13 @@ Rest_collision::do_shift (Grob *me, SCM elts)
       Grob * r = unsmob_grob (rcol->get_grob_property ("rest"));
       Interval restdim = r->extent (r, Y_AXIS);        // ??
 
-      if (restdim.empty_b ())
+      if (restdim.is_empty ())
        return SCM_UNSPECIFIED;
       
 
       Real staff_space = Staff_symbol_referencer::staff_space (rcol);
 
-      Real minimum_dist = gh_scm2double (me->get_grob_property ("minimum-distance")) * staff_space;
+      Real minimum_dist = robust_scm2double (me->get_grob_property ("minimum-distance"), 1.0) * staff_space;
 
 
       Grob *common = common_refpoint_of_array (notes, rcol, Y_AXIS);
@@ -239,7 +247,7 @@ Rest_collision::do_shift (Grob *me, SCM elts)
 
 
 ADD_INTERFACE (Rest_collision,"rest-collision-interface",
-  "Move around ordinary rests (not multi-measure-rests) to avoid
-conflicts.",
-  "maximum-rest-count minimum-distance elements");
+  "Move around ordinary rests (not multi-measure-rests) to avoid "
+"conflicts.",
+  "maximum-rest-count minimum-distance positioning-done elements");