diff options
| author | Eli Zaretskii | 2019-08-17 11:02:52 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2019-08-17 11:02:52 +0300 |
| commit | 3a04be20056f19c5ffbf448128ccce067d11e99e (patch) | |
| tree | a99eaf87d89cf77253b342a52166f64f654d8d81 /src | |
| parent | 15de1d11334fd7da3255881e0836a22d08760482 (diff) | |
| download | emacs-3a04be20056f19c5ffbf448128ccce067d11e99e.tar.gz emacs-3a04be20056f19c5ffbf448128ccce067d11e99e.zip | |
; Improve commentary in xdisp.c
* src/xdisp.c: Add to the commentary the description of
stop_charpos, and how it is used during iteration.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xdisp.c | 97 |
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/>. */ | |||
| 152 | description of the environment in which the text is to be | 152 | description of the environment in which the text is to be |
| 153 | displayed. But this is too early, read on. | 153 | displayed. But this is too early, read on. |
| 154 | 154 | ||
| 155 | Iteration over buffer and strings. | ||
| 156 | |||
| 155 | Characters and pixmaps displayed for a range of buffer text depend | 157 | Characters and pixmaps displayed for a range of buffer text depend |
| 156 | on various settings of buffers and windows, on overlays and text | 158 | on various settings of buffers and windows, on overlays and text |
| 157 | properties, on display tables, on selective display. The good news | 159 | 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/>. */ | |||
| 176 | current X and Y position, and lots of other stuff you can better | 178 | current X and Y position, and lots of other stuff you can better |
| 177 | see in dispextern.h. | 179 | see in dispextern.h. |
| 178 | 180 | ||
| 181 | The "stop position". | ||
| 182 | |||
| 183 | Some of the fields maintained by the iterator change relatively | ||
| 184 | infrequently. These include the face of the characters, whether | ||
| 185 | text is invisible, the object (buffer or display or overlay string) | ||
| 186 | being iterated, character composition info, etc. For any given | ||
| 187 | buffer or string position, these sources of information that | ||
| 188 | affects the display can be determined by calling the appropriate | ||
| 189 | primitives, such as Fnext_single_property_change, but both these | ||
| 190 | calls and the processing of their return values is relatively | ||
| 191 | expensive. To optimize redisplay, the display engine checks these | ||
| 192 | sources of display information only when needed. To that end, it | ||
| 193 | always maintains the position of the next place where it must stop | ||
| 194 | and re-examine all those potential sources. This is called "stop | ||
| 195 | position" and is stored in the stop_charpos field of the iterator. | ||
| 196 | The stop position is updated by compute_stop_pos, which is called | ||
| 197 | whenever the iteration reaches the current stop position and | ||
| 198 | processes it. Processing a stop position is done by handle_stop, | ||
| 199 | which invokes a series of handlers, one each for every potential | ||
| 200 | source of display-related information; see the it_props array for | ||
| 201 | those handlers. For example, one handler is handle_face_prop, | ||
| 202 | which detects changes in face properties, and supplies the face ID | ||
| 203 | that the iterator will use for all the glyphs it generates up to | ||
| 204 | the next stop position; this face ID is the result of realizing the | ||
| 205 | face specified by the relevant text properties at this position. | ||
| 206 | Each handler called by handle_stop processes the sources of display | ||
| 207 | information for which it is "responsible", and returns a value | ||
| 208 | which tells handle_stop what to do next. | ||
| 209 | |||
| 210 | Once handle_stop returns, the information it stores in the iterator | ||
| 211 | fields will not be refreshed until the iteration reaches the next | ||
| 212 | stop position, which is computed by compute_stop_pos called at the | ||
| 213 | end of handle_stop. compute_stop_pos examines the buffer's or | ||
| 214 | string's interval tree to determine where the text properties | ||
| 215 | change, finds the next position where overlays and character | ||
| 216 | composition can change, and stores in stop_charpos the closest | ||
| 217 | position where any of these factors should be reconsider. | ||
| 218 | |||
| 219 | Producing glyphs. | ||
| 220 | |||
| 179 | Glyphs in a desired matrix are normally constructed in a loop | 221 | Glyphs in a desired matrix are normally constructed in a loop |
| 180 | calling get_next_display_element and then PRODUCE_GLYPHS. The call | 222 | calling get_next_display_element and then PRODUCE_GLYPHS. The call |
| 181 | to PRODUCE_GLYPHS will fill the iterator structure with pixel | 223 | 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/>. */ | |||
| 191 | Frame matrices. | 233 | Frame matrices. |
| 192 | 234 | ||
| 193 | That just couldn't be all, could it? What about terminal types not | 235 | That just couldn't be all, could it? What about terminal types not |
| 194 | supporting operations on sub-windows of the screen? To update the | 236 | supporting operations on sub-windows of the screen (a.k.a. "TTY" or |
| 195 | display on such a terminal, window-based glyph matrices are not | 237 | "text-mode terminal")? To update the display on such a terminal, |
| 196 | well suited. To be able to reuse part of the display (scrolling | 238 | window-based glyph matrices are not well suited. To be able to |
| 197 | lines up and down), we must instead have a view of the whole | 239 | reuse part of the display (scrolling lines up and down), we must |
| 198 | screen. This is what `frame matrices' are for. They are a trick. | 240 | instead have a view of the whole screen. This is what `frame |
| 199 | 241 | matrices' are for. They are a trick. | |
| 200 | Frames on terminals like above have a glyph pool. Windows on such | 242 | |
| 201 | a frame sub-allocate their glyph memory from their frame's glyph | 243 | Frames on text terminals have a glyph pool. Windows on such a |
| 244 | frame sub-allocate their glyph memory from their frame's glyph | ||
| 202 | pool. The frame itself is given its own glyph matrices. By | 245 | pool. The frame itself is given its own glyph matrices. By |
| 203 | coincidence---or maybe something else---rows in window glyph | 246 | coincidence---or maybe something else---rows in window glyph |
| 204 | matrices are slices of corresponding rows in frame matrices. Thus | 247 | matrices are slices of corresponding rows in frame matrices. Thus |
| 205 | writing to window matrices implicitly updates a frame matrix which | 248 | writing to window matrices implicitly updates a frame matrix which |
| 206 | provides us with the view of the whole screen that we originally | 249 | provides us with the view of the whole screen that we originally |
| 207 | wanted to have without having to move many bytes around. To be | 250 | wanted to have without having to move many bytes around. Then |
| 208 | honest, there is a little bit more done, but not much more. If you | 251 | updating all the visible windows on text-terminal frames is done by |
| 209 | plan to extend that code, take a look at dispnew.c. The function | 252 | using the frame matrices, which allows frame-global optimization of |
| 210 | build_frame_matrix is a good starting point. | 253 | what is actually written to the glass. |
| 254 | |||
| 255 | To be honest, there is a little bit more done, but not much more. | ||
| 256 | If you plan to extend that code, take a look at dispnew.c. The | ||
| 257 | function build_frame_matrix is a good starting point. | ||
| 211 | 258 | ||
| 212 | Bidirectional display. | 259 | Bidirectional display. |
| 213 | 260 | ||
| @@ -220,9 +267,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 220 | concerned, the effect of calling bidi_move_to_visually_next, the | 267 | concerned, the effect of calling bidi_move_to_visually_next, the |
| 221 | main interface of the reordering engine, is that the iterator gets | 268 | main interface of the reordering engine, is that the iterator gets |
| 222 | magically placed on the buffer or string position that is to be | 269 | magically placed on the buffer or string position that is to be |
| 223 | displayed next. In other words, a linear iteration through the | 270 | displayed next in the visual order. In other words, a linear |
| 224 | buffer/string is replaced with a non-linear one. All the rest of | 271 | iteration through the buffer/string is replaced with a non-linear |
| 225 | the redisplay is oblivious to the bidi reordering. | 272 | one. All the rest of the redisplay is oblivious to the bidi |
| 273 | reordering. | ||
| 226 | 274 | ||
| 227 | Well, almost oblivious---there are still complications, most of | 275 | Well, almost oblivious---there are still complications, most of |
| 228 | them due to the fact that buffer and string positions no longer | 276 | 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/>. */ | |||
| 231 | monotonously changing with vertical positions. Also, accounting | 279 | monotonously changing with vertical positions. Also, accounting |
| 232 | for face changes, overlays, etc. becomes more complex because | 280 | for face changes, overlays, etc. becomes more complex because |
| 233 | non-linear iteration could potentially skip many positions with | 281 | non-linear iteration could potentially skip many positions with |
| 234 | changes, and then cross them again on the way back... | 282 | changes, and then cross them again on the way back (see |
| 283 | handle_stop_backwards)... | ||
| 235 | 284 | ||
| 236 | One other prominent effect of bidirectional display is that some | 285 | One other prominent effect of bidirectional display is that some |
| 237 | paragraphs of text need to be displayed starting at the right | 286 | 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/>. */ | |||
| 252 | This way, the terminal-specific back-end can still draw the glyphs | 301 | This way, the terminal-specific back-end can still draw the glyphs |
| 253 | left to right, even for R2L lines. | 302 | left to right, even for R2L lines. |
| 254 | 303 | ||
| 255 | Bidirectional display and character compositions | 304 | Bidirectional display and character compositions. |
| 256 | 305 | ||
| 257 | Some scripts cannot be displayed by drawing each character | 306 | Some scripts cannot be displayed by drawing each character |
| 258 | individually, because adjacent characters change each other's shape | 307 | 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/>. */ | |||
| 272 | Each of these grapheme clusters is then delivered to PRODUCE_GLYPHS | 321 | Each of these grapheme clusters is then delivered to PRODUCE_GLYPHS |
| 273 | in the direction corresponding to the current bidi scan direction | 322 | in the direction corresponding to the current bidi scan direction |
| 274 | (recorded in the scan_dir member of the `struct bidi_it' object | 323 | (recorded in the scan_dir member of the `struct bidi_it' object |
| 275 | that is part of the buffer iterator). In particular, if the bidi | 324 | that is part of the iterator). In particular, if the bidi iterator |
| 276 | iterator currently scans the buffer backwards, the grapheme | 325 | currently scans the buffer backwards, the grapheme clusters are |
| 277 | clusters are delivered back to front. This reorders the grapheme | 326 | delivered back to front. This reorders the grapheme clusters as |
| 278 | clusters as appropriate for the current bidi context. Note that | 327 | appropriate for the current bidi context. Note that this means |
| 279 | this means that the grapheme clusters are always stored in the | 328 | that the grapheme clusters are always stored in the LGSTRING object |
| 280 | LGSTRING object (see composite.c) in the logical order. | 329 | (see composite.c) in the logical order. |
| 281 | 330 | ||
| 282 | Moving an iterator in bidirectional text | 331 | Moving an iterator in bidirectional text |
| 283 | without producing glyphs | 332 | without producing glyphs. |
| 284 | 333 | ||
| 285 | Note one important detail mentioned above: that the bidi reordering | 334 | Note one important detail mentioned above: that the bidi reordering |
| 286 | engine, driven by the iterator, produces characters in R2L rows | 335 | engine, driven by the iterator, produces characters in R2L rows |