values may also be specified.")
(self-alignment-Y ,number? "Like @code{self-alignment-X} but for
the Y@tie{}axis.")
+ (toward-stem-shift ,number? "Amount by which scripts are shifted
+toward the stem if their direction coincides with the stem direction.
+@code{0.0} means keep the default position (centered on the note head),
+@code{1.0} means centered on the stem. Interpolated values are possible.")
(shorten-pair ,number-pair? "The lengths to shorten a
text-spanner on both sides, for example a pedal bracket. Positive
values shorten the text-spanner, while negative values lengthen it.")
(define-public (script-interface::calc-x-offset grob)
(ly:grob-property grob 'positioning-done)
- (ly:self-alignment-interface::centered-on-x-parent grob))
+ (let* ((shift (ly:grob-property grob 'toward-stem-shift 0.0))
+ (note-head-location (ly:self-alignment-interface::centered-on-x-parent grob))
+ (note-head-grob (ly:grob-parent grob X))
+ (stem-grob (ly:grob-object note-head-grob 'stem)))
+ (+ note-head-location
+ ;; If the property 'toward-stem-shift is defined and the script has the
+ ;; same direction as the stem, move the script accordingly. Since scripts can
+ ;; also be over skips, we need to check whether the grob has a stem at all.
+ (if (ly:grob? stem-grob)
+ (let ((dir1 (ly:grob-property grob 'direction))
+ (dir2 (ly:grob-property stem-grob 'direction)))
+ (if (equal? dir1 dir2)
+ (let* ((common-refp (ly:grob-common-refpoint grob stem-grob X))
+ (stem-location (ly:grob-relative-coordinate stem-grob common-refp X)))
+ (* shift (- stem-location
+ note-head-location)))
+ 0.0))
+ 0.0))))
(side-relative-direction . -1)
(quantize-position . #t)
(avoid-slur . inside)
+ (toward-stem-shift . 0.5)
(padding . 0.20)
(script-priority . -100)))
("tenuto" .