Side bearing deltas / intermediate sidebearings

Hi! Here’s an interesting problem with linear interpolation: narrow styles require letter spacing to be equal to the counter space, but only until some point, when a tighter spacing is preferred (wide, normal and slightly narrow styles). Thus, if you interpolate between ultra condensed and normal widths, everything in-between is spaced too tightly, as you can see on the example below. In static instances that can be solved with a filter, cool.

Is there a solution for variable fonts? Perhaps, a way to add deltas to side bearings only, without having to store full intermediate masters in the exported file?

1 Like

For static instances, you can add a transform filter to adjust the spacing per instance. For Variable fonts it is a bit more complicated.

The “rule” with the internal and external spacing is more like a suggestion. The narrow glyphs look a bit too narrow to me.

But can it be solved anyhow? Perhaps with scripting?

The narrowest master of course doesn’t have to be that extreme of course, but the issue is still there with any decently narrow masters. It’s just a more pronounced example :slight_smile:

With a script, you could simply add a master on export with adjusted sibedearings.

I’m unsure whether this is a good practice, but for an export plugin I used the method of duplicating the font (export_font = font.copy) for creating a different setup for a variable font export.

Sure, but the file size would grow. Say it’s a weight-width-italic variable font; that’s extra 4 full masters to store just to fix spacing :slight_smile:

Can’t this be done with open type positioning in the same way as kerning? Just tried adding a pos every n-th step of the width, but this is ridiculous :smiley: Kerning interpolates, so there should be a way to interpolate this, right?

…
condition 50 < wdth < 60;
pos @All @All 10;

condition 60 < wdth < 70;
pos @All @All 8;
…

You can add variable GPOS:

pos @All <0 0 0 0 (wght:30) 50 0 50 0 (wght:70) 0 0 0 0>;

The 0 0 0 0 applies to the origin master (in my case at the beginning of the axis). Then at position 30, add 100 units to the width and at 70 ad nothing any more. so between 0 and 30 and 70 it interpolates.

3 Likes

Thank you, that looks perfect!
However, I don’t seem to be able to make it work. Is there anything else to know? Tried putting it into various features, but the exported font seem to ignore it

I added it to a “kern” feature that I added for just that purpose. You need a feature that is on by default and will “usually” contain GPOS. So the kern feature is not really a good option, maybe “mark” will work.
First test in FontGoggles or a web browser before you test in Adobe apps or even Office.

1 Like

I’m trying to do that with a 2 (and 3) axes font, but it works strangely, which took quite a while to figure out: it adds the extra spacing to the second master from the list, not at the requested axis location. My first master is the origin, and whatever master I put second will get the extra spacing, no matter what its axis location is. I tried specifying the coordinates for all axes and for one, same result. Is that a bug?

Can you send me the file?

Var Test.glyphs (230.8 KB)

VariableSpacingTestVF.ttf (2.6 KB)

In this example, I want spacing at width 50-70, adding
pos @All <0 0 0 0 (wdth:50) 250 0 500 0 (wdth:70) 0 0 0 0>;
but it adds spacing at width 0, weight 500, which is where the second master is:

Thanks for the file. We’ll look into it.

1 Like

Have you tried recently in the cutting edge version?

Hi, is this syntax only supported in variable? Is it also not meant for static fonts?
(I want to do contextual kerning. Since there are lots of pairs, I don’t want to use the Number Values)

This syntax is only available in variable.

Finally tested it again and it works perfectly!

Now thinking of how to calculate the same values for static instances — is there a function that can return the pos values for a given location from that syntax? Or some guidance? The calculations get a bit confusing with multiple axes and locations. My real-case example:

pos @All <0 0 0 0 (wdth:50 wght:100) 40 0 80 0 (wdth:50 wght:900) 0 0 0 0 (wdth:100 wght:900) 0 0 0 0>;

For static instances, you can add transform filters that change the side bearings directly.

Yes, that’s what I mean, but wondering what’s the best way to calculate the same values in-between?

That really depends on what you like to do. You probably need to write a script to do the calculations. Or use a spreadsheet.

I first thought it would be interesting to use number values set in the masters. But you need different values between the masters as otherwise you could just apply the numbers to the masters directly.