*** empty log message ***
authorhanda <handa>
Fri, 22 Aug 2003 03:26:44 +0000 (03:26 +0000)
committerhanda <handa>
Fri, 22 Aug 2003 03:26:44 +0000 (03:26 +0000)
example/otfdraw.c
example/otfdump.c
example/otflist.c
example/otfview.c
src/otf.h
src/otfdrive.c
src/otfopen.c

index 0218d01..609a3f2 100644 (file)
@@ -72,7 +72,7 @@ main (int argc, char **argv)
 
   if (argc != 2)
     {
-      fprintf (stderr, "Usage, dtfdump OTF-FILE");
+      fprintf (stderr, "Usage, otfdump OTF-FILE");
       exit (1);
     }
   
index 80b580d..71531ca 100644 (file)
@@ -770,6 +770,16 @@ dump_lookup_subtable_gsub (int indent, int index, unsigned type,
       break;
 
     case 7:
+      IPRINT ("(ExtensionLookupType %d)",
+             subtable->u.extension1.ExtensionLookupType);
+      IPRINT ("(ExtensionOffset %d)",
+             subtable->u.extension1.ExtensionOffset);
+      dump_lookup_subtable_gsub (indent, index, 
+                                subtable->u.extension1.ExtensionLookupType,
+                                (subtable
+                                 + subtable->u.extension1.ExtensionOffset));
+      break;
+
     case 8:
       printf (" not-yet-substcount");
       break;
index e38378e..5bd967b 100644 (file)
@@ -1,4 +1,5 @@
 #include <stdio.h>
+#include <unistd.h>
 #include <string.h>
 #include <dirent.h>
 
@@ -23,10 +24,10 @@ filter (const struct dirent *direntry)
 }
 
 int
-main ()
+main (int argc, char **argv)
 { 
   struct dirent **namelist;
-  int n = scandir (".", &namelist, filter, alphasort);
+  int n;
   int i, j;
   FT_Library ft_library;
   FT_Face face;
@@ -34,49 +35,26 @@ main ()
   if (FT_Init_FreeType (&ft_library))
     exit (1);
 
+  if (argc == 2)
+    chdir (argv[1]);
+  n = scandir (".", &namelist, filter, alphasort);
+
   for (i = 0; i < n; i++)
     if (! FT_New_Face (ft_library, namelist[i]->d_name, 0, &face))
       {
-       printf ("%s: %s: %s\n", namelist[i]->d_name,
-               face->family_name, face->style_name);
-       if (face->num_charmaps == 0)
-         continue;
+       char *name = alloca (strlen (namelist[i]->d_name)
+                            + strlen (face->family_name)
+                            + 4);
+       sprintf (name, "%s (%s)", namelist[i]->d_name, face->family_name);
+       printf ("%-40s %s", name, face->style_name);
        for (j = 0; j < face->num_charmaps; j++)
-         {
-           if (face->charmaps[j]->encoding == ft_encoding_symbol)
-             printf (" symbol");
-           else if (face->charmaps[j]->encoding == ft_encoding_unicode)
-             printf (" unicode");
-           else if (face->charmaps[j]->encoding == ft_encoding_latin_1)
-             printf (" latin_1");
-           else if (face->charmaps[j]->encoding == ft_encoding_latin_2)
-             printf (" latin_2");
-           else if (face->charmaps[j]->encoding == ft_encoding_sjis)
-             printf (" sjis");
-           else if (face->charmaps[j]->encoding == ft_encoding_gb2312)
-             printf (" gb2312");
-           else if (face->charmaps[j]->encoding == ft_encoding_big5)
-             printf (" big5");
-           else if (face->charmaps[j]->encoding == ft_encoding_wansung)
-             printf (" wansung");
-           else if (face->charmaps[j]->encoding == ft_encoding_johab)
-             printf (" johab");
-           else if (face->charmaps[j]->encoding == ft_encoding_adobe_standard)
-             printf (" adobe_standard");
-           else if (face->charmaps[j]->encoding == ft_encoding_adobe_expert)
-             printf (" adobe_expert");
-           else if (face->charmaps[j]->encoding == ft_encoding_adobe_custom)
-             printf (" adobe_custom");
-           else if (face->charmaps[j]->encoding == ft_encoding_apple_roman)
-             printf (" apple_roman");
-           else if (face->charmaps[j]->encoding == ft_encoding_none)
-             printf (" none");
-           else
-             printf (" 0x%X", (unsigned) face->charmaps[j]->encoding);
-           printf ("(%d-%d),", face->charmaps[j]->platform_id,
-                   face->charmaps[j]->encoding_id);
-         }
+         printf (" %d-%d", face->charmaps[j]->platform_id,
+                 face->charmaps[j]->encoding_id);
        printf ("\n");
       }
+    else
+      {
+       printf ("%s fail to open\n", namelist[i]->d_name);
+      }
   exit (0);
 }
