Implement GUI display of R2L lines, fix TTY display of R2L lines.
[bpt/emacs.git] / src / xdisp.c
index 8f36613..3f590f3 100644 (file)
@@ -32,9 +32,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
    decides it's time to do it.  This is done either automatically for
    you as part of the interpreter's command loop or as the result of
    calling Lisp functions like `sit-for'.  The C function `redisplay'
-   in xdisp.c is the only entry into the inner redisplay code.  (Or,
-   let's say almost---see the description of direct update
-   operations, below.)
+   in xdisp.c is the only entry into the inner redisplay code.
 
    The following diagram shows how redisplay code is invoked.  As you
    can see, Lisp calls redisplay and vice versa.  Under window systems
@@ -46,12 +44,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
    change the interpreter's state.  If you don't follow these rules,
    you will encounter bugs which are very hard to explain.
 
-            (Direct functions, see below)
-             direct_output_for_insert,
-             direct_forward_char (dispnew.c)
-         +---------------------------------+
-          |                                 |
-         |                                 V
    +--------------+   redisplay     +----------------+
    | Lisp machine |---------------->| Redisplay code |<--+
    +--------------+   (xdisp.c)     +----------------+   |
@@ -85,27 +77,42 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
    then compared to find a cheap way to update the display, e.g. by
    reusing part of the display by scrolling lines.
 
-
-   Direct operations.
-
    You will find a lot of redisplay optimizations when you start
    looking at the innards of redisplay.  The overall goal of all these
    optimizations is to make redisplay fast because it is done
-   frequently.
+   frequently.  Some of these optimizations are implemented by the
+   following functions:
+
+    . try_cursor_movement
+
+      This function tries to update the display if the text in the
+      window did not change and did not scroll, only point moved, and
+      it did not move off the displayed portion of the text.
+
+    . try_window_reusing_current_matrix
+
+      This function reuses the current matrix of a window when text
+      has not changed, but the window start changed (e.g., due to
+      scrolling).
+
+    . try_window_id
 
-   Two optimizations are not found in xdisp.c.  These are the direct
-   operations mentioned above.  As the name suggests they follow a
-   different principle than the rest of redisplay.  Instead of
-   building a desired matrix and then comparing it with the current
-   display, they perform their actions directly on the display and on
-   the current matrix.
+      This function attempts to redisplay a window by reusing parts of
+      its existing display.  It finds and reuses the part that was not
+      changed, and redraws the rest.
 
-   One direct operation updates the display after one character has
-   been entered.  The other one moves the cursor by one position
-   forward or backward.  You find these functions under the names
-   `direct_output_for_insert' and `direct_output_forward_char' in
-   dispnew.c.
+    . try_window
 
+      This function performs the full redisplay of a single window
+      assuming that its fonts were not changed and that the cursor
+      will not end up in the scroll margins.  (Loading fonts requires
+      re-adjustment of dimensions of glyph matrices, which makes this
+      method impossible to use.)
+
+   These optimizations are tried in sequence (some can be skipped if
+   it is known that they are not applicable).  If none of the
+   optimizations were successful, redisplay calls redisplay_windows,
+   which performs a full redisplay of all windows.
 
    Desired matrices.
 
@@ -137,13 +144,16 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
    see in dispextern.h.
 
    Glyphs in a desired matrix are normally constructed in a loop
-   calling get_next_display_element and then produce_glyphs.  The call
-   to produce_glyphs will fill the iterator structure with pixel
+   calling get_next_display_element and then PRODUCE_GLYPHS.  The call
+   to PRODUCE_GLYPHS will fill the iterator structure with pixel
    information about the element being displayed and at the same time
    produce glyphs for it.  If the display element fits on the line
    being displayed, set_iterator_to_next is called next, otherwise the
-   glyphs produced are discarded.
-
+   glyphs produced are discarded.  The function display_line is the
+   workhorse of filling glyph rows in the desired matrix with glyphs.
+   In addition to producing glyphs, it also handles line truncation
+   and continuation, word wrap, and cursor positioning (for the
+   latter, see also set_cursor_from_row).
 
    Frame matrices.
 
@@ -164,7 +174,50 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
    wanted to have without having to move many bytes around.  To be
    honest, there is a little bit more done, but not much more.  If you
    plan to extend that code, take a look at dispnew.c.  The function
