Deutsches Lilypond Forum (Archiv)
Allgemein => Fragen zu Funktionen => Thema gestartet von: chf am Mittwoch, 16. September 2015, 18:12
-
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
}
-
Ich hoffe, du kannst aus meiner Darstellung erkennen, worum es geht.
Die Glissandi sind anders verteilt und sollen alle ins Leere reichen.
Ich kann leider nicht erkennen worum es Dir geht bzw was das Ziel sein soll.
Kannst Du einen scan oder auch nur ein Handy-Photo des Originals posten?
Oder mit einem Grafikprogramm einfügen was Dir vorschwebt und dieses Bild dann einstellen?
Gruß,
Harm
-
Hallo Harm,
sorry - es ist dasselbe wie in "Haltelinie die Zweite", nur anders...
Das Bildchen hilft Dir (und mir!) hoffentlich weiter.
Die Figur im Mittelpunkt ist nicht ganz die gleiche wie die gestern vermittelte, hier ist es durch den Doppelgriff am Ende noch etwas komplizierter, alles andere wiederholt sich.
Gruß
Christa
-
Hallo Christa,
ich habe den Eindruck, daß der Glissando-stencil-tweak mit Deinem Beispiel so ziemlich ausgereizt ist.
Ich habe extrem rumtricksen müssen mit mehreren Voices, graces, hideNotes und ignore-collision.
Es geht, ja, aber das ist auch das Beste was man drüber sagen kann.
Ich frage mich, ob das Ganze via Tie.stencil-tweak nicht auch machbar wäre, vielleicht sogar besser (immerhin gibts ja tieWaitForNote). Allerdings kann ich jetzt schon massive Probleme mit diesem Ansatz ermessen. Ich probiers mal, wenn ich mehr Zeit habe...
Aber hier Dein Beispiel:
\layout {
%\override NoteHead.duration-log = #2
\durationLineSettings
}
\new Staff <<
\cadenzaOn
\new Voice
\with {
% \override Stem.stencil = #point-stencil
% \override Flag.stencil = #point-stencil
\durationLine #'(0.5 . -0.6)
}
\relative c' {
fis8[ gis, fis'! \gliss-length #4 a]\glissando
\once \hideNotes
\grace a4
fis!8[ gis,! fis'! \gliss-length #4 <a e'>]\glissando
\once \hideNotes
\stemUp
\grace <a e'>4
s
}
\new Voice
\with {
\override Stem.stencil = #point-stencil
% \override Flag.stencil = #point-stencil
\durationLine #'(0.5 . -0.6)
}
\relative c' {
\voiceTwo
\override NoteColumn.ignore-collision = ##t
s4 fis4\glissando \once \hideNotes \grace fis4 s4 fis \glissando
\once \hideNotes
\grace fis4
s
}
\new Voice
\with {
\override Stem.stencil = #point-stencil
% \override Flag.stencil = #point-stencil
\durationLine #'(0.5 . -0.6)
}
\relative c' {
\voiceTwo
s8 gis4\glissando s8 \once \hideNotes \grace gis4 s8 gis4\glissando s8
\once \hideNotes
\grace gis4
s
}
>>
Der scheme-code ist unverändert, insoweit habe ich mir das erneute einfügen diesmal gespart.
HTH,
Harm
-
Hallo Harm,
hab Dank! Das sieht ja wunderbar aus. Mehr Varianten habe ich nicht...
Gute Nacht!