diff options
author | Eli Zaretskii <eliz@gnu.org> | 2011-07-14 20:28:42 +0300 |
---|---|---|
committer | Eli Zaretskii <eliz@gnu.org> | 2011-07-14 20:28:42 +0300 |
commit | 0bb2392728c10748f3376f8cef6d9ca53e29f464 (patch) | |
tree | 9fec522054a4e27aea4acfd098aa7d3f05dd0e2c /src/dispextern.h | |
parent | 6a57fb5f2ba5f040a39fcf4d04ca37619aa754bd (diff) | |
parent | c965adc5e0e9f30a3caeac4b5fa2023f89347b2e (diff) | |
download | emacs-0bb2392728c10748f3376f8cef6d9ca53e29f464.tar.gz |
Support bidi reordering of overlay and display strings.
Fix bugs #7616, #8133, #8867.
src/xdisp.c (compute_display_string_pos)
(compute_display_string_end): Accept additional argument STRING.
(init_iterator, reseat_1): Initialize bidi_it->string.s to NULL.
(reseat_to_string): Initialize bidi_it->string.s and
bidi_it->string.schars.
(Fcurrent_bidi_paragraph_direction): Initialize itb.string.s to
NULL (avoids a crash in bidi_paragraph_init). Initialize
itb.string.lstring.
(init_iterator): Call bidi_init_it only of a valid
buffer position was specified. Initialize paragraph_embedding to
L2R.
(reseat_to_string): Initialize the bidi iterator.
(display_string): If we need to ignore text properties of
LISP_STRING, set IT->stop_charpos to IT->end_charpos. (The
original value of -1 will not work with bidi.)
(compute_display_string_pos): First arg is now struct
`text_pos *'; all callers changed. Support display properties on
Lisp strings.
(compute_display_string_end): Support display properties on Lisp
strings.
(init_iterator, reseat_1, reseat_to_string): Initialize the
string.bufpos member to 0 (zero, for compatibility with IT_CHARPOS
when iterating on a string not from display properties).
(compute_display_string_pos, compute_display_string_end): Fix
calculation of the object to scan. Fixes an error when using
arrow keys.
(next_element_from_buffer): Don't abort when IT_CHARPOS is before
base_level_stop; instead, set base_level_stop to BEGV. Fixes
crashes in vertical-motion.
(next_element_from_buffer): Improve commentary for when
the iterator is before prev_stop.
(init_iterator): Initialize bidi_p from the default value of
bidi-display-reordering, not from buffer-local value. Use the
buffer-local value only if initializing for buffer iteration.
(handle_invisible_prop): Support invisible properties on strings
that are being bidi-reordered.
(set_iterator_to_next): Support bidi reordering of C strings and
Lisp strings.
(next_element_from_string): Support bidi reordering of Lisp
strings.
(handle_stop_backwards): Support Lisp strings as well.
(display_string): Support display of R2L glyph rows. Use
IT_STRING_CHARPOS when displaying from a Lisp string.
(init_iterator): Don't initialize it->bidi_p for strings
here.
(reseat_to_string): Initialize it->bidi_p for strings here.
(next_element_from_string, next_element_from_c_string)
(next_element_from_buffer): Add xassert's for correspondence
between IT's object being iterated and it->bidi_it.string
structure.
(face_before_or_after_it_pos): Support bidi iteration.
(next_element_from_c_string): Handle the case of the first string
character that is not the first one in the visual order.
(get_visually_first_element): New function, refactored from common
parts of next_element_from_buffer, next_element_from_string, and
next_element_from_c_string.
(tool_bar_lines_needed, redisplay_tool_bar)
(display_menu_bar): Force left-to-right direction. Add a FIXME
comment for making that be controlled by a user option.
(push_it, pop_it): Save and restore the state of the
bidi iterator. Save and restore the bidi_p flag.
(pop_it): Iterate out of display property for string iteration as
well.
(iterate_out_of_display_property): Support iteration over strings.
(handle_single_display_spec): Set up it->bidi_it for iteration
over a display string, and call bidi_init_it.
(handle_single_display_spec, next_overlay_string)
(get_overlay_strings_1, push_display_prop): Set up the bidi
iterator for displaying display or overlay strings.
(forward_to_next_line_start): Don't use the shortcut if
bidi-iterating.
(back_to_previous_visible_line_start): If handle_display_prop
pushed the iterator stack, restore the internal state of the bidi
iterator by calling bidi_pop_it same number of times.
(reseat_at_next_visible_line_start): If ON_NEWLINE_P is non-zero,
and we are bidi-iterating, don't decrement the iterator position;
instead, set the first_elt flag in the bidi iterator, to produce
the same effect.
(reseat_1): Remove redundant setting of string_from_display_prop_p.
(push_display_prop): xassert that we are iterating a buffer.
(push_it, pop_it): Save and restore paragraph_embedding member.
(handle_single_display_spec, next_overlay_string)
(get_overlay_strings_1, reseat_1, reseat_to_string)
(push_display_prop): Set up the `unibyte' member of bidi_it.string
correctly. Don't assume unibyte strings are not bidi-reordered.
(compute_display_string_pos)
(compute_display_string_end): Fix handling the case of C string.
(push_it, pop_it): Save and restore from_disp_prop_p.
(handle_single_display_spec, push_display_prop): Set the
from_disp_prop_p flag.
(get_overlay_strings_1): Reset the from_disp_prop_p flag.
(pop_it): Call iterate_out_of_display_property only if we are
popping after iteration over a string that came from a display
property. Fix a typo in popping stretch info. Add an assertion
for verifying that the iterator position is in sync with the bidi
iterator.
(handle_single_display_spec, get_overlay_strings_1)
(push_display_prop): Fix initialization of paragraph direction for
string when that of the parent object is not yet determined.
(reseat_1): Call bidi_init_it to resync the bidi
iterator with IT's position. (Bug#7616)
(find_row_edges): If ROW->start.pos gives position
smaller than min_pos, use it as ROW->minpos. (Bug#7616)
(handle_stop, back_to_previous_visible_line_start, reseat_1):
Reset the from_disp_prop_p flag.
(SAVE_IT, RESTORE_IT): New macros.
(pos_visible_p, face_before_or_after_it_pos)
(back_to_previous_visible_line_start)
(move_it_in_display_line_to, move_it_in_display_line)
(move_it_to, move_it_vertically_backward, move_it_by_lines)
(try_scrolling, redisplay_window, display_line): Use them when
saving a temporary copy of the iterator and restoring it back.
(back_to_previous_visible_line_start, reseat_1)
(init_iterator): Empty the bidi cache "stack".
(move_it_in_display_line_to): If iterator ended up at
EOL, but we never saw any buffer positions smaller than
to_charpos, return MOVE_POS_MATCH_OR_ZV. Fixes vertical cursor
motion in bidi-reordered lines.
(move_it_in_display_line_to): Record prev_method and prev_pos
immediately before the call to set_iterator_to_next. Fixes cursor
motion in bidi-reordered lines with stretch glyphs and strings
displayed in margins. (Bug#8133) (Bug#8867)
Return MOVE_POS_MATCH_OR_ZV only if iterator position is past
TO_CHARPOS.
(pos_visible_p): Support positions in bidi-reordered lines. Save
and restore bidi cache.
src/bidi.c (bidi_level_of_next_char): clen should be EMACS_NT, not int.
(bidi_paragraph_info): Delete unused struct.
(bidi_cache_idx, bidi_cache_last_idx): Declare EMACS_INT.
(bidi_cache_start): New variable.
(bidi_cache_reset): Reset bidi_cache_idx to bidi_cache_start, not
to zero.
(bidi_cache_fetch_state, bidi_cache_search)
(bidi_cache_find_level_change, bidi_cache_iterator_state)
(bidi_cache_find, bidi_peek_at_next_level)
(bidi_level_of_next_char, bidi_find_other_level_edge)
(bidi_move_to_visually_next): Compare cache index with
bidi_cache_start rather than with zero.
(bidi_fetch_char): Accept new argument STRING; all callers
changed. Support iteration over a string. Support strings with
display properties. Support unibyte strings. Fix the type of
`len' according to what STRING_CHAR_AND_LENGTH expects.
(bidi_paragraph_init, bidi_resolve_explicit_1)
(bidi_resolve_explicit, bidi_resolve_weak)
(bidi_level_of_next_char, bidi_move_to_visually_next): Support
iteration over a string.
(bidi_set_sor_type, bidi_resolve_explicit_1)
(bidi_resolve_explicit, bidi_type_of_next_char): ignore_bn_limit
can now be zero (for strings); special values 0 and -1 were
changed to -1 and -2, respectively.
(bidi_char_at_pos): New function.
(bidi_paragraph_init, bidi_resolve_explicit, bidi_resolve_weak):
Call it instead of FETCH_MULTIBYTE_CHAR.
(bidi_move_to_visually_next): Abort if charpos or bytepos were not
initialized to valid values.
(bidi_init_it): Don't initialize charpos and bytepos with invalid
values.
(bidi_level_of_next_char): Allow the sentinel "position" to pass
the test for valid cached positions. Fix the logic for looking up
the sentinel state in the cache. GCPRO the Lisp string we are
iterating.
(bidi_push_it, bidi_pop_it): New functions.
(bidi_initialize): Initialize the bidi cache start stack pointer.
(bidi_cache_ensure_space): New function, refactored from part of
bidi_cache_iterator_state. Don't assume the required size is just
one BIDI_CACHE_CHUNK away.
(bidi_cache_start_stack, bidi_push_it): Use IT_STACK_SIZE.
(bidi_count_bytes, bidi_char_at_pos): New functions.
(bidi_cache_search): Don't assume bidi_cache_last_idx is
always valid if bidi_cache_idx is valid.
(bidi_cache_find_level_change): xassert that bidi_cache_last_idx
is valid if it's going to be used.
(bidi_shelve_cache, bidi_unshelve_cache): New functions.
(bidi_cache_fetch_state, bidi_cache_search)
(bidi_cache_find_level_change, bidi_cache_ensure_space)
(bidi_cache_iterator_state, bidi_cache_find)
(bidi_find_other_level_edge, bidi_cache_start_stack): All
variables related to cache indices are now EMACS_INT.
src/dispextern.h (struct bidi_string_data): New structure.
(struct bidi_it): New member `string'. Make flag members be 1-bit
fields, and put them last in the struct.
(compute_display_string_pos, compute_display_string_end): Update
prototypes.
(bidi_push_it, bidi_pop_it): Add prototypes.
(struct iterator_stack_entry): New members bidi_p,
paragraph_embedding, and from_disp_prop_p.
(struct it): Member bidi_p is now a bit field 1 bit wide.
(bidi_shelve_cache, bidi_unshelve_cache): Declare
prototypes.
src/.gdbinit (xvectype, xvector, xcompiled, xchartable, xboolvector)
(xpr, xfont, xbacktrace): Use "header.size" when accessing vectors
and vector-like objects.
src/dispnew.c (buffer_posn_from_coords): Save and restore the bidi
cache around display iteration.
src/window.c (Fwindow_end, window_scroll_pixel_based)
(displayed_window_lines, Frecenter): Save and restore the bidi
cache around display iteration.
lisp/buff-menu.el (Buffer-menu-buffer+size): Accept an additional
argument LRM; if non-nil, append an invisible LRM character to the
buffer name.
(list-buffers-noselect): Call Buffer-menu-buffer+size with the
last argument non-nil, when formatting buffer names.
(Buffer-menu-mode, list-buffers-noselect): Force left-to-right
paragraph direction.
doc/lispref/display.texi (Other Display Specs): Document that `left-fringe'
and `right-fringe' display specifications are of the "replacing"
kind.
Diffstat (limited to 'src/dispextern.h')
-rw-r--r-- | src/dispextern.h | 44 |
1 files changed, 36 insertions, 8 deletions
diff --git a/src/dispextern.h b/src/dispextern.h index c0a67690a5c..dc44c698164 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -1820,9 +1820,21 @@ struct bidi_stack { bidi_dir_t override; }; +/* Data type for storing information about a string being iterated on. */ +struct bidi_string_data { + Lisp_Object lstring; /* Lisp string to reorder, or nil */ + const unsigned char *s; /* string data, or NULL if reordering buffer */ + EMACS_INT schars; /* the number of characters in the string, + excluding the terminating null */ + EMACS_INT bufpos; /* buffer position of lstring, or 0 if N/A */ + unsigned from_disp_str : 1; /* 1 means the string comes from a + display property */ + unsigned unibyte : 1; /* 1 means the string is unibyte */ +}; + /* Data type for reordering bidirectional text. */ struct bidi_it { - EMACS_INT bytepos; /* iterator's position in buffer */ + EMACS_INT bytepos; /* iterator's position in buffer/string */ EMACS_INT charpos; int ch; /* character at that position, or u+FFFC ("object replacement character") for a run @@ -1852,12 +1864,13 @@ struct bidi_it { 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 */ + struct bidi_string_data string; /* string to reorder */ bidi_dir_t paragraph_dir; /* current paragraph direction */ - int new_paragraph; /* if non-zero, we expect a new paragraph */ - int frame_window_p; /* non-zero if displaying on a GUI frame */ EMACS_INT separator_limit; /* where paragraph separator should end */ EMACS_INT disp_pos; /* position of display string after ch */ + unsigned first_elt : 1; /* if non-zero, examine current char first */ + unsigned new_paragraph : 1; /* if non-zero, we expect a new paragraph */ + unsigned frame_window_p : 1; /* non-zero if displaying on a GUI frame */ }; /* Value is non-zero when the bidi iterator is at base paragraph @@ -2134,6 +2147,10 @@ struct it Don't handle some `display' properties in these strings. */ unsigned string_from_display_prop_p : 1; + /* 1 means we are iterating an object that came from a value of a + `display' property. */ + unsigned from_disp_prop_p : 1; + /* When METHOD == next_element_from_display_vector, this is 1 if we're doing an ellipsis. Otherwise meaningless. */ unsigned ellipsis_p : 1; @@ -2153,7 +2170,9 @@ struct it Lisp_Object *dpvec, *dpend; /* Length in bytes of the char that filled dpvec. A value of zero - means that no such character is involved. */ + means that no such character is involved. A negative value means + the rest of the line from the current iterator position onwards + is hidden by selective display or ellipsis. */ int dpvec_char_len; /* Face id to use for all characters in display vector. -1 if unused. */ @@ -2245,10 +2264,13 @@ struct it Lisp_Object from_overlay; enum glyph_row_area area; enum it_method method; + bidi_dir_t paragraph_embedding; unsigned multibyte_p : 1; unsigned string_from_display_prop_p : 1; unsigned display_ellipsis_p : 1; unsigned avoid_cursor_p : 1; + unsigned bidi_p:1; + unsigned from_disp_prop_p : 1; enum line_wrap_method line_wrap; /* properties from display property that are reset by another display property. */ @@ -2469,7 +2491,7 @@ struct it /* Non-zero means we need to reorder bidirectional text for display in the visual order. */ - int bidi_p; + unsigned bidi_p : 1; /* For iterating over bidirectional text. */ struct bidi_it bidi_it; @@ -2951,6 +2973,10 @@ extern void bidi_init_it (EMACS_INT, EMACS_INT, int, struct bidi_it *); extern void bidi_move_to_visually_next (struct bidi_it *); extern void bidi_paragraph_init (bidi_dir_t, struct bidi_it *, int); extern int bidi_mirror_char (int); +extern void bidi_push_it (struct bidi_it *); +extern void bidi_pop_it (struct bidi_it *); +extern void *bidi_shelve_cache (void); +extern void bidi_unshelve_cache (void *); /* Defined in xdisp.c */ @@ -3008,8 +3034,10 @@ extern void reseat_at_previous_visible_line_start (struct it *); extern Lisp_Object lookup_glyphless_char_display (int, struct it *); extern int calc_pixel_width_or_height (double *, struct it *, Lisp_Object, struct font *, int, int *); -extern EMACS_INT compute_display_string_pos (EMACS_INT, int); -extern EMACS_INT compute_display_string_end (EMACS_INT); +extern EMACS_INT compute_display_string_pos (struct text_pos *, + struct bidi_string_data *, int); +extern EMACS_INT compute_display_string_end (EMACS_INT, + struct bidi_string_data *); #ifdef HAVE_WINDOW_SYSTEM |