X-Git-Url: http://git.chise.org/gitweb/?p=m17n%2Fm17n-test.git;a=blobdiff_plain;f=flt.c;h=5cf2479de07582dcd00a684c5724fffac7924ff9;hp=dbf6c8898cb36a8cd23c9a88d75ec0843df31e85;hb=1cf616637034fe2f47296758983c415b25966d17;hpb=a85bd34569ff2afdab5b8d9adf11f4ba149daed9 diff --git a/flt.c b/flt.c index dbf6c88..5cf2479 100644 --- a/flt.c +++ b/flt.c @@ -9,11 +9,13 @@ #if defined (FLT_GUI) #include +#include #define PROGNAME "flt-gui" #elif defined (FLT_OTF) #include +#include #include #define PROGNAME "flt-otf" @@ -26,6 +28,7 @@ #else /* (defined (FLT_PANGO)) */ #include +#include #define PANGO_ENABLE_ENGINE #define PANGO_ENABLE_BACKEND #include @@ -113,11 +116,23 @@ new_face (char *fontname, char **err) #ifdef FLT_GUI -typedef struct +typedef struct _MFLTFont MFLTFont; + +struct _MFLTFont { + int x_ppem, y_ppem; + void (*get_glyph_id) (void); + void (*get_metrics) (void); + void (*suitable_p) (void); + void (*drive_otf) (void); MFont *font; FT_Face face; -} MFLTFont; +}; + +void get_glyph_id (void) {} +void get_metrics (void) {} +void suitable_p (void) {} +void drive_otf (void) {} MFrame *frame; @@ -157,21 +172,6 @@ close_font (MFLTFont *font) m17n_object_unref (frame); } -int -flt (MText *mt, int from, int to, MFLTFont *font, char *flt_name) -{ - MDrawControl control; - - memset (&control, 0, sizeof (MDrawControl)); - control.two_dimensional = 1; - control.enable_bidi = 1; - control.anti_alias = 1; - /*control.disable_caching = 1;*/ - mtext_put_prop (mt, from, to, Mfont, font->font); - mdraw_text_extents (frame, mt, from, to, &control, NULL, NULL, NULL); - return 0; -} - #elif defined (FLT_OTF) || defined (FLT_HB) typedef struct { @@ -180,55 +180,50 @@ typedef struct { } FontInfo; int -get_glyph_id (MFLTFont *font, MFLTGlyph *g) +get_glyph_id (MFLTFont *font, MFLTGlyphString *gstring, int from, int to) { FT_Face face = ((FontInfo *) font)->face; - g->code = FT_Get_Char_Index (face, g->code); + for (; from < to; from++) + { + MFLTGlyph *g = gstring->glyphs + from; - return (g->code ? 0 : -1); + if (! g->encoded + && ! (g->code = FT_Get_Char_Index (face, g->code))) + return -1; + g->encoded = 1; + } + return 0; } int -get_metric (MFLTFont *font, MFLTGlyphString *gstring, int from, int to) +get_metrics (MFLTFont *font, MFLTGlyphString *gstring, int from, int to) { FT_Face face = ((FontInfo *) font)->face; for (; from < to; from++) { MFLTGlyph *g = gstring->glyphs + from; - FT_Glyph_Metrics *metrics; - if (FT_Load_Glyph (face, g->code, FT_LOAD_DEFAULT)) - return -1; - metrics = &face->glyph->metrics; - g->lbearing = metrics->horiBearingX; - g->rbearing = metrics->horiBearingX + metrics->width; - g->xadv = metrics->horiAdvance; - g->yadv = metrics->vertAdvance; - g->ascent = metrics->horiBearingY; - g->descent = metrics->height - metrics->horiBearingY; + if (! g->measured) + { + FT_Glyph_Metrics *metrics; + + if (FT_Load_Glyph (face, g->code, FT_LOAD_DEFAULT)) + return -1; + metrics = &face->glyph->metrics; + g->lbearing = metrics->horiBearingX; + g->rbearing = metrics->horiBearingX + metrics->width; + g->xadv = metrics->horiAdvance; + g->yadv = metrics->vertAdvance; + g->ascent = metrics->horiBearingY; + g->descent = metrics->height - metrics->horiBearingY; + g->measured = 1; + } } return 0; } -int -flt (MText *mt, int from, int to, MFLTFont *font, char *flt_name) -{ - MFLTGlyphString gstring; - int len = to - from; - int i; - - memset (&gstring, 0, sizeof (MFLTGlyphString)); - gstring.glyph_size = sizeof (MFLTGlyph); - gstring.allocated = len * 2; - gstring.glyphs = alloca (sizeof (MFLTGlyph) * gstring.allocated); - for (i = 0; i < len; i++) - gstring.glyphs[i].c = mtext_ref_char (mt, from + i); - gstring.used = len; - return mflt_run (&gstring, 0, len, font, msymbol (flt_name)); -} - #ifdef FLT_OTF typedef struct { @@ -392,7 +387,11 @@ drive_otf (MFLTFont *font, MFLTOtfSpec *spec, g->c = in->glyphs[j].c; break; } - g->code = otfg->glyph_id; + if (g->code != otfg->glyph_id) + { + g->code = otfg->glyph_id; + g->measured = 0; + } out->used++; } } @@ -404,8 +403,6 @@ drive_otf (MFLTFont *font, MFLTOtfSpec *spec, out->glyphs[out->used++] = in->glyphs[from + i]; } - font->get_metric (font, out, gidx, out->used); - if (gpos_features) { FT_Face face; @@ -510,7 +507,7 @@ drive_otf (MFLTFont *font, MFLTOtfSpec *spec, return to; simple_copy: - font->get_metric (font, in, from, to); + font->get_metrics (font, in, from, to); for (i = 0; i < len; i++) { MFLTGlyph *g = in->glyphs + (from + i); @@ -741,7 +738,6 @@ setup_features (int gsubp, FontInfoHB *font_info, MFLTOtfSpec *spec, FT_UShort req_feature, index; FT_UInt *feature_list; int i, j, k; - HB_Error err; if (gsubp) { @@ -921,7 +917,11 @@ drive_otf (MFLTFont *font, MFLTOtfSpec *spec, out->glyphs[out->used] = in->glyphs[hg->cluster]; g = out->glyphs + out->used++; if (g->code != hg->gindex) - g->c = 0, g->code = hg->gindex; + { + g->c = 0; + g->code = hg->gindex; + g->measured = 0; + } adjustment[i].set = gpos_applied; if (gpos_applied) { @@ -1018,16 +1018,27 @@ typedef struct { } FontInfoPango; int -get_glyph_id (MFLTFont *font, MFLTGlyph *g) +get_glyph_id (MFLTFont *font, MFLTGlyphString *gstring, int from, int to) { FontInfoPango *font_info = (FontInfoPango *) font; - g->code = pango_fc_font_get_glyph (font_info->pango_font, g->c); - return (g->code ? 0 : -1); + for (; from < to; from++) + { + MFLTGlyph *g = gstring->glyphs + from; + + if (! g->encoded + && ! (g->code = pango_fc_font_get_glyph (font_info->pango_font, + g->code))) + return -1; + g->encoded = 1; + } + return 0; } +#define PANGO_SCALE_TO_26_6 (PANGO_SCALE / (1<<6)) + int -get_metric (MFLTFont *font, MFLTGlyphString *gstring, int from, int to) +get_metrics (MFLTFont *font, MFLTGlyphString *gstring, int from, int to) { FontInfoPango *font_info = (FontInfoPango *) font; int i; @@ -1035,19 +1046,26 @@ get_metric (MFLTFont *font, MFLTGlyphString *gstring, int from, int to) for (i = from; i < to; i++) { MFLTGlyph *g = gstring->glyphs + from; - PangoRectangle inc, logical; - pango_font_get_glyph_extents (PANGO_FONT (font_info->pango_font), - gstring->glyphs[i].code, &inc, &logical); - g->lbearing = inc.x; - g->rbearing = inc.x + inc.width; - g->xadv = logical.width; - g->yadv = 0; - g->ascent = - inc.y; - g->descent = inc.height + inc.y; + if (! g->measured) + { + PangoRectangle inc, logical; + + pango_font_get_glyph_extents (PANGO_FONT (font_info->pango_font), + gstring->glyphs[i].code, &inc, &logical); + g->lbearing = inc.x / PANGO_SCALE_TO_26_6; + g->rbearing = (inc.x + inc.width) / PANGO_SCALE_TO_26_6; + g->xadv = logical.width / PANGO_SCALE_TO_26_6; + g->yadv = 0; + g->ascent = - inc.y / PANGO_SCALE_TO_26_6; + g->descent = (inc.height + inc.y) / PANGO_SCALE_TO_26_6; + g->measured = 1; + } } + return 0; } + #ifndef PANGO_OT_DEFAULT_LANGUAGE #define PANGO_OT_DEFAULT_LANGUAGE ((guint) 0xFFFF) #endif @@ -1065,7 +1083,6 @@ setup_features (PangoOTTableType type, FontInfoPango *font_info, guint req_feature, index; guint *feature_list; int i, j, k; - int err; FT_Face face; PangoOTInfo *ot_info; @@ -1132,9 +1149,15 @@ setup_features (PangoOTTableType type, FontInfoPango *font_info, } info->count = i; info->ruleset = pango_ot_ruleset_new (ot_info); +#if 1 for (i = 0; i < info->count; i++) pango_ot_ruleset_add_feature (info->ruleset, type, info->indices[i], PANGO_OT_ALL_GLYPHS); +#else + for (i = info->count - 1; i >= 0; i--) + pango_ot_ruleset_add_feature (info->ruleset, type, info->indices[i], + PANGO_OT_ALL_GLYPHS); +#endif } GsubGposInfo * @@ -1185,10 +1208,14 @@ drive_otf (MFLTFont *font, MFLTOtfSpec *spec, out->glyphs[out->used] = in->glyphs[glyphs->log_clusters[i]]; g = out->glyphs + out->used++; if (g->code != glyph_info->glyph) - g->c = 0, g->code = glyph_info->glyph; - g->xoff = glyph_info->geometry.x_offset; - g->yoff = glyph_info->geometry.y_offset; - g->xadv = glyph_info->geometry.width; + { + g->c = 0; + g->code = glyph_info->glyph; + g->measured = 0; + } + g->xoff = glyph_info->geometry.x_offset / PANGO_SCALE_TO_26_6; + g->yoff = glyph_info->geometry.y_offset / PANGO_SCALE_TO_26_6; + g->xadv = glyph_info->geometry.width / PANGO_SCALE_TO_26_6; g->yadv = 0; adjustment[i].set = 0; } @@ -1254,25 +1281,77 @@ close_font (MFLTFont *font) g_object_unref (font_info->fontmap); } +#endif + +#ifdef FLT_GUI + int -flt (MText *mt, int from, int to, MFLTFont *font, char *flt_name) +run_flt (MText *mt, int from, int to, MFLTFont *font, char *flt_name) { - MFLTGlyphString gstring; - int len = to - from; - int i; + MDrawControl control; - memset (&gstring, 0, sizeof (MFLTGlyphString)); - gstring.glyph_size = sizeof (MFLTGlyph); - gstring.allocated = len * 2; - gstring.glyphs = alloca (sizeof (MFLTGlyph) * gstring.allocated); - for (i = 0; i < len; i++) - gstring.glyphs[i].c = mtext_ref_char (mt, from + i); - gstring.used = len; - return mflt_run (&gstring, 0, len, font, msymbol (flt_name)); + memset (&control, 0, sizeof (MDrawControl)); + control.two_dimensional = 1; + control.enable_bidi = 1; + control.anti_alias = 1; + /*control.disable_caching = 1;*/ + mtext_put_prop (mt, from, to, Mfont, font->font); + mdraw_text_extents (frame, mt, from, to, &control, NULL, NULL, NULL); + return 0; } +#else + +int +run_flt (MText *mt, int from, int to, MFLTFont *font, char *flt_name) +{ + static MFLT *flt = NULL; + MCharTable *coverage; + static MFLTGlyphString gstring; + + if (! flt + && ! (flt = mflt_get (flt_name))) + { + fprintf (stderr, "Invalid FLT name: %s\n", flt_name); + exit (1); + } + coverage = mflt_coverage (flt); + while (from < to) + { + int len = 0, i; + + for (; from < to; from++) + if (mchartable_lookup (coverage, mtext_ref_char (mt, from))) + { + for (i = from + 1; i < to; i++) + if (! mchartable_lookup (coverage, mtext_ref_char (mt, i))) + break; + len = i - from; + break; + } + if (len > 0) + { + if (gstring.allocated < len) + { + gstring.allocated = len * 2; + gstring.glyphs = realloc (gstring.glyphs, + sizeof (MFLTGlyph) * len * 2); + } + gstring.glyph_size = sizeof (MFLTGlyph); + for (i = 0; i < len; i++) + gstring.glyphs[i].c = mtext_ref_char (mt, from + i); + gstring.used = len; + i = mflt_run (&gstring, 0, len, font, flt); + if (i < 0) + return i; + from += len; + } + } + return to; +} #endif + int main (int argc, char **argv) { @@ -1281,6 +1360,7 @@ main (int argc, char **argv) MText *mt; MFLTFont *font; int len, i, j; + unsigned char *buf; if (argc < 3) { @@ -1300,23 +1380,35 @@ main (int argc, char **argv) exit (1); } font->get_glyph_id = get_glyph_id; - font->get_metric = get_metric; + font->get_metrics = get_metrics; font->drive_otf = drive_otf; - mt = mconv_decode_stream (msymbol ("utf-8"), stdin); + i = 0; + buf = malloc (4096); + while ((j = fread (buf + i, 1, 4096, stdin)) == 4096) + { + i += 4096; + buf = realloc (buf, i + 4096); + } + mt = mtext_from_data (buf, i, MTEXT_FORMAT_UTF_8); len = mtext_len (mt); for (i = 0, j = mtext_character (mt, i, len, '\n'); i < len; i = j + 1, j = mtext_character (mt, i, len, '\n')) { + int to; + if (j < 0) j = len; - if (flt (mt, i, j, font, flt_name) < 0) + to = run_flt (mt, i, j, font, flt_name); + if (to < 0) { fprintf (stderr, "Error in FLT processing.\n"); exit (1); } + i = j; } m17n_object_unref (mt); + free (buf); close_font (font); M17N_FINI (); return 0;