Hi, Current mgp in sarge was broken once m17n supported was added at 1.11b-2. In addition, I found that mgp 1.11b-2 missed build-depends on libfontconfig1-dev. Upstream developers and I fixed broken m17n support of mgp 1.11b. I uploaded 1.11b-3 to fix these issues, so please accept this version for sarge. Thanks, Fumitoshi UKAI diff -Nru mgp-1.11b-2/configure.in mgp-1.11b/configure.in --- mgp-1.11b-2/configure.in 2004-08-05 01:23:35.000000000 +0900 +++ mgp-1.11b/configure.in 2005-05-14 01:18:15.000000000 +0900 @@ -304,7 +304,7 @@ LIBS="$LIBS -L$i/lib" OPTFLAGS="$OPTFLAGS -I$i/include" AC_CHECK_LIB(mng, mng_initialize, - [LIBS="$LIBS -Wl,-rpath,$i/lib -lmng" + [LIBS="$LIBS -lmng" AC_DEFINE(MNG)], [AC_CHECK_LIB(mng, mng_readdisplay, [LIBS="$LIBS -lmng -ljpeg" @@ -383,6 +383,8 @@ [LIBS="$LIBS -liconv"; AC_DEFINE(HAVE_ICONV)])])]) fi +AC_CHECK_HEADERS(fontconfig/fontconfig.h) + AC_MSG_CHECKING(if gif handling is enabled) AC_ARG_ENABLE(gif, [ --enable-gif compile gif support in (need libungif).], diff -Nru mgp-1.11b-2/debian/changelog mgp-1.11b/debian/changelog --- mgp-1.11b-2/debian/changelog 2005-04-20 01:17:59.000000000 +0900 +++ mgp-1.11b/debian/changelog 2005-05-15 23:59:24.768476154 +0900 @@ -1,3 +1,11 @@ +mgp (1.11b-3) unstable; urgency=high + + * fix broken m17n support + closes: Bug#308213 + * add missing build-depends: libfontconfig1-dev + + -- Fumitoshi UKAI <ukai@debian.or.jp> Sun, 15 May 2005 23:53:37 +0900 + mgp (1.11b-2) unstable; urgency=low * build with --with-m17n-lib diff -Nru mgp-1.11b-2/debian/control mgp-1.11b/debian/control --- mgp-1.11b-2/debian/control 2005-04-19 01:48:04.000000000 +0900 +++ mgp-1.11b/debian/control 2005-05-14 01:25:12.000000000 +0900 @@ -2,7 +2,7 @@ Section: x11 Priority: optional Maintainer: Fumitoshi UKAI <ukai@debian.or.jp> -Build-Depends: debhelper (>= 3.0.0), cpp, devscripts, xutils, flex, bison, pkg-config, libxft2-dev, libpng12-0-dev, libmng-dev, xlibs-dev, gawk | awk, sharutils, zlib1g-dev, libungif4-dev, imlib11-dev, libtiff4-dev, libm17n-dev +Build-Depends: debhelper (>= 3.0.0), cpp, devscripts, xutils, flex, bison, pkg-config, libxft2-dev, libpng12-0-dev, libmng-dev, xlibs-dev, gawk | awk, sharutils, zlib1g-dev, libungif4-dev, imlib11-dev, libtiff4-dev, libm17n-dev, libfontconfig1-dev Standards-Version: 3.5.4 Package: mgp diff -Nru mgp-1.11b-2/draw.c mgp-1.11b/draw.c --- mgp-1.11b-2/draw.c 2004-09-08 01:57:42.000000000 +0900 +++ mgp-1.11b/draw.c 2005-05-14 01:18:15.000000000 +0900 @@ -65,10 +65,7 @@ static void process_direc __P((struct render_state *, int *)); static int set_position __P((struct render_state *)); -static void draw_line_start __P((struct render_state *)); -void draw_line_itemsize __P((struct render_state *, int, int, int)); static void draw_line_output __P((struct render_state *, char *)); -static void draw_line_end __P((struct render_state *)); static void cutin __P((struct render_state *, int, int, int)); #if 0 static void shrink __P((char *, u_int)); @@ -573,6 +570,13 @@ case CTL_FORE: fore_color[caching] = cp->ctl_value; +#ifdef USE_M17N + if (! (mgp_flag & FL_NOM17N)) + { + M17N_set_color (cp->ctl_value); + break; + } +#endif XSetForeground(display, gcfore, fore_color[caching]); break; @@ -628,6 +632,13 @@ #endif /*FREETYPE*/ case CTL_XFONT2: +#ifdef USE_M17N + if (! (mgp_flag & FL_NOM17N)) + { + M17N_set_font (cp->ctc2_value1, cp->ctc2_value2); + break; + } +#endif x_registerseed(state, cp->ctc2_value1, cp->ctc2_value2); break; @@ -718,6 +729,15 @@ p = (state->tabprefix) ? state->tabprefix : state->curprefix; if (!p) break; +#ifdef USE_M17N + if (! (mgp_flag & FL_NOM17N)) + { + cp->ct_op = CTL_TEXT; + cp->ctc_value = p; + M17N_draw_string (state, cp); + break; + } +#endif draw_line_output(state, p); break; } @@ -729,6 +749,13 @@ state->align = AL_LEFTFILL1; state->leftfillpos = state->linewidth; } +#ifdef USE_M17N + if (! (mgp_flag & FL_NOM17N)) + { + M17N_draw_string (state, cp); + break; + } +#endif draw_line_output(state, cp->ctc_value); break; @@ -952,7 +979,7 @@ return x; } -static void +void draw_line_start(state) struct render_state *state; { @@ -1003,17 +1030,10 @@ struct render_state *state; char *data; { -#ifdef USE_M17N - if (mgp_flag & FL_NOM17N) - draw_string(state, data); - else - M17N_draw_string(state, data); -#else draw_string(state, data); -#endif } -static void +void draw_line_end(state) struct render_state *state; { @@ -1313,12 +1333,6 @@ enum { MODE_UNKNOWN, MODE_X, MODE_VFLIB, MODE_FREETYPE } mode = MODE_UNKNOWN; char *p0; -#ifdef USE_M17N - if (!(mgp_flag & FL_NOM17N)){ - p0 = M17N_draw_fragment(state, p, len); - if (p0) return p0; - } -#endif #ifdef USE_XFT2 if (!(mgp_flag & FL_NOXFT)){ p0 = xft_draw_fragment(state, p, len, registry, charset16); @@ -4922,10 +4936,11 @@ } #endif #ifdef USE_M17N -obj_new_mtext(state, x, y, mt, drawframe, ascent, descent) +obj_new_mtext(state, x, y, mt, from, to, drawframe, ascent, descent) struct render_state *state; int x, y; MText *mt; + int from, to; MFrame *drawframe; int ascent, descent; { @@ -4941,8 +4956,10 @@ obj->descent = descent; obj->vertloc = VL_BASE; obj->data.m17ntext.mt = mt; + m17n_object_ref (mt); obj->data.m17ntext.drawframe = drawframe; - obj->data.m17ntext.len = mtext_len(mt); + obj->data.m17ntext.from = from; + obj->data.m17ntext.to = to; return 1; } #endif diff -Nru mgp-1.11b-2/m17n.c mgp-1.11b/m17n.c --- mgp-1.11b-2/m17n.c 2005-04-20 01:31:16.000000000 +0900 +++ mgp-1.11b/m17n.c 2005-05-14 01:18:15.000000000 +0900 @@ -1,5 +1,8 @@ /* * Copyright (C) 1997 and 1998 WIDE Project. All rights reserved. + * Copyright (C) 2005 + * National Institute of Advanced Industrial Science and Technology (AIST) + * Registration Number H16PRO276 * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -31,32 +34,48 @@ #ifdef USE_M17N #include "mgp.h" -#define M17N_MAX_CACHE 100 -static void M17N_format_line(); +#ifdef HAVE_FONTCONFIG_FONTCONFIG_H +/* This is to parse Xft font name pattern. */ +#include <fontconfig/fontconfig.h> +#endif + +/* Prototypes for internal functions. They start with "M17N__". */ + +static int M17N__line_break __P ((MText *, int, int, int ,int, int)); +static void M17N__format_line __P ((int, int, int *, int *)); +static MText *M17N__gen_mtext __P ((u_char *)); +static void M17N__define_font __P ((struct ctrl *)); +static MFont *M17N__get_font __P ((char *, char *, int)); + +/* The following two variables are set by M17N_draw_string and + referred by M17N__format_line (). */ + +/* Width remaining for the first line of a drawning text. */ +static int first_width; +/* Width of the currently drawing area. */ +static int area_width; static MDrawControl control; -static MText *mt; -static MFace *face_size; -static MFace *face_color; -static MFace *face_other; -static MSymbol lang; +static MFontset *fontset; +static MFace *faces[2]; +static MSymbol languages[2]; /* M-text containing a single space. It is used to get normal ascent/descent of an ASCII font selected for the current set of faces. */ static MText *space; -static struct render_state *current_state; -static int current_linewidth; -static int current_indent; + +static MSymbol Miso8859_1, Municode_bmp, Mjisx0208, Mgb2312, Mksc5601; +static MSymbol Mlatin, Mhan, Mhangul, Mkatakana, Mhiragana; static int kinsoku_range [][2] = { - 0x3041, 0x30FF, /* Kana */ - 0x2E80, 0x2FDF, /* radical */ - 0x3400, 0x4DB5, /* CJK Ideograph Extention A */ - 0x4E00, 0x9FAF, /* CJK Ideograph */ - 0XF900, 0xFAFF, /* CJK COMPATIBILITY IDEOGRAPH */ - 0X20000, 0x2A6D6, /* CJK Ideograph Extention B */ - 0x2F800, 0x2FA1D /* CJK COMPATIBILITY IDEOGRAPH */ + {0x3041, 0x30FF}, /* Kana */ + {0x2E80, 0x2FDF}, /* radical */ + {0x3400, 0x4DB5}, /* CJK Ideograph Extention A */ + {0x4E00, 0x9FAF}, /* CJK Ideograph */ + {0XF900, 0xFAFF}, /* CJK COMPATIBILITY IDEOGRAPH */ + {0X20000, 0x2A6D6}, /* CJK Ideograph Extention B */ + {0x2F800, 0x2FA1D} /* CJK COMPATIBILITY IDEOGRAPH */ }; static int kinsoku_list [] = { @@ -76,8 +95,10 @@ static MCharTable *kinsoku_table; static MSymbol Mkinsoku; +/* Find a linebreak position. Set in control.line_break */ + static int -m17n_line_break (mt, pos, from, to, line, y) +M17N__line_break (mt, pos, from, to, line, y) MText *mt; int pos, from, to; int line, y; @@ -96,70 +117,47 @@ return pos; } -void -M17N_init() -{ - int i; - M17N_INIT(); +/* Decide the width and indentation of the LINEth line. Set in + control.format. */ - space = mtext_from_data (" ", 1, MTEXT_FORMAT_US_ASCII); -#if 0 - face_other = mface (); - // default fontset is not truetype -// mface_put_prop (face_other, Mfontset, mfontset ("truetype")); - mface_put_prop (face_other, Mfontset, mfontset ("default")); -#endif - memset (&control, 0, sizeof control); - control.two_dimensional = 1; - control.enable_bidi = 1; - control.ignore_formatting_char = 1; - control.disable_caching = 0; - control.max_line_width = 0; - control.anti_alias = 1; - control.format = M17N_format_line; -// control.line_break = mdraw_default_line_break; - control.line_break = m17n_line_break; - - /* Generate kinsoku_char_table. */ - Mkinsoku = msymbol ("kinsoku"); - kinsoku_table = mchartable (Msymbol, Mnil); - for (i = 0; i < (sizeof(kinsoku_range) / sizeof(kinsoku_range[0])); i++) - mchartable_set_range (kinsoku_table, kinsoku_range[i][0], - kinsoku_range[i][1], Mt); - for (i = 0; i < (sizeof kinsoku_list / sizeof (int)); i++) - mchartable_set (kinsoku_table, kinsoku_list[i], Mkinsoku); +static void +M17N__format_line(line, y, indent, width) + int line, y, *indent, *width; +{ + *width = line == 0 ? first_width : area_width; + *indent = 0; } -#define MAXCACHEDMTEXT 40 -MText * -M17N_gen_mtext (p) +/* Return an M-text generated from the byte sequence at P. */ + +static MText * +M17N__gen_mtext (p) u_char *p; { - static MText *cached_mt[MAXCACHEDMTEXT]; - static u_char *cached_txt[MAXCACHEDMTEXT][BUFSIZ]; - static int cached_txt_len[MAXCACHEDMTEXT]; - static int cached_count; MSymbol coding; MText *mt = 0; - int i, len = strlen (p); + int i, len = strlen ((char *) p); - if (len == 0) return; - for (i = 0; i < cached_count; i ++) - if ((len == cached_txt_len[i]) && - !memcmp((void *)p, (void *)cached_txt[i], cached_txt_len[i])){ - m17n_object_ref(cached_mt[i]); - return cached_mt[i]; - } + if (len == 0) return NULL; if (!mt && mgp_charset[0] != '\0') { coding = mconv_resolve_coding (msymbol (mgp_charset)); if (coding) mt = mconv_decode_buffer (coding, p, len); } - if (strchr (p, '\033')) { + if (strchr ((char *) p, '\033')) { /* Try ISO-2022 encoding. */ coding = mconv_resolve_coding (msymbol ("iso-2022-7bit")); if (coding) mt = mconv_decode_buffer (coding, p, len); } + if (!mt) + { + /* Check ASCII only. */ + for (i = 0; i < len; i++) + if (p[i] >= 0x80) + break; + if (i == len) + mt = mtext_from_data (p, len, MTEXT_FORMAT_US_ASCII); + } if (!mt) { /* Try UTF-8. */ coding = mconv_resolve_coding (msymbol ("utf-8")); @@ -176,285 +174,450 @@ exit(1); } - bzero(cached_txt[cached_count], BUFSIZ); - if (cached_mt[cached_count]) - m17n_object_unref(cached_mt[cached_count]); - strcpy((char *)cached_txt[cached_count], p); - cached_txt_len[cached_count] = strlen(p); - cached_mt[cached_count] = mt; - cached_count = (cached_count + 1) % MAXCACHEDMTEXT; - m17n_object_ref(mt); - return mt; } -void -M17N_set_size(size) - int size; + +/* Return a font matching SEED and REGISTRY. If no such font is found + and RECORD is nonzero, create a new font and remember it. */ + +MFont * +M17N__get_font (seed, registry, record) + char *seed; + char *registry; + int record; { - static MFace *msize[M17N_MAX_CACHE]; - static int msize_num = 0; - int i, targetsize; - int delta, mindelta, mindelta_i; - - targetsize = size * 10; - - mindelta = -1; - for (i = 0; i < msize_num; i ++){ - if (msize[i]){ - delta = abs((int)mface_get_prop(msize[i], Msize) - targetsize); - if (!delta){ - face_size = msize[i]; - return; - } else { - if (mindelta < 0){ mindelta = delta; mindelta_i = i; } - else if (mindelta > delta) { mindelta = delta; mindelta_i = i; } - } - } - } - - /* If msize_num exceeds limit, choose the closest size */ - if (msize_num == M17N_MAX_CACHE) { - face_size = msize[mindelta_i]; - return; - } - - /* create new face */ - msize[msize_num] = mface(); - mface_put_prop (msize[msize_num], Msize, (void *) targetsize); - face_size = msize[msize_num]; - msize_num ++; - return; + static MPlist *font_list; + MPlist *plist; + MSymbol sym_seed, sym_registry; + MSymbol family, weight, slant; + MFont *font; + char *p; + + if (! font_list) + font_list = mplist (); + + sym_seed = msymbol (seed); + if (strncmp (registry, "iso8859", 7) == 0) + sym_registry = msymbol (registry); + else if (strncmp (registry, "jisx0208", 8) == 0) + sym_registry = Mjisx0208; + else if (strncmp (registry, "gb2312", 6) == 0) + sym_registry = Mgb2312; + else if (strncmp (registry, "ksc5601", 7) == 0) + sym_registry = Mksc5601; + else + sym_registry = msymbol (registry); + + for (plist = mplist_find_by_key (font_list, sym_seed); plist; + plist = mplist_find_by_key (plist, sym_seed)) + { + font = mplist_value (plist); + if (mfont_get_prop (font, Mregistry) == sym_registry) + return font; + } + + if (! record) + return NULL; + + family = weight = slant = Mnil; + if ((p = strchr (seed, '-')) != NULL) + { + /* Should be XLFD of format FAMILY-WEIGHT[-SLANT] */ + char *copy = alloca (strlen (seed) + 1); + + strcpy (copy, seed); + copy[p - seed] = '\0'; + family = msymbol (copy); + copy += p + 1 - seed; + p = strchr (copy, '-'); + if (! p) + weight = msymbol (copy); + else + { + *p = 0; + weight = msymbol (copy); + slant = msymbol (p + 1); + } + } + else if (strchr (seed, ':')) + { + /* Should be Xft (i.e. Fontconfig) pattern. */ +#ifdef HAVE_FONTCONFIG_FONTCONFIG_H + FcPattern *pat = FcNameParse ((FcChar8 *) seed); + FcChar8 *p; + int i; + + if (pat) + { + if (FcPatternGetString (pat, FC_FAMILY, 0, &p) == FcResultMatch) + family = msymbol ((char *) p); + if (FcPatternGetInteger (pat, FC_WEIGHT, 0, &i) == FcResultMatch) + weight = (i < FC_WEIGHT_EXTRALIGHT ? msymbol ("ultralight") + : i < FC_WEIGHT_LIGHT ? msymbol ("extralight") + : i < FC_WEIGHT_REGULAR ? msymbol ("light") + : i < FC_WEIGHT_MEDIUM ? msymbol ("regular") + : i < FC_WEIGHT_DEMIBOLD ? msymbol ("medium") + : i < FC_WEIGHT_BOLD ? msymbol ("demibold") + : i < FC_WEIGHT_EXTRABOLD ? msymbol ("bold") + : i < FC_WEIGHT_ULTRABOLD ? msymbol ("extrabold") + : i < FC_WEIGHT_BLACK ? msymbol ("ultrabold") + : msymbol ("black")); + if (FcPatternGetInteger (pat, FC_SLANT, 0, &i) == FcResultMatch) + slant = (i < FC_SLANT_ITALIC ? msymbol ("r") + : i < FC_SLANT_OBLIQUE ? msymbol ("i") + : msymbol ("o")); + FcPatternDestroy (pat); + } + else +#endif + /* Treat the seed as family name. */ + family = msymbol (seed); + } + else + /* Treat the name as family name. */ + family = msymbol (seed); + + font = mfont (); + mfont_put_prop (font, Mfamily, family); + mfont_put_prop (font, Mweight, weight); + mfont_put_prop (font, Mstyle, slant); + mfont_put_prop (font, Mregistry, sym_registry); + mplist_push (font_list, sym_seed, font); + return font; } +/* Pre-define the font set in CP. */ + void -M17N_set_color(color) - u_long color; +M17N__define_font (cp) + struct ctrl *cp; { - static u_long mcolor_val[M17N_MAX_CACHE]; - static MFace *mcolor[M17N_MAX_CACHE]; - static int mcolor_num = 0; - int i, delta, mindelta, mindelta_i; - char color_string[20]; - XColor xcolor; - - for (i = 0; i < mcolor_num; i ++){ - delta = abs(mcolor_val[i] - color); - if (!delta){ - face_color = mcolor[i]; - return; - } else { - if (mindelta < 0){ mindelta = delta; mindelta_i = i; } - else if (mindelta > delta) { mindelta = delta; mindelta_i = i; } - } - } - - /* If mcolor_num exceeds limit, choose the closest color */ - if (mcolor_num == M17N_MAX_CACHE) { - face_color = mcolor[mindelta_i]; - return; - } - - /* create new face */ - xcolor.pixel = color; - XQueryColor(display, colormap, &xcolor); - sprintf(color_string, "#%04X%04X%04X\0", xcolor.red, xcolor.green, xcolor.blue); - mcolor[mcolor_num] = mface(); - mcolor_val[mcolor_num] = color; - mface_put_prop(mcolor[mcolor_num], Mforeground, msymbol(color_string)); - face_color = mcolor[mcolor_num]; - mcolor_num ++; - return; + MSymbol family, registry; + MPlist *plist, *pl; + MFont *font, *recorded; + + for (; cp && cp->ct_op != CTL_XFONT2; cp = cp->ct_next); + if (! cp) + return; + + recorded = M17N__get_font (cp->ctc2_value1, cp->ctc2_value2, 1); + family = mfont_get_prop (recorded, Mfamily); + registry = mfont_get_prop (recorded, Mregistry); + if (registry == Miso8859_1) + { + /* This may be a TTF, in which case, we may be able to use it + for any scripts. */ + plist = mfontset_lookup (fontset, Mt, Mnil, Mnil); + } + else + { + plist = mplist (); + if (registry == Mjisx0208 || registry == Mgb2312) + mplist_put (plist, Mhan, NULL); + else if (registry == Mksc5601) + mplist_put (plist, Mhangul, NULL); + else if (strncmp (msymbol_name (registry), "iso8859-", 8) == 0) + mplist_put (plist, Mlatin, NULL); + } + font = mfont (); + mfont_put_prop (font, Mfamily, family); + for (pl = plist; mplist_key (pl) != Mnil; pl = mplist_next (pl)) + { + MSymbol script = mplist_key (pl); + MPlist *p = mfontset_lookup (fontset, script, Mt, Mnil); + MPlist *p0; + + for (p0 = p; mplist_key (p0) != Mnil; p0 = mplist_next (p0)) + { + MSymbol lang = mplist_key (p0); + + mfont_put_prop (font, Mregistry, registry); + mfontset_modify_entry (fontset, script, lang, Mnil, font, Mnil, -1); + if (registry == Miso8859_1) + { + mfont_put_prop (font, Mregistry, Municode_bmp); + mfontset_modify_entry (fontset, script, lang, Mnil, font, + Mnil, -1); + } + } + m17n_object_unref (p); + } + m17n_object_unref (plist); + + mfont_put_prop (font, Mregistry, registry); + mfontset_modify_entry (fontset, Mnil, Mnil, Mnil, font, Mnil, -1); + if (registry == Miso8859_1) + { + mfont_put_prop (font, Mregistry, Municode_bmp); + mfontset_modify_entry (fontset, Mnil, Mnil, Mnil, font, Mnil, -1); + } } -char * -M17N_draw_fragment(state, p, len) - struct render_state *state; - u_char *p; - u_int len; + +/* Internal API (functions called from the other files) */ + +void +M17N_init() { - static MFrame *drawframe; - static MFace *drawface; - static MPlist *plist; - MFace *faces[256]; - MText *mt; - MDrawGlyphInfo info; - MDrawMetric rect; - int ascent = 0, descent = 0, i, n, flheight = 0; - char tmptext[10000]; - Bool flag_s, flag_c, flag_o; - - if (!drawface) drawface = mface(); - if (!plist){ - plist = mplist (); - mplist_add(plist, Mdisplay, display); - drawframe = mframe (plist); - } - M17N_set_size(char_size[caching]); - M17N_set_color(fore_color[caching]); - - if (len >= 10000) len = 9999; - strncpy(tmptext, p, len); - tmptext[len] = 0; - mt = M17N_gen_mtext(tmptext); - - /* check if the faces attached Mface are already cached */ - flag_s = flag_c = flag_o = True; - n = mtext_get_prop_values (mt, 0, Mface, (void **) faces, 256); - for (i = 0; i < n; i ++){ - if (faces[i] == face_size) flag_s = False; - if (faces[i] == face_color) flag_c = False; - if (faces[i] == face_other) flag_o = False; - } - - /* if faces are not cached, push them to Mface */ - if (flag_s) mtext_push_prop (mt, 0, mtext_len(mt), Mface, face_size); - if (flag_c) mtext_push_prop (mt, 0, mtext_len(mt), Mface, face_color); - if (flag_o) mtext_push_prop (mt, 0, mtext_len(mt), Mface, face_other); - if (lang) mtext_push_prop (mt, 0, mtext_len(mt), Mlanguage, lang); - - current_linewidth = state->width - state->leftfillpos / 2 - state->linewidth; - current_indent = state->leftfillpos; - - /* Compare the normal ascent/descent and the physical - ascent/descent of this M-text, and use the bigger ones. */ - mdraw_text_extents(drawframe, space, 0, 1, - &control, NULL, &rect, NULL); - ascent = - rect.y, descent = rect.height + rect.y; - mdraw_text_extents(drawframe, mt, 0, 1, &control, &rect, NULL, NULL); - flheight = rect.height + rect.y; - mdraw_text_extents(drawframe, mt, 0, mtext_len(mt), - &control, &rect, NULL, NULL); - if (ascent < - rect.y) - ascent = - rect.y; - if (descent < rect.height + rect.y) - descent = rect.height + rect.y; - if (rect.width > 0) - state->brankline = 0; + int i; + M17N_INIT(); + + space = mtext_from_data (" ", 1, MTEXT_FORMAT_US_ASCII); + fontset = mfontset ("truetype"); + memset (&control, 0, sizeof control); + control.two_dimensional = 1; + control.enable_bidi = 1; + control.ignore_formatting_char = 1; + control.disable_caching = 0; + control.max_line_width = 0; + control.anti_alias = 1; + control.format = M17N__format_line; + control.line_break = M17N__line_break; - draw_line_itemsize(state, ascent, descent, flheight); - if (obj_new_mtext(state, state->linewidth, state->charoff, mt, - drawframe, ascent, descent)){ - state->linewidth += rect.width; - return p + len; - } else - return NULL; + /* Generate kinsoku_char_table. */ + Mkinsoku = msymbol ("kinsoku"); + kinsoku_table = mchartable (Msymbol, Mnil); + for (i = 0; i < (sizeof(kinsoku_range) / sizeof(kinsoku_range[0])); i++) + mchartable_set_range (kinsoku_table, kinsoku_range[i][0], + kinsoku_range[i][1], Mt); + for (i = 0; i < (sizeof kinsoku_list / sizeof (int)); i++) + mchartable_set (kinsoku_table, kinsoku_list[i], Mkinsoku); + + Miso8859_1 = msymbol ("iso8859-1"); + Municode_bmp = msymbol ("unicode-bmp"); + Mjisx0208 = msymbol ("jisx0208.1983-0"); + Mgb2312 = msymbol ("gb2312.1980-0"); + Mksc5601 = msymbol ("ksc5601.1987-0"); + + Mlatin = msymbol ("latin"); + Mhan = msymbol ("han"); + Mhangul = msymbol ("hangul"); + Mkatakana = msymbol ("katakana"); + Mhiragana = msymbol ("hiragana"); + + for (i = 0; i < MAXFONTDEF; i++) + if (fontdef_control[i]) + M17N__define_font (fontdef_control[i]); } +/* Set font-oriented properties (family, weight, slant) of the current + face to what specified in SEED. */ + void -M17N_draw_object(obj, target, x, y) - struct render_object *obj; - Drawable target; - int x, y; +M17N_set_font (seed, registry) + char *seed; + char *registry; { - MFace *faces[256]; - int i, n; + MFont *font = M17N__get_font (seed, registry, 0); + MFace *face = faces[caching]; - mdraw_text_with_control ( - obj->data.m17ntext.drawframe, - (MDrawWindow) target, x, y, - obj->data.m17ntext.mt, 0, - obj->data.m17ntext.len, &control); + if (! font) + return; + if (! faces[caching]) + face = faces[caching] = mface (); + mface_put_prop (face, Mfamily, (MSymbol) mfont_get_prop (font, Mfamily)); + mface_put_prop (face, Mweight, mfont_get_prop (font, Mweight)); + mface_put_prop (face, Mstyle, mfont_get_prop (font, Mstyle)); +} - /* detach extra properties */ - n = mtext_get_prop_values (obj->data.m17ntext.mt, 0, Mface, (void **) faces, 256); - for (i = n; i > 3; i --){ - mtext_pop_prop (obj->data.m17ntext.mt, 0, - obj->data.m17ntext.len, Mface); - } +void +M17N_set_color (color) + u_long color; +{ + MFace *face = faces[caching]; + char color_string[20]; + XColor xcolor; + + if (! faces[caching]) + face = faces[caching] = mface (); + + xcolor.pixel = color; + XQueryColor (display, colormap, &xcolor); + sprintf (color_string, "#%04X%04X%04X", + xcolor.red, xcolor.green, xcolor.blue); + mface_put_prop (face, Mforeground, msymbol (color_string)); } +/* Calculate the extents of text pointed by CP and update STATE. */ + void -M17N_draw_string(state, data) +M17N_draw_string (state, cp) struct render_state *state; - char *data; + struct ctrl *cp; { - char *p = data; - char *registry = NULL; - int charset16 = 0; - - if (strlen(p)) - M17N_draw_fragment(state, p, strlen(p)); + MText *mt; + static MFrame *drawframe; + static MPlist *plist; + MDrawGlyphInfo info; + MDrawMetric rect_sp, rect; + int ascent = 0, descent = 0; + int nchars; + int i, c; + + if (cp->ct_flag == 0) + { + /* cp->ctc_value points a raw byte sequence. */ + mt = M17N__gen_mtext ((u_char *) cp->ctc_value); + cp->ctc_value = (char *) mt; + cp->ct_flag = 1; + } + else + { + /* cp->ctc_valus points an M-text. */ + mt = (MText *) cp->ctc_value; + } + if (! mt) + return; + + nchars = mtext_len (mt); + if (! plist) + { + plist = mplist (); + mplist_add (plist, Mdisplay, display); + drawframe = mframe (plist); + } + + if (! mtext_get_prop (mt, 0, Mface)) + { + MFace *face; + + if (! faces[caching]) + faces[caching] = mface (); + face = mface_copy (faces[caching]); + mface_put_prop (face, Msize, (void *) (char_size[caching] * 10)); + mtext_push_prop (mt, 0, nchars, Mface, face); + if (languages[caching]) + mtext_push_prop (mt, 0, nchars, Mlanguage, languages[caching]); + m17n_object_unref (face); + } + + /* Compare the normal ascent/descent and the physical ascent/descent + of this M-text, and use the bigger ones. */ + mdraw_text_extents(drawframe, space, 0, 1, &control, NULL, NULL, &rect_sp); + rect_sp.height += rect_sp.y; /* calculate descent */ + + area_width = state->width - state->leftfillpos / 2; + first_width = area_width - state->linewidth; + mdraw_glyph_info (drawframe, mt, 0, 0, &control, &info); + if (info.line_to == nchars) + { + /* All text can be drawn on the current line. */ + mdraw_text_extents (drawframe, mt, 0, nchars, &control, + NULL, NULL, &rect); + rect.height += rect.y; /* calculate descent */ + ascent = rect_sp.y < rect.y ? - rect_sp.y : - rect.y; + descent = rect_sp.height > rect.height ? rect_sp.height : rect.height; + for (i = 0; state->brankline && i < nchars; i++) + if ((c = mtext_ref_char (mt, i)) != ' ' && c != '\t') + state->brankline = 0; + draw_line_itemsize(state, ascent, descent, 0); + obj_new_mtext (state, state->linewidth, state->charoff, + mt, 0, nchars, drawframe, ascent, descent); + state->linewidth += rect.width; + } + else + { + int i, c; + MDrawGlyphInfo info2; + /* We need a line break. Check if there's a room for at least + one fragment on the current line. */ + + /* Skip the leading spaces. */ + for (i = 0; i < nchars && mtext_ref_char (mt, 0) == ' '; i++); + for (; i < nchars; i++) + { + if ((c = mtext_ref_char (mt, i)) == ' ') + break; + else if (mchartable_lookup (kinsoku_table, c) == Mt) + { + i++; + break; + } + } + mdraw_glyph_info (drawframe, mt, 0, i - 1, &control, &info2); + if (info2.line_from > 0) + { + /* No room even for one fragment. Break the line before + drawing anything. */ + draw_line_end (state); + draw_line_start (state); + state->linewidth = state->leftfillpos; + first_width = area_width; + mdraw_clear_cache (mt); + mdraw_glyph_info (drawframe, mt, 0, 0, &control, &info); + } + + while (1) + { + for (i = info.line_to; i > info.line_from; i--) + if ((c = mtext_ref_char (mt, i - 1)) != ' ' && c != '\t') + { + state->brankline = 0; + break; + } + if (i == info.line_from) + i = info.line_to; + + mdraw_text_extents (drawframe, mt, info.line_from, i, + &control, NULL, NULL, &rect); + rect.height += rect.y; /* calculate descent */ + ascent = rect_sp.y < rect.y ? - rect_sp.y : - rect.y; + descent = rect_sp.height > rect.height ? rect_sp.height : rect.height; + draw_line_itemsize (state, ascent, descent, 0); + obj_new_mtext (state, state->linewidth, state->charoff, + mt, info.line_from, i, drawframe, ascent, descent); + state->linewidth += rect.width; + if (info.line_to >= nchars) + break; + draw_line_end (state); + draw_line_start (state); + state->linewidth = state->leftfillpos; + mdraw_glyph_info (drawframe, mt, info.line_to, info.line_to, + &control, &info); + } + } } -static void -M17N_format_line(line, y, indent, width) - int line, y, *indent, *width; +/* Draw the M-text stored in OBJ on TARGET at the coordinate (X Y). */ + +void +M17N_draw_object(obj, target, x, y) + struct render_object *obj; + Drawable target; + int x, y; { - *indent = 0; // we don't need to set this. - *width = current_linewidth; + control.format = NULL; + mdraw_text_with_control ( + obj->data.m17ntext.drawframe, + (MDrawWindow) target, x, y, + obj->data.m17ntext.mt, + obj->data.m17ntext.from, obj->data.m17ntext.to, &control); + control.format = M17N__format_line; } -#define M17NMAXKEY 3 -#define M17NMAXVAL 128 +/* Update faces[caching] or languages[caching] according to KEY and + VALUE. */ + void M17N_process_direc(key, value) char *key, *value; { - static u_char *mfontset_val[M17N_MAX_CACHE]; - static u_char *mfamily_val[M17N_MAX_CACHE]; - static MFace *mfontset_face[M17N_MAX_CACHE]; - static MFace *mfamily_face[M17N_MAX_CACHE]; - static int mfontset_num = 0; - static int mfamily_num = 0; - static MFace *last_used; + MSymbol key_sym = msymbol (key); + MFace *face = faces[caching]; - char *keywords[M17NMAXKEY] = {"fontset", "family", "language"}; - int i; + if (! faces[caching]) + face = faces[caching] = mface (); - for (i = 0; i < M17NMAXKEY; i ++) { - if (!strcmp(key, keywords[i])) { - break; - } - } - switch(i){ - case 0: - for (i = 0; i < mfontset_num; i ++){ - if (strlen(mfontset_val[i]) == strlen(value) && - !(strcmp(mfontset_val[i], value))){ - face_other = mfontset_face[i]; - goto done; - } - } - if (mfontset_num == M17N_MAX_CACHE){ - face_other = mfontset_face[0]; // adhoc - goto done; - } - mfontset_face[mfontset_num] = mface(); - mface_put_prop (mfontset_face[mfontset_num], Mfontset, mfontset (value)); - face_other = mfontset_face[mfontset_num]; - mfontset_val[mfontset_num] = strdup(value); - mfontset_num ++; - goto done; - break; - case 1: - for (i = 0; i < mfamily_num; i ++){ - if (strlen(mfamily_val[i]) == strlen(value) && - !(strcmp(mfamily_val[i], value))){ - face_other = mfamily_face[i]; - goto done; - } - } - if (mfamily_num == M17N_MAX_CACHE){ - face_other = mfamily_face[0]; // adhoc - goto done; - } - mfamily_face[mfamily_num] = mface(); - mface_put_prop (mfamily_face[mfamily_num], Mfamily, msymbol (value)); - face_other = mfamily_face[mfamily_num]; - mfamily_val[mfamily_num] = strdup(value); - mfamily_num ++; - goto done; - break; - case 2: - lang = msymbol(value); - break; - default: - fprintf(stderr, "unknown keyword:%s for m17n-lib\n", key); - } -done: - last_used = face_other; - return; + if (key_sym == Mfoundry || key_sym == Mfamily || key_sym == Mweight + || key_sym == Mstyle || key_sym == Mstretch || key_sym == Madstyle) + mface_put_prop (face, key_sym, value ? msymbol (value) : Mnil); + else if (key_sym == Mfontset) + mface_put_prop (face, key_sym, value ? mfontset (value) : fontset); + else if (key_sym == Mratio) + mface_put_prop (face, key_sym, value ? (void *) atoi (value) : (void *) 1); + else if (key_sym == Mlanguage) + languages[caching] = value ? msymbol (value) : Mnil; } #endif diff -Nru mgp-1.11b-2/mgp.h mgp-1.11b/mgp.h --- mgp-1.11b-2/mgp.h 2004-09-08 01:57:42.000000000 +0900 +++ mgp-1.11b/mgp.h 2005-05-14 01:18:15.000000000 +0900 @@ -531,7 +531,7 @@ struct { MText *mt; MFrame *drawframe; - int len; + int from, to; } m17ntext; #endif } data; @@ -735,6 +735,14 @@ extern void timebar __P((struct render_state *)); extern void draw_reinit __P((struct render_state *)); extern int get_regid __P((char *)); +extern void draw_line_itemsize __P((struct render_state *, int, int, int)); +extern void draw_line_start __P((struct render_state *)); +extern void draw_line_end __P ((struct render_state *)); + +#ifdef USE_M17N +extern int obj_new_mtext __P((struct render_state *, int, int, + MText *, int, int, MFrame *, int, int)); +#endif /*parse.c*/ extern void load_file __P((char *)); @@ -829,12 +837,11 @@ #endif #ifdef USE_M17N -void M17N_init __P((void)); -void M17N_set_size __P((int)); -void M17N_set_color __P((u_long)); -MText * M17N_gen_mtext __P((u_char *)); -void M17N_process_direc __P((char *, char *)); -void M17N_draw_string __P((struct render_state *, char *)); -char * M17N_draw_fragment __P((struct render_state *, u_char *, u_int)); -void M17N_draw_object __P((struct render_object *, Drawable, int, int)); +/*m17n.c*/ +extern void M17N_init __P((void)); +extern void M17N_set_font __P((char *, char *)); +extern void M17N_set_color __P((u_long)); +extern void M17N_process_direc __P((char *, char *)); +extern void M17N_draw_string __P((struct render_state *, struct ctrl *cp)); +extern void M17N_draw_object __P((struct render_object *, Drawable, int, int)); #endif diff -Nru mgp-1.11b-2/parse.c mgp-1.11b/parse.c --- mgp-1.11b-2/parse.c 2005-04-01 12:06:36.000000000 +0900 +++ mgp-1.11b/parse.c 2005-05-14 01:32:21.000000000 +0900 @@ -979,23 +979,27 @@ tmpstr[5]->ctc2_value1 = strdup("k14"); tmpstr[5]->ctc2_value2 = strdup("jisx0208.1983-*"); #ifdef USE_M17N - tmpstr[6] = ctlalloc1(CTL_M17N); - tmpstr[6]->ctc2_value1 = strdup("fontset"); - tmpstr[6]->ctc2_value2 = strdup("default"); - tmpstr[7] = ctlalloc1(CTL_M17N); - tmpstr[7]->ctc2_value1 = strdup("family"); - tmpstr[7]->ctc2_value2 = strdup("default"); - tmpstr[8] = ctlalloc1(CTL_M17N); - tmpstr[8]->ctc2_value1 = strdup("language"); - tmpstr[8]->ctc2_value2 = strdup("default"); -#else - tmpstr[6] = ctlalloc1(CTL_NOOP); - tmpstr[6]->ctc_value = strdup(""); - tmpstr[7] = ctlalloc1(CTL_NOOP); - tmpstr[7]->ctc_value = strdup(""); - tmpstr[8] = ctlalloc1(CTL_NOOP); - tmpstr[8]->ctc_value = strdup(""); + if (! (mgp_flag & FL_NOM17N)) { + tmpstr[6] = ctlalloc1(CTL_M17N); + tmpstr[6]->ctc2_value1 = strdup("fontset"); + tmpstr[6]->ctc2_value2 = strdup("default"); + tmpstr[7] = ctlalloc1(CTL_M17N); + tmpstr[7]->ctc2_value1 = strdup("family"); + tmpstr[7]->ctc2_value2 = strdup("default"); + tmpstr[8] = ctlalloc1(CTL_M17N); + tmpstr[8]->ctc2_value1 = strdup("language"); + tmpstr[8]->ctc2_value2 = strdup("default"); + } else #endif + { + tmpstr[6] = ctlalloc1(CTL_NOOP); + tmpstr[6]->ctc_value = strdup(""); + tmpstr[7] = ctlalloc1(CTL_NOOP); + tmpstr[7]->ctc_value = strdup(""); + tmpstr[8] = ctlalloc1(CTL_NOOP); + tmpstr[8]->ctc_value = strdup(""); + } + tmplong[0] = ctlalloc1(CTL_FORE); get_color(DEFAULT_FORE, &tmplong[0]->ctl_value); tmplong[1] = ctlalloc1(CTL_BACK);
Attachment:
pgpZfZ75hFRMC.pgp
Description: PGP signature