lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Finding the objects at the start of the current measure


From: Thomas Morley
Subject: Re: Finding the objects at the start of the current measure
Date: Tue, 26 Feb 2019 12:02:48 +0100

Am Mo., 25. Feb. 2019 um 13:14 Uhr schrieb Urs Liska <address@hidden>:
>
> Recently I managed (with considerable help from here) to write a function 
> that can a) center some arbitrary stuff in a measure and b) print markup 
> above/below that measure that pushes the surrounding barlines so the markup 
> fits in the measure. However, before I can make this nice function available 
> I have to resolve at least one further problem.
>
> The function works by
>
> - creating a markup stencil from the to-be-centered music
> - creating the actual markup stencils and measuring their width
> - inserting a MMR, setting its minimum-length to the determined width (plus 
> some padding)
> - replacing the MMR's stencil with the combined stencils created earlier.
>
> As can be seen in the attached image this works smoothly in regular cases 
> (first instance). However, it works *not* correctly when there is some stuff 
> like clefs, key or time signatures at the beginning of the measure. The 
> second and third instances in the image show cases where stuff of varying 
> width is at the beginning of the measure, and in both cases the measure is 
> not pushed wide enough. The same is true at the beginning of a system.
>
> So what I need to do is determine if there's anything at that beginning, 
> determine its width and calculate a value from there that I have to add to 
> the minimum-length override.
>
> I know that this is not linear. In the first instance (the 4/4 time sig) it 
> would probably be ok to simply add the time signature's width, but in the 
> other instance the to-be-added width is significantly less than the width of 
> the combined time and the key signatures. I recall having to deal with that 
> issue once, I think the calculation starts from a fixed width (2.0) and 
> interpolates that up to a certain width when things work "normal" again.
>
> First thing I need is to know: is it possible to know the width of these 
> elements in a before-line-breaking callback? I have serious doubts because at 
> that point we don't even know yet whether we're at a line break. However, in 
> later callbacks I can't set minimum-length anymore.
>
> If that is possible at all I'd need some help how to find the column where 
> all these objects may be or some property of the current measure or the 
> previous barline. From there I'd probably be able to get further on my own.
>
> Thanks
> Urs
>
> \version "2.19.82"
>
> \include "oll-core/package.ily"

Hi Urs,

because of my limited time I can't keep track what's going on oll.

Thus all your example code is limited to oll-users, I'd recommend to
break it doing to core-lilypond-functionality while asking here,
otherwise only those oll-users have a chance to compile your surely
nice code.

That said, I probably can imagine what the not-core-functions do ;)

Why not going for bound-padding instead of minimum-length.

Here a sketch:

foo =
    \override MultiMeasureRest.before-line-breaking =
    #(lambda (grob)
       (let* ((vag (ly:grob-parent grob Y)) ;; VerticalAxisGroup
              (vag-elts-array (ly:grob-object vag 'elements))
              (vag-elts-ls
                (if (ly:grob-array? vag-elts-array)
                    (ly:grob-array->list vag-elts-array)
                    '()))
              (mm-grobs
                (filter
                  (lambda (elt)
                    (and
                      (equal? (ly:grob-parent elt X) grob)
                      (grob::has-interface elt 'multi-measure-interface)))
                  vag-elts-ls)))

         (if (pair? mm-grobs)
             (let* ((mmr-stil-x-length
                      (interval-length
                        (ly:stencil-extent
                          (ly:multi-measure-rest::print grob) X)))
                    (mm-text-stil-x-lengths
                      (map
                        (lambda (mm)
                          (ly:stencil-extent
                            (grob-interpret-markup
                              mm
                              (ly:grob-property mm 'text))
                            X))
                        mm-grobs))
                    (max-text-x-length
                      (apply max (map cdr mm-text-stil-x-lengths)))
                    (half-x-diff
                      (/ (abs (- mmr-stil-x-length max-text-x-length)) 2)))
               (ly:grob-set-property! grob 'bound-padding half-x-diff)))))

{
    \foo
    R1
    \key bes \major
    R1

    \key b \major
    \time 16/16

    R1^"very very long"_"not short either"
    R^"very very very long"_"not really short either"
}



Cheers,
  Harm



reply via email to

[Prev in Thread] Current Thread [Next in Thread]