-   build_frame_matrix is a good starting point.  */
+   build_frame_matrix is a good starting point.
+
+   Bidirectional display.
+
+   Bidirectional display adds quite some hair to this already complex
+   design.  The good news are that a large portion of that hairy stuff
+   is hidden in bidi.c behind only 3 interfaces.  bidi.c implements a
+   reordering engine which is called by set_iterator_to_next and
+   returns the next character to display in the visual order.  See
+   commentary on bidi.c for more details.  As far as redisplay is
+   concerned, the effect of calling bidi_get_next_char_visually, the
+   main interface of the reordering engine, is that the iterator gets
+   magically placed on the buffer or string position that is to be
+   displayed next.  In other words, a linear iteration through the
+   buffer/string is replaced with a non-linear one.  All the rest of
+   the redisplay is oblivious to the bidi reordering.
+
+   Well, almost oblivious---there are still complications, most of
+   them due to the fact that buffer and string positions no longer
+   change monotonously with glyph indices in a glyph row.  Moreover,
+   for continued lines, the buffer positions may not even be
+   monotonously changing with vertical positions.  Also, accounting
+   for face changes, overlays, etc. becomes more complex because
+   non-linear iteration could potentially skip many positions with
+   changes, and then cross them again on the way back...
+
+   One other prominent effect of bidirectional display is that some
+   paragraphs of text need to be displayed starting at the right
+   margin of the window---the so-called right-to-left, or R2L
+   paragraphs.  R2L paragraphs are displayed with R2L glyph rows,
+   which have their reversed_p flag set.  The bidi reordering engine
+   produces characters in such rows starting from the character which
+   should be the rightmost on display.  PRODUCE_GLYPHS then reverses
+   the order, when it fills up the glyph row whose reversed_p flag is
+   set, by prepending each new glyph to what is already there, instead
+   of appending it.  When the glyph row is complete, the function
+   extend_face_to_end_of_line fills the empty space to the left of the
+   leftmost character with special glyphs, which will display as,
+   well, empty.  On text terminals, these special glyphs are simply
+   blank characters.  On graphics terminals, there's a single stretch
+   glyph with suitably computed width.  Both the blanks and the
+   stretch glyph are given the face of the background of the line.
+   This way, the terminal-specific back-end can still draw the glyphs
+   left to right, even for R2L lines.  */
 
 #include <config.h>
 #include <stdio.h>
@@ -351,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
@@ -1024,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));
 
 
 
@@ -1377,33 +1434,7 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, rowh, vpos)
        visible_p = 1;
       if (visible_p)
        {
-         if (it_method == GET_FROM_BUFFER)
-           {
-             Lisp_Object window, prop;
-
-             XSETWINDOW (window, w);
-             prop = Fget_char_property (make_number (charpos),
-                                        Qinvisible, window);
-
-             /* If charpos coincides with invisible text covered with an
-                ellipsis, use the first glyph of the ellipsis to compute
-                the pixel positions.  */
-             if (TEXT_PROP_MEANS_INVISIBLE (prop) == 2)
-               {
-                 struct glyph_row *row = it.glyph_row;
-                 struct glyph *glyph = row->glyphs[TEXT_AREA];
-                 struct glyph *end = glyph + row->used[TEXT_AREA];
-                 int x = row->x;
-
-                 for (; glyph < end
-                        && (!BUFFERP (glyph->object)
-                            || glyph->charpos < charpos);
-                      glyph++)
-                   x += glyph->pixel_width;
-                 top_x = x;
-               }
-           }
-         else if (it_method == GET_FROM_DISPLAY_VECTOR)
+         if (it_method == GET_FROM_DISPLAY_VECTOR)
            {
              /* We stopped on the last glyph of a display vector.
                 Try and recompute.  Hack alert!  */
@@ -3869,15 +3900,6 @@ handle_invisible_prop (it)
                     skip any text at the beginning, which resets the
                     FIRST_ELT flag.  */
                  bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
-                 /* If the paragraph base direction is R2L, its
-                    glyphs should be reversed.  */
-                 if (it->glyph_row)
-                   {
-                     if (it->bidi_it.paragraph_dir == R2L)
-                       it->glyph_row->reversed_p = 1;
-                     else
-                       it->glyph_row->reversed_p = 0;
-                   }
                }
              do
                {
@@ -5745,8 +5767,13 @@ reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
 
   it->stop_charpos = charpos;
   if (s == NULL && it->multibyte_p)
-    composition_compute_stop_pos (&it->cmp_it, charpos, -1, it->end_charpos,
-                                 it->string);
+    {
+      EMACS_INT endpos = SCHARS (it->string);
+      if (endpos > it->end_charpos)
+       endpos = it->end_charpos;
+      composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
+                                   it->string);
+    }
   CHECK_IT (it);
 }
 
@@ -6230,16 +6257,7 @@ set_iterator_to_next (it, reseat_p)
              /* If this is a new paragraph, determine its base
                 direction (a.k.a. its base embedding level).  */
              if (it->bidi_it.new_paragraph)
-               {
-                 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
-                 if (it->glyph_row)
-                   {
-                     if (it->bidi_it.paragraph_dir == R2L)
-                       it->glyph_row->reversed_p = 1;
-                     else
-                       it->glyph_row->reversed_p = 0;
-                   }
-               }
+               bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
              bidi_get_next_char_visually (&it->bidi_it);
              IT_BYTEPOS (*it) = it->bidi_it.bytepos;
              IT_CHARPOS (*it) = it->bidi_it.charpos;
@@ -6634,7 +6652,10 @@ next_element_from_stretch (it)
 /* Scan forward from CHARPOS in the current buffer, until we find a
    stop position > current IT's position.  Then handle the stop
    position before that.  This is called when we bump into a stop
-   position while reordering bidirectional text.  */
+   position while reordering bidirectional text.  CHARPOS should be
+   the last previously processed stop_pos (or BEGV, if none were
+   processed yet) whose position is less that IT's current
+   position.  */
 
 static void
 handle_stop_backwards (it, charpos)
