aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2010-10-16 14:52:54 +0200
committerEli Zaretskii2010-10-16 14:52:54 +0200
commitd2038a612693faa218797ba5a8b39ce86ecbd675 (patch)
treec4b353943e4b045b463fdbb79303b10da8a7cc62 /src
parent9a3d704fa95b96df3ec9a6027b15a76a770c4154 (diff)
downloademacs-d2038a612693faa218797ba5a8b39ce86ecbd675.tar.gz
emacs-d2038a612693faa218797ba5a8b39ce86ecbd675.zip
Support bidi-reordered text in mouse-highlighted mode- and header-lines.
Note: Not tested with actually bidi-reordered strings. xdisp.c (note_mode_line_or_margin_highlight): Support bidi-reordered strings and R2L glyph rows. Fix more comments.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog5
-rw-r--r--src/xdisp.c121
2 files changed, 79 insertions, 47 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 0f7d39e4d8a..5f6fed12620 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,10 @@
12010-10-16 Eli Zaretskii <eliz@gnu.org> 12010-10-16 Eli Zaretskii <eliz@gnu.org>
2 2
3 * xdisp.c (note_mode_line_or_margin_highlight): Support
4 bidi-reordered strings and R2L glyph rows. Fix more comments.
5
62010-10-16 Eli Zaretskii <eliz@gnu.org>
7
3 * xdisp.c (rows_from_pos_range, mouse_face_from_buffer_pos) 8 * xdisp.c (rows_from_pos_range, mouse_face_from_buffer_pos)
4 (note_mode_line_or_margin_highlight): Fix comments. 9 (note_mode_line_or_margin_highlight): Fix comments.
5 10
diff --git a/src/xdisp.c b/src/xdisp.c
index 4a7cc275c47..41be01c407f 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -24602,6 +24602,8 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
24602 int x0; 24602 int x0;
24603 struct glyph *end; 24603 struct glyph *end;
24604 24604
24605 /* Kludge alert: mode_line_string takes X/Y in pixels, but
24606 returns them in row/column units! */
24605 string = mode_line_string (w, area, &x, &y, &charpos, 24607 string = mode_line_string (w, area, &x, &y, &charpos,
24606 &object, &dx, &dy, &width, &height); 24608 &object, &dx, &dy, &width, &height);
24607 24609
@@ -24627,6 +24629,8 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
24627 else 24629 else
24628 { 24630 {
24629 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w); 24631 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
24632 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
24633 returns them in row/column units! */
24630 string = marginal_area_string (w, area, &x, &y, &charpos, 24634 string = marginal_area_string (w, area, &x, &y, &charpos,
24631 &object, &dx, &dy, &width, &height); 24635 &object, &dx, &dy, &width, &height);
24632 } 24636 }
@@ -24715,21 +24719,26 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
24715 int gpos; 24719 int gpos;
24716 int gseq_length; 24720 int gseq_length;
24717 int total_pixel_width; 24721 int total_pixel_width;
24718 EMACS_INT ignore; 24722 EMACS_INT begpos, endpos, ignore;
24719 24723
24720 int vpos, hpos; 24724 int vpos, hpos;
24721 24725
24722 b = Fprevious_single_property_change (make_number (charpos + 1), 24726 b = Fprevious_single_property_change (make_number (charpos + 1),
24723 Qmouse_face, string, Qnil); 24727 Qmouse_face, string, Qnil);
24724 if (NILP (b)) 24728 if (NILP (b))
24725 b = make_number (0); 24729 begpos = 0;
24730 else
24731 begpos = XINT (b);
24726 24732
24727 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil); 24733 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
24728 if (NILP (e)) 24734 if (NILP (e))
24729 e = make_number (SCHARS (string)); 24735 endpos = SCHARS (string);
24736 else
24737 endpos = XINT (e);
24730 24738
24731 /* Calculate the glyph position GPOS of GLYPH in the 24739 /* Calculate the glyph position GPOS of GLYPH in the
24732 displayed string. 24740 displayed string, relative to the beginning of the
24741 highlighted part of the string.
24733 24742
24734 Note: GPOS is different from CHARPOS. CHARPOS is the 24743 Note: GPOS is different from CHARPOS. CHARPOS is the
24735 position of GLYPH in the internal string object. A mode 24744 position of GLYPH in the internal string object. A mode
@@ -24737,71 +24746,89 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
24737 a flattened string by the Emacs Lisp interpreter. The 24746 a flattened string by the Emacs Lisp interpreter. The
24738 internal string is an element of those structures. The 24747 internal string is an element of those structures. The
24739 displayed string is the flattened string. */ 24748 displayed string is the flattened string. */
24740 gpos = 0; 24749 tmp_glyph = row_start_glyph;
24741 if (glyph > row_start_glyph) 24750 while (tmp_glyph < glyph
24742 { 24751 && (!(EQ (tmp_glyph->object, glyph->object)
24743 tmp_glyph = glyph - 1; 24752 && begpos <= tmp_glyph->charpos
24744 while (tmp_glyph >= row_start_glyph 24753 && tmp_glyph->charpos < endpos)))
24745 && tmp_glyph->charpos >= XINT (b) 24754 tmp_glyph++;
24746 && EQ (tmp_glyph->object, glyph->object)) 24755 gpos = glyph - tmp_glyph;
24747 { 24756
24748 tmp_glyph--; 24757 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
24749 gpos++; 24758 the highlighted part of the displayed string to which
24750 } 24759 GLYPH belongs. Note: GSEQ_LENGTH is different from
24751 } 24760 SCHARS (STRING), because the latter returns the length of
24752 24761 the internal string. */
24753 /* Calculate the glyph sequence length GSEQ_LENGTH of the 24762 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
24754 displayed string to which GLYPH belongs. Note: 24763 tmp_glyph > glyph
24755 GSEQ_LENGTH is different from SCHARS (STRING), because 24764 && (!(EQ (tmp_glyph->object, glyph->object)
24756 the latter returns the length of the internal string. */ 24765 && begpos <= tmp_glyph->charpos
24757 for (tmp_glyph = glyph, gseq_length = gpos; 24766 && tmp_glyph->charpos < endpos));
24758 tmp_glyph->charpos < XINT (e); 24767 tmp_glyph--)
24759 tmp_glyph++, gseq_length++) 24768 ;
24760 { 24769 gseq_length = gpos + (tmp_glyph - glyph) + 1;
24761 if (!EQ (tmp_glyph->object, glyph->object))
24762 break;
24763 }
24764 24770
24771 /* Calculate the total pixel width of all the glyphs between
24772 the beginning of the highlighted area and GLYPH. */
24765 total_pixel_width = 0; 24773 total_pixel_width = 0;
24766 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++) 24774 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
24767 total_pixel_width += tmp_glyph->pixel_width; 24775 total_pixel_width += tmp_glyph->pixel_width;
24768 24776
24769 /* Pre calculation of re-rendering position. */ 24777 /* Pre calculation of re-rendering position. Note: X is in
24778 column units here, after the call to mode_line_string or
24779 marginal_area_string. */
24770 hpos = x - gpos; 24780 hpos = x - gpos;
24771 vpos = (area == ON_MODE_LINE 24781 vpos = (area == ON_MODE_LINE
24772 ? (w->current_matrix)->nrows - 1 24782 ? (w->current_matrix)->nrows - 1
24773 : 0); 24783 : 0);
24774 24784
24775 /* If the re-rendering position is included in the last 24785 /* If GLYPH's position is included in the region that is
24776 re-rendering area, we should do nothing. */ 24786 already drawn in mouse face, we have nothing to do. */
24777 if ( EQ (window, dpyinfo->mouse_face_window) 24787 if ( EQ (window, dpyinfo->mouse_face_window)
24778 && dpyinfo->mouse_face_beg_col <= hpos 24788 && (!row->reversed_p
24779 && hpos < dpyinfo->mouse_face_end_col 24789 ? (dpyinfo->mouse_face_beg_col <= hpos
24790 && hpos < dpyinfo->mouse_face_end_col)
24791 /* In R2L rows we swap BEG and END, see below. */
24792 : (dpyinfo->mouse_face_end_col <= hpos
24793 && hpos < dpyinfo->mouse_face_beg_col))
24780 && dpyinfo->mouse_face_beg_row == vpos ) 24794 && dpyinfo->mouse_face_beg_row == vpos )
24781 return; 24795 return;
24782 24796
24783 if (clear_mouse_face (dpyinfo)) 24797 if (clear_mouse_face (dpyinfo))
24784 cursor = No_Cursor; 24798 cursor = No_Cursor;
24785 24799
24786 dpyinfo->mouse_face_beg_col = hpos; 24800 if (!row->reversed_p)
24787 dpyinfo->mouse_face_beg_row = vpos; 24801 {
24788 24802 dpyinfo->mouse_face_beg_col = hpos;
24789 dpyinfo->mouse_face_beg_x = original_x_pixel - (total_pixel_width + dx); 24803 dpyinfo->mouse_face_beg_x = original_x_pixel
24790 dpyinfo->mouse_face_beg_y = 0; 24804 - (total_pixel_width + dx);
24791 24805 dpyinfo->mouse_face_end_col = hpos + gseq_length;
24792 dpyinfo->mouse_face_end_col = hpos + gseq_length; 24806 dpyinfo->mouse_face_end_x = 0;
24793 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_beg_row; 24807 }
24794 24808 else
24795 dpyinfo->mouse_face_end_x = 0; 24809 {
24796 dpyinfo->mouse_face_end_y = 0; 24810 /* In R2L rows, show_mouse_face expects BEG and END
24811 coordinates to be swapped. */
24812 dpyinfo->mouse_face_end_col = hpos;
24813 dpyinfo->mouse_face_end_x = original_x_pixel
24814 - (total_pixel_width + dx);
24815 dpyinfo->mouse_face_beg_col = hpos + gseq_length;
24816 dpyinfo->mouse_face_beg_x = 0;
24817 }
24797 24818
24819 dpyinfo->mouse_face_beg_row = vpos;
24820 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_beg_row;
24821 dpyinfo->mouse_face_beg_y = 0;
24822 dpyinfo->mouse_face_end_y = 0;
24798 dpyinfo->mouse_face_past_end = 0; 24823 dpyinfo->mouse_face_past_end = 0;
24799 dpyinfo->mouse_face_window = window; 24824 dpyinfo->mouse_face_window = window;
24800 24825
24801 dpyinfo->mouse_face_face_id = face_at_string_position (w, string, 24826 dpyinfo->mouse_face_face_id = face_at_string_position (w, string,
24802 charpos, 24827 charpos,
24803 0, 0, 0, &ignore, 24828 0, 0, 0,
24804 glyph->face_id, 1); 24829 &ignore,
24830 glyph->face_id,
24831 1);
24805 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE); 24832 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
24806 24833
24807 if (NILP (pointer)) 24834 if (NILP (pointer))