]> git.donarmstrong.com Git - lilypond.git/blob - src/stem.cc
release: 0.0.13
[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
10 const int STEMLEN=7;
11 static int
12 ABS(int i) {
13     return (i < 0)?-i:i;
14 }
15
16
17 Stem::Stem(int c)
18 {
19     minnote = 1000;             // invalid values
20     maxnote = -1000;
21     bot = top = 0;
22     flag = 4;
23     dir =0;
24     staff_center=c;
25     stemlen=0;
26     print_flag=true;
27     stem_xoffset=0;
28 }
29
30
31 void
32 Stem::set_stemend(Real se)
33 {
34     assert(!output);
35     // todo: margins
36     assert((dir > 0 && se >= maxnote) || (se <= minnote && dir <0));
37     
38     top = (dir < 0) ? maxnote           : se;
39     bot = (dir < 0) ? se  : minnote;
40     flag = dir*ABS(flag);
41 }
42
43 void
44 Stem::add(Notehead *n)
45 {
46     if (n->balltype == 1)
47         return;
48     int p = n->position;
49     if ( p < minnote)
50         minnote = p;
51     if ( p> maxnote)
52         maxnote = p;
53 }
54 void
55 Stem::print()const
56 {
57     mtor << "Stem minmax=["<< minnote<<","<<maxnote<<"], flag: "<<flag;
58     Item::print();
59 }
60
61 void
62 Stem::set_default_dir()
63 {
64     Real mean = (minnote+maxnote)/2;
65     dir = (mean > staff_center) ? -1: 1;
66 }
67
68 void
69 Stem::set_default_stemlen()
70 {
71     if (!dir)
72         set_default_dir();
73
74     int stafftop = 2*staff_center;
75     stemlen = STEMLEN  + (maxnote - minnote);
76     
77     // uhh... how about non 5-line staffs?      
78     if (maxnote < -2 && dir == 1){
79         int t = staff_center - staff_center/2; 
80         stemlen = t - minnote +2;
81     } else if (minnote > stafftop + 2 && dir == -1) {
82         int t = staff_center + staff_center/2;
83         stemlen = maxnote -t +2;
84     }
85
86     assert(stemlen);
87 }
88
89
90 void
91 Stem::set_default_extents()
92 {
93     assert(minnote<=maxnote);
94
95     if (!stemlen)
96         set_default_stemlen();
97
98     set_stemend((dir< 0) ? maxnote-stemlen: minnote +stemlen);
99     if (dir > 0){       
100         stem_xoffset = paper()->note_width();
101     }
102 }
103
104 void
105 Stem::postprocess()
106 {
107     if (bot == top)
108         set_default_extents();
109     brew_molecole();
110 }
111
112 Interval
113 Stem::width()const
114 {
115     if (!print_flag || ABS(flag) <= 4)
116         return Interval(0,0);   // TODO!
117     Paperdef*p= paper();
118     Interval r(p->lookup_->flag(flag).dim.x);
119     r+= stem_xoffset;
120     return r;
121 }
122
123 void
124 Stem::brew_molecole()
125 {
126     assert(pstaff_);
127     assert(bot!=top);
128     assert(!output);
129     
130     Paperdef *p =paper();
131
132     Real dy = p->internote();
133     Symbol ss =p->lookup_->stem(bot*dy,top*dy);
134
135     
136     output = new Molecule(Atom(ss));
137
138     if (print_flag&&ABS(flag) > 4){
139         Symbol fl = p->lookup_->flag(flag);
140         Molecule m(fl);
141         if (flag < -4){         
142             output->add_bot(m);
143         } else if (flag > 4) {
144             output->add_top(m);
145         } else
146             assert(false); 
147     }
148
149     output->translate(Offset(stem_xoffset,0));
150
151 }
152
153 Real
154 Stem::hpos()const
155 {
156     return pcol_->hpos + stem_xoffset;
157 }
158
159
160 void
161 Stem::preprocess()
162 {
163  
164 }