(lookup_encoding_0, lookup_encoding_2)
authorhanda <handa>
Thu, 23 Jul 2009 07:57:02 +0000 (07:57 +0000)
committerhanda <handa>
Thu, 23 Jul 2009 07:57:02 +0000 (07:57 +0000)
(lookup_encoding_4, lookup_encoding_6, lookup_encoding_8)
(lookup_encoding_10, lookup_encoding_12): Arguments and return
value changed.
(lookup_cmap_func): New function type.
(lookup_cmap_func_table): New variable.
(get_GlyphID): New function.
(get_uvs_glyph): Call get_GlyphID instead of directly accessing
cmal->unicode_table.
(OTF_drive_cmap, OTF_drive_cmap2): Call one of lookup functions in
lookup_cmap_func_table.

src/otfdrive.c

index 7a41174..bb65f7e 100644 (file)
@@ -1259,83 +1259,107 @@ lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
   return gidx;
 }
 
-static int
-lookup_encoding_0 (OTF_EncodingSubtable0 *sub0, OTF_GlyphString *gstring)
+static unsigned
+lookup_encoding_0 (int c, OTF_EncodingSubtable *sub)
 {
-  int i, c;
-
-  for (i = 0; i < gstring->used; i++)
-    {
-      c = gstring->glyphs[i].c;
-      if (c < 0 || c >= 256)
-       gstring->glyphs[i].glyph_id = 0;
-      else
-       gstring->glyphs[i].glyph_id = sub0->glyphIdArray[c];
-    }
-  return 0;
+  return ((c < 0 || c >= 256)
+         ? 0
+         : sub->f.f0->glyphIdArray[c]);
 }
 
-static int
-lookup_encoding_2 (OTF_EncodingSubtable2 *sub2, OTF_GlyphString *gstring)
+static unsigned
+lookup_encoding_2 (int c, OTF_EncodingSubtable *sub)
 {
   return 0;
 }
 
-static int
-lookup_encoding_4 (OTF_EncodingSubtable4 *sub4, OTF_GlyphString *gstring)
+static unsigned
+lookup_encoding_4 (int c, OTF_EncodingSubtable *sub)
 {
-  int i, j, c;
-  int segCount = sub4->segCountX2 / 2;
+  int segCount, i;
+  OTF_EncodingSubtable4 *sub4;
 
-  for (i = 0; i < gstring->used; i++)
+  if (c < 0)
+    return 0;
+  sub4 = sub->f.f4;
+  segCount = sub4->segCountX2 / 2;
+  for (i = 0; i < segCount; i++)
     {
-      c = gstring->glyphs[i].c;
-      if (c < 0)
-       gstring->glyphs[i].glyph_id = 0;
-      for (j = 0; j < segCount; j++)
-       {
-         OTF_cmapSegment *seg = sub4->segments + i;
+      OTF_cmapSegment *seg = sub4->segments + i;
 
-         if (c >= seg->startCount && c <= seg->endCount)
-           {
-             if (seg->idRangeOffset == 0xFFFF)
-               gstring->glyphs[i].glyph_id = c + seg->idDelta;
-             else
-               gstring->glyphs[i].glyph_id
-                 = sub4->glyphIdArray[seg->idRangeOffset
-                                      + (c - seg->startCount)];
-             break;
-           }
+      if (c >= seg->startCount && c <= seg->endCount)
+       {
+         if (seg->idRangeOffset == 0xFFFF)
+           return c + seg->idDelta;
+         else
+           return sub4->glyphIdArray[seg->idRangeOffset
+                                     + (c - seg->startCount)];
        }
     }
-
   return 0;
 }
 
-static int
-lookup_encoding_6 (OTF_EncodingSubtable6 *sub6, OTF_GlyphString *gstring)
+static unsigned
+lookup_encoding_6 (int c, OTF_EncodingSubtable *sub)
 {
   return 0;
 }
 
-static int
-lookup_encoding_8 (OTF_EncodingSubtable8 *sub8, OTF_GlyphString *gstring)
+static unsigned
+lookup_encoding_8 (int c, OTF_EncodingSubtable *sub)
 {
   return 0;
 }
 
-static int
-lookup_encoding_10 (OTF_EncodingSubtable10 *sub10, OTF_GlyphString *gstring)
+static unsigned
+lookup_encoding_10 (int c, OTF_EncodingSubtable *sub)
 {
   return 0;
 }
 
-static int
-lookup_encoding_12 (OTF_EncodingSubtable12 *sub12, OTF_GlyphString *gstring)
+static unsigned
+lookup_encoding_12 (int c, OTF_EncodingSubtable *sub)
 {
+  OTF_EncodingSubtable12 *sub12;
+  OTF_cmapGroup *g, *gend;
+
+  if (c < 0)
+    return 0;
+  sub12 = sub->f.f12;
+  g = sub12->Groups;
+  gend = sub12->Groups + sub12->nGroups;
+  while (g < gend)
+    {
+      if (g->startCharCode <= c && c <= g->endCharCode)
+       return (g->startGlyphID + (c - g->startCharCode));
+      g++;
+    }
   return 0;
 }
 
+typedef unsigned (*lookup_cmap_func) (int, OTF_EncodingSubtable *);
+
+static lookup_cmap_func lookup_cmap_func_table[] =
+  {
+    lookup_encoding_0, lookup_encoding_2, lookup_encoding_4, lookup_encoding_6,
+    lookup_encoding_8, lookup_encoding_10, lookup_encoding_12
+  };
+
+static unsigned
+get_GlyphID (OTF_cmap *cmap, int c)
+{
+  OTF_EncodingSubtable *sub;
+  lookup_cmap_func lookupper;
+
+  if (c < 0x10000 && cmap->unicode_table)
+    return cmap->unicode_table[c];
+  if (cmap->table_index < 0)
+    return 0;
+  sub = &cmap->EncodingRecord[cmap->table_index].subtable;
+  lookupper = lookup_cmap_func_table[sub->format / 2];
+  return lookupper (c, sub);
+}
+
 static OTF_GlyphID
 get_uvs_glyph (OTF_cmap *cmap, OTF_EncodingSubtable14 *sub14, int c1, int c2)
 {
@@ -1371,7 +1395,7 @@ get_uvs_glyph (OTF_cmap *cmap, OTF_EncodingSubtable14 *sub14, int c1, int c2)
                  startUnicodeValue = uVRs[bottom].startUnicodeValue;
                  additionalCount = uVRs[bottom].additionalCount;
                  if (c1 <= startUnicodeValue + additionalCount)
-                   return cmap->unicode_table[c1];
+                   return get_GlyphID (cmap, c1);
                }
            }
          if (record->nonDefaultUVSOffset)
