Fix R2L paragraph display on TTY.

xdisp.c (unproduce_glyphs): New function.
 (display_line): Use it when produced glyphs are discarded from R2L
 glyph rows.
 (append_composite_glyph): In R2L rows, prepend the glyph rather
 than appending it.
 term.c (append_composite_glyph): In R2L rows, prepend the glyph
 rather than append it.  Set up the resolved_level and bidi_type
 attributes of the appended glyph.
This commit is contained in:
Eli Zaretskii 2010-04-20 16:08:35 +03:00
parent 43a03da53d
commit 93d68d0c2b
3 changed files with 102 additions and 7 deletions

View file

@ -1,5 +1,21 @@
2010-04-20 Eli Zaretskii <eliz@gnu.org>
Fix R2L paragraph display on TTY.
* xdisp.c (unproduce_glyphs): New function.
(display_line): Use it when produced glyphs are discarded from R2L
glyph rows.
(append_composite_glyph): In R2L rows, prepend the glyph rather
than appending it.
* term.c (append_composite_glyph): In R2L rows, prepend the glyph
rather than append it. Set up the resolved_level and bidi_type
attributes of the appended glyph.
2010-04-17 Eli Zaretskii <eliz@gnu.org>
Continue work on R2L paragraphs in GUI sessions.
* xdisp.c (extend_face_to_end_of_line): Fix off-by-one error on
TTY frames in testing whether a line needs face extension.
@ -22,8 +38,6 @@
which happens with R2L glyph rows. Fixes a crash when inserting a
character at end of an R2L line.
Continue work on R2L paragraphs in GUI sessions.
* xdisp.c (set_cursor_from_row): Don't be fooled by truncated
rows: don't treat them as having zero-width characters. Improve
comments.

View file

@ -1589,7 +1589,6 @@ append_glyph (it)
}
}
/* Produce glyphs for the display element described by IT. *IT
specifies what we want to produce a glyph for (character, image, ...),
and where in the glyph matrix we currently are (glyph row and hpos).
@ -1808,6 +1807,17 @@ append_composite_glyph (it)
glyph = it->glyph_row->glyphs[it->area] + it->glyph_row->used[it->area];
if (glyph < 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;
/* Make room for the new glyph. */
for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
g[1] = *g;
glyph = it->glyph_row->glyphs[it->area];
}
glyph->type = COMPOSITE_GLYPH;
glyph->pixel_width = it->pixel_width;
glyph->u.cmp.id = it->cmp_it.id;
@ -1828,6 +1838,18 @@ append_composite_glyph (it)
glyph->padding_p = 0;
glyph->charpos = CHARPOS (it->position);
glyph->object = it->object;
if (it->bidi_p)
{
glyph->resolved_level = it->bidi_it.resolved_level;
if ((it->bidi_it.type & 7) != it->bidi_it.type)
abort ();
glyph->bidi_type = it->bidi_it.type;
}
else
{
glyph->resolved_level = 0;
glyph->bidi_type = UNKNOWN_BT;
}
++it->glyph_row->used[it->area];
++glyph;

View file

@ -17203,6 +17203,31 @@ handle_line_prefix (struct it *it)
/* Remove N glyphs at the start of a reversed IT->glyph_row. Called
only for R2L lines from display_line, when it decides that too many
glyphs were produced by PRODUCE_GLYPHS, and the line needs to be
continued. */
static void
unproduce_glyphs (it, n)
struct it *it;
int n;
{
struct glyph *glyph, *end;
xassert (it->glyph_row);
xassert (it->glyph_row->reversed_p);
xassert (it->area == TEXT_AREA);
xassert (n <= it->glyph_row->used[TEXT_AREA]);
if (n > it->glyph_row->used[TEXT_AREA])
n = it->glyph_row->used[TEXT_AREA];
glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
for ( ; glyph < end; glyph++)
glyph[-n] = *glyph;
}
/* Construct the glyph row IT->glyph_row in the desired matrix of
IT->w from text at the current position of IT. See dispextern.h
for an overview of struct it. Value is non-zero if
@ -17467,6 +17492,9 @@ display_line (it)
/* A padding glyph that doesn't fit on this line.
This means the whole character doesn't fit
on the line. */
if (row->reversed_p)
unproduce_glyphs (it, row->used[TEXT_AREA]
- n_glyphs_before);
row->used[TEXT_AREA] = n_glyphs_before;
/* Fill the rest of the row with continuation
@ -17489,6 +17517,9 @@ display_line (it)
else if (wrap_row_used > 0)
{
back_to_wrap:
if (row->reversed_p)
unproduce_glyphs (it,
row->used[TEXT_AREA] - wrap_row_used);
*it = wrap_it;
it->continuation_lines_width += wrap_x;
row->used[TEXT_AREA] = wrap_row_used;
@ -17524,6 +17555,9 @@ display_line (it)
/* Something other than a TAB that draws past
the right edge of the window. Restore
positions to values before the element. */
if (row->reversed_p)
unproduce_glyphs (it, row->used[TEXT_AREA]
- (n_glyphs_before + i));
row->used[TEXT_AREA] = n_glyphs_before + i;
/* Display continuation glyphs. */
@ -17629,9 +17663,22 @@ display_line (it)
{
int i, n;
for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
break;
if (!row->reversed_p)
{
for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
break;
}
else
{
for (i = 0; i < row->used[TEXT_AREA]; i++)
if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
break;
/* Remove padding glyphs at the front of ROW, to
make room for the truncation glyphs we will be
adding below. */
unproduce_glyphs (it, i);
}
for (n = row->used[TEXT_AREA]; i < n; ++i)
{
@ -17882,7 +17929,8 @@ display_line (it)
/* The next row should use same value of the reversed_p flag as this
one. set_iterator_to_next decides when it's a new paragraph, and
PRODUCE_GLYPHS recomputes the value of the flag accordingly. */
it->glyph_row->reversed_p = row->reversed_p;
if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
it->glyph_row->reversed_p = row->reversed_p;
it->start = row_end;
return row->displays_text_p;
}
@ -21486,6 +21534,17 @@ append_composite_glyph (it)
glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
if (glyph < it->glyph_row->glyphs[area + 1])
{
/* 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;
/* Make room for the new glyph. */
for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
g[1] = *g;
glyph = it->glyph_row->glyphs[it->area];
}
glyph->charpos = CHARPOS (it->position);
glyph->object = it->object;
glyph->pixel_width = it->pixel_width;