lilypond-user
[Top][All Lists]
Advanced

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

Re: Flat slurs


From: Abraham Lee
Subject: Re: Flat slurs
Date: Mon, 13 Feb 2017 15:49:46 -0700

On Mon, Feb 13, 2017 at 1:16 PM, Urs Liska <address@hidden> wrote:
Yes, I'd definitely like to see that. How did you manage to get the seamless "thick" line?

Ok. You asked for it... ;-)

I did it by completely redefining the stencil completely using a markup path. The path has a line thickness and a shape thickness, similar to how slurs are created. See below for full code and examples (works with 2.18.2 and newer, from my tests).

%<---------------------------------------------

\version "2.18.2"

#(define (general-flattened-curve points thickness line-thickness ratio)
  "The four points passed to this function are as follows:
   - p0: left-most real control point location (x,y)
   - p1: left-curve-width, left-curve-rise
   - p2: right-curve-width, right-curve-rise
   - p3: right-most real control point location (x,y)
   
   For Ties, p1 rise and p2 rise should be the same, as should p0y and p3y"
  (let* ((p0 (car points))
         (p1 (cadr points))
         (p2 (caddr points))
         (p3 (cadddr points))
         (halfthick (/ thickness 2))
         
         (p00x (car p0))
         (p33x (car p3))
         (p11x (+ p00x (car p1)))
         (p22x (- p33x (car p2)))
         (p10x (+ p00x (* (- p11x p00x) (expt (- 1 ratio) 2))))
         (p01x (+ p00x (* (- p10x p00x) ratio)))
         (p23x (- p33x (* (- p33x p22x) (expt (- 1 ratio) 2))))
         (p32x (+ p23x (* (- p33x p23x) (- 1 ratio))))
         (p34x p32x)
         (p43x p23x)
         (p44x p22x)
         (p55x p11x)
         (p50x p10x)
         (p05x p01x)
        
         (p00y (cdr p0))
         (p11y (- (cdr p1) halfthick))
         (p22y (- (cdr p2) halfthick))
         (p33y (cdr p3))
         (p10y p11y)
         (p23y p11y)
         (p01y (+ p00y (* (- p11y p00y) ratio)))
         (p32y (+ p33y (* (- p22y p33y) ratio)))
         (p44y (+ p22y thickness))
         (p55y (+ p11y thickness))
         (p43y p44y)
         (p34y (+ p33y (* (- p44y p33y) ratio)))
         (p05y (+ p00y (* (- p55y p00y) ratio)))
         (p50y p55y)
        )
    (markup 
      (#:override (cons 'filled #t) 
        (#:path line-thickness
          (list (list 'moveto p00x p00y)
                (list 'curveto p01x p01y p10x p10y p11x p11y)
                (list 'lineto p22x p22y)
                (list 'curveto p23x p23y p32x p32y p33x p33y)
                (list 'curveto p34x p34y p43x p43y p44x p44y)
                (list 'lineto p55x p55y)
                (list 'curveto p50x p50y p05x p05y p00x p00y)
                (list 'closepath)
          )
        )
      )
    )
  )
)

#(define ((flattened-slur start-y left-height left-width right-width right-height) grob)
  ;; outer let to trigger suicide
  (let ((stil (ly:slur::print grob)))
    (if (grob::is-live? grob)
        (let* ((layout (ly:grob-layout grob))
               (optical-thinner 0.8)
               (def-line-thickness (ly:output-def-lookup layout 'line-thickness))
               (line-thickness 
                 (* def-line-thickness (ly:grob-property grob 'line-thickness 0.8)))
               (thickness 
                 (* optical-thinner 
                   (* def-line-thickness (ly:grob-property grob 'thickness 1.2))))
               (ratio (ly:grob-property grob 'ratio))
               (dir (ly:grob-property grob 'direction))
               (xex (ly:stencil-extent stil X))
               (yex (ly:stencil-extent stil Y))
               (lenx (interval-length xex))
               (leny (interval-length yex))
               (lenratio (/ left-width (+ left-width right-width)))
               (1-lenratio (1- lenratio))
               (left-tip-width (min left-width (* lenx lenratio)))
               (right-tip-width (min right-width (* lenx (- 1 lenratio))))
               (left-tip-height (+ start-y left-height))
               (right-tip-height (- left-tip-height right-height))
               (xtrans (car xex))
               (ytrans (if (> dir 0)(car yex) (cdr yex)))
               (cpts (list 
                 (cons 0 (* dir start-y)) 
                 (cons left-tip-width (* dir left-tip-height)) 
                 (cons right-tip-width (* dir left-tip-height)) 
                 (cons lenx (* dir right-tip-height))))
               (newstil 
                 (grob-interpret-markup grob 
                   (general-flattened-curve cpts thickness line-thickness ratio)))
              )
              (ly:stencil-translate newstil (cons xtrans ytrans)))
        stil)))

#(define ((flattened-tie tip-width height) grob)
  ;; outer let to trigger suicide
  (let ((stil (ly:tie::print grob)))
    (if (grob::is-live? grob)
        (let* ((layout (ly:grob-layout grob))
               (optical-thinner 0.8)
               (def-line-thickness (ly:output-def-lookup layout 'line-thickness))
               (line-thickness 
                 (* def-line-thickness (ly:grob-property grob 'line-thickness 0.8)))
               (thickness 
                 (* optical-thinner 
                   (* def-line-thickness (ly:grob-property grob 'thickness 1.2))))
               (ratio (assoc-ref (ly:grob-property grob 'details) 'ratio))
               (dir (ly:grob-property grob 'direction))
               (xex (ly:stencil-extent stil X))
               (yex (ly:stencil-extent stil Y))
               (lenx (interval-length xex))
               (leny (interval-length yex))
               (tip-width (min tip-width (/ lenx 2)))
               (xtrans (car xex))
               (ytrans (if (> dir 0)(car yex) (cdr yex)))
               (cpts (list 
                 (cons 0 0) 
                 (cons tip-width (* dir height)) 
                 (cons tip-width (* dir height)) 
                 (cons lenx 0)))
               (newstil 
                 (grob-interpret-markup grob 
                   (general-flattened-curve cpts thickness line-thickness ratio)))
        )
   (ly:stencil-translate newstil (cons xtrans ytrans)))
   stil)))

#(define default-flat-tie
  (flattened-tie 1 0.7))

test_ties = \relative c' {
  \override Tie.stencil = #default-flat-tie
  a4 ~ a a' ~ a |
  a'4 ~ a <a,, c e a c e a c e> ~ q
  
  \break
  
  \revert Tie.stencil 
    c4 ~ c ~
    \override Tie.stencil = #default-flat-tie 
    c2 ~ 
  \once \override Tie.details.ratio = #1
    c2 ~
    \once \override Tie.stencil = #(flattened-tie 0.5 0.4)
    c2 ~ 
  c1 ~
  
  \break
  
  \revert Tie.stencil 
    c4 ~ c ~
    \override Tie.stencil = #default-flat-tie 
    \override Tie.line-thickness = #0.5
    c4 ~ 
    \once \override Tie.thickness = #5
    c ~
  \once \override Tie.stencil = #(flattened-tie 4 2)
    c2 ~ c
}

\score {
  \test_ties
}

test_slurs = \relative c' {
  c4 ( d f, f' ~ |
  f1 ) |
  
  \once \override Slur.ratio = 0.4
  \once \override Slur.stencil = #(flattened-slur 0 2 4 6 3.5)
  c4 ( d f, f' ~ |
  f1 ) |
  
  c16_[ ( c' f c g c f c g c f c g c f c] |
  c,2 ) r |
  
  \once \override Slur.ratio = 0.5
  \once \override Slur.stencil = #(flattened-slur -3.5 4.5 5 5 1.8)
  c16_[ ( c' f c g c f c g c f c g c f c] |
  c,2 ) r |
}

\score {
  \test_slurs
}


%<---------------------------------------------

Nice exmaples

Thanks! Let me know if you have questions.

Best,
Abraham

reply via email to

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