@@ -6692,23 +6713,21 @@ 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);
-         /* If the paragraph base direction is R2L, its glyphs should
-            be reversed.  */
-         if (it->glyph_row)
-           {
-             if (it->bidi_it.paragraph_dir == R2L)
-               it->glyph_row->reversed_p = 1;
-             else
-               it->glyph_row->reversed_p = 0;
-           }
          bidi_get_next_char_visually (&it->bidi_it);
        }
       else
@@ -6723,13 +6742,6 @@ next_element_from_buffer (it)
          it->bidi_it.charpos = IT_CHARPOS (*it);
          it->bidi_it.bytepos = IT_BYTEPOS (*it);
          bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
-         if (it->glyph_row)
-           {
-             if (it->bidi_it.paragraph_dir == R2L)
-               it->glyph_row->reversed_p = 1;
-             else
-               it->glyph_row->reversed_p = 0;
-           }
          do
            {
              /* Now return to buffer position where we were asked to
@@ -7028,7 +7040,8 @@ move_it_in_display_line_to (struct it *it,
 #define BUFFER_POS_REACHED_P()                                 \
   ((op & MOVE_TO_POS) != 0                                     \
    && BUFFERP (it->object)                                     \
-   && IT_CHARPOS (*it) == to_charpos                           \
+   && (IT_CHARPOS (*it) == to_charpos                          \
+       || (!it->bidi_p && IT_CHARPOS (*it) > to_charpos))      \
    && (it->method == GET_FROM_BUFFER                           \
        || (it->method == GET_FROM_DISPLAY_VECTOR               \
           && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
@@ -7052,14 +7065,16 @@ move_it_in_display_line_to (struct it *it,
       if ((op & MOVE_TO_POS) != 0
          && BUFFERP (it->object)
          && it->method == GET_FROM_BUFFER
-         && (prev_method == GET_FROM_IMAGE
-             || prev_method == GET_FROM_STRETCH)
-         /* Passed TO_CHARPOS from left to right.  */
-         && ((prev_pos < to_charpos
-              && IT_CHARPOS (*it) > to_charpos)
-             /* Passed TO_CHARPOS from right to left.  */
-             || (prev_pos > to_charpos)
-                 && IT_CHARPOS (*it) < to_charpos))
+         && ((!it->bidi_p && IT_CHARPOS (*it) > to_charpos)
+             || (it->bidi_p
+                 && (prev_method == GET_FROM_IMAGE
+                     || prev_method == GET_FROM_STRETCH)
+                 /* Passed TO_CHARPOS from left to right.  */
+                 && ((prev_pos < to_charpos
+                      && IT_CHARPOS (*it) > to_charpos)
+                     /* Passed TO_CHARPOS from right to left.  */
+                     || (prev_pos > to_charpos
+                         && IT_CHARPOS (*it) < to_charpos)))))
        {
          if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
            {
@@ -8546,7 +8561,6 @@ message (m, a1, a2, a3)
          if (m)
            {
              int len;
-#ifdef NO_ARG_ARRAY
              char *a[3];
              a[0] = (char *) a1;
              a[1] = (char *) a2;
@@ -8554,11 +8568,6 @@ message (m, a1, a2, a3)
 
              len = doprnt (FRAME_MESSAGE_BUF (f),
                            FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
-#else
-             len = doprnt (FRAME_MESSAGE_BUF (f),
-                           FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
-                           (char **) &a1);
-#endif /* NO_ARG_ARRAY */
 
              message2 (FRAME_MESSAGE_BUF (f), len, 0);
            }
@@ -9813,32 +9822,7 @@ x_consider_frame_title (frame)
       if (! STRINGP (f->name)
          || SBYTES (f->name) != len
          || bcmp (title, SDATA (f->name), len) != 0)
-        {
-#ifdef HAVE_NS
-          if (FRAME_NS_P (f))
-            {
-              if (!MINI_WINDOW_P(XWINDOW(f->selected_window)))
-                {
-                  if (EQ (fmt, Qt))
-                    ns_set_name_as_filename (f);
-                  else
-                    x_implicitly_set_name (f, make_string(title, len),
-                                           Qnil);
-                }
-            }
-          else
-#endif
-           x_implicitly_set_name (f, make_string (title, len), Qnil);
-        }
-#ifdef HAVE_NS
-      if (FRAME_NS_P (f))
-        {
-          /* do this also for frames with explicit names */
-          ns_implicitly_set_icon_type(f);
-          ns_set_doc_edited(f, Fbuffer_modified_p
-                            (XWINDOW (f->selected_window)->buffer), Qnil);
-        }
-#endif
+       x_implicitly_set_name (f, make_string (title, len), Qnil);
     }
 }
 
@@ -9934,6 +9918,12 @@ prepare_menu_bars ()
          menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
 #ifdef HAVE_WINDOW_SYSTEM
          update_tool_bar (f, 0);
+#endif
+#ifdef HAVE_NS
+          if (windows_or_buffers_changed
+             && FRAME_NS_P (f))
+            ns_set_doc_edited (f, Fbuffer_modified_p
+                              (XWINDOW (f->selected_window)->buffer));
 #endif
          UNGCPRO;
        }
