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)
it->method = GET_FROM_STRING;
}
-#if 0 /* This is bogus because POS not having an overlay string
- position does not mean it's after the string. Example: A
- line starting with a before-string and initialization of IT
- to the previous row's end position. */
- else if (it->current.overlay_string_index >= 0)
- {
- /* If POS says we're already after an overlay string ending at
- POS, make sure to pop the iterator because it will be in
- front of that overlay string. When POS is ZV, we've thereby
- also ``processed'' overlay strings at ZV. */
- while (it->sp)
- pop_it (it);
- 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;
- }
-#endif /* 0 */
-
if (CHARPOS (pos->string_pos) >= 0)
{
/* Recorded position is not in an overlay string, but in another
{
if (it->ellipsis_p)
setup_for_ellipsis (it, 0);
+ /* When handling a display spec, we might load an
+ empty string. In that case, discard it here. We
+ used to discard it in handle_single_display_spec,
+ but that causes get_overlay_strings_1, above, to
+ ignore overlay strings that we must check. */
+ if (STRINGP (it->string) && !SCHARS (it->string))
+ pop_it (it);
return;
}
- it->ignore_overlay_strings_at_pos_p = 1;
- it->string_from_display_prop_p = 0;
- handle_overlay_change_p = 0;
+ else if (STRINGP (it->string) && !SCHARS (it->string))
+ pop_it (it);
+ else
+ {
+ 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
{
- int ret = handle_single_display_spec (it, prop, object, overlay,
- position, 0);
- if (ret < 0) /* Replaced by "", i.e. nothing. */
- return HANDLED_RECOMPUTE_PROPS;
- if (ret)
+ if (handle_single_display_spec (it, prop, object, overlay,
+ position, 0))
display_replaced_p = 1;
}
property ends.
Value is non-zero if something was found which replaces the display
- of buffer or string text. Specifically, the value is -1 if that
- "something" is "nothing". */
+ of buffer or string text. */
static int
handle_single_display_spec (it, spec, object, overlay, position,
if (STRINGP (value))
{
- if (SCHARS (value) == 0)
- {
- pop_it (it);
- return -1; /* Replaced by "", i.e. nothing. */
- }
it->string = value;
it->multibyte_p = STRING_MULTIBYTE (it->string);
it->current.overlay_string_index = -1;
if (it->cmp_it.id >= 0)
{
+ it->cmp_it.ch = -1;
it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
it->cmp_it.nglyphs = -1;
}
/* Save IT's settings. They are restored after all overlay
strings have been processed. */
xassert (!compute_stop_p || it->sp == 0);
- push_it (it);
+
+ /* When called from handle_stop, there might be an empty display
+ string loaded. In that case, don't bother saving it. */
+ if (!STRINGP (it->string) || SCHARS (it->string))
+ push_it (it);
/* Set up IT to deliver display elements from the first overlay
string. */
{
/* Automatic composition with glyph-string. */
Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
-
+
it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
}
else
if (it->face_box_p
&& it->s == NULL)
{
- int face_id;
- struct face *face;
+ if (it->method == GET_FROM_STRING && it->sp)
+ {
+ int face_id = underlying_face_id (it);
+ struct face *face = FACE_FROM_ID (it->f, face_id);
- it->end_of_box_run_p
- = ((face_id = face_after_it_pos (it),
- face_id != it->face_id)
- && (face = FACE_FROM_ID (it->f, face_id),
- face->box == FACE_NO_BOX));
+ if (face)
+ {
+ if (face->box == FACE_NO_BOX)
+ {
+ /* If the box comes from face properties in a
+ display string, check faces in that string. */
+ int string_face_id = face_after_it_pos (it);
+ it->end_of_box_run_p
+ = (FACE_FROM_ID (it->f, string_face_id)->box
+ == FACE_NO_BOX);
+ }
+ /* Otherwise, the box comes from the underlying face.
+ If this is the last string character displayed, check
+ the next buffer location. */
+ else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
+ && (it->current.overlay_string_index
+ == it->n_overlay_strings - 1))
+ {
+ EMACS_INT ignore;
+ int next_face_id;
+ struct text_pos pos = it->current.pos;
+ INC_TEXT_POS (pos, it->multibyte_p);
+
+ 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->end_of_box_run_p
+ = (FACE_FROM_ID (it->f, next_face_id)->box
+ == FACE_NO_BOX);
+ }
+ }
+ }
+ else
+ {
+ int face_id = face_after_it_pos (it);
+ it->end_of_box_run_p
+ = (face_id != it->face_id
+ && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
+ }
}
/* Value is 0 if end of buffer or string reached. */
{
int success_p = 1;
- /* Check this assumption, otherwise, we would never enter the
- if-statement, below. */
- xassert (IT_CHARPOS (*it) >= BEGV
- && IT_CHARPOS (*it) <= it->stop_charpos);
+ xassert (IT_CHARPOS (*it) >= BEGV);
if (IT_CHARPOS (*it) >= it->stop_charpos)
{
it->object = it->w->buffer;
it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
IT_BYTEPOS (*it), Qnil);
- }
+ }
return 1;
}
associated with the tab are displayed on the current
line. Since it->current_x does not include these glyphs,
we use it->last_visible_x instead. */
- it->continuation_lines_width +=
- (it->c == '\t') ? it->last_visible_x : it->current_x;
+ if (it->c == '\t')
+ {
+ it->continuation_lines_width += it->last_visible_x;
+ /* When moving by vpos, ensure that the iterator really
+ advances to the next line (bug#847, bug#969). Fixme:
+ do we need to do this in other circumstances? */
+ 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);
+ }
+ else
+ it->continuation_lines_width += it->current_x;
break;
default:
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);
}
sprintf (name, " *Echo Area %d*", i);
echo_buffer[i] = Fget_buffer_create (build_string (name));
XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
- /* to force word wrap in echo area -
+ /* to force word wrap in echo area -
it was decided to postpone this*/
/* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
while (CONSP (functions))
{
- call1 (XCAR (functions), frame);
+ if (!EQ (XCAR (functions), Qt))
+ call1 (XCAR (functions), frame);
functions = XCDR (functions);
}
UNGCPRO;
/* 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;
if (face_change_count)
++windows_or_buffers_changed;
- if (FRAME_TERMCAP_P (sf)
+ if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
&& FRAME_TTY (sf)->previous_frame != sf)
{
/* Since frames on a single ASCII terminal share the same
/* 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, it.last_visible_y - 1, -1,
- MOVE_TO_POS | MOVE_TO_Y);
+ 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;
if (scroll_down_p)
{
- /* 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);
-
+ /* 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;
- /* If moving by amount_to_scroll leaves STARTP unchanged,
- move it down one screen line. */
-
+ start_display (&it, w, startp);
move_it_vertically (&it, amount_to_scroll);
+
+ /* 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;
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);
/* Fill glyph string S with composition components specified by S->cmp.
BASE_FACE is the base face of the composition.
- S->gidx is the index of the first component for S.
+ S->cmp_from is the index of the first component for S.
OVERLAPS non-zero means S should draw the foreground only, and use
its physical height for clipping. See also draw_glyphs.
{
int i;
/* For all glyphs of this composition, starting at the offset
- S->gidx, until we reach the end of the definition or encounter a
+ S->cmp_from, until we reach the end of the definition or encounter a
glyph that requires the different face, add it to S. */
struct face *face;
xassert (s->nchars == 0);
xassert (start >= 0 && end > start);
- s->for_overlaps = overlaps,
+ s->for_overlaps = overlaps;
glyph = s->row->glyphs[s->area] + start;
last = s->row->glyphs[s->area] + end;
voffset = glyph->voffset;
for (s = head; s; s = s->next)
FRAME_RIF (f)->draw_glyph_string (s);
+#ifndef HAVE_NS
+ /* When focus a sole frame and move horizontally, this sets on_p to 0
+ causing a failure to erase prev cursor position. */
if (area == TEXT_AREA
&& !row->full_width_p
/* When drawing overlapping rows, only the glyph strings'
notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
row->y, MATRIX_ROW_BOTTOM_Y (row));
}
+#endif
/* Value is the x-position up to which drawn, relative to AREA of W.
This doesn't include parts drawn because of overhangs. */
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",