+ // If in a chord, remove dots which have vertical positions above or below
+ // the topmost or bottommost note, respectively ([Gould], p. 56).
+ // Note that a dot configuration can contain more than a single chord or
+ // rest (the latter gets ignored).
+ //
+ // The dot positioning algorithm vertically shifts dots; it thus can
+ // happen that, say, a dot of the upper voice's chord is positioned
+ // beneath a note head of the lower voice's chord, while the dots of the
+ // lower voice's chord are shifted down even more. We thus check all
+ // vertical ranges for valid positions and not only the range of the dot's
+ // parent chord.
+ //
+ // Do nothing if there is either no staff line, or no note head, or the
+ // `chord-dots' property not set.
+ Grob *st = Staff_symbol_referencer::get_staff_symbol (me);
+ vsize num_positions = allowed_y_positions.size ();
+ bool chord_dots = to_boolean (me->get_property ("chord-dots"));
+
+ if (st && num_positions && chord_dots)
+ {
+ for (Dot_configuration::const_iterator i (cfg.begin ());
+ i != cfg.end (); i++)
+ {
+ vsize j;
+
+ for (j = 0; j < num_positions; j++)
+ if (allowed_y_positions[j].contains (i->first))
+ break;
+
+ if (j == num_positions)
+ {
+ Grob *dot = i->second.dot_;
+ Grob *n = dot->get_parent (Y_AXIS);
+ if (n && Note_head::has_interface (n))
+ dot->suicide ();
+ }
+ }
+ }
+