2 quote-iterator.cc -- implement Quote_iterator
4 source file of the GNU LilyPond music typesetter
6 (c) 2004 Han-Wen Nienhuys <hanwen@xs4all.nl>
12 #include "music-sequence.hh"
13 #include "lily-guile.hh"
14 #include "music-iterator.hh"
20 class Quote_iterator : public Music_iterator
30 SCM transposed_musics_;
32 DECLARE_SCHEME_CALLBACK (constructor, ());
35 virtual void derived_mark ();
36 virtual void construct_children ();
37 virtual Moment pending_moment () const;
38 virtual void process (Moment);
39 virtual bool ok () const;
43 Quote_iterator::derived_mark ()
45 scm_gc_mark (transposed_musics_ );
48 Quote_iterator::Quote_iterator ()
50 event_vector_ = SCM_EOL;
56 moment_less (SCM a, SCM b)
58 return *unsmob_moment (a) < *unsmob_moment (b);
63 binsearch_scm_vector (SCM vec, SCM key, bool (*is_less)(SCM a,SCM b))
66 int hi = SCM_VECTOR_LENGTH (vec);
71 int cmp = (lo + hi) / 2;
73 SCM when = ly_caar (SCM_VECTOR_REF (vec, cmp));
74 bool result = (*is_less) (key, when);
87 Quote_iterator::construct_children ()
89 SCM dur = get_music ()->get_property ("duration");
90 if (!unsmob_duration (dur))
93 set_translator (get_outlet ()->get_default_interpreter ());
95 Moment now = get_outlet ()->now_mom ();
96 Moment stop = now + unsmob_duration (dur)->get_length ();
99 event_vector_ = get_music ()->get_property ("quoted-events");
101 if (ly_c_vector_p (event_vector_))
103 event_idx_ = binsearch_scm_vector (event_vector_, now.smobbed_copy (), &moment_less);
104 end_idx_ = binsearch_scm_vector (event_vector_, stop.smobbed_copy (), &moment_less);
108 get_music ()->origin()->warning (_("No events found for \\quote"));
114 Quote_iterator::ok () const
116 return ly_c_vector_p (event_vector_) && (event_idx_ <= end_idx_);
121 Quote_iterator::pending_moment () const
123 SCM entry = SCM_VECTOR_REF (event_vector_, event_idx_);
124 return *unsmob_moment (ly_caar (entry)) - start_moment_;
129 Quote_iterator::process (Moment m)
134 while (event_idx_ < end_idx_)
136 entry = SCM_VECTOR_REF (event_vector_, event_idx_);
138 Moment em = *unsmob_moment (ly_caar (entry));
149 if (ly_c_pair_p (entry))
151 Pitch * quote_pitch = unsmob_pitch (ly_cdar (entry));
152 Pitch * me_pitch = unsmob_pitch (get_outlet ()->get_property ("instrumentTransposition"));
154 for (SCM s = ly_cdr (entry); ly_c_pair_p (s); s = ly_cdr (s))
156 SCM ev_acc = ly_car (s);
159 Music * mus = unsmob_music (ly_car (ev_acc));
162 if (quote_pitch || me_pitch)
170 Pitch diff = interval (mp, qp);
172 SCM copy = ly_deep_mus_copy (mus->self_scm ());
173 mus = unsmob_music (copy);
174 transposed_musics_ = scm_cons (copy, transposed_musics_);
176 mus->transpose (diff);
180 bool b = get_outlet ()->try_music (mus);
183 mus->origin ()->warning (_f ("In quotation: junking event %s", mus->name ()));
186 programming_error ("need music in quote.");
192 IMPLEMENT_CTOR_CALLBACK (Quote_iterator);