/*
+ 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);