X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/3907e630a71d48e693062b350571990d7ba08bbb..0877d0dc24ee792b9b14592869ea1aa0934aee58:/src/xdisp.c diff --git a/src/xdisp.c b/src/xdisp.c index 9464e87b36..8b0d8b6cfa 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -1,6 +1,7 @@ /* Display generation from window structure and buffer text. -Copyright (C) 1985-1988, 1993-1995, 1997-2012 Free Software Foundation, Inc. +Copyright (C) 1985-1988, 1993-1995, 1997-2013 Free Software Foundation, +Inc. This file is part of GNU Emacs. @@ -515,11 +516,6 @@ Lisp_Object Qmenu_bar_update_hook; static int overlay_arrow_seen; -/* Number of windows showing the buffer of the selected - window (or another buffer with the same base buffer). */ - -int buffer_shared; - /* Vector containing glyphs for an ellipsis `...'. */ static Lisp_Object default_invis_vector[3]; @@ -874,7 +870,6 @@ static void push_it (struct it *, struct text_pos *); static void iterate_out_of_display_property (struct it *); static void pop_it (struct it *); static void sync_frame_with_window_matrix_rows (struct window *); -static void select_frame_for_redisplay (Lisp_Object); static void redisplay_internal (void); static int echo_area_display (int); static void redisplay_windows (Lisp_Object); @@ -1335,7 +1330,7 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y, BVAR (current_buffer, header_line_format)); start_display (&it, w, top); - move_it_to (&it, charpos, -1, it.last_visible_y-1, -1, + move_it_to (&it, charpos, -1, it.last_visible_y - 1, -1, (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y); if (charpos >= 0 @@ -1343,7 +1338,7 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y, && IT_CHARPOS (it) >= charpos) /* When scanning backwards under bidi iteration, move_it_to stops at or _before_ CHARPOS, because it stops at or to - the _right_ of the character at CHARPOS. */ + the _right_ of the character at CHARPOS. */ || (it.bidi_p && it.bidi_it.scan_dir == -1 && IT_CHARPOS (it) <= charpos))) { @@ -2564,8 +2559,24 @@ check_window_end (struct window *w) #endif /* GLYPH_DEBUG and ENABLE_CHECKING */ +/* Return mark position if current buffer has the region of non-zero length, + or -1 otherwise. */ + +static ptrdiff_t +markpos_of_region (void) +{ + if (!NILP (Vtransient_mark_mode) + && !NILP (BVAR (current_buffer, mark_active)) + && XMARKER (BVAR (current_buffer, mark))->buffer != NULL) + { + ptrdiff_t markpos = XMARKER (BVAR (current_buffer, mark))->charpos; + + if (markpos != PT) + return markpos; + } + return -1; +} - /*********************************************************************** Iterator initialization ***********************************************************************/ @@ -2594,7 +2605,7 @@ init_iterator (struct it *it, struct window *w, ptrdiff_t charpos, ptrdiff_t bytepos, struct glyph_row *row, enum face_id base_face_id) { - int highlight_region_p; + ptrdiff_t markpos; enum face_id remapped_base_face_id = base_face_id; /* Some precondition checks. */ @@ -2697,16 +2708,11 @@ init_iterator (struct it *it, struct window *w, /* Are multibyte characters enabled in current_buffer? */ it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters)); - /* Non-zero if we should highlight the region. */ - highlight_region_p - = (!NILP (Vtransient_mark_mode) - && !NILP (BVAR (current_buffer, mark_active)) - && XMARKER (BVAR (current_buffer, mark))->buffer != 0); - - /* Set IT->region_beg_charpos and IT->region_end_charpos to the - start and end of a visible region in window IT->w. Set both to - -1 to indicate no region. */ - if (highlight_region_p + /* If visible region is of non-zero length, set IT->region_beg_charpos + and IT->region_end_charpos to the start and end of a visible region + in window IT->w. Set both to -1 to indicate no region. */ + markpos = markpos_of_region (); + if (0 <= markpos /* Maybe highlight only in selected window. */ && (/* Either show region everywhere. */ highlight_nonselected_windows @@ -2718,7 +2724,6 @@ init_iterator (struct it *it, struct window *w, && WINDOWP (minibuf_selected_window) && w == XWINDOW (minibuf_selected_window)))) { - ptrdiff_t markpos = marker_position (BVAR (current_buffer, mark)); it->region_beg_charpos = min (PT, markpos); it->region_end_charpos = max (PT, markpos); } @@ -3760,18 +3765,26 @@ handle_face_prop (struct it *it) if (new_face_id != it->face_id) { struct face *new_face = FACE_FROM_ID (it->f, new_face_id); + /* If it->face_id is -1, old_face below will be NULL, see + the definition of FACE_FROM_ID. This will happen if this + is the initial call that gets the face. */ + struct face *old_face = FACE_FROM_ID (it->f, it->face_id); - /* If new face has a box but old face has not, this is - the start of a run of characters with box, i.e. it has - a shadow on the left side. The value of face_id of the - iterator will be -1 if this is the initial call that gets - the face. In this case, we have to look in front of IT's - position and see whether there is a face != new_face_id. */ - it->start_of_box_run_p - = (new_face->box != FACE_NO_BOX - && (it->face_id >= 0 - || IT_CHARPOS (*it) == BEG - || new_face_id != face_before_it_pos (it))); + /* If the value of face_id of the iterator is -1, we have to + look in front of IT's position and see whether there is a + face there that's different from new_face_id. */ + if (!old_face && IT_CHARPOS (*it) > BEG) + { + int prev_face_id = face_before_it_pos (it); + + old_face = FACE_FROM_ID (it->f, prev_face_id); + } + + /* If the new face has a box, but the old face does not, + this is the start of a run of characters with box face, + i.e. this character has a shadow on the left side. */ + it->start_of_box_run_p = (new_face->box != FACE_NO_BOX + && (old_face == NULL || !old_face->box)); it->face_box_p = new_face->box != FACE_NO_BOX; } } @@ -9385,7 +9398,8 @@ message_dolog (const char *m, ptrdiff_t nbytes, int nlflag, int multibyte) int old_windows_or_buffers_changed = windows_or_buffers_changed; ptrdiff_t point_at_end = 0; ptrdiff_t zv_at_end = 0; - Lisp_Object old_deactivate_mark, tem; + Lisp_Object old_deactivate_mark; + bool shown; struct gcpro gcpro1; old_deactivate_mark = Vdeactivate_mark; @@ -9500,7 +9514,7 @@ message_dolog (const char *m, ptrdiff_t nbytes, int nlflag, int multibyte) del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0); } } - BEGV = XMARKER (oldbegv)->charpos; + BEGV = marker_position (oldbegv); BEGV_BYTE = marker_byte_position (oldbegv); if (zv_at_end) @@ -9510,7 +9524,7 @@ message_dolog (const char *m, ptrdiff_t nbytes, int nlflag, int multibyte) } else { - ZV = XMARKER (oldzv)->charpos; + ZV = marker_position (oldzv); ZV_BYTE = marker_byte_position (oldzv); } @@ -9519,17 +9533,17 @@ message_dolog (const char *m, ptrdiff_t nbytes, int nlflag, int multibyte) else /* We can't do Fgoto_char (oldpoint) because it will run some Lisp code. */ - TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos, - XMARKER (oldpoint)->bytepos); + TEMP_SET_PT_BOTH (marker_position (oldpoint), + marker_byte_position (oldpoint)); UNGCPRO; unchain_marker (XMARKER (oldpoint)); unchain_marker (XMARKER (oldbegv)); unchain_marker (XMARKER (oldzv)); - tem = Fget_buffer_window (Fcurrent_buffer (), Qt); + shown = buffer_window_count (current_buffer) > 0; set_buffer_internal (oldbuf); - if (NILP (tem)) + if (!shown) windows_or_buffers_changed = old_windows_or_buffers_changed; message_log_need_newline = !nlflag; Vdeactivate_mark = old_deactivate_mark; @@ -10092,8 +10106,8 @@ with_echo_area_buffer_unwind_data (struct window *w) { XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i; ASET (vector, i, w->buffer); ++i; - ASET (vector, i, make_number (XMARKER (w->pointm)->charpos)); ++i; - ASET (vector, i, make_number (XMARKER (w->pointm)->bytepos)); ++i; + ASET (vector, i, make_number (marker_position (w->pointm))); ++i; + ASET (vector, i, make_number (marker_byte_position (w->pointm))); ++i; } else { @@ -10390,8 +10404,7 @@ resize_mini_window (struct window *w, int exact_p) max_height = total_height / 4; /* Correct that max. height if it's bogus. */ - max_height = max (1, max_height); - max_height = min (total_height, max_height); + max_height = clip_to_bounds (1, max_height, total_height); /* Find out the height of the text in the window. */ if (it.line_wrap == TRUNCATE) @@ -10894,9 +10907,8 @@ echo_area_display (int update_frame_p) static int buffer_shared_and_changed (void) { - /* The variable buffer_shared is set in redisplay_window and - indicates that we redisplay a buffer in different windows. */ - return (buffer_shared > 1 && UNCHANGED_MODIFIED < MODIFF); + return (buffer_window_count (current_buffer) > 1 + && UNCHANGED_MODIFIED < MODIFF); } /* Nonzero if W doesn't reflect the actual state of current buffer due @@ -10906,7 +10918,7 @@ buffer_shared_and_changed (void) static int window_outdated (struct window *w) { - return (w->last_modified < MODIFF + return (w->last_modified < MODIFF || w->last_overlay_modified < OVERLAY_MODIFF); } @@ -12494,11 +12506,7 @@ hscroll_window_tree (Lisp_Object window) if (w == XWINDOW (selected_window)) pt = PT; else - { - pt = marker_position (w->pointm); - pt = max (BEGV, pt); - pt = min (ZV, pt); - } + pt = clip_to_bounds (BEGV, marker_position (w->pointm), ZV); /* Move iterator to pt starting at cursor_row->start in a line with infinite width. */ @@ -12945,46 +12953,6 @@ reconsider_clip_changes (struct window *w, struct buffer *b) } -/* Select FRAME to forward the values of frame-local variables into C - variables so that the redisplay routines can access those values - directly. */ - -static void -select_frame_for_redisplay (Lisp_Object frame) -{ - Lisp_Object tail, tem; - Lisp_Object old = selected_frame; - struct Lisp_Symbol *sym; - - eassert (FRAMEP (frame) && FRAME_LIVE_P (XFRAME (frame))); - - selected_frame = frame; - - do { - for (tail = XFRAME (frame)->param_alist; - CONSP (tail); tail = XCDR (tail)) - if (CONSP (XCAR (tail)) - && (tem = XCAR (XCAR (tail)), - SYMBOLP (tem)) - && (sym = indirect_variable (XSYMBOL (tem)), - sym->redirect == SYMBOL_LOCALIZED) - && sym->val.blv->frame_local) - /* Use find_symbol_value rather than Fsymbol_value - to avoid an error if it is void. */ - find_symbol_value (tem); - } while (!EQ (frame, old) && (frame = old, 1)); -} - -/* Make sure that previously selected OLD_FRAME is selected unless it has been - deleted (by an X connection failure during redisplay, for example). */ - -static void -ensure_selected_frame (Lisp_Object old_frame) -{ - if (!EQ (old_frame, selected_frame) && FRAME_LIVE_P (XFRAME (old_frame))) - select_frame_for_redisplay (old_frame); -} - #define STOP_POLLING \ do { if (! polling_stopped_here) stop_polling (); \ polling_stopped_here = 1; } while (0) @@ -13010,7 +12978,7 @@ redisplay_internal (void) ptrdiff_t count, count1; struct frame *sf; int polling_stopped_here = 0; - Lisp_Object tail, frame, old_frame = selected_frame; + Lisp_Object tail, frame; struct backtrace backtrace; /* Non-zero means redisplay has to consider all windows on all @@ -13069,12 +13037,6 @@ redisplay_internal (void) /* Remember the currently selected window. */ sw = w; - /* When running redisplay, we play a bit fast-and-loose and allow e.g. - selected_frame and selected_window to be temporarily out-of-sync so - when we come back here via `goto retry', we need to resync because we - may need to run Elisp code (via prepare_menu_bars). */ - ensure_selected_frame (old_frame); - pending = 0; reconsider_clip_changes (w, current_buffer); last_escape_glyph_frame = NULL; @@ -13470,10 +13432,6 @@ redisplay_internal (void) FOR_EACH_FRAME (tail, frame) XFRAME (frame)->updated_p = 0; - /* Recompute # windows showing selected buffer. This will be - incremented each time such a window is displayed. */ - buffer_shared = 0; - FOR_EACH_FRAME (tail, frame) { struct frame *f = XFRAME (frame); @@ -13486,11 +13444,6 @@ redisplay_internal (void) if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf) { - if (! EQ (frame, selected_frame)) - /* Select the frame, for the sake of frame-local - variables. */ - select_frame_for_redisplay (frame); - /* Mark all the scroll bars to be removed; we'll redeem the ones we want when we redisplay their windows. */ if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook) @@ -13540,10 +13493,6 @@ redisplay_internal (void) } } - /* We played a bit fast-and-loose above and allowed selected_frame - and selected_window to be temporarily out-of-sync but let's make - sure this stays contained. */ - ensure_selected_frame (old_frame); eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window)); if (!pending) @@ -13769,7 +13718,6 @@ static Lisp_Object unwind_redisplay (Lisp_Object old_frame) { redisplaying_p = 0; - ensure_selected_frame (old_frame); return Qnil; } @@ -13786,8 +13734,8 @@ mark_window_display_accurate_1 (struct window *w, int accurate_p) { struct buffer *b = XBUFFER (w->buffer); - w->last_modified = accurate_p ? BUF_MODIFF(b) : 0; - w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF(b) : 0; + w->last_modified = accurate_p ? BUF_MODIFF (b) : 0; + w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF (b) : 0; w->last_had_star = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b); @@ -13811,7 +13759,7 @@ mark_window_display_accurate_1 (struct window *w, int accurate_p) if (w == XWINDOW (selected_window)) w->last_point = BUF_PT (b); else - w->last_point = XMARKER (w->pointm)->charpos; + w->last_point = marker_position (w->pointm); } } @@ -14242,7 +14190,12 @@ set_cursor_from_row (struct window *w, struct glyph_row *row, CHARPOS is zero or negative. */ int empty_line_p = (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end) - && INTEGERP (glyph->object) && glyph->charpos > 0; + && INTEGERP (glyph->object) && glyph->charpos > 0 + /* On a TTY, continued and truncated rows also have a glyph at + their end whose OBJECT is zero and whose CHARPOS is + positive (the continuation and truncation glyphs), but such + rows are obviously not "empty". */ + && !(row->continued_p || row->truncated_on_right_p); if (row->ends_in_ellipsis_p && pos_after == last_pos) { @@ -15080,8 +15033,7 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste /* Can't use this case if highlighting a region. When a region exists, cursor movement has to do more than just set the cursor. */ - && !(!NILP (Vtransient_mark_mode) - && !NILP (BVAR (current_buffer, mark_active))) + && markpos_of_region () < 0 && NILP (w->region_showing) && NILP (Vshow_trailing_whitespace) /* This code is not used for mini-buffer for the sake of the case @@ -15568,26 +15520,11 @@ redisplay_window (Lisp_Object window, int just_this_one_p) if (mode_line_update_needed (w)) update_mode_line = 1; - /* Count number of windows showing the selected buffer. An indirect - buffer counts as its base buffer. */ - if (!just_this_one_p) - { - struct buffer *current_base, *window_base; - current_base = current_buffer; - window_base = XBUFFER (XWINDOW (selected_window)->buffer); - if (current_base->base_buffer) - current_base = current_base->base_buffer; - if (window_base->base_buffer) - window_base = window_base->base_buffer; - if (current_base == window_base) - buffer_shared++; - } - /* Point refers normally to the selected window. For any other window, set up appropriate value. */ if (!EQ (window, selected_window)) { - ptrdiff_t new_pt = XMARKER (w->pointm)->charpos; + ptrdiff_t new_pt = marker_position (w->pointm); ptrdiff_t new_pt_byte = marker_byte_position (w->pointm); if (new_pt < BEGV) { @@ -15718,7 +15655,6 @@ redisplay_window (Lisp_Object window, int just_this_one_p) /* Some people insist on not letting point enter the scroll margin, even though this part handles windows that didn't scroll at all. */ - struct frame *f = XFRAME (w->frame); int margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4); int pixel_margin = margin * FRAME_LINE_HEIGHT (f); bool header_line = WINDOW_WANTS_HEADER_LINE_P (w); @@ -15765,8 +15701,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p) /* If we are highlighting the region, then we just changed the region, so redisplay to show it. */ - if (!NILP (Vtransient_mark_mode) - && !NILP (BVAR (current_buffer, mark_active))) + if (0 <= markpos_of_region ()) { clear_glyph_matrix (w->desired_matrix); if (!try_window (window, startp, 0)) @@ -16471,8 +16406,7 @@ try_window_reusing_current_matrix (struct window *w) return 0; /* Can't do this if region may have changed. */ - if ((!NILP (Vtransient_mark_mode) - && !NILP (BVAR (current_buffer, mark_active))) + if (0 <= markpos_of_region () || !NILP (w->region_showing) || !NILP (Vshow_trailing_whitespace)) return 0; @@ -17304,8 +17238,7 @@ try_window_id (struct window *w) /* Can't use this if highlighting a region because a cursor movement will do more than just set the cursor. */ - if (!NILP (Vtransient_mark_mode) - && !NILP (BVAR (current_buffer, mark_active))) + if (0 <= markpos_of_region ()) GIVE_UP (9); /* Likewise if highlighting trailing whitespace. */ @@ -18638,6 +18571,7 @@ append_space_for_newline (struct it *it, int default_face_p) int saved_char_to_display = it->char_to_display; int saved_x = it->current_x; int saved_face_id = it->face_id; + int saved_box_end = it->end_of_box_run_p; struct text_pos saved_pos; Lisp_Object saved_object; struct face *face; @@ -18659,6 +18593,16 @@ append_space_for_newline (struct it *it, int default_face_p) it->face_id = it->saved_face_id; face = FACE_FROM_ID (it->f, it->face_id); it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil); + /* In R2L rows, we will prepend a stretch glyph that will + have the end_of_box_run_p flag set for it, so there's no + need for the appended newline glyph to have that flag + set. */ + if (it->glyph_row->reversed_p + /* But if the appended newline glyph goes all the way to + the end of the row, there will be no stretch glyph, + so leave the box flag set. */ + && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x) + it->end_of_box_run_p = 0; PRODUCE_GLYPHS (it); @@ -18672,6 +18616,7 @@ append_space_for_newline (struct it *it, int default_face_p) it->len = saved_len; it->c = saved_c; it->char_to_display = saved_char_to_display; + it->end_of_box_run_p = saved_box_end; return 1; } } @@ -18761,7 +18706,7 @@ extend_face_to_end_of_line (struct it *it) struct glyph *g; int row_width, stretch_ascent, stretch_width; struct text_pos saved_pos; - int saved_face_id, saved_avoid_cursor; + int saved_face_id, saved_avoid_cursor, saved_box_start; for (row_width = 0, g = row_start; g < row_end; g++) row_width += g->pixel_width; @@ -18776,6 +18721,7 @@ extend_face_to_end_of_line (struct it *it) saved_avoid_cursor = it->avoid_cursor_p; it->avoid_cursor_p = 1; saved_face_id = it->face_id; + saved_box_start = it->start_of_box_run_p; /* 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. */ @@ -18783,11 +18729,13 @@ extend_face_to_end_of_line (struct it *it) it->face_id = default_face->id; else it->face_id = face->id; + it->start_of_box_run_p = 0; 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; + it->start_of_box_run_p = saved_box_start; } } #endif /* HAVE_WINDOW_SYSTEM */ @@ -20354,13 +20302,17 @@ redisplay_mode_lines (Lisp_Object window, int force) static int display_mode_lines (struct window *w) { - Lisp_Object old_selected_window, old_selected_frame; + Lisp_Object old_selected_window = selected_window; + Lisp_Object old_selected_frame = selected_frame; + Lisp_Object new_frame = w->frame; + Lisp_Object old_frame_selected_window = XFRAME (new_frame)->selected_window; int n = 0; - old_selected_frame = selected_frame; - selected_frame = w->frame; - old_selected_window = selected_window; + selected_frame = new_frame; + /* FIXME: If we were to allow the mode-line's computation changing the buffer + or window's point, then we'd need select_window_1 here as well. */ XSETWINDOW (selected_window, w); + XFRAME (new_frame)->selected_window = selected_window; /* These will be set while the mode line specs are processed. */ line_number_displayed = 0; @@ -20383,6 +20335,7 @@ display_mode_lines (struct window *w) ++n; } + XFRAME (new_frame)->selected_window = old_frame_selected_window; selected_frame = old_selected_frame; selected_window = old_selected_window; return n; @@ -21468,8 +21421,8 @@ decode_mode_spec (struct window *w, register int c, int field_width, register int i; /* Let lots_of_dashes be a string of infinite length. */ - if (mode_line_target == MODE_LINE_NOPROP || - mode_line_target == MODE_LINE_STRING) + if (mode_line_target == MODE_LINE_NOPROP + || mode_line_target == MODE_LINE_STRING) return "--"; if (field_width <= 0 || field_width > sizeof (lots_of_dashes)) @@ -21551,7 +21504,7 @@ decode_mode_spec (struct window *w, register int c, int field_width, if (mode_line_target == MODE_LINE_TITLE) return ""; - startpos = XMARKER (w->start)->charpos; + startpos = marker_position (w->start); startpos_byte = marker_byte_position (w->start); height = WINDOW_TOTAL_LINES (w); @@ -23487,8 +23440,7 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row, /* Let's rather be paranoid than getting a SEGV. */ end = min (end, row->used[area]); - start = max (0, start); - start = min (end, start); + start = clip_to_bounds (0, start, end); /* Translate X to frame coordinates. Set last_x to the right end of the drawing area. */ @@ -23767,8 +23719,18 @@ append_glyph (struct it *it) glyph->type = CHAR_GLYPH; glyph->avoid_cursor_p = it->avoid_cursor_p; glyph->multibyte_p = it->multibyte_p; - glyph->left_box_line_p = it->start_of_box_run_p; - glyph->right_box_line_p = it->end_of_box_run_p; + if (it->glyph_row->reversed_p && area == TEXT_AREA) + { + /* In R2L rows, the left and the right box edges need to be + drawn in reverse direction. */ + glyph->right_box_line_p = it->start_of_box_run_p; + glyph->left_box_line_p = it->end_of_box_run_p; + } + else + { + glyph->left_box_line_p = it->start_of_box_run_p; + glyph->right_box_line_p = it->end_of_box_run_p; + } glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent || it->phys_descent > it->descent); glyph->glyph_not_available_p = it->glyph_not_available_p; @@ -23842,8 +23804,18 @@ append_composite_glyph (struct it *it) } glyph->avoid_cursor_p = it->avoid_cursor_p; glyph->multibyte_p = it->multibyte_p; - glyph->left_box_line_p = it->start_of_box_run_p; - glyph->right_box_line_p = it->end_of_box_run_p; + if (it->glyph_row->reversed_p && area == TEXT_AREA) + { + /* In R2L rows, the left and the right box edges need to be + drawn in reverse direction. */ + glyph->right_box_line_p = it->start_of_box_run_p; + glyph->left_box_line_p = it->end_of_box_run_p; + } + else + { + glyph->left_box_line_p = it->start_of_box_run_p; + glyph->right_box_line_p = it->end_of_box_run_p; + } glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent || it->phys_descent > it->descent); glyph->padding_p = 0; @@ -24020,8 +23992,18 @@ produce_image_glyph (struct it *it) glyph->type = IMAGE_GLYPH; glyph->avoid_cursor_p = it->avoid_cursor_p; glyph->multibyte_p = it->multibyte_p; - glyph->left_box_line_p = it->start_of_box_run_p; - glyph->right_box_line_p = it->end_of_box_run_p; + if (it->glyph_row->reversed_p && area == TEXT_AREA) + { + /* In R2L rows, the left and the right box edges need to be + drawn in reverse direction. */ + glyph->right_box_line_p = it->start_of_box_run_p; + glyph->left_box_line_p = it->end_of_box_run_p; + } + else + { + glyph->left_box_line_p = it->start_of_box_run_p; + glyph->right_box_line_p = it->end_of_box_run_p; + } glyph->overlaps_vertically_p = 0; glyph->padding_p = 0; glyph->glyph_not_available_p = 0; @@ -24080,8 +24062,18 @@ append_stretch_glyph (struct it *it, Lisp_Object object, glyph->type = STRETCH_GLYPH; glyph->avoid_cursor_p = it->avoid_cursor_p; glyph->multibyte_p = it->multibyte_p; - glyph->left_box_line_p = it->start_of_box_run_p; - glyph->right_box_line_p = it->end_of_box_run_p; + if (it->glyph_row->reversed_p && area == TEXT_AREA) + { + /* In R2L rows, the left and the right box edges need to be + drawn in reverse direction. */ + glyph->right_box_line_p = it->start_of_box_run_p; + glyph->left_box_line_p = it->end_of_box_run_p; + } + else + { + glyph->left_box_line_p = it->start_of_box_run_p; + glyph->right_box_line_p = it->end_of_box_run_p; + } glyph->overlaps_vertically_p = 0; glyph->padding_p = 0; glyph->glyph_not_available_p = 0; @@ -24533,8 +24525,18 @@ append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len, glyph->slice.glyphless.lower_yoff = lower_yoff; glyph->avoid_cursor_p = it->avoid_cursor_p; glyph->multibyte_p = it->multibyte_p; - glyph->left_box_line_p = it->start_of_box_run_p; - glyph->right_box_line_p = it->end_of_box_run_p; + if (it->glyph_row->reversed_p && area == TEXT_AREA) + { + /* In R2L rows, the left and the right box edges need to be + drawn in reverse direction. */ + glyph->right_box_line_p = it->start_of_box_run_p; + glyph->left_box_line_p = it->end_of_box_run_p; + } + else + { + glyph->left_box_line_p = it->start_of_box_run_p; + glyph->right_box_line_p = it->end_of_box_run_p; + } glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent || it->phys_descent > it->descent); glyph->padding_p = 0;