Hi David,

2011/12/9 David Nalesnik <david.nales...@gmail.com>:
> Hi Harm,
>
> (...) looking
> with fresh eyes at the file I just attached, I really should have condensed
> that list of nearly identical offset calculations.  (See attached for the
> way I came up with.)

thanks for doing this! I did the next step to simplify the definition,
with defining "read-out".
-> attachment

>
>> > The results look fine to me, except for the arpeggio of course.  I don't
>> > know what the problem is here.
>>
>> The arpeggio seems to belong to the NoteColumn (with "2.15.x"),
>> although the IR speaks only about Stems and NoteHeads . This means
>> that a chord with an arpeggio has a bigger extent (and length) and is
>> selected when passing the condition of dir-correction as being greater
>> than one-note-head-length.
>> It's of course possible to change the condition, but I'm not sure,
>> perhaps it's a bug. Did you notice
>>
>> http://old.nabble.com/bug-or-feature-with-the-extent-of-NoteColumn-with-%222.15.20%22---td32935365.html
>> where I ask about it (so far without answer)?
>>
>
> Yes, I saw your thread and I'd be interested in hearing the answer too.  I
> just tried the file with 2.14.2, and the arpeggio works perfectly there.
>

If you haven't seen it already, it's now on the tracker:
http://code.google.com/p/lilypond/issues/detail?id=2091

Thanks,
  Harm
\version "2.14.2"

% Thanks to David Nalesnik

#(set-global-staff-size 20)

#(define (helper ls1 ls2 ls3)
 "Constructs an alist with the elements of ls1 and ls2"
 (set! ls3 (assq-set! ls3 (car ls1) (car ls2)))
        (if (null? (cdr ls1))
          ls3
          (helper (cdr ls1) (cdr ls2) ls3)))

#(define (helper-2 lst number)
  "Search the first element of the sorted lst, which is greater than number"
  (let ((ls (sort lst <)))
          (if (> (car ls) number)
              (car ls)
              (if (null? (cdr ls))
                  (begin
                    (display "no member of the list is greater than the number")
                    (newline))
                  (helper-2 (cdr ls) number)))))

#(use-modules (srfi srfi-1))

#(define (delete-adjacent-duplicates lst)
  "Deletes adjacent duplicates in lst
  eg. '(1 1 2 2) -> '(1 2)"
            (fold-right (lambda (elem ret)
                          (if (equal? elem (first ret))
                              ret
                              (cons elem ret)))
                        (list (last lst))
                        lst))

#(define (position-in-list obj ls)
  "Search the position of obj in ls"
        (define (position-in-list-helper obj ls bypassed)
          (if (null? ls)
              #f
              (if (equal? obj (car ls))
                  bypassed
                  (position-in-list-helper obj (cdr ls) (+ bypassed 1)))))
  (position-in-list-helper obj ls 0))
      
#(define (read-out ls1 ls2 ls3 symbol)
"Filters all elements of ls1 from ls2 and appends it to ls3"
(set! ls3 (append ls3 (filter (lambda (x) (eq? (car ls1) (symbol x))) ls2)))
  (if (null? (cdr ls1))
      ls3
      (read-out (cdr ls1) ls2 ls3 symbol)))
      
