]> git.donarmstrong.com Git - lilypond.git/blob - lily/slur.cc
release: 0.0.57
[lilypond.git] / lily / slur.cc
1 /*
2
3   TODO:
4   
5   think about crossing stems.
6   Begin and end should be treated as a Script.
7   
8  */
9 #include "slur.hh"
10 #include "scalar.hh"
11 #include "lookup.hh"
12 #include "paper-def.hh"
13 #include "notehead.hh"
14 #include "p-col.hh"
15 #include "molecule.hh"
16 #include "debug.hh"
17 #include "boxes.hh"
18
19
20
21 Slur::Slur()
22 {
23     open_right=open_left=false;
24 }
25
26 Offset
27 Slur::center() const
28 {
29     int pos1 = encompass.top()->position_i_;
30     int pos2 = encompass[0]->position_i_;
31
32     int dy =  pos1-pos2;
33
34     Real w = width().length();
35
36     return Offset(w/2,dy * paper()->internote());
37 }
38
39 void
40 Slur::add(Notehead*n)
41 {
42     encompass.push(n);
43     add_dependency(n);
44 }
45
46 void
47 Slur::set_default_dir()
48 {
49     int sumpos=0;
50     for (int i=0; i < encompass.size(); i ++) {
51         sumpos += encompass[i]->position_i_;
52     }
53
54     /* should consult stems */
55     Real meanpos = sumpos/Real(encompass.size());
56     if (meanpos < 5)            // todo
57         dir_i_ = -1;
58     else
59         dir_i_ = 1;    
60 }
61
62 void
63 Slur::do_pre_processing()
64 {
65     right_col_l_  = encompass.top()->pcol_l_;
66     left_col_l_ = encompass[0]->pcol_l_;    
67 }
68
69 Spanner*
70 Slur::do_break_at(PCol*l, PCol*r) const
71 {
72     assert(l->line_l_ == r->line_l_);
73     Slur*ret = new Slur(*this);
74
75     ret->encompass.set_size(0);
76     for (int i =0; i < encompass.size(); i++) {
77         if (encompass[i]->pcol_l_->line_l_==l->line_l_)
78             ret->encompass.push(encompass[i]);
79     }
80     if (right_col_l_ != r)
81         ret->open_right = true;
82     if (left_col_l_ != l)
83         ret->open_left = true;
84
85
86     return ret;
87 }
88
89 void
90 Slur::do_post_processing()
91 {
92     if (!dir_i_)
93         set_default_dir();
94 }
95
96 Molecule*
97 Slur::brew_molecule_p() const
98 {
99     Molecule*output = new Molecule;
100
101     int minp=1000, maxp=-1000;  // todo    
102     for (int i=0; i<encompass.size(); i++) {
103         minp = encompass[i]->position_i_ <? minp;
104         maxp = encompass[i]->position_i_ >? maxp;
105     }
106     assert(encompass.size()>0); // todo
107     
108     Notehead *lnote_p =encompass[0];
109     Notehead *rnote_p =encompass.top();
110     int lpos_i = lnote_p->position_i_;
111     int rpos_i = rnote_p->position_i_;
112     Offset  left_off(lnote_p->x_dir_i_, lpos_i + 2*dir_i_);
113     Offset right_off(lnote_p->x_dir_i_, rpos_i + 2*dir_i_);
114     if (!lnote_p->extremal_i_)
115         left_off += Offset(0.5, -dir_i_);
116     if (!rnote_p->extremal_i_)
117         right_off+= Offset(-0.5, -dir_i_);
118     
119     int dy = int(right_off.y - left_off.y);
120     
121     Real nw_f = paper()->note_width();
122     Real nh_f = paper()->internote();
123     Real w = width().length();
124     
125     w+= (right_off.x - left_off.x) * nw_f ;
126     Real round_w = w;           // slur lookup rounds the slurwidth .
127     
128     Symbol sl = paper()->lookup_l()->slur(dy , round_w, dir_i_);
129
130     Real error = w-round_w;
131     
132     Atom a(sl);
133     a.translate(Offset((left_off.x + 0.5 )*nw_f + error/2,
134                        left_off.y * nh_f));
135     output->add(a);
136     return output;
137 }
138
139 IMPLEMENT_STATIC_NAME(Slur);