X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Fm17n-flt.c;h=b6fcad667caffab7777d2fe29ee330c52872fd0c;hb=9b862a296364db1976fad00cd3a18550ee077f57;hp=ce209f6e05f175dab94af471fbfcc2061b71c232;hpb=e3618bf9724956419c43bd0ef39d0e01c7cb06ef;p=m17n%2Fm17n-lib.git diff --git a/src/m17n-flt.c b/src/m17n-flt.c index ce209f6..b6fcad6 100644 --- a/src/m17n-flt.c +++ b/src/m17n-flt.c @@ -1,5 +1,5 @@ /* m17n-flt.c -- Font Layout Table sub-module. - Copyright (C) 2003, 2004, 2007, 2008, 2009 + Copyright (C) 2003, 2004, 2007, 2008, 2009, 2010 National Institute of Advanced Industrial Science and Technology (AIST) Registration Number H15PRO112 @@ -255,18 +255,26 @@ static int flt_min_coverage, flt_max_coverage; enum GlyphInfoMask { - CombiningCodeMask = 0xFFFFFFF, - LeftPaddingMask = 1 << 28, - RightPaddingMask = 1 << 29 + CategoryCodeMask = 0x7F, + CombiningCodeMask = 0xFFFFFF, + CombinedMask = 1 << 28, + LeftPaddingMask = 1 << 29, + RightPaddingMask = 1 << 30 }; #define SET_GLYPH_INFO(g, mask, ctx, info) \ ((g)->internal = (((g)->internal & ~(mask)) | (info)), \ (ctx)->check_mask |= (mask)) +#define GET_CATEGORY_CODE(g) ((g)->internal & CategoryCodeMask) +#define SET_CATEGORY_CODE(g, code) \ + ((g)->internal = (((g)->internal & ~(CombiningCodeMask | CombinedMask)) \ + | (code))) +#define GET_COMBINED(g) ((g)->internal & CombinedMask) #define GET_COMBINING_CODE(g) ((g)->internal & CombiningCodeMask) -#define SET_COMBINING_CODE(g, ctx, code) \ - SET_GLYPH_INFO (g, CombiningCodeMask, ctx, code) +#define SET_COMBINING_CODE(g, ctx, code) \ + SET_GLYPH_INFO (g, CombiningCodeMask | CombinedMask, ctx, \ + (code) | CombinedMask) #define GET_LEFT_PADDING(g) ((g)->internal & LeftPaddingMask) #define SET_LEFT_PADDING(g, ctx, flag) \ SET_GLYPH_INFO (g, LeftPaddingMask, ctx, flag) @@ -451,15 +459,15 @@ typedef struct typedef struct { - unsigned int tag; - char category_code; -} FontLayoutFeatureTable; + int size; + unsigned int *tag; + char *code; +} FeatureCodeTable; typedef struct { MCharTable *table; - int feature_table_size; - FontLayoutFeatureTable *feature_table; + FeatureCodeTable feature_table; /* Non-null if the table must be re-configured by OTF specs included in the definition. */ MPlist *definition; @@ -508,7 +516,7 @@ apply_otf_feature (MFLTFont *font, MFLTOtfSpec *spec, mchartable_set (table, from + i, (void *) category); } -static unsigned int gen_otf_tag (char *p); +static unsigned int gen_otf_tag (char *p, int shift); /* Load a category table from PLIST. PLIST has this form: PLIST ::= ( FROM-CODE TO-CODE ? CATEGORY-CHAR ) * @@ -535,7 +543,14 @@ load_category_table (MPlist *plist, MFLTFont *font) elt = MPLIST_PLIST (p); if (MPLIST_SYMBOL_P (elt)) { - MPlist *next = MPLIST_NEXT (elt); + MPlist *next; + + if (! mflt_enable_new_feature) + { + M17N_OBJECT_UNREF (table); + return NULL; + } + next = MPLIST_NEXT (elt); if (! MPLIST_INTEGER_P (next)) MERROR_GOTO (MERROR_FLT, end); if (! feature_table_head) @@ -558,6 +573,11 @@ load_category_table (MPlist *plist, MFLTFont *font) } else if (MPLIST_SYMBOL_P (elt)) { + if (! mflt_enable_new_feature) + { + M17N_OBJECT_UNREF (table); + return NULL; + } if (font) { MFLTOtfSpec spec; @@ -603,9 +623,11 @@ load_category_table (MPlist *plist, MFLTFont *font) if (feature_table_head) { int i = 0; - category->feature_table_size = feature_table_size; - category->feature_table = malloc (sizeof (FontLayoutFeatureTable) - * feature_table_size); + category->feature_table.size = feature_table_size; + category->feature_table.tag = malloc (sizeof (unsigned int) + * feature_table_size); + category->feature_table.code = malloc (feature_table_size); + MPLIST_DO (p, feature_table_head) { MPlist *elt; @@ -619,8 +641,9 @@ load_category_table (MPlist *plist, MFLTFont *font) elt = MPLIST_NEXT (elt); if (! MPLIST_INTEGER_P (elt)) continue; - category->feature_table[i].tag = gen_otf_tag (MSYMBOL_NAME (feature)); - category->feature_table[i].category_code = MPLIST_INTEGER (elt); + category->feature_table.tag[i] + = gen_otf_tag (MSYMBOL_NAME (feature), 7); + category->feature_table.code[i] = MPLIST_INTEGER (elt); i++; } } @@ -637,22 +660,25 @@ unref_category_table (FontLayoutCategory *category) { if (category->definition) M17N_OBJECT_UNREF (category->definition); - if (category->feature_table) - free (category->feature_table); + if (category->feature_table.size > 0) + { + free (category->feature_table.tag); + free (category->feature_table.code); + } free (category); } } static unsigned int -gen_otf_tag (char *p) +gen_otf_tag (char *p, int shift) { unsigned int tag = 0; int i; for (i = 0; i < 4 && *p; i++, p++) - tag = (tag << 8) | *p; + tag = (tag << shift) | *p; for (; i < 4; i++) - tag = (tag << 8) | 0x20; + tag = (tag << shift) | 0x20; return tag; } @@ -708,86 +734,99 @@ otf_store_features (char *p, char *end, unsigned *buf) { if (negative++ == 0) buf[i++] = 0xFFFFFFFF; - buf[i++] = gen_otf_tag (p + 1), p += 6; + buf[i++] = gen_otf_tag (p + 1, 8), p += 6; } else - buf[i++] = gen_otf_tag (p), p += 5; + buf[i++] = gen_otf_tag (p, 8), p += 5; } buf[i] = 0; } +/* SYMBOL's name features[0] [1] for checking for applying + ------------- ------------------ ------------ ------------ + SCRIPT [-1,0] [-1,0] any|any all all + SCRIPT= NULL [-1,0] none&1 none all + SCRIPT+ [-1,0] NULL 1&none all none + SCRIPT=F1 [F1,0] [-1,0] F1&1 F1 all + SCRIPT+F1 [-1][0] [F1,0] none&F1 none F1 + SCRIPT=F1+ [F1,0] NULL F1&none F1 none + SCRIPT=~F2 [-1,F2,0] [-1,0] ~F2&1 all~F2 all + SCRIPT=F1,~F2 [F1,-1,A2,0][-1,0] F1&~F2&1 F1 (*1) all + + (*1) Invalid specification + */ + static int parse_otf_command (MSymbol symbol, MFLTOtfSpec *spec) { char *str = MSYMBOL_NAME (symbol); char *end = str + MSYMBOL_NAMELEN (symbol); unsigned int script, langsys; - char *gsub, *gpos; - int gsub_count = 0, gpos_count = 0; + char *features[3]; + int feature_count[2]; /* [0]:GSUB, [1]:GPOS */ + int i; char *p; memset (spec, 0, sizeof (MFLTOtfSpec)); spec->sym = symbol; - str += 5; /* skip the heading ":otf=" */ - script = gen_otf_tag (str); + str += 5; /* skip the heading ":otf=" or ":otf?" */ + if (str[-1] == '?') + { + if (! mflt_enable_new_feature) + /* The client can't use this command. */ + return -1; + if (! *str) + /* This is a spec to reset category codes. */ + return 0; + } + spec->script = gen_otf_tag (str, 8); str += 4; if (*str == '/') { - langsys = gen_otf_tag (str); + spec->langsys = gen_otf_tag (str, 8); str += 4; } else - langsys = 0; - gsub = str; + spec->langsys = 0; + features[0] = str; if (*str != '=') /* Apply all GSUB features. */ - gsub_count = 1; + feature_count[0] = -1; else { p = str + 1; - str = otf_count_features (p, end, '+', &gsub_count); + str = otf_count_features (p, end, '+', feature_count); if (! str) MERROR (MERROR_FLT, -1); } - gpos = str; + features[1] = str; if (*str != '+') /* Apply all GPOS features. */ - gpos_count = 1; + feature_count[1] = -1; else { p = str + 1; - str = otf_count_features (p, end, '\0', &gpos_count); + str = otf_count_features (p, end, '\0', feature_count + 1); if (! str) MERROR (MERROR_FLT, -1); } - - spec->script = script; - spec->langsys = langsys; - if (gsub_count > 0) - { - spec->features[0] = malloc (sizeof (int) * (gsub_count + 1)); - if (! spec->features[0]) - return -2; - if (*gsub == '=') - otf_store_features (gsub + 1, gpos, spec->features[0]); - else - spec->features[0][0] = 0xFFFFFFFF, spec->features[0][1] = 0; - } - if (gpos_count > 0) - { - spec->features[1] = malloc (sizeof (int) * (gpos_count + 1)); - if (! spec->features[1]) - { - if (spec->features[0]) - free (spec->features[0]); + features[2] = str; + for (i = 0; i < 2; i++) + if (feature_count[i]) + { + spec->features[i] = malloc (sizeof (int) + * (feature_count[i] < 0 ? 2 + : feature_count[i] + 1)); + if (! spec->features[i]) return -2; - } - if (*gpos == '+') - otf_store_features (gpos + 1, str, spec->features[1]); - else - spec->features[1][0] = 0xFFFFFFFF, spec->features[1][1] = 0; - } + if (feature_count[i] > 0) + otf_store_features (features[i] + 1, features[i + 1], + spec->features[i]); + else + spec->features[i][0] = 0xFFFFFFFF, spec->features[i][1] = 0; + } + return 0; } @@ -804,7 +843,7 @@ load_otf_command (FontLayoutCmd *cmd, MSymbol sym) char *name = MSYMBOL_NAME (sym); int result; - if (name[0] != ':' && name[0] != '?') + if (name[0] != ':') { /* This is old format of "otf:...". Change it to ":otf=...". */ char *str = alloca (MSYMBOL_NAMELEN (sym) + 2); @@ -817,7 +856,7 @@ load_otf_command (FontLayoutCmd *cmd, MSymbol sym) result = parse_otf_command (sym, &cmd->body.otf); if (result == -2) return result; - cmd->type = (name[0] == '?' ? FontLayoutCmdTypeOTFCategory + cmd->type = (name[4] == '?' ? FontLayoutCmdTypeOTFCategory : FontLayoutCmdTypeOTF); return 0; } @@ -1155,9 +1194,8 @@ load_command (FontLayoutStage *stage, MPlist *plist, if (len > 4 && ((name[0] == 'o' && name[1] == 't' && name[2] == 'f' && name[3] == ':') - || ((name[0] == ':' || name[0] == '?') - && name[1] == 'o' && name[2] == 't' - && name[3] == 'f' && name[4] == '='))) + || (name[0] == ':' && name[1] == 'o' && name[2] == 't' + && name[3] == 'f' && (name[4] == '=' || name[4] == '?')))) { result = load_otf_command (&cmd, sym); if (result < 0) @@ -1381,6 +1419,8 @@ load_flt (MFLT *flt, MPlist *key_list) continue; } category = load_category_table (pl, NULL); + if (! category) + goto err; if (! flt->coverage) { flt->coverage = category; @@ -1407,7 +1447,7 @@ load_flt (MFLT *flt, MPlist *key_list) } if (category) unref_category_table (category); - + err: if (! MPLIST_TAIL_P (plist)) { M17N_OBJECT_UNREF (top); @@ -1530,6 +1570,9 @@ typedef struct /* Pointer to the current stage. */ FontLayoutStage *stage; + /* Pointer to the category table of the next stage or NULL if none. */ + FontLayoutCategory *category; + /* Pointer to the font. */ MFLTFont *font; @@ -1553,6 +1596,7 @@ typedef struct static int run_command (int, int, int, int, FontLayoutContext *); static int run_otf (int, MFLTOtfSpec *, int, int, FontLayoutContext *); +static int try_otf (int, MFLTOtfSpec *, int, int, FontLayoutContext *); #define NMATCH 20 @@ -1616,7 +1660,7 @@ run_rule (int depth, if (len > (to - from)) return 0; for (i = 0; i < len; i++) - if (rule->src.seq.codes[i] != GREF (ctx->in, from + i)->code) + if (rule->src.seq.codes[i] != GREF (ctx->in, from + i)->c) break; if (i < len) return 0; @@ -1632,7 +1676,7 @@ run_rule (int depth, if (from >= to) return 0; - head = GREF (ctx->in, from)->code; + head = GREF (ctx->in, from)->c; if (head < rule->src.range.from || head > rule->src.range.to) return 0; ctx->code_offset = head - rule->src.range.from; @@ -1686,12 +1730,12 @@ run_rule (int depth, { if (MPLIST_INTEGER_P (p)) { - GREF (&gstring, i)->code = MPLIST_INTEGER (p); + GREF (&gstring, i)->c = MPLIST_INTEGER (p); GREF (&gstring, i)->encoded = 0; } else { - GREF (&gstring, i)->code = GREF (ctx->in, idx)->code; + GREF (&gstring, i)->c = GREF (ctx->in, idx)->code; GREF (&gstring, i)->encoded = GREF (ctx->in, idx)->encoded; idx++; } @@ -1825,6 +1869,46 @@ run_cond (int depth, return (pos); } +static void +decode_packed_otf_tag (FontLayoutContext *ctx, MFLTGlyphString *gstring, + int from, int to, FontLayoutCategory *category) +{ + for (; from < to; from++) + { + MFLTGlyph *g = GREF (gstring, from); + unsigned int tag = g->internal & 0xFFFFFFF; + char enc; + + if (GET_COMBINED (g)) + continue; + if (! category) + { + SET_CATEGORY_CODE (g, 0); + continue; + } + enc = '\0'; + if (tag & 0xFFFFF80) + { + int i; + + /* Clear the feature tag code. */ + g->internal &= ~0xFFFFFFF; + for (i = 0; i < category->feature_table.size; i++) + if (category->feature_table.tag[i] == tag) + { + enc = category->feature_table.code[i]; + if (ctx->in == gstring) + ctx->encoded[from - ctx->encoded_offset] = enc; + break; + } + } + if (! enc) + enc = (g->c > 0 ? (int) mchartable_lookup (category->table, g->c) + : g->c == 0 ? 1 : ' '); + SET_CATEGORY_CODE (g, enc); + } +} + static int run_otf (int depth, MFLTOtfSpec *otf_spec, int from, int to, FontLayoutContext *ctx) @@ -1860,6 +1944,8 @@ run_otf (int depth, adjustment); if (to < 0) return to; + decode_packed_otf_tag (ctx, ctx->out, from_idx, ctx->out->used, + ctx->category); out_len = ctx->out->used - from_idx; if (otf_spec->features[1]) { @@ -1916,7 +2002,6 @@ run_otf (int depth, g->descent -= aa->yoff; } } - SET_COMBINING_CODE (g, ctx, 0); g->adjusted = 1; } } @@ -1932,6 +2017,54 @@ run_otf (int depth, return to; } +static int +try_otf (int depth, MFLTOtfSpec *otf_spec, int from, int to, + FontLayoutContext *ctx) +{ + MFLTFont *font = ctx->font; + + if (MDEBUG_FLAG () > 2) + MDEBUG_PRINT3 ("\n [FLT] %*s%s", depth, "", MSYMBOL_NAME (otf_spec->sym)); + + if (! otf_spec->features[0] && ! otf_spec->features[1]) + { + /* Reset categories. */ + MCharTable *table = ctx->category->table; + int i; + + for (i = from; i < to; i++) + { + MFLTGlyph *g = GREF (ctx->in, i); + + if (! GET_COMBINED (g)) + { + char enc = (GET_ENCODED (g) + ? (g->c > 0 ? (int) mchartable_lookup (table, g->c) + : 1) + : g->code + ? (int) mchartable_lookup (table, g->code) + : ' '); + SET_CATEGORY_CODE (g, enc); + ctx->encoded[i - ctx->encoded_offset] = enc; + } + } + return from; + } + + if (ctx->stage->category->feature_table.size == 0) + return from; + + font->get_glyph_id (font, ctx->in, from, to); + if (mflt_try_otf) + { + to = mflt_try_otf (font, otf_spec, ctx->in, from, to); + if (to < 0) + return from; + decode_packed_otf_tag (ctx, ctx->in, from, to, ctx->stage->category); + } + return from; +} + static char work[16]; static char * @@ -1974,6 +2107,8 @@ run_command (int depth, int id, int from, int to, FontLayoutContext *ctx) if (id >= 0) { int i; + MCharTable *table = ctx->category ? ctx->category->table : NULL; + char enc; /* Direct code (== ctx->code_offset + id) output. The source is not consumed. */ @@ -1984,10 +2119,19 @@ run_command (int depth, int id, int from, int to, FontLayoutContext *ctx) GDUP (ctx, i); g = GREF (ctx->out, ctx->out->used - 1); g->c = g->code = ctx->code_offset + id; - SET_ENCODED (g, 0); - SET_MEASURED (g, 0); if (ctx->combining_code) SET_COMBINING_CODE (g, ctx, ctx->combining_code); + else if (table) + { + enc = (GET_ENCODED (g) + ? (g->c > 0 ? (int) mchartable_lookup (table, g->c) : 1) + : g->code + ? (int) mchartable_lookup (table, g->code) + : ' '); + SET_CATEGORY_CODE (g, enc); + } + SET_ENCODED (g, 0); + SET_MEASURED (g, 0); if (ctx->left_padding) SET_LEFT_PADDING (g, ctx, LeftPaddingMask); for (i = from; i < to; i++) @@ -2021,6 +2165,8 @@ run_command (int depth, int id, int from, int to, FontLayoutContext *ctx) to = run_cond (depth, &cmd->body.cond, from, to, ctx); else if (cmd->type == FontLayoutCmdTypeOTF) to = run_otf (depth, &cmd->body.otf, from, to, ctx); + else if (cmd->type == FontLayoutCmdTypeOTFCategory) + to = try_otf (depth, &cmd->body.otf, from, to, ctx); return to; } @@ -2052,7 +2198,7 @@ run_command (int depth, int id, int from, int to, FontLayoutContext *ctx) if (g->c < 0) MDEBUG_PRINT2 ("\n [FLT] %*s(COPY |)", depth, ""); else - MDEBUG_PRINT3 ("\n [FLT] %*s(COPY 0x%X)", depth, "", g->code); + MDEBUG_PRINT3 ("\n [FLT] %*s(COPY 0x%X)", depth, "", g->c); } ctx->code_offset = ctx->combining_code = ctx->left_padding = 0; return (from + 1); @@ -2091,13 +2237,16 @@ run_command (int depth, int id, int from, int to, FontLayoutContext *ctx) { int i; + if (MDEBUG_FLAG () > 2) + MDEBUG_PRINT2 ("\n [FLT] %*s|", depth, ""); i = from < to ? from : from - 1; GDUP (ctx, i); g = GREF (ctx->out, ctx->out->used - 1); g->c = -1, g->code = 0; g->xadv = g->yadv = 0; - SET_ENCODED (g, 0); + SET_ENCODED (g, 1); SET_MEASURED (g, 0); + SET_CATEGORY_CODE (g, ' '); return from; } @@ -2132,6 +2281,7 @@ run_stages (MFLTGlyphString *gstring, int from, int to, int i, j; MFLTGlyph *g; MPlist *stages = flt->stages; + FontLayoutCategory *prev_category = NULL; from_pos = GREF (ctx->in, from)->from; to_pos = GREF (ctx->in, to - 1)->to; @@ -2151,17 +2301,31 @@ run_stages (MFLTGlyphString *gstring, int from, int to, ctx->stage = (FontLayoutStage *) MPLIST_VAL (stages); table = ctx->stage->category->table; + stages = MPLIST_NEXT (stages); + if (MPLIST_TAIL_P (stages)) + ctx->category = NULL; + else + ctx->category = ((FontLayoutStage *) MPLIST_VAL (stages))->category; ctx->code_offset = ctx->combining_code = ctx->left_padding = 0; ctx->encoded_offset = from; for (i = from; i < to; i++) { MFLTGlyph *g = GREF (ctx->in, i); - char enc = (GET_ENCODED (g) - ? (g->c > 0 ? (int) mchartable_lookup (table, g->c) : 1) - : g->code - ? (int) mchartable_lookup (table, g->code) - : ' '); + char enc; + if (GET_COMBINED (g) + || (prev_category && prev_category != ctx->stage->category)) + { + enc = (GET_ENCODED (g) + ? (g->c > 0 ? (int) mchartable_lookup (table, g->c) : 1) + : g->code + ? (int) mchartable_lookup (table, g->code) + : ' '); + if (! GET_COMBINED (g)) + SET_CATEGORY_CODE (g, enc); + } + else + enc = GET_CATEGORY_CODE (g); ctx->encoded[i - from] = enc; if (! enc && stage_idx == 0) { @@ -2196,12 +2360,12 @@ run_stages (MFLTGlyphString *gstring, int from, int to, if (result < 0) return result; - stages = MPLIST_NEXT (stages); /* If this is the last stage, break the loop. */ if (MPLIST_TAIL_P (stages)) break; /* Otherwise, prepare for the next stage. */ + prev_category = ctx->stage->category; temp = ctx->in; ctx->in = ctx->out; if (buf.glyphs) @@ -2286,7 +2450,7 @@ run_stages (MFLTGlyphString *gstring, int from, int to, ctx->font->get_metrics (ctx->font, ctx->out, 0, ctx->out->used); /* Handle combining. */ - if (ctx->check_mask & CombiningCodeMask) + if (ctx->check_mask & CombinedMask) { MFLTGlyph *base = GREF (ctx->out, 0); int base_height = base->ascent + base->descent; @@ -2296,6 +2460,7 @@ run_stages (MFLTGlyphString *gstring, int from, int to, for (i = 1; i < ctx->out->used; i++) { if ((g = GREF (ctx->out, i)) + && GET_COMBINED (g) && (combining_code = GET_COMBINING_CODE (g))) { int height = g->ascent + g->descent; @@ -2351,7 +2516,7 @@ run_stages (MFLTGlyphString *gstring, int from, int to, for (i = 0; i < ctx->out->used; i++) { g = GREF (ctx->out, i); - if (! GET_COMBINING_CODE (g)) + if (! GET_COMBINED (g)) { if (GET_RIGHT_PADDING (g) && g->rbearing > g->xadv) { @@ -2508,10 +2673,12 @@ m17n_init_flt (void) Mgenerator = msymbol ("generator"); Mend = msymbol ("end"); + mflt_enable_new_feature = 0; mflt_iterate_otf_feature = NULL; mflt_font_id = NULL; + mflt_try_otf = NULL; - MDEBUG_PRINT_TIME ("INIT", (stderr, " to initialize the flt modules.")); + MDEBUG_PRINT_TIME ("INIT", (mdebug__output, " to initialize the flt modules.")); MDEBUG_POP_TIME (); } @@ -2526,7 +2693,7 @@ m17n_fini_flt (void) MDEBUG_PUSH_TIME (); free_flt_list (); - MDEBUG_PRINT_TIME ("FINI", (stderr, " to finalize the flt modules.")); + MDEBUG_PRINT_TIME ("FINI", (mdebug__output, " to finalize the flt modules.")); MDEBUG_POP_TIME (); m17n_fini_core (); } @@ -2652,6 +2819,8 @@ mflt_find (int c, MFLTFont *font) } best = flt; } + if (best == NULL) + return NULL; flt = best; goto found; } @@ -2842,9 +3011,14 @@ mflt_run (MFLTGlyphString *gstring, int from, int to, flt = configure_flt (flt, font, font_id); for (; this_to < to; this_to++) - if (! mchartable_lookup (flt->coverage->table, - GREF (gstring, this_to)->c)) - break; + { + char enc; + g = GREF (gstring, this_to); + enc = (int) mchartable_lookup (flt->coverage->table, g->c); + if (! enc) + break; + SET_CATEGORY_CODE (g, enc); + } if (MDEBUG_FLAG ()) { @@ -2885,14 +3059,24 @@ mflt_run (MFLTGlyphString *gstring, int from, int to, { MDEBUG_PRINT ("\n [FLT] (RESULT"); if (MDEBUG_FLAG () > 1) - for (i = 0; this_from < this_to; this_from++, i++) - { - if (i > 0 && i % 4 == 0) - MDEBUG_PRINT ("\n [FLT] "); - g = GREF (gstring, this_from); - MDEBUG_PRINT4 (" (%04X %d %d %d)", - g->code, g->xadv, g->xoff, g->yoff); - } + { + int idx = -1; + for (i = 0; this_from < this_to; i++, this_from++) + { + g = GREF (gstring, this_from); + if (g->from != idx) + { + if (i > 0) + MDEBUG_PRINT2 ("\n [FLT] %02d-%02d", + g->from, g->to); + else + MDEBUG_PRINT2 (" %02d-%02d", g->from, g->to); + idx = g->from; + } + MDEBUG_PRINT4 (" (%04X %d %d %d)", + g->code, g->xadv, g->xoff, g->yoff); + } + } else for (; this_from < this_to; this_from++) MDEBUG_PRINT1 (" %04X", GREF (gstring, this_from)->code); @@ -2921,6 +3105,8 @@ mflt_run (MFLTGlyphString *gstring, int from, int to, return to; } +int mflt_enable_new_feature; + int (*mflt_iterate_otf_feature) (struct _MFLTFont *font, MFLTOtfSpec *spec, int from, int to, @@ -2928,6 +3114,9 @@ int (*mflt_iterate_otf_feature) (struct _MFLTFont *font, MSymbol (*mflt_font_id) (struct _MFLTFont *font); +int (*mflt_try_otf) (struct _MFLTFont *font, MFLTOtfSpec *spec, + MFLTGlyphString *gstring, int from, int to); + /* for debugging... */ @@ -2940,7 +3129,7 @@ dump_flt_cmd (FontLayoutStage *stage, int id, int indent) prefix[indent] = 0; if (id >= 0) - fprintf (stderr, "0x%02X", id); + fprintf (mdebug__output, "0x%02X", id); else if (id <= CMD_ID_OFFSET_INDEX) { int idx = CMD_ID_TO_INDEX (id); @@ -2951,57 +3140,58 @@ dump_flt_cmd (FontLayoutStage *stage, int id, int indent) FontLayoutCmdRule *rule = &cmd->body.rule; int i; - fprintf (stderr, "(rule "); + fprintf (mdebug__output, "(rule "); if (rule->src_type == SRC_REGEX) - fprintf (stderr, "\"%s\"", rule->src.re.pattern); + fprintf (mdebug__output, "\"%s\"", rule->src.re.pattern); else if (rule->src_type == SRC_INDEX) - fprintf (stderr, "%d", rule->src.match_idx); + fprintf (mdebug__output, "%d", rule->src.match_idx); else if (rule->src_type == SRC_SEQ) - fprintf (stderr, "(seq)"); + fprintf (mdebug__output, "(seq)"); else if (rule->src_type == SRC_RANGE) - fprintf (stderr, "(range)"); + fprintf (mdebug__output, "(range)"); else - fprintf (stderr, "(invalid src)"); + fprintf (mdebug__output, "(invalid src)"); for (i = 0; i < rule->n_cmds; i++) { - fprintf (stderr, "\n%s ", prefix); + fprintf (mdebug__output, "\n%s ", prefix); dump_flt_cmd (stage, rule->cmd_ids[i], indent + 2); } - fprintf (stderr, ")"); + fprintf (mdebug__output, ")"); } else if (cmd->type == FontLayoutCmdTypeCond) { FontLayoutCmdCond *cond = &cmd->body.cond; int i; - fprintf (stderr, "(cond"); + fprintf (mdebug__output, "(cond"); for (i = 0; i < cond->n_cmds; i++) { - fprintf (stderr, "\n%s ", prefix); + fprintf (mdebug__output, "\n%s ", prefix); dump_flt_cmd (stage, cond->cmd_ids[i], indent + 2); } - fprintf (stderr, ")"); + fprintf (mdebug__output, ")"); } else if (cmd->type == FontLayoutCmdTypeOTF) { - fprintf (stderr, "(otf)"); + fprintf (mdebug__output, "(otf)"); } else - fprintf (stderr, "(error-command)"); + fprintf (mdebug__output, "(error-command)"); } else if (id <= CMD_ID_OFFSET_COMBINING) - fprintf (stderr, "cominging-code"); + fprintf (mdebug__output, "cominging-code"); else - fprintf (stderr, "(predefiend %d)", id); + fprintf (mdebug__output, "(predefiend %d)", id); } /***en @brief Dump a Font Layout Table. The mdebug_dump_flt () function prints the Font Layout Table $FLT - in a human readable way to the stderr. $INDENT specifies how many - columns to indent the lines but the first one. + in a human readable way to the stderr or to what specified by the + environment variable MDEBUG_OUTPUT_FILE. $INDENT specifies how + many columns to indent the lines but the first one. @return This function returns $FLT. */ @@ -3015,25 +3205,40 @@ mdebug_dump_flt (MFLT *flt, int indent) memset (prefix, 32, indent); prefix[indent] = 0; - fprintf (stderr, "(flt"); + fprintf (mdebug__output, "(flt"); MPLIST_DO (plist, flt->stages) { FontLayoutStage *stage = (FontLayoutStage *) MPLIST_VAL (plist); int i; - fprintf (stderr, "\n%s (stage %d", prefix, stage_idx); + fprintf (mdebug__output, "\n%s (stage %d", prefix, stage_idx); for (i = 0; i < stage->used; i++) { - fprintf (stderr, "\n%s ", prefix); + fprintf (mdebug__output, "\n%s ", prefix); dump_flt_cmd (stage, INDEX_TO_CMD_ID (i), indent + 4); } - fprintf (stderr, ")"); + fprintf (mdebug__output, ")"); stage_idx++; } - fprintf (stderr, ")"); + fprintf (mdebug__output, ")"); return flt; } +void +mflt_dump_gstring (MFLTGlyphString *gstring) +{ + int i; + + fprintf (mdebug__output, "(flt-gstring"); + for (i = 0; i < gstring->used; i++) + { + MFLTGlyph *g = GREF (gstring, i); + fprintf (mdebug__output, "\n (%02d pos:%d-%d c:%04X code:%04X cat:%c)", + i, g->from, g->to, g->c, g->code, GET_CATEGORY_CODE (g)); + } + fprintf (mdebug__output, ")\n"); +} + /*** @} */ /*