diff options
| author | Eli Zaretskii | 2011-06-18 11:09:05 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2011-06-18 11:09:05 +0300 |
| commit | 40eb66c401ddb10ed9caecd8b01ee7b3f42d1d78 (patch) | |
| tree | ea74ea6f9549b137fa8003a650c07081fead7a32 /src | |
| parent | 578b494e52299cde50995fadee1a41f5bae0a573 (diff) | |
| download | emacs-40eb66c401ddb10ed9caecd8b01ee7b3f42d1d78.tar.gz emacs-40eb66c401ddb10ed9caecd8b01ee7b3f42d1d78.zip | |
Fix the decision about box_face in mode line for reordered text.
This fixes display of composed characters in buffer name on mode line.
src/xdisp.c (face_before_or_after_it_pos): Support bidi iteration
when BEFORE_P is zero.
(next_element_from_c_string): Handle the case of the first string
character that is not the first one in the visual order.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 7 | ||||
| -rw-r--r-- | src/xdisp.c | 146 |
2 files changed, 129 insertions, 24 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 088ed078770..772ebd4d273 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,10 @@ | |||
| 1 | 2011-06-18 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * xdisp.c (face_before_or_after_it_pos): Support bidi iteration | ||
| 4 | when BEFORE_P is zero. | ||
| 5 | (next_element_from_c_string): Handle the case of the first string | ||
| 6 | character that is not the first one in the visual order. | ||
| 7 | |||
| 1 | 2011-06-16 Eli Zaretskii <eliz@gnu.org> | 8 | 2011-06-16 Eli Zaretskii <eliz@gnu.org> |
| 2 | 9 | ||
| 3 | * xdisp.c (init_iterator): Don't initialize it->bidi_p for strings | 10 | * xdisp.c (init_iterator): Don't initialize it->bidi_p for strings |
diff --git a/src/xdisp.c b/src/xdisp.c index 00c66d4d3f9..6a289bb51c0 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -3471,21 +3471,21 @@ underlying_face_id (struct it *it) | |||
| 3471 | 3471 | ||
| 3472 | 3472 | ||
| 3473 | /* Compute the face one character before or after the current position | 3473 | /* Compute the face one character before or after the current position |
| 3474 | of IT. BEFORE_P non-zero means get the face in front of IT's | 3474 | of IT, in the visual order. BEFORE_P non-zero means get the face |
| 3475 | position. Value is the id of the face. */ | 3475 | in front (to the left in L2R paragraphs, to the right in R2L |
| 3476 | paragraphs) of IT's screen position. Value is the ID of the face. */ | ||
| 3476 | 3477 | ||
| 3477 | static int | 3478 | static int |
| 3478 | face_before_or_after_it_pos (struct it *it, int before_p) | 3479 | face_before_or_after_it_pos (struct it *it, int before_p) |
| 3479 | { | 3480 | { |
| 3480 | int face_id, limit; | 3481 | int face_id, limit; |
| 3481 | EMACS_INT next_check_charpos; | 3482 | EMACS_INT next_check_charpos; |
| 3482 | struct text_pos pos; | ||
| 3483 | 3483 | ||
| 3484 | xassert (it->s == NULL); | 3484 | xassert (it->s == NULL); |
| 3485 | 3485 | ||
| 3486 | if (STRINGP (it->string)) | 3486 | if (STRINGP (it->string)) |
| 3487 | { | 3487 | { |
| 3488 | EMACS_INT bufpos; | 3488 | EMACS_INT bufpos, charpos; |
| 3489 | int base_face_id; | 3489 | int base_face_id; |
| 3490 | 3490 | ||
| 3491 | /* No face change past the end of the string (for the case | 3491 | /* No face change past the end of the string (for the case |
| @@ -3495,16 +3495,39 @@ face_before_or_after_it_pos (struct it *it, int before_p) | |||
| 3495 | || (IT_STRING_CHARPOS (*it) == 0 && before_p)) | 3495 | || (IT_STRING_CHARPOS (*it) == 0 && before_p)) |
| 3496 | return it->face_id; | 3496 | return it->face_id; |
| 3497 | 3497 | ||
| 3498 | /* Set pos to the position before or after IT's current position. */ | 3498 | if (!it->bidi_p) |
| 3499 | if (before_p) | 3499 | { |
| 3500 | pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string); | 3500 | /* Set charpos to the position before or after IT's current |
| 3501 | position, in the logical order, which in the non-bidi | ||
| 3502 | case is the same as the visual order. */ | ||
| 3503 | if (before_p) | ||
| 3504 | charpos = IT_STRING_CHARPOS (*it) - 1; | ||
| 3505 | else if (it->what == IT_COMPOSITION) | ||
| 3506 | /* For composition, we must check the character after the | ||
| 3507 | composition. */ | ||
| 3508 | charpos = IT_STRING_CHARPOS (*it) + it->cmp_it.nchars; | ||
| 3509 | else | ||
| 3510 | charpos = IT_STRING_CHARPOS (*it) + 1; | ||
| 3511 | } | ||
| 3501 | else | 3512 | else |
| 3502 | /* For composition, we must check the character after the | 3513 | { |
| 3503 | composition. */ | 3514 | if (before_p) |
| 3504 | pos = (it->what == IT_COMPOSITION | 3515 | charpos = IT_STRING_CHARPOS (*it) - 1; /* FIXME! */ |
| 3505 | ? string_pos (IT_STRING_CHARPOS (*it) | 3516 | else |
| 3506 | + it->cmp_it.nchars, it->string) | 3517 | { |
| 3507 | : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string)); | 3518 | /* Set charpos to the string position of the character |
| 3519 | that comes after IT's current position in the visual | ||
| 3520 | order. */ | ||
| 3521 | int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1); | ||
| 3522 | struct it it_copy = *it; | ||
| 3523 | |||
| 3524 | while (n--) | ||
| 3525 | bidi_move_to_visually_next (&it_copy.bidi_it); | ||
| 3526 | |||
| 3527 | charpos = it_copy.bidi_it.charpos; | ||
| 3528 | } | ||
| 3529 | } | ||
| 3530 | xassert (0 <= charpos && charpos <= SCHARS (it->string)); | ||
| 3508 | 3531 | ||
| 3509 | if (it->current.overlay_string_index >= 0) | 3532 | if (it->current.overlay_string_index >= 0) |
| 3510 | bufpos = IT_CHARPOS (*it); | 3533 | bufpos = IT_CHARPOS (*it); |
| @@ -3516,7 +3539,7 @@ face_before_or_after_it_pos (struct it *it, int before_p) | |||
| 3516 | /* Get the face for ASCII, or unibyte. */ | 3539 | /* Get the face for ASCII, or unibyte. */ |
| 3517 | face_id = face_at_string_position (it->w, | 3540 | face_id = face_at_string_position (it->w, |
| 3518 | it->string, | 3541 | it->string, |
| 3519 | CHARPOS (pos), | 3542 | charpos, |
| 3520 | bufpos, | 3543 | bufpos, |
| 3521 | it->region_beg_charpos, | 3544 | it->region_beg_charpos, |
| 3522 | it->region_end_charpos, | 3545 | it->region_end_charpos, |
| @@ -3528,16 +3551,19 @@ face_before_or_after_it_pos (struct it *it, int before_p) | |||
| 3528 | suitable for unibyte text if IT->string is unibyte. */ | 3551 | suitable for unibyte text if IT->string is unibyte. */ |
| 3529 | if (STRING_MULTIBYTE (it->string)) | 3552 | if (STRING_MULTIBYTE (it->string)) |
| 3530 | { | 3553 | { |
| 3554 | struct text_pos pos = string_pos (charpos, it->string); | ||
| 3531 | const unsigned char *p = SDATA (it->string) + BYTEPOS (pos); | 3555 | const unsigned char *p = SDATA (it->string) + BYTEPOS (pos); |
| 3532 | int c, len; | 3556 | int c, len; |
| 3533 | struct face *face = FACE_FROM_ID (it->f, face_id); | 3557 | struct face *face = FACE_FROM_ID (it->f, face_id); |
| 3534 | 3558 | ||
| 3535 | c = string_char_and_length (p, &len); | 3559 | c = string_char_and_length (p, &len); |
| 3536 | face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), it->string); | 3560 | face_id = FACE_FOR_CHAR (it->f, face, c, charpos, it->string); |
| 3537 | } | 3561 | } |
| 3538 | } | 3562 | } |
| 3539 | else | 3563 | else |
| 3540 | { | 3564 | { |
| 3565 | struct text_pos pos; | ||
| 3566 | |||
| 3541 | if ((IT_CHARPOS (*it) >= ZV && !before_p) | 3567 | if ((IT_CHARPOS (*it) >= ZV && !before_p) |
| 3542 | || (IT_CHARPOS (*it) <= BEGV && before_p)) | 3568 | || (IT_CHARPOS (*it) <= BEGV && before_p)) |
| 3543 | return it->face_id; | 3569 | return it->face_id; |
| @@ -3545,17 +3571,43 @@ face_before_or_after_it_pos (struct it *it, int before_p) | |||
| 3545 | limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT; | 3571 | limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT; |
| 3546 | pos = it->current.pos; | 3572 | pos = it->current.pos; |
| 3547 | 3573 | ||
| 3548 | if (before_p) | 3574 | if (!it->bidi_p) |
| 3549 | DEC_TEXT_POS (pos, it->multibyte_p); | 3575 | { |
| 3576 | if (before_p) | ||
| 3577 | DEC_TEXT_POS (pos, it->multibyte_p); | ||
| 3578 | else | ||
| 3579 | { | ||
| 3580 | if (it->what == IT_COMPOSITION) | ||
| 3581 | { | ||
| 3582 | /* For composition, we must check the position after | ||
| 3583 | the composition. */ | ||
| 3584 | pos.charpos += it->cmp_it.nchars; | ||
| 3585 | pos.bytepos += it->len; | ||
| 3586 | } | ||
| 3587 | else | ||
| 3588 | INC_TEXT_POS (pos, it->multibyte_p); | ||
| 3589 | } | ||
| 3590 | } | ||
| 3550 | else | 3591 | else |
| 3551 | { | 3592 | { |
| 3552 | if (it->what == IT_COMPOSITION) | 3593 | if (before_p) |
| 3553 | /* For composition, we must check the position after the | 3594 | DEC_TEXT_POS (pos, it->multibyte_p); /* FIXME! */ |
| 3554 | composition. */ | ||
| 3555 | pos.charpos += it->cmp_it.nchars, pos.bytepos += it->len; | ||
| 3556 | else | 3595 | else |
| 3557 | INC_TEXT_POS (pos, it->multibyte_p); | 3596 | { |
| 3597 | /* Set charpos to the buffer position of the character | ||
| 3598 | that comes after IT's current position in the visual | ||
| 3599 | order. */ | ||
| 3600 | int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1); | ||
| 3601 | struct it it_copy = *it; | ||
| 3602 | |||
| 3603 | while (n--) | ||
| 3604 | bidi_move_to_visually_next (&it_copy.bidi_it); | ||
| 3605 | |||
| 3606 | SET_TEXT_POS (pos, | ||
| 3607 | it_copy.bidi_it.charpos, it_copy.bidi_it.bytepos); | ||
| 3608 | } | ||
| 3558 | } | 3609 | } |
| 3610 | xassert (BEGV <= CHARPOS (pos) && CHARPOS (pos) <= ZV); | ||
| 3559 | 3611 | ||
| 3560 | /* Determine face for CHARSET_ASCII, or unibyte. */ | 3612 | /* Determine face for CHARSET_ASCII, or unibyte. */ |
| 3561 | face_id = face_at_buffer_position (it->w, | 3613 | face_id = face_at_buffer_position (it->w, |
| @@ -6798,8 +6850,54 @@ next_element_from_c_string (struct it *it) | |||
| 6798 | BYTEPOS (it->position) = CHARPOS (it->position) = 0; | 6850 | BYTEPOS (it->position) = CHARPOS (it->position) = 0; |
| 6799 | it->object = Qnil; | 6851 | it->object = Qnil; |
| 6800 | 6852 | ||
| 6801 | /* IT's position can be greater IT->string_nchars in case a field | 6853 | /* With bidi reordering, the character to display might not be the |
| 6802 | width or precision has been specified when the iterator was | 6854 | character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that |
| 6855 | we were reseated to a new string, whose paragraph direction is | ||
| 6856 | not known. */ | ||
| 6857 | if (it->bidi_p && it->bidi_it.first_elt) | ||
| 6858 | { | ||
| 6859 | it->bidi_it.charpos = IT_CHARPOS (*it); | ||
| 6860 | it->bidi_it.bytepos = IT_BYTEPOS (*it); | ||
| 6861 | if (it->bidi_it.charpos >= it->string_nchars) | ||
| 6862 | { | ||
| 6863 | /* Nothing to do, but reset the FIRST_ELT flag, like | ||
| 6864 | bidi_paragraph_init does, because we are not going to | ||
| 6865 | call it. */ | ||
| 6866 | it->bidi_it.first_elt = 0; | ||
| 6867 | } | ||
| 6868 | else if (it->bidi_it.charpos <= 0) | ||
| 6869 | { | ||
| 6870 | /* If we are at the beginning of the string, we can produce | ||
| 6871 | the next element right away. */ | ||
| 6872 | bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1); | ||
| 6873 | bidi_move_to_visually_next (&it->bidi_it); | ||
| 6874 | } | ||
| 6875 | else | ||
| 6876 | { | ||
| 6877 | EMACS_INT orig_bytepos = IT_BYTEPOS (*it); | ||
| 6878 | |||
| 6879 | /* We need to prime the bidi iterator starting at the string | ||
| 6880 | beginning, before we will be able to produce the next | ||
| 6881 | element. */ | ||
| 6882 | it->bidi_it.charpos = it->bidi_it.bytepos = 0; | ||
| 6883 | bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1); | ||
| 6884 | do | ||
| 6885 | { | ||
| 6886 | /* Now return to buffer position where we were asked to | ||
| 6887 | get the next display element, and produce that. */ | ||
| 6888 | bidi_move_to_visually_next (&it->bidi_it); | ||
| 6889 | } | ||
| 6890 | while (it->bidi_it.bytepos != orig_bytepos | ||
| 6891 | && it->bidi_it.charpos < it->string_nchars); | ||
| 6892 | } | ||
| 6893 | |||
| 6894 | /* Adjust IT's position information to where we ended up. */ | ||
| 6895 | IT_CHARPOS (*it) = it->bidi_it.charpos; | ||
| 6896 | IT_BYTEPOS (*it) = it->bidi_it.bytepos; | ||
| 6897 | } | ||
| 6898 | |||
| 6899 | /* IT's position can be greater than IT->string_nchars in case a | ||
| 6900 | field width or precision has been specified when the iterator was | ||
| 6803 | initialized. */ | 6901 | initialized. */ |
| 6804 | if (IT_CHARPOS (*it) >= it->end_charpos) | 6902 | if (IT_CHARPOS (*it) >= it->end_charpos) |
| 6805 | { | 6903 | { |