lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: `\offsetPosition` fails


From: Jean Abou Samra
Subject: Re: `\offsetPosition` fails
Date: Sat, 11 Feb 2023 19:14:57 +0100
User-agent: Evolution 3.46.3 (3.46.3-1.fc37)

Le samedi 11 février 2023 à 15:01 +0000, Werner LEMBERG a écrit :


I'm using the `\offsetPosition` command
([https://lsr.di.unimi.it/LSR/Item?id=748](https://lsr.di.unimi.it/LSR/Item?id=748)).  Unfortunately, it fails in
a multi-staff, real-world piece: it has zero effect, and I don't know
why.  What could be the cause for that?  If I had a hint, creating an
MWE would perhaps be more straightforward...

Interestingly, using the 'deprecated' part of this snippet instead I
get warnings like

  cyclic dependency: calculation-in-progress encountered for Slur.positions

but it actually works...

I can reproduce it by just adding \break in the original snippet. It fails except on the first system. This is because it assumes that Slur.control-points is still set to its original callback at the time after-line-breaking is run, which isn't true if something like ly:side-position-interface::move-to-extremal-staff, in BarNumber.after-line-breaking, reads control-points earlier, making (ly:grob-property-data grob 'control-points) return the computed value. A good example of how after-line-breaking can be fragile.

Try

\version "2.24.0"

%% http://lsr.di.unimi.it/LSR/Item?id=748

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% A function to modify the shape of slurs by offsetting the positions property
% from default control-point values. Setting either y1 or y2 to zero will leave
% that attachment-point unchanged. Syntax: \offsetPositions #'(y1 . y2)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

offsetPositions =
#(define-music-function (offsets) (pair?)
  #{
    \once \override Slur.control-points =
      #(lambda (grob)
         (match-let* ((((_ . y1) _ _ (_ . y2)) (ly:slur::calc-control-points grob)))
           (set! (ly:grob-property grob 'positions)
                 (cons (+ y1 (car offsets))
                       (+ y2 (cdr offsets))))
           (ly:slur::calc-control-points grob)))
  #})

\relative c'' {
  c4(^"default" c, d2)
  \offsetPositions #'(0 . 1)
  c'4(^"(0 . 1)" c, d2)
  \break
  \offsetPositions #'(0 . 2)
  c'4(^"(0 . 2)" c, d2)
  \bar "||"
  \break
  g4(^"default" a d'2)
  \offsetPositions #'(1 . 0)
  g,,4(^"(1 . 0)" a d'2)
  \offsetPositions #'(2 . 0)
  g,,4(^"(2 . 0)" a d'2)
}

I can see why the original snippet uses after-line-breaking: using ly:slur::calc-control-points directly here is suboptimal (needs updating if the default changes). The use of ly:grob-set-property! isn't wonderful either. Unfortunately, the slur code would need to be structured a bit differently to get rid of the latter one, although you could, if you care enough and with a bit more effort, address the former by creating a variant of grob-transformer passing the raw original callback to the transformer instead of the value it computes.

Attachment: signature.asc
Description: This is a digitally signed message part


reply via email to

[Prev in Thread] Current Thread [Next in Thread]