Commit f951a506 authored by Eli Zaretskii's avatar Eli Zaretskii

Implement cursor on the left fringe for R2L lines.

 xdisp.c (IT_OVERFLOW_NEWLINE_INTO_FRINGE): For R2L lines,
 consider the left fringe, not the right one.
 (set_cursor_from_row): 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.
 (extend_face_to_end_of_line): Append the stretch glyph only if its
 width is positive.
 (notice_overwritten_cursor, draw_phys_cursor_glyph)
 (erase_phys_cursor): For reversed cursor_row, support 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.
 fringe.c (draw_fringe_bitmap): For reversed glyph rows, allow
 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.
parent 2204f4de
......@@ -2,6 +2,31 @@
Implement display of R2L paragraphs in GUI sessions.
* xdisp.c (IT_OVERFLOW_NEWLINE_INTO_FRINGE): For R2L lines,
consider the left fringe, not the right one.
(set_cursor_from_row): 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.
(extend_face_to_end_of_line): Append the stretch glyph only if its
width is positive.
(notice_overwritten_cursor, draw_phys_cursor_glyph)
(erase_phys_cursor): For reversed cursor_row, support 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.
* fringe.c (draw_fringe_bitmap): For reversed glyph rows, allow
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 [HAVE_WINDOW_SYSTEM]: Add prototype for
append_stretch_glyph.
(set_cursor_from_row) <cursor_x>: Remove unused variable. Fix
......
......@@ -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);
......
......@@ -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;
}
}
......
......@@ -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;
}
......
......@@ -326,12 +326,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
......@@ -12600,9 +12602,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)
......@@ -12768,7 +12767,10 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
}
--glyph;
if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
break;
{
x--; /* can't use any pixel_width */
break;
}
x -= glyph->pixel_width;
}
......@@ -16851,20 +16853,23 @@ extend_face_to_end_of_line (it)
- 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;
if (stretch_width > 0)
{
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 */
}
......@@ -23221,7 +23226,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;
}
......@@ -23322,7 +23327,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;
......@@ -23402,7 +23409,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;
}
......@@ -23411,7 +23418,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
......
......@@ -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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment