Am So., 24. Okt. 2021 um 16:35 Uhr schrieb Aaron Hill
<[email protected]>:
>
> 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'''
}