aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenichi Handa1999-12-15 00:23:27 +0000
committerKenichi Handa1999-12-15 00:23:27 +0000
commit260a86a07c364e6dfac1cf1e1476575744461124 (patch)
treeab77538993c8f95ca40cd818182ff25744c25632 /src
parentf02d6d5cbbff57ab7985cb055ca98ac842d9de36 (diff)
downloademacs-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.c203
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
533static enum prop_handled handle_face_prop P_ ((struct it *)); 533static enum prop_handled handle_face_prop P_ ((struct it *));
534static enum prop_handled handle_invisible_prop P_ ((struct it *)); 534static enum prop_handled handle_invisible_prop P_ ((struct it *));
535static enum prop_handled handle_display_prop P_ ((struct it *)); 535static enum prop_handled handle_display_prop P_ ((struct it *));
536static enum prop_handled handle_composition_prop P_ ((struct it *));
536static enum prop_handled handle_overlay_change P_ ((struct it *)); 537static enum prop_handled handle_overlay_change P_ ((struct it *));
537static enum prop_handled handle_fontified_prop P_ ((struct it *)); 538static 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 *));
646static int next_element_from_string P_ ((struct it *)); 648static int next_element_from_string P_ ((struct it *));
647static int next_element_from_c_string P_ ((struct it *)); 649static int next_element_from_c_string P_ ((struct it *));
648static int next_element_from_buffer P_ ((struct it *)); 650static int next_element_from_buffer P_ ((struct it *));
651static int next_element_from_composition P_ ((struct it *));
649static int next_element_from_image P_ ((struct it *)); 652static int next_element_from_image P_ ((struct it *));
650static int next_element_from_stretch P_ ((struct it *)); 653static int next_element_from_stretch P_ ((struct it *));
651static void load_overlay_strings P_ ((struct it *)); 654static 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
2556static enum prop_handled
2557handle_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
4034static int
4035next_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
7064int
7065check_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 {