]> code.delx.au - gnu-emacs/blobdiff - src/xdisp.c
Merge from emacs--devo--0
[gnu-emacs] / src / xdisp.c
index fa09c076467f75cf54aacef8f896af70d593a8b4..0e60020f11015e87ea5cb0078e78006581cc88e7 100644 (file)
@@ -177,6 +177,7 @@ Boston, MA 02110-1301, USA.  */
 #include "termchar.h"
 #include "dispextern.h"
 #include "buffer.h"
+#include "character.h"
 #include "charset.h"
 #include "indent.h"
 #include "commands.h"
@@ -201,6 +202,12 @@ Boston, MA 02110-1301, USA.  */
 #include "macterm.h"
 #endif
 
+#ifdef HAVE_WINDOW_SYSTEM
+#ifdef USE_FONT_BACKEND
+#include "font.h"
+#endif /* USE_FONT_BACKEND */
+#endif /* HAVE_WINDOW_SYSTEM */
+
 #ifndef FRAME_X_OUTPUT
 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
 #endif
@@ -269,6 +276,12 @@ int auto_raise_tool_bar_buttons_p;
 
 int make_cursor_line_fully_visible_p;
 
+/* Margin below tool bar in pixels.  0 or nil means no margin.
+   If value is `internal-border-width' or `border-width',
+   the corresponding frame parameter is used.  */
+
+Lisp_Object Vtool_bar_border;
+
 /* Margin around tool bar buttons in pixels.  */
 
 Lisp_Object Vtool_bar_button_margin;
@@ -704,6 +717,10 @@ Lisp_Object Vresize_mini_windows;
 
 struct buffer *displayed_buffer;
 
+/* Space between overline and text. */
+
+EMACS_INT overline_margin;
+
 /* Value returned from text property handlers (see below).  */
 
 enum prop_handled
@@ -736,6 +753,7 @@ static enum prop_handled handle_display_prop P_ ((struct it *));
 static enum prop_handled handle_composition_prop P_ ((struct it *));
 static enum prop_handled handle_overlay_change P_ ((struct it *));
 static enum prop_handled handle_fontified_prop P_ ((struct it *));
+static enum prop_handled handle_auto_composed_prop P_ ((struct it *));
 
 /* Properties handled by iterators.  */
 
@@ -747,6 +765,7 @@ static struct props it_props[] =
   {&Qface,             FACE_PROP_IDX,          handle_face_prop},
   {&Qdisplay,          DISPLAY_PROP_IDX,       handle_display_prop},
   {&Qinvisible,                INVISIBLE_PROP_IDX,     handle_invisible_prop},
+  {&Qauto_composed,    AUTO_COMPOSED_PROP_IDX, handle_auto_composed_prop},
   {&Qcomposition,      COMPOSITION_PROP_IDX,   handle_composition_prop},
   {NULL,               0,                      NULL}
 };
@@ -852,7 +871,7 @@ static void store_mode_line_noprop_char P_ ((char));
 static int store_mode_line_noprop P_ ((const unsigned char *, int, int));
 static void x_consider_frame_title P_ ((Lisp_Object));
 static void handle_stop P_ ((struct it *));
-static int tool_bar_lines_needed P_ ((struct frame *));
+static int tool_bar_lines_needed P_ ((struct frame *, int *));
 static int single_display_spec_intangible_p P_ ((Lisp_Object));
 static void ensure_echo_area_buffers P_ ((void));
 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
@@ -894,7 +913,7 @@ static void redisplay_window P_ ((Lisp_Object, int));
 static Lisp_Object redisplay_window_error ();
 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
-static void update_menu_bar P_ ((struct frame *, int));
+static int update_menu_bar P_ ((struct frame *, int, int));
 static int try_window_reusing_current_matrix P_ ((struct window *));
 static int try_window_id P_ ((struct window *));
 static int display_line P_ ((struct it *));
@@ -910,6 +929,7 @@ static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
 static void compute_line_metrics P_ ((struct it *));
 static void run_redisplay_end_trigger_hook P_ ((struct it *));
 static int get_overlay_strings P_ ((struct it *, int));
+static int get_overlay_strings_1 P_ ((struct it *, int, int));
 static void next_overlay_string P_ ((struct it *));
 static void reseat P_ ((struct it *, struct text_pos, int));
 static void reseat_1 P_ ((struct it *, struct text_pos, int));
@@ -963,7 +983,7 @@ static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
 static void update_tool_bar P_ ((struct frame *, int));
 static void build_desired_tool_bar_string P_ ((struct frame *f));
 static int redisplay_tool_bar P_ ((struct frame *));
-static void display_tool_bar_line P_ ((struct it *));
+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));
@@ -1904,7 +1924,7 @@ get_glyph_string_clip_rects (s, rects, n)
     }
 
   if ((s->for_overlaps & OVERLAPS_BOTH) == 0
-      || (s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1)
+      || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
     {
 #ifdef CONVERT_FROM_XRECT
       CONVERT_FROM_XRECT (r, *rects);
@@ -1930,23 +1950,27 @@ get_glyph_string_clip_rects (s, rects, n)
        {
          rs[i] = r;
          if (r.y + r.height > row_y)
-           if (r.y < row_y)
-             rs[i].height = row_y - r.y;
-           else
-             rs[i].height = 0;
+           {
+             if (r.y < row_y)
+               rs[i].height = row_y - r.y;
+             else
+               rs[i].height = 0;
+           }
          i++;
        }
       if (s->for_overlaps & OVERLAPS_SUCC)
        {
          rs[i] = r;
          if (r.y < row_y + s->row->visible_height)
-           if (r.y + r.height > row_y + s->row->visible_height)
-             {
-               rs[i].y = row_y + s->row->visible_height;
-               rs[i].height = r.y + r.height - rs[i].y;
-             }
-           else
-             rs[i].height = 0;
+           {
+             if (r.y + r.height > row_y + s->row->visible_height)
+               {
+                 rs[i].y = row_y + s->row->visible_height;
+                 rs[i].height = r.y + r.height - rs[i].y;
+               }
+             else
+               rs[i].height = 0;
+           }
          i++;
        }
 
@@ -1976,15 +2000,15 @@ get_glyph_string_clip_rect (s, nr)
    Set w->phys_cursor_width to width of phys cursor.
 */
 
-int
-get_phys_cursor_geometry (w, row, glyph, heightp)
+void
+get_phys_cursor_geometry (w, row, glyph, xp, yp, heightp)
      struct window *w;
      struct glyph_row *row;
      struct glyph *glyph;
-     int *heightp;
+     int *xp, *yp, *heightp;
 {
   struct frame *f = XFRAME (WINDOW_FRAME (w));
-  int y, wd, h, h0, y0;
+  int x, y, wd, h, h0, y0;
 
   /* Compute the width of the rectangle to draw.  If on a stretch
      glyph, and `x-stretch-block-cursor' is nil, don't draw a
@@ -1994,6 +2018,14 @@ get_phys_cursor_geometry (w, row, glyph, heightp)
 #ifdef HAVE_NTGUI
   wd++; /* Why? */
 #endif
+
+  x = w->phys_cursor.x;
+  if (x < 0)
+    {
+      wd += x;
+      x = 0;
+    }
+
   if (glyph->type == STRETCH_GLYPH
       && !x_stretch_cursor_p)
     wd = min (FRAME_COLUMN_WIDTH (f), wd);
@@ -2023,8 +2055,9 @@ get_phys_cursor_geometry (w, row, glyph, heightp)
        }
     }
 
-  *heightp = h - 1;
-  return WINDOW_TO_FRAME_PIXEL_Y (w, y);
+  *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
+  *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
+  *heightp = h;
 }
 
 /*
@@ -2890,8 +2923,8 @@ init_from_display_pos (it, w, pos)
         also ``processed'' overlay strings at ZV.  */
       while (it->sp)
        pop_it (it);
-      it->current.overlay_string_index = -1;
-      it->method = GET_FROM_BUFFER;
+      xassert (it->current.overlay_string_index == -1);
+      xassert (it->method == GET_FROM_BUFFER);
       if (CHARPOS (pos->pos) == ZV)
        it->overlay_strings_at_end_processed_p = 1;
     }
@@ -3002,7 +3035,19 @@ handle_stop (it)
          if (handled == HANDLED_RECOMPUTE_PROPS)
            break;
          else if (handled == HANDLED_RETURN)
-           return;
+           {
+             /* We still want to show before and after strings from
+                overlays even if the actual buffer text is replaced.  */
+             if (!handle_overlay_change_p || it->sp > 1)
+               return;
+             if (!get_overlay_strings_1 (it, 0, 0))
+               return;
+             it->ignore_overlay_strings_at_pos_p = 1;
+             it->string_from_display_prop_p = 0;
+             handle_overlay_change_p = 0;
+             handled = HANDLED_RECOMPUTE_PROPS;
+             break;
+           }
          else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
            handle_overlay_change_p = 0;
        }
@@ -3443,7 +3488,7 @@ face_before_or_after_it_pos (it, before_p)
          struct face *face = FACE_FROM_ID (it->f, face_id);
 
          c = string_char_and_length (p, rest, &len);
-         face_id = FACE_FOR_CHAR (it->f, face, c);
+         face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), it->string);
        }
     }
   else
@@ -3482,7 +3527,7 @@ face_before_or_after_it_pos (it, before_p)
        {
          int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
          struct face *face = FACE_FROM_ID (it->f, face_id);
-         face_id = FACE_FOR_CHAR (it->f, face, c);
+         face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
        }
     }
 
@@ -3614,6 +3659,11 @@ handle_invisible_prop (it)
                 skip starting with next_stop.  */
              if (invis_p)
                IT_CHARPOS (*it) = next_stop;
+
+              /* If there are adjacent invisible texts, don't lose the
+                 second one's ellipsis. */
+              if (invis_p == 2)
+                display_ellipsis_p = 1;
            }
          while (invis_p);
 
@@ -3634,7 +3684,26 @@ handle_invisible_prop (it)
              it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
            }
          else if (display_ellipsis_p)
-           setup_for_ellipsis (it, 0);
+            {
+              /* Make sure that the glyphs of the ellipsis will get
+                 correct `charpos' values.  If we would not update
+                 it->position here, the glyphs would belong to the
+                 last visible character _before_ the invisible
+                 text, which confuses `set_cursor_from_row'.
+
+                 We use the last invisible position instead of the
+                 first because this way the cursor is always drawn on
+                 the first "." of the ellipsis, whenever PT is inside
+                 the invisible text.  Otherwise the cursor would be
+                 placed _after_ the ellipsis when the point is after the
+                 first invisible character.  */
+             if (!STRINGP (it->object))
+               {
+                 it->position.charpos = IT_CHARPOS (*it) - 1;
+                 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
+               }
+              setup_for_ellipsis (it, 0);
+            }
        }
     }
 
