]> git.eshelyaron.com Git - emacs.git/commitdiff
Added bidi-resolved-levels, with a bug.
authorEli Zaretskii <eliz@gnu.org>
Sun, 7 Sep 2014 17:46:54 +0000 (20:46 +0300)
committerEli Zaretskii <eliz@gnu.org>
Sun, 7 Sep 2014 17:46:54 +0000 (20:46 +0300)
src/xdisp.c

index 39e707171434a992765221454c216f6ff9bbe6b4..7cf1782b83f033eb628a52d8537f32362680e237 100644 (file)
@@ -21328,6 +21328,114 @@ Value is the new character position of point.  */)
 #undef ROW_GLYPH_NEWLINE_P
 }
 
+DEFUN ("bidi-resolved-levels", Fbidi_resolved_levels,
+       Sbidi_resolved_levels, 0, 1, 0,
+       doc: /* Return the resolved bidirectional levels of characters at VPOS.
+
+The resolved levels are produced by the Emacs bidi reordering engine
+that implements the UBA, the Unicode Bidirectional Algorithm.  Please
+read the Unicode Standard Annex 9 (UAX#9) for background information
+about these levels.
+
+VPOS is the zero-based number of the current window's screen line
+for which to produce the resolved levels.  If VPOS is nil or omitted,
+it defaults to the screen line of point.  If the window displays a
+header line, VPOS of zero will report on the header line, and first
+line of text in the window will have VPOS of 1.
+
+Value is an array of resolved levels, indexed by glyph number.
+Glyphs are numbered from zero starting from the beginning of the
+screen line, i.e. the left edge of the window for left-to-right lines
+and from the right edge for right-to-left lines.  The resolved levels
+are produced only for the window's text area; text in display margins
+is not included.
+
+If the selected window's display is not up-to-date, or if the specified
+screen line does not display text, this function returns nil.  It is
+highly recommended to bind this function to some simple key, like F8,
+in order to avoid these problems.
+
+This function exists mainly for testing the correctness of the
+Emacs UBA implementation, in particular with the test suite.  */)
+  (Lisp_Object vpos)
+{
+  struct window *w = XWINDOW (selected_window);
+  struct buffer *b = XBUFFER (w->contents);
+  int nrow;
+  struct glyph_row *row;
+
+  if (NILP (vpos))
+    {
+      int d1, d2, d3, d4, d5;
+
+      pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &nrow);
+    }
+  else
+    {
+      CHECK_NUMBER_COERCE_MARKER (vpos);
+      nrow = XINT (vpos);
+    }
+
+  /* We require up-to-date glyph matrix for this window.  */
+  if (w->window_end_valid
+      && !windows_or_buffers_changed
+      && b
+      && !b->clip_changed
+      && !b->prevent_redisplay_optimizations_p
+      && !window_outdated (w)
+      && nrow >= 0
+      && nrow < w->current_matrix->nrows
+      && (row = MATRIX_ROW (w->current_matrix, nrow))->enabled_p
+      && MATRIX_ROW_DISPLAYS_TEXT_P (row))
+    {
+      struct glyph *g, *e, *g1;
+      int nglyphs, i;
+      Lisp_Object levels;
+
+      if (!row->reversed_p)    /* Left-to-right glyph row.  */
+       {
+         g = g1 = row->glyphs[TEXT_AREA];
+         e = g + row->used[TEXT_AREA];
+
+         /* Skip over glyphs at the start of the row that was
+            generated by redisplay for its own needs.  */
+         while (g < e
+                && INTEGERP (g->object)
+                && g->charpos < 0)
+           g++;
+         g1 = g;
+
+         /* Count the "interesting" glyphs in this row.  */
+         for (nglyphs = 0; g < e && !INTEGERP (g->object); g++)
+           nglyphs++;
+
+         /* Create and fill the array.  */
+         levels = make_uninit_vector (nglyphs);
+         for (i = 0; g1 < g; i++, g1++)
+           ASET (levels, i, make_number (g1->resolved_level));
+       }
+      else                     /* Right-to-left glyph row.  */
+       {
+         g = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
+         e = row->glyphs[TEXT_AREA] - 1;
+         while (g > e
+                && INTEGERP (g->object)
+                && g->charpos < 0)
+           g--;
+         g1 = g;
+         for (nglyphs = 0; g > e && !INTEGERP (g->object); g--)
+           nglyphs++;
+         levels = make_uninit_vector (nglyphs);
+         for (i = 0; g1 > g; i++, g1--)
+           ASET (levels, i, make_number (g1->resolved_level));
+       }
+      return levels;
+    }
+  else
+    return Qnil;
+}
+
+
 \f
 /***********************************************************************
                               Menu Bar
@@ -30293,6 +30401,7 @@ syms_of_xdisp (void)
 
   DEFSYM (Qright_to_left, "right-to-left");
   DEFSYM (Qleft_to_right, "left-to-right");
+  defsubr (&Sbidi_resolved_levels);
 
 #ifdef HAVE_WINDOW_SYSTEM
   DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,