Implement GUI display of R2L lines, fix TTY display of R2L lines.

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.
 (append_stretch_glyph): In reversed row, prepend the glyph rather
 than append it.  Set resolved_level and bidi_type of the glyph.
 (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.  Fix off-by-one error on
 TTY frames in testing whether a line needs face extension.  Fix
 face extension at ZV.  If this is the last glyph row, use
 DEFAULT_FACE_ID, to avoid painting the rest of the window with the
 region face.
 (set_cursor_from_row, display_line): Use
 MATRIX_ROW_CONTINUATION_LINE_P instead of testing value of
 row->continuation_lines_width.
 (next_element_from_buffer): Don't call bidi_paragraph_init if we
 are at ZV.  Fixes a crash when reseated to ZV by
 try_window_reusing_current_matrix.
 (display_and_set_cursor, erase_phys_cursor): Handle negative HPOS,
 which happens with R2L glyph rows.  Fixes a crash when inserting a
 character at end of an R2L line.
 (set_cursor_from_row): Don't be fooled by truncated rows: don't
 treat them as having zero-width characters.  Improve comments.
 Don't reverse pos_before and pos_after for reversed glyph rows.
 Set cursor.x to negative value when the cursor might be on the
 left fringe.
 (IT_OVERFLOW_NEWLINE_INTO_FRINGE): For R2L lines, consider the
 left fringe, not the right one.
 (notice_overwritten_cursor, draw_phys_cursor_glyph)
 (erase_phys_cursor): For reversed cursor_row, support cursor on
 the left fringe.
 fringe.c (update_window_fringes): For R2L rows, swap the bitmaps
 of continuation indicators on the fringes.
 (draw_fringe_bitmap): For reversed glyph rows, allow cursor on the
 left fringe.
 w32term.c (w32_draw_window_cursor): For reversed glyph rows,
 draw cursor on the left fringe.
 xterm.c (x_draw_window_cursor): For reversed glyph rows, draw
 cursor on the left fringe.
 dispnew.c (update_text_area): Handle reversed desired rows when
 the cursor is on the left fringe.
 (set_window_cursor_after_update): Limit cursor's hpos by -1 from
 below, not by 0, for when the cursor is on the left fringe.

 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.
 (produce_special_glyphs): Mirror the backslash continuation
 character in R2L lines.
This commit is contained in:
Eli Zaretskii 2010-04-20 16:31:28 +03:00
commit 283ccc1841
7 changed files with 325 additions and 75 deletions

View file

@ -1,3 +1,70 @@
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.
(produce_special_glyphs): Mirror the backslash continuation
character in R2L lines.
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.
(append_stretch_glyph): In reversed row, prepend the glyph rather
than append it. Set resolved_level and bidi_type of the glyph.
(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. Fix off-by-one error on
TTY frames in testing whether a line needs face extension. Fix
face extension at ZV. If this is the last glyph row, use
DEFAULT_FACE_ID, to avoid painting the rest of the window with the
region face.
(set_cursor_from_row, display_line): Use
MATRIX_ROW_CONTINUATION_LINE_P instead of testing value of
row->continuation_lines_width.
(next_element_from_buffer): Don't call bidi_paragraph_init if we
are at ZV. Fixes a crash when reseated to ZV by
try_window_reusing_current_matrix.
(display_and_set_cursor, erase_phys_cursor): Handle negative HPOS,
which happens with R2L glyph rows. Fixes a crash when inserting a
character at end of an R2L line.
(set_cursor_from_row): Don't be fooled by truncated rows: don't
treat them as having zero-width characters. Improve comments.
Don't reverse pos_before and pos_after for reversed glyph rows.
Set cursor.x to negative value when the cursor might be on the
left fringe.
(IT_OVERFLOW_NEWLINE_INTO_FRINGE): For R2L lines, consider the
left fringe, not the right one.
(notice_overwritten_cursor, draw_phys_cursor_glyph)
(erase_phys_cursor): For reversed cursor_row, support cursor on
the left fringe.
* fringe.c (update_window_fringes): For R2L rows, swap the bitmaps
of continuation indicators on the fringes.
(draw_fringe_bitmap): For reversed glyph rows, allow cursor on the
left fringe.
* w32term.c (w32_draw_window_cursor): For reversed glyph rows,
draw cursor on the left fringe.
* xterm.c (x_draw_window_cursor): For reversed glyph rows, draw
cursor on the left fringe.
* dispnew.c (update_text_area): Handle reversed desired rows when
the cursor is on the left fringe.
(set_window_cursor_after_update): Limit cursor's hpos by -1 from
below, not by 0, for when the cursor is on the left fringe.
2010-04-20 Jan Djärv <jan.h.d@swipnet.se>
* gtkutil.c (xg_event_is_for_scrollbar): Check if grabbed

View file

@ -4251,7 +4251,9 @@ update_text_area (w, vpos)
doesn't work with lbearing/rbearing), so we must do it
this way. */
if (vpos == w->phys_cursor.vpos
&& w->phys_cursor.hpos >= desired_row->used[TEXT_AREA])
&& (desired_row->reversed_p
? (w->phys_cursor.hpos < 0)
: (w->phys_cursor.hpos >= desired_row->used[TEXT_AREA])))
{
w->phys_cursor_on_p = 0;
x = -1;
@ -4415,7 +4417,7 @@ set_window_cursor_after_update (w)
}
/* Window cursor can be out of sync for horizontally split windows. */
hpos = max (0, hpos);
hpos = max (-1, hpos); /* -1 is for when cursor is on the left fringe */
hpos = min (w->current_matrix->matrix_w - 1, hpos);
vpos = max (0, vpos);
vpos = min (w->current_matrix->nrows - 1, vpos);

View file

@ -825,7 +825,7 @@ draw_fringe_bitmap (w, row, left_p)
{
int overlay = 0;
if (!left_p && row->cursor_in_fringe_p)
if (left_p == row->reversed_p && row->cursor_in_fringe_p)
{
Lisp_Object cursor = Qnil;
@ -857,7 +857,7 @@ draw_fringe_bitmap (w, row, left_p)
int bm = get_logical_cursor_bitmap (w, cursor);
if (bm != NO_FRINGE_BITMAP)
{
draw_fringe_bitmap_1 (w, row, 0, 2, bm);
draw_fringe_bitmap_1 (w, row, left_p, 2, bm);
overlay = EQ (cursor, Qbox) ? 3 : 1;
}
}
@ -1090,7 +1090,8 @@ update_window_fringes (w, keep_current_p)
: LEFT_FRINGE (2, Qtop, 0));
else if (row->indicate_eob_p && EQ (boundary_bot, Qleft))
left = LEFT_FRINGE (3, Qbottom, row->ends_at_zv_p);
else if (MATRIX_ROW_CONTINUATION_LINE_P (row))
else if ((!row->reversed_p && MATRIX_ROW_CONTINUATION_LINE_P (row))
|| (row->reversed_p && row->continued_p))
left = LEFT_FRINGE (4, Qcontinuation, 0);
else if (row->indicate_empty_line_p && EQ (empty_pos, Qleft))
left = LEFT_FRINGE (5, Qempty_line, 0);
@ -1117,7 +1118,8 @@ update_window_fringes (w, keep_current_p)
: RIGHT_FRINGE (2, Qtop, 0));
else if (row->indicate_eob_p && EQ (boundary_bot, Qright))
right = RIGHT_FRINGE (3, Qbottom, row->ends_at_zv_p);
else if (row->continued_p)
else if ((!row->reversed_p && row->continued_p)
|| (row->reversed_p && MATRIX_ROW_CONTINUATION_LINE_P (row)))
right = RIGHT_FRINGE (4, Qcontinuation, 0);
else if (row->indicate_top_line_p && EQ (arrow_top, Qright))
right = RIGHT_FRINGE (6, Qup, 0);

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;
@ -1889,12 +1911,16 @@ produce_special_glyphs (it, what)
if (what == IT_CONTINUATION)
{
/* Continuation glyph. */
SET_GLYPH_FROM_CHAR (glyph, '\\');
/* Continuation glyph. For R2L lines, we mirror it by hand. */
if (it->bidi_it.paragraph_dir == R2L)
SET_GLYPH_FROM_CHAR (glyph, '/');
else
SET_GLYPH_FROM_CHAR (glyph, '\\');
if (it->dp
&& (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc))
&& GLYPH_CODE_CHAR_VALID_P (gc))
{
/* FIXME: Should we mirror GC for R2L lines? */
SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
}
@ -1907,6 +1933,7 @@ produce_special_glyphs (it, what)
&& (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc))
&& GLYPH_CODE_CHAR_VALID_P (gc))
{
/* FIXME: Should we mirror GC for R2L lines? */
SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
}