@@ -3824,7 +3893,7 @@ handle_single_display_spec (it, spec, object, position,
 {
   Lisp_Object form;
   Lisp_Object location, value;
-  struct text_pos start_pos;
+  struct text_pos start_pos, save_pos;
   int valid_p;
 
   /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
@@ -4033,7 +4102,7 @@ handle_single_display_spec (it, spec, object, position,
        {
          Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
          int face_id2 = lookup_derived_face (it->f, face_name,
-                                             'A', FRINGE_FACE_ID, 0);
+                                             FRINGE_FACE_ID, 0);
          if (face_id2 >= 0)
            face_id = face_id2;
        }
@@ -4041,7 +4110,10 @@ handle_single_display_spec (it, spec, object, position,
       /* Save current settings of IT so that we can restore them
         when we are finished with the glyph property value.  */
 
+      save_pos = it->position;
+      it->position = *position;
       push_it (it);
+      it->position = save_pos;
 
       it->area = TEXT_AREA;
       it->what = IT_IMAGE;
@@ -4115,7 +4187,10 @@ handle_single_display_spec (it, spec, object, position,
     {
       /* Save current settings of IT so that we can restore them
         when we are finished with the glyph property value.  */
+      save_pos = it->position;
+      it->position = *position;
       push_it (it);
+      it->position = save_pos;
 
       if (NILP (location))
        it->area = TEXT_AREA;
@@ -4378,6 +4453,117 @@ string_buffer_position (w, string, around_charpos)
                        `composition' property
  ***********************************************************************/
 
+static enum prop_handled
+handle_auto_composed_prop (it)
+     struct it *it;
+{
+  enum prop_handled handled = HANDLED_NORMALLY;
+
+  if (FUNCTIONP (Vauto_composition_function))
+    {
+      Lisp_Object val;
+      EMACS_INT pos, this_pos;
+
+      if (STRINGP (it->string))
+       pos = IT_STRING_CHARPOS (*it);
+      else
+       pos = IT_CHARPOS (*it);
+      this_pos = pos;
+
+      val =Fget_char_property (make_number (pos), Qauto_composed, it->string);
+      if (! NILP (val))
+       {
+         Lisp_Object limit = Qnil, next;
+         
+         /* As Fnext_single_char_property_change is very slow, we
+            limit the search to the current line.  */
+         if (STRINGP (it->string))
+           limit = make_number (SCHARS (it->string));
+         else
+           limit = make_number (find_next_newline_no_quit (pos, 1));
+
+         next = (Fnext_single_property_change
+                 (make_number (pos), Qauto_composed, it->string, limit));
+         if (XINT (next) < XINT (limit))
+           {
+             /* The current point is auto-composed, but there exist
+                characters not yet composed beyond the auto-composed
+                region.  There's a possiblity that the last
+                characters in the region may be newly composed.  */
+             int charpos = XINT (next) - 1, bytepos, c;
+
+             if (STRINGP (it->string))
+               {
+                 bytepos = string_char_to_byte (it->string, charpos);
+                 c = SDATA (it->string)[bytepos];
+               }
+             else
+               {
+                 bytepos = CHAR_TO_BYTE (charpos);
+                 c = FETCH_BYTE (bytepos);
+               }
+             if (c != '\n')
+               /* If the last character is not newline, it may be
+                  composed with the following characters.  */
+               val = Qnil, pos = charpos + 1;
+           }
+       }
+      if (NILP (val))
+       {
+         int count = SPECPDL_INDEX ();
+         Lisp_Object args[4];
+
+         args[0] = Vauto_composition_function;
+         specbind (Qauto_composition_function, Qnil);
+         args[1] = make_number (pos);
+         args[2] = it->string;
+#ifdef USE_FONT_BACKEND
+         if (enable_font_backend)
+           {
+             struct face *face = FACE_FROM_ID (it->f, it->face_id);
+             int c;
+
+             if (STRINGP (it->string))
+               {
+                 EMACS_INT pos_byte = IT_STRING_BYTEPOS (*it);
+                 const unsigned char *s = SDATA (it->string) + pos_byte;
+
+                 if (STRING_MULTIBYTE (it->string))
+                   it->c = STRING_CHAR (s, 0);
+                 else
+                   it->c = *s;
+               }
+             else
+               {
+                 EMACS_INT pos_byte = IT_BYTEPOS (*it);
+
+                 it->c = FETCH_CHAR (pos_byte);
+               }
+             args[3] = font_at (it->c, this_pos, face, it->w, it->string);
+           }
+         else
+#endif /* USE_FONT_BACKEND */
+           args[3] = Qnil;
+         safe_call (4, args);
+         unbind_to (count, Qnil);
+
+         if (this_pos == pos)
+           {
+             val = Fget_char_property (args[1], Qauto_composed, it->string);
+             /* Return HANDLED_RECOMPUTE_PROPS only if function composed
+                something.  This avoids an endless loop if they failed to
+                fontify the text for which reason ever.  */
+             if (! NILP (val))
+               handled = HANDLED_RECOMPUTE_PROPS;
+           }
+         else
+           handled = HANDLED_RECOMPUTE_PROPS;
+       }
+    }
+
+  return handled;
+}
+
 /* Set up iterator IT from `composition' property at its current
    position.  Called from handle_stop.  */
 
@@ -4386,7 +4572,7 @@ handle_composition_prop (it)
      struct it *it;
 {
   Lisp_Object prop, string;
-  int pos, pos_byte, end;
+  EMACS_INT pos, pos_byte, start, end;
   enum prop_handled handled = HANDLED_NORMALLY;
 
   if (STRINGP (it->string))
@@ -4405,24 +4591,69 @@ handle_composition_prop (it)
   /* If there's a valid composition and point is not inside of the
      composition (in the case that the composition is from the current
      buffer), draw a glyph composed from the composition components.  */
-  if (find_composition (pos, -1, &pos, &end, &prop, string)
-      && COMPOSITION_VALID_P (pos, end, prop)
-      && (STRINGP (it->string) || (PT <= pos || PT >= end)))
+  if (find_composition (pos, -1, &start, &end, &prop, string)
+      && COMPOSITION_VALID_P (start, end, prop)
+      && (STRINGP (it->string) || (PT <= start || PT >= end)))
     {
-      int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
+      int id;
+
+      if (start != pos)
+       {
+         if (STRINGP (it->string))
+           pos_byte = string_char_to_byte (it->string, start);
+         else
+           pos_byte = CHAR_TO_BYTE (start);
+       }
+      id = get_composition_id (start, pos_byte, end - start, prop, string);
 
       if (id >= 0)
        {
+         struct composition *cmp = composition_table[id];
+
+         if (cmp->glyph_len == 0)
+           {
+             /* No glyph.  */
+             if (STRINGP (it->string))
+               {
+                 IT_STRING_CHARPOS (*it) = end;
+                 IT_STRING_BYTEPOS (*it) = string_char_to_byte (it->string,
+                                                                end);
+               }
+             else
+               {
+                 IT_CHARPOS (*it) = end;
+                 IT_BYTEPOS (*it) = CHAR_TO_BYTE (end);
+               }
+             return HANDLED_RECOMPUTE_PROPS;
+           }
+
+         it->stop_charpos = end;
+         push_it (it);
+
          it->method = GET_FROM_COMPOSITION;
          it->cmp_id = id;
          it->cmp_len = COMPOSITION_LENGTH (prop);
+#ifdef USE_FONT_BACKEND
+         if (composition_table[id]->method == COMPOSITION_WITH_GLYPH_STRING)
+           {
+             Lisp_Object lgstring = AREF (XHASH_TABLE (composition_hash_table)
+                                          ->key_and_value,
+                                          cmp->hash_index * 2);
+             Lisp_Object font_object = LGSTRING_FONT (lgstring);
+             struct font *font = XSAVE_VALUE (font_object)->pointer;
+             struct face *face = FACE_FROM_ID (it->f, it->face_id);
+
+             it->face_id = face_for_font (it->f, font, face);
+             it->c = ' ';
+           }
+         else
+#endif /* USE_FONT_BACKEND */
          /* For a terminal, draw only the first character of the
              components.  */
          it->c = COMPOSITION_GLYPH (composition_table[id], 0);
          it->len = (STRINGP (it->string)
                     ? string_char_to_byte (it->string, end)
                     : CHAR_TO_BYTE (end)) - pos_byte;
-         it->stop_charpos = end;
          handled = HANDLED_RETURN;
        }
     }
@@ -4482,13 +4713,14 @@ next_overlay_string (it)
       int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
 
       pop_it (it);
-      xassert (it->stop_charpos >= BEGV
-              && it->stop_charpos <= it->end_charpos);
-      it->string = Qnil;
+      xassert (it->sp > 0
+              || it->method == GET_FROM_COMPOSITION
+              || (NILP (it->string)
+                  && it->method == GET_FROM_BUFFER
+                  && it->stop_charpos >= BEGV
+                  && it->stop_charpos <= it->end_charpos));
       it->current.overlay_string_index = -1;
-      SET_TEXT_POS (it->current.string_pos, -1, -1);
       it->n_overlay_strings = 0;
-      it->method = GET_FROM_BUFFER;
 
       /* If we're at the end of the buffer, record that we have
         processed the overlay strings there already, so that
@@ -4744,7 +4976,7 @@ load_overlay_strings (it, charpos)
    least one overlay string was found.  */
 
 static int
-get_overlay_strings (it, charpos)
+get_overlay_strings_1 (it, charpos, compute_stop_p)
      struct it *it;
      int charpos;
 {
@@ -4766,12 +4998,13 @@ get_overlay_strings (it, charpos)
       /* Make sure we know settings in current_buffer, so that we can
         restore meaningful values when we're done with the overlay
         strings.  */
-      compute_stop_pos (it);
+      if (compute_stop_p)
+       compute_stop_pos (it);
       xassert (it->face_id >= 0);
 
       /* Save IT's settings.  They are restored after all overlay
         strings have been processed.  */
-      xassert (it->sp == 0);
+      xassert (!compute_stop_p || it->sp == 0);
       push_it (it);
 
       /* Set up IT to deliver display elements from the first overlay
@@ -4783,13 +5016,22 @@ get_overlay_strings (it, charpos)
       it->end_charpos = SCHARS (it->string);
       it->multibyte_p = STRING_MULTIBYTE (it->string);
       it->method = GET_FROM_STRING;
+      return 1;
     }
-  else
-    {
-      it->string = Qnil;
-      it->current.overlay_string_index = -1;
-      it->method = GET_FROM_BUFFER;
-    }
+
+  it->current.overlay_string_index = -1;
+  return 0;
+}
+
+static int
+get_overlay_strings (it, charpos)
+     struct it *it;
+     int charpos;
+{
+  it->string = Qnil;
+  it->method = GET_FROM_BUFFER;
+
+  (void) get_overlay_strings_1 (it, charpos, 1);
 
   CHECK_IT (it);
 
@@ -4814,19 +5056,38 @@ push_it (it)
 {
   struct iterator_stack_entry *p;
 
-  xassert (it->sp < 2);
+  xassert (it->sp < IT_STACK_SIZE);
   p = it->stack + it->sp;
 
   p->stop_charpos = it->stop_charpos;
   xassert (it->face_id >= 0);
   p->face_id = it->face_id;
   p->string = it->string;
-  p->pos = it->current;
+  p->method = it->method;
+  switch (p->method)
+    {
+    case GET_FROM_IMAGE:
+      p->u.image.object = it->object;
+      p->u.image.image_id = it->image_id;
+      p->u.image.slice = it->slice;
+      break;
+    case GET_FROM_COMPOSITION:
+      p->u.comp.object = it->object;
+      p->u.comp.c = it->c;
+      p->u.comp.len = it->len;
+      p->u.comp.cmp_id = it->cmp_id;
+      p->u.comp.cmp_len = it->cmp_len;
+      break;
+    case GET_FROM_STRETCH:
+      p->u.stretch.object = it->object;
+      break;
+    }
+  p->position = it->position;
+  p->current = it->current;
   p->end_charpos = it->end_charpos;
   p->string_nchars = it->string_nchars;
   p->area = it->area;
   p->multibyte_p = it->multibyte_p;
-  p->slice = it->slice;
   p->space_width = it->space_width;
   p->font_height = it->font_height;
   p->voffset = it->voffset;
@@ -4853,13 +5114,40 @@ pop_it (it)
   p = it->stack + it->sp;
   it->stop_charpos = p->stop_charpos;
   it->face_id = p->face_id;
+  it->current = p->current;
+  it->position = p->position;
   it->string = p->string;
-  it->current = p->pos;
+  if (NILP (it->string))
+    SET_TEXT_POS (it->current.string_pos, -1, -1);
+  it->method = p->method;
+  switch (it->method)
+    {
+    case GET_FROM_IMAGE:
+      it->image_id = p->u.image.image_id;
+      it->object = p->u.image.object;
+      it->slice = p->u.image.slice;
+      break;
+    case GET_FROM_COMPOSITION:
+      it->object = p->u.comp.object;
+      it->c = p->u.comp.c;
+      it->len = p->u.comp.len;
+      it->cmp_id = p->u.comp.cmp_id;
+      it->cmp_len = p->u.comp.cmp_len;
+      break;
+    case GET_FROM_STRETCH:
+      it->object = p->u.comp.object;
+      break;
+    case GET_FROM_BUFFER:
+      it->object = it->w->buffer;
+      break;
+    case GET_FROM_STRING:
+      it->object = it->string;
+      break;
+    }
   it->end_charpos = p->end_charpos;
   it->string_nchars = p->string_nchars;
   it->area = p->area;
   it->multibyte_p = p->multibyte_p;
-  it->slice = p->slice;
   it->space_width = p->space_width;
   it->font_height = p->font_height;
   it->voffset = p->voffset;
@@ -4991,6 +5279,7 @@ back_to_previous_visible_line_start (it)
   while (IT_CHARPOS (*it) > BEGV)
     {
       back_to_previous_line_start (it);
+
       if (IT_CHARPOS (*it) <= BEGV)
        break;
 
@@ -5010,37 +5299,47 @@ back_to_previous_visible_line_start (it)
          continue;
       }
 
-      /* If newline has a display property that replaces the newline with something
-        else (image or text), find start of overlay or interval and continue search
-        from that point.  */
-      if (IT_CHARPOS (*it) > BEGV)
-       {
-         struct it it2 = *it;
-         int pos;
-         int beg, end;
-         Lisp_Object val, overlay;
-
-         pos = --IT_CHARPOS (it2);
-         --IT_BYTEPOS (it2);
-         it2.sp = 0;
-         if (handle_display_prop (&it2) == HANDLED_RETURN
-             && !NILP (val = get_char_property_and_overlay
-                       (make_number (pos), Qdisplay, Qnil, &overlay))
-             && (OVERLAYP (overlay)
-                 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
-                 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
-           {
-             if (beg < BEGV)
-               beg = BEGV;
-             IT_CHARPOS (*it) = beg;
-             IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
-             continue;
-           }
-       }
+      if (IT_CHARPOS (*it) <= BEGV)
+       break;
 
-      break;
+      {
+       struct it it2;
+       int pos;
+       int beg, end;
+       Lisp_Object val, overlay;
+
+       /* If newline is part of a composition, continue from start of composition */
+       if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
+           && beg < IT_CHARPOS (*it))
+         goto replaced;
+
+       /* If newline is replaced by a display property, find start of overlay
+          or interval and continue search from that point.  */
+       it2 = *it;
+       pos = --IT_CHARPOS (it2);
+       --IT_BYTEPOS (it2);
+       it2.sp = 0;
+       if (handle_display_prop (&it2) == HANDLED_RETURN
+           && !NILP (val = get_char_property_and_overlay
+                     (make_number (pos), Qdisplay, Qnil, &overlay))
+           && (OVERLAYP (overlay)
+               ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
+               : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
+         goto replaced;
+
+       /* Newline is not replaced by anything -- so we are done.  */
+       break;
+
+      replaced:
+       if (beg < BEGV)
+         beg = BEGV;
+       IT_CHARPOS (*it) = beg;
+       IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
+      }
     }
 
+  it->continuation_lines_width = 0;
+
   xassert (IT_CHARPOS (*it) >= BEGV);
   xassert (IT_CHARPOS (*it) == BEGV
           || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
@@ -5163,7 +5462,6 @@ reseat_1 (it, pos, set_stop_p)
   xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
 
   it->current.pos = it->position = pos;
-  XSETBUFFER (it->object, current_buffer);
   it->end_charpos = ZV;
   it->dpvec = NULL;
   it->current.dpvec_index = -1;
@@ -5172,15 +5470,11 @@ reseat_1 (it, pos, set_stop_p)
   IT_STRING_BYTEPOS (*it) = -1;
   it->string = Qnil;
   it->method = GET_FROM_BUFFER;
-  /* RMS: I added this to fix a bug in move_it_vertically_backward
-     where it->area continued to relate to the starting point
-     for the backward motion.  Bug report from
-     Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
-     However, I am not sure whether reseat still does the right thing
-     in general after this change.  */
+  it->object = it->w->buffer;
   it->area = TEXT_AREA;
   it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
   it->sp = 0;
+  it->string_from_display_prop_p = 0;
   it->face_before_selective_p = 0;
 
   if (set_stop_p)
@@ -5308,6 +5602,10 @@ static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) =
    display element from the current position of IT.  Value is zero if
    end of buffer (or C string) is reached.  */
 
+static struct frame *last_escape_glyph_frame = NULL;
+static unsigned last_escape_glyph_face_id = (1 << FACE_ID_BITS);
+static int last_escape_glyph_merged_face_id = 0;
+
 int
 get_next_display_element (it)
      struct it *it;
@@ -5369,31 +5667,26 @@ get_next_display_element (it)
             the translation.  This could easily be changed but I
             don't believe that it is worth doing.
 
-            If it->multibyte_p is nonzero, eight-bit characters and
-            non-printable multibyte characters are also translated to
-            octal form.
+            If it->multibyte_p is nonzero, non-printable non-ASCII
+            characters are also translated to octal form.
 
             If it->multibyte_p is zero, eight-bit characters that
             don't have corresponding multibyte char code are also
             translated to octal form.  */
          else if ((it->c < ' '
-                   && (it->area != TEXT_AREA
-                       /* In mode line, treat \n like other crl chars.  */
-                       || (it->c != '\t'
-                           && it->glyph_row && it->glyph_row->mode_line_p)
-                       || (it->c != '\n' && it->c != '\t')))
-                  || (it->multibyte_p
-                      ? ((it->c >= 127
-                          && it->len == 1)
-                         || !CHAR_PRINTABLE_P (it->c)
+                   ? (it->area != TEXT_AREA
+                      /* In mode line, treat \n, \t like other crl chars.  */
+                      || (it->c != '\t'
+                          && it->glyph_row && it->glyph_row->mode_line_p)
+                      || (it->c != '\n' && it->c != '\t'))
+                   : (it->multibyte_p
+                      ? (!CHAR_PRINTABLE_P (it->c)
                          || (!NILP (Vnobreak_char_display)
-                             && (it->c == 0x8a0 || it->c == 0x8ad
-                                 || it->c == 0x920 || it->c == 0x92d
-                                 || it->c == 0xe20 || it->c == 0xe2d
-                                 || it->c == 0xf20 || it->c == 0xf2d)))
+                             && (it->c == 0xA0 /* NO-BREAK SPACE */
+                                 || it->c == 0xAD /* SOFT HYPHEN */)))
                       : (it->c >= 127
-                         && (!unibyte_display_via_language_environment
-                             || it->c == unibyte_char_to_multibyte (it->c)))))
+                         && (! unibyte_display_via_language_environment
+                             || (UNIBYTE_CHAR_HAS_MULTIBYTE_P (it->c)))))))
            {
              /* IT->c is a control character which must be displayed
                 either as '\003' or as `^C' where the '\\' and '^'
@@ -5424,11 +5717,19 @@ get_next_display_element (it)
                       face_id = merge_faces (it->f, Qt, lface_id,
                                              it->face_id);
                    }
+                 else if (it->f == last_escape_glyph_frame
+                          && it->face_id == last_escape_glyph_face_id)
+                   {
+                     face_id = last_escape_glyph_merged_face_id;
+                   }
                  else
                    {
                      /* Merge the escape-glyph face into the current face.  */
                      face_id = merge_faces (it->f, Qescape_glyph, 0,
                                             it->face_id);
+                     last_escape_glyph_frame = it->f;
+                     last_escape_glyph_face_id = it->face_id;
+                     last_escape_glyph_merged_face_id = face_id;
                    }
 
                  XSETINT (it->ctl_chars[0], g);
@@ -5442,8 +5743,7 @@ get_next_display_element (it)
                 highlighting.  */
 
              if (EQ (Vnobreak_char_display, Qt)
-                 && (it->c == 0x8a0 || it->c == 0x920
-                     || it->c == 0xe20 || it->c == 0xf20))
+                 && it->c == 0xA0)
                {
                  /* Merge the no-break-space face into the current face.  */
                  face_id = merge_faces (it->f, Qnobreak_space, 0,
@@ -5475,19 +5775,26 @@ get_next_display_element (it)
                  face_id = merge_faces (it->f, Qt, lface_id,
                                         it->face_id);
                }
+             else if (it->f == last_escape_glyph_frame
+                      && it->face_id == last_escape_glyph_face_id)
+               {
+                 face_id = last_escape_glyph_merged_face_id;
+               }
              else
                {
                  /* Merge the escape-glyph face into the current face.  */
                  face_id = merge_faces (it->f, Qescape_glyph, 0,
                                         it->face_id);
+                 last_escape_glyph_frame = it->f;
+                 last_escape_glyph_face_id = it->face_id;
+                 last_escape_glyph_merged_face_id = face_id;
                }
 
              /* Handle soft hyphens in the mode where they only get
                 highlighting.  */
 
              if (EQ (Vnobreak_char_display, Qt)
-                 && (it->c == 0x8ad || it->c == 0x92d
-                     || it->c == 0xe2d || it->c == 0xf2d))
+                 && it->c == 0xAD)
                {
                  g = it->c = '-';
                  XSETINT (it->ctl_chars[0], g);
@@ -5498,13 +5805,10 @@ get_next_display_element (it)
              /* Handle non-break space and soft hyphen
                 with the escape glyph.  */
 
-             if (it->c == 0x8a0 || it->c == 0x8ad
-                 || it->c == 0x920 || it->c == 0x92d
-                 || it->c == 0xe20 || it->c == 0xe2d
-                 || it->c == 0xf20 || it->c == 0xf2d)
+             if (it->c == 0xA0 || it->c == 0xAD)
                {
                  XSETINT (it->ctl_chars[0], escape_glyph);
-                 g = it->c = ((it->c & 0xf) == 0 ? ' ' : '-');
+                 g = it->c = (it->c == 0xA0 ? ' ' : '-');
                  XSETINT (it->ctl_chars[1], g);
                  ctl_len = 2;
                  goto display_control;
@@ -5516,23 +5820,27 @@ get_next_display_element (it)
                int i;
 
                /* Set IT->ctl_chars[0] to the glyph for `\\'.  */
-               if (SINGLE_BYTE_CHAR_P (it->c))
-                 str[0] = it->c, len = 1;
+               if (CHAR_BYTE8_P (it->c))
+                 {
+                   str[0] = CHAR_TO_BYTE8 (it->c);
+                   len = 1;
+                 }
+               else if (it->c < 256)
+                 {
+                   str[0] = it->c;
+                   len = 1;
+                 }
                else
                  {
-                   len = CHAR_STRING_NO_SIGNAL (it->c, str);
-                   if (len < 0)
-                     {
-                       /* It's an invalid character, which shouldn't
-                          happen actually, but due to bugs it may
-                          happen.  Let's print the char as is, there's
-                          not much meaningful we can do with it.  */
-                         str[0] = it->c;
-                         str[1] = it->c >> 8;
-                         str[2] = it->c >> 16;
-                         str[3] = it->c >> 24;
-                         len = 4;
-                       }
+                   /* It's an invalid character, which shouldn't
+                      happen actually, but due to bugs it may
+                      happen.  Let's print the char as is, there's
+                      not much meaningful we can do with it.  */
+                     str[0] = it->c;
+                     str[1] = it->c >> 8;
+                     str[2] = it->c >> 16;
+                     str[3] = it->c >> 24;
+                     len = 4;
                    }
 
                for (i = 0; i < len; i++)
@@ -5571,7 +5879,11 @@ get_next_display_element (it)
          && FRAME_WINDOW_P (it->f))
        {
          struct face *face = FACE_FROM_ID (it->f, it->face_id);
-         it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
+         int pos = (it->s ? -1
+                    : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
+                    : IT_CHARPOS (*it));
+         
+         it->face_id = FACE_FOR_CHAR (it->f, face, it->c, pos, it->string);
        }
     }
 
@@ -5639,18 +5951,18 @@ set_iterator_to_next (it, reseat_p)
 
     case GET_FROM_COMPOSITION:
       xassert (it->cmp_id >= 0 && it->cmp_id < n_compositions);
-      if (STRINGP (it->string))
+      xassert (it->sp > 0);
+      pop_it (it);
+      if (it->method == GET_FROM_STRING)
        {
          IT_STRING_BYTEPOS (*it) += it->len;
          IT_STRING_CHARPOS (*it) += it->cmp_len;
-         it->method = GET_FROM_STRING;
          goto consider_string_end;
        }
-      else
+      else if (it->method == GET_FROM_BUFFER)
        {
          IT_BYTEPOS (*it) += it->len;
          IT_CHARPOS (*it) += it->cmp_len;
-         it->method = GET_FROM_BUFFER;
        }
       break;
 
@@ -5673,12 +5985,17 @@ set_iterator_to_next (it, reseat_p)
 
       if (it->dpvec + it->current.dpvec_index == it->dpend)
        {
+         int recheck_faces = it->ellipsis_p;
+
          if (it->s)
            it->method = GET_FROM_C_STRING;
          else if (STRINGP (it->string))
            it->method = GET_FROM_STRING;
          else
-           it->method = GET_FROM_BUFFER;
+           {
+             it->method = GET_FROM_BUFFER;
+             it->object = it->w->buffer;
+           }
 
          it->dpvec = NULL;
          it->current.dpvec_index = -1;
@@ -5695,8 +6012,9 @@ set_iterator_to_next (it, reseat_p)
              set_iterator_to_next (it, reseat_p);
            }
 
-         /* Recheck faces after display vector */
-         it->stop_charpos = IT_CHARPOS (*it);
+         /* Maybe recheck faces after display vector */
+         if (recheck_faces)
+           it->stop_charpos = IT_CHARPOS (*it);
        }
       break;
 
@@ -5725,9 +6043,8 @@ set_iterator_to_next (it, reseat_p)
              && it->sp > 0)
            {
              pop_it (it);
-             if (STRINGP (it->string))
+             if (it->method == GET_FROM_STRING)
                goto consider_string_end;
-             it->method = GET_FROM_BUFFER;
            }
        }
       break;
@@ -5739,13 +6056,8 @@ set_iterator_to_next (it, reseat_p)
          if the `display' property takes up the whole string.  */
       xassert (it->sp > 0);
       pop_it (it);
-      it->image_id = 0;
-      if (STRINGP (it->string))
-       {
-         it->method = GET_FROM_STRING;
-         goto consider_string_end;
-       }
-      it->method = GET_FROM_BUFFER;
+      if (it->method == GET_FROM_STRING)
+       goto consider_string_end;
       break;
 
     default:
@@ -5890,9 +6202,7 @@ next_element_from_string (it)
        }
     }
 
-  /* Record what we have and where it came from.  Note that we store a
-     buffer position in IT->position although it could arguably be a
-     string position.  */
+  /* Record what we have and where it came from.  */
   it->what = IT_CHARACTER;
   it->object = it->string;
   it->position = position;
@@ -5968,6 +6278,7 @@ next_element_from_ellipsis (it)
         setting face_before_selective_p.  */
       it->saved_face_id = it->face_id;
       it->method = GET_FROM_BUFFER;
+      it->object = it->w->buffer;
       reseat_at_next_visible_line_start (it, 1);
       it->face_before_selective_p = 1;
     }
@@ -6154,6 +6465,10 @@ next_element_from_composition (it)
   it->position = (STRINGP (it->string)
                  ? it->current.string_pos
                  : it->current.pos);
+  if (STRINGP (it->string))
+    it->object = it->string;
+  else
+    it->object = it->w->buffer;
   return 1;
 }
 
@@ -6571,6 +6886,16 @@ move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
             the line.  */
          if (skip == MOVE_X_REACHED)
            {
+             /* Wait!  We can conclude that TO_Y is in the line if
+                the already scanned glyphs make the line tall enough
+                because further scanning doesn't make it shorter.  */
+             line_height = it->max_ascent + it->max_descent;
+             if (to_y >= it->current_y
+                 && to_y < it->current_y + line_height)
+               {
+                 reached = 6;
+                 break;
+               }
              it_backup = *it;
              TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
              skip2 = move_it_in_display_line_to (it, to_charpos, -1,
@@ -6602,6 +6927,10 @@ move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
          if (reached)
            break;
        }
+      else if (BUFFERP (it->object)
+              && it->method == GET_FROM_BUFFER
+              && IT_CHARPOS (*it) >= to_charpos)
+       skip = MOVE_POS_MATCH_OR_ZV;
       else
        skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
 
@@ -7094,7 +7423,7 @@ message_dolog (m, nbytes, nlflag, multibyte)
          for (i = 0; i < nbytes; i += char_bytes)
            {
              c = string_char_and_length (m + i, nbytes - i, &char_bytes);
-             work[0] = (SINGLE_BYTE_CHAR_P (c)
+             work[0] = (ASCII_CHAR_P (c)
                         ? c
                         : multibyte_char_to_unibyte (c, Qnil));
              insert_1_both (work, 1, 1, 1, 0, 0);
@@ -7110,7 +7439,8 @@ message_dolog (m, nbytes, nlflag, multibyte)
             for the *Message* buffer.  */
          for (i = 0; i < nbytes; i++)
            {
-             c = unibyte_char_to_multibyte (msg[i]);
+             c = msg[i];
+             c = unibyte_char_to_multibyte (c);
              char_bytes = CHAR_STRING (c, str);
              insert_1_both (str, 1, char_bytes, 1, 0, 0);
            }
@@ -8381,7 +8711,7 @@ set_message_1 (a1, a2, nbytes, multibyte_p)
          for (i = 0; i < nbytes; i += n)
            {
              c = string_char_and_length (s + i, nbytes - i, &n);
-             work[0] = (SINGLE_BYTE_CHAR_P (c)
+             work[0] = (ASCII_CHAR_P (c)
                         ? c
                         : multibyte_char_to_unibyte (c, Qnil));
              insert_1_both (work, 1, 1, 1, 0, 0);
@@ -8398,7 +8728,8 @@ set_message_1 (a1, a2, nbytes, multibyte_p)
          /* Convert a single-byte string to multibyte.  */
          for (i = 0; i < nbytes; i++)
            {
-             c = unibyte_char_to_multibyte (msg[i]);
+             c = msg[i];
+             c = unibyte_char_to_multibyte (c);
              n = CHAR_STRING (c, str);
              insert_1_both (str, 1, n, 1, 0, 0);
            }
@@ -8863,6 +9194,9 @@ prepare_menu_bars ()
     {
       Lisp_Object tail, frame;
       int count = SPECPDL_INDEX ();
+      /* 1 means that update_menu_bar has run its hooks
+        so any further calls to update_menu_bar shouldn't do so again.  */
+      int menu_bar_hooks_run = 0;
 
       record_unwind_save_match_data ();
 
@@ -8894,9 +9228,12 @@ prepare_menu_bars ()
            }
 
          GCPRO1 (tail);
-         update_menu_bar (f, 0);
+         menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
 #ifdef HAVE_WINDOW_SYSTEM
          update_tool_bar (f, 0);
+#ifdef MAC_OS
+         mac_update_title_bar (f, 0);
+#endif
 #endif
          UNGCPRO;
        }
@@ -8906,9 +9243,12 @@ prepare_menu_bars ()
   else
     {
       struct frame *sf = SELECTED_FRAME ();
-      update_menu_bar (sf, 1);
+      update_menu_bar (sf, 1, 0);
 #ifdef HAVE_WINDOW_SYSTEM
       update_tool_bar (sf, 1);
+#ifdef MAC_OS
+      mac_update_title_bar (sf, 1);
+#endif
 #endif
     }
 
@@ -8924,12 +9264,18 @@ prepare_menu_bars ()
    before we start to fill in any display lines, because it can call
    eval.
 
-   If SAVE_MATCH_DATA is non-zero, we must save and restore it here.  */
+   If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
 
-static void
-update_menu_bar (f, save_match_data)
+   If HOOKS_RUN is 1, that means a previous call to update_menu_bar
+   already ran the menu bar hooks for this redisplay, so there
+   is no need to run them again.  The return value is the
+   updated value of this flag, to pass to the next call.  */
+
+static int
+update_menu_bar (f, save_match_data, hooks_run)
      struct frame *f;
      int save_match_data;
+     int hooks_run;
 {
   Lisp_Object window;
   register struct window *w;
@@ -8994,28 +9340,35 @@ update_menu_bar (f, save_match_data)
              specbind (Qoverriding_local_map, Qnil);
            }
 
-         /* Run the Lucid hook.  */
-         safe_run_hooks (Qactivate_menubar_hook);
+         if (!hooks_run)
+           {
+             /* Run the Lucid hook.  */
+             safe_run_hooks (Qactivate_menubar_hook);
+
+             /* If it has changed current-menubar from previous value,
+                really recompute the menu-bar from the value.  */
+             if (! NILP (Vlucid_menu_bar_dirty_flag))
+               call0 (Qrecompute_lucid_menubar);
 
-         /* If it has changed current-menubar from previous value,
-            really recompute the menu-bar from the value.  */
-         if (! NILP (Vlucid_menu_bar_dirty_flag))
-           call0 (Qrecompute_lucid_menubar);
+             safe_run_hooks (Qmenu_bar_update_hook);
+
+             hooks_run = 1;
+           }
 
-         safe_run_hooks (Qmenu_bar_update_hook);
          FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
 
          /* Redisplay the menu bar in case we changed it.  */
 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
     || defined (USE_GTK)
-         if (FRAME_WINDOW_P (f)
-#if defined (MAC_OS)
-              /* All frames on Mac OS share the same menubar.  So only the
-                 selected frame should be allowed to set it.  */
-              && f == SELECTED_FRAME ()
+         if (FRAME_WINDOW_P (f))
+           {
+#ifdef MAC_OS
+              /* All frames on Mac OS share the same menubar.  So only
+                 the selected frame should be allowed to set it.  */
+              if (f == SELECTED_FRAME ())
 #endif
-            )
-           set_frame_menubar (f, 0, 0);
+               set_frame_menubar (f, 0, 0);
+           }
          else
            /* On a terminal screen, the menu bar is an ordinary screen
               line, and this makes it get updated.  */
@@ -9030,6 +9383,8 @@ update_menu_bar (f, save_match_data)
          set_buffer_internal_1 (prev);
        }
     }
+
+  return hooks_run;
 }
 
 
@@ -9194,7 +9549,8 @@ update_tool_bar (f, save_match_data)
                                          &new_n_tool_bar);
 
          /* Redisplay the tool-bar if we changed it.  */
-         if (NILP (Fequal (new_tool_bar, f->tool_bar_items)))
+         if (new_n_tool_bar != f->n_tool_bar_items
+             || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
             {
               /* Redisplay that happens asynchronously due to an expose event
                  may access f->tool_bar_items.  Make sure we update both
@@ -9379,11 +9735,22 @@ build_desired_tool_bar_string (f)
 }
 
 
-/* Display one line of the tool-bar of frame IT->f.  */
+/* Display one line of the tool-bar of frame IT->f.
+
+   HEIGHT specifies the desired height of the tool-bar line.
+   If the actual height of the glyph row is less than HEIGHT, the
+   row's height is increased to HEIGHT, and the icons are centered
+   vertically in the new height.
+
+   If HEIGHT is -1, we are counting needed tool-bar lines, so don't
+   count a final empty row in case the tool-bar width exactly matches
+   the window width.
+*/
 
 static void
-display_tool_bar_line (it)
+display_tool_bar_line (it, height)
      struct it *it;
+     int height;
 {
   struct glyph_row *row = it->glyph_row;
   int max_x = it->last_visible_x;
@@ -9398,29 +9765,42 @@ display_tool_bar_line (it)
 
   while (it->current_x < max_x)
     {
-      int x_before, x, n_glyphs_before, i, nglyphs;
+      int x, n_glyphs_before, i, nglyphs;
+      struct it it_before;
 
       /* Get the next display element.  */
       if (!get_next_display_element (it))
-       break;
+       {
+         /* Don't count empty row if we are counting needed tool-bar lines.  */
+         if (height < 0 && !it->hpos)
+           return;
+         break;
+       }
 
       /* Produce glyphs.  */
-      x_before = it->current_x;
-      n_glyphs_before = it->glyph_row->used[TEXT_AREA];
+      n_glyphs_before = row->used[TEXT_AREA];
+      it_before = *it;
+
       PRODUCE_GLYPHS (it);
 
-      nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
+      nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
       i = 0;
-      x = x_before;
+      x = it_before.current_x;
       while (i < nglyphs)
        {
          struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
 
          if (x + glyph->pixel_width > max_x)
            {
-             /* Glyph doesn't fit on line.  */
-             it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
-             it->current_x = x;
+             /* Glyph doesn't fit on line.  Backtrack.  */
+             row->used[TEXT_AREA] = n_glyphs_before;
+             *it = it_before;
+             /* If this is the only glyph on this line, it will never fit on the
+                toolbar, so skip it.   But ensure there is at least one glyph,
+                so we don't accidentally disable the tool-bar.  */
+             if (n_glyphs_before == 0
+                 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
+               break;
              goto out;
            }
 
@@ -9439,11 +9819,24 @@ display_tool_bar_line (it)
  out:;
 
   row->displays_text_p = row->used[TEXT_AREA] != 0;
+  /* Use default face for the border below the tool bar.  */
+  if (!row->displays_text_p)
+    it->face_id = DEFAULT_FACE_ID;
   extend_face_to_end_of_line (it);
   last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
   last->right_box_line_p = 1;
   if (last == row->glyphs[TEXT_AREA])
     last->left_box_line_p = 1;
+
+  /* Make line the desired height and center it vertically.  */
+  if ((height -= it->max_ascent + it->max_descent) > 0)
+    {
+      /* Don't add more than one line height.  */
+      height %= FRAME_LINE_HEIGHT (it->f);
+      it->max_ascent += height / 2;
+      it->max_descent += (height + 1) / 2;
+    }
+
   compute_line_metrics (it);
 
   /* If line is empty, make it occupy the rest of the tool-bar.  */
@@ -9466,29 +9859,45 @@ display_tool_bar_line (it)
 }
 
 
+/* Max tool-bar height.  */
+
+#define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
+  ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
+
 /* Value is the number of screen lines needed to make all tool-bar
-   items of frame F visible.  */
+   items of frame F visible.  The number of actual rows needed is
+   returned in *N_ROWS if non-NULL.  */
 
 static int
-tool_bar_lines_needed (f)
+tool_bar_lines_needed (f, n_rows)
      struct frame *f;
+     int *n_rows;
 {
   struct window *w = XWINDOW (f->tool_bar_window);
   struct it it;
+  /* tool_bar_lines_needed is called from redisplay_tool_bar after building
+     the desired matrix, so use (unused) mode-line row as temporary row to
+     avoid destroying the first tool-bar row.  */
+  struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
 
   /* Initialize an iterator for iteration over
      F->desired_tool_bar_string in the tool-bar window of frame F.  */
-  init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
+  init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
   it.first_visible_x = 0;
   it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
   reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
 
   while (!ITERATOR_AT_END_P (&it))
     {
-      it.glyph_row = w->desired_matrix->rows;
-      clear_glyph_row (it.glyph_row);
-      display_tool_bar_line (&it);
+      clear_glyph_row (temp_row);
+      it.glyph_row = temp_row;
+      display_tool_bar_line (&it, -1);
     }
+  clear_glyph_row (temp_row);
+
+  /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar.  */
+  if (n_rows)
+    *n_rows = it.vpos > 0 ? it.vpos : -1;
 
   return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
 }
@@ -9518,7 +9927,7 @@ DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
       if (f->n_tool_bar_items)
        {
          build_desired_tool_bar_string (f);
-         nlines = tool_bar_lines_needed (f);
+         nlines = tool_bar_lines_needed (f, NULL);
        }
     }
 
@@ -9563,9 +9972,68 @@ redisplay_tool_bar (f)
   build_desired_tool_bar_string (f);
   reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
 
+  if (f->n_tool_bar_rows == 0)
+    {
+      int nlines;
+
+      if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
+          nlines != WINDOW_TOTAL_LINES (w)))
+       {
+         extern Lisp_Object Qtool_bar_lines;
+         Lisp_Object frame;
+         int old_height = WINDOW_TOTAL_LINES (w);
+
+         XSETFRAME (frame, f);
+         Fmodify_frame_parameters (frame,
+                                   Fcons (Fcons (Qtool_bar_lines,
+                                                 make_number (nlines)),
+                                          Qnil));
+         if (WINDOW_TOTAL_LINES (w) != old_height)
+           {
+             clear_glyph_matrix (w->desired_matrix);
+             fonts_changed_p = 1;
+             return 1;
+           }
+       }
+    }
+
   /* Display as many lines as needed to display all tool-bar items.  */
-  while (it.current_y < it.last_visible_y)
-    display_tool_bar_line (&it);
+
+  if (f->n_tool_bar_rows > 0)
+    {
+      int border, rows, height, extra;
+
+      if (INTEGERP (Vtool_bar_border))
+       border = XINT (Vtool_bar_border);
+      else if (EQ (Vtool_bar_border, Qinternal_border_width))
+       border = FRAME_INTERNAL_BORDER_WIDTH (f);
+      else if (EQ (Vtool_bar_border, Qborder_width))
+       border = f->border_width;
+      else
+       border = 0;
+      if (border < 0)
+       border = 0;
+
+      rows = f->n_tool_bar_rows;
+      height = max (1, (it.last_visible_y - border) / rows);
+      extra = it.last_visible_y - border - height * rows;
+
+      while (it.current_y < it.last_visible_y)
+       {
+         int h = 0;
+         if (extra > 0 && rows-- > 0)
+           {
+             h = (extra + rows - 1) / rows;
+             extra -= h;
+           }
+         display_tool_bar_line (&it, height + h);
+       }
+    }
+  else
+    {
+      while (it.current_y < it.last_visible_y)
+       display_tool_bar_line (&it, 0);
+    }
 
   /* It doesn't make much sense to try scrolling in the tool-bar
      window, so don't do it.  */
@@ -9574,17 +10042,20 @@ redisplay_tool_bar (f)
 
   if (auto_resize_tool_bars_p)
     {
-      int nlines;
+      int nlines, nrows;
+      int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
 
       /* If we couldn't display everything, change the tool-bar's
-        height.  */
-      if (IT_STRING_CHARPOS (it) < it.end_charpos)
+        height if there is room for more.  */
+      if (IT_STRING_CHARPOS (it) < it.end_charpos
+         && it.current_y < max_tool_bar_height)
        change_height_p = 1;
 
+      row = it.glyph_row - 1;
+
       /* If there are blank lines at the end, except for a partially
         visible blank line at the end that is smaller than
         FRAME_LINE_HEIGHT, change the tool-bar's height.  */
-      row = it.glyph_row - 1;
       if (!row->displays_text_p
          && row->height >= FRAME_LINE_HEIGHT (f))
        change_height_p = 1;
@@ -9592,13 +10063,14 @@ redisplay_tool_bar (f)
       /* If row displays tool-bar items, but is partially visible,
         change the tool-bar's height.  */
       if (row->displays_text_p
-         && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
+         && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
+         && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
        change_height_p = 1;
 
       /* Resize windows as needed by changing the `tool-bar-lines'
         frame parameter.  */
       if (change_height_p
-         && (nlines = tool_bar_lines_needed (f),
+         && (nlines = tool_bar_lines_needed (f, &nrows),
              nlines != WINDOW_TOTAL_LINES (w)))
        {
          extern Lisp_Object Qtool_bar_lines;
@@ -9606,13 +10078,16 @@ redisplay_tool_bar (f)
          int old_height = WINDOW_TOTAL_LINES (w);
 
          XSETFRAME (frame, f);
-         clear_glyph_matrix (w->desired_matrix);
          Fmodify_frame_parameters (frame,
                                    Fcons (Fcons (Qtool_bar_lines,
                                                  make_number (nlines)),
                                           Qnil));
          if (WINDOW_TOTAL_LINES (w) != old_height)
-           fonts_changed_p = 1;
+           {
+             clear_glyph_matrix (w->desired_matrix);
+             f->n_tool_bar_rows = nrows;
+             fonts_changed_p = 1;
+           }
        }
     }
 
@@ -10332,7 +10807,7 @@ check_point_in_composition (prev_buf, prev_pt, buf, pt)
      struct buffer *prev_buf, *buf;
      int prev_pt, pt;
 {
-  int start, end;
+  EMACS_INT start, end;
   Lisp_Object prop;
   Lisp_Object buffer;
 
@@ -10524,6 +10999,8 @@ redisplay_internal (preserve_echo_area)
  retry:
   pause = 0;
   reconsider_clip_changes (w, current_buffer);
+  last_escape_glyph_frame = NULL;
+  last_escape_glyph_face_id = (1 << FACE_ID_BITS);
 
   /* If new fonts have been loaded that make a glyph matrix adjustment
      necessary, do it.  */
@@ -11324,35 +11801,24 @@ disp_char_vector (dp, c)
      struct Lisp_Char_Table *dp;
      int c;
 {
-  int code[4], i;
   Lisp_Object val;
 
-  if (SINGLE_BYTE_CHAR_P (c))
-    return (dp->contents[c]);
-
-  SPLIT_CHAR (c, code[0], code[1], code[2]);
-  if (code[1] < 32)
-    code[1] = -1;
-  else if (code[2] < 32)
-    code[2] = -1;
-
-  /* Here, the possible range of code[0] (== charset ID) is
-     128..max_charset.  Since the top level char table contains data
-     for multibyte characters after 256th element, we must increment
-     code[0] by 128 to get a correct index.  */
-  code[0] += 128;
-  code[3] = -1;                /* anchor */
-
-  for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
+  if (ASCII_CHAR_P (c))
     {
-      val = dp->contents[code[i]];
-      if (!SUB_CHAR_TABLE_P (val))
-       return (NILP (val) ? dp->defalt : val);
+      val = dp->ascii;
+      if (SUB_CHAR_TABLE_P (val))
+       val = XSUB_CHAR_TABLE (val)->contents[c];
     }
+  else
+    {
+      Lisp_Object table;
 
-  /* Here, val is a sub char table.  We return the default value of
-     it.  */
-  return (dp->defalt);
+      XSETCHAR_TABLE (table, dp);
+      val = char_table_ref (table, c);
+    }
+  if (NILP (val))
+    val = dp->defalt;
+  return val;
 }
 
 
@@ -11429,9 +11895,11 @@ redisplay_window_1 (window)
 
 /* Set cursor position of W.  PT is assumed to be displayed in ROW.
    DELTA is the number of bytes by which positions recorded in ROW
-   differ from current buffer positions.  */
+   differ from current buffer positions.
 
-void
+   Return 0 if cursor is not on this row.  1 otherwise.  */
+
+int
 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
      struct window *w;
      struct glyph_row *row;
@@ -11478,7 +11946,7 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
          x += glyph->pixel_width;
          ++glyph;
          if (cursor_from_overlay_pos
-             && last_pos > cursor_from_overlay_pos)
+             && last_pos >= cursor_from_overlay_pos)
            {
              cursor_from_overlay_pos = 0;
              cursor = 0;
@@ -11486,16 +11954,21 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
        }
       else
        {
-         string_before_pos = last_pos;
-         string_start = glyph;
-         string_start_x = x;
+         if (string_start == NULL)
+           {
+             string_before_pos = last_pos;
+             string_start = glyph;
+             string_start_x = x;
+           }
          /* Skip all glyphs from string.  */
          do
            {
+             Lisp_Object cprop;
              int pos;
              if ((cursor == NULL || glyph > cursor)
-                 && !NILP (Fget_char_property (make_number ((glyph)->charpos),
-                                               Qcursor, (glyph)->object))
+                 && (cprop = Fget_char_property (make_number ((glyph)->charpos),
+                                                 Qcursor, (glyph)->object),
+                     !NILP (cprop))
                  && (pos = string_buffer_position (w, glyph->object,
                                                    string_before_pos),
                      (pos == 0   /* From overlay */
@@ -11506,14 +11979,15 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
                     Add 1 to last_pos so that if point corresponds to the
                     glyph right after the overlay, we still use a 'cursor'
                     property found in that overlay.  */
-                 cursor_from_overlay_pos = pos == 0 ? last_pos+1 : 0;
+                 cursor_from_overlay_pos = (pos ? 0 : last_pos
+                                            + (INTEGERP (cprop) ? XINT (cprop) : 0));
                  cursor = glyph;
                  cursor_x = x;
                }
              x += glyph->pixel_width;
              ++glyph;
            }
-         while (glyph < end && STRINGP (glyph->object));
+         while (glyph < end && EQ (glyph->object, string_start->object));
        }
     }
 
@@ -11543,25 +12017,25 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
         glyph on point by scanning from string_start again.  */
       Lisp_Object limit;
       Lisp_Object string;
+      struct glyph *stop = glyph;
       int pos;
 
       limit = make_number (pt_old + 1);
-      end = glyph;
       glyph = string_start;
       x = string_start_x;
       string = glyph->object;
       pos = string_buffer_position (w, string, string_before_pos);
       /* If STRING is from overlay, LAST_POS == 0.  We skip such glyphs
         because we always put cursor after overlay strings.  */
-      while (pos == 0 && glyph < end)
+      while (pos == 0 && glyph < stop)
        {
          string = glyph->object;
-         SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
-         if (glyph < end)
+         SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
+         if (glyph < stop)
            pos = string_buffer_position (w, glyph->object, string_before_pos);
        }
 
-      while (glyph < end)
+      while (glyph < stop)
        {
          pos = XINT (Fnext_single_char_property_change
                      (make_number (pos), Qdisplay, Qnil, limit));
@@ -11569,15 +12043,20 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
            break;
          /* Skip glyphs from the same string.  */
          string = glyph->object;
-         SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
+         SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
          /* Skip glyphs from an overlay.  */
-         while (glyph < end
+         while (glyph < stop
                 && ! string_buffer_position (w, glyph->object, pos))
            {
              string = glyph->object;
-             SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
+             SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
            }
        }
+
+      /* If we reached the end of the line, and end was from a string,
+        cursor is not on this line.  */
+      if (glyph == end && row->continued_p)
+       return 0;
     }
 
   w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
@@ -11611,6 +12090,8 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
       else
        CHARPOS (this_line_start_pos) = 0;
     }
+
+  return 1;
 }
 
 
