summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2019-08-17 11:02:52 +0300
committerEli Zaretskii <eliz@gnu.org>2019-08-17 11:02:52 +0300
commit3a04be20056f19c5ffbf448128ccce067d11e99e (patch)
treea99eaf87d89cf77253b342a52166f64f654d8d81
parent15de1d11334fd7da3255881e0836a22d08760482 (diff)
downloademacs-3a04be20056f19c5ffbf448128ccce067d11e99e.tar.gz
; Improve commentary in xdisp.c
* src/xdisp.c: Add to the commentary the description of stop_charpos, and how it is used during iteration.
-rw-r--r--src/xdisp.c97
1 files changed, 73 insertions, 24 deletions
diff --git a/src/xdisp.c b/src/xdisp.c
index aa6e1bd2df8..3b8cfab0592 100644
--- a/src/xdisp.c
+++ b/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
displayed. But this is too early, read on.
+ Iteration over buffer and strings.
+
Characters and pixmaps displayed for a range of buffer text depend
on various settings of buffers and windows, on overlays and text
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
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
calling get_next_display_element and then PRODUCE_GLYPHS. The call
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.
That just couldn't be all, could it? What about terminal types not
- supporting operations on sub-windows of the screen? To update the
- display on such a terminal, window-based glyph matrices are not
- well suited. To be able to reuse part of the display (scrolling
- lines up and down), we must 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
- a frame sub-allocate their glyph memory from their frame's glyph
+ supporting operations on sub-windows of the screen (a.k.a. "TTY" or
+ "text-mode terminal")? To update the display on such a terminal,
+ window-based glyph matrices are not well suited. To be able to
+ reuse part of the display (scrolling lines up and down), we must
+ instead have a view of the whole screen. This is what `frame
+ matrices' are for. They are a trick.
+
+ Frames on text terminals have a glyph pool. Windows on such a
+ frame sub-allocate their glyph memory from their frame's glyph
pool. The frame itself is given its own glyph matrices. By
coincidence---or maybe something else---rows in window glyph
matrices are slices of corresponding rows in frame matrices. Thus
writing to window matrices implicitly updates a frame matrix which
provides us with the view of the whole screen that we originally
- wanted to have without having to move many bytes around. 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.
+ wanted to have without having to move many bytes around. Then
+ updating all the visible windows on text-terminal frames is done by
+ using the frame matrices, which allows frame-global optimization of
+ 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.
@@ -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
main interface of the reordering engine, is that the iterator gets
magically placed on the buffer or string position that is to be
- displayed next. In other words, a linear iteration through the
- buffer/string is replaced with a non-linear one. All the rest of
- the redisplay is oblivious to the bidi reordering.
+ displayed next in the visual order. In other words, a linear
+ iteration through the buffer/string is replaced with a non-linear
+ one. All the rest of the redisplay is oblivious to the bidi
+ reordering.
Well, almost oblivious---there are still complications, most of
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
for face changes, overlays, etc. becomes more complex because
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
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
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
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
in the direction corresponding to the current bidi scan direction
(recorded in the scan_dir member of the `struct bidi_it' object
- that is part of the buffer iterator). In particular, if the bidi
- iterator currently scans the buffer backwards, the grapheme
- clusters are delivered back to front. This reorders the grapheme
- clusters as appropriate for the current bidi context. Note that
- this means that the grapheme clusters are always stored in the
- LGSTRING object (see composite.c) in the logical order.
+ that is part of the iterator). In particular, if the bidi iterator
+ currently scans the buffer backwards, the grapheme clusters are
+ delivered back to front. This reorders the grapheme clusters as
+ appropriate for the current bidi context. Note that this means
+ that the grapheme clusters are always stored in the LGSTRING object
+ (see composite.c) in the logical order.
Moving an iterator in bidirectional text
- without producing glyphs
+ without producing glyphs.
Note one important detail mentioned above: that the bidi reordering
engine, driven by the iterator, produces characters in R2L rows