X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fengraver.cc;h=d8ece19ee24435b9489ca0aab4b23a95191becb8;hb=b430c32d29caa72a7ae3f679f1f62066c1ebfa95;hp=8ae01f77b6b0e53471d312ee3274665f9298907c;hpb=e4f07a592ebde9621dede5a47430a51b9c232eb3;p=lilypond.git diff --git a/lily/engraver.cc b/lily/engraver.cc index 8ae01f77b6..d8ece19ee2 100644 --- a/lily/engraver.cc +++ b/lily/engraver.cc @@ -1,70 +1,200 @@ /* - engraver.cc -- implement Engraver + This file is part of LilyPond, the GNU music typesetter. - Sourcefile of GNU LilyPond music type setter + Copyright (C) 1997--2011 Han-Wen Nienhuys - (c) 1997--2000 Han-Wen Nienhuys + LilyPond is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + LilyPond is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LilyPond. If not, see . */ -#include "music-list.hh" -#include "musical-request.hh" #include "engraver.hh" -#include "engraver-group-engraver.hh" -#include "debug.hh" -#include "paper-def.hh" -#include "score-element.hh" -#include "group-interface.hh" + +#include "context.hh" +#include "international.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::fill_staff_info (Staff_info&) +Engraver::announce_grob (Grob_info inf) { - + get_daddy_engraver ()->announce_grob (inf); } void -Engraver::announce_element (Score_element_info i) +Engraver::announce_end_grob (Grob_info inf) { - Score_element * e = i.elem_l_; - - if (e->get_elt_property ("interfaces") == SCM_EOL) - Group_interface (e, "interfaces").add_thing (ly_symbol2scm (e->name())); - - if (!i.origin_trans_l_) - i.origin_trans_l_ = this; - daddy_grav_l()->announce_element (i); + inf.start_end_ = STOP; + get_daddy_engraver ()->announce_grob (inf); } +Grob_info +Engraver::make_grob_info (Grob *e, SCM cause) +{ + /* TODO: Remove Music code when it's no longer needed */ + if (Music *m = unsmob_music (cause)) + { + cause = m->to_event ()->unprotect (); + } + if (e->get_property ("cause") == SCM_EOL + && (unsmob_stream_event (cause) || unsmob_grob (cause))) + e->set_property ("cause", cause); + + return Grob_info (this, e); +} + +/* + CAUSE is the object (typically a Stream_event object) that + was the reason for making E. +*/ void -Engraver::typeset_element (Score_element*p) +Engraver::announce_grob (Grob *e, SCM cause) { - daddy_grav_l()->typeset_element (p); + announce_grob (make_grob_info (e, cause)); } +/* + CAUSE is the object (typically a grob or stream-event object) that + was the reason for ending E. */ +void +Engraver::announce_end_grob (Grob *e, SCM cause) +{ + announce_end_grob (make_grob_info (e, cause)); +} -Paper_def* -Engraver::paper_l () const +Engraver::Engraver () { - return dynamic_cast(output_def_l_); } +#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.") +{ + LY_ASSERT_TYPE (ly_is_procedure, cb, 1); -Staff_info -Engraver::get_staff_info() const + creation_callback = cb; + + return SCM_UNSPECIFIED; +} +#endif + +Grob * +Engraver::internal_make_grob (SCM symbol, + SCM cause, + char const * /* name */, + char const *file, + int line, + char const *fun) { - if (daddy_grav_l()) - return daddy_grav_l()->get_staff_info(); - Staff_info info; - return info; +#ifdef NDEBUG + (void)file; + (void)line; + (void)fun; +#endif + + SCM props = updated_grob_properties (context (), symbol); + + 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); + else if (klass == ly_symbol2scm ("Spanner")) + grob = new Spanner (props); + else if (klass == ly_symbol2scm ("Paper_column")) + grob = new Paper_column (props); + + 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_from_locale_string (file), + scm_from_int (line), scm_from_locale_string (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) +{ + Item *it = dynamic_cast (internal_make_grob (x, cause, name, file, line, fun)); + assert (it); + return it; +} +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)); +} +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; +} +Engraver * +unsmob_engraver (SCM eng) +{ + return dynamic_cast (unsmob_translator (eng)); +} -Engraver_group_engraver* -Engraver::daddy_grav_l () const +bool +ly_is_grob_cause (SCM obj) { - return (daddy_trans_l_ ) - ? dynamic_cast (daddy_trans_l_) - : 0; + return unsmob_grob (obj) || unsmob_stream_event (obj) || (obj == SCM_EOL); } + +#include "translator.icc" + +ADD_TRANSLATOR (Engraver, + /* doc */ + "Base class for engravers. Does nothing, so it is not used.", + + /* create */ + "", + + /* read */ + "", + + /* write */ + "" + ); +