diff options
| author | Kenichi Handa | 1999-12-15 00:23:27 +0000 |
|---|---|---|
| committer | Kenichi Handa | 1999-12-15 00:23:27 +0000 |
| commit | 260a86a07c364e6dfac1cf1e1476575744461124 (patch) | |
| tree | ab77538993c8f95ca40cd818182ff25744c25632 /src | |
| parent | f02d6d5cbbff57ab7985cb055ca98ac842d9de36 (diff) | |
| download | emacs-260a86a07c364e6dfac1cf1e1476575744461124.tar.gz emacs-260a86a07c364e6dfac1cf1e1476575744461124.zip | |
(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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xdisp.c | 203 |
1 files changed, 181 insertions, 22 deletions
diff --git a/src/xdisp.c b/src/xdisp.c index 26acf61d216..a88f9893c51 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -533,6 +533,7 @@ struct props | |||
| 533 | static enum prop_handled handle_face_prop P_ ((struct it *)); | 533 | static enum prop_handled handle_face_prop P_ ((struct it *)); |
| 534 | static enum prop_handled handle_invisible_prop P_ ((struct it *)); | 534 | static enum prop_handled handle_invisible_prop P_ ((struct it *)); |
| 535 | static enum prop_handled handle_display_prop P_ ((struct it *)); | 535 | static enum prop_handled handle_display_prop P_ ((struct it *)); |
| 536 | static enum prop_handled handle_composition_prop P_ ((struct it *)); | ||
| 536 | static enum prop_handled handle_overlay_change P_ ((struct it *)); | 537 | static enum prop_handled handle_overlay_change P_ ((struct it *)); |
| 537 | static enum prop_handled handle_fontified_prop P_ ((struct it *)); | 538 | static enum prop_handled handle_fontified_prop P_ ((struct it *)); |
| 538 | 539 | ||
| @@ -546,6 +547,7 @@ static struct props it_props[] = | |||
| 546 | {&Qface, FACE_PROP_IDX, handle_face_prop}, | 547 | {&Qface, FACE_PROP_IDX, handle_face_prop}, |
| 547 | {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop}, | 548 | {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop}, |
| 548 | {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop}, | 549 | {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop}, |
| 550 | {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop}, | ||
| 549 | {NULL, 0, NULL} | 551 | {NULL, 0, NULL} |
| 550 | }; | 552 | }; |
| 551 | 553 | ||
| @@ -646,6 +648,7 @@ static int next_element_from_display_vector P_ ((struct it *)); | |||
| 646 | static int next_element_from_string P_ ((struct it *)); | 648 | static int next_element_from_string P_ ((struct it *)); |
| 647 | static int next_element_from_c_string P_ ((struct it *)); | 649 | static int next_element_from_c_string P_ ((struct it *)); |
| 648 | static int next_element_from_buffer P_ ((struct it *)); | 650 | static int next_element_from_buffer P_ ((struct it *)); |
| 651 | static int next_element_from_composition P_ ((struct it *)); | ||
| 649 | static int next_element_from_image P_ ((struct it *)); | 652 | static int next_element_from_image P_ ((struct it *)); |
| 650 | static int next_element_from_stretch P_ ((struct it *)); | 653 | static int next_element_from_stretch P_ ((struct it *)); |
| 651 | static void load_overlay_strings P_ ((struct it *)); | 654 | static void load_overlay_strings P_ ((struct it *)); |
| @@ -1943,7 +1946,11 @@ face_before_or_after_it_pos (it, before_p) | |||
| 1943 | if (before_p) | 1946 | if (before_p) |
| 1944 | pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string); | 1947 | pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string); |
| 1945 | else | 1948 | else |
| 1946 | pos = string_pos (IT_STRING_CHARPOS (*it) + 1, it->string); | 1949 | /* For composition, we must check the character after the |
| 1950 | composition. */ | ||
| 1951 | pos = (it->what == IT_COMPOSITION | ||
| 1952 | ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string) | ||
| 1953 | : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string)); | ||
| 1947 | 1954 | ||
| 1948 | /* Get the face for ASCII, or unibyte. */ | 1955 | /* Get the face for ASCII, or unibyte. */ |
| 1949 | face_id | 1956 | face_id |
| @@ -1985,8 +1992,14 @@ face_before_or_after_it_pos (it, before_p) | |||
| 1985 | if (before_p) | 1992 | if (before_p) |
| 1986 | DEC_TEXT_POS (pos); | 1993 | DEC_TEXT_POS (pos); |
| 1987 | else | 1994 | else |
| 1988 | INC_TEXT_POS (pos); | 1995 | { |
| 1989 | 1996 | if (it->what == IT_COMPOSITION) | |
| 1997 | /* For composition, we must check the position after the | ||
| 1998 | composition. */ | ||
| 1999 | pos.charpos += it->cmp_len, pos.bytepos += it->len; | ||
| 2000 | else | ||
| 2001 | INC_TEXT_POS (pos); | ||
| 2002 | } | ||
| 1990 | /* Determine face for CHARSET_ASCII, or unibyte. */ | 2003 | /* Determine face for CHARSET_ASCII, or unibyte. */ |
| 1991 | face_id = face_at_buffer_position (it->w, | 2004 | face_id = face_at_buffer_position (it->w, |
| 1992 | CHARPOS (pos), | 2005 | CHARPOS (pos), |
| @@ -2534,6 +2547,64 @@ handle_single_display_prop (it, prop, object, position) | |||
| 2534 | 2547 | ||
| 2535 | 2548 | ||
| 2536 | /*********************************************************************** | 2549 | /*********************************************************************** |
| 2550 | `composition' property | ||
| 2551 | ***********************************************************************/ | ||
| 2552 | |||
| 2553 | /* Set up iterator IT from `composition' property at its current | ||
| 2554 | position. Called from handle_stop. */ | ||
| 2555 | |||
| 2556 | static enum prop_handled | ||
| 2557 | handle_composition_prop (it) | ||
| 2558 | struct it *it; | ||
| 2559 | { | ||
| 2560 | Lisp_Object prop, string; | ||
| 2561 | int pos, pos_byte, end; | ||
| 2562 | enum prop_handled handled = HANDLED_NORMALLY; | ||
| 2563 | |||
| 2564 | if (STRINGP (it->string)) | ||
| 2565 | { | ||
| 2566 | pos = IT_STRING_CHARPOS (*it); | ||
| 2567 | pos_byte = IT_STRING_BYTEPOS (*it); | ||
| 2568 | string = it->string; | ||
| 2569 | } | ||
| 2570 | else | ||
| 2571 | { | ||
| 2572 | pos = IT_CHARPOS (*it); | ||
| 2573 | pos_byte = IT_BYTEPOS (*it); | ||
| 2574 | string = Qnil; | ||
| 2575 | } | ||
| 2576 | |||
| 2577 | /* If there's a valid composition and point is not inside of the | ||
| 2578 | composition (in the case that the composition is from the current | ||
| 2579 | buffer), draw a glyph composed from the composition components. */ | ||
| 2580 | if (find_composition (pos, -1, &pos, &end, &prop, string) | ||
| 2581 | && COMPOSITION_VALID_P (pos, end, prop) | ||
| 2582 | && (STRINGP (it->string) || (PT <= pos || PT >= end))) | ||
| 2583 | { | ||
| 2584 | int id = get_composition_id (pos, pos_byte, end - pos, prop, string); | ||
| 2585 | |||
| 2586 | if (id >= 0) | ||
| 2587 | { | ||
| 2588 | it->method = next_element_from_composition; | ||
| 2589 | it->cmp_id = id; | ||
| 2590 | it->cmp_len = COMPOSITION_LENGTH (prop); | ||
| 2591 | /* For a terminal, draw only the first character of the | ||
| 2592 | components. */ | ||
| 2593 | it->c = COMPOSITION_GLYPH (composition_table[id], 0); | ||
| 2594 | it->len = (STRINGP (it->string) | ||
| 2595 | ? string_char_to_byte (it->string, end) | ||
| 2596 | : CHAR_TO_BYTE (end)) - pos_byte; | ||
| 2597 | it->stop_charpos = end; | ||
| 2598 | handled = HANDLED_RETURN; | ||
| 2599 | } | ||
| 2600 | } | ||
| 2601 | |||
| 2602 | return handled; | ||
| 2603 | } | ||
| 2604 | |||
| 2605 | |||
| 2606 | |||
| 2607 | /*********************************************************************** | ||
| 2537 | Overlay strings | 2608 | Overlay strings |
| 2538 | ***********************************************************************/ | 2609 | ***********************************************************************/ |
| 2539 | 2610 | ||
| @@ -3340,8 +3411,8 @@ get_next_display_element (it) | |||
| 3340 | } | 3411 | } |
| 3341 | else | 3412 | else |
| 3342 | { | 3413 | { |
| 3343 | unsigned char work[4], *str; | 3414 | unsigned char str[MAX_MULTIBYTE_LENGTH]; |
| 3344 | int len = CHAR_STRING (it->c, work, str); | 3415 | int len = CHAR_STRING (it->c, str); |
| 3345 | int i; | 3416 | int i; |
| 3346 | GLYPH escape_glyph; | 3417 | GLYPH escape_glyph; |
| 3347 | 3418 | ||
| @@ -3442,6 +3513,23 @@ set_iterator_to_next (it) | |||
| 3442 | xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it))); | 3513 | xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it))); |
| 3443 | } | 3514 | } |
| 3444 | } | 3515 | } |
| 3516 | else if (it->method == next_element_from_composition) | ||
| 3517 | { | ||
| 3518 | xassert (it->cmp_id >= 0 && it ->cmp_id < n_compositions); | ||
| 3519 | if (STRINGP (it->string)) | ||
| 3520 | { | ||
| 3521 | IT_STRING_BYTEPOS (*it) += it->len; | ||
| 3522 | IT_STRING_CHARPOS (*it) += it->cmp_len; | ||
| 3523 | it->method = next_element_from_string; | ||
| 3524 | goto consider_string_end; | ||
| 3525 | } | ||
| 3526 | else | ||
| 3527 | { | ||
| 3528 | IT_BYTEPOS (*it) += it->len; | ||
| 3529 | IT_CHARPOS (*it) += it->cmp_len; | ||
| 3530 | it->method = next_element_from_buffer; | ||
| 3531 | } | ||
| 3532 | } | ||
| 3445 | else if (it->method == next_element_from_c_string) | 3533 | else if (it->method == next_element_from_c_string) |
| 3446 | { | 3534 | { |
| 3447 | /* Current display element of IT is from a C string. */ | 3535 | /* Current display element of IT is from a C string. */ |
| @@ -3862,7 +3950,7 @@ next_element_from_buffer (it) | |||
| 3862 | 3950 | ||
| 3863 | /* Get the next character, maybe multibyte. */ | 3951 | /* Get the next character, maybe multibyte. */ |
| 3864 | p = BYTE_POS_ADDR (IT_BYTEPOS (*it)); | 3952 | p = BYTE_POS_ADDR (IT_BYTEPOS (*it)); |
| 3865 | if (it->multibyte_p) | 3953 | if (it->multibyte_p && !ASCII_BYTE_P (*p)) |
| 3866 | { | 3954 | { |
| 3867 | int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE) | 3955 | int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE) |
| 3868 | - IT_BYTEPOS (*it)); | 3956 | - IT_BYTEPOS (*it)); |
| @@ -3939,6 +4027,22 @@ run_redisplay_end_trigger_hook (it) | |||
| 3939 | } | 4027 | } |
| 3940 | 4028 | ||
| 3941 | 4029 | ||
| 4030 | /* Deliver a composition display element. The iterator IT is already | ||
| 4031 | filled with composition information (done in | ||
| 4032 | handle_composition_prop). Value is always 1. */ | ||
| 4033 | |||
| 4034 | static int | ||
| 4035 | next_element_from_composition (it) | ||
| 4036 | struct it *it; | ||
| 4037 | { | ||
| 4038 | it->what = IT_COMPOSITION; | ||
| 4039 | it->position = (STRINGP (it->string) | ||
| 4040 | ? it->current.string_pos | ||
| 4041 | : it->current.pos); | ||
| 4042 | return 1; | ||
| 4043 | } | ||
| 4044 | |||
| 4045 | |||
| 3942 | 4046 | ||
| 3943 | /*********************************************************************** | 4047 | /*********************************************************************** |
| 3944 | Moving an iterator without producing glyphs | 4048 | Moving an iterator without producing glyphs |
| @@ -4673,14 +4777,14 @@ message_dolog (m, len, nlflag, multibyte) | |||
| 4673 | { | 4777 | { |
| 4674 | int i, c, nbytes; | 4778 | int i, c, nbytes; |
| 4675 | unsigned char *msg = (unsigned char *) m; | 4779 | unsigned char *msg = (unsigned char *) m; |
| 4676 | unsigned char *str, work[4]; | 4780 | unsigned char str[MAX_MULTIBYTE_LENGTH]; |
| 4677 | /* Convert a single-byte string to multibyte | 4781 | /* Convert a single-byte string to multibyte |
| 4678 | for the *Message* buffer. */ | 4782 | for the *Message* buffer. */ |
| 4679 | for (i = 0; i < len; i++) | 4783 | for (i = 0; i < len; i++) |
| 4680 | { | 4784 | { |
| 4681 | c = unibyte_char_to_multibyte (msg[i]); | 4785 | c = unibyte_char_to_multibyte (msg[i]); |
| 4682 | nbytes = CHAR_STRING (c, work, str); | 4786 | nbytes = CHAR_STRING (c, str); |
| 4683 | insert_1_both (work, 1, nbytes, 1, 0, 0); | 4787 | insert_1_both (str, 1, nbytes, 1, 0, 0); |
| 4684 | } | 4788 | } |
| 4685 | } | 4789 | } |
| 4686 | else if (len) | 4790 | else if (len) |
| @@ -5780,14 +5884,14 @@ set_message_1 (s, string, nbytes, multibyte_p) | |||
| 5780 | /* Convert from single-byte to multi-byte. */ | 5884 | /* Convert from single-byte to multi-byte. */ |
| 5781 | int i, c, n; | 5885 | int i, c, n; |
| 5782 | unsigned char *msg = (unsigned char *) s; | 5886 | unsigned char *msg = (unsigned char *) s; |
| 5783 | unsigned char *str, work[4]; | 5887 | unsigned char str[MAX_MULTIBYTE_LENGTH]; |
| 5784 | 5888 | ||
| 5785 | /* Convert a single-byte string to multibyte. */ | 5889 | /* Convert a single-byte string to multibyte. */ |
| 5786 | for (i = 0; i < nbytes; i++) | 5890 | for (i = 0; i < nbytes; i++) |
| 5787 | { | 5891 | { |
| 5788 | c = unibyte_char_to_multibyte (msg[i]); | 5892 | c = unibyte_char_to_multibyte (msg[i]); |
| 5789 | n = CHAR_STRING (c, work, str); | 5893 | n = CHAR_STRING (c, str); |
| 5790 | insert_1_both (work, 1, n, 1, 0, 0); | 5894 | insert_1_both (str, 1, n, 1, 0, 0); |
| 5791 | } | 5895 | } |
| 5792 | } | 5896 | } |
| 5793 | else | 5897 | else |
| @@ -6953,6 +7057,43 @@ redisplay () | |||
| 6953 | redisplay_internal (0); | 7057 | redisplay_internal (0); |
| 6954 | } | 7058 | } |
| 6955 | 7059 | ||
| 7060 | /* Return 1 if point moved out of or into a composition. Otherwise | ||
| 7061 | return 0. PREV_BUF and PREV_PT are the last point buffer and | ||
| 7062 | position. BUF and PT are the current point buffer and position. */ | ||
| 7063 | |||
| 7064 | int | ||
| 7065 | check_point_in_composition (prev_buf, prev_pt, buf, pt) | ||
| 7066 | struct buffer *prev_buf, *buf; | ||
| 7067 | int prev_pt, pt; | ||
| 7068 | { | ||
| 7069 | int start, end; | ||
| 7070 | Lisp_Object prop; | ||
| 7071 | Lisp_Object buffer; | ||
| 7072 | |||
| 7073 | XSETBUFFER (buffer, buf); | ||
| 7074 | /* Check a composition at the last point if point moved within the | ||
| 7075 | same buffer. */ | ||
| 7076 | if (prev_buf == buf) | ||
| 7077 | { | ||
| 7078 | if (prev_pt == pt) | ||
| 7079 | /* Point didn't move. */ | ||
| 7080 | return 0; | ||
| 7081 | |||
| 7082 | if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf) | ||
| 7083 | && find_composition (prev_pt, -1, &start, &end, &prop, buffer) | ||
| 7084 | && COMPOSITION_VALID_P (start, end, prop) | ||
| 7085 | && start < prev_pt && end > prev_pt) | ||
| 7086 | /* The last point was within the composition. Return 1 iff | ||
| 7087 | point moved out of the composition. */ | ||
| 7088 | return (pt <= start || pt >= end); | ||
| 7089 | } | ||
| 7090 | |||
| 7091 | /* Check a composition at the current point. */ | ||
| 7092 | return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf) | ||
| 7093 | && find_composition (pt, -1, &start, &end, &prop, buffer) | ||
| 7094 | && COMPOSITION_VALID_P (start, end, prop) | ||
| 7095 | && start < pt && end > pt); | ||
| 7096 | } | ||
| 6956 | 7097 | ||
| 6957 | /* Reconsider the setting of B->clip_changed which is displayed | 7098 | /* Reconsider the setting of B->clip_changed which is displayed |
| 6958 | in window W. */ | 7099 | in window W. */ |
| @@ -6970,6 +7111,29 @@ reconsider_clip_changes (w, b) | |||
| 6970 | && w->current_matrix->zv == BUF_ZV (b) | 7111 | && w->current_matrix->zv == BUF_ZV (b) |
| 6971 | && w->current_matrix->begv == BUF_BEGV (b)) | 7112 | && w->current_matrix->begv == BUF_BEGV (b)) |
| 6972 | b->clip_changed = 0; | 7113 | b->clip_changed = 0; |
| 7114 | |||
| 7115 | /* If display wasn't paused, and W is not a tool bar window, see if | ||
| 7116 | point has been moved into or out of a composition. In that case, | ||
| 7117 | we set b->clip_changed to 1 to force updating the screen. If | ||
| 7118 | b->clip_changed has already been set to 1, we can skip this | ||
| 7119 | check. */ | ||
| 7120 | if (!b->clip_changed | ||
| 7121 | && BUFFERP (w->buffer) && !NILP (w->window_end_valid)) | ||
| 7122 | { | ||
| 7123 | int pt; | ||
| 7124 | |||
| 7125 | if (w == XWINDOW (selected_window)) | ||
| 7126 | pt = BUF_PT (current_buffer); | ||
| 7127 | else | ||
| 7128 | pt = marker_position (w->pointm); | ||
| 7129 | |||
| 7130 | if ((w->current_matrix->buffer != XBUFFER (w->buffer) | ||
| 7131 | || pt != w->last_point) | ||
| 7132 | && check_point_in_composition (w->current_matrix->buffer, | ||
| 7133 | w->last_point, | ||
| 7134 | XBUFFER (w->buffer), pt)) | ||
| 7135 | b->clip_changed = 1; | ||
| 7136 | } | ||
| 6973 | } | 7137 | } |
| 6974 | 7138 | ||
| 6975 | 7139 | ||
| @@ -7790,13 +7954,10 @@ disp_char_vector (dp, c) | |||
| 7790 | return (dp->contents[c]); | 7954 | return (dp->contents[c]); |
| 7791 | 7955 | ||
| 7792 | SPLIT_NON_ASCII_CHAR (c, code[0], code[1], code[2]); | 7956 | SPLIT_NON_ASCII_CHAR (c, code[0], code[1], code[2]); |
| 7793 | if (code[0] != CHARSET_COMPOSITION) | 7957 | if (code[1] < 32) |
| 7794 | { | 7958 | code[1] = -1; |
| 7795 | if (code[1] < 32) | 7959 | else if (code[2] < 32) |
| 7796 | code[1] = -1; | 7960 | code[2] = -1; |
| 7797 | else if (code[2] < 32) | ||
| 7798 | code[2] = -1; | ||
| 7799 | } | ||
| 7800 | 7961 | ||
| 7801 | /* Here, the possible range of code[0] (== charset ID) is | 7962 | /* Here, the possible range of code[0] (== charset ID) is |
| 7802 | 128..max_charset. Since the top level char table contains data | 7963 | 128..max_charset. Since the top level char table contains data |
| @@ -11864,9 +12025,7 @@ decode_mode_spec_coding (coding_system, buf, eol_flag) | |||
| 11864 | else if (INTEGERP (eoltype) | 12025 | else if (INTEGERP (eoltype) |
| 11865 | && CHAR_VALID_P (XINT (eoltype), 0)) | 12026 | && CHAR_VALID_P (XINT (eoltype), 0)) |
| 11866 | { | 12027 | { |
| 11867 | unsigned char work[4]; | 12028 | eol_str_len = CHAR_STRING (XINT (eoltype), eol_str); |
| 11868 | |||
| 11869 | eol_str_len = CHAR_STRING (XINT (eoltype), work, eol_str); | ||
| 11870 | } | 12029 | } |
| 11871 | else | 12030 | else |
| 11872 | { | 12031 | { |