Autor Thema: Haltestriche die dritte  (Gelesen 1679 mal)

chf

  • Member
Haltestriche die dritte
« am: Mittwoch, 16. September 2015, 18:12 »
Hallo Harm,
mein gelöstes Problem hat eine ungelöste Variante:
Ich hoffe, du kannst  aus meiner Darstellung erkennen, worum es geht.
Die Glissandi sind anders verteilt und sollen alle ins Leere reichen.
Ich habe versucht, das schöne Beispiel anzupassen, aber irgendwas ist im Weg...
Kannst du nochmal helfen?

Gruß und Dank
Christa

\version "2.18.2"

#(define-markup-command (bar-line layout props strg)(string?)
  #:properties ((font-size 0)
                (add-height 0))
             
  (define (string->string-list str)
    "Convert a string into a list of strings with length 1.
  @code{"aBc"} will be converted to @code{("a" "B" "c")}.
  An empty string will be converted to a list containing @code{""}."
    (if (and (string? str)
             (not (zero? (string-length str))))
        (map (lambda (s)
                     (string s))
             (string->list str))
        (list "")))
             
  (define (make-bar-line thickness height fontsize blot-diameter)
    "Draw a simple bar line."
    (ly:round-filled-box
      (cons 0 (* (magstep font-size) thickness))
      (interval-widen (cons 0 (+ add-height height)) (magstep font-size))
      blot-diameter))
                           
  (define (make-colon-bar-line height fontsize)
    (let* ((font
             (ly:paper-get-font layout
               (cons '((font-encoding . fetaMusic)) props)))
           (dot (ly:font-get-glyph font "dots.dot")))
    (ly:stencil-add
        dot
        (ly:stencil-translate-axis
          dot
          (magstep (+ (/ add-height 2) font-size))
          Y))))
             
  (define (make-bracket-bar-line height fontsize dir thick-bar )
    "Draw a bracket-style bar line. If @var{dir} is set to @code{LEFT}, the
     opening bracket will be drawn, for @code{RIGHT} we get the
     closing bracket."
    (let* ((font
              (ly:paper-get-font layout
                (cons '((font-encoding . fetaMusic)) props)))
           (brackettips-up (ly:font-get-glyph font "brackettips.up"))
           (brackettips-down (ly:font-get-glyph font "brackettips.down"))
           ;; the x-extent of the brackettips must not be taken into account
           ;; for bar line constructs like "[|:", so we set new bounds:
           (tip-up-stil
             (ly:make-stencil
               (ly:stencil-expr brackettips-up)
               (cons 0 0)
               (ly:stencil-extent brackettips-up Y)))
           (tip-down-stil
             (ly:make-stencil
               (ly:stencil-expr brackettips-down)
               (cons 0 0)
               (ly:stencil-extent brackettips-down Y)))
           (stencil
             (ly:stencil-add
               thick-bar
               (ly:stencil-translate-axis
                 tip-up-stil
                 (+ (/ (+ add-height height) 2) (magstep fontsize)  )
                 Y)
               (ly:stencil-translate-axis
                 tip-down-stil
                 (* -1 (+ (/ (+ add-height height) 2) (magstep fontsize) ))
                 Y))))
        (if (eq? dir LEFT)
            stencil
            (ly:stencil-scale stencil -1 1))))
           
  (define (make-brace-bar-line height fontsize)
    (let* ((new-height (max (* add-height height) 12))
           (font
             (ly:paper-get-font layout
               (cons '((font-encoding . fetaBraces)
                       (font-name . #f))
                     props)))
           (glyph-count (1- (ly:otf-glyph-count font)))
           (scale (ly:output-def-lookup layout 'output-scale))
           (scaled-size (+ add-height (magstep fontsize) (/ (ly:pt new-height) scale)))
           (glyph
             (lambda (n)
               (ly:font-get-glyph
                 font
                 (string-append "brace" (number->string n)))))
           (get-y-from-brace
             (lambda (brace)
               (interval-length
                (ly:stencil-extent (glyph brace) Y))))
           (find-brace
             (binary-search 0 glyph-count get-y-from-brace scaled-size))
           (glyph-found (glyph find-brace)))

    (if (or (null? (ly:stencil-expr glyph-found))
            (< scaled-size
               (interval-length (ly:stencil-extent (glyph 0) Y)))
            (> scaled-size
               (interval-length (ly:stencil-extent (glyph glyph-count) Y))))
        (begin
          (ly:warning (_ "no brace found for point size ~S ") new-height)
          (ly:warning (_ "defaulting to ~S pt")
          (/ (* scale (interval-length (ly:stencil-extent glyph-found Y)))
             (ly:pt 10)))))
    glyph-found))
             
    (let* ((line-thickness (ly:output-def-lookup layout 'line-thickness))
           (size (ly:output-def-lookup layout 'text-font-size 12))
           ;; Numerical values taken from the IR
           (thin-thickness (* line-thickness 1.9))
           (kern (* line-thickness 3.0))
           (thick-thickness (* line-thickness 6.0))
           (blot (ly:output-def-lookup layout 'blot-diameter))
           ;; Not sure about the numerical value, found it by try and error.
           (thin-bar-line
             (ly:stencil-aligned-to
               (make-bar-line thin-thickness (/ size 9) font-size blot)
               Y CENTER))
           (thick-bar-line
             (ly:stencil-aligned-to
               (make-bar-line thick-thickness (/ size 9) font-size blot)
               Y CENTER))
           (colon-bar-line
             (ly:stencil-aligned-to
               (make-colon-bar-line (/ size 9) font-size)
               Y CENTER))
           (bracket-left-bar-line
             (ly:stencil-aligned-to
               (make-bracket-bar-line (/ size 9) font-size -1 thick-bar-line)
               Y CENTER))
           (bracket-right-bar-line
             (ly:stencil-aligned-to
               (make-bracket-bar-line (/ size 9) font-size 1 thick-bar-line)
               Y CENTER))
           (brace-left-bar-line
             (ly:stencil-aligned-to
               (make-brace-bar-line (/ size 9) font-size)
               Y CENTER))
           (strg-list (string->string-list strg))
           (find-bar-line-proc
              (lambda (x) (cond ((string=? ":" x) colon-bar-line)
                                ((string=? "|" x) thin-bar-line)
                                ((string=? "." x) thick-bar-line)
                                ((string=? "[" x) bracket-left-bar-line)
                                ((string=? "]" x) bracket-right-bar-line)
                                ((string=? "{" x) brace-left-bar-line)
                                (else empty-stencil))))
           (bar-line-stils
             (remove ly:stencil-empty? (map find-bar-line-proc strg-list)))
           (stil
             (stack-stencils X
                             RIGHT
                             (* (magstep font-size) kern)
                             bar-line-stils))
           (stil-y-length (interval-length (ly:stencil-extent stil Y))))
      ;; Hm, should the stencil-translate be hard-coded?
      (ly:stencil-translate-axis
        stil
        (/ stil-y-length 4)
        Y)))


#(define get-grob-name
  (lambda (x) (if (ly:grob? x) (assq-ref (ly:grob-property x 'meta) 'name))))

#(define (get-grob-most-left-relative-coordinate ref-point)
  (lambda (grob)
      (cond
        ((eq? (get-grob-name grob) 'NoteColumn)
           (let* ((note-heads-array (ly:grob-object grob 'note-heads))
                  (note-heads-grobs
                    (if (not (null? note-heads-array))
                        (ly:grob-array->list note-heads-array)
                        '()))
                  (note-heads-refpoints
                    (map
                      (lambda (nh)
                        (ly:grob-relative-coordinate nh ref-point X))
                      note-heads-grobs))
                  (sorted-note-heads-refpoints (sort note-heads-refpoints <)))
            (if (not (null? sorted-note-heads-refpoints))
                (car sorted-note-heads-refpoints))))
         ((eq? (get-grob-name grob) 'AccidentalPlacement)
            (let* ((acc-list (ly:grob-object grob 'accidental-grobs))
                   (acc-refpoints
                     (map
                       (lambda (acc)
                         (ly:grob-relative-coordinate (cadr acc) ref-point X))
                       acc-list))
                   (sorted-acc-refpoints (sort acc-refpoints <)))
             (if (not (null? sorted-acc-refpoints))
                 (car sorted-acc-refpoints))))
         (else
           (if (ly:grob? grob)
               (ly:grob-relative-coordinate grob ref-point X))))))
               
#(define* (duration-line #:optional (equal-start? #f))
   (lambda (grob)
     (let* ((line-thickness (ly:staff-symbol-line-thickness grob))
            (staff-space (ly:staff-symbol-staff-space grob))
            (refp (ly:grob-system grob))
            (note-head? (lambda (x) (eq? (get-grob-name x) 'NoteHead)))
            (half-gliss-thick (- (/ staff-space 2) line-thickness))
            (thickness
              ;; (- half-gliss-thick 0.23) is my personal taste
              ;; If other value wanted, use common 'thickness override
              (ly:grob-property grob 'thickness (- half-gliss-thick 0.23)))
            (blot-diameter
              (ly:output-def-lookup (ly:grob-layout grob) 'blot-diameter))
       ;;;; left NoteColumn
            (left-Y (assoc-get 'Y (ly:grob-property grob 'left-bound-info)))
            (left-bound (ly:spanner-bound grob LEFT))
            (left-note-column (ly:grob-parent left-bound X))
            (left-note-col-X-ext
              (ly:grob-extent left-note-column left-note-column X))
            (left-note-column-coord
              (ly:grob-relative-coordinate left-note-column refp X))
       ;;;; DotColumn of left NoteColumn
            (dot-column-left (ly:note-column-dot-column left-note-column))
            (dot-column-left-X-extent
              (if (ly:grob? dot-column-left)
                  (ly:grob-extent dot-column-left dot-column-left X)
                  '(0 . 0)))
       ;;;; right NoteColumn
            (right-bound (ly:spanner-bound grob RIGHT))
            (right-bound-info (ly:grob-property grob 'right-bound-info))
            (right-note-column (ly:grob-parent right-bound X))
            (most-left-note-head-coord
             ((get-grob-most-left-relative-coordinate refp) right-note-column))
       ;;;; AccidentalPlacement of right NoteColumn
            (acc-placement (ly:note-column-accidentals right-note-column))
            (most-left-note-acc-coord
             ((get-grob-most-left-relative-coordinate refp) acc-placement))
       ;;;; Arpeggio of right NoteColumn
            (arpeggio (ly:grob-object right-note-column 'arpeggio))
            (arpeggio-coord
              (if (ly:grob? arpeggio)
                  (ly:grob-relative-coordinate arpeggio refp X)))
       ;;;; calculate most right left-bound coord
            (most-right-left-bound-coord
              (+ left-note-column-coord
                (cdr left-note-col-X-ext)
                (cdr dot-column-left-X-extent)))
       ;;;; catch most left right-bound coord
            (right-bound-coords-lst
              (list
                arpeggio-coord
                most-left-note-acc-coord
                most-left-note-head-coord))
            (cleared-right-bound-coords-lst
                (sort
                  (remove (lambda (x) (not (number? x))) right-bound-coords-lst)
                  <)))

    ;; create a flat glissando
    (ly:grob-set-nested-property! grob '(right-bound-info Y) left-Y)
   
    ;; Let all glissandi start at the same vertical position
    (if (and (note-head? left-bound) equal-start?)
        (ly:grob-set-nested-property!
          grob
          '(left-bound-info X)
          most-right-left-bound-coord))
       
    ;; Let all glissandi end at the same vertical position
    (if (note-head? right-bound)
        (ly:grob-set-nested-property!
          grob
          '(right-bound-info X)
          (car cleared-right-bound-coords-lst)))

    ;; print new stencil
    (let* ((stencil (ly:line-spanner::print grob))
           (stencil-x-ext
             (if (ly:stencil? stencil)
                 (ly:stencil-extent stencil X)
                 '(0 . 0)))
           (new-stencil
             (ly:round-filled-box
                stencil-x-ext
                (interval-widen (cons left-Y left-Y) thickness)
                blot-diameter)))
     new-stencil))))
     
gliss-length =
#(define-music-function (parser location lngth)(number?)
#{
  \once \override Glissando.minimum-length = #lngth
#})
     
durationLine =
#(define-music-function (parser location equal-start? left-right-padding)
   ((boolean? #f) pair?)
#{
  \override Glissando.stencil = #(duration-line equal-start?)
  \override Glissando.bound-details.left.padding = #(car left-right-padding)
  \override Glissando.bound-details.right.padding = #(cdr left-right-padding)
  \override Glissando.bound-details.left-broken.padding = #0.5
  \override Glissando.bound-details.right-broken.padding = #0.3   
#})

durationLineSettings = {
  \durationLine #'(-0.5 . 0.6)
  %% For equal glissando-start with little padding use:
  % \durationLine ##t #'(0.5 . 0.6)
 
  %% other possible settings
  %\override Glissando.thickness = #0.2
  \override Glissando.breakable = ##t
  \override Glissando.after-line-breaking = ##t
  \override Glissando.springs-and-rods = #ly:spanner::set-spacing-rods
 
  %% construction helpers, DELETE ME
  %\override Glissando.layer = #20
  %\override Glissando.color = #red
}

\relative c'' {
<g a>4
a8 [\gliss-length #6 g,\glissando \gliss-length #6 a'\glissando bes'\glissando \once \hideNotes bes]   
<<\new Voice
    \with {
      \durationLine #'(-0.5 . -0.6)
    }
    \relative {
      \cadenzaOn
      \gliss-length #20
      a'8[
      \override NoteColumn.glissando-skip = ##t
      g,\glissando           
      a'     
      bes'8]
      \revert NoteColumn.glissando-skip     
    }
  \new Voice
    \with {
      \override Stem.stencil = #point-stencil
      \override Flag.stencil = #point-stencil
      \durationLine #'(-0.5 . -0.6)
    }
    \relative {
        \voiceTwo
        s4
        a'8\glissando       
        bes'8
    }
   \new Voice
    \with {
      \override Stem.stencil = #point-stencil
      \override Flag.stencil = #point-stencil
      \override NoteHead.stencil = #point-stencil
      \durationLine #'(-0.5 . -0.6)
    }
    \relative {
        \voiceThree
        s4.
        bes'8\glissando
       
   }>>
 }
\layout {
          %\override NoteHead.duration-log = #2
          \durationLineSettings         
  }
 

harm6

  • Member
Re: Haltestriche die dritte
« Antwort #1 am: Mittwoch, 16. September 2015, 22:11 »
Zitat von: chf
Ich hoffe, du kannst  aus meiner Darstellung erkennen, worum es geht.
Die Glissandi sind anders verteilt und sollen alle ins Leere reichen.

Ich kann leider nicht erkennen worum es Dir geht bzw was das Ziel sein soll.

Kannst Du einen scan oder auch nur ein Handy-Photo des Originals posten?
Oder mit einem Grafikprogramm einfügen was Dir vorschwebt und dieses Bild dann einstellen?

Gruß,
  Harm

chf

  • Member
Re: Haltestriche die dritte
« Antwort #2 am: Donnerstag, 17. September 2015, 13:53 »
Hallo Harm,

sorry - es ist dasselbe wie in "Haltelinie die Zweite", nur anders...
Das Bildchen hilft Dir (und mir!) hoffentlich weiter.
Die Figur im Mittelpunkt ist nicht ganz die gleiche wie die gestern vermittelte, hier ist es durch den Doppelgriff am Ende noch etwas komplizierter, alles andere wiederholt sich.

Gruß
Christa
« Letzte Änderung: Donnerstag, 17. September 2015, 13:55 von chf »

harm6

  • Member
Re: Haltestriche die dritte
« Antwort #3 am: Freitag, 18. September 2015, 00:04 »
Hallo Christa,

ich habe den Eindruck, daß der Glissando-stencil-tweak mit Deinem Beispiel so ziemlich ausgereizt ist.
Ich habe extrem rumtricksen müssen mit mehreren Voices, graces, hideNotes und ignore-collision.

Es geht, ja, aber das ist auch das Beste was man drüber sagen kann.

Ich frage mich, ob das Ganze via Tie.stencil-tweak nicht auch machbar wäre, vielleicht sogar besser (immerhin gibts ja tieWaitForNote). Allerdings kann ich jetzt schon massive Probleme mit diesem Ansatz ermessen. Ich probiers mal, wenn ich mehr Zeit habe...

Aber hier Dein Beispiel:

\layout {
          %\override NoteHead.duration-log = #2
          \durationLineSettings         
  }
 
 
\new Staff <<
  \cadenzaOn
  \new Voice
    \with {
      %  \override Stem.stencil = #point-stencil
      %  \override Flag.stencil = #point-stencil
      \durationLine #'(0.5 . -0.6)
    }
    \relative c' {
      fis8[ gis, fis'! \gliss-length #4 a]\glissando
      \once \hideNotes
      \grace a4
      fis!8[ gis,! fis'! \gliss-length #4 <a e'>]\glissando
      \once \hideNotes
      \stemUp
      \grace <a e'>4
      s
    }
  \new Voice
    \with {
      \override Stem.stencil = #point-stencil
      %  \override Flag.stencil = #point-stencil
      \durationLine #'(0.5 . -0.6)
    }
    \relative c' {
      \voiceTwo
      \override NoteColumn.ignore-collision = ##t
      s4 fis4\glissando \once \hideNotes \grace fis4 s4 fis \glissando
      \once \hideNotes
      \grace fis4
      s
    }
  \new Voice
    \with {
      \override Stem.stencil = #point-stencil
      %  \override Flag.stencil = #point-stencil
      \durationLine #'(0.5 . -0.6)
    }
    \relative c' {
      \voiceTwo
      s8 gis4\glissando s8 \once \hideNotes \grace gis4 s8 gis4\glissando s8
      \once \hideNotes
      \grace gis4
      s
    }
>>

Der scheme-code ist unverändert, insoweit habe ich mir das erneute einfügen diesmal gespart.

HTH,
  Harm
« Letzte Änderung: Freitag, 18. September 2015, 01:45 von harm6 »

chf

  • Member
Re: Haltestriche die dritte
« Antwort #4 am: Freitag, 18. September 2015, 01:24 »
Hallo Harm,

hab Dank! Das sieht ja wunderbar aus. Mehr Varianten habe ich nicht...

Gute Nacht!