diff options
| author | Eli Zaretskii | 2010-04-20 16:31:28 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2010-04-20 16:31:28 +0300 |
| commit | 283ccc1841a43a9426b7fa4c397fc9593ae4022b (patch) | |
| tree | 8365f6715bb866e6c07410f600ae2a43900f77d4 /src | |
| parent | 3bb49aaf02507540cefed269bd410d318f8c81b4 (diff) | |
| parent | 93d68d0c2b085f65a867024fb8e7e28a629a003a (diff) | |
| download | emacs-283ccc1841a43a9426b7fa4c397fc9593ae4022b.tar.gz emacs-283ccc1841a43a9426b7fa4c397fc9593ae4022b.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 67 | ||||
| -rw-r--r-- | src/dispnew.c | 6 | ||||
| -rw-r--r-- | src/fringe.c | 10 | ||||
| -rw-r--r-- | src/term.c | 33 | ||||
| -rw-r--r-- | src/w32term.c | 6 | ||||
| -rw-r--r-- | src/xdisp.c | 234 | ||||
| -rw-r--r-- | src/xterm.c | 44 |
7 files changed, 325 insertions, 75 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 4cb7383144d..481588e5acc 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,70 @@ | |||
| 1 | 2010-04-20 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | Fix R2L paragraph display on TTY. | ||
| 4 | |||
| 5 | * xdisp.c (unproduce_glyphs): New function. | ||
| 6 | (display_line): Use it when produced glyphs are discarded from R2L | ||
| 7 | glyph rows. | ||
| 8 | (append_composite_glyph): In R2L rows, prepend the glyph rather | ||
| 9 | than appending it. | ||
| 10 | |||
| 11 | * term.c (append_composite_glyph): In R2L rows, prepend the glyph | ||
| 12 | rather than append it. Set up the resolved_level and bidi_type | ||
| 13 | attributes of the appended glyph. | ||
| 14 | (produce_special_glyphs): Mirror the backslash continuation | ||
| 15 | character in R2L lines. | ||
| 16 | |||
| 17 | Implement display of R2L paragraphs in GUI sessions. | ||
| 18 | |||
| 19 | * xdisp.c [HAVE_WINDOW_SYSTEM]: Add prototype for | ||
| 20 | append_stretch_glyph. | ||
| 21 | (set_cursor_from_row) <cursor_x>: Remove unused variable. Fix | ||
| 22 | off-by-one error in computing x at end of text in the row. | ||
| 23 | (append_stretch_glyph): In reversed row, prepend the glyph rather | ||
| 24 | than append it. Set resolved_level and bidi_type of the glyph. | ||
| 25 | (extend_face_to_end_of_line): If the row is reversed, prepend a | ||
| 26 | stretch glyph whose width is such that the rightmost glyph will be | ||
| 27 | drawn at the right margin of the window. Fix off-by-one error on | ||
| 28 | TTY frames in testing whether a line needs face extension. Fix | ||
| 29 | face extension at ZV. If this is the last glyph row, use | ||
| 30 | DEFAULT_FACE_ID, to avoid painting the rest of the window with the | ||
| 31 | region face. | ||
| 32 | (set_cursor_from_row, display_line): Use | ||
| 33 | MATRIX_ROW_CONTINUATION_LINE_P instead of testing value of | ||
| 34 | row->continuation_lines_width. | ||
| 35 | (next_element_from_buffer): Don't call bidi_paragraph_init if we | ||
| 36 | are at ZV. Fixes a crash when reseated to ZV by | ||
| 37 | try_window_reusing_current_matrix. | ||
| 38 | (display_and_set_cursor, erase_phys_cursor): Handle negative HPOS, | ||
| 39 | which happens with R2L glyph rows. Fixes a crash when inserting a | ||
| 40 | character at end of an R2L line. | ||
| 41 | (set_cursor_from_row): Don't be fooled by truncated rows: don't | ||
| 42 | treat them as having zero-width characters. Improve comments. | ||
| 43 | Don't reverse pos_before and pos_after for reversed glyph rows. | ||
| 44 | Set cursor.x to negative value when the cursor might be on the | ||
| 45 | left fringe. | ||
| 46 | (IT_OVERFLOW_NEWLINE_INTO_FRINGE): For R2L lines, consider the | ||
| 47 | left fringe, not the right one. | ||
| 48 | (notice_overwritten_cursor, draw_phys_cursor_glyph) | ||
| 49 | (erase_phys_cursor): For reversed cursor_row, support cursor on | ||
| 50 | the left fringe. | ||
| 51 | |||
| 52 | * fringe.c (update_window_fringes): For R2L rows, swap the bitmaps | ||
| 53 | of continuation indicators on the fringes. | ||
| 54 | (draw_fringe_bitmap): For reversed glyph rows, allow cursor on the | ||
| 55 | left fringe. | ||
| 56 | |||
| 57 | * w32term.c (w32_draw_window_cursor): For reversed glyph rows, | ||
| 58 | draw cursor on the left fringe. | ||
| 59 | |||
| 60 | * xterm.c (x_draw_window_cursor): For reversed glyph rows, draw | ||
| 61 | cursor on the left fringe. | ||
| 62 | |||
| 63 | * dispnew.c (update_text_area): Handle reversed desired rows when | ||
| 64 | the cursor is on the left fringe. | ||
| 65 | (set_window_cursor_after_update): Limit cursor's hpos by -1 from | ||
| 66 | below, not by 0, for when the cursor is on the left fringe. | ||
| 67 | |||
| 1 | 2010-04-20 Jan Djärv <jan.h.d@swipnet.se> | 68 | 2010-04-20 Jan Djärv <jan.h.d@swipnet.se> |
| 2 | 69 | ||
| 3 | * gtkutil.c (xg_event_is_for_scrollbar): Check if grabbed | 70 | * gtkutil.c (xg_event_is_for_scrollbar): Check if grabbed |
diff --git a/src/dispnew.c b/src/dispnew.c index 2be00c9c3b0..7ab2bf35811 100644 --- a/src/dispnew.c +++ b/src/dispnew.c | |||
| @@ -4251,7 +4251,9 @@ update_text_area (w, vpos) | |||
| 4251 | doesn't work with lbearing/rbearing), so we must do it | 4251 | doesn't work with lbearing/rbearing), so we must do it |
| 4252 | this way. */ | 4252 | this way. */ |
| 4253 | if (vpos == w->phys_cursor.vpos | 4253 | if (vpos == w->phys_cursor.vpos |
| 4254 | && w->phys_cursor.hpos >= desired_row->used[TEXT_AREA]) | 4254 | && (desired_row->reversed_p |
| 4255 | ? (w->phys_cursor.hpos < 0) | ||
| 4256 | : (w->phys_cursor.hpos >= desired_row->used[TEXT_AREA]))) | ||
| 4255 | { | 4257 | { |
| 4256 | w->phys_cursor_on_p = 0; | 4258 | w->phys_cursor_on_p = 0; |
| 4257 | x = -1; | 4259 | x = -1; |
| @@ -4415,7 +4417,7 @@ set_window_cursor_after_update (w) | |||
| 4415 | } | 4417 | } |
| 4416 | 4418 | ||
| 4417 | /* Window cursor can be out of sync for horizontally split windows. */ | 4419 | /* Window cursor can be out of sync for horizontally split windows. */ |
| 4418 | hpos = max (0, hpos); | 4420 | hpos = max (-1, hpos); /* -1 is for when cursor is on the left fringe */ |
| 4419 | hpos = min (w->current_matrix->matrix_w - 1, hpos); | 4421 | hpos = min (w->current_matrix->matrix_w - 1, hpos); |
| 4420 | vpos = max (0, vpos); | 4422 | vpos = max (0, vpos); |
| 4421 | vpos = min (w->current_matrix->nrows - 1, vpos); | 4423 | vpos = min (w->current_matrix->nrows - 1, vpos); |
diff --git a/src/fringe.c b/src/fringe.c index 952e95a5517..cfb944d58d1 100644 --- a/src/fringe.c +++ b/src/fringe.c | |||
| @@ -825,7 +825,7 @@ draw_fringe_bitmap (w, row, left_p) | |||
| 825 | { | 825 | { |
| 826 | int overlay = 0; | 826 | int overlay = 0; |
| 827 | 827 | ||
| 828 | if (!left_p && row->cursor_in_fringe_p) | 828 | if (left_p == row->reversed_p && row->cursor_in_fringe_p) |
| 829 | { | 829 | { |
| 830 | Lisp_Object cursor = Qnil; | 830 | Lisp_Object cursor = Qnil; |
| 831 | 831 | ||
| @@ -857,7 +857,7 @@ draw_fringe_bitmap (w, row, left_p) | |||
| 857 | int bm = get_logical_cursor_bitmap (w, cursor); | 857 | int bm = get_logical_cursor_bitmap (w, cursor); |
| 858 | if (bm != NO_FRINGE_BITMAP) | 858 | if (bm != NO_FRINGE_BITMAP) |
| 859 | { | 859 | { |
| 860 | draw_fringe_bitmap_1 (w, row, 0, 2, bm); | 860 | draw_fringe_bitmap_1 (w, row, left_p, 2, bm); |
| 861 | overlay = EQ (cursor, Qbox) ? 3 : 1; | 861 | overlay = EQ (cursor, Qbox) ? 3 : 1; |
| 862 | } | 862 | } |
| 863 | } | 863 | } |
| @@ -1090,7 +1090,8 @@ update_window_fringes (w, keep_current_p) | |||
| 1090 | : LEFT_FRINGE (2, Qtop, 0)); | 1090 | : LEFT_FRINGE (2, Qtop, 0)); |
| 1091 | else if (row->indicate_eob_p && EQ (boundary_bot, Qleft)) | 1091 | else if (row->indicate_eob_p && EQ (boundary_bot, Qleft)) |
| 1092 | left = LEFT_FRINGE (3, Qbottom, row->ends_at_zv_p); | 1092 | left = LEFT_FRINGE (3, Qbottom, row->ends_at_zv_p); |
| 1093 | else if (MATRIX_ROW_CONTINUATION_LINE_P (row)) | 1093 | else if ((!row->reversed_p && MATRIX_ROW_CONTINUATION_LINE_P (row)) |
| 1094 | || (row->reversed_p && row->continued_p)) | ||
| 1094 | left = LEFT_FRINGE (4, Qcontinuation, 0); | 1095 | left = LEFT_FRINGE (4, Qcontinuation, 0); |
| 1095 | else if (row->indicate_empty_line_p && EQ (empty_pos, Qleft)) | 1096 | else if (row->indicate_empty_line_p && EQ (empty_pos, Qleft)) |
| 1096 | left = LEFT_FRINGE (5, Qempty_line, 0); | 1097 | left = LEFT_FRINGE (5, Qempty_line, 0); |
| @@ -1117,7 +1118,8 @@ update_window_fringes (w, keep_current_p) | |||
| 1117 | : RIGHT_FRINGE (2, Qtop, 0)); | 1118 | : RIGHT_FRINGE (2, Qtop, 0)); |
| 1118 | else if (row->indicate_eob_p && EQ (boundary_bot, Qright)) | 1119 | else if (row->indicate_eob_p && EQ (boundary_bot, Qright)) |
| 1119 | right = RIGHT_FRINGE (3, Qbottom, row->ends_at_zv_p); | 1120 | right = RIGHT_FRINGE (3, Qbottom, row->ends_at_zv_p); |
| 1120 | else if (row->continued_p) | 1121 | else if ((!row->reversed_p && row->continued_p) |
| 1122 | || (row->reversed_p && MATRIX_ROW_CONTINUATION_LINE_P (row))) | ||
| 1121 | right = RIGHT_FRINGE (4, Qcontinuation, 0); | 1123 | right = RIGHT_FRINGE (4, Qcontinuation, 0); |
| 1122 | else if (row->indicate_top_line_p && EQ (arrow_top, Qright)) | 1124 | else if (row->indicate_top_line_p && EQ (arrow_top, Qright)) |
| 1123 | right = RIGHT_FRINGE (6, Qup, 0); | 1125 | right = RIGHT_FRINGE (6, Qup, 0); |
diff --git a/src/term.c b/src/term.c index 20f746decdb..bb143207758 100644 --- a/src/term.c +++ b/src/term.c | |||
| @@ -1589,7 +1589,6 @@ append_glyph (it) | |||
| 1589 | } | 1589 | } |
| 1590 | } | 1590 | } |
| 1591 | 1591 | ||
| 1592 | |||
| 1593 | /* Produce glyphs for the display element described by IT. *IT | 1592 | /* Produce glyphs for the display element described by IT. *IT |
| 1594 | specifies what we want to produce a glyph for (character, image, ...), | 1593 | specifies what we want to produce a glyph for (character, image, ...), |
| 1595 | and where in the glyph matrix we currently are (glyph row and hpos). | 1594 | and where in the glyph matrix we currently are (glyph row and hpos). |
| @@ -1808,6 +1807,17 @@ append_composite_glyph (it) | |||
| 1808 | glyph = it->glyph_row->glyphs[it->area] + it->glyph_row->used[it->area]; | 1807 | glyph = it->glyph_row->glyphs[it->area] + it->glyph_row->used[it->area]; |
| 1809 | if (glyph < it->glyph_row->glyphs[1 + it->area]) | 1808 | if (glyph < it->glyph_row->glyphs[1 + it->area]) |
| 1810 | { | 1809 | { |
| 1810 | /* If the glyph row is reversed, we need to prepend the glyph | ||
| 1811 | rather than append it. */ | ||
| 1812 | if (it->glyph_row->reversed_p && it->area == TEXT_AREA) | ||
| 1813 | { | ||
| 1814 | struct glyph *g; | ||
| 1815 | |||
| 1816 | /* Make room for the new glyph. */ | ||
| 1817 | for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--) | ||
| 1818 | g[1] = *g; | ||
| 1819 | glyph = it->glyph_row->glyphs[it->area]; | ||
| 1820 | } | ||
| 1811 | glyph->type = COMPOSITE_GLYPH; | 1821 | glyph->type = COMPOSITE_GLYPH; |
| 1812 | glyph->pixel_width = it->pixel_width; | 1822 | glyph->pixel_width = it->pixel_width; |
| 1813 | glyph->u.cmp.id = it->cmp_it.id; | 1823 | glyph->u.cmp.id = it->cmp_it.id; |
| @@ -1828,6 +1838,18 @@ append_composite_glyph (it) | |||
| 1828 | glyph->padding_p = 0; | 1838 | glyph->padding_p = 0; |
| 1829 | glyph->charpos = CHARPOS (it->position); | 1839 | glyph->charpos = CHARPOS (it->position); |
| 1830 | glyph->object = it->object; | 1840 | glyph->object = it->object; |
| 1841 | if (it->bidi_p) | ||
| 1842 | { | ||
| 1843 | glyph->resolved_level = it->bidi_it.resolved_level; | ||
| 1844 | if ((it->bidi_it.type & 7) != it->bidi_it.type) | ||
| 1845 | abort (); | ||
| 1846 | glyph->bidi_type = it->bidi_it.type; | ||
| 1847 | } | ||
| 1848 | else | ||
| 1849 | { | ||
| 1850 | glyph->resolved_level = 0; | ||
| 1851 | glyph->bidi_type = UNKNOWN_BT; | ||
| 1852 | } | ||
| 1831 | 1853 | ||
| 1832 | ++it->glyph_row->used[it->area]; | 1854 | ++it->glyph_row->used[it->area]; |
| 1833 | ++glyph; | 1855 | ++glyph; |
| @@ -1889,12 +1911,16 @@ produce_special_glyphs (it, what) | |||
| 1889 | 1911 | ||
| 1890 | if (what == IT_CONTINUATION) | 1912 | if (what == IT_CONTINUATION) |
| 1891 | { | 1913 | { |
| 1892 | /* Continuation glyph. */ | 1914 | /* Continuation glyph. For R2L lines, we mirror it by hand. */ |
| 1893 | SET_GLYPH_FROM_CHAR (glyph, '\\'); | 1915 | if (it->bidi_it.paragraph_dir == R2L) |
| 1916 | SET_GLYPH_FROM_CHAR (glyph, '/'); | ||
| 1917 | else | ||
| 1918 | SET_GLYPH_FROM_CHAR (glyph, '\\'); | ||
| 1894 | if (it->dp | 1919 | if (it->dp |
| 1895 | && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc)) | 1920 | && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc)) |
| 1896 | && GLYPH_CODE_CHAR_VALID_P (gc)) | 1921 | && GLYPH_CODE_CHAR_VALID_P (gc)) |
| 1897 | { | 1922 | { |
| 1923 | /* FIXME: Should we mirror GC for R2L lines? */ | ||
| 1898 | SET_GLYPH_FROM_GLYPH_CODE (glyph, gc); | 1924 | SET_GLYPH_FROM_GLYPH_CODE (glyph, gc); |
| 1899 | spec_glyph_lookup_face (XWINDOW (it->window), &glyph); | 1925 | spec_glyph_lookup_face (XWINDOW (it->window), &glyph); |
| 1900 | } | 1926 | } |
| @@ -1907,6 +1933,7 @@ produce_special_glyphs (it, what) | |||
| 1907 | && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc)) | 1933 | && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc)) |
| 1908 | && GLYPH_CODE_CHAR_VALID_P (gc)) | 1934 | && GLYPH_CODE_CHAR_VALID_P (gc)) |
| 1909 | { | 1935 | { |
| 1936 | /* FIXME: Should we mirror GC for R2L lines? */ | ||
| 1910 | SET_GLYPH_FROM_GLYPH_CODE (glyph, gc); | 1937 | SET_GLYPH_FROM_GLYPH_CODE (glyph, gc); |
| 1911 | spec_glyph_lookup_face (XWINDOW (it->window), &glyph); | 1938 | spec_glyph_lookup_face (XWINDOW (it->window), &glyph); |
| 1912 | } | 1939 | } |
diff --git a/src/w32term.c b/src/w32term.c index 7222e26efd2..0b71b7e02b7 100644 --- a/src/w32term.c +++ b/src/w32term.c | |||
| @@ -5136,10 +5136,12 @@ w32_draw_window_cursor (w, glyph_row, x, y, cursor_type, cursor_width, on_p, act | |||
| 5136 | } | 5136 | } |
| 5137 | 5137 | ||
| 5138 | if (glyph_row->exact_window_width_line_p | 5138 | if (glyph_row->exact_window_width_line_p |
| 5139 | && w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA]) | 5139 | && (glyph_row->reversed_p |
| 5140 | ? (w->phys_cursor.hpos < 0) | ||
| 5141 | : (w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA]))) | ||
| 5140 | { | 5142 | { |
| 5141 | glyph_row->cursor_in_fringe_p = 1; | 5143 | glyph_row->cursor_in_fringe_p = 1; |
| 5142 | draw_fringe_bitmap (w, glyph_row, 0); | 5144 | draw_fringe_bitmap (w, glyph_row, glyph_row->reversed_p); |
| 5143 | return; | 5145 | return; |
| 5144 | } | 5146 | } |
| 5145 | 5147 | ||
diff --git a/src/xdisp.c b/src/xdisp.c index 6728e01f3bd..3f590f3ccd9 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -404,12 +404,14 @@ extern Lisp_Object Voverflow_newline_into_fringe; | |||
| 404 | /* Test if overflow newline into fringe. Called with iterator IT | 404 | /* Test if overflow newline into fringe. Called with iterator IT |
| 405 | at or past right window margin, and with IT->current_x set. */ | 405 | at or past right window margin, and with IT->current_x set. */ |
| 406 | 406 | ||
| 407 | #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \ | 407 | #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \ |
| 408 | (!NILP (Voverflow_newline_into_fringe) \ | 408 | (!NILP (Voverflow_newline_into_fringe) \ |
| 409 | && FRAME_WINDOW_P (it->f) \ | 409 | && FRAME_WINDOW_P ((IT)->f) \ |
| 410 | && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \ | 410 | && ((IT)->bidi_it.paragraph_dir == R2L \ |
| 411 | && it->current_x == it->last_visible_x \ | 411 | ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \ |
| 412 | && it->line_wrap != WORD_WRAP) | 412 | : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \ |
| 413 | && (IT)->current_x == (IT)->last_visible_x \ | ||
| 414 | && (IT)->line_wrap != WORD_WRAP) | ||
| 413 | 415 | ||
| 414 | #else /* !HAVE_WINDOW_SYSTEM */ | 416 | #else /* !HAVE_WINDOW_SYSTEM */ |
| 415 | #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0 | 417 | #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0 |
| @@ -1077,6 +1079,8 @@ static void display_tool_bar_line P_ ((struct it *, int)); | |||
| 1077 | static void notice_overwritten_cursor P_ ((struct window *, | 1079 | static void notice_overwritten_cursor P_ ((struct window *, |
| 1078 | enum glyph_row_area, | 1080 | enum glyph_row_area, |
| 1079 | int, int, int, int)); | 1081 | int, int, int, int)); |
| 1082 | static void append_stretch_glyph P_ ((struct it *, Lisp_Object, | ||
| 1083 | int, int, int)); | ||
| 1080 | 1084 | ||
| 1081 | 1085 | ||
| 1082 | 1086 | ||
| @@ -6709,13 +6713,20 @@ next_element_from_buffer (it) | |||
| 6709 | { | 6713 | { |
| 6710 | it->bidi_it.charpos = IT_CHARPOS (*it); | 6714 | it->bidi_it.charpos = IT_CHARPOS (*it); |
| 6711 | it->bidi_it.bytepos = IT_BYTEPOS (*it); | 6715 | it->bidi_it.bytepos = IT_BYTEPOS (*it); |
| 6712 | /* If we are at the beginning of a line, we can produce the next | 6716 | if (it->bidi_it.bytepos == ZV_BYTE) |
| 6713 | element right away. */ | 6717 | { |
| 6714 | if (it->bidi_it.bytepos == BEGV_BYTE | 6718 | /* Nothing to do, but reset the FIRST_ELT flag, like |
| 6719 | bidi_paragraph_init does, because we are not going to | ||
| 6720 | call it. */ | ||
| 6721 | it->bidi_it.first_elt = 0; | ||
| 6722 | } | ||
| 6723 | else if (it->bidi_it.bytepos == BEGV_BYTE | ||
| 6715 | /* FIXME: Should support all Unicode line separators. */ | 6724 | /* FIXME: Should support all Unicode line separators. */ |
| 6716 | || FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n' | 6725 | || FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n' |
| 6717 | || FETCH_CHAR (it->bidi_it.bytepos) == '\n') | 6726 | || FETCH_CHAR (it->bidi_it.bytepos) == '\n') |
| 6718 | { | 6727 | { |
| 6728 | /* If we are at the beginning of a line, we can produce the | ||
| 6729 | next element right away. */ | ||
| 6719 | bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it); | 6730 | bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it); |
| 6720 | bidi_get_next_char_visually (&it->bidi_it); | 6731 | bidi_get_next_char_visually (&it->bidi_it); |
| 6721 | } | 6732 | } |
| @@ -12619,7 +12630,6 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos) | |||
| 12619 | /* The last known character position in row. */ | 12630 | /* The last known character position in row. */ |
| 12620 | int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta; | 12631 | int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta; |
| 12621 | int x = row->x; | 12632 | int x = row->x; |
| 12622 | int cursor_x = x; | ||
| 12623 | EMACS_INT pt_old = PT - delta; | 12633 | EMACS_INT pt_old = PT - delta; |
| 12624 | EMACS_INT pos_before = MATRIX_ROW_START_CHARPOS (row) + delta; | 12634 | EMACS_INT pos_before = MATRIX_ROW_START_CHARPOS (row) + delta; |
| 12625 | EMACS_INT pos_after = MATRIX_ROW_END_CHARPOS (row) + delta; | 12635 | EMACS_INT pos_after = MATRIX_ROW_END_CHARPOS (row) + delta; |
| @@ -12655,8 +12665,8 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos) | |||
| 12655 | } | 12665 | } |
| 12656 | while (end > glyph | 12666 | while (end > glyph |
| 12657 | && INTEGERP ((end - 1)->object) | 12667 | && INTEGERP ((end - 1)->object) |
| 12658 | /* CHARPOS is zero for blanks inserted by | 12668 | /* CHARPOS is zero for blanks and stretch glyphs |
| 12659 | extend_face_to_end_of_line. */ | 12669 | inserted by extend_face_to_end_of_line. */ |
| 12660 | && (end - 1)->charpos <= 0) | 12670 | && (end - 1)->charpos <= 0) |
| 12661 | --end; | 12671 | --end; |
| 12662 | glyph_before = glyph - 1; | 12672 | glyph_before = glyph - 1; |
| @@ -12670,9 +12680,6 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos) | |||
| 12670 | to front, so swap the edge pointers. */ | 12680 | to front, so swap the edge pointers. */ |
| 12671 | glyphs_end = end = glyph - 1; | 12681 | glyphs_end = end = glyph - 1; |
| 12672 | glyph += row->used[TEXT_AREA] - 1; | 12682 | glyph += row->used[TEXT_AREA] - 1; |
| 12673 | /* Reverse the known positions in the row. */ | ||
| 12674 | last_pos = pos_after = MATRIX_ROW_START_CHARPOS (row) + delta; | ||
| 12675 | pos_before = MATRIX_ROW_END_CHARPOS (row) + delta; | ||
| 12676 | 12683 | ||
| 12677 | while (glyph > end + 1 | 12684 | while (glyph > end + 1 |
| 12678 | && INTEGERP (glyph->object) | 12685 | && INTEGERP (glyph->object) |
| @@ -12687,7 +12694,6 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos) | |||
| 12687 | rightmost (first in the reading order) glyph. */ | 12694 | rightmost (first in the reading order) glyph. */ |
| 12688 | for (g = end + 1; g < glyph; g++) | 12695 | for (g = end + 1; g < glyph; g++) |
| 12689 | x += g->pixel_width; | 12696 | x += g->pixel_width; |
| 12690 | cursor_x = x; | ||
| 12691 | while (end < glyph | 12697 | while (end < glyph |
| 12692 | && INTEGERP ((end + 1)->object) | 12698 | && INTEGERP ((end + 1)->object) |
| 12693 | && (end + 1)->charpos <= 0) | 12699 | && (end + 1)->charpos <= 0) |
| @@ -12702,7 +12708,7 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos) | |||
| 12702 | rightmost glyph. Case in point: an empty last line that is | 12708 | rightmost glyph. Case in point: an empty last line that is |
| 12703 | part of an R2L paragraph. */ | 12709 | part of an R2L paragraph. */ |
| 12704 | cursor = end - 1; | 12710 | cursor = end - 1; |
| 12705 | x = -1; /* will be computed below, at lable compute_x */ | 12711 | x = -1; /* will be computed below, at label compute_x */ |
| 12706 | } | 12712 | } |
| 12707 | 12713 | ||
| 12708 | /* Step 1: Try to find the glyph whose character position | 12714 | /* Step 1: Try to find the glyph whose character position |
| @@ -12838,8 +12844,11 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos) | |||
| 12838 | string_seen = 1; | 12844 | string_seen = 1; |
| 12839 | } | 12845 | } |
| 12840 | --glyph; | 12846 | --glyph; |
| 12841 | if (glyph == end) | 12847 | if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */ |
| 12842 | break; | 12848 | { |
| 12849 | x--; /* can't use any pixel_width */ | ||
| 12850 | break; | ||
| 12851 | } | ||
| 12843 | x -= glyph->pixel_width; | 12852 | x -= glyph->pixel_width; |
| 12844 | } | 12853 | } |
| 12845 | 12854 | ||
| @@ -12879,7 +12888,10 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos) | |||
| 12879 | } | 12888 | } |
| 12880 | else if (match_with_avoid_cursor | 12889 | else if (match_with_avoid_cursor |
| 12881 | /* zero-width characters produce no glyphs */ | 12890 | /* zero-width characters produce no glyphs */ |
| 12882 | || eabs (glyph_after - glyph_before) == 1) | 12891 | || ((row->reversed_p |
| 12892 | ? glyph_after > glyphs_end | ||
| 12893 | : glyph_after < glyphs_end) | ||
| 12894 | && eabs (glyph_after - glyph_before) == 1)) | ||
| 12883 | { | 12895 | { |
| 12884 | cursor = glyph_after; | 12896 | cursor = glyph_after; |
| 12885 | x = -1; | 12897 | x = -1; |
| @@ -12998,16 +13010,17 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos) | |||
| 12998 | } | 13010 | } |
| 12999 | } | 13011 | } |
| 13000 | 13012 | ||
| 13001 | /* ROW could be part of a continued line, which might have other | 13013 | /* ROW could be part of a continued line, which, under bidi |
| 13002 | rows whose start and end charpos occlude point. Only set | 13014 | reordering, might have other rows whose start and end charpos |
| 13003 | w->cursor if we found a better approximation to the cursor | 13015 | occlude point. Only set w->cursor if we found a better |
| 13004 | position than we have from previously examined rows. */ | 13016 | approximation to the cursor position than we have from previously |
| 13017 | examined candidate rows belonging to the same continued line. */ | ||
| 13005 | if (/* we already have a candidate row */ | 13018 | if (/* we already have a candidate row */ |
| 13006 | w->cursor.vpos >= 0 | 13019 | w->cursor.vpos >= 0 |
| 13007 | /* that candidate is not the row we are processing */ | 13020 | /* that candidate is not the row we are processing */ |
| 13008 | && MATRIX_ROW (matrix, w->cursor.vpos) != row | 13021 | && MATRIX_ROW (matrix, w->cursor.vpos) != row |
| 13009 | /* this row is part of a continued line */ | 13022 | /* the row we are processing is part of a continued line */ |
| 13010 | && (row->continued_p || row->continuation_lines_width) | 13023 | && (row->continued_p || MATRIX_ROW_CONTINUATION_LINE_P (row)) |
| 13011 | /* Make sure cursor.vpos specifies a row whose start and end | 13024 | /* Make sure cursor.vpos specifies a row whose start and end |
| 13012 | charpos occlude point. This is because some callers of this | 13025 | charpos occlude point. This is because some callers of this |
| 13013 | function leave cursor.vpos at the row where the cursor was | 13026 | function leave cursor.vpos at the row where the cursor was |
| @@ -16850,9 +16863,11 @@ append_space_for_newline (it, default_face_p) | |||
| 16850 | 16863 | ||
| 16851 | 16864 | ||
| 16852 | /* Extend the face of the last glyph in the text area of IT->glyph_row | 16865 | /* Extend the face of the last glyph in the text area of IT->glyph_row |
| 16853 | to the end of the display line. Called from display_line. | 16866 | to the end of the display line. Called from display_line. If the |
| 16854 | If the glyph row is empty, add a space glyph to it so that we | 16867 | glyph row is empty, add a space glyph to it so that we know the |
| 16855 | know the face to draw. Set the glyph row flag fill_line_p. */ | 16868 | face to draw. Set the glyph row flag fill_line_p. If the glyph |
| 16869 | row is R2L, prepend a stretch glyph to cover the empty space to the | ||
| 16870 | left of the leftmost glyph. */ | ||
| 16856 | 16871 | ||
| 16857 | static void | 16872 | static void |
| 16858 | extend_face_to_end_of_line (it) | 16873 | extend_face_to_end_of_line (it) |
| @@ -16861,15 +16876,17 @@ extend_face_to_end_of_line (it) | |||
| 16861 | struct face *face; | 16876 | struct face *face; |
| 16862 | struct frame *f = it->f; | 16877 | struct frame *f = it->f; |
| 16863 | 16878 | ||
| 16864 | /* If line is already filled, do nothing. */ | 16879 | /* If line is already filled, do nothing. Non window-system frames |
| 16865 | if (it->current_x >= it->last_visible_x) | 16880 | get a grace of one more ``pixel'' because their characters are |
| 16881 | 1-``pixel'' wide, so they hit the equality too early. */ | ||
| 16882 | if (it->current_x >= it->last_visible_x + !FRAME_WINDOW_P (f)) | ||
| 16866 | return; | 16883 | return; |
| 16867 | 16884 | ||
| 16868 | /* Face extension extends the background and box of IT->face_id | 16885 | /* Face extension extends the background and box of IT->face_id |
| 16869 | to the end of the line. If the background equals the background | 16886 | to the end of the line. If the background equals the background |
| 16870 | of the frame, we don't have to do anything. */ | 16887 | of the frame, we don't have to do anything. */ |
| 16871 | if (it->face_before_selective_p) | 16888 | if (it->face_before_selective_p) |
| 16872 | face = FACE_FROM_ID (it->f, it->saved_face_id); | 16889 | face = FACE_FROM_ID (f, it->saved_face_id); |
| 16873 | else | 16890 | else |
| 16874 | face = FACE_FROM_ID (f, it->face_id); | 16891 | face = FACE_FROM_ID (f, it->face_id); |
| 16875 | 16892 | ||
| @@ -16877,7 +16894,8 @@ extend_face_to_end_of_line (it) | |||
| 16877 | && it->glyph_row->displays_text_p | 16894 | && it->glyph_row->displays_text_p |
| 16878 | && face->box == FACE_NO_BOX | 16895 | && face->box == FACE_NO_BOX |
| 16879 | && face->background == FRAME_BACKGROUND_PIXEL (f) | 16896 | && face->background == FRAME_BACKGROUND_PIXEL (f) |
| 16880 | && !face->stipple) | 16897 | && !face->stipple |
| 16898 | && !it->glyph_row->reversed_p) | ||
| 16881 | return; | 16899 | return; |
| 16882 | 16900 | ||
| 16883 | /* Set the glyph row flag indicating that the face of the last glyph | 16901 | /* Set the glyph row flag indicating that the face of the last glyph |
| @@ -16904,6 +16922,50 @@ extend_face_to_end_of_line (it) | |||
| 16904 | it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id; | 16922 | it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id; |
| 16905 | it->glyph_row->used[TEXT_AREA] = 1; | 16923 | it->glyph_row->used[TEXT_AREA] = 1; |
| 16906 | } | 16924 | } |
| 16925 | #ifdef HAVE_WINDOW_SYSTEM | ||
| 16926 | if (it->glyph_row->reversed_p) | ||
| 16927 | { | ||
| 16928 | /* Prepend a stretch glyph to the row, such that the | ||
| 16929 | rightmost glyph will be drawn flushed all the way to the | ||
| 16930 | right margin of the window. The stretch glyph that will | ||
| 16931 | occupy the empty space, if any, to the left of the | ||
| 16932 | glyphs. */ | ||
| 16933 | struct font *font = face->font ? face->font : FRAME_FONT (f); | ||
| 16934 | struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA]; | ||
| 16935 | struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA]; | ||
| 16936 | struct glyph *g; | ||
| 16937 | int row_width, stretch_ascent, stretch_width; | ||
| 16938 | struct text_pos saved_pos; | ||
| 16939 | int saved_face_id, saved_avoid_cursor; | ||
| 16940 | |||
| 16941 | for (row_width = 0, g = row_start; g < row_end; g++) | ||
| 16942 | row_width += g->pixel_width; | ||
| 16943 | stretch_width = window_box_width (it->w, TEXT_AREA) - row_width; | ||
| 16944 | if (stretch_width > 0) | ||
| 16945 | { | ||
| 16946 | stretch_ascent = | ||
| 16947 | (((it->ascent + it->descent) | ||
| 16948 | * FONT_BASE (font)) / FONT_HEIGHT (font)); | ||
| 16949 | saved_pos = it->position; | ||
| 16950 | bzero (&it->position, sizeof it->position); | ||
| 16951 | saved_avoid_cursor = it->avoid_cursor_p; | ||
| 16952 | it->avoid_cursor_p = 1; | ||
| 16953 | saved_face_id = it->face_id; | ||
| 16954 | /* The last row's stretch glyph should get the default | ||
| 16955 | face, to avoid painting the rest of the window with | ||
| 16956 | the region face, if the region ends at ZV. */ | ||
| 16957 | if (it->glyph_row->ends_at_zv_p) | ||
| 16958 | it->face_id = DEFAULT_FACE_ID; | ||
| 16959 | else | ||
| 16960 | it->face_id = face->id; | ||
| 16961 | append_stretch_glyph (it, make_number (0), stretch_width, | ||
| 16962 | it->ascent + it->descent, stretch_ascent); | ||
| 16963 | it->position = saved_pos; | ||
| 16964 | it->avoid_cursor_p = saved_avoid_cursor; | ||
| 16965 | it->face_id = saved_face_id; | ||
| 16966 | } | ||
| 16967 | } | ||
| 16968 | #endif /* HAVE_WINDOW_SYSTEM */ | ||
| 16907 | } | 16969 | } |
| 16908 | else | 16970 | else |
| 16909 | { | 16971 | { |
| @@ -16922,7 +16984,13 @@ extend_face_to_end_of_line (it) | |||
| 16922 | it->object = make_number (0); | 16984 | it->object = make_number (0); |
| 16923 | it->c = ' '; | 16985 | it->c = ' '; |
| 16924 | it->len = 1; | 16986 | it->len = 1; |
| 16925 | it->face_id = face->id; | 16987 | /* The last row's blank glyphs should get the default face, to |
| 16988 | avoid painting the rest of the window with the region face, | ||
| 16989 | if the region ends at ZV. */ | ||
| 16990 | if (it->glyph_row->ends_at_zv_p) | ||
| 16991 | it->face_id = DEFAULT_FACE_ID; | ||
| 16992 | else | ||
| 16993 | it->face_id = face->id; | ||
| 16926 | 16994 | ||
| 16927 | PRODUCE_GLYPHS (it); | 16995 | PRODUCE_GLYPHS (it); |
| 16928 | 16996 | ||
| @@ -17208,6 +17276,31 @@ handle_line_prefix (struct it *it) | |||
| 17208 | 17276 | ||
| 17209 | 17277 | ||
| 17210 | 17278 | ||
| 17279 | /* Remove N glyphs at the start of a reversed IT->glyph_row. Called | ||
| 17280 | only for R2L lines from display_line, when it decides that too many | ||
| 17281 | glyphs were produced by PRODUCE_GLYPHS, and the line needs to be | ||
| 17282 | continued. */ | ||
| 17283 | static void | ||
| 17284 | unproduce_glyphs (it, n) | ||
| 17285 | struct it *it; | ||
| 17286 | int n; | ||
| 17287 | { | ||
| 17288 | struct glyph *glyph, *end; | ||
| 17289 | |||
| 17290 | xassert (it->glyph_row); | ||
| 17291 | xassert (it->glyph_row->reversed_p); | ||
| 17292 | xassert (it->area == TEXT_AREA); | ||
| 17293 | xassert (n <= it->glyph_row->used[TEXT_AREA]); | ||
| 17294 | |||
| 17295 | if (n > it->glyph_row->used[TEXT_AREA]) | ||
| 17296 | n = it->glyph_row->used[TEXT_AREA]; | ||
| 17297 | glyph = it->glyph_row->glyphs[TEXT_AREA] + n; | ||
| 17298 | end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA]; | ||
| 17299 | for ( ; glyph < end; glyph++) | ||
| 17300 | glyph[-n] = *glyph; | ||
| 17301 | } | ||
| 17302 | |||
| 17303 | |||
| 17211 | /* Construct the glyph row IT->glyph_row in the desired matrix of | 17304 | /* Construct the glyph row IT->glyph_row in the desired matrix of |
| 17212 | IT->w from text at the current position of IT. See dispextern.h | 17305 | IT->w from text at the current position of IT. See dispextern.h |
| 17213 | for an overview of struct it. Value is non-zero if | 17306 | for an overview of struct it. Value is non-zero if |
| @@ -17472,6 +17565,9 @@ display_line (it) | |||
| 17472 | /* A padding glyph that doesn't fit on this line. | 17565 | /* A padding glyph that doesn't fit on this line. |
| 17473 | This means the whole character doesn't fit | 17566 | This means the whole character doesn't fit |
| 17474 | on the line. */ | 17567 | on the line. */ |
| 17568 | if (row->reversed_p) | ||
| 17569 | unproduce_glyphs (it, row->used[TEXT_AREA] | ||
| 17570 | - n_glyphs_before); | ||
| 17475 | row->used[TEXT_AREA] = n_glyphs_before; | 17571 | row->used[TEXT_AREA] = n_glyphs_before; |
| 17476 | 17572 | ||
| 17477 | /* Fill the rest of the row with continuation | 17573 | /* Fill the rest of the row with continuation |
| @@ -17494,6 +17590,9 @@ display_line (it) | |||
| 17494 | else if (wrap_row_used > 0) | 17590 | else if (wrap_row_used > 0) |
| 17495 | { | 17591 | { |
| 17496 | back_to_wrap: | 17592 | back_to_wrap: |
| 17593 | if (row->reversed_p) | ||
| 17594 | unproduce_glyphs (it, | ||
| 17595 | row->used[TEXT_AREA] - wrap_row_used); | ||
| 17497 | *it = wrap_it; | 17596 | *it = wrap_it; |
| 17498 | it->continuation_lines_width += wrap_x; | 17597 | it->continuation_lines_width += wrap_x; |
| 17499 | row->used[TEXT_AREA] = wrap_row_used; | 17598 | row->used[TEXT_AREA] = wrap_row_used; |
| @@ -17529,6 +17628,9 @@ display_line (it) | |||
| 17529 | /* Something other than a TAB that draws past | 17628 | /* Something other than a TAB that draws past |
| 17530 | the right edge of the window. Restore | 17629 | the right edge of the window. Restore |
| 17531 | positions to values before the element. */ | 17630 | positions to values before the element. */ |
| 17631 | if (row->reversed_p) | ||
| 17632 | unproduce_glyphs (it, row->used[TEXT_AREA] | ||
| 17633 | - (n_glyphs_before + i)); | ||
| 17532 | row->used[TEXT_AREA] = n_glyphs_before + i; | 17634 | row->used[TEXT_AREA] = n_glyphs_before + i; |
| 17533 | 17635 | ||
| 17534 | /* Display continuation glyphs. */ | 17636 | /* Display continuation glyphs. */ |
| @@ -17634,9 +17736,22 @@ display_line (it) | |||
| 17634 | { | 17736 | { |
| 17635 | int i, n; | 17737 | int i, n; |
| 17636 | 17738 | ||
| 17637 | for (i = row->used[TEXT_AREA] - 1; i > 0; --i) | 17739 | if (!row->reversed_p) |
| 17638 | if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i])) | 17740 | { |
| 17639 | break; | 17741 | for (i = row->used[TEXT_AREA] - 1; i > 0; --i) |
| 17742 | if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i])) | ||
| 17743 | break; | ||
| 17744 | } | ||
| 17745 | else | ||
| 17746 | { | ||
| 17747 | for (i = 0; i < row->used[TEXT_AREA]; i++) | ||
| 17748 | if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i])) | ||
| 17749 | break; | ||
| 17750 | /* Remove padding glyphs at the front of ROW, to | ||
| 17751 | make room for the truncation glyphs we will be | ||
| 17752 | adding below. */ | ||
| 17753 | unproduce_glyphs (it, i); | ||
| 17754 | } | ||
| 17640 | 17755 | ||
| 17641 | for (n = row->used[TEXT_AREA]; i < n; ++i) | 17756 | for (n = row->used[TEXT_AREA]; i < n; ++i) |
| 17642 | { | 17757 | { |
| @@ -17823,7 +17938,7 @@ display_line (it) | |||
| 17823 | *it = save_it; | 17938 | *it = save_it; |
| 17824 | } | 17939 | } |
| 17825 | else if (!row->continued_p | 17940 | else if (!row->continued_p |
| 17826 | && row->continuation_lines_width | 17941 | && MATRIX_ROW_CONTINUATION_LINE_P (row) |
| 17827 | && it->eol_pos.charpos > 0) | 17942 | && it->eol_pos.charpos > 0) |
| 17828 | { | 17943 | { |
| 17829 | /* Last row of a continued line. Use the position | 17944 | /* Last row of a continued line. Use the position |
| @@ -21493,6 +21608,17 @@ append_composite_glyph (it) | |||
| 21493 | glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; | 21608 | glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; |
| 21494 | if (glyph < it->glyph_row->glyphs[area + 1]) | 21609 | if (glyph < it->glyph_row->glyphs[area + 1]) |
| 21495 | { | 21610 | { |
| 21611 | /* If the glyph row is reversed, we need to prepend the glyph | ||
| 21612 | rather than append it. */ | ||
| 21613 | if (it->glyph_row->reversed_p && it->area == TEXT_AREA) | ||
| 21614 | { | ||
| 21615 | struct glyph *g; | ||
| 21616 | |||
| 21617 | /* Make room for the new glyph. */ | ||
| 21618 | for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--) | ||
| 21619 | g[1] = *g; | ||
| 21620 | glyph = it->glyph_row->glyphs[it->area]; | ||
| 21621 | } | ||
| 21496 | glyph->charpos = CHARPOS (it->position); | 21622 | glyph->charpos = CHARPOS (it->position); |
| 21497 | glyph->object = it->object; | 21623 | glyph->object = it->object; |
| 21498 | glyph->pixel_width = it->pixel_width; | 21624 | glyph->pixel_width = it->pixel_width; |
| @@ -21738,6 +21864,17 @@ append_stretch_glyph (it, object, width, height, ascent) | |||
| 21738 | glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; | 21864 | glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; |
| 21739 | if (glyph < it->glyph_row->glyphs[area + 1]) | 21865 | if (glyph < it->glyph_row->glyphs[area + 1]) |
| 21740 | { | 21866 | { |
| 21867 | /* If the glyph row is reversed, we need to prepend the glyph | ||
| 21868 | rather than append it. */ | ||
| 21869 | if (it->glyph_row->reversed_p && area == TEXT_AREA) | ||
| 21870 | { | ||
| 21871 | struct glyph *g; | ||
| 21872 | |||
| 21873 | /* Make room for the additional glyph. */ | ||
| 21874 | for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--) | ||
| 21875 | g[1] = *g; | ||
| 21876 | glyph = it->glyph_row->glyphs[area]; | ||
| 21877 | } | ||
| 21741 | glyph->charpos = CHARPOS (it->position); | 21878 | glyph->charpos = CHARPOS (it->position); |
| 21742 | glyph->object = object; | 21879 | glyph->object = object; |
| 21743 | glyph->pixel_width = width; | 21880 | glyph->pixel_width = width; |
| @@ -21764,6 +21901,11 @@ append_stretch_glyph (it, object, width, height, ascent) | |||
| 21764 | abort (); | 21901 | abort (); |
| 21765 | glyph->bidi_type = it->bidi_it.type; | 21902 | glyph->bidi_type = it->bidi_it.type; |
| 21766 | } | 21903 | } |
| 21904 | else | ||
| 21905 | { | ||
| 21906 | glyph->resolved_level = 0; | ||
| 21907 | glyph->bidi_type = UNKNOWN_BT; | ||
| 21908 | } | ||
| 21767 | ++it->glyph_row->used[area]; | 21909 | ++it->glyph_row->used[area]; |
| 21768 | } | 21910 | } |
| 21769 | else | 21911 | else |
| @@ -23244,7 +23386,7 @@ notice_overwritten_cursor (w, area, x0, x1, y0, y1) | |||
| 23244 | if (row->cursor_in_fringe_p) | 23386 | if (row->cursor_in_fringe_p) |
| 23245 | { | 23387 | { |
| 23246 | row->cursor_in_fringe_p = 0; | 23388 | row->cursor_in_fringe_p = 0; |
| 23247 | draw_fringe_bitmap (w, row, 0); | 23389 | draw_fringe_bitmap (w, row, row->reversed_p); |
| 23248 | w->phys_cursor_on_p = 0; | 23390 | w->phys_cursor_on_p = 0; |
| 23249 | return; | 23391 | return; |
| 23250 | } | 23392 | } |
| @@ -23345,7 +23487,9 @@ draw_phys_cursor_glyph (w, row, hl) | |||
| 23345 | /* If cursor hpos is out of bounds, don't draw garbage. This can | 23487 | /* If cursor hpos is out of bounds, don't draw garbage. This can |
| 23346 | happen in mini-buffer windows when switching between echo area | 23488 | happen in mini-buffer windows when switching between echo area |
| 23347 | glyphs and mini-buffer. */ | 23489 | glyphs and mini-buffer. */ |
| 23348 | if (w->phys_cursor.hpos < row->used[TEXT_AREA]) | 23490 | if ((row->reversed_p |
| 23491 | ? (w->phys_cursor.hpos >= 0) | ||
| 23492 | : (w->phys_cursor.hpos < row->used[TEXT_AREA]))) | ||
| 23349 | { | 23493 | { |
| 23350 | int on_p = w->phys_cursor_on_p; | 23494 | int on_p = w->phys_cursor_on_p; |
| 23351 | int x1; | 23495 | int x1; |
| @@ -23425,7 +23569,7 @@ erase_phys_cursor (w) | |||
| 23425 | if (cursor_row->cursor_in_fringe_p) | 23569 | if (cursor_row->cursor_in_fringe_p) |
| 23426 | { | 23570 | { |
| 23427 | cursor_row->cursor_in_fringe_p = 0; | 23571 | cursor_row->cursor_in_fringe_p = 0; |
| 23428 | draw_fringe_bitmap (w, cursor_row, 0); | 23572 | draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p); |
| 23429 | goto mark_cursor_off; | 23573 | goto mark_cursor_off; |
| 23430 | } | 23574 | } |
| 23431 | 23575 | ||
| @@ -23434,7 +23578,9 @@ erase_phys_cursor (w) | |||
| 23434 | should have cleared the cursor. Note that we wouldn't be | 23578 | should have cleared the cursor. Note that we wouldn't be |
| 23435 | able to erase the cursor in this case because we don't have a | 23579 | able to erase the cursor in this case because we don't have a |
| 23436 | cursor glyph at hand. */ | 23580 | cursor glyph at hand. */ |
| 23437 | if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA]) | 23581 | if ((cursor_row->reversed_p |
| 23582 | ? (w->phys_cursor.hpos < 0) | ||
| 23583 | : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA]))) | ||
| 23438 | goto mark_cursor_off; | 23584 | goto mark_cursor_off; |
| 23439 | 23585 | ||
| 23440 | /* If the cursor is in the mouse face area, redisplay that when | 23586 | /* If the cursor is in the mouse face area, redisplay that when |
| @@ -23450,7 +23596,7 @@ erase_phys_cursor (w) | |||
| 23450 | /* Don't redraw the cursor's spot in mouse face if it is at the | 23596 | /* Don't redraw the cursor's spot in mouse face if it is at the |
| 23451 | end of a line (on a newline). The cursor appears there, but | 23597 | end of a line (on a newline). The cursor appears there, but |
| 23452 | mouse highlighting does not. */ | 23598 | mouse highlighting does not. */ |
| 23453 | && cursor_row->used[TEXT_AREA] > hpos) | 23599 | && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0) |
| 23454 | mouse_face_here_p = 1; | 23600 | mouse_face_here_p = 1; |
| 23455 | 23601 | ||
| 23456 | /* Maybe clear the display under the cursor. */ | 23602 | /* Maybe clear the display under the cursor. */ |
| @@ -23532,7 +23678,7 @@ display_and_set_cursor (w, on, hpos, vpos, x, y) | |||
| 23532 | 23678 | ||
| 23533 | glyph = NULL; | 23679 | glyph = NULL; |
| 23534 | if (!glyph_row->exact_window_width_line_p | 23680 | if (!glyph_row->exact_window_width_line_p |
| 23535 | || hpos < glyph_row->used[TEXT_AREA]) | 23681 | || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA])) |
| 23536 | glyph = glyph_row->glyphs[TEXT_AREA] + hpos; | 23682 | glyph = glyph_row->glyphs[TEXT_AREA] + hpos; |
| 23537 | 23683 | ||
| 23538 | xassert (interrupt_input_blocked); | 23684 | xassert (interrupt_input_blocked); |
diff --git a/src/xterm.c b/src/xterm.c index 29ed5bb865c..712d4aaa162 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -7492,36 +7492,40 @@ x_draw_window_cursor (w, glyph_row, x, y, cursor_type, cursor_width, on_p, activ | |||
| 7492 | w->phys_cursor_on_p = 1; | 7492 | w->phys_cursor_on_p = 1; |
| 7493 | 7493 | ||
| 7494 | if (glyph_row->exact_window_width_line_p | 7494 | if (glyph_row->exact_window_width_line_p |
| 7495 | && w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA]) | 7495 | && (glyph_row->reversed_p |
| 7496 | ? (w->phys_cursor.hpos < 0) | ||
| 7497 | : (w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA]))) | ||
| 7496 | { | 7498 | { |
| 7497 | glyph_row->cursor_in_fringe_p = 1; | 7499 | glyph_row->cursor_in_fringe_p = 1; |
| 7498 | draw_fringe_bitmap (w, glyph_row, 0); | 7500 | draw_fringe_bitmap (w, glyph_row, glyph_row->reversed_p); |
| 7499 | } | 7501 | } |
| 7500 | else | 7502 | else |
| 7501 | switch (cursor_type) | ||
| 7502 | { | 7503 | { |
| 7503 | case HOLLOW_BOX_CURSOR: | 7504 | switch (cursor_type) |
| 7504 | x_draw_hollow_cursor (w, glyph_row); | 7505 | { |
| 7505 | break; | 7506 | case HOLLOW_BOX_CURSOR: |
| 7507 | x_draw_hollow_cursor (w, glyph_row); | ||
| 7508 | break; | ||
| 7506 | 7509 | ||
| 7507 | case FILLED_BOX_CURSOR: | 7510 | case FILLED_BOX_CURSOR: |
| 7508 | draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR); | 7511 | draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR); |
| 7509 | break; | 7512 | break; |
| 7510 | 7513 | ||
| 7511 | case BAR_CURSOR: | 7514 | case BAR_CURSOR: |
| 7512 | x_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR); | 7515 | x_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR); |
| 7513 | break; | 7516 | break; |
| 7514 | 7517 | ||
| 7515 | case HBAR_CURSOR: | 7518 | case HBAR_CURSOR: |
| 7516 | x_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR); | 7519 | x_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR); |
| 7517 | break; | 7520 | break; |
| 7518 | 7521 | ||
| 7519 | case NO_CURSOR: | 7522 | case NO_CURSOR: |
| 7520 | w->phys_cursor_width = 0; | 7523 | w->phys_cursor_width = 0; |
| 7521 | break; | 7524 | break; |
| 7522 | 7525 | ||
| 7523 | default: | 7526 | default: |
| 7524 | abort (); | 7527 | abort (); |
| 7528 | } | ||
| 7525 | } | 7529 | } |
| 7526 | 7530 | ||
| 7527 | #ifdef HAVE_X_I18N | 7531 | #ifdef HAVE_X_I18N |