slope_f_ = 0;
left_y_ = 0;
- multiple_i_ = 0;
+ multiplicity_i_ = 0;
}
/*
return gi.count ();
}
+Stem*
+Beam::stem_top ()const
+{
+ return Group_interface__extract_elements ((Beam*) this, (Stem*) 0, "stems")[stem_count () - 1];
+}
+
void
Beam::add_stem (Stem*s)
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
{
Molecule *mol_p = new Molecule;
- if (!sinfo_.size ())
+ if (!stem_count ())
return mol_p;
Real x0 = stem (0)->hpos_f ();
Molecule sb = stem_beams (i, next, prev);
Real x = i->hpos_f ()-x0;
- sb.translate (Offset (x, (x * slope_f_ + left_y_) *
- i->staff_line_leading_f ()/2 ));
+ sb.translate (Offset (x, x * slope_f_ + left_y_));
mol_p->add_molecule (sb);
}
mol_p->translate_axis (x0
Offset
Beam::center () const
{
- Stem_info si = sinfo_[0];
-
- Real w= (si.stem_l_->note_delta_f () + extent (X_AXIS).length ())/2.0;
- return Offset (w, ( w* slope_f_) *
- si.stem_l_->staff_line_leading_f ()/2);
+ Real w = (stem (0)->note_delta_f () + extent (X_AXIS).length ())/2.0;
+ return Offset (w, w * slope_f_);
}
/*
{
bool knee = false;
int knee_y = 0;
- Real internote_f = stem (0)->staff_line_leading_f ()/2;
if (gap != SCM_UNDEFINED)
{
int auto_gap_i = gh_scm2int (gap);
for (int i=1; i < stem_count (); i++)
{
- bool is_b = (bool)(sinfo_[i].interstaff_f_ - sinfo_[i-1].interstaff_f_);
- int l_y = (int)(stem (i-1)->chord_start_f () / internote_f)
- + (int)sinfo_[i-1].interstaff_f_;
- int r_y = (int)(stem (i)->chord_start_f () / internote_f)
- + (int)sinfo_[i].interstaff_f_;
+ bool is_b = (bool)(stem (i)->get_real ("interstaff-f") - stem (i-1)->get_real ("interstaff-f"));
+ int l_y = (int)(stem (i-1)->chord_start_f ())
+ + (int)stem (i-1)->get_real ("interstaff-f");
+ int r_y = (int)(stem (i)->chord_start_f ())
+ + (int)stem (i)->get_real ("interstaff-f");
int gap_i = r_y - l_y;
/*
{
for (int i=0; i < stem_count (); i++)
{
- int y = (int)(stem (i)->chord_start_f () / internote_f)
- + (int)sinfo_[i].interstaff_f_;
+ int y = (int)(stem (i)->chord_start_f ())
+ + (int)stem (i)->get_real ("interstaff-f");
stem (i)->set_direction ( y < knee_y ? UP : DOWN);
stem (i)->set_elt_property ("dir-forced", SCM_BOOL_T);
}
set_elt_property ("transparent", SCM_BOOL_T);
return;
}
- set_steminfo ();
+ beamify_stems ();
if (auto_knees ())
{
/*
if auto-knee did its work, most probably stem directions
have changed, so we must recalculate all.
*/
- set_direction ( get_default_dir ());
+ set_direction (get_default_dir ());
set_direction (get_direction ());
/* auto-knees used to only work for slope = 0
set_elt_property ("damping", gh_int2scm(1000));
*/
- sinfo_.clear ();
- set_steminfo ();
+ beamify_stems ();
}
calculate_slope ();
set_stemlens ();
void
Beam::solve_slope ()
{
- assert (sinfo_.size () > 1);
+ assert (stem_count () > 1);
Least_squares l;
- for (int i=0; i < sinfo_.size (); i++)
+ Real x0 = stem (0)->hpos_f ();
+ for (int i=0; i < stem_count (); i++)
{
- l.input.push (Offset (sinfo_[i].x_, sinfo_[i].idealy_f_));
+ l.input.push (Offset (stem (i)->hpos_f () - x0,
+ stem (i)->get_real ("idealy-f")));
}
l.minimise (slope_f_, left_y_);
}
Real
Beam::check_stemlengths_f (bool set_b)
{
- Real interbeam_f = paper_l ()->interbeam_f (multiple_i_);
+ Real interbeam_f = paper_l ()->interbeam_f (multiplicity_i_);
Real beam_f = gh_scm2double (get_elt_property ("beam-thickness"));
Real staffline_f = paper_l ()-> get_var ("stafflinethickness");
Real epsilon_f = staffline_f / 8;
Real dy_f = 0.0;
- for (int i=0; i < sinfo_.size (); i++)
+ Real x0 = stem (0)->hpos_f ();
+ Real internote_f = paper_l ()->get_var ("interline");
+ for (int i=0; i < stem_count (); i++)
{
- Real y = sinfo_[i].x_ * slope_f_ + left_y_;
+ Real y = (stem (i)->hpos_f () - x0) * slope_f_ + left_y_;
// correct for knee
- if (get_direction () != sinfo_[i].get_direction ())
+ if (get_direction () != stem (i)->get_direction ())
{
- Real internote_f = sinfo_[i].stem_l_->staff_line_leading_f ()/2;
y -= get_direction () * (beam_f / 2
- + (sinfo_[i].mult_i_ - 1) * interbeam_f) / internote_f;
- if (!i && sinfo_[i].stem_l_->staff_symbol_l () !=
- sinfo_.top ().stem_l_->staff_symbol_l ())
- y += get_direction () * (multiple_i_ - (sinfo_[i].stem_l_->flag_i_ - 2) >? 0)
- * interbeam_f / internote_f;
+ + (multiplicity_i_ - 1) * interbeam_f);
+ if (!i
+ && stem (i)->staff_symbol_l () != stem_top ()->staff_symbol_l ())
+ y += get_direction () * (multiplicity_i_ - (stem (i)->flag_i_ - 2) >? 0)
+ * interbeam_f;
}
+ /* caution: stem measures in staff-positions */
if (set_b)
- sinfo_[i].stem_l_->set_stemend (y - sinfo_[i].interstaff_f_);
+ stem (i)->set_stemend ((y - stem (i)->get_real ("interstaff-f"))
+ / internote_f);
y *= get_direction ();
- if (y > sinfo_[i].maxy_f_)
- dy_f = dy_f <? sinfo_[i].maxy_f_ - y;
- if (y < sinfo_[i].miny_f_)
+ if (y > stem (i)->get_real ("maxy-f"))
+ dy_f = dy_f <? stem (i)->get_real ("maxy-f") - y;
+ if (y < stem (i)->get_real ("miny-f"))
{
// when all too short, normal stems win..
if (dy_f < -epsilon_f)
warning (_ ("weird beam vertical offset"));
- dy_f = dy_f >? sinfo_[i].miny_f_ - y;
+ dy_f = dy_f >? stem (i)->get_real ("miny-f") - y;
}
}
return dy_f;
}
void
-Beam::set_steminfo ()
+Beam::beamify_stems ()
{
if(!stem_count ())
return;
- assert (multiple_i_);
+ assert (multiplicity_i_);
int total_count_i = 0;
int forced_count_i = 0;
total_count_i++;
}
+ Real internote_f = paper_l ()->get_var ("interline");
bool grace_b = get_elt_property ("grace") == SCM_BOOL_T;
String type_str = grace_b ? "grace_" : "";
int stem_max = (int)rint(paper_l ()->get_var ("stem_max"));
Real shorten_f = paper_l ()->get_var (type_str + "forced_stem_shorten"
- + to_str (multiple_i_ <? stem_max));
+ + to_str (multiplicity_i_ <? stem_max)) * internote_f;
- Real leftx = 0;
for (int i=0; i < stem_count (); i++)
{
Stem *s = stem (i);
continue;
}
- Stem_info info (s, multiple_i_);
- if (leftx == 0)
- leftx = info.x_;
- info.x_ -= leftx;
- if (info.get_direction () == get_direction ())
+ s->beamify ();
+ if (s->get_direction () == get_direction ())
{
if (forced_count_i == total_count_i)
- info.idealy_f_ -= shorten_f;
+ s->set_real ("idealy-f", s->get_real ("idealy-f") - shorten_f);
else if (forced_count_i > total_count_i / 2)
- info.idealy_f_ -= shorten_f / 2;
+ s->set_real ("idealy-f", s->get_real ("idealy-f") - shorten_f/2);
}
- sinfo_.push (info);
}
}
void
Beam::calculate_slope ()
{
- if (!sinfo_.size ())
+ if (!stem_count ())
slope_f_ = left_y_ = 0;
- else if (sinfo_[0].idealy_f_ == sinfo_.top ().idealy_f_)
+ else if (stem (0)->get_real ("idealy-f") == stem_top ()->get_real ("idealy-f"))
{
slope_f_ = 0;
- left_y_ = sinfo_[0].idealy_f_;
+ left_y_ = stem (0)->get_real ("idealy-f");
left_y_ *= get_direction ();
}
else
*/
Real dx_f = stem (stem_count () -1)->hpos_f () - stem (0)->hpos_f ();
- // urg, these y internote-y-dimensions
- Real internote_f = stem (0)->staff_line_leading_f ()/2;
-
- Real lengthened = paper_l ()->get_var ("beam_lengthened") / internote_f;
- Real steep = paper_l ()->get_var ("beam_steep_slope") / internote_f;
- if (((left_y_ - sinfo_[0].idealy_f_ > lengthened)
+ Real lengthened = paper_l ()->get_var ("beam_lengthened");
+ Real steep = paper_l ()->get_var ("beam_steep_slope");
+ if (((left_y_ - stem (0)->get_real ("idealy-f") > lengthened)
&& (slope_f_ > steep))
- || ((left_y_ + slope_f_ * dx_f - sinfo_.top ().idealy_f_ > lengthened)
+ || ((left_y_ + slope_f_ * dx_f - stem_top ()->get_real ("idealy-f") > lengthened)
&& (slope_f_ < -steep)))
{
slope_f_ = 0;
return;
Real interline_f = stem (0)->staff_line_leading_f ();
- Real internote_f = interline_f / 2;
Real staffline_f = paper_l ()->get_var ("stafflinethickness");
Real beam_f = gh_scm2double (get_elt_property ("beam-thickness"));;
Real dx_f = stem (stem_count () -1 )->hpos_f () - stem (0)->hpos_f ();
- // dim(y) = internote; so slope = (y/internote)/x
- Real dy_f = dx_f * abs (slope_f_ * internote_f);
+ Real dy_f = dx_f * abs (slope_f_);
Real quanty_f = 0.0;
allowed_fraction[1] = (beam_f / 2 + staffline_f / 2);
allowed_fraction[2] = (beam_f + staffline_f);
-
Interval iv = quantise_iv (allowed_fraction, interline_f, dy_f);
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_);
+ slope_f_ = (quanty_f / dx_f) * sign (slope_f_);
}
/*
*/
Real space = stem (0)->staff_line_leading_f ();
- Real internote_f = space /2;
Real staffline_f = paper_l ()->get_var ("stafflinethickness");
Real beam_f = gh_scm2double (get_elt_property ("beam-thickness"));;
*/
// isn't this asymmetric ? --hwn
- // dim(left_y_) = internote
- Real dy_f = get_direction () * left_y_ * internote_f;
+ Real dy_f = get_direction () * left_y_;
Real beamdx_f = stem (stem_count () -1)->hpos_f () - stem (0)->hpos_f ();
- Real beamdy_f = beamdx_f * slope_f_ * internote_f;
+ Real beamdy_f = beamdx_f * slope_f_;
Array<Real> allowed_position;
if (q == ly_symbol2scm ("normal"))
{
- if ((multiple_i_ <= 2) || (abs (beamdy_f) >= staffline_f / 2))
+ if ((multiplicity_i_ <= 2) || (abs (beamdy_f) >= staffline_f / 2))
allowed_position.push (straddle);
- if ((multiple_i_ <= 1) || (abs (beamdy_f) >= staffline_f / 2))
+ if ((multiplicity_i_ <= 1) || (abs (beamdy_f) >= staffline_f / 2))
allowed_position.push (sit);
allowed_position.push (hang);
}
else if (q == ly_symbol2scm ("traditional"))
{
// TODO: check and fix TRADITIONAL
- if ((multiple_i_ <= 2) || (abs (beamdy_f) >= staffline_f / 2))
+ if ((multiplicity_i_ <= 2) || (abs (beamdy_f) >= staffline_f / 2))
allowed_position.push (straddle);
- if ((multiple_i_ <= 1) && (beamdy_f <= staffline_f / 2))
+ if ((multiplicity_i_ <= 1) && (beamdy_f <= staffline_f / 2))
allowed_position.push (sit);
if (beamdy_f >= -staffline_f / 2)
allowed_position.push (hang);
if (extend_b)
quanty_f = iv[BIGGER];
- // dim(left_y_) = internote
- left_y_ = get_direction () * quanty_f / internote_f;
+ left_y_ = get_direction () * quanty_f;
}
void
{
Direction d = LEFT;
do {
- multiple_i_ = multiple_i_ >? stem (i)->beams_i_drul_[d];
+ multiplicity_i_ = multiplicity_i_ >? stem (i)->beams_i_drul_[d];
} while ((flip (&d)) != LEFT);
}
programming_error ("Beams are not left-to-right");
Real staffline_f = paper_l ()->get_var ("stafflinethickness");
- Real interbeam_f = paper_l ()->interbeam_f (multiple_i_);
-
- Real internote_f = here->staff_line_leading_f ()/2;
+ Real interbeam_f = paper_l ()->interbeam_f (multiplicity_i_);
Real beam_f = gh_scm2double (get_elt_property ("beam-thickness"));;
Real dy = interbeam_f;
Real stemdx = staffline_f;
- Real sl = slope_f_* internote_f;
+ Real sl = slope_f_;
Molecule leftbeams;
Molecule rightbeams;
-/*
- stem-info.cc -- implement Stem_info
-
- source file of the GNU LilyPond music typesetter
-
- (c) 1997--1999 Jan Nieuwenhuizen <janneke@gnu.org>
-
-*/
-
-#include "proto.hh"
-#include "misc.hh"
-#include "cross-staff.hh"
-#include "debug.hh"
-#include "stem.hh"
-#include "paper-def.hh"
-#include "lookup.hh"
-#include "stem-info.hh"
-#include "beam.hh"
-
-
-Stem_info::Stem_info ()
-{
-}
-
-
-/*
- FIXME: y dims should not be in internote.
-
-
- GURG UGRGINRG INA UG R
-
- JUNKME -> this should set elt properties of STEM.
-*/
-Stem_info::Stem_info (Stem*s, int mult)
-{
- mult_i_ =mult;
- stem_l_ = s;
- Beam* beam_l = stem_l_->beam_l ();
-
- x_ = stem_l_->hpos_f ();
- set_direction (stem_l_->get_direction ());
- SCM bd = stem_l_->remove_elt_property ("beam-dir");
-
- if (gh_number_p (bd))
- {
- beam_dir_ = gh_scm2int (bd);
- }
- else
- {
- programming_error ("Beam direction not set.");
- beam_dir_ = UP; // GURAUGRNAGURAGU! urg !
- }
-
- Paper_def* paper_l = stem_l_->paper_l ();
- Real internote_f = stem_l_->staff_line_leading_f ()/2;
- Real interbeam_f = paper_l->interbeam_f (mult_i_);
- Real beam_f = gh_scm2double (beam_l->get_elt_property ("beam-thickness"));
-
-
- // strangely enough, dim(chord_start_f) == pt (and not internote!)
- idealy_f_ = stem_l_->chord_start_f () / internote_f;
-
- // calculate using dim(y) == pt
- idealy_f_ *= internote_f;
-
- // for simplicity, we calculate as if dir == UP
- idealy_f_ *= beam_dir_;
-
- bool grace_b = stem_l_->get_elt_property ("grace") != SCM_UNDEFINED;
- bool no_extend_b = stem_l_->get_elt_property ("no-stem-extend")
- != SCM_UNDEFINED;
-
- int stem_max = (int)rint(paper_l->get_var ("stem_max"));
- String type_str = grace_b ? "grace_" : "";
- Real min_stem_f = paper_l->get_var (type_str + "minimum_stem_length"
- + to_str (mult_i_ <? stem_max)) * internote_f;
- Real stem_f = paper_l->get_var (type_str + "stem_length"
- + to_str (mult_i_ <? stem_max))* internote_f;
-
- if (!beam_dir_ || (beam_dir_ == get_direction ()))
- /* normal beamed stem */
- {
- if (mult_i_)
- {
- idealy_f_ += beam_f;
- idealy_f_ += (mult_i_ - 1) * interbeam_f;
- }
- miny_f_ = idealy_f_;
- maxy_f_ = INT_MAX;
-
- idealy_f_ += stem_f;
- miny_f_ += min_stem_f;
-
- /*
- lowest beam of (UP) beam must never be lower than second staffline
-
- Hmm, reference (Wanske?)
-
- Although this (additional) rule is probably correct,
- I expect that highest beam (UP) should also never be lower
- than middle staffline, just as normal stems.
-
- */
- if (!grace_b && !no_extend_b)
- {
- //highest beam of (UP) beam must never be lower than middle staffline
- miny_f_ = miny_f_ >? 0;
- //lowest beam of (UP) beam must never be lower than second staffline
- miny_f_ = miny_f_ >? (- 2 * internote_f - beam_f
- + (mult_i_ > 0) * beam_f + interbeam_f * (mult_i_ - 1));
- }
- }
- else
- /* knee */
- {
- idealy_f_ -= beam_f;
- maxy_f_ = idealy_f_;
- miny_f_ = -INT_MAX;
-
- idealy_f_ -= stem_f;
- maxy_f_ -= min_stem_f;
- }
-
- // set dim(y) == internote
- idealy_f_ /= internote_f;
- miny_f_ /= internote_f;
- maxy_f_ /= internote_f;
-
- idealy_f_ = maxy_f_ <? idealy_f_;
- idealy_f_ = miny_f_ >? idealy_f_;
-
- interstaff_f_ = calc_interstaff_dist (stem_l_, beam_l) / internote_f;
- idealy_f_ += interstaff_f_* beam_dir_;
- miny_f_ += interstaff_f_ * beam_dir_;
- maxy_f_ += interstaff_f_ * beam_dir_;
-}
-
-
source file of the GNU LilyPond music typesetter
(c) 1996, 1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+ Jan Nieuwenhuizen <janneke@gnu.org>
TODO: This is way too hairy
*/
#include "beam.hh"
#include "rest.hh"
#include "group-interface.hh"
+#include "cross-staff.hh"
Stem::Stem ()
{
SCM b= get_elt_property ("beam");
return dynamic_cast<Beam*> (unsmob_element (b));
}
+
+
+/*
+ stupid name: we're calculating and setting (caching??)
+ some stem length parameters for beamed stem
+*/
+void
+Stem::beamify ()
+{
+ assert (beam_l ());
+
+ SCM bd = remove_elt_property ("beam-dir");
+ Real internote_f = staff_line_leading_f ()/2;
+
+ Direction beam_dir;
+ Real idealy_f;
+ Real interstaff_f;
+ Real maxy_f;
+ Real miny_f;
+
+ if (gh_number_p (bd))
+ {
+ beam_dir = (Direction)gh_scm2int (bd);
+ }
+ else
+ {
+ programming_error ("Beam direction not set.");
+ beam_dir = UP; // GURAUGRNAGURAGU! urg !
+ }
+
+ Real interbeam_f = paper_l ()->interbeam_f (beam_l ()->multiplicity_i_);
+ Real beam_f = gh_scm2double (beam_l ()->get_elt_property ("beam-thickness"));
+
+ idealy_f = chord_start_f ();
+
+ // for simplicity, we calculate as if dir == UP
+ idealy_f *= beam_dir;
+
+ bool grace_b = get_elt_property ("grace") != SCM_UNDEFINED;
+ bool no_extend_b = get_elt_property ("no-stem-extend") != SCM_UNDEFINED;
+
+ int stem_max = (int)rint(paper_l ()->get_var ("stem_max"));
+ String type_str = grace_b ? "grace_" : "";
+ Real min_stem_f = paper_l ()->get_var (type_str + "minimum_stem_length"
+ + to_str (beam_l ()->multiplicity_i_ <? stem_max)) * internote_f;
+ Real stem_f = paper_l ()->get_var (type_str + "stem_length"
+ + to_str (beam_l ()->multiplicity_i_ <? stem_max)) * internote_f;
+
+ if (!beam_dir || (beam_dir == get_direction ()))
+ /* normal beamed stem */
+ {
+ if (beam_l ()->multiplicity_i_)
+ {
+ idealy_f += beam_f;
+ idealy_f += (beam_l ()->multiplicity_i_ - 1) * interbeam_f;
+ }
+ miny_f = idealy_f;
+ maxy_f = INT_MAX;
+
+ idealy_f += stem_f;
+ miny_f += min_stem_f;
+
+ /*
+ lowest beam of (UP) beam must never be lower than second staffline
+
+ Hmm, reference (Wanske?)
+
+ Although this (additional) rule is probably correct,
+ I expect that highest beam (UP) should also never be lower
+ than middle staffline, just as normal stems.
+
+ */
+ if (!grace_b && !no_extend_b)
+ {
+ //highest beam of (UP) beam must never be lower than middle staffline
+ miny_f = miny_f >? 0;
+ //lowest beam of (UP) beam must never be lower than second staffline
+ miny_f = miny_f >? (- 2 * internote_f - beam_f
+ + (beam_l ()->multiplicity_i_ > 0) * beam_f + interbeam_f * (beam_l ()->multiplicity_i_ - 1));
+ }
+ }
+ else
+ /* knee */
+ {
+ idealy_f -= beam_f;
+ maxy_f = idealy_f;
+ miny_f = -INT_MAX;
+
+ idealy_f -= stem_f;
+ maxy_f -= min_stem_f;
+ }
+
+ idealy_f = maxy_f <? idealy_f;
+ idealy_f = miny_f >? idealy_f;
+
+ interstaff_f = calc_interstaff_dist (this, beam_l ());
+ idealy_f += interstaff_f * beam_dir;
+ miny_f += interstaff_f * beam_dir;
+ maxy_f += interstaff_f * beam_dir;
+
+ set_elt_property ("interstaff-f", gh_double2scm (interstaff_f));
+ set_elt_property ("idealy-f", gh_double2scm (idealy_f));
+ set_elt_property ("miny-f", gh_double2scm (miny_f));
+ set_real ("maxy-f", gh_double2scm (maxy_f));
+}
+