aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii <[email protected]>2012-11-03 11:25:34 +0200
committerEli Zaretskii <[email protected]>2012-11-03 11:25:34 +0200
commit67b50ba47bcf46bd8a699fa0c1f2af1cce3f2338 (patch)
tree72f5e7e6f9e68b7625517e9acfc998511ae79604
parentc65b407b40fcfd0aa99ba159c5b67d16133380a2 (diff)
Fix bidi initialization in init_from_display_pos.
src/xdisp.c (init_from_display_pos): Fix initialization of the bidi iterator when starting in the middle of a display or overlay string. Fixes: debbugs:12745
-rw-r--r--src/ChangeLog6
-rw-r--r--src/xdisp.c38
2 files changed, 44 insertions, 0 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index e762eb13b8..8b7c1d9113 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,9 @@
+2012-11-03 Eli Zaretskii <[email protected]>
+
+ * xdisp.c (init_from_display_pos): Fix initialization of the bidi
+ iterator when starting in the middle of a display or overlay
+ string. (Bug#12745)
+
2012-11-01 Eli Zaretskii <[email protected]>
* w32proc.c (getpgrp, setpgid): New functions. (Bug#12776)
diff --git a/src/xdisp.c b/src/xdisp.c
index b3b08edcd0..bc1cbd94bd 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -928,6 +928,7 @@ static enum move_it_result
move_it_in_display_line_to (struct it *, ptrdiff_t, int,
enum move_operation_enum);
void move_it_vertically_backward (struct it *, int);
+static void get_visually_first_element (struct it *);
static void init_to_row_start (struct it *, struct window *,
struct glyph_row *);
static int init_to_row_end (struct it *, struct window *,
@@ -3113,6 +3114,40 @@ init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
eassert (STRINGP (it->string));
it->current.string_pos = pos->string_pos;
it->method = GET_FROM_STRING;
+ it->end_charpos = SCHARS (it->string);
+ /* Set up the bidi iterator for this overlay string. */
+ if (it->bidi_p)
+ {
+ it->bidi_it.string.lstring = it->string;
+ it->bidi_it.string.s = NULL;
+ it->bidi_it.string.schars = SCHARS (it->string);
+ it->bidi_it.string.bufpos = it->overlay_strings_charpos;
+ it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
+ it->bidi_it.string.unibyte = !it->multibyte_p;
+ bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
+ FRAME_WINDOW_P (it->f), &it->bidi_it);
+
+ /* Synchronize the state of the bidi iterator with
+ pos->string_pos. For any string position other than
+ zero, this will be done automagically when we resume
+ iteration over the string and get_visually_first_element
+ is called. But if string_pos is zero, and the string is
+ to be reordered for display, we need to resync manually,
+ since it could be that the iteration state recorded in
+ pos ended at string_pos of 0 moving backwards in string. */
+ if (CHARPOS (pos->string_pos) == 0)
+ {
+ get_visually_first_element (it);
+ if (IT_STRING_CHARPOS (*it) != 0)
+ do {
+ /* Paranoia. */
+ eassert (it->bidi_it.charpos < it->bidi_it.string.schars);
+ bidi_move_to_visually_next (&it->bidi_it);
+ } while (it->bidi_it.charpos != 0);
+ }
+ eassert (IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
+ && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos);
+ }
}
if (CHARPOS (pos->string_pos) >= 0)
@@ -3122,6 +3157,9 @@ init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
IT should already be filled with that string. */
it->current.string_pos = pos->string_pos;
eassert (STRINGP (it->string));
+ if (it->bidi_p)
+ bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
+ FRAME_WINDOW_P (it->f), &it->bidi_it);
}
/* Restore position in display vector translations, control