[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Pedal cautionary continuations and other bracket decorations
From: |
Thomas Morley |
Subject: |
Re: Pedal cautionary continuations and other bracket decorations |
Date: |
Sun, 13 Nov 2016 10:36:42 +0100 |
2016-11-13 1:39 GMT+01:00 Andrew Bernard <address@hidden>:
> Hi Harm,
>
> When there is a sustain on event followed by a sustain off event, the label
> 1/2 ped should not occur - it's only for the start of the lines, and when
> these events occur very close together with short notes there would not be
> room.
>
> I cannot see a way of getting at the grob that represents the next bit after
> the ^ to and to not draw the text on it, for to my limited knowledge there
> appears to be no distinguishing property in the set of broken grob parts that
> can identify this.
>
> Andrew
Hi Andrew,
if I understand correctly the code below may do what you want.
Basically I go for the left bound of the PedalBracket and check
whether two of them are bounded there (which would then be an ending
and a starting spanner).
Please test thoroughly, I'm not entirely sure it is sufficient
already. More comments inline.
You are aware an unbroken PedalBracket is not affected by your code?
I didn't touch this behaviour, though.
\version "2.19.50"
#(define (make-arrow-path arrow-length arrowhead-height arrowhead-width)
"Arrow with triangular arrowhead."
(list
'moveto 0 0
'lineto arrow-length 0
'lineto arrow-length (/ arrowhead-width 2)
'lineto (+ arrow-length arrowhead-height) 0
'lineto arrow-length (- (/ arrowhead-width 2))
'lineto arrow-length 0
'closepath
))
pedalWithArrowsAndText =
\override Score.PianoPedalBracket.after-line-breaking =
#(lambda (grob)
;; function to modify the individual grob part
(define add-decorations
(lambda (g list-length)
(let* (
;; unpack the argument
(index (car g))
(grobber (cadr g))
(last (= index list-length))
;; Get the default-stencil and its x-dimension and x-length.
(stil (ly:piano-pedal-bracket::print grobber))
(stil-x-extent (ly:stencil-extent stil X))
(stil-x-length (interval-length stil-x-extent))
;; make arrow for the rhs end
(thickness 0.1)
(arrowhead-height 1.0)
(arrowhead-width 1.0)
(arrow-length 1.0)
(arrow
(make-path-stencil
(make-arrow-path
arrow-length
arrowhead-height
arrowhead-width)
thickness 1 1 #t))
(new-stil (if (not last)
(ly:stencil-combine-at-edge stil X RIGHT arrow -2)
stil))
;; make text for the lhs end
(text-stil
(grob-interpret-markup grobber
(markup
#:line
(#:abs-fontsize
6
(#:sans
(#:upright
(#:whiteout (#:box (#:pad-markup 0.3 "½ ped")))))))))
;; get a list of spanners bounded by PianoPedalBrackets
;; left-bound, which is PaperColumn or NonMusicalPaperColumn
(left-bound-spanners
(ly:grob-array->list
(ly:grob-object
(ly:spanner-bound grobber LEFT)
'bounded-by-me)))
;; filter left-bound-spanners for PianoPedalBrackets
(piano-pedal-brackets
(filter
(lambda (gr)
(grob::has-interface gr 'piano-pedal-bracket-interface))
left-bound-spanners))
;; delete identical PianoPedalBracket from piano-pedal-brackets
;; TODO `delete-duplicates' may be expensive, see guile-manual
;; find another method
(bounded-piano-brackets-per-column
(delete-duplicates piano-pedal-brackets))
;; only add text-stil, if current Column has not two
;; PianoPedalBrackets
;; TODO is this condition really sufficient?
(new-stil
(if (= (length bounded-piano-brackets-per-column) 2)
new-stil
(ly:stencil-stack new-stil X LEFT text-stil -6))))
(ly:grob-set-property! grobber 'stencil new-stil))))
(let* (
(stil (ly:piano-pedal-bracket::print grob))
(orig (ly:grob-original grob))
(pieces (if (ly:grob? orig)
(ly:spanner-broken-into orig)
'()))
(pieces-indexed-list (zip (iota (length pieces) 1) pieces))
(pieces-length (length pieces)))
;; We want arrows on all segments but the last, and text on all segments,
;; so we have to pass some notion of list index to the function doing the
;; decorating. Hence the ziplist combining grob segment and index in pairs.
(let loop ((x 1)
(count 0))
(if (< count pieces-length)
(begin
(add-decorations (list-ref pieces-indexed-list count) pieces-length)
(loop x (+ count 1))
)))
#t
))
%==========================================================================
treble = {
\clef treble
\time 4/4
c'4 c' c' c'
c' c' c' c'
}
bass = {
\clef bass
\time 4/4
c4
\pedalWithArrowsAndText
c\sustainOn c c
c c c c
\break
c c c c
\break
c c c^\sustainOff\sustainOn c
\break
c c c c
\break
c c\sustainOff\sustainOn c c
\break
c c c c
\break
c c c c\sustainOff
}
\score {
\new PianoStaff
<<
\new Staff = "treble" { \treble }
\new Staff = "bass" { \bass }
>>
\layout {
\context {
\Score
pedalSustainStyle = #'bracket
}
}
}
HTH,
Harm