debug-beam-quanting to #t.
* lily/beam-concave.cc (calc_concaveness): set concaveness to
10000 if this is a "hard" concave beam.
* lily/beam.cc (calc_least_squares_positions): change from
calc_least_squares_dy
(set_stem_lengths): this is now a chained callback.
* lily/context-property.cc (execute_general_pushpop_property):
bugfix override with procedure should have effect.
* scm/define-grob-properties.scm (all-internal-grob-properties):
remove position-callbacks.
* scm/define-grobs.scm (all-grob-descriptions): use
ly:make-callback-chain for positions property.
* scm/layout-beam.scm (check-quant-callbacks): return list of
chained callbacks.
* scm/lily.scm (type-p-name-alist): add callback-chain
* lily/lily-guile.cc (type_check_assignment): type check failure
is warning not message.
* lily/grob-property.cc (try_callback): walk callback chain if
appropriate.
* lily/chained-callback.cc: new file. new smob type.
* lily/lily-guile.cc (procedure_arity): new function.
+2005-10-31 Han-Wen Nienhuys <hanwen@xs4all.nl>
+
+ * input/regression/beam-quant-standard.ly: reindent, set
+ debug-beam-quanting to #t.
+
+ * lily/beam-concave.cc (calc_concaveness): set concaveness to
+ 10000 if this is a "hard" concave beam.
+
+ * lily/beam.cc (calc_least_squares_positions): change from
+ calc_least_squares_dy
+ (set_stem_lengths): this is now a chained callback.
+
+ * lily/context-property.cc (execute_general_pushpop_property):
+ bugfix override with procedure should have effect.
+
+ * scm/define-grob-properties.scm (all-internal-grob-properties):
+ remove position-callbacks.
+
+ * scm/define-grobs.scm (all-grob-descriptions): use
+ ly:make-callback-chain for positions property.
+
+ * scm/layout-beam.scm (check-quant-callbacks): return list of
+ chained callbacks.
+
+ * scm/lily.scm (type-p-name-alist): add callback-chain
+
+ * lily/lily-guile.cc (type_check_assignment): type check failure
+ is warning not message.
+
+ * lily/grob-property.cc (try_callback): walk callback chain if
+ appropriate.
+
+ * lily/chained-callback.cc: new file. new smob type.
+
+ * lily/lily-guile.cc (procedure_arity): new function.
+
2005-10-28 Han-Wen Nienhuys <hanwen@xs4all.nl>
* Documentation/topdocs/INSTALL.texi (Top): add perl flex bison.
\header {
- texidoc = "This file tests a few standard beam quants, taken from
+ texidoc = "This file tests a few standard beam quants, taken from
Ted Ross' book. If LilyPond finds another quant, the correct quant
is printed over the beam."
-
+
}
\version "2.7.13"
\layout {
- raggedright = ##t
-% #(define debug-beam-quanting #t)
+ raggedright = ##t
+ #(define debug-beam-quanting #t)
}
filler = \new Voice \relative {
- \hideNotes
- e4 e
+ \hideNotes
+ e4 e
}
-%
+ %
%%
%% Ross p108--112
primes = \relative {
- \time 3/4
- \assertBeamQuant #'(0 . 0) #'(0 . 0)
- c8[ c]
- \filler
- \assertBeamQuant #'(1 . -1) #'(1 . -1)
- d8[ d]
-
- \filler
-
- \assertBeamQuant #'(1 . 0) #'(1 . 0)
- e8[ e]
- \filler
-
-
- \assertBeamQuant #'(2 . -1) #'(2 . -1)
- f8[ f]
- \filler
-
-
- \assertBeamQuant #'(2 . 0) #'(2 . 0)
- g8[ g]
- \filler
-
-
- \assertBeamQuant #'(2 . 1) #'(2 . 1)
- a8[ a]
- \filler
-
+ \time 3/4
+ \assertBeamQuant #'(0 . 0) #'(0 . 0)
+ c8[ c]
+ \filler
+ \assertBeamQuant #'(1 . -1) #'(1 . -1)
+ d8[ d]
+
+ \filler
+
+ \assertBeamQuant #'(1 . 0) #'(1 . 0)
+ e8[ e]
+ \filler
+
+
+ \assertBeamQuant #'(2 . -1) #'(2 . -1)
+ f8[ f]
+ \filler
+
+
+ \assertBeamQuant #'(2 . 0) #'(2 . 0)
+ g8[ g]
+ \filler
+
+
+ \assertBeamQuant #'(2 . 1) #'(2 . 1)
+ a8[ a]
+ \filler
+
%{
- \once \override Beam #'inspect-quants = #'(2.2 . 2.2)
- \assertBeamQuant
- a8[ a]
- \filler
-
+ \once \override Beam #'inspect-quants = #'(2.2 . 2.2)
+ \assertBeamQuant
+ a8[ a]
+ \filler
+
%}
-
+
}
seconds = \relative {
-
- \assertBeamQuant #'(0 . 0) #'(0 . 1)
- a8[ b]
- \filler
-
+
+ \assertBeamQuant #'(0 . 0) #'(0 . 1)
+ a8[ b]
+ \filler
+
- \assertBeamQuant #'(0 . 0) #'(0 . 1)
- b8[ c]
- \filler
-
+ \assertBeamQuant #'(0 . 0) #'(0 . 1)
+ b8[ c]
+ \filler
+
- \assertBeamQuant #'(0 . 0) #'(0 . 1)
- c8[ d]
- \filler
-
- \assertBeamQuant #'(1 . -1) #'(1 . 0)
- d8[ e]
- \filler
-
-
- \assertBeamQuant #'(1 . 0) #'(1 . 1)
- e8[ f]
- \filler
-
-
- \assertBeamQuant #'(2 . -1) #'(2 . 0)
- f8[ g]
- \filler
-
-
- \assertBeamQuant #'(2 . 0) #'(2 . 1)
- g8[ a]
- \filler
+ \assertBeamQuant #'(0 . 0) #'(0 . 1)
+ c8[ d]
+ \filler
+
+ \assertBeamQuant #'(1 . -1) #'(1 . 0)
+ d8[ e]
+ \filler
+
+
+ \assertBeamQuant #'(1 . 0) #'(1 . 1)
+ e8[ f]
+ \filler
+
+
+ \assertBeamQuant #'(2 . -1) #'(2 . 0)
+ f8[ g]
+ \filler
+
+
+ \assertBeamQuant #'(2 . 0) #'(2 . 1)
+ g8[ a]
+ \filler
- \assertBeamQuant #'(3 . -1) #'(3 . 0)
- a8[ b]
- \filler
+ \assertBeamQuant #'(3 . -1) #'(3 . 0)
+ a8[ b]
+ \filler
}
filler = \new Voice \relative {
- \hideNotes
- e4 e4.
+ \hideNotes
+ e4 e4.
}
-% Ross, p122
+ % Ross, p122
primeSixteenths = \relative {
- \stemUp
- \assertBeamQuant #'(0 . -1) #'(0 . -1)
- g16[ g]
- \filler
- \assertBeamQuant #'(0 . -1) #'(0 . -1)
- a16[ a]
- \filler
- \assertBeamQuant #'(0 . -1) #'(0 . -1)
- b16[ b]
- \filler
- \assertBeamQuant #'(0 . 0) #'(0 . 0)
- c16[ c]
- \filler
- \assertBeamQuant #'(1 . -1) #'(1 . -1)
- d16[ d]
- \filler
- \assertBeamQuant #'(1 . 0) #'(1 . 0)
- e16[ e]
- \filler
- \assertBeamQuant #'(2 . -1) #'(2 . -1)
- f16[ f]
- \filler
- \assertBeamQuant #'(2 . 0) #'(2 . 0)
- g16[ g]
- \filler
- \assertBeamQuant #'(3 . -1) #'(3 . -1)
- a16[ a]
- \filler
- \assertBeamQuant #'(3 . 0) #'(3 . 0)
- b16[ b]
- \filler
+ \stemUp
+ \assertBeamQuant #'(0 . -1) #'(0 . -1)
+ g16[ g]
+ \filler
+ \assertBeamQuant #'(0 . -1) #'(0 . -1)
+ a16[ a]
+ \filler
+ \assertBeamQuant #'(0 . -1) #'(0 . -1)
+ b16[ b]
+ \filler
+ \assertBeamQuant #'(0 . 0) #'(0 . 0)
+ c16[ c]
+ \filler
+ \assertBeamQuant #'(1 . -1) #'(1 . -1)
+ d16[ d]
+ \filler
+ \assertBeamQuant #'(1 . 0) #'(1 . 0)
+ e16[ e]
+ \filler
+ \assertBeamQuant #'(2 . -1) #'(2 . -1)
+ f16[ f]
+ \filler
+ \assertBeamQuant #'(2 . 0) #'(2 . 0)
+ g16[ g]
+ \filler
+ \assertBeamQuant #'(3 . -1) #'(3 . -1)
+ a16[ a]
+ \filler
+ \assertBeamQuant #'(3 . 0) #'(3 . 0)
+ b16[ b]
+ \filler
}
\new Voice { \primes \seconds \primeSixteenths }
if (is_concave_single_notes (far_positions, beam_dir))
{
- (void) me->get_property ("least-squares-dy"); // ugh. dependency handling.
-
- Drul_array<Real> pos = ly_scm2interval (me->get_property ("positions"));
- Real r = linear_combination (pos, 0.0);
-
- r /= Staff_symbol_referencer::staff_space (me);
- me->set_property ("positions", ly_interval2scm (Drul_array<Real> (r, r)));
- me->set_property ("least-squares-dy", scm_from_double (0));
+ concaveness = 10000;
}
else
{
return scm_from_double (concaveness);
}
+
+
+
return best_idx;
}
-MAKE_SCHEME_CALLBACK (Beam, quanting, 1);
+MAKE_SCHEME_CALLBACK (Beam, quanting, 2);
SCM
-Beam::quanting (SCM smob)
+Beam::quanting (SCM smob, SCM posns)
{
Grob *me = unsmob_grob (smob);
Beam_quant_parameters parameters;
parameters.fill (me);
- SCM s = me->get_property ("positions");
- Real yl = scm_to_double (scm_car (s));
- Real yr = scm_to_double (scm_cdr (s));
+ Real yl = scm_to_double (scm_car (posns));
+ Real yr = scm_to_double (scm_cdr (posns));
/*
Calculations are relative to a unit-scaled staff, i.e. the quants are
programming_error ("can't find quant");
}
#endif
+
+ Interval final_positions;
if (best_idx < 0)
{
warning (_ ("no feasible beam position"));
- me->set_property ("positions", ly_interval2scm (Interval (0, 0)));
+ final_positions = Interval (0, 0);
}
else
- me->set_property ("positions",
- ly_interval2scm (Drul_array<Real> (qscores[best_idx].yl,
- qscores[best_idx].yr)));
+ {
+ final_positions = Drul_array<Real> (qscores[best_idx].yl,
+ qscores[best_idx].yr);
+ }
+
#if DEBUG_QUANTING
if (best_idx >= 0
&& to_boolean (me->get_layout ()->lookup_variable (ly_symbol2scm ("debug-beam-quanting"))))
}
#endif
- return SCM_UNSPECIFIED;
+ return ly_interval2scm (final_positions);
}
Real
Direction stem_dir = stems.size () ? to_dir (stems[0]->get_property ("direction")) : UP;
- Stencil tm = *unsmob_stencil (Text_interface::interpret_markup
+ Stencil score = *unsmob_stencil (Text_interface::interpret_markup
(me->get_layout ()->self_scm (), properties, quant_score));
- the_beam.add_at_edge (Y_AXIS, stem_dir, tm, 1.0, 0);
+
+ if (!score.is_empty ())
+ the_beam.add_at_edge (Y_AXIS, stem_dir, score, 1.0, 0);
}
#endif
for (SCM i = callbacks; scm_is_pair (i); i = scm_cdr (i))
scm_call_1 (scm_car (i), me->self_scm ());
- /*
- TODO: move this in separate calc function.
- */
- set_stem_lengths (me);
return SCM_UNSPECIFIED;
}
+
void
set_minimum_dy (Grob *me, Real *dy)
{
/*
Compute a first approximation to the beam slope.
*/
-MAKE_SCHEME_CALLBACK (Beam, calc_least_squares_dy, 1);
+MAKE_SCHEME_CALLBACK (Beam, calc_least_squares_positions, 2);
SCM
-Beam::calc_least_squares_dy (SCM smob)
+Beam::calc_least_squares_positions (SCM smob, SCM posns)
{
+ (void) posns;
+
Grob *me = unsmob_grob (smob);
int count = visible_stem_count (me);
Interval pos (0, 0);
- if (count < 1)
- {
- me->set_property ("positions", ly_interval2scm (pos));
- return scm_from_double (0.0);
- }
-
Array<Real> x_posns;
extract_grob_set (me, "stems", stems);
Grob *commonx = common_refpoint_of_array (stems, me, X_AXIS);
*/
scale_drul (&pos, 1 / Staff_symbol_referencer::staff_space (me));
- me->set_property ("positions", ly_interval2scm (pos));
-
- return scm_from_double (ldy);
+ me->set_property ("least-squares-dy", scm_from_double (ldy));
+ return ly_interval2scm (pos);
}
/*
TODO: we should use the concaveness to control the amount of damping
applied.
*/
-MAKE_SCHEME_CALLBACK (Beam, shift_region_to_valid, 1);
+MAKE_SCHEME_CALLBACK (Beam, shift_region_to_valid, 2);
SCM
-Beam::shift_region_to_valid (SCM grob)
+Beam::shift_region_to_valid (SCM grob, SCM posns)
{
Grob *me = unsmob_grob (grob);
/*
Grob *fvs = first_visible_stem (me);
if (!fvs)
- return SCM_UNSPECIFIED;
+ return posns;
Real x0 = fvs->relative_coordinate (commonx, X_AXIS);
for (int i = 0; i < stems.size (); i++)
Grob *lvs = last_visible_stem (me);
if (!lvs)
- return SCM_UNSPECIFIED;
+ return posns;
Real dx = lvs->relative_coordinate (commonx, X_AXIS) - x0;
- Drul_array<Real> pos = ly_scm2interval (me->get_property ("positions"));
+ Drul_array<Real> pos = ly_scm2interval (posns);
+
scale_drul (&pos, Staff_symbol_referencer::staff_space (me));
pos = Drul_array<Real> (y, (y + dy));
scale_drul (&pos, 1 / Staff_symbol_referencer::staff_space (me));
- me->set_property ("positions", ly_interval2scm (pos));
- return SCM_UNSPECIFIED;
+ return ly_interval2scm (pos);
}
/* This neat trick is by Werner Lemberg,
damped = tanh (slope)
corresponds with some tables in [Wanske] CHECKME */
-MAKE_SCHEME_CALLBACK (Beam, slope_damping, 1);
+MAKE_SCHEME_CALLBACK (Beam, slope_damping, 2);
SCM
-Beam::slope_damping (SCM smob)
+Beam::slope_damping (SCM smob, SCM posns)
{
Grob *me = unsmob_grob (smob);
+ Drul_array<Real> pos = ly_scm2interval (posns);
if (visible_stem_count (me) <= 1)
return SCM_UNSPECIFIED;
- /* trigger callback. */
- (void) me->get_property ("least-squares-dy");
SCM s = me->get_property ("damping");
Real damping = scm_to_double (s);
-
+ Real concaveness = robust_scm2double (me->get_property ("concaveness"), 0.0);
+ if (concaveness >= 10000)
+ {
+ pos[LEFT] = pos[RIGHT];
+ me->set_property ("least-squares-dy", scm_from_double (0));
+ damping = 0;
+ }
+
if (damping)
{
- Real concaveness = robust_scm2double (me->get_property ("concaveness"), 0.0);
-
- Drul_array<Real> pos = ly_scm2interval (me->get_property ("positions"));
scale_drul (&pos, Staff_symbol_referencer::staff_space (me));
Real dy = pos[RIGHT] - pos[LEFT];
pos[RIGHT] -= (dy - damped_dy) / 2;
scale_drul (&pos, 1 / Staff_symbol_referencer::staff_space (me));
-
- me->set_property ("positions", ly_interval2scm (pos));
}
- return SCM_UNSPECIFIED;
+
+ return ly_interval2scm (pos);
}
/*
Hmm. At this time, beam position and slope are determined. Maybe,
stem directions and length should set to relative to the chord's
position of the beam. */
-void
-Beam::set_stem_lengths (Grob *me)
+MAKE_SCHEME_CALLBACK(Beam, set_stem_lengths, 2);
+SCM
+Beam::set_stem_lengths (SCM smob, SCM posns)
{
+ Grob *me = unsmob_grob (smob);
+
extract_grob_set (me, "stems", stems);
if (!stems.size ())
- return;
+ return posns;
Grob *common[2];
for (int a = 2; a--;)
common[a] = common_refpoint_of_array (stems, me, Axis (a));
- Drul_array<Real> pos = ly_scm2realdrul (me->get_property ("positions"));
+ Drul_array<Real> pos = ly_scm2realdrul (posns);
Real staff_space = Staff_symbol_referencer::staff_space (me);
scale_drul (&pos, staff_space);
Stem::set_stemend (s, 2 * stem_y / staff_space);
}
+
+ return posns;
}
void
--- /dev/null
+/*
+ chained-callback.cc -- chained callbacks.
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 2005 Han-Wen Nienhuys <hanwen@xs4all.nl>
+
+*/
+
+#include "lily-guile.hh"
+
+static scm_t_bits chain_tag;
+
+bool
+is_callback_chain (SCM s)
+{
+ return (SCM_NIMP (s) && SCM_CELL_TYPE (s) == chain_tag);
+}
+
+SCM
+callback_chain_extract_procedures (SCM chain_smob)
+{
+ assert (is_callback_chain (chain_smob));
+ return (SCM) SCM_CELL_WORD_1(chain_smob);
+}
+
+LY_DEFINE(ly_callback_chain_p, "ly:callback-chain?",
+ 1,0,0, (SCM chain),
+ "Type predicate.")
+{
+ return scm_from_bool (is_callback_chain (chain));
+}
+
+LY_DEFINE(ly_make_callback_chain, "ly:make-callback-chain",
+ 0, 0, 1, (SCM procedures),
+ "Make a grob callback chain. @var{procedures} should be a "
+ "list of procedures taking 2 arguments.")
+{
+ SCM z;
+
+ for (SCM s = procedures;
+ scm_is_pair (s); s = scm_cdr (s))
+ {
+ SCM proc = scm_car (s);
+ if (!ly_is_procedure (proc))
+ {
+ scm_misc_error ("Must be a procedure: ~a",
+ "ly:make-callback-chain",
+ proc);
+ }
+
+ if (procedure_arity (proc) != 2)
+ {
+ scm_misc_error ("Procedure should take 2 arguments: ~a",
+ "ly:make-callback-chain",
+ proc);
+ }
+ }
+
+ SCM_NEWSMOB(z, chain_tag, procedures);
+ return z;
+}
+
+int
+print_callback_chain (SCM s, SCM port, scm_print_state *)
+{
+ scm_puts ("#<callback-chain ", port);
+ scm_display (scm_cdr (s), port);
+ scm_puts (" >", port);
+ return 1;
+}
+
+
+void init_chained_callback ()
+{
+ chain_tag = scm_make_smob_type ("callback-chain", 0);
+ scm_set_smob_mark (chain_tag, scm_markcdr);
+ scm_set_smob_print (chain_tag, print_callback_chain);
+};
+
+
+
+ADD_SCM_INIT_FUNC(chain, init_chained_callback);
bool ok = true;
if (!scm_is_pair (scm_cdr (grob_property_path)))
{
- ok = !ly_is_procedure (new_value)
- && type_check_assignment (symbol, new_value,
- ly_symbol2scm ("backend-type?"));
+ if (!ly_is_procedure (new_value)
+ && !is_callback_chain (new_value))
+ ok = type_check_assignment (symbol, new_value,
+ ly_symbol2scm ("backend-type?"));
/*
tack onto alist. We can use set_car, since
Grob::internal_get_property (SCM sym) const
{
SCM val = get_property_data (sym);
- if (ly_is_procedure (val))
+ if (ly_is_procedure (val) || is_callback_chain (val))
{
val = ((Grob*)this)->try_callback (sym, val);
}
if (debug_property_callbacks)
grob_property_callback_stack = scm_acons (sym, proc, grob_property_callback_stack);
#endif
- SCM value = scm_call_1 (proc, self_scm ());
+
+ SCM value = SCM_EOL;
+ if (ly_is_procedure (proc))
+ value = scm_call_1 (proc, self_scm ());
+ else if (is_callback_chain (proc))
+ {
+ for (SCM s = callback_chain_extract_procedures (proc);
+ scm_is_pair (s); s = scm_cdr (s))
+ {
+ value = scm_call_2 (scm_car (s), self_scm (), value);
+ }
+ }
+ else
+ assert (false);
+
#ifndef NDEBUG
if (debug_property_callbacks)
grob_property_callback_stack = scm_cdr (grob_property_callback_stack);
DECLARE_SCHEME_CALLBACK (print, (SCM));
DECLARE_SCHEME_CALLBACK (calc_direction, (SCM));
DECLARE_SCHEME_CALLBACK (calc_positions, (SCM));
- DECLARE_SCHEME_CALLBACK (calc_least_squares_dy, (SCM));
+ DECLARE_SCHEME_CALLBACK (calc_least_squares_positions, (SCM, SCM));
DECLARE_SCHEME_CALLBACK (calc_concaveness, (SCM));
/* position callbacks */
- DECLARE_SCHEME_CALLBACK (slope_damping, (SCM));
- DECLARE_SCHEME_CALLBACK (shift_region_to_valid, (SCM));
- DECLARE_SCHEME_CALLBACK (quanting, (SCM));
- static Real score_slopes_dy (Real, Real, Real, Real, Real, bool, Beam_quant_parameters const *);
+ DECLARE_SCHEME_CALLBACK (shift_region_to_valid, (SCM, SCM));
+ DECLARE_SCHEME_CALLBACK (slope_damping, (SCM, SCM));
+ DECLARE_SCHEME_CALLBACK (quanting, (SCM, SCM));
+ DECLARE_SCHEME_CALLBACK (set_stem_lengths, (SCM,SCM));
+
+static Real score_slopes_dy (Real, Real, Real, Real, Real, bool, Beam_quant_parameters const *);
static Real score_stem_lengths (Link_array<Grob> const &stems,
Array<Stem_info> const &stem_infos,
static Real calc_stem_y (Grob *, Grob *s, Grob **c,
Real, Real,
Drul_array<Real> pos, bool french);
- static void set_stem_lengths (Grob *);
static int forced_stem_count (Grob *);
};
Interval robust_relative_extent (Grob *, Grob *, Axis);
+bool is_callback_chain (SCM s);
+SCM callback_chain_extract_procedures (SCM chain_smob);
+
#endif /* GROB_HH */
SCM ly_alist_vals (SCM alist);
SCM ly_hash2alist (SCM tab);
+int procedure_arity (SCM);
+
/* inserts at front, removing dublicates */
inline SCM ly_assoc_front_x (SCM alist, SCM key, SCM val)
{
SCM typefunc = ly_lily_module_constant ("type-name");
SCM type_name = scm_call_1 (typefunc, type);
- message (_f ("type check for `%s' failed; value `%s' must be of type `%s'",
+ warning (_f ("type check for `%s' failed; value `%s' must be of type `%s'",
ly_symbol2string (sym).to_str0 (),
print_scm_val (val),
ly_scm2string (type_name).to_str0 ()));
return scm_call_1 (func, tab);
}
+int
+procedure_arity (SCM proc)
+{
+ assert (ly_is_procedure (proc));
+ SCM arity = scm_procedure_property (proc,
+ ly_symbol2scm ("arity"));
+
+ SCM fixed = scm_car (arity);
+ return scm_to_int (fixed);
+}
% for regression testing purposes.
assertBeamQuant =
#(def-music-function (parser location l r) (pair? pair?)
- (make-grob-property-override 'Beam 'position-callbacks
- (check-quant-callbacks l r)))
+ (make-grob-property-override 'Beam 'positions
+ (apply ly:make-callback-chain (check-quant-callbacks l r))))
% for regression testing purposes.
assertBeamSlope =
#(def-music-function (parser location comp) (procedure?)
- (make-grob-property-override 'Beam 'position-callbacks
- (check-slope-callbacks comp)))
+ (make-grob-property-override 'Beam 'positions
+ (apply ly:make-callback-chain (check-slope-callbacks comp))))
(stem-info ,pair? "caching of stem parameters")
(note-columns ,pair? "list of NoteColumn grobs.")
- (position-callbacks ,list? "list of
-functions set spanner positions.")
-
;;; add-join would be enough if in Mensural_ligature::brew_ligature_primitive
;;; the next note could be seen
(join-right-amount ,number? "")
;; todo: clean this up a bit: the list is getting
;; rather long.
(gap . 0.8)
-
- (position-callbacks . (,Beam::slope_damping
- ,Beam::shift_region_to_valid
- ,Beam::quanting))
- (least-squares-dy . ,Beam::calc_least_squares_dy)
+
+ (positions . ,(ly:make-callback-chain
+ Beam::calc_least_squares_positions
+ Beam::slope_damping
+ Beam::shift_region_to_valid
+ Beam::quanting
+ Beam::set_stem_lengths
+ ))
(concaveness . ,Beam::calc_concaveness)
- (positions . ,Beam::calc_positions)
(direction . ,Beam::calc_direction)
(stencil . ,Beam::print)
-
;; TODO: should be in SLT.
(thickness . 0.48) ; in staff-space
;;;; (c) 2000--2005 Jan Nieuwenhuizen <janneke@gnu.org>
;;;;
-(define ((check-beam-quant posl posr) beam)
+(define ((check-beam-quant posl posr) beam posns)
"Check whether BEAM has POSL and POSR quants. POSL are (POSITION
. QUANT) pairs, where QUANT is -1 (hang), 0 (center), 1 (sit) or -2/ 2 (inter)
"
- (let* ((posns (ly:grob-property beam 'positions))
- (thick (ly:grob-property beam 'thickness))
+ (let* ((thick (ly:grob-property beam 'thickness))
(layout (ly:grob-layout beam))
(lthick (ly:output-def-lookup layout 'linethickness))
(staff-thick lthick) ; fixme.
want-l want-r posns)
(set! (ly:grob-property beam 'quant-score)
(format "(~S,~S)" want-l want-r)))
- (set! (ly:grob-property beam 'quant-score) ""))))
+ (set! (ly:grob-property beam 'quant-score) ""))
-(define ((check-beam-slope-sign comparison) beam)
+ posns
+ ))
+
+(define ((check-beam-slope-sign comparison) beam posns)
"Check whether the slope of BEAM is correct wrt. COMPARISON."
- (let* ((posns (ly:grob-property beam 'positions))
- (slope-sign (- (cdr posns) (car posns)))
+ (let* ((slope-sign (- (cdr posns) (car posns)))
(correct (comparison slope-sign 0)))
(if (not correct)
(procedure-name comparison) "0" slope-sign)
(set! (ly:grob-property beam 'quant-score)
(format "~S 0" (procedure-name comparison))))
- (set! (ly:grob-property beam 'quant-score) ""))))
+
+ (set! (ly:grob-property beam 'quant-score) ""))
+ posns))
+
(define-public (check-quant-callbacks l r)
- (list Beam::least_squares
- Beam::check_concave
+ (list Beam::calc_least_squares_positions
Beam::slope_damping
Beam::shift_region_to_valid
Beam::quanting
- (check-beam-quant l r)))
+ Beam::set_stem_lengths
+ (check-beam-quant l r)
+ ))
+
(define-public (check-slope-callbacks comparison)
- (list Beam::least_squares
- Beam::check_concave
+ (list Beam::calc_least_squares_positions
Beam::slope_damping
Beam::shift_region_to_valid
Beam::quanting
- (check-beam-slope-sign comparison)))
-
+ Beam::set_stem_lengths
+ (check-beam-slope-sign comparison)
+ ))
(,ly:pitch? . "pitch")
(,ly:translator? . "translator")
(,ly:font-metric? . "font metric")
+ (,ly:callback-chain? . "callback chain")
(,markup-list? . "list of markups")
(,markup? . "markup")
(,ly:music-list? . "list of music")