Merge from emacs-24 branch
[bpt/emacs.git] / src / xdisp.c
index 01472a6..3cbd4b1 100644 (file)
@@ -1,6 +1,6 @@
 /* Display generation from window structure and buffer text.
 
-Copyright (C) 1985-1988, 1993-1995, 1997-2011  Free Software Foundation, Inc.
+Copyright (C) 1985-1988, 1993-1995, 1997-2012  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -954,7 +954,7 @@ static int coords_in_mouse_face_p (struct window *, int, int);
 
    This is the height of W minus the height of a mode line, if any.  */
 
-inline int
+int
 window_text_bottom_y (struct window *w)
 {
   int height = WINDOW_TOTAL_HEIGHT (w);
@@ -968,7 +968,7 @@ window_text_bottom_y (struct window *w)
    means return the total width of W, not including fringes to
    the left and right of the window.  */
 
-inline int
+int
 window_box_width (struct window *w, int area)
 {
   int cols = XFASTINT (w->total_cols);
@@ -1007,7 +1007,7 @@ window_box_width (struct window *w, int area)
 /* Return the pixel height of the display area of window W, not
    including mode lines of W, if any.  */
 
-inline int
+int
 window_box_height (struct window *w)
 {
   struct frame *f = XFRAME (w->frame);
@@ -1054,7 +1054,7 @@ window_box_height (struct window *w)
    area AREA of window W.  AREA < 0 means return the left edge of the
    whole window, to the right of the left fringe of W.  */
 
-inline int
+int
 window_box_left_offset (struct window *w, int area)
 {
   int x;
@@ -1086,7 +1086,7 @@ window_box_left_offset (struct window *w, int area)
    area AREA of window W.  AREA < 0 means return the right edge of the
    whole window, to the left of the right fringe of W.  */
 
-inline int
+int
 window_box_right_offset (struct window *w, int area)
 {
   return window_box_left_offset (w, area) + window_box_width (w, area);
@@ -1096,7 +1096,7 @@ window_box_right_offset (struct window *w, int area)
    area AREA of window W.  AREA < 0 means return the left edge of the
    whole window, to the right of the left fringe of W.  */
 
-inline int
+int
 window_box_left (struct window *w, int area)
 {
   struct frame *f = XFRAME (w->frame);
@@ -1116,7 +1116,7 @@ window_box_left (struct window *w, int area)
    area AREA of window W.  AREA < 0 means return the right edge of the
    whole window, to the left of the right fringe of W.  */
 
-inline int
+int
 window_box_right (struct window *w, int area)
 {
   return window_box_left (w, area) + window_box_width (w, area);
@@ -1129,7 +1129,7 @@ window_box_right (struct window *w, int area)
    coordinates of the upper-left corner of the box.  Return in
    *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box.  */
 
-inline void
+void
 window_box (struct window *w, int area, int *box_x, int *box_y,
            int *box_width, int *box_height)
 {
@@ -1445,7 +1445,7 @@ pos_visible_p (struct window *w, EMACS_INT charpos, int *x, int *y,
                     position is CHARPOS.  For the contingency that we
                     didn't, and stopped at the first newline from the
                     display string, move back over the glyphs
-                    prfoduced from the string, until we find the
+                    produced from the string, until we find the
                     rightmost glyph not from the string.  */
                  if (IT_CHARPOS (it3) != charpos && EQ (it3.object, string))
                    {
@@ -1915,7 +1915,7 @@ get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int
         environments with anti-aliased text: if the same text is
         drawn onto the same place multiple times, it gets thicker.
         If the overlap we are processing is for the erased cursor, we
-        take the intersection with the rectagle of the cursor.  */
+        take the intersection with the rectangle of the cursor.  */
       if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
        {
          XRectangle rc, r_save = r;
@@ -2750,9 +2750,12 @@ init_iterator (struct it *it, struct window *w,
   if (charpos >= BUF_BEG (current_buffer))
     {
       it->end_charpos = ZV;
-      it->face_id = -1;
       IT_CHARPOS (*it) = charpos;
 
+      /* We will rely on `reseat' to set this up properly, via
+        handle_face_prop.  */
+      it->face_id = it->base_face_id;
+
       /* Compute byte position if not specified.  */
       if (bytepos < charpos)
        IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
@@ -2763,9 +2766,13 @@ init_iterator (struct it *it, struct window *w,
       /* Do we need to reorder bidirectional text?  Not if this is a
         unibyte buffer: by definition, none of the single-byte
         characters are strong R2L, so no reordering is needed.  And
-        bidi.c doesn't support unibyte buffers anyway.  */
+        bidi.c doesn't support unibyte buffers anyway.  Also, don't
+        reorder while we are loading loadup.el, since the tables of
+        character properties needed for reordering are not yet
+        available.  */
       it->bidi_p =
-       !NILP (BVAR (current_buffer, bidi_display_reordering))
+       NILP (Vpurify_flag)
+       && !NILP (BVAR (current_buffer, bidi_display_reordering))
        && it->multibyte_p;
 
       /* If we are to reorder bidirectional text, init the bidi
@@ -2842,8 +2849,14 @@ start_display (struct it *it, struct window *w, struct text_pos pos)
                  || (new_x == it->last_visible_x
                      && FRAME_WINDOW_P (it->f))))
            {
-             if (it->current.dpvec_index >= 0
-                 || it->current.overlay_string_index >= 0)
+             if ((it->current.dpvec_index >= 0
+                  || it->current.overlay_string_index >= 0)
+                 /* If we are on a newline from a display vector or
+                    overlay string, then we are already at the end of
+                    a screen line; no need to go to the next line in
+                    that case, as this line is not really continued.
+                    (If we do go to the next line, C-e will not DTRT.)  */
+                 && it->c != '\n')
                {
                  set_iterator_to_next (it, 1);
                  move_it_in_display_line_to (it, -1, -1, 0);
@@ -2851,6 +2864,13 @@ start_display (struct it *it, struct window *w, struct text_pos pos)
 
              it->continuation_lines_width += it->current_x;
            }
+         /* If the character at POS is displayed via a display
+            vector, move_it_to above stops at the final glyph of
+            IT->dpvec.  To make the caller redisplay that character
+            again (a.k.a. start at POS), we need to reset the
+            dpvec_index to the beginning of IT->dpvec.  */
+         else if (it->current.dpvec_index >= 0)
+           it->current.dpvec_index = 0;
 
          /* We're starting a new display line, not affected by the
             height of the continued line, so clear the appropriate
@@ -3155,13 +3175,11 @@ compute_stop_pos (struct it *it)
   Lisp_Object object, limit, position;
   EMACS_INT charpos, bytepos;
 
-  /* If nowhere else, stop at the end.  */
-  it->stop_charpos = it->end_charpos;
-
   if (STRINGP (it->string))
     {
       /* Strings are usually short, so don't limit the search for
         properties.  */
+      it->stop_charpos = it->end_charpos;
       object = it->string;
       limit = Qnil;
       charpos = IT_STRING_CHARPOS (*it);
@@ -3171,6 +3189,12 @@ compute_stop_pos (struct it *it)
     {
       EMACS_INT pos;
 
+      /* If end_charpos is out of range for some reason, such as a
+        misbehaving display function, rationalize it (Bug#5984).  */
+      if (it->end_charpos > ZV)
+       it->end_charpos = ZV;
+      it->stop_charpos = it->end_charpos;
+
       /* If next overlay change is in front of the current stop pos
         (which is IT->end_charpos), stop there.  Note: value of
         next_overlay_change is point-max if no overlay change
@@ -3649,7 +3673,9 @@ handle_face_prop (struct it *it)
             with, so that overlay strings appear in the same face as
             surrounding text, unless they specify their own
             faces.  */
-         base_face_id = underlying_face_id (it);
+         base_face_id = it->string_from_prefix_prop_p
+           ? DEFAULT_FACE_ID
+           : underlying_face_id (it);
        }
 
       new_face_id = face_at_string_position (it->w,
@@ -4069,29 +4095,41 @@ handle_invisible_prop (struct it *it)
          while (invis_p);
 
          /* The position newpos is now either ZV or on visible text.  */
-         if (it->bidi_p && newpos < ZV)
+         if (it->bidi_p)
            {
              EMACS_INT bpos = CHAR_TO_BYTE (newpos);
-
-             if (FETCH_BYTE (bpos) == '\n'
-                 || (newpos > BEGV && FETCH_BYTE (bpos - 1) == '\n'))
+             int on_newline =
+               bpos == ZV_BYTE || FETCH_BYTE (bpos) == '\n';
+             int after_newline =
+               newpos <= BEGV || FETCH_BYTE (bpos - 1) == '\n';
+
+             /* If the invisible text ends on a newline or on a
+                character after a newline, we can avoid the costly,
+                character by character, bidi iteration to NEWPOS, and
+                instead simply reseat the iterator there.  That's
+                because all bidi reordering information is tossed at
+                the newline.  This is a big win for modes that hide
+                complete lines, like Outline, Org, etc.  */
+             if (on_newline || after_newline)
                {
-                 /* If the invisible text ends on a newline or the
-                    character after a newline, we can avoid the
-                    costly, character by character, bidi iteration to
-                    newpos, and instead simply reseat the iterator
-                    there.  That's because all bidi reordering
-                    information is tossed at the newline.  This is a
-                    big win for modes that hide complete lines, like
-                    Outline, Org, etc.  (Implementation note: the
-                    call to reseat_1 is necessary, because it signals
-                    to the bidi iterator that it needs to reinit its
-                    internal information when the next element for
-                    display is requested.  */
                  struct text_pos tpos;
+                 bidi_dir_t pdir = it->bidi_it.paragraph_dir;
 
                  SET_TEXT_POS (tpos, newpos, bpos);
                  reseat_1 (it, tpos, 0);
+                 /* If we reseat on a newline/ZV, we need to prep the
+                    bidi iterator for advancing to the next character
+                    after the newline/EOB, keeping the current paragraph
+                    direction (so that PRODUCE_GLYPHS does TRT wrt
+                    prepending/appending glyphs to a glyph row).  */
+                 if (on_newline)
+                   {
+                     it->bidi_it.first_elt = 0;
+                     it->bidi_it.paragraph_dir = pdir;
+                     it->bidi_it.ch = (bpos == ZV_BYTE) ? -1 : '\n';
+                     it->bidi_it.nchars = 1;
+                     it->bidi_it.ch_len = 1;
+                   }
                }
              else      /* Must use the slow method.  */
                {
@@ -4100,11 +4138,11 @@ handle_invisible_prop (struct it *it)
                     non-base embedding level.  Therefore, we need to
                     skip invisible text using the bidi iterator,
                     starting at IT's current position, until we find
-                    ourselves outside the invisible text.  Skipping
-                    invisible text _after_ bidi iteration avoids
-                    affecting the visual order of the displayed text
-                    when invisible properties are added or
-                    removed.  */
+                    ourselves outside of the invisible text.
+                    Skipping invisible text _after_ bidi iteration
+                    avoids affecting the visual order of the
+                    displayed text when invisible properties are
+                    added or removed.  */
                  if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
                    {
                      /* If we were `reseat'ed to a new paragraph,
@@ -4306,7 +4344,7 @@ handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
   int rv;
 
   if (CONSP (spec)
-      /* Simple specerties.  */
+      /* Simple specifications.  */
       && !EQ (XCAR (spec), Qimage)
       && !EQ (XCAR (spec), Qspace)
       && !EQ (XCAR (spec), Qwhen)
@@ -4941,7 +4979,7 @@ string_buffer_position_lim (Lisp_Object string,
   Lisp_Object limit, prop, pos;
   int found = 0;
 
-  pos = make_number (from);
+  pos = make_number (max (from, BEGV));
 
   if (!back_p) /* looking forward */
     {
@@ -5120,6 +5158,12 @@ next_overlay_string (struct it *it)
       it->current.overlay_string_index = -1;
       it->n_overlay_strings = 0;
       it->overlay_strings_charpos = -1;
+      /* If there's an empty display string on the stack, pop the
+        stack, to resync the bidi iterator with IT's position.  Such
+        empty strings are pushed onto the stack in
+        get_overlay_strings_1.  */
+      if (it->sp > 0 && STRINGP (it->string) && !SCHARS (it->string))
+       pop_it (it);
 
       /* If we're at the end of the buffer, record that we have
         processed the overlay strings there already, so that
@@ -5417,8 +5461,15 @@ get_overlay_strings_1 (struct it *it, EMACS_INT charpos, int compute_stop_p)
       xassert (!compute_stop_p || it->sp == 0);
 
       /* When called from handle_stop, there might be an empty display
-         string loaded.  In that case, don't bother saving it.  */
-      if (!STRINGP (it->string) || SCHARS (it->string))
+         string loaded.  In that case, don't bother saving it.  But
+         don't use this optimization with the bidi iterator, since we
+         need the corresponding pop_it call to resync the bidi
+         iterator's position with IT's position, after we are done
+         with the overlay strings.  (The corresponding call to pop_it
+         in case of an empty display string is in
+         next_overlay_string.)  */
+      if (!(!it->bidi_p
+           && STRINGP (it->string) && !SCHARS (it->string)))
        push_it (it, NULL);
 
       /* Set up IT to deliver display elements from the first overlay
@@ -5527,6 +5578,7 @@ push_it (struct it *it, struct text_pos *position)
   p->font_height = it->font_height;
   p->voffset = it->voffset;
   p->string_from_display_prop_p = it->string_from_display_prop_p;
+  p->string_from_prefix_prop_p = it->string_from_prefix_prop_p;
   p->display_ellipsis_p = 0;
   p->line_wrap = it->line_wrap;
   p->bidi_p = it->bidi_p;
@@ -5636,6 +5688,7 @@ pop_it (struct it *it)
   it->font_height = p->font_height;
   it->voffset = p->voffset;
   it->string_from_display_prop_p = p->string_from_display_prop_p;
+  it->string_from_prefix_prop_p = p->string_from_prefix_prop_p;
   it->line_wrap = p->line_wrap;
   it->bidi_p = p->bidi_p;
   it->paragraph_embedding = p->paragraph_embedding;
@@ -6066,6 +6119,8 @@ reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
   it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
   it->sp = 0;
   it->string_from_display_prop_p = 0;
+  it->string_from_prefix_prop_p = 0;
+
   it->from_disp_prop_p = 0;
   it->face_before_selective_p = 0;
   if (it->bidi_p)
@@ -6129,8 +6184,12 @@ reseat_to_string (struct it *it, const char *s, Lisp_Object string,
     it->multibyte_p = multibyte > 0;
 
   /* Bidirectional reordering of strings is controlled by the default
-     value of bidi-display-reordering.  */
-  it->bidi_p = !NILP (BVAR (&buffer_defaults, bidi_display_reordering));
+     value of bidi-display-reordering.  Don't try to reorder while
+     loading loadup.el, as the necessary character property tables are
+     not yet available.  */
+  it->bidi_p =
+    NILP (Vpurify_flag)
+    && !NILP (BVAR (&buffer_defaults, bidi_display_reordering));
 
   if (s == NULL)
     {
@@ -6371,8 +6430,8 @@ get_next_display_element (struct it *it)
        {
          Lisp_Object dv;
          struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
-         enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen }
-         nbsp_or_shy = char_is_other;
+         int nonascii_space_p = 0;
+         int nonascii_hyphen_p = 0;
          int c = it->c;        /* This is the character to display.  */
 
          if (! it->multibyte_p && ! ASCII_CHAR_P (c))
@@ -6424,10 +6483,15 @@ get_next_display_element (struct it *it)
              goto get_next;
            }
 
+         /* If `nobreak-char-display' is non-nil, we display
+            non-ASCII spaces and hyphens specially.  */
          if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
-           nbsp_or_shy = (c == 0xA0   ? char_is_nbsp
-                          : c == 0xAD ? char_is_soft_hyphen
-                          :             char_is_other);
+           {
+             if (c == 0xA0)
+               nonascii_space_p = 1;
+             else if (c == 0xAD || c == 0x2010 || c == 0x2011)
+               nonascii_hyphen_p = 1;
+           }
 
          /* Translate control characters into `\003' or `^C' form.
             Control characters coming from a display table entry are
@@ -6435,7 +6499,8 @@ get_next_display_element (struct it *it)
             the translation.  This could easily be changed but I
             don't believe that it is worth doing.
 
-            NBSP and SOFT-HYPEN are property translated too.
+            The characters handled by `nobreak-char-display' must be
+            translated too.
 
             Non-printable characters and raw-byte characters are also
             translated to octal form.  */
@@ -6446,14 +6511,15 @@ get_next_display_element (struct it *it)
                      && it->glyph_row
                      && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
                  || (c != '\n' && c != '\t'))
-              : (nbsp_or_shy
+              : (nonascii_space_p
+                 || nonascii_hyphen_p
                  || CHAR_BYTE8_P (c)
                  || ! CHAR_PRINTABLE_P (c))))
            {
-             /* C is a control character, NBSP, SOFT-HYPEN, raw-byte,
-                or a non-printable character which must be displayed
-                either as '\003' or as `^C' where the '\\' and '^'
-                can be defined in the display table.  Fill
+             /* C is a control character, non-ASCII space/hyphen,
+                raw-byte, or a non-printable character which must be
+                displayed either as '\003' or as `^C' where the '\\'
+                and '^' can be defined in the display table.  Fill
                 IT->ctl_chars with glyphs for what we have to
                 display.  Then, set IT->dpvec to these glyphs.  */
              Lisp_Object gc;
@@ -6502,17 +6568,14 @@ get_next_display_element (struct it *it)
                  goto display_control;
                }
 
-             /* Handle non-break space in the mode where it only gets
+             /* Handle non-ascii space in the mode where it only gets
                 highlighting.  */
 
-             if (EQ (Vnobreak_char_display, Qt)
-                 && nbsp_or_shy == char_is_nbsp)
+             if (nonascii_space_p && EQ (Vnobreak_char_display, Qt))
                {
-                 /* Merge the no-break-space face into the current face.  */
+                 /* Merge `nobreak-space' into the current face.  */
                  face_id = merge_faces (it->f, Qnobreak_space, 0,
                                         it->face_id);
-
-                 c = ' ';
                  XSETINT (it->ctl_chars[0], ' ');
                  ctl_len = 1;
                  goto display_control;
@@ -6552,25 +6615,21 @@ get_next_display_element (struct it *it)
                  last_escape_glyph_merged_face_id = face_id;
                }
 
-             /* Handle soft hyphens in the mode where they only get
-                highlighting.  */
+             /* Draw non-ASCII hyphen with just highlighting: */
 
-             if (EQ (Vnobreak_char_display, Qt)
-                 && nbsp_or_shy == char_is_soft_hyphen)
+             if (nonascii_hyphen_p && EQ (Vnobreak_char_display, Qt))
                {
                  XSETINT (it->ctl_chars[0], '-');
                  ctl_len = 1;
                  goto display_control;
                }
 
-             /* Handle non-break space and soft hyphen
-                with the escape glyph.  */
+             /* Draw non-ASCII space/hyphen with escape glyph: */
 
-             if (nbsp_or_shy)
+             if (nonascii_space_p || nonascii_hyphen_p)
                {
                  XSETINT (it->ctl_chars[0], escape_glyph);
-                 c = (nbsp_or_shy == char_is_nbsp ? ' ' : '-');
-                 XSETINT (it->ctl_chars[1], c);
+                 XSETINT (it->ctl_chars[1], nonascii_space_p ? ' ' : '-');
                  ctl_len = 2;
                  goto display_control;
                }
@@ -7309,7 +7368,7 @@ next_element_from_string (struct it *it)
   if (it->current.overlay_string_index >= 0)
     {
       /* Get the next character from an overlay string.  In overlay
-        strings, There is no field width or padding with spaces to
+        strings, there is no field width or padding with spaces to
         do.  */
       if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
        {
@@ -8768,7 +8827,10 @@ move_it_vertically_backward (struct it *it, int dy)
         reordering.  We want to get to the character position
         that is immediately after the newline of the previous
         line.  */
-      if (it->bidi_p && IT_CHARPOS (*it) > BEGV
+      if (it->bidi_p
+         && !it->continuation_lines_width
+         && !STRINGP (it->string)
+         && IT_CHARPOS (*it) > BEGV
          && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
        {
          EMACS_INT nl_pos =
@@ -8904,7 +8966,6 @@ move_it_by_lines (struct it *it, int dvpos)
     {
       /* DVPOS == 0 means move to the start of the screen line.  */
       move_it_vertically_backward (it, 0);
-      xassert (it->current_x == 0 && it->hpos == 0);
       /* Let next call to line_bottom_y calculate real line height */
       last_height = 0;
     }
@@ -8912,7 +8973,20 @@ move_it_by_lines (struct it *it, int dvpos)
     {
       move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
       if (!IT_POS_VALID_AFTER_MOVE_P (it))
-       move_it_to (it, IT_CHARPOS (*it) + 1, -1, -1, -1, MOVE_TO_POS);
+       {
+         /* Only move to the next buffer position if we ended up in a
+            string from display property, not in an overlay string
+            (before-string or after-string).  That is because the
+            latter don't conceal the underlying buffer position, so
+            we can ask to move the iterator to the exact position we
+            are interested in.  Note that, even if we are already at
+            IT_CHARPOS (*it), the call below is not a no-op, as it
+            will detect that we are at the end of the string, pop the
+            iterator, and compute it->current_x and it->hpos
+            correctly.  */
+         move_it_to (it, IT_CHARPOS (*it) + it->string_from_display_prop_p,
+                     -1, -1, -1, MOVE_TO_POS);
+       }
     }
   else
     {
@@ -10195,7 +10269,7 @@ current_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
 }
 
 
-/* Push the current message on Vmessage_stack for later restauration
+/* Push the current message on Vmessage_stack for later restoration
    by restore_message.  Value is non-zero if the current message isn't
    empty.  This is a relatively infrequent operation, so it's not
    worth optimizing.  */
@@ -13605,7 +13679,7 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
   /* Non-zero means we've seen at least one glyph that came from a
      display string.  */
   int string_seen = 0;
-  /* Largest and smalles buffer positions seen so far during scan of
+  /* Largest and smallest buffer positions seen so far during scan of
      glyph row.  */
   EMACS_INT bpos_max = pos_before;
   EMACS_INT bpos_min = pos_after;
@@ -13616,6 +13690,13 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
      comes from a text property, not from an overlay.  */
   int string_from_text_prop = 0;
 
+  /* Don't even try doing anything if called for a mode-line or
+     header-line row, since the rest of the code isn't prepared to
+     deal with such calamities.  */
+  xassert (!row->mode_line_p);
+  if (row->mode_line_p)
+    return 0;
+
   /* Skip over glyphs not having an object at the start and the end of
      the row.  These are special glyphs like truncation marks on
      terminal frames.  */
@@ -13738,16 +13819,31 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
 
            chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
                                         glyph->object);
+           if (!NILP (chprop))
+             {
+               /* If the string came from a `display' text property,
+                  look up the buffer position of that property and
+                  use that position to update bpos_max, as if we
+                  actually saw such a position in one of the row's
+                  glyphs.  This helps with supporting integer values
+                  of `cursor' property on the display string in
+                  situations where most or all of the row's buffer
+                  text is completely covered by display properties,
+                  so that no glyph with valid buffer positions is
+                  ever seen in the row.  */
+               EMACS_INT prop_pos =
+                 string_buffer_position_lim (glyph->object, pos_before,
+                                             pos_after, 0);
+
+               if (prop_pos >= pos_before)
+                 bpos_max = prop_pos - 1;
+             }
            if (INTEGERP (chprop))
              {
                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.  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
+                  this glyph.  Note that, 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
@@ -13807,6 +13903,15 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
 
            chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
                                         glyph->object);
+           if (!NILP (chprop))
+             {
+               EMACS_INT prop_pos =
+                 string_buffer_position_lim (glyph->object, pos_before,
+                                             pos_after, 0);
+
+               if (prop_pos >= pos_before)
+                 bpos_max = prop_pos - 1;
+             }
            if (INTEGERP (chprop))
              {
                bpos_covered = bpos_max + XINT (chprop);
@@ -13944,15 +14049,18 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
                      || 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
-                        it comes from an overlay (tem == 0), and it
-                        has the `cursor' property on one of its
+                        found in the buffer at point, or at position
+                        that is closer to point than pos_after, then
+                        we've 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)
+                     if (tem == 0
+                         || tem == pt_old
+                         || (tem - pt_old > 0 && tem < pos_after))
                        {
                          /* The glyphs from this string could have
                             been reordered.  Find the one with the
@@ -13990,7 +14098,8 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
                                }
                            }
 
-                         if (tem == pt_old)
+                         if (tem == pt_old
+                             || (tem - pt_old > 0 && tem < pos_after))
                            goto compute_x;
                        }
                      if (tem)
@@ -14091,7 +14200,7 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
              || (STRINGP (g1->object)
                  && (!NILP (Fget_char_property (make_number (g1->charpos),
                                                Qcursor, g1->object))
-                     /* pevious candidate is from the same display
+                     /* previous candidate is from the same display
                         string as this one, and the display string
                         came from a text property */
                      || (EQ (g1->object, glyph->object)
@@ -14321,7 +14430,7 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
     {
       int scroll_margin_y;
 
-      /* Compute the pixel ypos of the scroll margin, then move it to
+      /* Compute the pixel ypos of the scroll margin, then move IT to
         either that ypos or PT, whichever comes first.  */
       start_display (&it, w, startp);
       scroll_margin_y = it.last_visible_y - this_scroll_margin
@@ -14351,7 +14460,8 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
          if (dy > scroll_max)
            return SCROLLING_FAILED;
 
-         scroll_down_p = 1;
+         if (dy > 0)
+           scroll_down_p = 1;
        }
     }
 
@@ -14807,6 +14917,8 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste
          else if (rc != CURSOR_MOVEMENT_SUCCESS
                   && !NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
            {
+             struct glyph_row *row1;
+
              /* If rows are bidi-reordered and point moved, back up
                 until we find a row that does not belong to a
                 continuation line.  This is because we must consider
@@ -14817,25 +14929,28 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste
              /* FIXME: Revisit this when glyph ``spilling'' in
                 continuation lines' rows is implemented for
                 bidi-reordered rows.  */
-             while (MATRIX_ROW_CONTINUATION_LINE_P (row))
+             for (row1 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
+                  MATRIX_ROW_CONTINUATION_LINE_P (row);
+                  --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)
+                 if (row <= row1)
                    {
                      rc = CURSOR_MOVEMENT_MUST_SCROLL;
                      break;
                    }
-
+                 xassert (row->enabled_p);
                }
            }
          if (must_scroll)
            ;
          else if (rc != CURSOR_MOVEMENT_SUCCESS
              && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
+             /* Make sure this isn't a header line by any chance, since
+                then MATRIX_ROW_PARTIALLY_VISIBLE_P might yield non-zero.  */
+             && !row->mode_line_p
              && make_cursor_line_fully_visible_p)
            {
              if (PT == MATRIX_ROW_END_CHARPOS (row)
@@ -15014,7 +15129,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
   int current_matrix_up_to_date_p = 0;
   int used_current_matrix_p = 0;
   /* This is less strict than current_matrix_up_to_date_p.
-     It indictes that the buffer contents and narrowing are unchanged.  */
+     It indicates that the buffer contents and narrowing are unchanged.  */
   int buffer_unchanged_p = 0;
   int temp_scroll_step = 0;
   int count = SPECPDL_INDEX ();
@@ -15536,8 +15651,8 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
        ? min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
        : 0;
       EMACS_INT margin_pos = CHARPOS (startp);
-      int scrolling_up;
       Lisp_Object aggressive;
+      int scrolling_up;
 
       /* If there is a scroll margin at the top of the window, find
         its character position.  */
@@ -15546,7 +15661,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
             accessible region of the buffer.  This can happen when we
             have just switched to a different buffer and/or changed
             its restriction.  In that case, startp is initialized to
-            the character position 1 (BEG) because we did not yet
+            the character position 1 (BEGV) because we did not yet
             have chance to display the buffer even once.  */
          && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
        {
@@ -15555,7 +15670,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
 
          SAVE_IT (it1, it, it1data);
          start_display (&it1, w, startp);
-         move_it_vertically (&it1, margin);
+         move_it_vertically (&it1, margin * FRAME_LINE_HEIGHT (f));
          margin_pos = IT_CHARPOS (it1);
          RESTORE_IT (&it, &it, it1data);
        }
@@ -15579,7 +15694,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
              pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
              if (pt_offset == 0 && float_amount > 0)
                pt_offset = 1;
-             if (pt_offset)
+             if (pt_offset && margin > 0)
                margin -= 1;
            }
          /* Compute how much to move the window start backward from
@@ -15699,6 +15814,25 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
          goto recenter;
        }
 
+      /* Users who set scroll-conservatively to a large number want
+        point just above/below the scroll margin.  If we ended up
+        with point's row partially visible, move the window start to
+        make that row fully visible and out of the margin.  */
+      if (scroll_conservatively > SCROLL_LIMIT)
+       {
+         int margin =
+           scroll_margin > 0
+           ? min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
+           : 0;
+         int move_down = w->cursor.vpos >= WINDOW_TOTAL_LINES (w) / 2;
+
+         move_it_by_lines (&it, move_down ? margin + 1 : -(margin + 1));
+         clear_glyph_matrix (w->desired_matrix);
+         if (1 == try_window (window, it.current.pos,
+                              TRY_WINDOW_CHECK_MARGINS))
+           goto done;
+       }
+
       /* If centering point failed to make the whole line visible,
         put point at the top instead.  That has to make the whole line
         visible, if it can be done.  */
@@ -16068,13 +16202,20 @@ try_window_reusing_current_matrix (struct window *w)
 
              start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
            }
-         /* If we have reached alignment,
-            we can copy the rest of the rows.  */
-         if (IT_CHARPOS (it) == CHARPOS (start))
+         /* If we have reached alignment, we can copy the rest of the
+            rows.  */
+         if (IT_CHARPOS (it) == CHARPOS (start)
+             /* Don't accept "alignment" inside a display vector,
+                since start_row could have started in the middle of
+                that same display vector (thus their character
+                positions match), and we have no way of telling if
+                that is the case.  */
+             && it.current.dpvec_index < 0)
            break;
 
          if (display_line (&it))
            last_text_row = it.glyph_row - 1;
+
        }
 
       /* A value of current_y < last_visible_y means that we stopped
@@ -16240,7 +16381,10 @@ try_window_reusing_current_matrix (struct window *w)
           ++first_row_to_display)
        {
          if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
-             && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
+             && (PT < MATRIX_ROW_END_CHARPOS (first_row_to_display)
+                 || (PT == MATRIX_ROW_END_CHARPOS (first_row_to_display)
+                     && first_row_to_display->ends_at_zv_p
+                     && pt_row == NULL)))
            pt_row = first_row_to_display;
        }
 
@@ -16332,7 +16476,9 @@ try_window_reusing_current_matrix (struct window *w)
       if (pt_row)
        {
          for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
-              row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
+              row < bottom_row
+                && PT >= MATRIX_ROW_END_CHARPOS (row)
+                && !row->ends_at_zv_p;
               row++)
            {
              w->cursor.vpos++;
@@ -16473,7 +16619,15 @@ find_last_unchanged_at_beg_row (struct window *w)
             continued.  */
          && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
               && (row->continued_p
-                  || row->exact_window_width_line_p)))
+                  || row->exact_window_width_line_p))
+         /* If ROW->end is beyond ZV, then ROW->end is outdated and
+            needs to be recomputed, so don't consider this row as
+            unchanged.  This happens when the last line was
+            bidi-reordered and was killed immediately before this
+            redisplay cycle.  In that case, ROW->end stores the
+            buffer position of the first visual-order character of
+            the killed text, which is now beyond ZV.  */
+         && CHARPOS (row->end.pos) <= ZV)
        row_found = row;
 
       /* Stop if last visible row.  */
@@ -16996,7 +17150,7 @@ try_window_id (struct window *w)
   last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
   if (last_unchanged_at_beg_row)
     {
-      /* Avoid starting to display in the moddle of a character, a TAB
+      /* Avoid starting to display in the middle of a character, a TAB
         for instance.  This is easier than to set up the iterator
         exactly, and it's not a frequent case, so the additional
         effort wouldn't really pay off.  */
@@ -17925,6 +18079,23 @@ insert_left_trunc_glyphs (struct it *it)
     }
 }
 
+/* Compute the hash code for ROW.  */
+unsigned
+row_hash (struct glyph_row *row)
+{
+  int area, k;
+  unsigned hashval = 0;
+
+  for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
+    for (k = 0; k < row->used[area]; ++k)
+      hashval = ((((hashval << 4) + (hashval >> 24)) & 0x0fffffff)
+                 + row->glyphs[area][k].u.val
+                 + row->glyphs[area][k].face_id
+                 + row->glyphs[area][k].padding_p
+                 + (row->glyphs[area][k].type << 2));
+
+  return hashval;
+}
 
 /* Compute the pixel height and width of IT->glyph_row.
 
@@ -18011,17 +18182,7 @@ compute_line_metrics (struct it *it)
     }
 
   /* Compute a hash code for this row.  */
-  {
-    int area, i;
-    row->hash = 0;
-    for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
-      for (i = 0; i < row->used[area]; ++i)
-       row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
-                    + row->glyphs[area][i].u.val
-                    + row->glyphs[area][i].face_id
-                    + row->glyphs[area][i].padding_p
-                    + (row->glyphs[area][i].type << 2));
-  }
+  row->hash = row_hash (row);
 
   it->max_ascent = it->max_descent = 0;
   it->max_phys_ascent = it->max_phys_descent = 0;
@@ -18072,8 +18233,10 @@ append_space_for_newline (struct it *it, int default_face_p)
          it->c = it->char_to_display = ' ';
          it->len = 1;
 
+         /* If the default face was remapped, be sure to use the
+            remapped face for the appended newline. */
          if (default_face_p)
-           it->face_id = DEFAULT_FACE_ID;
+           it->face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
          else if (it->face_before_selective_p)
            it->face_id = it->saved_face_id;
          face = FACE_FROM_ID (it->f, it->face_id);
@@ -18109,7 +18272,7 @@ append_space_for_newline (struct it *it, int default_face_p)
 static void
 extend_face_to_end_of_line (struct it *it)
 {
-  struct face *face;
+  struct face *face, *default_face;
   struct frame *f = it->f;
 
   /* If line is already filled, do nothing.  Non window-system frames
@@ -18123,6 +18286,9 @@ extend_face_to_end_of_line (struct it *it)
         && !it->glyph_row->continued_p))
     return;
 
+  /* The default face, possibly remapped. */
+  default_face = FACE_FROM_ID (f, lookup_basic_face (f, DEFAULT_FACE_ID));
+
   /* 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.  */
@@ -18160,7 +18326,7 @@ extend_face_to_end_of_line (struct it *it)
       if (it->glyph_row->used[TEXT_AREA] == 0)
        {
          it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
-         it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
+         it->glyph_row->glyphs[TEXT_AREA][0].face_id = face->id;
          it->glyph_row->used[TEXT_AREA] = 1;
        }
 #ifdef HAVE_WINDOW_SYSTEM
@@ -18196,7 +18362,7 @@ extend_face_to_end_of_line (struct it *it)
                 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;
+               it->face_id = default_face->id;
              else
                it->face_id = face->id;
              append_stretch_glyph (it, make_number (0), stretch_width,
@@ -18229,7 +18395,7 @@ extend_face_to_end_of_line (struct it *it)
         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;
+       it->face_id = default_face->id;
       else
        it->face_id = face->id;
 
@@ -18362,9 +18528,11 @@ cursor_row_p (struct glyph_row *row)
       /* Suppose the row ends on a string.
         Unless the row is continued, that means it ends on a newline
         in the string.  If it's anything other than a display string
-        (e.g. a before-string from an overlay), we don't want the
+        (e.g., a before-string from an overlay), we don't want the
         cursor there.  (This heuristic seems to give the optimal
-        behavior for the various types of multi-line strings.)  */
+        behavior for the various types of multi-line strings.)
+        One exception: if the string has `cursor' property on one of
+        its characters, we _do_ want the cursor there.  */
       if (CHARPOS (row->end.string_pos) >= 0)
        {
          if (row->continued_p)
@@ -18386,6 +18554,25 @@ cursor_row_p (struct glyph_row *row)
                    result =
                      (!NILP (prop)
                       && display_prop_string_p (prop, glyph->object));
+                   /* If there's a `cursor' property on one of the
+                      string's characters, this row is a cursor row,
+                      even though this is not a display string.  */
+                   if (!result)
+                     {
+                       Lisp_Object s = glyph->object;
+
+                       for ( ; glyph >= beg && EQ (glyph->object, s); --glyph)
+                         {
+                           EMACS_INT gpos = glyph->charpos;
+
+                           if (!NILP (Fget_char_property (make_number (gpos),
+                                                          Qcursor, s)))
+                             {
+                               result = 1;
+                               break;
+                             }
+                         }
+                     }
                    break;
                  }
            }
@@ -18424,12 +18611,13 @@ cursor_row_p (struct glyph_row *row)
    `line-prefix' and `wrap-prefix' properties.  */
 
 static int
-push_display_prop (struct it *it, Lisp_Object prop)
+push_prefix_prop (struct it *it, Lisp_Object prop)
 {
   struct text_pos pos =
-    (it->method == GET_FROM_STRING) ? it->current.string_pos : it->current.pos;
+    STRINGP (it->string) ? it->current.string_pos : it->current.pos;
 
   xassert (it->method == GET_FROM_BUFFER
+          || it->method == GET_FROM_DISPLAY_VECTOR
           || it->method == GET_FROM_STRING);
 
   /* We need to save the current buffer/string position, so it will be
@@ -18447,6 +18635,7 @@ push_display_prop (struct it *it, Lisp_Object prop)
        }
 
       it->string = prop;
+      it->string_from_prefix_prop_p = 1;
       it->multibyte_p = STRING_MULTIBYTE (it->string);
       it->current.overlay_string_index = -1;
       IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
@@ -18533,7 +18722,7 @@ handle_line_prefix (struct it *it)
       if (NILP (prefix))
        prefix = Vline_prefix;
     }
-  if (! NILP (prefix) && push_display_prop (it, prefix))
+  if (! NILP (prefix) && push_prefix_prop (it, prefix))
     {
       /* If the prefix is wider than the window, and we try to wrap
         it, it would acquire its own wrap prefix, and so on till the
@@ -18814,7 +19003,8 @@ display_line (struct it *it)
 #define RECORD_MAX_MIN_POS(IT)                                 \
   do                                                           \
     {                                                          \
-      int composition_p = (IT)->what == IT_COMPOSITION;                \
+      int composition_p = !STRINGP ((IT)->string)              \
+       && ((IT)->what == IT_COMPOSITION);                      \
       EMACS_INT current_pos =                                  \
        composition_p ? (IT)->cmp_it.charpos                    \
                      : IT_CHARPOS (*(IT));                     \
@@ -18869,8 +19059,13 @@ display_line (struct it *it)
          /* A row that displays right-to-left text must always have
             its last face extended all the way to the end of line,
             even if this row ends in ZV, because we still write to
-            the screen left to right.  */
-         if (row->reversed_p)
+            the screen left to right.  We also need to extend the
+            last face if the default face is remapped to some
+            different face, otherwise the functions that clear
+            portions of the screen will clear with the default face's
+            background color.  */
+         if (row->reversed_p
+             || lookup_basic_face (it->f, DEFAULT_FACE_ID) != DEFAULT_FACE_ID)
            extend_face_to_end_of_line (it);
          break;
        }
@@ -19357,9 +19552,18 @@ display_line (struct it *it)
       overlay_arrow_seen = 1;
     }
 
+  /* Highlight trailing whitespace.  */
+  if (!NILP (Vshow_trailing_whitespace))
+    highlight_trailing_whitespace (it->f, it->glyph_row);
+
   /* Compute pixel dimensions of this line.  */
   compute_line_metrics (it);
 
+  /* Implementation note: No changes in the glyphs of ROW or in their
+     faces can be done past this point, because compute_line_metrics
+     computes ROW's hash value and stores it within the glyph_row
+     structure.  */
+
   /* Record whether this row ends inside an ellipsis.  */
   row->ends_in_ellipsis_p
     = (it->method == GET_FROM_DISPLAY_VECTOR
@@ -19394,10 +19598,6 @@ display_line (struct it *it)
       && cursor_row_p (row))
     set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
 
-  /* Highlight trailing whitespace.  */
-  if (!NILP (Vshow_trailing_whitespace))
-    highlight_trailing_whitespace (it->f, it->glyph_row);
-
   /* Prepare for the next line.  This line starts horizontally at (X
      HPOS) = (0 0).  Vertical positions are incremented.  As a
      convenience for the caller, IT->glyph_row is set to the next
@@ -19443,7 +19643,10 @@ See also `bidi-paragraph-direction'.  */)
     }
 
   if (NILP (BVAR (buf, bidi_display_reordering))
-      || NILP (BVAR (buf, enable_multibyte_characters)))
+      || NILP (BVAR (buf, enable_multibyte_characters))
+      /* When we are loading loadup.el, the character property tables
+        needed for bidi iteration are not yet available.  */
+      || !NILP (Vpurify_flag))
     return Qleft_to_right;
   else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
     return BVAR (buf, bidi_paragraph_direction);
@@ -19484,6 +19687,7 @@ See also `bidi-paragraph-direction'.  */)
            bytepos--;
        }
       bidi_init_it (pos, bytepos, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb);
+      itb.paragraph_dir = NEUTRAL_DIR;
       itb.string.s = NULL;
       itb.string.lstring = Qnil;
       itb.string.bufpos = 0;
@@ -22020,7 +22224,7 @@ get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
 
 
 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
-   Retunr 1 if FONT has a glyph for C, otherwise return 0.  */
+   Return 1 if FONT has a glyph for C, otherwise return 0.  */
 
 static inline int
 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
@@ -22092,6 +22296,12 @@ fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
     }
   s->cmp_to = i;
 
+  if (s->face == NULL)
+    {
+      s->face = base_face->ascii_face;
+      s->font = s->face->font;
+    }
+
   /* All glyph strings for the same composition has the same width,
      i.e. the width set for the first component of the composition.  */
   s->width = s->first_glyph->pixel_width;
@@ -22648,7 +22858,7 @@ compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
     ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id;                \
     struct composition *cmp = composition_table[cmp_id];                   \
     XChar2b *char2b;                                                       \
-    struct glyph_string *first_s IF_LINT (= NULL);                         \
+    struct glyph_string *first_s = NULL;                                   \
     int n;                                                                 \
                                                                            \
     char2b = (XChar2b *) alloca ((sizeof *char2b) * cmp->glyph_len);       \
@@ -23587,7 +23797,7 @@ produce_stretch_glyph (struct it *it)
     {
       width = it->last_visible_x - it->current_x;
 #ifdef HAVE_WINDOW_SYSTEM
-      /* Subtact one more pixel from the stretch width, but only on
+      /* Subtract one more pixel from the stretch width, but only on
         GUI frames, since on a TTY each glyph is one "pixel" wide.  */
       width -= FRAME_WINDOW_P (it->f);
 #endif
@@ -23874,7 +24084,7 @@ produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
          sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
          str = buf;
        }
-      for (len = 0; str[len] && ASCII_BYTE_P (str[len]); len++)
+      for (len = 0; str[len] && ASCII_BYTE_P (str[len]) && len < 6; len++)
        code[len] = font->driver->encode_char (font, str[len]);
       upper_len = (len + 1) / 2;
       font->driver->text_extents (font, code, upper_len,
@@ -24310,7 +24520,7 @@ x_produce_glyphs (struct it *it)
          /* Initialize the bounding box.  */
          if (pcm)
            {
-             width = pcm->width;
+             width = cmp->glyph_len > 0 ? pcm->width : 0;
              ascent = pcm->ascent;
              descent = pcm->descent;
              lbearing = pcm->lbearing;
@@ -24318,7 +24528,7 @@ x_produce_glyphs (struct it *it)
            }
          else
            {
-             width = font->space_width;
+             width = cmp->glyph_len > 0 ? font->space_width : 0;
              ascent = FONT_BASE (font);
              descent = FONT_DESCENT (font);
              lbearing = 0;
@@ -24536,7 +24746,7 @@ x_produce_glyphs (struct it *it)
       if (it->descent < 0)
        it->descent = 0;
 
-      if (it->glyph_row)
+      if (it->glyph_row && cmp->glyph_len > 0)
        append_composite_glyph (it);
     }
   else if (it->what == IT_COMPOSITION)
@@ -24624,9 +24834,17 @@ x_produce_glyphs (struct it *it)
 void
 x_write_glyphs (struct glyph *start, int len)
 {
-  int x, hpos;
+  int x, hpos, chpos = updated_window->phys_cursor.hpos;
 
   xassert (updated_window && updated_row);
+  /* When the window is hscrolled, cursor hpos can legitimately be out
+     of bounds, but we draw the cursor at the corresponding window
+     margin in that case.  */
+  if (!updated_row->reversed_p && chpos < 0)
+    chpos = 0;
+  if (updated_row->reversed_p && chpos >= updated_row->used[TEXT_AREA])
+    chpos = updated_row->used[TEXT_AREA] - 1;
+
   BLOCK_INPUT;
 
   /* Write glyphs.  */
@@ -24641,8 +24859,8 @@ x_write_glyphs (struct glyph *start, int len)
   if (updated_area == TEXT_AREA
       && updated_window->phys_cursor_on_p
       && updated_window->phys_cursor.vpos == output_cursor.vpos
-      && updated_window->phys_cursor.hpos >= hpos
-      && updated_window->phys_cursor.hpos < hpos + len)
+      && chpos >= hpos
+      && chpos < hpos + len)
     updated_window->phys_cursor_on_p = 0;
 
   UNBLOCK_INPUT;
@@ -25152,8 +25370,17 @@ draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
     {
       int on_p = w->phys_cursor_on_p;
       int x1;
-      x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
-                       w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
+      int hpos = w->phys_cursor.hpos;
+
+      /* When the window is hscrolled, cursor hpos can legitimately be
+        out of bounds, but we draw the cursor at the corresponding
+        window margin in that case.  */
+      if (!row->reversed_p && hpos < 0)
+       hpos = 0;
+      if (row->reversed_p && hpos >= row->used[TEXT_AREA])
+       hpos = row->used[TEXT_AREA] - 1;
+
+      x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, hpos, hpos + 1,
                        hl, 0);
       w->phys_cursor_on_p = on_p;
 
@@ -25241,6 +25468,14 @@ erase_phys_cursor (struct window *w)
        : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
     goto mark_cursor_off;
 
+  /* When the window is hscrolled, cursor hpos can legitimately be out
+     of bounds, but we draw the cursor at the corresponding window
+     margin in that case.  */
+  if (!cursor_row->reversed_p && hpos < 0)
+    hpos = 0;
+  if (cursor_row->reversed_p && hpos >= cursor_row->used[TEXT_AREA])
+    hpos = cursor_row->used[TEXT_AREA] - 1;
+
   /* If the cursor is in the mouse face area, redisplay that when
      we clear the cursor.  */
   if (! NILP (hlinfo->mouse_face_window)
@@ -25384,8 +25619,26 @@ update_window_cursor (struct window *w, int on)
      of being deleted.  */
   if (w->current_matrix)
     {
+      int hpos = w->phys_cursor.hpos;
+      int vpos = w->phys_cursor.vpos;
+      struct glyph_row *row;
+
+      if (vpos >= w->current_matrix->nrows
+         || hpos >= w->current_matrix->matrix_w)
+       return;
+
+      row = MATRIX_ROW (w->current_matrix, vpos);
+
+      /* When the window is hscrolled, cursor hpos can legitimately be
+        out of bounds, but we draw the cursor at the corresponding
+        window margin in that case.  */
+      if (!row->reversed_p && hpos < 0)
+       hpos = 0;
+      if (row->reversed_p && hpos >= row->used[TEXT_AREA])
+       hpos = row->used[TEXT_AREA] - 1;
+
       BLOCK_INPUT;
-      display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
+      display_and_set_cursor (w, on, hpos, vpos,
                              w->phys_cursor.x, w->phys_cursor.y);
       UNBLOCK_INPUT;
     }
@@ -25555,9 +25808,18 @@ show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
       if (FRAME_WINDOW_P (f)
          && phys_cursor_on_p && !w->phys_cursor_on_p)
        {
+         int hpos = w->phys_cursor.hpos;
+
+         /* When the window is hscrolled, cursor hpos can legitimately be
+            out of bounds, but we draw the cursor at the corresponding
+            window margin in that case.  */
+         if (!row->reversed_p && hpos < 0)
+           hpos = 0;
+         if (row->reversed_p && hpos >= row->used[TEXT_AREA])
+           hpos = row->used[TEXT_AREA] - 1;
+
          BLOCK_INPUT;
-         display_and_set_cursor (w, 1,
-                                 w->phys_cursor.hpos, w->phys_cursor.vpos,
+         display_and_set_cursor (w, 1, hpos, w->phys_cursor.vpos,
                                  w->phys_cursor.x, w->phys_cursor.y);
          UNBLOCK_INPUT;
        }
@@ -25656,19 +25918,33 @@ coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
 int
 cursor_in_mouse_face_p (struct window *w)
 {
-  return coords_in_mouse_face_p (w, w->phys_cursor.hpos, w->phys_cursor.vpos);
+  int hpos = w->phys_cursor.hpos;
+  int vpos = w->phys_cursor.vpos;
+  struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
+
+  /* When the window is hscrolled, cursor hpos can legitimately be out
+     of bounds, but we draw the cursor at the corresponding window
+     margin in that case.  */
+  if (!row->reversed_p && hpos < 0)
+    hpos = 0;
+  if (row->reversed_p && hpos >= row->used[TEXT_AREA])
+    hpos = row->used[TEXT_AREA] - 1;
+
+  return coords_in_mouse_face_p (w, hpos, vpos);
 }
 
 
 \f
 /* Find the glyph rows START_ROW and END_ROW of window W that display
    characters between buffer positions START_CHARPOS and END_CHARPOS
-   (excluding END_CHARPOS).  This is similar to row_containing_pos,
-   but is more accurate when bidi reordering makes buffer positions
-   change non-linearly with glyph rows.  */
+   (excluding END_CHARPOS).  DISP_STRING is a display string that
+   covers these buffer positions.  This is similar to
+   row_containing_pos, but is more accurate when bidi reordering makes
+   buffer positions change non-linearly with glyph rows.  */
 static void
 rows_from_pos_range (struct window *w,
                     EMACS_INT start_charpos, EMACS_INT end_charpos,
+                    Lisp_Object disp_string,
                     struct glyph_row **start, struct glyph_row **end)
 {
   struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
@@ -25720,8 +25996,11 @@ rows_from_pos_range (struct window *w,
 
          while (g < e)
            {
-             if ((BUFFERP (g->object) || INTEGERP (g->object))
-                 && start_charpos <= g->charpos && g->charpos < end_charpos)
+             if (((BUFFERP (g->object) || INTEGERP (g->object))
+                  && start_charpos <= g->charpos && g->charpos < end_charpos)
+                 /* A glyph that comes from DISP_STRING is by
+                    definition to be highlighted.  */
+                 || EQ (g->object, disp_string))
                *start = row;
              g++;
            }
@@ -25740,14 +26019,15 @@ rows_from_pos_range (struct window *w,
   for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
     {
       struct glyph_row *next = row + 1;
+      EMACS_INT next_start = MATRIX_ROW_START_CHARPOS (next);
 
       if (!next->enabled_p
          || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
          /* The first row >= START whose range of displayed characters
             does NOT intersect the range [START_CHARPOS..END_CHARPOS]
             is the row END + 1.  */
-         || (start_charpos < MATRIX_ROW_START_CHARPOS (next)
-             && end_charpos < MATRIX_ROW_START_CHARPOS (next))
+         || (start_charpos < next_start
+             && end_charpos < next_start)
          || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
               || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
                   && !next->ends_at_zv_p
@@ -25766,12 +26046,29 @@ rows_from_pos_range (struct window *w,
             but none of the characters it displays are in the range, it is
             also END + 1. */
          struct glyph *g = next->glyphs[TEXT_AREA];
+         struct glyph *s = g;
          struct glyph *e = g + next->used[TEXT_AREA];
 
          while (g < e)
            {
-             if ((BUFFERP (g->object) || INTEGERP (g->object))
-                 && start_charpos <= g->charpos && g->charpos < end_charpos)
+             if (((BUFFERP (g->object) || INTEGERP (g->object))
+                  && ((start_charpos <= g->charpos && g->charpos < end_charpos)
+                      /* If the buffer position of the first glyph in
+                         the row is equal to END_CHARPOS, it means
+                         the last character to be highlighted is the
+                         newline of ROW, and we must consider NEXT as
+                         END, not END+1.  */
+                      || (((!next->reversed_p && g == s)
+                           || (next->reversed_p && g == e - 1))
+                          && (g->charpos == end_charpos
+                              /* Special case for when NEXT is an
+                                 empty line at ZV.  */
+                              || (g->charpos == -1
+                                  && !row->ends_at_zv_p
+                                  && next_start == end_charpos)))))
+                 /* A glyph that comes from DISP_STRING is by
+                    definition to be highlighted.  */
+                 || EQ (g->object, disp_string))
                break;
              g++;
            }
@@ -25780,6 +26077,13 @@ rows_from_pos_range (struct window *w,
              *end = row;
              break;
            }
+         /* The first row that ends at ZV must be the last to be
+            highlighted.  */
+         else if (next->ends_at_zv_p)
+           {
+             *end = next;
+             break;
+           }
        }
     }
 }
@@ -25790,7 +26094,7 @@ rows_from_pos_range (struct window *w,
    for the overlay or run of text properties specifying the mouse
    face.  BEFORE_STRING and AFTER_STRING, if non-nil, are a
    before-string and after-string that must also be highlighted.
-   COVER_STRING, if non-nil, is a display string that may cover some
+   DISP_STRING, if non-nil, is a display string that may cover some
    or all of the highlighted text.  */
 
 static void
@@ -25801,7 +26105,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
                            EMACS_INT end_charpos,
                            Lisp_Object before_string,
                            Lisp_Object after_string,
-                           Lisp_Object cover_string)
+                           Lisp_Object disp_string)
 {
   struct window *w = XWINDOW (window);
   struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
@@ -25810,17 +26114,17 @@ mouse_face_from_buffer_pos (Lisp_Object window,
   EMACS_INT ignore, pos;
   int x;
 
-  xassert (NILP (cover_string) || STRINGP (cover_string));
+  xassert (NILP (disp_string) || STRINGP (disp_string));
   xassert (NILP (before_string) || STRINGP (before_string));
   xassert (NILP (after_string) || STRINGP (after_string));
 
   /* Find the rows corresponding to START_CHARPOS and END_CHARPOS.  */
-  rows_from_pos_range (w, start_charpos, end_charpos, &r1, &r2);
+  rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2);
   if (r1 == NULL)
     r1 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
   /* If the before-string or display-string contains newlines,
      rows_from_pos_range skips to its last row.  Move back.  */
-  if (!NILP (before_string) || !NILP (cover_string))
+  if (!NILP (before_string) || !NILP (disp_string))
     {
       struct glyph_row *prev;
       while ((prev = r1 - 1, prev >= first)
@@ -25832,7 +26136,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
          while (--glyph >= beg && INTEGERP (glyph->object));
          if (glyph < beg
              || !(EQ (glyph->object, before_string)
-                  || EQ (glyph->object, cover_string)))
+                  || EQ (glyph->object, disp_string)))
            break;
          r1 = prev;
        }
@@ -25857,10 +26161,10 @@ mouse_face_from_buffer_pos (Lisp_Object window,
        r2 = next;
     }
   /* The rest of the display engine assumes that mouse_face_beg_row is
-     either above below mouse_face_end_row or identical to it.  But
-     with bidi-reordered continued lines, the row for START_CHARPOS
-     could be below the row for END_CHARPOS.  If so, swap the rows and
-     store them in correct order.  */
+     either above mouse_face_end_row or identical to it.  But with
+     bidi-reordered continued lines, the row for START_CHARPOS could
+     be below the row for END_CHARPOS.  If so, swap the rows and store
+     them in correct order.  */
   if (r1->y > r2->y)
     {
       struct glyph_row *tem = r2;
@@ -25875,7 +26179,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
   hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
 
   /* For a bidi-reordered row, the positions of BEFORE_STRING,
-     AFTER_STRING, COVER_STRING, START_CHARPOS, and END_CHARPOS
+     AFTER_STRING, DISP_STRING, START_CHARPOS, and END_CHARPOS
      could be anywhere in the row and in any order.  The strategy
      below is to find the leftmost and the rightmost glyph that
      belongs to either of these 3 strings, or whose position is
@@ -25901,11 +26205,11 @@ mouse_face_from_buffer_pos (Lisp_Object window,
          x += glyph->pixel_width;
 
       /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
-        or COVER_STRING, and the first glyph from buffer whose
+        or DISP_STRING, and the first glyph from buffer whose
         position is between START_CHARPOS and END_CHARPOS.  */
       for (; glyph < end
             && !INTEGERP (glyph->object)
-            && !EQ (glyph->object, cover_string)
+            && !EQ (glyph->object, disp_string)
             && !(BUFFERP (glyph->object)
                  && (glyph->charpos >= start_charpos
                      && glyph->charpos < end_charpos));
@@ -25952,11 +26256,11 @@ mouse_face_from_buffer_pos (Lisp_Object window,
          ;
 
       /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
-        or COVER_STRING, and the first glyph from buffer whose
+        or DISP_STRING, and the first glyph from buffer whose
         position is between START_CHARPOS and END_CHARPOS.  */
       for (; glyph > end
             && !INTEGERP (glyph->object)
-            && !EQ (glyph->object, cover_string)
+            && !EQ (glyph->object, disp_string)
             && !(BUFFERP (glyph->object)
                  && (glyph->charpos >= start_charpos
                      && glyph->charpos < end_charpos));
@@ -26012,17 +26316,16 @@ mouse_face_from_buffer_pos (Lisp_Object window,
         row, and also blanks and stretch glyphs inserted by
         extend_face_to_end_of_line.  */
       while (end > glyph
-            && INTEGERP ((end - 1)->object)
-            && (end - 1)->charpos <= 0)
+            && INTEGERP ((end - 1)->object))
        --end;
       /* Scan the rest of the glyph row from the end, looking for the
         first glyph that comes from BEFORE_STRING, AFTER_STRING, or
-        COVER_STRING, or whose position is between START_CHARPOS
+        DISP_STRING, or whose position is between START_CHARPOS
         and END_CHARPOS */
       for (--end;
             end > glyph
             && !INTEGERP (end->object)
-            && !EQ (end->object, cover_string)
+            && !EQ (end->object, disp_string)
             && !(BUFFERP (end->object)
                  && (end->charpos >= start_charpos
                      && end->charpos < end_charpos));
@@ -26059,20 +26362,19 @@ mouse_face_from_buffer_pos (Lisp_Object window,
       x = r2->x;
       end++;
       while (end < glyph
-            && INTEGERP (end->object)
-            && end->charpos <= 0)
+            && INTEGERP (end->object))
        {
          x += end->pixel_width;
          ++end;
        }
       /* Scan the rest of the glyph row from the end, looking for the
         first glyph that comes from BEFORE_STRING, AFTER_STRING, or
-        COVER_STRING, or whose position is between START_CHARPOS
+        DISP_STRING, or whose position is between START_CHARPOS
         and END_CHARPOS */
       for ( ;
             end < glyph
             && !INTEGERP (end->object)
-            && !EQ (end->object, cover_string)
+            && !EQ (end->object, disp_string)
             && !(BUFFERP (end->object)
                  && (end->charpos >= start_charpos
                      && end->charpos < end_charpos));
@@ -26095,6 +26397,19 @@ mouse_face_from_buffer_pos (Lisp_Object window,
            }
          x += end->pixel_width;
        }
+      /* If we exited the above loop because we arrived at the last
+        glyph of the row, and its buffer position is still not in
+        range, it means the last character in range is the preceding
+        newline.  Bump the end column and x values to get past the
+        last glyph.  */
+      if (end == glyph
+         && BUFFERP (end->object)
+         && (end->charpos < start_charpos
+             || end->charpos >= end_charpos))
+       {
+         x += end->pixel_width;
+         ++end;
+       }
       hlinfo->mouse_face_end_x = x;
       hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
     }
@@ -26782,7 +27097,7 @@ void
 note_mouse_highlight (struct frame *f, int x, int y)
 {
   Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
-  enum window_part part;
+  enum window_part part = ON_NOTHING;
   Lisp_Object window;
   struct window *w;
   Cursor cursor = No_Cursor;
@@ -26816,11 +27131,14 @@ note_mouse_highlight (struct frame *f, int x, int y)
   /* Which window is that in?  */
   window = window_from_coordinates (f, x, y, &part, 1);
 
-  /* If we were displaying active text in another window, clear that.
-     Also clear if we move out of text area in same window.  */
+  /* If displaying active text in another window, clear that.  */
   if (! EQ (window, hlinfo->mouse_face_window)
-      || (part != ON_TEXT && part != ON_MODE_LINE && part != ON_HEADER_LINE
-         && !NILP (hlinfo->mouse_face_window)))
+      /* Also clear if we move out of text area in same window.  */
+      || (!NILP (hlinfo->mouse_face_window)
+         && !NILP (window)
+         && part != ON_TEXT
+         && part != ON_MODE_LINE
+         && part != ON_HEADER_LINE))
     clear_mouse_face (hlinfo);
 
   /* Not on a window -> return.  */
@@ -26873,7 +27191,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
       && XFASTINT (w->last_modified) == BUF_MODIFF (b)
       && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
     {
-      int hpos, vpos, dx, dy, area;
+      int hpos, vpos, dx, dy, area = LAST_AREA;
       EMACS_INT pos;
       struct glyph *glyph;
       Lisp_Object object;
@@ -27064,7 +27382,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
              /* The mouse-highlighting, if any, comes from an overlay
                 or text property in the buffer.  */
              Lisp_Object buffer IF_LINT (= Qnil);
-             Lisp_Object cover_string IF_LINT (= Qnil);
+             Lisp_Object disp_string IF_LINT (= Qnil);
 
              if (STRINGP (object))
                {
@@ -27078,13 +27396,13 @@ note_mouse_highlight (struct frame *f, int x, int y)
                      mouse_face = get_char_property_and_overlay
                        (make_number (pos), Qmouse_face, w->buffer, &overlay);
                      buffer = w->buffer;
-                     cover_string = object;
+                     disp_string = object;
                    }
                }
              else
                {
                  buffer = object;
-                 cover_string = Qnil;
+                 disp_string = Qnil;
                }
 
              if (!NILP (mouse_face))
@@ -27133,10 +27451,14 @@ note_mouse_highlight (struct frame *f, int x, int y)
                    }
 
                  mouse_face_from_buffer_pos (window, hlinfo, pos,
-                                             XFASTINT (before),
-                                             XFASTINT (after),
+                                             NILP (before)
+                                             ? 1
+                                             : XFASTINT (before),
+                                             NILP (after)
+                                             ? BUF_Z (XBUFFER (buffer))
+                                             : XFASTINT (after),
                                              before_string, after_string,
-                                             cover_string);
+                                             disp_string);
                  cursor = No_Cursor;
                }
            }
@@ -27934,7 +28256,6 @@ syms_of_xdisp (void)
   DEFSYM (Qhollow, "hollow");
   DEFSYM (Qhand, "hand");
   DEFSYM (Qarrow, "arrow");
-  DEFSYM (Qtext, "text");
   DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
 
   list_of_error = Fcons (Fcons (intern_c_string ("error"),
@@ -27984,28 +28305,34 @@ syms_of_xdisp (void)
 
 #ifdef HAVE_WINDOW_SYSTEM
   DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
-    doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
+    doc: /* Non-nil means draw block cursor as wide as the glyph under it.
 For example, if a block cursor is over a tab, it will be drawn as
 wide as that tab on the display.  */);
   x_stretch_cursor_p = 0;
 #endif
 
   DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
-    doc: /* *Non-nil means highlight trailing whitespace.
+    doc: /* Non-nil means highlight trailing whitespace.
 The face used for trailing whitespace is `trailing-whitespace'.  */);
   Vshow_trailing_whitespace = Qnil;
 
   DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
-    doc: /* *Control highlighting of nobreak space and soft hyphen.
-A value of t means highlight the character itself (for nobreak space,
-use face `nobreak-space').
-A value of nil means no highlighting.
-Other values mean display the escape glyph followed by an ordinary
-space or ordinary hyphen.  */);
+    doc: /* Control highlighting of non-ASCII space and hyphen chars.
+If the value is t, Emacs highlights non-ASCII chars which have the
+same appearance as an ASCII space or hyphen, using the `nobreak-space'
+or `escape-glyph' face respectively.
+
+U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
+U+2011 (non-breaking hyphen) are affected.
+
+Any other non-nil value means to display these characters as a escape
+glyph followed by an ordinary space or hyphen.
+
+A value of nil means no special handling of these characters.  */);
   Vnobreak_char_display = Qt;
 
   DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
-    doc: /* *The pointer shape to show in void text areas.
+    doc: /* The pointer shape to show in void text areas.
 A value of nil means to show the text pointer.  Other options are `arrow',
 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'.  */);
   Vvoid_text_area_pointer = Qarrow;
@@ -28038,14 +28365,14 @@ where to display overlay arrows.  */);
     = Fcons (intern_c_string ("overlay-arrow-position"), Qnil);
 
   DEFVAR_INT ("scroll-step", emacs_scroll_step,
-    doc: /* *The number of lines to try scrolling a window by when point moves out.
+    doc: /* The number of lines to try scrolling a window by when point moves out.
 If that fails to bring point back on frame, point is centered instead.
 If this is zero, point is always centered after it moves off frame.
 If you want scrolling to always be a line at a time, you should set
 `scroll-conservatively' to a large value rather than set this to 1.  */);
 
   DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
-    doc: /* *Scroll up to this many lines, to bring point back on screen.
+    doc: /* Scroll up to this many lines, to bring point back on screen.
 If point moves off-screen, redisplay will scroll by up to
 `scroll-conservatively' lines in order to bring point just barely
 onto the screen again.  If that cannot be done, then redisplay
@@ -28059,7 +28386,7 @@ A value of zero means always recenter point if it moves off screen.  */);
   scroll_conservatively = 0;
 
   DEFVAR_INT ("scroll-margin", scroll_margin,
-    doc: /* *Number of lines of margin at the top and bottom of a window.
+    doc: /* Number of lines of margin at the top and bottom of a window.
 Recenter the window whenever point gets within this many lines
 of the top or bottom of the window.  */);
   scroll_margin = 0;
@@ -28095,20 +28422,20 @@ Any other value means to use the appropriate face, `mode-line',
   mode_line_inverse_video = 1;
 
   DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
-    doc: /* *Maximum buffer size for which line number should be displayed.
+    doc: /* Maximum buffer size for which line number should be displayed.
 If the buffer is bigger than this, the line number does not appear
 in the mode line.  A value of nil means no limit.  */);
   Vline_number_display_limit = Qnil;
 
   DEFVAR_INT ("line-number-display-limit-width",
              line_number_display_limit_width,
-    doc: /* *Maximum line width (in characters) for line number display.
+    doc: /* Maximum line width (in characters) for line number display.
 If the average length of the lines near point is bigger than this, then the
 line number may be omitted from the mode line.  */);
   line_number_display_limit_width = 200;
 
   DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
-    doc: /* *Non-nil means highlight region even in nonselected windows.  */);
+    doc: /* Non-nil means highlight region even in nonselected windows.  */);
   highlight_nonselected_windows = 0;
 
   DEFVAR_BOOL ("multiple-frames", multiple_frames,
@@ -28161,7 +28488,11 @@ all the functions in the list are called, with the frame as argument.  */);
 Each function is called with two arguments, the window and its new
 display-start position.  Note that these functions are also called by
 `set-window-buffer'.  Also note that the value of `window-end' is not
-valid when these functions are called.  */);
+valid when these functions are called.
+
+Warning: Do not use this feature to alter the way the window
+is scrolled.  It is not designed for that, and such use probably won't
+work.  */);
   Vwindow_scroll_functions = Qnil;
 
   DEFVAR_LISP ("window-text-change-functions",
@@ -28176,7 +28507,7 @@ See `set-window-redisplay-end-trigger'.  */);
   Vredisplay_end_trigger_functions = Qnil;
 
   DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
-     doc: /* *Non-nil means autoselect window with mouse pointer.
+     doc: /* Non-nil means autoselect window with mouse pointer.
 If nil, do not autoselect windows.
 A positive number means delay autoselection by that many seconds: a
 window is autoselected only after the mouse has remained in that
@@ -28196,7 +28527,7 @@ When customizing this variable make sure that the actual value of
   Vmouse_autoselect_window = Qnil;
 
   DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
-    doc: /* *Non-nil means automatically resize tool-bars.
+    doc: /* Non-nil means automatically resize tool-bars.
 This dynamically changes the tool-bar's height to the minimum height
 that is needed to make all tool-bar items visible.
 If value is `grow-only', the tool-bar's height is only increased
@@ -28204,15 +28535,15 @@ automatically; to decrease the tool-bar height, use \\[recenter].  */);
   Vauto_resize_tool_bars = Qt;
 
   DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
-    doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them.  */);
+    doc: /* Non-nil means raise tool-bar buttons when the mouse moves over them.  */);
   auto_raise_tool_bar_buttons_p = 1;
 
   DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
-    doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible.  */);
+    doc: /* Non-nil means to scroll (recenter) cursor line if it is not fully visible.  */);
   make_cursor_line_fully_visible_p = 1;
 
   DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
-    doc: /* *Border below tool-bar in pixels.
+    doc: /* Border below tool-bar in pixels.
 If an integer, use it as the height of the border.
 If it is one of `internal-border-width' or `border-width', use the
 value of the corresponding frame parameter.
@@ -28220,7 +28551,7 @@ Otherwise, no border is added below the tool-bar.  */);
   Vtool_bar_border = Qinternal_border_width;
 
   DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
-    doc: /* *Margin around tool-bar buttons in pixels.
+    doc: /* Margin around tool-bar buttons in pixels.
 If an integer, use that for both horizontal and vertical margins.
 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
 HORZ specifying the horizontal margin, and VERT specifying the
@@ -28228,7 +28559,7 @@ vertical margin.  */);
   Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
 
   DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
-    doc: /* *Relief thickness of tool-bar buttons.  */);
+    doc: /* Relief thickness of tool-bar buttons.  */);
   tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
 
   DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
@@ -28243,7 +28574,7 @@ It can be one of
   Vtool_bar_style = Qnil;
 
   DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
-    doc: /* *Maximum number of characters a label can have to be shown.
+    doc: /* Maximum number of characters a label can have to be shown.
 The tool bar style must also show labels for this to have any effect, see
 `tool-bar-style'.  */);
   tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
@@ -28258,7 +28589,7 @@ fontified regions the property `fontified'.  */);
 
   DEFVAR_BOOL ("unibyte-display-via-language-environment",
                unibyte_display_via_language_environment,
-    doc: /* *Non-nil means display unibyte text according to language environment.
+    doc: /* Non-nil means display unibyte text according to language environment.
 Specifically, this means that raw bytes in the range 160-255 decimal
 are displayed by converting them to the equivalent multibyte characters
 according to the current language environment.  As a result, they are
@@ -28269,7 +28600,7 @@ but does not change the fact they are interpreted as raw bytes.  */);
   unibyte_display_via_language_environment = 0;
 
   DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
-    doc: /* *Maximum height for resizing mini-windows (the minibuffer and the echo area).
+    doc: /* Maximum height for resizing mini-windows (the minibuffer and the echo area).
 If a float, it specifies a fraction of the mini-window frame's height.
 If an integer, it specifies a number of lines.  */);
   Vmax_mini_window_height = make_float (0.25);
@@ -28303,12 +28634,12 @@ point visible.  */);
   DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
 
   DEFVAR_INT ("hscroll-margin", hscroll_margin,
-    doc: /* *How many columns away from the window edge point is allowed to get
+    doc: /* How many columns away from the window edge point is allowed to get
 before automatic hscrolling will horizontally scroll the window.  */);
   hscroll_margin = 5;
 
   DEFVAR_LISP ("hscroll-step", Vhscroll_step,
-    doc: /* *How many columns to scroll the window when point gets too close to the edge.
+    doc: /* How many columns to scroll the window when point gets too close to the edge.
 When point is less than `hscroll-margin' columns from the window
 edge, automatic hscrolling will scroll the window by the amount of columns
 determined by this variable.  If its value is a positive integer, scroll that
@@ -28395,9 +28726,9 @@ To add a prefix to continuation lines, use `wrap-prefix'.  */);
 #endif /* GLYPH_DEBUG */
 
   DEFVAR_INT ("overline-margin", overline_margin,
-              doc: /* *Space between overline and text, in pixels.
+              doc: /* Space between overline and text, in pixels.
 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
-margin to the caracter height.  */);
+margin to the character height.  */);
   overline_margin = 2;
 
   DEFVAR_INT ("underline-minimum-offset",
@@ -28416,7 +28747,7 @@ cursor shapes.  */);
   display_hourglass_p = 1;
 
   DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
-              doc: /* *Seconds to wait before displaying an hourglass pointer when Emacs is busy.  */);
+              doc: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy.  */);
   Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
 
   hourglass_atimer = NULL;
@@ -28512,7 +28843,8 @@ init_xdisp (void)
 
 /* Platform-independent portion of hourglass implementation. */
 
-/* Return non-zero if houglass timer has been started or hourglass is shown.  */
+/* Return non-zero if hourglass timer has been started or hourglass is
+   shown.  */
 int
 hourglass_started (void)
 {