index cf46900..ab35173 100644 (file)
@@ -304,12 +304,12 @@ create_widgets ()
       XtAddCallback (charmap[i + 1], XtNcallback, CharmapProc, (XtPointer) i);
     }
 
-  XtSetArg (arg[0], XtNlabel, "<< (P)");
+  XtSetArg (arg[0], XtNlabel, "-0x1000 (P)");
   XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (PREV_action));
   PREV = XtCreateManagedWidget ("PREV", commandWidgetClass,
                                navi_area, arg, 2);
   XtAddCallback (PREV, XtNcallback, GlyphProc, (XtPointer) -2);
-  XtSetArg (arg[0], XtNlabel, "< (p)");
+  XtSetArg (arg[0], XtNlabel, "-0x80 (p)");
   XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (prev_action));
   prev = XtCreateManagedWidget ("prev", commandWidgetClass,
                                navi_area, arg, 2);
@@ -317,12 +317,12 @@ create_widgets ()
   XtSetArg (arg[0], XtNlabel, " 0000 ");
   label = XtCreateManagedWidget ("label", labelWidgetClass,
                                 navi_area, arg, 1);
-  XtSetArg (arg[0], XtNlabel, "(n) >");
+  XtSetArg (arg[0], XtNlabel, "+0x80 (n)");
   XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (next_action));
   next = XtCreateManagedWidget ("next", commandWidgetClass,
                                navi_area, arg, 2);
   XtAddCallback (next, XtNcallback, GlyphProc, (XtPointer) 1);
-  XtSetArg (arg[0], XtNlabel, "(N) >>");
+  XtSetArg (arg[0], XtNlabel, "+0x1000 (N)");
   XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (NEXT_action));
   NEXT = XtCreateManagedWidget ("NEXT", commandWidgetClass,
                                navi_area, arg, 2);
@@ -424,6 +424,13 @@ main (int argc, char **argv)
   int i;
   int pixel_size = DEFAULT_PIXEL_SIZE;
 
+  {
+    char *str = getenv ("PIXEL_SIZE");
+
+    if (str && (i = atoi (str)) > 0)
+      pixel_size = i;
+  }
+
   gstring.size = gstring.used = 256;
   g = calloc (256, sizeof (OTF_Glyph));
   gstring.glyphs = g;
index bd0704d..3dd6ed5 100644 (file)
--- a/src/otf.h
+++ b/src/otf.h
@@ -54,7 +54,7 @@ Boston, MA 02111-1307, USA.  */
     (3-5) OTF_drive_gpos()
     (3-6) OTF_drive_tables()
 
-    (4) API for error handling 
+    (4) API for error handling
     (4-1) Error codes
     (4-2) OTF_perror()
 
@@ -446,7 +446,7 @@ enum OTF_LookupFlagBit
     OTF_Reserved = 0x00F0,
     OTF_MarkAttachmentType = 0xFF00
   };
