2 ligature-engraver.cc -- implement Ligature_engraver
4 source file of the GNU LilyPond music typesetter
6 (c) 2002 Juergen Reuter <reuter@ipd.uka.de>
9 #include "ligature-engraver.hh"
10 #include "ligature-head.hh"
12 #include "score-engraver.hh"
17 * TODO: lyrics/melisma/syllables: there should be at most one
18 * syllable of lyrics per ligature (i.e. for the lyrics context, a
19 * ligature should count as a single note, regardless of how many
20 * heads the ligature consists of).
22 * TODO: currently, you have to add/remove the proper
23 * Ligature_engraver (Ligature_bracket_engraver,
24 * Mensural_ligature_engraver) to the proper translator
25 * (e.g. VoiceContext) to choose between various representations.
26 * Since adding/removing an engraver to a translator is a global
27 * action in the paper block, you can not mix various representations
28 * _within_ the same score. Hence, for selecting a representation,
29 * one would rather like to have a property that can be set e.g. for
30 * several staves individually. However, it seems that this approach
31 * would require to have a single, complicated Ligature_engraver that
32 * consists of all the code... This needs further thoughts.
34 Ligature_engraver::Ligature_engraver ()
37 finished_ligature_ = 0;
38 reqs_drul_[LEFT] = reqs_drul_[RIGHT] = 0;
41 brew_ligature_primitive_proc = SCM_EOL;
45 Ligature_engraver::try_music (Music *m)
47 if (m->is_mus_type ("abort-event"))
49 reqs_drul_[START] = 0;
52 ligature_->suicide ();
55 else if (m->is_mus_type ("ligature-event"))
57 Direction d = to_dir (m->get_mus_property ("span-direction"));
65 Ligature_engraver::create_ligature_spanner ()
67 return new Spanner (SCM_EOL);
71 Ligature_engraver::process_music ()
76 reqs_drul_[STOP]->origin ()->warning (_ ("can't find start of ligature"));
81 reqs_drul_[STOP]->origin ()->warning (_ ("no right bound"));
85 ligature_->set_bound (RIGHT, last_bound);
89 finished_ligature_ = ligature_;
92 last_bound = unsmob_grob (get_property ("currentMusicalColumn"));
96 // TODO: maybe forbid breaks only if not transcribing
97 top_engraver ()->forbid_breaks ();
99 if (reqs_drul_[START])
103 reqs_drul_[START]->origin ()->warning (_ ("already have a ligature"));
107 prev_start_req_ = reqs_drul_[START];
108 ligature_ = create_ligature_spanner ();
109 brew_ligature_primitive_proc =
110 ligature_->get_grob_property ("ligature-primitive-callback");
111 if (brew_ligature_primitive_proc == SCM_EOL)
113 warning ("Ligature_engraver: ligature-primitive-callback undefined");
116 Grob *bound = unsmob_grob (get_property ("currentMusicalColumn"));
119 reqs_drul_[START]->origin ()->warning (_ ("no left bound"));
123 ligature_->set_bound (LEFT, bound);
126 ligature_start_mom_ = now_mom ();
128 announce_grob(ligature_, reqs_drul_[START]->self_scm());
133 Ligature_engraver::start_translation_timestep ()
135 reqs_drul_[START] = 0;
136 reqs_drul_[STOP] = 0;
140 Ligature_engraver::try_stop_ligature ()
142 if (finished_ligature_)
144 typeset_grob (finished_ligature_);
145 finished_ligature_ = 0;
150 Ligature_engraver::stop_translation_timestep ()
152 try_stop_ligature ();
156 Ligature_engraver::finalize ()
158 try_stop_ligature ();
161 prev_start_req_->origin ()->warning (_ ("unterminated ligature"));
162 ligature_->suicide ();
167 Ligature_engraver::acknowledge_grob (Grob_info info)
171 if (Ligature_head::has_interface (info.grob_))
173 info.grob_->set_grob_property ("ligature-primitive-callback",
174 brew_ligature_primitive_proc);
176 else if (Rest::has_interface (info.grob_))
178 info.music_cause ()->origin ()->warning (_ ("ligature may not contain rest; ignoring rest"));
179 prev_start_req_->origin ()->warning (_ ("ligature was started here"));
180 // TODO: maybe better should stop ligature here rather than
181 // ignoring the rest?
186 ENTER_DESCRIPTION (Ligature_engraver,
187 /* descr */ "Abstract class; a concrete subclass handles Ligature_events by engraving Ligatures in a concrete style.",
188 /* creats */ "Ligature_engraver",
189 /* accepts */ "ligature-event abort-event",
190 /* acks */ "ligature-head-interface rest-interface",