]> git.donarmstrong.com Git - lilypond.git/commitdiff
Merge branch 'master' of git+ssh://jneem@git.sv.gnu.org/srv/git/lilypond
authorJoe Neeman <joeneeman@gmail.com>
Wed, 31 Jan 2007 07:38:46 +0000 (09:38 +0200)
committerJoe Neeman <joeneeman@gmail.com>
Wed, 31 Jan 2007 07:38:46 +0000 (09:38 +0200)
Conflicts:

lily/text-spanner-engraver.cc

13 files changed:
1  2 
lily/align-interface.cc
lily/bar-number-engraver.cc
lily/beam.cc
lily/grob.cc
lily/paper-score.cc
lily/prob-scheme.cc
lily/slur.cc
lily/stem.cc
lily/text-spanner-engraver.cc
lily/trill-spanner-engraver.cc
ly/engraver-init.ly
scm/define-grob-properties.scm
scm/define-grobs.scm

diff --combined lily/align-interface.cc
index 69fb5e921c3a56f4efd3867493d75fb2cf0b8840,09887a7c9fd893581d403f539f87fabc495e3570..68077c817622aa69c77bcda35d434bb808a5a12d
@@@ -30,16 -30,23 +30,19 @@@ SC
  Align_interface::calc_positioning_done (SCM smob)
  {
    Grob *me = unsmob_grob (smob);
+   me->set_property ("positioning-done", SCM_BOOL_T);
    SCM axis = scm_car (me->get_property ("axes"));
    Axis ax = Axis (scm_to_int (axis));
  
 -  SCM force = me->get_property ("forced-distance");
 -  if (scm_is_number (force))
 -    Align_interface::align_to_fixed_distance (me, ax);
 -  else
 -    Align_interface::align_elements_to_extents (me, ax);
 +  Align_interface::align_elements_to_extents (me, ax);
  
    return SCM_BOOL_T;
  }
  
  /*
 -  merge with align-to-extents?
 +  TODO: This belongs to the old two-pass spacing. Delete me.
  */
  MAKE_SCHEME_CALLBACK(Align_interface, stretch_after_break, 1)
  SCM
@@@ -76,6 -83,55 +79,6 @@@ Align_interface::stretch_after_break (S
    return SCM_UNSPECIFIED;
  }
  
 -/*
 -  merge with align-to-extents?
 -*/
 -void
 -Align_interface::align_to_fixed_distance (Grob *me, Axis a)
 -{
 -  Direction stacking_dir = robust_scm2dir (me->get_property ("stacking-dir"),
 -                                         DOWN);
 -
 -  Real dy = robust_scm2double (me->get_property ("forced-distance"), 0.0);
 -
 -  extract_grob_set (me, "elements", elem_source);
 -
 -  vector<Grob*> elems (elem_source); // writable..
 -
 -  Real where = 0;
 -
 -  Interval v;
 -  v.set_empty ();
 -  vector<Real> translates;
 -
 -  for (vsize j = elems.size (); j--;)
 -    {
 -      /*
 -      This is not very elegant, in that we need special support for
 -      hara-kiri. Unfortunately, the generic wiring of
 -      force_hara_kiri_callback () (extent and offset callback) is
 -      such that we might get into a loop if we call extent () or
 -      offset () the elements.
 -      */
 -      if (a == Y_AXIS
 -        && Hara_kiri_group_spanner::has_interface (elems[j]))
 -      Hara_kiri_group_spanner::consider_suicide (elems[j]);
 -
 -      if (!elems[j]->is_live ())
 -      elems.erase (elems.begin () + j);
 -    }
 -
 -  for (vsize j = 0; j < elems.size (); j++)
 -    {
 -      where += stacking_dir * dy;
 -      translates.push_back (where);
 -      v.unite (Interval (where, where));
 -    }
 -
 -  for (vsize i = 0; i < translates.size (); i++)
 -    elems[i]->translate_axis (translates[i] - v.center (), a);
 -}
 -
  /* for each grob, find its upper and lower skylines. If the grob has
     an empty extent, delete it from the list instead. If the extent is
     non-empty but there is no skyline available (or pure is true), just
@@@ -112,54 -168,52 +115,54 @@@ get_skylines (Grob *me
    for (vsize i = elements->size (); i--;)
      {
        Grob *g = (*elements)[i];
 -      Interval extent = g->maybe_pure_extent (g, a, pure, start, end);
 -      Interval other_extent = pure ? Interval (-infinity_f, infinity_f)
 -      : g->extent (common_refpoint, other_axis (a));
 -      Box b;
 -      b[a] = extent;
 -      b[other_axis (a)] = other_extent;
 -
 -      if (extent.is_empty ())
 -      {
 -        elements->erase (elements->begin () + i);
 -        continue;
 -      }
 -
        Skyline_pair skylines;
 -      if (!pure
 -        && Skyline_pair::unsmob (g->get_property ("skylines")))
 -      skylines = *Skyline_pair::unsmob (g->get_property ("skylines"));
 -      else
 -      {
 -        if (!pure)
 -          programming_error ("no skylines for alignment-child\n");
 -        
 -        skylines = Skyline_pair (b, 0, other_axis (a));
 -      }
  
        /* each skyline is calculated relative to (potentially) a different other_axis
         coordinate. In order to compare the skylines effectively, we need to shift them
         to some absolute reference point */
        if (!pure)
        {
 +        Skyline_pair *skys = Skyline_pair::unsmob (g->get_property ("skylines"));
 +        if (skys)
 +          skylines = *skys;
 +        else
 +          programming_error ("no skylines for alignment-child\n");
 +
          /* this is perhaps an abuse of minimum-?-extent: maybe we should create
             another property? But it seems that the only (current) use of
             minimum-Y-extent is to separate vertically-aligned elements */
          SCM min_extent = g->get_property (a == X_AXIS ? "minimum-X-extent" : "minimum-Y-extent");
 +
          if (is_number_pair (min_extent))
            {
 +            Box b;
 +            Interval other_extent = g->extent (common_refpoint, other_axis (a));
              b[a] = ly_scm2interval (min_extent);
 -            skylines.insert (b, 0, other_axis (a));
 +            b[other_axis (a)] = other_extent;
 +            if (!other_extent.is_empty ())
 +              skylines.insert (b, 0, other_axis (a));
            }
  
          Real offset = child_refpoints[i]->relative_coordinate (common_refpoint, other_axis (a));
          skylines.shift (offset);
        }
 +      else
 +      {
 +        assert (a == Y_AXIS);
 +        Interval extent = g->pure_height (g, start, end);
 +        if (!extent.is_empty ())
 +          {
 +            Box b;
 +            b[a] = extent;
 +            b[other_axis (a)] = Interval (-infinity_f, infinity_f);
 +            skylines.insert (b, 0, other_axis (a));
 +          }
 +      }
  
 -
 -      ret->push_back (skylines);
 +      if (skylines.is_empty ())
 +      elements->erase (elements->begin () + i);
 +      else
 +      ret->push_back (skylines);
      }
    reverse (*ret);
  }