View file

@ -5136,10 +5136,12 @@ w32_draw_window_cursor (w, glyph_row, x, y, cursor_type, cursor_width, on_p, act
}
if (glyph_row->exact_window_width_line_p
&& w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA])
&& (glyph_row->reversed_p
? (w->phys_cursor.hpos < 0)
: (w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA])))
{
glyph_row->cursor_in_fringe_p = 1;
draw_fringe_bitmap (w, glyph_row, 0);
draw_fringe_bitmap (w, glyph_row, glyph_row->reversed_p);
return;
}

View file

@ -404,12 +404,14 @@ extern Lisp_Object Voverflow_newline_into_fringe;
/* Test if overflow newline into fringe. Called with iterator IT
at or past right window margin, and with IT->current_x set. */
#define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
(!NILP (Voverflow_newline_into_fringe) \
&& FRAME_WINDOW_P (it->f) \
&& WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
&& it->current_x == it->last_visible_x \
&& it->line_wrap != WORD_WRAP)
#define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
(!NILP (Voverflow_newline_into_fringe) \
&& FRAME_WINDOW_P ((IT)->f) \
&& ((IT)->bidi_it.paragraph_dir == R2L \
? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
: (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
&& (IT)->current_x == (IT)->last_visible_x \
&& (IT)->line_wrap != WORD_WRAP)
#else /* !HAVE_WINDOW_SYSTEM */
#define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
@ -1077,6 +1079,8 @@ static void display_tool_bar_line P_ ((struct it *, int));
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));
@ -6709,13 +6713,20 @@ next_element_from_buffer (it)
{
it->bidi_it.charpos = IT_CHARPOS (*it);
it->bidi_it.bytepos = IT_BYTEPOS (*it);
/* If we are at the beginning of a line, we can produce the next
element right away. */
if (it->bidi_it.bytepos == BEGV_BYTE
if (it->bidi_it.bytepos == ZV_BYTE)
{
/* Nothing to do, but reset the FIRST_ELT flag, like
bidi_paragraph_init does, because we are not going to
call it. */
it->bidi_it.first_elt = 0;
}
else if (it->bidi_it.bytepos == BEGV_BYTE
/* FIXME: Should support all Unicode line separators. */
|| FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
|| FETCH_CHAR (it->bidi_it.bytepos) == '\n')
{
/* If we are at the beginning of a line, we can produce the
next element right away. */
bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
bidi_get_next_char_visually (&it->bidi_it);
}
@ -12619,7 +12630,6 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
/* 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;
@ -12655,8 +12665,8 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
}
while (end > glyph
&& INTEGERP ((end - 1)->object)
/* CHARPOS is zero for blanks inserted by
extend_face_to_end_of_line. */
/* CHARPOS is zero for blanks and stretch glyphs
inserted by extend_face_to_end_of_line. */
&& (end - 1)->charpos <= 0)
--end;
glyph_before = glyph - 1;
@ -12670,9 +12680,6 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
to front, so swap the edge pointers. */
glyphs_end = end = glyph - 1;
glyph += row->used[TEXT_AREA] - 1;
/* Reverse the known positions in the row. */
last_pos = pos_after = MATRIX_ROW_START_CHARPOS (row) + delta;
pos_before = MATRIX_ROW_END_CHARPOS (row) + delta;
while (glyph > end + 1
&& INTEGERP (glyph->object)
@ -12687,7 +12694,6 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
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)
@ -12702,7 +12708,7 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
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
@ -12838,8 +12844,11 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
string_seen = 1;
}
--glyph;
if (glyph == end)
break;
if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
{
x--; /* can't use any pixel_width */
break;
}
x -= glyph->pixel_width;
}
@ -12879,7 +12888,10 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
}
else if (match_with_avoid_cursor
/* zero-width characters produce no glyphs */
|| eabs (glyph_after - glyph_before) == 1)
|| ((row->reversed_p
? glyph_after > glyphs_end
: glyph_after < glyphs_end)
&& eabs (glyph_after - glyph_before) == 1))
{
cursor = glyph_after;
x = -1;
@ -12998,16 +13010,17 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
}
}
/* ROW could be part of a continued line, which might have other
rows whose start and end charpos occlude point. Only set
w->cursor if we found a better approximation to the cursor
position than we have from previously examined rows. */
/* ROW could be part of a continued line, which, under bidi
reordering, might have other rows whose start and end charpos
occlude point. Only set w->cursor if we found a better
approximation to the cursor position than we have from previously
examined candidate rows belonging to the same continued line. */
if (/* we already have a candidate row */
w->cursor.vpos >= 0
/* that candidate is not the row we are processing */
&& MATRIX_ROW (matrix, w->cursor.vpos) != row
/* this row is part of a continued line */
&& (row->continued_p || row->continuation_lines_width)
/* the row we are processing is part of a continued line */
&& (row->continued_p || MATRIX_ROW_CONTINUATION_LINE_P (row))
/* Make sure cursor.vpos specifies a row whose start and end
charpos occlude point. This is because some callers of this
function leave cursor.vpos at the row where the cursor was
@ -16850,9 +16863,11 @@ append_space_for_newline (it, default_face_p)
/* 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)
@ -16861,15 +16876,17 @@ extend_face_to_end_of_line (it)
struct face *face;
struct frame *f = it->f;
/* If line is already filled, do nothing. */
if (it->current_x >= it->last_visible_x)
/* If line is already filled, do nothing. Non window-system frames
get a grace of one more ``pixel'' because their characters are
1-``pixel'' wide, so they hit the equality too early. */
if (it->current_x >= it->last_visible_x + !FRAME_WINDOW_P (f))
return;
/* Face extension extends the background and box of IT->face_id
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);
@ -16877,7 +16894,8 @@ extend_face_to_end_of_line (it)
&& 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
@ -16904,6 +16922,50 @@ extend_face_to_end_of_line (it)
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_width (it->w, TEXT_AREA) - row_width;
if (stretch_width > 0)
{
stretch_ascent =
(((it->ascent + it->descent)
* FONT_BASE (font)) / FONT_HEIGHT (font));
saved_pos = it->position;
bzero (&it->position, sizeof it->position);
saved_avoid_cursor = it->avoid_cursor_p;
it->avoid_cursor_p = 1;
saved_face_id = it->face_id;
/* The last row's stretch glyph should get the default
face, to avoid painting the rest of the window with
the region face, if the region ends at ZV. */
if (it->glyph_row->ends_at_zv_p)
it->face_id = DEFAULT_FACE_ID;
else
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
{
@ -16922,7 +16984,13 @@ extend_face_to_end_of_line (it)
it->object = make_number (0);
it->c = ' ';
it->len = 1;
it->face_id = face->id;
/* The last row's blank glyphs should get the default face, to
avoid painting the rest of the window with the region face,
if the region ends at ZV. */
if (it->glyph_row->ends_at_zv_p)
it->face_id = DEFAULT_FACE_ID;
else
it->face_id = face->id;
PRODUCE_GLYPHS (it);
@ -17208,6 +17276,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
@ -17472,6 +17565,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
@ -17494,6 +17590,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;
@ -17529,6 +17628,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. */
@ -17634,9 +17736,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)
{
@ -17823,7 +17938,7 @@ display_line (it)
*it = save_it;
}
else if (!row->continued_p
&& row->continuation_lines_width
&& MATRIX_ROW_CONTINUATION_LINE_P (row)
&& it->eol_pos.charpos > 0)
{
/* Last row of a continued line. Use the position
@ -21493,6 +21608,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;
@ -21738,6 +21864,17 @@ append_stretch_glyph (it, object, width, height, ascent)
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;
@ -21764,6 +21901,11 @@ append_stretch_glyph (it, object, width, height, ascent)
abort ();
glyph->bidi_type = it->bidi_it.type;
}
else
{
glyph->resolved_level = 0;
glyph->bidi_type = UNKNOWN_BT;
}
++it->glyph_row->used[area];
}
else
@ -23244,7 +23386,7 @@ notice_overwritten_cursor (w, area, x0, x1, y0, y1)
if (row->cursor_in_fringe_p)
{
row->cursor_in_fringe_p = 0;
draw_fringe_bitmap (w, row, 0);
draw_fringe_bitmap (w, row, row->reversed_p);
w->phys_cursor_on_p = 0;
return;
}
@ -23345,7 +23487,9 @@ draw_phys_cursor_glyph (w, row, hl)
/* If cursor hpos is out of bounds, don't draw garbage. This can
happen in mini-buffer windows when switching between echo area
glyphs and mini-buffer. */
if (w->phys_cursor.hpos < row->used[TEXT_AREA])
if ((row->reversed_p
? (w->phys_cursor.hpos >= 0)
: (w->phys_cursor.hpos < row->used[TEXT_AREA])))
{
int on_p = w->phys_cursor_on_p;
int x1;
@ -23425,7 +23569,7 @@ erase_phys_cursor (w)
if (cursor_row->cursor_in_fringe_p)
{
cursor_row->cursor_in_fringe_p = 0;
draw_fringe_bitmap (w, cursor_row, 0);
draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
goto mark_cursor_off;
}
@ -23434,7 +23578,9 @@ erase_phys_cursor (w)
should have cleared the cursor. Note that we wouldn't be
able to erase the cursor in this case because we don't have a
cursor glyph at hand. */
if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
if ((cursor_row->reversed_p
? (w->phys_cursor.hpos < 0)
: (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
goto mark_cursor_off;
/* If the cursor is in the mouse face area, redisplay that when
@ -23450,7 +23596,7 @@ erase_phys_cursor (w)
/* Don't redraw the cursor's spot in mouse face if it is at the
end of a line (on a newline). The cursor appears there, but
mouse highlighting does not. */
&& cursor_row->used[TEXT_AREA] > hpos)
&& cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
mouse_face_here_p = 1;
/* Maybe clear the display under the cursor. */
@ -23532,7 +23678,7 @@ display_and_set_cursor (w, on, hpos, vpos, x, y)
glyph = NULL;
if (!glyph_row->exact_window_width_line_p
|| hpos < glyph_row->used[TEXT_AREA])
|| (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
xassert (interrupt_input_blocked);

View file

@ -7492,36 +7492,40 @@ x_draw_window_cursor (w, glyph_row, x, y, cursor_type, cursor_width, on_p, activ
w->phys_cursor_on_p = 1;
if (glyph_row->exact_window_width_line_p
&& w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA])
&& (glyph_row->reversed_p
? (w->phys_cursor.hpos < 0)
: (w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA])))
{
glyph_row->cursor_in_fringe_p = 1;
draw_fringe_bitmap (w, glyph_row, 0);
draw_fringe_bitmap (w, glyph_row, glyph_row->reversed_p);
}
else
switch (cursor_type)
{
case HOLLOW_BOX_CURSOR:
x_draw_hollow_cursor (w, glyph_row);
break;
switch (cursor_type)
{
case HOLLOW_BOX_CURSOR:
x_draw_hollow_cursor (w, glyph_row);
break;
case FILLED_BOX_CURSOR:
draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
break;
case FILLED_BOX_CURSOR:
draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
break;
case BAR_CURSOR:
x_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR);
break;
case BAR_CURSOR:
x_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR);
break;
case HBAR_CURSOR:
x_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR);
break;
case HBAR_CURSOR:
x_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR);
break;
case NO_CURSOR:
w->phys_cursor_width = 0;
break;
case NO_CURSOR:
w->phys_cursor_width = 0;
break;
default:
abort ();
default:
abort ();
}
}
#ifdef HAVE_X_I18N