2 new-phrasing-engraver.cc -- implement New_phrasing_engraver
4 source file of the GNU LilyPond music typesetter
6 (c) 2003--2004 Han-Wen Nienhuys <hanwen@xs4all.nl>
11 #include "translator-group.hh"
12 #include "engraver.hh"
13 #include "note-head.hh"
14 #include "lyric-extender.hh"
16 #include "group-interface.hh"
18 struct Phrasing_association
21 Link_array<Grob> lyrics_;
22 Link_array<Grob> heads_;
23 Link_array<Spanner> past_extenders_;
24 Link_array<Spanner> new_extenders_;
28 Phrasing_association()
34 class Lyric_phrasing_engraver : public Engraver
37 ~Lyric_phrasing_engraver ();
38 TRANSLATOR_DECLARATIONS(Lyric_phrasing_engraver);
40 virtual void acknowledge_grob (Grob_info);
41 virtual void process_acknowledged_grobs ();
42 virtual void stop_translation_timestep ();
45 void add_lyric_phrasing (Grob_info);
46 void add_voice_phrasing (Grob_info);
47 void add_lyric_extender (Grob_info);
48 Phrasing_association *get_phrasing_assoc (String nm);
49 String get_voice_name_for_lyric (Translator_group*tr);
50 Link_array<Phrasing_association> assocs_;
53 Lyric_phrasing_engraver::Lyric_phrasing_engraver()
58 Lyric_phrasing_engraver::acknowledge_grob (Grob_info i)
62 if (Note_head::has_interface (h))
63 add_voice_phrasing (i);
64 else if (h->internal_has_interface (ly_symbol2scm ("lyric-syllable-interface")))
65 add_lyric_phrasing (i);
66 else if (Lyric_extender::has_interface (h))
67 add_lyric_extender (i);
70 Phrasing_association *
71 Lyric_phrasing_engraver::get_phrasing_assoc (String nm)
73 Phrasing_association * a=0;
74 for (int i=0 ; !a && i < assocs_.size (); i++)
76 if (assocs_[i]->name_ == nm)
82 a = new Phrasing_association ;
92 Lyric_phrasing_engraver::get_voice_name_for_lyric (Translator_group*tr)
94 SCM voice = tr->get_property ("associatedVoice");
95 String nm = tr->id_string_;
96 if (gh_string_p (voice))
97 nm = ly_scm2string (voice);
100 int idx = nm.index_last ('-');
102 nm = nm.left_string (idx);
110 Lyric_phrasing_engraver::add_lyric_extender (Grob_info inf)
112 Translator_group * tr = inf.origin_trans_->daddy_trans_;
113 while (tr && !tr->is_alias (ly_symbol2scm ("LyricsVoice")))
114 tr = tr->daddy_trans_;
120 Phrasing_association *a = get_phrasing_assoc (get_voice_name_for_lyric (tr));
121 a->new_extenders_.push (dynamic_cast<Spanner*> (inf.grob_));
126 Lyric_phrasing_engraver::add_voice_phrasing (Grob_info inf)
128 Translator_group * tr = inf.origin_trans_->daddy_trans_;
129 while (tr && !tr->is_alias (ly_symbol2scm ("Voice")))
130 tr = tr->daddy_trans_;
135 Phrasing_association *a = get_phrasing_assoc (tr->id_string_);
136 a->heads_.push (inf.grob_);
137 a->melisma_ = melisma_busy (inf.origin_trans_);
141 Lyric_phrasing_engraver::add_lyric_phrasing (Grob_info inf)
143 Translator_group * tr = inf.origin_trans_->daddy_trans_;
144 while (tr && !tr->is_alias (ly_symbol2scm ("LyricsVoice")))
145 tr = tr->daddy_trans_;
151 Phrasing_association *a = get_phrasing_assoc (get_voice_name_for_lyric (tr));
152 a->lyrics_.push (inf.grob_);
153 a->past_extenders_.clear ();
157 Lyric_phrasing_engraver::stop_translation_timestep ()
159 for (int i = assocs_.size (); i--; )
161 assocs_[i]->heads_.clear ();
162 assocs_[i]->lyrics_.clear ();
163 assocs_[i]->past_extenders_.concat (assocs_[i]->new_extenders_) ;
164 assocs_[i]->new_extenders_.clear ();
169 Lyric_phrasing_engraver::process_acknowledged_grobs ()
171 for (int i = 0; i < assocs_.size (); i++)
173 Phrasing_association * a = assocs_[i];
174 if (! (a->heads_.size() && (a->lyrics_.size () || a->past_extenders_.size ())))
177 Grob *h = a->heads_[0];
178 Direction alignment = CENTER;
182 for (int j = 0; j < a->lyrics_.size (); j++)
184 Grob *l = a->lyrics_[j];
185 if (!l->get_parent (X_AXIS))
187 l->set_parent (h, X_AXIS);
189 l->set_grob_property ("self-alignment-X", gh_int2scm (alignment));
193 for (int j = a->past_extenders_.size(); j--;)
194 Pointer_group_interface::add_grob (a->past_extenders_[j],ly_symbol2scm ("heads"), h);
198 Lyric_phrasing_engraver::~Lyric_phrasing_engraver ()
200 for (int i =assocs_.size(); i--;)
204 ENTER_DESCRIPTION(Lyric_phrasing_engraver,
205 "This engraver combines note heads and lyrics for alignment. ",
208 "lyric-syllable-interface note-head-interface lyric-extender-interface",