]> 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, 20 Dec 2006 07:11:54 +0000 (09:11 +0200)
committerJoe Neeman <joeneeman@gmail.com>
Wed, 20 Dec 2006 07:11:54 +0000 (09:11 +0200)
18 files changed:
Documentation/user/programming-interface.itely
Documentation/user/tweaks.itely
Documentation/user/working.itely
lily/accidental-placement.cc
lily/align-interface.cc
lily/axis-group-interface.cc
lily/dynamic-engraver.cc
lily/include/accidental-placement.hh
lily/include/axis-group-interface.hh
lily/include/separation-item.hh
lily/include/skyline.hh
lily/item.cc
lily/script-column.cc
lily/separation-item.cc
lily/skyline.cc
ly/property-init.ly
scm/define-grob-properties.scm
scm/define-grobs.scm

index 9a62200bbabba423e9f2f34d9c7609a9e1d8af4b..1cadde8f2ecedbc21556b1ca58c6a8562ad44e78 100644 (file)
@@ -123,7 +123,7 @@ tempoMark = #(define-music-function (parser location padding marktext)
                                     (number? string?)
 #{
   \once \override Score . RehearsalMark #'padding = $padding
-  \once \override Score . RehearsalMark #'no-spacing-rods = ##t
+  \once \override Score . RehearsalMark #'extra-spacing-width = #'(+inf.0 . -inf.0)
   \mark \markup { \bold $marktext }
 #})
 
index bbef69b00b094477b42670432b0a8cd17ad0040e..b26704c13c5f28c8cb78ca42e17b466d7868a104 100644 (file)
@@ -460,7 +460,7 @@ tempoMark = #(define-music-function (parser location padding marktext)
                                     (number? string?)
 #{
   \once \override Score . RehearsalMark #'padding = $padding
-  \once \override Score . RehearsalMark #'no-spacing-rods = ##t
+  \once \override Score . RehearsalMark #'extra-spacing-width = #'(+inf.0 . -inf.0)
   \mark \markup { \bold $marktext }
 #})
 
index 2872272a9f09c7341d70129e976dd0e41669ee5b..ff343cf51e4e024853f1d22c64d75e0572f68c83 100644 (file)
@@ -298,7 +298,7 @@ mpdolce = #(make-dynamic-script (markup #:hspace 1 #:translate (cons 5 0)
 tempoMark = #(define-music-function (parser location markp) (string?)
 #{
   \once \override Score . RehearsalMark #'self-alignment-X = #left
-  \once \override Score . RehearsalMark #'no-spacing-rods = ##t
+  \once \override Score . RehearsalMark #'extra-spacing-width = #'(+inf.0 . -inf.0)
   \mark \markup { \bold $markp }
 #})
 
@@ -326,7 +326,7 @@ mpdolce = #(make-dynamic-script (markup #:hspace 1 #:translate (cons 5 0)
 tempoMark = #(define-music-function (parser location markp) (string?)
 #@{
   \once \override Score . RehearsalMark #'self-alignment-X = #left
-  \once \override Score . RehearsalMark #'no-spacing-rods = ##t
+  \once \override Score . RehearsalMark #'extra-spacing-width = #'(+inf.0 . -inf.0)
   \mark \markup @{ \bold $markp @}
 #@})
 @end example
@@ -354,7 +354,7 @@ mpdolce = #(make-dynamic-script (markup #:hspace 1 #:translate (cons 5 0)
 tempoMark = #(define-music-function (parser location markp) (string?)
 #{
   \once \override Score . RehearsalMark #'self-alignment-X = #left
-  \once \override Score . RehearsalMark #'no-spacing-rods = ##t
+  \once \override Score . RehearsalMark #'extra-spacing-width = #'(+inf.0 . -inf.0)
   \mark \markup { \bold $markp }
 #})
 
@@ -383,7 +383,7 @@ mpdolce = #(make-dynamic-script (markup #:hspace 1 #:translate (cons 5 0)
 tempoMark = #(define-music-function (parser location markp) (string?)
 #@{
   \once \override Score . RehearsalMark #'self-alignment-X = #left
-  \once \override Score . RehearsalMark #'no-spacing-rods = ##t
+  \once \override Score . RehearsalMark #'extra-spacing-width = #'(+inf.0 . -inf.0)
   \mark \markup @{ \bold $markp @}
 #@})
 
@@ -408,7 +408,7 @@ mpdolce = #(make-dynamic-script (markup #:hspace 1 #:translate (cons 5 0)
 tempoMark = #(define-music-function (parser location markp) (string?)
 #{
   \once \override Score . RehearsalMark #'self-alignment-X = #left
-  \once \override Score . RehearsalMark #'no-spacing-rods = ##t
+  \once \override Score . RehearsalMark #'extra-spacing-width = #'(+inf.0 . -inf.0)
   \mark \markup { \bold $markp }
 #})
 
@@ -450,7 +450,7 @@ mpdolce = #(make-dynamic-script (markup #:hspace 1 #:translate (cons 5 0)
 tempoMark = #(define-music-function (parser location markp) (string?)
 #@{
   \once \override Score . RehearsalMark #'self-alignment-X = #left
-  \once \override Score . RehearsalMark #'no-spacing-rods = ##t
+  \once \override Score . RehearsalMark #'extra-spacing-width = #'(+inf.0 . -inf.0)
   \mark \markup @{ \bold $markp @}
 #@})
 
@@ -475,7 +475,7 @@ mpdolce = #(make-dynamic-script (markup #:hspace 1 #:translate (cons 5 0)
 tempoMark = #(define-music-function (parser location markp) (string?)
 #{
   \once \override Score . RehearsalMark #'self-alignment-X = #left
-  \once \override Score . RehearsalMark #'no-spacing-rods = ##t
+  \once \override Score . RehearsalMark #'extra-spacing-width = #'(+inf.0 . -inf.0)
   \mark \markup { \bold $markp }
 #})
 
index f6bfefff5d944ca100b370bb9e1cdcb9133166ea..6aaf49b2e6ea12c11ab32370de72453f9a9f85ed 100644 (file)
@@ -75,6 +75,24 @@ Accidental_placement::split_accidentals (Grob *accs,
       }
 }
 
