]> git.donarmstrong.com Git - lilypond.git/commitdiff
Extracts Accidentals for AccidentalPlacements in the side-position-interface.
authorMike Solomon <mike@apollinemike.com>
Wed, 29 Aug 2012 08:06:36 +0000 (10:06 +0200)
committerMike Solomon <mike@apollinemike.com>
Wed, 29 Aug 2012 08:06:36 +0000 (10:06 +0200)
Because AccidentalPlacements have no height, this makes sure that all
accidentals are accounted for in case an engraver missed them.

input/regression/accidental-fingering-collision.ly [new file with mode: 0644]
lily/grob.cc
lily/include/grob.hh
lily/side-position-interface.cc

diff --git a/input/regression/accidental-fingering-collision.ly b/input/regression/accidental-fingering-collision.ly
new file mode 100644 (file)
index 0000000..ac7a07e
--- /dev/null
@@ -0,0 +1,13 @@
+\version "2.17.0"
+
+\header {
+  texidoc = "Horizontal @code{Fingering} grobs should not collide with
+accidentals.
+"
+}
+
+\relative c' {
+  \time 2/4
+  \set fingeringOrientations = #'(left)
+  <a-3 cis-4> <a-3 cis!-4> |
+}
\ No newline at end of file
index 593b0814a64070a20c83b4dc7c0f2146986f93db..9edf8a2f8a88ff4da6a7c1f260ee947ce7e44453 100644 (file)
@@ -20,6 +20,7 @@
 #include "grob.hh"
 
 #include <cstring>
+#include <set>
 
 #include "align-interface.hh"
 #include "axis-group-interface.hh"
@@ -910,6 +911,20 @@ common_refpoint_of_array (vector<Grob *> const &arr, Grob *common, Axis a)
   return common;
 }
 
+Grob *
+common_refpoint_of_array (set<Grob *> const &arr, Grob *common, Axis a)
+{
+  set<Grob *>::iterator it;
+
+  for (it = arr.begin (); it != arr.end (); it++)
+    if (common)
+      common = common->common_refpoint (*it, a);
+    else
+      common = *it;
+
+  return common;
+}
+
 Interval
 robust_relative_extent (Grob *me, Grob *refpoint, Axis a)
 {
index 14a7b4792509e1021fc7d87d1b8d3237572c29f5..09cd566ad335b39708990d05ab74894ff2099af1 100644 (file)
@@ -25,6 +25,8 @@
 #include "dimension-cache.hh"
 #include "grob-interface.hh"
 
+#include <set>
+
 class Grob
 {
 private:
@@ -171,6 +173,7 @@ Item *unsmob_item (SCM);
 /* refpoints */
 Grob *common_refpoint_of_list (SCM elt_list, Grob *, Axis a);
 Grob *common_refpoint_of_array (vector<Grob *> const &, Grob *, Axis a);
+Grob *common_refpoint_of_array (set<Grob *> const &, Grob *, Axis a);
 System *get_root_system (Grob *me);
 
 /* extents */
index 75104e44b9fb512de3b51482acefda7fcef25df7..5a0d16606c9faa6eecbd406b98641e061156f9b7 100644 (file)
 
 #include <cmath>                // ceil.
 #include <algorithm>
+#include <set>
 #include <map>
 
 using namespace std;
 
 #include "accidental-interface.hh"
+#include "accidental-placement.hh"
 #include "axis-group-interface.hh"
 #include "directional-element-interface.hh"
 #include "grob.hh"
@@ -80,6 +82,34 @@ finish_offset (Grob *me, Direction dir, Real total_off, Real *current_offset)
   return scm_from_double (total_off);
 }
 
+set<Grob *>
+get_support_set (Grob *me)
+{
+  // Only slightly kludgy heuristic...
+  // We want to make sure that all AccidentalPlacements'
+  // accidentals make it into the side support
+  extract_grob_set (me, "side-support-elements", proto_support);
+  set<Grob *> support;
+
+  for (vsize i = 0; i < proto_support.size (); i++)
+    {
+      if (Accidental_placement::has_interface (proto_support[i]))
+        {
+          Grob *accs = proto_support[i];
+          for (SCM acs = accs->get_object ("accidental-grobs"); scm_is_pair (acs);
+               acs = scm_cdr (acs))
+            for (SCM s = scm_cdar (acs); scm_is_pair (s); s = scm_cdr (s))
+              {
+                Grob *a = unsmob_grob (scm_car (s));
+                support.insert (a);
+              }
+        }
+      else
+        support.insert (proto_support[i]);
+    }
+  return support;
+}
+
 /* Put the element next to the support, optionally taking in
    account the extent of the support.
 
@@ -91,7 +121,7 @@ Side_position_interface::general_side_position (Grob *me, Axis a, bool use_exten
                                                 bool pure, int start, int end,
                                                 Real *current_offset)
 {
-  extract_grob_set (me, "side-support-elements", support);
+  set<Grob *> support = get_support_set (me);
 
   Grob *common = common_refpoint_of_array (support, me->get_parent (a), a);
   Grob *staff_symbol = Staff_symbol_referencer::get_staff_symbol (me);
@@ -114,9 +144,11 @@ Side_position_interface::general_side_position (Grob *me, Axis a, bool use_exten
 
   Direction dir = get_grob_direction (me);
 
-  for (vsize i = 0; i < support.size (); i++)
+  set<Grob *>::iterator it;
+
+  for (it = support.begin (); it != support.end (); it++)
     {
-      Grob *e = support[i];
+      Grob *e = *it;
 
       // In the case of a stem, we will find a note head as well
       // ignoring the stem solves cyclic dependencies if the stem is
@@ -166,7 +198,7 @@ Side_position_interface::skyline_side_position (Grob *me, Axis a,
                                                 bool pure, int start, int end,
                                                 Real *current_offset)
 {
-  extract_grob_set (me, "side-support-elements", support);
+  set<Grob *> support = get_support_set (me);
 
   Grob *common[2];
   for (Axis ax = X_AXIS; ax < NO_AXES; incr (ax))
@@ -210,10 +242,12 @@ Side_position_interface::skyline_side_position (Grob *me, Axis a,
   vector<Box> boxes;
   vector<Skyline_pair> skyps;
   Real min_h = dir == LEFT ? infinity_f : -infinity_f;
+  set<Grob *>::iterator it;
+
   map<Grob *, vector<Grob *> > note_column_map; // for parts of a note column
-  for (vsize i = 0; i < support.size (); i++)
+  for (it = support.begin (); it != support.end (); it++)
     {
-      Grob *e = support[i];
+      Grob *e = *it;
 
       // In the case of a stem, we will find a note head as well
       // ignoring the stem solves cyclic dependencies if the stem is