diff options
author | Neil Puttock <n.puttock@gmail.com> | 2009-04-12 13:15:03 +0100 |
---|---|---|
committer | Neil Puttock <n.puttock@gmail.com> | 2009-04-15 20:34:41 +0100 |
commit | 131eeda0980667a4aeac1742f0f29961c16cb7e0 (patch) | |
tree | 9f9d4a22bc4a13b4c93e71d9e6513558b873346d | |
parent | 08d1196bc276543397ded663f8c6456f148e7bbb (diff) |
Move left-broken line-spanner check to callback.
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
-rw-r--r-- | input/regression/spanner-after-line-breaking.ly | 36 | ||||
-rw-r--r-- | lily/hairpin.cc | 38 | ||||
-rw-r--r-- | lily/include/hairpin.hh | 2 | ||||
-rw-r--r-- | lily/include/spanner.hh | 1 | ||||
-rw-r--r-- | lily/line-spanner.cc | 22 | ||||
-rw-r--r-- | lily/spanner.cc | 48 | ||||
-rw-r--r-- | python/convertrules.py | 4 | ||||
-rw-r--r-- | scm/define-grobs.scm | 6 |
8 files changed, 79 insertions, 78 deletions
diff --git a/input/regression/spanner-after-line-breaking.ly b/input/regression/spanner-after-line-breaking.ly new file mode 100644 index 0000000000..dd5a1edc76 --- /dev/null +++ b/input/regression/spanner-after-line-breaking.ly @@ -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 +} diff --git a/lily/hairpin.cc b/lily/hairpin.cc index 249c50206a..bb4fec084b 100644 --- a/lily/hairpin.cc +++ b/lily/hairpin.cc @@ -20,16 +20,6 @@ #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)) { diff --git a/lily/include/hairpin.hh b/lily/include/hairpin.hh index 5ce62aaba3..c4a5300de5 100644 --- a/lily/include/hairpin.hh +++ b/lily/include/hairpin.hh @@ -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(); }; diff --git a/lily/include/spanner.hh b/lily/include/spanner.hh index 24176326d3..57dcb9271e 100644 --- a/lily/include/spanner.hh +++ b/lily/include/spanner.hh @@ -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_; diff --git a/lily/line-spanner.cc b/lily/line-spanner.cc index b19151987f..2e6eb1b851 100644 --- a/lily/line-spanner.cc +++ b/lily/line-spanner.cc @@ -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); diff --git a/lily/spanner.cc b/lily/spanner.cc index 8533bc72fc..12346042df 100644 --- a/lily/spanner.cc +++ b/lily/spanner.cc @@ -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" diff --git a/python/convertrules.py b/python/convertrules.py index 72479a952f..0016b97970 100644 --- a/python/convertrules.py +++ b/python/convertrules.py @@ -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) diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm index 97f36809b8..f8945f99ba 100644 --- a/scm/define-grobs.scm +++ b/scm/define-grobs.scm @@ -756,6 +756,7 @@ (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) @@ -802,7 +803,7 @@ . ( (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) @@ -2012,7 +2013,7 @@ )) (stencil . ,ly:line-spanner::print) - + (after-line-breaking . ,ly:spanner::kill-zero-spanned-time) (style . trill) (staff-padding . 1.0) (padding . 0.5) @@ -2223,6 +2224,7 @@ (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) |