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 (Span_req *req_ = dynamic_cast<Span_req*> (m))
49 if (scm_equal_p (req_->get_mus_property ("span-type"),
50 scm_makfrom0str ("abort")) == SCM_BOOL_T)
52 reqs_drul_[START] = 0;
55 ligature_->suicide ();
58 else if (scm_equal_p (req_->get_mus_property ("span-type"),
59 scm_makfrom0str ("ligature")) == SCM_BOOL_T)
61 Direction d = req_->get_span_dir ();
70 Ligature_engraver::create_ligature_spanner ()
72 return new Spanner (SCM_EOL);
76 Ligature_engraver::process_music ()
81 reqs_drul_[STOP]->origin ()->warning (_ ("can't find start of ligature"));
86 reqs_drul_[STOP]->origin ()->warning (_ ("no right bound"));
90 ligature_->set_bound (RIGHT, last_bound);
94 finished_ligature_ = ligature_;
97 last_bound = unsmob_grob (get_property ("currentMusicalColumn"));
101 // TODO: maybe forbid breaks only if not transcribing
102 top_engraver ()->forbid_breaks ();
104 if (reqs_drul_[START])
108 reqs_drul_[START]->origin ()->warning (_ ("already have a ligature"));
112 prev_start_req_ = reqs_drul_[START];
113 ligature_ = create_ligature_spanner ();
114 brew_ligature_primitive_proc =
115 ligature_->get_grob_property ("ligature-primitive-callback");
116 if (brew_ligature_primitive_proc == SCM_EOL)
118 warning ("Ligature_engraver: ligature-primitive-callback undefined");
121 Grob *bound = unsmob_grob (get_property ("currentMusicalColumn"));
124 reqs_drul_[START]->origin ()->warning (_ ("no left bound"));
128 ligature_->set_bound (LEFT, bound);
131 ligature_start_mom_ = now_mom ();
133 announce_grob(ligature_, reqs_drul_[START]->self_scm());
138 Ligature_engraver::start_translation_timestep ()
140 reqs_drul_[START] = 0;
141 reqs_drul_[STOP] = 0;
145 Ligature_engraver::try_stop_ligature ()
147 if (finished_ligature_)
149 typeset_grob (finished_ligature_);
150 finished_ligature_ = 0;
155 Ligature_engraver::stop_translation_timestep ()
157 try_stop_ligature ();
161 Ligature_engraver::finalize ()
163 try_stop_ligature ();
166 prev_start_req_->origin ()->warning (_ ("unterminated ligature"));
167 ligature_->suicide ();
172 Ligature_engraver::acknowledge_grob (Grob_info info)
176 if (Ligature_head::has_interface (info.grob_))
178 info.grob_->set_grob_property ("ligature-primitive-callback",
179 brew_ligature_primitive_proc);
181 else if (Rest::has_interface (info.grob_))
183 info.music_cause ()->origin ()->warning (_ ("ligature may not contain rest; ignoring rest"));
184 prev_start_req_->origin ()->warning (_ ("ligature was started here"));
185 // TODO: maybe better should stop ligature here rather than
186 // ignoring the rest?
191 ENTER_DESCRIPTION(Ligature_engraver,
192 /* descr */ "Abstract class; a concrete subclass handles Ligature_requests by engraving Ligatures in a concrete style.",
193 /* creats*/ "Ligature",
194 /* acks */ "ligature-head-interface rest-interface",