]> git.donarmstrong.com Git - lilypond.git/commitdiff
* input/regression/beam-quant-standard.ly: reindent, set
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Mon, 31 Oct 2005 15:38:55 +0000 (15:38 +0000)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Mon, 31 Oct 2005 15:38:55 +0000 (15:38 +0000)
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.

17 files changed:
ChangeLog
input/regression/beam-quant-standard.ly
lily/beam-concave.cc
lily/beam-quanting.cc
lily/beam.cc
lily/chained-callback.cc [new file with mode: 0644]
lily/context-property.cc
lily/grob-property.cc
lily/include/beam.hh
lily/include/grob.hh
lily/include/lily-guile.hh
lily/lily-guile.cc
ly/spanners-init.ly
scm/define-grob-properties.scm
scm/define-grobs.scm
scm/layout-beam.scm
scm/lily.scm

index ad9c7d89e2b4f74f254a868a5ca8c04f392e52a8..a21300fa51ee55bc05012feb9274219eb7124aa5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,39 @@
+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.
index 3a2bf9a56dea492b4c30a6f4e660e106085a01ed..e96236c2ac2dfe0829c9faaef0b17ccda6929433 100644 (file)
 \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 }
index 7c38e96aa1b58bfd34acd13c783bcfecf043a2c9..4eb2bab8fd3b56f3286fedee71f404253e4536d5 100644 (file)
@@ -130,14 +130,7 @@ Beam::calc_concaveness (SCM smob)
 
   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
     {
@@ -147,3 +140,6 @@ Beam::calc_concaveness (SCM smob)
 
   return scm_from_double (concaveness);
 }
+
+
+
index d0a09e9530cf8027f109c919372a2b8bdb325d51..75e00fb93c01330adca02a4ef5ad66da713a5254 100644 (file)
@@ -93,18 +93,17 @@ best_quant_score_idx (Array<Quant_score> const &qscores)
   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
@@ -300,15 +299,19 @@ Beam::quanting (SCM smob)
        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"))))
@@ -321,7 +324,7 @@ Beam::quanting (SCM smob)
     }
 #endif
 
-  return SCM_UNSPECIFIED;
+  return ly_interval2scm (final_positions);
 }
 
 Real
index acc48074923ed94de0fa3b559d2cef6d0545347b..9cd5793264647d2b3387ec178fdd0e419419e699 100644 (file)
@@ -505,9 +505,11 @@ Beam::print (SCM grob)
 
       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
 
@@ -738,14 +740,11 @@ Beam::calc_positions (SCM smob)
   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)
 {
@@ -771,21 +770,17 @@ 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);
@@ -873,9 +868,8 @@ Beam::calc_least_squares_dy (SCM smob)
   */
   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);
 }
 
 /*
@@ -885,9 +879,9 @@ Beam::calc_least_squares_dy (SCM smob)
   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);
   /*
@@ -901,7 +895,7 @@ Beam::shift_region_to_valid (SCM 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++)
@@ -914,11 +908,12 @@ Beam::shift_region_to_valid (SCM grob)
 
   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));
 
@@ -975,33 +970,35 @@ Beam::shift_region_to_valid (SCM grob)
   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];
@@ -1026,10 +1023,9 @@ Beam::slope_damping (SCM smob)
       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);
 }
 
 /*
@@ -1095,18 +1091,21 @@ Beam::calc_stem_y (Grob *me, Grob *s, Grob ** common,
   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);
 
@@ -1146,6 +1145,8 @@ Beam::set_stem_lengths (Grob *me)
 
       Stem::set_stemend (s, 2 * stem_y / staff_space);
     }
+
+  return posns;
 }
 
 void
diff --git a/lily/chained-callback.cc b/lily/chained-callback.cc
new file mode 100644 (file)
index 0000000..646c7a4
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+  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);
index 2fc887300d15cb49acee7e9ebc291e6946e519e4..45dccdc05c6a5b8b609537cb5e3b2e814b5f3095 100644 (file)
@@ -136,9 +136,10 @@ execute_general_pushpop_property (Context *context,
       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
index 3c8a07db5cf5d79e0cc3300fe4e74813303e18cb..e1d0446d7f433d5f591615b9b3c969ddf0201b78 100644 (file)
@@ -100,7 +100,7 @@ SCM
 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);
     }
@@ -129,7 +129,21 @@ Grob::try_callback (SCM sym, SCM proc)
   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);
index d688cacd369512b98496ba2ced4a1bfb00c62586..83e2c591f7a9e7d52b26d7be475ff8d98fc3ac62 100644 (file)
@@ -59,14 +59,16 @@ public:
   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,
@@ -89,7 +91,6 @@ private:
   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 *);
 };
 
index 6c08afeeec96e0399a337732f68798fd4570e651..211bf08d394b2bb2550925a25dd9a029dfec5444 100644 (file)
@@ -139,4 +139,7 @@ SCM ly_grobs2scm (Link_array<Grob> a);
 
 Interval robust_relative_extent (Grob *, Grob *, Axis);
 
+bool is_callback_chain (SCM s);
+SCM callback_chain_extract_procedures (SCM chain_smob);
+
 #endif /* GROB_HH */
index 920f9968b90344b92f2f7fa74750f2836d0afd4d..93469b18a921ab375fa1278c54f2d33e0a719f7a 100644 (file)
@@ -77,6 +77,8 @@ SCM alist_to_hashq (SCM);
 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)
 {
index 681d1762c02ca4a1d486b7a32d95c7f3265fd5b6..bbc3fa5b140cb3c5c78c235009fd30ae9bfba48e 100644 (file)
@@ -465,7 +465,7 @@ type_check_assignment (SCM sym, SCM val, SCM type_symbol)
          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 ()));
@@ -706,3 +706,13 @@ ly_hash2alist (SCM tab)
   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);
+}
index 2a0ee17aefb931315ee9bddb2a2dd2fa3bf06fe2..56d0272bd512bf0cff213095119dd8a1a783fee6 100644 (file)
@@ -96,13 +96,13 @@ sostenutoUp = #(make-span-event 'SostenutoEvent STOP)
 % 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))))
 
 
index aa88de25b105eb65ff8c51d44266db8747386979..2eb918263c0ac9e16b630e3e8e6a7db032a0709f 100644 (file)
@@ -549,9 +549,6 @@ debugging")
      (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? "")
index 189d9bdf9c2b038bbf4ee78c3f67d39ace68b795..314c1e492134dbbf72596d3f659ab0e675cfc2ff 100644 (file)
        ;; 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
index 29a74052232d2ddbd7200ae4d66a4de4192ef00c..051cc5f2af25c60fb40445664ff3971e77de3332 100644 (file)
@@ -6,13 +6,12 @@
 ;;;; (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)      
+       ))
index 197936b3e4945c4179bc3f5753453ab47d47e13b..5b6912420a4bf8c9931a60b6e66ee515077b3d8c 100644 (file)
@@ -281,6 +281,7 @@ The syntax is the same as `define*-public'."
        (,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")