[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] /srv/bzr/emacs/trunk r99950: Implement GUI display of R2L
From: |
Eli Zaretskii |
Subject: |
[Emacs-diffs] /srv/bzr/emacs/trunk r99950: Implement GUI display of R2L lines, fix TTY display of R2L lines. |
Date: |
Tue, 20 Apr 2010 16:31:28 +0300 |
User-agent: |
Bazaar (2.0.3) |
------------------------------------------------------------
revno: 99950 [merge]
committer: Eli Zaretskii <address@hidden>
branch nick: trunk
timestamp: Tue 2010-04-20 16:31:28 +0300
message:
Implement GUI display of R2L lines, fix TTY display of R2L lines.
xdisp.c [HAVE_WINDOW_SYSTEM]: Add prototype for
append_stretch_glyph.
(set_cursor_from_row) <cursor_x>: Remove unused variable. Fix
off-by-one error in computing x at end of text in the row.
(append_stretch_glyph): In reversed row, prepend the glyph rather
than append it. Set resolved_level and bidi_type of the glyph.
(extend_face_to_end_of_line): If the row is reversed, prepend a
stretch glyph whose width is such that the rightmost glyph will be
drawn at the right margin of the window. Fix off-by-one error on
TTY frames in testing whether a line needs face extension. Fix
face extension at ZV. If this is the last glyph row, use
DEFAULT_FACE_ID, to avoid painting the rest of the window with the
region face.
(set_cursor_from_row, display_line): Use
MATRIX_ROW_CONTINUATION_LINE_P instead of testing value of
row->continuation_lines_width.
(next_element_from_buffer): Don't call bidi_paragraph_init if we
are at ZV. Fixes a crash when reseated to ZV by
try_window_reusing_current_matrix.
(display_and_set_cursor, erase_phys_cursor): Handle negative HPOS,
which happens with R2L glyph rows. Fixes a crash when inserting a
character at end of an R2L line.
(set_cursor_from_row): Don't be fooled by truncated rows: don't
treat them as having zero-width characters. Improve comments.
Don't reverse pos_before and pos_after for reversed glyph rows.
Set cursor.x to negative value when the cursor might be on the
left fringe.
(IT_OVERFLOW_NEWLINE_INTO_FRINGE): For R2L lines, consider the
left fringe, not the right one.
(notice_overwritten_cursor, draw_phys_cursor_glyph)
(erase_phys_cursor): For reversed cursor_row, support cursor on
the left fringe.
fringe.c (update_window_fringes): For R2L rows, swap the bitmaps
of continuation indicators on the fringes.
(draw_fringe_bitmap): For reversed glyph rows, allow cursor on the
left fringe.
w32term.c (w32_draw_window_cursor): For reversed glyph rows,
draw cursor on the left fringe.
xterm.c (x_draw_window_cursor): For reversed glyph rows, draw
cursor on the left fringe.
dispnew.c (update_text_area): Handle reversed desired rows when
the cursor is on the left fringe.
(set_window_cursor_after_update): Limit cursor's hpos by -1 from
below, not by 0, for when the cursor is on the left fringe.
xdisp.c (unproduce_glyphs): New function.
(display_line): Use it when produced glyphs are discarded from R2L
glyph rows.
(append_composite_glyph): In R2L rows, prepend the glyph rather
than appending it.
term.c (append_composite_glyph): In R2L rows, prepend the glyph
rather than append it. Set up the resolved_level and bidi_type
attributes of the appended glyph.
(produce_special_glyphs): Mirror the backslash continuation
character in R2L lines.
modified:
src/ChangeLog
src/dispnew.c
src/fringe.c
src/term.c
src/w32term.c
src/xdisp.c
src/xterm.c
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog 2010-04-20 11:38:30 +0000
+++ b/src/ChangeLog 2010-04-20 13:31:28 +0000
@@ -1,3 +1,70 @@
+2010-04-20 Eli Zaretskii <address@hidden>
+
+ Fix R2L paragraph display on TTY.
+
+ * xdisp.c (unproduce_glyphs): New function.
+ (display_line): Use it when produced glyphs are discarded from R2L
+ glyph rows.
+ (append_composite_glyph): In R2L rows, prepend the glyph rather
+ than appending it.
+
+ * term.c (append_composite_glyph): In R2L rows, prepend the glyph
+ rather than append it. Set up the resolved_level and bidi_type
+ attributes of the appended glyph.
+ (produce_special_glyphs): Mirror the backslash continuation
+ character in R2L lines.
+
+ Implement display of R2L paragraphs in GUI sessions.
+
+ * xdisp.c [HAVE_WINDOW_SYSTEM]: Add prototype for
+ append_stretch_glyph.
+ (set_cursor_from_row) <cursor_x>: Remove unused variable. Fix
+ off-by-one error in computing x at end of text in the row.
+ (append_stretch_glyph): In reversed row, prepend the glyph rather
+ than append it. Set resolved_level and bidi_type of the glyph.
+ (extend_face_to_end_of_line): If the row is reversed, prepend a
+ stretch glyph whose width is such that the rightmost glyph will be
+ drawn at the right margin of the window. Fix off-by-one error on
+ TTY frames in testing whether a line needs face extension. Fix
+ face extension at ZV. If this is the last glyph row, use
+ DEFAULT_FACE_ID, to avoid painting the rest of the window with the
+ region face.
+ (set_cursor_from_row, display_line): Use
+ MATRIX_ROW_CONTINUATION_LINE_P instead of testing value of
+ row->continuation_lines_width.
+ (next_element_from_buffer): Don't call bidi_paragraph_init if we
+ are at ZV. Fixes a crash when reseated to ZV by
+ try_window_reusing_current_matrix.
+ (display_and_set_cursor, erase_phys_cursor): Handle negative HPOS,
+ which happens with R2L glyph rows. Fixes a crash when inserting a
+ character at end of an R2L line.
+ (set_cursor_from_row): Don't be fooled by truncated rows: don't
+ treat them as having zero-width characters. Improve comments.
+ Don't reverse pos_before and pos_after for reversed glyph rows.
+ Set cursor.x to negative value when the cursor might be on the
+ left fringe.
+ (IT_OVERFLOW_NEWLINE_INTO_FRINGE): For R2L lines, consider the
+ left fringe, not the right one.
+ (notice_overwritten_cursor, draw_phys_cursor_glyph)
+ (erase_phys_cursor): For reversed cursor_row, support cursor on
+ the left fringe.
+
+ * fringe.c (update_window_fringes): For R2L rows, swap the bitmaps
+ of continuation indicators on the fringes.
+ (draw_fringe_bitmap): For reversed glyph rows, allow cursor on the
+ left fringe.
+
+ * w32term.c (w32_draw_window_cursor): For reversed glyph rows,
+ draw cursor on the left fringe.
+
+ * xterm.c (x_draw_window_cursor): For reversed glyph rows, draw
+ cursor on the left fringe.
+
+ * dispnew.c (update_text_area): Handle reversed desired rows when
+ the cursor is on the left fringe.
+ (set_window_cursor_after_update): Limit cursor's hpos by -1 from
+ below, not by 0, for when the cursor is on the left fringe.
+
2010-04-20 Jan Djärv <address@hidden>
* gtkutil.c (xg_event_is_for_scrollbar): Check if grabbed
=== modified file 'src/dispnew.c'
--- a/src/dispnew.c 2010-04-02 03:10:33 +0000
+++ b/src/dispnew.c 2010-04-10 16:28:30 +0000
@@ -4251,7 +4251,9 @@
doesn't work with lbearing/rbearing), so we must do it
this way. */
if (vpos == w->phys_cursor.vpos
- && w->phys_cursor.hpos >= desired_row->used[TEXT_AREA])
+ && (desired_row->reversed_p
+ ? (w->phys_cursor.hpos < 0)
+ : (w->phys_cursor.hpos >= desired_row->used[TEXT_AREA])))
{
w->phys_cursor_on_p = 0;
x = -1;
@@ -4415,7 +4417,7 @@
}
/* Window cursor can be out of sync for horizontally split windows. */
- hpos = max (0, hpos);
+ hpos = max (-1, hpos); /* -1 is for when cursor is on the left fringe */
hpos = min (w->current_matrix->matrix_w - 1, hpos);
vpos = max (0, vpos);
vpos = min (w->current_matrix->nrows - 1, vpos);
=== modified file 'src/fringe.c'
--- a/src/fringe.c 2010-01-13 08:35:10 +0000
+++ b/src/fringe.c 2010-04-17 12:33:05 +0000
@@ -825,7 +825,7 @@
{
int overlay = 0;
- if (!left_p && row->cursor_in_fringe_p)
+ if (left_p == row->reversed_p && row->cursor_in_fringe_p)
{
Lisp_Object cursor = Qnil;
@@ -857,7 +857,7 @@
int bm = get_logical_cursor_bitmap (w, cursor);
if (bm != NO_FRINGE_BITMAP)
{
- draw_fringe_bitmap_1 (w, row, 0, 2, bm);
+ draw_fringe_bitmap_1 (w, row, left_p, 2, bm);
overlay = EQ (cursor, Qbox) ? 3 : 1;
}
}
@@ -1090,7 +1090,8 @@
: LEFT_FRINGE (2, Qtop, 0));
else if (row->indicate_eob_p && EQ (boundary_bot, Qleft))
left = LEFT_FRINGE (3, Qbottom, row->ends_at_zv_p);
- else if (MATRIX_ROW_CONTINUATION_LINE_P (row))
+ else if ((!row->reversed_p && MATRIX_ROW_CONTINUATION_LINE_P (row))
+ || (row->reversed_p && row->continued_p))
left = LEFT_FRINGE (4, Qcontinuation, 0);
else if (row->indicate_empty_line_p && EQ (empty_pos, Qleft))
left = LEFT_FRINGE (5, Qempty_line, 0);
@@ -1117,7 +1118,8 @@
: RIGHT_FRINGE (2, Qtop, 0));
else if (row->indicate_eob_p && EQ (boundary_bot, Qright))
right = RIGHT_FRINGE (3, Qbottom, row->ends_at_zv_p);
- else if (row->continued_p)
+ else if ((!row->reversed_p && row->continued_p)
+ || (row->reversed_p && MATRIX_ROW_CONTINUATION_LINE_P (row)))
right = RIGHT_FRINGE (4, Qcontinuation, 0);
else if (row->indicate_top_line_p && EQ (arrow_top, Qright))
right = RIGHT_FRINGE (6, Qup, 0);
=== modified file 'src/term.c'
--- a/src/term.c 2010-04-20 01:50:52 +0000
+++ b/src/term.c 2010-04-20 13:31:28 +0000
@@ -1589,7 +1589,6 @@
}
}
-
/* Produce glyphs for the display element described by IT. *IT
specifies what we want to produce a glyph for (character, image, ...),
and where in the glyph matrix we currently are (glyph row and hpos).
@@ -1808,6 +1807,17 @@
glyph = it->glyph_row->glyphs[it->area] + it->glyph_row->used[it->area];
if (glyph < it->glyph_row->glyphs[1 + it->area])
{
+ /* If the glyph row is reversed, we need to prepend the glyph
+ rather than append it. */
+ if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
+ {
+ struct glyph *g;
+
+ /* Make room for the new glyph. */
+ for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
+ g[1] = *g;
+ glyph = it->glyph_row->glyphs[it->area];
+ }
glyph->type = COMPOSITE_GLYPH;
glyph->pixel_width = it->pixel_width;
glyph->u.cmp.id = it->cmp_it.id;
@@ -1828,6 +1838,18 @@
glyph->padding_p = 0;
glyph->charpos = CHARPOS (it->position);
glyph->object = it->object;
+ if (it->bidi_p)
+ {
+ glyph->resolved_level = it->bidi_it.resolved_level;
+ if ((it->bidi_it.type & 7) != it->bidi_it.type)
+ abort ();
+ glyph->bidi_type = it->bidi_it.type;
+ }
+ else
+ {
+ glyph->resolved_level = 0;
+ glyph->bidi_type = UNKNOWN_BT;
+ }
++it->glyph_row->used[it->area];
++glyph;
@@ -1889,12 +1911,16 @@
if (what == IT_CONTINUATION)
{
- /* Continuation glyph. */
- SET_GLYPH_FROM_CHAR (glyph, '\\');
+ /* Continuation glyph. For R2L lines, we mirror it by hand. */
+ if (it->bidi_it.paragraph_dir == R2L)
+ SET_GLYPH_FROM_CHAR (glyph, '/');
+ else
+ SET_GLYPH_FROM_CHAR (glyph, '\\');
if (it->dp
&& (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc))
&& GLYPH_CODE_CHAR_VALID_P (gc))
{
+ /* FIXME: Should we mirror GC for R2L lines? */
SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
}
@@ -1907,6 +1933,7 @@
&& (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc))
&& GLYPH_CODE_CHAR_VALID_P (gc))
{
+ /* FIXME: Should we mirror GC for R2L lines? */
SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
}
=== modified file 'src/w32term.c'
--- a/src/w32term.c 2010-04-02 03:10:33 +0000
+++ b/src/w32term.c 2010-04-10 16:28:30 +0000
@@ -5136,10 +5136,12 @@
}
if (glyph_row->exact_window_width_line_p
- && w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA])
+ && (glyph_row->reversed_p
+ ? (w->phys_cursor.hpos < 0)
+ : (w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA])))
{
glyph_row->cursor_in_fringe_p = 1;
- draw_fringe_bitmap (w, glyph_row, 0);
+ draw_fringe_bitmap (w, glyph_row, glyph_row->reversed_p);
return;
}
=== modified file 'src/xdisp.c'
--- a/src/xdisp.c 2010-04-20 01:50:52 +0000
+++ b/src/xdisp.c 2010-04-20 13:31:28 +0000
@@ -404,12 +404,14 @@
/* Test if overflow newline into fringe. Called with iterator IT
at or past right window margin, and with IT->current_x set. */
-#define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
- (!NILP (Voverflow_newline_into_fringe) \
- && FRAME_WINDOW_P (it->f) \
- && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
- && it->current_x == it->last_visible_x \
- && it->line_wrap != WORD_WRAP)
+#define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
+ (!NILP (Voverflow_newline_into_fringe) \
+ && FRAME_WINDOW_P ((IT)->f) \
+ && ((IT)->bidi_it.paragraph_dir == R2L \
+ ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
+ : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
+ && (IT)->current_x == (IT)->last_visible_x \
+ && (IT)->line_wrap != WORD_WRAP)
#else /* !HAVE_WINDOW_SYSTEM */
#define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
@@ -1077,6 +1079,8 @@
static void notice_overwritten_cursor P_ ((struct window *,
enum glyph_row_area,
int, int, int, int));
+static void append_stretch_glyph P_ ((struct it *, Lisp_Object,
+ int, int, int));
@@ -6709,13 +6713,20 @@
{
it->bidi_it.charpos = IT_CHARPOS (*it);
it->bidi_it.bytepos = IT_BYTEPOS (*it);
- /* If we are at the beginning of a line, we can produce the next
- element right away. */
- if (it->bidi_it.bytepos == BEGV_BYTE
+ if (it->bidi_it.bytepos == ZV_BYTE)
+ {
+ /* Nothing to do, but reset the FIRST_ELT flag, like
+ bidi_paragraph_init does, because we are not going to
+ call it. */
+ it->bidi_it.first_elt = 0;
+ }
+ else if (it->bidi_it.bytepos == BEGV_BYTE
/* FIXME: Should support all Unicode line separators. */
|| FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
|| FETCH_CHAR (it->bidi_it.bytepos) == '\n')
{
+ /* If we are at the beginning of a line, we can produce the
+ next element right away. */
bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
bidi_get_next_char_visually (&it->bidi_it);
}
@@ -12619,7 +12630,6 @@
/* The last known character position in row. */
int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
int x = row->x;
- int cursor_x = x;
EMACS_INT pt_old = PT - delta;
EMACS_INT pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
EMACS_INT pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
@@ -12655,8 +12665,8 @@
}
while (end > glyph
&& INTEGERP ((end - 1)->object)
- /* CHARPOS is zero for blanks inserted by
- extend_face_to_end_of_line. */
+ /* CHARPOS is zero for blanks and stretch glyphs
+ inserted by extend_face_to_end_of_line. */
&& (end - 1)->charpos <= 0)
--end;
glyph_before = glyph - 1;
@@ -12670,9 +12680,6 @@
to front, so swap the edge pointers. */
glyphs_end = end = glyph - 1;
glyph += row->used[TEXT_AREA] - 1;
- /* Reverse the known positions in the row. */
- last_pos = pos_after = MATRIX_ROW_START_CHARPOS (row) + delta;
- pos_before = MATRIX_ROW_END_CHARPOS (row) + delta;
while (glyph > end + 1
&& INTEGERP (glyph->object)
@@ -12687,7 +12694,6 @@
rightmost (first in the reading order) glyph. */
for (g = end + 1; g < glyph; g++)
x += g->pixel_width;
- cursor_x = x;
while (end < glyph
&& INTEGERP ((end + 1)->object)
&& (end + 1)->charpos <= 0)
@@ -12702,7 +12708,7 @@
rightmost glyph. Case in point: an empty last line that is
part of an R2L paragraph. */
cursor = end - 1;
- x = -1; /* will be computed below, at lable compute_x */
+ x = -1; /* will be computed below, at label compute_x */
}
/* Step 1: Try to find the glyph whose character position
@@ -12838,8 +12844,11 @@
string_seen = 1;
}
--glyph;
- if (glyph == end)
- break;
+ if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
+ {
+ x--; /* can't use any pixel_width */
+ break;
+ }
x -= glyph->pixel_width;
}
@@ -12879,7 +12888,10 @@
}
else if (match_with_avoid_cursor
/* zero-width characters produce no glyphs */
- || eabs (glyph_after - glyph_before) == 1)
+ || ((row->reversed_p
+ ? glyph_after > glyphs_end
+ : glyph_after < glyphs_end)
+ && eabs (glyph_after - glyph_before) == 1))
{
cursor = glyph_after;
x = -1;
@@ -12998,16 +13010,17 @@
}
}
- /* ROW could be part of a continued line, which might have other
- rows whose start and end charpos occlude point. Only set
- w->cursor if we found a better approximation to the cursor
- position than we have from previously examined rows. */
+ /* ROW could be part of a continued line, which, under bidi
+ reordering, might have other rows whose start and end charpos
+ occlude point. Only set w->cursor if we found a better
+ approximation to the cursor position than we have from previously
+ examined candidate rows belonging to the same continued line. */
if (/* we already have a candidate row */
w->cursor.vpos >= 0
/* that candidate is not the row we are processing */
&& MATRIX_ROW (matrix, w->cursor.vpos) != row
- /* this row is part of a continued line */
- && (row->continued_p || row->continuation_lines_width)
+ /* the row we are processing is part of a continued line */
+ && (row->continued_p || MATRIX_ROW_CONTINUATION_LINE_P (row))
/* Make sure cursor.vpos specifies a row whose start and end
charpos occlude point. This is because some callers of this
function leave cursor.vpos at the row where the cursor was
@@ -16850,9 +16863,11 @@
/* Extend the face of the last glyph in the text area of IT->glyph_row
- to the end of the display line. Called from display_line.
- If the glyph row is empty, add a space glyph to it so that we
- know the face to draw. Set the glyph row flag fill_line_p. */
+ to the end of the display line. Called from display_line. If the
+ glyph row is empty, add a space glyph to it so that we know the
+ face to draw. Set the glyph row flag fill_line_p. If the glyph
+ row is R2L, prepend a stretch glyph to cover the empty space to the
+ left of the leftmost glyph. */
static void
extend_face_to_end_of_line (it)
@@ -16861,15 +16876,17 @@
struct face *face;
struct frame *f = it->f;
- /* If line is already filled, do nothing. */
- if (it->current_x >= it->last_visible_x)
+ /* If line is already filled, do nothing. Non window-system frames
+ get a grace of one more ``pixel'' because their characters are
+ 1-``pixel'' wide, so they hit the equality too early. */
+ if (it->current_x >= it->last_visible_x + !FRAME_WINDOW_P (f))
return;
/* Face extension extends the background and box of IT->face_id
to the end of the line. If the background equals the background
of the frame, we don't have to do anything. */
if (it->face_before_selective_p)
- face = FACE_FROM_ID (it->f, it->saved_face_id);
+ face = FACE_FROM_ID (f, it->saved_face_id);
else
face = FACE_FROM_ID (f, it->face_id);
@@ -16877,7 +16894,8 @@
&& it->glyph_row->displays_text_p
&& face->box == FACE_NO_BOX
&& face->background == FRAME_BACKGROUND_PIXEL (f)
- && !face->stipple)
+ && !face->stipple
+ && !it->glyph_row->reversed_p)
return;
/* Set the glyph row flag indicating that the face of the last glyph
@@ -16904,6 +16922,50 @@
it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
it->glyph_row->used[TEXT_AREA] = 1;
}
+#ifdef HAVE_WINDOW_SYSTEM
+ if (it->glyph_row->reversed_p)
+ {
+ /* Prepend a stretch glyph to the row, such that the
+ rightmost glyph will be drawn flushed all the way to the
+ right margin of the window. The stretch glyph that will
+ occupy the empty space, if any, to the left of the
+ glyphs. */
+ struct font *font = face->font ? face->font : FRAME_FONT (f);
+ struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
+ struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
+ struct glyph *g;
+ int row_width, stretch_ascent, stretch_width;
+ struct text_pos saved_pos;
+ int saved_face_id, saved_avoid_cursor;
+
+ for (row_width = 0, g = row_start; g < row_end; g++)
+ row_width += g->pixel_width;
+ stretch_width = window_box_width (it->w, TEXT_AREA) - row_width;
+ if (stretch_width > 0)
+ {
+ stretch_ascent =
+ (((it->ascent + it->descent)
+ * FONT_BASE (font)) / FONT_HEIGHT (font));
+ saved_pos = it->position;
+ bzero (&it->position, sizeof it->position);
+ saved_avoid_cursor = it->avoid_cursor_p;
+ it->avoid_cursor_p = 1;
+ saved_face_id = it->face_id;
+ /* The last row's stretch glyph should get the default
+ face, to avoid painting the rest of the window with
+ the region face, if the region ends at ZV. */
+ if (it->glyph_row->ends_at_zv_p)
+ it->face_id = DEFAULT_FACE_ID;
+ else
+ it->face_id = face->id;
+ append_stretch_glyph (it, make_number (0), stretch_width,
+ it->ascent + it->descent, stretch_ascent);
+ it->position = saved_pos;
+ it->avoid_cursor_p = saved_avoid_cursor;
+ it->face_id = saved_face_id;
+ }
+ }
+#endif /* HAVE_WINDOW_SYSTEM */
}
else
{
@@ -16922,7 +16984,13 @@
it->object = make_number (0);
it->c = ' ';
it->len = 1;
- it->face_id = face->id;
+ /* The last row's blank glyphs should get the default face, to
+ avoid painting the rest of the window with the region face,
+ if the region ends at ZV. */
+ if (it->glyph_row->ends_at_zv_p)
+ it->face_id = DEFAULT_FACE_ID;
+ else
+ it->face_id = face->id;
PRODUCE_GLYPHS (it);
@@ -17208,6 +17276,31 @@
+/* Remove N glyphs at the start of a reversed IT->glyph_row. Called
+ only for R2L lines from display_line, when it decides that too many
+ glyphs were produced by PRODUCE_GLYPHS, and the line needs to be
+ continued. */
+static void
+unproduce_glyphs (it, n)
+ struct it *it;
+ int n;
+{
+ struct glyph *glyph, *end;
+
+ xassert (it->glyph_row);
+ xassert (it->glyph_row->reversed_p);
+ xassert (it->area == TEXT_AREA);
+ xassert (n <= it->glyph_row->used[TEXT_AREA]);
+
+ if (n > it->glyph_row->used[TEXT_AREA])
+ n = it->glyph_row->used[TEXT_AREA];
+ glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
+ end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
+ for ( ; glyph < end; glyph++)
+ glyph[-n] = *glyph;
+}
+
+
/* Construct the glyph row IT->glyph_row in the desired matrix of
IT->w from text at the current position of IT. See dispextern.h
for an overview of struct it. Value is non-zero if
@@ -17472,6 +17565,9 @@
/* A padding glyph that doesn't fit on this line.
This means the whole character doesn't fit
on the line. */
+ if (row->reversed_p)
+ unproduce_glyphs (it, row->used[TEXT_AREA]
+ - n_glyphs_before);
row->used[TEXT_AREA] = n_glyphs_before;
/* Fill the rest of the row with continuation
@@ -17494,6 +17590,9 @@
else if (wrap_row_used > 0)
{
back_to_wrap:
+ if (row->reversed_p)
+ unproduce_glyphs (it,
+ row->used[TEXT_AREA] - wrap_row_used);
*it = wrap_it;
it->continuation_lines_width += wrap_x;
row->used[TEXT_AREA] = wrap_row_used;
@@ -17529,6 +17628,9 @@
/* Something other than a TAB that draws past
the right edge of the window. Restore
positions to values before the element. */
+ if (row->reversed_p)
+ unproduce_glyphs (it, row->used[TEXT_AREA]
+ - (n_glyphs_before + i));
row->used[TEXT_AREA] = n_glyphs_before + i;
/* Display continuation glyphs. */
@@ -17634,9 +17736,22 @@
{
int i, n;
- for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
- if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
- break;
+ if (!row->reversed_p)
+ {
+ for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
+ if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
+ break;
+ }
+ else
+ {
+ for (i = 0; i < row->used[TEXT_AREA]; i++)
+ if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
+ break;
+ /* Remove padding glyphs at the front of ROW, to
+ make room for the truncation glyphs we will be
+ adding below. */
+ unproduce_glyphs (it, i);
+ }
for (n = row->used[TEXT_AREA]; i < n; ++i)
{
@@ -17823,7 +17938,7 @@
*it = save_it;
}
else if (!row->continued_p
- && row->continuation_lines_width
+ && MATRIX_ROW_CONTINUATION_LINE_P (row)
&& it->eol_pos.charpos > 0)
{
/* Last row of a continued line. Use the position
@@ -21493,6 +21608,17 @@
glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
if (glyph < it->glyph_row->glyphs[area + 1])
{
+ /* If the glyph row is reversed, we need to prepend the glyph
+ rather than append it. */
+ if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
+ {
+ struct glyph *g;
+
+ /* Make room for the new glyph. */
+ for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
+ g[1] = *g;
+ glyph = it->glyph_row->glyphs[it->area];
+ }
glyph->charpos = CHARPOS (it->position);
glyph->object = it->object;
glyph->pixel_width = it->pixel_width;
@@ -21738,6 +21864,17 @@
glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
if (glyph < it->glyph_row->glyphs[area + 1])
{
+ /* If the glyph row is reversed, we need to prepend the glyph
+ rather than append it. */
+ if (it->glyph_row->reversed_p && area == TEXT_AREA)
+ {
+ struct glyph *g;
+
+ /* Make room for the additional glyph. */
+ for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
+ g[1] = *g;
+ glyph = it->glyph_row->glyphs[area];
+ }
glyph->charpos = CHARPOS (it->position);
glyph->object = object;
glyph->pixel_width = width;
@@ -21764,6 +21901,11 @@
abort ();
glyph->bidi_type = it->bidi_it.type;
}
+ else
+ {
+ glyph->resolved_level = 0;
+ glyph->bidi_type = UNKNOWN_BT;
+ }
++it->glyph_row->used[area];
}
else
@@ -23244,7 +23386,7 @@
if (row->cursor_in_fringe_p)
{
row->cursor_in_fringe_p = 0;
- draw_fringe_bitmap (w, row, 0);
+ draw_fringe_bitmap (w, row, row->reversed_p);
w->phys_cursor_on_p = 0;
return;
}
@@ -23345,7 +23487,9 @@
/* If cursor hpos is out of bounds, don't draw garbage. This can
happen in mini-buffer windows when switching between echo area
glyphs and mini-buffer. */
- if (w->phys_cursor.hpos < row->used[TEXT_AREA])
+ if ((row->reversed_p
+ ? (w->phys_cursor.hpos >= 0)
+ : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
{
int on_p = w->phys_cursor_on_p;
int x1;
@@ -23425,7 +23569,7 @@
if (cursor_row->cursor_in_fringe_p)
{
cursor_row->cursor_in_fringe_p = 0;
- draw_fringe_bitmap (w, cursor_row, 0);
+ draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
goto mark_cursor_off;
}
@@ -23434,7 +23578,9 @@
should have cleared the cursor. Note that we wouldn't be
able to erase the cursor in this case because we don't have a
cursor glyph at hand. */
- if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
+ if ((cursor_row->reversed_p
+ ? (w->phys_cursor.hpos < 0)
+ : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
goto mark_cursor_off;
/* If the cursor is in the mouse face area, redisplay that when
@@ -23450,7 +23596,7 @@
/* Don't redraw the cursor's spot in mouse face if it is at the
end of a line (on a newline). The cursor appears there, but
mouse highlighting does not. */
- && cursor_row->used[TEXT_AREA] > hpos)
+ && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
mouse_face_here_p = 1;
/* Maybe clear the display under the cursor. */
@@ -23532,7 +23678,7 @@
glyph = NULL;
if (!glyph_row->exact_window_width_line_p
- || hpos < glyph_row->used[TEXT_AREA])
+ || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
xassert (interrupt_input_blocked);
=== modified file 'src/xterm.c'
--- a/src/xterm.c 2010-04-19 15:07:52 +0000
+++ b/src/xterm.c 2010-04-20 13:31:28 +0000
@@ -7492,36 +7492,40 @@
w->phys_cursor_on_p = 1;
if (glyph_row->exact_window_width_line_p
- && w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA])
+ && (glyph_row->reversed_p
+ ? (w->phys_cursor.hpos < 0)
+ : (w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA])))
{
glyph_row->cursor_in_fringe_p = 1;
- draw_fringe_bitmap (w, glyph_row, 0);
+ draw_fringe_bitmap (w, glyph_row, glyph_row->reversed_p);
}
else
- switch (cursor_type)
{
- case HOLLOW_BOX_CURSOR:
- x_draw_hollow_cursor (w, glyph_row);
- break;
-
- case FILLED_BOX_CURSOR:
- draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
- break;
-
- case BAR_CURSOR:
- x_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR);
- break;
-
- case HBAR_CURSOR:
- x_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR);
- break;
-
- case NO_CURSOR:
- w->phys_cursor_width = 0;
- break;
-
- default:
- abort ();
+ switch (cursor_type)
+ {
+ case HOLLOW_BOX_CURSOR:
+ x_draw_hollow_cursor (w, glyph_row);
+ break;
+
+ case FILLED_BOX_CURSOR:
+ draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
+ break;
+
+ case BAR_CURSOR:
+ x_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR);
+ break;
+
+ case HBAR_CURSOR:
+ x_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR);
+ break;
+
+ case NO_CURSOR:
+ w->phys_cursor_width = 0;
+ break;
+
+ default:
+ abort ();
+ }
}
#ifdef HAVE_X_I18N
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] /srv/bzr/emacs/trunk r99950: Implement GUI display of R2L lines, fix TTY display of R2L lines.,
Eli Zaretskii <=