#include "item.hh"
#include "spanner.hh"
#include "note-head.hh"
+#include "protected-scm.hh"
#include "warn.hh"
class Cluster_engraver : public Engraver
private:
Drul_array<Music*> reqs_drul_;
- Pitch pitch_min, pitch_max;
- Spanner *cluster;
- SCM columns_scm;
+ Pitch pitch_min_, pitch_max_;
+ Spanner *cluster_;
+ SCM columns_scm_;
};
void reset_min_max (Pitch *pitch_min, Pitch *pitch_max)
Cluster_engraver::Cluster_engraver ()
{
- cluster = 0;
- columns_scm = SCM_EOL;
+ cluster_ = 0;
+ columns_scm_ = SCM_EOL;
reqs_drul_[LEFT] = reqs_drul_[RIGHT] = 0;
}
{
reqs_drul_[START] = 0;
reqs_drul_[STOP] = 0;
- if (cluster)
+ if (cluster_)
{
- cluster->suicide ();
- cluster = 0;
- columns_scm = SCM_EOL;
+ cluster_->suicide ();
+ cluster_ = 0;
+ columns_scm_ = SCM_EOL;
}
}
else if (m->is_mus_type ("cluster-event"))
{
if (reqs_drul_[STOP])
{
- if (!cluster)
+ if (!cluster_)
{
reqs_drul_[STOP]->origin ()->warning ("can't find start of cluster");
}
else
{
Grob *bound = unsmob_grob (get_property ("currentMusicalColumn"));
- cluster->set_bound (RIGHT, bound);
- cluster->set_grob_property ("segments", columns_scm);
- typeset_grob (cluster);
- cluster = 0;
- columns_scm = SCM_EOL;
+ cluster_->set_bound (RIGHT, bound);
}
- reqs_drul_[STOP] = 0;
}
if (reqs_drul_[START])
{
- if (cluster)
+ if (cluster_)
{
reqs_drul_[START]->origin ()->warning ("may not nest clusters");
}
else
{
SCM basicProperties = get_property ("Cluster");
- cluster = new Spanner (basicProperties);
- columns_scm = SCM_EOL;
+ cluster_ = new Spanner (basicProperties);
+ columns_scm_ = SCM_EOL;
Grob *bound = unsmob_grob (get_property ("currentMusicalColumn"));
- cluster->set_bound (LEFT, bound);
- announce_grob (cluster, bound->self_scm ());
+ cluster_->set_bound (LEFT, bound);
+ announce_grob (cluster_, bound->self_scm ());
}
reqs_drul_[START] = 0;
}
void
Cluster_engraver::start_translation_timestep ()
{
- reset_min_max (&pitch_min, &pitch_max);
+ reset_min_max (&pitch_min_, &pitch_max_);
}
void
Cluster_engraver::stop_translation_timestep ()
{
- if (cluster)
+ if (cluster_)
{
SCM column_scm = get_property ("currentMusicalColumn");
if (column_scm == SCM_EOL)
{
programming_error("failed retrieving current column");
- return;
}
-
- if (Pitch::compare (pitch_min, pitch_max) <= 0)
+ else
{
- int staff_position = pitch_min.steps ();
- SCM c0 = get_property ("centralCPosition");
- if (gh_number_p (c0))
- staff_position += gh_scm2int (c0);
- SCM segment = scm_list_n (column_scm,
- gh_int2scm (staff_position),
- pitch_min.smobbed_copy (),
- pitch_max.smobbed_copy (),
- SCM_UNDEFINED);
- segment = scm_list_n (segment, SCM_UNDEFINED);
- columns_scm = (columns_scm != SCM_EOL) ?
- gh_append2 (columns_scm, segment) : segment;
+ if (Pitch::compare (pitch_min_, pitch_max_) <= 0)
+ {
+ Real y_bottom = 0.5 * pitch_min_.steps ();
+ SCM c0 = get_property ("centralCPosition");
+ if (gh_number_p (c0))
+ y_bottom += 0.5 * gh_scm2int (c0);
+ else
+ programming_error ("Cluster_engraver: failed evaluating c0");
+ Real y_top = y_bottom +
+ 0.5 * (pitch_max_.steps () - pitch_min_.steps ());
+ column_scm = Protected_scm (column_scm);
+ SCM segment = scm_list_n (column_scm,
+ gh_double2scm (y_bottom),
+ gh_double2scm (y_top),
+ SCM_UNDEFINED);
+ segment = scm_list_n (segment, SCM_UNDEFINED);
+ columns_scm_ = (columns_scm_ != SCM_EOL) ?
+ gh_append2 (columns_scm_, segment) : segment;
+ cluster_->set_grob_property ("segments", columns_scm_); // Urrgh!
+ }
+ else
+ {
+ /* This timestep is caused by a different voice of the
+ same staff and hence should be ignored. */
+ }
}
- else
+
+ if (reqs_drul_[STOP])
{
- /* This timestep is caused by a different voice of the same
- staff and hence should be ignored. */
+ reqs_drul_[STOP] = 0;
+ cluster_->set_grob_property ("segments", columns_scm_);
+ typeset_grob (cluster_);
+ cluster_ = 0;
+ columns_scm_ = SCM_EOL;
}
}
}
if (nr && nr->is_mus_type ("note-event"))
{
Pitch pitch = *unsmob_pitch (nr->get_mus_property ("pitch"));
- if (Pitch::compare (pitch_min, pitch_max) > 0) // already init'd?
+ if (Pitch::compare (pitch_min_, pitch_max_) > 0) // already init'd?
{
// not yet init'd; use current pitch to init min/max
- pitch_min = pitch;
- pitch_max = pitch;
+ pitch_min_ = pitch;
+ pitch_max_ = pitch;
}
- else if (Pitch::compare (pitch, pitch_max) > 0) // new max?
+ else if (Pitch::compare (pitch, pitch_max_) > 0) // new max?
{
- pitch_max = pitch;
+ pitch_max_ = pitch;
}
- else if (Pitch::compare (pitch, pitch_min) < 0) // new min?
+ else if (Pitch::compare (pitch, pitch_min_) < 0) // new min?
{
- pitch_min = pitch;
+ pitch_min_ = pitch;
}
}
}