(OTF_DriveLog): Delete it.
[m17n/libotf.git] / src / otfdrive.c
index 4ae95b8..0139011 100644 (file)
@@ -1,6 +1,6 @@
 /* otfdrive.c -- OpenType font driver.
 
-Copyright (C) 2003, 2004
+Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
   National Institute of Advanced Industrial Science and Technology (AIST)
   Registration Number H15PRO167
 
@@ -27,10 +27,15 @@ write to the Free Software Foundation, Inc., 59 Temple Place, Suite
 #include <config.h>
 
 #include "otf.h"
-#include "otferror.h"
+#include "internal.h"
 
 extern int debug_flag;
 
+#ifdef USHORT
+#undef USHORT
+#endif
+#define USHORT unsigned short
+
 /* Return nonzero (-1 if ID is zero, 1 otherwise) if OTF_Glyph *G
    should be ignored according to LookupFlag FLAG.  */
 #define IGNORED_GLYPH(g, flag)                         \
@@ -190,7 +195,7 @@ get_langsys (OTF_ScriptList *script_list,
          for (j = 0; j < script->LangSysCount; j++)
            if (script->LangSysRecord[j].LangSysTag == langsys_tag)
              return script->LangSys + j;
-         return &script->DefaultLangSys;       
+         return &script->DefaultLangSys;
        }
     }
 
