]> git.donarmstrong.com Git - lilypond.git/blob - src/stem.cc
release: 0.0.26
[lilypond.git] / src / stem.cc
1 #include "stem.hh"
2 #include "dimen.hh" 
3 #include "debug.hh"
4 #include "paper.hh"
5 #include "notehead.hh"
6 #include "lookup.hh"
7 #include "molecule.hh"
8 #include "pcol.hh"
9 #include "misc.hh"
10
11 const int STEMLEN=7;
12 NAME_METHOD(Stem);
13 Stem::Stem(int c) //, Moment len)
14 {
15 //    note_length = len;
16     beams_left = 0;
17     beams_right = 0;
18     minnote = 1000;             // invalid values
19     maxnote = -1000;
20     bot = top = 0;
21     flag = 4;
22     dir =0;
23     staff_center=c;
24     stemlen=0;
25     print_flag=true;
26     stem_xoffset=0;
27 }
28
29 void
30 Stem::do_print() const
31 {
32 #ifndef NPRINT
33     mtor << "flag "<< flag << " print_flag " << print_flag
34          << "min,max [" << minnote << ", " << maxnote << "]";
35 #endif
36 }
37 void
38 Stem::set_stemend(Real se)
39 {
40
41     // todo: margins
42     assert((dir > 0 && se >= maxnote) || (se <= minnote && dir <0));
43     
44     top = (dir < 0) ? maxnote           : se;
45     bot = (dir < 0) ? se  : minnote;
46     flag = dir*abs(flag);
47 }
48
49 void
50 Stem::add(Notehead *n)
51 {
52     assert(status < PRECALCED);
53     
54     if (n->balltype == 1)
55         return;
56     int p = n->position;
57     if ( p < minnote)
58         minnote = p;
59     if ( p> maxnote)
60         maxnote = p;
61     heads.push(n);
62     n->dependencies.push(this);
63 }
64
65
66 void
67 Stem::set_default_dir()
68 {
69     Real mean = (minnote+maxnote)/2;
70     dir = (mean > staff_center) ? -1: 1;
71 }
72
73 void
74 Stem::set_default_stemlen()
75 {
76     if (!dir)
77         set_default_dir();
78
79     int stafftop = 2*staff_center;
80     stemlen = STEMLEN  + (maxnote - minnote);
81     
82     // uhh... how about non 5-line staffs?      
83     if (maxnote < -2 && dir == 1){
84         int t = staff_center - staff_center/2; 
85         stemlen = t - minnote +2;
86     } else if (minnote > stafftop + 2 && dir == -1) {
87         int t = staff_center + staff_center/2;
88         stemlen = maxnote -t +2;
89     }
90
91     assert(stemlen);
92 }
93
94
95 void
96 Stem::set_default_extents()
97 {
98     assert(minnote<=maxnote);
99
100     if (!stemlen)
101         set_default_stemlen();
102
103     set_stemend((dir< 0) ? maxnote-stemlen: minnote +stemlen);
104     if (dir > 0){       
105         stem_xoffset = paper()->note_width();
106     } else
107         stem_xoffset = 0;
108 }
109
110 void
111 Stem::set_noteheads()
112 {
113     heads.sort(Notehead::compare);
114     heads[0]->extremal = -1;
115     heads.last()->extremal = 1;
116     int parity=1;
117     int lastpos = heads[0]->position;
118     for (int i=1; i < heads.size(); i ++) {
119         int dy =abs(lastpos- heads[i]->position);
120         
121         if (dy <= 1) {
122             if (parity)
123                 heads[i]->x_dir = (stem_xoffset>0) ? 1:-1;
124             parity = !parity;
125         } else
126             parity = 0;
127         lastpos = heads[i]->position;
128     }
129 }
130
131 void
132 Stem::do_pre_processing()
133 {
134     if (bot == top)
135         set_default_extents();
136     set_noteheads();
137 }
138
139
140 Interval
141 Stem::width()const
142 {
143     if (!print_flag || abs(flag) <= 4)
144         return Interval(0,0);   // TODO!
145     Paperdef*p= paper();
146     Interval r(p->lookup_p_->flag(flag).dim.x);
147     r+= stem_xoffset;
148     return r;
149 }
150
151 Molecule*
152 Stem::brew_molecule_p()const return out;
153 {
154     assert(bot!=top);
155  
156     
157     Paperdef *p =paper();
158
159     Real dy = p->internote();
160     Symbol ss =p->lookup_p_->stem(bot*dy,top*dy);
161
162     
163     out = new Molecule(Atom(ss));
164
165     if (print_flag&&abs(flag) > 4){
166         Symbol fl = p->lookup_p_->flag(flag);
167         Molecule m(fl);
168         if (flag < -4){         
169             out->add_bottom(m);
170         } else if (flag > 4) {
171             out->add_top(m);
172         } else
173             assert(false); 
174     }
175
176     out->translate(Offset(stem_xoffset,0));
177 }
178
179 Real
180 Stem::hpos()const
181 {
182     return pcol_l_->hpos + stem_xoffset;
183 }
184
185