Modified slur stencil with added markup

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Modified slur stencil with added markup

Urs Liska-3
Hi,

I modified the snippet
http://lilypond.org/doc/v2.19/Documentation/snippets/text#text-center-text-below-hairpin-dynamics 
to create a slur with added centered text. It took me little effort to
adapt the snippet to work with a slur instead of a hairpin but I have
two problems I didn't manage to solve on my own. Here's the code:

\version "2.19.82"

annotatedSlur =
#(define-music-function (padding text) ((number? 1) markup?)
    #{
      \once \override Slur.after-line-breaking =
      #(lambda (grob)
         (let*
          ((stencil (ly:slur::print grob))
           (dir (ly:grob-property grob 'direction))
           (markup-stencil (grob-interpret-markup grob text))
           (new-stencil
            (ly:stencil-aligned-to
             (ly:stencil-combine-at-edge
              (ly:stencil-aligned-to stencil X CENTER)
              Y dir
              (ly:stencil-aligned-to markup-stencil X CENTER)
              padding)
             X LEFT)))
          (ly:grob-set-property! grob 'stencil new-stencil)))
    #})

{
   \annotatedSlur
   %\markup \score { c''' }
   \markup "hin."
   c''4 ( g' g' c'' )
}

The first problem is that the new stencil is incorrectly aligned
horizontally to the note heads. The *whole* new object is now aligned to
the left edge of the parent note column (rather than the center of the
note head). I might get back to some old code to figure out how to
retrieve the necessary data to calculate an offset of half the notehead,
but before going down that road I'd like to know if there's not an
easier way to combine two stencils while keeping one of them (the slur)
exactly where it was before.

The alignment problem is especially problematic when the "markup" is
wider than the slur.


The second problem is that this function doesn't increase the new
stencil's notion of its Y-extent. Concretely: this doesn't push the
whole thing downward. You can see this from the attached image showing
how the added \markup \score is cut off at the upper paper edge.

I tried to calculate the height of the markup and add it to the
stencil's Y-extent, but this didn't work. I can see why this won't have
any effect in after-line-breaking, but is there any way to make the
modified slur aware of its modified height? Is there a way to calculate
the markup's dimensions already in the music-function stage?

I had no luck with that. I succeeded to retrieve the markup's extent by
inserting another callback before-line-breaking, but I failed to
essentially *adding that height to the original slur's Y-extent. (Which
somewhat makes sense since that information may not be readily available
yet at that stage ...)

Any suggestions?

Thanks
Urs


_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user

document.png (10K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Modified slur stencil with added markup

Torsten Hämmerle
Hi Urs,

The centering of the slur stencil destroys its alignment (i.e. reference
point), so I'd just leave it alone and center-align the text by explicitly
calculating the necessary markup x shift from the stencil extents.


%%%%%%%%%%%%%%%%%%
\version "2.19.82"

annotatedSlur =
#(define-music-function (padding text) ((number? 1) markup?)
   #{
     \once \override Slur.after-line-breaking =
     #(lambda (grob)
        (let*
         ((stencil (ly:slur::print grob))
          (dir (ly:grob-property grob 'direction))
          (markup-stencil (grob-interpret-markup grob text))
          (shift (- (interval-center (ly:stencil-extent stencil X))
                   (interval-center (ly:stencil-extent markup-stencil X))))
          (new-stencil
           (ly:stencil-combine-at-edge
            stencil
            Y dir
            (ly:stencil-translate-axis markup-stencil shift X)
            padding)))
         (ly:grob-set-property! grob 'stencil new-stencil)))
   #})

{
  \annotatedSlur
  %\markup \score { c''' }
  \markup "hin."
  c''4 ( g' g' c'' )
}
%%%%%%%%%%%%%%%%%%

HTH,
Torsten



--
Sent from: http://lilypond.1069038.n5.nabble.com/User-f3.html

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: Modified slur stencil with added markup

Urs Liska-3
Hi Torsten,


Am 12.10.2018 um 00:56 schrieb Torsten Hämmerle:

> Hi Urs,
>
> The centering of the slur stencil destroys its alignment (i.e. reference
> point), so I'd just leave it alone and center-align the text by explicitly
> calculating the necessary markup x shift from the stencil extents.
>
>
> %%%%%%%%%%%%%%%%%%
> \version "2.19.82"
>
> annotatedSlur =
> #(define-music-function (padding text) ((number? 1) markup?)
>     #{
>       \once \override Slur.after-line-breaking =
>       #(lambda (grob)
>          (let*
>           ((stencil (ly:slur::print grob))
>            (dir (ly:grob-property grob 'direction))
>            (markup-stencil (grob-interpret-markup grob text))
>            (shift (- (interval-center (ly:stencil-extent stencil X))
>                     (interval-center (ly:stencil-extent markup-stencil X))))
>            (new-stencil
>             (ly:stencil-combine-at-edge
>              stencil
>              Y dir
>              (ly:stencil-translate-axis markup-stencil shift X)
>              padding)))
>           (ly:grob-set-property! grob 'stencil new-stencil)))
>     #})
>
> {
>    \annotatedSlur
>    %\markup \score { c''' }
>    \markup "hin."
>    c''4 ( g' g' c'' )
> }
> %%%%%%%%%%%%%%%%%%
>
> HTH,
> Torsten

Thank you very much, this indeed fixes the horizontal alignment problem
in a clean and understandable way - although I wouldn't have known how
to do it. What is 'interval-center'? Grepping the source doesn't show a
definition, so I'd assume it's in the C++ domain? I haven't found
anything about that in the documentation (or through Google).

Urs

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: Modified slur stencil with added markup

Thomas Morley-2
Am Fr., 12. Okt. 2018 um 09:59 Uhr schrieb Urs Liska <[hidden email]>:

> What is 'interval-center'? Grepping the source doesn't show a
> definition, so I'd assume it's in the C++ domain? I haven't found
> anything about that in the documentation (or through Google).

Hi Urs,

~/lilypond-git (master)$ git grep "interval-center"
Documentation/misc/ChangeLog-2.10:      (interval-center): new function.
scm/bar-line.scm:                              (interval-center
(staff-symbol-line-span
scm/bar-line.scm:             (set! anchor (interval-center x-extent))
scm/bar-line.scm:             (set! anchor (interval-center
scm/define-markup-commands.scm:         (center (interval-center
(ly:stencil-extent number-stencil Y)))
scm/define-markup-commands.scm:
       (car num-x) (- (interval-center num-y) dy)
scm/define-markup-commands.scm:
       (cdr num-x) (+ (interval-center num-y) dy))
scm/define-markup-commands.scm:                     (interval-center
(ly:stencil-extent rest-glyph Y))
scm/define-markup-commands.scm:                    (interval-center
(ly:stencil-extent mmr-stil X)))
scm/define-markup-commands.scm:                    (interval-center
(ly:stencil-extent mmr-number-stil X))))
scm/lily-library.scm:(define-public (interval-center x)
scm/output-lib.scm:    (interval-center note-head-w)))
scm/output-lib.scm:         (c (interval-center height)))
scm/output-lib.scm:         (y-center (interval-center elt-y-ext)))
scm/output-lib.scm:     (interval-center extent))))
scm/stencil.scm:                            (interval-center x-ext)
scm/stencil.scm:                            (interval-center y-ext))))))
scm/stencil.scm:                            (interval-center x-ext)
scm/stencil.scm:                            (interval-center y-ext))))))
scm/stencil.scm:                            (interval-center x-ext)
scm/stencil.scm:                            (interval-center y-ext))))))
scm/stencil.scm:                            (cons 0 (interval-center extent))))

So it's defined in scm/lily-library.scm

Cheers,
  Harm

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: Modified slur stencil with added markup

Torsten Hämmerle
In reply to this post by Urs Liska-3
Urs Liska-3 wrote
> What is 'interval-center'?


Hi Urs,

Harm already revealed where interval-center is being defined.

But why did I use it?
A stencil x-extent is a pair of left and right extent, and in order to know
the total extent, we'll have to add up (car x-extent) and (cdr x-extent) and
divide it by 2 in order to get the centre. This could be done manually or by
using interval-center.

Using the horizontal centre of both markup and slur, the necessary x-shift
can be easily calculated.

In this case, it is important to know that ly:stencil-combine-at-edge uses
the reference point for alignment and the stencil will stick out to the left
if the left extent is negative.
The slur has a positive (!) left extent, and that's why it is shiftet to the
right with regards to the reference point (at the left edge of the
notehead).
In your original attempt, centering the slur destroyed this slight shift and
moved the whole lot to the left.

All the best,
Torsten



--
Sent from: http://lilypond.1069038.n5.nabble.com/User-f3.html

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: Modified slur stencil with added markup

pablocordal
In reply to this post by Thomas Morley-2
Hi Urs and Torsten,

This snippet is exactly what I need. I'm trying to test it, but when I copy
your code in Frescobaldi (which uses Lilypond underneath) and try to compile
it I receive this error:

 error: syntax error, unexpected LYRIC_ELEMENT
  \markup  "hin."
                   
I don't know much about Lilypond code, so please can you please help me just
to make it work?

Thank you. Best regards





--
Sent from: http://lilypond.1069038.n5.nabble.com/User-f3.html

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: Modified slur stencil with added markup

Thomas Morley-2
Am So., 4. Nov. 2018 um 16:38 Uhr schrieb pablocordal <[hidden email]>:

>
> Hi Urs and Torsten,
>
> This snippet is exactly what I need. I'm trying to test it, but when I copy
> your code in Frescobaldi (which uses Lilypond underneath) and try to compile
> it I receive this error:
>
>  error: syntax error, unexpected LYRIC_ELEMENT
>   \markup  "hin."
>
> I don't know much about Lilypond code, so please can you please help me just
> to make it work?
>
> Thank you. Best regards

You likely use 2.18.2
With this version the possibility to use optional arguments is limited
and does not work for the current coding.

Please consider to upgrade to 2.19.82.

If you want to stay with 2.18 some adjustments in the function are
needed, also, the function must be called with _two_ arguments: the
padding-value and the markup-text.

\version "2.18.2"

annotatedSlur =
#(define-music-function (parser location padding text) (number? markup?)
   #{
     \once \override Slur.after-line-breaking =
     #(lambda (grob)
        (let*
         ((stencil (ly:slur::print grob))
          (dir (ly:grob-property grob 'direction))
          (markup-stencil (grob-interpret-markup grob text))
          (shift (- (interval-center (ly:stencil-extent stencil X))
                   (interval-center (ly:stencil-extent markup-stencil X))))
          (new-stencil
           (ly:stencil-combine-at-edge
            stencil
            Y dir
            (ly:stencil-translate-axis markup-stencil shift X)
            padding)))
         (ly:grob-set-property! grob 'stencil new-stencil)))
   #})

{
  \annotatedSlur
  %\markup \score { c''' }
  #1
  \markup  "hin."
  c''4( g' g' c'' )
}

HTH,
  Harm

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: Modified slur stencil with added markup

pablocordal
Thank you very very very much Harm. Now it works perfectly, it is just what I needed!.

Best regards

El dom., 4 nov. 2018 a las 17:20, Thomas Morley (<[hidden email]>) escribió:
Am So., 4. Nov. 2018 um 16:38 Uhr schrieb pablocordal <[hidden email]>:
>
> Hi Urs and Torsten,
>
> This snippet is exactly what I need. I'm trying to test it, but when I copy
> your code in Frescobaldi (which uses Lilypond underneath) and try to compile
> it I receive this error:
>
>  error: syntax error, unexpected LYRIC_ELEMENT
>   \markup  "hin."
>
> I don't know much about Lilypond code, so please can you please help me just
> to make it work?
>
> Thank you. Best regards

You likely use 2.18.2
With this version the possibility to use optional arguments is limited
and does not work for the current coding.

Please consider to upgrade to 2.19.82.

If you want to stay with 2.18 some adjustments in the function are
needed, also, the function must be called with _two_ arguments: the
padding-value and the markup-text.

\version "2.18.2"

annotatedSlur =
#(define-music-function (parser location padding text) (number? markup?)
   #{
     \once \override Slur.after-line-breaking =
     #(lambda (grob)
        (let*
         ((stencil (ly:slur::print grob))
          (dir (ly:grob-property grob 'direction))
          (markup-stencil (grob-interpret-markup grob text))
          (shift (- (interval-center (ly:stencil-extent stencil X))
                   (interval-center (ly:stencil-extent markup-stencil X))))
          (new-stencil
           (ly:stencil-combine-at-edge
            stencil
            Y dir
            (ly:stencil-translate-axis markup-stencil shift X)
            padding)))
         (ly:grob-set-property! grob 'stencil new-stencil)))
   #})

{
  \annotatedSlur
  %\markup \score { c''' }
  #1
  \markup  "hin."
  c''4( g' g' c'' )
}

HTH,
  Harm

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: Modified slur stencil with added markup

pablocordal
Hi again!
Can I propose a small modification in this funcion?

annotatedSlur =
#(define-music-function (parser location padding text) (number? markup?)
   #{
     \once \override Slur.after-line-breaking =
     #(lambda (grob)
        (let*
         ((stencil (ly:slur::print grob))
          (dir (ly:grob-property grob 'direction))
          (markup-stencil (grob-interpret-markup grob text))
          (shift (- (interval-center (ly:stencil-extent stencil X))
                   (interval-center (ly:stencil-extent markup-stencil X))))
          (new-stencil
           (ly:stencil-combine-at-edge
            stencil
            Y dir
            (ly:stencil-translate-axis markup-stencil shift X)
            padding)))
         (ly:grob-set-property! grob 'stencil new-stencil)))
   #})

Sometimes the text collides with another element, so it would be even better if the function would have another parameter for horizontal alignment. 
Any master coder can help me with this please?

Thank you. Best regards

El dom., 4 nov. 2018 a las 17:26, Pablo Cordal (<[hidden email]>) escribió:
Thank you very very very much Harm. Now it works perfectly, it is just what I needed!.

Best regards

El dom., 4 nov. 2018 a las 17:20, Thomas Morley (<[hidden email]>) escribió:
Am So., 4. Nov. 2018 um 16:38 Uhr schrieb pablocordal <[hidden email]>:
>
> Hi Urs and Torsten,
>
> This snippet is exactly what I need. I'm trying to test it, but when I copy
> your code in Frescobaldi (which uses Lilypond underneath) and try to compile
> it I receive this error:
>
>  error: syntax error, unexpected LYRIC_ELEMENT
>   \markup  "hin."
>
> I don't know much about Lilypond code, so please can you please help me just
> to make it work?
>
> Thank you. Best regards

You likely use 2.18.2
With this version the possibility to use optional arguments is limited
and does not work for the current coding.

Please consider to upgrade to 2.19.82.

If you want to stay with 2.18 some adjustments in the function are
needed, also, the function must be called with _two_ arguments: the
padding-value and the markup-text.

\version "2.18.2"

annotatedSlur =
#(define-music-function (parser location padding text) (number? markup?)
   #{
     \once \override Slur.after-line-breaking =
     #(lambda (grob)
        (let*
         ((stencil (ly:slur::print grob))
          (dir (ly:grob-property grob 'direction))
          (markup-stencil (grob-interpret-markup grob text))
          (shift (- (interval-center (ly:stencil-extent stencil X))
                   (interval-center (ly:stencil-extent markup-stencil X))))
          (new-stencil
           (ly:stencil-combine-at-edge
            stencil
            Y dir
            (ly:stencil-translate-axis markup-stencil shift X)
            padding)))
         (ly:grob-set-property! grob 'stencil new-stencil)))
   #})

{
  \annotatedSlur
  %\markup \score { c''' }
  #1
  \markup  "hin."
  c''4( g' g' c'' )
}

HTH,
  Harm

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: Modified slur stencil with added markup

pablocordal
Hi again!
Can I propose a small modification in the "annotated slur" funcion?

annotatedSlur =
#(define-music-function (parser location padding text) (number? markup?)
   #{
     \once \override Slur.after-line-breaking =
     #(lambda (grob)
        (let*
         ((stencil (ly:slur::print grob))
          (dir (ly:grob-property grob 'direction))
          (markup-stencil (grob-interpret-markup grob text))
          (shift (- (interval-center (ly:stencil-extent stencil X))
                   (interval-center (ly:stencil-extent markup-stencil X))))
          (new-stencil
           (ly:stencil-combine-at-edge
            stencil
            Y dir
            (ly:stencil-translate-axis markup-stencil shift X)
            padding)))
         (ly:grob-set-property! grob 'stencil new-stencil)))
   #})

Sometimes the text collides with another element, so it would be even better if the function would have another parameter for horizontal alignment. 
Any master coder can help me with this please?

Thank you. Best regards

El jue., 8 nov. 2018 a las 16:33, Pablo Cordal (<[hidden email]>) escribió:
Hi again!
Can I propose a small modification in this funcion?

annotatedSlur =
#(define-music-function (parser location padding text) (number? markup?)
   #{
     \once \override Slur.after-line-breaking =
     #(lambda (grob)
        (let*
         ((stencil (ly:slur::print grob))
          (dir (ly:grob-property grob 'direction))
          (markup-stencil (grob-interpret-markup grob text))
          (shift (- (interval-center (ly:stencil-extent stencil X))
                   (interval-center (ly:stencil-extent markup-stencil X))))
          (new-stencil
           (ly:stencil-combine-at-edge
            stencil
            Y dir
            (ly:stencil-translate-axis markup-stencil shift X)
            padding)))
         (ly:grob-set-property! grob 'stencil new-stencil)))
   #})

Sometimes the text collides with another element, so it would be even better if the function would have another parameter for horizontal alignment. 
Any master coder can help me with this please?

Thank you. Best regards

El dom., 4 nov. 2018 a las 17:26, Pablo Cordal (<[hidden email]>) escribió:
Thank you very very very much Harm. Now it works perfectly, it is just what I needed!.

Best regards

El dom., 4 nov. 2018 a las 17:20, Thomas Morley (<[hidden email]>) escribió:
Am So., 4. Nov. 2018 um 16:38 Uhr schrieb pablocordal <[hidden email]>:
>
> Hi Urs and Torsten,
>
> This snippet is exactly what I need. I'm trying to test it, but when I copy
> your code in Frescobaldi (which uses Lilypond underneath) and try to compile
> it I receive this error:
>
>  error: syntax error, unexpected LYRIC_ELEMENT
>   \markup  "hin."
>
> I don't know much about Lilypond code, so please can you please help me just
> to make it work?
>
> Thank you. Best regards

You likely use 2.18.2
With this version the possibility to use optional arguments is limited
and does not work for the current coding.

Please consider to upgrade to 2.19.82.

If you want to stay with 2.18 some adjustments in the function are
needed, also, the function must be called with _two_ arguments: the
padding-value and the markup-text.

\version "2.18.2"

annotatedSlur =
#(define-music-function (parser location padding text) (number? markup?)
   #{
     \once \override Slur.after-line-breaking =
     #(lambda (grob)
        (let*
         ((stencil (ly:slur::print grob))
          (dir (ly:grob-property grob 'direction))
          (markup-stencil (grob-interpret-markup grob text))
          (shift (- (interval-center (ly:stencil-extent stencil X))
                   (interval-center (ly:stencil-extent markup-stencil X))))
          (new-stencil
           (ly:stencil-combine-at-edge
            stencil
            Y dir
            (ly:stencil-translate-axis markup-stencil shift X)
            padding)))
         (ly:grob-set-property! grob 'stencil new-stencil)))
   #})

{
  \annotatedSlur
  %\markup \score { c''' }
  #1
  \markup  "hin."
  c''4( g' g' c'' )
}

HTH,
  Harm

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user