@@ -12294,8 +12775,18 @@ try_cursor_movement (window, startp, scroll_step)
            rc = CURSOR_MOVEMENT_MUST_SCROLL;
          else
            {
-             set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
-             rc = CURSOR_MOVEMENT_SUCCESS;
+             do
+               {
+                 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
+                   {
+                     rc = CURSOR_MOVEMENT_SUCCESS;
+                     break;
+                   }
+                 ++row;
+               }
+             while (MATRIX_ROW_BOTTOM_Y (row) < last_y
+                    && MATRIX_ROW_START_CHARPOS (row) == PT
+                    && cursor_row_p (w, row));
            }
        }
     }
@@ -12556,8 +13047,6 @@ redisplay_window (window, just_this_one_p)
       /* IT may overshoot PT if text at PT is invisible.  */
       else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
        w->force_start = Qt;
-
-
     }
 
   /* Handle case where place to start displaying has been specified,
@@ -12727,6 +13216,36 @@ redisplay_window (window, just_this_one_p)
               || (XFASTINT (w->last_modified) >= MODIFF
                   && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
     {
+
+      /* If first window line is a continuation line, and window start
+        is inside the modified region, but the first change is before
+        current window start, we must select a new window start.*/
+      if (NILP (w->start_at_line_beg)
+         && CHARPOS (startp) > BEGV)
+       {
+         /* Make sure beg_unchanged and end_unchanged are up to date.
+            Do it only if buffer has really changed.  This may or may
+            not have been done by try_window_id (see which) already. */
+         if (MODIFF > SAVE_MODIFF
+             /* This seems to happen sometimes after saving a buffer.  */
+             || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
+           {
+             if (GPT - BEG < BEG_UNCHANGED)
+               BEG_UNCHANGED = GPT - BEG;
+             if (Z - GPT < END_UNCHANGED)
+               END_UNCHANGED = Z - GPT;
+           }
+
+         if (CHARPOS (startp) > BEG + BEG_UNCHANGED
+             && CHARPOS (startp) <= Z - END_UNCHANGED)
+           {
+             /* There doesn't seems to be a simple way to find a new
+                window start that is near the old window start, so
+                we just recenter.  */
+             goto recenter;
+           }
+       }
+
 #if GLYPH_DEBUG
       debug_method_add (w, "same window start");
 #endif
@@ -14720,6 +15239,25 @@ dump_glyph (row, glyph, area)
               glyph->left_box_line_p,
               glyph->right_box_line_p);
     }
