Hi, With [!1957](https://gitlab.com/lilypond/lilypond/-/merge_requests/1957) that will soon become ready, I think it's about time to discuss how we want the “big picture” user experience and font developer experience to be with respect to alternative music fonts.
For those who haven't followed the (long) story, this MR basically lets LilyPond search for music fonts in the same way as it searches for text fonts. It thus makes it possible to make music fonts found with `ly:font-config-add-font` or `ly:font-config-add-directory`, in contrast to the current approach where you have to drop them into directories that are normally supposed to be internal to LilyPond (and therefore re-add them with every new LilyPond version). This lays the internal foundation for a better user experience of using alternative music fonts. While LilyPond doesn't support SMuFL right now, it's very desirable to have that in the medium term and I think it makes sense to keep it in mind for designing this — at least, to avoid making changes that will complicate it. Now, from the user point of view, the question is how we want to organize the UX of using an alternative music font: 1. Download the font: from where? Are some alternative fonts preinstalled with our official binaries? This would deserve a thread of its own and I won't discuss it here. 2. Install the font: how? 3. Use the font in a .ly file: how? For (3), the basic way to select a music font is ``` \paper { fonts.music = "whatever" } ``` The main issue is that this only switches the glyphs themselves. However, to look good, there are also other style adjustments to make in order to match the font, like the thickness of stems and staff lines, etc. We want to have a way to select a font *and* make those adjustments automatically at the same time. I can see two approaches. The first one is to keep doing what has been done so far: define include files. For an example, see [https://github.com/OpenLilyPondFonts/lilyjazz/blob/master/stylesheet/lilyjazz.ily](https://github.com/OpenLilyPondFonts/lilyjazz/blob/master/stylesheet/lilyjazz.ily) In that perspective, the font `.otf` file can be put next to the include file, and it can do something like ``` #(ly:font-config-add-directory (dirname (car (ly:input-file-line-char-column (*location*))))) ``` which registers the directory of the include file as a font directory. This is a workable approach. There are at least two reasons why this is suboptimal, though. The first reason is subjective: I would prefer if the way to select alternative music fonts was uniform with text fonts, i.e., with `\paper { fonts.music = "..." }`. Also, the include file would have to be `\include`d inside `\score` blocks to make the font change local to one score. I'm not very fond of this. See [!1929](https://gitlab.com/lilypond/lilypond/-/merge_requests/1929) for some discussion of this practice. The second reason is related to SMuFL. We want people to be able to take advantage of any SMuFL font downloaded from a random place on the Internet, and not require that every font come with a LilyPond include file to be usable with LilyPond. With SMuFL, there is a JSON file next to the font, which contains, among other things, an `engravingDefaults` structure. [https://w3c.github.io/smufl/latest/specification/engravingdefaults.html](https://w3c.github.io/smufl/latest/specification/engravingdefaults.html) So we'll also eventually want to read that. But it's obviously much more limited than the full range of things you can customize in LilyPond. Now to the second approach, which I prefer. In this approach, `\paper { fonts.music = "foo" }` remains the syntax to select an alternative music font. If, next to the `.otf` font file, a file called `stylesheet.ily` (or another bikeshed color) is found, it is read and defines the style parameters. Because we want to be able to apply it both globally and locally to one score/bookpart/book, we take it in the form of a `\layout` block. To do that, we read `stylesheet.ily` with `ly:parse-string-expression`. That is, in exactly the same way as the content of `#{ ... #}` is read. For the `stylesheet.ily` writer, this means that the file is written as a single `\layout` block (plus perhaps a `\version` statement). If in the future we support SMuFL, we'll also read the JSON metadata and synthetize a layout from it, then use it in the same way. `stylesheet.ily` would continue to be supported and could be used to define styles that SMuFL doesn't allow. This leaves with the question of how font files are found and where they are installed. We don't really want users to need `#(ly:font-config-add-directory "/home/me/...")` in every file with a custom music font. With the include-based approach, LilyPond has an include path, which can be extended with the `-I` option. Frescobaldi has a nice interface for adding include directories (in the LilyPond preferences). I was initially hoping to reuse that. However, Fontconfig scans directories recursively. We don't want to add all the include path to the font path because include directories (this also means the current directory) could contain many files and take forever to scan. A possibility would be to scan our include directories ourselves (in a shallow way) and add `.otf` files individually to Fontconfig. This isn't that nice for SMuFL fonts, though. Each SMuFL font has an associated JSON file, and I believe the two would normally be put into a directory of its own. Ergo, you would not be able to add a directory "my-custom-fonts" with one subdirectory per font inside. You would need to add each of the subdirectories individually. For this reason, I lean towards a `-dfont-path` option, similar to `-I` but for font directories, and scanned recursively. The downside, of course, is that we'll need to wait until a Frescobaldi update implements a graphical way to add font directories, like include directories, for this become a really seamless experience. (I would be willing to contribute that in Frescobaldi.) Well, that was long again. What are your thoughts? Do you see any problems or better alternatives? Thanks, Jean
signature.asc
Description: This is a digitally signed message part