-(define-public (stem::length val)
- (lambda (grob)
- (let* ((d (ly:grob-property grob 'direction))
- (ss (ly:staff-symbol-staff-space grob))
- (beg (ly:stem::calc-stem-begin-position grob))
- (y1 (* beg (* 0.5 ss)))
- (y2 (* ((if (eqv? d DOWN) - +) beg val) (* 0.5 ss))))
- (if (eqv? d DOWN)
- (cons y2 y1)
- (cons y1 y2)))))
-
+(define-public (stem::length grob)
+ (let* ((ss (ly:staff-symbol-staff-space grob))
+ (beg (ly:grob-property grob 'stem-begin-position))
+ (beam (ly:grob-object grob 'beam)))
+ (if (null? beam)
+ (abs (- (ly:stem::calc-stem-end-position grob) beg))
+ (begin
+ (ly:programming-error
+ "stem::length called but will not be used for beamed stem.")
+ 0.0))))
+
+(define-public (stem::pure-length grob beg end)
+ (let* ((ss (ly:staff-symbol-staff-space grob))
+ (beg (ly:grob-pure-property grob 'stem-begin-position 0 1000)))
+ (abs (- (ly:stem::pure-calc-stem-end-position grob 0 2147483646) beg))))
+
+(define (stem-stub::do-calculations grob)
+ (and (ly:grob-property (ly:grob-parent grob X) 'cross-staff)
+ (not (ly:grob-property (ly:grob-parent grob X) 'transparent))))
+
+(define-public (stem-stub::pure-height grob beg end)
+ (if (stem-stub::do-calculations grob)
+ '(0 . 0)
+ '(+inf.0 . -inf.0)))
+
+(define-public (stem-stub::width grob)
+ (if (stem-stub::do-calculations grob)
+ (grob::x-parent-width grob)
+ '(+inf.0 . -inf.0)))
+
+(define-public (stem-stub::extra-spacing-height grob)
+ (if (stem-stub::do-calculations grob)
+ (let* ((dad (ly:grob-parent grob X))
+ (refp (ly:grob-common-refpoint grob dad Y))
+ (stem_ph (ly:grob-pure-height dad refp 0 1000000))
+ (my_ph (ly:grob-pure-height grob refp 0 1000000))
+ ;; only account for distance if stem is on different staff than stub
+ (dist (if (grob::has-interface refp 'hara-kiri-group-spanner-interface)
+ 0
+ (- (car my_ph) (car stem_ph)))))
+ (if (interval-empty? (interval-intersection stem_ph my_ph)) #f (coord-translate stem_ph dist)))
+ #f))
+
+;; FIXME: NEED TO FIND A BETTER WAY TO HANDLE KIEVAN NOTATION