X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Ffont-flt.c;h=b4fdc694a48d3d7b3b6d159bd41966cc9cf528c7;hb=3dbe5210009c5328999362178544d143a8f7b992;hp=b93c5c4377a03d42146771e163c41c973d4a0cfb;hpb=49710cb3227e453a73f915dd6c54c2efa038a1a9;p=m17n%2Fm17n-lib.git diff --git a/src/font-flt.c b/src/font-flt.c index b93c5c4..b4fdc69 100644 --- a/src/font-flt.c +++ b/src/font-flt.c @@ -263,6 +263,17 @@ static MSymbol Mcond, Mrange; #define GLYPH_CODE_INDEX(code) ((code) - GLYPH_CODE_MIN) +#define UPDATE_CLUSTER_RANGE(ctx, g) \ + do { \ + if ((ctx)->cluster_begin_idx) \ + { \ + if (ctx->cluster_begin_pos > (g).pos) \ + ctx->cluster_begin_pos = (g).pos; \ + if (ctx->cluster_end_pos < (g).to) \ + ctx->cluster_end_pos = (g).to; \ + } \ + } while (0); + enum FontLayoutCmdRuleSrcType { SRC_REGEX, @@ -295,18 +306,15 @@ typedef struct typedef struct { + /* Beginning and end indices of series of SEQ commands. */ + int seq_beg, seq_end; + /* Range of the first character appears in the above series. */ + int seq_from, seq_to; + int n_cmds; int *cmd_ids; } FontLayoutCmdCond; -typedef struct -{ - MSymbol script; - MSymbol langsys; - MSymbol gsub_features; - MSymbol gpos_features; -} FontLayoutCmdOTF; - enum FontLayoutCmdType { FontLayoutCmdTypeRule, @@ -317,6 +325,14 @@ enum FontLayoutCmdType typedef struct { + MSymbol script; + MSymbol langsys; + MSymbol gsub_features; + MSymbol gpos_features; +} FontLayoutCmdOTF; + +typedef struct +{ enum FontLayoutCmdType type; union { FontLayoutCmdRule rule; @@ -574,12 +590,17 @@ load_command (FontLayoutStage *stage, MPlist *plist, if (MPLIST_SYMBOL_P (elt)) { + FontLayoutCmdCond *cond; + if (MPLIST_SYMBOL (elt) != Mcond) MERROR (MERROR_DRAW, INVALID_CMD_ID); elt = MPLIST_NEXT (elt); cmd->type = FontLayoutCmdTypeCond; - cmd->body.cond.n_cmds = len; - MTABLE_CALLOC (cmd->body.cond.cmd_ids, len, MERROR_DRAW); + cond = &cmd->body.cond; + cond->seq_beg = cond->seq_end = -1; + cond->seq_from = cond->seq_to = 0; + cond->n_cmds = len; + MTABLE_CALLOC (cond->cmd_ids, len, MERROR_DRAW); for (i = 0; i < len; i++, elt = MPLIST_NEXT (elt)) { int this_id = load_command (stage, elt, macros, INVALID_CMD_ID); @@ -588,8 +609,50 @@ load_command (FontLayoutStage *stage, MPlist *plist, MERROR (MERROR_DRAW, INVALID_CMD_ID); /* The above load_command may relocate stage->cmds. */ cmd = stage->cmds + CMD_ID_TO_INDEX (id); - cmd->body.cond.cmd_ids[i] = this_id; + cond = &cmd->body.cond; + cond->cmd_ids[i] = this_id; + if (this_id <= CMD_ID_OFFSET_INDEX) + { + FontLayoutCmd *this_cmd + = stage->cmds + CMD_ID_TO_INDEX (this_id); + + if (this_cmd->type == FontLayoutCmdTypeRule + && this_cmd->body.rule.src_type == SRC_SEQ) + { + int first_char = this_cmd->body.rule.src.seq.codes[0]; + + if (cond->seq_beg < 0) + { + /* The first SEQ command. */ + cond->seq_beg = i; + cond->seq_from = cond->seq_to = first_char; + } + else if (cond->seq_end < 0) + { + /* The following SEQ command. */ + if (cond->seq_from > first_char) + cond->seq_from = first_char; + else if (cond->seq_to < first_char) + cond->seq_to = first_char; + } + } + else + { + if (cond->seq_beg >= 0 && cond->seq_end < 0) + /* The previous one is the last SEQ command. */ + cond->seq_end = i; + } + } + else + { + if (cond->seq_beg >= 0 && cond->seq_end < 0) + /* The previous one is the last SEQ command. */ + cond->seq_end = i; + } } + if (cond->seq_beg >= 0 && cond->seq_end < 0) + /* The previous one is the last SEQ command. */ + cond->seq_end = i; } else { @@ -804,6 +867,7 @@ load_flt (MSymbol layouter_name) MPlist *top = NULL, *plist; MSymbol Mcategory = msymbol ("category"); MSymbol Mgenerator = msymbol ("generator"); + MSymbol Mend = msymbol ("end"); MFontLayoutTable *layouter = NULL; MCharTable *category = NULL; @@ -819,6 +883,9 @@ load_flt (MSymbol layouter_name) MSymbol sym; MPlist *elt; + if (MPLIST_SYMBOL_P (plist) + && MPLIST_SYMBOL (plist) == Mend) + break; if (! MPLIST_PLIST (plist)) MERROR_GOTO (MERROR_FONT, finish); elt = MPLIST_PLIST (plist); @@ -930,14 +997,6 @@ run_rule (int depth, int i; int orig_from = from; - if (ctx->cluster_begin_idx) - { - if (ctx->cluster_begin_pos > MGLYPH (from)->pos) - ctx->cluster_begin_pos = MGLYPH (from)->pos; - if (ctx->cluster_end_pos < MGLYPH (to)->pos) - ctx->cluster_end_pos = MGLYPH (to)->pos; - } - if (rule->src_type == SRC_SEQ) { int len; @@ -951,7 +1010,8 @@ run_rule (int depth, if (i < len) return 0; to = from + len; - MDEBUG_PRINT1 (" (SEQ 0x%X", rule->src.seq.codes[0]); + MDEBUG_PRINT3 ("\n [FLT] %*s(SEQ 0x%X", depth, "", + rule->src.seq.codes[0]); } else if (rule->src_type == SRC_RANGE) { @@ -964,7 +1024,7 @@ run_rule (int depth, return 0; ctx->code_offset = head - rule->src.range.from; to = from + 1; - MDEBUG_PRINT2 (" (RANGE 0x%X-0x%X", + MDEBUG_PRINT4 ("\n [FLT] %*s(RANGE 0x%X-0x%X", depth, "", rule->src.range.from, rule->src.range.to); } else if (rule->src_type == SRC_REGEX) @@ -982,7 +1042,7 @@ run_rule (int depth, NMATCH, pmatch, 0); if (result == 0 && pmatch[0].rm_so == 0) { - MDEBUG_PRINT3 (" (REGEX \"%s\" \"%s\" %d", + MDEBUG_PRINT5 ("\n [FLT] %*s(REGEX \"%s\" \"%s\" %d", depth, "", rule->src.re.pattern, ctx->encoded + from - ctx->encoded_offset, pmatch[0].rm_eo); @@ -1014,7 +1074,7 @@ run_rule (int depth, if (from < 0) return 0; to = ctx->match_indices[rule->src.match_idx * 2 + 1]; - MDEBUG_PRINT1 (" (INDEX %d", rule->src.match_idx); + MDEBUG_PRINT3 ("\n [FLT] %*s(INDEX %d", depth, "", rule->src.match_idx); } consumed = 0; @@ -1052,9 +1112,13 @@ run_cond (int depth, MDEBUG_PRINT2 ("\n [FLT] %*s(COND", depth, ""); depth++; for (i = 0; i < cond->n_cmds; i++) - if ((pos = run_command (depth, cond->cmd_ids[i], gstring, from, to, ctx)) - != 0) - break; + { + /* TODO: Write a code for optimization utilizaing the info + cond->seq_XXX. */ + if ((pos = run_command (depth, cond->cmd_ids[i], gstring, from, to, ctx)) + != 0) + break; + } if (pos < 0) MERROR (MERROR_DRAW, -1); MDEBUG_PRINT (")"); @@ -1067,13 +1131,19 @@ run_otf (int depth, FontLayoutContext *ctx) { #ifdef HAVE_OTF - int gidx = gstring->used; + int from_idx = gstring->used; + MDEBUG_PRINT4 ("\n [FLT] %*s(OTF %s,%s)", depth, "", + (otf_cmd->gsub_features == Mnil ? "" + : MSYMBOL_NAME (otf_cmd->gsub_features)), + (otf_cmd->gpos_features == Mnil ? "" + : MSYMBOL_NAME (otf_cmd->gpos_features))); to = mfont__ft_drive_otf (gstring, from, to, otf_cmd->script, otf_cmd->langsys, otf_cmd->gsub_features, otf_cmd->gpos_features); - if (gidx < gstring->used) - MGLYPH (gidx)->left_padding = ctx->left_padding; + if (ctx->cluster_begin_idx) + for (; from_idx < gstring->used; from_idx++) + UPDATE_CLUSTER_RANGE (ctx, gstring->glyphs[from_idx]); #endif return to; } @@ -1096,7 +1166,7 @@ run_command (int depth, int id, MGlyphString *gstring, int from, int to, g = *(MGLYPH (from - 1)); g.type = GLYPH_CHAR; g.code = ctx->code_offset + id; - MDEBUG_PRINT1 (" (DIRECT 0x%X", g.code); + MDEBUG_PRINT3 ("\n [FLT] %*s(DIRECT 0x%X", depth, "", g.code); if (ctx->combining_code) g.combining_code = ctx->combining_code; if (ctx->left_padding) @@ -1111,6 +1181,7 @@ run_command (int depth, int id, MGlyphString *gstring, int from, int to, g.to = tmp->to; } APPEND_GLYPH (gstring, g); + UPDATE_CLUSTER_RANGE (ctx, g); ctx->code_offset = ctx->combining_code = ctx->left_padding = 0; MDEBUG_PRINT (")"); return (from); @@ -1154,6 +1225,8 @@ run_command (int depth, int id, MGlyphString *gstring, int from, int to, if (ctx->left_padding) g.left_padding = ctx->left_padding; APPEND_GLYPH (gstring, g); + UPDATE_CLUSTER_RANGE (ctx, g); + MDEBUG_PRINT3 ("\n [FLT] %*s(COPY 0x%X)", depth, "", g.code); ctx->code_offset = ctx->combining_code = ctx->left_padding = 0; return (from + 1); } @@ -1161,7 +1234,7 @@ run_command (int depth, int id, MGlyphString *gstring, int from, int to, case CMD_ID_CLUSTER_BEGIN: if (! ctx->cluster_begin_idx) { - MDEBUG_PRINT1 (" <%d", MGLYPH (from)->pos); + MDEBUG_PRINT3 ("\n [FLT] %*s<%d", depth, "", MGLYPH (from)->pos); ctx->cluster_begin_idx = gstring->used; ctx->cluster_begin_pos = MGLYPH (from)->pos; ctx->cluster_end_pos = MGLYPH (from)->to; @@ -1256,8 +1329,7 @@ mfont__flt_encode_char (MSymbol layouter_name, int c) } int -mfont__flt_run (MGlyphString *gstring, int from, int to, - MSymbol layouter_name, MRealizedFace *ascii_rface) +mfont__flt_run (MGlyphString *gstring, int from, int to, MRealizedFace *rface) { int stage_idx = 0; int gidx; @@ -1266,7 +1338,9 @@ mfont__flt_run (MGlyphString *gstring, int from, int to, MCharTable *table; int encoded_len; int match_indices[NMATCH]; + MSymbol layouter_name = rface->rfont->layouter; MFontLayoutTable *layouter = get_font_layout_table (layouter_name); + MRealizedFace *ascii_rface = rface->ascii_rface; FontLayoutStage *stage; int from_pos, to_pos; MGlyph dummy; @@ -1325,11 +1399,28 @@ mfont__flt_run (MGlyphString *gstring, int from, int to, int len = to - from; int result; - MDEBUG_PRINT1 ("\n [FLT] (STAGE %d", stage_idx); + MDEBUG_PRINT2 ("\n [FLT] (STAGE %d \"%s\"", stage_idx, ctx.encoded); + if (mdebug__flag & mdebug_mask + && ctx.encoded_offset < to) + { + if (gstring->glyphs[ctx.encoded_offset].type == GLYPH_PAD) + fprintf (stderr, " (|"); + else + fprintf (stderr, " (%X", gstring->glyphs[ctx.encoded_offset].code); + for (i = ctx.encoded_offset + 1; i < to; i++) + { + if (gstring->glyphs[i].type == GLYPH_PAD) + fprintf (stderr, " |"); + else + fprintf (stderr, " %X", gstring->glyphs[i].code); + } + fprintf (stderr, ")"); + } + gidx = gstring->used; ctx.stage = stage; - result = run_command (2, INDEX_TO_CMD_ID (0), gstring, + result = run_command (4, INDEX_TO_CMD_ID (0), gstring, ctx.encoded_offset, to, &ctx); MDEBUG_PRINT (")"); if (result < 0) @@ -1359,7 +1450,7 @@ mfont__flt_run (MGlyphString *gstring, int from, int to, ctx.encoded[i - from] = ' '; else if (! g->otf_encoded) ctx.encoded[i - from] = (int) mchartable_lookup (table, g->code); -#ifdef HAVE_FREETYPE +#if defined (HAVE_FREETYPE) && defined (HAVE_OTF) else { int c = mfont__ft_decode_otf (g); @@ -1372,7 +1463,7 @@ mfont__flt_run (MGlyphString *gstring, int from, int to, } ctx.encoded[i - from] = (c >= 0 ? c : 1); } -#endif /* HAVE_FREETYPE */ +#endif /* HAVE_FREETYPE && HAVE_OTF */ } ctx.encoded[i - from] = '\0'; ctx.encoded_offset = from; @@ -1380,8 +1471,6 @@ mfont__flt_run (MGlyphString *gstring, int from, int to, ctx.match_indices[1] = to; } - MDEBUG_PRINT (")\n"); - if (from == to) { /* Somehow there's no glyph contributing to characters between @@ -1398,15 +1487,19 @@ mfont__flt_run (MGlyphString *gstring, int from, int to, } else { - /* Here we must check if all characters in the range is covered - by some glyph(s). If not, change and of glyphs to - cover uncovered characters. */ + /* Get actual glyph IDs of glyphs. Also check if all characters + in the range is covered by some glyph(s). If not, change + and of glyphs to cover uncovered characters. */ int len = to_pos - from_pos; int pos; MGlyph **glyphs = alloca (sizeof (MGlyph) * len); MGlyph *g, *gend = MGLYPH (to); MGlyph *latest = gend; + for (g = MGLYPH (from); g != gend; g++) + if (g->type == GLYPH_CHAR && ! g->otf_encoded) + g->code + = (rface->rfont->driver->encode_char) (rface->rfont, g->code); for (i = 0; i < len; i++) glyphs[i] = NULL; for (g = MGLYPH (from); g != gend; g++) @@ -1438,6 +1531,25 @@ mfont__flt_run (MGlyphString *gstring, int from, int to, latest = glyphs[i]; } } + MDEBUG_PRINT ("\n [FLT] (RESULT ("); + if (mdebug__flag & mdebug_mask + && ctx.encoded_offset < to) + { + if (gstring->glyphs[from].type == GLYPH_PAD) + fprintf (stderr, "|"); + else + fprintf (stderr, "%X", gstring->glyphs[from].code); + for (from++; from < to; from++) + { + if (gstring->glyphs[from].type == GLYPH_PAD) + fprintf (stderr, " |"); + else + fprintf (stderr, " %X", gstring->glyphs[from].code); + } + fprintf (stderr, "))"); + } + MDEBUG_PRINT (")\n"); + return to; }