]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix R2L paragraph display on TTY.
authorEli Zaretskii <eliz@gnu.org>
Tue, 20 Apr 2010 13:08:35 +0000 (16:08 +0300)
committerEli Zaretskii <eliz@gnu.org>
Tue, 20 Apr 2010 13:08:35 +0000 (16:08 +0300)
 xdisp.c (unproduce_glyphs): New function.
 (display_line): Use it when produced glyphs are discarded from R2L
 glyph rows.
 (append_composite_glyph): In R2L rows, prepend the glyph rather
 than appending it.
 term.c (append_composite_glyph): In R2L rows, prepend the glyph
 rather than append it.  Set up the resolved_level and bidi_type
 attributes of the appended glyph.

src/ChangeLog
src/term.c
src/xdisp.c

index 7f081d9563fd11c5e325a7547917830b0aa72ff6..9a83f0c8bc7b84b0461a4e3eddc488f0e55e94b6 100644 (file)
@@ -1,5 +1,21 @@
+2010-04-20  Eli Zaretskii  <eliz@gnu.org>
+
+       Fix R2L paragraph display on TTY.
+
+       * xdisp.c (unproduce_glyphs): New function.
+       (display_line): Use it when produced glyphs are discarded from R2L
+       glyph rows.
+       (append_composite_glyph): In R2L rows, prepend the glyph rather
+       than appending it.
+
+       * term.c (append_composite_glyph): In R2L rows, prepend the glyph
+       rather than append it.  Set up the resolved_level and bidi_type
+       attributes of the appended glyph.
+
 2010-04-17  Eli Zaretskii  <eliz@gnu.org>
 
+       Continue work on R2L paragraphs in GUI sessions.
+
        * xdisp.c (extend_face_to_end_of_line): Fix off-by-one error on
        TTY frames in testing whether a line needs face extension.
 
@@ -22,8 +38,6 @@
        which happens with R2L glyph rows.  Fixes a crash when inserting a
        character at end of an R2L line.
 
-       Continue work on R2L paragraphs in GUI sessions.
-
        * xdisp.c (set_cursor_from_row): Don't be fooled by truncated
        rows: don't treat them as having zero-width characters.  Improve
        comments.
index 31e0ad223dbffaf117c4b5b90c91bfd608c0b6ef..eda19d213742a64622cf9a80af6ebd5043b821cc 100644 (file)
@@ -1589,7 +1589,6 @@ append_glyph (it)
     }
 }
 
-
 /* Produce glyphs for the display element described by IT.  *IT
    specifies what we want to produce a glyph for (character, image, ...),
    and where in the glyph matrix we currently are (glyph row and hpos).
@@ -1808,6 +1807,17 @@ append_composite_glyph (it)
   glyph = it->glyph_row->glyphs[it->area] + it->glyph_row->used[it->area];
   if (glyph < it->glyph_row->glyphs[1 + it->area])
     {
+      /* If the glyph row is reversed, we need to prepend the glyph
+        rather than append it.  */
+      if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
+       {
+         struct glyph *g;
+
+         /* Make room for the new glyph.  */
+         for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
+           g[1] = *g;
+         glyph = it->glyph_row->glyphs[it->area];
+       }
       glyph->type = COMPOSITE_GLYPH;
       glyph->pixel_width = it->pixel_width;
       glyph->u.cmp.id = it->cmp_it.id;
@@ -1828,6 +1838,18 @@ append_composite_glyph (it)
       glyph->padding_p = 0;
       glyph->charpos = CHARPOS (it->position);
       glyph->object = it->object;
+      if (it->bidi_p)
+       {
+         glyph->resolved_level = it->bidi_it.resolved_level;
+         if ((it->bidi_it.type & 7) != it->bidi_it.type)
+           abort ();
+         glyph->bidi_type = it->bidi_it.type;
+       }
+      else
+       {
+         glyph->resolved_level = 0;
+         glyph->bidi_type = UNKNOWN_BT;
+       }
 
       ++it->glyph_row->used[it->area];
       ++glyph;
