Using path expressions to override stencils: Difference between revisions
No edit summary |
mNo edit summary |
||
| (One intermediate revision by the same user not shown) | |||
| Line 1: | Line 1: | ||
The stencil expression <code>path</code> can be used to override stencils for any printed object. The advantage of using <code>path</code> instead of <code>embedded-ps</code> is that <code>path</code> is supported by both the PostScript and SVG backends, and uses the same syntax. | The stencil expression <code>path</code> can be used to override stencils for any printed object. The advantage of using <code>path</code> instead of <code>embedded-ps</code> is that <code>path</code> is supported by both the PostScript and SVG backends of LilyPond, and uses the same syntax. | ||
There are six commands available to use in a <code>path</code> expression, and all commands use prefix notation. The six commands are <code>moveto, rmoveto, lineto, rlineto, curveto | There are six commands available to use in a <code>path</code> expression, and all commands use prefix notation. The six commands are <code>moveto</code>, <code>rmoveto</code>, <code>lineto</code>, <code>rlineto</code>, <code>curveto</code>, and <code>rcurveto</code>. Note that the commands that begin with <samp>r</samp> are the relative variants of the other three commands. | ||
The commands <code>moveto, rmoveto, lineto | The commands <code>moveto</code>, <code>rmoveto</code>, <code>lineto</code>, and <code>rlineto</code> take two arguments; they are the X- and Y-coordinates for the destination point. | ||
The commands <code>curveto</code> and <code>rcurveto</code> create cubic Bézier curves | The commands <code>curveto</code> and <code>rcurveto</code> create cubic Bézier curves and take six 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. | ||
This snippet also shows how to create a ‘filled’ stencil using <code>path</code>, adding a Scheme function to automatically resize custom stencils when individual staves are resized. | |||
Note that replacing the stencil of a grob doesn't change its dimensions. In case you experience strange spacing you have to adjust the <code>X-extent</code> and <code>Y-extent</code> properties. If you experience cropping, you might use the <code>\with-true-dimensions</code> trick shown below. | |||
See also snippet [[Generate special note head shapes]]. | |||
<lilypond version="2.24"> | <lilypond version="2.24"> | ||
%{ | %{ | ||
Note: since SVG path data needs an "M" or "m" at | Note: since SVG path data needs an "M" or "m" instruction at | ||
beginning to start a new subpath, every path expression | the beginning to start a new subpath, every path expression | ||
must begin with "rmoveto" (or "moveto") to work with the | must begin with "rmoveto" (or "moveto") to work with the SVG | ||
backend. | |||
%} | %} | ||
customClefStencilOne = | 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 = | customClefStencilTwo = | ||
#(ly:make-stencil | |||
;; Set path line thickness to 0.1. | |||
'(path | |||
;; Set path line thickness. | |||
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 | |||
;; Is path filled? `#t` or `#f`. | |||
#t) | |||
;; Horizontal extent. | |||
(cons 0 1.5) | |||
;; Vertical extent. | |||
(cons -3 2)) | |||
% | % A Scheme function to automatically resize a custom stencil | ||
% when an individual staff is resized (uses font-size) | % when an individual staff is resized (uses `font-size`). | ||
scaleCustomClefStencilTwo = | scaleCustomClefStencilTwo = | ||
#(lambda (grob) | #(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 | customClefOne = \override Staff.Clef.stencil = \customClefStencilOne | ||
customClefTwo = \override Staff.Clef.stencil = \scaleCustomClefStencilTwo | customClefTwo = \override Staff.Clef.stencil = \scaleCustomClefStencilTwo | ||
normalClefs = \revert Staff.Clef.stencil | normalClefs = \revert Staff.Clef.stencil | ||
music = | music = \relative c' { | ||
\relative c' { | \hide Staff.TimeSignature | ||
\customClefOne | \customClefOne | ||
\clef "alto" | \clef "alto" | ||
| Line 80: | Line 82: | ||
c1 g1 | c1 g1 | ||
\normalClefs | \normalClefs | ||
\clef " | \clef "alto" | ||
c1 g1 | c1 g1 | ||
\clef " | \clef "bass" | ||
c1 g1 | c1 g1 | ||
} | } | ||
\new Staff | \markup \with-true-dimensions % work around a cropping issue | ||
\music | \score { | ||
<< | |||
\new Staff \with { | |||
fontSize = #-3 | |||
\override StaffSymbol.staff-space = #(magstep -3) | |||
\override StaffSymbol.thickness = #(magstep -3) | |||
} \music | |||
\new Staff \music | |||
\new Staff \with { | \new Staff \with { | ||
fontSize = #2 | |||
\override StaffSymbol.staff-space = #(magstep 2) | |||
\override StaffSymbol.thickness = #(magstep 2) | |||
} \music | |||
>> | |||
} | } | ||
</lilypond> | </lilypond> | ||
[[Category: | [[Category:Really cool]] | ||
[[Category:Scheme]] | [[Category:Scheme]] | ||
[[Category:Symbols and glyphs]] | [[Category:Symbols and glyphs]] | ||
[[Category: | [[Category:Tweaks and overrides]] | ||
[[Category:Snippet]] | |||