Am So., 24. Okt. 2021 um 16:35 Uhr schrieb Aaron Hill <lilyp...@hillvisions.com>: > > On 2021-10-24 6:22 am, Thomas Morley wrote: > > Though, how could I have found it myself? > > My lack of C++-knowledge hinders me to understand the "logic from > > Line_spanner::print". I usually learn things from looking at > > scheme-codings. > > Not sure it would have been clear without digging into the print > function. For reference, here are the relevant lines: > > //// > Interval normalized_endpoints = from_scm (get_property (me, > "normalized-endpoints"), Interval (0, 1)); > Real y_length = span_points[RIGHT][Y_AXIS] - > span_points[LEFT][Y_AXIS]; > > span_points[LEFT][Y_AXIS] += normalized_endpoints[LEFT] * y_length; > span_points[RIGHT][Y_AXIS] -= (1 - normalized_endpoints[RIGHT]) * > y_length; > ////
Yeah, I found them already, but I have even difficulties to decipher what's a varable, what's an operation, what's a procedure ... > > But there is none in our source using 'normalized-endpoints, apart > > from setting it in some grob-definitions. > > The description reads: "Represents left and right placement over the > > _total_ spanner, where the _width_ of the spanner is normalized > > between 0 and 1." > > I think the wording is misleading, at least "total" means the unbroken > > spanner for me, thus I never considered to look at it for broken > > spanners. > > The word "width" means the extent in X-axis direction, again no reason > > to look at it for extents in Y-axis. > > You are right that "width" is talking about the X extent, but "total" > does not just mean an unbroken spanner but the entire spanner, broken or > otherwise. Well, my first thought about it was different. Maybe I find a better wording, then I'll put up a patch. > The resulting normalized values are in essence percentages > of the total width if you were to lay each broken element end-to-end. > For example, if a spanner is broken into two parts of equal size, then > you should see normalized-endpoints as the intervals [0, 0.5] and [0.5, > 1]. > > > > P.S. > > While the Y-values are fixed now, I found some flaw, if left/right > > padding is not zero. At least for broken or cross-staff Glissando. > > I'll continue research..., unless someone has another hint? Meanwhile I found the culprit with non-zero paddings, see attached. > Yup, there's more code in Line_spanner::print that factors in the > padding values. It is perhaps harder to locate because the variable was > named "gaps". And it turns out there is more than just padding that > will affect your calculation. Try setting a stencil in either > bound-details, as that will also shorten the effective spanner line. > Arrows, however, seem to overlay on the line without changing its > length. > > Let me take a stab at converting the print routine to Scheme. Would be great !! > -- Aaron Hill Best, Harm
\version "2.23.3" \paper { indent = 0 ragged-right = ##f line-width = 120 } \layout { \context { \Voice \override Glissando.layer = 1000 \override Glissando.bound-details.left.padding = 15 \override Glissando.bound-details.right.padding = 15 \override Glissando.breakable = ##t } } %% cross stensil #(define* (make-cross-stencil coords #:optional (thick 0.1) (sz 0.2)) (ly:stencil-add (make-line-stencil thick (- (car coords) sz) (- (cdr coords) sz) (+ (car coords) sz) (+ (cdr coords) sz)) (make-line-stencil thick (- (car coords) sz) (+ (cdr coords) sz) (+ (car coords) sz) (- (cdr coords) sz)))) %% glissando stencil #(define glissando-stencil-proc (lambda (grob) (ly:line-spanner::print grob))) %% get start/end points #(define gliss-data (lambda (grob) (let* ((left-bound-info (ly:grob-property grob 'left-bound-info)) (Y-left (assoc-get 'Y left-bound-info)) (X-left (assoc-get 'X left-bound-info)) (left-padding (assoc-get 'padding left-bound-info)) (right-bound-info (ly:grob-property grob 'right-bound-info)) (Y-right (assoc-get 'Y right-bound-info)) (X-right (assoc-get 'X right-bound-info)) (right-padding (assoc-get 'padding right-bound-info)) (sys (ly:grob-system grob)) (line-thickness (ly:staff-symbol-line-thickness grob)) (grob-thickness (ly:grob-property grob 'thickness #f)) (thick (or grob-thickness line-thickness)) (grob-relative-coord (ly:grob-relative-coordinate grob sys X)) (current-y-coord (ly:grob-relative-coordinate grob sys Y)) (normalized-endpoints (ly:grob-property grob 'normalized-endpoints)) ;; Return the difference between highest and lowest Y (Y-length (- Y-right Y-left)) ;; For broken Glissando modify `Y-left' and `Y-right' with scaled ;; parts of `Y-length'. The scaling factors are taken from the pair ;; `normalized-endpoints', car for left, cdr for right. ;; For unbroken Glissandi `normalized-endpoints' defaults to '(0 . 1) ;; and actually unchanged `Y-left' and `Y-right' are used. (normal-Y-left (+ Y-left (* (car normalized-endpoints) Y-length))) (normal-Y-right (- Y-right (* (- 1 (cdr normalized-endpoints)) Y-length))) (gradient (/ (- (- normal-Y-right normal-Y-left current-y-coord)) (- (- X-left grob-relative-coord) (- X-right grob-relative-coord)))) ;; left/right-padding are values representing parts of the actual ;; line, i.e. not X, or Y-values but their magnitude ;; Thus we get the angel and calculate the x- and y-part as a pair, ;; then we use the part on the X-axis to find the needed coords (angle (ly:angle 1 gradient)) (left-padding-x (car (ly:directed angle left-padding))) (left-padding-y (* gradient left-padding-x)) (right-padding-x (car (ly:directed angle right-padding))) (right-padding-y (* gradient right-padding-x)) (start-coord (cons (- X-left grob-relative-coord (- left-padding-x) (/ thick 2)) (+ normal-Y-left left-padding-y))) (end-coord (cons (- X-right grob-relative-coord right-padding-x (- (/ thick 2))) (- normal-Y-right right-padding-y current-y-coord)))) (cons start-coord end-coord)))) #(define gliss-stencil-with-crosses (lambda (grob) (let* ((cross-coords (gliss-data grob))) (ly:stencil-add ;; left cross (stencil-with-color (make-cross-stencil (car cross-coords) 0.2 0.2) blue) ;; right cross (stencil-with-color (make-cross-stencil (cdr cross-coords) 0.2 0.2) red) ;; glissando (stencil-with-color (glissando-stencil-proc grob) green))))) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Examples %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Simple { \override Glissando.stencil = #gliss-stencil-with-crosses e''1\glissando s2 e' } %% cross-staff \new PianoStaff << \new Staff = "top" \with { \override VerticalAxisGroup.staff-staff-spacing.padding = 30 } \relative c'' { \override Glissando.stencil = #gliss-stencil-with-crosses c1\glissando \change Staff = "bottom" s2 g,,2 } \new Staff = "bottom" { \clef "bass" s1*2 } >> %% with line break { \override Glissando.stencil = #gliss-stencil-with-crosses e'''1\glissando \break s2 \once \override NoteColumn.glissando-skip = ##t c'' \break s2 b \break b1\glissando \break s2 \once \override NoteColumn.glissando-skip = ##t c'' \break s2 e''' }