diff options
| author | Eli Zaretskii | 2014-12-25 17:38:15 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2014-12-25 17:38:15 +0200 |
| commit | a41d07b329c034ad34e442bef93b6fcaeb556f9f (patch) | |
| tree | 2c2f674122fcb67314d13a7228eee142291a1200 | |
| parent | b70977ce02432b1ded569215096402e2eee318a3 (diff) | |
| download | emacs-a41d07b329c034ad34e442bef93b6fcaeb556f9f.tar.gz emacs-a41d07b329c034ad34e442bef93b6fcaeb556f9f.zip | |
Fix rendering of composed caharacters on the mode line. (Bug#19435)
src/xdisp.c (set_iterator_to_next) <GET_FROM_STRING>: Limit search in
composition_compute_stop_pos to the number of characters in the
string.
<GET_FROM_BUFFER, GET_FROM_STRING>: Simplify code.
src/composite.c (composition_compute_stop_pos): If no composition
was found in a string before ENDPOS, and ENDPOS is the string end,
no need to back up to a safe point.
src/dispextern.h (struct it) <end_charpos>: Improve commentary.
| -rw-r--r-- | src/ChangeLog | 13 | ||||
| -rw-r--r-- | src/composite.c | 3 | ||||
| -rw-r--r-- | src/dispextern.h | 5 | ||||
| -rw-r--r-- | src/xdisp.c | 171 |
4 files changed, 93 insertions, 99 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 2840109ac1c..2df83082fbd 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,16 @@ | |||
| 1 | 2014-12-25 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * xdisp.c (set_iterator_to_next) <GET_FROM_STRING>: Limit search in | ||
| 4 | composition_compute_stop_pos to the number of characters in the | ||
| 5 | string. (Bug#19435) | ||
| 6 | <GET_FROM_BUFFER, GET_FROM_STRING>: Simplify code. | ||
| 7 | |||
| 8 | * composite.c (composition_compute_stop_pos): If no composition | ||
| 9 | was found in a string before ENDPOS, and ENDPOS is the string end, | ||
| 10 | no need to back up to a safe point. | ||
| 11 | |||
| 12 | * dispextern.h (struct it) <end_charpos>: Improve commentary. | ||
| 13 | |||
| 1 | 2014-12-24 Jan Djärv <jan.h.d@swipnet.se> | 14 | 2014-12-24 Jan Djärv <jan.h.d@swipnet.se> |
| 2 | 15 | ||
| 3 | * nsimage.m (allocInitFromFile:): Initialize bmRep. | 16 | * nsimage.m (allocInitFromFile:): Initialize bmRep. |
diff --git a/src/composite.c b/src/composite.c index fa882141908..a1282103972 100644 --- a/src/composite.c +++ b/src/composite.c | |||
| @@ -1036,7 +1036,8 @@ composition_compute_stop_pos (struct composition_it *cmp_it, ptrdiff_t charpos, | |||
| 1036 | } | 1036 | } |
| 1037 | } | 1037 | } |
| 1038 | } | 1038 | } |
| 1039 | if (charpos == endpos) | 1039 | if (charpos == endpos |
| 1040 | && !(STRINGP (string) && endpos == SCHARS (string))) | ||
| 1040 | { | 1041 | { |
| 1041 | /* We couldn't find a composition point before ENDPOS. But, | 1042 | /* We couldn't find a composition point before ENDPOS. But, |
| 1042 | some character after ENDPOS may be composed with | 1043 | some character after ENDPOS may be composed with |
diff --git a/src/dispextern.h b/src/dispextern.h index 576f22870c2..0e5a73a929c 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -2222,7 +2222,10 @@ struct it | |||
| 2222 | ptrdiff_t base_level_stop; | 2222 | ptrdiff_t base_level_stop; |
| 2223 | 2223 | ||
| 2224 | /* Maximum string or buffer position + 1. ZV when iterating over | 2224 | /* Maximum string or buffer position + 1. ZV when iterating over |
| 2225 | current_buffer. */ | 2225 | current_buffer. When iterating over a string in display_string, |
| 2226 | this can be smaller or greater than the number of string | ||
| 2227 | characters, depending on the values of PRECISION and FIELD_WIDTH | ||
| 2228 | with which display_string was called. */ | ||
| 2226 | ptrdiff_t end_charpos; | 2229 | ptrdiff_t end_charpos; |
| 2227 | 2230 | ||
| 2228 | /* C string to iterate over. Non-null means get characters from | 2231 | /* C string to iterate over. Non-null means get characters from |
diff --git a/src/xdisp.c b/src/xdisp.c index e3e00357ed0..173df5d011b 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -7330,27 +7330,15 @@ set_iterator_to_next (struct it *it, int reseat_p) | |||
| 7330 | else if (it->cmp_it.id >= 0) | 7330 | else if (it->cmp_it.id >= 0) |
| 7331 | { | 7331 | { |
| 7332 | /* We are currently getting glyphs from a composition. */ | 7332 | /* We are currently getting glyphs from a composition. */ |
| 7333 | int i; | ||
| 7334 | |||
| 7335 | if (! it->bidi_p) | 7333 | if (! it->bidi_p) |
| 7336 | { | 7334 | { |
| 7337 | IT_CHARPOS (*it) += it->cmp_it.nchars; | 7335 | IT_CHARPOS (*it) += it->cmp_it.nchars; |
| 7338 | IT_BYTEPOS (*it) += it->cmp_it.nbytes; | 7336 | IT_BYTEPOS (*it) += it->cmp_it.nbytes; |
| 7339 | if (it->cmp_it.to < it->cmp_it.nglyphs) | ||
| 7340 | { | ||
| 7341 | it->cmp_it.from = it->cmp_it.to; | ||
| 7342 | } | ||
| 7343 | else | ||
| 7344 | { | ||
| 7345 | it->cmp_it.id = -1; | ||
| 7346 | composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it), | ||
| 7347 | IT_BYTEPOS (*it), | ||
| 7348 | it->end_charpos, Qnil); | ||
| 7349 | } | ||
| 7350 | } | 7337 | } |
| 7351 | else if (! it->cmp_it.reversed_p) | 7338 | else |
| 7352 | { | 7339 | { |
| 7353 | /* Composition created while scanning forward. */ | 7340 | int i; |
| 7341 | |||
| 7354 | /* Update IT's char/byte positions to point to the first | 7342 | /* Update IT's char/byte positions to point to the first |
| 7355 | character of the next grapheme cluster, or to the | 7343 | character of the next grapheme cluster, or to the |
| 7356 | character visually after the current composition. */ | 7344 | character visually after the current composition. */ |
| @@ -7358,52 +7346,34 @@ set_iterator_to_next (struct it *it, int reseat_p) | |||
| 7358 | bidi_move_to_visually_next (&it->bidi_it); | 7346 | bidi_move_to_visually_next (&it->bidi_it); |
| 7359 | IT_BYTEPOS (*it) = it->bidi_it.bytepos; | 7347 | IT_BYTEPOS (*it) = it->bidi_it.bytepos; |
| 7360 | IT_CHARPOS (*it) = it->bidi_it.charpos; | 7348 | IT_CHARPOS (*it) = it->bidi_it.charpos; |
| 7349 | } | ||
| 7361 | 7350 | ||
| 7362 | if (it->cmp_it.to < it->cmp_it.nglyphs) | 7351 | if ((! it->bidi_p || ! it->cmp_it.reversed_p) |
| 7363 | { | 7352 | && it->cmp_it.to < it->cmp_it.nglyphs) |
| 7364 | /* Proceed to the next grapheme cluster. */ | 7353 | { |
| 7365 | it->cmp_it.from = it->cmp_it.to; | 7354 | /* Composition created while scanning forward. Proceed |
| 7366 | } | 7355 | to the next grapheme cluster. */ |
| 7367 | else | 7356 | it->cmp_it.from = it->cmp_it.to; |
| 7368 | { | 7357 | } |
| 7369 | /* No more grapheme clusters in this composition. | 7358 | else if ((it->bidi_p && it->cmp_it.reversed_p) |
| 7370 | Find the next stop position. */ | 7359 | && it->cmp_it.from > 0) |
| 7371 | ptrdiff_t stop = it->end_charpos; | 7360 | { |
| 7372 | if (it->bidi_it.scan_dir < 0) | 7361 | /* Composition created while scanning backward. Proceed |
| 7373 | /* Now we are scanning backward and don't know | 7362 | to the previous grapheme cluster. */ |
| 7374 | where to stop. */ | 7363 | it->cmp_it.to = it->cmp_it.from; |
| 7375 | stop = -1; | ||
| 7376 | composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it), | ||
| 7377 | IT_BYTEPOS (*it), stop, Qnil); | ||
| 7378 | } | ||
| 7379 | } | 7364 | } |
| 7380 | else | 7365 | else |
| 7381 | { | 7366 | { |
| 7382 | /* Composition created while scanning backward. */ | 7367 | /* No more grapheme clusters in this composition. |
| 7383 | /* Update IT's char/byte positions to point to the last | 7368 | Find the next stop position. */ |
| 7384 | character of the previous grapheme cluster, or the | 7369 | ptrdiff_t stop = it->end_charpos; |
| 7385 | character visually after the current composition. */ | 7370 | |
| 7386 | for (i = 0; i < it->cmp_it.nchars; i++) | 7371 | if (it->bidi_it.scan_dir < 0) |
| 7387 | bidi_move_to_visually_next (&it->bidi_it); | 7372 | /* Now we are scanning backward and don't know |
| 7388 | IT_BYTEPOS (*it) = it->bidi_it.bytepos; | 7373 | where to stop. */ |
| 7389 | IT_CHARPOS (*it) = it->bidi_it.charpos; | 7374 | stop = -1; |
| 7390 | if (it->cmp_it.from > 0) | 7375 | composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it), |
| 7391 | { | 7376 | IT_BYTEPOS (*it), stop, Qnil); |
| 7392 | /* Proceed to the previous grapheme cluster. */ | ||
| 7393 | it->cmp_it.to = it->cmp_it.from; | ||
| 7394 | } | ||
| 7395 | else | ||
| 7396 | { | ||
| 7397 | /* No more grapheme clusters in this composition. | ||
| 7398 | Find the next stop position. */ | ||
| 7399 | ptrdiff_t stop = it->end_charpos; | ||
| 7400 | if (it->bidi_it.scan_dir < 0) | ||
| 7401 | /* Now we are scanning backward and don't know | ||
| 7402 | where to stop. */ | ||
| 7403 | stop = -1; | ||
| 7404 | composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it), | ||
| 7405 | IT_BYTEPOS (*it), stop, Qnil); | ||
| 7406 | } | ||
| 7407 | } | 7377 | } |
| 7408 | } | 7378 | } |
| 7409 | else | 7379 | else |
| @@ -7532,61 +7502,63 @@ set_iterator_to_next (struct it *it, int reseat_p) | |||
| 7532 | } | 7502 | } |
| 7533 | if (it->cmp_it.id >= 0) | 7503 | if (it->cmp_it.id >= 0) |
| 7534 | { | 7504 | { |
| 7535 | int i; | 7505 | /* We are delivering display elements from a composition. |
| 7536 | 7506 | Update the string position past the grapheme cluster | |
| 7507 | we've just processed. */ | ||
| 7537 | if (! it->bidi_p) | 7508 | if (! it->bidi_p) |
| 7538 | { | 7509 | { |
| 7539 | IT_STRING_CHARPOS (*it) += it->cmp_it.nchars; | 7510 | IT_STRING_CHARPOS (*it) += it->cmp_it.nchars; |
| 7540 | IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes; | 7511 | IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes; |
| 7541 | if (it->cmp_it.to < it->cmp_it.nglyphs) | ||
| 7542 | it->cmp_it.from = it->cmp_it.to; | ||
| 7543 | else | ||
| 7544 | { | ||
| 7545 | it->cmp_it.id = -1; | ||
| 7546 | composition_compute_stop_pos (&it->cmp_it, | ||
| 7547 | IT_STRING_CHARPOS (*it), | ||
| 7548 | IT_STRING_BYTEPOS (*it), | ||
| 7549 | it->end_charpos, it->string); | ||
| 7550 | } | ||
| 7551 | } | 7512 | } |
| 7552 | else if (! it->cmp_it.reversed_p) | 7513 | else |
| 7553 | { | 7514 | { |
| 7515 | int i; | ||
| 7516 | |||
| 7554 | for (i = 0; i < it->cmp_it.nchars; i++) | 7517 | for (i = 0; i < it->cmp_it.nchars; i++) |
| 7555 | bidi_move_to_visually_next (&it->bidi_it); | 7518 | bidi_move_to_visually_next (&it->bidi_it); |
| 7556 | IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos; | 7519 | IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos; |
| 7557 | IT_STRING_CHARPOS (*it) = it->bidi_it.charpos; | 7520 | IT_STRING_CHARPOS (*it) = it->bidi_it.charpos; |
| 7521 | } | ||
| 7558 | 7522 | ||
| 7559 | if (it->cmp_it.to < it->cmp_it.nglyphs) | 7523 | /* Did we exhaust all the grapheme clusters of this |
| 7560 | it->cmp_it.from = it->cmp_it.to; | 7524 | composition? */ |
| 7561 | else | 7525 | if ((! it->bidi_p || ! it->cmp_it.reversed_p) |
| 7562 | { | 7526 | && (it->cmp_it.to < it->cmp_it.nglyphs)) |
| 7563 | ptrdiff_t stop = it->end_charpos; | 7527 | { |
| 7564 | if (it->bidi_it.scan_dir < 0) | 7528 | /* Not all the grapheme clusters were processed yet; |
| 7565 | stop = -1; | 7529 | advance to the next cluster. */ |
| 7566 | composition_compute_stop_pos (&it->cmp_it, | 7530 | it->cmp_it.from = it->cmp_it.to; |
| 7567 | IT_STRING_CHARPOS (*it), | 7531 | } |
| 7568 | IT_STRING_BYTEPOS (*it), stop, | 7532 | else if ((it->bidi_p && it->cmp_it.reversed_p) |
| 7569 | it->string); | 7533 | && it->cmp_it.from > 0) |
| 7570 | } | 7534 | { |
| 7535 | /* Likewise: advance to the next cluster, but going in | ||
| 7536 | the reverse direction. */ | ||
| 7537 | it->cmp_it.to = it->cmp_it.from; | ||
| 7571 | } | 7538 | } |
| 7572 | else | 7539 | else |
| 7573 | { | 7540 | { |
| 7574 | for (i = 0; i < it->cmp_it.nchars; i++) | 7541 | /* This composition was fully processed; find the next |
| 7575 | bidi_move_to_visually_next (&it->bidi_it); | 7542 | candidate place for checking for composed |
| 7576 | IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos; | 7543 | characters. */ |
| 7577 | IT_STRING_CHARPOS (*it) = it->bidi_it.charpos; | 7544 | /* Always limit string searches to the string length; |
| 7578 | if (it->cmp_it.from > 0) | 7545 | any padding spaces are not part of the string, and |
| 7579 | it->cmp_it.to = it->cmp_it.from; | 7546 | there cannot be any compositions in that padding. */ |
| 7580 | else | 7547 | ptrdiff_t stop = SCHARS (it->string); |
| 7548 | |||
| 7549 | if (it->bidi_p && it->bidi_it.scan_dir < 0) | ||
| 7550 | stop = -1; | ||
| 7551 | else if (it->end_charpos < stop) | ||
| 7581 | { | 7552 | { |
| 7582 | ptrdiff_t stop = it->end_charpos; | 7553 | /* Cf. PRECISION in reseat_to_string: we might be |
| 7583 | if (it->bidi_it.scan_dir < 0) | 7554 | limited in how many of the string characters we |
| 7584 | stop = -1; | 7555 | need to deliver. */ |
| 7585 | composition_compute_stop_pos (&it->cmp_it, | 7556 | stop = it->end_charpos; |
| 7586 | IT_STRING_CHARPOS (*it), | ||
| 7587 | IT_STRING_BYTEPOS (*it), stop, | ||
| 7588 | it->string); | ||
| 7589 | } | 7557 | } |
| 7558 | composition_compute_stop_pos (&it->cmp_it, | ||
| 7559 | IT_STRING_CHARPOS (*it), | ||
| 7560 | IT_STRING_BYTEPOS (*it), stop, | ||
| 7561 | it->string); | ||
| 7590 | } | 7562 | } |
| 7591 | } | 7563 | } |
| 7592 | else | 7564 | else |
| @@ -7609,12 +7581,17 @@ set_iterator_to_next (struct it *it, int reseat_p) | |||
| 7609 | bidi_move_to_visually_next (&it->bidi_it); | 7581 | bidi_move_to_visually_next (&it->bidi_it); |
| 7610 | IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos; | 7582 | IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos; |
| 7611 | IT_STRING_CHARPOS (*it) = it->bidi_it.charpos; | 7583 | IT_STRING_CHARPOS (*it) = it->bidi_it.charpos; |
| 7584 | /* If the scan direction changes, we may need to update | ||
| 7585 | the place where to check for composed characters. */ | ||
| 7612 | if (prev_scan_dir != it->bidi_it.scan_dir) | 7586 | if (prev_scan_dir != it->bidi_it.scan_dir) |
| 7613 | { | 7587 | { |
| 7614 | ptrdiff_t stop = it->end_charpos; | 7588 | ptrdiff_t stop = SCHARS (it->string); |
| 7615 | 7589 | ||
| 7616 | if (it->bidi_it.scan_dir < 0) | 7590 | if (it->bidi_it.scan_dir < 0) |
| 7617 | stop = -1; | 7591 | stop = -1; |
| 7592 | else if (it->end_charpos < stop) | ||
| 7593 | stop = it->end_charpos; | ||
| 7594 | |||
| 7618 | composition_compute_stop_pos (&it->cmp_it, | 7595 | composition_compute_stop_pos (&it->cmp_it, |
| 7619 | IT_STRING_CHARPOS (*it), | 7596 | IT_STRING_CHARPOS (*it), |
| 7620 | IT_STRING_BYTEPOS (*it), stop, | 7597 | IT_STRING_BYTEPOS (*it), stop, |