Hello, Joe!

> In case it wasn't clear from what I said before, engravers in lilypond
> don't do the actual layout. Instead, they build the grobs and set up
> the connections between them. Most of the layout is done in callback
> functions.

Yes, I realize it now.  Your suggestion to create a new stem worked
fine.  I can get the relative coordinates of themes on different staves.

The attached file shows where I am now.  There are many minor issues,
and I hope I can solve most of them, but I'll certainly appreciate help.

I'm getting a message "Weird stem", and I don't see how to avoid it.
Perhaps I should create a totally new grob with a unique name, such as
StemSpan.  Is that possible?  What would be needed?

How do I make the new stem start at the same point as the original
one.  I tried this:

(set! (ly:grob-property stem 'axes) (list X))

I don't understand how it works.  Not setting axes leads to:

programming error: axes should be nonempty

Maybe I should use some other parent for the new stem?

The new stems are offset horizontally on purpose to see where they
are.  But the vertical position is wrong and I don't see how to fix it.

I'll appreciate if you have a look at the code.

-- 
Regards,
Pavel Roskin
\version "2.14.2"

#(define (grobParentByInterface grob intf axis)
   (if (memq intf (ly:grob-interfaces grob))
       grob
       (grobParentByInterface (ly:grob-parent grob axis) intf axis)))

#(define (extent-combine extents)
   (if (pair? (cdr extents))
       (interval-union (car extents) (extent-combine (cdr extents)))
       (car extents)))

#(define (crossStaffLength grob)
   (let* ((papercolumn (grobParentByInterface grob 'paper-column-interface X))
          (elementarray (ly:grob-object papercolumn 'elements))
          (yref (ly:grob-common-refpoint-of-array grob elementarray Y))
          (elements (ly:grob-object grob 'spanned-stems))
          (extents (map (lambda (x) (ly:grob-extent x yref Y)) elements))
          (foo (ly:message "extents: ~a" extents))
          (maxextent (extent-combine extents))
          (foo (ly:message "maxextent: ~a" maxextent))
          (length (- (car maxextent) (cdr maxextent))))
     length))

#(define (stemSpanStencil grob)
   (let* ((length (crossStaffLength grob)))
     (make-filled-box-stencil '(0.2 . 0.4) (cons 0 length))))

#(define (reparentStems ctx stems trans)
   (if (and (pair? stems) (pair? (cdr stems)))
       (let* ((stem (car stems))
              (parent (ly:grob-parent stem Y))
              (new-stem (ly:engraver-make-grob trans 'Stem '())))
         (ly:message "stems: ~a" stems)
         (ly:message "new-stem: ~a" new-stem)
         (set! (ly:grob-property stem 'axes) (list X))
         (ly:axis-group-interface::add-element stem new-stem)
         (set! (ly:grob-object new-stem 'spanned-stems) stems)
         (set! (ly:grob-object new-stem 'Y-offset) 5)
         (set! (ly:grob-property new-stem 'stencil) stemSpanStencil)
         (set! (ly:grob-property new-stem 'length) crossStaffLength))))

#(define (Cross_staff_stem_engraver ctx)
  (let ((stems '()))

    `((acknowledgers
       (stem-interface
        . ,(lambda (trans grob source)
             (set! stems (cons grob stems)))))

      (process-acknowledged
       . ,(lambda (trans)
             (reparentStems ctx stems trans) (set! stems '()))))))

\layout {
  \context {
    \PianoStaff
    \consists #Cross_staff_stem_engraver
  }
}

\new PianoStaff <<
  \new Staff { \stemUp g' a' b' c'' }
  \new Staff { \stemUp f' e' <f' d'> r }
>>
_______________________________________________
lilypond-devel mailing list
lilypond-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-devel

Reply via email to