+  else if (glyph->type == COMPOSITE_GLYPH)
+    {
+      fprintf (stderr,
+              "  %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
+              glyph - row->glyphs[TEXT_AREA],
+              '+',
+              glyph->charpos,
+              (BUFFERP (glyph->object)
+               ? 'B'
+               : (STRINGP (glyph->object)
+                  ? 'S'
+                  : '-')),
+              glyph->pixel_width,
+              glyph->u.cmp_id,
+              '.',
+              glyph->face_id,
+              glyph->left_box_line_p,
+              glyph->right_box_line_p);
+    }
 }
 
 
@@ -14735,7 +15273,7 @@ dump_glyph_row (row, vpos, glyphs)
 {
   if (glyphs != 1)
     {
-      fprintf (stderr, "Row Start   End Used oEI><\\CTZFesm     X    Y    W    H    V    A    P\n");
+      fprintf (stderr, "Row Start   End Used oE><\\CTZFesm     X    Y    W    H    V    A    P\n");
       fprintf (stderr, "======================================================================\n");
 
       fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d\
@@ -15193,7 +15731,7 @@ append_space_for_newline (it, default_face_p)
          else if (it->face_before_selective_p)
            it->face_id = it->saved_face_id;
          face = FACE_FROM_ID (it->f, it->face_id);
-         it->face_id = FACE_FOR_CHAR (it->f, face, 0);
+         it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
 
          PRODUCE_GLYPHS (it);
 
@@ -15239,6 +15777,7 @@ extend_face_to_end_of_line (it)
     face = FACE_FROM_ID (f, it->face_id);
 
   if (FRAME_WINDOW_P (f)
+      && it->glyph_row->displays_text_p
       && face->box == FACE_NO_BOX
       && face->background == FRAME_BACKGROUND_PIXEL (f)
       && !face->stipple)
@@ -15252,9 +15791,9 @@ extend_face_to_end_of_line (it)
          ASCII face.  This will be automatically undone the next time
          get_next_display_element returns a multibyte character.  Note
          that the character will always be single byte in unibyte text.  */
-  if (!SINGLE_BYTE_CHAR_P (it->c))
+  if (!ASCII_CHAR_P (it->c))
     {
-      it->face_id = FACE_FOR_CHAR (f, face, 0);
+      it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
     }
 
   if (FRAME_WINDOW_P (f))
@@ -15360,7 +15899,7 @@ highlight_trailing_whitespace (f, row)
                  && glyph->u.ch == ' '))
          && trailing_whitespace_p (glyph->charpos))
        {
-         int face_id = lookup_named_face (f, Qtrailing_whitespace, 0, 0);
+         int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
          if (face_id < 0)
            return;
 
@@ -16179,6 +16718,7 @@ display_mode_line (w, face_id, format)
      kboard-local variables in the mode_line_format will get the right
      values.  */
   push_frame_kboard (it.f);
+  record_unwind_save_match_data ();
   display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
   pop_frame_kboard ();
 
@@ -16431,8 +16971,11 @@ display_mode_element (it, depth, field_width, precision, elt, props, risky)
                    {
                      int bytepos = last_offset;
                      int charpos = string_byte_to_char (elt, bytepos);
+
+                     if (precision <= 0)
+                       nchars = string_byte_to_char (elt, offset) - charpos;
                      n += display_string (NULL, elt, Qnil, 0, charpos,
-                                          it, 0, prec, 0,
+                                          it, 0, nchars, 0,
                                           STRING_MULTIBYTE (elt));
                    }
                    break;
@@ -16856,7 +17399,7 @@ are the selected window and the window's buffer).  */)
     {
       if (EQ (face, Qt))
        face = (EQ (window, selected_window) ? Qmode_line : Qmode_line_inactive);
-      face_id = lookup_named_face (XFRAME (WINDOW_FRAME (w)), face, 0, 0);
+      face_id = lookup_named_face (XFRAME (WINDOW_FRAME (w)), face, 0);
     }
 
   if (face_id < 0)
@@ -17079,7 +17622,7 @@ decode_mode_spec_coding (coding_system, buf, eol_flag)
   /* The EOL conversion we are using.  */
   Lisp_Object eoltype;
 
-  val = Fget (coding_system, Qcoding_system);
+  val = CODING_SYSTEM_SPEC (coding_system);
   eoltype = Qnil;
 
   if (!VECTORP (val))          /* Not yet decided.  */
@@ -17092,12 +17635,14 @@ decode_mode_spec_coding (coding_system, buf, eol_flag)
     }
   else
     {
+      Lisp_Object attrs;
       Lisp_Object eolvalue;
 
-      eolvalue = Fget (coding_system, Qeol_type);
+      attrs = AREF (val, 0);
+      eolvalue = AREF (val, 2);
 
       if (multibyte)
-       *buf++ = XFASTINT (AREF (val, 1));
+       *buf++ = XFASTINT (CODING_ATTR_MNEMONIC (attrs));
 
       if (eol_flag)
        {
@@ -17107,10 +17652,10 @@ decode_mode_spec_coding (coding_system, buf, eol_flag)
            eoltype = eol_mnemonic_undecided;
          else if (VECTORP (eolvalue)) /* Not yet decided.  */
            eoltype = eol_mnemonic_undecided;
-         else                  /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
-           eoltype = (XFASTINT (eolvalue) == 0
+         else                  /* eolvalue is Qunix, Qdos, or Qmac.  */
+           eoltype = (EQ (eolvalue, Qunix)
                       ? eol_mnemonic_unix
-                      : (XFASTINT (eolvalue) == 1
+                      : (EQ (eolvalue, Qdos) == 1
                          ? eol_mnemonic_dos : eol_mnemonic_mac));
        }
     }
@@ -17123,8 +17668,7 @@ decode_mode_spec_coding (coding_system, buf, eol_flag)
          eol_str = SDATA (eoltype);
          eol_str_len = SBYTES (eoltype);
        }
-      else if (INTEGERP (eoltype)
-              && CHAR_VALID_P (XINT (eoltype), 0))
+      else if (CHARACTERP (eoltype))
        {
          unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
          eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
@@ -17505,8 +18049,10 @@ decode_mode_spec (w, c, field_width, precision, multibyte)
          {
            /* No need to mention EOL here--the terminal never needs
               to do EOL conversion.  */
-           p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
-           p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
+           p = decode_mode_spec_coding (CODING_ID_NAME (keyboard_coding.id),
+                                        p, 0);
+           p = decode_mode_spec_coding (CODING_ID_NAME (terminal_coding.id),
+                                        p, 0);
          }
        p = decode_mode_spec_coding (b->buffer_file_coding_system,
                                     p, eol_flag);
@@ -17681,7 +18227,7 @@ display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
    display them, and < 0 means obey the current buffer's value of
    enable_multibyte_characters.
 
-   Value is the number of glyphs produced.  */
+   Value is the number of columns displayed.  */
 
 static int
 display_string (string, lisp_string, face_string, face_string_pos,
@@ -17778,7 +18324,7 @@ display_string (string, lisp_string, face_string, face_string_pos,
                }
              break;
            }
-         else if (x + glyph->pixel_width > it->first_visible_x)
+         else if (x + glyph->pixel_width >= it->first_visible_x)
            {
              /* Glyph is at least partially visible.  */
              ++it->hpos;
@@ -18325,38 +18871,55 @@ get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
   if (two_byte_p)
     *two_byte_p = 0;
 
+#ifdef USE_FONT_BACKEND
+  if (enable_font_backend)
+    {
+      struct font *font = (struct font *) face->font_info;
+
+      if (font)
+       {
+         unsigned code = font->driver->encode_char (font, glyph->u.ch);
+
+         if (code != FONT_INVALID_CODE)
+           STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
+         else
+           STORE_XCHAR2B (char2b, 0, code);
+       }
+    }
+  else
+#endif /* USE_FONT_BACKEND */
   if (!glyph->multibyte_p)
     {
       /* Unibyte case.  We don't have to encode, but we have to make
         sure to use a face suitable for unibyte.  */
       STORE_XCHAR2B (char2b, 0, glyph->u.ch);
     }
-  else if (glyph->u.ch < 128
-          && glyph->face_id < BASIC_FACE_ID_SENTINEL)
+  else if (glyph->u.ch < 128)
     {
       /* Case of ASCII in a face known to fit ASCII.  */
       STORE_XCHAR2B (char2b, 0, glyph->u.ch);
     }
   else
     {
-      int c1, c2, charset;
+      struct font_info *font_info
+       = FONT_INFO_FROM_ID (f, face->font_info_id);
+      if (font_info)
+       {
+         struct charset *charset = CHARSET_FROM_ID (font_info->charset);
+         unsigned code = ENCODE_CHAR (charset, glyph->u.ch);
 
-      /* Split characters into bytes.  If c2 is -1 afterwards, C is
-        really a one-byte character so that byte1 is zero.  */
-      SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
-      if (c2 > 0)
-       STORE_XCHAR2B (char2b, c1, c2);
-      else
-       STORE_XCHAR2B (char2b, 0, c1);
+         if (CHARSET_DIMENSION (charset) == 1)
+           STORE_XCHAR2B (char2b, 0, code);
+         else
+           STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
 
-      /* Maybe encode the character in *CHAR2B.  */
-      if (charset != CHARSET_ASCII)
-       {
-         struct font_info *font_info
-           = FONT_INFO_FROM_ID (f, face->font_info_id);
-         if (font_info)
-           glyph->font_type
-             = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
+         /* Maybe encode the character in *CHAR2B.  */
+         if (CHARSET_ID (charset) != charset_ascii)
+           {
+             glyph->font_type
+               = rif->encode_char (glyph->u.ch, char2b, font_info, charset,
+                                   two_byte_p);
+           }
        }
     }
 
@@ -18390,20 +18953,55 @@ fill_composite_glyph_string (s, faces, overlaps)
   s->for_overlaps = overlaps;
 
   s->face = faces[s->gidx];
-  s->font = s->face->font;
-  s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
+  if (s->face == NULL)
+    {
+      s->font = NULL;
+      s->font_info = NULL;
+    }
+  else
+    {
+      s->font = s->face->font;
+      s->font_info = FONT_INFO_FROM_FACE (s->f, s->face);
+    }
+
+#ifdef USE_FONT_BACKEND
+  if (enable_font_backend && s->cmp->method == COMPOSITION_WITH_GLYPH_STRING)
+    {
+      Lisp_Object gstring
+       = AREF (XHASH_TABLE (composition_hash_table)->key_and_value,
+               s->cmp->hash_index * 2);
+
+      for (i = 0, s->nchars = 0; i < s->cmp->glyph_len; i++, s->nchars++)
+       {
+         Lisp_Object g = LGSTRING_GLYPH (gstring, i);
+         unsigned code;
 
+         if (NILP (LGLYPH_FROM (g)))
+           break;
+         code = XUINT (LGLYPH_CODE (g));
+         STORE_XCHAR2B (s->char2b + i, code >> 8, code & 0xFF);
+       }
+      s->width = s->cmp->pixel_width;
+    }
+  else
+    {
+#endif /* USE_FONT_BACKEND */
   /* For all glyphs of this composition, starting at the offset
      S->gidx, until we reach the end of the definition or encounter a
      glyph that requires the different face, add it to S.  */
   ++s->nchars;
-  for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
+  for (i = s->gidx + 1;
+       i < s->cmp->glyph_len && (faces[i] == s->face || ! faces[i] || ! s->face);
+       ++i)
     ++s->nchars;
 
   /* 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;
+#ifdef USE_FONT_BACKEND
+    }
+#endif /* USE_FONT_BACKEND */
 
   /* If the specified font could not be loaded, use the frame's
      default font, but record the fact that we couldn't load it in
@@ -18418,8 +19016,6 @@ fill_composite_glyph_string (s, faces, overlaps)
   /* Adjust base line for subscript/superscript text.  */
   s->ybase += s->first_glyph->voffset;
 
-  xassert (s->face && s->face->gc);
-
   /* This glyph string must always be drawn with 16-bit functions.  */
   s->two_byte_p = 1;
 
@@ -18477,7 +19073,7 @@ fill_glyph_string (s, face_id, start, end, overlaps)
     }
 
   s->font = s->face->font;
-  s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
+  s->font_info = FONT_INFO_FROM_FACE (s->f, s->face);
 
   /* If the specified font could not be loaded, use the frame's font,
      but record the fact that we couldn't load it in
@@ -18541,8 +19137,9 @@ fill_stretch_glyph_string (s, row, area, start, end)
   face_id = glyph->face_id;
   s->face = FACE_FROM_ID (s->f, face_id);
   s->font = s->face->font;
-  s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
+  s->font_info = FONT_INFO_FROM_FACE (s->f, s->face);
   s->width = glyph->pixel_width;
+  s->nchars = 1;
   voffset = glyph->voffset;
 
   for (++glyph;
@@ -18562,6 +19159,35 @@ fill_stretch_glyph_string (s, row, area, start, end)
   return glyph - s->row->glyphs[s->area];
 }
 
+static XCharStruct *
+get_per_char_metric (font, font_info, char2b, font_type)
+     XFontStruct *font;
+     struct font_info *font_info;
+     XChar2b *char2b;
+     int font_type;
+{
+#ifdef USE_FONT_BACKEND
+  if (enable_font_backend)
+    {
+      static XCharStruct pcm_value;
+      unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
+      struct font *fontp;
+      struct font_metrics metrics;
+
+      if (! font_info || code == FONT_INVALID_CODE)
+       return NULL;
+      fontp = (struct font *) font_info;
+      fontp->driver->text_extents (fontp, &code, 1, &metrics);
+      pcm_value.lbearing = metrics.lbearing;
+      pcm_value.rbearing = metrics.rbearing;
+      pcm_value.ascent = metrics.ascent;
+      pcm_value.descent = metrics.descent;
+      pcm_value.width = metrics.width;
+      return &pcm_value;
+    }
+#endif /* USE_FONT_BACKEND */
+  return rif->per_char_metric (font, char2b, font_type);
+}
 
 /* EXPORT for RIF:
    Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
@@ -18586,9 +19212,9 @@ x_get_glyph_overhangs (glyph, f, left, right)
 
       face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
       font = face->font;
-      font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
+      font_info = FONT_INFO_FROM_FACE (f, face);
       if (font  /* ++KFS: Should this be font_info ?  */
-         && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
+         && (pcm = get_per_char_metric (font, font_info, &char2b, glyph->font_type)))
        {
          if (pcm->rbearing > pcm->width)
            *right = pcm->rbearing - pcm->width;
@@ -18596,6 +19222,13 @@ x_get_glyph_overhangs (glyph, f, left, right)
            *left = -pcm->lbearing;
        }
     }
+  else if (glyph->type == COMPOSITE_GLYPH)
+    {
+      struct composition *cmp = composition_table[glyph->u.cmp_id];
+
+      *right = cmp->rbearing - cmp->pixel_width;
+      *left = - cmp->lbearing;
+    }
 }
 
 
