*** empty log message ***
authorhanda <handa>
Tue, 29 Sep 2009 06:12:47 +0000 (06:12 +0000)
committerhanda <handa>
Tue, 29 Sep 2009 06:12:47 +0000 (06:12 +0000)
ChangeLog
src/otf.h
src/otfdrive.c

index 7bbd072..919fdb2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2009-09-29  Kenichi Handa  <handa@m17n.org>
+
+       * src/otf.h (OTF_Feature_Callback): New type.
+       (OTF_iterate_gsub_feature): Extern it.
+
+       * src/otfdrive.c (OTF_iterate_gsub_feature): New function.
+
 2009-08-13  Kenichi Handa  <handa@m17n.org>
 
        * Version 0.9.10 released.
index 200695d..afdbdb2 100644 (file)
--- a/src/otf.h
+++ b/src/otf.h
@@ -69,6 +69,7 @@ extern "C" {
     (3-6) OTF_drive_tables()
     (3-7) OTF_get_unicode()
     (3-8) OTF_drive_gsub_alternate()
+    (3-9) OTF_iterate_on_feature()
 
     (4) API for error handling
     (4-1) Error codes
@@ -1417,6 +1418,14 @@ extern int OTF_drive_gsub_alternate (OTF *otf, OTF_GlyphString *gstring,
                                     const char *script, const char *language,
                                     const char *features);
 
+/*** (3-9) OTF_iterate_on_feature() */
+typedef int (*OTF_Feature_Callback) (OTF *otf, const char *feature,
+                                    int c, unsigned glyph_id);
+
+extern int OTF_iterate_gsub_feature (OTF *otf, OTF_Feature_Callback callback,
+                                    const char *script, const char *language,
+                                    const char *feature);
+
 /*** (4) API for error handling ***/
 
 /*** (4-1) Error codes ***/
index bb65f7e..51e62f5 100644 (file)
@@ -1846,3 +1846,105 @@ 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)
+{
+  char *errfmt = "GSUB iterate feature%s";
+  int errret = -1;
+  int i, j, k, l, m;
+
+  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++)
+    {
+      OTF_Lookup *lookup;
+
+      if (! lookup_flags[i]) continue;
+      lookup = gsub->LookupList.Lookup + i;
+      for (j = 0; j < lookup->SubTableCount; j++)
+       {
+         unsigned lookup_type = lookup->LookupType;
+         OTF_LookupSubTableGSUB *subtable = lookup->SubTable.gsub + j;
+         int coverage_idx;
+
+         if (lookup_type == 7)
+           {
+             OTF_GSUB_Extension1 *extension1 = &subtable->u.extension1;
+
+             lookup_type = extension1->ExtensionLookupType;
+             subtable = extension1->ExtensionSubtable;
+           }
+         if ((lookup_type >= 1 && lookup_type <= 4) || lookup_type == 8)
+           {
+             OTF_Coverage *coverage = &subtable->Coverage;
+
+             if (coverage->CoverageFormat == 1)
+               {
+                 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;
+                   }
+               }
+             else
+               {
+                 for (k = 0; k < coverage->Count; k++)
+                   {
+                     OTF_RangeRecord *range = coverage->table.RangeRecord + k;
+                     unsigned id;
+                     for (id = range->Start; id <= range->End; id++)
+                       {
+                         int c = OTF_get_unicode (otf, id);
+                         if (callback (otf, feature, c, id) < 0)
+                           return 0;
+                       }
+                   }
+               }
+
+             if (lookup_type == 4)
+               {
+                 OTF_GSUB_Ligature1 *lig1 = &subtable->u.ligature1;
+
+                 for (k = 0; k < lig1->LigSetCount; k++)
+                   {
+                     OTF_LigatureSet *ligset = lig1->LigatureSet + k;
+
+                     for (l = 0; l < ligset->LigatureCount; 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;
+                           }
+                       }
+                   }
+               }
+           }
+       }
+    }
+}