+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.
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.
}
}
-
/* 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).
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;
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;
\f
+/* 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
/* 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
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;
/* 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. */
{
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)
{
/* 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;
}
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;