From: Eli Zaretskii Date: Tue, 20 Apr 2010 13:08:35 +0000 (+0300) Subject: Fix R2L paragraph display on TTY. X-Git-Tag: emacs-pretest-24.0.90~104^2~275^2~438^2~473^2 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=93d68d0c2b085f65a867024fb8e7e28a629a003a;p=emacs.git 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. --- diff --git a/src/ChangeLog b/src/ChangeLog index 7f081d9563f..9a83f0c8bc7 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,21 @@ +2010-04-20 Eli Zaretskii + + 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 + 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. diff --git a/src/term.c b/src/term.c index 31e0ad223db..eda19d21374 100644 --- a/src/term.c +++ b/src/term.c @@ -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; diff --git a/src/xdisp.c b/src/xdisp.c index d11812ceb65..721af7b0251 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -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;