Mercurial > emacs
comparison src/xdisp.c @ 107998:531d454c3a99
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.
author | Eli Zaretskii <eliz@gnu.org> |
---|---|
date | Tue, 20 Apr 2010 16:31:28 +0300 |
parents | bef5d1738c0b 8ef8b6523597 |
children | 4d8277a44bb4 |
comparison
equal
deleted
inserted
replaced
107997:d94009e7a0cc | 107998:531d454c3a99 |
---|---|
402 extern Lisp_Object Voverflow_newline_into_fringe; | 402 extern Lisp_Object Voverflow_newline_into_fringe; |
403 | 403 |
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 |
416 #endif /* HAVE_WINDOW_SYSTEM */ | 418 #endif /* HAVE_WINDOW_SYSTEM */ |
417 | 419 |
1075 static int redisplay_tool_bar P_ ((struct frame *)); | 1077 static int redisplay_tool_bar P_ ((struct frame *)); |
1076 static void display_tool_bar_line P_ ((struct it *, int)); | 1078 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 |
1083 #endif /* HAVE_WINDOW_SYSTEM */ | 1087 #endif /* HAVE_WINDOW_SYSTEM */ |
1084 | 1088 |
6707 a different paragraph. */ | 6711 a different paragraph. */ |
6708 if (it->bidi_p && it->bidi_it.first_elt) | 6712 if (it->bidi_p && it->bidi_it.first_elt) |
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 } |
6722 else | 6733 else |
6723 { | 6734 { |
12617 struct glyph *end = glyph + row->used[TEXT_AREA]; | 12628 struct glyph *end = glyph + row->used[TEXT_AREA]; |
12618 struct glyph *cursor = NULL; | 12629 struct glyph *cursor = NULL; |
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; |
12626 struct glyph *glyph_before = glyph - 1, *glyph_after = end; | 12636 struct glyph *glyph_before = glyph - 1, *glyph_after = end; |
12627 /* A glyph beyond the edge of TEXT_AREA which we should never | 12637 /* A glyph beyond the edge of TEXT_AREA which we should never |
12653 x += glyph->pixel_width; | 12663 x += glyph->pixel_width; |
12654 ++glyph; | 12664 ++glyph; |
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; |
12663 glyph_after = end; | 12673 glyph_after = end; |
12664 } | 12674 } |
12668 | 12678 |
12669 /* If the glyph row is reversed, we need to process it from back | 12679 /* If the glyph row is reversed, we need to process it from back |
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) |
12679 && glyph->charpos < 0) | 12686 && glyph->charpos < 0) |
12680 { | 12687 { |
12685 --glyph; | 12692 --glyph; |
12686 /* By default, in reversed rows we put the cursor on the | 12693 /* By default, in reversed rows we put the cursor on the |
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) |
12694 ++end; | 12700 ++end; |
12695 glyph_before = glyph + 1; | 12701 glyph_before = glyph + 1; |
12700 { | 12706 { |
12701 /* In R2L rows that don't display text, put the cursor on the | 12707 /* In R2L rows that don't display text, put the cursor on the |
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 |
12709 corresponds to point. If that's not possible, find 2 glyphs | 12715 corresponds to point. If that's not possible, find 2 glyphs |
12710 whose character positions are the closest to point, one before | 12716 whose character positions are the closest to point, one before |
12836 } | 12842 } |
12837 } | 12843 } |
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 |
12846 /* Step 2: If we didn't find an exact match for point, we need to | 12855 /* Step 2: If we didn't find an exact match for point, we need to |
12847 look for a proper place to put the cursor among glyphs between | 12856 look for a proper place to put the cursor among glyphs between |
12877 glyph--; | 12886 glyph--; |
12878 } | 12887 } |
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; |
12886 } | 12898 } |
12887 else if (string_seen) | 12899 else if (string_seen) |
12996 abort (); | 13008 abort (); |
12997 x += g->pixel_width; | 13009 x += g->pixel_width; |
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 |
13014 displayed during the last redisplay cycle. */ | 13027 displayed during the last redisplay cycle. */ |
13015 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old | 13028 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old |
16848 return 0; | 16861 return 0; |
16849 } | 16862 } |
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) |
16859 struct it *it; | 16874 struct it *it; |
16860 { | 16875 { |
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 |
16876 if (FRAME_WINDOW_P (f) | 16893 if (FRAME_WINDOW_P (f) |
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 |
16884 in the text area has to be drawn to the end of the text area. */ | 16902 in the text area has to be drawn to the end of the text area. */ |
16885 it->glyph_row->fill_line_p = 1; | 16903 it->glyph_row->fill_line_p = 1; |
16902 { | 16920 { |
16903 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph; | 16921 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph; |
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 { |
16910 /* Save some values that must not be changed. */ | 16972 /* Save some values that must not be changed. */ |
16911 int saved_x = it->current_x; | 16973 int saved_x = it->current_x; |
16920 it->what = IT_CHARACTER; | 16982 it->what = IT_CHARACTER; |
16921 bzero (&it->position, sizeof it->position); | 16983 bzero (&it->position, sizeof it->position); |
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 |
16929 while (it->current_x <= it->last_visible_x) | 16997 while (it->current_x <= it->last_visible_x) |
16930 PRODUCE_GLYPHS (it); | 16998 PRODUCE_GLYPHS (it); |
17205 it->avoid_cursor_p = 1; | 17273 it->avoid_cursor_p = 1; |
17206 } | 17274 } |
17207 } | 17275 } |
17208 | 17276 |
17209 | 17277 |
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 | |
17210 | 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 |
17214 IT->glyph_row displays text, as opposed to a line displaying ZV | 17307 IT->glyph_row displays text, as opposed to a line displaying ZV |
17470 && !FRAME_WINDOW_P (it->f)) | 17563 && !FRAME_WINDOW_P (it->f)) |
17471 { | 17564 { |
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 |
17478 glyphs like in 20.x. */ | 17574 glyphs like in 20.x. */ |
17479 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] | 17575 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] |
17492 it->max_phys_descent = phys_descent; | 17588 it->max_phys_descent = phys_descent; |
17493 } | 17589 } |
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; |
17500 row->ascent = wrap_row_ascent; | 17599 row->ascent = wrap_row_ascent; |
17501 row->height = wrap_row_height; | 17600 row->height = wrap_row_height; |
17527 else | 17626 else |
17528 { | 17627 { |
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. */ |
17535 if (!FRAME_WINDOW_P (it->f)) | 17637 if (!FRAME_WINDOW_P (it->f)) |
17536 produce_special_glyphs (it, IT_CONTINUATION); | 17638 produce_special_glyphs (it, IT_CONTINUATION); |
17632 /* Maybe add truncation glyphs. */ | 17734 /* Maybe add truncation glyphs. */ |
17633 if (!FRAME_WINDOW_P (it->f)) | 17735 if (!FRAME_WINDOW_P (it->f)) |
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 { |
17643 row->used[TEXT_AREA] = i; | 17758 row->used[TEXT_AREA] = i; |
17644 produce_special_glyphs (it, IT_TRUNCATION); | 17759 produce_special_glyphs (it, IT_TRUNCATION); |
17821 save_it.eol_pos.charpos = save_it.eol_pos.bytepos = 0; | 17936 save_it.eol_pos.charpos = save_it.eol_pos.bytepos = 0; |
17822 } | 17937 } |
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 |
17830 recorded in ROW->eol_pos, to the effect that the | 17945 recorded in ROW->eol_pos, to the effect that the |
17831 newline belongs to this row, not to the row which | 17946 newline belongs to this row, not to the row which |
21491 xassert (it->glyph_row); | 21606 xassert (it->glyph_row); |
21492 | 21607 |
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; |
21499 glyph->ascent = it->ascent; | 21625 glyph->ascent = it->ascent; |
21500 glyph->descent = it->descent; | 21626 glyph->descent = it->descent; |
21736 xassert (ascent >= 0 && ascent <= height); | 21862 xassert (ascent >= 0 && ascent <= height); |
21737 | 21863 |
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; |
21744 glyph->ascent = ascent; | 21881 glyph->ascent = ascent; |
21745 glyph->descent = height - ascent; | 21882 glyph->descent = height - ascent; |
21761 { | 21898 { |
21762 glyph->resolved_level = it->bidi_it.resolved_level; | 21899 glyph->resolved_level = it->bidi_it.resolved_level; |
21763 if ((it->bidi_it.type & 7) != it->bidi_it.type) | 21900 if ((it->bidi_it.type & 7) != it->bidi_it.type) |
21764 abort (); | 21901 abort (); |
21765 glyph->bidi_type = it->bidi_it.type; | 21902 glyph->bidi_type = it->bidi_it.type; |
21903 } | |
21904 else | |
21905 { | |
21906 glyph->resolved_level = 0; | |
21907 glyph->bidi_type = UNKNOWN_BT; | |
21766 } | 21908 } |
21767 ++it->glyph_row->used[area]; | 21909 ++it->glyph_row->used[area]; |
21768 } | 21910 } |
21769 else | 21911 else |
21770 IT_EXPAND_MATRIX_WIDTH (it, area); | 21912 IT_EXPAND_MATRIX_WIDTH (it, area); |
23242 return; | 23384 return; |
23243 | 23385 |
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 } |
23251 | 23393 |
23252 cx0 = w->phys_cursor.x; | 23394 cx0 = w->phys_cursor.x; |
23343 enum draw_glyphs_face hl; | 23485 enum draw_glyphs_face hl; |
23344 { | 23486 { |
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; |
23352 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, | 23496 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, |
23353 w->phys_cursor.hpos, w->phys_cursor.hpos + 1, | 23497 w->phys_cursor.hpos, w->phys_cursor.hpos + 1, |
23423 | 23567 |
23424 /* If cursor is in the fringe, erase by drawing actual bitmap there. */ | 23568 /* If cursor is in the fringe, erase by drawing actual bitmap there. */ |
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 |
23432 /* This can happen when the new row is shorter than the old one. | 23576 /* This can happen when the new row is shorter than the old one. |
23433 In this case, either draw_glyphs or clear_end_of_line | 23577 In this case, either draw_glyphs or clear_end_of_line |
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 |
23441 we clear the cursor. */ | 23587 we clear the cursor. */ |
23442 if (! NILP (dpyinfo->mouse_face_window) | 23588 if (! NILP (dpyinfo->mouse_face_window) |
23448 || (vpos == dpyinfo->mouse_face_end_row | 23594 || (vpos == dpyinfo->mouse_face_end_row |
23449 && hpos < dpyinfo->mouse_face_end_col)) | 23595 && hpos < dpyinfo->mouse_face_end_col)) |
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. */ |
23457 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR) | 23603 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR) |
23458 { | 23604 { |
23530 return; | 23676 return; |
23531 } | 23677 } |
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); |
23539 | 23685 |
23540 /* Set new_cursor_type to the cursor we want to be displayed. */ | 23686 /* Set new_cursor_type to the cursor we want to be displayed. */ |