diff options
| author | Paul Eggert | 2012-02-10 10:58:48 -0800 |
|---|---|---|
| committer | Paul Eggert | 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 emacs-6e6c82a4e687708d5a7a3887f92db45bd74da276.zip | |
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. */) | |||
| 308 | } | 308 | } |
| 309 | } | 309 | } |
| 310 | 310 | ||
| 311 | |||
| 312 | /* Return width (columns) of C considering the buffer display table DP. */ | ||
| 313 | |||
| 314 | static ptrdiff_t | ||
| 315 | char_width (int c, struct Lisp_Char_Table *dp) | ||
| 316 | { | ||
| 317 | ptrdiff_t width = CHAR_WIDTH (c); | ||
| 318 | |||
| 319 | if (dp) | ||
| 320 | { | ||
| 321 | Lisp_Object disp = DISP_CHAR_VECTOR (dp, c), ch; | ||
| 322 | int i; | ||
| 323 | |||
| 324 | if (VECTORP (disp)) | ||
| 325 | for (i = 0, width = 0; i < ASIZE (disp); i++) | ||
| 326 | { | ||
| 327 | ch = AREF (disp, i); | ||
| 328 | if (CHARACTERP (ch)) | ||
| 329 | { | ||
| 330 | int w = CHAR_WIDTH (XFASTINT (ch)); | ||
| 331 | if (INT_ADD_OVERFLOW (width, w)) | ||
| 332 | string_overflow (); | ||
| 333 | width += w; | ||
| 334 | } | ||
| 335 | } | ||
| 336 | } | ||
| 337 | return width; | ||
| 338 | } | ||
| 339 | |||
| 340 | |||
| 311 | DEFUN ("char-width", Fchar_width, Schar_width, 1, 1, 0, | 341 | DEFUN ("char-width", Fchar_width, Schar_width, 1, 1, 0, |
| 312 | doc: /* Return width of CHAR when displayed in the current buffer. | 342 | doc: /* Return width of CHAR when displayed in the current buffer. |
| 313 | The width is measured by how many columns it occupies on the screen. | 343 | 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. | |||
| 315 | usage: (char-width CHAR) */) | 345 | usage: (char-width CHAR) */) |
| 316 | (Lisp_Object ch) | 346 | (Lisp_Object ch) |
| 317 | { | 347 | { |
| 318 | Lisp_Object disp; | 348 | int c; |
| 319 | int c, width; | 349 | ptrdiff_t width; |
| 320 | struct Lisp_Char_Table *dp = buffer_display_table (); | ||
| 321 | 350 | ||
| 322 | CHECK_CHARACTER (ch); | 351 | CHECK_CHARACTER (ch); |
| 323 | c = XINT (ch); | 352 | c = XINT (ch); |
| 324 | 353 | width = char_width (c, buffer_display_table ()); | |
| 325 | /* Get the way the display table would display it. */ | ||
| 326 | disp = dp ? DISP_CHAR_VECTOR (dp, c) : Qnil; | ||
| 327 | |||
| 328 | if (VECTORP (disp)) | ||
| 329 | width = sanitize_char_width (ASIZE (disp)); | ||
| 330 | else | ||
| 331 | width = CHAR_WIDTH (c); | ||
| 332 | |||
| 333 | return make_number (width); | 354 | return make_number (width); |
| 334 | } | 355 | } |
| 335 | 356 | ||
| @@ -350,25 +371,16 @@ c_string_width (const unsigned char *str, ptrdiff_t len, int precision, | |||
| 350 | 371 | ||
| 351 | while (i_byte < len) | 372 | while (i_byte < len) |
| 352 | { | 373 | { |
| 353 | int bytes, thiswidth; | 374 | int bytes; |
| 354 | Lisp_Object val; | ||
| 355 | int c = STRING_CHAR_AND_LENGTH (str + i_byte, bytes); | 375 | int c = STRING_CHAR_AND_LENGTH (str + i_byte, bytes); |
| 376 | ptrdiff_t thiswidth = char_width (c, dp); | ||
| 356 | 377 | ||
| 357 | if (dp) | 378 | if (precision <= 0) |
| 358 | { | ||
| 359 | val = DISP_CHAR_VECTOR (dp, c); | ||
| 360 | if (VECTORP (val)) | ||
| 361 | thiswidth = sanitize_char_width (ASIZE (val)); | ||
| 362 | else | ||
| 363 | thiswidth = CHAR_WIDTH (c); | ||
| 364 | } | ||
| 365 | else | ||
| 366 | { | 379 | { |
| 367 | thiswidth = CHAR_WIDTH (c); | 380 | if (INT_ADD_OVERFLOW (width, thiswidth)) |
| 381 | string_overflow (); | ||
| 368 | } | 382 | } |
| 369 | 383 | else if (precision - width < thiswidth) | |
| 370 | if (precision > 0 | ||
| 371 | && (width + thiswidth > precision)) | ||
| 372 | { | 384 | { |
| 373 | *nchars = i; | 385 | *nchars = i; |
| 374 | *nbytes = i_byte; | 386 | *nbytes = i_byte; |
| @@ -447,18 +459,7 @@ lisp_string_width (Lisp_Object string, ptrdiff_t precision, | |||
| 447 | else | 459 | else |
| 448 | c = str[i_byte], bytes = 1; | 460 | c = str[i_byte], bytes = 1; |
| 449 | chars = 1; | 461 | chars = 1; |
| 450 | if (dp) | 462 | thiswidth = char_width (c, dp); |
| 451 | { | ||
| 452 | val = DISP_CHAR_VECTOR (dp, c); | ||
| 453 | if (VECTORP (val)) | ||
| 454 | thiswidth = sanitize_char_width (ASIZE (val)); | ||
| 455 | else | ||
| 456 | thiswidth = CHAR_WIDTH (c); | ||
| 457 | } | ||
| 458 | else | ||
| 459 | { | ||
| 460 | thiswidth = CHAR_WIDTH (c); | ||
| 461 | } | ||
| 462 | } | 463 | } |
| 463 | 464 | ||
| 464 | if (precision <= 0) | 465 | if (precision <= 0) |