lilypond-user
[Top][All Lists]
Advanced

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

Re: Dotted notes


From: Thomas Morley
Subject: Re: Dotted notes
Date: Thu, 19 Apr 2018 01:56:29 +0200

2018-04-17 23:34 GMT+02:00 foxfanfare <address@hidden>:
> I struggle on this:
>
> \version "2.19.80"
>
> \paper {
>   #(set-paper-size "a7")
> }
> \bookpart {
>
>   \score {
>     \relative c' {
>       \cadenzaOn
>       \omit Staff.TimeSignature
>       c1.^"Default" d4.. e8... f16....
>     }
>   }
> }
>
> \bookpart {
>
>   \paper {
>     #(define fonts
>     (set-global-fonts
>       #:music "beethoven"
>       #:brace "beethoven"
>       #:factor (/ staff-height pt 20)
>   ))
>   }
>   \score {
>
>    \relative c' {
>      \cadenzaOn
>      \omit Staff.TimeSignature
>
>      c1.^"New Font" d4.. e8... f16.... \bar "" \break
>
>      \override Staff.Dots.font-size = #-1.5
>      %closer to note head:
>      \override Staff.Dots.extra-offset = #'(-0.1 . 0)
>
>      c1.^"Some Changes ?" d4.. e8... f16....
>
>    }
>   }
> }
>
> \layout {
>   ragged-right = ##t
> }
>
> When the font is changed, the dotted notes doesn't avoid the flags as it did
> with default emmentaler!
> I think it could be solved by settting some "padding" for the flags, but I
> wasn't able to find this command! (?)
>
> Also, when playing with their options, I was able to find a way to make them
> smaller and closer to the notehead (extra-offset) but I am unable to find
> the solution get the following dots closer to each other!
>
> Any suggestions?



Hi,

