X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Frest-collision.cc;h=aaaa743fd1904ac9b3b538b75f28904fc0302ba8;hb=0119396bf047bbc0a6debd06f48e6d18573e2303;hp=f5605bc6677ba0d4d119dc3447f99a8ca1b852ac;hpb=5175fb07679b964a62202f6c900451e88d120f69;p=lilypond.git diff --git a/lily/rest-collision.cc b/lily/rest-collision.cc index f5605bc667..aaaa743fd1 100644 --- a/lily/rest-collision.cc +++ b/lily/rest-collision.cc @@ -3,7 +3,7 @@ source file of the GNU LilyPond music typesetter - (c) 1997--2000 Han-Wen Nienhuys + (c) 1997--2001 Han-Wen Nienhuys */ #include // ceil. @@ -19,47 +19,58 @@ #include "staff-symbol-referencer.hh" #include "duration.hh" -Real -Rest_collision::force_shift_callback (Score_element *them, Axis a) +MAKE_SCHEME_CALLBACK(Rest_collision,force_shift_callback,2); +SCM +Rest_collision::force_shift_callback (SCM element_smob, SCM axis) { + Grob *them = unsmob_grob (element_smob); + Axis a = (Axis) gh_scm2int (axis); assert (a == Y_AXIS); - Score_element * rc = unsmob_element (them->get_elt_property ("rest-collision")); + Grob * rc = unsmob_grob (them->get_grob_property ("rest-collision")); if (rc) { /* Done: destruct pointers, so we do the shift only once. */ - SCM elts = rc->get_elt_property ("elements"); - rc->set_elt_property ("elements", SCM_EOL); + SCM elts = rc->get_grob_property ("elements"); + rc->set_grob_property ("elements", SCM_EOL); do_shift (rc, elts); } - return 0.0; + return gh_double2scm (0.0); } void -Rest_collision::add_column (Score_element*me,Score_element *p) +Rest_collision::add_column (Grob*me,Grob *p) { me->add_dependency (p); - Pointer_group_interface gi (me); - gi.add_element (p); + Pointer_group_interface::add_element (me, "elements", p); + + /* + only add callback for the rests, since we don't move anything else. - p->add_offset_callback (&Rest_collision::force_shift_callback, Y_AXIS); - p->set_elt_property ("rest-collision", me->self_scm ()); + (not?) + */ + p->add_offset_callback (Rest_collision::force_shift_callback_proc, Y_AXIS); + p->set_grob_property ("rest-collision", me->self_scm ()); } + +/* + Combination of dot-count and duration-log. + */ static SCM -head_characteristic (Score_element * col) +head_characteristic (Grob * col) { - Score_element * s = unsmob_element (col->get_elt_property ("rest")); + Grob * s = unsmob_grob (col->get_grob_property ("rest")); if (!s) return SCM_BOOL_F; else - return gh_cons (s->get_elt_property ("duration-log"), + return gh_cons (s->get_grob_property ("duration-log"), gh_int2scm (Rhythmic_head::dot_count (s))); } @@ -67,18 +78,27 @@ head_characteristic (Score_element * col) TODO: fixme, fucks up if called twice on the same set of rests. */ SCM -Rest_collision::do_shift (Score_element *me, SCM elts) +Rest_collision::do_shift (Grob *me, SCM elts) { /* ugh. -> score elt type */ - Link_array rests; - Link_array notes; - + Link_array rests; + Link_array notes; + Grob * commony = 0; for (SCM s = elts; gh_pair_p (s); s = gh_cdr (s)) { - Score_element * e = unsmob_element (gh_car (s)); - if (e && unsmob_element (e->get_elt_property ("rest"))) + + Grob * e = unsmob_grob (gh_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 notes.push (e); @@ -105,11 +125,6 @@ Rest_collision::do_shift (Score_element *me, SCM elts) // meisjes met meisjes if (!notes.size()) { - - /* - FIXME: col2rhythmic_head and rhythmic_head2mom sucks bigtime. - - */ SCM characteristic = head_characteristic (rests[0]); int i = 1; for (; i < rests.size (); i++) @@ -125,14 +140,14 @@ Rest_collision::do_shift (Score_element *me, SCM elts) (urg: all 3 of them, currently). */ int display_count; - SCM s = me->get_elt_property ("maximum-rest-count"); + SCM s = me->get_grob_property ("maximum-rest-count"); if (i == rests.size () && gh_number_p (s) && gh_scm2int (s) < rests.size ()) { display_count = gh_scm2int (s); for (; i > display_count; i--) { - Score_element* r = unsmob_element (rests[i-1]->get_elt_property ("rest")); + Grob* r = unsmob_grob (rests[i-1]->get_grob_property ("rest")); if (r) r->suicide (); rests[i-1]->suicide (); @@ -142,13 +157,29 @@ Rest_collision::do_shift (Score_element *me, SCM elts) display_count = rests.size (); /* - UGH. Should get dims from table. Should have minimum dist. + Ugh. Should have minimum dist. + + Ugh. What do we do if we have three different rests? + */ - int dy = display_count > 2 ? 6 : 4; + int dy = display_count > 2 ? 6 : 4; // FIXME Should get dims from table. if (display_count > 1) { - Note_column::translate_rests (rests[0],dy); - Note_column::translate_rests (rests[1], -dy); + Direction d0 = Note_column::dir (rests[0]); + Direction d1 = Note_column::dir (rests[1]); + + if (!d0 && !d1) + { + d0= UP; + d1 = DOWN; + } + else if (!d0) + d0 = - d1; + else if (!d1) + d1 = -d0; + + Note_column::translate_rests (rests[0],d0 *dy); + Note_column::translate_rests (rests[1], d1 *dy); } } // meisjes met jongetjes @@ -162,22 +193,21 @@ Rest_collision::do_shift (Score_element *me, SCM elts) { warning (_("too many notes for rest collision")); } - Score_element * rcol = rests[0]; + Grob * rcol = rests[0]; // try to be opposite of noteheads. Direction dir = - Note_column::dir (notes[0]); - Interval restdim = Note_column::rest_dim (rcol); + Grob * r = unsmob_grob (rcol->get_grob_property ("rest")); + Interval restdim = r->extent (r, Y_AXIS); // ?? + if (restdim.empty_b ()) return SCM_UNSPECIFIED; - // staff ref'd? - Real staff_space = me->paper_l()->get_var ("interline"); + // FIXME: staff ref'd? + Real staff_space = 1.0; - /* FIXME - staff_space = rcol->rests[0]->staff_space (); - */ - Real minimum_dist = gh_scm2double (me->get_elt_property ("minimum-distance")) * staff_space; + Real minimum_dist = gh_scm2double (me->get_grob_property ("minimum-distance")) * staff_space; /* assumption: ref points are the same. @@ -185,7 +215,9 @@ Rest_collision::do_shift (Score_element *me, SCM elts) Interval notedim; for (int i = 0; i < notes.size(); i++) { - notedim.unite (notes[i]->extent (Y_AXIS)); + Grob * stem = Note_column::stem_l (notes[i]); + Grob * head = Stem::first_head (stem); + notedim.unite (head->extent (commony, Y_AXIS)); } Interval inter (notedim); @@ -214,9 +246,9 @@ Rest_collision::do_shift (Score_element *me, SCM elts) } void -Rest_collision::set_interface (Score_element*me) +Rest_collision::set_interface (Grob*me) { - me->set_extent_callback (0, X_AXIS); - me->set_extent_callback (0, Y_AXIS); + me->set_extent_callback (SCM_EOL, X_AXIS); + me->set_extent_callback (SCM_EOL, Y_AXIS); }