Hi,

in order to make stemmed glissandi work with cross-staff glissandi, I
made the experience calling Glissando.stencil and getting the needed
values from the stencil to calculate the real start/end-points and
gradient will cause bad results for cross-staff Glissando.
Thus I tried to calculate those values not calling stencil.

It works now for unbroken, not cross-staff and cross-staff Glissando.
Alas not for broken Glissando. Basically because the Y-values are not
updated for each broken part in 'left/right-bound-info.
line-spanner.cc seems to handle this problem, though my C++ is close
to zero, I am not able to understand what's done there and move it to
scheme.

Any hints?

My current coding so far is attached.
As a test it uses the start/end-points to add crosses to Glissando.

Thanks,
  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 = 0
    \override Glissando.bound-details.right.padding = 0
    \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))
           (gradient
             (/
                (- Y-left Y-right)
                (- (- X-left grob-relative-coord)
                   (- X-right grob-relative-coord))))
           (left-padding-y
             (* gradient left-padding))
           (right-padding-y
             (* gradient right-padding))
           (orig (ly:grob-original grob))
           (siblings (ly:spanner-broken-into orig))
           (vag (ly:grob-object grob 'axis-group-parent-Y))
           (start-coord
             (cons
               (- X-left grob-relative-coord (- left-padding) (/ thick 2))
               (+ Y-left left-padding-y)))
           (end-coord
             (cons
               (- X-right grob-relative-coord right-padding (- (/ thick 2)))
               (- 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 = 10
      }
      \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 c''
}

Attachment: start-end-gradient-03.pdf
Description: Adobe PDF document

Reply via email to