[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Help with custom noteheads
From: |
Jean Abou Samra |
Subject: |
Re: Help with custom noteheads |
Date: |
Thu, 11 Aug 2022 14:57:04 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.12.0 |
Le 11/08/2022 à 13:40, Andrew Bernard a écrit :
So here is an MWE showing the start of what I want to do - make
circular unfilled noteheads, and fitting in the staff size. This is
only a start, as the set of note styles I need have many extra
doodads, so this is just to get going.
It's been a long time since I have done any Lilypond Scheme. I'm
wanting help on how to size and position the noteheads properly. This
initial code is only my first sketch. I'm aware I need to flip the
side when the stem points down - that's not the main focus. I am also
foggy on the last arguments specfying the x and y extents. I can't
recall what extents are and how they affect this context (having
trouble searching for extent in the NR).
Extents are also called 'dimensions'. The extents of a grob
don't affect it itself, but they affect how other grobs react
to it, for example how a stem will attach to a note head, or
what space is reserved between two staves.
Stencils also have extents. They are used whenever stacking
stencils, aligning them, etc.
If the X-extent and Y-extent are not set to something particular,
the default to compute a grob's extents is to get them from
the stencil.
I don't think you'll find much about this topic in the
official documentation, but there is a bit of info here:
https://extending-lilypond.readthedocs.io/en/latest/backend.html#coordinates-extents-and-reference-points
The code is my own using the Bezier approximation for a circle. The
variable k is kappa - as referenced in a previous post on 'Circles'
and r is radius.
LilyPond supports exact circles, as you have found out in the
PostScript code in the other thread. Use make-circle-stencil to
create a circle. By the way, if you don't want to learn about
stencil functions, you could also use a markup:
(grob-interpret-markup grob #{ \markup \draw-circle ... #})
Here's a commented snippet that should help you get started:
\version "2.23.11"
\layout {
\context {
\Score
% custom circular noteheads
\override NoteHead.stencil =
#(lambda (grob)
(let* (;; The thickness of lines in the staff symbol; depends
;; on font size.
(staff-thickness (ly:staff-symbol-line-thickness grob))
;; Our own thickness -- scale it by the staff symbol's
;; thickness.
(thickness (* staff-thickness (ly:grob-property grob
'thickness)))
;; Our radius, measured to the center of the line.
(radius (- (* 1/2 (ly:staff-symbol-staff-space grob)) ;
half space
(* 1/2 thickness) ; account for our thickness
(* 1/2 staff-thickness) ; account for staff
line thickness
))
;; Draw the circle.
(circle (make-circle-stencil radius thickness #f)))
;; LilyPond expects a note head to tell how it should mesh with
;; other with its X extent. The part of the X extent before 0
;; is the “breapth” value. In our case, use 1/2*thickness
for the
;; breapth so that a reversed note head (not on the normal
size of
;; the stem due to seconds in chords) has the center of its
;; circle line on the stem.
(ly:stencil-translate-axis
(ly:stencil-aligned-to circle X LEFT)
(* -1/2 thickness)
X)))%}
\override NoteHead.thickness = 1.15
\override Stem.thickness = 1.15 % match stem to note head
%% Attach stem exactly on the left or right of the note head, and at
%% the vertical center. In coordinates relative to the note head
dimensions,
%% that means '(1 . 0) or '(-1 . 0)
\override NoteHead.stem-attachment =
#(lambda (grob)
(let* ((stem (ly:grob-object grob 'stem))
(direction (ly:grob-property stem 'direction)))
(cons direction 0)))
}
}
test =
#(define-music-function (size) (number?)
#{
\new Staff \with { \magnifyStaff #size } \relative {
c'4 d e f |
g a b c |
c2 b | a g | f e | d c |
c1 | d | e | f | e | d | c |
<c d>1 | <c d>2 <c d>4 <c d>8 <c d>16 16
}
#})
\test 0.5
\test 0.7
\test 0.9
\test 1.1
\test 1.3
\test 1.6
Regards,
Jean