*** empty log message ***
authorhanda <handa>
Tue, 14 Oct 2003 12:57:38 +0000 (12:57 +0000)
committerhanda <handa>
Tue, 14 Oct 2003 12:57:38 +0000 (12:57 +0000)
src/otf.h
src/otfdrive.c
src/otfopen.c

index f490bf6..c3a307a 100644 (file)
--- a/src/otf.h
+++ b/src/otf.h
@@ -220,6 +220,8 @@ typedef struct
   unsigned numTables;
   OTF_EncodingRecord *EncodingRecord;
   unsigned short *unicode_table;
+  int max_glyph_id;
+  unsigned short *decode_table;
 } OTF_cmap;
 
 
@@ -1231,6 +1233,14 @@ extern int OTF_drive_tables (OTF *otf, OTF_GlyphString *gstring,
                             char *gsub_features, char *gpos_features);
 
 
+/*** (3-7) OTF_get_unicode()  */
+
+/***
+    Return Unicode code point corresponding to the glyph-id CODE.
+  */
+
+extern int OTF_get_unicode (OTF *otf, OTF_GlyphID code);
+
 /*** (4) API for error handling ***/
 
 /*** (4-1) Error codes ***/
index 14e422b..36c36ff 100644 (file)
@@ -200,34 +200,38 @@ setup_lookup_indices (OTF_LangSys *LangSys, OTF_FeatureList *FeatureList,
 static int
 match_ids (OTF_GlyphString *gstring, int gidx, int count, OTF_GlyphID *ids)
 {
-  int i, j;
+  OTF_Glyph *gbeg = gstring->glyphs + gidx;
+  OTF_Glyph *gend = gstring->glyphs + gstring->used;
+  OTF_Glyph *g;
+  int i;
 
-  if (gstring->used - gidx < count)
-    return -1;
-  for (i = j = 0; i < count; i++, j++)
-    {
-      if (! gstring->glyphs[gidx + j].glyph_id)
-       /* Skip this glyph.  */
-       i--;
-      else if (ids[i] && gstring->glyphs[gidx + i].glyph_id != ids[i])
-       return -1;
-    }
-  return j;
+  for (g = gbeg, i = 0; g < gend && i < count; g++)
+    if (g->glyph_id && g->glyph_id != ids[i++])
+      return -1;
+  return (i < count ? -1 : g - gbeg);
 }
 
 static int
 match_chain_ids (OTF_GlyphString *gstring, int gidx, OTF_ChainRule *rule)
 {
-  if (match_ids (gstring, gidx, rule->BacktrackGlyphCount, rule->Backtrack)
-      < 0)
+  int i, j;
+
+  for (i = rule->BacktrackGlyphCount, j = gidx - 1; j >= 0 && i > 0; j--)
+    if (gstring->glyphs[j].glyph_id)
+      i--;
+  if (i > 0)
     return -1;
-  gidx += rule->BacktrackGlyphCount + 1;
-  if (match_ids (gstring, gidx, rule->InputGlyphCount - 1, rule->Input)
-      < 0)
+
+  i = match_ids (gstring, j, rule->BacktrackGlyphCount, rule->Backtrack);
+  if (i < 0)
+    return -1;
+  gidx++;
+  i = match_ids (gstring, gidx, rule->InputGlyphCount - 1, rule->Input);
+  if (i < 0)
     return -1;
-  gidx += rule->InputGlyphCount;
-  if (match_ids (gstring, gidx, rule->LookaheadGlyphCount - 1, rule->LookAhead)
-      < 0)
+  gidx += i;
+  i = match_ids (gstring, gidx, rule->LookaheadGlyphCount, rule->LookAhead);
+  if (i < 0)
     return -1;
   return 0;
 }
@@ -236,14 +240,98 @@ static int
 match_classes (OTF_ClassDef *class_def, OTF_GlyphString *gstring, int gidx,
               int count, unsigned *classes)
 {
+  OTF_Glyph *gbeg = gstring->glyphs + gidx;
+  OTF_Glyph *gend = gstring->glyphs + gstring->used;
+  OTF_Glyph *g;
   int i;
 
-  if (gstring->used - gidx < count)
+  for (g = gbeg, i = 0; g < gend && i < count; g++)
+    if (g->glyph_id
+       && get_class_def (class_def, g->glyph_id) != classes[i++])
+      return -1;
+  return (i < count ? -1 : g - gbeg);
+}
+
+static int
+match_chain_classes (OTF_GlyphString *gstring, int gidx,
+                    OTF_ClassDef *BacktrackClassDef,
+                    OTF_ClassDef *InputClassDef,
+                    OTF_ClassDef *LookaheadClassDef,
+                    OTF_ChainClassRule *rule)
+{
+  int i, j;
+
+  for (i = rule->BacktrackGlyphCount, j = gidx - 1; j >= 0 && i > 0; j--)
+    if (gstring->glyphs[j].glyph_id)
+      i--;
+  if (i > 0)
     return -1;
-  for (i = 0; i < count; i++)
-    if (get_class_def (class_def, gstring->glyphs[gidx + i].glyph_id)
-       != classes[i])
+
+  i = match_classes (BacktrackClassDef, gstring, j,
+                    rule->BacktrackGlyphCount, rule->Backtrack);
+  if (i < 0)
+    return -1;
+  gidx++;
+  i = match_classes (InputClassDef, gstring, gidx,
+                    rule->InputGlyphCount - 1, rule->Input);
+  if (i < 0)
+    return -1;
+  gidx += i;
+  i = match_classes (LookaheadClassDef, gstring, gidx,
+                    rule->LookaheadGlyphCount, rule->LookAhead);
+  if (i < 0)
+    return -1;
+  return 0;
+}
+
+
+static int
+match_coverages (OTF_GlyphString *gstring, int gidx, int count,
+                OTF_Coverage *coverages)
+{
+  OTF_Glyph *gbeg = gstring->glyphs + gidx;
+  OTF_Glyph *gend = gstring->glyphs + gstring->used;
+  OTF_Glyph *g;
+  int i;
+
+  for (g = gbeg, i = 0; g < gend && i < count; g++)
+    if (g->glyph_id
+       && get_coverage_index (coverages + i, g->glyph_id) < 0)
       return -1;
+  return (i < count ? -1 : g - gbeg);
+}
+
+static int
+match_chain_coverages (OTF_GlyphString *gstring, int gidx,
+                      OTF_GSUB_ChainContext3 *context3)
+{
+  int i, j;
+
+  if (gidx < context3->BacktrackGlyphCount
+      || (gidx + context3->InputGlyphCount
+         + context3->LookaheadGlyphCount) >= gstring->used)
+    return -1;
+
+  for (i = context3->BacktrackGlyphCount, j = gidx - 1; j >= 0 && i > 0; j--)
+    if (gstring->glyphs[j].glyph_id)
+      i--;
+  if (i > 0)
+    return -1;
+
+  i = match_coverages (gstring, j, context3->BacktrackGlyphCount,
+                      context3->Backtrack);
+  if (i < 0)
+    return -1;
+  gidx++;
+  i = match_coverages (gstring, gidx, context3->InputGlyphCount - 1,
+                      context3->Input + 1);
+  if (i < 0)
+    return -1;
+  gidx += i;
+  i = match_coverages (gstring, gidx, context3->LookaheadGlyphCount,
+                      context3->LookAhead);
+  if (i < 0)
+    return -1;
   return 0;
 }
 
@@ -331,11 +419,14 @@ lookup_gsub (OTF_LookupList *lookup_list, unsigned lookup_list_index,
 
              for (j = 0; j < ligset->LigatureCount; j++)
                {
+                 int n;
+
                  lig = ligset->Ligature + j;
-                 if (match_ids (gstring, gidx + 1,
-                                lig->CompCount - 1, lig->Component) < 0)
+                 n = match_ids (gstring, gidx + 1,
+                                lig->CompCount - 1, lig->Component);
+                 if (n < 0)
                    continue;
-                 gstring_subst (gstring, gidx, gidx + lig->CompCount,
+                 gstring_subst (gstring, gidx, gidx + 1 + n,
                                 &lig->LigGlyph, 1);
                  gidx++;
                  break;
@@ -403,26 +494,17 @@ lookup_gsub (OTF_LookupList *lookup_list, unsigned lookup_list_index,
            {
              OTF_GSUB_Context3 *context3 = &subtable->u.context3;
              int orig_used;
-             int j, k;
+             int j;
 
-             if (gstring->used - gidx < context3->GlyphCount)
-               continue;
-             /* Start from the secoding coverage_idx because the
-                first one is the same as subtable->Coverage and thus
-                already tested */
-             for (j = 1; j < context3->GlyphCount; j++)
-               if (get_coverage_index (context3->Coverage + j,
-                                       gstring->glyphs[gidx + j].glyph_id)
-                   < 0)
-                 break;
-             if (j < context3->GlyphCount)
+             if (match_coverages (gstring, gidx + 1, context3->GlyphCount - 1,
+                                  context3->Coverage + 1) < 0)
                continue;
              orig_used = gstring->used;
-             for (k = 0; k < context3->LookupCount; k++)
+             for (j = 0; j < context3->LookupCount; j++)
                lookup_gsub (lookup_list,
-                            context3->LookupRecord[k].LookupListIndex,
+                            context3->LookupRecord[j].LookupListIndex,
                             gstring,
-                            gidx + context3->LookupRecord[k].SequenceIndex);
+                            gidx + context3->LookupRecord[j].SequenceIndex);
              gidx += context3->GlyphCount + (gstring->used - orig_used);
            }
          break;
@@ -438,13 +520,12 @@ lookup_gsub (OTF_LookupList *lookup_list, unsigned lookup_list_index,
              for (j = 0; j < set->ChainRuleCount; j++)
                {
                  OTF_ChainRule *rule = set->ChainRule + j;
-                 int backs = rule->BacktrackGlyphCount;
-                 int inputs = rule->InputGlyphCount;
-                 int aheads = rule->LookaheadGlyphCount;
 
-                 if (gidx < backs || gidx + inputs + aheads > gstring->used)
+                 if (gidx < rule->BacktrackGlyphCount
+                     || (gidx + rule->InputGlyphCount
+                         + rule->LookaheadGlyphCount) >= gstring->used)
                    continue;
-                 if (match_chain_ids (gstring, gidx - backs, rule) < 0)
+                 if (match_chain_ids (gstring, gidx, rule) < 0)
                    continue;
                  orig_used = gstring->used;
                  for (k = 0; k < rule->LookupCount; k++)
@@ -470,35 +551,18 @@ lookup_gsub (OTF_LookupList *lookup_list, unsigned lookup_list_index,
              for (j = 0; j < set->ChainClassRuleCnt; j++)
                {
                  OTF_ChainClassRule *rule = set->ChainClassRule + j;
-                 int fore_idx = gidx + rule->InputGlyphCount;
                  int k;
 
                  if (gidx < rule->BacktrackGlyphCount
                      || (gidx + rule->InputGlyphCount
                          + rule->LookaheadGlyphCount) >= gstring->used)
                    continue;
-                 for (k = 0; k < rule->BacktrackGlyphCount; k++)
-                   if (get_class_def (&context2->BacktrackClassDef,
-                                      gstring->glyphs[gidx - 1 - k].glyph_id)
-                       != rule->Backtrack[k])
-                     break;
-                 if (k < rule->BacktrackGlyphCount)
-                   continue;
-                 for (k = 1; k < rule->InputGlyphCount; k++)
-                   if (get_class_def (&context2->InputClassDef,
-                                      gstring->glyphs[gidx + k].glyph_id)
-                       != rule->Input[k - 1])
-                     break;
-                 if (k < rule->InputGlyphCount)
-                   continue;
-                 for (k = 0; k < rule->LookaheadGlyphCount; k++)
-                   if (get_class_def (&context2->LookaheadClassDef,
-                                      gstring->glyphs[fore_idx + k].glyph_id)
-                       != rule->LookAhead[k])
-                     break;
-                 if (k < rule->LookaheadGlyphCount)
+                 if (match_chain_classes (gstring, gidx,
+                                          &context2->BacktrackClassDef,
+                                          &context2->InputClassDef,
+                                          &context2->LookaheadClassDef,
+                                          rule) < 0)
                    continue;
-
                  orig_used = gstring->used;
                  for (k = 0; k < rule->LookupCount; k++)
                    lookup_gsub (lookup_list,
@@ -512,42 +576,11 @@ lookup_gsub (OTF_LookupList *lookup_list, unsigned lookup_list_index,
          else
            {
              OTF_GSUB_ChainContext3 *context3 = &subtable->u.chain_context3;
-             int back_gidx = gidx - context3->BacktrackGlyphCount;
-             int fore_gidx = gidx + context3->InputGlyphCount;
              int orig_used;
              int j;
 
-             if (back_gidx < 0
-                 || fore_gidx + context3->LookaheadGlyphCount > gstring->used)
-               break;
-
-             for (j = 0; j < context3->BacktrackGlyphCount; j++)
-               if (get_coverage_index (context3->Backtrack + j,
-                                       gstring->glyphs[gidx - 1 - j].glyph_id)
-                   < 0)
-                 break;
-             if (j < context3->BacktrackGlyphCount)
+             if (match_chain_coverages (gstring, gidx, context3) < 0)
                continue;
-
-             /* Start from the second coverage_idx because the first
-                one is the same as subtable->Coverage and thus
-                already tested */
-             for (j = 1; j < context3->InputGlyphCount; j++)
-               if (get_coverage_index (context3->Input + j,
-                                       gstring->glyphs[gidx + j].glyph_id)
-                   < 0)
-                 break;
-             if (j < context3->InputGlyphCount)
-               continue;
-
-             for (j = 0; j < context3->LookaheadGlyphCount; j++)
-               if (get_coverage_index (context3->LookAhead + j,
-                                       gstring->glyphs[fore_gidx + j].glyph_id)
-                   < 0)
-                 break;
-             if (j < context3->LookaheadGlyphCount)
-               continue;
-
              orig_used = gstring->used;
              for (j = 0; j < context3->LookupCount; j++)
                lookup_gsub (lookup_list,
@@ -910,7 +943,7 @@ OTF_drive_cmap (OTF *otf, OTF_GlyphString *gstring)
   for (i = 0; i < gstring->used; i++)
     {
       int c = gstring->glyphs[i].c;
-      if (c < 32 || ! cmap || ! cmap->unicode_table)
+      if (c < 32 || ! cmap->unicode_table)
        gstring->glyphs[i].glyph_id = 0;
       else
        gstring->glyphs[i].glyph_id = cmap->unicode_table[c];
@@ -920,6 +953,18 @@ OTF_drive_cmap (OTF *otf, OTF_GlyphString *gstring)
   return 0;
 }
 
+int
+OTF_get_unicode (OTF *otf, OTF_GlyphID code)
+{
+  if (! otf->cmap
+      && OTF_get_table (otf, "cmap") < 0)
+    return code;
+  if (code == 0
+      || code > otf->cmap->max_glyph_id
+      || otf->cmap->decode_table)
+    return code;
+  return otf->cmap->decode_table[code];
+}
 
 int
 OTF_drive_gdef (OTF *otf, OTF_GlyphString *gstring)
index 29f4133..fb797ab 100644 (file)
@@ -550,8 +550,9 @@ read_cmap_table (OTF *otf, OTF_Stream *stream)
   if (unicode_index >= 0)
     {
       OTF_EncodingRecord *rec = cmap->EncodingRecord + unicode_index;
+      OTF_GlyphID glyph_id, max_glyph_id = 0;
 
-      OTF_MALLOC (cmap->unicode_table, 0x10000, "");
+      OTF_CALLOC (cmap->unicode_table, 0x10000, "");
       switch (rec->subtable.format)
        {
        case 4:
@@ -566,17 +567,31 @@ read_cmap_table (OTF *otf, OTF_Stream *stream)
 
                if (seg->idRangeOffset == 0xFFFF)
                  for (c = seg->startCount; c <= seg->endCount; c++)
-                   cmap->unicode_table[c] = c + seg->idDelta;
+                   {
+                     glyph_id = c + seg->idDelta;
+                     cmap->unicode_table[c] = glyph_id;
+                     if (glyph_id > max_glyph_id)
+                       max_glyph_id = glyph_id;
+                   }
                else
                  for (c = seg->startCount; c <= seg->endCount && c != 0xFFFF;
                       c++)
-                   cmap->unicode_table[c]
-                     = sub4->glyphIdArray[seg->idRangeOffset
-                                          + (c - seg->startCount)];
+                   {
+                     glyph_id = sub4->glyphIdArray[seg->idRangeOffset
+                                                   + (c - seg->startCount)];
+                     cmap->unicode_table[c] = glyph_id;
+                     if (glyph_id > max_glyph_id)
+                       max_glyph_id = glyph_id;
+                   }
              }
          }
        }
 
+      OTF_CALLOC (cmap->decode_table, max_glyph_id + 1, "");
+      for (i = 0; i < 0x10000; i++)
+       if (cmap->unicode_table[i])
+         cmap->decode_table[cmap->unicode_table[i]] = i;
+      cmap->max_glyph_id = max_glyph_id;
     }
 
   return cmap;