changeset 107646:dfdf14a6f5a0

Support MS-Windows build and reversed rows in GUI frames; add initial docs. doc/emacs/mule.texi (International): Mention support of bidirectional editing. (Bidirectional Editing): New section. etc/HELLO: Reorder Arabic and Hebrew into logical order, and insert RLM before the opening paren, to make the display more reasonable. Add setting for bidi-display-reordering in the local variables section. lisp/files.el: Make bidi-display-reordering safe variable for boolean values. src/xdisp (append_glyph): If the glyph row is reversed, prepend the glyph rather than appending it. src/makefile.w32-in (OBJ1): Add $(BLD)/bidi.$(O). ($(BLD)/bidi.$(O)): New target.
author Eli Zaretskii <eliz@gnu.org>
date Mon, 29 Mar 2010 08:26:24 -0400
parents 6e29ba4351e0
children 808cc9f56518
files doc/emacs/mule.texi etc/HELLO etc/NEWS lisp/files.el src/ChangeLog.bidi src/makefile.w32-in src/xdisp.c
diffstat 7 files changed, 168 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/doc/emacs/mule.texi	Sun Mar 28 11:18:10 2010 -0400
+++ b/doc/emacs/mule.texi	Mon Mar 29 08:26:24 2010 -0400
@@ -67,6 +67,12 @@
 possible problems and explains how to solve them.
 
 @item
+Characters from scripts whose natural ordering of text is from right
+to left are reordered for display (@pxref{Bidirectional Editing}).
+These scripts include Arabic, Hebrew, Syriac, Thaana, and a few
+others.
+
+@item
 You can insert non-@acronym{ASCII} characters or search for them.  To do that,
 you can specify an input method (@pxref{Select Input Method}) suitable
 for your language, or use the default input method set up when you set
@@ -107,6 +113,7 @@
 * Unibyte Mode::            You can pick one European character set
                               to use without multibyte characters.
 * Charsets::                How Emacs groups its internal character codes.
+* Bidirectional Editing::   Support for right-to-left scripts.
 @end menu
 
 @node International Chars
@@ -1653,6 +1660,84 @@
 point before it and type @kbd{C-u C-x =} (@pxref{International
 Chars}).
 
+@node Bidirectional Editing
+@section Bidirectional Editing
+@cindex bidirectional editing
+@cindex right-to-left text
+
+  Emacs supports editing text written in scripts, such as Arabic and
+Hebrew, whose natural ordering of horizontal text for display is from
+right to left.  However, digits and Latin text embedded in these
+scripts are still displayed left to right.  It is also not uncommon to
+have small portions of text in Arabic or Hebrew embedded in otherwise
+Latin document, e.g., as comments and strings in a program source
+file.  For these reasons, text that uses these scripts is actually
+@dfn{bidirectional}: a mixture of runs of left-to-right and
+right-to-left characters.
+
+  This section describes the facilities and options provided by Emacs
+for editing bidirectional text.
+
+@cindex logical order
+@cindex visual order
+  Emacs stores right-to-left and bidirectional text in the so-called
+@dfn{logical} (or @dfn{reading}) order: the buffer or string position
+of the first character you read precedes that of the next character.
+Reordering of bidirectional text into the @dfn{visual} order happens
+at display time.  As result, character positions no longer increase
+monotonically with their positions on display.  Emacs implements the
+Unicode Bidirectional Algorithm described in the Unicode Standard
+Annex #9, for reordering of bidirectional text for display.
+
+@vindex bidi-display-reordering
+  The buffer-local variable @code{bidi-display-reordering} controls
+whether text in the buffer is reordered for display.  If its value is
+non-@code{nil}, Emacs reorders characters that have right-to-left
+directionality when they are displayed.  The default value is
+@code{nil}.
+
+  Each paragraph of bidirectional text can have its own @dfn{base
+direction}, either right-to-left or left-to-right.  (Paragraph
+boundaries are defined by the regular expressions
+@code{paragraph-start} and @code{paragraph-separate}, see
+@ref{Paragraphs}.)  Text in left-to-right paragraphs begins at the
+left margin of the window and is truncated or continued when it
+reaches the right margin.  By contrast, text in right-to-left
+paragraphs begins at the right margin and is continued or truncated at
+the left margin.
+
+@vindex bidi-paragraph-direction
+  Emacs determines the base direction of each paragraph dynamically,
+based on the text at the beginning of the paragraph.  However,
+sometimes a buffer may need to force a certain base direction for its
+paragraphs.  The variable @code{bidi-paragraph-direction}, if
+non-@code{nil}, disables the dynamic determination of the base
+direction, and instead forces all paragraphs in the buffer to have the
+direction specified by its buffer-local value.  The value can be either
+@code{right-to-left} or @code{left-to-right}.  Any other value is
+interpreted as @code{nil}.
+
+@cindex LRM
+@cindex RLM
+  Alternatively, you can control the base direction of a paragraph by
+inserting special formatting characters in front of the paragraph.
+The special character @code{RIGHT-TO-LEFT MARK}, or @sc{rlm}, forces
+the right-to-left direction on the following paragraph, while
+@code{LEFT-TO-RIGHT MARK}, or @sc{lrm} forces the left-to-right
+direction.  (You can use @kbd{C-x 8 RET} to insert these characters.)
+In a GUI session, the @sc{lrm} and @sc{rlm} characters display as
+blanks.
+
+  Because characters are reordered for display, Emacs commands that
+operate in the logical order or on stretches of buffer positions may
+produce unusual effects.  For example, @kbd{C-f} and @kbd{C-b}
+commands move point in the logical order, so the cursor will sometimes
+jump when point traverses reordered bidirectional text.  Similarly, a
+highlighted region covering a contiguous range of character positions
+may look discontinuous if the region spans reordered text.  This is
+normal and similar to behavior of other programs that support
+bidirectional text.
+
 @ignore
    arch-tag: 310ba60d-31ef-4ce7-91f1-f282dd57b6b3
 @end ignore
