]> git.donarmstrong.com Git - lilypond.git/blob - lily/multi-measure-rest-engraver.cc
release: 1.3.92
[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       if (sp->span_type_str_ == "rest")
77         {
78           if (sp->span_dir_ == STOP)
79             {
80               stop_req_l_ = sp;
81             }
82           else if (sp->span_dir_ == START && !new_req_l_)
83             {
84               new_req_l_ = sp;
85             }
86           return true;
87         }
88     }
89   return false;
90 }
91
92
93
94 void
95 Multi_measure_rest_engraver::do_process_music ()
96 {
97   if (new_req_l_ && stop_req_l_)
98     stop_req_l_ = 0;
99
100   if (new_req_l_)
101     start_moment_ = now_mom ();
102
103   if (stop_req_l_)
104     {
105       busy_span_req_l_ =0;
106       stop_req_l_ = 0;
107     }
108   
109   if (new_req_l_)
110     {
111       busy_span_req_l_ = new_req_l_;
112       new_req_l_ =0;
113     }
114
115   if (busy_span_req_l_ && !mmrest_p_)
116     {
117       mmrest_p_ = new Spanner (get_property ("basicMultiMeasureRestProperties"));
118
119       Multi_measure_rest::set_interface (mmrest_p_);
120       Staff_symbol_referencer::set_interface (mmrest_p_);
121
122       announce_element (mmrest_p_, busy_span_req_l_);
123       start_measure_i_
124         = gh_scm2int (get_property ("currentBarNumber"));
125     }
126 }
127
128 void
129 Multi_measure_rest_engraver::do_pre_move_processing ()
130 {
131   SCM smp = get_property ("measurePosition");
132   Moment mp =  (unsmob_moment (smp)) ? *unsmob_moment (smp) : Moment (0);
133
134   if (mmrest_p_ && (now_mom () >= start_moment_) 
135     && !mp
136     && (scm_ilength (mmrest_p_->get_elt_property ("columns")) >= 2))
137     {
138       typeset_element (mmrest_p_);
139       /*
140         must keep mmrest_p_ around to set measures_i_
141        */
142     }
143   if (lastrest_p_)
144     {
145       typeset_element (lastrest_p_);
146       lastrest_p_ = 0;
147     }
148
149   if (new_req_l_)
150     {
151       busy_span_req_l_ = new_req_l_;
152       new_req_l_ =0;
153     }
154   
155 }
156
157 void
158 Multi_measure_rest_engraver::do_post_move_processing ()
159 {
160   SCM smp = get_property ("measurePosition");
161   Moment mp =  (unsmob_moment (smp)) ? *unsmob_moment (smp) : Moment (0);
162   
163   if (mmrest_p_ && !mp)
164     {
165       lastrest_p_ = mmrest_p_;
166       int cur = gh_scm2int (get_property ("currentBarNumber"));
167       lastrest_p_->set_elt_property ("measure-count",
168                                      gh_int2scm (cur - start_measure_i_));
169       mmrest_p_ = 0;
170     }
171 }
172
173
174 void
175 Multi_measure_rest_engraver::do_removal_processing ()
176 {
177   if (mmrest_p_)
178     typeset_element (mmrest_p_);
179   if (lastrest_p_)
180     typeset_element (lastrest_p_);
181 }