MakeOTF GSUB offset overflow

That would be a combining spacing mark, then.

Hi @blinkenlichten, I think the definitely solution for you is trying to make the shaping with rearrangement instead of creating precomposed glyphs (ligatures).

In order to give you a hint with your example, try to do the rearrangement in ccmp using Chaining contextual substitution (GSUB LookupType 6) with sub-runs.

I understand that this kind of lookup is not as simple as the others, but I will try to explain a little bit the concept, and also you can find attached to this message a .glyphs file that contains those rearrangement rules and a workable font with that shaping.

LepchaTest.zip (4.0 KB)

The idea is to move the dependent vowel (oVowel-lepcha) from any part from the right of the consonant (la-lepcha) to the left to the latter; this is because I assume that you are following the Unicode syllable order:

Consonant + (nukta) + (Ra) + (Ya) + (dependent vowel) + (final consonant sign) + (Ran)
Image from SIL

Rearrangement is not directly supported by OT as it is in AAT, but you can use a combination of lookups to “move” those glyphs. When I say “move” I mean insert in one part and delete in other part the same glyph in a specific context.

First, create a lookup that inserts to the left of the consonant the glyph that you want to move. This lookup needs to be placed outside of any feature, in Glyphs you can do it in PREFIX section. For that, we are going to use what is called Multiple Substitution (GSUB LookupType 2) or what @mekkablue calls one to many:

lookup Insert_oVowel {
  sub la-lepcha by oVowel-lepcha la-lepcha;
} Insert_oVowel;

Now we need to create another lookup (outside any feature) that remove the glyphs that was previously added by Insert_oVowel to the left of the consonant, we are going to do that with a Ligature substitution (GSUB LookupType 4). Since this GSUB subtable allow us to use classes in the glyph sequence, we can declare a class for dependent vowels:

@dependentLeftVowel = [ oVowel-lepcha ]

And then we write the lookup that is going to clean the dependent left vowel up, that that was previously inserte by Insert_oVowel, this lookup should looks like the following:

lookup RemoveVowels {
  lookupflag IgnoreMarks;
  sub la-lepcha @dependentLeftVowel by la-lepcha;
  sub raSub-lepcha @dependentLeftVowel by raSub-lepcha;
} RemoveVowels;

Now that we have the rules for Insert_oVowel and RemoveVowels, we can mix then in the same lookup as a sub-runs using the following lookup, this time in the ccmp feature:

lookup lepcha_rearrangement {
  lookupflag IgnoreMarks;
  sub @consonant' lookup Insert_oVowel oVowel-lepcha ;
  sub @consonant' lookup Insert_oVowel @joinedConsonant oVowel-lepcha ;
  sub @dependentLeftVowel @consonant' lookup RemoveVowels @dependentLeftVowel';
  sub @dependentLeftVowel @consonant @joinedConsonant' lookup RemoveVowels @dependentLeftVowel';
} lepcha_rearrangement;

And don’t forget the following classes:
@consonant = [ la-lepcha ]
@joinedConsonant = [ raSub-lepcha ]

@blinkenlichten, let me know if this works for you.

Best,

Nicolás

Note: I placed Ra in @joinedConsonant in order to make shorter this example.

1 Like

@Georg: I beg your pardon, I didn’t want to blame anybody, just reporting what worked in my case and what did not.

@Nicolas: My heartfelt thanks for your dedicated step-by-step advice. I beg you not to feel offended by the fact that, finally, I took a different approach.

After all the attention and care I received at this forum, I’d like to share the solution I applied to complete my ‘mega-liga’ Lepcha font. May be this will be of use to others running into the same problems. Thus, I changed the thread’s title for better detection in the forum search.

When I was stuck with my main font file at around 6000 ligatures, I created a second file (extension) containing the remaining around 1200 ligatures.

The glyphs of the extension file were then copied into the main file, without updating the features (as this would have triggered the MakeOTF error). Both were exported into fonts, resulting in

  • a main font containing all the glyphs and part of the features
  • and an extension font containg part of the glyphs with their corresponding features.

Merging the extension features with the main font was done using DTL OTMaster, exporting the GSUB features of both into a (.fea) text file. The definitions of the extension ligatures were inserted into those of the main.fea with a text editor.

The following is a matter of course for the experts, I mention the details just for possible likes of me (greenhorns):
Substitutional definitions have to be arranged in consistent blocks, all the ligatures beginning with 1C00, for example, have to be in one row and ordered according to length, starting with all those having the highest number of composits down to the series of the those with least number of composits.

With the generous help of the professionals at URW++ (developers of OTMaster), I had to overcome another pitfall. It does not suffice to add ‘useExtension’ if I have all the ligatures in one lookup. MakeOTF does not segregate the bunch of ligatures into fitting portions by itself. I manually grouped the ligatures into seven lookups of around 1000 ligatures the following way:

> lookup GSUB_LOOKUP_00000 useExtension
> {
>  lookupflag 0;
>     sub \uni1C23 \uni1C24 \uni1C27 \uni1C36 \uni1C35 by \uni1C231C241C271C361C35.liga;

>     … etc.

>     sub \uni1C4F \uni1C2B by \uni1C4F1C2B.liga;
> } GSUB_LOOKUP_00000;

> lookup GSUB_LOOKUP_00001 useExtension
> {
>  lookupflag 0;
>     sub \uni1C19 \uni1C27 \uni1C36 \uni1C35 by \uni1C191C271C361C35.liga;

>     … etc.

>     sub \uni1C03 \uni1C2B by \uni1C031C2B.liga;
> } GSUB_LOOKUP_00001;

> lookup GSUB_LOOKUP_00002 useExtension
> {
>  lookupflag 0;
>     sub \uni1C04 \uni1C27 \uni1C36 \uni1C35 by \uni1C041C271C361C35.liga;

>     … etc.

>     sub \uni1C00 \uni1C2B by \uni1C001C2B.liga;
> } GSUB_LOOKUP_00002;

In a final step, I imported the GSUB features into the main font file with OTMaster. Save. Finished. The result is an OpenType font file of reasonable 769kB working fail-safe.

Postscript: Examining the features file in GLYPHS’ temp folder, I have the impression that, may be, the same procedure could be applied manually editing this file. However, I have no clue about the syntax required, here.

I don’t think that you need to hopp through so many holes. There is no difference in adding the feature file with OTMaster or by just fixing the feature file in glyphs directly. So you don’t need the extra font and you can just export directly from Glyphs.

You basically can copy the feature into Glyphs and it should work. You might need to use the Glyphs name Services to convert to naming you use in Glyphs.

Sure, I likely took a long way round and I’m eager to explore the ‘shortcut’.
I merged the two feature files into one.

feature liga {
sub a-lepcha ran-lepcha k-lepcha by a_ran_k-lepcha.liga;

                … 7200 more ligatures …

sub ya-lepcha uu-lepcha kang-lepcha by ya_uu_kang-lepcha.liga;
} liga ;

So, what’s the correct wording to manually insert several lookups?

Add a liga feature. In the text area puts:

lookup liga1 {
    sub a-lepcha ran-lepcha k-lepcha by a_ran_k-lepcha.liga;
    .... more lines
} liga1;
lookup liga2 {
    sub ya-lepcha uu-lepcha kang-lepcha by ya_uu_kang-lepcha.liga;
    ....
} liga2;

That way you can add as may lookups as you need. And you can add the lookup flags for ach of them.