]> git.donarmstrong.com Git - lilypond.git/blob - lily/multi-measure-rest-engraver.cc
patch::: 1.3.108.jcn3
[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   void deprecated_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   virtual void process_acknowledged ();
39
40 private:
41   Span_req * new_req_l_;
42   Span_req * busy_span_req_l_;
43   Span_req * stop_req_l_;
44   int start_measure_i_;
45   Moment start_moment_;
46   
47   Spanner *mmrest_p_;
48   Spanner *lastrest_p_;
49 };
50
51 ADD_THIS_TRANSLATOR (Multi_measure_rest_engraver);
52
53 Multi_measure_rest_engraver::Multi_measure_rest_engraver ()
54 {
55   start_measure_i_ = 0;
56   mmrest_p_  = lastrest_p_ =0;
57   new_req_l_ = busy_span_req_l_ = stop_req_l_ =0;
58 }
59
60 void
61 Multi_measure_rest_engraver::acknowledge_element (Score_element_info i)
62 {
63   Item * item = dynamic_cast<Item*> (i.elem_l_); 
64   if (item && Bar::has_interface (item))
65     {
66       if (mmrest_p_)
67         Multi_measure_rest::add_column (mmrest_p_,item);
68       if (lastrest_p_)
69         Multi_measure_rest::add_column (lastrest_p_,item);
70     }
71 }
72
73 bool
74 Multi_measure_rest_engraver::do_try_music (Music* req_l)
75 {
76   if (Span_req * sp = dynamic_cast<Span_req*> (req_l))
77     {
78       
79       if (scm_equal_p (sp->get_mus_property ("span-type"),
80                        ly_str02scm ("rest")))
81         {
82           if (sp->get_span_dir() == STOP)
83             {
84               stop_req_l_ = sp;
85             }
86           else if (sp->get_span_dir() == START && !new_req_l_)
87             {
88               new_req_l_ = sp;
89             }
90           return true;
91         }
92     }
93   return false;
94 }
95
96 void
97 Multi_measure_rest_engraver::process_acknowledged ()
98 {  
99   deprecated_process_music ();
100 }
101
102
103 void
104 Multi_measure_rest_engraver::deprecated_process_music ()
105 {
106   if (new_req_l_ && stop_req_l_)
107     stop_req_l_ = 0;
108
109   if (new_req_l_)
110     start_moment_ = now_mom ();
111
112   if (stop_req_l_)
113     {
114       busy_span_req_l_ =0;
115       stop_req_l_ = 0;
116     }
117   
118   if (new_req_l_)
119     {
120       busy_span_req_l_ = new_req_l_;
121       new_req_l_ =0;
122     }
123
124   if (busy_span_req_l_ && !mmrest_p_)
125     {
126       mmrest_p_ = new Spanner (get_property ("MultiMeasureRest"));
127
128       Multi_measure_rest::set_interface (mmrest_p_);
129       Staff_symbol_referencer::set_interface (mmrest_p_);
130
131       announce_element (mmrest_p_, busy_span_req_l_);
132       start_measure_i_
133         = gh_scm2int (get_property ("currentBarNumber"));
134     }
135 }
136
137 void
138 Multi_measure_rest_engraver::do_pre_move_processing ()
139 {
140   SCM smp = get_property ("measurePosition");
141   Moment mp =  (unsmob_moment (smp)) ? *unsmob_moment (smp) : Moment (0);
142
143   if (mmrest_p_ && (now_mom () >= start_moment_) 
144     && !mp
145     && (scm_ilength (mmrest_p_->get_elt_property ("columns")) >= 2))
146     {
147       typeset_element (mmrest_p_);
148       /*
149         must keep mmrest_p_ around to set measures_i_
150        */
151     }
152   if (lastrest_p_)
153     {
154       typeset_element (lastrest_p_);
155       lastrest_p_ = 0;
156     }
157
158   if (new_req_l_)
159     {
160       busy_span_req_l_ = new_req_l_;
161       new_req_l_ =0;
162     }
163   
164 }
165
166 void
167 Multi_measure_rest_engraver::do_post_move_processing ()
168 {
169   SCM smp = get_property ("measurePosition");
170   Moment mp =  (unsmob_moment (smp)) ? *unsmob_moment (smp) : Moment (0);
171   
172   if (mmrest_p_ && !mp)
173     {
174       lastrest_p_ = mmrest_p_;
175       int cur = gh_scm2int (get_property ("currentBarNumber"));
176       lastrest_p_->set_elt_property ("measure-count",
177                                      gh_int2scm (cur - start_measure_i_));
178       mmrest_p_ = 0;
179     }
180 }
181
182
183 void
184 Multi_measure_rest_engraver::do_removal_processing ()
185 {
186   if (mmrest_p_)
187     typeset_element (mmrest_p_);
188   if (lastrest_p_)
189     typeset_element (lastrest_p_);
190 }