/* 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.
extern Lisp_Object Qmenu_item;
extern Lisp_Object Qwhen;
extern Lisp_Object Qhelp_echo;
+extern Lisp_Object Qbefore_string, Qafter_string;
Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
&& it->current_x == it->last_visible_x \
&& it->line_wrap != WORD_WRAP)
+#else /* !HAVE_WINDOW_SYSTEM */
+#define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
#endif /* HAVE_WINDOW_SYSTEM */
/* Test if the display element loaded in IT is a space or tab
int visible_p = 0;
struct buffer *old_buffer = NULL;
- if (noninteractive)
+ if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
return visible_p;
if (XBUFFER (w->buffer) != current_buffer)
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;
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);
it->current_x = it->hpos = 0;
}
}
-
-#if 0 /* Don't assert the following because start_display is sometimes
- called intentionally with a window start that is not at a
- line start. Please leave this code in as a comment. */
-
- /* Window start should be on a line start, now. */
- xassert (it->continuation_lines_width
- || IT_CHARPOS (it) == BEGV
- || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
-#endif /* 0 */
}
&next_stop,
(IT_CHARPOS (*it)
+ TEXT_PROP_DISTANCE_LIMIT),
- 0);
+ 0, it->base_face_id);
/* Is this a start of a run of characters with box face?
Caveat: this can be called for a freshly initialized
&next_stop,
base_face_id, 0);
-#if 0 /* This shouldn't be neccessary. Let's check it. */
- /* If IT is used to display a mode line we would really like to
- use the mode line face instead of the frame's default face. */
- if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
- && new_face_id == DEFAULT_FACE_ID)
- new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
-#endif
-
/* Is this a start of a run of characters with box? Caveat:
this can be called for a freshly allocated iterator; face_id
is -1 is this case. We know that the new face will not
it->region_beg_charpos,
it->region_end_charpos,
&next_check_charpos,
- limit, 0);
+ limit, 0, -1);
/* Correct the face for charsets different from ASCII. Do it
for the multibyte case only. The face returned above is
struct it *it;
int charpos;
{
- extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
+ extern Lisp_Object Qwindow, Qpriority;
Lisp_Object overlay, window, str, invisible;
struct Lisp_Overlay *ov;
int start, end;
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;
}
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;
}
if (success_p && it->dpvec == NULL)
{
Lisp_Object dv;
+ struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
if (it->dp
&& (dv = DISP_CHAR_VECTOR (it->dp, 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->glyph_row
+ && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
|| (it->c != '\n' && it->c != '\t'))
: (it->multibyte_p
? (!CHAR_PRINTABLE_P (it->c)
|| it->c == 0xAD /* SOFT HYPHEN */)))
: (it->c >= 127
&& (! unibyte_display_via_language_environment
- || (UNIBYTE_CHAR_HAS_MULTIBYTE_P (it->c)))))))
+ || (DECODE_CHAR (unibyte, it->c) <= 0xA0))))))
{
/* IT->c is a control character which must be displayed
either as '\003' or as `^C' where the '\\' and '^'
next_face_id = face_at_buffer_position
(it->w, CHARPOS (pos), it->region_beg_charpos,
it->region_end_charpos, &ignore,
- (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0);
+ (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0,
+ -1);
it->end_of_box_run_p
= (FACE_FROM_ID (it->f, next_face_id)->box
== FACE_NO_BOX);
}
set_iterator_to_next (it, 1);
-#ifdef HAVE_WINDOW_SYSTEM
- if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
+ /* One graphical terminals, newlines may
+ "overflow" into the fringe if
+ overflow-newline-into-fringe is non-nil.
+ On text-only terminals, newlines may
+ overflow into the last glyph on the
+ display line.*/
+ if (!FRAME_WINDOW_P (it->f)
+ || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
{
if (!get_next_display_element (it))
{
break;
}
}
-#endif /* HAVE_WINDOW_SYSTEM */
}
}
else
if (it->line_wrap == TRUNCATE
&& it->current_x >= it->last_visible_x)
{
-#ifdef HAVE_WINDOW_SYSTEM
- if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
+ if (!FRAME_WINDOW_P (it->f)
+ || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
{
if (!get_next_display_element (it)
|| BUFFER_POS_REACHED_P ())
break;
}
}
-#endif /* HAVE_WINDOW_SYSTEM */
result = MOVE_LINE_TRUNCATED;
break;
}
int op;
{
enum move_it_result skip, skip2 = MOVE_X_REACHED;
- int line_height;
- int reached = 0;
+ int line_height, line_start_x = 0, reached = 0;
for (;;)
{
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
if (it->current_x != it->last_visible_x
&& (op & MOVE_TO_VPOS)
&& !(op & (MOVE_TO_X | MOVE_TO_POS)))
- set_iterator_to_next (it, 0);
+ {
+ line_start_x = it->current_x + it->pixel_width
+ - it->last_visible_x;
+ set_iterator_to_next (it, 0);
+ }
}
else
it->continuation_lines_width += it->current_x;
/* Reset/increment for the next run. */
recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
- it->current_x = it->hpos = 0;
+ it->current_x = line_start_x;
+ line_start_x = 0;
+ it->hpos = 0;
it->current_y += it->max_ascent + it->max_descent;
++it->vpos;
last_height = it->max_ascent + it->max_descent;
value of nlines is > 0 if continuation lines were involved. */
if (nlines > 0)
move_it_by_lines (it, nlines, 1);
-#if 0
- /* I think this assert is bogus if buffer contains
- invisible text or images. KFS. */
- xassert (IT_CHARPOS (*it) <= start_pos);
-#endif
}
else
{
}
while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
}
-
-#if 0
- /* I think this assert is bogus if buffer contains
- invisible text or images. KFS. */
- xassert (IT_CHARPOS (*it) >= BEGV);
-#endif
}
}
}
struct frame *sf = SELECTED_FRAME ();
message_enable_multibyte = multibyte;
- if (noninteractive)
+ if (FRAME_INITIAL_P (sf))
{
if (noninteractive_need_newline)
putc ('\n', stderr);
struct frame *sf = SELECTED_FRAME ();
message_enable_multibyte = multibyte;
- if (noninteractive)
+ if (FRAME_INITIAL_P (sf))
{
if (noninteractive_need_newline)
putc ('\n', stderr);
putc ('\n', stderr);
noninteractive_need_newline = 0;
fprintf (stderr, m, SDATA (string));
- if (cursor_in_echo_area == 0)
+ if (!cursor_in_echo_area)
fprintf (stderr, "\n");
fflush (stderr);
}
struct frame *f;
int save_match_data;
{
-#if defined (USE_GTK) || defined (HAVE_NS) || USE_MAC_TOOLBAR
+#if defined (USE_GTK) || defined (HAVE_NS)
int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
#else
int do_update = WINDOWP (f->tool_bar_window)
struct it it;
struct glyph_row *row;
-#if defined (USE_GTK) || defined (HAVE_NS) || USE_MAC_TOOLBAR
+#if defined (USE_GTK) || defined (HAVE_NS)
if (FRAME_EXTERNAL_TOOL_BAR (f))
update_frame_tool_bar (f);
return 0;
/* No redisplay if running in batch mode or frame is not yet fully
initialized, or redisplay is explicitly turned off by setting
Vinhibit_redisplay. */
- if (noninteractive
+ if (FRAME_INITIAL_P (SELECTED_FRAME ())
|| !NILP (Vinhibit_redisplay))
return;
}
}
-
/* Notice any pending interrupt request to change frame size. */
do_pending_window_change (1);
if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
redisplay_windows (FRAME_ROOT_WINDOW (f));
+ /* The X error handler may have deleted that frame. */
+ if (!FRAME_LIVE_P (f))
+ continue;
+
/* Any scroll bars which redisplay_windows should have
nuked should now go away. */
if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
redisplay_windows (w->hchild);
else if (!NILP (w->vchild))
redisplay_windows (w->vchild);
- else
+ else if (!NILP (w->buffer))
{
displayed_buffer = XBUFFER (w->buffer);
/* Use list_of_error, not Qerror, so that
return 1;
}
return 0;
-
-#if 0
- /* This code used to try to scroll the window just enough to make
- the line visible. It returned 0 to say that the caller should
- allocate larger glyph matrices. */
-
- if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
- {
- int dy = row->height - row->visible_height;
- w->vscroll = 0;
- w->cursor.y += dy;
- shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
- }
- else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
- {
- int dy = - (row->height - row->visible_height);
- w->vscroll = dy;
- w->cursor.y += dy;
- shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
- }
-
- /* When we change the cursor y-position of the selected window,
- change this_line_y as well so that the display optimization for
- the cursor line of the selected window in redisplay_internal uses
- the correct y-position. */
- if (w == XWINDOW (selected_window))
- this_line_y = w->cursor.y;
-
- /* If vscrolling requires a larger glyph matrix, arrange for a fresh
- redisplay with larger matrices. */
- if (matrix->nrows < required_matrix_height (w))
- {
- fonts_changed_p = 1;
- return 0;
- }
-
- return 1;
-#endif /* 0 */
}
struct text_pos pos, startp;
struct it it;
int this_scroll_margin, scroll_max, rc, height;
- int dy = 0, amount_to_scroll = 0;
+ int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
Lisp_Object aggressive;
int scroll_limit = INT_MAX / FRAME_LINE_HEIGHT (f);
/* Compute scroll margin height in pixels. We scroll when point is
within this distance from the top or bottom of the window. */
if (scroll_margin > 0)
- {
- this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
- this_scroll_margin *= FRAME_LINE_HEIGHT (f);
- }
+ this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
+ * FRAME_LINE_HEIGHT (f);
else
this_scroll_margin = 0;
/* Force scroll_conservatively to have a reasonable value, to avoid
- overflow while computing how much to scroll. Note that it's
- fairly common for users to supply scroll-conservatively equal to
- `most-positive-fixnum', which can be larger than INT_MAX. */
+ overflow while computing how much to scroll. Note that the user
+ can supply scroll-conservatively equal to `most-positive-fixnum',
+ which can be larger than INT_MAX. */
if (scroll_conservatively > scroll_limit)
{
scroll_conservatively = scroll_limit;
too_near_end:
- /* Decide whether we have to scroll down. */
+ /* Decide whether to scroll down. */
if (PT > CHARPOS (startp))
{
int scroll_margin_y;
if (PT > CHARPOS (it.current.pos))
{
- /* Point is in the scroll margin at the bottom of the
- window, or below. Compute the distance from the scroll
- margin to PT, and give up if the distance is greater than
- scroll_max. */
- move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
+ int y0 = line_bottom_y (&it);
- /* To make point visible, we must move the window start down
- so that the cursor line is visible, which means we have
- to add in the height of the cursor line. */
- dy = line_bottom_y (&it) - scroll_margin_y;
+ /* Compute the distance from the scroll margin to PT
+ (including the height of the cursor line). Moving the
+ iterator unconditionally to PT can be slow if PT is far
+ away, so stop 10 lines past the window bottom (is there a
+ way to do the right thing quickly?). */
+ move_it_to (&it, PT, -1,
+ it.last_visible_y + 10 * FRAME_LINE_HEIGHT (f),
+ -1, MOVE_TO_POS | MOVE_TO_Y);
+ dy = line_bottom_y (&it) - y0;
if (dy > scroll_max)
return SCROLLING_FAILED;
+
+ scroll_down_p = 1;
}
}
- if (dy > 0)
+ if (scroll_down_p)
{
+ /* Point is in or below the bottom scroll margin, so move the
+ window start down. If scrolling conservatively, move it just
+ enough down to make point visible. If scroll_step is set,
+ move it down by scroll_step. */
if (scroll_conservatively)
- /* Set AMOUNT_TO_SCROLL to at least one line,
- and at most scroll_conservatively lines. */
amount_to_scroll
= min (max (dy, FRAME_LINE_HEIGHT (f)),
FRAME_LINE_HEIGHT (f) * scroll_conservatively);
if (amount_to_scroll <= 0)
return SCROLLING_FAILED;
- /* Move the window start down. If scrolling conservatively,
- move it just enough down to make point visible. If
- scroll_step is set, move it down by scroll_step. */
start_display (&it, w, startp);
move_it_vertically (&it, amount_to_scroll);
- /* If moving by amount_to_scroll leaves STARTP unchanged,
- move it down one screen line. */
+ /* If STARTP is unchanged, move it down another screen line. */
if (CHARPOS (it.current.pos) == CHARPOS (startp))
move_it_by_lines (&it, 1, 1);
startp = it.current.pos;
used_current_matrix_p = 1;
goto done;
-#if 0 /* try_cursor_movement never returns this value. */
- case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
- goto need_larger_matrices;
-#endif
-
case CURSOR_MOVEMENT_MUST_SCROLL:
goto try_to_scroll;
#ifdef HAVE_WINDOW_SYSTEM
if (FRAME_WINDOW_P (f))
{
-#if defined (USE_GTK) || defined (HAVE_NS) || USE_MAC_TOOLBAR
+#if defined (USE_GTK) || defined (HAVE_NS)
redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
#else
redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
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)
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);
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++;
}
}
}
else
abort ();
-#if 0 /* This leads to problems, for instance when the cursor is
- at ZV, and the cursor line displays no text. */
- /* Disable rows below what's displayed in the window. This makes
- debugging easier. */
- enable_glyph_matrix_rows (current_matrix,
- XFASTINT (w->window_end_vpos) + 1,
- bottom_vpos, 0);
-#endif
-
IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
debug_end_vpos = XFASTINT (w->window_end_vpos));
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);
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
display the cursor there under X. Set the charpos of the
first glyph of blank lines not corresponding to any text
to -1. */
-#ifdef HAVE_WINDOW_SYSTEM
if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
row->exact_window_width_line_p = 1;
- else
-#endif /* HAVE_WINDOW_SYSTEM */
- if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
- || row->used[TEXT_AREA] == 0)
+ else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
+ || row->used[TEXT_AREA] == 0)
{
row->glyphs[TEXT_AREA]->charpos = -1;
row->displays_text_p = 0;
goto back_to_wrap;
set_iterator_to_next (it, 1);
-#ifdef HAVE_WINDOW_SYSTEM
if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
{
if (!get_next_display_element (it))
row->exact_window_width_line_p = 1;
}
}
-#endif /* HAVE_WINDOW_SYSTEM */
}
}
else if (CHAR_GLYPH_PADDING_P (*glyph)
row->ends_in_newline_from_string_p = STRINGP (it->object);
-#ifdef HAVE_WINDOW_SYSTEM
/* Add a space at the end of the line that is used to
display the cursor there. */
if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
append_space_for_newline (it, 0);
-#endif /* HAVE_WINDOW_SYSTEM */
/* Extend the face to the end of the line. */
extend_face_to_end_of_line (it);
produce_special_glyphs (it, IT_TRUNCATION);
}
}
-#ifdef HAVE_WINDOW_SYSTEM
- else
+ else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
{
/* Don't truncate if we can overflow newline into fringe. */
- if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
+ if (!get_next_display_element (it))
{
- if (!get_next_display_element (it))
- {
- it->continuation_lines_width = 0;
- row->ends_at_zv_p = 1;
- row->exact_window_width_line_p = 1;
- break;
- }
- if (ITERATOR_AT_END_OF_LINE_P (it))
- {
- row->exact_window_width_line_p = 1;
- goto at_end_of_line;
- }
+ it->continuation_lines_width = 0;
+ row->ends_at_zv_p = 1;
+ row->exact_window_width_line_p = 1;
+ break;
+ }
+ if (ITERATOR_AT_END_OF_LINE_P (it))
+ {
+ row->exact_window_width_line_p = 1;
+ goto at_end_of_line;
}
}
-#endif /* HAVE_WINDOW_SYSTEM */
row->truncated_on_right_p = 1;
it->continuation_lines_width = 0;
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++)
{
{
struct composition *cmp = composition_table[glyph->u.cmp.id];
- if (cmp->rbearing - cmp->pixel_width)
+ if (cmp->rbearing > cmp->pixel_width)
*right = cmp->rbearing - cmp->pixel_width;
- if (cmp->lbearing < 0);
- *left = - cmp->lbearing;
+ if (cmp->lbearing < 0)
+ *left = - cmp->lbearing;
}
else
{
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;
+ *right = metrics.rbearing - metrics.width;
if (metrics.lbearing < 0)
*left = - metrics.lbearing;
}
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;
if (it->descent < 0)
it->descent = 0;
-#if 0 /* this breaks image tiling */
- /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
- int face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
- if (face_ascent > it->ascent)
- it->ascent = it->phys_ascent = face_ascent;
-#endif
-
it->nglyphs = 1;
if (face->box != FACE_NO_BOX)
{
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->char_to_display))
{
+ struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
+
+ /* get_next_display_element assures that this decoding
+ never fails. */
+ it->char_to_display = DECODE_CHAR (unibyte, it->c);
it->multibyte_p = 1;
it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display,
-1, Qnil);
\f
-/* Find the glyph matrix position of buffer position CHARPOS in window
- *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
- current glyphs must be up to date. If CHARPOS is above window
- start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
- of last line in W. In the row containing CHARPOS, stop before glyphs
- having STOP as object. */
-
-#if 1 /* This is a version of fast_find_position that's more correct
- in the presence of hscrolling, for example. I didn't install
- it right away because the problem fixed is minor, it failed
- in 20.x as well, and I think it's too risky to install
- so near the release of 21.1. 2001-09-25 gerd. */
+/* This function sets the mouse_face_* elements of DPYINFO, assuming
+ the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
+ window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
+ for the overlay or run of text properties specifying the mouse
+ face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
+ before-string and after-string that must also be highlighted.
+ DISPLAY_STRING, if non-nil, is a display string that may cover some
+ or all of the highlighted text. */
-static
-int
-fast_find_position (w, charpos, hpos, vpos, x, y, stop)
- struct window *w;
- EMACS_INT charpos;
- int *hpos, *vpos, *x, *y;
- Lisp_Object stop;
+static void
+mouse_face_from_buffer_pos (Lisp_Object window,
+ Display_Info *dpyinfo,
+ EMACS_INT mouse_charpos,
+ EMACS_INT start_charpos,
+ EMACS_INT end_charpos,
+ Lisp_Object before_string,
+ Lisp_Object after_string,
+ Lisp_Object display_string)
{
- struct glyph_row *row, *first;
+ struct window *w = XWINDOW (window);
+ struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
+ struct glyph_row *row;
struct glyph *glyph, *end;
- int past_end = 0;
+ EMACS_INT ignore;
+ int x;
+
+ xassert (NILP (display_string) || STRINGP (display_string));
+ xassert (NILP (before_string) || STRINGP (before_string));
+ xassert (NILP (after_string) || STRINGP (after_string));
- first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
- if (charpos < MATRIX_ROW_START_CHARPOS (first))
+ /* Find the first highlighted glyph. */
+ if (start_charpos < MATRIX_ROW_START_CHARPOS (first))
{
- *x = first->x;
- *y = first->y;
- *hpos = 0;
- *vpos = MATRIX_ROW_VPOS (first, w->current_matrix);
- return 1;
+ dpyinfo->mouse_face_beg_col = 0;
+ dpyinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (first, w->current_matrix);
+ dpyinfo->mouse_face_beg_x = first->x;
+ dpyinfo->mouse_face_beg_y = first->y;
+ }
+ else
+ {
+ row = row_containing_pos (w, start_charpos, first, NULL, 0);
+ if (row == NULL)
+ row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
+
+ /* If the before-string or display-string contains newlines,
+ row_containing_pos skips to its last row. Move back. */
+ if (!NILP (before_string) || !NILP (display_string))
+ {
+ struct glyph_row *prev;
+ while ((prev = row - 1, prev >= first)
+ && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
+ && prev->used[TEXT_AREA] > 0)
+ {
+ struct glyph *beg = prev->glyphs[TEXT_AREA];
+ glyph = beg + prev->used[TEXT_AREA];
+ while (--glyph >= beg && INTEGERP (glyph->object));
+ if (glyph < beg
+ || !(EQ (glyph->object, before_string)
+ || EQ (glyph->object, display_string)))
+ break;
+ row = prev;
+ }
+ }
+
+ glyph = row->glyphs[TEXT_AREA];
+ end = glyph + row->used[TEXT_AREA];
+ x = row->x;
+ dpyinfo->mouse_face_beg_y = row->y;
+ dpyinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (row, w->current_matrix);
+
+ /* Skip truncation glyphs at the start of the glyph row. */
+ if (row->displays_text_p)
+ for (; glyph < end
+ && INTEGERP (glyph->object)
+ && glyph->charpos < 0;
+ ++glyph)
+ x += glyph->pixel_width;
+
+ /* Scan the glyph row, stopping before BEFORE_STRING or
+ DISPLAY_STRING or START_CHARPOS. */
+ for (; glyph < end
+ && !INTEGERP (glyph->object)
+ && !EQ (glyph->object, before_string)
+ && !EQ (glyph->object, display_string)
+ && !(BUFFERP (glyph->object)
+ && glyph->charpos >= start_charpos);
+ ++glyph)
+ x += glyph->pixel_width;
+
+ dpyinfo->mouse_face_beg_x = x;
+ dpyinfo->mouse_face_beg_col = glyph - row->glyphs[TEXT_AREA];
}
- row = row_containing_pos (w, charpos, first, NULL, 0);
+ /* Find the last highlighted glyph. */
+ row = row_containing_pos (w, end_charpos, first, NULL, 0);
if (row == NULL)
{
row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
- past_end = 1;
+ dpyinfo->mouse_face_past_end = 1;
}
-
- /* If whole rows or last part of a row came from a display overlay,
- row_containing_pos will skip over such rows because their end pos
- equals the start pos of the overlay or interval.
-
- Move back if we have a STOP object and previous row's
- end glyph came from STOP. */
- if (!NILP (stop))
+ else if (!NILP (after_string))
{
- struct glyph_row *prev;
- while ((prev = row - 1, prev >= first)
- && MATRIX_ROW_END_CHARPOS (prev) == charpos
- && prev->used[TEXT_AREA] > 0)
- {
- struct glyph *beg = prev->glyphs[TEXT_AREA];
- glyph = beg + prev->used[TEXT_AREA];
- while (--glyph >= beg
- && INTEGERP (glyph->object));
- if (glyph < beg
- || !EQ (stop, glyph->object))
- break;
- row = prev;
- }
- }
+ /* If the after-string has newlines, advance to its last row. */
+ struct glyph_row *next;
+ struct glyph_row *last
+ = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
- *x = row->x;
- *y = row->y;
- *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
+ for (next = row + 1;
+ next <= last
+ && next->used[TEXT_AREA] > 0
+ && EQ (next->glyphs[TEXT_AREA]->object, after_string);
+ ++next)
+ row = next;
+ }
glyph = row->glyphs[TEXT_AREA];
end = glyph + row->used[TEXT_AREA];
+ x = row->x;
+ dpyinfo->mouse_face_end_y = row->y;
+ dpyinfo->mouse_face_end_row = MATRIX_ROW_VPOS (row, w->current_matrix);
- /* Skip over glyphs not having an object at the start of the row.
- These are special glyphs like truncation marks on terminal
- frames. */
+ /* Skip truncation glyphs at the start of the row. */
if (row->displays_text_p)
- while (glyph < end
+ for (; glyph < end
&& INTEGERP (glyph->object)
- && !EQ (stop, glyph->object)
- && glyph->charpos < 0)
- {
- *x += glyph->pixel_width;
- ++glyph;
- }
+ && glyph->charpos < 0;
+ ++glyph)
+ x += glyph->pixel_width;
- while (glyph < end
+ /* Scan the glyph row, stopping at END_CHARPOS or when we encounter
+ AFTER_STRING. */
+ for (; glyph < end
&& !INTEGERP (glyph->object)
- && !EQ (stop, glyph->object)
- && (!BUFFERP (glyph->object)
- || glyph->charpos < charpos))
- {
- *x += glyph->pixel_width;
- ++glyph;
- }
-
- *hpos = glyph - row->glyphs[TEXT_AREA];
- return !past_end;
-}
-
-#else /* not 1 */
-
-static int
-fast_find_position (w, pos, hpos, vpos, x, y, stop)
- struct window *w;
- EMACS_INT pos;
- int *hpos, *vpos, *x, *y;
- Lisp_Object stop;
-{
- int i;
- int lastcol;
- int maybe_next_line_p = 0;
- int line_start_position;
- int yb = window_text_bottom_y (w);
- struct glyph_row *row, *best_row;
- int row_vpos, best_row_vpos;
- int current_x;
-
- row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
- row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
+ && !EQ (glyph->object, after_string)
+ && !(BUFFERP (glyph->object) && glyph->charpos >= end_charpos);
+ ++glyph)
+ x += glyph->pixel_width;
- while (row->y < yb)
+ /* If we found AFTER_STRING, consume it and stop. */
+ if (EQ (glyph->object, after_string))
{
- if (row->used[TEXT_AREA])
- line_start_position = row->glyphs[TEXT_AREA]->charpos;
- else
- line_start_position = 0;
-
- if (line_start_position > pos)
- break;
- /* If the position sought is the end of the buffer,
- don't include the blank lines at the bottom of the window. */
- else if (line_start_position == pos
- && pos == BUF_ZV (XBUFFER (w->buffer)))
- {
- maybe_next_line_p = 1;
- break;
- }
- else if (line_start_position > 0)
- {
- best_row = row;
- best_row_vpos = row_vpos;
- }
-
- if (row->y + row->height >= yb)
- break;
-
- ++row;
- ++row_vpos;
+ for (; EQ (glyph->object, after_string) && glyph < end; ++glyph)
+ x += glyph->pixel_width;
}
-
- /* Find the right column within BEST_ROW. */
- lastcol = 0;
- current_x = best_row->x;
- for (i = 0; i < best_row->used[TEXT_AREA]; i++)
+ else
{
- struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
- int charpos = glyph->charpos;
+ /* If there's no after-string, we must check if we overshot,
+ which might be the case if we stopped after a string glyph.
+ That glyph may belong to a before-string or display-string
+ associated with the end position, which must not be
+ highlighted. */
+ Lisp_Object prev_object;
+ int pos;
- if (BUFFERP (glyph->object))
+ while (glyph > row->glyphs[TEXT_AREA])
{
- if (charpos == pos)
- {
- *hpos = i;
- *vpos = best_row_vpos;
- *x = current_x;
- *y = best_row->y;
- return 1;
- }
- else if (charpos > pos)
+ prev_object = (glyph - 1)->object;
+ if (!STRINGP (prev_object) || EQ (prev_object, display_string))
break;
- }
- else if (EQ (glyph->object, stop))
- break;
- if (charpos > 0)
- lastcol = i;
- current_x += glyph->pixel_width;
- }
+ pos = string_buffer_position (w, prev_object, end_charpos);
+ if (pos && pos < end_charpos)
+ break;
- /* If we're looking for the end of the buffer,
- and we didn't find it in the line we scanned,
- use the start of the following line. */
- if (maybe_next_line_p)
- {
- ++best_row;
- ++best_row_vpos;
- lastcol = 0;
- current_x = best_row->x;
+ for (; glyph > row->glyphs[TEXT_AREA]
+ && EQ ((glyph - 1)->object, prev_object);
+ --glyph)
+ x -= (glyph - 1)->pixel_width;
+ }
}
- *vpos = best_row_vpos;
- *hpos = lastcol + 1;
- *x = current_x;
- *y = best_row->y;
- return 0;
+ dpyinfo->mouse_face_end_x = x;
+ dpyinfo->mouse_face_end_col = glyph - row->glyphs[TEXT_AREA];
+ dpyinfo->mouse_face_window = window;
+ dpyinfo->mouse_face_face_id
+ = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
+ mouse_charpos + 1,
+ !dpyinfo->mouse_face_hidden, -1);
+ show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
}
-#endif /* not 1 */
-
/* Find the position of the glyph for position POS in OBJECT in
window W's current matrix, and return in *X, *Y the pixel
|| (OVERLAYP (dpyinfo->mouse_face_overlay)
&& mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
{
- /* Find the highest priority overlay that has a mouse-face
- property. */
+ /* Find the highest priority overlay with a mouse-face. */
overlay = Qnil;
for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
{
overlay = overlay_vec[i];
}
- /* If we're actually highlighting the same overlay as
- before, there's no need to do that again. */
- if (!NILP (overlay)
- && EQ (overlay, dpyinfo->mouse_face_overlay))
+ /* If we're highlighting the same overlay as before, there's
+ no need to do that again. */
+ if (!NILP (overlay) && EQ (overlay, dpyinfo->mouse_face_overlay))
goto check_help_echo;
-
dpyinfo->mouse_face_overlay = overlay;
/* Clear the display of the old active region, if any. */
if (NILP (overlay))
mouse_face = Fget_text_property (position, Qmouse_face, object);
- /* Handle the overlay case. */
- if (!NILP (overlay))
- {
- /* Find the range of text around this char that
- should be active. */
- Lisp_Object before, after;
- EMACS_INT ignore;
-
- before = Foverlay_start (overlay);
- after = Foverlay_end (overlay);
- /* Record this as the current active region. */
- fast_find_position (w, XFASTINT (before),
- &dpyinfo->mouse_face_beg_col,
- &dpyinfo->mouse_face_beg_row,
- &dpyinfo->mouse_face_beg_x,
- &dpyinfo->mouse_face_beg_y, Qnil);
-
- dpyinfo->mouse_face_past_end
- = !fast_find_position (w, XFASTINT (after),
- &dpyinfo->mouse_face_end_col,
- &dpyinfo->mouse_face_end_row,
- &dpyinfo->mouse_face_end_x,
- &dpyinfo->mouse_face_end_y, Qnil);
- dpyinfo->mouse_face_window = window;
-
- dpyinfo->mouse_face_face_id
- = face_at_buffer_position (w, pos, 0, 0,
- &ignore, pos + 1,
- !dpyinfo->mouse_face_hidden);
-
- /* Display it as active. */
- show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
- cursor = No_Cursor;
- }
- /* Handle the text property case. */
- else if (!NILP (mouse_face) && BUFFERP (object))
- {
- /* Find the range of text around this char that
- should be active. */
- Lisp_Object before, after, beginning, end;
- EMACS_INT ignore;
-
- beginning = Fmarker_position (w->start);
- end = make_number (BUF_Z (XBUFFER (object))
- - XFASTINT (w->window_end_pos));
- before
- = Fprevious_single_property_change (make_number (pos + 1),
- Qmouse_face,
- object, beginning);
- after
- = Fnext_single_property_change (position, Qmouse_face,
- object, end);
-
- /* Record this as the current active region. */
- fast_find_position (w, XFASTINT (before),
- &dpyinfo->mouse_face_beg_col,
- &dpyinfo->mouse_face_beg_row,
- &dpyinfo->mouse_face_beg_x,
- &dpyinfo->mouse_face_beg_y, Qnil);
- dpyinfo->mouse_face_past_end
- = !fast_find_position (w, XFASTINT (after),
- &dpyinfo->mouse_face_end_col,
- &dpyinfo->mouse_face_end_row,
- &dpyinfo->mouse_face_end_x,
- &dpyinfo->mouse_face_end_y, Qnil);
- dpyinfo->mouse_face_window = window;
-
- if (BUFFERP (object))
- dpyinfo->mouse_face_face_id
- = face_at_buffer_position (w, pos, 0, 0,
- &ignore, pos + 1,
- !dpyinfo->mouse_face_hidden);
-
- /* Display it as active. */
- show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
- cursor = No_Cursor;
- }
- else if (!NILP (mouse_face) && STRINGP (object))
+ /* Next, compute the bounds of the mouse highlighting and
+ display it. */
+ if (!NILP (mouse_face) && STRINGP (object))
{
+ /* The mouse-highlighting comes from a display string
+ with a mouse-face. */
Lisp_Object b, e;
EMACS_INT ignore;
- b = Fprevious_single_property_change (make_number (pos + 1),
- Qmouse_face,
- object, Qnil);
- e = Fnext_single_property_change (position, Qmouse_face,
- object, Qnil);
+ b = Fprevious_single_property_change
+ (make_number (pos + 1), Qmouse_face, object, Qnil);
+ e = Fnext_single_property_change
+ (position, Qmouse_face, object, Qnil);
if (NILP (b))
b = make_number (0);
if (NILP (e))
show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
cursor = No_Cursor;
}
- else if (STRINGP (object) && NILP (mouse_face))
+ else
{
- /* A string which doesn't have mouse-face, but
- the text ``under'' it might have. */
- struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
- int start = MATRIX_ROW_START_CHARPOS (r);
-
- pos = string_buffer_position (w, object, start);
- if (pos > 0)
- mouse_face = get_char_property_and_overlay (make_number (pos),
- Qmouse_face,
- w->buffer,
- &overlay);
- if (!NILP (mouse_face) && !NILP (overlay))
+ /* The mouse-highlighting, if any, comes from an overlay
+ or text property in the buffer. */
+ Lisp_Object buffer, display_string;
+
+ if (STRINGP (object))
{
- Lisp_Object before = Foverlay_start (overlay);
- Lisp_Object after = Foverlay_end (overlay);
- EMACS_INT ignore;
+ /* If we are on a display string with no mouse-face,
+ check if the text under it has one. */
+ struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
+ int start = MATRIX_ROW_START_CHARPOS (r);
+ pos = string_buffer_position (w, object, start);
+ if (pos > 0)
+ {
+ mouse_face = get_char_property_and_overlay
+ (make_number (pos), Qmouse_face, w->buffer, &overlay);
+ buffer = w->buffer;
+ display_string = object;
+ }
+ }
+ else
+ {
+ buffer = object;
+ display_string = Qnil;
+ }
+
+ if (!NILP (mouse_face))
+ {
+ Lisp_Object before, after;
+ Lisp_Object before_string, after_string;
+
+ if (NILP (overlay))
+ {
+ /* Handle the text property case. */
+ before = Fprevious_single_property_change
+ (make_number (pos + 1), Qmouse_face, buffer,
+ Fmarker_position (w->start));
+ after = Fnext_single_property_change
+ (make_number (pos), Qmouse_face, buffer,
+ make_number (BUF_Z (XBUFFER (buffer))
+ - XFASTINT (w->window_end_pos)));
+ before_string = after_string = Qnil;
+ }
+ else
+ {
+ /* Handle the overlay case. */
+ before = Foverlay_start (overlay);
+ after = Foverlay_end (overlay);
+ before_string = Foverlay_get (overlay, Qbefore_string);
+ after_string = Foverlay_get (overlay, Qafter_string);
+
+ if (!STRINGP (before_string)) before_string = Qnil;
+ if (!STRINGP (after_string)) after_string = Qnil;
+ }
- /* Note that we might not be able to find position
- BEFORE in the glyph matrix if the overlay is
- entirely covered by a `display' property. In
- this case, we overshoot. So let's stop in
- the glyph matrix before glyphs for OBJECT. */
- fast_find_position (w, XFASTINT (before),
- &dpyinfo->mouse_face_beg_col,
- &dpyinfo->mouse_face_beg_row,
- &dpyinfo->mouse_face_beg_x,
- &dpyinfo->mouse_face_beg_y,
- object);
-
- dpyinfo->mouse_face_past_end
- = !fast_find_position (w, XFASTINT (after),
- &dpyinfo->mouse_face_end_col,
- &dpyinfo->mouse_face_end_row,
- &dpyinfo->mouse_face_end_x,
- &dpyinfo->mouse_face_end_y,
- Qnil);
- dpyinfo->mouse_face_window = window;
- dpyinfo->mouse_face_face_id
- = face_at_buffer_position (w, pos, 0, 0,
- &ignore, pos + 1,
- !dpyinfo->mouse_face_hidden);
-
- /* Display it as active. */
- show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
+ mouse_face_from_buffer_pos (window, dpyinfo, pos,
+ XFASTINT (before),
+ XFASTINT (after),
+ before_string, after_string,
+ display_string);
cursor = No_Cursor;
}
}
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",
inhibit_menubar_update = 0;
DEFVAR_LISP ("wrap-prefix", &Vwrap_prefix,
- doc: /* Prefix added to the beginning of all continuation lines at display-time.
-May be a string, an image, or a stretch-glyph such as used by the
-`display' text-property.
+ doc: /* Prefix prepended to all continuation lines at display time.
+The value may be a string, an image, or a stretch-glyph; it is
+interpreted in the same way as the value of a `display' text property.
-This variable is overridden by any `wrap-prefix' text-property.
+This variable is overridden by any `wrap-prefix' text or overlay
+property.
-To add a prefix to non-continuation lines, use the `line-prefix' variable. */);
+To add a prefix to non-continuation lines, use `line-prefix'. */);
Vwrap_prefix = Qnil;
staticpro (&Qwrap_prefix);
Qwrap_prefix = intern ("wrap-prefix");
Fmake_variable_buffer_local (Qwrap_prefix);
DEFVAR_LISP ("line-prefix", &Vline_prefix,
- doc: /* Prefix added to the beginning of all non-continuation lines at display-time.
-May be a string, an image, or a stretch-glyph such as used by the
-`display' text-property.
+ doc: /* Prefix prepended to all non-continuation lines at display time.
+The value may be a string, an image, or a stretch-glyph; it is
+interpreted in the same way as the value of a `display' text property.
-This variable is overridden by any `line-prefix' text-property.
+This variable is overridden by any `line-prefix' text or overlay
+property.
-To add a prefix to continuation lines, use the `wrap-prefix' variable. */);
+To add a prefix to continuation lines, use `wrap-prefix'. */);
Vline_prefix = Qnil;
staticpro (&Qline_prefix);
Qline_prefix = intern ("line-prefix");