From: Eli Zaretskii Date: Sat, 14 May 2011 13:41:52 +0000 (+0300) Subject: Text covered by `display' overlays is correctly reordered. X-Git-Tag: emacs-pretest-24.0.90~104^2~275^2~41 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=7b60010279ef966ed79de968c918e3e9f4b42e3b;p=emacs.git Text covered by `display' overlays is correctly reordered. 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. --- diff --git a/src/ChangeLog b/src/ChangeLog index decde924b09..b122f0612b2 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,7 +1,17 @@ 2011-05-14 Eli Zaretskii + * 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 diff --git a/src/bidi.c b/src/bidi.c index c1422a9d9a4..742224607e4 100644 --- a/src/bidi.c +++ b/src/bidi.c @@ -597,19 +597,29 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos, 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 @@ -978,7 +988,7 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) curchar = BIDI_EOB; bidi_it->ch_len = 1; bidi_it->nchars = 1; - bidi_it->disp_pos = ZV_BYTE; + bidi_it->disp_pos = ZV; } else { diff --git a/src/dispextern.h b/src/dispextern.h index f94723099f9..f5036169f75 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -1848,7 +1848,7 @@ struct bidi_it { 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 @@ -3007,6 +3007,7 @@ extern Lisp_Object lookup_glyphless_char_display (int, struct it *); 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 diff --git a/src/xdisp.c b/src/xdisp.c index fc2a80c115f..508728d95f8 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -3093,11 +3093,55 @@ next_overlay_change (EMACS_INT pos) 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); }