Commit 58dd0aa4 authored by Eli Zaretskii's avatar Eli Zaretskii
Browse files

Fix bug #11832 with truncated lines when fringes are disabled on GUI frames.

 src/xdisp.c (init_iterator): Get dimensions of truncation and
 continuation glyphs even if on GUI frames.  Adjust
 it->last_visible_x on GUI frames when the left or right fringes,
 or both, are absent.
 (start_display, move_it_in_display_line_to): Handle the case of a
 GUI frame without a fringe to display continuation or truncation
 glyphs.
 (insert_left_trunc_glyphs): Support GUI frames: make sure
 truncation glyphs overwrite enough glyphs from the current line to
 have sufficient space in pixels.
 (display_line): Support truncation and continuation glyphs on GUI
 frames.  If some spare pixels are left on the line after inserting
 the truncation glyphs, fill that space with a stretch glyph of a
 suitably computed width.
 src/term.c (produce_special_glyphs): Call PRODUCE_GLYPHS, not
 produce_glyphs, to support GUI sessions.
parent 8a705674
2012-07-07 Eli Zaretskii <eliz@gnu.org>
Support truncation and continuation glyphs on GUI frames, when
fringes are disabled. (Bug#11832)
* xdisp.c (init_iterator): Get dimensions of truncation and
continuation glyphs even if on GUI frames. Adjust
it->last_visible_x on GUI frames when the left or right fringes,
or both, are absent.
(start_display, move_it_in_display_line_to): Handle the case of a
GUI frame without a fringe to display continuation or truncation
glyphs.
(insert_left_trunc_glyphs): Support GUI frames: make sure
truncation glyphs overwrite enough glyphs from the current line to
have sufficient space in pixels.
(display_line): Support truncation and continuation glyphs on GUI
frames. If some spare pixels are left on the line after inserting
the truncation glyphs, fill that space with a stretch glyph of a
suitably computed width.
* term.c (produce_special_glyphs): Call PRODUCE_GLYPHS, not
produce_glyphs, to support GUI sessions.
2012-07-07 Paul Eggert <eggert@cs.ucla.edu>
 
* sysdep.c (ULLONG_MAX): Define if not already defined (Bug#11781).
......
......@@ -1940,7 +1940,7 @@ produce_special_glyphs (struct it *it, enum display_element_type what)
temp_it.face_id = GLYPH_FACE (glyph);
temp_it.len = CHAR_BYTES (temp_it.c);
produce_glyphs (&temp_it);
PRODUCE_GLYPHS (&temp_it);
it->pixel_width = temp_it.pixel_width;
it->nglyphs = temp_it.pixel_width;
}
......
......@@ -2731,31 +2731,28 @@ init_iterator (struct it *it, struct window *w,
it->line_wrap = TRUNCATE;
 
/* Get dimensions of truncation and continuation glyphs. These are
displayed as fringe bitmaps under X, so we don't need them for such
frames. */
if (!FRAME_WINDOW_P (it->f))
displayed as fringe bitmaps under X, but we need them for such
frames when the fringes are turned off. */
if (it->line_wrap == TRUNCATE)
{
if (it->line_wrap == TRUNCATE)
{
/* We will need the truncation glyph. */
eassert (it->glyph_row == NULL);
produce_special_glyphs (it, IT_TRUNCATION);
it->truncation_pixel_width = it->pixel_width;
}
else
{
/* We will need the continuation glyph. */
eassert (it->glyph_row == NULL);
produce_special_glyphs (it, IT_CONTINUATION);
it->continuation_pixel_width = it->pixel_width;
}
/* Reset these values to zero because the produce_special_glyphs
above has changed them. */
it->pixel_width = it->ascent = it->descent = 0;
it->phys_ascent = it->phys_descent = 0;
/* We will need the truncation glyph. */
eassert (it->glyph_row == NULL);
produce_special_glyphs (it, IT_TRUNCATION);
it->truncation_pixel_width = it->pixel_width;
}
else
{
/* We will need the continuation glyph. */
eassert (it->glyph_row == NULL);
produce_special_glyphs (it, IT_CONTINUATION);
it->continuation_pixel_width = it->pixel_width;
}
 
/* Reset these values to zero because 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
continuation glyphs, so that we don't produce glyphs when calling
produce_special_glyphs, above. */
......@@ -2783,11 +2780,14 @@ init_iterator (struct it *it, struct window *w,
it->last_visible_x = (it->first_visible_x
+ window_box_width (w, TEXT_AREA));
 
/* If we truncate lines, leave room for the truncator glyph(s) at
/* If we truncate lines, leave room for the truncation glyph(s) at
the right margin. Otherwise, leave room for the continuation
glyph(s). Truncation and continuation glyphs are not inserted
for window-based redisplay. */
if (!FRAME_WINDOW_P (it->f))
glyph(s). Done only if the window has no fringes. Since we
don't know at this point whether there will be any R2L lines in
the window, we reserve space for truncation/continuation glyphs
even if only one of the fringes is absent. */
if (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
|| (it->bidi_p && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0))
{
if (it->line_wrap == TRUNCATE)
it->last_visible_x -= it->truncation_pixel_width;
......@@ -2923,7 +2923,10 @@ start_display (struct it *it, struct window *w, struct text_pos pos)
/* Or it fits exactly and we're on a window
system frame. */
|| (new_x == it->last_visible_x
&& FRAME_WINDOW_P (it->f))))
&& FRAME_WINDOW_P (it->f)
&& ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
? WINDOW_LEFT_FRINGE_WIDTH (it->w)
: WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
{
if ((it->current.dpvec_index >= 0
|| it->current.overlay_string_index >= 0)
......@@ -8327,7 +8330,10 @@ move_it_in_display_line_to (struct it *it,
/* Or it fits exactly and we're on a window
system frame. */
|| (new_x == it->last_visible_x
&& FRAME_WINDOW_P (it->f))))
&& FRAME_WINDOW_P (it->f)
&& ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
? WINDOW_LEFT_FRINGE_WIDTH (it->w)
: WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
{
if (/* IT->hpos == 0 means the very first glyph
doesn't fit on the line, e.g. a wide image. */
......@@ -8509,6 +8515,9 @@ move_it_in_display_line_to (struct it *it,
&& it->current_x >= it->last_visible_x)
{
if (!FRAME_WINDOW_P (it->f)
|| ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
? WINDOW_LEFT_FRINGE_WIDTH (it->w)
: WINDOW_RIGHT_FRINGE_WIDTH (it->w))
|| IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
{
int at_eob_p = 0;
......@@ -18203,11 +18212,8 @@ get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
}
 
 
/* Insert truncation glyphs at the start of IT->glyph_row. Truncation
glyphs are only inserted for terminal frames since we can't really
win with truncation glyphs when partially visible glyphs are
involved. Which glyphs to insert is determined by
produce_special_glyphs. */
/* Insert truncation glyphs at the start of IT->glyph_row. Which
glyphs to insert is determined by produce_special_glyphs. */
 
static void
insert_left_trunc_glyphs (struct it *it)
......@@ -18215,7 +18221,11 @@ insert_left_trunc_glyphs (struct it *it)
struct it truncate_it;
struct glyph *from, *end, *to, *toend;
 
eassert (!FRAME_WINDOW_P (it->f));
eassert (!FRAME_WINDOW_P (it->f)
|| (!it->glyph_row->reversed_p
&& WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
|| (it->glyph_row->reversed_p
&& WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0));
 
/* Get the truncation glyphs. */
truncate_it = *it;
......@@ -18230,20 +18240,66 @@ insert_left_trunc_glyphs (struct it *it)
/* Overwrite glyphs from IT with truncation glyphs. */
if (!it->glyph_row->reversed_p)
{
short tused = truncate_it.glyph_row->used[TEXT_AREA];
from = truncate_it.glyph_row->glyphs[TEXT_AREA];
end = from + truncate_it.glyph_row->used[TEXT_AREA];
end = from + tused;
to = it->glyph_row->glyphs[TEXT_AREA];
toend = to + it->glyph_row->used[TEXT_AREA];
if (FRAME_WINDOW_P (it->f))
{
/* On GUI frames, when variable-size fonts are displayed,
the truncation glyphs may need more pixels than the row's
glyphs they overwrite. We overwrite more glyphs to free
enough screen real estate, and enlarge the stretch glyph
on the right (see display_line), if there is one, to
preserve the screen position of the truncation glyphs on
the right. */
int w = 0;
struct glyph *g = to;
short used;
while (g < toend && it->glyph_row->x + w < 0)
{
w += g->pixel_width;
++g;
}
it->glyph_row->x = 0;
w = 0;
while (g < toend && w < it->truncation_pixel_width)
{
w += g->pixel_width;
++g;
}
if (g - to - tused > 0)
{
memmove (to + tused, g, toend - g);
it->glyph_row->used[TEXT_AREA] -= g - to - tused;
}
used = it->glyph_row->used[TEXT_AREA];
if (it->glyph_row->truncated_on_right_p
&& WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
&& it->glyph_row->glyphs[TEXT_AREA][used - 2].type
== STRETCH_GLYPH)
{
int extra = w - it->truncation_pixel_width;
it->glyph_row->glyphs[TEXT_AREA][used - 2].pixel_width += extra;
}
}
 
while (from < end)
*to++ = *from++;
 
/* There may be padding glyphs left over. Overwrite them too. */
while (to < toend && CHAR_GLYPH_PADDING_P (*to))
if (!FRAME_WINDOW_P (it->f))
{
from = truncate_it.glyph_row->glyphs[TEXT_AREA];
while (from < end)
*to++ = *from++;
while (to < toend && CHAR_GLYPH_PADDING_P (*to))
{
from = truncate_it.glyph_row->glyphs[TEXT_AREA];
while (from < end)
*to++ = *from++;
}
}
 
if (to > toend)
......@@ -18251,22 +18307,48 @@ insert_left_trunc_glyphs (struct it *it)
}
else
{
short tused = truncate_it.glyph_row->used[TEXT_AREA];
/* In R2L rows, overwrite the last (rightmost) glyphs, and do
that back to front. */
end = truncate_it.glyph_row->glyphs[TEXT_AREA];
from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
toend = it->glyph_row->glyphs[TEXT_AREA];
to = toend + it->glyph_row->used[TEXT_AREA] - 1;
if (FRAME_WINDOW_P (it->f))
{
int w = 0;
struct glyph *g = to;
while (g >= toend && w < it->truncation_pixel_width)
{
w += g->pixel_width;
--g;
}
if (to - g - tused > 0)
to = g + tused;
if (it->glyph_row->truncated_on_right_p
&& WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
&& it->glyph_row->glyphs[TEXT_AREA][1].type == STRETCH_GLYPH)
{
int extra = w - it->truncation_pixel_width;
it->glyph_row->glyphs[TEXT_AREA][1].pixel_width += extra;
}
}
 
while (from >= end && to >= toend)
*to-- = *from--;
while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
if (!FRAME_WINDOW_P (it->f))
{
from =
truncate_it.glyph_row->glyphs[TEXT_AREA]
+ truncate_it.glyph_row->used[TEXT_AREA] - 1;
while (from >= end && to >= toend)
*to-- = *from--;
while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
{
from =
truncate_it.glyph_row->glyphs[TEXT_AREA]
+ truncate_it.glyph_row->used[TEXT_AREA] - 1;
while (from >= end && to >= toend)
*to-- = *from--;
}
}
if (from >= end)
{
......@@ -19392,13 +19474,19 @@ display_line (struct it *it)
new_x > it->last_visible_x
/* Or it fits exactly on a window system frame. */
|| (new_x == it->last_visible_x
&& FRAME_WINDOW_P (it->f))))
&& FRAME_WINDOW_P (it->f)
&& (row->reversed_p
? WINDOW_LEFT_FRINGE_WIDTH (it->w)
: WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
{
/* End of a continued line. */
 
if (it->hpos == 0
|| (new_x == it->last_visible_x
&& FRAME_WINDOW_P (it->f)))
&& FRAME_WINDOW_P (it->f)
&& (row->reversed_p
? WINDOW_LEFT_FRINGE_WIDTH (it->w)
: WINDOW_RIGHT_FRINGE_WIDTH (it->w))))
{
/* Current glyph is the only one on the line or
fits exactly on the line. We must continue
......@@ -19509,6 +19597,10 @@ display_line (struct it *it)
window system frames. We leave the glyph in
this row and let it fill the row, but don't
consume the TAB. */
if ((row->reversed_p
? WINDOW_LEFT_FRINGE_WIDTH (it->w)
: WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
produce_special_glyphs (it, IT_CONTINUATION);
it->continuation_lines_width += it->last_visible_x;
row->ends_in_middle_of_char_p = 1;
row->continued_p = 1;
......@@ -19526,7 +19618,10 @@ display_line (struct it *it)
row->used[TEXT_AREA] = n_glyphs_before + i;
 
/* Display continuation glyphs. */
if (!FRAME_WINDOW_P (it->f))
if (!FRAME_WINDOW_P (it->f)
|| (row->reversed_p
? WINDOW_LEFT_FRINGE_WIDTH (it->w)
: WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
produce_special_glyphs (it, IT_CONTINUATION);
row->continued_p = 1;
 
......@@ -19633,12 +19728,15 @@ display_line (struct it *it)
/* If we truncate lines, we are done when the last displayed
glyphs reach past the right margin of the window. */
if (it->line_wrap == TRUNCATE
&& (FRAME_WINDOW_P (it->f)
&& (FRAME_WINDOW_P (it->f) && WINDOW_RIGHT_FRINGE_WIDTH (it->w)
? (it->current_x >= it->last_visible_x)
: (it->current_x > it->last_visible_x)))
{
/* Maybe add truncation glyphs. */
if (!FRAME_WINDOW_P (it->f))
if (!FRAME_WINDOW_P (it->f)
|| (row->reversed_p
? WINDOW_LEFT_FRINGE_WIDTH (it->w)
: WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
{
int i, n;
 
......@@ -19663,9 +19761,36 @@ display_line (struct it *it)
i = row->used[TEXT_AREA] - (i + 1);
}
 
for (n = row->used[TEXT_AREA]; i < n; ++i)
it->current_x = x_before;
if (!FRAME_WINDOW_P (it->f))
{
for (n = row->used[TEXT_AREA]; i < n; ++i)
{
row->used[TEXT_AREA] = i;
produce_special_glyphs (it, IT_TRUNCATION);
}
}
else
{
int stretch_width = it->last_visible_x - it->current_x;
row->used[TEXT_AREA] = i;
if (stretch_width > 0)
{
struct face *face = FACE_FROM_ID (it->f, it->face_id);
struct font *font =
face->font ? face->font : FRAME_FONT (it->f);
int stretch_ascent =
(((it->ascent + it->descent)
* FONT_BASE (font)) / FONT_HEIGHT (font));
struct text_pos saved_pos = it->position;
memset (&it->position, 0, sizeof it->position);
append_stretch_glyph (it, make_number (0), stretch_width,
it->ascent + it->descent,
stretch_ascent);
it->position = saved_pos;
}
produce_special_glyphs (it, IT_TRUNCATION);
}
}
......@@ -19684,6 +19809,7 @@ display_line (struct it *it)
row->exact_window_width_line_p = 1;
goto at_end_of_line;
}
it->current_x = x_before;
}
 
row->truncated_on_right_p = 1;
......@@ -19691,7 +19817,6 @@ display_line (struct it *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;
break;
}
}
......@@ -19704,7 +19829,10 @@ display_line (struct it *it)
if (it->first_visible_x
&& IT_CHARPOS (*it) != CHARPOS (row->start.pos))
{
if (!FRAME_WINDOW_P (it->f))
if (!FRAME_WINDOW_P (it->f)
|| (row->reversed_p
? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
: WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
insert_left_trunc_glyphs (it);
row->truncated_on_left_p = 1;
}
......@@ -21913,7 +22041,10 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st
if (it->first_visible_x
&& it_charpos > 0)
{
if (!FRAME_WINDOW_P (it->f))
if (!FRAME_WINDOW_P (it->f)
|| (row->reversed_p
? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
: WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
insert_left_trunc_glyphs (it);
row->truncated_on_left_p = 1;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment