X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fnote-collision.cc;h=d93260afd624419ce48d11761f0064cc927bf8b1;hb=3dd7c6f29c9ca494976f69736b470b6300135099;hp=894f16071fa5d5e76e0d2101ffe4a897e47c13b3;hpb=9d9e2e5637e06d98245c3395b58207ec173e7e7d;p=lilypond.git diff --git a/lily/note-collision.cc b/lily/note-collision.cc index 894f16071f..d93260afd6 100644 --- a/lily/note-collision.cc +++ b/lily/note-collision.cc @@ -1,9 +1,9 @@ /* - collision.cc -- implement Collision + note-collision.cc -- implement Note_collision source file of the GNU LilyPond music typesetter - (c) 1997--2007 Han-Wen Nienhuys + (c) 1997--2009 Han-Wen Nienhuys */ #include "note-collision.hh" @@ -30,7 +30,7 @@ check_meshing_chords (Grob *me, Drul_array > const &clash_groups) { - if (!extents[UP].size () || ! extents[DOWN].size ()) + if (!extents[UP].size () || !extents[DOWN].size ()) return; Grob *clash_up = clash_groups[UP][0]; @@ -49,7 +49,7 @@ check_meshing_chords (Grob *me, vector ups = Stem::note_head_positions (Note_column::get_stem (clash_up)); vector dps = Stem::note_head_positions (Note_column::get_stem (clash_down)); - /* Too far apart to collide. */ + /* Too far apart to collide. */ if (ups[0] > dps.back () + 1) return; @@ -65,7 +65,7 @@ check_meshing_chords (Grob *me, int up_ball_type = Rhythmic_head::duration_log (head_up); int down_ball_type = Rhythmic_head::duration_log (head_down); - /* Do not merge whole notes (or longer, like breve, longa, maxima). */ + /* Do not merge whole notes (or longer, like breve, longa, maxima). */ if (merge_possible && (up_ball_type <= 0 || down_ball_type <= 0)) merge_possible = false; @@ -74,8 +74,7 @@ check_meshing_chords (Grob *me, && !to_boolean (me->get_property ("merge-differently-dotted"))) merge_possible = false; - /* Can only merge different heads if merge-differently-headed is - set. */ + /* Can only merge different heads if merge-differently-headed is set. */ if (merge_possible && up_ball_type != down_ball_type && !to_boolean (me->get_property ("merge-differently-headed"))) @@ -154,18 +153,21 @@ check_meshing_chords (Grob *me, full_collide = full_collide || (close_half_collide && distant_half_collide); - Drul_array center_note_shifts; - center_note_shifts[LEFT] = 0.0; - center_note_shifts[RIGHT] = 0.0; - 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; /* For full collisions, the right hand head may obscure dots, so - make sure the dotted heads go to the right. */ + make sure the dotted heads go to the right. */ bool stem_to_stem = false; if (full_collide) { @@ -176,7 +178,7 @@ check_meshing_chords (Grob *me, } /* The solfa is a triangle, which is inverted depending on stem - direction. In case of a collision, one of them should be removed, + 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 @@ -193,7 +195,7 @@ check_meshing_chords (Grob *me, { shift_amount = 0; - /* If possible, don't wipe any heads. Else, wipe shortest head, + /* If possible, don't wipe any heads. Else, wipe shortest head, or head with smallest amount of dots. Note: when merging different heads, dots on the smaller one disappear. */ Grob *wipe_ball = 0; @@ -223,6 +225,15 @@ check_meshing_chords (Grob *me, { wipe_ball = head_up; dot_wipe_head = head_up; + /* + If upper head is eighth note or shorter, and lower head is half note, + shift by the difference between the open and filled note head widths, + otherwise upper stem will be misaligned slightly. + */ + if (Stem::duration_log (stems[DOWN]) == 1 + && Stem::duration_log (stems[UP]) >= 3) + shift_amount = (1 - head_up->extent (head_up, X_AXIS).length () / + head_down->extent (head_down, X_AXIS).length ()) * 0.5; } if (dot_wipe_head) @@ -232,12 +243,10 @@ check_meshing_chords (Grob *me, } if (wipe_ball && wipe_ball->is_live ()) - { - wipe_ball->set_property ("transparent", SCM_BOOL_T); - } + wipe_ball->set_property ("transparent", SCM_BOOL_T); } /* TODO: these numbers are magic; should devise a set of grob props - to tune this behavior. */ + to tune this behavior. */ else if (stem_to_stem) shift_amount = -abs (shift_amount) * 0.65; else if (close_half_collide && !touch) @@ -247,7 +256,7 @@ check_meshing_chords (Grob *me, else if (distant_half_collide || close_half_collide || full_collide) shift_amount *= 0.5; - /* we're meshing. */ + /* we're meshing. */ else if (Rhythmic_head::dot_count (head_up) || Rhythmic_head::dot_count (head_down)) shift_amount *= 0.1; else @@ -283,24 +292,24 @@ check_meshing_chords (Grob *me, { Grob *staff = Staff_symbol_referencer::get_staff_symbol (me); if (!Staff_symbol_referencer::on_line (staff, ups[0])) - /* - TODO: consider junking the else body. - */ - if (to_boolean (me->get_property ("prefer-dotted-right"))) - { + { + /* + 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); - } + 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 - obscure dots. Move dots to the right. */ + obscure dots. Move dots to the right. */ if (abs (shift_amount) > 1e-6 && Rhythmic_head::dot_count (head_down) > Rhythmic_head::dot_count (head_up) && (full_collide || close_half_collide)) @@ -354,7 +363,7 @@ Note_collision_interface::calc_positioning_done (SCM smob) { /* Trigger positioning - */ + */ clash_groups[d][i]->extent (me, X_AXIS); } } @@ -423,9 +432,7 @@ Note_collision_interface::get_clash_groups (Grob *me) if (Note_column::has_interface (se)) { if (!Note_column::dir (se)) - { - se->programming_error ("note-column has no direction"); - } + se->programming_error ("note-column has no direction"); else clash_groups[Note_column::dir (se)].push_back (se); } @@ -442,9 +449,9 @@ Note_collision_interface::get_clash_groups (Grob *me) return clash_groups; } -/** This complicated routine moves note columns around horizontally to - ensure that notes don't clash. - +/* + This complicated routine moves note columns around horizontally to + ensure that notes don't clash. */ SCM Note_collision_interface::automatic_shift (Grob *me, @@ -523,7 +530,7 @@ Note_collision_interface::automatic_shift (Grob *me, /* see input/regression/dot-up-voice-collision.ly - */ + */ for (vsize i = 0; i < clash_groups[UP].size (); i++) { Grob *g = clash_groups[UP][i]; @@ -567,10 +574,8 @@ Note_collision_interface::forced_shift (Grob *me) SCM force = se->get_property ("force-hshift"); if (scm_is_number (force)) - { - tups = scm_cons (scm_cons (se->self_scm (), force), - tups); - } + tups = scm_cons (scm_cons (se->self_scm (), force), + tups); } return tups; }