Am Mi., 13. Apr. 2022 um 17:57 Uhr schrieb Jean Abou Samra <j...@abou-samra.fr>: > > Le 13/04/2022 à 17:03, Thomas Morley a écrit : > > Am Di., 12. Apr. 2022 um 11:54 Uhr schrieb Jean Abou Samra > > <j...@abou-samra.fr>: > >> Le 12/04/2022 à 11:16, Thomas Morley a écrit : > > [...] > >>> In many details DurationLine was tailored after Glissando and > >>> Glissando _is_ effected by the breathing sign. > > [...] > > > >> Well, if the goal is to have DurationLine similar to Glissando, > >> how about reusing line-spanner-interface code? I haven't reviewed > >> the code very thoroughly, but I assumed there was a difference > >> warranting a different code path. If you put > >> ly:line-spanner::calc-{left,right}-bound-info in > >> DurationLine.{left,righ}-bound-info, that gives you X values for free > >> in the bound info properties. Would that solve the problem? > > If I go for ly:line-spanner::calc-{left,right}-bound-info then > > > > \layout { > > \context { > > \Voice > > \consists Duration_line_engraver > > } > > } > > > > { b1\- } > > > > errors with > > "programming error: extremal broken spanner's bound has no parent > > vertical axis group" > > More complex examples may add: > > "programming error: bound item has no parent vertical axis group" > > Both coming from `ly:line-spanner::calc-right-bound-info' based upon > > `Line_spanner::calc_bound_info' in /lily/line-spanner.cc > > > > As a mere user I'd say: "Nice error-message, but why should I care...?" > > > > As a programmer, I doubt the example above can be made working with > > ly:line-spanner::calc-right-bound-info. > > At least, I don't know how. > > > Oh, I'm sorry, I missed that detail of my own code. A DurationLine will > always be horizontal, thus you can and should use > ly:horizontal-line-spanner::calc-{left,right}-bound-info (with 'horizontal' > in the name). The difference is that the functions without 'horizontal' > try to compute vertical positions. This falls apart here, for understandable > reasons: the right bound of your DurationLine is a NonMusicalPaperColumn, > so how would one tell where the line should end vertically?
Using ly:horizontal-line-spanner::calc-{left,right}-bound-info makes for huge simplifications. Alas, it introduces a minor and reintroduces a major problem. The minor: the X-value depends now on attach-dir. For the start of the DurationLine this is ofcourse RIGHT. But if starting at a skip, left-bound is PaperColumn there we would want LEFT. Can be fixed by accurate conditions. Count it as done. The major: `ly:horizontal-line-spanner::calc-right-bound-info' and `unbroken-or-last-broken-spanner?' (and friends) don't agree what's the last part of the spanner. To illustrate: \version "2.23.7" \layout { \context { \Voice \consists "Duration_line_engraver" } } { \override DurationLine.bound-details.right.foo = "I am last part (bound-details)" \override DurationLine.bound-details.right-broken.foo = "I am not last part (bound-details)" \override DurationLine.after-line-breaking = #(lambda (grob) (pretty-print (if (unbroken-or-last-broken-spanner? grob) "I am last part (unbroken-or-last-broken-spanner?)" "I am not last part (unbroken-or-last-broken-spanner?)")) (pretty-print (assoc-get 'foo (ly:horizontal-line-spanner::calc-right-bound-info grob)))) b1\- } => "I am last part (unbroken-or-last-broken-spanner?)" "I am not last part (bound-details)" The problem occurs if we have a broken DurationLine with end-items running to the very end of the score. To fix it one would again need something like: { \override DurationLine.bound-details = #(grob-transformer 'bound-details (lambda (grob orig) (if (end-broken-spanner? grob) (cons (cons 'right-broken (cons '(end-style . arrow) (assoc-get 'right-broken orig))) orig) orig))) b1\- \break s1 \break s1 \bar "|." } Or like \lastEndStyle which you cleared with commit 46671d13257f6ad68d1778a1cc850e59116c856a Author: Jean Abou Samra <j...@abou-samra.fr> Date: Wed Dec 29 00:16:46 2021 +0100 Fix broken spanner functions They were broken (pun intended) on spanners of which one bound is a non-musical column at a system boundary. For example, unbroken-or-last-broken-spanner? would return false on a spanner running to the NonMusicalPaperColumn at the end of a score. This fixes the known issue with duration lines running to the end of the piece, and will be needed in a refactoring of spanner-placement treatment for balloon-interface. While at it, document these functions. This is unfortunate. Any chance making `ly:horizontal-line-spanner::calc-right-bound-info' and friends identify the last spanner-part correctly, i.e. like `unbroken-or-last-broken-spanner?' ? At any rate, many thanks for the hint to ly:_horizontal:-line-spanner::calc-left/right-bound-info. I may remember wrong, but I think I tried ly:line-spanner::calc-left/right-bound-info already while implementing DurationLine and excluded it for the known reasons, but was not aware that ly:_horizontal:-line-spanner::calc-left/right-bound-info exists at all. Well, my bad, though, any chance to document ly:horizontal-line-spanner::calc-left-bound-info-and-text ly:horizontal-line-spanner::calc-left/right-bound-info ly:line-spanner::calc-left/right-bound-info in IR 4. Scheme functions? > >> If there is a reason to keep DurationLine calculations separate, you > >> could go for using ly:generic-bound-extent. The line-spanner-interface > >> uses its C++ equivalent internally. > > Didn't try this so far. > > But the description: > > "Function: ly:generic-bound-extent grob common > > Determine the extent of grob relative to common along the x axis, > > finding its extent as a bound when it a has bound-alignment-interfaces > > property list set and otherwise the full extent." > > is kryptic to say the least. > > > It's in a sense similar to the (so far nonexistent/C++-only) function > ly:axis-group-interface::staff-extent we discussed, except that it > doesn't filter grobs for having a certain grob in their ancestry, > but for having one of certain interfaces, captured in the > bound-alignment-interfaces property. E.g., for NonMusicalPaperColumn, > this property defaults to '(break-alignment-interface), which means > that > > (ly:generic-bound-extent [NonMusicalPaperColumn] [System]) > > gives you the extent of the elements of the NonMusicalPaperColumn > that are part of a BreakAlignment, i.e. grobs with the > break-aligned-interface, > like BarLine, KeySignature, etc., but not those that are outside > of a BreakAlignment, i.e. those having the break-*aligned*-interface > (tricky difference, I know, I always need to look up which is 'alignable' > and which is 'aligned' ...), namely MetronomeMark, RehearsalMark, ... > There are some slightly fussy details, but that's the idea. Is that > clear? Your description is far better than the doc-string. There I stumbled across "extent as a bound", with not the slightest idea what this could mean, especially compared with "the full extent". In general I find typical usage examples like > (ly:generic-bound-extent [NonMusicalPaperColumn] [System]) very helpful. Best, Harm