Adapt compute_display_string_pos to iteration over strings.
authorEli Zaretskii <eliz@gnu.org>
Thu, 9 Jun 2011 17:12:10 +0000 (20:12 +0300)
committerEli Zaretskii <eliz@gnu.org>
Thu, 9 Jun 2011 17:12:10 +0000 (20:12 +0300)
Just compiled, not yet tested.

 src/xdisp.c (compute_display_string_pos): First arg is now struct
 `text_pos *'; all callers changed.  Support display properties on
 Lisp strings.
 (compute_display_string_end): Support display properties on Lisp
 strings.
 (init_iterator, reseat_1, reseat_to_string): Initialize the
 string.bufpos member to 0 (zero, for compatibility with IT_CHARPOS
 when iterating on a string not from display properties).
 src/bidi.c (bidi_fetch_char): Support strings with display
 properties.
 src/dispextern.h (struct bidi_string_data): New member bufpos.
 (compute_display_string_pos): Update prototype.

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

index 51e4561..2f305d0 100644 (file)
@@ -1,3 +1,20 @@
+2011-06-09  Eli Zaretskii  <eliz@gnu.org>
+
+       * xdisp.c (compute_display_string_pos): First arg is now struct
+       `text_pos *'; all callers changed.  Support display properties on
+       Lisp strings.
+       (compute_display_string_end): Support display properties on Lisp
+       strings.
+       (init_iterator, reseat_1, reseat_to_string): Initialize the
+       string.bufpos member to 0 (zero, for compatibility with IT_CHARPOS
+       when iterating on a string not from display properties).
+
+       * bidi.c (bidi_fetch_char): Support strings with display
+       properties.
+
+       * dispextern.h (struct bidi_string_data): New member bufpos.
+       (compute_display_string_pos): Update prototype.
+
 2011-06-09  Eli Zaretskii  <eliz@gnu.org>
 
        * bidi.c (bidi_level_of_next_char): Allow the sentinel "position"
index a0a57b4..ffa2c77 100644 (file)
@@ -624,11 +624,15 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos,
 {
   int ch;
   EMACS_INT endpos = string->s ? string->schars : ZV;
+  struct text_pos pos;
 
   /* If we got past the last known position of display string, compute
      the position of the next one.  That position could be at CHARPOS.  */
   if (charpos < endpos && charpos > *disp_pos)
-    *disp_pos = compute_display_string_pos (charpos, string, frame_window_p);
+    {
+      SET_TEXT_POS (pos, charpos, bytepos);
+      *disp_pos = compute_display_string_pos (&pos, string, frame_window_p);
+    }
 
   /* Fetch the character at BYTEPOS.  */
   if (charpos >= endpos)
@@ -677,8 +681,10 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos,
   /* If we just entered a run of characters covered by a display
      string, compute the position of the next display string.  */
   if (charpos + *nchars <= endpos && charpos + *nchars > *disp_pos)
-    *disp_pos = compute_display_string_pos (charpos + *nchars, string,
-                                           frame_window_p);
+    {
+      SET_TEXT_POS (pos, charpos + *nchars, bytepos + *ch_len);
+      *disp_pos = compute_display_string_pos (&pos, string, frame_window_p);
+    }
 
   return ch;
 }
index 979cb43..5cb28fa 100644 (file)
@@ -1818,6 +1818,7 @@ struct bidi_string_data {
   const unsigned char *s;      /* string data, or NULL if reordering buffer */
   EMACS_INT schars;            /* the number of characters in the string,
                                   excluding the terminating null */
+  EMACS_INT bufpos;            /* buffer position of lstring, or 0 if N/A */
   unsigned from_disp_str : 1;  /* 1 means the string comes from a
                                   display property */
 };
@@ -3018,7 +3019,7 @@ extern void reseat_at_previous_visible_line_start (struct it *);
 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_pos (struct text_pos *,
                                             struct bidi_string_data *, int);
 extern EMACS_INT compute_display_string_end (EMACS_INT,
                                             struct bidi_string_data *);
index 712088d..1194cce 100644 (file)
@@ -2349,6 +2349,7 @@ init_iterator (struct it *it, struct window *w,
   it->paragraph_embedding = L2R;
   it->bidi_it.string.lstring = Qnil;
   it->bidi_it.string.s = NULL;
+  it->bidi_it.string.bufpos = 0;
 
   /* The window in which we iterate over current_buffer:  */
   XSETWINDOW (it->window, w);
@@ -3098,38 +3099,47 @@ next_overlay_change (EMACS_INT pos)
 }
 
 /* Return the character position of a display string at or after
-   CHARPOS.  If no display string exists at or after CHARPOS, return
-   ZV.  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.  STRING is the string to iterate; if STRING->s is
-   NULL, we are iterating a buffer.  FRAME_WINDOW_P is non-zero when
-   we are displaying a window on a GUI frame.  */
+   position specified by POSITION.  If no display string exists at or
+   after POSITION, return ZV.  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.  STRING is data about the
+   string to iterate; if STRING->lstring is nil, we are iterating a
+   buffer.  FRAME_WINDOW_P is non-zero when we are displaying a window
+   on a GUI frame.  */
 EMACS_INT
