2 new-dynamic-engraver.cc -- implement New_dynamic_engraver
4 source file of the GNU LilyPond music typesetter
6 (c) 2008 Han-Wen Nienhuys <hanwen@lilypond.org>
11 #include "engraver.hh"
14 #include "pointer-group-interface.hh"
15 #include "text-interface.hh"
16 #include "note-column.hh"
17 #include "self-alignment-interface.hh"
19 #include "stream-event.hh"
21 #include "translator.icc"
23 class New_dynamic_engraver : public Engraver
25 TRANSLATOR_DECLARATIONS (New_dynamic_engraver);
26 DECLARE_ACKNOWLEDGER (note_column);
27 DECLARE_TRANSLATOR_LISTENER (absolute_dynamic);
28 DECLARE_TRANSLATOR_LISTENER (span_dynamic);
31 virtual void process_music ();
32 virtual void stop_translation_timestep ();
34 Drul_array<Stream_event *> accepted_spanevents_drul_;
35 Spanner *current_spanner_;
36 Spanner *finished_spanner_;
39 Stream_event *script_event_;
40 Stream_event *current_span_event_;
43 New_dynamic_engraver::New_dynamic_engraver ()
46 current_span_event_ = 0;
48 finished_spanner_ = 0;
50 accepted_spanevents_drul_.set (0, 0);
53 IMPLEMENT_TRANSLATOR_LISTENER (New_dynamic_engraver, absolute_dynamic);
55 New_dynamic_engraver::listen_absolute_dynamic (Stream_event *ev)
57 ASSIGN_EVENT_ONCE (script_event_, ev);
60 IMPLEMENT_TRANSLATOR_LISTENER (New_dynamic_engraver, span_dynamic);
62 New_dynamic_engraver::listen_span_dynamic (Stream_event *ev)
64 Direction d = to_dir (ev->get_property ("span-direction"));
66 ASSIGN_EVENT_ONCE (accepted_spanevents_drul_[d], ev);
71 New_dynamic_engraver::process_music ()
74 && (accepted_spanevents_drul_[STOP] || script_event_ || accepted_spanevents_drul_[START]))
76 Stream_event* ender = accepted_spanevents_drul_[STOP];
78 ender = script_event_;
81 ender = accepted_spanevents_drul_[START];
83 finished_spanner_ = current_spanner_;
84 announce_end_grob (finished_spanner_, ender->self_scm ());
86 current_span_event_ = 0;
89 if (accepted_spanevents_drul_[START])
91 current_span_event_ = accepted_spanevents_drul_[START];
93 SCM start_sym = current_span_event_->get_property ("class");
96 if (start_sym == ly_symbol2scm ("decrescendo-event"))
97 start_type = "decrescendo";
98 else if (start_sym == ly_symbol2scm ("crescendo-event"))
99 start_type = "crescendo";
102 programming_error ("unknown dynamic spanner type");
106 SCM cresc_type = get_property ((start_type + "Spanner").c_str ());
108 if (cresc_type == ly_symbol2scm ("text"))
111 = make_spanner ("DynamicTextSpanner",
112 accepted_spanevents_drul_[START]->self_scm ());
114 SCM text = get_property ((start_type + "Text").c_str ());
115 if (Text_interface::is_markup (text))
117 current_spanner_->set_property ("text", text);
122 if (cresc_type != ly_symbol2scm ("hairpin"))
124 // Fixme: should put value in error message.
125 ly_display_scm (cresc_type);
127 ->origin()->warning ("unknown crescendo style; defaulting to hairpin.");
129 current_spanner_ = make_spanner ("Hairpin",
130 current_span_event_->self_scm ());
131 if (finished_spanner_)
133 Pointer_group_interface::add_grob (finished_spanner_,
134 ly_symbol2scm ("adjacent-hairpins"),
137 Pointer_group_interface::add_grob (current_spanner_,
138 ly_symbol2scm ("adjacent-hairpins"),
146 script_ = make_item ("DynamicText", script_event_->self_scm ());
147 script_->set_property ("text",
148 script_event_->get_property ("text"));
150 if (finished_spanner_)
151 finished_spanner_->set_bound (RIGHT, script_);
152 if (current_spanner_)
154 current_spanner_->set_bound (LEFT, script_);
155 set_nested_property (current_spanner_,
156 scm_list_3 (ly_symbol2scm ("bound-details"),
157 ly_symbol2scm ("left"),
158 ly_symbol2scm ("attach-dir")
160 scm_from_int (RIGHT));
169 New_dynamic_engraver::stop_translation_timestep ()
171 if (finished_spanner_ && !finished_spanner_->get_bound (RIGHT))
172 finished_spanner_->set_bound (RIGHT,
173 unsmob_grob (get_property ("currentMusicalColumn")));
175 if (current_spanner_ && !current_spanner_->get_bound (LEFT))
176 current_spanner_->set_bound (LEFT,
177 unsmob_grob (get_property ("currentMusicalColumn")));
180 accepted_spanevents_drul_.set (0, 0);
181 finished_spanner_ = 0;
185 New_dynamic_engraver::acknowledge_note_column (Grob_info info)
187 if (script_ && !script_->get_parent (X_AXIS))
189 extract_grob_set (info.grob (), "note-heads", heads);
192 Grob *head = heads[0];
193 script_->set_parent (head, X_AXIS);
194 Self_alignment_interface::set_center_parent (script_, X_AXIS);
198 if (current_spanner_ && !current_spanner_->get_bound (LEFT))
199 current_spanner_->set_bound (LEFT, info.grob ());
200 if (finished_spanner_ && !finished_spanner_->get_bound (RIGHT))
201 finished_spanner_->set_bound (RIGHT, info.grob ());
204 ADD_ACKNOWLEDGER (New_dynamic_engraver, note_column);
205 ADD_TRANSLATOR (New_dynamic_engraver,
207 "Create hairpins, dynamic texts, and their vertical"
208 " alignments. The symbols are collected onto a"
209 " @code{DynamicLineSpanner} grob which takes care of vertical"
213 "DynamicTextSpanner "
219 "currentMusicalColumn ",