Hello Jean,
thank you for the information about after-line-breaking and the timing of
skyline computing. Is there an equivalent property to trigger callback
after the skylines are calculated? I am trying to use (ly:stencil-add ...)
to add to the stencil of a notehead by drawing a line from one notehead in
one staff to a notehead in another staff. The notehead grob does not appear
to have a cross-staff property to delay stencil callback.

\language "english"
\version "2.23.14"

#(set-global-staff-size 12)

\score {
    <<
        \new Staff {
            \override NoteHead.cross-staff = ##t
            \once \override NoteHead.after-line-breaking = #(lambda (grob)
                    (let*
                        (
                           (sys (ly:grob-system grob))
                           (x-extent (ly:grob-extent grob sys X))
                           (y-extent (ly:grob-extent grob sys Y))
                        )
                        (display (list x-extent ))
                    )
                )
            c'1
            c'1
            c'1
            c'1
        }
        \new Staff {
            c'1
            c'1
            c'1
            c'1
        }
    >>
}

A larger example of the function (without a great deal of context) looks
like this:

interrupt = #(define-music-function (value) (number?)
  #{
      \once \override Staff.NoteHead.after-line-breaking = #(lambda (grob)
              (let* (
                (stem (ly:grob-object grob 'stem))
                (stem-dir (ly:grob-property stem 'direction))
                (stem-thickness (ly:grob-property stem 'thickness))
                (thickness (/ stem-thickness 10))
                (notecol (ly:grob-parent grob X))
                (meta  (assoc 'other-grob (ly:grob-property notecol 'meta)))
                (other (if meta
                              (cdr meta)
                              grob
                      ))
                (notehead-width (cdr (ly:grob-property grob 'X-extent)))
                (sys (ly:grob-system grob))
                (now-pos (ly:grob-extent grob sys X))
                (next-pos (ly:grob-extent other sys X))

                ;;the offending lines
                (now-pos-y (ly:grob-extent grob common Y))
                (next-pos-y (ly:grob-extent other common Y))

                (x-distance
                    (if (= stem-dir -1)
                      (+ (- (get-distance now-pos next-pos)
notehead-width ) (/ thickness 2))
                      (- (get-distance now-pos next-pos) (/ thickness 2))
                    ))
                (y-distance
                    (if (= stem-dir -1)
                      (+ (- (get-distance now-pos-y next-pos-y)
notehead-width ) (/ thickness 2))
                      (- (get-distance now-pos-y next-pos-y) (/ thickness 2))
                    ))

                ;; alternative which takes input number
                ;(ps-bracket
                ;    (if (= stem-dir -1)
                ;      (draw-ps-bracket x-distance notehead-width (-
value 0.5) thickness)
                ;      (draw-ps-bracket x-distance notehead-width
value thickness)
                ;    ))
                (ps-bracket
                    (if (= stem-dir -1)
                      (draw-ps-bracket x-distance notehead-width (-
y-distance 0.5) thickness)
                      (draw-ps-bracket x-distance notehead-width
y-distance thickness)
                    ))
                (ps-line (draw-ps-line x-distance notehead-width thickness))
                (grob-stencil (ly:grob-property grob 'stencil))
                (stencil-bracket (ly:stencil-add grob-stencil ps-bracket ))
                (stencil-line (ly:stencil-add grob-stencil ps-line))
                )
                (if (assoc 'is-lower-in-chord (ly:grob-property grob 'meta))
                        (ly:grob-set-property! grob 'stencil stencil-line)
                        (ly:grob-set-property! grob 'stencil stencil-bracket)
                  )
              )
            )
  #}
)

best,
greg

On Fri, Nov 18, 2022 at 5:22 AM Jean Abou Samra <j...@abou-samra.fr> wrote:

> Le 18/11/2022 à 00:29, Gregory Evans a écrit :
> >
> > Hi lilypond users,
> > I have a question about getting the Y position of a grob. I saw this
> > question has been asked previously but I could not find if it had been
> > answered. In the following example, an after-line-breaking function is
> > defined such that no change on the output should occur. The grob is
> > only queried with |(ly:grob-extent grob ... Y)| but this value is not
> > used. There is a difference in the vertical spacing between the staves
> > of the staff group based on whether this query is present or not. The
> > intention is to be able to query a grob for its Y position relative to
> > another grob in order to draw cross-staff spanners, where it is
> > necessary to calculate the distance between grobs not only on the X
> > axis but also on the Y axis. Here, the system is being used to
> > accurately get the X position, but using the system to get the Y
> > position triggers this spacing error but appears to return the correct
> > position before the spacing shift.
> >
>
>
> Because you are requesting it in after-line-breaking, which is earlier
> than LilyPond can provide it to you. At this point of the compilation,
> line breaking has just happened and page spacing (vertical spacing
> of systems and staves in each system) has not happened yet. The
> next thing LilyPond will do is computing the skylines (outlines) of the
> staves in order to be able to space them. If you ask for the offset of some
> staff relative to the system, it triggers these things prematurely
> while they're not ready.
>
> If you are writing a stencil callback, it is usually not OK to ask
> for the coordinate of a staff relative to the whole system, because
> it is a cyclic dependency: the coordinate depends on the spacing,
> which depends on the outline, which depends on the stencil of your
> grob. However, for cross-staff grobs, it is necessary, so if you
> are writing one, you need to \override YourGrob.cross-staff = ##t,
> and then LilyPond will completely ignore it for vertical spacing
> purposes, and the stencil callback will only be run at a later point
> where vertical spacing is already done.
>
>
> \version "2.23.81"
>
> \language "english"
>
> #(set-global-staff-size 12)
>
> \score {
>      <<
>          \new Staff {
>              %% See what weird things happen to the beam if it's not
>              %% properly marked cross-staff.
>              \override Beam.cross-staff = ##f
>              c'8[
>              \change Staff = down
>              c''8]
>          }
>          \new Staff = down {
>              s4
>          }
>      >>
> }
>
>
> Best,
> Jean
>
>
>
>

-- 
gregory rowland evans
http://www.gregoryrowlandevans.com
https://github.com/GregoryREvans
https://soundcloud.com/gregory-rowland-evans

Reply via email to