diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2012-02-10 10:58:48 -0800 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2012-02-10 10:58:48 -0800 |
commit | 6e6c82a4e687708d5a7a3887f92db45bd74da276 (patch) | |
tree | 85dc3105240e84a8cddadb25d572e170fcdbd8bc /src/character.c | |
parent | 78df1fb1d46d556bfc2698ca1802972b13613ba8 (diff) | |
parent | cc26d239af9a82cff079556a1daff4b4bf60eb5c (diff) | |
download | emacs-6e6c82a4e687708d5a7a3887f92db45bd74da276.tar.gz |
Merge from trunk.
Diffstat (limited to 'src/character.c')
-rw-r--r-- | src/character.c | 79 |
1 files changed, 40 insertions, 39 deletions
diff --git a/src/character.c b/src/character.c index f15a20f6999..b85cedad937 100644 --- a/src/character.c +++ b/src/character.c @@ -308,6 +308,36 @@ If the multibyte character does not represent a byte, return -1. */) } } + +/* Return width (columns) of C considering the buffer display table DP. */ + +static ptrdiff_t +char_width (int c, struct Lisp_Char_Table *dp) +{ + ptrdiff_t width = CHAR_WIDTH (c); + + if (dp) + { + Lisp_Object disp = DISP_CHAR_VECTOR (dp, c), ch; + int i; + + if (VECTORP (disp)) + for (i = 0, width = 0; i < ASIZE (disp); i++) + { + ch = AREF (disp, i); + if (CHARACTERP (ch)) + { + int w = CHAR_WIDTH (XFASTINT (ch)); + if (INT_ADD_OVERFLOW (width, w)) + string_overflow (); + width += w; + } + } + } + return width; +} + + DEFUN ("char-width", Fchar_width, Schar_width, 1, 1, 0, doc: /* Return width of CHAR when displayed in the current buffer. The width is measured by how many columns it occupies on the screen. @@ -315,21 +345,12 @@ Tab is taken to occupy `tab-width' columns. usage: (char-width CHAR) */) (Lisp_Object ch) { - Lisp_Object disp; - int c, width; - struct Lisp_Char_Table *dp = buffer_display_table (); + int c; + ptrdiff_t width; CHECK_CHARACTER (ch); c = XINT (ch); - - /* Get the way the display table would display it. */ - disp = dp ? DISP_CHAR_VECTOR (dp, c) : Qnil; - - if (VECTORP (disp)) - width = sanitize_char_width (ASIZE (disp)); - else - width = CHAR_WIDTH (c); - + width = char_width (c, buffer_display_table ()); return make_number (width); } @@ -350,25 +371,16 @@ c_string_width (const unsigned char *str, ptrdiff_t len, int precision, while (i_byte < len) { - int bytes, thiswidth; - Lisp_Object val; + int bytes; int c = STRING_CHAR_AND_LENGTH (str + i_byte, bytes); + ptrdiff_t thiswidth = char_width (c, dp); - if (dp) - { - val = DISP_CHAR_VECTOR (dp, c); - if (VECTORP (val)) - thiswidth = sanitize_char_width (ASIZE (val)); - else - thiswidth = CHAR_WIDTH (c); - } - else + if (precision <= 0) { - thiswidth = CHAR_WIDTH (c); + if (INT_ADD_OVERFLOW (width, thiswidth)) + string_overflow (); } - - if (precision > 0 - && (width + thiswidth > precision)) + else if (precision - width < thiswidth) { *nchars = i; *nbytes = i_byte; @@ -447,18 +459,7 @@ lisp_string_width (Lisp_Object string, ptrdiff_t precision, else c = str[i_byte], bytes = 1; chars = 1; - if (dp) - { - val = DISP_CHAR_VECTOR (dp, c); - if (VECTORP (val)) - thiswidth = sanitize_char_width (ASIZE (val)); - else - thiswidth = CHAR_WIDTH (c); - } - else - { - thiswidth = CHAR_WIDTH (c); - } + thiswidth = char_width (c, dp); } if (precision <= 0) |