From bb269206f6ee49b68bb23cf955c531a7fc6ba140 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Thu, 9 Jun 2011 17:39:27 +0300 Subject: [PATCH] Add code to initialize bidi iterator for displaying strings. For now, ifdef'ed away. Some more testing. src/bidi.c (bidi_level_of_next_char): Allow the sentinel "position" to pass the test for valid cached positions. src/xdisp.c (init_iterator): Call bidi_init_it only of a valid buffer position was specified. Initialize paragraph_embedding to L2R. (reseat_to_string): Initialize the bidi iterator (for now ifdef'ed out). (display_string): If we need to ignore text properties of LISP_STRING, set IT->stop_charpos to IT->end_charpos. (The original value of -1 will not work with bidi.) src/dispextern.h (struct bidi_string_data): New member lstring. --- src/ChangeLog | 16 ++++++++ src/bidi.c | 6 ++- src/dispextern.h | 3 +- src/xdisp.c | 103 +++++++++++++++++++++++++++++++++-------------- 4 files changed, 95 insertions(+), 33 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 96b8d7ae7be..51e4561f8db 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,19 @@ +2011-06-09 Eli Zaretskii + + * bidi.c (bidi_level_of_next_char): Allow the sentinel "position" + to pass the test for valid cached positions. + + * xdisp.c (init_iterator): Call bidi_init_it only of a valid + buffer position was specified. Initialize paragraph_embedding to + L2R. + (reseat_to_string): Initialize the bidi iterator (for now ifdef'ed + out). + (display_string): If we need to ignore text properties of + LISP_STRING, set IT->stop_charpos to IT->end_charpos. (The + original value of -1 will not work with bidi.) + + * dispextern.h (struct bidi_string_data): New member lstring. + 2011-06-09 Eli Zaretskii * xdisp.c (Fcurrent_bidi_paragraph_direction): Initialize diff --git a/src/bidi.c b/src/bidi.c index ac950a9000a..a0a57b4c681 100644 --- a/src/bidi.c +++ b/src/bidi.c @@ -1679,7 +1679,11 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) abort (); next_char_pos = bidi_it->charpos + bidi_it->nchars; } - else if (bidi_it->charpos > (bidi_it->string.s ? 0 : 1)) + else if (bidi_it->charpos >= (bidi_it->string.s ? 0 : 1)) + /* Implementation note: we allow next_char_pos to be as low as + 0 for buffers or -1 for strings, and that is okay because + that's the "position" of the sentinel iterator state we + cached at the beginning of the iteration. */ next_char_pos = bidi_it->charpos - 1; if (next_char_pos >= 0) type = bidi_cache_find (next_char_pos, -1, bidi_it); diff --git a/src/dispextern.h b/src/dispextern.h index 0f7089d7916..979cb43e98f 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -1814,7 +1814,8 @@ struct bidi_stack { /* Data type for storing information about a string being iterated on. */ struct bidi_string_data { - const unsigned char *s; /* the string, or NULL if reordering buffer */ + Lisp_Object lstring; /* Lisp string to reorder, or nil */ + const unsigned char *s; /* string data, or NULL if reordering buffer */ EMACS_INT schars; /* the number of characters in the string, excluding the terminating null */ unsigned from_disp_str : 1; /* 1 means the string comes from a diff --git a/src/xdisp.c b/src/xdisp.c index 72aea8d224f..712088db324 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -129,9 +129,13 @@ along with GNU Emacs. If not, see . */ argument. Iteration over things to be displayed is then simple. It is - started by initializing an iterator with a call to init_iterator. - Calls to get_next_display_element fill the iterator structure with - relevant information about the next thing to display. Calls to + started by initializing an iterator with a call to init_iterator, + passing it the buffer position where to start iteration. For + iteration over strings, pass -1 as the position to init_iterator, + and call reseat_to_string when the string is ready, to initialize + the iterator for that string. Thereafter, calls to + get_next_display_element fill the iterator structure with relevant + information about the next thing to display. Calls to set_iterator_to_next move the iterator to the next thing. Besides this, an iterator also contains information about the @@ -2342,6 +2346,8 @@ init_iterator (struct it *it, struct window *w, it->base_face_id = remapped_base_face_id; it->string = Qnil; IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1; + it->paragraph_embedding = L2R; + it->bidi_it.string.lstring = Qnil; it->bidi_it.string.s = NULL; /* The window in which we iterate over current_buffer: */ @@ -2555,21 +2561,6 @@ init_iterator (struct it *it, struct window *w, it->start_of_box_run_p = 1; } - /* If we are to reorder bidirectional text, init the bidi - iterator. */ - if (it->bidi_p) - { - /* Note the paragraph direction that this buffer wants to - use. */ - if (EQ (BVAR (current_buffer, bidi_paragraph_direction), Qleft_to_right)) - it->paragraph_embedding = L2R; - else if (EQ (BVAR (current_buffer, bidi_paragraph_direction), Qright_to_left)) - it->paragraph_embedding = R2L; - else - it->paragraph_embedding = NEUTRAL_DIR; - bidi_init_it (charpos, bytepos, FRAME_WINDOW_P (it->f), &it->bidi_it); - } - /* If a buffer position was specified, set the iterator there, getting overlays and face properties from that position. */ if (charpos >= BUF_BEG (current_buffer)) @@ -2586,6 +2577,24 @@ init_iterator (struct it *it, struct window *w, it->start = it->current; + /* If we are to reorder bidirectional text, init the bidi + iterator. */ + if (it->bidi_p) + { + /* Note the paragraph direction that this buffer wants to + use. */ + if (EQ (BVAR (current_buffer, bidi_paragraph_direction), + Qleft_to_right)) + it->paragraph_embedding = L2R; + else if (EQ (BVAR (current_buffer, bidi_paragraph_direction), + Qright_to_left)) + it->paragraph_embedding = R2L; + else + it->paragraph_embedding = NEUTRAL_DIR; + bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f), + &it->bidi_it); + } + /* Compute faces etc. */ reseat (it, it->current.pos, 1); } @@ -5486,6 +5495,7 @@ reseat_1 (struct it *it, struct text_pos pos, int set_stop_p) it->bidi_it.paragraph_dir = NEUTRAL_DIR; it->bidi_it.disp_pos = -1; it->bidi_it.string.s = NULL; + it->bidi_it.string.lstring = Qnil; } if (set_stop_p) @@ -5536,6 +5546,8 @@ reseat_to_string (struct it *it, const char *s, Lisp_Object string, if (multibyte >= 0) it->multibyte_p = multibyte > 0; #if 0 + /* String reordering is controlled by the default value of + bidi-display-reordering. */ it->bidi_p = it->multibyte_p && BVAR (&buffer_defaults, bidi_display_reordering); #endif @@ -5550,9 +5562,15 @@ reseat_to_string (struct it *it, const char *s, Lisp_Object string, it->current.string_pos = string_pos (charpos, string); #if 0 if (it->bidi_p) - bidi_init_it (); - it->bidi_it.string.s = SDATA (string); - it->bidi_it.string.schars = it->end_charpos; + { + it->paragraph_embedding = NEUTRAL_DIR; + it->bidi_it.string.lstring = string; + it->bidi_it.string.s = SDATA (string); + it->bidi_it.string.schars = it->end_charpos; + it->bidi_it.string.from_disp_str = 0; + bidi_init_it (charpos, IT_STRING_BYTEPOS (*it), + FRAME_WINDOW_P (it->f), &it->bidi_it); + } #endif } else @@ -5569,18 +5587,22 @@ reseat_to_string (struct it *it, const char *s, Lisp_Object string, it->end_charpos = it->string_nchars = number_of_chars (s, 1); #if 0 if (it->bidi_p) - bidi_init_it (); - it->bidi_it.string.s = s; - it->bidi_it.string.schars = it->end_charpos; + { + it->paragraph_embedding = NEUTRAL_DIR; + it->bidi_it.string.lstring = Qnil; + it->bidi_it.string.s = s; + it->bidi_it.string.schars = it->end_charpos; + it->bidi_it.string.from_disp_str = 0; + bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f), + &it->bidi_it); + } #endif } else { + /* Unibyte (a.k.a. ASCII) C strings are never bidi-reordered. */ IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos; it->end_charpos = it->string_nchars = strlen (s); -#if 0 - it->bidi_p = 0; -#endif } it->method = GET_FROM_C_STRING; @@ -5589,7 +5611,13 @@ reseat_to_string (struct it *it, const char *s, Lisp_Object string, /* PRECISION > 0 means don't return more than PRECISION characters from the string. */ if (precision > 0 && it->end_charpos - charpos > precision) - it->end_charpos = it->string_nchars = charpos + precision; + { + it->end_charpos = it->string_nchars = charpos + precision; +#if 0 + if (it->bidi_p) + it->bidi_it.string.schars = it->end_charpos; +#endif + } /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH characters have been returned. FIELD_WIDTH == 0 means don't pad, @@ -5597,6 +5625,9 @@ reseat_to_string (struct it *it, const char *s, Lisp_Object string, padding with `-' at the end of a mode line. */ if (field_width < 0) field_width = INFINITY; + /* Implementation note: We deliberately don't enlarge + it->bidi_it.string.schars here to fit it->end_charpos, because + the bidi iterator cannot produce characters out of thin air. */ if (field_width > it->end_charpos - charpos) it->end_charpos = charpos + field_width; @@ -5605,6 +5636,16 @@ reseat_to_string (struct it *it, const char *s, Lisp_Object string, it->dp = XCHAR_TABLE (Vstandard_display_table); it->stop_charpos = charpos; +#if 0 + it->prev_stop = charpos; + it->base_level_stop = 0; + if (it->bidi_p) + { + it->bidi_it.first_elt = 1; + it->bidi_it.paragraph_dir = NEUTRAL_DIR; + it->bidi_it.disp_pos = -1; + } +#endif if (s == NULL && it->multibyte_p) { EMACS_INT endpos = SCHARS (it->string); @@ -19989,10 +20030,10 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st if (string && STRINGP (lisp_string)) /* LISP_STRING is the one returned by decode_mode_spec. We should ignore its text properties. */ - it->stop_charpos = -1; + it->stop_charpos = it->end_charpos; - /* If displaying STRING, set up the face of the iterator - from LISP_STRING, if that's given. */ + /* If displaying STRING, set up the face of the iterator from + FACE_STRING, if that's given. */ if (STRINGP (face_string)) { EMACS_INT endptr; -- 2.39.5