X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fengraver.cc;h=c8eb805638d4619ba378968f103c815842f162b4;hb=ce593a5d9614d463ac0255eac17ceb50ce3bcc29;hp=55929a854b0ac2498c13a9777313502773dbe37f;hpb=d9b43b93f2c885409bafdb157138158f65cc49aa;p=lilypond.git diff --git a/lily/engraver.cc b/lily/engraver.cc index 55929a854b..c8eb805638 100644 --- a/lily/engraver.cc +++ b/lily/engraver.cc @@ -3,87 +3,174 @@ Sourcefile of GNU LilyPond music type setter - (c) 1997--2002 Han-Wen Nienhuys + (c) 1997--2006 Han-Wen Nienhuys */ -#include "music.hh" #include "engraver.hh" -#include "engraver-group-engraver.hh" -#include "grob.hh" -#include "main.hh" + +#include "context.hh" +#include "international.hh" +#include "lilypond-key.hh" +#include "music.hh" +#include "paper-column.hh" #include "score-engraver.hh" +#include "spanner.hh" +#include "stream-event.hh" #include "warn.hh" +Engraver_group * +Engraver::get_daddy_engraver () const +{ + return dynamic_cast (get_daddy_translator ()); +} + void Engraver::announce_grob (Grob_info inf) { - daddy_grav_l ()->announce_grob (inf); + get_daddy_engraver ()->announce_grob (inf); } void -Engraver::announce_grob (Grob* e, Music *m) +Engraver::announce_end_grob (Grob_info inf) { - /* - TODO: junk grob-info, and make a cause grob-property to store - `causes' generically. - */ - - if (m && store_locations_global_b - && m->origin ()->location_str ().length_i ()) + get_daddy_engraver ()->announce_grob (inf); +} + +/* + CAUSE is the object (typically a Stream_event object) that + was the reason for making E. +*/ +void +Engraver::announce_grob (Grob *e, SCM cause) +{ + /* TODO: Remove Music code when it's no longer needed */ + if (Music *m = unsmob_music (cause)) { - e->set_grob_property ("origin", m->get_mus_property ("origin")); + cause = m->to_event ()->unprotect (); } - - Grob_info i (e, m ? m->self_scm () : SCM_UNDEFINED); - if (!i.origin_trans_l_) - i.origin_trans_l_ = this; - daddy_grav_l ()->announce_grob (i); + if (unsmob_stream_event (cause) || unsmob_grob (cause)) + e->set_property ("cause", cause); + + Grob_info i (this, e); + + Engraver_group *g = get_daddy_engraver (); + if (g) + g->announce_grob (i); } - +/* + CAUSE is the object (typically a Music object) that + was the reason for making E. +*/ void -Engraver::typeset_grob (Grob*p) +Engraver::announce_end_grob (Grob *e, SCM cause) { - daddy_grav_l ()->typeset_grob (p); + /* TODO: Remove Music code when it's no longer needed */ + if (Music *m = unsmob_music (cause)) + { + cause = m->to_event ()->unprotect (); + } + if (unsmob_stream_event (cause) || unsmob_grob (cause)) + e->set_property ("cause", cause); + + Grob_info i (this, e); + + i.start_end_ = STOP; + Engraver_group *g = get_daddy_engraver (); + if (g) + g->announce_grob (i); } -Engraver_group_engraver* -Engraver::daddy_grav_l () const +Engraver::Engraver () { - return (daddy_trans_l_) - ? dynamic_cast (daddy_trans_l_) - : 0; } -void -Engraver::process_music () +#ifndef NDEBUG +static SCM creation_callback = SCM_EOL; +LY_DEFINE (ly_set_grob_creation_callback, "ly:set-grob-creation-callback", + 1, 0, 0, (SCM cb), + "Specify a procedure that will be called every time a new grob " + "is created. The callback will receive as arguments the grob " + "that was created, the name of the C++ source file that caused " + "the grob to be created and the corresponding line number in the " + "C++ source file.") { - + SCM_ASSERT_TYPE(ly_is_procedure (cb), cb, SCM_ARG1, __FUNCTION__, + "procedure"); + + creation_callback = cb; + + return SCM_UNSPECIFIED; } +#endif -Engraver::Engraver() +Grob * +Engraver::internal_make_grob (SCM symbol, SCM cause, char const *name, char const *file, int line, char const *fun) { -} + (void) file; + (void) fun; + (void) line; + + SCM props = updated_grob_properties (context (), symbol); + + Object_key const *key = context ()->get_grob_key (name); + Grob *grob = 0; + + SCM handle = scm_sloppy_assq (ly_symbol2scm ("meta"), props); + SCM klass = scm_cdr (scm_sloppy_assq (ly_symbol2scm ("class"), scm_cdr (handle))); + if (klass == ly_symbol2scm ("Item")) + grob = new Item (props, key); + else if (klass == ly_symbol2scm ("Spanner")) + grob = new Spanner (props, key); + else if (klass == ly_symbol2scm ("Paper_column")) + grob = new Paper_column (props, key); -Score_engraver* -Engraver::top_engraver () const + assert (grob); + announce_grob (grob, cause); + +#ifndef NDEBUG + if (ly_is_procedure (creation_callback)) + scm_apply_0 (creation_callback, + scm_list_n (grob->self_scm (), scm_makfrom0str (file), + scm_from_int (line), scm_makfrom0str (fun), SCM_UNDEFINED)); +#endif + + return grob; +} + +Item * +Engraver::internal_make_item (SCM x, SCM cause, + char const *name, + char const *file, int line, char const *fun) { - /* - ugh. - */ - if (dynamic_cast((Engraver*)this)) - return dynamic_cast ((Engraver*)this); + Item *it = dynamic_cast (internal_make_grob (x, cause, name, file, line, fun)); + assert (it); + return it; +} - if (daddy_trans_l_) - return dynamic_cast (daddy_trans_l_)->top_engraver (); +Paper_column * +Engraver::internal_make_column (SCM x, char const *name, + char const *file, int line, char const *fun) +{ + return dynamic_cast (internal_make_grob (x, SCM_EOL, name, file, line, fun)); +} - programming_error ("No score engraver!"); - return 0; +Spanner * +Engraver::internal_make_spanner (SCM x, SCM cause, char const *name, char const *file, int line, char const *fun) +{ + Spanner *sp = dynamic_cast (internal_make_grob (x, cause, name, file, line, fun)); + assert (sp); + return sp; } -ENTER_DESCRIPTION(Engraver, - "", "", "", "", ""); +#include "translator.icc" + +ADD_TRANSLATOR (Engraver, + "Base class for engravers. Does nothing, so it is not used.", + "", + "", + "");