(load_flt): New arg full. If full is zero, load only
authorhanda <handa>
Sun, 16 Sep 2007 10:59:49 +0000 (10:59 +0000)
committerhanda <handa>
Sun, 16 Sep 2007 10:59:49 +0000 (10:59 +0000)
coverage.
(run_otf): Call font->get_metrics, not font->get_metric.
(run_stages): Likewise.
(CHECK_FLT_COVERAGE): New macro.
(CHECK_FLT_STAGES): Call load_flt with the second arg 1.
(check_otf_spec): New function.
(m17n_fini_flt): Unref flt->coverage.
(mflt_find): Argument changed.
(mflt_name): New function.
(mflt_coverage): Use CHECK_FLT_COVERAGE.

src/m17n-flt.c

index 76a908f..ac9b2f1 100644 (file)
@@ -1156,19 +1156,34 @@ load_generator (MPlist *plist)
 /* Load stages of the font layout table FLT.  */
 
 static int
-load_flt (MFLT *flt)
+load_flt (MFLT *flt, int full)
 {
-  MPlist *top = NULL, *plist;
-  MSymbol Mcategory = msymbol ("category");
-  MSymbol Mgenerator = msymbol ("generator");
-  MSymbol Mend = msymbol ("end");
+  static MSymbol Mcategory, Mgenerator, Mend;
+  MPlist *top, *plist;
   MCharTable *category = NULL;
 
-  if (! (top = (MPlist *) mdatabase_load (flt->mdb)))
-    MERROR (MERROR_FLT, -1);
-  if (! MPLIST_PLIST_P (top))
+  if (! Mcategory)
+    {
+      Mcategory = msymbol ("category");
+      Mgenerator = msymbol ("generator");
+      Mend = msymbol ("end");
+    }
+
+  if (full)
+    {
+      top = (MPlist *) mdatabase_load (flt->mdb);
+    }
+  else
     {
-      M17N_OBJECT_UNREF (top);
+      plist = mplist ();
+      mplist_add (plist, Mcategory, Mt);
+      top = (MPlist *) mdatabase__load_for_keys (flt->mdb, plist);
+      M17N_OBJECT_UNREF (plist);
+    }
+  if (! top || ! MPLIST_PLIST_P (top))
+    {
+      if (top)
+       M17N_OBJECT_UNREF (top);
       MERROR (MERROR_FLT, -1);
     }
 
@@ -1197,6 +1212,11 @@ load_flt (MFLT *flt)
          if (category)
            M17N_OBJECT_UNREF (category);
          category = load_category_table (elt);
+         if (! flt->coverage)
+           {
+             flt->coverage = category;
+             M17N_OBJECT_REF (category);
+           }
        }
       else if (sym == Mgenerator)
        {
@@ -1210,12 +1230,7 @@ load_flt (MFLT *flt)
          stage->category = category;
          M17N_OBJECT_REF (category);
          if (! flt->stages)
-           {
-             /* Here don't do M17N_OBJECT_REF (category) because we
-                don't unref the value of the element added below.  */
-             flt->coverage = category;
-             flt->stages = mplist ();
-           }
+           flt->stages = mplist ();
          mplist_add (flt->stages, Mt, stage);
        }
     }
