Using path expressions to override stencils
The stencil expression path can be used to override stencils for any printed object. The advantage of using path instead of embedded-ps is that path is supported by both the PostScript and SVG backends, and uses the same syntax.
There are six commands available to use in a path expression, and all commands use prefix notation. The six commands are moveto, rmoveto, lineto, rlineto, curveto, and rcurveto. Note that the commands that begin with r are the relative variants of the other three commands.
The commands moveto, rmoveto, lineto, and rlineto take 2 arguments; they are the X and Y coordinates for the destination point.
The commands curveto and rcurveto create cubic Bézier curves, and take 6 arguments; the first two are the X and Y coordinates for the first control point, the second two are the X and Y coordinates for the second control point, and the last two are the X and Y coordinates for the destination point.
In addition this snippet shows how to create a filled stencil using path, and adds a scheme function to automatically resize custom stencils when individual staves are resized.
\version "2.24.0"
%% http://lsr.di.unimi.it/LSR/Item?id=623
%{
Note: since SVG path data needs an "M" or "m" at the
beginning to start a new subpath, every path expression
must begin with "rmoveto" (or "moveto") to work with the
SVG backend.
%}
customClefStencilOne =
#(ly:make-stencil
`(path 0.2
(rmoveto 0 0
rcurveto 0 0.75 1 0.75 1 0
rcurveto 0 -0.75 -1 -0.75 -1 0
rcurveto -1 0 -1 1.5 -0.5 1.5
rmoveto 0.5 -1.5
rcurveto -1 0 -1 -1.5 -0.5 -1.5
rmoveto 0.5 1.5
rmoveto 1 0
rcurveto 2.5 0 2.5 4 4 4
rmoveto -4 -4
rcurveto 2.5 0 2.5 -4 4 -4))
(cons -0.5 1)
(cons -3 5))
% a filled custom stencil
customClefStencilTwo =
#(ly:make-stencil
;; path line thickness is set to 0.1
`(path 0.1
;; path coordinates
(moveto 0 0
curveto 0 1 0.7 2.5 1.5 1.5
lineto 1.5 -3
closepath)
;; path cap style
round
;; path join style
round
;; path filled? #t or #f
#t)
;; horizontal extent
(cons 0 1.5)
;; vertical extent
(cons -3 2))
% scheme function to automatically resize a custom stencil
% when an individual staff is resized (uses font-size)
scaleCustomClefStencilTwo =
#(lambda (grob)
(let* ((sz (ly:grob-property grob 'font-size 0.0))
(mult (magstep sz)))
(ly:stencil-scale
customClefStencilTwo
mult mult)))
customClefOne = \override Staff.Clef.stencil = \customClefStencilOne
customClefTwo = \override Staff.Clef.stencil = \scaleCustomClefStencilTwo
normalClefs = \revert Staff.Clef.stencil
music =
\relative c' {
\customClefOne
\clef "alto"
c1 g1
\customClefTwo
\clef "bass"
c1 g1
\normalClefs
\clef "treble"
c1 g1
\clef "alto"
c1 g1
}
<<
\new Staff \with {
fontSize = #-3
\override StaffSymbol.staff-space = #(magstep -3)
\override StaffSymbol.thickness = #(magstep -3)
}
\music
\new Staff
\music
\new Staff \with {
fontSize = #2
\override StaffSymbol.staff-space = #(magstep 2)
\override StaffSymbol.thickness = #(magstep 2)
}
\music
>>