aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenichi Handa1998-02-20 01:40:47 +0000
committerKenichi Handa1998-02-20 01:40:47 +0000
commitc9c0f7cf48021bcbaf899525ba0d0fe1556aae8d (patch)
tree0cc690f28f94d6c73e8b266fda18266cae9fc3dd /src
parent2d9eea4477dda68e9fa018ddfa0dca19920d1fc2 (diff)
downloademacs-c9c0f7cf48021bcbaf899525ba0d0fe1556aae8d.tar.gz
emacs-c9c0f7cf48021bcbaf899525ba0d0fe1556aae8d.zip
(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.
Diffstat (limited to 'src')
-rw-r--r--src/indent.c202
1 files changed, 95 insertions, 107 deletions
diff --git a/src/indent.c b/src/indent.c
index 28a661dd9f1..733272ee97b 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -266,6 +266,67 @@ skip_invisible (pos, next_boundary_p, to, window)
266 return pos; 266 return pos;
267} 267}
268 268
269/* Set variables WIDTH and BYTES for a multibyte sequence starting at P.
270
271 C is *P which should satisfy `BASE_LEADING_CODE_P (c)'.
272
273 DP is a display table or NULL.
274
275 This macro is used in current_column_1, Fmove_to_column, and
276 compute_motion. */
277
278#define MULTIBYTE_BYTES_WIDTH(p, c, dp) \
279 do { \
280 unsigned char *pend = p + 1; \
281 \
282 wide_column = 0; \
283 while (! CHAR_HEAD_P (*pend)) pend++; \
284 \
285 if (c == LEADING_CODE_COMPOSITION) \
286 { \
287 int id = str_cmpchar_id (p, pend - p); \
288 int ch = MAKE_COMPOSITE_CHAR (id); \
289 \
290 if (id >= 0) \
291 { \
292 bytes = cmpchar_table[id]->len; \
293 if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, ch))) \
294 width = XVECTOR (DISP_CHAR_VECTOR (dp, ch))->size; \
295 else \
296 wide_column = width = cmpchar_table[id]->width; \
297 } \
298 else \
299 { \
300 bytes = 1; \
301 width = 4; \
302 } \
303 } \
304 else \
305 { \
306 bytes = BYTES_BY_CHAR_HEAD (c); \
307 if (bytes >= 2 && bytes <= pend - p) \
308 { \
309 int ch; \
310 \
311 if (dp && (ch = STRING_CHAR (p, bytes), \
312 VECTORP (DISP_CHAR_VECTOR (dp, ch)))) \
313 width = XVECTOR (DISP_CHAR_VECTOR (dp, ch))->size; \
314 else \
315 wide_column = width = WIDTH_BY_CHAR_HEAD (c); \
316 } \
317 else \
318 { \
319 bytes = 1; \
320 width = 4; \
321 } \
322 } \
323 if (p + bytes < pend) \
324 { \
325 width += 4 * (pend - (p + bytes)); \
326 bytes = pend - p; \
327 } \
328 } while (0)
329
269DEFUN ("current-column", Fcurrent_column, Scurrent_column, 0, 0, 0, 330DEFUN ("current-column", Fcurrent_column, Scurrent_column, 0, 0, 0,
270 "Return the horizontal position of point. Beginning of line is column 0.\n\ 331 "Return the horizontal position of point. Beginning of line is column 0.\n\
271This is calculated by adding together the widths of all the displayed\n\ 332This is calculated by adding together the widths of all the displayed\n\
@@ -439,7 +500,9 @@ current_column_1 ()
439 } 500 }
440 501
441 c = FETCH_BYTE (scan_byte); 502 c = FETCH_BYTE (scan_byte);
442 if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c))) 503 if (dp != 0
504 && ! (multibyte && BASE_LEADING_CODE_P (c))
505 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
443 { 506 {
444 col += XVECTOR (DISP_CHAR_VECTOR (dp, c))->size; 507 col += XVECTOR (DISP_CHAR_VECTOR (dp, c))->size;
445 scan++; 508 scan++;
@@ -460,42 +523,14 @@ current_column_1 ()
460 } 523 }
461 else if (multibyte && BASE_LEADING_CODE_P (c)) 524 else if (multibyte && BASE_LEADING_CODE_P (c))
462 { 525 {
463 scan_byte--; 526 unsigned char *ptr;
464 /* Start of multi-byte form. */ 527 int bytes, width, wide_column;
465 if (c == LEADING_CODE_COMPOSITION)
466 {
467 unsigned char *ptr = BYTE_POS_ADDR (scan_byte);
468 528
469 int cmpchar_id 529 scan_byte--;
470 = str_cmpchar_id (ptr, next_boundary_byte - scan_byte); 530 ptr = BYTE_POS_ADDR (scan_byte);
471 if (cmpchar_id >= 0) 531 MULTIBYTE_BYTES_WIDTH (ptr, c, dp);
472 { 532 scan_byte += bytes;
473 scan_byte += cmpchar_table[cmpchar_id]->len; 533 col += width;
474 col += cmpchar_table[cmpchar_id]->width;
475 }
476 else
477 { /* invalid composite character */
478 scan_byte++;
479 col += 4;
480 }
481 }
482 else
483 {
484 /* Here, we check that the following bytes are valid
485 constituents of multi-byte form. */
486 int len = BYTES_BY_CHAR_HEAD (c), i;
487
488 for (i = 1, scan_byte++; i < len; i++, scan_byte++)
489 /* We don't need range checking for PTR because there
490 are anchors (`\0') at GAP and Z. */
491 if (CHAR_HEAD_P (FETCH_BYTE (scan_byte)))
492 break;
493
494 if (i < len)
495 col += 4, scan_byte -= i - 1;
496 else
497 col += WIDTH_BY_CHAR_HEAD (c);
498 }
499 } 534 }
500 else if (ctl_arrow && (c < 040 || c == 0177)) 535 else if (ctl_arrow && (c < 040 || c == 0177))
501 col += 2; 536 col += 2;
@@ -838,7 +873,9 @@ The return value is the current column.")
838 break; 873 break;
839 874
840 c = FETCH_BYTE (pos_byte); 875 c = FETCH_BYTE (pos_byte);
841 if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c))) 876 if (dp != 0
877 && ! (multibyte && BASE_LEADING_CODE_P (c))
878 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
842 { 879 {
843 col += XVECTOR (DISP_CHAR_VECTOR (dp, c))->size; 880 col += XVECTOR (DISP_CHAR_VECTOR (dp, c))->size;
844 pos_byte++; 881 pos_byte++;
@@ -867,41 +904,13 @@ The return value is the current column.")
867 { 904 {
868 /* Start of multi-byte form. */ 905 /* Start of multi-byte form. */
869 unsigned char *ptr; 906 unsigned char *ptr;
907 int bytes, width, wide_column;
870 908
871 pos_byte--; /* rewind to the character head */ 909 pos_byte--;
872 ptr = BYTE_POS_ADDR (pos_byte); 910 ptr = BYTE_POS_ADDR (pos_byte);
873 if (c == LEADING_CODE_COMPOSITION) 911 MULTIBYTE_BYTES_WIDTH (ptr, c, dp);
874 { 912 pos_byte += bytes;
875 int cmpchar_id = str_cmpchar_id (ptr, end_byte - pos_byte); 913 col += width;
876
877 if (cmpchar_id >= 0)
878 {
879 col += cmpchar_table[cmpchar_id]->width;
880 pos_byte += cmpchar_table[cmpchar_id]->len;
881 }
882 else
883 { /* invalid composite character */
884 col += 4;
885 pos_byte++;
886 }
887 }
888 else
889 {
890 /* Here, we check that the following bytes are valid
891 constituents of multi-byte form. */
892 int len = BYTES_BY_CHAR_HEAD (c), i;
893
894 for (i = 1, ptr++; i < len; i++, ptr++)
895 /* We don't need range checking for PTR because there
896 are anchors (`\0') both at GPT and Z. */
897 if (CHAR_HEAD_P (*ptr))
898 break;
899
900 if (i < len)
901 col += 4, pos_byte++;
902 else
903 col += WIDTH_BY_CHAR_HEAD (c), pos_byte += i;
904 }
905 } 914 }
906 else 915 else
907 col += 4; 916 col += 4;
@@ -1046,8 +1055,8 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
1046 Lisp_Object window; 1055 Lisp_Object window;
1047 1056
1048 int multibyte = !NILP (current_buffer->enable_multibyte_characters); 1057 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
1049 int wide_column = 0; /* Set to 1 when a previous character 1058 int wide_column_end_hpos = 0; /* Horizontal position at the end of
1050 is wide-colomn. */ 1059 last wide-column character. */
1051 int prev_pos; /* Previous buffer position. */ 1060 int prev_pos; /* Previous buffer position. */
1052 int prev_pos_byte; /* Previous buffer position. */ 1061 int prev_pos_byte; /* Previous buffer position. */
1053 int contin_hpos; /* HPOS of last column of continued line. */ 1062 int contin_hpos; /* HPOS of last column of continued line. */
@@ -1187,7 +1196,7 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
1187 /* Remember the previous value. */ 1196 /* Remember the previous value. */
1188 prev_tab_offset = tab_offset; 1197 prev_tab_offset = tab_offset;
1189 1198
1190 if (wide_column) 1199 if (wide_column_end_hpos > width)
1191 { 1200 {
1192 hpos -= prev_hpos; 1201 hpos -= prev_hpos;
1193 tab_offset += prev_hpos; 1202 tab_offset += prev_hpos;
@@ -1223,7 +1232,7 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
1223 */ 1232 */
1224 1233
1225 if (contin_hpos && prev_hpos == 0 1234 if (contin_hpos && prev_hpos == 0
1226 && contin_hpos < width && !wide_column) 1235 && contin_hpos < width && !wide_column_end_hpos)
1227 { 1236 {
1228 /* Line breaking occurs in the middle of multi-column 1237 /* Line breaking occurs in the middle of multi-column
1229 character. Go back to previous line. */ 1238 character. Go back to previous line. */
@@ -1240,7 +1249,8 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
1240 if (vpos > tovpos || vpos == tovpos && hpos >= tohpos) 1249 if (vpos > tovpos || vpos == tovpos && hpos >= tohpos)
1241 { 1250 {
1242 if (contin_hpos && prev_hpos == 0 1251 if (contin_hpos && prev_hpos == 0
1243 && ((hpos > tohpos && contin_hpos == width) || wide_column)) 1252 && ((hpos > tohpos && contin_hpos == width)
1253 || (wide_column_end_hpos > width)))
1244 { /* Line breaks because we can't put the character at the 1254 { /* Line breaks because we can't put the character at the
1245 previous line any more. It is not the multi-column 1255 previous line any more. It is not the multi-column
1246 character continued in middle. Go back to previous 1256 character continued in middle. Go back to previous
@@ -1260,7 +1270,7 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
1260 prev_hpos = hpos; 1270 prev_hpos = hpos;
1261 prev_pos = pos; 1271 prev_pos = pos;
1262 prev_pos_byte = pos_byte; 1272 prev_pos_byte = pos_byte;
1263 wide_column = 0; 1273 wide_column_end_hpos = 0;
1264 1274
1265 /* Consult the width run cache to see if we can avoid inspecting 1275 /* Consult the width run cache to see if we can avoid inspecting
1266 the text character-by-character. */ 1276 the text character-by-character. */
@@ -1348,8 +1358,9 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
1348 } 1358 }
1349 } 1359 }
1350 1360
1351 if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c)) 1361 if (dp != 0
1352 && ! (multibyte && BASE_LEADING_CODE_P (c))) 1362 && ! (multibyte && BASE_LEADING_CODE_P (c))
1363 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
1353 hpos += XVECTOR (DISP_CHAR_VECTOR (dp, c))->size; 1364 hpos += XVECTOR (DISP_CHAR_VECTOR (dp, c))->size;
1354 else if (c >= 040 && c < 0177) 1365 else if (c >= 040 && c < 0177)
1355 hpos++; 1366 hpos++;
@@ -1429,37 +1440,14 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
1429 { 1440 {
1430 /* Start of multi-byte form. */ 1441 /* Start of multi-byte form. */
1431 unsigned char *ptr; 1442 unsigned char *ptr;
1432 int len, actual_len; 1443 int bytes, width, wide_column;
1433
1434 pos--, pos_byte--; /* rewind POS */
1435 1444
1445 pos_byte--; /* rewind POS_BYTE */
1436 ptr = BYTE_POS_ADDR (pos_byte); 1446 ptr = BYTE_POS_ADDR (pos_byte);
1437 len = BUFFER_CEILING_OF (pos_byte) - pos_byte + 1; 1447 MULTIBYTE_BYTES_WIDTH (ptr, c, dp);
1438 1448 pos_byte += bytes;
1439 c = STRING_CHAR_AND_LENGTH (ptr, len, actual_len); 1449 wide_column_end_hpos = hpos + wide_column;
1440 1450 hpos += width;
1441 if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
1442 hpos += XVECTOR (DISP_CHAR_VECTOR (dp, c))->size;
1443 else if (actual_len == 1)
1444 hpos += 4;
1445 else if (COMPOSITE_CHAR_P (c))
1446 {
1447 int id = COMPOSITE_CHAR_ID (c);
1448 int width = (id < n_cmpchars) ? cmpchar_table[id]->width : 0;
1449 hpos += width;
1450 if (width > 1)
1451 wide_column = 1;
1452 }
1453 else
1454 {
1455 int width = WIDTH_BY_CHAR_HEAD (*ptr);
1456 hpos += width;
1457 if (width > 1)
1458 wide_column = 1;
1459 }
1460
1461 pos++;
1462 pos_byte += actual_len;
1463 } 1451 }
1464 else 1452 else
1465 hpos += (ctl_arrow && c < 0200) ? 2 : 4; 1453 hpos += (ctl_arrow && c < 0200) ? 2 : 4;