[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