[kerx] Make Format1 work
authorBehdad Esfahbod <behdad@behdad.org>
Thu, 11 Oct 2018 01:46:58 +0000 (21:46 -0400)
committerBehdad Esfahbod <behdad@behdad.org>
Thu, 11 Oct 2018 01:46:58 +0000 (21:46 -0400)
Tested using Kannada MN:

$ HB_OPTIONS=aat ./hb-shape Kannada\ MN.ttc -u 0C95,0CCd,C95,CCD
[kn_ka.virama=0+1299|kn_ka.vattu=0+115|_blank=0@-115,0+385]

$ HB_OPTIONS=aat ./hb-shape Kannada\ MN.ttc -u 0C95,0CCd,C95,CCD --features=-kern
[kn_ka.virama=0+1799|kn_ka.vattu=0+230|_blank=0+0]

I don't see the GPOS table in the font do the same.  ¯\_(ツ)_/¯

src/hb-aat-layout-kerx-table.hh

index 552bb06..cc99868 100644 (file)
@@ -123,7 +123,7 @@ struct KerxSubTableFormat1
     inline driver_context_t (const KerxSubTableFormat1 *table,
                             hb_aat_apply_context_t *c_) :
        c (c_),
-       kernAction (table+table->kernAction),
+       kernAction (&table->machine + table->kernAction),
        depth (0) {}
 
     inline bool is_actionable (StateTableDriver<EntryData> *driver,
@@ -159,16 +159,21 @@ struct KerxSubTableFormat1
          return false;
        }
 
-        for (; depth; depth--)
+        for (unsigned int i = 0; i < depth; i++)
        {
-         unsigned int idx = stack[depth - 1];
+         /* Apparently, when spec says "Each pops one glyph from the kerning stack
+          * and applies the kerning value to it.", it doesn't mean it in that order.
+          * The deepest item in the stack corresponds to the first item in the action
+          * list.  Discovered by testing. */
+         unsigned int idx = stack[i];
          int v = *actions++;
          /* XXX Non-forward direction... */
          if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
-           buffer->pos[idx].x_advance += v;
+           buffer->pos[idx].x_advance += c->font->em_scale_x (v);
          else
-           buffer->pos[idx].y_advance += v;
+           buffer->pos[idx].y_advance += c->font->em_scale_y (v);
        }
+       depth = 0;
       }
 
       return true;