#include "output-def.hh"
#include "pointer-group-interface.hh"
#include "rhythmic-head.hh"
+#include "staff-symbol-referencer.hh"
#include "side-position-interface.hh"
#include "stem.hh"
#include "warn.hh"
if (!Note_column::get_stem (cu) || !Note_column::get_stem (cd))
return;
+ Drul_array<Grob*> stems (Note_column::get_stem (cd),
+ Note_column::get_stem (cu));
+
Grob *nu = Note_column::first_head (cu);
Grob *nd = Note_column::first_head (cd);
if (ups[0] > dps.back () + 1)
return;
- // FIXME: what's this?
+ /* Merge heads if the notes lie the same line, or if the "stem-up-note" is
+ above the "stem-down-note". */
bool merge_possible = (ups[0] >= dps[0]) && (ups.back () >= dps.back ());
/* Do not merge notes typeset in different style. */
nd->get_property ("style")))
merge_possible = false;
- int upball_type = Note_head::get_balltype (nu);
- int dnball_type = Note_head::get_balltype (nd);
+ int upball_type = Rhythmic_head::duration_log (nu);
+ int dnball_type = Rhythmic_head::duration_log (nd);
/* Do not merge whole notes (or longer, like breve, longa, maxima). */
if (merge_possible && (upball_type <= 0 || dnball_type <= 0))
/* Should never merge quarter and half notes, as this would make
them indistinguishable. */
if (merge_possible
- && ((Rhythmic_head::duration_log (nu) == 1
- && Rhythmic_head::duration_log (nd) == 2)
- || (Rhythmic_head::duration_log (nu) == 2
- && Rhythmic_head::duration_log (nd) == 1)))
+ && ((Stem::duration_log (stems[UP]) == 1
+ && Stem::duration_log (stems[DOWN]) == 2)
+ || (Stem::duration_log (stems[UP]) == 2
+ && Stem::duration_log (stems[DOWN]) == 1)))
merge_possible = false;
/*
else
shift_amount *= 0.17;
+ /*
+ * Fix issue #44:
+ *
+ * Dots from left note head collide with right note head. Only occurs
+ * with a close half collide, if the left note head is between
+ * lines and the right note head is on a line, and if right note head
+ * hasn't got any dots.
+ */
+ if (close_half_collide
+ && Rhythmic_head::dot_count (nu)
+ && !Rhythmic_head::dot_count (nd))
+ {
+ Grob *staff = Staff_symbol_referencer::get_staff_symbol (me);
+ if (!Staff_symbol_referencer::on_line (staff, ups[0]))
+ {
+ Grob *d = unsmob_grob (nu->get_object ("dot"));
+ Grob *parent = d->get_parent (X_AXIS);
+ if (Dot_column::has_interface (parent))
+ Side_position_interface::add_support (parent, nd);
+ }
+ }
+
/* For full or close half collisions, the right hand head may
obscure dots. Move dots to the right. */
if (abs (shift_amount) > 1e-6
if (cg[d].size ())
{
Grob *h = cg[d][0];
- wid = Note_column::first_head (h)->extent (h, X_AXIS).length ();
+ Grob *fh = Note_column::first_head (h);
+ if (fh)
+ wid = fh->extent (h, X_AXIS).length ();
}
}
while (flip (&d) != UP);
{
Grob *se = elements[i];
if (Note_column::has_interface (se))
- clash_groups[Note_column::dir (se)].push_back (se);
+ {
+ if (!Note_column::dir (se))
+ {
+ se->programming_error ("note-column has no direction");
+ }
+ else
+ clash_groups[Note_column::dir (se)].push_back (se);
+ }
}
Direction d = UP;
do
{
vector<Grob*> &clashes (clash_groups[d]);
- vector_sort (clashes, Note_column::shift_compare);
+ vector_sort (clashes, Note_column::shift_less);
}
while ((flip (&d)) != UP);
/* properties */
"merge-differently-dotted "
"merge-differently-headed "
- "positioning-done");
+ "positioning-done ");