source file of the GNU LilyPond music typesetter
- (c) 1997--2001 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+ (c) 1997--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
*/
#include "translator-group.hh"
#include "debug.hh"
#include "sequential-music-iterator.hh"
#include "music-list.hh"
-#include "request-chord-iterator.hh"
+
+/*
+
+ TODO: handling of grace notes is exquisite pain. This handling
+ should be formally specified and then the implementation verified.
+
+*/
+
+/*
+
+ TODO: the grace note handling hasn't been done for skip() and
+ get_music(), meaning that staff-switching and partcombining will be
+ broken with grace notes.
+
+ */
+/*
+
+ TODO: the grace note handling hasn't been done for skip() and
+ get_music(), meaning that staff-switching and partcombining will be
+ broken with grace notes.
+
+ */
/*
Invariant for the data structure.
if (gh_pair_p (cursor_))
- iter_p_->music_l_ == unsmob_music (gh_car (cursor_))
+ iter_p_->music_l_ == unsmob_music (ly_car (cursor_))
else
iter_p_ == 0;
{
cursor_ = SCM_EOL;
here_mom_ = Moment (0);
- grace_skips_ = 0;
+ grace_fixups_ = 0;
iter_p_ =0;
}
Sequential_music_iterator::Sequential_music_iterator (Sequential_music_iterator const &src)
: Music_iterator (src)
{
- grace_skips_ = src.grace_skips_;
+ grace_fixups_ = src.grace_fixups_;
cursor_ = src.cursor_;
here_mom_ = src.here_mom_;
if (src.iter_p_)
}
-Grace_skip *
-get_grace_skips (SCM cursor)
+/*
+
+
+ if (start_music.grace)
+ here.grace -= start_music.grace
+
+ last
+ if (len
+
+ */
+
+Grace_fixup *
+get_grace_fixups (SCM cursor)
{
- Moment here (0);
+ Moment here;
Moment last (-1);
- Grace_skip *head = 0;
- Grace_skip **tail = &head;
-
- for (; gh_pair_p (cursor); cursor = gh_cdr (cursor))
+ Grace_fixup *head = 0;
+ Grace_fixup **tail = &head;
+
+ for (; gh_pair_p (cursor); cursor = ly_cdr (cursor))
{
- Music * mus = unsmob_music (gh_car (cursor));
- Moment l =mus->length_mom ();
+ Music * mus = unsmob_music (ly_car (cursor));
Moment s = mus->start_mom ();
+ Moment l =mus->length_mom () - s;
- if (s.grace_part_ && last >= Moment (0))
+ if (s.grace_part_)
{
- Grace_skip *p =new Grace_skip;
- p->start_ = last;
- p->length_ = (here - last).main_part_;
- p->grace_start_ = s.grace_part_;
- p->next_ = 0;
- *tail = p;
- tail = &(*tail)->next_;
+ if (last != Moment (-1))
+ {
+ Grace_fixup *p =new Grace_fixup;
+ p->start_ = last;
+ p->length_ = here - last;
+ p->grace_start_ = s.grace_part_;
+ p->next_ = 0;
+ *tail = p;
+ tail = &(*tail)->next_;
+ }
+
+ here.grace_part_ = s.grace_part_;
}
- if (l.main_part_)
+ if (l.to_bool())
{
- l.grace_part_ = Rational (0);
last = here;
here += l;
}
{
cursor_ = dynamic_cast<Music_sequence const*> (music_l ())->music_list ();
- iter_p_ = gh_pair_p (cursor_) ? get_iterator_p (unsmob_music (gh_car (cursor_))) : 0;
+ iter_p_ = gh_pair_p (cursor_) ? get_iterator_p (unsmob_music (ly_car (cursor_))) : 0;
while (iter_p_ && !iter_p_->ok ())
{
next_element ();
}
- grace_skips_ = get_grace_skips (cursor_);
-
here_mom_ = music_l ()->start_mom ();
+ grace_fixups_ = get_grace_fixups (cursor_);
/*
iter_p_->ok () is tautology, but what the heck.
void
Sequential_music_iterator::next_element ()
{
- Moment len =iter_p_->music_length_mom ();
- Moment start = iter_p_->music_start_mom ();
- assert (!grace_skips_ || grace_skips_->start_ >= here_mom_);
+ Moment len =iter_p_->music_length_mom () - iter_p_->music_start_mom ();
+ assert (!grace_fixups_ || grace_fixups_->start_ >= here_mom_);
- if (len.main_part_ && grace_skips_ && grace_skips_->start_ == here_mom_)
+ if (len.main_part_ && grace_fixups_ &&
+ grace_fixups_->start_ == here_mom_)
{
- Moment sk;
- sk.main_part_ = grace_skips_->length_;
- here_mom_ += sk;
- here_mom_.grace_part_ = grace_skips_->grace_start_;
-
- Grace_skip * n =grace_skips_->next_;
- delete grace_skips_;
- grace_skips_ = n;
+ here_mom_ += grace_fixups_->length_;
+ here_mom_.grace_part_ += grace_fixups_->grace_start_;
+
+ Grace_fixup * n =grace_fixups_->next_;
+ delete grace_fixups_;
+ grace_fixups_ = n;
}
else if (len.grace_part_ && !len.main_part_)
{
!len.grace_part_ || len.main_part_
We skip over a big chunk (mainpart != 0). Any starting graces
- in that chunk are compensated by subtracting START.
+ in that chunk should be in len.grace_part_
*/
- here_mom_ += len - start;
+ here_mom_ += len;
}
delete iter_p_;
- cursor_ = gh_cdr (cursor_);
+ cursor_ = ly_cdr (cursor_);
if (gh_pair_p (cursor_))
- iter_p_ = get_iterator_p (unsmob_music (gh_car (cursor_)));
+ iter_p_ = get_iterator_p (unsmob_music (ly_car (cursor_)));
else
iter_p_ = 0;
}
s = gh_append2 (nm, s);
Moment m = 0;
- for (SCM i = nm; gh_pair_p (i); i = gh_cdr (i))
- m = m >? unsmob_music (gh_car (i))->length_mom ();
-
+ for (SCM i = nm; gh_pair_p (i); i = ly_cdr (i))
+ {
+ Music *mus=unsmob_music (ly_car (i));
+ m = m >? (mus->length_mom () - mus->start_mom ());
+ }
if (m > Moment (0))
break ;
else
return s;
}
+
+
/*
Skip events till UNTIL. We don't do any other side effects such as
descending to child iterator contexts, because they might depend on
\context specs and \translator changes being executed
-
+
+ TODO: build support for grace notes here.
*/
void
Sequential_music_iterator::skip (Moment until)
{
while (iter_p_)
{
- if (grace_skips_ &&
- grace_skips_->start_ == here_mom_
- && (grace_skips_->start_ + grace_skips_->length_).main_part_ ==
- until.main_part_)
+ if (grace_fixups_ &&
+ grace_fixups_->start_ == here_mom_
+ && (grace_fixups_->start_ + grace_fixups_->length_
+ + Moment (Rational (0), grace_fixups_->grace_start_) == until))
{
/*
do the stuff/note/rest preceding a grace.
*/
- Moment u = until;
- u.grace_part_ = 0;
- iter_p_->process (u - here_mom_);
+ iter_p_->process (iter_p_->music_length_mom ());
}
else
iter_p_->process (until - here_mom_ + iter_p_->music_start_mom ());
/*
Fix-up a grace note halfway in the music.
*/
- if (grace_skips_ && here_mom_ == grace_skips_->start_
- && cp.main_part_ >= grace_skips_->length_)
+ if (grace_fixups_ && here_mom_ == grace_fixups_->start_
+ && grace_fixups_->length_ + iter_p_->music_start_mom () == cp)
{
- cp += here_mom_ ;
- cp.grace_part_ = grace_skips_->grace_start_;
- return cp;
-
+ return here_mom_ + grace_fixups_->length_ + Moment (0, grace_fixups_->grace_start_);
}
- /*
- Fix-up a grace note at the start of the music.
- */
+ /*
+ Fix-up a grace note at the start of the music.
+ */
return cp + here_mom_ - iter_p_->music_start_mom ();
}