+vector<Grob*>
+Accidental_placement::get_break_reminder_accidentals (vector<Grob*> const &elts, Grob *left)
+{
+  vector<Grob*> br;
+  vector<Grob*> ra;
+  vector<Grob*> ret;
+
+  if (dynamic_cast<Item *> (left)->break_status_dir () != RIGHT)
+    return vector<Grob*> ();
+
+  for (vsize i = 0; i < elts.size (); i++)
+    {
+      split_accidentals (elts[i], &br, &ra);
+      ret.insert (ret.end (), br.begin (), br.end ());
+    }
+  return ret;
+}
+
 /*
   Accidentals are special, because they appear and disappear after
   ties at will.
index f2eacf7608893e0c964511a87c812494bc6ec623..2f23220c5a1bfe518f3b5998b8c063101eb54835 100644 (file)
@@ -123,28 +123,71 @@ Align_interface::align_to_fixed_distance (Grob *me, Axis a)
       v.unite (Interval (where, where));
     }
 
-  /*
-    TODO: support self-alignment-{Y, X}
-  */
   for (vsize i = 0; i < translates.size (); i++)
     elems[i]->translate_axis (translates[i] - v.center (), a);
 }
 
-/*
-  Hairy function to put elements where they should be. Can be tweaked
-  from the outside by setting extra-space in its
-  children
-
-  We assume that the children the refpoints of the children are still
-  found at 0.0 -- we will fuck up with thresholds if children's
-  extents are already moved to locations such as (-16, -8), since the
-  dy needed to put things in a row doesn't relate to the distances
-  between original refpoints.
-
-  TODO: maybe we should rethink and throw out thresholding altogether.
-  The original function has been taken over by
-  align_to_fixed_distance ().
-*/
+/* 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
+   create a flat skyline from the bounding box */
+static void
+get_skylines (Grob *me,
+             vector<Grob*> *const elements,
+             Axis a,
+             bool pure, int start, int end,
+             vector<Skyline_pair> *const ret)
+{
+  Grob *other_axis_common = common_refpoint_of_array (*elements, me, other_axis (a));
+  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 (other_axis_common, other_axis (a));
+      Box b = (a == X_AXIS) ? Box (extent, other_extent) : Box (other_extent, 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)
+       {
+         /* 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))
+           {
+             b[a] = ly_scm2interval (min_extent);
+             skylines.insert (b, 0, other_axis (a));
+           }
+         Real offset = g->relative_coordinate (other_axis_common, other_axis (a));
+         skylines.shift (-offset);
+       }
+
+
+      ret->push_back (skylines);
+    }
+  reverse (*ret);
+}
 
 vector<Real>
 Align_interface::get_extents_aligned_translates (Grob *me,
@@ -169,63 +212,29 @@ Align_interface::get_extents_aligned_translates (Grob *me,
   Direction stacking_dir = robust_scm2dir (me->get_property ("stacking-dir"),
                                           DOWN);
 
-  Interval threshold = robust_scm2interval (me->get_property ("threshold"),
-                                           Interval (0, Interval::infinity ()));
+  vector<Grob*> elems (all_grobs); // writable copy
+  vector<Skyline_pair> skylines;
 
-  vector<Interval> dims;
-  vector<Grob*> elems;
+  get_skylines (me, &elems, a, pure, start, end, &skylines);
 
-  for (vsize i = 0; i < all_grobs.size (); i++)
-    {
-      Interval y = all_grobs[i]->maybe_pure_extent (all_grobs[i], a, pure, start, end);
-      if (!y.is_empty ())
-       {
-         Grob *e = dynamic_cast<Grob *> (all_grobs[i]);
-
-         elems.push_back (e);
-         dims.push_back (y);
-       }
-    }
-
-  /*
-    Read self-alignment-X and self-alignment-Y. This may seem like
-    code duplication. (and really: it is), but this is necessary to
-    prevent ugly cyclic dependencies that arise when you combine
-    self-alignment on a child with alignment of children.
-  */
-  SCM align ((a == X_AXIS)
-            ? me->get_property ("self-alignment-X")
-            : me->get_property ("self-alignment-Y"));
-
-  Interval total;
   Real where = 0;
-  Real extra_space = 0.0;
   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)
+                                       : SCM_EOL,
+                                       0.0);
 
-  extra_space = robust_scm2double (scm_is_pair (extra_space_handle)
-                                  ? scm_cdr (extra_space_handle)
-                                  : SCM_EOL,
-                                  extra_space);
-
-  Real padding = robust_scm2double (me->get_property ("padding"),
-                                   0.0);
+  Real padding = robust_scm2double (me->get_property ("padding"), 0.0);
   vector<Real> translates;
   for (vsize j = 0; j < elems.size (); j++)
     {
-      Real dy = -dims[j][-stacking_dir];
-      if (j)
-       dy += dims[j - 1][stacking_dir];
-
-      /*
-       we want dy to be > 0
-      */
-      dy *= stacking_dir;
-      if (j)
-       dy = min (max (dy, threshold[SMALLER]), threshold[BIGGER]);
-
+      Real dy = 0;
+      if (j == 0)
+       dy = skylines[j][-stacking_dir].max_height ();
+      else
+       dy = skylines[j-1][stacking_dir].distance (skylines[j][-stacking_dir]);
 
       where += stacking_dir * (dy + padding + extra_space / elems.size ());
-      total.unite (dims[j] + where);
       translates.push_back (where);
     }
 
@@ -243,25 +252,16 @@ Align_interface::get_extents_aligned_translates (Grob *me,
        }
     }
 
-  
-  Real center_offset = 0.0;
-  
-  /*
-    also move the grobs that were empty, to maintain spatial order.
-  */
   vector<Real> all_translates;
-  if (translates.size ())
+
+  if (!translates.empty ())
     {
       Real w = translates[0];
-
-      if (scm_is_number (align))
-       center_offset = total.linear_combination (scm_to_double (align));
-
       for  (vsize i = 0, j = 0; j < all_grobs.size (); j++)
        {
          if (i < elems.size () && all_grobs[j] == elems[i])
            w = translates[i++];
-         all_translates.push_back (w - center_offset);
+         all_translates.push_back (w);
        }
     }
   return all_translates;
