]> git.donarmstrong.com Git - lilypond.git/blob - src/stem.cc
release: 0.0.15
[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, Real 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     assert(!output);
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     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 }
65
66
67 void
68 Stem::set_default_dir()
69 {
70     Real mean = (minnote+maxnote)/2;
71     dir = (mean > staff_center) ? -1: 1;
72 }
73
74 void
75 Stem::set_default_stemlen()
76 {
77     if (!dir)
78         set_default_dir();
79
80     int stafftop = 2*staff_center;
81     stemlen = STEMLEN  + (maxnote - minnote);
82     
83     // uhh... how about non 5-line staffs?      
84     if (maxnote < -2 && dir == 1){
85         int t = staff_center - staff_center/2; 
86         stemlen = t - minnote +2;
87     } else if (minnote > stafftop + 2 && dir == -1) {
88         int t = staff_center + staff_center/2;
89         stemlen = maxnote -t +2;
90     }
91
92     assert(stemlen);
93 }
94
95
96 void
97 Stem::set_default_extents()
98 {
99     assert(minnote<=maxnote);
100
101     if (!stemlen)
102         set_default_stemlen();
103
104     set_stemend((dir< 0) ? maxnote-stemlen: minnote +stemlen);
105     if (dir > 0){       
106         stem_xoffset = paper()->note_width();
107     } else
108         stem_xoffset = 0;
109 }
110
111 void
112 Stem::postprocess()
113 {
114     if (bot == top)
115         set_default_extents();
116     brew_molecole();
117 }
118
119 Interval
120 Stem::width()const
121 {
122     if (!print_flag || ABS(flag) <= 4)
123         return Interval(0,0);   // TODO!
124     Paperdef*p= paper();
125     Interval r(p->lookup_->flag(flag).dim.x);
126     r+= stem_xoffset;
127     return r;
128 }
129
130 void
131 Stem::brew_molecole()
132 {
133     assert(pstaff_);
134     assert(bot!=top);
135     assert(!output);
136     
137     Paperdef *p =paper();
138
139     Real dy = p->internote();
140     Symbol ss =p->lookup_->stem(bot*dy,top*dy);
141
142     
143     output = new Molecule(Atom(ss));
144
145     if (print_flag&&ABS(flag) > 4){
146         Symbol fl = p->lookup_->flag(flag);
147         Molecule m(fl);
148         if (flag < -4){         
149             output->add_bot(m);
150         } else if (flag > 4) {
151             output->add_top(m);
152         } else
153             assert(false); 
154     }
155
156     output->translate(Offset(stem_xoffset,0));
157
158 }
159
160 Real
161 Stem::hpos()const
162 {
163     return pcol_->hpos + stem_xoffset;
164 }
165
166
167 void
168 Stem::preprocess()
169 {
170     set_default_extents();      // needed for the flags.
171 }