Positioning properties like 'Y-offset' are often linked to callback functions. When it is time to place a grob, LilyPond calls that function and stores the result in the property 'Y-offset', overwriting the link to the callback function.
Sometimes, most notably during line/page-breaking, we want *hypothetical* positions: where a grob would be placed *if* line-breaking put paper-columns 'start' through 'end' on one line. We do not want to evaluate every positioning callback, and even if we did there is no mechanism to restore all the links to the original callback functions, so we use estimates of positions through 'pure' functions. 'Pure' functions can look up a 'Y-offset' if it is data, but are not usually permitted to use a callback function. There are utility functions named maybe_pure_*() that look up properties that are data, but refrain from using most callbacks. The exceptions, callbacks that may be evaluated, were previously enumerated in lists; now they are simply those functions wrapped in an unpure-pure-container. When such a container is accessed through a 'pure' function-call, its return value is *not* stored in the grob property, so the link to the unpure-pure-container remains in place for the next use.
'pure' could now mean simply: this function promises to change no grob data. It may cache data, and perform output, and other procedural things, so long we retain our ability to evaluate more hypothetical layouts. The various functions labeled pure do not all keep this promise. (My struggle today was using pure_vertical_stencil_from_extents on a note-column, and finding it set the cross-staff beam position, through various paths.) The code before Mike's two big commits does not seem perfect in this regard either. 'cross-staff' marks grobs whose positioning (relative to their parent) depends on the spacing of staves on the page. These grobs have to be positioned last, after all grobs moving with their parent Staff are positioned relative to him, and staves are spaced. There is not an overarching mechanism to enforce this timing. Positions of cross-staff grobs could be estimated (and sometime are through 'pure' function calls) but they are most often ignored. All non-cross-staff grobs must find their positions while the positions of cross-staff grobs remain hypothetical. That is, any positions callbacks for a non-cross-staff grob may use only 'pure' functions to access properties of cross-staff grobs. _______________________________________________ lilypond-devel mailing list lilypond-devel@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-devel