@@@ -196,7 -250,6 +199,7 @@@ Align_interface::get_extents_aligned_tr
    get_skylines (me, &elems, a, pure, start, end, &skylines);
  
    Real where = 0;
 +  /* TODO: extra-space stuff belongs to two-pass spacing. Delete me */
    SCM extra_space_handle = scm_assq (ly_symbol2scm ("alignment-extra-space"), line_break_details);
    Real extra_space = robust_scm2double (scm_is_pair (extra_space_handle)
                                        ? scm_cdr (extra_space_handle)
@@@ -257,25 -310,6 +260,25 @@@ Align_interface::align_elements_to_exte
        all_grobs[j]->translate_axis (translates[j], a);
  }
  
 +/* After we have already determined the y-offsets of our children, we may still
 +   want to stretch them a little. */
 +void
 +Align_interface::stretch (Grob *me, Real amount, Axis a)
 +{
 +  extract_grob_set (me, "elements", elts);
 +  Real non_empty_elts = stretchable_children_count (me);
 +  Real offset = 0.0;
 +  Direction dir = robust_scm2dir (me->get_property ("stacking-dir"), DOWN);
 +  for (vsize i = 0; i < elts.size (); i++)
 +    {
 +      elts[i]->translate_axis (dir * offset, a);
 +      if (!elts[i]->extent (me, a).is_empty ()
 +        && !to_boolean (elts[i]->get_property ("keep-fixed-while-stretching")))
 +      offset += amount / non_empty_elts;
 +    }
 +  me->flush_extent_cache (Y_AXIS);
 +}
 +
  Real
  Align_interface::get_pure_child_y_translation (Grob *me, Grob *ch, int start, int end)
  {
@@@ -345,59 -379,22 +348,59 @@@ Align_interface::set_ordered (Grob *me
    ga->set_ordered (true);
  }
  
 +int
 +Align_interface::stretchable_children_count (Grob const *me)
 +{
 +  extract_grob_set (me, "elements", elts);
 +  int ret = 0;
 +
 +  /* start at 1: we will never move the first child while stretching */
 +  for (vsize i = 1; i < elts.size (); i++)
 +    if (!to_boolean (elts[i]->get_property ("keep-fixed-while-stretching"))
 +      && !elts[i]->extent (elts[i], Y_AXIS).is_empty ())
 +      ret++;
 +
 +  return ret;
 +}
 +
 +MAKE_SCHEME_CALLBACK (Align_interface, calc_max_stretch, 1)
 +SCM
 +Align_interface::calc_max_stretch (SCM smob)
 +{
 +  Grob *me = unsmob_grob (smob);
 +  Spanner *spanner_me = dynamic_cast<Spanner*> (me);
 +  Real ret = 0;
 +
 +  if (spanner_me && stretchable_children_count (me) > 0)
 +    {
 +      Paper_column *left = dynamic_cast<Paper_column*> (spanner_me->get_bound (LEFT));
 +      Real height = me->extent (me, Y_AXIS).length ();
 +      SCM line_break_details = left->get_property ("line-break-system-details");
 +      SCM fixed_offsets = scm_assq (ly_symbol2scm ("alignment-offsets"),
 +                                  line_break_details);
 +
 +      /* if there are fixed offsets, we refuse to stretch */
 +      if (fixed_offsets != SCM_BOOL_F)
 +      ret = 0;
 +      else
 +      ret = height * height / 80.0; /* why this, exactly? -- jneem */
 +    }
 +  return scm_from_double (ret);
 +}
 +
  /*
    Find Y-axis parent of G that has a #'forced-distance property. This
    has the effect of finding the piano-staff given an object in that
    piano staff.
 +
 +  FIXME: piano staves no longer have forced-distance. The code that
 +  relies on this function (in line-spanner) is broken.
  */
  Grob *
  find_fixed_alignment_parent (Grob *g)
  {
 -  while (g)
 -    {
 -      if (scm_is_number (g->get_property ("forced-distance")))
 -      return g;
 -
 -      g = g->get_parent (Y_AXIS);
 -    }
 -
 +  (void) g;
 +  programming_error ("deprecated. We don't use forced-distance anymore");
    return 0;
  }
  
@@@ -417,6 -414,7 +420,6 @@@ ADD_INTERFACE (Align_interface
               "align-dir "
               "axes "
               "elements "
 -             "forced-distance "
               "padding "
               "positioning-done "
               "stacking-dir "
index 84ba60c83f60d0187f7b3a000a09423d7a3be1d5,ecc83ac756b6bfa315c6f788897d4f1d93bd67d1..9f2396504248255304a885ac9d6773718798dfa6
@@@ -36,8 -36,6 +36,6 @@@ protected
  void
  Bar_number_engraver::process_music ()
  {
-   // todo include (&&!time->cadenza_b_)
    SCM wb = get_property ("whichBar");
  
    if (scm_is_string (wb))
@@@ -100,7 -98,12 +98,7 @@@ Bar_number_engraver::acknowledge_break_
  void
  Bar_number_engraver::stop_translation_timestep ()
  {
 -  if (text_)
 -    {
 -      text_->set_object ("side-support-elements",
 -                       grob_list_to_grob_array (get_property ("stavesFound")));
 -      text_ = 0;
 -    }
 +  text_ = 0;
  }
  
  void
diff --combined lily/beam.cc
index 75f859ffe4a46e274be806ecce5c548631e3b452,28492eaee14f74722599118a5f344ea4621aea3a..18cfae23cd2f58462b524a5387c95ad8871d7b92
@@@ -695,7 -695,7 +695,7 @@@ Beam::consider_auto_knees (Grob *me
            sets stem directions, a constant shift does not have an
            influence.
          */
 -        head_extents += stem->relative_coordinate (common, Y_AXIS);
 +        head_extents += stem->pure_relative_y_coordinate (common, 0, INT_MAX);
  
          if (to_dir (stem->get_property_data ("direction")))
            {
@@@ -974,6 -974,7 +974,6 @@@ Beam::shift_region_to_valid (SCM grob, 
    Real dx = lvs->relative_coordinate (commonx, X_AXIS) - x0;
  
    Drul_array<Real> pos = ly_scm2interval (posns);
 -  
  
    scale_drul (&pos, Staff_symbol_referencer::staff_space (me));
  
@@@ -1306,7 -1307,7 +1306,7 @@@ Beam::last_normal_stem (Grob *me
  
    rest -> stem -> beam -> interpolate_y_position ()
  */
- MAKE_SCHEME_CALLBACK_WITH_OPTARGS (Beam, rest_collision_callback, 2, 1);
+ MAKE_SCHEME_CALLBACK_WITH_OPTARGS (Beam, rest_collision_callback, 2, 1, "");
  SCM
  Beam::rest_collision_callback (SCM smob, SCM prev_offset)
  {
@@@ -1420,24 -1421,6 +1420,24 @@@ Beam::is_knee (Grob *me
    return knee;
  }
  
 +bool
 +Beam::is_cross_staff (Grob *me)
 +{
 +  extract_grob_set (me, "stems", stems);
 +  Grob *staff_symbol = Staff_symbol_referencer::get_staff_symbol (me);
 +  for (vsize i = 0; i < stems.size (); i++)
 +    if (Staff_symbol_referencer::get_staff_symbol (stems[i]) != staff_symbol)
 +      return true;
 +  return false;
 +}
 +
 +MAKE_SCHEME_CALLBACK (Beam, cross_staff, 1)
 +SCM
 +Beam::cross_staff (SCM smob)
 +{
 +  return scm_from_bool (is_cross_staff (unsmob_grob (smob)));
 +}
 +
  int
  Beam::get_direction_beam_count (Grob *me, Direction d)
  {
diff --combined lily/grob.cc
index d1318ba95481fac4d743fe164dba7c5341b41de8,e12152821b075a4a194f1f3b3e8facb80eb227be..37d715bf0743f4c2cb31b27970656d0ff40a2a51
@@@ -394,7 -394,7 +394,7 @@@ Grob::extent (Grob *refp, Axis a) cons
        (a == X_AXIS)
        ? ly_symbol2scm ("X-extent")
        : ly_symbol2scm ("Y-extent");
+       
        SCM ext = internal_get_property (ext_sym);
        if (is_number_pair (ext))
        real_ext.unite (ly_scm2interval (ext));
@@@ -613,7 -613,6 +613,7 @@@ ADD_INTERFACE (Grob
               "before-line-breaking "
               "cause "
               "color "
 +             "cross-staff "
               "extra-X-extent "
               "extra-Y-extent "
               "extra-offset "
diff --combined lily/paper-score.cc
index f91a4cddee1deaa0ab3e2466dc5f99037c7097f7,4a2eceef12e8e6462da1474efe5f798a537bfdd5..db0258328232ee30cec1a199bd7862c0e51f8f61
@@@ -106,9 -106,9 +106,9 @@@ Paper_score::calc_breaking (
  
    int system_count = robust_scm2int (layout ()->c_variable ("system-count"), 0);
    if (system_count)
 -    algorithm.resize (system_count);
 +    return algorithm.solve (0, VPOS, system_count);
  
 -  return algorithm.solve ();
 +  return algorithm.best_solution (0, VPOS);
  }
  
  void
@@@ -152,9 -152,14 +152,15 @@@ Paper_score::get_paper_systems (
        vector<Column_x_positions> breaking = calc_breaking ();
        system_->break_into_pieces (breaking);
        message (_ ("Drawing systems...") + " ");
 +      system_->do_break_substitution_and_fixup_refpoints ();
        paper_systems_ = system_->get_paper_systems ();
      }
    return paper_systems_;
  }
  
+ Paper_score *
+ unsmob_paper_score (SCM x)
+ {
+   return dynamic_cast<Paper_score*> (unsmob_music_output (x));
+ }
diff --combined lily/prob-scheme.cc
index dc53e51d3387e1bdae82b12774a3a6c08be4fcbe,c22c88bc729ab57a1c189ce10def62f0c730fdd7..a9838bb4353be12aafaea4ef3a315bbf19f477d3
@@@ -7,15 -7,14 +7,15 @@@
  */
  
  #include "prob.hh"
 +#include "skyline.hh"
  
  LY_DEFINE (ly_prob_set_property_x, "ly:prob-set-property!",
           2, 1, 0, (SCM obj, SCM sym, SCM value),
           "Set property @var{sym} of @var{obj} to @var{value}")
  {
+   LY_ASSERT_SMOB (Prob, obj, 1);
    Prob *ps = unsmob_prob (obj);
-   SCM_ASSERT_TYPE (ps, obj, SCM_ARG1, __FUNCTION__, "Prob");
-   SCM_ASSERT_TYPE (scm_is_symbol (sym), sym, SCM_ARG2, __FUNCTION__, "symbol");
+   LY_ASSERT_TYPE (ly_is_symbol, sym, 2);
  
    ps->set_property (sym, value);
    return SCM_UNSPECIFIED;
@@@ -23,7 -22,7 +23,7 @@@
  
  /*
    Hmm, this is not orthogonal.
 */
+ */
  LY_DEFINE (ly_prob_property_p, "ly:prob-property?",
           2, 1, 0, (SCM obj, SCM sym),
           "Is boolean prop @var{sym} set?")
@@@ -35,9 -34,9 +35,9 @@@ LY_DEFINE (ly_prob_property, "ly:prob-p
           2, 1, 0, (SCM obj, SCM sym, SCM dfault),
           "Return the value for @var{sym}.")
  {
+   LY_ASSERT_SMOB (Prob, obj, 1);
    Prob *ps = unsmob_prob (obj);
-   SCM_ASSERT_TYPE (ps, obj, SCM_ARG1, __FUNCTION__, "Prob");
-   SCM_ASSERT_TYPE (scm_is_symbol (sym), sym, SCM_ARG2, __FUNCTION__, "symbol");
+   LY_ASSERT_TYPE (ly_is_symbol,sym, 2);
  
    if (dfault == SCM_UNDEFINED)
      dfault = SCM_EOL;
@@@ -84,28 -83,3 +84,28 @@@ LY_DEFINE(ly_paper_system_p, "ly:paper-
  {
    return ly_prob_type_p (obj, ly_symbol2scm ("paper-system"));
  }
 +
 +LY_DEFINE (ly_paper_system_minimum_distance, "ly:paper-system-minimum-distance",
 +         2, 0, 0, (SCM sys1, SCM sys2),
 +         "Measure the minimum distance between these two paper-systems "
 +         "using their stored skylines if possible and falling back to "
 +         "their extents otherwise.")
 +{
 +  Real ret = 0;
 +  Prob *p1 = unsmob_prob (sys1);
 +  Prob *p2 = unsmob_prob (sys2);
 +  Skyline_pair *sky1 = Skyline_pair::unsmob (p1->get_property ("skylines"));
 +  Skyline_pair *sky2 = Skyline_pair::unsmob (p2->get_property ("skylines"));
 +
 +  if (sky1 && sky2)
 +    ret = (*sky1)[DOWN].distance ((*sky2)[UP]);
 +  else
 +    {
 +      Stencil *s1 = unsmob_stencil (p1->get_property ("stencil"));
 +      Stencil *s2 = unsmob_stencil (p2->get_property ("stencil"));
 +      Interval iv1 = s1->extent (Y_AXIS);
 +      Interval iv2 = s2->extent (Y_AXIS);
 +      ret = iv2[UP] - iv1[DOWN];
 +    }
 +  return scm_from_double (ret);
 +}
diff --combined lily/slur.cc
index f3938b23d11ef5c14e53ab090eadf46ddb0a90db,9ce45e61f59bbd515522d72f59eb306ad25cf6f5..3b26af8bebabb63b83ba8c965cbf5687e45b696d
@@@ -221,7 -221,7 +221,7 @@@ Slur::add_extra_encompass (Grob *me, Gr
    Pointer_group_interface::add_grob (me, ly_symbol2scm ("encompass-objects"), n);
  }
  
- MAKE_SCHEME_CALLBACK_WITH_OPTARGS (Slur, pure_outside_slur_callback, 4, 1);
+ MAKE_SCHEME_CALLBACK_WITH_OPTARGS (Slur, pure_outside_slur_callback, 4, 1, "");
  SCM
  Slur::pure_outside_slur_callback (SCM grob, SCM start_scm, SCM end_scm, SCM offset_scm)
  {
    return scm_from_double (offset + dir * slur->pure_height (slur, start, end).length () / 4);
  }
  
- MAKE_SCHEME_CALLBACK_WITH_OPTARGS (Slur, outside_slur_callback, 2, 1);
+ MAKE_SCHEME_CALLBACK_WITH_OPTARGS (Slur, outside_slur_callback, 2, 1, "");
  SCM
  Slur::outside_slur_callback (SCM grob, SCM offset_scm)
  {
@@@ -356,20 -356,6 +356,20 @@@ Slur::auxiliary_acknowledge_extra_objec
      e->warning ("Ignoring grob for slur. avoid-slur not set?");
  }
  
 +MAKE_SCHEME_CALLBACK (Slur, cross_staff, 1)
 +SCM
 +Slur::cross_staff (SCM smob)
 +{
 +  Grob *me = unsmob_grob (smob);
 +  Grob *staff = Staff_symbol_referencer::get_staff_symbol (me);
 +  assert (staff); // delete me
 +  extract_grob_set (me, "note-columns", cols);
 +
 +  for (vsize i = 0; i < cols.size (); i++)
 +    if (Staff_symbol_referencer::get_staff_symbol (cols[i]) != staff)
 +      return SCM_BOOL_T;
 +  return SCM_BOOL_F;
 +}
  
  ADD_INTERFACE (Slur,
               
diff --combined lily/stem.cc
index dd247b4baa1997e2d74ea8783d13649631d91f38,857dfb7d49fbbc37aceed0421697de11b9806566..09786b750b5d205d4b7f834b6c6fa69fe507453b
@@@ -239,10 -239,6 +239,10 @@@ Stem::pure_height (SCM smob, SCM start
  
    if (!is_normal_stem (me))
      return ly_interval2scm (iv);
 +
 +  /* if we are part of a cross-staff beam, return empty */
 +  if (get_beam (me) && Beam::is_cross_staff (get_beam (me)))
 +    return ly_interval2scm (iv);
    
    Real ss = Staff_symbol_referencer::staff_space (me);
    Real len = scm_to_double (calc_length (smob)) * ss / 2;
@@@ -414,6 -410,8 +414,8 @@@ Stem::calc_positioning_done (SCM smob
    if (!head_count (me))
      return SCM_BOOL_T;
  
+   me->set_property ("positioning-done", SCM_BOOL_T);
+   
    extract_grob_set (me, "note-heads", ro_heads);
    vector<Grob*> heads (ro_heads);
    vector_sort (heads, position_less);
@@@ -559,13 -557,11 +561,11 @@@ SC
  Stem::height (SCM smob)
  {
    Grob *me = unsmob_grob (smob);
+   if (!is_normal_stem (me))
+     return ly_interval2scm (Interval ());
+   
    Direction dir = get_grob_direction (me);
    
-   /* Trigger callback.
-   UGH. Should be automatic
-   */
    Grob *beam = get_beam (me);
    if (beam)
      {
@@@ -912,10 -908,14 +912,14 @@@ Stem::calc_stem_info (SCM smob
    Real height_of_my_trem = 0.0;
    Grob *trem = unsmob_grob (me->get_object ("tremolo-flag"));
    if (trem)
-       height_of_my_trem = trem->extent (trem, Y_AXIS).length ()
+     {
+       height_of_my_trem
+       = Stem_tremolo::vertical_length (trem)
          /* hack a bit of space around the trem. */
          + beam_translation;
+     }
  
+   
    /* UGH
       It seems that also for ideal minimum length, we must use
       the maximum beam count (for this direction):
@@@ -1001,20 -1001,6 +1005,20 @@@ Stem::beam_multiplicity (Grob *stem
    return le;
  }
  
 +bool
 +Stem::is_cross_staff (Grob *stem)
 +{
 +  Grob *beam = unsmob_grob (stem->get_object ("beam"));
 +  return beam && Beam::is_cross_staff (beam);
 +}
 +
 +MAKE_SCHEME_CALLBACK (Stem, cross_staff, 1)
 +SCM
 +Stem::cross_staff (SCM smob)
 +{
 +  return scm_from_bool (is_cross_staff (unsmob_grob (smob)));
 +}
 +
  /* FIXME:  Too many properties  */
  ADD_INTERFACE (Stem,
               "The stem represent the graphical stem.  "
index 0b9f3e4a67db4463eb7cf372cd525f91d0871839,0bdc95efc03c183daf390641d7763d562b460e2e..f7b2576d85043c734d0dc9e55add6526ff762ddc
@@@ -22,6 -22,7 +22,6 @@@ public
    TRANSLATOR_DECLARATIONS (Text_spanner_engraver);
  protected:
    virtual void finalize ();
 -  DECLARE_ACKNOWLEDGER (note_column);
    DECLARE_TRANSLATOR_LISTENER (text_span);
    void stop_translation_timestep ();
    void process_music ();
@@@ -81,6 -82,20 +81,6 @@@ Text_spanner_engraver::process_music (
      }
  }
  
 -void
 -Text_spanner_engraver::acknowledge_note_column (Grob_info info)
 -{
 -  Spanner *spans[2] ={span_, finished_};
 -  for (int i = 0; i < 2; i++)
 -    {
 -      if (spans[i])
 -      {
 -        Side_position_interface::add_support (spans[i], info.grob ());
 -        add_bound_item (spans[i], info.grob ());
 -      }
 -    }
 -}
 -
  void
  Text_spanner_engraver::typeset_all ()
  {
@@@ -121,8 -136,15 +121,13 @@@ Text_spanner_engraver::finalize (
      }
  }
  
 -ADD_ACKNOWLEDGER (Text_spanner_engraver, note_column);
 -
  ADD_TRANSLATOR (Text_spanner_engraver,
-               /* doc */ "Create text spanner from an event.",
-               /* create */ "TextSpanner",
-               /* read */ "",
-               /* write */ "");
+               /* doc */
+               "Create text spanner from an event.",
+               /* create */
+               "TextSpanner ",
+               /* read */
+               "",
+               /* write */
+               ""
+               );
index 8e56784812c6369e692011c0d69ae33c20a6272f,0100e66b52bc6f56082796ebd9f88d942db531ae..d2ef7e1eb8045c836316aa3c838ed8ebe3667374
@@@ -29,6 -29,7 +29,6 @@@ public
    TRANSLATOR_DECLARATIONS (Trill_spanner_engraver);
  protected:
    virtual void finalize ();
 -  DECLARE_ACKNOWLEDGER (note_column);
    DECLARE_TRANSLATOR_LISTENER (trill_span);
    void stop_translation_timestep ();
    void process_music ();
@@@ -87,6 -88,20 +87,6 @@@ Trill_spanner_engraver::process_music (
      }
  }
  
 -void
 -Trill_spanner_engraver::acknowledge_note_column (Grob_info info)
 -{
 -  Spanner *spans[2] ={span_, finished_};
 -  for (int i = 0; i < 2; i++)
 -    {
 -      if (spans[i])
 -      {
 -        Side_position_interface::add_support (spans[i], info.grob ());
 -        add_bound_item (spans[i], info.grob ());
 -      }
 -    }
 -}
 -
  void
  Trill_spanner_engraver::typeset_all ()
  {
@@@ -126,8 -141,10 +126,9 @@@ Trill_spanner_engraver::finalize (
      }
  }
  
 -ADD_ACKNOWLEDGER (Trill_spanner_engraver, note_column);
  ADD_TRANSLATOR (Trill_spanner_engraver,
                /* doc */ "Create trill spanner from an event.",
-               /* create */ "TrillSpanner",
+               /* create */
+               "TrillSpanner ",
                /* read */ "",
                /* write */ "");
diff --combined ly/engraver-init.ly
index ddcced5c46f0d30df301fc06141b6e51fa75eb23,aa78dd538ffb4d7633d1d46174d795da5e1fb1d7..0f8560c8106926083f3518db1cedc1f34bbd1cc5
@@@ -57,6 -57,7 +57,6 @@@
    \consists "Figured_bass_position_engraver"
    \consists "Script_row_engraver"
  
 -  \override VerticalAxisGroup #'minimum-Y-extent = #'(-3.5 . 3.5)
    localKeySignature = #'()
    createSpacing = ##t
    ignoreFiguredBassRest = ##t 
@@@ -306,8 -307,11 +306,8 @@@ contained staves are not connected vert
    \description
    "Just like @code{GrandStaff} but with a forced distance between
      the staves, so cross staff beaming and slurring can be used."
 -  
 -  \override VerticalAlignment #'forced-distance = #12
 -  \override VerticalAlignment #'self-alignment-Y = #0
  
 -  \consists "Vertical_align_engraver"
 +  \override VerticalAxisGroup #'minimum-Y-extent = #'(-4 . 4)
    \consists "Instrument_name_engraver"
    
    instrumentName = #'()
@@@ -376,7 -380,6 +376,7 @@@ printing of a single line of lyrics.  
  
    \override VerticalAxisGroup #'remove-first = ##t
    \override VerticalAxisGroup #'remove-empty = ##t
 +  \override VerticalAxisGroup #'keep-fixed-while-stretching = ##t
    \override SeparationItem #'padding = #0.2
    \override InstrumentName #'self-alignment-Y = ##f
  
@@@ -756,10 -759,7 +756,7 @@@ AncientRemoveEmptyStaffContext = \conte
    %%
    \override TextSpanner #'dash-fraction = #'()
    \override TextSpanner #'style = #'line
-   \override TextSpanner #'edge-height = #'(0 . 0)
    \override TextSpanner #'padding = #-0.1
-   \override TextSpanner #'enclose-bounds = #1
-   \override TextSpanner #'edge-text = #'("" . "")
  }
  
  \context {
    %%
    \override TextSpanner #'dash-fraction = #'()
    \override TextSpanner #'style = #'line
-   \override TextSpanner #'edge-height = #'(0 . 0)
    \override TextSpanner #'padding = #-0.1
-   \override TextSpanner #'enclose-bounds = #1
-   \override TextSpanner #'edge-text = #'("" . "")
  }
  
  \context {
index 68e92a4fbb1274a0040f6f4fc020107290be6b79,7de42c3ae1cd6e5b6a5d45b4522a38180a453080..7cf4d853f8ea18c8329f0586af2c0e7884f4389d
@@@ -35,7 -35,6 +35,6 @@@ relative to its Y-parent"
       (allow-loose-spacing ,boolean? "If set, column can be detached from main spacing.")
       (arpeggio-direction ,ly:dir? "If set, put an
  arrow on the arpeggio squiggly line.")
-      (arrow ,boolean? "Add an arrow to the line.")
       (arrow-length ,number? "Arrow length.")
       (arrow-width ,number? "Arrow width.")
       (auto-knee-gap ,ly:dimension? "If a gap is found between note heads
@@@ -130,9 -129,6 +129,6 @@@ the vertical edges '(@var{left-height} 
       (edge-text ,pair? "A pair specifying the texts to be set at the
  edges '(@var{left-text} . @var{right-text}).")
       (eccentricity ,number? "How asymmetrical to make a slur. Positive means move the center to the right.")
-      (enclose-bounds ,number?
-                    "How much of the bound a spanner should enclose:
- +1 = completely, 0 = center, -1 not at all.")
       (expand-limit ,integer? "maximum number of measures expanded in church rests.")
       ;; remove me?
       (extra-dy ,number? "Slope glissandi this much extra.")
@@@ -170,6 -166,8 +166,6 @@@ include @code{medium}, @code{bold}, @co
       (font-shape ,symbol? "Select the shape of a font. Choices include @code{upright},
  @code{italic}, @code{caps}.")
       (forced ,boolean? "manually forced accidental")
 -     (forced-distance ,ly:dimension? "A fixed distance between object
 -reference points in an alignment.")
       (force-hshift ,number? "This specifies a manual shift for notes
  in collisions. The unit is the note head width of the first voice
  note.  This is used by @internalsref{note-collision-interface}.")
@@@ -209,7 -207,6 +205,7 @@@ set beam/slur quant to this position, a
       (inspect-index ,integer? "If debugging is set,
  set beam/slur configuration to this index, and print the respective scores.")
       (implicit ,boolean? "Is this an implicit bass figure?")
 +     (keep-fixed-while-stretching ,boolean? "A grob with this property set to true will be fixed relative to the staff above it when systems are stretched.")
       (keep-inside-line ,boolean? "If set, this column cannot have
  things sticking into the margin.")
       (kern ,ly:dimension? "Amount of extra white space to add. For
@@@ -242,8 -239,6 +238,8 @@@ column is the start of a system."
       (long-text ,markup? "Text markup.  See @usermanref{Text markup}.")
       (max-beam-connect ,integer? "Maximum number of beams to connect
  to beams from this stem. Further beams are typeset as beamlets.")
 +     (max-stretch ,number? "The maximum amount that this vertical-axis-group
 +can be vertically stretched (for example, in order to better fill a page).")
       (measure-length ,ly:moment? "Length of a
  measure. Used in some spacing situations.")
       (measure-count ,integer? "The number of measures for a
@@@ -470,7 -465,6 +466,7 @@@ function is to protect objects from bei
       (arpeggio ,ly:grob? "pointer to arpeggio object.")
       (beam ,ly:grob? "pointer to the beam, if applicable.")
       (bracket ,ly:grob? "the bracket for a  number.")
 +     (cross-staff ,boolean? "for a beam or a stem, true if we depend on inter-staff spacing")
       (direction-source ,ly:grob? "in case side-relative-direction is
  set, which grob to get the direction from .")
       (dot ,ly:grob? "reference to Dots object.")
diff --combined scm/define-grobs.scm
index 5acb4fc1c6bd3972ce69681f0d43abb0d52720c1,b7d25131bfee6c4afb5885162ad072105a7fa2cc..eefc76fe1343181c821de59f2792f3e4dc52b0c1
        (beaming . ,ly:beam::calc-beaming)
        (stencil . ,ly:beam::print)
        (clip-edges . #t)
 +      (cross-staff . ,ly:beam::cross-staff)
  
        (details .  ((hint-direction-penalty . 20)))
        ;; TODO: should be in SLT.
        (Y-offset . ,ly:side-position-interface::y-aligned-side)
        (staff-padding . 0.1)
        (padding . 0.6)
 -      (avoid-slur . outside)
        (slur-padding . 0.3)
        (minimum-space . 1.2)
        (direction . ,DOWN)
        (font-series . bold)
        (font-encoding . fetaDynamic)
        (font-shape . italic)
 -      (avoid-slur . around)
        (extra-spacing-width . (+inf.0 . -inf.0))
        (outside-staff-priority . 250)
        (meta . ((class . Item)
        (font-shape . italic)
        (style . dashed-line)
  
+       ;; make sure the spanner doesn't get too close to notes
+       (minimum-Y-extent . (-1 . 1))
        (bound-details . ((right . ((attach-dir .  ,LEFT)
                                    (Y . 0)
                                    (padding . 0.75)
                                   (padding . 0.5)
                                   ))
                          (left-broken . ((attach-dir .  ,RIGHT)
-                                         
-                                         ;; make sure the - - - stays at reasonable
-                                         ;; distance from staff.
-                                         (text . " ")
                                   ))
                          ))
-       (stencil . ,ly:new-line-spanner::print)
-       (left-bound-info . ,ly:new-line-spanner::calc-left-bound-info-and-text)
-       (right-bound-info . ,ly:new-line-spanner::calc-right-bound-info)
+       (stencil . ,ly:line-spanner::print)
+       (left-bound-info . ,ly:line-spanner::calc-left-bound-info-and-text)
+       (right-bound-info . ,ly:line-spanner::calc-right-bound-info)
  
        ;; need to blend with dynamic texts.
        (font-size . 1)
        (meta . ((class . Spanner)
                 (interfaces . (font-interface
                                text-interface
-                               new-line-spanner-interface
+                               line-spanner-interface
                                line-interface
                                dynamic-interface
                                dynamic-text-spanner-interface
                                   (padding . 1.5)
                                      ))
                          ))
-       (stencil . ,ly:new-line-spanner::print)
-       (left-bound-info . ,ly:new-line-spanner::calc-left-bound-info)
-       (right-bound-info . ,ly:new-line-spanner::calc-right-bound-info)
+       (stencil . ,ly:line-spanner::print)
+       (left-bound-info . ,ly:line-spanner::calc-left-bound-info)
+       (right-bound-info . ,ly:line-spanner::calc-right-bound-info)
        (meta . ((class . Spanner)
                 (interfaces . (line-interface
                                unbreakable-spanner-interface
-                               new-line-spanner-interface))))))
+                               line-spanner-interface))))))
  
      (GraceSpacing
       . (
        (minimum-length . 1.5)
        (height-limit . 2.0)
        (ratio . 0.333)
 +      (cross-staff . ,ly:slur::cross-staff)
        (meta . ((class . Spanner)
                 (interfaces . (slur-interface))))))
  
        (height-limit . 2.0)
        (ratio . 0.25)
        (avoid-slur . inside)
 +      (cross-staff . ,ly:slur::cross-staff)
        (meta . ((class . Spanner)
                 (interfaces . (slur-interface))))))
  
        (Y-extent . ,ly:stem::height)
        (length . ,ly:stem::calc-length)
        (thickness . 1.3)
 +      (cross-staff . ,ly:stem::cross-staff)
        (details
         . (
            ;; 3.5 (or 3 measured from note head) is standard length
        (X-offset . ,ly:self-alignment-interface::x-aligned-on-self)
        (meta . ((class . Item)
                 (interfaces . (piano-pedal-interface
-                               text-spanner-interface
-                               line-spanner-interface
                                text-interface
                                self-alignment-interface
                                piano-pedal-script-interface
        (X-extent . ,ly:axis-group-interface::width)
        (Y-extent . ,ly:axis-group-interface::height)
        (skylines . ,ly:axis-group-interface::calc-skylines)
 +      (max-stretch . ,ly:axis-group-interface::calc-max-stretch)
        (skyline-horizontal-padding . 1.0)
        (meta . ((class . System)
                 (interfaces . (system-interface
  
      (TextSpanner
       . (
-       (stencil . ,ly:text-spanner::print)
        (Y-offset . ,ly:side-position-interface::y-aligned-side)
        (font-shape . italic)
        (style . dashed-line)
        (side-axis . ,Y)
        (direction . ,UP)
        (outside-staff-priority . 350)
+       (left-bound-info . ,ly:line-spanner::calc-left-bound-info)
+       (right-bound-info . ,ly:line-spanner::calc-right-bound-info)
+       (bound-details . ((left . ((Y . 0)
+                                  (padding . 0.25)
+                                  (attach-dir . ,LEFT)
+                                  ))
+                         (right . ((Y . 0)
+                                   (padding . 0.25)
+                                  ))
+                         ))
+       (stencil . ,ly:line-spanner::print)
        (meta . ((class . Spanner)
-                (interfaces . (text-spanner-interface
-                               line-spanner-interface
+                (interfaces . (line-spanner-interface
                                side-position-interface
                                font-interface))))))
  
  
      (TrillSpanner
       . (
-       (left-bound-info . ,ly:new-line-spanner::calc-left-bound-info)
-       (right-bound-info . ,ly:new-line-spanner::calc-right-bound-info)
+       (left-bound-info . ,ly:line-spanner::calc-left-bound-info)
+       (right-bound-info . ,ly:line-spanner::calc-right-bound-info)
  
        (bound-details . ((left . ((text . ,(make-translate-scaled-markup
                                             '(0.5 . -0.6)
                          (right . ((Y . 0)))
                          ))
        
-       (stencil . ,ly:new-line-spanner::print)
+       (stencil . ,ly:line-spanner::print)
  
        (style . trill)
        (staff-padding . 1.0)
        (side-axis . ,Y)
        (outside-staff-priority . 50)
        (meta . ((class . Spanner)
-                (interfaces . (text-spanner-interface
-                               new-line-spanner-interface
+                (interfaces . (line-spanner-interface
+                               line-interface
+                               trill-spanner-interface
                                side-position-interface
                                font-interface))))))
  
        (stacking-dir . -1)
        (padding . 0.5)
        (skylines . ,ly:axis-group-interface::combine-skylines)
 +      (max-stretch . ,ly:align-interface::calc-max-stretch)
        (meta . ((class . Spanner)
                 (object-callbacks . ((Y-common . ,ly:axis-group-interface::calc-y-common)))
                 (interfaces . (align-interface
        (Y-offset . ,ly:hara-kiri-group-spanner::force-hara-kiri-callback)
        (Y-extent . ,ly:hara-kiri-group-spanner::y-extent)
        (X-extent . ,ly:axis-group-interface::width)
 -      (skylines . ,ly:axis-group-interface::calc-skylines);
 +      (skylines . ,ly:axis-group-interface::calc-skylines)
 +      (max-stretch . ,ly:axis-group-interface::calc-max-stretch)
        (meta . ((class . Spanner)
                 (object-callbacks . ((X-common . ,ly:axis-group-interface::calc-x-common)))
                 (interfaces . (axis-group-interface
                                   (padding . 1.5)
                                      ))
                          ))
-       (stencil . ,ly:new-line-spanner::print)
-       (left-bound-info . ,ly:new-line-spanner::calc-left-bound-info)
-       (right-bound-info . ,ly:new-line-spanner::calc-right-bound-info)
+       (stencil . ,ly:line-spanner::print)
+       (left-bound-info . ,ly:line-spanner::calc-left-bound-info)
+       (right-bound-info . ,ly:line-spanner::calc-right-bound-info)
        (meta . ((class . Spanner)
-                (interfaces . (new-line-spanner-interface
+                (interfaces . (line-spanner-interface
                                line-interface))))
        ))