Cursor positioning is not yet right near the overlay.
src/xdisp.c (compute_display_string_pos): Non-trivial implementation.
(compute_display_string_end): New function.
src/dispextern.h (compute_display_string_end): Declare prototype.
src/bidi.c (bidi_resolve_explicit_1): Use ZV for disp_pos.
(bidi_fetch_char): Implement support for runs of characters
covered by display strings.
2011-05-14 Eli Zaretskii <eliz@gnu.org>
+ * xdisp.c (compute_display_string_pos): Non-trivial implementation.
+ (compute_display_string_end): New function.
+
+ * dispextern.h (compute_display_string_end): Declare prototype.
+
+ * bidi.c (bidi_resolve_explicit_1): Use ZV for disp_pos.
+ (bidi_fetch_char): Implement support for runs of characters
+ covered by display strings.
+
* bidi.c (bidi_fetch_char): Accept also character position
- corresponding to BYTEPOS. All callers changed.
+ corresponding to BYTEPOS. DISP_POS is now a character position,
+ not a byte position. All callers changed.
(bidi_cache_iterator_state, bidi_resolve_explicit_1)
(bidi_resolve_explicit, bidi_resolve_weak)
(bidi_level_of_next_char, bidi_move_to_visually_next): Abort if
ch = BIDI_EOB;
*ch_len = 1;
*nchars = 1;
+ *disp_pos = ZV;
}
-#if 0
else if (charpos >= *disp_pos)
{
- /* support characters covered by a display string */
- ch = 0xFFFC; /* Unicode Object Replacement Character */
+ EMACS_INT disp_end_pos;
+
+ /* We don't expect to find ourselves in the middle of a display
+ property. Hopefully, it will never be needed. */
+ if (charpos > *disp_pos)
+ abort ();
+ /* Return the Unicode Object Replacement Character to represent
+ the entire run of characters covered by the display
+ string. */
+ ch = 0xFFFC;
+ disp_end_pos = compute_display_string_end (*disp_pos);
+ *nchars = disp_end_pos - *disp_pos;
+ *ch_len = CHAR_TO_BYTE (disp_end_pos) - bytepos;
}
-#endif
else
{
ch = FETCH_MULTIBYTE_CHAR (bytepos);
- *ch_len = CHAR_BYTES (ch);
*nchars = 1;
+ *ch_len = CHAR_BYTES (ch);
}
/* If we just entered a run of characters covered by a display
curchar = BIDI_EOB;
bidi_it->ch_len = 1;
bidi_it->nchars = 1;
- bidi_it->disp_pos = ZV_BYTE;
+ bidi_it->disp_pos = ZV;
}
else
{
bidi_dir_t paragraph_dir; /* current paragraph direction */
int new_paragraph; /* if non-zero, we expect a new paragraph */
EMACS_INT separator_limit; /* where paragraph separator should end */
- EMACS_INT disp_pos; /* byte position of display string after ch */
+ EMACS_INT disp_pos; /* position of display string after ch */
};
/* Value is non-zero when the bidi iterator is at base paragraph
extern int calc_pixel_width_or_height (double *, struct it *, Lisp_Object,
struct font *, int, int *);
extern EMACS_INT compute_display_string_pos (EMACS_INT);
+extern EMACS_INT compute_display_string_end (EMACS_INT);
#ifdef HAVE_WINDOW_SYSTEM
EMACS_INT
compute_display_string_pos (EMACS_INT charpos)
{
- /* FIXME: Support display properties on strings. */
+ /* FIXME: Support display properties on strings (object = Qnil means
+ current buffer). */
+ Lisp_Object object = Qnil;
+ Lisp_Object pos = make_number (charpos);
+
if (charpos >= ZV)
return ZV;
- /* FIXME! */
- return ZV;
+
+ /* If the character at CHARPOS is where the display string begins,
+ return CHARPOS. */
+ if (!NILP (Fget_char_property (pos, Qdisplay, object))
+ && (charpos <= BEGV
+ || NILP (Fget_char_property (make_number (charpos - 1), Qdisplay,
+ object))))
+ return charpos;
+
+ /* Look forward for the first character where the `display' property
+ changes from nil to non-nil. */
+ do {
+ pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
+ } while (XFASTINT (pos) < ZV
+ && NILP (Fget_char_property (pos, Qdisplay, object)));
+
+ return XFASTINT (pos);
+}
+
+/* Return the character position of the end of the display string that
+ started at CHARPOS. A display string is either an overlay with
+ `display' property whose value is a string or a `display' text
+ property whose value is a string. */
+EMACS_INT
+compute_display_string_end (EMACS_INT charpos)
+{
+ /* FIXME: Support display properties on strings (object = Qnil means
+ current buffer). */
+ Lisp_Object object = Qnil;
+ Lisp_Object pos = make_number (charpos);
+
+ if (charpos >= ZV)
+ return ZV;
+
+ if (NILP (Fget_char_property (pos, Qdisplay, object)))
+ abort ();
+
+ /* Look forward for the first character where the `display' property
+ changes. */
+ pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
+
+ return XFASTINT (pos);
}