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
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;
}
/* 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);
{
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;
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;
}
}
}
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;
}
/* 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
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)
}
--glyph;
if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
- break;
+ {
+ x--; /* can't use any pixel_width */
+ break;
+ }
x -= glyph->pixel_width;
}
- 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 */
}
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;
}
/* 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;
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;
}
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
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