]> git.donarmstrong.com Git - lilypond.git/blob - src/slur.cc
15a94cf8c30e2dc513da0372d894b7ddda156b04
[lilypond.git] / src / slur.cc
1 #include "slur.hh"
2 #include "scalar.hh"
3 #include "lookup.hh"
4 #include "paper.hh"
5 #include "notehead.hh"
6 #include "pcol.hh"
7 #include "molecule.hh"
8 #include "debug.hh"
9 #include "boxes.hh"
10
11 Slur::Slur()
12 {
13     dir = 0;
14     open_right=open_left=false;
15 }
16
17 Offset
18 Slur::center() const
19 {
20     int pos1 = encompass.last()->position;
21     int pos2 = encompass[0]->position;
22
23     int dy =  pos1-pos2;
24
25     Real w = width().length();
26
27     return Offset(w/2,dy * paper()->internote());
28 }
29
30 void
31 Slur::add(Notehead*n)
32 {
33     encompass.add(n);
34     dependencies.add(n);
35 }
36
37 void
38 Slur::set_default_dir()
39 {
40     int sumpos=0;
41     for (int i=0; i < encompass.sz(); i ++) {
42         sumpos += encompass[i]->position;
43     }
44
45     /* should consult stems */
46     Real meanpos = sumpos/Real(encompass.sz());
47     if (meanpos < 5)            // todo
48         dir = -1;
49     else
50         dir = 1;    
51 }
52
53 void
54 Slur::print()const
55 {
56     mtor << "Slur.\n";   
57 }
58
59 void
60 Slur::do_pre_processing()
61 {
62     right  = encompass.last()->pcol_;
63     left = encompass[0]->pcol_;    
64 }
65
66 Spanner*
67 Slur::do_break_at(PCol*l, PCol*r) const
68 {
69     assert(l->line == r->line);
70     Slur*ret = new Slur(*this);
71
72     ret->encompass.set_size(0);
73     for (int i =0; i < encompass.sz(); i++) {
74         if (encompass[i]->pcol_->line==l->line)
75             ret->encompass.add(encompass[i]);
76     }
77     if (right != r)
78         ret->open_right = true;
79     if (left != l)
80         ret->open_left = true;
81
82
83     return ret;
84 }
85
86 void
87 Slur::do_post_processing()
88 {
89     set_default_dir();
90 }
91
92 Molecule*
93 Slur::brew_molecule() const
94 {
95     Molecule*output = new Molecule;
96     assert(left->line == right->line);
97     int minp=1000, maxp=-1000;  // todo    
98     for (int i=0; i<encompass.sz(); i++) {
99         minp = encompass[i]->position <? minp;
100         maxp = encompass[i]->position >? maxp;
101     }
102     assert(encompass.sz()>0);   // todo
103     
104     Notehead *lnote_p =encompass[0];
105     Notehead *rnote_p =encompass.last();
106     int pos1 = lnote_p->position;
107     int pos2 = rnote_p->position;
108
109     int dy =  pos2-pos1;
110     Real nw_f = paper()->note_width();
111     Real w = width().length();
112     w+= (-lnote_p->x_dir + rnote_p->x_dir)* nw_f ;
113     Real round_w = w;           // slur lookup rounds the slurwidth .
114     
115     Symbol sl = paper()->lookup_->slur(dy , round_w, dir);
116
117     Real error = w-round_w;
118     
119     Atom a(sl);
120     a.translate(Offset((lnote_p->x_dir + 0.5 )*nw_f + error/2,
121                        (pos2+2*dir) * paper()->internote()));
122     output->add(a);
123     return output;
124 }
125