From 59739227dd9f0e5e129f60fcc3af8646e7833364 Mon Sep 17 00:00:00 2001 From: handa Date: Mon, 11 Oct 2004 00:58:40 +0000 Subject: [PATCH] (compose_glyph_string): Use more constant font for glyphs. Adjust for the member change in MGlyph. (layout_glyph_string): Adjust for the member change in MGlyph. (alloc_gstring): Intilize scracth_glyph to avoid compose_glyph_string on it. (get_gstring): Don't call compose_glyph_string on scracth_glyph. (mdraw_coordinates_position): Fix previous change. --- src/draw.c | 230 ++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 137 insertions(+), 93 deletions(-) diff --git a/src/draw.c b/src/draw.c index 4f0f887..aead2d6 100644 --- a/src/draw.c +++ b/src/draw.c @@ -223,9 +223,9 @@ reorder_combining_chars (MGlyphString *gstring, int from, int to) /** Scan M-text MT from FROM to TO, and compose glyphs in GSTRING for displaying them on FRAME. - This function fills members , , , , , - of glyphs. The other members are filled by - layout_glyph_string. */ + This function fills these members: + pos, to, c, code, rface, bidi_level, categories, type, combining_code + The other members are filled by layout_glyph_string. */ static void compose_glyph_string (MFrame *frame, MText *mt, int from, int to, @@ -233,50 +233,105 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to, { MRealizedFace *default_rface = frame->rface; int stop, face_change, language_change, charset_change; - MGlyph g_tmp, *g; + MGlyph g_tmp, *g, *last_g; int pos; MSymbol language = Mnil, script = Mnil, charset = Mnil; MSymbol non_latin_script = Mnil; MRealizedFace *rface = default_rface; + MRealizedFont *rfont; int size = gstring->control.fixed_width; int i; - int last; MLIST_RESET (gstring); gstring->from = from; - /* At first generate glyphs while using the member as a - flag for rface re-checking. */ + /* At first generate glyphs with , , , , + and members.*/ INIT_GLYPH (g_tmp); /** Put anchor glyphs at the head and tail. */ g_tmp.type = GLYPH_ANCHOR; g_tmp.pos = g_tmp.to = from; - g_tmp.c = 0; APPEND_GLYPH (gstring, g_tmp); - - stop = face_change = charset_change = language_change = pos = from; - last = 0; + stop = face_change = pos = from; while (1) { int c; - MSymbol this_script; + MSymbol category; + + if (pos == stop) + { + if (pos == to) + break; + if (pos == face_change) + { + MFace *faces[64]; + int num = mtext_get_prop_values (mt, pos, Mface, + (void **) faces, 64); + + mtext_prop_range (mt, Mface, pos, NULL, &face_change, 1); + rface = (num > 0 ? mface__realize (frame, faces, num, size) + : default_rface); + } + stop = to; + if (stop > face_change) + stop = face_change; + } if (pos < mtext_nchars (mt)) c = mtext_ref_char (mt, pos); else c = '\n'; - g_tmp.category = mchar_get_prop (c, Mcategory); - if (c < 0x100) + 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.rface = rface; + category = mchar_get_prop (c, Mcategory); + if (category == McatCf) + g_tmp.category = GLYPH_CATEGORY_FORMATTER; + else if (MSYMBOL_NAME (category)[0] == 'M') + g_tmp.category = GLYPH_CATEGORY_MODIFIER; + else + g_tmp.category = GLYPH_CATEGORY_NORMAL; + + if ((c <= ' ' || c == 127) && g_tmp.type == GLYPH_CHAR) { - /* Short cut for the obvious case. */ - g_tmp.type = (c == ' ' || c == '\n' || c == '\t' - ? GLYPH_SPACE : GLYPH_CHAR); - this_script = Mlatin; + MGlyph ctrl[2]; + + ctrl[0] = ctrl[1] = g_tmp; + ctrl[0].c = '^'; + ctrl[1].c = c < ' ' ? c + 0x40 : '?'; + APPEND_GLYPH (gstring, ctrl[0]); + APPEND_GLYPH (gstring, ctrl[1]); } else + APPEND_GLYPH (gstring, g_tmp); + if (c == '\n' && gstring->control.two_dimensional) + break; + } + /* Append an anchor glyph. */ + INIT_GLYPH (g_tmp); + g_tmp.type = GLYPH_ANCHOR; + g_tmp.pos = g_tmp.to = pos; + APPEND_GLYPH (gstring, g_tmp); + gstring->to = pos; + + /* 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; + MSymbol this_script; + + if (c < 0x100) + /* Short cut for the obvious case. */ + this_script = Mlatin; + else { - g_tmp.type = GLYPH_CHAR; this_script = (MSymbol) mchar_get_prop (c, Mscript); if (this_script == Minherited || this_script == Mnil) this_script = script; @@ -286,12 +341,12 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to, { /* Search forward for a character that explicitly specifies a non-latin script. */ - int c1; MSymbol sym; + MGlyph *g1; - for (i = pos + 1; i < to; i++) - if ((c1 = mtext_ref_char (mt, i)) >= 0x100 - && (sym = mchar_get_prop (c1, Mscript)) != Mnil + for (g1 = g + 1; g1->type != GLYPH_ANCHOR; g1++) + if (g1->c >= 0x100 + && (sym = mchar_get_prop (g1->c, Mscript)) != Mnil && sym != Minherited) { this_script = sym; @@ -300,20 +355,16 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to, } } - if (pos == stop || script != this_script - || MGLYPH (last)->type != g_tmp.type) + pos = g->pos; + if (pos == stop || script != this_script || g->rface->rfont != rfont) { - g = MGLYPH (last); - if (g->type != GLYPH_ANCHOR) - while (g < gstring->glyphs + gstring->used) - g = mface__for_chars (script, language, charset, - g, gstring->glyphs + gstring->used, size); - if (pos == to) - break; - last = gstring->used; + while (last_g < g) + last_g = mface__for_chars (script, language, charset, + last_g, g, size); script = this_script; if (script != Mnil && script != Mlatin) non_latin_script = script; + rfont = g->rface->ascii_rface->rfont; if (pos == stop) { if (pos < mtext_nchars (mt) && pos == language_change) @@ -328,63 +379,20 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to, mtext_prop_range (mt, Mcharset, pos, NULL, &charset_change, 0); } - if (pos < mtext_nchars (mt) && pos == face_change) - { - MFace *faces[64]; - int num = mtext_get_prop_values (mt, pos, Mface, - (void **) faces, 64); - - mtext_prop_range (mt, Mface, pos, NULL, &face_change, 1); - rface = (num > 0 - ? mface__realize (frame, faces, num, - language, charset, size) - : default_rface); - } stop = to; if (stop > language_change) stop = language_change; if (stop > charset_change) stop = charset_change; - if (face_change < stop) - stop = face_change; } } - - g_tmp.c = c; - g_tmp.pos = pos++; - g_tmp.to = pos; - g_tmp.rface = rface; - - if ((c <= 32 || c == 127) && g_tmp.type == GLYPH_CHAR) - { - MGlyph ctrl[2]; - - ctrl[0] = ctrl[1] = g_tmp; - ctrl[0].c = '^'; - ctrl[1].c = c < ' ' ? c + 0x40 : '?'; - mface__for_chars (Mlatin, language, charset, ctrl, ctrl + 2, size); - APPEND_GLYPH (gstring, ctrl[0]); - APPEND_GLYPH (gstring, ctrl[1]); - } - else - APPEND_GLYPH (gstring, g_tmp); - if (c == '\n' - && gstring->control.two_dimensional) - break; } + while (last_g < g) + last_g = mface__for_chars (script, language, charset, last_g, g, size); - /* Append an anchor glyph. */ - g_tmp.type = GLYPH_ANCHOR; - g_tmp.c = 0; - g_tmp.code = MCHAR_INVALID_CODE; - g_tmp.pos = g_tmp.to = pos; - g_tmp.rface = NULL; - APPEND_GLYPH (gstring, g_tmp); - - gstring->to = pos; - - /* Next, run FLT if necessary. */ - for (i = 1, g = MGLYPH (i); g->type != GLYPH_ANCHOR;) + /* The next loop is to run FLT or perform the default combining if + necessary. */ + for (i = 1, g = MGLYPH (1); g->type != GLYPH_ANCHOR;) { MGlyph *this = g; @@ -399,7 +407,7 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to, for (prev = MGLYPH (start - 1); (prev->type == GLYPH_CHAR - && prev->category == McatCf + && prev->category == GLYPH_CATEGORY_FORMATTER && (code = mfont__encode_char (this->rface->rfont, prev->c) != MCHAR_INVALID_CODE)); start--, prev--) @@ -408,7 +416,7 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to, for (g++; (g->type == GLYPH_CHAR && (g->rface->rfont == this->rface->rfont - || (g->category == McatCf + || (g->category == GLYPH_CATEGORY_FORMATTER && ((code = mfont__encode_char (this->rface->rfont, g->c)) != MCHAR_INVALID_CODE)))); @@ -424,8 +432,7 @@ compose_glyph_string (MFrame *frame, MText *mt, int from, int to, { while (this->type == GLYPH_CHAR && this->c >= 0x100 - && this->category - && MSYMBOL_NAME (this->category)[0] == 'M' + && this->category == GLYPH_CATEGORY_MODIFIER && this->rface->rfont && this->rface->rfont->layouter == Mnil) { @@ -770,7 +777,7 @@ layout_glyph_string (MFrame *frame, MGlyphString *gstring) } } - if (g->category == McatCf && ignore_formatting_char) + if (g->category == GLYPH_CATEGORY_FORMATTER && ignore_formatting_char) g->type = GLYPH_SPACE; if (g->type == GLYPH_CHAR) @@ -785,7 +792,8 @@ layout_glyph_string (MFrame *frame, MGlyphString *gstring) || box != g->rface->box || ((fromg->code == MCHAR_INVALID_CODE) != (g->code == MCHAR_INVALID_CODE)) - || (g->category == McatCf && ignore_formatting_char)) + || (g->category == GLYPH_CATEGORY_FORMATTER + && ignore_formatting_char)) break; if (rfont && fromg->code != MCHAR_INVALID_CODE) { @@ -1436,7 +1444,34 @@ alloc_gstring (MFrame *frame, MText *mt, int pos, MDrawControl *control, if (pos == mt->nchars) { + MGlyph *g; + gstring = &scratch_gstring; + if (gstring->size == 0) + { + MGlyph g_tmp; + + INIT_GLYPH (g_tmp); + g_tmp.type = GLYPH_ANCHOR; + APPEND_GLYPH (gstring, g_tmp); + APPEND_GLYPH (gstring, g_tmp); + APPEND_GLYPH (gstring, g_tmp); + gstring->glyphs[1].type = GLYPH_CHAR; + gstring->glyphs[1].c = ' '; + gstring->glyphs[1].code = ' '; + } + gstring->from = pos; + g = MGLYPH (0); + g->rface = frame->rface; + g->pos = g->to = pos; + g++; + g->rface = frame->rface; + g->pos = pos++, g->to = pos; + g->c = '\n', g->code = '\n'; + g++; + g->rface = frame->rface; + g->pos = g->to = pos; + gstring->to = pos; } else { @@ -1574,15 +1609,20 @@ get_gstring (MFrame *frame, MText *mt, int pos, int to, MDrawControl *control) int beg, end; int line = 0, y = 0; - beg = mtext_character (mt, pos, 0, '\n'); - if (beg < 0) - beg = 0; + if (pos < mtext_nchars (mt)) + { + beg = mtext_character (mt, pos, 0, '\n'); + if (beg < 0) + beg = 0; + else + beg++; + } else - beg++; + beg = pos; end = mtext_nchars (mt) + (control->cursor_width != 0); - gstring = alloc_gstring (frame, mt, beg, control, line, y); - compose_glyph_string (frame, mt, beg, end, gstring); + if (beg < mtext_nchars (mt)) + compose_glyph_string (frame, mt, beg, end, gstring); layout_glyph_string (frame, gstring); end = gstring->to; if (gstring->width_limit @@ -2485,6 +2525,10 @@ mdraw_coordinates_position (MFrame *frame, MText *mt, int from, int to, break; } } + if (g->type == GLYPH_ANCHOR + && control->two_dimensional + && g[-1].c == '\n') + g--; from = g->pos; M17N_OBJECT_UNREF (gstring->top); -- 1.7.10.4