*** empty log message ***
[m17n/libotf.git] / src / otfdrive.c
index 6d0baed..59b8114 100644 (file)
@@ -24,6 +24,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place, Suite
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <config.h>
 
 #include "otf.h"
 #include "otferror.h"
@@ -125,7 +126,8 @@ get_langsys (OTF_ScriptList *script_list, char *script, char *language)
   int i, j;
 
   for (i = 0; i < script_list->ScriptCount; i++)
-    if (script_list->Script[i].ScriptTag == script_tag)
+    if (! script_tag
+       || script_list->Script[i].ScriptTag == script_tag)
       {
        OTF_Script *script = script_list->Script + i;
 
@@ -492,23 +494,24 @@ lookup_gsub (OTF_LookupList *lookup_list, unsigned lookup_list_index,
 
              class = get_class_def (&context2->ClassDef, g->glyph_id);
              set = context2->ClassSet + class;
-             for (j = 0; j < set->ClassRuleCnt; j++)
-               {
-                 rule = set->ClassRule + j;
-                 if (match_classes (&context2->ClassDef,
-                                    gstring, gidx + 1,
-                                    rule->GlyphCount - 1, rule->Class)
-                     < 0)
-                   continue;
-                 orig_used = gstring->used;
-                 for (k = 0; k < rule->LookupCount; k++)
-                   lookup_gsub (lookup_list,
-                                rule->LookupRecord[k].LookupListIndex,
-                                gstring,
-                                gidx + rule->LookupRecord[k].SequenceIndex);
-                 gidx += rule->GlyphCount + (gstring->used - orig_used);
-                 break;
-               }
+             if (set)
+               for (j = 0; j < set->ClassRuleCnt; j++)
+                 {
+                   rule = set->ClassRule + j;
+                   if (match_classes (&context2->ClassDef,
+                                      gstring, gidx + 1,
+                                      rule->GlyphCount - 1, rule->Class)
+                       < 0)
+                     continue;
+                   orig_used = gstring->used;
+                   for (k = 0; k < rule->LookupCount; k++)
+                     lookup_gsub (lookup_list,
+                                  rule->LookupRecord[k].LookupListIndex,
+                                  gstring,
+                                  gidx + rule->LookupRecord[k].SequenceIndex);
+                   gidx += rule->GlyphCount + (gstring->used - orig_used);
+                   break;
+                 }
            }
          else                  /* subtable->Format == 3 */
            {
@@ -565,7 +568,6 @@ lookup_gsub (OTF_LookupList *lookup_list, unsigned lookup_list_index,
              int j;
              int orig_used;
 
-             // printf ("GSUB 6-2: c:0x%x g:0x%x\n", g->c, g->glyph_id);
              class = get_class_def (&context2->InputClassDef, g->glyph_id);
              set = context2->ChainClassSet + class;
              for (j = 0; j < set->ChainClassRuleCnt; j++)
@@ -602,7 +604,7 @@ lookup_gsub (OTF_LookupList *lookup_list, unsigned lookup_list_index,
              if (gidx < context3->BacktrackGlyphCount
                  || (gidx + context3->InputGlyphCount
                      + context3->LookaheadGlyphCount) > gstring->used)
-               return -1;
+               continue;
              if (match_chain_coverages (gstring, gidx, context3) < 0)
                continue;
              orig_used = gstring->used;
@@ -648,14 +650,7 @@ lookup_gsub (OTF_LookupList *lookup_list, unsigned lookup_list_index,
        }
     }
   if (gidx == orig_gidx)
-    {
-      //printf ("not applied\n");
-      gidx++;
-    }
-  else
-    {
-      // printf ("done\n");
-    }
+    gidx++;
   return gidx;
 }
 
@@ -705,16 +700,12 @@ lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
       OTF_LookupSubTableGPOS *subtable = lookup->SubTable.gpos + i;
       int coverage_idx;
 
-      // printf ("subtype:%d ", subtable->Format);
       if (subtable->Coverage.offset)
        {
          coverage_idx = get_coverage_index (&subtable->Coverage,
                                             g->glyph_id);
          if (coverage_idx < 0)
-           {
-             // printf ("not covererd ");
-             continue;
-           }
+           continue;
        }
 
       switch (lookup->LookupType)
@@ -738,53 +729,68 @@ lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
          break;
 
        case 2:
-         if (gidx + 1 >= gstring->used)
-           continue;
-         if (subtable->Format == 1)
-           {
-             OTF_GPOS_Pair1 *pair1 = &subtable->u.pair1;
-             OTF_PairSet *set = pair1->PairSet + coverage_idx;
-             int j;
+         {
+           int next_gidx = gidx + 1;
+           OTF_Glyph *nextg;
 
-             for (j = 0; j < set->PairValueCount; j++)
-               {
-                 if (set->PairValueRecord[j].SecondGlyph != g[1].glyph_id)
-                   continue;
-                 gidx++;
-                 g->positioning_type = lookup->LookupType;
-                 g->f.f2.format = pair1->ValueFormat1;
-                 g->f.f2.value = &set->PairValueRecord[j].Value1;
-                 if (pair1->ValueFormat2)
+           while (next_gidx < gstring->used
+                  && ! gstring->glyphs[next_gidx].glyph_id)
+             next_gidx++;
+
+           if (next_gidx >= gstring->used)
+             continue;
+           nextg = gstring->glyphs + next_gidx;
+           if (subtable->Format == 1)
+             {
+               OTF_GPOS_Pair1 *pair1 = &subtable->u.pair1;
+               OTF_PairSet *set = pair1->PairSet + coverage_idx;
+               int j;
+
+               for (j = 0; j < set->PairValueCount; j++)
+                 if (set->PairValueRecord[j].SecondGlyph == nextg->glyph_id)
                    {
-                     g++, gidx++;
-                     g->positioning_type = lookup->LookupType;
-                     g->f.f2.format = pair1->ValueFormat2;
-                     g->f.f2.value = &set->PairValueRecord[j].Value2;
+                     if (pair1->ValueFormat1)
+                       {
+                         g->positioning_type = lookup->LookupType;
+                         g->f.f2.format = pair1->ValueFormat1;
+                         g->f.f2.value = &set->PairValueRecord[j].Value1;
+                       }
+                     gidx = next_gidx;
+                     if (pair1->ValueFormat2)
+                       {
+                         nextg->positioning_type = lookup->LookupType;
+                         nextg->f.f2.format = pair1->ValueFormat2;
+                         nextg->f.f2.value = &set->PairValueRecord[j].Value2;
+                         gidx++;
+                       }
+                     break;
                    }
-               }
-           }
-         else if (subtable->Format == 2)
-           {
-             OTF_GPOS_Pair2 *pair2 = &subtable->u.pair2;
-             unsigned class1, class2;
-
-             // printf ("GPOS 2-2: c:0x%x g:0x%x\n", g->c, g->glyph_id);
-             gidx++;
-             class1 = get_class_def (&pair2->ClassDef1, g->glyph_id);
-             class2 = get_class_def (&pair2->ClassDef2, g[1].glyph_id);
-             g->positioning_type = lookup->LookupType;
-             g->f.f2.format = pair2->ValueFormat1;
-             g->f.f2.value
-               = &pair2->Class1Record[class1].Class2Record[class2].Value1;
-             if (pair2->ValueFormat2)
-               {
-                 g++, gidx++;
-                 g->positioning_type = lookup->LookupType;
-                 g->f.f2.format = pair2->ValueFormat2;
-                 g->f.f2.value
-                   = &pair2->Class1Record[class1].Class2Record[class2].Value2;
-               }
-           }
+             }
+           else if (subtable->Format == 2)
+             {
+               OTF_GPOS_Pair2 *pair2 = &subtable->u.pair2;
+               unsigned class1, class2;
+
+               class1 = get_class_def (&pair2->ClassDef1, g->glyph_id);
+               class2 = get_class_def (&pair2->ClassDef2, nextg->glyph_id);
+               if (pair2->ValueFormat1)
+                 {
+                   g->positioning_type = lookup->LookupType;
+                   g->f.f2.format = pair2->ValueFormat1;
+                   g->f.f2.value
+                     = &pair2->Class1Record[class1].Class2Record[class2].Value1;
+                 }
+               gidx = next_gidx;
+               if (pair2->ValueFormat2)
+                 {
+                   nextg->positioning_type = lookup->LookupType;
+                   nextg->f.f2.format = pair2->ValueFormat2;
+                   nextg->f.f2.value
+                     = &pair2->Class1Record[class1].Class2Record[class2].Value2;
+                   gidx++;
+                 }
+             }
+         }
          break;
 
        case 3:
@@ -813,7 +819,6 @@ lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
 
              if (coverage_idx_base < 0)
                continue;
-             // printf ("GPOS 4-1: c:0x%x g:0x%x\n", g->c, g->glyph_id);
              mark_record = mark_base1->MarkArray.MarkRecord + coverage_idx;
              base_record
                = mark_base1->BaseArray.AnchorRecord + coverage_idx_base;
@@ -851,7 +856,6 @@ lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
 
              if (coverage_idx_base < 0)
                continue;
-             // printf ("GPOS 6-1: c:0x%x g:0x%x\n", g->c, g->glyph_id);
              mark1_record = mark_mark1->Mark1Array.MarkRecord + coverage_idx;
              mark2_record
                = mark_mark1->Mark2Array.AnchorRecord + coverage_idx_base;
@@ -878,7 +882,6 @@ lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
              int j;
              int orig_used;
 
-             // printf ("GPOS 8-2: c:0x%x g:0x%x\n", g->c, g->glyph_id);
              class = get_class_def (&context2->InputClassDef, g->glyph_id);
              set = context2->ChainClassSet + class;
              for (j = 0; j < set->ChainClassRuleCnt; j++)
@@ -938,15 +941,85 @@ lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index,
        }
     }
   if (gidx == orig_gidx)
