Text covered by `display' overlays is correctly reordered.
authorEli Zaretskii <eliz@gnu.org>
Sat, 14 May 2011 13:41:52 +0000 (16:41 +0300)
committerEli Zaretskii <eliz@gnu.org>
Sat, 14 May 2011 13:41:52 +0000 (16:41 +0300)
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.

src/ChangeLog
src/bidi.c
src/dispextern.h
src/xdisp.c

index decde92..b122f06 100644 (file)
@@ -1,7 +1,17 @@
 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
index c1422a9..7422246 100644 (file)
@@ -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
     {
index f947230..f503616 100644 (file)
@@ -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
 
index fc2a80c..508728d 100644 (file)
@@ -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);
 }