2 extender-engraver.cc -- implement Extender_engraver
4 source file of the GNU LilyPond music typesetter
6 (c) 1999--2009 Glen Prideaux <glenprideaux@iname.com>,
7 Han-Wen Nienhuys <hanwen@xs4all.nl>,
8 Jan Nieuwenhuizen <janneke@gnu.org>
12 #include "engraver.hh"
13 #include "international.hh"
15 #include "lyric-extender.hh"
16 #include "note-head.hh"
17 #include "pointer-group-interface.hh"
18 #include "stream-event.hh"
22 #include "translator.icc"
24 void completize_extender (Spanner
*sp
);
26 class Extender_engraver
: public Engraver
30 Spanner
*pending_extender_
;
33 TRANSLATOR_DECLARATIONS (Extender_engraver
);
36 DECLARE_TRANSLATOR_LISTENER (extender
);
37 DECLARE_ACKNOWLEDGER (lyric_syllable
);
39 virtual void finalize ();
41 void stop_translation_timestep ();
42 void process_music ();
45 Extender_engraver::Extender_engraver ()
48 pending_extender_
= 0;
52 IMPLEMENT_TRANSLATOR_LISTENER (Extender_engraver
, extender
);
54 Extender_engraver::listen_extender (Stream_event
*ev
)
56 ASSIGN_EVENT_ONCE (ev_
, ev
);
60 Extender_engraver::process_music ()
63 extender_
= make_spanner ("LyricExtender", ev_
->self_scm ());
67 Extender_engraver::acknowledge_lyric_syllable (Grob_info i
)
69 Item
*item
= i
.item ();
71 extender_
->set_bound (LEFT
, item
);
73 if (pending_extender_
)
75 pending_extender_
->set_object ("next", item
->self_scm ());
76 completize_extender (pending_extender_
);
77 pending_extender_
= 0;
82 Extender_engraver::stop_translation_timestep ()
84 if (extender_
|| pending_extender_
)
86 Context
*voice
= get_voice_to_lyrics (context ());
87 Grob
*h
= voice
? get_current_note_head (voice
) : 0;
93 Pointer_group_interface::add_grob (extender_
,
94 ly_symbol2scm ("heads"), h
);
97 if (pending_extender_
)
99 Pointer_group_interface::add_grob (pending_extender_
,
100 ly_symbol2scm ("heads"), h
);
101 if (!melisma_busy (voice
))
103 completize_extender (pending_extender_
);
104 pending_extender_
= 0;
110 if (pending_extender_
111 && !get_property ("extendersOverRests"))
113 completize_extender (pending_extender_
);
114 pending_extender_
= 0;
120 pending_extender_
= extender_
;
129 completize_extender (Spanner
*sp
)
131 if (!sp
->get_bound (RIGHT
))
133 extract_item_set (sp
, "heads", heads
);
135 sp
->set_bound (RIGHT
, heads
.back ());
140 Extender_engraver::finalize ()
144 completize_extender (extender_
);
146 if (!extender_
->get_bound (RIGHT
))
147 extender_
->warning (_ ("unterminated extender"));
151 if (pending_extender_
)
153 completize_extender (pending_extender_
);
155 if (!pending_extender_
->get_bound (RIGHT
))
156 pending_extender_
->warning (_ ("unterminated extender"));
157 pending_extender_
= 0;
161 ADD_ACKNOWLEDGER (Extender_engraver
, lyric_syllable
);
162 ADD_TRANSLATOR (Extender_engraver
,
164 "Create lyric extenders.",
170 "extendersOverRests ",