aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2010-10-02 17:05:20 +0200
committerEli Zaretskii2010-10-02 17:05:20 +0200
commit1f382a02c1ca5043c2b2cbaca314578da98af24c (patch)
tree6f7e5ab36a11fddebd3596691bdec7dfd64f5036 /src
parent12d54c2e095dee28d8829c93d14ae18f92f474fb (diff)
downloademacs-1f382a02c1ca5043c2b2cbaca314578da98af24c.tar.gz
emacs-1f382a02c1ca5043c2b2cbaca314578da98af24c.zip
Fix mouse highlight in bidi-reordered continued lines.
xdisp.c (row_containing_pos): Don't return too early when CHARPOS is in a bidi-reordered continued line. Return immediately when the first hit is found in a line that is not continued, or when an exact match for CHARPOS is found. (mouse_face_from_buffer_pos): Rewrite to not assume that START_CHARPOS is always in mouse_face_beg_row. If necessary, swap mouse_face_beg_row and mouse_face_end_row so that the former is always above the latter or identical to it. Continued lines that begin or end outside of the visible region still don't work.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog8
-rw-r--r--src/xdisp.c328
2 files changed, 175 insertions, 161 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 2b77f081f52..61afecff203 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -5,6 +5,14 @@
5 (note_mouse_highlight): Clear mouse highlight when mouse pointer 5 (note_mouse_highlight): Clear mouse highlight when mouse pointer
6 is in a R2L row on the stretch glyph that stands for no text 6 is in a R2L row on the stretch glyph that stands for no text
7 beyond the line end. 7 beyond the line end.
8 (row_containing_pos): Don't return too early when CHARPOS is in a
9 bidi-reordered continued line. Return immediately when the first
10 hit is found in a line that is not continued, or when an exact
11 match for CHARPOS is found.
12 (mouse_face_from_buffer_pos): Rewrite to not assume that
13 START_CHARPOS is always in mouse_face_beg_row. If necessary, swap
14 mouse_face_beg_row and mouse_face_end_row so that the former is
15 always above the latter or identical to it.
8 16
92010-08-28 Eli Zaretskii <eliz@gnu.org> 172010-08-28 Eli Zaretskii <eliz@gnu.org>
10 18
diff --git a/src/xdisp.c b/src/xdisp.c
index e19c26cbc19..9e65d8f1bb0 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -15329,10 +15329,12 @@ row_containing_pos (struct window *w, int charpos, struct glyph_row *start,
15329 { 15329 {
15330 struct glyph *g; 15330 struct glyph *g;
15331 15331
15332 if (NILP (XBUFFER (w->buffer)->bidi_display_reordering)) 15332 if (NILP (XBUFFER (w->buffer)->bidi_display_reordering)
15333 || (!best_row && !row->continued_p))
15333 return row; 15334 return row;
15334 /* In bidi-reordered rows, there could be several rows 15335 /* In bidi-reordered rows, there could be several rows
15335 occluding point. We need to find the one which fits 15336 occluding point, all of them belonging to the same
15337 continued line. We need to find the row which fits
15336 CHARPOS the best. */ 15338 CHARPOS the best. */
15337 for (g = row->glyphs[TEXT_AREA]; 15339 for (g = row->glyphs[TEXT_AREA];
15338 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]; 15340 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
@@ -15344,11 +15346,14 @@ row_containing_pos (struct window *w, int charpos, struct glyph_row *start,
15344 { 15346 {
15345 mindif = eabs (g->charpos - charpos); 15347 mindif = eabs (g->charpos - charpos);
15346 best_row = row; 15348 best_row = row;
15349 /* Exact match always wins. */
15350 if (mindif == 0)
15351 return best_row;
15347 } 15352 }
15348 } 15353 }
15349 } 15354 }
15350 } 15355 }
15351 else if (best_row) 15356 else if (best_row && !row->continued_p)
15352 return best_row; 15357 return best_row;
15353 ++row; 15358 ++row;
15354 } 15359 }
@@ -23894,7 +23899,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
23894{ 23899{
23895 struct window *w = XWINDOW (window); 23900 struct window *w = XWINDOW (window);
23896 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix); 23901 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
23897 struct glyph_row *row, *r; 23902 struct glyph_row *r1, *r2;
23898 struct glyph *glyph, *end; 23903 struct glyph *glyph, *end;
23899 EMACS_INT ignore, pos; 23904 EMACS_INT ignore, pos;
23900 int x; 23905 int x;
@@ -23903,7 +23908,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
23903 xassert (NILP (before_string) || STRINGP (before_string)); 23908 xassert (NILP (before_string) || STRINGP (before_string));
23904 xassert (NILP (after_string) || STRINGP (after_string)); 23909 xassert (NILP (after_string) || STRINGP (after_string));
23905 23910
23906 /* Find the first highlighted glyph. */ 23911 /* Find the row with START_CHARPOS. */
23907 if (start_charpos < MATRIX_ROW_START_CHARPOS (first) 23912 if (start_charpos < MATRIX_ROW_START_CHARPOS (first)
23908 && (NILP (XBUFFER (w->buffer)->bidi_display_reordering) 23913 && (NILP (XBUFFER (w->buffer)->bidi_display_reordering)
23909 || row_containing_pos (w, start_charpos, first, NULL, 0) == NULL)) 23914 || row_containing_pos (w, start_charpos, first, NULL, 0) == NULL))
@@ -23915,20 +23920,16 @@ mouse_face_from_buffer_pos (Lisp_Object window,
23915 } 23920 }
23916 else 23921 else
23917 { 23922 {
23918 /* FIXME: this assumes that START_CHARPOS is in beg_row. This 23923 r1 = row_containing_pos (w, start_charpos, first, NULL, 0);
23919 is false for reordered lines that are continued. Need to 23924 if (r1 == NULL)
23920 compute beg_row and end_row separately from beg_col and 23925 r1 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
23921 end_col. */
23922 row = row_containing_pos (w, start_charpos, first, NULL, 0);
23923 if (row == NULL)
23924 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
23925 23926
23926 /* If the before-string or display-string contains newlines, 23927 /* If the before-string or display-string contains newlines,
23927 row_containing_pos skips to its last row. Move back. */ 23928 row_containing_pos skips to its last row. Move back. */
23928 if (!NILP (before_string) || !NILP (display_string)) 23929 if (!NILP (before_string) || !NILP (display_string))
23929 { 23930 {
23930 struct glyph_row *prev; 23931 struct glyph_row *prev;
23931 while ((prev = row - 1, prev >= first) 23932 while ((prev = r1 - 1, prev >= first)
23932 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos 23933 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
23933 && prev->used[TEXT_AREA] > 0) 23934 && prev->used[TEXT_AREA] > 0)
23934 { 23935 {
@@ -23939,139 +23940,16 @@ mouse_face_from_buffer_pos (Lisp_Object window,
23939 || !(EQ (glyph->object, before_string) 23940 || !(EQ (glyph->object, before_string)
23940 || EQ (glyph->object, display_string))) 23941 || EQ (glyph->object, display_string)))
23941 break; 23942 break;
23942 row = prev; 23943 r1 = prev;
23943 } 23944 }
23944 } 23945 }
23945
23946 dpyinfo->mouse_face_beg_y = row->y;
23947 dpyinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (row, w->current_matrix);
23948
23949 /* For a bidi-reordered row, the positions of BEFORE_STRING,
23950 AFTER_STRING, DISPLAY_STRING, START_CHARPOS, and END_CHARPOS
23951 could be anywhere in the row and in any order. The strategy
23952 below is to find the leftmost and the rightmost glyph that
23953 belongs to either of these 3 strings, or whose position is
23954 between START_CHARPOS and END_CHARPOS, and highlight all the
23955 glyphs between those two. This may cover more than just the
23956 text between START_CHARPOS and END_CHARPOS if the range of
23957 characters strides the bidi level boundary, e.g. if the
23958 beginning is in R2L text while the end is in L2R text or vice
23959 versa. */
23960 if (!row->reversed_p)
23961 {
23962 /* This row is in a left to right paragraph. Scan it left
23963 to right. */
23964 glyph = row->glyphs[TEXT_AREA];
23965 end = glyph + row->used[TEXT_AREA];
23966 x = row->x;
23967
23968 /* Skip truncation glyphs at the start of the glyph row. */
23969 if (row->displays_text_p)
23970 for (; glyph < end
23971 && INTEGERP (glyph->object)
23972 && glyph->charpos < 0;
23973 ++glyph)
23974 x += glyph->pixel_width;
23975
23976 /* Scan the glyph row, looking for BEFORE_STRING,
23977 AFTER_STRING, or DISPLAY_STRING, and the first glyph from
23978 buffer whose position is between START_CHARPOS and
23979 END_CHARPOS. */
23980 for (; glyph < end
23981 && !INTEGERP (glyph->object)
23982 && !EQ (glyph->object, display_string)
23983 && !(BUFFERP (glyph->object)
23984 && (glyph->charpos >= start_charpos
23985 && glyph->charpos < end_charpos));
23986 ++glyph)
23987 {
23988 /* BEFORE_STRING or AFTER_STRING are only relevant if
23989 they are present at buffer positions between
23990 START_CHARPOS and END_CHARPOS, or if they come from
23991 an overlay. */
23992 if (EQ (glyph->object, before_string))
23993 {
23994 pos = string_buffer_position (w, before_string,
23995 start_charpos);
23996 /* If pos == 0, it means before_string came from an
23997 overlay, not from a buffer position. */
23998 if (!pos || pos >= start_charpos && pos < end_charpos)
23999 break;
24000 }
24001 else if (EQ (glyph->object, after_string))
24002 {
24003 pos = string_buffer_position (w, after_string, end_charpos);
24004 if (!pos || pos >= start_charpos && pos < end_charpos)
24005 break;
24006 }
24007 x += glyph->pixel_width;
24008 }
24009 dpyinfo->mouse_face_beg_x = x;
24010 dpyinfo->mouse_face_beg_col = glyph - row->glyphs[TEXT_AREA];
24011 }
24012 else
24013 {
24014 /* This row is in a right to left paragraph. Scan it right
24015 to left. */
24016 struct glyph *g;
24017
24018 end = row->glyphs[TEXT_AREA] - 1;
24019 glyph = end + row->used[TEXT_AREA];
24020
24021 /* Skip truncation glyphs at the start of the glyph row. */
24022 if (row->displays_text_p)
24023 for (; glyph > end
24024 && INTEGERP (glyph->object)
24025 && glyph->charpos < 0;
24026 --glyph)
24027 ;
24028
24029 /* Scan the glyph row, looking for BEFORE_STRING,
24030 AFTER_STRING, or DISPLAY_STRING, and the first glyph from
24031 buffer whose position is between START_CHARPOS and
24032 END_CHARPOS. */
24033 for (; glyph > end
24034 && !INTEGERP (glyph->object)
24035 && !EQ (glyph->object, display_string)
24036 && !(BUFFERP (glyph->object)
24037 && (glyph->charpos >= start_charpos
24038 && glyph->charpos < end_charpos));
24039 --glyph)
24040 {
24041 /* BEFORE_STRING or AFTER_STRING are only relevant if
24042 they are present at buffer positions between
24043 START_CHARPOS and END_CHARPOS, or if they come from
24044 an overlay. */
24045 if (EQ (glyph->object, before_string))
24046 {
24047 pos = string_buffer_position (w, before_string,
24048 start_charpos);
24049 /* If pos == 0, it means before_string came from an
24050 overlay, not from a buffer position. */
24051 if (!pos || pos >= start_charpos && pos < end_charpos)
24052 break;
24053 }
24054 else if (EQ (glyph->object, after_string))
24055 {
24056 pos = string_buffer_position (w, after_string, end_charpos);
24057 if (!pos || pos >= start_charpos && pos < end_charpos)
24058 break;
24059 }
24060 }
24061
24062 glyph++; /* first glyph to the right of the highlighted area */
24063 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
24064 x += g->pixel_width;
24065 dpyinfo->mouse_face_beg_x = x;
24066 dpyinfo->mouse_face_beg_col = glyph - row->glyphs[TEXT_AREA];
24067 }
24068 } 23946 }
24069 23947
24070 /* Find the last highlighted glyph. */ 23948 /* Find the row with END_CHARPOS. */
24071 r = row_containing_pos (w, end_charpos, first, NULL, 0); 23949 r2 = row_containing_pos (w, end_charpos, first, NULL, 0);
24072 if (r == NULL) 23950 if (r2 == NULL)
24073 { 23951 {
24074 r = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos)); 23952 r2 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
24075 dpyinfo->mouse_face_past_end = 1; 23953 dpyinfo->mouse_face_past_end = 1;
24076 } 23954 }
24077 else if (!NILP (after_string)) 23955 else if (!NILP (after_string))
@@ -24081,36 +23959,164 @@ mouse_face_from_buffer_pos (Lisp_Object window,
24081 struct glyph_row *last 23959 struct glyph_row *last
24082 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos)); 23960 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
24083 23961
24084 for (next = r + 1; 23962 for (next = r2 + 1;
24085 next <= last 23963 next <= last
24086 && next->used[TEXT_AREA] > 0 23964 && next->used[TEXT_AREA] > 0
24087 && EQ (next->glyphs[TEXT_AREA]->object, after_string); 23965 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
24088 ++next) 23966 ++next)
24089 r = next; 23967 r2 = next;
23968 }
23969
23970 /* The rest of the display engine assumes that mouse_face_beg_row is
23971 either above below mouse_face_end_row or identical to it. But
23972 with bidi-reordered continued lines, the row for START_CHARPOS
23973 could be below the row for END_CHARPOS. If so, swap the rows and
23974 store them in correct order. */
23975 if (r1->y > r2->y)
23976 {
23977 struct glyph_row *tem = r2;
23978
23979 r2 = r1;
23980 r1 = tem;
23981 }
23982 dpyinfo->mouse_face_beg_y = r1->y;
23983 dpyinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
23984 dpyinfo->mouse_face_end_y = r2->y;
23985 dpyinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
23986
23987 /* For a bidi-reordered row, the positions of BEFORE_STRING,
23988 AFTER_STRING, DISPLAY_STRING, START_CHARPOS, and END_CHARPOS
23989 could be anywhere in the row and in any order. The strategy
23990 below is to find the leftmost and the rightmost glyph that
23991 belongs to either of these 3 strings, or whose position is
23992 between START_CHARPOS and END_CHARPOS, and highlight all the
23993 glyphs between those two. This may cover more than just the text
23994 between START_CHARPOS and END_CHARPOS if the range of characters
23995 strides the bidi level boundary, e.g. if the beginning is in R2L
23996 text while the end is in L2R text or vice versa. */
23997 if (!r1->reversed_p)
23998 {
23999 /* This row is in a left to right paragraph. Scan it left to
24000 right. */
24001 glyph = r1->glyphs[TEXT_AREA];
24002 end = glyph + r1->used[TEXT_AREA];
24003 x = r1->x;
24004
24005 /* Skip truncation glyphs at the start of the glyph row. */
24006 if (r1->displays_text_p)
24007 for (; glyph < end
24008 && INTEGERP (glyph->object)
24009 && glyph->charpos < 0;
24010 ++glyph)
24011 x += glyph->pixel_width;
24012
24013 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
24014 or DISPLAY_STRING, and the first glyph from buffer whose
24015 position is between START_CHARPOS and END_CHARPOS. */
24016 for (; glyph < end
24017 && !INTEGERP (glyph->object)
24018 && !EQ (glyph->object, display_string)
24019 && !(BUFFERP (glyph->object)
24020 && (glyph->charpos >= start_charpos
24021 && glyph->charpos < end_charpos));
24022 ++glyph)
24023 {
24024 /* BEFORE_STRING or AFTER_STRING are only relevant if they
24025 are present at buffer positions between START_CHARPOS and
24026 END_CHARPOS, or if they come from an overlay. */
24027 if (EQ (glyph->object, before_string))
24028 {
24029 pos = string_buffer_position (w, before_string,
24030 start_charpos);
24031 /* If pos == 0, it means before_string came from an
24032 overlay, not from a buffer position. */
24033 if (!pos || pos >= start_charpos && pos < end_charpos)
24034 break;
24035 }
24036 else if (EQ (glyph->object, after_string))
24037 {
24038 pos = string_buffer_position (w, after_string, end_charpos);
24039 if (!pos || pos >= start_charpos && pos < end_charpos)
24040 break;
24041 }
24042 x += glyph->pixel_width;
24043 }
24044 dpyinfo->mouse_face_beg_x = x;
24045 dpyinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
24046 }
24047 else
24048 {
24049 /* This row is in a right to left paragraph. Scan it right to
24050 left. */
24051 struct glyph *g;
24052
24053 end = r1->glyphs[TEXT_AREA] - 1;
24054 glyph = end + r1->used[TEXT_AREA];
24055
24056 /* Skip truncation glyphs at the start of the glyph row. */
24057 if (r1->displays_text_p)
24058 for (; glyph > end
24059 && INTEGERP (glyph->object)
24060 && glyph->charpos < 0;
24061 --glyph)
24062 ;
24063
24064 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
24065 or DISPLAY_STRING, and the first glyph from buffer whose
24066 position is between START_CHARPOS and END_CHARPOS. */
24067 for (; glyph > end
24068 && !INTEGERP (glyph->object)
24069 && !EQ (glyph->object, display_string)
24070 && !(BUFFERP (glyph->object)
24071 && (glyph->charpos >= start_charpos
24072 && glyph->charpos < end_charpos));
24073 --glyph)
24074 {
24075 /* BEFORE_STRING or AFTER_STRING are only relevant if they
24076 are present at buffer positions between START_CHARPOS and
24077 END_CHARPOS, or if they come from an overlay. */
24078 if (EQ (glyph->object, before_string))
24079 {
24080 pos = string_buffer_position (w, before_string, start_charpos);
24081 /* If pos == 0, it means before_string came from an
24082 overlay, not from a buffer position. */
24083 if (!pos || pos >= start_charpos && pos < end_charpos)
24084 break;
24085 }
24086 else if (EQ (glyph->object, after_string))
24087 {
24088 pos = string_buffer_position (w, after_string, end_charpos);
24089 if (!pos || pos >= start_charpos && pos < end_charpos)
24090 break;
24091 }
24092 }
24093
24094 glyph++; /* first glyph to the right of the highlighted area */
24095 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
24096 x += g->pixel_width;
24097 dpyinfo->mouse_face_beg_x = x;
24098 dpyinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
24090 } 24099 }
24091 24100
24092 /* If the highlight ends in a different row, compute GLYPH and END 24101 /* If the highlight ends in a different row, compute GLYPH and END
24093 for the end row. */ 24102 for the end row. Otherwise, reuse the values computed above for
24094 if (r != row) 24103 the row where the highlight begins. */
24104 if (r2 != r1)
24095 { 24105 {
24096 if (!r->reversed_p) 24106 if (!r2->reversed_p)
24097 { 24107 {
24098 glyph = r->glyphs[TEXT_AREA]; 24108 glyph = r2->glyphs[TEXT_AREA];
24099 end = glyph + r->used[TEXT_AREA]; 24109 end = glyph + r2->used[TEXT_AREA];
24100 x = r->x; 24110 x = r2->x;
24101 } 24111 }
24102 else 24112 else
24103 { 24113 {
24104 end = r->glyphs[TEXT_AREA] - 1; 24114 end = r2->glyphs[TEXT_AREA] - 1;
24105 glyph = end + r->used[TEXT_AREA]; 24115 glyph = end + r2->used[TEXT_AREA];
24106 } 24116 }
24107 row = r;
24108 } 24117 }
24109 24118
24110 dpyinfo->mouse_face_end_y = row->y; 24119 if (!r2->reversed_p)
24111 dpyinfo->mouse_face_end_row = MATRIX_ROW_VPOS (row, w->current_matrix);
24112
24113 if (!row->reversed_p)
24114 { 24120 {
24115 /* Skip truncation and continuation glyphs near the end of the 24121 /* Skip truncation and continuation glyphs near the end of the
24116 row, and also blanks and stretch glyphs inserted by 24122 row, and also blanks and stretch glyphs inserted by
@@ -24153,14 +24159,14 @@ mouse_face_from_buffer_pos (Lisp_Object window,
24153 x += glyph->pixel_width; 24159 x += glyph->pixel_width;
24154 24160
24155 dpyinfo->mouse_face_end_x = x; 24161 dpyinfo->mouse_face_end_x = x;
24156 dpyinfo->mouse_face_end_col = glyph - row->glyphs[TEXT_AREA]; 24162 dpyinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
24157 } 24163 }
24158 else 24164 else
24159 { 24165 {
24160 /* Skip truncation and continuation glyphs near the end of the 24166 /* Skip truncation and continuation glyphs near the end of the
24161 row, and also blanks and stretch glyphs inserted by 24167 row, and also blanks and stretch glyphs inserted by
24162 extend_face_to_end_of_line. */ 24168 extend_face_to_end_of_line. */
24163 x = row->x; 24169 x = r2->x;
24164 end++; 24170 end++;
24165 while (end < glyph 24171 while (end < glyph
24166 && INTEGERP (end->object) 24172 && INTEGERP (end->object)
@@ -24200,7 +24206,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
24200 x += end->pixel_width; 24206 x += end->pixel_width;
24201 } 24207 }
24202 dpyinfo->mouse_face_end_x = x; 24208 dpyinfo->mouse_face_end_x = x;
24203 dpyinfo->mouse_face_end_col = end - row->glyphs[TEXT_AREA]; 24209 dpyinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
24204 } 24210 }
24205 24211
24206 dpyinfo->mouse_face_window = window; 24212 dpyinfo->mouse_face_window = window;
@@ -24859,8 +24865,8 @@ note_mouse_highlight (struct frame *f, int x, int y)
24859 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p 24865 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p
24860 /* R2L rows have a stretch glyph at their front, which 24866 /* R2L rows have a stretch glyph at their front, which
24861 stands for no text, whereas L2R rows have no glyphs at 24867 stands for no text, whereas L2R rows have no glyphs at
24862 all beyond the end of text. Treat such stretch glyphs as 24868 all beyond the end of text. Treat such stretch glyphs
24863 NULL glyphs in L2R rows. */ 24869 like we do with NULL glyphs in L2R rows. */
24864 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p 24870 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
24865 && glyph == MATRIX_ROW (w->current_matrix, vpos)->glyphs[TEXT_AREA] 24871 && glyph == MATRIX_ROW (w->current_matrix, vpos)->glyphs[TEXT_AREA]
24866 && glyph->type == STRETCH_GLYPH 24872 && glyph->type == STRETCH_GLYPH