diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/bidi.c | 8 | ||||
| -rw-r--r-- | src/dispextern.h | 23 | ||||
| -rw-r--r-- | src/xdisp.c | 90 |
3 files changed, 107 insertions, 14 deletions
diff --git a/src/bidi.c b/src/bidi.c index d637ee0eeb5..6b51b54da2e 100644 --- a/src/bidi.c +++ b/src/bidi.c | |||
| @@ -23,7 +23,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 23 | as per UAX#9, a part of the Unicode Standard. | 23 | as per UAX#9, a part of the Unicode Standard. |
| 24 | 24 | ||
| 25 | Unlike the reference and most other implementations, this one is | 25 | Unlike the reference and most other implementations, this one is |
| 26 | designed to be called once for every character in the buffer. | 26 | designed to be called once for every character in the buffer or |
| 27 | string. | ||
| 27 | 28 | ||
| 28 | The main entry point is bidi_get_next_char_visually. Each time it | 29 | The main entry point is bidi_get_next_char_visually. Each time it |
| 29 | is called, it finds the next character in the visual order, and | 30 | is called, it finds the next character in the visual order, and |
| @@ -34,6 +35,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 34 | more details about its algorithm that finds the next visual-order | 35 | more details about its algorithm that finds the next visual-order |
| 35 | character by resolving their levels on the fly. | 36 | character by resolving their levels on the fly. |
| 36 | 37 | ||
| 38 | The two other entry points are bidi_paragraph_init and | ||
| 39 | bidi_mirror_char. The first determines the base direction of a | ||
| 40 | paragraph, while the second returns the mirrored version of its | ||
| 41 | argument character. | ||
| 42 | |||
| 37 | If you want to understand the code, you will have to read it | 43 | If you want to understand the code, you will have to read it |
| 38 | together with the relevant portions of UAX#9. The comments include | 44 | together with the relevant portions of UAX#9. The comments include |
| 39 | references to UAX#9 rules, for that very reason. | 45 | references to UAX#9 rules, for that very reason. |
diff --git a/src/dispextern.h b/src/dispextern.h index 00da256c43e..b0a072f71f8 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -2222,13 +2222,22 @@ struct it | |||
| 2222 | MODE_LINE_FACE_ID, etc, depending on what we are displaying. */ | 2222 | MODE_LINE_FACE_ID, etc, depending on what we are displaying. */ |
| 2223 | int base_face_id; | 2223 | int base_face_id; |
| 2224 | 2224 | ||
| 2225 | /* If what == IT_CHARACTER, character and length in bytes. This is | 2225 | /* If `what' == IT_CHARACTER, the character and the length in bytes |
| 2226 | a character from a buffer or string. It may be different from | 2226 | of its multibyte sequence. The character comes from a buffer or |
| 2227 | the character displayed in case that | 2227 | a string. It may be different from the character displayed in |
| 2228 | unibyte_display_via_language_environment is set. | 2228 | case that unibyte_display_via_language_environment is set. |
| 2229 | 2229 | ||
| 2230 | If what == IT_COMPOSITION, the first component of a composition | 2230 | If `what' == IT_COMPOSITION, the first component of a composition |
| 2231 | and length in bytes of the composition. */ | 2231 | and length in bytes of the composition. |
| 2232 | |||
| 2233 | If `what' is anything else, these tow are undefined (will | ||
| 2234 | probably hold values for the last IT_CHARACTER or IT_COMPOSITION | ||
| 2235 | traversed by the iterator. | ||
| 2236 | |||
| 2237 | The values are updated by get_next_display_element, so they are | ||
| 2238 | out of sync with the value returned by IT_CHARPOS between the | ||
| 2239 | time set_iterator_to_next advances the position and the time | ||
| 2240 | get_next_display_element loads the new values into c and len. */ | ||
| 2232 | int c, len; | 2241 | int c, len; |
| 2233 | 2242 | ||
| 2234 | /* If what == IT_COMPOSITION, iterator substructure for the | 2243 | /* If what == IT_COMPOSITION, iterator substructure for the |
diff --git a/src/xdisp.c b/src/xdisp.c index d0bf26e1f00..5a16d07944b 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -80,7 +80,39 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 80 | You will find a lot of redisplay optimizations when you start | 80 | You will find a lot of redisplay optimizations when you start |
| 81 | looking at the innards of redisplay. The overall goal of all these | 81 | looking at the innards of redisplay. The overall goal of all these |
| 82 | optimizations is to make redisplay fast because it is done | 82 | optimizations is to make redisplay fast because it is done |
| 83 | frequently. | 83 | frequently. Some of these optimizations are implemented by the |
| 84 | following functions: | ||
| 85 | |||
| 86 | . try_cursor_movement | ||
| 87 | |||
| 88 | This function tries to update the display if the text in the | ||
| 89 | window did not change and did not scroll, only point moved, and | ||
| 90 | it did not move off the displayed portion of the text. | ||
| 91 | |||
| 92 | . try_window_reusing_current_matrix | ||
| 93 | |||
| 94 | This function reuses the current matrix of a window when text | ||
| 95 | has not changed, but the window start changed (e.g., due to | ||
| 96 | scrolling). | ||
| 97 | |||
| 98 | . try_window_id | ||
| 99 | |||
| 100 | This function attempts to redisplay a window by reusing parts of | ||
| 101 | its existing display. It finds and reuses the part that was not | ||
| 102 | changed, and redraws the rest. | ||
| 103 | |||
| 104 | . try_window | ||
| 105 | |||
| 106 | This function performs the full redisplay of a single window | ||
| 107 | assuming that its fonts were not changed and that the cursor | ||
| 108 | will not end up in the scroll margins. (Loading fonts requires | ||
| 109 | re-adjustment of dimensions of glyph matrices, which makes this | ||
| 110 | method impossible to use.) | ||
| 111 | |||
| 112 | These optimizations are tried in sequence (some can be skipped if | ||
| 113 | it is known that they are not applicable). If none of the | ||
| 114 | optimizations were successful, redisplay calls redisplay_windows, | ||
| 115 | which performs a full redisplay of all windows. | ||
| 84 | 116 | ||
| 85 | Desired matrices. | 117 | Desired matrices. |
| 86 | 118 | ||
| @@ -112,13 +144,16 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 112 | see in dispextern.h. | 144 | see in dispextern.h. |
| 113 | 145 | ||
| 114 | Glyphs in a desired matrix are normally constructed in a loop | 146 | Glyphs in a desired matrix are normally constructed in a loop |
| 115 | calling get_next_display_element and then produce_glyphs. The call | 147 | calling get_next_display_element and then PRODUCE_GLYPHS. The call |
| 116 | to produce_glyphs will fill the iterator structure with pixel | 148 | to PRODUCE_GLYPHS will fill the iterator structure with pixel |
| 117 | information about the element being displayed and at the same time | 149 | information about the element being displayed and at the same time |
| 118 | produce glyphs for it. If the display element fits on the line | 150 | produce glyphs for it. If the display element fits on the line |
| 119 | being displayed, set_iterator_to_next is called next, otherwise the | 151 | being displayed, set_iterator_to_next is called next, otherwise the |
| 120 | glyphs produced are discarded. | 152 | glyphs produced are discarded. The function display_line is the |
| 121 | 153 | workhorse of filling glyph rows in the desired matrix with glyphs. | |
| 154 | In addition to producing glyphs, it also handles line truncation | ||
| 155 | and continuation, word wrap, and cursor positioning (for the | ||
| 156 | latter, see also set_cursor_from_row). | ||
| 122 | 157 | ||
| 123 | Frame matrices. | 158 | Frame matrices. |
| 124 | 159 | ||
| @@ -139,7 +174,50 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 139 | wanted to have without having to move many bytes around. To be | 174 | wanted to have without having to move many bytes around. To be |
| 140 | honest, there is a little bit more done, but not much more. If you | 175 | honest, there is a little bit more done, but not much more. If you |
| 141 | plan to extend that code, take a look at dispnew.c. The function | 176 | plan to extend that code, take a look at dispnew.c. The function |
| 142 | build_frame_matrix is a good starting point. */ | 177 | build_frame_matrix is a good starting point. |
| 178 | |||
| 179 | Bidirectional display. | ||
| 180 | |||
| 181 | Bidirectional display adds quite some hair to this already complex | ||
| 182 | design. The good news are that a large portion of that hairy stuff | ||
| 183 | is hidden in bidi.c behind only 3 interfaces. bidi.c implements a | ||
| 184 | reordering engine which is called by set_iterator_to_next and | ||
| 185 | returns the next character to display in the visual order. See | ||
| 186 | commentary on bidi.c for more details. As far as redisplay is | ||
| 187 | concerned, the effect of calling bidi_get_next_char_visually, the | ||
| 188 | main interface of the reordering engine, is that the iterator gets | ||
| 189 | magically placed on the buffer or string position that is to be | ||
| 190 | displayed next. In other words, a linear iteration through the | ||
| 191 | buffer/string is replaced with a non-linear one. All the rest of | ||
| 192 | the redisplay is oblivious to the bidi reordering. | ||
| 193 | |||
| 194 | Well, almost oblivious---there are still complications, most of | ||
| 195 | them due to the fact that buffer and string positions no longer | ||
| 196 | change monotonously with glyph indices in a glyph row. Moreover, | ||
| 197 | for continued lines, the buffer positions may not even be | ||
| 198 | monotonously changing with vertical positions. Also, accounting | ||
| 199 | for face changes, overlays, etc. becomes more complex because | ||
| 200 | non-linear iteration could potentially skip many positions with | ||
| 201 | changes, and then cross them again on the way back... | ||
| 202 | |||
| 203 | One other prominent effect of bidirectional display is that some | ||
| 204 | paragraphs of text need to be displayed starting at the right | ||
| 205 | margin of the window---the so-called right-to-left, or R2L | ||
| 206 | paragraphs. R2L paragraphs are displayed with R2L glyph rows, | ||
| 207 | which have their reversed_p flag set. The bidi reordering engine | ||
| 208 | produces characters in such rows starting from the character which | ||
| 209 | should be the rightmost on display. PRODUCE_GLYPHS then reverses | ||
| 210 | the order, when it fills up the glyph row whose reversed_p flag is | ||
| 211 | set, by prepending each new glyph to what is already there, instead | ||
| 212 | of appending it. When the glyph row is complete, the function | ||
| 213 | extend_face_to_end_of_line fills the empty space to the left of the | ||
| 214 | leftmost character with special glyphs, which will display as, | ||
| 215 | well, empty. On text terminals, these special glyphs are simply | ||
| 216 | blank characters. On graphics terminals, there's a single stretch | ||
| 217 | glyph with suitably computed width. Both the blanks and the | ||
| 218 | stretch glyph are given the face of the background of the line. | ||
| 219 | This way, the terminal-specific back-end can still draw the glyphs | ||
| 220 | left to right, even for R2L lines. */ | ||
| 143 | 221 | ||
| 144 | #include <config.h> | 222 | #include <config.h> |
| 145 | #include <stdio.h> | 223 | #include <stdio.h> |