Merge from origin/emacs-25
[emacs.git] / src / xdisp.c
blobdc68cd48e5fec7729f39b58ab094fdea9c7b50de
1 /* Display generation from window structure and buffer text.
3 Copyright (C) 1985-1988, 1993-1995, 1997-2016 Free Software Foundation,
4 Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or (at
11 your option) any later version.
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
23 Redisplay.
25 Emacs separates the task of updating the display from code
26 modifying global state, e.g. buffer text. This way functions
27 operating on buffers don't also have to be concerned with updating
28 the display.
30 Updating the display is triggered by the Lisp interpreter when it
31 decides it's time to do it. This is done either automatically for
32 you as part of the interpreter's command loop or as the result of
33 calling Lisp functions like `sit-for'. The C function `redisplay'
34 in xdisp.c is the only entry into the inner redisplay code.
36 The following diagram shows how redisplay code is invoked. As you
37 can see, Lisp calls redisplay and vice versa. Under window systems
38 like X, some portions of the redisplay code are also called
39 asynchronously during mouse movement or expose events. It is very
40 important that these code parts do NOT use the C library (malloc,
41 free) because many C libraries under Unix are not reentrant. They
42 may also NOT call functions of the Lisp interpreter which could
43 change the interpreter's state. If you don't follow these rules,
44 you will encounter bugs which are very hard to explain.
46 +--------------+ redisplay +----------------+
47 | Lisp machine |---------------->| Redisplay code |<--+
48 +--------------+ (xdisp.c) +----------------+ |
49 ^ | |
50 +----------------------------------+ |
51 Don't use this path when called |
52 asynchronously! |
54 expose_window (asynchronous) |
56 X expose events -----+
58 What does redisplay do? Obviously, it has to figure out somehow what
59 has been changed since the last time the display has been updated,
60 and to make these changes visible. Preferably it would do that in
61 a moderately intelligent way, i.e. fast.
63 Changes in buffer text can be deduced from window and buffer
64 structures, and from some global variables like `beg_unchanged' and
65 `end_unchanged'. The contents of the display are additionally
66 recorded in a `glyph matrix', a two-dimensional matrix of glyph
67 structures. Each row in such a matrix corresponds to a line on the
68 display, and each glyph in a row corresponds to a column displaying
69 a character, an image, or what else. This matrix is called the
70 `current glyph matrix' or `current matrix' in redisplay
71 terminology.
73 For buffer parts that have been changed since the last update, a
74 second glyph matrix is constructed, the so called `desired glyph
75 matrix' or short `desired matrix'. Current and desired matrix are
76 then compared to find a cheap way to update the display, e.g. by
77 reusing part of the display by scrolling lines.
79 You will find a lot of redisplay optimizations when you start
80 looking at the innards of redisplay. The overall goal of all these
81 optimizations is to make redisplay fast because it is done
82 frequently. Some of these optimizations are implemented by the
83 following functions:
85 . try_cursor_movement
87 This function tries to update the display if the text in the
88 window did not change and did not scroll, only point moved, and
89 it did not move off the displayed portion of the text.
91 . try_window_reusing_current_matrix
93 This function reuses the current matrix of a window when text
94 has not changed, but the window start changed (e.g., due to
95 scrolling).
97 . try_window_id
99 This function attempts to redisplay a window by reusing parts of
100 its existing display. It finds and reuses the part that was not
101 changed, and redraws the rest. (The "id" part in the function's
102 name stands for "insert/delete", not for "identification" or
103 somesuch.)
105 . try_window
107 This function performs the full redisplay of a single window
108 assuming that its fonts were not changed and that the cursor
109 will not end up in the scroll margins. (Loading fonts requires
110 re-adjustment of dimensions of glyph matrices, which makes this
111 method impossible to use.)
113 These optimizations are tried in sequence (some can be skipped if
114 it is known that they are not applicable). If none of the
115 optimizations were successful, redisplay calls redisplay_windows,
116 which performs a full redisplay of all windows.
118 Note that there's one more important optimization up Emacs's
119 sleeve, but it is related to actually redrawing the potentially
120 changed portions of the window/frame, not to reproducing the
121 desired matrices of those potentially changed portions. Namely,
122 the function update_frame and its subroutines, which you will find
123 in dispnew.c, compare the desired matrices with the current
124 matrices, and only redraw the portions that changed. So it could
125 happen that the functions in this file for some reason decide that
126 the entire desired matrix needs to be regenerated from scratch, and
127 still only parts of the Emacs display, or even nothing at all, will
128 be actually delivered to the glass, because update_frame has found
129 that the new and the old screen contents are similar or identical.
131 Desired matrices.
133 Desired matrices are always built per Emacs window. The function
134 `display_line' is the central function to look at if you are
135 interested. It constructs one row in a desired matrix given an
136 iterator structure containing both a buffer position and a
137 description of the environment in which the text is to be
138 displayed. But this is too early, read on.
140 Characters and pixmaps displayed for a range of buffer text depend
141 on various settings of buffers and windows, on overlays and text
142 properties, on display tables, on selective display. The good news
143 is that all this hairy stuff is hidden behind a small set of
144 interface functions taking an iterator structure (struct it)
145 argument.
147 Iteration over things to be displayed is then simple. It is
148 started by initializing an iterator with a call to init_iterator,
149 passing it the buffer position where to start iteration. For
150 iteration over strings, pass -1 as the position to init_iterator,
151 and call reseat_to_string when the string is ready, to initialize
152 the iterator for that string. Thereafter, calls to
153 get_next_display_element fill the iterator structure with relevant
154 information about the next thing to display. Calls to
155 set_iterator_to_next move the iterator to the next thing.
157 Besides this, an iterator also contains information about the
158 display environment in which glyphs for display elements are to be
159 produced. It has fields for the width and height of the display,
160 the information whether long lines are truncated or continued, a
161 current X and Y position, and lots of other stuff you can better
162 see in dispextern.h.
164 Glyphs in a desired matrix are normally constructed in a loop
165 calling get_next_display_element and then PRODUCE_GLYPHS. The call
166 to PRODUCE_GLYPHS will fill the iterator structure with pixel
167 information about the element being displayed and at the same time
168 produce glyphs for it. If the display element fits on the line
169 being displayed, set_iterator_to_next is called next, otherwise the
170 glyphs produced are discarded. The function display_line is the
171 workhorse of filling glyph rows in the desired matrix with glyphs.
172 In addition to producing glyphs, it also handles line truncation
173 and continuation, word wrap, and cursor positioning (for the
174 latter, see also set_cursor_from_row).
176 Frame matrices.
178 That just couldn't be all, could it? What about terminal types not
179 supporting operations on sub-windows of the screen? To update the
180 display on such a terminal, window-based glyph matrices are not
181 well suited. To be able to reuse part of the display (scrolling
182 lines up and down), we must instead have a view of the whole
183 screen. This is what `frame matrices' are for. They are a trick.
185 Frames on terminals like above have a glyph pool. Windows on such
186 a frame sub-allocate their glyph memory from their frame's glyph
187 pool. The frame itself is given its own glyph matrices. By
188 coincidence---or maybe something else---rows in window glyph
189 matrices are slices of corresponding rows in frame matrices. Thus
190 writing to window matrices implicitly updates a frame matrix which
191 provides us with the view of the whole screen that we originally
192 wanted to have without having to move many bytes around. To be
193 honest, there is a little bit more done, but not much more. If you
194 plan to extend that code, take a look at dispnew.c. The function
195 build_frame_matrix is a good starting point.
197 Bidirectional display.
199 Bidirectional display adds quite some hair to this already complex
200 design. The good news are that a large portion of that hairy stuff
201 is hidden in bidi.c behind only 3 interfaces. bidi.c implements a
202 reordering engine which is called by set_iterator_to_next and
203 returns the next character to display in the visual order. See
204 commentary on bidi.c for more details. As far as redisplay is
205 concerned, the effect of calling bidi_move_to_visually_next, the
206 main interface of the reordering engine, is that the iterator gets
207 magically placed on the buffer or string position that is to be
208 displayed next. In other words, a linear iteration through the
209 buffer/string is replaced with a non-linear one. All the rest of
210 the redisplay is oblivious to the bidi reordering.
212 Well, almost oblivious---there are still complications, most of
213 them due to the fact that buffer and string positions no longer
214 change monotonously with glyph indices in a glyph row. Moreover,
215 for continued lines, the buffer positions may not even be
216 monotonously changing with vertical positions. Also, accounting
217 for face changes, overlays, etc. becomes more complex because
218 non-linear iteration could potentially skip many positions with
219 changes, and then cross them again on the way back...
221 One other prominent effect of bidirectional display is that some
222 paragraphs of text need to be displayed starting at the right
223 margin of the window---the so-called right-to-left, or R2L
224 paragraphs. R2L paragraphs are displayed with R2L glyph rows,
225 which have their reversed_p flag set. The bidi reordering engine
226 produces characters in such rows starting from the character which
227 should be the rightmost on display. PRODUCE_GLYPHS then reverses
228 the order, when it fills up the glyph row whose reversed_p flag is
229 set, by prepending each new glyph to what is already there, instead
230 of appending it. When the glyph row is complete, the function
231 extend_face_to_end_of_line fills the empty space to the left of the
232 leftmost character with special glyphs, which will display as,
233 well, empty. On text terminals, these special glyphs are simply
234 blank characters. On graphics terminals, there's a single stretch
235 glyph of a suitably computed width. Both the blanks and the
236 stretch glyph are given the face of the background of the line.
237 This way, the terminal-specific back-end can still draw the glyphs
238 left to right, even for R2L lines.
240 Bidirectional display and character compositions
242 Some scripts cannot be displayed by drawing each character
243 individually, because adjacent characters change each other's shape
244 on display. For example, Arabic and Indic scripts belong to this
245 category.
247 Emacs display supports this by providing "character compositions",
248 most of which is implemented in composite.c. During the buffer
249 scan that delivers characters to PRODUCE_GLYPHS, if the next
250 character to be delivered is a composed character, the iteration
251 calls composition_reseat_it and next_element_from_composition. If
252 they succeed to compose the character with one or more of the
253 following characters, the whole sequence of characters that where
254 composed is recorded in the `struct composition_it' object that is
255 part of the buffer iterator. The composed sequence could produce
256 one or more font glyphs (called "grapheme clusters") on the screen.
257 Each of these grapheme clusters is then delivered to PRODUCE_GLYPHS
258 in the direction corresponding to the current bidi scan direction
259 (recorded in the scan_dir member of the `struct bidi_it' object
260 that is part of the buffer iterator). In particular, if the bidi
261 iterator currently scans the buffer backwards, the grapheme
262 clusters are delivered back to front. This reorders the grapheme
263 clusters as appropriate for the current bidi context. Note that
264 this means that the grapheme clusters are always stored in the
265 LGSTRING object (see composite.c) in the logical order.
267 Moving an iterator in bidirectional text
268 without producing glyphs
270 Note one important detail mentioned above: that the bidi reordering
271 engine, driven by the iterator, produces characters in R2L rows
272 starting at the character that will be the rightmost on display.
273 As far as the iterator is concerned, the geometry of such rows is
274 still left to right, i.e. the iterator "thinks" the first character
275 is at the leftmost pixel position. The iterator does not know that
276 PRODUCE_GLYPHS reverses the order of the glyphs that the iterator
277 delivers. This is important when functions from the move_it_*
278 family are used to get to certain screen position or to match
279 screen coordinates with buffer coordinates: these functions use the
280 iterator geometry, which is left to right even in R2L paragraphs.
281 This works well with most callers of move_it_*, because they need
282 to get to a specific column, and columns are still numbered in the
283 reading order, i.e. the rightmost character in a R2L paragraph is
284 still column zero. But some callers do not get well with this; a
285 notable example is mouse clicks that need to find the character
286 that corresponds to certain pixel coordinates. See
287 buffer_posn_from_coords in dispnew.c for how this is handled. */
289 #include <config.h>
290 #include <stdio.h>
291 #include <limits.h>
293 #include "lisp.h"
294 #include "atimer.h"
295 #include "composite.h"
296 #include "keyboard.h"
297 #include "systime.h"
298 #include "frame.h"
299 #include "window.h"
300 #include "termchar.h"
301 #include "dispextern.h"
302 #include "character.h"
303 #include "buffer.h"
304 #include "charset.h"
305 #include "indent.h"
306 #include "commands.h"
307 #include "keymap.h"
308 #include "disptab.h"
309 #include "termhooks.h"
310 #include "termopts.h"
311 #include "intervals.h"
312 #include "coding.h"
313 #include "region-cache.h"
314 #include "font.h"
315 #include "fontset.h"
316 #include "blockinput.h"
317 #include "xwidget.h"
318 #ifdef HAVE_WINDOW_SYSTEM
319 #include TERM_HEADER
320 #endif /* HAVE_WINDOW_SYSTEM */
322 #ifndef FRAME_X_OUTPUT
323 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
324 #endif
326 #define INFINITY 10000000
328 /* Holds the list (error). */
329 static Lisp_Object list_of_error;
331 #ifdef HAVE_WINDOW_SYSTEM
333 /* Test if overflow newline into fringe. Called with iterator IT
334 at or past right window margin, and with IT->current_x set. */
336 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
337 (!NILP (Voverflow_newline_into_fringe) \
338 && FRAME_WINDOW_P ((IT)->f) \
339 && ((IT)->bidi_it.paragraph_dir == R2L \
340 ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
341 : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
342 && (IT)->current_x == (IT)->last_visible_x)
344 #else /* !HAVE_WINDOW_SYSTEM */
345 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) false
346 #endif /* HAVE_WINDOW_SYSTEM */
348 /* Test if the display element loaded in IT, or the underlying buffer
349 or string character, is a space or a TAB character. This is used
350 to determine where word wrapping can occur. */
352 #define IT_DISPLAYING_WHITESPACE(it) \
353 ((it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t')) \
354 || ((STRINGP (it->string) \
355 && (SREF (it->string, IT_STRING_BYTEPOS (*it)) == ' ' \
356 || SREF (it->string, IT_STRING_BYTEPOS (*it)) == '\t')) \
357 || (it->s \
358 && (it->s[IT_BYTEPOS (*it)] == ' ' \
359 || it->s[IT_BYTEPOS (*it)] == '\t')) \
360 || (IT_BYTEPOS (*it) < ZV_BYTE \
361 && (*BYTE_POS_ADDR (IT_BYTEPOS (*it)) == ' ' \
362 || *BYTE_POS_ADDR (IT_BYTEPOS (*it)) == '\t')))) \
364 /* True means print newline to stdout before next mini-buffer message. */
366 bool noninteractive_need_newline;
368 /* True means print newline to message log before next message. */
370 static bool message_log_need_newline;
372 /* Three markers that message_dolog uses.
373 It could allocate them itself, but that causes trouble
374 in handling memory-full errors. */
375 static Lisp_Object message_dolog_marker1;
376 static Lisp_Object message_dolog_marker2;
377 static Lisp_Object message_dolog_marker3;
379 /* The buffer position of the first character appearing entirely or
380 partially on the line of the selected window which contains the
381 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
382 redisplay optimization in redisplay_internal. */
384 static struct text_pos this_line_start_pos;
386 /* Number of characters past the end of the line above, including the
387 terminating newline. */
389 static struct text_pos this_line_end_pos;
391 /* The vertical positions and the height of this line. */
393 static int this_line_vpos;
394 static int this_line_y;
395 static int this_line_pixel_height;
397 /* X position at which this display line starts. Usually zero;
398 negative if first character is partially visible. */
400 static int this_line_start_x;
402 /* The smallest character position seen by move_it_* functions as they
403 move across display lines. Used to set MATRIX_ROW_START_CHARPOS of
404 hscrolled lines, see display_line. */
406 static struct text_pos this_line_min_pos;
408 /* Buffer that this_line_.* variables are referring to. */
410 static struct buffer *this_line_buffer;
412 /* True if an overlay arrow has been displayed in this window. */
414 static bool overlay_arrow_seen;
416 /* Vector containing glyphs for an ellipsis `...'. */
418 static Lisp_Object default_invis_vector[3];
420 /* This is the window where the echo area message was displayed. It
421 is always a mini-buffer window, but it may not be the same window
422 currently active as a mini-buffer. */
424 Lisp_Object echo_area_window;
426 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
427 pushes the current message and the value of
428 message_enable_multibyte on the stack, the function restore_message
429 pops the stack and displays MESSAGE again. */
431 static Lisp_Object Vmessage_stack;
433 /* True means multibyte characters were enabled when the echo area
434 message was specified. */
436 static bool message_enable_multibyte;
438 /* At each redisplay cycle, we should refresh everything there is to refresh.
439 To do that efficiently, we use many optimizations that try to make sure we
440 don't waste too much time updating things that haven't changed.
441 The coarsest such optimization is that, in the most common cases, we only
442 look at the selected-window.
444 To know whether other windows should be considered for redisplay, we use the
445 variable windows_or_buffers_changed: as long as it is 0, it means that we
446 have not noticed anything that should require updating anything else than
447 the selected-window. If it is set to REDISPLAY_SOME, it means that since
448 last redisplay, some changes have been made which could impact other
449 windows. To know which ones need redisplay, every buffer, window, and frame
450 has a `redisplay' bit, which (if true) means that this object needs to be
451 redisplayed. If windows_or_buffers_changed is 0, we know there's no point
452 looking for those `redisplay' bits (actually, there might be some such bits
453 set, but then only on objects which aren't displayed anyway).
455 OTOH if it's non-zero we wil have to loop through all windows and then check
456 the `redisplay' bit of the corresponding window, frame, and buffer, in order
457 to decide whether that window needs attention or not. Note that we can't
458 just look at the frame's redisplay bit to decide that the whole frame can be
459 skipped, since even if the frame's redisplay bit is unset, some of its
460 windows's redisplay bits may be set.
462 Mostly for historical reasons, windows_or_buffers_changed can also take
463 other non-zero values. In that case, the precise value doesn't matter (it
464 encodes the cause of the setting but is only used for debugging purposes),
465 and what it means is that we shouldn't pay attention to any `redisplay' bits
466 and we should simply try and redisplay every window out there. */
468 int windows_or_buffers_changed;
470 /* Nonzero if we should redraw the mode lines on the next redisplay.
471 Similarly to `windows_or_buffers_changed', If it has value REDISPLAY_SOME,
472 then only redisplay the mode lines in those buffers/windows/frames where the
473 `redisplay' bit has been set.
474 For any other value, redisplay all mode lines (the number used is then only
475 used to track down the cause for this full-redisplay).
477 Since the frame title uses the same %-constructs as the mode line
478 (except %c and %l), if this variable is non-zero, we also consider
479 redisplaying the title of each frame, see x_consider_frame_title.
481 The `redisplay' bits are the same as those used for
482 windows_or_buffers_changed, and setting windows_or_buffers_changed also
483 causes recomputation of the mode lines of all those windows. IOW this
484 variable only has an effect if windows_or_buffers_changed is zero, in which
485 case we should only need to redisplay the mode-line of those objects with
486 a `redisplay' bit set but not the window's text content (tho we may still
487 need to refresh the text content of the selected-window). */
489 int update_mode_lines;
491 /* True after display_mode_line if %l was used and it displayed a
492 line number. */
494 static bool line_number_displayed;
496 /* The name of the *Messages* buffer, a string. */
498 static Lisp_Object Vmessages_buffer_name;
500 /* Current, index 0, and last displayed echo area message. Either
501 buffers from echo_buffers, or nil to indicate no message. */
503 Lisp_Object echo_area_buffer[2];
505 /* The buffers referenced from echo_area_buffer. */
507 static Lisp_Object echo_buffer[2];
509 /* A vector saved used in with_area_buffer to reduce consing. */
511 static Lisp_Object Vwith_echo_area_save_vector;
513 /* True means display_echo_area should display the last echo area
514 message again. Set by redisplay_preserve_echo_area. */
516 static bool display_last_displayed_message_p;
518 /* True if echo area is being used by print; false if being used by
519 message. */
521 static bool message_buf_print;
523 /* Set to true in clear_message to make redisplay_internal aware
524 of an emptied echo area. */
526 static bool message_cleared_p;
528 /* A scratch glyph row with contents used for generating truncation
529 glyphs. Also used in direct_output_for_insert. */
531 #define MAX_SCRATCH_GLYPHS 100
532 static struct glyph_row scratch_glyph_row;
533 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
535 /* Ascent and height of the last line processed by move_it_to. */
537 static int last_height;
539 /* True if there's a help-echo in the echo area. */
541 bool help_echo_showing_p;
543 /* The maximum distance to look ahead for text properties. Values
544 that are too small let us call compute_char_face and similar
545 functions too often which is expensive. Values that are too large
546 let us call compute_char_face and alike too often because we
547 might not be interested in text properties that far away. */
549 #define TEXT_PROP_DISTANCE_LIMIT 100
551 /* SAVE_IT and RESTORE_IT are called when we save a snapshot of the
552 iterator state and later restore it. This is needed because the
553 bidi iterator on bidi.c keeps a stacked cache of its states, which
554 is really a singleton. When we use scratch iterator objects to
555 move around the buffer, we can cause the bidi cache to be pushed or
556 popped, and therefore we need to restore the cache state when we
557 return to the original iterator. */
558 #define SAVE_IT(ITCOPY, ITORIG, CACHE) \
559 do { \
560 if (CACHE) \
561 bidi_unshelve_cache (CACHE, true); \
562 ITCOPY = ITORIG; \
563 CACHE = bidi_shelve_cache (); \
564 } while (false)
566 #define RESTORE_IT(pITORIG, pITCOPY, CACHE) \
567 do { \
568 if (pITORIG != pITCOPY) \
569 *(pITORIG) = *(pITCOPY); \
570 bidi_unshelve_cache (CACHE, false); \
571 CACHE = NULL; \
572 } while (false)
574 /* Functions to mark elements as needing redisplay. */
575 enum { REDISPLAY_SOME = 2}; /* Arbitrary choice. */
577 void
578 redisplay_other_windows (void)
580 if (!windows_or_buffers_changed)
581 windows_or_buffers_changed = REDISPLAY_SOME;
584 void
585 wset_redisplay (struct window *w)
587 /* Beware: selected_window can be nil during early stages. */
588 if (!EQ (make_lisp_ptr (w, Lisp_Vectorlike), selected_window))
589 redisplay_other_windows ();
590 w->redisplay = true;
593 void
594 fset_redisplay (struct frame *f)
596 redisplay_other_windows ();
597 f->redisplay = true;
600 void
601 bset_redisplay (struct buffer *b)
603 int count = buffer_window_count (b);
604 if (count > 0)
606 /* ... it's visible in other window than selected, */
607 if (count > 1 || b != XBUFFER (XWINDOW (selected_window)->contents))
608 redisplay_other_windows ();
609 /* Even if we don't set windows_or_buffers_changed, do set `redisplay'
610 so that if we later set windows_or_buffers_changed, this buffer will
611 not be omitted. */
612 b->text->redisplay = true;
616 void
617 bset_update_mode_line (struct buffer *b)
619 if (!update_mode_lines)
620 update_mode_lines = REDISPLAY_SOME;
621 b->text->redisplay = true;
624 void
625 maybe_set_redisplay (Lisp_Object symbol)
627 if (HASH_TABLE_P (Vredisplay__variables)
628 && hash_lookup (XHASH_TABLE (Vredisplay__variables), symbol, NULL) >= 0)
630 bset_update_mode_line (current_buffer);
631 current_buffer->prevent_redisplay_optimizations_p = true;
635 #ifdef GLYPH_DEBUG
637 /* True means print traces of redisplay if compiled with
638 GLYPH_DEBUG defined. */
640 bool trace_redisplay_p;
642 #endif /* GLYPH_DEBUG */
644 #ifdef DEBUG_TRACE_MOVE
645 /* True means trace with TRACE_MOVE to stderr. */
646 static bool trace_move;
648 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
649 #else
650 #define TRACE_MOVE(x) (void) 0
651 #endif
653 /* Buffer being redisplayed -- for redisplay_window_error. */
655 static struct buffer *displayed_buffer;
657 /* Value returned from text property handlers (see below). */
659 enum prop_handled
661 HANDLED_NORMALLY,
662 HANDLED_RECOMPUTE_PROPS,
663 HANDLED_OVERLAY_STRING_CONSUMED,
664 HANDLED_RETURN
667 /* A description of text properties that redisplay is interested
668 in. */
670 struct props
672 /* The symbol index of the name of the property. */
673 short name;
675 /* A unique index for the property. */
676 enum prop_idx idx;
678 /* A handler function called to set up iterator IT from the property
679 at IT's current position. Value is used to steer handle_stop. */
680 enum prop_handled (*handler) (struct it *it);
683 static enum prop_handled handle_face_prop (struct it *);
684 static enum prop_handled handle_invisible_prop (struct it *);
685 static enum prop_handled handle_display_prop (struct it *);
686 static enum prop_handled handle_composition_prop (struct it *);
687 static enum prop_handled handle_overlay_change (struct it *);
688 static enum prop_handled handle_fontified_prop (struct it *);
690 /* Properties handled by iterators. */
692 static struct props it_props[] =
694 {SYMBOL_INDEX (Qfontified), FONTIFIED_PROP_IDX, handle_fontified_prop},
695 /* Handle `face' before `display' because some sub-properties of
696 `display' need to know the face. */
697 {SYMBOL_INDEX (Qface), FACE_PROP_IDX, handle_face_prop},
698 {SYMBOL_INDEX (Qdisplay), DISPLAY_PROP_IDX, handle_display_prop},
699 {SYMBOL_INDEX (Qinvisible), INVISIBLE_PROP_IDX, handle_invisible_prop},
700 {SYMBOL_INDEX (Qcomposition), COMPOSITION_PROP_IDX, handle_composition_prop},
701 {0, 0, NULL}
704 /* Value is the position described by X. If X is a marker, value is
705 the marker_position of X. Otherwise, value is X. */
707 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
709 /* Enumeration returned by some move_it_.* functions internally. */
711 enum move_it_result
713 /* Not used. Undefined value. */
714 MOVE_UNDEFINED,
716 /* Move ended at the requested buffer position or ZV. */
717 MOVE_POS_MATCH_OR_ZV,
719 /* Move ended at the requested X pixel position. */
720 MOVE_X_REACHED,
722 /* Move within a line ended at the end of a line that must be
723 continued. */
724 MOVE_LINE_CONTINUED,
726 /* Move within a line ended at the end of a line that would
727 be displayed truncated. */
728 MOVE_LINE_TRUNCATED,
730 /* Move within a line ended at a line end. */
731 MOVE_NEWLINE_OR_CR
734 /* This counter is used to clear the face cache every once in a while
735 in redisplay_internal. It is incremented for each redisplay.
736 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
737 cleared. */
739 #define CLEAR_FACE_CACHE_COUNT 500
740 static int clear_face_cache_count;
742 /* Similarly for the image cache. */
744 #ifdef HAVE_WINDOW_SYSTEM
745 #define CLEAR_IMAGE_CACHE_COUNT 101
746 static int clear_image_cache_count;
748 /* Null glyph slice */
749 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
750 #endif
752 /* True while redisplay_internal is in progress. */
754 bool redisplaying_p;
756 /* If a string, XTread_socket generates an event to display that string.
757 (The display is done in read_char.) */
759 Lisp_Object help_echo_string;
760 Lisp_Object help_echo_window;
761 Lisp_Object help_echo_object;
762 ptrdiff_t help_echo_pos;
764 /* Temporary variable for XTread_socket. */
766 Lisp_Object previous_help_echo_string;
768 /* Platform-independent portion of hourglass implementation. */
770 #ifdef HAVE_WINDOW_SYSTEM
772 /* True means an hourglass cursor is currently shown. */
773 static bool hourglass_shown_p;
775 /* If non-null, an asynchronous timer that, when it expires, displays
776 an hourglass cursor on all frames. */
777 static struct atimer *hourglass_atimer;
779 #endif /* HAVE_WINDOW_SYSTEM */
781 /* Default number of seconds to wait before displaying an hourglass
782 cursor. */
783 #define DEFAULT_HOURGLASS_DELAY 1
785 #ifdef HAVE_WINDOW_SYSTEM
787 /* Default pixel width of `thin-space' display method. */
788 #define THIN_SPACE_WIDTH 1
790 #endif /* HAVE_WINDOW_SYSTEM */
792 /* Function prototypes. */
794 static void setup_for_ellipsis (struct it *, int);
795 static void set_iterator_to_next (struct it *, bool);
796 static void mark_window_display_accurate_1 (struct window *, bool);
797 static bool row_for_charpos_p (struct glyph_row *, ptrdiff_t);
798 static bool cursor_row_p (struct glyph_row *);
799 static int redisplay_mode_lines (Lisp_Object, bool);
801 static void handle_line_prefix (struct it *);
803 static void handle_stop_backwards (struct it *, ptrdiff_t);
804 static void unwind_with_echo_area_buffer (Lisp_Object);
805 static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
806 static bool current_message_1 (ptrdiff_t, Lisp_Object);
807 static bool truncate_message_1 (ptrdiff_t, Lisp_Object);
808 static void set_message (Lisp_Object);
809 static bool set_message_1 (ptrdiff_t, Lisp_Object);
810 static bool display_echo_area_1 (ptrdiff_t, Lisp_Object);
811 static bool resize_mini_window_1 (ptrdiff_t, Lisp_Object);
812 static void unwind_redisplay (void);
813 static void extend_face_to_end_of_line (struct it *);
814 static intmax_t message_log_check_duplicate (ptrdiff_t, ptrdiff_t);
815 static void push_it (struct it *, struct text_pos *);
816 static void iterate_out_of_display_property (struct it *);
817 static void pop_it (struct it *);
818 static void redisplay_internal (void);
819 static void echo_area_display (bool);
820 static void redisplay_windows (Lisp_Object);
821 static void redisplay_window (Lisp_Object, bool);
822 static Lisp_Object redisplay_window_error (Lisp_Object);
823 static Lisp_Object redisplay_window_0 (Lisp_Object);
824 static Lisp_Object redisplay_window_1 (Lisp_Object);
825 static bool set_cursor_from_row (struct window *, struct glyph_row *,
826 struct glyph_matrix *, ptrdiff_t, ptrdiff_t,
827 int, int);
828 static bool cursor_row_fully_visible_p (struct window *, bool, bool);
829 static bool update_menu_bar (struct frame *, bool, bool);
830 static bool try_window_reusing_current_matrix (struct window *);
831 static int try_window_id (struct window *);
832 static bool display_line (struct it *);
833 static int display_mode_lines (struct window *);
834 static int display_mode_line (struct window *, enum face_id, Lisp_Object);
835 static int display_mode_element (struct it *, int, int, int, Lisp_Object,
836 Lisp_Object, bool);
837 static int store_mode_line_string (const char *, Lisp_Object, bool, int, int,
838 Lisp_Object);
839 static const char *decode_mode_spec (struct window *, int, int, Lisp_Object *);
840 static void display_menu_bar (struct window *);
841 static ptrdiff_t display_count_lines (ptrdiff_t, ptrdiff_t, ptrdiff_t,
842 ptrdiff_t *);
843 static int display_string (const char *, Lisp_Object, Lisp_Object,
844 ptrdiff_t, ptrdiff_t, struct it *, int, int, int, int);
845 static void compute_line_metrics (struct it *);
846 static void run_redisplay_end_trigger_hook (struct it *);
847 static bool get_overlay_strings (struct it *, ptrdiff_t);
848 static bool get_overlay_strings_1 (struct it *, ptrdiff_t, bool);
849 static void next_overlay_string (struct it *);
850 static void reseat (struct it *, struct text_pos, bool);
851 static void reseat_1 (struct it *, struct text_pos, bool);
852 static bool next_element_from_display_vector (struct it *);
853 static bool next_element_from_string (struct it *);
854 static bool next_element_from_c_string (struct it *);
855 static bool next_element_from_buffer (struct it *);
856 static bool next_element_from_composition (struct it *);
857 static bool next_element_from_image (struct it *);
858 static bool next_element_from_stretch (struct it *);
859 static bool next_element_from_xwidget (struct it *);
860 static void load_overlay_strings (struct it *, ptrdiff_t);
861 static bool get_next_display_element (struct it *);
862 static enum move_it_result
863 move_it_in_display_line_to (struct it *, ptrdiff_t, int,
864 enum move_operation_enum);
865 static void get_visually_first_element (struct it *);
866 static void compute_stop_pos (struct it *);
867 static int face_before_or_after_it_pos (struct it *, bool);
868 static ptrdiff_t next_overlay_change (ptrdiff_t);
869 static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object,
870 Lisp_Object, struct text_pos *, ptrdiff_t, bool);
871 static int handle_single_display_spec (struct it *, Lisp_Object,
872 Lisp_Object, Lisp_Object,
873 struct text_pos *, ptrdiff_t, int, bool);
874 static int underlying_face_id (struct it *);
876 #define face_before_it_pos(IT) face_before_or_after_it_pos (IT, true)
877 #define face_after_it_pos(IT) face_before_or_after_it_pos (IT, false)
879 #ifdef HAVE_WINDOW_SYSTEM
881 static void update_tool_bar (struct frame *, bool);
882 static void x_draw_bottom_divider (struct window *w);
883 static void notice_overwritten_cursor (struct window *,
884 enum glyph_row_area,
885 int, int, int, int);
886 static int normal_char_height (struct font *, int);
887 static void normal_char_ascent_descent (struct font *, int, int *, int *);
889 static void append_stretch_glyph (struct it *, Lisp_Object,
890 int, int, int);
892 static Lisp_Object get_it_property (struct it *, Lisp_Object);
893 static Lisp_Object calc_line_height_property (struct it *, Lisp_Object,
894 struct font *, int, bool);
896 #endif /* HAVE_WINDOW_SYSTEM */
898 static void produce_special_glyphs (struct it *, enum display_element_type);
899 static void show_mouse_face (Mouse_HLInfo *, enum draw_glyphs_face);
900 static bool coords_in_mouse_face_p (struct window *, int, int);
904 /***********************************************************************
905 Window display dimensions
906 ***********************************************************************/
908 /* Return the bottom boundary y-position for text lines in window W.
909 This is the first y position at which a line cannot start.
910 It is relative to the top of the window.
912 This is the height of W minus the height of a mode line, if any. */
915 window_text_bottom_y (struct window *w)
917 int height = WINDOW_PIXEL_HEIGHT (w);
919 height -= WINDOW_BOTTOM_DIVIDER_WIDTH (w);
921 if (WINDOW_WANTS_MODELINE_P (w))
922 height -= CURRENT_MODE_LINE_HEIGHT (w);
924 height -= WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
926 return height;
929 /* Return the pixel width of display area AREA of window W.
930 ANY_AREA means return the total width of W, not including
931 fringes to the left and right of the window. */
934 window_box_width (struct window *w, enum glyph_row_area area)
936 int width = w->pixel_width;
938 if (!w->pseudo_window_p)
940 width -= WINDOW_SCROLL_BAR_AREA_WIDTH (w);
941 width -= WINDOW_RIGHT_DIVIDER_WIDTH (w);
943 if (area == TEXT_AREA)
944 width -= (WINDOW_MARGINS_WIDTH (w)
945 + WINDOW_FRINGES_WIDTH (w));
946 else if (area == LEFT_MARGIN_AREA)
947 width = WINDOW_LEFT_MARGIN_WIDTH (w);
948 else if (area == RIGHT_MARGIN_AREA)
949 width = WINDOW_RIGHT_MARGIN_WIDTH (w);
952 /* With wide margins, fringes, etc. we might end up with a negative
953 width, correct that here. */
954 return max (0, width);
958 /* Return the pixel height of the display area of window W, not
959 including mode lines of W, if any. */
962 window_box_height (struct window *w)
964 struct frame *f = XFRAME (w->frame);
965 int height = WINDOW_PIXEL_HEIGHT (w);
967 eassert (height >= 0);
969 height -= WINDOW_BOTTOM_DIVIDER_WIDTH (w);
970 height -= WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
972 /* Note: the code below that determines the mode-line/header-line
973 height is essentially the same as that contained in the macro
974 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
975 the appropriate glyph row has its `mode_line_p' flag set,
976 and if it doesn't, uses estimate_mode_line_height instead. */
978 if (WINDOW_WANTS_MODELINE_P (w))
980 struct glyph_row *ml_row
981 = (w->current_matrix && w->current_matrix->rows
982 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
983 : 0);
984 if (ml_row && ml_row->mode_line_p)
985 height -= ml_row->height;
986 else
987 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
990 if (WINDOW_WANTS_HEADER_LINE_P (w))
992 struct glyph_row *hl_row
993 = (w->current_matrix && w->current_matrix->rows
994 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
995 : 0);
996 if (hl_row && hl_row->mode_line_p)
997 height -= hl_row->height;
998 else
999 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1002 /* With a very small font and a mode-line that's taller than
1003 default, we might end up with a negative height. */
1004 return max (0, height);
1007 /* Return the window-relative coordinate of the left edge of display
1008 area AREA of window W. ANY_AREA means return the left edge of the
1009 whole window, to the right of the left fringe of W. */
1012 window_box_left_offset (struct window *w, enum glyph_row_area area)
1014 int x;
1016 if (w->pseudo_window_p)
1017 return 0;
1019 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1021 if (area == TEXT_AREA)
1022 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1023 + window_box_width (w, LEFT_MARGIN_AREA));
1024 else if (area == RIGHT_MARGIN_AREA)
1025 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1026 + window_box_width (w, LEFT_MARGIN_AREA)
1027 + window_box_width (w, TEXT_AREA)
1028 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1030 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1031 else if (area == LEFT_MARGIN_AREA
1032 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1033 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1035 /* Don't return more than the window's pixel width. */
1036 return min (x, w->pixel_width);
1040 /* Return the window-relative coordinate of the right edge of display
1041 area AREA of window W. ANY_AREA means return the right edge of the
1042 whole window, to the left of the right fringe of W. */
1044 static int
1045 window_box_right_offset (struct window *w, enum glyph_row_area area)
1047 /* Don't return more than the window's pixel width. */
1048 return min (window_box_left_offset (w, area) + window_box_width (w, area),
1049 w->pixel_width);
1052 /* Return the frame-relative coordinate of the left edge of display
1053 area AREA of window W. ANY_AREA means return the left edge of the
1054 whole window, to the right of the left fringe of W. */
1057 window_box_left (struct window *w, enum glyph_row_area area)
1059 struct frame *f = XFRAME (w->frame);
1060 int x;
1062 if (w->pseudo_window_p)
1063 return FRAME_INTERNAL_BORDER_WIDTH (f);
1065 x = (WINDOW_LEFT_EDGE_X (w)
1066 + window_box_left_offset (w, area));
1068 return x;
1072 /* Return the frame-relative coordinate of the right edge of display
1073 area AREA of window W. ANY_AREA means return the right edge of the
1074 whole window, to the left of the right fringe of W. */
1077 window_box_right (struct window *w, enum glyph_row_area area)
1079 return window_box_left (w, area) + window_box_width (w, area);
1082 /* Get the bounding box of the display area AREA of window W, without
1083 mode lines, in frame-relative coordinates. ANY_AREA means the
1084 whole window, not including the left and right fringes of
1085 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1086 coordinates of the upper-left corner of the box. Return in
1087 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1089 void
1090 window_box (struct window *w, enum glyph_row_area area, int *box_x,
1091 int *box_y, int *box_width, int *box_height)
1093 if (box_width)
1094 *box_width = window_box_width (w, area);
1095 if (box_height)
1096 *box_height = window_box_height (w);
1097 if (box_x)
1098 *box_x = window_box_left (w, area);
1099 if (box_y)
1101 *box_y = WINDOW_TOP_EDGE_Y (w);
1102 if (WINDOW_WANTS_HEADER_LINE_P (w))
1103 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1107 #ifdef HAVE_WINDOW_SYSTEM
1109 /* Get the bounding box of the display area AREA of window W, without
1110 mode lines and both fringes of the window. Return in *TOP_LEFT_X
1111 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1112 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1113 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1114 box. */
1116 static void
1117 window_box_edges (struct window *w, int *top_left_x, int *top_left_y,
1118 int *bottom_right_x, int *bottom_right_y)
1120 window_box (w, ANY_AREA, top_left_x, top_left_y,
1121 bottom_right_x, bottom_right_y);
1122 *bottom_right_x += *top_left_x;
1123 *bottom_right_y += *top_left_y;
1126 #endif /* HAVE_WINDOW_SYSTEM */
1128 /***********************************************************************
1129 Utilities
1130 ***********************************************************************/
1132 /* Return the bottom y-position of the line the iterator IT is in.
1133 This can modify IT's settings. */
1136 line_bottom_y (struct it *it)
1138 int line_height = it->max_ascent + it->max_descent;
1139 int line_top_y = it->current_y;
1141 if (line_height == 0)
1143 if (last_height)
1144 line_height = last_height;
1145 else if (IT_CHARPOS (*it) < ZV)
1147 move_it_by_lines (it, 1);
1148 line_height = (it->max_ascent || it->max_descent
1149 ? it->max_ascent + it->max_descent
1150 : last_height);
1152 else
1154 struct glyph_row *row = it->glyph_row;
1156 /* Use the default character height. */
1157 it->glyph_row = NULL;
1158 it->what = IT_CHARACTER;
1159 it->c = ' ';
1160 it->len = 1;
1161 PRODUCE_GLYPHS (it);
1162 line_height = it->ascent + it->descent;
1163 it->glyph_row = row;
1167 return line_top_y + line_height;
1170 DEFUN ("line-pixel-height", Fline_pixel_height,
1171 Sline_pixel_height, 0, 0, 0,
1172 doc: /* Return height in pixels of text line in the selected window.
1174 Value is the height in pixels of the line at point. */)
1175 (void)
1177 struct it it;
1178 struct text_pos pt;
1179 struct window *w = XWINDOW (selected_window);
1180 struct buffer *old_buffer = NULL;
1181 Lisp_Object result;
1183 if (XBUFFER (w->contents) != current_buffer)
1185 old_buffer = current_buffer;
1186 set_buffer_internal_1 (XBUFFER (w->contents));
1188 SET_TEXT_POS (pt, PT, PT_BYTE);
1189 start_display (&it, w, pt);
1190 it.vpos = it.current_y = 0;
1191 last_height = 0;
1192 result = make_number (line_bottom_y (&it));
1193 if (old_buffer)
1194 set_buffer_internal_1 (old_buffer);
1196 return result;
1199 /* Return the default pixel height of text lines in window W. The
1200 value is the canonical height of the W frame's default font, plus
1201 any extra space required by the line-spacing variable or frame
1202 parameter.
1204 Implementation note: this ignores any line-spacing text properties
1205 put on the newline characters. This is because those properties
1206 only affect the _screen_ line ending in the newline (i.e., in a
1207 continued line, only the last screen line will be affected), which
1208 means only a small number of lines in a buffer can ever use this
1209 feature. Since this function is used to compute the default pixel
1210 equivalent of text lines in a window, we can safely ignore those
1211 few lines. For the same reasons, we ignore the line-height
1212 properties. */
1214 default_line_pixel_height (struct window *w)
1216 struct frame *f = WINDOW_XFRAME (w);
1217 int height = FRAME_LINE_HEIGHT (f);
1219 if (!FRAME_INITIAL_P (f) && BUFFERP (w->contents))
1221 struct buffer *b = XBUFFER (w->contents);
1222 Lisp_Object val = BVAR (b, extra_line_spacing);
1224 if (NILP (val))
1225 val = BVAR (&buffer_defaults, extra_line_spacing);
1226 if (!NILP (val))
1228 if (RANGED_INTEGERP (0, val, INT_MAX))
1229 height += XFASTINT (val);
1230 else if (FLOATP (val))
1232 int addon = XFLOAT_DATA (val) * height + 0.5;
1234 if (addon >= 0)
1235 height += addon;
1238 else
1239 height += f->extra_line_spacing;
1242 return height;
1245 /* Subroutine of pos_visible_p below. Extracts a display string, if
1246 any, from the display spec given as its argument. */
1247 static Lisp_Object
1248 string_from_display_spec (Lisp_Object spec)
1250 if (CONSP (spec))
1252 while (CONSP (spec))
1254 if (STRINGP (XCAR (spec)))
1255 return XCAR (spec);
1256 spec = XCDR (spec);
1259 else if (VECTORP (spec))
1261 ptrdiff_t i;
1263 for (i = 0; i < ASIZE (spec); i++)
1265 if (STRINGP (AREF (spec, i)))
1266 return AREF (spec, i);
1268 return Qnil;
1271 return spec;
1275 /* Limit insanely large values of W->hscroll on frame F to the largest
1276 value that will still prevent first_visible_x and last_visible_x of
1277 'struct it' from overflowing an int. */
1278 static int
1279 window_hscroll_limited (struct window *w, struct frame *f)
1281 ptrdiff_t window_hscroll = w->hscroll;
1282 int window_text_width = window_box_width (w, TEXT_AREA);
1283 int colwidth = FRAME_COLUMN_WIDTH (f);
1285 if (window_hscroll > (INT_MAX - window_text_width) / colwidth - 1)
1286 window_hscroll = (INT_MAX - window_text_width) / colwidth - 1;
1288 return window_hscroll;
1291 /* Return true if position CHARPOS is visible in window W.
1292 CHARPOS < 0 means return info about WINDOW_END position.
1293 If visible, set *X and *Y to pixel coordinates of top left corner.
1294 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1295 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1297 bool
1298 pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1299 int *rtop, int *rbot, int *rowh, int *vpos)
1301 struct it it;
1302 void *itdata = bidi_shelve_cache ();
1303 struct text_pos top;
1304 bool visible_p = false;
1305 struct buffer *old_buffer = NULL;
1306 bool r2l = false;
1308 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
1309 return visible_p;
1311 if (XBUFFER (w->contents) != current_buffer)
1313 old_buffer = current_buffer;
1314 set_buffer_internal_1 (XBUFFER (w->contents));
1317 SET_TEXT_POS_FROM_MARKER (top, w->start);
1318 /* Scrolling a minibuffer window via scroll bar when the echo area
1319 shows long text sometimes resets the minibuffer contents behind
1320 our backs. */
1321 if (CHARPOS (top) > ZV)
1322 SET_TEXT_POS (top, BEGV, BEGV_BYTE);
1324 /* If the top of the window is after CHARPOS, the latter is surely
1325 not visible. */
1326 if (charpos >= 0 && CHARPOS (top) > charpos)
1327 return visible_p;
1329 /* Compute exact mode line heights. */
1330 if (WINDOW_WANTS_MODELINE_P (w))
1331 w->mode_line_height
1332 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1333 BVAR (current_buffer, mode_line_format));
1335 if (WINDOW_WANTS_HEADER_LINE_P (w))
1336 w->header_line_height
1337 = display_mode_line (w, HEADER_LINE_FACE_ID,
1338 BVAR (current_buffer, header_line_format));
1340 start_display (&it, w, top);
1341 move_it_to (&it, charpos, -1, it.last_visible_y - 1, -1,
1342 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1344 if (charpos >= 0
1345 && (((!it.bidi_p || it.bidi_it.scan_dir != -1)
1346 && IT_CHARPOS (it) >= charpos)
1347 /* When scanning backwards under bidi iteration, move_it_to
1348 stops at or _before_ CHARPOS, because it stops at or to
1349 the _right_ of the character at CHARPOS. */
1350 || (it.bidi_p && it.bidi_it.scan_dir == -1
1351 && IT_CHARPOS (it) <= charpos)))
1353 /* We have reached CHARPOS, or passed it. How the call to
1354 move_it_to can overshoot: (i) If CHARPOS is on invisible text
1355 or covered by a display property, move_it_to stops at the end
1356 of the invisible text, to the right of CHARPOS. (ii) If
1357 CHARPOS is in a display vector, move_it_to stops on its last
1358 glyph. */
1359 int top_x = it.current_x;
1360 int top_y = it.current_y;
1361 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1362 int bottom_y;
1363 struct it save_it;
1364 void *save_it_data = NULL;
1366 /* Calling line_bottom_y may change it.method, it.position, etc. */
1367 SAVE_IT (save_it, it, save_it_data);
1368 last_height = 0;
1369 bottom_y = line_bottom_y (&it);
1370 if (top_y < window_top_y)
1371 visible_p = bottom_y > window_top_y;
1372 else if (top_y < it.last_visible_y)
1373 visible_p = true;
1374 if (bottom_y >= it.last_visible_y
1375 && it.bidi_p && it.bidi_it.scan_dir == -1
1376 && IT_CHARPOS (it) < charpos)
1378 /* When the last line of the window is scanned backwards
1379 under bidi iteration, we could be duped into thinking
1380 that we have passed CHARPOS, when in fact move_it_to
1381 simply stopped short of CHARPOS because it reached
1382 last_visible_y. To see if that's what happened, we call
1383 move_it_to again with a slightly larger vertical limit,
1384 and see if it actually moved vertically; if it did, we
1385 didn't really reach CHARPOS, which is beyond window end. */
1386 /* Why 10? because we don't know how many canonical lines
1387 will the height of the next line(s) be. So we guess. */
1388 int ten_more_lines = 10 * default_line_pixel_height (w);
1390 move_it_to (&it, charpos, -1, bottom_y + ten_more_lines, -1,
1391 MOVE_TO_POS | MOVE_TO_Y);
1392 if (it.current_y > top_y)
1393 visible_p = false;
1396 RESTORE_IT (&it, &save_it, save_it_data);
1397 if (visible_p)
1399 if (it.method == GET_FROM_DISPLAY_VECTOR)
1401 /* We stopped on the last glyph of a display vector.
1402 Try and recompute. Hack alert! */
1403 if (charpos < 2 || top.charpos >= charpos)
1404 top_x = it.glyph_row->x;
1405 else
1407 struct it it2, it2_prev;
1408 /* The idea is to get to the previous buffer
1409 position, consume the character there, and use
1410 the pixel coordinates we get after that. But if
1411 the previous buffer position is also displayed
1412 from a display vector, we need to consume all of
1413 the glyphs from that display vector. */
1414 start_display (&it2, w, top);
1415 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1416 /* If we didn't get to CHARPOS - 1, there's some
1417 replacing display property at that position, and
1418 we stopped after it. That is exactly the place
1419 whose coordinates we want. */
1420 if (IT_CHARPOS (it2) != charpos - 1)
1421 it2_prev = it2;
1422 else
1424 /* Iterate until we get out of the display
1425 vector that displays the character at
1426 CHARPOS - 1. */
1427 do {
1428 get_next_display_element (&it2);
1429 PRODUCE_GLYPHS (&it2);
1430 it2_prev = it2;
1431 set_iterator_to_next (&it2, true);
1432 } while (it2.method == GET_FROM_DISPLAY_VECTOR
1433 && IT_CHARPOS (it2) < charpos);
1435 if (ITERATOR_AT_END_OF_LINE_P (&it2_prev)
1436 || it2_prev.current_x > it2_prev.last_visible_x)
1437 top_x = it.glyph_row->x;
1438 else
1440 top_x = it2_prev.current_x;
1441 top_y = it2_prev.current_y;
1445 else if (IT_CHARPOS (it) != charpos)
1447 Lisp_Object cpos = make_number (charpos);
1448 Lisp_Object spec = Fget_char_property (cpos, Qdisplay, Qnil);
1449 Lisp_Object string = string_from_display_spec (spec);
1450 struct text_pos tpos;
1451 bool newline_in_string
1452 = (STRINGP (string)
1453 && memchr (SDATA (string), '\n', SBYTES (string)));
1455 SET_TEXT_POS (tpos, charpos, CHAR_TO_BYTE (charpos));
1456 bool replacing_spec_p
1457 = (!NILP (spec)
1458 && handle_display_spec (NULL, spec, Qnil, Qnil, &tpos,
1459 charpos, FRAME_WINDOW_P (it.f)));
1460 /* The tricky code below is needed because there's a
1461 discrepancy between move_it_to and how we set cursor
1462 when PT is at the beginning of a portion of text
1463 covered by a display property or an overlay with a
1464 display property, or the display line ends in a
1465 newline from a display string. move_it_to will stop
1466 _after_ such display strings, whereas
1467 set_cursor_from_row conspires with cursor_row_p to
1468 place the cursor on the first glyph produced from the
1469 display string. */
1471 /* We have overshoot PT because it is covered by a
1472 display property that replaces the text it covers.
1473 If the string includes embedded newlines, we are also
1474 in the wrong display line. Backtrack to the correct
1475 line, where the display property begins. */
1476 if (replacing_spec_p)
1478 Lisp_Object startpos, endpos;
1479 EMACS_INT start, end;
1480 struct it it3;
1482 /* Find the first and the last buffer positions
1483 covered by the display string. */
1484 endpos =
1485 Fnext_single_char_property_change (cpos, Qdisplay,
1486 Qnil, Qnil);
1487 startpos =
1488 Fprevious_single_char_property_change (endpos, Qdisplay,
1489 Qnil, Qnil);
1490 start = XFASTINT (startpos);
1491 end = XFASTINT (endpos);
1492 /* Move to the last buffer position before the
1493 display property. */
1494 start_display (&it3, w, top);
1495 if (start > CHARPOS (top))
1496 move_it_to (&it3, start - 1, -1, -1, -1, MOVE_TO_POS);
1497 /* Move forward one more line if the position before
1498 the display string is a newline or if it is the
1499 rightmost character on a line that is
1500 continued or word-wrapped. */
1501 if (it3.method == GET_FROM_BUFFER
1502 && (it3.c == '\n'
1503 || FETCH_BYTE (IT_BYTEPOS (it3)) == '\n'))
1504 move_it_by_lines (&it3, 1);
1505 else if (move_it_in_display_line_to (&it3, -1,
1506 it3.current_x
1507 + it3.pixel_width,
1508 MOVE_TO_X)
1509 == MOVE_LINE_CONTINUED)
1511 move_it_by_lines (&it3, 1);
1512 /* When we are under word-wrap, the #$@%!
1513 move_it_by_lines moves 2 lines, so we need to
1514 fix that up. */
1515 if (it3.line_wrap == WORD_WRAP)
1516 move_it_by_lines (&it3, -1);
1519 /* Record the vertical coordinate of the display
1520 line where we wound up. */
1521 top_y = it3.current_y;
1522 if (it3.bidi_p)
1524 /* When characters are reordered for display,
1525 the character displayed to the left of the
1526 display string could be _after_ the display
1527 property in the logical order. Use the
1528 smallest vertical position of these two. */
1529 start_display (&it3, w, top);
1530 move_it_to (&it3, end + 1, -1, -1, -1, MOVE_TO_POS);
1531 if (it3.current_y < top_y)
1532 top_y = it3.current_y;
1534 /* Move from the top of the window to the beginning
1535 of the display line where the display string
1536 begins. */
1537 start_display (&it3, w, top);
1538 move_it_to (&it3, -1, 0, top_y, -1, MOVE_TO_X | MOVE_TO_Y);
1539 /* If it3_moved stays false after the 'while' loop
1540 below, that means we already were at a newline
1541 before the loop (e.g., the display string begins
1542 with a newline), so we don't need to (and cannot)
1543 inspect the glyphs of it3.glyph_row, because
1544 PRODUCE_GLYPHS will not produce anything for a
1545 newline, and thus it3.glyph_row stays at its
1546 stale content it got at top of the window. */
1547 bool it3_moved = false;
1548 /* Finally, advance the iterator until we hit the
1549 first display element whose character position is
1550 CHARPOS, or until the first newline from the
1551 display string, which signals the end of the
1552 display line. */
1553 while (get_next_display_element (&it3))
1555 PRODUCE_GLYPHS (&it3);
1556 if (IT_CHARPOS (it3) == charpos
1557 || ITERATOR_AT_END_OF_LINE_P (&it3))
1558 break;
1559 it3_moved = true;
1560 set_iterator_to_next (&it3, false);
1562 top_x = it3.current_x - it3.pixel_width;
1563 /* Normally, we would exit the above loop because we
1564 found the display element whose character
1565 position is CHARPOS. For the contingency that we
1566 didn't, and stopped at the first newline from the
1567 display string, move back over the glyphs
1568 produced from the string, until we find the
1569 rightmost glyph not from the string. */
1570 if (it3_moved
1571 && newline_in_string
1572 && IT_CHARPOS (it3) != charpos && EQ (it3.object, string))
1574 struct glyph *g = it3.glyph_row->glyphs[TEXT_AREA]
1575 + it3.glyph_row->used[TEXT_AREA];
1577 while (EQ ((g - 1)->object, string))
1579 --g;
1580 top_x -= g->pixel_width;
1582 eassert (g < it3.glyph_row->glyphs[TEXT_AREA]
1583 + it3.glyph_row->used[TEXT_AREA]);
1588 *x = top_x;
1589 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1590 *rtop = max (0, window_top_y - top_y);
1591 *rbot = max (0, bottom_y - it.last_visible_y);
1592 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1593 - max (top_y, window_top_y)));
1594 *vpos = it.vpos;
1595 if (it.bidi_it.paragraph_dir == R2L)
1596 r2l = true;
1599 else
1601 /* Either we were asked to provide info about WINDOW_END, or
1602 CHARPOS is in the partially visible glyph row at end of
1603 window. */
1604 struct it it2;
1605 void *it2data = NULL;
1607 SAVE_IT (it2, it, it2data);
1608 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1609 move_it_by_lines (&it, 1);
1610 if (charpos < IT_CHARPOS (it)
1611 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1613 visible_p = true;
1614 RESTORE_IT (&it2, &it2, it2data);
1615 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1616 *x = it2.current_x;
1617 *y = it2.current_y + it2.max_ascent - it2.ascent;
1618 *rtop = max (0, -it2.current_y);
1619 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1620 - it.last_visible_y));
1621 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1622 it.last_visible_y)
1623 - max (it2.current_y,
1624 WINDOW_HEADER_LINE_HEIGHT (w))));
1625 *vpos = it2.vpos;
1626 if (it2.bidi_it.paragraph_dir == R2L)
1627 r2l = true;
1629 else
1630 bidi_unshelve_cache (it2data, true);
1632 bidi_unshelve_cache (itdata, false);
1634 if (old_buffer)
1635 set_buffer_internal_1 (old_buffer);
1637 if (visible_p)
1639 if (w->hscroll > 0)
1640 *x -=
1641 window_hscroll_limited (w, WINDOW_XFRAME (w))
1642 * WINDOW_FRAME_COLUMN_WIDTH (w);
1643 /* For lines in an R2L paragraph, we need to mirror the X pixel
1644 coordinate wrt the text area. For the reasons, see the
1645 commentary in buffer_posn_from_coords and the explanation of
1646 the geometry used by the move_it_* functions at the end of
1647 the large commentary near the beginning of this file. */
1648 if (r2l)
1649 *x = window_box_width (w, TEXT_AREA) - *x - 1;
1652 #if false
1653 /* Debugging code. */
1654 if (visible_p)
1655 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1656 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1657 else
1658 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1659 #endif
1661 return visible_p;
1665 /* Return the next character from STR. Return in *LEN the length of
1666 the character. This is like STRING_CHAR_AND_LENGTH but never
1667 returns an invalid character. If we find one, we return a `?', but
1668 with the length of the invalid character. */
1670 static int
1671 string_char_and_length (const unsigned char *str, int *len)
1673 int c;
1675 c = STRING_CHAR_AND_LENGTH (str, *len);
1676 if (!CHAR_VALID_P (c))
1677 /* We may not change the length here because other places in Emacs
1678 don't use this function, i.e. they silently accept invalid
1679 characters. */
1680 c = '?';
1682 return c;
1687 /* Given a position POS containing a valid character and byte position
1688 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1690 static struct text_pos
1691 string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, ptrdiff_t nchars)
1693 eassert (STRINGP (string) && nchars >= 0);
1695 if (STRING_MULTIBYTE (string))
1697 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1698 int len;
1700 while (nchars--)
1702 string_char_and_length (p, &len);
1703 p += len;
1704 CHARPOS (pos) += 1;
1705 BYTEPOS (pos) += len;
1708 else
1709 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1711 return pos;
1715 /* Value is the text position, i.e. character and byte position,
1716 for character position CHARPOS in STRING. */
1718 static struct text_pos
1719 string_pos (ptrdiff_t charpos, Lisp_Object string)
1721 struct text_pos pos;
1722 eassert (STRINGP (string));
1723 eassert (charpos >= 0);
1724 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1725 return pos;
1729 /* Value is a text position, i.e. character and byte position, for
1730 character position CHARPOS in C string S. MULTIBYTE_P
1731 means recognize multibyte characters. */
1733 static struct text_pos
1734 c_string_pos (ptrdiff_t charpos, const char *s, bool multibyte_p)
1736 struct text_pos pos;
1738 eassert (s != NULL);
1739 eassert (charpos >= 0);
1741 if (multibyte_p)
1743 int len;
1745 SET_TEXT_POS (pos, 0, 0);
1746 while (charpos--)
1748 string_char_and_length ((const unsigned char *) s, &len);
1749 s += len;
1750 CHARPOS (pos) += 1;
1751 BYTEPOS (pos) += len;
1754 else
1755 SET_TEXT_POS (pos, charpos, charpos);
1757 return pos;
1761 /* Value is the number of characters in C string S. MULTIBYTE_P
1762 means recognize multibyte characters. */
1764 static ptrdiff_t
1765 number_of_chars (const char *s, bool multibyte_p)
1767 ptrdiff_t nchars;
1769 if (multibyte_p)
1771 ptrdiff_t rest = strlen (s);
1772 int len;
1773 const unsigned char *p = (const unsigned char *) s;
1775 for (nchars = 0; rest > 0; ++nchars)
1777 string_char_and_length (p, &len);
1778 rest -= len, p += len;
1781 else
1782 nchars = strlen (s);
1784 return nchars;
1788 /* Compute byte position NEWPOS->bytepos corresponding to
1789 NEWPOS->charpos. POS is a known position in string STRING.
1790 NEWPOS->charpos must be >= POS.charpos. */
1792 static void
1793 compute_string_pos (struct text_pos *newpos, struct text_pos pos, Lisp_Object string)
1795 eassert (STRINGP (string));
1796 eassert (CHARPOS (*newpos) >= CHARPOS (pos));
1798 if (STRING_MULTIBYTE (string))
1799 *newpos = string_pos_nchars_ahead (pos, string,
1800 CHARPOS (*newpos) - CHARPOS (pos));
1801 else
1802 BYTEPOS (*newpos) = CHARPOS (*newpos);
1805 /* EXPORT:
1806 Return an estimation of the pixel height of mode or header lines on
1807 frame F. FACE_ID specifies what line's height to estimate. */
1810 estimate_mode_line_height (struct frame *f, enum face_id face_id)
1812 #ifdef HAVE_WINDOW_SYSTEM
1813 if (FRAME_WINDOW_P (f))
1815 int height = FONT_HEIGHT (FRAME_FONT (f));
1817 /* This function is called so early when Emacs starts that the face
1818 cache and mode line face are not yet initialized. */
1819 if (FRAME_FACE_CACHE (f))
1821 struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
1822 if (face)
1824 if (face->font)
1825 height = normal_char_height (face->font, -1);
1826 if (face->box_line_width > 0)
1827 height += 2 * face->box_line_width;
1831 return height;
1833 #endif
1835 return 1;
1838 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1839 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1840 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP, do
1841 not force the value into range. */
1843 void
1844 pixel_to_glyph_coords (struct frame *f, int pix_x, int pix_y, int *x, int *y,
1845 NativeRectangle *bounds, bool noclip)
1848 #ifdef HAVE_WINDOW_SYSTEM
1849 if (FRAME_WINDOW_P (f))
1851 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1852 even for negative values. */
1853 if (pix_x < 0)
1854 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1855 if (pix_y < 0)
1856 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1858 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1859 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1861 if (bounds)
1862 STORE_NATIVE_RECT (*bounds,
1863 FRAME_COL_TO_PIXEL_X (f, pix_x),
1864 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1865 FRAME_COLUMN_WIDTH (f) - 1,
1866 FRAME_LINE_HEIGHT (f) - 1);
1868 /* PXW: Should we clip pixels before converting to columns/lines? */
1869 if (!noclip)
1871 if (pix_x < 0)
1872 pix_x = 0;
1873 else if (pix_x > FRAME_TOTAL_COLS (f))
1874 pix_x = FRAME_TOTAL_COLS (f);
1876 if (pix_y < 0)
1877 pix_y = 0;
1878 else if (pix_y > FRAME_TOTAL_LINES (f))
1879 pix_y = FRAME_TOTAL_LINES (f);
1882 #endif
1884 *x = pix_x;
1885 *y = pix_y;
1889 /* Find the glyph under window-relative coordinates X/Y in window W.
1890 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1891 strings. Return in *HPOS and *VPOS the row and column number of
1892 the glyph found. Return in *AREA the glyph area containing X.
1893 Value is a pointer to the glyph found or null if X/Y is not on
1894 text, or we can't tell because W's current matrix is not up to
1895 date. */
1897 static struct glyph *
1898 x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
1899 int *dx, int *dy, int *area)
1901 struct glyph *glyph, *end;
1902 struct glyph_row *row = NULL;
1903 int x0, i;
1905 /* Find row containing Y. Give up if some row is not enabled. */
1906 for (i = 0; i < w->current_matrix->nrows; ++i)
1908 row = MATRIX_ROW (w->current_matrix, i);
1909 if (!row->enabled_p)
1910 return NULL;
1911 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1912 break;
1915 *vpos = i;
1916 *hpos = 0;
1918 /* Give up if Y is not in the window. */
1919 if (i == w->current_matrix->nrows)
1920 return NULL;
1922 /* Get the glyph area containing X. */
1923 if (w->pseudo_window_p)
1925 *area = TEXT_AREA;
1926 x0 = 0;
1928 else
1930 if (x < window_box_left_offset (w, TEXT_AREA))
1932 *area = LEFT_MARGIN_AREA;
1933 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1935 else if (x < window_box_right_offset (w, TEXT_AREA))
1937 *area = TEXT_AREA;
1938 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1940 else
1942 *area = RIGHT_MARGIN_AREA;
1943 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1947 /* Find glyph containing X. */
1948 glyph = row->glyphs[*area];
1949 end = glyph + row->used[*area];
1950 x -= x0;
1951 while (glyph < end && x >= glyph->pixel_width)
1953 x -= glyph->pixel_width;
1954 ++glyph;
1957 if (glyph == end)
1958 return NULL;
1960 if (dx)
1962 *dx = x;
1963 *dy = y - (row->y + row->ascent - glyph->ascent);
1966 *hpos = glyph - row->glyphs[*area];
1967 return glyph;
1970 /* Convert frame-relative x/y to coordinates relative to window W.
1971 Takes pseudo-windows into account. */
1973 static void
1974 frame_to_window_pixel_xy (struct window *w, int *x, int *y)
1976 if (w->pseudo_window_p)
1978 /* A pseudo-window is always full-width, and starts at the
1979 left edge of the frame, plus a frame border. */
1980 struct frame *f = XFRAME (w->frame);
1981 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1982 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1984 else
1986 *x -= WINDOW_LEFT_EDGE_X (w);
1987 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1991 #ifdef HAVE_WINDOW_SYSTEM
1993 /* EXPORT:
1994 Return in RECTS[] at most N clipping rectangles for glyph string S.
1995 Return the number of stored rectangles. */
1998 get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
2000 XRectangle r;
2002 if (n <= 0)
2003 return 0;
2005 if (s->row->full_width_p)
2007 /* Draw full-width. X coordinates are relative to S->w->left_col. */
2008 r.x = WINDOW_LEFT_EDGE_X (s->w);
2009 if (s->row->mode_line_p)
2010 r.width = WINDOW_PIXEL_WIDTH (s->w) - WINDOW_RIGHT_DIVIDER_WIDTH (s->w);
2011 else
2012 r.width = WINDOW_PIXEL_WIDTH (s->w);
2014 /* Unless displaying a mode or menu bar line, which are always
2015 fully visible, clip to the visible part of the row. */
2016 if (s->w->pseudo_window_p)
2017 r.height = s->row->visible_height;
2018 else
2019 r.height = s->height;
2021 else
2023 /* This is a text line that may be partially visible. */
2024 r.x = window_box_left (s->w, s->area);
2025 r.width = window_box_width (s->w, s->area);
2026 r.height = s->row->visible_height;
2029 if (s->clip_head)
2030 if (r.x < s->clip_head->x)
2032 if (r.width >= s->clip_head->x - r.x)
2033 r.width -= s->clip_head->x - r.x;
2034 else
2035 r.width = 0;
2036 r.x = s->clip_head->x;
2038 if (s->clip_tail)
2039 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
2041 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
2042 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
2043 else
2044 r.width = 0;
2047 /* If S draws overlapping rows, it's sufficient to use the top and
2048 bottom of the window for clipping because this glyph string
2049 intentionally draws over other lines. */
2050 if (s->for_overlaps)
2052 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2053 r.height = window_text_bottom_y (s->w) - r.y;
2055 /* Alas, the above simple strategy does not work for the
2056 environments with anti-aliased text: if the same text is
2057 drawn onto the same place multiple times, it gets thicker.
2058 If the overlap we are processing is for the erased cursor, we
2059 take the intersection with the rectangle of the cursor. */
2060 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
2062 XRectangle rc, r_save = r;
2064 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
2065 rc.y = s->w->phys_cursor.y;
2066 rc.width = s->w->phys_cursor_width;
2067 rc.height = s->w->phys_cursor_height;
2069 x_intersect_rectangles (&r_save, &rc, &r);
2072 else
2074 /* Don't use S->y for clipping because it doesn't take partially
2075 visible lines into account. For example, it can be negative for
2076 partially visible lines at the top of a window. */
2077 if (!s->row->full_width_p
2078 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
2079 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2080 else
2081 r.y = max (0, s->row->y);
2084 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
2086 /* If drawing the cursor, don't let glyph draw outside its
2087 advertised boundaries. Cleartype does this under some circumstances. */
2088 if (s->hl == DRAW_CURSOR)
2090 struct glyph *glyph = s->first_glyph;
2091 int height, max_y;
2093 if (s->x > r.x)
2095 if (r.width >= s->x - r.x)
2096 r.width -= s->x - r.x;
2097 else /* R2L hscrolled row with cursor outside text area */
2098 r.width = 0;
2099 r.x = s->x;
2101 r.width = min (r.width, glyph->pixel_width);
2103 /* If r.y is below window bottom, ensure that we still see a cursor. */
2104 height = min (glyph->ascent + glyph->descent,
2105 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
2106 max_y = window_text_bottom_y (s->w) - height;
2107 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
2108 if (s->ybase - glyph->ascent > max_y)
2110 r.y = max_y;
2111 r.height = height;
2113 else
2115 /* Don't draw cursor glyph taller than our actual glyph. */
2116 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
2117 if (height < r.height)
2119 max_y = r.y + r.height;
2120 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
2121 r.height = min (max_y - r.y, height);
2126 if (s->row->clip)
2128 XRectangle r_save = r;
2130 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
2131 r.width = 0;
2134 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
2135 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
2137 #ifdef CONVERT_FROM_XRECT
2138 CONVERT_FROM_XRECT (r, *rects);
2139 #else
2140 *rects = r;
2141 #endif
2142 return 1;
2144 else
2146 /* If we are processing overlapping and allowed to return
2147 multiple clipping rectangles, we exclude the row of the glyph
2148 string from the clipping rectangle. This is to avoid drawing
2149 the same text on the environment with anti-aliasing. */
2150 #ifdef CONVERT_FROM_XRECT
2151 XRectangle rs[2];
2152 #else
2153 XRectangle *rs = rects;
2154 #endif
2155 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
2157 if (s->for_overlaps & OVERLAPS_PRED)
2159 rs[i] = r;
2160 if (r.y + r.height > row_y)
2162 if (r.y < row_y)
2163 rs[i].height = row_y - r.y;
2164 else
2165 rs[i].height = 0;
2167 i++;
2169 if (s->for_overlaps & OVERLAPS_SUCC)
2171 rs[i] = r;
2172 if (r.y < row_y + s->row->visible_height)
2174 if (r.y + r.height > row_y + s->row->visible_height)
2176 rs[i].y = row_y + s->row->visible_height;
2177 rs[i].height = r.y + r.height - rs[i].y;
2179 else
2180 rs[i].height = 0;
2182 i++;
2185 n = i;
2186 #ifdef CONVERT_FROM_XRECT
2187 for (i = 0; i < n; i++)
2188 CONVERT_FROM_XRECT (rs[i], rects[i]);
2189 #endif
2190 return n;
2194 /* EXPORT:
2195 Return in *NR the clipping rectangle for glyph string S. */
2197 void
2198 get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
2200 get_glyph_string_clip_rects (s, nr, 1);
2204 /* EXPORT:
2205 Return the position and height of the phys cursor in window W.
2206 Set w->phys_cursor_width to width of phys cursor.
2209 void
2210 get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
2211 struct glyph *glyph, int *xp, int *yp, int *heightp)
2213 struct frame *f = XFRAME (WINDOW_FRAME (w));
2214 int x, y, wd, h, h0, y0, ascent;
2216 /* Compute the width of the rectangle to draw. If on a stretch
2217 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2218 rectangle as wide as the glyph, but use a canonical character
2219 width instead. */
2220 wd = glyph->pixel_width;
2222 x = w->phys_cursor.x;
2223 if (x < 0)
2225 wd += x;
2226 x = 0;
2229 if (glyph->type == STRETCH_GLYPH
2230 && !x_stretch_cursor_p)
2231 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2232 w->phys_cursor_width = wd;
2234 /* Don't let the hollow cursor glyph descend below the glyph row's
2235 ascent value, lest the hollow cursor looks funny. */
2236 y = w->phys_cursor.y;
2237 ascent = row->ascent;
2238 if (row->ascent < glyph->ascent)
2240 y -= glyph->ascent - row->ascent;
2241 ascent = glyph->ascent;
2244 /* If y is below window bottom, ensure that we still see a cursor. */
2245 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2247 h = max (h0, ascent + glyph->descent);
2248 h0 = min (h0, ascent + glyph->descent);
2250 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2251 if (y < y0)
2253 h = max (h - (y0 - y) + 1, h0);
2254 y = y0 - 1;
2256 else
2258 y0 = window_text_bottom_y (w) - h0;
2259 if (y > y0)
2261 h += y - y0;
2262 y = y0;
2266 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2267 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2268 *heightp = h;
2272 * Remember which glyph the mouse is over.
2275 void
2276 remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
2278 Lisp_Object window;
2279 struct window *w;
2280 struct glyph_row *r, *gr, *end_row;
2281 enum window_part part;
2282 enum glyph_row_area area;
2283 int x, y, width, height;
2285 /* Try to determine frame pixel position and size of the glyph under
2286 frame pixel coordinates X/Y on frame F. */
2288 if (window_resize_pixelwise)
2290 width = height = 1;
2291 goto virtual_glyph;
2293 else if (!f->glyphs_initialized_p
2294 || (window = window_from_coordinates (f, gx, gy, &part, false),
2295 NILP (window)))
2297 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2298 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2299 goto virtual_glyph;
2302 w = XWINDOW (window);
2303 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2304 height = WINDOW_FRAME_LINE_HEIGHT (w);
2306 x = window_relative_x_coord (w, part, gx);
2307 y = gy - WINDOW_TOP_EDGE_Y (w);
2309 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2310 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2312 if (w->pseudo_window_p)
2314 area = TEXT_AREA;
2315 part = ON_MODE_LINE; /* Don't adjust margin. */
2316 goto text_glyph;
2319 switch (part)
2321 case ON_LEFT_MARGIN:
2322 area = LEFT_MARGIN_AREA;
2323 goto text_glyph;
2325 case ON_RIGHT_MARGIN:
2326 area = RIGHT_MARGIN_AREA;
2327 goto text_glyph;
2329 case ON_HEADER_LINE:
2330 case ON_MODE_LINE:
2331 gr = (part == ON_HEADER_LINE
2332 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2333 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2334 gy = gr->y;
2335 area = TEXT_AREA;
2336 goto text_glyph_row_found;
2338 case ON_TEXT:
2339 area = TEXT_AREA;
2341 text_glyph:
2342 gr = 0; gy = 0;
2343 for (; r <= end_row && r->enabled_p; ++r)
2344 if (r->y + r->height > y)
2346 gr = r; gy = r->y;
2347 break;
2350 text_glyph_row_found:
2351 if (gr && gy <= y)
2353 struct glyph *g = gr->glyphs[area];
2354 struct glyph *end = g + gr->used[area];
2356 height = gr->height;
2357 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2358 if (gx + g->pixel_width > x)
2359 break;
2361 if (g < end)
2363 if (g->type == IMAGE_GLYPH)
2365 /* Don't remember when mouse is over image, as
2366 image may have hot-spots. */
2367 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2368 return;
2370 width = g->pixel_width;
2372 else
2374 /* Use nominal char spacing at end of line. */
2375 x -= gx;
2376 gx += (x / width) * width;
2379 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2381 gx += window_box_left_offset (w, area);
2382 /* Don't expand over the modeline to make sure the vertical
2383 drag cursor is shown early enough. */
2384 height = min (height,
2385 max (0, WINDOW_BOX_HEIGHT_NO_MODE_LINE (w) - gy));
2388 else
2390 /* Use nominal line height at end of window. */
2391 gx = (x / width) * width;
2392 y -= gy;
2393 gy += (y / height) * height;
2394 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2395 /* See comment above. */
2396 height = min (height,
2397 max (0, WINDOW_BOX_HEIGHT_NO_MODE_LINE (w) - gy));
2399 break;
2401 case ON_LEFT_FRINGE:
2402 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2403 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2404 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2405 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2406 goto row_glyph;
2408 case ON_RIGHT_FRINGE:
2409 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2410 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2411 : window_box_right_offset (w, TEXT_AREA));
2412 if (WINDOW_RIGHT_DIVIDER_WIDTH (w) == 0
2413 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
2414 && !WINDOW_RIGHTMOST_P (w))
2415 if (gx < WINDOW_PIXEL_WIDTH (w) - width)
2416 /* Make sure the vertical border can get her own glyph to the
2417 right of the one we build here. */
2418 width = WINDOW_RIGHT_FRINGE_WIDTH (w) - width;
2419 else
2420 width = WINDOW_PIXEL_WIDTH (w) - gx;
2421 else
2422 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2424 goto row_glyph;
2426 case ON_VERTICAL_BORDER:
2427 gx = WINDOW_PIXEL_WIDTH (w) - width;
2428 goto row_glyph;
2430 case ON_VERTICAL_SCROLL_BAR:
2431 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2433 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2434 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2435 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2436 : 0)));
2437 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2439 row_glyph:
2440 gr = 0, gy = 0;
2441 for (; r <= end_row && r->enabled_p; ++r)
2442 if (r->y + r->height > y)
2444 gr = r; gy = r->y;
2445 break;
2448 if (gr && gy <= y)
2449 height = gr->height;
2450 else
2452 /* Use nominal line height at end of window. */
2453 y -= gy;
2454 gy += (y / height) * height;
2456 break;
2458 case ON_RIGHT_DIVIDER:
2459 gx = WINDOW_PIXEL_WIDTH (w) - WINDOW_RIGHT_DIVIDER_WIDTH (w);
2460 width = WINDOW_RIGHT_DIVIDER_WIDTH (w);
2461 gy = 0;
2462 /* The bottom divider prevails. */
2463 height = WINDOW_PIXEL_HEIGHT (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
2464 goto add_edge;
2466 case ON_BOTTOM_DIVIDER:
2467 gx = 0;
2468 width = WINDOW_PIXEL_WIDTH (w);
2469 gy = WINDOW_PIXEL_HEIGHT (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
2470 height = WINDOW_BOTTOM_DIVIDER_WIDTH (w);
2471 goto add_edge;
2473 default:
2475 virtual_glyph:
2476 /* If there is no glyph under the mouse, then we divide the screen
2477 into a grid of the smallest glyph in the frame, and use that
2478 as our "glyph". */
2480 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2481 round down even for negative values. */
2482 if (gx < 0)
2483 gx -= width - 1;
2484 if (gy < 0)
2485 gy -= height - 1;
2487 gx = (gx / width) * width;
2488 gy = (gy / height) * height;
2490 goto store_rect;
2493 add_edge:
2494 gx += WINDOW_LEFT_EDGE_X (w);
2495 gy += WINDOW_TOP_EDGE_Y (w);
2497 store_rect:
2498 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2500 /* Visible feedback for debugging. */
2501 #if false && defined HAVE_X_WINDOWS
2502 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2503 f->output_data.x->normal_gc,
2504 gx, gy, width, height);
2505 #endif
2509 #endif /* HAVE_WINDOW_SYSTEM */
2511 static void
2512 adjust_window_ends (struct window *w, struct glyph_row *row, bool current)
2514 eassert (w);
2515 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
2516 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
2517 w->window_end_vpos
2518 = MATRIX_ROW_VPOS (row, current ? w->current_matrix : w->desired_matrix);
2521 /***********************************************************************
2522 Lisp form evaluation
2523 ***********************************************************************/
2525 /* Error handler for safe_eval and safe_call. */
2527 static Lisp_Object
2528 safe_eval_handler (Lisp_Object arg, ptrdiff_t nargs, Lisp_Object *args)
2530 add_to_log ("Error during redisplay: %S signaled %S",
2531 Flist (nargs, args), arg);
2532 return Qnil;
2535 /* Call function FUNC with the rest of NARGS - 1 arguments
2536 following. Return the result, or nil if something went
2537 wrong. Prevent redisplay during the evaluation. */
2539 static Lisp_Object
2540 safe__call (bool inhibit_quit, ptrdiff_t nargs, Lisp_Object func, va_list ap)
2542 Lisp_Object val;
2544 if (inhibit_eval_during_redisplay)
2545 val = Qnil;
2546 else
2548 ptrdiff_t i;
2549 ptrdiff_t count = SPECPDL_INDEX ();
2550 Lisp_Object *args;
2551 USE_SAFE_ALLOCA;
2552 SAFE_ALLOCA_LISP (args, nargs);
2554 args[0] = func;
2555 for (i = 1; i < nargs; i++)
2556 args[i] = va_arg (ap, Lisp_Object);
2558 specbind (Qinhibit_redisplay, Qt);
2559 if (inhibit_quit)
2560 specbind (Qinhibit_quit, Qt);
2561 /* Use Qt to ensure debugger does not run,
2562 so there is no possibility of wanting to redisplay. */
2563 val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
2564 safe_eval_handler);
2565 SAFE_FREE ();
2566 val = unbind_to (count, val);
2569 return val;
2572 Lisp_Object
2573 safe_call (ptrdiff_t nargs, Lisp_Object func, ...)
2575 Lisp_Object retval;
2576 va_list ap;
2578 va_start (ap, func);
2579 retval = safe__call (false, nargs, func, ap);
2580 va_end (ap);
2581 return retval;
2584 /* Call function FN with one argument ARG.
2585 Return the result, or nil if something went wrong. */
2587 Lisp_Object
2588 safe_call1 (Lisp_Object fn, Lisp_Object arg)
2590 return safe_call (2, fn, arg);
2593 static Lisp_Object
2594 safe__call1 (bool inhibit_quit, Lisp_Object fn, ...)
2596 Lisp_Object retval;
2597 va_list ap;
2599 va_start (ap, fn);
2600 retval = safe__call (inhibit_quit, 2, fn, ap);
2601 va_end (ap);
2602 return retval;
2605 Lisp_Object
2606 safe_eval (Lisp_Object sexpr)
2608 return safe__call1 (false, Qeval, sexpr);
2611 static Lisp_Object
2612 safe__eval (bool inhibit_quit, Lisp_Object sexpr)
2614 return safe__call1 (inhibit_quit, Qeval, sexpr);
2617 /* Call function FN with two arguments ARG1 and ARG2.
2618 Return the result, or nil if something went wrong. */
2620 Lisp_Object
2621 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2623 return safe_call (3, fn, arg1, arg2);
2628 /***********************************************************************
2629 Debugging
2630 ***********************************************************************/
2632 /* Define CHECK_IT to perform sanity checks on iterators.
2633 This is for debugging. It is too slow to do unconditionally. */
2635 static void
2636 CHECK_IT (struct it *it)
2638 #if false
2639 if (it->method == GET_FROM_STRING)
2641 eassert (STRINGP (it->string));
2642 eassert (IT_STRING_CHARPOS (*it) >= 0);
2644 else
2646 eassert (IT_STRING_CHARPOS (*it) < 0);
2647 if (it->method == GET_FROM_BUFFER)
2649 /* Check that character and byte positions agree. */
2650 eassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2654 if (it->dpvec)
2655 eassert (it->current.dpvec_index >= 0);
2656 else
2657 eassert (it->current.dpvec_index < 0);
2658 #endif
2662 /* Check that the window end of window W is what we expect it
2663 to be---the last row in the current matrix displaying text. */
2665 static void
2666 CHECK_WINDOW_END (struct window *w)
2668 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2669 if (!MINI_WINDOW_P (w) && w->window_end_valid)
2671 struct glyph_row *row;
2672 eassert ((row = MATRIX_ROW (w->current_matrix, w->window_end_vpos),
2673 !row->enabled_p
2674 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2675 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2677 #endif
2680 /***********************************************************************
2681 Iterator initialization
2682 ***********************************************************************/
2684 /* Initialize IT for displaying current_buffer in window W, starting
2685 at character position CHARPOS. CHARPOS < 0 means that no buffer
2686 position is specified which is useful when the iterator is assigned
2687 a position later. BYTEPOS is the byte position corresponding to
2688 CHARPOS.
2690 If ROW is not null, calls to produce_glyphs with IT as parameter
2691 will produce glyphs in that row.
2693 BASE_FACE_ID is the id of a base face to use. It must be one of
2694 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2695 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2696 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2698 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2699 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2700 will be initialized to use the corresponding mode line glyph row of
2701 the desired matrix of W. */
2703 void
2704 init_iterator (struct it *it, struct window *w,
2705 ptrdiff_t charpos, ptrdiff_t bytepos,
2706 struct glyph_row *row, enum face_id base_face_id)
2708 enum face_id remapped_base_face_id = base_face_id;
2710 /* Some precondition checks. */
2711 eassert (w != NULL && it != NULL);
2712 eassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2713 && charpos <= ZV));
2715 /* If face attributes have been changed since the last redisplay,
2716 free realized faces now because they depend on face definitions
2717 that might have changed. Don't free faces while there might be
2718 desired matrices pending which reference these faces. */
2719 if (!inhibit_free_realized_faces)
2721 if (face_change)
2723 face_change = false;
2724 free_all_realized_faces (Qnil);
2726 else if (XFRAME (w->frame)->face_change)
2728 XFRAME (w->frame)->face_change = 0;
2729 free_all_realized_faces (w->frame);
2733 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2734 if (! NILP (Vface_remapping_alist))
2735 remapped_base_face_id
2736 = lookup_basic_face (XFRAME (w->frame), base_face_id);
2738 /* Use one of the mode line rows of W's desired matrix if
2739 appropriate. */
2740 if (row == NULL)
2742 if (base_face_id == MODE_LINE_FACE_ID
2743 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2744 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2745 else if (base_face_id == HEADER_LINE_FACE_ID)
2746 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2749 /* Clear IT, and set it->object and other IT's Lisp objects to Qnil.
2750 Other parts of redisplay rely on that. */
2751 memclear (it, sizeof *it);
2752 it->current.overlay_string_index = -1;
2753 it->current.dpvec_index = -1;
2754 it->base_face_id = remapped_base_face_id;
2755 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2756 it->paragraph_embedding = L2R;
2757 it->bidi_it.w = w;
2759 /* The window in which we iterate over current_buffer: */
2760 XSETWINDOW (it->window, w);
2761 it->w = w;
2762 it->f = XFRAME (w->frame);
2764 it->cmp_it.id = -1;
2766 /* Extra space between lines (on window systems only). */
2767 if (base_face_id == DEFAULT_FACE_ID
2768 && FRAME_WINDOW_P (it->f))
2770 if (NATNUMP (BVAR (current_buffer, extra_line_spacing)))
2771 it->extra_line_spacing = XFASTINT (BVAR (current_buffer, extra_line_spacing));
2772 else if (FLOATP (BVAR (current_buffer, extra_line_spacing)))
2773 it->extra_line_spacing = (XFLOAT_DATA (BVAR (current_buffer, extra_line_spacing))
2774 * FRAME_LINE_HEIGHT (it->f));
2775 else if (it->f->extra_line_spacing > 0)
2776 it->extra_line_spacing = it->f->extra_line_spacing;
2779 /* If realized faces have been removed, e.g. because of face
2780 attribute changes of named faces, recompute them. When running
2781 in batch mode, the face cache of the initial frame is null. If
2782 we happen to get called, make a dummy face cache. */
2783 if (FRAME_FACE_CACHE (it->f) == NULL)
2784 init_frame_faces (it->f);
2785 if (FRAME_FACE_CACHE (it->f)->used == 0)
2786 recompute_basic_faces (it->f);
2788 it->override_ascent = -1;
2790 /* Are control characters displayed as `^C'? */
2791 it->ctl_arrow_p = !NILP (BVAR (current_buffer, ctl_arrow));
2793 /* -1 means everything between a CR and the following line end
2794 is invisible. >0 means lines indented more than this value are
2795 invisible. */
2796 it->selective = (INTEGERP (BVAR (current_buffer, selective_display))
2797 ? (clip_to_bounds
2798 (-1, XINT (BVAR (current_buffer, selective_display)),
2799 PTRDIFF_MAX))
2800 : (!NILP (BVAR (current_buffer, selective_display))
2801 ? -1 : 0));
2802 it->selective_display_ellipsis_p
2803 = !NILP (BVAR (current_buffer, selective_display_ellipses));
2805 /* Display table to use. */
2806 it->dp = window_display_table (w);
2808 /* Are multibyte characters enabled in current_buffer? */
2809 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
2811 /* Get the position at which the redisplay_end_trigger hook should
2812 be run, if it is to be run at all. */
2813 if (MARKERP (w->redisplay_end_trigger)
2814 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2815 it->redisplay_end_trigger_charpos
2816 = marker_position (w->redisplay_end_trigger);
2817 else if (INTEGERP (w->redisplay_end_trigger))
2818 it->redisplay_end_trigger_charpos
2819 = clip_to_bounds (PTRDIFF_MIN, XINT (w->redisplay_end_trigger),
2820 PTRDIFF_MAX);
2822 it->tab_width = SANE_TAB_WIDTH (current_buffer);
2824 /* Are lines in the display truncated? */
2825 if (TRUNCATE != 0)
2826 it->line_wrap = TRUNCATE;
2827 if (base_face_id == DEFAULT_FACE_ID
2828 && !it->w->hscroll
2829 && (WINDOW_FULL_WIDTH_P (it->w)
2830 || NILP (Vtruncate_partial_width_windows)
2831 || (INTEGERP (Vtruncate_partial_width_windows)
2832 /* PXW: Shall we do something about this? */
2833 && (XINT (Vtruncate_partial_width_windows)
2834 <= WINDOW_TOTAL_COLS (it->w))))
2835 && NILP (BVAR (current_buffer, truncate_lines)))
2836 it->line_wrap = NILP (BVAR (current_buffer, word_wrap))
2837 ? WINDOW_WRAP : WORD_WRAP;
2839 /* Get dimensions of truncation and continuation glyphs. These are
2840 displayed as fringe bitmaps under X, but we need them for such
2841 frames when the fringes are turned off. But leave the dimensions
2842 zero for tooltip frames, as these glyphs look ugly there and also
2843 sabotage calculations of tooltip dimensions in x-show-tip. */
2844 #ifdef HAVE_WINDOW_SYSTEM
2845 if (!(FRAME_WINDOW_P (it->f)
2846 && FRAMEP (tip_frame)
2847 && it->f == XFRAME (tip_frame)))
2848 #endif
2850 if (it->line_wrap == TRUNCATE)
2852 /* We will need the truncation glyph. */
2853 eassert (it->glyph_row == NULL);
2854 produce_special_glyphs (it, IT_TRUNCATION);
2855 it->truncation_pixel_width = it->pixel_width;
2857 else
2859 /* We will need the continuation glyph. */
2860 eassert (it->glyph_row == NULL);
2861 produce_special_glyphs (it, IT_CONTINUATION);
2862 it->continuation_pixel_width = it->pixel_width;
2866 /* Reset these values to zero because the produce_special_glyphs
2867 above has changed them. */
2868 it->pixel_width = it->ascent = it->descent = 0;
2869 it->phys_ascent = it->phys_descent = 0;
2871 /* Set this after getting the dimensions of truncation and
2872 continuation glyphs, so that we don't produce glyphs when calling
2873 produce_special_glyphs, above. */
2874 it->glyph_row = row;
2875 it->area = TEXT_AREA;
2877 /* Get the dimensions of the display area. The display area
2878 consists of the visible window area plus a horizontally scrolled
2879 part to the left of the window. All x-values are relative to the
2880 start of this total display area. */
2881 if (base_face_id != DEFAULT_FACE_ID)
2883 /* Mode lines, menu bar in terminal frames. */
2884 it->first_visible_x = 0;
2885 it->last_visible_x = WINDOW_PIXEL_WIDTH (w);
2887 else
2889 it->first_visible_x
2890 = window_hscroll_limited (it->w, it->f) * FRAME_COLUMN_WIDTH (it->f);
2891 it->last_visible_x = (it->first_visible_x
2892 + window_box_width (w, TEXT_AREA));
2894 /* If we truncate lines, leave room for the truncation glyph(s) at
2895 the right margin. Otherwise, leave room for the continuation
2896 glyph(s). Done only if the window has no right fringe. */
2897 if (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0)
2899 if (it->line_wrap == TRUNCATE)
2900 it->last_visible_x -= it->truncation_pixel_width;
2901 else
2902 it->last_visible_x -= it->continuation_pixel_width;
2905 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2906 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2909 /* Leave room for a border glyph. */
2910 if (!FRAME_WINDOW_P (it->f)
2911 && !WINDOW_RIGHTMOST_P (it->w))
2912 it->last_visible_x -= 1;
2914 it->last_visible_y = window_text_bottom_y (w);
2916 /* For mode lines and alike, arrange for the first glyph having a
2917 left box line if the face specifies a box. */
2918 if (base_face_id != DEFAULT_FACE_ID)
2920 struct face *face;
2922 it->face_id = remapped_base_face_id;
2924 /* If we have a boxed mode line, make the first character appear
2925 with a left box line. */
2926 face = FACE_FROM_ID_OR_NULL (it->f, remapped_base_face_id);
2927 if (face && face->box != FACE_NO_BOX)
2928 it->start_of_box_run_p = true;
2931 /* If a buffer position was specified, set the iterator there,
2932 getting overlays and face properties from that position. */
2933 if (charpos >= BUF_BEG (current_buffer))
2935 it->stop_charpos = charpos;
2936 it->end_charpos = ZV;
2937 eassert (charpos == BYTE_TO_CHAR (bytepos));
2938 IT_CHARPOS (*it) = charpos;
2939 IT_BYTEPOS (*it) = bytepos;
2941 /* We will rely on `reseat' to set this up properly, via
2942 handle_face_prop. */
2943 it->face_id = it->base_face_id;
2945 it->start = it->current;
2946 /* Do we need to reorder bidirectional text? Not if this is a
2947 unibyte buffer: by definition, none of the single-byte
2948 characters are strong R2L, so no reordering is needed. And
2949 bidi.c doesn't support unibyte buffers anyway. Also, don't
2950 reorder while we are loading loadup.el, since the tables of
2951 character properties needed for reordering are not yet
2952 available. */
2953 it->bidi_p =
2954 !redisplay__inhibit_bidi
2955 && !NILP (BVAR (current_buffer, bidi_display_reordering))
2956 && it->multibyte_p;
2958 /* If we are to reorder bidirectional text, init the bidi
2959 iterator. */
2960 if (it->bidi_p)
2962 /* Since we don't know at this point whether there will be
2963 any R2L lines in the window, we reserve space for
2964 truncation/continuation glyphs even if only the left
2965 fringe is absent. */
2966 if (base_face_id == DEFAULT_FACE_ID
2967 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
2968 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) != 0)
2970 if (it->line_wrap == TRUNCATE)
2971 it->last_visible_x -= it->truncation_pixel_width;
2972 else
2973 it->last_visible_x -= it->continuation_pixel_width;
2975 /* Note the paragraph direction that this buffer wants to
2976 use. */
2977 if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
2978 Qleft_to_right))
2979 it->paragraph_embedding = L2R;
2980 else if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
2981 Qright_to_left))
2982 it->paragraph_embedding = R2L;
2983 else
2984 it->paragraph_embedding = NEUTRAL_DIR;
2985 bidi_unshelve_cache (NULL, false);
2986 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
2987 &it->bidi_it);
2990 /* Compute faces etc. */
2991 reseat (it, it->current.pos, true);
2994 CHECK_IT (it);
2998 /* Initialize IT for the display of window W with window start POS. */
3000 void
3001 start_display (struct it *it, struct window *w, struct text_pos pos)
3003 struct glyph_row *row;
3004 bool first_vpos = WINDOW_WANTS_HEADER_LINE_P (w);
3006 row = w->desired_matrix->rows + first_vpos;
3007 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
3008 it->first_vpos = first_vpos;
3010 /* Don't reseat to previous visible line start if current start
3011 position is in a string or image. */
3012 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
3014 int first_y = it->current_y;
3016 /* If window start is not at a line start, skip forward to POS to
3017 get the correct continuation lines width. */
3018 bool start_at_line_beg_p = (CHARPOS (pos) == BEGV
3019 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
3020 if (!start_at_line_beg_p)
3022 int new_x;
3024 reseat_at_previous_visible_line_start (it);
3025 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
3027 new_x = it->current_x + it->pixel_width;
3029 /* If lines are continued, this line may end in the middle
3030 of a multi-glyph character (e.g. a control character
3031 displayed as \003, or in the middle of an overlay
3032 string). In this case move_it_to above will not have
3033 taken us to the start of the continuation line but to the
3034 end of the continued line. */
3035 if (it->current_x > 0
3036 && it->line_wrap != TRUNCATE /* Lines are continued. */
3037 && (/* And glyph doesn't fit on the line. */
3038 new_x > it->last_visible_x
3039 /* Or it fits exactly and we're on a window
3040 system frame. */
3041 || (new_x == it->last_visible_x
3042 && FRAME_WINDOW_P (it->f)
3043 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
3044 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
3045 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
3047 if ((it->current.dpvec_index >= 0
3048 || it->current.overlay_string_index >= 0)
3049 /* If we are on a newline from a display vector or
3050 overlay string, then we are already at the end of
3051 a screen line; no need to go to the next line in
3052 that case, as this line is not really continued.
3053 (If we do go to the next line, C-e will not DTRT.) */
3054 && it->c != '\n')
3056 set_iterator_to_next (it, true);
3057 move_it_in_display_line_to (it, -1, -1, 0);
3060 it->continuation_lines_width += it->current_x;
3062 /* If the character at POS is displayed via a display
3063 vector, move_it_to above stops at the final glyph of
3064 IT->dpvec. To make the caller redisplay that character
3065 again (a.k.a. start at POS), we need to reset the
3066 dpvec_index to the beginning of IT->dpvec. */
3067 else if (it->current.dpvec_index >= 0)
3068 it->current.dpvec_index = 0;
3070 /* We're starting a new display line, not affected by the
3071 height of the continued line, so clear the appropriate
3072 fields in the iterator structure. */
3073 it->max_ascent = it->max_descent = 0;
3074 it->max_phys_ascent = it->max_phys_descent = 0;
3076 it->current_y = first_y;
3077 it->vpos = 0;
3078 it->current_x = it->hpos = 0;
3084 /* Return true if POS is a position in ellipses displayed for invisible
3085 text. W is the window we display, for text property lookup. */
3087 static bool
3088 in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
3090 Lisp_Object prop, window;
3091 bool ellipses_p = false;
3092 ptrdiff_t charpos = CHARPOS (pos->pos);
3094 /* If POS specifies a position in a display vector, this might
3095 be for an ellipsis displayed for invisible text. We won't
3096 get the iterator set up for delivering that ellipsis unless
3097 we make sure that it gets aware of the invisible text. */
3098 if (pos->dpvec_index >= 0
3099 && pos->overlay_string_index < 0
3100 && CHARPOS (pos->string_pos) < 0
3101 && charpos > BEGV
3102 && (XSETWINDOW (window, w),
3103 prop = Fget_char_property (make_number (charpos),
3104 Qinvisible, window),
3105 TEXT_PROP_MEANS_INVISIBLE (prop) == 0))
3107 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
3108 window);
3109 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
3112 return ellipses_p;
3116 /* Initialize IT for stepping through current_buffer in window W,
3117 starting at position POS that includes overlay string and display
3118 vector/ control character translation position information. Value
3119 is false if there are overlay strings with newlines at POS. */
3121 static bool
3122 init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
3124 ptrdiff_t charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
3125 int i;
3126 bool overlay_strings_with_newlines = false;
3128 /* If POS specifies a position in a display vector, this might
3129 be for an ellipsis displayed for invisible text. We won't
3130 get the iterator set up for delivering that ellipsis unless
3131 we make sure that it gets aware of the invisible text. */
3132 if (in_ellipses_for_invisible_text_p (pos, w))
3134 --charpos;
3135 bytepos = 0;
3138 /* Keep in mind: the call to reseat in init_iterator skips invisible
3139 text, so we might end up at a position different from POS. This
3140 is only a problem when POS is a row start after a newline and an
3141 overlay starts there with an after-string, and the overlay has an
3142 invisible property. Since we don't skip invisible text in
3143 display_line and elsewhere immediately after consuming the
3144 newline before the row start, such a POS will not be in a string,
3145 but the call to init_iterator below will move us to the
3146 after-string. */
3147 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
3149 /* This only scans the current chunk -- it should scan all chunks.
3150 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
3151 to 16 in 22.1 to make this a lesser problem. */
3152 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
3154 const char *s = SSDATA (it->overlay_strings[i]);
3155 const char *e = s + SBYTES (it->overlay_strings[i]);
3157 while (s < e && *s != '\n')
3158 ++s;
3160 if (s < e)
3162 overlay_strings_with_newlines = true;
3163 break;
3167 /* If position is within an overlay string, set up IT to the right
3168 overlay string. */
3169 if (pos->overlay_string_index >= 0)
3171 int relative_index;
3173 /* If the first overlay string happens to have a `display'
3174 property for an image, the iterator will be set up for that
3175 image, and we have to undo that setup first before we can
3176 correct the overlay string index. */
3177 if (it->method == GET_FROM_IMAGE)
3178 pop_it (it);
3180 /* We already have the first chunk of overlay strings in
3181 IT->overlay_strings. Load more until the one for
3182 pos->overlay_string_index is in IT->overlay_strings. */
3183 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
3185 ptrdiff_t n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
3186 it->current.overlay_string_index = 0;
3187 while (n--)
3189 load_overlay_strings (it, 0);
3190 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
3194 it->current.overlay_string_index = pos->overlay_string_index;
3195 relative_index = (it->current.overlay_string_index
3196 % OVERLAY_STRING_CHUNK_SIZE);
3197 it->string = it->overlay_strings[relative_index];
3198 eassert (STRINGP (it->string));
3199 it->current.string_pos = pos->string_pos;
3200 it->method = GET_FROM_STRING;
3201 it->end_charpos = SCHARS (it->string);
3202 /* Set up the bidi iterator for this overlay string. */
3203 if (it->bidi_p)
3205 it->bidi_it.string.lstring = it->string;
3206 it->bidi_it.string.s = NULL;
3207 it->bidi_it.string.schars = SCHARS (it->string);
3208 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
3209 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
3210 it->bidi_it.string.unibyte = !it->multibyte_p;
3211 it->bidi_it.w = it->w;
3212 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3213 FRAME_WINDOW_P (it->f), &it->bidi_it);
3215 /* Synchronize the state of the bidi iterator with
3216 pos->string_pos. For any string position other than
3217 zero, this will be done automagically when we resume
3218 iteration over the string and get_visually_first_element
3219 is called. But if string_pos is zero, and the string is
3220 to be reordered for display, we need to resync manually,
3221 since it could be that the iteration state recorded in
3222 pos ended at string_pos of 0 moving backwards in string. */
3223 if (CHARPOS (pos->string_pos) == 0)
3225 get_visually_first_element (it);
3226 if (IT_STRING_CHARPOS (*it) != 0)
3227 do {
3228 /* Paranoia. */
3229 eassert (it->bidi_it.charpos < it->bidi_it.string.schars);
3230 bidi_move_to_visually_next (&it->bidi_it);
3231 } while (it->bidi_it.charpos != 0);
3233 eassert (IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
3234 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos);
3238 if (CHARPOS (pos->string_pos) >= 0)
3240 /* Recorded position is not in an overlay string, but in another
3241 string. This can only be a string from a `display' property.
3242 IT should already be filled with that string. */
3243 it->current.string_pos = pos->string_pos;
3244 eassert (STRINGP (it->string));
3245 if (it->bidi_p)
3246 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3247 FRAME_WINDOW_P (it->f), &it->bidi_it);
3250 /* Restore position in display vector translations, control
3251 character translations or ellipses. */
3252 if (pos->dpvec_index >= 0)
3254 if (it->dpvec == NULL)
3255 get_next_display_element (it);
3256 eassert (it->dpvec && it->current.dpvec_index == 0);
3257 it->current.dpvec_index = pos->dpvec_index;
3260 CHECK_IT (it);
3261 return !overlay_strings_with_newlines;
3265 /* Initialize IT for stepping through current_buffer in window W
3266 starting at ROW->start. */
3268 static void
3269 init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
3271 init_from_display_pos (it, w, &row->start);
3272 it->start = row->start;
3273 it->continuation_lines_width = row->continuation_lines_width;
3274 CHECK_IT (it);
3278 /* Initialize IT for stepping through current_buffer in window W
3279 starting in the line following ROW, i.e. starting at ROW->end.
3280 Value is false if there are overlay strings with newlines at ROW's
3281 end position. */
3283 static bool
3284 init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
3286 bool success = false;
3288 if (init_from_display_pos (it, w, &row->end))
3290 if (row->continued_p)
3291 it->continuation_lines_width
3292 = row->continuation_lines_width + row->pixel_width;
3293 CHECK_IT (it);
3294 success = true;
3297 return success;
3303 /***********************************************************************
3304 Text properties
3305 ***********************************************************************/
3307 /* Called when IT reaches IT->stop_charpos. Handle text property and
3308 overlay changes. Set IT->stop_charpos to the next position where
3309 to stop. */
3311 static void
3312 handle_stop (struct it *it)
3314 enum prop_handled handled;
3315 bool handle_overlay_change_p;
3316 struct props *p;
3318 it->dpvec = NULL;
3319 it->current.dpvec_index = -1;
3320 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3321 it->ellipsis_p = false;
3323 /* Use face of preceding text for ellipsis (if invisible) */
3324 if (it->selective_display_ellipsis_p)
3325 it->saved_face_id = it->face_id;
3327 /* Here's the description of the semantics of, and the logic behind,
3328 the various HANDLED_* statuses:
3330 HANDLED_NORMALLY means the handler did its job, and the loop
3331 should proceed to calling the next handler in order.
3333 HANDLED_RECOMPUTE_PROPS means the handler caused a significant
3334 change in the properties and overlays at current position, so the
3335 loop should be restarted, to re-invoke the handlers that were
3336 already called. This happens when fontification-functions were
3337 called by handle_fontified_prop, and actually fontified
3338 something. Another case where HANDLED_RECOMPUTE_PROPS is
3339 returned is when we discover overlay strings that need to be
3340 displayed right away. The loop below will continue for as long
3341 as the status is HANDLED_RECOMPUTE_PROPS.
3343 HANDLED_RETURN means return immediately to the caller, to
3344 continue iteration without calling any further handlers. This is
3345 used when we need to act on some property right away, for example
3346 when we need to display the ellipsis or a replacing display
3347 property, such as display string or image.
3349 HANDLED_OVERLAY_STRING_CONSUMED means an overlay string was just
3350 consumed, and the handler switched to the next overlay string.
3351 This signals the loop below to refrain from looking for more
3352 overlays before all the overlay strings of the current overlay
3353 are processed.
3355 Some of the handlers called by the loop push the iterator state
3356 onto the stack (see 'push_it'), and arrange for the iteration to
3357 continue with another object, such as an image, a display string,
3358 or an overlay string. In most such cases, it->stop_charpos is
3359 set to the first character of the string, so that when the
3360 iteration resumes, this function will immediately be called
3361 again, to examine the properties at the beginning of the string.
3363 When a display or overlay string is exhausted, the iterator state
3364 is popped (see 'pop_it'), and iteration continues with the
3365 previous object. Again, in many such cases this function is
3366 called again to find the next position where properties might
3367 change. */
3371 handled = HANDLED_NORMALLY;
3373 /* Call text property handlers. */
3374 for (p = it_props; p->handler; ++p)
3376 handled = p->handler (it);
3378 if (handled == HANDLED_RECOMPUTE_PROPS)
3379 break;
3380 else if (handled == HANDLED_RETURN)
3382 /* We still want to show before and after strings from
3383 overlays even if the actual buffer text is replaced. */
3384 if (!handle_overlay_change_p
3385 || it->sp > 1
3386 /* Don't call get_overlay_strings_1 if we already
3387 have overlay strings loaded, because doing so
3388 will load them again and push the iterator state
3389 onto the stack one more time, which is not
3390 expected by the rest of the code that processes
3391 overlay strings. */
3392 || (it->current.overlay_string_index < 0
3393 && !get_overlay_strings_1 (it, 0, false)))
3395 if (it->ellipsis_p)
3396 setup_for_ellipsis (it, 0);
3397 /* When handling a display spec, we might load an
3398 empty string. In that case, discard it here. We
3399 used to discard it in handle_single_display_spec,
3400 but that causes get_overlay_strings_1, above, to
3401 ignore overlay strings that we must check. */
3402 if (STRINGP (it->string) && !SCHARS (it->string))
3403 pop_it (it);
3404 return;
3406 else if (STRINGP (it->string) && !SCHARS (it->string))
3407 pop_it (it);
3408 else
3410 it->string_from_display_prop_p = false;
3411 it->from_disp_prop_p = false;
3412 handle_overlay_change_p = false;
3414 handled = HANDLED_RECOMPUTE_PROPS;
3415 break;
3417 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3418 handle_overlay_change_p = false;
3421 if (handled != HANDLED_RECOMPUTE_PROPS)
3423 /* Don't check for overlay strings below when set to deliver
3424 characters from a display vector. */
3425 if (it->method == GET_FROM_DISPLAY_VECTOR)
3426 handle_overlay_change_p = false;
3428 /* Handle overlay changes.
3429 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3430 if it finds overlays. */
3431 if (handle_overlay_change_p)
3432 handled = handle_overlay_change (it);
3435 if (it->ellipsis_p)
3437 setup_for_ellipsis (it, 0);
3438 break;
3441 while (handled == HANDLED_RECOMPUTE_PROPS);
3443 /* Determine where to stop next. */
3444 if (handled == HANDLED_NORMALLY)
3445 compute_stop_pos (it);
3449 /* Compute IT->stop_charpos from text property and overlay change
3450 information for IT's current position. */
3452 static void
3453 compute_stop_pos (struct it *it)
3455 register INTERVAL iv, next_iv;
3456 Lisp_Object object, limit, position;
3457 ptrdiff_t charpos, bytepos;
3459 if (STRINGP (it->string))
3461 /* Strings are usually short, so don't limit the search for
3462 properties. */
3463 it->stop_charpos = it->end_charpos;
3464 object = it->string;
3465 limit = Qnil;
3466 charpos = IT_STRING_CHARPOS (*it);
3467 bytepos = IT_STRING_BYTEPOS (*it);
3469 else
3471 ptrdiff_t pos;
3473 /* If end_charpos is out of range for some reason, such as a
3474 misbehaving display function, rationalize it (Bug#5984). */
3475 if (it->end_charpos > ZV)
3476 it->end_charpos = ZV;
3477 it->stop_charpos = it->end_charpos;
3479 /* If next overlay change is in front of the current stop pos
3480 (which is IT->end_charpos), stop there. Note: value of
3481 next_overlay_change is point-max if no overlay change
3482 follows. */
3483 charpos = IT_CHARPOS (*it);
3484 bytepos = IT_BYTEPOS (*it);
3485 pos = next_overlay_change (charpos);
3486 if (pos < it->stop_charpos)
3487 it->stop_charpos = pos;
3489 /* Set up variables for computing the stop position from text
3490 property changes. */
3491 XSETBUFFER (object, current_buffer);
3492 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3495 /* Get the interval containing IT's position. Value is a null
3496 interval if there isn't such an interval. */
3497 position = make_number (charpos);
3498 iv = validate_interval_range (object, &position, &position, false);
3499 if (iv)
3501 Lisp_Object values_here[LAST_PROP_IDX];
3502 struct props *p;
3504 /* Get properties here. */
3505 for (p = it_props; p->handler; ++p)
3506 values_here[p->idx] = textget (iv->plist,
3507 builtin_lisp_symbol (p->name));
3509 /* Look for an interval following iv that has different
3510 properties. */
3511 for (next_iv = next_interval (iv);
3512 (next_iv
3513 && (NILP (limit)
3514 || XFASTINT (limit) > next_iv->position));
3515 next_iv = next_interval (next_iv))
3517 for (p = it_props; p->handler; ++p)
3519 Lisp_Object new_value = textget (next_iv->plist,
3520 builtin_lisp_symbol (p->name));
3521 if (!EQ (values_here[p->idx], new_value))
3522 break;
3525 if (p->handler)
3526 break;
3529 if (next_iv)
3531 if (INTEGERP (limit)
3532 && next_iv->position >= XFASTINT (limit))
3533 /* No text property change up to limit. */
3534 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3535 else
3536 /* Text properties change in next_iv. */
3537 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3541 if (it->cmp_it.id < 0)
3543 ptrdiff_t stoppos = it->end_charpos;
3545 if (it->bidi_p && it->bidi_it.scan_dir < 0)
3546 stoppos = -1;
3547 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3548 stoppos, it->string);
3551 eassert (STRINGP (it->string)
3552 || (it->stop_charpos >= BEGV
3553 && it->stop_charpos >= IT_CHARPOS (*it)));
3557 /* Return the position of the next overlay change after POS in
3558 current_buffer. Value is point-max if no overlay change
3559 follows. This is like `next-overlay-change' but doesn't use
3560 xmalloc. */
3562 static ptrdiff_t
3563 next_overlay_change (ptrdiff_t pos)
3565 ptrdiff_t i, noverlays;
3566 ptrdiff_t endpos;
3567 Lisp_Object *overlays;
3568 USE_SAFE_ALLOCA;
3570 /* Get all overlays at the given position. */
3571 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, true);
3573 /* If any of these overlays ends before endpos,
3574 use its ending point instead. */
3575 for (i = 0; i < noverlays; ++i)
3577 Lisp_Object oend;
3578 ptrdiff_t oendpos;
3580 oend = OVERLAY_END (overlays[i]);
3581 oendpos = OVERLAY_POSITION (oend);
3582 endpos = min (endpos, oendpos);
3585 SAFE_FREE ();
3586 return endpos;
3589 /* How many characters forward to search for a display property or
3590 display string. Searching too far forward makes the bidi display
3591 sluggish, especially in small windows. */
3592 #define MAX_DISP_SCAN 250
3594 /* Return the character position of a display string at or after
3595 position specified by POSITION. If no display string exists at or
3596 after POSITION, return ZV. A display string is either an overlay
3597 with `display' property whose value is a string, or a `display'
3598 text property whose value is a string. STRING is data about the
3599 string to iterate; if STRING->lstring is nil, we are iterating a
3600 buffer. FRAME_WINDOW_P is true when we are displaying a window
3601 on a GUI frame. DISP_PROP is set to zero if we searched
3602 MAX_DISP_SCAN characters forward without finding any display
3603 strings, non-zero otherwise. It is set to 2 if the display string
3604 uses any kind of `(space ...)' spec that will produce a stretch of
3605 white space in the text area. */
3606 ptrdiff_t
3607 compute_display_string_pos (struct text_pos *position,
3608 struct bidi_string_data *string,
3609 struct window *w,
3610 bool frame_window_p, int *disp_prop)
3612 /* OBJECT = nil means current buffer. */
3613 Lisp_Object object, object1;
3614 Lisp_Object pos, spec, limpos;
3615 bool string_p = string && (STRINGP (string->lstring) || string->s);
3616 ptrdiff_t eob = string_p ? string->schars : ZV;
3617 ptrdiff_t begb = string_p ? 0 : BEGV;
3618 ptrdiff_t bufpos, charpos = CHARPOS (*position);
3619 ptrdiff_t lim =
3620 (charpos < eob - MAX_DISP_SCAN) ? charpos + MAX_DISP_SCAN : eob;
3621 struct text_pos tpos;
3622 int rv = 0;
3624 if (string && STRINGP (string->lstring))
3625 object1 = object = string->lstring;
3626 else if (w && !string_p)
3628 XSETWINDOW (object, w);
3629 object1 = Qnil;
3631 else
3632 object1 = object = Qnil;
3634 *disp_prop = 1;
3636 if (charpos >= eob
3637 /* We don't support display properties whose values are strings
3638 that have display string properties. */
3639 || string->from_disp_str
3640 /* C strings cannot have display properties. */
3641 || (string->s && !STRINGP (object)))
3643 *disp_prop = 0;
3644 return eob;
3647 /* If the character at CHARPOS is where the display string begins,
3648 return CHARPOS. */
3649 pos = make_number (charpos);
3650 if (STRINGP (object))
3651 bufpos = string->bufpos;
3652 else
3653 bufpos = charpos;
3654 tpos = *position;
3655 if (!NILP (spec = Fget_char_property (pos, Qdisplay, object))
3656 && (charpos <= begb
3657 || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
3658 object),
3659 spec))
3660 && (rv = handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
3661 frame_window_p)))
3663 if (rv == 2)
3664 *disp_prop = 2;
3665 return charpos;
3668 /* Look forward for the first character with a `display' property
3669 that will replace the underlying text when displayed. */
3670 limpos = make_number (lim);
3671 do {
3672 pos = Fnext_single_char_property_change (pos, Qdisplay, object1, limpos);
3673 CHARPOS (tpos) = XFASTINT (pos);
3674 if (CHARPOS (tpos) >= lim)
3676 *disp_prop = 0;
3677 break;
3679 if (STRINGP (object))
3680 BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos));
3681 else
3682 BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos));
3683 spec = Fget_char_property (pos, Qdisplay, object);
3684 if (!STRINGP (object))
3685 bufpos = CHARPOS (tpos);
3686 } while (NILP (spec)
3687 || !(rv = handle_display_spec (NULL, spec, object, Qnil, &tpos,
3688 bufpos, frame_window_p)));
3689 if (rv == 2)
3690 *disp_prop = 2;
3692 return CHARPOS (tpos);
3695 /* Return the character position of the end of the display string that
3696 started at CHARPOS. If there's no display string at CHARPOS,
3697 return -1. A display string is either an overlay with `display'
3698 property whose value is a string or a `display' text property whose
3699 value is a string. */
3700 ptrdiff_t
3701 compute_display_string_end (ptrdiff_t charpos, struct bidi_string_data *string)
3703 /* OBJECT = nil means current buffer. */
3704 Lisp_Object object =
3705 (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
3706 Lisp_Object pos = make_number (charpos);
3707 ptrdiff_t eob =
3708 (STRINGP (object) || (string && string->s)) ? string->schars : ZV;
3710 if (charpos >= eob || (string->s && !STRINGP (object)))
3711 return eob;
3713 /* It could happen that the display property or overlay was removed
3714 since we found it in compute_display_string_pos above. One way
3715 this can happen is if JIT font-lock was called (through
3716 handle_fontified_prop), and jit-lock-functions remove text
3717 properties or overlays from the portion of buffer that includes
3718 CHARPOS. Muse mode is known to do that, for example. In this
3719 case, we return -1 to the caller, to signal that no display
3720 string is actually present at CHARPOS. See bidi_fetch_char for
3721 how this is handled.
3723 An alternative would be to never look for display properties past
3724 it->stop_charpos. But neither compute_display_string_pos nor
3725 bidi_fetch_char that calls it know or care where the next
3726 stop_charpos is. */
3727 if (NILP (Fget_char_property (pos, Qdisplay, object)))
3728 return -1;
3730 /* Look forward for the first character where the `display' property
3731 changes. */
3732 pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
3734 return XFASTINT (pos);
3739 /***********************************************************************
3740 Fontification
3741 ***********************************************************************/
3743 /* Handle changes in the `fontified' property of the current buffer by
3744 calling hook functions from Qfontification_functions to fontify
3745 regions of text. */
3747 static enum prop_handled
3748 handle_fontified_prop (struct it *it)
3750 Lisp_Object prop, pos;
3751 enum prop_handled handled = HANDLED_NORMALLY;
3753 if (!NILP (Vmemory_full))
3754 return handled;
3756 /* Get the value of the `fontified' property at IT's current buffer
3757 position. (The `fontified' property doesn't have a special
3758 meaning in strings.) If the value is nil, call functions from
3759 Qfontification_functions. */
3760 if (!STRINGP (it->string)
3761 && it->s == NULL
3762 && !NILP (Vfontification_functions)
3763 && !NILP (Vrun_hooks)
3764 && (pos = make_number (IT_CHARPOS (*it)),
3765 prop = Fget_char_property (pos, Qfontified, Qnil),
3766 /* Ignore the special cased nil value always present at EOB since
3767 no amount of fontifying will be able to change it. */
3768 NILP (prop) && IT_CHARPOS (*it) < Z))
3770 ptrdiff_t count = SPECPDL_INDEX ();
3771 Lisp_Object val;
3772 struct buffer *obuf = current_buffer;
3773 ptrdiff_t begv = BEGV, zv = ZV;
3774 bool old_clip_changed = current_buffer->clip_changed;
3776 val = Vfontification_functions;
3777 specbind (Qfontification_functions, Qnil);
3779 eassert (it->end_charpos == ZV);
3781 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3782 safe_call1 (val, pos);
3783 else
3785 Lisp_Object fns, fn;
3787 fns = Qnil;
3789 for (; CONSP (val); val = XCDR (val))
3791 fn = XCAR (val);
3793 if (EQ (fn, Qt))
3795 /* A value of t indicates this hook has a local
3796 binding; it means to run the global binding too.
3797 In a global value, t should not occur. If it
3798 does, we must ignore it to avoid an endless
3799 loop. */
3800 for (fns = Fdefault_value (Qfontification_functions);
3801 CONSP (fns);
3802 fns = XCDR (fns))
3804 fn = XCAR (fns);
3805 if (!EQ (fn, Qt))
3806 safe_call1 (fn, pos);
3809 else
3810 safe_call1 (fn, pos);
3814 unbind_to (count, Qnil);
3816 /* Fontification functions routinely call `save-restriction'.
3817 Normally, this tags clip_changed, which can confuse redisplay
3818 (see discussion in Bug#6671). Since we don't perform any
3819 special handling of fontification changes in the case where
3820 `save-restriction' isn't called, there's no point doing so in
3821 this case either. So, if the buffer's restrictions are
3822 actually left unchanged, reset clip_changed. */
3823 if (obuf == current_buffer)
3825 if (begv == BEGV && zv == ZV)
3826 current_buffer->clip_changed = old_clip_changed;
3828 /* There isn't much we can reasonably do to protect against
3829 misbehaving fontification, but here's a fig leaf. */
3830 else if (BUFFER_LIVE_P (obuf))
3831 set_buffer_internal_1 (obuf);
3833 /* The fontification code may have added/removed text.
3834 It could do even a lot worse, but let's at least protect against
3835 the most obvious case where only the text past `pos' gets changed',
3836 as is/was done in grep.el where some escapes sequences are turned
3837 into face properties (bug#7876). */
3838 it->end_charpos = ZV;
3840 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3841 something. This avoids an endless loop if they failed to
3842 fontify the text for which reason ever. */
3843 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3844 handled = HANDLED_RECOMPUTE_PROPS;
3847 return handled;
3852 /***********************************************************************
3853 Faces
3854 ***********************************************************************/
3856 /* Set up iterator IT from face properties at its current position.
3857 Called from handle_stop. */
3859 static enum prop_handled
3860 handle_face_prop (struct it *it)
3862 int new_face_id;
3863 ptrdiff_t next_stop;
3865 if (!STRINGP (it->string))
3867 new_face_id
3868 = face_at_buffer_position (it->w,
3869 IT_CHARPOS (*it),
3870 &next_stop,
3871 (IT_CHARPOS (*it)
3872 + TEXT_PROP_DISTANCE_LIMIT),
3873 false, it->base_face_id);
3875 /* Is this a start of a run of characters with box face?
3876 Caveat: this can be called for a freshly initialized
3877 iterator; face_id is -1 in this case. We know that the new
3878 face will not change until limit, i.e. if the new face has a
3879 box, all characters up to limit will have one. But, as
3880 usual, we don't know whether limit is really the end. */
3881 if (new_face_id != it->face_id)
3883 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3884 /* If it->face_id is -1, old_face below will be NULL, see
3885 the definition of FACE_FROM_ID_OR_NULL. This will happen
3886 if this is the initial call that gets the face. */
3887 struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id);
3889 /* If the value of face_id of the iterator is -1, we have to
3890 look in front of IT's position and see whether there is a
3891 face there that's different from new_face_id. */
3892 if (!old_face && IT_CHARPOS (*it) > BEG)
3894 int prev_face_id = face_before_it_pos (it);
3896 old_face = FACE_FROM_ID_OR_NULL (it->f, prev_face_id);
3899 /* If the new face has a box, but the old face does not,
3900 this is the start of a run of characters with box face,
3901 i.e. this character has a shadow on the left side. */
3902 it->start_of_box_run_p = (new_face->box != FACE_NO_BOX
3903 && (old_face == NULL || !old_face->box));
3904 it->face_box_p = new_face->box != FACE_NO_BOX;
3907 else
3909 int base_face_id;
3910 ptrdiff_t bufpos;
3911 int i;
3912 Lisp_Object from_overlay
3913 = (it->current.overlay_string_index >= 0
3914 ? it->string_overlays[it->current.overlay_string_index
3915 % OVERLAY_STRING_CHUNK_SIZE]
3916 : Qnil);
3918 /* See if we got to this string directly or indirectly from
3919 an overlay property. That includes the before-string or
3920 after-string of an overlay, strings in display properties
3921 provided by an overlay, their text properties, etc.
3923 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3924 if (! NILP (from_overlay))
3925 for (i = it->sp - 1; i >= 0; i--)
3927 if (it->stack[i].current.overlay_string_index >= 0)
3928 from_overlay
3929 = it->string_overlays[it->stack[i].current.overlay_string_index
3930 % OVERLAY_STRING_CHUNK_SIZE];
3931 else if (! NILP (it->stack[i].from_overlay))
3932 from_overlay = it->stack[i].from_overlay;
3934 if (!NILP (from_overlay))
3935 break;
3938 if (! NILP (from_overlay))
3940 bufpos = IT_CHARPOS (*it);
3941 /* For a string from an overlay, the base face depends
3942 only on text properties and ignores overlays. */
3943 base_face_id
3944 = face_for_overlay_string (it->w,
3945 IT_CHARPOS (*it),
3946 &next_stop,
3947 (IT_CHARPOS (*it)
3948 + TEXT_PROP_DISTANCE_LIMIT),
3949 false,
3950 from_overlay);
3952 else
3954 bufpos = 0;
3956 /* For strings from a `display' property, use the face at
3957 IT's current buffer position as the base face to merge
3958 with, so that overlay strings appear in the same face as
3959 surrounding text, unless they specify their own faces.
3960 For strings from wrap-prefix and line-prefix properties,
3961 use the default face, possibly remapped via
3962 Vface_remapping_alist. */
3963 /* Note that the fact that we use the face at _buffer_
3964 position means that a 'display' property on an overlay
3965 string will not inherit the face of that overlay string,
3966 but will instead revert to the face of buffer text
3967 covered by the overlay. This is visible, e.g., when the
3968 overlay specifies a box face, but neither the buffer nor
3969 the display string do. This sounds like a design bug,
3970 but Emacs always did that since v21.1, so changing that
3971 might be a big deal. */
3972 base_face_id = it->string_from_prefix_prop_p
3973 ? (!NILP (Vface_remapping_alist)
3974 ? lookup_basic_face (it->f, DEFAULT_FACE_ID)
3975 : DEFAULT_FACE_ID)
3976 : underlying_face_id (it);
3979 new_face_id = face_at_string_position (it->w,
3980 it->string,
3981 IT_STRING_CHARPOS (*it),
3982 bufpos,
3983 &next_stop,
3984 base_face_id, false);
3986 /* Is this a start of a run of characters with box? Caveat:
3987 this can be called for a freshly allocated iterator; face_id
3988 is -1 is this case. We know that the new face will not
3989 change until the next check pos, i.e. if the new face has a
3990 box, all characters up to that position will have a
3991 box. But, as usual, we don't know whether that position
3992 is really the end. */
3993 if (new_face_id != it->face_id)
3995 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3996 struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id);
3998 /* If new face has a box but old face hasn't, this is the
3999 start of a run of characters with box, i.e. it has a
4000 shadow on the left side. */
4001 it->start_of_box_run_p
4002 = new_face->box && (old_face == NULL || !old_face->box);
4003 it->face_box_p = new_face->box != FACE_NO_BOX;
4007 it->face_id = new_face_id;
4008 return HANDLED_NORMALLY;
4012 /* Return the ID of the face ``underlying'' IT's current position,
4013 which is in a string. If the iterator is associated with a
4014 buffer, return the face at IT's current buffer position.
4015 Otherwise, use the iterator's base_face_id. */
4017 static int
4018 underlying_face_id (struct it *it)
4020 int face_id = it->base_face_id, i;
4022 eassert (STRINGP (it->string));
4024 for (i = it->sp - 1; i >= 0; --i)
4025 if (NILP (it->stack[i].string))
4026 face_id = it->stack[i].face_id;
4028 return face_id;
4032 /* Compute the face one character before or after the current position
4033 of IT, in the visual order. BEFORE_P means get the face
4034 in front (to the left in L2R paragraphs, to the right in R2L
4035 paragraphs) of IT's screen position. Value is the ID of the face. */
4037 static int
4038 face_before_or_after_it_pos (struct it *it, bool before_p)
4040 int face_id, limit;
4041 ptrdiff_t next_check_charpos;
4042 struct it it_copy;
4043 void *it_copy_data = NULL;
4045 eassert (it->s == NULL);
4047 if (STRINGP (it->string))
4049 ptrdiff_t bufpos, charpos;
4050 int base_face_id;
4052 /* No face change past the end of the string (for the case
4053 we are padding with spaces). No face change before the
4054 string start. */
4055 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
4056 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
4057 return it->face_id;
4059 if (!it->bidi_p)
4061 /* Set charpos to the position before or after IT's current
4062 position, in the logical order, which in the non-bidi
4063 case is the same as the visual order. */
4064 if (before_p)
4065 charpos = IT_STRING_CHARPOS (*it) - 1;
4066 else if (it->what == IT_COMPOSITION)
4067 /* For composition, we must check the character after the
4068 composition. */
4069 charpos = IT_STRING_CHARPOS (*it) + it->cmp_it.nchars;
4070 else
4071 charpos = IT_STRING_CHARPOS (*it) + 1;
4073 else
4075 if (before_p)
4077 /* With bidi iteration, the character before the current
4078 in the visual order cannot be found by simple
4079 iteration, because "reverse" reordering is not
4080 supported. Instead, we need to start from the string
4081 beginning and go all the way to the current string
4082 position, remembering the previous position. */
4083 /* Ignore face changes before the first visible
4084 character on this display line. */
4085 if (it->current_x <= it->first_visible_x)
4086 return it->face_id;
4087 SAVE_IT (it_copy, *it, it_copy_data);
4088 IT_STRING_CHARPOS (it_copy) = 0;
4089 bidi_init_it (0, 0, FRAME_WINDOW_P (it_copy.f), &it_copy.bidi_it);
4093 charpos = IT_STRING_CHARPOS (it_copy);
4094 if (charpos >= SCHARS (it->string))
4095 break;
4096 bidi_move_to_visually_next (&it_copy.bidi_it);
4098 while (IT_STRING_CHARPOS (it_copy) != IT_STRING_CHARPOS (*it));
4100 RESTORE_IT (it, it, it_copy_data);
4102 else
4104 /* Set charpos to the string position of the character
4105 that comes after IT's current position in the visual
4106 order. */
4107 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4109 it_copy = *it;
4110 while (n--)
4111 bidi_move_to_visually_next (&it_copy.bidi_it);
4113 charpos = it_copy.bidi_it.charpos;
4116 eassert (0 <= charpos && charpos <= SCHARS (it->string));
4118 if (it->current.overlay_string_index >= 0)
4119 bufpos = IT_CHARPOS (*it);
4120 else
4121 bufpos = 0;
4123 base_face_id = underlying_face_id (it);
4125 /* Get the face for ASCII, or unibyte. */
4126 face_id = face_at_string_position (it->w,
4127 it->string,
4128 charpos,
4129 bufpos,
4130 &next_check_charpos,
4131 base_face_id, false);
4133 /* Correct the face for charsets different from ASCII. Do it
4134 for the multibyte case only. The face returned above is
4135 suitable for unibyte text if IT->string is unibyte. */
4136 if (STRING_MULTIBYTE (it->string))
4138 struct text_pos pos1 = string_pos (charpos, it->string);
4139 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos1);
4140 int c, len;
4141 struct face *face = FACE_FROM_ID (it->f, face_id);
4143 c = string_char_and_length (p, &len);
4144 face_id = FACE_FOR_CHAR (it->f, face, c, charpos, it->string);
4147 else
4149 struct text_pos pos;
4151 if ((IT_CHARPOS (*it) >= ZV && !before_p)
4152 || (IT_CHARPOS (*it) <= BEGV && before_p))
4153 return it->face_id;
4155 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
4156 pos = it->current.pos;
4158 if (!it->bidi_p)
4160 if (before_p)
4161 DEC_TEXT_POS (pos, it->multibyte_p);
4162 else
4164 if (it->what == IT_COMPOSITION)
4166 /* For composition, we must check the position after
4167 the composition. */
4168 pos.charpos += it->cmp_it.nchars;
4169 pos.bytepos += it->len;
4171 else
4172 INC_TEXT_POS (pos, it->multibyte_p);
4175 else
4177 if (before_p)
4179 int current_x;
4181 /* With bidi iteration, the character before the current
4182 in the visual order cannot be found by simple
4183 iteration, because "reverse" reordering is not
4184 supported. Instead, we need to use the move_it_*
4185 family of functions, and move to the previous
4186 character starting from the beginning of the visual
4187 line. */
4188 /* Ignore face changes before the first visible
4189 character on this display line. */
4190 if (it->current_x <= it->first_visible_x)
4191 return it->face_id;
4192 SAVE_IT (it_copy, *it, it_copy_data);
4193 /* Implementation note: Since move_it_in_display_line
4194 works in the iterator geometry, and thinks the first
4195 character is always the leftmost, even in R2L lines,
4196 we don't need to distinguish between the R2L and L2R
4197 cases here. */
4198 current_x = it_copy.current_x;
4199 move_it_vertically_backward (&it_copy, 0);
4200 move_it_in_display_line (&it_copy, ZV, current_x - 1, MOVE_TO_X);
4201 pos = it_copy.current.pos;
4202 RESTORE_IT (it, it, it_copy_data);
4204 else
4206 /* Set charpos to the buffer position of the character
4207 that comes after IT's current position in the visual
4208 order. */
4209 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4211 it_copy = *it;
4212 while (n--)
4213 bidi_move_to_visually_next (&it_copy.bidi_it);
4215 SET_TEXT_POS (pos,
4216 it_copy.bidi_it.charpos, it_copy.bidi_it.bytepos);
4219 eassert (BEGV <= CHARPOS (pos) && CHARPOS (pos) <= ZV);
4221 /* Determine face for CHARSET_ASCII, or unibyte. */
4222 face_id = face_at_buffer_position (it->w,
4223 CHARPOS (pos),
4224 &next_check_charpos,
4225 limit, false, -1);
4227 /* Correct the face for charsets different from ASCII. Do it
4228 for the multibyte case only. The face returned above is
4229 suitable for unibyte text if current_buffer is unibyte. */
4230 if (it->multibyte_p)
4232 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
4233 struct face *face = FACE_FROM_ID (it->f, face_id);
4234 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
4238 return face_id;
4243 /***********************************************************************
4244 Invisible text
4245 ***********************************************************************/
4247 /* Set up iterator IT from invisible properties at its current
4248 position. Called from handle_stop. */
4250 static enum prop_handled
4251 handle_invisible_prop (struct it *it)
4253 enum prop_handled handled = HANDLED_NORMALLY;
4254 int invis;
4255 Lisp_Object prop;
4257 if (STRINGP (it->string))
4259 Lisp_Object end_charpos, limit;
4261 /* Get the value of the invisible text property at the
4262 current position. Value will be nil if there is no such
4263 property. */
4264 end_charpos = make_number (IT_STRING_CHARPOS (*it));
4265 prop = Fget_text_property (end_charpos, Qinvisible, it->string);
4266 invis = TEXT_PROP_MEANS_INVISIBLE (prop);
4268 if (invis != 0 && IT_STRING_CHARPOS (*it) < it->end_charpos)
4270 /* Record whether we have to display an ellipsis for the
4271 invisible text. */
4272 bool display_ellipsis_p = (invis == 2);
4273 ptrdiff_t len, endpos;
4275 handled = HANDLED_RECOMPUTE_PROPS;
4277 /* Get the position at which the next visible text can be
4278 found in IT->string, if any. */
4279 endpos = len = SCHARS (it->string);
4280 XSETINT (limit, len);
4283 end_charpos
4284 = Fnext_single_property_change (end_charpos, Qinvisible,
4285 it->string, limit);
4286 /* Since LIMIT is always an integer, so should be the
4287 value returned by Fnext_single_property_change. */
4288 eassert (INTEGERP (end_charpos));
4289 if (INTEGERP (end_charpos))
4291 endpos = XFASTINT (end_charpos);
4292 prop = Fget_text_property (end_charpos, Qinvisible, it->string);
4293 invis = TEXT_PROP_MEANS_INVISIBLE (prop);
4294 if (invis == 2)
4295 display_ellipsis_p = true;
4297 else /* Should never happen; but if it does, exit the loop. */
4298 endpos = len;
4300 while (invis != 0 && endpos < len);
4302 if (display_ellipsis_p)
4303 it->ellipsis_p = true;
4305 if (endpos < len)
4307 /* Text at END_CHARPOS is visible. Move IT there. */
4308 struct text_pos old;
4309 ptrdiff_t oldpos;
4311 old = it->current.string_pos;
4312 oldpos = CHARPOS (old);
4313 if (it->bidi_p)
4315 if (it->bidi_it.first_elt
4316 && it->bidi_it.charpos < SCHARS (it->string))
4317 bidi_paragraph_init (it->paragraph_embedding,
4318 &it->bidi_it, true);
4319 /* Bidi-iterate out of the invisible text. */
4322 bidi_move_to_visually_next (&it->bidi_it);
4324 while (oldpos <= it->bidi_it.charpos
4325 && it->bidi_it.charpos < endpos);
4327 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
4328 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
4329 if (IT_CHARPOS (*it) >= endpos)
4330 it->prev_stop = endpos;
4332 else
4334 IT_STRING_CHARPOS (*it) = endpos;
4335 compute_string_pos (&it->current.string_pos, old, it->string);
4338 else
4340 /* The rest of the string is invisible. If this is an
4341 overlay string, proceed with the next overlay string
4342 or whatever comes and return a character from there. */
4343 if (it->current.overlay_string_index >= 0
4344 && !display_ellipsis_p)
4346 next_overlay_string (it);
4347 /* Don't check for overlay strings when we just
4348 finished processing them. */
4349 handled = HANDLED_OVERLAY_STRING_CONSUMED;
4351 else
4353 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
4354 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
4359 else
4361 ptrdiff_t newpos, next_stop, start_charpos, tem;
4362 Lisp_Object pos, overlay;
4364 /* First of all, is there invisible text at this position? */
4365 tem = start_charpos = IT_CHARPOS (*it);
4366 pos = make_number (tem);
4367 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
4368 &overlay);
4369 invis = TEXT_PROP_MEANS_INVISIBLE (prop);
4371 /* If we are on invisible text, skip over it. */
4372 if (invis != 0 && start_charpos < it->end_charpos)
4374 /* Record whether we have to display an ellipsis for the
4375 invisible text. */
4376 bool display_ellipsis_p = invis == 2;
4378 handled = HANDLED_RECOMPUTE_PROPS;
4380 /* Loop skipping over invisible text. The loop is left at
4381 ZV or with IT on the first char being visible again. */
4384 /* Try to skip some invisible text. Return value is the
4385 position reached which can be equal to where we start
4386 if there is nothing invisible there. This skips both
4387 over invisible text properties and overlays with
4388 invisible property. */
4389 newpos = skip_invisible (tem, &next_stop, ZV, it->window);
4391 /* If we skipped nothing at all we weren't at invisible
4392 text in the first place. If everything to the end of
4393 the buffer was skipped, end the loop. */
4394 if (newpos == tem || newpos >= ZV)
4395 invis = 0;
4396 else
4398 /* We skipped some characters but not necessarily
4399 all there are. Check if we ended up on visible
4400 text. Fget_char_property returns the property of
4401 the char before the given position, i.e. if we
4402 get invis = 0, this means that the char at
4403 newpos is visible. */
4404 pos = make_number (newpos);
4405 prop = Fget_char_property (pos, Qinvisible, it->window);
4406 invis = TEXT_PROP_MEANS_INVISIBLE (prop);
4409 /* If we ended up on invisible text, proceed to
4410 skip starting with next_stop. */
4411 if (invis != 0)
4412 tem = next_stop;
4414 /* If there are adjacent invisible texts, don't lose the
4415 second one's ellipsis. */
4416 if (invis == 2)
4417 display_ellipsis_p = true;
4419 while (invis != 0);
4421 /* The position newpos is now either ZV or on visible text. */
4422 if (it->bidi_p)
4424 ptrdiff_t bpos = CHAR_TO_BYTE (newpos);
4425 bool on_newline
4426 = bpos == ZV_BYTE || FETCH_BYTE (bpos) == '\n';
4427 bool after_newline
4428 = newpos <= BEGV || FETCH_BYTE (bpos - 1) == '\n';
4430 /* If the invisible text ends on a newline or on a
4431 character after a newline, we can avoid the costly,
4432 character by character, bidi iteration to NEWPOS, and
4433 instead simply reseat the iterator there. That's
4434 because all bidi reordering information is tossed at
4435 the newline. This is a big win for modes that hide
4436 complete lines, like Outline, Org, etc. */
4437 if (on_newline || after_newline)
4439 struct text_pos tpos;
4440 bidi_dir_t pdir = it->bidi_it.paragraph_dir;
4442 SET_TEXT_POS (tpos, newpos, bpos);
4443 reseat_1 (it, tpos, false);
4444 /* If we reseat on a newline/ZV, we need to prep the
4445 bidi iterator for advancing to the next character
4446 after the newline/EOB, keeping the current paragraph
4447 direction (so that PRODUCE_GLYPHS does TRT wrt
4448 prepending/appending glyphs to a glyph row). */
4449 if (on_newline)
4451 it->bidi_it.first_elt = false;
4452 it->bidi_it.paragraph_dir = pdir;
4453 it->bidi_it.ch = (bpos == ZV_BYTE) ? -1 : '\n';
4454 it->bidi_it.nchars = 1;
4455 it->bidi_it.ch_len = 1;
4458 else /* Must use the slow method. */
4460 /* With bidi iteration, the region of invisible text
4461 could start and/or end in the middle of a
4462 non-base embedding level. Therefore, we need to
4463 skip invisible text using the bidi iterator,
4464 starting at IT's current position, until we find
4465 ourselves outside of the invisible text.
4466 Skipping invisible text _after_ bidi iteration
4467 avoids affecting the visual order of the
4468 displayed text when invisible properties are
4469 added or removed. */
4470 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
4472 /* If we were `reseat'ed to a new paragraph,
4473 determine the paragraph base direction. We
4474 need to do it now because
4475 next_element_from_buffer may not have a
4476 chance to do it, if we are going to skip any
4477 text at the beginning, which resets the
4478 FIRST_ELT flag. */
4479 bidi_paragraph_init (it->paragraph_embedding,
4480 &it->bidi_it, true);
4484 bidi_move_to_visually_next (&it->bidi_it);
4486 while (it->stop_charpos <= it->bidi_it.charpos
4487 && it->bidi_it.charpos < newpos);
4488 IT_CHARPOS (*it) = it->bidi_it.charpos;
4489 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
4490 /* If we overstepped NEWPOS, record its position in
4491 the iterator, so that we skip invisible text if
4492 later the bidi iteration lands us in the
4493 invisible region again. */
4494 if (IT_CHARPOS (*it) >= newpos)
4495 it->prev_stop = newpos;
4498 else
4500 IT_CHARPOS (*it) = newpos;
4501 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
4504 if (display_ellipsis_p)
4506 /* Make sure that the glyphs of the ellipsis will get
4507 correct `charpos' values. If we would not update
4508 it->position here, the glyphs would belong to the
4509 last visible character _before_ the invisible
4510 text, which confuses `set_cursor_from_row'.
4512 We use the last invisible position instead of the
4513 first because this way the cursor is always drawn on
4514 the first "." of the ellipsis, whenever PT is inside
4515 the invisible text. Otherwise the cursor would be
4516 placed _after_ the ellipsis when the point is after the
4517 first invisible character. */
4518 if (!STRINGP (it->object))
4520 it->position.charpos = newpos - 1;
4521 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
4525 /* If there are before-strings at the start of invisible
4526 text, and the text is invisible because of a text
4527 property, arrange to show before-strings because 20.x did
4528 it that way. (If the text is invisible because of an
4529 overlay property instead of a text property, this is
4530 already handled in the overlay code.) */
4531 if (NILP (overlay)
4532 && get_overlay_strings (it, it->stop_charpos))
4534 handled = HANDLED_RECOMPUTE_PROPS;
4535 if (it->sp > 0)
4537 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
4538 /* The call to get_overlay_strings above recomputes
4539 it->stop_charpos, but it only considers changes
4540 in properties and overlays beyond iterator's
4541 current position. This causes us to miss changes
4542 that happen exactly where the invisible property
4543 ended. So we play it safe here and force the
4544 iterator to check for potential stop positions
4545 immediately after the invisible text. Note that
4546 if get_overlay_strings returns true, it
4547 normally also pushed the iterator stack, so we
4548 need to update the stop position in the slot
4549 below the current one. */
4550 it->stack[it->sp - 1].stop_charpos
4551 = CHARPOS (it->stack[it->sp - 1].current.pos);
4554 else if (display_ellipsis_p)
4556 it->ellipsis_p = true;
4557 /* Let the ellipsis display before
4558 considering any properties of the following char.
4559 Fixes jasonr@gnu.org 01 Oct 07 bug. */
4560 handled = HANDLED_RETURN;
4565 return handled;
4569 /* Make iterator IT return `...' next.
4570 Replaces LEN characters from buffer. */
4572 static void
4573 setup_for_ellipsis (struct it *it, int len)
4575 /* Use the display table definition for `...'. Invalid glyphs
4576 will be handled by the method returning elements from dpvec. */
4577 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
4579 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
4580 it->dpvec = v->contents;
4581 it->dpend = v->contents + v->header.size;
4583 else
4585 /* Default `...'. */
4586 it->dpvec = default_invis_vector;
4587 it->dpend = default_invis_vector + 3;
4590 it->dpvec_char_len = len;
4591 it->current.dpvec_index = 0;
4592 it->dpvec_face_id = -1;
4594 /* Use IT->saved_face_id for the ellipsis, so that it has the same
4595 face as the preceding text. IT->saved_face_id was set in
4596 handle_stop to the face of the preceding character, and will be
4597 different from IT->face_id only if the invisible text skipped in
4598 handle_invisible_prop has some non-default face on its first
4599 character. We thus ignore the face of the invisible text when we
4600 display the ellipsis. IT's face is restored in set_iterator_to_next. */
4601 if (it->saved_face_id >= 0)
4602 it->face_id = it->saved_face_id;
4604 /* If the ellipsis represents buffer text, it means we advanced in
4605 the buffer, so we should no longer ignore overlay strings. */
4606 if (it->method == GET_FROM_BUFFER)
4607 it->ignore_overlay_strings_at_pos_p = false;
4609 it->method = GET_FROM_DISPLAY_VECTOR;
4610 it->ellipsis_p = true;
4615 /***********************************************************************
4616 'display' property
4617 ***********************************************************************/
4619 /* Set up iterator IT from `display' property at its current position.
4620 Called from handle_stop.
4621 We return HANDLED_RETURN if some part of the display property
4622 overrides the display of the buffer text itself.
4623 Otherwise we return HANDLED_NORMALLY. */
4625 static enum prop_handled
4626 handle_display_prop (struct it *it)
4628 Lisp_Object propval, object, overlay;
4629 struct text_pos *position;
4630 ptrdiff_t bufpos;
4631 /* Nonzero if some property replaces the display of the text itself. */
4632 int display_replaced = 0;
4634 if (STRINGP (it->string))
4636 object = it->string;
4637 position = &it->current.string_pos;
4638 bufpos = CHARPOS (it->current.pos);
4640 else
4642 XSETWINDOW (object, it->w);
4643 position = &it->current.pos;
4644 bufpos = CHARPOS (*position);
4647 /* Reset those iterator values set from display property values. */
4648 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
4649 it->space_width = Qnil;
4650 it->font_height = Qnil;
4651 it->voffset = 0;
4653 /* We don't support recursive `display' properties, i.e. string
4654 values that have a string `display' property, that have a string
4655 `display' property etc. */
4656 if (!it->string_from_display_prop_p)
4657 it->area = TEXT_AREA;
4659 propval = get_char_property_and_overlay (make_number (position->charpos),
4660 Qdisplay, object, &overlay);
4661 if (NILP (propval))
4662 return HANDLED_NORMALLY;
4663 /* Now OVERLAY is the overlay that gave us this property, or nil
4664 if it was a text property. */
4666 if (!STRINGP (it->string))
4667 object = it->w->contents;
4669 display_replaced = handle_display_spec (it, propval, object, overlay,
4670 position, bufpos,
4671 FRAME_WINDOW_P (it->f));
4672 return display_replaced != 0 ? HANDLED_RETURN : HANDLED_NORMALLY;
4675 /* Subroutine of handle_display_prop. Returns non-zero if the display
4676 specification in SPEC is a replacing specification, i.e. it would
4677 replace the text covered by `display' property with something else,
4678 such as an image or a display string. If SPEC includes any kind or
4679 `(space ...) specification, the value is 2; this is used by
4680 compute_display_string_pos, which see.
4682 See handle_single_display_spec for documentation of arguments.
4683 FRAME_WINDOW_P is true if the window being redisplayed is on a
4684 GUI frame; this argument is used only if IT is NULL, see below.
4686 IT can be NULL, if this is called by the bidi reordering code
4687 through compute_display_string_pos, which see. In that case, this
4688 function only examines SPEC, but does not otherwise "handle" it, in
4689 the sense that it doesn't set up members of IT from the display
4690 spec. */
4691 static int
4692 handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4693 Lisp_Object overlay, struct text_pos *position,
4694 ptrdiff_t bufpos, bool frame_window_p)
4696 int replacing = 0;
4698 if (CONSP (spec)
4699 /* Simple specifications. */
4700 && !EQ (XCAR (spec), Qimage)
4701 #ifdef HAVE_XWIDGETS
4702 && !EQ (XCAR (spec), Qxwidget)
4703 #endif
4704 && !EQ (XCAR (spec), Qspace)
4705 && !EQ (XCAR (spec), Qwhen)
4706 && !EQ (XCAR (spec), Qslice)
4707 && !EQ (XCAR (spec), Qspace_width)
4708 && !EQ (XCAR (spec), Qheight)
4709 && !EQ (XCAR (spec), Qraise)
4710 /* Marginal area specifications. */
4711 && !(CONSP (XCAR (spec)) && EQ (XCAR (XCAR (spec)), Qmargin))
4712 && !EQ (XCAR (spec), Qleft_fringe)
4713 && !EQ (XCAR (spec), Qright_fringe)
4714 && !NILP (XCAR (spec)))
4716 for (; CONSP (spec); spec = XCDR (spec))
4718 int rv = handle_single_display_spec (it, XCAR (spec), object,
4719 overlay, position, bufpos,
4720 replacing, frame_window_p);
4721 if (rv != 0)
4723 replacing = rv;
4724 /* If some text in a string is replaced, `position' no
4725 longer points to the position of `object'. */
4726 if (!it || STRINGP (object))
4727 break;
4731 else if (VECTORP (spec))
4733 ptrdiff_t i;
4734 for (i = 0; i < ASIZE (spec); ++i)
4736 int rv = handle_single_display_spec (it, AREF (spec, i), object,
4737 overlay, position, bufpos,
4738 replacing, frame_window_p);
4739 if (rv != 0)
4741 replacing = rv;
4742 /* If some text in a string is replaced, `position' no
4743 longer points to the position of `object'. */
4744 if (!it || STRINGP (object))
4745 break;
4749 else
4750 replacing = handle_single_display_spec (it, spec, object, overlay, position,
4751 bufpos, 0, frame_window_p);
4752 return replacing;
4755 /* Value is the position of the end of the `display' property starting
4756 at START_POS in OBJECT. */
4758 static struct text_pos
4759 display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
4761 Lisp_Object end;
4762 struct text_pos end_pos;
4764 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
4765 Qdisplay, object, Qnil);
4766 CHARPOS (end_pos) = XFASTINT (end);
4767 if (STRINGP (object))
4768 compute_string_pos (&end_pos, start_pos, it->string);
4769 else
4770 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
4772 return end_pos;
4776 /* Set up IT from a single `display' property specification SPEC. OBJECT
4777 is the object in which the `display' property was found. *POSITION
4778 is the position in OBJECT at which the `display' property was found.
4779 BUFPOS is the buffer position of OBJECT (different from POSITION if
4780 OBJECT is not a buffer). DISPLAY_REPLACED non-zero means that we
4781 previously saw a display specification which already replaced text
4782 display with something else, for example an image; we ignore such
4783 properties after the first one has been processed.
4785 OVERLAY is the overlay this `display' property came from,
4786 or nil if it was a text property.
4788 If SPEC is a `space' or `image' specification, and in some other
4789 cases too, set *POSITION to the position where the `display'
4790 property ends.
4792 If IT is NULL, only examine the property specification in SPEC, but
4793 don't set up IT. In that case, FRAME_WINDOW_P means SPEC
4794 is intended to be displayed in a window on a GUI frame.
4796 Value is non-zero if something was found which replaces the display
4797 of buffer or string text. */
4799 static int
4800 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4801 Lisp_Object overlay, struct text_pos *position,
4802 ptrdiff_t bufpos, int display_replaced,
4803 bool frame_window_p)
4805 Lisp_Object form;
4806 Lisp_Object location, value;
4807 struct text_pos start_pos = *position;
4809 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4810 If the result is non-nil, use VALUE instead of SPEC. */
4811 form = Qt;
4812 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4814 spec = XCDR (spec);
4815 if (!CONSP (spec))
4816 return 0;
4817 form = XCAR (spec);
4818 spec = XCDR (spec);
4821 if (!NILP (form) && !EQ (form, Qt))
4823 ptrdiff_t count = SPECPDL_INDEX ();
4825 /* Bind `object' to the object having the `display' property, a
4826 buffer or string. Bind `position' to the position in the
4827 object where the property was found, and `buffer-position'
4828 to the current position in the buffer. */
4830 if (NILP (object))
4831 XSETBUFFER (object, current_buffer);
4832 specbind (Qobject, object);
4833 specbind (Qposition, make_number (CHARPOS (*position)));
4834 specbind (Qbuffer_position, make_number (bufpos));
4835 form = safe_eval (form);
4836 unbind_to (count, Qnil);
4839 if (NILP (form))
4840 return 0;
4842 /* Handle `(height HEIGHT)' specifications. */
4843 if (CONSP (spec)
4844 && EQ (XCAR (spec), Qheight)
4845 && CONSP (XCDR (spec)))
4847 if (it)
4849 if (!FRAME_WINDOW_P (it->f))
4850 return 0;
4852 it->font_height = XCAR (XCDR (spec));
4853 if (!NILP (it->font_height))
4855 int new_height = -1;
4857 if (CONSP (it->font_height)
4858 && (EQ (XCAR (it->font_height), Qplus)
4859 || EQ (XCAR (it->font_height), Qminus))
4860 && CONSP (XCDR (it->font_height))
4861 && RANGED_INTEGERP (0, XCAR (XCDR (it->font_height)), INT_MAX))
4863 /* `(+ N)' or `(- N)' where N is an integer. */
4864 int steps = XINT (XCAR (XCDR (it->font_height)));
4865 if (EQ (XCAR (it->font_height), Qplus))
4866 steps = - steps;
4867 it->face_id = smaller_face (it->f, it->face_id, steps);
4869 else if (FUNCTIONP (it->font_height))
4871 /* Call function with current height as argument.
4872 Value is the new height. */
4873 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4874 Lisp_Object height;
4875 height = safe_call1 (it->font_height,
4876 face->lface[LFACE_HEIGHT_INDEX]);
4877 if (NUMBERP (height))
4878 new_height = XFLOATINT (height);
4880 else if (NUMBERP (it->font_height))
4882 /* Value is a multiple of the canonical char height. */
4883 struct face *f;
4885 f = FACE_FROM_ID (it->f,
4886 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4887 new_height = (XFLOATINT (it->font_height)
4888 * XINT (f->lface[LFACE_HEIGHT_INDEX]));
4890 else
4892 /* Evaluate IT->font_height with `height' bound to the
4893 current specified height to get the new height. */
4894 ptrdiff_t count = SPECPDL_INDEX ();
4895 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4897 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4898 value = safe_eval (it->font_height);
4899 unbind_to (count, Qnil);
4901 if (NUMBERP (value))
4902 new_height = XFLOATINT (value);
4905 if (new_height > 0)
4906 it->face_id = face_with_height (it->f, it->face_id, new_height);
4910 return 0;
4913 /* Handle `(space-width WIDTH)'. */
4914 if (CONSP (spec)
4915 && EQ (XCAR (spec), Qspace_width)
4916 && CONSP (XCDR (spec)))
4918 if (it)
4920 if (!FRAME_WINDOW_P (it->f))
4921 return 0;
4923 value = XCAR (XCDR (spec));
4924 if (NUMBERP (value) && XFLOATINT (value) > 0)
4925 it->space_width = value;
4928 return 0;
4931 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4932 if (CONSP (spec)
4933 && EQ (XCAR (spec), Qslice))
4935 Lisp_Object tem;
4937 if (it)
4939 if (!FRAME_WINDOW_P (it->f))
4940 return 0;
4942 if (tem = XCDR (spec), CONSP (tem))
4944 it->slice.x = XCAR (tem);
4945 if (tem = XCDR (tem), CONSP (tem))
4947 it->slice.y = XCAR (tem);
4948 if (tem = XCDR (tem), CONSP (tem))
4950 it->slice.width = XCAR (tem);
4951 if (tem = XCDR (tem), CONSP (tem))
4952 it->slice.height = XCAR (tem);
4958 return 0;
4961 /* Handle `(raise FACTOR)'. */
4962 if (CONSP (spec)
4963 && EQ (XCAR (spec), Qraise)
4964 && CONSP (XCDR (spec)))
4966 if (it)
4968 if (!FRAME_WINDOW_P (it->f))
4969 return 0;
4971 #ifdef HAVE_WINDOW_SYSTEM
4972 value = XCAR (XCDR (spec));
4973 if (NUMBERP (value))
4975 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4976 it->voffset = - (XFLOATINT (value)
4977 * (normal_char_height (face->font, -1)));
4979 #endif /* HAVE_WINDOW_SYSTEM */
4982 return 0;
4985 /* Don't handle the other kinds of display specifications
4986 inside a string that we got from a `display' property. */
4987 if (it && it->string_from_display_prop_p)
4988 return 0;
4990 /* Characters having this form of property are not displayed, so
4991 we have to find the end of the property. */
4992 if (it)
4994 start_pos = *position;
4995 *position = display_prop_end (it, object, start_pos);
4996 /* If the display property comes from an overlay, don't consider
4997 any potential stop_charpos values before the end of that
4998 overlay. Since display_prop_end will happily find another
4999 'display' property coming from some other overlay or text
5000 property on buffer positions before this overlay's end, we
5001 need to ignore them, or else we risk displaying this
5002 overlay's display string/image twice. */
5003 if (!NILP (overlay))
5005 ptrdiff_t ovendpos = OVERLAY_POSITION (OVERLAY_END (overlay));
5007 if (ovendpos > CHARPOS (*position))
5008 SET_TEXT_POS (*position, ovendpos, CHAR_TO_BYTE (ovendpos));
5011 value = Qnil;
5013 /* Stop the scan at that end position--we assume that all
5014 text properties change there. */
5015 if (it)
5016 it->stop_charpos = position->charpos;
5018 /* Handle `(left-fringe BITMAP [FACE])'
5019 and `(right-fringe BITMAP [FACE])'. */
5020 if (CONSP (spec)
5021 && (EQ (XCAR (spec), Qleft_fringe)
5022 || EQ (XCAR (spec), Qright_fringe))
5023 && CONSP (XCDR (spec)))
5025 if (it)
5027 if (!FRAME_WINDOW_P (it->f))
5028 /* If we return here, POSITION has been advanced
5029 across the text with this property. */
5031 /* Synchronize the bidi iterator with POSITION. This is
5032 needed because we are not going to push the iterator
5033 on behalf of this display property, so there will be
5034 no pop_it call to do this synchronization for us. */
5035 if (it->bidi_p)
5037 it->position = *position;
5038 iterate_out_of_display_property (it);
5039 *position = it->position;
5041 return 1;
5044 else if (!frame_window_p)
5045 return 1;
5047 #ifdef HAVE_WINDOW_SYSTEM
5048 value = XCAR (XCDR (spec));
5049 int fringe_bitmap = SYMBOLP (value) ? lookup_fringe_bitmap (value) : 0;
5050 if (! fringe_bitmap)
5051 /* If we return here, POSITION has been advanced
5052 across the text with this property. */
5054 if (it && it->bidi_p)
5056 it->position = *position;
5057 iterate_out_of_display_property (it);
5058 *position = it->position;
5060 return 1;
5063 if (it)
5065 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
5067 if (CONSP (XCDR (XCDR (spec))))
5069 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
5070 int face_id2 = lookup_derived_face (it->f, face_name,
5071 FRINGE_FACE_ID, false);
5072 if (face_id2 >= 0)
5073 face_id = face_id2;
5076 /* Save current settings of IT so that we can restore them
5077 when we are finished with the glyph property value. */
5078 push_it (it, position);
5080 it->area = TEXT_AREA;
5081 it->what = IT_IMAGE;
5082 it->image_id = -1; /* no image */
5083 it->position = start_pos;
5084 it->object = NILP (object) ? it->w->contents : object;
5085 it->method = GET_FROM_IMAGE;
5086 it->from_overlay = Qnil;
5087 it->face_id = face_id;
5088 it->from_disp_prop_p = true;
5090 /* Say that we haven't consumed the characters with
5091 `display' property yet. The call to pop_it in
5092 set_iterator_to_next will clean this up. */
5093 *position = start_pos;
5095 if (EQ (XCAR (spec), Qleft_fringe))
5097 it->left_user_fringe_bitmap = fringe_bitmap;
5098 it->left_user_fringe_face_id = face_id;
5100 else
5102 it->right_user_fringe_bitmap = fringe_bitmap;
5103 it->right_user_fringe_face_id = face_id;
5106 #endif /* HAVE_WINDOW_SYSTEM */
5107 return 1;
5110 /* Prepare to handle `((margin left-margin) ...)',
5111 `((margin right-margin) ...)' and `((margin nil) ...)'
5112 prefixes for display specifications. */
5113 location = Qunbound;
5114 if (CONSP (spec) && CONSP (XCAR (spec)))
5116 Lisp_Object tem;
5118 value = XCDR (spec);
5119 if (CONSP (value))
5120 value = XCAR (value);
5122 tem = XCAR (spec);
5123 if (EQ (XCAR (tem), Qmargin)
5124 && (tem = XCDR (tem),
5125 tem = CONSP (tem) ? XCAR (tem) : Qnil,
5126 (NILP (tem)
5127 || EQ (tem, Qleft_margin)
5128 || EQ (tem, Qright_margin))))
5129 location = tem;
5132 if (EQ (location, Qunbound))
5134 location = Qnil;
5135 value = spec;
5138 /* After this point, VALUE is the property after any
5139 margin prefix has been stripped. It must be a string,
5140 an image specification, or `(space ...)'.
5142 LOCATION specifies where to display: `left-margin',
5143 `right-margin' or nil. */
5145 bool valid_p = (STRINGP (value)
5146 #ifdef HAVE_WINDOW_SYSTEM
5147 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
5148 && valid_image_p (value))
5149 #endif /* not HAVE_WINDOW_SYSTEM */
5150 || (CONSP (value) && EQ (XCAR (value), Qspace))
5151 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
5152 && valid_xwidget_spec_p (value)));
5154 if (valid_p && display_replaced == 0)
5156 int retval = 1;
5158 if (!it)
5160 /* Callers need to know whether the display spec is any kind
5161 of `(space ...)' spec that is about to affect text-area
5162 display. */
5163 if (CONSP (value) && EQ (XCAR (value), Qspace) && NILP (location))
5164 retval = 2;
5165 return retval;
5168 /* Save current settings of IT so that we can restore them
5169 when we are finished with the glyph property value. */
5170 push_it (it, position);
5171 it->from_overlay = overlay;
5172 it->from_disp_prop_p = true;
5174 if (NILP (location))
5175 it->area = TEXT_AREA;
5176 else if (EQ (location, Qleft_margin))
5177 it->area = LEFT_MARGIN_AREA;
5178 else
5179 it->area = RIGHT_MARGIN_AREA;
5181 if (STRINGP (value))
5183 it->string = value;
5184 it->multibyte_p = STRING_MULTIBYTE (it->string);
5185 it->current.overlay_string_index = -1;
5186 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5187 it->end_charpos = it->string_nchars = SCHARS (it->string);
5188 it->method = GET_FROM_STRING;
5189 it->stop_charpos = 0;
5190 it->prev_stop = 0;
5191 it->base_level_stop = 0;
5192 it->string_from_display_prop_p = true;
5193 /* Say that we haven't consumed the characters with
5194 `display' property yet. The call to pop_it in
5195 set_iterator_to_next will clean this up. */
5196 if (BUFFERP (object))
5197 *position = start_pos;
5199 /* Force paragraph direction to be that of the parent
5200 object. If the parent object's paragraph direction is
5201 not yet determined, default to L2R. */
5202 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5203 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5204 else
5205 it->paragraph_embedding = L2R;
5207 /* Set up the bidi iterator for this display string. */
5208 if (it->bidi_p)
5210 it->bidi_it.string.lstring = it->string;
5211 it->bidi_it.string.s = NULL;
5212 it->bidi_it.string.schars = it->end_charpos;
5213 it->bidi_it.string.bufpos = bufpos;
5214 it->bidi_it.string.from_disp_str = true;
5215 it->bidi_it.string.unibyte = !it->multibyte_p;
5216 it->bidi_it.w = it->w;
5217 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5220 else if (CONSP (value) && EQ (XCAR (value), Qspace))
5222 it->method = GET_FROM_STRETCH;
5223 it->object = value;
5224 *position = it->position = start_pos;
5225 retval = 1 + (it->area == TEXT_AREA);
5227 else if (valid_xwidget_spec_p (value))
5229 it->what = IT_XWIDGET;
5230 it->method = GET_FROM_XWIDGET;
5231 it->position = start_pos;
5232 it->object = NILP (object) ? it->w->contents : object;
5233 *position = start_pos;
5234 it->xwidget = lookup_xwidget (value);
5236 #ifdef HAVE_WINDOW_SYSTEM
5237 else
5239 it->what = IT_IMAGE;
5240 it->image_id = lookup_image (it->f, value);
5241 it->position = start_pos;
5242 it->object = NILP (object) ? it->w->contents : object;
5243 it->method = GET_FROM_IMAGE;
5245 /* Say that we haven't consumed the characters with
5246 `display' property yet. The call to pop_it in
5247 set_iterator_to_next will clean this up. */
5248 *position = start_pos;
5250 #endif /* HAVE_WINDOW_SYSTEM */
5252 return retval;
5255 /* Invalid property or property not supported. Restore
5256 POSITION to what it was before. */
5257 *position = start_pos;
5258 return 0;
5261 /* Check if PROP is a display property value whose text should be
5262 treated as intangible. OVERLAY is the overlay from which PROP
5263 came, or nil if it came from a text property. CHARPOS and BYTEPOS
5264 specify the buffer position covered by PROP. */
5266 bool
5267 display_prop_intangible_p (Lisp_Object prop, Lisp_Object overlay,
5268 ptrdiff_t charpos, ptrdiff_t bytepos)
5270 bool frame_window_p = FRAME_WINDOW_P (XFRAME (selected_frame));
5271 struct text_pos position;
5273 SET_TEXT_POS (position, charpos, bytepos);
5274 return (handle_display_spec (NULL, prop, Qnil, overlay,
5275 &position, charpos, frame_window_p)
5276 != 0);
5280 /* Return true if PROP is a display sub-property value containing STRING.
5282 Implementation note: this and the following function are really
5283 special cases of handle_display_spec and
5284 handle_single_display_spec, and should ideally use the same code.
5285 Until they do, these two pairs must be consistent and must be
5286 modified in sync. */
5288 static bool
5289 single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
5291 if (EQ (string, prop))
5292 return true;
5294 /* Skip over `when FORM'. */
5295 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
5297 prop = XCDR (prop);
5298 if (!CONSP (prop))
5299 return false;
5300 /* Actually, the condition following `when' should be eval'ed,
5301 like handle_single_display_spec does, and we should return
5302 false if it evaluates to nil. However, this function is
5303 called only when the buffer was already displayed and some
5304 glyph in the glyph matrix was found to come from a display
5305 string. Therefore, the condition was already evaluated, and
5306 the result was non-nil, otherwise the display string wouldn't
5307 have been displayed and we would have never been called for
5308 this property. Thus, we can skip the evaluation and assume
5309 its result is non-nil. */
5310 prop = XCDR (prop);
5313 if (CONSP (prop))
5314 /* Skip over `margin LOCATION'. */
5315 if (EQ (XCAR (prop), Qmargin))
5317 prop = XCDR (prop);
5318 if (!CONSP (prop))
5319 return false;
5321 prop = XCDR (prop);
5322 if (!CONSP (prop))
5323 return false;
5326 return EQ (prop, string) || (CONSP (prop) && EQ (XCAR (prop), string));
5330 /* Return true if STRING appears in the `display' property PROP. */
5332 static bool
5333 display_prop_string_p (Lisp_Object prop, Lisp_Object string)
5335 if (CONSP (prop)
5336 && !EQ (XCAR (prop), Qwhen)
5337 && !(CONSP (XCAR (prop)) && EQ (Qmargin, XCAR (XCAR (prop)))))
5339 /* A list of sub-properties. */
5340 while (CONSP (prop))
5342 if (single_display_spec_string_p (XCAR (prop), string))
5343 return true;
5344 prop = XCDR (prop);
5347 else if (VECTORP (prop))
5349 /* A vector of sub-properties. */
5350 ptrdiff_t i;
5351 for (i = 0; i < ASIZE (prop); ++i)
5352 if (single_display_spec_string_p (AREF (prop, i), string))
5353 return true;
5355 else
5356 return single_display_spec_string_p (prop, string);
5358 return false;
5361 /* Look for STRING in overlays and text properties in the current
5362 buffer, between character positions FROM and TO (excluding TO).
5363 BACK_P means look back (in this case, TO is supposed to be
5364 less than FROM).
5365 Value is the first character position where STRING was found, or
5366 zero if it wasn't found before hitting TO.
5368 This function may only use code that doesn't eval because it is
5369 called asynchronously from note_mouse_highlight. */
5371 static ptrdiff_t
5372 string_buffer_position_lim (Lisp_Object string,
5373 ptrdiff_t from, ptrdiff_t to, bool back_p)
5375 Lisp_Object limit, prop, pos;
5376 bool found = false;
5378 pos = make_number (max (from, BEGV));
5380 if (!back_p) /* looking forward */
5382 limit = make_number (min (to, ZV));
5383 while (!found && !EQ (pos, limit))
5385 prop = Fget_char_property (pos, Qdisplay, Qnil);
5386 if (!NILP (prop) && display_prop_string_p (prop, string))
5387 found = true;
5388 else
5389 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
5390 limit);
5393 else /* looking back */
5395 limit = make_number (max (to, BEGV));
5396 while (!found && !EQ (pos, limit))
5398 prop = Fget_char_property (pos, Qdisplay, Qnil);
5399 if (!NILP (prop) && display_prop_string_p (prop, string))
5400 found = true;
5401 else
5402 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
5403 limit);
5407 return found ? XINT (pos) : 0;
5410 /* Determine which buffer position in current buffer STRING comes from.
5411 AROUND_CHARPOS is an approximate position where it could come from.
5412 Value is the buffer position or 0 if it couldn't be determined.
5414 This function is necessary because we don't record buffer positions
5415 in glyphs generated from strings (to keep struct glyph small).
5416 This function may only use code that doesn't eval because it is
5417 called asynchronously from note_mouse_highlight. */
5419 static ptrdiff_t
5420 string_buffer_position (Lisp_Object string, ptrdiff_t around_charpos)
5422 const int MAX_DISTANCE = 1000;
5423 ptrdiff_t found = string_buffer_position_lim (string, around_charpos,
5424 around_charpos + MAX_DISTANCE,
5425 false);
5427 if (!found)
5428 found = string_buffer_position_lim (string, around_charpos,
5429 around_charpos - MAX_DISTANCE, true);
5430 return found;
5435 /***********************************************************************
5436 `composition' property
5437 ***********************************************************************/
5439 /* Set up iterator IT from `composition' property at its current
5440 position. Called from handle_stop. */
5442 static enum prop_handled
5443 handle_composition_prop (struct it *it)
5445 Lisp_Object prop, string;
5446 ptrdiff_t pos, pos_byte, start, end;
5448 if (STRINGP (it->string))
5450 unsigned char *s;
5452 pos = IT_STRING_CHARPOS (*it);
5453 pos_byte = IT_STRING_BYTEPOS (*it);
5454 string = it->string;
5455 s = SDATA (string) + pos_byte;
5456 it->c = STRING_CHAR (s);
5458 else
5460 pos = IT_CHARPOS (*it);
5461 pos_byte = IT_BYTEPOS (*it);
5462 string = Qnil;
5463 it->c = FETCH_CHAR (pos_byte);
5466 /* If there's a valid composition and point is not inside of the
5467 composition (in the case that the composition is from the current
5468 buffer), draw a glyph composed from the composition components. */
5469 if (find_composition (pos, -1, &start, &end, &prop, string)
5470 && composition_valid_p (start, end, prop)
5471 && (STRINGP (it->string) || (PT <= start || PT >= end)))
5473 if (start < pos)
5474 /* As we can't handle this situation (perhaps font-lock added
5475 a new composition), we just return here hoping that next
5476 redisplay will detect this composition much earlier. */
5477 return HANDLED_NORMALLY;
5478 if (start != pos)
5480 if (STRINGP (it->string))
5481 pos_byte = string_char_to_byte (it->string, start);
5482 else
5483 pos_byte = CHAR_TO_BYTE (start);
5485 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
5486 prop, string);
5488 if (it->cmp_it.id >= 0)
5490 it->cmp_it.ch = -1;
5491 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
5492 it->cmp_it.nglyphs = -1;
5496 return HANDLED_NORMALLY;
5501 /***********************************************************************
5502 Overlay strings
5503 ***********************************************************************/
5505 /* The following structure is used to record overlay strings for
5506 later sorting in load_overlay_strings. */
5508 struct overlay_entry
5510 Lisp_Object overlay;
5511 Lisp_Object string;
5512 EMACS_INT priority;
5513 bool after_string_p;
5517 /* Set up iterator IT from overlay strings at its current position.
5518 Called from handle_stop. */
5520 static enum prop_handled
5521 handle_overlay_change (struct it *it)
5523 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
5524 return HANDLED_RECOMPUTE_PROPS;
5525 else
5526 return HANDLED_NORMALLY;
5530 /* Set up the next overlay string for delivery by IT, if there is an
5531 overlay string to deliver. Called by set_iterator_to_next when the
5532 end of the current overlay string is reached. If there are more
5533 overlay strings to display, IT->string and
5534 IT->current.overlay_string_index are set appropriately here.
5535 Otherwise IT->string is set to nil. */
5537 static void
5538 next_overlay_string (struct it *it)
5540 ++it->current.overlay_string_index;
5541 if (it->current.overlay_string_index == it->n_overlay_strings)
5543 /* No more overlay strings. Restore IT's settings to what
5544 they were before overlay strings were processed, and
5545 continue to deliver from current_buffer. */
5547 it->ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
5548 pop_it (it);
5549 eassert (it->sp > 0
5550 || (NILP (it->string)
5551 && it->method == GET_FROM_BUFFER
5552 && it->stop_charpos >= BEGV
5553 && it->stop_charpos <= it->end_charpos));
5554 it->current.overlay_string_index = -1;
5555 it->n_overlay_strings = 0;
5556 /* If there's an empty display string on the stack, pop the
5557 stack, to resync the bidi iterator with IT's position. Such
5558 empty strings are pushed onto the stack in
5559 get_overlay_strings_1. */
5560 if (it->sp > 0 && STRINGP (it->string) && !SCHARS (it->string))
5561 pop_it (it);
5563 /* Since we've exhausted overlay strings at this buffer
5564 position, set the flag to ignore overlays until we move to
5565 another position. The flag is reset in
5566 next_element_from_buffer. */
5567 it->ignore_overlay_strings_at_pos_p = true;
5569 /* If we're at the end of the buffer, record that we have
5570 processed the overlay strings there already, so that
5571 next_element_from_buffer doesn't try it again. */
5572 if (NILP (it->string)
5573 && IT_CHARPOS (*it) >= it->end_charpos
5574 && it->overlay_strings_charpos >= it->end_charpos)
5575 it->overlay_strings_at_end_processed_p = true;
5576 /* Note: we reset overlay_strings_charpos only here, to make
5577 sure the just-processed overlays were indeed at EOB.
5578 Otherwise, overlays on text with invisible text property,
5579 which are processed with IT's position past the invisible
5580 text, might fool us into thinking the overlays at EOB were
5581 already processed (linum-mode can cause this, for
5582 example). */
5583 it->overlay_strings_charpos = -1;
5585 else
5587 /* There are more overlay strings to process. If
5588 IT->current.overlay_string_index has advanced to a position
5589 where we must load IT->overlay_strings with more strings, do
5590 it. We must load at the IT->overlay_strings_charpos where
5591 IT->n_overlay_strings was originally computed; when invisible
5592 text is present, this might not be IT_CHARPOS (Bug#7016). */
5593 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
5595 if (it->current.overlay_string_index && i == 0)
5596 load_overlay_strings (it, it->overlay_strings_charpos);
5598 /* Initialize IT to deliver display elements from the overlay
5599 string. */
5600 it->string = it->overlay_strings[i];
5601 it->multibyte_p = STRING_MULTIBYTE (it->string);
5602 SET_TEXT_POS (it->current.string_pos, 0, 0);
5603 it->method = GET_FROM_STRING;
5604 it->stop_charpos = 0;
5605 it->end_charpos = SCHARS (it->string);
5606 if (it->cmp_it.stop_pos >= 0)
5607 it->cmp_it.stop_pos = 0;
5608 it->prev_stop = 0;
5609 it->base_level_stop = 0;
5611 /* Set up the bidi iterator for this overlay string. */
5612 if (it->bidi_p)
5614 it->bidi_it.string.lstring = it->string;
5615 it->bidi_it.string.s = NULL;
5616 it->bidi_it.string.schars = SCHARS (it->string);
5617 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
5618 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5619 it->bidi_it.string.unibyte = !it->multibyte_p;
5620 it->bidi_it.w = it->w;
5621 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5625 CHECK_IT (it);
5629 /* Compare two overlay_entry structures E1 and E2. Used as a
5630 comparison function for qsort in load_overlay_strings. Overlay
5631 strings for the same position are sorted so that
5633 1. All after-strings come in front of before-strings, except
5634 when they come from the same overlay.
5636 2. Within after-strings, strings are sorted so that overlay strings
5637 from overlays with higher priorities come first.
5639 2. Within before-strings, strings are sorted so that overlay
5640 strings from overlays with higher priorities come last.
5642 Value is analogous to strcmp. */
5645 static int
5646 compare_overlay_entries (const void *e1, const void *e2)
5648 struct overlay_entry const *entry1 = e1;
5649 struct overlay_entry const *entry2 = e2;
5650 int result;
5652 if (entry1->after_string_p != entry2->after_string_p)
5654 /* Let after-strings appear in front of before-strings if
5655 they come from different overlays. */
5656 if (EQ (entry1->overlay, entry2->overlay))
5657 result = entry1->after_string_p ? 1 : -1;
5658 else
5659 result = entry1->after_string_p ? -1 : 1;
5661 else if (entry1->priority != entry2->priority)
5663 if (entry1->after_string_p)
5664 /* After-strings sorted in order of decreasing priority. */
5665 result = entry2->priority < entry1->priority ? -1 : 1;
5666 else
5667 /* Before-strings sorted in order of increasing priority. */
5668 result = entry1->priority < entry2->priority ? -1 : 1;
5670 else
5671 result = 0;
5673 return result;
5677 /* Load the vector IT->overlay_strings with overlay strings from IT's
5678 current buffer position, or from CHARPOS if that is > 0. Set
5679 IT->n_overlays to the total number of overlay strings found.
5681 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
5682 a time. On entry into load_overlay_strings,
5683 IT->current.overlay_string_index gives the number of overlay
5684 strings that have already been loaded by previous calls to this
5685 function.
5687 IT->add_overlay_start contains an additional overlay start
5688 position to consider for taking overlay strings from, if non-zero.
5689 This position comes into play when the overlay has an `invisible'
5690 property, and both before and after-strings. When we've skipped to
5691 the end of the overlay, because of its `invisible' property, we
5692 nevertheless want its before-string to appear.
5693 IT->add_overlay_start will contain the overlay start position
5694 in this case.
5696 Overlay strings are sorted so that after-string strings come in
5697 front of before-string strings. Within before and after-strings,
5698 strings are sorted by overlay priority. See also function
5699 compare_overlay_entries. */
5701 static void
5702 load_overlay_strings (struct it *it, ptrdiff_t charpos)
5704 Lisp_Object overlay, window, str, invisible;
5705 struct Lisp_Overlay *ov;
5706 ptrdiff_t start, end;
5707 ptrdiff_t n = 0, i, j;
5708 int invis;
5709 struct overlay_entry entriesbuf[20];
5710 ptrdiff_t size = ARRAYELTS (entriesbuf);
5711 struct overlay_entry *entries = entriesbuf;
5712 USE_SAFE_ALLOCA;
5714 if (charpos <= 0)
5715 charpos = IT_CHARPOS (*it);
5717 /* Append the overlay string STRING of overlay OVERLAY to vector
5718 `entries' which has size `size' and currently contains `n'
5719 elements. AFTER_P means STRING is an after-string of
5720 OVERLAY. */
5721 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
5722 do \
5724 Lisp_Object priority; \
5726 if (n == size) \
5728 struct overlay_entry *old = entries; \
5729 SAFE_NALLOCA (entries, 2, size); \
5730 memcpy (entries, old, size * sizeof *entries); \
5731 size *= 2; \
5734 entries[n].string = (STRING); \
5735 entries[n].overlay = (OVERLAY); \
5736 priority = Foverlay_get ((OVERLAY), Qpriority); \
5737 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
5738 entries[n].after_string_p = (AFTER_P); \
5739 ++n; \
5741 while (false)
5743 /* Process overlay before the overlay center. */
5744 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
5746 XSETMISC (overlay, ov);
5747 eassert (OVERLAYP (overlay));
5748 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5749 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5751 if (end < charpos)
5752 break;
5754 /* Skip this overlay if it doesn't start or end at IT's current
5755 position. */
5756 if (end != charpos && start != charpos)
5757 continue;
5759 /* Skip this overlay if it doesn't apply to IT->w. */
5760 window = Foverlay_get (overlay, Qwindow);
5761 if (WINDOWP (window) && XWINDOW (window) != it->w)
5762 continue;
5764 /* If the text ``under'' the overlay is invisible, both before-
5765 and after-strings from this overlay are visible; start and
5766 end position are indistinguishable. */
5767 invisible = Foverlay_get (overlay, Qinvisible);
5768 invis = TEXT_PROP_MEANS_INVISIBLE (invisible);
5770 /* If overlay has a non-empty before-string, record it. */
5771 if ((start == charpos || (end == charpos && invis != 0))
5772 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5773 && SCHARS (str))
5774 RECORD_OVERLAY_STRING (overlay, str, false);
5776 /* If overlay has a non-empty after-string, record it. */
5777 if ((end == charpos || (start == charpos && invis != 0))
5778 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5779 && SCHARS (str))
5780 RECORD_OVERLAY_STRING (overlay, str, true);
5783 /* Process overlays after the overlay center. */
5784 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
5786 XSETMISC (overlay, ov);
5787 eassert (OVERLAYP (overlay));
5788 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5789 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5791 if (start > charpos)
5792 break;
5794 /* Skip this overlay if it doesn't start or end at IT's current
5795 position. */
5796 if (end != charpos && start != charpos)
5797 continue;
5799 /* Skip this overlay if it doesn't apply to IT->w. */
5800 window = Foverlay_get (overlay, Qwindow);
5801 if (WINDOWP (window) && XWINDOW (window) != it->w)
5802 continue;
5804 /* If the text ``under'' the overlay is invisible, it has a zero
5805 dimension, and both before- and after-strings apply. */
5806 invisible = Foverlay_get (overlay, Qinvisible);
5807 invis = TEXT_PROP_MEANS_INVISIBLE (invisible);
5809 /* If overlay has a non-empty before-string, record it. */
5810 if ((start == charpos || (end == charpos && invis != 0))
5811 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5812 && SCHARS (str))
5813 RECORD_OVERLAY_STRING (overlay, str, false);
5815 /* If overlay has a non-empty after-string, record it. */
5816 if ((end == charpos || (start == charpos && invis != 0))
5817 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5818 && SCHARS (str))
5819 RECORD_OVERLAY_STRING (overlay, str, true);
5822 #undef RECORD_OVERLAY_STRING
5824 /* Sort entries. */
5825 if (n > 1)
5826 qsort (entries, n, sizeof *entries, compare_overlay_entries);
5828 /* Record number of overlay strings, and where we computed it. */
5829 it->n_overlay_strings = n;
5830 it->overlay_strings_charpos = charpos;
5832 /* IT->current.overlay_string_index is the number of overlay strings
5833 that have already been consumed by IT. Copy some of the
5834 remaining overlay strings to IT->overlay_strings. */
5835 i = 0;
5836 j = it->current.overlay_string_index;
5837 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
5839 it->overlay_strings[i] = entries[j].string;
5840 it->string_overlays[i++] = entries[j++].overlay;
5843 CHECK_IT (it);
5844 SAFE_FREE ();
5848 /* Get the first chunk of overlay strings at IT's current buffer
5849 position, or at CHARPOS if that is > 0. Value is true if at
5850 least one overlay string was found. */
5852 static bool
5853 get_overlay_strings_1 (struct it *it, ptrdiff_t charpos, bool compute_stop_p)
5855 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5856 process. This fills IT->overlay_strings with strings, and sets
5857 IT->n_overlay_strings to the total number of strings to process.
5858 IT->pos.overlay_string_index has to be set temporarily to zero
5859 because load_overlay_strings needs this; it must be set to -1
5860 when no overlay strings are found because a zero value would
5861 indicate a position in the first overlay string. */
5862 it->current.overlay_string_index = 0;
5863 load_overlay_strings (it, charpos);
5865 /* If we found overlay strings, set up IT to deliver display
5866 elements from the first one. Otherwise set up IT to deliver
5867 from current_buffer. */
5868 if (it->n_overlay_strings)
5870 /* Make sure we know settings in current_buffer, so that we can
5871 restore meaningful values when we're done with the overlay
5872 strings. */
5873 if (compute_stop_p)
5874 compute_stop_pos (it);
5875 eassert (it->face_id >= 0);
5877 /* Save IT's settings. They are restored after all overlay
5878 strings have been processed. */
5879 eassert (!compute_stop_p || it->sp == 0);
5881 /* When called from handle_stop, there might be an empty display
5882 string loaded. In that case, don't bother saving it. But
5883 don't use this optimization with the bidi iterator, since we
5884 need the corresponding pop_it call to resync the bidi
5885 iterator's position with IT's position, after we are done
5886 with the overlay strings. (The corresponding call to pop_it
5887 in case of an empty display string is in
5888 next_overlay_string.) */
5889 if (!(!it->bidi_p
5890 && STRINGP (it->string) && !SCHARS (it->string)))
5891 push_it (it, NULL);
5893 /* Set up IT to deliver display elements from the first overlay
5894 string. */
5895 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5896 it->string = it->overlay_strings[0];
5897 it->from_overlay = Qnil;
5898 it->stop_charpos = 0;
5899 eassert (STRINGP (it->string));
5900 it->end_charpos = SCHARS (it->string);
5901 it->prev_stop = 0;
5902 it->base_level_stop = 0;
5903 it->multibyte_p = STRING_MULTIBYTE (it->string);
5904 it->method = GET_FROM_STRING;
5905 it->from_disp_prop_p = 0;
5907 /* Force paragraph direction to be that of the parent
5908 buffer. */
5909 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5910 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5911 else
5912 it->paragraph_embedding = L2R;
5914 /* Set up the bidi iterator for this overlay string. */
5915 if (it->bidi_p)
5917 ptrdiff_t pos = (charpos > 0 ? charpos : IT_CHARPOS (*it));
5919 it->bidi_it.string.lstring = it->string;
5920 it->bidi_it.string.s = NULL;
5921 it->bidi_it.string.schars = SCHARS (it->string);
5922 it->bidi_it.string.bufpos = pos;
5923 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5924 it->bidi_it.string.unibyte = !it->multibyte_p;
5925 it->bidi_it.w = it->w;
5926 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5928 return true;
5931 it->current.overlay_string_index = -1;
5932 return false;
5935 static bool
5936 get_overlay_strings (struct it *it, ptrdiff_t charpos)
5938 it->string = Qnil;
5939 it->method = GET_FROM_BUFFER;
5941 get_overlay_strings_1 (it, charpos, true);
5943 CHECK_IT (it);
5945 /* Value is true if we found at least one overlay string. */
5946 return STRINGP (it->string);
5951 /***********************************************************************
5952 Saving and restoring state
5953 ***********************************************************************/
5955 /* Save current settings of IT on IT->stack. Called, for example,
5956 before setting up IT for an overlay string, to be able to restore
5957 IT's settings to what they were after the overlay string has been
5958 processed. If POSITION is non-NULL, it is the position to save on
5959 the stack instead of IT->position. */
5961 static void
5962 push_it (struct it *it, struct text_pos *position)
5964 struct iterator_stack_entry *p;
5966 eassert (it->sp < IT_STACK_SIZE);
5967 p = it->stack + it->sp;
5969 p->stop_charpos = it->stop_charpos;
5970 p->prev_stop = it->prev_stop;
5971 p->base_level_stop = it->base_level_stop;
5972 p->cmp_it = it->cmp_it;
5973 eassert (it->face_id >= 0);
5974 p->face_id = it->face_id;
5975 p->string = it->string;
5976 p->method = it->method;
5977 p->from_overlay = it->from_overlay;
5978 switch (p->method)
5980 case GET_FROM_IMAGE:
5981 p->u.image.object = it->object;
5982 p->u.image.image_id = it->image_id;
5983 p->u.image.slice = it->slice;
5984 break;
5985 case GET_FROM_STRETCH:
5986 p->u.stretch.object = it->object;
5987 break;
5988 case GET_FROM_XWIDGET:
5989 p->u.xwidget.object = it->object;
5990 break;
5991 case GET_FROM_BUFFER:
5992 case GET_FROM_DISPLAY_VECTOR:
5993 case GET_FROM_STRING:
5994 case GET_FROM_C_STRING:
5995 break;
5996 default:
5997 emacs_abort ();
5999 p->position = position ? *position : it->position;
6000 p->current = it->current;
6001 p->end_charpos = it->end_charpos;
6002 p->string_nchars = it->string_nchars;
6003 p->area = it->area;
6004 p->multibyte_p = it->multibyte_p;
6005 p->avoid_cursor_p = it->avoid_cursor_p;
6006 p->space_width = it->space_width;
6007 p->font_height = it->font_height;
6008 p->voffset = it->voffset;
6009 p->string_from_display_prop_p = it->string_from_display_prop_p;
6010 p->string_from_prefix_prop_p = it->string_from_prefix_prop_p;
6011 p->display_ellipsis_p = false;
6012 p->line_wrap = it->line_wrap;
6013 p->bidi_p = it->bidi_p;
6014 p->paragraph_embedding = it->paragraph_embedding;
6015 p->from_disp_prop_p = it->from_disp_prop_p;
6016 ++it->sp;
6018 /* Save the state of the bidi iterator as well. */
6019 if (it->bidi_p)
6020 bidi_push_it (&it->bidi_it);
6023 static void
6024 iterate_out_of_display_property (struct it *it)
6026 bool buffer_p = !STRINGP (it->string);
6027 ptrdiff_t eob = (buffer_p ? ZV : it->end_charpos);
6028 ptrdiff_t bob = (buffer_p ? BEGV : 0);
6030 eassert (eob >= CHARPOS (it->position) && CHARPOS (it->position) >= bob);
6032 /* Maybe initialize paragraph direction. If we are at the beginning
6033 of a new paragraph, next_element_from_buffer may not have a
6034 chance to do that. */
6035 if (it->bidi_it.first_elt && it->bidi_it.charpos < eob)
6036 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, true);
6037 /* prev_stop can be zero, so check against BEGV as well. */
6038 while (it->bidi_it.charpos >= bob
6039 && it->prev_stop <= it->bidi_it.charpos
6040 && it->bidi_it.charpos < CHARPOS (it->position)
6041 && it->bidi_it.charpos < eob)
6042 bidi_move_to_visually_next (&it->bidi_it);
6043 /* Record the stop_pos we just crossed, for when we cross it
6044 back, maybe. */
6045 if (it->bidi_it.charpos > CHARPOS (it->position))
6046 it->prev_stop = CHARPOS (it->position);
6047 /* If we ended up not where pop_it put us, resync IT's
6048 positional members with the bidi iterator. */
6049 if (it->bidi_it.charpos != CHARPOS (it->position))
6050 SET_TEXT_POS (it->position, it->bidi_it.charpos, it->bidi_it.bytepos);
6051 if (buffer_p)
6052 it->current.pos = it->position;
6053 else
6054 it->current.string_pos = it->position;
6057 /* Restore IT's settings from IT->stack. Called, for example, when no
6058 more overlay strings must be processed, and we return to delivering
6059 display elements from a buffer, or when the end of a string from a
6060 `display' property is reached and we return to delivering display
6061 elements from an overlay string, or from a buffer. */
6063 static void
6064 pop_it (struct it *it)
6066 struct iterator_stack_entry *p;
6067 bool from_display_prop = it->from_disp_prop_p;
6068 ptrdiff_t prev_pos = IT_CHARPOS (*it);
6070 eassert (it->sp > 0);
6071 --it->sp;
6072 p = it->stack + it->sp;
6073 it->stop_charpos = p->stop_charpos;
6074 it->prev_stop = p->prev_stop;
6075 it->base_level_stop = p->base_level_stop;
6076 it->cmp_it = p->cmp_it;
6077 it->face_id = p->face_id;
6078 it->current = p->current;
6079 it->position = p->position;
6080 it->string = p->string;
6081 it->from_overlay = p->from_overlay;
6082 if (NILP (it->string))
6083 SET_TEXT_POS (it->current.string_pos, -1, -1);
6084 it->method = p->method;
6085 switch (it->method)
6087 case GET_FROM_IMAGE:
6088 it->image_id = p->u.image.image_id;
6089 it->object = p->u.image.object;
6090 it->slice = p->u.image.slice;
6091 break;
6092 case GET_FROM_XWIDGET:
6093 it->object = p->u.xwidget.object;
6094 break;
6095 case GET_FROM_STRETCH:
6096 it->object = p->u.stretch.object;
6097 break;
6098 case GET_FROM_BUFFER:
6099 it->object = it->w->contents;
6100 break;
6101 case GET_FROM_STRING:
6103 struct face *face = FACE_FROM_ID_OR_NULL (it->f, it->face_id);
6105 /* Restore the face_box_p flag, since it could have been
6106 overwritten by the face of the object that we just finished
6107 displaying. */
6108 if (face)
6109 it->face_box_p = face->box != FACE_NO_BOX;
6110 it->object = it->string;
6112 break;
6113 case GET_FROM_DISPLAY_VECTOR:
6114 if (it->s)
6115 it->method = GET_FROM_C_STRING;
6116 else if (STRINGP (it->string))
6117 it->method = GET_FROM_STRING;
6118 else
6120 it->method = GET_FROM_BUFFER;
6121 it->object = it->w->contents;
6123 break;
6124 case GET_FROM_C_STRING:
6125 break;
6126 default:
6127 emacs_abort ();
6129 it->end_charpos = p->end_charpos;
6130 it->string_nchars = p->string_nchars;
6131 it->area = p->area;
6132 it->multibyte_p = p->multibyte_p;
6133 it->avoid_cursor_p = p->avoid_cursor_p;
6134 it->space_width = p->space_width;
6135 it->font_height = p->font_height;
6136 it->voffset = p->voffset;
6137 it->string_from_display_prop_p = p->string_from_display_prop_p;
6138 it->string_from_prefix_prop_p = p->string_from_prefix_prop_p;
6139 it->line_wrap = p->line_wrap;
6140 it->bidi_p = p->bidi_p;
6141 it->paragraph_embedding = p->paragraph_embedding;
6142 it->from_disp_prop_p = p->from_disp_prop_p;
6143 if (it->bidi_p)
6145 bidi_pop_it (&it->bidi_it);
6146 /* Bidi-iterate until we get out of the portion of text, if any,
6147 covered by a `display' text property or by an overlay with
6148 `display' property. (We cannot just jump there, because the
6149 internal coherency of the bidi iterator state can not be
6150 preserved across such jumps.) We also must determine the
6151 paragraph base direction if the overlay we just processed is
6152 at the beginning of a new paragraph. */
6153 if (from_display_prop
6154 && (it->method == GET_FROM_BUFFER || it->method == GET_FROM_STRING))
6155 iterate_out_of_display_property (it);
6157 eassert ((BUFFERP (it->object)
6158 && IT_CHARPOS (*it) == it->bidi_it.charpos
6159 && IT_BYTEPOS (*it) == it->bidi_it.bytepos)
6160 || (STRINGP (it->object)
6161 && IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
6162 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos)
6163 || (CONSP (it->object) && it->method == GET_FROM_STRETCH));
6165 /* If we move the iterator over text covered by a display property
6166 to a new buffer position, any info about previously seen overlays
6167 is no longer valid. */
6168 if (from_display_prop && it->sp == 0 && CHARPOS (it->position) != prev_pos)
6169 it->ignore_overlay_strings_at_pos_p = false;
6174 /***********************************************************************
6175 Moving over lines
6176 ***********************************************************************/
6178 /* Set IT's current position to the previous line start. */
6180 static void
6181 back_to_previous_line_start (struct it *it)
6183 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
6185 DEC_BOTH (cp, bp);
6186 IT_CHARPOS (*it) = find_newline_no_quit (cp, bp, -1, &IT_BYTEPOS (*it));
6190 /* Move IT to the next line start.
6192 Value is true if a newline was found. Set *SKIPPED_P to true if
6193 we skipped over part of the text (as opposed to moving the iterator
6194 continuously over the text). Otherwise, don't change the value
6195 of *SKIPPED_P.
6197 If BIDI_IT_PREV is non-NULL, store into it the state of the bidi
6198 iterator on the newline, if it was found.
6200 Newlines may come from buffer text, overlay strings, or strings
6201 displayed via the `display' property. That's the reason we can't
6202 simply use find_newline_no_quit.
6204 Note that this function may not skip over invisible text that is so
6205 because of text properties and immediately follows a newline. If
6206 it would, function reseat_at_next_visible_line_start, when called
6207 from set_iterator_to_next, would effectively make invisible
6208 characters following a newline part of the wrong glyph row, which
6209 leads to wrong cursor motion. */
6211 static bool
6212 forward_to_next_line_start (struct it *it, bool *skipped_p,
6213 struct bidi_it *bidi_it_prev)
6215 ptrdiff_t old_selective;
6216 bool newline_found_p = false;
6217 int n;
6218 const int MAX_NEWLINE_DISTANCE = 500;
6220 /* If already on a newline, just consume it to avoid unintended
6221 skipping over invisible text below. */
6222 if (it->what == IT_CHARACTER
6223 && it->c == '\n'
6224 && CHARPOS (it->position) == IT_CHARPOS (*it))
6226 if (it->bidi_p && bidi_it_prev)
6227 *bidi_it_prev = it->bidi_it;
6228 set_iterator_to_next (it, false);
6229 it->c = 0;
6230 return true;
6233 /* Don't handle selective display in the following. It's (a)
6234 unnecessary because it's done by the caller, and (b) leads to an
6235 infinite recursion because next_element_from_ellipsis indirectly
6236 calls this function. */
6237 old_selective = it->selective;
6238 it->selective = 0;
6240 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
6241 from buffer text. */
6242 for (n = 0;
6243 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
6244 n += !STRINGP (it->string))
6246 if (!get_next_display_element (it))
6247 return false;
6248 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
6249 if (newline_found_p && it->bidi_p && bidi_it_prev)
6250 *bidi_it_prev = it->bidi_it;
6251 set_iterator_to_next (it, false);
6254 /* If we didn't find a newline near enough, see if we can use a
6255 short-cut. */
6256 if (!newline_found_p)
6258 ptrdiff_t bytepos, start = IT_CHARPOS (*it);
6259 ptrdiff_t limit = find_newline_no_quit (start, IT_BYTEPOS (*it),
6260 1, &bytepos);
6261 Lisp_Object pos;
6263 eassert (!STRINGP (it->string));
6265 /* If there isn't any `display' property in sight, and no
6266 overlays, we can just use the position of the newline in
6267 buffer text. */
6268 if (it->stop_charpos >= limit
6269 || ((pos = Fnext_single_property_change (make_number (start),
6270 Qdisplay, Qnil,
6271 make_number (limit)),
6272 NILP (pos))
6273 && next_overlay_change (start) == ZV))
6275 if (!it->bidi_p)
6277 IT_CHARPOS (*it) = limit;
6278 IT_BYTEPOS (*it) = bytepos;
6280 else
6282 struct bidi_it bprev;
6284 /* Help bidi.c avoid expensive searches for display
6285 properties and overlays, by telling it that there are
6286 none up to `limit'. */
6287 if (it->bidi_it.disp_pos < limit)
6289 it->bidi_it.disp_pos = limit;
6290 it->bidi_it.disp_prop = 0;
6292 do {
6293 bprev = it->bidi_it;
6294 bidi_move_to_visually_next (&it->bidi_it);
6295 } while (it->bidi_it.charpos != limit);
6296 IT_CHARPOS (*it) = limit;
6297 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6298 if (bidi_it_prev)
6299 *bidi_it_prev = bprev;
6301 *skipped_p = newline_found_p = true;
6303 else
6305 while (get_next_display_element (it)
6306 && !newline_found_p)
6308 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
6309 if (newline_found_p && it->bidi_p && bidi_it_prev)
6310 *bidi_it_prev = it->bidi_it;
6311 set_iterator_to_next (it, false);
6316 it->selective = old_selective;
6317 return newline_found_p;
6321 /* Set IT's current position to the previous visible line start. Skip
6322 invisible text that is so either due to text properties or due to
6323 selective display. Caution: this does not change IT->current_x and
6324 IT->hpos. */
6326 static void
6327 back_to_previous_visible_line_start (struct it *it)
6329 while (IT_CHARPOS (*it) > BEGV)
6331 back_to_previous_line_start (it);
6333 if (IT_CHARPOS (*it) <= BEGV)
6334 break;
6336 /* If selective > 0, then lines indented more than its value are
6337 invisible. */
6338 if (it->selective > 0
6339 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6340 it->selective))
6341 continue;
6343 /* Check the newline before point for invisibility. */
6345 Lisp_Object prop;
6346 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
6347 Qinvisible, it->window);
6348 if (TEXT_PROP_MEANS_INVISIBLE (prop) != 0)
6349 continue;
6352 if (IT_CHARPOS (*it) <= BEGV)
6353 break;
6356 struct it it2;
6357 void *it2data = NULL;
6358 ptrdiff_t pos;
6359 ptrdiff_t beg, end;
6360 Lisp_Object val, overlay;
6362 SAVE_IT (it2, *it, it2data);
6364 /* If newline is part of a composition, continue from start of composition */
6365 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
6366 && beg < IT_CHARPOS (*it))
6367 goto replaced;
6369 /* If newline is replaced by a display property, find start of overlay
6370 or interval and continue search from that point. */
6371 pos = --IT_CHARPOS (it2);
6372 --IT_BYTEPOS (it2);
6373 it2.sp = 0;
6374 bidi_unshelve_cache (NULL, false);
6375 it2.string_from_display_prop_p = false;
6376 it2.from_disp_prop_p = false;
6377 if (handle_display_prop (&it2) == HANDLED_RETURN
6378 && !NILP (val = get_char_property_and_overlay
6379 (make_number (pos), Qdisplay, Qnil, &overlay))
6380 && (OVERLAYP (overlay)
6381 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
6382 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
6384 RESTORE_IT (it, it, it2data);
6385 goto replaced;
6388 /* Newline is not replaced by anything -- so we are done. */
6389 RESTORE_IT (it, it, it2data);
6390 break;
6392 replaced:
6393 if (beg < BEGV)
6394 beg = BEGV;
6395 IT_CHARPOS (*it) = beg;
6396 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
6400 it->continuation_lines_width = 0;
6402 eassert (IT_CHARPOS (*it) >= BEGV);
6403 eassert (IT_CHARPOS (*it) == BEGV
6404 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6405 CHECK_IT (it);
6409 /* Reseat iterator IT at the previous visible line start. Skip
6410 invisible text that is so either due to text properties or due to
6411 selective display. At the end, update IT's overlay information,
6412 face information etc. */
6414 void
6415 reseat_at_previous_visible_line_start (struct it *it)
6417 back_to_previous_visible_line_start (it);
6418 reseat (it, it->current.pos, true);
6419 CHECK_IT (it);
6423 /* Reseat iterator IT on the next visible line start in the current
6424 buffer. ON_NEWLINE_P means position IT on the newline
6425 preceding the line start. Skip over invisible text that is so
6426 because of selective display. Compute faces, overlays etc at the
6427 new position. Note that this function does not skip over text that
6428 is invisible because of text properties. */
6430 static void
6431 reseat_at_next_visible_line_start (struct it *it, bool on_newline_p)
6433 bool skipped_p = false;
6434 struct bidi_it bidi_it_prev;
6435 bool newline_found_p
6436 = forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6438 /* Skip over lines that are invisible because they are indented
6439 more than the value of IT->selective. */
6440 if (it->selective > 0)
6441 while (IT_CHARPOS (*it) < ZV
6442 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6443 it->selective))
6445 eassert (IT_BYTEPOS (*it) == BEGV
6446 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6447 newline_found_p =
6448 forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6451 /* Position on the newline if that's what's requested. */
6452 if (on_newline_p && newline_found_p)
6454 if (STRINGP (it->string))
6456 if (IT_STRING_CHARPOS (*it) > 0)
6458 if (!it->bidi_p)
6460 --IT_STRING_CHARPOS (*it);
6461 --IT_STRING_BYTEPOS (*it);
6463 else
6465 /* We need to restore the bidi iterator to the state
6466 it had on the newline, and resync the IT's
6467 position with that. */
6468 it->bidi_it = bidi_it_prev;
6469 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6470 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6474 else if (IT_CHARPOS (*it) > BEGV)
6476 if (!it->bidi_p)
6478 --IT_CHARPOS (*it);
6479 --IT_BYTEPOS (*it);
6481 else
6483 /* We need to restore the bidi iterator to the state it
6484 had on the newline and resync IT with that. */
6485 it->bidi_it = bidi_it_prev;
6486 IT_CHARPOS (*it) = it->bidi_it.charpos;
6487 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6489 reseat (it, it->current.pos, false);
6492 else if (skipped_p)
6493 reseat (it, it->current.pos, false);
6495 CHECK_IT (it);
6500 /***********************************************************************
6501 Changing an iterator's position
6502 ***********************************************************************/
6504 /* Change IT's current position to POS in current_buffer.
6505 If FORCE_P, always check for text properties at the new position.
6506 Otherwise, text properties are only looked up if POS >=
6507 IT->check_charpos of a property. */
6509 static void
6510 reseat (struct it *it, struct text_pos pos, bool force_p)
6512 ptrdiff_t original_pos = IT_CHARPOS (*it);
6514 reseat_1 (it, pos, false);
6516 /* Determine where to check text properties. Avoid doing it
6517 where possible because text property lookup is very expensive. */
6518 if (force_p
6519 || CHARPOS (pos) > it->stop_charpos
6520 || CHARPOS (pos) < original_pos)
6522 if (it->bidi_p)
6524 /* For bidi iteration, we need to prime prev_stop and
6525 base_level_stop with our best estimations. */
6526 /* Implementation note: Of course, POS is not necessarily a
6527 stop position, so assigning prev_pos to it is a lie; we
6528 should have called compute_stop_backwards. However, if
6529 the current buffer does not include any R2L characters,
6530 that call would be a waste of cycles, because the
6531 iterator will never move back, and thus never cross this
6532 "fake" stop position. So we delay that backward search
6533 until the time we really need it, in next_element_from_buffer. */
6534 if (CHARPOS (pos) != it->prev_stop)
6535 it->prev_stop = CHARPOS (pos);
6536 if (CHARPOS (pos) < it->base_level_stop)
6537 it->base_level_stop = 0; /* meaning it's unknown */
6538 handle_stop (it);
6540 else
6542 handle_stop (it);
6543 it->prev_stop = it->base_level_stop = 0;
6548 CHECK_IT (it);
6552 /* Change IT's buffer position to POS. SET_STOP_P means set
6553 IT->stop_pos to POS, also. */
6555 static void
6556 reseat_1 (struct it *it, struct text_pos pos, bool set_stop_p)
6558 /* Don't call this function when scanning a C string. */
6559 eassert (it->s == NULL);
6561 /* POS must be a reasonable value. */
6562 eassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
6564 it->current.pos = it->position = pos;
6565 it->end_charpos = ZV;
6566 it->dpvec = NULL;
6567 it->current.dpvec_index = -1;
6568 it->current.overlay_string_index = -1;
6569 IT_STRING_CHARPOS (*it) = -1;
6570 IT_STRING_BYTEPOS (*it) = -1;
6571 it->string = Qnil;
6572 it->method = GET_FROM_BUFFER;
6573 it->object = it->w->contents;
6574 it->area = TEXT_AREA;
6575 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
6576 it->sp = 0;
6577 it->string_from_display_prop_p = false;
6578 it->string_from_prefix_prop_p = false;
6580 it->from_disp_prop_p = false;
6581 it->face_before_selective_p = false;
6582 if (it->bidi_p)
6584 bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6585 &it->bidi_it);
6586 bidi_unshelve_cache (NULL, false);
6587 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6588 it->bidi_it.string.s = NULL;
6589 it->bidi_it.string.lstring = Qnil;
6590 it->bidi_it.string.bufpos = 0;
6591 it->bidi_it.string.from_disp_str = false;
6592 it->bidi_it.string.unibyte = false;
6593 it->bidi_it.w = it->w;
6596 if (set_stop_p)
6598 it->stop_charpos = CHARPOS (pos);
6599 it->base_level_stop = CHARPOS (pos);
6601 /* This make the information stored in it->cmp_it invalidate. */
6602 it->cmp_it.id = -1;
6606 /* Set up IT for displaying a string, starting at CHARPOS in window W.
6607 If S is non-null, it is a C string to iterate over. Otherwise,
6608 STRING gives a Lisp string to iterate over.
6610 If PRECISION > 0, don't return more then PRECISION number of
6611 characters from the string.
6613 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
6614 characters have been returned. FIELD_WIDTH < 0 means an infinite
6615 field width.
6617 MULTIBYTE = 0 means disable processing of multibyte characters,
6618 MULTIBYTE > 0 means enable it,
6619 MULTIBYTE < 0 means use IT->multibyte_p.
6621 IT must be initialized via a prior call to init_iterator before
6622 calling this function. */
6624 static void
6625 reseat_to_string (struct it *it, const char *s, Lisp_Object string,
6626 ptrdiff_t charpos, ptrdiff_t precision, int field_width,
6627 int multibyte)
6629 /* No text property checks performed by default, but see below. */
6630 it->stop_charpos = -1;
6632 /* Set iterator position and end position. */
6633 memset (&it->current, 0, sizeof it->current);
6634 it->current.overlay_string_index = -1;
6635 it->current.dpvec_index = -1;
6636 eassert (charpos >= 0);
6638 /* If STRING is specified, use its multibyteness, otherwise use the
6639 setting of MULTIBYTE, if specified. */
6640 if (multibyte >= 0)
6641 it->multibyte_p = multibyte > 0;
6643 /* Bidirectional reordering of strings is controlled by the default
6644 value of bidi-display-reordering. Don't try to reorder while
6645 loading loadup.el, as the necessary character property tables are
6646 not yet available. */
6647 it->bidi_p =
6648 !redisplay__inhibit_bidi
6649 && !NILP (BVAR (&buffer_defaults, bidi_display_reordering));
6651 if (s == NULL)
6653 eassert (STRINGP (string));
6654 it->string = string;
6655 it->s = NULL;
6656 it->end_charpos = it->string_nchars = SCHARS (string);
6657 it->method = GET_FROM_STRING;
6658 it->current.string_pos = string_pos (charpos, string);
6660 if (it->bidi_p)
6662 it->bidi_it.string.lstring = string;
6663 it->bidi_it.string.s = NULL;
6664 it->bidi_it.string.schars = it->end_charpos;
6665 it->bidi_it.string.bufpos = 0;
6666 it->bidi_it.string.from_disp_str = false;
6667 it->bidi_it.string.unibyte = !it->multibyte_p;
6668 it->bidi_it.w = it->w;
6669 bidi_init_it (charpos, IT_STRING_BYTEPOS (*it),
6670 FRAME_WINDOW_P (it->f), &it->bidi_it);
6673 else
6675 it->s = (const unsigned char *) s;
6676 it->string = Qnil;
6678 /* Note that we use IT->current.pos, not it->current.string_pos,
6679 for displaying C strings. */
6680 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
6681 if (it->multibyte_p)
6683 it->current.pos = c_string_pos (charpos, s, true);
6684 it->end_charpos = it->string_nchars = number_of_chars (s, true);
6686 else
6688 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
6689 it->end_charpos = it->string_nchars = strlen (s);
6692 if (it->bidi_p)
6694 it->bidi_it.string.lstring = Qnil;
6695 it->bidi_it.string.s = (const unsigned char *) s;
6696 it->bidi_it.string.schars = it->end_charpos;
6697 it->bidi_it.string.bufpos = 0;
6698 it->bidi_it.string.from_disp_str = false;
6699 it->bidi_it.string.unibyte = !it->multibyte_p;
6700 it->bidi_it.w = it->w;
6701 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6702 &it->bidi_it);
6704 it->method = GET_FROM_C_STRING;
6707 /* PRECISION > 0 means don't return more than PRECISION characters
6708 from the string. */
6709 if (precision > 0 && it->end_charpos - charpos > precision)
6711 it->end_charpos = it->string_nchars = charpos + precision;
6712 if (it->bidi_p)
6713 it->bidi_it.string.schars = it->end_charpos;
6716 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
6717 characters have been returned. FIELD_WIDTH == 0 means don't pad,
6718 FIELD_WIDTH < 0 means infinite field width. This is useful for
6719 padding with `-' at the end of a mode line. */
6720 if (field_width < 0)
6721 field_width = INFINITY;
6722 /* Implementation note: We deliberately don't enlarge
6723 it->bidi_it.string.schars here to fit it->end_charpos, because
6724 the bidi iterator cannot produce characters out of thin air. */
6725 if (field_width > it->end_charpos - charpos)
6726 it->end_charpos = charpos + field_width;
6728 /* Use the standard display table for displaying strings. */
6729 if (DISP_TABLE_P (Vstandard_display_table))
6730 it->dp = XCHAR_TABLE (Vstandard_display_table);
6732 it->stop_charpos = charpos;
6733 it->prev_stop = charpos;
6734 it->base_level_stop = 0;
6735 if (it->bidi_p)
6737 it->bidi_it.first_elt = true;
6738 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6739 it->bidi_it.disp_pos = -1;
6741 if (s == NULL && it->multibyte_p)
6743 ptrdiff_t endpos = SCHARS (it->string);
6744 if (endpos > it->end_charpos)
6745 endpos = it->end_charpos;
6746 composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
6747 it->string);
6749 CHECK_IT (it);
6754 /***********************************************************************
6755 Iteration
6756 ***********************************************************************/
6758 /* Map enum it_method value to corresponding next_element_from_* function. */
6760 typedef bool (*next_element_function) (struct it *);
6762 static next_element_function const get_next_element[NUM_IT_METHODS] =
6764 next_element_from_buffer,
6765 next_element_from_display_vector,
6766 next_element_from_string,
6767 next_element_from_c_string,
6768 next_element_from_image,
6769 next_element_from_stretch,
6770 next_element_from_xwidget,
6773 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
6776 /* Return true iff a character at CHARPOS (and BYTEPOS) is composed
6777 (possibly with the following characters). */
6779 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
6780 ((IT)->cmp_it.id >= 0 \
6781 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
6782 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
6783 END_CHARPOS, (IT)->w, \
6784 FACE_FROM_ID_OR_NULL ((IT)->f, \
6785 (IT)->face_id), \
6786 (IT)->string)))
6789 /* Lookup the char-table Vglyphless_char_display for character C (-1
6790 if we want information for no-font case), and return the display
6791 method symbol. By side-effect, update it->what and
6792 it->glyphless_method. This function is called from
6793 get_next_display_element for each character element, and from
6794 x_produce_glyphs when no suitable font was found. */
6796 Lisp_Object
6797 lookup_glyphless_char_display (int c, struct it *it)
6799 Lisp_Object glyphless_method = Qnil;
6801 if (CHAR_TABLE_P (Vglyphless_char_display)
6802 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)
6804 if (c >= 0)
6806 glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
6807 if (CONSP (glyphless_method))
6808 glyphless_method = FRAME_WINDOW_P (it->f)
6809 ? XCAR (glyphless_method)
6810 : XCDR (glyphless_method);
6812 else
6813 glyphless_method = XCHAR_TABLE (Vglyphless_char_display)->extras[0];
6816 retry:
6817 if (NILP (glyphless_method))
6819 if (c >= 0)
6820 /* The default is to display the character by a proper font. */
6821 return Qnil;
6822 /* The default for the no-font case is to display an empty box. */
6823 glyphless_method = Qempty_box;
6825 if (EQ (glyphless_method, Qzero_width))
6827 if (c >= 0)
6828 return glyphless_method;
6829 /* This method can't be used for the no-font case. */
6830 glyphless_method = Qempty_box;
6832 if (EQ (glyphless_method, Qthin_space))
6833 it->glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE;
6834 else if (EQ (glyphless_method, Qempty_box))
6835 it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX;
6836 else if (EQ (glyphless_method, Qhex_code))
6837 it->glyphless_method = GLYPHLESS_DISPLAY_HEX_CODE;
6838 else if (STRINGP (glyphless_method))
6839 it->glyphless_method = GLYPHLESS_DISPLAY_ACRONYM;
6840 else
6842 /* Invalid value. We use the default method. */
6843 glyphless_method = Qnil;
6844 goto retry;
6846 it->what = IT_GLYPHLESS;
6847 return glyphless_method;
6850 /* Merge escape glyph face and cache the result. */
6852 static struct frame *last_escape_glyph_frame = NULL;
6853 static int last_escape_glyph_face_id = (1 << FACE_ID_BITS);
6854 static int last_escape_glyph_merged_face_id = 0;
6856 static int
6857 merge_escape_glyph_face (struct it *it)
6859 int face_id;
6861 if (it->f == last_escape_glyph_frame
6862 && it->face_id == last_escape_glyph_face_id)
6863 face_id = last_escape_glyph_merged_face_id;
6864 else
6866 /* Merge the `escape-glyph' face into the current face. */
6867 face_id = merge_faces (it->f, Qescape_glyph, 0, it->face_id);
6868 last_escape_glyph_frame = it->f;
6869 last_escape_glyph_face_id = it->face_id;
6870 last_escape_glyph_merged_face_id = face_id;
6872 return face_id;
6875 /* Likewise for glyphless glyph face. */
6877 static struct frame *last_glyphless_glyph_frame = NULL;
6878 static int last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
6879 static int last_glyphless_glyph_merged_face_id = 0;
6882 merge_glyphless_glyph_face (struct it *it)
6884 int face_id;
6886 if (it->f == last_glyphless_glyph_frame
6887 && it->face_id == last_glyphless_glyph_face_id)
6888 face_id = last_glyphless_glyph_merged_face_id;
6889 else
6891 /* Merge the `glyphless-char' face into the current face. */
6892 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
6893 last_glyphless_glyph_frame = it->f;
6894 last_glyphless_glyph_face_id = it->face_id;
6895 last_glyphless_glyph_merged_face_id = face_id;
6897 return face_id;
6900 /* Forget the `escape-glyph' and `glyphless-char' faces. This should
6901 be called before redisplaying windows, and when the frame's face
6902 cache is freed. */
6903 void
6904 forget_escape_and_glyphless_faces (void)
6906 last_escape_glyph_frame = NULL;
6907 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
6908 last_glyphless_glyph_frame = NULL;
6909 last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
6912 /* Load IT's display element fields with information about the next
6913 display element from the current position of IT. Value is false if
6914 end of buffer (or C string) is reached. */
6916 static bool
6917 get_next_display_element (struct it *it)
6919 /* True means that we found a display element. False means that
6920 we hit the end of what we iterate over. Performance note: the
6921 function pointer `method' used here turns out to be faster than
6922 using a sequence of if-statements. */
6923 bool success_p;
6925 get_next:
6926 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
6928 if (it->what == IT_CHARACTER)
6930 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
6931 and only if (a) the resolved directionality of that character
6932 is R..." */
6933 /* FIXME: Do we need an exception for characters from display
6934 tables? */
6935 if (it->bidi_p && it->bidi_it.type == STRONG_R
6936 && !inhibit_bidi_mirroring)
6937 it->c = bidi_mirror_char (it->c);
6938 /* Map via display table or translate control characters.
6939 IT->c, IT->len etc. have been set to the next character by
6940 the function call above. If we have a display table, and it
6941 contains an entry for IT->c, translate it. Don't do this if
6942 IT->c itself comes from a display table, otherwise we could
6943 end up in an infinite recursion. (An alternative could be to
6944 count the recursion depth of this function and signal an
6945 error when a certain maximum depth is reached.) Is it worth
6946 it? */
6947 if (success_p && it->dpvec == NULL)
6949 Lisp_Object dv;
6950 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
6951 bool nonascii_space_p = false;
6952 bool nonascii_hyphen_p = false;
6953 int c = it->c; /* This is the character to display. */
6955 if (! it->multibyte_p && ! ASCII_CHAR_P (c))
6957 eassert (SINGLE_BYTE_CHAR_P (c));
6958 if (unibyte_display_via_language_environment)
6960 c = DECODE_CHAR (unibyte, c);
6961 if (c < 0)
6962 c = BYTE8_TO_CHAR (it->c);
6964 else
6965 c = BYTE8_TO_CHAR (it->c);
6968 if (it->dp
6969 && (dv = DISP_CHAR_VECTOR (it->dp, c),
6970 VECTORP (dv)))
6972 struct Lisp_Vector *v = XVECTOR (dv);
6974 /* Return the first character from the display table
6975 entry, if not empty. If empty, don't display the
6976 current character. */
6977 if (v->header.size)
6979 it->dpvec_char_len = it->len;
6980 it->dpvec = v->contents;
6981 it->dpend = v->contents + v->header.size;
6982 it->current.dpvec_index = 0;
6983 it->dpvec_face_id = -1;
6984 it->saved_face_id = it->face_id;
6985 it->method = GET_FROM_DISPLAY_VECTOR;
6986 it->ellipsis_p = false;
6988 else
6990 set_iterator_to_next (it, false);
6992 goto get_next;
6995 if (! NILP (lookup_glyphless_char_display (c, it)))
6997 if (it->what == IT_GLYPHLESS)
6998 goto done;
6999 /* Don't display this character. */
7000 set_iterator_to_next (it, false);
7001 goto get_next;
7004 /* If `nobreak-char-display' is non-nil, we display
7005 non-ASCII spaces and hyphens specially. */
7006 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
7008 if (c == NO_BREAK_SPACE)
7009 nonascii_space_p = true;
7010 else if (c == SOFT_HYPHEN || c == HYPHEN
7011 || c == NON_BREAKING_HYPHEN)
7012 nonascii_hyphen_p = true;
7015 /* Translate control characters into `\003' or `^C' form.
7016 Control characters coming from a display table entry are
7017 currently not translated because we use IT->dpvec to hold
7018 the translation. This could easily be changed but I
7019 don't believe that it is worth doing.
7021 The characters handled by `nobreak-char-display' must be
7022 translated too.
7024 Non-printable characters and raw-byte characters are also
7025 translated to octal form. */
7026 if (((c < ' ' || c == 127) /* ASCII control chars. */
7027 ? (it->area != TEXT_AREA
7028 /* In mode line, treat \n, \t like other crl chars. */
7029 || (c != '\t'
7030 && it->glyph_row
7031 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
7032 || (c != '\n' && c != '\t'))
7033 : (nonascii_space_p
7034 || nonascii_hyphen_p
7035 || CHAR_BYTE8_P (c)
7036 || ! CHAR_PRINTABLE_P (c))))
7038 /* C is a control character, non-ASCII space/hyphen,
7039 raw-byte, or a non-printable character which must be
7040 displayed either as '\003' or as `^C' where the '\\'
7041 and '^' can be defined in the display table. Fill
7042 IT->ctl_chars with glyphs for what we have to
7043 display. Then, set IT->dpvec to these glyphs. */
7044 Lisp_Object gc;
7045 int ctl_len;
7046 int face_id;
7047 int lface_id = 0;
7048 int escape_glyph;
7050 /* Handle control characters with ^. */
7052 if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
7054 int g;
7056 g = '^'; /* default glyph for Control */
7057 /* Set IT->ctl_chars[0] to the glyph for `^'. */
7058 if (it->dp
7059 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc)))
7061 g = GLYPH_CODE_CHAR (gc);
7062 lface_id = GLYPH_CODE_FACE (gc);
7065 face_id = (lface_id
7066 ? merge_faces (it->f, Qt, lface_id, it->face_id)
7067 : merge_escape_glyph_face (it));
7069 XSETINT (it->ctl_chars[0], g);
7070 XSETINT (it->ctl_chars[1], c ^ 0100);
7071 ctl_len = 2;
7072 goto display_control;
7075 /* Handle non-ascii space in the mode where it only gets
7076 highlighting. */
7078 if (nonascii_space_p && EQ (Vnobreak_char_display, Qt))
7080 /* Merge `nobreak-space' into the current face. */
7081 face_id = merge_faces (it->f, Qnobreak_space, 0,
7082 it->face_id);
7083 XSETINT (it->ctl_chars[0], ' ');
7084 ctl_len = 1;
7085 goto display_control;
7088 /* Handle non-ascii hyphens in the mode where it only
7089 gets highlighting. */
7091 if (nonascii_hyphen_p && EQ (Vnobreak_char_display, Qt))
7093 /* Merge `nobreak-space' into the current face. */
7094 face_id = merge_faces (it->f, Qnobreak_hyphen, 0,
7095 it->face_id);
7096 XSETINT (it->ctl_chars[0], '-');
7097 ctl_len = 1;
7098 goto display_control;
7101 /* Handle sequences that start with the "escape glyph". */
7103 /* the default escape glyph is \. */
7104 escape_glyph = '\\';
7106 if (it->dp
7107 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
7109 escape_glyph = GLYPH_CODE_CHAR (gc);
7110 lface_id = GLYPH_CODE_FACE (gc);
7113 face_id = (lface_id
7114 ? merge_faces (it->f, Qt, lface_id, it->face_id)
7115 : merge_escape_glyph_face (it));
7117 /* Draw non-ASCII space/hyphen with escape glyph: */
7119 if (nonascii_space_p || nonascii_hyphen_p)
7121 XSETINT (it->ctl_chars[0], escape_glyph);
7122 XSETINT (it->ctl_chars[1], nonascii_space_p ? ' ' : '-');
7123 ctl_len = 2;
7124 goto display_control;
7128 char str[10];
7129 int len, i;
7131 if (CHAR_BYTE8_P (c))
7132 /* Display \200 instead of \17777600. */
7133 c = CHAR_TO_BYTE8 (c);
7134 len = sprintf (str, "%03o", c + 0u);
7136 XSETINT (it->ctl_chars[0], escape_glyph);
7137 for (i = 0; i < len; i++)
7138 XSETINT (it->ctl_chars[i + 1], str[i]);
7139 ctl_len = len + 1;
7142 display_control:
7143 /* Set up IT->dpvec and return first character from it. */
7144 it->dpvec_char_len = it->len;
7145 it->dpvec = it->ctl_chars;
7146 it->dpend = it->dpvec + ctl_len;
7147 it->current.dpvec_index = 0;
7148 it->dpvec_face_id = face_id;
7149 it->saved_face_id = it->face_id;
7150 it->method = GET_FROM_DISPLAY_VECTOR;
7151 it->ellipsis_p = false;
7152 goto get_next;
7154 it->char_to_display = c;
7156 else if (success_p)
7158 it->char_to_display = it->c;
7162 #ifdef HAVE_WINDOW_SYSTEM
7163 /* Adjust face id for a multibyte character. There are no multibyte
7164 character in unibyte text. */
7165 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
7166 && it->multibyte_p
7167 && success_p
7168 && FRAME_WINDOW_P (it->f))
7170 struct face *face = FACE_FROM_ID (it->f, it->face_id);
7172 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
7174 /* Automatic composition with glyph-string. */
7175 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
7177 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
7179 else
7181 ptrdiff_t pos = (it->s ? -1
7182 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
7183 : IT_CHARPOS (*it));
7184 int c;
7186 if (it->what == IT_CHARACTER)
7187 c = it->char_to_display;
7188 else
7190 struct composition *cmp = composition_table[it->cmp_it.id];
7191 int i;
7193 c = ' ';
7194 for (i = 0; i < cmp->glyph_len; i++)
7195 /* TAB in a composition means display glyphs with
7196 padding space on the left or right. */
7197 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
7198 break;
7200 it->face_id = FACE_FOR_CHAR (it->f, face, c, pos, it->string);
7203 #endif /* HAVE_WINDOW_SYSTEM */
7205 done:
7206 /* Is this character the last one of a run of characters with
7207 box? If yes, set IT->end_of_box_run_p to true. */
7208 if (it->face_box_p
7209 && it->s == NULL)
7211 if (it->method == GET_FROM_STRING && it->sp)
7213 int face_id = underlying_face_id (it);
7214 struct face *face = FACE_FROM_ID_OR_NULL (it->f, face_id);
7216 if (face)
7218 if (face->box == FACE_NO_BOX)
7220 /* If the box comes from face properties in a
7221 display string, check faces in that string. */
7222 int string_face_id = face_after_it_pos (it);
7223 it->end_of_box_run_p
7224 = (FACE_FROM_ID (it->f, string_face_id)->box
7225 == FACE_NO_BOX);
7227 /* Otherwise, the box comes from the underlying face.
7228 If this is the last string character displayed, check
7229 the next buffer location. */
7230 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
7231 /* n_overlay_strings is unreliable unless
7232 overlay_string_index is non-negative. */
7233 && ((it->current.overlay_string_index >= 0
7234 && (it->current.overlay_string_index
7235 == it->n_overlay_strings - 1))
7236 /* A string from display property. */
7237 || it->from_disp_prop_p))
7239 ptrdiff_t ignore;
7240 int next_face_id;
7241 bool text_from_string = false;
7242 /* Normally, the next buffer location is stored in
7243 IT->current.pos... */
7244 struct text_pos pos = it->current.pos;
7246 /* ...but for a string from a display property, the
7247 next buffer position is stored in the 'position'
7248 member of the iteration stack slot below the
7249 current one, see handle_single_display_spec. By
7250 contrast, it->current.pos was not yet updated to
7251 point to that buffer position; that will happen
7252 in pop_it, after we finish displaying the current
7253 string. Note that we already checked above that
7254 it->sp is positive, so subtracting one from it is
7255 safe. */
7256 if (it->from_disp_prop_p)
7258 int stackp = it->sp - 1;
7260 /* Find the stack level with data from buffer. */
7261 while (stackp >= 0
7262 && STRINGP ((it->stack + stackp)->string))
7263 stackp--;
7264 if (stackp < 0)
7266 /* If no stack slot was found for iterating
7267 a buffer, we are displaying text from a
7268 string, most probably the mode line or
7269 the header line, and that string has a
7270 display string on some of its
7271 characters. */
7272 text_from_string = true;
7273 pos = it->stack[it->sp - 1].position;
7275 else
7276 pos = (it->stack + stackp)->position;
7278 else
7279 INC_TEXT_POS (pos, it->multibyte_p);
7281 if (text_from_string)
7283 Lisp_Object base_string = it->stack[it->sp - 1].string;
7285 if (CHARPOS (pos) >= SCHARS (base_string) - 1)
7286 it->end_of_box_run_p = true;
7287 else
7289 next_face_id
7290 = face_at_string_position (it->w, base_string,
7291 CHARPOS (pos), 0,
7292 &ignore, face_id, false);
7293 it->end_of_box_run_p
7294 = (FACE_FROM_ID (it->f, next_face_id)->box
7295 == FACE_NO_BOX);
7298 else if (CHARPOS (pos) >= ZV)
7299 it->end_of_box_run_p = true;
7300 else
7302 next_face_id =
7303 face_at_buffer_position (it->w, CHARPOS (pos), &ignore,
7304 CHARPOS (pos)
7305 + TEXT_PROP_DISTANCE_LIMIT,
7306 false, -1);
7307 it->end_of_box_run_p
7308 = (FACE_FROM_ID (it->f, next_face_id)->box
7309 == FACE_NO_BOX);
7314 /* next_element_from_display_vector sets this flag according to
7315 faces of the display vector glyphs, see there. */
7316 else if (it->method != GET_FROM_DISPLAY_VECTOR)
7318 int face_id = face_after_it_pos (it);
7319 it->end_of_box_run_p
7320 = (face_id != it->face_id
7321 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
7324 /* If we reached the end of the object we've been iterating (e.g., a
7325 display string or an overlay string), and there's something on
7326 IT->stack, proceed with what's on the stack. It doesn't make
7327 sense to return false if there's unprocessed stuff on the stack,
7328 because otherwise that stuff will never be displayed. */
7329 if (!success_p && it->sp > 0)
7331 set_iterator_to_next (it, false);
7332 success_p = get_next_display_element (it);
7335 /* Value is false if end of buffer or string reached. */
7336 return success_p;
7340 /* Move IT to the next display element.
7342 RESEAT_P means if called on a newline in buffer text,
7343 skip to the next visible line start.
7345 Functions get_next_display_element and set_iterator_to_next are
7346 separate because I find this arrangement easier to handle than a
7347 get_next_display_element function that also increments IT's
7348 position. The way it is we can first look at an iterator's current
7349 display element, decide whether it fits on a line, and if it does,
7350 increment the iterator position. The other way around we probably
7351 would either need a flag indicating whether the iterator has to be
7352 incremented the next time, or we would have to implement a
7353 decrement position function which would not be easy to write. */
7355 void
7356 set_iterator_to_next (struct it *it, bool reseat_p)
7358 /* Reset flags indicating start and end of a sequence of characters
7359 with box. Reset them at the start of this function because
7360 moving the iterator to a new position might set them. */
7361 it->start_of_box_run_p = it->end_of_box_run_p = false;
7363 switch (it->method)
7365 case GET_FROM_BUFFER:
7366 /* The current display element of IT is a character from
7367 current_buffer. Advance in the buffer, and maybe skip over
7368 invisible lines that are so because of selective display. */
7369 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
7370 reseat_at_next_visible_line_start (it, false);
7371 else if (it->cmp_it.id >= 0)
7373 /* We are currently getting glyphs from a composition. */
7374 if (! it->bidi_p)
7376 IT_CHARPOS (*it) += it->cmp_it.nchars;
7377 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
7379 else
7381 int i;
7383 /* Update IT's char/byte positions to point to the first
7384 character of the next grapheme cluster, or to the
7385 character visually after the current composition. */
7386 for (i = 0; i < it->cmp_it.nchars; i++)
7387 bidi_move_to_visually_next (&it->bidi_it);
7388 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7389 IT_CHARPOS (*it) = it->bidi_it.charpos;
7392 if ((! it->bidi_p || ! it->cmp_it.reversed_p)
7393 && it->cmp_it.to < it->cmp_it.nglyphs)
7395 /* Composition created while scanning forward. Proceed
7396 to the next grapheme cluster. */
7397 it->cmp_it.from = it->cmp_it.to;
7399 else if ((it->bidi_p && it->cmp_it.reversed_p)
7400 && it->cmp_it.from > 0)
7402 /* Composition created while scanning backward. Proceed
7403 to the previous grapheme cluster. */
7404 it->cmp_it.to = it->cmp_it.from;
7406 else
7408 /* No more grapheme clusters in this composition.
7409 Find the next stop position. */
7410 ptrdiff_t stop = it->end_charpos;
7412 if (it->bidi_it.scan_dir < 0)
7413 /* Now we are scanning backward and don't know
7414 where to stop. */
7415 stop = -1;
7416 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7417 IT_BYTEPOS (*it), stop, Qnil);
7420 else
7422 eassert (it->len != 0);
7424 if (!it->bidi_p)
7426 IT_BYTEPOS (*it) += it->len;
7427 IT_CHARPOS (*it) += 1;
7429 else
7431 int prev_scan_dir = it->bidi_it.scan_dir;
7432 /* If this is a new paragraph, determine its base
7433 direction (a.k.a. its base embedding level). */
7434 if (it->bidi_it.new_paragraph)
7435 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it,
7436 false);
7437 bidi_move_to_visually_next (&it->bidi_it);
7438 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7439 IT_CHARPOS (*it) = it->bidi_it.charpos;
7440 if (prev_scan_dir != it->bidi_it.scan_dir)
7442 /* As the scan direction was changed, we must
7443 re-compute the stop position for composition. */
7444 ptrdiff_t stop = it->end_charpos;
7445 if (it->bidi_it.scan_dir < 0)
7446 stop = -1;
7447 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7448 IT_BYTEPOS (*it), stop, Qnil);
7451 eassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
7453 break;
7455 case GET_FROM_C_STRING:
7456 /* Current display element of IT is from a C string. */
7457 if (!it->bidi_p
7458 /* If the string position is beyond string's end, it means
7459 next_element_from_c_string is padding the string with
7460 blanks, in which case we bypass the bidi iterator,
7461 because it cannot deal with such virtual characters. */
7462 || IT_CHARPOS (*it) >= it->bidi_it.string.schars)
7464 IT_BYTEPOS (*it) += it->len;
7465 IT_CHARPOS (*it) += 1;
7467 else
7469 bidi_move_to_visually_next (&it->bidi_it);
7470 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7471 IT_CHARPOS (*it) = it->bidi_it.charpos;
7473 break;
7475 case GET_FROM_DISPLAY_VECTOR:
7476 /* Current display element of IT is from a display table entry.
7477 Advance in the display table definition. Reset it to null if
7478 end reached, and continue with characters from buffers/
7479 strings. */
7480 ++it->current.dpvec_index;
7482 /* Restore face of the iterator to what they were before the
7483 display vector entry (these entries may contain faces). */
7484 it->face_id = it->saved_face_id;
7486 if (it->dpvec + it->current.dpvec_index >= it->dpend)
7488 bool recheck_faces = it->ellipsis_p;
7490 if (it->s)
7491 it->method = GET_FROM_C_STRING;
7492 else if (STRINGP (it->string))
7493 it->method = GET_FROM_STRING;
7494 else
7496 it->method = GET_FROM_BUFFER;
7497 it->object = it->w->contents;
7500 it->dpvec = NULL;
7501 it->current.dpvec_index = -1;
7503 /* Skip over characters which were displayed via IT->dpvec. */
7504 if (it->dpvec_char_len < 0)
7505 reseat_at_next_visible_line_start (it, true);
7506 else if (it->dpvec_char_len > 0)
7508 it->len = it->dpvec_char_len;
7509 set_iterator_to_next (it, reseat_p);
7512 /* Maybe recheck faces after display vector. */
7513 if (recheck_faces)
7515 if (it->method == GET_FROM_STRING)
7516 it->stop_charpos = IT_STRING_CHARPOS (*it);
7517 else
7518 it->stop_charpos = IT_CHARPOS (*it);
7521 break;
7523 case GET_FROM_STRING:
7524 /* Current display element is a character from a Lisp string. */
7525 eassert (it->s == NULL && STRINGP (it->string));
7526 /* Don't advance past string end. These conditions are true
7527 when set_iterator_to_next is called at the end of
7528 get_next_display_element, in which case the Lisp string is
7529 already exhausted, and all we want is pop the iterator
7530 stack. */
7531 if (it->current.overlay_string_index >= 0)
7533 /* This is an overlay string, so there's no padding with
7534 spaces, and the number of characters in the string is
7535 where the string ends. */
7536 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7537 goto consider_string_end;
7539 else
7541 /* Not an overlay string. There could be padding, so test
7542 against it->end_charpos. */
7543 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7544 goto consider_string_end;
7546 if (it->cmp_it.id >= 0)
7548 /* We are delivering display elements from a composition.
7549 Update the string position past the grapheme cluster
7550 we've just processed. */
7551 if (! it->bidi_p)
7553 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
7554 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
7556 else
7558 int i;
7560 for (i = 0; i < it->cmp_it.nchars; i++)
7561 bidi_move_to_visually_next (&it->bidi_it);
7562 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7563 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7566 /* Did we exhaust all the grapheme clusters of this
7567 composition? */
7568 if ((! it->bidi_p || ! it->cmp_it.reversed_p)
7569 && (it->cmp_it.to < it->cmp_it.nglyphs))
7571 /* Not all the grapheme clusters were processed yet;
7572 advance to the next cluster. */
7573 it->cmp_it.from = it->cmp_it.to;
7575 else if ((it->bidi_p && it->cmp_it.reversed_p)
7576 && it->cmp_it.from > 0)
7578 /* Likewise: advance to the next cluster, but going in
7579 the reverse direction. */
7580 it->cmp_it.to = it->cmp_it.from;
7582 else
7584 /* This composition was fully processed; find the next
7585 candidate place for checking for composed
7586 characters. */
7587 /* Always limit string searches to the string length;
7588 any padding spaces are not part of the string, and
7589 there cannot be any compositions in that padding. */
7590 ptrdiff_t stop = SCHARS (it->string);
7592 if (it->bidi_p && it->bidi_it.scan_dir < 0)
7593 stop = -1;
7594 else if (it->end_charpos < stop)
7596 /* Cf. PRECISION in reseat_to_string: we might be
7597 limited in how many of the string characters we
7598 need to deliver. */
7599 stop = it->end_charpos;
7601 composition_compute_stop_pos (&it->cmp_it,
7602 IT_STRING_CHARPOS (*it),
7603 IT_STRING_BYTEPOS (*it), stop,
7604 it->string);
7607 else
7609 if (!it->bidi_p
7610 /* If the string position is beyond string's end, it
7611 means next_element_from_string is padding the string
7612 with blanks, in which case we bypass the bidi
7613 iterator, because it cannot deal with such virtual
7614 characters. */
7615 || IT_STRING_CHARPOS (*it) >= it->bidi_it.string.schars)
7617 IT_STRING_BYTEPOS (*it) += it->len;
7618 IT_STRING_CHARPOS (*it) += 1;
7620 else
7622 int prev_scan_dir = it->bidi_it.scan_dir;
7624 bidi_move_to_visually_next (&it->bidi_it);
7625 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7626 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7627 /* If the scan direction changes, we may need to update
7628 the place where to check for composed characters. */
7629 if (prev_scan_dir != it->bidi_it.scan_dir)
7631 ptrdiff_t stop = SCHARS (it->string);
7633 if (it->bidi_it.scan_dir < 0)
7634 stop = -1;
7635 else if (it->end_charpos < stop)
7636 stop = it->end_charpos;
7638 composition_compute_stop_pos (&it->cmp_it,
7639 IT_STRING_CHARPOS (*it),
7640 IT_STRING_BYTEPOS (*it), stop,
7641 it->string);
7646 consider_string_end:
7648 if (it->current.overlay_string_index >= 0)
7650 /* IT->string is an overlay string. Advance to the
7651 next, if there is one. */
7652 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7654 it->ellipsis_p = false;
7655 next_overlay_string (it);
7656 if (it->ellipsis_p)
7657 setup_for_ellipsis (it, 0);
7660 else
7662 /* IT->string is not an overlay string. If we reached
7663 its end, and there is something on IT->stack, proceed
7664 with what is on the stack. This can be either another
7665 string, this time an overlay string, or a buffer. */
7666 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
7667 && it->sp > 0)
7669 pop_it (it);
7670 if (it->method == GET_FROM_STRING)
7671 goto consider_string_end;
7674 break;
7676 case GET_FROM_IMAGE:
7677 case GET_FROM_STRETCH:
7678 case GET_FROM_XWIDGET:
7680 /* The position etc with which we have to proceed are on
7681 the stack. The position may be at the end of a string,
7682 if the `display' property takes up the whole string. */
7683 eassert (it->sp > 0);
7684 pop_it (it);
7685 if (it->method == GET_FROM_STRING)
7686 goto consider_string_end;
7687 break;
7689 default:
7690 /* There are no other methods defined, so this should be a bug. */
7691 emacs_abort ();
7694 eassert (it->method != GET_FROM_STRING
7695 || (STRINGP (it->string)
7696 && IT_STRING_CHARPOS (*it) >= 0));
7699 /* Load IT's display element fields with information about the next
7700 display element which comes from a display table entry or from the
7701 result of translating a control character to one of the forms `^C'
7702 or `\003'.
7704 IT->dpvec holds the glyphs to return as characters.
7705 IT->saved_face_id holds the face id before the display vector--it
7706 is restored into IT->face_id in set_iterator_to_next. */
7708 static bool
7709 next_element_from_display_vector (struct it *it)
7711 Lisp_Object gc;
7712 int prev_face_id = it->face_id;
7713 int next_face_id;
7715 /* Precondition. */
7716 eassert (it->dpvec && it->current.dpvec_index >= 0);
7718 it->face_id = it->saved_face_id;
7720 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
7721 That seemed totally bogus - so I changed it... */
7722 gc = it->dpvec[it->current.dpvec_index];
7724 if (GLYPH_CODE_P (gc))
7726 struct face *this_face, *prev_face, *next_face;
7728 it->c = GLYPH_CODE_CHAR (gc);
7729 it->len = CHAR_BYTES (it->c);
7731 /* The entry may contain a face id to use. Such a face id is
7732 the id of a Lisp face, not a realized face. A face id of
7733 zero means no face is specified. */
7734 if (it->dpvec_face_id >= 0)
7735 it->face_id = it->dpvec_face_id;
7736 else
7738 int lface_id = GLYPH_CODE_FACE (gc);
7739 if (lface_id > 0)
7740 it->face_id = merge_faces (it->f, Qt, lface_id,
7741 it->saved_face_id);
7744 /* Glyphs in the display vector could have the box face, so we
7745 need to set the related flags in the iterator, as
7746 appropriate. */
7747 this_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id);
7748 prev_face = FACE_FROM_ID_OR_NULL (it->f, prev_face_id);
7750 /* Is this character the first character of a box-face run? */
7751 it->start_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
7752 && (!prev_face
7753 || prev_face->box == FACE_NO_BOX));
7755 /* For the last character of the box-face run, we need to look
7756 either at the next glyph from the display vector, or at the
7757 face we saw before the display vector. */
7758 next_face_id = it->saved_face_id;
7759 if (it->current.dpvec_index < it->dpend - it->dpvec - 1)
7761 if (it->dpvec_face_id >= 0)
7762 next_face_id = it->dpvec_face_id;
7763 else
7765 int lface_id =
7766 GLYPH_CODE_FACE (it->dpvec[it->current.dpvec_index + 1]);
7768 if (lface_id > 0)
7769 next_face_id = merge_faces (it->f, Qt, lface_id,
7770 it->saved_face_id);
7773 next_face = FACE_FROM_ID_OR_NULL (it->f, next_face_id);
7774 it->end_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
7775 && (!next_face
7776 || next_face->box == FACE_NO_BOX));
7777 it->face_box_p = this_face && this_face->box != FACE_NO_BOX;
7779 else
7780 /* Display table entry is invalid. Return a space. */
7781 it->c = ' ', it->len = 1;
7783 /* Don't change position and object of the iterator here. They are
7784 still the values of the character that had this display table
7785 entry or was translated, and that's what we want. */
7786 it->what = IT_CHARACTER;
7787 return true;
7790 /* Get the first element of string/buffer in the visual order, after
7791 being reseated to a new position in a string or a buffer. */
7792 static void
7793 get_visually_first_element (struct it *it)
7795 bool string_p = STRINGP (it->string) || it->s;
7796 ptrdiff_t eob = (string_p ? it->bidi_it.string.schars : ZV);
7797 ptrdiff_t bob = (string_p ? 0 : BEGV);
7799 if (STRINGP (it->string))
7801 it->bidi_it.charpos = IT_STRING_CHARPOS (*it);
7802 it->bidi_it.bytepos = IT_STRING_BYTEPOS (*it);
7804 else
7806 it->bidi_it.charpos = IT_CHARPOS (*it);
7807 it->bidi_it.bytepos = IT_BYTEPOS (*it);
7810 if (it->bidi_it.charpos == eob)
7812 /* Nothing to do, but reset the FIRST_ELT flag, like
7813 bidi_paragraph_init does, because we are not going to
7814 call it. */
7815 it->bidi_it.first_elt = false;
7817 else if (it->bidi_it.charpos == bob
7818 || (!string_p
7819 && (FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
7820 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')))
7822 /* If we are at the beginning of a line/string, we can produce
7823 the next element right away. */
7824 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, true);
7825 bidi_move_to_visually_next (&it->bidi_it);
7827 else
7829 ptrdiff_t orig_bytepos = it->bidi_it.bytepos;
7831 /* We need to prime the bidi iterator starting at the line's or
7832 string's beginning, before we will be able to produce the
7833 next element. */
7834 if (string_p)
7835 it->bidi_it.charpos = it->bidi_it.bytepos = 0;
7836 else
7837 it->bidi_it.charpos = find_newline_no_quit (IT_CHARPOS (*it),
7838 IT_BYTEPOS (*it), -1,
7839 &it->bidi_it.bytepos);
7840 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, true);
7843 /* Now return to buffer/string position where we were asked
7844 to get the next display element, and produce that. */
7845 bidi_move_to_visually_next (&it->bidi_it);
7847 while (it->bidi_it.bytepos != orig_bytepos
7848 && it->bidi_it.charpos < eob);
7851 /* Adjust IT's position information to where we ended up. */
7852 if (STRINGP (it->string))
7854 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7855 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7857 else
7859 IT_CHARPOS (*it) = it->bidi_it.charpos;
7860 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7863 if (STRINGP (it->string) || !it->s)
7865 ptrdiff_t stop, charpos, bytepos;
7867 if (STRINGP (it->string))
7869 eassert (!it->s);
7870 stop = SCHARS (it->string);
7871 if (stop > it->end_charpos)
7872 stop = it->end_charpos;
7873 charpos = IT_STRING_CHARPOS (*it);
7874 bytepos = IT_STRING_BYTEPOS (*it);
7876 else
7878 stop = it->end_charpos;
7879 charpos = IT_CHARPOS (*it);
7880 bytepos = IT_BYTEPOS (*it);
7882 if (it->bidi_it.scan_dir < 0)
7883 stop = -1;
7884 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, stop,
7885 it->string);
7889 /* Load IT with the next display element from Lisp string IT->string.
7890 IT->current.string_pos is the current position within the string.
7891 If IT->current.overlay_string_index >= 0, the Lisp string is an
7892 overlay string. */
7894 static bool
7895 next_element_from_string (struct it *it)
7897 struct text_pos position;
7899 eassert (STRINGP (it->string));
7900 eassert (!it->bidi_p || EQ (it->string, it->bidi_it.string.lstring));
7901 eassert (IT_STRING_CHARPOS (*it) >= 0);
7902 position = it->current.string_pos;
7904 /* With bidi reordering, the character to display might not be the
7905 character at IT_STRING_CHARPOS. BIDI_IT.FIRST_ELT means
7906 that we were reseat()ed to a new string, whose paragraph
7907 direction is not known. */
7908 if (it->bidi_p && it->bidi_it.first_elt)
7910 get_visually_first_element (it);
7911 SET_TEXT_POS (position, IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it));
7914 /* Time to check for invisible text? */
7915 if (IT_STRING_CHARPOS (*it) < it->end_charpos)
7917 if (IT_STRING_CHARPOS (*it) >= it->stop_charpos)
7919 if (!(!it->bidi_p
7920 || BIDI_AT_BASE_LEVEL (it->bidi_it)
7921 || IT_STRING_CHARPOS (*it) == it->stop_charpos))
7923 /* With bidi non-linear iteration, we could find
7924 ourselves far beyond the last computed stop_charpos,
7925 with several other stop positions in between that we
7926 missed. Scan them all now, in buffer's logical
7927 order, until we find and handle the last stop_charpos
7928 that precedes our current position. */
7929 handle_stop_backwards (it, it->stop_charpos);
7930 return GET_NEXT_DISPLAY_ELEMENT (it);
7932 else
7934 if (it->bidi_p)
7936 /* Take note of the stop position we just moved
7937 across, for when we will move back across it. */
7938 it->prev_stop = it->stop_charpos;
7939 /* If we are at base paragraph embedding level, take
7940 note of the last stop position seen at this
7941 level. */
7942 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
7943 it->base_level_stop = it->stop_charpos;
7945 handle_stop (it);
7947 /* Since a handler may have changed IT->method, we must
7948 recurse here. */
7949 return GET_NEXT_DISPLAY_ELEMENT (it);
7952 else if (it->bidi_p
7953 /* If we are before prev_stop, we may have overstepped
7954 on our way backwards a stop_pos, and if so, we need
7955 to handle that stop_pos. */
7956 && IT_STRING_CHARPOS (*it) < it->prev_stop
7957 /* We can sometimes back up for reasons that have nothing
7958 to do with bidi reordering. E.g., compositions. The
7959 code below is only needed when we are above the base
7960 embedding level, so test for that explicitly. */
7961 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
7963 /* If we lost track of base_level_stop, we have no better
7964 place for handle_stop_backwards to start from than string
7965 beginning. This happens, e.g., when we were reseated to
7966 the previous screenful of text by vertical-motion. */
7967 if (it->base_level_stop <= 0
7968 || IT_STRING_CHARPOS (*it) < it->base_level_stop)
7969 it->base_level_stop = 0;
7970 handle_stop_backwards (it, it->base_level_stop);
7971 return GET_NEXT_DISPLAY_ELEMENT (it);
7975 if (it->current.overlay_string_index >= 0)
7977 /* Get the next character from an overlay string. In overlay
7978 strings, there is no field width or padding with spaces to
7979 do. */
7980 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7982 it->what = IT_EOB;
7983 return false;
7985 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7986 IT_STRING_BYTEPOS (*it),
7987 it->bidi_it.scan_dir < 0
7988 ? -1
7989 : SCHARS (it->string))
7990 && next_element_from_composition (it))
7992 return true;
7994 else if (STRING_MULTIBYTE (it->string))
7996 const unsigned char *s = (SDATA (it->string)
7997 + IT_STRING_BYTEPOS (*it));
7998 it->c = string_char_and_length (s, &it->len);
8000 else
8002 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
8003 it->len = 1;
8006 else
8008 /* Get the next character from a Lisp string that is not an
8009 overlay string. Such strings come from the mode line, for
8010 example. We may have to pad with spaces, or truncate the
8011 string. See also next_element_from_c_string. */
8012 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
8014 it->what = IT_EOB;
8015 return false;
8017 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
8019 /* Pad with spaces. */
8020 it->c = ' ', it->len = 1;
8021 CHARPOS (position) = BYTEPOS (position) = -1;
8023 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
8024 IT_STRING_BYTEPOS (*it),
8025 it->bidi_it.scan_dir < 0
8026 ? -1
8027 : it->string_nchars)
8028 && next_element_from_composition (it))
8030 return true;
8032 else if (STRING_MULTIBYTE (it->string))
8034 const unsigned char *s = (SDATA (it->string)
8035 + IT_STRING_BYTEPOS (*it));
8036 it->c = string_char_and_length (s, &it->len);
8038 else
8040 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
8041 it->len = 1;
8045 /* Record what we have and where it came from. */
8046 it->what = IT_CHARACTER;
8047 it->object = it->string;
8048 it->position = position;
8049 return true;
8053 /* Load IT with next display element from C string IT->s.
8054 IT->string_nchars is the maximum number of characters to return
8055 from the string. IT->end_charpos may be greater than
8056 IT->string_nchars when this function is called, in which case we
8057 may have to return padding spaces. Value is false if end of string
8058 reached, including padding spaces. */
8060 static bool
8061 next_element_from_c_string (struct it *it)
8063 bool success_p = true;
8065 eassert (it->s);
8066 eassert (!it->bidi_p || it->s == it->bidi_it.string.s);
8067 it->what = IT_CHARACTER;
8068 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
8069 it->object = make_number (0);
8071 /* With bidi reordering, the character to display might not be the
8072 character at IT_CHARPOS. BIDI_IT.FIRST_ELT means that
8073 we were reseated to a new string, whose paragraph direction is
8074 not known. */
8075 if (it->bidi_p && it->bidi_it.first_elt)
8076 get_visually_first_element (it);
8078 /* IT's position can be greater than IT->string_nchars in case a
8079 field width or precision has been specified when the iterator was
8080 initialized. */
8081 if (IT_CHARPOS (*it) >= it->end_charpos)
8083 /* End of the game. */
8084 it->what = IT_EOB;
8085 success_p = false;
8087 else if (IT_CHARPOS (*it) >= it->string_nchars)
8089 /* Pad with spaces. */
8090 it->c = ' ', it->len = 1;
8091 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
8093 else if (it->multibyte_p)
8094 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
8095 else
8096 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
8098 return success_p;
8102 /* Set up IT to return characters from an ellipsis, if appropriate.
8103 The definition of the ellipsis glyphs may come from a display table
8104 entry. This function fills IT with the first glyph from the
8105 ellipsis if an ellipsis is to be displayed. */
8107 static bool
8108 next_element_from_ellipsis (struct it *it)
8110 if (it->selective_display_ellipsis_p)
8111 setup_for_ellipsis (it, it->len);
8112 else
8114 /* The face at the current position may be different from the
8115 face we find after the invisible text. Remember what it
8116 was in IT->saved_face_id, and signal that it's there by
8117 setting face_before_selective_p. */
8118 it->saved_face_id = it->face_id;
8119 it->method = GET_FROM_BUFFER;
8120 it->object = it->w->contents;
8121 reseat_at_next_visible_line_start (it, true);
8122 it->face_before_selective_p = true;
8125 return GET_NEXT_DISPLAY_ELEMENT (it);
8129 /* Deliver an image display element. The iterator IT is already
8130 filled with image information (done in handle_display_prop). Value
8131 is always true. */
8134 static bool
8135 next_element_from_image (struct it *it)
8137 it->what = IT_IMAGE;
8138 return true;
8141 static bool
8142 next_element_from_xwidget (struct it *it)
8144 it->what = IT_XWIDGET;
8145 return true;
8149 /* Fill iterator IT with next display element from a stretch glyph
8150 property. IT->object is the value of the text property. Value is
8151 always true. */
8153 static bool
8154 next_element_from_stretch (struct it *it)
8156 it->what = IT_STRETCH;
8157 return true;
8160 /* Scan backwards from IT's current position until we find a stop
8161 position, or until BEGV. This is called when we find ourself
8162 before both the last known prev_stop and base_level_stop while
8163 reordering bidirectional text. */
8165 static void
8166 compute_stop_pos_backwards (struct it *it)
8168 const int SCAN_BACK_LIMIT = 1000;
8169 struct text_pos pos;
8170 struct display_pos save_current = it->current;
8171 struct text_pos save_position = it->position;
8172 ptrdiff_t charpos = IT_CHARPOS (*it);
8173 ptrdiff_t where_we_are = charpos;
8174 ptrdiff_t save_stop_pos = it->stop_charpos;
8175 ptrdiff_t save_end_pos = it->end_charpos;
8177 eassert (NILP (it->string) && !it->s);
8178 eassert (it->bidi_p);
8179 it->bidi_p = false;
8182 it->end_charpos = min (charpos + 1, ZV);
8183 charpos = max (charpos - SCAN_BACK_LIMIT, BEGV);
8184 SET_TEXT_POS (pos, charpos, CHAR_TO_BYTE (charpos));
8185 reseat_1 (it, pos, false);
8186 compute_stop_pos (it);
8187 /* We must advance forward, right? */
8188 if (it->stop_charpos <= charpos)
8189 emacs_abort ();
8191 while (charpos > BEGV && it->stop_charpos >= it->end_charpos);
8193 if (it->stop_charpos <= where_we_are)
8194 it->prev_stop = it->stop_charpos;
8195 else
8196 it->prev_stop = BEGV;
8197 it->bidi_p = true;
8198 it->current = save_current;
8199 it->position = save_position;
8200 it->stop_charpos = save_stop_pos;
8201 it->end_charpos = save_end_pos;
8204 /* Scan forward from CHARPOS in the current buffer/string, until we
8205 find a stop position > current IT's position. Then handle the stop
8206 position before that. This is called when we bump into a stop
8207 position while reordering bidirectional text. CHARPOS should be
8208 the last previously processed stop_pos (or BEGV/0, if none were
8209 processed yet) whose position is less that IT's current
8210 position. */
8212 static void
8213 handle_stop_backwards (struct it *it, ptrdiff_t charpos)
8215 bool bufp = !STRINGP (it->string);
8216 ptrdiff_t where_we_are = (bufp ? IT_CHARPOS (*it) : IT_STRING_CHARPOS (*it));
8217 struct display_pos save_current = it->current;
8218 struct text_pos save_position = it->position;
8219 struct text_pos pos1;
8220 ptrdiff_t next_stop;
8222 /* Scan in strict logical order. */
8223 eassert (it->bidi_p);
8224 it->bidi_p = false;
8227 it->prev_stop = charpos;
8228 if (bufp)
8230 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
8231 reseat_1 (it, pos1, false);
8233 else
8234 it->current.string_pos = string_pos (charpos, it->string);
8235 compute_stop_pos (it);
8236 /* We must advance forward, right? */
8237 if (it->stop_charpos <= it->prev_stop)
8238 emacs_abort ();
8239 charpos = it->stop_charpos;
8241 while (charpos <= where_we_are);
8243 it->bidi_p = true;
8244 it->current = save_current;
8245 it->position = save_position;
8246 next_stop = it->stop_charpos;
8247 it->stop_charpos = it->prev_stop;
8248 handle_stop (it);
8249 it->stop_charpos = next_stop;
8252 /* Load IT with the next display element from current_buffer. Value
8253 is false if end of buffer reached. IT->stop_charpos is the next
8254 position at which to stop and check for text properties or buffer
8255 end. */
8257 static bool
8258 next_element_from_buffer (struct it *it)
8260 bool success_p = true;
8262 eassert (IT_CHARPOS (*it) >= BEGV);
8263 eassert (NILP (it->string) && !it->s);
8264 eassert (!it->bidi_p
8265 || (EQ (it->bidi_it.string.lstring, Qnil)
8266 && it->bidi_it.string.s == NULL));
8268 /* With bidi reordering, the character to display might not be the
8269 character at IT_CHARPOS. BIDI_IT.FIRST_ELT means that
8270 we were reseat()ed to a new buffer position, which is potentially
8271 a different paragraph. */
8272 if (it->bidi_p && it->bidi_it.first_elt)
8274 get_visually_first_element (it);
8275 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8278 if (IT_CHARPOS (*it) >= it->stop_charpos)
8280 if (IT_CHARPOS (*it) >= it->end_charpos)
8282 bool overlay_strings_follow_p;
8284 /* End of the game, except when overlay strings follow that
8285 haven't been returned yet. */
8286 if (it->overlay_strings_at_end_processed_p)
8287 overlay_strings_follow_p = false;
8288 else
8290 it->overlay_strings_at_end_processed_p = true;
8291 overlay_strings_follow_p = get_overlay_strings (it, 0);
8294 if (overlay_strings_follow_p)
8295 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
8296 else
8298 it->what = IT_EOB;
8299 it->position = it->current.pos;
8300 success_p = false;
8303 else if (!(!it->bidi_p
8304 || BIDI_AT_BASE_LEVEL (it->bidi_it)
8305 || IT_CHARPOS (*it) == it->stop_charpos))
8307 /* With bidi non-linear iteration, we could find ourselves
8308 far beyond the last computed stop_charpos, with several
8309 other stop positions in between that we missed. Scan
8310 them all now, in buffer's logical order, until we find
8311 and handle the last stop_charpos that precedes our
8312 current position. */
8313 handle_stop_backwards (it, it->stop_charpos);
8314 it->ignore_overlay_strings_at_pos_p = false;
8315 return GET_NEXT_DISPLAY_ELEMENT (it);
8317 else
8319 if (it->bidi_p)
8321 /* Take note of the stop position we just moved across,
8322 for when we will move back across it. */
8323 it->prev_stop = it->stop_charpos;
8324 /* If we are at base paragraph embedding level, take
8325 note of the last stop position seen at this
8326 level. */
8327 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
8328 it->base_level_stop = it->stop_charpos;
8330 handle_stop (it);
8331 it->ignore_overlay_strings_at_pos_p = false;
8332 return GET_NEXT_DISPLAY_ELEMENT (it);
8335 else if (it->bidi_p
8336 /* If we are before prev_stop, we may have overstepped on
8337 our way backwards a stop_pos, and if so, we need to
8338 handle that stop_pos. */
8339 && IT_CHARPOS (*it) < it->prev_stop
8340 /* We can sometimes back up for reasons that have nothing
8341 to do with bidi reordering. E.g., compositions. The
8342 code below is only needed when we are above the base
8343 embedding level, so test for that explicitly. */
8344 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
8346 if (it->base_level_stop <= 0
8347 || IT_CHARPOS (*it) < it->base_level_stop)
8349 /* If we lost track of base_level_stop, we need to find
8350 prev_stop by looking backwards. This happens, e.g., when
8351 we were reseated to the previous screenful of text by
8352 vertical-motion. */
8353 it->base_level_stop = BEGV;
8354 compute_stop_pos_backwards (it);
8355 handle_stop_backwards (it, it->prev_stop);
8357 else
8358 handle_stop_backwards (it, it->base_level_stop);
8359 it->ignore_overlay_strings_at_pos_p = false;
8360 return GET_NEXT_DISPLAY_ELEMENT (it);
8362 else
8364 /* No face changes, overlays etc. in sight, so just return a
8365 character from current_buffer. */
8366 unsigned char *p;
8367 ptrdiff_t stop;
8369 /* We moved to the next buffer position, so any info about
8370 previously seen overlays is no longer valid. */
8371 it->ignore_overlay_strings_at_pos_p = false;
8373 /* Maybe run the redisplay end trigger hook. Performance note:
8374 This doesn't seem to cost measurable time. */
8375 if (it->redisplay_end_trigger_charpos
8376 && it->glyph_row
8377 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
8378 run_redisplay_end_trigger_hook (it);
8380 stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
8381 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
8382 stop)
8383 && next_element_from_composition (it))
8385 return true;
8388 /* Get the next character, maybe multibyte. */
8389 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
8390 if (it->multibyte_p && !ASCII_CHAR_P (*p))
8391 it->c = STRING_CHAR_AND_LENGTH (p, it->len);
8392 else
8393 it->c = *p, it->len = 1;
8395 /* Record what we have and where it came from. */
8396 it->what = IT_CHARACTER;
8397 it->object = it->w->contents;
8398 it->position = it->current.pos;
8400 /* Normally we return the character found above, except when we
8401 really want to return an ellipsis for selective display. */
8402 if (it->selective)
8404 if (it->c == '\n')
8406 /* A value of selective > 0 means hide lines indented more
8407 than that number of columns. */
8408 if (it->selective > 0
8409 && IT_CHARPOS (*it) + 1 < ZV
8410 && indented_beyond_p (IT_CHARPOS (*it) + 1,
8411 IT_BYTEPOS (*it) + 1,
8412 it->selective))
8414 success_p = next_element_from_ellipsis (it);
8415 it->dpvec_char_len = -1;
8418 else if (it->c == '\r' && it->selective == -1)
8420 /* A value of selective == -1 means that everything from the
8421 CR to the end of the line is invisible, with maybe an
8422 ellipsis displayed for it. */
8423 success_p = next_element_from_ellipsis (it);
8424 it->dpvec_char_len = -1;
8429 /* Value is false if end of buffer reached. */
8430 eassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
8431 return success_p;
8435 /* Run the redisplay end trigger hook for IT. */
8437 static void
8438 run_redisplay_end_trigger_hook (struct it *it)
8440 /* IT->glyph_row should be non-null, i.e. we should be actually
8441 displaying something, or otherwise we should not run the hook. */
8442 eassert (it->glyph_row);
8444 ptrdiff_t charpos = it->redisplay_end_trigger_charpos;
8445 it->redisplay_end_trigger_charpos = 0;
8447 /* Since we are *trying* to run these functions, don't try to run
8448 them again, even if they get an error. */
8449 wset_redisplay_end_trigger (it->w, Qnil);
8450 CALLN (Frun_hook_with_args, Qredisplay_end_trigger_functions, it->window,
8451 make_number (charpos));
8453 /* Notice if it changed the face of the character we are on. */
8454 handle_face_prop (it);
8458 /* Deliver a composition display element. Unlike the other
8459 next_element_from_XXX, this function is not registered in the array
8460 get_next_element[]. It is called from next_element_from_buffer and
8461 next_element_from_string when necessary. */
8463 static bool
8464 next_element_from_composition (struct it *it)
8466 it->what = IT_COMPOSITION;
8467 it->len = it->cmp_it.nbytes;
8468 if (STRINGP (it->string))
8470 if (it->c < 0)
8472 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
8473 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
8474 return false;
8476 it->position = it->current.string_pos;
8477 it->object = it->string;
8478 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
8479 IT_STRING_BYTEPOS (*it), it->string);
8481 else
8483 if (it->c < 0)
8485 IT_CHARPOS (*it) += it->cmp_it.nchars;
8486 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
8487 if (it->bidi_p)
8489 if (it->bidi_it.new_paragraph)
8490 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it,
8491 false);
8492 /* Resync the bidi iterator with IT's new position.
8493 FIXME: this doesn't support bidirectional text. */
8494 while (it->bidi_it.charpos < IT_CHARPOS (*it))
8495 bidi_move_to_visually_next (&it->bidi_it);
8497 return false;
8499 it->position = it->current.pos;
8500 it->object = it->w->contents;
8501 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
8502 IT_BYTEPOS (*it), Qnil);
8504 return true;
8509 /***********************************************************************
8510 Moving an iterator without producing glyphs
8511 ***********************************************************************/
8513 /* Check if iterator is at a position corresponding to a valid buffer
8514 position after some move_it_ call. */
8516 #define IT_POS_VALID_AFTER_MOVE_P(it) \
8517 ((it)->method != GET_FROM_STRING || IT_STRING_CHARPOS (*it) == 0)
8520 /* Move iterator IT to a specified buffer or X position within one
8521 line on the display without producing glyphs.
8523 OP should be a bit mask including some or all of these bits:
8524 MOVE_TO_X: Stop upon reaching x-position TO_X.
8525 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
8526 Regardless of OP's value, stop upon reaching the end of the display line.
8528 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
8529 This means, in particular, that TO_X includes window's horizontal
8530 scroll amount.
8532 The return value has several possible values that
8533 say what condition caused the scan to stop:
8535 MOVE_POS_MATCH_OR_ZV
8536 - when TO_POS or ZV was reached.
8538 MOVE_X_REACHED
8539 -when TO_X was reached before TO_POS or ZV were reached.
8541 MOVE_LINE_CONTINUED
8542 - when we reached the end of the display area and the line must
8543 be continued.
8545 MOVE_LINE_TRUNCATED
8546 - when we reached the end of the display area and the line is
8547 truncated.
8549 MOVE_NEWLINE_OR_CR
8550 - when we stopped at a line end, i.e. a newline or a CR and selective
8551 display is on. */
8553 static enum move_it_result
8554 move_it_in_display_line_to (struct it *it,
8555 ptrdiff_t to_charpos, int to_x,
8556 enum move_operation_enum op)
8558 enum move_it_result result = MOVE_UNDEFINED;
8559 struct glyph_row *saved_glyph_row;
8560 struct it wrap_it, atpos_it, atx_it, ppos_it;
8561 void *wrap_data = NULL, *atpos_data = NULL, *atx_data = NULL;
8562 void *ppos_data = NULL;
8563 bool may_wrap = false;
8564 enum it_method prev_method = it->method;
8565 ptrdiff_t closest_pos UNINIT;
8566 ptrdiff_t prev_pos = IT_CHARPOS (*it);
8567 bool saw_smaller_pos = prev_pos < to_charpos;
8569 /* Don't produce glyphs in produce_glyphs. */
8570 saved_glyph_row = it->glyph_row;
8571 it->glyph_row = NULL;
8573 /* Use wrap_it to save a copy of IT wherever a word wrap could
8574 occur. Use atpos_it to save a copy of IT at the desired buffer
8575 position, if found, so that we can scan ahead and check if the
8576 word later overshoots the window edge. Use atx_it similarly, for
8577 pixel positions. */
8578 wrap_it.sp = -1;
8579 atpos_it.sp = -1;
8580 atx_it.sp = -1;
8582 /* Use ppos_it under bidi reordering to save a copy of IT for the
8583 initial position. We restore that position in IT when we have
8584 scanned the entire display line without finding a match for
8585 TO_CHARPOS and all the character positions are greater than
8586 TO_CHARPOS. We then restart the scan from the initial position,
8587 and stop at CLOSEST_POS, which is a position > TO_CHARPOS that is
8588 the closest to TO_CHARPOS. */
8589 if (it->bidi_p)
8591 if ((op & MOVE_TO_POS) && IT_CHARPOS (*it) >= to_charpos)
8593 SAVE_IT (ppos_it, *it, ppos_data);
8594 closest_pos = IT_CHARPOS (*it);
8596 else
8597 closest_pos = ZV;
8600 #define BUFFER_POS_REACHED_P() \
8601 ((op & MOVE_TO_POS) != 0 \
8602 && BUFFERP (it->object) \
8603 && (IT_CHARPOS (*it) == to_charpos \
8604 || ((!it->bidi_p \
8605 || BIDI_AT_BASE_LEVEL (it->bidi_it)) \
8606 && IT_CHARPOS (*it) > to_charpos) \
8607 || (it->what == IT_COMPOSITION \
8608 && ((IT_CHARPOS (*it) > to_charpos \
8609 && to_charpos >= it->cmp_it.charpos) \
8610 || (IT_CHARPOS (*it) < to_charpos \
8611 && to_charpos <= it->cmp_it.charpos)))) \
8612 && (it->method == GET_FROM_BUFFER \
8613 || (it->method == GET_FROM_DISPLAY_VECTOR \
8614 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
8616 /* If there's a line-/wrap-prefix, handle it. */
8617 if (it->hpos == 0 && it->method == GET_FROM_BUFFER)
8618 handle_line_prefix (it);
8620 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8621 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8623 while (true)
8625 int x, i, ascent = 0, descent = 0;
8627 /* Utility macro to reset an iterator with x, ascent, and descent. */
8628 #define IT_RESET_X_ASCENT_DESCENT(IT) \
8629 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
8630 (IT)->max_descent = descent)
8632 /* Stop if we move beyond TO_CHARPOS (after an image or a
8633 display string or stretch glyph). */
8634 if ((op & MOVE_TO_POS) != 0
8635 && BUFFERP (it->object)
8636 && it->method == GET_FROM_BUFFER
8637 && (((!it->bidi_p
8638 /* When the iterator is at base embedding level, we
8639 are guaranteed that characters are delivered for
8640 display in strictly increasing order of their
8641 buffer positions. */
8642 || BIDI_AT_BASE_LEVEL (it->bidi_it))
8643 && IT_CHARPOS (*it) > to_charpos)
8644 || (it->bidi_p
8645 && (prev_method == GET_FROM_IMAGE
8646 || prev_method == GET_FROM_STRETCH
8647 || prev_method == GET_FROM_STRING)
8648 /* Passed TO_CHARPOS from left to right. */
8649 && ((prev_pos < to_charpos
8650 && IT_CHARPOS (*it) > to_charpos)
8651 /* Passed TO_CHARPOS from right to left. */
8652 || (prev_pos > to_charpos
8653 && IT_CHARPOS (*it) < to_charpos)))))
8655 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8657 result = MOVE_POS_MATCH_OR_ZV;
8658 break;
8660 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8661 /* If wrap_it is valid, the current position might be in a
8662 word that is wrapped. So, save the iterator in
8663 atpos_it and continue to see if wrapping happens. */
8664 SAVE_IT (atpos_it, *it, atpos_data);
8667 /* Stop when ZV reached.
8668 We used to stop here when TO_CHARPOS reached as well, but that is
8669 too soon if this glyph does not fit on this line. So we handle it
8670 explicitly below. */
8671 if (!get_next_display_element (it))
8673 result = MOVE_POS_MATCH_OR_ZV;
8674 break;
8677 if (it->line_wrap == TRUNCATE)
8679 if (BUFFER_POS_REACHED_P ())
8681 result = MOVE_POS_MATCH_OR_ZV;
8682 break;
8685 else
8687 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
8689 if (IT_DISPLAYING_WHITESPACE (it))
8690 may_wrap = true;
8691 else if (may_wrap)
8693 /* We have reached a glyph that follows one or more
8694 whitespace characters. If the position is
8695 already found, we are done. */
8696 if (atpos_it.sp >= 0)
8698 RESTORE_IT (it, &atpos_it, atpos_data);
8699 result = MOVE_POS_MATCH_OR_ZV;
8700 goto done;
8702 if (atx_it.sp >= 0)
8704 RESTORE_IT (it, &atx_it, atx_data);
8705 result = MOVE_X_REACHED;
8706 goto done;
8708 /* Otherwise, we can wrap here. */
8709 SAVE_IT (wrap_it, *it, wrap_data);
8710 may_wrap = false;
8715 /* Remember the line height for the current line, in case
8716 the next element doesn't fit on the line. */
8717 ascent = it->max_ascent;
8718 descent = it->max_descent;
8720 /* The call to produce_glyphs will get the metrics of the
8721 display element IT is loaded with. Record the x-position
8722 before this display element, in case it doesn't fit on the
8723 line. */
8724 x = it->current_x;
8726 PRODUCE_GLYPHS (it);
8728 if (it->area != TEXT_AREA)
8730 prev_method = it->method;
8731 if (it->method == GET_FROM_BUFFER)
8732 prev_pos = IT_CHARPOS (*it);
8733 set_iterator_to_next (it, true);
8734 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8735 SET_TEXT_POS (this_line_min_pos,
8736 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8737 if (it->bidi_p
8738 && (op & MOVE_TO_POS)
8739 && IT_CHARPOS (*it) > to_charpos
8740 && IT_CHARPOS (*it) < closest_pos)
8741 closest_pos = IT_CHARPOS (*it);
8742 continue;
8745 /* The number of glyphs we get back in IT->nglyphs will normally
8746 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
8747 character on a terminal frame, or (iii) a line end. For the
8748 second case, IT->nglyphs - 1 padding glyphs will be present.
8749 (On X frames, there is only one glyph produced for a
8750 composite character.)
8752 The behavior implemented below means, for continuation lines,
8753 that as many spaces of a TAB as fit on the current line are
8754 displayed there. For terminal frames, as many glyphs of a
8755 multi-glyph character are displayed in the current line, too.
8756 This is what the old redisplay code did, and we keep it that
8757 way. Under X, the whole shape of a complex character must
8758 fit on the line or it will be completely displayed in the
8759 next line.
8761 Note that both for tabs and padding glyphs, all glyphs have
8762 the same width. */
8763 if (it->nglyphs)
8765 /* More than one glyph or glyph doesn't fit on line. All
8766 glyphs have the same width. */
8767 int single_glyph_width = it->pixel_width / it->nglyphs;
8768 int new_x;
8769 int x_before_this_char = x;
8770 int hpos_before_this_char = it->hpos;
8772 for (i = 0; i < it->nglyphs; ++i, x = new_x)
8774 new_x = x + single_glyph_width;
8776 /* We want to leave anything reaching TO_X to the caller. */
8777 if ((op & MOVE_TO_X) && new_x > to_x)
8779 if (BUFFER_POS_REACHED_P ())
8781 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8782 goto buffer_pos_reached;
8783 if (atpos_it.sp < 0)
8785 SAVE_IT (atpos_it, *it, atpos_data);
8786 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8789 else
8791 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8793 it->current_x = x;
8794 result = MOVE_X_REACHED;
8795 break;
8797 if (atx_it.sp < 0)
8799 SAVE_IT (atx_it, *it, atx_data);
8800 IT_RESET_X_ASCENT_DESCENT (&atx_it);
8805 if (/* Lines are continued. */
8806 it->line_wrap != TRUNCATE
8807 && (/* And glyph doesn't fit on the line. */
8808 new_x > it->last_visible_x
8809 /* Or it fits exactly and we're on a window
8810 system frame. */
8811 || (new_x == it->last_visible_x
8812 && FRAME_WINDOW_P (it->f)
8813 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8814 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8815 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
8817 bool moved_forward = false;
8819 if (/* IT->hpos == 0 means the very first glyph
8820 doesn't fit on the line, e.g. a wide image. */
8821 it->hpos == 0
8822 || (new_x == it->last_visible_x
8823 && FRAME_WINDOW_P (it->f)))
8825 ++it->hpos;
8826 it->current_x = new_x;
8828 /* The character's last glyph just barely fits
8829 in this row. */
8830 if (i == it->nglyphs - 1)
8832 /* If this is the destination position,
8833 return a position *before* it in this row,
8834 now that we know it fits in this row. */
8835 if (BUFFER_POS_REACHED_P ())
8837 bool can_wrap = true;
8839 /* If we are at a whitespace character
8840 that barely fits on this screen line,
8841 but the next character is also
8842 whitespace, we cannot wrap here. */
8843 if (it->line_wrap == WORD_WRAP
8844 && wrap_it.sp >= 0
8845 && may_wrap
8846 && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8848 struct it tem_it;
8849 void *tem_data = NULL;
8851 SAVE_IT (tem_it, *it, tem_data);
8852 set_iterator_to_next (it, true);
8853 if (get_next_display_element (it)
8854 && IT_DISPLAYING_WHITESPACE (it))
8855 can_wrap = false;
8856 RESTORE_IT (it, &tem_it, tem_data);
8858 if (it->line_wrap != WORD_WRAP
8859 || wrap_it.sp < 0
8860 /* If we've just found whitespace
8861 where we can wrap, effectively
8862 ignore the previous wrap point --
8863 it is no longer relevant, but we
8864 won't have an opportunity to
8865 update it, since we've reached
8866 the edge of this screen line. */
8867 || (may_wrap && can_wrap
8868 && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)))
8870 it->hpos = hpos_before_this_char;
8871 it->current_x = x_before_this_char;
8872 result = MOVE_POS_MATCH_OR_ZV;
8873 break;
8875 if (it->line_wrap == WORD_WRAP
8876 && atpos_it.sp < 0)
8878 SAVE_IT (atpos_it, *it, atpos_data);
8879 atpos_it.current_x = x_before_this_char;
8880 atpos_it.hpos = hpos_before_this_char;
8884 prev_method = it->method;
8885 if (it->method == GET_FROM_BUFFER)
8886 prev_pos = IT_CHARPOS (*it);
8887 set_iterator_to_next (it, true);
8888 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8889 SET_TEXT_POS (this_line_min_pos,
8890 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8891 /* On graphical terminals, newlines may
8892 "overflow" into the fringe if
8893 overflow-newline-into-fringe is non-nil.
8894 On text terminals, and on graphical
8895 terminals with no right margin, newlines
8896 may overflow into the last glyph on the
8897 display line.*/
8898 if (!FRAME_WINDOW_P (it->f)
8899 || ((it->bidi_p
8900 && it->bidi_it.paragraph_dir == R2L)
8901 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8902 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
8903 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8905 if (!get_next_display_element (it))
8907 result = MOVE_POS_MATCH_OR_ZV;
8908 break;
8910 moved_forward = true;
8911 if (BUFFER_POS_REACHED_P ())
8913 if (ITERATOR_AT_END_OF_LINE_P (it))
8914 result = MOVE_POS_MATCH_OR_ZV;
8915 else
8916 result = MOVE_LINE_CONTINUED;
8917 break;
8919 if (ITERATOR_AT_END_OF_LINE_P (it)
8920 && (it->line_wrap != WORD_WRAP
8921 || wrap_it.sp < 0
8922 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)))
8924 result = MOVE_NEWLINE_OR_CR;
8925 break;
8930 else
8931 IT_RESET_X_ASCENT_DESCENT (it);
8933 /* If the screen line ends with whitespace, and we
8934 are under word-wrap, don't use wrap_it: it is no
8935 longer relevant, but we won't have an opportunity
8936 to update it, since we are done with this screen
8937 line. */
8938 if (may_wrap && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)
8939 /* If the character after the one which set the
8940 may_wrap flag is also whitespace, we can't
8941 wrap here, since the screen line cannot be
8942 wrapped in the middle of whitespace.
8943 Therefore, wrap_it _is_ relevant in that
8944 case. */
8945 && !(moved_forward && IT_DISPLAYING_WHITESPACE (it)))
8947 /* If we've found TO_X, go back there, as we now
8948 know the last word fits on this screen line. */
8949 if ((op & MOVE_TO_X) && new_x == it->last_visible_x
8950 && atx_it.sp >= 0)
8952 RESTORE_IT (it, &atx_it, atx_data);
8953 atpos_it.sp = -1;
8954 atx_it.sp = -1;
8955 result = MOVE_X_REACHED;
8956 break;
8959 else if (wrap_it.sp >= 0)
8961 RESTORE_IT (it, &wrap_it, wrap_data);
8962 atpos_it.sp = -1;
8963 atx_it.sp = -1;
8966 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
8967 IT_CHARPOS (*it)));
8968 result = MOVE_LINE_CONTINUED;
8969 break;
8972 if (BUFFER_POS_REACHED_P ())
8974 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8975 goto buffer_pos_reached;
8976 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8978 SAVE_IT (atpos_it, *it, atpos_data);
8979 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8983 if (new_x > it->first_visible_x)
8985 /* Glyph is visible. Increment number of glyphs that
8986 would be displayed. */
8987 ++it->hpos;
8991 if (result != MOVE_UNDEFINED)
8992 break;
8994 else if (BUFFER_POS_REACHED_P ())
8996 buffer_pos_reached:
8997 IT_RESET_X_ASCENT_DESCENT (it);
8998 result = MOVE_POS_MATCH_OR_ZV;
8999 break;
9001 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
9003 /* Stop when TO_X specified and reached. This check is
9004 necessary here because of lines consisting of a line end,
9005 only. The line end will not produce any glyphs and we
9006 would never get MOVE_X_REACHED. */
9007 eassert (it->nglyphs == 0);
9008 result = MOVE_X_REACHED;
9009 break;
9012 /* Is this a line end? If yes, we're done. */
9013 if (ITERATOR_AT_END_OF_LINE_P (it))
9015 /* If we are past TO_CHARPOS, but never saw any character
9016 positions smaller than TO_CHARPOS, return
9017 MOVE_POS_MATCH_OR_ZV, like the unidirectional display
9018 did. */
9019 if (it->bidi_p && (op & MOVE_TO_POS) != 0)
9021 if (!saw_smaller_pos && IT_CHARPOS (*it) > to_charpos)
9023 if (closest_pos < ZV)
9025 RESTORE_IT (it, &ppos_it, ppos_data);
9026 /* Don't recurse if closest_pos is equal to
9027 to_charpos, since we have just tried that. */
9028 if (closest_pos != to_charpos)
9029 move_it_in_display_line_to (it, closest_pos, -1,
9030 MOVE_TO_POS);
9031 result = MOVE_POS_MATCH_OR_ZV;
9033 else
9034 goto buffer_pos_reached;
9036 else if (it->line_wrap == WORD_WRAP && atpos_it.sp >= 0
9037 && IT_CHARPOS (*it) > to_charpos)
9038 goto buffer_pos_reached;
9039 else
9040 result = MOVE_NEWLINE_OR_CR;
9042 else
9043 result = MOVE_NEWLINE_OR_CR;
9044 /* If we've processed the newline, make sure this flag is
9045 reset, as it must only be set when the newline itself is
9046 processed. */
9047 if (result == MOVE_NEWLINE_OR_CR)
9048 it->constrain_row_ascent_descent_p = false;
9049 break;
9052 prev_method = it->method;
9053 if (it->method == GET_FROM_BUFFER)
9054 prev_pos = IT_CHARPOS (*it);
9055 /* The current display element has been consumed. Advance
9056 to the next. */
9057 set_iterator_to_next (it, true);
9058 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
9059 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
9060 if (IT_CHARPOS (*it) < to_charpos)
9061 saw_smaller_pos = true;
9062 if (it->bidi_p
9063 && (op & MOVE_TO_POS)
9064 && IT_CHARPOS (*it) >= to_charpos
9065 && IT_CHARPOS (*it) < closest_pos)
9066 closest_pos = IT_CHARPOS (*it);
9068 /* Stop if lines are truncated and IT's current x-position is
9069 past the right edge of the window now. */
9070 if (it->line_wrap == TRUNCATE
9071 && it->current_x >= it->last_visible_x)
9073 if (!FRAME_WINDOW_P (it->f)
9074 || ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
9075 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
9076 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
9077 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
9079 bool at_eob_p = false;
9081 if ((at_eob_p = !get_next_display_element (it))
9082 || BUFFER_POS_REACHED_P ()
9083 /* If we are past TO_CHARPOS, but never saw any
9084 character positions smaller than TO_CHARPOS,
9085 return MOVE_POS_MATCH_OR_ZV, like the
9086 unidirectional display did. */
9087 || (it->bidi_p && (op & MOVE_TO_POS) != 0
9088 && !saw_smaller_pos
9089 && IT_CHARPOS (*it) > to_charpos))
9091 if (it->bidi_p
9092 && !BUFFER_POS_REACHED_P ()
9093 && !at_eob_p && closest_pos < ZV)
9095 RESTORE_IT (it, &ppos_it, ppos_data);
9096 if (closest_pos != to_charpos)
9097 move_it_in_display_line_to (it, closest_pos, -1,
9098 MOVE_TO_POS);
9100 result = MOVE_POS_MATCH_OR_ZV;
9101 break;
9103 if (ITERATOR_AT_END_OF_LINE_P (it))
9105 result = MOVE_NEWLINE_OR_CR;
9106 break;
9109 else if (it->bidi_p && (op & MOVE_TO_POS) != 0
9110 && !saw_smaller_pos
9111 && IT_CHARPOS (*it) > to_charpos)
9113 if (closest_pos < ZV)
9115 RESTORE_IT (it, &ppos_it, ppos_data);
9116 if (closest_pos != to_charpos)
9117 move_it_in_display_line_to (it, closest_pos, -1,
9118 MOVE_TO_POS);
9120 result = MOVE_POS_MATCH_OR_ZV;
9121 break;
9123 result = MOVE_LINE_TRUNCATED;
9124 break;
9126 #undef IT_RESET_X_ASCENT_DESCENT
9129 #undef BUFFER_POS_REACHED_P
9131 /* If we scanned beyond TO_POS, restore the saved iterator either to
9132 the wrap point (if found), or to atpos/atx location. We decide which
9133 data to use to restore the saved iterator state by their X coordinates,
9134 since buffer positions might increase non-monotonically with screen
9135 coordinates due to bidi reordering. */
9136 if (result == MOVE_LINE_CONTINUED
9137 && it->line_wrap == WORD_WRAP
9138 && wrap_it.sp >= 0
9139 && ((atpos_it.sp >= 0 && wrap_it.current_x < atpos_it.current_x)
9140 || (atx_it.sp >= 0 && wrap_it.current_x < atx_it.current_x)))
9141 RESTORE_IT (it, &wrap_it, wrap_data);
9142 else if (atpos_it.sp >= 0)
9143 RESTORE_IT (it, &atpos_it, atpos_data);
9144 else if (atx_it.sp >= 0)
9145 RESTORE_IT (it, &atx_it, atx_data);
9147 done:
9149 if (atpos_data)
9150 bidi_unshelve_cache (atpos_data, true);
9151 if (atx_data)
9152 bidi_unshelve_cache (atx_data, true);
9153 if (wrap_data)
9154 bidi_unshelve_cache (wrap_data, true);
9155 if (ppos_data)
9156 bidi_unshelve_cache (ppos_data, true);
9158 /* Restore the iterator settings altered at the beginning of this
9159 function. */
9160 it->glyph_row = saved_glyph_row;
9161 return result;
9164 /* For external use. */
9165 void
9166 move_it_in_display_line (struct it *it,
9167 ptrdiff_t to_charpos, int to_x,
9168 enum move_operation_enum op)
9170 if (it->line_wrap == WORD_WRAP
9171 && (op & MOVE_TO_X))
9173 struct it save_it;
9174 void *save_data = NULL;
9175 int skip;
9177 SAVE_IT (save_it, *it, save_data);
9178 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
9179 /* When word-wrap is on, TO_X may lie past the end
9180 of a wrapped line. Then it->current is the
9181 character on the next line, so backtrack to the
9182 space before the wrap point. */
9183 if (skip == MOVE_LINE_CONTINUED)
9185 int prev_x = max (it->current_x - 1, 0);
9186 RESTORE_IT (it, &save_it, save_data);
9187 move_it_in_display_line_to
9188 (it, -1, prev_x, MOVE_TO_X);
9190 else
9191 bidi_unshelve_cache (save_data, true);
9193 else
9194 move_it_in_display_line_to (it, to_charpos, to_x, op);
9198 /* Move IT forward until it satisfies one or more of the criteria in
9199 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
9201 OP is a bit-mask that specifies where to stop, and in particular,
9202 which of those four position arguments makes a difference. See the
9203 description of enum move_operation_enum.
9205 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
9206 screen line, this function will set IT to the next position that is
9207 displayed to the right of TO_CHARPOS on the screen.
9209 Return the maximum pixel length of any line scanned but never more
9210 than it.last_visible_x. */
9213 move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos, int op)
9215 enum move_it_result skip, skip2 = MOVE_X_REACHED;
9216 int line_height, line_start_x = 0, reached = 0;
9217 int max_current_x = 0;
9218 void *backup_data = NULL;
9220 for (;;)
9222 if (op & MOVE_TO_VPOS)
9224 /* If no TO_CHARPOS and no TO_X specified, stop at the
9225 start of the line TO_VPOS. */
9226 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
9228 if (it->vpos == to_vpos)
9230 reached = 1;
9231 break;
9233 else
9234 skip = move_it_in_display_line_to (it, -1, -1, 0);
9236 else
9238 /* TO_VPOS >= 0 means stop at TO_X in the line at
9239 TO_VPOS, or at TO_POS, whichever comes first. */
9240 if (it->vpos == to_vpos)
9242 reached = 2;
9243 break;
9246 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
9248 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
9250 reached = 3;
9251 break;
9253 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
9255 /* We have reached TO_X but not in the line we want. */
9256 skip = move_it_in_display_line_to (it, to_charpos,
9257 -1, MOVE_TO_POS);
9258 if (skip == MOVE_POS_MATCH_OR_ZV)
9260 reached = 4;
9261 break;
9266 else if (op & MOVE_TO_Y)
9268 struct it it_backup;
9270 if (it->line_wrap == WORD_WRAP)
9271 SAVE_IT (it_backup, *it, backup_data);
9273 /* TO_Y specified means stop at TO_X in the line containing
9274 TO_Y---or at TO_CHARPOS if this is reached first. The
9275 problem is that we can't really tell whether the line
9276 contains TO_Y before we have completely scanned it, and
9277 this may skip past TO_X. What we do is to first scan to
9278 TO_X.
9280 If TO_X is not specified, use a TO_X of zero. The reason
9281 is to make the outcome of this function more predictable.
9282 If we didn't use TO_X == 0, we would stop at the end of
9283 the line which is probably not what a caller would expect
9284 to happen. */
9285 skip = move_it_in_display_line_to
9286 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
9287 (MOVE_TO_X | (op & MOVE_TO_POS)));
9289 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
9290 if (skip == MOVE_POS_MATCH_OR_ZV)
9291 reached = 5;
9292 else if (skip == MOVE_X_REACHED)
9294 /* If TO_X was reached, we want to know whether TO_Y is
9295 in the line. We know this is the case if the already
9296 scanned glyphs make the line tall enough. Otherwise,
9297 we must check by scanning the rest of the line. */
9298 line_height = it->max_ascent + it->max_descent;
9299 if (to_y >= it->current_y
9300 && to_y < it->current_y + line_height)
9302 reached = 6;
9303 break;
9305 SAVE_IT (it_backup, *it, backup_data);
9306 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
9307 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
9308 op & MOVE_TO_POS);
9309 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
9310 line_height = it->max_ascent + it->max_descent;
9311 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
9313 if (to_y >= it->current_y
9314 && to_y < it->current_y + line_height)
9316 /* If TO_Y is in this line and TO_X was reached
9317 above, we scanned too far. We have to restore
9318 IT's settings to the ones before skipping. But
9319 keep the more accurate values of max_ascent and
9320 max_descent we've found while skipping the rest
9321 of the line, for the sake of callers, such as
9322 pos_visible_p, that need to know the line
9323 height. */
9324 int max_ascent = it->max_ascent;
9325 int max_descent = it->max_descent;
9327 RESTORE_IT (it, &it_backup, backup_data);
9328 it->max_ascent = max_ascent;
9329 it->max_descent = max_descent;
9330 reached = 6;
9332 else
9334 skip = skip2;
9335 if (skip == MOVE_POS_MATCH_OR_ZV)
9336 reached = 7;
9339 else
9341 /* Check whether TO_Y is in this line. */
9342 line_height = it->max_ascent + it->max_descent;
9343 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
9345 if (to_y >= it->current_y
9346 && to_y < it->current_y + line_height)
9348 if (to_y > it->current_y)
9349 max_current_x = max (it->current_x, max_current_x);
9351 /* When word-wrap is on, TO_X may lie past the end
9352 of a wrapped line. Then it->current is the
9353 character on the next line, so backtrack to the
9354 space before the wrap point. */
9355 if (skip == MOVE_LINE_CONTINUED
9356 && it->line_wrap == WORD_WRAP)
9358 int prev_x = max (it->current_x - 1, 0);
9359 RESTORE_IT (it, &it_backup, backup_data);
9360 skip = move_it_in_display_line_to
9361 (it, -1, prev_x, MOVE_TO_X);
9364 reached = 6;
9368 if (reached)
9370 max_current_x = max (it->current_x, max_current_x);
9371 break;
9374 else if (BUFFERP (it->object)
9375 && (it->method == GET_FROM_BUFFER
9376 || it->method == GET_FROM_STRETCH)
9377 && IT_CHARPOS (*it) >= to_charpos
9378 /* Under bidi iteration, a call to set_iterator_to_next
9379 can scan far beyond to_charpos if the initial
9380 portion of the next line needs to be reordered. In
9381 that case, give move_it_in_display_line_to another
9382 chance below. */
9383 && !(it->bidi_p
9384 && it->bidi_it.scan_dir == -1))
9385 skip = MOVE_POS_MATCH_OR_ZV;
9386 else
9387 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
9389 switch (skip)
9391 case MOVE_POS_MATCH_OR_ZV:
9392 max_current_x = max (it->current_x, max_current_x);
9393 reached = 8;
9394 goto out;
9396 case MOVE_NEWLINE_OR_CR:
9397 max_current_x = max (it->current_x, max_current_x);
9398 set_iterator_to_next (it, true);
9399 it->continuation_lines_width = 0;
9400 break;
9402 case MOVE_LINE_TRUNCATED:
9403 max_current_x = it->last_visible_x;
9404 it->continuation_lines_width = 0;
9405 reseat_at_next_visible_line_start (it, false);
9406 if ((op & MOVE_TO_POS) != 0
9407 && IT_CHARPOS (*it) > to_charpos)
9409 reached = 9;
9410 goto out;
9412 break;
9414 case MOVE_LINE_CONTINUED:
9415 max_current_x = it->last_visible_x;
9416 /* For continued lines ending in a tab, some of the glyphs
9417 associated with the tab are displayed on the current
9418 line. Since it->current_x does not include these glyphs,
9419 we use it->last_visible_x instead. */
9420 if (it->c == '\t')
9422 it->continuation_lines_width += it->last_visible_x;
9423 /* When moving by vpos, ensure that the iterator really
9424 advances to the next line (bug#847, bug#969). Fixme:
9425 do we need to do this in other circumstances? */
9426 if (it->current_x != it->last_visible_x
9427 && (op & MOVE_TO_VPOS)
9428 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
9430 line_start_x = it->current_x + it->pixel_width
9431 - it->last_visible_x;
9432 if (FRAME_WINDOW_P (it->f))
9434 struct face *face = FACE_FROM_ID (it->f, it->face_id);
9435 struct font *face_font = face->font;
9437 /* When display_line produces a continued line
9438 that ends in a TAB, it skips a tab stop that
9439 is closer than the font's space character
9440 width (see x_produce_glyphs where it produces
9441 the stretch glyph which represents a TAB).
9442 We need to reproduce the same logic here. */
9443 eassert (face_font);
9444 if (face_font)
9446 if (line_start_x < face_font->space_width)
9447 line_start_x
9448 += it->tab_width * face_font->space_width;
9451 set_iterator_to_next (it, false);
9454 else
9455 it->continuation_lines_width += it->current_x;
9456 break;
9458 default:
9459 emacs_abort ();
9462 /* Reset/increment for the next run. */
9463 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
9464 it->current_x = line_start_x;
9465 line_start_x = 0;
9466 it->hpos = 0;
9467 it->current_y += it->max_ascent + it->max_descent;
9468 ++it->vpos;
9469 last_height = it->max_ascent + it->max_descent;
9470 it->max_ascent = it->max_descent = 0;
9473 out:
9475 /* On text terminals, we may stop at the end of a line in the middle
9476 of a multi-character glyph. If the glyph itself is continued,
9477 i.e. it is actually displayed on the next line, don't treat this
9478 stopping point as valid; move to the next line instead (unless
9479 that brings us offscreen). */
9480 if (!FRAME_WINDOW_P (it->f)
9481 && op & MOVE_TO_POS
9482 && IT_CHARPOS (*it) == to_charpos
9483 && it->what == IT_CHARACTER
9484 && it->nglyphs > 1
9485 && it->line_wrap == WINDOW_WRAP
9486 && it->current_x == it->last_visible_x - 1
9487 && it->c != '\n'
9488 && it->c != '\t'
9489 && it->w->window_end_valid
9490 && it->vpos < it->w->window_end_vpos)
9492 it->continuation_lines_width += it->current_x;
9493 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
9494 it->current_y += it->max_ascent + it->max_descent;
9495 ++it->vpos;
9496 last_height = it->max_ascent + it->max_descent;
9499 if (backup_data)
9500 bidi_unshelve_cache (backup_data, true);
9502 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
9504 return max_current_x;
9508 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
9510 If DY > 0, move IT backward at least that many pixels. DY = 0
9511 means move IT backward to the preceding line start or BEGV. This
9512 function may move over more than DY pixels if IT->current_y - DY
9513 ends up in the middle of a line; in this case IT->current_y will be
9514 set to the top of the line moved to. */
9516 void
9517 move_it_vertically_backward (struct it *it, int dy)
9519 int nlines, h;
9520 struct it it2, it3;
9521 void *it2data = NULL, *it3data = NULL;
9522 ptrdiff_t start_pos;
9523 int nchars_per_row
9524 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9525 ptrdiff_t pos_limit;
9527 move_further_back:
9528 eassert (dy >= 0);
9530 start_pos = IT_CHARPOS (*it);
9532 /* Estimate how many newlines we must move back. */
9533 nlines = max (1, dy / default_line_pixel_height (it->w));
9534 if (it->line_wrap == TRUNCATE || nchars_per_row == 0)
9535 pos_limit = BEGV;
9536 else
9537 pos_limit = max (start_pos - nlines * nchars_per_row, BEGV);
9539 /* Set the iterator's position that many lines back. But don't go
9540 back more than NLINES full screen lines -- this wins a day with
9541 buffers which have very long lines. */
9542 while (nlines-- && IT_CHARPOS (*it) > pos_limit)
9543 back_to_previous_visible_line_start (it);
9545 /* Reseat the iterator here. When moving backward, we don't want
9546 reseat to skip forward over invisible text, set up the iterator
9547 to deliver from overlay strings at the new position etc. So,
9548 use reseat_1 here. */
9549 reseat_1 (it, it->current.pos, true);
9551 /* We are now surely at a line start. */
9552 it->current_x = it->hpos = 0; /* FIXME: this is incorrect when bidi
9553 reordering is in effect. */
9554 it->continuation_lines_width = 0;
9556 /* Move forward and see what y-distance we moved. First move to the
9557 start of the next line so that we get its height. We need this
9558 height to be able to tell whether we reached the specified
9559 y-distance. */
9560 SAVE_IT (it2, *it, it2data);
9561 it2.max_ascent = it2.max_descent = 0;
9564 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
9565 MOVE_TO_POS | MOVE_TO_VPOS);
9567 while (!(IT_POS_VALID_AFTER_MOVE_P (&it2)
9568 /* If we are in a display string which starts at START_POS,
9569 and that display string includes a newline, and we are
9570 right after that newline (i.e. at the beginning of a
9571 display line), exit the loop, because otherwise we will
9572 infloop, since move_it_to will see that it is already at
9573 START_POS and will not move. */
9574 || (it2.method == GET_FROM_STRING
9575 && IT_CHARPOS (it2) == start_pos
9576 && SREF (it2.string, IT_STRING_BYTEPOS (it2) - 1) == '\n')));
9577 eassert (IT_CHARPOS (*it) >= BEGV);
9578 SAVE_IT (it3, it2, it3data);
9580 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
9581 eassert (IT_CHARPOS (*it) >= BEGV);
9582 /* H is the actual vertical distance from the position in *IT
9583 and the starting position. */
9584 h = it2.current_y - it->current_y;
9585 /* NLINES is the distance in number of lines. */
9586 nlines = it2.vpos - it->vpos;
9588 /* Correct IT's y and vpos position
9589 so that they are relative to the starting point. */
9590 it->vpos -= nlines;
9591 it->current_y -= h;
9593 if (dy == 0)
9595 /* DY == 0 means move to the start of the screen line. The
9596 value of nlines is > 0 if continuation lines were involved,
9597 or if the original IT position was at start of a line. */
9598 RESTORE_IT (it, it, it2data);
9599 if (nlines > 0)
9600 move_it_by_lines (it, nlines);
9601 /* The above code moves us to some position NLINES down,
9602 usually to its first glyph (leftmost in an L2R line), but
9603 that's not necessarily the start of the line, under bidi
9604 reordering. We want to get to the character position
9605 that is immediately after the newline of the previous
9606 line. */
9607 if (it->bidi_p
9608 && !it->continuation_lines_width
9609 && !STRINGP (it->string)
9610 && IT_CHARPOS (*it) > BEGV
9611 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9613 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
9615 DEC_BOTH (cp, bp);
9616 cp = find_newline_no_quit (cp, bp, -1, NULL);
9617 move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS);
9619 bidi_unshelve_cache (it3data, true);
9621 else
9623 /* The y-position we try to reach, relative to *IT.
9624 Note that H has been subtracted in front of the if-statement. */
9625 int target_y = it->current_y + h - dy;
9626 int y0 = it3.current_y;
9627 int y1;
9628 int line_height;
9630 RESTORE_IT (&it3, &it3, it3data);
9631 y1 = line_bottom_y (&it3);
9632 line_height = y1 - y0;
9633 RESTORE_IT (it, it, it2data);
9634 /* If we did not reach target_y, try to move further backward if
9635 we can. If we moved too far backward, try to move forward. */
9636 if (target_y < it->current_y
9637 /* This is heuristic. In a window that's 3 lines high, with
9638 a line height of 13 pixels each, recentering with point
9639 on the bottom line will try to move -39/2 = 19 pixels
9640 backward. Try to avoid moving into the first line. */
9641 && (it->current_y - target_y
9642 > min (window_box_height (it->w), line_height * 2 / 3))
9643 && IT_CHARPOS (*it) > BEGV)
9645 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
9646 target_y - it->current_y));
9647 dy = it->current_y - target_y;
9648 goto move_further_back;
9650 else if (target_y >= it->current_y + line_height
9651 && IT_CHARPOS (*it) < ZV)
9653 /* Should move forward by at least one line, maybe more.
9655 Note: Calling move_it_by_lines can be expensive on
9656 terminal frames, where compute_motion is used (via
9657 vmotion) to do the job, when there are very long lines
9658 and truncate-lines is nil. That's the reason for
9659 treating terminal frames specially here. */
9661 if (!FRAME_WINDOW_P (it->f))
9662 move_it_vertically (it, target_y - it->current_y);
9663 else
9667 move_it_by_lines (it, 1);
9669 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
9676 /* Move IT by a specified amount of pixel lines DY. DY negative means
9677 move backwards. DY = 0 means move to start of screen line. At the
9678 end, IT will be on the start of a screen line. */
9680 void
9681 move_it_vertically (struct it *it, int dy)
9683 if (dy <= 0)
9684 move_it_vertically_backward (it, -dy);
9685 else
9687 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
9688 move_it_to (it, ZV, -1, it->current_y + dy, -1,
9689 MOVE_TO_POS | MOVE_TO_Y);
9690 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
9692 /* If buffer ends in ZV without a newline, move to the start of
9693 the line to satisfy the post-condition. */
9694 if (IT_CHARPOS (*it) == ZV
9695 && ZV > BEGV
9696 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9697 move_it_by_lines (it, 0);
9702 /* Move iterator IT past the end of the text line it is in. */
9704 void
9705 move_it_past_eol (struct it *it)
9707 enum move_it_result rc;
9709 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
9710 if (rc == MOVE_NEWLINE_OR_CR)
9711 set_iterator_to_next (it, false);
9715 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
9716 negative means move up. DVPOS == 0 means move to the start of the
9717 screen line.
9719 Optimization idea: If we would know that IT->f doesn't use
9720 a face with proportional font, we could be faster for
9721 truncate-lines nil. */
9723 void
9724 move_it_by_lines (struct it *it, ptrdiff_t dvpos)
9727 /* The commented-out optimization uses vmotion on terminals. This
9728 gives bad results, because elements like it->what, on which
9729 callers such as pos_visible_p rely, aren't updated. */
9730 /* struct position pos;
9731 if (!FRAME_WINDOW_P (it->f))
9733 struct text_pos textpos;
9735 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
9736 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
9737 reseat (it, textpos, true);
9738 it->vpos += pos.vpos;
9739 it->current_y += pos.vpos;
9741 else */
9743 if (dvpos == 0)
9745 /* DVPOS == 0 means move to the start of the screen line. */
9746 move_it_vertically_backward (it, 0);
9747 /* Let next call to line_bottom_y calculate real line height. */
9748 last_height = 0;
9750 else if (dvpos > 0)
9752 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
9753 if (!IT_POS_VALID_AFTER_MOVE_P (it))
9755 /* Only move to the next buffer position if we ended up in a
9756 string from display property, not in an overlay string
9757 (before-string or after-string). That is because the
9758 latter don't conceal the underlying buffer position, so
9759 we can ask to move the iterator to the exact position we
9760 are interested in. Note that, even if we are already at
9761 IT_CHARPOS (*it), the call below is not a no-op, as it
9762 will detect that we are at the end of the string, pop the
9763 iterator, and compute it->current_x and it->hpos
9764 correctly. */
9765 move_it_to (it, IT_CHARPOS (*it) + it->string_from_display_prop_p,
9766 -1, -1, -1, MOVE_TO_POS);
9769 else
9771 struct it it2;
9772 void *it2data = NULL;
9773 ptrdiff_t start_charpos, i;
9774 int nchars_per_row
9775 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9776 bool hit_pos_limit = false;
9777 ptrdiff_t pos_limit;
9779 /* Start at the beginning of the screen line containing IT's
9780 position. This may actually move vertically backwards,
9781 in case of overlays, so adjust dvpos accordingly. */
9782 dvpos += it->vpos;
9783 move_it_vertically_backward (it, 0);
9784 dvpos -= it->vpos;
9786 /* Go back -DVPOS buffer lines, but no farther than -DVPOS full
9787 screen lines, and reseat the iterator there. */
9788 start_charpos = IT_CHARPOS (*it);
9789 if (it->line_wrap == TRUNCATE || nchars_per_row == 0)
9790 pos_limit = BEGV;
9791 else
9792 pos_limit = max (start_charpos + dvpos * nchars_per_row, BEGV);
9794 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > pos_limit; --i)
9795 back_to_previous_visible_line_start (it);
9796 if (i > 0 && IT_CHARPOS (*it) <= pos_limit)
9797 hit_pos_limit = true;
9798 reseat (it, it->current.pos, true);
9800 /* Move further back if we end up in a string or an image. */
9801 while (!IT_POS_VALID_AFTER_MOVE_P (it))
9803 /* First try to move to start of display line. */
9804 dvpos += it->vpos;
9805 move_it_vertically_backward (it, 0);
9806 dvpos -= it->vpos;
9807 if (IT_POS_VALID_AFTER_MOVE_P (it))
9808 break;
9809 /* If start of line is still in string or image,
9810 move further back. */
9811 back_to_previous_visible_line_start (it);
9812 reseat (it, it->current.pos, true);
9813 dvpos--;
9816 it->current_x = it->hpos = 0;
9818 /* Above call may have moved too far if continuation lines
9819 are involved. Scan forward and see if it did. */
9820 SAVE_IT (it2, *it, it2data);
9821 it2.vpos = it2.current_y = 0;
9822 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
9823 it->vpos -= it2.vpos;
9824 it->current_y -= it2.current_y;
9825 it->current_x = it->hpos = 0;
9827 /* If we moved too far back, move IT some lines forward. */
9828 if (it2.vpos > -dvpos)
9830 int delta = it2.vpos + dvpos;
9832 RESTORE_IT (&it2, &it2, it2data);
9833 SAVE_IT (it2, *it, it2data);
9834 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
9835 /* Move back again if we got too far ahead. */
9836 if (IT_CHARPOS (*it) >= start_charpos)
9837 RESTORE_IT (it, &it2, it2data);
9838 else
9839 bidi_unshelve_cache (it2data, true);
9841 else if (hit_pos_limit && pos_limit > BEGV
9842 && dvpos < 0 && it2.vpos < -dvpos)
9844 /* If we hit the limit, but still didn't make it far enough
9845 back, that means there's a display string with a newline
9846 covering a large chunk of text, and that caused
9847 back_to_previous_visible_line_start try to go too far.
9848 Punish those who commit such atrocities by going back
9849 until we've reached DVPOS, after lifting the limit, which
9850 could make it slow for very long lines. "If it hurts,
9851 don't do that!" */
9852 dvpos += it2.vpos;
9853 RESTORE_IT (it, it, it2data);
9854 for (i = -dvpos; i > 0; --i)
9856 back_to_previous_visible_line_start (it);
9857 it->vpos--;
9859 reseat_1 (it, it->current.pos, true);
9861 else
9862 RESTORE_IT (it, it, it2data);
9866 /* Return true if IT points into the middle of a display vector. */
9868 bool
9869 in_display_vector_p (struct it *it)
9871 return (it->method == GET_FROM_DISPLAY_VECTOR
9872 && it->current.dpvec_index > 0
9873 && it->dpvec + it->current.dpvec_index != it->dpend);
9876 DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 6, 0,
9877 doc: /* Return the size of the text of WINDOW's buffer in pixels.
9878 WINDOW must be a live window and defaults to the selected one. The
9879 return value is a cons of the maximum pixel-width of any text line and
9880 the maximum pixel-height of all text lines.
9882 The optional argument FROM, if non-nil, specifies the first text
9883 position and defaults to the minimum accessible position of the buffer.
9884 If FROM is t, use the minimum accessible position that starts a
9885 non-empty line. TO, if non-nil, specifies the last text position and
9886 defaults to the maximum accessible position of the buffer. If TO is t,
9887 use the maximum accessible position that ends a non-empty line.
9889 The optional argument X-LIMIT, if non-nil, specifies the maximum text
9890 width that can be returned. X-LIMIT nil or omitted, means to use the
9891 pixel-width of WINDOW's body; use this if you want to know how high
9892 WINDOW should be become in order to fit all of its buffer's text with
9893 the width of WINDOW unaltered. Use the maximum width WINDOW may assume
9894 if you intend to change WINDOW's width. In any case, text whose
9895 x-coordinate is beyond X-LIMIT is ignored. Since calculating the width
9896 of long lines can take some time, it's always a good idea to make this
9897 argument as small as possible; in particular, if the buffer contains
9898 long lines that shall be truncated anyway.
9900 The optional argument Y-LIMIT, if non-nil, specifies the maximum text
9901 height (excluding the height of the mode- or header-line, if any) that
9902 can be returned. Text lines whose y-coordinate is beyond Y-LIMIT are
9903 ignored. Since calculating the text height of a large buffer can take
9904 some time, it makes sense to specify this argument if the size of the
9905 buffer is large or unknown.
9907 Optional argument MODE-AND-HEADER-LINE nil or omitted means do not
9908 include the height of the mode- or header-line of WINDOW in the return
9909 value. If it is either the symbol `mode-line' or `header-line', include
9910 only the height of that line, if present, in the return value. If t,
9911 include the height of both, if present, in the return value. */)
9912 (Lisp_Object window, Lisp_Object from, Lisp_Object to, Lisp_Object x_limit,
9913 Lisp_Object y_limit, Lisp_Object mode_and_header_line)
9915 struct window *w = decode_live_window (window);
9916 Lisp_Object buffer = w->contents;
9917 struct buffer *b;
9918 struct it it;
9919 struct buffer *old_b = NULL;
9920 ptrdiff_t start, end, pos;
9921 struct text_pos startp;
9922 void *itdata = NULL;
9923 int c, max_x = 0, max_y = 0, x = 0, y = 0;
9925 CHECK_BUFFER (buffer);
9926 b = XBUFFER (buffer);
9928 if (b != current_buffer)
9930 old_b = current_buffer;
9931 set_buffer_internal (b);
9934 if (NILP (from))
9935 start = BEGV;
9936 else if (EQ (from, Qt))
9938 start = pos = BEGV;
9939 while ((pos++ < ZV) && (c = FETCH_CHAR (pos))
9940 && (c == ' ' || c == '\t' || c == '\n' || c == '\r'))
9941 start = pos;
9942 while ((pos-- > BEGV) && (c = FETCH_CHAR (pos)) && (c == ' ' || c == '\t'))
9943 start = pos;
9945 else
9947 CHECK_NUMBER_COERCE_MARKER (from);
9948 start = min (max (XINT (from), BEGV), ZV);
9951 if (NILP (to))
9952 end = ZV;
9953 else if (EQ (to, Qt))
9955 end = pos = ZV;
9956 while ((pos-- > BEGV) && (c = FETCH_CHAR (pos))
9957 && (c == ' ' || c == '\t' || c == '\n' || c == '\r'))
9958 end = pos;
9959 while ((pos++ < ZV) && (c = FETCH_CHAR (pos)) && (c == ' ' || c == '\t'))
9960 end = pos;
9962 else
9964 CHECK_NUMBER_COERCE_MARKER (to);
9965 end = max (start, min (XINT (to), ZV));
9968 if (!NILP (x_limit) && RANGED_INTEGERP (0, x_limit, INT_MAX))
9969 max_x = XINT (x_limit);
9971 if (NILP (y_limit))
9972 max_y = INT_MAX;
9973 else if (RANGED_INTEGERP (0, y_limit, INT_MAX))
9974 max_y = XINT (y_limit);
9976 itdata = bidi_shelve_cache ();
9977 SET_TEXT_POS (startp, start, CHAR_TO_BYTE (start));
9978 start_display (&it, w, startp);
9980 if (NILP (x_limit))
9981 x = move_it_to (&it, end, -1, max_y, -1, MOVE_TO_POS | MOVE_TO_Y);
9982 else
9984 it.last_visible_x = max_x;
9985 /* Actually, we never want move_it_to stop at to_x. But to make
9986 sure that move_it_in_display_line_to always moves far enough,
9987 we set it to INT_MAX and specify MOVE_TO_X. */
9988 x = move_it_to (&it, end, INT_MAX, max_y, -1,
9989 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
9990 /* Don't return more than X-LIMIT. */
9991 if (x > max_x)
9992 x = max_x;
9995 /* Subtract height of header-line which was counted automatically by
9996 start_display. */
9997 y = it.current_y + it.max_ascent + it.max_descent
9998 - WINDOW_HEADER_LINE_HEIGHT (w);
9999 /* Don't return more than Y-LIMIT. */
10000 if (y > max_y)
10001 y = max_y;
10003 if (EQ (mode_and_header_line, Qheader_line)
10004 || EQ (mode_and_header_line, Qt))
10005 /* Re-add height of header-line as requested. */
10006 y = y + WINDOW_HEADER_LINE_HEIGHT (w);
10008 if (EQ (mode_and_header_line, Qmode_line)
10009 || EQ (mode_and_header_line, Qt))
10010 /* Add height of mode-line as requested. */
10011 y = y + WINDOW_MODE_LINE_HEIGHT (w);
10013 bidi_unshelve_cache (itdata, false);
10015 if (old_b)
10016 set_buffer_internal (old_b);
10018 return Fcons (make_number (x), make_number (y));
10021 /***********************************************************************
10022 Messages
10023 ***********************************************************************/
10025 /* Return the number of arguments the format string FORMAT needs. */
10027 static ptrdiff_t
10028 format_nargs (char const *format)
10030 ptrdiff_t nargs = 0;
10031 for (char const *p = format; (p = strchr (p, '%')); p++)
10032 if (p[1] == '%')
10033 p++;
10034 else
10035 nargs++;
10036 return nargs;
10039 /* Add a message with format string FORMAT and formatted arguments
10040 to *Messages*. */
10042 void
10043 add_to_log (const char *format, ...)
10045 va_list ap;
10046 va_start (ap, format);
10047 vadd_to_log (format, ap);
10048 va_end (ap);
10051 void
10052 vadd_to_log (char const *format, va_list ap)
10054 ptrdiff_t form_nargs = format_nargs (format);
10055 ptrdiff_t nargs = 1 + form_nargs;
10056 Lisp_Object args[10];
10057 eassert (nargs <= ARRAYELTS (args));
10058 AUTO_STRING (args0, format);
10059 args[0] = args0;
10060 for (ptrdiff_t i = 1; i <= nargs; i++)
10061 args[i] = va_arg (ap, Lisp_Object);
10062 Lisp_Object msg = Qnil;
10063 msg = Fformat_message (nargs, args);
10065 ptrdiff_t len = SBYTES (msg) + 1;
10066 USE_SAFE_ALLOCA;
10067 char *buffer = SAFE_ALLOCA (len);
10068 memcpy (buffer, SDATA (msg), len);
10070 message_dolog (buffer, len - 1, true, STRING_MULTIBYTE (msg));
10071 SAFE_FREE ();
10075 /* Output a newline in the *Messages* buffer if "needs" one. */
10077 void
10078 message_log_maybe_newline (void)
10080 if (message_log_need_newline)
10081 message_dolog ("", 0, true, false);
10085 /* Add a string M of length NBYTES to the message log, optionally
10086 terminated with a newline when NLFLAG is true. MULTIBYTE, if
10087 true, means interpret the contents of M as multibyte. This
10088 function calls low-level routines in order to bypass text property
10089 hooks, etc. which might not be safe to run.
10091 This may GC (insert may run before/after change hooks),
10092 so the buffer M must NOT point to a Lisp string. */
10094 void
10095 message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
10097 const unsigned char *msg = (const unsigned char *) m;
10099 if (!NILP (Vmemory_full))
10100 return;
10102 if (!NILP (Vmessage_log_max))
10104 struct buffer *oldbuf;
10105 Lisp_Object oldpoint, oldbegv, oldzv;
10106 int old_windows_or_buffers_changed = windows_or_buffers_changed;
10107 ptrdiff_t point_at_end = 0;
10108 ptrdiff_t zv_at_end = 0;
10109 Lisp_Object old_deactivate_mark;
10111 old_deactivate_mark = Vdeactivate_mark;
10112 oldbuf = current_buffer;
10114 /* Ensure the Messages buffer exists, and switch to it.
10115 If we created it, set the major-mode. */
10116 bool newbuffer = NILP (Fget_buffer (Vmessages_buffer_name));
10117 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
10118 if (newbuffer
10119 && !NILP (Ffboundp (intern ("messages-buffer-mode"))))
10120 call0 (intern ("messages-buffer-mode"));
10122 bset_undo_list (current_buffer, Qt);
10123 bset_cache_long_scans (current_buffer, Qnil);
10125 oldpoint = message_dolog_marker1;
10126 set_marker_restricted_both (oldpoint, Qnil, PT, PT_BYTE);
10127 oldbegv = message_dolog_marker2;
10128 set_marker_restricted_both (oldbegv, Qnil, BEGV, BEGV_BYTE);
10129 oldzv = message_dolog_marker3;
10130 set_marker_restricted_both (oldzv, Qnil, ZV, ZV_BYTE);
10132 if (PT == Z)
10133 point_at_end = 1;
10134 if (ZV == Z)
10135 zv_at_end = 1;
10137 BEGV = BEG;
10138 BEGV_BYTE = BEG_BYTE;
10139 ZV = Z;
10140 ZV_BYTE = Z_BYTE;
10141 TEMP_SET_PT_BOTH (Z, Z_BYTE);
10143 /* Insert the string--maybe converting multibyte to single byte
10144 or vice versa, so that all the text fits the buffer. */
10145 if (multibyte
10146 && NILP (BVAR (current_buffer, enable_multibyte_characters)))
10148 ptrdiff_t i;
10149 int c, char_bytes;
10150 char work[1];
10152 /* Convert a multibyte string to single-byte
10153 for the *Message* buffer. */
10154 for (i = 0; i < nbytes; i += char_bytes)
10156 c = string_char_and_length (msg + i, &char_bytes);
10157 work[0] = CHAR_TO_BYTE8 (c);
10158 insert_1_both (work, 1, 1, true, false, false);
10161 else if (! multibyte
10162 && ! NILP (BVAR (current_buffer, enable_multibyte_characters)))
10164 ptrdiff_t i;
10165 int c, char_bytes;
10166 unsigned char str[MAX_MULTIBYTE_LENGTH];
10167 /* Convert a single-byte string to multibyte
10168 for the *Message* buffer. */
10169 for (i = 0; i < nbytes; i++)
10171 c = msg[i];
10172 MAKE_CHAR_MULTIBYTE (c);
10173 char_bytes = CHAR_STRING (c, str);
10174 insert_1_both ((char *) str, 1, char_bytes, true, false, false);
10177 else if (nbytes)
10178 insert_1_both (m, chars_in_text (msg, nbytes), nbytes,
10179 true, false, false);
10181 if (nlflag)
10183 ptrdiff_t this_bol, this_bol_byte, prev_bol, prev_bol_byte;
10184 printmax_t dups;
10186 insert_1_both ("\n", 1, 1, true, false, false);
10188 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, false);
10189 this_bol = PT;
10190 this_bol_byte = PT_BYTE;
10192 /* See if this line duplicates the previous one.
10193 If so, combine duplicates. */
10194 if (this_bol > BEG)
10196 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, false);
10197 prev_bol = PT;
10198 prev_bol_byte = PT_BYTE;
10200 dups = message_log_check_duplicate (prev_bol_byte,
10201 this_bol_byte);
10202 if (dups)
10204 del_range_both (prev_bol, prev_bol_byte,
10205 this_bol, this_bol_byte, false);
10206 if (dups > 1)
10208 char dupstr[sizeof " [ times]"
10209 + INT_STRLEN_BOUND (printmax_t)];
10211 /* If you change this format, don't forget to also
10212 change message_log_check_duplicate. */
10213 int duplen = sprintf (dupstr, " [%"pMd" times]", dups);
10214 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
10215 insert_1_both (dupstr, duplen, duplen,
10216 true, false, true);
10221 /* If we have more than the desired maximum number of lines
10222 in the *Messages* buffer now, delete the oldest ones.
10223 This is safe because we don't have undo in this buffer. */
10225 if (NATNUMP (Vmessage_log_max))
10227 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
10228 -XFASTINT (Vmessage_log_max) - 1, false);
10229 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, false);
10232 BEGV = marker_position (oldbegv);
10233 BEGV_BYTE = marker_byte_position (oldbegv);
10235 if (zv_at_end)
10237 ZV = Z;
10238 ZV_BYTE = Z_BYTE;
10240 else
10242 ZV = marker_position (oldzv);
10243 ZV_BYTE = marker_byte_position (oldzv);
10246 if (point_at_end)
10247 TEMP_SET_PT_BOTH (Z, Z_BYTE);
10248 else
10249 /* We can't do Fgoto_char (oldpoint) because it will run some
10250 Lisp code. */
10251 TEMP_SET_PT_BOTH (marker_position (oldpoint),
10252 marker_byte_position (oldpoint));
10254 unchain_marker (XMARKER (oldpoint));
10255 unchain_marker (XMARKER (oldbegv));
10256 unchain_marker (XMARKER (oldzv));
10258 /* We called insert_1_both above with its 5th argument (PREPARE)
10259 false, which prevents insert_1_both from calling
10260 prepare_to_modify_buffer, which in turns prevents us from
10261 incrementing windows_or_buffers_changed even if *Messages* is
10262 shown in some window. So we must manually set
10263 windows_or_buffers_changed here to make up for that. */
10264 windows_or_buffers_changed = old_windows_or_buffers_changed;
10265 bset_redisplay (current_buffer);
10267 set_buffer_internal (oldbuf);
10269 message_log_need_newline = !nlflag;
10270 Vdeactivate_mark = old_deactivate_mark;
10275 /* We are at the end of the buffer after just having inserted a newline.
10276 (Note: We depend on the fact we won't be crossing the gap.)
10277 Check to see if the most recent message looks a lot like the previous one.
10278 Return 0 if different, 1 if the new one should just replace it, or a
10279 value N > 1 if we should also append " [N times]". */
10281 static intmax_t
10282 message_log_check_duplicate (ptrdiff_t prev_bol_byte, ptrdiff_t this_bol_byte)
10284 ptrdiff_t i;
10285 ptrdiff_t len = Z_BYTE - 1 - this_bol_byte;
10286 bool seen_dots = false;
10287 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
10288 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
10290 for (i = 0; i < len; i++)
10292 if (i >= 3 && p1[i - 3] == '.' && p1[i - 2] == '.' && p1[i - 1] == '.')
10293 seen_dots = true;
10294 if (p1[i] != p2[i])
10295 return seen_dots;
10297 p1 += len;
10298 if (*p1 == '\n')
10299 return 2;
10300 if (*p1++ == ' ' && *p1++ == '[')
10302 char *pend;
10303 intmax_t n = strtoimax ((char *) p1, &pend, 10);
10304 if (0 < n && n < INTMAX_MAX && strncmp (pend, " times]\n", 8) == 0)
10305 return n + 1;
10307 return 0;
10311 /* Display an echo area message M with a specified length of NBYTES
10312 bytes. The string may include null characters. If M is not a
10313 string, clear out any existing message, and let the mini-buffer
10314 text show through.
10316 This function cancels echoing. */
10318 void
10319 message3 (Lisp_Object m)
10321 clear_message (true, true);
10322 cancel_echoing ();
10324 /* First flush out any partial line written with print. */
10325 message_log_maybe_newline ();
10326 if (STRINGP (m))
10328 ptrdiff_t nbytes = SBYTES (m);
10329 bool multibyte = STRING_MULTIBYTE (m);
10330 char *buffer;
10331 USE_SAFE_ALLOCA;
10332 SAFE_ALLOCA_STRING (buffer, m);
10333 message_dolog (buffer, nbytes, true, multibyte);
10334 SAFE_FREE ();
10336 if (! inhibit_message)
10337 message3_nolog (m);
10340 /* Log the message M to stderr. Log an empty line if M is not a string. */
10342 static void
10343 message_to_stderr (Lisp_Object m)
10345 if (noninteractive_need_newline)
10347 noninteractive_need_newline = false;
10348 fputc ('\n', stderr);
10350 if (STRINGP (m))
10352 Lisp_Object coding_system = Vlocale_coding_system;
10353 Lisp_Object s;
10355 if (!NILP (Vcoding_system_for_write))
10356 coding_system = Vcoding_system_for_write;
10357 if (!NILP (coding_system))
10358 s = code_convert_string_norecord (m, coding_system, true);
10359 else
10360 s = m;
10362 fwrite (SDATA (s), SBYTES (s), 1, stderr);
10364 if (!cursor_in_echo_area)
10365 fputc ('\n', stderr);
10366 fflush (stderr);
10369 /* The non-logging version of message3.
10370 This does not cancel echoing, because it is used for echoing.
10371 Perhaps we need to make a separate function for echoing
10372 and make this cancel echoing. */
10374 void
10375 message3_nolog (Lisp_Object m)
10377 struct frame *sf = SELECTED_FRAME ();
10379 if (FRAME_INITIAL_P (sf))
10380 message_to_stderr (m);
10381 /* Error messages get reported properly by cmd_error, so this must be just an
10382 informative message; if the frame hasn't really been initialized yet, just
10383 toss it. */
10384 else if (INTERACTIVE && sf->glyphs_initialized_p)
10386 /* Get the frame containing the mini-buffer
10387 that the selected frame is using. */
10388 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
10389 Lisp_Object frame = XWINDOW (mini_window)->frame;
10390 struct frame *f = XFRAME (frame);
10392 if (FRAME_VISIBLE_P (sf) && !FRAME_VISIBLE_P (f))
10393 Fmake_frame_visible (frame);
10395 if (STRINGP (m) && SCHARS (m) > 0)
10397 set_message (m);
10398 if (minibuffer_auto_raise)
10399 Fraise_frame (frame);
10400 /* Assume we are not echoing.
10401 (If we are, echo_now will override this.) */
10402 echo_message_buffer = Qnil;
10404 else
10405 clear_message (true, true);
10407 do_pending_window_change (false);
10408 echo_area_display (true);
10409 do_pending_window_change (false);
10410 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
10411 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
10416 /* Display a null-terminated echo area message M. If M is 0, clear
10417 out any existing message, and let the mini-buffer text show through.
10419 The buffer M must continue to exist until after the echo area gets
10420 cleared or some other message gets displayed there. Do not pass
10421 text that is stored in a Lisp string. Do not pass text in a buffer
10422 that was alloca'd. */
10424 void
10425 message1 (const char *m)
10427 message3 (m ? build_unibyte_string (m) : Qnil);
10431 /* The non-logging counterpart of message1. */
10433 void
10434 message1_nolog (const char *m)
10436 message3_nolog (m ? build_unibyte_string (m) : Qnil);
10439 /* Display a message M which contains a single %s
10440 which gets replaced with STRING. */
10442 void
10443 message_with_string (const char *m, Lisp_Object string, bool log)
10445 CHECK_STRING (string);
10447 bool need_message;
10448 if (noninteractive)
10449 need_message = !!m;
10450 else if (!INTERACTIVE)
10451 need_message = false;
10452 else
10454 /* The frame whose minibuffer we're going to display the message on.
10455 It may be larger than the selected frame, so we need
10456 to use its buffer, not the selected frame's buffer. */
10457 Lisp_Object mini_window;
10458 struct frame *f, *sf = SELECTED_FRAME ();
10460 /* Get the frame containing the minibuffer
10461 that the selected frame is using. */
10462 mini_window = FRAME_MINIBUF_WINDOW (sf);
10463 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10465 /* Error messages get reported properly by cmd_error, so this must be
10466 just an informative message; if the frame hasn't really been
10467 initialized yet, just toss it. */
10468 need_message = f->glyphs_initialized_p;
10471 if (need_message)
10473 AUTO_STRING (fmt, m);
10474 Lisp_Object msg = CALLN (Fformat_message, fmt, string);
10476 if (noninteractive)
10477 message_to_stderr (msg);
10478 else
10480 if (log)
10481 message3 (msg);
10482 else
10483 message3_nolog (msg);
10485 /* Print should start at the beginning of the message
10486 buffer next time. */
10487 message_buf_print = false;
10493 /* Dump an informative message to the minibuf. If M is 0, clear out
10494 any existing message, and let the mini-buffer text show through.
10496 The message must be safe ASCII and the format must not contain ` or
10497 '. If your message and format do not fit into this category,
10498 convert your arguments to Lisp objects and use Fmessage instead. */
10500 static void ATTRIBUTE_FORMAT_PRINTF (1, 0)
10501 vmessage (const char *m, va_list ap)
10503 if (noninteractive)
10505 if (m)
10507 if (noninteractive_need_newline)
10508 putc ('\n', stderr);
10509 noninteractive_need_newline = false;
10510 vfprintf (stderr, m, ap);
10511 if (!cursor_in_echo_area)
10512 fprintf (stderr, "\n");
10513 fflush (stderr);
10516 else if (INTERACTIVE)
10518 /* The frame whose mini-buffer we're going to display the message
10519 on. It may be larger than the selected frame, so we need to
10520 use its buffer, not the selected frame's buffer. */
10521 Lisp_Object mini_window;
10522 struct frame *f, *sf = SELECTED_FRAME ();
10524 /* Get the frame containing the mini-buffer
10525 that the selected frame is using. */
10526 mini_window = FRAME_MINIBUF_WINDOW (sf);
10527 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10529 /* Error messages get reported properly by cmd_error, so this must be
10530 just an informative message; if the frame hasn't really been
10531 initialized yet, just toss it. */
10532 if (f->glyphs_initialized_p)
10534 if (m)
10536 ptrdiff_t len;
10537 ptrdiff_t maxsize = FRAME_MESSAGE_BUF_SIZE (f);
10538 USE_SAFE_ALLOCA;
10539 char *message_buf = SAFE_ALLOCA (maxsize + 1);
10541 len = doprnt (message_buf, maxsize, m, 0, ap);
10543 message3 (make_string (message_buf, len));
10544 SAFE_FREE ();
10546 else
10547 message1 (0);
10549 /* Print should start at the beginning of the message
10550 buffer next time. */
10551 message_buf_print = false;
10556 void
10557 message (const char *m, ...)
10559 va_list ap;
10560 va_start (ap, m);
10561 vmessage (m, ap);
10562 va_end (ap);
10566 /* Display the current message in the current mini-buffer. This is
10567 only called from error handlers in process.c, and is not time
10568 critical. */
10570 void
10571 update_echo_area (void)
10573 if (!NILP (echo_area_buffer[0]))
10575 Lisp_Object string;
10576 string = Fcurrent_message ();
10577 message3 (string);
10582 /* Make sure echo area buffers in `echo_buffers' are live.
10583 If they aren't, make new ones. */
10585 static void
10586 ensure_echo_area_buffers (void)
10588 for (int i = 0; i < 2; i++)
10589 if (!BUFFERP (echo_buffer[i])
10590 || !BUFFER_LIVE_P (XBUFFER (echo_buffer[i])))
10592 Lisp_Object old_buffer = echo_buffer[i];
10593 static char const name_fmt[] = " *Echo Area %d*";
10594 char name[sizeof name_fmt + INT_STRLEN_BOUND (int)];
10595 AUTO_STRING_WITH_LEN (lname, name, sprintf (name, name_fmt, i));
10596 echo_buffer[i] = Fget_buffer_create (lname);
10597 bset_truncate_lines (XBUFFER (echo_buffer[i]), Qnil);
10598 /* to force word wrap in echo area -
10599 it was decided to postpone this*/
10600 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
10602 for (int j = 0; j < 2; j++)
10603 if (EQ (old_buffer, echo_area_buffer[j]))
10604 echo_area_buffer[j] = echo_buffer[i];
10609 /* Call FN with args A1..A2 with either the current or last displayed
10610 echo_area_buffer as current buffer.
10612 WHICH zero means use the current message buffer
10613 echo_area_buffer[0]. If that is nil, choose a suitable buffer
10614 from echo_buffer[] and clear it.
10616 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
10617 suitable buffer from echo_buffer[] and clear it.
10619 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
10620 that the current message becomes the last displayed one, choose a
10621 suitable buffer for echo_area_buffer[0], and clear it.
10623 Value is what FN returns. */
10625 static bool
10626 with_echo_area_buffer (struct window *w, int which,
10627 bool (*fn) (ptrdiff_t, Lisp_Object),
10628 ptrdiff_t a1, Lisp_Object a2)
10630 Lisp_Object buffer;
10631 bool this_one, the_other, clear_buffer_p, rc;
10632 ptrdiff_t count = SPECPDL_INDEX ();
10634 /* If buffers aren't live, make new ones. */
10635 ensure_echo_area_buffers ();
10637 clear_buffer_p = false;
10639 if (which == 0)
10640 this_one = false, the_other = true;
10641 else if (which > 0)
10642 this_one = true, the_other = false;
10643 else
10645 this_one = false, the_other = true;
10646 clear_buffer_p = true;
10648 /* We need a fresh one in case the current echo buffer equals
10649 the one containing the last displayed echo area message. */
10650 if (!NILP (echo_area_buffer[this_one])
10651 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
10652 echo_area_buffer[this_one] = Qnil;
10655 /* Choose a suitable buffer from echo_buffer[] if we don't
10656 have one. */
10657 if (NILP (echo_area_buffer[this_one]))
10659 echo_area_buffer[this_one]
10660 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
10661 ? echo_buffer[the_other]
10662 : echo_buffer[this_one]);
10663 clear_buffer_p = true;
10666 buffer = echo_area_buffer[this_one];
10668 /* Don't get confused by reusing the buffer used for echoing
10669 for a different purpose. */
10670 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
10671 cancel_echoing ();
10673 record_unwind_protect (unwind_with_echo_area_buffer,
10674 with_echo_area_buffer_unwind_data (w));
10676 /* Make the echo area buffer current. Note that for display
10677 purposes, it is not necessary that the displayed window's buffer
10678 == current_buffer, except for text property lookup. So, let's
10679 only set that buffer temporarily here without doing a full
10680 Fset_window_buffer. We must also change w->pointm, though,
10681 because otherwise an assertions in unshow_buffer fails, and Emacs
10682 aborts. */
10683 set_buffer_internal_1 (XBUFFER (buffer));
10684 if (w)
10686 wset_buffer (w, buffer);
10687 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
10688 set_marker_both (w->old_pointm, buffer, BEG, BEG_BYTE);
10691 bset_undo_list (current_buffer, Qt);
10692 bset_read_only (current_buffer, Qnil);
10693 specbind (Qinhibit_read_only, Qt);
10694 specbind (Qinhibit_modification_hooks, Qt);
10696 if (clear_buffer_p && Z > BEG)
10697 del_range (BEG, Z);
10699 eassert (BEGV >= BEG);
10700 eassert (ZV <= Z && ZV >= BEGV);
10702 rc = fn (a1, a2);
10704 eassert (BEGV >= BEG);
10705 eassert (ZV <= Z && ZV >= BEGV);
10707 unbind_to (count, Qnil);
10708 return rc;
10712 /* Save state that should be preserved around the call to the function
10713 FN called in with_echo_area_buffer. */
10715 static Lisp_Object
10716 with_echo_area_buffer_unwind_data (struct window *w)
10718 int i = 0;
10719 Lisp_Object vector, tmp;
10721 /* Reduce consing by keeping one vector in
10722 Vwith_echo_area_save_vector. */
10723 vector = Vwith_echo_area_save_vector;
10724 Vwith_echo_area_save_vector = Qnil;
10726 if (NILP (vector))
10727 vector = Fmake_vector (make_number (11), Qnil);
10729 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
10730 ASET (vector, i, Vdeactivate_mark); ++i;
10731 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
10733 if (w)
10735 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
10736 ASET (vector, i, w->contents); ++i;
10737 ASET (vector, i, make_number (marker_position (w->pointm))); ++i;
10738 ASET (vector, i, make_number (marker_byte_position (w->pointm))); ++i;
10739 ASET (vector, i, make_number (marker_position (w->old_pointm))); ++i;
10740 ASET (vector, i, make_number (marker_byte_position (w->old_pointm))); ++i;
10741 ASET (vector, i, make_number (marker_position (w->start))); ++i;
10742 ASET (vector, i, make_number (marker_byte_position (w->start))); ++i;
10744 else
10746 int end = i + 8;
10747 for (; i < end; ++i)
10748 ASET (vector, i, Qnil);
10751 eassert (i == ASIZE (vector));
10752 return vector;
10756 /* Restore global state from VECTOR which was created by
10757 with_echo_area_buffer_unwind_data. */
10759 static void
10760 unwind_with_echo_area_buffer (Lisp_Object vector)
10762 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
10763 Vdeactivate_mark = AREF (vector, 1);
10764 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
10766 if (WINDOWP (AREF (vector, 3)))
10768 struct window *w;
10769 Lisp_Object buffer;
10771 w = XWINDOW (AREF (vector, 3));
10772 buffer = AREF (vector, 4);
10774 wset_buffer (w, buffer);
10775 set_marker_both (w->pointm, buffer,
10776 XFASTINT (AREF (vector, 5)),
10777 XFASTINT (AREF (vector, 6)));
10778 set_marker_both (w->old_pointm, buffer,
10779 XFASTINT (AREF (vector, 7)),
10780 XFASTINT (AREF (vector, 8)));
10781 set_marker_both (w->start, buffer,
10782 XFASTINT (AREF (vector, 9)),
10783 XFASTINT (AREF (vector, 10)));
10786 Vwith_echo_area_save_vector = vector;
10790 /* Set up the echo area for use by print functions. MULTIBYTE_P
10791 means we will print multibyte. */
10793 void
10794 setup_echo_area_for_printing (bool multibyte_p)
10796 /* If we can't find an echo area any more, exit. */
10797 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
10798 Fkill_emacs (Qnil);
10800 ensure_echo_area_buffers ();
10802 if (!message_buf_print)
10804 /* A message has been output since the last time we printed.
10805 Choose a fresh echo area buffer. */
10806 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10807 echo_area_buffer[0] = echo_buffer[1];
10808 else
10809 echo_area_buffer[0] = echo_buffer[0];
10811 /* Switch to that buffer and clear it. */
10812 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10813 bset_truncate_lines (current_buffer, Qnil);
10815 if (Z > BEG)
10817 ptrdiff_t count = SPECPDL_INDEX ();
10818 specbind (Qinhibit_read_only, Qt);
10819 /* Note that undo recording is always disabled. */
10820 del_range (BEG, Z);
10821 unbind_to (count, Qnil);
10823 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10825 /* Set up the buffer for the multibyteness we need. */
10826 if (multibyte_p
10827 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10828 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
10830 /* Raise the frame containing the echo area. */
10831 if (minibuffer_auto_raise)
10833 struct frame *sf = SELECTED_FRAME ();
10834 Lisp_Object mini_window;
10835 mini_window = FRAME_MINIBUF_WINDOW (sf);
10836 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
10839 message_log_maybe_newline ();
10840 message_buf_print = true;
10842 else
10844 if (NILP (echo_area_buffer[0]))
10846 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10847 echo_area_buffer[0] = echo_buffer[1];
10848 else
10849 echo_area_buffer[0] = echo_buffer[0];
10852 if (current_buffer != XBUFFER (echo_area_buffer[0]))
10854 /* Someone switched buffers between print requests. */
10855 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10856 bset_truncate_lines (current_buffer, Qnil);
10862 /* Display an echo area message in window W. Value is true if W's
10863 height is changed. If display_last_displayed_message_p,
10864 display the message that was last displayed, otherwise
10865 display the current message. */
10867 static bool
10868 display_echo_area (struct window *w)
10870 bool no_message_p, window_height_changed_p;
10872 /* Temporarily disable garbage collections while displaying the echo
10873 area. This is done because a GC can print a message itself.
10874 That message would modify the echo area buffer's contents while a
10875 redisplay of the buffer is going on, and seriously confuse
10876 redisplay. */
10877 ptrdiff_t count = inhibit_garbage_collection ();
10879 /* If there is no message, we must call display_echo_area_1
10880 nevertheless because it resizes the window. But we will have to
10881 reset the echo_area_buffer in question to nil at the end because
10882 with_echo_area_buffer will sets it to an empty buffer. */
10883 bool i = display_last_displayed_message_p;
10884 /* According to the C99, C11 and C++11 standards, the integral value
10885 of a "bool" is always 0 or 1, so this array access is safe here,
10886 if oddly typed. */
10887 no_message_p = NILP (echo_area_buffer[i]);
10889 window_height_changed_p
10890 = with_echo_area_buffer (w, display_last_displayed_message_p,
10891 display_echo_area_1,
10892 (intptr_t) w, Qnil);
10894 if (no_message_p)
10895 echo_area_buffer[i] = Qnil;
10897 unbind_to (count, Qnil);
10898 return window_height_changed_p;
10902 /* Helper for display_echo_area. Display the current buffer which
10903 contains the current echo area message in window W, a mini-window,
10904 a pointer to which is passed in A1. A2..A4 are currently not used.
10905 Change the height of W so that all of the message is displayed.
10906 Value is true if height of W was changed. */
10908 static bool
10909 display_echo_area_1 (ptrdiff_t a1, Lisp_Object a2)
10911 intptr_t i1 = a1;
10912 struct window *w = (struct window *) i1;
10913 Lisp_Object window;
10914 struct text_pos start;
10916 /* We are about to enter redisplay without going through
10917 redisplay_internal, so we need to forget these faces by hand
10918 here. */
10919 forget_escape_and_glyphless_faces ();
10921 /* Do this before displaying, so that we have a large enough glyph
10922 matrix for the display. If we can't get enough space for the
10923 whole text, display the last N lines. That works by setting w->start. */
10924 bool window_height_changed_p = resize_mini_window (w, false);
10926 /* Use the starting position chosen by resize_mini_window. */
10927 SET_TEXT_POS_FROM_MARKER (start, w->start);
10929 /* Display. */
10930 clear_glyph_matrix (w->desired_matrix);
10931 XSETWINDOW (window, w);
10932 try_window (window, start, 0);
10934 return window_height_changed_p;
10938 /* Resize the echo area window to exactly the size needed for the
10939 currently displayed message, if there is one. If a mini-buffer
10940 is active, don't shrink it. */
10942 void
10943 resize_echo_area_exactly (void)
10945 if (BUFFERP (echo_area_buffer[0])
10946 && WINDOWP (echo_area_window))
10948 struct window *w = XWINDOW (echo_area_window);
10949 Lisp_Object resize_exactly = (minibuf_level == 0 ? Qt : Qnil);
10950 bool resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
10951 (intptr_t) w, resize_exactly);
10952 if (resized_p)
10954 windows_or_buffers_changed = 42;
10955 update_mode_lines = 30;
10956 redisplay_internal ();
10962 /* Callback function for with_echo_area_buffer, when used from
10963 resize_echo_area_exactly. A1 contains a pointer to the window to
10964 resize, EXACTLY non-nil means resize the mini-window exactly to the
10965 size of the text displayed. A3 and A4 are not used. Value is what
10966 resize_mini_window returns. */
10968 static bool
10969 resize_mini_window_1 (ptrdiff_t a1, Lisp_Object exactly)
10971 intptr_t i1 = a1;
10972 return resize_mini_window ((struct window *) i1, !NILP (exactly));
10976 /* Resize mini-window W to fit the size of its contents. EXACT_P
10977 means size the window exactly to the size needed. Otherwise, it's
10978 only enlarged until W's buffer is empty.
10980 Set W->start to the right place to begin display. If the whole
10981 contents fit, start at the beginning. Otherwise, start so as
10982 to make the end of the contents appear. This is particularly
10983 important for y-or-n-p, but seems desirable generally.
10985 Value is true if the window height has been changed. */
10987 bool
10988 resize_mini_window (struct window *w, bool exact_p)
10990 struct frame *f = XFRAME (w->frame);
10991 bool window_height_changed_p = false;
10993 eassert (MINI_WINDOW_P (w));
10995 /* By default, start display at the beginning. */
10996 set_marker_both (w->start, w->contents,
10997 BUF_BEGV (XBUFFER (w->contents)),
10998 BUF_BEGV_BYTE (XBUFFER (w->contents)));
11000 /* Don't resize windows while redisplaying a window; it would
11001 confuse redisplay functions when the size of the window they are
11002 displaying changes from under them. Such a resizing can happen,
11003 for instance, when which-func prints a long message while
11004 we are running fontification-functions. We're running these
11005 functions with safe_call which binds inhibit-redisplay to t. */
11006 if (!NILP (Vinhibit_redisplay))
11007 return false;
11009 /* Nil means don't try to resize. */
11010 if (NILP (Vresize_mini_windows)
11011 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
11012 return false;
11014 if (!FRAME_MINIBUF_ONLY_P (f))
11016 struct it it;
11017 int total_height = (WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_ROOT_WINDOW (f)))
11018 + WINDOW_PIXEL_HEIGHT (w));
11019 int unit = FRAME_LINE_HEIGHT (f);
11020 int height, max_height;
11021 struct text_pos start;
11022 struct buffer *old_current_buffer = NULL;
11024 if (current_buffer != XBUFFER (w->contents))
11026 old_current_buffer = current_buffer;
11027 set_buffer_internal (XBUFFER (w->contents));
11030 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
11032 /* Compute the max. number of lines specified by the user. */
11033 if (FLOATP (Vmax_mini_window_height))
11034 max_height = XFLOATINT (Vmax_mini_window_height) * total_height;
11035 else if (INTEGERP (Vmax_mini_window_height))
11036 max_height = XINT (Vmax_mini_window_height) * unit;
11037 else
11038 max_height = total_height / 4;
11040 /* Correct that max. height if it's bogus. */
11041 max_height = clip_to_bounds (unit, max_height, total_height);
11043 /* Find out the height of the text in the window. */
11044 if (it.line_wrap == TRUNCATE)
11045 height = unit;
11046 else
11048 last_height = 0;
11049 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
11050 if (it.max_ascent == 0 && it.max_descent == 0)
11051 height = it.current_y + last_height;
11052 else
11053 height = it.current_y + it.max_ascent + it.max_descent;
11054 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
11057 /* Compute a suitable window start. */
11058 if (height > max_height)
11060 height = (max_height / unit) * unit;
11061 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
11062 move_it_vertically_backward (&it, height - unit);
11063 start = it.current.pos;
11065 else
11066 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
11067 SET_MARKER_FROM_TEXT_POS (w->start, start);
11069 if (EQ (Vresize_mini_windows, Qgrow_only))
11071 /* Let it grow only, until we display an empty message, in which
11072 case the window shrinks again. */
11073 if (height > WINDOW_PIXEL_HEIGHT (w))
11075 int old_height = WINDOW_PIXEL_HEIGHT (w);
11077 FRAME_WINDOWS_FROZEN (f) = true;
11078 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), true);
11079 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
11081 else if (height < WINDOW_PIXEL_HEIGHT (w)
11082 && (exact_p || BEGV == ZV))
11084 int old_height = WINDOW_PIXEL_HEIGHT (w);
11086 FRAME_WINDOWS_FROZEN (f) = false;
11087 shrink_mini_window (w, true);
11088 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
11091 else
11093 /* Always resize to exact size needed. */
11094 if (height > WINDOW_PIXEL_HEIGHT (w))
11096 int old_height = WINDOW_PIXEL_HEIGHT (w);
11098 FRAME_WINDOWS_FROZEN (f) = true;
11099 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), true);
11100 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
11102 else if (height < WINDOW_PIXEL_HEIGHT (w))
11104 int old_height = WINDOW_PIXEL_HEIGHT (w);
11106 FRAME_WINDOWS_FROZEN (f) = false;
11107 shrink_mini_window (w, true);
11109 if (height)
11111 FRAME_WINDOWS_FROZEN (f) = true;
11112 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), true);
11115 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
11119 if (old_current_buffer)
11120 set_buffer_internal (old_current_buffer);
11123 return window_height_changed_p;
11127 /* Value is the current message, a string, or nil if there is no
11128 current message. */
11130 Lisp_Object
11131 current_message (void)
11133 Lisp_Object msg;
11135 if (!BUFFERP (echo_area_buffer[0]))
11136 msg = Qnil;
11137 else
11139 with_echo_area_buffer (0, 0, current_message_1,
11140 (intptr_t) &msg, Qnil);
11141 if (NILP (msg))
11142 echo_area_buffer[0] = Qnil;
11145 return msg;
11149 static bool
11150 current_message_1 (ptrdiff_t a1, Lisp_Object a2)
11152 intptr_t i1 = a1;
11153 Lisp_Object *msg = (Lisp_Object *) i1;
11155 if (Z > BEG)
11156 *msg = make_buffer_string (BEG, Z, true);
11157 else
11158 *msg = Qnil;
11159 return false;
11163 /* Push the current message on Vmessage_stack for later restoration
11164 by restore_message. Value is true if the current message isn't
11165 empty. This is a relatively infrequent operation, so it's not
11166 worth optimizing. */
11168 bool
11169 push_message (void)
11171 Lisp_Object msg = current_message ();
11172 Vmessage_stack = Fcons (msg, Vmessage_stack);
11173 return STRINGP (msg);
11177 /* Restore message display from the top of Vmessage_stack. */
11179 void
11180 restore_message (void)
11182 eassert (CONSP (Vmessage_stack));
11183 message3_nolog (XCAR (Vmessage_stack));
11187 /* Handler for unwind-protect calling pop_message. */
11189 void
11190 pop_message_unwind (void)
11192 /* Pop the top-most entry off Vmessage_stack. */
11193 eassert (CONSP (Vmessage_stack));
11194 Vmessage_stack = XCDR (Vmessage_stack);
11198 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
11199 exits. If the stack is not empty, we have a missing pop_message
11200 somewhere. */
11202 void
11203 check_message_stack (void)
11205 if (!NILP (Vmessage_stack))
11206 emacs_abort ();
11210 /* Truncate to NCHARS what will be displayed in the echo area the next
11211 time we display it---but don't redisplay it now. */
11213 void
11214 truncate_echo_area (ptrdiff_t nchars)
11216 if (nchars == 0)
11217 echo_area_buffer[0] = Qnil;
11218 else if (!noninteractive
11219 && INTERACTIVE
11220 && !NILP (echo_area_buffer[0]))
11222 struct frame *sf = SELECTED_FRAME ();
11223 /* Error messages get reported properly by cmd_error, so this must be
11224 just an informative message; if the frame hasn't really been
11225 initialized yet, just toss it. */
11226 if (sf->glyphs_initialized_p)
11227 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil);
11232 /* Helper function for truncate_echo_area. Truncate the current
11233 message to at most NCHARS characters. */
11235 static bool
11236 truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2)
11238 if (BEG + nchars < Z)
11239 del_range (BEG + nchars, Z);
11240 if (Z == BEG)
11241 echo_area_buffer[0] = Qnil;
11242 return false;
11245 /* Set the current message to STRING. */
11247 static void
11248 set_message (Lisp_Object string)
11250 eassert (STRINGP (string));
11252 message_enable_multibyte = STRING_MULTIBYTE (string);
11254 with_echo_area_buffer (0, -1, set_message_1, 0, string);
11255 message_buf_print = false;
11256 help_echo_showing_p = false;
11258 if (STRINGP (Vdebug_on_message)
11259 && STRINGP (string)
11260 && fast_string_match (Vdebug_on_message, string) >= 0)
11261 call_debugger (list2 (Qerror, string));
11265 /* Helper function for set_message. First argument is ignored and second
11266 argument has the same meaning as for set_message.
11267 This function is called with the echo area buffer being current. */
11269 static bool
11270 set_message_1 (ptrdiff_t a1, Lisp_Object string)
11272 eassert (STRINGP (string));
11274 /* Change multibyteness of the echo buffer appropriately. */
11275 if (message_enable_multibyte
11276 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
11277 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
11279 bset_truncate_lines (current_buffer, message_truncate_lines ? Qt : Qnil);
11280 if (!NILP (BVAR (current_buffer, bidi_display_reordering)))
11281 bset_bidi_paragraph_direction (current_buffer, Qleft_to_right);
11283 /* Insert new message at BEG. */
11284 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
11286 /* This function takes care of single/multibyte conversion.
11287 We just have to ensure that the echo area buffer has the right
11288 setting of enable_multibyte_characters. */
11289 insert_from_string (string, 0, 0, SCHARS (string), SBYTES (string), true);
11291 return false;
11295 /* Clear messages. CURRENT_P means clear the current message.
11296 LAST_DISPLAYED_P means clear the message last displayed. */
11298 void
11299 clear_message (bool current_p, bool last_displayed_p)
11301 if (current_p)
11303 echo_area_buffer[0] = Qnil;
11304 message_cleared_p = true;
11307 if (last_displayed_p)
11308 echo_area_buffer[1] = Qnil;
11310 message_buf_print = false;
11313 /* Clear garbaged frames.
11315 This function is used where the old redisplay called
11316 redraw_garbaged_frames which in turn called redraw_frame which in
11317 turn called clear_frame. The call to clear_frame was a source of
11318 flickering. I believe a clear_frame is not necessary. It should
11319 suffice in the new redisplay to invalidate all current matrices,
11320 and ensure a complete redisplay of all windows. */
11322 static void
11323 clear_garbaged_frames (void)
11325 if (frame_garbaged)
11327 Lisp_Object tail, frame;
11328 struct frame *sf = SELECTED_FRAME ();
11330 FOR_EACH_FRAME (tail, frame)
11332 struct frame *f = XFRAME (frame);
11334 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
11336 if (f->resized_p
11337 /* It makes no sense to redraw a non-selected TTY
11338 frame, since that will actually clear the
11339 selected frame, and might leave the selected
11340 frame with corrupted display, if it happens not
11341 to be marked garbaged. */
11342 && !(f != sf && (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))))
11343 redraw_frame (f);
11344 else
11345 clear_current_matrices (f);
11346 fset_redisplay (f);
11347 f->garbaged = false;
11348 f->resized_p = false;
11352 frame_garbaged = false;
11357 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P, update
11358 selected_frame. */
11360 static void
11361 echo_area_display (bool update_frame_p)
11363 Lisp_Object mini_window;
11364 struct window *w;
11365 struct frame *f;
11366 bool window_height_changed_p = false;
11367 struct frame *sf = SELECTED_FRAME ();
11369 mini_window = FRAME_MINIBUF_WINDOW (sf);
11370 w = XWINDOW (mini_window);
11371 f = XFRAME (WINDOW_FRAME (w));
11373 /* Don't display if frame is invisible or not yet initialized. */
11374 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
11375 return;
11377 #ifdef HAVE_WINDOW_SYSTEM
11378 /* When Emacs starts, selected_frame may be the initial terminal
11379 frame. If we let this through, a message would be displayed on
11380 the terminal. */
11381 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
11382 return;
11383 #endif /* HAVE_WINDOW_SYSTEM */
11385 /* Redraw garbaged frames. */
11386 clear_garbaged_frames ();
11388 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
11390 echo_area_window = mini_window;
11391 window_height_changed_p = display_echo_area (w);
11392 w->must_be_updated_p = true;
11394 /* Update the display, unless called from redisplay_internal.
11395 Also don't update the screen during redisplay itself. The
11396 update will happen at the end of redisplay, and an update
11397 here could cause confusion. */
11398 if (update_frame_p && !redisplaying_p)
11400 int n = 0;
11402 /* If the display update has been interrupted by pending
11403 input, update mode lines in the frame. Due to the
11404 pending input, it might have been that redisplay hasn't
11405 been called, so that mode lines above the echo area are
11406 garbaged. This looks odd, so we prevent it here. */
11407 if (!display_completed)
11408 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), false);
11410 if (window_height_changed_p
11411 /* Don't do this if Emacs is shutting down. Redisplay
11412 needs to run hooks. */
11413 && !NILP (Vrun_hooks))
11415 /* Must update other windows. Likewise as in other
11416 cases, don't let this update be interrupted by
11417 pending input. */
11418 ptrdiff_t count = SPECPDL_INDEX ();
11419 specbind (Qredisplay_dont_pause, Qt);
11420 fset_redisplay (f);
11421 redisplay_internal ();
11422 unbind_to (count, Qnil);
11424 else if (FRAME_WINDOW_P (f) && n == 0)
11426 /* Window configuration is the same as before.
11427 Can do with a display update of the echo area,
11428 unless we displayed some mode lines. */
11429 update_single_window (w);
11430 flush_frame (f);
11432 else
11433 update_frame (f, true, true);
11435 /* If cursor is in the echo area, make sure that the next
11436 redisplay displays the minibuffer, so that the cursor will
11437 be replaced with what the minibuffer wants. */
11438 if (cursor_in_echo_area)
11439 wset_redisplay (XWINDOW (mini_window));
11442 else if (!EQ (mini_window, selected_window))
11443 wset_redisplay (XWINDOW (mini_window));
11445 /* Last displayed message is now the current message. */
11446 echo_area_buffer[1] = echo_area_buffer[0];
11447 /* Inform read_char that we're not echoing. */
11448 echo_message_buffer = Qnil;
11450 /* Prevent redisplay optimization in redisplay_internal by resetting
11451 this_line_start_pos. This is done because the mini-buffer now
11452 displays the message instead of its buffer text. */
11453 if (EQ (mini_window, selected_window))
11454 CHARPOS (this_line_start_pos) = 0;
11456 if (window_height_changed_p)
11458 fset_redisplay (f);
11460 /* If window configuration was changed, frames may have been
11461 marked garbaged. Clear them or we will experience
11462 surprises wrt scrolling.
11463 FIXME: How/why/when? */
11464 clear_garbaged_frames ();
11468 /* True if W's buffer was changed but not saved. */
11470 static bool
11471 window_buffer_changed (struct window *w)
11473 struct buffer *b = XBUFFER (w->contents);
11475 eassert (BUFFER_LIVE_P (b));
11477 return (BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star;
11480 /* True if W has %c in its mode line and mode line should be updated. */
11482 static bool
11483 mode_line_update_needed (struct window *w)
11485 return (w->column_number_displayed != -1
11486 && !(PT == w->last_point && !window_outdated (w))
11487 && (w->column_number_displayed != current_column ()));
11490 /* True if window start of W is frozen and may not be changed during
11491 redisplay. */
11493 static bool
11494 window_frozen_p (struct window *w)
11496 if (FRAME_WINDOWS_FROZEN (XFRAME (WINDOW_FRAME (w))))
11498 Lisp_Object window;
11500 XSETWINDOW (window, w);
11501 if (MINI_WINDOW_P (w))
11502 return false;
11503 else if (EQ (window, selected_window))
11504 return false;
11505 else if (MINI_WINDOW_P (XWINDOW (selected_window))
11506 && EQ (window, Vminibuf_scroll_window))
11507 /* This special window can't be frozen too. */
11508 return false;
11509 else
11510 return true;
11512 return false;
11515 /***********************************************************************
11516 Mode Lines and Frame Titles
11517 ***********************************************************************/
11519 /* A buffer for constructing non-propertized mode-line strings and
11520 frame titles in it; allocated from the heap in init_xdisp and
11521 resized as needed in store_mode_line_noprop_char. */
11523 static char *mode_line_noprop_buf;
11525 /* The buffer's end, and a current output position in it. */
11527 static char *mode_line_noprop_buf_end;
11528 static char *mode_line_noprop_ptr;
11530 #define MODE_LINE_NOPROP_LEN(start) \
11531 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
11533 static enum {
11534 MODE_LINE_DISPLAY = 0,
11535 MODE_LINE_TITLE,
11536 MODE_LINE_NOPROP,
11537 MODE_LINE_STRING
11538 } mode_line_target;
11540 /* Alist that caches the results of :propertize.
11541 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
11542 static Lisp_Object mode_line_proptrans_alist;
11544 /* List of strings making up the mode-line. */
11545 static Lisp_Object mode_line_string_list;
11547 /* Base face property when building propertized mode line string. */
11548 static Lisp_Object mode_line_string_face;
11549 static Lisp_Object mode_line_string_face_prop;
11552 /* Unwind data for mode line strings */
11554 static Lisp_Object Vmode_line_unwind_vector;
11556 static Lisp_Object
11557 format_mode_line_unwind_data (struct frame *target_frame,
11558 struct buffer *obuf,
11559 Lisp_Object owin,
11560 bool save_proptrans)
11562 Lisp_Object vector, tmp;
11564 /* Reduce consing by keeping one vector in
11565 Vwith_echo_area_save_vector. */
11566 vector = Vmode_line_unwind_vector;
11567 Vmode_line_unwind_vector = Qnil;
11569 if (NILP (vector))
11570 vector = Fmake_vector (make_number (10), Qnil);
11572 ASET (vector, 0, make_number (mode_line_target));
11573 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
11574 ASET (vector, 2, mode_line_string_list);
11575 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
11576 ASET (vector, 4, mode_line_string_face);
11577 ASET (vector, 5, mode_line_string_face_prop);
11579 if (obuf)
11580 XSETBUFFER (tmp, obuf);
11581 else
11582 tmp = Qnil;
11583 ASET (vector, 6, tmp);
11584 ASET (vector, 7, owin);
11585 if (target_frame)
11587 /* Similarly to `with-selected-window', if the operation selects
11588 a window on another frame, we must restore that frame's
11589 selected window, and (for a tty) the top-frame. */
11590 ASET (vector, 8, target_frame->selected_window);
11591 if (FRAME_TERMCAP_P (target_frame))
11592 ASET (vector, 9, FRAME_TTY (target_frame)->top_frame);
11595 return vector;
11598 static void
11599 unwind_format_mode_line (Lisp_Object vector)
11601 Lisp_Object old_window = AREF (vector, 7);
11602 Lisp_Object target_frame_window = AREF (vector, 8);
11603 Lisp_Object old_top_frame = AREF (vector, 9);
11605 mode_line_target = XINT (AREF (vector, 0));
11606 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
11607 mode_line_string_list = AREF (vector, 2);
11608 if (! EQ (AREF (vector, 3), Qt))
11609 mode_line_proptrans_alist = AREF (vector, 3);
11610 mode_line_string_face = AREF (vector, 4);
11611 mode_line_string_face_prop = AREF (vector, 5);
11613 /* Select window before buffer, since it may change the buffer. */
11614 if (!NILP (old_window))
11616 /* If the operation that we are unwinding had selected a window
11617 on a different frame, reset its frame-selected-window. For a
11618 text terminal, reset its top-frame if necessary. */
11619 if (!NILP (target_frame_window))
11621 Lisp_Object frame
11622 = WINDOW_FRAME (XWINDOW (target_frame_window));
11624 if (!EQ (frame, WINDOW_FRAME (XWINDOW (old_window))))
11625 Fselect_window (target_frame_window, Qt);
11627 if (!NILP (old_top_frame) && !EQ (old_top_frame, frame))
11628 Fselect_frame (old_top_frame, Qt);
11631 Fselect_window (old_window, Qt);
11634 if (!NILP (AREF (vector, 6)))
11636 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
11637 ASET (vector, 6, Qnil);
11640 Vmode_line_unwind_vector = vector;
11644 /* Store a single character C for the frame title in mode_line_noprop_buf.
11645 Re-allocate mode_line_noprop_buf if necessary. */
11647 static void
11648 store_mode_line_noprop_char (char c)
11650 /* If output position has reached the end of the allocated buffer,
11651 increase the buffer's size. */
11652 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
11654 ptrdiff_t len = MODE_LINE_NOPROP_LEN (0);
11655 ptrdiff_t size = len;
11656 mode_line_noprop_buf =
11657 xpalloc (mode_line_noprop_buf, &size, 1, STRING_BYTES_BOUND, 1);
11658 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
11659 mode_line_noprop_ptr = mode_line_noprop_buf + len;
11662 *mode_line_noprop_ptr++ = c;
11666 /* Store part of a frame title in mode_line_noprop_buf, beginning at
11667 mode_line_noprop_ptr. STRING is the string to store. Do not copy
11668 characters that yield more columns than PRECISION; PRECISION <= 0
11669 means copy the whole string. Pad with spaces until FIELD_WIDTH
11670 number of characters have been copied; FIELD_WIDTH <= 0 means don't
11671 pad. Called from display_mode_element when it is used to build a
11672 frame title. */
11674 static int
11675 store_mode_line_noprop (const char *string, int field_width, int precision)
11677 const unsigned char *str = (const unsigned char *) string;
11678 int n = 0;
11679 ptrdiff_t dummy, nbytes;
11681 /* Copy at most PRECISION chars from STR. */
11682 nbytes = strlen (string);
11683 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
11684 while (nbytes--)
11685 store_mode_line_noprop_char (*str++);
11687 /* Fill up with spaces until FIELD_WIDTH reached. */
11688 while (field_width > 0
11689 && n < field_width)
11691 store_mode_line_noprop_char (' ');
11692 ++n;
11695 return n;
11698 /***********************************************************************
11699 Frame Titles
11700 ***********************************************************************/
11702 #ifdef HAVE_WINDOW_SYSTEM
11704 /* Set the title of FRAME, if it has changed. The title format is
11705 Vicon_title_format if FRAME is iconified, otherwise it is
11706 frame_title_format. */
11708 static void
11709 x_consider_frame_title (Lisp_Object frame)
11711 struct frame *f = XFRAME (frame);
11713 if ((FRAME_WINDOW_P (f)
11714 || FRAME_MINIBUF_ONLY_P (f)
11715 || f->explicit_name)
11716 && NILP (Fframe_parameter (frame, Qtooltip)))
11718 /* Do we have more than one visible frame on this X display? */
11719 Lisp_Object tail, other_frame, fmt;
11720 ptrdiff_t title_start;
11721 char *title;
11722 ptrdiff_t len;
11723 struct it it;
11724 ptrdiff_t count = SPECPDL_INDEX ();
11726 FOR_EACH_FRAME (tail, other_frame)
11728 struct frame *tf = XFRAME (other_frame);
11730 if (tf != f
11731 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
11732 && !FRAME_MINIBUF_ONLY_P (tf)
11733 && !EQ (other_frame, tip_frame)
11734 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
11735 break;
11738 /* Set global variable indicating that multiple frames exist. */
11739 multiple_frames = CONSP (tail);
11741 /* Switch to the buffer of selected window of the frame. Set up
11742 mode_line_target so that display_mode_element will output into
11743 mode_line_noprop_buf; then display the title. */
11744 record_unwind_protect (unwind_format_mode_line,
11745 format_mode_line_unwind_data
11746 (f, current_buffer, selected_window, false));
11747 /* select-frame calls resize_mini_window, which could resize the
11748 mini-window and by that undo the effect of this redisplay
11749 cycle wrt minibuffer and echo-area display. Binding
11750 inhibit-redisplay to t makes the call to resize_mini_window a
11751 no-op, thus avoiding the adverse side effects. */
11752 specbind (Qinhibit_redisplay, Qt);
11754 Fselect_window (f->selected_window, Qt);
11755 set_buffer_internal_1
11756 (XBUFFER (XWINDOW (f->selected_window)->contents));
11757 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
11759 mode_line_target = MODE_LINE_TITLE;
11760 title_start = MODE_LINE_NOPROP_LEN (0);
11761 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
11762 NULL, DEFAULT_FACE_ID);
11763 display_mode_element (&it, 0, -1, -1, fmt, Qnil, false);
11764 len = MODE_LINE_NOPROP_LEN (title_start);
11765 title = mode_line_noprop_buf + title_start;
11766 unbind_to (count, Qnil);
11768 /* Set the title only if it's changed. This avoids consing in
11769 the common case where it hasn't. (If it turns out that we've
11770 already wasted too much time by walking through the list with
11771 display_mode_element, then we might need to optimize at a
11772 higher level than this.) */
11773 if (! STRINGP (f->name)
11774 || SBYTES (f->name) != len
11775 || memcmp (title, SDATA (f->name), len) != 0)
11776 x_implicitly_set_name (f, make_string (title, len), Qnil);
11780 #endif /* not HAVE_WINDOW_SYSTEM */
11783 /***********************************************************************
11784 Menu Bars
11785 ***********************************************************************/
11787 /* True if we will not redisplay all visible windows. */
11788 #define REDISPLAY_SOME_P() \
11789 ((windows_or_buffers_changed == 0 \
11790 || windows_or_buffers_changed == REDISPLAY_SOME) \
11791 && (update_mode_lines == 0 \
11792 || update_mode_lines == REDISPLAY_SOME))
11794 /* Prepare for redisplay by updating menu-bar item lists when
11795 appropriate. This can call eval. */
11797 static void
11798 prepare_menu_bars (void)
11800 bool all_windows = windows_or_buffers_changed || update_mode_lines;
11801 bool some_windows = REDISPLAY_SOME_P ();
11802 Lisp_Object tooltip_frame;
11804 #ifdef HAVE_WINDOW_SYSTEM
11805 tooltip_frame = tip_frame;
11806 #else
11807 tooltip_frame = Qnil;
11808 #endif
11810 if (FUNCTIONP (Vpre_redisplay_function))
11812 Lisp_Object windows = all_windows ? Qt : Qnil;
11813 if (all_windows && some_windows)
11815 Lisp_Object ws = window_list ();
11816 for (windows = Qnil; CONSP (ws); ws = XCDR (ws))
11818 Lisp_Object this = XCAR (ws);
11819 struct window *w = XWINDOW (this);
11820 if (w->redisplay
11821 || XFRAME (w->frame)->redisplay
11822 || XBUFFER (w->contents)->text->redisplay)
11824 windows = Fcons (this, windows);
11828 safe__call1 (true, Vpre_redisplay_function, windows);
11831 /* Update all frame titles based on their buffer names, etc. We do
11832 this before the menu bars so that the buffer-menu will show the
11833 up-to-date frame titles. */
11834 #ifdef HAVE_WINDOW_SYSTEM
11835 if (all_windows)
11837 Lisp_Object tail, frame;
11839 FOR_EACH_FRAME (tail, frame)
11841 struct frame *f = XFRAME (frame);
11842 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
11843 if (some_windows
11844 && !f->redisplay
11845 && !w->redisplay
11846 && !XBUFFER (w->contents)->text->redisplay)
11847 continue;
11849 if (!EQ (frame, tooltip_frame)
11850 && (FRAME_ICONIFIED_P (f)
11851 || FRAME_VISIBLE_P (f) == 1
11852 /* Exclude TTY frames that are obscured because they
11853 are not the top frame on their console. This is
11854 because x_consider_frame_title actually switches
11855 to the frame, which for TTY frames means it is
11856 marked as garbaged, and will be completely
11857 redrawn on the next redisplay cycle. This causes
11858 TTY frames to be completely redrawn, when there
11859 are more than one of them, even though nothing
11860 should be changed on display. */
11861 || (FRAME_VISIBLE_P (f) == 2 && FRAME_WINDOW_P (f))))
11862 x_consider_frame_title (frame);
11865 #endif /* HAVE_WINDOW_SYSTEM */
11867 /* Update the menu bar item lists, if appropriate. This has to be
11868 done before any actual redisplay or generation of display lines. */
11870 if (all_windows)
11872 Lisp_Object tail, frame;
11873 ptrdiff_t count = SPECPDL_INDEX ();
11874 /* True means that update_menu_bar has run its hooks
11875 so any further calls to update_menu_bar shouldn't do so again. */
11876 bool menu_bar_hooks_run = false;
11878 record_unwind_save_match_data ();
11880 FOR_EACH_FRAME (tail, frame)
11882 struct frame *f = XFRAME (frame);
11883 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
11885 /* Ignore tooltip frame. */
11886 if (EQ (frame, tooltip_frame))
11887 continue;
11889 if (some_windows
11890 && !f->redisplay
11891 && !w->redisplay
11892 && !XBUFFER (w->contents)->text->redisplay)
11893 continue;
11895 run_window_size_change_functions (frame);
11896 menu_bar_hooks_run = update_menu_bar (f, false, menu_bar_hooks_run);
11897 #ifdef HAVE_WINDOW_SYSTEM
11898 update_tool_bar (f, false);
11899 #endif
11902 unbind_to (count, Qnil);
11904 else
11906 struct frame *sf = SELECTED_FRAME ();
11907 update_menu_bar (sf, true, false);
11908 #ifdef HAVE_WINDOW_SYSTEM
11909 update_tool_bar (sf, true);
11910 #endif
11915 /* Update the menu bar item list for frame F. This has to be done
11916 before we start to fill in any display lines, because it can call
11917 eval.
11919 If SAVE_MATCH_DATA, we must save and restore it here.
11921 If HOOKS_RUN, a previous call to update_menu_bar
11922 already ran the menu bar hooks for this redisplay, so there
11923 is no need to run them again. The return value is the
11924 updated value of this flag, to pass to the next call. */
11926 static bool
11927 update_menu_bar (struct frame *f, bool save_match_data, bool hooks_run)
11929 Lisp_Object window;
11930 struct window *w;
11932 /* If called recursively during a menu update, do nothing. This can
11933 happen when, for instance, an activate-menubar-hook causes a
11934 redisplay. */
11935 if (inhibit_menubar_update)
11936 return hooks_run;
11938 window = FRAME_SELECTED_WINDOW (f);
11939 w = XWINDOW (window);
11941 if (FRAME_WINDOW_P (f)
11943 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11944 || defined (HAVE_NS) || defined (USE_GTK)
11945 FRAME_EXTERNAL_MENU_BAR (f)
11946 #else
11947 FRAME_MENU_BAR_LINES (f) > 0
11948 #endif
11949 : FRAME_MENU_BAR_LINES (f) > 0)
11951 /* If the user has switched buffers or windows, we need to
11952 recompute to reflect the new bindings. But we'll
11953 recompute when update_mode_lines is set too; that means
11954 that people can use force-mode-line-update to request
11955 that the menu bar be recomputed. The adverse effect on
11956 the rest of the redisplay algorithm is about the same as
11957 windows_or_buffers_changed anyway. */
11958 if (windows_or_buffers_changed
11959 /* This used to test w->update_mode_line, but we believe
11960 there is no need to recompute the menu in that case. */
11961 || update_mode_lines
11962 || window_buffer_changed (w))
11964 struct buffer *prev = current_buffer;
11965 ptrdiff_t count = SPECPDL_INDEX ();
11967 specbind (Qinhibit_menubar_update, Qt);
11969 set_buffer_internal_1 (XBUFFER (w->contents));
11970 if (save_match_data)
11971 record_unwind_save_match_data ();
11972 if (NILP (Voverriding_local_map_menu_flag))
11974 specbind (Qoverriding_terminal_local_map, Qnil);
11975 specbind (Qoverriding_local_map, Qnil);
11978 if (!hooks_run)
11980 /* Run the Lucid hook. */
11981 safe_run_hooks (Qactivate_menubar_hook);
11983 /* If it has changed current-menubar from previous value,
11984 really recompute the menu-bar from the value. */
11985 if (! NILP (Vlucid_menu_bar_dirty_flag))
11986 call0 (Qrecompute_lucid_menubar);
11988 safe_run_hooks (Qmenu_bar_update_hook);
11990 hooks_run = true;
11993 XSETFRAME (Vmenu_updating_frame, f);
11994 fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
11996 /* Redisplay the menu bar in case we changed it. */
11997 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11998 || defined (HAVE_NS) || defined (USE_GTK)
11999 if (FRAME_WINDOW_P (f))
12001 #if defined (HAVE_NS)
12002 /* All frames on Mac OS share the same menubar. So only
12003 the selected frame should be allowed to set it. */
12004 if (f == SELECTED_FRAME ())
12005 #endif
12006 set_frame_menubar (f, false, false);
12008 else
12009 /* On a terminal screen, the menu bar is an ordinary screen
12010 line, and this makes it get updated. */
12011 w->update_mode_line = true;
12012 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
12013 /* In the non-toolkit version, the menu bar is an ordinary screen
12014 line, and this makes it get updated. */
12015 w->update_mode_line = true;
12016 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
12018 unbind_to (count, Qnil);
12019 set_buffer_internal_1 (prev);
12023 return hooks_run;
12026 /***********************************************************************
12027 Tool-bars
12028 ***********************************************************************/
12030 #ifdef HAVE_WINDOW_SYSTEM
12032 /* Select `frame' temporarily without running all the code in
12033 do_switch_frame.
12034 FIXME: Maybe do_switch_frame should be trimmed down similarly
12035 when `norecord' is set. */
12036 static void
12037 fast_set_selected_frame (Lisp_Object frame)
12039 if (!EQ (selected_frame, frame))
12041 selected_frame = frame;
12042 selected_window = XFRAME (frame)->selected_window;
12046 /* Update the tool-bar item list for frame F. This has to be done
12047 before we start to fill in any display lines. Called from
12048 prepare_menu_bars. If SAVE_MATCH_DATA, we must save
12049 and restore it here. */
12051 static void
12052 update_tool_bar (struct frame *f, bool save_match_data)
12054 #if defined (USE_GTK) || defined (HAVE_NS)
12055 bool do_update = FRAME_EXTERNAL_TOOL_BAR (f);
12056 #else
12057 bool do_update = (WINDOWP (f->tool_bar_window)
12058 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0);
12059 #endif
12061 if (do_update)
12063 Lisp_Object window;
12064 struct window *w;
12066 window = FRAME_SELECTED_WINDOW (f);
12067 w = XWINDOW (window);
12069 /* If the user has switched buffers or windows, we need to
12070 recompute to reflect the new bindings. But we'll
12071 recompute when update_mode_lines is set too; that means
12072 that people can use force-mode-line-update to request
12073 that the menu bar be recomputed. The adverse effect on
12074 the rest of the redisplay algorithm is about the same as
12075 windows_or_buffers_changed anyway. */
12076 if (windows_or_buffers_changed
12077 || w->update_mode_line
12078 || update_mode_lines
12079 || window_buffer_changed (w))
12081 struct buffer *prev = current_buffer;
12082 ptrdiff_t count = SPECPDL_INDEX ();
12083 Lisp_Object frame, new_tool_bar;
12084 int new_n_tool_bar;
12086 /* Set current_buffer to the buffer of the selected
12087 window of the frame, so that we get the right local
12088 keymaps. */
12089 set_buffer_internal_1 (XBUFFER (w->contents));
12091 /* Save match data, if we must. */
12092 if (save_match_data)
12093 record_unwind_save_match_data ();
12095 /* Make sure that we don't accidentally use bogus keymaps. */
12096 if (NILP (Voverriding_local_map_menu_flag))
12098 specbind (Qoverriding_terminal_local_map, Qnil);
12099 specbind (Qoverriding_local_map, Qnil);
12102 /* We must temporarily set the selected frame to this frame
12103 before calling tool_bar_items, because the calculation of
12104 the tool-bar keymap uses the selected frame (see
12105 `tool-bar-make-keymap' in tool-bar.el). */
12106 eassert (EQ (selected_window,
12107 /* Since we only explicitly preserve selected_frame,
12108 check that selected_window would be redundant. */
12109 XFRAME (selected_frame)->selected_window));
12110 record_unwind_protect (fast_set_selected_frame, selected_frame);
12111 XSETFRAME (frame, f);
12112 fast_set_selected_frame (frame);
12114 /* Build desired tool-bar items from keymaps. */
12115 new_tool_bar
12116 = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
12117 &new_n_tool_bar);
12119 /* Redisplay the tool-bar if we changed it. */
12120 if (new_n_tool_bar != f->n_tool_bar_items
12121 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
12123 /* Redisplay that happens asynchronously due to an expose event
12124 may access f->tool_bar_items. Make sure we update both
12125 variables within BLOCK_INPUT so no such event interrupts. */
12126 block_input ();
12127 fset_tool_bar_items (f, new_tool_bar);
12128 f->n_tool_bar_items = new_n_tool_bar;
12129 w->update_mode_line = true;
12130 unblock_input ();
12133 unbind_to (count, Qnil);
12134 set_buffer_internal_1 (prev);
12139 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12141 /* Set F->desired_tool_bar_string to a Lisp string representing frame
12142 F's desired tool-bar contents. F->tool_bar_items must have
12143 been set up previously by calling prepare_menu_bars. */
12145 static void
12146 build_desired_tool_bar_string (struct frame *f)
12148 int i, size, size_needed;
12149 Lisp_Object image, plist;
12151 image = plist = Qnil;
12153 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
12154 Otherwise, make a new string. */
12156 /* The size of the string we might be able to reuse. */
12157 size = (STRINGP (f->desired_tool_bar_string)
12158 ? SCHARS (f->desired_tool_bar_string)
12159 : 0);
12161 /* We need one space in the string for each image. */
12162 size_needed = f->n_tool_bar_items;
12164 /* Reuse f->desired_tool_bar_string, if possible. */
12165 if (size < size_needed || NILP (f->desired_tool_bar_string))
12166 fset_desired_tool_bar_string
12167 (f, Fmake_string (make_number (size_needed), make_number (' ')));
12168 else
12170 AUTO_LIST4 (props, Qdisplay, Qnil, Qmenu_item, Qnil);
12171 Fremove_text_properties (make_number (0), make_number (size),
12172 props, f->desired_tool_bar_string);
12175 /* Put a `display' property on the string for the images to display,
12176 put a `menu_item' property on tool-bar items with a value that
12177 is the index of the item in F's tool-bar item vector. */
12178 for (i = 0; i < f->n_tool_bar_items; ++i)
12180 #define PROP(IDX) \
12181 AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
12183 bool enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
12184 bool selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
12185 int hmargin, vmargin, relief, idx, end;
12187 /* If image is a vector, choose the image according to the
12188 button state. */
12189 image = PROP (TOOL_BAR_ITEM_IMAGES);
12190 if (VECTORP (image))
12192 if (enabled_p)
12193 idx = (selected_p
12194 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
12195 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
12196 else
12197 idx = (selected_p
12198 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
12199 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
12201 eassert (ASIZE (image) >= idx);
12202 image = AREF (image, idx);
12204 else
12205 idx = -1;
12207 /* Ignore invalid image specifications. */
12208 if (!valid_image_p (image))
12209 continue;
12211 /* Display the tool-bar button pressed, or depressed. */
12212 plist = Fcopy_sequence (XCDR (image));
12214 /* Compute margin and relief to draw. */
12215 relief = (tool_bar_button_relief >= 0
12216 ? tool_bar_button_relief
12217 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
12218 hmargin = vmargin = relief;
12220 if (RANGED_INTEGERP (1, Vtool_bar_button_margin,
12221 INT_MAX - max (hmargin, vmargin)))
12223 hmargin += XFASTINT (Vtool_bar_button_margin);
12224 vmargin += XFASTINT (Vtool_bar_button_margin);
12226 else if (CONSP (Vtool_bar_button_margin))
12228 if (RANGED_INTEGERP (1, XCAR (Vtool_bar_button_margin),
12229 INT_MAX - hmargin))
12230 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
12232 if (RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin),
12233 INT_MAX - vmargin))
12234 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
12237 if (auto_raise_tool_bar_buttons_p)
12239 /* Add a `:relief' property to the image spec if the item is
12240 selected. */
12241 if (selected_p)
12243 plist = Fplist_put (plist, QCrelief, make_number (-relief));
12244 hmargin -= relief;
12245 vmargin -= relief;
12248 else
12250 /* If image is selected, display it pressed, i.e. with a
12251 negative relief. If it's not selected, display it with a
12252 raised relief. */
12253 plist = Fplist_put (plist, QCrelief,
12254 (selected_p
12255 ? make_number (-relief)
12256 : make_number (relief)));
12257 hmargin -= relief;
12258 vmargin -= relief;
12261 /* Put a margin around the image. */
12262 if (hmargin || vmargin)
12264 if (hmargin == vmargin)
12265 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
12266 else
12267 plist = Fplist_put (plist, QCmargin,
12268 Fcons (make_number (hmargin),
12269 make_number (vmargin)));
12272 /* If button is not enabled, and we don't have special images
12273 for the disabled state, make the image appear disabled by
12274 applying an appropriate algorithm to it. */
12275 if (!enabled_p && idx < 0)
12276 plist = Fplist_put (plist, QCconversion, Qdisabled);
12278 /* Put a `display' text property on the string for the image to
12279 display. Put a `menu-item' property on the string that gives
12280 the start of this item's properties in the tool-bar items
12281 vector. */
12282 image = Fcons (Qimage, plist);
12283 AUTO_LIST4 (props, Qdisplay, image, Qmenu_item,
12284 make_number (i * TOOL_BAR_ITEM_NSLOTS));
12286 /* Let the last image hide all remaining spaces in the tool bar
12287 string. The string can be longer than needed when we reuse a
12288 previous string. */
12289 if (i + 1 == f->n_tool_bar_items)
12290 end = SCHARS (f->desired_tool_bar_string);
12291 else
12292 end = i + 1;
12293 Fadd_text_properties (make_number (i), make_number (end),
12294 props, f->desired_tool_bar_string);
12295 #undef PROP
12300 /* Display one line of the tool-bar of frame IT->f.
12302 HEIGHT specifies the desired height of the tool-bar line.
12303 If the actual height of the glyph row is less than HEIGHT, the
12304 row's height is increased to HEIGHT, and the icons are centered
12305 vertically in the new height.
12307 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
12308 count a final empty row in case the tool-bar width exactly matches
12309 the window width.
12312 static void
12313 display_tool_bar_line (struct it *it, int height)
12315 struct glyph_row *row = it->glyph_row;
12316 int max_x = it->last_visible_x;
12317 struct glyph *last;
12319 /* Don't extend on a previously drawn tool bar items (Bug#16058). */
12320 clear_glyph_row (row);
12321 row->enabled_p = true;
12322 row->y = it->current_y;
12324 /* Note that this isn't made use of if the face hasn't a box,
12325 so there's no need to check the face here. */
12326 it->start_of_box_run_p = true;
12328 while (it->current_x < max_x)
12330 int x, n_glyphs_before, i, nglyphs;
12331 struct it it_before;
12333 /* Get the next display element. */
12334 if (!get_next_display_element (it))
12336 /* Don't count empty row if we are counting needed tool-bar lines. */
12337 if (height < 0 && !it->hpos)
12338 return;
12339 break;
12342 /* Produce glyphs. */
12343 n_glyphs_before = row->used[TEXT_AREA];
12344 it_before = *it;
12346 PRODUCE_GLYPHS (it);
12348 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
12349 i = 0;
12350 x = it_before.current_x;
12351 while (i < nglyphs)
12353 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
12355 if (x + glyph->pixel_width > max_x)
12357 /* Glyph doesn't fit on line. Backtrack. */
12358 row->used[TEXT_AREA] = n_glyphs_before;
12359 *it = it_before;
12360 /* If this is the only glyph on this line, it will never fit on the
12361 tool-bar, so skip it. But ensure there is at least one glyph,
12362 so we don't accidentally disable the tool-bar. */
12363 if (n_glyphs_before == 0
12364 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
12365 break;
12366 goto out;
12369 ++it->hpos;
12370 x += glyph->pixel_width;
12371 ++i;
12374 /* Stop at line end. */
12375 if (ITERATOR_AT_END_OF_LINE_P (it))
12376 break;
12378 set_iterator_to_next (it, true);
12381 out:;
12383 row->displays_text_p = row->used[TEXT_AREA] != 0;
12385 /* Use default face for the border below the tool bar.
12387 FIXME: When auto-resize-tool-bars is grow-only, there is
12388 no additional border below the possibly empty tool-bar lines.
12389 So to make the extra empty lines look "normal", we have to
12390 use the tool-bar face for the border too. */
12391 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
12392 && !EQ (Vauto_resize_tool_bars, Qgrow_only))
12393 it->face_id = DEFAULT_FACE_ID;
12395 extend_face_to_end_of_line (it);
12396 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
12397 last->right_box_line_p = true;
12398 if (last == row->glyphs[TEXT_AREA])
12399 last->left_box_line_p = true;
12401 /* Make line the desired height and center it vertically. */
12402 if ((height -= it->max_ascent + it->max_descent) > 0)
12404 /* Don't add more than one line height. */
12405 height %= FRAME_LINE_HEIGHT (it->f);
12406 it->max_ascent += height / 2;
12407 it->max_descent += (height + 1) / 2;
12410 compute_line_metrics (it);
12412 /* If line is empty, make it occupy the rest of the tool-bar. */
12413 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row))
12415 row->height = row->phys_height = it->last_visible_y - row->y;
12416 row->visible_height = row->height;
12417 row->ascent = row->phys_ascent = 0;
12418 row->extra_line_spacing = 0;
12421 row->full_width_p = true;
12422 row->continued_p = false;
12423 row->truncated_on_left_p = false;
12424 row->truncated_on_right_p = false;
12426 it->current_x = it->hpos = 0;
12427 it->current_y += row->height;
12428 ++it->vpos;
12429 ++it->glyph_row;
12433 /* Value is the number of pixels needed to make all tool-bar items of
12434 frame F visible. The actual number of glyph rows needed is
12435 returned in *N_ROWS if non-NULL. */
12436 static int
12437 tool_bar_height (struct frame *f, int *n_rows, bool pixelwise)
12439 struct window *w = XWINDOW (f->tool_bar_window);
12440 struct it it;
12441 /* tool_bar_height is called from redisplay_tool_bar after building
12442 the desired matrix, so use (unused) mode-line row as temporary row to
12443 avoid destroying the first tool-bar row. */
12444 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
12446 /* Initialize an iterator for iteration over
12447 F->desired_tool_bar_string in the tool-bar window of frame F. */
12448 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
12449 temp_row->reversed_p = false;
12450 it.first_visible_x = 0;
12451 it.last_visible_x = WINDOW_PIXEL_WIDTH (w);
12452 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
12453 it.paragraph_embedding = L2R;
12455 while (!ITERATOR_AT_END_P (&it))
12457 clear_glyph_row (temp_row);
12458 it.glyph_row = temp_row;
12459 display_tool_bar_line (&it, -1);
12461 clear_glyph_row (temp_row);
12463 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
12464 if (n_rows)
12465 *n_rows = it.vpos > 0 ? it.vpos : -1;
12467 if (pixelwise)
12468 return it.current_y;
12469 else
12470 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
12473 #endif /* !USE_GTK && !HAVE_NS */
12475 DEFUN ("tool-bar-height", Ftool_bar_height, Stool_bar_height,
12476 0, 2, 0,
12477 doc: /* Return the number of lines occupied by the tool bar of FRAME.
12478 If FRAME is nil or omitted, use the selected frame. Optional argument
12479 PIXELWISE non-nil means return the height of the tool bar in pixels. */)
12480 (Lisp_Object frame, Lisp_Object pixelwise)
12482 int height = 0;
12484 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12485 struct frame *f = decode_any_frame (frame);
12487 if (WINDOWP (f->tool_bar_window)
12488 && WINDOW_PIXEL_HEIGHT (XWINDOW (f->tool_bar_window)) > 0)
12490 update_tool_bar (f, true);
12491 if (f->n_tool_bar_items)
12493 build_desired_tool_bar_string (f);
12494 height = tool_bar_height (f, NULL, !NILP (pixelwise));
12497 #endif
12499 return make_number (height);
12503 /* Display the tool-bar of frame F. Value is true if tool-bar's
12504 height should be changed. */
12505 static bool
12506 redisplay_tool_bar (struct frame *f)
12508 f->tool_bar_redisplayed = true;
12509 #if defined (USE_GTK) || defined (HAVE_NS)
12511 if (FRAME_EXTERNAL_TOOL_BAR (f))
12512 update_frame_tool_bar (f);
12513 return false;
12515 #else /* !USE_GTK && !HAVE_NS */
12517 struct window *w;
12518 struct it it;
12519 struct glyph_row *row;
12521 /* If frame hasn't a tool-bar window or if it is zero-height, don't
12522 do anything. This means you must start with tool-bar-lines
12523 non-zero to get the auto-sizing effect. Or in other words, you
12524 can turn off tool-bars by specifying tool-bar-lines zero. */
12525 if (!WINDOWP (f->tool_bar_window)
12526 || (w = XWINDOW (f->tool_bar_window),
12527 WINDOW_TOTAL_LINES (w) == 0))
12528 return false;
12530 /* Set up an iterator for the tool-bar window. */
12531 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
12532 it.first_visible_x = 0;
12533 it.last_visible_x = WINDOW_PIXEL_WIDTH (w);
12534 row = it.glyph_row;
12535 row->reversed_p = false;
12537 /* Build a string that represents the contents of the tool-bar. */
12538 build_desired_tool_bar_string (f);
12539 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
12540 /* FIXME: This should be controlled by a user option. But it
12541 doesn't make sense to have an R2L tool bar if the menu bar cannot
12542 be drawn also R2L, and making the menu bar R2L is tricky due
12543 toolkit-specific code that implements it. If an R2L tool bar is
12544 ever supported, display_tool_bar_line should also be augmented to
12545 call unproduce_glyphs like display_line and display_string
12546 do. */
12547 it.paragraph_embedding = L2R;
12549 if (f->n_tool_bar_rows == 0)
12551 int new_height = tool_bar_height (f, &f->n_tool_bar_rows, true);
12553 if (new_height != WINDOW_PIXEL_HEIGHT (w))
12555 x_change_tool_bar_height (f, new_height);
12556 frame_default_tool_bar_height = new_height;
12557 /* Always do that now. */
12558 clear_glyph_matrix (w->desired_matrix);
12559 f->fonts_changed = true;
12560 return true;
12564 /* Display as many lines as needed to display all tool-bar items. */
12566 if (f->n_tool_bar_rows > 0)
12568 int border, rows, height, extra;
12570 if (TYPE_RANGED_INTEGERP (int, Vtool_bar_border))
12571 border = XINT (Vtool_bar_border);
12572 else if (EQ (Vtool_bar_border, Qinternal_border_width))
12573 border = FRAME_INTERNAL_BORDER_WIDTH (f);
12574 else if (EQ (Vtool_bar_border, Qborder_width))
12575 border = f->border_width;
12576 else
12577 border = 0;
12578 if (border < 0)
12579 border = 0;
12581 rows = f->n_tool_bar_rows;
12582 height = max (1, (it.last_visible_y - border) / rows);
12583 extra = it.last_visible_y - border - height * rows;
12585 while (it.current_y < it.last_visible_y)
12587 int h = 0;
12588 if (extra > 0 && rows-- > 0)
12590 h = (extra + rows - 1) / rows;
12591 extra -= h;
12593 display_tool_bar_line (&it, height + h);
12596 else
12598 while (it.current_y < it.last_visible_y)
12599 display_tool_bar_line (&it, 0);
12602 /* It doesn't make much sense to try scrolling in the tool-bar
12603 window, so don't do it. */
12604 w->desired_matrix->no_scrolling_p = true;
12605 w->must_be_updated_p = true;
12607 if (!NILP (Vauto_resize_tool_bars))
12609 bool change_height_p = true;
12611 /* If we couldn't display everything, change the tool-bar's
12612 height if there is room for more. */
12613 if (IT_STRING_CHARPOS (it) < it.end_charpos)
12614 change_height_p = true;
12616 /* We subtract 1 because display_tool_bar_line advances the
12617 glyph_row pointer before returning to its caller. We want to
12618 examine the last glyph row produced by
12619 display_tool_bar_line. */
12620 row = it.glyph_row - 1;
12622 /* If there are blank lines at the end, except for a partially
12623 visible blank line at the end that is smaller than
12624 FRAME_LINE_HEIGHT, change the tool-bar's height. */
12625 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
12626 && row->height >= FRAME_LINE_HEIGHT (f))
12627 change_height_p = true;
12629 /* If row displays tool-bar items, but is partially visible,
12630 change the tool-bar's height. */
12631 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12632 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
12633 change_height_p = true;
12635 /* Resize windows as needed by changing the `tool-bar-lines'
12636 frame parameter. */
12637 if (change_height_p)
12639 int nrows;
12640 int new_height = tool_bar_height (f, &nrows, true);
12642 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
12643 && !f->minimize_tool_bar_window_p)
12644 ? (new_height > WINDOW_PIXEL_HEIGHT (w))
12645 : (new_height != WINDOW_PIXEL_HEIGHT (w)));
12646 f->minimize_tool_bar_window_p = false;
12648 if (change_height_p)
12650 x_change_tool_bar_height (f, new_height);
12651 frame_default_tool_bar_height = new_height;
12652 clear_glyph_matrix (w->desired_matrix);
12653 f->n_tool_bar_rows = nrows;
12654 f->fonts_changed = true;
12656 return true;
12661 f->minimize_tool_bar_window_p = false;
12662 return false;
12664 #endif /* USE_GTK || HAVE_NS */
12667 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12669 /* Get information about the tool-bar item which is displayed in GLYPH
12670 on frame F. Return in *PROP_IDX the index where tool-bar item
12671 properties start in F->tool_bar_items. Value is false if
12672 GLYPH doesn't display a tool-bar item. */
12674 static bool
12675 tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
12677 Lisp_Object prop;
12678 int charpos;
12680 /* This function can be called asynchronously, which means we must
12681 exclude any possibility that Fget_text_property signals an
12682 error. */
12683 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
12684 charpos = max (0, charpos);
12686 /* Get the text property `menu-item' at pos. The value of that
12687 property is the start index of this item's properties in
12688 F->tool_bar_items. */
12689 prop = Fget_text_property (make_number (charpos),
12690 Qmenu_item, f->current_tool_bar_string);
12691 if (! INTEGERP (prop))
12692 return false;
12693 *prop_idx = XINT (prop);
12694 return true;
12698 /* Get information about the tool-bar item at position X/Y on frame F.
12699 Return in *GLYPH a pointer to the glyph of the tool-bar item in
12700 the current matrix of the tool-bar window of F, or NULL if not
12701 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
12702 item in F->tool_bar_items. Value is
12704 -1 if X/Y is not on a tool-bar item
12705 0 if X/Y is on the same item that was highlighted before.
12706 1 otherwise. */
12708 static int
12709 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
12710 int *hpos, int *vpos, int *prop_idx)
12712 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12713 struct window *w = XWINDOW (f->tool_bar_window);
12714 int area;
12716 /* Find the glyph under X/Y. */
12717 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
12718 if (*glyph == NULL)
12719 return -1;
12721 /* Get the start of this tool-bar item's properties in
12722 f->tool_bar_items. */
12723 if (!tool_bar_item_info (f, *glyph, prop_idx))
12724 return -1;
12726 /* Is mouse on the highlighted item? */
12727 if (EQ (f->tool_bar_window, hlinfo->mouse_face_window)
12728 && *vpos >= hlinfo->mouse_face_beg_row
12729 && *vpos <= hlinfo->mouse_face_end_row
12730 && (*vpos > hlinfo->mouse_face_beg_row
12731 || *hpos >= hlinfo->mouse_face_beg_col)
12732 && (*vpos < hlinfo->mouse_face_end_row
12733 || *hpos < hlinfo->mouse_face_end_col
12734 || hlinfo->mouse_face_past_end))
12735 return 0;
12737 return 1;
12741 /* EXPORT:
12742 Handle mouse button event on the tool-bar of frame F, at
12743 frame-relative coordinates X/Y. DOWN_P is true for a button press,
12744 false for button release. MODIFIERS is event modifiers for button
12745 release. */
12747 void
12748 handle_tool_bar_click (struct frame *f, int x, int y, bool down_p,
12749 int modifiers)
12751 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12752 struct window *w = XWINDOW (f->tool_bar_window);
12753 int hpos, vpos, prop_idx;
12754 struct glyph *glyph;
12755 Lisp_Object enabled_p;
12756 int ts;
12758 /* If not on the highlighted tool-bar item, and mouse-highlight is
12759 non-nil, return. This is so we generate the tool-bar button
12760 click only when the mouse button is released on the same item as
12761 where it was pressed. However, when mouse-highlight is disabled,
12762 generate the click when the button is released regardless of the
12763 highlight, since tool-bar items are not highlighted in that
12764 case. */
12765 frame_to_window_pixel_xy (w, &x, &y);
12766 ts = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12767 if (ts == -1
12768 || (ts != 0 && !NILP (Vmouse_highlight)))
12769 return;
12771 /* When mouse-highlight is off, generate the click for the item
12772 where the button was pressed, disregarding where it was
12773 released. */
12774 if (NILP (Vmouse_highlight) && !down_p)
12775 prop_idx = f->last_tool_bar_item;
12777 /* If item is disabled, do nothing. */
12778 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12779 if (NILP (enabled_p))
12780 return;
12782 if (down_p)
12784 /* Show item in pressed state. */
12785 if (!NILP (Vmouse_highlight))
12786 show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
12787 f->last_tool_bar_item = prop_idx;
12789 else
12791 Lisp_Object key, frame;
12792 struct input_event event;
12793 EVENT_INIT (event);
12795 /* Show item in released state. */
12796 if (!NILP (Vmouse_highlight))
12797 show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
12799 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
12801 XSETFRAME (frame, f);
12802 event.kind = TOOL_BAR_EVENT;
12803 event.frame_or_window = frame;
12804 event.arg = frame;
12805 kbd_buffer_store_event (&event);
12807 event.kind = TOOL_BAR_EVENT;
12808 event.frame_or_window = frame;
12809 event.arg = key;
12810 event.modifiers = modifiers;
12811 kbd_buffer_store_event (&event);
12812 f->last_tool_bar_item = -1;
12817 /* Possibly highlight a tool-bar item on frame F when mouse moves to
12818 tool-bar window-relative coordinates X/Y. Called from
12819 note_mouse_highlight. */
12821 static void
12822 note_tool_bar_highlight (struct frame *f, int x, int y)
12824 Lisp_Object window = f->tool_bar_window;
12825 struct window *w = XWINDOW (window);
12826 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
12827 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12828 int hpos, vpos;
12829 struct glyph *glyph;
12830 struct glyph_row *row;
12831 int i;
12832 Lisp_Object enabled_p;
12833 int prop_idx;
12834 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
12835 bool mouse_down_p;
12836 int rc;
12838 /* Function note_mouse_highlight is called with negative X/Y
12839 values when mouse moves outside of the frame. */
12840 if (x <= 0 || y <= 0)
12842 clear_mouse_face (hlinfo);
12843 return;
12846 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12847 if (rc < 0)
12849 /* Not on tool-bar item. */
12850 clear_mouse_face (hlinfo);
12851 return;
12853 else if (rc == 0)
12854 /* On same tool-bar item as before. */
12855 goto set_help_echo;
12857 clear_mouse_face (hlinfo);
12859 /* Mouse is down, but on different tool-bar item? */
12860 mouse_down_p = (x_mouse_grabbed (dpyinfo)
12861 && f == dpyinfo->last_mouse_frame);
12863 if (mouse_down_p && f->last_tool_bar_item != prop_idx)
12864 return;
12866 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
12868 /* If tool-bar item is not enabled, don't highlight it. */
12869 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12870 if (!NILP (enabled_p) && !NILP (Vmouse_highlight))
12872 /* Compute the x-position of the glyph. In front and past the
12873 image is a space. We include this in the highlighted area. */
12874 row = MATRIX_ROW (w->current_matrix, vpos);
12875 for (i = x = 0; i < hpos; ++i)
12876 x += row->glyphs[TEXT_AREA][i].pixel_width;
12878 /* Record this as the current active region. */
12879 hlinfo->mouse_face_beg_col = hpos;
12880 hlinfo->mouse_face_beg_row = vpos;
12881 hlinfo->mouse_face_beg_x = x;
12882 hlinfo->mouse_face_past_end = false;
12884 hlinfo->mouse_face_end_col = hpos + 1;
12885 hlinfo->mouse_face_end_row = vpos;
12886 hlinfo->mouse_face_end_x = x + glyph->pixel_width;
12887 hlinfo->mouse_face_window = window;
12888 hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
12890 /* Display it as active. */
12891 show_mouse_face (hlinfo, draw);
12894 set_help_echo:
12896 /* Set help_echo_string to a help string to display for this tool-bar item.
12897 XTread_socket does the rest. */
12898 help_echo_object = help_echo_window = Qnil;
12899 help_echo_pos = -1;
12900 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
12901 if (NILP (help_echo_string))
12902 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
12905 #endif /* !USE_GTK && !HAVE_NS */
12907 #endif /* HAVE_WINDOW_SYSTEM */
12911 /************************************************************************
12912 Horizontal scrolling
12913 ************************************************************************/
12915 /* For all leaf windows in the window tree rooted at WINDOW, set their
12916 hscroll value so that PT is (i) visible in the window, and (ii) so
12917 that it is not within a certain margin at the window's left and
12918 right border. Value is true if any window's hscroll has been
12919 changed. */
12921 static bool
12922 hscroll_window_tree (Lisp_Object window)
12924 bool hscrolled_p = false;
12925 bool hscroll_relative_p = FLOATP (Vhscroll_step);
12926 int hscroll_step_abs = 0;
12927 double hscroll_step_rel = 0;
12929 if (hscroll_relative_p)
12931 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
12932 if (hscroll_step_rel < 0)
12934 hscroll_relative_p = false;
12935 hscroll_step_abs = 0;
12938 else if (TYPE_RANGED_INTEGERP (int, Vhscroll_step))
12940 hscroll_step_abs = XINT (Vhscroll_step);
12941 if (hscroll_step_abs < 0)
12942 hscroll_step_abs = 0;
12944 else
12945 hscroll_step_abs = 0;
12947 while (WINDOWP (window))
12949 struct window *w = XWINDOW (window);
12951 if (WINDOWP (w->contents))
12952 hscrolled_p |= hscroll_window_tree (w->contents);
12953 else if (w->cursor.vpos >= 0)
12955 int h_margin;
12956 int text_area_width;
12957 struct glyph_row *cursor_row;
12958 struct glyph_row *bottom_row;
12960 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->desired_matrix, w);
12961 if (w->cursor.vpos < bottom_row - w->desired_matrix->rows)
12962 cursor_row = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
12963 else
12964 cursor_row = bottom_row - 1;
12966 if (!cursor_row->enabled_p)
12968 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12969 if (w->cursor.vpos < bottom_row - w->current_matrix->rows)
12970 cursor_row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
12971 else
12972 cursor_row = bottom_row - 1;
12974 bool row_r2l_p = cursor_row->reversed_p;
12976 text_area_width = window_box_width (w, TEXT_AREA);
12978 /* Scroll when cursor is inside this scroll margin. */
12979 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
12981 /* If the position of this window's point has explicitly
12982 changed, no more suspend auto hscrolling. */
12983 if (NILP (Fequal (Fwindow_point (window), Fwindow_old_point (window))))
12984 w->suspend_auto_hscroll = false;
12986 /* Remember window point. */
12987 Fset_marker (w->old_pointm,
12988 ((w == XWINDOW (selected_window))
12989 ? make_number (BUF_PT (XBUFFER (w->contents)))
12990 : Fmarker_position (w->pointm)),
12991 w->contents);
12993 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->contents))
12994 && !w->suspend_auto_hscroll
12995 /* In some pathological cases, like restoring a window
12996 configuration into a frame that is much smaller than
12997 the one from which the configuration was saved, we
12998 get glyph rows whose start and end have zero buffer
12999 positions, which we cannot handle below. Just skip
13000 such windows. */
13001 && CHARPOS (cursor_row->start.pos) >= BUF_BEG (w->contents)
13002 /* For left-to-right rows, hscroll when cursor is either
13003 (i) inside the right hscroll margin, or (ii) if it is
13004 inside the left margin and the window is already
13005 hscrolled. */
13006 && ((!row_r2l_p
13007 && ((w->hscroll && w->cursor.x <= h_margin)
13008 || (cursor_row->enabled_p
13009 && cursor_row->truncated_on_right_p
13010 && (w->cursor.x >= text_area_width - h_margin))))
13011 /* For right-to-left rows, the logic is similar,
13012 except that rules for scrolling to left and right
13013 are reversed. E.g., if cursor.x <= h_margin, we
13014 need to hscroll "to the right" unconditionally,
13015 and that will scroll the screen to the left so as
13016 to reveal the next portion of the row. */
13017 || (row_r2l_p
13018 && ((cursor_row->enabled_p
13019 /* FIXME: It is confusing to set the
13020 truncated_on_right_p flag when R2L rows
13021 are actually truncated on the left. */
13022 && cursor_row->truncated_on_right_p
13023 && w->cursor.x <= h_margin)
13024 || (w->hscroll
13025 && (w->cursor.x >= text_area_width - h_margin))))))
13027 struct it it;
13028 ptrdiff_t hscroll;
13029 struct buffer *saved_current_buffer;
13030 ptrdiff_t pt;
13031 int wanted_x;
13033 /* Find point in a display of infinite width. */
13034 saved_current_buffer = current_buffer;
13035 current_buffer = XBUFFER (w->contents);
13037 if (w == XWINDOW (selected_window))
13038 pt = PT;
13039 else
13040 pt = clip_to_bounds (BEGV, marker_position (w->pointm), ZV);
13042 /* Move iterator to pt starting at cursor_row->start in
13043 a line with infinite width. */
13044 init_to_row_start (&it, w, cursor_row);
13045 it.last_visible_x = INFINITY;
13046 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
13047 current_buffer = saved_current_buffer;
13049 /* Position cursor in window. */
13050 if (!hscroll_relative_p && hscroll_step_abs == 0)
13051 hscroll = max (0, (it.current_x
13052 - (ITERATOR_AT_END_OF_LINE_P (&it)
13053 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
13054 : (text_area_width / 2))))
13055 / FRAME_COLUMN_WIDTH (it.f);
13056 else if ((!row_r2l_p
13057 && w->cursor.x >= text_area_width - h_margin)
13058 || (row_r2l_p && w->cursor.x <= h_margin))
13060 if (hscroll_relative_p)
13061 wanted_x = text_area_width * (1 - hscroll_step_rel)
13062 - h_margin;
13063 else
13064 wanted_x = text_area_width
13065 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
13066 - h_margin;
13067 hscroll
13068 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
13070 else
13072 if (hscroll_relative_p)
13073 wanted_x = text_area_width * hscroll_step_rel
13074 + h_margin;
13075 else
13076 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
13077 + h_margin;
13078 hscroll
13079 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
13081 hscroll = max (hscroll, w->min_hscroll);
13083 /* Don't prevent redisplay optimizations if hscroll
13084 hasn't changed, as it will unnecessarily slow down
13085 redisplay. */
13086 if (w->hscroll != hscroll)
13088 struct buffer *b = XBUFFER (w->contents);
13089 b->prevent_redisplay_optimizations_p = true;
13090 w->hscroll = hscroll;
13091 hscrolled_p = true;
13096 window = w->next;
13099 /* Value is true if hscroll of any leaf window has been changed. */
13100 return hscrolled_p;
13104 /* Set hscroll so that cursor is visible and not inside horizontal
13105 scroll margins for all windows in the tree rooted at WINDOW. See
13106 also hscroll_window_tree above. Value is true if any window's
13107 hscroll has been changed. If it has, desired matrices on the frame
13108 of WINDOW are cleared. */
13110 static bool
13111 hscroll_windows (Lisp_Object window)
13113 bool hscrolled_p = hscroll_window_tree (window);
13114 if (hscrolled_p)
13115 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
13116 return hscrolled_p;
13121 /************************************************************************
13122 Redisplay
13123 ************************************************************************/
13125 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined.
13126 This is sometimes handy to have in a debugger session. */
13128 #ifdef GLYPH_DEBUG
13130 /* First and last unchanged row for try_window_id. */
13132 static int debug_first_unchanged_at_end_vpos;
13133 static int debug_last_unchanged_at_beg_vpos;
13135 /* Delta vpos and y. */
13137 static int debug_dvpos, debug_dy;
13139 /* Delta in characters and bytes for try_window_id. */
13141 static ptrdiff_t debug_delta, debug_delta_bytes;
13143 /* Values of window_end_pos and window_end_vpos at the end of
13144 try_window_id. */
13146 static ptrdiff_t debug_end_vpos;
13148 /* Append a string to W->desired_matrix->method. FMT is a printf
13149 format string. If trace_redisplay_p is true also printf the
13150 resulting string to stderr. */
13152 static void debug_method_add (struct window *, char const *, ...)
13153 ATTRIBUTE_FORMAT_PRINTF (2, 3);
13155 static void
13156 debug_method_add (struct window *w, char const *fmt, ...)
13158 void *ptr = w;
13159 char *method = w->desired_matrix->method;
13160 int len = strlen (method);
13161 int size = sizeof w->desired_matrix->method;
13162 int remaining = size - len - 1;
13163 va_list ap;
13165 if (len && remaining)
13167 method[len] = '|';
13168 --remaining, ++len;
13171 va_start (ap, fmt);
13172 vsnprintf (method + len, remaining + 1, fmt, ap);
13173 va_end (ap);
13175 if (trace_redisplay_p)
13176 fprintf (stderr, "%p (%s): %s\n",
13177 ptr,
13178 ((BUFFERP (w->contents)
13179 && STRINGP (BVAR (XBUFFER (w->contents), name)))
13180 ? SSDATA (BVAR (XBUFFER (w->contents), name))
13181 : "no buffer"),
13182 method + len);
13185 #endif /* GLYPH_DEBUG */
13188 /* Value is true if all changes in window W, which displays
13189 current_buffer, are in the text between START and END. START is a
13190 buffer position, END is given as a distance from Z. Used in
13191 redisplay_internal for display optimization. */
13193 static bool
13194 text_outside_line_unchanged_p (struct window *w,
13195 ptrdiff_t start, ptrdiff_t end)
13197 bool unchanged_p = true;
13199 /* If text or overlays have changed, see where. */
13200 if (window_outdated (w))
13202 /* Gap in the line? */
13203 if (GPT < start || Z - GPT < end)
13204 unchanged_p = false;
13206 /* Changes start in front of the line, or end after it? */
13207 if (unchanged_p
13208 && (BEG_UNCHANGED < start - 1
13209 || END_UNCHANGED < end))
13210 unchanged_p = false;
13212 /* If selective display, can't optimize if changes start at the
13213 beginning of the line. */
13214 if (unchanged_p
13215 && INTEGERP (BVAR (current_buffer, selective_display))
13216 && XINT (BVAR (current_buffer, selective_display)) > 0
13217 && (BEG_UNCHANGED < start || GPT <= start))
13218 unchanged_p = false;
13220 /* If there are overlays at the start or end of the line, these
13221 may have overlay strings with newlines in them. A change at
13222 START, for instance, may actually concern the display of such
13223 overlay strings as well, and they are displayed on different
13224 lines. So, quickly rule out this case. (For the future, it
13225 might be desirable to implement something more telling than
13226 just BEG/END_UNCHANGED.) */
13227 if (unchanged_p)
13229 if (BEG + BEG_UNCHANGED == start
13230 && overlay_touches_p (start))
13231 unchanged_p = false;
13232 if (END_UNCHANGED == end
13233 && overlay_touches_p (Z - end))
13234 unchanged_p = false;
13237 /* Under bidi reordering, adding or deleting a character in the
13238 beginning of a paragraph, before the first strong directional
13239 character, can change the base direction of the paragraph (unless
13240 the buffer specifies a fixed paragraph direction), which will
13241 require redisplaying the whole paragraph. It might be worthwhile
13242 to find the paragraph limits and widen the range of redisplayed
13243 lines to that, but for now just give up this optimization. */
13244 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
13245 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
13246 unchanged_p = false;
13249 return unchanged_p;
13253 /* Do a frame update, taking possible shortcuts into account. This is
13254 the main external entry point for redisplay.
13256 If the last redisplay displayed an echo area message and that message
13257 is no longer requested, we clear the echo area or bring back the
13258 mini-buffer if that is in use. */
13260 void
13261 redisplay (void)
13263 redisplay_internal ();
13267 static Lisp_Object
13268 overlay_arrow_string_or_property (Lisp_Object var)
13270 Lisp_Object val;
13272 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
13273 return val;
13275 return Voverlay_arrow_string;
13278 /* Return true if there are any overlay-arrows in current_buffer. */
13279 static bool
13280 overlay_arrow_in_current_buffer_p (void)
13282 Lisp_Object vlist;
13284 for (vlist = Voverlay_arrow_variable_list;
13285 CONSP (vlist);
13286 vlist = XCDR (vlist))
13288 Lisp_Object var = XCAR (vlist);
13289 Lisp_Object val;
13291 if (!SYMBOLP (var))
13292 continue;
13293 val = find_symbol_value (var);
13294 if (MARKERP (val)
13295 && current_buffer == XMARKER (val)->buffer)
13296 return true;
13298 return false;
13302 /* Return true if any overlay_arrows have moved or overlay-arrow-string
13303 has changed. */
13305 static bool
13306 overlay_arrows_changed_p (void)
13308 Lisp_Object vlist;
13310 for (vlist = Voverlay_arrow_variable_list;
13311 CONSP (vlist);
13312 vlist = XCDR (vlist))
13314 Lisp_Object var = XCAR (vlist);
13315 Lisp_Object val, pstr;
13317 if (!SYMBOLP (var))
13318 continue;
13319 val = find_symbol_value (var);
13320 if (!MARKERP (val))
13321 continue;
13322 if (! EQ (COERCE_MARKER (val),
13323 Fget (var, Qlast_arrow_position))
13324 || ! (pstr = overlay_arrow_string_or_property (var),
13325 EQ (pstr, Fget (var, Qlast_arrow_string))))
13326 return true;
13328 return false;
13331 /* Mark overlay arrows to be updated on next redisplay. */
13333 static void
13334 update_overlay_arrows (int up_to_date)
13336 Lisp_Object vlist;
13338 for (vlist = Voverlay_arrow_variable_list;
13339 CONSP (vlist);
13340 vlist = XCDR (vlist))
13342 Lisp_Object var = XCAR (vlist);
13344 if (!SYMBOLP (var))
13345 continue;
13347 if (up_to_date > 0)
13349 Lisp_Object val = find_symbol_value (var);
13350 Fput (var, Qlast_arrow_position,
13351 COERCE_MARKER (val));
13352 Fput (var, Qlast_arrow_string,
13353 overlay_arrow_string_or_property (var));
13355 else if (up_to_date < 0
13356 || !NILP (Fget (var, Qlast_arrow_position)))
13358 Fput (var, Qlast_arrow_position, Qt);
13359 Fput (var, Qlast_arrow_string, Qt);
13365 /* Return overlay arrow string to display at row.
13366 Return integer (bitmap number) for arrow bitmap in left fringe.
13367 Return nil if no overlay arrow. */
13369 static Lisp_Object
13370 overlay_arrow_at_row (struct it *it, struct glyph_row *row)
13372 Lisp_Object vlist;
13374 for (vlist = Voverlay_arrow_variable_list;
13375 CONSP (vlist);
13376 vlist = XCDR (vlist))
13378 Lisp_Object var = XCAR (vlist);
13379 Lisp_Object val;
13381 if (!SYMBOLP (var))
13382 continue;
13384 val = find_symbol_value (var);
13386 if (MARKERP (val)
13387 && current_buffer == XMARKER (val)->buffer
13388 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
13390 if (FRAME_WINDOW_P (it->f)
13391 /* FIXME: if ROW->reversed_p is set, this should test
13392 the right fringe, not the left one. */
13393 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
13395 #ifdef HAVE_WINDOW_SYSTEM
13396 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
13398 int fringe_bitmap = lookup_fringe_bitmap (val);
13399 if (fringe_bitmap != 0)
13400 return make_number (fringe_bitmap);
13402 #endif
13403 return make_number (-1); /* Use default arrow bitmap. */
13405 return overlay_arrow_string_or_property (var);
13409 return Qnil;
13412 /* Return true if point moved out of or into a composition. Otherwise
13413 return false. PREV_BUF and PREV_PT are the last point buffer and
13414 position. BUF and PT are the current point buffer and position. */
13416 static bool
13417 check_point_in_composition (struct buffer *prev_buf, ptrdiff_t prev_pt,
13418 struct buffer *buf, ptrdiff_t pt)
13420 ptrdiff_t start, end;
13421 Lisp_Object prop;
13422 Lisp_Object buffer;
13424 XSETBUFFER (buffer, buf);
13425 /* Check a composition at the last point if point moved within the
13426 same buffer. */
13427 if (prev_buf == buf)
13429 if (prev_pt == pt)
13430 /* Point didn't move. */
13431 return false;
13433 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
13434 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
13435 && composition_valid_p (start, end, prop)
13436 && start < prev_pt && end > prev_pt)
13437 /* The last point was within the composition. Return true iff
13438 point moved out of the composition. */
13439 return (pt <= start || pt >= end);
13442 /* Check a composition at the current point. */
13443 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
13444 && find_composition (pt, -1, &start, &end, &prop, buffer)
13445 && composition_valid_p (start, end, prop)
13446 && start < pt && end > pt);
13449 /* Reconsider the clip changes of buffer which is displayed in W. */
13451 static void
13452 reconsider_clip_changes (struct window *w)
13454 struct buffer *b = XBUFFER (w->contents);
13456 if (b->clip_changed
13457 && w->window_end_valid
13458 && w->current_matrix->buffer == b
13459 && w->current_matrix->zv == BUF_ZV (b)
13460 && w->current_matrix->begv == BUF_BEGV (b))
13461 b->clip_changed = false;
13463 /* If display wasn't paused, and W is not a tool bar window, see if
13464 point has been moved into or out of a composition. In that case,
13465 set b->clip_changed to force updating the screen. If
13466 b->clip_changed has already been set, skip this check. */
13467 if (!b->clip_changed && w->window_end_valid)
13469 ptrdiff_t pt = (w == XWINDOW (selected_window)
13470 ? PT : marker_position (w->pointm));
13472 if ((w->current_matrix->buffer != b || pt != w->last_point)
13473 && check_point_in_composition (w->current_matrix->buffer,
13474 w->last_point, b, pt))
13475 b->clip_changed = true;
13479 static void
13480 propagate_buffer_redisplay (void)
13481 { /* Resetting b->text->redisplay is problematic!
13482 We can't just reset it in the case that some window that displays
13483 it has not been redisplayed; and such a window can stay
13484 unredisplayed for a long time if it's currently invisible.
13485 But we do want to reset it at the end of redisplay otherwise
13486 its displayed windows will keep being redisplayed over and over
13487 again.
13488 So we copy all b->text->redisplay flags up to their windows here,
13489 such that mark_window_display_accurate can safely reset
13490 b->text->redisplay. */
13491 Lisp_Object ws = window_list ();
13492 for (; CONSP (ws); ws = XCDR (ws))
13494 struct window *thisw = XWINDOW (XCAR (ws));
13495 struct buffer *thisb = XBUFFER (thisw->contents);
13496 if (thisb->text->redisplay)
13497 thisw->redisplay = true;
13501 #define STOP_POLLING \
13502 do { if (! polling_stopped_here) stop_polling (); \
13503 polling_stopped_here = true; } while (false)
13505 #define RESUME_POLLING \
13506 do { if (polling_stopped_here) start_polling (); \
13507 polling_stopped_here = false; } while (false)
13510 /* Perhaps in the future avoid recentering windows if it
13511 is not necessary; currently that causes some problems. */
13513 static void
13514 redisplay_internal (void)
13516 struct window *w = XWINDOW (selected_window);
13517 struct window *sw;
13518 struct frame *fr;
13519 bool pending;
13520 bool must_finish = false, match_p;
13521 struct text_pos tlbufpos, tlendpos;
13522 int number_of_visible_frames;
13523 ptrdiff_t count;
13524 struct frame *sf;
13525 bool polling_stopped_here = false;
13526 Lisp_Object tail, frame;
13528 /* True means redisplay has to consider all windows on all
13529 frames. False, only selected_window is considered. */
13530 bool consider_all_windows_p;
13532 /* True means redisplay has to redisplay the miniwindow. */
13533 bool update_miniwindow_p = false;
13535 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
13537 /* No redisplay if running in batch mode or frame is not yet fully
13538 initialized, or redisplay is explicitly turned off by setting
13539 Vinhibit_redisplay. */
13540 if (FRAME_INITIAL_P (SELECTED_FRAME ())
13541 || !NILP (Vinhibit_redisplay))
13542 return;
13544 /* Don't examine these until after testing Vinhibit_redisplay.
13545 When Emacs is shutting down, perhaps because its connection to
13546 X has dropped, we should not look at them at all. */
13547 fr = XFRAME (w->frame);
13548 sf = SELECTED_FRAME ();
13550 if (!fr->glyphs_initialized_p)
13551 return;
13553 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
13554 if (popup_activated ())
13555 return;
13556 #endif
13558 /* I don't think this happens but let's be paranoid. */
13559 if (redisplaying_p)
13560 return;
13562 /* Record a function that clears redisplaying_p
13563 when we leave this function. */
13564 count = SPECPDL_INDEX ();
13565 record_unwind_protect_void (unwind_redisplay);
13566 redisplaying_p = true;
13567 specbind (Qinhibit_free_realized_faces, Qnil);
13569 /* Record this function, so it appears on the profiler's backtraces. */
13570 record_in_backtrace (Qredisplay_internal_xC_functionx, 0, 0);
13572 FOR_EACH_FRAME (tail, frame)
13573 XFRAME (frame)->already_hscrolled_p = false;
13575 retry:
13576 /* Remember the currently selected window. */
13577 sw = w;
13579 pending = false;
13580 forget_escape_and_glyphless_faces ();
13582 inhibit_free_realized_faces = false;
13584 /* If face_change, init_iterator will free all realized faces, which
13585 includes the faces referenced from current matrices. So, we
13586 can't reuse current matrices in this case. */
13587 if (face_change)
13588 windows_or_buffers_changed = 47;
13590 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
13591 && FRAME_TTY (sf)->previous_frame != sf)
13593 /* Since frames on a single ASCII terminal share the same
13594 display area, displaying a different frame means redisplay
13595 the whole thing. */
13596 SET_FRAME_GARBAGED (sf);
13597 #ifndef DOS_NT
13598 set_tty_color_mode (FRAME_TTY (sf), sf);
13599 #endif
13600 FRAME_TTY (sf)->previous_frame = sf;
13603 /* Set the visible flags for all frames. Do this before checking for
13604 resized or garbaged frames; they want to know if their frames are
13605 visible. See the comment in frame.h for FRAME_SAMPLE_VISIBILITY. */
13606 number_of_visible_frames = 0;
13608 FOR_EACH_FRAME (tail, frame)
13610 struct frame *f = XFRAME (frame);
13612 if (FRAME_VISIBLE_P (f))
13614 ++number_of_visible_frames;
13615 /* Adjust matrices for visible frames only. */
13616 if (f->fonts_changed)
13618 adjust_frame_glyphs (f);
13619 /* Disable all redisplay optimizations for this frame.
13620 This is because adjust_frame_glyphs resets the
13621 enabled_p flag for all glyph rows of all windows, so
13622 many optimizations will fail anyway, and some might
13623 fail to test that flag and do bogus things as
13624 result. */
13625 SET_FRAME_GARBAGED (f);
13626 f->fonts_changed = false;
13628 /* If cursor type has been changed on the frame
13629 other than selected, consider all frames. */
13630 if (f != sf && f->cursor_type_changed)
13631 fset_redisplay (f);
13633 clear_desired_matrices (f);
13636 /* Notice any pending interrupt request to change frame size. */
13637 do_pending_window_change (true);
13639 /* do_pending_window_change could change the selected_window due to
13640 frame resizing which makes the selected window too small. */
13641 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
13642 sw = w;
13644 /* Clear frames marked as garbaged. */
13645 clear_garbaged_frames ();
13647 /* Build menubar and tool-bar items. */
13648 if (NILP (Vmemory_full))
13649 prepare_menu_bars ();
13651 reconsider_clip_changes (w);
13653 /* In most cases selected window displays current buffer. */
13654 match_p = XBUFFER (w->contents) == current_buffer;
13655 if (match_p)
13657 /* Detect case that we need to write or remove a star in the mode line. */
13658 if ((SAVE_MODIFF < MODIFF) != w->last_had_star)
13659 w->update_mode_line = true;
13661 if (mode_line_update_needed (w))
13662 w->update_mode_line = true;
13664 /* If reconsider_clip_changes above decided that the narrowing
13665 in the current buffer changed, make sure all other windows
13666 showing that buffer will be redisplayed. */
13667 if (current_buffer->clip_changed)
13668 bset_update_mode_line (current_buffer);
13671 /* Normally the message* functions will have already displayed and
13672 updated the echo area, but the frame may have been trashed, or
13673 the update may have been preempted, so display the echo area
13674 again here. Checking message_cleared_p captures the case that
13675 the echo area should be cleared. */
13676 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
13677 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
13678 || (message_cleared_p
13679 && minibuf_level == 0
13680 /* If the mini-window is currently selected, this means the
13681 echo-area doesn't show through. */
13682 && !MINI_WINDOW_P (XWINDOW (selected_window))))
13684 echo_area_display (false);
13686 /* If echo_area_display resizes the mini-window, the redisplay and
13687 window_sizes_changed flags of the selected frame are set, but
13688 it's too late for the hooks in window-size-change-functions,
13689 which have been examined already in prepare_menu_bars. So in
13690 that case we call the hooks here only for the selected frame. */
13691 if (sf->redisplay)
13693 ptrdiff_t count1 = SPECPDL_INDEX ();
13695 record_unwind_save_match_data ();
13696 run_window_size_change_functions (selected_frame);
13697 unbind_to (count1, Qnil);
13700 if (message_cleared_p)
13701 update_miniwindow_p = true;
13703 must_finish = true;
13705 /* If we don't display the current message, don't clear the
13706 message_cleared_p flag, because, if we did, we wouldn't clear
13707 the echo area in the next redisplay which doesn't preserve
13708 the echo area. */
13709 if (!display_last_displayed_message_p)
13710 message_cleared_p = false;
13712 else if (EQ (selected_window, minibuf_window)
13713 && (current_buffer->clip_changed || window_outdated (w))
13714 && resize_mini_window (w, false))
13716 if (sf->redisplay)
13718 ptrdiff_t count1 = SPECPDL_INDEX ();
13720 record_unwind_save_match_data ();
13721 run_window_size_change_functions (selected_frame);
13722 unbind_to (count1, Qnil);
13725 /* Resized active mini-window to fit the size of what it is
13726 showing if its contents might have changed. */
13727 must_finish = true;
13729 /* If window configuration was changed, frames may have been
13730 marked garbaged. Clear them or we will experience
13731 surprises wrt scrolling. */
13732 clear_garbaged_frames ();
13735 if (windows_or_buffers_changed && !update_mode_lines)
13736 /* Code that sets windows_or_buffers_changed doesn't distinguish whether
13737 only the windows's contents needs to be refreshed, or whether the
13738 mode-lines also need a refresh. */
13739 update_mode_lines = (windows_or_buffers_changed == REDISPLAY_SOME
13740 ? REDISPLAY_SOME : 32);
13742 /* If specs for an arrow have changed, do thorough redisplay
13743 to ensure we remove any arrow that should no longer exist. */
13744 if (overlay_arrows_changed_p ())
13745 /* Apparently, this is the only case where we update other windows,
13746 without updating other mode-lines. */
13747 windows_or_buffers_changed = 49;
13749 consider_all_windows_p = (update_mode_lines
13750 || windows_or_buffers_changed);
13752 #define AINC(a,i) \
13754 Lisp_Object entry = Fgethash (make_number (i), a, make_number (0)); \
13755 if (INTEGERP (entry)) \
13756 Fputhash (make_number (i), make_number (1 + XINT (entry)), a); \
13759 AINC (Vredisplay__all_windows_cause, windows_or_buffers_changed);
13760 AINC (Vredisplay__mode_lines_cause, update_mode_lines);
13762 /* Optimize the case that only the line containing the cursor in the
13763 selected window has changed. Variables starting with this_ are
13764 set in display_line and record information about the line
13765 containing the cursor. */
13766 tlbufpos = this_line_start_pos;
13767 tlendpos = this_line_end_pos;
13768 if (!consider_all_windows_p
13769 && CHARPOS (tlbufpos) > 0
13770 && !w->update_mode_line
13771 && !current_buffer->clip_changed
13772 && !current_buffer->prevent_redisplay_optimizations_p
13773 && FRAME_VISIBLE_P (XFRAME (w->frame))
13774 && !FRAME_OBSCURED_P (XFRAME (w->frame))
13775 && !XFRAME (w->frame)->cursor_type_changed
13776 && !XFRAME (w->frame)->face_change
13777 /* Make sure recorded data applies to current buffer, etc. */
13778 && this_line_buffer == current_buffer
13779 && match_p
13780 && !w->force_start
13781 && !w->optional_new_start
13782 /* Point must be on the line that we have info recorded about. */
13783 && PT >= CHARPOS (tlbufpos)
13784 && PT <= Z - CHARPOS (tlendpos)
13785 /* All text outside that line, including its final newline,
13786 must be unchanged. */
13787 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
13788 CHARPOS (tlendpos)))
13790 if (CHARPOS (tlbufpos) > BEGV
13791 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
13792 && (CHARPOS (tlbufpos) == ZV
13793 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
13794 /* Former continuation line has disappeared by becoming empty. */
13795 goto cancel;
13796 else if (window_outdated (w) || MINI_WINDOW_P (w))
13798 /* We have to handle the case of continuation around a
13799 wide-column character (see the comment in indent.c around
13800 line 1340).
13802 For instance, in the following case:
13804 -------- Insert --------
13805 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
13806 J_I_ ==> J_I_ `^^' are cursors.
13807 ^^ ^^
13808 -------- --------
13810 As we have to redraw the line above, we cannot use this
13811 optimization. */
13813 struct it it;
13814 int line_height_before = this_line_pixel_height;
13816 /* Note that start_display will handle the case that the
13817 line starting at tlbufpos is a continuation line. */
13818 start_display (&it, w, tlbufpos);
13820 /* Implementation note: It this still necessary? */
13821 if (it.current_x != this_line_start_x)
13822 goto cancel;
13824 TRACE ((stderr, "trying display optimization 1\n"));
13825 w->cursor.vpos = -1;
13826 overlay_arrow_seen = false;
13827 it.vpos = this_line_vpos;
13828 it.current_y = this_line_y;
13829 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
13830 display_line (&it);
13832 /* If line contains point, is not continued,
13833 and ends at same distance from eob as before, we win. */
13834 if (w->cursor.vpos >= 0
13835 /* Line is not continued, otherwise this_line_start_pos
13836 would have been set to 0 in display_line. */
13837 && CHARPOS (this_line_start_pos)
13838 /* Line ends as before. */
13839 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
13840 /* Line has same height as before. Otherwise other lines
13841 would have to be shifted up or down. */
13842 && this_line_pixel_height == line_height_before)
13844 /* If this is not the window's last line, we must adjust
13845 the charstarts of the lines below. */
13846 if (it.current_y < it.last_visible_y)
13848 struct glyph_row *row
13849 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
13850 ptrdiff_t delta, delta_bytes;
13852 /* We used to distinguish between two cases here,
13853 conditioned by Z - CHARPOS (tlendpos) == ZV, for
13854 when the line ends in a newline or the end of the
13855 buffer's accessible portion. But both cases did
13856 the same, so they were collapsed. */
13857 delta = (Z
13858 - CHARPOS (tlendpos)
13859 - MATRIX_ROW_START_CHARPOS (row));
13860 delta_bytes = (Z_BYTE
13861 - BYTEPOS (tlendpos)
13862 - MATRIX_ROW_START_BYTEPOS (row));
13864 increment_matrix_positions (w->current_matrix,
13865 this_line_vpos + 1,
13866 w->current_matrix->nrows,
13867 delta, delta_bytes);
13870 /* If this row displays text now but previously didn't,
13871 or vice versa, w->window_end_vpos may have to be
13872 adjusted. */
13873 if (MATRIX_ROW_DISPLAYS_TEXT_P (it.glyph_row - 1))
13875 if (w->window_end_vpos < this_line_vpos)
13876 w->window_end_vpos = this_line_vpos;
13878 else if (w->window_end_vpos == this_line_vpos
13879 && this_line_vpos > 0)
13880 w->window_end_vpos = this_line_vpos - 1;
13881 w->window_end_valid = false;
13883 /* Update hint: No need to try to scroll in update_window. */
13884 w->desired_matrix->no_scrolling_p = true;
13886 #ifdef GLYPH_DEBUG
13887 *w->desired_matrix->method = 0;
13888 debug_method_add (w, "optimization 1");
13889 #endif
13890 #ifdef HAVE_WINDOW_SYSTEM
13891 update_window_fringes (w, false);
13892 #endif
13893 goto update;
13895 else
13896 goto cancel;
13898 else if (/* Cursor position hasn't changed. */
13899 PT == w->last_point
13900 /* Make sure the cursor was last displayed
13901 in this window. Otherwise we have to reposition it. */
13903 /* PXW: Must be converted to pixels, probably. */
13904 && 0 <= w->cursor.vpos
13905 && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
13907 if (!must_finish)
13909 do_pending_window_change (true);
13910 /* If selected_window changed, redisplay again. */
13911 if (WINDOWP (selected_window)
13912 && (w = XWINDOW (selected_window)) != sw)
13913 goto retry;
13915 /* We used to always goto end_of_redisplay here, but this
13916 isn't enough if we have a blinking cursor. */
13917 if (w->cursor_off_p == w->last_cursor_off_p)
13918 goto end_of_redisplay;
13920 goto update;
13922 /* If highlighting the region, or if the cursor is in the echo area,
13923 then we can't just move the cursor. */
13924 else if (NILP (Vshow_trailing_whitespace)
13925 && !cursor_in_echo_area)
13927 struct it it;
13928 struct glyph_row *row;
13930 /* Skip from tlbufpos to PT and see where it is. Note that
13931 PT may be in invisible text. If so, we will end at the
13932 next visible position. */
13933 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
13934 NULL, DEFAULT_FACE_ID);
13935 it.current_x = this_line_start_x;
13936 it.current_y = this_line_y;
13937 it.vpos = this_line_vpos;
13939 /* The call to move_it_to stops in front of PT, but
13940 moves over before-strings. */
13941 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
13943 if (it.vpos == this_line_vpos
13944 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
13945 row->enabled_p))
13947 eassert (this_line_vpos == it.vpos);
13948 eassert (this_line_y == it.current_y);
13949 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13950 if (cursor_row_fully_visible_p (w, false, true))
13952 #ifdef GLYPH_DEBUG
13953 *w->desired_matrix->method = 0;
13954 debug_method_add (w, "optimization 3");
13955 #endif
13956 goto update;
13958 else
13959 goto cancel;
13961 else
13962 goto cancel;
13965 cancel:
13966 /* Text changed drastically or point moved off of line. */
13967 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, false);
13970 CHARPOS (this_line_start_pos) = 0;
13971 ++clear_face_cache_count;
13972 #ifdef HAVE_WINDOW_SYSTEM
13973 ++clear_image_cache_count;
13974 #endif
13976 /* Build desired matrices, and update the display. If
13977 consider_all_windows_p, do it for all windows on all frames that
13978 require redisplay, as specified by their 'redisplay' flag.
13979 Otherwise do it for selected_window, only. */
13981 if (consider_all_windows_p)
13983 FOR_EACH_FRAME (tail, frame)
13984 XFRAME (frame)->updated_p = false;
13986 propagate_buffer_redisplay ();
13988 FOR_EACH_FRAME (tail, frame)
13990 struct frame *f = XFRAME (frame);
13992 /* We don't have to do anything for unselected terminal
13993 frames. */
13994 if ((FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
13995 && !EQ (FRAME_TTY (f)->top_frame, frame))
13996 continue;
13998 retry_frame:
13999 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
14001 bool gcscrollbars
14002 /* Only GC scrollbars when we redisplay the whole frame. */
14003 = f->redisplay || !REDISPLAY_SOME_P ();
14004 bool f_redisplay_flag = f->redisplay;
14005 /* Mark all the scroll bars to be removed; we'll redeem
14006 the ones we want when we redisplay their windows. */
14007 if (gcscrollbars && FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
14008 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
14010 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
14011 redisplay_windows (FRAME_ROOT_WINDOW (f));
14012 /* Remember that the invisible frames need to be redisplayed next
14013 time they're visible. */
14014 else if (!REDISPLAY_SOME_P ())
14015 f->redisplay = true;
14017 /* The X error handler may have deleted that frame. */
14018 if (!FRAME_LIVE_P (f))
14019 continue;
14021 /* Any scroll bars which redisplay_windows should have
14022 nuked should now go away. */
14023 if (gcscrollbars && FRAME_TERMINAL (f)->judge_scroll_bars_hook)
14024 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
14026 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
14028 /* If fonts changed on visible frame, display again. */
14029 if (f->fonts_changed)
14031 adjust_frame_glyphs (f);
14032 /* Disable all redisplay optimizations for this
14033 frame. For the reasons, see the comment near
14034 the previous call to adjust_frame_glyphs above. */
14035 SET_FRAME_GARBAGED (f);
14036 f->fonts_changed = false;
14037 goto retry_frame;
14040 /* See if we have to hscroll. */
14041 if (!f->already_hscrolled_p)
14043 f->already_hscrolled_p = true;
14044 if (hscroll_windows (f->root_window))
14045 goto retry_frame;
14048 /* If the frame's redisplay flag was not set before
14049 we went about redisplaying its windows, but it is
14050 set now, that means we employed some redisplay
14051 optimizations inside redisplay_windows, and
14052 bypassed producing some screen lines. But if
14053 f->redisplay is now set, it might mean the old
14054 faces are no longer valid (e.g., if redisplaying
14055 some window called some Lisp which defined a new
14056 face or redefined an existing face), so trying to
14057 use them in update_frame will segfault.
14058 Therefore, we must redisplay this frame. */
14059 if (!f_redisplay_flag && f->redisplay)
14060 goto retry_frame;
14062 /* Prevent various kinds of signals during display
14063 update. stdio is not robust about handling
14064 signals, which can cause an apparent I/O error. */
14065 if (interrupt_input)
14066 unrequest_sigio ();
14067 STOP_POLLING;
14069 pending |= update_frame (f, false, false);
14070 f->cursor_type_changed = false;
14071 f->updated_p = true;
14076 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
14078 if (!pending)
14080 /* Do the mark_window_display_accurate after all windows have
14081 been redisplayed because this call resets flags in buffers
14082 which are needed for proper redisplay. */
14083 FOR_EACH_FRAME (tail, frame)
14085 struct frame *f = XFRAME (frame);
14086 if (f->updated_p)
14088 f->redisplay = false;
14089 mark_window_display_accurate (f->root_window, true);
14090 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
14091 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
14096 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
14098 displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents);
14099 /* Use list_of_error, not Qerror, so that
14100 we catch only errors and don't run the debugger. */
14101 internal_condition_case_1 (redisplay_window_1, selected_window,
14102 list_of_error,
14103 redisplay_window_error);
14104 if (update_miniwindow_p)
14105 internal_condition_case_1 (redisplay_window_1,
14106 FRAME_MINIBUF_WINDOW (sf), list_of_error,
14107 redisplay_window_error);
14109 /* Compare desired and current matrices, perform output. */
14111 update:
14112 /* If fonts changed, display again. Likewise if redisplay_window_1
14113 above caused some change (e.g., a change in faces) that requires
14114 considering the entire frame again. */
14115 if (sf->fonts_changed || sf->redisplay)
14117 if (sf->redisplay)
14119 /* Set this to force a more thorough redisplay.
14120 Otherwise, we might immediately loop back to the
14121 above "else-if" clause (since all the conditions that
14122 led here might still be true), and we will then
14123 infloop, because the selected-frame's redisplay flag
14124 is not (and cannot be) reset. */
14125 windows_or_buffers_changed = 50;
14127 goto retry;
14130 /* Prevent freeing of realized faces, since desired matrices are
14131 pending that reference the faces we computed and cached. */
14132 inhibit_free_realized_faces = true;
14134 /* Prevent various kinds of signals during display update.
14135 stdio is not robust about handling signals,
14136 which can cause an apparent I/O error. */
14137 if (interrupt_input)
14138 unrequest_sigio ();
14139 STOP_POLLING;
14141 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
14143 if (hscroll_windows (selected_window))
14144 goto retry;
14146 XWINDOW (selected_window)->must_be_updated_p = true;
14147 pending = update_frame (sf, false, false);
14148 sf->cursor_type_changed = false;
14151 /* We may have called echo_area_display at the top of this
14152 function. If the echo area is on another frame, that may
14153 have put text on a frame other than the selected one, so the
14154 above call to update_frame would not have caught it. Catch
14155 it here. */
14156 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
14157 struct frame *mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
14159 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
14161 XWINDOW (mini_window)->must_be_updated_p = true;
14162 pending |= update_frame (mini_frame, false, false);
14163 mini_frame->cursor_type_changed = false;
14164 if (!pending && hscroll_windows (mini_window))
14165 goto retry;
14169 /* If display was paused because of pending input, make sure we do a
14170 thorough update the next time. */
14171 if (pending)
14173 /* Prevent the optimization at the beginning of
14174 redisplay_internal that tries a single-line update of the
14175 line containing the cursor in the selected window. */
14176 CHARPOS (this_line_start_pos) = 0;
14178 /* Let the overlay arrow be updated the next time. */
14179 update_overlay_arrows (0);
14181 /* If we pause after scrolling, some rows in the current
14182 matrices of some windows are not valid. */
14183 if (!WINDOW_FULL_WIDTH_P (w)
14184 && !FRAME_WINDOW_P (XFRAME (w->frame)))
14185 update_mode_lines = 36;
14187 else
14189 if (!consider_all_windows_p)
14191 /* This has already been done above if
14192 consider_all_windows_p is set. */
14193 if (XBUFFER (w->contents)->text->redisplay
14194 && buffer_window_count (XBUFFER (w->contents)) > 1)
14195 /* This can happen if b->text->redisplay was set during
14196 jit-lock. */
14197 propagate_buffer_redisplay ();
14198 mark_window_display_accurate_1 (w, true);
14200 /* Say overlay arrows are up to date. */
14201 update_overlay_arrows (1);
14203 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
14204 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
14207 update_mode_lines = 0;
14208 windows_or_buffers_changed = 0;
14211 /* Start SIGIO interrupts coming again. Having them off during the
14212 code above makes it less likely one will discard output, but not
14213 impossible, since there might be stuff in the system buffer here.
14214 But it is much hairier to try to do anything about that. */
14215 if (interrupt_input)
14216 request_sigio ();
14217 RESUME_POLLING;
14219 /* If a frame has become visible which was not before, redisplay
14220 again, so that we display it. Expose events for such a frame
14221 (which it gets when becoming visible) don't call the parts of
14222 redisplay constructing glyphs, so simply exposing a frame won't
14223 display anything in this case. So, we have to display these
14224 frames here explicitly. */
14225 if (!pending)
14227 int new_count = 0;
14229 FOR_EACH_FRAME (tail, frame)
14231 if (XFRAME (frame)->visible)
14232 new_count++;
14235 if (new_count != number_of_visible_frames)
14236 windows_or_buffers_changed = 52;
14239 /* Change frame size now if a change is pending. */
14240 do_pending_window_change (true);
14242 /* If we just did a pending size change, or have additional
14243 visible frames, or selected_window changed, redisplay again. */
14244 if ((windows_or_buffers_changed && !pending)
14245 || (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw))
14246 goto retry;
14248 /* Clear the face and image caches.
14250 We used to do this only if consider_all_windows_p. But the cache
14251 needs to be cleared if a timer creates images in the current
14252 buffer (e.g. the test case in Bug#6230). */
14254 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
14256 clear_face_cache (false);
14257 clear_face_cache_count = 0;
14260 #ifdef HAVE_WINDOW_SYSTEM
14261 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
14263 clear_image_caches (Qnil);
14264 clear_image_cache_count = 0;
14266 #endif /* HAVE_WINDOW_SYSTEM */
14268 end_of_redisplay:
14269 #ifdef HAVE_NS
14270 ns_set_doc_edited ();
14271 #endif
14272 if (interrupt_input && interrupts_deferred)
14273 request_sigio ();
14275 unbind_to (count, Qnil);
14276 RESUME_POLLING;
14280 /* Redisplay, but leave alone any recent echo area message unless
14281 another message has been requested in its place.
14283 This is useful in situations where you need to redisplay but no
14284 user action has occurred, making it inappropriate for the message
14285 area to be cleared. See tracking_off and
14286 wait_reading_process_output for examples of these situations.
14288 FROM_WHERE is an integer saying from where this function was
14289 called. This is useful for debugging. */
14291 void
14292 redisplay_preserve_echo_area (int from_where)
14294 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
14296 if (!NILP (echo_area_buffer[1]))
14298 /* We have a previously displayed message, but no current
14299 message. Redisplay the previous message. */
14300 display_last_displayed_message_p = true;
14301 redisplay_internal ();
14302 display_last_displayed_message_p = false;
14304 else
14305 redisplay_internal ();
14307 flush_frame (SELECTED_FRAME ());
14311 /* Function registered with record_unwind_protect in redisplay_internal. */
14313 static void
14314 unwind_redisplay (void)
14316 redisplaying_p = false;
14320 /* Mark the display of leaf window W as accurate or inaccurate.
14321 If ACCURATE_P, mark display of W as accurate.
14322 If !ACCURATE_P, arrange for W to be redisplayed the next
14323 time redisplay_internal is called. */
14325 static void
14326 mark_window_display_accurate_1 (struct window *w, bool accurate_p)
14328 struct buffer *b = XBUFFER (w->contents);
14330 w->last_modified = accurate_p ? BUF_MODIFF (b) : 0;
14331 w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF (b) : 0;
14332 w->last_had_star = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
14334 if (accurate_p)
14336 b->clip_changed = false;
14337 b->prevent_redisplay_optimizations_p = false;
14338 eassert (buffer_window_count (b) > 0);
14339 /* Resetting b->text->redisplay is problematic!
14340 In order to make it safer to do it here, redisplay_internal must
14341 have copied all b->text->redisplay to their respective windows. */
14342 b->text->redisplay = false;
14344 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
14345 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
14346 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
14347 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
14349 w->current_matrix->buffer = b;
14350 w->current_matrix->begv = BUF_BEGV (b);
14351 w->current_matrix->zv = BUF_ZV (b);
14353 w->last_cursor_vpos = w->cursor.vpos;
14354 w->last_cursor_off_p = w->cursor_off_p;
14356 if (w == XWINDOW (selected_window))
14357 w->last_point = BUF_PT (b);
14358 else
14359 w->last_point = marker_position (w->pointm);
14361 w->window_end_valid = true;
14362 w->update_mode_line = false;
14365 w->redisplay = !accurate_p;
14369 /* Mark the display of windows in the window tree rooted at WINDOW as
14370 accurate or inaccurate. If ACCURATE_P, mark display of
14371 windows as accurate. If !ACCURATE_P, arrange for windows to
14372 be redisplayed the next time redisplay_internal is called. */
14374 void
14375 mark_window_display_accurate (Lisp_Object window, bool accurate_p)
14377 struct window *w;
14379 for (; !NILP (window); window = w->next)
14381 w = XWINDOW (window);
14382 if (WINDOWP (w->contents))
14383 mark_window_display_accurate (w->contents, accurate_p);
14384 else
14385 mark_window_display_accurate_1 (w, accurate_p);
14388 if (accurate_p)
14389 update_overlay_arrows (1);
14390 else
14391 /* Force a thorough redisplay the next time by setting
14392 last_arrow_position and last_arrow_string to t, which is
14393 unequal to any useful value of Voverlay_arrow_... */
14394 update_overlay_arrows (-1);
14398 /* Return value in display table DP (Lisp_Char_Table *) for character
14399 C. Since a display table doesn't have any parent, we don't have to
14400 follow parent. Do not call this function directly but use the
14401 macro DISP_CHAR_VECTOR. */
14403 Lisp_Object
14404 disp_char_vector (struct Lisp_Char_Table *dp, int c)
14406 Lisp_Object val;
14408 if (ASCII_CHAR_P (c))
14410 val = dp->ascii;
14411 if (SUB_CHAR_TABLE_P (val))
14412 val = XSUB_CHAR_TABLE (val)->contents[c];
14414 else
14416 Lisp_Object table;
14418 XSETCHAR_TABLE (table, dp);
14419 val = char_table_ref (table, c);
14421 if (NILP (val))
14422 val = dp->defalt;
14423 return val;
14428 /***********************************************************************
14429 Window Redisplay
14430 ***********************************************************************/
14432 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
14434 static void
14435 redisplay_windows (Lisp_Object window)
14437 while (!NILP (window))
14439 struct window *w = XWINDOW (window);
14441 if (WINDOWP (w->contents))
14442 redisplay_windows (w->contents);
14443 else if (BUFFERP (w->contents))
14445 displayed_buffer = XBUFFER (w->contents);
14446 /* Use list_of_error, not Qerror, so that
14447 we catch only errors and don't run the debugger. */
14448 internal_condition_case_1 (redisplay_window_0, window,
14449 list_of_error,
14450 redisplay_window_error);
14453 window = w->next;
14457 static Lisp_Object
14458 redisplay_window_error (Lisp_Object ignore)
14460 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
14461 return Qnil;
14464 static Lisp_Object
14465 redisplay_window_0 (Lisp_Object window)
14467 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
14468 redisplay_window (window, false);
14469 return Qnil;
14472 static Lisp_Object
14473 redisplay_window_1 (Lisp_Object window)
14475 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
14476 redisplay_window (window, true);
14477 return Qnil;
14481 /* Set cursor position of W. PT is assumed to be displayed in ROW.
14482 DELTA and DELTA_BYTES are the numbers of characters and bytes by
14483 which positions recorded in ROW differ from current buffer
14484 positions.
14486 Return true iff cursor is on this row. */
14488 static bool
14489 set_cursor_from_row (struct window *w, struct glyph_row *row,
14490 struct glyph_matrix *matrix,
14491 ptrdiff_t delta, ptrdiff_t delta_bytes,
14492 int dy, int dvpos)
14494 struct glyph *glyph = row->glyphs[TEXT_AREA];
14495 struct glyph *end = glyph + row->used[TEXT_AREA];
14496 struct glyph *cursor = NULL;
14497 /* The last known character position in row. */
14498 ptrdiff_t last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
14499 int x = row->x;
14500 ptrdiff_t pt_old = PT - delta;
14501 ptrdiff_t pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
14502 ptrdiff_t pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
14503 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
14504 /* A glyph beyond the edge of TEXT_AREA which we should never
14505 touch. */
14506 struct glyph *glyphs_end = end;
14507 /* True means we've found a match for cursor position, but that
14508 glyph has the avoid_cursor_p flag set. */
14509 bool match_with_avoid_cursor = false;
14510 /* True means we've seen at least one glyph that came from a
14511 display string. */
14512 bool string_seen = false;
14513 /* Largest and smallest buffer positions seen so far during scan of
14514 glyph row. */
14515 ptrdiff_t bpos_max = pos_before;
14516 ptrdiff_t bpos_min = pos_after;
14517 /* Last buffer position covered by an overlay string with an integer
14518 `cursor' property. */
14519 ptrdiff_t bpos_covered = 0;
14520 /* True means the display string on which to display the cursor
14521 comes from a text property, not from an overlay. */
14522 bool string_from_text_prop = false;
14524 /* Don't even try doing anything if called for a mode-line or
14525 header-line row, since the rest of the code isn't prepared to
14526 deal with such calamities. */
14527 eassert (!row->mode_line_p);
14528 if (row->mode_line_p)
14529 return false;
14531 /* Skip over glyphs not having an object at the start and the end of
14532 the row. These are special glyphs like truncation marks on
14533 terminal frames. */
14534 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14536 if (!row->reversed_p)
14538 while (glyph < end
14539 && NILP (glyph->object)
14540 && glyph->charpos < 0)
14542 x += glyph->pixel_width;
14543 ++glyph;
14545 while (end > glyph
14546 && NILP ((end - 1)->object)
14547 /* CHARPOS is zero for blanks and stretch glyphs
14548 inserted by extend_face_to_end_of_line. */
14549 && (end - 1)->charpos <= 0)
14550 --end;
14551 glyph_before = glyph - 1;
14552 glyph_after = end;
14554 else
14556 struct glyph *g;
14558 /* If the glyph row is reversed, we need to process it from back
14559 to front, so swap the edge pointers. */
14560 glyphs_end = end = glyph - 1;
14561 glyph += row->used[TEXT_AREA] - 1;
14563 while (glyph > end + 1
14564 && NILP (glyph->object)
14565 && glyph->charpos < 0)
14567 --glyph;
14568 x -= glyph->pixel_width;
14570 if (NILP (glyph->object) && glyph->charpos < 0)
14571 --glyph;
14572 /* By default, in reversed rows we put the cursor on the
14573 rightmost (first in the reading order) glyph. */
14574 for (g = end + 1; g < glyph; g++)
14575 x += g->pixel_width;
14576 while (end < glyph
14577 && NILP ((end + 1)->object)
14578 && (end + 1)->charpos <= 0)
14579 ++end;
14580 glyph_before = glyph + 1;
14581 glyph_after = end;
14584 else if (row->reversed_p)
14586 /* In R2L rows that don't display text, put the cursor on the
14587 rightmost glyph. Case in point: an empty last line that is
14588 part of an R2L paragraph. */
14589 cursor = end - 1;
14590 /* Avoid placing the cursor on the last glyph of the row, where
14591 on terminal frames we hold the vertical border between
14592 adjacent windows. */
14593 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
14594 && !WINDOW_RIGHTMOST_P (w)
14595 && cursor == row->glyphs[LAST_AREA] - 1)
14596 cursor--;
14597 x = -1; /* will be computed below, at label compute_x */
14600 /* Step 1: Try to find the glyph whose character position
14601 corresponds to point. If that's not possible, find 2 glyphs
14602 whose character positions are the closest to point, one before
14603 point, the other after it. */
14604 if (!row->reversed_p)
14605 while (/* not marched to end of glyph row */
14606 glyph < end
14607 /* glyph was not inserted by redisplay for internal purposes */
14608 && !NILP (glyph->object))
14610 if (BUFFERP (glyph->object))
14612 ptrdiff_t dpos = glyph->charpos - pt_old;
14614 if (glyph->charpos > bpos_max)
14615 bpos_max = glyph->charpos;
14616 if (glyph->charpos < bpos_min)
14617 bpos_min = glyph->charpos;
14618 if (!glyph->avoid_cursor_p)
14620 /* If we hit point, we've found the glyph on which to
14621 display the cursor. */
14622 if (dpos == 0)
14624 match_with_avoid_cursor = false;
14625 break;
14627 /* See if we've found a better approximation to
14628 POS_BEFORE or to POS_AFTER. */
14629 if (0 > dpos && dpos > pos_before - pt_old)
14631 pos_before = glyph->charpos;
14632 glyph_before = glyph;
14634 else if (0 < dpos && dpos < pos_after - pt_old)
14636 pos_after = glyph->charpos;
14637 glyph_after = glyph;
14640 else if (dpos == 0)
14641 match_with_avoid_cursor = true;
14643 else if (STRINGP (glyph->object))
14645 Lisp_Object chprop;
14646 ptrdiff_t glyph_pos = glyph->charpos;
14648 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
14649 glyph->object);
14650 if (!NILP (chprop))
14652 /* If the string came from a `display' text property,
14653 look up the buffer position of that property and
14654 use that position to update bpos_max, as if we
14655 actually saw such a position in one of the row's
14656 glyphs. This helps with supporting integer values
14657 of `cursor' property on the display string in
14658 situations where most or all of the row's buffer
14659 text is completely covered by display properties,
14660 so that no glyph with valid buffer positions is
14661 ever seen in the row. */
14662 ptrdiff_t prop_pos =
14663 string_buffer_position_lim (glyph->object, pos_before,
14664 pos_after, false);
14666 if (prop_pos >= pos_before)
14667 bpos_max = prop_pos;
14669 if (INTEGERP (chprop))
14671 bpos_covered = bpos_max + XINT (chprop);
14672 /* If the `cursor' property covers buffer positions up
14673 to and including point, we should display cursor on
14674 this glyph. Note that, if a `cursor' property on one
14675 of the string's characters has an integer value, we
14676 will break out of the loop below _before_ we get to
14677 the position match above. IOW, integer values of
14678 the `cursor' property override the "exact match for
14679 point" strategy of positioning the cursor. */
14680 /* Implementation note: bpos_max == pt_old when, e.g.,
14681 we are in an empty line, where bpos_max is set to
14682 MATRIX_ROW_START_CHARPOS, see above. */
14683 if (bpos_max <= pt_old && bpos_covered >= pt_old)
14685 cursor = glyph;
14686 break;
14690 string_seen = true;
14692 x += glyph->pixel_width;
14693 ++glyph;
14695 else if (glyph > end) /* row is reversed */
14696 while (!NILP (glyph->object))
14698 if (BUFFERP (glyph->object))
14700 ptrdiff_t dpos = glyph->charpos - pt_old;
14702 if (glyph->charpos > bpos_max)
14703 bpos_max = glyph->charpos;
14704 if (glyph->charpos < bpos_min)
14705 bpos_min = glyph->charpos;
14706 if (!glyph->avoid_cursor_p)
14708 if (dpos == 0)
14710 match_with_avoid_cursor = false;
14711 break;
14713 if (0 > dpos && dpos > pos_before - pt_old)
14715 pos_before = glyph->charpos;
14716 glyph_before = glyph;
14718 else if (0 < dpos && dpos < pos_after - pt_old)
14720 pos_after = glyph->charpos;
14721 glyph_after = glyph;
14724 else if (dpos == 0)
14725 match_with_avoid_cursor = true;
14727 else if (STRINGP (glyph->object))
14729 Lisp_Object chprop;
14730 ptrdiff_t glyph_pos = glyph->charpos;
14732 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
14733 glyph->object);
14734 if (!NILP (chprop))
14736 ptrdiff_t prop_pos =
14737 string_buffer_position_lim (glyph->object, pos_before,
14738 pos_after, false);
14740 if (prop_pos >= pos_before)
14741 bpos_max = prop_pos;
14743 if (INTEGERP (chprop))
14745 bpos_covered = bpos_max + XINT (chprop);
14746 /* If the `cursor' property covers buffer positions up
14747 to and including point, we should display cursor on
14748 this glyph. */
14749 if (bpos_max <= pt_old && bpos_covered >= pt_old)
14751 cursor = glyph;
14752 break;
14755 string_seen = true;
14757 --glyph;
14758 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
14760 x--; /* can't use any pixel_width */
14761 break;
14763 x -= glyph->pixel_width;
14766 /* Step 2: If we didn't find an exact match for point, we need to
14767 look for a proper place to put the cursor among glyphs between
14768 GLYPH_BEFORE and GLYPH_AFTER. */
14769 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14770 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
14771 && !(bpos_max <= pt_old && pt_old <= bpos_covered))
14773 /* An empty line has a single glyph whose OBJECT is nil and
14774 whose CHARPOS is the position of a newline on that line.
14775 Note that on a TTY, there are more glyphs after that, which
14776 were produced by extend_face_to_end_of_line, but their
14777 CHARPOS is zero or negative. */
14778 bool empty_line_p =
14779 ((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14780 && NILP (glyph->object) && glyph->charpos > 0
14781 /* On a TTY, continued and truncated rows also have a glyph at
14782 their end whose OBJECT is nil and whose CHARPOS is
14783 positive (the continuation and truncation glyphs), but such
14784 rows are obviously not "empty". */
14785 && !(row->continued_p || row->truncated_on_right_p));
14787 if (row->ends_in_ellipsis_p && pos_after == last_pos)
14789 ptrdiff_t ellipsis_pos;
14791 /* Scan back over the ellipsis glyphs. */
14792 if (!row->reversed_p)
14794 ellipsis_pos = (glyph - 1)->charpos;
14795 while (glyph > row->glyphs[TEXT_AREA]
14796 && (glyph - 1)->charpos == ellipsis_pos)
14797 glyph--, x -= glyph->pixel_width;
14798 /* That loop always goes one position too far, including
14799 the glyph before the ellipsis. So scan forward over
14800 that one. */
14801 x += glyph->pixel_width;
14802 glyph++;
14804 else /* row is reversed */
14806 ellipsis_pos = (glyph + 1)->charpos;
14807 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14808 && (glyph + 1)->charpos == ellipsis_pos)
14809 glyph++, x += glyph->pixel_width;
14810 x -= glyph->pixel_width;
14811 glyph--;
14814 else if (match_with_avoid_cursor)
14816 cursor = glyph_after;
14817 x = -1;
14819 else if (string_seen)
14821 int incr = row->reversed_p ? -1 : +1;
14823 /* Need to find the glyph that came out of a string which is
14824 present at point. That glyph is somewhere between
14825 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
14826 positioned between POS_BEFORE and POS_AFTER in the
14827 buffer. */
14828 struct glyph *start, *stop;
14829 ptrdiff_t pos = pos_before;
14831 x = -1;
14833 /* If the row ends in a newline from a display string,
14834 reordering could have moved the glyphs belonging to the
14835 string out of the [GLYPH_BEFORE..GLYPH_AFTER] range. So
14836 in this case we extend the search to the last glyph in
14837 the row that was not inserted by redisplay. */
14838 if (row->ends_in_newline_from_string_p)
14840 glyph_after = end;
14841 pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
14844 /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
14845 correspond to POS_BEFORE and POS_AFTER, respectively. We
14846 need START and STOP in the order that corresponds to the
14847 row's direction as given by its reversed_p flag. If the
14848 directionality of characters between POS_BEFORE and
14849 POS_AFTER is the opposite of the row's base direction,
14850 these characters will have been reordered for display,
14851 and we need to reverse START and STOP. */
14852 if (!row->reversed_p)
14854 start = min (glyph_before, glyph_after);
14855 stop = max (glyph_before, glyph_after);
14857 else
14859 start = max (glyph_before, glyph_after);
14860 stop = min (glyph_before, glyph_after);
14862 for (glyph = start + incr;
14863 row->reversed_p ? glyph > stop : glyph < stop; )
14866 /* Any glyphs that come from the buffer are here because
14867 of bidi reordering. Skip them, and only pay
14868 attention to glyphs that came from some string. */
14869 if (STRINGP (glyph->object))
14871 Lisp_Object str;
14872 ptrdiff_t tem;
14873 /* If the display property covers the newline, we
14874 need to search for it one position farther. */
14875 ptrdiff_t lim = pos_after
14876 + (pos_after == MATRIX_ROW_END_CHARPOS (row) + delta);
14878 string_from_text_prop = false;
14879 str = glyph->object;
14880 tem = string_buffer_position_lim (str, pos, lim, false);
14881 if (tem == 0 /* from overlay */
14882 || pos <= tem)
14884 /* If the string from which this glyph came is
14885 found in the buffer at point, or at position
14886 that is closer to point than pos_after, then
14887 we've found the glyph we've been looking for.
14888 If it comes from an overlay (tem == 0), and
14889 it has the `cursor' property on one of its
14890 glyphs, record that glyph as a candidate for
14891 displaying the cursor. (As in the
14892 unidirectional version, we will display the
14893 cursor on the last candidate we find.) */
14894 if (tem == 0
14895 || tem == pt_old
14896 || (tem - pt_old > 0 && tem < pos_after))
14898 /* The glyphs from this string could have
14899 been reordered. Find the one with the
14900 smallest string position. Or there could
14901 be a character in the string with the
14902 `cursor' property, which means display
14903 cursor on that character's glyph. */
14904 ptrdiff_t strpos = glyph->charpos;
14906 if (tem)
14908 cursor = glyph;
14909 string_from_text_prop = true;
14911 for ( ;
14912 (row->reversed_p ? glyph > stop : glyph < stop)
14913 && EQ (glyph->object, str);
14914 glyph += incr)
14916 Lisp_Object cprop;
14917 ptrdiff_t gpos = glyph->charpos;
14919 cprop = Fget_char_property (make_number (gpos),
14920 Qcursor,
14921 glyph->object);
14922 if (!NILP (cprop))
14924 cursor = glyph;
14925 break;
14927 if (tem && glyph->charpos < strpos)
14929 strpos = glyph->charpos;
14930 cursor = glyph;
14934 if (tem == pt_old
14935 || (tem - pt_old > 0 && tem < pos_after))
14936 goto compute_x;
14938 if (tem)
14939 pos = tem + 1; /* don't find previous instances */
14941 /* This string is not what we want; skip all of the
14942 glyphs that came from it. */
14943 while ((row->reversed_p ? glyph > stop : glyph < stop)
14944 && EQ (glyph->object, str))
14945 glyph += incr;
14947 else
14948 glyph += incr;
14951 /* If we reached the end of the line, and END was from a string,
14952 the cursor is not on this line. */
14953 if (cursor == NULL
14954 && (row->reversed_p ? glyph <= end : glyph >= end)
14955 && (row->reversed_p ? end > glyphs_end : end < glyphs_end)
14956 && STRINGP (end->object)
14957 && row->continued_p)
14958 return false;
14960 /* A truncated row may not include PT among its character positions.
14961 Setting the cursor inside the scroll margin will trigger
14962 recalculation of hscroll in hscroll_window_tree. But if a
14963 display string covers point, defer to the string-handling
14964 code below to figure this out. */
14965 else if (row->truncated_on_left_p && pt_old < bpos_min)
14967 cursor = glyph_before;
14968 x = -1;
14970 else if ((row->truncated_on_right_p && pt_old > bpos_max)
14971 /* Zero-width characters produce no glyphs. */
14972 || (!empty_line_p
14973 && (row->reversed_p
14974 ? glyph_after > glyphs_end
14975 : glyph_after < glyphs_end)))
14977 cursor = glyph_after;
14978 x = -1;
14982 compute_x:
14983 if (cursor != NULL)
14984 glyph = cursor;
14985 else if (glyph == glyphs_end
14986 && pos_before == pos_after
14987 && STRINGP ((row->reversed_p
14988 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14989 : row->glyphs[TEXT_AREA])->object))
14991 /* If all the glyphs of this row came from strings, put the
14992 cursor on the first glyph of the row. This avoids having the
14993 cursor outside of the text area in this very rare and hard
14994 use case. */
14995 glyph =
14996 row->reversed_p
14997 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14998 : row->glyphs[TEXT_AREA];
15000 if (x < 0)
15002 struct glyph *g;
15004 /* Need to compute x that corresponds to GLYPH. */
15005 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
15007 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
15008 emacs_abort ();
15009 x += g->pixel_width;
15013 /* ROW could be part of a continued line, which, under bidi
15014 reordering, might have other rows whose start and end charpos
15015 occlude point. Only set w->cursor if we found a better
15016 approximation to the cursor position than we have from previously
15017 examined candidate rows belonging to the same continued line. */
15018 if (/* We already have a candidate row. */
15019 w->cursor.vpos >= 0
15020 /* That candidate is not the row we are processing. */
15021 && MATRIX_ROW (matrix, w->cursor.vpos) != row
15022 /* Make sure cursor.vpos specifies a row whose start and end
15023 charpos occlude point, and it is valid candidate for being a
15024 cursor-row. This is because some callers of this function
15025 leave cursor.vpos at the row where the cursor was displayed
15026 during the last redisplay cycle. */
15027 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
15028 && pt_old <= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
15029 && cursor_row_p (MATRIX_ROW (matrix, w->cursor.vpos)))
15031 struct glyph *g1
15032 = MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
15034 /* Don't consider glyphs that are outside TEXT_AREA. */
15035 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
15036 return false;
15037 /* Keep the candidate whose buffer position is the closest to
15038 point or has the `cursor' property. */
15039 if (/* Previous candidate is a glyph in TEXT_AREA of that row. */
15040 w->cursor.hpos >= 0
15041 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
15042 && ((BUFFERP (g1->object)
15043 && (g1->charpos == pt_old /* An exact match always wins. */
15044 || (BUFFERP (glyph->object)
15045 && eabs (g1->charpos - pt_old)
15046 < eabs (glyph->charpos - pt_old))))
15047 /* Previous candidate is a glyph from a string that has
15048 a non-nil `cursor' property. */
15049 || (STRINGP (g1->object)
15050 && (!NILP (Fget_char_property (make_number (g1->charpos),
15051 Qcursor, g1->object))
15052 /* Previous candidate is from the same display
15053 string as this one, and the display string
15054 came from a text property. */
15055 || (EQ (g1->object, glyph->object)
15056 && string_from_text_prop)
15057 /* this candidate is from newline and its
15058 position is not an exact match */
15059 || (NILP (glyph->object)
15060 && glyph->charpos != pt_old)))))
15061 return false;
15062 /* If this candidate gives an exact match, use that. */
15063 if (!((BUFFERP (glyph->object) && glyph->charpos == pt_old)
15064 /* If this candidate is a glyph created for the
15065 terminating newline of a line, and point is on that
15066 newline, it wins because it's an exact match. */
15067 || (!row->continued_p
15068 && NILP (glyph->object)
15069 && glyph->charpos == 0
15070 && pt_old == MATRIX_ROW_END_CHARPOS (row) - 1))
15071 /* Otherwise, keep the candidate that comes from a row
15072 spanning less buffer positions. This may win when one or
15073 both candidate positions are on glyphs that came from
15074 display strings, for which we cannot compare buffer
15075 positions. */
15076 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
15077 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
15078 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
15079 return false;
15081 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
15082 w->cursor.x = x;
15083 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
15084 w->cursor.y = row->y + dy;
15086 if (w == XWINDOW (selected_window))
15088 if (!row->continued_p
15089 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
15090 && row->x == 0)
15092 this_line_buffer = XBUFFER (w->contents);
15094 CHARPOS (this_line_start_pos)
15095 = MATRIX_ROW_START_CHARPOS (row) + delta;
15096 BYTEPOS (this_line_start_pos)
15097 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
15099 CHARPOS (this_line_end_pos)
15100 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
15101 BYTEPOS (this_line_end_pos)
15102 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
15104 this_line_y = w->cursor.y;
15105 this_line_pixel_height = row->height;
15106 this_line_vpos = w->cursor.vpos;
15107 this_line_start_x = row->x;
15109 else
15110 CHARPOS (this_line_start_pos) = 0;
15113 return true;
15117 /* Run window scroll functions, if any, for WINDOW with new window
15118 start STARTP. Sets the window start of WINDOW to that position.
15120 We assume that the window's buffer is really current. */
15122 static struct text_pos
15123 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
15125 struct window *w = XWINDOW (window);
15126 SET_MARKER_FROM_TEXT_POS (w->start, startp);
15128 eassert (current_buffer == XBUFFER (w->contents));
15130 if (!NILP (Vwindow_scroll_functions))
15132 run_hook_with_args_2 (Qwindow_scroll_functions, window,
15133 make_number (CHARPOS (startp)));
15134 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15135 /* In case the hook functions switch buffers. */
15136 set_buffer_internal (XBUFFER (w->contents));
15139 return startp;
15143 /* Make sure the line containing the cursor is fully visible.
15144 A value of true means there is nothing to be done.
15145 (Either the line is fully visible, or it cannot be made so,
15146 or we cannot tell.)
15148 If FORCE_P, return false even if partial visible cursor row
15149 is higher than window.
15151 If CURRENT_MATRIX_P, use the information from the
15152 window's current glyph matrix; otherwise use the desired glyph
15153 matrix.
15155 A value of false means the caller should do scrolling
15156 as if point had gone off the screen. */
15158 static bool
15159 cursor_row_fully_visible_p (struct window *w, bool force_p,
15160 bool current_matrix_p)
15162 struct glyph_matrix *matrix;
15163 struct glyph_row *row;
15164 int window_height;
15166 if (!make_cursor_line_fully_visible_p)
15167 return true;
15169 /* It's not always possible to find the cursor, e.g, when a window
15170 is full of overlay strings. Don't do anything in that case. */
15171 if (w->cursor.vpos < 0)
15172 return true;
15174 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
15175 row = MATRIX_ROW (matrix, w->cursor.vpos);
15177 /* If the cursor row is not partially visible, there's nothing to do. */
15178 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
15179 return true;
15181 /* If the row the cursor is in is taller than the window's height,
15182 it's not clear what to do, so do nothing. */
15183 window_height = window_box_height (w);
15184 if (row->height >= window_height)
15186 if (!force_p || MINI_WINDOW_P (w)
15187 || w->vscroll || w->cursor.vpos == 0)
15188 return true;
15190 return false;
15194 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
15195 means only WINDOW is redisplayed in redisplay_internal.
15196 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
15197 in redisplay_window to bring a partially visible line into view in
15198 the case that only the cursor has moved.
15200 LAST_LINE_MISFIT should be true if we're scrolling because the
15201 last screen line's vertical height extends past the end of the screen.
15203 Value is
15205 1 if scrolling succeeded
15207 0 if scrolling didn't find point.
15209 -1 if new fonts have been loaded so that we must interrupt
15210 redisplay, adjust glyph matrices, and try again. */
15212 enum
15214 SCROLLING_SUCCESS,
15215 SCROLLING_FAILED,
15216 SCROLLING_NEED_LARGER_MATRICES
15219 /* If scroll-conservatively is more than this, never recenter.
15221 If you change this, don't forget to update the doc string of
15222 `scroll-conservatively' and the Emacs manual. */
15223 #define SCROLL_LIMIT 100
15225 static int
15226 try_scrolling (Lisp_Object window, bool just_this_one_p,
15227 ptrdiff_t arg_scroll_conservatively, ptrdiff_t scroll_step,
15228 bool temp_scroll_step, bool last_line_misfit)
15230 struct window *w = XWINDOW (window);
15231 struct frame *f = XFRAME (w->frame);
15232 struct text_pos pos, startp;
15233 struct it it;
15234 int this_scroll_margin, scroll_max, rc, height;
15235 int dy = 0, amount_to_scroll = 0;
15236 bool scroll_down_p = false;
15237 int extra_scroll_margin_lines = last_line_misfit;
15238 Lisp_Object aggressive;
15239 /* We will never try scrolling more than this number of lines. */
15240 int scroll_limit = SCROLL_LIMIT;
15241 int frame_line_height = default_line_pixel_height (w);
15242 int window_total_lines
15243 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
15245 #ifdef GLYPH_DEBUG
15246 debug_method_add (w, "try_scrolling");
15247 #endif
15249 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15251 /* Compute scroll margin height in pixels. We scroll when point is
15252 within this distance from the top or bottom of the window. */
15253 if (scroll_margin > 0)
15254 this_scroll_margin = min (scroll_margin, window_total_lines / 4)
15255 * frame_line_height;
15256 else
15257 this_scroll_margin = 0;
15259 /* Force arg_scroll_conservatively to have a reasonable value, to
15260 avoid scrolling too far away with slow move_it_* functions. Note
15261 that the user can supply scroll-conservatively equal to
15262 `most-positive-fixnum', which can be larger than INT_MAX. */
15263 if (arg_scroll_conservatively > scroll_limit)
15265 arg_scroll_conservatively = scroll_limit + 1;
15266 scroll_max = scroll_limit * frame_line_height;
15268 else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
15269 /* Compute how much we should try to scroll maximally to bring
15270 point into view. */
15271 scroll_max = (max (scroll_step,
15272 max (arg_scroll_conservatively, temp_scroll_step))
15273 * frame_line_height);
15274 else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
15275 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
15276 /* We're trying to scroll because of aggressive scrolling but no
15277 scroll_step is set. Choose an arbitrary one. */
15278 scroll_max = 10 * frame_line_height;
15279 else
15280 scroll_max = 0;
15282 too_near_end:
15284 /* Decide whether to scroll down. */
15285 if (PT > CHARPOS (startp))
15287 int scroll_margin_y;
15289 /* Compute the pixel ypos of the scroll margin, then move IT to
15290 either that ypos or PT, whichever comes first. */
15291 start_display (&it, w, startp);
15292 scroll_margin_y = it.last_visible_y - this_scroll_margin
15293 - frame_line_height * extra_scroll_margin_lines;
15294 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
15295 (MOVE_TO_POS | MOVE_TO_Y));
15297 if (PT > CHARPOS (it.current.pos))
15299 int y0 = line_bottom_y (&it);
15300 /* Compute how many pixels below window bottom to stop searching
15301 for PT. This avoids costly search for PT that is far away if
15302 the user limited scrolling by a small number of lines, but
15303 always finds PT if scroll_conservatively is set to a large
15304 number, such as most-positive-fixnum. */
15305 int slack = max (scroll_max, 10 * frame_line_height);
15306 int y_to_move = it.last_visible_y + slack;
15308 /* Compute the distance from the scroll margin to PT or to
15309 the scroll limit, whichever comes first. This should
15310 include the height of the cursor line, to make that line
15311 fully visible. */
15312 move_it_to (&it, PT, -1, y_to_move,
15313 -1, MOVE_TO_POS | MOVE_TO_Y);
15314 dy = line_bottom_y (&it) - y0;
15316 if (dy > scroll_max)
15317 return SCROLLING_FAILED;
15319 if (dy > 0)
15320 scroll_down_p = true;
15322 else if (PT == IT_CHARPOS (it)
15323 && IT_CHARPOS (it) < ZV
15324 && it.method == GET_FROM_STRING
15325 && arg_scroll_conservatively > scroll_limit
15326 && it.current_x == 0)
15328 enum move_it_result skip;
15329 int y1 = it.current_y;
15330 int vpos;
15332 /* A before-string that includes newlines and is displayed
15333 on the last visible screen line could fail us under
15334 scroll-conservatively > 100, because we will be unable to
15335 position the cursor on that last visible line. Try to
15336 recover by finding the first screen line that has some
15337 glyphs coming from the buffer text. */
15338 do {
15339 skip = move_it_in_display_line_to (&it, ZV, -1, MOVE_TO_POS);
15340 if (skip != MOVE_NEWLINE_OR_CR
15341 || IT_CHARPOS (it) != PT
15342 || it.method == GET_FROM_BUFFER)
15343 break;
15344 vpos = it.vpos;
15345 move_it_to (&it, -1, -1, -1, vpos + 1, MOVE_TO_VPOS);
15346 } while (it.vpos > vpos);
15348 dy = it.current_y - y1;
15350 if (dy > scroll_max)
15351 return SCROLLING_FAILED;
15353 if (dy > 0)
15354 scroll_down_p = true;
15358 if (scroll_down_p)
15360 /* Point is in or below the bottom scroll margin, so move the
15361 window start down. If scrolling conservatively, move it just
15362 enough down to make point visible. If scroll_step is set,
15363 move it down by scroll_step. */
15364 if (arg_scroll_conservatively)
15365 amount_to_scroll
15366 = min (max (dy, frame_line_height),
15367 frame_line_height * arg_scroll_conservatively);
15368 else if (scroll_step || temp_scroll_step)
15369 amount_to_scroll = scroll_max;
15370 else
15372 aggressive = BVAR (current_buffer, scroll_up_aggressively);
15373 height = WINDOW_BOX_TEXT_HEIGHT (w);
15374 if (NUMBERP (aggressive))
15376 double float_amount = XFLOATINT (aggressive) * height;
15377 int aggressive_scroll = float_amount;
15378 if (aggressive_scroll == 0 && float_amount > 0)
15379 aggressive_scroll = 1;
15380 /* Don't let point enter the scroll margin near top of
15381 the window. This could happen if the value of
15382 scroll_up_aggressively is too large and there are
15383 non-zero margins, because scroll_up_aggressively
15384 means put point that fraction of window height
15385 _from_the_bottom_margin_. */
15386 if (aggressive_scroll + 2 * this_scroll_margin > height)
15387 aggressive_scroll = height - 2 * this_scroll_margin;
15388 amount_to_scroll = dy + aggressive_scroll;
15392 if (amount_to_scroll <= 0)
15393 return SCROLLING_FAILED;
15395 start_display (&it, w, startp);
15396 if (arg_scroll_conservatively <= scroll_limit)
15397 move_it_vertically (&it, amount_to_scroll);
15398 else
15400 /* Extra precision for users who set scroll-conservatively
15401 to a large number: make sure the amount we scroll
15402 the window start is never less than amount_to_scroll,
15403 which was computed as distance from window bottom to
15404 point. This matters when lines at window top and lines
15405 below window bottom have different height. */
15406 struct it it1;
15407 void *it1data = NULL;
15408 /* We use a temporary it1 because line_bottom_y can modify
15409 its argument, if it moves one line down; see there. */
15410 int start_y;
15412 SAVE_IT (it1, it, it1data);
15413 start_y = line_bottom_y (&it1);
15414 do {
15415 RESTORE_IT (&it, &it, it1data);
15416 move_it_by_lines (&it, 1);
15417 SAVE_IT (it1, it, it1data);
15418 } while (IT_CHARPOS (it) < ZV
15419 && line_bottom_y (&it1) - start_y < amount_to_scroll);
15420 bidi_unshelve_cache (it1data, true);
15423 /* If STARTP is unchanged, move it down another screen line. */
15424 if (IT_CHARPOS (it) == CHARPOS (startp))
15425 move_it_by_lines (&it, 1);
15426 startp = it.current.pos;
15428 else
15430 struct text_pos scroll_margin_pos = startp;
15431 int y_offset = 0;
15433 /* See if point is inside the scroll margin at the top of the
15434 window. */
15435 if (this_scroll_margin)
15437 int y_start;
15439 start_display (&it, w, startp);
15440 y_start = it.current_y;
15441 move_it_vertically (&it, this_scroll_margin);
15442 scroll_margin_pos = it.current.pos;
15443 /* If we didn't move enough before hitting ZV, request
15444 additional amount of scroll, to move point out of the
15445 scroll margin. */
15446 if (IT_CHARPOS (it) == ZV
15447 && it.current_y - y_start < this_scroll_margin)
15448 y_offset = this_scroll_margin - (it.current_y - y_start);
15451 if (PT < CHARPOS (scroll_margin_pos))
15453 /* Point is in the scroll margin at the top of the window or
15454 above what is displayed in the window. */
15455 int y0, y_to_move;
15457 /* Compute the vertical distance from PT to the scroll
15458 margin position. Move as far as scroll_max allows, or
15459 one screenful, or 10 screen lines, whichever is largest.
15460 Give up if distance is greater than scroll_max or if we
15461 didn't reach the scroll margin position. */
15462 SET_TEXT_POS (pos, PT, PT_BYTE);
15463 start_display (&it, w, pos);
15464 y0 = it.current_y;
15465 y_to_move = max (it.last_visible_y,
15466 max (scroll_max, 10 * frame_line_height));
15467 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
15468 y_to_move, -1,
15469 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15470 dy = it.current_y - y0;
15471 if (dy > scroll_max
15472 || IT_CHARPOS (it) < CHARPOS (scroll_margin_pos))
15473 return SCROLLING_FAILED;
15475 /* Additional scroll for when ZV was too close to point. */
15476 dy += y_offset;
15478 /* Compute new window start. */
15479 start_display (&it, w, startp);
15481 if (arg_scroll_conservatively)
15482 amount_to_scroll = max (dy, frame_line_height
15483 * max (scroll_step, temp_scroll_step));
15484 else if (scroll_step || temp_scroll_step)
15485 amount_to_scroll = scroll_max;
15486 else
15488 aggressive = BVAR (current_buffer, scroll_down_aggressively);
15489 height = WINDOW_BOX_TEXT_HEIGHT (w);
15490 if (NUMBERP (aggressive))
15492 double float_amount = XFLOATINT (aggressive) * height;
15493 int aggressive_scroll = float_amount;
15494 if (aggressive_scroll == 0 && float_amount > 0)
15495 aggressive_scroll = 1;
15496 /* Don't let point enter the scroll margin near
15497 bottom of the window, if the value of
15498 scroll_down_aggressively happens to be too
15499 large. */
15500 if (aggressive_scroll + 2 * this_scroll_margin > height)
15501 aggressive_scroll = height - 2 * this_scroll_margin;
15502 amount_to_scroll = dy + aggressive_scroll;
15506 if (amount_to_scroll <= 0)
15507 return SCROLLING_FAILED;
15509 move_it_vertically_backward (&it, amount_to_scroll);
15510 startp = it.current.pos;
15514 /* Run window scroll functions. */
15515 startp = run_window_scroll_functions (window, startp);
15517 /* Display the window. Give up if new fonts are loaded, or if point
15518 doesn't appear. */
15519 if (!try_window (window, startp, 0))
15520 rc = SCROLLING_NEED_LARGER_MATRICES;
15521 else if (w->cursor.vpos < 0)
15523 clear_glyph_matrix (w->desired_matrix);
15524 rc = SCROLLING_FAILED;
15526 else
15528 /* Maybe forget recorded base line for line number display. */
15529 if (!just_this_one_p
15530 || current_buffer->clip_changed
15531 || BEG_UNCHANGED < CHARPOS (startp))
15532 w->base_line_number = 0;
15534 /* If cursor ends up on a partially visible line,
15535 treat that as being off the bottom of the screen. */
15536 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1,
15537 false)
15538 /* It's possible that the cursor is on the first line of the
15539 buffer, which is partially obscured due to a vscroll
15540 (Bug#7537). In that case, avoid looping forever. */
15541 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
15543 clear_glyph_matrix (w->desired_matrix);
15544 ++extra_scroll_margin_lines;
15545 goto too_near_end;
15547 rc = SCROLLING_SUCCESS;
15550 return rc;
15554 /* Compute a suitable window start for window W if display of W starts
15555 on a continuation line. Value is true if a new window start
15556 was computed.
15558 The new window start will be computed, based on W's width, starting
15559 from the start of the continued line. It is the start of the
15560 screen line with the minimum distance from the old start W->start,
15561 which is still before point (otherwise point will definitely not
15562 be visible in the window). */
15564 static bool
15565 compute_window_start_on_continuation_line (struct window *w)
15567 struct text_pos pos, start_pos, pos_before_pt;
15568 bool window_start_changed_p = false;
15570 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
15572 /* If window start is on a continuation line... Window start may be
15573 < BEGV in case there's invisible text at the start of the
15574 buffer (M-x rmail, for example). */
15575 if (CHARPOS (start_pos) > BEGV
15576 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
15578 struct it it;
15579 struct glyph_row *row;
15581 /* Handle the case that the window start is out of range. */
15582 if (CHARPOS (start_pos) < BEGV)
15583 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
15584 else if (CHARPOS (start_pos) > ZV)
15585 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
15587 /* Find the start of the continued line. This should be fast
15588 because find_newline is fast (newline cache). */
15589 row = w->desired_matrix->rows + WINDOW_WANTS_HEADER_LINE_P (w);
15590 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
15591 row, DEFAULT_FACE_ID);
15592 reseat_at_previous_visible_line_start (&it);
15594 /* If the line start is "too far" away from the window start,
15595 say it takes too much time to compute a new window start.
15596 Also, give up if the line start is after point, as in that
15597 case point will not be visible with any window start we
15598 compute. */
15599 if (IT_CHARPOS (it) <= PT
15600 || (CHARPOS (start_pos) - IT_CHARPOS (it)
15601 /* PXW: Do we need upper bounds here? */
15602 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w)))
15604 int min_distance, distance;
15606 /* Move forward by display lines to find the new window
15607 start. If window width was enlarged, the new start can
15608 be expected to be > the old start. If window width was
15609 decreased, the new window start will be < the old start.
15610 So, we're looking for the display line start with the
15611 minimum distance from the old window start. */
15612 pos_before_pt = pos = it.current.pos;
15613 min_distance = INFINITY;
15614 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
15615 distance < min_distance)
15617 min_distance = distance;
15618 if (CHARPOS (pos) <= PT)
15619 pos_before_pt = pos;
15620 pos = it.current.pos;
15621 if (it.line_wrap == WORD_WRAP)
15623 /* Under WORD_WRAP, move_it_by_lines is likely to
15624 overshoot and stop not at the first, but the
15625 second character from the left margin. So in
15626 that case, we need a more tight control on the X
15627 coordinate of the iterator than move_it_by_lines
15628 promises in its contract. The method is to first
15629 go to the last (rightmost) visible character of a
15630 line, then move to the leftmost character on the
15631 next line in a separate call. */
15632 move_it_to (&it, ZV, it.last_visible_x, it.current_y, -1,
15633 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15634 move_it_to (&it, ZV, 0,
15635 it.current_y + it.max_ascent + it.max_descent, -1,
15636 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15638 else
15639 move_it_by_lines (&it, 1);
15642 /* It makes very little sense to make the new window start
15643 after point, as point won't be visible. If that's what
15644 the loop above finds, fall back on the candidate before
15645 or at point that is closest to the old window start. */
15646 if (CHARPOS (pos) > PT)
15647 pos = pos_before_pt;
15649 /* Set the window start there. */
15650 SET_MARKER_FROM_TEXT_POS (w->start, pos);
15651 window_start_changed_p = true;
15655 return window_start_changed_p;
15659 /* Try cursor movement in case text has not changed in window WINDOW,
15660 with window start STARTP. Value is
15662 CURSOR_MOVEMENT_SUCCESS if successful
15664 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
15666 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
15667 display. *SCROLL_STEP is set to true, under certain circumstances, if
15668 we want to scroll as if scroll-step were set to 1. See the code.
15670 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
15671 which case we have to abort this redisplay, and adjust matrices
15672 first. */
15674 enum
15676 CURSOR_MOVEMENT_SUCCESS,
15677 CURSOR_MOVEMENT_CANNOT_BE_USED,
15678 CURSOR_MOVEMENT_MUST_SCROLL,
15679 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
15682 static int
15683 try_cursor_movement (Lisp_Object window, struct text_pos startp,
15684 bool *scroll_step)
15686 struct window *w = XWINDOW (window);
15687 struct frame *f = XFRAME (w->frame);
15688 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
15690 #ifdef GLYPH_DEBUG
15691 if (inhibit_try_cursor_movement)
15692 return rc;
15693 #endif
15695 /* Previously, there was a check for Lisp integer in the
15696 if-statement below. Now, this field is converted to
15697 ptrdiff_t, thus zero means invalid position in a buffer. */
15698 eassert (w->last_point > 0);
15699 /* Likewise there was a check whether window_end_vpos is nil or larger
15700 than the window. Now window_end_vpos is int and so never nil, but
15701 let's leave eassert to check whether it fits in the window. */
15702 eassert (!w->window_end_valid
15703 || w->window_end_vpos < w->current_matrix->nrows);
15705 /* Handle case where text has not changed, only point, and it has
15706 not moved off the frame. */
15707 if (/* Point may be in this window. */
15708 PT >= CHARPOS (startp)
15709 /* Selective display hasn't changed. */
15710 && !current_buffer->clip_changed
15711 /* Function force-mode-line-update is used to force a thorough
15712 redisplay. It sets either windows_or_buffers_changed or
15713 update_mode_lines. So don't take a shortcut here for these
15714 cases. */
15715 && !update_mode_lines
15716 && !windows_or_buffers_changed
15717 && !f->cursor_type_changed
15718 && NILP (Vshow_trailing_whitespace)
15719 /* This code is not used for mini-buffer for the sake of the case
15720 of redisplaying to replace an echo area message; since in
15721 that case the mini-buffer contents per se are usually
15722 unchanged. This code is of no real use in the mini-buffer
15723 since the handling of this_line_start_pos, etc., in redisplay
15724 handles the same cases. */
15725 && !EQ (window, minibuf_window)
15726 && (FRAME_WINDOW_P (f)
15727 || !overlay_arrow_in_current_buffer_p ()))
15729 int this_scroll_margin, top_scroll_margin;
15730 struct glyph_row *row = NULL;
15731 int frame_line_height = default_line_pixel_height (w);
15732 int window_total_lines
15733 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
15735 #ifdef GLYPH_DEBUG
15736 debug_method_add (w, "cursor movement");
15737 #endif
15739 /* Scroll if point within this distance from the top or bottom
15740 of the window. This is a pixel value. */
15741 if (scroll_margin > 0)
15743 this_scroll_margin = min (scroll_margin, window_total_lines / 4);
15744 this_scroll_margin *= frame_line_height;
15746 else
15747 this_scroll_margin = 0;
15749 top_scroll_margin = this_scroll_margin;
15750 if (WINDOW_WANTS_HEADER_LINE_P (w))
15751 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
15753 /* Start with the row the cursor was displayed during the last
15754 not paused redisplay. Give up if that row is not valid. */
15755 if (w->last_cursor_vpos < 0
15756 || w->last_cursor_vpos >= w->current_matrix->nrows)
15757 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15758 else
15760 row = MATRIX_ROW (w->current_matrix, w->last_cursor_vpos);
15761 if (row->mode_line_p)
15762 ++row;
15763 if (!row->enabled_p)
15764 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15767 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
15769 bool scroll_p = false, must_scroll = false;
15770 int last_y = window_text_bottom_y (w) - this_scroll_margin;
15772 if (PT > w->last_point)
15774 /* Point has moved forward. */
15775 while (MATRIX_ROW_END_CHARPOS (row) < PT
15776 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
15778 eassert (row->enabled_p);
15779 ++row;
15782 /* If the end position of a row equals the start
15783 position of the next row, and PT is at that position,
15784 we would rather display cursor in the next line. */
15785 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15786 && MATRIX_ROW_END_CHARPOS (row) == PT
15787 && row < MATRIX_MODE_LINE_ROW (w->current_matrix)
15788 && MATRIX_ROW_START_CHARPOS (row+1) == PT
15789 && !cursor_row_p (row))
15790 ++row;
15792 /* If within the scroll margin, scroll. Note that
15793 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
15794 the next line would be drawn, and that
15795 this_scroll_margin can be zero. */
15796 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
15797 || PT > MATRIX_ROW_END_CHARPOS (row)
15798 /* Line is completely visible last line in window
15799 and PT is to be set in the next line. */
15800 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
15801 && PT == MATRIX_ROW_END_CHARPOS (row)
15802 && !row->ends_at_zv_p
15803 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
15804 scroll_p = true;
15806 else if (PT < w->last_point)
15808 /* Cursor has to be moved backward. Note that PT >=
15809 CHARPOS (startp) because of the outer if-statement. */
15810 while (!row->mode_line_p
15811 && (MATRIX_ROW_START_CHARPOS (row) > PT
15812 || (MATRIX_ROW_START_CHARPOS (row) == PT
15813 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
15814 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
15815 row > w->current_matrix->rows
15816 && (row-1)->ends_in_newline_from_string_p))))
15817 && (row->y > top_scroll_margin
15818 || CHARPOS (startp) == BEGV))
15820 eassert (row->enabled_p);
15821 --row;
15824 /* Consider the following case: Window starts at BEGV,
15825 there is invisible, intangible text at BEGV, so that
15826 display starts at some point START > BEGV. It can
15827 happen that we are called with PT somewhere between
15828 BEGV and START. Try to handle that case. */
15829 if (row < w->current_matrix->rows
15830 || row->mode_line_p)
15832 row = w->current_matrix->rows;
15833 if (row->mode_line_p)
15834 ++row;
15837 /* Due to newlines in overlay strings, we may have to
15838 skip forward over overlay strings. */
15839 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15840 && MATRIX_ROW_END_CHARPOS (row) == PT
15841 && !cursor_row_p (row))
15842 ++row;
15844 /* If within the scroll margin, scroll. */
15845 if (row->y < top_scroll_margin
15846 && CHARPOS (startp) != BEGV)
15847 scroll_p = true;
15849 else
15851 /* Cursor did not move. So don't scroll even if cursor line
15852 is partially visible, as it was so before. */
15853 rc = CURSOR_MOVEMENT_SUCCESS;
15856 if (PT < MATRIX_ROW_START_CHARPOS (row)
15857 || PT > MATRIX_ROW_END_CHARPOS (row))
15859 /* if PT is not in the glyph row, give up. */
15860 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15861 must_scroll = true;
15863 else if (rc != CURSOR_MOVEMENT_SUCCESS
15864 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
15866 struct glyph_row *row1;
15868 /* If rows are bidi-reordered and point moved, back up
15869 until we find a row that does not belong to a
15870 continuation line. This is because we must consider
15871 all rows of a continued line as candidates for the
15872 new cursor positioning, since row start and end
15873 positions change non-linearly with vertical position
15874 in such rows. */
15875 /* FIXME: Revisit this when glyph ``spilling'' in
15876 continuation lines' rows is implemented for
15877 bidi-reordered rows. */
15878 for (row1 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15879 MATRIX_ROW_CONTINUATION_LINE_P (row);
15880 --row)
15882 /* If we hit the beginning of the displayed portion
15883 without finding the first row of a continued
15884 line, give up. */
15885 if (row <= row1)
15887 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15888 break;
15890 eassert (row->enabled_p);
15893 if (must_scroll)
15895 else if (rc != CURSOR_MOVEMENT_SUCCESS
15896 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
15897 /* Make sure this isn't a header line by any chance, since
15898 then MATRIX_ROW_PARTIALLY_VISIBLE_P might yield true. */
15899 && !row->mode_line_p
15900 && make_cursor_line_fully_visible_p)
15902 if (PT == MATRIX_ROW_END_CHARPOS (row)
15903 && !row->ends_at_zv_p
15904 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
15905 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15906 else if (row->height > window_box_height (w))
15908 /* If we end up in a partially visible line, let's
15909 make it fully visible, except when it's taller
15910 than the window, in which case we can't do much
15911 about it. */
15912 *scroll_step = true;
15913 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15915 else
15917 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15918 if (!cursor_row_fully_visible_p (w, false, true))
15919 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15920 else
15921 rc = CURSOR_MOVEMENT_SUCCESS;
15924 else if (scroll_p)
15925 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15926 else if (rc != CURSOR_MOVEMENT_SUCCESS
15927 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
15929 /* With bidi-reordered rows, there could be more than
15930 one candidate row whose start and end positions
15931 occlude point. We need to let set_cursor_from_row
15932 find the best candidate. */
15933 /* FIXME: Revisit this when glyph ``spilling'' in
15934 continuation lines' rows is implemented for
15935 bidi-reordered rows. */
15936 bool rv = false;
15940 bool at_zv_p = false, exact_match_p = false;
15942 if (MATRIX_ROW_START_CHARPOS (row) <= PT
15943 && PT <= MATRIX_ROW_END_CHARPOS (row)
15944 && cursor_row_p (row))
15945 rv |= set_cursor_from_row (w, row, w->current_matrix,
15946 0, 0, 0, 0);
15947 /* As soon as we've found the exact match for point,
15948 or the first suitable row whose ends_at_zv_p flag
15949 is set, we are done. */
15950 if (rv)
15952 at_zv_p = MATRIX_ROW (w->current_matrix,
15953 w->cursor.vpos)->ends_at_zv_p;
15954 if (!at_zv_p
15955 && w->cursor.hpos >= 0
15956 && w->cursor.hpos < MATRIX_ROW_USED (w->current_matrix,
15957 w->cursor.vpos))
15959 struct glyph_row *candidate =
15960 MATRIX_ROW (w->current_matrix, w->cursor.vpos);
15961 struct glyph *g =
15962 candidate->glyphs[TEXT_AREA] + w->cursor.hpos;
15963 ptrdiff_t endpos = MATRIX_ROW_END_CHARPOS (candidate);
15965 exact_match_p =
15966 (BUFFERP (g->object) && g->charpos == PT)
15967 || (NILP (g->object)
15968 && (g->charpos == PT
15969 || (g->charpos == 0 && endpos - 1 == PT)));
15971 if (at_zv_p || exact_match_p)
15973 rc = CURSOR_MOVEMENT_SUCCESS;
15974 break;
15977 if (MATRIX_ROW_BOTTOM_Y (row) == last_y)
15978 break;
15979 ++row;
15981 while (((MATRIX_ROW_CONTINUATION_LINE_P (row)
15982 || row->continued_p)
15983 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
15984 || (MATRIX_ROW_START_CHARPOS (row) == PT
15985 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
15986 /* If we didn't find any candidate rows, or exited the
15987 loop before all the candidates were examined, signal
15988 to the caller that this method failed. */
15989 if (rc != CURSOR_MOVEMENT_SUCCESS
15990 && !(rv
15991 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
15992 && !row->continued_p))
15993 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15994 else if (rv)
15995 rc = CURSOR_MOVEMENT_SUCCESS;
15997 else
16001 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
16003 rc = CURSOR_MOVEMENT_SUCCESS;
16004 break;
16006 ++row;
16008 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
16009 && MATRIX_ROW_START_CHARPOS (row) == PT
16010 && cursor_row_p (row));
16015 return rc;
16019 void
16020 set_vertical_scroll_bar (struct window *w)
16022 ptrdiff_t start, end, whole;
16024 /* Calculate the start and end positions for the current window.
16025 At some point, it would be nice to choose between scrollbars
16026 which reflect the whole buffer size, with special markers
16027 indicating narrowing, and scrollbars which reflect only the
16028 visible region.
16030 Note that mini-buffers sometimes aren't displaying any text. */
16031 if (!MINI_WINDOW_P (w)
16032 || (w == XWINDOW (minibuf_window)
16033 && NILP (echo_area_buffer[0])))
16035 struct buffer *buf = XBUFFER (w->contents);
16036 whole = BUF_ZV (buf) - BUF_BEGV (buf);
16037 start = marker_position (w->start) - BUF_BEGV (buf);
16038 /* I don't think this is guaranteed to be right. For the
16039 moment, we'll pretend it is. */
16040 end = BUF_Z (buf) - w->window_end_pos - BUF_BEGV (buf);
16042 if (end < start)
16043 end = start;
16044 if (whole < (end - start))
16045 whole = end - start;
16047 else
16048 start = end = whole = 0;
16050 /* Indicate what this scroll bar ought to be displaying now. */
16051 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
16052 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
16053 (w, end - start, whole, start);
16057 void
16058 set_horizontal_scroll_bar (struct window *w)
16060 int start, end, whole, portion;
16062 if (!MINI_WINDOW_P (w)
16063 || (w == XWINDOW (minibuf_window)
16064 && NILP (echo_area_buffer[0])))
16066 struct buffer *b = XBUFFER (w->contents);
16067 struct buffer *old_buffer = NULL;
16068 struct it it;
16069 struct text_pos startp;
16071 if (b != current_buffer)
16073 old_buffer = current_buffer;
16074 set_buffer_internal (b);
16077 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16078 start_display (&it, w, startp);
16079 it.last_visible_x = INT_MAX;
16080 whole = move_it_to (&it, -1, INT_MAX, window_box_height (w), -1,
16081 MOVE_TO_X | MOVE_TO_Y);
16082 /* whole = move_it_to (&it, w->window_end_pos, INT_MAX,
16083 window_box_height (w), -1,
16084 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); */
16086 start = w->hscroll * FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w));
16087 end = start + window_box_width (w, TEXT_AREA);
16088 portion = end - start;
16089 /* After enlarging a horizontally scrolled window such that it
16090 gets at least as wide as the text it contains, make sure that
16091 the thumb doesn't fill the entire scroll bar so we can still
16092 drag it back to see the entire text. */
16093 whole = max (whole, end);
16095 if (it.bidi_p)
16097 Lisp_Object pdir;
16099 pdir = Fcurrent_bidi_paragraph_direction (Qnil);
16100 if (EQ (pdir, Qright_to_left))
16102 start = whole - end;
16103 end = start + portion;
16107 if (old_buffer)
16108 set_buffer_internal (old_buffer);
16110 else
16111 start = end = whole = portion = 0;
16113 w->hscroll_whole = whole;
16115 /* Indicate what this scroll bar ought to be displaying now. */
16116 if (FRAME_TERMINAL (XFRAME (w->frame))->set_horizontal_scroll_bar_hook)
16117 (*FRAME_TERMINAL (XFRAME (w->frame))->set_horizontal_scroll_bar_hook)
16118 (w, portion, whole, start);
16122 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P means only
16123 selected_window is redisplayed.
16125 We can return without actually redisplaying the window if fonts has been
16126 changed on window's frame. In that case, redisplay_internal will retry.
16128 As one of the important parts of redisplaying a window, we need to
16129 decide whether the previous window-start position (stored in the
16130 window's w->start marker position) is still valid, and if it isn't,
16131 recompute it. Some details about that:
16133 . The previous window-start could be in a continuation line, in
16134 which case we need to recompute it when the window width
16135 changes. See compute_window_start_on_continuation_line and its
16136 call below.
16138 . The text that changed since last redisplay could include the
16139 previous window-start position. In that case, we try to salvage
16140 what we can from the current glyph matrix by calling
16141 try_scrolling, which see.
16143 . Some Emacs command could force us to use a specific window-start
16144 position by setting the window's force_start flag, or gently
16145 propose doing that by setting the window's optional_new_start
16146 flag. In these cases, we try using the specified start point if
16147 that succeeds (i.e. the window desired matrix is successfully
16148 recomputed, and point location is within the window). In case
16149 of optional_new_start, we first check if the specified start
16150 position is feasible, i.e. if it will allow point to be
16151 displayed in the window. If using the specified start point
16152 fails, e.g., if new fonts are needed to be loaded, we abort the
16153 redisplay cycle and leave it up to the next cycle to figure out
16154 things.
16156 . Note that the window's force_start flag is sometimes set by
16157 redisplay itself, when it decides that the previous window start
16158 point is fine and should be kept. Search for "goto force_start"
16159 below to see the details. Like the values of window-start
16160 specified outside of redisplay, these internally-deduced values
16161 are tested for feasibility, and ignored if found to be
16162 unfeasible.
16164 . Note that the function try_window, used to completely redisplay
16165 a window, accepts the window's start point as its argument.
16166 This is used several times in the redisplay code to control
16167 where the window start will be, according to user options such
16168 as scroll-conservatively, and also to ensure the screen line
16169 showing point will be fully (as opposed to partially) visible on
16170 display. */
16172 static void
16173 redisplay_window (Lisp_Object window, bool just_this_one_p)
16175 struct window *w = XWINDOW (window);
16176 struct frame *f = XFRAME (w->frame);
16177 struct buffer *buffer = XBUFFER (w->contents);
16178 struct buffer *old = current_buffer;
16179 struct text_pos lpoint, opoint, startp;
16180 bool update_mode_line;
16181 int tem;
16182 struct it it;
16183 /* Record it now because it's overwritten. */
16184 bool current_matrix_up_to_date_p = false;
16185 bool used_current_matrix_p = false;
16186 /* This is less strict than current_matrix_up_to_date_p.
16187 It indicates that the buffer contents and narrowing are unchanged. */
16188 bool buffer_unchanged_p = false;
16189 bool temp_scroll_step = false;
16190 ptrdiff_t count = SPECPDL_INDEX ();
16191 int rc;
16192 int centering_position = -1;
16193 bool last_line_misfit = false;
16194 ptrdiff_t beg_unchanged, end_unchanged;
16195 int frame_line_height;
16196 bool use_desired_matrix;
16197 void *itdata = NULL;
16199 SET_TEXT_POS (lpoint, PT, PT_BYTE);
16200 opoint = lpoint;
16202 #ifdef GLYPH_DEBUG
16203 *w->desired_matrix->method = 0;
16204 #endif
16206 if (!just_this_one_p
16207 && REDISPLAY_SOME_P ()
16208 && !w->redisplay
16209 && !w->update_mode_line
16210 && !f->face_change
16211 && !f->redisplay
16212 && !buffer->text->redisplay
16213 && BUF_PT (buffer) == w->last_point)
16214 return;
16216 /* Make sure that both W's markers are valid. */
16217 eassert (XMARKER (w->start)->buffer == buffer);
16218 eassert (XMARKER (w->pointm)->buffer == buffer);
16220 /* We come here again if we need to run window-text-change-functions
16221 below. */
16222 restart:
16223 reconsider_clip_changes (w);
16224 frame_line_height = default_line_pixel_height (w);
16226 /* Has the mode line to be updated? */
16227 update_mode_line = (w->update_mode_line
16228 || update_mode_lines
16229 || buffer->clip_changed
16230 || buffer->prevent_redisplay_optimizations_p);
16232 if (!just_this_one_p)
16233 /* If `just_this_one_p' is set, we apparently set must_be_updated_p more
16234 cleverly elsewhere. */
16235 w->must_be_updated_p = true;
16237 if (MINI_WINDOW_P (w))
16239 if (w == XWINDOW (echo_area_window)
16240 && !NILP (echo_area_buffer[0]))
16242 if (update_mode_line)
16243 /* We may have to update a tty frame's menu bar or a
16244 tool-bar. Example `M-x C-h C-h C-g'. */
16245 goto finish_menu_bars;
16246 else
16247 /* We've already displayed the echo area glyphs in this window. */
16248 goto finish_scroll_bars;
16250 else if ((w != XWINDOW (minibuf_window)
16251 || minibuf_level == 0)
16252 /* When buffer is nonempty, redisplay window normally. */
16253 && BUF_Z (XBUFFER (w->contents)) == BUF_BEG (XBUFFER (w->contents))
16254 /* Quail displays non-mini buffers in minibuffer window.
16255 In that case, redisplay the window normally. */
16256 && !NILP (Fmemq (w->contents, Vminibuffer_list)))
16258 /* W is a mini-buffer window, but it's not active, so clear
16259 it. */
16260 int yb = window_text_bottom_y (w);
16261 struct glyph_row *row;
16262 int y;
16264 for (y = 0, row = w->desired_matrix->rows;
16265 y < yb;
16266 y += row->height, ++row)
16267 blank_row (w, row, y);
16268 goto finish_scroll_bars;
16271 clear_glyph_matrix (w->desired_matrix);
16274 /* Otherwise set up data on this window; select its buffer and point
16275 value. */
16276 /* Really select the buffer, for the sake of buffer-local
16277 variables. */
16278 set_buffer_internal_1 (XBUFFER (w->contents));
16280 current_matrix_up_to_date_p
16281 = (w->window_end_valid
16282 && !current_buffer->clip_changed
16283 && !current_buffer->prevent_redisplay_optimizations_p
16284 && !window_outdated (w));
16286 /* Run the window-text-change-functions
16287 if it is possible that the text on the screen has changed
16288 (either due to modification of the text, or any other reason). */
16289 if (!current_matrix_up_to_date_p
16290 && !NILP (Vwindow_text_change_functions))
16292 safe_run_hooks (Qwindow_text_change_functions);
16293 goto restart;
16296 beg_unchanged = BEG_UNCHANGED;
16297 end_unchanged = END_UNCHANGED;
16299 SET_TEXT_POS (opoint, PT, PT_BYTE);
16301 specbind (Qinhibit_point_motion_hooks, Qt);
16303 buffer_unchanged_p
16304 = (w->window_end_valid
16305 && !current_buffer->clip_changed
16306 && !window_outdated (w));
16308 /* When windows_or_buffers_changed is non-zero, we can't rely
16309 on the window end being valid, so set it to zero there. */
16310 if (windows_or_buffers_changed)
16312 /* If window starts on a continuation line, maybe adjust the
16313 window start in case the window's width changed. */
16314 if (XMARKER (w->start)->buffer == current_buffer)
16315 compute_window_start_on_continuation_line (w);
16317 w->window_end_valid = false;
16318 /* If so, we also can't rely on current matrix
16319 and should not fool try_cursor_movement below. */
16320 current_matrix_up_to_date_p = false;
16323 /* Some sanity checks. */
16324 CHECK_WINDOW_END (w);
16325 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
16326 emacs_abort ();
16327 if (BYTEPOS (opoint) < CHARPOS (opoint))
16328 emacs_abort ();
16330 if (mode_line_update_needed (w))
16331 update_mode_line = true;
16333 /* Point refers normally to the selected window. For any other
16334 window, set up appropriate value. */
16335 if (!EQ (window, selected_window))
16337 ptrdiff_t new_pt = marker_position (w->pointm);
16338 ptrdiff_t new_pt_byte = marker_byte_position (w->pointm);
16340 if (new_pt < BEGV)
16342 new_pt = BEGV;
16343 new_pt_byte = BEGV_BYTE;
16344 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
16346 else if (new_pt > (ZV - 1))
16348 new_pt = ZV;
16349 new_pt_byte = ZV_BYTE;
16350 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
16353 /* We don't use SET_PT so that the point-motion hooks don't run. */
16354 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
16357 /* If any of the character widths specified in the display table
16358 have changed, invalidate the width run cache. It's true that
16359 this may be a bit late to catch such changes, but the rest of
16360 redisplay goes (non-fatally) haywire when the display table is
16361 changed, so why should we worry about doing any better? */
16362 if (current_buffer->width_run_cache
16363 || (current_buffer->base_buffer
16364 && current_buffer->base_buffer->width_run_cache))
16366 struct Lisp_Char_Table *disptab = buffer_display_table ();
16368 if (! disptab_matches_widthtab
16369 (disptab, XVECTOR (BVAR (current_buffer, width_table))))
16371 struct buffer *buf = current_buffer;
16373 if (buf->base_buffer)
16374 buf = buf->base_buffer;
16375 invalidate_region_cache (buf, buf->width_run_cache, BEG, Z);
16376 recompute_width_table (current_buffer, disptab);
16380 /* If window-start is screwed up, choose a new one. */
16381 if (XMARKER (w->start)->buffer != current_buffer)
16382 goto recenter;
16384 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16386 /* If someone specified a new starting point but did not insist,
16387 check whether it can be used. */
16388 if ((w->optional_new_start || window_frozen_p (w))
16389 && CHARPOS (startp) >= BEGV
16390 && CHARPOS (startp) <= ZV)
16392 ptrdiff_t it_charpos;
16394 w->optional_new_start = false;
16395 start_display (&it, w, startp);
16396 move_it_to (&it, PT, 0, it.last_visible_y, -1,
16397 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
16398 /* Record IT's position now, since line_bottom_y might change
16399 that. */
16400 it_charpos = IT_CHARPOS (it);
16401 /* Make sure we set the force_start flag only if the cursor row
16402 will be fully visible. Otherwise, the code under force_start
16403 label below will try to move point back into view, which is
16404 not what the code which sets optional_new_start wants. */
16405 if ((it.current_y == 0 || line_bottom_y (&it) < it.last_visible_y)
16406 && !w->force_start)
16408 if (it_charpos == PT)
16409 w->force_start = true;
16410 /* IT may overshoot PT if text at PT is invisible. */
16411 else if (it_charpos > PT && CHARPOS (startp) <= PT)
16412 w->force_start = true;
16413 #ifdef GLYPH_DEBUG
16414 if (w->force_start)
16416 if (window_frozen_p (w))
16417 debug_method_add (w, "set force_start from frozen window start");
16418 else
16419 debug_method_add (w, "set force_start from optional_new_start");
16421 #endif
16425 force_start:
16427 /* Handle case where place to start displaying has been specified,
16428 unless the specified location is outside the accessible range. */
16429 if (w->force_start)
16431 /* We set this later on if we have to adjust point. */
16432 int new_vpos = -1;
16434 w->force_start = false;
16435 w->vscroll = 0;
16436 w->window_end_valid = false;
16438 /* Forget any recorded base line for line number display. */
16439 if (!buffer_unchanged_p)
16440 w->base_line_number = 0;
16442 /* Redisplay the mode line. Select the buffer properly for that.
16443 Also, run the hook window-scroll-functions
16444 because we have scrolled. */
16445 /* Note, we do this after clearing force_start because
16446 if there's an error, it is better to forget about force_start
16447 than to get into an infinite loop calling the hook functions
16448 and having them get more errors. */
16449 if (!update_mode_line
16450 || ! NILP (Vwindow_scroll_functions))
16452 update_mode_line = true;
16453 w->update_mode_line = true;
16454 startp = run_window_scroll_functions (window, startp);
16457 if (CHARPOS (startp) < BEGV)
16458 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
16459 else if (CHARPOS (startp) > ZV)
16460 SET_TEXT_POS (startp, ZV, ZV_BYTE);
16462 /* Redisplay, then check if cursor has been set during the
16463 redisplay. Give up if new fonts were loaded. */
16464 /* We used to issue a CHECK_MARGINS argument to try_window here,
16465 but this causes scrolling to fail when point begins inside
16466 the scroll margin (bug#148) -- cyd */
16467 if (!try_window (window, startp, 0))
16469 w->force_start = true;
16470 clear_glyph_matrix (w->desired_matrix);
16471 goto need_larger_matrices;
16474 if (w->cursor.vpos < 0)
16476 /* If point does not appear, try to move point so it does
16477 appear. The desired matrix has been built above, so we
16478 can use it here. First see if point is in invisible
16479 text, and if so, move it to the first visible buffer
16480 position past that. */
16481 struct glyph_row *r = NULL;
16482 Lisp_Object invprop =
16483 get_char_property_and_overlay (make_number (PT), Qinvisible,
16484 Qnil, NULL);
16486 if (TEXT_PROP_MEANS_INVISIBLE (invprop) != 0)
16488 ptrdiff_t alt_pt;
16489 Lisp_Object invprop_end =
16490 Fnext_single_char_property_change (make_number (PT), Qinvisible,
16491 Qnil, Qnil);
16493 if (NATNUMP (invprop_end))
16494 alt_pt = XFASTINT (invprop_end);
16495 else
16496 alt_pt = ZV;
16497 r = row_containing_pos (w, alt_pt, w->desired_matrix->rows,
16498 NULL, 0);
16500 if (r)
16501 new_vpos = MATRIX_ROW_BOTTOM_Y (r);
16502 else /* Give up and just move to the middle of the window. */
16503 new_vpos = window_box_height (w) / 2;
16506 if (!cursor_row_fully_visible_p (w, false, false))
16508 /* Point does appear, but on a line partly visible at end of window.
16509 Move it back to a fully-visible line. */
16510 new_vpos = window_box_height (w);
16511 /* But if window_box_height suggests a Y coordinate that is
16512 not less than we already have, that line will clearly not
16513 be fully visible, so give up and scroll the display.
16514 This can happen when the default face uses a font whose
16515 dimensions are different from the frame's default
16516 font. */
16517 if (new_vpos >= w->cursor.y)
16519 w->cursor.vpos = -1;
16520 clear_glyph_matrix (w->desired_matrix);
16521 goto try_to_scroll;
16524 else if (w->cursor.vpos >= 0)
16526 /* Some people insist on not letting point enter the scroll
16527 margin, even though this part handles windows that didn't
16528 scroll at all. */
16529 int window_total_lines
16530 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
16531 int margin = min (scroll_margin, window_total_lines / 4);
16532 int pixel_margin = margin * frame_line_height;
16533 bool header_line = WINDOW_WANTS_HEADER_LINE_P (w);
16535 /* Note: We add an extra FRAME_LINE_HEIGHT, because the loop
16536 below, which finds the row to move point to, advances by
16537 the Y coordinate of the _next_ row, see the definition of
16538 MATRIX_ROW_BOTTOM_Y. */
16539 if (w->cursor.vpos < margin + header_line)
16541 w->cursor.vpos = -1;
16542 clear_glyph_matrix (w->desired_matrix);
16543 goto try_to_scroll;
16545 else
16547 int window_height = window_box_height (w);
16549 if (header_line)
16550 window_height += CURRENT_HEADER_LINE_HEIGHT (w);
16551 if (w->cursor.y >= window_height - pixel_margin)
16553 w->cursor.vpos = -1;
16554 clear_glyph_matrix (w->desired_matrix);
16555 goto try_to_scroll;
16560 /* If we need to move point for either of the above reasons,
16561 now actually do it. */
16562 if (new_vpos >= 0)
16564 struct glyph_row *row;
16566 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
16567 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
16568 ++row;
16570 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
16571 MATRIX_ROW_START_BYTEPOS (row));
16573 if (w != XWINDOW (selected_window))
16574 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
16575 else if (current_buffer == old)
16576 SET_TEXT_POS (lpoint, PT, PT_BYTE);
16578 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
16580 /* Re-run pre-redisplay-function so it can update the region
16581 according to the new position of point. */
16582 /* Other than the cursor, w's redisplay is done so we can set its
16583 redisplay to false. Also the buffer's redisplay can be set to
16584 false, since propagate_buffer_redisplay should have already
16585 propagated its info to `w' anyway. */
16586 w->redisplay = false;
16587 XBUFFER (w->contents)->text->redisplay = false;
16588 safe__call1 (true, Vpre_redisplay_function, Fcons (window, Qnil));
16590 if (w->redisplay || XBUFFER (w->contents)->text->redisplay)
16592 /* pre-redisplay-function made changes (e.g. move the region)
16593 that require another round of redisplay. */
16594 clear_glyph_matrix (w->desired_matrix);
16595 if (!try_window (window, startp, 0))
16596 goto need_larger_matrices;
16599 if (w->cursor.vpos < 0 || !cursor_row_fully_visible_p (w, false, false))
16601 clear_glyph_matrix (w->desired_matrix);
16602 goto try_to_scroll;
16605 #ifdef GLYPH_DEBUG
16606 debug_method_add (w, "forced window start");
16607 #endif
16608 goto done;
16611 /* Handle case where text has not changed, only point, and it has
16612 not moved off the frame, and we are not retrying after hscroll.
16613 (current_matrix_up_to_date_p is true when retrying.) */
16614 if (current_matrix_up_to_date_p
16615 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
16616 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
16618 switch (rc)
16620 case CURSOR_MOVEMENT_SUCCESS:
16621 used_current_matrix_p = true;
16622 goto done;
16624 case CURSOR_MOVEMENT_MUST_SCROLL:
16625 goto try_to_scroll;
16627 default:
16628 emacs_abort ();
16631 /* If current starting point was originally the beginning of a line
16632 but no longer is, find a new starting point. */
16633 else if (w->start_at_line_beg
16634 && !(CHARPOS (startp) <= BEGV
16635 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
16637 #ifdef GLYPH_DEBUG
16638 debug_method_add (w, "recenter 1");
16639 #endif
16640 goto recenter;
16643 /* Try scrolling with try_window_id. Value is > 0 if update has
16644 been done, it is -1 if we know that the same window start will
16645 not work. It is 0 if unsuccessful for some other reason. */
16646 else if ((tem = try_window_id (w)) != 0)
16648 #ifdef GLYPH_DEBUG
16649 debug_method_add (w, "try_window_id %d", tem);
16650 #endif
16652 if (f->fonts_changed)
16653 goto need_larger_matrices;
16654 if (tem > 0)
16655 goto done;
16657 /* Otherwise try_window_id has returned -1 which means that we
16658 don't want the alternative below this comment to execute. */
16660 else if (CHARPOS (startp) >= BEGV
16661 && CHARPOS (startp) <= ZV
16662 && PT >= CHARPOS (startp)
16663 && (CHARPOS (startp) < ZV
16664 /* Avoid starting at end of buffer. */
16665 || CHARPOS (startp) == BEGV
16666 || !window_outdated (w)))
16668 int d1, d2, d5, d6;
16669 int rtop, rbot;
16671 /* If first window line is a continuation line, and window start
16672 is inside the modified region, but the first change is before
16673 current window start, we must select a new window start.
16675 However, if this is the result of a down-mouse event (e.g. by
16676 extending the mouse-drag-overlay), we don't want to select a
16677 new window start, since that would change the position under
16678 the mouse, resulting in an unwanted mouse-movement rather
16679 than a simple mouse-click. */
16680 if (!w->start_at_line_beg
16681 && NILP (do_mouse_tracking)
16682 && CHARPOS (startp) > BEGV
16683 && CHARPOS (startp) > BEG + beg_unchanged
16684 && CHARPOS (startp) <= Z - end_unchanged
16685 /* Even if w->start_at_line_beg is nil, a new window may
16686 start at a line_beg, since that's how set_buffer_window
16687 sets it. So, we need to check the return value of
16688 compute_window_start_on_continuation_line. (See also
16689 bug#197). */
16690 && XMARKER (w->start)->buffer == current_buffer
16691 && compute_window_start_on_continuation_line (w)
16692 /* It doesn't make sense to force the window start like we
16693 do at label force_start if it is already known that point
16694 will not be fully visible in the resulting window, because
16695 doing so will move point from its correct position
16696 instead of scrolling the window to bring point into view.
16697 See bug#9324. */
16698 && pos_visible_p (w, PT, &d1, &d2, &rtop, &rbot, &d5, &d6)
16699 /* A very tall row could need more than the window height,
16700 in which case we accept that it is partially visible. */
16701 && (rtop != 0) == (rbot != 0))
16703 w->force_start = true;
16704 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16705 #ifdef GLYPH_DEBUG
16706 debug_method_add (w, "recomputed window start in continuation line");
16707 #endif
16708 goto force_start;
16711 #ifdef GLYPH_DEBUG
16712 debug_method_add (w, "same window start");
16713 #endif
16715 /* Try to redisplay starting at same place as before.
16716 If point has not moved off frame, accept the results. */
16717 if (!current_matrix_up_to_date_p
16718 /* Don't use try_window_reusing_current_matrix in this case
16719 because a window scroll function can have changed the
16720 buffer. */
16721 || !NILP (Vwindow_scroll_functions)
16722 || MINI_WINDOW_P (w)
16723 || !(used_current_matrix_p
16724 = try_window_reusing_current_matrix (w)))
16726 IF_DEBUG (debug_method_add (w, "1"));
16727 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
16728 /* -1 means we need to scroll.
16729 0 means we need new matrices, but fonts_changed
16730 is set in that case, so we will detect it below. */
16731 goto try_to_scroll;
16734 if (f->fonts_changed)
16735 goto need_larger_matrices;
16737 if (w->cursor.vpos >= 0)
16739 if (!just_this_one_p
16740 || current_buffer->clip_changed
16741 || BEG_UNCHANGED < CHARPOS (startp))
16742 /* Forget any recorded base line for line number display. */
16743 w->base_line_number = 0;
16745 if (!cursor_row_fully_visible_p (w, true, false))
16747 clear_glyph_matrix (w->desired_matrix);
16748 last_line_misfit = true;
16750 /* Drop through and scroll. */
16751 else
16752 goto done;
16754 else
16755 clear_glyph_matrix (w->desired_matrix);
16758 try_to_scroll:
16760 /* Redisplay the mode line. Select the buffer properly for that. */
16761 if (!update_mode_line)
16763 update_mode_line = true;
16764 w->update_mode_line = true;
16767 /* Try to scroll by specified few lines. */
16768 if ((scroll_conservatively
16769 || emacs_scroll_step
16770 || temp_scroll_step
16771 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
16772 || NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
16773 && CHARPOS (startp) >= BEGV
16774 && CHARPOS (startp) <= ZV)
16776 /* The function returns -1 if new fonts were loaded, 1 if
16777 successful, 0 if not successful. */
16778 int ss = try_scrolling (window, just_this_one_p,
16779 scroll_conservatively,
16780 emacs_scroll_step,
16781 temp_scroll_step, last_line_misfit);
16782 switch (ss)
16784 case SCROLLING_SUCCESS:
16785 goto done;
16787 case SCROLLING_NEED_LARGER_MATRICES:
16788 goto need_larger_matrices;
16790 case SCROLLING_FAILED:
16791 break;
16793 default:
16794 emacs_abort ();
16798 /* Finally, just choose a place to start which positions point
16799 according to user preferences. */
16801 recenter:
16803 #ifdef GLYPH_DEBUG
16804 debug_method_add (w, "recenter");
16805 #endif
16807 /* Forget any previously recorded base line for line number display. */
16808 if (!buffer_unchanged_p)
16809 w->base_line_number = 0;
16811 /* Determine the window start relative to point. */
16812 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
16813 it.current_y = it.last_visible_y;
16814 if (centering_position < 0)
16816 int window_total_lines
16817 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
16818 int margin
16819 = scroll_margin > 0
16820 ? min (scroll_margin, window_total_lines / 4)
16821 : 0;
16822 ptrdiff_t margin_pos = CHARPOS (startp);
16823 Lisp_Object aggressive;
16824 bool scrolling_up;
16826 /* If there is a scroll margin at the top of the window, find
16827 its character position. */
16828 if (margin
16829 /* Cannot call start_display if startp is not in the
16830 accessible region of the buffer. This can happen when we
16831 have just switched to a different buffer and/or changed
16832 its restriction. In that case, startp is initialized to
16833 the character position 1 (BEGV) because we did not yet
16834 have chance to display the buffer even once. */
16835 && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
16837 struct it it1;
16838 void *it1data = NULL;
16840 SAVE_IT (it1, it, it1data);
16841 start_display (&it1, w, startp);
16842 move_it_vertically (&it1, margin * frame_line_height);
16843 margin_pos = IT_CHARPOS (it1);
16844 RESTORE_IT (&it, &it, it1data);
16846 scrolling_up = PT > margin_pos;
16847 aggressive =
16848 scrolling_up
16849 ? BVAR (current_buffer, scroll_up_aggressively)
16850 : BVAR (current_buffer, scroll_down_aggressively);
16852 if (!MINI_WINDOW_P (w)
16853 && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
16855 int pt_offset = 0;
16857 /* Setting scroll-conservatively overrides
16858 scroll-*-aggressively. */
16859 if (!scroll_conservatively && NUMBERP (aggressive))
16861 double float_amount = XFLOATINT (aggressive);
16863 pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
16864 if (pt_offset == 0 && float_amount > 0)
16865 pt_offset = 1;
16866 if (pt_offset && margin > 0)
16867 margin -= 1;
16869 /* Compute how much to move the window start backward from
16870 point so that point will be displayed where the user
16871 wants it. */
16872 if (scrolling_up)
16874 centering_position = it.last_visible_y;
16875 if (pt_offset)
16876 centering_position -= pt_offset;
16877 centering_position -=
16878 (frame_line_height * (1 + margin + last_line_misfit)
16879 + WINDOW_HEADER_LINE_HEIGHT (w));
16880 /* Don't let point enter the scroll margin near top of
16881 the window. */
16882 if (centering_position < margin * frame_line_height)
16883 centering_position = margin * frame_line_height;
16885 else
16886 centering_position = margin * frame_line_height + pt_offset;
16888 else
16889 /* Set the window start half the height of the window backward
16890 from point. */
16891 centering_position = window_box_height (w) / 2;
16893 move_it_vertically_backward (&it, centering_position);
16895 eassert (IT_CHARPOS (it) >= BEGV);
16897 /* The function move_it_vertically_backward may move over more
16898 than the specified y-distance. If it->w is small, e.g. a
16899 mini-buffer window, we may end up in front of the window's
16900 display area. Start displaying at the start of the line
16901 containing PT in this case. */
16902 if (it.current_y <= 0)
16904 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
16905 move_it_vertically_backward (&it, 0);
16906 it.current_y = 0;
16909 it.current_x = it.hpos = 0;
16911 /* Set the window start position here explicitly, to avoid an
16912 infinite loop in case the functions in window-scroll-functions
16913 get errors. */
16914 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
16916 /* Run scroll hooks. */
16917 startp = run_window_scroll_functions (window, it.current.pos);
16919 /* We invoke try_window and try_window_reusing_current_matrix below,
16920 and they manipulate the bidi cache. Save and restore the cache
16921 state of our iterator, so we could continue using it after that. */
16922 itdata = bidi_shelve_cache ();
16924 /* Redisplay the window. */
16925 use_desired_matrix = false;
16926 if (!current_matrix_up_to_date_p
16927 || windows_or_buffers_changed
16928 || f->cursor_type_changed
16929 /* Don't use try_window_reusing_current_matrix in this case
16930 because it can have changed the buffer. */
16931 || !NILP (Vwindow_scroll_functions)
16932 || !just_this_one_p
16933 || MINI_WINDOW_P (w)
16934 || !(used_current_matrix_p
16935 = try_window_reusing_current_matrix (w)))
16936 use_desired_matrix = (try_window (window, startp, 0) == 1);
16938 bidi_unshelve_cache (itdata, false);
16940 /* If new fonts have been loaded (due to fontsets), give up. We
16941 have to start a new redisplay since we need to re-adjust glyph
16942 matrices. */
16943 if (f->fonts_changed)
16944 goto need_larger_matrices;
16946 /* If cursor did not appear assume that the middle of the window is
16947 in the first line of the window. Do it again with the next line.
16948 (Imagine a window of height 100, displaying two lines of height
16949 60. Moving back 50 from it->last_visible_y will end in the first
16950 line.) */
16951 if (w->cursor.vpos < 0)
16953 if (w->window_end_valid && PT >= Z - w->window_end_pos)
16955 clear_glyph_matrix (w->desired_matrix);
16956 move_it_by_lines (&it, 1);
16957 try_window (window, it.current.pos, 0);
16959 else if (PT < IT_CHARPOS (it))
16961 clear_glyph_matrix (w->desired_matrix);
16962 move_it_by_lines (&it, -1);
16963 try_window (window, it.current.pos, 0);
16965 else if (scroll_conservatively > SCROLL_LIMIT
16966 && (it.method == GET_FROM_STRING
16967 || overlay_touches_p (IT_CHARPOS (it)))
16968 && IT_CHARPOS (it) < ZV)
16970 /* If the window starts with a before-string that spans more
16971 than one screen line, using that position to display the
16972 window might fail to bring point into the view, because
16973 start_display will always start by displaying the string,
16974 whereas the code above determines where to set w->start
16975 by the buffer position of the place where it takes screen
16976 coordinates. Try to recover by finding the next screen
16977 line that displays buffer text. */
16978 ptrdiff_t pos0 = IT_CHARPOS (it);
16980 clear_glyph_matrix (w->desired_matrix);
16981 do {
16982 move_it_by_lines (&it, 1);
16983 } while (IT_CHARPOS (it) == pos0);
16984 try_window (window, it.current.pos, 0);
16986 else
16988 /* Not much we can do about it. */
16992 /* Consider the following case: Window starts at BEGV, there is
16993 invisible, intangible text at BEGV, so that display starts at
16994 some point START > BEGV. It can happen that we are called with
16995 PT somewhere between BEGV and START. Try to handle that case,
16996 and similar ones. */
16997 if (w->cursor.vpos < 0)
16999 /* Prefer the desired matrix to the current matrix, if possible,
17000 in the fallback calculations below. This is because using
17001 the current matrix might completely goof, e.g. if its first
17002 row is after point. */
17003 struct glyph_matrix *matrix =
17004 use_desired_matrix ? w->desired_matrix : w->current_matrix;
17005 /* First, try locating the proper glyph row for PT. */
17006 struct glyph_row *row =
17007 row_containing_pos (w, PT, matrix->rows, NULL, 0);
17009 /* Sometimes point is at the beginning of invisible text that is
17010 before the 1st character displayed in the row. In that case,
17011 row_containing_pos fails to find the row, because no glyphs
17012 with appropriate buffer positions are present in the row.
17013 Therefore, we next try to find the row which shows the 1st
17014 position after the invisible text. */
17015 if (!row)
17017 Lisp_Object val =
17018 get_char_property_and_overlay (make_number (PT), Qinvisible,
17019 Qnil, NULL);
17021 if (TEXT_PROP_MEANS_INVISIBLE (val) != 0)
17023 ptrdiff_t alt_pos;
17024 Lisp_Object invis_end =
17025 Fnext_single_char_property_change (make_number (PT), Qinvisible,
17026 Qnil, Qnil);
17028 if (NATNUMP (invis_end))
17029 alt_pos = XFASTINT (invis_end);
17030 else
17031 alt_pos = ZV;
17032 row = row_containing_pos (w, alt_pos, matrix->rows, NULL, 0);
17035 /* Finally, fall back on the first row of the window after the
17036 header line (if any). This is slightly better than not
17037 displaying the cursor at all. */
17038 if (!row)
17040 row = matrix->rows;
17041 if (row->mode_line_p)
17042 ++row;
17044 set_cursor_from_row (w, row, matrix, 0, 0, 0, 0);
17047 if (!cursor_row_fully_visible_p (w, false, false))
17049 /* If vscroll is enabled, disable it and try again. */
17050 if (w->vscroll)
17052 w->vscroll = 0;
17053 clear_glyph_matrix (w->desired_matrix);
17054 goto recenter;
17057 /* Users who set scroll-conservatively to a large number want
17058 point just above/below the scroll margin. If we ended up
17059 with point's row partially visible, move the window start to
17060 make that row fully visible and out of the margin. */
17061 if (scroll_conservatively > SCROLL_LIMIT)
17063 int window_total_lines
17064 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
17065 int margin =
17066 scroll_margin > 0
17067 ? min (scroll_margin, window_total_lines / 4)
17068 : 0;
17069 bool move_down = w->cursor.vpos >= window_total_lines / 2;
17071 move_it_by_lines (&it, move_down ? margin + 1 : -(margin + 1));
17072 clear_glyph_matrix (w->desired_matrix);
17073 if (1 == try_window (window, it.current.pos,
17074 TRY_WINDOW_CHECK_MARGINS))
17075 goto done;
17078 /* If centering point failed to make the whole line visible,
17079 put point at the top instead. That has to make the whole line
17080 visible, if it can be done. */
17081 if (centering_position == 0)
17082 goto done;
17084 clear_glyph_matrix (w->desired_matrix);
17085 centering_position = 0;
17086 goto recenter;
17089 done:
17091 SET_TEXT_POS_FROM_MARKER (startp, w->start);
17092 w->start_at_line_beg = (CHARPOS (startp) == BEGV
17093 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n');
17095 /* Display the mode line, if we must. */
17096 if ((update_mode_line
17097 /* If window not full width, must redo its mode line
17098 if (a) the window to its side is being redone and
17099 (b) we do a frame-based redisplay. This is a consequence
17100 of how inverted lines are drawn in frame-based redisplay. */
17101 || (!just_this_one_p
17102 && !FRAME_WINDOW_P (f)
17103 && !WINDOW_FULL_WIDTH_P (w))
17104 /* Line number to display. */
17105 || w->base_line_pos > 0
17106 /* Column number is displayed and different from the one displayed. */
17107 || (w->column_number_displayed != -1
17108 && (w->column_number_displayed != current_column ())))
17109 /* This means that the window has a mode line. */
17110 && (WINDOW_WANTS_MODELINE_P (w)
17111 || WINDOW_WANTS_HEADER_LINE_P (w)))
17114 display_mode_lines (w);
17116 /* If mode line height has changed, arrange for a thorough
17117 immediate redisplay using the correct mode line height. */
17118 if (WINDOW_WANTS_MODELINE_P (w)
17119 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
17121 f->fonts_changed = true;
17122 w->mode_line_height = -1;
17123 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
17124 = DESIRED_MODE_LINE_HEIGHT (w);
17127 /* If header line height has changed, arrange for a thorough
17128 immediate redisplay using the correct header line height. */
17129 if (WINDOW_WANTS_HEADER_LINE_P (w)
17130 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
17132 f->fonts_changed = true;
17133 w->header_line_height = -1;
17134 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
17135 = DESIRED_HEADER_LINE_HEIGHT (w);
17138 if (f->fonts_changed)
17139 goto need_larger_matrices;
17142 if (!line_number_displayed && w->base_line_pos != -1)
17144 w->base_line_pos = 0;
17145 w->base_line_number = 0;
17148 finish_menu_bars:
17150 /* When we reach a frame's selected window, redo the frame's menu
17151 bar and the frame's title. */
17152 if (update_mode_line
17153 && EQ (FRAME_SELECTED_WINDOW (f), window))
17155 bool redisplay_menu_p;
17157 if (FRAME_WINDOW_P (f))
17159 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
17160 || defined (HAVE_NS) || defined (USE_GTK)
17161 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
17162 #else
17163 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
17164 #endif
17166 else
17167 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
17169 if (redisplay_menu_p)
17170 display_menu_bar (w);
17172 #ifdef HAVE_WINDOW_SYSTEM
17173 if (FRAME_WINDOW_P (f))
17175 #if defined (USE_GTK) || defined (HAVE_NS)
17176 if (FRAME_EXTERNAL_TOOL_BAR (f))
17177 redisplay_tool_bar (f);
17178 #else
17179 if (WINDOWP (f->tool_bar_window)
17180 && (FRAME_TOOL_BAR_LINES (f) > 0
17181 || !NILP (Vauto_resize_tool_bars))
17182 && redisplay_tool_bar (f))
17183 ignore_mouse_drag_p = true;
17184 #endif
17186 x_consider_frame_title (w->frame);
17187 #endif
17190 #ifdef HAVE_WINDOW_SYSTEM
17191 if (FRAME_WINDOW_P (f)
17192 && update_window_fringes (w, (just_this_one_p
17193 || (!used_current_matrix_p && !overlay_arrow_seen)
17194 || w->pseudo_window_p)))
17196 update_begin (f);
17197 block_input ();
17198 if (draw_window_fringes (w, true))
17200 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
17201 x_draw_right_divider (w);
17202 else
17203 x_draw_vertical_border (w);
17205 unblock_input ();
17206 update_end (f);
17209 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
17210 x_draw_bottom_divider (w);
17211 #endif /* HAVE_WINDOW_SYSTEM */
17213 /* We go to this label, with fonts_changed set, if it is
17214 necessary to try again using larger glyph matrices.
17215 We have to redeem the scroll bar even in this case,
17216 because the loop in redisplay_internal expects that. */
17217 need_larger_matrices:
17219 finish_scroll_bars:
17221 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w) || WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
17223 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
17224 /* Set the thumb's position and size. */
17225 set_vertical_scroll_bar (w);
17227 if (WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
17228 /* Set the thumb's position and size. */
17229 set_horizontal_scroll_bar (w);
17231 /* Note that we actually used the scroll bar attached to this
17232 window, so it shouldn't be deleted at the end of redisplay. */
17233 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
17234 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
17237 /* Restore current_buffer and value of point in it. The window
17238 update may have changed the buffer, so first make sure `opoint'
17239 is still valid (Bug#6177). */
17240 if (CHARPOS (opoint) < BEGV)
17241 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
17242 else if (CHARPOS (opoint) > ZV)
17243 TEMP_SET_PT_BOTH (Z, Z_BYTE);
17244 else
17245 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
17247 set_buffer_internal_1 (old);
17248 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
17249 shorter. This can be caused by log truncation in *Messages*. */
17250 if (CHARPOS (lpoint) <= ZV)
17251 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
17253 unbind_to (count, Qnil);
17257 /* Build the complete desired matrix of WINDOW with a window start
17258 buffer position POS.
17260 Value is 1 if successful. It is zero if fonts were loaded during
17261 redisplay which makes re-adjusting glyph matrices necessary, and -1
17262 if point would appear in the scroll margins.
17263 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
17264 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
17265 set in FLAGS.) */
17268 try_window (Lisp_Object window, struct text_pos pos, int flags)
17270 struct window *w = XWINDOW (window);
17271 struct it it;
17272 struct glyph_row *last_text_row = NULL;
17273 struct frame *f = XFRAME (w->frame);
17274 int frame_line_height = default_line_pixel_height (w);
17276 /* Make POS the new window start. */
17277 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
17279 /* Mark cursor position as unknown. No overlay arrow seen. */
17280 w->cursor.vpos = -1;
17281 overlay_arrow_seen = false;
17283 /* Initialize iterator and info to start at POS. */
17284 start_display (&it, w, pos);
17285 it.glyph_row->reversed_p = false;
17287 /* Display all lines of W. */
17288 while (it.current_y < it.last_visible_y)
17290 if (display_line (&it))
17291 last_text_row = it.glyph_row - 1;
17292 if (f->fonts_changed && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
17293 return 0;
17296 /* Don't let the cursor end in the scroll margins. */
17297 if ((flags & TRY_WINDOW_CHECK_MARGINS)
17298 && !MINI_WINDOW_P (w))
17300 int this_scroll_margin;
17301 int window_total_lines
17302 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
17304 if (scroll_margin > 0)
17306 this_scroll_margin = min (scroll_margin, window_total_lines / 4);
17307 this_scroll_margin *= frame_line_height;
17309 else
17310 this_scroll_margin = 0;
17312 if ((w->cursor.y >= 0 /* not vscrolled */
17313 && w->cursor.y < this_scroll_margin
17314 && CHARPOS (pos) > BEGV
17315 && IT_CHARPOS (it) < ZV)
17316 /* rms: considering make_cursor_line_fully_visible_p here
17317 seems to give wrong results. We don't want to recenter
17318 when the last line is partly visible, we want to allow
17319 that case to be handled in the usual way. */
17320 || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
17322 w->cursor.vpos = -1;
17323 clear_glyph_matrix (w->desired_matrix);
17324 return -1;
17328 /* If bottom moved off end of frame, change mode line percentage. */
17329 if (w->window_end_pos <= 0 && Z != IT_CHARPOS (it))
17330 w->update_mode_line = true;
17332 /* Set window_end_pos to the offset of the last character displayed
17333 on the window from the end of current_buffer. Set
17334 window_end_vpos to its row number. */
17335 if (last_text_row)
17337 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
17338 adjust_window_ends (w, last_text_row, false);
17339 eassert
17340 (MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->desired_matrix,
17341 w->window_end_vpos)));
17343 else
17345 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
17346 w->window_end_pos = Z - ZV;
17347 w->window_end_vpos = 0;
17350 /* But that is not valid info until redisplay finishes. */
17351 w->window_end_valid = false;
17352 return 1;
17357 /************************************************************************
17358 Window redisplay reusing current matrix when buffer has not changed
17359 ************************************************************************/
17361 /* Try redisplay of window W showing an unchanged buffer with a
17362 different window start than the last time it was displayed by
17363 reusing its current matrix. Value is true if successful.
17364 W->start is the new window start. */
17366 static bool
17367 try_window_reusing_current_matrix (struct window *w)
17369 struct frame *f = XFRAME (w->frame);
17370 struct glyph_row *bottom_row;
17371 struct it it;
17372 struct run run;
17373 struct text_pos start, new_start;
17374 int nrows_scrolled, i;
17375 struct glyph_row *last_text_row;
17376 struct glyph_row *last_reused_text_row;
17377 struct glyph_row *start_row;
17378 int start_vpos, min_y, max_y;
17380 #ifdef GLYPH_DEBUG
17381 if (inhibit_try_window_reusing)
17382 return false;
17383 #endif
17385 if (/* This function doesn't handle terminal frames. */
17386 !FRAME_WINDOW_P (f)
17387 /* Don't try to reuse the display if windows have been split
17388 or such. */
17389 || windows_or_buffers_changed
17390 || f->cursor_type_changed)
17391 return false;
17393 /* Can't do this if showing trailing whitespace. */
17394 if (!NILP (Vshow_trailing_whitespace))
17395 return false;
17397 /* If top-line visibility has changed, give up. */
17398 if (WINDOW_WANTS_HEADER_LINE_P (w)
17399 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
17400 return false;
17402 /* Give up if old or new display is scrolled vertically. We could
17403 make this function handle this, but right now it doesn't. */
17404 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17405 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
17406 return false;
17408 /* The variable new_start now holds the new window start. The old
17409 start `start' can be determined from the current matrix. */
17410 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
17411 start = start_row->minpos;
17412 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
17414 /* Clear the desired matrix for the display below. */
17415 clear_glyph_matrix (w->desired_matrix);
17417 if (CHARPOS (new_start) <= CHARPOS (start))
17419 /* Don't use this method if the display starts with an ellipsis
17420 displayed for invisible text. It's not easy to handle that case
17421 below, and it's certainly not worth the effort since this is
17422 not a frequent case. */
17423 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
17424 return false;
17426 IF_DEBUG (debug_method_add (w, "twu1"));
17428 /* Display up to a row that can be reused. The variable
17429 last_text_row is set to the last row displayed that displays
17430 text. Note that it.vpos == 0 if or if not there is a
17431 header-line; it's not the same as the MATRIX_ROW_VPOS! */
17432 start_display (&it, w, new_start);
17433 w->cursor.vpos = -1;
17434 last_text_row = last_reused_text_row = NULL;
17436 while (it.current_y < it.last_visible_y && !f->fonts_changed)
17438 /* If we have reached into the characters in the START row,
17439 that means the line boundaries have changed. So we
17440 can't start copying with the row START. Maybe it will
17441 work to start copying with the following row. */
17442 while (IT_CHARPOS (it) > CHARPOS (start))
17444 /* Advance to the next row as the "start". */
17445 start_row++;
17446 start = start_row->minpos;
17447 /* If there are no more rows to try, or just one, give up. */
17448 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
17449 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
17450 || CHARPOS (start) == ZV)
17452 clear_glyph_matrix (w->desired_matrix);
17453 return false;
17456 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
17458 /* If we have reached alignment, we can copy the rest of the
17459 rows. */
17460 if (IT_CHARPOS (it) == CHARPOS (start)
17461 /* Don't accept "alignment" inside a display vector,
17462 since start_row could have started in the middle of
17463 that same display vector (thus their character
17464 positions match), and we have no way of telling if
17465 that is the case. */
17466 && it.current.dpvec_index < 0)
17467 break;
17469 it.glyph_row->reversed_p = false;
17470 if (display_line (&it))
17471 last_text_row = it.glyph_row - 1;
17475 /* A value of current_y < last_visible_y means that we stopped
17476 at the previous window start, which in turn means that we
17477 have at least one reusable row. */
17478 if (it.current_y < it.last_visible_y)
17480 struct glyph_row *row;
17482 /* IT.vpos always starts from 0; it counts text lines. */
17483 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
17485 /* Find PT if not already found in the lines displayed. */
17486 if (w->cursor.vpos < 0)
17488 int dy = it.current_y - start_row->y;
17490 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17491 row = row_containing_pos (w, PT, row, NULL, dy);
17492 if (row)
17493 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
17494 dy, nrows_scrolled);
17495 else
17497 clear_glyph_matrix (w->desired_matrix);
17498 return false;
17502 /* Scroll the display. Do it before the current matrix is
17503 changed. The problem here is that update has not yet
17504 run, i.e. part of the current matrix is not up to date.
17505 scroll_run_hook will clear the cursor, and use the
17506 current matrix to get the height of the row the cursor is
17507 in. */
17508 run.current_y = start_row->y;
17509 run.desired_y = it.current_y;
17510 run.height = it.last_visible_y - it.current_y;
17512 if (run.height > 0 && run.current_y != run.desired_y)
17514 update_begin (f);
17515 FRAME_RIF (f)->update_window_begin_hook (w);
17516 FRAME_RIF (f)->clear_window_mouse_face (w);
17517 FRAME_RIF (f)->scroll_run_hook (w, &run);
17518 FRAME_RIF (f)->update_window_end_hook (w, false, false);
17519 update_end (f);
17522 /* Shift current matrix down by nrows_scrolled lines. */
17523 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
17524 rotate_matrix (w->current_matrix,
17525 start_vpos,
17526 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
17527 nrows_scrolled);
17529 /* Disable lines that must be updated. */
17530 for (i = 0; i < nrows_scrolled; ++i)
17531 (start_row + i)->enabled_p = false;
17533 /* Re-compute Y positions. */
17534 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
17535 max_y = it.last_visible_y;
17536 for (row = start_row + nrows_scrolled;
17537 row < bottom_row;
17538 ++row)
17540 row->y = it.current_y;
17541 row->visible_height = row->height;
17543 if (row->y < min_y)
17544 row->visible_height -= min_y - row->y;
17545 if (row->y + row->height > max_y)
17546 row->visible_height -= row->y + row->height - max_y;
17547 if (row->fringe_bitmap_periodic_p)
17548 row->redraw_fringe_bitmaps_p = true;
17550 it.current_y += row->height;
17552 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
17553 last_reused_text_row = row;
17554 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
17555 break;
17558 /* Disable lines in the current matrix which are now
17559 below the window. */
17560 for (++row; row < bottom_row; ++row)
17561 row->enabled_p = row->mode_line_p = false;
17564 /* Update window_end_pos etc.; last_reused_text_row is the last
17565 reused row from the current matrix containing text, if any.
17566 The value of last_text_row is the last displayed line
17567 containing text. */
17568 if (last_reused_text_row)
17569 adjust_window_ends (w, last_reused_text_row, true);
17570 else if (last_text_row)
17571 adjust_window_ends (w, last_text_row, false);
17572 else
17574 /* This window must be completely empty. */
17575 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
17576 w->window_end_pos = Z - ZV;
17577 w->window_end_vpos = 0;
17579 w->window_end_valid = false;
17581 /* Update hint: don't try scrolling again in update_window. */
17582 w->desired_matrix->no_scrolling_p = true;
17584 #ifdef GLYPH_DEBUG
17585 debug_method_add (w, "try_window_reusing_current_matrix 1");
17586 #endif
17587 return true;
17589 else if (CHARPOS (new_start) > CHARPOS (start))
17591 struct glyph_row *pt_row, *row;
17592 struct glyph_row *first_reusable_row;
17593 struct glyph_row *first_row_to_display;
17594 int dy;
17595 int yb = window_text_bottom_y (w);
17597 /* Find the row starting at new_start, if there is one. Don't
17598 reuse a partially visible line at the end. */
17599 first_reusable_row = start_row;
17600 while (first_reusable_row->enabled_p
17601 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
17602 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
17603 < CHARPOS (new_start)))
17604 ++first_reusable_row;
17606 /* Give up if there is no row to reuse. */
17607 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
17608 || !first_reusable_row->enabled_p
17609 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
17610 != CHARPOS (new_start)))
17611 return false;
17613 /* We can reuse fully visible rows beginning with
17614 first_reusable_row to the end of the window. Set
17615 first_row_to_display to the first row that cannot be reused.
17616 Set pt_row to the row containing point, if there is any. */
17617 pt_row = NULL;
17618 for (first_row_to_display = first_reusable_row;
17619 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
17620 ++first_row_to_display)
17622 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
17623 && (PT < MATRIX_ROW_END_CHARPOS (first_row_to_display)
17624 || (PT == MATRIX_ROW_END_CHARPOS (first_row_to_display)
17625 && first_row_to_display->ends_at_zv_p
17626 && pt_row == NULL)))
17627 pt_row = first_row_to_display;
17630 /* Start displaying at the start of first_row_to_display. */
17631 eassert (first_row_to_display->y < yb);
17632 init_to_row_start (&it, w, first_row_to_display);
17634 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
17635 - start_vpos);
17636 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
17637 - nrows_scrolled);
17638 it.current_y = (first_row_to_display->y - first_reusable_row->y
17639 + WINDOW_HEADER_LINE_HEIGHT (w));
17641 /* Display lines beginning with first_row_to_display in the
17642 desired matrix. Set last_text_row to the last row displayed
17643 that displays text. */
17644 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
17645 if (pt_row == NULL)
17646 w->cursor.vpos = -1;
17647 last_text_row = NULL;
17648 while (it.current_y < it.last_visible_y && !f->fonts_changed)
17649 if (display_line (&it))
17650 last_text_row = it.glyph_row - 1;
17652 /* If point is in a reused row, adjust y and vpos of the cursor
17653 position. */
17654 if (pt_row)
17656 w->cursor.vpos -= nrows_scrolled;
17657 w->cursor.y -= first_reusable_row->y - start_row->y;
17660 /* Give up if point isn't in a row displayed or reused. (This
17661 also handles the case where w->cursor.vpos < nrows_scrolled
17662 after the calls to display_line, which can happen with scroll
17663 margins. See bug#1295.) */
17664 if (w->cursor.vpos < 0)
17666 clear_glyph_matrix (w->desired_matrix);
17667 return false;
17670 /* Scroll the display. */
17671 run.current_y = first_reusable_row->y;
17672 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
17673 run.height = it.last_visible_y - run.current_y;
17674 dy = run.current_y - run.desired_y;
17676 if (run.height)
17678 update_begin (f);
17679 FRAME_RIF (f)->update_window_begin_hook (w);
17680 FRAME_RIF (f)->clear_window_mouse_face (w);
17681 FRAME_RIF (f)->scroll_run_hook (w, &run);
17682 FRAME_RIF (f)->update_window_end_hook (w, false, false);
17683 update_end (f);
17686 /* Adjust Y positions of reused rows. */
17687 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
17688 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
17689 max_y = it.last_visible_y;
17690 for (row = first_reusable_row; row < first_row_to_display; ++row)
17692 row->y -= dy;
17693 row->visible_height = row->height;
17694 if (row->y < min_y)
17695 row->visible_height -= min_y - row->y;
17696 if (row->y + row->height > max_y)
17697 row->visible_height -= row->y + row->height - max_y;
17698 if (row->fringe_bitmap_periodic_p)
17699 row->redraw_fringe_bitmaps_p = true;
17702 /* Scroll the current matrix. */
17703 eassert (nrows_scrolled > 0);
17704 rotate_matrix (w->current_matrix,
17705 start_vpos,
17706 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
17707 -nrows_scrolled);
17709 /* Disable rows not reused. */
17710 for (row -= nrows_scrolled; row < bottom_row; ++row)
17711 row->enabled_p = false;
17713 /* Point may have moved to a different line, so we cannot assume that
17714 the previous cursor position is valid; locate the correct row. */
17715 if (pt_row)
17717 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
17718 row < bottom_row
17719 && PT >= MATRIX_ROW_END_CHARPOS (row)
17720 && !row->ends_at_zv_p;
17721 row++)
17723 w->cursor.vpos++;
17724 w->cursor.y = row->y;
17726 if (row < bottom_row)
17728 /* Can't simply scan the row for point with
17729 bidi-reordered glyph rows. Let set_cursor_from_row
17730 figure out where to put the cursor, and if it fails,
17731 give up. */
17732 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
17734 if (!set_cursor_from_row (w, row, w->current_matrix,
17735 0, 0, 0, 0))
17737 clear_glyph_matrix (w->desired_matrix);
17738 return false;
17741 else
17743 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
17744 struct glyph *end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
17746 for (; glyph < end
17747 && (!BUFFERP (glyph->object)
17748 || glyph->charpos < PT);
17749 glyph++)
17751 w->cursor.hpos++;
17752 w->cursor.x += glyph->pixel_width;
17758 /* Adjust window end. A null value of last_text_row means that
17759 the window end is in reused rows which in turn means that
17760 only its vpos can have changed. */
17761 if (last_text_row)
17762 adjust_window_ends (w, last_text_row, false);
17763 else
17764 w->window_end_vpos -= nrows_scrolled;
17766 w->window_end_valid = false;
17767 w->desired_matrix->no_scrolling_p = true;
17769 #ifdef GLYPH_DEBUG
17770 debug_method_add (w, "try_window_reusing_current_matrix 2");
17771 #endif
17772 return true;
17775 return false;
17780 /************************************************************************
17781 Window redisplay reusing current matrix when buffer has changed
17782 ************************************************************************/
17784 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
17785 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
17786 ptrdiff_t *, ptrdiff_t *);
17787 static struct glyph_row *
17788 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
17789 struct glyph_row *);
17792 /* Return the last row in MATRIX displaying text. If row START is
17793 non-null, start searching with that row. IT gives the dimensions
17794 of the display. Value is null if matrix is empty; otherwise it is
17795 a pointer to the row found. */
17797 static struct glyph_row *
17798 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
17799 struct glyph_row *start)
17801 struct glyph_row *row, *row_found;
17803 /* Set row_found to the last row in IT->w's current matrix
17804 displaying text. The loop looks funny but think of partially
17805 visible lines. */
17806 row_found = NULL;
17807 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
17808 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
17810 eassert (row->enabled_p);
17811 row_found = row;
17812 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
17813 break;
17814 ++row;
17817 return row_found;
17821 /* Return the last row in the current matrix of W that is not affected
17822 by changes at the start of current_buffer that occurred since W's
17823 current matrix was built. Value is null if no such row exists.
17825 BEG_UNCHANGED us the number of characters unchanged at the start of
17826 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
17827 first changed character in current_buffer. Characters at positions <
17828 BEG + BEG_UNCHANGED are at the same buffer positions as they were
17829 when the current matrix was built. */
17831 static struct glyph_row *
17832 find_last_unchanged_at_beg_row (struct window *w)
17834 ptrdiff_t first_changed_pos = BEG + BEG_UNCHANGED;
17835 struct glyph_row *row;
17836 struct glyph_row *row_found = NULL;
17837 int yb = window_text_bottom_y (w);
17839 /* Find the last row displaying unchanged text. */
17840 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17841 MATRIX_ROW_DISPLAYS_TEXT_P (row)
17842 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
17843 ++row)
17845 if (/* If row ends before first_changed_pos, it is unchanged,
17846 except in some case. */
17847 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
17848 /* When row ends in ZV and we write at ZV it is not
17849 unchanged. */
17850 && !row->ends_at_zv_p
17851 /* When first_changed_pos is the end of a continued line,
17852 row is not unchanged because it may be no longer
17853 continued. */
17854 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
17855 && (row->continued_p
17856 || row->exact_window_width_line_p))
17857 /* If ROW->end is beyond ZV, then ROW->end is outdated and
17858 needs to be recomputed, so don't consider this row as
17859 unchanged. This happens when the last line was
17860 bidi-reordered and was killed immediately before this
17861 redisplay cycle. In that case, ROW->end stores the
17862 buffer position of the first visual-order character of
17863 the killed text, which is now beyond ZV. */
17864 && CHARPOS (row->end.pos) <= ZV)
17865 row_found = row;
17867 /* Stop if last visible row. */
17868 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
17869 break;
17872 return row_found;
17876 /* Find the first glyph row in the current matrix of W that is not
17877 affected by changes at the end of current_buffer since the
17878 time W's current matrix was built.
17880 Return in *DELTA the number of chars by which buffer positions in
17881 unchanged text at the end of current_buffer must be adjusted.
17883 Return in *DELTA_BYTES the corresponding number of bytes.
17885 Value is null if no such row exists, i.e. all rows are affected by
17886 changes. */
17888 static struct glyph_row *
17889 find_first_unchanged_at_end_row (struct window *w,
17890 ptrdiff_t *delta, ptrdiff_t *delta_bytes)
17892 struct glyph_row *row;
17893 struct glyph_row *row_found = NULL;
17895 *delta = *delta_bytes = 0;
17897 /* Display must not have been paused, otherwise the current matrix
17898 is not up to date. */
17899 eassert (w->window_end_valid);
17901 /* A value of window_end_pos >= END_UNCHANGED means that the window
17902 end is in the range of changed text. If so, there is no
17903 unchanged row at the end of W's current matrix. */
17904 if (w->window_end_pos >= END_UNCHANGED)
17905 return NULL;
17907 /* Set row to the last row in W's current matrix displaying text. */
17908 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
17910 /* If matrix is entirely empty, no unchanged row exists. */
17911 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
17913 /* The value of row is the last glyph row in the matrix having a
17914 meaningful buffer position in it. The end position of row
17915 corresponds to window_end_pos. This allows us to translate
17916 buffer positions in the current matrix to current buffer
17917 positions for characters not in changed text. */
17918 ptrdiff_t Z_old =
17919 MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
17920 ptrdiff_t Z_BYTE_old =
17921 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
17922 ptrdiff_t last_unchanged_pos, last_unchanged_pos_old;
17923 struct glyph_row *first_text_row
17924 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17926 *delta = Z - Z_old;
17927 *delta_bytes = Z_BYTE - Z_BYTE_old;
17929 /* Set last_unchanged_pos to the buffer position of the last
17930 character in the buffer that has not been changed. Z is the
17931 index + 1 of the last character in current_buffer, i.e. by
17932 subtracting END_UNCHANGED we get the index of the last
17933 unchanged character, and we have to add BEG to get its buffer
17934 position. */
17935 last_unchanged_pos = Z - END_UNCHANGED + BEG;
17936 last_unchanged_pos_old = last_unchanged_pos - *delta;
17938 /* Search backward from ROW for a row displaying a line that
17939 starts at a minimum position >= last_unchanged_pos_old. */
17940 for (; row > first_text_row; --row)
17942 /* This used to abort, but it can happen.
17943 It is ok to just stop the search instead here. KFS. */
17944 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
17945 break;
17947 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
17948 row_found = row;
17952 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
17954 return row_found;
17958 /* Make sure that glyph rows in the current matrix of window W
17959 reference the same glyph memory as corresponding rows in the
17960 frame's frame matrix. This function is called after scrolling W's
17961 current matrix on a terminal frame in try_window_id and
17962 try_window_reusing_current_matrix. */
17964 static void
17965 sync_frame_with_window_matrix_rows (struct window *w)
17967 struct frame *f = XFRAME (w->frame);
17968 struct glyph_row *window_row, *window_row_end, *frame_row;
17970 /* Preconditions: W must be a leaf window and full-width. Its frame
17971 must have a frame matrix. */
17972 eassert (BUFFERP (w->contents));
17973 eassert (WINDOW_FULL_WIDTH_P (w));
17974 eassert (!FRAME_WINDOW_P (f));
17976 /* If W is a full-width window, glyph pointers in W's current matrix
17977 have, by definition, to be the same as glyph pointers in the
17978 corresponding frame matrix. Note that frame matrices have no
17979 marginal areas (see build_frame_matrix). */
17980 window_row = w->current_matrix->rows;
17981 window_row_end = window_row + w->current_matrix->nrows;
17982 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
17983 while (window_row < window_row_end)
17985 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
17986 struct glyph *end = window_row->glyphs[LAST_AREA];
17988 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
17989 frame_row->glyphs[TEXT_AREA] = start;
17990 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
17991 frame_row->glyphs[LAST_AREA] = end;
17993 /* Disable frame rows whose corresponding window rows have
17994 been disabled in try_window_id. */
17995 if (!window_row->enabled_p)
17996 frame_row->enabled_p = false;
17998 ++window_row, ++frame_row;
18003 /* Find the glyph row in window W containing CHARPOS. Consider all
18004 rows between START and END (not inclusive). END null means search
18005 all rows to the end of the display area of W. Value is the row
18006 containing CHARPOS or null. */
18008 struct glyph_row *
18009 row_containing_pos (struct window *w, ptrdiff_t charpos,
18010 struct glyph_row *start, struct glyph_row *end, int dy)
18012 struct glyph_row *row = start;
18013 struct glyph_row *best_row = NULL;
18014 ptrdiff_t mindif = BUF_ZV (XBUFFER (w->contents)) + 1;
18015 int last_y;
18017 /* If we happen to start on a header-line, skip that. */
18018 if (row->mode_line_p)
18019 ++row;
18021 if ((end && row >= end) || !row->enabled_p)
18022 return NULL;
18024 last_y = window_text_bottom_y (w) - dy;
18026 while (true)
18028 /* Give up if we have gone too far. */
18029 if ((end && row >= end) || !row->enabled_p)
18030 return NULL;
18031 /* This formerly returned if they were equal.
18032 I think that both quantities are of a "last plus one" type;
18033 if so, when they are equal, the row is within the screen. -- rms. */
18034 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
18035 return NULL;
18037 /* If it is in this row, return this row. */
18038 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
18039 || (MATRIX_ROW_END_CHARPOS (row) == charpos
18040 /* The end position of a row equals the start
18041 position of the next row. If CHARPOS is there, we
18042 would rather consider it displayed in the next
18043 line, except when this line ends in ZV. */
18044 && !row_for_charpos_p (row, charpos)))
18045 && charpos >= MATRIX_ROW_START_CHARPOS (row))
18047 struct glyph *g;
18049 if (NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
18050 || (!best_row && !row->continued_p))
18051 return row;
18052 /* In bidi-reordered rows, there could be several rows whose
18053 edges surround CHARPOS, all of these rows belonging to
18054 the same continued line. We need to find the row which
18055 fits CHARPOS the best. */
18056 for (g = row->glyphs[TEXT_AREA];
18057 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
18058 g++)
18060 if (!STRINGP (g->object))
18062 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
18064 mindif = eabs (g->charpos - charpos);
18065 best_row = row;
18066 /* Exact match always wins. */
18067 if (mindif == 0)
18068 return best_row;
18073 else if (best_row && !row->continued_p)
18074 return best_row;
18075 ++row;
18080 /* Try to redisplay window W by reusing its existing display. W's
18081 current matrix must be up to date when this function is called,
18082 i.e., window_end_valid must be true.
18084 Value is
18086 >= 1 if successful, i.e. display has been updated
18087 specifically:
18088 1 means the changes were in front of a newline that precedes
18089 the window start, and the whole current matrix was reused
18090 2 means the changes were after the last position displayed
18091 in the window, and the whole current matrix was reused
18092 3 means portions of the current matrix were reused, while
18093 some of the screen lines were redrawn
18094 -1 if redisplay with same window start is known not to succeed
18095 0 if otherwise unsuccessful
18097 The following steps are performed:
18099 1. Find the last row in the current matrix of W that is not
18100 affected by changes at the start of current_buffer. If no such row
18101 is found, give up.
18103 2. Find the first row in W's current matrix that is not affected by
18104 changes at the end of current_buffer. Maybe there is no such row.
18106 3. Display lines beginning with the row + 1 found in step 1 to the
18107 row found in step 2 or, if step 2 didn't find a row, to the end of
18108 the window.
18110 4. If cursor is not known to appear on the window, give up.
18112 5. If display stopped at the row found in step 2, scroll the
18113 display and current matrix as needed.
18115 6. Maybe display some lines at the end of W, if we must. This can
18116 happen under various circumstances, like a partially visible line
18117 becoming fully visible, or because newly displayed lines are displayed
18118 in smaller font sizes.
18120 7. Update W's window end information. */
18122 static int
18123 try_window_id (struct window *w)
18125 struct frame *f = XFRAME (w->frame);
18126 struct glyph_matrix *current_matrix = w->current_matrix;
18127 struct glyph_matrix *desired_matrix = w->desired_matrix;
18128 struct glyph_row *last_unchanged_at_beg_row;
18129 struct glyph_row *first_unchanged_at_end_row;
18130 struct glyph_row *row;
18131 struct glyph_row *bottom_row;
18132 int bottom_vpos;
18133 struct it it;
18134 ptrdiff_t delta = 0, delta_bytes = 0, stop_pos;
18135 int dvpos, dy;
18136 struct text_pos start_pos;
18137 struct run run;
18138 int first_unchanged_at_end_vpos = 0;
18139 struct glyph_row *last_text_row, *last_text_row_at_end;
18140 struct text_pos start;
18141 ptrdiff_t first_changed_charpos, last_changed_charpos;
18143 #ifdef GLYPH_DEBUG
18144 if (inhibit_try_window_id)
18145 return 0;
18146 #endif
18148 /* This is handy for debugging. */
18149 #if false
18150 #define GIVE_UP(X) \
18151 do { \
18152 TRACE ((stderr, "try_window_id give up %d\n", (X))); \
18153 return 0; \
18154 } while (false)
18155 #else
18156 #define GIVE_UP(X) return 0
18157 #endif
18159 SET_TEXT_POS_FROM_MARKER (start, w->start);
18161 /* Don't use this for mini-windows because these can show
18162 messages and mini-buffers, and we don't handle that here. */
18163 if (MINI_WINDOW_P (w))
18164 GIVE_UP (1);
18166 /* This flag is used to prevent redisplay optimizations. */
18167 if (windows_or_buffers_changed || f->cursor_type_changed)
18168 GIVE_UP (2);
18170 /* This function's optimizations cannot be used if overlays have
18171 changed in the buffer displayed by the window, so give up if they
18172 have. */
18173 if (w->last_overlay_modified != OVERLAY_MODIFF)
18174 GIVE_UP (200);
18176 /* Verify that narrowing has not changed.
18177 Also verify that we were not told to prevent redisplay optimizations.
18178 It would be nice to further
18179 reduce the number of cases where this prevents try_window_id. */
18180 if (current_buffer->clip_changed
18181 || current_buffer->prevent_redisplay_optimizations_p)
18182 GIVE_UP (3);
18184 /* Window must either use window-based redisplay or be full width. */
18185 if (!FRAME_WINDOW_P (f)
18186 && (!FRAME_LINE_INS_DEL_OK (f)
18187 || !WINDOW_FULL_WIDTH_P (w)))
18188 GIVE_UP (4);
18190 /* Give up if point is known NOT to appear in W. */
18191 if (PT < CHARPOS (start))
18192 GIVE_UP (5);
18194 /* Another way to prevent redisplay optimizations. */
18195 if (w->last_modified == 0)
18196 GIVE_UP (6);
18198 /* Verify that window is not hscrolled. */
18199 if (w->hscroll != 0)
18200 GIVE_UP (7);
18202 /* Verify that display wasn't paused. */
18203 if (!w->window_end_valid)
18204 GIVE_UP (8);
18206 /* Likewise if highlighting trailing whitespace. */
18207 if (!NILP (Vshow_trailing_whitespace))
18208 GIVE_UP (11);
18210 /* Can't use this if overlay arrow position and/or string have
18211 changed. */
18212 if (overlay_arrows_changed_p ())
18213 GIVE_UP (12);
18215 /* When word-wrap is on, adding a space to the first word of a
18216 wrapped line can change the wrap position, altering the line
18217 above it. It might be worthwhile to handle this more
18218 intelligently, but for now just redisplay from scratch. */
18219 if (!NILP (BVAR (XBUFFER (w->contents), word_wrap)))
18220 GIVE_UP (21);
18222 /* Under bidi reordering, adding or deleting a character in the
18223 beginning of a paragraph, before the first strong directional
18224 character, can change the base direction of the paragraph (unless
18225 the buffer specifies a fixed paragraph direction), which will
18226 require redisplaying the whole paragraph. It might be worthwhile
18227 to find the paragraph limits and widen the range of redisplayed
18228 lines to that, but for now just give up this optimization and
18229 redisplay from scratch. */
18230 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
18231 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
18232 GIVE_UP (22);
18234 /* Give up if the buffer has line-spacing set, as Lisp-level changes
18235 to that variable require thorough redisplay. */
18236 if (!NILP (BVAR (XBUFFER (w->contents), extra_line_spacing)))
18237 GIVE_UP (23);
18239 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
18240 only if buffer has really changed. The reason is that the gap is
18241 initially at Z for freshly visited files. The code below would
18242 set end_unchanged to 0 in that case. */
18243 if (MODIFF > SAVE_MODIFF
18244 /* This seems to happen sometimes after saving a buffer. */
18245 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
18247 if (GPT - BEG < BEG_UNCHANGED)
18248 BEG_UNCHANGED = GPT - BEG;
18249 if (Z - GPT < END_UNCHANGED)
18250 END_UNCHANGED = Z - GPT;
18253 /* The position of the first and last character that has been changed. */
18254 first_changed_charpos = BEG + BEG_UNCHANGED;
18255 last_changed_charpos = Z - END_UNCHANGED;
18257 /* If window starts after a line end, and the last change is in
18258 front of that newline, then changes don't affect the display.
18259 This case happens with stealth-fontification. Note that although
18260 the display is unchanged, glyph positions in the matrix have to
18261 be adjusted, of course. */
18262 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
18263 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
18264 && ((last_changed_charpos < CHARPOS (start)
18265 && CHARPOS (start) == BEGV)
18266 || (last_changed_charpos < CHARPOS (start) - 1
18267 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
18269 ptrdiff_t Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
18270 struct glyph_row *r0;
18272 /* Compute how many chars/bytes have been added to or removed
18273 from the buffer. */
18274 Z_old = MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
18275 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
18276 Z_delta = Z - Z_old;
18277 Z_delta_bytes = Z_BYTE - Z_BYTE_old;
18279 /* Give up if PT is not in the window. Note that it already has
18280 been checked at the start of try_window_id that PT is not in
18281 front of the window start. */
18282 if (PT >= MATRIX_ROW_END_CHARPOS (row) + Z_delta)
18283 GIVE_UP (13);
18285 /* If window start is unchanged, we can reuse the whole matrix
18286 as is, after adjusting glyph positions. No need to compute
18287 the window end again, since its offset from Z hasn't changed. */
18288 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
18289 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + Z_delta
18290 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + Z_delta_bytes
18291 /* PT must not be in a partially visible line. */
18292 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + Z_delta
18293 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
18295 /* Adjust positions in the glyph matrix. */
18296 if (Z_delta || Z_delta_bytes)
18298 struct glyph_row *r1
18299 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
18300 increment_matrix_positions (w->current_matrix,
18301 MATRIX_ROW_VPOS (r0, current_matrix),
18302 MATRIX_ROW_VPOS (r1, current_matrix),
18303 Z_delta, Z_delta_bytes);
18306 /* Set the cursor. */
18307 row = row_containing_pos (w, PT, r0, NULL, 0);
18308 if (row)
18309 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
18310 return 1;
18314 /* Handle the case that changes are all below what is displayed in
18315 the window, and that PT is in the window. This shortcut cannot
18316 be taken if ZV is visible in the window, and text has been added
18317 there that is visible in the window. */
18318 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
18319 /* ZV is not visible in the window, or there are no
18320 changes at ZV, actually. */
18321 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
18322 || first_changed_charpos == last_changed_charpos))
18324 struct glyph_row *r0;
18326 /* Give up if PT is not in the window. Note that it already has
18327 been checked at the start of try_window_id that PT is not in
18328 front of the window start. */
18329 if (PT >= MATRIX_ROW_END_CHARPOS (row))
18330 GIVE_UP (14);
18332 /* If window start is unchanged, we can reuse the whole matrix
18333 as is, without changing glyph positions since no text has
18334 been added/removed in front of the window end. */
18335 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
18336 if (TEXT_POS_EQUAL_P (start, r0->minpos)
18337 /* PT must not be in a partially visible line. */
18338 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
18339 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
18341 /* We have to compute the window end anew since text
18342 could have been added/removed after it. */
18343 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
18344 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
18346 /* Set the cursor. */
18347 row = row_containing_pos (w, PT, r0, NULL, 0);
18348 if (row)
18349 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
18350 return 2;
18354 /* Give up if window start is in the changed area.
18356 The condition used to read
18358 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
18360 but why that was tested escapes me at the moment. */
18361 if (CHARPOS (start) >= first_changed_charpos
18362 && CHARPOS (start) <= last_changed_charpos)
18363 GIVE_UP (15);
18365 /* Check that window start agrees with the start of the first glyph
18366 row in its current matrix. Check this after we know the window
18367 start is not in changed text, otherwise positions would not be
18368 comparable. */
18369 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
18370 if (!TEXT_POS_EQUAL_P (start, row->minpos))
18371 GIVE_UP (16);
18373 /* Give up if the window ends in strings. Overlay strings
18374 at the end are difficult to handle, so don't try. */
18375 row = MATRIX_ROW (current_matrix, w->window_end_vpos);
18376 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
18377 GIVE_UP (20);
18379 /* Compute the position at which we have to start displaying new
18380 lines. Some of the lines at the top of the window might be
18381 reusable because they are not displaying changed text. Find the
18382 last row in W's current matrix not affected by changes at the
18383 start of current_buffer. Value is null if changes start in the
18384 first line of window. */
18385 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
18386 if (last_unchanged_at_beg_row)
18388 /* Avoid starting to display in the middle of a character, a TAB
18389 for instance. This is easier than to set up the iterator
18390 exactly, and it's not a frequent case, so the additional
18391 effort wouldn't really pay off. */
18392 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
18393 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
18394 && last_unchanged_at_beg_row > w->current_matrix->rows)
18395 --last_unchanged_at_beg_row;
18397 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
18398 GIVE_UP (17);
18400 if (! init_to_row_end (&it, w, last_unchanged_at_beg_row))
18401 GIVE_UP (18);
18402 start_pos = it.current.pos;
18404 /* Start displaying new lines in the desired matrix at the same
18405 vpos we would use in the current matrix, i.e. below
18406 last_unchanged_at_beg_row. */
18407 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
18408 current_matrix);
18409 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
18410 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
18412 eassert (it.hpos == 0 && it.current_x == 0);
18414 else
18416 /* There are no reusable lines at the start of the window.
18417 Start displaying in the first text line. */
18418 start_display (&it, w, start);
18419 it.vpos = it.first_vpos;
18420 start_pos = it.current.pos;
18423 /* Find the first row that is not affected by changes at the end of
18424 the buffer. Value will be null if there is no unchanged row, in
18425 which case we must redisplay to the end of the window. delta
18426 will be set to the value by which buffer positions beginning with
18427 first_unchanged_at_end_row have to be adjusted due to text
18428 changes. */
18429 first_unchanged_at_end_row
18430 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
18431 IF_DEBUG (debug_delta = delta);
18432 IF_DEBUG (debug_delta_bytes = delta_bytes);
18434 /* Set stop_pos to the buffer position up to which we will have to
18435 display new lines. If first_unchanged_at_end_row != NULL, this
18436 is the buffer position of the start of the line displayed in that
18437 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
18438 that we don't stop at a buffer position. */
18439 stop_pos = 0;
18440 if (first_unchanged_at_end_row)
18442 eassert (last_unchanged_at_beg_row == NULL
18443 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
18445 /* If this is a continuation line, move forward to the next one
18446 that isn't. Changes in lines above affect this line.
18447 Caution: this may move first_unchanged_at_end_row to a row
18448 not displaying text. */
18449 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
18450 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
18451 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
18452 < it.last_visible_y))
18453 ++first_unchanged_at_end_row;
18455 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
18456 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
18457 >= it.last_visible_y))
18458 first_unchanged_at_end_row = NULL;
18459 else
18461 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
18462 + delta);
18463 first_unchanged_at_end_vpos
18464 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
18465 eassert (stop_pos >= Z - END_UNCHANGED);
18468 else if (last_unchanged_at_beg_row == NULL)
18469 GIVE_UP (19);
18472 #ifdef GLYPH_DEBUG
18474 /* Either there is no unchanged row at the end, or the one we have
18475 now displays text. This is a necessary condition for the window
18476 end pos calculation at the end of this function. */
18477 eassert (first_unchanged_at_end_row == NULL
18478 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
18480 debug_last_unchanged_at_beg_vpos
18481 = (last_unchanged_at_beg_row
18482 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
18483 : -1);
18484 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
18486 #endif /* GLYPH_DEBUG */
18489 /* Display new lines. Set last_text_row to the last new line
18490 displayed which has text on it, i.e. might end up as being the
18491 line where the window_end_vpos is. */
18492 w->cursor.vpos = -1;
18493 last_text_row = NULL;
18494 overlay_arrow_seen = false;
18495 if (it.current_y < it.last_visible_y
18496 && !f->fonts_changed
18497 && (first_unchanged_at_end_row == NULL
18498 || IT_CHARPOS (it) < stop_pos))
18499 it.glyph_row->reversed_p = false;
18500 while (it.current_y < it.last_visible_y
18501 && !f->fonts_changed
18502 && (first_unchanged_at_end_row == NULL
18503 || IT_CHARPOS (it) < stop_pos))
18505 if (display_line (&it))
18506 last_text_row = it.glyph_row - 1;
18509 if (f->fonts_changed)
18510 return -1;
18512 /* The redisplay iterations in display_line above could have
18513 triggered font-lock, which could have done something that
18514 invalidates IT->w window's end-point information, on which we
18515 rely below. E.g., one package, which will remain unnamed, used
18516 to install a font-lock-fontify-region-function that called
18517 bury-buffer, whose side effect is to switch the buffer displayed
18518 by IT->w, and that predictably resets IT->w's window_end_valid
18519 flag, which we already tested at the entry to this function.
18520 Amply punish such packages/modes by giving up on this
18521 optimization in those cases. */
18522 if (!w->window_end_valid)
18524 clear_glyph_matrix (w->desired_matrix);
18525 return -1;
18528 /* Compute differences in buffer positions, y-positions etc. for
18529 lines reused at the bottom of the window. Compute what we can
18530 scroll. */
18531 if (first_unchanged_at_end_row
18532 /* No lines reused because we displayed everything up to the
18533 bottom of the window. */
18534 && it.current_y < it.last_visible_y)
18536 dvpos = (it.vpos
18537 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
18538 current_matrix));
18539 dy = it.current_y - first_unchanged_at_end_row->y;
18540 run.current_y = first_unchanged_at_end_row->y;
18541 run.desired_y = run.current_y + dy;
18542 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
18544 else
18546 delta = delta_bytes = dvpos = dy
18547 = run.current_y = run.desired_y = run.height = 0;
18548 first_unchanged_at_end_row = NULL;
18550 IF_DEBUG ((debug_dvpos = dvpos, debug_dy = dy));
18553 /* Find the cursor if not already found. We have to decide whether
18554 PT will appear on this window (it sometimes doesn't, but this is
18555 not a very frequent case.) This decision has to be made before
18556 the current matrix is altered. A value of cursor.vpos < 0 means
18557 that PT is either in one of the lines beginning at
18558 first_unchanged_at_end_row or below the window. Don't care for
18559 lines that might be displayed later at the window end; as
18560 mentioned, this is not a frequent case. */
18561 if (w->cursor.vpos < 0)
18563 /* Cursor in unchanged rows at the top? */
18564 if (PT < CHARPOS (start_pos)
18565 && last_unchanged_at_beg_row)
18567 row = row_containing_pos (w, PT,
18568 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
18569 last_unchanged_at_beg_row + 1, 0);
18570 if (row)
18571 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
18574 /* Start from first_unchanged_at_end_row looking for PT. */
18575 else if (first_unchanged_at_end_row)
18577 row = row_containing_pos (w, PT - delta,
18578 first_unchanged_at_end_row, NULL, 0);
18579 if (row)
18580 set_cursor_from_row (w, row, w->current_matrix, delta,
18581 delta_bytes, dy, dvpos);
18584 /* Give up if cursor was not found. */
18585 if (w->cursor.vpos < 0)
18587 clear_glyph_matrix (w->desired_matrix);
18588 return -1;
18592 /* Don't let the cursor end in the scroll margins. */
18594 int this_scroll_margin, cursor_height;
18595 int frame_line_height = default_line_pixel_height (w);
18596 int window_total_lines
18597 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (it.f) / frame_line_height;
18599 this_scroll_margin =
18600 max (0, min (scroll_margin, window_total_lines / 4));
18601 this_scroll_margin *= frame_line_height;
18602 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
18604 if ((w->cursor.y < this_scroll_margin
18605 && CHARPOS (start) > BEGV)
18606 /* Old redisplay didn't take scroll margin into account at the bottom,
18607 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
18608 || (w->cursor.y + (make_cursor_line_fully_visible_p
18609 ? cursor_height + this_scroll_margin
18610 : 1)) > it.last_visible_y)
18612 w->cursor.vpos = -1;
18613 clear_glyph_matrix (w->desired_matrix);
18614 return -1;
18618 /* Scroll the display. Do it before changing the current matrix so
18619 that xterm.c doesn't get confused about where the cursor glyph is
18620 found. */
18621 if (dy && run.height)
18623 update_begin (f);
18625 if (FRAME_WINDOW_P (f))
18627 FRAME_RIF (f)->update_window_begin_hook (w);
18628 FRAME_RIF (f)->clear_window_mouse_face (w);
18629 FRAME_RIF (f)->scroll_run_hook (w, &run);
18630 FRAME_RIF (f)->update_window_end_hook (w, false, false);
18632 else
18634 /* Terminal frame. In this case, dvpos gives the number of
18635 lines to scroll by; dvpos < 0 means scroll up. */
18636 int from_vpos
18637 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
18638 int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
18639 int end = (WINDOW_TOP_EDGE_LINE (w)
18640 + WINDOW_WANTS_HEADER_LINE_P (w)
18641 + window_internal_height (w));
18643 #if defined (HAVE_GPM) || defined (MSDOS)
18644 x_clear_window_mouse_face (w);
18645 #endif
18646 /* Perform the operation on the screen. */
18647 if (dvpos > 0)
18649 /* Scroll last_unchanged_at_beg_row to the end of the
18650 window down dvpos lines. */
18651 set_terminal_window (f, end);
18653 /* On dumb terminals delete dvpos lines at the end
18654 before inserting dvpos empty lines. */
18655 if (!FRAME_SCROLL_REGION_OK (f))
18656 ins_del_lines (f, end - dvpos, -dvpos);
18658 /* Insert dvpos empty lines in front of
18659 last_unchanged_at_beg_row. */
18660 ins_del_lines (f, from, dvpos);
18662 else if (dvpos < 0)
18664 /* Scroll up last_unchanged_at_beg_vpos to the end of
18665 the window to last_unchanged_at_beg_vpos - |dvpos|. */
18666 set_terminal_window (f, end);
18668 /* Delete dvpos lines in front of
18669 last_unchanged_at_beg_vpos. ins_del_lines will set
18670 the cursor to the given vpos and emit |dvpos| delete
18671 line sequences. */
18672 ins_del_lines (f, from + dvpos, dvpos);
18674 /* On a dumb terminal insert dvpos empty lines at the
18675 end. */
18676 if (!FRAME_SCROLL_REGION_OK (f))
18677 ins_del_lines (f, end + dvpos, -dvpos);
18680 set_terminal_window (f, 0);
18683 update_end (f);
18686 /* Shift reused rows of the current matrix to the right position.
18687 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
18688 text. */
18689 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
18690 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
18691 if (dvpos < 0)
18693 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
18694 bottom_vpos, dvpos);
18695 clear_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
18696 bottom_vpos);
18698 else if (dvpos > 0)
18700 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
18701 bottom_vpos, dvpos);
18702 clear_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
18703 first_unchanged_at_end_vpos + dvpos);
18706 /* For frame-based redisplay, make sure that current frame and window
18707 matrix are in sync with respect to glyph memory. */
18708 if (!FRAME_WINDOW_P (f))
18709 sync_frame_with_window_matrix_rows (w);
18711 /* Adjust buffer positions in reused rows. */
18712 if (delta || delta_bytes)
18713 increment_matrix_positions (current_matrix,
18714 first_unchanged_at_end_vpos + dvpos,
18715 bottom_vpos, delta, delta_bytes);
18717 /* Adjust Y positions. */
18718 if (dy)
18719 shift_glyph_matrix (w, current_matrix,
18720 first_unchanged_at_end_vpos + dvpos,
18721 bottom_vpos, dy);
18723 if (first_unchanged_at_end_row)
18725 first_unchanged_at_end_row += dvpos;
18726 if (first_unchanged_at_end_row->y >= it.last_visible_y
18727 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
18728 first_unchanged_at_end_row = NULL;
18731 /* If scrolling up, there may be some lines to display at the end of
18732 the window. */
18733 last_text_row_at_end = NULL;
18734 if (dy < 0)
18736 /* Scrolling up can leave for example a partially visible line
18737 at the end of the window to be redisplayed. */
18738 /* Set last_row to the glyph row in the current matrix where the
18739 window end line is found. It has been moved up or down in
18740 the matrix by dvpos. */
18741 int last_vpos = w->window_end_vpos + dvpos;
18742 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
18744 /* If last_row is the window end line, it should display text. */
18745 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_row));
18747 /* If window end line was partially visible before, begin
18748 displaying at that line. Otherwise begin displaying with the
18749 line following it. */
18750 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
18752 init_to_row_start (&it, w, last_row);
18753 it.vpos = last_vpos;
18754 it.current_y = last_row->y;
18756 else
18758 init_to_row_end (&it, w, last_row);
18759 it.vpos = 1 + last_vpos;
18760 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
18761 ++last_row;
18764 /* We may start in a continuation line. If so, we have to
18765 get the right continuation_lines_width and current_x. */
18766 it.continuation_lines_width = last_row->continuation_lines_width;
18767 it.hpos = it.current_x = 0;
18769 /* Display the rest of the lines at the window end. */
18770 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
18771 while (it.current_y < it.last_visible_y && !f->fonts_changed)
18773 /* Is it always sure that the display agrees with lines in
18774 the current matrix? I don't think so, so we mark rows
18775 displayed invalid in the current matrix by setting their
18776 enabled_p flag to false. */
18777 SET_MATRIX_ROW_ENABLED_P (w->current_matrix, it.vpos, false);
18778 if (display_line (&it))
18779 last_text_row_at_end = it.glyph_row - 1;
18783 /* Update window_end_pos and window_end_vpos. */
18784 if (first_unchanged_at_end_row && !last_text_row_at_end)
18786 /* Window end line if one of the preserved rows from the current
18787 matrix. Set row to the last row displaying text in current
18788 matrix starting at first_unchanged_at_end_row, after
18789 scrolling. */
18790 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
18791 row = find_last_row_displaying_text (w->current_matrix, &it,
18792 first_unchanged_at_end_row);
18793 eassume (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
18794 adjust_window_ends (w, row, true);
18795 eassert (w->window_end_bytepos >= 0);
18796 IF_DEBUG (debug_method_add (w, "A"));
18798 else if (last_text_row_at_end)
18800 adjust_window_ends (w, last_text_row_at_end, false);
18801 eassert (w->window_end_bytepos >= 0);
18802 IF_DEBUG (debug_method_add (w, "B"));
18804 else if (last_text_row)
18806 /* We have displayed either to the end of the window or at the
18807 end of the window, i.e. the last row with text is to be found
18808 in the desired matrix. */
18809 adjust_window_ends (w, last_text_row, false);
18810 eassert (w->window_end_bytepos >= 0);
18812 else if (first_unchanged_at_end_row == NULL
18813 && last_text_row == NULL
18814 && last_text_row_at_end == NULL)
18816 /* Displayed to end of window, but no line containing text was
18817 displayed. Lines were deleted at the end of the window. */
18818 bool first_vpos = WINDOW_WANTS_HEADER_LINE_P (w);
18819 int vpos = w->window_end_vpos;
18820 struct glyph_row *current_row = current_matrix->rows + vpos;
18821 struct glyph_row *desired_row = desired_matrix->rows + vpos;
18823 for (row = NULL; !row; --vpos, --current_row, --desired_row)
18825 eassert (first_vpos <= vpos);
18826 if (desired_row->enabled_p)
18828 if (MATRIX_ROW_DISPLAYS_TEXT_P (desired_row))
18829 row = desired_row;
18831 else if (MATRIX_ROW_DISPLAYS_TEXT_P (current_row))
18832 row = current_row;
18835 w->window_end_vpos = vpos + 1;
18836 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
18837 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
18838 eassert (w->window_end_bytepos >= 0);
18839 IF_DEBUG (debug_method_add (w, "C"));
18841 else
18842 emacs_abort ();
18844 IF_DEBUG ((debug_end_pos = w->window_end_pos,
18845 debug_end_vpos = w->window_end_vpos));
18847 /* Record that display has not been completed. */
18848 w->window_end_valid = false;
18849 w->desired_matrix->no_scrolling_p = true;
18850 return 3;
18852 #undef GIVE_UP
18857 /***********************************************************************
18858 More debugging support
18859 ***********************************************************************/
18861 #ifdef GLYPH_DEBUG
18863 void dump_glyph_row (struct glyph_row *, int, int) EXTERNALLY_VISIBLE;
18864 void dump_glyph_matrix (struct glyph_matrix *, int) EXTERNALLY_VISIBLE;
18865 void dump_glyph (struct glyph_row *, struct glyph *, int) EXTERNALLY_VISIBLE;
18868 /* Dump the contents of glyph matrix MATRIX on stderr.
18870 GLYPHS 0 means don't show glyph contents.
18871 GLYPHS 1 means show glyphs in short form
18872 GLYPHS > 1 means show glyphs in long form. */
18874 void
18875 dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs)
18877 int i;
18878 for (i = 0; i < matrix->nrows; ++i)
18879 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
18883 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
18884 the glyph row and area where the glyph comes from. */
18886 void
18887 dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
18889 if (glyph->type == CHAR_GLYPH
18890 || glyph->type == GLYPHLESS_GLYPH)
18892 fprintf (stderr,
18893 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
18894 glyph - row->glyphs[TEXT_AREA],
18895 (glyph->type == CHAR_GLYPH
18896 ? 'C'
18897 : 'G'),
18898 glyph->charpos,
18899 (BUFFERP (glyph->object)
18900 ? 'B'
18901 : (STRINGP (glyph->object)
18902 ? 'S'
18903 : (NILP (glyph->object)
18904 ? '0'
18905 : '-'))),
18906 glyph->pixel_width,
18907 glyph->u.ch,
18908 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
18909 ? glyph->u.ch
18910 : '.'),
18911 glyph->face_id,
18912 glyph->left_box_line_p,
18913 glyph->right_box_line_p);
18915 else if (glyph->type == STRETCH_GLYPH)
18917 fprintf (stderr,
18918 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
18919 glyph - row->glyphs[TEXT_AREA],
18920 'S',
18921 glyph->charpos,
18922 (BUFFERP (glyph->object)
18923 ? 'B'
18924 : (STRINGP (glyph->object)
18925 ? 'S'
18926 : (NILP (glyph->object)
18927 ? '0'
18928 : '-'))),
18929 glyph->pixel_width,
18931 ' ',
18932 glyph->face_id,
18933 glyph->left_box_line_p,
18934 glyph->right_box_line_p);
18936 else if (glyph->type == IMAGE_GLYPH)
18938 fprintf (stderr,
18939 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
18940 glyph - row->glyphs[TEXT_AREA],
18941 'I',
18942 glyph->charpos,
18943 (BUFFERP (glyph->object)
18944 ? 'B'
18945 : (STRINGP (glyph->object)
18946 ? 'S'
18947 : (NILP (glyph->object)
18948 ? '0'
18949 : '-'))),
18950 glyph->pixel_width,
18951 glyph->u.img_id,
18952 '.',
18953 glyph->face_id,
18954 glyph->left_box_line_p,
18955 glyph->right_box_line_p);
18957 else if (glyph->type == COMPOSITE_GLYPH)
18959 fprintf (stderr,
18960 " %5"pD"d %c %9"pI"d %c %3d 0x%06x",
18961 glyph - row->glyphs[TEXT_AREA],
18962 '+',
18963 glyph->charpos,
18964 (BUFFERP (glyph->object)
18965 ? 'B'
18966 : (STRINGP (glyph->object)
18967 ? 'S'
18968 : (NILP (glyph->object)
18969 ? '0'
18970 : '-'))),
18971 glyph->pixel_width,
18972 glyph->u.cmp.id);
18973 if (glyph->u.cmp.automatic)
18974 fprintf (stderr,
18975 "[%d-%d]",
18976 glyph->slice.cmp.from, glyph->slice.cmp.to);
18977 fprintf (stderr, " . %4d %1.1d%1.1d\n",
18978 glyph->face_id,
18979 glyph->left_box_line_p,
18980 glyph->right_box_line_p);
18982 else if (glyph->type == XWIDGET_GLYPH)
18984 #ifndef HAVE_XWIDGETS
18985 eassume (false);
18986 #else
18987 fprintf (stderr,
18988 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
18989 glyph - row->glyphs[TEXT_AREA],
18990 'X',
18991 glyph->charpos,
18992 (BUFFERP (glyph->object)
18993 ? 'B'
18994 : (STRINGP (glyph->object)
18995 ? 'S'
18996 : '-')),
18997 glyph->pixel_width,
18998 glyph->u.xwidget,
18999 '.',
19000 glyph->face_id,
19001 glyph->left_box_line_p,
19002 glyph->right_box_line_p);
19003 #endif
19008 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
19009 GLYPHS 0 means don't show glyph contents.
19010 GLYPHS 1 means show glyphs in short form
19011 GLYPHS > 1 means show glyphs in long form. */
19013 void
19014 dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
19016 if (glyphs != 1)
19018 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
19019 fprintf (stderr, "==============================================================================\n");
19021 fprintf (stderr, "%3d %9"pI"d %9"pI"d %4d %1.1d%1.1d%1.1d%1.1d\
19022 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
19023 vpos,
19024 MATRIX_ROW_START_CHARPOS (row),
19025 MATRIX_ROW_END_CHARPOS (row),
19026 row->used[TEXT_AREA],
19027 row->contains_overlapping_glyphs_p,
19028 row->enabled_p,
19029 row->truncated_on_left_p,
19030 row->truncated_on_right_p,
19031 row->continued_p,
19032 MATRIX_ROW_CONTINUATION_LINE_P (row),
19033 MATRIX_ROW_DISPLAYS_TEXT_P (row),
19034 row->ends_at_zv_p,
19035 row->fill_line_p,
19036 row->ends_in_middle_of_char_p,
19037 row->starts_in_middle_of_char_p,
19038 row->mouse_face_p,
19039 row->x,
19040 row->y,
19041 row->pixel_width,
19042 row->height,
19043 row->visible_height,
19044 row->ascent,
19045 row->phys_ascent);
19046 /* The next 3 lines should align to "Start" in the header. */
19047 fprintf (stderr, " %9"pD"d %9"pD"d\t%5d\n", row->start.overlay_string_index,
19048 row->end.overlay_string_index,
19049 row->continuation_lines_width);
19050 fprintf (stderr, " %9"pI"d %9"pI"d\n",
19051 CHARPOS (row->start.string_pos),
19052 CHARPOS (row->end.string_pos));
19053 fprintf (stderr, " %9d %9d\n", row->start.dpvec_index,
19054 row->end.dpvec_index);
19057 if (glyphs > 1)
19059 int area;
19061 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
19063 struct glyph *glyph = row->glyphs[area];
19064 struct glyph *glyph_end = glyph + row->used[area];
19066 /* Glyph for a line end in text. */
19067 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
19068 ++glyph_end;
19070 if (glyph < glyph_end)
19071 fprintf (stderr, " Glyph# Type Pos O W Code C Face LR\n");
19073 for (; glyph < glyph_end; ++glyph)
19074 dump_glyph (row, glyph, area);
19077 else if (glyphs == 1)
19079 int area;
19080 char s[SHRT_MAX + 4];
19082 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
19084 int i;
19086 for (i = 0; i < row->used[area]; ++i)
19088 struct glyph *glyph = row->glyphs[area] + i;
19089 if (i == row->used[area] - 1
19090 && area == TEXT_AREA
19091 && NILP (glyph->object)
19092 && glyph->type == CHAR_GLYPH
19093 && glyph->u.ch == ' ')
19095 strcpy (&s[i], "[\\n]");
19096 i += 4;
19098 else if (glyph->type == CHAR_GLYPH
19099 && glyph->u.ch < 0x80
19100 && glyph->u.ch >= ' ')
19101 s[i] = glyph->u.ch;
19102 else
19103 s[i] = '.';
19106 s[i] = '\0';
19107 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
19113 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
19114 Sdump_glyph_matrix, 0, 1, "p",
19115 doc: /* Dump the current matrix of the selected window to stderr.
19116 Shows contents of glyph row structures. With non-nil
19117 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
19118 glyphs in short form, otherwise show glyphs in long form.
19120 Interactively, no argument means show glyphs in short form;
19121 with numeric argument, its value is passed as the GLYPHS flag. */)
19122 (Lisp_Object glyphs)
19124 struct window *w = XWINDOW (selected_window);
19125 struct buffer *buffer = XBUFFER (w->contents);
19127 fprintf (stderr, "PT = %"pI"d, BEGV = %"pI"d. ZV = %"pI"d\n",
19128 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
19129 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
19130 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
19131 fprintf (stderr, "=============================================\n");
19132 dump_glyph_matrix (w->current_matrix,
19133 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 0);
19134 return Qnil;
19138 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
19139 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* Dump the current glyph matrix of the selected frame to stderr.
19140 Only text-mode frames have frame glyph matrices. */)
19141 (void)
19143 struct frame *f = XFRAME (selected_frame);
19145 if (f->current_matrix)
19146 dump_glyph_matrix (f->current_matrix, 1);
19147 else
19148 fprintf (stderr, "*** This frame doesn't have a frame glyph matrix ***\n");
19149 return Qnil;
19153 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
19154 doc: /* Dump glyph row ROW to stderr.
19155 GLYPH 0 means don't dump glyphs.
19156 GLYPH 1 means dump glyphs in short form.
19157 GLYPH > 1 or omitted means dump glyphs in long form. */)
19158 (Lisp_Object row, Lisp_Object glyphs)
19160 struct glyph_matrix *matrix;
19161 EMACS_INT vpos;
19163 CHECK_NUMBER (row);
19164 matrix = XWINDOW (selected_window)->current_matrix;
19165 vpos = XINT (row);
19166 if (vpos >= 0 && vpos < matrix->nrows)
19167 dump_glyph_row (MATRIX_ROW (matrix, vpos),
19168 vpos,
19169 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
19170 return Qnil;
19174 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
19175 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
19176 GLYPH 0 means don't dump glyphs.
19177 GLYPH 1 means dump glyphs in short form.
19178 GLYPH > 1 or omitted means dump glyphs in long form.
19180 If there's no tool-bar, or if the tool-bar is not drawn by Emacs,
19181 do nothing. */)
19182 (Lisp_Object row, Lisp_Object glyphs)
19184 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
19185 struct frame *sf = SELECTED_FRAME ();
19186 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
19187 EMACS_INT vpos;
19189 CHECK_NUMBER (row);
19190 vpos = XINT (row);
19191 if (vpos >= 0 && vpos < m->nrows)
19192 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
19193 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
19194 #endif
19195 return Qnil;
19199 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
19200 doc: /* Toggle tracing of redisplay.
19201 With ARG, turn tracing on if and only if ARG is positive. */)
19202 (Lisp_Object arg)
19204 if (NILP (arg))
19205 trace_redisplay_p = !trace_redisplay_p;
19206 else
19208 arg = Fprefix_numeric_value (arg);
19209 trace_redisplay_p = XINT (arg) > 0;
19212 return Qnil;
19216 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
19217 doc: /* Like `format', but print result to stderr.
19218 usage: (trace-to-stderr STRING &rest OBJECTS) */)
19219 (ptrdiff_t nargs, Lisp_Object *args)
19221 Lisp_Object s = Fformat (nargs, args);
19222 fwrite (SDATA (s), 1, SBYTES (s), stderr);
19223 return Qnil;
19226 #endif /* GLYPH_DEBUG */
19230 /***********************************************************************
19231 Building Desired Matrix Rows
19232 ***********************************************************************/
19234 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
19235 Used for non-window-redisplay windows, and for windows w/o left fringe. */
19237 static struct glyph_row *
19238 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
19240 struct frame *f = XFRAME (WINDOW_FRAME (w));
19241 struct buffer *buffer = XBUFFER (w->contents);
19242 struct buffer *old = current_buffer;
19243 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
19244 ptrdiff_t arrow_len = SCHARS (overlay_arrow_string);
19245 const unsigned char *arrow_end = arrow_string + arrow_len;
19246 const unsigned char *p;
19247 struct it it;
19248 bool multibyte_p;
19249 int n_glyphs_before;
19251 set_buffer_temp (buffer);
19252 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
19253 scratch_glyph_row.reversed_p = false;
19254 it.glyph_row->used[TEXT_AREA] = 0;
19255 SET_TEXT_POS (it.position, 0, 0);
19257 multibyte_p = !NILP (BVAR (buffer, enable_multibyte_characters));
19258 p = arrow_string;
19259 while (p < arrow_end)
19261 Lisp_Object face, ilisp;
19263 /* Get the next character. */
19264 if (multibyte_p)
19265 it.c = it.char_to_display = string_char_and_length (p, &it.len);
19266 else
19268 it.c = it.char_to_display = *p, it.len = 1;
19269 if (! ASCII_CHAR_P (it.c))
19270 it.char_to_display = BYTE8_TO_CHAR (it.c);
19272 p += it.len;
19274 /* Get its face. */
19275 ilisp = make_number (p - arrow_string);
19276 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
19277 it.face_id = compute_char_face (f, it.char_to_display, face);
19279 /* Compute its width, get its glyphs. */
19280 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
19281 SET_TEXT_POS (it.position, -1, -1);
19282 PRODUCE_GLYPHS (&it);
19284 /* If this character doesn't fit any more in the line, we have
19285 to remove some glyphs. */
19286 if (it.current_x > it.last_visible_x)
19288 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
19289 break;
19293 set_buffer_temp (old);
19294 return it.glyph_row;
19298 /* Insert truncation glyphs at the start of IT->glyph_row. Which
19299 glyphs to insert is determined by produce_special_glyphs. */
19301 static void
19302 insert_left_trunc_glyphs (struct it *it)
19304 struct it truncate_it;
19305 struct glyph *from, *end, *to, *toend;
19307 eassert (!FRAME_WINDOW_P (it->f)
19308 || (!it->glyph_row->reversed_p
19309 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
19310 || (it->glyph_row->reversed_p
19311 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0));
19313 /* Get the truncation glyphs. */
19314 truncate_it = *it;
19315 truncate_it.current_x = 0;
19316 truncate_it.face_id = DEFAULT_FACE_ID;
19317 truncate_it.glyph_row = &scratch_glyph_row;
19318 truncate_it.area = TEXT_AREA;
19319 truncate_it.glyph_row->used[TEXT_AREA] = 0;
19320 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
19321 truncate_it.object = Qnil;
19322 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
19324 /* Overwrite glyphs from IT with truncation glyphs. */
19325 if (!it->glyph_row->reversed_p)
19327 short tused = truncate_it.glyph_row->used[TEXT_AREA];
19329 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
19330 end = from + tused;
19331 to = it->glyph_row->glyphs[TEXT_AREA];
19332 toend = to + it->glyph_row->used[TEXT_AREA];
19333 if (FRAME_WINDOW_P (it->f))
19335 /* On GUI frames, when variable-size fonts are displayed,
19336 the truncation glyphs may need more pixels than the row's
19337 glyphs they overwrite. We overwrite more glyphs to free
19338 enough screen real estate, and enlarge the stretch glyph
19339 on the right (see display_line), if there is one, to
19340 preserve the screen position of the truncation glyphs on
19341 the right. */
19342 int w = 0;
19343 struct glyph *g = to;
19344 short used;
19346 /* The first glyph could be partially visible, in which case
19347 it->glyph_row->x will be negative. But we want the left
19348 truncation glyphs to be aligned at the left margin of the
19349 window, so we override the x coordinate at which the row
19350 will begin. */
19351 it->glyph_row->x = 0;
19352 while (g < toend && w < it->truncation_pixel_width)
19354 w += g->pixel_width;
19355 ++g;
19357 if (g - to - tused > 0)
19359 memmove (to + tused, g, (toend - g) * sizeof(*g));
19360 it->glyph_row->used[TEXT_AREA] -= g - to - tused;
19362 used = it->glyph_row->used[TEXT_AREA];
19363 if (it->glyph_row->truncated_on_right_p
19364 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
19365 && it->glyph_row->glyphs[TEXT_AREA][used - 2].type
19366 == STRETCH_GLYPH)
19368 int extra = w - it->truncation_pixel_width;
19370 it->glyph_row->glyphs[TEXT_AREA][used - 2].pixel_width += extra;
19374 while (from < end)
19375 *to++ = *from++;
19377 /* There may be padding glyphs left over. Overwrite them too. */
19378 if (!FRAME_WINDOW_P (it->f))
19380 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
19382 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
19383 while (from < end)
19384 *to++ = *from++;
19388 if (to > toend)
19389 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
19391 else
19393 short tused = truncate_it.glyph_row->used[TEXT_AREA];
19395 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
19396 that back to front. */
19397 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
19398 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
19399 toend = it->glyph_row->glyphs[TEXT_AREA];
19400 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
19401 if (FRAME_WINDOW_P (it->f))
19403 int w = 0;
19404 struct glyph *g = to;
19406 while (g >= toend && w < it->truncation_pixel_width)
19408 w += g->pixel_width;
19409 --g;
19411 if (to - g - tused > 0)
19412 to = g + tused;
19413 if (it->glyph_row->truncated_on_right_p
19414 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
19415 && it->glyph_row->glyphs[TEXT_AREA][1].type == STRETCH_GLYPH)
19417 int extra = w - it->truncation_pixel_width;
19419 it->glyph_row->glyphs[TEXT_AREA][1].pixel_width += extra;
19423 while (from >= end && to >= toend)
19424 *to-- = *from--;
19425 if (!FRAME_WINDOW_P (it->f))
19427 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
19429 from =
19430 truncate_it.glyph_row->glyphs[TEXT_AREA]
19431 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
19432 while (from >= end && to >= toend)
19433 *to-- = *from--;
19436 if (from >= end)
19438 /* Need to free some room before prepending additional
19439 glyphs. */
19440 int move_by = from - end + 1;
19441 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
19442 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
19444 for ( ; g >= g0; g--)
19445 g[move_by] = *g;
19446 while (from >= end)
19447 *to-- = *from--;
19448 it->glyph_row->used[TEXT_AREA] += move_by;
19453 /* Compute the hash code for ROW. */
19454 unsigned
19455 row_hash (struct glyph_row *row)
19457 int area, k;
19458 unsigned hashval = 0;
19460 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
19461 for (k = 0; k < row->used[area]; ++k)
19462 hashval = ((((hashval << 4) + (hashval >> 24)) & 0x0fffffff)
19463 + row->glyphs[area][k].u.val
19464 + row->glyphs[area][k].face_id
19465 + row->glyphs[area][k].padding_p
19466 + (row->glyphs[area][k].type << 2));
19468 return hashval;
19471 /* Compute the pixel height and width of IT->glyph_row.
19473 Most of the time, ascent and height of a display line will be equal
19474 to the max_ascent and max_height values of the display iterator
19475 structure. This is not the case if
19477 1. We hit ZV without displaying anything. In this case, max_ascent
19478 and max_height will be zero.
19480 2. We have some glyphs that don't contribute to the line height.
19481 (The glyph row flag contributes_to_line_height_p is for future
19482 pixmap extensions).
19484 The first case is easily covered by using default values because in
19485 these cases, the line height does not really matter, except that it
19486 must not be zero. */
19488 static void
19489 compute_line_metrics (struct it *it)
19491 struct glyph_row *row = it->glyph_row;
19493 if (FRAME_WINDOW_P (it->f))
19495 int i, min_y, max_y;
19497 /* The line may consist of one space only, that was added to
19498 place the cursor on it. If so, the row's height hasn't been
19499 computed yet. */
19500 if (row->height == 0)
19502 if (it->max_ascent + it->max_descent == 0)
19503 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
19504 row->ascent = it->max_ascent;
19505 row->height = it->max_ascent + it->max_descent;
19506 row->phys_ascent = it->max_phys_ascent;
19507 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
19508 row->extra_line_spacing = it->max_extra_line_spacing;
19511 /* Compute the width of this line. */
19512 row->pixel_width = row->x;
19513 for (i = 0; i < row->used[TEXT_AREA]; ++i)
19514 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
19516 eassert (row->pixel_width >= 0);
19517 eassert (row->ascent >= 0 && row->height > 0);
19519 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
19520 || MATRIX_ROW_OVERLAPS_PRED_P (row));
19522 /* If first line's physical ascent is larger than its logical
19523 ascent, use the physical ascent, and make the row taller.
19524 This makes accented characters fully visible. */
19525 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
19526 && row->phys_ascent > row->ascent)
19528 row->height += row->phys_ascent - row->ascent;
19529 row->ascent = row->phys_ascent;
19532 /* Compute how much of the line is visible. */
19533 row->visible_height = row->height;
19535 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
19536 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
19538 if (row->y < min_y)
19539 row->visible_height -= min_y - row->y;
19540 if (row->y + row->height > max_y)
19541 row->visible_height -= row->y + row->height - max_y;
19543 else
19545 row->pixel_width = row->used[TEXT_AREA];
19546 if (row->continued_p)
19547 row->pixel_width -= it->continuation_pixel_width;
19548 else if (row->truncated_on_right_p)
19549 row->pixel_width -= it->truncation_pixel_width;
19550 row->ascent = row->phys_ascent = 0;
19551 row->height = row->phys_height = row->visible_height = 1;
19552 row->extra_line_spacing = 0;
19555 /* Compute a hash code for this row. */
19556 row->hash = row_hash (row);
19558 it->max_ascent = it->max_descent = 0;
19559 it->max_phys_ascent = it->max_phys_descent = 0;
19563 /* Append one space to the glyph row of iterator IT if doing a
19564 window-based redisplay. The space has the same face as
19565 IT->face_id. Value is true if a space was added.
19567 This function is called to make sure that there is always one glyph
19568 at the end of a glyph row that the cursor can be set on under
19569 window-systems. (If there weren't such a glyph we would not know
19570 how wide and tall a box cursor should be displayed).
19572 At the same time this space let's a nicely handle clearing to the
19573 end of the line if the row ends in italic text. */
19575 static bool
19576 append_space_for_newline (struct it *it, bool default_face_p)
19578 if (FRAME_WINDOW_P (it->f))
19580 int n = it->glyph_row->used[TEXT_AREA];
19582 if (it->glyph_row->glyphs[TEXT_AREA] + n
19583 < it->glyph_row->glyphs[1 + TEXT_AREA])
19585 /* Save some values that must not be changed.
19586 Must save IT->c and IT->len because otherwise
19587 ITERATOR_AT_END_P wouldn't work anymore after
19588 append_space_for_newline has been called. */
19589 enum display_element_type saved_what = it->what;
19590 int saved_c = it->c, saved_len = it->len;
19591 int saved_char_to_display = it->char_to_display;
19592 int saved_x = it->current_x;
19593 int saved_face_id = it->face_id;
19594 bool saved_box_end = it->end_of_box_run_p;
19595 struct text_pos saved_pos;
19596 Lisp_Object saved_object;
19597 struct face *face;
19599 saved_object = it->object;
19600 saved_pos = it->position;
19602 it->what = IT_CHARACTER;
19603 memset (&it->position, 0, sizeof it->position);
19604 it->object = Qnil;
19605 it->c = it->char_to_display = ' ';
19606 it->len = 1;
19608 /* If the default face was remapped, be sure to use the
19609 remapped face for the appended newline. */
19610 if (default_face_p)
19611 it->face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
19612 else if (it->face_before_selective_p)
19613 it->face_id = it->saved_face_id;
19614 face = FACE_FROM_ID (it->f, it->face_id);
19615 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
19616 /* In R2L rows, we will prepend a stretch glyph that will
19617 have the end_of_box_run_p flag set for it, so there's no
19618 need for the appended newline glyph to have that flag
19619 set. */
19620 if (it->glyph_row->reversed_p
19621 /* But if the appended newline glyph goes all the way to
19622 the end of the row, there will be no stretch glyph,
19623 so leave the box flag set. */
19624 && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x)
19625 it->end_of_box_run_p = false;
19627 PRODUCE_GLYPHS (it);
19629 #ifdef HAVE_WINDOW_SYSTEM
19630 /* Make sure this space glyph has the right ascent and
19631 descent values, or else cursor at end of line will look
19632 funny, and height of empty lines will be incorrect. */
19633 struct glyph *g = it->glyph_row->glyphs[TEXT_AREA] + n;
19634 struct font *font = face->font ? face->font : FRAME_FONT (it->f);
19635 if (n == 0)
19637 Lisp_Object height, total_height;
19638 int extra_line_spacing = it->extra_line_spacing;
19639 int boff = font->baseline_offset;
19641 if (font->vertical_centering)
19642 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19644 it->object = saved_object; /* get_it_property needs this */
19645 normal_char_ascent_descent (font, -1, &it->ascent, &it->descent);
19646 /* Must do a subset of line height processing from
19647 x_produce_glyph for newline characters. */
19648 height = get_it_property (it, Qline_height);
19649 if (CONSP (height)
19650 && CONSP (XCDR (height))
19651 && NILP (XCDR (XCDR (height))))
19653 total_height = XCAR (XCDR (height));
19654 height = XCAR (height);
19656 else
19657 total_height = Qnil;
19658 height = calc_line_height_property (it, height, font, boff, true);
19660 if (it->override_ascent >= 0)
19662 it->ascent = it->override_ascent;
19663 it->descent = it->override_descent;
19664 boff = it->override_boff;
19666 if (EQ (height, Qt))
19667 extra_line_spacing = 0;
19668 else
19670 Lisp_Object spacing;
19672 it->phys_ascent = it->ascent;
19673 it->phys_descent = it->descent;
19674 if (!NILP (height)
19675 && XINT (height) > it->ascent + it->descent)
19676 it->ascent = XINT (height) - it->descent;
19678 if (!NILP (total_height))
19679 spacing = calc_line_height_property (it, total_height, font,
19680 boff, false);
19681 else
19683 spacing = get_it_property (it, Qline_spacing);
19684 spacing = calc_line_height_property (it, spacing, font,
19685 boff, false);
19687 if (INTEGERP (spacing))
19689 extra_line_spacing = XINT (spacing);
19690 if (!NILP (total_height))
19691 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
19694 if (extra_line_spacing > 0)
19696 it->descent += extra_line_spacing;
19697 if (extra_line_spacing > it->max_extra_line_spacing)
19698 it->max_extra_line_spacing = extra_line_spacing;
19700 it->max_ascent = it->ascent;
19701 it->max_descent = it->descent;
19702 /* Make sure compute_line_metrics recomputes the row height. */
19703 it->glyph_row->height = 0;
19706 g->ascent = it->max_ascent;
19707 g->descent = it->max_descent;
19708 #endif
19710 it->override_ascent = -1;
19711 it->constrain_row_ascent_descent_p = false;
19712 it->current_x = saved_x;
19713 it->object = saved_object;
19714 it->position = saved_pos;
19715 it->what = saved_what;
19716 it->face_id = saved_face_id;
19717 it->len = saved_len;
19718 it->c = saved_c;
19719 it->char_to_display = saved_char_to_display;
19720 it->end_of_box_run_p = saved_box_end;
19721 return true;
19725 return false;
19729 /* Extend the face of the last glyph in the text area of IT->glyph_row
19730 to the end of the display line. Called from display_line. If the
19731 glyph row is empty, add a space glyph to it so that we know the
19732 face to draw. Set the glyph row flag fill_line_p. If the glyph
19733 row is R2L, prepend a stretch glyph to cover the empty space to the
19734 left of the leftmost glyph. */
19736 static void
19737 extend_face_to_end_of_line (struct it *it)
19739 struct face *face, *default_face;
19740 struct frame *f = it->f;
19742 /* If line is already filled, do nothing. Non window-system frames
19743 get a grace of one more ``pixel'' because their characters are
19744 1-``pixel'' wide, so they hit the equality too early. This grace
19745 is needed only for R2L rows that are not continued, to produce
19746 one extra blank where we could display the cursor. */
19747 if ((it->current_x >= it->last_visible_x
19748 + (!FRAME_WINDOW_P (f)
19749 && it->glyph_row->reversed_p
19750 && !it->glyph_row->continued_p))
19751 /* If the window has display margins, we will need to extend
19752 their face even if the text area is filled. */
19753 && !(WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
19754 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0))
19755 return;
19757 /* The default face, possibly remapped. */
19758 default_face = FACE_FROM_ID_OR_NULL (f,
19759 lookup_basic_face (f, DEFAULT_FACE_ID));
19761 /* Face extension extends the background and box of IT->face_id
19762 to the end of the line. If the background equals the background
19763 of the frame, we don't have to do anything. */
19764 face = FACE_FROM_ID (f, (it->face_before_selective_p
19765 ? it->saved_face_id
19766 : it->face_id));
19768 if (FRAME_WINDOW_P (f)
19769 && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row)
19770 && face->box == FACE_NO_BOX
19771 && face->background == FRAME_BACKGROUND_PIXEL (f)
19772 #ifdef HAVE_WINDOW_SYSTEM
19773 && !face->stipple
19774 #endif
19775 && !it->glyph_row->reversed_p)
19776 return;
19778 /* Set the glyph row flag indicating that the face of the last glyph
19779 in the text area has to be drawn to the end of the text area. */
19780 it->glyph_row->fill_line_p = true;
19782 /* If current character of IT is not ASCII, make sure we have the
19783 ASCII face. This will be automatically undone the next time
19784 get_next_display_element returns a multibyte character. Note
19785 that the character will always be single byte in unibyte
19786 text. */
19787 if (!ASCII_CHAR_P (it->c))
19789 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
19792 if (FRAME_WINDOW_P (f))
19794 /* If the row is empty, add a space with the current face of IT,
19795 so that we know which face to draw. */
19796 if (it->glyph_row->used[TEXT_AREA] == 0)
19798 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
19799 it->glyph_row->glyphs[TEXT_AREA][0].face_id = face->id;
19800 it->glyph_row->used[TEXT_AREA] = 1;
19802 /* Mode line and the header line don't have margins, and
19803 likewise the frame's tool-bar window, if there is any. */
19804 if (!(it->glyph_row->mode_line_p
19805 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
19806 || (WINDOWP (f->tool_bar_window)
19807 && it->w == XWINDOW (f->tool_bar_window))
19808 #endif
19811 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
19812 && it->glyph_row->used[LEFT_MARGIN_AREA] == 0)
19814 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0] = space_glyph;
19815 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0].face_id =
19816 default_face->id;
19817 it->glyph_row->used[LEFT_MARGIN_AREA] = 1;
19819 if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0
19820 && it->glyph_row->used[RIGHT_MARGIN_AREA] == 0)
19822 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0] = space_glyph;
19823 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0].face_id =
19824 default_face->id;
19825 it->glyph_row->used[RIGHT_MARGIN_AREA] = 1;
19828 #ifdef HAVE_WINDOW_SYSTEM
19829 if (it->glyph_row->reversed_p)
19831 /* Prepend a stretch glyph to the row, such that the
19832 rightmost glyph will be drawn flushed all the way to the
19833 right margin of the window. The stretch glyph that will
19834 occupy the empty space, if any, to the left of the
19835 glyphs. */
19836 struct font *font = face->font ? face->font : FRAME_FONT (f);
19837 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
19838 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
19839 struct glyph *g;
19840 int row_width, stretch_ascent, stretch_width;
19841 struct text_pos saved_pos;
19842 int saved_face_id;
19843 bool saved_avoid_cursor, saved_box_start;
19845 for (row_width = 0, g = row_start; g < row_end; g++)
19846 row_width += g->pixel_width;
19848 /* FIXME: There are various minor display glitches in R2L
19849 rows when only one of the fringes is missing. The
19850 strange condition below produces the least bad effect. */
19851 if ((WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
19852 == (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0)
19853 || WINDOW_RIGHT_FRINGE_WIDTH (it->w) != 0)
19854 stretch_width = window_box_width (it->w, TEXT_AREA);
19855 else
19856 stretch_width = it->last_visible_x - it->first_visible_x;
19857 stretch_width -= row_width;
19859 if (stretch_width > 0)
19861 stretch_ascent =
19862 (((it->ascent + it->descent)
19863 * FONT_BASE (font)) / FONT_HEIGHT (font));
19864 saved_pos = it->position;
19865 memset (&it->position, 0, sizeof it->position);
19866 saved_avoid_cursor = it->avoid_cursor_p;
19867 it->avoid_cursor_p = true;
19868 saved_face_id = it->face_id;
19869 saved_box_start = it->start_of_box_run_p;
19870 /* The last row's stretch glyph should get the default
19871 face, to avoid painting the rest of the window with
19872 the region face, if the region ends at ZV. */
19873 if (it->glyph_row->ends_at_zv_p)
19874 it->face_id = default_face->id;
19875 else
19876 it->face_id = face->id;
19877 it->start_of_box_run_p = false;
19878 append_stretch_glyph (it, Qnil, stretch_width,
19879 it->ascent + it->descent, stretch_ascent);
19880 it->position = saved_pos;
19881 it->avoid_cursor_p = saved_avoid_cursor;
19882 it->face_id = saved_face_id;
19883 it->start_of_box_run_p = saved_box_start;
19885 /* If stretch_width comes out negative, it means that the
19886 last glyph is only partially visible. In R2L rows, we
19887 want the leftmost glyph to be partially visible, so we
19888 need to give the row the corresponding left offset. */
19889 if (stretch_width < 0)
19890 it->glyph_row->x = stretch_width;
19892 #endif /* HAVE_WINDOW_SYSTEM */
19894 else
19896 /* Save some values that must not be changed. */
19897 int saved_x = it->current_x;
19898 struct text_pos saved_pos;
19899 Lisp_Object saved_object;
19900 enum display_element_type saved_what = it->what;
19901 int saved_face_id = it->face_id;
19903 saved_object = it->object;
19904 saved_pos = it->position;
19906 it->what = IT_CHARACTER;
19907 memset (&it->position, 0, sizeof it->position);
19908 it->object = Qnil;
19909 it->c = it->char_to_display = ' ';
19910 it->len = 1;
19912 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
19913 && (it->glyph_row->used[LEFT_MARGIN_AREA]
19914 < WINDOW_LEFT_MARGIN_WIDTH (it->w))
19915 && !it->glyph_row->mode_line_p
19916 && default_face->background != FRAME_BACKGROUND_PIXEL (f))
19918 struct glyph *g = it->glyph_row->glyphs[LEFT_MARGIN_AREA];
19919 struct glyph *e = g + it->glyph_row->used[LEFT_MARGIN_AREA];
19921 for (it->current_x = 0; g < e; g++)
19922 it->current_x += g->pixel_width;
19924 it->area = LEFT_MARGIN_AREA;
19925 it->face_id = default_face->id;
19926 while (it->glyph_row->used[LEFT_MARGIN_AREA]
19927 < WINDOW_LEFT_MARGIN_WIDTH (it->w))
19929 PRODUCE_GLYPHS (it);
19930 /* term.c:produce_glyphs advances it->current_x only for
19931 TEXT_AREA. */
19932 it->current_x += it->pixel_width;
19935 it->current_x = saved_x;
19936 it->area = TEXT_AREA;
19939 /* The last row's blank glyphs should get the default face, to
19940 avoid painting the rest of the window with the region face,
19941 if the region ends at ZV. */
19942 if (it->glyph_row->ends_at_zv_p)
19943 it->face_id = default_face->id;
19944 else
19945 it->face_id = face->id;
19946 PRODUCE_GLYPHS (it);
19948 while (it->current_x <= it->last_visible_x)
19949 PRODUCE_GLYPHS (it);
19951 if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0
19952 && (it->glyph_row->used[RIGHT_MARGIN_AREA]
19953 < WINDOW_RIGHT_MARGIN_WIDTH (it->w))
19954 && !it->glyph_row->mode_line_p
19955 && default_face->background != FRAME_BACKGROUND_PIXEL (f))
19957 struct glyph *g = it->glyph_row->glyphs[RIGHT_MARGIN_AREA];
19958 struct glyph *e = g + it->glyph_row->used[RIGHT_MARGIN_AREA];
19960 for ( ; g < e; g++)
19961 it->current_x += g->pixel_width;
19963 it->area = RIGHT_MARGIN_AREA;
19964 it->face_id = default_face->id;
19965 while (it->glyph_row->used[RIGHT_MARGIN_AREA]
19966 < WINDOW_RIGHT_MARGIN_WIDTH (it->w))
19968 PRODUCE_GLYPHS (it);
19969 it->current_x += it->pixel_width;
19972 it->area = TEXT_AREA;
19975 /* Don't count these blanks really. It would let us insert a left
19976 truncation glyph below and make us set the cursor on them, maybe. */
19977 it->current_x = saved_x;
19978 it->object = saved_object;
19979 it->position = saved_pos;
19980 it->what = saved_what;
19981 it->face_id = saved_face_id;
19986 /* Value is true if text starting at CHARPOS in current_buffer is
19987 trailing whitespace. */
19989 static bool
19990 trailing_whitespace_p (ptrdiff_t charpos)
19992 ptrdiff_t bytepos = CHAR_TO_BYTE (charpos);
19993 int c = 0;
19995 while (bytepos < ZV_BYTE
19996 && (c = FETCH_CHAR (bytepos),
19997 c == ' ' || c == '\t'))
19998 ++bytepos;
20000 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
20002 if (bytepos != PT_BYTE)
20003 return true;
20005 return false;
20009 /* Highlight trailing whitespace, if any, in ROW. */
20011 static void
20012 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
20014 int used = row->used[TEXT_AREA];
20016 if (used)
20018 struct glyph *start = row->glyphs[TEXT_AREA];
20019 struct glyph *glyph = start + used - 1;
20021 if (row->reversed_p)
20023 /* Right-to-left rows need to be processed in the opposite
20024 direction, so swap the edge pointers. */
20025 glyph = start;
20026 start = row->glyphs[TEXT_AREA] + used - 1;
20029 /* Skip over glyphs inserted to display the cursor at the
20030 end of a line, for extending the face of the last glyph
20031 to the end of the line on terminals, and for truncation
20032 and continuation glyphs. */
20033 if (!row->reversed_p)
20035 while (glyph >= start
20036 && glyph->type == CHAR_GLYPH
20037 && NILP (glyph->object))
20038 --glyph;
20040 else
20042 while (glyph <= start
20043 && glyph->type == CHAR_GLYPH
20044 && NILP (glyph->object))
20045 ++glyph;
20048 /* If last glyph is a space or stretch, and it's trailing
20049 whitespace, set the face of all trailing whitespace glyphs in
20050 IT->glyph_row to `trailing-whitespace'. */
20051 if ((row->reversed_p ? glyph <= start : glyph >= start)
20052 && BUFFERP (glyph->object)
20053 && (glyph->type == STRETCH_GLYPH
20054 || (glyph->type == CHAR_GLYPH
20055 && glyph->u.ch == ' '))
20056 && trailing_whitespace_p (glyph->charpos))
20058 int face_id = lookup_named_face (f, Qtrailing_whitespace, false);
20059 if (face_id < 0)
20060 return;
20062 if (!row->reversed_p)
20064 while (glyph >= start
20065 && BUFFERP (glyph->object)
20066 && (glyph->type == STRETCH_GLYPH
20067 || (glyph->type == CHAR_GLYPH
20068 && glyph->u.ch == ' ')))
20069 (glyph--)->face_id = face_id;
20071 else
20073 while (glyph <= start
20074 && BUFFERP (glyph->object)
20075 && (glyph->type == STRETCH_GLYPH
20076 || (glyph->type == CHAR_GLYPH
20077 && glyph->u.ch == ' ')))
20078 (glyph++)->face_id = face_id;
20085 /* Value is true if glyph row ROW should be
20086 considered to hold the buffer position CHARPOS. */
20088 static bool
20089 row_for_charpos_p (struct glyph_row *row, ptrdiff_t charpos)
20091 bool result = true;
20093 if (charpos == CHARPOS (row->end.pos)
20094 || charpos == MATRIX_ROW_END_CHARPOS (row))
20096 /* Suppose the row ends on a string.
20097 Unless the row is continued, that means it ends on a newline
20098 in the string. If it's anything other than a display string
20099 (e.g., a before-string from an overlay), we don't want the
20100 cursor there. (This heuristic seems to give the optimal
20101 behavior for the various types of multi-line strings.)
20102 One exception: if the string has `cursor' property on one of
20103 its characters, we _do_ want the cursor there. */
20104 if (CHARPOS (row->end.string_pos) >= 0)
20106 if (row->continued_p)
20107 result = true;
20108 else
20110 /* Check for `display' property. */
20111 struct glyph *beg = row->glyphs[TEXT_AREA];
20112 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
20113 struct glyph *glyph;
20115 result = false;
20116 for (glyph = end; glyph >= beg; --glyph)
20117 if (STRINGP (glyph->object))
20119 Lisp_Object prop
20120 = Fget_char_property (make_number (charpos),
20121 Qdisplay, Qnil);
20122 result =
20123 (!NILP (prop)
20124 && display_prop_string_p (prop, glyph->object));
20125 /* If there's a `cursor' property on one of the
20126 string's characters, this row is a cursor row,
20127 even though this is not a display string. */
20128 if (!result)
20130 Lisp_Object s = glyph->object;
20132 for ( ; glyph >= beg && EQ (glyph->object, s); --glyph)
20134 ptrdiff_t gpos = glyph->charpos;
20136 if (!NILP (Fget_char_property (make_number (gpos),
20137 Qcursor, s)))
20139 result = true;
20140 break;
20144 break;
20148 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
20150 /* If the row ends in middle of a real character,
20151 and the line is continued, we want the cursor here.
20152 That's because CHARPOS (ROW->end.pos) would equal
20153 PT if PT is before the character. */
20154 if (!row->ends_in_ellipsis_p)
20155 result = row->continued_p;
20156 else
20157 /* If the row ends in an ellipsis, then
20158 CHARPOS (ROW->end.pos) will equal point after the
20159 invisible text. We want that position to be displayed
20160 after the ellipsis. */
20161 result = false;
20163 /* If the row ends at ZV, display the cursor at the end of that
20164 row instead of at the start of the row below. */
20165 else
20166 result = row->ends_at_zv_p;
20169 return result;
20172 /* Value is true if glyph row ROW should be
20173 used to hold the cursor. */
20175 static bool
20176 cursor_row_p (struct glyph_row *row)
20178 return row_for_charpos_p (row, PT);
20183 /* Push the property PROP so that it will be rendered at the current
20184 position in IT. Return true if PROP was successfully pushed, false
20185 otherwise. Called from handle_line_prefix to handle the
20186 `line-prefix' and `wrap-prefix' properties. */
20188 static bool
20189 push_prefix_prop (struct it *it, Lisp_Object prop)
20191 struct text_pos pos =
20192 STRINGP (it->string) ? it->current.string_pos : it->current.pos;
20194 eassert (it->method == GET_FROM_BUFFER
20195 || it->method == GET_FROM_DISPLAY_VECTOR
20196 || it->method == GET_FROM_STRING
20197 || it->method == GET_FROM_IMAGE);
20199 /* We need to save the current buffer/string position, so it will be
20200 restored by pop_it, because iterate_out_of_display_property
20201 depends on that being set correctly, but some situations leave
20202 it->position not yet set when this function is called. */
20203 push_it (it, &pos);
20205 if (STRINGP (prop))
20207 if (SCHARS (prop) == 0)
20209 pop_it (it);
20210 return false;
20213 it->string = prop;
20214 it->string_from_prefix_prop_p = true;
20215 it->multibyte_p = STRING_MULTIBYTE (it->string);
20216 it->current.overlay_string_index = -1;
20217 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
20218 it->end_charpos = it->string_nchars = SCHARS (it->string);
20219 it->method = GET_FROM_STRING;
20220 it->stop_charpos = 0;
20221 it->prev_stop = 0;
20222 it->base_level_stop = 0;
20224 /* Force paragraph direction to be that of the parent
20225 buffer/string. */
20226 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
20227 it->paragraph_embedding = it->bidi_it.paragraph_dir;
20228 else
20229 it->paragraph_embedding = L2R;
20231 /* Set up the bidi iterator for this display string. */
20232 if (it->bidi_p)
20234 it->bidi_it.string.lstring = it->string;
20235 it->bidi_it.string.s = NULL;
20236 it->bidi_it.string.schars = it->end_charpos;
20237 it->bidi_it.string.bufpos = IT_CHARPOS (*it);
20238 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
20239 it->bidi_it.string.unibyte = !it->multibyte_p;
20240 it->bidi_it.w = it->w;
20241 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
20244 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
20246 it->method = GET_FROM_STRETCH;
20247 it->object = prop;
20249 #ifdef HAVE_WINDOW_SYSTEM
20250 else if (IMAGEP (prop))
20252 it->what = IT_IMAGE;
20253 it->image_id = lookup_image (it->f, prop);
20254 it->method = GET_FROM_IMAGE;
20256 #endif /* HAVE_WINDOW_SYSTEM */
20257 else
20259 pop_it (it); /* bogus display property, give up */
20260 return false;
20263 return true;
20266 /* Return the character-property PROP at the current position in IT. */
20268 static Lisp_Object
20269 get_it_property (struct it *it, Lisp_Object prop)
20271 Lisp_Object position, object = it->object;
20273 if (STRINGP (object))
20274 position = make_number (IT_STRING_CHARPOS (*it));
20275 else if (BUFFERP (object))
20277 position = make_number (IT_CHARPOS (*it));
20278 object = it->window;
20280 else
20281 return Qnil;
20283 return Fget_char_property (position, prop, object);
20286 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
20288 static void
20289 handle_line_prefix (struct it *it)
20291 Lisp_Object prefix;
20293 if (it->continuation_lines_width > 0)
20295 prefix = get_it_property (it, Qwrap_prefix);
20296 if (NILP (prefix))
20297 prefix = Vwrap_prefix;
20299 else
20301 prefix = get_it_property (it, Qline_prefix);
20302 if (NILP (prefix))
20303 prefix = Vline_prefix;
20305 if (! NILP (prefix) && push_prefix_prop (it, prefix))
20307 /* If the prefix is wider than the window, and we try to wrap
20308 it, it would acquire its own wrap prefix, and so on till the
20309 iterator stack overflows. So, don't wrap the prefix. */
20310 it->line_wrap = TRUNCATE;
20311 it->avoid_cursor_p = true;
20317 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
20318 only for R2L lines from display_line and display_string, when they
20319 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
20320 the line/string needs to be continued on the next glyph row. */
20321 static void
20322 unproduce_glyphs (struct it *it, int n)
20324 struct glyph *glyph, *end;
20326 eassert (it->glyph_row);
20327 eassert (it->glyph_row->reversed_p);
20328 eassert (it->area == TEXT_AREA);
20329 eassert (n <= it->glyph_row->used[TEXT_AREA]);
20331 if (n > it->glyph_row->used[TEXT_AREA])
20332 n = it->glyph_row->used[TEXT_AREA];
20333 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
20334 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
20335 for ( ; glyph < end; glyph++)
20336 glyph[-n] = *glyph;
20339 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
20340 and ROW->maxpos. */
20341 static void
20342 find_row_edges (struct it *it, struct glyph_row *row,
20343 ptrdiff_t min_pos, ptrdiff_t min_bpos,
20344 ptrdiff_t max_pos, ptrdiff_t max_bpos)
20346 /* FIXME: Revisit this when glyph ``spilling'' in continuation
20347 lines' rows is implemented for bidi-reordered rows. */
20349 /* ROW->minpos is the value of min_pos, the minimal buffer position
20350 we have in ROW, or ROW->start.pos if that is smaller. */
20351 if (min_pos <= ZV && min_pos < row->start.pos.charpos)
20352 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
20353 else
20354 /* We didn't find buffer positions smaller than ROW->start, or
20355 didn't find _any_ valid buffer positions in any of the glyphs,
20356 so we must trust the iterator's computed positions. */
20357 row->minpos = row->start.pos;
20358 if (max_pos <= 0)
20360 max_pos = CHARPOS (it->current.pos);
20361 max_bpos = BYTEPOS (it->current.pos);
20364 /* Here are the various use-cases for ending the row, and the
20365 corresponding values for ROW->maxpos:
20367 Line ends in a newline from buffer eol_pos + 1
20368 Line is continued from buffer max_pos + 1
20369 Line is truncated on right it->current.pos
20370 Line ends in a newline from string max_pos + 1(*)
20371 (*) + 1 only when line ends in a forward scan
20372 Line is continued from string max_pos
20373 Line is continued from display vector max_pos
20374 Line is entirely from a string min_pos == max_pos
20375 Line is entirely from a display vector min_pos == max_pos
20376 Line that ends at ZV ZV
20378 If you discover other use-cases, please add them here as
20379 appropriate. */
20380 if (row->ends_at_zv_p)
20381 row->maxpos = it->current.pos;
20382 else if (row->used[TEXT_AREA])
20384 bool seen_this_string = false;
20385 struct glyph_row *r1 = row - 1;
20387 /* Did we see the same display string on the previous row? */
20388 if (STRINGP (it->object)
20389 /* this is not the first row */
20390 && row > it->w->desired_matrix->rows
20391 /* previous row is not the header line */
20392 && !r1->mode_line_p
20393 /* previous row also ends in a newline from a string */
20394 && r1->ends_in_newline_from_string_p)
20396 struct glyph *start, *end;
20398 /* Search for the last glyph of the previous row that came
20399 from buffer or string. Depending on whether the row is
20400 L2R or R2L, we need to process it front to back or the
20401 other way round. */
20402 if (!r1->reversed_p)
20404 start = r1->glyphs[TEXT_AREA];
20405 end = start + r1->used[TEXT_AREA];
20406 /* Glyphs inserted by redisplay have nil as their object. */
20407 while (end > start
20408 && NILP ((end - 1)->object)
20409 && (end - 1)->charpos <= 0)
20410 --end;
20411 if (end > start)
20413 if (EQ ((end - 1)->object, it->object))
20414 seen_this_string = true;
20416 else
20417 /* If all the glyphs of the previous row were inserted
20418 by redisplay, it means the previous row was
20419 produced from a single newline, which is only
20420 possible if that newline came from the same string
20421 as the one which produced this ROW. */
20422 seen_this_string = true;
20424 else
20426 end = r1->glyphs[TEXT_AREA] - 1;
20427 start = end + r1->used[TEXT_AREA];
20428 while (end < start
20429 && NILP ((end + 1)->object)
20430 && (end + 1)->charpos <= 0)
20431 ++end;
20432 if (end < start)
20434 if (EQ ((end + 1)->object, it->object))
20435 seen_this_string = true;
20437 else
20438 seen_this_string = true;
20441 /* Take note of each display string that covers a newline only
20442 once, the first time we see it. This is for when a display
20443 string includes more than one newline in it. */
20444 if (row->ends_in_newline_from_string_p && !seen_this_string)
20446 /* If we were scanning the buffer forward when we displayed
20447 the string, we want to account for at least one buffer
20448 position that belongs to this row (position covered by
20449 the display string), so that cursor positioning will
20450 consider this row as a candidate when point is at the end
20451 of the visual line represented by this row. This is not
20452 required when scanning back, because max_pos will already
20453 have a much larger value. */
20454 if (CHARPOS (row->end.pos) > max_pos)
20455 INC_BOTH (max_pos, max_bpos);
20456 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
20458 else if (CHARPOS (it->eol_pos) > 0)
20459 SET_TEXT_POS (row->maxpos,
20460 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
20461 else if (row->continued_p)
20463 /* If max_pos is different from IT's current position, it
20464 means IT->method does not belong to the display element
20465 at max_pos. However, it also means that the display
20466 element at max_pos was displayed in its entirety on this
20467 line, which is equivalent to saying that the next line
20468 starts at the next buffer position. */
20469 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
20470 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
20471 else
20473 INC_BOTH (max_pos, max_bpos);
20474 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
20477 else if (row->truncated_on_right_p)
20478 /* display_line already called reseat_at_next_visible_line_start,
20479 which puts the iterator at the beginning of the next line, in
20480 the logical order. */
20481 row->maxpos = it->current.pos;
20482 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
20483 /* A line that is entirely from a string/image/stretch... */
20484 row->maxpos = row->minpos;
20485 else
20486 emacs_abort ();
20488 else
20489 row->maxpos = it->current.pos;
20492 /* Construct the glyph row IT->glyph_row in the desired matrix of
20493 IT->w from text at the current position of IT. See dispextern.h
20494 for an overview of struct it. Value is true if
20495 IT->glyph_row displays text, as opposed to a line displaying ZV
20496 only. */
20498 static bool
20499 display_line (struct it *it)
20501 struct glyph_row *row = it->glyph_row;
20502 Lisp_Object overlay_arrow_string;
20503 struct it wrap_it;
20504 void *wrap_data = NULL;
20505 bool may_wrap = false;
20506 int wrap_x UNINIT;
20507 int wrap_row_used = -1;
20508 int wrap_row_ascent UNINIT, wrap_row_height UNINIT;
20509 int wrap_row_phys_ascent UNINIT, wrap_row_phys_height UNINIT;
20510 int wrap_row_extra_line_spacing UNINIT;
20511 ptrdiff_t wrap_row_min_pos UNINIT, wrap_row_min_bpos UNINIT;
20512 ptrdiff_t wrap_row_max_pos UNINIT, wrap_row_max_bpos UNINIT;
20513 int cvpos;
20514 ptrdiff_t min_pos = ZV + 1, max_pos = 0;
20515 ptrdiff_t min_bpos UNINIT, max_bpos UNINIT;
20516 bool pending_handle_line_prefix = false;
20518 /* We always start displaying at hpos zero even if hscrolled. */
20519 eassert (it->hpos == 0 && it->current_x == 0);
20521 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
20522 >= it->w->desired_matrix->nrows)
20524 it->w->nrows_scale_factor++;
20525 it->f->fonts_changed = true;
20526 return false;
20529 /* Clear the result glyph row and enable it. */
20530 prepare_desired_row (it->w, row, false);
20532 row->y = it->current_y;
20533 row->start = it->start;
20534 row->continuation_lines_width = it->continuation_lines_width;
20535 row->displays_text_p = true;
20536 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
20537 it->starts_in_middle_of_char_p = false;
20539 /* Arrange the overlays nicely for our purposes. Usually, we call
20540 display_line on only one line at a time, in which case this
20541 can't really hurt too much, or we call it on lines which appear
20542 one after another in the buffer, in which case all calls to
20543 recenter_overlay_lists but the first will be pretty cheap. */
20544 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
20546 /* Move over display elements that are not visible because we are
20547 hscrolled. This may stop at an x-position < IT->first_visible_x
20548 if the first glyph is partially visible or if we hit a line end. */
20549 if (it->current_x < it->first_visible_x)
20551 enum move_it_result move_result;
20553 this_line_min_pos = row->start.pos;
20554 move_result = move_it_in_display_line_to (it, ZV, it->first_visible_x,
20555 MOVE_TO_POS | MOVE_TO_X);
20556 /* If we are under a large hscroll, move_it_in_display_line_to
20557 could hit the end of the line without reaching
20558 it->first_visible_x. Pretend that we did reach it. This is
20559 especially important on a TTY, where we will call
20560 extend_face_to_end_of_line, which needs to know how many
20561 blank glyphs to produce. */
20562 if (it->current_x < it->first_visible_x
20563 && (move_result == MOVE_NEWLINE_OR_CR
20564 || move_result == MOVE_POS_MATCH_OR_ZV))
20565 it->current_x = it->first_visible_x;
20567 /* Record the smallest positions seen while we moved over
20568 display elements that are not visible. This is needed by
20569 redisplay_internal for optimizing the case where the cursor
20570 stays inside the same line. The rest of this function only
20571 considers positions that are actually displayed, so
20572 RECORD_MAX_MIN_POS will not otherwise record positions that
20573 are hscrolled to the left of the left edge of the window. */
20574 min_pos = CHARPOS (this_line_min_pos);
20575 min_bpos = BYTEPOS (this_line_min_pos);
20577 else if (it->area == TEXT_AREA)
20579 /* We only do this when not calling move_it_in_display_line_to
20580 above, because that function calls itself handle_line_prefix. */
20581 handle_line_prefix (it);
20583 else
20585 /* Line-prefix and wrap-prefix are always displayed in the text
20586 area. But if this is the first call to display_line after
20587 init_iterator, the iterator might have been set up to write
20588 into a marginal area, e.g. if the line begins with some
20589 display property that writes to the margins. So we need to
20590 wait with the call to handle_line_prefix until whatever
20591 writes to the margin has done its job. */
20592 pending_handle_line_prefix = true;
20595 /* Get the initial row height. This is either the height of the
20596 text hscrolled, if there is any, or zero. */
20597 row->ascent = it->max_ascent;
20598 row->height = it->max_ascent + it->max_descent;
20599 row->phys_ascent = it->max_phys_ascent;
20600 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
20601 row->extra_line_spacing = it->max_extra_line_spacing;
20603 /* Utility macro to record max and min buffer positions seen until now. */
20604 #define RECORD_MAX_MIN_POS(IT) \
20605 do \
20607 bool composition_p \
20608 = !STRINGP ((IT)->string) && ((IT)->what == IT_COMPOSITION); \
20609 ptrdiff_t current_pos = \
20610 composition_p ? (IT)->cmp_it.charpos \
20611 : IT_CHARPOS (*(IT)); \
20612 ptrdiff_t current_bpos = \
20613 composition_p ? CHAR_TO_BYTE (current_pos) \
20614 : IT_BYTEPOS (*(IT)); \
20615 if (current_pos < min_pos) \
20617 min_pos = current_pos; \
20618 min_bpos = current_bpos; \
20620 if (IT_CHARPOS (*it) > max_pos) \
20622 max_pos = IT_CHARPOS (*it); \
20623 max_bpos = IT_BYTEPOS (*it); \
20626 while (false)
20628 /* Loop generating characters. The loop is left with IT on the next
20629 character to display. */
20630 while (true)
20632 int n_glyphs_before, hpos_before, x_before;
20633 int x, nglyphs;
20634 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
20636 /* Retrieve the next thing to display. Value is false if end of
20637 buffer reached. */
20638 if (!get_next_display_element (it))
20640 /* Maybe add a space at the end of this line that is used to
20641 display the cursor there under X. Set the charpos of the
20642 first glyph of blank lines not corresponding to any text
20643 to -1. */
20644 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
20645 row->exact_window_width_line_p = true;
20646 else if ((append_space_for_newline (it, true)
20647 && row->used[TEXT_AREA] == 1)
20648 || row->used[TEXT_AREA] == 0)
20650 row->glyphs[TEXT_AREA]->charpos = -1;
20651 row->displays_text_p = false;
20653 if (!NILP (BVAR (XBUFFER (it->w->contents), indicate_empty_lines))
20654 && (!MINI_WINDOW_P (it->w)
20655 || (minibuf_level && EQ (it->window, minibuf_window))))
20656 row->indicate_empty_line_p = true;
20659 it->continuation_lines_width = 0;
20660 row->ends_at_zv_p = true;
20661 /* A row that displays right-to-left text must always have
20662 its last face extended all the way to the end of line,
20663 even if this row ends in ZV, because we still write to
20664 the screen left to right. We also need to extend the
20665 last face if the default face is remapped to some
20666 different face, otherwise the functions that clear
20667 portions of the screen will clear with the default face's
20668 background color. */
20669 if (row->reversed_p
20670 || lookup_basic_face (it->f, DEFAULT_FACE_ID) != DEFAULT_FACE_ID)
20671 extend_face_to_end_of_line (it);
20672 break;
20675 /* Now, get the metrics of what we want to display. This also
20676 generates glyphs in `row' (which is IT->glyph_row). */
20677 n_glyphs_before = row->used[TEXT_AREA];
20678 x = it->current_x;
20680 /* Remember the line height so far in case the next element doesn't
20681 fit on the line. */
20682 if (it->line_wrap != TRUNCATE)
20684 ascent = it->max_ascent;
20685 descent = it->max_descent;
20686 phys_ascent = it->max_phys_ascent;
20687 phys_descent = it->max_phys_descent;
20689 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
20691 if (IT_DISPLAYING_WHITESPACE (it))
20692 may_wrap = true;
20693 else if (may_wrap)
20695 SAVE_IT (wrap_it, *it, wrap_data);
20696 wrap_x = x;
20697 wrap_row_used = row->used[TEXT_AREA];
20698 wrap_row_ascent = row->ascent;
20699 wrap_row_height = row->height;
20700 wrap_row_phys_ascent = row->phys_ascent;
20701 wrap_row_phys_height = row->phys_height;
20702 wrap_row_extra_line_spacing = row->extra_line_spacing;
20703 wrap_row_min_pos = min_pos;
20704 wrap_row_min_bpos = min_bpos;
20705 wrap_row_max_pos = max_pos;
20706 wrap_row_max_bpos = max_bpos;
20707 may_wrap = false;
20712 PRODUCE_GLYPHS (it);
20714 /* If this display element was in marginal areas, continue with
20715 the next one. */
20716 if (it->area != TEXT_AREA)
20718 row->ascent = max (row->ascent, it->max_ascent);
20719 row->height = max (row->height, it->max_ascent + it->max_descent);
20720 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
20721 row->phys_height = max (row->phys_height,
20722 it->max_phys_ascent + it->max_phys_descent);
20723 row->extra_line_spacing = max (row->extra_line_spacing,
20724 it->max_extra_line_spacing);
20725 set_iterator_to_next (it, true);
20726 /* If we didn't handle the line/wrap prefix above, and the
20727 call to set_iterator_to_next just switched to TEXT_AREA,
20728 process the prefix now. */
20729 if (it->area == TEXT_AREA && pending_handle_line_prefix)
20731 pending_handle_line_prefix = false;
20732 handle_line_prefix (it);
20734 continue;
20737 /* Does the display element fit on the line? If we truncate
20738 lines, we should draw past the right edge of the window. If
20739 we don't truncate, we want to stop so that we can display the
20740 continuation glyph before the right margin. If lines are
20741 continued, there are two possible strategies for characters
20742 resulting in more than 1 glyph (e.g. tabs): Display as many
20743 glyphs as possible in this line and leave the rest for the
20744 continuation line, or display the whole element in the next
20745 line. Original redisplay did the former, so we do it also. */
20746 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
20747 hpos_before = it->hpos;
20748 x_before = x;
20750 if (/* Not a newline. */
20751 nglyphs > 0
20752 /* Glyphs produced fit entirely in the line. */
20753 && it->current_x < it->last_visible_x)
20755 it->hpos += nglyphs;
20756 row->ascent = max (row->ascent, it->max_ascent);
20757 row->height = max (row->height, it->max_ascent + it->max_descent);
20758 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
20759 row->phys_height = max (row->phys_height,
20760 it->max_phys_ascent + it->max_phys_descent);
20761 row->extra_line_spacing = max (row->extra_line_spacing,
20762 it->max_extra_line_spacing);
20763 if (it->current_x - it->pixel_width < it->first_visible_x
20764 /* In R2L rows, we arrange in extend_face_to_end_of_line
20765 to add a right offset to the line, by a suitable
20766 change to the stretch glyph that is the leftmost
20767 glyph of the line. */
20768 && !row->reversed_p)
20769 row->x = x - it->first_visible_x;
20770 /* Record the maximum and minimum buffer positions seen so
20771 far in glyphs that will be displayed by this row. */
20772 if (it->bidi_p)
20773 RECORD_MAX_MIN_POS (it);
20775 else
20777 int i, new_x;
20778 struct glyph *glyph;
20780 for (i = 0; i < nglyphs; ++i, x = new_x)
20782 /* Identify the glyphs added by the last call to
20783 PRODUCE_GLYPHS. In R2L rows, they are prepended to
20784 the previous glyphs. */
20785 if (!row->reversed_p)
20786 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
20787 else
20788 glyph = row->glyphs[TEXT_AREA] + nglyphs - 1 - i;
20789 new_x = x + glyph->pixel_width;
20791 if (/* Lines are continued. */
20792 it->line_wrap != TRUNCATE
20793 && (/* Glyph doesn't fit on the line. */
20794 new_x > it->last_visible_x
20795 /* Or it fits exactly on a window system frame. */
20796 || (new_x == it->last_visible_x
20797 && FRAME_WINDOW_P (it->f)
20798 && (row->reversed_p
20799 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
20800 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
20802 /* End of a continued line. */
20804 if (it->hpos == 0
20805 || (new_x == it->last_visible_x
20806 && FRAME_WINDOW_P (it->f)
20807 && (row->reversed_p
20808 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
20809 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))))
20811 /* Current glyph is the only one on the line or
20812 fits exactly on the line. We must continue
20813 the line because we can't draw the cursor
20814 after the glyph. */
20815 row->continued_p = true;
20816 it->current_x = new_x;
20817 it->continuation_lines_width += new_x;
20818 ++it->hpos;
20819 if (i == nglyphs - 1)
20821 /* If line-wrap is on, check if a previous
20822 wrap point was found. */
20823 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)
20824 && wrap_row_used > 0
20825 /* Even if there is a previous wrap
20826 point, continue the line here as
20827 usual, if (i) the previous character
20828 was a space or tab AND (ii) the
20829 current character is not. */
20830 && (!may_wrap
20831 || IT_DISPLAYING_WHITESPACE (it)))
20832 goto back_to_wrap;
20834 /* Record the maximum and minimum buffer
20835 positions seen so far in glyphs that will be
20836 displayed by this row. */
20837 if (it->bidi_p)
20838 RECORD_MAX_MIN_POS (it);
20839 set_iterator_to_next (it, true);
20840 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
20842 if (!get_next_display_element (it))
20844 row->exact_window_width_line_p = true;
20845 it->continuation_lines_width = 0;
20846 row->continued_p = false;
20847 row->ends_at_zv_p = true;
20849 else if (ITERATOR_AT_END_OF_LINE_P (it))
20851 row->continued_p = false;
20852 row->exact_window_width_line_p = true;
20854 /* If line-wrap is on, check if a
20855 previous wrap point was found. */
20856 else if (wrap_row_used > 0
20857 /* Even if there is a previous wrap
20858 point, continue the line here as
20859 usual, if (i) the previous character
20860 was a space or tab AND (ii) the
20861 current character is not. */
20862 && (!may_wrap
20863 || IT_DISPLAYING_WHITESPACE (it)))
20864 goto back_to_wrap;
20868 else if (it->bidi_p)
20869 RECORD_MAX_MIN_POS (it);
20870 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20871 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
20872 extend_face_to_end_of_line (it);
20874 else if (CHAR_GLYPH_PADDING_P (*glyph)
20875 && !FRAME_WINDOW_P (it->f))
20877 /* A padding glyph that doesn't fit on this line.
20878 This means the whole character doesn't fit
20879 on the line. */
20880 if (row->reversed_p)
20881 unproduce_glyphs (it, row->used[TEXT_AREA]
20882 - n_glyphs_before);
20883 row->used[TEXT_AREA] = n_glyphs_before;
20885 /* Fill the rest of the row with continuation
20886 glyphs like in 20.x. */
20887 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
20888 < row->glyphs[1 + TEXT_AREA])
20889 produce_special_glyphs (it, IT_CONTINUATION);
20891 row->continued_p = true;
20892 it->current_x = x_before;
20893 it->continuation_lines_width += x_before;
20895 /* Restore the height to what it was before the
20896 element not fitting on the line. */
20897 it->max_ascent = ascent;
20898 it->max_descent = descent;
20899 it->max_phys_ascent = phys_ascent;
20900 it->max_phys_descent = phys_descent;
20901 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20902 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
20903 extend_face_to_end_of_line (it);
20905 else if (wrap_row_used > 0)
20907 back_to_wrap:
20908 if (row->reversed_p)
20909 unproduce_glyphs (it,
20910 row->used[TEXT_AREA] - wrap_row_used);
20911 RESTORE_IT (it, &wrap_it, wrap_data);
20912 it->continuation_lines_width += wrap_x;
20913 row->used[TEXT_AREA] = wrap_row_used;
20914 row->ascent = wrap_row_ascent;
20915 row->height = wrap_row_height;
20916 row->phys_ascent = wrap_row_phys_ascent;
20917 row->phys_height = wrap_row_phys_height;
20918 row->extra_line_spacing = wrap_row_extra_line_spacing;
20919 min_pos = wrap_row_min_pos;
20920 min_bpos = wrap_row_min_bpos;
20921 max_pos = wrap_row_max_pos;
20922 max_bpos = wrap_row_max_bpos;
20923 row->continued_p = true;
20924 row->ends_at_zv_p = false;
20925 row->exact_window_width_line_p = false;
20926 it->continuation_lines_width += x;
20928 /* Make sure that a non-default face is extended
20929 up to the right margin of the window. */
20930 extend_face_to_end_of_line (it);
20932 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
20934 /* A TAB that extends past the right edge of the
20935 window. This produces a single glyph on
20936 window system frames. We leave the glyph in
20937 this row and let it fill the row, but don't
20938 consume the TAB. */
20939 if ((row->reversed_p
20940 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
20941 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
20942 produce_special_glyphs (it, IT_CONTINUATION);
20943 it->continuation_lines_width += it->last_visible_x;
20944 row->ends_in_middle_of_char_p = true;
20945 row->continued_p = true;
20946 glyph->pixel_width = it->last_visible_x - x;
20947 it->starts_in_middle_of_char_p = true;
20948 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20949 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
20950 extend_face_to_end_of_line (it);
20952 else
20954 /* Something other than a TAB that draws past
20955 the right edge of the window. Restore
20956 positions to values before the element. */
20957 if (row->reversed_p)
20958 unproduce_glyphs (it, row->used[TEXT_AREA]
20959 - (n_glyphs_before + i));
20960 row->used[TEXT_AREA] = n_glyphs_before + i;
20962 /* Display continuation glyphs. */
20963 it->current_x = x_before;
20964 it->continuation_lines_width += x;
20965 if (!FRAME_WINDOW_P (it->f)
20966 || (row->reversed_p
20967 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
20968 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
20969 produce_special_glyphs (it, IT_CONTINUATION);
20970 row->continued_p = true;
20972 extend_face_to_end_of_line (it);
20974 if (nglyphs > 1 && i > 0)
20976 row->ends_in_middle_of_char_p = true;
20977 it->starts_in_middle_of_char_p = true;
20980 /* Restore the height to what it was before the
20981 element not fitting on the line. */
20982 it->max_ascent = ascent;
20983 it->max_descent = descent;
20984 it->max_phys_ascent = phys_ascent;
20985 it->max_phys_descent = phys_descent;
20988 break;
20990 else if (new_x > it->first_visible_x)
20992 /* Increment number of glyphs actually displayed. */
20993 ++it->hpos;
20995 /* Record the maximum and minimum buffer positions
20996 seen so far in glyphs that will be displayed by
20997 this row. */
20998 if (it->bidi_p)
20999 RECORD_MAX_MIN_POS (it);
21001 if (x < it->first_visible_x && !row->reversed_p)
21002 /* Glyph is partially visible, i.e. row starts at
21003 negative X position. Don't do that in R2L
21004 rows, where we arrange to add a right offset to
21005 the line in extend_face_to_end_of_line, by a
21006 suitable change to the stretch glyph that is
21007 the leftmost glyph of the line. */
21008 row->x = x - it->first_visible_x;
21009 /* When the last glyph of an R2L row only fits
21010 partially on the line, we need to set row->x to a
21011 negative offset, so that the leftmost glyph is
21012 the one that is partially visible. But if we are
21013 going to produce the truncation glyph, this will
21014 be taken care of in produce_special_glyphs. */
21015 if (row->reversed_p
21016 && new_x > it->last_visible_x
21017 && !(it->line_wrap == TRUNCATE
21018 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0))
21020 eassert (FRAME_WINDOW_P (it->f));
21021 row->x = it->last_visible_x - new_x;
21024 else
21026 /* Glyph is completely off the left margin of the
21027 window. This should not happen because of the
21028 move_it_in_display_line at the start of this
21029 function, unless the text display area of the
21030 window is empty. */
21031 eassert (it->first_visible_x <= it->last_visible_x);
21034 /* Even if this display element produced no glyphs at all,
21035 we want to record its position. */
21036 if (it->bidi_p && nglyphs == 0)
21037 RECORD_MAX_MIN_POS (it);
21039 row->ascent = max (row->ascent, it->max_ascent);
21040 row->height = max (row->height, it->max_ascent + it->max_descent);
21041 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
21042 row->phys_height = max (row->phys_height,
21043 it->max_phys_ascent + it->max_phys_descent);
21044 row->extra_line_spacing = max (row->extra_line_spacing,
21045 it->max_extra_line_spacing);
21047 /* End of this display line if row is continued. */
21048 if (row->continued_p || row->ends_at_zv_p)
21049 break;
21052 at_end_of_line:
21053 /* Is this a line end? If yes, we're also done, after making
21054 sure that a non-default face is extended up to the right
21055 margin of the window. */
21056 if (ITERATOR_AT_END_OF_LINE_P (it))
21058 int used_before = row->used[TEXT_AREA];
21060 row->ends_in_newline_from_string_p = STRINGP (it->object);
21062 /* Add a space at the end of the line that is used to
21063 display the cursor there. */
21064 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
21065 append_space_for_newline (it, false);
21067 /* Extend the face to the end of the line. */
21068 extend_face_to_end_of_line (it);
21070 /* Make sure we have the position. */
21071 if (used_before == 0)
21072 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
21074 /* Record the position of the newline, for use in
21075 find_row_edges. */
21076 it->eol_pos = it->current.pos;
21078 /* Consume the line end. This skips over invisible lines. */
21079 set_iterator_to_next (it, true);
21080 it->continuation_lines_width = 0;
21081 break;
21084 /* Proceed with next display element. Note that this skips
21085 over lines invisible because of selective display. */
21086 set_iterator_to_next (it, true);
21088 /* If we truncate lines, we are done when the last displayed
21089 glyphs reach past the right margin of the window. */
21090 if (it->line_wrap == TRUNCATE
21091 && ((FRAME_WINDOW_P (it->f)
21092 /* Images are preprocessed in produce_image_glyph such
21093 that they are cropped at the right edge of the
21094 window, so an image glyph will always end exactly at
21095 last_visible_x, even if there's no right fringe. */
21096 && ((row->reversed_p
21097 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
21098 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))
21099 || it->what == IT_IMAGE))
21100 ? (it->current_x >= it->last_visible_x)
21101 : (it->current_x > it->last_visible_x)))
21103 /* Maybe add truncation glyphs. */
21104 if (!FRAME_WINDOW_P (it->f)
21105 || (row->reversed_p
21106 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
21107 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
21109 int i, n;
21111 if (!row->reversed_p)
21113 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
21114 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
21115 break;
21117 else
21119 for (i = 0; i < row->used[TEXT_AREA]; i++)
21120 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
21121 break;
21122 /* Remove any padding glyphs at the front of ROW, to
21123 make room for the truncation glyphs we will be
21124 adding below. The loop below always inserts at
21125 least one truncation glyph, so also remove the
21126 last glyph added to ROW. */
21127 unproduce_glyphs (it, i + 1);
21128 /* Adjust i for the loop below. */
21129 i = row->used[TEXT_AREA] - (i + 1);
21132 /* produce_special_glyphs overwrites the last glyph, so
21133 we don't want that if we want to keep that last
21134 glyph, which means it's an image. */
21135 if (it->current_x > it->last_visible_x)
21137 it->current_x = x_before;
21138 if (!FRAME_WINDOW_P (it->f))
21140 for (n = row->used[TEXT_AREA]; i < n; ++i)
21142 row->used[TEXT_AREA] = i;
21143 produce_special_glyphs (it, IT_TRUNCATION);
21146 else
21148 row->used[TEXT_AREA] = i;
21149 produce_special_glyphs (it, IT_TRUNCATION);
21151 it->hpos = hpos_before;
21154 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
21156 /* Don't truncate if we can overflow newline into fringe. */
21157 if (!get_next_display_element (it))
21159 it->continuation_lines_width = 0;
21160 row->ends_at_zv_p = true;
21161 row->exact_window_width_line_p = true;
21162 break;
21164 if (ITERATOR_AT_END_OF_LINE_P (it))
21166 row->exact_window_width_line_p = true;
21167 goto at_end_of_line;
21169 it->current_x = x_before;
21170 it->hpos = hpos_before;
21173 row->truncated_on_right_p = true;
21174 it->continuation_lines_width = 0;
21175 reseat_at_next_visible_line_start (it, false);
21176 /* We insist below that IT's position be at ZV because in
21177 bidi-reordered lines the character at visible line start
21178 might not be the character that follows the newline in
21179 the logical order. */
21180 if (IT_BYTEPOS (*it) > BEG_BYTE)
21181 row->ends_at_zv_p =
21182 IT_BYTEPOS (*it) >= ZV_BYTE && FETCH_BYTE (ZV_BYTE - 1) != '\n';
21183 else
21184 row->ends_at_zv_p = false;
21185 break;
21189 if (wrap_data)
21190 bidi_unshelve_cache (wrap_data, true);
21192 /* If line is not empty and hscrolled, maybe insert truncation glyphs
21193 at the left window margin. */
21194 if (it->first_visible_x
21195 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
21197 if (!FRAME_WINDOW_P (it->f)
21198 || (((row->reversed_p
21199 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
21200 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
21201 /* Don't let insert_left_trunc_glyphs overwrite the
21202 first glyph of the row if it is an image. */
21203 && row->glyphs[TEXT_AREA]->type != IMAGE_GLYPH))
21204 insert_left_trunc_glyphs (it);
21205 row->truncated_on_left_p = true;
21208 /* Remember the position at which this line ends.
21210 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
21211 cannot be before the call to find_row_edges below, since that is
21212 where these positions are determined. */
21213 row->end = it->current;
21214 if (!it->bidi_p)
21216 row->minpos = row->start.pos;
21217 row->maxpos = row->end.pos;
21219 else
21221 /* ROW->minpos and ROW->maxpos must be the smallest and
21222 `1 + the largest' buffer positions in ROW. But if ROW was
21223 bidi-reordered, these two positions can be anywhere in the
21224 row, so we must determine them now. */
21225 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
21228 /* If the start of this line is the overlay arrow-position, then
21229 mark this glyph row as the one containing the overlay arrow.
21230 This is clearly a mess with variable size fonts. It would be
21231 better to let it be displayed like cursors under X. */
21232 if ((MATRIX_ROW_DISPLAYS_TEXT_P (row) || !overlay_arrow_seen)
21233 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
21234 !NILP (overlay_arrow_string)))
21236 /* Overlay arrow in window redisplay is a fringe bitmap. */
21237 if (STRINGP (overlay_arrow_string))
21239 struct glyph_row *arrow_row
21240 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
21241 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
21242 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
21243 struct glyph *p = row->glyphs[TEXT_AREA];
21244 struct glyph *p2, *end;
21246 /* Copy the arrow glyphs. */
21247 while (glyph < arrow_end)
21248 *p++ = *glyph++;
21250 /* Throw away padding glyphs. */
21251 p2 = p;
21252 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
21253 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
21254 ++p2;
21255 if (p2 > p)
21257 while (p2 < end)
21258 *p++ = *p2++;
21259 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
21262 else
21264 eassert (INTEGERP (overlay_arrow_string));
21265 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
21267 overlay_arrow_seen = true;
21270 /* Highlight trailing whitespace. */
21271 if (!NILP (Vshow_trailing_whitespace))
21272 highlight_trailing_whitespace (it->f, it->glyph_row);
21274 /* Compute pixel dimensions of this line. */
21275 compute_line_metrics (it);
21277 /* Implementation note: No changes in the glyphs of ROW or in their
21278 faces can be done past this point, because compute_line_metrics
21279 computes ROW's hash value and stores it within the glyph_row
21280 structure. */
21282 /* Record whether this row ends inside an ellipsis. */
21283 row->ends_in_ellipsis_p
21284 = (it->method == GET_FROM_DISPLAY_VECTOR
21285 && it->ellipsis_p);
21287 /* Save fringe bitmaps in this row. */
21288 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
21289 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
21290 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
21291 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
21293 it->left_user_fringe_bitmap = 0;
21294 it->left_user_fringe_face_id = 0;
21295 it->right_user_fringe_bitmap = 0;
21296 it->right_user_fringe_face_id = 0;
21298 /* Maybe set the cursor. */
21299 cvpos = it->w->cursor.vpos;
21300 if ((cvpos < 0
21301 /* In bidi-reordered rows, keep checking for proper cursor
21302 position even if one has been found already, because buffer
21303 positions in such rows change non-linearly with ROW->VPOS,
21304 when a line is continued. One exception: when we are at ZV,
21305 display cursor on the first suitable glyph row, since all
21306 the empty rows after that also have their position set to ZV. */
21307 /* FIXME: Revisit this when glyph ``spilling'' in continuation
21308 lines' rows is implemented for bidi-reordered rows. */
21309 || (it->bidi_p
21310 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
21311 && PT >= MATRIX_ROW_START_CHARPOS (row)
21312 && PT <= MATRIX_ROW_END_CHARPOS (row)
21313 && cursor_row_p (row))
21314 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
21316 /* Prepare for the next line. This line starts horizontally at (X
21317 HPOS) = (0 0). Vertical positions are incremented. As a
21318 convenience for the caller, IT->glyph_row is set to the next
21319 row to be used. */
21320 it->current_x = it->hpos = 0;
21321 it->current_y += row->height;
21322 SET_TEXT_POS (it->eol_pos, 0, 0);
21323 ++it->vpos;
21324 ++it->glyph_row;
21325 /* The next row should by default use the same value of the
21326 reversed_p flag as this one. set_iterator_to_next decides when
21327 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
21328 the flag accordingly. */
21329 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
21330 it->glyph_row->reversed_p = row->reversed_p;
21331 it->start = row->end;
21332 return MATRIX_ROW_DISPLAYS_TEXT_P (row);
21334 #undef RECORD_MAX_MIN_POS
21337 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
21338 Scurrent_bidi_paragraph_direction, 0, 1, 0,
21339 doc: /* Return paragraph direction at point in BUFFER.
21340 Value is either `left-to-right' or `right-to-left'.
21341 If BUFFER is omitted or nil, it defaults to the current buffer.
21343 Paragraph direction determines how the text in the paragraph is displayed.
21344 In left-to-right paragraphs, text begins at the left margin of the window
21345 and the reading direction is generally left to right. In right-to-left
21346 paragraphs, text begins at the right margin and is read from right to left.
21348 See also `bidi-paragraph-direction'. */)
21349 (Lisp_Object buffer)
21351 struct buffer *buf = current_buffer;
21352 struct buffer *old = buf;
21354 if (! NILP (buffer))
21356 CHECK_BUFFER (buffer);
21357 buf = XBUFFER (buffer);
21360 if (NILP (BVAR (buf, bidi_display_reordering))
21361 || NILP (BVAR (buf, enable_multibyte_characters))
21362 /* When we are loading loadup.el, the character property tables
21363 needed for bidi iteration are not yet available. */
21364 || redisplay__inhibit_bidi)
21365 return Qleft_to_right;
21366 else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
21367 return BVAR (buf, bidi_paragraph_direction);
21368 else
21370 /* Determine the direction from buffer text. We could try to
21371 use current_matrix if it is up to date, but this seems fast
21372 enough as it is. */
21373 struct bidi_it itb;
21374 ptrdiff_t pos = BUF_PT (buf);
21375 ptrdiff_t bytepos = BUF_PT_BYTE (buf);
21376 int c;
21377 void *itb_data = bidi_shelve_cache ();
21379 set_buffer_temp (buf);
21380 /* bidi_paragraph_init finds the base direction of the paragraph
21381 by searching forward from paragraph start. We need the base
21382 direction of the current or _previous_ paragraph, so we need
21383 to make sure we are within that paragraph. To that end, find
21384 the previous non-empty line. */
21385 if (pos >= ZV && pos > BEGV)
21386 DEC_BOTH (pos, bytepos);
21387 AUTO_STRING (trailing_white_space, "[\f\t ]*\n");
21388 if (fast_looking_at (trailing_white_space,
21389 pos, bytepos, ZV, ZV_BYTE, Qnil) > 0)
21391 while ((c = FETCH_BYTE (bytepos)) == '\n'
21392 || c == ' ' || c == '\t' || c == '\f')
21394 if (bytepos <= BEGV_BYTE)
21395 break;
21396 bytepos--;
21397 pos--;
21399 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
21400 bytepos--;
21402 bidi_init_it (pos, bytepos, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb);
21403 itb.paragraph_dir = NEUTRAL_DIR;
21404 itb.string.s = NULL;
21405 itb.string.lstring = Qnil;
21406 itb.string.bufpos = 0;
21407 itb.string.from_disp_str = false;
21408 itb.string.unibyte = false;
21409 /* We have no window to use here for ignoring window-specific
21410 overlays. Using NULL for window pointer will cause
21411 compute_display_string_pos to use the current buffer. */
21412 itb.w = NULL;
21413 bidi_paragraph_init (NEUTRAL_DIR, &itb, true);
21414 bidi_unshelve_cache (itb_data, false);
21415 set_buffer_temp (old);
21416 switch (itb.paragraph_dir)
21418 case L2R:
21419 return Qleft_to_right;
21420 break;
21421 case R2L:
21422 return Qright_to_left;
21423 break;
21424 default:
21425 emacs_abort ();
21430 DEFUN ("bidi-find-overridden-directionality",
21431 Fbidi_find_overridden_directionality,
21432 Sbidi_find_overridden_directionality, 2, 3, 0,
21433 doc: /* Return position between FROM and TO where directionality was overridden.
21435 This function returns the first character position in the specified
21436 region of OBJECT where there is a character whose `bidi-class' property
21437 is `L', but which was forced to display as `R' by a directional
21438 override, and likewise with characters whose `bidi-class' is `R'
21439 or `AL' that were forced to display as `L'.
21441 If no such character is found, the function returns nil.
21443 OBJECT is a Lisp string or buffer to search for overridden
21444 directionality, and defaults to the current buffer if nil or omitted.
21445 OBJECT can also be a window, in which case the function will search
21446 the buffer displayed in that window. Passing the window instead of
21447 a buffer is preferable when the buffer is displayed in some window,
21448 because this function will then be able to correctly account for
21449 window-specific overlays, which can affect the results.
21451 Strong directional characters `L', `R', and `AL' can have their
21452 intrinsic directionality overridden by directional override
21453 control characters RLO (u+202e) and LRO (u+202d). See the
21454 function `get-char-code-property' for a way to inquire about
21455 the `bidi-class' property of a character. */)
21456 (Lisp_Object from, Lisp_Object to, Lisp_Object object)
21458 struct buffer *buf = current_buffer;
21459 struct buffer *old = buf;
21460 struct window *w = NULL;
21461 bool frame_window_p = FRAME_WINDOW_P (SELECTED_FRAME ());
21462 struct bidi_it itb;
21463 ptrdiff_t from_pos, to_pos, from_bpos;
21464 void *itb_data;
21466 if (!NILP (object))
21468 if (BUFFERP (object))
21469 buf = XBUFFER (object);
21470 else if (WINDOWP (object))
21472 w = decode_live_window (object);
21473 buf = XBUFFER (w->contents);
21474 frame_window_p = FRAME_WINDOW_P (XFRAME (w->frame));
21476 else
21477 CHECK_STRING (object);
21480 if (STRINGP (object))
21482 /* Characters in unibyte strings are always treated by bidi.c as
21483 strong LTR. */
21484 if (!STRING_MULTIBYTE (object)
21485 /* When we are loading loadup.el, the character property
21486 tables needed for bidi iteration are not yet
21487 available. */
21488 || redisplay__inhibit_bidi)
21489 return Qnil;
21491 validate_subarray (object, from, to, SCHARS (object), &from_pos, &to_pos);
21492 if (from_pos >= SCHARS (object))
21493 return Qnil;
21495 /* Set up the bidi iterator. */
21496 itb_data = bidi_shelve_cache ();
21497 itb.paragraph_dir = NEUTRAL_DIR;
21498 itb.string.lstring = object;
21499 itb.string.s = NULL;
21500 itb.string.schars = SCHARS (object);
21501 itb.string.bufpos = 0;
21502 itb.string.from_disp_str = false;
21503 itb.string.unibyte = false;
21504 itb.w = w;
21505 bidi_init_it (0, 0, frame_window_p, &itb);
21507 else
21509 /* Nothing this fancy can happen in unibyte buffers, or in a
21510 buffer that disabled reordering, or if FROM is at EOB. */
21511 if (NILP (BVAR (buf, bidi_display_reordering))
21512 || NILP (BVAR (buf, enable_multibyte_characters))
21513 /* When we are loading loadup.el, the character property
21514 tables needed for bidi iteration are not yet
21515 available. */
21516 || redisplay__inhibit_bidi)
21517 return Qnil;
21519 set_buffer_temp (buf);
21520 validate_region (&from, &to);
21521 from_pos = XINT (from);
21522 to_pos = XINT (to);
21523 if (from_pos >= ZV)
21524 return Qnil;
21526 /* Set up the bidi iterator. */
21527 itb_data = bidi_shelve_cache ();
21528 from_bpos = CHAR_TO_BYTE (from_pos);
21529 if (from_pos == BEGV)
21531 itb.charpos = BEGV;
21532 itb.bytepos = BEGV_BYTE;
21534 else if (FETCH_CHAR (from_bpos - 1) == '\n')
21536 itb.charpos = from_pos;
21537 itb.bytepos = from_bpos;
21539 else
21540 itb.charpos = find_newline_no_quit (from_pos, CHAR_TO_BYTE (from_pos),
21541 -1, &itb.bytepos);
21542 itb.paragraph_dir = NEUTRAL_DIR;
21543 itb.string.s = NULL;
21544 itb.string.lstring = Qnil;
21545 itb.string.bufpos = 0;
21546 itb.string.from_disp_str = false;
21547 itb.string.unibyte = false;
21548 itb.w = w;
21549 bidi_init_it (itb.charpos, itb.bytepos, frame_window_p, &itb);
21552 ptrdiff_t found;
21553 do {
21554 /* For the purposes of this function, the actual base direction of
21555 the paragraph doesn't matter, so just set it to L2R. */
21556 bidi_paragraph_init (L2R, &itb, false);
21557 while ((found = bidi_find_first_overridden (&itb)) < from_pos)
21559 } while (found == ZV && itb.ch == '\n' && itb.charpos < to_pos);
21561 bidi_unshelve_cache (itb_data, false);
21562 set_buffer_temp (old);
21564 return (from_pos <= found && found < to_pos) ? make_number (found) : Qnil;
21567 DEFUN ("move-point-visually", Fmove_point_visually,
21568 Smove_point_visually, 1, 1, 0,
21569 doc: /* Move point in the visual order in the specified DIRECTION.
21570 DIRECTION can be 1, meaning move to the right, or -1, which moves to the
21571 left.
21573 Value is the new character position of point. */)
21574 (Lisp_Object direction)
21576 struct window *w = XWINDOW (selected_window);
21577 struct buffer *b = XBUFFER (w->contents);
21578 struct glyph_row *row;
21579 int dir;
21580 Lisp_Object paragraph_dir;
21582 #define ROW_GLYPH_NEWLINE_P(ROW,GLYPH) \
21583 (!(ROW)->continued_p \
21584 && NILP ((GLYPH)->object) \
21585 && (GLYPH)->type == CHAR_GLYPH \
21586 && (GLYPH)->u.ch == ' ' \
21587 && (GLYPH)->charpos >= 0 \
21588 && !(GLYPH)->avoid_cursor_p)
21590 CHECK_NUMBER (direction);
21591 dir = XINT (direction);
21592 if (dir > 0)
21593 dir = 1;
21594 else
21595 dir = -1;
21597 /* If current matrix is up-to-date, we can use the information
21598 recorded in the glyphs, at least as long as the goal is on the
21599 screen. */
21600 if (w->window_end_valid
21601 && !windows_or_buffers_changed
21602 && b
21603 && !b->clip_changed
21604 && !b->prevent_redisplay_optimizations_p
21605 && !window_outdated (w)
21606 /* We rely below on the cursor coordinates to be up to date, but
21607 we cannot trust them if some command moved point since the
21608 last complete redisplay. */
21609 && w->last_point == BUF_PT (b)
21610 && w->cursor.vpos >= 0
21611 && w->cursor.vpos < w->current_matrix->nrows
21612 && (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos))->enabled_p)
21614 struct glyph *g = row->glyphs[TEXT_AREA];
21615 struct glyph *e = dir > 0 ? g + row->used[TEXT_AREA] : g - 1;
21616 struct glyph *gpt = g + w->cursor.hpos;
21618 for (g = gpt + dir; (dir > 0 ? g < e : g > e); g += dir)
21620 if (BUFFERP (g->object) && g->charpos != PT)
21622 SET_PT (g->charpos);
21623 w->cursor.vpos = -1;
21624 return make_number (PT);
21626 else if (!NILP (g->object) && !EQ (g->object, gpt->object))
21628 ptrdiff_t new_pos;
21630 if (BUFFERP (gpt->object))
21632 new_pos = PT;
21633 if ((gpt->resolved_level - row->reversed_p) % 2 == 0)
21634 new_pos += (row->reversed_p ? -dir : dir);
21635 else
21636 new_pos -= (row->reversed_p ? -dir : dir);
21638 else if (BUFFERP (g->object))
21639 new_pos = g->charpos;
21640 else
21641 break;
21642 SET_PT (new_pos);
21643 w->cursor.vpos = -1;
21644 return make_number (PT);
21646 else if (ROW_GLYPH_NEWLINE_P (row, g))
21648 /* Glyphs inserted at the end of a non-empty line for
21649 positioning the cursor have zero charpos, so we must
21650 deduce the value of point by other means. */
21651 if (g->charpos > 0)
21652 SET_PT (g->charpos);
21653 else if (row->ends_at_zv_p && PT != ZV)
21654 SET_PT (ZV);
21655 else if (PT != MATRIX_ROW_END_CHARPOS (row) - 1)
21656 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
21657 else
21658 break;
21659 w->cursor.vpos = -1;
21660 return make_number (PT);
21663 if (g == e || NILP (g->object))
21665 if (row->truncated_on_left_p || row->truncated_on_right_p)
21666 goto simulate_display;
21667 if (!row->reversed_p)
21668 row += dir;
21669 else
21670 row -= dir;
21671 if (row < MATRIX_FIRST_TEXT_ROW (w->current_matrix)
21672 || row > MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
21673 goto simulate_display;
21675 if (dir > 0)
21677 if (row->reversed_p && !row->continued_p)
21679 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
21680 w->cursor.vpos = -1;
21681 return make_number (PT);
21683 g = row->glyphs[TEXT_AREA];
21684 e = g + row->used[TEXT_AREA];
21685 for ( ; g < e; g++)
21687 if (BUFFERP (g->object)
21688 /* Empty lines have only one glyph, which stands
21689 for the newline, and whose charpos is the
21690 buffer position of the newline. */
21691 || ROW_GLYPH_NEWLINE_P (row, g)
21692 /* When the buffer ends in a newline, the line at
21693 EOB also has one glyph, but its charpos is -1. */
21694 || (row->ends_at_zv_p
21695 && !row->reversed_p
21696 && NILP (g->object)
21697 && g->type == CHAR_GLYPH
21698 && g->u.ch == ' '))
21700 if (g->charpos > 0)
21701 SET_PT (g->charpos);
21702 else if (!row->reversed_p
21703 && row->ends_at_zv_p
21704 && PT != ZV)
21705 SET_PT (ZV);
21706 else
21707 continue;
21708 w->cursor.vpos = -1;
21709 return make_number (PT);
21713 else
21715 if (!row->reversed_p && !row->continued_p)
21717 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
21718 w->cursor.vpos = -1;
21719 return make_number (PT);
21721 e = row->glyphs[TEXT_AREA];
21722 g = e + row->used[TEXT_AREA] - 1;
21723 for ( ; g >= e; g--)
21725 if (BUFFERP (g->object)
21726 || (ROW_GLYPH_NEWLINE_P (row, g)
21727 && g->charpos > 0)
21728 /* Empty R2L lines on GUI frames have the buffer
21729 position of the newline stored in the stretch
21730 glyph. */
21731 || g->type == STRETCH_GLYPH
21732 || (row->ends_at_zv_p
21733 && row->reversed_p
21734 && NILP (g->object)
21735 && g->type == CHAR_GLYPH
21736 && g->u.ch == ' '))
21738 if (g->charpos > 0)
21739 SET_PT (g->charpos);
21740 else if (row->reversed_p
21741 && row->ends_at_zv_p
21742 && PT != ZV)
21743 SET_PT (ZV);
21744 else
21745 continue;
21746 w->cursor.vpos = -1;
21747 return make_number (PT);
21754 simulate_display:
21756 /* If we wind up here, we failed to move by using the glyphs, so we
21757 need to simulate display instead. */
21759 if (b)
21760 paragraph_dir = Fcurrent_bidi_paragraph_direction (w->contents);
21761 else
21762 paragraph_dir = Qleft_to_right;
21763 if (EQ (paragraph_dir, Qright_to_left))
21764 dir = -dir;
21765 if (PT <= BEGV && dir < 0)
21766 xsignal0 (Qbeginning_of_buffer);
21767 else if (PT >= ZV && dir > 0)
21768 xsignal0 (Qend_of_buffer);
21769 else
21771 struct text_pos pt;
21772 struct it it;
21773 int pt_x, target_x, pixel_width, pt_vpos;
21774 bool at_eol_p;
21775 bool overshoot_expected = false;
21776 bool target_is_eol_p = false;
21778 /* Setup the arena. */
21779 SET_TEXT_POS (pt, PT, PT_BYTE);
21780 start_display (&it, w, pt);
21781 /* When lines are truncated, we could be called with point
21782 outside of the windows edges, in which case move_it_*
21783 functions either prematurely stop at window's edge or jump to
21784 the next screen line, whereas we rely below on our ability to
21785 reach point, in order to start from its X coordinate. So we
21786 need to disregard the window's horizontal extent in that case. */
21787 if (it.line_wrap == TRUNCATE)
21788 it.last_visible_x = INFINITY;
21790 if (it.cmp_it.id < 0
21791 && it.method == GET_FROM_STRING
21792 && it.area == TEXT_AREA
21793 && it.string_from_display_prop_p
21794 && (it.sp > 0 && it.stack[it.sp - 1].method == GET_FROM_BUFFER))
21795 overshoot_expected = true;
21797 /* Find the X coordinate of point. We start from the beginning
21798 of this or previous line to make sure we are before point in
21799 the logical order (since the move_it_* functions can only
21800 move forward). */
21801 reseat:
21802 reseat_at_previous_visible_line_start (&it);
21803 it.current_x = it.hpos = it.current_y = it.vpos = 0;
21804 if (IT_CHARPOS (it) != PT)
21806 move_it_to (&it, overshoot_expected ? PT - 1 : PT,
21807 -1, -1, -1, MOVE_TO_POS);
21808 /* If we missed point because the character there is
21809 displayed out of a display vector that has more than one
21810 glyph, retry expecting overshoot. */
21811 if (it.method == GET_FROM_DISPLAY_VECTOR
21812 && it.current.dpvec_index > 0
21813 && !overshoot_expected)
21815 overshoot_expected = true;
21816 goto reseat;
21818 else if (IT_CHARPOS (it) != PT && !overshoot_expected)
21819 move_it_in_display_line (&it, PT, -1, MOVE_TO_POS);
21821 pt_x = it.current_x;
21822 pt_vpos = it.vpos;
21823 if (dir > 0 || overshoot_expected)
21825 struct glyph_row *row = it.glyph_row;
21827 /* When point is at beginning of line, we don't have
21828 information about the glyph there loaded into struct
21829 it. Calling get_next_display_element fixes that. */
21830 if (pt_x == 0)
21831 get_next_display_element (&it);
21832 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
21833 it.glyph_row = NULL;
21834 PRODUCE_GLYPHS (&it); /* compute it.pixel_width */
21835 it.glyph_row = row;
21836 /* PRODUCE_GLYPHS advances it.current_x, so we must restore
21837 it, lest it will become out of sync with it's buffer
21838 position. */
21839 it.current_x = pt_x;
21841 else
21842 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
21843 pixel_width = it.pixel_width;
21844 if (overshoot_expected && at_eol_p)
21845 pixel_width = 0;
21846 else if (pixel_width <= 0)
21847 pixel_width = 1;
21849 /* If there's a display string (or something similar) at point,
21850 we are actually at the glyph to the left of point, so we need
21851 to correct the X coordinate. */
21852 if (overshoot_expected)
21854 if (it.bidi_p)
21855 pt_x += pixel_width * it.bidi_it.scan_dir;
21856 else
21857 pt_x += pixel_width;
21860 /* Compute target X coordinate, either to the left or to the
21861 right of point. On TTY frames, all characters have the same
21862 pixel width of 1, so we can use that. On GUI frames we don't
21863 have an easy way of getting at the pixel width of the
21864 character to the left of point, so we use a different method
21865 of getting to that place. */
21866 if (dir > 0)
21867 target_x = pt_x + pixel_width;
21868 else
21869 target_x = pt_x - (!FRAME_WINDOW_P (it.f)) * pixel_width;
21871 /* Target X coordinate could be one line above or below the line
21872 of point, in which case we need to adjust the target X
21873 coordinate. Also, if moving to the left, we need to begin at
21874 the left edge of the point's screen line. */
21875 if (dir < 0)
21877 if (pt_x > 0)
21879 start_display (&it, w, pt);
21880 if (it.line_wrap == TRUNCATE)
21881 it.last_visible_x = INFINITY;
21882 reseat_at_previous_visible_line_start (&it);
21883 it.current_x = it.current_y = it.hpos = 0;
21884 if (pt_vpos != 0)
21885 move_it_by_lines (&it, pt_vpos);
21887 else
21889 move_it_by_lines (&it, -1);
21890 target_x = it.last_visible_x - !FRAME_WINDOW_P (it.f);
21891 target_is_eol_p = true;
21892 /* Under word-wrap, we don't know the x coordinate of
21893 the last character displayed on the previous line,
21894 which immediately precedes the wrap point. To find
21895 out its x coordinate, we try moving to the right
21896 margin of the window, which will stop at the wrap
21897 point, and then reset target_x to point at the
21898 character that precedes the wrap point. This is not
21899 needed on GUI frames, because (see below) there we
21900 move from the left margin one grapheme cluster at a
21901 time, and stop when we hit the wrap point. */
21902 if (!FRAME_WINDOW_P (it.f) && it.line_wrap == WORD_WRAP)
21904 void *it_data = NULL;
21905 struct it it2;
21907 SAVE_IT (it2, it, it_data);
21908 move_it_in_display_line_to (&it, ZV, target_x,
21909 MOVE_TO_POS | MOVE_TO_X);
21910 /* If we arrived at target_x, that _is_ the last
21911 character on the previous line. */
21912 if (it.current_x != target_x)
21913 target_x = it.current_x - 1;
21914 RESTORE_IT (&it, &it2, it_data);
21918 else
21920 if (at_eol_p
21921 || (target_x >= it.last_visible_x
21922 && it.line_wrap != TRUNCATE))
21924 if (pt_x > 0)
21925 move_it_by_lines (&it, 0);
21926 move_it_by_lines (&it, 1);
21927 target_x = 0;
21931 /* Move to the target X coordinate. */
21932 /* On GUI frames, as we don't know the X coordinate of the
21933 character to the left of point, moving point to the left
21934 requires walking, one grapheme cluster at a time, until we
21935 find ourself at a place immediately to the left of the
21936 character at point. */
21937 if (FRAME_WINDOW_P (it.f) && dir < 0)
21939 struct text_pos new_pos;
21940 enum move_it_result rc = MOVE_X_REACHED;
21942 if (it.current_x == 0)
21943 get_next_display_element (&it);
21944 if (it.what == IT_COMPOSITION)
21946 new_pos.charpos = it.cmp_it.charpos;
21947 new_pos.bytepos = -1;
21949 else
21950 new_pos = it.current.pos;
21952 while (it.current_x + it.pixel_width <= target_x
21953 && (rc == MOVE_X_REACHED
21954 /* Under word-wrap, move_it_in_display_line_to
21955 stops at correct coordinates, but sometimes
21956 returns MOVE_POS_MATCH_OR_ZV. */
21957 || (it.line_wrap == WORD_WRAP
21958 && rc == MOVE_POS_MATCH_OR_ZV)))
21960 int new_x = it.current_x + it.pixel_width;
21962 /* For composed characters, we want the position of the
21963 first character in the grapheme cluster (usually, the
21964 composition's base character), whereas it.current
21965 might give us the position of the _last_ one, e.g. if
21966 the composition is rendered in reverse due to bidi
21967 reordering. */
21968 if (it.what == IT_COMPOSITION)
21970 new_pos.charpos = it.cmp_it.charpos;
21971 new_pos.bytepos = -1;
21973 else
21974 new_pos = it.current.pos;
21975 if (new_x == it.current_x)
21976 new_x++;
21977 rc = move_it_in_display_line_to (&it, ZV, new_x,
21978 MOVE_TO_POS | MOVE_TO_X);
21979 if (ITERATOR_AT_END_OF_LINE_P (&it) && !target_is_eol_p)
21980 break;
21982 /* The previous position we saw in the loop is the one we
21983 want. */
21984 if (new_pos.bytepos == -1)
21985 new_pos.bytepos = CHAR_TO_BYTE (new_pos.charpos);
21986 it.current.pos = new_pos;
21988 else if (it.current_x != target_x)
21989 move_it_in_display_line_to (&it, ZV, target_x, MOVE_TO_POS | MOVE_TO_X);
21991 /* If we ended up in a display string that covers point, move to
21992 buffer position to the right in the visual order. */
21993 if (dir > 0)
21995 while (IT_CHARPOS (it) == PT)
21997 set_iterator_to_next (&it, false);
21998 if (!get_next_display_element (&it))
21999 break;
22003 /* Move point to that position. */
22004 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
22007 return make_number (PT);
22009 #undef ROW_GLYPH_NEWLINE_P
22012 DEFUN ("bidi-resolved-levels", Fbidi_resolved_levels,
22013 Sbidi_resolved_levels, 0, 1, 0,
22014 doc: /* Return the resolved bidirectional levels of characters at VPOS.
22016 The resolved levels are produced by the Emacs bidi reordering engine
22017 that implements the UBA, the Unicode Bidirectional Algorithm. Please
22018 read the Unicode Standard Annex 9 (UAX#9) for background information
22019 about these levels.
22021 VPOS is the zero-based number of the current window's screen line
22022 for which to produce the resolved levels. If VPOS is nil or omitted,
22023 it defaults to the screen line of point. If the window displays a
22024 header line, VPOS of zero will report on the header line, and first
22025 line of text in the window will have VPOS of 1.
22027 Value is an array of resolved levels, indexed by glyph number.
22028 Glyphs are numbered from zero starting from the beginning of the
22029 screen line, i.e. the left edge of the window for left-to-right lines
22030 and from the right edge for right-to-left lines. The resolved levels
22031 are produced only for the window's text area; text in display margins
22032 is not included.
22034 If the selected window's display is not up-to-date, or if the specified
22035 screen line does not display text, this function returns nil. It is
22036 highly recommended to bind this function to some simple key, like F8,
22037 in order to avoid these problems.
22039 This function exists mainly for testing the correctness of the
22040 Emacs UBA implementation, in particular with the test suite. */)
22041 (Lisp_Object vpos)
22043 struct window *w = XWINDOW (selected_window);
22044 struct buffer *b = XBUFFER (w->contents);
22045 int nrow;
22046 struct glyph_row *row;
22048 if (NILP (vpos))
22050 int d1, d2, d3, d4, d5;
22052 pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &nrow);
22054 else
22056 CHECK_NUMBER_COERCE_MARKER (vpos);
22057 nrow = XINT (vpos);
22060 /* We require up-to-date glyph matrix for this window. */
22061 if (w->window_end_valid
22062 && !windows_or_buffers_changed
22063 && b
22064 && !b->clip_changed
22065 && !b->prevent_redisplay_optimizations_p
22066 && !window_outdated (w)
22067 && nrow >= 0
22068 && nrow < w->current_matrix->nrows
22069 && (row = MATRIX_ROW (w->current_matrix, nrow))->enabled_p
22070 && MATRIX_ROW_DISPLAYS_TEXT_P (row))
22072 struct glyph *g, *e, *g1;
22073 int nglyphs, i;
22074 Lisp_Object levels;
22076 if (!row->reversed_p) /* Left-to-right glyph row. */
22078 g = g1 = row->glyphs[TEXT_AREA];
22079 e = g + row->used[TEXT_AREA];
22081 /* Skip over glyphs at the start of the row that was
22082 generated by redisplay for its own needs. */
22083 while (g < e
22084 && NILP (g->object)
22085 && g->charpos < 0)
22086 g++;
22087 g1 = g;
22089 /* Count the "interesting" glyphs in this row. */
22090 for (nglyphs = 0; g < e && !NILP (g->object); g++)
22091 nglyphs++;
22093 /* Create and fill the array. */
22094 levels = make_uninit_vector (nglyphs);
22095 for (i = 0; g1 < g; i++, g1++)
22096 ASET (levels, i, make_number (g1->resolved_level));
22098 else /* Right-to-left glyph row. */
22100 g = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
22101 e = row->glyphs[TEXT_AREA] - 1;
22102 while (g > e
22103 && NILP (g->object)
22104 && g->charpos < 0)
22105 g--;
22106 g1 = g;
22107 for (nglyphs = 0; g > e && !NILP (g->object); g--)
22108 nglyphs++;
22109 levels = make_uninit_vector (nglyphs);
22110 for (i = 0; g1 > g; i++, g1--)
22111 ASET (levels, i, make_number (g1->resolved_level));
22113 return levels;
22115 else
22116 return Qnil;
22121 /***********************************************************************
22122 Menu Bar
22123 ***********************************************************************/
22125 /* Redisplay the menu bar in the frame for window W.
22127 The menu bar of X frames that don't have X toolkit support is
22128 displayed in a special window W->frame->menu_bar_window.
22130 The menu bar of terminal frames is treated specially as far as
22131 glyph matrices are concerned. Menu bar lines are not part of
22132 windows, so the update is done directly on the frame matrix rows
22133 for the menu bar. */
22135 static void
22136 display_menu_bar (struct window *w)
22138 struct frame *f = XFRAME (WINDOW_FRAME (w));
22139 struct it it;
22140 Lisp_Object items;
22141 int i;
22143 /* Don't do all this for graphical frames. */
22144 #ifdef HAVE_NTGUI
22145 if (FRAME_W32_P (f))
22146 return;
22147 #endif
22148 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
22149 if (FRAME_X_P (f))
22150 return;
22151 #endif
22153 #ifdef HAVE_NS
22154 if (FRAME_NS_P (f))
22155 return;
22156 #endif /* HAVE_NS */
22158 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
22159 eassert (!FRAME_WINDOW_P (f));
22160 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
22161 it.first_visible_x = 0;
22162 it.last_visible_x = FRAME_PIXEL_WIDTH (f);
22163 #elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
22164 if (FRAME_WINDOW_P (f))
22166 /* Menu bar lines are displayed in the desired matrix of the
22167 dummy window menu_bar_window. */
22168 struct window *menu_w;
22169 menu_w = XWINDOW (f->menu_bar_window);
22170 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
22171 MENU_FACE_ID);
22172 it.first_visible_x = 0;
22173 it.last_visible_x = FRAME_PIXEL_WIDTH (f);
22175 else
22176 #endif /* not USE_X_TOOLKIT and not USE_GTK */
22178 /* This is a TTY frame, i.e. character hpos/vpos are used as
22179 pixel x/y. */
22180 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
22181 MENU_FACE_ID);
22182 it.first_visible_x = 0;
22183 it.last_visible_x = FRAME_COLS (f);
22186 /* FIXME: This should be controlled by a user option. See the
22187 comments in redisplay_tool_bar and display_mode_line about
22188 this. */
22189 it.paragraph_embedding = L2R;
22191 /* Clear all rows of the menu bar. */
22192 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
22194 struct glyph_row *row = it.glyph_row + i;
22195 clear_glyph_row (row);
22196 row->enabled_p = true;
22197 row->full_width_p = true;
22198 row->reversed_p = false;
22201 /* Display all items of the menu bar. */
22202 items = FRAME_MENU_BAR_ITEMS (it.f);
22203 for (i = 0; i < ASIZE (items); i += 4)
22205 Lisp_Object string;
22207 /* Stop at nil string. */
22208 string = AREF (items, i + 1);
22209 if (NILP (string))
22210 break;
22212 /* Remember where item was displayed. */
22213 ASET (items, i + 3, make_number (it.hpos));
22215 /* Display the item, pad with one space. */
22216 if (it.current_x < it.last_visible_x)
22217 display_string (NULL, string, Qnil, 0, 0, &it,
22218 SCHARS (string) + 1, 0, 0, -1);
22221 /* Fill out the line with spaces. */
22222 if (it.current_x < it.last_visible_x)
22223 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
22225 /* Compute the total height of the lines. */
22226 compute_line_metrics (&it);
22229 /* Deep copy of a glyph row, including the glyphs. */
22230 static void
22231 deep_copy_glyph_row (struct glyph_row *to, struct glyph_row *from)
22233 struct glyph *pointers[1 + LAST_AREA];
22234 int to_used = to->used[TEXT_AREA];
22236 /* Save glyph pointers of TO. */
22237 memcpy (pointers, to->glyphs, sizeof to->glyphs);
22239 /* Do a structure assignment. */
22240 *to = *from;
22242 /* Restore original glyph pointers of TO. */
22243 memcpy (to->glyphs, pointers, sizeof to->glyphs);
22245 /* Copy the glyphs. */
22246 memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA],
22247 min (from->used[TEXT_AREA], to_used) * sizeof (struct glyph));
22249 /* If we filled only part of the TO row, fill the rest with
22250 space_glyph (which will display as empty space). */
22251 if (to_used > from->used[TEXT_AREA])
22252 fill_up_frame_row_with_spaces (to, to_used);
22255 /* Display one menu item on a TTY, by overwriting the glyphs in the
22256 frame F's desired glyph matrix with glyphs produced from the menu
22257 item text. Called from term.c to display TTY drop-down menus one
22258 item at a time.
22260 ITEM_TEXT is the menu item text as a C string.
22262 FACE_ID is the face ID to be used for this menu item. FACE_ID
22263 could specify one of 3 faces: a face for an enabled item, a face
22264 for a disabled item, or a face for a selected item.
22266 X and Y are coordinates of the first glyph in the frame's desired
22267 matrix to be overwritten by the menu item. Since this is a TTY, Y
22268 is the zero-based number of the glyph row and X is the zero-based
22269 glyph number in the row, starting from left, where to start
22270 displaying the item.
22272 SUBMENU means this menu item drops down a submenu, which
22273 should be indicated by displaying a proper visual cue after the
22274 item text. */
22276 void
22277 display_tty_menu_item (const char *item_text, int width, int face_id,
22278 int x, int y, bool submenu)
22280 struct it it;
22281 struct frame *f = SELECTED_FRAME ();
22282 struct window *w = XWINDOW (f->selected_window);
22283 struct glyph_row *row;
22284 size_t item_len = strlen (item_text);
22286 eassert (FRAME_TERMCAP_P (f));
22288 /* Don't write beyond the matrix's last row. This can happen for
22289 TTY screens that are not high enough to show the entire menu.
22290 (This is actually a bit of defensive programming, as
22291 tty_menu_display already limits the number of menu items to one
22292 less than the number of screen lines.) */
22293 if (y >= f->desired_matrix->nrows)
22294 return;
22296 init_iterator (&it, w, -1, -1, f->desired_matrix->rows + y, MENU_FACE_ID);
22297 it.first_visible_x = 0;
22298 it.last_visible_x = FRAME_COLS (f) - 1;
22299 row = it.glyph_row;
22300 /* Start with the row contents from the current matrix. */
22301 deep_copy_glyph_row (row, f->current_matrix->rows + y);
22302 bool saved_width = row->full_width_p;
22303 row->full_width_p = true;
22304 bool saved_reversed = row->reversed_p;
22305 row->reversed_p = false;
22306 row->enabled_p = true;
22308 /* Arrange for the menu item glyphs to start at (X,Y) and have the
22309 desired face. */
22310 eassert (x < f->desired_matrix->matrix_w);
22311 it.current_x = it.hpos = x;
22312 it.current_y = it.vpos = y;
22313 int saved_used = row->used[TEXT_AREA];
22314 bool saved_truncated = row->truncated_on_right_p;
22315 row->used[TEXT_AREA] = x;
22316 it.face_id = face_id;
22317 it.line_wrap = TRUNCATE;
22319 /* FIXME: This should be controlled by a user option. See the
22320 comments in redisplay_tool_bar and display_mode_line about this.
22321 Also, if paragraph_embedding could ever be R2L, changes will be
22322 needed to avoid shifting to the right the row characters in
22323 term.c:append_glyph. */
22324 it.paragraph_embedding = L2R;
22326 /* Pad with a space on the left. */
22327 display_string (" ", Qnil, Qnil, 0, 0, &it, 1, 0, FRAME_COLS (f) - 1, -1);
22328 width--;
22329 /* Display the menu item, pad with spaces to WIDTH. */
22330 if (submenu)
22332 display_string (item_text, Qnil, Qnil, 0, 0, &it,
22333 item_len, 0, FRAME_COLS (f) - 1, -1);
22334 width -= item_len;
22335 /* Indicate with " >" that there's a submenu. */
22336 display_string (" >", Qnil, Qnil, 0, 0, &it, width, 0,
22337 FRAME_COLS (f) - 1, -1);
22339 else
22340 display_string (item_text, Qnil, Qnil, 0, 0, &it,
22341 width, 0, FRAME_COLS (f) - 1, -1);
22343 row->used[TEXT_AREA] = max (saved_used, row->used[TEXT_AREA]);
22344 row->truncated_on_right_p = saved_truncated;
22345 row->hash = row_hash (row);
22346 row->full_width_p = saved_width;
22347 row->reversed_p = saved_reversed;
22350 /***********************************************************************
22351 Mode Line
22352 ***********************************************************************/
22354 /* Redisplay mode lines in the window tree whose root is WINDOW.
22355 If FORCE, redisplay mode lines unconditionally.
22356 Otherwise, redisplay only mode lines that are garbaged. Value is
22357 the number of windows whose mode lines were redisplayed. */
22359 static int
22360 redisplay_mode_lines (Lisp_Object window, bool force)
22362 int nwindows = 0;
22364 while (!NILP (window))
22366 struct window *w = XWINDOW (window);
22368 if (WINDOWP (w->contents))
22369 nwindows += redisplay_mode_lines (w->contents, force);
22370 else if (force
22371 || FRAME_GARBAGED_P (XFRAME (w->frame))
22372 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
22374 struct text_pos lpoint;
22375 struct buffer *old = current_buffer;
22377 /* Set the window's buffer for the mode line display. */
22378 SET_TEXT_POS (lpoint, PT, PT_BYTE);
22379 set_buffer_internal_1 (XBUFFER (w->contents));
22381 /* Point refers normally to the selected window. For any
22382 other window, set up appropriate value. */
22383 if (!EQ (window, selected_window))
22385 struct text_pos pt;
22387 CLIP_TEXT_POS_FROM_MARKER (pt, w->pointm);
22388 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
22391 /* Display mode lines. */
22392 clear_glyph_matrix (w->desired_matrix);
22393 if (display_mode_lines (w))
22394 ++nwindows;
22396 /* Restore old settings. */
22397 set_buffer_internal_1 (old);
22398 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
22401 window = w->next;
22404 return nwindows;
22408 /* Display the mode and/or header line of window W. Value is the
22409 sum number of mode lines and header lines displayed. */
22411 static int
22412 display_mode_lines (struct window *w)
22414 Lisp_Object old_selected_window = selected_window;
22415 Lisp_Object old_selected_frame = selected_frame;
22416 Lisp_Object new_frame = w->frame;
22417 Lisp_Object old_frame_selected_window = XFRAME (new_frame)->selected_window;
22418 int n = 0;
22420 selected_frame = new_frame;
22421 /* FIXME: If we were to allow the mode-line's computation changing the buffer
22422 or window's point, then we'd need select_window_1 here as well. */
22423 XSETWINDOW (selected_window, w);
22424 XFRAME (new_frame)->selected_window = selected_window;
22426 /* These will be set while the mode line specs are processed. */
22427 line_number_displayed = false;
22428 w->column_number_displayed = -1;
22430 if (WINDOW_WANTS_MODELINE_P (w))
22432 struct window *sel_w = XWINDOW (old_selected_window);
22434 /* Select mode line face based on the real selected window. */
22435 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
22436 BVAR (current_buffer, mode_line_format));
22437 ++n;
22440 if (WINDOW_WANTS_HEADER_LINE_P (w))
22442 display_mode_line (w, HEADER_LINE_FACE_ID,
22443 BVAR (current_buffer, header_line_format));
22444 ++n;
22447 XFRAME (new_frame)->selected_window = old_frame_selected_window;
22448 selected_frame = old_selected_frame;
22449 selected_window = old_selected_window;
22450 if (n > 0)
22451 w->must_be_updated_p = true;
22452 return n;
22456 /* Display mode or header line of window W. FACE_ID specifies which
22457 line to display; it is either MODE_LINE_FACE_ID or
22458 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
22459 display. Value is the pixel height of the mode/header line
22460 displayed. */
22462 static int
22463 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
22465 struct it it;
22466 struct face *face;
22467 ptrdiff_t count = SPECPDL_INDEX ();
22469 init_iterator (&it, w, -1, -1, NULL, face_id);
22470 /* Don't extend on a previously drawn mode-line.
22471 This may happen if called from pos_visible_p. */
22472 it.glyph_row->enabled_p = false;
22473 prepare_desired_row (w, it.glyph_row, true);
22475 it.glyph_row->mode_line_p = true;
22477 /* FIXME: This should be controlled by a user option. But
22478 supporting such an option is not trivial, since the mode line is
22479 made up of many separate strings. */
22480 it.paragraph_embedding = L2R;
22482 record_unwind_protect (unwind_format_mode_line,
22483 format_mode_line_unwind_data (NULL, NULL,
22484 Qnil, false));
22486 mode_line_target = MODE_LINE_DISPLAY;
22488 /* Temporarily make frame's keyboard the current kboard so that
22489 kboard-local variables in the mode_line_format will get the right
22490 values. */
22491 push_kboard (FRAME_KBOARD (it.f));
22492 record_unwind_save_match_data ();
22493 display_mode_element (&it, 0, 0, 0, format, Qnil, false);
22494 pop_kboard ();
22496 unbind_to (count, Qnil);
22498 /* Fill up with spaces. */
22499 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
22501 compute_line_metrics (&it);
22502 it.glyph_row->full_width_p = true;
22503 it.glyph_row->continued_p = false;
22504 it.glyph_row->truncated_on_left_p = false;
22505 it.glyph_row->truncated_on_right_p = false;
22507 /* Make a 3D mode-line have a shadow at its right end. */
22508 face = FACE_FROM_ID (it.f, face_id);
22509 extend_face_to_end_of_line (&it);
22510 if (face->box != FACE_NO_BOX)
22512 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
22513 + it.glyph_row->used[TEXT_AREA] - 1);
22514 last->right_box_line_p = true;
22517 return it.glyph_row->height;
22520 /* Move element ELT in LIST to the front of LIST.
22521 Return the updated list. */
22523 static Lisp_Object
22524 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
22526 register Lisp_Object tail, prev;
22527 register Lisp_Object tem;
22529 tail = list;
22530 prev = Qnil;
22531 while (CONSP (tail))
22533 tem = XCAR (tail);
22535 if (EQ (elt, tem))
22537 /* Splice out the link TAIL. */
22538 if (NILP (prev))
22539 list = XCDR (tail);
22540 else
22541 Fsetcdr (prev, XCDR (tail));
22543 /* Now make it the first. */
22544 Fsetcdr (tail, list);
22545 return tail;
22547 else
22548 prev = tail;
22549 tail = XCDR (tail);
22550 QUIT;
22553 /* Not found--return unchanged LIST. */
22554 return list;
22557 /* Contribute ELT to the mode line for window IT->w. How it
22558 translates into text depends on its data type.
22560 IT describes the display environment in which we display, as usual.
22562 DEPTH is the depth in recursion. It is used to prevent
22563 infinite recursion here.
22565 FIELD_WIDTH is the number of characters the display of ELT should
22566 occupy in the mode line, and PRECISION is the maximum number of
22567 characters to display from ELT's representation. See
22568 display_string for details.
22570 Returns the hpos of the end of the text generated by ELT.
22572 PROPS is a property list to add to any string we encounter.
22574 If RISKY, remove (disregard) any properties in any string
22575 we encounter, and ignore :eval and :propertize.
22577 The global variable `mode_line_target' determines whether the
22578 output is passed to `store_mode_line_noprop',
22579 `store_mode_line_string', or `display_string'. */
22581 static int
22582 display_mode_element (struct it *it, int depth, int field_width, int precision,
22583 Lisp_Object elt, Lisp_Object props, bool risky)
22585 int n = 0, field, prec;
22586 bool literal = false;
22588 tail_recurse:
22589 if (depth > 100)
22590 elt = build_string ("*too-deep*");
22592 depth++;
22594 switch (XTYPE (elt))
22596 case Lisp_String:
22598 /* A string: output it and check for %-constructs within it. */
22599 unsigned char c;
22600 ptrdiff_t offset = 0;
22602 if (SCHARS (elt) > 0
22603 && (!NILP (props) || risky))
22605 Lisp_Object oprops, aelt;
22606 oprops = Ftext_properties_at (make_number (0), elt);
22608 /* If the starting string's properties are not what
22609 we want, translate the string. Also, if the string
22610 is risky, do that anyway. */
22612 if (NILP (Fequal (props, oprops)) || risky)
22614 /* If the starting string has properties,
22615 merge the specified ones onto the existing ones. */
22616 if (! NILP (oprops) && !risky)
22618 Lisp_Object tem;
22620 oprops = Fcopy_sequence (oprops);
22621 tem = props;
22622 while (CONSP (tem))
22624 oprops = Fplist_put (oprops, XCAR (tem),
22625 XCAR (XCDR (tem)));
22626 tem = XCDR (XCDR (tem));
22628 props = oprops;
22631 aelt = Fassoc (elt, mode_line_proptrans_alist);
22632 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
22634 /* AELT is what we want. Move it to the front
22635 without consing. */
22636 elt = XCAR (aelt);
22637 mode_line_proptrans_alist
22638 = move_elt_to_front (aelt, mode_line_proptrans_alist);
22640 else
22642 Lisp_Object tem;
22644 /* If AELT has the wrong props, it is useless.
22645 so get rid of it. */
22646 if (! NILP (aelt))
22647 mode_line_proptrans_alist
22648 = Fdelq (aelt, mode_line_proptrans_alist);
22650 elt = Fcopy_sequence (elt);
22651 Fset_text_properties (make_number (0), Flength (elt),
22652 props, elt);
22653 /* Add this item to mode_line_proptrans_alist. */
22654 mode_line_proptrans_alist
22655 = Fcons (Fcons (elt, props),
22656 mode_line_proptrans_alist);
22657 /* Truncate mode_line_proptrans_alist
22658 to at most 50 elements. */
22659 tem = Fnthcdr (make_number (50),
22660 mode_line_proptrans_alist);
22661 if (! NILP (tem))
22662 XSETCDR (tem, Qnil);
22667 offset = 0;
22669 if (literal)
22671 prec = precision - n;
22672 switch (mode_line_target)
22674 case MODE_LINE_NOPROP:
22675 case MODE_LINE_TITLE:
22676 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
22677 break;
22678 case MODE_LINE_STRING:
22679 n += store_mode_line_string (NULL, elt, true, 0, prec, Qnil);
22680 break;
22681 case MODE_LINE_DISPLAY:
22682 n += display_string (NULL, elt, Qnil, 0, 0, it,
22683 0, prec, 0, STRING_MULTIBYTE (elt));
22684 break;
22687 break;
22690 /* Handle the non-literal case. */
22692 while ((precision <= 0 || n < precision)
22693 && SREF (elt, offset) != 0
22694 && (mode_line_target != MODE_LINE_DISPLAY
22695 || it->current_x < it->last_visible_x))
22697 ptrdiff_t last_offset = offset;
22699 /* Advance to end of string or next format specifier. */
22700 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
22703 if (offset - 1 != last_offset)
22705 ptrdiff_t nchars, nbytes;
22707 /* Output to end of string or up to '%'. Field width
22708 is length of string. Don't output more than
22709 PRECISION allows us. */
22710 offset--;
22712 prec = c_string_width (SDATA (elt) + last_offset,
22713 offset - last_offset, precision - n,
22714 &nchars, &nbytes);
22716 switch (mode_line_target)
22718 case MODE_LINE_NOPROP:
22719 case MODE_LINE_TITLE:
22720 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
22721 break;
22722 case MODE_LINE_STRING:
22724 ptrdiff_t bytepos = last_offset;
22725 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
22726 ptrdiff_t endpos = (precision <= 0
22727 ? string_byte_to_char (elt, offset)
22728 : charpos + nchars);
22729 Lisp_Object mode_string
22730 = Fsubstring (elt, make_number (charpos),
22731 make_number (endpos));
22732 n += store_mode_line_string (NULL, mode_string, false,
22733 0, 0, Qnil);
22735 break;
22736 case MODE_LINE_DISPLAY:
22738 ptrdiff_t bytepos = last_offset;
22739 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
22741 if (precision <= 0)
22742 nchars = string_byte_to_char (elt, offset) - charpos;
22743 n += display_string (NULL, elt, Qnil, 0, charpos,
22744 it, 0, nchars, 0,
22745 STRING_MULTIBYTE (elt));
22747 break;
22750 else /* c == '%' */
22752 ptrdiff_t percent_position = offset;
22754 /* Get the specified minimum width. Zero means
22755 don't pad. */
22756 field = 0;
22757 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
22758 field = field * 10 + c - '0';
22760 /* Don't pad beyond the total padding allowed. */
22761 if (field_width - n > 0 && field > field_width - n)
22762 field = field_width - n;
22764 /* Note that either PRECISION <= 0 or N < PRECISION. */
22765 prec = precision - n;
22767 if (c == 'M')
22768 n += display_mode_element (it, depth, field, prec,
22769 Vglobal_mode_string, props,
22770 risky);
22771 else if (c != 0)
22773 bool multibyte;
22774 ptrdiff_t bytepos, charpos;
22775 const char *spec;
22776 Lisp_Object string;
22778 bytepos = percent_position;
22779 charpos = (STRING_MULTIBYTE (elt)
22780 ? string_byte_to_char (elt, bytepos)
22781 : bytepos);
22782 spec = decode_mode_spec (it->w, c, field, &string);
22783 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
22785 switch (mode_line_target)
22787 case MODE_LINE_NOPROP:
22788 case MODE_LINE_TITLE:
22789 n += store_mode_line_noprop (spec, field, prec);
22790 break;
22791 case MODE_LINE_STRING:
22793 Lisp_Object tem = build_string (spec);
22794 props = Ftext_properties_at (make_number (charpos), elt);
22795 /* Should only keep face property in props */
22796 n += store_mode_line_string (NULL, tem, false,
22797 field, prec, props);
22799 break;
22800 case MODE_LINE_DISPLAY:
22802 int nglyphs_before, nwritten;
22804 nglyphs_before = it->glyph_row->used[TEXT_AREA];
22805 nwritten = display_string (spec, string, elt,
22806 charpos, 0, it,
22807 field, prec, 0,
22808 multibyte);
22810 /* Assign to the glyphs written above the
22811 string where the `%x' came from, position
22812 of the `%'. */
22813 if (nwritten > 0)
22815 struct glyph *glyph
22816 = (it->glyph_row->glyphs[TEXT_AREA]
22817 + nglyphs_before);
22818 int i;
22820 for (i = 0; i < nwritten; ++i)
22822 glyph[i].object = elt;
22823 glyph[i].charpos = charpos;
22826 n += nwritten;
22829 break;
22832 else /* c == 0 */
22833 break;
22837 break;
22839 case Lisp_Symbol:
22840 /* A symbol: process the value of the symbol recursively
22841 as if it appeared here directly. Avoid error if symbol void.
22842 Special case: if value of symbol is a string, output the string
22843 literally. */
22845 register Lisp_Object tem;
22847 /* If the variable is not marked as risky to set
22848 then its contents are risky to use. */
22849 if (NILP (Fget (elt, Qrisky_local_variable)))
22850 risky = true;
22852 tem = Fboundp (elt);
22853 if (!NILP (tem))
22855 tem = Fsymbol_value (elt);
22856 /* If value is a string, output that string literally:
22857 don't check for % within it. */
22858 if (STRINGP (tem))
22859 literal = true;
22861 if (!EQ (tem, elt))
22863 /* Give up right away for nil or t. */
22864 elt = tem;
22865 goto tail_recurse;
22869 break;
22871 case Lisp_Cons:
22873 register Lisp_Object car, tem;
22875 /* A cons cell: five distinct cases.
22876 If first element is :eval or :propertize, do something special.
22877 If first element is a string or a cons, process all the elements
22878 and effectively concatenate them.
22879 If first element is a negative number, truncate displaying cdr to
22880 at most that many characters. If positive, pad (with spaces)
22881 to at least that many characters.
22882 If first element is a symbol, process the cadr or caddr recursively
22883 according to whether the symbol's value is non-nil or nil. */
22884 car = XCAR (elt);
22885 if (EQ (car, QCeval))
22887 /* An element of the form (:eval FORM) means evaluate FORM
22888 and use the result as mode line elements. */
22890 if (risky)
22891 break;
22893 if (CONSP (XCDR (elt)))
22895 Lisp_Object spec;
22896 spec = safe__eval (true, XCAR (XCDR (elt)));
22897 n += display_mode_element (it, depth, field_width - n,
22898 precision - n, spec, props,
22899 risky);
22902 else if (EQ (car, QCpropertize))
22904 /* An element of the form (:propertize ELT PROPS...)
22905 means display ELT but applying properties PROPS. */
22907 if (risky)
22908 break;
22910 if (CONSP (XCDR (elt)))
22911 n += display_mode_element (it, depth, field_width - n,
22912 precision - n, XCAR (XCDR (elt)),
22913 XCDR (XCDR (elt)), risky);
22915 else if (SYMBOLP (car))
22917 tem = Fboundp (car);
22918 elt = XCDR (elt);
22919 if (!CONSP (elt))
22920 goto invalid;
22921 /* elt is now the cdr, and we know it is a cons cell.
22922 Use its car if CAR has a non-nil value. */
22923 if (!NILP (tem))
22925 tem = Fsymbol_value (car);
22926 if (!NILP (tem))
22928 elt = XCAR (elt);
22929 goto tail_recurse;
22932 /* Symbol's value is nil (or symbol is unbound)
22933 Get the cddr of the original list
22934 and if possible find the caddr and use that. */
22935 elt = XCDR (elt);
22936 if (NILP (elt))
22937 break;
22938 else if (!CONSP (elt))
22939 goto invalid;
22940 elt = XCAR (elt);
22941 goto tail_recurse;
22943 else if (INTEGERP (car))
22945 register int lim = XINT (car);
22946 elt = XCDR (elt);
22947 if (lim < 0)
22949 /* Negative int means reduce maximum width. */
22950 if (precision <= 0)
22951 precision = -lim;
22952 else
22953 precision = min (precision, -lim);
22955 else if (lim > 0)
22957 /* Padding specified. Don't let it be more than
22958 current maximum. */
22959 if (precision > 0)
22960 lim = min (precision, lim);
22962 /* If that's more padding than already wanted, queue it.
22963 But don't reduce padding already specified even if
22964 that is beyond the current truncation point. */
22965 field_width = max (lim, field_width);
22967 goto tail_recurse;
22969 else if (STRINGP (car) || CONSP (car))
22971 Lisp_Object halftail = elt;
22972 int len = 0;
22974 while (CONSP (elt)
22975 && (precision <= 0 || n < precision))
22977 n += display_mode_element (it, depth,
22978 /* Do padding only after the last
22979 element in the list. */
22980 (! CONSP (XCDR (elt))
22981 ? field_width - n
22982 : 0),
22983 precision - n, XCAR (elt),
22984 props, risky);
22985 elt = XCDR (elt);
22986 len++;
22987 if ((len & 1) == 0)
22988 halftail = XCDR (halftail);
22989 /* Check for cycle. */
22990 if (EQ (halftail, elt))
22991 break;
22995 break;
22997 default:
22998 invalid:
22999 elt = build_string ("*invalid*");
23000 goto tail_recurse;
23003 /* Pad to FIELD_WIDTH. */
23004 if (field_width > 0 && n < field_width)
23006 switch (mode_line_target)
23008 case MODE_LINE_NOPROP:
23009 case MODE_LINE_TITLE:
23010 n += store_mode_line_noprop ("", field_width - n, 0);
23011 break;
23012 case MODE_LINE_STRING:
23013 n += store_mode_line_string ("", Qnil, false, field_width - n, 0,
23014 Qnil);
23015 break;
23016 case MODE_LINE_DISPLAY:
23017 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
23018 0, 0, 0);
23019 break;
23023 return n;
23026 /* Store a mode-line string element in mode_line_string_list.
23028 If STRING is non-null, display that C string. Otherwise, the Lisp
23029 string LISP_STRING is displayed.
23031 FIELD_WIDTH is the minimum number of output glyphs to produce.
23032 If STRING has fewer characters than FIELD_WIDTH, pad to the right
23033 with spaces. FIELD_WIDTH <= 0 means don't pad.
23035 PRECISION is the maximum number of characters to output from
23036 STRING. PRECISION <= 0 means don't truncate the string.
23038 If COPY_STRING, make a copy of LISP_STRING before adding
23039 properties to the string.
23041 PROPS are the properties to add to the string.
23042 The mode_line_string_face face property is always added to the string.
23045 static int
23046 store_mode_line_string (const char *string, Lisp_Object lisp_string,
23047 bool copy_string,
23048 int field_width, int precision, Lisp_Object props)
23050 ptrdiff_t len;
23051 int n = 0;
23053 if (string != NULL)
23055 len = strlen (string);
23056 if (precision > 0 && len > precision)
23057 len = precision;
23058 lisp_string = make_string (string, len);
23059 if (NILP (props))
23060 props = mode_line_string_face_prop;
23061 else if (!NILP (mode_line_string_face))
23063 Lisp_Object face = Fplist_get (props, Qface);
23064 props = Fcopy_sequence (props);
23065 if (NILP (face))
23066 face = mode_line_string_face;
23067 else
23068 face = list2 (face, mode_line_string_face);
23069 props = Fplist_put (props, Qface, face);
23071 Fadd_text_properties (make_number (0), make_number (len),
23072 props, lisp_string);
23074 else
23076 len = XFASTINT (Flength (lisp_string));
23077 if (precision > 0 && len > precision)
23079 len = precision;
23080 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
23081 precision = -1;
23083 if (!NILP (mode_line_string_face))
23085 Lisp_Object face;
23086 if (NILP (props))
23087 props = Ftext_properties_at (make_number (0), lisp_string);
23088 face = Fplist_get (props, Qface);
23089 if (NILP (face))
23090 face = mode_line_string_face;
23091 else
23092 face = list2 (face, mode_line_string_face);
23093 props = list2 (Qface, face);
23094 if (copy_string)
23095 lisp_string = Fcopy_sequence (lisp_string);
23097 if (!NILP (props))
23098 Fadd_text_properties (make_number (0), make_number (len),
23099 props, lisp_string);
23102 if (len > 0)
23104 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
23105 n += len;
23108 if (field_width > len)
23110 field_width -= len;
23111 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
23112 if (!NILP (props))
23113 Fadd_text_properties (make_number (0), make_number (field_width),
23114 props, lisp_string);
23115 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
23116 n += field_width;
23119 return n;
23123 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
23124 1, 4, 0,
23125 doc: /* Format a string out of a mode line format specification.
23126 First arg FORMAT specifies the mode line format (see `mode-line-format'
23127 for details) to use.
23129 By default, the format is evaluated for the currently selected window.
23131 Optional second arg FACE specifies the face property to put on all
23132 characters for which no face is specified. The value nil means the
23133 default face. The value t means whatever face the window's mode line
23134 currently uses (either `mode-line' or `mode-line-inactive',
23135 depending on whether the window is the selected window or not).
23136 An integer value means the value string has no text
23137 properties.
23139 Optional third and fourth args WINDOW and BUFFER specify the window
23140 and buffer to use as the context for the formatting (defaults
23141 are the selected window and the WINDOW's buffer). */)
23142 (Lisp_Object format, Lisp_Object face,
23143 Lisp_Object window, Lisp_Object buffer)
23145 struct it it;
23146 int len;
23147 struct window *w;
23148 struct buffer *old_buffer = NULL;
23149 int face_id;
23150 bool no_props = INTEGERP (face);
23151 ptrdiff_t count = SPECPDL_INDEX ();
23152 Lisp_Object str;
23153 int string_start = 0;
23155 w = decode_any_window (window);
23156 XSETWINDOW (window, w);
23158 if (NILP (buffer))
23159 buffer = w->contents;
23160 CHECK_BUFFER (buffer);
23162 /* Make formatting the modeline a non-op when noninteractive, otherwise
23163 there will be problems later caused by a partially initialized frame. */
23164 if (NILP (format) || noninteractive)
23165 return empty_unibyte_string;
23167 if (no_props)
23168 face = Qnil;
23170 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
23171 : EQ (face, Qt) ? (EQ (window, selected_window)
23172 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
23173 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
23174 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
23175 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
23176 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
23177 : DEFAULT_FACE_ID;
23179 old_buffer = current_buffer;
23181 /* Save things including mode_line_proptrans_alist,
23182 and set that to nil so that we don't alter the outer value. */
23183 record_unwind_protect (unwind_format_mode_line,
23184 format_mode_line_unwind_data
23185 (XFRAME (WINDOW_FRAME (w)),
23186 old_buffer, selected_window, true));
23187 mode_line_proptrans_alist = Qnil;
23189 Fselect_window (window, Qt);
23190 set_buffer_internal_1 (XBUFFER (buffer));
23192 init_iterator (&it, w, -1, -1, NULL, face_id);
23194 if (no_props)
23196 mode_line_target = MODE_LINE_NOPROP;
23197 mode_line_string_face_prop = Qnil;
23198 mode_line_string_list = Qnil;
23199 string_start = MODE_LINE_NOPROP_LEN (0);
23201 else
23203 mode_line_target = MODE_LINE_STRING;
23204 mode_line_string_list = Qnil;
23205 mode_line_string_face = face;
23206 mode_line_string_face_prop
23207 = NILP (face) ? Qnil : list2 (Qface, face);
23210 push_kboard (FRAME_KBOARD (it.f));
23211 display_mode_element (&it, 0, 0, 0, format, Qnil, false);
23212 pop_kboard ();
23214 if (no_props)
23216 len = MODE_LINE_NOPROP_LEN (string_start);
23217 str = make_string (mode_line_noprop_buf + string_start, len);
23219 else
23221 mode_line_string_list = Fnreverse (mode_line_string_list);
23222 str = Fmapconcat (Qidentity, mode_line_string_list,
23223 empty_unibyte_string);
23226 unbind_to (count, Qnil);
23227 return str;
23230 /* Write a null-terminated, right justified decimal representation of
23231 the positive integer D to BUF using a minimal field width WIDTH. */
23233 static void
23234 pint2str (register char *buf, register int width, register ptrdiff_t d)
23236 register char *p = buf;
23238 if (d <= 0)
23239 *p++ = '0';
23240 else
23242 while (d > 0)
23244 *p++ = d % 10 + '0';
23245 d /= 10;
23249 for (width -= (int) (p - buf); width > 0; --width)
23250 *p++ = ' ';
23251 *p-- = '\0';
23252 while (p > buf)
23254 d = *buf;
23255 *buf++ = *p;
23256 *p-- = d;
23260 /* Write a null-terminated, right justified decimal and "human
23261 readable" representation of the nonnegative integer D to BUF using
23262 a minimal field width WIDTH. D should be smaller than 999.5e24. */
23264 static const char power_letter[] =
23266 0, /* no letter */
23267 'k', /* kilo */
23268 'M', /* mega */
23269 'G', /* giga */
23270 'T', /* tera */
23271 'P', /* peta */
23272 'E', /* exa */
23273 'Z', /* zetta */
23274 'Y' /* yotta */
23277 static void
23278 pint2hrstr (char *buf, int width, ptrdiff_t d)
23280 /* We aim to represent the nonnegative integer D as
23281 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
23282 ptrdiff_t quotient = d;
23283 int remainder = 0;
23284 /* -1 means: do not use TENTHS. */
23285 int tenths = -1;
23286 int exponent = 0;
23288 /* Length of QUOTIENT.TENTHS as a string. */
23289 int length;
23291 char * psuffix;
23292 char * p;
23294 if (quotient >= 1000)
23296 /* Scale to the appropriate EXPONENT. */
23299 remainder = quotient % 1000;
23300 quotient /= 1000;
23301 exponent++;
23303 while (quotient >= 1000);
23305 /* Round to nearest and decide whether to use TENTHS or not. */
23306 if (quotient <= 9)
23308 tenths = remainder / 100;
23309 if (remainder % 100 >= 50)
23311 if (tenths < 9)
23312 tenths++;
23313 else
23315 quotient++;
23316 if (quotient == 10)
23317 tenths = -1;
23318 else
23319 tenths = 0;
23323 else
23324 if (remainder >= 500)
23326 if (quotient < 999)
23327 quotient++;
23328 else
23330 quotient = 1;
23331 exponent++;
23332 tenths = 0;
23337 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
23338 if (tenths == -1 && quotient <= 99)
23339 if (quotient <= 9)
23340 length = 1;
23341 else
23342 length = 2;
23343 else
23344 length = 3;
23345 p = psuffix = buf + max (width, length);
23347 /* Print EXPONENT. */
23348 *psuffix++ = power_letter[exponent];
23349 *psuffix = '\0';
23351 /* Print TENTHS. */
23352 if (tenths >= 0)
23354 *--p = '0' + tenths;
23355 *--p = '.';
23358 /* Print QUOTIENT. */
23361 int digit = quotient % 10;
23362 *--p = '0' + digit;
23364 while ((quotient /= 10) != 0);
23366 /* Print leading spaces. */
23367 while (buf < p)
23368 *--p = ' ';
23371 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
23372 If EOL_FLAG, set also a mnemonic character for end-of-line
23373 type of CODING_SYSTEM. Return updated pointer into BUF. */
23375 static unsigned char invalid_eol_type[] = "(*invalid*)";
23377 static char *
23378 decode_mode_spec_coding (Lisp_Object coding_system, char *buf, bool eol_flag)
23380 Lisp_Object val;
23381 bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
23382 const unsigned char *eol_str;
23383 int eol_str_len;
23384 /* The EOL conversion we are using. */
23385 Lisp_Object eoltype;
23387 val = CODING_SYSTEM_SPEC (coding_system);
23388 eoltype = Qnil;
23390 if (!VECTORP (val)) /* Not yet decided. */
23392 *buf++ = multibyte ? '-' : ' ';
23393 if (eol_flag)
23394 eoltype = eol_mnemonic_undecided;
23395 /* Don't mention EOL conversion if it isn't decided. */
23397 else
23399 Lisp_Object attrs;
23400 Lisp_Object eolvalue;
23402 attrs = AREF (val, 0);
23403 eolvalue = AREF (val, 2);
23405 *buf++ = multibyte
23406 ? XFASTINT (CODING_ATTR_MNEMONIC (attrs))
23407 : ' ';
23409 if (eol_flag)
23411 /* The EOL conversion that is normal on this system. */
23413 if (NILP (eolvalue)) /* Not yet decided. */
23414 eoltype = eol_mnemonic_undecided;
23415 else if (VECTORP (eolvalue)) /* Not yet decided. */
23416 eoltype = eol_mnemonic_undecided;
23417 else /* eolvalue is Qunix, Qdos, or Qmac. */
23418 eoltype = (EQ (eolvalue, Qunix)
23419 ? eol_mnemonic_unix
23420 : EQ (eolvalue, Qdos)
23421 ? eol_mnemonic_dos : eol_mnemonic_mac);
23425 if (eol_flag)
23427 /* Mention the EOL conversion if it is not the usual one. */
23428 if (STRINGP (eoltype))
23430 eol_str = SDATA (eoltype);
23431 eol_str_len = SBYTES (eoltype);
23433 else if (CHARACTERP (eoltype))
23435 int c = XFASTINT (eoltype);
23436 return buf + CHAR_STRING (c, (unsigned char *) buf);
23438 else
23440 eol_str = invalid_eol_type;
23441 eol_str_len = sizeof (invalid_eol_type) - 1;
23443 memcpy (buf, eol_str, eol_str_len);
23444 buf += eol_str_len;
23447 return buf;
23450 /* Return a string for the output of a mode line %-spec for window W,
23451 generated by character C. FIELD_WIDTH > 0 means pad the string
23452 returned with spaces to that value. Return a Lisp string in
23453 *STRING if the resulting string is taken from that Lisp string.
23455 Note we operate on the current buffer for most purposes. */
23457 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
23459 static const char *
23460 decode_mode_spec (struct window *w, register int c, int field_width,
23461 Lisp_Object *string)
23463 Lisp_Object obj;
23464 struct frame *f = XFRAME (WINDOW_FRAME (w));
23465 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
23466 /* We are going to use f->decode_mode_spec_buffer as the buffer to
23467 produce strings from numerical values, so limit preposterously
23468 large values of FIELD_WIDTH to avoid overrunning the buffer's
23469 end. The size of the buffer is enough for FRAME_MESSAGE_BUF_SIZE
23470 bytes plus the terminating null. */
23471 int width = min (field_width, FRAME_MESSAGE_BUF_SIZE (f));
23472 struct buffer *b = current_buffer;
23474 obj = Qnil;
23475 *string = Qnil;
23477 switch (c)
23479 case '*':
23480 if (!NILP (BVAR (b, read_only)))
23481 return "%";
23482 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
23483 return "*";
23484 return "-";
23486 case '+':
23487 /* This differs from %* only for a modified read-only buffer. */
23488 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
23489 return "*";
23490 if (!NILP (BVAR (b, read_only)))
23491 return "%";
23492 return "-";
23494 case '&':
23495 /* This differs from %* in ignoring read-only-ness. */
23496 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
23497 return "*";
23498 return "-";
23500 case '%':
23501 return "%";
23503 case '[':
23505 int i;
23506 char *p;
23508 if (command_loop_level > 5)
23509 return "[[[... ";
23510 p = decode_mode_spec_buf;
23511 for (i = 0; i < command_loop_level; i++)
23512 *p++ = '[';
23513 *p = 0;
23514 return decode_mode_spec_buf;
23517 case ']':
23519 int i;
23520 char *p;
23522 if (command_loop_level > 5)
23523 return " ...]]]";
23524 p = decode_mode_spec_buf;
23525 for (i = 0; i < command_loop_level; i++)
23526 *p++ = ']';
23527 *p = 0;
23528 return decode_mode_spec_buf;
23531 case '-':
23533 register int i;
23535 /* Let lots_of_dashes be a string of infinite length. */
23536 if (mode_line_target == MODE_LINE_NOPROP
23537 || mode_line_target == MODE_LINE_STRING)
23538 return "--";
23539 if (field_width <= 0
23540 || field_width > sizeof (lots_of_dashes))
23542 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
23543 decode_mode_spec_buf[i] = '-';
23544 decode_mode_spec_buf[i] = '\0';
23545 return decode_mode_spec_buf;
23547 else
23548 return lots_of_dashes;
23551 case 'b':
23552 obj = BVAR (b, name);
23553 break;
23555 case 'c':
23556 /* %c and %l are ignored in `frame-title-format'.
23557 (In redisplay_internal, the frame title is drawn _before_ the
23558 windows are updated, so the stuff which depends on actual
23559 window contents (such as %l) may fail to render properly, or
23560 even crash emacs.) */
23561 if (mode_line_target == MODE_LINE_TITLE)
23562 return "";
23563 else
23565 ptrdiff_t col = current_column ();
23566 w->column_number_displayed = col;
23567 pint2str (decode_mode_spec_buf, width, col);
23568 return decode_mode_spec_buf;
23571 case 'e':
23572 #if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
23574 if (NILP (Vmemory_full))
23575 return "";
23576 else
23577 return "!MEM FULL! ";
23579 #else
23580 return "";
23581 #endif
23583 case 'F':
23584 /* %F displays the frame name. */
23585 if (!NILP (f->title))
23586 return SSDATA (f->title);
23587 if (f->explicit_name || ! FRAME_WINDOW_P (f))
23588 return SSDATA (f->name);
23589 return "Emacs";
23591 case 'f':
23592 obj = BVAR (b, filename);
23593 break;
23595 case 'i':
23597 ptrdiff_t size = ZV - BEGV;
23598 pint2str (decode_mode_spec_buf, width, size);
23599 return decode_mode_spec_buf;
23602 case 'I':
23604 ptrdiff_t size = ZV - BEGV;
23605 pint2hrstr (decode_mode_spec_buf, width, size);
23606 return decode_mode_spec_buf;
23609 case 'l':
23611 ptrdiff_t startpos, startpos_byte, line, linepos, linepos_byte;
23612 ptrdiff_t topline, nlines, height;
23613 ptrdiff_t junk;
23615 /* %c and %l are ignored in `frame-title-format'. */
23616 if (mode_line_target == MODE_LINE_TITLE)
23617 return "";
23619 startpos = marker_position (w->start);
23620 startpos_byte = marker_byte_position (w->start);
23621 height = WINDOW_TOTAL_LINES (w);
23623 /* If we decided that this buffer isn't suitable for line numbers,
23624 don't forget that too fast. */
23625 if (w->base_line_pos == -1)
23626 goto no_value;
23628 /* If the buffer is very big, don't waste time. */
23629 if (INTEGERP (Vline_number_display_limit)
23630 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
23632 w->base_line_pos = 0;
23633 w->base_line_number = 0;
23634 goto no_value;
23637 if (w->base_line_number > 0
23638 && w->base_line_pos > 0
23639 && w->base_line_pos <= startpos)
23641 line = w->base_line_number;
23642 linepos = w->base_line_pos;
23643 linepos_byte = buf_charpos_to_bytepos (b, linepos);
23645 else
23647 line = 1;
23648 linepos = BUF_BEGV (b);
23649 linepos_byte = BUF_BEGV_BYTE (b);
23652 /* Count lines from base line to window start position. */
23653 nlines = display_count_lines (linepos_byte,
23654 startpos_byte,
23655 startpos, &junk);
23657 topline = nlines + line;
23659 /* Determine a new base line, if the old one is too close
23660 or too far away, or if we did not have one.
23661 "Too close" means it's plausible a scroll-down would
23662 go back past it. */
23663 if (startpos == BUF_BEGV (b))
23665 w->base_line_number = topline;
23666 w->base_line_pos = BUF_BEGV (b);
23668 else if (nlines < height + 25 || nlines > height * 3 + 50
23669 || linepos == BUF_BEGV (b))
23671 ptrdiff_t limit = BUF_BEGV (b);
23672 ptrdiff_t limit_byte = BUF_BEGV_BYTE (b);
23673 ptrdiff_t position;
23674 ptrdiff_t distance =
23675 (height * 2 + 30) * line_number_display_limit_width;
23677 if (startpos - distance > limit)
23679 limit = startpos - distance;
23680 limit_byte = CHAR_TO_BYTE (limit);
23683 nlines = display_count_lines (startpos_byte,
23684 limit_byte,
23685 - (height * 2 + 30),
23686 &position);
23687 /* If we couldn't find the lines we wanted within
23688 line_number_display_limit_width chars per line,
23689 give up on line numbers for this window. */
23690 if (position == limit_byte && limit == startpos - distance)
23692 w->base_line_pos = -1;
23693 w->base_line_number = 0;
23694 goto no_value;
23697 w->base_line_number = topline - nlines;
23698 w->base_line_pos = BYTE_TO_CHAR (position);
23701 /* Now count lines from the start pos to point. */
23702 nlines = display_count_lines (startpos_byte,
23703 PT_BYTE, PT, &junk);
23705 /* Record that we did display the line number. */
23706 line_number_displayed = true;
23708 /* Make the string to show. */
23709 pint2str (decode_mode_spec_buf, width, topline + nlines);
23710 return decode_mode_spec_buf;
23711 no_value:
23713 char *p = decode_mode_spec_buf;
23714 int pad = width - 2;
23715 while (pad-- > 0)
23716 *p++ = ' ';
23717 *p++ = '?';
23718 *p++ = '?';
23719 *p = '\0';
23720 return decode_mode_spec_buf;
23723 break;
23725 case 'm':
23726 obj = BVAR (b, mode_name);
23727 break;
23729 case 'n':
23730 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
23731 return " Narrow";
23732 break;
23734 case 'p':
23736 ptrdiff_t pos = marker_position (w->start);
23737 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
23739 if (w->window_end_pos <= BUF_Z (b) - BUF_ZV (b))
23741 if (pos <= BUF_BEGV (b))
23742 return "All";
23743 else
23744 return "Bottom";
23746 else if (pos <= BUF_BEGV (b))
23747 return "Top";
23748 else
23750 if (total > 1000000)
23751 /* Do it differently for a large value, to avoid overflow. */
23752 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
23753 else
23754 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
23755 /* We can't normally display a 3-digit number,
23756 so get us a 2-digit number that is close. */
23757 if (total == 100)
23758 total = 99;
23759 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
23760 return decode_mode_spec_buf;
23764 /* Display percentage of size above the bottom of the screen. */
23765 case 'P':
23767 ptrdiff_t toppos = marker_position (w->start);
23768 ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos;
23769 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
23771 if (botpos >= BUF_ZV (b))
23773 if (toppos <= BUF_BEGV (b))
23774 return "All";
23775 else
23776 return "Bottom";
23778 else
23780 if (total > 1000000)
23781 /* Do it differently for a large value, to avoid overflow. */
23782 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
23783 else
23784 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
23785 /* We can't normally display a 3-digit number,
23786 so get us a 2-digit number that is close. */
23787 if (total == 100)
23788 total = 99;
23789 if (toppos <= BUF_BEGV (b))
23790 sprintf (decode_mode_spec_buf, "Top%2"pD"d%%", total);
23791 else
23792 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
23793 return decode_mode_spec_buf;
23797 case 's':
23798 /* status of process */
23799 obj = Fget_buffer_process (Fcurrent_buffer ());
23800 if (NILP (obj))
23801 return "no process";
23802 #ifndef MSDOS
23803 obj = Fsymbol_name (Fprocess_status (obj));
23804 #endif
23805 break;
23807 case '@':
23809 ptrdiff_t count = inhibit_garbage_collection ();
23810 Lisp_Object curdir = BVAR (current_buffer, directory);
23811 Lisp_Object val = Qnil;
23813 if (STRINGP (curdir))
23814 val = call1 (intern ("file-remote-p"), curdir);
23816 unbind_to (count, Qnil);
23818 if (NILP (val))
23819 return "-";
23820 else
23821 return "@";
23824 case 'z':
23825 /* coding-system (not including end-of-line format) */
23826 case 'Z':
23827 /* coding-system (including end-of-line type) */
23829 bool eol_flag = (c == 'Z');
23830 char *p = decode_mode_spec_buf;
23832 if (! FRAME_WINDOW_P (f))
23834 /* No need to mention EOL here--the terminal never needs
23835 to do EOL conversion. */
23836 p = decode_mode_spec_coding (CODING_ID_NAME
23837 (FRAME_KEYBOARD_CODING (f)->id),
23838 p, false);
23839 p = decode_mode_spec_coding (CODING_ID_NAME
23840 (FRAME_TERMINAL_CODING (f)->id),
23841 p, false);
23843 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
23844 p, eol_flag);
23846 #if false /* This proves to be annoying; I think we can do without. -- rms. */
23847 #ifdef subprocesses
23848 obj = Fget_buffer_process (Fcurrent_buffer ());
23849 if (PROCESSP (obj))
23851 p = decode_mode_spec_coding
23852 (XPROCESS (obj)->decode_coding_system, p, eol_flag);
23853 p = decode_mode_spec_coding
23854 (XPROCESS (obj)->encode_coding_system, p, eol_flag);
23856 #endif /* subprocesses */
23857 #endif /* false */
23858 *p = 0;
23859 return decode_mode_spec_buf;
23863 if (STRINGP (obj))
23865 *string = obj;
23866 return SSDATA (obj);
23868 else
23869 return "";
23873 /* Count up to COUNT lines starting from START_BYTE. COUNT negative
23874 means count lines back from START_BYTE. But don't go beyond
23875 LIMIT_BYTE. Return the number of lines thus found (always
23876 nonnegative).
23878 Set *BYTE_POS_PTR to the byte position where we stopped. This is
23879 either the position COUNT lines after/before START_BYTE, if we
23880 found COUNT lines, or LIMIT_BYTE if we hit the limit before finding
23881 COUNT lines. */
23883 static ptrdiff_t
23884 display_count_lines (ptrdiff_t start_byte,
23885 ptrdiff_t limit_byte, ptrdiff_t count,
23886 ptrdiff_t *byte_pos_ptr)
23888 register unsigned char *cursor;
23889 unsigned char *base;
23891 register ptrdiff_t ceiling;
23892 register unsigned char *ceiling_addr;
23893 ptrdiff_t orig_count = count;
23895 /* If we are not in selective display mode,
23896 check only for newlines. */
23897 bool selective_display
23898 = (!NILP (BVAR (current_buffer, selective_display))
23899 && !INTEGERP (BVAR (current_buffer, selective_display)));
23901 if (count > 0)
23903 while (start_byte < limit_byte)
23905 ceiling = BUFFER_CEILING_OF (start_byte);
23906 ceiling = min (limit_byte - 1, ceiling);
23907 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
23908 base = (cursor = BYTE_POS_ADDR (start_byte));
23912 if (selective_display)
23914 while (*cursor != '\n' && *cursor != 015
23915 && ++cursor != ceiling_addr)
23916 continue;
23917 if (cursor == ceiling_addr)
23918 break;
23920 else
23922 cursor = memchr (cursor, '\n', ceiling_addr - cursor);
23923 if (! cursor)
23924 break;
23927 cursor++;
23929 if (--count == 0)
23931 start_byte += cursor - base;
23932 *byte_pos_ptr = start_byte;
23933 return orig_count;
23936 while (cursor < ceiling_addr);
23938 start_byte += ceiling_addr - base;
23941 else
23943 while (start_byte > limit_byte)
23945 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
23946 ceiling = max (limit_byte, ceiling);
23947 ceiling_addr = BYTE_POS_ADDR (ceiling);
23948 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
23949 while (true)
23951 if (selective_display)
23953 while (--cursor >= ceiling_addr
23954 && *cursor != '\n' && *cursor != 015)
23955 continue;
23956 if (cursor < ceiling_addr)
23957 break;
23959 else
23961 cursor = memrchr (ceiling_addr, '\n', cursor - ceiling_addr);
23962 if (! cursor)
23963 break;
23966 if (++count == 0)
23968 start_byte += cursor - base + 1;
23969 *byte_pos_ptr = start_byte;
23970 /* When scanning backwards, we should
23971 not count the newline posterior to which we stop. */
23972 return - orig_count - 1;
23975 start_byte += ceiling_addr - base;
23979 *byte_pos_ptr = limit_byte;
23981 if (count < 0)
23982 return - orig_count + count;
23983 return orig_count - count;
23989 /***********************************************************************
23990 Displaying strings
23991 ***********************************************************************/
23993 /* Display a NUL-terminated string, starting with index START.
23995 If STRING is non-null, display that C string. Otherwise, the Lisp
23996 string LISP_STRING is displayed. There's a case that STRING is
23997 non-null and LISP_STRING is not nil. It means STRING is a string
23998 data of LISP_STRING. In that case, we display LISP_STRING while
23999 ignoring its text properties.
24001 If FACE_STRING is not nil, FACE_STRING_POS is a position in
24002 FACE_STRING. Display STRING or LISP_STRING with the face at
24003 FACE_STRING_POS in FACE_STRING:
24005 Display the string in the environment given by IT, but use the
24006 standard display table, temporarily.
24008 FIELD_WIDTH is the minimum number of output glyphs to produce.
24009 If STRING has fewer characters than FIELD_WIDTH, pad to the right
24010 with spaces. If STRING has more characters, more than FIELD_WIDTH
24011 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
24013 PRECISION is the maximum number of characters to output from
24014 STRING. PRECISION < 0 means don't truncate the string.
24016 This is roughly equivalent to printf format specifiers:
24018 FIELD_WIDTH PRECISION PRINTF
24019 ----------------------------------------
24020 -1 -1 %s
24021 -1 10 %.10s
24022 10 -1 %10s
24023 20 10 %20.10s
24025 MULTIBYTE zero means do not display multibyte chars, > 0 means do
24026 display them, and < 0 means obey the current buffer's value of
24027 enable_multibyte_characters.
24029 Value is the number of columns displayed. */
24031 static int
24032 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
24033 ptrdiff_t face_string_pos, ptrdiff_t start, struct it *it,
24034 int field_width, int precision, int max_x, int multibyte)
24036 int hpos_at_start = it->hpos;
24037 int saved_face_id = it->face_id;
24038 struct glyph_row *row = it->glyph_row;
24039 ptrdiff_t it_charpos;
24041 /* Initialize the iterator IT for iteration over STRING beginning
24042 with index START. */
24043 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
24044 precision, field_width, multibyte);
24045 if (string && STRINGP (lisp_string))
24046 /* LISP_STRING is the one returned by decode_mode_spec. We should
24047 ignore its text properties. */
24048 it->stop_charpos = it->end_charpos;
24050 /* If displaying STRING, set up the face of the iterator from
24051 FACE_STRING, if that's given. */
24052 if (STRINGP (face_string))
24054 ptrdiff_t endptr;
24055 struct face *face;
24057 it->face_id
24058 = face_at_string_position (it->w, face_string, face_string_pos,
24059 0, &endptr, it->base_face_id, false);
24060 face = FACE_FROM_ID (it->f, it->face_id);
24061 it->face_box_p = face->box != FACE_NO_BOX;
24064 /* Set max_x to the maximum allowed X position. Don't let it go
24065 beyond the right edge of the window. */
24066 if (max_x <= 0)
24067 max_x = it->last_visible_x;
24068 else
24069 max_x = min (max_x, it->last_visible_x);
24071 /* Skip over display elements that are not visible. because IT->w is
24072 hscrolled. */
24073 if (it->current_x < it->first_visible_x)
24074 move_it_in_display_line_to (it, 100000, it->first_visible_x,
24075 MOVE_TO_POS | MOVE_TO_X);
24077 row->ascent = it->max_ascent;
24078 row->height = it->max_ascent + it->max_descent;
24079 row->phys_ascent = it->max_phys_ascent;
24080 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
24081 row->extra_line_spacing = it->max_extra_line_spacing;
24083 if (STRINGP (it->string))
24084 it_charpos = IT_STRING_CHARPOS (*it);
24085 else
24086 it_charpos = IT_CHARPOS (*it);
24088 /* This condition is for the case that we are called with current_x
24089 past last_visible_x. */
24090 while (it->current_x < max_x)
24092 int x_before, x, n_glyphs_before, i, nglyphs;
24094 /* Get the next display element. */
24095 if (!get_next_display_element (it))
24096 break;
24098 /* Produce glyphs. */
24099 x_before = it->current_x;
24100 n_glyphs_before = row->used[TEXT_AREA];
24101 PRODUCE_GLYPHS (it);
24103 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
24104 i = 0;
24105 x = x_before;
24106 while (i < nglyphs)
24108 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
24110 if (it->line_wrap != TRUNCATE
24111 && x + glyph->pixel_width > max_x)
24113 /* End of continued line or max_x reached. */
24114 if (CHAR_GLYPH_PADDING_P (*glyph))
24116 /* A wide character is unbreakable. */
24117 if (row->reversed_p)
24118 unproduce_glyphs (it, row->used[TEXT_AREA]
24119 - n_glyphs_before);
24120 row->used[TEXT_AREA] = n_glyphs_before;
24121 it->current_x = x_before;
24123 else
24125 if (row->reversed_p)
24126 unproduce_glyphs (it, row->used[TEXT_AREA]
24127 - (n_glyphs_before + i));
24128 row->used[TEXT_AREA] = n_glyphs_before + i;
24129 it->current_x = x;
24131 break;
24133 else if (x + glyph->pixel_width >= it->first_visible_x)
24135 /* Glyph is at least partially visible. */
24136 ++it->hpos;
24137 if (x < it->first_visible_x)
24138 row->x = x - it->first_visible_x;
24140 else
24142 /* Glyph is off the left margin of the display area.
24143 Should not happen. */
24144 emacs_abort ();
24147 row->ascent = max (row->ascent, it->max_ascent);
24148 row->height = max (row->height, it->max_ascent + it->max_descent);
24149 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
24150 row->phys_height = max (row->phys_height,
24151 it->max_phys_ascent + it->max_phys_descent);
24152 row->extra_line_spacing = max (row->extra_line_spacing,
24153 it->max_extra_line_spacing);
24154 x += glyph->pixel_width;
24155 ++i;
24158 /* Stop if max_x reached. */
24159 if (i < nglyphs)
24160 break;
24162 /* Stop at line ends. */
24163 if (ITERATOR_AT_END_OF_LINE_P (it))
24165 it->continuation_lines_width = 0;
24166 break;
24169 set_iterator_to_next (it, true);
24170 if (STRINGP (it->string))
24171 it_charpos = IT_STRING_CHARPOS (*it);
24172 else
24173 it_charpos = IT_CHARPOS (*it);
24175 /* Stop if truncating at the right edge. */
24176 if (it->line_wrap == TRUNCATE
24177 && it->current_x >= it->last_visible_x)
24179 /* Add truncation mark, but don't do it if the line is
24180 truncated at a padding space. */
24181 if (it_charpos < it->string_nchars)
24183 if (!FRAME_WINDOW_P (it->f))
24185 int ii, n;
24187 if (it->current_x > it->last_visible_x)
24189 if (!row->reversed_p)
24191 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
24192 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
24193 break;
24195 else
24197 for (ii = 0; ii < row->used[TEXT_AREA]; ii++)
24198 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
24199 break;
24200 unproduce_glyphs (it, ii + 1);
24201 ii = row->used[TEXT_AREA] - (ii + 1);
24203 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
24205 row->used[TEXT_AREA] = ii;
24206 produce_special_glyphs (it, IT_TRUNCATION);
24209 produce_special_glyphs (it, IT_TRUNCATION);
24211 row->truncated_on_right_p = true;
24213 break;
24217 /* Maybe insert a truncation at the left. */
24218 if (it->first_visible_x
24219 && it_charpos > 0)
24221 if (!FRAME_WINDOW_P (it->f)
24222 || (row->reversed_p
24223 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
24224 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
24225 insert_left_trunc_glyphs (it);
24226 row->truncated_on_left_p = true;
24229 it->face_id = saved_face_id;
24231 /* Value is number of columns displayed. */
24232 return it->hpos - hpos_at_start;
24237 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
24238 appears as an element of LIST or as the car of an element of LIST.
24239 If PROPVAL is a list, compare each element against LIST in that
24240 way, and return 1/2 if any element of PROPVAL is found in LIST.
24241 Otherwise return 0. This function cannot quit.
24242 The return value is 2 if the text is invisible but with an ellipsis
24243 and 1 if it's invisible and without an ellipsis. */
24246 invisible_prop (Lisp_Object propval, Lisp_Object list)
24248 Lisp_Object tail, proptail;
24250 for (tail = list; CONSP (tail); tail = XCDR (tail))
24252 register Lisp_Object tem;
24253 tem = XCAR (tail);
24254 if (EQ (propval, tem))
24255 return 1;
24256 if (CONSP (tem) && EQ (propval, XCAR (tem)))
24257 return NILP (XCDR (tem)) ? 1 : 2;
24260 if (CONSP (propval))
24262 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
24264 Lisp_Object propelt;
24265 propelt = XCAR (proptail);
24266 for (tail = list; CONSP (tail); tail = XCDR (tail))
24268 register Lisp_Object tem;
24269 tem = XCAR (tail);
24270 if (EQ (propelt, tem))
24271 return 1;
24272 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
24273 return NILP (XCDR (tem)) ? 1 : 2;
24278 return 0;
24281 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
24282 doc: /* Non-nil if the property makes the text invisible.
24283 POS-OR-PROP can be a marker or number, in which case it is taken to be
24284 a position in the current buffer and the value of the `invisible' property
24285 is checked; or it can be some other value, which is then presumed to be the
24286 value of the `invisible' property of the text of interest.
24287 The non-nil value returned can be t for truly invisible text or something
24288 else if the text is replaced by an ellipsis. */)
24289 (Lisp_Object pos_or_prop)
24291 Lisp_Object prop
24292 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
24293 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
24294 : pos_or_prop);
24295 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
24296 return (invis == 0 ? Qnil
24297 : invis == 1 ? Qt
24298 : make_number (invis));
24301 /* Calculate a width or height in pixels from a specification using
24302 the following elements:
24304 SPEC ::=
24305 NUM - a (fractional) multiple of the default font width/height
24306 (NUM) - specifies exactly NUM pixels
24307 UNIT - a fixed number of pixels, see below.
24308 ELEMENT - size of a display element in pixels, see below.
24309 (NUM . SPEC) - equals NUM * SPEC
24310 (+ SPEC SPEC ...) - add pixel values
24311 (- SPEC SPEC ...) - subtract pixel values
24312 (- SPEC) - negate pixel value
24314 NUM ::=
24315 INT or FLOAT - a number constant
24316 SYMBOL - use symbol's (buffer local) variable binding.
24318 UNIT ::=
24319 in - pixels per inch *)
24320 mm - pixels per 1/1000 meter *)
24321 cm - pixels per 1/100 meter *)
24322 width - width of current font in pixels.
24323 height - height of current font in pixels.
24325 *) using the ratio(s) defined in display-pixels-per-inch.
24327 ELEMENT ::=
24329 left-fringe - left fringe width in pixels
24330 right-fringe - right fringe width in pixels
24332 left-margin - left margin width in pixels
24333 right-margin - right margin width in pixels
24335 scroll-bar - scroll-bar area width in pixels
24337 Examples:
24339 Pixels corresponding to 5 inches:
24340 (5 . in)
24342 Total width of non-text areas on left side of window (if scroll-bar is on left):
24343 '(space :width (+ left-fringe left-margin scroll-bar))
24345 Align to first text column (in header line):
24346 '(space :align-to 0)
24348 Align to middle of text area minus half the width of variable `my-image'
24349 containing a loaded image:
24350 '(space :align-to (0.5 . (- text my-image)))
24352 Width of left margin minus width of 1 character in the default font:
24353 '(space :width (- left-margin 1))
24355 Width of left margin minus width of 2 characters in the current font:
24356 '(space :width (- left-margin (2 . width)))
24358 Center 1 character over left-margin (in header line):
24359 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
24361 Different ways to express width of left fringe plus left margin minus one pixel:
24362 '(space :width (- (+ left-fringe left-margin) (1)))
24363 '(space :width (+ left-fringe left-margin (- (1))))
24364 '(space :width (+ left-fringe left-margin (-1)))
24368 static bool
24369 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
24370 struct font *font, bool width_p, int *align_to)
24372 double pixels;
24374 # define OK_PIXELS(val) (*res = (val), true)
24375 # define OK_ALIGN_TO(val) (*align_to = (val), true)
24377 if (NILP (prop))
24378 return OK_PIXELS (0);
24380 eassert (FRAME_LIVE_P (it->f));
24382 if (SYMBOLP (prop))
24384 if (SCHARS (SYMBOL_NAME (prop)) == 2)
24386 char *unit = SSDATA (SYMBOL_NAME (prop));
24388 if (unit[0] == 'i' && unit[1] == 'n')
24389 pixels = 1.0;
24390 else if (unit[0] == 'm' && unit[1] == 'm')
24391 pixels = 25.4;
24392 else if (unit[0] == 'c' && unit[1] == 'm')
24393 pixels = 2.54;
24394 else
24395 pixels = 0;
24396 if (pixels > 0)
24398 double ppi = (width_p ? FRAME_RES_X (it->f)
24399 : FRAME_RES_Y (it->f));
24401 if (ppi > 0)
24402 return OK_PIXELS (ppi / pixels);
24403 return false;
24407 #ifdef HAVE_WINDOW_SYSTEM
24408 if (EQ (prop, Qheight))
24409 return OK_PIXELS (font
24410 ? normal_char_height (font, -1)
24411 : FRAME_LINE_HEIGHT (it->f));
24412 if (EQ (prop, Qwidth))
24413 return OK_PIXELS (font
24414 ? FONT_WIDTH (font)
24415 : FRAME_COLUMN_WIDTH (it->f));
24416 #else
24417 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
24418 return OK_PIXELS (1);
24419 #endif
24421 if (EQ (prop, Qtext))
24422 return OK_PIXELS (width_p
24423 ? window_box_width (it->w, TEXT_AREA)
24424 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
24426 if (align_to && *align_to < 0)
24428 *res = 0;
24429 if (EQ (prop, Qleft))
24430 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
24431 if (EQ (prop, Qright))
24432 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
24433 if (EQ (prop, Qcenter))
24434 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
24435 + window_box_width (it->w, TEXT_AREA) / 2);
24436 if (EQ (prop, Qleft_fringe))
24437 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
24438 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
24439 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
24440 if (EQ (prop, Qright_fringe))
24441 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
24442 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
24443 : window_box_right_offset (it->w, TEXT_AREA));
24444 if (EQ (prop, Qleft_margin))
24445 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
24446 if (EQ (prop, Qright_margin))
24447 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
24448 if (EQ (prop, Qscroll_bar))
24449 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
24451 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
24452 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
24453 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
24454 : 0)));
24456 else
24458 if (EQ (prop, Qleft_fringe))
24459 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
24460 if (EQ (prop, Qright_fringe))
24461 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
24462 if (EQ (prop, Qleft_margin))
24463 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
24464 if (EQ (prop, Qright_margin))
24465 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
24466 if (EQ (prop, Qscroll_bar))
24467 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
24470 prop = buffer_local_value (prop, it->w->contents);
24471 if (EQ (prop, Qunbound))
24472 prop = Qnil;
24475 if (NUMBERP (prop))
24477 int base_unit = (width_p
24478 ? FRAME_COLUMN_WIDTH (it->f)
24479 : FRAME_LINE_HEIGHT (it->f));
24480 return OK_PIXELS (XFLOATINT (prop) * base_unit);
24483 if (CONSP (prop))
24485 Lisp_Object car = XCAR (prop);
24486 Lisp_Object cdr = XCDR (prop);
24488 if (SYMBOLP (car))
24490 #ifdef HAVE_WINDOW_SYSTEM
24491 if (FRAME_WINDOW_P (it->f)
24492 && valid_image_p (prop))
24494 ptrdiff_t id = lookup_image (it->f, prop);
24495 struct image *img = IMAGE_FROM_ID (it->f, id);
24497 return OK_PIXELS (width_p ? img->width : img->height);
24499 if (FRAME_WINDOW_P (it->f) && valid_xwidget_spec_p (prop))
24501 // TODO: Don't return dummy size.
24502 return OK_PIXELS (100);
24504 #endif
24505 if (EQ (car, Qplus) || EQ (car, Qminus))
24507 bool first = true;
24508 double px;
24510 pixels = 0;
24511 while (CONSP (cdr))
24513 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
24514 font, width_p, align_to))
24515 return false;
24516 if (first)
24517 pixels = (EQ (car, Qplus) ? px : -px), first = false;
24518 else
24519 pixels += px;
24520 cdr = XCDR (cdr);
24522 if (EQ (car, Qminus))
24523 pixels = -pixels;
24524 return OK_PIXELS (pixels);
24527 car = buffer_local_value (car, it->w->contents);
24528 if (EQ (car, Qunbound))
24529 car = Qnil;
24532 if (NUMBERP (car))
24534 double fact;
24535 pixels = XFLOATINT (car);
24536 if (NILP (cdr))
24537 return OK_PIXELS (pixels);
24538 if (calc_pixel_width_or_height (&fact, it, cdr,
24539 font, width_p, align_to))
24540 return OK_PIXELS (pixels * fact);
24541 return false;
24544 return false;
24547 return false;
24550 void
24551 get_font_ascent_descent (struct font *font, int *ascent, int *descent)
24553 #ifdef HAVE_WINDOW_SYSTEM
24554 normal_char_ascent_descent (font, -1, ascent, descent);
24555 #else
24556 *ascent = 1;
24557 *descent = 0;
24558 #endif
24562 /***********************************************************************
24563 Glyph Display
24564 ***********************************************************************/
24566 #ifdef HAVE_WINDOW_SYSTEM
24568 #ifdef GLYPH_DEBUG
24570 void
24571 dump_glyph_string (struct glyph_string *s)
24573 fprintf (stderr, "glyph string\n");
24574 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
24575 s->x, s->y, s->width, s->height);
24576 fprintf (stderr, " ybase = %d\n", s->ybase);
24577 fprintf (stderr, " hl = %d\n", s->hl);
24578 fprintf (stderr, " left overhang = %d, right = %d\n",
24579 s->left_overhang, s->right_overhang);
24580 fprintf (stderr, " nchars = %d\n", s->nchars);
24581 fprintf (stderr, " extends to end of line = %d\n",
24582 s->extends_to_end_of_line_p);
24583 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
24584 fprintf (stderr, " bg width = %d\n", s->background_width);
24587 #endif /* GLYPH_DEBUG */
24589 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
24590 of XChar2b structures for S; it can't be allocated in
24591 init_glyph_string because it must be allocated via `alloca'. W
24592 is the window on which S is drawn. ROW and AREA are the glyph row
24593 and area within the row from which S is constructed. START is the
24594 index of the first glyph structure covered by S. HL is a
24595 face-override for drawing S. */
24597 #ifdef HAVE_NTGUI
24598 #define OPTIONAL_HDC(hdc) HDC hdc,
24599 #define DECLARE_HDC(hdc) HDC hdc;
24600 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
24601 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
24602 #endif
24604 #ifndef OPTIONAL_HDC
24605 #define OPTIONAL_HDC(hdc)
24606 #define DECLARE_HDC(hdc)
24607 #define ALLOCATE_HDC(hdc, f)
24608 #define RELEASE_HDC(hdc, f)
24609 #endif
24611 static void
24612 init_glyph_string (struct glyph_string *s,
24613 OPTIONAL_HDC (hdc)
24614 XChar2b *char2b, struct window *w, struct glyph_row *row,
24615 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
24617 memset (s, 0, sizeof *s);
24618 s->w = w;
24619 s->f = XFRAME (w->frame);
24620 #ifdef HAVE_NTGUI
24621 s->hdc = hdc;
24622 #endif
24623 s->display = FRAME_X_DISPLAY (s->f);
24624 s->window = FRAME_X_WINDOW (s->f);
24625 s->char2b = char2b;
24626 s->hl = hl;
24627 s->row = row;
24628 s->area = area;
24629 s->first_glyph = row->glyphs[area] + start;
24630 s->height = row->height;
24631 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
24632 s->ybase = s->y + row->ascent;
24636 /* Append the list of glyph strings with head H and tail T to the list
24637 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
24639 static void
24640 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
24641 struct glyph_string *h, struct glyph_string *t)
24643 if (h)
24645 if (*head)
24646 (*tail)->next = h;
24647 else
24648 *head = h;
24649 h->prev = *tail;
24650 *tail = t;
24655 /* Prepend the list of glyph strings with head H and tail T to the
24656 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
24657 result. */
24659 static void
24660 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
24661 struct glyph_string *h, struct glyph_string *t)
24663 if (h)
24665 if (*head)
24666 (*head)->prev = t;
24667 else
24668 *tail = t;
24669 t->next = *head;
24670 *head = h;
24675 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
24676 Set *HEAD and *TAIL to the resulting list. */
24678 static void
24679 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
24680 struct glyph_string *s)
24682 s->next = s->prev = NULL;
24683 append_glyph_string_lists (head, tail, s, s);
24687 /* Get face and two-byte form of character C in face FACE_ID on frame F.
24688 The encoding of C is returned in *CHAR2B. DISPLAY_P means
24689 make sure that X resources for the face returned are allocated.
24690 Value is a pointer to a realized face that is ready for display if
24691 DISPLAY_P. */
24693 static struct face *
24694 get_char_face_and_encoding (struct frame *f, int c, int face_id,
24695 XChar2b *char2b, bool display_p)
24697 struct face *face = FACE_FROM_ID (f, face_id);
24698 unsigned code = 0;
24700 if (face->font)
24702 code = face->font->driver->encode_char (face->font, c);
24704 if (code == FONT_INVALID_CODE)
24705 code = 0;
24707 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
24709 /* Make sure X resources of the face are allocated. */
24710 #ifdef HAVE_X_WINDOWS
24711 if (display_p)
24712 #endif
24714 eassert (face != NULL);
24715 prepare_face_for_display (f, face);
24718 return face;
24722 /* Get face and two-byte form of character glyph GLYPH on frame F.
24723 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
24724 a pointer to a realized face that is ready for display. */
24726 static struct face *
24727 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
24728 XChar2b *char2b)
24730 struct face *face;
24731 unsigned code = 0;
24733 eassert (glyph->type == CHAR_GLYPH);
24734 face = FACE_FROM_ID (f, glyph->face_id);
24736 /* Make sure X resources of the face are allocated. */
24737 prepare_face_for_display (f, face);
24739 if (face->font)
24741 if (CHAR_BYTE8_P (glyph->u.ch))
24742 code = CHAR_TO_BYTE8 (glyph->u.ch);
24743 else
24744 code = face->font->driver->encode_char (face->font, glyph->u.ch);
24746 if (code == FONT_INVALID_CODE)
24747 code = 0;
24750 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
24751 return face;
24755 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
24756 Return true iff FONT has a glyph for C. */
24758 static bool
24759 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
24761 unsigned code;
24763 if (CHAR_BYTE8_P (c))
24764 code = CHAR_TO_BYTE8 (c);
24765 else
24766 code = font->driver->encode_char (font, c);
24768 if (code == FONT_INVALID_CODE)
24769 return false;
24770 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
24771 return true;
24775 /* Fill glyph string S with composition components specified by S->cmp.
24777 BASE_FACE is the base face of the composition.
24778 S->cmp_from is the index of the first component for S.
24780 OVERLAPS non-zero means S should draw the foreground only, and use
24781 its physical height for clipping. See also draw_glyphs.
24783 Value is the index of a component not in S. */
24785 static int
24786 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
24787 int overlaps)
24789 int i;
24790 /* For all glyphs of this composition, starting at the offset
24791 S->cmp_from, until we reach the end of the definition or encounter a
24792 glyph that requires the different face, add it to S. */
24793 struct face *face;
24795 eassert (s);
24797 s->for_overlaps = overlaps;
24798 s->face = NULL;
24799 s->font = NULL;
24800 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
24802 int c = COMPOSITION_GLYPH (s->cmp, i);
24804 /* TAB in a composition means display glyphs with padding space
24805 on the left or right. */
24806 if (c != '\t')
24808 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
24809 -1, Qnil);
24811 face = get_char_face_and_encoding (s->f, c, face_id,
24812 s->char2b + i, true);
24813 if (face)
24815 if (! s->face)
24817 s->face = face;
24818 s->font = s->face->font;
24820 else if (s->face != face)
24821 break;
24824 ++s->nchars;
24826 s->cmp_to = i;
24828 if (s->face == NULL)
24830 s->face = base_face->ascii_face;
24831 s->font = s->face->font;
24834 /* All glyph strings for the same composition has the same width,
24835 i.e. the width set for the first component of the composition. */
24836 s->width = s->first_glyph->pixel_width;
24838 /* If the specified font could not be loaded, use the frame's
24839 default font, but record the fact that we couldn't load it in
24840 the glyph string so that we can draw rectangles for the
24841 characters of the glyph string. */
24842 if (s->font == NULL)
24844 s->font_not_found_p = true;
24845 s->font = FRAME_FONT (s->f);
24848 /* Adjust base line for subscript/superscript text. */
24849 s->ybase += s->first_glyph->voffset;
24851 return s->cmp_to;
24854 static int
24855 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
24856 int start, int end, int overlaps)
24858 struct glyph *glyph, *last;
24859 Lisp_Object lgstring;
24860 int i;
24862 s->for_overlaps = overlaps;
24863 glyph = s->row->glyphs[s->area] + start;
24864 last = s->row->glyphs[s->area] + end;
24865 s->cmp_id = glyph->u.cmp.id;
24866 s->cmp_from = glyph->slice.cmp.from;
24867 s->cmp_to = glyph->slice.cmp.to + 1;
24868 s->face = FACE_FROM_ID (s->f, face_id);
24869 lgstring = composition_gstring_from_id (s->cmp_id);
24870 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
24871 glyph++;
24872 while (glyph < last
24873 && glyph->u.cmp.automatic
24874 && glyph->u.cmp.id == s->cmp_id
24875 && s->cmp_to == glyph->slice.cmp.from)
24876 s->cmp_to = (glyph++)->slice.cmp.to + 1;
24878 for (i = s->cmp_from; i < s->cmp_to; i++)
24880 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
24881 unsigned code = LGLYPH_CODE (lglyph);
24883 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
24885 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
24886 return glyph - s->row->glyphs[s->area];
24890 /* Fill glyph string S from a sequence glyphs for glyphless characters.
24891 See the comment of fill_glyph_string for arguments.
24892 Value is the index of the first glyph not in S. */
24895 static int
24896 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
24897 int start, int end, int overlaps)
24899 struct glyph *glyph, *last;
24900 int voffset;
24902 eassert (s->first_glyph->type == GLYPHLESS_GLYPH);
24903 s->for_overlaps = overlaps;
24904 glyph = s->row->glyphs[s->area] + start;
24905 last = s->row->glyphs[s->area] + end;
24906 voffset = glyph->voffset;
24907 s->face = FACE_FROM_ID (s->f, face_id);
24908 s->font = s->face->font ? s->face->font : FRAME_FONT (s->f);
24909 s->nchars = 1;
24910 s->width = glyph->pixel_width;
24911 glyph++;
24912 while (glyph < last
24913 && glyph->type == GLYPHLESS_GLYPH
24914 && glyph->voffset == voffset
24915 && glyph->face_id == face_id)
24917 s->nchars++;
24918 s->width += glyph->pixel_width;
24919 glyph++;
24921 s->ybase += voffset;
24922 return glyph - s->row->glyphs[s->area];
24926 /* Fill glyph string S from a sequence of character glyphs.
24928 FACE_ID is the face id of the string. START is the index of the
24929 first glyph to consider, END is the index of the last + 1.
24930 OVERLAPS non-zero means S should draw the foreground only, and use
24931 its physical height for clipping. See also draw_glyphs.
24933 Value is the index of the first glyph not in S. */
24935 static int
24936 fill_glyph_string (struct glyph_string *s, int face_id,
24937 int start, int end, int overlaps)
24939 struct glyph *glyph, *last;
24940 int voffset;
24941 bool glyph_not_available_p;
24943 eassert (s->f == XFRAME (s->w->frame));
24944 eassert (s->nchars == 0);
24945 eassert (start >= 0 && end > start);
24947 s->for_overlaps = overlaps;
24948 glyph = s->row->glyphs[s->area] + start;
24949 last = s->row->glyphs[s->area] + end;
24950 voffset = glyph->voffset;
24951 s->padding_p = glyph->padding_p;
24952 glyph_not_available_p = glyph->glyph_not_available_p;
24954 while (glyph < last
24955 && glyph->type == CHAR_GLYPH
24956 && glyph->voffset == voffset
24957 /* Same face id implies same font, nowadays. */
24958 && glyph->face_id == face_id
24959 && glyph->glyph_not_available_p == glyph_not_available_p)
24961 s->face = get_glyph_face_and_encoding (s->f, glyph,
24962 s->char2b + s->nchars);
24963 ++s->nchars;
24964 eassert (s->nchars <= end - start);
24965 s->width += glyph->pixel_width;
24966 if (glyph++->padding_p != s->padding_p)
24967 break;
24970 s->font = s->face->font;
24972 /* If the specified font could not be loaded, use the frame's font,
24973 but record the fact that we couldn't load it in
24974 S->font_not_found_p so that we can draw rectangles for the
24975 characters of the glyph string. */
24976 if (s->font == NULL || glyph_not_available_p)
24978 s->font_not_found_p = true;
24979 s->font = FRAME_FONT (s->f);
24982 /* Adjust base line for subscript/superscript text. */
24983 s->ybase += voffset;
24985 eassert (s->face && s->face->gc);
24986 return glyph - s->row->glyphs[s->area];
24990 /* Fill glyph string S from image glyph S->first_glyph. */
24992 static void
24993 fill_image_glyph_string (struct glyph_string *s)
24995 eassert (s->first_glyph->type == IMAGE_GLYPH);
24996 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
24997 eassert (s->img);
24998 s->slice = s->first_glyph->slice.img;
24999 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
25000 s->font = s->face->font;
25001 s->width = s->first_glyph->pixel_width;
25003 /* Adjust base line for subscript/superscript text. */
25004 s->ybase += s->first_glyph->voffset;
25008 #ifdef HAVE_XWIDGETS
25009 static void
25010 fill_xwidget_glyph_string (struct glyph_string *s)
25012 eassert (s->first_glyph->type == XWIDGET_GLYPH);
25013 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
25014 s->font = s->face->font;
25015 s->width = s->first_glyph->pixel_width;
25016 s->ybase += s->first_glyph->voffset;
25017 s->xwidget = s->first_glyph->u.xwidget;
25019 #endif
25020 /* Fill glyph string S from a sequence of stretch glyphs.
25022 START is the index of the first glyph to consider,
25023 END is the index of the last + 1.
25025 Value is the index of the first glyph not in S. */
25027 static int
25028 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
25030 struct glyph *glyph, *last;
25031 int voffset, face_id;
25033 eassert (s->first_glyph->type == STRETCH_GLYPH);
25035 glyph = s->row->glyphs[s->area] + start;
25036 last = s->row->glyphs[s->area] + end;
25037 face_id = glyph->face_id;
25038 s->face = FACE_FROM_ID (s->f, face_id);
25039 s->font = s->face->font;
25040 s->width = glyph->pixel_width;
25041 s->nchars = 1;
25042 voffset = glyph->voffset;
25044 for (++glyph;
25045 (glyph < last
25046 && glyph->type == STRETCH_GLYPH
25047 && glyph->voffset == voffset
25048 && glyph->face_id == face_id);
25049 ++glyph)
25050 s->width += glyph->pixel_width;
25052 /* Adjust base line for subscript/superscript text. */
25053 s->ybase += voffset;
25055 /* The case that face->gc == 0 is handled when drawing the glyph
25056 string by calling prepare_face_for_display. */
25057 eassert (s->face);
25058 return glyph - s->row->glyphs[s->area];
25061 static struct font_metrics *
25062 get_per_char_metric (struct font *font, XChar2b *char2b)
25064 static struct font_metrics metrics;
25065 unsigned code;
25067 if (! font)
25068 return NULL;
25069 code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
25070 if (code == FONT_INVALID_CODE)
25071 return NULL;
25072 font->driver->text_extents (font, &code, 1, &metrics);
25073 return &metrics;
25076 /* A subroutine that computes "normal" values of ASCENT and DESCENT
25077 for FONT. Values are taken from font-global ones, except for fonts
25078 that claim preposterously large values, but whose glyphs actually
25079 have reasonable dimensions. C is the character to use for metrics
25080 if the font-global values are too large; if C is negative, the
25081 function selects a default character. */
25082 static void
25083 normal_char_ascent_descent (struct font *font, int c, int *ascent, int *descent)
25085 *ascent = FONT_BASE (font);
25086 *descent = FONT_DESCENT (font);
25088 if (FONT_TOO_HIGH (font))
25090 XChar2b char2b;
25092 /* Get metrics of C, defaulting to a reasonably sized ASCII
25093 character. */
25094 if (get_char_glyph_code (c >= 0 ? c : '{', font, &char2b))
25096 struct font_metrics *pcm = get_per_char_metric (font, &char2b);
25098 if (!(pcm->width == 0 && pcm->rbearing == 0 && pcm->lbearing == 0))
25100 /* We add 1 pixel to character dimensions as heuristics
25101 that produces nicer display, e.g. when the face has
25102 the box attribute. */
25103 *ascent = pcm->ascent + 1;
25104 *descent = pcm->descent + 1;
25110 /* A subroutine that computes a reasonable "normal character height"
25111 for fonts that claim preposterously large vertical dimensions, but
25112 whose glyphs are actually reasonably sized. C is the character
25113 whose metrics to use for those fonts, or -1 for default
25114 character. */
25115 static int
25116 normal_char_height (struct font *font, int c)
25118 int ascent, descent;
25120 normal_char_ascent_descent (font, c, &ascent, &descent);
25122 return ascent + descent;
25125 /* EXPORT for RIF:
25126 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
25127 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
25128 assumed to be zero. */
25130 void
25131 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
25133 *left = *right = 0;
25135 if (glyph->type == CHAR_GLYPH)
25137 XChar2b char2b;
25138 struct face *face = get_glyph_face_and_encoding (f, glyph, &char2b);
25139 if (face->font)
25141 struct font_metrics *pcm = get_per_char_metric (face->font, &char2b);
25142 if (pcm)
25144 if (pcm->rbearing > pcm->width)
25145 *right = pcm->rbearing - pcm->width;
25146 if (pcm->lbearing < 0)
25147 *left = -pcm->lbearing;
25151 else if (glyph->type == COMPOSITE_GLYPH)
25153 if (! glyph->u.cmp.automatic)
25155 struct composition *cmp = composition_table[glyph->u.cmp.id];
25157 if (cmp->rbearing > cmp->pixel_width)
25158 *right = cmp->rbearing - cmp->pixel_width;
25159 if (cmp->lbearing < 0)
25160 *left = - cmp->lbearing;
25162 else
25164 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
25165 struct font_metrics metrics;
25167 composition_gstring_width (gstring, glyph->slice.cmp.from,
25168 glyph->slice.cmp.to + 1, &metrics);
25169 if (metrics.rbearing > metrics.width)
25170 *right = metrics.rbearing - metrics.width;
25171 if (metrics.lbearing < 0)
25172 *left = - metrics.lbearing;
25178 /* Return the index of the first glyph preceding glyph string S that
25179 is overwritten by S because of S's left overhang. Value is -1
25180 if no glyphs are overwritten. */
25182 static int
25183 left_overwritten (struct glyph_string *s)
25185 int k;
25187 if (s->left_overhang)
25189 int x = 0, i;
25190 struct glyph *glyphs = s->row->glyphs[s->area];
25191 int first = s->first_glyph - glyphs;
25193 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
25194 x -= glyphs[i].pixel_width;
25196 k = i + 1;
25198 else
25199 k = -1;
25201 return k;
25205 /* Return the index of the first glyph preceding glyph string S that
25206 is overwriting S because of its right overhang. Value is -1 if no
25207 glyph in front of S overwrites S. */
25209 static int
25210 left_overwriting (struct glyph_string *s)
25212 int i, k, x;
25213 struct glyph *glyphs = s->row->glyphs[s->area];
25214 int first = s->first_glyph - glyphs;
25216 k = -1;
25217 x = 0;
25218 for (i = first - 1; i >= 0; --i)
25220 int left, right;
25221 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
25222 if (x + right > 0)
25223 k = i;
25224 x -= glyphs[i].pixel_width;
25227 return k;
25231 /* Return the index of the last glyph following glyph string S that is
25232 overwritten by S because of S's right overhang. Value is -1 if
25233 no such glyph is found. */
25235 static int
25236 right_overwritten (struct glyph_string *s)
25238 int k = -1;
25240 if (s->right_overhang)
25242 int x = 0, i;
25243 struct glyph *glyphs = s->row->glyphs[s->area];
25244 int first = (s->first_glyph - glyphs
25245 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
25246 int end = s->row->used[s->area];
25248 for (i = first; i < end && s->right_overhang > x; ++i)
25249 x += glyphs[i].pixel_width;
25251 k = i;
25254 return k;
25258 /* Return the index of the last glyph following glyph string S that
25259 overwrites S because of its left overhang. Value is negative
25260 if no such glyph is found. */
25262 static int
25263 right_overwriting (struct glyph_string *s)
25265 int i, k, x;
25266 int end = s->row->used[s->area];
25267 struct glyph *glyphs = s->row->glyphs[s->area];
25268 int first = (s->first_glyph - glyphs
25269 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
25271 k = -1;
25272 x = 0;
25273 for (i = first; i < end; ++i)
25275 int left, right;
25276 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
25277 if (x - left < 0)
25278 k = i;
25279 x += glyphs[i].pixel_width;
25282 return k;
25286 /* Set background width of glyph string S. START is the index of the
25287 first glyph following S. LAST_X is the right-most x-position + 1
25288 in the drawing area. */
25290 static void
25291 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
25293 /* If the face of this glyph string has to be drawn to the end of
25294 the drawing area, set S->extends_to_end_of_line_p. */
25296 if (start == s->row->used[s->area]
25297 && ((s->row->fill_line_p
25298 && (s->hl == DRAW_NORMAL_TEXT
25299 || s->hl == DRAW_IMAGE_RAISED
25300 || s->hl == DRAW_IMAGE_SUNKEN))
25301 || s->hl == DRAW_MOUSE_FACE))
25302 s->extends_to_end_of_line_p = true;
25304 /* If S extends its face to the end of the line, set its
25305 background_width to the distance to the right edge of the drawing
25306 area. */
25307 if (s->extends_to_end_of_line_p)
25308 s->background_width = last_x - s->x + 1;
25309 else
25310 s->background_width = s->width;
25314 /* Compute overhangs and x-positions for glyph string S and its
25315 predecessors, or successors. X is the starting x-position for S.
25316 BACKWARD_P means process predecessors. */
25318 static void
25319 compute_overhangs_and_x (struct glyph_string *s, int x, bool backward_p)
25321 if (backward_p)
25323 while (s)
25325 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
25326 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
25327 x -= s->width;
25328 s->x = x;
25329 s = s->prev;
25332 else
25334 while (s)
25336 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
25337 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
25338 s->x = x;
25339 x += s->width;
25340 s = s->next;
25347 /* The following macros are only called from draw_glyphs below.
25348 They reference the following parameters of that function directly:
25349 `w', `row', `area', and `overlap_p'
25350 as well as the following local variables:
25351 `s', `f', and `hdc' (in W32) */
25353 #ifdef HAVE_NTGUI
25354 /* On W32, silently add local `hdc' variable to argument list of
25355 init_glyph_string. */
25356 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
25357 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
25358 #else
25359 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
25360 init_glyph_string (s, char2b, w, row, area, start, hl)
25361 #endif
25363 /* Add a glyph string for a stretch glyph to the list of strings
25364 between HEAD and TAIL. START is the index of the stretch glyph in
25365 row area AREA of glyph row ROW. END is the index of the last glyph
25366 in that glyph row area. X is the current output position assigned
25367 to the new glyph string constructed. HL overrides that face of the
25368 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
25369 is the right-most x-position of the drawing area. */
25371 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
25372 and below -- keep them on one line. */
25373 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
25374 do \
25376 s = alloca (sizeof *s); \
25377 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
25378 START = fill_stretch_glyph_string (s, START, END); \
25379 append_glyph_string (&HEAD, &TAIL, s); \
25380 s->x = (X); \
25382 while (false)
25385 /* Add a glyph string for an image glyph to the list of strings
25386 between HEAD and TAIL. START is the index of the image glyph in
25387 row area AREA of glyph row ROW. END is the index of the last glyph
25388 in that glyph row area. X is the current output position assigned
25389 to the new glyph string constructed. HL overrides that face of the
25390 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
25391 is the right-most x-position of the drawing area. */
25393 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
25394 do \
25396 s = alloca (sizeof *s); \
25397 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
25398 fill_image_glyph_string (s); \
25399 append_glyph_string (&HEAD, &TAIL, s); \
25400 ++START; \
25401 s->x = (X); \
25403 while (false)
25405 #ifndef HAVE_XWIDGETS
25406 # define BUILD_XWIDGET_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
25407 eassume (false)
25408 #else
25409 # define BUILD_XWIDGET_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
25410 do \
25412 s = alloca (sizeof *s); \
25413 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
25414 fill_xwidget_glyph_string (s); \
25415 append_glyph_string (&(HEAD), &(TAIL), s); \
25416 ++(START); \
25417 s->x = (X); \
25419 while (false)
25420 #endif
25422 /* Add a glyph string for a sequence of character glyphs to the list
25423 of strings between HEAD and TAIL. START is the index of the first
25424 glyph in row area AREA of glyph row ROW that is part of the new
25425 glyph string. END is the index of the last glyph in that glyph row
25426 area. X is the current output position assigned to the new glyph
25427 string constructed. HL overrides that face of the glyph; e.g. it
25428 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
25429 right-most x-position of the drawing area. */
25431 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
25432 do \
25434 int face_id; \
25435 XChar2b *char2b; \
25437 face_id = (row)->glyphs[area][START].face_id; \
25439 s = alloca (sizeof *s); \
25440 SAFE_NALLOCA (char2b, 1, (END) - (START)); \
25441 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
25442 append_glyph_string (&HEAD, &TAIL, s); \
25443 s->x = (X); \
25444 START = fill_glyph_string (s, face_id, START, END, overlaps); \
25446 while (false)
25449 /* Add a glyph string for a composite sequence to the list of strings
25450 between HEAD and TAIL. START is the index of the first glyph in
25451 row area AREA of glyph row ROW that is part of the new glyph
25452 string. END is the index of the last glyph in that glyph row area.
25453 X is the current output position assigned to the new glyph string
25454 constructed. HL overrides that face of the glyph; e.g. it is
25455 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
25456 x-position of the drawing area. */
25458 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
25459 do { \
25460 int face_id = (row)->glyphs[area][START].face_id; \
25461 struct face *base_face = FACE_FROM_ID (f, face_id); \
25462 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
25463 struct composition *cmp = composition_table[cmp_id]; \
25464 XChar2b *char2b; \
25465 struct glyph_string *first_s = NULL; \
25466 int n; \
25468 SAFE_NALLOCA (char2b, 1, cmp->glyph_len); \
25470 /* Make glyph_strings for each glyph sequence that is drawable by \
25471 the same face, and append them to HEAD/TAIL. */ \
25472 for (n = 0; n < cmp->glyph_len;) \
25474 s = alloca (sizeof *s); \
25475 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
25476 append_glyph_string (&(HEAD), &(TAIL), s); \
25477 s->cmp = cmp; \
25478 s->cmp_from = n; \
25479 s->x = (X); \
25480 if (n == 0) \
25481 first_s = s; \
25482 n = fill_composite_glyph_string (s, base_face, overlaps); \
25485 ++START; \
25486 s = first_s; \
25487 } while (false)
25490 /* Add a glyph string for a glyph-string sequence to the list of strings
25491 between HEAD and TAIL. */
25493 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
25494 do { \
25495 int face_id; \
25496 XChar2b *char2b; \
25497 Lisp_Object gstring; \
25499 face_id = (row)->glyphs[area][START].face_id; \
25500 gstring = (composition_gstring_from_id \
25501 ((row)->glyphs[area][START].u.cmp.id)); \
25502 s = alloca (sizeof *s); \
25503 SAFE_NALLOCA (char2b, 1, LGSTRING_GLYPH_LEN (gstring)); \
25504 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
25505 append_glyph_string (&(HEAD), &(TAIL), s); \
25506 s->x = (X); \
25507 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
25508 } while (false)
25511 /* Add a glyph string for a sequence of glyphless character's glyphs
25512 to the list of strings between HEAD and TAIL. The meanings of
25513 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
25515 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
25516 do \
25518 int face_id; \
25520 face_id = (row)->glyphs[area][START].face_id; \
25522 s = alloca (sizeof *s); \
25523 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
25524 append_glyph_string (&HEAD, &TAIL, s); \
25525 s->x = (X); \
25526 START = fill_glyphless_glyph_string (s, face_id, START, END, \
25527 overlaps); \
25529 while (false)
25532 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
25533 of AREA of glyph row ROW on window W between indices START and END.
25534 HL overrides the face for drawing glyph strings, e.g. it is
25535 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
25536 x-positions of the drawing area.
25538 This is an ugly monster macro construct because we must use alloca
25539 to allocate glyph strings (because draw_glyphs can be called
25540 asynchronously). */
25542 #define BUILD_GLYPH_STRINGS_1(START, END, HEAD, TAIL, HL, X, LAST_X) \
25543 do \
25545 HEAD = TAIL = NULL; \
25546 while (START < END) \
25548 struct glyph *first_glyph = (row)->glyphs[area] + START; \
25549 switch (first_glyph->type) \
25551 case CHAR_GLYPH: \
25552 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
25553 HL, X, LAST_X); \
25554 break; \
25556 case COMPOSITE_GLYPH: \
25557 if (first_glyph->u.cmp.automatic) \
25558 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
25559 HL, X, LAST_X); \
25560 else \
25561 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
25562 HL, X, LAST_X); \
25563 break; \
25565 case STRETCH_GLYPH: \
25566 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
25567 HL, X, LAST_X); \
25568 break; \
25570 case IMAGE_GLYPH: \
25571 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
25572 HL, X, LAST_X); \
25573 break;
25575 #define BUILD_GLYPH_STRINGS_XW(START, END, HEAD, TAIL, HL, X, LAST_X) \
25576 case XWIDGET_GLYPH: \
25577 BUILD_XWIDGET_GLYPH_STRING (START, END, HEAD, TAIL, \
25578 HL, X, LAST_X); \
25579 break;
25581 #define BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X) \
25582 case GLYPHLESS_GLYPH: \
25583 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
25584 HL, X, LAST_X); \
25585 break; \
25587 default: \
25588 emacs_abort (); \
25591 if (s) \
25593 set_glyph_string_background_width (s, START, LAST_X); \
25594 (X) += s->width; \
25597 } while (false)
25600 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
25601 BUILD_GLYPH_STRINGS_1(START, END, HEAD, TAIL, HL, X, LAST_X) \
25602 BUILD_GLYPH_STRINGS_XW(START, END, HEAD, TAIL, HL, X, LAST_X) \
25603 BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X)
25606 /* Draw glyphs between START and END in AREA of ROW on window W,
25607 starting at x-position X. X is relative to AREA in W. HL is a
25608 face-override with the following meaning:
25610 DRAW_NORMAL_TEXT draw normally
25611 DRAW_CURSOR draw in cursor face
25612 DRAW_MOUSE_FACE draw in mouse face.
25613 DRAW_INVERSE_VIDEO draw in mode line face
25614 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
25615 DRAW_IMAGE_RAISED draw an image with a raised relief around it
25617 If OVERLAPS is non-zero, draw only the foreground of characters and
25618 clip to the physical height of ROW. Non-zero value also defines
25619 the overlapping part to be drawn:
25621 OVERLAPS_PRED overlap with preceding rows
25622 OVERLAPS_SUCC overlap with succeeding rows
25623 OVERLAPS_BOTH overlap with both preceding/succeeding rows
25624 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
25626 Value is the x-position reached, relative to AREA of W. */
25628 static int
25629 draw_glyphs (struct window *w, int x, struct glyph_row *row,
25630 enum glyph_row_area area, ptrdiff_t start, ptrdiff_t end,
25631 enum draw_glyphs_face hl, int overlaps)
25633 struct glyph_string *head, *tail;
25634 struct glyph_string *s;
25635 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
25636 int i, j, x_reached, last_x, area_left = 0;
25637 struct frame *f = XFRAME (WINDOW_FRAME (w));
25638 DECLARE_HDC (hdc);
25640 ALLOCATE_HDC (hdc, f);
25642 /* Let's rather be paranoid than getting a SEGV. */
25643 end = min (end, row->used[area]);
25644 start = clip_to_bounds (0, start, end);
25646 /* Translate X to frame coordinates. Set last_x to the right
25647 end of the drawing area. */
25648 if (row->full_width_p)
25650 /* X is relative to the left edge of W, without scroll bars
25651 or fringes. */
25652 area_left = WINDOW_LEFT_EDGE_X (w);
25653 last_x = (WINDOW_LEFT_EDGE_X (w) + WINDOW_PIXEL_WIDTH (w)
25654 - (row->mode_line_p ? WINDOW_RIGHT_DIVIDER_WIDTH (w) : 0));
25656 else
25658 area_left = window_box_left (w, area);
25659 last_x = area_left + window_box_width (w, area);
25661 x += area_left;
25663 /* Build a doubly-linked list of glyph_string structures between
25664 head and tail from what we have to draw. Note that the macro
25665 BUILD_GLYPH_STRINGS will modify its start parameter. That's
25666 the reason we use a separate variable `i'. */
25667 i = start;
25668 USE_SAFE_ALLOCA;
25669 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
25670 if (tail)
25671 x_reached = tail->x + tail->background_width;
25672 else
25673 x_reached = x;
25675 /* If there are any glyphs with lbearing < 0 or rbearing > width in
25676 the row, redraw some glyphs in front or following the glyph
25677 strings built above. */
25678 if (head && !overlaps && row->contains_overlapping_glyphs_p)
25680 struct glyph_string *h, *t;
25681 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
25682 int mouse_beg_col UNINIT, mouse_end_col UNINIT;
25683 bool check_mouse_face = false;
25684 int dummy_x = 0;
25686 /* If mouse highlighting is on, we may need to draw adjacent
25687 glyphs using mouse-face highlighting. */
25688 if (area == TEXT_AREA && row->mouse_face_p
25689 && hlinfo->mouse_face_beg_row >= 0
25690 && hlinfo->mouse_face_end_row >= 0)
25692 ptrdiff_t row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
25694 if (row_vpos >= hlinfo->mouse_face_beg_row
25695 && row_vpos <= hlinfo->mouse_face_end_row)
25697 check_mouse_face = true;
25698 mouse_beg_col = (row_vpos == hlinfo->mouse_face_beg_row)
25699 ? hlinfo->mouse_face_beg_col : 0;
25700 mouse_end_col = (row_vpos == hlinfo->mouse_face_end_row)
25701 ? hlinfo->mouse_face_end_col
25702 : row->used[TEXT_AREA];
25706 /* Compute overhangs for all glyph strings. */
25707 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
25708 for (s = head; s; s = s->next)
25709 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
25711 /* Prepend glyph strings for glyphs in front of the first glyph
25712 string that are overwritten because of the first glyph
25713 string's left overhang. The background of all strings
25714 prepended must be drawn because the first glyph string
25715 draws over it. */
25716 i = left_overwritten (head);
25717 if (i >= 0)
25719 enum draw_glyphs_face overlap_hl;
25721 /* If this row contains mouse highlighting, attempt to draw
25722 the overlapped glyphs with the correct highlight. This
25723 code fails if the overlap encompasses more than one glyph
25724 and mouse-highlight spans only some of these glyphs.
25725 However, making it work perfectly involves a lot more
25726 code, and I don't know if the pathological case occurs in
25727 practice, so we'll stick to this for now. --- cyd */
25728 if (check_mouse_face
25729 && mouse_beg_col < start && mouse_end_col > i)
25730 overlap_hl = DRAW_MOUSE_FACE;
25731 else
25732 overlap_hl = DRAW_NORMAL_TEXT;
25734 if (hl != overlap_hl)
25735 clip_head = head;
25736 j = i;
25737 BUILD_GLYPH_STRINGS (j, start, h, t,
25738 overlap_hl, dummy_x, last_x);
25739 start = i;
25740 compute_overhangs_and_x (t, head->x, true);
25741 prepend_glyph_string_lists (&head, &tail, h, t);
25742 if (clip_head == NULL)
25743 clip_head = head;
25746 /* Prepend glyph strings for glyphs in front of the first glyph
25747 string that overwrite that glyph string because of their
25748 right overhang. For these strings, only the foreground must
25749 be drawn, because it draws over the glyph string at `head'.
25750 The background must not be drawn because this would overwrite
25751 right overhangs of preceding glyphs for which no glyph
25752 strings exist. */
25753 i = left_overwriting (head);
25754 if (i >= 0)
25756 enum draw_glyphs_face overlap_hl;
25758 if (check_mouse_face
25759 && mouse_beg_col < start && mouse_end_col > i)
25760 overlap_hl = DRAW_MOUSE_FACE;
25761 else
25762 overlap_hl = DRAW_NORMAL_TEXT;
25764 if (hl == overlap_hl || clip_head == NULL)
25765 clip_head = head;
25766 BUILD_GLYPH_STRINGS (i, start, h, t,
25767 overlap_hl, dummy_x, last_x);
25768 for (s = h; s; s = s->next)
25769 s->background_filled_p = true;
25770 compute_overhangs_and_x (t, head->x, true);
25771 prepend_glyph_string_lists (&head, &tail, h, t);
25774 /* Append glyphs strings for glyphs following the last glyph
25775 string tail that are overwritten by tail. The background of
25776 these strings has to be drawn because tail's foreground draws
25777 over it. */
25778 i = right_overwritten (tail);
25779 if (i >= 0)
25781 enum draw_glyphs_face overlap_hl;
25783 if (check_mouse_face
25784 && mouse_beg_col < i && mouse_end_col > end)
25785 overlap_hl = DRAW_MOUSE_FACE;
25786 else
25787 overlap_hl = DRAW_NORMAL_TEXT;
25789 if (hl != overlap_hl)
25790 clip_tail = tail;
25791 BUILD_GLYPH_STRINGS (end, i, h, t,
25792 overlap_hl, x, last_x);
25793 /* Because BUILD_GLYPH_STRINGS updates the first argument,
25794 we don't have `end = i;' here. */
25795 compute_overhangs_and_x (h, tail->x + tail->width, false);
25796 append_glyph_string_lists (&head, &tail, h, t);
25797 if (clip_tail == NULL)
25798 clip_tail = tail;
25801 /* Append glyph strings for glyphs following the last glyph
25802 string tail that overwrite tail. The foreground of such
25803 glyphs has to be drawn because it writes into the background
25804 of tail. The background must not be drawn because it could
25805 paint over the foreground of following glyphs. */
25806 i = right_overwriting (tail);
25807 if (i >= 0)
25809 enum draw_glyphs_face overlap_hl;
25810 if (check_mouse_face
25811 && mouse_beg_col < i && mouse_end_col > end)
25812 overlap_hl = DRAW_MOUSE_FACE;
25813 else
25814 overlap_hl = DRAW_NORMAL_TEXT;
25816 if (hl == overlap_hl || clip_tail == NULL)
25817 clip_tail = tail;
25818 i++; /* We must include the Ith glyph. */
25819 BUILD_GLYPH_STRINGS (end, i, h, t,
25820 overlap_hl, x, last_x);
25821 for (s = h; s; s = s->next)
25822 s->background_filled_p = true;
25823 compute_overhangs_and_x (h, tail->x + tail->width, false);
25824 append_glyph_string_lists (&head, &tail, h, t);
25826 if (clip_head || clip_tail)
25827 for (s = head; s; s = s->next)
25829 s->clip_head = clip_head;
25830 s->clip_tail = clip_tail;
25834 /* Draw all strings. */
25835 for (s = head; s; s = s->next)
25836 FRAME_RIF (f)->draw_glyph_string (s);
25838 #ifndef HAVE_NS
25839 /* When focus a sole frame and move horizontally, this clears on_p
25840 causing a failure to erase prev cursor position. */
25841 if (area == TEXT_AREA
25842 && !row->full_width_p
25843 /* When drawing overlapping rows, only the glyph strings'
25844 foreground is drawn, which doesn't erase a cursor
25845 completely. */
25846 && !overlaps)
25848 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
25849 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
25850 : (tail ? tail->x + tail->background_width : x));
25851 x0 -= area_left;
25852 x1 -= area_left;
25854 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
25855 row->y, MATRIX_ROW_BOTTOM_Y (row));
25857 #endif
25859 /* Value is the x-position up to which drawn, relative to AREA of W.
25860 This doesn't include parts drawn because of overhangs. */
25861 if (row->full_width_p)
25862 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
25863 else
25864 x_reached -= area_left;
25866 RELEASE_HDC (hdc, f);
25868 SAFE_FREE ();
25869 return x_reached;
25872 /* Expand row matrix if too narrow. Don't expand if area
25873 is not present. */
25875 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
25877 if (!it->f->fonts_changed \
25878 && (it->glyph_row->glyphs[area] \
25879 < it->glyph_row->glyphs[area + 1])) \
25881 it->w->ncols_scale_factor++; \
25882 it->f->fonts_changed = true; \
25886 /* Store one glyph for IT->char_to_display in IT->glyph_row.
25887 Called from x_produce_glyphs when IT->glyph_row is non-null. */
25889 static void
25890 append_glyph (struct it *it)
25892 struct glyph *glyph;
25893 enum glyph_row_area area = it->area;
25895 eassert (it->glyph_row);
25896 eassert (it->char_to_display != '\n' && it->char_to_display != '\t');
25898 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
25899 if (glyph < it->glyph_row->glyphs[area + 1])
25901 /* If the glyph row is reversed, we need to prepend the glyph
25902 rather than append it. */
25903 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25905 struct glyph *g;
25907 /* Make room for the additional glyph. */
25908 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
25909 g[1] = *g;
25910 glyph = it->glyph_row->glyphs[area];
25912 glyph->charpos = CHARPOS (it->position);
25913 glyph->object = it->object;
25914 if (it->pixel_width > 0)
25916 eassert (it->pixel_width <= SHRT_MAX);
25917 glyph->pixel_width = it->pixel_width;
25918 glyph->padding_p = false;
25920 else
25922 /* Assure at least 1-pixel width. Otherwise, cursor can't
25923 be displayed correctly. */
25924 glyph->pixel_width = 1;
25925 glyph->padding_p = true;
25927 glyph->ascent = it->ascent;
25928 glyph->descent = it->descent;
25929 glyph->voffset = it->voffset;
25930 glyph->type = CHAR_GLYPH;
25931 glyph->avoid_cursor_p = it->avoid_cursor_p;
25932 glyph->multibyte_p = it->multibyte_p;
25933 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25935 /* In R2L rows, the left and the right box edges need to be
25936 drawn in reverse direction. */
25937 glyph->right_box_line_p = it->start_of_box_run_p;
25938 glyph->left_box_line_p = it->end_of_box_run_p;
25940 else
25942 glyph->left_box_line_p = it->start_of_box_run_p;
25943 glyph->right_box_line_p = it->end_of_box_run_p;
25945 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
25946 || it->phys_descent > it->descent);
25947 glyph->glyph_not_available_p = it->glyph_not_available_p;
25948 glyph->face_id = it->face_id;
25949 glyph->u.ch = it->char_to_display;
25950 glyph->slice.img = null_glyph_slice;
25951 glyph->font_type = FONT_TYPE_UNKNOWN;
25952 if (it->bidi_p)
25954 glyph->resolved_level = it->bidi_it.resolved_level;
25955 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
25956 glyph->bidi_type = it->bidi_it.type;
25958 else
25960 glyph->resolved_level = 0;
25961 glyph->bidi_type = UNKNOWN_BT;
25963 ++it->glyph_row->used[area];
25965 else
25966 IT_EXPAND_MATRIX_WIDTH (it, area);
25969 /* Store one glyph for the composition IT->cmp_it.id in
25970 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
25971 non-null. */
25973 static void
25974 append_composite_glyph (struct it *it)
25976 struct glyph *glyph;
25977 enum glyph_row_area area = it->area;
25979 eassert (it->glyph_row);
25981 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
25982 if (glyph < it->glyph_row->glyphs[area + 1])
25984 /* If the glyph row is reversed, we need to prepend the glyph
25985 rather than append it. */
25986 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
25988 struct glyph *g;
25990 /* Make room for the new glyph. */
25991 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
25992 g[1] = *g;
25993 glyph = it->glyph_row->glyphs[it->area];
25995 glyph->charpos = it->cmp_it.charpos;
25996 glyph->object = it->object;
25997 eassert (it->pixel_width <= SHRT_MAX);
25998 glyph->pixel_width = it->pixel_width;
25999 glyph->ascent = it->ascent;
26000 glyph->descent = it->descent;
26001 glyph->voffset = it->voffset;
26002 glyph->type = COMPOSITE_GLYPH;
26003 if (it->cmp_it.ch < 0)
26005 glyph->u.cmp.automatic = false;
26006 glyph->u.cmp.id = it->cmp_it.id;
26007 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
26009 else
26011 glyph->u.cmp.automatic = true;
26012 glyph->u.cmp.id = it->cmp_it.id;
26013 glyph->slice.cmp.from = it->cmp_it.from;
26014 glyph->slice.cmp.to = it->cmp_it.to - 1;
26016 glyph->avoid_cursor_p = it->avoid_cursor_p;
26017 glyph->multibyte_p = it->multibyte_p;
26018 if (it->glyph_row->reversed_p && area == TEXT_AREA)
26020 /* In R2L rows, the left and the right box edges need to be
26021 drawn in reverse direction. */
26022 glyph->right_box_line_p = it->start_of_box_run_p;
26023 glyph->left_box_line_p = it->end_of_box_run_p;
26025 else
26027 glyph->left_box_line_p = it->start_of_box_run_p;
26028 glyph->right_box_line_p = it->end_of_box_run_p;
26030 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
26031 || it->phys_descent > it->descent);
26032 glyph->padding_p = false;
26033 glyph->glyph_not_available_p = false;
26034 glyph->face_id = it->face_id;
26035 glyph->font_type = FONT_TYPE_UNKNOWN;
26036 if (it->bidi_p)
26038 glyph->resolved_level = it->bidi_it.resolved_level;
26039 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
26040 glyph->bidi_type = it->bidi_it.type;
26042 ++it->glyph_row->used[area];
26044 else
26045 IT_EXPAND_MATRIX_WIDTH (it, area);
26049 /* Change IT->ascent and IT->height according to the setting of
26050 IT->voffset. */
26052 static void
26053 take_vertical_position_into_account (struct it *it)
26055 if (it->voffset)
26057 if (it->voffset < 0)
26058 /* Increase the ascent so that we can display the text higher
26059 in the line. */
26060 it->ascent -= it->voffset;
26061 else
26062 /* Increase the descent so that we can display the text lower
26063 in the line. */
26064 it->descent += it->voffset;
26069 /* Produce glyphs/get display metrics for the image IT is loaded with.
26070 See the description of struct display_iterator in dispextern.h for
26071 an overview of struct display_iterator. */
26073 static void
26074 produce_image_glyph (struct it *it)
26076 struct image *img;
26077 struct face *face;
26078 int glyph_ascent, crop;
26079 struct glyph_slice slice;
26081 eassert (it->what == IT_IMAGE);
26083 face = FACE_FROM_ID (it->f, it->face_id);
26084 /* Make sure X resources of the face is loaded. */
26085 prepare_face_for_display (it->f, face);
26087 if (it->image_id < 0)
26089 /* Fringe bitmap. */
26090 it->ascent = it->phys_ascent = 0;
26091 it->descent = it->phys_descent = 0;
26092 it->pixel_width = 0;
26093 it->nglyphs = 0;
26094 return;
26097 img = IMAGE_FROM_ID (it->f, it->image_id);
26098 /* Make sure X resources of the image is loaded. */
26099 prepare_image_for_display (it->f, img);
26101 slice.x = slice.y = 0;
26102 slice.width = img->width;
26103 slice.height = img->height;
26105 if (INTEGERP (it->slice.x))
26106 slice.x = XINT (it->slice.x);
26107 else if (FLOATP (it->slice.x))
26108 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
26110 if (INTEGERP (it->slice.y))
26111 slice.y = XINT (it->slice.y);
26112 else if (FLOATP (it->slice.y))
26113 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
26115 if (INTEGERP (it->slice.width))
26116 slice.width = XINT (it->slice.width);
26117 else if (FLOATP (it->slice.width))
26118 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
26120 if (INTEGERP (it->slice.height))
26121 slice.height = XINT (it->slice.height);
26122 else if (FLOATP (it->slice.height))
26123 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
26125 if (slice.x >= img->width)
26126 slice.x = img->width;
26127 if (slice.y >= img->height)
26128 slice.y = img->height;
26129 if (slice.x + slice.width >= img->width)
26130 slice.width = img->width - slice.x;
26131 if (slice.y + slice.height > img->height)
26132 slice.height = img->height - slice.y;
26134 if (slice.width == 0 || slice.height == 0)
26135 return;
26137 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
26139 it->descent = slice.height - glyph_ascent;
26140 if (slice.y == 0)
26141 it->descent += img->vmargin;
26142 if (slice.y + slice.height == img->height)
26143 it->descent += img->vmargin;
26144 it->phys_descent = it->descent;
26146 it->pixel_width = slice.width;
26147 if (slice.x == 0)
26148 it->pixel_width += img->hmargin;
26149 if (slice.x + slice.width == img->width)
26150 it->pixel_width += img->hmargin;
26152 /* It's quite possible for images to have an ascent greater than
26153 their height, so don't get confused in that case. */
26154 if (it->descent < 0)
26155 it->descent = 0;
26157 it->nglyphs = 1;
26159 if (face->box != FACE_NO_BOX)
26161 if (face->box_line_width > 0)
26163 if (slice.y == 0)
26164 it->ascent += face->box_line_width;
26165 if (slice.y + slice.height == img->height)
26166 it->descent += face->box_line_width;
26169 if (it->start_of_box_run_p && slice.x == 0)
26170 it->pixel_width += eabs (face->box_line_width);
26171 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
26172 it->pixel_width += eabs (face->box_line_width);
26175 take_vertical_position_into_account (it);
26177 /* Automatically crop wide image glyphs at right edge so we can
26178 draw the cursor on same display row. */
26179 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
26180 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
26182 it->pixel_width -= crop;
26183 slice.width -= crop;
26186 if (it->glyph_row)
26188 struct glyph *glyph;
26189 enum glyph_row_area area = it->area;
26191 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
26192 if (it->glyph_row->reversed_p)
26194 struct glyph *g;
26196 /* Make room for the new glyph. */
26197 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
26198 g[1] = *g;
26199 glyph = it->glyph_row->glyphs[it->area];
26201 if (glyph < it->glyph_row->glyphs[area + 1])
26203 glyph->charpos = CHARPOS (it->position);
26204 glyph->object = it->object;
26205 glyph->pixel_width = clip_to_bounds (-1, it->pixel_width, SHRT_MAX);
26206 glyph->ascent = glyph_ascent;
26207 glyph->descent = it->descent;
26208 glyph->voffset = it->voffset;
26209 glyph->type = IMAGE_GLYPH;
26210 glyph->avoid_cursor_p = it->avoid_cursor_p;
26211 glyph->multibyte_p = it->multibyte_p;
26212 if (it->glyph_row->reversed_p && area == TEXT_AREA)
26214 /* In R2L rows, the left and the right box edges need to be
26215 drawn in reverse direction. */
26216 glyph->right_box_line_p = it->start_of_box_run_p;
26217 glyph->left_box_line_p = it->end_of_box_run_p;
26219 else
26221 glyph->left_box_line_p = it->start_of_box_run_p;
26222 glyph->right_box_line_p = it->end_of_box_run_p;
26224 glyph->overlaps_vertically_p = false;
26225 glyph->padding_p = false;
26226 glyph->glyph_not_available_p = false;
26227 glyph->face_id = it->face_id;
26228 glyph->u.img_id = img->id;
26229 glyph->slice.img = slice;
26230 glyph->font_type = FONT_TYPE_UNKNOWN;
26231 if (it->bidi_p)
26233 glyph->resolved_level = it->bidi_it.resolved_level;
26234 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
26235 glyph->bidi_type = it->bidi_it.type;
26237 ++it->glyph_row->used[area];
26239 else
26240 IT_EXPAND_MATRIX_WIDTH (it, area);
26244 static void
26245 produce_xwidget_glyph (struct it *it)
26247 #ifdef HAVE_XWIDGETS
26248 struct xwidget *xw;
26249 int glyph_ascent, crop;
26250 eassert (it->what == IT_XWIDGET);
26252 struct face *face = FACE_FROM_ID (it->f, it->face_id);
26253 /* Make sure X resources of the face is loaded. */
26254 prepare_face_for_display (it->f, face);
26256 xw = it->xwidget;
26257 it->ascent = it->phys_ascent = glyph_ascent = xw->height/2;
26258 it->descent = xw->height/2;
26259 it->phys_descent = it->descent;
26260 it->pixel_width = xw->width;
26261 /* It's quite possible for images to have an ascent greater than
26262 their height, so don't get confused in that case. */
26263 if (it->descent < 0)
26264 it->descent = 0;
26266 it->nglyphs = 1;
26268 if (face->box != FACE_NO_BOX)
26270 if (face->box_line_width > 0)
26272 it->ascent += face->box_line_width;
26273 it->descent += face->box_line_width;
26276 if (it->start_of_box_run_p)
26277 it->pixel_width += eabs (face->box_line_width);
26278 it->pixel_width += eabs (face->box_line_width);
26281 take_vertical_position_into_account (it);
26283 /* Automatically crop wide image glyphs at right edge so we can
26284 draw the cursor on same display row. */
26285 crop = it->pixel_width - (it->last_visible_x - it->current_x);
26286 if (crop > 0 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
26287 it->pixel_width -= crop;
26289 if (it->glyph_row)
26291 enum glyph_row_area area = it->area;
26292 struct glyph *glyph
26293 = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
26295 if (it->glyph_row->reversed_p)
26297 struct glyph *g;
26299 /* Make room for the new glyph. */
26300 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
26301 g[1] = *g;
26302 glyph = it->glyph_row->glyphs[it->area];
26304 if (glyph < it->glyph_row->glyphs[area + 1])
26306 glyph->charpos = CHARPOS (it->position);
26307 glyph->object = it->object;
26308 glyph->pixel_width = clip_to_bounds (-1, it->pixel_width, SHRT_MAX);
26309 glyph->ascent = glyph_ascent;
26310 glyph->descent = it->descent;
26311 glyph->voffset = it->voffset;
26312 glyph->type = XWIDGET_GLYPH;
26313 glyph->avoid_cursor_p = it->avoid_cursor_p;
26314 glyph->multibyte_p = it->multibyte_p;
26315 if (it->glyph_row->reversed_p && area == TEXT_AREA)
26317 /* In R2L rows, the left and the right box edges need to be
26318 drawn in reverse direction. */
26319 glyph->right_box_line_p = it->start_of_box_run_p;
26320 glyph->left_box_line_p = it->end_of_box_run_p;
26322 else
26324 glyph->left_box_line_p = it->start_of_box_run_p;
26325 glyph->right_box_line_p = it->end_of_box_run_p;
26327 glyph->overlaps_vertically_p = 0;
26328 glyph->padding_p = 0;
26329 glyph->glyph_not_available_p = 0;
26330 glyph->face_id = it->face_id;
26331 glyph->u.xwidget = it->xwidget;
26332 glyph->font_type = FONT_TYPE_UNKNOWN;
26333 if (it->bidi_p)
26335 glyph->resolved_level = it->bidi_it.resolved_level;
26336 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
26337 glyph->bidi_type = it->bidi_it.type;
26339 ++it->glyph_row->used[area];
26341 else
26342 IT_EXPAND_MATRIX_WIDTH (it, area);
26344 #endif
26347 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
26348 of the glyph, WIDTH and HEIGHT are the width and height of the
26349 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
26351 static void
26352 append_stretch_glyph (struct it *it, Lisp_Object object,
26353 int width, int height, int ascent)
26355 struct glyph *glyph;
26356 enum glyph_row_area area = it->area;
26358 eassert (ascent >= 0 && ascent <= height);
26360 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
26361 if (glyph < it->glyph_row->glyphs[area + 1])
26363 /* If the glyph row is reversed, we need to prepend the glyph
26364 rather than append it. */
26365 if (it->glyph_row->reversed_p && area == TEXT_AREA)
26367 struct glyph *g;
26369 /* Make room for the additional glyph. */
26370 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
26371 g[1] = *g;
26372 glyph = it->glyph_row->glyphs[area];
26374 /* Decrease the width of the first glyph of the row that
26375 begins before first_visible_x (e.g., due to hscroll).
26376 This is so the overall width of the row becomes smaller
26377 by the scroll amount, and the stretch glyph appended by
26378 extend_face_to_end_of_line will be wider, to shift the
26379 row glyphs to the right. (In L2R rows, the corresponding
26380 left-shift effect is accomplished by setting row->x to a
26381 negative value, which won't work with R2L rows.)
26383 This must leave us with a positive value of WIDTH, since
26384 otherwise the call to move_it_in_display_line_to at the
26385 beginning of display_line would have got past the entire
26386 first glyph, and then it->current_x would have been
26387 greater or equal to it->first_visible_x. */
26388 if (it->current_x < it->first_visible_x)
26389 width -= it->first_visible_x - it->current_x;
26390 eassert (width > 0);
26392 glyph->charpos = CHARPOS (it->position);
26393 glyph->object = object;
26394 /* FIXME: It would be better to use TYPE_MAX here, but
26395 __typeof__ is not portable enough... */
26396 glyph->pixel_width = clip_to_bounds (-1, width, SHRT_MAX);
26397 glyph->ascent = ascent;
26398 glyph->descent = height - ascent;
26399 glyph->voffset = it->voffset;
26400 glyph->type = STRETCH_GLYPH;
26401 glyph->avoid_cursor_p = it->avoid_cursor_p;
26402 glyph->multibyte_p = it->multibyte_p;
26403 if (it->glyph_row->reversed_p && area == TEXT_AREA)
26405 /* In R2L rows, the left and the right box edges need to be
26406 drawn in reverse direction. */
26407 glyph->right_box_line_p = it->start_of_box_run_p;
26408 glyph->left_box_line_p = it->end_of_box_run_p;
26410 else
26412 glyph->left_box_line_p = it->start_of_box_run_p;
26413 glyph->right_box_line_p = it->end_of_box_run_p;
26415 glyph->overlaps_vertically_p = false;
26416 glyph->padding_p = false;
26417 glyph->glyph_not_available_p = false;
26418 glyph->face_id = it->face_id;
26419 glyph->u.stretch.ascent = ascent;
26420 glyph->u.stretch.height = height;
26421 glyph->slice.img = null_glyph_slice;
26422 glyph->font_type = FONT_TYPE_UNKNOWN;
26423 if (it->bidi_p)
26425 glyph->resolved_level = it->bidi_it.resolved_level;
26426 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
26427 glyph->bidi_type = it->bidi_it.type;
26429 else
26431 glyph->resolved_level = 0;
26432 glyph->bidi_type = UNKNOWN_BT;
26434 ++it->glyph_row->used[area];
26436 else
26437 IT_EXPAND_MATRIX_WIDTH (it, area);
26440 #endif /* HAVE_WINDOW_SYSTEM */
26442 /* Produce a stretch glyph for iterator IT. IT->object is the value
26443 of the glyph property displayed. The value must be a list
26444 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
26445 being recognized:
26447 1. `:width WIDTH' specifies that the space should be WIDTH *
26448 canonical char width wide. WIDTH may be an integer or floating
26449 point number.
26451 2. `:relative-width FACTOR' specifies that the width of the stretch
26452 should be computed from the width of the first character having the
26453 `glyph' property, and should be FACTOR times that width.
26455 3. `:align-to HPOS' specifies that the space should be wide enough
26456 to reach HPOS, a value in canonical character units.
26458 Exactly one of the above pairs must be present.
26460 4. `:height HEIGHT' specifies that the height of the stretch produced
26461 should be HEIGHT, measured in canonical character units.
26463 5. `:relative-height FACTOR' specifies that the height of the
26464 stretch should be FACTOR times the height of the characters having
26465 the glyph property.
26467 Either none or exactly one of 4 or 5 must be present.
26469 6. `:ascent ASCENT' specifies that ASCENT percent of the height
26470 of the stretch should be used for the ascent of the stretch.
26471 ASCENT must be in the range 0 <= ASCENT <= 100. */
26473 void
26474 produce_stretch_glyph (struct it *it)
26476 /* (space :width WIDTH :height HEIGHT ...) */
26477 Lisp_Object prop, plist;
26478 int width = 0, height = 0, align_to = -1;
26479 bool zero_width_ok_p = false;
26480 double tem;
26481 struct font *font = NULL;
26483 #ifdef HAVE_WINDOW_SYSTEM
26484 int ascent = 0;
26485 bool zero_height_ok_p = false;
26487 if (FRAME_WINDOW_P (it->f))
26489 struct face *face = FACE_FROM_ID (it->f, it->face_id);
26490 font = face->font ? face->font : FRAME_FONT (it->f);
26491 prepare_face_for_display (it->f, face);
26493 #endif
26495 /* List should start with `space'. */
26496 eassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
26497 plist = XCDR (it->object);
26499 /* Compute the width of the stretch. */
26500 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
26501 && calc_pixel_width_or_height (&tem, it, prop, font, true, 0))
26503 /* Absolute width `:width WIDTH' specified and valid. */
26504 zero_width_ok_p = true;
26505 width = (int)tem;
26507 else if (prop = Fplist_get (plist, QCrelative_width), NUMVAL (prop) > 0)
26509 /* Relative width `:relative-width FACTOR' specified and valid.
26510 Compute the width of the characters having the `glyph'
26511 property. */
26512 struct it it2;
26513 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
26515 it2 = *it;
26516 if (it->multibyte_p)
26517 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
26518 else
26520 it2.c = it2.char_to_display = *p, it2.len = 1;
26521 if (! ASCII_CHAR_P (it2.c))
26522 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
26525 it2.glyph_row = NULL;
26526 it2.what = IT_CHARACTER;
26527 PRODUCE_GLYPHS (&it2);
26528 width = NUMVAL (prop) * it2.pixel_width;
26530 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
26531 && calc_pixel_width_or_height (&tem, it, prop, font, true,
26532 &align_to))
26534 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
26535 align_to = (align_to < 0
26537 : align_to - window_box_left_offset (it->w, TEXT_AREA));
26538 else if (align_to < 0)
26539 align_to = window_box_left_offset (it->w, TEXT_AREA);
26540 width = max (0, (int)tem + align_to - it->current_x);
26541 zero_width_ok_p = true;
26543 else
26544 /* Nothing specified -> width defaults to canonical char width. */
26545 width = FRAME_COLUMN_WIDTH (it->f);
26547 if (width <= 0 && (width < 0 || !zero_width_ok_p))
26548 width = 1;
26550 #ifdef HAVE_WINDOW_SYSTEM
26551 /* Compute height. */
26552 if (FRAME_WINDOW_P (it->f))
26554 int default_height = normal_char_height (font, ' ');
26556 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
26557 && calc_pixel_width_or_height (&tem, it, prop, font, false, 0))
26559 height = (int)tem;
26560 zero_height_ok_p = true;
26562 else if (prop = Fplist_get (plist, QCrelative_height),
26563 NUMVAL (prop) > 0)
26564 height = default_height * NUMVAL (prop);
26565 else
26566 height = default_height;
26568 if (height <= 0 && (height < 0 || !zero_height_ok_p))
26569 height = 1;
26571 /* Compute percentage of height used for ascent. If
26572 `:ascent ASCENT' is present and valid, use that. Otherwise,
26573 derive the ascent from the font in use. */
26574 if (prop = Fplist_get (plist, QCascent),
26575 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
26576 ascent = height * NUMVAL (prop) / 100.0;
26577 else if (!NILP (prop)
26578 && calc_pixel_width_or_height (&tem, it, prop, font, false, 0))
26579 ascent = min (max (0, (int)tem), height);
26580 else
26581 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
26583 else
26584 #endif /* HAVE_WINDOW_SYSTEM */
26585 height = 1;
26587 if (width > 0 && it->line_wrap != TRUNCATE
26588 && it->current_x + width > it->last_visible_x)
26590 width = it->last_visible_x - it->current_x;
26591 #ifdef HAVE_WINDOW_SYSTEM
26592 /* Subtract one more pixel from the stretch width, but only on
26593 GUI frames, since on a TTY each glyph is one "pixel" wide. */
26594 width -= FRAME_WINDOW_P (it->f);
26595 #endif
26598 if (width > 0 && height > 0 && it->glyph_row)
26600 Lisp_Object o_object = it->object;
26601 Lisp_Object object = it->stack[it->sp - 1].string;
26602 int n = width;
26604 if (!STRINGP (object))
26605 object = it->w->contents;
26606 #ifdef HAVE_WINDOW_SYSTEM
26607 if (FRAME_WINDOW_P (it->f))
26608 append_stretch_glyph (it, object, width, height, ascent);
26609 else
26610 #endif
26612 it->object = object;
26613 it->char_to_display = ' ';
26614 it->pixel_width = it->len = 1;
26615 while (n--)
26616 tty_append_glyph (it);
26617 it->object = o_object;
26621 it->pixel_width = width;
26622 #ifdef HAVE_WINDOW_SYSTEM
26623 if (FRAME_WINDOW_P (it->f))
26625 it->ascent = it->phys_ascent = ascent;
26626 it->descent = it->phys_descent = height - it->ascent;
26627 it->nglyphs = width > 0 && height > 0;
26628 take_vertical_position_into_account (it);
26630 else
26631 #endif
26632 it->nglyphs = width;
26635 /* Get information about special display element WHAT in an
26636 environment described by IT. WHAT is one of IT_TRUNCATION or
26637 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
26638 non-null glyph_row member. This function ensures that fields like
26639 face_id, c, len of IT are left untouched. */
26641 static void
26642 produce_special_glyphs (struct it *it, enum display_element_type what)
26644 struct it temp_it;
26645 Lisp_Object gc;
26646 GLYPH glyph;
26648 temp_it = *it;
26649 temp_it.object = Qnil;
26650 memset (&temp_it.current, 0, sizeof temp_it.current);
26652 if (what == IT_CONTINUATION)
26654 /* Continuation glyph. For R2L lines, we mirror it by hand. */
26655 if (it->bidi_it.paragraph_dir == R2L)
26656 SET_GLYPH_FROM_CHAR (glyph, '/');
26657 else
26658 SET_GLYPH_FROM_CHAR (glyph, '\\');
26659 if (it->dp
26660 && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
26662 /* FIXME: Should we mirror GC for R2L lines? */
26663 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
26664 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
26667 else if (what == IT_TRUNCATION)
26669 /* Truncation glyph. */
26670 SET_GLYPH_FROM_CHAR (glyph, '$');
26671 if (it->dp
26672 && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc)))
26674 /* FIXME: Should we mirror GC for R2L lines? */
26675 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
26676 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
26679 else
26680 emacs_abort ();
26682 #ifdef HAVE_WINDOW_SYSTEM
26683 /* On a GUI frame, when the right fringe (left fringe for R2L rows)
26684 is turned off, we precede the truncation/continuation glyphs by a
26685 stretch glyph whose width is computed such that these special
26686 glyphs are aligned at the window margin, even when very different
26687 fonts are used in different glyph rows. */
26688 if (FRAME_WINDOW_P (temp_it.f)
26689 /* init_iterator calls this with it->glyph_row == NULL, and it
26690 wants only the pixel width of the truncation/continuation
26691 glyphs. */
26692 && temp_it.glyph_row
26693 /* insert_left_trunc_glyphs calls us at the beginning of the
26694 row, and it has its own calculation of the stretch glyph
26695 width. */
26696 && temp_it.glyph_row->used[TEXT_AREA] > 0
26697 && (temp_it.glyph_row->reversed_p
26698 ? WINDOW_LEFT_FRINGE_WIDTH (temp_it.w)
26699 : WINDOW_RIGHT_FRINGE_WIDTH (temp_it.w)) == 0)
26701 int stretch_width = temp_it.last_visible_x - temp_it.current_x;
26703 if (stretch_width > 0)
26705 struct face *face = FACE_FROM_ID (temp_it.f, temp_it.face_id);
26706 struct font *font =
26707 face->font ? face->font : FRAME_FONT (temp_it.f);
26708 int stretch_ascent =
26709 (((temp_it.ascent + temp_it.descent)
26710 * FONT_BASE (font)) / FONT_HEIGHT (font));
26712 append_stretch_glyph (&temp_it, Qnil, stretch_width,
26713 temp_it.ascent + temp_it.descent,
26714 stretch_ascent);
26717 #endif
26719 temp_it.dp = NULL;
26720 temp_it.what = IT_CHARACTER;
26721 temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph);
26722 temp_it.face_id = GLYPH_FACE (glyph);
26723 temp_it.len = CHAR_BYTES (temp_it.c);
26725 PRODUCE_GLYPHS (&temp_it);
26726 it->pixel_width = temp_it.pixel_width;
26727 it->nglyphs = temp_it.nglyphs;
26730 #ifdef HAVE_WINDOW_SYSTEM
26732 /* Calculate line-height and line-spacing properties.
26733 An integer value specifies explicit pixel value.
26734 A float value specifies relative value to current face height.
26735 A cons (float . face-name) specifies relative value to
26736 height of specified face font.
26738 Returns height in pixels, or nil. */
26740 static Lisp_Object
26741 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
26742 int boff, bool override)
26744 Lisp_Object face_name = Qnil;
26745 int ascent, descent, height;
26747 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
26748 return val;
26750 if (CONSP (val))
26752 face_name = XCAR (val);
26753 val = XCDR (val);
26754 if (!NUMBERP (val))
26755 val = make_number (1);
26756 if (NILP (face_name))
26758 height = it->ascent + it->descent;
26759 goto scale;
26763 if (NILP (face_name))
26765 font = FRAME_FONT (it->f);
26766 boff = FRAME_BASELINE_OFFSET (it->f);
26768 else if (EQ (face_name, Qt))
26770 override = false;
26772 else
26774 int face_id;
26775 struct face *face;
26777 face_id = lookup_named_face (it->f, face_name, false);
26778 face = FACE_FROM_ID_OR_NULL (it->f, face_id);
26779 if (face == NULL || ((font = face->font) == NULL))
26780 return make_number (-1);
26781 boff = font->baseline_offset;
26782 if (font->vertical_centering)
26783 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
26786 normal_char_ascent_descent (font, -1, &ascent, &descent);
26788 if (override)
26790 it->override_ascent = ascent;
26791 it->override_descent = descent;
26792 it->override_boff = boff;
26795 height = ascent + descent;
26797 scale:
26798 if (FLOATP (val))
26799 height = (int)(XFLOAT_DATA (val) * height);
26800 else if (INTEGERP (val))
26801 height *= XINT (val);
26803 return make_number (height);
26807 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
26808 is a face ID to be used for the glyph. FOR_NO_FONT is true if
26809 and only if this is for a character for which no font was found.
26811 If the display method (it->glyphless_method) is
26812 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
26813 length of the acronym or the hexadecimal string, UPPER_XOFF and
26814 UPPER_YOFF are pixel offsets for the upper part of the string,
26815 LOWER_XOFF and LOWER_YOFF are for the lower part.
26817 For the other display methods, LEN through LOWER_YOFF are zero. */
26819 static void
26820 append_glyphless_glyph (struct it *it, int face_id, bool for_no_font, int len,
26821 short upper_xoff, short upper_yoff,
26822 short lower_xoff, short lower_yoff)
26824 struct glyph *glyph;
26825 enum glyph_row_area area = it->area;
26827 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
26828 if (glyph < it->glyph_row->glyphs[area + 1])
26830 /* If the glyph row is reversed, we need to prepend the glyph
26831 rather than append it. */
26832 if (it->glyph_row->reversed_p && area == TEXT_AREA)
26834 struct glyph *g;
26836 /* Make room for the additional glyph. */
26837 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
26838 g[1] = *g;
26839 glyph = it->glyph_row->glyphs[area];
26841 glyph->charpos = CHARPOS (it->position);
26842 glyph->object = it->object;
26843 eassert (it->pixel_width <= SHRT_MAX);
26844 glyph->pixel_width = it->pixel_width;
26845 glyph->ascent = it->ascent;
26846 glyph->descent = it->descent;
26847 glyph->voffset = it->voffset;
26848 glyph->type = GLYPHLESS_GLYPH;
26849 glyph->u.glyphless.method = it->glyphless_method;
26850 glyph->u.glyphless.for_no_font = for_no_font;
26851 glyph->u.glyphless.len = len;
26852 glyph->u.glyphless.ch = it->c;
26853 glyph->slice.glyphless.upper_xoff = upper_xoff;
26854 glyph->slice.glyphless.upper_yoff = upper_yoff;
26855 glyph->slice.glyphless.lower_xoff = lower_xoff;
26856 glyph->slice.glyphless.lower_yoff = lower_yoff;
26857 glyph->avoid_cursor_p = it->avoid_cursor_p;
26858 glyph->multibyte_p = it->multibyte_p;
26859 if (it->glyph_row->reversed_p && area == TEXT_AREA)
26861 /* In R2L rows, the left and the right box edges need to be
26862 drawn in reverse direction. */
26863 glyph->right_box_line_p = it->start_of_box_run_p;
26864 glyph->left_box_line_p = it->end_of_box_run_p;
26866 else
26868 glyph->left_box_line_p = it->start_of_box_run_p;
26869 glyph->right_box_line_p = it->end_of_box_run_p;
26871 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
26872 || it->phys_descent > it->descent);
26873 glyph->padding_p = false;
26874 glyph->glyph_not_available_p = false;
26875 glyph->face_id = face_id;
26876 glyph->font_type = FONT_TYPE_UNKNOWN;
26877 if (it->bidi_p)
26879 glyph->resolved_level = it->bidi_it.resolved_level;
26880 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
26881 glyph->bidi_type = it->bidi_it.type;
26883 ++it->glyph_row->used[area];
26885 else
26886 IT_EXPAND_MATRIX_WIDTH (it, area);
26890 /* Produce a glyph for a glyphless character for iterator IT.
26891 IT->glyphless_method specifies which method to use for displaying
26892 the character. See the description of enum
26893 glyphless_display_method in dispextern.h for the detail.
26895 FOR_NO_FONT is true if and only if this is for a character for
26896 which no font was found. ACRONYM, if non-nil, is an acronym string
26897 for the character. */
26899 static void
26900 produce_glyphless_glyph (struct it *it, bool for_no_font, Lisp_Object acronym)
26902 int face_id;
26903 struct face *face;
26904 struct font *font;
26905 int base_width, base_height, width, height;
26906 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
26907 int len;
26909 /* Get the metrics of the base font. We always refer to the current
26910 ASCII face. */
26911 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
26912 font = face->font ? face->font : FRAME_FONT (it->f);
26913 normal_char_ascent_descent (font, -1, &it->ascent, &it->descent);
26914 it->ascent += font->baseline_offset;
26915 it->descent -= font->baseline_offset;
26916 base_height = it->ascent + it->descent;
26917 base_width = font->average_width;
26919 face_id = merge_glyphless_glyph_face (it);
26921 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
26923 it->pixel_width = THIN_SPACE_WIDTH;
26924 len = 0;
26925 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
26927 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
26929 width = CHAR_WIDTH (it->c);
26930 if (width == 0)
26931 width = 1;
26932 else if (width > 4)
26933 width = 4;
26934 it->pixel_width = base_width * width;
26935 len = 0;
26936 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
26938 else
26940 char buf[7];
26941 const char *str;
26942 unsigned int code[6];
26943 int upper_len;
26944 int ascent, descent;
26945 struct font_metrics metrics_upper, metrics_lower;
26947 face = FACE_FROM_ID (it->f, face_id);
26948 font = face->font ? face->font : FRAME_FONT (it->f);
26949 prepare_face_for_display (it->f, face);
26951 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
26953 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
26954 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
26955 if (CONSP (acronym))
26956 acronym = XCAR (acronym);
26957 str = STRINGP (acronym) ? SSDATA (acronym) : "";
26959 else
26961 eassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
26962 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c + 0u);
26963 str = buf;
26965 for (len = 0; str[len] && ASCII_CHAR_P (str[len]) && len < 6; len++)
26966 code[len] = font->driver->encode_char (font, str[len]);
26967 upper_len = (len + 1) / 2;
26968 font->driver->text_extents (font, code, upper_len,
26969 &metrics_upper);
26970 font->driver->text_extents (font, code + upper_len, len - upper_len,
26971 &metrics_lower);
26975 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
26976 width = max (metrics_upper.width, metrics_lower.width) + 4;
26977 upper_xoff = upper_yoff = 2; /* the typical case */
26978 if (base_width >= width)
26980 /* Align the upper to the left, the lower to the right. */
26981 it->pixel_width = base_width;
26982 lower_xoff = base_width - 2 - metrics_lower.width;
26984 else
26986 /* Center the shorter one. */
26987 it->pixel_width = width;
26988 if (metrics_upper.width >= metrics_lower.width)
26989 lower_xoff = (width - metrics_lower.width) / 2;
26990 else
26992 /* FIXME: This code doesn't look right. It formerly was
26993 missing the "lower_xoff = 0;", which couldn't have
26994 been right since it left lower_xoff uninitialized. */
26995 lower_xoff = 0;
26996 upper_xoff = (width - metrics_upper.width) / 2;
27000 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
27001 top, bottom, and between upper and lower strings. */
27002 height = (metrics_upper.ascent + metrics_upper.descent
27003 + metrics_lower.ascent + metrics_lower.descent) + 5;
27004 /* Center vertically.
27005 H:base_height, D:base_descent
27006 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
27008 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
27009 descent = D - H/2 + h/2;
27010 lower_yoff = descent - 2 - ld;
27011 upper_yoff = lower_yoff - la - 1 - ud; */
27012 ascent = - (it->descent - (base_height + height + 1) / 2);
27013 descent = it->descent - (base_height - height) / 2;
27014 lower_yoff = descent - 2 - metrics_lower.descent;
27015 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
27016 - metrics_upper.descent);
27017 /* Don't make the height shorter than the base height. */
27018 if (height > base_height)
27020 it->ascent = ascent;
27021 it->descent = descent;
27025 it->phys_ascent = it->ascent;
27026 it->phys_descent = it->descent;
27027 if (it->glyph_row)
27028 append_glyphless_glyph (it, face_id, for_no_font, len,
27029 upper_xoff, upper_yoff,
27030 lower_xoff, lower_yoff);
27031 it->nglyphs = 1;
27032 take_vertical_position_into_account (it);
27036 /* RIF:
27037 Produce glyphs/get display metrics for the display element IT is
27038 loaded with. See the description of struct it in dispextern.h
27039 for an overview of struct it. */
27041 void
27042 x_produce_glyphs (struct it *it)
27044 int extra_line_spacing = it->extra_line_spacing;
27046 it->glyph_not_available_p = false;
27048 if (it->what == IT_CHARACTER)
27050 XChar2b char2b;
27051 struct face *face = FACE_FROM_ID (it->f, it->face_id);
27052 struct font *font = face->font;
27053 struct font_metrics *pcm = NULL;
27054 int boff; /* Baseline offset. */
27056 if (font == NULL)
27058 /* When no suitable font is found, display this character by
27059 the method specified in the first extra slot of
27060 Vglyphless_char_display. */
27061 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
27063 eassert (it->what == IT_GLYPHLESS);
27064 produce_glyphless_glyph (it, true,
27065 STRINGP (acronym) ? acronym : Qnil);
27066 goto done;
27069 boff = font->baseline_offset;
27070 if (font->vertical_centering)
27071 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
27073 if (it->char_to_display != '\n' && it->char_to_display != '\t')
27075 it->nglyphs = 1;
27077 if (it->override_ascent >= 0)
27079 it->ascent = it->override_ascent;
27080 it->descent = it->override_descent;
27081 boff = it->override_boff;
27083 else
27085 it->ascent = FONT_BASE (font) + boff;
27086 it->descent = FONT_DESCENT (font) - boff;
27089 if (get_char_glyph_code (it->char_to_display, font, &char2b))
27091 pcm = get_per_char_metric (font, &char2b);
27092 if (pcm->width == 0
27093 && pcm->rbearing == 0 && pcm->lbearing == 0)
27094 pcm = NULL;
27097 if (pcm)
27099 it->phys_ascent = pcm->ascent + boff;
27100 it->phys_descent = pcm->descent - boff;
27101 it->pixel_width = pcm->width;
27102 /* Don't use font-global values for ascent and descent
27103 if they result in an exceedingly large line height. */
27104 if (it->override_ascent < 0)
27106 if (FONT_TOO_HIGH (font))
27108 it->ascent = it->phys_ascent;
27109 it->descent = it->phys_descent;
27110 /* These limitations are enforced by an
27111 assertion near the end of this function. */
27112 if (it->ascent < 0)
27113 it->ascent = 0;
27114 if (it->descent < 0)
27115 it->descent = 0;
27119 else
27121 it->glyph_not_available_p = true;
27122 it->phys_ascent = it->ascent;
27123 it->phys_descent = it->descent;
27124 it->pixel_width = font->space_width;
27127 if (it->constrain_row_ascent_descent_p)
27129 if (it->descent > it->max_descent)
27131 it->ascent += it->descent - it->max_descent;
27132 it->descent = it->max_descent;
27134 if (it->ascent > it->max_ascent)
27136 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
27137 it->ascent = it->max_ascent;
27139 it->phys_ascent = min (it->phys_ascent, it->ascent);
27140 it->phys_descent = min (it->phys_descent, it->descent);
27141 extra_line_spacing = 0;
27144 /* If this is a space inside a region of text with
27145 `space-width' property, change its width. */
27146 bool stretched_p
27147 = it->char_to_display == ' ' && !NILP (it->space_width);
27148 if (stretched_p)
27149 it->pixel_width *= XFLOATINT (it->space_width);
27151 /* If face has a box, add the box thickness to the character
27152 height. If character has a box line to the left and/or
27153 right, add the box line width to the character's width. */
27154 if (face->box != FACE_NO_BOX)
27156 int thick = face->box_line_width;
27158 if (thick > 0)
27160 it->ascent += thick;
27161 it->descent += thick;
27163 else
27164 thick = -thick;
27166 if (it->start_of_box_run_p)
27167 it->pixel_width += thick;
27168 if (it->end_of_box_run_p)
27169 it->pixel_width += thick;
27172 /* If face has an overline, add the height of the overline
27173 (1 pixel) and a 1 pixel margin to the character height. */
27174 if (face->overline_p)
27175 it->ascent += overline_margin;
27177 if (it->constrain_row_ascent_descent_p)
27179 if (it->ascent > it->max_ascent)
27180 it->ascent = it->max_ascent;
27181 if (it->descent > it->max_descent)
27182 it->descent = it->max_descent;
27185 take_vertical_position_into_account (it);
27187 /* If we have to actually produce glyphs, do it. */
27188 if (it->glyph_row)
27190 if (stretched_p)
27192 /* Translate a space with a `space-width' property
27193 into a stretch glyph. */
27194 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
27195 / FONT_HEIGHT (font));
27196 append_stretch_glyph (it, it->object, it->pixel_width,
27197 it->ascent + it->descent, ascent);
27199 else
27200 append_glyph (it);
27202 /* If characters with lbearing or rbearing are displayed
27203 in this line, record that fact in a flag of the
27204 glyph row. This is used to optimize X output code. */
27205 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
27206 it->glyph_row->contains_overlapping_glyphs_p = true;
27208 if (! stretched_p && it->pixel_width == 0)
27209 /* We assure that all visible glyphs have at least 1-pixel
27210 width. */
27211 it->pixel_width = 1;
27213 else if (it->char_to_display == '\n')
27215 /* A newline has no width, but we need the height of the
27216 line. But if previous part of the line sets a height,
27217 don't increase that height. */
27219 Lisp_Object height;
27220 Lisp_Object total_height = Qnil;
27222 it->override_ascent = -1;
27223 it->pixel_width = 0;
27224 it->nglyphs = 0;
27226 height = get_it_property (it, Qline_height);
27227 /* Split (line-height total-height) list. */
27228 if (CONSP (height)
27229 && CONSP (XCDR (height))
27230 && NILP (XCDR (XCDR (height))))
27232 total_height = XCAR (XCDR (height));
27233 height = XCAR (height);
27235 height = calc_line_height_property (it, height, font, boff, true);
27237 if (it->override_ascent >= 0)
27239 it->ascent = it->override_ascent;
27240 it->descent = it->override_descent;
27241 boff = it->override_boff;
27243 else
27245 if (FONT_TOO_HIGH (font))
27247 it->ascent = font->pixel_size + boff - 1;
27248 it->descent = -boff + 1;
27249 if (it->descent < 0)
27250 it->descent = 0;
27252 else
27254 it->ascent = FONT_BASE (font) + boff;
27255 it->descent = FONT_DESCENT (font) - boff;
27259 if (EQ (height, Qt))
27261 if (it->descent > it->max_descent)
27263 it->ascent += it->descent - it->max_descent;
27264 it->descent = it->max_descent;
27266 if (it->ascent > it->max_ascent)
27268 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
27269 it->ascent = it->max_ascent;
27271 it->phys_ascent = min (it->phys_ascent, it->ascent);
27272 it->phys_descent = min (it->phys_descent, it->descent);
27273 it->constrain_row_ascent_descent_p = true;
27274 extra_line_spacing = 0;
27276 else
27278 Lisp_Object spacing;
27280 it->phys_ascent = it->ascent;
27281 it->phys_descent = it->descent;
27283 if ((it->max_ascent > 0 || it->max_descent > 0)
27284 && face->box != FACE_NO_BOX
27285 && face->box_line_width > 0)
27287 it->ascent += face->box_line_width;
27288 it->descent += face->box_line_width;
27290 if (!NILP (height)
27291 && XINT (height) > it->ascent + it->descent)
27292 it->ascent = XINT (height) - it->descent;
27294 if (!NILP (total_height))
27295 spacing = calc_line_height_property (it, total_height, font,
27296 boff, false);
27297 else
27299 spacing = get_it_property (it, Qline_spacing);
27300 spacing = calc_line_height_property (it, spacing, font,
27301 boff, false);
27303 if (INTEGERP (spacing))
27305 extra_line_spacing = XINT (spacing);
27306 if (!NILP (total_height))
27307 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
27311 else /* i.e. (it->char_to_display == '\t') */
27313 if (font->space_width > 0)
27315 int tab_width = it->tab_width * font->space_width;
27316 int x = it->current_x + it->continuation_lines_width;
27317 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
27319 /* If the distance from the current position to the next tab
27320 stop is less than a space character width, use the
27321 tab stop after that. */
27322 if (next_tab_x - x < font->space_width)
27323 next_tab_x += tab_width;
27325 it->pixel_width = next_tab_x - x;
27326 it->nglyphs = 1;
27327 if (FONT_TOO_HIGH (font))
27329 if (get_char_glyph_code (' ', font, &char2b))
27331 pcm = get_per_char_metric (font, &char2b);
27332 if (pcm->width == 0
27333 && pcm->rbearing == 0 && pcm->lbearing == 0)
27334 pcm = NULL;
27337 if (pcm)
27339 it->ascent = pcm->ascent + boff;
27340 it->descent = pcm->descent - boff;
27342 else
27344 it->ascent = font->pixel_size + boff - 1;
27345 it->descent = -boff + 1;
27347 if (it->ascent < 0)
27348 it->ascent = 0;
27349 if (it->descent < 0)
27350 it->descent = 0;
27352 else
27354 it->ascent = FONT_BASE (font) + boff;
27355 it->descent = FONT_DESCENT (font) - boff;
27357 it->phys_ascent = it->ascent;
27358 it->phys_descent = it->descent;
27360 if (it->glyph_row)
27362 append_stretch_glyph (it, it->object, it->pixel_width,
27363 it->ascent + it->descent, it->ascent);
27366 else
27368 it->pixel_width = 0;
27369 it->nglyphs = 1;
27373 if (FONT_TOO_HIGH (font))
27375 int font_ascent, font_descent;
27377 /* For very large fonts, where we ignore the declared font
27378 dimensions, and go by per-character metrics instead,
27379 don't let the row ascent and descent values (and the row
27380 height computed from them) be smaller than the "normal"
27381 character metrics. This avoids unpleasant effects
27382 whereby lines on display would change their height
27383 depending on which characters are shown. */
27384 normal_char_ascent_descent (font, -1, &font_ascent, &font_descent);
27385 it->max_ascent = max (it->max_ascent, font_ascent);
27386 it->max_descent = max (it->max_descent, font_descent);
27389 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
27391 /* A static composition.
27393 Note: A composition is represented as one glyph in the
27394 glyph matrix. There are no padding glyphs.
27396 Important note: pixel_width, ascent, and descent are the
27397 values of what is drawn by draw_glyphs (i.e. the values of
27398 the overall glyphs composed). */
27399 struct face *face = FACE_FROM_ID (it->f, it->face_id);
27400 int boff; /* baseline offset */
27401 struct composition *cmp = composition_table[it->cmp_it.id];
27402 int glyph_len = cmp->glyph_len;
27403 struct font *font = face->font;
27405 it->nglyphs = 1;
27407 /* If we have not yet calculated pixel size data of glyphs of
27408 the composition for the current face font, calculate them
27409 now. Theoretically, we have to check all fonts for the
27410 glyphs, but that requires much time and memory space. So,
27411 here we check only the font of the first glyph. This may
27412 lead to incorrect display, but it's very rare, and C-l
27413 (recenter-top-bottom) can correct the display anyway. */
27414 if (! cmp->font || cmp->font != font)
27416 /* Ascent and descent of the font of the first character
27417 of this composition (adjusted by baseline offset).
27418 Ascent and descent of overall glyphs should not be less
27419 than these, respectively. */
27420 int font_ascent, font_descent, font_height;
27421 /* Bounding box of the overall glyphs. */
27422 int leftmost, rightmost, lowest, highest;
27423 int lbearing, rbearing;
27424 int i, width, ascent, descent;
27425 int c;
27426 XChar2b char2b;
27427 struct font_metrics *pcm;
27428 ptrdiff_t pos;
27430 eassume (0 < glyph_len); /* See Bug#8512. */
27432 c = COMPOSITION_GLYPH (cmp, glyph_len - 1);
27433 while (c == '\t' && 0 < --glyph_len);
27435 bool right_padded = glyph_len < cmp->glyph_len;
27436 for (i = 0; i < glyph_len; i++)
27438 c = COMPOSITION_GLYPH (cmp, i);
27439 if (c != '\t')
27440 break;
27441 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
27443 bool left_padded = i > 0;
27445 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
27446 : IT_CHARPOS (*it));
27447 /* If no suitable font is found, use the default font. */
27448 bool font_not_found_p = font == NULL;
27449 if (font_not_found_p)
27451 face = face->ascii_face;
27452 font = face->font;
27454 boff = font->baseline_offset;
27455 if (font->vertical_centering)
27456 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
27457 normal_char_ascent_descent (font, -1, &font_ascent, &font_descent);
27458 font_ascent += boff;
27459 font_descent -= boff;
27460 font_height = font_ascent + font_descent;
27462 cmp->font = font;
27464 pcm = NULL;
27465 if (! font_not_found_p)
27467 get_char_face_and_encoding (it->f, c, it->face_id,
27468 &char2b, false);
27469 pcm = get_per_char_metric (font, &char2b);
27472 /* Initialize the bounding box. */
27473 if (pcm)
27475 width = cmp->glyph_len > 0 ? pcm->width : 0;
27476 ascent = pcm->ascent;
27477 descent = pcm->descent;
27478 lbearing = pcm->lbearing;
27479 rbearing = pcm->rbearing;
27481 else
27483 width = cmp->glyph_len > 0 ? font->space_width : 0;
27484 ascent = FONT_BASE (font);
27485 descent = FONT_DESCENT (font);
27486 lbearing = 0;
27487 rbearing = width;
27490 rightmost = width;
27491 leftmost = 0;
27492 lowest = - descent + boff;
27493 highest = ascent + boff;
27495 if (! font_not_found_p
27496 && font->default_ascent
27497 && CHAR_TABLE_P (Vuse_default_ascent)
27498 && !NILP (Faref (Vuse_default_ascent,
27499 make_number (it->char_to_display))))
27500 highest = font->default_ascent + boff;
27502 /* Draw the first glyph at the normal position. It may be
27503 shifted to right later if some other glyphs are drawn
27504 at the left. */
27505 cmp->offsets[i * 2] = 0;
27506 cmp->offsets[i * 2 + 1] = boff;
27507 cmp->lbearing = lbearing;
27508 cmp->rbearing = rbearing;
27510 /* Set cmp->offsets for the remaining glyphs. */
27511 for (i++; i < glyph_len; i++)
27513 int left, right, btm, top;
27514 int ch = COMPOSITION_GLYPH (cmp, i);
27515 int face_id;
27516 struct face *this_face;
27518 if (ch == '\t')
27519 ch = ' ';
27520 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
27521 this_face = FACE_FROM_ID (it->f, face_id);
27522 font = this_face->font;
27524 if (font == NULL)
27525 pcm = NULL;
27526 else
27528 get_char_face_and_encoding (it->f, ch, face_id,
27529 &char2b, false);
27530 pcm = get_per_char_metric (font, &char2b);
27532 if (! pcm)
27533 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
27534 else
27536 width = pcm->width;
27537 ascent = pcm->ascent;
27538 descent = pcm->descent;
27539 lbearing = pcm->lbearing;
27540 rbearing = pcm->rbearing;
27541 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
27543 /* Relative composition with or without
27544 alternate chars. */
27545 left = (leftmost + rightmost - width) / 2;
27546 btm = - descent + boff;
27547 if (font->relative_compose
27548 && (! CHAR_TABLE_P (Vignore_relative_composition)
27549 || NILP (Faref (Vignore_relative_composition,
27550 make_number (ch)))))
27553 if (- descent >= font->relative_compose)
27554 /* One extra pixel between two glyphs. */
27555 btm = highest + 1;
27556 else if (ascent <= 0)
27557 /* One extra pixel between two glyphs. */
27558 btm = lowest - 1 - ascent - descent;
27561 else
27563 /* A composition rule is specified by an integer
27564 value that encodes global and new reference
27565 points (GREF and NREF). GREF and NREF are
27566 specified by numbers as below:
27568 0---1---2 -- ascent
27572 9--10--11 -- center
27574 ---3---4---5--- baseline
27576 6---7---8 -- descent
27578 int rule = COMPOSITION_RULE (cmp, i);
27579 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
27581 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
27582 grefx = gref % 3, nrefx = nref % 3;
27583 grefy = gref / 3, nrefy = nref / 3;
27584 if (xoff)
27585 xoff = font_height * (xoff - 128) / 256;
27586 if (yoff)
27587 yoff = font_height * (yoff - 128) / 256;
27589 left = (leftmost
27590 + grefx * (rightmost - leftmost) / 2
27591 - nrefx * width / 2
27592 + xoff);
27594 btm = ((grefy == 0 ? highest
27595 : grefy == 1 ? 0
27596 : grefy == 2 ? lowest
27597 : (highest + lowest) / 2)
27598 - (nrefy == 0 ? ascent + descent
27599 : nrefy == 1 ? descent - boff
27600 : nrefy == 2 ? 0
27601 : (ascent + descent) / 2)
27602 + yoff);
27605 cmp->offsets[i * 2] = left;
27606 cmp->offsets[i * 2 + 1] = btm + descent;
27608 /* Update the bounding box of the overall glyphs. */
27609 if (width > 0)
27611 right = left + width;
27612 if (left < leftmost)
27613 leftmost = left;
27614 if (right > rightmost)
27615 rightmost = right;
27617 top = btm + descent + ascent;
27618 if (top > highest)
27619 highest = top;
27620 if (btm < lowest)
27621 lowest = btm;
27623 if (cmp->lbearing > left + lbearing)
27624 cmp->lbearing = left + lbearing;
27625 if (cmp->rbearing < left + rbearing)
27626 cmp->rbearing = left + rbearing;
27630 /* If there are glyphs whose x-offsets are negative,
27631 shift all glyphs to the right and make all x-offsets
27632 non-negative. */
27633 if (leftmost < 0)
27635 for (i = 0; i < cmp->glyph_len; i++)
27636 cmp->offsets[i * 2] -= leftmost;
27637 rightmost -= leftmost;
27638 cmp->lbearing -= leftmost;
27639 cmp->rbearing -= leftmost;
27642 if (left_padded && cmp->lbearing < 0)
27644 for (i = 0; i < cmp->glyph_len; i++)
27645 cmp->offsets[i * 2] -= cmp->lbearing;
27646 rightmost -= cmp->lbearing;
27647 cmp->rbearing -= cmp->lbearing;
27648 cmp->lbearing = 0;
27650 if (right_padded && rightmost < cmp->rbearing)
27652 rightmost = cmp->rbearing;
27655 cmp->pixel_width = rightmost;
27656 cmp->ascent = highest;
27657 cmp->descent = - lowest;
27658 if (cmp->ascent < font_ascent)
27659 cmp->ascent = font_ascent;
27660 if (cmp->descent < font_descent)
27661 cmp->descent = font_descent;
27664 if (it->glyph_row
27665 && (cmp->lbearing < 0
27666 || cmp->rbearing > cmp->pixel_width))
27667 it->glyph_row->contains_overlapping_glyphs_p = true;
27669 it->pixel_width = cmp->pixel_width;
27670 it->ascent = it->phys_ascent = cmp->ascent;
27671 it->descent = it->phys_descent = cmp->descent;
27672 if (face->box != FACE_NO_BOX)
27674 int thick = face->box_line_width;
27676 if (thick > 0)
27678 it->ascent += thick;
27679 it->descent += thick;
27681 else
27682 thick = - thick;
27684 if (it->start_of_box_run_p)
27685 it->pixel_width += thick;
27686 if (it->end_of_box_run_p)
27687 it->pixel_width += thick;
27690 /* If face has an overline, add the height of the overline
27691 (1 pixel) and a 1 pixel margin to the character height. */
27692 if (face->overline_p)
27693 it->ascent += overline_margin;
27695 take_vertical_position_into_account (it);
27696 if (it->ascent < 0)
27697 it->ascent = 0;
27698 if (it->descent < 0)
27699 it->descent = 0;
27701 if (it->glyph_row && cmp->glyph_len > 0)
27702 append_composite_glyph (it);
27704 else if (it->what == IT_COMPOSITION)
27706 /* A dynamic (automatic) composition. */
27707 struct face *face = FACE_FROM_ID (it->f, it->face_id);
27708 Lisp_Object gstring;
27709 struct font_metrics metrics;
27711 it->nglyphs = 1;
27713 gstring = composition_gstring_from_id (it->cmp_it.id);
27714 it->pixel_width
27715 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
27716 &metrics);
27717 if (it->glyph_row
27718 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
27719 it->glyph_row->contains_overlapping_glyphs_p = true;
27720 it->ascent = it->phys_ascent = metrics.ascent;
27721 it->descent = it->phys_descent = metrics.descent;
27722 if (face->box != FACE_NO_BOX)
27724 int thick = face->box_line_width;
27726 if (thick > 0)
27728 it->ascent += thick;
27729 it->descent += thick;
27731 else
27732 thick = - thick;
27734 if (it->start_of_box_run_p)
27735 it->pixel_width += thick;
27736 if (it->end_of_box_run_p)
27737 it->pixel_width += thick;
27739 /* If face has an overline, add the height of the overline
27740 (1 pixel) and a 1 pixel margin to the character height. */
27741 if (face->overline_p)
27742 it->ascent += overline_margin;
27743 take_vertical_position_into_account (it);
27744 if (it->ascent < 0)
27745 it->ascent = 0;
27746 if (it->descent < 0)
27747 it->descent = 0;
27749 if (it->glyph_row)
27750 append_composite_glyph (it);
27752 else if (it->what == IT_GLYPHLESS)
27753 produce_glyphless_glyph (it, false, Qnil);
27754 else if (it->what == IT_IMAGE)
27755 produce_image_glyph (it);
27756 else if (it->what == IT_STRETCH)
27757 produce_stretch_glyph (it);
27758 else if (it->what == IT_XWIDGET)
27759 produce_xwidget_glyph (it);
27761 done:
27762 /* Accumulate dimensions. Note: can't assume that it->descent > 0
27763 because this isn't true for images with `:ascent 100'. */
27764 eassert (it->ascent >= 0 && it->descent >= 0);
27765 if (it->area == TEXT_AREA)
27766 it->current_x += it->pixel_width;
27768 if (extra_line_spacing > 0)
27770 it->descent += extra_line_spacing;
27771 if (extra_line_spacing > it->max_extra_line_spacing)
27772 it->max_extra_line_spacing = extra_line_spacing;
27775 it->max_ascent = max (it->max_ascent, it->ascent);
27776 it->max_descent = max (it->max_descent, it->descent);
27777 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
27778 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
27781 /* EXPORT for RIF:
27782 Output LEN glyphs starting at START at the nominal cursor position.
27783 Advance the nominal cursor over the text. UPDATED_ROW is the glyph row
27784 being updated, and UPDATED_AREA is the area of that row being updated. */
27786 void
27787 x_write_glyphs (struct window *w, struct glyph_row *updated_row,
27788 struct glyph *start, enum glyph_row_area updated_area, int len)
27790 int x, hpos, chpos = w->phys_cursor.hpos;
27792 eassert (updated_row);
27793 /* When the window is hscrolled, cursor hpos can legitimately be out
27794 of bounds, but we draw the cursor at the corresponding window
27795 margin in that case. */
27796 if (!updated_row->reversed_p && chpos < 0)
27797 chpos = 0;
27798 if (updated_row->reversed_p && chpos >= updated_row->used[TEXT_AREA])
27799 chpos = updated_row->used[TEXT_AREA] - 1;
27801 block_input ();
27803 /* Write glyphs. */
27805 hpos = start - updated_row->glyphs[updated_area];
27806 x = draw_glyphs (w, w->output_cursor.x,
27807 updated_row, updated_area,
27808 hpos, hpos + len,
27809 DRAW_NORMAL_TEXT, 0);
27811 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
27812 if (updated_area == TEXT_AREA
27813 && w->phys_cursor_on_p
27814 && w->phys_cursor.vpos == w->output_cursor.vpos
27815 && chpos >= hpos
27816 && chpos < hpos + len)
27817 w->phys_cursor_on_p = false;
27819 unblock_input ();
27821 /* Advance the output cursor. */
27822 w->output_cursor.hpos += len;
27823 w->output_cursor.x = x;
27827 /* EXPORT for RIF:
27828 Insert LEN glyphs from START at the nominal cursor position. */
27830 void
27831 x_insert_glyphs (struct window *w, struct glyph_row *updated_row,
27832 struct glyph *start, enum glyph_row_area updated_area, int len)
27834 struct frame *f;
27835 int line_height, shift_by_width, shifted_region_width;
27836 struct glyph_row *row;
27837 struct glyph *glyph;
27838 int frame_x, frame_y;
27839 ptrdiff_t hpos;
27841 eassert (updated_row);
27842 block_input ();
27843 f = XFRAME (WINDOW_FRAME (w));
27845 /* Get the height of the line we are in. */
27846 row = updated_row;
27847 line_height = row->height;
27849 /* Get the width of the glyphs to insert. */
27850 shift_by_width = 0;
27851 for (glyph = start; glyph < start + len; ++glyph)
27852 shift_by_width += glyph->pixel_width;
27854 /* Get the width of the region to shift right. */
27855 shifted_region_width = (window_box_width (w, updated_area)
27856 - w->output_cursor.x
27857 - shift_by_width);
27859 /* Shift right. */
27860 frame_x = window_box_left (w, updated_area) + w->output_cursor.x;
27861 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, w->output_cursor.y);
27863 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
27864 line_height, shift_by_width);
27866 /* Write the glyphs. */
27867 hpos = start - row->glyphs[updated_area];
27868 draw_glyphs (w, w->output_cursor.x, row, updated_area,
27869 hpos, hpos + len,
27870 DRAW_NORMAL_TEXT, 0);
27872 /* Advance the output cursor. */
27873 w->output_cursor.hpos += len;
27874 w->output_cursor.x += shift_by_width;
27875 unblock_input ();
27879 /* EXPORT for RIF:
27880 Erase the current text line from the nominal cursor position
27881 (inclusive) to pixel column TO_X (exclusive). The idea is that
27882 everything from TO_X onward is already erased.
27884 TO_X is a pixel position relative to UPDATED_AREA of currently
27885 updated window W. TO_X == -1 means clear to the end of this area. */
27887 void
27888 x_clear_end_of_line (struct window *w, struct glyph_row *updated_row,
27889 enum glyph_row_area updated_area, int to_x)
27891 struct frame *f;
27892 int max_x, min_y, max_y;
27893 int from_x, from_y, to_y;
27895 eassert (updated_row);
27896 f = XFRAME (w->frame);
27898 if (updated_row->full_width_p)
27899 max_x = (WINDOW_PIXEL_WIDTH (w)
27900 - (updated_row->mode_line_p ? WINDOW_RIGHT_DIVIDER_WIDTH (w) : 0));
27901 else
27902 max_x = window_box_width (w, updated_area);
27903 max_y = window_text_bottom_y (w);
27905 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
27906 of window. For TO_X > 0, truncate to end of drawing area. */
27907 if (to_x == 0)
27908 return;
27909 else if (to_x < 0)
27910 to_x = max_x;
27911 else
27912 to_x = min (to_x, max_x);
27914 to_y = min (max_y, w->output_cursor.y + updated_row->height);
27916 /* Notice if the cursor will be cleared by this operation. */
27917 if (!updated_row->full_width_p)
27918 notice_overwritten_cursor (w, updated_area,
27919 w->output_cursor.x, -1,
27920 updated_row->y,
27921 MATRIX_ROW_BOTTOM_Y (updated_row));
27923 from_x = w->output_cursor.x;
27925 /* Translate to frame coordinates. */
27926 if (updated_row->full_width_p)
27928 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
27929 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
27931 else
27933 int area_left = window_box_left (w, updated_area);
27934 from_x += area_left;
27935 to_x += area_left;
27938 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
27939 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, w->output_cursor.y));
27940 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
27942 /* Prevent inadvertently clearing to end of the X window. */
27943 if (to_x > from_x && to_y > from_y)
27945 block_input ();
27946 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
27947 to_x - from_x, to_y - from_y);
27948 unblock_input ();
27952 #endif /* HAVE_WINDOW_SYSTEM */
27956 /***********************************************************************
27957 Cursor types
27958 ***********************************************************************/
27960 /* Value is the internal representation of the specified cursor type
27961 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
27962 of the bar cursor. */
27964 static enum text_cursor_kinds
27965 get_specified_cursor_type (Lisp_Object arg, int *width)
27967 enum text_cursor_kinds type;
27969 if (NILP (arg))
27970 return NO_CURSOR;
27972 if (EQ (arg, Qbox))
27973 return FILLED_BOX_CURSOR;
27975 if (EQ (arg, Qhollow))
27976 return HOLLOW_BOX_CURSOR;
27978 if (EQ (arg, Qbar))
27980 *width = 2;
27981 return BAR_CURSOR;
27984 if (CONSP (arg)
27985 && EQ (XCAR (arg), Qbar)
27986 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
27988 *width = XINT (XCDR (arg));
27989 return BAR_CURSOR;
27992 if (EQ (arg, Qhbar))
27994 *width = 2;
27995 return HBAR_CURSOR;
27998 if (CONSP (arg)
27999 && EQ (XCAR (arg), Qhbar)
28000 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
28002 *width = XINT (XCDR (arg));
28003 return HBAR_CURSOR;
28006 /* Treat anything unknown as "hollow box cursor".
28007 It was bad to signal an error; people have trouble fixing
28008 .Xdefaults with Emacs, when it has something bad in it. */
28009 type = HOLLOW_BOX_CURSOR;
28011 return type;
28014 /* Set the default cursor types for specified frame. */
28015 void
28016 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
28018 int width = 1;
28019 Lisp_Object tem;
28021 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
28022 FRAME_CURSOR_WIDTH (f) = width;
28024 /* By default, set up the blink-off state depending on the on-state. */
28026 tem = Fassoc (arg, Vblink_cursor_alist);
28027 if (!NILP (tem))
28029 FRAME_BLINK_OFF_CURSOR (f)
28030 = get_specified_cursor_type (XCDR (tem), &width);
28031 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
28033 else
28034 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
28036 /* Make sure the cursor gets redrawn. */
28037 f->cursor_type_changed = true;
28041 #ifdef HAVE_WINDOW_SYSTEM
28043 /* Return the cursor we want to be displayed in window W. Return
28044 width of bar/hbar cursor through WIDTH arg. Return with
28045 ACTIVE_CURSOR arg set to true if cursor in window W is `active'
28046 (i.e. if the `system caret' should track this cursor).
28048 In a mini-buffer window, we want the cursor only to appear if we
28049 are reading input from this window. For the selected window, we
28050 want the cursor type given by the frame parameter or buffer local
28051 setting of cursor-type. If explicitly marked off, draw no cursor.
28052 In all other cases, we want a hollow box cursor. */
28054 static enum text_cursor_kinds
28055 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
28056 bool *active_cursor)
28058 struct frame *f = XFRAME (w->frame);
28059 struct buffer *b = XBUFFER (w->contents);
28060 int cursor_type = DEFAULT_CURSOR;
28061 Lisp_Object alt_cursor;
28062 bool non_selected = false;
28064 *active_cursor = true;
28066 /* Echo area */
28067 if (cursor_in_echo_area
28068 && FRAME_HAS_MINIBUF_P (f)
28069 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
28071 if (w == XWINDOW (echo_area_window))
28073 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
28075 *width = FRAME_CURSOR_WIDTH (f);
28076 return FRAME_DESIRED_CURSOR (f);
28078 else
28079 return get_specified_cursor_type (BVAR (b, cursor_type), width);
28082 *active_cursor = false;
28083 non_selected = true;
28086 /* Detect a nonselected window or nonselected frame. */
28087 else if (w != XWINDOW (f->selected_window)
28088 || f != FRAME_DISPLAY_INFO (f)->x_highlight_frame)
28090 *active_cursor = false;
28092 if (MINI_WINDOW_P (w) && minibuf_level == 0)
28093 return NO_CURSOR;
28095 non_selected = true;
28098 /* Never display a cursor in a window in which cursor-type is nil. */
28099 if (NILP (BVAR (b, cursor_type)))
28100 return NO_CURSOR;
28102 /* Get the normal cursor type for this window. */
28103 if (EQ (BVAR (b, cursor_type), Qt))
28105 cursor_type = FRAME_DESIRED_CURSOR (f);
28106 *width = FRAME_CURSOR_WIDTH (f);
28108 else
28109 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
28111 /* Use cursor-in-non-selected-windows instead
28112 for non-selected window or frame. */
28113 if (non_selected)
28115 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
28116 if (!EQ (Qt, alt_cursor))
28117 return get_specified_cursor_type (alt_cursor, width);
28118 /* t means modify the normal cursor type. */
28119 if (cursor_type == FILLED_BOX_CURSOR)
28120 cursor_type = HOLLOW_BOX_CURSOR;
28121 else if (cursor_type == BAR_CURSOR && *width > 1)
28122 --*width;
28123 return cursor_type;
28126 /* Use normal cursor if not blinked off. */
28127 if (!w->cursor_off_p)
28129 if (glyph != NULL && glyph->type == XWIDGET_GLYPH)
28130 return NO_CURSOR;
28131 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
28133 if (cursor_type == FILLED_BOX_CURSOR)
28135 /* Using a block cursor on large images can be very annoying.
28136 So use a hollow cursor for "large" images.
28137 If image is not transparent (no mask), also use hollow cursor. */
28138 struct image *img = IMAGE_OPT_FROM_ID (f, glyph->u.img_id);
28139 if (img != NULL && IMAGEP (img->spec))
28141 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
28142 where N = size of default frame font size.
28143 This should cover most of the "tiny" icons people may use. */
28144 if (!img->mask
28145 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
28146 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
28147 cursor_type = HOLLOW_BOX_CURSOR;
28150 else if (cursor_type != NO_CURSOR)
28152 /* Display current only supports BOX and HOLLOW cursors for images.
28153 So for now, unconditionally use a HOLLOW cursor when cursor is
28154 not a solid box cursor. */
28155 cursor_type = HOLLOW_BOX_CURSOR;
28158 return cursor_type;
28161 /* Cursor is blinked off, so determine how to "toggle" it. */
28163 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
28164 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist), !NILP (alt_cursor)))
28165 return get_specified_cursor_type (XCDR (alt_cursor), width);
28167 /* Then see if frame has specified a specific blink off cursor type. */
28168 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
28170 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
28171 return FRAME_BLINK_OFF_CURSOR (f);
28174 #if false
28175 /* Some people liked having a permanently visible blinking cursor,
28176 while others had very strong opinions against it. So it was
28177 decided to remove it. KFS 2003-09-03 */
28179 /* Finally perform built-in cursor blinking:
28180 filled box <-> hollow box
28181 wide [h]bar <-> narrow [h]bar
28182 narrow [h]bar <-> no cursor
28183 other type <-> no cursor */
28185 if (cursor_type == FILLED_BOX_CURSOR)
28186 return HOLLOW_BOX_CURSOR;
28188 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
28190 *width = 1;
28191 return cursor_type;
28193 #endif
28195 return NO_CURSOR;
28199 /* Notice when the text cursor of window W has been completely
28200 overwritten by a drawing operation that outputs glyphs in AREA
28201 starting at X0 and ending at X1 in the line starting at Y0 and
28202 ending at Y1. X coordinates are area-relative. X1 < 0 means all
28203 the rest of the line after X0 has been written. Y coordinates
28204 are window-relative. */
28206 static void
28207 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
28208 int x0, int x1, int y0, int y1)
28210 int cx0, cx1, cy0, cy1;
28211 struct glyph_row *row;
28213 if (!w->phys_cursor_on_p)
28214 return;
28215 if (area != TEXT_AREA)
28216 return;
28218 if (w->phys_cursor.vpos < 0
28219 || w->phys_cursor.vpos >= w->current_matrix->nrows
28220 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
28221 !(row->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (row))))
28222 return;
28224 if (row->cursor_in_fringe_p)
28226 row->cursor_in_fringe_p = false;
28227 draw_fringe_bitmap (w, row, row->reversed_p);
28228 w->phys_cursor_on_p = false;
28229 return;
28232 cx0 = w->phys_cursor.x;
28233 cx1 = cx0 + w->phys_cursor_width;
28234 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
28235 return;
28237 /* The cursor image will be completely removed from the
28238 screen if the output area intersects the cursor area in
28239 y-direction. When we draw in [y0 y1[, and some part of
28240 the cursor is at y < y0, that part must have been drawn
28241 before. When scrolling, the cursor is erased before
28242 actually scrolling, so we don't come here. When not
28243 scrolling, the rows above the old cursor row must have
28244 changed, and in this case these rows must have written
28245 over the cursor image.
28247 Likewise if part of the cursor is below y1, with the
28248 exception of the cursor being in the first blank row at
28249 the buffer and window end because update_text_area
28250 doesn't draw that row. (Except when it does, but
28251 that's handled in update_text_area.) */
28253 cy0 = w->phys_cursor.y;
28254 cy1 = cy0 + w->phys_cursor_height;
28255 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
28256 return;
28258 w->phys_cursor_on_p = false;
28261 #endif /* HAVE_WINDOW_SYSTEM */
28264 /************************************************************************
28265 Mouse Face
28266 ************************************************************************/
28268 #ifdef HAVE_WINDOW_SYSTEM
28270 /* EXPORT for RIF:
28271 Fix the display of area AREA of overlapping row ROW in window W
28272 with respect to the overlapping part OVERLAPS. */
28274 void
28275 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
28276 enum glyph_row_area area, int overlaps)
28278 int i, x;
28280 block_input ();
28282 x = 0;
28283 for (i = 0; i < row->used[area];)
28285 if (row->glyphs[area][i].overlaps_vertically_p)
28287 int start = i, start_x = x;
28291 x += row->glyphs[area][i].pixel_width;
28292 ++i;
28294 while (i < row->used[area]
28295 && row->glyphs[area][i].overlaps_vertically_p);
28297 draw_glyphs (w, start_x, row, area,
28298 start, i,
28299 DRAW_NORMAL_TEXT, overlaps);
28301 else
28303 x += row->glyphs[area][i].pixel_width;
28304 ++i;
28308 unblock_input ();
28312 /* EXPORT:
28313 Draw the cursor glyph of window W in glyph row ROW. See the
28314 comment of draw_glyphs for the meaning of HL. */
28316 void
28317 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
28318 enum draw_glyphs_face hl)
28320 /* If cursor hpos is out of bounds, don't draw garbage. This can
28321 happen in mini-buffer windows when switching between echo area
28322 glyphs and mini-buffer. */
28323 if ((row->reversed_p
28324 ? (w->phys_cursor.hpos >= 0)
28325 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
28327 bool on_p = w->phys_cursor_on_p;
28328 int x1;
28329 int hpos = w->phys_cursor.hpos;
28331 /* When the window is hscrolled, cursor hpos can legitimately be
28332 out of bounds, but we draw the cursor at the corresponding
28333 window margin in that case. */
28334 if (!row->reversed_p && hpos < 0)
28335 hpos = 0;
28336 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
28337 hpos = row->used[TEXT_AREA] - 1;
28339 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, hpos, hpos + 1,
28340 hl, 0);
28341 w->phys_cursor_on_p = on_p;
28343 if (hl == DRAW_CURSOR)
28344 w->phys_cursor_width = x1 - w->phys_cursor.x;
28345 /* When we erase the cursor, and ROW is overlapped by other
28346 rows, make sure that these overlapping parts of other rows
28347 are redrawn. */
28348 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
28350 w->phys_cursor_width = x1 - w->phys_cursor.x;
28352 if (row > w->current_matrix->rows
28353 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
28354 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
28355 OVERLAPS_ERASED_CURSOR);
28357 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
28358 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
28359 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
28360 OVERLAPS_ERASED_CURSOR);
28366 /* Erase the image of a cursor of window W from the screen. */
28368 void
28369 erase_phys_cursor (struct window *w)
28371 struct frame *f = XFRAME (w->frame);
28372 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28373 int hpos = w->phys_cursor.hpos;
28374 int vpos = w->phys_cursor.vpos;
28375 bool mouse_face_here_p = false;
28376 struct glyph_matrix *active_glyphs = w->current_matrix;
28377 struct glyph_row *cursor_row;
28378 struct glyph *cursor_glyph;
28379 enum draw_glyphs_face hl;
28381 /* No cursor displayed or row invalidated => nothing to do on the
28382 screen. */
28383 if (w->phys_cursor_type == NO_CURSOR)
28384 goto mark_cursor_off;
28386 /* VPOS >= active_glyphs->nrows means that window has been resized.
28387 Don't bother to erase the cursor. */
28388 if (vpos >= active_glyphs->nrows)
28389 goto mark_cursor_off;
28391 /* If row containing cursor is marked invalid, there is nothing we
28392 can do. */
28393 cursor_row = MATRIX_ROW (active_glyphs, vpos);
28394 if (!cursor_row->enabled_p)
28395 goto mark_cursor_off;
28397 /* If line spacing is > 0, old cursor may only be partially visible in
28398 window after split-window. So adjust visible height. */
28399 cursor_row->visible_height = min (cursor_row->visible_height,
28400 window_text_bottom_y (w) - cursor_row->y);
28402 /* If row is completely invisible, don't attempt to delete a cursor which
28403 isn't there. This can happen if cursor is at top of a window, and
28404 we switch to a buffer with a header line in that window. */
28405 if (cursor_row->visible_height <= 0)
28406 goto mark_cursor_off;
28408 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
28409 if (cursor_row->cursor_in_fringe_p)
28411 cursor_row->cursor_in_fringe_p = false;
28412 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
28413 goto mark_cursor_off;
28416 /* This can happen when the new row is shorter than the old one.
28417 In this case, either draw_glyphs or clear_end_of_line
28418 should have cleared the cursor. Note that we wouldn't be
28419 able to erase the cursor in this case because we don't have a
28420 cursor glyph at hand. */
28421 if ((cursor_row->reversed_p
28422 ? (w->phys_cursor.hpos < 0)
28423 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
28424 goto mark_cursor_off;
28426 /* When the window is hscrolled, cursor hpos can legitimately be out
28427 of bounds, but we draw the cursor at the corresponding window
28428 margin in that case. */
28429 if (!cursor_row->reversed_p && hpos < 0)
28430 hpos = 0;
28431 if (cursor_row->reversed_p && hpos >= cursor_row->used[TEXT_AREA])
28432 hpos = cursor_row->used[TEXT_AREA] - 1;
28434 /* If the cursor is in the mouse face area, redisplay that when
28435 we clear the cursor. */
28436 if (! NILP (hlinfo->mouse_face_window)
28437 && coords_in_mouse_face_p (w, hpos, vpos)
28438 /* Don't redraw the cursor's spot in mouse face if it is at the
28439 end of a line (on a newline). The cursor appears there, but
28440 mouse highlighting does not. */
28441 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
28442 mouse_face_here_p = true;
28444 /* Maybe clear the display under the cursor. */
28445 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
28447 int x, y;
28448 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
28449 int width;
28451 cursor_glyph = get_phys_cursor_glyph (w);
28452 if (cursor_glyph == NULL)
28453 goto mark_cursor_off;
28455 width = cursor_glyph->pixel_width;
28456 x = w->phys_cursor.x;
28457 if (x < 0)
28459 width += x;
28460 x = 0;
28462 width = min (width, window_box_width (w, TEXT_AREA) - x);
28463 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
28464 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
28466 if (width > 0)
28467 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
28470 /* Erase the cursor by redrawing the character underneath it. */
28471 if (mouse_face_here_p)
28472 hl = DRAW_MOUSE_FACE;
28473 else
28474 hl = DRAW_NORMAL_TEXT;
28475 draw_phys_cursor_glyph (w, cursor_row, hl);
28477 mark_cursor_off:
28478 w->phys_cursor_on_p = false;
28479 w->phys_cursor_type = NO_CURSOR;
28483 /* Display or clear cursor of window W. If !ON, clear the cursor.
28484 If ON, display the cursor; where to put the cursor is specified by
28485 HPOS, VPOS, X and Y. */
28487 void
28488 display_and_set_cursor (struct window *w, bool on,
28489 int hpos, int vpos, int x, int y)
28491 struct frame *f = XFRAME (w->frame);
28492 int new_cursor_type;
28493 int new_cursor_width;
28494 bool active_cursor;
28495 struct glyph_row *glyph_row;
28496 struct glyph *glyph;
28498 /* This is pointless on invisible frames, and dangerous on garbaged
28499 windows and frames; in the latter case, the frame or window may
28500 be in the midst of changing its size, and x and y may be off the
28501 window. */
28502 if (! FRAME_VISIBLE_P (f)
28503 || FRAME_GARBAGED_P (f)
28504 || vpos >= w->current_matrix->nrows
28505 || hpos >= w->current_matrix->matrix_w)
28506 return;
28508 /* If cursor is off and we want it off, return quickly. */
28509 if (!on && !w->phys_cursor_on_p)
28510 return;
28512 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
28513 /* If cursor row is not enabled, we don't really know where to
28514 display the cursor. */
28515 if (!glyph_row->enabled_p)
28517 w->phys_cursor_on_p = false;
28518 return;
28521 glyph = NULL;
28522 if (!glyph_row->exact_window_width_line_p
28523 || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
28524 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
28526 eassert (input_blocked_p ());
28528 /* Set new_cursor_type to the cursor we want to be displayed. */
28529 new_cursor_type = get_window_cursor_type (w, glyph,
28530 &new_cursor_width, &active_cursor);
28532 /* If cursor is currently being shown and we don't want it to be or
28533 it is in the wrong place, or the cursor type is not what we want,
28534 erase it. */
28535 if (w->phys_cursor_on_p
28536 && (!on
28537 || w->phys_cursor.x != x
28538 || w->phys_cursor.y != y
28539 /* HPOS can be negative in R2L rows whose
28540 exact_window_width_line_p flag is set (i.e. their newline
28541 would "overflow into the fringe"). */
28542 || hpos < 0
28543 || new_cursor_type != w->phys_cursor_type
28544 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
28545 && new_cursor_width != w->phys_cursor_width)))
28546 erase_phys_cursor (w);
28548 /* Don't check phys_cursor_on_p here because that flag is only set
28549 to false in some cases where we know that the cursor has been
28550 completely erased, to avoid the extra work of erasing the cursor
28551 twice. In other words, phys_cursor_on_p can be true and the cursor
28552 still not be visible, or it has only been partly erased. */
28553 if (on)
28555 w->phys_cursor_ascent = glyph_row->ascent;
28556 w->phys_cursor_height = glyph_row->height;
28558 /* Set phys_cursor_.* before x_draw_.* is called because some
28559 of them may need the information. */
28560 w->phys_cursor.x = x;
28561 w->phys_cursor.y = glyph_row->y;
28562 w->phys_cursor.hpos = hpos;
28563 w->phys_cursor.vpos = vpos;
28566 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
28567 new_cursor_type, new_cursor_width,
28568 on, active_cursor);
28572 /* Switch the display of W's cursor on or off, according to the value
28573 of ON. */
28575 static void
28576 update_window_cursor (struct window *w, bool on)
28578 /* Don't update cursor in windows whose frame is in the process
28579 of being deleted. */
28580 if (w->current_matrix)
28582 int hpos = w->phys_cursor.hpos;
28583 int vpos = w->phys_cursor.vpos;
28584 struct glyph_row *row;
28586 if (vpos >= w->current_matrix->nrows
28587 || hpos >= w->current_matrix->matrix_w)
28588 return;
28590 row = MATRIX_ROW (w->current_matrix, vpos);
28592 /* When the window is hscrolled, cursor hpos can legitimately be
28593 out of bounds, but we draw the cursor at the corresponding
28594 window margin in that case. */
28595 if (!row->reversed_p && hpos < 0)
28596 hpos = 0;
28597 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
28598 hpos = row->used[TEXT_AREA] - 1;
28600 block_input ();
28601 display_and_set_cursor (w, on, hpos, vpos,
28602 w->phys_cursor.x, w->phys_cursor.y);
28603 unblock_input ();
28608 /* Call update_window_cursor with parameter ON_P on all leaf windows
28609 in the window tree rooted at W. */
28611 static void
28612 update_cursor_in_window_tree (struct window *w, bool on_p)
28614 while (w)
28616 if (WINDOWP (w->contents))
28617 update_cursor_in_window_tree (XWINDOW (w->contents), on_p);
28618 else
28619 update_window_cursor (w, on_p);
28621 w = NILP (w->next) ? 0 : XWINDOW (w->next);
28626 /* EXPORT:
28627 Display the cursor on window W, or clear it, according to ON_P.
28628 Don't change the cursor's position. */
28630 void
28631 x_update_cursor (struct frame *f, bool on_p)
28633 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
28637 /* EXPORT:
28638 Clear the cursor of window W to background color, and mark the
28639 cursor as not shown. This is used when the text where the cursor
28640 is about to be rewritten. */
28642 void
28643 x_clear_cursor (struct window *w)
28645 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
28646 update_window_cursor (w, false);
28649 #endif /* HAVE_WINDOW_SYSTEM */
28651 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
28652 and MSDOS. */
28653 static void
28654 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
28655 int start_hpos, int end_hpos,
28656 enum draw_glyphs_face draw)
28658 #ifdef HAVE_WINDOW_SYSTEM
28659 if (FRAME_WINDOW_P (XFRAME (w->frame)))
28661 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
28662 return;
28664 #endif
28665 #if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT)
28666 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
28667 #endif
28670 /* Display the active region described by mouse_face_* according to DRAW. */
28672 static void
28673 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
28675 struct window *w = XWINDOW (hlinfo->mouse_face_window);
28676 struct frame *f = XFRAME (WINDOW_FRAME (w));
28678 if (/* If window is in the process of being destroyed, don't bother
28679 to do anything. */
28680 w->current_matrix != NULL
28681 /* Don't update mouse highlight if hidden. */
28682 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
28683 /* Recognize when we are called to operate on rows that don't exist
28684 anymore. This can happen when a window is split. */
28685 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
28687 bool phys_cursor_on_p = w->phys_cursor_on_p;
28688 struct glyph_row *row, *first, *last;
28690 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
28691 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
28693 for (row = first; row <= last && row->enabled_p; ++row)
28695 int start_hpos, end_hpos, start_x;
28697 /* For all but the first row, the highlight starts at column 0. */
28698 if (row == first)
28700 /* R2L rows have BEG and END in reversed order, but the
28701 screen drawing geometry is always left to right. So
28702 we need to mirror the beginning and end of the
28703 highlighted area in R2L rows. */
28704 if (!row->reversed_p)
28706 start_hpos = hlinfo->mouse_face_beg_col;
28707 start_x = hlinfo->mouse_face_beg_x;
28709 else if (row == last)
28711 start_hpos = hlinfo->mouse_face_end_col;
28712 start_x = hlinfo->mouse_face_end_x;
28714 else
28716 start_hpos = 0;
28717 start_x = 0;
28720 else if (row->reversed_p && row == last)
28722 start_hpos = hlinfo->mouse_face_end_col;
28723 start_x = hlinfo->mouse_face_end_x;
28725 else
28727 start_hpos = 0;
28728 start_x = 0;
28731 if (row == last)
28733 if (!row->reversed_p)
28734 end_hpos = hlinfo->mouse_face_end_col;
28735 else if (row == first)
28736 end_hpos = hlinfo->mouse_face_beg_col;
28737 else
28739 end_hpos = row->used[TEXT_AREA];
28740 if (draw == DRAW_NORMAL_TEXT)
28741 row->fill_line_p = true; /* Clear to end of line. */
28744 else if (row->reversed_p && row == first)
28745 end_hpos = hlinfo->mouse_face_beg_col;
28746 else
28748 end_hpos = row->used[TEXT_AREA];
28749 if (draw == DRAW_NORMAL_TEXT)
28750 row->fill_line_p = true; /* Clear to end of line. */
28753 if (end_hpos > start_hpos)
28755 draw_row_with_mouse_face (w, start_x, row,
28756 start_hpos, end_hpos, draw);
28758 row->mouse_face_p
28759 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
28763 /* When we've written over the cursor, arrange for it to
28764 be displayed again. */
28765 if (FRAME_WINDOW_P (f)
28766 && phys_cursor_on_p && !w->phys_cursor_on_p)
28768 #ifdef HAVE_WINDOW_SYSTEM
28769 int hpos = w->phys_cursor.hpos;
28771 /* When the window is hscrolled, cursor hpos can legitimately be
28772 out of bounds, but we draw the cursor at the corresponding
28773 window margin in that case. */
28774 if (!row->reversed_p && hpos < 0)
28775 hpos = 0;
28776 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
28777 hpos = row->used[TEXT_AREA] - 1;
28779 block_input ();
28780 display_and_set_cursor (w, true, hpos, w->phys_cursor.vpos,
28781 w->phys_cursor.x, w->phys_cursor.y);
28782 unblock_input ();
28783 #endif /* HAVE_WINDOW_SYSTEM */
28787 #ifdef HAVE_WINDOW_SYSTEM
28788 /* Change the mouse cursor. */
28789 if (FRAME_WINDOW_P (f) && NILP (do_mouse_tracking))
28791 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
28792 if (draw == DRAW_NORMAL_TEXT
28793 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
28794 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
28795 else
28796 #endif
28797 if (draw == DRAW_MOUSE_FACE)
28798 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
28799 else
28800 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
28802 #endif /* HAVE_WINDOW_SYSTEM */
28805 /* EXPORT:
28806 Clear out the mouse-highlighted active region.
28807 Redraw it un-highlighted first. Value is true if mouse
28808 face was actually drawn unhighlighted. */
28810 bool
28811 clear_mouse_face (Mouse_HLInfo *hlinfo)
28813 bool cleared
28814 = !hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window);
28815 if (cleared)
28816 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
28817 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
28818 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
28819 hlinfo->mouse_face_window = Qnil;
28820 hlinfo->mouse_face_overlay = Qnil;
28821 return cleared;
28824 /* Return true if the coordinates HPOS and VPOS on windows W are
28825 within the mouse face on that window. */
28826 static bool
28827 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
28829 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
28831 /* Quickly resolve the easy cases. */
28832 if (!(WINDOWP (hlinfo->mouse_face_window)
28833 && XWINDOW (hlinfo->mouse_face_window) == w))
28834 return false;
28835 if (vpos < hlinfo->mouse_face_beg_row
28836 || vpos > hlinfo->mouse_face_end_row)
28837 return false;
28838 if (vpos > hlinfo->mouse_face_beg_row
28839 && vpos < hlinfo->mouse_face_end_row)
28840 return true;
28842 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
28844 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
28846 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
28847 return true;
28849 else if ((vpos == hlinfo->mouse_face_beg_row
28850 && hpos >= hlinfo->mouse_face_beg_col)
28851 || (vpos == hlinfo->mouse_face_end_row
28852 && hpos < hlinfo->mouse_face_end_col))
28853 return true;
28855 else
28857 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
28859 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
28860 return true;
28862 else if ((vpos == hlinfo->mouse_face_beg_row
28863 && hpos <= hlinfo->mouse_face_beg_col)
28864 || (vpos == hlinfo->mouse_face_end_row
28865 && hpos > hlinfo->mouse_face_end_col))
28866 return true;
28868 return false;
28872 /* EXPORT:
28873 True if physical cursor of window W is within mouse face. */
28875 bool
28876 cursor_in_mouse_face_p (struct window *w)
28878 int hpos = w->phys_cursor.hpos;
28879 int vpos = w->phys_cursor.vpos;
28880 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
28882 /* When the window is hscrolled, cursor hpos can legitimately be out
28883 of bounds, but we draw the cursor at the corresponding window
28884 margin in that case. */
28885 if (!row->reversed_p && hpos < 0)
28886 hpos = 0;
28887 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
28888 hpos = row->used[TEXT_AREA] - 1;
28890 return coords_in_mouse_face_p (w, hpos, vpos);
28895 /* Find the glyph rows START_ROW and END_ROW of window W that display
28896 characters between buffer positions START_CHARPOS and END_CHARPOS
28897 (excluding END_CHARPOS). DISP_STRING is a display string that
28898 covers these buffer positions. This is similar to
28899 row_containing_pos, but is more accurate when bidi reordering makes
28900 buffer positions change non-linearly with glyph rows. */
28901 static void
28902 rows_from_pos_range (struct window *w,
28903 ptrdiff_t start_charpos, ptrdiff_t end_charpos,
28904 Lisp_Object disp_string,
28905 struct glyph_row **start, struct glyph_row **end)
28907 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
28908 int last_y = window_text_bottom_y (w);
28909 struct glyph_row *row;
28911 *start = NULL;
28912 *end = NULL;
28914 while (!first->enabled_p
28915 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
28916 first++;
28918 /* Find the START row. */
28919 for (row = first;
28920 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
28921 row++)
28923 /* A row can potentially be the START row if the range of the
28924 characters it displays intersects the range
28925 [START_CHARPOS..END_CHARPOS). */
28926 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
28927 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
28928 /* See the commentary in row_containing_pos, for the
28929 explanation of the complicated way to check whether
28930 some position is beyond the end of the characters
28931 displayed by a row. */
28932 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
28933 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
28934 && !row->ends_at_zv_p
28935 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
28936 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
28937 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
28938 && !row->ends_at_zv_p
28939 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
28941 /* Found a candidate row. Now make sure at least one of the
28942 glyphs it displays has a charpos from the range
28943 [START_CHARPOS..END_CHARPOS).
28945 This is not obvious because bidi reordering could make
28946 buffer positions of a row be 1,2,3,102,101,100, and if we
28947 want to highlight characters in [50..60), we don't want
28948 this row, even though [50..60) does intersect [1..103),
28949 the range of character positions given by the row's start
28950 and end positions. */
28951 struct glyph *g = row->glyphs[TEXT_AREA];
28952 struct glyph *e = g + row->used[TEXT_AREA];
28954 while (g < e)
28956 if (((BUFFERP (g->object) || NILP (g->object))
28957 && start_charpos <= g->charpos && g->charpos < end_charpos)
28958 /* A glyph that comes from DISP_STRING is by
28959 definition to be highlighted. */
28960 || EQ (g->object, disp_string))
28961 *start = row;
28962 g++;
28964 if (*start)
28965 break;
28969 /* Find the END row. */
28970 if (!*start
28971 /* If the last row is partially visible, start looking for END
28972 from that row, instead of starting from FIRST. */
28973 && !(row->enabled_p
28974 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
28975 row = first;
28976 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
28978 struct glyph_row *next = row + 1;
28979 ptrdiff_t next_start = MATRIX_ROW_START_CHARPOS (next);
28981 if (!next->enabled_p
28982 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
28983 /* The first row >= START whose range of displayed characters
28984 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
28985 is the row END + 1. */
28986 || (start_charpos < next_start
28987 && end_charpos < next_start)
28988 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
28989 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
28990 && !next->ends_at_zv_p
28991 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
28992 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
28993 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
28994 && !next->ends_at_zv_p
28995 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
28997 *end = row;
28998 break;
29000 else
29002 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
29003 but none of the characters it displays are in the range, it is
29004 also END + 1. */
29005 struct glyph *g = next->glyphs[TEXT_AREA];
29006 struct glyph *s = g;
29007 struct glyph *e = g + next->used[TEXT_AREA];
29009 while (g < e)
29011 if (((BUFFERP (g->object) || NILP (g->object))
29012 && ((start_charpos <= g->charpos && g->charpos < end_charpos)
29013 /* If the buffer position of the first glyph in
29014 the row is equal to END_CHARPOS, it means
29015 the last character to be highlighted is the
29016 newline of ROW, and we must consider NEXT as
29017 END, not END+1. */
29018 || (((!next->reversed_p && g == s)
29019 || (next->reversed_p && g == e - 1))
29020 && (g->charpos == end_charpos
29021 /* Special case for when NEXT is an
29022 empty line at ZV. */
29023 || (g->charpos == -1
29024 && !row->ends_at_zv_p
29025 && next_start == end_charpos)))))
29026 /* A glyph that comes from DISP_STRING is by
29027 definition to be highlighted. */
29028 || EQ (g->object, disp_string))
29029 break;
29030 g++;
29032 if (g == e)
29034 *end = row;
29035 break;
29037 /* The first row that ends at ZV must be the last to be
29038 highlighted. */
29039 else if (next->ends_at_zv_p)
29041 *end = next;
29042 break;
29048 /* This function sets the mouse_face_* elements of HLINFO, assuming
29049 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
29050 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
29051 for the overlay or run of text properties specifying the mouse
29052 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
29053 before-string and after-string that must also be highlighted.
29054 DISP_STRING, if non-nil, is a display string that may cover some
29055 or all of the highlighted text. */
29057 static void
29058 mouse_face_from_buffer_pos (Lisp_Object window,
29059 Mouse_HLInfo *hlinfo,
29060 ptrdiff_t mouse_charpos,
29061 ptrdiff_t start_charpos,
29062 ptrdiff_t end_charpos,
29063 Lisp_Object before_string,
29064 Lisp_Object after_string,
29065 Lisp_Object disp_string)
29067 struct window *w = XWINDOW (window);
29068 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
29069 struct glyph_row *r1, *r2;
29070 struct glyph *glyph, *end;
29071 ptrdiff_t ignore, pos;
29072 int x;
29074 eassert (NILP (disp_string) || STRINGP (disp_string));
29075 eassert (NILP (before_string) || STRINGP (before_string));
29076 eassert (NILP (after_string) || STRINGP (after_string));
29078 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
29079 rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2);
29080 if (r1 == NULL)
29081 r1 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
29082 /* If the before-string or display-string contains newlines,
29083 rows_from_pos_range skips to its last row. Move back. */
29084 if (!NILP (before_string) || !NILP (disp_string))
29086 struct glyph_row *prev;
29087 while ((prev = r1 - 1, prev >= first)
29088 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
29089 && prev->used[TEXT_AREA] > 0)
29091 struct glyph *beg = prev->glyphs[TEXT_AREA];
29092 glyph = beg + prev->used[TEXT_AREA];
29093 while (--glyph >= beg && NILP (glyph->object));
29094 if (glyph < beg
29095 || !(EQ (glyph->object, before_string)
29096 || EQ (glyph->object, disp_string)))
29097 break;
29098 r1 = prev;
29101 if (r2 == NULL)
29103 r2 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
29104 hlinfo->mouse_face_past_end = true;
29106 else if (!NILP (after_string))
29108 /* If the after-string has newlines, advance to its last row. */
29109 struct glyph_row *next;
29110 struct glyph_row *last
29111 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
29113 for (next = r2 + 1;
29114 next <= last
29115 && next->used[TEXT_AREA] > 0
29116 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
29117 ++next)
29118 r2 = next;
29120 /* The rest of the display engine assumes that mouse_face_beg_row is
29121 either above mouse_face_end_row or identical to it. But with
29122 bidi-reordered continued lines, the row for START_CHARPOS could
29123 be below the row for END_CHARPOS. If so, swap the rows and store
29124 them in correct order. */
29125 if (r1->y > r2->y)
29127 struct glyph_row *tem = r2;
29129 r2 = r1;
29130 r1 = tem;
29133 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
29134 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
29136 /* For a bidi-reordered row, the positions of BEFORE_STRING,
29137 AFTER_STRING, DISP_STRING, START_CHARPOS, and END_CHARPOS
29138 could be anywhere in the row and in any order. The strategy
29139 below is to find the leftmost and the rightmost glyph that
29140 belongs to either of these 3 strings, or whose position is
29141 between START_CHARPOS and END_CHARPOS, and highlight all the
29142 glyphs between those two. This may cover more than just the text
29143 between START_CHARPOS and END_CHARPOS if the range of characters
29144 strides the bidi level boundary, e.g. if the beginning is in R2L
29145 text while the end is in L2R text or vice versa. */
29146 if (!r1->reversed_p)
29148 /* This row is in a left to right paragraph. Scan it left to
29149 right. */
29150 glyph = r1->glyphs[TEXT_AREA];
29151 end = glyph + r1->used[TEXT_AREA];
29152 x = r1->x;
29154 /* Skip truncation glyphs at the start of the glyph row. */
29155 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
29156 for (; glyph < end
29157 && NILP (glyph->object)
29158 && glyph->charpos < 0;
29159 ++glyph)
29160 x += glyph->pixel_width;
29162 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
29163 or DISP_STRING, and the first glyph from buffer whose
29164 position is between START_CHARPOS and END_CHARPOS. */
29165 for (; glyph < end
29166 && !NILP (glyph->object)
29167 && !EQ (glyph->object, disp_string)
29168 && !(BUFFERP (glyph->object)
29169 && (glyph->charpos >= start_charpos
29170 && glyph->charpos < end_charpos));
29171 ++glyph)
29173 /* BEFORE_STRING or AFTER_STRING are only relevant if they
29174 are present at buffer positions between START_CHARPOS and
29175 END_CHARPOS, or if they come from an overlay. */
29176 if (EQ (glyph->object, before_string))
29178 pos = string_buffer_position (before_string,
29179 start_charpos);
29180 /* If pos == 0, it means before_string came from an
29181 overlay, not from a buffer position. */
29182 if (!pos || (pos >= start_charpos && pos < end_charpos))
29183 break;
29185 else if (EQ (glyph->object, after_string))
29187 pos = string_buffer_position (after_string, end_charpos);
29188 if (!pos || (pos >= start_charpos && pos < end_charpos))
29189 break;
29191 x += glyph->pixel_width;
29193 hlinfo->mouse_face_beg_x = x;
29194 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
29196 else
29198 /* This row is in a right to left paragraph. Scan it right to
29199 left. */
29200 struct glyph *g;
29202 end = r1->glyphs[TEXT_AREA] - 1;
29203 glyph = end + r1->used[TEXT_AREA];
29205 /* Skip truncation glyphs at the start of the glyph row. */
29206 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
29207 for (; glyph > end
29208 && NILP (glyph->object)
29209 && glyph->charpos < 0;
29210 --glyph)
29213 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
29214 or DISP_STRING, and the first glyph from buffer whose
29215 position is between START_CHARPOS and END_CHARPOS. */
29216 for (; glyph > end
29217 && !NILP (glyph->object)
29218 && !EQ (glyph->object, disp_string)
29219 && !(BUFFERP (glyph->object)
29220 && (glyph->charpos >= start_charpos
29221 && glyph->charpos < end_charpos));
29222 --glyph)
29224 /* BEFORE_STRING or AFTER_STRING are only relevant if they
29225 are present at buffer positions between START_CHARPOS and
29226 END_CHARPOS, or if they come from an overlay. */
29227 if (EQ (glyph->object, before_string))
29229 pos = string_buffer_position (before_string, start_charpos);
29230 /* If pos == 0, it means before_string came from an
29231 overlay, not from a buffer position. */
29232 if (!pos || (pos >= start_charpos && pos < end_charpos))
29233 break;
29235 else if (EQ (glyph->object, after_string))
29237 pos = string_buffer_position (after_string, end_charpos);
29238 if (!pos || (pos >= start_charpos && pos < end_charpos))
29239 break;
29243 glyph++; /* first glyph to the right of the highlighted area */
29244 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
29245 x += g->pixel_width;
29246 hlinfo->mouse_face_beg_x = x;
29247 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
29250 /* If the highlight ends in a different row, compute GLYPH and END
29251 for the end row. Otherwise, reuse the values computed above for
29252 the row where the highlight begins. */
29253 if (r2 != r1)
29255 if (!r2->reversed_p)
29257 glyph = r2->glyphs[TEXT_AREA];
29258 end = glyph + r2->used[TEXT_AREA];
29259 x = r2->x;
29261 else
29263 end = r2->glyphs[TEXT_AREA] - 1;
29264 glyph = end + r2->used[TEXT_AREA];
29268 if (!r2->reversed_p)
29270 /* Skip truncation and continuation glyphs near the end of the
29271 row, and also blanks and stretch glyphs inserted by
29272 extend_face_to_end_of_line. */
29273 while (end > glyph
29274 && NILP ((end - 1)->object))
29275 --end;
29276 /* Scan the rest of the glyph row from the end, looking for the
29277 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
29278 DISP_STRING, or whose position is between START_CHARPOS
29279 and END_CHARPOS */
29280 for (--end;
29281 end > glyph
29282 && !NILP (end->object)
29283 && !EQ (end->object, disp_string)
29284 && !(BUFFERP (end->object)
29285 && (end->charpos >= start_charpos
29286 && end->charpos < end_charpos));
29287 --end)
29289 /* BEFORE_STRING or AFTER_STRING are only relevant if they
29290 are present at buffer positions between START_CHARPOS and
29291 END_CHARPOS, or if they come from an overlay. */
29292 if (EQ (end->object, before_string))
29294 pos = string_buffer_position (before_string, start_charpos);
29295 if (!pos || (pos >= start_charpos && pos < end_charpos))
29296 break;
29298 else if (EQ (end->object, after_string))
29300 pos = string_buffer_position (after_string, end_charpos);
29301 if (!pos || (pos >= start_charpos && pos < end_charpos))
29302 break;
29305 /* Find the X coordinate of the last glyph to be highlighted. */
29306 for (; glyph <= end; ++glyph)
29307 x += glyph->pixel_width;
29309 hlinfo->mouse_face_end_x = x;
29310 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
29312 else
29314 /* Skip truncation and continuation glyphs near the end of the
29315 row, and also blanks and stretch glyphs inserted by
29316 extend_face_to_end_of_line. */
29317 x = r2->x;
29318 end++;
29319 while (end < glyph
29320 && NILP (end->object))
29322 x += end->pixel_width;
29323 ++end;
29325 /* Scan the rest of the glyph row from the end, looking for the
29326 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
29327 DISP_STRING, or whose position is between START_CHARPOS
29328 and END_CHARPOS */
29329 for ( ;
29330 end < glyph
29331 && !NILP (end->object)
29332 && !EQ (end->object, disp_string)
29333 && !(BUFFERP (end->object)
29334 && (end->charpos >= start_charpos
29335 && end->charpos < end_charpos));
29336 ++end)
29338 /* BEFORE_STRING or AFTER_STRING are only relevant if they
29339 are present at buffer positions between START_CHARPOS and
29340 END_CHARPOS, or if they come from an overlay. */
29341 if (EQ (end->object, before_string))
29343 pos = string_buffer_position (before_string, start_charpos);
29344 if (!pos || (pos >= start_charpos && pos < end_charpos))
29345 break;
29347 else if (EQ (end->object, after_string))
29349 pos = string_buffer_position (after_string, end_charpos);
29350 if (!pos || (pos >= start_charpos && pos < end_charpos))
29351 break;
29353 x += end->pixel_width;
29355 /* If we exited the above loop because we arrived at the last
29356 glyph of the row, and its buffer position is still not in
29357 range, it means the last character in range is the preceding
29358 newline. Bump the end column and x values to get past the
29359 last glyph. */
29360 if (end == glyph
29361 && BUFFERP (end->object)
29362 && (end->charpos < start_charpos
29363 || end->charpos >= end_charpos))
29365 x += end->pixel_width;
29366 ++end;
29368 hlinfo->mouse_face_end_x = x;
29369 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
29372 hlinfo->mouse_face_window = window;
29373 hlinfo->mouse_face_face_id
29374 = face_at_buffer_position (w, mouse_charpos, &ignore,
29375 mouse_charpos + 1,
29376 !hlinfo->mouse_face_hidden, -1);
29377 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
29380 /* The following function is not used anymore (replaced with
29381 mouse_face_from_string_pos), but I leave it here for the time
29382 being, in case someone would. */
29384 #if false /* not used */
29386 /* Find the position of the glyph for position POS in OBJECT in
29387 window W's current matrix, and return in *X, *Y the pixel
29388 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
29390 RIGHT_P means return the position of the right edge of the glyph.
29391 !RIGHT_P means return the left edge position.
29393 If no glyph for POS exists in the matrix, return the position of
29394 the glyph with the next smaller position that is in the matrix, if
29395 RIGHT_P is false. If RIGHT_P, and no glyph for POS
29396 exists in the matrix, return the position of the glyph with the
29397 next larger position in OBJECT.
29399 Value is true if a glyph was found. */
29401 static bool
29402 fast_find_string_pos (struct window *w, ptrdiff_t pos, Lisp_Object object,
29403 int *hpos, int *vpos, int *x, int *y, bool right_p)
29405 int yb = window_text_bottom_y (w);
29406 struct glyph_row *r;
29407 struct glyph *best_glyph = NULL;
29408 struct glyph_row *best_row = NULL;
29409 int best_x = 0;
29411 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
29412 r->enabled_p && r->y < yb;
29413 ++r)
29415 struct glyph *g = r->glyphs[TEXT_AREA];
29416 struct glyph *e = g + r->used[TEXT_AREA];
29417 int gx;
29419 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
29420 if (EQ (g->object, object))
29422 if (g->charpos == pos)
29424 best_glyph = g;
29425 best_x = gx;
29426 best_row = r;
29427 goto found;
29429 else if (best_glyph == NULL
29430 || ((eabs (g->charpos - pos)
29431 < eabs (best_glyph->charpos - pos))
29432 && (right_p
29433 ? g->charpos < pos
29434 : g->charpos > pos)))
29436 best_glyph = g;
29437 best_x = gx;
29438 best_row = r;
29443 found:
29445 if (best_glyph)
29447 *x = best_x;
29448 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
29450 if (right_p)
29452 *x += best_glyph->pixel_width;
29453 ++*hpos;
29456 *y = best_row->y;
29457 *vpos = MATRIX_ROW_VPOS (best_row, w->current_matrix);
29460 return best_glyph != NULL;
29462 #endif /* not used */
29464 /* Find the positions of the first and the last glyphs in window W's
29465 current matrix that occlude positions [STARTPOS..ENDPOS) in OBJECT
29466 (assumed to be a string), and return in HLINFO's mouse_face_*
29467 members the pixel and column/row coordinates of those glyphs. */
29469 static void
29470 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
29471 Lisp_Object object,
29472 ptrdiff_t startpos, ptrdiff_t endpos)
29474 int yb = window_text_bottom_y (w);
29475 struct glyph_row *r;
29476 struct glyph *g, *e;
29477 int gx;
29478 bool found = false;
29480 /* Find the glyph row with at least one position in the range
29481 [STARTPOS..ENDPOS), and the first glyph in that row whose
29482 position belongs to that range. */
29483 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
29484 r->enabled_p && r->y < yb;
29485 ++r)
29487 if (!r->reversed_p)
29489 g = r->glyphs[TEXT_AREA];
29490 e = g + r->used[TEXT_AREA];
29491 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
29492 if (EQ (g->object, object)
29493 && startpos <= g->charpos && g->charpos < endpos)
29495 hlinfo->mouse_face_beg_row
29496 = MATRIX_ROW_VPOS (r, w->current_matrix);
29497 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
29498 hlinfo->mouse_face_beg_x = gx;
29499 found = true;
29500 break;
29503 else
29505 struct glyph *g1;
29507 e = r->glyphs[TEXT_AREA];
29508 g = e + r->used[TEXT_AREA];
29509 for ( ; g > e; --g)
29510 if (EQ ((g-1)->object, object)
29511 && startpos <= (g-1)->charpos && (g-1)->charpos < endpos)
29513 hlinfo->mouse_face_beg_row
29514 = MATRIX_ROW_VPOS (r, w->current_matrix);
29515 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
29516 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
29517 gx += g1->pixel_width;
29518 hlinfo->mouse_face_beg_x = gx;
29519 found = true;
29520 break;
29523 if (found)
29524 break;
29527 if (!found)
29528 return;
29530 /* Starting with the next row, look for the first row which does NOT
29531 include any glyphs whose positions are in the range. */
29532 for (++r; r->enabled_p && r->y < yb; ++r)
29534 g = r->glyphs[TEXT_AREA];
29535 e = g + r->used[TEXT_AREA];
29536 found = false;
29537 for ( ; g < e; ++g)
29538 if (EQ (g->object, object)
29539 && startpos <= g->charpos && g->charpos < endpos)
29541 found = true;
29542 break;
29544 if (!found)
29545 break;
29548 /* The highlighted region ends on the previous row. */
29549 r--;
29551 /* Set the end row. */
29552 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r, w->current_matrix);
29554 /* Compute and set the end column and the end column's horizontal
29555 pixel coordinate. */
29556 if (!r->reversed_p)
29558 g = r->glyphs[TEXT_AREA];
29559 e = g + r->used[TEXT_AREA];
29560 for ( ; e > g; --e)
29561 if (EQ ((e-1)->object, object)
29562 && startpos <= (e-1)->charpos && (e-1)->charpos < endpos)
29563 break;
29564 hlinfo->mouse_face_end_col = e - g;
29566 for (gx = r->x; g < e; ++g)
29567 gx += g->pixel_width;
29568 hlinfo->mouse_face_end_x = gx;
29570 else
29572 e = r->glyphs[TEXT_AREA];
29573 g = e + r->used[TEXT_AREA];
29574 for (gx = r->x ; e < g; ++e)
29576 if (EQ (e->object, object)
29577 && startpos <= e->charpos && e->charpos < endpos)
29578 break;
29579 gx += e->pixel_width;
29581 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
29582 hlinfo->mouse_face_end_x = gx;
29586 #ifdef HAVE_WINDOW_SYSTEM
29588 /* See if position X, Y is within a hot-spot of an image. */
29590 static bool
29591 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
29593 if (!CONSP (hot_spot))
29594 return false;
29596 if (EQ (XCAR (hot_spot), Qrect))
29598 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
29599 Lisp_Object rect = XCDR (hot_spot);
29600 Lisp_Object tem;
29601 if (!CONSP (rect))
29602 return false;
29603 if (!CONSP (XCAR (rect)))
29604 return false;
29605 if (!CONSP (XCDR (rect)))
29606 return false;
29607 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
29608 return false;
29609 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
29610 return false;
29611 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
29612 return false;
29613 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
29614 return false;
29615 return true;
29617 else if (EQ (XCAR (hot_spot), Qcircle))
29619 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
29620 Lisp_Object circ = XCDR (hot_spot);
29621 Lisp_Object lr, lx0, ly0;
29622 if (CONSP (circ)
29623 && CONSP (XCAR (circ))
29624 && (lr = XCDR (circ), NUMBERP (lr))
29625 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
29626 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
29628 double r = XFLOATINT (lr);
29629 double dx = XINT (lx0) - x;
29630 double dy = XINT (ly0) - y;
29631 return (dx * dx + dy * dy <= r * r);
29634 else if (EQ (XCAR (hot_spot), Qpoly))
29636 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
29637 if (VECTORP (XCDR (hot_spot)))
29639 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
29640 Lisp_Object *poly = v->contents;
29641 ptrdiff_t n = v->header.size;
29642 ptrdiff_t i;
29643 bool inside = false;
29644 Lisp_Object lx, ly;
29645 int x0, y0;
29647 /* Need an even number of coordinates, and at least 3 edges. */
29648 if (n < 6 || n & 1)
29649 return false;
29651 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
29652 If count is odd, we are inside polygon. Pixels on edges
29653 may or may not be included depending on actual geometry of the
29654 polygon. */
29655 if ((lx = poly[n-2], !INTEGERP (lx))
29656 || (ly = poly[n-1], !INTEGERP (lx)))
29657 return false;
29658 x0 = XINT (lx), y0 = XINT (ly);
29659 for (i = 0; i < n; i += 2)
29661 int x1 = x0, y1 = y0;
29662 if ((lx = poly[i], !INTEGERP (lx))
29663 || (ly = poly[i+1], !INTEGERP (ly)))
29664 return false;
29665 x0 = XINT (lx), y0 = XINT (ly);
29667 /* Does this segment cross the X line? */
29668 if (x0 >= x)
29670 if (x1 >= x)
29671 continue;
29673 else if (x1 < x)
29674 continue;
29675 if (y > y0 && y > y1)
29676 continue;
29677 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
29678 inside = !inside;
29680 return inside;
29683 return false;
29686 Lisp_Object
29687 find_hot_spot (Lisp_Object map, int x, int y)
29689 while (CONSP (map))
29691 if (CONSP (XCAR (map))
29692 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
29693 return XCAR (map);
29694 map = XCDR (map);
29697 return Qnil;
29700 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
29701 3, 3, 0,
29702 doc: /* Lookup in image map MAP coordinates X and Y.
29703 An image map is an alist where each element has the format (AREA ID PLIST).
29704 An AREA is specified as either a rectangle, a circle, or a polygon:
29705 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
29706 pixel coordinates of the upper left and bottom right corners.
29707 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
29708 and the radius of the circle; r may be a float or integer.
29709 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
29710 vector describes one corner in the polygon.
29711 Returns the alist element for the first matching AREA in MAP. */)
29712 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
29714 if (NILP (map))
29715 return Qnil;
29717 CHECK_NUMBER (x);
29718 CHECK_NUMBER (y);
29720 return find_hot_spot (map,
29721 clip_to_bounds (INT_MIN, XINT (x), INT_MAX),
29722 clip_to_bounds (INT_MIN, XINT (y), INT_MAX));
29724 #endif /* HAVE_WINDOW_SYSTEM */
29727 /* Display frame CURSOR, optionally using shape defined by POINTER. */
29728 static void
29729 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
29731 #ifdef HAVE_WINDOW_SYSTEM
29732 if (!FRAME_WINDOW_P (f))
29733 return;
29735 /* Do not change cursor shape while dragging mouse. */
29736 if (EQ (do_mouse_tracking, Qdragging))
29737 return;
29739 if (!NILP (pointer))
29741 if (EQ (pointer, Qarrow))
29742 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
29743 else if (EQ (pointer, Qhand))
29744 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
29745 else if (EQ (pointer, Qtext))
29746 cursor = FRAME_X_OUTPUT (f)->text_cursor;
29747 else if (EQ (pointer, intern ("hdrag")))
29748 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
29749 else if (EQ (pointer, intern ("nhdrag")))
29750 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
29751 # ifdef HAVE_X_WINDOWS
29752 else if (EQ (pointer, intern ("vdrag")))
29753 cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
29754 # endif
29755 else if (EQ (pointer, intern ("hourglass")))
29756 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
29757 else if (EQ (pointer, Qmodeline))
29758 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
29759 else
29760 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
29763 if (cursor != No_Cursor)
29764 FRAME_RIF (f)->define_frame_cursor (f, cursor);
29765 #endif
29768 /* Take proper action when mouse has moved to the mode or header line
29769 or marginal area AREA of window W, x-position X and y-position Y.
29770 X is relative to the start of the text display area of W, so the
29771 width of bitmap areas and scroll bars must be subtracted to get a
29772 position relative to the start of the mode line. */
29774 static void
29775 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
29776 enum window_part area)
29778 struct window *w = XWINDOW (window);
29779 struct frame *f = XFRAME (w->frame);
29780 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
29781 #ifdef HAVE_WINDOW_SYSTEM
29782 Display_Info *dpyinfo;
29783 #endif
29784 Cursor cursor = No_Cursor;
29785 Lisp_Object pointer = Qnil;
29786 int dx, dy, width, height;
29787 ptrdiff_t charpos;
29788 Lisp_Object string, object = Qnil;
29789 Lisp_Object pos UNINIT;
29790 Lisp_Object mouse_face;
29791 int original_x_pixel = x;
29792 struct glyph * glyph = NULL, * row_start_glyph = NULL;
29793 struct glyph_row *row UNINIT;
29795 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
29797 int x0;
29798 struct glyph *end;
29800 /* Kludge alert: mode_line_string takes X/Y in pixels, but
29801 returns them in row/column units! */
29802 string = mode_line_string (w, area, &x, &y, &charpos,
29803 &object, &dx, &dy, &width, &height);
29805 row = (area == ON_MODE_LINE
29806 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
29807 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
29809 /* Find the glyph under the mouse pointer. */
29810 if (row->mode_line_p && row->enabled_p)
29812 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
29813 end = glyph + row->used[TEXT_AREA];
29815 for (x0 = original_x_pixel;
29816 glyph < end && x0 >= glyph->pixel_width;
29817 ++glyph)
29818 x0 -= glyph->pixel_width;
29820 if (glyph >= end)
29821 glyph = NULL;
29824 else
29826 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
29827 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
29828 returns them in row/column units! */
29829 string = marginal_area_string (w, area, &x, &y, &charpos,
29830 &object, &dx, &dy, &width, &height);
29833 Lisp_Object help = Qnil;
29835 #ifdef HAVE_WINDOW_SYSTEM
29836 if (IMAGEP (object))
29838 Lisp_Object image_map, hotspot;
29839 if ((image_map = Fplist_get (XCDR (object), QCmap),
29840 !NILP (image_map))
29841 && (hotspot = find_hot_spot (image_map, dx, dy),
29842 CONSP (hotspot))
29843 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
29845 Lisp_Object plist;
29847 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
29848 If so, we could look for mouse-enter, mouse-leave
29849 properties in PLIST (and do something...). */
29850 hotspot = XCDR (hotspot);
29851 if (CONSP (hotspot)
29852 && (plist = XCAR (hotspot), CONSP (plist)))
29854 pointer = Fplist_get (plist, Qpointer);
29855 if (NILP (pointer))
29856 pointer = Qhand;
29857 help = Fplist_get (plist, Qhelp_echo);
29858 if (!NILP (help))
29860 help_echo_string = help;
29861 XSETWINDOW (help_echo_window, w);
29862 help_echo_object = w->contents;
29863 help_echo_pos = charpos;
29867 if (NILP (pointer))
29868 pointer = Fplist_get (XCDR (object), QCpointer);
29870 #endif /* HAVE_WINDOW_SYSTEM */
29872 if (STRINGP (string))
29873 pos = make_number (charpos);
29875 /* Set the help text and mouse pointer. If the mouse is on a part
29876 of the mode line without any text (e.g. past the right edge of
29877 the mode line text), use the default help text and pointer. */
29878 if (STRINGP (string) || area == ON_MODE_LINE)
29880 /* Arrange to display the help by setting the global variables
29881 help_echo_string, help_echo_object, and help_echo_pos. */
29882 if (NILP (help))
29884 if (STRINGP (string))
29885 help = Fget_text_property (pos, Qhelp_echo, string);
29887 if (!NILP (help))
29889 help_echo_string = help;
29890 XSETWINDOW (help_echo_window, w);
29891 help_echo_object = string;
29892 help_echo_pos = charpos;
29894 else if (area == ON_MODE_LINE)
29896 Lisp_Object default_help
29897 = buffer_local_value (Qmode_line_default_help_echo,
29898 w->contents);
29900 if (STRINGP (default_help))
29902 help_echo_string = default_help;
29903 XSETWINDOW (help_echo_window, w);
29904 help_echo_object = Qnil;
29905 help_echo_pos = -1;
29910 #ifdef HAVE_WINDOW_SYSTEM
29911 /* Change the mouse pointer according to what is under it. */
29912 if (FRAME_WINDOW_P (f))
29914 bool draggable = (! WINDOW_BOTTOMMOST_P (w)
29915 || minibuf_level
29916 || NILP (Vresize_mini_windows));
29918 dpyinfo = FRAME_DISPLAY_INFO (f);
29919 if (STRINGP (string))
29921 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
29923 if (NILP (pointer))
29924 pointer = Fget_text_property (pos, Qpointer, string);
29926 /* Change the mouse pointer according to what is under X/Y. */
29927 if (NILP (pointer)
29928 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
29930 Lisp_Object map;
29931 map = Fget_text_property (pos, Qlocal_map, string);
29932 if (!KEYMAPP (map))
29933 map = Fget_text_property (pos, Qkeymap, string);
29934 if (!KEYMAPP (map) && draggable)
29935 cursor = dpyinfo->vertical_scroll_bar_cursor;
29938 else if (draggable)
29939 /* Default mode-line pointer. */
29940 cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
29942 #endif
29945 /* Change the mouse face according to what is under X/Y. */
29946 bool mouse_face_shown = false;
29947 if (STRINGP (string))
29949 mouse_face = Fget_text_property (pos, Qmouse_face, string);
29950 if (!NILP (Vmouse_highlight) && !NILP (mouse_face)
29951 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
29952 && glyph)
29954 Lisp_Object b, e;
29956 struct glyph * tmp_glyph;
29958 int gpos;
29959 int gseq_length;
29960 int total_pixel_width;
29961 ptrdiff_t begpos, endpos, ignore;
29963 int vpos, hpos;
29965 b = Fprevious_single_property_change (make_number (charpos + 1),
29966 Qmouse_face, string, Qnil);
29967 if (NILP (b))
29968 begpos = 0;
29969 else
29970 begpos = XINT (b);
29972 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
29973 if (NILP (e))
29974 endpos = SCHARS (string);
29975 else
29976 endpos = XINT (e);
29978 /* Calculate the glyph position GPOS of GLYPH in the
29979 displayed string, relative to the beginning of the
29980 highlighted part of the string.
29982 Note: GPOS is different from CHARPOS. CHARPOS is the
29983 position of GLYPH in the internal string object. A mode
29984 line string format has structures which are converted to
29985 a flattened string by the Emacs Lisp interpreter. The
29986 internal string is an element of those structures. The
29987 displayed string is the flattened string. */
29988 tmp_glyph = row_start_glyph;
29989 while (tmp_glyph < glyph
29990 && (!(EQ (tmp_glyph->object, glyph->object)
29991 && begpos <= tmp_glyph->charpos
29992 && tmp_glyph->charpos < endpos)))
29993 tmp_glyph++;
29994 gpos = glyph - tmp_glyph;
29996 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
29997 the highlighted part of the displayed string to which
29998 GLYPH belongs. Note: GSEQ_LENGTH is different from
29999 SCHARS (STRING), because the latter returns the length of
30000 the internal string. */
30001 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
30002 tmp_glyph > glyph
30003 && (!(EQ (tmp_glyph->object, glyph->object)
30004 && begpos <= tmp_glyph->charpos
30005 && tmp_glyph->charpos < endpos));
30006 tmp_glyph--)
30008 gseq_length = gpos + (tmp_glyph - glyph) + 1;
30010 /* Calculate the total pixel width of all the glyphs between
30011 the beginning of the highlighted area and GLYPH. */
30012 total_pixel_width = 0;
30013 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
30014 total_pixel_width += tmp_glyph->pixel_width;
30016 /* Pre calculation of re-rendering position. Note: X is in
30017 column units here, after the call to mode_line_string or
30018 marginal_area_string. */
30019 hpos = x - gpos;
30020 vpos = (area == ON_MODE_LINE
30021 ? (w->current_matrix)->nrows - 1
30022 : 0);
30024 /* If GLYPH's position is included in the region that is
30025 already drawn in mouse face, we have nothing to do. */
30026 if ( EQ (window, hlinfo->mouse_face_window)
30027 && (!row->reversed_p
30028 ? (hlinfo->mouse_face_beg_col <= hpos
30029 && hpos < hlinfo->mouse_face_end_col)
30030 /* In R2L rows we swap BEG and END, see below. */
30031 : (hlinfo->mouse_face_end_col <= hpos
30032 && hpos < hlinfo->mouse_face_beg_col))
30033 && hlinfo->mouse_face_beg_row == vpos )
30034 return;
30036 if (clear_mouse_face (hlinfo))
30037 cursor = No_Cursor;
30039 if (!row->reversed_p)
30041 hlinfo->mouse_face_beg_col = hpos;
30042 hlinfo->mouse_face_beg_x = original_x_pixel
30043 - (total_pixel_width + dx);
30044 hlinfo->mouse_face_end_col = hpos + gseq_length;
30045 hlinfo->mouse_face_end_x = 0;
30047 else
30049 /* In R2L rows, show_mouse_face expects BEG and END
30050 coordinates to be swapped. */
30051 hlinfo->mouse_face_end_col = hpos;
30052 hlinfo->mouse_face_end_x = original_x_pixel
30053 - (total_pixel_width + dx);
30054 hlinfo->mouse_face_beg_col = hpos + gseq_length;
30055 hlinfo->mouse_face_beg_x = 0;
30058 hlinfo->mouse_face_beg_row = vpos;
30059 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
30060 hlinfo->mouse_face_past_end = false;
30061 hlinfo->mouse_face_window = window;
30063 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
30064 charpos,
30065 0, &ignore,
30066 glyph->face_id,
30067 true);
30068 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
30069 mouse_face_shown = true;
30071 if (NILP (pointer))
30072 pointer = Qhand;
30076 /* If mouse-face doesn't need to be shown, clear any existing
30077 mouse-face. */
30078 if ((area == ON_MODE_LINE || area == ON_HEADER_LINE) && !mouse_face_shown)
30079 clear_mouse_face (hlinfo);
30081 define_frame_cursor1 (f, cursor, pointer);
30085 /* EXPORT:
30086 Take proper action when the mouse has moved to position X, Y on
30087 frame F with regards to highlighting portions of display that have
30088 mouse-face properties. Also de-highlight portions of display where
30089 the mouse was before, set the mouse pointer shape as appropriate
30090 for the mouse coordinates, and activate help echo (tooltips).
30091 X and Y can be negative or out of range. */
30093 void
30094 note_mouse_highlight (struct frame *f, int x, int y)
30096 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
30097 enum window_part part = ON_NOTHING;
30098 Lisp_Object window;
30099 struct window *w;
30100 Cursor cursor = No_Cursor;
30101 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
30102 struct buffer *b;
30104 /* When a menu is active, don't highlight because this looks odd. */
30105 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
30106 if (popup_activated ())
30107 return;
30108 #endif
30110 if (!f->glyphs_initialized_p
30111 || f->pointer_invisible)
30112 return;
30114 hlinfo->mouse_face_mouse_x = x;
30115 hlinfo->mouse_face_mouse_y = y;
30116 hlinfo->mouse_face_mouse_frame = f;
30118 if (hlinfo->mouse_face_defer)
30119 return;
30121 /* Which window is that in? */
30122 window = window_from_coordinates (f, x, y, &part, true);
30124 /* If displaying active text in another window, clear that. */
30125 if (! EQ (window, hlinfo->mouse_face_window)
30126 /* Also clear if we move out of text area in same window. */
30127 || (!NILP (hlinfo->mouse_face_window)
30128 && !NILP (window)
30129 && part != ON_TEXT
30130 && part != ON_MODE_LINE
30131 && part != ON_HEADER_LINE))
30132 clear_mouse_face (hlinfo);
30134 /* Not on a window -> return. */
30135 if (!WINDOWP (window))
30136 return;
30138 /* Reset help_echo_string. It will get recomputed below. */
30139 help_echo_string = Qnil;
30141 /* Convert to window-relative pixel coordinates. */
30142 w = XWINDOW (window);
30143 frame_to_window_pixel_xy (w, &x, &y);
30145 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
30146 /* Handle tool-bar window differently since it doesn't display a
30147 buffer. */
30148 if (EQ (window, f->tool_bar_window))
30150 note_tool_bar_highlight (f, x, y);
30151 return;
30153 #endif
30155 /* Mouse is on the mode, header line or margin? */
30156 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
30157 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
30159 note_mode_line_or_margin_highlight (window, x, y, part);
30161 #ifdef HAVE_WINDOW_SYSTEM
30162 if (part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
30164 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
30165 /* Show non-text cursor (Bug#16647). */
30166 goto set_cursor;
30168 else
30169 #endif
30170 return;
30173 #ifdef HAVE_WINDOW_SYSTEM
30174 if (part == ON_VERTICAL_BORDER)
30176 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
30177 help_echo_string = build_string ("drag-mouse-1: resize");
30179 else if (part == ON_RIGHT_DIVIDER)
30181 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
30182 help_echo_string = build_string ("drag-mouse-1: resize");
30184 else if (part == ON_BOTTOM_DIVIDER)
30185 if (! WINDOW_BOTTOMMOST_P (w)
30186 || minibuf_level
30187 || NILP (Vresize_mini_windows))
30189 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
30190 help_echo_string = build_string ("drag-mouse-1: resize");
30192 else
30193 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
30194 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
30195 || part == ON_VERTICAL_SCROLL_BAR
30196 || part == ON_HORIZONTAL_SCROLL_BAR)
30197 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
30198 else
30199 cursor = FRAME_X_OUTPUT (f)->text_cursor;
30200 #endif
30202 /* Are we in a window whose display is up to date?
30203 And verify the buffer's text has not changed. */
30204 b = XBUFFER (w->contents);
30205 if (part == ON_TEXT && w->window_end_valid && !window_outdated (w))
30207 int hpos, vpos, dx, dy, area = LAST_AREA;
30208 ptrdiff_t pos;
30209 struct glyph *glyph;
30210 Lisp_Object object;
30211 Lisp_Object mouse_face = Qnil, position;
30212 Lisp_Object *overlay_vec = NULL;
30213 ptrdiff_t i, noverlays;
30214 struct buffer *obuf;
30215 ptrdiff_t obegv, ozv;
30216 bool same_region;
30218 /* Find the glyph under X/Y. */
30219 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
30221 #ifdef HAVE_WINDOW_SYSTEM
30222 /* Look for :pointer property on image. */
30223 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
30225 struct image *img = IMAGE_OPT_FROM_ID (f, glyph->u.img_id);
30226 if (img != NULL && IMAGEP (img->spec))
30228 Lisp_Object image_map, hotspot;
30229 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
30230 !NILP (image_map))
30231 && (hotspot = find_hot_spot (image_map,
30232 glyph->slice.img.x + dx,
30233 glyph->slice.img.y + dy),
30234 CONSP (hotspot))
30235 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
30237 Lisp_Object plist;
30239 /* Could check XCAR (hotspot) to see if we enter/leave
30240 this hot-spot.
30241 If so, we could look for mouse-enter, mouse-leave
30242 properties in PLIST (and do something...). */
30243 hotspot = XCDR (hotspot);
30244 if (CONSP (hotspot)
30245 && (plist = XCAR (hotspot), CONSP (plist)))
30247 pointer = Fplist_get (plist, Qpointer);
30248 if (NILP (pointer))
30249 pointer = Qhand;
30250 help_echo_string = Fplist_get (plist, Qhelp_echo);
30251 if (!NILP (help_echo_string))
30253 help_echo_window = window;
30254 help_echo_object = glyph->object;
30255 help_echo_pos = glyph->charpos;
30259 if (NILP (pointer))
30260 pointer = Fplist_get (XCDR (img->spec), QCpointer);
30263 #endif /* HAVE_WINDOW_SYSTEM */
30265 /* Clear mouse face if X/Y not over text. */
30266 if (glyph == NULL
30267 || area != TEXT_AREA
30268 || !MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->current_matrix, vpos))
30269 /* Glyph's OBJECT is nil for glyphs inserted by the
30270 display engine for its internal purposes, like truncation
30271 and continuation glyphs and blanks beyond the end of
30272 line's text on text terminals. If we are over such a
30273 glyph, we are not over any text. */
30274 || NILP (glyph->object)
30275 /* R2L rows have a stretch glyph at their front, which
30276 stands for no text, whereas L2R rows have no glyphs at
30277 all beyond the end of text. Treat such stretch glyphs
30278 like we do with NULL glyphs in L2R rows. */
30279 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
30280 && glyph == MATRIX_ROW_GLYPH_START (w->current_matrix, vpos)
30281 && glyph->type == STRETCH_GLYPH
30282 && glyph->avoid_cursor_p))
30284 if (clear_mouse_face (hlinfo))
30285 cursor = No_Cursor;
30286 if (FRAME_WINDOW_P (f) && NILP (pointer))
30288 #ifdef HAVE_WINDOW_SYSTEM
30289 if (area != TEXT_AREA)
30290 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
30291 else
30292 pointer = Vvoid_text_area_pointer;
30293 #endif
30295 goto set_cursor;
30298 pos = glyph->charpos;
30299 object = glyph->object;
30300 if (!STRINGP (object) && !BUFFERP (object))
30301 goto set_cursor;
30303 /* If we get an out-of-range value, return now; avoid an error. */
30304 if (BUFFERP (object) && pos > BUF_Z (b))
30305 goto set_cursor;
30307 /* Make the window's buffer temporarily current for
30308 overlays_at and compute_char_face. */
30309 obuf = current_buffer;
30310 current_buffer = b;
30311 obegv = BEGV;
30312 ozv = ZV;
30313 BEGV = BEG;
30314 ZV = Z;
30316 /* Is this char mouse-active or does it have help-echo? */
30317 position = make_number (pos);
30319 USE_SAFE_ALLOCA;
30321 if (BUFFERP (object))
30323 /* Put all the overlays we want in a vector in overlay_vec. */
30324 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, false);
30325 /* Sort overlays into increasing priority order. */
30326 noverlays = sort_overlays (overlay_vec, noverlays, w);
30328 else
30329 noverlays = 0;
30331 if (NILP (Vmouse_highlight))
30333 clear_mouse_face (hlinfo);
30334 goto check_help_echo;
30337 same_region = coords_in_mouse_face_p (w, hpos, vpos);
30339 if (same_region)
30340 cursor = No_Cursor;
30342 /* Check mouse-face highlighting. */
30343 if (! same_region
30344 /* If there exists an overlay with mouse-face overlapping
30345 the one we are currently highlighting, we have to
30346 check if we enter the overlapping overlay, and then
30347 highlight only that. */
30348 || (OVERLAYP (hlinfo->mouse_face_overlay)
30349 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
30351 /* Find the highest priority overlay with a mouse-face. */
30352 Lisp_Object overlay = Qnil;
30353 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
30355 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
30356 if (!NILP (mouse_face))
30357 overlay = overlay_vec[i];
30360 /* If we're highlighting the same overlay as before, there's
30361 no need to do that again. */
30362 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
30363 goto check_help_echo;
30364 hlinfo->mouse_face_overlay = overlay;
30366 /* Clear the display of the old active region, if any. */
30367 if (clear_mouse_face (hlinfo))
30368 cursor = No_Cursor;
30370 /* If no overlay applies, get a text property. */
30371 if (NILP (overlay))
30372 mouse_face = Fget_text_property (position, Qmouse_face, object);
30374 /* Next, compute the bounds of the mouse highlighting and
30375 display it. */
30376 if (!NILP (mouse_face) && STRINGP (object))
30378 /* The mouse-highlighting comes from a display string
30379 with a mouse-face. */
30380 Lisp_Object s, e;
30381 ptrdiff_t ignore;
30383 s = Fprevious_single_property_change
30384 (make_number (pos + 1), Qmouse_face, object, Qnil);
30385 e = Fnext_single_property_change
30386 (position, Qmouse_face, object, Qnil);
30387 if (NILP (s))
30388 s = make_number (0);
30389 if (NILP (e))
30390 e = make_number (SCHARS (object));
30391 mouse_face_from_string_pos (w, hlinfo, object,
30392 XINT (s), XINT (e));
30393 hlinfo->mouse_face_past_end = false;
30394 hlinfo->mouse_face_window = window;
30395 hlinfo->mouse_face_face_id
30396 = face_at_string_position (w, object, pos, 0, &ignore,
30397 glyph->face_id, true);
30398 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
30399 cursor = No_Cursor;
30401 else
30403 /* The mouse-highlighting, if any, comes from an overlay
30404 or text property in the buffer. */
30405 Lisp_Object buffer UNINIT;
30406 Lisp_Object disp_string UNINIT;
30408 if (STRINGP (object))
30410 /* If we are on a display string with no mouse-face,
30411 check if the text under it has one. */
30412 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
30413 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
30414 pos = string_buffer_position (object, start);
30415 if (pos > 0)
30417 mouse_face = get_char_property_and_overlay
30418 (make_number (pos), Qmouse_face, w->contents, &overlay);
30419 buffer = w->contents;
30420 disp_string = object;
30423 else
30425 buffer = object;
30426 disp_string = Qnil;
30429 if (!NILP (mouse_face))
30431 Lisp_Object before, after;
30432 Lisp_Object before_string, after_string;
30433 /* To correctly find the limits of mouse highlight
30434 in a bidi-reordered buffer, we must not use the
30435 optimization of limiting the search in
30436 previous-single-property-change and
30437 next-single-property-change, because
30438 rows_from_pos_range needs the real start and end
30439 positions to DTRT in this case. That's because
30440 the first row visible in a window does not
30441 necessarily display the character whose position
30442 is the smallest. */
30443 Lisp_Object lim1
30444 = NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
30445 ? Fmarker_position (w->start)
30446 : Qnil;
30447 Lisp_Object lim2
30448 = NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
30449 ? make_number (BUF_Z (XBUFFER (buffer))
30450 - w->window_end_pos)
30451 : Qnil;
30453 if (NILP (overlay))
30455 /* Handle the text property case. */
30456 before = Fprevious_single_property_change
30457 (make_number (pos + 1), Qmouse_face, buffer, lim1);
30458 after = Fnext_single_property_change
30459 (make_number (pos), Qmouse_face, buffer, lim2);
30460 before_string = after_string = Qnil;
30462 else
30464 /* Handle the overlay case. */
30465 before = Foverlay_start (overlay);
30466 after = Foverlay_end (overlay);
30467 before_string = Foverlay_get (overlay, Qbefore_string);
30468 after_string = Foverlay_get (overlay, Qafter_string);
30470 if (!STRINGP (before_string)) before_string = Qnil;
30471 if (!STRINGP (after_string)) after_string = Qnil;
30474 mouse_face_from_buffer_pos (window, hlinfo, pos,
30475 NILP (before)
30477 : XFASTINT (before),
30478 NILP (after)
30479 ? BUF_Z (XBUFFER (buffer))
30480 : XFASTINT (after),
30481 before_string, after_string,
30482 disp_string);
30483 cursor = No_Cursor;
30488 check_help_echo:
30490 /* Look for a `help-echo' property. */
30491 if (NILP (help_echo_string)) {
30492 Lisp_Object help, overlay;
30494 /* Check overlays first. */
30495 help = overlay = Qnil;
30496 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
30498 overlay = overlay_vec[i];
30499 help = Foverlay_get (overlay, Qhelp_echo);
30502 if (!NILP (help))
30504 help_echo_string = help;
30505 help_echo_window = window;
30506 help_echo_object = overlay;
30507 help_echo_pos = pos;
30509 else
30511 Lisp_Object obj = glyph->object;
30512 ptrdiff_t charpos = glyph->charpos;
30514 /* Try text properties. */
30515 if (STRINGP (obj)
30516 && charpos >= 0
30517 && charpos < SCHARS (obj))
30519 help = Fget_text_property (make_number (charpos),
30520 Qhelp_echo, obj);
30521 if (NILP (help))
30523 /* If the string itself doesn't specify a help-echo,
30524 see if the buffer text ``under'' it does. */
30525 struct glyph_row *r
30526 = MATRIX_ROW (w->current_matrix, vpos);
30527 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
30528 ptrdiff_t p = string_buffer_position (obj, start);
30529 if (p > 0)
30531 help = Fget_char_property (make_number (p),
30532 Qhelp_echo, w->contents);
30533 if (!NILP (help))
30535 charpos = p;
30536 obj = w->contents;
30541 else if (BUFFERP (obj)
30542 && charpos >= BEGV
30543 && charpos < ZV)
30544 help = Fget_text_property (make_number (charpos), Qhelp_echo,
30545 obj);
30547 if (!NILP (help))
30549 help_echo_string = help;
30550 help_echo_window = window;
30551 help_echo_object = obj;
30552 help_echo_pos = charpos;
30557 #ifdef HAVE_WINDOW_SYSTEM
30558 /* Look for a `pointer' property. */
30559 if (FRAME_WINDOW_P (f) && NILP (pointer))
30561 /* Check overlays first. */
30562 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
30563 pointer = Foverlay_get (overlay_vec[i], Qpointer);
30565 if (NILP (pointer))
30567 Lisp_Object obj = glyph->object;
30568 ptrdiff_t charpos = glyph->charpos;
30570 /* Try text properties. */
30571 if (STRINGP (obj)
30572 && charpos >= 0
30573 && charpos < SCHARS (obj))
30575 pointer = Fget_text_property (make_number (charpos),
30576 Qpointer, obj);
30577 if (NILP (pointer))
30579 /* If the string itself doesn't specify a pointer,
30580 see if the buffer text ``under'' it does. */
30581 struct glyph_row *r
30582 = MATRIX_ROW (w->current_matrix, vpos);
30583 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
30584 ptrdiff_t p = string_buffer_position (obj, start);
30585 if (p > 0)
30586 pointer = Fget_char_property (make_number (p),
30587 Qpointer, w->contents);
30590 else if (BUFFERP (obj)
30591 && charpos >= BEGV
30592 && charpos < ZV)
30593 pointer = Fget_text_property (make_number (charpos),
30594 Qpointer, obj);
30597 #endif /* HAVE_WINDOW_SYSTEM */
30599 BEGV = obegv;
30600 ZV = ozv;
30601 current_buffer = obuf;
30602 SAFE_FREE ();
30605 set_cursor:
30606 define_frame_cursor1 (f, cursor, pointer);
30610 /* EXPORT for RIF:
30611 Clear any mouse-face on window W. This function is part of the
30612 redisplay interface, and is called from try_window_id and similar
30613 functions to ensure the mouse-highlight is off. */
30615 void
30616 x_clear_window_mouse_face (struct window *w)
30618 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
30619 Lisp_Object window;
30621 block_input ();
30622 XSETWINDOW (window, w);
30623 if (EQ (window, hlinfo->mouse_face_window))
30624 clear_mouse_face (hlinfo);
30625 unblock_input ();
30629 /* EXPORT:
30630 Just discard the mouse face information for frame F, if any.
30631 This is used when the size of F is changed. */
30633 void
30634 cancel_mouse_face (struct frame *f)
30636 Lisp_Object window;
30637 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
30639 window = hlinfo->mouse_face_window;
30640 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
30641 reset_mouse_highlight (hlinfo);
30646 /***********************************************************************
30647 Exposure Events
30648 ***********************************************************************/
30650 #ifdef HAVE_WINDOW_SYSTEM
30652 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
30653 which intersects rectangle R. R is in window-relative coordinates. */
30655 static void
30656 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
30657 enum glyph_row_area area)
30659 struct glyph *first = row->glyphs[area];
30660 struct glyph *end = row->glyphs[area] + row->used[area];
30661 struct glyph *last;
30662 int first_x, start_x, x;
30664 if (area == TEXT_AREA && row->fill_line_p)
30665 /* If row extends face to end of line write the whole line. */
30666 draw_glyphs (w, 0, row, area,
30667 0, row->used[area],
30668 DRAW_NORMAL_TEXT, 0);
30669 else
30671 /* Set START_X to the window-relative start position for drawing glyphs of
30672 AREA. The first glyph of the text area can be partially visible.
30673 The first glyphs of other areas cannot. */
30674 start_x = window_box_left_offset (w, area);
30675 x = start_x;
30676 if (area == TEXT_AREA)
30677 x += row->x;
30679 /* Find the first glyph that must be redrawn. */
30680 while (first < end
30681 && x + first->pixel_width < r->x)
30683 x += first->pixel_width;
30684 ++first;
30687 /* Find the last one. */
30688 last = first;
30689 first_x = x;
30690 /* Use a signed int intermediate value to avoid catastrophic
30691 failures due to comparison between signed and unsigned, when
30692 x is negative (can happen for wide images that are hscrolled). */
30693 int r_end = r->x + r->width;
30694 while (last < end && x < r_end)
30696 x += last->pixel_width;
30697 ++last;
30700 /* Repaint. */
30701 if (last > first)
30702 draw_glyphs (w, first_x - start_x, row, area,
30703 first - row->glyphs[area], last - row->glyphs[area],
30704 DRAW_NORMAL_TEXT, 0);
30709 /* Redraw the parts of the glyph row ROW on window W intersecting
30710 rectangle R. R is in window-relative coordinates. Value is
30711 true if mouse-face was overwritten. */
30713 static bool
30714 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
30716 eassert (row->enabled_p);
30718 if (row->mode_line_p || w->pseudo_window_p)
30719 draw_glyphs (w, 0, row, TEXT_AREA,
30720 0, row->used[TEXT_AREA],
30721 DRAW_NORMAL_TEXT, 0);
30722 else
30724 if (row->used[LEFT_MARGIN_AREA])
30725 expose_area (w, row, r, LEFT_MARGIN_AREA);
30726 if (row->used[TEXT_AREA])
30727 expose_area (w, row, r, TEXT_AREA);
30728 if (row->used[RIGHT_MARGIN_AREA])
30729 expose_area (w, row, r, RIGHT_MARGIN_AREA);
30730 draw_row_fringe_bitmaps (w, row);
30733 return row->mouse_face_p;
30737 /* Redraw those parts of glyphs rows during expose event handling that
30738 overlap other rows. Redrawing of an exposed line writes over parts
30739 of lines overlapping that exposed line; this function fixes that.
30741 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
30742 row in W's current matrix that is exposed and overlaps other rows.
30743 LAST_OVERLAPPING_ROW is the last such row. */
30745 static void
30746 expose_overlaps (struct window *w,
30747 struct glyph_row *first_overlapping_row,
30748 struct glyph_row *last_overlapping_row,
30749 XRectangle *r)
30751 struct glyph_row *row;
30753 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
30754 if (row->overlapping_p)
30756 eassert (row->enabled_p && !row->mode_line_p);
30758 row->clip = r;
30759 if (row->used[LEFT_MARGIN_AREA])
30760 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
30762 if (row->used[TEXT_AREA])
30763 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
30765 if (row->used[RIGHT_MARGIN_AREA])
30766 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
30767 row->clip = NULL;
30772 /* Return true if W's cursor intersects rectangle R. */
30774 static bool
30775 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
30777 XRectangle cr, result;
30778 struct glyph *cursor_glyph;
30779 struct glyph_row *row;
30781 if (w->phys_cursor.vpos >= 0
30782 && w->phys_cursor.vpos < w->current_matrix->nrows
30783 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
30784 row->enabled_p)
30785 && row->cursor_in_fringe_p)
30787 /* Cursor is in the fringe. */
30788 cr.x = window_box_right_offset (w,
30789 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
30790 ? RIGHT_MARGIN_AREA
30791 : TEXT_AREA));
30792 cr.y = row->y;
30793 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
30794 cr.height = row->height;
30795 return x_intersect_rectangles (&cr, r, &result);
30798 cursor_glyph = get_phys_cursor_glyph (w);
30799 if (cursor_glyph)
30801 /* r is relative to W's box, but w->phys_cursor.x is relative
30802 to left edge of W's TEXT area. Adjust it. */
30803 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
30804 cr.y = w->phys_cursor.y;
30805 cr.width = cursor_glyph->pixel_width;
30806 cr.height = w->phys_cursor_height;
30807 /* ++KFS: W32 version used W32-specific IntersectRect here, but
30808 I assume the effect is the same -- and this is portable. */
30809 return x_intersect_rectangles (&cr, r, &result);
30811 /* If we don't understand the format, pretend we're not in the hot-spot. */
30812 return false;
30816 /* EXPORT:
30817 Draw a vertical window border to the right of window W if W doesn't
30818 have vertical scroll bars. */
30820 void
30821 x_draw_vertical_border (struct window *w)
30823 struct frame *f = XFRAME (WINDOW_FRAME (w));
30825 /* We could do better, if we knew what type of scroll-bar the adjacent
30826 windows (on either side) have... But we don't :-(
30827 However, I think this works ok. ++KFS 2003-04-25 */
30829 /* Redraw borders between horizontally adjacent windows. Don't
30830 do it for frames with vertical scroll bars because either the
30831 right scroll bar of a window, or the left scroll bar of its
30832 neighbor will suffice as a border. */
30833 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f) || FRAME_RIGHT_DIVIDER_WIDTH (f))
30834 return;
30836 /* Note: It is necessary to redraw both the left and the right
30837 borders, for when only this single window W is being
30838 redisplayed. */
30839 if (!WINDOW_RIGHTMOST_P (w)
30840 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
30842 int x0, x1, y0, y1;
30844 window_box_edges (w, &x0, &y0, &x1, &y1);
30845 y1 -= 1;
30847 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
30848 x1 -= 1;
30850 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
30853 if (!WINDOW_LEFTMOST_P (w)
30854 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
30856 int x0, x1, y0, y1;
30858 window_box_edges (w, &x0, &y0, &x1, &y1);
30859 y1 -= 1;
30861 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
30862 x0 -= 1;
30864 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
30869 /* Draw window dividers for window W. */
30871 void
30872 x_draw_right_divider (struct window *w)
30874 struct frame *f = WINDOW_XFRAME (w);
30876 if (w->mini || w->pseudo_window_p)
30877 return;
30878 else if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
30880 int x0 = WINDOW_RIGHT_EDGE_X (w) - WINDOW_RIGHT_DIVIDER_WIDTH (w);
30881 int x1 = WINDOW_RIGHT_EDGE_X (w);
30882 int y0 = WINDOW_TOP_EDGE_Y (w);
30883 /* The bottom divider prevails. */
30884 int y1 = WINDOW_BOTTOM_EDGE_Y (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
30886 FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
30890 static void
30891 x_draw_bottom_divider (struct window *w)
30893 struct frame *f = XFRAME (WINDOW_FRAME (w));
30895 if (w->mini || w->pseudo_window_p)
30896 return;
30897 else if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
30899 int x0 = WINDOW_LEFT_EDGE_X (w);
30900 int x1 = WINDOW_RIGHT_EDGE_X (w);
30901 int y0 = WINDOW_BOTTOM_EDGE_Y (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
30902 int y1 = WINDOW_BOTTOM_EDGE_Y (w);
30904 FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
30908 /* Redraw the part of window W intersection rectangle FR. Pixel
30909 coordinates in FR are frame-relative. Call this function with
30910 input blocked. Value is true if the exposure overwrites
30911 mouse-face. */
30913 static bool
30914 expose_window (struct window *w, XRectangle *fr)
30916 struct frame *f = XFRAME (w->frame);
30917 XRectangle wr, r;
30918 bool mouse_face_overwritten_p = false;
30920 /* If window is not yet fully initialized, do nothing. This can
30921 happen when toolkit scroll bars are used and a window is split.
30922 Reconfiguring the scroll bar will generate an expose for a newly
30923 created window. */
30924 if (w->current_matrix == NULL)
30925 return false;
30927 /* When we're currently updating the window, display and current
30928 matrix usually don't agree. Arrange for a thorough display
30929 later. */
30930 if (w->must_be_updated_p)
30932 SET_FRAME_GARBAGED (f);
30933 return false;
30936 /* Frame-relative pixel rectangle of W. */
30937 wr.x = WINDOW_LEFT_EDGE_X (w);
30938 wr.y = WINDOW_TOP_EDGE_Y (w);
30939 wr.width = WINDOW_PIXEL_WIDTH (w);
30940 wr.height = WINDOW_PIXEL_HEIGHT (w);
30942 if (x_intersect_rectangles (fr, &wr, &r))
30944 int yb = window_text_bottom_y (w);
30945 struct glyph_row *row;
30946 struct glyph_row *first_overlapping_row, *last_overlapping_row;
30948 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
30949 r.x, r.y, r.width, r.height));
30951 /* Convert to window coordinates. */
30952 r.x -= WINDOW_LEFT_EDGE_X (w);
30953 r.y -= WINDOW_TOP_EDGE_Y (w);
30955 /* Turn off the cursor. */
30956 bool cursor_cleared_p = (!w->pseudo_window_p
30957 && phys_cursor_in_rect_p (w, &r));
30958 if (cursor_cleared_p)
30959 x_clear_cursor (w);
30961 /* If the row containing the cursor extends face to end of line,
30962 then expose_area might overwrite the cursor outside the
30963 rectangle and thus notice_overwritten_cursor might clear
30964 w->phys_cursor_on_p. We remember the original value and
30965 check later if it is changed. */
30966 bool phys_cursor_on_p = w->phys_cursor_on_p;
30968 /* Use a signed int intermediate value to avoid catastrophic
30969 failures due to comparison between signed and unsigned, when
30970 y0 or y1 is negative (can happen for tall images). */
30971 int r_bottom = r.y + r.height;
30973 /* Update lines intersecting rectangle R. */
30974 first_overlapping_row = last_overlapping_row = NULL;
30975 for (row = w->current_matrix->rows;
30976 row->enabled_p;
30977 ++row)
30979 int y0 = row->y;
30980 int y1 = MATRIX_ROW_BOTTOM_Y (row);
30982 if ((y0 >= r.y && y0 < r_bottom)
30983 || (y1 > r.y && y1 < r_bottom)
30984 || (r.y >= y0 && r.y < y1)
30985 || (r_bottom > y0 && r_bottom < y1))
30987 /* A header line may be overlapping, but there is no need
30988 to fix overlapping areas for them. KFS 2005-02-12 */
30989 if (row->overlapping_p && !row->mode_line_p)
30991 if (first_overlapping_row == NULL)
30992 first_overlapping_row = row;
30993 last_overlapping_row = row;
30996 row->clip = fr;
30997 if (expose_line (w, row, &r))
30998 mouse_face_overwritten_p = true;
30999 row->clip = NULL;
31001 else if (row->overlapping_p)
31003 /* We must redraw a row overlapping the exposed area. */
31004 if (y0 < r.y
31005 ? y0 + row->phys_height > r.y
31006 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
31008 if (first_overlapping_row == NULL)
31009 first_overlapping_row = row;
31010 last_overlapping_row = row;
31014 if (y1 >= yb)
31015 break;
31018 /* Display the mode line if there is one. */
31019 if (WINDOW_WANTS_MODELINE_P (w)
31020 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
31021 row->enabled_p)
31022 && row->y < r_bottom)
31024 if (expose_line (w, row, &r))
31025 mouse_face_overwritten_p = true;
31028 if (!w->pseudo_window_p)
31030 /* Fix the display of overlapping rows. */
31031 if (first_overlapping_row)
31032 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
31033 fr);
31035 /* Draw border between windows. */
31036 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
31037 x_draw_right_divider (w);
31038 else
31039 x_draw_vertical_border (w);
31041 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
31042 x_draw_bottom_divider (w);
31044 /* Turn the cursor on again. */
31045 if (cursor_cleared_p
31046 || (phys_cursor_on_p && !w->phys_cursor_on_p))
31047 update_window_cursor (w, true);
31051 return mouse_face_overwritten_p;
31056 /* Redraw (parts) of all windows in the window tree rooted at W that
31057 intersect R. R contains frame pixel coordinates. Value is
31058 true if the exposure overwrites mouse-face. */
31060 static bool
31061 expose_window_tree (struct window *w, XRectangle *r)
31063 struct frame *f = XFRAME (w->frame);
31064 bool mouse_face_overwritten_p = false;
31066 while (w && !FRAME_GARBAGED_P (f))
31068 mouse_face_overwritten_p
31069 |= (WINDOWP (w->contents)
31070 ? expose_window_tree (XWINDOW (w->contents), r)
31071 : expose_window (w, r));
31073 w = NILP (w->next) ? NULL : XWINDOW (w->next);
31076 return mouse_face_overwritten_p;
31080 /* EXPORT:
31081 Redisplay an exposed area of frame F. X and Y are the upper-left
31082 corner of the exposed rectangle. W and H are width and height of
31083 the exposed area. All are pixel values. W or H zero means redraw
31084 the entire frame. */
31086 void
31087 expose_frame (struct frame *f, int x, int y, int w, int h)
31089 XRectangle r;
31090 bool mouse_face_overwritten_p = false;
31092 TRACE ((stderr, "expose_frame "));
31094 /* No need to redraw if frame will be redrawn soon. */
31095 if (FRAME_GARBAGED_P (f))
31097 TRACE ((stderr, " garbaged\n"));
31098 return;
31101 /* If basic faces haven't been realized yet, there is no point in
31102 trying to redraw anything. This can happen when we get an expose
31103 event while Emacs is starting, e.g. by moving another window. */
31104 if (FRAME_FACE_CACHE (f) == NULL
31105 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
31107 TRACE ((stderr, " no faces\n"));
31108 return;
31111 if (w == 0 || h == 0)
31113 r.x = r.y = 0;
31114 r.width = FRAME_TEXT_WIDTH (f);
31115 r.height = FRAME_TEXT_HEIGHT (f);
31117 else
31119 r.x = x;
31120 r.y = y;
31121 r.width = w;
31122 r.height = h;
31125 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
31126 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
31128 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
31129 if (WINDOWP (f->tool_bar_window))
31130 mouse_face_overwritten_p
31131 |= expose_window (XWINDOW (f->tool_bar_window), &r);
31132 #endif
31134 #ifdef HAVE_X_WINDOWS
31135 #ifndef MSDOS
31136 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
31137 if (WINDOWP (f->menu_bar_window))
31138 mouse_face_overwritten_p
31139 |= expose_window (XWINDOW (f->menu_bar_window), &r);
31140 #endif /* not USE_X_TOOLKIT and not USE_GTK */
31141 #endif
31142 #endif
31144 /* Some window managers support a focus-follows-mouse style with
31145 delayed raising of frames. Imagine a partially obscured frame,
31146 and moving the mouse into partially obscured mouse-face on that
31147 frame. The visible part of the mouse-face will be highlighted,
31148 then the WM raises the obscured frame. With at least one WM, KDE
31149 2.1, Emacs is not getting any event for the raising of the frame
31150 (even tried with SubstructureRedirectMask), only Expose events.
31151 These expose events will draw text normally, i.e. not
31152 highlighted. Which means we must redo the highlight here.
31153 Subsume it under ``we love X''. --gerd 2001-08-15 */
31154 /* Included in Windows version because Windows most likely does not
31155 do the right thing if any third party tool offers
31156 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
31157 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
31159 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
31160 if (f == hlinfo->mouse_face_mouse_frame)
31162 int mouse_x = hlinfo->mouse_face_mouse_x;
31163 int mouse_y = hlinfo->mouse_face_mouse_y;
31164 clear_mouse_face (hlinfo);
31165 note_mouse_highlight (f, mouse_x, mouse_y);
31171 /* EXPORT:
31172 Determine the intersection of two rectangles R1 and R2. Return
31173 the intersection in *RESULT. Value is true if RESULT is not
31174 empty. */
31176 bool
31177 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
31179 XRectangle *left, *right;
31180 XRectangle *upper, *lower;
31181 bool intersection_p = false;
31183 /* Rearrange so that R1 is the left-most rectangle. */
31184 if (r1->x < r2->x)
31185 left = r1, right = r2;
31186 else
31187 left = r2, right = r1;
31189 /* X0 of the intersection is right.x0, if this is inside R1,
31190 otherwise there is no intersection. */
31191 if (right->x <= left->x + left->width)
31193 result->x = right->x;
31195 /* The right end of the intersection is the minimum of
31196 the right ends of left and right. */
31197 result->width = (min (left->x + left->width, right->x + right->width)
31198 - result->x);
31200 /* Same game for Y. */
31201 if (r1->y < r2->y)
31202 upper = r1, lower = r2;
31203 else
31204 upper = r2, lower = r1;
31206 /* The upper end of the intersection is lower.y0, if this is inside
31207 of upper. Otherwise, there is no intersection. */
31208 if (lower->y <= upper->y + upper->height)
31210 result->y = lower->y;
31212 /* The lower end of the intersection is the minimum of the lower
31213 ends of upper and lower. */
31214 result->height = (min (lower->y + lower->height,
31215 upper->y + upper->height)
31216 - result->y);
31217 intersection_p = true;
31221 return intersection_p;
31224 #endif /* HAVE_WINDOW_SYSTEM */
31227 /***********************************************************************
31228 Initialization
31229 ***********************************************************************/
31231 void
31232 syms_of_xdisp (void)
31234 Vwith_echo_area_save_vector = Qnil;
31235 staticpro (&Vwith_echo_area_save_vector);
31237 Vmessage_stack = Qnil;
31238 staticpro (&Vmessage_stack);
31240 /* Non-nil means don't actually do any redisplay. */
31241 DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
31243 DEFSYM (Qredisplay_internal_xC_functionx, "redisplay_internal (C function)");
31245 DEFVAR_BOOL("inhibit-message", inhibit_message,
31246 doc: /* Non-nil means calls to `message' are not displayed.
31247 They are still logged to the *Messages* buffer. */);
31248 inhibit_message = 0;
31250 message_dolog_marker1 = Fmake_marker ();
31251 staticpro (&message_dolog_marker1);
31252 message_dolog_marker2 = Fmake_marker ();
31253 staticpro (&message_dolog_marker2);
31254 message_dolog_marker3 = Fmake_marker ();
31255 staticpro (&message_dolog_marker3);
31257 #ifdef GLYPH_DEBUG
31258 defsubr (&Sdump_frame_glyph_matrix);
31259 defsubr (&Sdump_glyph_matrix);
31260 defsubr (&Sdump_glyph_row);
31261 defsubr (&Sdump_tool_bar_row);
31262 defsubr (&Strace_redisplay);
31263 defsubr (&Strace_to_stderr);
31264 #endif
31265 #ifdef HAVE_WINDOW_SYSTEM
31266 defsubr (&Stool_bar_height);
31267 defsubr (&Slookup_image_map);
31268 #endif
31269 defsubr (&Sline_pixel_height);
31270 defsubr (&Sformat_mode_line);
31271 defsubr (&Sinvisible_p);
31272 defsubr (&Scurrent_bidi_paragraph_direction);
31273 defsubr (&Swindow_text_pixel_size);
31274 defsubr (&Smove_point_visually);
31275 defsubr (&Sbidi_find_overridden_directionality);
31277 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
31278 DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
31279 DEFSYM (Qoverriding_local_map, "overriding-local-map");
31280 DEFSYM (Qwindow_scroll_functions, "window-scroll-functions");
31281 DEFSYM (Qwindow_text_change_functions, "window-text-change-functions");
31282 DEFSYM (Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions");
31283 DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
31284 DEFSYM (Qeval, "eval");
31285 DEFSYM (QCdata, ":data");
31287 /* Names of text properties relevant for redisplay. */
31288 DEFSYM (Qdisplay, "display");
31289 DEFSYM (Qspace_width, "space-width");
31290 DEFSYM (Qraise, "raise");
31291 DEFSYM (Qslice, "slice");
31292 DEFSYM (Qspace, "space");
31293 DEFSYM (Qmargin, "margin");
31294 DEFSYM (Qpointer, "pointer");
31295 DEFSYM (Qleft_margin, "left-margin");
31296 DEFSYM (Qright_margin, "right-margin");
31297 DEFSYM (Qcenter, "center");
31298 DEFSYM (Qline_height, "line-height");
31299 DEFSYM (QCalign_to, ":align-to");
31300 DEFSYM (QCrelative_width, ":relative-width");
31301 DEFSYM (QCrelative_height, ":relative-height");
31302 DEFSYM (QCeval, ":eval");
31303 DEFSYM (QCpropertize, ":propertize");
31304 DEFSYM (QCfile, ":file");
31305 DEFSYM (Qfontified, "fontified");
31306 DEFSYM (Qfontification_functions, "fontification-functions");
31308 /* Name of the face used to highlight trailing whitespace. */
31309 DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
31311 /* Name and number of the face used to highlight escape glyphs. */
31312 DEFSYM (Qescape_glyph, "escape-glyph");
31314 /* Name and number of the face used to highlight non-breaking
31315 spaces/hyphens. */
31316 DEFSYM (Qnobreak_space, "nobreak-space");
31317 DEFSYM (Qnobreak_hyphen, "nobreak-hyphen");
31319 /* The symbol 'image' which is the car of the lists used to represent
31320 images in Lisp. Also a tool bar style. */
31321 DEFSYM (Qimage, "image");
31323 /* Tool bar styles. */
31324 DEFSYM (Qtext, "text");
31325 DEFSYM (Qboth, "both");
31326 DEFSYM (Qboth_horiz, "both-horiz");
31327 DEFSYM (Qtext_image_horiz, "text-image-horiz");
31329 /* The image map types. */
31330 DEFSYM (QCmap, ":map");
31331 DEFSYM (QCpointer, ":pointer");
31332 DEFSYM (Qrect, "rect");
31333 DEFSYM (Qcircle, "circle");
31334 DEFSYM (Qpoly, "poly");
31336 DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
31338 DEFSYM (Qgrow_only, "grow-only");
31339 DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
31340 DEFSYM (Qposition, "position");
31341 DEFSYM (Qbuffer_position, "buffer-position");
31342 DEFSYM (Qobject, "object");
31344 /* Cursor shapes. */
31345 DEFSYM (Qbar, "bar");
31346 DEFSYM (Qhbar, "hbar");
31347 DEFSYM (Qbox, "box");
31348 DEFSYM (Qhollow, "hollow");
31350 /* Pointer shapes. */
31351 DEFSYM (Qhand, "hand");
31352 DEFSYM (Qarrow, "arrow");
31353 /* also Qtext */
31355 DEFSYM (Qdragging, "dragging");
31357 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
31359 list_of_error = list1 (list2 (Qerror, Qvoid_variable));
31360 staticpro (&list_of_error);
31362 /* Values of those variables at last redisplay are stored as
31363 properties on 'overlay-arrow-position' symbol. However, if
31364 Voverlay_arrow_position is a marker, last-arrow-position is its
31365 numerical position. */
31366 DEFSYM (Qlast_arrow_position, "last-arrow-position");
31367 DEFSYM (Qlast_arrow_string, "last-arrow-string");
31369 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
31370 properties on a symbol in overlay-arrow-variable-list. */
31371 DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
31372 DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
31374 echo_buffer[0] = echo_buffer[1] = Qnil;
31375 staticpro (&echo_buffer[0]);
31376 staticpro (&echo_buffer[1]);
31378 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
31379 staticpro (&echo_area_buffer[0]);
31380 staticpro (&echo_area_buffer[1]);
31382 Vmessages_buffer_name = build_pure_c_string ("*Messages*");
31383 staticpro (&Vmessages_buffer_name);
31385 mode_line_proptrans_alist = Qnil;
31386 staticpro (&mode_line_proptrans_alist);
31387 mode_line_string_list = Qnil;
31388 staticpro (&mode_line_string_list);
31389 mode_line_string_face = Qnil;
31390 staticpro (&mode_line_string_face);
31391 mode_line_string_face_prop = Qnil;
31392 staticpro (&mode_line_string_face_prop);
31393 Vmode_line_unwind_vector = Qnil;
31394 staticpro (&Vmode_line_unwind_vector);
31396 DEFSYM (Qmode_line_default_help_echo, "mode-line-default-help-echo");
31398 help_echo_string = Qnil;
31399 staticpro (&help_echo_string);
31400 help_echo_object = Qnil;
31401 staticpro (&help_echo_object);
31402 help_echo_window = Qnil;
31403 staticpro (&help_echo_window);
31404 previous_help_echo_string = Qnil;
31405 staticpro (&previous_help_echo_string);
31406 help_echo_pos = -1;
31408 DEFSYM (Qright_to_left, "right-to-left");
31409 DEFSYM (Qleft_to_right, "left-to-right");
31410 defsubr (&Sbidi_resolved_levels);
31412 #ifdef HAVE_WINDOW_SYSTEM
31413 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
31414 doc: /* Non-nil means draw block cursor as wide as the glyph under it.
31415 For example, if a block cursor is over a tab, it will be drawn as
31416 wide as that tab on the display. */);
31417 x_stretch_cursor_p = 0;
31418 #endif
31420 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
31421 doc: /* Non-nil means highlight trailing whitespace.
31422 The face used for trailing whitespace is `trailing-whitespace'. */);
31423 Vshow_trailing_whitespace = Qnil;
31425 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
31426 doc: /* Control highlighting of non-ASCII space and hyphen chars.
31427 If the value is t, Emacs highlights non-ASCII chars which have the
31428 same appearance as an ASCII space or hyphen, using the `nobreak-space'
31429 or `nobreak-hyphen' face respectively.
31431 U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
31432 U+2011 (non-breaking hyphen) are affected.
31434 Any other non-nil value means to display these characters as a escape
31435 glyph followed by an ordinary space or hyphen.
31437 A value of nil means no special handling of these characters. */);
31438 Vnobreak_char_display = Qt;
31440 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
31441 doc: /* The pointer shape to show in void text areas.
31442 A value of nil means to show the text pointer. Other options are
31443 `arrow', `text', `hand', `vdrag', `hdrag', `nhdrag', `modeline', and
31444 `hourglass'. */);
31445 Vvoid_text_area_pointer = Qarrow;
31447 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
31448 doc: /* Non-nil means don't actually do any redisplay.
31449 This is used for internal purposes. */);
31450 Vinhibit_redisplay = Qnil;
31452 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
31453 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
31454 Vglobal_mode_string = Qnil;
31456 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
31457 doc: /* Marker for where to display an arrow on top of the buffer text.
31458 This must be the beginning of a line in order to work.
31459 See also `overlay-arrow-string'. */);
31460 Voverlay_arrow_position = Qnil;
31462 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
31463 doc: /* String to display as an arrow in non-window frames.
31464 See also `overlay-arrow-position'. */);
31465 Voverlay_arrow_string = build_pure_c_string ("=>");
31467 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
31468 doc: /* List of variables (symbols) which hold markers for overlay arrows.
31469 The symbols on this list are examined during redisplay to determine
31470 where to display overlay arrows. */);
31471 Voverlay_arrow_variable_list
31472 = list1 (intern_c_string ("overlay-arrow-position"));
31474 DEFVAR_INT ("scroll-step", emacs_scroll_step,
31475 doc: /* The number of lines to try scrolling a window by when point moves out.
31476 If that fails to bring point back on frame, point is centered instead.
31477 If this is zero, point is always centered after it moves off frame.
31478 If you want scrolling to always be a line at a time, you should set
31479 `scroll-conservatively' to a large value rather than set this to 1. */);
31481 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
31482 doc: /* Scroll up to this many lines, to bring point back on screen.
31483 If point moves off-screen, redisplay will scroll by up to
31484 `scroll-conservatively' lines in order to bring point just barely
31485 onto the screen again. If that cannot be done, then redisplay
31486 recenters point as usual.
31488 If the value is greater than 100, redisplay will never recenter point,
31489 but will always scroll just enough text to bring point into view, even
31490 if you move far away.
31492 A value of zero means always recenter point if it moves off screen. */);
31493 scroll_conservatively = 0;
31495 DEFVAR_INT ("scroll-margin", scroll_margin,
31496 doc: /* Number of lines of margin at the top and bottom of a window.
31497 Recenter the window whenever point gets within this many lines
31498 of the top or bottom of the window. */);
31499 scroll_margin = 0;
31501 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
31502 doc: /* Pixels per inch value for non-window system displays.
31503 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
31504 Vdisplay_pixels_per_inch = make_float (72.0);
31506 #ifdef GLYPH_DEBUG
31507 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
31508 #endif
31510 DEFVAR_LISP ("truncate-partial-width-windows",
31511 Vtruncate_partial_width_windows,
31512 doc: /* Non-nil means truncate lines in windows narrower than the frame.
31513 For an integer value, truncate lines in each window narrower than the
31514 full frame width, provided the total window width in column units is less
31515 than that integer; otherwise, respect the value of `truncate-lines'.
31516 The total width of the window is as returned by `window-total-width', it
31517 includes the fringes, the continuation and truncation glyphs, the
31518 display margins (if any), and the scroll bar
31520 For any other non-nil value, truncate lines in all windows that do
31521 not span the full frame width.
31523 A value of nil means to respect the value of `truncate-lines'.
31525 If `word-wrap' is enabled, you might want to reduce this. */);
31526 Vtruncate_partial_width_windows = make_number (50);
31528 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
31529 doc: /* Maximum buffer size for which line number should be displayed.
31530 If the buffer is bigger than this, the line number does not appear
31531 in the mode line. A value of nil means no limit. */);
31532 Vline_number_display_limit = Qnil;
31534 DEFVAR_INT ("line-number-display-limit-width",
31535 line_number_display_limit_width,
31536 doc: /* Maximum line width (in characters) for line number display.
31537 If the average length of the lines near point is bigger than this, then the
31538 line number may be omitted from the mode line. */);
31539 line_number_display_limit_width = 200;
31541 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
31542 doc: /* Non-nil means highlight region even in nonselected windows. */);
31543 highlight_nonselected_windows = false;
31545 DEFVAR_BOOL ("multiple-frames", multiple_frames,
31546 doc: /* Non-nil if more than one frame is visible on this display.
31547 Minibuffer-only frames don't count, but iconified frames do.
31548 This variable is not guaranteed to be accurate except while processing
31549 `frame-title-format' and `icon-title-format'. */);
31551 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
31552 doc: /* Template for displaying the title bar of visible frames.
31553 \(Assuming the window manager supports this feature.)
31555 This variable has the same structure as `mode-line-format', except that
31556 the %c and %l constructs are ignored. It is used only on frames for
31557 which no explicit name has been set (see `modify-frame-parameters'). */);
31559 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
31560 doc: /* Template for displaying the title bar of an iconified frame.
31561 \(Assuming the window manager supports this feature.)
31562 This variable has the same structure as `mode-line-format' (which see),
31563 and is used only on frames for which no explicit name has been set
31564 \(see `modify-frame-parameters'). */);
31565 Vicon_title_format
31566 = Vframe_title_format
31567 = listn (CONSTYPE_PURE, 3,
31568 intern_c_string ("multiple-frames"),
31569 build_pure_c_string ("%b"),
31570 listn (CONSTYPE_PURE, 4,
31571 empty_unibyte_string,
31572 intern_c_string ("invocation-name"),
31573 build_pure_c_string ("@"),
31574 intern_c_string ("system-name")));
31576 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
31577 doc: /* Maximum number of lines to keep in the message log buffer.
31578 If nil, disable message logging. If t, log messages but don't truncate
31579 the buffer when it becomes large. */);
31580 Vmessage_log_max = make_number (1000);
31582 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
31583 doc: /* List of functions to call before redisplaying a window with scrolling.
31584 Each function is called with two arguments, the window and its new
31585 display-start position.
31586 These functions are called whenever the `window-start' marker is modified,
31587 either to point into another buffer (e.g. via `set-window-buffer') or another
31588 place in the same buffer.
31589 Note that the value of `window-end' is not valid when these functions are
31590 called.
31592 Warning: Do not use this feature to alter the way the window
31593 is scrolled. It is not designed for that, and such use probably won't
31594 work. */);
31595 Vwindow_scroll_functions = Qnil;
31597 DEFVAR_LISP ("window-text-change-functions",
31598 Vwindow_text_change_functions,
31599 doc: /* Functions to call in redisplay when text in the window might change. */);
31600 Vwindow_text_change_functions = Qnil;
31602 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
31603 doc: /* Functions called when redisplay of a window reaches the end trigger.
31604 Each function is called with two arguments, the window and the end trigger value.
31605 See `set-window-redisplay-end-trigger'. */);
31606 Vredisplay_end_trigger_functions = Qnil;
31608 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
31609 doc: /* Non-nil means autoselect window with mouse pointer.
31610 If nil, do not autoselect windows.
31611 A positive number means delay autoselection by that many seconds: a
31612 window is autoselected only after the mouse has remained in that
31613 window for the duration of the delay.
31614 A negative number has a similar effect, but causes windows to be
31615 autoselected only after the mouse has stopped moving. (Because of
31616 the way Emacs compares mouse events, you will occasionally wait twice
31617 that time before the window gets selected.)
31618 Any other value means to autoselect window instantaneously when the
31619 mouse pointer enters it.
31621 Autoselection selects the minibuffer only if it is active, and never
31622 unselects the minibuffer if it is active.
31624 When customizing this variable make sure that the actual value of
31625 `focus-follows-mouse' matches the behavior of your window manager. */);
31626 Vmouse_autoselect_window = Qnil;
31628 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
31629 doc: /* Non-nil means automatically resize tool-bars.
31630 This dynamically changes the tool-bar's height to the minimum height
31631 that is needed to make all tool-bar items visible.
31632 If value is `grow-only', the tool-bar's height is only increased
31633 automatically; to decrease the tool-bar height, use \\[recenter]. */);
31634 Vauto_resize_tool_bars = Qt;
31636 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
31637 doc: /* Non-nil means raise tool-bar buttons when the mouse moves over them. */);
31638 auto_raise_tool_bar_buttons_p = true;
31640 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
31641 doc: /* Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
31642 make_cursor_line_fully_visible_p = true;
31644 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
31645 doc: /* Border below tool-bar in pixels.
31646 If an integer, use it as the height of the border.
31647 If it is one of `internal-border-width' or `border-width', use the
31648 value of the corresponding frame parameter.
31649 Otherwise, no border is added below the tool-bar. */);
31650 Vtool_bar_border = Qinternal_border_width;
31652 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
31653 doc: /* Margin around tool-bar buttons in pixels.
31654 If an integer, use that for both horizontal and vertical margins.
31655 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
31656 HORZ specifying the horizontal margin, and VERT specifying the
31657 vertical margin. */);
31658 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
31660 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
31661 doc: /* Relief thickness of tool-bar buttons. */);
31662 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
31664 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
31665 doc: /* Tool bar style to use.
31666 It can be one of
31667 image - show images only
31668 text - show text only
31669 both - show both, text below image
31670 both-horiz - show text to the right of the image
31671 text-image-horiz - show text to the left of the image
31672 any other - use system default or image if no system default.
31674 This variable only affects the GTK+ toolkit version of Emacs. */);
31675 Vtool_bar_style = Qnil;
31677 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
31678 doc: /* Maximum number of characters a label can have to be shown.
31679 The tool bar style must also show labels for this to have any effect, see
31680 `tool-bar-style'. */);
31681 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
31683 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
31684 doc: /* List of functions to call to fontify regions of text.
31685 Each function is called with one argument POS. Functions must
31686 fontify a region starting at POS in the current buffer, and give
31687 fontified regions the property `fontified'. */);
31688 Vfontification_functions = Qnil;
31689 Fmake_variable_buffer_local (Qfontification_functions);
31691 DEFVAR_BOOL ("unibyte-display-via-language-environment",
31692 unibyte_display_via_language_environment,
31693 doc: /* Non-nil means display unibyte text according to language environment.
31694 Specifically, this means that raw bytes in the range 160-255 decimal
31695 are displayed by converting them to the equivalent multibyte characters
31696 according to the current language environment. As a result, they are
31697 displayed according to the current fontset.
31699 Note that this variable affects only how these bytes are displayed,
31700 but does not change the fact they are interpreted as raw bytes. */);
31701 unibyte_display_via_language_environment = false;
31703 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
31704 doc: /* Maximum height for resizing mini-windows (the minibuffer and the echo area).
31705 If a float, it specifies a fraction of the mini-window frame's height.
31706 If an integer, it specifies a number of lines. */);
31707 Vmax_mini_window_height = make_float (0.25);
31709 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
31710 doc: /* How to resize mini-windows (the minibuffer and the echo area).
31711 A value of nil means don't automatically resize mini-windows.
31712 A value of t means resize them to fit the text displayed in them.
31713 A value of `grow-only', the default, means let mini-windows grow only;
31714 they return to their normal size when the minibuffer is closed, or the
31715 echo area becomes empty. */);
31716 /* Contrary to the doc string, we initialize this to nil, so that
31717 loading loadup.el won't try to resize windows before loading
31718 window.el, where some functions we need to call for this live.
31719 We assign the 'grow-only' value right after loading window.el
31720 during loadup. */
31721 Vresize_mini_windows = Qnil;
31723 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
31724 doc: /* Alist specifying how to blink the cursor off.
31725 Each element has the form (ON-STATE . OFF-STATE). Whenever the
31726 `cursor-type' frame-parameter or variable equals ON-STATE,
31727 comparing using `equal', Emacs uses OFF-STATE to specify
31728 how to blink it off. ON-STATE and OFF-STATE are values for
31729 the `cursor-type' frame parameter.
31731 If a frame's ON-STATE has no entry in this list,
31732 the frame's other specifications determine how to blink the cursor off. */);
31733 Vblink_cursor_alist = Qnil;
31735 DEFVAR_BOOL ("auto-hscroll-mode", automatic_hscrolling_p,
31736 doc: /* Allow or disallow automatic horizontal scrolling of windows.
31737 If non-nil, windows are automatically scrolled horizontally to make
31738 point visible. */);
31739 automatic_hscrolling_p = true;
31740 DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
31742 DEFVAR_INT ("hscroll-margin", hscroll_margin,
31743 doc: /* How many columns away from the window edge point is allowed to get
31744 before automatic hscrolling will horizontally scroll the window. */);
31745 hscroll_margin = 5;
31747 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
31748 doc: /* How many columns to scroll the window when point gets too close to the edge.
31749 When point is less than `hscroll-margin' columns from the window
31750 edge, automatic hscrolling will scroll the window by the amount of columns
31751 determined by this variable. If its value is a positive integer, scroll that
31752 many columns. If it's a positive floating-point number, it specifies the
31753 fraction of the window's width to scroll. If it's nil or zero, point will be
31754 centered horizontally after the scroll. Any other value, including negative
31755 numbers, are treated as if the value were zero.
31757 Automatic hscrolling always moves point outside the scroll margin, so if
31758 point was more than scroll step columns inside the margin, the window will
31759 scroll more than the value given by the scroll step.
31761 Note that the lower bound for automatic hscrolling specified by `scroll-left'
31762 and `scroll-right' overrides this variable's effect. */);
31763 Vhscroll_step = make_number (0);
31765 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
31766 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
31767 Bind this around calls to `message' to let it take effect. */);
31768 message_truncate_lines = false;
31770 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
31771 doc: /* Normal hook run to update the menu bar definitions.
31772 Redisplay runs this hook before it redisplays the menu bar.
31773 This is used to update menus such as Buffers, whose contents depend on
31774 various data. */);
31775 Vmenu_bar_update_hook = Qnil;
31777 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
31778 doc: /* Frame for which we are updating a menu.
31779 The enable predicate for a menu binding should check this variable. */);
31780 Vmenu_updating_frame = Qnil;
31782 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
31783 doc: /* Non-nil means don't update menu bars. Internal use only. */);
31784 inhibit_menubar_update = false;
31786 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
31787 doc: /* Prefix prepended to all continuation lines at display time.
31788 The value may be a string, an image, or a stretch-glyph; it is
31789 interpreted in the same way as the value of a `display' text property.
31791 This variable is overridden by any `wrap-prefix' text or overlay
31792 property.
31794 To add a prefix to non-continuation lines, use `line-prefix'. */);
31795 Vwrap_prefix = Qnil;
31796 DEFSYM (Qwrap_prefix, "wrap-prefix");
31797 Fmake_variable_buffer_local (Qwrap_prefix);
31799 DEFVAR_LISP ("line-prefix", Vline_prefix,
31800 doc: /* Prefix prepended to all non-continuation lines at display time.
31801 The value may be a string, an image, or a stretch-glyph; it is
31802 interpreted in the same way as the value of a `display' text property.
31804 This variable is overridden by any `line-prefix' text or overlay
31805 property.
31807 To add a prefix to continuation lines, use `wrap-prefix'. */);
31808 Vline_prefix = Qnil;
31809 DEFSYM (Qline_prefix, "line-prefix");
31810 Fmake_variable_buffer_local (Qline_prefix);
31812 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
31813 doc: /* Non-nil means don't eval Lisp during redisplay. */);
31814 inhibit_eval_during_redisplay = false;
31816 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
31817 doc: /* Non-nil means don't free realized faces. Internal use only. */);
31818 inhibit_free_realized_faces = false;
31820 DEFVAR_BOOL ("inhibit-bidi-mirroring", inhibit_bidi_mirroring,
31821 doc: /* Non-nil means don't mirror characters even when bidi context requires that.
31822 Intended for use during debugging and for testing bidi display;
31823 see biditest.el in the test suite. */);
31824 inhibit_bidi_mirroring = false;
31826 #ifdef GLYPH_DEBUG
31827 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
31828 doc: /* Inhibit try_window_id display optimization. */);
31829 inhibit_try_window_id = false;
31831 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
31832 doc: /* Inhibit try_window_reusing display optimization. */);
31833 inhibit_try_window_reusing = false;
31835 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
31836 doc: /* Inhibit try_cursor_movement display optimization. */);
31837 inhibit_try_cursor_movement = false;
31838 #endif /* GLYPH_DEBUG */
31840 DEFVAR_INT ("overline-margin", overline_margin,
31841 doc: /* Space between overline and text, in pixels.
31842 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
31843 margin to the character height. */);
31844 overline_margin = 2;
31846 DEFVAR_INT ("underline-minimum-offset",
31847 underline_minimum_offset,
31848 doc: /* Minimum distance between baseline and underline.
31849 This can improve legibility of underlined text at small font sizes,
31850 particularly when using variable `x-use-underline-position-properties'
31851 with fonts that specify an UNDERLINE_POSITION relatively close to the
31852 baseline. The default value is 1. */);
31853 underline_minimum_offset = 1;
31855 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
31856 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
31857 This feature only works when on a window system that can change
31858 cursor shapes. */);
31859 display_hourglass_p = true;
31861 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
31862 doc: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
31863 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
31865 #ifdef HAVE_WINDOW_SYSTEM
31866 hourglass_atimer = NULL;
31867 hourglass_shown_p = false;
31868 #endif /* HAVE_WINDOW_SYSTEM */
31870 /* Name of the face used to display glyphless characters. */
31871 DEFSYM (Qglyphless_char, "glyphless-char");
31873 /* Method symbols for Vglyphless_char_display. */
31874 DEFSYM (Qhex_code, "hex-code");
31875 DEFSYM (Qempty_box, "empty-box");
31876 DEFSYM (Qthin_space, "thin-space");
31877 DEFSYM (Qzero_width, "zero-width");
31879 DEFVAR_LISP ("pre-redisplay-function", Vpre_redisplay_function,
31880 doc: /* Function run just before redisplay.
31881 It is called with one argument, which is the set of windows that are to
31882 be redisplayed. This set can be nil (meaning, only the selected window),
31883 or t (meaning all windows). */);
31884 Vpre_redisplay_function = intern ("ignore");
31886 /* Symbol for the purpose of Vglyphless_char_display. */
31887 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
31888 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
31890 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
31891 doc: /* Char-table defining glyphless characters.
31892 Each element, if non-nil, should be one of the following:
31893 an ASCII acronym string: display this string in a box
31894 `hex-code': display the hexadecimal code of a character in a box
31895 `empty-box': display as an empty box
31896 `thin-space': display as 1-pixel width space
31897 `zero-width': don't display
31898 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
31899 display method for graphical terminals and text terminals respectively.
31900 GRAPHICAL and TEXT should each have one of the values listed above.
31902 The char-table has one extra slot to control the display of a character for
31903 which no font is found. This slot only takes effect on graphical terminals.
31904 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
31905 `thin-space'. The default is `empty-box'.
31907 If a character has a non-nil entry in an active display table, the
31908 display table takes effect; in this case, Emacs does not consult
31909 `glyphless-char-display' at all. */);
31910 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
31911 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
31912 Qempty_box);
31914 DEFVAR_LISP ("debug-on-message", Vdebug_on_message,
31915 doc: /* If non-nil, debug if a message matching this regexp is displayed. */);
31916 Vdebug_on_message = Qnil;
31918 DEFVAR_LISP ("redisplay--all-windows-cause", Vredisplay__all_windows_cause,
31919 doc: /* */);
31920 Vredisplay__all_windows_cause = Fmake_hash_table (0, NULL);
31922 DEFVAR_LISP ("redisplay--mode-lines-cause", Vredisplay__mode_lines_cause,
31923 doc: /* */);
31924 Vredisplay__mode_lines_cause = Fmake_hash_table (0, NULL);
31926 DEFVAR_LISP ("redisplay--variables", Vredisplay__variables,
31927 doc: /* A hash-table of variables changing which triggers a thorough redisplay. */);
31928 Vredisplay__variables = Qnil;
31930 DEFVAR_BOOL ("redisplay--inhibit-bidi", redisplay__inhibit_bidi,
31931 doc: /* Non-nil means it is not safe to attempt bidi reordering for display. */);
31932 /* Initialize to t, since we need to disable reordering until
31933 loadup.el successfully loads charprop.el. */
31934 redisplay__inhibit_bidi = true;
31938 /* Initialize this module when Emacs starts. */
31940 void
31941 init_xdisp (void)
31943 CHARPOS (this_line_start_pos) = 0;
31945 if (!noninteractive)
31947 struct window *m = XWINDOW (minibuf_window);
31948 Lisp_Object frame = m->frame;
31949 struct frame *f = XFRAME (frame);
31950 Lisp_Object root = FRAME_ROOT_WINDOW (f);
31951 struct window *r = XWINDOW (root);
31952 int i;
31954 echo_area_window = minibuf_window;
31956 r->top_line = FRAME_TOP_MARGIN (f);
31957 r->pixel_top = r->top_line * FRAME_LINE_HEIGHT (f);
31958 r->total_cols = FRAME_COLS (f);
31959 r->pixel_width = r->total_cols * FRAME_COLUMN_WIDTH (f);
31960 r->total_lines = FRAME_TOTAL_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
31961 r->pixel_height = r->total_lines * FRAME_LINE_HEIGHT (f);
31963 m->top_line = FRAME_TOTAL_LINES (f) - 1;
31964 m->pixel_top = m->top_line * FRAME_LINE_HEIGHT (f);
31965 m->total_cols = FRAME_COLS (f);
31966 m->pixel_width = m->total_cols * FRAME_COLUMN_WIDTH (f);
31967 m->total_lines = 1;
31968 m->pixel_height = m->total_lines * FRAME_LINE_HEIGHT (f);
31970 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
31971 scratch_glyph_row.glyphs[TEXT_AREA + 1]
31972 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
31974 /* The default ellipsis glyphs `...'. */
31975 for (i = 0; i < 3; ++i)
31976 default_invis_vector[i] = make_number ('.');
31980 /* Allocate the buffer for frame titles.
31981 Also used for `format-mode-line'. */
31982 int size = 100;
31983 mode_line_noprop_buf = xmalloc (size);
31984 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
31985 mode_line_noprop_ptr = mode_line_noprop_buf;
31986 mode_line_target = MODE_LINE_DISPLAY;
31989 help_echo_showing_p = false;
31992 #ifdef HAVE_WINDOW_SYSTEM
31994 /* Platform-independent portion of hourglass implementation. */
31996 /* Timer function of hourglass_atimer. */
31998 static void
31999 show_hourglass (struct atimer *timer)
32001 /* The timer implementation will cancel this timer automatically
32002 after this function has run. Set hourglass_atimer to null
32003 so that we know the timer doesn't have to be canceled. */
32004 hourglass_atimer = NULL;
32006 if (!hourglass_shown_p)
32008 Lisp_Object tail, frame;
32010 block_input ();
32012 FOR_EACH_FRAME (tail, frame)
32014 struct frame *f = XFRAME (frame);
32016 if (FRAME_LIVE_P (f) && FRAME_WINDOW_P (f)
32017 && FRAME_RIF (f)->show_hourglass)
32018 FRAME_RIF (f)->show_hourglass (f);
32021 hourglass_shown_p = true;
32022 unblock_input ();
32026 /* Cancel a currently active hourglass timer, and start a new one. */
32028 void
32029 start_hourglass (void)
32031 struct timespec delay;
32033 cancel_hourglass ();
32035 if (INTEGERP (Vhourglass_delay)
32036 && XINT (Vhourglass_delay) > 0)
32037 delay = make_timespec (min (XINT (Vhourglass_delay),
32038 TYPE_MAXIMUM (time_t)),
32040 else if (FLOATP (Vhourglass_delay)
32041 && XFLOAT_DATA (Vhourglass_delay) > 0)
32042 delay = dtotimespec (XFLOAT_DATA (Vhourglass_delay));
32043 else
32044 delay = make_timespec (DEFAULT_HOURGLASS_DELAY, 0);
32046 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
32047 show_hourglass, NULL);
32050 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
32051 shown. */
32053 void
32054 cancel_hourglass (void)
32056 if (hourglass_atimer)
32058 cancel_atimer (hourglass_atimer);
32059 hourglass_atimer = NULL;
32062 if (hourglass_shown_p)
32064 Lisp_Object tail, frame;
32066 block_input ();
32068 FOR_EACH_FRAME (tail, frame)
32070 struct frame *f = XFRAME (frame);
32072 if (FRAME_LIVE_P (f) && FRAME_WINDOW_P (f)
32073 && FRAME_RIF (f)->hide_hourglass)
32074 FRAME_RIF (f)->hide_hourglass (f);
32075 #ifdef HAVE_NTGUI
32076 /* No cursors on non GUI frames - restore to stock arrow cursor. */
32077 else if (!FRAME_W32_P (f))
32078 w32_arrow_cursor ();
32079 #endif
32082 hourglass_shown_p = false;
32083 unblock_input ();
32087 #endif /* HAVE_WINDOW_SYSTEM */