-compute_display_string_pos (EMACS_INT charpos, struct bidi_string_data *string,
-                           int frame_window_p)
+compute_display_string_pos (struct text_pos *position,
+                           struct bidi_string_data *string, int frame_window_p)
 {
-  /* FIXME: Support display properties on strings (object = Qnil means
-     current buffer).  */
-  Lisp_Object object = Qnil;
+  /* OBJECT = nil means current buffer.  */
+  Lisp_Object object = string ? string->lstring : Qnil;
   Lisp_Object pos, spec;
-  struct text_pos position;
-  EMACS_INT bufpos;
-
-  if (charpos >= ZV)
-    return ZV;
+  EMACS_INT eob = STRINGP (object) ? string->schars : ZV;
+  EMACS_INT begb = STRINGP (object) ? 0 : BEGV;
+  EMACS_INT bufpos, charpos = CHARPOS (*position);
+  struct text_pos tpos;
+
+  if (charpos >= eob
+      /* We don't support display properties whose values are strings
+        that have display string properties.  */
+      || string->from_disp_str
+      /* C strings cannot have display properties.  */
+      || (string->s && !STRINGP (object)))
+    return eob;
 
   /* If the character at CHARPOS is where the display string begins,
      return CHARPOS.  */
   pos = make_number (charpos);
-  CHARPOS (position) = charpos;
-  BYTEPOS (position) = CHAR_TO_BYTE (charpos);
-  bufpos = charpos;    /* FIXME! support strings as well */
+  if (STRINGP (object))
+    bufpos = string->bufpos;
+  else
+    bufpos = charpos;
+  tpos = *position;
   if (!NILP (spec = Fget_char_property (pos, Qdisplay, object))
-      && (charpos <= BEGV
+      && (charpos <= begb
          || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
                                      object),
                  spec))
-      && handle_display_spec (NULL, spec, object, Qnil, &position, bufpos,
+      && handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
                              frame_window_p))
     return charpos;
 
@@ -3137,17 +3147,21 @@ compute_display_string_pos (EMACS_INT charpos, struct bidi_string_data *string,
      that will replace the underlying text when displayed.  */
   do {
     pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
-    CHARPOS (position) = XFASTINT (pos);
-    BYTEPOS (position) = CHAR_TO_BYTE (CHARPOS (position));
-    if (CHARPOS (position) >= ZV)
+    CHARPOS (tpos) = XFASTINT (pos);
+    if (STRINGP (object))
+      BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos));
+    else
+      BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos));
+    if (CHARPOS (tpos) >= eob)
       break;
     spec = Fget_char_property (pos, Qdisplay, object);
-    bufpos = CHARPOS (position);       /* FIXME! support strings as well */
+    if (!STRINGP (object))
+      bufpos = CHARPOS (tpos);
   } while (NILP (spec)
-          || !handle_display_spec (NULL, spec, object, Qnil, &position, bufpos,
+          || !handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
                                    frame_window_p));
 
-  return CHARPOS (position);
+  return CHARPOS (tpos);
 }
 
 /* Return the character position of the end of the display string that
@@ -3157,13 +3171,13 @@ compute_display_string_pos (EMACS_INT charpos, struct bidi_string_data *string,
 EMACS_INT
 compute_display_string_end (EMACS_INT charpos, struct bidi_string_data *string)
 {
-  /* FIXME: Support display properties on strings (object = Qnil means
-     current buffer).  */
-  Lisp_Object object = Qnil;
+  /* OBJECT = nil means current buffer.  */
+  Lisp_Object object = string ? string->lstring : Qnil;
   Lisp_Object pos = make_number (charpos);
+  EMACS_INT eob = STRINGP (object) ? string->schars : ZV;
 
-  if (charpos >= ZV)
-    return ZV;
+  if (charpos >= eob)
+    return eob;
 
   if (NILP (Fget_char_property (pos, Qdisplay, object)))
     abort ();
@@ -5496,6 +5510,7 @@ reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
       it->bidi_it.disp_pos = -1;
       it->bidi_it.string.s = NULL;
       it->bidi_it.string.lstring = Qnil;
+      it->bidi_it.string.bufpos = 0;
     }
 
   if (set_stop_p)
@@ -5567,6 +5582,7 @@ reseat_to_string (struct it *it, const char *s, Lisp_Object string,
          it->bidi_it.string.lstring = string;
          it->bidi_it.string.s = SDATA (string);
          it->bidi_it.string.schars = it->end_charpos;
+         it->bidi_it.string.bufpos = 0;
          it->bidi_it.string.from_disp_str = 0;
          bidi_init_it (charpos, IT_STRING_BYTEPOS (*it),
                        FRAME_WINDOW_P (it->f), &it->bidi_it);
@@ -5592,6 +5608,7 @@ reseat_to_string (struct it *it, const char *s, Lisp_Object string,
              it->bidi_it.string.lstring = Qnil;
              it->bidi_it.string.s = s;
              it->bidi_it.string.schars = it->end_charpos;
+             it->bidi_it.string.bufpos = 0;
              it->bidi_it.string.from_disp_str = 0;
              bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
                            &it->bidi_it);