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> 2009-10-10 Eli Zaretskii <eliz@gnu.org>
* xdisp.c (set_cursor_from_row): Skip over glyphs near end of row * 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) ...@@ -853,8 +853,11 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it)
{ {
EMACS_INT bytepos = bidi_it->bytepos; 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. */ /* 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 (); abort ();
if (dir == L2R) if (dir == L2R)
...@@ -883,9 +886,11 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it) ...@@ -883,9 +886,11 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it)
return; return;
/* If we are on a newline, get past it to where the next /* 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; pos = bidi_it->charpos;
if (FETCH_CHAR (bytepos) == '\n') if (bytepos > BEGV_BYTE && FETCH_CHAR (bytepos) == '\n')
{ {
bytepos++; bytepos++;
pos++; pos++;
...@@ -1900,8 +1905,6 @@ bidi_get_next_char_visually (struct bidi_it *bidi_it) ...@@ -1900,8 +1905,6 @@ bidi_get_next_char_visually (struct bidi_it *bidi_it)
old_level = bidi_it->resolved_level; old_level = bidi_it->resolved_level;
new_level = bidi_level_of_next_char (bidi_it); 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 /* Reordering of resolved levels (clause L2) is implemented by
jumping to the other edge of the level and flipping direction of jumping to the other edge of the level and flipping direction of
......
...@@ -370,6 +370,13 @@ struct glyph ...@@ -370,6 +370,13 @@ struct glyph
/* Non-zero means don't display cursor here. */ /* Non-zero means don't display cursor here. */
unsigned avoid_cursor_p : 1; 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 #define FACE_ID_BITS 20
/* Face of the glyph. This is a realized face ID, /* Face of the glyph. This is a realized face ID,
......
...@@ -1545,6 +1545,26 @@ append_glyph (it) ...@@ -1545,6 +1545,26 @@ append_glyph (it)
+ it->glyph_row->used[it->area]); + it->glyph_row->used[it->area]);
end = it->glyph_row->glyphs[1 + 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; for (i = 0;
i < it->pixel_width && glyph < end; i < it->pixel_width && glyph < end;
++i) ++i)
...@@ -1556,6 +1576,11 @@ append_glyph (it) ...@@ -1556,6 +1576,11 @@ append_glyph (it)
glyph->padding_p = i > 0; glyph->padding_p = i > 0;
glyph->charpos = CHARPOS (it->position); glyph->charpos = CHARPOS (it->position);
glyph->object = it->object; 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]; ++it->glyph_row->used[it->area];
++glyph; ++glyph;
......
...@@ -6571,6 +6571,12 @@ next_element_from_buffer (it) ...@@ -6571,6 +6571,12 @@ next_element_from_buffer (it)
|| FETCH_CHAR (it->bidi_it.bytepos) == '\n') || FETCH_CHAR (it->bidi_it.bytepos) == '\n')
{ {
bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it); 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); bidi_get_next_char_visually (&it->bidi_it);
} }
else else
...@@ -6585,6 +6591,8 @@ next_element_from_buffer (it) ...@@ -6585,6 +6591,8 @@ next_element_from_buffer (it)
it->bidi_it.charpos = IT_CHARPOS (*it); it->bidi_it.charpos = IT_CHARPOS (*it);
it->bidi_it.bytepos = IT_BYTEPOS (*it); it->bidi_it.bytepos = IT_BYTEPOS (*it);
bidi_paragraph_init (it->paragraph_embedding, &it->bidi_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 { do {
/* Now return to buffer position where we were asked to /* Now return to buffer position where we were asked to
get the next display element, and produce that. */ get the next display element, and produce that. */
...@@ -16538,27 +16546,6 @@ extend_face_to_end_of_line (it) ...@@ -16538,27 +16546,6 @@ extend_face_to_end_of_line (it)
while (it->current_x <= it->last_visible_x) while (it->current_x <= it->last_visible_x)
PRODUCE_GLYPHS (it); 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 /* 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. */ truncation glyph below and make us set the cursor on them, maybe. */
it->current_x = saved_x; it->current_x = saved_x;
...@@ -16850,6 +16837,10 @@ display_line (it) ...@@ -16850,6 +16837,10 @@ display_line (it)
row->displays_text_p = 1; row->displays_text_p = 1;
row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p; row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
it->starts_in_middle_of_char_p = 0; 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 /* Arrange the overlays nicely for our purposes. Usually, we call
display_line on only one line at a time, in which case this display_line on only one line at a time, in which case this
...@@ -20932,6 +20923,11 @@ append_glyph (it) ...@@ -20932,6 +20923,11 @@ append_glyph (it)
glyph->u.ch = it->char_to_display; glyph->u.ch = it->char_to_display;
glyph->slice = null_glyph_slice; glyph->slice = null_glyph_slice;
glyph->font_type = FONT_TYPE_UNKNOWN; 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]; ++it->glyph_row->used[area];
} }
else else
...@@ -20984,6 +20980,11 @@ append_composite_glyph (it) ...@@ -20984,6 +20980,11 @@ append_composite_glyph (it)
glyph->face_id = it->face_id; glyph->face_id = it->face_id;
glyph->slice = null_glyph_slice; glyph->slice = null_glyph_slice;
glyph->font_type = FONT_TYPE_UNKNOWN; 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]; ++it->glyph_row->used[area];
} }
else else
...@@ -21158,6 +21159,11 @@ produce_image_glyph (it) ...@@ -21158,6 +21159,11 @@ produce_image_glyph (it)
glyph->u.img_id = img->id; glyph->u.img_id = img->id;
glyph->slice = slice; glyph->slice = slice;
glyph->font_type = FONT_TYPE_UNKNOWN; 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]; ++it->glyph_row->used[area];
} }
else else
...@@ -21204,6 +21210,11 @@ append_stretch_glyph (it, object, width, height, ascent) ...@@ -21204,6 +21210,11 @@ append_stretch_glyph (it, object, width, height, ascent)
glyph->u.stretch.height = height; glyph->u.stretch.height = height;
glyph->slice = null_glyph_slice; glyph->slice = null_glyph_slice;
glyph->font_type = FONT_TYPE_UNKNOWN; 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]; ++it->glyph_row->used[area];
} }
else 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