From: Han-Wen Nienhuys Date: Sat, 6 May 2006 00:19:09 +0000 (+0000) Subject: * lily/beam.cc: read grow-direction for feathered beaming. X-Git-Tag: release/2.9.4~9 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;ds=sidebyside;h=ec6440458dcf6f119af6b71f0a54b43b5e97ebf3;p=lilypond.git * lily/beam.cc: read grow-direction for feathered beaming. * Documentation/topdocs/NEWS.tely (Top): typo. --- diff --git a/ChangeLog b/ChangeLog index e5707c366a..8993bbb6e5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2006-05-06 Han-Wen Nienhuys + * lily/beam.cc: read grow-direction for feathered beaming. + * Documentation/topdocs/NEWS.tely (Top): typo. 2006-05-05 Han-Wen Nienhuys diff --git a/Documentation/topdocs/NEWS.tely b/Documentation/topdocs/NEWS.tely index 77eb3572b8..ce3d424b6b 100644 --- a/Documentation/topdocs/NEWS.tely +++ b/Documentation/topdocs/NEWS.tely @@ -66,13 +66,25 @@ which scares away people. @end ignore +@item +The beam printing code has been completely rewritten, and now includes +support for feathered beaming, + +@lilypond[ragged-right,fragment,relative=2] + \override Beam #'grow-direction = #LEFT + c16[ + c c c + c c c c ] +@end lilypond + +This feature was sponsored by Jamie Bullock. + @item The @code{\note} markup command now also accepts note head styles. @lilypond[ragged-right,fragment,relative=2] c4^\markup { \override #'(style . triangle) \note-by-number #2 #1 #1 = 100 - } @end lilypond diff --git a/input/regression/beam-feather.ly b/input/regression/beam-feather.ly new file mode 100644 index 0000000000..0d541df622 --- /dev/null +++ b/input/regression/beam-feather.ly @@ -0,0 +1,21 @@ +\header { + + texidoc = "Specifying @code{grow-direction} on a beam, will cause + feathered beaming. The @code{\featherDurations} function can be used + to adjust note durations." + +} + +\version "2.9.4" + +\paper { + ragged-right = ##t + indent = #0.0 +} + +\featherDurations #(ly:make-moment 3 4) \relative c'' { + \override Beam #'grow-direction = #LEFT + c16[ + c c c + c c c c ] +} diff --git a/lily/beam.cc b/lily/beam.cc index ea68186213..598b3c042c 100644 --- a/lily/beam.cc +++ b/lily/beam.cc @@ -446,23 +446,23 @@ Beam::print (SCM grob) Grob *commonx = 0; vector segments = get_beam_segments (me, &commonx); - Real x0, dx; + Interval span; if (visible_stem_count (me)) { - x0 = first_visible_stem (me)->relative_coordinate (commonx, X_AXIS); - dx = last_visible_stem (me)->relative_coordinate (commonx, X_AXIS) - x0; + span[LEFT] = first_visible_stem (me)->relative_coordinate (commonx, X_AXIS); + span[RIGHT] = last_visible_stem (me)->relative_coordinate (commonx, X_AXIS); } else { extract_grob_set (me, "stems", stems); - x0 = stems[0]->relative_coordinate (commonx, X_AXIS); - dx = stems.back ()->relative_coordinate (commonx, X_AXIS) - x0; + span[LEFT] = stems[0]->relative_coordinate (commonx, X_AXIS); + span[RIGHT] = stems.back ()->relative_coordinate (commonx, X_AXIS); } Real blot = me->layout ()->get_dimension (ly_symbol2scm ("blot-diameter")); SCM posns = me->get_property ("quantized-positions"); - Drul_array pos; + Interval pos; if (!is_number_pair (posns)) { programming_error ("no beam positions?"); @@ -474,19 +474,29 @@ Beam::print (SCM grob) scale_drul (&pos, Staff_symbol_referencer::staff_space (me)); Real dy = pos[RIGHT] - pos[LEFT]; - Real slope = (dy && dx) ? dy / dx : 0; + Real slope = (dy && span.length ()) ? dy / span.length () : 0; Real thick = get_thickness (me); Real beam_dy = get_beam_translation (me); - + Direction feather_dir = to_dir (me->get_property ("grow-direction")); + Stencil the_beam; for (vsize i = 0; i < segments.size (); i ++) { - Stencil b = Lookup::beam (slope, segments[i].horizontal_.length (), thick, blot); + Real local_slope = slope; + if (feather_dir) + { + local_slope += feather_dir * segments[i].vertical_count_ * beam_dy / span.length (); + } + + Stencil b = Lookup::beam (local_slope, segments[i].horizontal_.length (), thick, blot); b.translate_axis (segments[i].horizontal_[LEFT], X_AXIS); - b.translate_axis (slope * (segments[i].horizontal_[LEFT] - x0) + + b.translate_axis (local_slope + * (segments[i].horizontal_[LEFT] - span.linear_combination (feather_dir)) + + pos.linear_combination (feather_dir) + beam_dy * segments[i].vertical_count_, Y_AXIS); the_beam.add_stencil (b); } @@ -516,7 +526,6 @@ Beam::print (SCM grob) } #endif - the_beam.translate_axis (pos[LEFT], Y_AXIS); the_beam.translate_axis (-me->relative_coordinate (commonx, X_AXIS), X_AXIS); return the_beam.smobbed_copy (); } @@ -1439,6 +1448,7 @@ ADD_INTERFACE (Beam, "direction " "gap " "gap-count " + "grow-direction " "inspect-quants " "knee " "length-fraction " diff --git a/lily/music-sequence.cc b/lily/music-sequence.cc index 69b9343650..8a2915ad10 100644 --- a/lily/music-sequence.cc +++ b/lily/music-sequence.cc @@ -47,8 +47,13 @@ Music_sequence::maximum_length (SCM l) for (SCM s = l; scm_is_pair (s); s = scm_cdr (s)) { Music *m = unsmob_music (scm_car (s)); - Moment l = m->get_length (); - dur = max (dur, l); + if (!m) + programming_error ("Music sequence should have music elements"); + else + { + Moment l = m->get_length (); + dur = max (dur, l); + } } return dur; diff --git a/ly/music-functions-init.ly b/ly/music-functions-init.ly index 571bd79dd7..a7818e7e45 100644 --- a/ly/music-functions-init.ly +++ b/ly/music-functions-init.ly @@ -438,3 +438,30 @@ parenthesize = (set! (ly:music-property arg 'parenthesize) #t) arg) + + +featherDurations= +#(define-music-function (parser location factor argument) (ly:moment? ly:music?) + (let* + ((orig-duration (ly:music-length argument)) + (multiplier (ly:make-moment 1 1)) + ) + + (music-map + (lambda (mus) + (if (and (eq? (ly:music-property mus 'name) 'EventChord) + (< 0 (ly:moment-main-denominator (ly:music-length mus)))) + (begin + (ly:music-compress mus multiplier) + (set! multiplier (ly:moment-mul factor multiplier))) + ) + mus) + argument) + + (display (list (ly:music-length argument) orig-duration)) + (ly:music-compress + argument + (ly:moment-div orig-duration (ly:music-length argument))) + + argument)) +