]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/slur.cc
release: 0.1.12
[lilypond.git] / lily / slur.cc
index 6e8e9e5f69495ce23884e49762c6e2d27e46c80f..a4349ab750a06095055957dd57408138b2813f7a 100644 (file)
@@ -1,13 +1,23 @@
 /*
+  slur.cc -- implement  Slur
 
+  source file of the GNU LilyPond music typesetter
+
+  (c) 1996, 1997 Han-Wen Nienhuys <hanwen@stack.nl>
+*/
+
+/*
   TODO:
+  
   think about crossing stems.
+  Begin and end should be treated as a Script.
  */
 #include "slur.hh"
 #include "scalar.hh"
 #include "lookup.hh"
 #include "paper-def.hh"
-#include "notehead.hh"
+#include "note-column.hh"
+#include "stem.hh"
 #include "p-col.hh"
 #include "molecule.hh"
 #include "debug.hh"
 
 
 
-Slur::Slur()
-{
-    open_right=open_left=false;
-}
-
-Offset
-Slur::center() const
-{
-    int pos1 = encompass.top()->position;
-    int pos2 = encompass[0]->position;
-
-    int dy =  pos1-pos2;
-
-    Real w = width().length();
-
-    return Offset(w/2,dy * paper()->internote());
-}
-
 void
-Slur::add(Notehead*n)
+Slur::add (Note_column*n)
 {
-    encompass.push(n);
-    add_dependency(n);
+  encompass_arr_.push (n);
+  add_dependency (n);
 }
 
 void
 Slur::set_default_dir()
 {
-    int sumpos=0;
-    for (int i=0; i < encompass.size(); i ++) {
-       sumpos += encompass[i]->position;
+  dir_ = DOWN;
+  for (int i=0; i < encompass_arr_.size(); i ++) 
+    {
+      if (encompass_arr_[i]->dir_ < 0) 
+       {
+         dir_ =UP;
+         break;
+       }
     }
-
-    /* should consult stems */
-    Real meanpos = sumpos/Real(encompass.size());
-    if (meanpos < 5)           // todo
-       dir_i_ = -1;
-    else
-       dir_i_ = 1;    
 }
 
 void
 Slur::do_pre_processing()
 {
-    right_col_l_  = encompass.top()->pcol_l_;
-    left_col_l_ = encompass[0]->pcol_l_;    
+  set_bounds(LEFT, encompass_arr_[0]);    
+  set_bounds(RIGHT, encompass_arr_.top());
 }
 
-Spanner*
-Slur::do_break_at(PCol*l, PCol*r) const
-{
-    assert(l->line_l_ == r->line_l_);
-    Slur*ret = new Slur(*this);
 
-    ret->encompass.set_size(0);
-    for (int i =0; i < encompass.size(); i++) {
-       if (encompass[i]->pcol_l_->line_l_==l->line_l_)
-           ret->encompass.push(encompass[i]);
+void
+Slur::do_substitute_dependency (Score_elem*o, Score_elem*n)
+{
+  int i;
+  while ((i = encompass_arr_.find_i ((Note_column*)o->item())) >=0) 
+    {
+      if (n)
+       encompass_arr_[i] = (Note_column*)n->item();
+      else
+       encompass_arr_.del (i);
     }
-    if (right_col_l_ != r)
-       ret->open_right = true;
-    if (left_col_l_ != l)
-       ret->open_left = true;
+}
 
 
-    return ret;
+static int 
+Note_column_compare (Note_column *const&n1 , Note_column* const&n2)
+{
+  return Item::left_right_compare(n1, n2);
 }
 
 void
 Slur::do_post_processing()
 {
-    if (!dir_i_)
-       set_default_dir();
-}
-
-Molecule*
-Slur::brew_molecule_p() const
-{
-    Molecule*output = new Molecule;
-
-    int minp=1000, maxp=-1000; // todo    
-    for (int i=0; i<encompass.size(); i++) {
-       minp = encompass[i]->position <? minp;
-       maxp = encompass[i]->position >? maxp;
+  encompass_arr_.sort (Note_column_compare);
+  if (!dir_)
+    set_default_dir();
+  Real inter_f = paper()->internote_f ();
+  
+  Drul_array<Note_column*> extrema;
+  extrema[LEFT] = encompass_arr_[0];
+  extrema[RIGHT] = encompass_arr_.top();
+
+  Direction d=LEFT;
+  Real nw_f = paper()->note_width ();
+  while ((d *= -1) != LEFT);
+  do 
+    {
+      if  (extrema[d] != spanned_drul_[d]) 
+       {
+         dx_f_drul_[d] = -d 
+           *(spanned_drul_[d]->width ().length ()/nw_f -0.5);
+       }
+      else if (extrema[d]->stem_l_ && !extrema[d]->stem_l_->transparent_b_) 
+       pos_i_drul_[d] = (int)rint (extrema[d]->stem_l_->height()[dir_]/inter_f);
+      else 
+       pos_i_drul_[d] = (int)rint (extrema[d]->head_positions_interval()[dir_]);
+      pos_i_drul_[d] += dir_;
     }
-    assert(encompass.size()>0);        // todo
-    
-    Notehead *lnote_p =encompass[0];
-    Notehead *rnote_p =encompass.top();
-    int lpos_i = lnote_p->position;
-    int rpos_i = rnote_p->position;
-    Offset  left_off(lnote_p->x_dir, lpos_i + 2*dir_i_);
-    Offset right_off(lnote_p->x_dir, rpos_i + 2*dir_i_);
-    if (!lnote_p->extremal)
-       left_off += Offset(0.5, -dir_i_);
-    if (!rnote_p->extremal)
-       right_off+= Offset(-0.5, -dir_i_);
-    
-    int dy = int(right_off.y - left_off.y);
-    
-    Real nw_f = paper()->note_width();
-    Real nh_f = paper()->internote();
-    Real w = width().length();
-    
-    w+= (right_off.x - left_off.x) * nw_f ;
-    Real round_w = w;          // slur lookup rounds the slurwidth .
-    
-    Symbol sl = paper()->lookup_l()->slur(dy , round_w, dir_i_);
-
-    Real error = w-round_w;
-    
-    Atom a(sl);
-    a.translate(Offset((left_off.x + 0.5 )*nw_f + error/2,
-                      left_off.y * nh_f));
-    output->add(a);
-    return output;
+  while ((d *= -1) != LEFT);
 }
 
-IMPLEMENT_STATIC_NAME(Slur);
+IMPLEMENT_IS_TYPE_B1(Slur,Spanner);