Hello, our problem here is that such things like the positioning of beams are not known for quite some time. But we could use something like after-line-breaking to adjust the results. Somewhat like here.
Valentin Am Sonntag, 20. Februar 2022, 21:17:31 CET schrieb Luca Fascione: > So... would anybody be able to lend a hand here please? > > Many thanks > Luca > > On Sat, Feb 12, 2022 at 7:49 PM Luca Fascione <l.fasci...@gmail.com> wrote: > > Hello, > > sorry for the double-post, I'm unsure whether this should go to -user or > > -devel. > > > > I'm looking for some guidance to set up fingering on classical guitar > > sheets. > > > > I am attaching a simple piece of music, with two engraving sets (measures > > 1-5 and 6-10), one "as-is" from lilypond, the other using some trickery > > involving one-note chords, purely to show a sample of what the result I'm > > after (and it's an approximation), vs what I get at the moment. > > > > Measures 1-5 in the source look like what I am intending to type, but it > > has a number of engraving defects I don't understand (you can see the > > beams > > don't avoid the fingerings, nor they are located correctly wrt the > > accidentals, the second beat of measure 5 illustrates this well. I'm not > > super in love with measure 10 either, but if I understand the docs > > correctly, the issue there is that the 'offset' correction is applied > > post-layout, and so naturally it won't back-affect the placement of the > > beams. > > > > I have made several other experiments, I'm just not wanting to waste > > people's time. But setting Fingering.side-axis = #X seems somewhat > > promising, but it seems unable to find any usable Y data about the > > parents, > > and smashes all numbers on the B line, as well as not dealing with > > accidentals. > > > > I have an engraving project in front of me, for which I'm more than happy > > to put in the time to contribute the code to a proper solution myself, and > > I really don't want to make poor use of time from folks busy with other > > work, but I feel I'll need some level of guidance as to what to do. For > > context I can do C++ and I can manage guile ok (I'm a software engineer > > for > > work, I'm mostly working in the field of computer graphics). > > > > I was looking into this problem several years ago also, and Han-Wen > > Nienhuys at the time suggested I should use a positioning callback > > attached > > to the Fingering grobs, but I couldn't find a way to do such a thing (in > > particular I can't find what property to use for this). So far I've traced > > the Fingering system to be an instance of the Articulations/Scripts > > system, > > but that's as far as I got. > > > > It seems to me what's needed would be to decide where the heads go, then > > the accidentals, at this stage deal with the fingering and only then there > > would be enough bboxes to reason about the beaming (this is the skyline > > concept I think). In reasoning about how Articulations are engraved, it's > > possible the order of events for fingering would be different from the > > order of events in other articulations (which I think are laid out after > > beams are in place, if I am not mistaken), warranting a bigger change, but > > I have no idea where that is located/managed. > > > > Many thanks for your time, > > Luca
\version "2.22.1" % file to test various requirements to engrave fingering for guitar % the main goal is to obtain fingering places approx NorthEast of the note heads, right at % the head. % In all other respects this is a minimal working example %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Functions and global definitions % string numbers orientation UP stringUp = \set stringNumberOrientations = #'(up) % string numbers orientation DOWN stringDown = \set stringNumberOrientations = #'(down) Barre = #(define-music-function (barre location str music) (string? ly:music?) (let ((elts (extract-named-music music '(NoteEvent EventChord RestEvent SkipEvent)))) (if (pair? elts) (let ((first-element (first elts)) (last-element (last elts))) (set! (ly:music-property first-element 'articulations) (cons (make-music 'TextSpanEvent 'span-direction -1) (ly:music-property first-element 'articulations))) (set! (ly:music-property last-element 'articulations) (cons (make-music 'TextSpanEvent 'span-direction 1) (ly:music-property last-element 'articulations)))))) #{ \once \override TextSpanner.font-size = #1 \once \override TextSpanner.staff-padding = #3 \once \override TextSpanner.style = #'line \once \override TextSpanner.to-barline = ##f \once \override TextSpanner.direction = #UP \once \override TextSpanner.bound-details = #`((left (text . ,#{ \markup { #str } #}) (Y . 0) (padding . -0.5) (stencil-align-dir-y . .0) (attach-dir . -1)) (right (text . ,#{ \markup { \draw-line #'( .25 . -.5) } #}) (Y . 0) (padding . 0.5) (attach-dir . 1))) \once \override TextSpanner.bound-details.left-broken.attach-dir = #-1 \once \override TextSpanner.bound-details.left-broken.text = ##f \once \override TextSpanner.bound-details.right-broken.text = ##f $music #}) Barref = #(define-music-function (barre location num den str music) (string? string? string? ly:music?) (let ((elts (extract-named-music music '(NoteEvent EventChord RestEvent SkipEvent)))) (if (pair? elts) (let ((first-element (first elts)) (last-element (last elts))) (set! (ly:music-property first-element 'articulations) (cons (make-music 'TextSpanEvent 'span-direction -1) (ly:music-property first-element 'articulations))) (set! (ly:music-property last-element 'articulations) (cons (make-music 'TextSpanEvent 'span-direction 1) (ly:music-property last-element 'articulations)))))) #{ \once \override TextSpanner.font-size = #1 \once \override TextSpanner.staff-padding = #3 \once \override TextSpanner.style = #'line \once \override TextSpanner.to-barline = ##f \once \override TextSpanner.direction = #UP \once \override TextSpanner.bound-details = #`((left (text . ,#{ \markup { \tiny \fraction #num #den #str } #}) (Y . 0) (padding . -0.5) (stencil-align-dir-y . .0) (attach-dir . -1)) (right (text . ,#{ \markup { \draw-line #'( .25 . -.5) } #}) (Y . 0) (padding . 0.5) (attach-dir . 1))) \once \override TextSpanner.bound-details.left-broken.attach-dir = #-1 \once \override TextSpanner.bound-details.left-broken.text = ##f \once \override TextSpanner.bound-details.right-broken.text = ##f $music #}) stringNumberSpanner = #(define-music-function (StringNumber) (string?) #{ \override TextSpanner.style = #'solid \override TextSpanner.font-name = #'"Minion Pro Bold" \override TextSpanner.font-size = #-2 \override TextSpanner.bound-details.left.stencil-align-dir-y = #CENTER \override TextSpanner.bound-details.left.text = \markup { \circle \number $StringNumber } #}) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Configuration for the fingering #(define (Fingering_stuff_engraver context) (let ((head #f) (stem #f) (fingering #f)) (make-engraver (acknowledgers ((finger-interface engraver grob source-engraver) (set! fingering grob)) ((note-head-interface engraver grob source-engraver) (set! head grob)) ((stem-interface engraver grob source-engraver) (set! stem grob))) ((process-music engraver) (if (and fingering stem head) (ly:grob-set-property! fingering 'details `((head . ,head) (stem . ,stem) . ,(ly:grob-property fingering 'details)))) (set! head #f) (set! stem #f) (set! fingering #f))))) \layout { \context { \Voice \consists #Fingering_stuff_engraver % setup fingering on the left of the noteheads %\override Voice.fingeringOrientations = #'(left) % now move it up one stave-space and right a little \override Fingering.extra-offset = #'(0 . 0) \override Fingering.X-offset = #0.5 \override Fingering.Y-offset = 0 \override Fingering.after-line-breaking = #(lambda (grob) (let* ((det (ly:grob-property grob 'details)) (stem (assoc-get 'stem det)) (stem-height (interval-length (ly:grob-property stem 'Y-extent))) (bm (if stem (ly:grob-property stem 'beaming) '())) (bm-left (if (null? bm) #f (car bm))) (total-beams (if bm-left (1+ (apply max bm-left)) 0)) (CONST_BEAM_SPACE 1) (effective-stem-length (- stem-height (* total-beams CONST_BEAM_SPACE))) (prev-offset (ly:grob-property grob 'Y-offset)) (grob-height (interval-length (ly:grob-property grob 'Y-extent))) (head (assoc-get 'head det)) (head-offset (if head (ly:grob-property head 'Y-offset))) (offset-diff (- prev-offset head-offset)) (nescessary-height (+ offset-diff grob-height 0.7)) (shift (- effective-stem-length nescessary-height)) (offset-diff-after-shift (- (+ prev-offset shift) head-offset)) (x-shift (if (< offset-diff-after-shift 0.1) -0.7 (if (< offset-diff-after-shift 0.3) -0.5 0)))) (if (and stem head) (if (and bm-left (< effective-stem-length nescessary-height)) (ly:grob-set-property! grob 'extra-offset (cons x-shift (- effective-stem-length nescessary-height))) )))) % align to side of parent grob (-1 left, 0 center, 1 right) % if another number, it's in half-parent's width units \override Fingering.parent-alignment-X = #-1 % align to side of parent grob (1 top, 0 center, -1 bottom) % if another number, it's in half-parent's height units %\override Fingering.parent-alignment-Y = #1 % align referenced to this side of stencil (-1 left, 0 center, 1 right) % if another number, it's in half-object's width units \override Fingering.self-alignment-X = #1 % align referenced to this side of stencil (1 top, 0 center, -1 bottom) % if another number, it's in half-object's height units %\override Fingering.self-alignment-Y = #-1 % align to the side of the parent, not above %\override Fingering.side-axis = #X %\override Fingering.use-skylines = ##t % fingering should sit inside the staff \override Fingering.staff-padding = #'() % fingering should sit right at the note head, no worries about the beaming \override Fingering.add-stem-support = ##f \override Fingering.direction = #LEFT % setup the size for the right-hand fingering notation \override StrokeFinger.font-size = -2 % setup the shape for the right-hand fingering notation \override StrokeFinger.font-shape = #'upright % keep right-hand fingering inside slurs \override StrokeFinger.avoid-slur = #'inside % string numbers below the notehead %\override Voice.stringNumberOrientations = #'(down) % plucking fingering notation above the notehead %\override Voice.strokeFingerOrientations = #'(up) %\once \override StringNumber.self-alignment-X = #RIGHT %\once \override Fingering.self-alignment-X = #RIGHT %\override StringNumber.self-alignment-X = #RIGHT } } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Minimal document setup \paper { #(set-paper-size "a4") } \header{ title = "Fingering tests" subtitle = "A little sampler to setup guitar fingering" composer = "Luca Fascione" lastupdated = "2022/Feb/12" tagline = ##f } % various pieces of sample music \parallelMusic guitarHi,guitarMid,guitarLo { \mergeDifferentlyHeadedOn \bar "[|:" \slurDown \stringUp cis'4-1 gis,16 b e'-0 b | s2 | \Barref "4" "6" "CII" { a,16-0 a-1 e-1 a-1 } gis,4-3 | a4-1 e,16 cis'-1 d'-2 e'-0 | s2 | \Barre "CII" { fis,16-1 fis-4 cis-3 fis } e,4-0 | \Barref "1" "2" "CII" { fis'16-1 cis'-1( d'-2) fis' } e'-0 gis-1 b-0 d'-4 | s2 | d4-0 e,-0 | \break cis'2-1 | s2| \Barref "4" "6" "CII" {a,16-0 a-1 e-1 a a,-0( cis-3) e-1 a-1 } | %5 cis'4-2 \Barre "CIV" {cis16 eis'32-3( fis'-4) gis'16-1 a'-2} | s2 | eis16-3 gis-1 d-0 gis cis4-1 | } \parallelMusic guitarHiB,guitarMidB,guitarLoB { \mergeDifferentlyHeadedOn \bar "[|:" \slurDown \stringUp <cis'-1>4 <gis,>16 b <e'-0> b | s2 | \Barref "4" "6" "CII" { <a,-0>16 <a-1> <e-1> <a-1> } <gis,-3>4 | <a-1>4 e,16 <cis'-1> <d'-2> <e'-0> | s2 | \Barre "CII" { <fis,-1>16 <fis-4> <cis-3> fis } <e,-0>4 | \Barref "1" "2" "CII" { <fis'-1>16 <cis'-1(> <d'-2)> fis' } <e'-0> <gis-1> <b-0> <d'-4> | s2 | <d-0>4 <e,-0> | \break <cis'-1>2 | s2| \Barref "4" "6" "CII" {<a,-0>16 <a-1> <e-1> a <a,-0(> <cis-3)> <e-1> <a-1> } | %5 cis'4-2 \Barre "CIV" {cis16 <eis'-3(>32 <fis'-4)> <gis'-1>16 <a'-2>} | s2 | <eis-3>16 <gis-1> <d-0> gis <cis-1>4 | } guitar = { \accidentalStyle modern-cautionary { \key a \major \time 2/4 \clef "violin_8" << \voiceOne \guitarHi \\ \voiceFour \guitarMid \\ \voiceTwo \guitarLo >> } } fingeringSetup = { % setup fingering on the left of the noteheads \set fingeringOrientations = #'(left) % now move it up and right a little \override Fingering.extra-offset = #'(0.125 . 0.5) } guitarB = { \accidentalStyle modern-cautionary { \key a \major \time 2/4 \clef "violin_8" << \new Voice = "hi" { \fingeringSetup \voiceOne \guitarHiB } \new Voice = "mid" { \fingeringSetup \voiceFour \guitarMidB } \new Voice = "lo" { \fingeringSetup \voiceTwo \guitarLoB } >> } } \score { \new Staff = "guitar" { \guitar \break \guitarB } \layout { } }
signature.asc
Description: This is a digitally signed message part.