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