X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Frest-collision.cc;h=6a7eceecaba2586874b35c919319f024559528db;hb=d088cb4d9526a4a93e92bdf3d0b6cbb012883b6f;hp=f791015c8fa3211202213da28ca31f81d3865bb2;hpb=d9b43b93f2c885409bafdb157138158f65cc49aa;p=lilypond.git diff --git a/lily/rest-collision.cc b/lily/rest-collision.cc index f791015c8f..6a7eceecab 100644 --- a/lily/rest-collision.cc +++ b/lily/rest-collision.cc @@ -3,12 +3,12 @@ source file of the GNU LilyPond music typesetter - (c) 1997--2002 Han-Wen Nienhuys + (c) 1997--2003 Han-Wen Nienhuys */ #include // ceil. -#include "debug.hh" +#include "warn.hh" #include "rest-collision.hh" #include "note-column.hh" #include "stem.hh" @@ -29,15 +29,11 @@ Rest_collision::force_shift_callback (SCM element_smob, SCM axis) Grob * rc = unsmob_grob (them->get_grob_property ("rest-collision")); - if (rc) + if (rc && !to_boolean (rc->get_grob_property ("positioning-done"))) { - /* - Done: destruct pointers, so we do the shift only once. - */ - SCM elts = rc->get_grob_property ("elements"); - rc->set_grob_property ("elements", SCM_EOL); + rc->set_grob_property ("positioning-done", SCM_BOOL_T); - do_shift (rc, elts); + do_shift (rc); } return gh_double2scm (0.0); @@ -50,7 +46,8 @@ Rest_collision::add_column (Grob*me,Grob *p) Pointer_group_interface::add_grob (me, ly_symbol2scm ("elements"), p); /* - only add callback for the rests, since we don't move anything else. + only add callback for the rests, since we don't move anything + else. (not?) */ @@ -79,29 +76,21 @@ head_characteristic (Grob * col) TODO: look at horizontal-shift to determine ordering between rests for more than two voices. + + TODO: look at previous note to determine vertical position? */ SCM -Rest_collision::do_shift (Grob *me, SCM elts) +Rest_collision::do_shift (Grob *me) { - /* - ugh. -> score elt type - */ + SCM elts = me->get_grob_property ("elements"); + Link_array rests; Link_array notes; - Grob * commony = 0; + for (SCM s = elts; gh_pair_p (s); s = ly_cdr (s)) { - Grob * e = unsmob_grob (ly_car (s)); - if (!e) - continue; - - if (!commony) - commony = e; - else - commony= commony->common_refpoint (e, Y_AXIS); - if (unsmob_grob (e->get_grob_property ("rest"))) rests.push (e); else @@ -153,7 +142,12 @@ Rest_collision::do_shift (Grob *me, SCM elts) { Grob* r = unsmob_grob (rests[i-1]->get_grob_property ("rest")); if (r) - r->suicide (); + { + Grob * d = unsmob_grob (r->get_grob_property ("dot")); + if (d) + d->suicide(); + r->suicide (); + } rests[i-1]->suicide (); } } @@ -193,35 +187,31 @@ Rest_collision::do_shift (Grob *me, SCM elts) { warning (_ ("too many colliding rests")); } - if (notes.size () > 1) - { - warning (_ ("too many notes for rest collision")); - } Grob * rcol = rests[0]; + Direction dir = Note_column::dir (rests[0]); - // try to be opposite of noteheads. - Direction dir = - Note_column::dir (notes[0]); - + if (!dir) + { + dir = - Note_column::dir (notes[0]); + } Grob * r = unsmob_grob (rcol->get_grob_property ("rest")); Interval restdim = r->extent (r, Y_AXIS); // ?? - if (restdim.empty_b ()) + if (restdim.is_empty ()) return SCM_UNSPECIFIED; - // FIXME: staff ref'd? - Real staff_space = 1.0; + + Real staff_space = Staff_symbol_referencer::staff_space (rcol); Real minimum_dist = gh_scm2double (me->get_grob_property ("minimum-distance")) * staff_space; - - /* - assumption: ref points are the same. - */ + + + Grob *common = common_refpoint_of_array (notes, rcol, Y_AXIS); + Interval notedim; for (int i = 0; i < notes.size (); i++) { - Grob * stem = Note_column::stem_l (notes[i]); - Grob * head = Stem::first_head (stem); - notedim.unite (head->extent (commony, Y_AXIS)); + notedim.unite (notes[i]->extent (common, Y_AXIS)); } Interval inter (notedim); @@ -230,12 +220,12 @@ Rest_collision::do_shift (Grob *me, SCM elts) Real dist = minimum_dist + dir * (notedim[dir] - restdim[-dir]) >? 0; - - // FIXME - //int stafflines = 5; // rcol->rests[0]->line_count; int stafflines = Staff_symbol_referencer::line_count (me); - // hurg? - stafflines = stafflines != 0 ? stafflines : 5; + if (!stafflines) + { + programming_error ("No staff line count ? "); + stafflines =5; + } // move discretely by half spaces. int discrete_dist = int (ceil (dist / (0.5 *staff_space))); @@ -249,10 +239,9 @@ Rest_collision::do_shift (Grob *me, SCM elts) return SCM_UNSPECIFIED; } -void -Rest_collision::set_interface (Grob*me) -{ - me->set_extent_callback (SCM_EOL, X_AXIS); - me->set_extent_callback (SCM_EOL, Y_AXIS); -} + +ADD_INTERFACE (Rest_collision,"rest-collision-interface", + "Move around ordinary rests (not multi-measure-rests) to avoid " +"conflicts.", + "maximum-rest-count minimum-distance positioning-done elements");