@@ -11613,7 +11603,7 @@ static void
 select_frame_for_redisplay (frame)
      Lisp_Object frame;
 {
-  Lisp_Object tail, symbol, val;
+  Lisp_Object tail, tem;
   Lisp_Object old = selected_frame;
   struct Lisp_Symbol *sym;
 
@@ -11621,20 +11611,18 @@ select_frame_for_redisplay (frame)
 
   selected_frame = frame;
 
-  do
-    {
-      for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
-       if (CONSP (XCAR (tail))
-           && (symbol = XCAR (XCAR (tail)),
-               SYMBOLP (symbol))
-           && (sym = indirect_variable (XSYMBOL (symbol)),
-               val = sym->value,
-               (BUFFER_LOCAL_VALUEP (val)))
-           && XBUFFER_LOCAL_VALUE (val)->check_frame)
-         /* Use find_symbol_value rather than Fsymbol_value
-            to avoid an error if it is void.  */
-         find_symbol_value (symbol);
-    } while (!EQ (frame, old) && (frame = old, 1));
+  do {
+    for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
+      if (CONSP (XCAR (tail))
+         && (tem = XCAR (XCAR (tail)),
+             SYMBOLP (tem))
+         && (sym = indirect_variable (XSYMBOL (tem)),
+             sym->redirect == SYMBOL_LOCALIZED)
+         && sym->val.blv->frame_local)
+       /* Use find_symbol_value rather than Fsymbol_value
+          to avoid an error if it is void.  */
+       find_symbol_value (tem);
+  } while (!EQ (frame, old) && (frame = old, 1));
 }
 
 
@@ -11690,16 +11678,6 @@ redisplay_internal (preserve_echo_area)
   if (!f->glyphs_initialized_p)
     return;
 
-  /* The flag redisplay_performed_directly_p is set by
-     direct_output_for_insert when it already did the whole screen
-     update necessary.  */
-  if (redisplay_performed_directly_p)
-    {
-      redisplay_performed_directly_p = 0;
-      if (!hscroll_windows (selected_window))
-       return;
-    }
-
 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
   if (popup_activated ())
     return;
@@ -12652,11 +12630,13 @@ 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;
   struct glyph *glyph_before = glyph - 1, *glyph_after = end;
+  /* A glyph beyond the edge of TEXT_AREA which we should never
+     touch.  */
+  struct glyph *glyphs_end = end;
   /* Non-zero means we've found a match for cursor position, but that
      glyph has the avoid_cursor_p flag set.  */
   int match_with_avoid_cursor = 0;
@@ -12685,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;
@@ -12698,11 +12678,8 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
 
          /* If the glyph row is reversed, we need to process it from back
             to front, so swap the edge pointers.  */
-         end = glyph - 1;
+         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)
@@ -12713,10 +12690,10 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
            }
          if (INTEGERP (glyph->object) && glyph->charpos < 0)
            --glyph;
-         /* By default, put the cursor on the rightmost glyph.  */
+         /* By default, in reversed rows we put the cursor on the
+            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)
@@ -12731,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
@@ -12790,7 +12767,16 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
                bpos_covered = bpos_max + XINT (chprop);
                /* If the `cursor' property covers buffer positions up
                   to and including point, we should display cursor on
-                  this glyph.  */
+                  this glyph.  Note that overlays and text properties
+                  with string values stop bidi reordering, so every
+                  buffer position to the left of the string is always
+                  smaller than any position to the right of the
+                  string.  Therefore, if a `cursor' property on one
+                  of the string's characters has an integer value, we
+                  will break out of the loop below _before_ we get to
+                  the position match above.  IOW, integer values of
+                  the `cursor' property override the "exact match for
+                  point" strategy of positioning the cursor.  */
                /* Implementation note: bpos_max == pt_old when, e.g.,
                   we are in an empty line, where bpos_max is set to
                   MATRIX_ROW_START_CHARPOS, see above.  */
@@ -12858,15 +12844,19 @@ 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;
     }
 
   /* Step 2: If we didn't find an exact match for point, we need to
      look for a proper place to put the cursor among glyphs between
      GLYPH_BEFORE and GLYPH_AFTER.  */
