+2009-10-17 Eli Zaretskii <eliz@gnu.org>
+
+ * dispextern.h (struct glyph): New members resolved_level and
+ bidi_type.
+
+ * xdisp.c (append_glyph, append_composite_glyph)
+ (produce_image_glyph, append_stretch_glyph): Set them.
+
+ * term.c (append_glyph): Ditto.
+
+ * xdisp.c (display_line, next_element_from_buffer): Set the glyph
+ row's reversed_p flag if the paragraph base direction is odd.
+ (extend_face_to_end_of_line): Don't reverse the glyphs here.
+
+ * term.c (append_glyph): Reverse glyphs here.
+
+ * bidi.c (bidi_get_next_char_visually): Don't exit early when at
+ ZV.
+ (bidi_paragraph_init): Don't step over a newline if at BEGV.
+
+2009-10-16 Eli Zaretskii <eliz@gnu.org>
+
+ * bidi.c (bidi_paragraph_init): Handle empty buffers.
+
2009-10-10 Eli Zaretskii <eliz@gnu.org>
* xdisp.c (set_cursor_from_row): Skip over glyphs near end of row
{
EMACS_INT bytepos = bidi_it->bytepos;
+ /* Special case for an empty buffer. */
+ if (bytepos == BEGV_BYTE && bytepos == ZV_BYTE)
+ dir = L2R;
/* We should never be called at EOB or before BEGV. */
- if (bytepos >= ZV_BYTE || bytepos < BEGV_BYTE)
+ else if (bytepos >= ZV_BYTE || bytepos < BEGV_BYTE)
abort ();
if (dir == L2R)
return;
/* If we are on a newline, get past it to where the next
- paragraph might start. */
+ paragraph might start. But don't do that at BEGV since then
+ we are potentially in a new paragraph that doesn't yet
+ exist. */
pos = bidi_it->charpos;
- if (FETCH_CHAR (bytepos) == '\n')
+ if (bytepos > BEGV_BYTE && FETCH_CHAR (bytepos) == '\n')
{
bytepos++;
pos++;
old_level = bidi_it->resolved_level;
new_level = bidi_level_of_next_char (bidi_it);
- if (bidi_it->ch == BIDI_EOB)
- return;
/* Reordering of resolved levels (clause L2) is implemented by
jumping to the other edge of the level and flipping direction of
/* Non-zero means don't display cursor here. */
unsigned avoid_cursor_p : 1;
+ /* Resolved bidirection level of the characters [0..63]. */
+ unsigned resolved_level : 6;
+
+ /* Resolved bidirectional type of this character, see enum
+ bidi_type_t below. */
+ unsigned bidi_type : 5;
+
#define FACE_ID_BITS 20
/* Face of the glyph. This is a realized face ID,
+ it->glyph_row->used[it->area]);
end = it->glyph_row->glyphs[1 + it->area];
+ /* If the glyph row is reversed, we need to prepend the glyph rather
+ than append it. */
+ if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
+ {
+ struct glyph *g;
+ int move_by = it->pixel_width;
+
+ /* Make room for the new glyphs. */
+ if (move_by > end - glyph) /* don't overstep end of this area */
+ move_by = end - glyph;
+ for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
+ g[move_by] = *g;
+ glyph = it->glyph_row->glyphs[it->area];
+ end = glyph + move_by;
+ }
+
+ /* BIDI Note: we put the glyphs of a "multi-pixel" character left to
+ right, even in the REVERSED_P case, since (a) all of its u.ch are
+ identical, and (b) the PADDING_P flag needs to be set for the
+ leftmost one, because we write to the terminal left-to-right. */
for (i = 0;
i < it->pixel_width && glyph < end;
++i)
glyph->padding_p = i > 0;
glyph->charpos = CHARPOS (it->position);
glyph->object = it->object;
+ if (it->bidi_p)
+ {
+ glyph->resolved_level = it->bidi_it.resolved_level;
+ glyph->bidi_type = it->bidi_it.type;
+ }
++it->glyph_row->used[it->area];
++glyph;
|| FETCH_CHAR (it->bidi_it.bytepos) == '\n')
{
bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
+ /* If the paragraph base direction is R2L, its glyphs should
+ be reversed. */
+ if (it->glyph_row && (it->bidi_it.level_stack[0].level & 1) != 0)
+ it->glyph_row->reversed_p = 1;
+ if (it->glyph_row && (it->bidi_it.level_stack[0].level & 1) != 0)
+ it->glyph_row->reversed_p = 1;
bidi_get_next_char_visually (&it->bidi_it);
}
else
it->bidi_it.charpos = IT_CHARPOS (*it);
it->bidi_it.bytepos = IT_BYTEPOS (*it);
bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
+ if (it->glyph_row && (it->bidi_it.level_stack[0].level & 1) != 0)
+ it->glyph_row->reversed_p = 1;
do {
/* Now return to buffer position where we were asked to
get the next display element, and produce that. */
while (it->current_x <= it->last_visible_x)
PRODUCE_GLYPHS (it);
- /* If the paragraph base direction is right to left, reverse the
- glyphs of a non-empty glyph row. */
- if (it->bidi_p && it->bidi_it.level_stack[0].level == 1)
- {
- if (text_len > 0)
- {
- struct glyph *gleft = it->glyph_row->glyphs[TEXT_AREA];
- struct glyph *gright =
- gleft + it->glyph_row->used[TEXT_AREA] - 1;
- struct glyph tem;
-
- for ( ; gleft < gright; gleft++, gright--)
- {
- tem = *gleft;
- *gleft = *gright;
- *gright = tem;
- }
- }
- it->glyph_row->reversed_p = 1;
- }
-
/* Don't count these blanks really. It would let us insert a left
truncation glyph below and make us set the cursor on them, maybe. */
it->current_x = saved_x;
row->displays_text_p = 1;
row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
it->starts_in_middle_of_char_p = 0;
+ /* If the paragraph base direction is R2L, its glyphs should be
+ reversed. */
+ if (it->bidi_p && (it->bidi_it.level_stack[0].level & 1) != 0)
+ row->reversed_p = 1;
/* Arrange the overlays nicely for our purposes. Usually, we call
display_line on only one line at a time, in which case this
glyph->u.ch = it->char_to_display;
glyph->slice = null_glyph_slice;
glyph->font_type = FONT_TYPE_UNKNOWN;
+ if (it->bidi_p)
+ {
+ glyph->resolved_level = it->bidi_it.resolved_level;
+ glyph->bidi_type = it->bidi_it.type;
+ }
++it->glyph_row->used[area];
}
else
glyph->face_id = it->face_id;
glyph->slice = null_glyph_slice;
glyph->font_type = FONT_TYPE_UNKNOWN;
+ if (it->bidi_p)
+ {
+ glyph->resolved_level = it->bidi_it.resolved_level;
+ glyph->bidi_type = it->bidi_it.type;
+ }
++it->glyph_row->used[area];
}
else
glyph->u.img_id = img->id;
glyph->slice = slice;
glyph->font_type = FONT_TYPE_UNKNOWN;
+ if (it->bidi_p)
+ {
+ glyph->resolved_level = it->bidi_it.resolved_level;
+ glyph->bidi_type = it->bidi_it.type;
+ }
++it->glyph_row->used[area];
}
else
glyph->u.stretch.height = height;
glyph->slice = null_glyph_slice;
glyph->font_type = FONT_TYPE_UNKNOWN;
+ if (it->bidi_p)
+ {
+ glyph->resolved_level = it->bidi_it.resolved_level;
+ glyph->bidi_type = it->bidi_it.type;
+ }
++it->glyph_row->used[area];
}
else