/* 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);
}
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)
{
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);
}
}
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);
}
}
- 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)
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 */
{
MFLT *flt = MPLIST_VAL (plist);
+ if (flt->coverage)
+ M17N_OBJECT_UNREF (flt->coverage);
if (flt->stages)
{
MPLIST_DO (pl, MPLIST_NEXT (flt->stages))
}
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;
}