-  if (!(BUFFERP (glyph->object) && glyph->charpos == pt_old)
+  if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
+       && BUFFERP (glyph->object) && glyph->charpos == pt_old)
       && bpos_covered < pt_old)
     {
       if (row->ends_in_ellipsis_p && pos_after == last_pos)
@@ -12898,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;
@@ -12930,12 +12923,19 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
 
                  str = glyph->object;
                  tem = string_buffer_position_lim (w, str, pos, pos_after, 0);
-                 if (pos <= tem)
+                 if (tem == 0  /* from overlay */
+                     || pos <= tem)
                    {
                      /* If the string from which this glyph came is
                         found in the buffer at point, then we've
-                        found the glyph we've been looking for.  */
-                     if (tem == pt_old)
+                        found the glyph we've been looking for.  If
+                        it comes from an overlay (tem == 0), and it
+                        has the `cursor' property on one of its
+                        glyphs, record that glyph as a candidate for
+                        displaying the cursor.  (As in the
+                        unidirectional version, we will display the
+                        cursor on the last candidate we find.)  */
+                     if (tem == 0 || tem == pt_old)
                        {
                          /* The glyphs from this string could have
                             been reordered.  Find the one with the
@@ -12968,9 +12968,11 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
                                }
                            }
 
-                         goto compute_x;
+                         if (tem == pt_old)
+                           goto compute_x;
                        }
-                     pos = tem + 1; /* don't find previous instances */
+                     if (tem)
+                       pos = tem + 1; /* don't find previous instances */
                    }
                  /* This string is not what we want; skip all of the
                     glyphs that came from it.  */
@@ -13008,6 +13010,53 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
        }
     }
 
+  /* 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
+      /* 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
+        displayed during the last redisplay cycle.  */
+      && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
+      && pt_old < MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)))
+    {
+      struct glyph *g1 =
+       MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
+
+      /* Don't consider glyphs that are outside TEXT_AREA.  */
+      if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
+       return 0;
+      /* Keep the candidate whose buffer position is the closest to
+        point.  */
+      if (/* previous candidate is a glyph in TEXT_AREA of that row */
+         w->cursor.hpos >= 0
+         && w->cursor.hpos < MATRIX_ROW_USED(matrix, w->cursor.vpos)
+         && BUFFERP (g1->object)
+         && (g1->charpos == pt_old /* an exact match always wins */
+             || (BUFFERP (glyph->object)
+                 && eabs (g1->charpos - pt_old)
+                  < eabs (glyph->charpos - pt_old))))
+       return 0;
+      /* If this candidate gives an exact match, use that.  */
+      if (!(BUFFERP (glyph->object) && glyph->charpos == pt_old)
+         /* Otherwise, keep the candidate that comes from a row
+            spanning less buffer positions.  This may win when one or
+            both candidate positions are on glyphs that came from
+            display strings, for which we cannot compare buffer
+            positions.  */
+         && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
+            - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
+            < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
+       return 0;
+    }
   w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
   w->cursor.x = x;
   w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
@@ -13554,6 +13603,32 @@ try_cursor_movement (window, startp, scroll_step)
            ++row;
          if (!row->enabled_p)
            rc = CURSOR_MOVEMENT_MUST_SCROLL;
+         /* If rows are bidi-reordered, back up until we find a row
+            that does not belong to a continuation line.  This is
+            because we must consider all rows of a continued line as
+            candidates for cursor positioning, since row start and
+            end positions change non-linearly with vertical position
+            in such rows.  */
+         /* FIXME: Revisit this when glyph ``spilling'' in
+            continuation lines' rows is implemented for
+            bidi-reordered rows.  */
+         if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering))
+           {
+             while (MATRIX_ROW_CONTINUATION_LINE_P (row))
+               {
+                 xassert (row->enabled_p);
+                 --row;
+                 /* If we hit the beginning of the displayed portion
+                    without finding the first row of a continued
+                    line, give up.  */
+                 if (row <= w->current_matrix->rows)
+                   {
+                     rc = CURSOR_MOVEMENT_MUST_SCROLL;
+                     break;
+                   }
+
+               }
+           }
        }
 
       if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
@@ -13677,6 +13752,46 @@ try_cursor_movement (window, startp, scroll_step)
            }
          else if (scroll_p)
            rc = CURSOR_MOVEMENT_MUST_SCROLL;
+         else if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering))
+           {
+             /* With bidi-reordered rows, there could be more than
+                one candidate row whose start and end positions
+                occlude point.  We need to let set_cursor_from_row
+                find the best candidate.  */
+             /* FIXME: Revisit this when glyph ``spilling'' in
+                continuation lines' rows is implemented for
+                bidi-reordered rows.  */
+             int rv = 0;
+
+             do
+               {
+                 rv |= set_cursor_from_row (w, row, w->current_matrix,
+                                            0, 0, 0, 0);
+                 /* As soon as we've found the first suitable row
+                    whose ends_at_zv_p flag is set, we are done.  */
+                 if (rv
+                     && MATRIX_ROW (w->current_matrix, w->cursor.vpos)->ends_at_zv_p)
+                   {
+                     rc = CURSOR_MOVEMENT_SUCCESS;
+                     break;
+                   }
+                 ++row;
+               }
+             while (MATRIX_ROW_BOTTOM_Y (row) < last_y
+                    && MATRIX_ROW_START_CHARPOS (row) <= PT
+                    && PT <= MATRIX_ROW_END_CHARPOS (row)
+                    && cursor_row_p (w, row));
+             /* If we didn't find any candidate rows, or exited the
+                loop before all the candidates were examined, signal
+                to the caller that this method failed.  */
+             if (rc != CURSOR_MOVEMENT_SUCCESS
+                 && (!rv
+                     || (MATRIX_ROW_START_CHARPOS (row) <= PT
+                         && PT <= MATRIX_ROW_END_CHARPOS (row))))
+               rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
+             else
+               rc = CURSOR_MOVEMENT_SUCCESS;
+           }
          else
            {
              do
@@ -14177,7 +14292,7 @@ redisplay_window (window, just_this_one_p)
               = try_window_reusing_current_matrix (w)))
        {
          IF_DEBUG (debug_method_add (w, "1"));
-         if (try_window (window, startp, 1) < 0)
+         if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
            /* -1 means we need to scroll.
               0 means we need new matrices, but fonts_changed_p
               is set in that case, so we will detect it below.  */
@@ -14528,13 +14643,15 @@ redisplay_window (window, just_this_one_p)
    Value is 1 if successful.  It is zero if fonts were loaded during
    redisplay which makes re-adjusting glyph matrices necessary, and -1
    if point would appear in the scroll margins.
-   (We check that only if CHECK_MARGINS is nonzero.  */
+   (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
+   unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
+   set in FLAGS.)  */
 
 int
-try_window (window, pos, check_margins)
+try_window (window, pos, flags)
      Lisp_Object window;
      struct text_pos pos;
-     int check_margins;
+     int flags;
 {
   struct window *w = XWINDOW (window);
   struct it it;
@@ -14556,12 +14673,12 @@ try_window (window, pos, check_margins)
     {
       if (display_line (&it))
        last_text_row = it.glyph_row - 1;
-      if (fonts_changed_p)
+      if (fonts_changed_p && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
        return 0;
     }
 
   /* Don't let the cursor end in the scroll margins.  */
-  if (check_margins
+  if ((flags & TRY_WINDOW_CHECK_MARGINS)
       && !MINI_WINDOW_P (w))
     {
       int this_scroll_margin;
@@ -15302,6 +15419,8 @@ row_containing_pos (w, charpos, start, end, dy)
      int dy;
 {
   struct glyph_row *row = start;
+  struct glyph_row *best_row = NULL;
+  EMACS_INT mindif = BUF_ZV (XBUFFER (w->buffer)) + 1;
   int last_y;
 
   /* If we happen to start on a header-line, skip that.  */
@@ -15334,7 +15453,30 @@ row_containing_pos (w, charpos, start, end, dy)
                 && !row->ends_at_zv_p
                 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
          && charpos >= MATRIX_ROW_START_CHARPOS (row))
-       return row;
+       {
+         struct glyph *g;
+
+         if (NILP (XBUFFER (w->buffer)->bidi_display_reordering))
+           return row;
+         /* In bidi-reordered rows, there could be several rows
+            occluding point.  We need to find the one which fits
+            CHARPOS the best.  */
+         for (g = row->glyphs[TEXT_AREA];
+              g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
+              g++)
+           {
+             if (!STRINGP (g->object))
+               {
+                 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
+                   {
+                     mindif = eabs (g->charpos - charpos);
+                     best_row = row;
+                   }
+               }
+           }
+       }
+      else if (best_row)
+       return best_row;
       ++row;
     }
 }
@@ -16721,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)
@@ -16732,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);
 
@@ -16748,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
@@ -16775,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
     {
@@ -16793,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);
 
@@ -16849,19 +17046,37 @@ highlight_trailing_whitespace (f, row)
       struct glyph *start = row->glyphs[TEXT_AREA];
       struct glyph *glyph = start + used - 1;
 
+      if (row->reversed_p)
+       {
+         /* Right-to-left rows need to be processed in the opposite
+            direction, so swap the edge pointers. */
+         glyph = start;
+         start = row->glyphs[TEXT_AREA] + used - 1;
+       }
+
       /* Skip over glyphs inserted to display the cursor at the
         end of a line, for extending the face of the last glyph
         to the end of the line on terminals, and for truncation
         and continuation glyphs.  */
-      while (glyph >= start
-            && glyph->type == CHAR_GLYPH
-            && INTEGERP (glyph->object))
-       --glyph;
+      if (!row->reversed_p)
+       {
+         while (glyph >= start
+                && glyph->type == CHAR_GLYPH
+                && INTEGERP (glyph->object))
+           --glyph;
+       }
+      else
+       {
+         while (glyph <= start
+                && glyph->type == CHAR_GLYPH
+                && INTEGERP (glyph->object))
+           ++glyph;
+       }
 
       /* If last glyph is a space or stretch, and it's trailing
         whitespace, set the face of all trailing whitespace glyphs in
         IT->glyph_row to `trailing-whitespace'.  */
-      if (glyph >= start
+      if ((row->reversed_p ? glyph <= start : glyph >= start)
          && BUFFERP (glyph->object)
          && (glyph->type == STRETCH_GLYPH
              || (glyph->type == CHAR_GLYPH
@@ -16872,12 +17087,24 @@ highlight_trailing_whitespace (f, row)
          if (face_id < 0)
            return;
 
-         while (glyph >= start
-                && BUFFERP (glyph->object)
-                && (glyph->type == STRETCH_GLYPH
-                    || (glyph->type == CHAR_GLYPH
-                        && glyph->u.ch == ' ')))
-           (glyph--)->face_id = face_id;
+         if (!row->reversed_p)
+           {
+             while (glyph >= start
+                    && BUFFERP (glyph->object)
+                    && (glyph->type == STRETCH_GLYPH
+                        || (glyph->type == CHAR_GLYPH
+                            && glyph->u.ch == ' ')))
+               (glyph--)->face_id = face_id;
+           }
+         else
+           {
+             while (glyph <= start
+                    && BUFFERP (glyph->object)
+                    && (glyph->type == STRETCH_GLYPH
+                        || (glyph->type == CHAR_GLYPH
+                            && glyph->u.ch == ' ')))
+               (glyph++)->face_id = face_id;
+           }
        }
     }
 }
@@ -17049,6 +17276,31 @@ handle_line_prefix (struct it *it)
 
 \f
 
+/* 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
@@ -17067,6 +17319,7 @@ display_line (it)
   int wrap_row_phys_ascent, wrap_row_phys_height;
   int wrap_row_extra_line_spacing;
   struct display_pos row_end;
+  int cvpos;
 
   /* We always start displaying at hpos zero even if hscrolled.  */
   xassert (it->hpos == 0 && it->current_x == 0);
@@ -17160,7 +17413,6 @@ display_line (it)
             even if this row ends in ZV.  */
          if (row->reversed_p)
            extend_face_to_end_of_line (it);
-         row_end = it->current;
          break;
        }
 
@@ -17313,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
@@ -17335,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;
@@ -17370,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.  */
@@ -17395,7 +17656,6 @@ display_line (it)
                      it->max_phys_descent = phys_descent;
                    }
 
-                 row_end = it->current;
                  break;
                }
              else if (new_x > it->first_visible_x)
