changeset 108198:0501d22b885f

Fix display of truncated R2L lines on a TTY. xdisp.c (display_line): Fix prepending of truncation glyphs to R2L rows. (insert_left_trunc_glyphs): Support addition of left truncation glyphs to R2L rows.
author Eli Zaretskii <eliz@gnu.org>
date Sat, 01 May 2010 16:39:44 +0300
parents 7da109ac81d1
children 97b67e89ecc5
files src/ChangeLog src/xdisp.c
diffstat 2 files changed, 61 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Sat May 01 13:49:09 2010 +0300
+++ b/src/ChangeLog	Sat May 01 16:39:44 2010 +0300
@@ -4,6 +4,9 @@
 	(display_line): Use it.
 	(extend_face_to_end_of_line): In almost-filled rows, extend only
 	if the row is R2L and not continued.
+	(display_line): Fix prepending of truncation glyphs to R2L rows.
+	(insert_left_trunc_glyphs): Support addition of left truncation
+	glyphs to R2L rows.
 
 2010-04-27  Eli Zaretskii  <eliz@gnu.org>
 
--- a/src/xdisp.c	Sat May 01 13:49:09 2010 +0300
+++ b/src/xdisp.c	Sat May 01 16:39:44 2010 +0300
@@ -16739,24 +16739,61 @@
   produce_special_glyphs (&truncate_it, IT_TRUNCATION);
 
   /* Overwrite glyphs from IT with truncation glyphs.  */
-  from = truncate_it.glyph_row->glyphs[TEXT_AREA];
-  end = from + truncate_it.glyph_row->used[TEXT_AREA];
-  to = it->glyph_row->glyphs[TEXT_AREA];
-  toend = to + it->glyph_row->used[TEXT_AREA];
-
-  while (from < end)
-    *to++ = *from++;
-
-  /* There may be padding glyphs left over.  Overwrite them too.  */
-  while (to < toend && CHAR_GLYPH_PADDING_P (*to))
+  if (!it->glyph_row->reversed_p)
     {
       from = truncate_it.glyph_row->glyphs[TEXT_AREA];
+      end = from + truncate_it.glyph_row->used[TEXT_AREA];
+      to = it->glyph_row->glyphs[TEXT_AREA];
+      toend = to + it->glyph_row->used[TEXT_AREA];
+
       while (from < end)
 	*to++ = *from++;
-    }
-
-  if (to > toend)
-    it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
+
+      /* There may be padding glyphs left over.  Overwrite them too.  */
+      while (to < toend && CHAR_GLYPH_PADDING_P (*to))
+	{
+	  from = truncate_it.glyph_row->glyphs[TEXT_AREA];
+	  while (from < end)
+	    *to++ = *from++;
+	}
+
+      if (to > toend)
+	it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
+    }
+  else
+    {
+      /* In R2L rows, overwrite the last (rightmost) glyphs, and do
+	 that back to front.  */
+      end = truncate_it.glyph_row->glyphs[TEXT_AREA];
+      from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
+      toend = it->glyph_row->glyphs[TEXT_AREA];
+      to = toend + it->glyph_row->used[TEXT_AREA] - 1;
+
+      while (from >= end && to >= toend)
+	*to-- = *from--;
+      while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
+	{
+	  from =
+	    truncate_it.glyph_row->glyphs[TEXT_AREA]
+	    + truncate_it.glyph_row->used[TEXT_AREA] - 1;
+	  while (from >= end && to >= toend)
+	    *to-- = *from--;
+	}
+      if (from >= end)
+	{
+	  /* Need to free some room before prepending additional
+	     glyphs.  */
+	  int move_by = from - end + 1;
+	  struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
+	  struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
+
+	  for ( ; g >= g0; g--)
+	    g[move_by] = *g;
+	  while (from >= end)
+	    *to-- = *from--;
+	  it->glyph_row->used[TEXT_AREA] += move_by;
+	}
+    }
 }
 
 
@@ -17938,10 +17975,14 @@
 		  for (i = 0; i < row->used[TEXT_AREA]; i++)
 		    if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
 		      break;
-		  /* Remove padding glyphs at the front of ROW, to
+		  /* Remove any padding glyphs at the front of ROW, to
 		     make room for the truncation glyphs we will be
-		     adding below.  */
-		  unproduce_glyphs (it, i);
+		     adding below.  The loop below always inserts at
+		     least one truncation glyph, so also remove the
+		     last glyph added to ROW.  */
+		  unproduce_glyphs (it, i + 1);
+		  /* Adjust i for the loop below.  */
+		  i = row->used[TEXT_AREA] - (i + 1);
 		}
 
 	      for (n = row->used[TEXT_AREA]; i < n; ++i)