\version "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 = 15 \override Glissando.bound-details.right.padding = 15 \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* ((left-bound-info (ly:grob-property grob 'left-bound-info)) (Y-left (assoc-get 'Y left-bound-info)) (X-left (assoc-get 'X left-bound-info)) (left-padding (assoc-get 'padding left-bound-info)) (right-bound-info (ly:grob-property grob 'right-bound-info)) (Y-right (assoc-get 'Y right-bound-info)) (X-right (assoc-get 'X right-bound-info)) (right-padding (assoc-get 'padding right-bound-info)) (sys (ly:grob-system grob)) (line-thickness (ly:staff-symbol-line-thickness grob)) (grob-thickness (ly:grob-property grob 'thickness #f)) (thick (or grob-thickness line-thickness)) (grob-relative-coord (ly:grob-relative-coordinate grob sys X)) (current-y-coord (ly:grob-relative-coordinate grob sys Y)) (normalized-endpoints (ly:grob-property grob 'normalized-endpoints)) ;; Return the difference between highest and lowest Y (Y-length (- Y-right Y-left)) ;; For broken Glissando modify `Y-left' and `Y-right' with scaled ;; parts of `Y-length'. The scaling factors are taken from the pair ;; `normalized-endpoints', car for left, cdr for right. ;; For unbroken Glissandi `normalized-endpoints' defaults to '(0 . 1) ;; and actually unchanged `Y-left' and `Y-right' are used. (normal-Y-left (+ Y-left (* (car normalized-endpoints) Y-length))) (normal-Y-right (- Y-right (* (- 1 (cdr normalized-endpoints)) Y-length))) (gradient (/ (- (- normal-Y-right normal-Y-left current-y-coord)) (- (- X-left grob-relative-coord) (- X-right grob-relative-coord)))) ;; left/right-padding are values representing parts of the actual ;; line, i.e. not X, or Y-values but their magnitude ;; Thus we get the angel and calculate the x- and y-part as a pair, ;; then we use the part on the X-axis to find the needed coords (angle (ly:angle 1 gradient)) (left-padding-x (car (ly:directed angle left-padding))) (left-padding-y (* gradient left-padding-x)) (right-padding-x (car (ly:directed angle right-padding))) (right-padding-y (* gradient right-padding-x)) (start-coord (cons (- X-left grob-relative-coord (- left-padding-x) (/ thick 2)) (+ normal-Y-left left-padding-y))) (end-coord (cons (- X-right grob-relative-coord right-padding-x (- (/ thick 2))) (- normal-Y-right right-padding-y current-y-coord)))) (cons start-coord end-coord)))) #(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) green))))) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Examples %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Simple { \override Glissando.stencil = #gliss-stencil-with-crosses e''1\glissando s2 e' } %% cross-staff \new PianoStaff << \new Staff = "top" \with { \override VerticalAxisGroup.staff-staff-spacing.padding = 30 } \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 \once \override NoteColumn.glissando-skip = ##t c'' \break s2 b \break b1\glissando \break s2 \once \override NoteColumn.glissando-skip = ##t c'' \break s2 e''' }