#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;
MERROR (MERROR_FONT, NULL);
category_code = MPLIST_INTEGER (elt);
}
- if (! isalpha (category_code))
+ if (! isalnum (category_code))
MERROR (MERROR_FONT, NULL);
if (from == to)
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);
}
if (MDEBUG_FLAG () > 2)
MDEBUG_PRINT3 ("\n [FLT] %*s(INDEX %d", depth, "", rule->src.match_idx);
}
+ else if (rule->src_type == SRC_EXIST)
+ {
+ MGlyph *g = MGLYPH (from);
+ int encoded = g->otf_encoded;
+ unsigned code;
+
+ if (rule->src.exist.c < 0)
+ {
+ if (from >= to)
+ return 0;
+ code = g->code;
+ to = from + 1;
+ }
+ else
+ {
+ code = rule->src.exist.c;
+ to = from;
+ encoded = 0;
+ }
+ if (! encoded)
+ {
+ code = (g->rface->rfont->driver->encode_char
+ (NULL, (MFont *) g->rface->rfont, NULL, code));
+ if (code == MCHAR_INVALID_CODE)
+ return 0;
+ }
+ }
consumed = 0;
depth++;
/* Direct code (== id + ctx->code_offset) output.
The source is not consumed. */
- if (from < to)
+ if (from < to || from == 1)
g = *(MGLYPH (from));
else
g = *(MGLYPH (from - 1));
Mcond = msymbol ("cond");
Mrange = msymbol ("range");
Mlayouter = msymbol ("layouter");
+ Mexist = msymbol ("exist");
flt_list = mplist ();
return 0;
}