X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Fm17n-flt.c;h=7423026341376d084eb1254df120eb8bb35a82f3;hb=3628173afa3d3f97a9fd07277382fa08c9de8970;hp=14d8a54e32327a3ae852c6db5d53b56cd33c8da0;hpb=317aea5fc2baca769ac4b1d19c3cde94bdae051a;p=m17n%2Fm17n-lib.git diff --git a/src/m17n-flt.c b/src/m17n-flt.c index 14d8a54..7423026 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 @@ -257,9 +257,9 @@ enum GlyphInfoMask { CategoryCodeMask = 0x7F, CombiningCodeMask = 0xFFFFFF, - CombinedMask = 1 << 27, - LeftPaddingMask = 1 << 28, - RightPaddingMask = 1 << 29 + CombinedMask = 1 << 28, + LeftPaddingMask = 1 << 29, + RightPaddingMask = 1 << 30 }; #define SET_GLYPH_INFO(g, mask, ctx, info) \ @@ -543,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) @@ -566,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; @@ -743,7 +755,16 @@ parse_otf_command (MSymbol symbol, MFLTOtfSpec *spec) memset (spec, 0, sizeof (MFLTOtfSpec)); spec->sym = symbol; - str += 5; /* skip the heading ":otf=" */ + 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; + } script = gen_otf_tag (str, 8); str += 4; if (*str == '/') @@ -818,7 +839,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); @@ -831,7 +852,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; } @@ -1169,9 +1190,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) @@ -1395,6 +1415,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; @@ -1421,7 +1443,7 @@ load_flt (MFLT *flt, MPlist *key_list) } if (category) unref_category_table (category); - + err: if (! MPLIST_TAIL_P (plist)) { M17N_OBJECT_UNREF (top); @@ -1570,7 +1592,7 @@ typedef struct static int run_command (int, int, int, int, FontLayoutContext *); static int run_otf (int, MFLTOtfSpec *, int, int, FontLayoutContext *); -static int run_otf_category (int, MFLTOtfSpec *, int, int, FontLayoutContext *); +static int try_otf (int, MFLTOtfSpec *, int, int, FontLayoutContext *); #define NMATCH 20 @@ -1704,12 +1726,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++; } @@ -1844,8 +1866,8 @@ run_cond (int depth, } static void -decode_packed_otf_tag (MFLTGlyphString *gstring, int from, int to, - FontLayoutCategory *category) +decode_packed_otf_tag (FontLayoutContext *ctx, MFLTGlyphString *gstring, + int from, int to, FontLayoutCategory *category) { for (; from < to; from++) { @@ -1853,6 +1875,8 @@ decode_packed_otf_tag (MFLTGlyphString *gstring, int from, int to, unsigned int tag = g->internal & 0xFFFFFFF; char enc; + if (GET_COMBINED (g)) + continue; if (! category) { SET_CATEGORY_CODE (g, 0); @@ -1862,16 +1886,19 @@ decode_packed_otf_tag (MFLTGlyphString *gstring, int from, int to, { int i; - g->internal &= 0x30000000; + /* Clear the feature tag code. */ + g->internal &= ~0xFFFFFFF; for (i = 0, enc = '\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; } } else - enc = GET_COMBINED (g) ? '\0' : GET_CATEGORY_CODE (g); + enc = '\0'; if (! enc) enc = g->c > 0 ? (int) mchartable_lookup (category->table, g->c) : 1; SET_CATEGORY_CODE (g, enc); @@ -1913,7 +1940,8 @@ run_otf (int depth, adjustment); if (to < 0) return to; - decode_packed_otf_tag (ctx->out, from_idx, ctx->out->used, ctx->category); + 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]) { @@ -1986,28 +2014,49 @@ run_otf (int depth, } static int -run_otf_category (int depth, MFLTOtfSpec *otf_spec, int from, int to, - FontLayoutContext *ctx) +try_otf (int depth, MFLTOtfSpec *otf_spec, int from, int to, + FontLayoutContext *ctx) { MFLTFont *font = ctx->font; - int from_idx = ctx->out->used; - - if (! ctx->category || ctx->category->feature_table.size == 0) - return from; if (MDEBUG_FLAG () > 2) MDEBUG_PRINT3 ("\n [FLT] %*s%s", depth, "", MSYMBOL_NAME (otf_spec->sym)); - font->get_glyph_id (font, ctx->in, from, to); - if (font->drive_otf) + if (! otf_spec->features[0] && ! otf_spec->features[1]) { - int out_len; + /* Reset categories. */ + MCharTable *table = ctx->category->table; int i; - to = font->drive_otf (font, otf_spec, ctx->in, from, to, NULL, NULL); + 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->in, from, to, ctx->category); + decode_packed_otf_tag (ctx, ctx->in, from, to, ctx->stage->category); } return from; } @@ -2113,7 +2162,7 @@ run_command (int depth, int id, int from, int to, FontLayoutContext *ctx) else if (cmd->type == FontLayoutCmdTypeOTF) to = run_otf (depth, &cmd->body.otf, from, to, ctx); else if (cmd->type == FontLayoutCmdTypeOTFCategory) - to = run_otf_category (depth, &cmd->body.otf, from, to, ctx); + to = try_otf (depth, &cmd->body.otf, from, to, ctx); return to; } @@ -2136,17 +2185,6 @@ run_command (int depth, int id, int from, int to, FontLayoutContext *ctx) g = GREF (ctx->out, ctx->out->used - 1); if (ctx->combining_code) SET_COMBINING_CODE (g, ctx, ctx->combining_code); - else if (! GET_COMBINED (g) && ctx->category) - { - MCharTable *table = ctx->category->table; - 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); - } if (ctx->left_padding) SET_LEFT_PADDING (g, ctx, LeftPaddingMask); if (ctx->cluster_begin_idx >= 0) @@ -2200,8 +2238,8 @@ run_command (int depth, int id, int from, int to, FontLayoutContext *ctx) g = GREF (ctx->out, ctx->out->used - 1); g->c = -1, g->code = 0; g->xadv = g->yadv = 0; - SET_ENCODED (g, 1); - SET_MEASURED (g, 1); + SET_ENCODED (g, 0); + SET_MEASURED (g, 0); SET_CATEGORY_CODE (g, ' '); return from; } @@ -2237,6 +2275,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; @@ -2268,12 +2307,17 @@ run_stages (MFLTGlyphString *gstring, int from, int to, MFLTGlyph *g = GREF (ctx->in, i); char enc; - if (GET_COMBINED (g)) - 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) + || (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; @@ -2315,6 +2359,7 @@ run_stages (MFLTGlyphString *gstring, int from, int to, break; /* Otherwise, prepare for the next stage. */ + prev_category = ctx->stage->category; temp = ctx->in; ctx->in = ctx->out; if (buf.glyphs) @@ -2622,10 +2667,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 (); } @@ -2640,7 +2687,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 (); } @@ -2766,6 +2813,8 @@ mflt_find (int c, MFLTFont *font) } best = flt; } + if (best == NULL) + return NULL; flt = best; goto found; } @@ -3040,6 +3089,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, @@ -3047,6 +3098,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... */ @@ -3059,7 +3113,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); @@ -3070,57 +3124,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. */ @@ -3134,22 +3189,22 @@ 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; } @@ -3158,14 +3213,14 @@ mflt_dump_gstring (MFLTGlyphString *gstring) { int i; - fprintf (stderr, "(flt-gstring"); + fprintf (mdebug__output, "(flt-gstring"); for (i = 0; i < gstring->used; i++) { MFLTGlyph *g = GREF (gstring, i); - fprintf (stderr, "\n (%02d pos:%d-%d c:%04X code:%04X cat:%c)", + 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 (stderr, ")\n"); + fprintf (mdebug__output, ")\n"); } /*** @} */