index d11812ceb6519b74b9c06ad6e9ff9f59154fcb15..721af7b0251812e2ec243cb341748f77aa2edb00 100644 (file)
@@ -17203,6 +17203,31 @@ handle_line_prefix (struct it *it)
 
 \f
 
+/* Remove N glyphs at the start of a reversed IT->glyph_row.  Called
+   only for R2L lines from display_line, when it decides that too many
+   glyphs were produced by PRODUCE_GLYPHS, and the line needs to be
+   continued.  */
+static void
+unproduce_glyphs (it, n)
+     struct it *it;
+     int n;
+{
+  struct glyph *glyph, *end;
+
+  xassert (it->glyph_row);
+  xassert (it->glyph_row->reversed_p);
+  xassert (it->area == TEXT_AREA);
+  xassert (n <= it->glyph_row->used[TEXT_AREA]);
+
+  if (n > it->glyph_row->used[TEXT_AREA])
+    n = it->glyph_row->used[TEXT_AREA];
+  glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
+  end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
+  for ( ; glyph < end; glyph++)
+    glyph[-n] = *glyph;
+}
+
+
 /* Construct the glyph row IT->glyph_row in the desired matrix of
    IT->w from text at the current position of IT.  See dispextern.h
    for an overview of struct it.  Value is non-zero if
@@ -17467,6 +17492,9 @@ display_line (it)
                      /* A padding glyph that doesn't fit on this line.
                         This means the whole character doesn't fit
                         on the line.  */
+                     if (row->reversed_p)
+                       unproduce_glyphs (it, row->used[TEXT_AREA]
+                                              - n_glyphs_before);
                      row->used[TEXT_AREA] = n_glyphs_before;
 
                      /* Fill the rest of the row with continuation
@@ -17489,6 +17517,9 @@ display_line (it)
                  else if (wrap_row_used > 0)
                    {
                    back_to_wrap:
+                     if (row->reversed_p)
+                       unproduce_glyphs (it,
+                                         row->used[TEXT_AREA] - wrap_row_used);
                      *it = wrap_it;
                      it->continuation_lines_width += wrap_x;
                      row->used[TEXT_AREA] = wrap_row_used;
@@ -17524,6 +17555,9 @@ display_line (it)
                      /* Something other than a TAB that draws past
                         the right edge of the window.  Restore
                         positions to values before the element.  */
+                     if (row->reversed_p)
+                       unproduce_glyphs (it, row->used[TEXT_AREA]
+                                              - (n_glyphs_before + i));
                      row->used[TEXT_AREA] = n_glyphs_before + i;
 
                      /* Display continuation glyphs.  */
@@ -17629,9 +17663,22 @@ display_line (it)
            {
              int i, n;
 
-             for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
-               if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
-                 break;
+             if (!row->reversed_p)
+               {
+                 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
+                   if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
+                     break;
+               }
+             else
+               {
+                 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
+                    make room for the truncation glyphs we will be
+                    adding below.  */
+                 unproduce_glyphs (it, i);
+               }
 
              for (n = row->used[TEXT_AREA]; i < n; ++i)
                {
@@ -17882,7 +17929,8 @@ display_line (it)
   /* The next row should use same value of the reversed_p flag as this
      one.  set_iterator_to_next decides when it's a new paragraph, and
      PRODUCE_GLYPHS recomputes the value of the flag accordingly.  */
-  it->glyph_row->reversed_p = row->reversed_p;
+  if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
+    it->glyph_row->reversed_p = row->reversed_p;
   it->start = row_end;
   return row->displays_text_p;
 }
@@ -21486,6 +21534,17 @@ append_composite_glyph (it)
   glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
   if (glyph < it->glyph_row->glyphs[area + 1])
     {
+      /* If the glyph row is reversed, we need to prepend the glyph
+        rather than append it.  */
+      if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
+       {
+         struct glyph *g;
+
+         /* Make room for the new glyph.  */
+         for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
+           g[1] = *g;
+         glyph = it->glyph_row->glyphs[it->area];
+       }
       glyph->charpos = CHARPOS (it->position);
       glyph->object = it->object;
       glyph->pixel_width = it->pixel_width;