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.
This commit is contained in:
Eli Zaretskii 2010-03-29 08:26:24 -04:00
parent c0546589ab
commit f4b6ba46b8
7 changed files with 168 additions and 12 deletions

View file

@ -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

View file

@ -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<HLH5HL(B
@ -34,7 +34,7 @@ Georgian ($,1JEJ0J@J7J5J4J:J8(B) $,1J2J0J;J0J@JOJ=J1J0(B
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 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;; Local Variables:
;;; tab-width: 32
;;; bidi-display-reordering: t
;;; End:

View file

@ -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.

View file

@ -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)

View file

@ -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

View file

@ -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) \

View file

@ -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