@@ -1457,7 +1472,7 @@ run_otf (int depth,
          break;
       if (i < out_len)
        {
-         font->get_metric (font, ctx->out, from_idx, ctx->out->used);
+         font->get_metrics (font, ctx->out, from_idx, ctx->out->used);
          for (i = 0, a = adjustment; i < out_len; i++, a++)
            {
              MFLTGlyph *g = GREF (ctx->out, from_idx + i);
@@ -1864,7 +1879,7 @@ run_stages (MFLTGlyphString *gstring, int from, int to,
              }
          }
 
-      ctx->font->get_metric (ctx->font, ctx->out, 0, ctx->out->used);
+      ctx->font->get_metrics (ctx->font, ctx->out, 0, ctx->out->used);
 
       /* Handle combining.  */
       if (ctx->check_mask & CombiningCodeMask)
@@ -1949,7 +1964,39 @@ run_stages (MFLTGlyphString *gstring, int from, int to,
   return to;
 }
 
-#define CHECK_FLT_STAGES(flt) ((flt)->stages || load_flt (flt) == 0)
+#define CHECK_FLT_COVERAGE(flt) ((flt)->coverage || load_flt (flt, 0) == 0)
+#define CHECK_FLT_STAGES(flt) ((flt)->stages || load_flt (flt, 1) == 0)
+
+static int
+check_otf_spec (MFLTOtfSpec *src, MFLTOtfSpec *tgt)
+{
+  int i, j;
+  unsigned int feature;
+
+  if (src->script && src->script != tgt->script)
+    return 0;
+  if (src->langsys && src->langsys != tgt->langsys)
+    return 0;
+  for (i = 0; i < src->gsub_count; i++)
+    {
+      feature = src->gsub[i];
+      for (j = 0; j < tgt->gsub_count; j++)
+       if (feature == tgt->gsub[j])
+         break;
+      if (j == tgt->gsub_count)
+       return 0;
+    }
+  for (i = 0; i < src->gpos_count; i++)
+    {
+      feature = src->gpos[i];
+      for (j = 0; j < tgt->gpos_count; j++)
+       if (feature == tgt->gpos[j])
+         break;
+      if (j == tgt->gpos_count)
+       return 0;
+    }
+  return 1;
+}
 
 \f
 /* Internal API */
@@ -2021,6 +2068,8 @@ m17n_fini_flt (void)
        {
          MFLT *flt = MPLIST_VAL (plist);
 
+         if (flt->coverage)
+           M17N_OBJECT_UNREF (flt->coverage);
          if (flt->stages)
            {
              MPLIST_DO (pl, MPLIST_NEXT (flt->stages))
@@ -2056,49 +2105,54 @@ mflt_get (char *name)
 }
 
 MFLT *
-mflt_find (MFLTGlyphString *gstring, int pos, MFLTFont *font)
+mflt_find (int c, MFLTFont *font)
 {
   MPlist *plist;
-  MSymbol script;
-  int i;
-  static MSymbol Mcommon = NULL;
-
-  if (! Mcommon)
-    Mcommon = msymbol ("common");
+  MFLT *flt;
 
-  for (i = pos; i < gstring->used; i++)
-    {
-      script = mchar_get_prop (GREF (gstring, i)->c, Mscript);
-      if (script != Minherited && script != Mcommon)
-       break;
-    }
-  if (i == gstring->used)
-    return NULL;
-  if (! flt_list
-      && list_flt () < 0)
+  if (! flt_list && list_flt () < 0)
     return NULL;
-  MPLIST_DO (plist, flt_list)
+  if (font)
     {
-      MFLT *flt = MPLIST_VAL (plist);
-
-      if ((flt->otf.script == gstring->script
-          || ! gstring->script)
-         && (! font
-             || ! font->suitable_p
-             || font->suitable_p (font, flt->family, &flt->otf)))
+      MPLIST_DO (plist, flt_list)
        {
-         if (! CHECK_FLT_STAGES (flt))
+         flt = MPLIST_VAL (plist);
+         if (flt->family && flt->family != font->family)
            continue;
-         return flt;
+         if (flt->otf.sym
+             && (! font->otf.sym
+                 || ! check_otf_spec (&flt->otf, &font->otf)))
+           continue;
+         if (c < 0
+             || (CHECK_FLT_COVERAGE (flt)
+                 && mchartable_lookup (flt->coverage, c)))
+           return flt;
+       }
+      return NULL;
+    }
+  if (c >= 0)
+    {
+      MPLIST_DO (plist, flt_list)
+       {
+         flt = MPLIST_VAL (plist);
+         if (CHECK_FLT_COVERAGE (flt)
+             && mchartable_lookup (flt->coverage, c))
+           return flt;
        }
     }
   return NULL;
 }
 
+char *
+mflt_name (MFLT *flt)
+{
+  return MSYMBOL_NAME (flt->name);
+}
+
 MCharTable *
 mflt_coverage (MFLT *flt)
 {
-  if (! CHECK_FLT_STAGES (flt))
+  if (! CHECK_FLT_COVERAGE (flt))
     MERROR (MERROR_FLT, NULL);
   return flt->coverage;
 }