index 9149f667bc42443cee407e82373b8078af67ae64..4319bb8b92cd0594311142bed40928dddeec28ae 100644 (file)
@@ -179,13 +179,54 @@ Axis_group_interface::pure_height (SCM smob, SCM start_scm, SCM end_scm)
 
   return pure_group_height (me, start, end);
 }
+
+MAKE_SCHEME_CALLBACK (Axis_group_interface, calc_skylines, 1);
+SCM
+Axis_group_interface::calc_skylines (SCM smob)
+{
+  Grob *me = unsmob_grob (smob);
+  extract_grob_set (me, "elements", elts);
+  return skyline_spacing (me, elts).smobbed_copy ();
+}
+
+/* whereas calc_skylines calculates skylines for axis-groups with a lot of
+   visible children, combine_skylines is designed for axis-groups whose only
+   children are other axis-groups (ie. VerticalAlignment). Rather than
+   calculating all the skylines from scratch, we just merge the skylines
+   of the children.
+*/
+MAKE_SCHEME_CALLBACK (Axis_group_interface, combine_skylines, 1);
+SCM
+Axis_group_interface::combine_skylines (SCM smob)
+{
+  Grob *me = unsmob_grob (smob);
+  extract_grob_set (me, "elements", elements);
+  Grob *y_common = common_refpoint_of_array (elements, me, Y_AXIS);
+
+  assert (y_common == me);
+
+  Skyline_pair ret;
+  for (vsize i = 0; i < elements.size (); i++)
+    {
+      SCM skyline_scm = elements[i]->get_property ("skylines");
+      if (Skyline_pair::unsmob (skyline_scm))
+       {
+         Real offset = elements[i]->relative_coordinate (y_common, Y_AXIS);
+         Skyline_pair other = *Skyline_pair::unsmob (skyline_scm);
+         other.raise (offset);
+         ret.merge (other);
+       }
+    }
+  return ret.smobbed_copy ();
+}
   
 SCM
 Axis_group_interface::generic_group_extent (Grob *me, Axis a)
 {
+  /* trigger the callback to do skyline-spacing on the children */
+  (void) me->get_property ("skylines");
+
   extract_grob_set (me, "elements", elts);
-  if (a == Y_AXIS && to_boolean (me->get_property ("skyline-spacing")))
-    skyline_spacing (me, elts);
   Grob *common = common_refpoint_of_array (elts, me, a);
 
   Real my_coord = me->relative_coordinate (common, a);
@@ -258,8 +299,8 @@ Axis_group_interface::get_children (Grob *me, vector<Grob*> *found)
 bool
 staff_priority_less (Grob * const &g1, Grob * const &g2)
 {
-  int priority_1 = robust_scm2int (g1->get_property ("outside-staff-priority"), INT_MIN);
-  int priority_2 = robust_scm2int (g2->get_property ("outside-staff-priority"), INT_MIN);
+  Real priority_1 = robust_scm2double (g1->get_property ("outside-staff-priority"), -infinity_f);
+  Real priority_2 = robust_scm2double (g2->get_property ("outside-staff-priority"), -infinity_f);
 
   if (priority_1 < priority_2)
     return true;
@@ -307,7 +348,7 @@ add_boxes (Grob *me, Grob *x_common, Grob *y_common, vector<Box> *const boxes)
    edge of the just-placed grob).  Otherwise, we skip it until the next pass.
 */
 static void
-add_grobs_of_one_priority (Drul_array<Skyline> *const skylines,
+add_grobs_of_one_priority (Skyline_pair *const skylines,
                           vector<Grob*> elements,
                           Grob *x_common,
                           Grob *y_common)
@@ -354,7 +395,7 @@ add_grobs_of_one_priority (Drul_array<Skyline> *const skylines,
                  elements[i]->translate_axis (dir*dist, Y_AXIS);
                }
              (*skylines)[dir].insert (b, 0, X_AXIS);
-             elements[i]->del_property ("outside-staff-padding");
+             elements[i]->set_property ("outside-staff-priority", SCM_BOOL_F);
              last_affected_position[dir] = b[X_AXIS][RIGHT];
            }
          elements.erase (elements.begin () + i);
@@ -362,13 +403,15 @@ add_grobs_of_one_priority (Drul_array<Skyline> *const skylines,
     }
 }
 
-void
+Skyline_pair
 Axis_group_interface::skyline_spacing (Grob *me, vector<Grob*> elements)
 {
   vector_sort (elements, staff_priority_less);
   Grob *x_common = common_refpoint_of_array (elements, me, X_AXIS);
   Grob *y_common = common_refpoint_of_array (elements, me, Y_AXIS);
 
+  assert (y_common == me);
+
   vsize i = 0;
   vector<Box> boxes;
 
@@ -376,8 +419,7 @@ Axis_group_interface::skyline_spacing (Grob *me, vector<Grob*> elements)
         && !scm_is_number (elements[i]->get_property ("outside-staff-priority")); i++)
     add_boxes (elements[i], x_common, y_common, &boxes);
 
-  Drul_array<Skyline> skylines (Skyline (boxes, 0, X_AXIS, DOWN),
-                               Skyline (boxes, 0, X_AXIS, UP));
+  Skyline_pair skylines (boxes, 0, X_AXIS);
   for (; i < elements.size (); i++)
     {
       SCM priority = elements[i]->get_property ("outside-staff-priority");
@@ -389,6 +431,7 @@ Axis_group_interface::skyline_spacing (Grob *me, vector<Grob*> elements)
 
       add_grobs_of_one_priority (&skylines, current_elts, x_common, y_common);
     }
