X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fligature-engraver.cc;h=ce6e8a8c2b14ff872ad7e64b451f91ea5c93a857;hb=a8172deda8ce6983c19b8217cd7b1879a8fcb653;hp=1c7c35db4f3cf7f79e40b36799a1797540f5e28e;hpb=14d74ac262744d16fc753ee41042d32860d58633;p=lilypond.git diff --git a/lily/ligature-engraver.cc b/lily/ligature-engraver.cc index 1c7c35db4f..ce6e8a8c2b 100644 --- a/lily/ligature-engraver.cc +++ b/lily/ligature-engraver.cc @@ -1,11 +1,10 @@ -/* +/* ligature-engraver.cc -- implement Ligature_engraver - + source file of the GNU LilyPond music typesetter - - (c) 2002--2004 Juergen Reuter - - */ + + (c) 2002--2005 Juergen Reuter +*/ #include "ligature-engraver.hh" @@ -16,9 +15,11 @@ #include "warn.hh" #include "context.hh" +#include "translator.icc" + /* * This abstract class provides the general framework for ligatures of - * any kind. It cares for handling start/stop ligatures requests and + * any kind. It cares for handling start/stop ligatures events and * collecting all noteheads inbetween, but delegates creation of a * ligature spanner for each start/stop pair and typesetting of the * ligature spanner to a concrete subclass. @@ -59,7 +60,7 @@ * 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 layout 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 @@ -70,8 +71,8 @@ Ligature_engraver::Ligature_engraver () { ligature_ = 0; finished_ligature_ = 0; - reqs_drul_[LEFT] = reqs_drul_[RIGHT] = 0; - prev_start_req_ = 0; + events_drul_[LEFT] = events_drul_[RIGHT] = 0; + prev_start_event_ = 0; last_bound_ = 0; brew_ligature_primitive_proc = SCM_EOL; } @@ -82,27 +83,18 @@ Ligature_engraver::try_music (Music *m) if (m->is_mus_type ("ligature-event")) { Direction d = to_dir (m->get_property ("span-direction")); - reqs_drul_[d] = m; + events_drul_[d] = m; return true; } return false; } -Spanner * -Ligature_engraver::create_ligature_spanner () -{ - programming_error ("Ligature_engraver::create_ligature_spanner (): " - "this is an abstract method that should not be called, " - "but overridden by a subclass"); - return 0; -} - /* * This method should do something that comes close to the following * .ly snippet: * * \property Voice.NoteHead \override #'print-function = - * < value of #'ligature-primitive-callback of Voice.NoteHead > + * < value of noteHeadLigaturePrimitive * * 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 @@ -114,12 +106,9 @@ Ligature_engraver::create_ligature_spanner () void Ligature_engraver::override_stencil_callback () { - SCM target_callback = ly_symbol2scm ("print-function"); - SCM source_callback = ly_symbol2scm ("ligature-primitive-callback"); - 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); + ly_symbol2scm ("stencil"), + get_property ("noteHeadLigaturePrimitive")); } /* @@ -138,32 +127,27 @@ Ligature_engraver::override_stencil_callback () void Ligature_engraver::revert_stencil_callback () { - SCM symbol = ly_symbol2scm ("NoteHead"); - SCM key = ly_symbol2scm ("print-function"); - execute_pushpop_property (context (), symbol, key, SCM_UNDEFINED); + execute_pushpop_property (context (), ly_symbol2scm ("NoteHead"), + ly_symbol2scm ("stencil"), SCM_UNDEFINED); } void Ligature_engraver::process_music () { - if (reqs_drul_[STOP]) + if (events_drul_[STOP]) { if (!ligature_) { - reqs_drul_[STOP]->origin ()->warning (_ ("can't find start of ligature")); + events_drul_[STOP]->origin ()->warning (_ ("can't find start of ligature")); return; } if (!last_bound_) - { - reqs_drul_[STOP]->origin ()->warning (_ ("no right bound")); - } + events_drul_[STOP]->origin ()->warning (_ ("no right bound")); else - { - ligature_->set_bound (RIGHT, last_bound_); - } + ligature_->set_bound (RIGHT, last_bound_); - prev_start_req_ = 0; + prev_start_event_ = 0; finished_primitives_ = primitives_; finished_ligature_ = ligature_; primitives_.clear (); @@ -178,49 +162,31 @@ Ligature_engraver::process_music () get_score_engraver ()->forbid_breaks (); } - if (reqs_drul_[START]) + if (events_drul_[START]) { if (ligature_) { - reqs_drul_[START]->origin ()->warning (_ ("already have a ligature")); + events_drul_[START]->origin ()->warning (_ ("already have a ligature")); return; } - prev_start_req_ = reqs_drul_[START]; + prev_start_event_ = events_drul_[START]; ligature_ = create_ligature_spanner (); - brew_ligature_primitive_proc = - ligature_->get_property ("ligature-primitive-callback"); - if (brew_ligature_primitive_proc == SCM_EOL) - { - warning ("Ligature_engraver: ligature-primitive-callback undefined"); - } Grob *bound = unsmob_grob (get_property ("currentMusicalColumn")); if (!bound) - { - reqs_drul_[START]->origin ()->warning (_ ("no left bound")); - } + events_drul_[START]->origin ()->warning (_ ("no left bound")); else - { - ligature_->set_bound (LEFT, bound); - } + ligature_->set_bound (LEFT, bound); ligature_start_mom_ = now_mom (); // TODO: dump cause into make_item/spanner. - // announce_grob (ligature_, reqs_drul_[START]->self_scm ()); + // announce_grob (ligature_, events_drul_[START]->self_scm ()); override_stencil_callback (); } } -void -Ligature_engraver::typeset_ligature (Spanner *, Array) -{ - programming_error ("Ligature_engraver::typeset_ligature (): " - "this is an abstract method that should not be called, " - "but overridden by a subclass"); -} - void Ligature_engraver::stop_translation_timestep () { @@ -239,8 +205,8 @@ Ligature_engraver::stop_translation_timestep () finished_ligature_ = 0; } - reqs_drul_[START] = 0; - reqs_drul_[STOP] = 0; + events_drul_[START] = 0; + events_drul_[STOP] = 0; } void @@ -254,7 +220,7 @@ Ligature_engraver::finalize () } if (ligature_) { - prev_start_req_->origin ()->warning (_ ("unterminated ligature")); + prev_start_event_->origin ()->warning (_ ("unterminated ligature")); ligature_->suicide (); } } @@ -266,30 +232,30 @@ Ligature_engraver::current_ligature () } void -Ligature_engraver::acknowledge_grob (Grob_info info) +Ligature_engraver::acknowledge_note_head (Grob_info info) { if (ligature_) { - if (Note_head::has_interface (info.grob_)) - { - primitives_.push (info); - info.grob_->set_property ("print-function", - brew_ligature_primitive_proc); - } - if (Rest::has_interface (info.grob_)) + primitives_.push (info); + if (info.grob ()) { - 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? + info.grob ()->set_property ("stencil", + brew_ligature_primitive_proc); } } } -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 */ ""); +void +Ligature_engraver::acknowledge_rest (Grob_info info) +{ + if (ligature_) + { + info.music_cause ()->origin ()->warning (_ ("ignoring rest: ligature may not contain rest")); + prev_start_event_->origin ()->warning (_ ("ligature was started here")); + // TODO: maybe better should stop ligature here rather than + // ignoring the rest? + } +} + +// no ADD_ACKNOWLEDGER / ADD_ACKNOWLEDGER / ADD_TRANSLATOR macro calls +// since this class is abstract