|
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.
signature.asc
Description: This is a digitally signed message part
[Prev in Thread] | Current Thread | [Next in Thread] |