summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenichi Handa <handa@m17n.org>2003-01-31 06:11:29 +0000
committerKenichi Handa <handa@m17n.org>2003-01-31 06:11:29 +0000
commita82f9242032a9e0e2371b738a1ebf37f6b523a9b (patch)
tree0705fad689effda7473aa3cacc6858278d8ba05b
parentf4b670efaf52034db7970dfdb7fc69629b56ae9f (diff)
downloademacs-a82f9242032a9e0e2371b738a1ebf37f6b523a9b.tar.gz
(SKIP_GLYPHS): New macro.
(set_cursor_from_row): Pay attention to string display properties.
-rw-r--r--src/ChangeLog13
-rw-r--r--src/xdisp.c86
2 files changed, 96 insertions, 3 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index e93ba9f4aed..78476587c08 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,16 @@
+2003-01-31 Kenichi Handa <handa@m17n.org>
+
+ * xdisp.c (SKIP_GLYPHS): New macro.
+ (set_cursor_from_row): Pay attention to string display properties.
+
+ * category.c (copy_category_entry): Fix for the case that RANGE
+ is an integer.
+
+ * xterm.c (x_encode_char): Call ccl_driver with the last arg Qnil.
+
+ * w32term.c (w32_encode_char): Call ccl_driver with the last arg
+ Qnil.
+
2003-01-30 Kenichi Handa <handa@m17n.org>
* charset.c (Fcharset_id_internal): New function.
diff --git a/src/xdisp.c b/src/xdisp.c
index 9a934ba2311..50e85a185dc 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -9356,6 +9356,19 @@ redisplay_window_1 (window)
return Qnil;
}
+
+/* Increment GLYPH until it reaches END or CONDITION fails while
+ adding (GLYPH)->pixel_width to X. */
+
+#define SKIP_GLYPHS(glyph, end, x, condition) \
+ do \
+ { \
+ (x) += (glyph)->pixel_width; \
+ ++(glyph); \
+ } \
+ while ((glyph) < (end) && (condition))
+
+
/* Set cursor position of W. PT is assumed to be displayed in ROW.
DELTA is the number of bytes by which positions recorded in ROW
differ from current buffer positions. */
@@ -9369,6 +9382,14 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
{
struct glyph *glyph = row->glyphs[TEXT_AREA];
struct glyph *end = glyph + row->used[TEXT_AREA];
+ /* The first glyph that starts a sequence of glyphs from string. */
+ struct glyph *string_start;
+ /* The X coordinate of string_start. */
+ int string_start_x;
+ /* The last known character position. */
+ int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
+ /* The last known character position before string_start. */
+ int string_before_pos;
int x = row->x;
int pt_old = PT - delta;
@@ -9384,13 +9405,72 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
++glyph;
}
+ string_start = NULL;
while (glyph < end
&& !INTEGERP (glyph->object)
&& (!BUFFERP (glyph->object)
- || glyph->charpos < pt_old))
+ || (last_pos = glyph->charpos) < pt_old))
+ {
+ if (! STRINGP (glyph->object))
+ {
+ string_start = NULL;
+ x += glyph->pixel_width;
+ ++glyph;
+ }
+ else
+ {
+ string_before_pos = last_pos;
+ string_start = glyph;
+ string_start_x = x;
+ /* Skip all glyphs from string. */
+ SKIP_GLYPHS (glyph, end, x, STRINGP (glyph->object));
+ }
+ }
+
+ if (string_start
+ && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
{
- x += glyph->pixel_width;
- ++glyph;
+ /* We may have skipped over point because the previous glyphs
+ are from string. As there's no easy way to know the
+ character position of the current glyph, find the correct
+ glyph on point by scanning from string_start again. */
+ Lisp_Object limit;
+ Lisp_Object string;
+ int pos;
+
+ limit = make_number (pt_old + 1);
+ end = glyph;
+ glyph = string_start;
+ x = string_start_x;
+ string = glyph->object;
+ pos = string_buffer_position (w, string, string_before_pos);
+ /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
+ because we always put cursor after overlay strings. */
+ while (pos == 0 && glyph < end)
+ {
+ string = glyph->object;
+ SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
+ if (glyph < end)
+ pos = string_buffer_position (w, glyph->object, string_before_pos);
+ }
+
+ while (glyph < end)
+ {
+ pos = XINT (Fnext_single_char_property_change
+ (make_number (pos), Qdisplay, Qnil, limit));
+ if (pos > pt_old)
+ break;
+ /* Skip glyphs from the same string. */
+ string = glyph->object;
+ SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
+ /* Skip glyphs from an overlay. */
+ while (glyph < end
+ && ! string_buffer_position (w, glyph->object, pos))
+ {
+ string = glyph->object;
+ SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
+ }
+ }
}
w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];