@@ -18725,39 +19358,49 @@ get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
 {
   struct face *face = FACE_FROM_ID (f, face_id);
 
+#ifdef USE_FONT_BACKEND
+  if (enable_font_backend)
+    {
+      struct font *font = (struct font *) face->font_info;
+
+      if (font)
+       {
+         unsigned code = font->driver->encode_char (font, c);
+
+         if (code != FONT_INVALID_CODE)
+           STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
+         else
+           STORE_XCHAR2B (char2b, 0, 0);
+       }
+    }
+  else
+#endif /* USE_FONT_BACKEND */
   if (!multibyte_p)
     {
       /* Unibyte case.  We don't have to encode, but we have to make
         sure to use a face suitable for unibyte.  */
       STORE_XCHAR2B (char2b, 0, c);
-      face_id = FACE_FOR_CHAR (f, face, c);
+      face_id = FACE_FOR_CHAR (f, face, c, -1, Qnil);
       face = FACE_FROM_ID (f, face_id);
     }
-  else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
+  else if (c < 128)
     {
       /* Case of ASCII in a face known to fit ASCII.  */
       STORE_XCHAR2B (char2b, 0, c);
     }
-  else
+  else if (face->font != NULL)
     {
-      int c1, c2, charset;
+      struct font_info *font_info
+       = FONT_INFO_FROM_ID (f, face->font_info_id);
+      struct charset *charset = CHARSET_FROM_ID (font_info->charset);
+      unsigned code = ENCODE_CHAR (charset, c);
 
-      /* Split characters into bytes.  If c2 is -1 afterwards, C is
-        really a one-byte character so that byte1 is zero.  */
-      SPLIT_CHAR (c, charset, c1, c2);
-      if (c2 > 0)
-       STORE_XCHAR2B (char2b, c1, c2);
+      if (CHARSET_DIMENSION (charset) == 1)
+       STORE_XCHAR2B (char2b, 0, code);
       else
-       STORE_XCHAR2B (char2b, 0, c1);
-
-      /* Maybe encode the character in *CHAR2B.  */
-      if (face->font != NULL)
-       {
-         struct font_info *font_info
-           = FONT_INFO_FROM_ID (f, face->font_info_id);
-         if (font_info)
-           rif->encode_char (c, char2b, font_info, 0);
-       }
+       STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
+       /* Maybe encode the character in *CHAR2B.  */
+      rif->encode_char (c, char2b, font_info, charset, NULL);
     }
 
   /* Make sure X resources of the face are allocated.  */
@@ -18912,10 +19555,9 @@ compute_overhangs_and_x (s, x, backward_p)
 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X)           \
      do                                                                           \
        {                                                                  \
-        int c, face_id;                                                   \
+        int face_id;                                                      \
         XChar2b *char2b;                                                  \
                                                                           \
-        c = (row)->glyphs[area][START].u.ch;                              \
         face_id = (row)->glyphs[area][START].face_id;                     \
                                                                           \
         s = (struct glyph_string *) alloca (sizeof *s);                   \
@@ -18949,6 +19591,14 @@ compute_overhangs_and_x (s, x, backward_p)
     struct glyph_string *first_s = NULL;                                 \
     int n;                                                               \
                                                                          \
+    if (cmp->method > COMPOSITION_WITH_RULE_ALTCHARS)                    \
+      {                                                                          \
+       /* This happens only when USE_FONT_BACKEND is defined.  */        \
+       char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len);       \
+       faces = &base_face;                                               \
+      }                                                                          \
+    else                                                                 \
+      {                                                                          \
     base_face = base_face->ascii_face;                                   \
     char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len);                  \
     faces = (struct face **) alloca ((sizeof *faces) * glyph_len);       \
