FontLayoutCmd *cmds;
} FontLayoutStage;
-typedef MPlist MFontLayoutTable; /* t vs FontLayoutStage */
-
struct _MFLT
{
MSymbol name;
MSymbol family;
MFLTOtfSpec otf;
+ MDatabase *mdb;
+ MCharTable *coverage;
MPlist *stages;
};
if (! MSTRUCT_CALLOC_SAFE (flt))
goto memfull;
flt->name = tags[2];
+ flt->mdb = mdb;
mplist_push (flt_list, flt->name, flt);
if (properties)
MPLIST_DO (properties, properties)
}
-/* Load FLT of name LAYOUTER_NAME from the m17n database into a newly
- allocated memory, and return it. */
+/* Load stages of the font layout table FLT. */
-static MFontLayoutTable *
-load_flt (MSymbol layouter_name)
+static int
+load_flt (MFLT *flt)
{
- MDatabase *mdb;
MPlist *top = NULL, *plist;
MSymbol Mcategory = msymbol ("category");
MSymbol Mgenerator = msymbol ("generator");
MSymbol Mend = msymbol ("end");
- MFontLayoutTable *layouter = NULL;
MCharTable *category = NULL;
- if (! (mdb = mdatabase_find (Mfont, Mlayouter, layouter_name, Mnil)))
- MERROR_GOTO (MERROR_FONT, finish);
- if (! (top = (MPlist *) mdatabase_load (mdb)))
- MERROR_GOTO (0, finish);
+ if (! (top = (MPlist *) mdatabase_load (flt->mdb)))
+ MERROR (MERROR_FLT, -1);
if (! MPLIST_PLIST_P (top))
- MERROR_GOTO (MERROR_FONT, finish);
+ {
+ M17N_OBJECT_UNREF (top);
+ MERROR (MERROR_FLT, -1);
+ }
MPLIST_DO (plist, top)
{
if (MPLIST_SYMBOL_P (plist)
&& MPLIST_SYMBOL (plist) == Mend)
- break;
+ {
+ mplist_set (plist, Mnil, NULL);
+ break;
+ }
if (! MPLIST_PLIST (plist))
- MERROR_GOTO (MERROR_FONT, finish);
+ break;
elt = MPLIST_PLIST (plist);
if (! MPLIST_SYMBOL_P (elt))
- MERROR_GOTO (MERROR_FONT, finish);
+ break;
sym = MPLIST_SYMBOL (elt);
elt = MPLIST_NEXT (elt);
if (! elt)
- MERROR_GOTO (MERROR_FONT, finish);
+ break;
if (sym == Mcategory)
{
if (category)
FontLayoutStage *stage;
if (! category)
- MERROR_GOTO (MERROR_FONT, finish);
+ break;
stage = load_generator (elt);
if (! stage)
- MERROR_GOTO (MERROR_FONT, finish);
+ break;
stage->category = category;
M17N_OBJECT_REF (category);
- if (! layouter)
+ if (! flt->stages)
{
- layouter = mplist ();
/* Here don't do M17N_OBJECT_REF (category) because we
don't unref the value of the element added below. */
- mplist_add (layouter, Mcategory, category);
+ flt->coverage = category;
+ flt->stages = mplist ();
}
- mplist_add (layouter, Mt, stage);
+ mplist_add (flt->stages, Mt, stage);
}
}
-
if (category)
M17N_OBJECT_UNREF (category);
-
- finish:
M17N_OBJECT_UNREF (top);
- return layouter;
+ if (! MPLIST_TAIL_P (plist))
+ {
+ M17N_OBJECT_UNREF (flt->stages);
+ MERROR (MERROR_FLT, -1);
+ }
+ return 0;
}
free (stage);
}
-
-static MFontLayoutTable *
-get_font_layout_table (MSymbol layouter_name)
-{
- MFLT *flt;
-
- if (! flt_list
- && list_flt () < 0)
- return NULL;
- flt = mplist_get (flt_list, layouter_name);
- if (! flt->stages)
- flt->stages = load_flt (layouter_name);
- return flt->stages;
-}
-
-
/* FLS (Font Layout Service) */
/* Structure to hold information about a context of FLS. */
static int
run_stages (MFLTGlyphString *gstring, int from, int to,
- MFontLayoutTable *layouter, FontLayoutContext *ctx)
+ MFLT *flt, FontLayoutContext *ctx)
{
MFLTGlyphString buf, *temp;
int stage_idx = 0;
int from_pos, to_pos, len;
int i, j;
MFLTGlyph *g;
+ MPlist *stages = flt->stages;
from_pos = GREF (ctx->in, from)->from;
to_pos = GREF (ctx->in, to - 1)->to;
MCharTable *table;
int result;
- ctx->stage = (FontLayoutStage *) MPLIST_VAL (layouter);
+ ctx->stage = (FontLayoutStage *) MPLIST_VAL (stages);
table = ctx->stage->category;
ctx->code_offset = ctx->combining_code = ctx->left_padding = 0;
if (ctx->encoded_offset < from)
if (result < 0)
return result;
- layouter = MPLIST_NEXT (layouter);
+ stages = MPLIST_NEXT (stages);
/* If this is the last stage, break the loop. */
- if (MPLIST_TAIL_P (layouter))
+ if (MPLIST_TAIL_P (stages))
break;
/* Otherwise, prepare for the next stage. */
return to;
}
+#define CHECK_FLT_STAGES(flt) ((flt)->stages || load_flt (flt) < 0)
+
\f
/* Internal API */
int m17n__flt_initialized;
unsigned
-mfont__flt_encode_char (MSymbol layouter_name, int c)
+mfont__flt_encode_char (MFLT *flt, int c)
{
- MFontLayoutTable *layouter = get_font_layout_table (layouter_name);
- MCharTable *table;
unsigned code;
- if (! layouter)
+ if (! CHECK_FLT_STAGES (flt))
return MCHAR_INVALID_CODE;
- table = MPLIST_VAL (layouter);
- code = (unsigned) mchartable_lookup (table, c);
+ code = (unsigned) mchartable_lookup (flt->coverage, c);
return (code ? code : MCHAR_INVALID_CODE);
}
#endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
MFLT *
-mflt_find (MFLTGlyphString *gstring, int pos, MFLTFont *font, int *start)
+mflt_find (MFLTGlyphString *gstring, int pos, MFLTFont *font)
{
MPlist *plist;
MSymbol script;
MFLT *flt = MPLIST_VAL (plist);
if ((flt->otf.script == gstring->script
- || ! flt->otf.script || ! gstring->script)
+ || ! gstring->script)
&& (! font
|| ! font->suitable_p
|| font->suitable_p (font, flt->family, &flt->otf)))
{
- if (! flt->stages
- && ! (flt->stages = load_flt (flt->name)))
- return NULL;
+ if (! CHECK_FLT_STAGES (flt))
+ continue;
+ if (start)
+ {
+ MCharTable *category = MPLIST_VAL (flt->stages);
+
+ for (i = pos; i < gstring->used; i++)
+ if (mchartable_lookup (category, GREF (gstring, i)->c))
+ break;
+ *start = i;
+ }
return flt;
}
}
return NULL;
}
+MCharTable *
+mflt_coverage (MFLT *flt)
+{
+ if (! CHECK_FLT_STAGES (flt))
+ MERROR (MERROR_FLT, NULL);
+ return flt->coverages;
+}
+
int
mflt_run (MFLTGlyphString *gstring, int from, int to,
- MFLTFont *font, MSymbol layouter_name)
+ MFLTFont *font, MFLT *flt)
{
int i, j;
FontLayoutContext ctx;
- MCharTable *table;
int match_indices[NMATCH];
- MFontLayoutTable *layouter = get_font_layout_table (layouter_name);
- FontLayoutStage *stage;
MFLTGlyph *g;
MFLTGlyphString out;
- if (! layouter)
+ if (! CHECK_FLT_STAGES (flt))
{
GREPLACE (NULL, 0, 0, gstring, from, to);
return from;
}
- MDEBUG_PRINT1 (" [FLT] (%s", msymbol_name (layouter_name));
+ MDEBUG_PRINT1 (" [FLT] (%s", MSYMBOL_NAME (flt->name));
/* Setup CTX. */
memset (&ctx, 0, sizeof ctx);
- table = MPLIST_VAL (layouter);
- layouter = MPLIST_NEXT (layouter);
- stage = (FontLayoutStage *) MPLIST_VAL (layouter);
/* Find previous glyphs that are also supported by the layouter. */
for (i = from;
i > 0 && (g = GREF (gstring, i - 1))
- && g->c && mchartable_lookup (table, g->c);
+ && g->c && mchartable_lookup (flt->coverage, g->c);
i--)
g->code = g->c;
ctx.encoded_offset = i;
}
for (i = 0; (i < 3 &&
- (to = run_stages (gstring, from, to, layouter, &ctx)) == -2);
+ (to = run_stages (gstring, from, to, flt, &ctx)) == -2);
i++)
{
ctx.out = &out;
}
void
-mdebug_dump_flt (MFontLayoutTable *flt, int indent)
+mdebug_dump_flt (MFLT *flt, int indent)
{
char *prefix = (char *) alloca (indent + 1);
MPlist *plist;
memset (prefix, 32, indent);
prefix[indent] = 0;
fprintf (stderr, "(flt");
- MPLIST_DO (plist, flt)
+ MPLIST_DO (plist, flt->stages)
{
FontLayoutStage *stage = (FontLayoutStage *) MPLIST_VAL (plist);
int i;