/*
[TODO]
- * centre beam symbol
+ * center beam symbol
* less hairy code
* redo grouping
- */
+
+TODO:
+
+The relationship Stem <-> Beam is way too hairy. Let's figure who
+needs what, and what information should be available when.
+
+ */
#include <math.h>
-#include "p-col.hh"
-#include "array.hh"
#include "proto.hh"
#include "dimensions.hh"
#include "beam.hh"
-#include "abbreviation-beam.hh"
#include "misc.hh"
#include "debug.hh"
#include "molecule.hh"
left_y_ = 0;
quantisation_ = NORMAL;
multiple_i_ = 0;
- vertical_align_drul_[MIN] = 0;
- vertical_align_drul_[MAX] = -1;
}
void
Beam::add_stem (Stem*s)
{
+#if 0
+ if (!stems_.size ())
+ {
+ dim_cache_[Y_AXIS]->parent_l_ = s->dim_cache_[Y_AXIS];
+ }
+#endif
stems_.push (s);
s->add_dependency (this);
+
+ assert (!s->beam_l_);
s->beam_l_ = this;
if (!spanned_drul_[LEFT])
set_bounds (RIGHT,s);
}
+Stem_info
+Beam::get_stem_info (Stem *s)
+{
+ Stem_info i;
+ for (int i=0; i < sinfo_.size (); i++)
+ {
+ if (sinfo_[i].stem_l_ == s)
+ return sinfo_[i];
+ }
+ assert (false);
+ return i;
+}
+
Molecule*
Beam::do_brew_molecule_p () const
{
mol_p->translate_axis (x0
- spanned_drul_[LEFT]->absolute_coordinate (X_AXIS), X_AXIS);
- // correct if last note (and therefore reference point of beam)
- // is on different staff
- Stem_info si = sinfo_.top ();
- mol_p->translate_axis (-si.interstaff_f_ * si.stem_l_->staff_line_leading_f ()/2,
- Y_AXIS);
-
return mol_p;
}
Stem_info si = sinfo_[0];
Real w= (si.stem_l_->note_delta_f () + extent (X_AXIS).length ())/2.0;
- return Offset (w, (left_y_ + w* slope_f_) *
+ return Offset (w, ( w* slope_f_) *
si.stem_l_->staff_line_leading_f ()/2);
}
Beam::do_pre_processing ()
{
if (!dir_)
- set_default_dir ();
+ dir_ = get_default_dir ();
+
+
+ set_direction (dir_);
}
void
stems_.top ()->hpos_f ());
}
-void
-Beam::set_default_dir ()
+Direction
+Beam::get_default_dir () const
{
Drul_array<int> total;
total[UP] = total[DOWN] = 0;
Drul_array<int> count;
count[UP] = count[DOWN] = 0;
Direction d = DOWN;
-
+
+ Direction beamdir;
for (int i=0; i <stems_.size (); i++)
do {
Stem *s = stems_[i];
switch (a)
{
case MAJORITY:
- dir_ = (count[UP] > count[DOWN]) ? UP : DOWN;
+ beamdir = (count[UP] > count[DOWN]) ? UP : DOWN;
break;
case MEAN:
- // mean centre distance
- dir_ = (total[UP] > total[DOWN]) ? UP : DOWN;
+ // mean center distance
+ beamdir = (total[UP] > total[DOWN]) ? UP : DOWN;
break;
default:
case MEDIAN:
- // median centre distance
+ // median center distance
if (!count[UP])
- dir_ = DOWN;
+ beamdir = DOWN;
else if (!count[DOWN])
- dir_ = UP;
+ beamdir = UP;
else
- dir_ = (total[UP] / count[UP] > total[DOWN] / count[DOWN]) ? UP : DOWN;
+ beamdir = (total[UP] / count[UP] > total[DOWN] / count[DOWN]) ? UP : DOWN;
break;
}
+ return beamdir;
+}
+void
+Beam::set_direction (Direction d)
+{
+ dir_ = d;
for (int i=0; i <stems_.size (); i++)
{
Stem *s = stems_[i];
- s->set_elt_property (beam_dir_scm_sym, gh_int2scm (dir_));
+ s->set_elt_property (beam_dir_scm_sym, gh_int2scm (d));
SCM force = s->remove_elt_property (dir_forced_scm_sym);
if (force == SCM_BOOL_F)
- s->dir_ = dir_;
+ s->dir_ = d;
}
}
void
Beam::solve_slope ()
{
- /*
- should use minimum energy formulation (cf linespacing)
- */
assert (sinfo_.size () > 1);
DOUT << "Beam::solve_slope: \n";
l.minimise (slope_f_, left_y_);
}
+/*
+ ugh. Naming: this doesn't check, but sets as well.
+ */
+
Real
Beam::check_stemlengths_f (bool set_b)
{
for (int i=0; i < stems_.size (); i++)
{
Stem *s = stems_[i];
- s->mult_i_ = multiple_i_;
+
s->set_default_extents ();
if (s->invisible_b ())
continue;
total_count_i++;
}
- Real internote_f = stems_[0]->staff_line_leading_f ()/2;
+ bool grace_b = get_elt_property (grace_scm_sym) != SCM_BOOL_F;
+ String type_str = grace_b ? "grace_" : "";
int stem_max = (int)rint(paper_l ()->get_var ("stem_max"));
- Real shorten_f = paper_l ()->get_var (String ("forced_stem_shorten"
- + to_str (multiple_i_ <? stem_max)))
- / internote_f;
+ Real shorten_f = paper_l ()->get_var (type_str + "forced_stem_shorten"
+ + to_str (multiple_i_ <? stem_max));
Real leftx = 0;
for (int i=0; i < stems_.size (); i++)
if (s->invisible_b ())
continue;
- Stem_info info (s);
+ Stem_info info (s, multiple_i_);
if (leftx == 0)
leftx = info.x_;
info.x_ -= leftx;
Interval iv = quantise_iv (allowed_fraction, interline_f, dy_f);
- quanty_f = (dy_f - iv.min () <= iv.max () - dy_f)
- ? iv.min ()
- : iv.max ();
+ quanty_f = (dy_f - iv[SMALLER] <= iv[BIGGER] - dy_f)
+ ? iv[SMALLER]
+ : iv[BIGGER];
slope_f_ = (quanty_f / dx_f) / internote_f * sign (slope_f_);
Interval iv = quantise_iv (allowed_position, space, dy_f);
- Real quanty_f = dy_f - iv.min () <= iv.max () - dy_f ? iv.min () : iv.max ();
+ Real quanty_f = dy_f - iv[SMALLER] <= iv[BIGGER] - dy_f ? iv[SMALLER] : iv[BIGGER];
if (extend_b)
- quanty_f = iv.max ();
+ quanty_f = iv[BIGGER];
// dim(left_y_) = internote
left_y_ = dir_ * quanty_f / internote_f;
// enge floots
Real epsilon_f = staffline_f / 8;
- DOUT << "Beam::set_stemlens: \n";
Real dy_f = check_stemlengths_f (false);
for (int i = 0; i < 2; i++)
{
dy_f = check_stemlengths_f (true);
if (abs (dy_f) <= epsilon_f)
{
- DOUT << "Beam::set_stemlens: " << i << " iterations\n";
break;
}
}
Molecule
Beam::stem_beams (Stem *here, Stem *next, Stem *prev) const
{
- assert (!next || next->hpos_f () > here->hpos_f ());
- assert (!prev || prev->hpos_f () < here->hpos_f ());
+ if ((next && !(next->hpos_f () > here->hpos_f ())) ||
+ (prev && !(prev->hpos_f () < here->hpos_f ())))
+ programming_error ("Beams are not left-to-right");
Real staffline_f = paper_l ()->rule_thickness ();
Real interbeam_f = paper_l ()->interbeam_f (multiple_i_);
a.translate_axis( - stemdx/2, X_AXIS);
int j = 0;
Real gap_f = 0;
- if (here->beam_gap_i_)
+
+ SCM gap = get_elt_property (beam_gap_scm_sym);
+ if (gap != SCM_BOOL_F)
{
- int nogap = rwholebeams - here->beam_gap_i_;
+ int gap_i = gh_scm2int (gap);
+ int nogap = rwholebeams - gap_i;
+
for (; j < nogap; j++)
{
Molecule b (a);