@@ -17429,10 +17689,7 @@ display_line (it)
 
          /* End of this display line if row is continued.  */
          if (row->continued_p || row->ends_at_zv_p)
-           {
-             row_end = it->current;
-             break;
-           }
+           break;
        }
 
     at_end_of_line:
@@ -17458,22 +17715,8 @@ display_line (it)
            row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
 
          /* Consume the line end.  This skips over invisible lines.  */
-         if (it->bidi_p)
-           {
-             /* When we are reordering bidi text, we still need the
-                next character in logical order, to set row->end
-                correctly below.  */
-             push_it (it);
-             it->bidi_p = 0;
-             set_iterator_to_next (it, 1);
-             row_end = it->current;
-             pop_it (it);
-             it->bidi_p = 1;
-           }
          set_iterator_to_next (it, 1);
          it->continuation_lines_width = 0;
-         if (!it->bidi_p)
-           row_end = it->current;
          break;
        }
 
@@ -17493,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)
                {
@@ -17511,7 +17767,6 @@ display_line (it)
                  it->continuation_lines_width = 0;
                  row->ends_at_zv_p = 1;
                  row->exact_window_width_line_p = 1;
-                 row_end = it->current;
                  break;
                }
              if (ITERATOR_AT_END_OF_LINE_P (it))