@@ -18956,11 +19606,18 @@ compute_overhangs_and_x (s, x, backward_p)
     for (n = 0; n < glyph_len; n++)                                      \
       {                                                                          \
        int c = COMPOSITION_GLYPH (cmp, n);                               \
-       int this_face_id = FACE_FOR_CHAR (f, base_face, c);               \
-       faces[n] = FACE_FROM_ID (f, this_face_id);                        \
-       get_char_face_and_encoding (f, c, this_face_id,                   \
+                                                                         \
+       if (c == '\t')                                                    \
+         faces[n] = NULL;                                                \
+       else                                                              \
+         {                                                               \
+           int this_face_id = FACE_FOR_CHAR (f, base_face, c, -1, Qnil); \
+           faces[n] = FACE_FROM_ID (f, this_face_id);                    \
+           get_char_face_and_encoding (f, c, this_face_id,               \
                                    char2b + n, 1, 1);                    \
+         }                                                               \
       }                                                                          \
+    }                                                                    \
                                                                          \
     /* Make glyph_strings for each glyph sequence that is drawable by    \
        the same face, and append them to HEAD/TAIL.  */                          \
@@ -19027,8 +19684,11 @@ compute_overhangs_and_x (s, x, backward_p)
                 abort ();                                                 \
               }                                                           \
                                                                           \
