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