X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Frest-collision.cc;h=e80e0d9cd751c57a7d59aa00d8b7a24191b8d436;hb=5cc390968095201b69f142ad01842ac3f08144a2;hp=a8f2b3ea907f7b2c151451c5bd418f0f549831dc;hpb=07a5ed85c189a97d04c550679826dfc5eca2eb18;p=lilypond.git diff --git a/lily/rest-collision.cc b/lily/rest-collision.cc index a8f2b3ea90..e80e0d9cd7 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--2000 Han-Wen Nienhuys + (c) 1997--2004 Han-Wen Nienhuys */ #include // ceil. -#include "debug.hh" +#include "warn.hh" #include "rest-collision.hh" #include "note-column.hh" #include "stem.hh" @@ -19,7 +19,7 @@ #include "staff-symbol-referencer.hh" #include "duration.hh" -MAKE_SCHEME_CALLBACK(Rest_collision,force_shift_callback,2); +MAKE_SCHEME_CALLBACK (Rest_collision,force_shift_callback,2); SCM Rest_collision::force_shift_callback (SCM element_smob, SCM axis) { @@ -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); @@ -47,15 +43,16 @@ void Rest_collision::add_column (Grob*me,Grob *p) { me->add_dependency (p); - Pointer_group_interface::add_element (me, "elements", 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?) + (not?) */ - p->add_offset_callback (Rest_collision::force_shift_callback_proc, Y_AXIS); - p->set_grob_property ("rest-collision", me->self_scm ()); + p->add_offset_callback (Rest_collision::force_shift_callback_proc, Y_AXIS); + p->set_grob_property ("rest-collision", me->self_scm ()); } @@ -76,28 +73,24 @@ head_characteristic (Grob * col) /* TODO: fixme, fucks up if called twice on the same set of rests. + + 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 = gh_cdr (s)) + + for (SCM s = elts; gh_pair_p (s); s = ly_cdr (s)) { - - Grob * e = unsmob_grob (gh_car (s)); - if (!e) - continue; - - if (!commony) - commony = e; - else - commony= commony->common_refpoint (e, Y_AXIS); - + Grob * e = unsmob_grob (ly_car (s)); if (unsmob_grob (e->get_grob_property ("rest"))) rests.push (e); else @@ -115,21 +108,27 @@ Rest_collision::do_shift (Grob *me, SCM elts) */ // no rests to collide - if (!rests.size()) + if (!rests.size ()) return SCM_UNSPECIFIED; // no partners to collide with - if (rests.size() + notes.size () < 2) - return SCM_UNSPECIFIED; - + if (rests.size () + notes.size () < 2) + { + if (rests.size () == 1 + && Note_column::dir (rests[0])) + { + Note_column::translate_rests (rests[0], + 4 * Note_column::dir (rests[0])); + } + } // meisjes met meisjes - if (!notes.size()) + if (!notes.size ()) { - SCM characteristic = head_characteristic (rests[0]); + SCM characteristic = head_characteristic (rests[0]); int i = 1; for (; i < rests.size (); i++) { - if (!gh_equal_p (head_characteristic (rests[i]), characteristic)) + if (!gh_equal_p (head_characteristic (rests[i]), characteristic)) break; } @@ -137,7 +136,7 @@ Rest_collision::do_shift (Grob *me, SCM elts) If all durations are the same, we'll check if there are more rests than maximum-rest-count. Otherwise (different durations), we'll try to display them all - (urg: all 3 of them, currently). + (urg: all 3 of them, currently). */ int display_count; SCM s = me->get_grob_property ("maximum-rest-count"); @@ -149,7 +148,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 (); } } @@ -187,37 +191,33 @@ Rest_collision::do_shift (Grob *me, SCM elts) { if (rests.size () > 1) { - warning (_("too many colliding rests")); - } - if (notes.size () > 1) - { - warning (_("too many notes for rest collision")); + warning (_ ("too many colliding rests")); } 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 minimum_dist = gh_scm2double (me->get_grob_property ("minimum-distance")) * staff_space; - - /* - assumption: ref points are the same. - */ + Real staff_space = Staff_symbol_referencer::staff_space (rcol); + + Real minimum_dist = robust_scm2double (me->get_grob_property ("minimum-distance"), 1.0) * staff_space; + + + Grob *common = common_refpoint_of_array (notes, rcol, Y_AXIS); + Interval notedim; - for (int i = 0; i < notes.size(); i++) + 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); @@ -226,12 +226,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))); @@ -245,10 +245,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");