-             set_glyph_string_background_width (s, START, LAST_X);        \
-            (X) += s->width;                                              \
+            if (s)                                                        \
+              {                                                           \
+                set_glyph_string_background_width (s, START, LAST_X);     \
+                (X) += s->width;                                          \
+              }                                                           \
             }                                                             \
        }                                                                  \
      while (0)
@@ -19062,7 +19722,7 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps)
      int x;
      struct glyph_row *row;
      enum glyph_row_area area;
-     int start, end;
+     EMACS_INT start, end;
      enum draw_glyphs_face hl;
      int overlaps;
 {
@@ -19182,6 +19842,7 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps)
       if (i >= 0)
        {
          clip_tail = tail;
+         i++;                  /* We must include the Ith glyph.  */
          BUILD_GLYPH_STRINGS (end, i, h, t,
                               DRAW_NORMAL_TEXT, x, last_x);
          for (s = h; s; s = s->next)
@@ -19688,20 +20349,6 @@ produce_stretch_glyph (it)
   it->descent = it->phys_descent = height - it->ascent;
   it->nglyphs = width > 0 && height > 0 ? 1 : 0;
 
-  if (width > 0 && height > 0 && face->box != FACE_NO_BOX)
-    {
-      if (face->box_line_width > 0)
-       {
-         it->ascent += face->box_line_width;
-         it->descent += face->box_line_width;
-       }
-
-      if (it->start_of_box_run_p)
-       it->pixel_width += abs (face->box_line_width);
-      if (it->end_of_box_run_p)
-       it->pixel_width += abs (face->box_line_width);
-    }
-
   take_vertical_position_into_account (it);
 }
 
@@ -19776,7 +20423,7 @@ calc_line_height_property (it, val, font, boff, override)
       struct face *face;
       struct font_info *font_info;
 
-      face_id = lookup_named_face (it->f, face_name, ' ', 0);
+      face_id = lookup_named_face (it->f, face_name, 0);
       if (face_id < 0)
        return make_number (-1);
 
@@ -19785,7 +20432,7 @@ calc_line_height_property (it, val, font, boff, override)
       if (font == NULL)
        return make_number (-1);
 
-      font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
+      font_info = FONT_INFO_FROM_FACE (it->f, face);
       boff = font_info->baseline_offset;
       if (font_info->vertical_centering)
        boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
@@ -19815,8 +20462,8 @@ calc_line_height_property (it, val, font, boff, override)
 
 /* RIF:
    Produce glyphs/get display metrics for the display element IT is
-   loaded with.  See the description of struct display_iterator in
-   dispextern.h for an overview of struct display_iterator.  */
+   loaded with.  See the description of struct it in dispextern.h
+   for an overview of struct it.  */
 
 void
 x_produce_glyphs (it)
@@ -19849,23 +20496,17 @@ x_produce_glyphs (it)
       /* Maybe translate single-byte characters to multibyte, or the
         other way.  */
       it->char_to_display = it->c;
-      if (!ASCII_BYTE_P (it->c))
+      if (!ASCII_BYTE_P (it->c)
+         && ! it->multibyte_p)
        {
-         if (unibyte_display_via_language_environment
-             && SINGLE_BYTE_CHAR_P (it->c)
-             && (it->c >= 0240
-                 || !NILP (Vnonascii_translation_table)))
+         if (SINGLE_BYTE_CHAR_P (it->c)
+             && unibyte_display_via_language_environment)
+           it->char_to_display = unibyte_char_to_multibyte (it->c);
+         if (! SINGLE_BYTE_CHAR_P (it->c))
            {
-             it->char_to_display = unibyte_char_to_multibyte (it->c);
              it->multibyte_p = 1;
-             it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
-             face = FACE_FROM_ID (it->f, it->face_id);
-           }
-         else if (!SINGLE_BYTE_CHAR_P (it->c)
-                  && !it->multibyte_p)
-           {
-             it->multibyte_p = 1;
-             it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
+             it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display,
+                                          -1, Qnil);
              face = FACE_FROM_ID (it->f, it->face_id);
            }
        }
@@ -19885,7 +20526,7 @@ x_produce_glyphs (it)
        }
       else
        {
-         font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
+         font_info = FONT_INFO_FROM_FACE (it->f, face);
          boff = font_info->baseline_offset;
          if (font_info->vertical_centering)
            boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
@@ -19899,7 +20540,7 @@ x_produce_glyphs (it)
 
          it->nglyphs = 1;
 
-         pcm = rif->per_char_metric (font, &char2b,
+         pcm = get_per_char_metric (font, font_info, &char2b,
                                      FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
 
          if (it->override_ascent >= 0)
@@ -19975,7 +20616,7 @@ x_produce_glyphs (it)
          /* If face has an overline, add the height of the overline
             (1 pixel) and a 1 pixel margin to the character height.  */
          if (face->overline_p)
-           it->ascent += 2;
+           it->ascent += overline_margin;
 
          if (it->constrain_row_ascent_descent_p)
            {
@@ -20126,20 +20767,18 @@ x_produce_glyphs (it)
 
          /* If we found a font, this font should give us the right
             metrics.  If we didn't find a font, use the frame's
-            default font and calculate the width of the character
-            from the charset width; this is what old redisplay code
-            did.  */
+            default font and calculate the width of the character by
+            multiplying the width of font by the width of the
+            character.  */
 
-         pcm = rif->per_char_metric (font, &char2b,
+         pcm = get_per_char_metric (font, font_info, &char2b,
                                      FONT_TYPE_FOR_MULTIBYTE (font, it->c));
 
          if (font_not_found_p || !pcm)
            {
-             int charset = CHAR_CHARSET (it->char_to_display);
-
              it->glyph_not_available_p = 1;
              it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
-                                * CHARSET_WIDTH (charset));
+                                * CHAR_WIDTH (it->char_to_display));
              it->phys_ascent = FONT_BASE (font) + boff;
              it->phys_descent = FONT_DESCENT (font) - boff;
            }
@@ -20177,7 +20816,7 @@ x_produce_glyphs (it)
          /* If face has an overline, add the height of the overline
             (1 pixel) and a 1 pixel margin to the character height.  */
          if (face->overline_p)
-           it->ascent += 2;
+           it->ascent += overline_margin;
 
          take_vertical_position_into_account (it);
 
@@ -20198,20 +20837,24 @@ x_produce_glyphs (it)
       struct font_info *font_info;
       int boff;                        /* baseline offset */
       struct composition *cmp = composition_table[it->cmp_id];
+      int pos;
 
       /* Maybe translate single-byte characters to multibyte.  */
       it->char_to_display = it->c;
       if (unibyte_display_via_language_environment
-         && SINGLE_BYTE_CHAR_P (it->c)
-         && (it->c >= 0240
-             || (it->c >= 0200
-                 && !NILP (Vnonascii_translation_table))))
+         && it->c >= 0200)
        {
          it->char_to_display = unibyte_char_to_multibyte (it->c);
        }
 
+#ifdef USE_FONT_BACKEND
+      if (cmp->method != COMPOSITION_WITH_GLYPH_STRING)
+       {
+#endif /* USE_FONT_BACKEND */
       /* Get face and font to use.  Encode IT->char_to_display.  */
-      it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
+      pos = STRINGP (it->string) ? IT_STRING_CHARPOS (*it) : IT_CHARPOS (*it);
+      it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display,
+                                  pos, it->string);
       face = FACE_FROM_ID (it->f, it->face_id);
       get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
                                  &char2b, it->multibyte_p, 0);
@@ -20227,11 +20870,14 @@ x_produce_glyphs (it)
        }
       else
        {
-         font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
+         font_info = FONT_INFO_FROM_FACE (it->f, face);
          boff = font_info->baseline_offset;
          if (font_info->vertical_centering)
            boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
        }
