X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;ds=sidebyside;f=lily%2Fstem.cc;h=7b387d8d6d5452dca97139e034750aaef23a7fe2;hb=1f72695816f79df61958fc3649591fbf6b95a05a;hp=5a74da6df8ffe38f0e51e9653d94b47c1c68de9d;hpb=5e47fbe9f5a8e10458a9d737d1c35cff2eae6791;p=lilypond.git diff --git a/lily/stem.cc b/lily/stem.cc index 5a74da6df8..7b387d8d6d 100644 --- a/lily/stem.cc +++ b/lily/stem.cc @@ -3,13 +3,12 @@ source file of the GNU LilyPond music typesetter - (c) 1996,1997 Han-Wen Nienhuys + (c) 1996, 1997--1999 Han-Wen Nienhuys TODO: This is way too hairy */ #include "stem.hh" -#include "dimen.hh" #include "debug.hh" #include "paper-def.hh" #include "note-head.hh" @@ -20,32 +19,46 @@ #include "beam.hh" #include "rest.hh" -const int STEMLEN=7; -IMPLEMENT_IS_TYPE_B1 (Stem,Item); + + +Stem::~Stem () +{ +} Stem::Stem () { /* TODO: staff-size */ - abbrev_flag_i_ = 0; - beam_l_ = 0; - beams_left_i_ = 0; - beams_right_i_ = 0; + beams_i_drul_[LEFT] = beams_i_drul_[RIGHT] = -1; + mult_i_ = 0; yextent_drul_[DOWN] = yextent_drul_[UP] = 0; flag_i_ = 2; dir_ = CENTER; + beam_dir_ = CENTER; + dir_forced_b_ = false; stem_xdir_ = LEFT; staff_size_i_ = 8; beam_gap_i_ = 0; + beam_l_ = 0; } Interval_t Stem::head_positions () const { + /* + Mysterious FreeBSD fix by John Galbraith. Somehow, the empty intervals + trigger FP exceptions on FreeBSD. Fix: do not return infinity + + */ + if (!head_l_arr_.size ()) + { + return Interval_t (100,-100); + } + Interval_t r; for (int i =0; i < head_l_arr_.size (); i++) { @@ -60,7 +73,7 @@ void Stem::do_print () const { #ifndef NPRINT - DOUT << "flag "<< flag_i_ << "abbrev_flag_i_" << abbrev_flag_i_; + DOUT << "flag "<< flag_i_; if (beam_l_) DOUT << "beamed"; #endif @@ -78,6 +91,12 @@ Stem::stem_begin_f () const return yextent_drul_[Direction(-dir_)]; } +Real +Stem::chord_start_f () const +{ + return head_positions()[dir_] * paper ()->internote_f (); +} + Real Stem::stem_end_f () const { @@ -89,7 +108,7 @@ Stem::set_stemend (Real se) { // todo: margins if (dir_ && dir_ * head_positions()[dir_] >= se*dir_) - warning (_("Weird stem size; check for narrow beams")); + warning (_ ("weird stem size; check for narrow beams")); yextent_drul_[dir_] = se; @@ -103,16 +122,16 @@ Stem::type_i () const } void -Stem::add (Rhythmic_head *n) +Stem::add_head (Rhythmic_head *n) { n->add_dependency (this); // ? - if (n->is_type_b (Note_head::static_name ())) + if (Note_head *nh = dynamic_cast (n)) { - head_l_arr_.push ((Note_head*)n); + head_l_arr_.push (nh); } - else if (n->is_type_b (Rest::static_name ())) + else if (Rest *r = dynamic_cast (n)) { - rest_l_arr_.push ((Rest*)n); + rest_l_arr_.push (r); } } @@ -124,7 +143,7 @@ Stem::invisible_b () const } int -Stem::get_center_distance (Direction d) +Stem::get_center_distance (Direction d) const { int staff_center = 0; int distance = d*(head_positions()[d] - staff_center); @@ -132,16 +151,16 @@ Stem::get_center_distance (Direction d) } Direction -Stem::get_default_dir () +Stem::get_default_dir () const { - return (get_center_distance (UP) >= + return (get_center_distance (UP) > get_center_distance (DOWN)) ? DOWN : UP; } Direction -Stem::get_dir () +Stem::get_dir () const { return dir_; } @@ -155,39 +174,33 @@ Stem::set_default_dir () void Stem::set_default_stemlen () { - Real len = STEMLEN; - Real dy = paper ()->interbeam_f (); - - // ugh, should get nice *rule* for this - if (abbrev_flag_i_ > 1) - len += (abbrev_flag_i_ - 1)* dy / 2; - + Real internote_f = paper ()->internote_f (); + Real length_f = paper ()->get_var ("stem_length0") / internote_f; + Real shorten_f = paper ()->get_var ("forced_stem_shorten0") / internote_f; if (!dir_) set_default_dir (); - - /* If the stem points in the "wrong" direction, it should be - shortened, according to [Roush & Gourlay]. Their suggestion to knock off - a whole staffspace is a bit drastical though. - */ - else if (dir_ != get_default_dir ()) - len -= 1.0; + /* + stems in unnatural (forced) direction should be shortened, + accoding to [Roush & Gourlay] + */ + if (((int)chord_start_f ()) + && (dir_ != get_default_dir ())) + length_f -= shorten_f; if (flag_i_ >= 5) - len += 2.0; + length_f += 2.0; if (flag_i_ >= 6) - len += 1.0; + length_f += 1.0; - set_stemend ((dir_ > 0) ? head_positions()[BIGGER] + len : - head_positions()[SMALLER] - len); - + set_stemend ((dir_ > 0) ? head_positions()[BIGGER] + length_f: + head_positions()[SMALLER] - length_f); if (dir_ * stem_end_f () < 0) - { - set_stemend (0); - } + set_stemend (0); } +//xxx void Stem::set_default_extents () { @@ -252,16 +265,11 @@ Interval Stem::do_width () const { Interval r (0, 0); - if (abbrev_flag_i_) - { - r = abbrev_mol ().extent ().x (); - } - else if (beam_l_ || abs (flag_i_) <= 2) + if (beam_l_ || abs (flag_i_) <= 2) ; // TODO! else { - Paper_def*p= paper (); - r = p->lookup_l ()->flag (flag_i_, dir_).dim_.x (); + r = lookup_l ()->flag (flag_i_, dir_).dim_.x (); r += note_delta_f (); } return r; @@ -269,79 +277,35 @@ Stem::do_width () const -Molecule -Stem::abbrev_mol () const -{ - Real dy = paper ()->interbeam_f (); - Real w = 1.5 * paper ()->lookup_l ()->ball (2).dim_.x ().length (); - Real interline_f = paper ()->interline_f (); - Real beamdy = interline_f/2; - - int beams_i = 0; - Real slope_f = paper ()->internote_f () / 4; - - if (beam_l_) { - // huh? - slope_f = 2 * beam_l_->slope_f_; - // ugh, rather calc from Abbreviation_req - beams_i = beams_right_i_ >? beams_left_i_; - } - paper ()->lookup_l ()->beam (slope_f, 20 PT, 1 PT); - - Molecule beams; - Atom a (paper ()->lookup_l ()->beam (slope_f, w, .48 * interline_f)); - a.translate (Offset(- w / 2, stem_end_f () - (w / 2 * slope_f))); - - // ugh - if (!beams_i) - a.translate_axis (dy + beamdy - dir_ * dy, Y_AXIS); - else - a.translate_axis (2 * beamdy - dir_ * (beamdy - dy), Y_AXIS); - - for (int i = 0; i < abbrev_flag_i_; i++) - { - Atom b (a); - b.translate_axis (-dir_ * dy * (beams_i + i), Y_AXIS); - beams.add (b); - } - - return beams; -} const Real ANGLE = 20* (2.0*M_PI/360.0); // ugh! Molecule* -Stem::brew_molecule_p () const +Stem::do_brew_molecule_p () const { Molecule *mol_p =new Molecule; - Paper_def *p =paper (); Drul_array stem_y = yextent_drul_; - Real dy = p->internote_f (); - + Real dy = paper ()->internote_f (); Real head_wid = 0; if (head_l_arr_.size ()) - head_wid = head_l_arr_[0]->width ().length (); + head_wid = head_l_arr_[0]->extent (X_AXIS).length (); stem_y[Direction(-dir_)] += dir_ * head_wid * tan(ANGLE)/(2*dy); if (!invisible_b ()) { - Atom ss =p->lookup_l ()->stem (stem_y[DOWN]*dy, + Molecule ss =lookup_l ()->stem (stem_y[DOWN]*dy, stem_y[UP]*dy); - mol_p->add (Atom (ss)); + mol_p->add_molecule (ss); } - if (!beam_l_ &&abs (flag_i_) > 2) + if (!beam_l_ && abs (flag_i_) > 2) { - Atom fl = p->lookup_l ()->flag (flag_i_, dir_); + Molecule fl = lookup_l ()->flag (flag_i_, dir_); fl.translate_axis(stem_y[dir_]*dy, Y_AXIS); - mol_p->add(fl); - assert (!abbrev_flag_i_); + mol_p->add_molecule (fl); } - if (abbrev_flag_i_) - mol_p->add (abbrev_mol ()); - if (head_l_arr_.size()) { mol_p->translate_axis (note_delta_f (), X_AXIS); @@ -353,29 +317,33 @@ Real Stem::note_delta_f () const { Real r=0; - if (head_l_arr_.size() && stem_xdir_ != CENTER) + if (head_l_arr_.size()) { - Interval head_wid(0, head_l_arr_[0]->width ().length ()); + Interval head_wid(0, head_l_arr_[0]->extent (X_AXIS).length ()); Real rule_thick(paper ()->rule_thickness ()); Interval stem_wid(-rule_thick/2, rule_thick/2); - r = head_wid[stem_xdir_] - stem_wid[stem_xdir_]; + if (stem_xdir_ == CENTER) + r = head_wid.center (); + else + r = head_wid[stem_xdir_] - stem_wid[stem_xdir_]; } return r; } + Real Stem::hpos_f () const { - return note_delta_f () +Item::hpos_f (); + return note_delta_f () + Item::hpos_f (); } /* TODO: head_l_arr_/rest_l_arr_ in do_substitute_dependent () */ void - Stem::do_substitute_dependency (Score_elem*o,Score_elem*n) +Stem::do_substitute_dependency (Score_element*o,Score_element*n) { - Item * o_l = o->item (); - Item * n_l = n? n->item () : 0; - head_l_arr_.substitute ((Note_head*)o_l, (Note_head*)n_l); - rest_l_arr_.substitute ((Rest*)o_l, (Rest*)n_l); + if (Note_head*h=dynamic_cast (o)) + head_l_arr_.substitute (h, dynamic_cast(n)); + if (Rest *r=dynamic_cast (o)) + rest_l_arr_.substitute (r, dynamic_cast(n)); }