; Improve commentary in xdisp.c
* src/xdisp.c: Add to the commentary the description of stop_charpos, and how it is used during iteration.
This commit is contained in:
parent
15de1d1133
commit
3a04be2005
1 changed files with 72 additions and 23 deletions
95
src/xdisp.c
95
src/xdisp.c
|
@ -152,6 +152,8 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
description of the environment in which the text is to be
|
description of the environment in which the text is to be
|
||||||
displayed. But this is too early, read on.
|
displayed. But this is too early, read on.
|
||||||
|
|
||||||
|
Iteration over buffer and strings.
|
||||||
|
|
||||||
Characters and pixmaps displayed for a range of buffer text depend
|
Characters and pixmaps displayed for a range of buffer text depend
|
||||||
on various settings of buffers and windows, on overlays and text
|
on various settings of buffers and windows, on overlays and text
|
||||||
properties, on display tables, on selective display. The good news
|
properties, on display tables, on selective display. The good news
|
||||||
|
@ -176,6 +178,46 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
current X and Y position, and lots of other stuff you can better
|
current X and Y position, and lots of other stuff you can better
|
||||||
see in dispextern.h.
|
see in dispextern.h.
|
||||||
|
|
||||||
|
The "stop position".
|
||||||
|
|
||||||
|
Some of the fields maintained by the iterator change relatively
|
||||||
|
infrequently. These include the face of the characters, whether
|
||||||
|
text is invisible, the object (buffer or display or overlay string)
|
||||||
|
being iterated, character composition info, etc. For any given
|
||||||
|
buffer or string position, these sources of information that
|
||||||
|
affects the display can be determined by calling the appropriate
|
||||||
|
primitives, such as Fnext_single_property_change, but both these
|
||||||
|
calls and the processing of their return values is relatively
|
||||||
|
expensive. To optimize redisplay, the display engine checks these
|
||||||
|
sources of display information only when needed. To that end, it
|
||||||
|
always maintains the position of the next place where it must stop
|
||||||
|
and re-examine all those potential sources. This is called "stop
|
||||||
|
position" and is stored in the stop_charpos field of the iterator.
|
||||||
|
The stop position is updated by compute_stop_pos, which is called
|
||||||
|
whenever the iteration reaches the current stop position and
|
||||||
|
processes it. Processing a stop position is done by handle_stop,
|
||||||
|
which invokes a series of handlers, one each for every potential
|
||||||
|
source of display-related information; see the it_props array for
|
||||||
|
those handlers. For example, one handler is handle_face_prop,
|
||||||
|
which detects changes in face properties, and supplies the face ID
|
||||||
|
that the iterator will use for all the glyphs it generates up to
|
||||||
|
the next stop position; this face ID is the result of realizing the
|
||||||
|
face specified by the relevant text properties at this position.
|
||||||
|
Each handler called by handle_stop processes the sources of display
|
||||||
|
information for which it is "responsible", and returns a value
|
||||||
|
which tells handle_stop what to do next.
|
||||||
|
|
||||||
|
Once handle_stop returns, the information it stores in the iterator
|
||||||
|
fields will not be refreshed until the iteration reaches the next
|
||||||
|
stop position, which is computed by compute_stop_pos called at the
|
||||||
|
end of handle_stop. compute_stop_pos examines the buffer's or
|
||||||
|
string's interval tree to determine where the text properties
|
||||||
|
change, finds the next position where overlays and character
|
||||||
|
composition can change, and stores in stop_charpos the closest
|
||||||
|
position where any of these factors should be reconsider.
|
||||||
|
|
||||||
|
Producing glyphs.
|
||||||
|
|
||||||
Glyphs in a desired matrix are normally constructed in a loop
|
Glyphs in a desired matrix are normally constructed in a loop
|
||||||
calling get_next_display_element and then PRODUCE_GLYPHS. The call
|
calling get_next_display_element and then PRODUCE_GLYPHS. The call
|
||||||
to PRODUCE_GLYPHS will fill the iterator structure with pixel
|
to PRODUCE_GLYPHS will fill the iterator structure with pixel
|
||||||
|
@ -191,23 +233,28 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
Frame matrices.
|
Frame matrices.
|
||||||
|
|
||||||
That just couldn't be all, could it? What about terminal types not
|
That just couldn't be all, could it? What about terminal types not
|
||||||
supporting operations on sub-windows of the screen? To update the
|
supporting operations on sub-windows of the screen (a.k.a. "TTY" or
|
||||||
display on such a terminal, window-based glyph matrices are not
|
"text-mode terminal")? To update the display on such a terminal,
|
||||||
well suited. To be able to reuse part of the display (scrolling
|
window-based glyph matrices are not well suited. To be able to
|
||||||
lines up and down), we must instead have a view of the whole
|
reuse part of the display (scrolling lines up and down), we must
|
||||||
screen. This is what `frame matrices' are for. They are a trick.
|
instead have a view of the whole screen. This is what `frame
|
||||||
|
matrices' are for. They are a trick.
|
||||||
|
|
||||||
Frames on terminals like above have a glyph pool. Windows on such
|
Frames on text terminals have a glyph pool. Windows on such a
|
||||||
a frame sub-allocate their glyph memory from their frame's glyph
|
frame sub-allocate their glyph memory from their frame's glyph
|
||||||
pool. The frame itself is given its own glyph matrices. By
|
pool. The frame itself is given its own glyph matrices. By
|
||||||
coincidence---or maybe something else---rows in window glyph
|
coincidence---or maybe something else---rows in window glyph
|
||||||
matrices are slices of corresponding rows in frame matrices. Thus
|
matrices are slices of corresponding rows in frame matrices. Thus
|
||||||
writing to window matrices implicitly updates a frame matrix which
|
writing to window matrices implicitly updates a frame matrix which
|
||||||
provides us with the view of the whole screen that we originally
|
provides us with the view of the whole screen that we originally
|
||||||
wanted to have without having to move many bytes around. To be
|
wanted to have without having to move many bytes around. Then
|
||||||
honest, there is a little bit more done, but not much more. If you
|
updating all the visible windows on text-terminal frames is done by
|
||||||
plan to extend that code, take a look at dispnew.c. The function
|
using the frame matrices, which allows frame-global optimization of
|
||||||
build_frame_matrix is a good starting point.
|
what is actually written to the glass.
|
||||||
|
|
||||||
|
To be honest, there is a little bit more done, but not much more.
|
||||||
|
If you plan to extend that code, take a look at dispnew.c. The
|
||||||
|
function build_frame_matrix is a good starting point.
|
||||||
|
|
||||||
Bidirectional display.
|
Bidirectional display.
|
||||||
|
|
||||||
|
@ -220,9 +267,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
concerned, the effect of calling bidi_move_to_visually_next, the
|
concerned, the effect of calling bidi_move_to_visually_next, the
|
||||||
main interface of the reordering engine, is that the iterator gets
|
main interface of the reordering engine, is that the iterator gets
|
||||||
magically placed on the buffer or string position that is to be
|
magically placed on the buffer or string position that is to be
|
||||||
displayed next. In other words, a linear iteration through the
|
displayed next in the visual order. In other words, a linear
|
||||||
buffer/string is replaced with a non-linear one. All the rest of
|
iteration through the buffer/string is replaced with a non-linear
|
||||||
the redisplay is oblivious to the bidi reordering.
|
one. All the rest of the redisplay is oblivious to the bidi
|
||||||
|
reordering.
|
||||||
|
|
||||||
Well, almost oblivious---there are still complications, most of
|
Well, almost oblivious---there are still complications, most of
|
||||||
them due to the fact that buffer and string positions no longer
|
them due to the fact that buffer and string positions no longer
|
||||||
|
@ -231,7 +279,8 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
monotonously changing with vertical positions. Also, accounting
|
monotonously changing with vertical positions. Also, accounting
|
||||||
for face changes, overlays, etc. becomes more complex because
|
for face changes, overlays, etc. becomes more complex because
|
||||||
non-linear iteration could potentially skip many positions with
|
non-linear iteration could potentially skip many positions with
|
||||||
changes, and then cross them again on the way back...
|
changes, and then cross them again on the way back (see
|
||||||
|
handle_stop_backwards)...
|
||||||
|
|
||||||
One other prominent effect of bidirectional display is that some
|
One other prominent effect of bidirectional display is that some
|
||||||
paragraphs of text need to be displayed starting at the right
|
paragraphs of text need to be displayed starting at the right
|
||||||
|
@ -252,7 +301,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
This way, the terminal-specific back-end can still draw the glyphs
|
This way, the terminal-specific back-end can still draw the glyphs
|
||||||
left to right, even for R2L lines.
|
left to right, even for R2L lines.
|
||||||
|
|
||||||
Bidirectional display and character compositions
|
Bidirectional display and character compositions.
|
||||||
|
|
||||||
Some scripts cannot be displayed by drawing each character
|
Some scripts cannot be displayed by drawing each character
|
||||||
individually, because adjacent characters change each other's shape
|
individually, because adjacent characters change each other's shape
|
||||||
|
@ -272,15 +321,15 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
Each of these grapheme clusters is then delivered to PRODUCE_GLYPHS
|
Each of these grapheme clusters is then delivered to PRODUCE_GLYPHS
|
||||||
in the direction corresponding to the current bidi scan direction
|
in the direction corresponding to the current bidi scan direction
|
||||||
(recorded in the scan_dir member of the `struct bidi_it' object
|
(recorded in the scan_dir member of the `struct bidi_it' object
|
||||||
that is part of the buffer iterator). In particular, if the bidi
|
that is part of the iterator). In particular, if the bidi iterator
|
||||||
iterator currently scans the buffer backwards, the grapheme
|
currently scans the buffer backwards, the grapheme clusters are
|
||||||
clusters are delivered back to front. This reorders the grapheme
|
delivered back to front. This reorders the grapheme clusters as
|
||||||
clusters as appropriate for the current bidi context. Note that
|
appropriate for the current bidi context. Note that this means
|
||||||
this means that the grapheme clusters are always stored in the
|
that the grapheme clusters are always stored in the LGSTRING object
|
||||||
LGSTRING object (see composite.c) in the logical order.
|
(see composite.c) in the logical order.
|
||||||
|
|
||||||
Moving an iterator in bidirectional text
|
Moving an iterator in bidirectional text
|
||||||
without producing glyphs
|
without producing glyphs.
|
||||||
|
|
||||||
Note one important detail mentioned above: that the bidi reordering
|
Note one important detail mentioned above: that the bidi reordering
|
||||||
engine, driven by the iterator, produces characters in R2L rows
|
engine, driven by the iterator, produces characters in R2L rows
|
||||||
|
|
Loading…
Add table
Reference in a new issue