X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Ffootnote-engraver.cc;h=2f2b9577c2b5f3e5a996147c697e585b690063f2;hb=f9e274a49562fcf1db4428fe25c7ddbd7e2c99cd;hp=116c7443140f0c6517ef985cb4778b531f631568;hpb=f28aa78743eb5fe9444193748da69cdc32d077da;p=lilypond.git diff --git a/lily/footnote-engraver.cc b/lily/footnote-engraver.cc index 116c744314..2f2b9577c2 100644 --- a/lily/footnote-engraver.cc +++ b/lily/footnote-engraver.cc @@ -1,7 +1,7 @@ /* This file is part of LilyPond, the GNU music typesetter. - Copyright (C) 2006--2011 Han-Wen Nienhuys + Copyright (C) 2011--2012 Mike Solomon LilyPond is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,9 +19,13 @@ #include "engraver.hh" +#include "music.hh" #include "stream-event.hh" +#include "international.hh" #include "item.hh" +#include "pointer-group-interface.hh" #include "spanner.hh" +#include "system.hh" #include "translator.icc" @@ -31,11 +35,15 @@ class Footnote_engraver : public Engraver DECLARE_TRANSLATOR_LISTENER (footnote); DECLARE_ACKNOWLEDGER (grob); + DECLARE_END_ACKNOWLEDGER (grob); vector events_; + vector > annotated_spanners_; void stop_translation_timestep (); + void finalize (); + virtual void derived_mark () const; - void footnotify (Grob *, Stream_event *); + void footnotify (Grob *, SCM); }; IMPLEMENT_TRANSLATOR_LISTENER (Footnote_engraver, footnote); @@ -51,35 +59,40 @@ Footnote_engraver::stop_translation_timestep () events_.clear (); } +void +Footnote_engraver::finalize () +{ + annotated_spanners_.clear (); +} + +void +Footnote_engraver::derived_mark () const +{ + for (vsize i = 0; i < events_.size (); ++i) + scm_gc_mark (events_[i]->self_scm ()); +} + Footnote_engraver::Footnote_engraver () { } void -Footnote_engraver::footnotify (Grob *g, Stream_event *event) +Footnote_engraver::footnotify (Grob *g, SCM cause) { Spanner *s = dynamic_cast(g); - + if (s) { - Spanner *b = make_spanner ("FootnoteSpanner", event->self_scm ()); - b->set_property ("footnote-text", event->get_property ("footnote-text")); - b->set_property ("text", event->get_property ("text")); + Spanner *b = make_spanner ("FootnoteSpanner", cause); b->set_parent (s, Y_AXIS); b->set_parent (s, X_AXIS); - bool bar = scm_is_string (get_property ("whichBar")); - Grob *bound = unsmob_grob (bar - ? get_property ("currentCommandColumn") - : get_property ("currentMusicalColumn")); + Grob *bound = unsmob_grob (get_property ("currentMusicalColumn")); b->set_bound (LEFT, bound); - b->set_bound (RIGHT, bound); - b->set_property ("parent-spanner", s->self_scm ()); + annotated_spanners_.push_back (Drul_array (s, b)); } else { - Grob *b = make_item ("Footnote", event->self_scm ()); - b->set_property ("footnote-text", event->get_property ("footnote-text")); - b->set_property ("text", event->get_property ("text")); + Grob *b = make_item ("FootnoteItem", cause); b->set_parent (g, Y_AXIS); b->set_parent (g, X_AXIS); } @@ -88,39 +101,72 @@ Footnote_engraver::footnotify (Grob *g, Stream_event *event) void Footnote_engraver::acknowledge_grob (Grob_info info) { - Stream_event *cause = info.event_cause (); + Music *mus = unsmob_music (info.grob ()->get_property ("footnote-music")); - SCM arts = cause ? cause->get_property ("articulations") : SCM_EOL; - for (SCM s = arts; scm_is_pair (s); s = scm_cdr (s)) + if (mus) { - Stream_event *e = unsmob_stream_event (scm_car (s)); - if (e->in_event_class ("footnote-event")) + if (!mus->is_mus_type ("footnote-event")) { - footnotify (info.grob (), e); + mus->origin ()->programming_error (_ ("Must be footnote-event.")); + return; } + + footnotify (info.grob (), mus->to_event (context ())->unprotect ()); + + // This grob has exhausted its footnote + info.grob ()->set_property ("footnote-music", SCM_EOL); + return; } - for (vsize i = 0; i < events_.size (); i++) + if (!events_.empty ()) { - if (info.grob ()->name () == ly_symbol2string (events_[i]->get_property ("symbol"))) - footnotify (info.grob (), events_[i]); + string grobname = info.grob ()->name (); + + for (vsize i = 0; i < events_.size (); i++) + { + SCM name = events_[i]->get_property ("symbol"); + if (scm_is_symbol (name) + && grobname == ly_symbol2string (name)) + { + footnotify (info.grob (), events_[i]->self_scm ()); + // Event has exhausted its footnote + events_[i]->set_property ("symbol", SCM_EOL); + } + } } } +void +Footnote_engraver::acknowledge_end_grob (Grob_info info) +{ + Spanner *s = dynamic_cast(info.grob ()); + if (s) + for (vsize i = 0; i < annotated_spanners_.size (); i++) + { + if (annotated_spanners_[i][LEFT] == s) + { + Grob *bound = unsmob_grob (get_property ("currentMusicalColumn")); + annotated_spanners_[i][RIGHT]->set_bound (RIGHT, bound); + break; + } + } +} ADD_ACKNOWLEDGER (Footnote_engraver, grob); +ADD_END_ACKNOWLEDGER (Footnote_engraver, grob); ADD_TRANSLATOR (Footnote_engraver, - /* doc */ - "Create footnote texts.", + /* doc */ + "Create footnote texts.", - /* create */ - "Footnote ", + /* create */ + "FootnoteItem " + "FootnoteSpanner ", - /*read*/ - "", + /*read*/ + "currentMusicalColumn ", - /*write*/ - "" - ); + /*write*/ + "" + );