[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] /srv/bzr/emacs/trunk r108938: Fix bug #11832 with truncate
From: |
Eli Zaretskii |
Subject: |
[Emacs-diffs] /srv/bzr/emacs/trunk r108938: Fix bug #11832 with truncated lines when fringes are disabled on GUI frames. |
Date: |
Sat, 07 Jul 2012 19:36:02 +0300 |
User-agent: |
Bazaar (2.5.0) |
------------------------------------------------------------
revno: 108938
fixes bug: http://debbugs.gnu.org/11832
committer: Eli Zaretskii <address@hidden>
branch nick: trunk
timestamp: Sat 2012-07-07 19:36:02 +0300
message:
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.
modified:
src/ChangeLog
src/term.c
src/xdisp.c
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog 2012-07-07 03:06:00 +0000
+++ b/src/ChangeLog 2012-07-07 16:36:02 +0000
@@ -1,3 +1,25 @@
+2012-07-07 Eli Zaretskii <address@hidden>
+
+ 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 <address@hidden>
* sysdep.c (ULLONG_MAX): Define if not already defined (Bug#11781).
=== modified file 'src/term.c'
--- a/src/term.c 2012-07-05 18:35:48 +0000
+++ b/src/term.c 2012-07-07 16:36:02 +0000
@@ -1940,7 +1940,7 @@
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;
}
=== modified file 'src/xdisp.c'
--- a/src/xdisp.c 2012-07-05 18:35:48 +0000
+++ b/src/xdisp.c 2012-07-07 16:36:02 +0000
@@ -2731,30 +2731,27 @@
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))
- {
- 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;
- }
+ displayed as fringe bitmaps under X, but we need them for such
+ frames when the fringes are turned off. */
+ 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;
- }
+ /* 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
@@ -2783,11 +2780,14 @@
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 @@
/* 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 @@
/* 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 @@
&& 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 @@
}
-/* 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 @@
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 @@
/* 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 @@
}
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 @@
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 @@
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 @@
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 @@
/* 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 @@
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 @@
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 @@
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 @@
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 @@
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;
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] /srv/bzr/emacs/trunk r108938: Fix bug #11832 with truncated lines when fringes are disabled on GUI frames.,
Eli Zaretskii <=