lilypond-user
[Top][All Lists]
Advanced

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

Re: DurationLine avoiding RehearsalMarks


From: Jean Abou Samra
Subject: Re: DurationLine avoiding RehearsalMarks
Date: Fri, 15 Apr 2022 13:27:38 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.7.0



Le 15/04/2022 à 13:17, Thomas Morley a écrit :
Am Fr., 15. Apr. 2022 um 12:52 Uhr schrieb Jean Abou Samra <jean@abou-samra.fr>:


Le 15/04/2022 à 11:45, Thomas Morley a écrit :
Am Fr., 15. Apr. 2022 um 10:39 Uhr schrieb Jean Abou Samra <jean@abou-samra.fr>:

Le 15/04/2022 à 10:13, Thomas Morley a écrit :
Am Mi., 13. Apr. 2022 um 17:57 Uhr schrieb Jean Abou Samra <jean@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 <jean@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 <jean@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?'
?

Ah, this one is showing up again. Yes, this is not too hard to
fix (but please allow me some time).

No problem.
If you don't mind I'll open an issue for it with the code-example above.
Meanwhile I found a different workaround, without the need to have the
apply an extra override.
If testings suceed, I'll upload a patch with the new code for DurationLine.
The workaround could be removed later easily.

The attached patch fixes it for me.

Thanks,
Jean
Will test in the evening, real life will occupy me the afternoon.
Though, at first glance:
I fear using "unbroken-or-first-broken-spanner?" will not cover middle
part(s) of a multiple broken spanner.
Shouldn't it be "unbroken-or-not-last-broken-spanner?"
?
To be defined as:
(define-public (unbroken-or-not-last-broken-spanner? spanner)
   "Is @var{spanner} either unbroken or not the last of its broken
siblings?"
   (check-broken-spanner
    #t
    (lambda (siblings)
      (not (eq? spanner (last siblings))))
    spanner))

Though, not tested.



Are you sure? unbroken-or-first-broken-spanner? is used to decide
between left and left-broken. Only the first broken spanner should
use left and not left-broken, all the others need left-broken on
top of left.

I have tested this with

\version "2.23.8"

\paper {
  ragged-right = ##t
}


\new Voice \with {
  \consists Duration_line_engraver
}
{
  \override Score.SpacingSpanner.spacing-increment = 5
  \override DurationLine.stencil = #ly:line-spanner::print
  \override DurationLine.left-bound-info = #ly:horizontal-line-spanner::calc-left-bound-info   \override DurationLine.right-bound-info = #ly:horizontal-line-spanner::calc-right-bound-info
  \override DurationLine.bound-details.left.text = "left"
  \override DurationLine.bound-details.left-broken.text = "left-broken"
  \override DurationLine.bound-details.right.text = "right"
  \override DurationLine.bound-details.right-broken.text = "right-broken"
  c'1\- \break s1 \break s1 c'1 \break
  c'1\- \break
  s1
}


which gives the attached output. Looks fine to me.


Jean

Attachment: broken-duration-lines.pdf
Description: Adobe PDF document


reply via email to

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