@@ -17527,7 +17782,6 @@ display_line (it)
          row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
          it->hpos = hpos_before;
          it->current_x = x_before;
-         row_end = it->current;
          break;
        }
     }
@@ -17588,7 +17842,116 @@ display_line (it)
   compute_line_metrics (it);
 
   /* Remember the position at which this line ends.  */
-  row->end = row_end;
+  row->end = row_end = it->current;
+  if (it->bidi_p)
+    {
+      /* ROW->start and ROW->end must be the smallest and largest
+        buffer positions in ROW.  But if ROW was bidi-reordered,
+        these two positions can be anywhere in the row, so we must
+        rescan all of the ROW's glyphs to find them.  */
+      /* FIXME: Revisit this when glyph ``spilling'' in continuation
+        lines' rows is implemented for bidi-reordered rows.  */
+      EMACS_INT min_pos = ZV + 1, max_pos = 0;
+      struct glyph *g;
+      struct it save_it;
+      struct text_pos tpos;
+
+      for (g = row->glyphs[TEXT_AREA];
+          g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
+          g++)
+       {
+         if (BUFFERP (g->object))
+           {
+             if (g->charpos > 0 && g->charpos < min_pos)
+               min_pos = g->charpos;
+             if (g->charpos > max_pos)
+               max_pos = g->charpos;
+           }
+       }
+      /* Empty lines have a valid buffer position at their first
+        glyph, but that glyph's OBJECT is zero, as if it didn't come
+        from a buffer.  If we didn't find any valid buffer positions
+        in this row, maybe we have such an empty line.  */
+      if (min_pos == ZV + 1 && row->used[TEXT_AREA])
+       {
+         for (g = row->glyphs[TEXT_AREA];
+              g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
+              g++)
+           {
+             if (INTEGERP (g->object))
+               {
+                 if (g->charpos > 0 && g->charpos < min_pos)
+                   min_pos = g->charpos;
+                 if (g->charpos > max_pos)
+                   max_pos = g->charpos;
+               }
+           }
+       }
+      if (min_pos <= ZV)
+       {
+         if (min_pos != row->start.pos.charpos)
+           {
+             row->start.pos.charpos = min_pos;
+             row->start.pos.bytepos = CHAR_TO_BYTE (min_pos);
+           }
+         if (max_pos == 0)
+           max_pos = min_pos;
+       }
+      /* For ROW->end, we need the position that is _after_ max_pos,
+        in the logical order, unless we are at ZV.  */
+      if (row->ends_at_zv_p)
+       {
+         row_end = row->end = it->current;
+         if (!row->used[TEXT_AREA])
+           {
+             row->start.pos.charpos = row_end.pos.charpos;
+             row->start.pos.bytepos = row_end.pos.bytepos;
+           }
+       }
+      else if (row->used[TEXT_AREA] && max_pos)
+       {
+         SET_TEXT_POS (tpos, max_pos + 1, CHAR_TO_BYTE (max_pos + 1));
+         row_end = it->current;
+         row_end.pos = tpos;
+         /* If the character at max_pos+1 is a newline, skip that as
+            well.  Note that this may skip some invisible text.  */
+         if (FETCH_CHAR (tpos.bytepos) == '\n'
+             || (FETCH_CHAR (tpos.bytepos) == '\r' && it->selective))
+           {
+             save_it = *it;
+             it->bidi_p = 0;
+             reseat_1 (it, tpos, 0);
+             set_iterator_to_next (it, 1);
+             /* Record the position after the newline of a continued
+                row.  We will need that to set ROW->end of the last
+                row produced for a continued line.  */
+             if (row->continued_p)
+               {
+                 save_it.eol_pos.charpos = IT_CHARPOS (*it);
+                 save_it.eol_pos.bytepos = IT_BYTEPOS (*it);
+               }
+             else
+               {
+                 row_end = it->current;
+                 save_it.eol_pos.charpos = save_it.eol_pos.bytepos = 0;
+               }
+             *it = save_it;
+           }
+         else if (!row->continued_p
+                  && MATRIX_ROW_CONTINUATION_LINE_P (row)
+                  && it->eol_pos.charpos > 0)
+           {
+             /* Last row of a continued line.  Use the position
+                recorded in ROW->eol_pos, to the effect that the
+                newline belongs to this row, not to the row which
+                displays the character with the largest buffer
+                position.  */
+             row_end.pos = it->eol_pos;
+             it->eol_pos.charpos = it->eol_pos.bytepos = 0;
+           }
+         row->end = row_end;
+       }
+    }
 
   /* Record whether this row ends inside an ellipsis.  */
   row->ends_in_ellipsis_p
@@ -17607,7 +17970,18 @@ display_line (it)
   it->right_user_fringe_face_id = 0;
 
   /* Maybe set the cursor.  */
-  if (it->w->cursor.vpos < 0
+  cvpos = it->w->cursor.vpos;
+  if ((cvpos < 0
+       /* In bidi-reordered rows, keep checking for proper cursor
+         position even if one has been found already, because buffer
+         positions in such rows change non-linearly with ROW->VPOS,
+         when a line is continued.  One exception: when we are at ZV,
+         display cursor on the first suitable glyph row, since all
+         the empty rows after that also have their position set to ZV.  */
+       /* FIXME: Revisit this when glyph ``spilling'' in continuation
+         lines' rows is implemented for bidi-reordered rows.  */
+       || (it->bidi_p
+          && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
       && PT >= MATRIX_ROW_START_CHARPOS (row)
       && PT <= MATRIX_ROW_END_CHARPOS (row)
       && cursor_row_p (it->w, row))
@@ -17625,10 +17999,12 @@ display_line (it)
   it->current_y += row->height;
   ++it->vpos;
   ++it->glyph_row;
-  /* The next row should use same value of the reversed_p flag as this
-     one.  set_iterator_to_next decides when it's a new paragraph and
-     recomputes the value of the flag accordingly.  */
-  it->glyph_row->reversed_p = row->reversed_p;
+  /* The next row should by default use the same value of the
+     reversed_p flag as this one.  set_iterator_to_next decides when
+     it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
+     the flag accordingly.  */
+  if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
+    it->glyph_row->reversed_p = row->reversed_p;
   it->start = row_end;
   return row->displays_text_p;
 }
@@ -21158,6 +21534,17 @@ append_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 && 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 = it->object;
       if (it->pixel_width > 0)
@@ -21194,6 +21581,11 @@ append_glyph (it)
            abort ();
          glyph->bidi_type = it->bidi_it.type;
        }
+      else
+       {
+         glyph->resolved_level = 0;
+         glyph->bidi_type = UNKNOWN_BT;
+       }
       ++it->glyph_row->used[area];
     }
   else
@@ -21216,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;
@@ -21461,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;
@@ -21487,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
@@ -22967,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;
     }
@@ -23068,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;
@@ -23148,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;
     }
 
@@ -23157,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
@@ -23173,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.  */
@@ -23255,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);
@@ -23303,9 +23726,6 @@ display_and_set_cursor (w, on, hpos, vpos, x, y)
 /* Switch the display of W's cursor on or off, according to the value
    of ON.  */
 
-#ifndef HAVE_NS
-static
-#endif
 void
 update_window_cursor (w, on)
      struct window *w;
@@ -24224,7 +24644,8 @@ note_mouse_highlight (f, x, y)
 #endif
 
   if (NILP (Vmouse_highlight)
-      || !f->glyphs_initialized_p)
+      || !f->glyphs_initialized_p
+      || f->pointer_invisible)
     return;
 
   dpyinfo->mouse_face_mouse_x = x;
@@ -25450,9 +25871,9 @@ syms_of_xdisp ()
   staticpro (&previous_help_echo_string);
   help_echo_pos = -1;
 
-  Qright_to_left = intern ("right-to-left");
+  Qright_to_left = intern_c_string ("right-to-left");
   staticpro (&Qright_to_left);
-  Qleft_to_right = intern ("left-to-right");
+  Qleft_to_right = intern_c_string ("left-to-right");
   staticpro (&Qleft_to_right);
 
 #ifdef HAVE_WINDOW_SYSTEM