]> git.donarmstrong.com Git - lilypond.git/blob - lily/multi-measure-rest-engraver.cc
release: 1.3.105
[lilypond.git] / lily / multi-measure-rest-engraver.cc
1 /*
2   multi_measure_rest-engraver.cc -- implement Multi_measure_rest_engraver
3
4   (c) 1998--2000 Jan Nieuwenhuizen <janneke@gnu.org>
5        Han-Wen Nienhuys <hanwen@cs.uu.nl>
6 */
7
8 #include "musical-request.hh"
9 #include "multi-measure-rest.hh"
10 #include "paper-column.hh"
11 #include "engraver-group-engraver.hh"
12 #include "bar.hh"
13 #include "staff-symbol-referencer.hh"
14 #include "engraver.hh"
15 #include "moment.hh"
16 #include "spanner.hh"
17
18 /**
19    The name says it all: make multi measure rests 
20
21 FIXME? The MM rest engraver must be able to see bar lines, so it won't
22 work at Voice level. Not a problem in practice, but aesthetically pleasing? 
23
24 */
25 class Multi_measure_rest_engraver : public Engraver
26 {
27 public:
28   VIRTUAL_COPY_CONS(Translator);
29   Multi_measure_rest_engraver ();
30
31 protected:
32   virtual void acknowledge_element (Score_element_info i);
33   virtual void do_process_music ();
34   virtual bool do_try_music (Music*);
35   virtual void do_pre_move_processing ();
36   virtual void do_post_move_processing ();
37   virtual void do_removal_processing ();
38 private:
39   Span_req * new_req_l_;
40   Span_req * busy_span_req_l_;
41   Span_req * stop_req_l_;
42   int start_measure_i_;
43   Moment start_moment_;
44   
45   Spanner *mmrest_p_;
46   Spanner *lastrest_p_;
47 };
48
49 ADD_THIS_TRANSLATOR (Multi_measure_rest_engraver);
50
51 Multi_measure_rest_engraver::Multi_measure_rest_engraver ()
52 {
53   start_measure_i_ = 0;
54   mmrest_p_  = lastrest_p_ =0;
55   new_req_l_ = busy_span_req_l_ = stop_req_l_ =0;
56 }
57
58 void
59 Multi_measure_rest_engraver::acknowledge_element (Score_element_info i)
60 {
61   Item * item = dynamic_cast<Item*> (i.elem_l_); 
62   if (item && Bar::has_interface (item))
63     {
64       if (mmrest_p_)
65         Multi_measure_rest::add_column (mmrest_p_,item);
66       if (lastrest_p_)
67         Multi_measure_rest::add_column (lastrest_p_,item);
68     }
69 }
70
71 bool
72 Multi_measure_rest_engraver::do_try_music (Music* req_l)
73 {
74   if (Span_req * sp = dynamic_cast<Span_req*> (req_l))
75     {
76       
77       if (scm_equal_p (sp->get_mus_property ("span-type"),
78                        ly_str02scm ("rest")))
79         {
80           if (sp->get_span_dir() == STOP)
81             {
82               stop_req_l_ = sp;
83             }
84           else if (sp->get_span_dir() == START && !new_req_l_)
85             {
86               new_req_l_ = sp;
87             }
88           return true;
89         }
90     }
91   return false;
92 }
93
94
95
96 void
97 Multi_measure_rest_engraver::do_process_music ()
98 {
99   if (new_req_l_ && stop_req_l_)
100     stop_req_l_ = 0;
101
102   if (new_req_l_)
103     start_moment_ = now_mom ();
104
105   if (stop_req_l_)
106     {
107       busy_span_req_l_ =0;
108       stop_req_l_ = 0;
109     }
110   
111   if (new_req_l_)
112     {
113       busy_span_req_l_ = new_req_l_;
114       new_req_l_ =0;
115     }
116
117   if (busy_span_req_l_ && !mmrest_p_)
118     {
119       mmrest_p_ = new Spanner (get_property ("MultiMeasureRest"));
120
121       Multi_measure_rest::set_interface (mmrest_p_);
122       Staff_symbol_referencer::set_interface (mmrest_p_);
123
124       announce_element (mmrest_p_, busy_span_req_l_);
125       start_measure_i_
126         = gh_scm2int (get_property ("currentBarNumber"));
127     }
128 }
129
130 void
131 Multi_measure_rest_engraver::do_pre_move_processing ()
132 {
133   SCM smp = get_property ("measurePosition");
134   Moment mp =  (unsmob_moment (smp)) ? *unsmob_moment (smp) : Moment (0);
135
136   if (mmrest_p_ && (now_mom () >= start_moment_) 
137     && !mp
138     && (scm_ilength (mmrest_p_->get_elt_property ("columns")) >= 2))
139     {
140       typeset_element (mmrest_p_);
141       /*
142         must keep mmrest_p_ around to set measures_i_
143        */
144     }
145   if (lastrest_p_)
146     {
147       typeset_element (lastrest_p_);
148       lastrest_p_ = 0;
149     }
150
151   if (new_req_l_)
152     {
153       busy_span_req_l_ = new_req_l_;
154       new_req_l_ =0;
155     }
156   
157 }
158
159 void
160 Multi_measure_rest_engraver::do_post_move_processing ()
161 {
162   SCM smp = get_property ("measurePosition");
163   Moment mp =  (unsmob_moment (smp)) ? *unsmob_moment (smp) : Moment (0);
164   
165   if (mmrest_p_ && !mp)
166     {
167       lastrest_p_ = mmrest_p_;
168       int cur = gh_scm2int (get_property ("currentBarNumber"));
169       lastrest_p_->set_elt_property ("measure-count",
170                                      gh_int2scm (cur - start_measure_i_));
171       mmrest_p_ = 0;
172     }
173 }
174
175
176 void
177 Multi_measure_rest_engraver::do_removal_processing ()
178 {
179   if (mmrest_p_)
180     typeset_element (mmrest_p_);
181   if (lastrest_p_)
182     typeset_element (lastrest_p_);
183 }