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.
This commit is contained in:
commit
0bb2392728
14 changed files with 2093 additions and 668 deletions
|
@ -1,3 +1,9 @@
|
|||
2011-07-14 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* display.texi (Other Display Specs): Document that `left-fringe'
|
||||
and `right-fringe' display specifications are of the "replacing"
|
||||
kind.
|
||||
|
||||
2011-07-14 Lars Magne Ingebrigtsen <larsi@gnus.org>
|
||||
|
||||
* help.texi (Documentation Basics): Add a link to the Function
|
||||
|
|
|
@ -3899,7 +3899,8 @@ Margins}).
|
|||
@itemx (right-fringe @var{bitmap} @r{[}@var{face}@r{]})
|
||||
This display specification on any character of a line of text causes
|
||||
the specified @var{bitmap} be displayed in the left or right fringes
|
||||
for that line. The optional @var{face} specifies the colors to be
|
||||
for that line, instead of the characters that have the display
|
||||
specification. The optional @var{face} specifies the colors to be
|
||||
used for the bitmap. @xref{Fringe Bitmaps}, for the details.
|
||||
|
||||
@item (space-width @var{factor})
|
||||
|
|
6
etc/NEWS
6
etc/NEWS
|
@ -171,7 +171,7 @@ in your ~/.authinfo file instead.
|
|||
*** Emacs now supports display and editing of bidirectional text.
|
||||
|
||||
See the node "Bidirectional Editing" in the Emacs Manual for some
|
||||
initial documentation.
|
||||
additional 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.
|
||||
|
@ -190,10 +190,6 @@ Reordering of bidirectional text for display in Emacs is a "Full
|
|||
bidirectionality" class implementation of the Unicode Bidirectional
|
||||
Algorithm.
|
||||
|
||||
Note that some advanced display features, such as overlay strings and
|
||||
`display' text properties, do not yet work correctly when
|
||||
bidirectional text is reordered for display.
|
||||
|
||||
+++
|
||||
*** Enhanced support for characters that have no glyphs in available fonts.
|
||||
If a character has no glyphs in any of the available fonts, Emacs by
|
||||
|
|
35
etc/TODO
35
etc/TODO
|
@ -639,6 +639,37 @@ up on top of all others
|
|||
|
||||
**** Undo for color-drag face customization.
|
||||
|
||||
** Bidirectional editing
|
||||
|
||||
*** Allow the user to control the direction of the UI
|
||||
|
||||
**** Introduce user option to control direction of mode line.
|
||||
This requires to figure out what to do with unibyte strings that are
|
||||
used in constructing the mode line. Currently, unibyte strings are
|
||||
not reordered by bidi.c, without which R2L mode line will not display
|
||||
correctly. One possibility would be to STRING_SET_MULTIBYTE all Lisp
|
||||
strings involved in the mode line, and then pass them through bidi.c.
|
||||
|
||||
Another problem is the header line, which is produced by the same
|
||||
routines as the mode line. While it makes sense to have the mode-line
|
||||
direction controlled by a single global variable, header lines are
|
||||
buffer-specific, so they need a separate treatment in this regard.
|
||||
|
||||
**** User options to control direction of menu bar and tool bar.
|
||||
For the tool bar, it's relatively easy: set it.paragraph_embedding
|
||||
in redisplay_tool_bar according to the user variable, and make
|
||||
f->desired_tool_bar_string multibyte with STRING_SET_MULTIBYTE. Some
|
||||
minor changes will be needed to set the right_box_line_p and
|
||||
left_box_line_p flags correctly for the R2L tool bar.
|
||||
|
||||
However, it makes no sense to display the tool bar right to left if
|
||||
the menu bar cannot be displayed in the same direction.
|
||||
|
||||
R2L menu bar is tricky for the same reasons as the mode line. In
|
||||
addition, toolkit builds create their menu bars in toolkit-specific
|
||||
parts of code, bypassing xdisp.c, so those parts need to be enhanced
|
||||
with toolkit-specific code to display the menu bar right to left.
|
||||
|
||||
** ImageMagick support
|
||||
|
||||
*** image-type-header-regexps priorities the jpeg loader over the
|
||||
|
@ -663,8 +694,8 @@ view, page-flipping becomes uselessly slow.
|
|||
|
||||
*** Integrate with image-dired.
|
||||
|
||||
*** Integrate with docview.
|
||||
|
||||
*** Integrate with docview.
|
||||
|
||||
*** Integrate with image-mode.
|
||||
Some work has been done, e.g. M-x image-transform-fit-to-height will
|
||||
fit the image to the height of the Emacs window.
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
2011-07-14 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* 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.
|
||||
|
||||
2011-07-14 Lars Magne Ingebrigtsen <larsi@gnus.org>
|
||||
|
||||
* image.el (put-image): Mention the `put-image' overlay property
|
||||
|
|
|
@ -266,7 +266,10 @@ Letters do not insert themselves; instead, they are commands.
|
|||
(set (make-local-variable 'buffer-stale-function)
|
||||
(lambda (&optional _noconfirm) 'fast))
|
||||
(setq truncate-lines t)
|
||||
(setq buffer-read-only t))
|
||||
(setq buffer-read-only t)
|
||||
;; Force L2R direction, to avoid messing the display if the first
|
||||
;; buffer in the list happens to begin with a strong R2L character.
|
||||
(setq bidi-paragraph-direction 'left-to-right))
|
||||
|
||||
(define-obsolete-variable-alias 'buffer-menu-mode-hook
|
||||
'Buffer-menu-mode-hook "23.1")
|
||||
|
@ -663,7 +666,7 @@ For more information, see the function `buffer-menu'."
|
|||
":" ;; (if (char-displayable-p ?…) "…" ":")
|
||||
)
|
||||
|
||||
(defun Buffer-menu-buffer+size (name size &optional name-props size-props)
|
||||
(defun Buffer-menu-buffer+size (name size &optional name-props size-props lrm)
|
||||
(if (> (+ (string-width name) (string-width size) 2)
|
||||
Buffer-menu-buffer+size-width)
|
||||
(setq name
|
||||
|
@ -678,9 +681,17 @@ For more information, see the function `buffer-menu'."
|
|||
(string-width tail)
|
||||
2))
|
||||
Buffer-menu-short-ellipsis
|
||||
tail)))
|
||||
tail
|
||||
;; Append an invisible LRM character to the
|
||||
;; buffer's name to avoid ugly display with the
|
||||
;; buffer size to the left of the name, when the
|
||||
;; name begins with R2L character.
|
||||
(if lrm (propertize (string ?\x200e) 'invisible t) ""))))
|
||||
;; Don't put properties on (buffer-name).
|
||||
(setq name (copy-sequence name)))
|
||||
(setq name (concat (copy-sequence name)
|
||||
(if lrm
|
||||
(propertize (string ?\x200e) 'invisible t)
|
||||
""))))
|
||||
(add-text-properties 0 (length name) name-props name)
|
||||
(add-text-properties 0 (length size) size-props size)
|
||||
(let ((name+space-width (- Buffer-menu-buffer+size-width
|
||||
|
@ -813,6 +824,10 @@ For more information, see the function `buffer-menu'."
|
|||
(setq buffer-read-only nil)
|
||||
(erase-buffer)
|
||||
(setq standard-output (current-buffer))
|
||||
;; Force L2R direction, to avoid messing the display if the
|
||||
;; first buffer in the list happens to begin with a strong R2L
|
||||
;; character.
|
||||
(setq bidi-paragraph-direction 'left-to-right)
|
||||
(unless Buffer-menu-use-header-line
|
||||
;; Use U+2014 (EM DASH) to underline if possible, else use ASCII
|
||||
;; (i.e. U+002D, HYPHEN-MINUS).
|
||||
|
@ -914,7 +929,8 @@ For more information, see the function `buffer-menu'."
|
|||
(max (length size) 3)
|
||||
2))
|
||||
name
|
||||
"mouse-2: select this buffer"))))
|
||||
"mouse-2: select this buffer"))
|
||||
nil t))
|
||||
" "
|
||||
(if (> (string-width (nth 4 buffer)) Buffer-menu-mode-width)
|
||||
(truncate-string-to-width (nth 4 buffer)
|
||||
|
|
16
src/.gdbinit
16
src/.gdbinit
|
@ -677,7 +677,7 @@ end
|
|||
|
||||
define xvectype
|
||||
xgetptr $
|
||||
set $size = ((struct Lisp_Vector *) $ptr)->size
|
||||
set $size = ((struct Lisp_Vector *) $ptr)->header.size
|
||||
output ($size & PVEC_FLAG) ? (enum pvec_type) ($size & PVEC_TYPE_MASK) : $size & ~gdb_array_mark_flag
|
||||
echo \n
|
||||
end
|
||||
|
@ -818,7 +818,7 @@ end
|
|||
define xvector
|
||||
xgetptr $
|
||||
print (struct Lisp_Vector *) $ptr
|
||||
output ($->size > 50) ? 0 : ($->contents[0])@($->size & ~gdb_array_mark_flag)
|
||||
output ($->header.size > 50) ? 0 : ($->contents[0])@($->header.size & ~gdb_array_mark_flag)
|
||||
echo \n
|
||||
end
|
||||
document xvector
|
||||
|
@ -853,7 +853,7 @@ end
|
|||
define xcompiled
|
||||
xgetptr $
|
||||
print (struct Lisp_Vector *) $ptr
|
||||
output ($->contents[0])@($->size & 0xff)
|
||||
output ($->contents[0])@($->header.size & 0xff)
|
||||
end
|
||||
document xcompiled
|
||||
Print $ as a compiled function pointer.
|
||||
|
@ -903,7 +903,7 @@ define xchartable
|
|||
print (struct Lisp_Char_Table *) $ptr
|
||||
printf "Purpose: "
|
||||
xprintsym $->purpose
|
||||
printf " %d extra slots", ($->size & 0x1ff) - 68
|
||||
printf " %d extra slots", ($->header.size & 0x1ff) - 68
|
||||
echo \n
|
||||
end
|
||||
document xchartable
|
||||
|
@ -927,7 +927,7 @@ end
|
|||
define xboolvector
|
||||
xgetptr $
|
||||
print (struct Lisp_Bool_Vector *) $ptr
|
||||
output ($->size > 256) ? 0 : ($->data[0])@((($->size & ~gdb_array_mark_flag) + 7)/ 8)
|
||||
output ($->header.size > 256) ? 0 : ($->data[0])@((($->header.size & ~gdb_array_mark_flag) + 7)/ 8)
|
||||
echo \n
|
||||
end
|
||||
document xboolvector
|
||||
|
@ -1093,7 +1093,7 @@ define xpr
|
|||
# end
|
||||
end
|
||||
if $type == Lisp_Vectorlike
|
||||
set $size = ((struct Lisp_Vector *) $ptr)->size
|
||||
set $size = ((struct Lisp_Vector *) $ptr)->header.size
|
||||
if ($size & PVEC_FLAG)
|
||||
set $vec = (enum pvec_type) ($size & PVEC_TYPE_MASK)
|
||||
if $vec == PVEC_NORMAL_VECTOR
|
||||
|
@ -1202,7 +1202,7 @@ end
|
|||
|
||||
define xfont
|
||||
xgetptr $
|
||||
set $size = (((struct Lisp_Vector *) $ptr)->size & 0x1FF)
|
||||
set $size = (((struct Lisp_Vector *) $ptr)->header.size & 0x1FF)
|
||||
if $size == FONT_SPEC_MAX
|
||||
print (struct font_spec *) $ptr
|
||||
else
|
||||
|
@ -1229,7 +1229,7 @@ define xbacktrace
|
|||
printf "0x%x ", $ptr
|
||||
if $type == Lisp_Vectorlike
|
||||
xgetptr (*$bt->function)
|
||||
set $size = ((struct Lisp_Vector *) $ptr)->size
|
||||
set $size = ((struct Lisp_Vector *) $ptr)->header.size
|
||||
output ($size & PVEC_FLAG) ? (enum pvec_type) ($size & PVEC_TYPE_MASK) : $size & ~gdb_array_mark_flag
|
||||
else
|
||||
printf "Lisp type %d", $type
|
||||
|
|
206
src/ChangeLog
206
src/ChangeLog
|
@ -1,3 +1,209 @@
|
|||
2011-07-14 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
Support bidi reordering of display and overlay strings.
|
||||
* 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.
|
||||
|
||||
* 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.
|
||||
|
||||
* 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.
|
||||
|
||||
* .gdbinit (xvectype, xvector, xcompiled, xchartable, xboolvector)
|
||||
(xpr, xfont, xbacktrace): Use "header.size" when accessing vectors
|
||||
and vector-like objects.
|
||||
|
||||
* dispnew.c (buffer_posn_from_coords): Save and restore the bidi
|
||||
cache around display iteration.
|
||||
|
||||
* window.c (Fwindow_end, window_scroll_pixel_based)
|
||||
(displayed_window_lines, Frecenter): Save and restore the bidi
|
||||
cache around display iteration.
|
||||
|
||||
2011-07-14 Lars Magne Ingebrigtsen <larsi@gnus.org>
|
||||
|
||||
* editfns.c (Fdelete_region): Clarify the use of the named
|
||||
|
|
1106
src/bidi.c
1106
src/bidi.c
File diff suppressed because it is too large
Load diff
|
@ -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
|
||||
|
||||
|
|
|
@ -5275,10 +5275,12 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p
|
|||
struct image *img = 0;
|
||||
#endif
|
||||
int x0, x1, to_x;
|
||||
void *itdata = NULL;
|
||||
|
||||
/* We used to set current_buffer directly here, but that does the
|
||||
wrong thing with `face-remapping-alist' (bug#2044). */
|
||||
Fset_buffer (w->buffer);
|
||||
itdata = bidi_shelve_cache ();
|
||||
SET_TEXT_POS_FROM_MARKER (startp, w->start);
|
||||
CHARPOS (startp) = min (ZV, max (BEGV, CHARPOS (startp)));
|
||||
BYTEPOS (startp) = min (ZV_BYTE, max (BEGV_BYTE, BYTEPOS (startp)));
|
||||
|
@ -5312,6 +5314,7 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p
|
|||
argument is ZV to prevent move_it_in_display_line from matching
|
||||
based on buffer positions. */
|
||||
move_it_in_display_line (&it, ZV, to_x, MOVE_TO_X);
|
||||
bidi_unshelve_cache (itdata);
|
||||
|
||||
Fset_buffer (old_current_buffer);
|
||||
|
||||
|
|
|
@ -1989,6 +1989,7 @@ whether or not it is currently displayed in some window. */)
|
|||
struct gcpro gcpro1, gcpro2, gcpro3;
|
||||
Lisp_Object lcols = Qnil;
|
||||
double cols IF_LINT (= 0);
|
||||
void *itdata = NULL;
|
||||
|
||||
/* Allow LINES to be of the form (HPOS . VPOS) aka (COLUMNS . LINES). */
|
||||
if (CONSP (lines) && (NUMBERP (XCAR (lines))))
|
||||
|
@ -2029,6 +2030,7 @@ whether or not it is currently displayed in some window. */)
|
|||
EMACS_INT it_start;
|
||||
int first_x, it_overshoot_expected IF_LINT (= 0);
|
||||
|
||||
itdata = bidi_shelve_cache ();
|
||||
SET_TEXT_POS (pt, PT, PT_BYTE);
|
||||
start_display (&it, w, pt);
|
||||
first_x = it.first_visible_x;
|
||||
|
@ -2133,6 +2135,7 @@ whether or not it is currently displayed in some window. */)
|
|||
}
|
||||
|
||||
SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
|
||||
bidi_unshelve_cache (itdata);
|
||||
}
|
||||
|
||||
if (BUFFERP (old_buffer))
|
||||
|
|
45
src/window.c
45
src/window.c
|
@ -1351,6 +1351,7 @@ if it isn't already recorded. */)
|
|||
struct text_pos startp;
|
||||
struct it it;
|
||||
struct buffer *old_buffer = NULL;
|
||||
void *itdata = NULL;
|
||||
|
||||
/* Cannot use Fvertical_motion because that function doesn't
|
||||
cope with variable-height lines. */
|
||||
|
@ -1372,11 +1373,13 @@ if it isn't already recorded. */)
|
|||
else
|
||||
SET_TEXT_POS_FROM_MARKER (startp, w->start);
|
||||
|
||||
itdata = bidi_shelve_cache ();
|
||||
start_display (&it, w, startp);
|
||||
move_it_vertically (&it, window_box_height (w));
|
||||
if (it.current_y < it.last_visible_y)
|
||||
move_it_past_eol (&it);
|
||||
value = make_number (IT_CHARPOS (it));
|
||||
bidi_unshelve_cache (itdata);
|
||||
|
||||
if (old_buffer)
|
||||
set_buffer_internal (old_buffer);
|
||||
|
@ -4238,6 +4241,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
|
|||
/* True if we fiddled the window vscroll field without really scrolling. */
|
||||
int vscrolled = 0;
|
||||
int x, y, rtop, rbot, rowh, vpos;
|
||||
void *itdata = NULL;
|
||||
|
||||
SET_TEXT_POS_FROM_MARKER (start, w->start);
|
||||
|
||||
|
@ -4248,6 +4252,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
|
|||
|
||||
if (!pos_visible_p (w, PT, &x, &y, &rtop, &rbot, &rowh, &vpos))
|
||||
{
|
||||
itdata = bidi_shelve_cache ();
|
||||
/* Move backward half the height of the window. Performance note:
|
||||
vmotion used here is about 10% faster, but would give wrong
|
||||
results for variable height lines. */
|
||||
|
@ -4268,6 +4273,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
|
|||
}
|
||||
|
||||
start = it.current.pos;
|
||||
bidi_unshelve_cache (itdata);
|
||||
}
|
||||
else if (auto_window_vscroll_p)
|
||||
{
|
||||
|
@ -4330,6 +4336,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
|
|||
Fset_window_vscroll (window, make_number (0), Qt);
|
||||
}
|
||||
|
||||
itdata = bidi_shelve_cache ();
|
||||
/* If scroll_preserve_screen_position is non-nil, we try to set
|
||||
point in the same window line as it is now, so get that line. */
|
||||
if (!NILP (Vscroll_preserve_screen_position))
|
||||
|
@ -4408,12 +4415,16 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
|
|||
- it.current_y + it.max_ascent + it.max_descent);
|
||||
adjust_glyphs (it.f);
|
||||
}
|
||||
else if (noerror)
|
||||
return;
|
||||
else if (n < 0) /* could happen with empty buffers */
|
||||
xsignal0 (Qbeginning_of_buffer);
|
||||
else
|
||||
xsignal0 (Qend_of_buffer);
|
||||
{
|
||||
bidi_unshelve_cache (itdata);
|
||||
if (noerror)
|
||||
return;
|
||||
else if (n < 0) /* could happen with empty buffers */
|
||||
xsignal0 (Qbeginning_of_buffer);
|
||||
else
|
||||
xsignal0 (Qend_of_buffer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4421,10 +4432,14 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
|
|||
/* The first line was only partially visible, make it fully
|
||||
visible. */
|
||||
w->vscroll = 0;
|
||||
else if (noerror)
|
||||
return;
|
||||
else
|
||||
xsignal0 (Qbeginning_of_buffer);
|
||||
{
|
||||
bidi_unshelve_cache (itdata);
|
||||
if (noerror)
|
||||
return;
|
||||
else
|
||||
xsignal0 (Qbeginning_of_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
/* If control gets here, then we vscrolled. */
|
||||
|
@ -4568,6 +4583,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
|
|||
SET_PT_BOTH (charpos, bytepos);
|
||||
}
|
||||
}
|
||||
bidi_unshelve_cache (itdata);
|
||||
}
|
||||
|
||||
|
||||
|
@ -4970,6 +4986,7 @@ displayed_window_lines (struct window *w)
|
|||
int height = window_box_height (w);
|
||||
struct buffer *old_buffer;
|
||||
int bottom_y;
|
||||
void *itdata = NULL;
|
||||
|
||||
if (XBUFFER (w->buffer) != current_buffer)
|
||||
{
|
||||
|
@ -4989,9 +5006,11 @@ displayed_window_lines (struct window *w)
|
|||
else
|
||||
SET_TEXT_POS_FROM_MARKER (start, w->start);
|
||||
|
||||
itdata = bidi_shelve_cache ();
|
||||
start_display (&it, w, start);
|
||||
move_it_vertically (&it, height);
|
||||
bottom_y = line_bottom_y (&it);
|
||||
bidi_unshelve_cache (itdata);
|
||||
|
||||
/* rms: On a non-window display,
|
||||
the value of it.vpos at the bottom of the screen
|
||||
|
@ -5090,12 +5109,14 @@ and redisplay normally--don't erase and redraw the frame. */)
|
|||
{
|
||||
struct it it;
|
||||
struct text_pos pt;
|
||||
void *itdata = bidi_shelve_cache ();
|
||||
|
||||
SET_TEXT_POS (pt, PT, PT_BYTE);
|
||||
start_display (&it, w, pt);
|
||||
move_it_vertically_backward (&it, window_box_height (w) / 2);
|
||||
charpos = IT_CHARPOS (it);
|
||||
bytepos = IT_BYTEPOS (it);
|
||||
bidi_unshelve_cache (itdata);
|
||||
}
|
||||
else if (iarg < 0)
|
||||
{
|
||||
|
@ -5104,6 +5125,7 @@ and redisplay normally--don't erase and redraw the frame. */)
|
|||
int nlines = -iarg;
|
||||
int extra_line_spacing;
|
||||
int h = window_box_height (w);
|
||||
void *itdata = bidi_shelve_cache ();
|
||||
|
||||
iarg = - max (-iarg, this_scroll_margin);
|
||||
|
||||
|
@ -5141,7 +5163,10 @@ and redisplay normally--don't erase and redraw the frame. */)
|
|||
h -= nlines * (FRAME_LINE_HEIGHT (it.f) + extra_line_spacing);
|
||||
}
|
||||
if (h <= 0)
|
||||
return Qnil;
|
||||
{
|
||||
bidi_unshelve_cache (itdata);
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
/* Now find the new top line (starting position) of the window. */
|
||||
start_display (&it, w, pt);
|
||||
|
@ -5161,6 +5186,8 @@ and redisplay normally--don't erase and redraw the frame. */)
|
|||
|
||||
charpos = IT_CHARPOS (it);
|
||||
bytepos = IT_BYTEPOS (it);
|
||||
|
||||
bidi_unshelve_cache (itdata);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
1252
src/xdisp.c
1252
src/xdisp.c
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue