]> git.eshelyaron.com Git - emacs.git/commitdiff
Implement cursor on the left fringe for R2L lines.
authorEli Zaretskii <eliz@gnu.org>
Sat, 10 Apr 2010 16:28:30 +0000 (19:28 +0300)
committerEli Zaretskii <eliz@gnu.org>
Sat, 10 Apr 2010 16:28:30 +0000 (19:28 +0300)
 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.

src/ChangeLog
src/dispnew.c
src/fringe.c
src/w32term.c
src/xdisp.c
src/xterm.c

index 268a245caf3e784c0342f74801ff688311f6f597..e6faa0a4c9e5a8fd7fcef783a53fa32697c2df41 100644 (file)
@@ -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
index 2be00c9c3b02f54e66e4976bb6d5e772e39c69af..7ab2bf358113230de610700273b47df3dc39a62e 100644 (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);
index 952e95a55179458fcb82007e059851a57d759d1e..335dde03c8ad96084df85902d2c865fd289faba6 100644 (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;
            }
        }
index 7222e26efd22fdcbf90161068ec3b72e6e1e0bf6..0b71b7e02b76c6e56aa7e822d272cac0e31fa5e9 100644 (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;
        }
 
index f93ed533c28f4dd839d7c2ea4d28e6e7eec0257b..1320b8a7380abb01b1cedf2e0e3fe82e6993e685 100644 (file)
@@ -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
index 29ed5bb865c77352a281af65098062334a8e50fa..712d4aaa162f65d07e83b9ff3db0203d492916c3 100644 (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