/*
This file is part of LilyPond, the GNU music typesetter.
- Copyright (C) 1997--2011 Han-Wen Nienhuys <hanwen@xs4all.nl>
+ Copyright (C) 1997--2012 Han-Wen Nienhuys <hanwen@xs4all.nl>
LilyPond is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
{
Grob *stem_;
Grob *tremolo_;
+ vector <Grob *> maybe_flags_;
Stream_event *rhythmic_ev_;
Stream_event *tremolo_ev_;
+ bool tuplet_start_;
TRANSLATOR_DECLARATIONS (Stem_engraver);
protected:
- void make_stem (Grob_info);
+ void make_stem (Grob_info, bool);
DECLARE_TRANSLATOR_LISTENER (tremolo);
+ DECLARE_TRANSLATOR_LISTENER (tuplet_span);
DECLARE_ACKNOWLEDGER (rhythmic_head);
void stop_translation_timestep ();
+ void finalize ();
+ void kill_unused_flags ();
};
Stem_engraver::Stem_engraver ()
stem_ = 0;
tremolo_ = 0;
rhythmic_ev_ = 0;
+ tuplet_start_ = false;
}
void
-Stem_engraver::make_stem (Grob_info gi)
+Stem_engraver::make_stem (Grob_info gi, bool tuplet_start)
{
/* Announce the cause of the head as cause of the stem. The
stem needs a rhythmic structure to fit it into a beam. */
stem_ = make_item ("Stem", gi.grob ()->self_scm ());
-
+ if (tuplet_start)
+ stem_->set_property ("tuplet-start", SCM_BOOL_T);
+ (void) make_item ("StemStub", gi.grob ()->self_scm ());
if (tremolo_ev_)
{
/* Stem tremolo is never applied to a note by default,
return;
if (!stem_)
- make_stem (gi);
+ make_stem (gi, tuplet_start_);
int ds = Stem::duration_log (stem_);
int dc = d->duration_log ();
}
Stem::add_head (stem_, gi.grob ());
+
+ if (Stem::is_normal_stem (stem_)
+ && Stem::duration_log (stem_) > 2)
+ {
+ Item *flag = make_item ("Flag", stem_->self_scm ());
+ flag->set_parent (stem_, X_AXIS);
+ stem_->set_object ("flag", flag->self_scm ());
+ maybe_flags_.push_back (flag);
+ }
+ if (tuplet_start_)
+ stem_->set_property ("tuplet-start", SCM_BOOL_T);
+}
+
+void
+Stem_engraver::kill_unused_flags ()
+{
+ for (vsize i = 0; i < maybe_flags_.size (); i++)
+ if (unsmob_grob (maybe_flags_[i]->get_parent (X_AXIS)->get_object ("beam")))
+ maybe_flags_[i]->suicide ();
+}
+
+void
+Stem_engraver::finalize ()
+{
+ kill_unused_flags ();
}
void
Stem_engraver::stop_translation_timestep ()
{
+ if (scm_is_string (get_property ("whichBar")))
+ kill_unused_flags ();
+
tremolo_ = 0;
if (stem_)
{
}
stem_ = 0;
}
+ tuplet_start_ = false;
tremolo_ev_ = 0;
}
+IMPLEMENT_TRANSLATOR_LISTENER (Stem_engraver, tuplet_span);
+void
+Stem_engraver::listen_tuplet_span (Stream_event *ev)
+{
+ Direction dir = to_dir (ev->get_property ("span-direction"));
+ if (dir == START)
+ {
+ // set stem property if stem already exists
+ if (stem_)
+ stem_->set_property ("tuplet-start", SCM_BOOL_T);
+ tuplet_start_ = true; // stash the value for use in later creation
+ }
+}
+
IMPLEMENT_TRANSLATOR_LISTENER (Stem_engraver, tremolo);
void
Stem_engraver::listen_tremolo (Stream_event *ev)
/* read */
"tremoloFlags "
"stemLeftBeamCount "
- "stemRightBeamCount ",
+ "stemRightBeamCount "
+ "whichBar ",
/* write */
""