aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2011-06-18 11:09:05 +0300
committerEli Zaretskii2011-06-18 11:09:05 +0300
commit40eb66c401ddb10ed9caecd8b01ee7b3f42d1d78 (patch)
treeea74ea6f9549b137fa8003a650c07081fead7a32
parent578b494e52299cde50995fadee1a41f5bae0a573 (diff)
downloademacs-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.
-rw-r--r--src/ChangeLog7
-rw-r--r--src/xdisp.c146
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 @@
12011-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
12011-06-16 Eli Zaretskii <eliz@gnu.org> 82011-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
3477static int 3478static int
3478face_before_or_after_it_pos (struct it *it, int before_p) 3479face_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 {