Mercurial > emacs
changeset 107990:aec214e3b4dd
Initial implementation of display of R2L paragraphs in GUI sessions.
xdisp.c [HAVE_WINDOW_SYSTEM]: Add prototype for
append_stretch_glyph.
(set_cursor_from_row) <cursor_x>: Remove unused variable. Fix
off-by-one error in computing x at end of text in the row.
(extend_face_to_end_of_line): If the row is reversed, prepend a
stretch glyph whose width is such that the rightmost glyph will be
drawn at the right margin of the window.
(append_stretch_glyph): In reversed row, prepend the glyph rather
than append it. Set resolved_level and bidi_type of the glyph.
author | Eli Zaretskii <eliz@gnu.org> |
---|---|
date | Sat, 10 Apr 2010 15:40:35 +0300 |
parents | 29a7e4af9d84 |
children | 74557d25410e |
files | src/ChangeLog src/xdisp.c |
diffstat | 2 files changed, 80 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/src/ChangeLog Fri Apr 09 14:17:35 2010 +0300 +++ b/src/ChangeLog Sat Apr 10 15:40:35 2010 +0300 @@ -1,3 +1,17 @@ +2010-04-10 Eli Zaretskii <eliz@gnu.org> + + Implement display of R2L paragraphs in GUI sessions. + + * xdisp.c [HAVE_WINDOW_SYSTEM]: Add prototype for + append_stretch_glyph. + (set_cursor_from_row) <cursor_x>: Remove unused variable. Fix + off-by-one error in computing x at end of text in the row. + (extend_face_to_end_of_line): If the row is reversed, prepend a + stretch glyph whose width is such that the rightmost glyph will be + drawn at the right margin of the window. + (append_stretch_glyph): In reversed row, prepend the glyph rather + than append it. Set resolved_level and bidi_type of the glyph. + 2010-04-08 Eli Zaretskii <eliz@gnu.org> * xdisp.c (set_cursor_from_row): Don't dereference glyphs beyond
--- a/src/xdisp.c Fri Apr 09 14:17:35 2010 +0300 +++ b/src/xdisp.c Sat Apr 10 15:40:35 2010 +0300 @@ -999,6 +999,8 @@ static void notice_overwritten_cursor P_ ((struct window *, enum glyph_row_area, int, int, int, int)); +static void append_stretch_glyph P_ ((struct it *, Lisp_Object, + int, int, int)); @@ -12548,7 +12550,6 @@ /* The last known character position in row. */ int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta; int x = row->x; - int cursor_x = x; EMACS_INT pt_old = PT - delta; EMACS_INT pos_before = MATRIX_ROW_START_CHARPOS (row) + delta; EMACS_INT pos_after = MATRIX_ROW_END_CHARPOS (row) + delta; @@ -12616,7 +12617,6 @@ rightmost (first in the reading order) glyph. */ for (g = end + 1; g < glyph; g++) x += g->pixel_width; - cursor_x = x; while (end < glyph && INTEGERP ((end + 1)->object) && (end + 1)->charpos <= 0) @@ -12631,7 +12631,7 @@ rightmost glyph. Case in point: an empty last line that is part of an R2L paragraph. */ cursor = end - 1; - x = -1; /* will be computed below, at lable compute_x */ + x = -1; /* will be computed below, at label compute_x */ } /* Step 1: Try to find the glyph whose character position @@ -12767,7 +12767,7 @@ string_seen = 1; } --glyph; - if (glyph == end) + if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */ break; x -= glyph->pixel_width; } @@ -16772,9 +16772,11 @@ /* Extend the face of the last glyph in the text area of IT->glyph_row - to the end of the display line. Called from display_line. - If the glyph row is empty, add a space glyph to it so that we - know the face to draw. Set the glyph row flag fill_line_p. */ + to the end of the display line. Called from display_line. If the + glyph row is empty, add a space glyph to it so that we know the + face to draw. Set the glyph row flag fill_line_p. If the glyph + row is R2L, prepend a stretch glyph to cover the empty space to the + left of the leftmost glyph. */ static void extend_face_to_end_of_line (it) @@ -16791,7 +16793,7 @@ to the end of the line. If the background equals the background of the frame, we don't have to do anything. */ if (it->face_before_selective_p) - face = FACE_FROM_ID (it->f, it->saved_face_id); + face = FACE_FROM_ID (f, it->saved_face_id); else face = FACE_FROM_ID (f, it->face_id); @@ -16799,7 +16801,8 @@ && it->glyph_row->displays_text_p && face->box == FACE_NO_BOX && face->background == FRAME_BACKGROUND_PIXEL (f) - && !face->stipple) + && !face->stipple + && !it->glyph_row->reversed_p) return; /* Set the glyph row flag indicating that the face of the last glyph @@ -16826,6 +16829,44 @@ it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id; it->glyph_row->used[TEXT_AREA] = 1; } +#ifdef HAVE_WINDOW_SYSTEM + if (it->glyph_row->reversed_p) + { + /* Prepend a stretch glyph to the row, such that the + rightmost glyph will be drawn flushed all the way to the + right margin of the window. The stretch glyph that will + occupy the empty space, if any, to the left of the + glyphs. */ + struct font *font = face->font ? face->font : FRAME_FONT (f); + struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA]; + struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA]; + struct glyph *g; + int row_width, stretch_ascent, stretch_width; + struct text_pos saved_pos; + int saved_face_id, saved_avoid_cursor; + + for (row_width = 0, g = row_start; g < row_end; g++) + row_width += g->pixel_width; + stretch_width = WINDOW_BOX_RIGHT_EDGE_X(it->w) + - WINDOW_BOX_LEFT_EDGE_X(it->w) + - WINDOW_TOTAL_FRINGE_WIDTH(it->w) + - row_width; + stretch_ascent = + (((it->ascent + it->descent) + * FONT_BASE (font)) / FONT_HEIGHT (font)); + saved_pos = it->position; + saved_avoid_cursor = it->avoid_cursor_p; + saved_face_id = it->face_id; + bzero (&it->position, sizeof it->position); + it->avoid_cursor_p = 1; + it->face_id = face->id; + append_stretch_glyph (it, make_number (0), stretch_width, + it->ascent + it->descent, stretch_ascent); + it->position = saved_pos; + it->avoid_cursor_p = saved_avoid_cursor; + it->face_id = saved_face_id; + } +#endif /* HAVE_WINDOW_SYSTEM */ } else { @@ -21658,6 +21699,17 @@ 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 && area == TEXT_AREA) + { + struct glyph *g; + + /* Make room for the additional glyph. */ + for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--) + g[1] = *g; + glyph = it->glyph_row->glyphs[area]; + } glyph->charpos = CHARPOS (it->position); glyph->object = object; glyph->pixel_width = width; @@ -21684,6 +21736,11 @@ abort (); glyph->bidi_type = it->bidi_it.type; } + else + { + glyph->resolved_level = 0; + glyph->bidi_type = UNKNOWN_BT; + } ++it->glyph_row->used[area]; } else