Override anchors in calt feature code

Hi everyone!
I would like to know if it’s possible to override anchors for mark placement by writing calt feature code. Because in some instances I need to move the mark [if there’s 2 marks under 1 letter] in order they should fit.
Alternatively, how is mark to mark positioning done?

Precisely what are you trying to do? The real solution may not be calt depending on your goal…

Tosche is right. This sounds like an addendum to the mark or mkmk features:

  1. in Font Info > Features, add a feature called mark (or mkmk, depending on your purpose),
  2. as the first code line, use # Automatic Code End,
  3. add your pos rules, perhaps inside a lookup.

The code will be inserted after the automatic code of the respective feature, but still inside the feature.

I am working on a Hebrew font, which can have 2 marks on the bottom of the glyph, so how can I make that if there’s only 1 mark, it should be centred, but if there are 2 bottom marks they should move so both together are centred?


I see. I guess the easiest hack would be calt, ccmp, or some other features that’s guaranteed to run before mark. You would place three anchors in the letter glyph (bottom_1, bottom, bottom_2). The diacritics will be duplicated (one for the left, another for right) and use contextual substitution. Inside the left and right diacritics, each will have _bottom_1 or _bottom_2 anchor.

Maybe you could choose anchors depending on the context without duplicating diacritics, but it’s probably more complicated.

Here’s another option to consider. This is what I did with the last font that included Hebrew: Created a single glyph for each mark that included multiple marks using components. Then you only need the single anchor. Some are encoded in Unicode; others are set as ligatures.

For example, /hatafsegol-hb would include /sheva-hb and /segol-hb as components and a _bottom anchor.

/hatafsegol_siluqleft-hb would include /sheva-hb, /siluqleft-hb, and /segol-hb as components plus that _bottom anchor.

Good idea!
But the only problem is that there are 10 x 11 possible combinations, which means to add 110 ligatures! Is that the right way to do it? Isn’t there a better & more efficient way to do it with feature code [GPOS lookup]?

Yes. Contextual positioning. pos glyph1 glyph2' <xxx yyy 0 0>; moves glyph2 by xxx and yyy, but only if it comes after glyph1. You can put it in mkmk after this line: # Automatic Code End.

1 Like

Does this work with marks? & can I place it in kern or do I have to put it in mkmk?
Will it override anchors or do I have to delete anchors?
Thanks so much!

I tried, but it doesn’t work, likely because it doesn’t override anchor.

Can you send me the .glyphs file please to support (at) (this website without www). I will have a look.

What version do you have? The custom mkmk Is fixed in the latest cutting edge version

I had a look at @yiddy’s font. There is indeed a bug if you use Hebrew code with the # End Automatic Code line in the mark feature. The code gets inserted but at the wrong spot. I will file a bug report.

At the moment, your best guess is duplicating the marks with a .left suffix and replacing the _bottom with a _bottomleft anchor in those. The glyph substitution code should probably take place in ccmp, as Toshi writes.

EDIT: You can also add bottom anchors to the bottom marks (triggers the creation of mkmk feature), vertically below the _bottom anchors, always at a distance of, e.g., 150 units. Then add all the bottom marks to the @BOTTOMMARK class, and code like this to mkmk:

# Automatic Code End
lookupflag RightToLeft;
script hebr;
pos @BOTTOMMARKS' <-100 0 0 0> @BOTTOMMARKS;
pos @BOTTOMMARKS @BOTTOMMARKS' <100 150 0 0>;

Which gets you something like this:

The placement is probably very bad, but you can experiment with the values in the two pos lines to get it right.

1 Like

Thanks for your help!
I tried everything [I mean your EDIT], but still it doesn’t work, even after manually entering the mkmk code in the .fea file in the right location…

That is strange, because I used the one you sent me, and got it to work. What do you mean by ‘doesn’t work’? Are you getting error messages?

Can you send me the current version of the file where you tried?

After updating to the latest cutting version - this worked!
Just what I needed!
@mekkablue, you’re a genius…