Mercurial > emacs
changeset 20938:12e635300b44
(MULTIBYTE_BYTES_WIDTH): New macro.
(current_column_1): Don't follow a display table for a heading
byte of a multibyte character. Use the macro
MULTIBYTE_BYTES_WIDTH.
(Fmove_to_column): Likewise.
(compute_motion): Likewise. Handling of wide-column character
fixed.
author | Kenichi Handa <handa@m17n.org> |
---|---|
date | Fri, 20 Feb 1998 01:40:47 +0000 |
parents | f77dcb2556c5 |
children | fea711fa5768 |
files | src/indent.c |
diffstat | 1 files changed, 97 insertions(+), 109 deletions(-) [+] |
line wrap: on
line diff
--- a/src/indent.c Fri Feb 20 01:40:47 1998 +0000 +++ b/src/indent.c Fri Feb 20 01:40:47 1998 +0000 @@ -266,6 +266,67 @@ return pos; } +/* Set variables WIDTH and BYTES for a multibyte sequence starting at P. + + C is *P which should satisfy `BASE_LEADING_CODE_P (c)'. + + DP is a display table or NULL. + + This macro is used in current_column_1, Fmove_to_column, and + compute_motion. */ + +#define MULTIBYTE_BYTES_WIDTH(p, c, dp) \ + do { \ + unsigned char *pend = p + 1; \ + \ + wide_column = 0; \ + while (! CHAR_HEAD_P (*pend)) pend++; \ + \ + if (c == LEADING_CODE_COMPOSITION) \ + { \ + int id = str_cmpchar_id (p, pend - p); \ + int ch = MAKE_COMPOSITE_CHAR (id); \ + \ + if (id >= 0) \ + { \ + bytes = cmpchar_table[id]->len; \ + if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, ch))) \ + width = XVECTOR (DISP_CHAR_VECTOR (dp, ch))->size; \ + else \ + wide_column = width = cmpchar_table[id]->width; \ + } \ + else \ + { \ + bytes = 1; \ + width = 4; \ + } \ + } \ + else \ + { \ + bytes = BYTES_BY_CHAR_HEAD (c); \ + if (bytes >= 2 && bytes <= pend - p) \ + { \ + int ch; \ + \ + if (dp && (ch = STRING_CHAR (p, bytes), \ + VECTORP (DISP_CHAR_VECTOR (dp, ch)))) \ + width = XVECTOR (DISP_CHAR_VECTOR (dp, ch))->size; \ + else \ + wide_column = width = WIDTH_BY_CHAR_HEAD (c); \ + } \ + else \ + { \ + bytes = 1; \ + width = 4; \ + } \ + } \ + if (p + bytes < pend) \ + { \ + width += 4 * (pend - (p + bytes)); \ + bytes = pend - p; \ + } \ + } while (0) + DEFUN ("current-column", Fcurrent_column, Scurrent_column, 0, 0, 0, "Return the horizontal position of point. Beginning of line is column 0.\n\ This is calculated by adding together the widths of all the displayed\n\ @@ -439,7 +500,9 @@ } c = FETCH_BYTE (scan_byte); - if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c))) + if (dp != 0 + && ! (multibyte && BASE_LEADING_CODE_P (c)) + && VECTORP (DISP_CHAR_VECTOR (dp, c))) { col += XVECTOR (DISP_CHAR_VECTOR (dp, c))->size; scan++; @@ -460,42 +523,14 @@ } else if (multibyte && BASE_LEADING_CODE_P (c)) { - scan_byte--; - /* Start of multi-byte form. */ - if (c == LEADING_CODE_COMPOSITION) - { - unsigned char *ptr = BYTE_POS_ADDR (scan_byte); + unsigned char *ptr; + int bytes, width, wide_column; - int cmpchar_id - = str_cmpchar_id (ptr, next_boundary_byte - scan_byte); - if (cmpchar_id >= 0) - { - scan_byte += cmpchar_table[cmpchar_id]->len; - col += cmpchar_table[cmpchar_id]->width; - } - else - { /* invalid composite character */ - scan_byte++; - col += 4; - } - } - else - { - /* Here, we check that the following bytes are valid - constituents of multi-byte form. */ - int len = BYTES_BY_CHAR_HEAD (c), i; - - for (i = 1, scan_byte++; i < len; i++, scan_byte++) - /* We don't need range checking for PTR because there - are anchors (`\0') at GAP and Z. */ - if (CHAR_HEAD_P (FETCH_BYTE (scan_byte))) - break; - - if (i < len) - col += 4, scan_byte -= i - 1; - else - col += WIDTH_BY_CHAR_HEAD (c); - } + scan_byte--; + ptr = BYTE_POS_ADDR (scan_byte); + MULTIBYTE_BYTES_WIDTH (ptr, c, dp); + scan_byte += bytes; + col += width; } else if (ctl_arrow && (c < 040 || c == 0177)) col += 2; @@ -838,7 +873,9 @@ break; c = FETCH_BYTE (pos_byte); - if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c))) + if (dp != 0 + && ! (multibyte && BASE_LEADING_CODE_P (c)) + && VECTORP (DISP_CHAR_VECTOR (dp, c))) { col += XVECTOR (DISP_CHAR_VECTOR (dp, c))->size; pos_byte++; @@ -867,41 +904,13 @@ { /* Start of multi-byte form. */ unsigned char *ptr; - - pos_byte--; /* rewind to the character head */ - ptr = BYTE_POS_ADDR (pos_byte); - if (c == LEADING_CODE_COMPOSITION) - { - int cmpchar_id = str_cmpchar_id (ptr, end_byte - pos_byte); + int bytes, width, wide_column; - if (cmpchar_id >= 0) - { - col += cmpchar_table[cmpchar_id]->width; - pos_byte += cmpchar_table[cmpchar_id]->len; - } - else - { /* invalid composite character */ - col += 4; - pos_byte++; - } - } - else - { - /* Here, we check that the following bytes are valid - constituents of multi-byte form. */ - int len = BYTES_BY_CHAR_HEAD (c), i; - - for (i = 1, ptr++; i < len; i++, ptr++) - /* We don't need range checking for PTR because there - are anchors (`\0') both at GPT and Z. */ - if (CHAR_HEAD_P (*ptr)) - break; - - if (i < len) - col += 4, pos_byte++; - else - col += WIDTH_BY_CHAR_HEAD (c), pos_byte += i; - } + pos_byte--; + ptr = BYTE_POS_ADDR (pos_byte); + MULTIBYTE_BYTES_WIDTH (ptr, c, dp); + pos_byte += bytes; + col += width; } else col += 4; @@ -1046,8 +1055,8 @@ Lisp_Object window; int multibyte = !NILP (current_buffer->enable_multibyte_characters); - int wide_column = 0; /* Set to 1 when a previous character - is wide-colomn. */ + int wide_column_end_hpos = 0; /* Horizontal position at the end of + last wide-column character. */ int prev_pos; /* Previous buffer position. */ int prev_pos_byte; /* Previous buffer position. */ int contin_hpos; /* HPOS of last column of continued line. */ @@ -1187,7 +1196,7 @@ /* Remember the previous value. */ prev_tab_offset = tab_offset; - if (wide_column) + if (wide_column_end_hpos > width) { hpos -= prev_hpos; tab_offset += prev_hpos; @@ -1223,7 +1232,7 @@ */ if (contin_hpos && prev_hpos == 0 - && contin_hpos < width && !wide_column) + && contin_hpos < width && !wide_column_end_hpos) { /* Line breaking occurs in the middle of multi-column character. Go back to previous line. */ @@ -1240,7 +1249,8 @@ if (vpos > tovpos || vpos == tovpos && hpos >= tohpos) { if (contin_hpos && prev_hpos == 0 - && ((hpos > tohpos && contin_hpos == width) || wide_column)) + && ((hpos > tohpos && contin_hpos == width) + || (wide_column_end_hpos > width))) { /* Line breaks because we can't put the character at the previous line any more. It is not the multi-column character continued in middle. Go back to previous @@ -1260,7 +1270,7 @@ prev_hpos = hpos; prev_pos = pos; prev_pos_byte = pos_byte; - wide_column = 0; + wide_column_end_hpos = 0; /* Consult the width run cache to see if we can avoid inspecting the text character-by-character. */ @@ -1348,8 +1358,9 @@ } } - if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c)) - && ! (multibyte && BASE_LEADING_CODE_P (c))) + if (dp != 0 + && ! (multibyte && BASE_LEADING_CODE_P (c)) + && VECTORP (DISP_CHAR_VECTOR (dp, c))) hpos += XVECTOR (DISP_CHAR_VECTOR (dp, c))->size; else if (c >= 040 && c < 0177) hpos++; @@ -1429,37 +1440,14 @@ { /* Start of multi-byte form. */ unsigned char *ptr; - int len, actual_len; - - pos--, pos_byte--; /* rewind POS */ - - ptr = BYTE_POS_ADDR (pos_byte); - len = BUFFER_CEILING_OF (pos_byte) - pos_byte + 1; - - c = STRING_CHAR_AND_LENGTH (ptr, len, actual_len); + int bytes, width, wide_column; - if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c))) - hpos += XVECTOR (DISP_CHAR_VECTOR (dp, c))->size; - else if (actual_len == 1) - hpos += 4; - else if (COMPOSITE_CHAR_P (c)) - { - int id = COMPOSITE_CHAR_ID (c); - int width = (id < n_cmpchars) ? cmpchar_table[id]->width : 0; - hpos += width; - if (width > 1) - wide_column = 1; - } - else - { - int width = WIDTH_BY_CHAR_HEAD (*ptr); - hpos += width; - if (width > 1) - wide_column = 1; - } - - pos++; - pos_byte += actual_len; + pos_byte--; /* rewind POS_BYTE */ + ptr = BYTE_POS_ADDR (pos_byte); + MULTIBYTE_BYTES_WIDTH (ptr, c, dp); + pos_byte += bytes; + wide_column_end_hpos = hpos + wide_column; + hpos += width; } else hpos += (ctl_arrow && c < 0200) ? 2 : 4;