# HG changeset patch # User Eli Zaretskii # Date 1269865584 14400 # Node ID dfdf14a6f5a0a46c0aaacac687b61fa8cb2df26d # Parent 6e29ba4351e00ddeac296038b599f5ea777eedb4 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. diff -r 6e29ba4351e0 -r dfdf14a6f5a0 doc/emacs/mule.texi --- 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 diff -r 6e29ba4351e0 -r dfdf14a6f5a0 etc/HELLO --- 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 + + * 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 -r 6e29ba4351e0 -r dfdf14a6f5a0 src/makefile.w32-in --- 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) \ diff -r 6e29ba4351e0 -r dfdf14a6f5a0 src/xdisp.c --- 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