-    
+
 typedef struct
 {
   OTF_Offset offset;
@@ -696,7 +696,8 @@ typedef OTF_ChainContext3 OTF_GSUB_ChainContext3;
 typedef struct
 {
   unsigned ExtensionLookupType;
-  unsigned ExtentionOffset;
+  unsigned ExtensionOffset;
+  OTF_LookupSubTableGSUB *ExtensionSubtable;
 } OTF_GSUB_Extension1;
 
 typedef struct
@@ -707,7 +708,7 @@ typedef struct
   OTF_Coverage *LookAhead;
   unsigned GlyphCount;
   OTF_GlyphID *Substitute;
-} OTF_GSUB_ReverseChainSingle1;
+} OTF_GSUB_ReverseChain1;
 
 struct OTF_LookupSubTableGSUB
 {
@@ -734,7 +735,7 @@ struct OTF_LookupSubTableGSUB
     /* LookupType 7 */
     OTF_GSUB_Extension1 extension1;
     /* LookupType 8 */
-    OTF_GSUB_ReverseChainSingle1 reverse_chain_single1;
+    OTF_GSUB_ReverseChain1 reverse_chain1;
   } u;
 };
 
@@ -799,7 +800,7 @@ typedef struct
 typedef struct
 {
   unsigned ValueFormat;
-  OTF_ValueRecord Value;  
+  OTF_ValueRecord Value;
 } OTF_GPOS_Single1;
 
 typedef struct
@@ -1062,7 +1063,7 @@ typedef struct
 
   /* MarkAttachClassDef of the glyph.  The value is extracted from the
      GDEF table.  */
