2 dynamic-engraver.cc -- implement Dynamic_engraver
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
9 #include "dimensions.hh"
10 #include "crescendo.hh"
11 #include "musical-request.hh"
13 #include "paper-def.hh"
14 #include "paper-column.hh"
15 #include "staff-symbol.hh"
16 #include "note-column.hh"
17 #include "text-item.hh"
18 #include "side-position-interface.hh"
19 #include "engraver.hh"
21 #include "note-head.hh"
22 #include "group-interface.hh"
23 #include "directional-element-interface.hh"
24 #include "staff-symbol-referencer.hh"
25 #include "translator-group.hh"
27 class Dynamic_line_spanner : public Spanner
30 Dynamic_line_spanner ();
31 VIRTUAL_COPY_CONS(Score_element);
32 void add_column (Item*);
33 Direction get_default_dir () const;
36 Dynamic_line_spanner::Dynamic_line_spanner ()
38 set_elt_property ("transparent", SCM_BOOL_T);
39 side_position (this).set_axis (Y_AXIS);
43 Dynamic_line_spanner::add_column (Item* n)
45 if (!get_bound (LEFT))
54 Dynamic_line_spanner::get_default_dir () const
60 print text & hairpin dynamics.
62 class Dynamic_engraver : public Engraver
65 Crescendo * finished_cresc_p_;
68 Text_script_req* text_req_l_;
69 Span_req * span_start_req_l_;
70 Drul_array<Span_req*> span_req_l_drul_;
72 Dynamic_line_spanner* line_spanner_;
73 Moment last_request_mom_;
78 VIRTUAL_COPY_CONS(Translator);
82 void announce_element (Score_element_info);
84 virtual void do_removal_processing ();
85 virtual void acknowledge_element (Score_element_info);
86 virtual bool do_try_music (Music *req_l);
87 virtual void do_process_music ();
88 virtual void do_pre_move_processing ();
89 virtual void do_post_move_processing ();
92 ADD_THIS_TRANSLATOR (Dynamic_engraver);
95 Dynamic_engraver::announce_element (Score_element_info i)
97 group (i.elem_l_, "interfaces").add_thing (ly_symbol2scm ("dynamic"));
99 Engraver::announce_element (i);
103 Dynamic_engraver::Dynamic_engraver ()
106 finished_cresc_p_ = 0;
108 span_start_req_l_ = 0;
112 span_req_l_drul_[START] = 0;
113 span_req_l_drul_[STOP] = 0;
117 Dynamic_engraver::do_post_move_processing ()
120 span_req_l_drul_[START] = 0;
121 span_req_l_drul_[STOP] = 0;
123 /* ugr; we must attach the Dynamic_line_spanner to something
124 to be sure that the linebreaker will not be confused
126 // if (line_spanner_)
127 // line_spanner_->add_column (LEFT, get_staff_info ().command_pcol_l ());
131 Dynamic_engraver::do_try_music (Music * m)
133 if (Text_script_req* d = dynamic_cast <Text_script_req*> (m))
135 if (d->style_str_ == "dynamic")
141 else if (Span_req* s = dynamic_cast <Span_req*> (m))
143 if ((s->span_type_str_ == "crescendo"
144 || s->span_type_str_ == "decrescendo"))
146 span_req_l_drul_[s->span_dir_] = s;
154 Dynamic_engraver::do_process_music ()
156 if ((span_req_l_drul_[START] || text_req_l_) && !line_spanner_)
158 line_spanner_ = new Dynamic_line_spanner;
159 side_position (line_spanner_).set_axis (Y_AXIS);
160 announce_element (Score_element_info
162 text_req_l_ ? text_req_l_ : span_req_l_drul_[START]));
166 if (span_req_l_drul_[START] || text_req_l_)
167 last_request_mom_ = now_mom ();
171 String loud = text_req_l_->text_str_;
173 text_p_ = new Text_item;
174 text_p_->set_elt_property ("text",
175 ly_str02scm (loud.ch_C ()));
176 text_p_->set_elt_property ("style", gh_str02scm ("dynamic"));
177 text_p_->set_elt_property ("script-priority",
180 assert (line_spanner_);
181 text_p_->set_parent (line_spanner_, Y_AXIS);
182 announce_element (Score_element_info (text_p_, text_req_l_));
185 if (span_req_l_drul_[STOP])
189 span_req_l_drul_[STOP]->warning
190 (_ ("can't find start of (de)crescendo"));
194 assert (!finished_cresc_p_);
195 cresc_p_->set_bound(RIGHT, get_staff_info ().musical_pcol_l ());
196 // cresc_p_->add_dependency (get_staff_info ().musical_pcol_l ());
197 finished_cresc_p_ = cresc_p_;
199 span_start_req_l_ = 0;
203 if (span_req_l_drul_[START])
205 if (span_start_req_l_)
207 span_req_l_drul_[START]->warning
208 (span_start_req_l_->span_dir_ == 1
210 _ ("already have a crescendo")
211 : _ ("already have a decrescendo"));
215 span_start_req_l_ = span_req_l_drul_[START];
216 cresc_p_ = new Crescendo;
217 cresc_p_->set_elt_property
219 gh_int2scm ((span_req_l_drul_[START]->span_type_str_ == "crescendo")
220 ? BIGGER : SMALLER));
222 SCM s = get_property (span_req_l_drul_[START]->span_type_str_ + "Text");
225 cresc_p_->set_elt_property ("start-text", s);
226 daddy_trans_l_->set_property (span_req_l_drul_[START]->span_type_str_
227 + "Text", SCM_UNDEFINED);
230 s = get_property (span_req_l_drul_[START]->span_type_str_ + "Spanner");
231 if (gh_string_p (s)) //&& ly_scm2string (s) != "hairpin")
233 cresc_p_->set_elt_property ("spanner", s);
234 daddy_trans_l_->set_property (span_req_l_drul_[START]->span_type_str_
235 + "Spanner", SCM_UNDEFINED);
238 cresc_p_->set_bound(LEFT, get_staff_info ().musical_pcol_l ());
241 // cresc_p_->add_dependency (get_staff_info ().musical_pcol_l ());
244 We know how wide the text is, if we can be sure that the
245 text already has relevant pointers into the paperdef,
246 and it has its font-size property set.
248 Since font-size may be set by a context higher up, we
249 can not be sure of the size.
255 index_set_cell (cresc_p_->get_elt_property ("dynamic-drul"),
257 if (finished_cresc_p_)
258 index_set_cell (finished_cresc_p_->get_elt_property ("dynamic-drul"),
262 assert (line_spanner_);
263 cresc_p_->set_parent (line_spanner_, Y_AXIS);
264 // cresc_p_->add_dependency (line_spanner_);
265 announce_element (Score_element_info (cresc_p_, span_req_l_drul_[START]));
271 Dynamic_engraver::do_pre_move_processing ()
278 Dynamic_engraver::do_removal_processing ()
282 typeset_element (cresc_p_ );
283 span_start_req_l_->warning (_ ("unterminated (de)crescendo"));
289 typeset_element (line_spanner_);
296 Dynamic_engraver::typeset_all ()
298 if (finished_cresc_p_)
300 typeset_element (finished_cresc_p_);
301 finished_cresc_p_ =0;
306 typeset_element (text_p_);
311 TODO: This should be optionised:
312 * break when group of dynamic requests ends
314 * continue through piece */
315 if (line_spanner_ && last_request_mom_ < now_mom ())
318 side_position (line_spanner_).add_staff_support ();
320 typeset_element (line_spanner_);
326 Dynamic_engraver::acknowledge_element (Score_element_info i)
330 if (Note_column* n = dynamic_cast<Note_column*> (i.elem_l_))
332 side_position (line_spanner_).add_support (n);
333 line_spanner_->add_column (n);