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.
signature.asc
Description: This is a digitally signed message part
