source file of the GNU LilyPond music typesetter
- (c) 1997--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+ (c) 1997--2009 Han-Wen Nienhuys <hanwen@xs4all.nl>
Jan Nieuwenhuizen <janneke@gnu.org>
*/
#include <algorithm>
using namespace std;
+#include "grob.hh"
#include "align-interface.hh"
#include "international.hh"
#include "output-def.hh"
#include "staff-symbol-referencer.hh"
#include "stem.hh"
#include "warn.hh"
+#include "main.hh"
Real
get_detail (SCM alist, SCM sym, Real def)
{
SCM details = him->get_property ("details");
+ /*
+ TODO: The default values should be copied to define-grobs.scm.
+ */
INTER_QUANT_PENALTY = get_detail (details, ly_symbol2scm ("inter-quant-penalty"), 1000.0);
SECONDARY_BEAM_DEMERIT = get_detail (details, ly_symbol2scm ("secondary-beam-demerit"), 10.0);
STEM_LENGTH_DEMERIT_FACTOR = get_detail (details, ly_symbol2scm ("stem-length-demerit-factor"), 5);
REGION_SIZE = get_detail (details, ly_symbol2scm ("region-size"), 2);
BEAM_EPS = get_detail (details, ly_symbol2scm ("beam-eps"), 1e-3);
-
- // possibly ridiculous, but too short stems just won't do
STEM_LENGTH_LIMIT_PENALTY = get_detail (details, ly_symbol2scm ("stem-length-limit-penalty"), 5000);
DAMPING_DIRECTION_PENALTY = get_detail (details, ly_symbol2scm ("damping-direction-penalty"), 800);
+ HINT_DIRECTION_PENALTY = get_detail (details, ly_symbol2scm ("hint-direction-penalty"), 20);
MUSICAL_DIRECTION_FACTOR = get_detail (details, ly_symbol2scm ("musical-direction-factor"), 400);
IDEAL_SLOPE_FACTOR = get_detail (details, ly_symbol2scm ("ideal-slope-factor"), 10);
ROUND_TO_ZERO_SLOPE = get_detail (details, ly_symbol2scm ("round-to-zero-slope"), 0.02);
Real yr;
Real demerits;
-#if DEBUG_QUANTING
+#if DEBUG_BEAM_SCORING
string score_card_;
#endif
};
/*
Calculations are relative to a unit-scaled staff, i.e. the quants are
divided by the current staff_space.
-
*/
Real ss = Staff_symbol_referencer::staff_space (me);
Real thickness = Beam::get_thickness (me) / ss;
going to REGION_SIZE == 2, yields another 0.6 second with
wtk1-fugue2.
-
(result indexes between 70 and 575) ? --hwn.
*/
for (int a = 2; a--;)
common[a] = common_refpoint_of_array (stems, me, Axis (a));
- Grob *fvs = first_visible_stem (me);
- Grob *lvs = last_visible_stem (me);
+ Grob *fvs = first_normal_stem (me);
+ Grob *lvs = last_normal_stem (me);
Real xl = fvs ? fvs->relative_coordinate (common[X_AXIS], X_AXIS) : 0.0;
Real xr = fvs ? lvs->relative_coordinate (common[X_AXIS], X_AXIS) : 0.0;
/*
- We store some info to quickly interpolate.
-
- Sometimes my head is screwed on backwards. The stemlength are
- AFFINE linear in YL and YR. If YL == YR == 0, then we might have
+ We store some info to quickly interpolate. The stemlength are
+ affine linear in YL and YR. If YL == YR == 0, then we might have
stem_y != 0.0, when we're cross staff.
*/
bool f = to_boolean (s->get_property ("french-beaming"))
&& s != lvs && s != fvs;
- base_lengths.push_back (calc_stem_y (me, s, common, xl, xr,
- Interval (0, 0), f) / ss);
- stem_xposns.push_back (s->relative_coordinate (common[X_AXIS], X_AXIS));
- }
+ if (Stem::is_normal_stem (s))
+ {
+ base_lengths.push_back (calc_stem_y (me, s, common, xl, xr, CENTER,
+ Interval (0, 0), f) / ss);
+ }
+ else
+ {
+ base_lengths.push_back (0);
+ }
- bool xstaff = false;
- if (lvs && fvs)
- {
- Grob *commony = fvs->common_refpoint (lvs, Y_AXIS);
- xstaff = Align_interface::has_interface (commony);
+ stem_xposns.push_back (s->relative_coordinate (common[X_AXIS], X_AXIS));
}
+ bool xstaff = Align_interface::has_interface (common[Y_AXIS]);
Direction ldir = Direction (stem_infos[0].dir_);
Direction rdir = Direction (stem_infos.back ().dir_);
xstaff, ¶meters);
qscores[i].demerits += d;
-#if DEBUG_QUANTING
+#if DEBUG_BEAM_SCORING
qscores[i].score_card_ += to_string ("S%.2f", d);
#endif
}
edge_beam_counts, ldir, rdir, ¶meters);
qscores[i].demerits += d;
-#if DEBUG_QUANTING
+#if DEBUG_BEAM_SCORING
qscores[i].score_card_ += to_string (" F %.2f", d);
#endif
}
qscores[i].yl, qscores[i].yr, ¶meters);
qscores[i].demerits += d;
-#if DEBUG_QUANTING
+#if DEBUG_BEAM_SCORING
qscores[i].score_card_ += to_string (" L %.2f", d);
#endif
}
int best_idx = best_quant_score_idx (qscores);
-#if DEBUG_QUANTING
+#if DEBUG_BEAM_SCORING
SCM inspect_quants = me->get_property ("inspect-quants");
- if (to_boolean (me->layout ()->lookup_variable (ly_symbol2scm ("debug-beam-quanting")))
+ if (to_boolean (me->layout ()->lookup_variable (ly_symbol2scm ("debug-beam-scoring")))
&& scm_is_pair (inspect_quants))
{
Drul_array<Real> ins = ly_scm2interval (inspect_quants);
}
}
if (mindist > 1e5)
- programming_error ("can't find quant");
+ programming_error ("cannot find quant");
}
#endif
qscores[best_idx].yr);
}
-#if DEBUG_QUANTING
+#if DEBUG_BEAM_SCORING
if (best_idx >= 0
- && to_boolean (me->layout ()->lookup_variable (ly_symbol2scm ("debug-beam-quanting"))))
+ && to_boolean (me->layout ()->lookup_variable (ly_symbol2scm ("debug-beam-scoring"))))
{
qscores[best_idx].score_card_ += to_string ("i%d", best_idx);
// debug quanting
me->set_property ("quant-score",
- scm_makfrom0str (qscores[best_idx].score_card_.c_str ()));
+ ly_string2scm (qscores[best_idx].score_card_));
}
#endif
for (vsize i = 0; i < stems.size (); i++)
{
Grob *s = stems[i];
- if (Stem::is_invisible (s))
+ if (!Stem::is_normal_stem (s))
continue;
Real x = stem_xs[i];
Direction d = DOWN;
do
score[d] /= max (count[d], 1);
- while (flip (&d) != DOWN)
- ;
+ while (flip (&d) != DOWN);
return score[LEFT] + score[RIGHT];
}
TODO: find a way to incorporate the complexity of the beam in this
penalty.
*/
- if (fabs (dy / dx) > parameters->ROUND_TO_ZERO_SLOPE
- && sign (dy_damp) != sign (dy))
- dem += parameters->DAMPING_DIRECTION_PENALTY;
-
+ if (sign (dy_damp) != sign (dy))
+ {
+ if (!dy)
+ {
+ if (fabs (dy_damp / dx) > parameters->ROUND_TO_ZERO_SLOPE)
+ dem += parameters->DAMPING_DIRECTION_PENALTY;
+ else
+ dem += parameters->HINT_DIRECTION_PENALTY;
+ }
+ else
+ dem += parameters->DAMPING_DIRECTION_PENALTY;
+ }
+
dem += parameters->MUSICAL_DIRECTION_FACTOR
* max (0.0, (fabs (dy) - fabs (dy_mus)));