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