]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/note-collision.cc
Run `make grand-replace'.
[lilypond.git] / lily / note-collision.cc
index bcdd36b4d5ec4aca26399868c5992b4d605dc01d..7ac359b36f8a52f5576ebde0bf1817459d19cf5b 100644 (file)
@@ -3,7 +3,7 @@
 
   source file of the GNU LilyPond music typesetter
 
-  (c) 1997--2007 Han-Wen Nienhuys <hanwen@xs4all.nl>
+  (c) 1997--2008 Han-Wen Nienhuys <hanwen@xs4all.nl>
 */
 
 #include "note-collision.hh"
@@ -81,16 +81,6 @@ check_meshing_chords (Grob *me,
       && !to_boolean (me->get_property ("merge-differently-headed")))
     merge_possible = false;
 
-  if (merge_possible
-      && head_up->get_property ("style") == ly_symbol2scm ("fa")
-      && head_down->get_property ("style") == ly_symbol2scm ("fa"))
-    {
-      Interval uphead_size = head_up->extent (head_up, Y_AXIS);
-      Offset att =  Offset (0.0, -1.0);
-      head_up->set_property ("stem-attachment", ly_offset2scm (att));
-      head_up->set_property ("transparent", SCM_BOOL_T); 
-    }
-  
   /* Should never merge quarter and half notes, as this would make
      them indistinguishable.  */
   if (merge_possible
@@ -171,6 +161,13 @@ check_meshing_chords (Grob *me,
   Real shift_amount = 1;
 
   bool touch = (ups[0] >= dps.back ());
+  /* As a special case, if the topmost part of the downstem chord is a second,
+     the top note of which is the same pitch as the lowest upstem note, they
+     shouldn't count as touching.
+  */
+  if (dps.back () == ups[0] && dps.size () > 1 && dps[dps.size() - 2] == ups[0] - 1)
+    touch = false;
+
   if (touch)
     shift_amount *= -1;
 
@@ -178,11 +175,27 @@ check_meshing_chords (Grob *me,
      make sure the dotted heads go to the right.  */
   bool stem_to_stem = false;
   if (full_collide)
-    if (Rhythmic_head::dot_count (head_up) > Rhythmic_head::dot_count (head_down))
-      shift_amount = 1;
-    else if (Rhythmic_head::dot_count (head_up) < Rhythmic_head::dot_count (head_down))
-      stem_to_stem = true;
+    {
+      if (Rhythmic_head::dot_count (head_up) > Rhythmic_head::dot_count (head_down))
+       shift_amount = 1;
+      else if (Rhythmic_head::dot_count (head_up) < Rhythmic_head::dot_count (head_down))
+       stem_to_stem = true;
+    }
 
+  /* The solfa is a triangle, which is inverted depending on stem
+     direction. In case of a collision, one of them should be removed,
+     so the resulting note does not look like a block.
+  */
+  if (merge_possible
+      && head_up->get_property ("style") == ly_symbol2scm ("fa")
+      && head_down->get_property ("style") == ly_symbol2scm ("fa"))
+    {
+      Interval uphead_size = head_up->extent (head_up, Y_AXIS);
+      Offset att = Offset (0.0, -1.0);
+      head_up->set_property ("stem-attachment", ly_offset2scm (att));
+      head_up->set_property ("transparent", SCM_BOOL_T); 
+    }
+  
   if (merge_possible)
     {
       shift_amount = 0;
@@ -277,12 +290,20 @@ check_meshing_chords (Grob *me,
     {
       Grob *staff = Staff_symbol_referencer::get_staff_symbol (me);
       if (!Staff_symbol_referencer::on_line (staff, ups[0]))
-       {
-         Grob *d = unsmob_grob (head_up->get_object ("dot"));
-         Grob *parent = d->get_parent (X_AXIS);
-         if (Dot_column::has_interface (parent))
-           Side_position_interface::add_support (parent, head_down);
-       }
+       /*
+         TODO: consider junking the else body.
+       */
+       if (to_boolean (me->get_property ("prefer-dotted-right")))
+         {
+           shift_amount = 0.5;
+         }
+       else
+         {
+           Grob *d = unsmob_grob (head_up->get_object ("dot"));
+           Grob *parent = d->get_parent (X_AXIS);
+           if (Dot_column::has_interface (parent))
+             Side_position_interface::add_support (parent, head_down);
+         }
     }
 
   /* For full or close half collisions, the right hand head may
@@ -331,30 +352,30 @@ Note_collision_interface::calc_positioning_done (SCM smob)
   Grob *me = unsmob_grob (smob);
   me->set_property ("positioning-done", SCM_BOOL_T);
   
-  Drul_array<vector<Grob*> > cg = get_clash_groups (me);
+  Drul_array<vector<Grob*> > clash_groups = get_clash_groups (me);
 
   Direction d = UP;
   do
     {
-      for (vsize i = cg[d].size (); i--; )
+      for (vsize i = clash_groups[d].size (); i--; )
        {
          /*
            Trigger positioning
           */
-         cg[d][i]->extent (me, X_AXIS);
+         clash_groups[d][i]->extent (me, X_AXIS);
        }
     }
   while (flip (&d) != UP);
 
-  SCM autos (automatic_shift (me, cg));
+  SCM autos (automatic_shift (me, clash_groups));
   SCM hand (forced_shift (me));
 
   Real wid = 0.0;
   do
     {
-      if (cg[d].size ())
+      if (clash_groups[d].size ())
        {
-         Grob *h = cg[d][0];
+         Grob *h = clash_groups[d][0];
          Grob *fh = Note_column::first_head (h);
          if (fh)
            wid = fh->extent (h, X_AXIS).length ();
@@ -569,12 +590,15 @@ Note_collision_interface::add_column (Grob *me, Grob *ncol)
 }
 
 ADD_INTERFACE (Note_collision_interface,
-              "An object that handles collisions between notes with different stem "
-              "directions and horizontal shifts. Most of the interesting properties "
-              "are to be set in @ref{note-column-interface}: these are "
-              "@code{force-hshift} and @code{horizontal-shift}.",
+              "An object that handles collisions between notes with"
+              " different stem directions and horizontal shifts.  Most of"
+              " the interesting properties are to be set in"
+              " @ref{note-column-interface}: these are @code{force-hshift}"
+              " and @code{horizontal-shift}.",
 
               /* properties */
               "merge-differently-dotted "
               "merge-differently-headed "
-              "positioning-done ");
+              "positioning-done "
+              "prefer-dotted-right "
+              );