]> git.donarmstrong.com Git - lilypond.git/commitdiff
Move left-broken line-spanner check to callback.
authorNeil Puttock <n.puttock@gmail.com>
Sun, 12 Apr 2009 12:15:03 +0000 (13:15 +0100)
committerNeil Puttock <n.puttock@gmail.com>
Wed, 15 Apr 2009 19:34:41 +0000 (20:34 +0100)
Currently, left-broken line spanners and hairpins are removed when they
end on the first note of the new system.  Though this is appropriate
for glissandi and voice followers, there is no way to override this
default behaviour.

This patch allows the user to tweak the appearance by overriding
'after-line-breaking.

- removed left-broken check from ly:line-spanner::print to a new
after-line-breaking callback, ly:spanner::kill-zero-spanned-time

- removed hairpin after-line-breaking callback and associated method
consider_suicide ()

- added new callback to Hairpin, Glissando, TrillSpanner and VoiceFollower

- added convert rule for ly:hairpin::after-line-breaking

input/regression/spanner-after-line-breaking.ly [new file with mode: 0644]
lily/hairpin.cc
lily/include/hairpin.hh
lily/include/spanner.hh
lily/line-spanner.cc
lily/spanner.cc
python/convertrules.py
scm/define-grobs.scm

diff --git a/input/regression/spanner-after-line-breaking.ly b/input/regression/spanner-after-line-breaking.ly
new file mode 100644 (file)
index 0000000..dd5a1ed
--- /dev/null
@@ -0,0 +1,36 @@
+\version "2.13.1"
+
+\header {
+texidoc = "The visibility of left-broken line spanners and hairpins
+which end on the first note (i.e., span no time between bounds) is
+controlled by the callback @code{ly:spanner::kill-zero-spanned-time}.
+"
+}
+
+\paper { ragged-right = ##t }
+
+\relative c' {
+  \override TextSpanner #'bound-details =
+    #'((left
+        (Y . 0)
+        (padding . 0.25)
+        (attach-dir . -1)
+        (text . "L"))
+       (right
+        (Y . 0)
+        (padding . 0.25)
+        (text . "R"))
+       (left-broken
+        (padding . 5)
+        (text . #f))
+       (right-broken
+        (text . #f)))
+  c1\startTextSpan\< \break
+  \override Hairpin #'to-barline = ##f
+  \override Hairpin #'after-line-breaking = ##f
+  c2\stopTextSpan\!
+  \override TextSpanner #'after-line-breaking =
+    #ly:spanner::kill-zero-spanned-time
+  c\startTextSpan\< \break
+  c1\!\stopTextSpan
+}
index 249c50206a4803f0f10252521b898318596f6efa..bb4fec084bb66c10c64a2ea724731a9285294448 100644 (file)
 #include "note-column.hh"
 #include "warn.hh"
 
-MAKE_SCHEME_CALLBACK (Hairpin, after_line_breaking, 1);
-SCM
-Hairpin::after_line_breaking (SCM smob)
-{
-  Spanner *me = dynamic_cast<Spanner *> (unsmob_grob (smob));
-  consider_suicide (me);
-
-  return SCM_UNSPECIFIED;
-}
-
 MAKE_SCHEME_CALLBACK (Hairpin, height, 1);
 SCM
 Hairpin::height (SCM smob)
@@ -52,38 +42,12 @@ Hairpin::pure_height (SCM smob, SCM, SCM)
   return ly_interval2scm (Interval (-height, height));
 }
 
-void
-Hairpin::consider_suicide (Spanner*me)
-{
-  Drul_array<bool> broken;
-  Drul_array<Item *> bounds;
-  Direction d = LEFT;
-  do
-    {
-      bounds[d] = me->get_bound (d);
-      broken[d] = bounds[d]->break_status_dir () != CENTER;
-    }
-  while (flip (&d) != LEFT);
-
-  if (broken[LEFT]
-      && ly_is_equal (bounds[RIGHT]->get_column ()->get_property ("when"),
-                     bounds[LEFT]->get_property ("when")))
-    me->suicide ();
-}
-
 MAKE_SCHEME_CALLBACK (Hairpin, print, 1);
-
 SCM
 Hairpin::print (SCM smob)
 {
-  Spanner *me = dynamic_cast<Spanner *> (unsmob_grob (smob));
+  Spanner *me = unsmob_spanner (smob);
 
-  if (Spanner *orig = dynamic_cast<Spanner*> (me->original ()))
-    {
-      for (vsize i = 0; i < orig->broken_intos_.size (); i++)
-       Hairpin::consider_suicide (orig->broken_intos_[i]);
-    }
-  
   SCM s = me->get_property ("grow-direction");
   if (!is_direction (s))
     {
index 5ce62aaba318bb4062bec6a8dbd21a8ecbdff8e2..c4a5300de53a25c90431dac27b166bffa6a23ad9 100644 (file)
@@ -18,8 +18,6 @@ public:
   DECLARE_SCHEME_CALLBACK (print, (SCM));
   DECLARE_SCHEME_CALLBACK (height, (SCM));
   DECLARE_SCHEME_CALLBACK (pure_height, (SCM, SCM, SCM));
-  DECLARE_SCHEME_CALLBACK (after_line_breaking, (SCM));
-  static void consider_suicide (Spanner*);
   DECLARE_GROB_INTERFACE();
 };
 
index 24176326d3084e22f013a0b46fc49045e33c68a5..57dcb9271eab238fab161bb6362e97efde704a1f 100644 (file)
@@ -36,6 +36,7 @@ class Spanner : public Grob
 public:
   DECLARE_SCHEME_CALLBACK (set_spacing_rods, (SCM));
   DECLARE_SCHEME_CALLBACK (bounds_width, (SCM));
+  DECLARE_SCHEME_CALLBACK (kill_zero_spanned_time, (SCM));
 
   vector<Spanner*> broken_intos_;
 
index b19151987f012dd9c046be13d1a54b3b73806bc3..2e6eb1b8512d3cbae56320a1b563cf45d2da975f 100644 (file)
@@ -13,7 +13,6 @@
 #include "item.hh"
 #include "lily-proto.hh"
 #include "line-interface.hh"
-#include "moment.hh"
 #include "output-def.hh"
 #include "pointer-group-interface.hh"
 #include "spanner.hh"
@@ -26,7 +25,6 @@ class Line_spanner
 {
 public:
   DECLARE_SCHEME_CALLBACK (print, (SCM));
-  DECLARE_SCHEME_CALLBACK (after_line_breaking, (SCM));
   DECLARE_SCHEME_CALLBACK (calc_left_bound_info, (SCM));
   DECLARE_SCHEME_CALLBACK (calc_left_bound_info_and_text, (SCM));
   DECLARE_SCHEME_CALLBACK (calc_right_bound_info, (SCM));
@@ -212,28 +210,8 @@ Line_spanner::print (SCM smob)
 {
   Spanner *me = dynamic_cast<Spanner *> (unsmob_grob (smob));
 
-  Interval_t<Moment> moments = me->spanned_time ();
-  /*
-    We remove the line at the start of the line.  For piano voice
-    indicators, it makes no sense to have them at the start of the
-    line.
-
-    I'm not sure what the official rules for glissandi are, but
-    usually the 2nd note of the glissando is "exact", so when playing
-    from the start of the line, there is no need to glide.
-
-    From a typographical p.o.v. this makes sense, since the amount of
-    space left of a note at the start of a line is very small.
-
-    --hwn.
-
-  */
-  if (moments.length () == Moment (0,0))
-    return SCM_EOL;
-  
   Drul_array<SCM> bounds (me->get_property ("left-bound-info"),
                          me->get_property ("right-bound-info"));
-
   
   Grob *commonx = me->get_bound (LEFT)->common_refpoint (me->get_bound (RIGHT), X_AXIS);
   commonx = me->common_refpoint (commonx, X_AXIS);
index 8533bc72fcbd1392b74aceb48e47085d770b3f53..12346042df772cbb88f0b4380470ba0a1fe14391 100644 (file)
@@ -6,15 +6,14 @@
   (c) 1996--2009 Han-Wen Nienhuys <hanwen@xs4all.nl>
 */
 
-#include "pointer-group-interface.hh"
 #include "libc-extension.hh"
-#include "paper-column.hh"
+#include "moment.hh"
 #include "paper-column.hh"
 #include "paper-score.hh"
+#include "pointer-group-interface.hh"
 #include "stencil.hh"
 #include "system.hh"
 #include "warn.hh"
-#include "moment.hh"
 
 Grob *
 Spanner::clone () const
@@ -78,9 +77,7 @@ Spanner::do_break_processing ()
       for (int a = X_AXIS; a < NO_AXES; a++)
        {
          if (Spanner *parent = dynamic_cast<Spanner *> (get_parent ((Axis)a)))
-           {
-             parent_rank_slice.intersect (parent->spanned_rank_interval ());
-           }
+           parent_rank_slice.intersect (parent->spanned_rank_interval ());
        }
   
       for (vsize i = 1; i < break_points.size (); i++)
@@ -118,7 +115,6 @@ Spanner::do_break_processing ()
          span->set_bound (RIGHT, bounds[RIGHT]);
 
          if (!bounds[LEFT]->get_system ()
-
              || !bounds[RIGHT]->get_system ()
              || bounds[LEFT]->get_system () != bounds[RIGHT]->get_system ())
            {
@@ -178,7 +174,7 @@ Spanner::spanned_time () const
 Item *
 Spanner::get_bound (Direction d) const
 {
-  return spanned_drul_ [d];
+  return spanned_drul_[d];
 }
 
 /*
@@ -209,7 +205,6 @@ Spanner::set_bound (Direction d, Grob *s)
 
     [maybe we should try keeping all columns alive?, and perhaps
     inherit position from their (non-)musical brother]
-
   */
   if (dynamic_cast<Paper_column *> (i))
     Pointer_group_interface::add_grob (i, ly_symbol2scm ("bounded-by-me"), this);
@@ -219,14 +214,13 @@ Spanner::Spanner (SCM s)
   : Grob (s)
 {
   break_index_ = 0;
-  spanned_drul_[LEFT] = 0;
-  spanned_drul_[RIGHT] = 0;
+  spanned_drul_.set (0, 0);
 }
 
 Spanner::Spanner (Spanner const &s)
   : Grob (s)
 {
-  spanned_drul_[LEFT] = spanned_drul_[RIGHT] = 0;
+  spanned_drul_.set (0, 0);
 }
 
 Real
@@ -254,7 +248,7 @@ Spanner::get_system () const
 Grob *
 Spanner::find_broken_piece (System *l) const
 {
-  vsize idx = binary_search (broken_intos_, (Spanner *)l, Spanner::less);
+  vsize idx = binary_search (broken_intos_, (Spanner *) l, Spanner::less);
   if (idx != VPOS)
     return broken_intos_ [idx];
   return 0;
@@ -412,7 +406,6 @@ Spanner::bounds_width (SCM grob)
 {
   Spanner *me = unsmob_spanner (grob);
 
-
   Grob *common = me->get_bound (LEFT)->common_refpoint (me->get_bound (RIGHT), X_AXIS);
 
   Interval w (me->get_bound (LEFT)->relative_coordinate (common, X_AXIS),
@@ -423,6 +416,33 @@ Spanner::bounds_width (SCM grob)
   return ly_interval2scm (w);
 }
 
+MAKE_SCHEME_CALLBACK (Spanner, kill_zero_spanned_time, 1);
+SCM
+Spanner::kill_zero_spanned_time (SCM grob)
+{
+  Spanner *me = unsmob_spanner (grob);
+  Interval_t<Moment> moments = me->spanned_time ();
+  /*
+    Remove the line or hairpin at the start of the line.  For
+    piano voice indicators, it makes no sense to have them at
+    the start of the line.
+
+    I'm not sure what the official rules for glissandi are, but
+    usually the 2nd note of the glissando is "exact", so when playing
+    from the start of the line, there is no need to glide.
+
+    From a typographical p.o.v. this makes sense, since the amount of
+    space left of a note at the start of a line is very small.
+
+    --hwn.
+
+  */
+  if (moments.length () == Moment (0, 0))
+    me->suicide ();
+
+  return SCM_UNSPECIFIED;
+}
+
 ADD_INTERFACE (Spanner,
               "Some objects are horizontally spanned between objects.  For"
               " example, slurs, beams, ties, etc.  These grobs form a subtype"
index 72479a952f27d98de986e7ab573aaf87d40630c8..0016b97970303a37e83e87f90f65ecbdff570dd6 100644 (file)
@@ -2891,12 +2891,14 @@ longer in reversed order.\n"))
     return str
 
 @rule ((2, 13, 1),
-       _ ("\\bar \".\" now produces a thick barline"))
+       _ ("\\bar \".\" now produces a thick barline\n\
+ly:hairpin::after-line-breaking -> ly:spanner::kill-zero-spanned-time"))
 def conv(str):
     if re.search(r'\\bar\s*"."', str):
         stderr_write ("\n")
         stderr_write (NOT_SMART % _("\\bar \".\" now produces a thick barline.\n"))
         stderr_write (UPDATE_MANUALLY)
+    str = re.sub (r'ly:hairpin::after-line-breaking', r'ly:spanner::kill-zero-spanned-time', str)
     return str
 
 # Guidelines to write rules (please keep this at the end of this file)
index 97f36809b893f296b2c06bf05c0eb0890e5e163a..f8945f99ba98044186fc35b39763304f3df4fe89 100644 (file)
                                   (padding . 1.5)
                                      ))
                          ))
+       (after-line-breaking . ,ly:spanner::kill-zero-spanned-time)
        (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)
      . (
        (stencil . ,ly:hairpin::print)
        (springs-and-rods . ,ly:spanner::set-spacing-rods)
-       (after-line-breaking . ,ly:hairpin::after-line-breaking)
+       (after-line-breaking . ,ly:spanner::kill-zero-spanned-time)
        (grow-direction . ,hairpin::calc-grow-direction)
        (circled-tip . #f)
        (to-barline . #t)
                          ))
        
        (stencil . ,ly:line-spanner::print)
-
+       (after-line-breaking . ,ly:spanner::kill-zero-spanned-time)
        (style . trill)
        (staff-padding . 1.0)
        (padding . 0.5)
                                   (padding . 1.5)
                                      ))
                          ))
+       (after-line-breaking . ,ly:spanner::kill-zero-spanned-time)
        (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)