@brief FLT support for a window system.
This section defines the m17n FLT API concerning character
- layouting facility using FLT (Font Layout Table). */
+ layouting facility using FLT (Font Layout Table). FLT
+
+
+*/
/*=*/
#include <sys/types.h>
#include <regex.h>
-#include "m17n.h"
+#include "m17n-core.h"
#include "m17n-flt.h"
#include "m17n-misc.h"
#include "internal.h"
#define CMD_ID_TO_INDEX(id) (CMD_ID_OFFSET_INDEX - (id))
#define INDEX_TO_CMD_ID(idx) (CMD_ID_OFFSET_INDEX - (idx))
-static MSymbol Mcond, Mrange;
+static MSymbol Mcond, Mrange, Mexist;
#define GLYPH_CODE_P(code) \
((code) >= GLYPH_CODE_MIN && (code) <= GLYPH_CODE_MAX)
SRC_REGEX,
SRC_INDEX,
SRC_SEQ,
- SRC_RANGE
+ SRC_RANGE,
+ SRC_EXIST
};
typedef struct
struct {
int from, to;
} range;
+ struct {
+ int c;
+ } exist;
} src;
int n_cmds;
spec->script = script;
spec->langsys = langsys;
- spec->gsub_count = gsub_count;
- spec->gpos_count = gpos_count;
- if (gsub_count + gpos_count > 0)
+ spec->gsub_gpos[0].count = gsub_count;
+ if (gsub_count > 0)
{
- spec->gsub = malloc (sizeof (int) * (gsub_count + gpos_count));
- if (! spec->gsub)
+ spec->gsub_gpos[0].tags = malloc (sizeof (int) * gsub_count);
+ if (! spec->gsub_gpos[0].tags)
MERROR (MERROR_FLT, -2);
- spec->gpos = spec->gsub + gsub_count;
- if (gsub_count > 0)
- memcpy (spec->gsub, gsub, sizeof (int) * gsub_count);
- if (gpos_count > 0)
- memcpy (spec->gpos, gpos, sizeof (int) * gpos_count);
+ memcpy (spec->gsub_gpos[0].tags, gsub, sizeof (int) * gsub_count);
+ }
+ spec->gsub_gpos[1].count = gpos_count;
+ if (gpos_count > 0)
+ {
+ spec->gsub_gpos[1].tags = malloc (sizeof (int) * gpos_count);
+ if (! spec->gsub_gpos[1].tags)
+ MERROR (MERROR_FLT, -2);
+ memcpy (spec->gsub_gpos[1].tags, gpos, sizeof (int) * gpos_count);
}
return 0;
}
if (result == -2)
return result;
if (result < 0)
- cmd->body.otf.gsub_count = cmd->body.otf.gpos_count = 0;
+ cmd->body.otf.gsub_gpos[0].count = cmd->body.otf.gsub_gpos[1].count = 0;
cmd->type = FontLayoutCmdTypeOTF;
return 0;
}
{
/* PLIST ::= ( cond ... ) | ( STRING ... ) | ( INTEGER ... )
| ( ( INTEGER INTEGER ) ... )
- | ( ( range INTEGER INTEGER ) ... ) */
+ | ( ( range INTEGER INTEGER ) ... )
+ | ( ( exist INTEGER ) ... ) */
MPlist *elt = MPLIST_PLIST (plist);
int len = MPLIST_LENGTH (elt) - 1;
FontLayoutCmd *cmd;
}
else if (MPLIST_SYMBOL_P (pl) && size == 3)
{
+ if (MPLIST_SYMBOL (pl) != Mrange)
+ MERROR (MERROR_FLT, INVALID_CMD_ID);
cmd->body.rule.src_type = SRC_RANGE;
pl = MPLIST_NEXT (pl);
if (! MPLIST_INTEGER_P (pl))
cmd->body.rule.src.range.to
= (unsigned) MPLIST_INTEGER (pl);
}
+ else if (MPLIST_SYMBOL_P (pl) && size <= 2)
+ {
+ if (MPLIST_SYMBOL (pl) != Mexist)
+ MERROR (MERROR_FLT, INVALID_CMD_ID);
+ cmd->body.rule.src_type = SRC_EXIST;
+ if (size == 1)
+ cmd->body.rule.src.exist.c = -1;
+ else
+ {
+ pl = MPLIST_NEXT (pl);
+ if (! MPLIST_INTEGER_P (pl))
+ MERROR (MERROR_DRAW, INVALID_CMD_ID);
+ cmd->body.rule.src.exist.c = MPLIST_INTEGER (pl);
+ }
+ }
else
MERROR (MERROR_DRAW, INVALID_CMD_ID);
}
free (cmd->body.cond.cmd_ids);
else if (cmd->type == FontLayoutCmdTypeOTF)
{
- if (cmd->body.otf.gsub_count + cmd->body.otf.gpos_count > 0)
- free (cmd->body.otf.gsub);
+ if (cmd->body.otf.gsub_gpos[0].count > 0)
+ free (cmd->body.otf.gsub_gpos[0].tags);
+ if (cmd->body.otf.gsub_gpos[1].count > 0)
+ free (cmd->body.otf.gsub_gpos[1].tags);
}
}
if (MDEBUG_FLAG () > 2)
MDEBUG_PRINT3 ("\n [FLT] %*s(INDEX %d", depth, "", rule->src.match_idx);
}
+ else if (rule->src_type == SRC_EXIST)
+ {
+ int encoded;
+ unsigned code;
+
+ if (rule->src.exist.c < 0)
+ {
+ if (from >= to)
+ return 0;
+ code = GREF (ctx->in, from)->code;
+ to = from + 1;
+ encoded = GREF (ctx->in, from)->encoded;
+ }
+ else
+ {
+ code = rule->src.exist.c;
+ to = from;
+ encoded = 0;
+ }
+ if (! encoded)
+ {
+ static MFLTGlyphString gstring;
+
+ if (! gstring.glyph_size)
+ {
+ gstring.glyph_size = ctx->in->glyph_size;
+ gstring.glyphs = calloc (1, gstring.glyph_size);
+ gstring.allocated = 1;
+ gstring.used = 1;
+ }
+ gstring.glyphs[0].code = code;
+ if (ctx->font->get_glyph_id (ctx->font, &gstring, 0, 1) < 0
+ || ! gstring.glyphs[0].encoded)
+ return 0;
+ }
+ }
consumed = 0;
depth++;
if (to < 0)
return to;
out_len = ctx->out->used - from_idx;
- if (otf_spec->gpos_count > 0)
+ if (otf_spec->gsub_gpos[1].count > 0)
{
MFLTGlyphAdjustment *a;
if (MDEBUG_FLAG () > 2)
MDEBUG_PRINT3 ("\n [FLT] %*s(DIRECT 0x%X", depth, "",
ctx->code_offset + id);
- i = from < to ? from : from - 1;
+ i = (from < to || from == 0) ? from : from - 1;
GDUP (ctx, i);
g = GREF (ctx->out, ctx->out->used - 1);
g->code = ctx->code_offset + id;
#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 */
merror_code = MERROR_NONE;
if (m17n__flt_initialized++)
return;
- m17n_init ();
+ m17n_init_core ();
if (merror_code != MERROR_NONE)
{
m17n__flt_initialized--;
}
MDEBUG_PUSH_TIME ();
+ MDEBUG_PUSH_TIME ();
Mcond = msymbol ("cond");
Mrange = msymbol ("range");
Mfont = msymbol ("font");
Mlayouter = msymbol ("layouter");
+ Mexist = msymbol ("exist");
MDEBUG_POP_TIME ();
MDEBUG_PRINT_TIME ("INIT", (stderr, " to initialize the flt modules."));
MDEBUG_POP_TIME ();
-
- return;
}
void
MDEBUG_PUSH_TIME ();
MDEBUG_PUSH_TIME ();
+ MDEBUG_PRINT_TIME ("FINI", (stderr, " to finalize database module."));
if (flt_list)
{
MDEBUG_POP_TIME ();
MDEBUG_PRINT_TIME ("FINI", (stderr, " to finalize the flt modules."));
MDEBUG_POP_TIME ();
- m17n_fini ();
+ m17n_fini_core ();
}
/*** @} */
if (flt->family && flt->family != font->family)
continue;
if (flt->otf.sym
- && (! font->otf.sym
- || ! check_otf_spec (&flt->otf, &font->otf)))
+ && (! font->check_otf (font, &flt->otf)))
continue;
- if (c < 0
- || (CHECK_FLT_COVERAGE (flt)
- && mchartable_lookup (flt->coverage, c)))
- return flt;
+ if (c >= 0
+ && (! CHECK_FLT_COVERAGE (flt)
+ || ! mchartable_lookup (flt->coverage, c)))
+ continue;
+ return flt;
}
return NULL;
}
ctx.out->allocated *= 2;
}
+#if 0
for (i = from; i < to; i++)
{
MFLTGlyph *g = GREF (gstring, i);
g->xoff >>= 6;
g->yoff >>= 6;
}
+#endif
if (MDEBUG_FLAG ())
{