lilypond-user
[Top][All Lists]
Advanced

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

Re: Flat flared hairpins


From: Thomas Morley
Subject: Re: Flat flared hairpins
Date: Wed, 2 Jan 2019 23:21:28 +0100

Am Mi., 2. Jan. 2019 um 01:26 Uhr schrieb Andrew Bernard
<address@hidden>:
>
> Hi Thomas,
>
> The correction works and all is good. Thanks so much.
>
> An interesting point I discovered. If you use \< for the hairpins, the LEFT, 
> RIGHT settings are correct. but if you use /< they are reversed - but still 
> work fine. A fascinating side effect of the code.

Well, it's coming from 'elbowed-hairpin'. There it's a feature, here
we have to fight against.
Below a code which drops 'elbowed-hairpin',

> [It did have me a bit confused for a while. And of course, in this usage, 
> there is no need for a distinction between \< and \<.]

The code will read whether cresc or decresc is used and place the
flares accordingly. Only in the case you want both flares, you need to
do
\override Hairpin.details.flare-position = #CENTER

Also, see Change-log, doc-string and exmples.

\version "2.19.82"

#(define flat-flared-hairpin
  (lambda (grob)
;; Change-log:
;; (1) Correct scaling of flare-height (for use with 'elbowed-hairpin')
;; (2) - Dropped usage of 'elbowed-hairpin', use 'make-connected-line' directly
;;       No scaling is needed any more
;;     - Look at 'grow-direction to choose flares for start or end
;;       Only for getting both flares 'details.flare-position' must be set.

"Is supposed to take a maybe broken Hairpin.
Looking at 'grow-direction, a crescendo gets an opening flare at the end, a
decrescendo gets a closing flare at start.
If details.flare-position is set 0 or CENTER flares are printed at
start and end.
Otherwise a flat line is printed.
The behaviour is determined looking at some sub-properties of 'details:
  - details.flare-position: default is #f
      Remark: can't look at 'grow-direction, because setting it zero causes an
              assertion failure.
  - details.flare-height: height of the flare, numerical value
      default is 1
      TODO: replace with Hairpin.height?
  - details.flare-width: width of the flare, numerical value
      default is 1"
    (let* ((orig (ly:grob-original grob))
           (broken-siblings (ly:spanner-broken-into orig))
           (siblings
             (if (pair? broken-siblings)
                 broken-siblings
                 (list grob)))
           (decresc? (eqv? (ly:grob-property grob 'grow-direction) LEFT))
           (details (ly:grob-property grob 'details))
           (flare-position
             (assoc-get 'flare-position details #f))
           (flare-height
             (assoc-get 'flare-height details 1))
           (flare-width
             (assoc-get 'flare-width details 1))
           (flare-left
             (lambda (g)
               (let* ((stil (ly:hairpin::print g))
                      (stil-x-ext (ly:stencil-extent stil X))
                      (x-start (car stil-x-ext))
                      (stil-y-ext (ly:stencil-extent stil Y))
                      (stil-x-length (interval-length stil-x-ext))
                      (stil-y-length (interval-length stil-y-ext)))
                 (if (and (or (eqv? flare-position 0) decresc?)
                          (equal? g (car siblings)))
                     (list
                       (cons x-start flare-height)
                       (cons (+ x-start flare-width) 0))
                     (list (cons x-start 0))))))
           (flare-right
             (lambda (g)
               (let* ((stil (ly:hairpin::print g))
                      (stil-x-ext (ly:stencil-extent stil X))
                      (x-start (car stil-x-ext))
                      (stil-y-ext (ly:stencil-extent stil Y))
                      (stil-x-length (interval-length stil-x-ext))
                      (stil-y-length (interval-length stil-y-ext)))
                 (if (and (or (eqv? flare-position 0) (not decresc?))
                          (equal? g (last siblings)))
                     (list
                       (cons (+ x-start (- stil-x-length flare-width)) 0)
                       (cons (+ x-start stil-x-length) flare-height))
                     (list (cons (+ x-start stil-x-length) 0))))))
           (points-list `(,@(flare-left grob) ,@(flare-right grob))))
      (ly:stencil-add
        (make-connected-line points-list grob)
        ;; TODO:
        ;;   Overlapping stencils, a problem?
        ;;   Would it be less expensive to draw the missing lines separately?
        (ly:stencil-scale (make-connected-line points-list grob) 1 -1)))))


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% EXAMPLES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\paper {
  ragged-right = ##f
  indent = 25
}

mus = { c'1\> \break cis' \break d' dis'\! }

musII = { c'1\< cis' d' dis'\! }

musIII = { c'1\< \break cis' \break d'\! }

\layout {
  \override Hairpin.stencil = #flat-flared-hairpin
  \override Hairpin.details.flare-height = 2 %% default is 1
  \override Hairpin.details.flare-width = 2 %% default is 1
  \override Hairpin.thickness = 2
  \override Hairpin.stencil =
    #(lambda (grob) (box-stencil (flat-flared-hairpin grob) 0 0))
}

{
  \set Staff.instrumentName = "TEST 1: decresc "
  c'1\> \break cis' \break d' dis'\!
}

{
  \set Staff.instrumentName = "TEST 2: both "
  \override Hairpin.details.flare-position = #CENTER
  c'1\> \break cis' \break d' dis'\!
}

{
  \set Staff.instrumentName = "TEST 3 cresc "
  c'1\< \break cis' \break d' dis'\!
}


{
  \set Staff.instrumentName = "TEST 4: both "
  \override Hairpin.details.flare-position = #CENTER
  c'1\> cis' d' dis'\!
}

{
  \set Staff.instrumentName = "TEST 5"
  \override Hairpin.to-barline = ##f
  \override Hairpin.after-line-breaking = ##t
  c'1\< \break cis' \break d'\!
}

{
  \override DynamicLineSpanner.staff-padding = 4
  \grace { c''32\< d'\! }
  d'1\> f'1 g' a'\!
}




Cheers,
  Harm



reply via email to

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