Fix previous change.
authorhanda <handa>
Tue, 29 Sep 2009 08:09:05 +0000 (08:09 +0000)
committerhanda <handa>
Tue, 29 Sep 2009 08:09:05 +0000 (08:09 +0000)
src/otf.h
src/otfdrive.c

index afdbdb2..2564b80 100644 (file)
--- a/src/otf.h
+++ b/src/otf.h
@@ -1420,7 +1420,7 @@ extern int OTF_drive_gsub_alternate (OTF *otf, OTF_GlyphString *gstring,
 
 /*** (3-9) OTF_iterate_on_feature() */
 typedef int (*OTF_Feature_Callback) (OTF *otf, const char *feature,
-                                    int c, unsigned glyph_id);
+                                    unsigned glyph_id);
 
 extern int OTF_iterate_gsub_feature (OTF *otf, OTF_Feature_Callback callback,
                                     const char *script, const char *language,
index 51e62f5..24981a0 100644 (file)
@@ -1847,104 +1847,175 @@ OTF_drive_gsub_alternate (OTF *otf, OTF_GlyphString *gstring,
   return OTF_drive_gsub_internal (otf, gstring, script, language, features, 1);
 }
 
-int
-OTF_iterate_gsub_feature (OTF *otf, OTF_Feature_Callback callback,
-                         const char *script, const char *language,
-                         const char *feature)
+static int
+iterate_coverage (OTF *otf, const char *feature, 
+                 OTF_Feature_Callback callback,
+                 OTF_Coverage *coverage)
 {
-  char *errfmt = "GSUB iterate feature%s";
-  int errret = -1;
-  int i, j, k, l, m;
+  int i;
 
-  OTF_GSUB *gsub;
-  OTF_LangSys *langsys;
-  char *lookup_flags;
+  if (coverage->CoverageFormat == 1)
+    {
+      for (i = 0; i < coverage->Count; i++)
+       if (callback (otf, feature, coverage->table.GlyphArray[i]) < 0)
+         return -1;
+    }
+  else
+    {
+      for (i = 0; i < coverage->Count; i++)
+       {
+         OTF_RangeRecord *range = coverage->table.RangeRecord + i;
+         unsigned id;
+         for (id = range->Start; id <= range->End; id++)
+           if (callback (otf, feature, id) < 0)
+             return -1;
+       }
+    }
+  return 0;
+}
 
-  if (OTF_get_table (otf, "GSUB") < 0)
-    return errret;
-  gsub = otf->gsub;
-  if (gsub->FeatureList.FeatureCount == 0
-      || gsub->LookupList.LookupCount == 0)
-    return 0;
-  langsys = get_langsys (&gsub->ScriptList, script, language);
-  if (! langsys)
-    return errret;
-  lookup_flags = alloca (gsub->LookupList.LookupCount);
-  if (! lookup_flags
-      || setup_lookup_flags (&gsub->LookupList, &gsub->FeatureList, langsys,
-                            feature, lookup_flags) < 0)
-    OTF_ERROR (OTF_ERROR_MEMORY, " feature");
+static int
+iterate_feature (OTF *otf, const char *feature,
+                OTF_Feature_Callback callback,
+                OTF_Lookup *lookup)
+{
+  int i, j, k, l;
 
-  for (i = 0; i < gsub->LookupList.LookupCount; i++)
+  for (i = 0; i < lookup->SubTableCount; i++)
     {
-      OTF_Lookup *lookup;
+      unsigned lookup_type = lookup->LookupType;
+      OTF_LookupSubTableGSUB *subtable = lookup->SubTable.gsub + i;
 
-      if (! lookup_flags[i]) continue;
-      lookup = gsub->LookupList.Lookup + i;
-      for (j = 0; j < lookup->SubTableCount; j++)
+      if (lookup_type == 7)
        {
-         unsigned lookup_type = lookup->LookupType;
-         OTF_LookupSubTableGSUB *subtable = lookup->SubTable.gsub + j;
-         int coverage_idx;
+         OTF_GSUB_Extension1 *extension1 = &subtable->u.extension1;
 
-         if (lookup_type == 7)
-           {
-             OTF_GSUB_Extension1 *extension1 = &subtable->u.extension1;
+         lookup_type = extension1->ExtensionLookupType;
+         subtable = extension1->ExtensionSubtable;
+       }
 
-             lookup_type = extension1->ExtensionLookupType;
-             subtable = extension1->ExtensionSubtable;
-           }
-         if ((lookup_type >= 1 && lookup_type <= 4) || lookup_type == 8)
+      if ((lookup_type >= 1 && lookup_type <= 3) || lookup_type == 8)
+       {
+         if (iterate_coverage (otf, feature, callback, &subtable->Coverage)
+             < 0)
+           return -1;
+       }
+      else if (lookup_type == 4)
+       {
+         OTF_GSUB_Ligature1 *lig1;
+
+         if (iterate_coverage (otf, feature, callback, &subtable->Coverage)
+             < 0)
+           return -1;
+         lig1 = &subtable->u.ligature1;
+         for (j = 0; j < lig1->LigSetCount; j++)
            {
-             OTF_Coverage *coverage = &subtable->Coverage;
+             OTF_LigatureSet *ligset = lig1->LigatureSet + j;
 
-             if (coverage->CoverageFormat == 1)
+             for (k = 0; k < ligset->LigatureCount; k++)
                {
-                 for (k = 0; k < coverage->Count; k++)
-                   {
-                     unsigned id = coverage->table.GlyphArray[k];
-                     int c = OTF_get_unicode (otf, id);
-                     if (callback (otf, feature, c, id) < 0)
-                       return 0;
-                   }
+                 OTF_Ligature *lig = ligset->Ligature + k;
+                 for (l = 0; l < lig->CompCount - 1; l++)
+                   if (callback (otf, feature, lig->Component[l]) < 0)
+                     return -1;
                }
-             else
+           }
+       }
+      else if (lookup_type == 6)
+       {
+         if (subtable->Format == 1)
+           {
+             OTF_GSUB_ChainContext1 *context1 = &subtable->u.chain_context1;
+             for (j = 0; j < context1->ChainRuleSetCount; j++)
                {
-                 for (k = 0; k < coverage->Count; k++)
+                 OTF_ChainRuleSet *set = context1->ChainRuleSet + j;
+                 for (k = 0; k < set->ChainRuleCount; k++)
                    {
-                     OTF_RangeRecord *range = coverage->table.RangeRecord + k;
-                     unsigned id;
-                     for (id = range->Start; id <= range->End; id++)
+                     OTF_ChainRule *rule = set->ChainRule + k;
+                     for (l = 0; l < rule->LookupCount; l++)
                        {
-                         int c = OTF_get_unicode (otf, id);
-                         if (callback (otf, feature, c, id) < 0)
-                           return 0;
+                         OTF_Lookup *lkup
+                           = (otf->gsub->LookupList.Lookup
+                              + rule->LookupRecord[l].LookupListIndex);
+                         if (iterate_feature (otf, feature, callback, lkup)
+                             < 0)
+                           return -1;
                        }
                    }
                }
+           }
+         else if (subtable->Format == 2)
+           {
+             OTF_GSUB_ChainContext2 *context2 = &subtable->u.chain_context2;
 
-             if (lookup_type == 4)
+             for (j = 0; j < context2->ChainClassSetCnt; j++)
                {
-                 OTF_GSUB_Ligature1 *lig1 = &subtable->u.ligature1;
-
-                 for (k = 0; k < lig1->LigSetCount; k++)
+                 OTF_ChainClassSet *set = context2->ChainClassSet + j;
+                 for (k = 0; k < set->ChainClassRuleCnt; j++)
                    {
-                     OTF_LigatureSet *ligset = lig1->LigatureSet + k;
+                     OTF_ChainClassRule *rule = set->ChainClassRule + k;
 
-                     for (l = 0; l < ligset->LigatureCount; l++)
+                     for (l = 0; l < rule->LookupCount; l++)
                        {
-                         OTF_Ligature *lig = ligset->Ligature + l;
-                         for (m = 0; m < lig->CompCount - 1; m++)
-                           {
-                             unsigned id = lig->Component[m];
-                             int c = OTF_get_unicode (otf, id);
-                             if (callback (otf, feature, c, id) < 0)
-                               return 0;
-                           }
+                         OTF_Lookup *lkup
+                           = (otf->gsub->LookupList.Lookup
+                              + rule->LookupRecord[k].LookupListIndex);
+                         if (iterate_feature (otf, feature, callback, lkup)
+                             < 0)
+                           return -1;
                        }
                    }
                }
            }
+         else
+           {
+             OTF_GSUB_ChainContext3 *context3 = &subtable->u.chain_context3;
+             for (j = 0; j < context3->LookupCount; j++)
+               {
+                 OTF_Lookup *lkup
+                   = (otf->gsub->LookupList.Lookup
+                      + context3->LookupRecord[j].LookupListIndex);
+                 if (iterate_feature (otf, feature, callback, lkup) < 0)
+                   return -1;
+               }
+           }
        }
     }
+  return 0;
+}
+
+int
+OTF_iterate_gsub_feature (OTF *otf, OTF_Feature_Callback callback,
+                         const char *script, const char *language,
+                         const char *feature)
+{
+  char *errfmt = "GSUB iterate feature%s";
+  int errret = -1;
+  int i;
+
+  OTF_GSUB *gsub;
+  OTF_LangSys *langsys;
+  char *lookup_flags;
+
+  if (OTF_get_table (otf, "GSUB") < 0)
+    return errret;
+  gsub = otf->gsub;
+  if (gsub->FeatureList.FeatureCount == 0
+      || gsub->LookupList.LookupCount == 0)
+    return 0;
+  langsys = get_langsys (&gsub->ScriptList, script, language);
+  if (! langsys)
+    return errret;
+  lookup_flags = alloca (gsub->LookupList.LookupCount);
+  if (! lookup_flags
+      || setup_lookup_flags (&gsub->LookupList, &gsub->FeatureList, langsys,
+                            feature, lookup_flags) < 0)
+    OTF_ERROR (OTF_ERROR_MEMORY, " feature");
+
+  for (i = 0; i < gsub->LookupList.LookupCount; i++)
+    if (lookup_flags[i])
+      if (iterate_feature (otf, feature, callback, gsub->LookupList.Lookup + i)
+         < 0)
+       return -1;
+  return 0;
 }