#(define ((center-note-column x-offs) grob)
     (let* ((sys (ly:grob-system grob))
            (elements-lst (ly:grob-array->list (ly:grob-object sys 'all-elements)))
            (grob-name (lambda (x) (assq-ref (ly:grob-property x 'meta) 'name)))
            (X-extent (lambda (q) (ly:grob-extent q sys X)))
      ;; NoteColumn
            (note-column-coord (ly:grob-relative-coordinate grob sys X))
            (grob-ext (X-extent grob))
            (grob-length (interval-length grob-ext))
      ;; NoteHeads
            (note-heads (ly:grob-object grob 'note-heads))
            (note-heads-grobs (if (not (null? note-heads))
                         (ly:grob-array->list note-heads)
                         '()))
            (one-note-head (if (not (null? note-heads-grobs))
                        (car note-heads-grobs)
                        '()))
            (one-note-head-length (if (not (null? one-note-head))
                             (interval-length (ly:grob-extent one-note-head sys X))
                             0))
      ;; Stem
            (stem (ly:grob-object grob 'stem))
            (stem-dir (ly:grob-property stem 'direction))
            (stem-length-x (interval-length (ly:grob-extent stem sys X)))
      ;; DotColumn
            (dot-column (ly:note-column-dot-column grob))
      ;; AccidentalPlacement
            (accidental-placement (ly:note-column-accidentals grob))
      ;; Arpeggio
            (arpeggio (ly:grob-object grob 'arpeggio))
      ;; Rest
            (rest (ly:grob-object grob 'rest))
      ;; Grobs to center between
            (args (list 'BarLine 
             	        'Clef 
             	        'KeySignature
             	        'KeyCancellation
             	        'TimeSignature))
            (grob-lst (read-out args elements-lst '() grob-name)) 
            (new-grob-lst (remove (lambda (x) (interval-empty? (X-extent x))) grob-lst))
            (coords (map (lambda (x) (ly:grob-relative-coordinate x sys X)) new-grob-lst))
            (coords-list (delete-adjacent-duplicates (sort coords <)))
            (grob-alist (if (not (null? new-grob-lst))
                            (helper coords new-grob-lst '())
                            '()))

      ;; Bounds
            (right-bound-coords (helper-2 coords-list note-column-coord))
            (right-bound-position-in-coords-list (position-in-list right-bound-coords coords-list))
            (left-bound-coords (list-ref coords-list (- right-bound-position-in-coords-list 1)))

            (grob-x1 (assoc-ref grob-alist left-bound-coords))
            (grob-x2 (assoc-ref grob-alist right-bound-coords))
            
            ;;(bounds-coord (cons left-bound-coords right-bound-coords)) ;; if you want to display this
            (bounds (cons grob-x1 grob-x2))
            
            (left (cdr (X-extent (car bounds))))
            (right (car (X-extent (cdr bounds))))
            
            (basic-offset
              (- (average left right)
                 (interval-center (X-extent grob))
                 (* -1 x-offs)))
            (dir-correction
              (if (> grob-length one-note-head-length)
                  (* stem-dir (* -2 stem-length-x) grob-length)
                  0))

            ) ;; End of Defs in let*

   ;; Calculation
   (begin
     ;;(newline)
     ;;(display bounds)
     ;;(newline)
     ;;(ly:grob-set-property! grob-x1 'color red)
     ;;(ly:grob-set-property! grob-x2 'color blue)
     ;;(display (cons left right)) (newline)

     (for-each
       (lambda (x)
         (cond ((ly:grob? x)
          (ly:grob-translate-axis!
            x
            (- basic-offset dir-correction)
            X))))
        (list
          (cond ((not (null? note-heads)) grob))
          dot-column accidental-placement arpeggio rest))
  )))

centerNoteColumnOn = \override Staff.NoteColumn #'after-line-breaking = #(center-note-column 0)

centerNoteColumnOff = \revert Staff.NoteColumn #'after-line-breaking

onceCenterNoteColumn =
#(define-music-function (parser location x-offs)(number?)
#{
        \once \override Staff.NoteColumn #'after-line-breaking = #(center-note-column $x-offs)
#})

%------------ Test

\paper {
        ragged-right = ##f
}
%%{
% tiny example:

   <<
   \new Staff
   { \time 3/4 \key b\minor R2.*3 }
   \new Staff
   {
     \time 3/4 \key b\minor b''2.
     \key a\minor \onceCenterNoteColumn #0 <a'' bes''>2.
     \clef "treble" R
   }
   >>
%}
%%{
% full test:
\layout {
        indent = 0
    \context {
      \Score
      \override NonMusicalPaperColumn #'line-break-permission = ##f
      \override BarNumber #'break-visibility = #'#(#t #t #t)
    }
    \context {
      \Staff
      %\remove Time_signature_engraver
      %\remove Key_engraver
      %\remove Clef_engraver
    }
}

\markup \vspace #2

testVoice = \relative c' {
        \key b\minor
        \time 3/4
        b'2_"Zeit?" r4
        \key g\minor
        \time 3/4
        \clef "bass"
        R2.
        \key a\minor
        \time 3/4
        \clef "treble"
        R2.
        \key g\minor
        \clef "bass"
        R2.
        \key a\minor
        \clef "treble"
%5
        R2. \break
        \key g\minor
        \clef "bass"
        R2.
        \key a\minor
        \clef "treble"
%7
        R2.
        \key g\minor
        \clef "bass"
        R2.*1\fermataMarkup
        \key a\minor
        \clef "treble"
        R
        \bar "|."
}

voice = \relative c' {
        \key b\minor
        \time 3/4
        b'2 r4
        R2.*6
        R2.*1\fermataMarkup
        R
        \bar "|."
}

pUp = \relative c' {
        \key b\minor
        \clef "bass"
        \time 3/4

%        \stemUp

        <d, fis b>2.\pp  (
        \centerNoteColumnOn
        \once \override Score.Arpeggio #'padding = #-1.5
        \set Score.connectArpeggios = ##t
        <fis ais>\arpeggio
        <fis d'!>
        <e! g! c!>  )
%5
        \onceCenterNoteColumn #-0.4
        <dis fis! a b> (
        <e g b> )
%7
        <dis fis b> ~
        <dis fis b>\fermata
        r
}

pDown = \relative c' {
        \key b\minor
        \clef "bass"
        \time 3/4
        <b,, fis' b>2. ( |
        \centerNoteColumnOn
        <ais fis' ais>\arpeggio |
        <d fis d'>  |
        <c g' c> ) |
%5
\onceCenterNoteColumn #-0.4
        <b b'> ~ |
        <b b'>-.-> |
%7
        <b b'> ~ |
        <b b'>\fermata |
        r
}
\score {
  <<
    \new Staff %\voice
               \testVoice
    \new PianoStaff <<
        \new Staff <<
           \pUp
        >>
        \new Staff <<
           \pDown
        >>
        >>
  >>
  \layout {
    \context {
      \Score
      \remove "Bar_number_engraver"
    }
  }
}
%}
_______________________________________________
lilypond-devel mailing list
lilypond-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-devel

Reply via email to