-  unsigned MarkAttachClass;  
+  unsigned MarkAttachClass;
 
   /* Positioning format type of the glyph.  The value specifies how
      the glyph positioning information is encoded in the member <f>.
index f7b86b5..7b9be26 100644 (file)
@@ -141,10 +141,11 @@ get_langsys (OTF_ScriptList *script_list, char *script, char *language)
 }
 
 static int
-get_feature_index (OTF_LangSys *LangSys, OTF_FeatureList *FeatureList,
-                  char *features, int *feature_index)
+setup_lookup_indices (OTF_LangSys *LangSys, OTF_FeatureList *FeatureList,
+                     char *features, int *lookup_indices)
 {
-  int nfeatures = 0;
+  int i, j, n = 0;
+  OTF_Feature *feature;
 
   if (features)
     {
@@ -155,35 +156,40 @@ get_feature_index (OTF_LangSys *LangSys, OTF_FeatureList *FeatureList,
       for (p1 = p0; *p1; p1++)
        if (*p1 == ',')
          *p1 = '\0';
-      
-      while (len > 0)
+
+      while (p0 < p1)
        {
          int this_len = strlen (p0) + 1;
          OTF_Tag tag = OTF_tag (p0);
 
          if (tag)
-           {
-             int i;
-
-             for (i = 0; i < FeatureList->FeatureCount; i++)
-               if (tag == FeatureList->Feature[i].FeatureTag)
-                 {
-                   feature_index[nfeatures++] = i;
-                   if (nfeatures == FeatureList->FeatureCount)
-                     break;
-                 }
-           }
+           for (i = 0; i < FeatureList->FeatureCount; i++)
+             {
+               feature = FeatureList->Feature + i;
+               if (tag == feature->FeatureTag)
+                 for (j = 0; j < feature->LookupCount; j++)
+                   {
+                     lookup_indices[feature->LookupListIndex[j]] = 1;
+                     n++;
+                   }
+             }
          p0 += this_len;
-         len -= this_len;
        }
     }
   else
     {
-      for (; nfeatures < LangSys->FeatureCount; nfeatures++)
-       feature_index[nfeatures] = LangSys->FeatureIndex[nfeatures];
+      for (i = 0; i < LangSys->FeatureCount; i++)
+       {
+         feature = FeatureList->Feature + LangSys->FeatureIndex[i];
+         for (j = 0; j < feature->LookupCount; j++)
+           {
+             lookup_indices[feature->LookupListIndex[j]] = 1;
+             n++;
+           }
+       }
     }
 
-  return nfeatures;
+  return (n > 0);
 }
 
 static int
@@ -234,9 +240,18 @@ lookup_gsub (OTF_LookupList *lookup_list, unsigned lookup_list_index,
   /* Try all subtables until one of them handles the current glyph.  */
   for (i = 0; i < lookup->SubTableCount && gidx == orig_gidx; i++)
     {
+      unsigned lookup_type = lookup->LookupType;
       OTF_LookupSubTableGSUB *subtable = lookup->SubTable.gsub + i;
       int coverage_idx;
 
+      if (lookup_type == 7)
+       {
+         OTF_GSUB_Extension1 *extension1 = &subtable->u.extension1;
+
+         lookup_type = extension1->ExtensionLookupType;
+         subtable = extension1->ExtensionSubtable;
+       }
+
       if (subtable->Coverage.offset)
        {
          coverage_idx = get_coverage_index (&subtable->Coverage,
@@ -302,11 +317,11 @@ lookup_gsub (OTF_LookupList *lookup_list, unsigned lookup_list_index,
          else
            OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " (invalid SubFormat)");
          break;
-             
+
        case 5:
          if (subtable->Format == 1)
            {
-             OTF_GSUB_Context1 *context1 = &subtable->u.context1; 
+             OTF_GSUB_Context1 *context1 = &subtable->u.context1;
              OTF_RuleSet *set = context1->RuleSet + coverage_idx;
              OTF_Rule *rule;
              int orig_used;
@@ -330,7 +345,7 @@ lookup_gsub (OTF_LookupList *lookup_list, unsigned lookup_list_index,
            }
          else if (subtable->Format == 2)
            {
-             OTF_GSUB_Context2 *context2 = &subtable->u.context2; 
+             OTF_GSUB_Context2 *context2 = &subtable->u.context2;
              OTF_ClassSet *set;
              OTF_ClassRule *rule;
              unsigned class;
@@ -359,7 +374,7 @@ lookup_gsub (OTF_LookupList *lookup_list, unsigned lookup_list_index,
            }
          else                  /* subtable->Format == 3 */
            {
-             OTF_GSUB_Context3 *context3 = &subtable->u.context3; 
+             OTF_GSUB_Context3 *context3 = &subtable->u.context3;
              int orig_used;
              int j, k;
 
@@ -387,7 +402,17 @@ lookup_gsub (OTF_LookupList *lookup_list, unsigned lookup_list_index,
 
        case 6:
          if (subtable->Format == 1)
-           OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " (not yet supported)");
+           {
+             OTF_GSUB_ChainContext1 *context1 = &subtable->u.chain_context1;
+             OTF_ChainRuleSet *set = context1->ChainRuleSet + coverage_idx;
+             OTF_ChainRule *rule;
+             int j, k;
+             
+             for (j = 0; j < set->ChainRuleCount; j++)
+               {
+                 rule = set->ChainRule + j;
+               }
+           }
          else if (subtable->Format == 2)
            {
              OTF_GSUB_ChainContext2 *context2 = &subtable->u.chain_context2;
@@ -490,6 +515,34 @@ lookup_gsub (OTF_LookupList *lookup_list, unsigned lookup_list_index,
            }
          break;
 
+       case 8:
+         {
+           OTF_GSUB_ReverseChain1 *reverse = &subtable->u.reverse_chain1;
+           int back_gidx = gidx + 1 + reverse->BacktrackGlyphCount;
+           int ahead_gidx = gidx - reverse->LookaheadGlyphCount;
+           int j;
+
+           if (back_gidx > gstring->used || ahead_gidx < 0)
+             break;
+
+           for (j = 0; j < reverse->BacktrackGlyphCount; j++)
+             if (get_coverage_index (reverse->Backtrack + j,
+                                     gstring->glyphs[gidx + 1 + j].glyph_id)
+                 < 0)
+               break;
+           if (j < reverse->BacktrackGlyphCount)
+             continue;
+           for (j = 0; j < reverse->LookaheadGlyphCount; j++)
+             if (get_coverage_index (reverse->LookAhead + j,
+                                     gstring->glyphs[gidx - 1 - j].glyph_id)
+                 < 0)
+               break;
+           if (j < reverse->LookaheadGlyphCount)
+             continue;
+           g->glyph_id = reverse->Substitute[coverage_idx];
+           gidx--;
+         }
+
        default:
          continue;
        }
@@ -628,7 +681,7 @@ lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
          else
            OTF_ERROR (OTF_ERROR_GPOS_DRIVE, " (not yet supported)");
          break;
-             
+
        case 5:
          OTF_ERROR (OTF_ERROR_GPOS_DRIVE, " (not yet supported)");
          break;
@@ -846,9 +899,8 @@ OTF_drive_gsub (OTF *otf, OTF_GlyphString *gstring,
   int errret = -1;
   OTF_GSUB *gsub;
   OTF_LangSys *LangSys;
-  int nfeatures;
-  int *feature_index;
-  int i, j;
+  int *lookup_indices;
+  int i;
 
   if (! otf->gsub
       && OTF_get_table (otf, "GSUB") < 0)
@@ -859,32 +911,41 @@ OTF_drive_gsub (OTF *otf, OTF_GlyphString *gstring,
   if (! LangSys)
     return errret;
 
-  feature_index = alloca (sizeof (int) * gsub->FeatureList.FeatureCount);
-  if (! feature_index)
+  i = gsub->LookupList.LookupCount;
+  lookup_indices = alloca (sizeof (int) * i);
+  if (! lookup_indices)
     OTF_ERROR (OTF_ERROR_MEMORY, " feature list");
+  memset (lookup_indices, 0, sizeof (int) * i);
+  if (setup_lookup_indices (LangSys, &gsub->FeatureList,
+                           features, lookup_indices) < 0)
+    OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " no lookups");
 
-  nfeatures = get_feature_index (LangSys, &gsub->FeatureList,
-                                features, feature_index);
-  if (nfeatures == 0)
-    OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " no feature");
-
-  for (i = 0; i < nfeatures; i++)
-    {
-      OTF_Feature *feature = gsub->FeatureList.Feature + feature_index[i];
-
-      for (j = 0; j < feature->LookupCount; j++)
-       {
-         int gidx = 0;
+  for (i = 0; i < gsub->LookupList.LookupCount; i++)
+    if (lookup_indices[i])
+      {
+       int gidx;
 
-         while (gidx < gstring->used)
-           {
-             gidx = lookup_gsub (&gsub->LookupList,
-                                 feature->LookupListIndex[j], gstring, gidx);
-             if (gidx < 0)
-               return errret;
-           }
-       }
-    }
+       if (gsub->LookupList.Lookup[i].LookupType != 8)
+         {
+           gidx = 0;
+           while (gidx < gstring->used)
+             {
+               gidx = lookup_gsub (&gsub->LookupList, i, gstring, gidx);
+               if (gidx < 0)
+                 return errret;
+             }
+         }
+       else
+         {
+           gidx = gstring->used - 1;
+           while (gidx >= 0)
+             {
+               gidx = lookup_gsub (&gsub->LookupList, i, gstring, gidx);
+               if (gidx < 0)
+                 return errret;
+             }
+         }
+      }
 
   return 0;
 }
@@ -897,9 +958,8 @@ OTF_drive_gpos (OTF *otf, OTF_GlyphString *gstring,
   int errret = -1;
   OTF_GPOS *gpos;
   OTF_LangSys *LangSys;
-  int nfeatures;
-  int *feature_index;
-  int i, j;
+  int *lookup_indices;
+  int i;
 
   if (! otf->gpos
       && OTF_get_table (otf, "GPOS") < 0)
@@ -910,32 +970,27 @@ OTF_drive_gpos (OTF *otf, OTF_GlyphString *gstring,
   if (! LangSys)
     return errret;
 
-  feature_index = alloca (sizeof (int) * gpos->FeatureList.FeatureCount);
-  if (! feature_index)
+  i = gpos->LookupList.LookupCount;
+  lookup_indices = alloca (sizeof (int) * i);
+  if (! lookup_indices)
     OTF_ERROR (OTF_ERROR_MEMORY, " feature list");
+  memset (lookup_indices, 0, sizeof (int) * i);
+  if (setup_lookup_indices (LangSys, &gpos->FeatureList,
+                           features, lookup_indices) < 0)
+    OTF_ERROR (OTF_ERROR_GPOS_DRIVE, " no lookups");
 
-  nfeatures = get_feature_index (LangSys, &gpos->FeatureList,
-                                features, feature_index);
-  if (nfeatures == 0)
-    OTF_ERROR (OTF_ERROR_GSUB_DRIVE, " no feature");
-
-  for (i = 0; i < nfeatures; i++)
-    {
-      OTF_Feature *feature = gpos->FeatureList.Feature + feature_index[i];
-
-      for (j = 0; j < feature->LookupCount; j++)
-       {
-         int gidx = 0;
+  for (i = 0; i < gpos->LookupList.LookupCount; i++)
+    if (lookup_indices[i])
+      {
+       int gidx = 0;
 
-         while (gidx < gstring->used)
-           {
-             gidx = lookup_gpos (&gpos->LookupList,
-                                 feature->LookupListIndex[j], gstring, gidx);
-             if (gidx < 0)
-               return errret;
-           }
-       }
-    }
+       while (gidx < gstring->used)
+         {
+           gidx = lookup_gpos (&gpos->LookupList, i, gstring, gidx);
+           if (gidx < 0)
+             return errret;
+         }
+      }
 
   return 0;
 }
index b6da3db..c50b32c 100644 (file)
@@ -573,7 +573,7 @@ read_glyph_ids (OTF *otf, OTF_Stream *stream, OTF_GlyphID **ids,
     READ_GLYPHID (stream, (*ids)[i]);
   return count;
 }
-     
+
 static unsigned
 read_range_records (OTF *otf, OTF_Stream *stream, OTF_RangeRecord **record)
 {
@@ -604,7 +604,7 @@ read_coverage (OTF *otf, OTF_Stream *stream, long offset,
   int errret = -1;
   OTF_StreamState state;
   int count;
-  
+
   READ_OFFSET (stream, coverage->offset);
   SAVE_STREAM (stream, state);
   SEEK_STREAM (stream, offset + coverage->offset);
@@ -684,7 +684,7 @@ read_class_def (OTF *otf, OTF_Stream *stream, long offset, OTF_ClassDef *class)
   char *errfmt = "ClassDef%s";
   int errret = -1;
   OTF_StreamState state;
-  
+
   READ_OFFSET (stream, class->offset);
   if (! class->offset)
     return 0;
@@ -955,7 +955,7 @@ read_script_list (OTF *otf, OTF_Stream *stream, long offset,
          for (k = 0; k < langsys->FeatureCount; k++)
            READ_USHORT (stream, langsys->FeatureIndex[k]);
        }
-         
+
       for (j = 0; j < script->LangSysCount; j++)
        {
          OTF_LangSys *langsys = script->LangSys + j;
@@ -1336,7 +1336,7 @@ read_chain_class_rule_list (OTF *otf, OTF_Stream *stream, long offset,
        = read_glyph_ids (otf, stream,
                          (OTF_GlyphID **) &(*rule)[i].LookAhead, 0, -1);
       (*rule)[i].LookupCount
-       = read_lookup_record_list (otf, stream, 
+       = read_lookup_record_list (otf, stream,
                                   &(*rule)[i].LookupRecord, -1);
       if (! (*rule)[i].LookupCount)
        return errret;
@@ -1618,7 +1618,33 @@ read_alternate_set_list (OTF *otf, OTF_Stream *stream, long offset,
   return count;
 }
 
-static int 
+static int
+read_reverse_chain1 (OTF *otf, OTF_Stream *stream, long offset,
+                    OTF_Coverage *coverage,
+                    OTF_GSUB_ReverseChain1 *reverse_chain)
+{
+  int count;
+
+  if (read_coverage (otf, stream, offset, coverage) < 0)
+    return -1;
+  count = read_coverage_list (otf, stream, offset,
+                             &reverse_chain->Backtrack, -1);
+  if (count < 0)
+    return -1;
+  reverse_chain->BacktrackGlyphCount = (unsigned) count;
+  count = read_coverage_list (otf, stream, offset,
+                             &reverse_chain->LookAhead, -1);
+  if (count <= 0)
+    return -1;
+  reverse_chain->LookaheadGlyphCount = (unsigned) count;
+  count = read_glyph_ids (otf, stream, &reverse_chain->Substitute, 0, -1);
+  if (count <= 0)
+    return -1;
+  reverse_chain->GlyphCount = count;  
+  return 0;
+}
+
+static int
 read_lookup_subtable_gsub (OTF *otf, OTF_Stream *stream, long offset,
                           unsigned type, OTF_LookupSubTableGSUB *subtable)
 {
@@ -1626,7 +1652,7 @@ read_lookup_subtable_gsub (OTF *otf, OTF_Stream *stream, long offset,
   int errret = -1;
 
   SEEK_STREAM (stream, offset);
-  READ_UINT16 (stream, subtable->Format);
+  READ_USHORT (stream, subtable->Format);
   sprintf (errfmt, "GSUB Lookup %d-%d%%s", type, subtable->Format);
   switch (type)
     {
@@ -1662,7 +1688,7 @@ read_lookup_subtable_gsub (OTF *otf, OTF_Stream *stream, long offset,
       else
        OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
       break;
-      
+
     case 3:
       if (subtable->Format == 1)
        {
@@ -1715,7 +1741,7 @@ read_lookup_subtable_gsub (OTF *otf, OTF_Stream *stream, long offset,
       else
        OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
       break;
-      
+
     case 6:
       if (subtable->Format == 1)
        {
@@ -1738,10 +1764,37 @@ read_lookup_subtable_gsub (OTF *otf, OTF_Stream *stream, long offset,
       else
        OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
       break;
-      
+
     case 7:
+      if (subtable->Format == 1)
+       {
+         unsigned ex_type;
+         long ex_offset;
+         OTF_LookupSubTableGSUB *ex_subtable;
+
+         READ_USHORT (stream, ex_type);
+         READ_ULONG (stream, ex_offset);
+         OTF_CALLOC (ex_subtable, 1, " (SubTable)");
+         if (read_lookup_subtable_gsub (otf, stream, offset + ex_offset,
+                                        ex_type, ex_subtable) < 0)
+           return errret;
+         subtable->u.extension1.ExtensionLookupType = ex_type;
+         subtable->u.extension1.ExtensionOffset = ex_offset;
+         subtable->u.extension1.ExtensionSubtable = ex_subtable;
+       }
+      else
+       OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
+      break;
+
     case 8:
-      OTF_ERROR (OTF_ERROR_TABLE, " (not yet supported)");      
+      if (subtable->Format == 1)
+       {
+         if (read_reverse_chain1 (otf, stream, offset, &subtable->Coverage,
+                                  &subtable->u.reverse_chain1) < 0)
+           return errret;
+       }
+      else
+       OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
       break;
 
     default:
@@ -1862,7 +1915,7 @@ read_mark_array (OTF *otf, OTF_Stream *stream, long offset,
   int errret = -1;
   OTF_StreamState state;
   int i;
-  
+
   READ_OFFSET (stream, array->offset);
   SAVE_STREAM (stream, state);
   SEEK_STREAM (stream, offset + array->offset);
@@ -1889,7 +1942,7 @@ read_anchor_array (OTF *otf, OTF_Stream *stream, long offset,
   int errret = -1;
   OTF_StreamState state;
   int i, j;
-  
+
   READ_OFFSET (stream, array->offset);
   SAVE_STREAM (stream, state);
   SEEK_STREAM (stream, offset + array->offset);
@@ -1938,7 +1991,7 @@ read_class1_record_list (OTF *otf, OTF_Stream *stream, long offset,
   return rec;
 }
 
-static int 
+static int
 read_lookup_subtable_gpos (OTF *otf, OTF_Stream *stream,
                           long offset, unsigned type,
                           OTF_LookupSubTableGPOS *subtable)
@@ -2002,7 +2055,7 @@ read_lookup_subtable_gpos (OTF *otf, OTF_Stream *stream,
       else
        OTF_ERROR (OTF_ERROR_TABLE, " (Invalid SubFormat)");
       break;
-      
+
     case 3:
       OTF_ERROR (OTF_ERROR_TABLE, " (not yet supported)");
       break;
@@ -2139,7 +2192,7 @@ read_jstf_table (OTF_Stream *stream, long offset)
 
 int
 read_offset_table (OTF *otf, OTF_Stream *stream, OTF_OffsetTable *table)
-{  
+{
   int errret = -1;
 
   READ_FIXED (stream, table->sfnt_version);
@@ -2204,7 +2257,7 @@ read_header_part (OTF *otf, FILE *fp)
     return -1;
 
   internal_data->header_stream = stream;
-  
+
   /* Size of Offset Table is 12 bytes.  */
   if (setup_stream (stream, fp, 0, 12, "Offset Table") < 0)
     return -1;