@@ -201,13 +206,13 @@ get_langsys (OTF_ScriptList *script_list,
   for (j = 0; j < dflt->LangSysCount; j++)
     if (dflt->LangSysRecord[j].LangSysTag == langsys_tag)
       return dflt->LangSys + j;
-  return &dflt->DefaultLangSys;        
+  return &dflt->DefaultLangSys;
 }
 
 static int
 setup_lookup_flags (OTF_LookupList *LookupList, OTF_FeatureList *FeatureList,
                    OTF_LangSys *LangSys,
-                   const char *features, char *lookup_flags)
+                   const char *features, USHORT *lookup_flags)
 {
   int i, j, n = 0;
   OTF_Feature *feature;
@@ -217,7 +222,7 @@ setup_lookup_flags (OTF_LookupList *LookupList, OTF_FeatureList *FeatureList,
     return -1;
   for (i = 0; i < FeatureList->FeatureCount; i++)
     feature_table[i] = 0;
-  memset (lookup_flags, 0, LookupList->LookupCount);
+  memset (lookup_flags, 0, sizeof (USHORT) * LookupList->LookupCount);
 
   while (*features)
     {
@@ -228,7 +233,7 @@ setup_lookup_flags (OTF_LookupList *LookupList, OTF_FeatureList *FeatureList,
       if (*features == '*')
        {
          /* Consume all remaining features.  */
-         for (i = 0; i < LangSys->FeatureCount; i++) 
+         for (i = 0; i < LangSys->FeatureCount; i++)
            {
              int index = LangSys->FeatureIndex[i];
 
@@ -236,7 +241,7 @@ setup_lookup_flags (OTF_LookupList *LookupList, OTF_FeatureList *FeatureList,
                {
                  feature = FeatureList->Feature + index;
                  for (j = 0; j < feature->LookupCount; j++)
-                   lookup_flags[feature->LookupListIndex[j]] = 1;
+                   lookup_flags[feature->LookupListIndex[j]] = i + 1;
                }
            }
          break;
@@ -261,7 +266,7 @@ setup_lookup_flags (OTF_LookupList *LookupList, OTF_FeatureList *FeatureList,
                break;
              if (use_it > 0)
                for (j = 0; j < feature->LookupCount; j++)
-                 lookup_flags[feature->LookupListIndex[j]] = 1;
+                 lookup_flags[feature->LookupListIndex[j]] = j + 1;
              feature_table[i] = use_it;
              break;
            }
@@ -272,17 +277,17 @@ setup_lookup_flags (OTF_LookupList *LookupList, OTF_FeatureList *FeatureList,
 
 static int
 match_ids (OTF_GlyphString *gstring, int gidx, int flag,
-          int count, OTF_GlyphID *ids)
+          int count, OTF_GlyphID *ids, int direction)
 {
-  OTF_Glyph *gbeg = gstring->glyphs + gidx;
-  OTF_Glyph *gend = gstring->glyphs + gstring->used;
-  OTF_Glyph *g;
-  int i;
+  OTF_Glyph *g = gstring->glyphs + gidx;
+  OTF_Glyph *gend = gstring->glyphs + (direction > 0 ? gstring->used : -1);
+  int i, j;
 
-  for (g = gbeg, i = 0; g < gend && i < count; g++)
-    if (! IGNORED_GLYPH (g, flag) && g->glyph_id != ids[i++])
+  for (i = j = 0; i < count && g != gend; j++, g += direction)
+    if (! IGNORED_GLYPH (g, flag)
+       && g->glyph_id != ids[i++])
       return -1;
-  return (i < count ? -1 : g - gbeg);
+  return (i < count ? -1 : j);
 }
 
 static int
@@ -291,29 +296,18 @@ match_chain_ids (OTF_GlyphString *gstring, int gidx, int flag,
 {
   int i = rule->BacktrackGlyphCount;
 
-  if (i > 0)
-    {
-      int j;
-      OTF_Glyph *g;
-
-      for (j = gidx - 1, g = gstring->glyphs + j; j >= 0; j--, g--)
-       if (! IGNORED_GLYPH (g, flag) && --i == 0)
-         break;
-      if (i > 0)
-       return -1;
-      if (match_ids (gstring, j, flag,
-                    rule->BacktrackGlyphCount, rule->Backtrack)
-         < 0)
-       return -1;
-    }
+  if (i > 0
+      && (gidx < i
+         || match_ids (gstring, gidx - 1, flag, i, rule->Backtrack, -1) < 0))
+    return -1;
   gidx++;
   i = match_ids (gstring, gidx, flag,
-                rule->InputGlyphCount - 1, rule->Input);
+                rule->InputGlyphCount - 1, rule->Input, 1);
   if (i < 0)
     return -1;
   gidx += i;
   i = match_ids (gstring, gidx, flag,
-                rule->LookaheadGlyphCount, rule->LookAhead);
+                rule->LookaheadGlyphCount, rule->LookAhead, 1);
   if (i < 0)
     return -1;
   return 0;
@@ -321,18 +315,17 @@ match_chain_ids (OTF_GlyphString *gstring, int gidx, int flag,
 
 static int
 match_classes (OTF_ClassDef *class_def, OTF_GlyphString *gstring, int gidx,
-              int flag, int count, unsigned *classes)
+              int flag, int count, unsigned *classes, int direction)
 {
-  OTF_Glyph *gbeg = gstring->glyphs + gidx;
-  OTF_Glyph *gend = gstring->glyphs + gstring->used;
-  OTF_Glyph *g;
-  int i;
+  OTF_Glyph *g = gstring->glyphs + gidx;
+  OTF_Glyph *gend = gstring->glyphs + (direction > 0 ? gstring->used : -1);
+  int i, j;
 
-  for (g = gbeg, i = 0; g < gend && i < count; g++)
+  for (i = j = 0; i < count && g != gend; j++, g += direction)
     if (! IGNORED_GLYPH (g, flag)
        && get_class_def (class_def, g->glyph_id) != classes[i++])
       return -1;
-  return (i < count ? -1 : g - gbeg);
+  return (i < count ? -1 : j);
 }
 
 static int
@@ -344,28 +337,19 @@ match_chain_classes (OTF_GlyphString *gstring, int gidx, int flag,
 {
   int i = rule->BacktrackGlyphCount;
 
-  if (i > 0)
-    {
-      int j;
-      OTF_Glyph *g;
-
-      for (j = gidx - 1, g = gstring->glyphs + j; j >= 0; j--, g--)
-       if (! IGNORED_GLYPH (g, flag) && i-- == 0)
-         break;
-      if (i > 0)
-       return -1;
-      if (match_classes (BacktrackClassDef, gstring, j, flag,
-                        rule->BacktrackGlyphCount, rule->Backtrack) < 0);
-      return -1;
-    }
+  if (i > 0
+      && (gidx < i
+         || match_classes (BacktrackClassDef, gstring, gidx - 1, flag, i,
+                           rule->Backtrack, -1) < 0))
+    return -1;
   gidx++;
   i = match_classes (InputClassDef, gstring, gidx, flag,
-                    rule->InputGlyphCount - 1, rule->Input);
+                    rule->InputGlyphCount - 1, rule->Input, 1);
   if (i < 0)
     return -1;
   gidx += i;
   i = match_classes (LookaheadClassDef, gstring, gidx, flag,
-                    rule->LookaheadGlyphCount, rule->LookAhead);
+                    rule->LookaheadGlyphCount, rule->LookAhead, 1);
   if (i < 0)
     return -1;
   return 0;
@@ -374,18 +358,17 @@ match_chain_classes (OTF_GlyphString *gstring, int gidx, int flag,
 
 static int
 match_coverages (OTF_GlyphString *gstring, int gidx, int flag, int count,
-                OTF_Coverage *coverages)
+                OTF_Coverage *coverages, int direction)
 {
-  OTF_Glyph *gbeg = gstring->glyphs + gidx;
-  OTF_Glyph *gend = gstring->glyphs + gstring->used;
-  OTF_Glyph *g;
-  int i;
+  OTF_Glyph *g = gstring->glyphs + gidx;
+  OTF_Glyph *gend = gstring->glyphs + (direction > 0 ? gstring->used : - 1);
+  int i, j;
 
-  for (g = gbeg, i = 0; g < gend && i < count; g++)
+  for (i = j = 0; i < count && g != gend; j++, g += direction)
     if (! IGNORED_GLYPH (g, flag)
        && get_coverage_index (coverages + i++, g->glyph_id) < 0)
       return -1;
-  return (i < count ? -1 : g - gbeg);
+  return (i < count ? -1 : j);
 }
 
 static int
@@ -394,35 +377,32 @@ match_chain_coverages (OTF_GlyphString *gstring, int gidx, int flag,
 {
   int i = context3->BacktrackGlyphCount;
 
-  if (i > 0)
-    {
-      int j;
-      OTF_Glyph *g;
-
-      for (j = gidx - 1, g= gstring->glyphs +j; j >= 0; j--, g--)
-       if (! IGNORED_GLYPH (g, flag) && --i == 0)
-         break;
-      if (i > 0)
-       return -1;
-      if (match_coverages (gstring, j, flag, context3->BacktrackGlyphCount,
-                          context3->Backtrack) < 0)
-       return -1;
-    }
+  if (i > 0
+      && (gidx < i
+         || match_coverages (gstring, gidx - 1, flag, i,
+                             context3->Backtrack, -1) < 0))
+    return -1;
   gidx++;
   if (context3->InputGlyphCount > 1)
     {
       i = match_coverages (gstring, gidx, flag, context3->InputGlyphCount - 1,
-                          context3->Input + 1);
+                          context3->Input + 1, 1);
       if (i < 0)
        return -1;
       gidx += i;
     }
   if (match_coverages (gstring, gidx, flag, context3->LookaheadGlyphCount,
-                      context3->LookAhead) < 0)
+                      context3->LookAhead, 1) < 0)
     return -1;
   return 0;
 }
 
+/* Apply the lookup indexed by LOOKUP_LIST_INDEX in LOOKUP_LIST to the
+   glyphs indexed by GIDX in GSTRING and the followings.  If
+   successfully applied, return the index of the next glyph to apply
+   the lookup.  If not applied, return GIDX.  If error happened,
+   return -1.  */
+
 static int
 lookup_gsub (OTF *otf, OTF_LookupList *lookup_list, unsigned lookup_list_index,
             OTF_GlyphString *gstring, int gidx, int alternate_subst)
@@ -437,7 +417,7 @@ lookup_gsub (OTF *otf, OTF_LookupList *lookup_list, unsigned lookup_list_index,
   int i;
 
   if (IGNORED_GLYPH (g, flag))
-    return (gidx + 1);
+    return gidx;
 
   /* Try all subtables until one of them handles the current glyph.  */
   for (i = 0; i < lookup->SubTableCount && gidx == orig_gidx; i++)
@@ -519,7 +499,7 @@ lookup_gsub (OTF *otf, OTF_LookupList *lookup_list, unsigned lookup_list_index,
 
                  lig = ligset->Ligature + j;
                  n = match_ids (gstring, gidx + 1, flag,
-                                lig->CompCount - 1, lig->Component);
+                                lig->CompCount - 1, lig->Component, 1);
                  if (n < 0)
                    continue;
                  gstring_subst (otf, gstring, gidx, gidx + 1 + n, flag,
@@ -545,7 +525,7 @@ lookup_gsub (OTF *otf, OTF_LookupList *lookup_list, unsigned lookup_list_index,
                {
                  rule = set->Rule + j;
                  if (match_ids (gstring, gidx + 1, flag,
-                                rule->GlyphCount - 1, rule->Input) < 0)
+                                rule->GlyphCount - 1, rule->Input, 1) < 0)
                    continue;
                  orig_used = gstring->used;
                  for (k = 0; k < rule->LookupCount; k++)
@@ -575,7 +555,7 @@ lookup_gsub (OTF *otf, OTF_LookupList *lookup_list, unsigned lookup_list_index,
                    rule = set->ClassRule + j;
                    if (match_classes (&context2->ClassDef,
                                       gstring, gidx + 1, flag,
-                                      rule->GlyphCount - 1, rule->Class)
+                                      rule->GlyphCount - 1, rule->Class, 1)
                        < 0)
                      continue;
                    orig_used = gstring->used;
@@ -597,7 +577,7 @@ lookup_gsub (OTF *otf, OTF_LookupList *lookup_list, unsigned lookup_list_index,
 
              if (match_coverages (gstring, gidx + 1, flag,
                                   context3->GlyphCount - 1,
-                                  context3->Coverage + 1) < 0)
+                                  context3->Coverage + 1, 1) < 0)
                continue;
              orig_used = gstring->used;
              for (j = 0; j < context3->LookupCount; j++)
@@ -617,7 +597,7 @@ lookup_gsub (OTF *otf, OTF_LookupList *lookup_list, unsigned lookup_list_index,
              OTF_ChainRuleSet *set = context1->ChainRuleSet + coverage_idx;
              int orig_used;
              int j, k;
-             
+
              for (j = 0; j < set->ChainRuleCount; j++)
                {
                  OTF_ChainRule *rule = set->ChainRule + j;
@@ -730,8 +710,6 @@ lookup_gsub (OTF *otf, OTF_LookupList *lookup_list, unsigned lookup_list_index,
          continue;
        }
     }
-  if (gidx == orig_gidx)
-    gidx++;
   return gidx;
 }
 
@@ -747,7 +725,7 @@ gstring_insert_for_gpos (OTF_GlyphString *gstring, int gidx)
 
   while (gidx < gstring->used
         && ! gstring->glyphs[gidx].glyph_id
-        && gstring->glyphs[gidx].positioning_type)
+        && (gstring->glyphs[gidx].positioning_type & 0xF))
     gidx++;
   GSTRING_INSERT (gstring, gidx, 1);
   gstring->glyphs[gidx] = gstring->glyphs[orig_gidx];
@@ -775,7 +753,7 @@ print_glyph_positioning (OTF_Glyph *g, int type)
 {
   if (type)
     fprintf (stderr, " %0X=", g->glyph_id);
-  switch (g->positioning_type)
+  switch (g->positioning_type & 0xF)
     {
     case 1: case 2:
       {
@@ -814,6 +792,8 @@ print_glyph_positioning (OTF_Glyph *g, int type)
     }
 }
 
+/* See the comment of lookup_gsub.  */
+
 static int
 lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
             OTF_GlyphString *gstring, int gidx, int accumulate)
@@ -834,7 +814,7 @@ lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
     {
       if (debug_flag)
        fprintf (stderr, " glyph ignored\n");
-      return (gidx + 1);
+      return gidx;
     }
 
   /* Try all subtables until one of them handles the current glyph.  */
@@ -886,10 +866,11 @@ lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
            }
          if (accumulate && g->positioning_type)
            {
-             gidx = gstring_insert_for_gpos (gstring, gidx);         
+             gidx = gstring_insert_for_gpos (gstring, gidx);
              g = gstring->glyphs + gidx;
            }
-         g->positioning_type = positioning_type;
+         g->positioning_type
+           = (g->positioning_type & 0xFFFFFFF0) | positioning_type;
          g->f.f1.format = format;
          g->f.f1.value = value;
          if (debug_flag)
@@ -919,14 +900,15 @@ lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
                    {
                      if (pair1->ValueFormat1)
                        {
-                         if (accumulate && g->positioning_type)
+                         if (accumulate && (g->positioning_type & 0xF))
                            {
                              gidx = gstring_insert_for_gpos (gstring, gidx);
                              g = gstring->glyphs + gidx;
                              next_gidx += gidx - orig_gidx;
                              nextg = gstring->glyphs + next_gidx;
                            }
-                         g->positioning_type = lookup_type;
+                         g->positioning_type
+                           = (g->positioning_type & 0xFFFFFFF0) | lookup_type;
                          g->f.f2.format = pair1->ValueFormat1;
                          g->f.f2.value = &set->PairValueRecord[j].Value1;
                          if (debug_flag)
@@ -936,12 +918,13 @@ lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
                      g = nextg;
                      if (pair1->ValueFormat2)
                        {
-                         if (accumulate && g->positioning_type)
+                         if (accumulate && (g->positioning_type & 0xF))
                            {
                              gidx = gstring_insert_for_gpos (gstring, gidx);
                              g = gstring->glyphs + gidx;
                            }
-                         g->positioning_type = lookup_type;
+                         g->positioning_type
+                           = (g->positioning_type & 0xFFFFFFF0) | lookup_type;
                          g->f.f2.format = pair1->ValueFormat2;
                          g->f.f2.value = &set->PairValueRecord[j].Value2;
                          if (debug_flag)
@@ -959,14 +942,15 @@ lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
                class2 = get_class_def (&pair2->ClassDef2, nextg->glyph_id);
                if (pair2->ValueFormat1)
                  {
-                   if (accumulate && g->positioning_type)
+                   if (accumulate && (g->positioning_type & 0xF))
                      {
                        gidx = gstring_insert_for_gpos (gstring, gidx);
                        g = gstring->glyphs + gidx;
                        next_gidx += gidx - orig_gidx;
                        nextg = gstring->glyphs + next_gidx;
                      }
-                   g->positioning_type = lookup_type;
+                   g->positioning_type
+                   = (g->positioning_type & 0xFFFFFFF0) | lookup_type;
                    g->f.f2.format = pair2->ValueFormat1;
                    g->f.f2.value
                      = &pair2->Class1Record[class1].Class2Record[class2].Value1;
@@ -977,12 +961,13 @@ lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
                g = nextg;
                if (pair2->ValueFormat2)
                  {
-                   if (accumulate && g->positioning_type)
+                   if (accumulate && (g->positioning_type & 0xF))
                      {
                        gidx = gstring_insert_for_gpos (gstring, gidx);
                        g = gstring->glyphs + gidx;
                      }
-                   g->positioning_type = lookup_type;
+                   g->positioning_type
+                     = (g->positioning_type & 0xFFFFFFF0) | lookup_type;
                    g->f.f2.format = pair2->ValueFormat2;
                    g->f.f2.value
                      = &pair2->Class1Record[class1].Class2Record[class2].Value2;
@@ -996,8 +981,9 @@ lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
        case 3:
          {
            OTF_GPOS_Cursive1 *cursive1 = &subtable->u.cursive1;
-         
-           g->positioning_type = lookup_type;
+
+           g->positioning_type
+           = (g->positioning_type & 0xFFFFFFF0) | lookup_type;
            g->f.f3.entry_anchor
              = &cursive1->EntryExitRecord[coverage_idx].EntryAnchor;
            g->f.f3.exit_anchor
@@ -1036,7 +1022,8 @@ lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
              g->f.f4.mark_anchor = &mark_record->MarkAnchor;
              g->f.f4.base_anchor
                = &base_record->Anchor[mark_record->Class];
-             g->positioning_type = lookup_type;
+             g->positioning_type
+               = (g->positioning_type & 0xFFFFFFF0) | lookup_type;
              if (debug_flag)
                print_glyph_positioning (g, 0);
              gidx++;
@@ -1055,7 +1042,7 @@ lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
              OTF_LigatureAttach *attach;
              int *num_class = alloca (sizeof (int) * mark_lig1->ClassCount);
              int j;
-                                      
+
              for (j = 0; j < mark_lig1->ClassCount; j++)
                num_class[j] = 0;
 
@@ -1064,7 +1051,7 @@ lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
                    && (IGNORED_GLYPH (ligg, flag)
                        || ligg->GlyphClass > OTF_GlyphClassLigature));
                   ligg--)
-               if (ligg->positioning_type == 5
+               if ((ligg->positioning_type & 0xF) == 5
                    && ligg->MarkAttachClass < mark_lig1->ClassCount)
                  num_class[ligg->MarkAttachClass]++;
              if (ligg < gstring->glyphs)
@@ -1086,7 +1073,8 @@ lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
                  if (lig_anchor[mark_record->Class].AnchorFormat
                      && num_class[mark_record->Class]-- == 0)
                    {
-                     g->positioning_type = lookup_type;
+                     g->positioning_type
+                       = (g->positioning_type & 0xFFFFFFF0) | lookup_type;
                      g->f.f5.mark_anchor = &mark_record->MarkAnchor;
                      g->f.f5.ligature_anchor = lig_anchor + mark_record->Class;
                      if (debug_flag)
@@ -1125,7 +1113,8 @@ lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
              g->f.f6.mark1_anchor = &mark1_record->MarkAnchor;
              g->f.f6.mark2_anchor
                = &mark2_record->Anchor[mark1_record->Class];
-             g->positioning_type = lookup_type;
+             g->positioning_type
+               = (g->positioning_type & 0xFFFFFFF0) | lookup_type;
              if (debug_flag)
                print_glyph_positioning (g, 0);
              gidx++;
@@ -1146,7 +1135,7 @@ lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
                {
                  rule = set->Rule + j;
                  if (match_ids (gstring, gidx + 1, flag,
-                                rule->GlyphCount - 1, rule->Input) < 0)
+                                rule->GlyphCount - 1, rule->Input, 1) < 0)
                    continue;
                  orig_used = gstring->used;
                  for (k = 0; k < rule->LookupCount; k++)
@@ -1176,7 +1165,7 @@ lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
                    rule = set->ClassRule + j;
                    if (match_classes (&context2->ClassDef,
                                       gstring, gidx + 1, flag,
-                                      rule->GlyphCount - 1, rule->Class)
+                                      rule->GlyphCount - 1, rule->Class, 1)
                        < 0)
                      continue;
                    orig_used = gstring->used;
@@ -1198,7 +1187,7 @@ lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
 
              if (match_coverages (gstring, gidx + 1, flag,
                                   context3->GlyphCount - 1,
-                                  context3->Coverage + 1) < 0)
+                                  context3->Coverage + 1, 1) < 0)
                continue;
              orig_used = gstring->used;
              for (j = 0; j < context3->LookupCount; j++)
@@ -1218,7 +1207,7 @@ lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
              OTF_ChainRuleSet *set = context1->ChainRuleSet + coverage_idx;
              int orig_used;
              int j, k;
-             
+
              for (j = 0; j < set->ChainRuleCount; j++)
                {
                  OTF_ChainRule *rule = set->ChainRule + j;
@@ -1305,14 +1294,13 @@ lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
          continue;
        }
     }
-  if (gidx == orig_gidx)
+  if (debug_flag)
     {
-      if (debug_flag)
+      if (gidx == orig_gidx)
        fprintf (stderr, " no match\n");
-      gidx++;
+      else
+       fprintf (stderr, "\n");
     }
-  else if (debug_flag)
-    fprintf (stderr, "\n");
   return gidx;
 }
 
@@ -1485,7 +1473,7 @@ get_uvs_glyph (OTF_cmap *cmap, OTF_EncodingSubtable14 *sub14, int c1, int c2)
 
 static void
 check_cmap_uvs (OTF_cmap *cmap, OTF_GlyphString *gstring, int idx)
-{  
+{
   OTF_EncodingSubtable14 *sub14;
   int c1 = gstring->glyphs[idx - 1].c;
   int c2 = gstring->glyphs[idx].c;
@@ -1736,19 +1724,20 @@ static int
 OTF_drive_gsub_internal (OTF *otf, OTF_GlyphString *gstring,
                         const char *script, const char *language,
                         const char *features,
-                        int alternate_subst)
+                        int alternate_subst, int with_log)
 {
   char *errfmt = "GSUB driving%s";
   int errret = -1;
   OTF_GSUB *gsub;
   OTF_LangSys *LangSys;
-  char *lookup_flags;
+  USHORT *lookup_flags;
   int i;
-
+  USHORT *log;
+  
   for (i = 0; i < gstring->used; i++)
     {
-      gstring->glyphs[i].positioning_type = 0;
       gstring->glyphs[i].f.index.from = gstring->glyphs[i].f.index.to = i;
+      gstring->glyphs[i].positioning_type = 0;
     }
 
   if (OTF_get_table (otf, "GSUB") < 0)
@@ -1762,7 +1751,7 @@ OTF_drive_gsub_internal (OTF *otf, OTF_GlyphString *gstring,
   if (! LangSys)
     return errret;
 
-  lookup_flags = alloca (gsub->LookupList.LookupCount);
+  lookup_flags = alloca (sizeof (USHORT) * gsub->LookupList.LookupCount);
   if (! lookup_flags
       || setup_lookup_flags (&gsub->LookupList, &gsub->FeatureList, LangSys,
                             features, lookup_flags) < 0)
@@ -1771,6 +1760,7 @@ OTF_drive_gsub_internal (OTF *otf, OTF_GlyphString *gstring,
   for (i = 0; i < gsub->LookupList.LookupCount; i++)
     {
       int gidx;
+      int j;
 
       if (! lookup_flags[i]) continue;
 
@@ -1779,10 +1769,21 @@ OTF_drive_gsub_internal (OTF *otf, OTF_GlyphString *gstring,
          gidx = 0;
          while (gidx < gstring->used)
            {
-             gidx = lookup_gsub (otf, &gsub->LookupList, i, gstring, gidx,
-                                 alternate_subst);
-             if (gidx < 0)
+             int result = lookup_gsub (otf, &gsub->LookupList, i, gstring,
+                                       gidx, alternate_subst);
+             if (result < 0)
                return errret;
+             if (gidx < result)
+               {
+                 if (with_log)
+                   for (j = gidx; j < result; j++)
+                     gstring->glyphs[j].positioning_type
+                       = ((gstring->glyphs[j].positioning_type & 0xF)
+                          | (lookup_flags[i] << 4));
+                 gidx = result;
+               }
+             else
+               gidx++;
            }
        }
       else
@@ -1790,10 +1791,21 @@ OTF_drive_gsub_internal (OTF *otf, OTF_GlyphString *gstring,
          gidx = gstring->used - 1;
          while (gidx >= 0)
            {
-             gidx = lookup_gsub (otf, &gsub->LookupList, i, gstring, gidx,
-                                 alternate_subst);
-             if (gidx < 0)
+             int result = lookup_gsub (otf, &gsub->LookupList, i, gstring,
+                                       gidx, alternate_subst);
+             if (result < 0)
                return errret;
+             if (gidx > result)
+               {
+                 if (with_log)
+                   for (j = gidx; j > result; j--)
+                     gstring->glyphs[j].positioning_type
+                       = ((gstring->glyphs[j].positioning_type & 0xF)
+                          | (lookup_flags[i] << 4));
+                 gidx = result;
+               }
+             else
+               gidx--;
            }
        }
     }
@@ -1807,20 +1819,32 @@ OTF_drive_gsub (OTF *otf, OTF_GlyphString *gstring,
 {
   if (! otf->cmap)
     OTF_get_table (otf, "cmap");
-  return OTF_drive_gsub_internal (otf, gstring, script, language, features, 0);
+  return OTF_drive_gsub_internal (otf, gstring, script, language, features,
+                                 0, 0);
 }
 
 int
+OTF_drive_gsub_with_log (OTF *otf, OTF_GlyphString *gstring,
+                        const char *script, const char *language,
+                        const char *features)
+{
+  if (! otf->cmap)
+    OTF_get_table (otf, "cmap");
+  return OTF_drive_gsub_internal (otf, gstring, script, language, features,
+                                 0, 1);
+}
+
+static int
 OTF_drive_gpos_internal (OTF *otf, OTF_GlyphString *gstring,
                         const char *script, const char *language,
                         const char *features,
-                        int accumulate)
+                        int accumulate, int with_log)
 {
   char *errfmt = "GPOS driving%s";
   int errret = -1;
   OTF_GPOS *gpos;
   OTF_LangSys *LangSys;
-  char *lookup_flags;
+  USHORT *lookup_flags;
   int i, n;
 
   for (i = 0; i < gstring->used; i++)
@@ -1837,7 +1861,7 @@ OTF_drive_gpos_internal (OTF *otf, OTF_GlyphString *gstring,
   if (! LangSys)
     return errret;
 
-  lookup_flags = alloca (gpos->LookupList.LookupCount);
+  lookup_flags = alloca (sizeof (USHORT) * gpos->LookupList.LookupCount);
   if (! lookup_flags
       || setup_lookup_flags (&gpos->LookupList, &gpos->FeatureList, LangSys,
                             features, lookup_flags) < 0)
@@ -1846,14 +1870,27 @@ OTF_drive_gpos_internal (OTF *otf, OTF_GlyphString *gstring,
   for (i = 0; i < gpos->LookupList.LookupCount; i++)
     {
       int gidx = 0;
+      int j;
 
       if (! lookup_flags[i]) continue;
 
       while (gidx < gstring->used)
        {
-         gidx = lookup_gpos (&gpos->LookupList, i, gstring, gidx, accumulate);
-         if (gidx < 0)
+         int result = lookup_gpos (&gpos->LookupList, i, gstring, gidx,
+                                   accumulate);
+         if (result < 0)
            return errret;
+         if (gidx < result)
+           {
+             if (with_log)
+               for (j = gidx; j < result; j++)
+                 gstring->glyphs[j].positioning_type
+                   = ((gstring->glyphs[j].positioning_type & 0xF)
+                      | (lookup_flags[i] << 4));
+             gidx = result;
+           }
+         else
+           gidx++;
        }
     }
 
@@ -1866,7 +1903,8 @@ OTF_drive_gpos (OTF *otf, OTF_GlyphString *gstring,
 {
   if (! otf->cmap)
     OTF_get_table (otf, "cmap");
-  return OTF_drive_gpos_internal (otf, gstring, script, language, features, 0);
+  return OTF_drive_gpos_internal (otf, gstring, script, language, features,
+                                 0, 0);
 }
 
 int
@@ -1875,7 +1913,19 @@ OTF_drive_gpos2 (OTF *otf, OTF_GlyphString *gstring,
 {
   if (! otf->cmap)
     OTF_get_table (otf, "cmap");
-  return OTF_drive_gpos_internal (otf, gstring, script, language, features, 1);
+  return OTF_drive_gpos_internal (otf, gstring, script, language, features,
+                                 1, 0);
+}
+
+int
+OTF_drive_gpos_with_log (OTF *otf, OTF_GlyphString *gstring,
+                        const char *script, const char *language,
+                        const char *features)
+{
+  if (! otf->cmap)
+    OTF_get_table (otf, "cmap");
+  return OTF_drive_gpos_internal (otf, gstring, script, language, features,
+                                 1, 1);
 }
 
 int
@@ -1901,11 +1951,12 @@ OTF_drive_gsub_alternate (OTF *otf, OTF_GlyphString *gstring,
                          const char *script, const char *language,
                          const char *features)
 {
-  return OTF_drive_gsub_internal (otf, gstring, script, language, features, 1);
+  return OTF_drive_gsub_internal (otf, gstring, script, language, features,
+                                 1, 0);
 }
 
 static int
-iterate_coverage (OTF *otf, const char *feature, 
+iterate_coverage (OTF *otf, const char *feature,
                  OTF_Feature_Callback callback,
                  OTF_Coverage *coverage)
 {
@@ -2052,7 +2103,7 @@ OTF_iterate_gsub_feature (OTF *otf, OTF_Feature_Callback callback,
 
   OTF_GSUB *gsub;
   OTF_LangSys *langsys;
-  char *lookup_flags;
+  USHORT *lookup_flags;
 
   if (OTF_get_table (otf, "GSUB") < 0)
     return errret;
@@ -2063,7 +2114,7 @@ OTF_iterate_gsub_feature (OTF *otf, OTF_Feature_Callback callback,
   langsys = get_langsys (&gsub->ScriptList, script, language);
   if (! langsys)
     return errret;
-  lookup_flags = alloca (gsub->LookupList.LookupCount);
+  lookup_flags = alloca (sizeof (USHORT) * gsub->LookupList.LookupCount);
   if (! lookup_flags
       || setup_lookup_flags (&gsub->LookupList, &gsub->FeatureList, langsys,
                             feature, lookup_flags) < 0)