\version "2.19.25" #(define (offset-subtract a b) (cons (- (car b) (car a)) (- (cdr b) (cdr a)))) #(define (offset-mul a b) (cons (* (car a) (car b)) (* (cdr a) (cdr b)))) #(define (offset-direction o) (cond ((and (inf? (car o)) (not (inf? (cdr o)))) (cons (if (> (car o) 0.0) 1.0 -1.0) 0.0)) ((inf? (cdr o)) (cons 0.0 (if (> (cdr o) 0.0) 1.0 -1.0))) ((and (= (car o) 0.0) (= (cdr o) 0.0)) o) (else (let ((len (sqrt (+ (* (car o)(car o)) (* (cdr o)(cdr o)))))) (cons (/ (car o) len) (/ (cdr o) len)))))) #(define (line-spanner::print grob) (let* (; Triggers simple-Y calculations (simple-y (and (eq? #t (ly:grob-property grob 'simple-Y)) (not (eq? #t (ly:grob-property grob 'cross-staff))))) (bound-info-L (ly:grob-property grob 'left-bound-info)) (bound-info-R (ly:grob-property grob 'right-bound-info)) (commonx (ly:grob-common-refpoint (ly:spanner-bound grob LEFT) (ly:spanner-bound grob RIGHT) X)) (commonx (ly:grob-common-refpoint grob commonx X)) (span-points (list (cons (assoc-get 'X bound-info-L 0.0) (assoc-get 'Y bound-info-L 0.0)) (cons (assoc-get 'X bound-info-R 0.0) (assoc-get 'Y bound-info-R 0.0)))) ; For scaling of 'padding and 'stencil-offset (magstep (expt 2 (/ (ly:grob-property grob 'font-size 0.0) 6))) (gaps (cons (assoc-get 'padding bound-info-L 0.0) (assoc-get 'padding bound-info-R 0.0))) ;; not supported in Scheme yet (arrows (cons (assoc-get 'arrow bound-info-L #f) (assoc-get 'arrow bound-info-R #f))) (stencils (cons (assoc-get 'stencil bound-info-L) ;; NB (assoc-get 'stencil bound-info-R))) ;; NB (commony (cons (assoc-get 'common-Y bound-info-L grob) (assoc-get 'common-Y bound-info-R grob))) (my-common-y (ly:grob-common-refpoint (car commony) (cdr commony) Y)) (span-points (if (not simple-y) (list (cons (caar span-points) (+ (cdar span-points) (ly:grob-relative-coordinate (car commony) my-common-y Y))) (cons (caadr span-points) (+ (cdadr span-points) (ly:grob-relative-coordinate (cdr commony) my-common-y Y)))) span-points)) (normalized-endpoints (ly:grob-property grob 'normalized-endpoints (cons 0 1))) (y-length (- (cdadr span-points) (cdar span-points))) (span-points (list (cons (caar span-points) (+ (cdar span-points) (* (car normalized-endpoints) y-length))) (cons (caadr span-points) (- (cdadr span-points) (* (- 1 (cdr normalized-endpoints)) y-length))))) (dz (offset-subtract (car span-points) (cadr span-points))) (dz-dir (offset-direction dz))) ;; Draw nothing if total padding is larger than line's length ;; (if (> (+ (car gaps) (cdr gaps)) ;; (sqrt (+ (* (car dz) (car dz)) (* (cdr dz) (cdr dz))))) ;; '() (let* ((line empty-stencil) ;; adjust endpoints for padding (span-points (list (coord-translate (car span-points) (coord-scale dz-dir (* (car gaps) magstep))) (coord-translate (cadr span-points) (coord-scale dz-dir (* -1 (cdr gaps) magstep))))) ;; Ugh. This is such a verbose way of translating the original. (left-stencil (if (car stencils) (ly:stencil-translate (car stencils) (car span-points)) #f)) (left-align (assoc-get 'stencil-align-dir-y bound-info-L #f)) (left-off (assoc-get 'stencil-offset bound-info-L #f)) (left-stencil (if (and left-stencil (number? left-align)) (ly:stencil-aligned-to left-stencil Y left-align) left-stencil)) (left-stencil (if (and left-stencil (number-pair? left-off)) (ly:stencil-translate left-stencil (offset-scale left-off magstep)) left-stencil)) (line (if left-stencil (ly:stencil-add line left-stencil) line)) (right-stencil (if (cdr stencils) (ly:stencil-translate (cdr stencils) (cadr span-points)) #f)) (right-align (assoc-get 'stencil-align-dir-y bound-info-R #f)) (right-off (assoc-get 'stencil-offset bound-info-R #f)) (right-stencil (if (and right-stencil (number? right-align)) (ly:stencil-aligned-to right-stencil Y right-align) right-stencil)) (right-stencil (if (and right-stencil (number-pair? right-off)) (ly:stencil-translate right-stencil (offset-scale right-off magstep)) right-stencil)) (line (if right-stencil (ly:stencil-add line right-stencil) line)) ;; Adjust endpoints to clear stencils (span-points (list (if (ly:stencil? (car stencils)) (coord-translate (car span-points) (offset-scale dz-dir (/ (cdr (ly:stencil-extent (car stencils) X)) (car dz-dir)))) (car span-points)) (if (ly:stencil? (cdr stencils)) (coord-translate (cadr span-points) (offset-scale dz-dir (/ (car (ly:stencil-extent (cdr stencils) X)) (car dz-dir)))) (cadr span-points)))) ;; for arrow (adjust (offset-scale dz-dir (ly:staff-symbol-staff-space grob))) (line-left (car span-points)) ; deal with arrow later (line-right (cadr span-points))) ; deal with arrow later ; (if (> (car line-right) (car line-left)) (set! line (ly:stencil-add line ;(make-line-stencil 0.0 (ly:line-interface::line grob (car line-left) (cdr line-left) (car line-right) (cdr line-right))));) (set! line (ly:stencil-translate line (cons (- (ly:grob-relative-coordinate grob commonx X)) (if simple-y 0.0 (- (ly:grob-relative-coordinate grob my-common-y Y)))))) line)))%) spanners = { s2*7 | s4 \override TextSpanner.bound-details.left.text = "(poco accel." \override TextSpanner.bound-details.right.text = "poco rit.)" \override TextSpanner.bound-details.right.padding = #6 <>\startTextSpan s4 | s2 | s4. <>\stopTextSpan s8 | s4 <>^\markup{a tempo} s4 | } notes = \relative c'' { \time 2/4 \repeat unfold 8 { a4 a4 } R2*7 r4 a~ | \repeat unfold 6 a2~ | a | } \layout { \context { \Score { \compressFullBarRests \override TextSpanner.stencil = #line-spanner::print \override TextSpanner.bound-details.left.padding = #0 \override TextSpanner.bound-details.left-broken.text = ##f \override TextSpanner.bound-details.right-broken.text = ##f } } } \score { << \new Staff << \spanners \notes % { s2*9 \break } >> >> }