]> code.delx.au - gnu-emacs/blobdiff - src/xdisp.c
(get_adstyle_property): Fix previous change.
[gnu-emacs] / src / xdisp.c
index 5509d1e65ed041824b1efe18bae55295a74eb8d2..7a01d60d5a70ca73a62162a8ba0b23ece2f06557 100644 (file)
@@ -1,7 +1,7 @@
 /* Display generation from window structure and buffer text.
    Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
                  1997, 1998, 1999, 2000, 2001, 2002, 2003,
-                 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+                 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -1349,21 +1349,27 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, rowh, vpos)
   move_it_to (&it, charpos, -1, it.last_visible_y-1, -1,
              (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
 
-  /* Note that we may overshoot because of invisible text.  */
   if (charpos >= 0 && IT_CHARPOS (it) >= charpos)
     {
+      /* We have reached CHARPOS, or passed it.  How the call to
+        move_it_to can overshoot: (i) If CHARPOS is on invisible
+        text, move_it_to stops at the end of the invisible text,
+        after CHARPOS.  (ii) If CHARPOS is in a display vector,
+        move_it_to stops on its last glyph.  */
       int top_x = it.current_x;
       int top_y = it.current_y;
+      enum it_method it_method = it.method;
+      /* Calling line_bottom_y may change it.method.  */
       int bottom_y = (last_height = 0, line_bottom_y (&it));
       int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
 
       if (top_y < window_top_y)
        visible_p = bottom_y > window_top_y;
       else if (top_y < it.last_visible_y)
-         visible_p = 1;
+       visible_p = 1;
       if (visible_p)
        {
-         if (it.method == GET_FROM_BUFFER)
+         if (it_method == GET_FROM_BUFFER)
            {
              Lisp_Object window, prop;
 
@@ -1381,12 +1387,37 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, rowh, vpos)
                  struct glyph *end = glyph + row->used[TEXT_AREA];
                  int x = row->x;
 
-                 for (; glyph < end && glyph->charpos < charpos; glyph++)
+                 for (; glyph < end
+                        && (!BUFFERP (glyph->object)
+                            || glyph->charpos < charpos);
+                      glyph++)
                    x += glyph->pixel_width;
-
                  top_x = x;
                }
            }
+         else if (it_method == GET_FROM_DISPLAY_VECTOR)
+           {
+             /* We stopped on the last glyph of a display vector.
+                Try and recompute.  Hack alert!  */
+             if (charpos < 2 || top.charpos >= charpos)
+               top_x = it.glyph_row->x;
+             else
+               {
+                 struct it it2;
+                 start_display (&it2, w, top);
+                 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
+                 get_next_display_element (&it2);
+                 PRODUCE_GLYPHS (&it2);
+                 if (ITERATOR_AT_END_OF_LINE_P (&it2)
+                     || it2.current_x > it2.last_visible_x)
+                   top_x = it.glyph_row->x;
+                 else
+                   {
+                     top_x = it2.current_x;
+                     top_y = it2.current_y;
+                   }
+               }
+           }
 
          *x = top_x;
          *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
@@ -5105,6 +5136,7 @@ push_it (it)
   p->voffset = it->voffset;
   p->string_from_display_prop_p = it->string_from_display_prop_p;
   p->display_ellipsis_p = 0;
+  p->line_wrap = it->line_wrap;
   ++it->sp;
 }
 
@@ -5160,6 +5192,7 @@ pop_it (it)
   it->font_height = p->font_height;
   it->voffset = p->voffset;
   it->string_from_display_prop_p = p->string_from_display_prop_p;
+  it->line_wrap = p->line_wrap;
 }
 
 
@@ -7206,7 +7239,8 @@ move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
            break;
        }
       else if (BUFFERP (it->object)
-              && it->method == GET_FROM_BUFFER
+              && (it->method == GET_FROM_BUFFER
+                  || it->method == GET_FROM_STRETCH)
               && IT_CHARPOS (*it) >= to_charpos)
        skip = MOVE_POS_MATCH_OR_ZV;
       else
@@ -14393,13 +14427,6 @@ try_window_reusing_current_matrix (w)
        if (display_line (&it))
          last_text_row = it.glyph_row - 1;
 
-      /* Give up If point isn't in a row displayed or reused.  */
-      if (w->cursor.vpos < 0)
-       {
-         clear_glyph_matrix (w->desired_matrix);
-         return 0;
-       }
-
       /* If point is in a reused row, adjust y and vpos of the cursor
         position.  */
       if (pt_row)
@@ -14408,6 +14435,16 @@ try_window_reusing_current_matrix (w)
          w->cursor.y -= first_reusable_row->y - start_row->y;
        }
 
