Mercurial > emacs
changeset 35407:916718dc2950
(strwidth): Use c_string_width.
(c_string_width): New function.
(lisp_string_width): New arguments PRECISION, NCHARS, NBYTES.
Caller changed.
author | Kenichi Handa <handa@m17n.org> |
---|---|
date | Fri, 19 Jan 2001 05:22:21 +0000 |
parents | 06c94b0d85d2 |
children | 9a2cf1e0032c |
files | src/charset.c |
diffstat | 1 files changed, 111 insertions(+), 38 deletions(-) [+] |
line wrap: on
line diff
--- a/src/charset.c Fri Jan 19 05:22:01 2001 +0000 +++ b/src/charset.c Fri Jan 19 05:22:21 2001 +0000 @@ -1233,67 +1233,140 @@ unsigned char *str; int len; { - unsigned char *endp = str + len; + return c_string_width (str, len, -1, NULL, NULL); +} + +/* Return width of string STR of length LEN when displayed in the + current buffer. The width is measured by how many columns it + occupies on the screen. If PRECISION > 0, return the width of + longest substring that doesn't exceed PRECISION, and set number of + characters and bytes of the substring in *NCHARS and *NBYTES + respectively. */ + +int +c_string_width (str, len, precision, nchars, nbytes) + unsigned char *str; + int precision, *nchars, *nbytes; +{ + int i = 0, i_byte = 0; int width = 0; + int chars; struct Lisp_Char_Table *dp = buffer_display_table (); - while (str < endp) + while (i_byte < len) { - Lisp_Object disp; - int thislen; - int c = STRING_CHAR_AND_LENGTH (str, endp - str, thislen); + int bytes, thiswidth; + Lisp_Object val; + + if (dp) + { + int c = STRING_CHAR_AND_LENGTH (str + i_byte, len - i_byte, bytes); - /* Get the way the display table would display it. */ - if (dp) - disp = DISP_CHAR_VECTOR (dp, c); + chars = 1; + val = DISP_CHAR_VECTOR (dp, c); + if (VECTORP (val)) + thiswidth = XVECTOR (val)->size; + else + thiswidth = ONE_BYTE_CHAR_WIDTH (str[i_byte]); + } else - disp = Qnil; + { + chars = 1; + PARSE_MULTIBYTE_SEQ (str + i_byte, len - i_byte, bytes); + thiswidth = ONE_BYTE_CHAR_WIDTH (str[i_byte]); + } - if (VECTORP (disp)) - width += XVECTOR (disp)->size; - else - width += ONE_BYTE_CHAR_WIDTH (*str); + if (precision > 0 + && (width + thiswidth > precision)) + { + *nchars = i; + *nbytes = i_byte; + return width; + } + i++; + i_byte += bytes; + width += thiswidth; + } - str += thislen; + if (precision > 0) + { + *nchars = i; + *nbytes = i_byte; } + return width; } +/* Return width of Lisp string STRING when displayed in the current + buffer. The width is measured by how many columns it occupies on + the screen while paying attention to compositions. If PRECISION > + 0, return the width of longest substring that doesn't exceed + PRECISION, and set number of characters and bytes of the substring + in *NCHARS and *NBYTES respectively. */ + int -lisp_string_width (str) - Lisp_Object str; +lisp_string_width (string, precision, nchars, nbytes) + Lisp_Object string; + int precision, *nchars, *nbytes; { - int len = XSTRING (str)->size, len_byte = STRING_BYTES (XSTRING (str)); - int i = 0, i_byte; + int len = XSTRING (string)->size; + int len_byte = STRING_BYTES (XSTRING (string)); + unsigned char *str = XSTRING (string)->data; + int i = 0, i_byte = 0; int width = 0; - int start, end, start_byte; - Lisp_Object prop; - int cmp_id; + struct Lisp_Char_Table *dp = buffer_display_table (); while (i < len) { - if (find_composition (i, len, &start, &end, &prop, str)) + int chars, bytes, thiswidth; + Lisp_Object val; + int cmp_id; + int ignore, end; + + if (find_composition (i, -1, &ignore, &end, &val, string) + && ((cmp_id = get_composition_id (i, i_byte, end - i, val, string)) + >= 0)) { - start_byte = string_char_to_byte (str, start); - if (i < start) - { - i_byte = string_char_to_byte (str, i); - width += strwidth (XSTRING (str)->data + i_byte, - start_byte - i_byte); - } - cmp_id - = get_composition_id (start, start_byte, end - start, prop, str); - if (cmp_id >= 0) - width += composition_table[cmp_id]->width; - i = end; + thiswidth = composition_table[cmp_id]->width; + chars = end - i; + bytes = string_char_to_byte (string, end) - i_byte; + } + else if (dp) + { + int c = STRING_CHAR_AND_LENGTH (str + i_byte, len - i_byte, bytes); + + chars = 1; + val = DISP_CHAR_VECTOR (dp, c); + if (VECTORP (val)) + thiswidth = XVECTOR (val)->size; + else + thiswidth = ONE_BYTE_CHAR_WIDTH (str[i_byte]); } else { - i_byte = string_char_to_byte (str, i); - width += strwidth (XSTRING (str)->data + i_byte, len_byte - i_byte); - i = len; + chars = 1; + PARSE_MULTIBYTE_SEQ (str + i_byte, len_byte - i_byte, bytes); + thiswidth = ONE_BYTE_CHAR_WIDTH (str[i_byte]); + } + + if (precision > 0 + && (width + thiswidth > precision)) + { + *nchars = i; + *nbytes = i_byte; + return width; } + i += chars; + i_byte += bytes; + width += thiswidth; + } + + if (precision > 0) + { + *nchars = i; + *nbytes = i_byte; } + return width; } @@ -1310,7 +1383,7 @@ Lisp_Object val; CHECK_STRING (str, 0); - XSETFASTINT (val, lisp_string_width (str)); + XSETFASTINT (val, lisp_string_width (str, -1, NULL, NULL)); return val; }