]> git.donarmstrong.com Git - lilypond.git/commitdiff
Add and use note-collision-threshold grob property
authorPaul Morris <paulwmorris@gmail.com>
Thu, 26 Nov 2015 01:58:01 +0000 (20:58 -0500)
committerJames Lowe <pkx166h@gmail.com>
Fri, 11 Dec 2015 15:46:57 +0000 (15:46 +0000)
Includes a regression test.

input/regression/note-collision-threshold.ly [new file with mode: 0644]
lily/note-collision.cc
lily/stem.cc
scm/define-grob-properties.scm
scm/define-grobs.scm

diff --git a/input/regression/note-collision-threshold.ly b/input/regression/note-collision-threshold.ly
new file mode 100644 (file)
index 0000000..e01a2e1
--- /dev/null
@@ -0,0 +1,46 @@
+\version "2.19.34"
+
+\header {
+  texidoc = "Whether simultaneous notes are identified as
+  vertically colliding or not depends on the value of the
+  @code{note-collision-threshold} property of the @code{Stem}
+  grob (for notes in the same voice) and the @code{NoteCollision}
+  grob (for notes in different voices)."
+}
+
+music = <<
+  \new Voice \relative {
+    \voiceOne
+    <c' d>4 <d e> <f g> <g a>
+    e g g a
+
+  }
+  \new Voice \relative {
+    \voiceTwo
+    s4 s s s
+    d' f a b
+  }
+>>
+
+customizations = \with {
+  staffLineLayoutFunction = #ly:pitch-semitones
+  \override StaffSymbol.staff-space = #0.7
+  \override StaffSymbol.line-positions = #'(-4 0 4)
+}
+
+
+\markup "collisions"
+
+\new Staff \with {
+  \customizations
+}
+\music
+
+\markup "collisions prevented"
+
+\new Staff \with {
+  \customizations
+  \override Stem.note-collision-threshold = #2
+  \override NoteCollision.note-collision-threshold = #2
+}
+\music
index f98cb5a3a037d279c5234b314638432a5252737f..664ce234a7ea92fc1aa06ae3d2800cac70c74932 100644 (file)
@@ -55,8 +55,10 @@ check_meshing_chords (Grob *me,
   vector<int> ups = Stem::note_head_positions (stems[UP]);
   vector<int> dps = Stem::note_head_positions (stems[DOWN]);
 
+  int threshold = robust_scm2int (me->get_property ("note-collision-threshold"), 1);
+
   /* Too far apart to collide. */
-  if (ups[0] > dps.back () + 1)
+  if (ups[0] > dps.back () + threshold)
     return 0.0;
 
   /* If the chords just 'touch' their extreme noteheads,
@@ -64,8 +66,8 @@ check_meshing_chords (Grob *me,
   */
   bool touch = false;
   if (ups[0] >= dps.back ()
-      && (dps.size () < 2 || ups[0] >= dps[dps.size () - 2] + 2)
-      && (ups.size () < 2 || ups[1] >= dps.back () + 2))
+      && (dps.size () < 2 || ups[0] >= dps[dps.size () - 2] + threshold + 1)
+      && (ups.size () < 2 || ups[1] >= dps.back () + threshold + 1))
     touch = true;
 
   /* Filter out the 'o's in this configuration, since they're no
@@ -141,7 +143,9 @@ check_meshing_chords (Grob *me,
 
   for (vsize i = 0, j = 0; i < ups.size () && j < dps.size ();)
     {
-      if (abs (ups[i] - dps[j]) == 1)
+      if (ups[i] == dps[j])
+        full_collide = true;
+      else if (abs (ups[i] - dps[j]) <= threshold)
         {
           merge_possible = false;
           if (ups[i] > dps[j])
@@ -149,8 +153,6 @@ check_meshing_chords (Grob *me,
           else
             distant_half_collide = true;
         }
-      else if (ups[i] == dps[j])
-        full_collide = true;
       else if (ups[i] > dps[0] && ups[i] < dps.back ())
         merge_possible = false;
       else if (dps[j] > ups[0] && dps[j] < ups.back ())
@@ -607,6 +609,7 @@ ADD_INTERFACE (Note_collision_interface,
                /* properties */
                "merge-differently-dotted "
                "merge-differently-headed "
+               "note-collision-threshold "
                "positioning-done "
                "prefer-dotted-right "
               );
index f0335c58d2efe34bf06ce608a651f8f272c5f67f..947a429c23f472770474dd10c9fb8abb8a4053e6 100644 (file)
@@ -552,6 +552,7 @@ Stem::calc_positioning_done (SCM smob)
     }
   bool parity = true;
   Real lastpos = Real (Staff_symbol_referencer::get_position (heads[0]));
+  int threshold = robust_scm2int (me->get_property ("note-collision-threshold"), 1);
   for (vsize i = 1; i < heads.size (); i++)
     {
       Real p = Staff_symbol_referencer::get_position (heads[i]);
@@ -561,7 +562,7 @@ Stem::calc_positioning_done (SCM smob)
         dy should always be 0.5, 0.0, 1.0, but provide safety margin
         for rounding errors.
       */
-      if (dy < 1.1)
+      if (dy < 0.1 + threshold)
         {
           if (parity)
             {
@@ -1184,6 +1185,7 @@ ADD_INTERFACE (Stem,
                "neutral-direction "
                "no-stem-extend "
                "note-heads "
+               "note-collision-threshold "
                "positioning-done "
                "rests "
                "stem-begin-position "
index 5017128901456d5f4f5521df8718852dbae200f8..d2e74a96a94473ecdb6bc8837bb43963f5662af1 100644 (file)
@@ -706,6 +706,11 @@ over the total spanner, where the width of the spanner is normalized
 between 0 and 1.")
      (note-names ,vector? "Vector of strings containing names for
 easy-notation note heads.")
+     (note-collision-threshold ,ly:dimension? "Simultaneous notes that
+are this close or closer in units of @code{staff-space} will be
+identified as vertically colliding. Used by @code{Stem} grobs for notes
+in the same voice, and @code{NoteCollision} grobs for notes in
+different voices. Default value@tie{}1.")
      (number-type ,symbol? "Numbering style. Choices include
 @code{roman-lower}, @code{roman-upper} and @code{arabic}.")
 
index 3528933f6836ac4f50d47234fb17c9fdeefc4884..971df383e92eacfbbe992bbcb5216a38e0774939 100644 (file)
     (NoteCollision
      . (
         (axes . (,X ,Y))
+        (note-collision-threshold . 1)
         (positioning-done . ,ly:note-collision-interface::calc-positioning-done)
         (prefer-dotted-right . #t)
         (X-extent . ,ly:axis-group-interface::width)
         (duration-log . ,stem::calc-duration-log)
         (length . ,(ly:make-unpure-pure-container ly:stem::calc-length ly:stem::pure-calc-length))
         (neutral-direction . ,DOWN)
+        (note-collision-threshold . 1)
         (positioning-done . ,ly:stem::calc-positioning-done)
         (stem-info . ,ly:stem::calc-stem-info)
         (stem-begin-position . ,(ly:make-unpure-pure-container ly:stem::calc-stem-begin-position ly:stem::pure-calc-stem-begin-position))