From 6b682d2b398b241fe32fe98104ef0a58ec20bde9 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Mon, 15 Sep 2014 18:25:54 +0300 Subject: [PATCH] Fix display of R2L lines in partial-width windows. src/xdisp.c (init_iterator): Don't use it->bidi_p before it is assigned the correct value. (extend_face_to_end_of_line): Account for truncation and continuation glyphs in R2L rows when one of the fringes is not displayed. (display_line): Don't assign negative X offset to a row if we are going to produce a truncation glyph for it. When handling truncated R2L rows, consider the width of the left fringe instead of the right one. (produce_special_glyphs): Fix bogus assignments. --- src/ChangeLog | 14 +++++++++++++ src/xdisp.c | 56 +++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 57 insertions(+), 13 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index c32b4c44988..09b606d1dd5 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,17 @@ +2014-09-15 Eli Zaretskii + + Fix display of R2L lines in partial-width windows. + * xdisp.c (init_iterator): Don't use it->bidi_p before it is + assigned the correct value. + (extend_face_to_end_of_line): Account for truncation and + continuation glyphs in R2L rows when one of the fringes is not + displayed. + (display_line): Don't assign negative X offset to a row if we are + going to produce a truncation glyph for it. When handling + truncated R2L rows, consider the width of the left fringe instead + of the right one. + (produce_special_glyphs): Fix bogus assignments. + 2014-09-14 Eli Zaretskii * w32.c (fcntl): Support O_NONBLOCK fcntl on the write side of diff --git a/src/xdisp.c b/src/xdisp.c index 6b327c84290..909349b81b3 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -2994,12 +2994,8 @@ init_iterator (struct it *it, struct window *w, /* If we truncate lines, leave room for the truncation glyph(s) at the right margin. Otherwise, leave room for the continuation - glyph(s). Done only if the window has no fringes. Since we - don't know at this point whether there will be any R2L lines in - the window, we reserve space for truncation/continuation glyphs - even if only one of the fringes is absent. */ - if (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0 - || (it->bidi_p && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)) + glyph(s). Done only if the window has no right fringe. */ + if (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0) { if (it->line_wrap == TRUNCATE) it->last_visible_x -= it->truncation_pixel_width; @@ -3064,6 +3060,19 @@ init_iterator (struct it *it, struct window *w, iterator. */ if (it->bidi_p) { + /* Since we don't know at this point whether there will be + any R2L lines in the window, we reserve space for + truncation/continuation glyphs even if only the left + fringe is absent. */ + if (base_face_id == DEFAULT_FACE_ID + && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0 + && WINDOW_RIGHT_FRINGE_WIDTH (it->w) != 0) + { + if (it->line_wrap == TRUNCATE) + it->last_visible_x -= it->truncation_pixel_width; + else + it->last_visible_x -= it->continuation_pixel_width; + } /* Note the paragraph direction that this buffer wants to use. */ if (EQ (BVAR (current_buffer, bidi_paragraph_direction), @@ -19334,7 +19343,18 @@ extend_face_to_end_of_line (struct it *it) for (row_width = 0, g = row_start; g < row_end; g++) row_width += g->pixel_width; - stretch_width = window_box_width (it->w, TEXT_AREA) - row_width; + + /* FIXME: There are various minor display glitches in R2L + rows when only one of the fringes is missing. The + strange condition below produces the least bad effect. */ + if ((WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0) + == (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0) + || WINDOW_RIGHT_FRINGE_WIDTH (it->w) != 0) + stretch_width = window_box_width (it->w, TEXT_AREA); + else + stretch_width = it->last_visible_x - it->first_visible_x; + stretch_width -= row_width; + if (stretch_width > 0) { stretch_ascent = @@ -20475,9 +20495,17 @@ display_line (struct it *it) /* When the last glyph of an R2L row only fits partially on the line, we need to set row->x to a negative offset, so that the leftmost glyph is - the one that is partially visible. */ - if (row->reversed_p && new_x > it->last_visible_x) - row->x = it->last_visible_x - new_x; + the one that is partially visible. But if we are + going to produce the truncation glyph, this will + be taken care of in produce_special_glyphs. */ + if (row->reversed_p + && new_x > it->last_visible_x + && !(it->line_wrap == TRUNCATE + && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)) + { + eassert (FRAME_WINDOW_P (it->f)); + row->x = it->last_visible_x - new_x; + } } else { @@ -20551,7 +20579,10 @@ display_line (struct it *it) that they are cropped at the right edge of the window, so an image glyph will always end exactly at last_visible_x, even if there's no right fringe. */ - && (WINDOW_RIGHT_FRINGE_WIDTH (it->w) || it->what == IT_IMAGE)) + && ((row->reversed_p + ? WINDOW_LEFT_FRINGE_WIDTH (it->w) + : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) + || it->what == IT_IMAGE)) ? (it->current_x >= it->last_visible_x) : (it->current_x > it->last_visible_x))) { @@ -25719,14 +25750,13 @@ produce_special_glyphs (struct it *it, enum display_element_type what) temp_it.dp = NULL; temp_it.what = IT_CHARACTER; - temp_it.len = 1; temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph); temp_it.face_id = GLYPH_FACE (glyph); temp_it.len = CHAR_BYTES (temp_it.c); PRODUCE_GLYPHS (&temp_it); it->pixel_width = temp_it.pixel_width; - it->nglyphs = temp_it.pixel_width; + it->nglyphs = temp_it.nglyphs; } #ifdef HAVE_WINDOW_SYSTEM -- 2.39.2