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