src/dispextern.h (struct bidi_string_data): New member `unibyte'.
src/xdisp.c (handle_single_display_spec, next_overlay_string)
(get_overlay_strings_1, reseat_1, reseat_to_string)
(push_display_prop): Set up the `unibyte' member of bidi_it.string
correctly. Don't assume unibyte strings are not bidi-reordered.
(compute_display_string_pos)
(compute_display_string_end): Fix handling the case of C string.
src/bidi.c (bidi_count_bytes, bidi_char_at_pos): Accept an
additional argument UNIBYTE, and support unibyte strings. All
callers changed.
(bidi_fetch_char): Support unibyte strings.
+2011-07-01 Eli Zaretskii <eliz@gnu.org>
+
+ * dispextern.h (struct bidi_string_data): New member `unibyte'.
+
+ * xdisp.c (handle_single_display_spec, next_overlay_string)
+ (get_overlay_strings_1, reseat_1, reseat_to_string)
+ (push_display_prop): Set up the `unibyte' member of bidi_it.string
+ correctly. Don't assume unibyte strings are not bidi-reordered.
+ (compute_display_string_pos)
+ (compute_display_string_end): Fix handling the case of C string.
+
+ * bidi.c (bidi_count_bytes, bidi_char_at_pos): Accept an
+ additional argument UNIBYTE, and support unibyte strings. All
+ callers changed.
+ (bidi_fetch_char): Support unibyte strings.
+
2011-06-25 Eli Zaretskii <eliz@gnu.org>
* xdisp.c (set_iterator_to_next, get_visually_first_element): Use
Fetching characters
***********************************************************************/
-/* Count bytes in multibyte string S between BEG/BEGBYTE and END. BEG
- and END are zero-based character positions in S, BEGBYTE is byte
- position corresponding to BEG. */
+/* Count bytes in string S between BEG/BEGBYTE and END. BEG and END
+ are zero-based character positions in S, BEGBYTE is byte position
+ corresponding to BEG. UNIBYTE, if non-zero, means S is a unibyte
+ string. */
static inline EMACS_INT
bidi_count_bytes (const unsigned char *s, const EMACS_INT beg,
- const EMACS_INT begbyte, const EMACS_INT end)
+ const EMACS_INT begbyte, const EMACS_INT end, int unibyte)
{
EMACS_INT pos = beg;
const unsigned char *p = s + begbyte, *start = p;
- if (!CHAR_HEAD_P (*p))
- abort ();
-
- while (pos < end)
+ if (unibyte)
+ p = s + end;
+ else
{
- p += BYTES_BY_CHAR_HEAD (*p);
- pos++;
+ if (!CHAR_HEAD_P (*p))
+ abort ();
+
+ while (pos < end)
+ {
+ p += BYTES_BY_CHAR_HEAD (*p);
+ pos++;
+ }
}
return p - start;
/* Fetch and returns the character at byte position BYTEPOS. If S is
non-NULL, fetch the character from string S; otherwise fetch the
- character from the current buffer. */
+ character from the current buffer. UNIBYTE non-zero means S is a
+ unibyte string. */
static inline int
-bidi_char_at_pos (EMACS_INT bytepos, const unsigned char *s)
+bidi_char_at_pos (EMACS_INT bytepos, const unsigned char *s, int unibyte)
{
if (s)
- return STRING_CHAR (s + bytepos);
+ {
+ if (unibyte)
+ return s[bytepos];
+ else
+ return STRING_CHAR (s + bytepos);
+ }
else
return FETCH_MULTIBYTE_CHAR (bytepos);
}
ch = 0xFFFC;
disp_end_pos = compute_display_string_end (*disp_pos, string);
*nchars = disp_end_pos - *disp_pos;
+ if (*nchars <= 0)
+ abort ();
if (string->s)
*ch_len = bidi_count_bytes (string->s, *disp_pos, bytepos,
- disp_end_pos);
+ disp_end_pos, string->unibyte);
else if (STRINGP (string->lstring))
*ch_len = bidi_count_bytes (SDATA (string->lstring), *disp_pos,
- bytepos, disp_end_pos);
+ bytepos, disp_end_pos, string->unibyte);
else
*ch_len = CHAR_TO_BYTE (disp_end_pos) - bytepos;
}
{
EMACS_INT len;
- ch = STRING_CHAR_AND_LENGTH (string->s + bytepos, len);
- *ch_len = len;
+ if (!string->unibyte)
+ {
+ ch = STRING_CHAR_AND_LENGTH (string->s + bytepos, len);
+ *ch_len = len;
+ }
+ else
+ {
+ ch = UNIBYTE_TO_CHAR (string->s[bytepos]);
+ *ch_len = 1;
+ }
}
else if (STRINGP (string->lstring))
{
EMACS_INT len;
- ch = STRING_CHAR_AND_LENGTH (SDATA (string->lstring) + bytepos, len);
- *ch_len = len;
+ if (!string->unibyte)
+ {
+ ch = STRING_CHAR_AND_LENGTH (SDATA (string->lstring) + bytepos,
+ len);
+ *ch_len = len;
+ }
+ else
+ {
+ ch = UNIBYTE_TO_CHAR (SREF (string->lstring, bytepos));
+ *ch_len = 1;
+ }
}
else
{
pos = bidi_it->charpos;
s = STRINGP (bidi_it->string.lstring) ?
SDATA (bidi_it->string.lstring) : bidi_it->string.s;
- if (bytepos > begbyte && bidi_char_at_pos (bytepos, s) == '\n')
+ if (bytepos > begbyte
+ && bidi_char_at_pos (bytepos, s, bidi_it->string.unibyte) == '\n')
{
bytepos++;
pos++;
if (bidi_it->charpos < 0)
bidi_it->charpos = 0;
- bidi_it->bytepos = bidi_count_bytes (p, 0, 0, bidi_it->charpos);
+ bidi_it->bytepos = bidi_count_bytes (p, 0, 0, bidi_it->charpos,
+ bidi_it->string.unibyte);
}
else
{
&& bidi_it->ignore_bn_limit == -1 /* only if not already known */
&& bidi_it->charpos < eob /* not already at EOB */
&& bidi_explicit_dir_char (bidi_char_at_pos (bidi_it->bytepos
- + bidi_it->ch_len, s)))
+ + bidi_it->ch_len, s,
+ bidi_it->string.unibyte)))
{
/* Avoid pushing and popping embedding levels if the level run
is empty, as this breaks level runs where it shouldn't.
bidi_copy_it (&saved_it, bidi_it);
while (bidi_explicit_dir_char (bidi_char_at_pos (bidi_it->bytepos
- + bidi_it->ch_len, s)))
+ + bidi_it->ch_len, s,
+ bidi_it->string.unibyte)))
{
/* This advances to the next character, skipping any
characters covered by display strings. */
next_char =
bidi_it->charpos + bidi_it->nchars >= eob
? BIDI_EOB
- : bidi_char_at_pos (bidi_it->bytepos + bidi_it->ch_len, s);
+ : bidi_char_at_pos (bidi_it->bytepos + bidi_it->ch_len, s,
+ bidi_it->string.unibyte);
type_of_next = bidi_get_type (next_char, override);
if (type_of_next == WEAK_BN
next_char =
bidi_it->charpos + bidi_it->nchars >= eob
? BIDI_EOB
- : bidi_char_at_pos (bidi_it->bytepos + bidi_it->ch_len, s);
+ : bidi_char_at_pos (bidi_it->bytepos + bidi_it->ch_len, s,
+ bidi_it->string.unibyte);
type_of_next = bidi_get_type (next_char, override);
if (type_of_next == WEAK_ET
EMACS_INT bufpos; /* buffer position of lstring, or 0 if N/A */
unsigned from_disp_str : 1; /* 1 means the string comes from a
display property */
+ unsigned unibyte : 1; /* 1 means the string is unibyte */
};
/* Data type for reordering bidirectional text. */
Lisp_Object object =
(string && STRINGP (string->lstring)) ? string->lstring : Qnil;
Lisp_Object pos, spec;
- EMACS_INT eob = STRINGP (object) ? string->schars : ZV;
- EMACS_INT begb = STRINGP (object) ? 0 : BEGV;
+ int string_p = (string && (STRINGP (string->lstring) || string->s));
+ EMACS_INT eob = string_p ? string->schars : ZV;
+ EMACS_INT begb = string_p ? 0 : BEGV;
EMACS_INT bufpos, charpos = CHARPOS (*position);
struct text_pos tpos;
Lisp_Object object =
(string && STRINGP (string->lstring)) ? string->lstring : Qnil;
Lisp_Object pos = make_number (charpos);
- EMACS_INT eob = STRINGP (object) ? string->schars : ZV;
+ EMACS_INT eob =
+ (STRINGP (object) || (string && string->s)) ? string->schars : ZV;
if (charpos >= eob || (string->s && !STRINGP (object)))
return eob;
it->paragraph_embedding =
(it->bidi_p ? it->bidi_it.paragraph_dir : L2R);
- /* Do we need to reorder this display string? */
- if (it->multibyte_p)
- {
- if (BUFFERP (object))
- it->bidi_p =
- !NILP (BVAR (XBUFFER (object), bidi_display_reordering));
- else
- it->bidi_p =
- !NILP (BVAR (&buffer_defaults, bidi_display_reordering));
- }
- else
- it->bidi_p = 0;
-
/* Set up the bidi iterator for this display string. */
if (it->bidi_p)
{
it->bidi_it.string.schars = it->end_charpos;
it->bidi_it.string.bufpos = bufpos;
it->bidi_it.string.from_disp_str = 1;
+ it->bidi_it.string.unibyte = !it->multibyte_p;
bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
}
}
it->prev_stop = 0;
it->base_level_stop = 0;
- /* Do we need to reorder this overlay string? */
- it->bidi_p =
- it->multibyte_p
- && !NILP (BVAR (current_buffer, bidi_display_reordering));
-
/* Set up the bidi iterator for this overlay string. */
if (it->bidi_p)
{
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 (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
}
}
it->multibyte_p = STRING_MULTIBYTE (it->string);
it->method = GET_FROM_STRING;
- /* Do we need to reorder this overlay string? */
- it->bidi_p =
- it->multibyte_p
- && !NILP (BVAR (current_buffer, bidi_display_reordering));
-
/* Force paragraph direction to be that of the parent
buffer. */
it->paragraph_embedding = (it->bidi_p ? it->bidi_it.paragraph_dir : L2R);
it->bidi_it.string.schars = SCHARS (it->string);
it->bidi_it.string.bufpos = pos;
it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
+ it->bidi_it.string.unibyte = !it->multibyte_p;
bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
}
return 1;
it->bidi_it.string.s = NULL;
it->bidi_it.string.lstring = Qnil;
it->bidi_it.string.bufpos = 0;
+ it->bidi_it.string.unibyte = 0;
}
if (set_stop_p)
/* Bidirectional reordering of strings is controlled by the default
value of bidi-display-reordering. */
- it->bidi_p =
- !NILP (BVAR (&buffer_defaults, bidi_display_reordering))
- && it->multibyte_p;
+ it->bidi_p = !NILP (BVAR (&buffer_defaults, bidi_display_reordering));
if (s == NULL)
{
it->bidi_it.string.schars = it->end_charpos;
it->bidi_it.string.bufpos = 0;
it->bidi_it.string.from_disp_str = 0;
+ it->bidi_it.string.unibyte = !it->multibyte_p;
bidi_init_it (charpos, IT_STRING_BYTEPOS (*it),
FRAME_WINDOW_P (it->f), &it->bidi_it);
}
{
it->current.pos = c_string_pos (charpos, s, 1);
it->end_charpos = it->string_nchars = number_of_chars (s, 1);
-
- if (it->bidi_p)
- {
- it->bidi_it.string.lstring = Qnil;
- it->bidi_it.string.s = s;
- it->bidi_it.string.schars = it->end_charpos;
- it->bidi_it.string.bufpos = 0;
- it->bidi_it.string.from_disp_str = 0;
- bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
- &it->bidi_it);
- }
}
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 (it->bidi_p)
+ {
+ it->bidi_it.string.lstring = Qnil;
+ it->bidi_it.string.s = s;
+ it->bidi_it.string.schars = it->end_charpos;
+ it->bidi_it.string.bufpos = 0;
+ it->bidi_it.string.from_disp_str = 0;
+ it->bidi_it.string.unibyte = !it->multibyte_p;
+ bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
+ &it->bidi_it);
+ }
it->method = GET_FROM_C_STRING;
}
buffer. */
it->paragraph_embedding = (it->bidi_p ? it->bidi_it.paragraph_dir : L2R);
- /* Do we need to reorder this string? */
- if (it->multibyte_p)
- it->bidi_p = !NILP (BVAR (current_buffer, bidi_display_reordering));
- else
- it->bidi_p = 0;
-
/* Set up the bidi iterator for this display string. */
if (it->bidi_p)
{
it->bidi_it.string.schars = it->end_charpos;
it->bidi_it.string.bufpos = IT_CHARPOS (*it);
it->bidi_it.string.from_disp_str = 1;
+ it->bidi_it.string.unibyte = !it->multibyte_p;
bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
}
}