-/*
+/*
ligature-engraver.cc -- implement Ligature_engraver
-
+
source file of the GNU LilyPond music typesetter
-
- (c) 2002--2003 Juergen Reuter <reuter@ipd.uka.de>
-
- */
+
+ (c) 2002--2005 Juergen Reuter <reuter@ipd.uka.de>
+*/
+
#include "ligature-engraver.hh"
+
#include "spanner.hh"
#include "score-engraver.hh"
#include "note-head.hh"
#include "rest.hh"
#include "warn.hh"
-#include "translator-group.hh"
+#include "context.hh"
/*
* This abstract class provides the general framework for ligatures of
* Mensural_ligature_engraver) to the proper translator
* (e.g. VoiceContext) to choose between various representations.
* Since adding/removing an engraver to a translator is a global
- * action in the paper block, you can not mix various representations
+ * action in the layout block, you cannot mix various representations
* _within_ the same score. Hence, for selecting a representation,
* one would rather like to have a property that can be set e.g. for
* several staves individually. However, it seems that this approach
bool
Ligature_engraver::try_music (Music *m)
{
- if (m->is_mus_type ("abort-event"))
- {
- reqs_drul_[START] = 0;
- reqs_drul_[STOP] = 0;
- if (ligature_)
- ligature_->suicide ();
- ligature_ = 0;
- }
- else if (m->is_mus_type ("ligature-event"))
+ if (m->is_mus_type ("ligature-event"))
{
- Direction d = to_dir (m->get_mus_property ("span-direction"));
+ Direction d = to_dir (m->get_property ("span-direction"));
reqs_drul_[d] = m;
return true;
}
* This method should do something that comes close to the following
* .ly snippet:
*
- * \property Voice.NoteHead \override #'molecule-callback =
+ * \property Voice.NoteHead \override #'print-function =
* < value of #'ligature-primitive-callback of Voice.NoteHead >
*
* TODO: What we are doing here on the c++ level, should actually be
* performed on the SCM level. However, I do not know how to teach
- * lilypond to apply an \override and \revert on #'molecule-callback,
+ * lilypond to apply an \override and \revert on #'print-function,
* whenever lily encounters a \[ and \] in an .ly file, respectively.
* Also encounter, that lily should not crash if a user erronously
* nests \[ and \].
*/
void
-Ligature_engraver::override_molecule_callback ()
+Ligature_engraver::override_stencil_callback ()
{
- SCM symbol = ly_symbol2scm ("NoteHead");
- SCM target_callback = ly_symbol2scm ("molecule-callback");
+ SCM target_callback = ly_symbol2scm ("print-function");
SCM source_callback = ly_symbol2scm ("ligature-primitive-callback");
- SCM noteHeadProperties = daddy_trans_->get_property ("NoteHead");
- SCM value = ly_cdr (scm_sloppy_assq (source_callback, noteHeadProperties));
- daddy_trans_->execute_pushpop_property (symbol, target_callback, value);
+ SCM noteHeadProperties = updated_grob_properties (context (), ly_symbol2scm ("NoteHead"));
+ SCM value = scm_cdr (scm_sloppy_assq (source_callback, noteHeadProperties));
+ execute_pushpop_property (context (), ly_symbol2scm ("NoteHead"),
+ target_callback, value);
}
/*
* This method should do something that comes close to the following
* .ly snippet:
*
- * \property Voice.NoteHead \revert #'molecule-callback
+ * \property Voice.NoteHead \revert #'print-function
*
* TODO: What we are doing here on the c++ level, should actually be
* performed on the SCM level. However, I do not know how to teach
- * lilypond to apply an \override and \revert on #'molecule-callback,
+ * lilypond to apply an \override and \revert on #'print-function,
* whenever lily encounters a \[ and \] in an .ly file, respectively.
* Also encounter, that lily should not crash if a user erronously
* nests \[ and \].
*/
void
-Ligature_engraver::revert_molecule_callback ()
+Ligature_engraver::revert_stencil_callback ()
{
SCM symbol = ly_symbol2scm ("NoteHead");
- SCM key = ly_symbol2scm ("molecule-callback");
- daddy_trans_->execute_pushpop_property (symbol, key, SCM_UNDEFINED);
+ SCM key = ly_symbol2scm ("print-function");
+ execute_pushpop_property (context (), symbol, key, SCM_UNDEFINED);
}
void
finished_ligature_ = ligature_;
primitives_.clear ();
ligature_ = 0;
- revert_molecule_callback ();
+ revert_stencil_callback ();
}
last_bound_ = unsmob_grob (get_property ("currentMusicalColumn"));
if (ligature_)
{
// TODO: maybe forbid breaks only if not transcribing
- top_engraver ()->forbid_breaks ();
+ get_score_engraver ()->forbid_breaks ();
}
if (reqs_drul_[START])
prev_start_req_ = reqs_drul_[START];
ligature_ = create_ligature_spanner ();
- brew_ligature_primitive_proc =
- ligature_->get_grob_property ("ligature-primitive-callback");
+ brew_ligature_primitive_proc
+ = ligature_->get_property ("ligature-primitive-callback");
if (brew_ligature_primitive_proc == SCM_EOL)
{
- warning ("Ligature_engraver: ligature-primitive-callback undefined");
+ programming_error ("Ligature_engraver: ligature-primitive-callback undefined");
}
Grob *bound = unsmob_grob (get_property ("currentMusicalColumn"));
}
ligature_start_mom_ = now_mom ();
-
- announce_grob(ligature_, reqs_drul_[START]->self_scm());
- override_molecule_callback ();
- }
-}
-void
-Ligature_engraver::start_translation_timestep ()
-{
- reqs_drul_[START] = 0;
- reqs_drul_[STOP] = 0;
+ // TODO: dump cause into make_item/spanner.
+ // announce_grob (ligature_, reqs_drul_[START]->self_scm ());
+ override_stencil_callback ();
+ }
}
void
{
if (finished_ligature_)
{
- typeset_ligature (finished_ligature_, finished_primitives_);
- finished_primitives_.clear ();
+ if (!finished_primitives_.size ())
+ {
+ finished_ligature_->programming_error ("Ligature_engraver::stop_translation_timestep (): "
+ "junking empty ligature");
+ }
+ else
+ {
+ typeset_ligature (finished_ligature_, finished_primitives_);
+ finished_primitives_.clear ();
+ }
finished_ligature_ = 0;
}
+
+ reqs_drul_[START] = 0;
+ reqs_drul_[STOP] = 0;
}
void
if (Note_head::has_interface (info.grob_))
{
primitives_.push (info);
- info.grob_->set_grob_property ("molecule-callback",
- brew_ligature_primitive_proc);
+ info.grob_->set_property ("print-function",
+ brew_ligature_primitive_proc);
}
if (Rest::has_interface (info.grob_))
{
- info.music_cause ()->origin ()->warning (_ ("ligature may not contain rest; ignoring rest"));
+ info.music_cause ()->origin ()->warning (_ ("ignoring rest: ligature may not contain rest"));
prev_start_req_->origin ()->warning (_ ("ligature was started here"));
// TODO: maybe better should stop ligature here rather than
// ignoring the rest?
}
}
-ENTER_DESCRIPTION (Ligature_engraver,
-/* descr */ "Abstract class; a concrete subclass handles Ligature_events by engraving Ligatures in a concrete style.",
-/* creats */ "",
-/* accepts */ "ligature-event abort-event",
-/* acks */ "note-head-interface rest-interface",
-/* reads */ "",
-/* write */ "");
+ADD_TRANSLATOR (Ligature_engraver,
+ /* descr */ "Abstract class; a concrete subclass handles Ligature_events by engraving Ligatures in a concrete style.",
+ /* creats */ "",
+ /* accepts */ "ligature-event",
+ /* acks */ "note-head-interface rest-interface",
+ /* reads */ "",
+ /* write */ "");