/*
This file is part of LilyPond, the GNU music typesetter.
- Copyright (C) 2008--2011 Han-Wen Nienhuys <hanwen@lilypond.org>
+ Copyright (C) 2008--2015 Han-Wen Nienhuys <hanwen@lilypond.org>
LilyPond is free software: you can redistribute it and/or modify
class Dynamic_align_engraver : public Engraver
{
TRANSLATOR_DECLARATIONS (Dynamic_align_engraver);
- DECLARE_ACKNOWLEDGER (note_column);
- DECLARE_ACKNOWLEDGER (dynamic);
- DECLARE_ACKNOWLEDGER (footnote_spanner);
- DECLARE_END_ACKNOWLEDGER (dynamic);
+ void acknowledge_rhythmic_head (Grob_info);
+ void acknowledge_stem (Grob_info);
+ void acknowledge_dynamic (Grob_info);
+ void acknowledge_footnote_spanner (Grob_info);
+ void acknowledge_end_dynamic (Grob_info);
protected:
virtual void stop_translation_timestep ();
private:
- void create_line_spanner (Stream_event *cause);
+ void create_line_spanner (Grob *cause);
void set_spanner_bounds (Spanner *line, bool end);
Spanner *line_;
Spanner *ended_line_; // Spanner manually broken, don't use it for new grobs
set<Spanner *> running_;
};
-Dynamic_align_engraver::Dynamic_align_engraver ()
+Dynamic_align_engraver::Dynamic_align_engraver (Context *c)
+ : Engraver (c)
{
line_ = 0;
ended_line_ = 0;
current_dynamic_spanner_ = 0;
}
-ADD_ACKNOWLEDGER (Dynamic_align_engraver, dynamic);
-ADD_ACKNOWLEDGER (Dynamic_align_engraver, note_column);
-ADD_ACKNOWLEDGER (Dynamic_align_engraver, footnote_spanner);
-ADD_END_ACKNOWLEDGER (Dynamic_align_engraver, dynamic);
void
-Dynamic_align_engraver::create_line_spanner (Stream_event *event)
+Dynamic_align_engraver::create_line_spanner (Grob *cause)
{
if (!line_)
- line_ = make_spanner ("DynamicLineSpanner",
- event ? event->self_scm () : SCM_EOL);
+ line_ = make_spanner ("DynamicLineSpanner", cause->self_scm ());
}
void
Dynamic_align_engraver::acknowledge_end_dynamic (Grob_info info)
{
- if (Spanner::has_interface (info.grob ()))
+ if (has_interface<Spanner> (info.grob ()))
ended_.push_back (info.spanner ());
/* If the break flag is set, store the current spanner and let new dynamics
- * create a new spanner
+ * create a new spanner
*/
- bool spanner_broken = current_dynamic_spanner_ == info.spanner () &&
- to_boolean (current_dynamic_spanner_->get_property ("spanner-broken"));
+ bool spanner_broken = current_dynamic_spanner_ == info.spanner ()
+ && to_boolean (current_dynamic_spanner_->get_property ("spanner-broken"));
if (spanner_broken && line_)
{
if (ended_line_)
}
void
-Dynamic_align_engraver::acknowledge_note_column (Grob_info info)
+Dynamic_align_engraver::acknowledge_rhythmic_head (Grob_info info)
+{
+ support_.push_back (info.grob ());
+}
+
+void
+Dynamic_align_engraver::acknowledge_stem (Grob_info info)
{
support_.push_back (info.grob ());
}
}
}
- create_line_spanner (cause);
- if (Spanner::has_interface (info.grob ()))
+ create_line_spanner (info.grob ());
+ if (has_interface<Spanner> (info.grob ()))
{
started_.push_back (info.spanner ());
current_dynamic_spanner_ = info.spanner ();
if (cause)
{
if (Direction d = to_dir (cause->get_property ("direction")))
- set_grob_direction (line_, d);
+ set_grob_direction (line_, d);
}
}
{
if (!line)
return;
- Direction d = LEFT;
- do
+
+ for (LEFT_and_RIGHT (d))
{
- if ((d == LEFT && !line->get_bound (LEFT)) ||
- (end && d == RIGHT && !line->get_bound (RIGHT)))
- {
- vector<Spanner *> const &spanners
- = (d == LEFT) ? started_ : ended_;
-
- Grob *bound = 0;
- if (scripts_.size ())
- bound = scripts_[0];
- else if (spanners.size ())
- bound = spanners[0]->get_bound (d);
- else
- {
- bound = unsmob_grob (get_property ("currentMusicalColumn"));
- programming_error ("started DynamicLineSpanner but have no left bound");
- }
-
- line->set_bound (d, bound);
- }
+ if ((d == LEFT && !line->get_bound (LEFT))
+ || (end && d == RIGHT && !line->get_bound (RIGHT)))
+ {
+ vector<Spanner *> const &spanners
+ = (d == LEFT) ? started_ : ended_;
+
+ Grob *bound = 0;
+ if (scripts_.size ())
+ bound = scripts_[0];
+ else if (spanners.size ())
+ bound = spanners[0]->get_bound (d);
+ else
+ {
+ bound = unsmob<Grob> (get_property ("currentMusicalColumn"));
+ programming_error ("started DynamicLineSpanner but have no left bound");
+ }
+
+ line->set_bound (d, bound);
+ }
}
- while (flip (&d) != LEFT);
}
void
set<Spanner *>::iterator it = running_.find (sp);
if (it != running_.end ())
- running_.erase (it);
+ running_.erase (it);
else
- started_[i]->programming_error ("lost track of this dynamic spanner");
+ started_[i]->programming_error ("lost track of this dynamic spanner");
}
bool end = line_ && running_.empty ();
// is ended now
set_spanner_bounds (ended_line_, true);
set_spanner_bounds (line_, end);
- // If the flag is set to break the spanner after the current child, don't
+ // If the flag is set to break the spanner after the current child, don't
// add any more support points (needed e.g. for style=none, where the
// invisible spanner should NOT be shifted since we don't have a line).
- bool spanner_broken = current_dynamic_spanner_ &&
- to_boolean (current_dynamic_spanner_->get_property ("spanner-broken"));
+ bool spanner_broken = current_dynamic_spanner_
+ && to_boolean (current_dynamic_spanner_->get_property ("spanner-broken"));
for (vsize i = 0; line_ && !spanner_broken && i < support_.size (); i++)
Side_position_interface::add_support (line_, support_[i]);
support_.clear ();
}
+void
+Dynamic_align_engraver::boot ()
+{
+ ADD_ACKNOWLEDGER (Dynamic_align_engraver, dynamic);
+ ADD_ACKNOWLEDGER (Dynamic_align_engraver, rhythmic_head);
+ ADD_ACKNOWLEDGER (Dynamic_align_engraver, stem);
+ ADD_ACKNOWLEDGER (Dynamic_align_engraver, footnote_spanner);
+ ADD_END_ACKNOWLEDGER (Dynamic_align_engraver, dynamic);
+}
+
ADD_TRANSLATOR (Dynamic_align_engraver,
- /* doc */
- "Align hairpins and dynamic texts on a horizontal line.",
+ /* doc */
+ "Align hairpins and dynamic texts on a horizontal line.",
- /* create */
- "DynamicLineSpanner ",
+ /* create */
+ "DynamicLineSpanner ",
- /* read */
- "currentMusicalColumn ",
+ /* read */
+ "currentMusicalColumn ",
- /* write */
- ""
- );
+ /* write */
+ ""
+ );