return pos;
}
\f
+/* 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\
}
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++;
}
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;
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++;
{
/* Start of multi-byte form. */
unsigned char *ptr;
+ int bytes, width, wide_column;
- pos_byte--; /* rewind to the character head */
+ pos_byte--;
ptr = BYTE_POS_ADDR (pos_byte);
- if (c == LEADING_CODE_COMPOSITION)
- {
- int cmpchar_id = str_cmpchar_id (ptr, end_byte - pos_byte);
-
- 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;
- }
+ MULTIBYTE_BYTES_WIDTH (ptr, c, dp);
+ pos_byte += bytes;
+ col += width;
}
else
col += 4;
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. */
/* 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;
*/
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. */
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
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. */
}
}
- 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++;
{
/* Start of multi-byte form. */
unsigned char *ptr;
- int len, actual_len;
-
- pos--, pos_byte--; /* rewind POS */
+ int bytes, width, wide_column;
+ pos_byte--; /* rewind POS_BYTE */
ptr = BYTE_POS_ADDR (pos_byte);
- len = BUFFER_CEILING_OF (pos_byte) - pos_byte + 1;
-
- c = STRING_CHAR_AND_LENGTH (ptr, len, actual_len);
-
- 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;
+ 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;