+  return skylines;
 }
 
 ADD_INTERFACE (Axis_group_interface,
@@ -400,6 +443,6 @@ ADD_INTERFACE (Axis_group_interface,
               "elements "
               "common-refpoint-of-elements "
               "pure-relevant-elements "
-              "skyline-spacing "
+              "skylines "
               "cached-pure-extents "
               );
index 5c3d0feecdf2627da0f4ffca841dc5ef864298a9..8f64db11363add6c9653bacb8efed2f7cc0a9254 100644 (file)
@@ -64,7 +64,6 @@ class Dynamic_engraver : public Engraver
 
   TRANSLATOR_DECLARATIONS (Dynamic_engraver);
   DECLARE_ACKNOWLEDGER (accidental);
-  DECLARE_ACKNOWLEDGER (script);
   DECLARE_ACKNOWLEDGER (stem_tremolo);
   DECLARE_ACKNOWLEDGER (note_column);
   DECLARE_ACKNOWLEDGER (slur);
@@ -454,27 +453,7 @@ Dynamic_engraver::acknowledge_note_column (Grob_info info)
     finished_cresc_->set_bound (RIGHT, info.grob ());
 }
 
-void
-Dynamic_engraver::acknowledge_script (Grob_info info)
-{
-  if (!line_spanner_ || !script_)
-    return;
-
-  SCM p = info.grob ()->get_property ("script-priority");
-
-  /*
-    UGH.
-
-    DynamicText doesn't really have a script-priority field.
-  */
-  if (scm_is_number (p)
-      && scm_to_int (p)
-      < scm_to_int (script_->get_property ("script-priority")))
-    Side_position_interface::add_support (line_spanner_, info.grob ());
-}
-
 ADD_ACKNOWLEDGER (Dynamic_engraver, accidental);
-ADD_ACKNOWLEDGER (Dynamic_engraver, script);
 ADD_ACKNOWLEDGER (Dynamic_engraver, note_column);
 ADD_ACKNOWLEDGER (Dynamic_engraver, slur);
 ADD_ACKNOWLEDGER (Dynamic_engraver, stem_tremolo);
index c34fc0b76615ca275e21bd36a18abf2f52ebb5ae..5d09bdc2df699cfbd555051536c434db5b39d589 100644 (file)
@@ -18,6 +18,8 @@ public:
   DECLARE_SCHEME_CALLBACK (alignment_callback, (SCM element));
   static void add_accidental (Grob *, Grob *);
 
+  static vector<Grob*> get_break_reminder_accidentals (vector<Grob*> const &elts,
+                                                      Grob *left);
   static Interval get_relevant_accidental_extent (Grob *me,
                                                  Item *item_col,
                                                  Grob *acc);
index b38537c661adb815447b0ad0912f46a73922e5e9..4272b1a8901acaa2a8678dee0f5ebad2c00c070d 100644 (file)
@@ -12,6 +12,7 @@
 #include "std-vector.hh"
 #include "lily-proto.hh"
 #include "grob-interface.hh"