+#ifdef USE_FONT_BACKEND
+       }
+#endif
 
       /* There are no padding glyphs, so there is only one glyph to
         produce for the composition.  Important is that pixel_width,
@@ -20244,9 +20890,21 @@ x_produce_glyphs (it)
         now.  Theoretically, we have to check all fonts for the
         glyphs, but that requires much time and memory space.  So,
         here we check only the font of the first glyph.  This leads
-        to incorrect display very rarely, and C-l (recenter) can
-        correct the display anyway.  */
-      if (cmp->font != (void *) font)
+        to incorrect display, but it's very rare, and C-l (recenter)
+        can correct the display anyway.  */
+      if (cmp->glyph_len == 0)
+       {
+         cmp->lbearing = cmp->rbearing = 0;
+         cmp->pixel_width = cmp->ascent = cmp->descent = 0;
+       }
+#ifdef USE_FONT_BACKEND
+      else if (cmp->method == COMPOSITION_WITH_GLYPH_STRING)
+       {
+         if (! cmp->font)
+           font_prepare_composition (cmp);
+       }
+#endif /* USE_FONT_BACKEND */
+      else if (cmp->font != (void *) font)
        {
          /* Ascent and descent of the font of the first character of
             this composition (adjusted by baseline offset).  Ascent
@@ -20254,26 +20912,37 @@ x_produce_glyphs (it)
             them respectively.  */
          int font_ascent = FONT_BASE (font) + boff;
          int font_descent = FONT_DESCENT (font) - boff;
+         int font_height = FONT_HEIGHT (font);
          /* Bounding box of the overall glyphs.  */
          int leftmost, rightmost, lowest, highest;
+         int lbearing, rbearing;
          int i, width, ascent, descent;
+         int fully_padded = 0;
 
          cmp->font = (void *) font;
 
          /* Initialize the bounding box.  */
          if (font_info
-             && (pcm = rif->per_char_metric (font, &char2b,
+             && (pcm = get_per_char_metric (font, font_info, &char2b,
                                              FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
            {
              width = pcm->width;
              ascent = pcm->ascent;
              descent = pcm->descent;
+             lbearing = pcm->lbearing;
+             if (lbearing > 0)
+               lbearing = 0;
+             rbearing = pcm->rbearing;
+             if (rbearing < width)
+               rbearing = width;
            }
          else
            {
              width = FONT_WIDTH (font);
              ascent = FONT_BASE (font);
              descent = FONT_DESCENT (font);
+             lbearing = 0;
+             rbearing = width;
            }
 
          rightmost = width;
@@ -20293,14 +20962,25 @@ x_produce_glyphs (it)
             the left.  */
          cmp->offsets[0] = 0;
          cmp->offsets[1] = boff;
+         cmp->lbearing = lbearing;
+         cmp->rbearing = rbearing;
 
          /* Set cmp->offsets for the remaining glyphs.  */
          for (i = 1; i < cmp->glyph_len; i++)
            {
              int left, right, btm, top;
              int ch = COMPOSITION_GLYPH (cmp, i);
-             int face_id = FACE_FOR_CHAR (it->f, face, ch);
+             int face_id;
 
+             if (ch == '\t')
+               {
+                 fully_padded = 1;
+                 cmp->offsets[i * 2] = 0;
+                 cmp->offsets[i * 2 + 1] = boff;
+                 continue;
+               }
+
+             face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
              face = FACE_FROM_ID (it->f, face_id);
              get_char_face_and_encoding (it->f, ch, face->id,
                                          &char2b, it->multibyte_p, 0);
@@ -20314,25 +20994,33 @@ x_produce_glyphs (it)
              else
                {
                  font_info
-                   = FONT_INFO_FROM_ID (it->f, face->font_info_id);
+                   = FONT_INFO_FROM_FACE (it->f, face);
                  boff = font_info->baseline_offset;
                  if (font_info->vertical_centering)
                    boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
                }
 
              if (font_info
-                 && (pcm = rif->per_char_metric (font, &char2b,
+                 && (pcm = get_per_char_metric (font, font_info, &char2b,
                                                  FONT_TYPE_FOR_MULTIBYTE (font, ch))))
                {
                  width = pcm->width;
                  ascent = pcm->ascent;
                  descent = pcm->descent;
+                 lbearing = pcm->lbearing;
+                 if (lbearing > 0)
+                   lbearing = 0;
+                 rbearing = pcm->rbearing;
+                 if (rbearing < width)
+                   rbearing = width;
                }
              else
                {
                  width = FONT_WIDTH (font);
                  ascent = 1;
                  descent = 0;
+                 lbearing = 0;
+                 rbearing = width;
                }
 
              if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
@@ -20373,15 +21061,21 @@ x_produce_glyphs (it)
                        6---7---8 -- descent
                  */
                  int rule = COMPOSITION_RULE (cmp, i);
-                 int gref, nref, grefx, grefy, nrefx, nrefy;
+                 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
 
-                 COMPOSITION_DECODE_RULE (rule, gref, nref);
+                 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
                  grefx = gref % 3, nrefx = nref % 3;
                  grefy = gref / 3, nrefy = nref / 3;
+                 if (xoff)
+                   xoff = font_height * (xoff - 128) / 256;
+                 if (yoff)
+                   yoff = font_height * (yoff - 128) / 256;
 
                  left = (leftmost
                          + grefx * (rightmost - leftmost) / 2
-                         - nrefx * width / 2);
+                         - nrefx * width / 2
+                         + xoff);
+                 
                  btm = ((grefy == 0 ? highest
                          : grefy == 1 ? 0
                          : grefy == 2 ? lowest
@@ -20389,23 +21083,32 @@ x_produce_glyphs (it)
                         - (nrefy == 0 ? ascent + descent
                            : nrefy == 1 ? descent - boff
                            : nrefy == 2 ? 0
-                           : (ascent + descent) / 2));
+                           : (ascent + descent) / 2)
+                        + yoff);
                }
 
              cmp->offsets[i * 2] = left;
              cmp->offsets[i * 2 + 1] = btm + descent;
 
              /* Update the bounding box of the overall glyphs. */
-             right = left + width;
+             if (width > 0)
+               {
+                 right = left + width;
+                 if (left < leftmost)
+                   leftmost = left;
+                 if (right > rightmost)
+                   rightmost = right;
+               }
              top = btm + descent + ascent;
-             if (left < leftmost)
-               leftmost = left;
-             if (right > rightmost)
-               rightmost = right;
              if (top > highest)
                highest = top;
              if (btm < lowest)
                lowest = btm;
+
+             if (cmp->lbearing > left + lbearing)
+               cmp->lbearing = left + lbearing;
+             if (cmp->rbearing < left + rbearing)
+               cmp->rbearing = left + rbearing;
            }
 
          /* If there are glyphs whose x-offsets are negative,
@@ -20416,6 +21119,17 @@ x_produce_glyphs (it)
              for (i = 0; i < cmp->glyph_len; i++)
                cmp->offsets[i * 2] -= leftmost;
              rightmost -= leftmost;
+             cmp->lbearing -= leftmost;
+             cmp->rbearing -= leftmost;
+           }
+
+         if (fully_padded)
+           {
+             for (i = 0; i < cmp->glyph_len; i++)
+               cmp->offsets[i * 2] -= cmp->lbearing;
+             rightmost = cmp->rbearing - cmp->lbearing;
+             cmp->lbearing = 0;
+             cmp->rbearing = rightmost; 
            }
 
          cmp->pixel_width = rightmost;
@@ -20427,6 +21141,11 @@ x_produce_glyphs (it)
            cmp->descent = font_descent;
        }
 
+      if (it->glyph_row
+         && (cmp->lbearing < 0
+             || cmp->rbearing > cmp->pixel_width))
+       it->glyph_row->contains_overlapping_glyphs_p = 1;
+
       it->pixel_width = cmp->pixel_width;
       it->ascent = it->phys_ascent = cmp->ascent;
       it->descent = it->phys_descent = cmp->descent;
@@ -20452,7 +21171,7 @@ x_produce_glyphs (it)
       /* If face has an overline, add the height of the overline
         (1 pixel) and a 1 pixel margin to the character height.  */
       if (face->overline_p)
-       it->ascent += 2;
+       it->ascent += overline_margin;
 
       take_vertical_position_into_account (it);
 
@@ -20537,7 +21256,8 @@ x_insert_glyphs (start, len)
   int line_height, shift_by_width, shifted_region_width;
   struct glyph_row *row;
   struct glyph *glyph;
-  int frame_x, frame_y, hpos;
+  int frame_x, frame_y;
+  EMACS_INT hpos;
 
   xassert (updated_window && updated_row);
   BLOCK_INPUT;
@@ -20827,10 +21547,33 @@ get_window_cursor_type (w, glyph, width, active_cursor)
   /* Use normal cursor if not blinked off.  */
   if (!w->cursor_off_p)
     {
-      if (glyph != NULL && glyph->type == IMAGE_GLYPH) {
-       if (cursor_type == FILLED_BOX_CURSOR)
-         cursor_type = HOLLOW_BOX_CURSOR;
+#ifdef HAVE_WINDOW_SYSTEM
+      if (glyph != NULL && glyph->type == IMAGE_GLYPH)
+       {
+         if (cursor_type == FILLED_BOX_CURSOR)
+           {
+             /* Using a block cursor on large images can be very annoying.
+                So use a hollow cursor for "large" images.  */
+             struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
+             if (img != NULL && IMAGEP (img->spec))
+               {
+                 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
+                    where N = size of default frame font size.
+                    This should cover most of the "tiny" icons people may use.  */
+                 if (img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
+                     || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
+                   cursor_type = HOLLOW_BOX_CURSOR;
+               }
+           }
+         else if (cursor_type != NO_CURSOR)
+           {
+             /* Display current only supports BOX and HOLLOW cursors for images.
+                So for now, unconditionally use a HOLLOW cursor when cursor is
+                not a solid box cursor.  */
+             cursor_type = HOLLOW_BOX_CURSOR;
+           }
       }
+#endif
       return cursor_type;
     }
 
@@ -21116,7 +21859,7 @@ erase_phys_cursor (w)
   /* Maybe clear the display under the cursor.  */
   if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
     {
-      int x, y;
+      int x, y, left_x;
       int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
       int width;
 
@@ -21124,11 +21867,16 @@ erase_phys_cursor (w)
       if (cursor_glyph == NULL)
        goto mark_cursor_off;
 
-      x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
+      width = cursor_glyph->pixel_width;
+      left_x = window_box_left_offset (w, TEXT_AREA);
+      x = w->phys_cursor.x;
+      if (x < left_x)
+       width -= left_x - x;
+      width = min (width, window_box_width (w, TEXT_AREA) - x);
       y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
-      width = min (cursor_glyph->pixel_width,
-                  window_box_width (w, TEXT_AREA) - w->phys_cursor.x);
+      x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
 
+      if (width > 0)
       rif->clear_frame_area (f, x, y, width, cursor_row->visible_height);
     }
 
@@ -21457,7 +22205,7 @@ cursor_in_mouse_face_p (w)
 static int
 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
      struct window *w;
-     int charpos;
+     EMACS_INT charpos;
      int *hpos, *vpos, *x, *y;
      Lisp_Object stop;
 {
@@ -21545,7 +22293,7 @@ fast_find_position (w, charpos, hpos, vpos, x, y, stop)
 static int
 fast_find_position (w, pos, hpos, vpos, x, y, stop)
      struct window *w;
-     int pos;
+     EMACS_INT pos;
      int *hpos, *vpos, *x, *y;
      Lisp_Object stop;
 {
@@ -21659,7 +22407,7 @@ fast_find_position (w, pos, hpos, vpos, x, y, stop)
 static int
 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
      struct window *w;
-     int pos;
+     EMACS_INT pos;
      Lisp_Object object;
      int *hpos, *vpos, *x, *y;
      int right_p;
@@ -22221,7 +22969,10 @@ note_mouse_highlight (f, x, y)
     }
 
   if (part == ON_VERTICAL_BORDER)
-    cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
+    {
+      cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
+      help_echo_string = build_string ("drag-mouse-1: resize");
+    }
   else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
           || part == ON_SCROLL_BAR)
     cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
@@ -23592,6 +24343,14 @@ otherwise.  */);
     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.
+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.
+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.
 If an integer, use that for both horizontal and vertical margins.
@@ -23659,7 +24418,7 @@ before automatic hscrolling will horizontally scroll the window.  */);
 
   DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
     doc: /* *How many columns to scroll the window when point gets too close to the edge.
-When point is less than `automatic-hscroll-margin' columns from the window
+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
 many columns.  If it's a positive floating-point number, it specifies the
@@ -23712,6 +24471,12 @@ whose contents depend on various data.  */);
               doc: /* Inhibit try_cursor_movement display optimization.  */);
   inhibit_try_cursor_movement = 0;
 #endif /* GLYPH_DEBUG */
+
+  DEFVAR_INT ("overline-margin", &overline_margin,
+              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.  */);
+  overline_margin = 2;
 }