X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fnote-column.cc;h=c5c8dfca3394cd8bb3c936a6ed88182d44c7f5e8;hb=da7dbf5f2f54bc66984ab2524c490335d567b5e7;hp=9dbc4f93ddd454294c9929d5bf0e82cc3d60e290;hpb=c2eeafc72b47697c1b01530952875521a1f0dc81;p=lilypond.git diff --git a/lily/note-column.cc b/lily/note-column.cc index 9dbc4f93dd..c5c8dfca33 100644 --- a/lily/note-column.cc +++ b/lily/note-column.cc @@ -1,162 +1,185 @@ /* note-column.cc -- implement Note_column - source file of the LilyPond music typesetter + source file of the GNU LilyPond music typesetter - (c) 1997 Han-Wen Nienhuys + (c) 1997--1999 Han-Wen Nienhuys */ - +#include "dot-column.hh" #include "note-column.hh" -#include "debug.hh" -#include "script.hh" -#include "notehead.hh" +#include "beam.hh" +#include "note-head.hh" #include "stem.hh" +#include "rest.hh" +#include "debug.hh" +#include "paper-def.hh" -IMPLEMENT_STATIC_NAME(Note_column); - - -void -Note_column::add(Stem*stem_l) +bool +Note_column::rest_b () const { - assert(!stem_l_); - stem_l_ = stem_l; - add_dependency(stem_l); + return rest_l_arr_.size (); } -void -Note_column::add(Notehead* n_l) +int +Note_column::shift_compare (Note_column *const &p1, Note_column*const&p2) { - if (head_l_arr_.size()){ - if (n_l->rest_b_ != rest_b_) return; // ugly fix. Should think about integrating rests into colunms. - } else - rest_b_ = n_l->rest_b_; - - head_l_arr_.push(n_l); - add_dependency(n_l); + SCM s1 = p1->get_elt_property (horizontal_shift_scm_sym); + SCM s2 = p2->get_elt_property (horizontal_shift_scm_sym); + + int h1 = (s1 == SCM_BOOL_F) ? 0 : gh_scm2int (SCM_CDR(s1)); + int h2 = (s2 == SCM_BOOL_F) ? 0 : gh_scm2int (SCM_CDR(s2)); + return h1 - h2; } -void -Note_column::add(Script*s_l) +Note_column::Note_column() { - script_l_arr_.push(s_l); - add_dependency(s_l); + set_axes (X_AXIS,X_AXIS); + stem_l_ = 0; } void -Note_column::translate(Offset o) +Note_column::sort() { - for (int i=0; i < head_l_arr_.size(); i++) - head_l_arr_[i]->translate(o); - for (int i=0; i < script_l_arr_.size(); i++) - script_l_arr_[i]->translate(o); - if (stem_l_) - stem_l_->translate(o); + head_l_arr_.sort (Note_head::compare); } - - -void -Note_column::do_print()const + +Slice +Note_column::head_positions_interval() const { - mtor << "heads: " << head_l_arr_.size() << '\n'; - mtor << "scripts: " << script_l_arr_.size() << '\n'; + Slice iv; + + iv.set_empty (); + for (int i=0; i position_i_; + iv.unite (Slice (j,j)); + } + return iv; } -Interval -Note_column::do_height()const return r +Direction +Note_column::dir () const { - if (stem_l_) - r.unite(stem_l_->height()); - for (int i=0; i < head_l_arr_.size(); i++) - r.unite(head_l_arr_[i]->height()); - for (int i=0; i < script_l_arr_.size(); i++) - r.unite(script_l_arr_[i]->height()); + if (stem_l_) + return stem_l_->dir_; + else if (head_l_arr_.size ()) + return sign (head_positions_interval().center ()); + + programming_error ("Note column without heads and stem!"); + return CENTER; } -Interval -Note_column::do_width()const return r; + +void +Note_column::set_stem (Stem * stem_l) { - if (stem_l_) - r.unite(stem_l_->width()); - for (int i=0; i < head_l_arr_.size(); i++) - r.unite(head_l_arr_[i]->width()); - for (int i=0; i < script_l_arr_.size(); i++) - r.unite(script_l_arr_[i]->width()); + stem_l_ = stem_l; + add_dependency (stem_l); + add_element (stem_l); } + void -Note_column::do_pre_processing() +Note_column::do_substitute_element_pointer (Score_element*o, Score_element*n) { - if (stem_l_ && !dir_i_) - dir_i_ = stem_l_->dir_i_; - - if (!script_l_arr_.size()) - return; - - Array placed_l_arr_a[4]; - for (int i=0; i < script_l_arr_.size(); i++) { - Script*s_l = script_l_arr_[i]; - int j = (s_l->dir_i_ >0) ? 0 : 2; - if (!s_l->inside_staff_b_) - j ++; - - placed_l_arr_a[j].push(s_l); + if (stem_l_ == o) + { + stem_l_ = n ? dynamic_cast (n):0; } - for (int j =0; j <4; j++) { - placed_l_arr_a[j].sort( Script::compare); + if (dynamic_cast (o)) + { + head_l_arr_.substitute (dynamic_cast (o), + (n)? dynamic_cast (n) : 0); } - - Notehead *top_head_l=0; - Notehead *bot_head_l=0; - for (int i=0; i< head_l_arr_.size(); i++) { - if (head_l_arr_[i]->extremal == -1) - bot_head_l = head_l_arr_[i]; - else if (head_l_arr_[i]->extremal == 1) - top_head_l = head_l_arr_[i]; + + if (dynamic_cast (o)) + { + rest_l_arr_.substitute (dynamic_cast (o), + (n)? dynamic_cast (n) : 0); } - /* argh. This sux. */ - if (!top_head_l) - top_head_l = bot_head_l; - if (!bot_head_l) - bot_head_l = top_head_l; - //assert(bot_head_l && top_head_l); - Item *support_l=top_head_l; - int j; - for (j = 0; j < 2; j++ ) { - for (int i=0; i < placed_l_arr_a[j].size(); i++) { - if (support_l) - placed_l_arr_a[j][i]->add_support(support_l); - support_l = placed_l_arr_a[j][i]; - } +} + +void +Note_column::add_head (Rhythmic_head *h) +{ + if (Rest*r=dynamic_cast (h)) + { + rest_l_arr_.push (r); } - - support_l=bot_head_l; - for (; j < 4; j++ ) { - for (int i=0; i < placed_l_arr_a[j].size(); i++) { - if (support_l) - placed_l_arr_a[j][i]->add_support(support_l); - support_l = placed_l_arr_a[j][i]; - } + if (Note_head *nh=dynamic_cast (h)) + { + head_l_arr_.push (nh); } + add_element (h); } -Note_column::Note_column() +/** + translate the rest symbols vertically by amount DY_I. + */ +void +Note_column::translate_rests (int dy_i) { - h_shift_b_ =false; - stem_l_ =0; - rest_b_ = false; - dir_i_ =0; + invalidate_cache (Y_AXIS); + for (int i=0; i < rest_l_arr_.size(); i++) + rest_l_arr_[i]->position_i_ += dy_i; } + void -Note_column::sort() +Note_column::do_print() const +{ +#ifndef NPRINT + DOUT << "rests: " << rest_l_arr_.size() << ", "; + DOUT << "heads: " << head_l_arr_.size(); +#endif +} + +void +Note_column::set_dotcol (Dot_column *d) { - head_l_arr_.sort( Notehead::compare); + add_element (d); } + +/* + [TODO] + handle rest under beam (do_post: beams are calculated now) + what about combination of collisions and rest under beam. + + Should lookup + + rest -> stem -> beam -> interpolate_y_position () -Interval_t -Note_column::head_positions_interval()const +*/ + +void +Note_column::do_post_processing () { - ( (Note_column*)this)->sort(); - return Interval_t ( head_l_arr_[0]->position, - head_l_arr_.top()->position); + if (!stem_l_ || !rest_b ()) + return; + + Beam * b = stem_l_->beam_l_; + if (!b || !b->stems_.size ()) + return; + + /* ugh. Should be done by beam. */ + Direction d = stem_l_->get_dir (); + Real beamy = (stem_l_->hpos_f () - b->stems_[0]->hpos_f ()) * b->slope_f_ + b->left_y_; + + Real staff_space = rest_l_arr_[0]->staff_line_leading_f (); + Real rest_dim = extent (Y_AXIS)[d]*2.0 /staff_space ; + + Real minimum_dist + = paper_l ()->get_var ("restcollision_minimum_beamdist") ; + Real dist = + minimum_dist + -d * (beamy - rest_dim) >? 0; + + int stafflines = rest_l_arr_[0]->lines_i (); + + // move discretely by half spaces. + int discrete_dist = int (ceil (dist )); + + // move by whole spaces inside the staff. + if (discrete_dist < stafflines+1) + discrete_dist = int (ceil (discrete_dist / 2.0)* 2.0); + translate_rests (-d * discrete_dist); }