Hi everybody! Please test and comment, patch and examples attached.
Cheers, Knut
>From 456cee254df6133a611f108d2e9ca3671b01886f Mon Sep 17 00:00:00 2001 From: Knut Petersen <[email protected]> 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 <[email protected]> --- 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 [email protected] https://lists.gnu.org/mailman/listinfo/lilypond-user
