X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Frest-collision.cc;h=52c0149bcee8559fdebc2fa2ea1cb657c87cd3ce;hb=875cf3061b68867a109cdaf52c93be868a3e01be;hp=7b3da49d41f6ed2eb4c85a42a5a48c9ff7875ef8;hpb=48bdd9154a32245a075494b403639181615864e2;p=lilypond.git diff --git a/lily/rest-collision.cc b/lily/rest-collision.cc index 7b3da49d41..52c0149bce 100644 --- a/lily/rest-collision.cc +++ b/lily/rest-collision.cc @@ -3,135 +3,115 @@ source file of the GNU LilyPond music typesetter - (c) 1997 Han-Wen Nienhuys + (c) 1997--1999 Han-Wen Nienhuys */ - +#include "beam.hh" #include "debug.hh" #include "rest-collision.hh" -#include "rest-column.hh" #include "note-column.hh" #include "stem.hh" #include "note-head.hh" #include "collision.hh" #include "paper-def.hh" - - -IMPLEMENT_IS_TYPE_B1(Rest_collision,Item); +#include "rest.hh" void -Rest_collision::add(Note_column *nc_l) +Rest_collision::add_column (Note_column *nc_l) { - add_dependency(nc_l); - ncol_l_arr_.push(nc_l); + add_dependency (nc_l); + if (nc_l->rest_b ()) + rest_l_arr_.push (nc_l); + else + ncol_l_arr_.push (nc_l); } void -Rest_collision::add(Rest_column *rc_l) +Rest_collision::do_pre_processing() { - add_dependency(rc_l); - rest_l_arr_.push(rc_l); -} + /* + handle rest-rest and rest-note collisions + + [todo] + * decide not to print rest if too crowded? + + * ignore rests under beams. + */ + + // no rests to collide + if (!rest_l_arr_.size()) + return; + + // no partners to collide with + if (rest_l_arr_.size() + ncol_l_arr_.size () < 2) + return; + + // meisjes met meisjes + if (!ncol_l_arr_.size()) + { + /* + UGH. Should get dims from table. Should have minimum dist. + */ + int dy = rest_l_arr_.size() > 2 ? 6 : 4; + + rest_l_arr_[0]->translate_rests (rest_l_arr_[0]->dir () *dy); + rest_l_arr_.top()->translate_rests (rest_l_arr_.top ()->dir ()* dy); + } + // meisjes met jongetjes + else + { + if (rest_l_arr_.size () > 1) + { + warning (_("too many colliding rests")); + } + if (ncol_l_arr_.size () > 1) + { + warning (_("too many notes for rest collision")); + } + Note_column * rcol = rest_l_arr_[0]; -void -Rest_collision::add(Collision * c_l) -{ - add_dependency(c_l); - for (int i=0; i < c_l->clash_l_arr_.size(); i ++) - ncol_l_arr_.push(c_l->clash_l_arr_[i]); -} + // try to be opposite of noteheads. + Direction dir = - ncol_l_arr_[0]->dir(); -void -Rest_collision::do_post_processing() -{ - /* - handle rest under beam (do_post: beams are calculated now) - - [todo] - i-d like to have access to the beam itself, - iso only the (half-initialised?) stem - - what about combination of collisions and rest under beam - */ - - // no rests to collide - if (!rest_l_arr_.size()) - return; - // can this happen? - Stem* stem_l = rest_l_arr_[0]->stem_l_; - if (!stem_l) - return; - // no beam - if (!(stem_l->beams_left_i_ || stem_l->beams_right_i_)) - return; - - int dir_i = rest_l_arr_[0]->dir_i_; - int midpos = 4; -#if 1 - // ugh - int stem_length_i = 7 - 2; - // ugh, Stem::stem_start vs Stem::stem_end - int pos = (stem_l->stem_end_f() - midpos) - dir_i * stem_length_i; -#else // nogo: stem_start not set for rests? - int pos = (stem_l->stem_start_f() - midpos) + dir_i * 2; -#endif - rest_l_arr_[0]->translate_heads(pos); -} + Interval restdim; + for (int i=0; i < rcol->rest_l_arr_.size(); i++) + restdim.unite (rcol->rest_l_arr_[i]->extent (Y_AXIS)); -void -Rest_collision::do_pre_processing() -{ - /* - handle rest-rest and rest-note collisions + if (restdim.empty_b ()) + return; + + // staff ref'd? + Real staff_space = rcol->rest_l_arr_[0]->staff_line_leading_f (); + Real internote_f = staff_space/2; + Real minimum_dist = paper_l ()->get_var ("restcollision_minimum_dist") + * internote_f; + + /* + assumption: ref points are the same. + */ + Interval notedim; + for (int i = 0; i < ncol_l_arr_.size(); i++) + { + notedim.unite (ncol_l_arr_[i]->extent (Y_AXIS)); + } - [todo] - decide not to print rest if too crowded? - */ + Interval inter (notedim); + inter.intersect (restdim); - // no rests to collide - if (!rest_l_arr_.size()) - return; + Real dist = + minimum_dist + dir * (notedim[dir] - restdim[-dir]) >? 0; - // no partners to collide with - if (rest_l_arr_.size() + ncol_l_arr_.size() < 2 ) - return; - // meisjes met meisjes - if (!ncol_l_arr_.size()) { - int dy = rest_l_arr_.size() > 2 ? 6 : 4; - - rest_l_arr_[0]->translate_heads(rest_l_arr_[0]->dir_i_ *dy); - // top is last element... - rest_l_arr_.top()->translate_heads(rest_l_arr_.top()->dir_i_* dy); - } - // meisjes met jongetjes - else { -#if 0 // breendet: rests go always under - // geen gemug, trug op je rug - int dir_i = -1; - rest_l_arr_[0]->translate_heads(dir_i * 3 ); -#else - // int dir_i = - ncol_l_arr_[0]->dir_i_; - int dir_i = rest_l_arr_[0]->dir_i_; - // hope it's 4: if it works->doco - int midpos = 4; - - // minimum move - int minpos = 4; - - // quart rest height - // UGH Should get dims from table! - int size_i = 6; - - int sep_i = 3 + size_i / 2; - for (int i = 0; i < ncol_l_arr_.size(); i++) { - // how to know whether to sort? - ncol_l_arr_[i]->sort(); - for ( int j = 0; j < ncol_l_arr_[i]->head_l_arr_.size(); j++ ) - minpos = minpos >? dir_i * - (ncol_l_arr_[i]->head_l_arr_[j]->position_i_ -midpos ) + sep_i; - } - rest_l_arr_[0]->translate_heads(dir_i * minpos ); -#endif + int stafflines = rcol->rest_l_arr_[0]->lines_i (); + + + // move discretely by half spaces. + int discrete_dist = int (ceil (dist / (0.5 *staff_space))); + + // move by whole spaces inside the staff. + if (discrete_dist < stafflines+1) + discrete_dist = int (ceil (discrete_dist / 2.0)* 2.0); + + rcol->translate_rests (dir * discrete_dist); } } @@ -139,23 +119,25 @@ void Rest_collision::do_print() const { #ifndef NPRINT - mtor << "rests: " << rest_l_arr_.size() << ", "; - mtor << "cols: " << ncol_l_arr_.size(); + DEBUG_OUT << "rests: " << rest_l_arr_.size() << ", "; + DEBUG_OUT << "cols: " << ncol_l_arr_.size(); #endif } void -Rest_collision::do_substitute_dependency(Score_elem*o,Score_elem*n) +Rest_collision::do_substitute_element_pointer (Score_element*o,Score_element*n) { - Item*o_l = o->item(); - Item*n_l = n?n->item():0; - - rest_l_arr_.substitute((Rest_column*)o_l,(Rest_column*)n_l); - ncol_l_arr_.substitute((Note_column*)o_l,(Note_column*)n_l); + if (Note_column *onl = dynamic_cast (o)) + { + Note_column *n_l = n?dynamic_cast (n):0; + rest_l_arr_.substitute (onl, n_l); + ncol_l_arr_.substitute (onl, n_l); + } } Rest_collision::Rest_collision() { - transparent_b_ = true; - empty_b_ = true; + set_elt_property ("transparent", SCM_BOOL_T); + set_empty (true, X_AXIS, Y_AXIS); } +