]> git.donarmstrong.com Git - lilypond.git/blob - lily/multi-measure-rest-engraver.cc
21c205532495045df4467a20ab6cb4d7e44990ac
[lilypond.git] / lily / multi-measure-rest-engraver.cc
1 /*
2   multi_measure_rest-engraver.cc -- implement Multi_measure_rest_engraver
3
4   (c) 1998--2001 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
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 */
22 class Multi_measure_rest_engraver : public Engraver
23 {
24 public:
25   VIRTUAL_COPY_CONS (Translator);
26   Multi_measure_rest_engraver ();
27
28 protected:
29   virtual bool try_music (Music*);
30   virtual void process_music ();
31   virtual void stop_translation_timestep ();
32   virtual void start_translation_timestep ();
33   virtual void finalize ();
34
35 private:
36   Span_req * new_req_l_;
37   Span_req * busy_span_req_l_;
38   Span_req * stop_req_l_;
39   int start_measure_i_;
40   Moment start_moment_;
41   
42   Spanner *mmrest_p_;
43   Spanner *lastrest_p_;
44 };
45
46 ADD_THIS_TRANSLATOR (Multi_measure_rest_engraver);
47
48 Multi_measure_rest_engraver::Multi_measure_rest_engraver ()
49 {
50   start_measure_i_ = 0;
51   mmrest_p_  = lastrest_p_ =0;
52   new_req_l_ = busy_span_req_l_ = stop_req_l_ =0;
53 }
54
55
56 bool
57 Multi_measure_rest_engraver::try_music (Music* req_l)
58 {
59   if (Span_req * sp = dynamic_cast<Span_req*> (req_l))
60     {
61       
62       if (scm_equal_p (sp->get_mus_property ("span-type"),
63                        ly_str02scm ("rest")) == SCM_BOOL_T)
64         {
65           if (sp->get_span_dir () == STOP)
66             {
67               stop_req_l_ = sp;
68             }
69           else if (sp->get_span_dir () == START && !new_req_l_)
70             {
71               new_req_l_ = sp;
72             }
73           return true;
74         }
75     }
76   return false;
77 }
78
79 void
80 Multi_measure_rest_engraver::process_music ()
81 {
82   if (new_req_l_ && stop_req_l_)
83     stop_req_l_ = 0;
84
85   if (new_req_l_)
86     start_moment_ = now_mom ();
87
88   if (stop_req_l_)
89     {
90       busy_span_req_l_ =0;
91       stop_req_l_ = 0;
92     }
93   
94   if (new_req_l_)
95     {
96       busy_span_req_l_ = new_req_l_;
97       new_req_l_ =0;
98     }
99
100   if (busy_span_req_l_ && !mmrest_p_)
101     {
102       mmrest_p_ = new Spanner (get_property ("MultiMeasureRest"));
103
104       Multi_measure_rest::set_interface (mmrest_p_);
105       Staff_symbol_referencer::set_interface (mmrest_p_);
106
107       announce_grob (mmrest_p_, busy_span_req_l_);
108       start_measure_i_
109         = gh_scm2int (get_property ("currentBarNumber"));
110     }
111
112   if (gh_string_p (get_property ("whichBar")))
113     {
114       Grob *cmc = unsmob_grob (get_property( "currentCommandColumn"));
115       Item *it = dynamic_cast<Item*> (cmc);
116       if (mmrest_p_)
117         add_bound_item (mmrest_p_, it);
118       if (lastrest_p_)
119         add_bound_item (lastrest_p_,it);
120     }
121 }
122
123 void
124 Multi_measure_rest_engraver::stop_translation_timestep ()
125 {
126   SCM smp = get_property ("measurePosition");
127   Moment mp = (unsmob_moment (smp)) ? *unsmob_moment (smp) : Moment (0);
128
129   if (mmrest_p_ && (now_mom () >= start_moment_) 
130       && !mp.to_bool ()
131       && mmrest_p_->get_bound (LEFT) && mmrest_p_->get_bound (RIGHT))
132     {
133       typeset_grob (mmrest_p_);
134       /*
135         we must keep mmrest_p_ around to set measure-count, so
136         no mmrest_p_ = 0 here. 
137        */
138     }
139
140   if (lastrest_p_)
141     {
142       /* sanity check */
143       if (lastrest_p_->get_bound (LEFT) && lastrest_p_->get_bound (RIGHT)
144           && lastrest_p_->get_bound (LEFT) != lastrest_p_->get_bound (RIGHT))
145         typeset_grob (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::start_translation_timestep ()
159 {
160   SCM smp = get_property ("measurePosition");
161   Moment mp = (unsmob_moment (smp)) ? *unsmob_moment (smp) : Moment (0);
162   
163   if (mmrest_p_ && !mp.to_bool ())
164     {
165       lastrest_p_ = mmrest_p_;
166       int cur = gh_scm2int (get_property ("currentBarNumber"));
167       lastrest_p_->set_grob_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::finalize ()
176 {
177   if (mmrest_p_)
178     typeset_grob (mmrest_p_);
179   if (lastrest_p_)
180     typeset_grob (lastrest_p_);
181 }