Hi everybody! Please test and comment, patch and examples attached.
Cheers, Knut
>From 456cee254df6133a611f108d2e9ca3671b01886f Mon Sep 17 00:00:00 2001 From: Knut Petersen <knut_peter...@t-online.de> Date: Mon, 12 Dec 2016 13:13:13 +0100 Subject: [PATCH] Enhance and clean lyric-extender.cc, add force-extender property Allow exteners to be forced even after single notes, automatically kill extenders that are not needed. Also removed some dead and unnecessary code. Signed-off-by: Knut Petersen <knut_peter...@t-online.de> --- lily/lyric-extender.cc | 39 +++++++++++++++++++-------------------- scm/define-grob-properties.scm | 4 ++++ scm/define-grobs.scm | 1 + 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/lily/lyric-extender.cc b/lily/lyric-extender.cc index 8afe2c5569..6fd70b7c7b 100644 --- a/lily/lyric-extender.cc +++ b/lily/lyric-extender.cc @@ -45,51 +45,49 @@ Lyric_extender::print (SCM smob) common = common->common_refpoint (me->get_system (), X_AXIS); Real sl = me->layout ()->get_dimension (ly_symbol2scm ("line-thickness")); + bool at_start_of_line = !left_edge->internal_has_interface (ly_symbol2scm ("lyric-syllable-interface")); + bool at_end_of_line = me->get_bound (RIGHT)->break_status_dir (); + bool force_extender = to_boolean (me->get_property ("force-extender")); extract_grob_set (me, "heads", heads); - if (!heads.size ()) + if (!heads.size () || (!force_extender && !at_start_of_line && !at_end_of_line && heads.size () < 2)) return SCM_EOL; common = common_refpoint_of_array (heads, common, X_AXIS); Real left_point = 0.0; - if (left_edge->internal_has_interface (ly_symbol2scm ("lyric-syllable-interface"))) + if (!at_start_of_line) left_point = left_edge->extent (common, X_AXIS)[RIGHT]; - else if (heads.size ()) - left_point = heads[0]->extent (common, X_AXIS)[LEFT]; else - left_point = left_edge->extent (common, X_AXIS)[RIGHT]; + left_point = heads[0]->extent (common, X_AXIS)[LEFT]; if (isinf (left_point)) return SCM_EOL; - /* It seems that short extenders are even lengthened to go past the - note head, but haven't found a pattern in it yet. --hwn 1/1/04 */ - SCM minlen = me->get_property ("minimum-length"); - Real right_point - = left_point + (robust_scm2double (minlen, 0)); - - right_point = min (right_point, me->get_system ()->get_bound (RIGHT)->relative_coordinate (common, X_AXIS)); - - if (heads.size ()) - right_point = max (right_point, heads.back ()->extent (common, X_AXIS)[RIGHT]); - Real h = sl * robust_scm2double (me->get_property ("thickness"), 0); Drul_array<Real> paddings (robust_scm2double (me->get_property ("left-padding"), h), robust_scm2double (me->get_property ("right-padding"), h)); + Real minlen = robust_scm2double (me->get_property ("minimum-length"), 0); + + Real right_point = heads.back ()->extent (common, X_AXIS)[RIGHT]; + + if (force_extender) + right_point = max (heads.back ()->extent (common, X_AXIS)[RIGHT], left_point + minlen); + if (right_text) right_point = min (right_point, (robust_relative_extent (right_text, common, X_AXIS)[LEFT] - paddings[RIGHT])); - /* run to end of line. */ - if (me->get_bound (RIGHT)->break_status_dir ()) + if (at_end_of_line) right_point = max (right_point, (robust_relative_extent (me->get_bound (RIGHT), common, X_AXIS)[LEFT] - paddings[RIGHT])); - left_point += paddings[LEFT]; + if (!at_start_of_line) + left_point += paddings[LEFT]; + Real w = right_point - left_point; - if (w < 1.5 * h) + if (w < minlen && !at_start_of_line && !at_end_of_line && !force_extender) return SCM_EOL; Stencil mol (Lookup::round_filled_box (Box (Interval (0, w), @@ -111,4 +109,5 @@ ADD_INTERFACE (Lyric_extender, "next " "right-padding " "thickness " + "force-extender " ); diff --git a/scm/define-grob-properties.scm b/scm/define-grob-properties.scm index c234792dd2..2ee4fe1ed6 100644 --- a/scm/define-grob-properties.scm +++ b/scm/define-grob-properties.scm @@ -330,6 +330,10 @@ allowed.") (footnote ,boolean? "Should this be a footnote or in-note?") (footnote-music ,ly:music? "Music creating a footnote.") (footnote-text ,markup? "A footnote for the grob.") + (force-extender ,boolean? "Force a lyric extender to be generated +if none would be generated otherwise and/or force it to be at least as +wide as indicated by minimum-width unless it would collide with the +next syllable.") (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 @rinternals{note-collision-interface}.") diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm index e36ea12bf2..b8abe332ac 100644 --- a/scm/define-grobs.scm +++ b/scm/define-grobs.scm @@ -1361,6 +1361,7 @@ (LyricExtender . ( + (force-extender . #f) (minimum-length . 1.5) (stencil . ,ly:lyric-extender::print) (thickness . 0.8) ; line-thickness -- 2.11.0
\version "2.19.53" \pointAndClickOff #(set-global-staff-size 17) \paper { ragged-right = ##f } \score { << \new Staff \relative c'' { \time 2/1 \repeat volta 2 { r4 g4 d'2. a4 bes2~ bes a2 g1~ } \alternative{ { g2 fis4 e fis1 d'1 c2 bes} { g\repeatTie fis4 e fis1 } } \bar "|." } \addlyrics { of Prin- ces all __ _ _ the __ _ flowâr. Who took a- %% volta 2 \once \override Lyrics.LyricExtender.force-extender = ##t \tweak self-alignment-X #-4 \markup \null __ the __ _ flowâr. } >> }
1006.pdf
Description: Adobe PDF document
\version "2.19.53" \paper { ragged-right = ##f } \pointAndClickOff #(set-global-staff-size 16) #(define (has-hyphen? event) (let* ((art (ly:music-property event 'articulations)) (is-hyphen? (lambda (ev) (eq? (ly:music-property ev 'name) 'HyphenEvent)))) (find is-hyphen? art))) #(define (add-extender! event) (ly:music-set-property! event 'articulations (append (ly:music-property event 'articulations) (list (make-music (quote ExtenderEvent))))) event) add-lyric-extenders = #(define-music-function (parser location lyrics) (ly:music?) (music-map (lambda (event) (if (and (eq? (ly:music-property event 'name) 'LyricEvent) (not (has-hyphen? event))) (add-extender! event)) event) lyrics)) \markup { "no extenders"} << { c''2. 4 ~ 4 2. ~ 2. 4 ~ \break 2. 4 2 ~ 2 \bar "|." } \addlyrics { foo -- bar foo -- bar foo -- bar } >> \markup { "automatic extenders"} << { c''2. 4 ~ 4 2. ~ 2. 4 ~ \break 2. 4 2 ~ 2 \bar "|." } \addlyrics { \add-lyric-extenders \repeat unfold 3 { foo -- bar }} >> << { c''2. 4 ~ 4 2. ~ 2. 4 ~ \break 2. 4 1 \bar "|." } \addlyrics { \add-lyric-extenders \repeat unfold 3 { foo -- bar }} >> \markup { "automatic extenders, extender on last note forced"} << { c''2. 4 ~ 4 2. ~ 2. 4 ~ \break 2. 4 1 \bar "|." } \addlyrics { \add-lyric-extenders { foo -- bar foo -- bar foo -- \override Lyrics.LyricExtender.minimum-length = #30 \override Lyrics.LyricExtender.force-extender = ##t bar }} >> \markup { "automatic extenders, minimum-length 8 "} << { c''1 2 ~ 2 2 4 ~ 4 4 8 ~ 8 8 16 ~ 16 4 1 \bar "|." } \addlyrics { \add-lyric-extenders { \override Lyrics.LyricExtender.minimum-length = #8 \repeat unfold 10 { foo -- bar }}} >> \markup { "automatic extenders, minimum-length 4 "} << { c''1 2 ~ 2 2 4 ~ 4 4 8 ~ 8 8 16 ~ 16 4 1 \bar "|." } \addlyrics { \add-lyric-extenders { \override Lyrics.LyricExtender.minimum-length = #4 \repeat unfold 10 { foo -- bar }}} >> \markup { "automatic extenders, minimum-length 2 "} << { c''1 2 ~ 2 2 4 ~ 4 4 8 ~ 8 8 16 ~ 16 4 1 \bar "|." } \addlyrics { \add-lyric-extenders { \override Lyrics.LyricExtender.minimum-length = #2 \repeat unfold 10 { foo -- bar }}} >> \markup { "automatic extenders, minimum-length 1 "} << { c''1 2 ~ 2 2 4 ~ 4 4 8 ~ 8 8 16 ~ 16 4 1 \bar "|." } \addlyrics { \add-lyric-extenders { \override Lyrics.LyricExtender.minimum-length = #1 \repeat unfold 10 { foo -- bar }}} >> \layout {}
lyrextest.pdf
Description: Adobe PDF document
_______________________________________________ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user