[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: `TextSpanner` vs. `DynamicTextSpanner`
From: |
Jean Abou Samra |
Subject: |
Re: `TextSpanner` vs. `DynamicTextSpanner` |
Date: |
Fri, 4 Mar 2022 09:37:46 +0100 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.5.0 |
Le 04/03/2022 à 05:00, Werner LEMBERG a écrit :
Is there a similar auxiliary grob for `TextSpanner`?
No, since consecutive text spanners are not aligned vertically.
{
c'1\tweak bound-details.left.text "aaa" \startTextSpan
c'1\stopTextSpan\tweak bound-details.left.text "aaaa"\startTextSpan
c'1\stopTextSpan
}
Maybe they should be for tempo indications?
Sometimes, this would be very helpful, yes (see attached image from
the last scene of 'Wozzeck'). I guess a possible work-around would be
to (ab)use `DynamicTextSpanner` for that.
If you don't need dynamic spanners and tempo spanners at the
same time, that will work, yes. There is also this kind of code:
\version "2.22.1"
#(use-modules (ice-9 match)
(srfi srfi-26))
#(define (define-grob! grob-name grob-entry)
(set! all-grob-descriptions
(cons ((@@ (lily) completize-grob-entry)
(cons grob-name grob-entry))
all-grob-descriptions)))
#(define-grob!
'TempoLineSpanner
`((axes . (,Y))
(cross-staff . ,ly:side-position-interface::calc-cross-staff)
(direction . ,UP)
(minimum-space . 1.2)
(outside-staff-priority . 250)
(padding . 0.6)
(side-axis . ,Y)
(slur-padding . 0.3)
(staff-padding . 0.1)
(vertical-skylines .
,grob::always-vertical-skylines-from-element-stencils)
(X-extent . ,ly:axis-group-interface::width)
(Y-extent . ,axis-group-interface::height)
(Y-offset . ,side-position-interface::y-aligned-side)
(meta . ((class . Spanner)
(object-callbacks . ((pure-Y-common .
,ly:axis-group-interface::calc-pure-y-common)
(pure-relevant-grobs .
,ly:axis-group-interface::calc-pure-relevant-grobs)))
(interfaces . (axis-group-interface
outside-staff-interface
side-position-interface))))))
#(ly:add-interface 'text-spanner-interface "" '())
#(define (transform-in-path! alist path transformer)
(match path
(() (transformer alist))
((p . rest) (assq-set! alist p (transform-in-path! (assq-ref alist p)
rest
transformer)))))
#(set! all-grob-descriptions
(transform-in-path! all-grob-descriptions
'(TextSpanner meta interfaces)
(cute cons 'text-spanner-interface <>)))
#(define (Tempo_align_engraver context)
(let ((baseline #f)
(tempo-found #f)
(last-tempo-active #f)
(direction #f))
(define (end-baseline!)
(let ((column (ly:context-property context 'currentMusicalColumn)))
(ly:spanner-set-bound! baseline RIGHT column)
(if direction
(begin
(ly:grob-set-property! baseline 'direction direction)
(set! direction #f)))
(set! baseline #f)))
(make-engraver
(acknowledgers
((text-spanner-interface engraver grob source-engraver)
(let ((ev (event-cause grob)))
(if (ly:event-property ev 'is-tempo #f)
(let ((d (ly:event-property ev 'direction #f))
(column (ly:context-property context
'currentMusicalColumn)))
(set! tempo-found #t)
(set! last-tempo-active #t)
(ly:grob-set-property! grob 'Y-offset 0)
(ly:grob-set-nested-property! grob
'(bound-details right
attach-dir)
LEFT)
(cond
((not baseline)
(set! baseline (ly:engraver-make-grob engraver
'TempoLineSpanner grob))
(set! direction d)
(ly:spanner-set-bound! baseline LEFT column)
(ly:axis-group-interface::add-element baseline grob))
((and (not direction)
d)
;; Adding spanner with forced direction to baseline
;; without forced direction, forcing the direction
;; of the baseline.
(set! direction d)
(ly:grob-set-property! baseline 'direction direction)
(ly:axis-group-interface::add-element baseline grob))
((not direction)
;; No direction constraints
(ly:axis-group-interface::add-element baseline grob))
((or (not d)
(eqv? d direction))
;; Baseline has forced direction and the new tempo
spanner's
;; is compatible with it.
(ly:axis-group-interface::add-element baseline grob))
(else
;; Incompatible directions, break baseline.
(end-baseline!)
(set! baseline (ly:engraver-make-grob engraver
'TempoLineSpanner grob))
(set! direction d)
(ly:spanner-set-bound! baseline LEFT column)
(ly:axis-group-interface::add-element baseline
grob))))))))
(end-acknowledgers
((text-spanner-interface engraver grob source-engraver)
(let ((ev (event-cause grob)))
(if (ly:event-property ev 'is-tempo #f)
(set! last-tempo-active #f)))))
((stop-translation-timestep engraver)
(if (and baseline
(not last-tempo-active)
(not tempo-found))
(end-baseline!))
(set! tempo-found #f))
((finalize engraver)
(if baseline
(end-baseline!))))))
\layout {
\context {
\Global
\grobdescriptions #all-grob-descriptions
}
\context {
\Staff
\consists #Tempo_align_engraver
}
}
startTempoSpan =
#(define-event-function (text) (markup?)
#{ \withMusicProperty #'is-tempo ##t \tweak bound-details.left.text
#text \startTextSpan #})
stopTempoSpan = \stopTextSpan
%%
{
c'1\startTempoSpan "rit."
1\stopTempoSpan\startTempoSpan "acc."
1\stopTempoSpan
1_\startTempoSpan "rit."
1\stopTempoSpan \startTempoSpan "acc."
1\stopTempoSpan
1\startTempoSpan "rit."
1\stopTempoSpan_\startTempoSpan "acc."
1\stopTempoSpan
1_\startTempoSpan "rit."
1\stopTempoSpan_\startTempoSpan "acc."
1\stopTempoSpan
1^\startTempoSpan "rit."
1_\startTempoSpan "acc." \stopTempoSpan
1\stopTempoSpan
}
But then, it's more a matter of adding dedicated grobs since I don't
think it would be desirable to do this for all text spanners --
nothing prevents overlapping text spanners, unlike, say, overlapping
hairpins (in the same voice, that is), so I don't think there is a
reason to make them continuous.
What do you mean with 'dedicated grobs'?
A TempoSpanner and a TempoLineSpanner grob, created by \startTempo
and \stopTempo (or whatever names). See issue #3176.
Jean