Commit 5e65aec0 authored by Eli Zaretskii's avatar Eli Zaretskii
Browse files

Retrospective commit from 2009-10-17.

Continue working on display of R2L glyph rows.  Reverse glyphs in
term.c:append_glyph rather than in extend_face_to_end_of_line.
Fix bidi iteration near BEGV and ZV.

 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.
 (bidi_paragraph_init): Handle empty buffers.
parent e5a2fec7
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
......
......@@ -853,8 +853,11 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it)
{
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)
......@@ -883,9 +886,11 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it)
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++;
......@@ -1900,8 +1905,6 @@ bidi_get_next_char_visually (struct bidi_it *bidi_it)
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
......
......@@ -370,6 +370,13 @@ struct glyph
/* 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,
......
......@@ -1545,6 +1545,26 @@ append_glyph (it)
+ 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)
......@@ -1556,6 +1576,11 @@ append_glyph (it)
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;
......
......@@ -6571,6 +6571,12 @@ next_element_from_buffer (it)
|| 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
......@@ -6585,6 +6591,8 @@ next_element_from_buffer (it)
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. */
......@@ -16538,27 +16546,6 @@ extend_face_to_end_of_line (it)
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;
......@@ -16850,6 +16837,10 @@ display_line (it)
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
......@@ -20932,6 +20923,11 @@ append_glyph (it)
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
......@@ -20984,6 +20980,11 @@ append_composite_glyph (it)
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
......@@ -21158,6 +21159,11 @@ produce_image_glyph (it)
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
......@@ -21204,6 +21210,11 @@ append_stretch_glyph (it, object, width, height, ascent)
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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment