lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Changing the size of the arpeggio's arrow


From: Thomas Morley
Subject: Re: Changing the size of the arpeggio's arrow
Date: Wed, 22 Apr 2020 09:49:06 +0200

Am Mi., 22. Apr. 2020 um 01:57 Uhr schrieb Paolo Prete <address@hidden>:
>
> Hello.
>
> The following code uses a (very, very, very helpful) function that Harm wrote 
> some months ago.
> Unfortunately, it causes a compiler's error if  the size of the arrow is too 
> big (in the following snippet the error is obtained when the size (my-scale) 
> is >= 2).
> Harm (or anyone else), please can you fix it if possible?
> Many thanks,
>
> Best,
> P
>
> %%%%%%%%%%%%%%%%%%%%%%%%%%%%
> \version "2.19.84"
>
> biggerArrow =
> #(define-music-function (scale)(number?)
> "Returns an override for @code{Arpeggio.stencil}, with arrow-heads scaled by
> @var{scale}"
> #{
>   \override Arpeggio.stencil =
>   #(lambda (grob)
>     (let* ((arp-dir (ly:grob-property grob 'arpeggio-direction)))
>       ;; If 'arpeggio-direction is unset use default-stencil
>       (if (null? arp-dir)
>           (ly:arpeggio::print grob)
>           (let* ((arrow-glyph
>                    (format #f
>                      "scripts.arpeggio.arrow.~a1"
>                      (if (negative? arp-dir) "M" "")))
>                  (font (ly:grob-default-font grob))
>                  (arrow-head-stil (ly:font-get-glyph font arrow-glyph))
>                  (arrow (ly:stencil-scale arrow-head-stil scale scale))
>                  (arrow-y-ext (ly:stencil-extent arrow Y))
>                  (arrow-x-ext (ly:stencil-extent arrow X))
>                  (arrow-width (interval-length arrow-x-ext))
>                  (pos (ly:grob-property grob 'positions)))
>
>             ;; 'positions modified to reflect the height of the arrow-head
>             (ly:grob-set-property! grob 'positions
>               (if (positive? arp-dir)
>                   (cons (car pos) (- (cdr pos) arrow-width))
>                   (cons (+ (car pos) arrow-width) (cdr pos))))
>
>             ;; unset 'arpeggio-direction to get the default trill-line stencil
>             (ly:grob-set-property! grob 'arpeggio-direction '())
>
>             (let* ((stil (ly:arpeggio::print grob))
>                    (stil-y-ext (ly:stencil-extent stil Y))
>                    (stil-x-ext (ly:stencil-extent stil X))
>                    (stil-width (interval-length stil-x-ext))
>                    ;; A scaled arrow-head will be slightly off, find the value
>                    ;; to compensate for x-axis, before adding it to the
>                    ;; arpeggio-line
>                    (scale-compensate-x (/ (- stil-width arrow-width) 2))
>                    (new-stil
>                      (ly:stencil-add
>                        (ly:stencil-translate
>                          arrow
>                          (cons
>                            scale-compensate-x
>                            (if (negative? arp-dir)
>                                ;; For a down pointing arrow, it's top will be 
> at
>                                ;; arpeggio-line-bottom, move by it's height to
>                                ;; let the arrow-basis match with the 
> line-bottom
>                                (- (car stil-y-ext)
>                                   (interval-length arrow-y-ext))
>                                (cdr stil-y-ext))))
>                        stil)))
>
>                ;; We need to adjust 'X-extent to reflect the enlarged arrow,
>                ;; in order to avoid spacing issues
>                (ly:grob-set-property! grob 'X-extent
>                  (interval-widen
>                    (ly:arpeggio::width grob)
>                    (* scale-compensate-x -2)))
>
>                ;; Do we need to resize the stencil? For now commented
>                ;(ly:make-stencil
>                ;  (ly:stencil-expr new-stil)
>                ;  (interval-widen stil-x-ext (* scale-compensate-x -2))
>                ;  (ly:stencil-extent new-stil Y))
>                new-stil
>                )))))
> #})
>
> %% enlarged
> my-scale = 1.5
>
> {
>   \arpeggioArrowUp
>   \biggerArrow \my-scale
>   <c' e' g'>\arpeggio
> }

Hi Paolo,

this function was the example of my talk at the Music Engraving
Conference in Salzburg this January.
While preparing the talk I cured some glitches in the original
function above. Reworked code below.
Though, the visual outcome is bad for scaling values > 2, because the
"tip" of the arrow-head, meant to join the arpeggio-element, becomes
too large and sticks out.
Would be better to create a new arrow-head, via markup-command or else.
In any case, it looks strange to have a very huge arrow-head sitting
on a default-sized trill-like arpeggio-line, imho.

Anyway, here the Salzburg-code:

scaleArpeggioArrow =
#(define-music-function (scale)(number?)
#{
  \override Arpeggio.stencil =
  #(lambda (grob)
    (let ((arp-dir (ly:grob-property grob 'arpeggio-direction)))
      (if (null? arp-dir)
          (ly:arpeggio::print grob)
          (let* ((arrow-glyph
                   (format #f
                     "scripts.arpeggio.arrow.~a1"
                     (if (negative? arp-dir)
                         "M"
                         "")))
                 (font (ly:grob-default-font grob))
                 (arrow-head-stil (ly:font-get-glyph font arrow-glyph))
                 (scaled-arrow (ly:stencil-scale arrow-head-stil scale scale))
                 (arrow-y-ext (ly:stencil-extent scaled-arrow Y))
                 (arrow-height (interval-length arrow-y-ext))
                 (arrow-x-ext (ly:stencil-extent scaled-arrow X))
                 (arrow-width (interval-length arrow-x-ext))
                 (positions (ly:grob-property grob 'positions)))

      (ly:grob-set-property! grob 'arpeggio-direction '())

      (ly:grob-set-property! grob 'positions
        (if (positive? arp-dir)
            (cons (car positions) (1- (cdr positions)))
            (cons (1+ (car positions)) (cdr positions))))

      (let* ((arpeggio-stil (ly:arpeggio::print grob))
             (arpeggio-stil-y-ext (ly:stencil-extent arpeggio-stil Y))
             (arpeggio-stil-x-ext (ly:stencil-extent arpeggio-stil X))
             (arpeggio-width (interval-length arpeggio-stil-x-ext))
             (increased-width (- arrow-width arpeggio-width)))

        (ly:grob-set-property! grob 'X-extent
          (interval-widen
            (ly:arpeggio::width grob)
            increased-width))

        (ly:stencil-add
          (ly:stencil-translate
            scaled-arrow
            (cons
              (/ increased-width -2)
              (if (negative? arp-dir)
                  (- (car arpeggio-stil-y-ext) arrow-height)
                  (cdr arpeggio-stil-y-ext))))
          arpeggio-stil))))))
#})

Cheers,
  Harm



reply via email to

[Prev in Thread] Current Thread [Next in Thread]