Hallo Harm,
mein gelöstes Problem hat eine ungelöste Variante:
Ich hoffe, du kannst aus meiner Darstellung erkennen, worum es geht.
Die Glissandi sind anders verteilt und sollen alle ins Leere reichen.
Ich habe versucht, das schöne Beispiel anzupassen, aber irgendwas ist im Weg...
Kannst du nochmal helfen?
Gruß und Dank
Christa
\version "2.18.2"
#(define-markup-command (bar-line layout props strg)(string?)
#:properties ((font-size 0)
(add-height 0))
(define (string->string-list str)
"Convert a string into a list of strings with length 1.
@code{"aBc"} will be converted to @code{("a" "B" "c")}.
An empty string will be converted to a list containing @code{""}."
(if (and (string? str)
(not (zero? (string-length str))))
(map (lambda (s)
(string s))
(string->list str))
(list "")))
(define (make-bar-line thickness height fontsize blot-diameter)
"Draw a simple bar line."
(ly:round-filled-box
(cons 0 (* (magstep font-size) thickness))
(interval-widen (cons 0 (+ add-height height)) (magstep font-size))
blot-diameter))
(define (make-colon-bar-line height fontsize)
(let* ((font
(ly:paper-get-font layout
(cons '((font-encoding . fetaMusic)) props)))
(dot (ly:font-get-glyph font "dots.dot")))
(ly:stencil-add
dot
(ly:stencil-translate-axis
dot
(magstep (+ (/ add-height 2) font-size))
Y))))
(define (make-bracket-bar-line height fontsize dir thick-bar )
"Draw a bracket-style bar line. If @var{dir} is set to @code{LEFT}, the
opening bracket will be drawn, for @code{RIGHT} we get the
closing bracket."
(let* ((font
(ly:paper-get-font layout
(cons '((font-encoding . fetaMusic)) props)))
(brackettips-up (ly:font-get-glyph font "brackettips.up"))
(brackettips-down (ly:font-get-glyph font "brackettips.down"))
;; the x-extent of the brackettips must not be taken into account
;; for bar line constructs like "[|:", so we set new bounds:
(tip-up-stil
(ly:make-stencil
(ly:stencil-expr brackettips-up)
(cons 0 0)
(ly:stencil-extent brackettips-up Y)))
(tip-down-stil
(ly:make-stencil
(ly:stencil-expr brackettips-down)
(cons 0 0)
(ly:stencil-extent brackettips-down Y)))
(stencil
(ly:stencil-add
thick-bar
(ly:stencil-translate-axis
tip-up-stil
(+ (/ (+ add-height height) 2) (magstep fontsize) )
Y)
(ly:stencil-translate-axis
tip-down-stil
(* -1 (+ (/ (+ add-height height) 2) (magstep fontsize) ))
Y))))
(if (eq? dir LEFT)
stencil
(ly:stencil-scale stencil -1 1))))
(define (make-brace-bar-line height fontsize)
(let* ((new-height (max (* add-height height) 12))
(font
(ly:paper-get-font layout
(cons '((font-encoding . fetaBraces)
(font-name . #f))
props)))
(glyph-count (1- (ly:otf-glyph-count font)))
(scale (ly:output-def-lookup layout 'output-scale))
(scaled-size (+ add-height (magstep fontsize) (/ (ly:pt new-height) scale)))
(glyph
(lambda (n)
(ly:font-get-glyph
font
(string-append "brace" (number->string n)))))
(get-y-from-brace
(lambda (brace)
(interval-length
(ly:stencil-extent (glyph brace) Y))))
(find-brace
(binary-search 0 glyph-count get-y-from-brace scaled-size))
(glyph-found (glyph find-brace)))
(if (or (null? (ly:stencil-expr glyph-found))
(< scaled-size
(interval-length (ly:stencil-extent (glyph 0) Y)))
(> scaled-size
(interval-length (ly:stencil-extent (glyph glyph-count) Y))))
(begin
(ly:warning (_ "no brace found for point size ~S ") new-height)
(ly:warning (_ "defaulting to ~S pt")
(/ (* scale (interval-length (ly:stencil-extent glyph-found Y)))
(ly:pt 10)))))
glyph-found))
(let* ((line-thickness (ly:output-def-lookup layout 'line-thickness))
(size (ly:output-def-lookup layout 'text-font-size 12))
;; Numerical values taken from the IR
(thin-thickness (* line-thickness 1.9))
(kern (* line-thickness 3.0))
(thick-thickness (* line-thickness 6.0))
(blot (ly:output-def-lookup layout 'blot-diameter))
;; Not sure about the numerical value, found it by try and error.
(thin-bar-line
(ly:stencil-aligned-to
(make-bar-line thin-thickness (/ size 9) font-size blot)
Y CENTER))
(thick-bar-line
(ly:stencil-aligned-to
(make-bar-line thick-thickness (/ size 9) font-size blot)
Y CENTER))
(colon-bar-line
(ly:stencil-aligned-to
(make-colon-bar-line (/ size 9) font-size)
Y CENTER))
(bracket-left-bar-line
(ly:stencil-aligned-to
(make-bracket-bar-line (/ size 9) font-size -1 thick-bar-line)
Y CENTER))
(bracket-right-bar-line
(ly:stencil-aligned-to
(make-bracket-bar-line (/ size 9) font-size 1 thick-bar-line)
Y CENTER))
(brace-left-bar-line
(ly:stencil-aligned-to
(make-brace-bar-line (/ size 9) font-size)
Y CENTER))
(strg-list (string->string-list strg))
(find-bar-line-proc
(lambda (x) (cond ((string=? ":" x) colon-bar-line)
((string=? "|" x) thin-bar-line)
((string=? "." x) thick-bar-line)
((string=? "[" x) bracket-left-bar-line)
((string=? "]" x) bracket-right-bar-line)
((string=? "{" x) brace-left-bar-line)
(else empty-stencil))))
(bar-line-stils
(remove ly:stencil-empty? (map find-bar-line-proc strg-list)))
(stil
(stack-stencils X
RIGHT
(* (magstep font-size) kern)
bar-line-stils))
(stil-y-length (interval-length (ly:stencil-extent stil Y))))
;; Hm, should the stencil-translate be hard-coded?
(ly:stencil-translate-axis
stil
(/ stil-y-length 4)
Y)))
#(define get-grob-name
(lambda (x) (if (ly:grob? x) (assq-ref (ly:grob-property x 'meta) 'name))))
#(define (get-grob-most-left-relative-coordinate ref-point)
(lambda (grob)
(cond
((eq? (get-grob-name grob) 'NoteColumn)
(let* ((note-heads-array (ly:grob-object grob 'note-heads))
(note-heads-grobs
(if (not (null? note-heads-array))
(ly:grob-array->list note-heads-array)
'()))
(note-heads-refpoints
(map
(lambda (nh)
(ly:grob-relative-coordinate nh ref-point X))
note-heads-grobs))
(sorted-note-heads-refpoints (sort note-heads-refpoints <)))
(if (not (null? sorted-note-heads-refpoints))
(car sorted-note-heads-refpoints))))
((eq? (get-grob-name grob) 'AccidentalPlacement)
(let* ((acc-list (ly:grob-object grob 'accidental-grobs))
(acc-refpoints
(map
(lambda (acc)
(ly:grob-relative-coordinate (cadr acc) ref-point X))
acc-list))
(sorted-acc-refpoints (sort acc-refpoints <)))
(if (not (null? sorted-acc-refpoints))
(car sorted-acc-refpoints))))
(else
(if (ly:grob? grob)
(ly:grob-relative-coordinate grob ref-point X))))))
#(define* (duration-line #:optional (equal-start? #f))
(lambda (grob)
(let* ((line-thickness (ly:staff-symbol-line-thickness grob))
(staff-space (ly:staff-symbol-staff-space grob))
(refp (ly:grob-system grob))
(note-head? (lambda (x) (eq? (get-grob-name x) 'NoteHead)))
(half-gliss-thick (- (/ staff-space 2) line-thickness))
(thickness
;; (- half-gliss-thick 0.23) is my personal taste
;; If other value wanted, use common 'thickness override
(ly:grob-property grob 'thickness (- half-gliss-thick 0.23)))
(blot-diameter
(ly:output-def-lookup (ly:grob-layout grob) 'blot-diameter))
;;;; left NoteColumn
(left-Y (assoc-get 'Y (ly:grob-property grob 'left-bound-info)))
(left-bound (ly:spanner-bound grob LEFT))
(left-note-column (ly:grob-parent left-bound X))
(left-note-col-X-ext
(ly:grob-extent left-note-column left-note-column X))
(left-note-column-coord
(ly:grob-relative-coordinate left-note-column refp X))
;;;; DotColumn of left NoteColumn
(dot-column-left (ly:note-column-dot-column left-note-column))
(dot-column-left-X-extent
(if (ly:grob? dot-column-left)
(ly:grob-extent dot-column-left dot-column-left X)
'(0 . 0)))
;;;; right NoteColumn
(right-bound (ly:spanner-bound grob RIGHT))
(right-bound-info (ly:grob-property grob 'right-bound-info))
(right-note-column (ly:grob-parent right-bound X))
(most-left-note-head-coord
((get-grob-most-left-relative-coordinate refp) right-note-column))
;;;; AccidentalPlacement of right NoteColumn
(acc-placement (ly:note-column-accidentals right-note-column))
(most-left-note-acc-coord
((get-grob-most-left-relative-coordinate refp) acc-placement))
;;;; Arpeggio of right NoteColumn
(arpeggio (ly:grob-object right-note-column 'arpeggio))
(arpeggio-coord
(if (ly:grob? arpeggio)
(ly:grob-relative-coordinate arpeggio refp X)))
;;;; calculate most right left-bound coord
(most-right-left-bound-coord
(+ left-note-column-coord
(cdr left-note-col-X-ext)
(cdr dot-column-left-X-extent)))
;;;; catch most left right-bound coord
(right-bound-coords-lst
(list
arpeggio-coord
most-left-note-acc-coord
most-left-note-head-coord))
(cleared-right-bound-coords-lst
(sort
(remove (lambda (x) (not (number? x))) right-bound-coords-lst)
<)))
;; create a flat glissando
(ly:grob-set-nested-property! grob '(right-bound-info Y) left-Y)
;; Let all glissandi start at the same vertical position
(if (and (note-head? left-bound) equal-start?)
(ly:grob-set-nested-property!
grob
'(left-bound-info X)
most-right-left-bound-coord))
;; Let all glissandi end at the same vertical position
(if (note-head? right-bound)
(ly:grob-set-nested-property!
grob
'(right-bound-info X)
(car cleared-right-bound-coords-lst)))
;; print new stencil
(let* ((stencil (ly:line-spanner::print grob))
(stencil-x-ext
(if (ly:stencil? stencil)
(ly:stencil-extent stencil X)
'(0 . 0)))
(new-stencil
(ly:round-filled-box
stencil-x-ext
(interval-widen (cons left-Y left-Y) thickness)
blot-diameter)))
new-stencil))))
gliss-length =
#(define-music-function (parser location lngth)(number?)
#{
\once \override Glissando.minimum-length = #lngth
#})
durationLine =
#(define-music-function (parser location equal-start? left-right-padding)
((boolean? #f) pair?)
#{
\override Glissando.stencil = #(duration-line equal-start?)
\override Glissando.bound-details.left.padding = #(car left-right-padding)
\override Glissando.bound-details.right.padding = #(cdr left-right-padding)
\override Glissando.bound-details.left-broken.padding = #0.5
\override Glissando.bound-details.right-broken.padding = #0.3
#})
durationLineSettings = {
\durationLine #'(-0.5 . 0.6)
%% For equal glissando-start with little padding use:
% \durationLine ##t #'(0.5 . 0.6)
%% other possible settings
%\override Glissando.thickness = #0.2
\override Glissando.breakable = ##t
\override Glissando.after-line-breaking = ##t
\override Glissando.springs-and-rods = #ly:spanner::set-spacing-rods
%% construction helpers, DELETE ME
%\override Glissando.layer = #20
%\override Glissando.color = #red
}
\relative c'' {
<g a>4
a8 [\gliss-length #6 g,\glissando \gliss-length #6 a'\glissando bes'\glissando \once \hideNotes bes]
<<\new Voice
\with {
\durationLine #'(-0.5 . -0.6)
}
\relative {
\cadenzaOn
\gliss-length #20
a'8[
\override NoteColumn.glissando-skip = ##t
g,\glissando
a'
bes'8]
\revert NoteColumn.glissando-skip
}
\new Voice
\with {
\override Stem.stencil = #point-stencil
\override Flag.stencil = #point-stencil
\durationLine #'(-0.5 . -0.6)
}
\relative {
\voiceTwo
s4
a'8\glissando
bes'8
}
\new Voice
\with {
\override Stem.stencil = #point-stencil
\override Flag.stencil = #point-stencil
\override NoteHead.stencil = #point-stencil
\durationLine #'(-0.5 . -0.6)
}
\relative {
\voiceThree
s4.
bes'8\glissando
}>>
}
\layout {
%\override NoteHead.duration-log = #2
\durationLineSettings
}