# HG changeset patch # User Eli Zaretskii # Date 1282993742 -10800 # Node ID 9fbc584102c22407f969901f868f5fef09ef4e5a # Parent f4fc1590d90472a7e7cfe5349474dad86e8fcde4 Support R2L rows. Continued lines still don't work correctly. xdisp.c (mouse_face_from_buffer_pos): Fix code using bug#1220 as test case. Implement highlight for R2L rows. diff -r f4fc1590d904 -r 9fbc584102c2 src/ChangeLog --- a/src/ChangeLog Sat Aug 28 12:32:44 2010 +0300 +++ b/src/ChangeLog Sat Aug 28 14:09:02 2010 +0300 @@ -1,7 +1,7 @@ 2010-08-28 Eli Zaretskii * xdisp.c (mouse_face_from_buffer_pos): Fix code using bug#1220 as - test case. + test case. Implement highlight for R2L rows. 2010-08-21 Eli Zaretskii diff -r f4fc1590d904 -r 9fbc584102c2 src/xdisp.c --- a/src/xdisp.c Sat Aug 28 12:32:44 2010 +0300 +++ b/src/xdisp.c Sat Aug 28 14:09:02 2010 +0300 @@ -23916,9 +23916,10 @@ ++glyph) x += glyph->pixel_width; - /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING, - or DISPLAY_STRING, and the first glyph whose position is - between START_CHARPOS and END_CHARPOS. */ + /* Scan the glyph row, looking for BEFORE_STRING, + AFTER_STRING, or DISPLAY_STRING, and the first glyph from + buffer whose position is between START_CHARPOS and + END_CHARPOS. */ for (; glyph < end && !INTEGERP (glyph->object) && !EQ (glyph->object, display_string) @@ -23953,7 +23954,64 @@ } else { - /* FIXME! */ + /* This row is in a right to left paragraph. Scan it right + to left. */ + struct glyph *g; + + end = row->glyphs[TEXT_AREA] - 1; + glyph = end + row->used[TEXT_AREA]; + + /* Skip truncation glyphs at the start of the glyph row. */ + if (row->displays_text_p) + for (; glyph > end + && INTEGERP (glyph->object) + && glyph->charpos < 0; + --glyph) + ; + + /* Scan the glyph row, looking for BEFORE_STRING, + AFTER_STRING, or DISPLAY_STRING, and the first glyph from + buffer whose position is between START_CHARPOS and + END_CHARPOS. */ + for (; glyph > end + && !INTEGERP (glyph->object) + && !EQ (glyph->object, display_string) + && !(BUFFERP (glyph->object) + && (glyph->charpos >= start_charpos + && glyph->charpos < end_charpos)); + --glyph) + { + /* BEFORE_STRING or AFTER_STRING are only relevant if + they are present at buffer positions between + START_CHARPOS and END_CHARPOS, or if they come from + an overlay. */ + if (EQ (glyph->object, before_string)) + { + pos = string_buffer_position (w, before_string, + start_charpos); + /* If pos == 0, it means before_string came from an + overlay, not from a buffer position. */ + if (!pos || pos >= start_charpos && pos < end_charpos) + break; + } + else if (EQ (glyph->object, after_string)) + { + pos = string_buffer_position (w, after_string, end_charpos); + if (!pos || pos >= start_charpos && pos < end_charpos) + break; + } + } + + /* Mouse highlight uses the screen geometry, which is left + to right even in R2L paragraphs. Therefore, for R2L + paragraphs, the "first" highlighted glyph actually + determines the _end_ column and x of the highlighted + area. */ + glyph++; /* first glyph beyond the highlighted area */ + for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++) + x += g->pixel_width; + dpyinfo->mouse_face_end_x = x; + dpyinfo->mouse_face_end_col = glyph - row->glyphs[TEXT_AREA]; } } @@ -24023,14 +24081,60 @@ /* Find the X coordinate of the last glyph to be highlighted. */ for (; glyph <= end; ++glyph) x += glyph->pixel_width; - } - else - { - /* FIXME! */ - } - - dpyinfo->mouse_face_end_x = x; - dpyinfo->mouse_face_end_col = glyph - row->glyphs[TEXT_AREA]; + + dpyinfo->mouse_face_end_x = x; + dpyinfo->mouse_face_end_col = glyph - row->glyphs[TEXT_AREA]; + } + else + { + /* Skip truncation and continuation glyphs near the end of the + row, and also blanks and stretch glyphs inserted by + extend_face_to_end_of_line. */ + x = row->x; + end++; + while (end < glyph + && INTEGERP (end->object) + && end->charpos <= 0) + { + x += end->pixel_width; + ++end; + } + /* Scan the rest of the glyph row from the end, looking for the + first glyph that comes from BEFORE_STRING, AFTER_STRING, or + DISPLAY_STRING, or whose position is between START_CHARPOS + and END_CHARPOS */ + for ( ; + end < glyph + && !INTEGERP (end->object) + && !EQ (end->object, display_string) + && !(BUFFERP (end->object) + && (end->charpos >= start_charpos + && end->charpos < end_charpos)); + ++end) + { + /* BEFORE_STRING or AFTER_STRING are only relevant if they + are present at buffer positions between START_CHARPOS and + END_CHARPOS, or if they come from an overlay. */ + if (EQ (end->object, before_string)) + { + pos = string_buffer_position (w, before_string, start_charpos); + if (!pos || pos >= start_charpos && pos < end_charpos) + break; + } + else if (EQ (end->object, after_string)) + { + pos = string_buffer_position (w, after_string, end_charpos); + if (!pos || pos >= start_charpos && pos < end_charpos) + break; + } + x += end->pixel_width; + } + /* In the left-to-right screen geometry, END is actually the + _beginning_ of the highlighted area for R2L paragraphs. */ + dpyinfo->mouse_face_beg_x = x; + dpyinfo->mouse_face_beg_col = end - row->glyphs[TEXT_AREA]; + } + dpyinfo->mouse_face_window = window; dpyinfo->mouse_face_face_id = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,