Good morning.
I'm trying to write code that convert a linear staff in a circular one.
My idea is:
-let lilypond write a normal linear single staff
-for each grob, fetch the stencil and their position (x coordinate
relative to the system and y coordinate relative to the staff) using the
callback after-line-breaking
-save stencils, x-coords, y-coords in three global list variables (each
callback add an element to the lists)
-after the end of the Score block put a markup block that plots the
circular staff and draws all the stencils (with the right translation
and rotation) calculated from the three global lists
Is it possible to obtain this using global lists? I wasn't able to do
it. Maybe there is a better solution?
Is it possible to have a single line staff on the top (automatically
incrementing the page width in order to avoid multiple staff lines) and
the circular staff below it?
This is the structure of my code (without the global lists):
\version "2.24.4"
\language "italiano"
%TODO: define empty global lists
#(define (trasforma-circolare grob)
; Ricava i parametri
(let*
(
(nome (assoc-get 'name (ly:grob-property grob 'meta)))
(x (ly:grob-relative-coordinate grob (ly:grob-system grob) X)) ;
x-coord respect to the system
(y (ly:grob-staff-position grob)) ; y-coord respect to the staff
(stncl (ly:grob-property grob 'stencil))
)
%TODO: add elements x, y, stncl to the global lists
)
)
CircularStaff = \markup {
\fill-line {
\overlay {
\draw-circle #20 #0.15 ##f
\draw-circle #21 #0.15 ##f
\draw-circle #22 #0.15 ##f
\draw-circle #23 #0.15 ##f
\draw-circle #24 #0.15 ##f
%TODO: read the global lists, convert rectangular coords to polar,
rotate and translate stencil and print one stencil for each element
(using map)
%it is easy to draw stencils here because with \overlay we have
the reference point always at the center of the circular staff, so
%we spread the x-coords to an angle from 0 to 360 and we add to
the y-coord the radius of the inner circular staff line
}
}
}
\paper {
page-breaking = #ly:one-page-breaking
ragged-right = ##t
ragged-last = ##t
indent = #0
}
\header { title = "TITOLO" tagline = ##f}
LinearStaff = \new Staff \relative do' { \time 4/4 \key re \major
\autoBeamOff
do4 re8 mi8 fa4. r8
}
\score {
\LinearStaff
}
\markup \null
\CircularStaff
\layout {
\context {
\Score
\override Clef.after-line-breaking = #trasforma-circolare
%...
%for every grob (KeySignature, TimeSignature, NoteHead, ...) add a
callback
}
}