static int invisible_text_between_p P_ ((struct it *, int, int));
#endif
-static int next_element_from_ellipsis P_ ((struct it *));
static void pint2str P_ ((char *, int, int));
static void pint2hrstr P_ ((char *, int, int));
static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
static void back_to_previous_visible_line_start P_ ((struct it *));
void reseat_at_previous_visible_line_start P_ ((struct it *));
static void reseat_at_next_visible_line_start P_ ((struct it *, int));
+static int next_element_from_ellipsis P_ ((struct it *));
static int next_element_from_display_vector P_ ((struct it *));
static int next_element_from_string P_ ((struct it *));
static int next_element_from_c_string P_ ((struct it *));
}
-/* Return 1 if position CHARPOS is visible in window W. Set *FULLY to
- 1 if POS is visible and the line containing POS is fully visible.
+/* Return 1 if position CHARPOS is visible in window W.
+ If visible, set *X and *Y to pixel coordinates of top left corner.
+ Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
and header-lines heights. */
int
-pos_visible_p (w, charpos, fully, x, y, exact_mode_line_heights_p)
+pos_visible_p (w, charpos, x, y, rtop, rbot, exact_mode_line_heights_p)
struct window *w;
- int charpos, *fully, *x, *y, exact_mode_line_heights_p;
+ int charpos, *x, *y, *rtop, *rbot, exact_mode_line_heights_p;
{
struct it it;
struct text_pos top;
- int visible_p;
+ int visible_p = 0;
struct buffer *old_buffer = NULL;
+ if (noninteractive)
+ return visible_p;
+
if (XBUFFER (w->buffer) != current_buffer)
{
old_buffer = current_buffer;
set_buffer_internal_1 (XBUFFER (w->buffer));
}
- *fully = visible_p = 0;
SET_TEXT_POS_FROM_MARKER (top, w->start);
/* Compute exact mode line heights, if requested. */
if (IT_CHARPOS (it) >= charpos)
{
int top_y = it.current_y;
- int bottom_y = line_bottom_y (&it);
+ 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;
- *fully = bottom_y <= it.last_visible_y;
- }
if (visible_p && x)
{
*x = it.current_x;
- *y = max (top_y + it.max_ascent - it.ascent, window_top_y);
+ *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
+ if (rtop)
+ {
+ *rtop = max (0, window_top_y - top_y);
+ *rbot = max (0, bottom_y - it.last_visible_y);
+ }
}
}
else if (it.current_y + it.max_ascent + it.max_descent > it.last_visible_y)
move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
*x = it2.current_x;
*y = it2.current_y + it2.max_ascent - it2.ascent;
+ if (rtop)
+ {
+ *rtop = 0;
+ *rbot = max (0, (it2.current_y + it2.max_ascent + it2.max_descent) - it.last_visible_y);
+ }
}
}
}
r.height = s->row->visible_height;
}
+ if (s->clip_head)
+ if (r.x < s->clip_head->x)
+ {
+ if (r.width >= s->clip_head->x - r.x)
+ r.width -= s->clip_head->x - r.x;
+ else
+ r.width = 0;
+ r.x = s->clip_head->x;
+ }
+ if (s->clip_tail)
+ if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
+ {
+ if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
+ r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
+ else
+ r.width = 0;
+ }
+
/* If S draws overlapping rows, it's sufficient to use the top and
bottom of the window for clipping because this glyph string
intentionally draws over other lines. */
if (s->hl == DRAW_CURSOR)
{
struct glyph *glyph = s->first_glyph;
- int height;
+ int height, max_y;
if (s->x > r.x)
{
}
r.width = min (r.width, glyph->pixel_width);
- /* Don't draw cursor glyph taller than our actual glyph. */
- height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
- if (height < r.height)
+ /* If r.y is below window bottom, ensure that we still see a cursor. */
+ height = min (glyph->ascent + glyph->descent,
+ min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
+ max_y = window_text_bottom_y (s->w) - height;
+ max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
+ if (s->ybase - glyph->ascent > max_y)
+ {
+ r.y = max_y;
+ r.height = height;
+ }
+ else
{
- int max_y = r.y + r.height;
- r.y = min (max_y, s->ybase + glyph->descent - height);
- r.height = min (max_y - r.y, height);
+ /* Don't draw cursor glyph taller than our actual glyph. */
+ height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
+ if (height < r.height)
+ {
+ max_y = r.y + r.height;
+ r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
+ r.height = min (max_y - r.y, height);
+ }
}
}
#endif
}
+
+/* EXPORT:
+ Return the position and height of the phys cursor in window W.
+ Set w->phys_cursor_width to width of phys cursor.
+*/
+
+int
+get_phys_cursor_geometry (w, row, glyph, heightp)
+ struct window *w;
+ struct glyph_row *row;
+ struct glyph *glyph;
+ int *heightp;
+{
+ struct frame *f = XFRAME (WINDOW_FRAME (w));
+ 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
+ rectangle as wide as the glyph, but use a canonical character
+ width instead. */
+ wd = glyph->pixel_width - 1;
+#ifdef HAVE_NTGUI
+ wd++; /* Why? */
+#endif
+ if (glyph->type == STRETCH_GLYPH
+ && !x_stretch_cursor_p)
+ wd = min (FRAME_COLUMN_WIDTH (f), wd);
+ w->phys_cursor_width = wd;
+
+ y = w->phys_cursor.y + row->ascent - glyph->ascent;
+
+ /* If y is below window bottom, ensure that we still see a cursor. */
+ h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
+
+ h = max (h0, glyph->ascent + glyph->descent);
+ h0 = min (h0, glyph->ascent + glyph->descent);
+
+ y0 = WINDOW_HEADER_LINE_HEIGHT (w);
+ if (y < y0)
+ {
+ h = max (h - (y0 - y) + 1, h0);
+ y = y0 - 1;
+ }
+ else
+ {
+ y0 = window_text_bottom_y (w) - h0;
+ if (y > y0)
+ {
+ h += y - y0;
+ y = y0;
+ }
+ }
+
+ *heightp = h - 1;
+ return WINDOW_TO_FRAME_PIXEL_Y (w, y);
+}
+
+
#endif /* HAVE_WINDOW_SYSTEM */
\f
check_it (it)
struct it *it;
{
- if (it->method == next_element_from_string)
+ if (it->method == GET_FROM_STRING)
{
xassert (STRINGP (it->string));
xassert (IT_STRING_CHARPOS (*it) >= 0);
else
{
xassert (IT_STRING_CHARPOS (*it) < 0);
- if (it->method == next_element_from_buffer)
+ if (it->method == GET_FROM_BUFFER)
{
/* Check that character and byte positions agree. */
xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
property for an image, the iterator will be set up for that
image, and we have to undo that setup first before we can
correct the overlay string index. */
- if (it->method == next_element_from_image)
+ if (it->method == GET_FROM_IMAGE)
pop_it (it);
/* We already have the first chunk of overlay strings in
it->string = it->overlay_strings[relative_index];
xassert (STRINGP (it->string));
it->current.string_pos = pos->string_pos;
- it->method = next_element_from_string;
+ it->method = GET_FROM_STRING;
}
#if 0 /* This is bogus because POS not having an overlay string
while (it->sp)
pop_it (it);
it->current.overlay_string_index = -1;
- it->method = next_element_from_buffer;
+ it->method = GET_FROM_BUFFER;
if (CHARPOS (pos->pos) == ZV)
it->overlay_strings_at_end_processed_p = 1;
}
{
/* Don't check for overlay strings below when set to deliver
characters from a display vector. */
- if (it->method == next_element_from_display_vector)
+ if (it->method == GET_FROM_DISPLAY_VECTOR)
handle_overlay_change_p = 0;
/* Handle overlay changes. */
/* Remember the current face id in case glyphs specify faces.
IT's face is restored in set_iterator_to_next. */
it->saved_face_id = it->face_id;
- it->method = next_element_from_display_vector;
+ it->method = GET_FROM_DISPLAY_VECTOR;
it->ellipsis_p = 1;
}
it->image_id = -1; /* no image */
it->position = start_pos;
it->object = NILP (object) ? it->w->buffer : object;
- it->method = next_element_from_image;
+ it->method = GET_FROM_IMAGE;
it->face_id = face_id;
/* Say that we haven't consumed the characters with
it->current.overlay_string_index = -1;
IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
it->end_charpos = it->string_nchars = SCHARS (it->string);
- it->method = next_element_from_string;
+ it->method = GET_FROM_STRING;
it->stop_charpos = 0;
it->string_from_display_prop_p = 1;
/* Say that we haven't consumed the characters with
}
else if (CONSP (value) && EQ (XCAR (value), Qspace))
{
- it->method = next_element_from_stretch;
+ it->method = GET_FROM_STRETCH;
it->object = value;
it->current.pos = it->position = start_pos;
}
it->image_id = lookup_image (it->f, value);
it->position = start_pos;
it->object = NILP (object) ? it->w->buffer : object;
- it->method = next_element_from_image;
+ it->method = GET_FROM_IMAGE;
/* Say that we haven't consumed the characters with
`display' property yet. The call to pop_it in
if (id >= 0)
{
- it->method = next_element_from_composition;
+ it->method = GET_FROM_COMPOSITION;
it->cmp_id = id;
it->cmp_len = COMPOSITION_LENGTH (prop);
/* For a terminal, draw only the first character of the
it->current.overlay_string_index = -1;
SET_TEXT_POS (it->current.string_pos, -1, -1);
it->n_overlay_strings = 0;
- it->method = next_element_from_buffer;
+ 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
it->string = it->overlay_strings[i];
it->multibyte_p = STRING_MULTIBYTE (it->string);
SET_TEXT_POS (it->current.string_pos, 0, 0);
- it->method = next_element_from_string;
+ it->method = GET_FROM_STRING;
it->stop_charpos = 0;
}
xassert (STRINGP (it->string));
it->end_charpos = SCHARS (it->string);
it->multibyte_p = STRING_MULTIBYTE (it->string);
- it->method = next_element_from_string;
+ it->method = GET_FROM_STRING;
}
else
{
it->string = Qnil;
it->current.overlay_string_index = -1;
- it->method = next_element_from_buffer;
+ it->method = GET_FROM_BUFFER;
}
CHECK_IT (it);
back_to_previous_visible_line_start (it)
struct it *it;
{
- int visible_p = 0;
-
- /* Go back one newline if not on BEGV already. */
- if (IT_CHARPOS (*it) > BEGV)
- back_to_previous_line_start (it);
-
- /* Move over lines that are invisible because of selective display
- or text properties. */
- while (IT_CHARPOS (*it) > BEGV
- && !visible_p)
+ while (IT_CHARPOS (*it) > BEGV)
{
- visible_p = 1;
+ back_to_previous_line_start (it);
+ if (IT_CHARPOS (*it) <= BEGV)
+ break;
/* If selective > 0, then lines indented more than that values
are invisible. */
if (it->selective > 0
&& indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
(double) it->selective)) /* iftc */
- visible_p = 0;
- else
- {
- Lisp_Object prop;
+ continue;
- /* Check the newline before point for invisibility. */
- prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
+ /* Check the newline before point for invisibility. */
+ {
+ Lisp_Object prop;
+ prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
Qinvisible, it->window);
- if (TEXT_PROP_MEANS_INVISIBLE (prop))
- visible_p = 0;
- }
-
-#if 0
- /* Commenting this out fixes the bug described in
- http://www.math.ku.dk/~larsh/emacs/emacs-loops-on-large-images/test-case.txt. */
- if (visible_p)
- {
- struct it it2 = *it;
-
- if (handle_display_prop (&it2) == HANDLED_RETURN)
- visible_p = 0;
- }
-#endif
+ if (TEXT_PROP_MEANS_INVISIBLE (prop))
+ continue;
+ }
- /* Back one more newline if the current one is invisible. */
- if (!visible_p)
- back_to_previous_line_start (it);
+ /* 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. */
+ {
+ struct it it2 = *it;
+ int pos = IT_CHARPOS (*it);
+ int beg, end;
+ Lisp_Object val, overlay;
+
+ 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;
+ }
+ }
+ break;
}
xassert (IT_CHARPOS (*it) >= BEGV);
IT_STRING_CHARPOS (*it) = -1;
IT_STRING_BYTEPOS (*it) = -1;
it->string = Qnil;
- it->method = next_element_from_buffer;
+ 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
it->string = string;
it->s = NULL;
it->end_charpos = it->string_nchars = SCHARS (string);
- it->method = next_element_from_string;
+ it->method = GET_FROM_STRING;
it->current.string_pos = string_pos (charpos, string);
}
else
it->end_charpos = it->string_nchars = strlen (s);
}
- it->method = next_element_from_c_string;
+ it->method = GET_FROM_C_STRING;
}
/* PRECISION > 0 means don't return more than PRECISION characters
Iteration
***********************************************************************/
+/* Map enum it_method value to corresponding next_element_from_* function. */
+
+static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) =
+{
+ next_element_from_buffer,
+ next_element_from_display_vector,
+ next_element_from_composition,
+ next_element_from_string,
+ next_element_from_c_string,
+ next_element_from_image,
+ next_element_from_stretch
+};
+
+
/* Load IT's display element fields with information about the next
display element from the current position of IT. Value is zero if
end of buffer (or C string) is reached. */
int success_p;
get_next:
- success_p = (*it->method) (it);
+ success_p = (*get_next_element[it->method]) (it);
if (it->what == IT_CHARACTER)
{
it->current.dpvec_index = 0;
it->dpvec_face_id = -1;
it->saved_face_id = it->face_id;
- it->method = next_element_from_display_vector;
+ it->method = GET_FROM_DISPLAY_VECTOR;
it->ellipsis_p = 0;
}
else
else if ((it->c < ' '
&& (it->area != TEXT_AREA
/* In mode line, treat \n like other crl chars. */
- || (it->c != '\n'
+ || (it->c != '\t'
&& it->glyph_row && it->glyph_row->mode_line_p)
|| (it->c != '\n' && it->c != '\t')))
|| (it->multibyte_p
it->current.dpvec_index = 0;
it->dpvec_face_id = face_id;
it->saved_face_id = it->face_id;
- it->method = next_element_from_display_vector;
+ it->method = GET_FROM_DISPLAY_VECTOR;
it->ellipsis_p = 0;
goto get_next;
}
moving the iterator to a new position might set them. */
it->start_of_box_run_p = it->end_of_box_run_p = 0;
- if (it->method == next_element_from_buffer)
+ switch (it->method)
{
+ case GET_FROM_BUFFER:
/* The current display element of IT is a character from
current_buffer. Advance in the buffer, and maybe skip over
invisible lines that are so because of selective display. */
IT_CHARPOS (*it) += 1;
xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
}
- }
- else if (it->method == next_element_from_composition)
- {
- xassert (it->cmp_id >= 0 && it ->cmp_id < n_compositions);
+ break;
+
+ case GET_FROM_COMPOSITION:
+ xassert (it->cmp_id >= 0 && it->cmp_id < n_compositions);
if (STRINGP (it->string))
{
IT_STRING_BYTEPOS (*it) += it->len;
IT_STRING_CHARPOS (*it) += it->cmp_len;
- it->method = next_element_from_string;
+ it->method = GET_FROM_STRING;
goto consider_string_end;
}
else
{
IT_BYTEPOS (*it) += it->len;
IT_CHARPOS (*it) += it->cmp_len;
- it->method = next_element_from_buffer;
+ it->method = GET_FROM_BUFFER;
}
- }
- else if (it->method == next_element_from_c_string)
- {
+ break;
+
+ case GET_FROM_C_STRING:
/* Current display element of IT is from a C string. */
IT_BYTEPOS (*it) += it->len;
IT_CHARPOS (*it) += 1;
- }
- else if (it->method == next_element_from_display_vector)
- {
+ break;
+
+ case GET_FROM_DISPLAY_VECTOR:
/* Current display element of IT is from a display table entry.
Advance in the display table definition. Reset it to null if
end reached, and continue with characters from buffers/
if (it->dpvec + it->current.dpvec_index == it->dpend)
{
if (it->s)
- it->method = next_element_from_c_string;
+ it->method = GET_FROM_C_STRING;
else if (STRINGP (it->string))
- it->method = next_element_from_string;
+ it->method = GET_FROM_STRING;
else
- it->method = next_element_from_buffer;
+ it->method = GET_FROM_BUFFER;
it->dpvec = NULL;
it->current.dpvec_index = -1;
/* Recheck faces after display vector */
it->stop_charpos = IT_CHARPOS (*it);
}
- }
- else if (it->method == next_element_from_string)
- {
+ break;
+
+ case GET_FROM_STRING:
/* Current display element is a character from a Lisp string. */
xassert (it->s == NULL && STRINGP (it->string));
IT_STRING_BYTEPOS (*it) += it->len;
&& it->sp > 0)
{
pop_it (it);
- if (!STRINGP (it->string))
- it->method = next_element_from_buffer;
- else
+ if (STRINGP (it->string))
goto consider_string_end;
+ it->method = GET_FROM_BUFFER;
}
}
- }
- else if (it->method == next_element_from_image
- || it->method == next_element_from_stretch)
- {
+ break;
+
+ case GET_FROM_IMAGE:
+ case GET_FROM_STRETCH:
/* The position etc with which we have to proceed are on
the stack. The position may be at the end of a string,
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 = next_element_from_string;
+ it->method = GET_FROM_STRING;
goto consider_string_end;
}
- else
- it->method = next_element_from_buffer;
+ it->method = GET_FROM_BUFFER;
+ break;
+
+ default:
+ /* There are no other methods defined, so this should be a bug. */
+ abort ();
}
- else
- /* There are no other methods defined, so this should be a bug. */
- abort ();
- xassert (it->method != next_element_from_string
+ xassert (it->method != GET_FROM_STRING
|| (STRINGP (it->string)
&& IT_STRING_CHARPOS (*it) >= 0));
}
was in IT->saved_face_id, and signal that it's there by
setting face_before_selective_p. */
it->saved_face_id = it->face_id;
- it->method = next_element_from_buffer;
+ it->method = GET_FROM_BUFFER;
reseat_at_next_visible_line_start (it, 1);
it->face_before_selective_p = 1;
}
saved_glyph_row = it->glyph_row;
it->glyph_row = NULL;
-#define BUFFER_POS_REACHED_P() \
- ((op & MOVE_TO_POS) != 0 \
- && BUFFERP (it->object) \
- && IT_CHARPOS (*it) >= to_charpos \
- && it->method == next_element_from_buffer)
+#define BUFFER_POS_REACHED_P() \
+ ((op & MOVE_TO_POS) != 0 \
+ && BUFFERP (it->object) \
+ && IT_CHARPOS (*it) >= to_charpos \
+ && (it->method == GET_FROM_BUFFER || \
+ (it->method == GET_FROM_DISPLAY_VECTOR && \
+ it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
+
while (1)
{
it->current_y -= it2.current_y;
it->current_x = it->hpos = 0;
- /* If we moved too far, move IT some lines forward. */
+ /* If we moved too far back, move IT some lines forward. */
if (it2.vpos > -dvpos)
{
int delta = it2.vpos + dvpos;
+ it2 = *it;
move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
+ /* Move back again if we got too far ahead. */
+ if (IT_CHARPOS (*it) >= start_charpos)
+ *it = it2;
}
}
}
in_display_vector_p (it)
struct it *it;
{
- return (it->method == next_element_from_display_vector
+ return (it->method == GET_FROM_DISPLAY_VECTOR
&& it->current.dpvec_index > 0
&& it->dpvec + it->current.dpvec_index != it->dpend);
}
/* Last displayed message is now the current message. */
echo_area_buffer[1] = echo_area_buffer[0];
+ /* Inform read_char that we're not echoing. */
+ echo_message_buffer = Qnil;
/* Prevent redisplay optimization in redisplay_internal by resetting
this_line_start_pos. This is done because the mini-buffer now
/* If centering point failed to make the whole line visible,
put point at the top instead. That has to make the whole line
visible, if it can be done. */
+ if (centering_position == 0)
+ goto done;
clear_glyph_matrix (w->desired_matrix);
centering_position = 0;
goto point_at_top;
bottom_vpos, dy);
if (first_unchanged_at_end_row)
- first_unchanged_at_end_row += dvpos;
+ {
+ first_unchanged_at_end_row += dvpos;
+ if (first_unchanged_at_end_row->y >= it.last_visible_y
+ || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
+ first_unchanged_at_end_row = NULL;
+ }
/* If scrolling up, there may be some lines to display at the end of
the window. */
/* Update window_end_pos and window_end_vpos. */
if (first_unchanged_at_end_row
- && first_unchanged_at_end_row->y < it.last_visible_y
&& !last_text_row_at_end)
{
/* Window end line if one of the preserved rows from the current
/* Record whether this row ends inside an ellipsis. */
row->ends_in_ellipsis_p
- = (it->method == next_element_from_display_vector
+ = (it->method == GET_FROM_DISPLAY_VECTOR
&& it->ellipsis_p);
/* Save fringe bitmaps in this row. */
{
struct glyph_string *head, *tail;
struct glyph_string *s;
+ struct glyph_string *clip_head = NULL, *clip_tail = NULL;
int last_x, area_width;
int x_reached;
int i, j;
start = i;
compute_overhangs_and_x (t, head->x, 1);
prepend_glyph_string_lists (&head, &tail, h, t);
+ clip_head = head;
}
/* Prepend glyph strings for glyphs in front of the first glyph
i = left_overwriting (head);
if (i >= 0)
{
+ clip_head = head;
BUILD_GLYPH_STRINGS (i, start, h, t,
DRAW_NORMAL_TEXT, dummy_x, last_x);
for (s = h; s; s = s->next)
DRAW_NORMAL_TEXT, x, last_x);
compute_overhangs_and_x (h, tail->x + tail->width, 0);
append_glyph_string_lists (&head, &tail, h, t);
+ clip_tail = tail;
}
/* Append glyph strings for glyphs following the last glyph
i = right_overwriting (tail);
if (i >= 0)
{
+ clip_tail = tail;
BUILD_GLYPH_STRINGS (end, i, h, t,
DRAW_NORMAL_TEXT, x, last_x);
for (s = h; s; s = s->next)
compute_overhangs_and_x (h, tail->x + tail->width, 0);
append_glyph_string_lists (&head, &tail, h, t);
}
+ if (clip_head || clip_tail)
+ for (s = head; s; s = s->next)
+ {
+ s->clip_head = clip_head;
+ s->clip_tail = clip_tail;
+ }
}
/* Draw all strings. */
completely. */
&& !overlaps_p)
{
- int x0 = head ? head->x : x;
- int x1 = tail ? tail->x + tail->background_width : x;
+ int x0 = clip_head ? clip_head->x : (head ? head->x : x);
+ int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
+ : (tail ? tail->x + tail->background_width : x));
int text_left = window_box_left (w, TEXT_AREA);
x0 -= text_left;
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. Backtrack if we
+ have a STOP object and previous row's end glyph came from STOP. */
+ if (!NILP (stop))
+ {
+ struct glyph_row *prev = row-1;
+ while ((prev = row - 1, prev >= first)
+ && MATRIX_ROW_END_CHARPOS (prev) == charpos
+ && prev->used[TEXT_AREA] > 0)
+ {
+ end = prev->glyphs[TEXT_AREA];
+ glyph = end + prev->used[TEXT_AREA];
+ while (--glyph >= end
+ && INTEGERP (glyph->object));
+ if (glyph >= end
+ && !EQ (stop, glyph->object))
+ break;
+ row = prev;
+ }
+ }
+
*x = row->x;
*y = row->y;
*vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
help_echo_pos = charpos;
}
}
- if (NILP (pointer))
- pointer = Fsafe_plist_get (XCDR (object), QCpointer);
}
+ if (NILP (pointer))
+ pointer = Fsafe_plist_get (XCDR (object), QCpointer);
}
if (STRINGP (string))
|| (r.y >= y0 && r.y < y1)
|| (r.y + r.height > y0 && r.y + r.height < y1))
{
- if (row->overlapping_p)
+ /* A header line may be overlapping, but there is no need
+ to fix overlapping areas for them. KFS 2005-02-12 */
+ if (row->overlapping_p && !row->mode_line_p)
{
if (first_overlapping_row == NULL)
first_overlapping_row = row;