\version "2.22.0" % "2.23.3" \paper { indent = 0 ragged-right = ##f line-width = 120 } \layout { \context { \Voice \override Glissando.layer = 1000 \override Glissando.bound-details.left.padding = 0 \override Glissando.bound-details.right.padding = 0 \override Glissando.breakable = ##t } } %% cross stensil #(define* (make-cross-stencil coords #:optional (thick 0.1) (sz 0.2)) (ly:stencil-add (make-line-stencil thick (- (car coords) sz) (- (cdr coords) sz) (+ (car coords) sz) (+ (cdr coords) sz)) (make-line-stencil thick (- (car coords) sz) (+ (cdr coords) sz) (+ (car coords) sz) (- (cdr coords) sz)))) %% glissando stencil #(define glissando-stencil-proc (lambda (grob) (ly:line-spanner::print grob))) %% get start/end points #(define gliss-data (lambda (grob) (let* ((simple-y? (and (ly:grob-property grob 'simple-Y) (not (ly:grob-property grob 'cross-staff)))) (lbi (ly:grob-property grob 'left-bound-info)) (rbi (ly:grob-property grob 'right-bound-info)) (common-x (ly:grob-common-refpoint grob (ly:grob-common-refpoint (ly:spanner-bound grob LEFT) (ly:spanner-bound grob RIGHT) X) X)) (scaling (magstep (ly:grob-property grob 'font-size 0))) (left-padding (ly:assoc-get 'padding lbi 0)) (left-stencil (ly:assoc-get 'stencil lbi #f)) (left-common-y (ly:assoc-get 'common-y lbi grob)) (right-padding (ly:assoc-get 'padding rbi 0)) (right-stencil (ly:assoc-get 'stencil rbi #f)) (right-common-y (ly:assoc-get 'common-y rbi grob)) (common-y (ly:grob-common-refpoint left-common-y right-common-y Y)) (normalized-endpoints (ly:grob-property grob 'normalized-endpoints '(0 . 1))) (span-left-x (ly:assoc-get 'X lbi 0)) (span-left-y (ly:assoc-get 'Y lbi 0)) (span-right-x (ly:assoc-get 'X rbi 0)) (span-right-y (ly:assoc-get 'Y rbi 0))) (if (not simple-y?) (begin (set! span-left-y (+ span-left-y (ly:grob-relative-coordinate left-common-y common-y Y))) (set! span-right-y (+ span-right-y (ly:grob-relative-coordinate right-common-y common-y Y))))) (let ((y-length (- span-right-y span-left-y))) (set! span-left-y (+ span-left-y (* (car normalized-endpoints) y-length))) (set! span-right-y (- span-right-y (* (- 1 (cdr normalized-endpoints)) y-length)))) (let* ((span-dx (- span-right-x span-left-x)) (span-dy (- span-right-y span-left-y)) (span-length (sqrt (+ (* span-dx span-dx) (* span-dy span-dy))))) (if (> (+ left-padding right-padding) span-length) '() (let* ((grad-dx (/ span-dx span-length)) (grad-dy (/ span-dy span-length))) (set! span-left-x (+ span-left-x (* left-padding scaling grad-dx))) (set! span-left-y (+ span-left-y (* left-padding scaling grad-dy))) (set! span-right-x (- span-right-x (* right-padding scaling grad-dx))) (set! span-right-y (- span-right-y (* right-padding scaling grad-dy))) (if (and (ly:stencil? left-stencil) (not (ly:stencil-empty? left-stencil))) (let ((factor (/ (cdr (ly:stencil-extent left-stencil X)) grad-dx))) (set! span-left-x (+ span-left-x (* factor grad-dx))) (set! span-left-y (+ span-left-y (* factor grad-dy))))) (if (and (ly:stencil? right-stencil) (not (ly:stencil-empty? right-stencil))) (let ((factor (/ (car (ly:stencil-extent right-stencil X)) grad-dx))) (set! span-right-x (+ span-right-x (* factor grad-dx))) (set! span-right-y (+ span-right-y (* factor grad-dy))))) (let* ((dx (ly:grob-relative-coordinate grob common-x X)) (dy (if simple-y? 0 (ly:grob-relative-coordinate grob common-y Y))) (system (ly:grob-system grob)) (dy-right (ly:grob-relative-coordinate grob system Y))) (set! span-left-x (- span-left-x dx)) (set! span-left-y (- span-left-y dy)) (set! span-right-x (- span-right-x dx)) (set! span-right-y (- span-right-y dy dy-right)) (cons (cons span-left-x span-left-y) (cons span-right-x span-right-y))))))))) #(define gliss-stencil-with-crosses (lambda (grob) (let* ((cross-coords (gliss-data grob))) (ly:stencil-add ;; left cross (stencil-with-color (make-cross-stencil (car cross-coords) 0.2 0.2) blue) ;; right cross (stencil-with-color (make-cross-stencil (cdr cross-coords) 0.2 0.2) red) ;; glissando (stencil-with-color (glissando-stencil-proc grob) magenta))))) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Examples %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Simple { \override Glissando.stencil = #gliss-stencil-with-crosses e''1\glissando s2 e' } %% Padding { \override Glissando.stencil = #gliss-stencil-with-crosses \override Glissando.bound-details.left.padding = #3 \override Glissando.bound-details.right.padding = #5 e''1\glissando s2 e' } %% Stencils { \override Glissando.stencil = #gliss-stencil-with-crosses \override Glissando.font-size = #3 \override Glissando.bound-details.left.text = \markup \vcenter \box \left-align "lorem" \override Glissando.bound-details.right.text = \markup \vcenter \box \right-align "ipsum" e''1\glissando s2 e' } %% cross-staff \new PianoStaff << \new Staff = "top" \with { \override VerticalAxisGroup.staff-staff-spacing.padding = 10 } \relative c'' { \override Glissando.stencil = #gliss-stencil-with-crosses c1\glissando \change Staff = "bottom" s2 g,,2 } \new Staff = "bottom" { \clef "bass" s1*2 } >> %% with line break { \override Glissando.stencil = #gliss-stencil-with-crosses e'''1\glissando \break s2 c'' }