Re: \vshape and custom curve-stencil for TextSpanner

2022-07-23 Thread Thomas Morley
Am Sa., 23. Juli 2022 um 16:06 Uhr schrieb Jean Abou Samra :
>
> Hi Harm,
>
>
> Le 23/07/2022 à 10:59, Thomas Morley a écrit :
> > I'm attempting to create a s-curve stencil for TextSpanner.
> > While so far all works as wished and it is possibel to use \shape,
> > \vshape doesn't print the control-points.
> >
> > What am I missing?
>
>
> \shape works because it's an override/tweak to the control-points
> property, and your code reads this property.
>
> \vshape is implemented with separate grobs, ControlPoint and
> ControlPolygon. This is so that you can override their basic
> properties (color, layer, thickness, ...) independently from the
> bezier grob. They are created by the Show_control_points_engraver,
> which acknowledges bezier curve grobs and reads their
> show-control-points-property. Your custom TextSpanner isn't
> recognized because it doesn't have the bezier-curve-interface,
> and this is what Show_control_points_engraver acknowledges.

Thanks, for your detailed explanation.
To get around it one could do:

#(define (add-to-interfaces iface name grob-descriptions-alist)
  (map
(lambda (x)
  (if (eq? (car x) name)
  (let* (;; Use `list-copy' like `completize-grob-entry' in
 ;; scm/define-grobs.scm
 (grob-entry (map list-copy (cdr x)))
 ;; Though why here again?
 (meta-entry (map list-copy (assoc-get 'meta grob-entry)))
 ;; and not here?
 (ifaces-entry
  (assoc-get 'interfaces meta-entry)))
(set! ifaces-entry (cons iface ifaces-entry))
(set! meta-entry (assoc-set! meta-entry 'interfaces ifaces-entry))
(set! grob-entry (assoc-set! grob-entry 'meta meta-entry))
(cons name grob-entry))
  x))
   grob-descriptions-alist))

\layout {
  \context {
\Global
\grobdescriptions
  #(add-to-interfaces
'bezier-curve-interface
'TextSpanner
all-grob-descriptions)
  }
}

> Do you have a specific reason to use a TextSpanner? How
> about using a Slur?

Well, I need to directly connect two notes/rests, probably with a lot
of other stuff in between.
For this connection several styles are possible
(1) A straight line (maybe dashed or dotted)
Thus TextSpanner was my first thought. Alas, in most cases the line will
not be horizontal so I need some stencil override anyway.
Pretty simple, though, can be made to work automatically.
(2) A curve, probably a s-curve.
Thus current thread topic
(3) A multiple kneed line:
 
|___||
 v
(the graphic will likely not survive mail delivery unchanged, though
maybe you can imagine it)

To summarize, all three possibilities will need other stencils.
If control-points are available (Slur) it is probably not hard to get to (1).
For (2), a Slur may be good out of the box, otherwise vshape will always work.
For kneed lines (3), make connected-path-stencil may work.

All three possibilities can be made to work with TextSpanner and Slur.
I think I have to experiment, what works out better.

Thanks,
  Harm



Re: \vshape and custom curve-stencil for TextSpanner

2022-07-23 Thread Jean Abou Samra

Hi Harm,


Le 23/07/2022 à 10:59, Thomas Morley a écrit :

I'm attempting to create a s-curve stencil for TextSpanner.
While so far all works as wished and it is possibel to use \shape,
\vshape doesn't print the control-points.

What am I missing?



\shape works because it's an override/tweak to the control-points
property, and your code reads this property.

\vshape is implemented with separate grobs, ControlPoint and
ControlPolygon. This is so that you can override their basic
properties (color, layer, thickness, ...) independently from the
bezier grob. They are created by the Show_control_points_engraver,
which acknowledges bezier curve grobs and reads their
show-control-points-property. Your custom TextSpanner isn't
recognized because it doesn't have the bezier-curve-interface,
and this is what Show_control_points_engraver acknowledges.
Do you have a specific reason to use a TextSpanner? How
about using a Slur?



Code below.
Thanks to Jean how fixed make-path-stencil!



You're welcome :-)

Best,
Jean




\vshape and custom curve-stencil for TextSpanner

2022-07-23 Thread Thomas Morley
Hi,

I'm attempting to create a s-curve stencil for TextSpanner.
While so far all works as wished and it is possibel to use \shape,
\vshape doesn't print the control-points.

What am I missing?

Code below.
Thanks to Jean how fixed make-path-stencil!

Thanks,
  Harm

\version "2.23.11"

#(define (make-s-curve-stencil line-thickness thickness control-points)
  (let* ((start-pt (car control-points))
 (end-pt (last control-points))
 (lngth (- (car end-pt) (car start-pt)))
 (second-cp (second control-points))
 (third-cp (third control-points))
 (second-delta
   (* (- (car second-cp) (car start-pt)) (/ thickness (/ lngth 2
 (second-out
   (cons (car second-cp)
 (+ (cdr second-cp) second-delta)))
 (second-in
   (cons (car second-cp)
 (- (cdr second-cp) second-delta)))
 (third-delta
   (* (- (car end-pt) (car third-cp)) (/ thickness (/ lngth 2
 (third-out
   (cons (car third-cp)
 (+ (cdr third-cp) third-delta)))
 (third-in
   (cons (car third-cp)
 (- (cdr third-cp) third-delta)))
 (coord-list
   (list
 start-pt
 second-out
 third-out
 end-pt
 third-in
 second-in)))
((@@ (lily) make-bezier-sandwich-stencil) coord-list line-thickness)))

#(define horizontal-spanner-cps
  (lambda (grob)
(let* ((left-info (ly:grob-property grob 'left-bound-info))
   (right-info (ly:grob-property grob 'right-bound-info))
   (left-x (assoc-get 'X left-info))
   (right-x (assoc-get 'X right-info))
   (lngth (- right-x left-x))
   (height 2)
   (cp-2 (cons (* lngth 0.25) height))
   (cp-3 (cons (* lngth 0.75) (- height
  (list
'(0 . 0)
cp-2
cp-3
(cons (- right-x left-x) 0)

#(define text-spanner::s-curve-stencil
  (lambda (grob)
(let* ((layout (ly:grob-layout grob))
   (line-thick (ly:output-def-lookup layout 'line-thickness))
   (thickness (ly:grob-property grob 'thickness 1.2))
   (thick (* line-thick thickness)))
;(box-stencil
 (make-s-curve-stencil line-thick thick
   (ly:grob-property grob 'control-points))
; 0 0)
)))

{
  \override TextSpanner.control-points = #horizontal-spanner-cps
  \override TextSpanner.show-control-points = ##t
  \override TextSpanner.stencil = #text-spanner::s-curve-stencil

  \vshape #'((0 . 0)(0 . 10)(0 . -10)(0 . 0)) TextSpanner
  b1\startTextSpan
  b\stopTextSpan
}