Re: GSoC 2020: SMuFL glyph name to index lookup
>> It is a technical detail that LilyPond primarily communicates with >> OTF fonts via glyph names: this is necessary only because LilyPond >> natively emits PostScript code, which predates the invention of >> OpenType and thus doesn't use character codes. > > it's not just a historical decision. LilyPond needs to make > programmatic choices about which glyphs to select, for example, > which flag to print on a note depends on the duration of a note and > its stem direction. Using names makes encoding that easier: we just > look for flags{"u" for up, "d" for down}{duration-log}. This why I > think it will be practical to keep a map of Feta names around even > if the whole font gets a SmuFL layout. I agree. However, I think the right solution is to make LilyPond use SMuFL character codes internally. This will definitely make the code uglier (so we need *lots* of comments), but I don't see an alternative to that in the long end. Accessing glyphs with LilyPond's glyph names would be an add-on. Using glyph names as shown in the SMuFL specification would be another add-on. > once you have done 1-6 and it seems to be working (no output > differences, but a debugger shows that you load character codes from > the hash table), expand this mechanism to other classes of glyphs, > eg. flags, clefs, scripts, etc. You can do this is in follow up > changes, so we don't have to do a big-bang conversion. This is an excellent suggestion. > beyond making lilypond load glyphs through smufl, this scheme also has > the benefit of rearranging Emmentaler in Smufl layout, so it can be > used in other places. Yes. Werner
Re: GSoC 2020: SMuFL glyph name to index lookup
Hi, Am 28.05.20 um 06:44 schrieb Werner LEMBERG: >> This would mean every user would need to learn the new vocabulary if >> they want to reference glyphs in their scheme code. > Definitely not :-) However, I can imagine that LilyPond provides an > option to *also* allow Bravura glyph names (or maybe instead; I don't > have an opinion here) for `\musicGlyph`. > Here is an implementation of the analogous `\smuflglyph`: https://github.com/openlilylib/openlilylib/blob/master/custom-music-fonts/smufl/definitions.ily#L170 And here is the mapping of smufl names to code points: https://github.com/openlilylib/openlilylib/blob/master/custom-music-fonts/smufl/smufldata.ily converted from the json file provided by SMuFL. And here is a mapping of LilyPond names and SMuFL names (not complete but extensive): https://github.com/openlilylib/openlilylib/blob/master/custom-music-fonts/smufl/definitions.ily All taken from OpenLilyLib: https://github.com/openlilylib/openlilylib/tree/master/custom-music-fonts/smufl It is probably not the way to go for GSoC but might be interesting or save some typing work. Cheers, Joram
Re: GSoC 2020: SMuFL glyph name to index lookup
On Thu, May 28, 2020 at 6:44 AM Werner LEMBERG wrote: > I think there is a fundamental misunderstanding. Bravura is an > OpenType font, and the only intended communication with such fonts is > via character code values and *not* glyph names. It is a technical > detail that LilyPond primarily communicates with OTF fonts via glyph > names: this is necessary only because LilyPond natively emits > PostScript code, which predates the invention of OpenType and thus > doesn't use character codes. it's not just a historical decision. LilyPond needs to make programmatic choices about which glyphs to select, for example, which flag to print on a note depends on the duration of a note and its stem direction. Using names makes encoding that easier: we just look for flags{"u" for up, "d" for down}{duration-log}. This why I think it will be practical to keep a map of Feta names around even if the whole font gets a SmuFL layout. > > On the other hand, I could keep the current LilyPond naming system, > > hand-writing a dictionary that translates LilyPond names straight into > > SMuFL code points. > > Exactly. You could hand write it, but for 500 glyphs, it may be a bit of work. I would look into the following route: The feta/emmentaler fonts are generated with scripts under mf/ . You could 1) update the MF code to emit Smufl character codes together with the glyphs (look at scripts/build/mf-to-table.py and mf/feta-autometric.mf). You can dump the mapping from mf-to-table in a format that Python can easily read/write. JSON is probably the simplest choice. 2) update the gen-emmentaler.py script so it composes the emmentaler font using the Smufl layout. Read the information generated in 1) to help you. 3) use the information created in 1) to create a separate table mapping feta/emmentaler name to Smufl character code. I would suggest to dump the mapping as a .scm file that loads the name => number map into a hash table. You can copy the .scm file into the scm/ directory, as it won't be changing very often. 4) load the table into lilypond. Check out lily/lily-imports.cc to see how to load data from Scheme 5) use the table in LilyPond. In Open_type_font, use the GUILE hash table functions to do the name=>number lookup. 6) Do this for just a subclass of glyphs (eg. note heads). You can have a fallback in 5) to use the old mechanism if the hash table doesn't turn up a Smufl character code. once you have done 1-6 and it seems to be working (no output differences, but a debugger shows that you load character codes from the hash table), expand this mechanism to other classes of glyphs, eg. flags, clefs, scripts, etc. You can do this is in follow up changes, so we don't have to do a big-bang conversion. beyond making lilypond load glyphs through smufl, this scheme also has the benefit of rearranging Emmentaler in Smufl layout, so it can be used in other places. -- Han-Wen Nienhuys - hanw...@gmail.com - http://www.xs4all.nl/~hanwen
Re: GSoC 2020: SMuFL glyph name to index lookup
It seems to me that if you are going to use SMuFL fonts, you're either going to have to completely rewrite every lilypond glyph-name lookup (which should probably be phase 3 of the project) or you're going to have to have a lilypond-glyph-name-to-smufl-code-point lookup. If I were doing it as part of a staged approach, I'd do the SMuFL code point lookup. Whether the lilypond-glyph-name-to-smufl-code-point lookup has an intermediate step of smufl-glyph-name probably doesn't matter to me, at least for now. It will be less efficient, but I'd be shocked if you could measure the difference in process time. Most of our time is spent doing layout, not looking up glyphs. It seems to me like you'll want to have a lilypond-glyph-name to smufl-glyph-name table created anyway, because you're going to have to make the changes to smufl-glyph-name in the code (or else hardcode the code points, but you seem to think they are possible to change, so we shouldn't do that). So I don't think the work to make the lilypond to smufl glyph name lookup is wasted work. But I think these are mostly stylistic decisions, and there's not much in the way of objective criteria that says one way or another is better. So do what you think best, IMO. Thanks, Carl On 5/27/20, 6:48 PM, "lilypond-devel on behalf of Owen Lamb" wrote: Hi all, I do believe I've finally tracked down the place where lilypond glyph names are turned into character codes: Open_type_font::name_to_index. I can add a ternary operator here based on whether the Open_type_font is_smufl (a new property that, in the future, should be detected and set when the font is initialized), and hook it into a new function which returns the correct code point based on the SMuFL specification. Now, I could take a few different routes with this. On one hand, I could replace every instance of the lilypond glyph naming system (i.e. clefs.G) with the SMuFL one (i.e. gClef). This would mean every user would need to learn the new vocabulary if they want to reference glyphs in their scheme code. (There's also the question of what to do about glyphs in LilyPond that don't have a counterpart in SMuFL, which I plan to research anyway.) On the other hand, I could keep the current LilyPond naming system, hand-writing a dictionary that translates LilyPond names straight into SMuFL code points. This would retain a bit of nonstandardness, which might annoy future developers, with the benefit of keeping my changes largely inconsequential to the seasoned user. On the third hand (I suppose it's a three-handed monster, oh well), I could write multiple lookup functions--one to map lilypond name to SMuFL-name, and another to map SMuFL-name to code point. This would make updating to new versions of SMuFL especially easy, and keep end user experience the same, but the lookup time would be twice as long, making performance suffer. So, the way I see it, I have to sacrifice either backwards-compatibility, full standardization, or performance. What do you all think I should go for? Is there something I missed? Thanks, Owen
Re: GSoC 2020: SMuFL glyph name to index lookup
> It seems to me that if you are going to use SMuFL fonts, you're > either going to have to completely rewrite every lilypond glyph-name > lookup (which should probably be phase 3 of the project) or you're > going to have to have a lilypond-glyph-name-to-smufl-code-point > lookup. To decide whether LilyPond completely abandons the current glyph names by replacing them with the SMuFL mnemonics is something the LilyPond community has to decide. Using `convert-ly`, this could be easily done. However, I don't know whether this makes sense. > It seems to me like you'll want to have a lilypond-glyph-name to > smufl-glyph-name table created anyway, because you're going to have > to make the changes to smufl-glyph-name in the code (or else > hardcode the code points, but you seem to think they are possible to > change, so we shouldn't do that). No, they don't change. SMuFL might deprecate code points in favour of new solutions, but no code points get removed. Werner
Re: GSoC 2020: SMuFL glyph name to index lookup
> I do believe I've finally tracked down the place where lilypond > glyph names are turned into character codes: > Open_type_font::name_to_index. I can add a ternary operator here > based on whether the Open_type_font is_smufl (a new property that, > in the future, should be detected and set when the font is > initialized), and hook it into a new function which returns the > correct code point based on the SMuFL specification. I think there is a fundamental misunderstanding. Bravura is an OpenType font, and the only intended communication with such fonts is via character code values and *not* glyph names. It is a technical detail that LilyPond primarily communicates with OTF fonts via glyph names: this is necessary only because LilyPond natively emits PostScript code, which predates the invention of OpenType and thus doesn't use character codes. > Now, I could take a few different routes with this. > > On one hand, I could replace every instance of the lilypond glyph > naming system (i.e. clefs.G) with the SMuFL one (i.e. gClef). But the glyph name 'gClef' is internal to the Bravura font specification! It is just an aid for the font developer to have something mnemonic. Glyph names that are visible to clients (this is, being part of the font file itself) are normally of the form 'uni' or 'uX', with '' and 'X' four-digit and five-digit uppercase hexadecimal values, respectively; this is recommended by the Adobe Glyph List Specification for New Fonts, obeyed by virtually all fonts today. https://github.com/adobe-type-tools/agl-aglfn/ If a font developer decides to use funny glyph names like 'MyVeryCheesyGeeClef' in the OpenType font: well, this *is* possible (but non-standard, of course), and today, with recent applications, such a font should work out of the box because only character codes are of importance. Instead, the route must be as follows. (1) Create a mapping from LilyPond glyph names to SMuFL character codes (which usually are in the Unicode's PUA). This is a static table since SMuFL has stabilized; if a new SMuFL version gets released, this table has to be updated within LilyPond. (2) Convert the character code resulting from (1) to the font's glyph index and proceed as usual. Only (1) is missing currently, AFAICS. It has to be investigated whether this mapping is one to one; I can imagine that some glyphs in LilyPond map to more than a single glyph in SMuFL and vice versa. > This would mean every user would need to learn the new vocabulary if > they want to reference glyphs in their scheme code. Definitely not :-) However, I can imagine that LilyPond provides an option to *also* allow Bravura glyph names (or maybe instead; I don't have an opinion here) for `\musicGlyph`. > (There's also the question of what to do about glyphs in LilyPond > that don't have a counterpart in SMuFL, which I plan to research > anyway.) This is the tricky part, I guess. > On the other hand, I could keep the current LilyPond naming system, > hand-writing a dictionary that translates LilyPond names straight into > SMuFL code points. Exactly. > This would retain a bit of nonstandardness, ... Not at all, IMHO. > ... which might annoy future developers, with the benefit of keeping > my changes largely inconsequential to the seasoned user. Again: Having an option to allow SMuFL glyph names is very useful, but it is not the right way to communicate with fonts following the SMuFL standard. > On the third hand (I suppose it's a three-handed monster, oh well), > I could write multiple lookup functions--one to map lilypond name to > SMuFL-name, and another to map SMuFL-name to code point. Rather not. > So, the way I see it, I have to sacrifice either > backwards-compatibility, full standardization, or performance. Fortunately, there's nothing to sacrifice :-) Werner
GSoC 2020: SMuFL glyph name to index lookup
Hi all, I do believe I've finally tracked down the place where lilypond glyph names are turned into character codes: Open_type_font::name_to_index. I can add a ternary operator here based on whether the Open_type_font is_smufl (a new property that, in the future, should be detected and set when the font is initialized), and hook it into a new function which returns the correct code point based on the SMuFL specification. Now, I could take a few different routes with this. On one hand, I could replace every instance of the lilypond glyph naming system (i.e. clefs.G) with the SMuFL one (i.e. gClef). This would mean every user would need to learn the new vocabulary if they want to reference glyphs in their scheme code. (There's also the question of what to do about glyphs in LilyPond that don't have a counterpart in SMuFL, which I plan to research anyway.) On the other hand, I could keep the current LilyPond naming system, hand-writing a dictionary that translates LilyPond names straight into SMuFL code points. This would retain a bit of nonstandardness, which might annoy future developers, with the benefit of keeping my changes largely inconsequential to the seasoned user. On the third hand (I suppose it's a three-handed monster, oh well), I could write multiple lookup functions--one to map lilypond name to SMuFL-name, and another to map SMuFL-name to code point. This would make updating to new versions of SMuFL especially easy, and keep end user experience the same, but the lookup time would be twice as long, making performance suffer. So, the way I see it, I have to sacrifice either backwards-compatibility, full standardization, or performance. What do you all think I should go for? Is there something I missed? Thanks, Owen