--- a/etc/HELLO	Sun Mar 28 11:18:10 2010 -0400
+++ b/etc/HELLO	Mon Mar 29 08:26:24 2010 -0400
@@ -16,7 +16,7 @@
 LANGUAGE (NATIVE NAME)	HELLO
 ----------------------	-----
 Amharic ($,1O M[MmN{(B)	$,1M`MKM](B
-Arabic (,GIqjHQYdG(B)	,GecjdY(B ,GeGdqSdG(B
+Arabic $,1ro(B(,GGdYQHjqI(B)	,GecjdY(B ,GeGdqSdG(B
 Bengali ($,17,7>6b727>(B)	$,17(7.787M6u7>70(B
 Braille	$,2(3(1('('(5(B
 Burmese ($,1H9HYH;H4HYrlH9HL(B)	$,1H9H$HYrmH"H<HLH5HL(B
@@ -34,7 +34,7 @@
 German (Deutsch)	Guten Tag / Gr,A|_(B Gott
 Greek (,Fekkgmij\(B)	,FCei\(B ,Fsar(B
 Gujarati ($,19W:!9\9p9~9d: (B)	$,19h9n9x:-9d:'(B
-Hebrew (,Hzixar(B)	,Hylem(B
+Hebrew $,1ro(B($,1-",q-(,y-*(B)	,Hylem(B
 Hungarian (magyar)	Sz,Bi(Bp j,Bs(B napot!
 Hindi ($,15y55B5f6 (B)	$,15h5n5x6-5d6'(B / $,15h5n5x6-5U5~5p(B $,16D(B
 Italian (italiano)	Ciao / Buon giorno
@@ -91,4 +91,5 @@
 
 ;;; Local Variables:
 ;;; tab-width: 32
+;;; bidi-display-reordering: t
 ;;; End:
--- a/etc/NEWS	Sun Mar 28 11:18:10 2010 -0400
+++ b/etc/NEWS	Mon Mar 29 08:26:24 2010 -0400
@@ -36,6 +36,30 @@
 
 * Changes in Emacs 24.1
 
++++
+** Emacs now supports display and editing of bidirectional text.
+Warning: This is still very much experimental!  The existing support
+is minimal, and when it's turned on (see below), many features are
+likely to give unexpected results, or break, or even crash!  Use at
+your own risk!
+
+See the node "Bidirectional Editing" in the Emacs Manual for some
+initial documentation.
+
+To turn this on in any given buffer, set the buffer-local variable
+`bidi-display-reordering' to a non-nil value.  The default is nil.
+
+The buffer-local variable `bidi-paragraph-direction', if non-nil,
+forces each paragraph in the buffer to have its base direction
+according to the value of this variable.  Possible values are
+`right-to-left' and `left-to-right'.  If the value is nil (the
+default), Emacs determines the base direction of each paragraph from
+its text, as specified by the Unicode Bidirectional Algorithm.
+
+Reordering of bidirectional text for display in Emacs is a "Full
+bidirectionality" class implementation of the Unicode Bidirectional
+Algorithm.
+
 ** GTK scroll-bars are now placed on the right by default.
 Use `set-scroll-bar-mode' to change this.
 
--- a/lisp/files.el	Sun Mar 28 11:18:10 2010 -0400
+++ b/lisp/files.el	Mon Mar 29 08:26:24 2010 -0400
@@ -2768,14 +2768,15 @@
 
 (mapc (lambda (pair)
 	(put (car pair) 'safe-local-variable (cdr pair)))
-      '((buffer-read-only     . booleanp)   ;; C source code
-	(default-directory    . stringp)    ;; C source code
-	(fill-column          . integerp)   ;; C source code
-	(indent-tabs-mode     . booleanp)   ;; C source code
-	(left-margin          . integerp)   ;; C source code
-	(no-update-autoloads  . booleanp)
-	(tab-width            . integerp)   ;; C source code
-	(truncate-lines       . booleanp))) ;; C source code
+      '((buffer-read-only        . booleanp)   ;; C source code
+	(default-directory       . stringp)    ;; C source code
+	(fill-column             . integerp)   ;; C source code
+	(indent-tabs-mode        . booleanp)   ;; C source code
+	(left-margin             . integerp)   ;; C source code
+	(no-update-autoloads     . booleanp)
+	(tab-width               . integerp)   ;; C source code
+	(truncate-lines          . booleanp)   ;; C source code
+	(bidi-display-reordering . booleanp))) ;; C source code
 
 (put 'c-set-style 'safe-local-eval-function t)
 
--- a/src/ChangeLog.bidi	Sun Mar 28 11:18:10 2010 -0400
+++ b/src/ChangeLog.bidi	Mon Mar 29 08:26:24 2010 -0400
@@ -1,5 +1,25 @@
+2010-03-29  Eli Zaretskii  <eliz@gnu.org>
+
+	* doc/emacs/mule.texi (International): Mention support of
+	bidirectional editing.
+	(Bidirectional Editing): New section.
+
 2010-03-28  Eli Zaretskii  <eliz@gnu.org>
 
+	* etc/HELLO: Reorder Arabic and Hebrew into logical order, and
+	insert RLM before the opening paren, to make the display more
+	reasonable.  Add setting for bidi-display-reordering in the local
+	variables section.
+
+	* lisp/files.el: Make bidi-display-reordering safe variable for
+	boolean values.
+
+	* xdisp (append_glyph): If the glyph row is reversed, prepend the
+	glyph rather than appending it.
+
+	* makefile.w32-in (OBJ1): Add $(BLD)/bidi.$(O).
+	($(BLD)/bidi.$(O)): New target.
+
 	* bidi.c (bidi_get_next_char_visually): Improve commentary.
 
 	* dispextern.h (PRODUCE_GLYPHS): Set the reversed_p flag in the
--- a/src/makefile.w32-in	Sun Mar 28 11:18:10 2010 -0400
+++ b/src/makefile.w32-in	Mon Mar 29 08:26:24 2010 -0400
@@ -115,6 +115,7 @@
 	$(BLD)/vm-limit.$(O)		\
 	$(BLD)/region-cache.$(O)	\
 	$(BLD)/strftime.$(O)		\
+	$(BLD)/bidi.$(O)		\
 	$(BLD)/charset.$(O)		\
 	$(BLD)/character.$(O)		\
 	$(BLD)/chartab.$(O)		\
@@ -338,6 +339,14 @@
 	$(SRC)/syssignal.h \
 	$(SRC)/systime.h
 
+$(BLD)/bidi.$(O) : \
+	$(SRC)/bidi.c \
+	$(CONFIG_H) \
+	$(SRC)/lisp.h \
+	$(SRC)/buffer.h \
+	$(SRC)/character.h \
+	$(SRC)/dispextern.h
+
 $(BLD)/buffer.$(O) : \
 	$(SRC)/buffer.c \
 	$(CONFIG_H) \
--- a/src/xdisp.c	Sun Mar 28 11:18:10 2010 -0400
+++ b/src/xdisp.c	Mon Mar 29 08:26:24 2010 -0400
@@ -17823,8 +17823,8 @@
   ++it->vpos;
   ++it->glyph_row;
   /* 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
-     recomputes the value of the flag accordingly.  */
+     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;
   it->start = row_end;
   return row->displays_text_p;
@@ -21355,6 +21355,17 @@
   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 && area == TEXT_AREA)
+	{
+	  struct glyph *g;
+
+	  /* Make room for the additional glyph.  */
+	  for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
+	    g[1] = *g;
+	  glyph = it->glyph_row->glyphs[area];
+	}
       glyph->charpos = CHARPOS (it->position);
       glyph->object = it->object;
       if (it->pixel_width > 0)
@@ -21391,6 +21402,11 @@
 	    abort ();
 	  glyph->bidi_type = it->bidi_it.type;
 	}
+      else
+	{
+	  glyph->resolved_level = 0;
+	  glyph->bidi_type = UNKNOWN_BT;
+	}
       ++it->glyph_row->used[area];
     }
   else