Hi, I have a series of glyphs that I want to shift vertically, depending on their prefix. This is for Gregorian chant notation.
For example, I have created a ligature created by typing 212. Depending on which position it is on the staff, it’s typed as 1.212, 2.212, 3.212… etc.
I have a great many of these glyphs to create. I have been creating individual ligatures for each, but surely there is a better way.
Is there a way to indicate that typing 1. or 2. or 3., etc will apply a vertical shift to the glyph that follows? It appears I should use GPOS? If so, I’m unsure exactly how to do it.
I’m sorry, I’m a bit lost. How do I assign glyphs to a class? I’m very willing to work through documentation on my own, but I don’t know how to do it.
Here’s what I have currently, hundreds of these:
The more complex ones start with “one period,” “two period,” etc.
I would be very happy to get some personal help on this, willing to compensate someone for their time. This is over my head, I’m afraid
Ok, some success finally!! I set it up so that "2’ shifts the glyph up.
(Grr… forum deleted the photo I had… but it worked).
But the only way I was able to achieve this was remove most of the glyphs and start at the very basic level. However I was still excited to see it works!
Here’s the challenge: one and one_period.liga are glyphs that should exist in the font (the user can enter simple numbers and numbers with periods):
Is there a way to have one, one_period.liga, and use 1. 2. 3. 4. etc for GPOS?
Or if it’s simpler, I guess I could make 1/, 2/, 3/ etc. into blank, 0-width ligatures, and make those be the things that trigger a GPOS?
Ok, I am running into another problem. I have added a few glyphs to a class. Then I added a Single Adjustment to that class, to shift it upwards by 120 units when preceded by “one slash.”
However, it’s not working. It does not shift the glyph correctly. Here’s the code:
###
# OpenType Layout feature definitions
# Format: OpenType Feature File Specification version 1.25.1
# Generated on: 2024-09-19 00:31
# Generated by: FontCreator
# Font name: MusChant
# Font copyright:
#
# Totals:
# Language systems: 1
# GSUB lookups: 2
# GSUB features: 1 (liga)
# GPOS lookups: 1
# GPOS features: 1 (blwm)
#
# Languagesystem definitions
#
languagesystem latn dflt; # Latin default
#
# Global glyph class definitions
#
@BASE = [D F one one_period.liga one.period.alt one_two.liga one_three.liga three_one.liga one_four.liga four_one.liga one_five.liga five_one.liga one_l.liga one.liga.alt one_two_one.liga one_two_one_l.liga one_two_one_l.alt one_four_three.liga one_four_two.liga one_three_two.liga two_one_two.liga three_two_three_one.liga one_three_two_three.liga three_one_two.liga glyph02 glyph03 glyph04 glyph05 glyph06 glyph07 glyph08 glyph09 glyph10 glyph11 glyph13 glyph14 glyph15 glyph16 glyph17 glyph18 glyph19 glyph20 glyph21 glyph22 glyph28 glyph29 glyph30 glyph31 glyph32 glyph33];
@neumes = [c d q v D F one];
#
# Global lookup definitions
#
lookup SingleAdjustment1 { # GPOS lookup type SingleAdjustment
pos @neumes <0 120 0 0>;
} SingleAdjustment1;
#
# Feature definitions
#
feature blwm { # Below-base Mark Positioning
pos one slash @neumes' lookup SingleAdjustment1;
} blwm;
feature liga { # Standard Ligatures
lookup Ligature2 { # GSUB lookup type Ligature
sub one l by one_l.liga;
sub one period by one_period.liga;
} Ligature2;
lookup latn_liga { # GSUB lookup type Ligature
sub hyphenminus one slash by hyphenminus_one_slash.liga;
sub hyphenminus two slash by hyphenminus_two_slash.liga;
sub zero slash by zero_slash.liga;
sub one two one l by one_two_one_l.liga;
sub one three two three by one_three_two_three.liga;
sub one zero slash by one_zero_slash.liga;
sub one two one by one_two_one.liga;
sub one three two by one_three_two.liga;
sub one four two by one_four_two.liga;
sub one four three by one_four_three.liga;
sub one slash by one_slash.liga;
sub one l by one_l.liga;
sub one period by one_period.liga;
sub one two by one_two.liga;
sub one three by one_three.liga;
sub one four by one_four.liga;
sub one five by one_five.liga;
sub two one two by two_one_two.liga;
sub two slash by two_slash.liga;
sub two one by two_one.liga;
sub three two three one by three_two_three_one.liga;
sub three one two by three_one_two.liga;
sub three slash by three_slash.liga;
sub three one by three_one.liga;
sub four slash by four_slash.liga;
sub four one by four_one.liga;
sub five slash by five_slash.liga;
sub five one by five_one.liga;
sub six slash by six_slash.liga;
sub seven slash by seven_slash.liga;
sub eight slash by eight_slash.liga;
sub nine slash by nine_slash.liga;
} latn_liga;
} liga;
# Glyph class "BASE" already defined
table GDEF {
GlyphClassDef @BASE,,,;
} GDEF;
After I get this figured out, how do I add a second positioning? I want to do a greater vertical shift when I enter 2/.
Yes, sorry, I realize it may be a bit unclear. Here’s what I’m wanting to achieve. Ignore the horizontal lines; they’re created in the music program):
The user types 1, 2, 3, etc. for simple position on the staff (I had previously made these as individual glyphs, already vertically positioned).
They can also type 1., 2., 3., etc. for notes with dots after them. I had also created these individually.
Then they can type X.Y, where X is the position on the staff, and Y is the ligature. So in the example above, the ligature is 212, and it can be shifted up by its prefix. Previously I had also made these as ligatures: one_period_two_one_two.liga, two_period_two_one_two.liga, etc… tedious, but possible… until I realized the library of possible glyphs is massive. So that’s why I’m trying POS.
It is pretty important for the user to be able to to type 1 and 1. for simple notes, since these are very common. I am also fine creating 1, 2, 3, etc. as separate glyphs that are already placed. So, if the 1. ligature cannot work with POS and would cause a conflict, I could switch to something like the user entering 1/212, 2/212, etc. where the 1/ was a blank zero-width ligature? That would be fine with me. But I couldn’t get that to work either.
Thank you!
PS: I know this may seem a bit obscure, but there is a lot of excitement in the music notation community around the possibility of this sort of thing. So it’s worth it to me to work on it.
By the way, here is an example of the sort of thing I need to be able to replicate. This is already possible in other programs, but it is incredibly tedious and limited.
I think a lot of what you want can be accomplished, but you first need to determine what sets of glyphs should behave different, depending on other glyphs before or after them.
OpenType always processes substitutions before positioning, so you have to keep that in mind. MusChantGPOS2.zip (20.8 KB)
Ok, I looked at the code in the file you sent. Thank you! I think I’m close.
It seems best to use “one comma” as a prefix for all single adjustments. That way I won’t have to mess with chaining context.
Here’s what I need to code. I have set these inputs up as blank zero-width glyphs, and these combinations won’t be used anywhere else in the font:
Do I need to add each of these adjustments as individual Single Adjustments? Can I rename each adjustment to what is easiest to remember?
Last thing… some of these need to use alternate glyphs before they are adjusted vertically. For example:
When this glyph is preceded by “nine comma,” it needs to be replaced with one.alt9. When it is preceeded by “one zero comma,” it needs to be replaced with one.alt10. Does that make sense?
Thank you so much for your help. This is really coming together…
PS: I am thrilled to say that contextual positioning DOES work in Dorico!
These were input as 1 and 2,1:
Now all I need to figure out is how to add multiple single adjustments based on the input, and how to do the substitution glyphs.
One more update: I figured out how to do single adjustments, but when I try to add another adjustment as a lookup, it crashes. I posted the crash log on the other sub-forum.