From: James Lowe Date: Thu, 19 Jan 2012 21:31:13 +0000 (+0000) Subject: Doc: NR 5.5.5 Adv tweaks - Unpure-pure containers X-Git-Tag: release/2.15.28-1~7 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=1c8544f5052a64daf9c5895aff58c2d464fefd7e;p=lilypond.git Doc: NR 5.5.5 Adv tweaks - Unpure-pure containers Tracker issue 2040 Added information about Unpure-pure containers based on information from Mike Solo --- diff --git a/Documentation/notation/changing-defaults.itely b/Documentation/notation/changing-defaults.itely index 98163ce3e8..68aa8b8c49 100644 --- a/Documentation/notation/changing-defaults.itely +++ b/Documentation/notation/changing-defaults.itely @@ -3177,6 +3177,7 @@ appearance of the printed score. * Vertical grouping of grobs:: * Modifying stencils:: * Modifying shapes:: +* Unpure-pure containers:: @end menu @@ -3691,6 +3692,108 @@ required. Internals Reference: @rinternals{TieColumn}. +@cindex Scheme, pure containers +@cindex Scheme, unpure containers +@cindex pure containers, Scheme +@cindex unpure containers, Scheme +@cindex horizontal spacing, overriding + +@node Unpure-pure containers +@subsection Unpure-pure containers + +Unpure-pure containers are useful for overriding @emph{Y-axis} spacing +calculations - specifically @code{Y-offset} and @code{Y-extent} - with a +Scheme function instead of a literal (i.e. a number or pair). + +For certain grobs, the @code{Y-extent} is based on the @code{stencil} +property, overriding the stencil property of one of these will +require and additional @code{Y-extent} override with an unpure-pure +container. When a function overrides a @code{Y-offset} and/or +@code{Y-extent} it is assumed that this will trigger line breaking +calculations too early during compilation. So the function is not +evaluated at all (usually returning a value of @var{0} or +@var{'(0 . 0)}) which can result in collisions. A @q{pure} function +will not affect properties, objects or grob suicides and therefore will +always have its Y-axis-related evaluated correctly. + +Currently, there are about thirty functions that are already considered +@q{pure} and Unpure-pure containers are a way to set functions not on +this list as @q{pure}. The @q{pure} function is evaluated @emph{before} +any line-breaking and so the horizontal spacing can be adjusted +@q{in time}. The @q{unpure} function is then evaluated @emph{after} +line breaking. + +@warning{As it is difficult to always know which functions are on this +list we recommend that any @q{pure} functions you create do not use +@code{Beam} or @code{VerticalAlignment} grobs.} + +An unpure-pure container is constructed as follows; + +@code{(ly:make-unpure-pure-container f0 f1)} + +where @code{f0} is a function taking @var{n} arguments (@var{n >= 1}) +and the first argument must always be the grob. This is the function +that gives the actual result. @var{f1} is the function being labelled +as @q{pure} that takes @var{n + 2} arguments. Again, the first argument +must always still be the grob but the second and third are @q{start} +and @q{end} arguments. + +@var{start} and @var{end} are, for all intents and purposes, dummy +values that only matter for @code{Spanners} (i.e @code{Hairpin} or +@code{Beam}), that can return different height estimations based on a +starting and ending column. + +The rest are the other arguments to the first function (which +may be none if @var{n = 1}). + +The results of the second function are used as an approximation of the +value needed which is then used by the first function to get the real +value which is then used for fine-tuning much later during the spacing +process. + +@lilypond[verbatim,quote,ragged-right] +#(define (square-line-circle-space grob) +(let* ((pitch (ly:event-property (ly:grob-property grob 'cause) 'pitch)) + (notename (ly:pitch-notename pitch))) + (if (= 0 (modulo notename 2)) + (make-circle-stencil 0.5 0.0 #t) + (make-filled-box-stencil '(0 . 1.0) + '(-0.5 . 0.5))))) + +squareLineCircleSpace = { + \override NoteHead #'stencil = #square-line-circle-space +} + +smartSquareLineCircleSpace = { + \squareLineCircleSpace + \override NoteHead #'Y-extent = + #(ly:make-unpure-pure-container + ly:grob::stencil-height + (lambda (grob start end) (ly:grob::stencil-height grob))) +} + +\new Voice \with { \remove "Stem_engraver" } +\relative c'' { + \squareLineCircleSpace + cis4 ces cisis c + \smartSquareLineCircleSpace + cis4 ces cisis c +} +@end lilypond + +In the first measure, without the unpure-pure container, the spacing +engine does not know the width of the note head and lets it collide with +the accidentals. In the second measure, with unpure-pure containers, +the spacing engine knows the width of the note heads and avoids the +collision by lengthening the line accordingly. + +Usually for simple calculations nearly-identical functions for both the +@q{unpure} and @q{pure} parts can be used, by only changing the number +of arguments passed to, and the scope of, the function. + +@warning{If a function is labelled as @q{pure} and it turns out not to +be, the results can be unexpected.} + @node Using music functions @section Using music functions