#include "mtext.h"
#include "symbol.h"
#include "plist.h"
+#include "database.h"
#include "internal-flt.h"
/* Font Layouter */
typedef MPlist MFontLayoutTable; /* t vs FontLayoutStage */
+struct _MFLT
+{
+ MSymbol name;
+ MSymbol family;
+ MFLTOtfSpec otf;
+ MPlist *stages;
+};
+
/* Font layout table loader */
+static int parse_otf_command (MSymbol symbol, MFLTOtfSpec *spec);
+
+static int
+list_flt ()
+{
+ MPlist *plist = mdatabase_list (Mfont, Mlayouter, Mnil, Mnil);
+ MPlist *pl;
+
+ flt_list = mplist ();
+ MPLIST_DO (pl, plist)
+ {
+ MDatabase *mdb = MPLIST_VAL (pl);
+ MSymbol *tags = mdatabase_tag (mdb);
+ MPlist *properties = mdatabase__props (mdb), *p;
+ MFLT *flt;
+
+ if (! MSTRUCT_CALLOC_SAFE (flt))
+ goto memfull;
+ flt->name = tags[2];
+ mplist_push (flt_list, flt->name, flt);
+ if (properties)
+ MPLIST_DO (properties, properties)
+ {
+ MSymbol sym = Mnil;
+ char *otf_spec;
+
+ if (! MPLIST_PLIST_P (properties))
+ continue;
+ p = MPLIST_PLIST (properties);
+ if (! MPLIST_SYMBOL_P (p))
+ continue;
+ if (MPLIST_SYMBOL (p) != Mfont)
+ continue;
+ p = MPLIST_NEXT (p);
+ if (! MPLIST_PLIST_P (p))
+ continue;
+ p = MPLIST_PLIST (p);
+ if (! MPLIST_SYMBOL_P (p))
+ continue;
+ p = MPLIST_NEXT (p);
+ if (! MPLIST_SYMBOL_P (p))
+ continue;
+ flt->family = MPLIST_SYMBOL (p);
+ MPLIST_DO (p, MPLIST_NEXT (p))
+ if (MPLIST_SYMBOL_P (p))
+ sym = MPLIST_SYMBOL (p);
+ if (sym
+ && (otf_spec = MSYMBOL_NAME (sym))
+ && otf_spec[0] == ':' && otf_spec[1] == 'o'
+ && otf_spec[2] == 't' && otf_spec[3] == 'f')
+ {
+ if (parse_otf_command (sym, &flt->otf) == -2)
+ goto memfull;
+ }
+ }
+ }
+ M17N_OBJECT_UNREF (plist);
+ return 0;
+
+ memfull:
+ M17N_OBJECT_UNREF (plist);
+ M17N_OBJECT_UNREF (flt_list);
+ MERROR (MERROR_MEMORY, -1);
+}
+
/* Load a category table from PLIST. PLIST has this form:
PLIST ::= ( FROM-CODE TO-CODE ? CATEGORY-CHAR ) *
*/
finish:
M17N_OBJECT_UNREF (top);
- mplist_add (flt_list, layouter_name, layouter);
return layouter;
}
static MFontLayoutTable *
get_font_layout_table (MSymbol layouter_name)
{
- MPlist *plist = mplist_find_by_key (flt_list, layouter_name);
-
- return (plist ? MPLIST_VAL (plist) : load_flt (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;
}
Mrange = msymbol ("range");
Mfont = msymbol ("font");
Mlayouter = msymbol ("layouter");
- flt_list = mplist ();
MDEBUG_POP_TIME ();
MDEBUG_PRINT_TIME ("INIT", (stderr, " to initialize the flt modules."));
MDEBUG_PUSH_TIME ();
MDEBUG_PUSH_TIME ();
- MPLIST_DO (plist, flt_list)
+ if (flt_list)
{
- pl = MPLIST_PLIST (plist);
- if (pl)
+ MPLIST_DO (plist, flt_list)
{
- MPLIST_DO (pl, MPLIST_NEXT (pl))
- free_flt_stage (MPLIST_VAL (pl));
- pl = MPLIST_PLIST (plist);
- M17N_OBJECT_UNREF (pl);
+ MFLT *flt = MPLIST_VAL (plist);
+
+ if (flt->stages)
+ {
+ MPLIST_DO (pl, MPLIST_NEXT (flt->stages))
+ free_flt_stage (MPLIST_VAL (pl));
+ M17N_OBJECT_UNREF (flt->stages);
+ }
}
+ M17N_OBJECT_UNREF (flt_list);
}
- M17N_OBJECT_UNREF (flt_list);
MDEBUG_POP_TIME ();
MDEBUG_PRINT_TIME ("FINI", (stderr, " to finalize the flt modules."));
/*** @} */
#endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
+MFLT *
+mflt_find (MFLTGlyphString *gstring, int pos, MFLTFont *font, int *start)
+{
+ MPlist *plist;
+ MSymbol script;
+ int i;
+ static MSymbol Mcommon = NULL;
+
+ if (! Mcommon)
+ Mcommon = msymbol ("common");
+
+ 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)
+ return NULL;
+ MPLIST_DO (plist, flt_list)
+ {
+ MFLT *flt = MPLIST_VAL (plist);
+
+ if ((flt->otf.script == gstring->script
+ || ! flt->otf.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;
+ return flt;
+ }
+ }
+ return NULL;
+}
+
int
mflt_run (MFLTGlyphString *gstring, int from, int to,
MFLTFont *font, MSymbol layouter_name)
for (i = from, j = 0; i < to; i++, j++)
{
if (j > 0 && j % 8 == 0)
- MDEBUG_PRINT ("\n [FLT} ");
+ MDEBUG_PRINT ("\n [FLT] ");
MDEBUG_PRINT1 (" %04X", GREF (gstring, i)->c);
}
MDEBUG_PRINT (")");