]> git.donarmstrong.com Git - lilypond.git/blob - lily/stem.cc
release: 0.0.40
[lilypond.git] / lily / stem.cc
1 #include "stem.hh"
2 #include "dimen.hh" 
3 #include "debug.hh"
4 #include "paper-def.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
14 Stem::Stem(int c) //, Moment len)
15 {
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     if (!  ((dir > 0 && se >= maxnote) || (se <= minnote && dir <0))  ) 
43         warning("Weird stem size; check for narrow beams",0);
44     
45     top = (dir < 0) ? maxnote           : se;
46     bot = (dir < 0) ? se  : minnote;
47     flag = dir*abs(flag);
48 }
49
50 void
51 Stem::add(Notehead *n)
52 {
53     assert(status < PRECALCED);
54     
55     if (n->balltype == 1)
56         return;
57     int p = n->position;
58     if (p < minnote)
59         minnote = p;
60     if (p > maxnote)
61         maxnote = p;
62     heads.push(n);
63     n->add_dependency(this);
64 }
65
66
67 int
68 Stem::get_default_dir()
69 {
70     if (dir)
71         return dir;
72     Real mean = (minnote+maxnote)/2;
73     return (mean > staff_center) ? -1: 1;
74 }
75
76 void
77 Stem::set_default_dir()
78 {
79     dir = get_default_dir();
80 }
81
82 void
83 Stem::set_default_stemlen()
84 {
85     if (!dir)
86         set_default_dir();
87
88     int stafftop = 2*staff_center;
89     stemlen = STEMLEN  + (maxnote - minnote);
90     
91     // uhh... how about non 5-line staffs?
92     if (maxnote < -2 && dir == 1){
93         int t = staff_center - staff_center/2; 
94         stemlen = t - minnote +2;
95     } else if (minnote > stafftop + 2 && dir == -1) {
96         int t = staff_center + staff_center/2;
97         stemlen = maxnote -t +2;
98     }
99
100     assert(stemlen);
101 }
102
103
104 void
105 Stem::set_default_extents()
106 {
107     if (minnote > maxnote) {
108         warning("Empty stem. Ugh!", 0);
109         minnote = -10;
110         maxnote = 20;
111     }
112
113     if (!stemlen)
114         set_default_stemlen();
115
116     set_stemend((dir< 0) ? maxnote-stemlen: minnote +stemlen);
117     if (dir > 0){       
118         stem_xoffset = paper()->note_width()-paper()->rule_thickness();
119     } else
120         stem_xoffset = 0;
121 }
122
123 void
124 Stem::set_noteheads()
125 {
126     if(!heads.size())
127         return;
128     heads.sort(Notehead::compare);
129     heads[0]->extremal = -1;
130     heads.top()->extremal = 1;
131     int parity=1;
132     int lastpos = heads[0]->position;
133     for (int i=1; i < heads.size(); i ++) {
134         int dy =abs(lastpos- heads[i]->position);
135         
136         if (dy <= 1) {
137             if (parity)
138                 heads[i]->x_dir = (stem_xoffset>0) ? 1:-1;
139             parity = !parity;
140         } else
141             parity = 0;
142         lastpos = heads[i]->position;
143     }
144 }
145
146 void
147 Stem::do_pre_processing()
148 {
149     if (bot == top)
150         set_default_extents();
151     set_noteheads();
152 }
153
154
155 Interval
156 Stem::width()const
157 {
158     if (!print_flag || abs(flag) <= 4)
159         return Interval(0,0);   // TODO!
160     Paper_def*p= paper();
161     Interval r(p->lookup_l()->flag(flag).dim.x);
162     r+= stem_xoffset;
163     return r;
164 }
165
166 Molecule*
167 Stem::brew_molecule_p()const return out;
168 {
169     assert(bot!=top);
170  
171     
172     Paper_def *p =paper();
173
174     Real dy = p->internote();
175     Symbol ss =p->lookup_l()->stem(bot*dy,top*dy);
176
177     
178     out = new Molecule(Atom(ss));
179
180     if (print_flag&&abs(flag) > 4){
181         Symbol fl = p->lookup_l()->flag(flag);
182         Molecule m(fl);
183         if (flag < -4){         
184             out->add_bottom(m);
185         } else if (flag > 4) {
186             out->add_top(m);
187         } else
188             assert(false); 
189     }
190
191     out->translate(Offset(stem_xoffset,0));
192 }
193
194 Real
195 Stem::hindex()const
196 {
197     return pcol_l_->hpos + stem_xoffset; // hmm.  + offset_.x;
198 }
199
200