X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Fdraw.c;h=f5b23cf2fb1302c9081604e7ee9457a504c7650c;hb=15a6499fb848caba6a48d2051f868d0844fbc88e;hp=67079db2e6ca4c59fe1aa631226392a3f19c0956;hpb=a68edcaa81c84247897506f8a0f554733397ba56;p=m17n%2Fm17n-lib.git diff --git a/src/draw.c b/src/draw.c index 67079db..f5b23cf 100644 --- a/src/draw.c +++ b/src/draw.c @@ -1,5 +1,5 @@ /* draw.c -- drawing module. - Copyright (C) 2003, 2004 + Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 National Institute of Advanced Industrial Science and Technology (AIST) Registration Number H15PRO112 @@ -17,7 +17,7 @@ You should have received a copy of the GNU Lesser General Public License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 02111-1307, USA. */ /***en @@ -67,6 +67,7 @@ #include "mtext.h" #include "textprop.h" #include "internal-gui.h" +#include "internal-flt.h" #include "face.h" #include "font.h" @@ -80,7 +81,7 @@ static MSymbol M_glyph_string; /* Special scripts */ -static MSymbol Minherited, Mcommon; +static MSymbol Mcommon; /* Special categories */ static MSymbol McatCc, McatCf; @@ -97,25 +98,26 @@ static MSymbol MbidiRLE; static MSymbol MbidiRLO; static MSymbol MbidiBN; static MSymbol MbidiS; +static MSymbol MbidiNSM; -static void -visual_order (MGlyphString *gstring) +static int +analyse_bidi_level (MGlyphString *gstring) { int len = gstring->used - 2; - MGlyph *glyphs; int bidi_sensitive = gstring->control.orientation_reversed; + int max_level; MGlyph *g; int i; #ifdef HAVE_FRIBIDI FriBidiCharType base = bidi_sensitive ? FRIBIDI_TYPE_RTL : FRIBIDI_TYPE_LTR; FriBidiChar *logical = alloca (sizeof (FriBidiChar) * len); - FriBidiChar *visual; - FriBidiStrIndex *indices; FriBidiLevel *levels; + FriBidiStrIndex *indices; #else /* not HAVE_FRIBIDI */ int *logical = alloca (sizeof (int) * len); - int *indices; char *levels = alloca (len); + + memset (levels, 0, sizeof (int) * len); #endif /* not HAVE_FRIBIDI */ for (g = MGLYPH (1), i = 0; g->type != GLYPH_ANCHOR; g++, i++) @@ -126,7 +128,7 @@ visual_order (MGlyphString *gstring) #endif /* not HAVE_FRIBIDI */ ) { - MSymbol bidi = (MSymbol) mchar_get_prop (g->c, Mbidi_category); + MSymbol bidi = (MSymbol) mchar_get_prop (g->g.c, Mbidi_category); if (bidi == MbidiR || bidi == MbidiAL || bidi == MbidiRLE || bidi == MbidiRLO) @@ -136,94 +138,183 @@ visual_order (MGlyphString *gstring) levels[i] = 1; #endif /* not HAVE_FRIBIDI */ } +#ifndef HAVE_FRIBIDI + else if (bidi == MbidiNSM && i > 0 && levels[i - 1]) + levels[i] = 1; +#endif /* not HAVE_FRIBIDI */ } - logical[i] = g->c; + logical[i] = g->g.c; } if (! bidi_sensitive) - return; + return 0; - glyphs = alloca (sizeof (MGlyph) * len); - memcpy (glyphs, gstring->glyphs + 1, sizeof (MGlyph) * len); #ifdef HAVE_FRIBIDI - visual = alloca (sizeof (FriBidiChar) * (len + 1)); - indices = alloca (sizeof (FriBidiStrIndex) * (len + 1)); levels = alloca (sizeof (FriBidiLevel) * (len + 1)); + indices = alloca (sizeof (FriBidiStrIndex) * (len + 1)); - fribidi_log2vis (logical, len, &base, visual, indices, NULL, levels); -#else /* not HAVE_FRIBIDI */ - indices = alloca (sizeof (int) * len); - for (i = 0; i < len; i++) + fribidi_log2vis (logical, len, &base, NULL, NULL, indices, levels); +#endif /* not HAVE_FRIBIDI */ + + MGLYPH (0)->bidi_level = 0; + max_level = 0; + for (g = MGLYPH (1), i = 0; i < len; g++, i++) { - if (levels[i]) + g->bidi_level = levels[i]; + if (max_level < g->bidi_level) + max_level = g->bidi_level; + } + MGLYPH (i)->bidi_level = 0; + return max_level; +} + +static void +visual_order (MGlyphString *gstring) +{ + MGlyph *glyphs = alloca (sizeof (MGlyph) * gstring->used); + int i, j, gidx; + + memcpy (glyphs, gstring->glyphs, sizeof (MGlyph) * gstring->used); + + for (i = gidx = 0; i < gstring->used - 1; gidx++) + { + int level = glyphs[i].bidi_level; + + gstring->glyphs[gidx] = glyphs[i]; + glyphs[i].rface = NULL; + + if (level % 2) { - int j, k; + int prev_level = glyphs[i - 1].bidi_level; - for (j = i + 1; j < len && levels[j]; j++); - for (k = j--; i < k; i++, j--) - indices[i] = j; - i--; + if (prev_level == level) + i--; + else if (prev_level > level) + { + for (; glyphs[i - 1].bidi_level > level; i--); + if (glyphs[i].bidi_level % 2) + for (level = glyphs[i].bidi_level; + glyphs[i + 1].bidi_level == level; i++); + } + else + for (i++; ! glyphs[i].rface; i++); } else - indices[i] = i; - } -#endif /* not HAVE_FRIBIDI */ + { + int next_level = glyphs[i + 1].bidi_level; - for (i = 0; i < len;) - { - /* Index into gstring->glyphs plus 1 for GLYPHS[i]. */ - int j = indices[i]; - /* Length of grapheme-cluster */ - int seglen; + if (next_level == level) + i++; + else if (next_level > level) + { + for (; glyphs[i + 1].bidi_level > level; i++); + if ((glyphs[i].bidi_level % 2) == 0) + for (level = glyphs[i].bidi_level; + glyphs[i - 1].bidi_level == level; i--); + } + else + { + int save = i + 1; - g = glyphs + i; -#ifdef HAVE_FRIBIDI - if (visual[j] != logical[i]) - { - /* Mirrored. */ - g->c = visual[j]; - if (g->rface->rfont) - g->code = mfont__encode_char (NULL, (MFont *) g->rface->rfont, - NULL, g->c); + for (i--; glyphs[i].bidi_level >= level; i--); + if (! glyphs[i].rface) + for (i = save; ! glyphs[i].rface; i++); + } } -#endif /* HAVE_FRIBIDI */ - g->bidi_level = levels[i]; - for (seglen = 1, g++; - i + seglen < len && (glyphs[i].pos == glyphs[i + seglen].pos - || glyphs[i + seglen].combining_code); - seglen++, g++) + } + for (i = 1; i < gstring->used - 1; i++) + { + MGlyph *g = gstring->glyphs + i; + + for (j = i; g->g.from == gstring->glyphs[j + 1].g.from; j++); + if (j > i) { - g->bidi_level = levels[i]; - if (indices[i + seglen] < j) - j = indices[i + seglen]; + memcpy (glyphs + i, gstring->glyphs + i, + sizeof (MGlyph) * (j - i + 1)); + for (; i <= j; i++) + g[j - i] = glyphs[i]; + i--; } - memcpy (MGLYPH (j + 1), glyphs + i, sizeof (MGlyph) * seglen); - i += seglen; } } -static void -reorder_combining_chars (MGlyphString *gstring, int from, int to) +static MSymbol +font_id (MFLTFont *font) { - MGlyph *g, *gbeg = MGLYPH (from + 1), *gend = MGLYPH (to), temp; - int reordered = 1; - - while (reordered) + return ((MFLTFontForRealized *) font)->rfont->id; +} + +static int +run_flt (MGlyphString *gstring, int from, int to, MRealizedFace *rface) +{ + MRealizedFont *rfont = rface->rfont; + MSymbol layouter = rface->layouter; + MFLTGlyphString flt_gstr; + MFLTFontForRealized font; + MFLT *flt; + int from_pos = MGLYPH (from)->g.from; + int len = to - from; + int catcode; + int i; + + flt = mflt_get (layouter); + flt_gstr.glyph_size = sizeof (MGlyph); + flt_gstr.glyphs = (MFLTGlyph *) (gstring->glyphs); + flt_gstr.used = gstring->used; + flt_gstr.allocated = gstring->size; + flt_gstr.r2l = 0; + font.font.family = mfont_get_prop (rfont->font, Mfamily); + font.font.x_ppem = rfont->x_ppem; + font.font.y_ppem = rfont->y_ppem; + font.font.get_glyph_id = mfont__get_glyph_id; + font.font.get_metrics = mfont__get_metrics; + font.font.check_otf = rfont->driver->check_otf; + font.font.drive_otf = rfont->driver->drive_otf; + font.font.internal = NULL; + font.rfont = rfont; + mflt_font_id = font_id; + mflt_iterate_otf_feature = rfont->driver->iterate_otf_feature; + mflt_try_otf = rfont->driver->try_otf; + for (i = 0; i < 3; i++) { - reordered = 0; - for (g = gbeg; g != gend; g++) - if (COMBINING_CODE_CLASS (g->combining_code) > 0 - && (COMBINING_CODE_CLASS (g[-1].combining_code) - > COMBINING_CODE_CLASS (g->combining_code))) - { - reordered = 1; - temp = *g; - *g = g[-1]; - g[-1] = temp; - } + to = mflt_run (&flt_gstr, from, to, &font.font, flt); + if (to != -2) + break; + APPEND_GLYPH (gstring, *MGLYPH (0)); + APPEND_GLYPH (gstring, *MGLYPH (0)); + gstring->used -= 2; } -} + if (from + len != to) + gstring->used += to - (from + len); + for (i = from, catcode = -1; i < to; i++) + { + MGlyph *g = MGLYPH (i); + + g->g.from += from_pos - from; + g->g.to += from_pos - from + 1; + g->g.xadv >>= 6; + g->g.yadv >>= 6; + g->g.ascent >>= 6; + g->g.descent >>= 6; + g->g.lbearing >>= 6; + g->g.rbearing >>= 6; + g->g.xoff >>= 6; + g->g.yoff >>= 6; + g->rface = rface; + if (catcode < 0 || g->g.from != g[-1].g.from) + { + MSymbol category = mchar_get_prop (g->g.c, Mcategory); + catcode = (category == McatCf + ? GLYPH_CATEGORY_FORMATTER + : category != Mnil && MSYMBOL_NAME (category)[0] == 'M' + ? GLYPH_CATEGORY_MODIFIER + : GLYPH_CATEGORY_NORMAL); + } + g->category = catcode; + } + return to; +} /** Scan M-text MT from FROM to TO, and compose glyphs in GSTRING for displaying them on FRAME. @@ -245,6 +336,7 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to, MRealizedFace *rface = default_rface; MRealizedFont *rfont; int size = gstring->control.fixed_width; + int max_bidi_level = 0; int i; MLIST_RESET (gstring); @@ -256,7 +348,7 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to, /** Put anchor glyphs at the head and tail. */ g_tmp.type = GLYPH_ANCHOR; - g_tmp.pos = g_tmp.to = from; + g_tmp.g.from = g_tmp.g.to = from; APPEND_GLYPH (gstring, g_tmp); stop = face_change = font_change = pos = from; while (1) @@ -311,9 +403,9 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to, c = '\n'; g_tmp.type = (c == ' ' || c == '\n' || c == '\t') ? GLYPH_SPACE : GLYPH_CHAR; - g_tmp.c = c; - g_tmp.pos = pos++; - g_tmp.to = pos; + g_tmp.g.c = c; + g_tmp.g.from = pos++; + g_tmp.g.to = pos; g_tmp.rface = rface; category = mchar_get_prop (c, Mcategory); if (category == McatCf) @@ -328,8 +420,8 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to, MGlyph ctrl[2]; ctrl[0] = ctrl[1] = g_tmp; - ctrl[0].c = '^'; - ctrl[1].c = c < ' ' ? c + 0x40 : '?'; + ctrl[0].g.c = '^'; + ctrl[1].g.c = c < ' ' ? c + 0x40 : '?'; APPEND_GLYPH (gstring, ctrl[0]); APPEND_GLYPH (gstring, ctrl[1]); } @@ -341,17 +433,20 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to, /* Append an anchor glyph. */ INIT_GLYPH (g_tmp); g_tmp.type = GLYPH_ANCHOR; - g_tmp.pos = g_tmp.to = pos; + g_tmp.g.from = g_tmp.g.to = pos; APPEND_GLYPH (gstring, g_tmp); gstring->to = pos; + if (gstring->control.enable_bidi) + max_bidi_level = analyse_bidi_level (gstring); + /* The next loop is to change each member for non-ASCII characters if necessary. */ stop = charset_change = language_change = from; rfont = default_rface->rfont; for (last_g = g = MGLYPH (1); g->type != GLYPH_ANCHOR; g++) { - int c = g->c; + int c = g->g.c; MSymbol this_script; if (c < 0x100) @@ -361,8 +456,16 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to, { this_script = (MSymbol) mchar_get_prop (c, Mscript); if (this_script == Minherited || this_script == Mcommon) - this_script = script; - if (this_script == Mcommon) + { + if (g > MGLYPH (1)) + { + MSymbol category = mchar_get_prop (g[-1].g.c, Mcategory); + + if (category != Mnil && MSYMBOL_NAME (category)[0] != 'Z') + this_script = script; + } + } + if (this_script == Mcommon && non_latin_script) this_script = non_latin_script; if (this_script == Mcommon) { @@ -372,17 +475,19 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to, MGlyph *g1; for (g1 = g + 1; g1->type != GLYPH_ANCHOR; g1++) - if (g1->c >= 0x100 - && (sym = mchar_get_prop (g1->c, Mscript)) != Mcommon + if (g1->g.c >= 0x100 + && (sym = mchar_get_prop (g1->g.c, Mscript)) != Mcommon && sym != Minherited) { this_script = sym; break; } } + if (this_script == Minherited || this_script == Mcommon) + this_script = (MSymbol) mchar_get_prop (c, Mblock); } - pos = g->pos; + pos = g->g.from; if (pos == stop || script != this_script || g->rface->rfont != rfont) { while (last_g < g) @@ -429,59 +534,47 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to, if (this->rface->layouter != Mnil) { - MGlyph *prev; - unsigned code; - - for (prev = MGLYPH (start - 1); - (prev->type == GLYPH_CHAR - && prev->category == GLYPH_CATEGORY_FORMATTER - && (code = mfont__encode_char (NULL, - (MFont *) this->rface->rfont, - NULL, prev->c) - != MCHAR_INVALID_CODE)); - start--, prev--) - if (prev->rface->rfont != this->rface->rfont) - { - prev->rface->rfont = this->rface->rfont; - prev->code = code; - } + MGlyph *prev = MGLYPH (start - 1); + + while (prev->type == GLYPH_CHAR + && prev->category == GLYPH_CATEGORY_FORMATTER + && (mfont__encode_char (NULL, (MFont *) this->rface->rfont, + NULL, prev->g.c) + != MCHAR_INVALID_CODE)) + { + prev->rface->rfont = this->rface->rfont; + start--, prev--; + } for (g++; (g->type == GLYPH_CHAR && g->rface->layouter == this->rface->layouter && (g->rface->rfont == this->rface->rfont || (g->category == GLYPH_CATEGORY_FORMATTER - && ((code = mfont__encode_char (NULL, - (MFont *) this->rface->rfont, - NULL, - g->c)) + && (mfont__encode_char (NULL, + (MFont *) this->rface->rfont, + NULL, g->g.c) != MCHAR_INVALID_CODE)))); i++, g++) - if (g->rface->rfont != this->rface->rfont) - { - g->rface->rfont = this->rface->rfont; - g->code = code; - } - i = mfont__flt_run (gstring, start, i, this->rface); + g->rface->rfont = this->rface->rfont; + i = run_flt (gstring, start, i, this->rface); } else { - while (this->type == GLYPH_CHAR - && this->c >= 0x100 - && this->category == GLYPH_CATEGORY_MODIFIER - && this->rface->rfont - && this->rface->rfont->layouter == Mnil) + g++; + while (g->type == GLYPH_CHAR + && g->g.c >= 0x100 + && g->category == GLYPH_CATEGORY_MODIFIER + && g->rface->rfont + && g->rface->layouter == Mnil) + i++, g++; + if (start + 1 < i) { - int class = (int) mchar_get_prop (this->c, - Mcombining_class); - this->combining_code - = MAKE_COMBINING_CODE_BY_CLASS (class); - i++, this++; + this->rface->layouter = Mcombining; + run_flt (gstring, start, i, this->rface); } - if (start + 1 < i) - reorder_combining_chars (gstring, start, i); - if (this->type == GLYPH_ANCHOR) - break; + else + mfont__get_metric (gstring, start, i); } g = MGLYPH (i); } @@ -490,62 +583,10 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to, } /* At last, reorder glyphs visually if necessary. */ - if (gstring->control.enable_bidi) + if (max_bidi_level > 0) visual_order (gstring); } - -static int -combining_code_from_class (int class) -{ - int code; - - if (class < 200) - code = MAKE_COMBINING_CODE (3, 1, 3, 1, 128, 128); - else if (class == 200) /* below left attached */ - code = MAKE_COMBINING_CODE (2, 0, 0, 1, 128, 128); - else if (class == 202) /* below attached*/ - code = MAKE_COMBINING_CODE (2, 1, 0, 1, 128, 128); - else if (class == 204) /* below right attached */ - code = MAKE_COMBINING_CODE (2, 2, 0, 1, 128, 128); - else if (class == 208) /* left attached */ - code = MAKE_COMBINING_CODE (3, 0, 3, 2, 128, 128); - else if (class == 210) /* right attached */ - code = MAKE_COMBINING_CODE (3, 2, 3, 0, 128, 128); - else if (class == 212) /* above left attached */ - code = MAKE_COMBINING_CODE (0, 0, 2, 1, 128, 128); - else if (class == 214) /* above attached */ - code = MAKE_COMBINING_CODE (0, 1, 2, 1, 128, 128); - else if (class == 216) /* above right attached */ - code = MAKE_COMBINING_CODE (0, 2, 2, 1, 128, 128); - else if (class == 218) /* below left */ - code = MAKE_COMBINING_CODE (2, 0, 0, 1, 122, 128); - else if (class == 220) /* below */ - code = MAKE_COMBINING_CODE (2, 1, 0, 1, 122, 128); - else if (class == 222) /* below right */ - code = MAKE_COMBINING_CODE (2, 2, 0, 1, 122, 128); - else if (class == 224) /* left */ - code = MAKE_COMBINING_CODE (3, 0, 3, 2, 128, 122); - else if (class == 226) /* right */ - code = MAKE_COMBINING_CODE (3, 2, 3, 0, 128, 133); - else if (class == 228) /* above left */ - code = MAKE_COMBINING_CODE (0, 0, 2, 1, 133, 128); - else if (class == 230) /* above */ - code = MAKE_COMBINING_CODE (0, 1, 2, 1, 133, 128); - else if (class == 232) /* above right */ - code = MAKE_COMBINING_CODE (0, 2, 2, 1, 133, 128); - else if (class == 233) /* double below */ - code = MAKE_COMBINING_CODE (2, 2, 0, 2, 122, 128); - else if (class == 234) /* double above */ - code = MAKE_COMBINING_CODE (0, 2, 2, 2, 133, 128); - else if (class == 240) /* iota subscript */ - code = MAKE_COMBINING_CODE (2, 1, 0, 1, 122, 128); - else /* unknown */ - code = MAKE_COMBINING_CODE (3, 1, 3, 1, 128, 128); - return code; -} - - typedef struct { int width, lbearing, rbearing; } MSubTextExtents; @@ -557,181 +598,20 @@ layout_glyphs (MFrame *frame, MGlyphString *gstring, int from, int to, int g_physical_ascent, g_physical_descent; MGlyph *g = MGLYPH (from); MGlyph *last_g = MGLYPH (to); - int i; g_physical_ascent = gstring->physical_ascent; g_physical_descent = gstring->physical_descent; extents->width = extents->lbearing = extents->rbearing = 0; - for (i = from; i < to;) - { - if ( MGLYPH (i)->otf_encoded) - i++; - else - { - int j = i++; - - while (i < to && ! MGLYPH (i)->otf_encoded) i++; - mfont__get_metric (gstring, j, i); - } - } - - g = MGLYPH (from); - while (g < last_g) + for (g = MGLYPH (from); g < last_g; g++) { - MGlyph *base = g++; - MRealizedFont *rfont = base->rface->rfont; - int size = rfont->spec.size; - int width, lbearing, rbearing; - - if (g == last_g || ! g->combining_code) - { - /* No combining. */ - if (base->width == 0 && ! base->left_padding && ! base->right_padding - && GLYPH_INDEX (base) > from) - { - MGlyph *prev = base - 1; - - if (base->pos < prev->pos) - prev->pos = base->pos; - else - base->pos = prev->pos; - if (base->to > prev->to) - prev->to = base->to; - else - base->to = prev->to; - } - - if (base->left_padding && base->lbearing < 0) - { - base->xoff = - base->lbearing; - if (base->rbearing < 0) - base->width = base->rbearing - base->lbearing; - else - base->width += base->xoff; - base->rbearing += base->xoff; - base->lbearing = 0; - } - if (base->right_padding && base->rbearing > base->width) - { - base->width = base->rbearing; - } - lbearing = base->lbearing; - rbearing = base->rbearing; - } - else - { - /* With combining glyphs. */ - int left = -base->width; - int right = 0; - int top = - base->ascent; - int bottom = base->descent; - int height = bottom - top; - int begin = base->pos; - int end = base->to; - int i; - - width = base->width; - lbearing = (base->lbearing < 0 ? base->lbearing : 0); - rbearing = base->rbearing; - - while (g != last_g && g->combining_code) - { - int combining_code = g->combining_code; - - if (begin > g->pos) - begin = g->pos; - else if (end < g->to) - end = g->to; - - if (! COMBINING_PRECOMPUTED_P (combining_code)) - { - int base_x, base_y, add_x, add_y, off_x, off_y; - - if (COMBINING_BY_CLASS_P (combining_code)) - g->combining_code = combining_code - = combining_code_from_class (COMBINING_CODE_CLASS - (combining_code)); - - rfont = g->rface->rfont; - size = rfont->spec.size; - off_x = (size * (COMBINING_CODE_OFF_X (combining_code) - 128) - / 1000); - off_y = (size * (COMBINING_CODE_OFF_Y (combining_code) - 128) - / 1000); - base_x = COMBINING_CODE_BASE_X (combining_code); - base_y = COMBINING_CODE_BASE_Y (combining_code); - add_x = COMBINING_CODE_ADD_X (combining_code); - add_y = COMBINING_CODE_ADD_Y (combining_code); - - g->xoff = left + (width * base_x - g->width * add_x) / 2 + off_x; - if (g->xoff < left) - left = g->xoff; - if (g->xoff + g->width > right) - right = g->xoff + g->width; - width = right - left; - - if (base_y < 3) - g->yoff = top + height * base_y / 2; - else - g->yoff = 0; - if (add_y < 3) - g->yoff -= (g->ascent + g->descent) * add_y / 2 - g->ascent; - g->yoff -= off_y; - } - - if (g->xoff + g->lbearing < left + lbearing) - lbearing = g->xoff + g->lbearing - left; - if (g->xoff + g->rbearing > left + rbearing) - rbearing = g->xoff + g->rbearing - left; - if (g->yoff - g->ascent < top) - top = g->yoff - g->ascent; - if (g->yoff + g->descent > bottom) - bottom = g->yoff + g->descent; - height = bottom - top; - - g->width = 0; - g++; - } - - base->ascent = - top; - base->descent = bottom; - base->lbearing = lbearing; - base->rbearing = rbearing; - if (left < - base->width) - { - base->xoff = - base->width - left; - base->width += base->xoff; - base->rbearing += base->xoff; - base->lbearing += base->xoff; - } - if (right > 0) - { - base->width += right; - base->rbearing += right; - base->right_padding = 1; - for (i = 1; base + i != g; i++) - base[i].xoff -= right; - } - - for (i = 0; base + i != g; i++) - { - base[i].pos = begin; - base[i].to = end; - } - if (base->left_padding && lbearing < 0) - { - base->xoff -= lbearing; - base->width -= lbearing; - lbearing = 0; - } - } - - g_physical_ascent = MAX (g_physical_ascent, base->ascent); - g_physical_descent = MAX (g_physical_descent, base->descent); - extents->lbearing = MIN (extents->lbearing, extents->width + lbearing); - extents->rbearing = MAX (extents->rbearing, extents->width + rbearing); - extents->width += base->width; + g_physical_ascent = MAX (g_physical_ascent, g->g.ascent); + g_physical_descent = MAX (g_physical_descent, g->g.descent); + extents->lbearing = MIN (extents->lbearing, + extents->width + g->g.lbearing); + extents->rbearing = MAX (extents->rbearing, + extents->width + g->g.rbearing); + extents->width += g->g.xadv; } gstring->physical_ascent = g_physical_ascent; @@ -779,16 +659,16 @@ layout_glyph_string (MFrame *frame, MGlyphString *gstring) MGlyph box_glyph = g[-1]; box_glyph.type = GLYPH_BOX; - box_glyph.width + box_glyph.g.xadv = (control->fixed_width ? frame->space_width : box->inner_hmargin + box->width + box->outer_hmargin); - box_glyph.lbearing = 0; - box_glyph.rbearing = box_glyph.width; - box_glyph.xoff = 0; + box_glyph.g.lbearing = 0; + box_glyph.g.rbearing = box_glyph.g.xadv; + box_glyph.g.xoff = 0; box_glyph.right_padding = 1; - gstring->width += box_glyph.width; - gstring->rbearing += box_glyph.width; + gstring->width += box_glyph.g.xadv; + gstring->rbearing += box_glyph.g.xadv; INSERT_GLYPH (gstring, gidx, box_glyph); gidx++; g = MGLYPH (gidx); @@ -805,16 +685,16 @@ layout_glyph_string (MFrame *frame, MGlyphString *gstring) if (box_line_height < box_height) box_line_height = box_height; box_glyph.type = GLYPH_BOX; - box_glyph.width + box_glyph.g.xadv = (control->fixed_width ? frame->space_width : box->inner_hmargin + box->width + box->outer_hmargin); - box_glyph.lbearing = 0; - box_glyph.rbearing = box_glyph.width; - box_glyph.xoff = 0; + box_glyph.g.lbearing = 0; + box_glyph.g.rbearing = box_glyph.g.xadv; + box_glyph.g.xoff = 0; box_glyph.left_padding = 1; - gstring->width += box_glyph.width; - gstring->rbearing += box_glyph.width; + gstring->width += box_glyph.g.xadv; + gstring->rbearing += box_glyph.g.xadv; INSERT_GLYPH (gstring, gidx, box_glyph); gidx++; g = MGLYPH (gidx); @@ -834,12 +714,12 @@ layout_glyph_string (MFrame *frame, MGlyphString *gstring) for (g++; g->type == GLYPH_CHAR; g++) if (! rfont != ! g->rface->rfont || box != g->rface->box - || ((fromg->code == MCHAR_INVALID_CODE) - != (g->code == MCHAR_INVALID_CODE)) + || ((fromg->g.code == MCHAR_INVALID_CODE) + != (g->g.code == MCHAR_INVALID_CODE)) || (g->category == GLYPH_CATEGORY_FORMATTER && ignore_formatting_char)) break; - if (rfont && fromg->code != MCHAR_INVALID_CODE) + if (rfont && fromg->g.code != MCHAR_INVALID_CODE) { int extra_width; int to = GLYPH_INDEX (g); @@ -858,9 +738,9 @@ layout_glyph_string (MFrame *frame, MGlyphString *gstring) g = MGLYPH (from); pad = *g; pad.type = GLYPH_PAD; - pad.xoff = 0; - pad.lbearing = 0; - pad.width = pad.rbearing = extra_width; + pad.g.xoff = 0; + pad.g.lbearing = 0; + pad.g.xadv = pad.g.rbearing = extra_width; pad.left_padding = 1; INSERT_GLYPH (gstring, from, pad); to++; @@ -879,14 +759,14 @@ layout_glyph_string (MFrame *frame, MGlyphString *gstring) face, or a default value of the current frame, which is, however, not yet implemented. */ - if (extra_width + 2 < g->width) + if (extra_width + 2 < g->g.xadv) { - g->width -= extra_width; + g->g.xadv -= extra_width; } else { - extra_width = g->width - 2; - g->width = 2; + extra_width = g->g.xadv - 2; + g->g.xadv = 2; } gstring->width -= extra_width; gstring->rbearing -= extra_width; @@ -904,15 +784,15 @@ layout_glyph_string (MFrame *frame, MGlyphString *gstring) { pad = g[-1]; pad.type = GLYPH_PAD; - pad.xoff = 0; - pad.lbearing = 0; - pad.width = pad.rbearing = extra_width; + pad.g.xoff = 0; + pad.g.lbearing = 0; + pad.g.xadv = pad.g.rbearing = extra_width; INSERT_GLYPH (gstring, to, pad); to++; g = MGLYPH (to); } else - g[-1].width += extra_width; + g[-1].g.xadv += extra_width; extents.width += extra_width; } @@ -930,15 +810,15 @@ layout_glyph_string (MFrame *frame, MGlyphString *gstring) { for (; fromg < g; fromg++) { - if ((fromg->c >= 0x200B && fromg->c <= 0x200F) - || (fromg->c >= 0x202A && fromg->c <= 0x202E)) - fromg->width = fromg->rbearing = 1; + if ((fromg->g.c >= 0x200B && fromg->g.c <= 0x200F) + || (fromg->g.c >= 0x202A && fromg->g.c <= 0x202E)) + fromg->g.xadv = fromg->g.rbearing = 1; else - fromg->width = fromg->rbearing = rface->space_width; - fromg->xoff = fromg->lbearing = 0; - fromg->ascent = fromg->descent = 0; - gstring->width += fromg->width; - gstring->rbearing += fromg->width; + fromg->g.xadv = fromg->g.rbearing = rface->space_width; + fromg->g.xoff = fromg->g.lbearing = 0; + fromg->g.ascent = fromg->g.descent = 0; + gstring->width += fromg->g.xadv; + gstring->rbearing += fromg->g.xadv; } if (gstring->ascent < frame->rface->ascent) gstring->ascent = frame->rface->ascent; @@ -948,40 +828,40 @@ layout_glyph_string (MFrame *frame, MGlyphString *gstring) } else if (g->type == GLYPH_SPACE) { - if (g->c == ' ') - g->width = g->rface->space_width; - else if (g->c == '\n') + if (g->g.c == ' ') + g->g.xadv = g->rface->space_width; + else if (g->g.c == '\n') { - g->width = control->cursor_width; - if (g->width) + g->g.xadv = control->cursor_width; + if (g->g.xadv) { if (control->cursor_bidi) - g->width = 3; - else if (g->width < 0) - g->width = g->rface->space_width; + g->g.xadv = 3; + else if (g->g.xadv < 0) + g->g.xadv = g->rface->space_width; } } - else if (g->c == '\t') + else if (g->g.c == '\t') { - g->width = tab_width - ((gstring->indent + gstring->width) - % tab_width); + g->g.xadv = tab_width - ((gstring->indent + gstring->width) + % tab_width); tab_found = 1; } else - g->width = 1; + g->g.xadv = 1; if (g[-1].type == GLYPH_PAD) { /* This space glyph absorbs (maybe partially) the previous padding glyph. */ - g->width -= g[-1].width; - if (g->width < 1) + g->g.xadv -= g[-1].g.xadv; + if (g->g.xadv < 1) /* But, keep at least some space width. For the moment, we use the arbitrary width 2-pixel. */ - g->width = 2; + g->g.xadv = 2; } - g->rbearing = g->width; - gstring->width += g->width; - gstring->rbearing += g->width; + g->g.rbearing = g->g.xadv; + gstring->width += g->g.xadv; + gstring->rbearing += g->g.xadv; if (g->rface->rfont) { if (gstring->ascent < g->rface->ascent) @@ -993,8 +873,8 @@ layout_glyph_string (MFrame *frame, MGlyphString *gstring) } else { - gstring->width += g->width; - gstring->rbearing += g->width; + gstring->width += g->g.xadv; + gstring->rbearing += g->g.xadv; g++; } } @@ -1006,16 +886,16 @@ layout_glyph_string (MFrame *frame, MGlyphString *gstring) MGlyph box_glyph = g[-1]; box_glyph.type = GLYPH_BOX; - box_glyph.width + box_glyph.g.xadv = (control->fixed_width ? frame->space_width : box->inner_hmargin + box->width + box->outer_hmargin); - box_glyph.lbearing = 0; - box_glyph.rbearing = box_glyph.width; - box_glyph.xoff = 0; + box_glyph.g.lbearing = 0; + box_glyph.g.rbearing = box_glyph.g.xadv; + box_glyph.g.xoff = 0; box_glyph.right_padding = 1; - gstring->width += box_glyph.width; - gstring->rbearing += box_glyph.width; + gstring->width += box_glyph.g.xadv; + gstring->rbearing += box_glyph.g.xadv; INSERT_GLYPH (gstring, gidx, box_glyph); } @@ -1058,23 +938,23 @@ layout_glyph_string (MFrame *frame, MGlyphString *gstring) for (g = MGLYPH (gstring->used - 2); g->type != GLYPH_ANCHOR; g--) { - if (g->type == GLYPH_CHAR && g->c == '\t') + if (g->type == GLYPH_CHAR && g->g.c == '\t') { int this_width = tab_width - (width % tab_width); if (g[1].type == GLYPH_PAD) - this_width -= g[1].width; + this_width -= g[1].g.xadv; if (g[-1].type == GLYPH_PAD) - this_width -= g[-1].width; + this_width -= g[-1].g.xadv; if (this_width < 2) this_width = 2; - gstring->width += this_width - g->width; - gstring->rbearing += this_width - g->width; - g->width = this_width; + gstring->width += this_width - g->g.xadv; + gstring->rbearing += this_width - g->g.xadv; + g->g.xadv = this_width; width += this_width; } else - width += g->width; + width += g->g.xadv; } } } @@ -1105,9 +985,10 @@ draw_background (MFrame *frame, MDrawWindow win, int x, int y, } *from_idx = *to_idx = 0; + *to_x = x; while (g->type != GLYPH_ANCHOR) { - if (g->pos >= from && g->pos < to) + if (g->g.from >= from && g->g.from < to) { MGlyph *fromg = g, *cursor = NULL; MRealizedFace *rface = g->rface; @@ -1117,18 +998,18 @@ draw_background (MFrame *frame, MDrawWindow win, int x, int y, if (! *from_idx) *from_idx = GLYPH_INDEX (g); - while (g->pos >= from && g->pos < to + while (g->g.from >= from && g->g.from < to && g->rface == rface) { g->enabled = 1; if (g->type != GLYPH_BOX - && g->pos <= cursor_pos && g->to > cursor_pos) + && g->g.from <= cursor_pos && g->g.to > cursor_pos) { if (! cursor) cursor = g, cursor_x = x + width; - cursor_width += g->width; + cursor_width += g->g.xadv; } - width += g++->width; + width += g++->g.xadv; } if (width > 0 && (control->as_image @@ -1137,9 +1018,9 @@ draw_background (MFrame *frame, MDrawWindow win, int x, int y, int this_x = x, this_width = width; if (fromg->type == GLYPH_BOX) - this_x += fromg->width, this_width -= fromg->width; + this_x += fromg->g.xadv, this_width -= fromg->g.xadv; if (g[-1].type == GLYPH_BOX) - this_width -= g[-1].width; + this_width -= g[-1].g.xadv; (frame->driver->fill_space) (frame, win, rface, 0, this_x, y - gstring->text_ascent, this_width, @@ -1193,13 +1074,13 @@ draw_background (MFrame *frame, MDrawWindow win, int x, int y, while (fromg < g) { if (fromg->type != GLYPH_BOX - && fromg->pos <= prev_pos && fromg->to > prev_pos) + && fromg->g.from <= prev_pos && fromg->g.to > prev_pos) { if (! cursor) cursor = fromg, cursor_x = x + temp_width; - cursor_width += fromg->width; + cursor_width += fromg->g.xadv; } - temp_width += fromg++->width; + temp_width += fromg++->g.xadv; } if (cursor) { @@ -1254,10 +1135,10 @@ render_glyphs (MFrame *frame, MDrawWindow win, int x, int y, int width, (*frame->driver->region_to_rect) (region, &rect); if (rect.x > x) { - while (g != gend && x + g->rbearing <= rect.x) + while (g != gend && x + g->g.rbearing <= rect.x) { - x += g->width; - width -= g++->width; + x += g->g.xadv; + width -= g++->g.xadv; while (! g->enabled && g != gend) g++; } @@ -1266,14 +1147,14 @@ render_glyphs (MFrame *frame, MDrawWindow win, int x, int y, int width, if (rect.x < x + width) { while (g != gend - && (x + width - gend[-1].width + gend[-1].lbearing >= rect.x)) + && (x + width - gend[-1].g.xadv + gend[-1].g.lbearing >= rect.x)) { - width -= (--gend)->width; + width -= (--gend)->g.xadv; while (! gend->enabled && g != gend) gend--; } if (g != gend) - while (gend->type != GLYPH_ANCHOR && gend[-1].to == gend->to) + while (gend->type != GLYPH_ANCHOR && gend[-1].g.to == gend->g.to) gend++; } } @@ -1283,21 +1164,21 @@ render_glyphs (MFrame *frame, MDrawWindow win, int x, int y, int width, if (g->enabled) { MRealizedFace *rface = g->rface; - int width = g->width; + int width = g->g.xadv; MGlyph *from_g = g++; /* Handle the glyphs of the same type/face at once. */ while (g != gend && g->type == from_g->type && g->rface == rface - && ((g->code == MCHAR_INVALID_CODE) - == (from_g->code == MCHAR_INVALID_CODE)) + && ((g->g.code == MCHAR_INVALID_CODE) + == (from_g->g.code == MCHAR_INVALID_CODE)) && g->enabled) - width += g++->width; + width += g++->g.xadv; if (from_g->type == GLYPH_CHAR) { - if (rface->rfont && from_g->code != MCHAR_INVALID_CODE) + if (rface->rfont && from_g->g.code != MCHAR_INVALID_CODE) (rface->rfont->driver->render) (win, x, y, gstring, from_g, g, reverse, region); else @@ -1341,11 +1222,11 @@ find_overlapping_glyphs (MGlyphString *gstring, int *left, int *right, for (g = MGLYPH (*left) - 1, x = 0; g->type != GLYPH_ANCHOR; g--) { - x -= g->width; - if (x + g->rbearing > 0) + x -= g->g.xadv; + if (x + g->g.rbearing > 0) { - while (g[-1].pos == g->pos && g[-1].type != GLYPH_ANCHOR) - x -= (--g)->width; + while (g[-1].g.from == g->g.from && g[-1].type != GLYPH_ANCHOR) + x -= (--g)->g.xadv; left_idx = GLYPH_INDEX (g); left_x = x; } @@ -1353,11 +1234,11 @@ find_overlapping_glyphs (MGlyphString *gstring, int *left, int *right, for (g = MGLYPH (*right), x = 0; g->type != GLYPH_ANCHOR; g++) { - x += g->width; - if (x - g->width + g->lbearing < 0) + x += g->g.xadv; + if (x - g->g.xadv + g->g.lbearing < 0) { - while (g->pos == g[1].pos && g[1].type != GLYPH_ANCHOR) - x += (++g)->width; + while (g->g.from == g[1].g.from && g[1].type != GLYPH_ANCHOR) + x += (++g)->g.xadv; right_idx = GLYPH_INDEX (g) + 1; right_x = x; } @@ -1385,26 +1266,33 @@ find_overlapping_glyphs (MGlyphString *gstring, int *left, int *right, static int -gstring_width (MGlyphString *gstring, int from, int to, int *rbearing) +gstring_width (MGlyphString *gstring, int from, int to, + int *lbearing, int *rbearing) { MGlyph *g; int width; if (from <= gstring->from && to >= gstring->to) { + if (lbearing) + *lbearing = gstring->lbearing; if (rbearing) *rbearing = gstring->rbearing; return gstring->width; } + if (lbearing) + *lbearing = 0; if (rbearing) *rbearing = 0; for (g = MGLYPH (1), width = 0; g->type != GLYPH_ANCHOR; g++) - if (g->pos >= from && g->pos < to) + if (g->g.from >= from && g->g.from < to) { - if (rbearing && width + g->rbearing > *rbearing) - *rbearing = width + g->rbearing; - width += g->width; + if (lbearing && width + g->g.lbearing < *lbearing) + *lbearing = width + g->g.lbearing; + if (rbearing && width + g->g.rbearing > *rbearing) + *rbearing = width + g->g.rbearing; + width += g->g.xadv; } return width; } @@ -1420,8 +1308,10 @@ render_glyph_string (MFrame *frame, MDrawWindow win, int x, int y, int from_idx, to_idx; int to_x; + if (from == to) + return; if (control->orientation_reversed) - x -= gstring->indent + gstring_width (gstring, from, to, NULL); + x -= gstring->indent + gstring_width (gstring, from, to, NULL, NULL); else x += gstring->indent; @@ -1502,19 +1392,19 @@ alloc_gstring (MFrame *frame, MText *mt, int pos, MDrawControl *control, APPEND_GLYPH (gstring, g_tmp); APPEND_GLYPH (gstring, g_tmp); gstring->glyphs[1].type = GLYPH_SPACE; - gstring->glyphs[1].c = '\n'; - gstring->glyphs[1].code = '\n'; + gstring->glyphs[1].g.c = '\n'; + gstring->glyphs[1].g.code = '\n'; } gstring->from = pos; g = MGLYPH (0); g->rface = frame->rface; - g->pos = g->to = pos; + g->g.from = g->g.to = pos; g++; g->rface = frame->rface; - g->pos = pos++, g->to = pos; + g->g.from = pos++, g->g.to = pos; g++; g->rface = frame->rface; - g->pos = g->to = pos; + g->g.from = g->g.to = pos; gstring->to = pos; } else @@ -1558,7 +1448,7 @@ truncate_gstring (MFrame *frame, MText *mt, MGlyphString *gstring) MTABLE_ALLOCA (pos_width, gstring->to - gstring->from, MERROR_DRAW); memset (pos_width, 0, sizeof (int) * (gstring->to - gstring->from)); for (g = MGLYPH (1); g->type != GLYPH_ANCHOR; g++) - pos_width[g->pos - gstring->from] += g->width; + pos_width[g->g.from - gstring->from] += g->g.xadv; for (i = 0, width = 0; i < gstring->to - gstring->from; i++) { if (pos_width[i] > 0) @@ -1578,7 +1468,7 @@ truncate_gstring (MFrame *frame, MText *mt, MGlyphString *gstring) if (pos <= gstring->from) { g = find_glyph_in_gstring (gstring, gstring->from, 1); - pos = g->to; + pos = g->g.to; } else if (pos >= gstring->to) pos = gstring->to; @@ -1586,7 +1476,7 @@ truncate_gstring (MFrame *frame, MText *mt, MGlyphString *gstring) else if (i == 0) { g = find_glyph_in_gstring (gstring, gstring->from, 1); - pos = g->to; + pos = g->g.to; } if (pos < gstring->to) { @@ -1624,6 +1514,7 @@ get_gstring (MFrame *frame, MText *mt, int pos, int to, MDrawControl *control) || memcmp (control, &gstring->control, (char *) (&control->with_cursor) - (char *) (control)) + || control->cursor_pos != gstring->control.cursor_pos || control->cursor_width != gstring->control.cursor_width || control->cursor_bidi != gstring->control.cursor_bidi) { @@ -1655,8 +1546,8 @@ get_gstring (MFrame *frame, MText *mt, int pos, int to, MDrawControl *control) gst->to += offset; for (i = 0; i < gst->used; i++) { - gst->glyphs[i].pos += offset; - gst->glyphs[i].to += offset; + gst->glyphs[i].g.from += offset; + gst->glyphs[i].g.to += offset; } } M17N_OBJECT_REF (gstring); @@ -1777,13 +1668,13 @@ find_glyph_in_gstring (MGlyphString *gstring, int pos, int forwardp) if (forwardp) { for (g = MGLYPH (1); g->type != GLYPH_ANCHOR; g++) - if (g->pos <= pos && g->to > pos) + if (g->g.from <= pos && g->g.to > pos) break; } else { for (g = MGLYPH (gstring->used - 2); g->type != GLYPH_ANCHOR; g--) - if (g->pos <= pos && g->to > pos) + if (g->g.from <= pos && g->g.to > pos) break; } return g; @@ -1793,62 +1684,43 @@ find_glyph_in_gstring (MGlyphString *gstring, int pos, int forwardp) /* for debugging... */ char work[16]; -char * -dump_combining_code (int code) -{ - char *vallign = "tcbB"; - char *hallign = "lcr"; - char *p; - int off_x, off_y; - - if (! code) - return "none"; - if (COMBINING_BY_CLASS_P (code)) - code = combining_code_from_class (COMBINING_CODE_CLASS (code)); - work[0] = vallign[COMBINING_CODE_BASE_Y (code)]; - work[1] = hallign[COMBINING_CODE_BASE_X (code)]; - off_y = COMBINING_CODE_OFF_Y (code) - 128; - off_x = COMBINING_CODE_OFF_X (code) - 128; - if (off_y > 0) - sprintf (work + 2, "+%d", off_y); - else if (off_y < 0) - sprintf (work + 2, "%d", off_y); - else if (off_x == 0) - sprintf (work + 2, "."); - p = work + strlen (work); - if (off_x > 0) - sprintf (p, ">%d", off_x); - else if (off_x < 0) - sprintf (p, "<%d", -off_x); - p += strlen (p); - p[0] = vallign[COMBINING_CODE_ADD_Y (code)]; - p[1] = hallign[COMBINING_CODE_ADD_X (code)]; - p[2] = '\0'; - return work; -} - void -dump_gstring (MGlyphString *gstring, int indent) +dump_gstring (MGlyphString *gstring, int indent, int type) { char *prefix = (char *) alloca (indent + 1); - MGlyph *g, *last_g = gstring->glyphs + gstring->used; + MGlyph *g, *first_g, *last_g; memset (prefix, 32, indent); prefix[indent] = 0; fprintf (stderr, "(glyph-string"); - for (g = MGLYPH (0); g < last_g; g++) - fprintf (stderr, - "\n%s (%02d %s pos:%d-%d c:%04X code:%04X face:%x cmb:%s w:%02d bidi:%d)", - prefix, - g - gstring->glyphs, - (g->type == GLYPH_SPACE ? "SPC": g->type == GLYPH_PAD ? "PAD" - : g->type == GLYPH_ANCHOR ? "ANC" - : g->type == GLYPH_BOX ? "BOX" : "CHR"), - g->pos, g->to, g->c, g->code, (unsigned) g->rface, - dump_combining_code (g->combining_code), - g->width, g->bidi_level); + if (type == 0) + { + first_g = MGLYPH (0); + last_g = first_g + gstring->used; + } + else + { + first_g = (MGlyph *) ((MFLTGlyphString *) gstring)->glyphs; + last_g = first_g + ((MFLTGlyphString *) gstring)->used; + } + + for (g = first_g; g < last_g; g++) + { + fprintf (stderr, + "\n%s (%02d %s pos:%d-%d c:%04X code:%04X face:%x w:%02d bidi:%d", + prefix, + g - first_g, + (g->type == GLYPH_SPACE ? "SPC": g->type == GLYPH_PAD ? "PAD" + : g->type == GLYPH_ANCHOR ? "ANC" + : g->type == GLYPH_BOX ? "BOX" : "CHR"), + g->g.from, g->g.to, g->g.c, g->g.code, (unsigned) g->rface, + g->g.xadv, g->bidi_level); + if (g->g.xoff || g->g.yoff) + fprintf (stderr, " off:%d,%d", g->g.xoff, g->g.yoff); + fprintf (stderr, ")"); + } fprintf (stderr, ")"); } @@ -1863,7 +1735,6 @@ mdraw__init () memset (&scratch_gstring, 0, sizeof (scratch_gstring)); MLIST_INIT1 (&scratch_gstring, glyphs, 3); - Minherited = msymbol ("inherited"); Mcommon = msymbol ("common"); McatCc = msymbol ("Cc"); @@ -1875,8 +1746,13 @@ mdraw__init () MbidiRLO = msymbol ("RLO"); MbidiBN = msymbol ("BN"); MbidiS = msymbol ("S"); + MbidiNSM = msymbol ("NSM"); #ifdef HAVE_FRIBIDI +#if FRIBIDI_INTERFACE_VERSION < 3 fribidi_set_mirroring (TRUE); +#else + fribidi_set_mirroring (1); +#endif #endif M_break_at_space = msymbol ("bs"); @@ -1885,6 +1761,8 @@ mdraw__init () M_kinsoku_bol = msymbol ("kb"); M_kinsoku_eol = msymbol ("ke"); + mflt_enable_new_feature = 1; + return 0; } @@ -2091,7 +1969,7 @@ mdraw_text (MFrame *frame, MDrawWindow win, int x, int y, @return ½èÍý¤¬À®¸ù¤·¤¿¾ì¹ç¡¢mdraw_image_text () ¤Ï 0 - ¤òÊÖ¤¹¡£¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì¤¿¾ì¹ç¤Ï -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #m_errro ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ + ¤òÊÖ¤¹¡£¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì¤¿¾ì¹ç¤Ï -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ @latexonly \IPAlabel{mdraw_image_text} @endlatexonly */ @@ -2127,7 +2005,7 @@ mdraw_image_text (MFrame *frame, MDrawWindow win, int x, int y, this function also follows what specified in the drawing control object $CONTROL. - For instance, if of $CONTROL is nonzero, this + For instance, if \ of $CONTROL is nonzero, this function draw an M-text 2-dimensionally, i.e., newlines in M-text breaks lines and the following characters are drawn in the next line. See the documentation of the structure @ MDrawControl for @@ -2143,7 +2021,7 @@ mdraw_image_text (MFrame *frame, MDrawWindow win, int x, int y, ¥Æ¥­¥¹¥È¤ÎÉÁ²èÊýË¡¤Ï mdraw_text () ¤È¤Û¤ÜƱ¤¸¤Ç¤¢¤ë¤¬¡¢¤³¤Î´Ø¿ô¤ÏÉÁ²èÀ©¸æÍѤΥª¥Ö¥¸¥§¥¯¥È $CONTROL ¤Î»Ø¼¨¤Ë¤â½¾¤¦ÅÀ¤¬°Û¤Ê¤Ã¤Æ¤¤¤ë¡£ - ¤¿¤È¤¨¤Ð $CONTROL ¤Î ¤¬¥¼¥í¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï + ¤¿¤È¤¨¤Ð $CONTROL ¤Î \ ¤¬¥¼¥í¤Ç¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï M-text ¤ò2¼¡¸µÅª¤ËÉÁ¤¯¡£¤¹¤Ê¤ï¤Á M-text Ãæ¤Î²þ¹Ô¤Ç¹Ô¤ò²þ¤á¡¢Â³¤¯Ê¸»ú¤Ï¼¡¤Î¹Ô¤ËÉÁ¤¯¡£¾ÜºÙ¤Ï¹½Â¤ÂÎ @ MDrawControl ¤ÎÀâÌÀ¤ò»²¾È¤¹¤ë¤³¤È¡£*/ @@ -2237,7 +2115,7 @@ mdraw_text_extents (MFrame *frame, { MGlyphString *gstring; int y = 0; - int width, rbearing; + int width, lbearing, rbearing; ASSURE_CONTROL (control); M_CHECK_POS_X (mt, from, -1); @@ -2249,52 +2127,49 @@ mdraw_text_extents (MFrame *frame, gstring = get_gstring (frame, mt, from, to, control); if (! gstring) MERROR (MERROR_DRAW, -1); - width = gstring_width (gstring, from, to, &rbearing); + width = gstring_width (gstring, from, to, &lbearing, &rbearing); if (overall_ink_return) - { - overall_ink_return->y = - gstring->physical_ascent; - overall_ink_return->x = gstring->lbearing; - } + overall_ink_return->y = - gstring->physical_ascent; if (overall_logical_return) - { - overall_logical_return->y = - gstring->ascent; - overall_logical_return->x = 0; - } + overall_logical_return->y = - gstring->ascent; if (overall_line_return) - { - overall_line_return->y = - gstring->line_ascent; - overall_line_return->x = gstring->lbearing; - } + overall_line_return->y = - gstring->line_ascent; for (from = gstring->to; from < to; from = gstring->to) { - int this_width, this_rbearing; + int this_width, this_lbearing, this_rbearing; y += gstring->line_descent; M17N_OBJECT_UNREF (gstring->top); gstring = get_gstring (frame, mt, from, to, control); - this_width = gstring_width (gstring, from, to, &this_rbearing); + this_width = gstring_width (gstring, from, to, + &this_lbearing, &this_rbearing); y += gstring->line_ascent; if (width < this_width) width = this_width; if (rbearing < this_rbearing) rbearing = this_rbearing; + if (lbearing > this_lbearing) + lbearing = this_lbearing; } if (overall_ink_return) { - overall_ink_return->width = rbearing; + overall_ink_return->x = lbearing; + overall_ink_return->width = rbearing - lbearing; overall_ink_return->height = y + gstring->physical_descent - overall_ink_return->y; } if (overall_logical_return) { + overall_logical_return->x = 0; overall_logical_return->width = width; overall_logical_return->height = y + gstring->descent - overall_logical_return->y; } if (overall_line_return) { - overall_line_return->width = MAX (width, rbearing); + overall_line_return->x = lbearing; + overall_line_return->width = MAX (width, rbearing - lbearing); overall_line_return->height = y + gstring->line_descent - overall_line_return->y; } @@ -2389,15 +2264,15 @@ mdraw_text_per_char_extents (MFrame *frame, } for (g = MGLYPH (1), x = 0; g->type != GLYPH_ANCHOR; g++) - if (g->pos >= from && g->pos < to) + if (g->g.from >= from && g->g.from < to) { - int start = g->pos; - int end = g->to; - int width = g->width; - int lbearing = g->lbearing; - int rbearing = g->rbearing; - int ascent = g->ascent; - int descent = g->descent; + int start = g->g.from; + int end = g->g.to; + int width = g->g.xadv; + int lbearing = g->g.lbearing; + int rbearing = g->g.rbearing; + int ascent = g->g.ascent; + int descent = g->g.descent; int logical_ascent; int logical_descent; @@ -2411,17 +2286,17 @@ mdraw_text_per_char_extents (MFrame *frame, logical_ascent = g->rface->ascent; logical_descent = g->rface->descent; } - for (g++; g->type != GLYPH_ANCHOR && g->pos == start; g++) + for (g++; g->type != GLYPH_ANCHOR && g->g.from == start; g++) { - if (lbearing < width + g->lbearing) - lbearing = width + g->lbearing; - if (rbearing < width + g->rbearing) - rbearing = width + g->rbearing; - width += g->width; - if (ascent < g->ascent) - ascent = g->ascent; - if (descent < g->descent) - descent = g->descent; + if (lbearing < width + g->g.lbearing) + lbearing = width + g->g.lbearing; + if (rbearing < width + g->g.rbearing) + rbearing = width + g->g.rbearing; + width += g->g.xadv; + if (ascent < g->g.ascent) + ascent = g->g.ascent; + if (descent < g->g.descent) + descent = g->g.descent; } if (end > to) @@ -2554,9 +2429,9 @@ mdraw_coordinates_position (MFrame *frame, MText *mt, int from, int to, { width = gstring->indent; for (g = MGLYPH (1); g->type != GLYPH_ANCHOR; g++) - if (g->pos >= from && g->pos < to) + if (g->g.from >= from && g->g.from < to) { - width += g->width; + width += g->g.xadv; if (width > x_offset) break; } @@ -2565,18 +2440,18 @@ mdraw_coordinates_position (MFrame *frame, MText *mt, int from, int to, { width = - gstring->indent; for (g = MGLYPH (gstring->used - 2); g->type != GLYPH_ANCHOR; g--) - if (g->pos >= from && g->pos < to) + if (g->g.from >= from && g->g.from < to) { - width -= g->width; + width -= g->g.xadv; if (width < x_offset) break; } } if (g->type == GLYPH_ANCHOR && control->two_dimensional - && g[-1].c == '\n') + && g[-1].g.c == '\n') g--; - from = g->pos; + from = g->g.from; M17N_OBJECT_UNREF (gstring->top); return from; @@ -2639,23 +2514,23 @@ mdraw_glyph_info (MFrame *frame, MText *mt, int from, int pos, if (! control->orientation_reversed) { info->x = gstring->indent; - for (g = MGLYPH (1); g->pos > pos || g->to <= pos; g++) - info->x += g->width; + for (g = MGLYPH (1); g->g.from > pos || g->g.to <= pos; g++) + info->x += g->g.xadv; } else { info->x = - gstring->indent; - for (g = MGLYPH (gstring->used - 2); g->pos > pos || g->to <= pos; g--) - info->x -= g->width; - while (g[-1].to == g->to) + for (g = MGLYPH (gstring->used - 2); g->g.from > pos || g->g.to <= pos; g--) + info->x -= g->g.xadv; + while (g[-1].g.to == g->g.to) g--; } - info->from = g->pos; - info->to = g->to; - info->metrics.x = g->lbearing; + info->from = g->g.from; + info->to = g->g.to; + info->metrics.x = g->g.lbearing; info->metrics.y = - gstring->line_ascent; info->metrics.height = gstring->height; - info->metrics.width = - g->lbearing + g->width; + info->metrics.width = - g->g.lbearing + g->g.xadv; if (g->rface->rfont) info->font = (MFont *) g->rface->rfont; else @@ -2667,7 +2542,7 @@ mdraw_glyph_info (MFrame *frame, MText *mt, int from, int pos, /* The logically previous glyph is on this line. */ MGlyph *g_tmp = find_glyph_in_gstring (gstring, info->from - 1, 1); - info->prev_from = g_tmp->pos; + info->prev_from = g_tmp->g.from; } else if (info->line_from > 0 && gstring->from > 0) @@ -2677,14 +2552,14 @@ mdraw_glyph_info (MFrame *frame, MText *mt, int from, int pos, gstring->from, control); MGlyph *g_tmp = find_glyph_in_gstring (gst, info->from - 1, 1); - info->prev_from = g_tmp->pos; + info->prev_from = g_tmp->g.from; M17N_OBJECT_UNREF (gst->top); } else info->prev_from = -1; if (GLYPH_INDEX (g) > 1) - info->left_from = g[-1].pos, info->left_to = g[-1].to; + info->left_from = g[-1].g.from, info->left_to = g[-1].g.to; else if (! control->orientation_reversed) { if (info->line_from > 0) @@ -2695,7 +2570,7 @@ mdraw_glyph_info (MFrame *frame, MText *mt, int from, int pos, gst = get_gstring (frame, mt, p, gstring->from, control); g_tmp = gst->glyphs + (gst->used - 2); - info->left_from = g_tmp->pos, info->left_to = g_tmp->to; + info->left_from = g_tmp->g.from, info->left_to = g_tmp->g.to; M17N_OBJECT_UNREF (gst->top); } else @@ -2711,7 +2586,7 @@ mdraw_glyph_info (MFrame *frame, MText *mt, int from, int pos, gst = get_gstring (frame, mt, p, p + 1, control); g_tmp = gst->glyphs + (gst->used - 2); - info->left_from = g_tmp->pos, info->left_to = g_tmp->to; + info->left_from = g_tmp->g.from, info->left_to = g_tmp->g.to; M17N_OBJECT_UNREF (gst->top); } else @@ -2723,7 +2598,7 @@ mdraw_glyph_info (MFrame *frame, MText *mt, int from, int pos, /* The logically next glyph is on this line. */ MGlyph *g_tmp = find_glyph_in_gstring (gstring, info->to, 0); - info->next_to = g_tmp->to; + info->next_to = g_tmp->g.to; } else if (info->to + (control->cursor_width == 0) <= mtext_nchars (mt)) { @@ -2732,19 +2607,19 @@ mdraw_glyph_info (MFrame *frame, MText *mt, int from, int pos, MGlyphString *gst = get_gstring (frame, mt, p, p + 1, control); MGlyph *g_tmp = find_glyph_in_gstring (gst, p, 0); - info->next_to = g_tmp->to; + info->next_to = g_tmp->g.to; M17N_OBJECT_UNREF (gst->top); } else info->next_to = -1; - for (info->logical_width = (g++)->width; - g->pos == pos && g->type != GLYPH_ANCHOR; - info->metrics.width += g->width, info->logical_width += (g++)->width); - info->metrics.width += g[-1].rbearing - g[-1].width; + for (info->logical_width = (g++)->g.xadv; + g->g.from == pos && g->type != GLYPH_ANCHOR; + info->metrics.width += g->g.xadv, info->logical_width += (g++)->g.xadv); + info->metrics.width += g[-1].g.rbearing - g[-1].g.xadv; if (g->type != GLYPH_ANCHOR) - info->right_from = g->pos, info->right_to = g->to; + info->right_from = g->g.from, info->right_to = g->g.to; else if (! control->orientation_reversed) { if (gstring->to + (control->cursor_width == 0) <= mtext_nchars (mt)) @@ -2753,7 +2628,7 @@ mdraw_glyph_info (MFrame *frame, MText *mt, int from, int pos, M17N_OBJECT_UNREF (gstring->top); gstring = get_gstring (frame, mt, pos, pos + 1, control); g = MGLYPH (1); - info->right_from = g->pos, info->right_to = g->to; + info->right_from = g->g.from, info->right_to = g->g.to; } else info->right_from = info->right_to = -1; @@ -2766,7 +2641,7 @@ mdraw_glyph_info (MFrame *frame, MText *mt, int from, int pos, M17N_OBJECT_UNREF (gstring->top); gstring = get_gstring (frame, mt, pos, pos + 1, control); g = MGLYPH (1); - info->right_from = g->pos, info->right_to = g->to; + info->right_from = g->g.from, info->right_to = g->g.to; } else info->right_from = info->right_to = -1; @@ -2835,39 +2710,43 @@ mdraw_glyph_list (MFrame *frame, MText *mt, int from, int to, for (g = MGLYPH (1), n = 0; g->type != GLYPH_ANCHOR; g++) { if (g->type == GLYPH_BOX - || g->pos < from || g->pos >= to) + || g->g.from < from || g->g.from >= to) continue; if (g->type == GLYPH_PAD) { if (g->left_padding) - pad_width = g->width; + pad_width = g->g.xadv; else if (n > 0) { pad_width = 0; - glyphs[-1].x_advance += g->width; + glyphs[-1].x_advance += g->g.xadv; } continue; } if (n < array_size) { - glyphs->from = g->pos; - glyphs->to = g->to; - glyphs->glyph_code = g->code; - glyphs->x_off = g->xoff + pad_width; - glyphs->y_off = g->yoff; - glyphs->lbearing = g->lbearing; - glyphs->rbearing = g->rbearing; - glyphs->ascent = g->ascent; - glyphs->descent = g->descent; - glyphs->x_advance = g->width + pad_width; + glyphs->from = g->g.from; + glyphs->to = g->g.to; + glyphs->glyph_code = g->g.code; + glyphs->x_off = g->g.xoff + pad_width; + glyphs->y_off = g->g.yoff; + glyphs->lbearing = g->g.lbearing; + glyphs->rbearing = g->g.rbearing; + glyphs->ascent = g->g.ascent; + glyphs->descent = g->g.descent; + glyphs->x_advance = g->g.xadv + pad_width; glyphs->y_advance = 0; if (g->rface->rfont) { glyphs->font = (MFont *) g->rface->rfont; +#ifdef HAVE_FREETYPE glyphs->font_type = (glyphs->font->source == MFONT_SOURCE_X ? Mx : g->rface->rfont->driver == &mfont__ft_driver ? Mfreetype : Mxft); +#else /* not HAVE_FREETYPE */ + glyphs->font_type = Mx; +#endif /* not HAVE_FREETYPE */ glyphs->fontp = g->rface->rfont->fontp; } else @@ -2958,7 +2837,8 @@ int mdraw_line_break_option; character, and incremented each time when a long line is broken because of the width limit. - @return This function returns a character position to break the + @return + This function returns a character position to break the line. */