lilypond-1.3.129
[lilypond.git] / src / slur.cc
blobba77a6948e710a3ac129879974bcc876c019a240
1 /*
3 TODO:
4 think about crossing stems.
5 */
6 #include "slur.hh"
7 #include "scalar.hh"
8 #include "lookup.hh"
9 #include "paper-def.hh"
10 #include "notehead.hh"
11 #include "pcol.hh"
12 #include "molecule.hh"
13 #include "debug.hh"
14 #include "boxes.hh"
18 Slur::Slur()
20 open_right=open_left=false;
23 Offset
24 Slur::center() const
26 int pos1 = encompass.top()->position;
27 int pos2 = encompass[0]->position;
29 int dy = pos1-pos2;
31 Real w = width().length();
33 return Offset(w/2,dy * paper()->internote());
36 void
37 Slur::add(Notehead*n)
39 encompass.push(n);
40 add_dependency(n);
43 void
44 Slur::set_default_dir()
46 int sumpos=0;
47 for (int i=0; i < encompass.size(); i ++) {
48 sumpos += encompass[i]->position;
51 /* should consult stems */
52 Real meanpos = sumpos/Real(encompass.size());
53 if (meanpos < 5) // todo
54 dir_i_ = -1;
55 else
56 dir_i_ = 1;
59 void
60 Slur::do_pre_processing()
62 right = encompass.top()->pcol_l_;
63 left = encompass[0]->pcol_l_;
66 Spanner*
67 Slur::do_break_at(PCol*l, PCol*r) const
69 assert(l->line_l_ == r->line_l_);
70 Slur*ret = new Slur(*this);
72 ret->encompass.set_size(0);
73 for (int i =0; i < encompass.size(); i++) {
74 if (encompass[i]->pcol_l_->line_l_==l->line_l_)
75 ret->encompass.push(encompass[i]);
77 if (right != r)
78 ret->open_right = true;
79 if (left != l)
80 ret->open_left = true;
83 return ret;
86 void
87 Slur::do_post_processing()
89 if (!dir_i_)
90 set_default_dir();
93 Molecule*
94 Slur::brew_molecule_p() const
96 Molecule*output = new Molecule;
98 int minp=1000, maxp=-1000; // todo
99 for (int i=0; i<encompass.size(); i++) {
100 minp = encompass[i]->position <? minp;
101 maxp = encompass[i]->position >? maxp;
103 assert(encompass.size()>0); // todo
105 Notehead *lnote_p =encompass[0];
106 Notehead *rnote_p =encompass.top();
107 int lpos_i = lnote_p->position;
108 int rpos_i = rnote_p->position;
109 Offset left_off(lnote_p->x_dir, lpos_i + 2*dir_i_);
110 Offset right_off(lnote_p->x_dir, rpos_i + 2*dir_i_);
111 if (!lnote_p->extremal)
112 left_off += Offset(0.5, -dir_i_);
113 if (!rnote_p->extremal)
114 right_off+= Offset(-0.5, -dir_i_);
116 int dy = int(right_off.y - left_off.y);
118 Real nw_f = paper()->note_width();
119 Real nh_f = paper()->internote();
120 Real w = width().length();
122 w+= (right_off.x - left_off.x) * nw_f ;
123 Real round_w = w; // slur lookup rounds the slurwidth .
125 Symbol sl = paper()->lookup_p_->slur(dy , round_w, dir_i_);
127 Real error = w-round_w;
129 Atom a(sl);
130 a.translate(Offset((left_off.x + 0.5 )*nw_f + error/2,
131 left_off.y * nh_f));
132 output->add(a);
133 return output;