+#include "skyline.hh"
 
 struct Axis_group_interface
 {
@@ -20,6 +21,8 @@ struct Axis_group_interface
   DECLARE_SCHEME_CALLBACK (width, (SCM smob));
   DECLARE_SCHEME_CALLBACK (height, (SCM smob));
   DECLARE_SCHEME_CALLBACK (pure_height, (SCM smob, SCM start, SCM end));
+  DECLARE_SCHEME_CALLBACK (calc_skylines, (SCM smob));
+  DECLARE_SCHEME_CALLBACK (combine_skylines, (SCM smob));
   static Interval relative_group_extent (vector<Grob*> const &list,
                                         Grob *common, Axis);
   static Interval relative_pure_height (Grob *me, vector<Grob*> const &list,
@@ -28,7 +31,7 @@ struct Axis_group_interface
   static Interval cached_pure_height (Grob *me, vector<Grob*> const &list,
                                      Grob *common, int, int);
 
-  static void skyline_spacing (Grob *me, vector<Grob*> elements);
+  static Skyline_pair skyline_spacing (Grob *me, vector<Grob*> elements);
   static void add_element (Grob *me, Grob *);
   static void set_axes (Grob *, Axis, Axis);
   static bool has_axis (Grob *, Axis);
index ca63294852c86626712be3d2cf31209ee7fcbfc3..4fb59b5e6209ed16549db80de4c0615fe71a025e 100644 (file)
 #include "lily-proto.hh"
 #include "direction.hh"
 #include "grob-interface.hh"
+#include "skyline.hh"
 
 struct Separation_item
 {
   DECLARE_GROB_INTERFACE();
   DECLARE_SCHEME_CALLBACK(calc_skylines, (SCM));
 
-  static vector<Box> boxes (Grob *me);
-  static Interval conditional_width (Grob *, Grob *);
+  static vector<Box> boxes (Grob *me, Grob *left);
+  static Skyline conditional_skyline (Grob *, Grob *);
   static Interval width (Grob *);
   static Interval relative_width (Grob *, Grob *);
   static Grob *extremal_break_aligned_grob (Grob *, Direction, Interval *);
index 7f3130ecab09f770c4f9c7e4538d501d47ca94b4..36fd9d23e4aff9d2489602c4e8e5e808341abf86 100644 (file)
@@ -28,6 +28,7 @@ struct Building
 
   void precompute ();
   Building (Real start, Real start_height, Real end_height, Real end);
+  Building (Box const &b, Real horizon_padding, Axis a, Direction d);
   void print () const;
 
   Real height (Real x) const;
@@ -35,6 +36,7 @@ struct Building
   void leading_part (Real chop);
   bool conceals_beginning (Building const &other) const;
   bool conceals (Building const &other) const;
+  bool sane () const;
   Building sloped_neighbour (Real horizon_padding, Direction d) const;
 };
 
@@ -55,16 +57,36 @@ public:
   Skyline (Skyline const &src);
   Skyline (Direction sky);
   Skyline (vector<Box> const &bldgs, Real horizon_padding, Axis a, Direction sky);
+  Skyline (Box const &b, Real horizon_padding, Axis a, Direction sky);
   vector<Offset> to_points () const;
   void merge (Skyline const &);
   void insert (Box const &, Real horizon_padding, Axis);
   void print () const;
   void raise (Real);
+  void shift (Real);
   Real distance (Skyline const &) const;
   Real height (Real airplane) const;
   Real max_height () const;
   void set_minimum_height (Real height);
 };
 
+class Skyline_pair
+{
+private:
+  Drul_array<Skyline> skylines_;
+
+  DECLARE_SIMPLE_SMOBS(Skyline_pair);
+public:
+  Skyline_pair ();
+  Skyline_pair (vector<Box> const &boxes, Real horizon_padding, Axis a);
+  Skyline_pair (Box const &, Real horizon_padding, Axis a);
+  void raise (Real);
+  void shift (Real);
+  void insert (Box const &, Real horizon_padding, Axis);
+  void merge (Skyline_pair const &other);
+  Skyline &operator [] (Direction d);
+  Skyline const &operator [] (Direction d) const;
+};
+
 #endif /* SKYLINE_HH */
 
index 173df20ed87fd7b19451d2f4b212ea9c0dc18eea..5cf717a300695192cf49726f8f7dbce18fd18187 100644 (file)
@@ -233,5 +233,6 @@ ADD_INTERFACE (Item,
 
               /* properties */
               "break-visibility "
-              "no-spacing-rods "
+              "extra-spacing-width "
+              "infinite-spacing-height "
               "non-musical")
index 726b32727623e1bd4193b66d713dcf39c47f906b..a8fc0c3fc4c9c2067b6f68a86ede5e8c8c8be512 100644 (file)
@@ -133,7 +133,19 @@ Script_column::order_grobs (vector<Grob*> grobs)
        {
          Grob *g = unsmob_grob (scm_car (s));
          if (last)
-           Side_position_interface::add_support (g, last);
+           {
+             SCM outside_staff = last->get_property ("outside-staff-priority");
+             if (scm_is_number (outside_staff))
+               {
+                 /* we allow the outside-staff-priority ordering to override the
+                    script-priority ordering */
+                 if (!scm_is_number (g->get_property ("outside-staff-priority")))
+                   g->set_property ("outside-staff-priority",
+                                    scm_from_double (scm_to_double (outside_staff) + 0.1));
+               }
+             else
+               Side_position_interface::add_support (g, last);
+           }
 
          last = g;
        }
index 20de8fbbd57b6816723815e66c71753dbddd78b0..0867007375deff202948ba4c7c88a6eb663df03b 100644 (file)
@@ -31,17 +31,12 @@ void
 Separation_item::set_skyline_distance (Drul_array<Item *> items,
                                       Real padding)
 {
-  Drul_array<Skyline*> lines;
-  Direction d = LEFT;
-
-  do
-    {
-      SCM prop = items[d]->get_property ("skylines");
-      lines[d] = Skyline::unsmob (index_get_cell (prop, -d));
-    }
-  while (flip (&d) != LEFT);
-
-  Real dist = padding + lines[LEFT]->distance (*lines[RIGHT]);
+  Drul_array<Skyline_pair*> lines (Skyline_pair::unsmob (items[LEFT]->get_property ("skylines")),
+                                  Skyline_pair::unsmob (items[RIGHT]->get_property ("skylines")));
+  Skyline right = conditional_skyline (items[RIGHT], items[LEFT]);
+  right.merge ((*lines[RIGHT])[LEFT]);
+  
+  Real dist = padding + (*lines[LEFT])[RIGHT].distance (right);
   if (dist > 0)
     {
       Rod rod;
@@ -57,63 +52,19 @@ bool
 Separation_item::set_distance (Drul_array<Item *> items,
                               Real padding)
 {
-  if (!Item::is_non_musical (items[LEFT])
-      && !Item::is_non_musical (items[RIGHT]))
-    {
-      set_skyline_distance (items, padding);
-      return true;
-    }
-  
-  Interval li (Separation_item::width (items[LEFT]));
-  Interval ri (Separation_item::conditional_width (items[RIGHT], items[LEFT]));
-  if (!li.is_empty () && !ri.is_empty ())
-    {
-      Rod rod;
-
-      rod.item_drul_ = items;
-
-      rod.distance_ = li[RIGHT] - ri[LEFT] + padding;
-
-      if (rod.distance_  > 0)
-       rod.add_to_cols ();
-      return true;
-    }
-  return false;
+  set_skyline_distance (items, padding);
+  return true;
 }
 
 /*
   Return the width of ME given that we are considering the object on
   the LEFT.
 */
-Interval
-Separation_item::conditional_width (Grob *me, Grob *left)
+Skyline
+Separation_item::conditional_skyline (Grob *me, Grob *left)
 {
-  Interval w = width (me);
-
-  Item *item = dynamic_cast<Item *> (me);
-  Paper_column *pc = item->get_column ();
-
-  extract_grob_set (me, "conditional-elements", elts);
-  for (vsize i = 0; i < elts.size (); i++)
-    {
-      Item *il = dynamic_cast<Item *> (elts[i]);
-      if (pc != il->get_column ())
-       {
-         programming_error ("Separation_item element from wrong column");
-         continue;
-       }
-
-      if (to_boolean (il->get_property ("no-spacing-rods")))
-       continue;
-
-      if (Accidental_placement::has_interface (il))
-       w.unite (Accidental_placement::get_relevant_accidental_extent (il, pc, left));
-    }
-
-  SCM pad = me->get_property ("padding");
-
-  w.widen (robust_scm2double (pad, 0.0));
-  return w;
+  vector<Box> bs = boxes (me, left);
+  return Skyline (bs, 0.1, Y_AXIS, LEFT);
 }
 
 
@@ -122,31 +73,31 @@ SCM
 Separation_item::calc_skylines (SCM smob)
 {
   Item *me = unsmob_item (smob);
-  SCM lines = scm_cons (SCM_BOOL_F,SCM_BOOL_F);
-
-  Direction d = LEFT;
-  vector<Box> bs = boxes (me);
-  do
-    {
-      /* todo: the horizon_padding is somewhat arbitrary */
-      Skyline l (bs, 0.1, Y_AXIS, d);
-      index_set_cell (lines, d, l.smobbed_copy ());
-    }
-  while (flip (&d) != LEFT);
-
-  return lines;
+  vector<Box> bs = boxes (me, 0);
+  /* todo: the horizon_padding is somewhat arbitrary */
+  return Skyline_pair (bs, 0.1, Y_AXIS).smobbed_copy ();
 }
 
-
+/* if left is non-NULL, get the boxes corresponding to the
+   conditional-elements (conditioned on the grob LEFT). This
+   sounds more general than it is: conditional-elements are
+   always accidentals attached to a tied note.
+*/
 vector<Box>
-Separation_item::boxes (Grob *me)
+Separation_item::boxes (Grob *me, Grob *left)
 {
   Item *item = dynamic_cast<Item *> (me);
 
   int very_large = INT_MAX;
   Paper_column *pc = item->get_column ();
   vector<Box> out;
-  extract_grob_set (me, "elements", elts);
+  extract_grob_set (me, left ? "conditional-elements" : "elements", read_only_elts);
+  vector<Grob*> elts;
+
+  if (left)
+    elts = Accidental_placement::get_break_reminder_accidentals (read_only_elts, left);
+  else
+    elts = read_only_elts;
 
   Grob *ycommon = common_refpoint_of_array (elts, me, Y_AXIS);
   
@@ -158,13 +109,17 @@ Separation_item::boxes (Grob *me)
          continue;
        }
 
-      if (to_boolean (il->get_property ("no-spacing-rods")))
-       continue;
-
       Interval y (il->pure_height (ycommon, 0, very_large));
-      Box b (il->extent (pc, X_AXIS), y);
-
-      out.push_back (b);
+      Interval x (il->extent (pc, X_AXIS));
+
+      Interval extra = robust_scm2interval (elts[i]->get_property ("extra-spacing-width"),
+                                           Interval (0, 0));
+      x[LEFT] += extra[LEFT];
+      x[RIGHT] += extra[RIGHT];
+      if (to_boolean (elts[i]->get_property ("infinite-spacing-height")))
+       y = Interval (-infinity_f, infinity_f);
+      out.push_back (Box (x, y));
     }
 
   return out;      
@@ -174,39 +129,7 @@ Interval
 Separation_item::width (Grob *me)
 {
   SCM sw = me->get_property ("X-extent");
-  if (is_number_pair (sw))
-    return ly_scm2interval (sw);
-
-  Item *item = dynamic_cast<Item *> (me);
-  Paper_column *pc = item->get_column ();
-  Interval w;
-
-  extract_grob_set (me, "elements", elts);
-  for (vsize i = 0; i < elts.size (); i++)
-    {
-      Item *il = dynamic_cast<Item *> (elts[i]);
-      if (pc != il->get_column ())
-       {
-         /* this shouldn't happen, but let's continue anyway. */
-         programming_error ("Separation_item:  I've been drinking too much");
-         continue;             /*UGH UGH*/
-       }
-
-      if (to_boolean (il->get_property ("no-spacing-rods")))
-       continue;
-
-      Interval iv (il->extent (pc, X_AXIS));
-      if (!iv.is_empty ())
-       w.unite (iv);
-    }
-
-  SCM pad = me->get_property ("padding");
-
-  w.widen (robust_scm2double (pad, 0.0));
-
-  me->set_property ("X-extent", ly_interval2scm (w));
-
-  return w;
+  return ly_scm2interval (sw);
 }
 
 Interval
index ab877f28ce605fcb4854984c049885007007c47d..6b53a62ef845174c290f8ea02462afb156392e1a 100644 (file)
@@ -111,6 +111,19 @@ Building::Building (Real start, Real start_height, Real end_height, Real end)
   precompute ();
 }
 
+Building::Building (Box const &b, Real horizon_padding, Axis horizon_axis, Direction sky)
+{
+  Real height = sky * b[other_axis (horizon_axis)][sky];
+
+  iv_ = b[horizon_axis];
+  iv_.widen (horizon_padding + EPS);
+  height_[LEFT] = height;
+  height_[RIGHT] = height;
+
+  if (sane ())
+    precompute ();
+}
+
 void
 Building::precompute ()
 {
@@ -174,6 +187,14 @@ Building::sloped_neighbour (Real horizon_padding, Direction d) const
   return Building (left, left_height, right_height, right);
 }
 
+bool
+Building::sane () const
+{
+  return approx_less_than (iv_[LEFT], iv_[RIGHT])
+    && !isinf (height_[RIGHT])
+    && !isinf (height_[LEFT]);
+}
+
 static void
 skyline_trailing_part (list<Building> *sky, Real x)
 {
@@ -341,14 +362,9 @@ Skyline::Skyline (vector<Box> const &boxes, Real horizon_padding, Axis horizon_a
 
   for (vsize i = 0; i < boxes.size (); i++)
     {
-      Interval iv = boxes[i][horizon_axis];
-      Real height = sky * boxes[i][other_axis (horizon_axis)][sky];
-      
-      iv.widen (horizon_padding);
-      if (!iv.is_empty () && !isinf (height) && !approx_equal (iv[LEFT], iv[RIGHT]))
+      Building front (boxes[i], horizon_padding, horizon_axis, sky);
+      if (front.sane ())
        {
-         iv.widen (EPS);
-         Building front = Building (iv[LEFT], height, height, iv[RIGHT]);
          bldgs.push_front (front);
          if (horizon_padding > 0 && !isinf (front.iv_.length ()))
            {
@@ -362,6 +378,13 @@ Skyline::Skyline (vector<Box> const &boxes, Real horizon_padding, Axis horizon_a
   assert (is_legal_skyline ());
 }
 
+Skyline::Skyline (Box const &b, Real horizon_padding, Axis horizon_axis, Direction sky)
+{
+  sky_ = sky;
+  Building front (b, 0, horizon_axis, sky);
+  single_skyline (front, horizon_padding, &buildings_);
+}
+
 void
 Skyline::merge (Skyline const &other)
 {
@@ -379,14 +402,9 @@ Skyline::insert (Box const &b, Real horizon_padding, Axis a)
 {
   list<Building> other_bld;
   list<Building> my_bld;
-  Interval iv = b[a];
-  Real height = sky_ * b[other_axis (a)][sky_];
-
-  assert (!iv.is_empty ());
-  iv.widen (EPS);
 
   my_bld.splice (my_bld.begin (), buildings_);
-  single_skyline (Building (iv[LEFT], height, height, iv[RIGHT]), horizon_padding, &other_bld);
+  single_skyline (Building (b, 0, a, sky_), horizon_padding, &other_bld);
   internal_merge_skyline (&other_bld, &my_bld, &buildings_);
   assert (is_legal_skyline ());
 }
@@ -404,6 +422,17 @@ Skyline::raise (Real r)
   assert (is_legal_skyline ());
 }
 
+void
+Skyline::shift (Real r)
+{
+  list<Building>::iterator end = buildings_.end ();
+  for (list<Building>::iterator i = buildings_.begin (); i != end; i++)
+    {
+      i->iv_[LEFT] += r;
+      i->iv_[RIGHT] += r;
+    }
+}
+
 Real
 Skyline::distance (Skyline const &other) const
 {
@@ -476,6 +505,61 @@ Skyline::to_points () const
   return out;
 }
 
+Skyline_pair::Skyline_pair ()
+  : skylines_ (Skyline (DOWN), Skyline (UP))
+{
+}
+
+Skyline_pair::Skyline_pair (vector<Box> const &boxes, Real padding, Axis a)
+  : skylines_ (Skyline (boxes, padding, a, DOWN), Skyline (boxes, padding, a, UP))
+{
+}
+
+Skyline_pair::Skyline_pair (Box const &b, Real padding, Axis a)
+  : skylines_ (Skyline (b, padding, a, DOWN), Skyline (b, padding, a, UP))
+{
+}
+
+void
+Skyline_pair::raise (Real r)
+{
+  skylines_[UP].raise (r);
+  skylines_[DOWN].raise (r);
+}
+
+void
+Skyline_pair::shift (Real r)
+{
+  skylines_[UP].shift (r);
+  skylines_[DOWN].shift (r);
+}
+
+void
+Skyline_pair::insert (Box const &b, Real padding, Axis a)
+{
+  skylines_[UP].insert (b, padding, a);
+  skylines_[DOWN].insert (b, padding, a);
+}
+
+void
+Skyline_pair::merge (Skyline_pair const &other)
+{
+  skylines_[UP].merge (other[UP]);
+  skylines_[DOWN].merge (other[DOWN]);
+}
+
+Skyline&
+Skyline_pair::operator [] (Direction d)
+{
+  return skylines_[d];
+}
+
+Skyline const&
+Skyline_pair::operator [] (Direction d) const
+{
+  return skylines_[d];
+}
+
 /****************************************************************/
 
 
@@ -483,6 +567,10 @@ IMPLEMENT_SIMPLE_SMOBS (Skyline);
 IMPLEMENT_TYPE_P (Skyline, "ly:skyline?");
 IMPLEMENT_DEFAULT_EQUAL_P (Skyline);
 
+IMPLEMENT_SIMPLE_SMOBS (Skyline_pair);
+IMPLEMENT_TYPE_P (Skyline_pair, "ly:skyline-pair?");
+IMPLEMENT_DEFAULT_EQUAL_P (Skyline_pair);
+
 SCM
 Skyline::mark_smob (SCM)
 {
@@ -499,3 +587,19 @@ Skyline::print_smob (SCM s, SCM port, scm_print_state *)
 
   return 1;
 }
+
+SCM
+Skyline_pair::mark_smob (SCM)
+{
+  return SCM_EOL;
+}
+
+int
+Skyline_pair::print_smob (SCM s, SCM port, scm_print_state *)
+{
+  Skyline_pair *r = (Skyline_pair *) SCM_CELL_WORD_1 (s);
+  (void) r;
+
+  scm_puts ("#<Skyline-pair>", port);
+  return 1;
+}
index 10e301af306ccb3e24efcfc30c4289ec0ab208b9..f7fc11ae7358f6773049f39e729968c690b6ac2d 100644 (file)
@@ -123,8 +123,11 @@ endincipit =  \context Staff {
 autoBeamOff = \set autoBeaming = ##f
 autoBeamOn = \set autoBeaming = ##t
 
-fatText = \override TextScript  #'no-spacing-rods = ##f
-emptyText = \override TextScript  #'no-spacing-rods = ##t
+fatText = { \override TextScript  #'extra-spacing-width = #'(0 . 0)
+            \override TextScript  #'infinite-spacing-height = ##t }
+
+emptyText = { \override TextScript  #'extra-spacing-width = #'(+inf.0 . -inf.0)
+              \override TextScript  #'infinite-spacing-height = ##f }
 
 showStaffSwitch = \set followVoice = ##t
 hideStaffSwitch = \set followVoice = ##f
index 7fe48c14c5326fd71c76722d2fe33a611f092d13..b9012c52d7891d461637124c43022aa4ce6d8629 100644 (file)
@@ -141,6 +141,7 @@ edges '(@var{left-text} . @var{right-text}).")
      (extra-X-extent ,number-pair? "A grob is enlarged in X dimension
 by this much.")
      (extra-Y-extent ,number-pair? "See @code{extra-X-extent}.")
+     (extra-spacing-width ,number-pair? "In the horizontal spacing problem, we pad each item by this amount (by adding the car on the left side of the item and adding the cdr on the right side of the item). In order to make a grob take up no horizontal space at all, set this to (+inf.0 . -inf.0)")
      (X-extent ,number-pair? "Hard coded extent in X direction. ")
      (Y-extent ,number-pair? "See @code{X-extent}.")
      (extra-offset ,number-pair? "A pair representing an offset. This
@@ -202,6 +203,9 @@ of note-column for horizontal shifting. This is used by
 Choices are @code{around}, @code{inside}, @code{outside}.  If unset, script
 and slur ignore eachother.")
      (ignore-collision ,boolean? "If set, don't do note collision resolution on this NoteColumn.")
+     (infinite-spacing-height ,boolean? "If true, then for the purposes of
+horizontal spacing, treat this item as though it were infinitely tall. That
+is, no object from another column will be allowed to stick above or below this item.")
      (inspect-quants ,number-pair? "If debugging is set,
 set beam/slur quant to this position, and print the respective scores.")
      (inspect-index ,integer? "If debugging is set,
@@ -269,8 +273,6 @@ to flip the direction of custos stem.")
      (note-names ,vector? "Vector of strings containing names for
 easy-notation note heads.")
      (no-ledgers ,boolean? "If set, don't draw ledger lines on this object.")
-     (no-spacing-rods ,boolean? "Items with this property do not cause
-spacing constraints.")
      (no-stem-extend ,boolean? "If set, notes with ledger lines do not
 get stems extending to the middle staff line.")
      (non-musical ,boolean? "True if the grob belongs in a NonMusicalPaperColumn.")
@@ -349,7 +351,7 @@ note that starts here.")
 object.")
      (side-axis ,number? "If the value is #X (or equivalently 1), the object is placed horizontally next to the other object. If the value is #Y or 0, it is placed vertically.")
      (size ,number? "Size of object, relative to standard size.")
-     (skylines ,pair? "A pair of lists of (x height) pairs.")
+     (skylines ,ly:skyline-pair? "Two skylines, one above and one below this grob (or, for some grobs, to the left and to the right).")
      (slope ,number? "The slope of this object.")
      (slur-padding ,number? "Extra distance between slur and script.")
      (space-alist ,list? "A table that specifies distances between
@@ -563,8 +565,6 @@ than a whole rest.")
      (spaceable-staves ,ly:grob-array? "Objects to be spaced during page layout.")
      (skyline-distance ,number? "The distance between this staff and the next one, as determined by a skyline algorithm.")
      (skyline-horizontal-padding ,number? "For determining the vertical distance between 2 staves, it is possible to have a configuration which would result in a tight interleaving of grobs from the top staff and the bottom staff. The larger this parameter is, the farther apart the staves will be placed in such a configuration.")
-     (skyline-spacing ,boolean? "When true, this axis-group will vertically space its children
-using a skyline algorithm.")
 
      
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
index a3d1df686407f632eb15362606469e4895fca1f7..a794f75470ba16e892353429638d2b6c955b8598 100644 (file)
        (layer . 0)
        (break-visibility . ,all-visible)
        (non-musical . #t)
+       (extra-spacing-width . (-0.3 . 0.3))
 
        (stencil . ,ly:bar-line::print)
        (glyph-name . ,bar-line::calc-glyph-name)
      . (
        (axes . (,Y))
        (Y-extent . ,ly:axis-group-interface::height)
+       (skylines . ,ly:axis-group-interface::calc-skylines)
        (meta . ((class . Spanner)
                 (interfaces . (axis-group-interface
                                ))))))
     (CombineTextScript
      . (
        (stencil . ,ly:text-interface::print)
-       (no-spacing-rods . #t)
+       (extra-spacing-width . (+inf.0 . -inf.0))
        (Y-offset . ,ly:side-position-interface::y-aligned-side)
        (X-offset . ,ly:self-alignment-interface::x-aligned-on-self)
        (direction . ,UP)
        (font-encoding . fetaDynamic)
        (font-shape . italic)
        (avoid-slur . around)
-       (no-spacing-rods . #t)
-       (script-priority . 100)
+       (extra-spacing-width . (+inf.0 . -inf.0))
        (outside-staff-priority . 250)
        (meta . ((class . Item)
                 (interfaces . (font-interface
        
        (Y-offset . ,ly:side-position-interface::y-aligned-side)
        (stencil . ,ly:text-interface::print)
-
-       ;; no Y dimensions, because of lyrics under tenor clef.
-       (Y-extent . (0 . 0))
        (font-shape . italic)
        (padding . 0.6)
        (staff-padding . 0.2)
        (stencil . ,ly:text-interface::print)
        (direction . ,RIGHT)
        (X-offset . ,ly:self-alignment-interface::x-aligned-on-self)
-       (no-spacing-rods . #t)
+       (extra-spacing-width . (+inf.0 . -inf.0))
        (padding . 0.0) ;; padding relative to SostenutoPedalLineSpanner
        (font-shape . italic)
        (self-alignment-X . 0)
 
     (SustainPedal
      . (
-       (no-spacing-rods . #t)
+       (extra-spacing-width . (+inf.0 . -inf.0))
        (stencil . ,ly:sustain-pedal::print)
        (self-alignment-X . 0)
        (direction . ,RIGHT)
        (axes . (0 1))
        (X-extent . ,ly:axis-group-interface::width)
        (Y-extent . ,ly:axis-group-interface::height)
-       (skyline-spacing . #t)
+       (skylines . ,ly:axis-group-interface::calc-skylines)
        (skyline-horizontal-padding . 1.0)
        (meta . ((class . System)
                 (interfaces . (system-interface
 
     (TextScript
      . (
-       (no-spacing-rods . #t)
+       (extra-spacing-width . (+inf.0 . -inf.0))
        (X-offset . ,ly:self-alignment-interface::x-aligned-on-self)
        (Y-offset . ,ly:side-position-interface::y-aligned-side)
        (side-axis . ,Y)
      . (
        (stencil . ,ly:text-interface::print)
        (font-shape . italic)
-       (no-spacing-rods . #t)
+       (extra-spacing-width . (+inf.0 . -inf.0))
        (self-alignment-X . 0)
        (direction . ,RIGHT)
        (padding . 0.0)  ;; padding relative to UnaCordaPedalLineSpanner
        (Y-extent . ,ly:axis-group-interface::height)
        (X-extent . ,ly:axis-group-interface::width)
        (stacking-dir . -1)
-       (padding . 0.1) 
+       (padding . 0.1)
+       (skylines . ,ly:axis-group-interface::combine-skylines)
        (meta . ((class . Spanner)
                 (interfaces . (align-interface
                                axis-group-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)
-       (skyline-spacing . #t)
+       (skylines . ,ly:axis-group-interface::calc-skylines);
        (meta . ((class . Spanner)
                 (interfaces . (axis-group-interface
                                hara-kiri-group-spanner-interface
 
 (define pure-print-callbacks
   (list
+   ly:bar-line::print
    ly:note-head::print
    ly:accidental-interface::print
    ly:dots::print
         (ly:stencil? sten)
         (memq sten pure-print-callbacks))
        (ly:grob::stencil-height grob)
-
        '(0 . 0))))
 
 (define pure-conversions-alist