]> git.donarmstrong.com Git - lilypond.git/blob - lily/extender-engraver.cc
Merge branch 'master' of git://git.sv.gnu.org/lilypond
[lilypond.git] / lily / extender-engraver.cc
1 /*
2   extender-engraver.cc -- implement Extender_engraver
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1999--2006 Glen Prideaux <glenprideaux@iname.com>,
7   Han-Wen Nienhuys <hanwen@xs4all.nl>,
8   Jan Nieuwenhuizen <janneke@gnu.org>
9 */
10
11 #include "context.hh"
12 #include "engraver.hh"
13 #include "international.hh"
14 #include "item.hh"
15 #include "lyric-extender.hh"
16 #include "note-head.hh"
17 #include "pointer-group-interface.hh"
18 #include "stream-event.hh"
19 #include "warn.hh"
20 #include "spanner.hh"
21
22 #include "translator.icc"
23
24 void completize_extender (Spanner *sp);
25
26 class Extender_engraver : public Engraver
27 {
28   Stream_event *ev_;
29   Spanner *extender_;
30   Spanner *pending_extender_;
31
32 public:
33   TRANSLATOR_DECLARATIONS (Extender_engraver);
34
35 protected:
36   DECLARE_TRANSLATOR_LISTENER (extender);
37   DECLARE_ACKNOWLEDGER (lyric_syllable);
38   virtual void finalize ();
39   void stop_translation_timestep ();
40   void process_music ();
41 };
42
43 Extender_engraver::Extender_engraver ()
44 {
45   extender_ = 0;
46   pending_extender_ = 0;
47   ev_ = 0;
48 }
49
50 IMPLEMENT_TRANSLATOR_LISTENER (Extender_engraver, extender);
51 void
52 Extender_engraver::listen_extender (Stream_event *ev)
53 {
54   ASSIGN_EVENT_ONCE (ev_, ev);
55 }
56
57 void
58 Extender_engraver::process_music ()
59 {
60   if (ev_)
61     extender_ = make_spanner ("LyricExtender", ev_->self_scm ());
62 }
63
64 void
65 Extender_engraver::acknowledge_lyric_syllable (Grob_info i)
66 {
67   Item *item = i.item ();
68   if (extender_)
69     extender_->set_bound (LEFT, item);
70
71   if (pending_extender_)
72     {
73       pending_extender_->set_object ("next", item->self_scm ());
74       completize_extender (pending_extender_);
75       pending_extender_ = 0;
76     }
77 }
78
79 void
80 Extender_engraver::stop_translation_timestep ()
81 {
82   if (extender_ || pending_extender_)
83     {
84       Context *voice = get_voice_to_lyrics (context ());
85       Grob *h = voice ? get_current_note_head (voice) : 0;
86
87       if (h)
88         {
89           if (extender_)
90             {
91               Pointer_group_interface::add_grob (extender_,
92                                                  ly_symbol2scm ("heads"), h);
93             }
94
95           if (pending_extender_)
96             {
97               Pointer_group_interface::add_grob (pending_extender_,
98                                                  ly_symbol2scm ("heads"), h);
99             }
100         }
101       else
102         {
103           if (pending_extender_)
104             {
105               completize_extender (pending_extender_);
106               pending_extender_ = 0;
107             }
108           
109         }
110       if (extender_)
111         {
112           pending_extender_ = extender_;
113           extender_ = 0;
114         }
115     }
116
117   ev_ = 0;
118 }
119
120 void
121 completize_extender (Spanner *sp)
122 {
123   if (!sp->get_bound (RIGHT))
124     {
125       extract_item_set (sp, "heads", heads);
126       if (heads.size ())
127         sp->set_bound (RIGHT, heads.back ());
128     }
129 }
130
131 void
132 Extender_engraver::finalize ()
133 {
134   if (extender_)
135     {
136       completize_extender (extender_);
137
138       if (!extender_->get_bound (RIGHT))
139         extender_->warning (_ ("unterminated extender"));
140       extender_ = 0;
141     }
142
143   if (pending_extender_)
144     {
145       completize_extender (pending_extender_);
146
147       if (!pending_extender_->get_bound (RIGHT))
148         pending_extender_->warning (_ ("unterminated extender"));
149       pending_extender_ = 0;
150     }
151 }
152
153 ADD_ACKNOWLEDGER (Extender_engraver, lyric_syllable);
154 ADD_TRANSLATOR (Extender_engraver,
155                 /* doc */ "Create lyric extenders",
156                 /* create */ "LyricExtender",
157                 /* read */ "",
158                 /* write */ "");