+      /* Give up if point isn't in a row displayed or reused.  (This
+        also handles the case where w->cursor.vpos < nrows_scrolled
+        after the calls to display_line, which can happen with scroll
+        margins.  See bug#1295.)  */
+      if (w->cursor.vpos < 0)
+       {
+         clear_glyph_matrix (w->desired_matrix);
+         return 0;
+       }
+
       /* Scroll the display.  */
       run.current_y = first_reusable_row->y;
       run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
@@ -14464,11 +14501,15 @@ try_window_reusing_current_matrix (w)
          if (row < bottom_row)
            {
              struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
-             while (glyph->charpos < PT)
+             struct glyph *end = glyph + row->used[TEXT_AREA];
+
+             for (; glyph < end
+                    && (!BUFFERP (glyph->object)
+                        || glyph->charpos < PT);
+                  glyph++)
                {
                  w->cursor.hpos++;
                  w->cursor.x += glyph->pixel_width;
-                 glyph++;
                }
            }
        }
@@ -15651,7 +15692,7 @@ dump_glyph (row, glyph, area)
        fprintf (stderr,
                 "[%d-%d]",
                 glyph->u.cmp.from, glyph->u.cmp.to);
-      fprintf (stderr, " . %4d %1.1d%1.1d\n"
+      fprintf (stderr, " . %4d %1.1d%1.1d\n",
               glyph->face_id,
               glyph->left_box_line_p,
               glyph->right_box_line_p);
@@ -16467,7 +16508,13 @@ handle_line_prefix (struct it *it)
        prefix = Vline_prefix;
     }
   if (! NILP (prefix))
-    push_display_prop (it, prefix);
+    {
+      push_display_prop (it, prefix);
+      /* If the prefix is wider than the window, and we try to wrap
+        it, it would acquire its own wrap prefix, and so on till the
+        iterator stack overflows.  So, don't wrap the prefix.  */
+      it->line_wrap = TRUNCATE;
+    }
 }
 
 \f
@@ -19649,15 +19696,16 @@ fill_gstring_glyph_string (s, face_id, start, end, overlaps)
   last = s->row->glyphs[s->area] + end;
   s->cmp_id = glyph->u.cmp.id;
   s->cmp_from = glyph->u.cmp.from;
-  s->cmp_to = glyph->u.cmp.to;
+  s->cmp_to = glyph->u.cmp.to + 1;
   s->face = FACE_FROM_ID (s->f, face_id);
   lgstring = composition_gstring_from_id (s->cmp_id);
   s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
   glyph++;
   while (glyph < last
         && glyph->u.cmp.automatic
-        && glyph->u.cmp.id == s->cmp_id)
-    s->cmp_to = (glyph++)->u.cmp.to;
+        && glyph->u.cmp.id == s->cmp_id
+        && s->cmp_to == glyph->u.cmp.from)
+    s->cmp_to = (glyph++)->u.cmp.to + 1;
 
   for (i = s->cmp_from; i < s->cmp_to; i++)
     {
@@ -19866,7 +19914,7 @@ x_get_glyph_overhangs (glyph, f, left, right)
          struct font_metrics metrics;
 
          composition_gstring_width (gstring, glyph->u.cmp.from,
-                                    glyph->u.cmp.to, &metrics);
+                                    glyph->u.cmp.to + 1, &metrics);
          if (metrics.rbearing > metrics.width)
            *right = metrics.rbearing;
          if (metrics.lbearing < 0)
@@ -20614,7 +20662,7 @@ append_composite_glyph (it)
          glyph->u.cmp.automatic = 1;
          glyph->u.cmp.id = it->cmp_it.id;
          glyph->u.cmp.from = it->cmp_it.from;
-         glyph->u.cmp.to = it->cmp_it.to;
+         glyph->u.cmp.to = it->cmp_it.to - 1;
        }
       glyph->avoid_cursor_p = it->avoid_cursor_p;
       glyph->multibyte_p = it->multibyte_p;
@@ -25059,9 +25107,10 @@ all the functions in the list are called, with the frame as argument.  */);
 
   DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
     doc: /* List of functions to call before redisplaying a window with scrolling.
-Each function is called with two arguments, the window
-and its new display-start position.  Note that the value of `window-end'
-is not valid when these functions are called.  */);
+Each function is called with two arguments, the window and its new
+display-start position.  Note that these functions are also called by
+`set-window-buffer'.  Also note that the value of `window-end' is not
+valid when these functions are called.  */);
   Vwindow_scroll_functions = Qnil;
 
   DEFVAR_LISP ("window-text-change-functions",