]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/beam.cc
release: 0.0.65
[lilypond.git] / lily / beam.cc
index a20e859e23a03cefda2226205432aa672d5e7553..e838f90ea03c0c8adff09d26b4cd4ba0fdc8b2fd 100644 (file)
@@ -1,3 +1,17 @@
+/*
+  beam.cc -- implement Beam
+
+  source file of the GNU GNU LilyPond music typesetter
+
+  (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
+
+  TODO
+
+  Less hairy code. Better slope calculations.
+  knee: ([\stem 1; c8 \stem -1; c8]
+  
+*/
+
 #include "varray.hh"
 
 #include "proto.hh"
@@ -29,23 +43,28 @@ struct Stem_info {
 
 Stem_info::Stem_info(Stem const *s)
 {
-    x = s->hindex();
-    int dir = s->dir;
-    idealy  = max(dir*s->top, dir*s->bot);
-    miny = max(dir*s->minnote, dir*s-> maxnote);
+    x = s->hpos_f();
+    int dir = s->dir_i_;
+    idealy  = dir * s->stem_end_f();
+    miny = dir * s->stem_start_f();
     assert(miny <= idealy);
-
 }
 
+
 /* *************** */
+void
+Beam::do_break_at(PCol*l, PCol*r)
+{
+    assert (l->line_l_ == r->line_l_);
+}
+
+
 
 Offset
 Beam::center()const
 {
-    assert(status >= POSTCALCED);
-
     Real w=(paper()->note_width() + width().length())/2.0;
-    return Offset(w, (left_pos + w* slope)*paper()->internote());
+    return Offset(w, (left_pos + w* slope)*paper()->internote_f());
 }
 
 
@@ -58,24 +77,29 @@ Beam::Beam()
 void
 Beam::add(Stem*s)
 {
-    stems.bottom().add(s);
+    stems.push(s);
     s->add_dependency(this);
-    s->print_flag = false;
+    s->print_flag_b_ = false;
 }
 
 void
 Beam::set_default_dir()
 {
-    int dirs[2];
-    dirs[0]=0; dirs[1] =0;
-    for (iter_top(stems,i); i.ok(); i++) {
-       int d = i->get_default_dir();
-       dirs[(d+1)/2] ++;
-    }
-    dir_i_ =  (dirs[0] > dirs[1]) ? -1 : 1;
-    for (iter_top(stems,i); i.ok(); i++) {
-       i->dir = dir_i_;
+    int dirs_single = 0, dirs_chord = 0;
+    for (int i=0; i <stems.size(); i++) {
+       Stem *sl = stems[i];
+       if (sl->chord_b())
+           dirs_chord += sl->get_default_dir();
+       else
+           dirs_single += sl->get_center_distance();
     }
+    dirs_single = -sign(dirs_single);
+    dir_i_ = (dirs_single + dirs_chord > 0) ? 1 : -1;
+
+   for (int i=0; i <stems.size(); i++) {
+       Stem *sl = stems[i];
+       sl->dir_i_ = dir_i_;
+   }
 }
 
 /*
@@ -85,8 +109,13 @@ void
 Beam::solve_slope()
 {
     Array<Stem_info> sinfo;
-    for (iter_top(stems,i); i.ok(); i++) {
+  for (int j=0; j <stems.size(); j++) {
+       Stem *i = stems[j];
+
        i->set_default_extents();
+       if (i->invisible_b())
+           continue;
+       
        Stem_info info(i);
        sinfo.push(info);
     }
@@ -110,19 +139,20 @@ Beam::solve_slope()
     left_pos *= dir_i_;    
     slope *= dir_i_;
 
-                               // URG
-    Real sl = slope*paper()->internote();
+                               // ugh
+    Real sl = slope*paper()->internote_f();
     paper()->lookup_l()->beam(sl, 20 PT);
-    slope = sl /paper()->internote();
+    slope = sl /paper()->internote_f();
 }
 
 void
 Beam::set_stemlens()
 {
-    iter_top(stems,s);
-    Real x0 = s->hindex();    
-    for (; s.ok() ; s++) {
-       Real x =  s->hindex()-x0;
+    Real x0 = stems[0]->hpos_f();    
+    for (int j=0; j <stems.size(); j++) {
+       Stem *s = stems[j];
+
+       Real x =  s->hpos_f()-x0;
        s->set_stemend(left_pos + slope * x);   
     }
 }
@@ -146,10 +176,11 @@ Beam::set_grouping(Rhythmic_grouping def, Rhythmic_grouping cur)
 
     Array<int> b;
     {
-       iter_top(stems,s);
        Array<int> flags;
-       for (; s.ok(); s++) {
-           int f = intlog2(abs(s->flag))-2;
+       for (int j=0; j <stems.size(); j++) {
+           Stem *s = stems[j];
+
+           int f = intlog2(abs(s->flag_i_))-2;
            assert(f>0);
            flags.push(f);
        }
@@ -160,28 +191,18 @@ Beam::set_grouping(Rhythmic_grouping def, Rhythmic_grouping cur)
        assert(stems.size() == b.size()/2);
     }
 
-    iter_top(stems,s);
-    for (int i=0; i < b.size() && s.ok(); i+=2, s++) {
-       s->beams_left = b[i];
-       s->beams_right = b[i+1];
+    for (int j=0, i=0; i < b.size() && j <stems.size(); i+= 2, j++) {
+       Stem *s = stems[j];
+       s->beams_left_i_ = b[i];
+       s->beams_right_i_ = b[i+1];
     }
 }
 
-
-// todo.
-Spanner *
-Beam::do_break_at( PCol *, PCol *) const
-{
-    Beam *beam_p= new Beam(*this);
-    
-    return beam_p;
-}
-
 void
 Beam::do_pre_processing()
 {
-    left_col_l_ = (*stems.top())   ->pcol_l_;
-    right_col_l_ = (*stems.bottom())->pcol_l_;    
+    left_col_l_ = stems[0]   ->pcol_l_;
+    right_col_l_ = stems.top()->pcol_l_;    
     assert(stems.size()>1);
     if (!dir_i_)
        set_default_dir();
@@ -190,11 +211,10 @@ Beam::do_pre_processing()
 
 
 Interval
-Beam::width() const
+Beam::do_width() const
 {
-    Beam * me = (Beam*) this;  // ugh
-    return Interval( (*me->stems.top()) ->hindex(),
-                    (*me->stems.bottom()) ->hindex() );
+    return Interval( stems[0]->hpos_f(),
+                    stems.top()->hpos_f() );
 }
 
 /*
@@ -203,11 +223,11 @@ Beam::width() const
 Molecule
 Beam::stem_beams(Stem *here, Stem *next, Stem *prev)const
 {
-    assert( !next || next->hindex() > here->hindex()  );
-    assert( !prev || prev->hindex() < here->hindex()  );
-    Real dy=paper()->internote()*2;
+    assert( !next || next->hpos_f() > here->hpos_f()  );
+    assert( !prev || prev->hpos_f() < here->hpos_f()  );
+    Real dy=paper()->internote_f()*2;
     Real stemdx = paper()->rule_thickness();
-    Real sl = slope*paper()->internote();
+    Real sl = slope*paper()->internote_f();
     paper()->lookup_l()->beam(sl, 20 PT);
 
     Molecule leftbeams;
@@ -215,9 +235,9 @@ Beam::stem_beams(Stem *here, Stem *next, Stem *prev)const
 
     /* half beams extending to the left. */
     if (prev) {
-       int lhalfs= lhalfs = here->beams_left - prev->beams_right ;
-       int lwholebeams= here->beams_left <? prev->beams_right ;
-       Real w = (here->hindex() - prev->hindex())/4;
+       int lhalfs= lhalfs = here->beams_left_i_ - prev->beams_right_i_ ;
+       int lwholebeams= here->beams_left_i_ <? prev->beams_right_i_ ;
+       Real w = (here->hpos_f() - prev->hpos_f())/4;
        Symbol dummy;
        Atom a(dummy);
        if (lhalfs)             // generates warnings if not
@@ -231,10 +251,10 @@ Beam::stem_beams(Stem *here, Stem *next, Stem *prev)const
     }
        
     if (next){
-       int rhalfs = here->beams_right - next->beams_left;
-       int rwholebeams = here->beams_right <? next->beams_left
+       int rhalfs = here->beams_right_i_ - next->beams_left_i_;
+       int rwholebeams = here->beams_right_i_ <? next->beams_left_i_
 
-       Real w = next->hindex() - here->hindex();
+       Real w = next->hpos_f() - here->hpos_f();
        Atom a = paper()->lookup_l()->beam(sl, w + stemdx);
        
        int j = 0;
@@ -261,24 +281,24 @@ Beam::stem_beams(Stem *here, Stem *next, Stem *prev)const
 
 
 Molecule*
-Beam::brew_molecule_p() const return out;
+Beam::brew_molecule_p() const 
 {
-    Real inter=paper()->internote();
+    Molecule *out=0;
+    Real inter=paper()->internote_f();
     out = new Molecule;
-    Real x0 = stems.top()->hindex();
-    
-    for (iter_top(stems,i); i.ok(); i++) {
-       PCursor<Stem*> p(i-1);
-       PCursor<Stem*> n(i+1);
-       Stem * prev = p.ok() ? p.ptr() : 0;
-       Stem * next = n.ok() ? n.ptr() : 0;
+    Real x0 = stems[0]->hpos_f();
+    for (int j=0; j <stems.size(); j++) {
+       Stem *i = stems[j];
+       Stem * prev = (j > 0)? stems[j-1] : 0;
+       Stem * next = (j < stems.size()-1) ? stems[j+1] :0;
 
        Molecule sb = stem_beams(i, next, prev);
-       Real  x = i->hindex()-x0;
+       Real  x = i->hpos_f()-x0;
        sb.translate(Offset(x, (x * slope  + left_pos)* inter));
        out->add(sb);
     }
     out->translate(Offset(x0 - left_col_l_->hpos,0));
+    return out;
 }
 
 IMPLEMENT_STATIC_NAME(Beam);
@@ -292,7 +312,11 @@ Beam::do_print()const
 #endif
 }
 
-Beam::~Beam()
+void
+Beam::do_substitute_dependency(Score_elem*o,Score_elem*n)
 {
-
+    int i;
+    while ((i=stems.find_i((Stem*)o->item())) >=0) 
+          if (n) stems[i] = (Stem*) n->item();
+          else stems.del(i);
 }