@@ -1504,12 +1528,21 @@ OTF_drive_cmap (OTF *otf, OTF_GlyphString *gstring)
 {
   OTF_cmap *cmap;
   int i;
+  OTF_EncodingSubtable *sub;
+  lookup_cmap_func lookupper;
 
   if (! otf->cmap
       && OTF_get_table (otf, "cmap") < 0)
     return -1;
 
   cmap = otf->cmap;
+  if (cmap->table_index < 0)
+    lookupper = NULL;
+  else
+    {
+      sub = &cmap->EncodingRecord[cmap->table_index].subtable;
+      lookupper = lookup_cmap_func_table[sub->format / 2];
+    }
   for (i = 0; i < gstring->used; i++)
     if (! gstring->glyphs[i].glyph_id)
       {
@@ -1518,8 +1551,10 @@ OTF_drive_cmap (OTF *otf, OTF_GlyphString *gstring)
          gstring->glyphs[i].glyph_id = 0;
        else if (UVS_P (c) && i > 0)
          check_cmap_uvs (cmap, gstring, i);
-       else
+       else if (c < 0x10000)
          gstring->glyphs[i].glyph_id = cmap->unicode_table[c];
+       else if (lookupper)
+         gstring->glyphs[i].glyph_id = lookupper (c, sub);
       }
   return 0;
 }
@@ -1534,6 +1569,7 @@ OTF_drive_cmap2 (OTF *otf, OTF_GlyphString *gstring,
   char *errfmt = "CMAP Looking up%s";
   int errret = -1;
   OTF_EncodingRecord *enc;
+  lookup_cmap_func lookupper;
 
   if (! otf->cmap
       && OTF_get_table (otf, "cmap") < 0)
@@ -1547,17 +1583,23 @@ OTF_drive_cmap2 (OTF *otf, OTF_GlyphString *gstring,
   if (i == cmap->numTables)
     OTF_ERROR (OTF_ERROR_CMAP_DRIVE, " (unknown platformID/encodingID)");
   enc = cmap->EncodingRecord + i;
-  switch (enc->subtable.format)
-    {
-    case 0: return lookup_encoding_0 (enc->subtable.f.f0, gstring);
-    case 2: return lookup_encoding_2 (enc->subtable.f.f2, gstring);
-    case 4: return lookup_encoding_4 (enc->subtable.f.f4, gstring);
-    case 6: return lookup_encoding_6 (enc->subtable.f.f6, gstring);
-    case 8: return lookup_encoding_8 (enc->subtable.f.f8, gstring);
-    case 10: return lookup_encoding_10 (enc->subtable.f.f10, gstring);
-    case 12: return lookup_encoding_12 (enc->subtable.f.f12, gstring);
-    }
-  OTF_ERROR (OTF_ERROR_CMAP_DRIVE, " (invalid format)");
+  if (enc->subtable.format > 12)
+    OTF_ERROR (OTF_ERROR_CMAP_DRIVE, " (invalid format)");
+  lookupper = lookup_cmap_func_table[enc->subtable.format / 2];
+
+  for (i = 0; i < gstring->used; i++)
+    if (! gstring->glyphs[i].glyph_id)
+      {
+       int c = gstring->glyphs[i].c;
+       if (c < 32 || ! cmap->unicode_table)
+         gstring->glyphs[i].glyph_id = 0;
+       else if (UVS_P (c) && i > 0)
+         check_cmap_uvs (cmap, gstring, i);
+       else if (c < 0x10000)
+         gstring->glyphs[i].glyph_id = cmap->unicode_table[c];
+       else
+         gstring->glyphs[i].glyph_id = lookupper (c, &enc->subtable);
+      }
 }