lilypond-1.3.21
[lilypond.git] / src / stem.cc
blob74ea4b57fcf0f500e46353139a5b356357bd30c3
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"
11 const int STEMLEN=7;
14 Stem::Stem(int c) //, Moment 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;
29 void
30 Stem::do_print() const
32 #ifndef NPRINT
33 mtor << "flag "<< flag << " print_flag " << print_flag
34 << "min,max [" << minnote << ", " << maxnote << "]";
35 #endif
37 void
38 Stem::set_stemend(Real se)
41 // todo: margins
42 if (! ((dir > 0 && se >= maxnote) || (se <= minnote && dir <0)) )
43 warning("Weird stem size; check for narrow beams",0);
45 top = (dir < 0) ? maxnote : se;
46 bot = (dir < 0) ? se : minnote;
47 flag = dir*abs(flag);
50 void
51 Stem::add(Notehead *n)
53 assert(status < PRECALCED);
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);
67 int
68 Stem::get_default_dir()
70 if (dir)
71 return dir;
72 Real mean = (minnote+maxnote)/2;
73 return (mean > staff_center) ? -1: 1;
76 void
77 Stem::set_default_dir()
79 dir = get_default_dir();
82 void
83 Stem::set_default_stemlen()
85 if (!dir)
86 set_default_dir();
88 int stafftop = 2*staff_center;
89 stemlen = STEMLEN + (maxnote - minnote);
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;
100 assert(stemlen);
104 void
105 Stem::set_default_extents()
107 if (minnote > maxnote) {
108 warning("Empty stem. Ugh!", 0);
109 minnote = -10;
110 maxnote = 20;
113 if (!stemlen)
114 set_default_stemlen();
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;
123 void
124 Stem::set_noteheads()
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);
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;
146 void
147 Stem::do_pre_processing()
149 if (bot == top)
150 set_default_extents();
151 set_noteheads();
155 Interval
156 Stem::width()const
158 if (!print_flag || abs(flag) <= 4)
159 return Interval(0,0); // TODO!
160 Paper_def*p= paper();
161 Interval r(p->lookup_p_->flag(flag).dim.x);
162 r+= stem_xoffset;
163 return r;
166 Molecule*
167 Stem::brew_molecule_p()const return out;
169 assert(bot!=top);
172 Paper_def *p =paper();
174 Real dy = p->internote();
175 Symbol ss =p->lookup_p_->stem(bot*dy,top*dy);
178 out = new Molecule(Atom(ss));
180 if (print_flag&&abs(flag) > 4){
181 Symbol fl = p->lookup_p_->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);
191 out->translate(Offset(stem_xoffset,0));
194 Real
195 Stem::hindex()const
197 return pcol_l_->hpos + stem_xoffset; // hmm. + offset_.x;