[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: treble and bass clef simultaneously
From: |
Thomas Morley |
Subject: |
Re: treble and bass clef simultaneously |
Date: |
Sat, 30 Mar 2019 22:20:33 +0100 |
Am Sa., 30. März 2019 um 13:06 Uhr schrieb Thomas Morley
<address@hidden>:
>
> Am Sa., 30. März 2019 um 09:04 Uhr schrieb Werner LEMBERG <address@hidden>:
>
> > > More robust: [...]
>
> > Being a perfectionist I see a last spacing issue: If there are
> > accidentals in the main chord, the fake bass clef gets aligned with
> > the leftmost accidental (in the image, I've slightly moved the clef
> > down for testing purposes to assure that there is no collision with
> > the accidentals). I wonder why this is so – I'm not aware of the
> > necessity to do such an alignment at all –, and whether this can be
> > circumvented.
>
> The distance from bass-clef to the following note is set by
> \override Clef.space-alist.next-note = #'(fixed-space . 2)
> So the current alignment is more by accident.
>
> Above does not hold if the ClefVoice starts at line-begin.
> Per default main and additional bass-clef are vertical aligned then.
>
> I tried to get the bass-clef closer to the note in question with
> \override Clef.after-line-breaking = ...
> Though, this override does not work sufficiently. Try chords with and
> without accidentals in the main Voice to what I mean.
> Up to now I've not found a good method to do it better ...
>
> Cheers,
> Harm
Below my current approach for adjusting the additional clef at line-begin.
\version "2.19.82"
#(define shift-clef-at-line-begin
(lambda (grob)
;; If at line-start, this Clef is usually aligned with the main Clef.
;; Only for this case we try to move this clef towards the first
;; NoteColumn
(if (eqv? (ly:item-break-dir grob) 1)
(let* ((col (ly:item-get-column grob))
(min-dist (ly:grob-object col 'minimum-distances))
;; We try to find the next PaperColumn, hopefully with the
;; first event initiating a NoteColumn
(pap-col-dists
(filter
(lambda (x)
(and (pair? x)
(ly:grob? (car x))
(eq? (grob::name (car x)) 'PaperColumn)))
min-dist)))
;; Only proceed if a PaperColumn is found
(if (pair? pap-col-dists)
(let*(;; TODO sorting may be superfluous.
(sorted-pap-col-dists
(sort
pap-col-dists
(lambda (p q) (< (cdr p) (cdr q)))))
;; The relevant PaperColumn with distance.
(rel-pap-col-dist
(car sorted-pap-col-dists))
;; The relevant PaperColumn.
(pap-col
(car rel-pap-col-dist))
;; Clef's X-extent
(x-ext (ly:grob-property grob 'X-extent))
(space-alist
(ly:grob-property grob 'space-alist))
(sys (ly:grob-system grob))
;; Clef's X-extent relative to System.
(clef-grob-x-ext
(ly:grob-extent grob sys X))
;; A hackish method to get the relevant NoteColumn.
;; 'id is set in `clefTst´-function.
;; And here used for selection.
;; Lateron we want to move the clef relying only
;; on the (possible) Accidentals of _this_ NoteColumn,
;; not on Staff's AccidentalPlacement
(rel-nc
(filter
(lambda (g)
(and
(grob::has-interface g 'note-column-interface)
(equal? (ly:grob-property g 'id) "this")))
;; TODO do we need to check for ly:grob-array?
(ly:grob-array->list
(ly:grob-object pap-col 'elements))))
;; TODO if there are several entries in rel-nc,
;; simple car is likely insufficient
(rel-nc-grob-x-ext
(ly:grob-extent (car rel-nc) sys X))
;; Get the relevant NoteHeads
(nhs-array (ly:grob-object (car rel-nc) 'note-heads))
(nhs-list
(if (ly:grob-array? nhs-array)
(ly:grob-array->list nhs-array)
'()))
;; And their Accidentals
(raw-accs
(map
(lambda (nh)
(ly:grob-object nh 'accidental-grob))
nhs-list))
(accs
(remove null? raw-accs))
;; Get the left coordinate of most left Accidental
(most-left-acc-left-coord
(apply
min
;; If no Accidentals, use NoteCoulmn extent instead
(car rel-nc-grob-x-ext)
(map
(lambda (acc)
(car (ly:grob-extent acc sys X)))
accs)))
(amount
(-
;; As 1. step we move the clef towards the
;; NoteColumn and half clef's x-ext back.
;; The clef's left edge is now algned with left
;; edge of the NoteColumn ot the most left
;; Accidental
most-left-acc-left-coord
(interval-center x-ext)
;; Next we move the Clef to the left relying
;; on the relevant NoteColumns X-dimension
(interval-length rel-nc-grob-x-ext)
;; The default Clef doesn't sit on zero-X
;; thus we move it back this amount
(car clef-grob-x-ext)
;; Finally we apply the amount we get from
;; Clef.space-alist.next-note
(cdr (assoc-get 'next-note space-alist)))))
;; Very little moving is rather disturbing,
;; thus we provide a threshold
(if (> amount 1.5)
(ly:grob-translate-axis! grob amount X))))))))
\layout {
\context {
\Voice
\name "ClefVoice"
\alias "Voice"
\consists "Clef_engraver"
clefGlyph = #"clefs.F"
middleCPosition = #6
clefPosition = #-8
explicitClefVisibility = ##(#f #t #t)
\override Clef.full-size-change = ##t
\override Clef.font-size = #-4
\override Clef.space-alist.next-note = #'(fixed-space . 1)
%% If adjusting clef at line-begin is not desired, comment the line below
%% and the NoteColumn.id-override in `clefTst´
\override Clef.after-line-breaking = #shift-clef-at-line-begin
}
%% probably let ClefVoice be accepted by other contexts too
\context {
\Staff
\accepts "ClefVoice"
}
}
clefTst =
#(define-music-function (m1 m2) (ly:music? ly:music?)
(ly:music-set-property! m2 'elements
(let* ((m2-elts (ly:music-property m2 'elements))
(idx
(list-index
(lambda (m) (or (music-is-of-type? m 'note-event)
(music-is-of-type? m 'event-chord)))
m2-elts)))
(call-with-values
(lambda () (split-at m2-elts idx))
(lambda (a b)
(append
a
(list
#{
\context ClefVoice = "ClefVoice" {
%% Sometimes needed
\override Staff.TimeSignature.space-alist.clef =
#'(fixed-space . 1)
%% Mmmh, this is a Score-override, may cause problems ...
\temporary
\override Score.BreakAlignment.before-line-breaking =
#(lambda (grob)
(if (eqv? (ly:item-break-dir grob) 0)
(ly:grob-set-property! grob 'break-align-orders
(make-vector 3 '(span-bar
breathing-sign
staff-bar
key-cancellation
key-signature
time-signature
clef)))))
\voiceTwo
%% Hackish ...
\once \override NoteColumn.id = "this"
#(make-sequential-music b)
\revert Score.BreakAlignment.before-line-breaking
}
#}))))))
#{ << $m1 $m2 >> #})
\new PianoStaff <<
\new Staff = "right" {
\repeat unfold 8 { c'8_[ b''' b''' c'] } |
}
\new Staff = "left" \relative c'' {
\key ces \major
c8 g'' a g,, \clefTst { <fis ais cis> g } { c,,,4 } a'''8 g |
\clefTst { <fis ais cis>8 g } { s8 cis,,,16 s } a'''8 g c g a g |
\break
\clefTst { <fis ais cis>8 g } { <ces,,, ees>4 } a'''8 g c g a g |
c8 g'' a g,, \clefTst { <fis ais cis> g } { s ces,,,8 } a'''8 g |
}
>>
HTH,
Harm
- Re: treble and bass clef simultaneously, (continued)
Re: treble and bass clef simultaneously, Andrew Bernard, 2019/03/27
Re: treble and bass clef simultaneously, Thomas Morley, 2019/03/27