changeset 107991:74557d25410e

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.
author Eli Zaretskii <eliz@gnu.org>
date Sat, 10 Apr 2010 19:28:30 +0300
parents aec214e3b4dd
children 27128322dda6
files src/ChangeLog src/dispnew.c src/fringe.c src/w32term.c src/xdisp.c src/xterm.c
diffstat 6 files changed, 101 insertions(+), 59 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Sat Apr 10 15:40:35 2010 +0300
+++ b/src/ChangeLog	Sat Apr 10 19:28:30 2010 +0300
@@ -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
--- a/src/dispnew.c	Sat Apr 10 15:40:35 2010 +0300
+++ b/src/dispnew.c	Sat Apr 10 19:28:30 2010 +0300
@@ -4251,7 +4251,9 @@
 	     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 @@
     }
 
   /* 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);
--- a/src/fringe.c	Sat Apr 10 15:40:35 2010 +0300
+++ b/src/fringe.c	Sat Apr 10 19:28:30 2010 +0300
@@ -825,7 +825,7 @@
 {
   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 @@
 	  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;
 	    }
 	}
--- a/src/w32term.c	Sat Apr 10 15:40:35 2010 +0300
+++ b/src/w32term.c	Sat Apr 10 19:28:30 2010 +0300
@@ -5136,10 +5136,12 @@
 	}
 
       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;
 	}
 
--- a/src/xdisp.c	Sat Apr 10 15:40:35 2010 +0300
+++ b/src/xdisp.c	Sat Apr 10 19:28:30 2010 +0300
@@ -326,12 +326,14 @@
 /* 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 @@
 	     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 @@
 	  }
 	--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 @@
 	    		  - 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 @@
   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 @@
   /* 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 @@
   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 @@
      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
--- a/src/xterm.c	Sat Apr 10 15:40:35 2010 +0300
+++ b/src/xterm.c	Sat Apr 10 19:28:30 2010 +0300
@@ -7492,36 +7492,40 @@
       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;
-
-	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 HBAR_CURSOR:
-	  x_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR);
-	  break;
-
-	case NO_CURSOR:
-	  w->phys_cursor_width = 0;
-	  break;
-
-	default:
-	  abort ();
+	  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 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 NO_CURSOR:
+	      w->phys_cursor_width = 0;
+	      break;
+
+	    default:
+	      abort ();
+	    }
 	}
 
 #ifdef HAVE_X_I18N