From f4b6ba46b857e140c6482c0542c70fc989b1fe85 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Mon, 29 Mar 2010 08:26:24 -0400 Subject: [PATCH] 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. --- doc/emacs/mule.texi | 85 +++++++++++++++++++++++++++++++++++++++++++++ etc/HELLO | 5 +-- etc/NEWS | 24 +++++++++++++ lisp/files.el | 17 ++++----- src/ChangeLog.bidi | 20 +++++++++++ src/makefile.w32-in | 9 +++++ src/xdisp.c | 20 +++++++++-- 7 files changed, 168 insertions(+), 12 deletions(-) diff --git a/doc/emacs/mule.texi b/doc/emacs/mule.texi index 00aa9047aec..6420132e0ce 100644 --- a/doc/emacs/mule.texi +++ b/doc/emacs/mule.texi @@ -66,6 +66,12 @@ displays (@pxref{Terminal Coding}). If some characters are displayed incorrectly, refer to @ref{Undisplayable Characters}, which describes 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 @@ -107,6 +113,7 @@ to make sure Emacs interprets keyboard input correctly; see * 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 @@ older Emacs versions. 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 diff --git a/etc/HELLO b/etc/HELLO index 0f582f6c408..9e0c66a0241 100644 --- a/etc/HELLO +++ b/etc/HELLO @@ -16,7 +16,7 @@ Non-ASCII examples: 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. ;;; Local Variables: ;;; tab-width: 32 +;;; bidi-display-reordering: t ;;; End: diff --git a/etc/NEWS b/etc/NEWS index 1518f9ffc0c..408ba236bf8 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -36,6 +36,30 @@ lib-src/Makefile by hand in order to use the associated features. * 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. diff --git a/lisp/files.el b/lisp/files.el index ed12d2a393a..3b3bbe19bbb 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -2768,14 +2768,15 @@ asking you for confirmation." (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) diff --git a/src/ChangeLog.bidi b/src/ChangeLog.bidi index d27f747466b..33982c21450 100644 --- a/src/ChangeLog.bidi +++ b/src/ChangeLog.bidi @@ -1,5 +1,25 @@ +2010-03-29 Eli Zaretskii + + * doc/emacs/mule.texi (International): Mention support of + bidirectional editing. + (Bidirectional Editing): New section. + 2010-03-28 Eli Zaretskii + * 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 diff --git a/src/makefile.w32-in b/src/makefile.w32-in index 156eddd6092..edb3f3f711b 100644 --- a/src/makefile.w32-in +++ b/src/makefile.w32-in @@ -115,6 +115,7 @@ OBJ1 = $(BLD)/alloc.$(O) \ $(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 @@ $(BLD)/atimer.$(O) : \ $(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) \ diff --git a/src/xdisp.c b/src/xdisp.c index 867018180aa..ed2db08905d 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -17823,8 +17823,8 @@ display_line (it) ++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 @@ append_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 && 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 @@ append_glyph (it) abort (); glyph->bidi_type = it->bidi_it.type; } + else + { + glyph->resolved_level = 0; + glyph->bidi_type = UNKNOWN_BT; + } ++it->glyph_row->used[area]; } else -- 2.39.2