]> git.donarmstrong.com Git - lilypond.git/blob - src/stem.cc
release: 0.0.11
[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     set_default_extents();
108     brew_molecole();
109 }
110
111 Interval
112 Stem::width()const
113 {
114     if (!print_flag || ABS(flag) <= 4)
115         return Interval(0,0);   // TODO!
116     Paperdef*p= paper();
117     Interval r(p->lookup_->flag(flag).dim.x);
118     r+= stem_xoffset;
119     return r;
120 }
121
122 void
123 Stem::brew_molecole()
124 {
125     assert(pstaff_);
126     assert(bot!=top);
127     assert(!output);
128     
129     Paperdef *p =paper();
130
131     Real dy = p->internote();
132     Symbol ss =p->lookup_->stem(bot*dy,top*dy);
133
134     
135     output = new Molecule(Atom(ss));
136
137     if (print_flag&&ABS(flag) > 4){
138         Symbol fl = p->lookup_->flag(flag);
139         Molecule m(fl);
140         if (flag < -4){         
141             output->add_bot(m);
142         } else if (flag > 4) {
143             output->add_top(m);
144         } else
145             assert(false); 
146     }
147
148     output->translate(Offset(stem_xoffset,0));
149
150 }
151
152 Real
153 Stem::hpos()const
154 {
155     return pcol_->hpos + stem_xoffset;
156 }
157
158
159 void
160 Stem::preprocess()
161 {
162  
163 }