Am Fr., 3. Juni 2022 um 22:40 Uhr schrieb Aaron Hill <lilyp...@hillvisions.com>: > > On 2022-06-03 10:10 am, Paul Hodges wrote: > > I find that even using shorten-pair (with a negative first value) > > fails to do this as I expected. So now I don't know any way to print > > the bracket with the preferred layout... > > You would want to adjust the X-positions, so that the TupletNumber is > centered properly. See the difference: > > %%%% > \version "2.22.0" > > { > \offset shorten-pair #'(-1 . 0) > \tuplet 3/2 \relative { f'4 g a } > > \offset X-positions #'(-1 . 0) > \tuplet 3/2 \relative { f'4 g a } > } > %%%% > > Since an offset of one staff space is only approximate, you would need > to consult the bounds of the NoteColumns directly: > > %%%% > { > \override TupletBracket.X-positions = > #(lambda (grob) > ;; NOTE: The logic here does not fully replace > ;; ly:tuplet-bracket::calc-x-positions > (let* ((nc (ly:grob-object grob 'note-columns)) > (xref (ly:grob-common-refpoint-of-array grob nc X)) > (lb (ly:spanner-bound grob LEFT)) > (lbex (ly:generic-bound-extent lb xref)) > (lbrc (ly:grob-relative-coordinate lb xref X)) > (rb (ly:spanner-bound grob RIGHT)) > (rbex (ly:generic-bound-extent rb xref))) > (cons (- (car lbex) lbrc) (- (cdr rbex) lbrc)))) > > \tuplet 3/2 \relative c' { <e fis>4 g <a b> } > \tuplet 3/2 \relative c'' { <ees f>4 d <b c> } > } > %%%% > > Tuplet_Bracket::calc_x_positions relies on Item::get_x_bound_item, which > includes the logic to prefer using the Stem of a NoteColumn as the bound > item if the direction matches. > > The code above simply ignores that behavior and computes X-positions > purely based on the extents of the NoteColumns. Mind you, > Tuplet_Bracket::calc_x_positions does more work to account for > properties like connect-to-neighbor, break-overshoot, and > full-length-to-extent, so this is not a true replacement/fix. > > > -- Aaron Hill >
Hi Aaron, I had a similar idea, though, not ignoring `ly:tuplet-bracket::calc-x-positions', but calculating correction values. Ofcourse it's more complicated. At least it works for broken TupletBracket as well: \version "2.23.9" #(define tuplet-bracket::wrap-all-note-heads (grob-transformer 'X-positions (lambda (grob orig) ;; `orig' is the result of `ly:tuplet-bracket::calc-x-positions' ;; we calculate some left/right corrections adding them to it. ;; Because `orig' places TupletBracket ends not really centered above ;; the stems we need to take TupletBracket and Stem thickness into account (let* ((thick (ly:grob-property grob 'thickness)) (line-thick (ly:staff-symbol-line-thickness grob)) (used-thick (* thick line-thick)) (right-bound (ly:spanner-bound grob RIGHT)) (left-bound (ly:spanner-bound grob LEFT)) ;; Don't change `orig' if left or right bound is not NoteColumn (add-left (if (grob::has-interface left-bound 'note-column-interface) (+ (/ used-thick 2) (let* ((left-stem (ly:grob-object left-bound 'stem)) (lst-dir (ly:grob-property left-stem 'direction)) (lst-th (ly:grob-property left-stem 'thickness)) (lst-coord (ly:grob-relative-coordinate left-stem left-bound X)) (lb-X-ext (ly:grob-property left-bound 'X-extent))) (if (positive? lst-dir) (- lst-coord) (- (car lb-X-ext) (/ (* lst-th line-thick) 2))))) 0)) (add-right (if (grob::has-interface right-bound 'note-column-interface) (let* ((rb-X-ext (ly:grob-property right-bound 'X-extent)) (right-stem (ly:grob-object right-bound 'stem)) (rst-coord (ly:grob-relative-coordinate right-stem right-bound X))) (+ (- rst-coord) (/ used-thick -2) (cdr rb-X-ext))) 0))) (cons (+ (car orig) add-left) (+ (cdr orig) add-right)))))) \relative c'' { \override TupletBracket.X-positions = #tuplet-bracket::wrap-all-note-heads %% To get all broken parts visible: \override TupletBracket.bracket-visibility = ##t \voiceOne \times 2/3 { <c>4 q q } \voiceTwo \times 2/3 { <c> q \bar "" \break q } \voiceOne \times 2/3 { <c d> q \bar "" \break q } \voiceTwo \times 2/3 { <c d> \bar "" \break q q } } Cheers, Harm