Negative advance

I have observed many times that a variable font would produce negative advance (very frequent in Amstelvar), and in browsers like Chrome it wraps around to +VERY_BIG.

Per some discussion with @GregHitchcock we think that under-saturating advance width to 0 for these cases is a good idea. What's your opinion about it?

Comments

  • Call me clueless, but what is "negative advance" and what does "under-saturating" its width mean?
  • Adam Jagosz
    Adam Jagosz Posts: 689
    edited January 2019
    Negative advance width, when the right sidebearing is to the left of the left sidebearing. So you type a letter and the cursor actually goes back...
    Under-saturating, I guess advance = max(0, advance)?
  • Negative advance width, when the right sidebearing is to the left of the left sidebearing. So you type a letter and the cursor actually goes back...
    Under-saturating, I guess advance = max(0, advance)?
    yes.
  • John Hudson
    John Hudson Posts: 3,229
    we think that under-saturating advance width to 0 for these cases is a good idea
    Where are you proposing to do this? Are you saying that fonts should be built in this way, or that line layout should automatically prevent any advance width from collapsing below zero?
  • How can an advance width become negative? It is not allowed per OT spec; it is stored as an unsigned integer in the hmtx table.
  • John Hudson
    John Hudson Posts: 3,229
    How can an advance width become negative? It is not allowed per OT spec; it is stored as an unsigned integer in the hmtx table.
    As I understand the original post, it's referring to an outcome of additive extrapolation of reducing width deltas between axes. Since extrapolated widths are not stored in the hmtx table, they're not subject to the unsigned integer restriction.

    This problem is the metrics equivalent of what can happen in outline extrapolation: if you have two or more axes that shift some counter points in the same direction, the additive extrapolation can push these points outside the relatively static outer edge of a glyph. I've seen this happening with inktraps in the crotch of V being pushed beyond the bottom of the letter.

    Question (to which I should already know the answer): Is it possible to define MVAR metrics for instances in the design space (e.g. extrapolated corners) for which no glyph deltas exist in gvar? I'm wondering if that's a way to 'under-saturate' the advance width to zero (or to whatever practical width is appropriate to the design)?

  • Yes, variations easily lets you have negative advance widths with simple interpolation:

    E.g. A single axis font (ranging from -1 to 0, with default at 0), with default instance having htmx AW = 500. Have an HVAR delta of -1000 at axis=-1. Then, for any axis value < 0.5, the computed AW will be negative.

    A negative AW is an undefined state per the OpenType spec, as Jens described. We probably should have some guidance to clamp this and other values. E.g. you could use the same technique to create negative strikeout widths or gasp PPEMs.
  • Of course you are right, I was thinking only of the case that a variable font is built from separate master fonts. In that case, the advance width in each master can not be negative, and thus it must also be not negative in the variable font. Though through the combination of two axes with a big negative delta on the widths, it could still happen in the 'corner' instances.
  • k.l.
    k.l. Posts: 109
    edited January 2019
    E.g. A single axis font (ranging from -1 to 0, with default at 0), with default instance having htmx AW = 500. Have an HVAR delta of -1000 at axis=-1. Then, for any axis value < 0.5, the computed AW will be negative.
    This sounds like a rather unlikely case given that, as Jens said, in a real world scenario a type designer designs masters and then the font editor derives deltas from these.

    What I could imagine, though, is that a type designer designed a wide base master and two narrow variant masters. Then the two deltas derived from them, applied together, lead to a negative AW. But. Isn't this a type design flaw, a conceptual error, in terms of setting up axes? This would not be anything that can, or should, be taken care of automatically. AW may be forced to a minimum of zero, yes, but if AW got wrong in such a way then it is most likely that outlines did too ...

    [I rewrote this post completely.]