static void reseat_1 P_ ((struct it *, struct text_pos, int));
static void back_to_previous_visible_line_start P_ ((struct it *));
static 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_display_vector P_ ((struct it *));
static int next_element_from_string P_ ((struct it *));
static int next_element_from_c_string P_ ((struct it *));
/* Reset these values to zero becaue the produce_special_glyphs
above has changed them. */
it->pixel_width = it->ascent = it->descent = 0;
+ it->phys_ascent = it->phys_descent = 0;
}
/* Set this after getting the dimensions of truncation and
/* Reseat iterator IT on the next visible line start in the current
- buffer. Skip over invisible text that is so because of selective
- display. Compute faces, overlays etc at the new position. Note
- that this function does not skip over text that is invisible
- because of text properties. */
+ buffer. ON_NEWLINE_P non-zero means position IT on the newline
+ preceding the line start. Skip over invisible text that is so
+ because of selective display. Compute faces, overlays etc at the
+ new position. Note that this function does not skip over text that
+ is invisible because of text properties. */
static void
-reseat_at_next_visible_line_start (it)
+reseat_at_next_visible_line_start (it, on_newline_p)
struct it *it;
+ int on_newline_p;
{
/* Restore the buffer position when currently not delivering display
elements from the current buffer. This is the case, for example,
&& indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
it->selective))
forward_to_next_line_start (it);
+
+ /* Position on the newline if we should. */
+ if (on_newline_p && IT_CHARPOS (*it) > BEGV)
+ {
+ --IT_CHARPOS (*it);
+ IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
+ }
/* Set the iterator there. The 0 as the last parameter of
reseat means don't force a text property lookup. The lookup
current_buffer. Advance in the buffer, and maybe skip over
invisible lines that are so because of selective display. */
if (ITERATOR_AT_END_OF_LINE_P (it))
- reseat_at_next_visible_line_start (it);
+ reseat_at_next_visible_line_start (it, 0);
else
{
xassert (it->len != 0);
it->dpvec = NULL;
it->current.dpvec_index = -1;
- /* Consume the character which was displayed via IT->dpvec. */
- if (it->dpvec_char_len)
+ /* Skip over characters which were displayed via IT->dpvec. */
+ if (it->dpvec_char_len < 0)
+ reseat_at_next_visible_line_start (it, 1);
+ else if (it->dpvec_char_len > 0)
{
it->len = it->dpvec_char_len;
set_iterator_to_next (it);
&& indented_beyond_p (IT_CHARPOS (*it) + 1,
IT_BYTEPOS (*it) + 1,
it->selective))
- next_element_from_ellipsis (it);
+ {
+ next_element_from_ellipsis (it);
+ it->dpvec_char_len = -1;
+ }
}
else if (it->c == '\r' && it->selective == -1)
{
CR to the end of the line is invisible, with maybe an
ellipsis displayed for it. */
next_element_from_ellipsis (it);
+ it->dpvec_char_len = -1;
}
}
}
case MOVE_LINE_TRUNCATED:
it->continuation_lines_width = 0;
- reseat_at_next_visible_line_start (it);
+ reseat_at_next_visible_line_start (it, 0);
if ((op & MOVE_TO_POS) != 0
&& IT_CHARPOS (*it) > to_charpos)
goto out;
/* If line is empty, make it occupy the rest of the toolbar. */
if (!row->displays_text_p)
{
- row->height = it->last_visible_y - row->y;
- row->ascent = 0;
+ row->height = row->phys_height = it->last_visible_y - row->y;
+ row->ascent = row->phys_ascent = 0;
}
row->full_width_p = 1;
if (row->height == 0)
{
if (it->max_ascent + it->max_descent == 0)
- it->max_descent = CANON_Y_UNIT (it->f);
+ it->max_descent = it->max_phys_descent = CANON_Y_UNIT (it->f);
row->ascent = it->max_ascent;
row->height = it->max_ascent + it->max_descent;
+ row->phys_ascent = it->max_phys_ascent;
+ row->phys_height = it->max_phys_ascent + it->max_phys_descent;
}
/* Compute the width of this line. */
xassert (row->pixel_width >= 0);
xassert (row->ascent >= 0 && row->height > 0);
+ row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
+ || MATRIX_ROW_OVERLAPS_PRED_P (row));
+
+ /* If first line's physical ascent is larger than its logical
+ ascent, use the physical ascent, and make the row taller.
+ This makes accented characters fully visible. */
+ if (row == it->w->desired_matrix->rows
+ && row->phys_ascent > row->ascent)
+ {
+ row->height += row->phys_ascent - row->ascent;
+ row->ascent = row->phys_ascent;
+ }
+
/* Compute how much of the line is visible. */
row->visible_height = row->height;
else
{
row->pixel_width = row->used[TEXT_AREA];
- row->ascent = 0;
- row->height = row->visible_height = 1;
+ row->ascent = row->phys_ascent = 0;
+ row->height = row->phys_height = row->visible_height = 1;
}
/* Compute a hash code for this row. */
+ (row->glyphs[area][i].type << 2));
it->max_ascent = it->max_descent = 0;
+ it->max_phys_ascent = it->max_phys_descent = 0;
}
text hscrolled, if there is any, or zero. */
row->ascent = it->max_ascent;
row->height = it->max_ascent + it->max_descent;
+ row->phys_ascent = it->max_phys_ascent;
+ row->phys_height = it->max_phys_ascent + it->max_phys_descent;
/* Loop generating characters. The loop is left with IT on the next
character to display. */
{
row->ascent = max (row->ascent, it->max_ascent);
row->height = max (row->height, it->max_ascent + it->max_descent);
+ row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
+ row->phys_height = max (row->phys_height,
+ it->max_phys_ascent + it->max_phys_descent);
set_iterator_to_next (it);
continue;
}
++it->hpos;
row->ascent = max (row->ascent, it->max_ascent);
row->height = max (row->height, it->max_ascent + it->max_descent);
+ row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
+ row->phys_height = max (row->phys_height,
+ it->max_phys_ascent + it->max_phys_descent);
if (it->current_x - it->pixel_width < it->first_visible_x)
row->x = x - it->first_visible_x;
}
row->ascent = max (row->ascent, it->max_ascent);
row->height = max (row->height, it->max_ascent + it->max_descent);
+ row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
+ row->phys_height = max (row->phys_height,
+ it->max_phys_ascent + it->max_phys_descent);
/* End of this display line if row is continued. */
if (row->continued_p)
row->truncated_on_right_p = 1;
it->continuation_lines_width = 0;
- reseat_at_next_visible_line_start (it);
+ reseat_at_next_visible_line_start (it, 0);
row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
it->hpos = hpos_before;
it->current_x = x_before;
row->ascent = it->max_ascent;
row->height = it->max_ascent + it->max_descent;
+ row->phys_ascent = it->max_phys_ascent;
+ row->phys_height = it->max_phys_ascent + it->max_phys_descent;
/* This condition is for the case that we are called with current_x
past last_visible_x. */
row->ascent = max (row->ascent, it->max_ascent);
row->height = max (row->height, it->max_ascent + it->max_descent);
+ row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
+ row->phys_height = max (row->phys_height,
+ it->max_phys_ascent + it->max_phys_descent);
x += glyph->pixel_width;
++i;
}