2 multi_measure_rest-engraver.cc -- implement Multi_measure_rest_engraver
4 (c) 1998--2003 Jan Nieuwenhuizen <janneke@gnu.org>
5 Han-Wen Nienhuys <hanwen@cs.uu.nl>
9 #include "multi-measure-rest.hh"
10 #include "paper-column.hh"
11 #include "engraver-group-engraver.hh"
12 #include "side-position-interface.hh"
13 #include "staff-symbol-referencer.hh"
14 #include "engraver.hh"
19 The name says it all: make multi measure rests
22 class Multi_measure_rest_engraver
: public Engraver
25 TRANSLATOR_DECLARATIONS(Multi_measure_rest_engraver
);
28 virtual bool try_music (Music
*);
29 virtual void process_music ();
30 virtual void stop_translation_timestep ();
31 virtual void start_translation_timestep ();
32 virtual void finalize ();
36 Music
* busy_span_req_
;
45 Spanner
*last_number_
;
49 Multi_measure_rest_engraver::Multi_measure_rest_engraver ()
55 new_req_
= busy_span_req_
= stop_req_
=0;
59 Multi_measure_rest_engraver::try_music (Music
* req
)
61 if (req
->is_mus_type ("multi-measure-rest-event"))
63 Direction d
= to_dir (req
->get_mus_property ("span-direction"));
68 else if (d
== START
&& !new_req_
)
78 Multi_measure_rest_engraver::process_music ()
80 if (new_req_
&& stop_req_
)
84 start_moment_
= now_mom ();
94 busy_span_req_
= new_req_
;
98 if (busy_span_req_
&& !mmrest_
)
100 mmrest_
= new Spanner (get_property ("MultiMeasureRest"));
101 number_
= new Spanner (get_property ("MultiMeasureRestNumber"));
103 Side_position_interface::add_support (number_
, mmrest_
);
104 number_
->set_parent (mmrest_
, Y_AXIS
);
106 announce_grob (mmrest_
, busy_span_req_
->self_scm());
107 announce_grob (number_
, busy_span_req_
->self_scm());
109 = gh_scm2int (get_property ("currentBarNumber"));
112 if (gh_string_p (get_property ("whichBar")))
114 Grob
*cmc
= unsmob_grob (get_property( "currentCommandColumn"));
115 Item
*it
= dynamic_cast<Item
*> (cmc
);
118 add_bound_item (mmrest_
, it
);
119 add_bound_item (number_
, it
);
123 add_bound_item (last_rest_
,it
);
124 add_bound_item (last_number_
, it
);
130 Multi_measure_rest_engraver::stop_translation_timestep ()
132 SCM smp
= get_property ("measurePosition");
133 Moment mp
= (unsmob_moment (smp
)) ? *unsmob_moment (smp
) : Moment (0);
135 if (mmrest_
&& (now_mom () >= start_moment_
)
137 && mmrest_
->get_bound (LEFT
) && mmrest_
->get_bound (RIGHT
))
139 typeset_grob (mmrest_
);
140 typeset_grob (number_
);
141 Side_position_interface::add_staff_support (number_
);
143 we must keep mmrest_ around to set measure-count, so
153 if (last_rest_
->get_bound (LEFT
) && last_rest_
->get_bound (RIGHT
)
154 && last_rest_
->get_bound (LEFT
) != last_rest_
->get_bound (RIGHT
))
156 typeset_grob (last_rest_
);
157 typeset_grob (last_number_
);
165 busy_span_req_
= new_req_
;
172 Multi_measure_rest_engraver::start_translation_timestep ()
174 SCM smp
= get_property ("measurePosition");
175 Moment mp
= (unsmob_moment (smp
)) ? *unsmob_moment (smp
) : Moment (0);
177 if (mmrest_
&& !mp
.to_bool ())
179 last_rest_
= mmrest_
;
180 last_number_
= number_
;
182 int cur
= gh_scm2int (get_property ("currentBarNumber"));
183 int num
= cur
- start_measure_
;
184 last_rest_
->set_grob_property ("measure-count", gh_int2scm (num
));
186 SCM sml
= get_property ("measureLength");
187 Rational ml
= (unsmob_moment (sml
)) ? unsmob_moment (sml
)->main_part_
: Rational (1);
188 if (ml
>= Rational (2))
190 last_rest_
->set_grob_property ("use-breve-rest", SCM_BOOL_T
);
195 SCM text
=last_number_
->get_grob_property ("text");
196 SCM thres
= get_property ("restNumberThreshold");
198 if (gh_number_p (thres
))
199 t
= gh_scm2int (thres
);
201 if (text
== SCM_EOL
&& num
<= t
)
202 last_number_
->suicide();
203 else if (text
== SCM_EOL
)
205 text
= scm_number_to_string (gh_int2scm (num
), SCM_MAKINUM (10));
206 last_number_
->set_grob_property ("text", text
);
213 Multi_measure_rest_engraver::finalize ()
217 typeset_grob (mmrest_
);
218 typeset_grob (number_
);
222 typeset_grob (last_rest_
);
223 typeset_grob (last_number_
);
227 ENTER_DESCRIPTION(Multi_measure_rest_engraver
,
229 "Engraves multi-measure rests that are produced with @code{R}. Reads "
230 "measurePosition and currentBarNumber to determine what number to print "
231 "over the MultiMeasureRest. Reads measureLength to determine if it "
232 "should use a whole rest or a breve rest to represent 1 measure "
234 /* creats*/ "MultiMeasureRest MultiMeasureRestNumber",
235 /* accepts */ "multi-measure-rest-event",
237 /* reads */ "currentBarNumber restNumberThreshold currentCommandColumn measurePosition measureLength",