-/* Prevent interference from stafflines. */
-Interval
-Beam::quantise_interval (Grob *me, Interval pos, Direction quant_dir)
-{
- int multiplicity = get_multiplicity (me);
-
- Real staff_space = Staff_symbol_referencer::staff_space (me);
- Real thick = me->paper_l ()->get_var ("stafflinethickness");
- Direction dir = Directional_element_interface::get (me);
- Real dy = pos.delta ();
-
- Drul_array<Interval> bounds;
- Direction d = LEFT;
- do
- {
- SCM proc = d == LEFT
- ? me->get_grob_property ("left-position-quant-function")
- : me->get_grob_property ("right-position-quant-function");
-
- SCM quants = scm_apply (proc,
- me->self_scm (),
- scm_list_n (gh_int2scm (multiplicity),
- gh_double2scm (dir),
- gh_double2scm (dy),
- gh_double2scm (thick / staff_space),
- /* HUH? */
- SCM_EOL,
- SCM_UNDEFINED));
-
- Array<Real> a;
- for (SCM i = quants; gh_pair_p (i); i = ly_cdr (i))
- a.push (gh_scm2double (ly_car (i)));
-
- if (a.size () <= 1)
- return pos;
-
- bounds[d] = quantise_iv (a, pos[d]*dir/staff_space) * staff_space;
- }
- while (flip (&d) != LEFT);
-
- Real ady = abs (dy);
-
- // quant direction hints disabled for now
- int q = 0;//(int)quant_dir;
-
- /* TODO: make smart choice, find best left/right quants pair.
-
- Slope should never be steeper than least_squares (before damping)
- (save that value?)
- Slope should never be reduced to zero.
- */
- SCM s = me->get_grob_property ("least-squares-dy");
- Real lsdy = gh_number_p (s) ? gh_scm2double (s) : 0;
-
- // Interval qpos (0, 1000 * sign (dy));
- Interval qpos;
- Real epsilon = staff_space / 10;
- Direction ldir = LEFT;
- do
- {
- Direction rdir = LEFT;
- do
- {
- Interval i (bounds[LEFT][ldir]*dir, bounds[RIGHT][rdir]*dir);
- if ((!lsdy
- || (abs (i.delta ()) <= abs (lsdy) + epsilon
- && sign (i.delta ()) == sign (lsdy)))
- && (abs (abs (i.delta ()) - ady)
- <= abs (abs (qpos.delta ()) - ady))
- && sign (i.delta ()) == sign (pos.delta ())
- && (!q
- || (i[LEFT]*q >= pos[LEFT]*q && i[RIGHT]*q
- >= pos[RIGHT]*q)))
- qpos = i;
- }
- while (flip (&rdir) != LEFT);
- }
- while (flip (&ldir) != LEFT);
-
- return qpos;
-}
-
-
-/* Quantise vertical position (left and right) of beam.
- Generalisation of [Ross]. */
-MAKE_SCHEME_CALLBACK (Beam, quantise_position, 1);
-SCM
-Beam::quantise_position (SCM smob)
-{
- Grob *me = unsmob_grob (smob);
-
- Interval pos = ly_scm2interval (me->get_grob_property ("positions"));
- Real y_shift = check_stem_length_f (me, pos);
- pos += y_shift;
- Real staff_space = Staff_symbol_referencer::staff_space (me);
-
- Direction dir = Directional_element_interface::get (me);
- for (int i = 0; i < 10; i++)
- {
- Interval qpos = quantise_interval (me, pos, CENTER);
- // how to check for uninitised interval, (inf, -inf)?
- if (qpos[LEFT] < 1000)
- {
- y_shift = check_stem_length_f (me, qpos);
- if (y_shift * dir < staff_space / 2)
- {
- pos = qpos;
- break;
- }
- }
- pos += ((i + 1) * ((i % 2) * -2 + 1)) * dir * staff_space / 4;
- }
-
-
- me->set_grob_property ("positions", ly_interval2scm (pos));
- set_stem_lengths (me);
-
-#if 0
- pos = ly_scm2interval (me->get_grob_property ("positions"));
-
- y_shift = check_stem_length_f (me, pos);
-
- Real half_space = Staff_symbol_referencer::staff_space (me) / 2;
- /* HMMM */
- if (y_shift > half_space / 4)
- {
- pos += y_shift;
- int quant_dir = 0;
- /* for significantly lengthened or shortened stems,
- request quanting the other way.
- HMMM */
- if (abs (y_shift) > half_space / 2)
- quant_dir = sign (y_shift) * Directional_element_interface::get (me);
- pos = quantise_interval (me, pos, (Direction)quant_dir);
- }
-
- me->set_grob_property ("positions", ly_interval2scm (pos));
-#endif
-
- return SCM_UNSPECIFIED;
-}
-