Initial support for bidirectional editing.
Makefile.in (obj): Include bidi.o. (bidi.o): New target. makefile.w32-in (OBJ1): Add $(BLD)/bidi.$(O). ($(BLD)/bidi.$(O)): New target. bidi.c: New file. buffer.h (struct buffer): New members bidi_display_reordering and bidi_paragraph_direction. buffer.c (init_buffer_once): Initialize bidi_display_reordering and bidi_paragraph_direction. (syms_of_buffer): Declare Lisp variables bidi-display-reordering and bidi-paragraph-direction. (Fbuffer_swap_text): Swap the values of bidi_display_reordering and bidi_paragraph_direction. dispextern.h (BIDI_MAXLEVEL, BIDI_AT_BASE_LEVEL): New macros. (bidi_type_t, bidi_dir_t): New types. (bidi_saved_info, bidi_stack, bidi_it): New structures. (struct it): New members bidi_p, bidi_it, paragraph_embedding, prev_stop, base_level_stop, and eol_pos. (bidi_init_it, bidi_get_next_char_visually): New prototypes. (IT_STACK_SIZE): Enlarge to 5. (struct glyph_row): New member reversed_p. <string_buffer_position>: Update prototype. (PRODUCE_GLYPHS): Set the reversed_p flag in the iterator's glyph_row if bidi_it.paragraph_dir == R2L. (struct glyph): New members resolved_level and bidi_type. dispnew.c (direct_output_forward_char): Give up if we need bidi processing or buffer's direction is right-to-left. (prepare_desired_row): Preserve the reversed_p flag. (row_equal_p): Compare the reversed_p attributes as well. xdisp.c (init_iterator): Initialize it->bidi_p. Call bidi_init_it and set it->paragraph_embedding from the current buffer's value of bidi_paragraph_direction. (reseat_1): Initialize bidi_it.first_elt. (set_iterator_to_next, next_element_from_buffer): Use the value of paragraph_embedding to determine the paragraph direction. (set_iterator_to_next): Under bidi reordering, call bidi_get_next_char_visually. Call bidi_paragraph_init if the new_paragraph flag is set in the bidi iterator. (next_element_from_buffer): If bidi_it.first_elt is set, initialize paragraph direction and find the first character to display in the visual order. If reseated to a middle of a line, prime the bidi iterator starting at the line's beginning. Handle the situation where we overstepped stop_charpos due to non-linearity of the bidi iteration. Likewise for when we back up beyond the previous stop_charpos. When moving across stop_charpos, record it in prev_stop. (display_line): Set row->end and it->start for the next row to the next character in logical order. Always extend reversed_p rows to the end of line, even if they end at ZV. Copy the reversed_p flag to the next glyph row. Keep calling set_cursor_from_row for bidi-reordered rows even if we already have a possible candidate for cursor position. Set row_end after all the row's glyphs have been produced, by looping over the glyphs. Record the position after EOL in it->eol_pos, and use it to set end_pos of the last row produced for a continued line. <Qright_to_left, Qleft_to_right>: New variables. (syms_of_xdisp): Initialize and staticpro them. (string_buffer_position_lim): New function. (string_buffer_position): Most of code moved to string_buffer_position_lim. Last argument and return value are now EMACS_INT; all callers changed. (set_cursor_from_row): Rewritten to support bidirectional text and reversed glyph rows. (text_outside_line_unchanged_p, try_window_id): Disable optimizations if we are reordering bidirectional text and the paragraph direction can be affected by the change. (append_glyph, append_composite_glyph) (produce_image_glyph, append_stretch_glyph): Set the resolved_level and bidi_type members of each glyph. (append_glyph): If the glyph row is reversed, prepend the glyph rather than appending it. (handle_stop_backwards): New function. (reseat_1, pop_it, push_it): Set prev_stop and base_level_stop. (reseat): call handle_stop_backwards to recompute prev_stop and base_level_stop for the new position. (handle_invisible_prop): Under bidi iteration, skip invisible text using bidi_get_next_char_visually. If we are `reseat'ed, init the paragraph direction. Update IT->prev_stop after skipping invisible text. (move_it_in_display_line_to): New variables prev_method and prev_pos. Compare for strict equality in BUFFER_POS_REACHED_P. (try_cursor_movement): Examine all the candidate rows that occlude point, to return the best match. If rows are bidi-reordered and point moved backwards, back up to the row that is not a continuation line, and start looking for a suitable row from there. term.c (append_glyph): Reverse glyphs by pre-pending them, rather than appending, if the glyph_row's reversed_p flag is set. Set the resolved_level and bidi_type members of each glyph. .gdbinit (pbiditype): New command. (pgx): Use it to display bidi level and type of the glyph. (pitx): Display some bidi information about the iterator. (prowlims, pmtxrows): New commands. files.el: Make bidi-display-reordering safe variable for boolean values. mule.texi (International): Mention support of bidirectional editing. (Bidirectional Editing): New section. 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. NEWS: Mention initial support for bidirectional editing.
This commit is contained in:
commit
a7b0282034
19 changed files with 3631 additions and 229 deletions
|
@ -1,3 +1,8 @@
|
|||
2010-03-30 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* mule.texi (International): Mention support of bidirectional editing.
|
||||
(Bidirectional Editing): New section.
|
||||
|
||||
2010-03-28 Nick Roberts <nickrob@snap.net.nz>
|
||||
|
||||
* emacs.texi (Top): Update node names to those in building.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
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
2010-03-28 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* 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.
|
||||
* NEWS: Mention initial support for bidirectional editing.
|
||||
|
||||
2010-03-24 Francesc Rocher <rocher@member.fsf.org>
|
||||
|
||||
* MORE.STUFF: Remove CEDET entry, now distributed as part of
|
||||
|
|
|
@ -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:
|
||||
|
|
24
etc/NEWS
24
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.
|
||||
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2010-03-30 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* files.el: Make bidi-display-reordering safe variable for boolean
|
||||
values.
|
||||
|
||||
2010-03-29 Phil Hagelberg <phil@evri.com>
|
||||
Chong Yidong <cyd@stupidchicken.com>
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
60
src/.gdbinit
60
src/.gdbinit
|
@ -271,6 +271,9 @@ define pitx
|
|||
end
|
||||
end
|
||||
printf "\n"
|
||||
if ($it->bidi_p)
|
||||
printf "BIDI: base_stop=%d prev_stop=%d level=%d\n", $it->base_level_stop, $it->prev_stop, $it->bidi_it.resolved_level
|
||||
end
|
||||
if ($it->region_beg_charpos >= 0)
|
||||
printf "reg=%d-%d ", $it->region_beg_charpos, $it->region_end_charpos
|
||||
end
|
||||
|
@ -447,6 +450,36 @@ document pwin
|
|||
Pretty print window structure w.
|
||||
end
|
||||
|
||||
define pbiditype
|
||||
if ($arg0 == 0)
|
||||
printf "UNDEF"
|
||||
end
|
||||
if ($arg0 == 1)
|
||||
printf "L"
|
||||
end
|
||||
if ($arg0 == 2)
|
||||
printf "R"
|
||||
end
|
||||
if ($arg0 == 3)
|
||||
printf "EN"
|
||||
end
|
||||
if ($arg0 == 4)
|
||||
printf "AN"
|
||||
end
|
||||
if ($arg0 == 5)
|
||||
printf "BN"
|
||||
end
|
||||
if ($arg0 == 6)
|
||||
printf "B"
|
||||
end
|
||||
if ($arg0 < 0 || $arg0 > 6)
|
||||
printf "%d??", $arg0
|
||||
end
|
||||
end
|
||||
document pbiditype
|
||||
Print textual description of bidi type given as first argument.
|
||||
end
|
||||
|
||||
define pgx
|
||||
set $g = $arg0
|
||||
# CHAR_GLYPH
|
||||
|
@ -475,6 +508,11 @@ define pgx
|
|||
else
|
||||
printf " pos=%d", $g->charpos
|
||||
end
|
||||
# For characters, print their resolved level and bidi type
|
||||
if ($g->type == 0)
|
||||
printf " blev=%d,btyp=", $g->resolved_level
|
||||
pbiditype $g->bidi_type
|
||||
end
|
||||
printf " w=%d a+d=%d+%d", $g->pixel_width, $g->ascent, $g->descent
|
||||
# If not DEFAULT_FACE_ID
|
||||
if ($g->face_id != 0)
|
||||
|
@ -575,6 +613,28 @@ document pgrowit
|
|||
Pretty print all glyphs in it->glyph_row.
|
||||
end
|
||||
|
||||
define prowlims
|
||||
printf "start=%d,end=%d,reversed=%d,cont=%d,at_zv=%d\n", $arg0->start.pos.charpos, $arg0->end.pos.charpos, $arg0->reversed_p, $arg0->continued_p, $arg0->ends_at_zv_p
|
||||
end
|
||||
document prowlims
|
||||
Print important attributes of a glyph_row structure.
|
||||
Takes one argument, a pointer to a glyph_row structure.
|
||||
end
|
||||
|
||||
define pmtxrows
|
||||
set $mtx = $arg0
|
||||
set $gl = $mtx->rows
|
||||
set $glend = $mtx->rows + $mtx->nrows
|
||||
while ($gl < $glend)
|
||||
prowlims $gl
|
||||
set $gl = $gl + 1
|
||||
end
|
||||
end
|
||||
document pmtxrows
|
||||
Print data about glyph rows in a glyph matrix.
|
||||
Takes one argument, a pointer to a glyph_matrix structure.
|
||||
end
|
||||
|
||||
define xtype
|
||||
xgettype $
|
||||
output $type
|
||||
|
|
108
src/ChangeLog
108
src/ChangeLog
|
@ -1,3 +1,111 @@
|
|||
2010-03-30 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
Initial support for bidirectional editing.
|
||||
|
||||
* Makefile.in (obj): Include bidi.o.
|
||||
(bidi.o): New target.
|
||||
|
||||
* makefile.w32-in (OBJ1): Add $(BLD)/bidi.$(O).
|
||||
($(BLD)/bidi.$(O)): New target.
|
||||
|
||||
* bidi.c: New file.
|
||||
|
||||
* buffer.h (struct buffer): New members bidi_display_reordering
|
||||
and bidi_paragraph_direction.
|
||||
|
||||
* buffer.c (init_buffer_once): Initialize bidi_display_reordering
|
||||
and bidi_paragraph_direction.
|
||||
(syms_of_buffer): Declare Lisp variables bidi-display-reordering
|
||||
and bidi-paragraph-direction.
|
||||
(Fbuffer_swap_text): Swap the values of
|
||||
bidi_display_reordering and bidi_paragraph_direction.
|
||||
|
||||
* dispextern.h (BIDI_MAXLEVEL, BIDI_AT_BASE_LEVEL): New macros.
|
||||
(bidi_type_t, bidi_dir_t): New types.
|
||||
(bidi_saved_info, bidi_stack, bidi_it): New structures.
|
||||
(struct it): New members bidi_p, bidi_it, paragraph_embedding,
|
||||
prev_stop, base_level_stop, and eol_pos.
|
||||
(bidi_init_it, bidi_get_next_char_visually): New prototypes.
|
||||
(IT_STACK_SIZE): Enlarge to 5.
|
||||
(struct glyph_row): New member reversed_p.
|
||||
<string_buffer_position>: Update prototype.
|
||||
(PRODUCE_GLYPHS): Set the reversed_p flag in the iterator's
|
||||
glyph_row if bidi_it.paragraph_dir == R2L.
|
||||
(struct glyph): New members resolved_level and bidi_type.
|
||||
|
||||
* dispnew.c (direct_output_forward_char): Give up if we need bidi
|
||||
processing or buffer's direction is right-to-left.
|
||||
(prepare_desired_row): Preserve the reversed_p flag.
|
||||
(row_equal_p): Compare the reversed_p attributes as well.
|
||||
|
||||
* xdisp.c (init_iterator): Initialize it->bidi_p. Call
|
||||
bidi_init_it and set it->paragraph_embedding from the current
|
||||
buffer's value of bidi_paragraph_direction.
|
||||
(reseat_1): Initialize bidi_it.first_elt.
|
||||
(set_iterator_to_next, next_element_from_buffer): Use the value of
|
||||
paragraph_embedding to determine the paragraph direction.
|
||||
(set_iterator_to_next): Under bidi reordering, call
|
||||
bidi_get_next_char_visually. Call bidi_paragraph_init if the
|
||||
new_paragraph flag is set in the bidi iterator.
|
||||
(next_element_from_buffer): If bidi_it.first_elt is set,
|
||||
initialize paragraph direction and find the first character to
|
||||
display in the visual order. If reseated to a middle of a line,
|
||||
prime the bidi iterator starting at the line's beginning. Handle
|
||||
the situation where we overstepped stop_charpos due to
|
||||
non-linearity of the bidi iteration. Likewise for when we back up
|
||||
beyond the previous stop_charpos. When moving across stop_charpos,
|
||||
record it in prev_stop.
|
||||
(display_line): Set row->end and it->start for the next row to the
|
||||
next character in logical order. Always extend reversed_p rows to
|
||||
the end of line, even if they end at ZV. Copy the reversed_p flag
|
||||
to the next glyph row. Keep calling set_cursor_from_row for
|
||||
bidi-reordered rows even if we already have a possible candidate
|
||||
for cursor position. Set row_end after all the row's glyphs have
|
||||
been produced, by looping over the glyphs. Record the position
|
||||
after EOL in it->eol_pos, and use it to set end_pos of the last
|
||||
row produced for a continued line.
|
||||
<Qright_to_left, Qleft_to_right>: New variables.
|
||||
(syms_of_xdisp): Initialize and staticpro them.
|
||||
(string_buffer_position_lim): New function.
|
||||
(string_buffer_position): Most of code moved to
|
||||
string_buffer_position_lim. Last argument and return value are
|
||||
now EMACS_INT; all callers changed.
|
||||
(set_cursor_from_row): Rewritten to support bidirectional text and
|
||||
reversed glyph rows.
|
||||
(text_outside_line_unchanged_p, try_window_id): Disable
|
||||
optimizations if we are reordering bidirectional text and the
|
||||
paragraph direction can be affected by the change.
|
||||
(append_glyph, append_composite_glyph)
|
||||
(produce_image_glyph, append_stretch_glyph): Set the
|
||||
resolved_level and bidi_type members of each glyph.
|
||||
(append_glyph): If the glyph row is reversed, prepend the glyph
|
||||
rather than appending it.
|
||||
(handle_stop_backwards): New function.
|
||||
(reseat_1, pop_it, push_it): Set prev_stop and base_level_stop.
|
||||
(reseat): call handle_stop_backwards to recompute prev_stop and
|
||||
base_level_stop for the new position.
|
||||
(handle_invisible_prop): Under bidi iteration, skip invisible text
|
||||
using bidi_get_next_char_visually. If we are `reseat'ed, init the
|
||||
paragraph direction. Update IT->prev_stop after skipping
|
||||
invisible text.
|
||||
(move_it_in_display_line_to): New variables prev_method
|
||||
and prev_pos. Compare for strict equality in
|
||||
BUFFER_POS_REACHED_P.
|
||||
(try_cursor_movement): Examine all the candidate rows that occlude
|
||||
point, to return the best match. If rows are bidi-reordered
|
||||
and point moved backwards, back up to the row that is not a
|
||||
continuation line, and start looking for a suitable row from
|
||||
there.
|
||||
|
||||
* term.c (append_glyph): Reverse glyphs by pre-pending them,
|
||||
rather than appending, if the glyph_row's reversed_p flag is set.
|
||||
Set the resolved_level and bidi_type members of each glyph.
|
||||
|
||||
* .gdbinit (pbiditype): New command.
|
||||
(pgx): Use it to display bidi level and type of the glyph.
|
||||
(pitx): Display some bidi information about the iterator.
|
||||
(prowlims, pmtxrows): New commands.
|
||||
|
||||
2010-03-30 Dan Nicolaescu <dann@ics.uci.edu>
|
||||
|
||||
Remove all uses of C_DEBUG_SWITCH and LIBS_DEBUG.
|
||||
|
|
|
@ -496,7 +496,7 @@ FONT_DRIVERS = xfont.o
|
|||
/* lastfile must follow all files
|
||||
whose initialized data areas should be dumped as pure by dump-emacs. */
|
||||
obj= dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \
|
||||
charset.o coding.o category.o ccl.o character.o chartab.o \
|
||||
charset.o coding.o category.o ccl.o character.o chartab.o bidi.o \
|
||||
cm.o term.o terminal.o xfaces.o $(XOBJ) $(GTK_OBJ) $(DBUS_OBJ) \
|
||||
emacs.o keyboard.o macros.o keymap.o sysdep.o \
|
||||
buffer.o filelock.o insdel.o marker.o \
|
||||
|
@ -982,6 +982,7 @@ doc.o: buildobj.h
|
|||
|
||||
atimer.o: atimer.c atimer.h syssignal.h systime.h lisp.h blockinput.h \
|
||||
$(config_h)
|
||||
bidi.o: bidi.c buffer.h character.h dispextern.h lisp.h $(config_h)
|
||||
buffer.o: buffer.c buffer.h region-cache.h commands.h window.h \
|
||||
$(INTERVALS_H) blockinput.h atimer.h systime.h character.h \
|
||||
indent.h keyboard.h coding.h keymap.h frame.h lisp.h $(config_h)
|
||||
|
|
2028
src/bidi.c
Normal file
2028
src/bidi.c
Normal file
File diff suppressed because it is too large
Load diff
37
src/buffer.c
37
src/buffer.c
|
@ -2279,6 +2279,8 @@ DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text,
|
|||
swapfield (undo_list, Lisp_Object);
|
||||
swapfield (mark, Lisp_Object);
|
||||
swapfield (enable_multibyte_characters, Lisp_Object);
|
||||
swapfield (bidi_display_reordering, Lisp_Object);
|
||||
swapfield (bidi_paragraph_direction, Lisp_Object);
|
||||
/* FIXME: Not sure what we should do with these *_marker fields.
|
||||
Hopefully they're just nil anyway. */
|
||||
swapfield (pt_marker, Lisp_Object);
|
||||
|
@ -5206,7 +5208,9 @@ init_buffer_once ()
|
|||
buffer_defaults.truncate_lines = Qnil;
|
||||
buffer_defaults.word_wrap = Qnil;
|
||||
buffer_defaults.ctl_arrow = Qt;
|
||||
buffer_defaults.bidi_display_reordering = Qnil;
|
||||
buffer_defaults.direction_reversed = Qnil;
|
||||
buffer_defaults.bidi_paragraph_direction = Qnil;
|
||||
buffer_defaults.cursor_type = Qt;
|
||||
buffer_defaults.extra_line_spacing = Qnil;
|
||||
buffer_defaults.cursor_in_non_selected_windows = Qt;
|
||||
|
@ -5291,7 +5295,9 @@ init_buffer_once ()
|
|||
XSETFASTINT (buffer_local_flags.syntax_table, idx); ++idx;
|
||||
XSETFASTINT (buffer_local_flags.cache_long_line_scans, idx); ++idx;
|
||||
XSETFASTINT (buffer_local_flags.category_table, idx); ++idx;
|
||||
XSETFASTINT (buffer_local_flags.bidi_display_reordering, idx); ++idx;
|
||||
XSETFASTINT (buffer_local_flags.direction_reversed, idx); ++idx;
|
||||
XSETFASTINT (buffer_local_flags.bidi_paragraph_direction, idx); ++idx;
|
||||
XSETFASTINT (buffer_local_flags.buffer_file_coding_system, idx);
|
||||
/* Make this one a permanent local. */
|
||||
buffer_permanent_local_flags[idx++] = 1;
|
||||
|
@ -5548,11 +5554,6 @@ This is the same as (default-value 'abbrev-mode). */);
|
|||
doc: /* Default value of `ctl-arrow' for buffers that do not override it.
|
||||
This is the same as (default-value 'ctl-arrow). */);
|
||||
|
||||
DEFVAR_LISP_NOPRO ("default-direction-reversed",
|
||||
&buffer_defaults.direction_reversed,
|
||||
doc: /* Default value of `direction-reversed' for buffers that do not override it.
|
||||
This is the same as (default-value 'direction-reversed). */);
|
||||
|
||||
DEFVAR_LISP_NOPRO ("default-enable-multibyte-characters",
|
||||
&buffer_defaults.enable_multibyte_characters,
|
||||
doc: /* *Default value of `enable-multibyte-characters' for buffers not overriding it.
|
||||
|
@ -5809,11 +5810,29 @@ The variable `coding-system-for-write', if non-nil, overrides this variable.
|
|||
|
||||
This variable is never applied to a way of decoding a file while reading it. */);
|
||||
|
||||
DEFVAR_PER_BUFFER ("direction-reversed", ¤t_buffer->direction_reversed,
|
||||
Qnil,
|
||||
doc: /* *Non-nil means lines in the buffer are displayed right to left. */);
|
||||
DEFVAR_PER_BUFFER ("direction-reversed",
|
||||
¤t_buffer->direction_reversed, Qnil,
|
||||
doc: /* Non-nil means set beginning of lines at the right edge of the window.
|
||||
See also the variable `bidi-display-reordering'. */);
|
||||
|
||||
DEFVAR_PER_BUFFER ("truncate-lines", ¤t_buffer->truncate_lines, Qnil,
|
||||
DEFVAR_PER_BUFFER ("bidi-display-reordering",
|
||||
¤t_buffer->bidi_display_reordering, Qnil,
|
||||
doc: /* Non-nil means reorder bidirectional text for display in the visual order.
|
||||
See also the variable `direction-reversed'. */);
|
||||
|
||||
DEFVAR_PER_BUFFER ("bidi-paragraph-direction",
|
||||
¤t_buffer->bidi_paragraph_direction, Qnil,
|
||||
doc: /* *If non-nil, forces directionality of text paragraphs in the buffer.
|
||||
|
||||
If this is nil (the default), the direction of each paragraph is
|
||||
determined by the first strong directional character of its text.
|
||||
The values of `right-to-left' and `left-to-right' override that.
|
||||
Any other value is treated as nil.
|
||||
|
||||
This variable has no effect unless the buffer's value of
|
||||
\`bidi-display-reordering' is non-nil. */);
|
||||
|
||||
DEFVAR_PER_BUFFER ("truncate-lines", ¤t_buffer->truncate_lines, Qnil,
|
||||
doc: /* *Non-nil means do not display continuation lines.
|
||||
Instead, give each line of text just one screen line.
|
||||
|
||||
|
|
10
src/buffer.h
10
src/buffer.h
|
@ -662,8 +662,16 @@ struct buffer
|
|||
Lisp_Object word_wrap;
|
||||
/* Non-nil means display ctl chars with uparrow. */
|
||||
Lisp_Object ctl_arrow;
|
||||
/* Non-nil means display text from right to left. */
|
||||
/* Non-nil means reorder bidirectional text for display in the
|
||||
visual order. */
|
||||
Lisp_Object bidi_display_reordering;
|
||||
/* Non-nil means set beginning of lines at the right edge of
|
||||
windows. */
|
||||
Lisp_Object direction_reversed;
|
||||
/* If non-nil, specifies which direction of text to force in all the
|
||||
paragraphs of the buffer. Nil means determine paragraph
|
||||
direction dynamically for each paragraph. */
|
||||
Lisp_Object bidi_paragraph_direction;
|
||||
/* Non-nil means do selective display;
|
||||
see doc string in syms_of_buffer (buffer.c) for details. */
|
||||
Lisp_Object selective_display;
|
||||
|
|
163
src/dispextern.h
163
src/dispextern.h
|
@ -370,6 +370,16 @@ struct glyph
|
|||
/* Non-zero means don't display cursor here. */
|
||||
unsigned avoid_cursor_p : 1;
|
||||
|
||||
/* Resolved bidirectional level of this character [0..63]. */
|
||||
unsigned resolved_level : 5;
|
||||
|
||||
/* Resolved bidirectional type of this character, see enum
|
||||
bidi_type_t below. Note that according to UAX#9, only some
|
||||
values (STRONG_L, STRONG_R, WEAK_AN, WEAK_EN, WEAK_BN, and
|
||||
NEUTRAL_B) can appear in the resolved type, so we only reserve
|
||||
space for those that can. */
|
||||
unsigned bidi_type : 3;
|
||||
|
||||
#define FACE_ID_BITS 20
|
||||
|
||||
/* Face of the glyph. This is a realized face ID,
|
||||
|
@ -739,14 +749,18 @@ struct glyph_row
|
|||
/* First position in this row. This is the text position, including
|
||||
overlay position information etc, where the display of this row
|
||||
started, and can thus be less the position of the first glyph
|
||||
(e.g. due to invisible text or horizontal scrolling). */
|
||||
(e.g. due to invisible text or horizontal scrolling). BIDI Note:
|
||||
This is the smallest character position in the row, but not
|
||||
necessarily the character that is the leftmost on the display. */
|
||||
struct display_pos start;
|
||||
|
||||
/* Text position at the end of this row. This is the position after
|
||||
the last glyph on this row. It can be greater than the last
|
||||
glyph position + 1, due to truncation, invisible text etc. In an
|
||||
up-to-date display, this should always be equal to the start
|
||||
position of the next row. */
|
||||
position of the next row. BIDI Note: this is the character whose
|
||||
buffer position is the largest, but not necessarily the rightmost
|
||||
one on the display. */
|
||||
struct display_pos end;
|
||||
|
||||
/* Non-zero means the overlay arrow bitmap is on this line.
|
||||
|
@ -872,6 +886,10 @@ struct glyph_row
|
|||
the bottom line of the window, but not end of the buffer. */
|
||||
unsigned indicate_bottom_line_p : 1;
|
||||
|
||||
/* Non-zero means the row was reversed to display text in a
|
||||
right-to-left paragraph. */
|
||||
unsigned reversed_p : 1;
|
||||
|
||||
/* Continuation lines width at the start of the row. */
|
||||
int continuation_lines_width;
|
||||
|
||||
|
@ -924,12 +942,18 @@ struct glyph_row *matrix_row P_ ((struct glyph_matrix *, int));
|
|||
(MATRIX_ROW ((MATRIX), (ROW))->used[TEXT_AREA])
|
||||
|
||||
/* Return the character/ byte position at which the display of ROW
|
||||
starts. */
|
||||
starts. BIDI Note: this is the smallest character/byte position
|
||||
among characters in ROW, i.e. the first logical-order character
|
||||
displayed by ROW, which is not necessarily the smallest horizontal
|
||||
position. */
|
||||
|
||||
#define MATRIX_ROW_START_CHARPOS(ROW) ((ROW)->start.pos.charpos)
|
||||
#define MATRIX_ROW_START_BYTEPOS(ROW) ((ROW)->start.pos.bytepos)
|
||||
|
||||
/* Return the character/ byte position at which ROW ends. */
|
||||
/* Return the character/ byte position at which ROW ends. BIDI Note:
|
||||
this is the largest character/byte position among characters in
|
||||
ROW, i.e. the last logical-order character displayed by ROW, which
|
||||
is not necessarily the largest horizontal position. */
|
||||
|
||||
#define MATRIX_ROW_END_CHARPOS(ROW) ((ROW)->end.pos.charpos)
|
||||
#define MATRIX_ROW_END_BYTEPOS(ROW) ((ROW)->end.pos.bytepos)
|
||||
|
@ -1702,7 +1726,93 @@ struct face_cache
|
|||
|
||||
extern int face_change_count;
|
||||
|
||||
/* For reordering of bidirectional text. */
|
||||
#define BIDI_MAXLEVEL 64
|
||||
|
||||
/* Data type for describing the bidirectional character types. The
|
||||
first 7 must be at the beginning, because they are the only values
|
||||
valid in the `bidi_type' member of `struct glyph'; we only reserve
|
||||
3 bits for it, so we cannot use there values larger than 7. */
|
||||
typedef enum {
|
||||
UNKNOWN_BT = 0,
|
||||
STRONG_L, /* strong left-to-right */
|
||||
STRONG_R, /* strong right-to-left */
|
||||
WEAK_EN, /* european number */
|
||||
WEAK_AN, /* arabic number */
|
||||
WEAK_BN, /* boundary neutral */
|
||||
NEUTRAL_B, /* paragraph separator */
|
||||
STRONG_AL, /* arabic right-to-left letter */
|
||||
LRE, /* left-to-right embedding */
|
||||
LRO, /* left-to-right override */
|
||||
RLE, /* right-to-left embedding */
|
||||
RLO, /* right-to-left override */
|
||||
PDF, /* pop directional format */
|
||||
WEAK_ES, /* european number separator */
|
||||
WEAK_ET, /* european number terminator */
|
||||
WEAK_CS, /* common separator */
|
||||
WEAK_NSM, /* non-spacing mark */
|
||||
NEUTRAL_S, /* segment separator */
|
||||
NEUTRAL_WS, /* whitespace */
|
||||
NEUTRAL_ON /* other neutrals */
|
||||
} bidi_type_t;
|
||||
|
||||
/* The basic directionality data type. */
|
||||
typedef enum { NEUTRAL_DIR, L2R, R2L } bidi_dir_t;
|
||||
|
||||
/* Data type for storing information about characters we need to
|
||||
remember. */
|
||||
struct bidi_saved_info {
|
||||
int bytepos, charpos; /* character's buffer position */
|
||||
bidi_type_t type; /* character's resolved bidi type */
|
||||
bidi_type_t type_after_w1; /* original type of the character, after W1 */
|
||||
bidi_type_t orig_type; /* type as we found it in the buffer */
|
||||
};
|
||||
|
||||
/* Data type for keeping track of saved embedding levels and override
|
||||
status information. */
|
||||
struct bidi_stack {
|
||||
int level;
|
||||
bidi_dir_t override;
|
||||
};
|
||||
|
||||
/* Data type for iterating over bidi text. */
|
||||
struct bidi_it {
|
||||
EMACS_INT bytepos; /* iterator's position in buffer */
|
||||
EMACS_INT charpos;
|
||||
int ch; /* character itself */
|
||||
int ch_len; /* length of its multibyte sequence */
|
||||
bidi_type_t type; /* bidi type of this character, after
|
||||
resolving weak and neutral types */
|
||||
bidi_type_t type_after_w1; /* original type, after overrides and W1 */
|
||||
bidi_type_t orig_type; /* original type, as found in the buffer */
|
||||
int resolved_level; /* final resolved level of this character */
|
||||
int invalid_levels; /* how many PDFs to ignore */
|
||||
int invalid_rl_levels; /* how many PDFs from RLE/RLO to ignore */
|
||||
int prev_was_pdf; /* if non-zero, previous char was PDF */
|
||||
struct bidi_saved_info prev; /* info about previous character */
|
||||
struct bidi_saved_info last_strong; /* last-seen strong directional char */
|
||||
struct bidi_saved_info next_for_neutral; /* surrounding characters for... */
|
||||
struct bidi_saved_info prev_for_neutral; /* ...resolving neutrals */
|
||||
struct bidi_saved_info next_for_ws; /* character after sequence of ws */
|
||||
EMACS_INT next_en_pos; /* position of next EN char for ET */
|
||||
EMACS_INT ignore_bn_limit; /* position until which to ignore BNs */
|
||||
bidi_dir_t sor; /* direction of start-of-run in effect */
|
||||
int scan_dir; /* direction of text scan */
|
||||
int stack_idx; /* index of current data on the stack */
|
||||
/* Note: Everything from here on is not copied/saved when the bidi
|
||||
iterator state is saved, pushed, or popped. So only put here
|
||||
stuff that is not part of the bidi iterator's state! */
|
||||
struct bidi_stack level_stack[BIDI_MAXLEVEL]; /* stack of embedding levels */
|
||||
int first_elt; /* if non-zero, examine current char first */
|
||||
bidi_dir_t paragraph_dir; /* current paragraph direction */
|
||||
int new_paragraph; /* if non-zero, we expect a new paragraph */
|
||||
EMACS_INT separator_limit; /* where paragraph separator should end */
|
||||
};
|
||||
|
||||
/* Value is non-zero when the bidi iterator is at base paragraph
|
||||
embedding level. */
|
||||
#define BIDI_AT_BASE_LEVEL(BIDI_IT) \
|
||||
((BIDI_IT).resolved_level == (BIDI_IT).level_stack[0].level)
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -1854,7 +1964,7 @@ enum it_method {
|
|||
NUM_IT_METHODS
|
||||
};
|
||||
|
||||
#define IT_STACK_SIZE 4
|
||||
#define IT_STACK_SIZE 5
|
||||
|
||||
/* Iterator for composition (both for static and automatic). */
|
||||
struct composition_it
|
||||
|
@ -1902,6 +2012,14 @@ struct it
|
|||
text, overlay strings, end of text etc., which see. */
|
||||
EMACS_INT stop_charpos;
|
||||
|
||||
/* Previous stop position, i.e. the last one before the current
|
||||
iterator position in `current'. */
|
||||
EMACS_INT prev_stop;
|
||||
|
||||
/* Last stop position iterated across whose bidi embedding level is
|
||||
equal to the current paragraph's base embedding level. */
|
||||
EMACS_INT base_level_stop;
|
||||
|
||||
/* Maximum string or buffer position + 1. ZV when iterating over
|
||||
current_buffer. */
|
||||
EMACS_INT end_charpos;
|
||||
|
@ -2008,6 +2126,8 @@ struct it
|
|||
int string_nchars;
|
||||
EMACS_INT end_charpos;
|
||||
EMACS_INT stop_charpos;
|
||||
EMACS_INT prev_stop;
|
||||
EMACS_INT base_level_stop;
|
||||
struct composition_it cmp_it;
|
||||
int face_id;
|
||||
|
||||
|
@ -2207,6 +2327,14 @@ struct it
|
|||
incremented/reset by display_line, move_it_to etc. */
|
||||
int continuation_lines_width;
|
||||
|
||||
/* Buffer position that ends the buffer text line being iterated.
|
||||
This is normally the position after the newline at EOL. If this
|
||||
is the last line of the buffer and it doesn't have a newline,
|
||||
value is ZV/ZV_BYTE. Set and used only if IT->bidi_p, for
|
||||
setting the end position of glyph rows produced for continuation
|
||||
lines, see display_line. */
|
||||
struct text_pos eol_pos;
|
||||
|
||||
/* Current y-position. Automatically incremented by the height of
|
||||
glyph_row in move_it_to and display_line. */
|
||||
int current_y;
|
||||
|
@ -2233,6 +2361,14 @@ struct it
|
|||
|
||||
/* Face of the right fringe glyph. */
|
||||
unsigned right_user_fringe_face_id : FACE_ID_BITS;
|
||||
|
||||
/* Non-zero means we need to reorder bidirectional text for display
|
||||
in the visual order. */
|
||||
int bidi_p;
|
||||
|
||||
/* For iterating over bidirectional text. */
|
||||
struct bidi_it bidi_it;
|
||||
bidi_dir_t paragraph_embedding;
|
||||
};
|
||||
|
||||
|
||||
|
@ -2263,6 +2399,13 @@ struct it
|
|||
#define PRODUCE_GLYPHS(IT) \
|
||||
do { \
|
||||
extern int inhibit_free_realized_faces; \
|
||||
if ((IT)->glyph_row != NULL && (IT)->bidi_p) \
|
||||
{ \
|
||||
if ((IT)->bidi_it.paragraph_dir == R2L) \
|
||||
(IT)->glyph_row->reversed_p = 1; \
|
||||
else \
|
||||
(IT)->glyph_row->reversed_p = 0; \
|
||||
} \
|
||||
if (FRAME_RIF ((IT)->f) != NULL) \
|
||||
FRAME_RIF ((IT)->f)->produce_glyphs ((IT)); \
|
||||
else \
|
||||
|
@ -2704,12 +2847,20 @@ extern EMACS_INT tool_bar_button_relief;
|
|||
Function Prototypes
|
||||
***********************************************************************/
|
||||
|
||||
/* Defined in bidi.c */
|
||||
|
||||
extern void bidi_init_it P_ ((EMACS_INT, EMACS_INT, struct bidi_it *));
|
||||
extern void bidi_get_next_char_visually P_ ((struct bidi_it *));
|
||||
extern void bidi_paragraph_init P_ ((bidi_dir_t, struct bidi_it *));
|
||||
extern int bidi_mirror_char P_ ((int));
|
||||
|
||||
/* Defined in xdisp.c */
|
||||
|
||||
struct glyph_row *row_containing_pos P_ ((struct window *, int,
|
||||
struct glyph_row *,
|
||||
struct glyph_row *, int));
|
||||
int string_buffer_position P_ ((struct window *, Lisp_Object, int));
|
||||
EMACS_INT string_buffer_position P_ ((struct window *, Lisp_Object,
|
||||
EMACS_INT));
|
||||
int line_bottom_y P_ ((struct it *));
|
||||
int display_prop_intangible_p P_ ((Lisp_Object));
|
||||
void resize_echo_area_exactly P_ ((void));
|
||||
|
|
|
@ -1388,8 +1388,11 @@ prepare_desired_row (row)
|
|||
{
|
||||
if (!row->enabled_p)
|
||||
{
|
||||
unsigned rp = row->reversed_p;
|
||||
|
||||
clear_glyph_row (row);
|
||||
row->enabled_p = 1;
|
||||
row->reversed_p = rp;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1540,6 +1543,7 @@ row_equal_p (w, a, b, mouse_face_p)
|
|||
|| a->overlapped_p != b->overlapped_p
|
||||
|| (MATRIX_ROW_CONTINUATION_LINE_P (a)
|
||||
!= MATRIX_ROW_CONTINUATION_LINE_P (b))
|
||||
|| a->reversed_p != b->reversed_p
|
||||
/* Different partially visible characters on left margin. */
|
||||
|| a->x != b->x
|
||||
/* Different height. */
|
||||
|
@ -3500,6 +3504,8 @@ direct_output_for_insert (g)
|
|||
|| !display_completed
|
||||
/* Give up if buffer appears in two places. */
|
||||
|| buffer_shared > 1
|
||||
/* Give up if we need to reorder bidirectional text. */
|
||||
|| !NILP (current_buffer->bidi_display_reordering)
|
||||
/* Give up if currently displaying a message instead of the
|
||||
minibuffer contents. */
|
||||
|| (EQ (selected_window, minibuf_window)
|
||||
|
@ -3776,6 +3782,10 @@ direct_output_forward_char (n)
|
|||
if (!display_completed || cursor_in_echo_area)
|
||||
return 0;
|
||||
|
||||
/* Give up if we need to reorder bidirectional text. */
|
||||
if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering))
|
||||
return 0;
|
||||
|
||||
/* Give up if the buffer's direction is reversed. */
|
||||
if (!NILP (XBUFFER (w->buffer)->direction_reversed))
|
||||
return 0;
|
||||
|
|
|
@ -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) \
|
||||
|
|
32
src/term.c
32
src/term.c
|
@ -1540,6 +1540,26 @@ append_glyph (it)
|
|||
+ it->glyph_row->used[it->area]);
|
||||
end = it->glyph_row->glyphs[1 + it->area];
|
||||
|
||||
/* If the glyph row is reversed, we need to prepend the glyph rather
|
||||
than append it. */
|
||||
if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
|
||||
{
|
||||
struct glyph *g;
|
||||
int move_by = it->pixel_width;
|
||||
|
||||
/* Make room for the new glyphs. */
|
||||
if (move_by > end - glyph) /* don't overstep end of this area */
|
||||
move_by = end - glyph;
|
||||
for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
|
||||
g[move_by] = *g;
|
||||
glyph = it->glyph_row->glyphs[it->area];
|
||||
end = glyph + move_by;
|
||||
}
|
||||
|
||||
/* BIDI Note: we put the glyphs of a "multi-pixel" character left to
|
||||
right, even in the REVERSED_P case, since (a) all of its u.ch are
|
||||
identical, and (b) the PADDING_P flag needs to be set for the
|
||||
leftmost one, because we write to the terminal left-to-right. */
|
||||
for (i = 0;
|
||||
i < it->pixel_width && glyph < end;
|
||||
++i)
|
||||
|
@ -1551,6 +1571,18 @@ append_glyph (it)
|
|||
glyph->padding_p = i > 0;
|
||||
glyph->charpos = CHARPOS (it->position);
|
||||
glyph->object = it->object;
|
||||
if (it->bidi_p)
|
||||
{
|
||||
glyph->resolved_level = it->bidi_it.resolved_level;
|
||||
if ((it->bidi_it.type & 7) != it->bidi_it.type)
|
||||
abort ();
|
||||
glyph->bidi_type = it->bidi_it.type;
|
||||
}
|
||||
else
|
||||
{
|
||||
glyph->resolved_level = 0;
|
||||
glyph->bidi_type = UNKNOWN_BT;
|
||||
}
|
||||
|
||||
++it->glyph_row->used[it->area];
|
||||
++glyph;
|
||||
|
|
|
@ -117,7 +117,10 @@ struct window
|
|||
/* The buffer displayed in this window */
|
||||
/* Of the fields vchild, hchild and buffer, only one is non-nil. */
|
||||
Lisp_Object buffer;
|
||||
/* A marker pointing to where in the text to start displaying */
|
||||
/* A marker pointing to where in the text to start displaying.
|
||||
BIDI Note: This is the _logical-order_ start, i.e. the smallest
|
||||
buffer position visible in the window, not necessarily the
|
||||
character displayed in the top left corner of the window. */
|
||||
Lisp_Object start;
|
||||
/* A marker pointing to where in the text point is in this window,
|
||||
used only when the window is not selected.
|
||||
|
|
1246
src/xdisp.c
1246
src/xdisp.c
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue