Mercurial > emacs
changeset 26874:e45f9a84fca0
(it_props): Add an entry for composition.
(face_before_or_after_it_pos): For composition, check face of a
character after the composition.
(handle_composition_prop): New function.
(get_next_display_element): Adjusted for the change of
CHAR_STRING.
(set_iterator_to_next): Handle the case that it->method ==
next_element_from_composition.
(next_element_from_composition): New function.
(message_dolog): Adjusted for the change of CHAR_STRING.
(set_message_1): Likewise.
(check_point_in_composition): New function.
(reconsider_clip_changes): If point moved into or out of
composition, set b->clip_changed to 1 to force updating of the
screen.
(disp_char_vector): Delete codes for a composite character.
(decode_mode_spec_coding): Adjusted for the change of CHAR_STRING.
author | Kenichi Handa <handa@m17n.org> |
---|---|
date | Wed, 15 Dec 1999 00:23:27 +0000 |
parents | 5281eb29603f |
children | d6aa11f2a4af |
files | src/xdisp.c |
diffstat | 1 files changed, 181 insertions(+), 22 deletions(-) [+] |
line wrap: on
line diff
--- a/src/xdisp.c Wed Dec 15 00:22:26 1999 +0000 +++ b/src/xdisp.c Wed Dec 15 00:23:27 1999 +0000 @@ -533,6 +533,7 @@ static enum prop_handled handle_face_prop P_ ((struct it *)); static enum prop_handled handle_invisible_prop P_ ((struct it *)); static enum prop_handled handle_display_prop P_ ((struct it *)); +static enum prop_handled handle_composition_prop P_ ((struct it *)); static enum prop_handled handle_overlay_change P_ ((struct it *)); static enum prop_handled handle_fontified_prop P_ ((struct it *)); @@ -546,6 +547,7 @@ {&Qface, FACE_PROP_IDX, handle_face_prop}, {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop}, {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop}, + {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop}, {NULL, 0, NULL} }; @@ -646,6 +648,7 @@ static int next_element_from_string P_ ((struct it *)); static int next_element_from_c_string P_ ((struct it *)); static int next_element_from_buffer P_ ((struct it *)); +static int next_element_from_composition P_ ((struct it *)); static int next_element_from_image P_ ((struct it *)); static int next_element_from_stretch P_ ((struct it *)); static void load_overlay_strings P_ ((struct it *)); @@ -1943,7 +1946,11 @@ if (before_p) pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string); else - pos = string_pos (IT_STRING_CHARPOS (*it) + 1, it->string); + /* For composition, we must check the character after the + composition. */ + pos = (it->what == IT_COMPOSITION + ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string) + : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string)); /* Get the face for ASCII, or unibyte. */ face_id @@ -1985,8 +1992,14 @@ if (before_p) DEC_TEXT_POS (pos); else - INC_TEXT_POS (pos); - + { + if (it->what == IT_COMPOSITION) + /* For composition, we must check the position after the + composition. */ + pos.charpos += it->cmp_len, pos.bytepos += it->len; + else + INC_TEXT_POS (pos); + } /* Determine face for CHARSET_ASCII, or unibyte. */ face_id = face_at_buffer_position (it->w, CHARPOS (pos), @@ -2534,6 +2547,64 @@ /*********************************************************************** + `composition' property + ***********************************************************************/ + +/* Set up iterator IT from `composition' property at its current + position. Called from handle_stop. */ + +static enum prop_handled +handle_composition_prop (it) + struct it *it; +{ + Lisp_Object prop, string; + int pos, pos_byte, end; + enum prop_handled handled = HANDLED_NORMALLY; + + if (STRINGP (it->string)) + { + pos = IT_STRING_CHARPOS (*it); + pos_byte = IT_STRING_BYTEPOS (*it); + string = it->string; + } + else + { + pos = IT_CHARPOS (*it); + pos_byte = IT_BYTEPOS (*it); + string = Qnil; + } + + /* If there's a valid composition and point is not inside of the + composition (in the case that the composition is from the current + buffer), draw a glyph composed from the composition components. */ + if (find_composition (pos, -1, &pos, &end, &prop, string) + && COMPOSITION_VALID_P (pos, end, prop) + && (STRINGP (it->string) || (PT <= pos || PT >= end))) + { + int id = get_composition_id (pos, pos_byte, end - pos, prop, string); + + if (id >= 0) + { + it->method = next_element_from_composition; + it->cmp_id = id; + it->cmp_len = COMPOSITION_LENGTH (prop); + /* For a terminal, draw only the first character of the + components. */ + it->c = COMPOSITION_GLYPH (composition_table[id], 0); + it->len = (STRINGP (it->string) + ? string_char_to_byte (it->string, end) + : CHAR_TO_BYTE (end)) - pos_byte; + it->stop_charpos = end; + handled = HANDLED_RETURN; + } + } + + return handled; +} + + + +/*********************************************************************** Overlay strings ***********************************************************************/ @@ -3340,8 +3411,8 @@ } else { - unsigned char work[4], *str; - int len = CHAR_STRING (it->c, work, str); + unsigned char str[MAX_MULTIBYTE_LENGTH]; + int len = CHAR_STRING (it->c, str); int i; GLYPH escape_glyph; @@ -3442,6 +3513,23 @@ xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it))); } } + else if (it->method == next_element_from_composition) + { + xassert (it->cmp_id >= 0 && it ->cmp_id < n_compositions); + if (STRINGP (it->string)) + { + IT_STRING_BYTEPOS (*it) += it->len; + IT_STRING_CHARPOS (*it) += it->cmp_len; + it->method = next_element_from_string; + goto consider_string_end; + } + else + { + IT_BYTEPOS (*it) += it->len; + IT_CHARPOS (*it) += it->cmp_len; + it->method = next_element_from_buffer; + } + } else if (it->method == next_element_from_c_string) { /* Current display element of IT is from a C string. */ @@ -3862,7 +3950,7 @@ /* Get the next character, maybe multibyte. */ p = BYTE_POS_ADDR (IT_BYTEPOS (*it)); - if (it->multibyte_p) + if (it->multibyte_p && !ASCII_BYTE_P (*p)) { int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE) - IT_BYTEPOS (*it)); @@ -3939,6 +4027,22 @@ } +/* Deliver a composition display element. The iterator IT is already + filled with composition information (done in + handle_composition_prop). Value is always 1. */ + +static int +next_element_from_composition (it) + struct it *it; +{ + it->what = IT_COMPOSITION; + it->position = (STRINGP (it->string) + ? it->current.string_pos + : it->current.pos); + return 1; +} + + /*********************************************************************** Moving an iterator without producing glyphs @@ -4673,14 +4777,14 @@ { int i, c, nbytes; unsigned char *msg = (unsigned char *) m; - unsigned char *str, work[4]; + unsigned char str[MAX_MULTIBYTE_LENGTH]; /* Convert a single-byte string to multibyte for the *Message* buffer. */ for (i = 0; i < len; i++) { c = unibyte_char_to_multibyte (msg[i]); - nbytes = CHAR_STRING (c, work, str); - insert_1_both (work, 1, nbytes, 1, 0, 0); + nbytes = CHAR_STRING (c, str); + insert_1_both (str, 1, nbytes, 1, 0, 0); } } else if (len) @@ -5780,14 +5884,14 @@ /* Convert from single-byte to multi-byte. */ int i, c, n; unsigned char *msg = (unsigned char *) s; - unsigned char *str, work[4]; + unsigned char str[MAX_MULTIBYTE_LENGTH]; /* Convert a single-byte string to multibyte. */ for (i = 0; i < nbytes; i++) { c = unibyte_char_to_multibyte (msg[i]); - n = CHAR_STRING (c, work, str); - insert_1_both (work, 1, n, 1, 0, 0); + n = CHAR_STRING (c, str); + insert_1_both (str, 1, n, 1, 0, 0); } } else @@ -6953,6 +7057,43 @@ redisplay_internal (0); } +/* Return 1 if point moved out of or into a composition. Otherwise + return 0. PREV_BUF and PREV_PT are the last point buffer and + position. BUF and PT are the current point buffer and position. */ + +int +check_point_in_composition (prev_buf, prev_pt, buf, pt) + struct buffer *prev_buf, *buf; + int prev_pt, pt; +{ + int start, end; + Lisp_Object prop; + Lisp_Object buffer; + + XSETBUFFER (buffer, buf); + /* Check a composition at the last point if point moved within the + same buffer. */ + if (prev_buf == buf) + { + if (prev_pt == pt) + /* Point didn't move. */ + return 0; + + if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf) + && find_composition (prev_pt, -1, &start, &end, &prop, buffer) + && COMPOSITION_VALID_P (start, end, prop) + && start < prev_pt && end > prev_pt) + /* The last point was within the composition. Return 1 iff + point moved out of the composition. */ + return (pt <= start || pt >= end); + } + + /* Check a composition at the current point. */ + return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf) + && find_composition (pt, -1, &start, &end, &prop, buffer) + && COMPOSITION_VALID_P (start, end, prop) + && start < pt && end > pt); +} /* Reconsider the setting of B->clip_changed which is displayed in window W. */ @@ -6970,6 +7111,29 @@ && w->current_matrix->zv == BUF_ZV (b) && w->current_matrix->begv == BUF_BEGV (b)) b->clip_changed = 0; + + /* If display wasn't paused, and W is not a tool bar window, see if + point has been moved into or out of a composition. In that case, + we set b->clip_changed to 1 to force updating the screen. If + b->clip_changed has already been set to 1, we can skip this + check. */ + if (!b->clip_changed + && BUFFERP (w->buffer) && !NILP (w->window_end_valid)) + { + int pt; + + if (w == XWINDOW (selected_window)) + pt = BUF_PT (current_buffer); + else + pt = marker_position (w->pointm); + + if ((w->current_matrix->buffer != XBUFFER (w->buffer) + || pt != w->last_point) + && check_point_in_composition (w->current_matrix->buffer, + w->last_point, + XBUFFER (w->buffer), pt)) + b->clip_changed = 1; + } } @@ -7790,13 +7954,10 @@ return (dp->contents[c]); SPLIT_NON_ASCII_CHAR (c, code[0], code[1], code[2]); - if (code[0] != CHARSET_COMPOSITION) - { - if (code[1] < 32) - code[1] = -1; - else if (code[2] < 32) - code[2] = -1; - } + if (code[1] < 32) + code[1] = -1; + else if (code[2] < 32) + code[2] = -1; /* Here, the possible range of code[0] (== charset ID) is 128..max_charset. Since the top level char table contains data @@ -11864,9 +12025,7 @@ else if (INTEGERP (eoltype) && CHAR_VALID_P (XINT (eoltype), 0)) { - unsigned char work[4]; - - eol_str_len = CHAR_STRING (XINT (eoltype), work, eol_str); + eol_str_len = CHAR_STRING (XINT (eoltype), eol_str); } else {