+    gidx++;
+  return gidx;
+}
+
+static int
+lookup_encoding_0 (OTF_EncodingSubtable0 *sub0, OTF_GlyphString *gstring)
+{
+  int i, c;
+
+  for (i = 0; i < gstring->used; i++)
     {
-      // printf ("not applied\n");
-      gidx++;
+      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];
     }
-  else
+  return 0;
+}
+
+static int
+lookup_encoding_2 (OTF_EncodingSubtable2 *sub2, OTF_GlyphString *gstring)
+{
+  return 0;
+}
+
+static int
+lookup_encoding_4 (OTF_EncodingSubtable4 *sub4, OTF_GlyphString *gstring)
+{
+  int i, j, c;
+  int segCount = sub4->segCountX2 / 2;
+
+  for (i = 0; i < gstring->used; i++)
     {
-      // printf ("done\n");
+      c = gstring->glyphs[i].c;
+      if (c < 0)
+       gstring->glyphs[i].glyph_id = 0;
+      for (j = 0; j < segCount; j++)
+       {
+         OTF_cmapSegument *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;
+           }
+       }
     }
-  return gidx;
+
+  return 0;
+}
+
+static int
+lookup_encoding_6 (OTF_EncodingSubtable6 *sub6, OTF_GlyphString *gstring)
+{
+  return 0;
+}
+
+static int
+lookup_encoding_8 (OTF_EncodingSubtable8 *sub8, OTF_GlyphString *gstring)
+{
+  return 0;
+}
+
+static int
+lookup_encoding_10 (OTF_EncodingSubtable10 *sub10, OTF_GlyphString *gstring)
+{
+  return 0;
+}
+
+static int
+lookup_encoding_12 (OTF_EncodingSubtable12 *sub12, OTF_GlyphString *gstring)
+{
+  return 0;
 }
 
 \f
@@ -976,6 +1049,43 @@ OTF_drive_cmap (OTF *otf, OTF_GlyphString *gstring)
   return 0;
 }
 
+
+int
+OTF_drive_cmap2 (OTF *otf, OTF_GlyphString *gstring,
+                int platform_id, int encoding_id)
+{
+  OTF_cmap *cmap;
+  int i;
+  char *errfmt = "CMAP Looking up%s";
+  int errret = -1;
+  OTF_EncodingRecord *enc;
+
+  if (! otf->cmap
+      && OTF_get_table (otf, "cmap") < 0)
+    return -1;
+
+  cmap = otf->cmap;
+  for (i = 0; i < cmap->numTables; i++)
+    if (cmap->EncodingRecord[i].platformID == platform_id
+       && cmap->EncodingRecord[i].encodingID == encoding_id)
+      break;
+  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)");
+}
+
+
 int
 OTF_get_unicode (OTF *otf, OTF_GlyphID code)
 {