changeset 93264:6b2d6832b219

(check_display_width): New fun. (scan_for_column): Use it.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Wed, 26 Mar 2008 20:46:47 +0000
parents e40fb0b0ea6c
children e0ebf2441a57
files src/ChangeLog src/indent.c
diffstat 2 files changed, 59 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Wed Mar 26 20:26:50 2008 +0000
+++ b/src/ChangeLog	Wed Mar 26 20:46:47 2008 +0000
@@ -1,5 +1,8 @@
 2008-03-26  Stefan Monnier  <monnier@iro.umontreal.ca>
 
+	* indent.c (check_display_width): New fun.
+	(scan_for_column): Use it.
+
 	* data.c (syms_of_data): Mark most-positive-fixnum and
 	most-negative-fixnum as constants.
 
--- a/src/indent.c	Wed Mar 26 20:26:50 2008 +0000
+++ b/src/indent.c	Wed Mar 26 20:46:47 2008 +0000
@@ -504,6 +504,47 @@
   return col;
 }
 
+extern Lisp_Object Qspace, QCwidth, QCalign_to;
+
+/* Check the presence of a display property and compute its width.
+   If a property was found and its width was found as well, return
+   its width (>= 0) and set the position of the end of the property
+   in ENDPOS.
+   Otherwise just return -1.  */
+static int
+check_display_width (EMACS_INT pos, EMACS_INT col, EMACS_INT *endpos)
+{
+  Lisp_Object val, overlay;
+
+  if (CONSP (val = get_char_property_and_overlay
+	     (make_number (pos), Qdisplay, Qnil, &overlay))
+      && EQ (Qspace, XCAR (val)))
+    { /* FIXME: Use calc_pixel_width_or_height, as in term.c.  */
+      Lisp_Object plist = XCDR (val), prop;
+      int width = -1;
+
+      if ((prop = Fplist_get (plist, QCwidth), NATNUMP (prop)))
+	width = XINT (prop);
+      else if (FLOATP (prop))
+	width = (int)(XFLOAT_DATA (prop) + 0.5);
+      else if ((prop = Fplist_get (plist, QCalign_to), NATNUMP (prop)))
+	width = XINT (prop) - col;
+      else if (FLOATP (prop))
+	width = (int)(XFLOAT_DATA (prop) + 0.5) - col;
+	    
+      if (width >= 0)
+	{
+	  EMACS_INT start;
+	  if (OVERLAYP (overlay))
+	    *endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
+	  else
+	    get_property_and_range (pos, Qdisplay, &val, &start, endpos, Qnil);
+	  return width;
+	}
+    }
+  return -1;
+}
+
 /* Scanning from the beginning of the current line, stop at the buffer
    position ENDPOS or at the column GOALCOL or at the end of line, whichever
    comes first.
@@ -560,8 +601,7 @@
 	break;
       prev_col = col;
 
-      /* Check composition sequence.  */
-      {
+      { /* Check composition sequence.  */
 	int len, len_byte, width;
 
 	if (check_composition (scan, scan_byte, end,
@@ -575,6 +615,20 @@
 	  }
       }
 
+      { /* Check display property.  */
+	EMACS_INT end;
+	int width = check_display_width (scan, col, &end);
+	if (width >= 0)
+	  {
+	    col += width;
+	    if (end > scan) /* Avoid infinite loops with 0-width overlays.  */
+	      {
+		scan = end; scan_byte = charpos_to_bytepos (scan);
+		continue;
+	      }
+	  }
+      }
+
       c = FETCH_BYTE (scan_byte);
 
       /* See if there is a display table and it relates