obviously the flags from the beethoven-font have less y-extent.
Sometimes too less, so DotColumn doesn't notice there's flag which
should be avoided.
(I've cc-ed the original author of the font. Maybe he joins the discussion.)

To watch the values uncomment
\printFontFlagYExtent
in the test-code below.

Additionally I wrote some procedures to deal with this problem as well
as to get access and manipulate the dots of a DotColumn.
Per default most work is done in C++ and locked from the user, though
with a little trickery there's a way.

(1) The too short flags form beethoven-font may be corrected with
\tallerBeethovenFlags
(2) Alternatively you can move the DotColumn with \moveBeethovenDotColumn

Both functions are limited to beethoven-font, they will have no impact
on other fonts

(3) \dotsAndDotColumnPadding is the most generic one.
Put it in layout and add
\override Staff.DotColumn.padding = <what-ever-value>
and/or
\override Staff.DotColumn.details.dots-padding-factor = <what-ever-value>
where you want.
Both properties will influence each other.

Be aware, although it's the most generic one, it is also the most fragile one:
Because Dots in DotColumn are processed in C++ and only very few
grob-properties are accessible we have little chance to customize it,
apart from post-processing the ready stencil. A tedious and involved
work. This also means: if LilyPond internals change,
\dotsAndDotColumnPadding may break.

But here the code.

\version "2.19.81"

printFontFlagYExtent =
  \override Flag.after-line-breaking =
    #(lambda (grob)
       (let* ((stil (ly:flag::print grob))
              (stil-y-ext (ly:stencil-extent stil Y))
              (grob-default-font (ly:grob-default-font grob))
              (font (ly:font-name grob-default-font))
              (font-name (car (string-split font #\-))))
         (newline)
         (format #t "\nfont: ~a" font-name)
         (format #t "\nstil-y-ext:~a" stil-y-ext)))

tallerBeethovenFlags =
  \override Flag.before-line-breaking =
    #(lambda (grob)
       (let* ((stil (ly:flag::print grob))
              (stil-y-ext (ly:stencil-extent stil Y))
              (grob-default-font (ly:grob-default-font grob))
              (font (ly:font-name grob-default-font))
              (font-name (car (string-split font #\-))))
         (if (string=? font-name "beethoven")
             (ly:grob-set-property! grob 'stencil
               (ly:make-stencil
                 (ly:stencil-expr stil)
                 (ly:stencil-extent stil X)
                 (coord-translate
                   stil-y-ext
                   '(-0.054 . 0)))))))

moveBeethovenDotColumn =
\override Staff.DotColumn.before-line-breaking =
  #(lambda (grob)
    (let* ((grob-default-font (ly:grob-default-font grob))
           (font (ly:font-name grob-default-font))
           (font-name (car (string-split font #\-))))
      (if (string=? font-name "beethoven")
          (ly:grob-set-property! grob 'positioning-done
            (lambda (grob)
              (ly:dot-column::calc-positioning-done grob)
              (ly:grob-translate-axis! grob 1 X)
              #t)))))

#(define (lists-map function ls)
   "Apply @var{function} to @var{ls} and all of it sublists.
First it recurses over the children, then the function is applied to
@var{ls}."
   (if (list? ls)
       (set! ls (map (lambda (y) (lists-map function y)) ls))
       ls)
   (function ls))

#(define (delete-adjacent-duplicates lst)
  (if (pair? lst)
      (fold-right
        (lambda (elem ret)
          (if (equal? elem (first ret))
              ret
              (cons elem ret)))
        (list (last lst))
        lst)
      lst))

#(define (get-next-to-sym ls symbol proc)
  (define (helper l rl sym proc)
    (if (list? l)
        (append-map
          (lambda (x)
            (delete-adjacent-duplicates
              (helper
                x
                (remove
                  null?
                  (if (eq? sym (car l))
                      (cons (proc l) rl)
                      rl))
                sym
                proc)))
          l)
        rl))
  (helper ls '() symbol proc))

dotsAndDotColumnPadding =
\override Staff.DotColumn.before-line-breaking =
  #(lambda (grob)
     (let* ((dots (ly:grob-array->list (ly:grob-object grob 'dots)))
            (dots-stils
              (map (lambda (dot) (ly:grob-property dot 'stencil)) dots))
            (dots-stil-expr (map ly:stencil-expr dots-stils))
            (dot-column-padding
              (ly:grob-property grob 'padding 0))
            (details
              (ly:grob-property grob 'details))
            (dots-padding-factor
              (assoc-get 'dots-padding-factor details 1))
            (side-support-elements
              (ly:grob-object grob 'side-support-elements))
            (nhds
              (filter
                (lambda (el)
                  (grob::has-interface el 'note-head-interface))
                (ly:grob-array->list side-support-elements)))
            (common-ref-pt
              (ly:grob-common-refpoint-of-array grob side-support-elements X))
            (nhds-x-exts
              (map
                (lambda (nh)
                  (ly:grob-extent nh common-ref-pt X))
                nhds))
            (no-suspended-heads?
              (every (lambda (c) (zero? (car c))) nhds-x-exts))
            (new-stil-expr
              (lists-map
                (lambda (e)
                  (if (number-pair? e)
                      (cons (* dots-padding-factor (car e)) (cdr e))
                      e))
                 dots-stil-expr))
            (max-translate
              (apply max
                     (get-next-to-sym new-stil-expr 'translate-stencil caadr))))

       (ly:grob-set-property! grob 'positioning-done
         (lambda (grob)
           (ly:dot-column::calc-positioning-done grob)
           (ly:grob-translate-axis!
             grob
             (if no-suspended-heads?
                 dot-column-padding
                 0)
             X)
           #t))

       (for-each
         (lambda (dot dot-stil)
           (let ((x-ext (ly:stencil-extent dot-stil X))
                 (y-ext (ly:stencil-extent dot-stil Y)))
             (ly:grob-set-property! dot 'stencil
               (ly:make-stencil
                 (car new-stil-expr)
                 (cons (car x-ext)
                       (+
                          max-translate
                          (interval-length y-ext)))
                 y-ext))))
         dots
         dots-stils)))


\paper {
  ragged-right = ##t
  #(set-paper-size "a6")
}

\layout {
  \autoBeamOff
  %\printFontFlagYExtent
  %\tallerBeethovenFlags
  %\moveBeethovenDotColumn
  \dotsAndDotColumnPadding
}

mus = {
  d'16..
  f'
  a'
  <d' e' f'>16..
}

\bookpart {
  \mus
}

\bookpart {
  \paper {
    #(define fonts
      (set-global-fonts
        #:music "beethoven"
        #:brace "beethoven"
        #:factor (/ staff-height pt 20)))
  }
  {
    \override Staff.DotColumn.padding = 0.7
    \override Staff.DotColumn.details.dots-padding-factor = 1.3
    \mus
  }
}


HTH,
  Harm



reply via email to

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